Maintaining sessions in CLI and SDK

Maintaining sessions in CLI and SDK

2025.08.20

Introduction

In my previous article, I introduced how to continue conversations with Claude Code SDK.
While that was about continuation methods in the SDK, there's also a way to continue work done in Claude Code CLI using the SDK.

Here,
there was an exchange stating "Claude Code can't directly access its own metadata, but you can retrieve it with hooks, etc."
Based on this information, in this article we'll try continuing work done in the CLI using the SDK.

Environment

  • MacBook Pro (14-inch, M3, 2023)
  • OS : MacOS 14.5
  • Claude Code SDK: v1.0.85
  • Node.js: v20.x
  • jq : 1.8.1

Session ID?

Claude Code assigns a unique session ID to each conversation, like the following:

			
			#example session id
67dc7d72-2fee-4bc8-806d-6a5b1638ef95

		

By using this ID, you can resume processing while maintaining the context up to that point,
even if the process is interrupted.

This allows you to continue accurately later if you need to interrupt your work for any reason.
It also enables you to take over work started in CLI through a program using the SDK.

Try

Let's create a demo to test this.
We'll use hooks to output the SessionId to logs, and verify if we can inherit the context by specifying that ID in the SDK.

Creating a project

First, create any demo project with the following structure:

			
			your-project/
├── .claude/
│   ├── settings.json      # Hook settings
│   └── hooks/
│       └── save-session.sh  # Session saving script
├── .work/
│   └── sessions/          # For saving session information (auto-created)
│       ├── latest.json    # Latest session information
│       ├── {session_id}.json  # Individual session information
│       └── history.log    # Session history
└── any_directory/         # The main code of this repository
    ├── hoge.ts
    └── fuga.js

		

Create the .claude/hooks directory,
and create the shell script and settings.json described later.
Once created, let's start claude and just do /init for now.### Setting up hooks

Claude Code's hooks are extension processes that can be automatically executed before or after certain defined operations such as tool execution or process interruption.

First, let's create a script (.claude/hooks/save-session.sh) that will be executed by the hooks to save the session ID.

This script will automatically save session information each time a prompt is submitted.
(Please install jq beforehand as it's required)

			
			#!/bin/bash

INPUT=$(cat)

# Extract necessary information from JSON
SESSION_ID=$(echo "$INPUT" | jq -r '.session_id // empty')
CWD=$(echo "$INPUT" | jq -r '.cwd // empty')
# Path to conversation history file
TRANSCRIPT_PATH=$(echo "$INPUT" | jq -r '.transcript_path // empty')
# timestamp
TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")

if [ -n "$SESSION_ID" ]; then
    # Structure session information in JSON format
    SESSION_DATA=$(jq -n \
      --arg id "$SESSION_ID" \
      --arg cwd "$CWD" \
      --arg transcript "$TRANSCRIPT_PATH" \
      --arg ts "$TIMESTAMP" \
      '{
        sessionId: $id, 
        workingDirectory: $cwd,
        transcriptPath: $transcript,
        timestamp: $ts
      }')

    # Save session information
    # Save in the .work/sessions directory at the project root
    SESSIONS_DIR="${CLAUDE_PROJECT_DIR}/.work/sessions"
    mkdir -p "$SESSIONS_DIR"

    # Save as the latest session information
    echo "$SESSION_DATA" > "$SESSIONS_DIR/latest.json"

    # Save as an individual file for each session ID
    echo "$SESSION_DATA" > "$SESSIONS_DIR/${SESSION_ID}.json"

    # Record in the log file
    echo "[$TIMESTAMP] Session: $SESSION_ID | CWD: $CWD" >> "$SESSIONS_DIR/history.log"

    # Output success message to stderr
    echo "📝 Session ID saved: $SESSION_ID" >&2

fi

exit 0

		

${CLAUDE_PROJECT_DIR} is an environment variable provided by Claude Code that represents the path to the target project.
When this shell script is executed, the following files will be created or updated in ${CLAUDE_PROJECT_DIR}/.work/sessions/:

  • latest.json: Latest session information (overwritten each time)
  • {session_id}.json: Individual session information (for history retention)
  • history.log: Execution log of all sessions

Next, let's create .claude/settings.json and write the following to make save-session.sh run at the UserPromptSubmit timing (when a user submits a prompt via CLI):

			
			{
  "hooks": {
    "UserPromptSubmit": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/save-session.sh"
          }
        ]
      }
    ]
  }
}
```Let's make it executable by setting the appropriate permissions.

```bash
% chmod +x .claude/hooks/save-session.sh
```### Claude Code SDK Program Creation

We'll create a program to run Claude Code with the SDK.

```bash
% mkdir path/your/sdk-demo && cd path/your/sdk-demo
% npm init -y
npm install @anthropic-ai/claude-code@^1.0.85 dotenv chalk typescript tsx @types/node

		

Here's the package.json file:

			
			{
  "name": "sdk-continue",
  "version": "1.0.0",
  "scripts": {
    "verify": "tsx verify-session.ts"
  },
  "dependencies": {
    "@anthropic-ai/claude-code": "^1.0.85",
    "dotenv": "^16.3.1",
    "chalk": "^5.3.0"
  },
  "devDependencies": {
    "@types/node": "^20.10.0",
    "tsx": "^4.6.2",
    "typescript": "^5.3.3"
  }
}

		

Let's create verify-session.ts:

			
			  import { query } from '@anthropic-ai/claude-code';
  import * as dotenv from 'dotenv';

  dotenv.config();

  async function verifySession(sessionId: string, workingDir?: string) {
    console.log(' ** CLI Session Continuation Test ** ');
    console.log(`Session ID: ${sessionId}`);
    if (workingDir) {
      console.log(`Working Directory: ${workingDir}`);
    }
    console.log('='.repeat(60));

    const prompt =
  "Please summarize our previous conversation and the work we've done so far.";

    try {
      let responseText = '';

      for await (const message of query({
        prompt,
        options: {
          resume: sessionId,  //Pass the CLI session ID
          cwd: workingDir || process.cwd(),
        }
      })) {
        if (message.type === 'assistant' && message.message?.content) {
          const content = message.message.content;
          if (Array.isArray(content)) {
            content.forEach((item: any) => {
              if (item.type === 'text') {
                responseText += item.text;
              }
            });
          }
        } else if (message.type === 'completion') {
          console.log('\n Response:');
          console.log(responseText);
        }
      }

      console.log('\n✨ Session continuation test completed');

    } catch (error) {
      console.error('Error:', error);
    }
  }

  // Main execution
  const sessionId = process.argv[2];
  const workingDir = process.argv[3];

  verifySession(sessionId, workingDir).catch(console.error);
```Next, please get an API key for Claude to use Claude Code with the SDK, and add it to your .env file as ANTHROPIC_API_KEY.

### Running the CLI and SDK

Use the CLI to give a simple instruction (works from VSCode too):

```bash
% cd path/your-project
% claude

> Please create a simple text file

		

Let's check .work/sessions.
The history.json and latest.json files are updated.

			
			{
  "sessionId": "xxxxxx",
  "workingDirectory": "/path/your/project",
  "transcriptPath": "・・・・.jsonl",
  "timestamp": "2025-08-20T05:47:06Z"
}

		

Copy this sessionId and run the verify-session.ts program we created earlier.
The program will ask for a summary of the previous conversation.

			
			% npm run verify xxxxxx /path/your/project

・・・・

** CLI Session Continuation Test **
Session ID: xxxxxx
Working Directory: xxxxx
============================================================

Prompt 1:
Please provide a summary of our conversation so far and the work that has been done.
------------------------------------------------------------
## Conversation Summary

The user asked about what features should be implemented next, and I analyzed the current codebase to suggest features. Later, I was asked to create a test text file.

## Work Completed

1. **Project Status Assessment**
   - Read README.md to understand the project overview and features
   - Checked CHANGELOG.md to understand implementation history

2. **Proposed Future Features**
   - Presented 9 feature improvement ideas prioritized by importance
   - Recommended "incremental index updating" as the highest priority feature

3. **Test File Creation** (most recent task)
   - **Filename**: `/test_sample.txt`
   - **Content Created**: 
     - Mixed Japanese and English text
     - Multiple paragraphs
     - Numerical data (versions, dates, file sizes)
     - Approximately 500 character sample text for testing
   - **Purpose**: xxxxxxx
============================================================

Session continuation test completed

		

As shown above, interactions conducted via CLI or IDE can also be displayed through the SDK.
*Note: Some sessions may display more detailed conversation history

The SDK Message from the query result includes a session_id. This can be used to continue the Claude code SDK history in the CLI:

			
			% claude --resume <session_id> "next instruction"

		

Summary

This article explained how to maintain session continuity between Claude Code CLI and SDK.
This allows you to continue work started in the CLI using the SDK,
enhancing work continuity.

References

Share this article

FacebookHatena blogX

Related articles