From c4c16948d8c194d0b35033b783fc38816136c81a Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 20 Oct 2025 15:06:10 -0500 Subject: [PATCH 01/11] fix: update variable names in tests and enhance session handling in start script --- .../coder/modules/claude-code/main.test.ts | 6 +- .../modules/claude-code/scripts/start.sh | 56 ++++++++++++++++++- 2 files changed, 56 insertions(+), 6 deletions(-) diff --git a/registry/coder/modules/claude-code/main.test.ts b/registry/coder/modules/claude-code/main.test.ts index 9c132f1ab..afcb03556 100644 --- a/registry/coder/modules/claude-code/main.test.ts +++ b/registry/coder/modules/claude-code/main.test.ts @@ -167,7 +167,7 @@ describe("claude-code", async () => { const { id } = await setup({ moduleVariables: { permission_mode: mode, - task_prompt: "test prompt", + ai_prompt: "test prompt", }, }); await execModuleScript(id); @@ -185,7 +185,7 @@ describe("claude-code", async () => { const { id } = await setup({ moduleVariables: { model: model, - task_prompt: "test prompt", + ai_prompt: "test prompt", }, }); await execModuleScript(id); @@ -202,7 +202,7 @@ describe("claude-code", async () => { const { id } = await setup({ moduleVariables: { continue: "true", - task_prompt: "test prompt", + ai_prompt: "test prompt", }, }); await execModuleScript(id); diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 6eeb411b9..45d364e20 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -44,6 +44,26 @@ function validate_claude_installation() { fi } +has_session_for_workdir() { + local workdir="$1" + local workdir_abs=$(realpath "$workdir" 2> /dev/null || echo "$workdir") + + if [ -f "$HOME/.claude.json" ]; then + if jq -e ".projects[\"$workdir_abs\"]" "$HOME/.claude.json" > /dev/null 2>&1; then + return 0 + fi + fi + + local project_dir_name=$(echo "$workdir_abs" | sed 's|/|-|g') + local project_sessions_dir="$HOME/.claude/projects/$project_dir_name" + + if [ -d "$project_sessions_dir" ] && [ -n "$(ls -A "$project_sessions_dir" 2> /dev/null)" ]; then + return 0 + fi + + return 1 +} + ARGS=() function build_claude_args() { @@ -68,13 +88,43 @@ function build_claude_args() { function start_agentapi() { mkdir -p "$ARG_WORKDIR" cd "$ARG_WORKDIR" - if [ -n "$ARG_AI_PROMPT" ]; then - ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") - else + + if [ -n "$ARG_RESUME_SESSION_ID" ]; then + echo "Using explicit resume_session_id: $ARG_RESUME_SESSION_ID" + if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + elif [ "$ARG_CONTINUE" = "true" ]; then + echo "Using explicit continue flag" if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then ARGS+=(--dangerously-skip-permissions) fi + else + local has_existing_session=false + if has_session_for_workdir "$ARG_WORKDIR"; then + has_existing_session=true + echo "Session detected for workdir: $ARG_WORKDIR" + else + echo "No existing session for workdir: $ARG_WORKDIR" + fi + + if [ -n "$ARG_AI_PROMPT" ] && [ "$has_existing_session" = "false" ]; then + ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") + echo "Starting new session with prompt" + elif [ "$has_existing_session" = "true" ]; then + ARGS+=(--continue) + if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + echo "Resuming existing session" + else + if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + echo "Starting claude code session" + fi fi + printf "Running claude code with args: %s\n" "$(printf '%q ' "${ARGS[@]}")" agentapi server --type claude --term-width 67 --term-height 1190 -- claude "${ARGS[@]}" } From 512692ca10c29f6faa15fa6389b186810629f6a8 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 20 Oct 2025 15:40:37 -0500 Subject: [PATCH 02/11] fix: resolve session handling bug --- registry/coder/modules/claude-code/main.tf | 4 +-- .../modules/claude-code/scripts/start.sh | 32 ++++++++++--------- 2 files changed, 19 insertions(+), 17 deletions(-) diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index 8909a024b..5f736ac2c 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -134,8 +134,8 @@ variable "resume_session_id" { variable "continue" { type = bool - description = "Load the most recent conversation in the current directory. Task will fail in a new workspace with no conversation/session to continue" - default = false + description = "Automatically continue existing sessions when workspace restarts. When true, resumes existing conversation if found, otherwise runs prompt or starts new session. When false, always starts fresh (ignores existing sessions)." + default = true } variable "dangerously_skip_permissions" { diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 45d364e20..901f8ed68 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -95,28 +95,30 @@ function start_agentapi() { ARGS+=(--dangerously-skip-permissions) fi elif [ "$ARG_CONTINUE" = "true" ]; then - echo "Using explicit continue flag" - if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then - ARGS+=(--dangerously-skip-permissions) - fi - else - local has_existing_session=false if has_session_for_workdir "$ARG_WORKDIR"; then - has_existing_session=true echo "Session detected for workdir: $ARG_WORKDIR" - else - echo "No existing session for workdir: $ARG_WORKDIR" - fi - - if [ -n "$ARG_AI_PROMPT" ] && [ "$has_existing_session" = "false" ]; then - ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") - echo "Starting new session with prompt" - elif [ "$has_existing_session" = "true" ]; then ARGS+=(--continue) if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then ARGS+=(--dangerously-skip-permissions) fi echo "Resuming existing session" + else + echo "No existing session for workdir: $ARG_WORKDIR" + if [ -n "$ARG_AI_PROMPT" ]; then + ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") + echo "Starting new session with prompt" + else + if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + echo "Starting claude code session" + fi + fi + else + echo "Continue disabled, starting fresh session" + if [ -n "$ARG_AI_PROMPT" ]; then + ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") + echo "Starting new session with prompt" else if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then ARGS+=(--dangerously-skip-permissions) From 6a927f2f0a63d011816b0b7292fa8c3bd19b4279 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 20 Oct 2025 16:10:04 -0500 Subject: [PATCH 03/11] fix: improve session validation logic in start script --- .../coder/modules/claude-code/scripts/start.sh | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 901f8ed68..d5cdc080d 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -48,17 +48,16 @@ has_session_for_workdir() { local workdir="$1" local workdir_abs=$(realpath "$workdir" 2> /dev/null || echo "$workdir") - if [ -f "$HOME/.claude.json" ]; then - if jq -e ".projects[\"$workdir_abs\"]" "$HOME/.claude.json" > /dev/null 2>&1; then - return 0 - fi - fi - local project_dir_name=$(echo "$workdir_abs" | sed 's|/|-|g') local project_sessions_dir="$HOME/.claude/projects/$project_dir_name" - if [ -d "$project_sessions_dir" ] && [ -n "$(ls -A "$project_sessions_dir" 2> /dev/null)" ]; then - return 0 + if [ -d "$project_sessions_dir" ]; then + for file in "$project_sessions_dir"/*.jsonl; do + [ -f "$file" ] || continue + if ! grep -q '"content":"Warmup"' "$file" 2> /dev/null; then + return 0 + fi + done fi return 1 From e6571df89bfc7029eec567a1bd672c4aa08469da Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 20 Oct 2025 16:54:38 -0500 Subject: [PATCH 04/11] fix: enhance session validation logic in start script to ensure user messages are prioritized over warmup messages --- registry/coder/modules/claude-code/scripts/start.sh | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index d5cdc080d..e26e2e2eb 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -54,8 +54,14 @@ has_session_for_workdir() { if [ -d "$project_sessions_dir" ]; then for file in "$project_sessions_dir"/*.jsonl; do [ -f "$file" ] || continue - if ! grep -q '"content":"Warmup"' "$file" 2> /dev/null; then - return 0 + + if grep -q '"type":"user"' "$file" 2> /dev/null; then + local user_msg_count=$(grep -c '"type":"user"' "$file" 2> /dev/null || echo "0") + local warmup_count=$(grep -c '"content":"Warmup"' "$file" 2> /dev/null || echo "0") + + if [ "$user_msg_count" -gt "$warmup_count" ]; then + return 0 + fi fi done fi From 87b3d82ebfbee0b9740b9bd627bc5f409c66562a Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Mon, 20 Oct 2025 17:39:30 -0500 Subject: [PATCH 05/11] fix: update version to 3.1.2 and add session resumption behavior documentation in Claude Code module README --- registry/coder/modules/claude-code/README.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index ed10e2a56..79a65e1ee 100644 --- a/registry/coder/modules/claude-code/README.md +++ b/registry/coder/modules/claude-code/README.md @@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -32,6 +32,10 @@ module "claude-code" { - You can get the API key from the [Anthropic Console](https://console.anthropic.com/dashboard). - You can get the Session Token using the `claude setup-token` command. This is a long-lived authentication token (requires Claude subscription) +### Session Resumption Behavior + +By default, Claude Code automatically resumes existing conversations when your workspace restarts. Sessions are tracked per workspace directory, so conversations continue where you left off. If no session exists (first start), your `ai_prompt` will run normally. To disable this behavior and always start fresh, set `continue = false` + ## Examples ### Usage with Tasks and Advanced Configuration @@ -49,7 +53,7 @@ data "coder_parameter" "ai_prompt" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" @@ -85,7 +89,7 @@ Run and configure Claude Code as a standalone CLI in your workspace. ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder" install_claude_code = true @@ -108,7 +112,7 @@ variable "claude_code_oauth_token" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" claude_code_oauth_token = var.claude_code_oauth_token @@ -181,7 +185,7 @@ resource "coder_env" "bedrock_api_key" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" @@ -238,7 +242,7 @@ resource "coder_env" "google_application_credentials" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.1.1" + version = "3.1.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" model = "claude-sonnet-4@20250514" From ad73f0039afb329b7a61f2f7a00ba2270828c7f6 Mon Sep 17 00:00:00 2001 From: DevCats Date: Tue, 21 Oct 2025 07:54:47 -0500 Subject: [PATCH 06/11] chore: fix description grammar Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- registry/coder/modules/claude-code/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder/modules/claude-code/main.tf b/registry/coder/modules/claude-code/main.tf index 5f736ac2c..5470a41dc 100644 --- a/registry/coder/modules/claude-code/main.tf +++ b/registry/coder/modules/claude-code/main.tf @@ -134,7 +134,7 @@ variable "resume_session_id" { variable "continue" { type = bool - description = "Automatically continue existing sessions when workspace restarts. When true, resumes existing conversation if found, otherwise runs prompt or starts new session. When false, always starts fresh (ignores existing sessions)." + description = "Automatically continue existing sessions on workspace restart. When true, resumes existing conversation if found, otherwise runs prompt or starts new session. When false, always starts fresh (ignores existing sessions)." default = true } From a778e236cb5a423e82e20cd4305bc0e7780102b3 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Tue, 21 Oct 2025 08:41:16 -0500 Subject: [PATCH 07/11] fix: streamline session handling in start script by prioritizing sidechain checks and consolidating functions to build args --- .../modules/claude-code/scripts/start.sh | 28 ++++--------------- 1 file changed, 6 insertions(+), 22 deletions(-) diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index e26e2e2eb..8ebfdc729 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -54,48 +54,33 @@ has_session_for_workdir() { if [ -d "$project_sessions_dir" ]; then for file in "$project_sessions_dir"/*.jsonl; do [ -f "$file" ] || continue - if grep -q '"type":"user"' "$file" 2> /dev/null; then - local user_msg_count=$(grep -c '"type":"user"' "$file" 2> /dev/null || echo "0") - local warmup_count=$(grep -c '"content":"Warmup"' "$file" 2> /dev/null || echo "0") - - if [ "$user_msg_count" -gt "$warmup_count" ]; then + if grep -q '"isSidechain":false' "$file" 2> /dev/null; then return 0 fi fi done fi - return 1 } ARGS=() -function build_claude_args() { +function start_agentapi() { + mkdir -p "$ARG_WORKDIR" + cd "$ARG_WORKDIR" + if [ -n "$ARG_MODEL" ]; then ARGS+=(--model "$ARG_MODEL") fi - if [ -n "$ARG_RESUME_SESSION_ID" ]; then - ARGS+=(--resume "$ARG_RESUME_SESSION_ID") - fi - - if [ "$ARG_CONTINUE" = "true" ]; then - ARGS+=(--continue) - fi - if [ -n "$ARG_PERMISSION_MODE" ]; then ARGS+=(--permission-mode "$ARG_PERMISSION_MODE") fi -} - -function start_agentapi() { - mkdir -p "$ARG_WORKDIR" - cd "$ARG_WORKDIR" - if [ -n "$ARG_RESUME_SESSION_ID" ]; then echo "Using explicit resume_session_id: $ARG_RESUME_SESSION_ID" + ARGS+=(--resume "$ARG_RESUME_SESSION_ID") if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then ARGS+=(--dangerously-skip-permissions) fi @@ -137,5 +122,4 @@ function start_agentapi() { } validate_claude_installation -build_claude_args start_agentapi From 60cc4eec52cc81fb2680bcf547fb052f3f615c98 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Tue, 21 Oct 2025 13:01:00 -0500 Subject: [PATCH 08/11] fix: setup mock for existing session in test --- registry/coder/modules/claude-code/main.test.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/registry/coder/modules/claude-code/main.test.ts b/registry/coder/modules/claude-code/main.test.ts index afcb03556..78b0aa919 100644 --- a/registry/coder/modules/claude-code/main.test.ts +++ b/registry/coder/modules/claude-code/main.test.ts @@ -205,6 +205,17 @@ describe("claude-code", async () => { ai_prompt: "test prompt", }, }); + + const projectDir = "/home/coder/project"; + const projectDirName = projectDir.replace(/\//g, "-"); + const sessionDir = `/home/coder/.claude/projects/${projectDirName}`; + await execContainer(id, ["mkdir", "-p", sessionDir]); + await execContainer(id, [ + "bash", + "-c", + `echo '{"type":"user","isSidechain":false}' > ${sessionDir}/session-123.jsonl`, + ]); + await execModuleScript(id); const startLog = await execContainer(id, [ From 2053af3059820e38a00744849fda69937ba05bea Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Tue, 21 Oct 2025 13:31:03 -0500 Subject: [PATCH 09/11] fix: implement session ID extraction in start script and update tests to validate session resumption --- .../coder/modules/claude-code/main.test.ts | 7 +- .../modules/claude-code/scripts/start.sh | 66 ++++++++++++++++--- 2 files changed, 63 insertions(+), 10 deletions(-) diff --git a/registry/coder/modules/claude-code/main.test.ts b/registry/coder/modules/claude-code/main.test.ts index 78b0aa919..200a5df22 100644 --- a/registry/coder/modules/claude-code/main.test.ts +++ b/registry/coder/modules/claude-code/main.test.ts @@ -206,14 +206,16 @@ describe("claude-code", async () => { }, }); + // Create a mock session file so get_latest_session_id can extract the session ID const projectDir = "/home/coder/project"; const projectDirName = projectDir.replace(/\//g, "-"); const sessionDir = `/home/coder/.claude/projects/${projectDirName}`; + const testSessionId = "test-session-123"; await execContainer(id, ["mkdir", "-p", sessionDir]); await execContainer(id, [ "bash", "-c", - `echo '{"type":"user","isSidechain":false}' > ${sessionDir}/session-123.jsonl`, + `echo '{"type":"user","isSidechain":false,"sessionId":"${testSessionId}"}' > ${sessionDir}/session-123.jsonl`, ]); await execModuleScript(id); @@ -223,7 +225,8 @@ describe("claude-code", async () => { "-c", "cat /home/coder/.claude-module/agentapi-start.log", ]); - expect(startLog.stdout).toContain("--continue"); + expect(startLog.stdout).toContain("--resume"); + expect(startLog.stdout).toContain(testSessionId); }); test("pre-post-install-scripts", async () => { diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index 8ebfdc729..a5d9d0e99 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -64,6 +64,41 @@ has_session_for_workdir() { return 1 } +get_latest_session_id() { + local workdir="$1" + local workdir_abs=$(realpath "$workdir" 2> /dev/null || echo "$workdir") + local project_dir_name=$(echo "$workdir_abs" | sed 's|/|-|g') + local project_sessions_dir="$HOME/.claude/projects/$project_dir_name" + + if [ ! -d "$project_sessions_dir" ]; then + return 1 + fi + + local latest_session_id="" + local latest_time=0 + + for file in "$project_sessions_dir"/*.jsonl; do + [ -f "$file" ] || continue + + if grep -q '"type":"user"' "$file" 2> /dev/null; then + if grep -q '"isSidechain":false' "$file" 2> /dev/null; then + local file_time=$(stat -c %Y "$file" 2> /dev/null || stat -f %m "$file" 2> /dev/null || echo 0) + if [ "$file_time" -gt "$latest_time" ]; then + latest_time=$file_time + latest_session_id=$(grep '"isSidechain":false' "$file" | grep '"sessionId"' | head -1 | grep -o '"sessionId":"[^"]*"' | cut -d'"' -f4) + fi + fi + fi + done + + if [ -n "$latest_session_id" ]; then + echo "$latest_session_id" + return 0 + else + return 1 + fi +} + ARGS=() function start_agentapi() { @@ -81,24 +116,39 @@ function start_agentapi() { if [ -n "$ARG_RESUME_SESSION_ID" ]; then echo "Using explicit resume_session_id: $ARG_RESUME_SESSION_ID" ARGS+=(--resume "$ARG_RESUME_SESSION_ID") - if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then ARGS+=(--dangerously-skip-permissions) fi elif [ "$ARG_CONTINUE" = "true" ]; then if has_session_for_workdir "$ARG_WORKDIR"; then - echo "Session detected for workdir: $ARG_WORKDIR" - ARGS+=(--continue) - if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then - ARGS+=(--dangerously-skip-permissions) + local session_id=$(get_latest_session_id "$ARG_WORKDIR") + if [ -n "$session_id" ]; then + echo "Session detected for workdir: $ARG_WORKDIR" + echo "Latest session ID: $session_id" + ARGS+=(--resume "$session_id") + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + echo "Resuming existing session with explicit session ID" + else + echo "Could not extract session ID, starting new session" + if [ -n "$ARG_AI_PROMPT" ]; then + ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") + echo "Starting new session with prompt" + else + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then + ARGS+=(--dangerously-skip-permissions) + fi + echo "Starting claude code session" + fi fi - echo "Resuming existing session" else echo "No existing session for workdir: $ARG_WORKDIR" if [ -n "$ARG_AI_PROMPT" ]; then ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") echo "Starting new session with prompt" else - if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then ARGS+=(--dangerously-skip-permissions) fi echo "Starting claude code session" @@ -110,7 +160,7 @@ function start_agentapi() { ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") echo "Starting new session with prompt" else - if [ -n "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" ]; then + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then ARGS+=(--dangerously-skip-permissions) fi echo "Starting claude code session" From 8cfabbfac7b5100ce85ab29261c63c78f41d4d03 Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Tue, 21 Oct 2025 14:07:10 -0500 Subject: [PATCH 10/11] fix: use specific session id's when continue is true --- .../coder/modules/claude-code/main.test.ts | 15 ++-- .../modules/claude-code/scripts/start.sh | 85 +++---------------- 2 files changed, 20 insertions(+), 80 deletions(-) diff --git a/registry/coder/modules/claude-code/main.test.ts b/registry/coder/modules/claude-code/main.test.ts index 200a5df22..a7c2dd14c 100644 --- a/registry/coder/modules/claude-code/main.test.ts +++ b/registry/coder/modules/claude-code/main.test.ts @@ -198,7 +198,7 @@ describe("claude-code", async () => { expect(startLog.stdout).toContain(`--model ${model}`); }); - test("claude-continue-previous-conversation", async () => { + test("claude-continue-resume-existing-session", async () => { const { id } = await setup({ moduleVariables: { continue: "true", @@ -206,16 +206,14 @@ describe("claude-code", async () => { }, }); - // Create a mock session file so get_latest_session_id can extract the session ID - const projectDir = "/home/coder/project"; - const projectDirName = projectDir.replace(/\//g, "-"); - const sessionDir = `/home/coder/.claude/projects/${projectDirName}`; - const testSessionId = "test-session-123"; + // Create a mock session file with the predefined task session ID + const taskSessionId = "cd32e253-ca16-4fd3-9825-d837e74ae3c2"; + const sessionDir = `/home/coder/.claude/projects/-home-coder-project`; await execContainer(id, ["mkdir", "-p", sessionDir]); await execContainer(id, [ "bash", "-c", - `echo '{"type":"user","isSidechain":false,"sessionId":"${testSessionId}"}' > ${sessionDir}/session-123.jsonl`, + `touch ${sessionDir}/session-${taskSessionId}.jsonl`, ]); await execModuleScript(id); @@ -226,7 +224,8 @@ describe("claude-code", async () => { "cat /home/coder/.claude-module/agentapi-start.log", ]); expect(startLog.stdout).toContain("--resume"); - expect(startLog.stdout).toContain(testSessionId); + expect(startLog.stdout).toContain(taskSessionId); + expect(startLog.stdout).toContain("Resuming existing task session"); }); test("pre-post-install-scripts", async () => { diff --git a/registry/coder/modules/claude-code/scripts/start.sh b/registry/coder/modules/claude-code/scripts/start.sh index ca2234b3f..fb3180af9 100644 --- a/registry/coder/modules/claude-code/scripts/start.sh +++ b/registry/coder/modules/claude-code/scripts/start.sh @@ -64,55 +64,10 @@ function validate_claude_installation() { fi } -has_session_for_workdir() { - local workdir="$1" - local workdir_abs=$(realpath "$workdir" 2> /dev/null || echo "$workdir") - - local project_dir_name=$(echo "$workdir_abs" | sed 's|/|-|g') - local project_sessions_dir="$HOME/.claude/projects/$project_dir_name" - - if [ -d "$project_sessions_dir" ]; then - for file in "$project_sessions_dir"/*.jsonl; do - [ -f "$file" ] || continue - if grep -q '"type":"user"' "$file" 2> /dev/null; then - if grep -q '"isSidechain":false' "$file" 2> /dev/null; then - return 0 - fi - fi - done - fi - return 1 -} - -get_latest_session_id() { - local workdir="$1" - local workdir_abs=$(realpath "$workdir" 2> /dev/null || echo "$workdir") - local project_dir_name=$(echo "$workdir_abs" | sed 's|/|-|g') - local project_sessions_dir="$HOME/.claude/projects/$project_dir_name" - - if [ ! -d "$project_sessions_dir" ]; then - return 1 - fi - - local latest_session_id="" - local latest_time=0 - - for file in "$project_sessions_dir"/*.jsonl; do - [ -f "$file" ] || continue +TASK_SESSION_ID="cd32e253-ca16-4fd3-9825-d837e74ae3c2" - if grep -q '"type":"user"' "$file" 2> /dev/null; then - if grep -q '"isSidechain":false' "$file" 2> /dev/null; then - local file_time=$(stat -c %Y "$file" 2> /dev/null || stat -f %m "$file" 2> /dev/null || echo 0) - if [ "$file_time" -gt "$latest_time" ]; then - latest_time=$file_time - latest_session_id=$(grep '"isSidechain":false' "$file" | grep '"sessionId"' | head -1 | grep -o '"sessionId":"[^"]*"' | cut -d'"' -f4) - fi - fi - fi - done - - if [ -n "$latest_session_id" ]; then - echo "$latest_session_id" +task_session_exists() { + if find "$HOME/.claude" -type f -name "*${TASK_SESSION_ID}*" 2> /dev/null | grep -q .; then return 0 else return 1 @@ -140,38 +95,24 @@ function start_agentapi() { ARGS+=(--dangerously-skip-permissions) fi elif [ "$ARG_CONTINUE" = "true" ]; then - if has_session_for_workdir "$ARG_WORKDIR"; then - local session_id=$(get_latest_session_id "$ARG_WORKDIR") - if [ -n "$session_id" ]; then - echo "Session detected for workdir: $ARG_WORKDIR" - echo "Latest session ID: $session_id" - ARGS+=(--resume "$session_id") - if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then - ARGS+=(--dangerously-skip-permissions) - fi - echo "Resuming existing session with explicit session ID" - else - echo "Could not extract session ID, starting new session" - if [ -n "$ARG_AI_PROMPT" ]; then - ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") - echo "Starting new session with prompt" - else - if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then - ARGS+=(--dangerously-skip-permissions) - fi - echo "Starting claude code session" - fi + if task_session_exists; then + echo "Task session detected (ID: $TASK_SESSION_ID)" + ARGS+=(--resume "$TASK_SESSION_ID") + if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then + ARGS+=(--dangerously-skip-permissions) fi + echo "Resuming existing task session" else - echo "No existing session for workdir: $ARG_WORKDIR" + echo "No existing task session found" + ARGS+=(--session-id "$TASK_SESSION_ID") if [ -n "$ARG_AI_PROMPT" ]; then ARGS+=(--dangerously-skip-permissions "$ARG_AI_PROMPT") - echo "Starting new session with prompt" + echo "Starting new task session with prompt" else if [ "$ARG_DANGEROUSLY_SKIP_PERMISSIONS" = "true" ]; then ARGS+=(--dangerously-skip-permissions) fi - echo "Starting claude code session" + echo "Starting new task session" fi fi else From eb2fa8a4c7f573a0bc13c3322771af3c4157a36e Mon Sep 17 00:00:00 2001 From: DevelopmentCats Date: Tue, 21 Oct 2025 16:38:05 -0500 Subject: [PATCH 11/11] chore: update version to 3.2.2 --- registry/coder/modules/claude-code/README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/registry/coder/modules/claude-code/README.md b/registry/coder/modules/claude-code/README.md index 439cf55c3..d3cee145c 100644 --- a/registry/coder/modules/claude-code/README.md +++ b/registry/coder/modules/claude-code/README.md @@ -13,7 +13,7 @@ Run the [Claude Code](https://docs.anthropic.com/en/docs/agents-and-tools/claude ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" claude_api_key = "xxxx-xxxxx-xxxx" @@ -70,7 +70,7 @@ data "coder_parameter" "ai_prompt" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" @@ -106,7 +106,7 @@ Run and configure Claude Code as a standalone CLI in your workspace. ```tf module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder" install_claude_code = true @@ -129,7 +129,7 @@ variable "claude_code_oauth_token" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" claude_code_oauth_token = var.claude_code_oauth_token @@ -202,7 +202,7 @@ resource "coder_env" "bedrock_api_key" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" model = "global.anthropic.claude-sonnet-4-5-20250929-v1:0" @@ -259,7 +259,7 @@ resource "coder_env" "google_application_credentials" { module "claude-code" { source = "registry.coder.com/coder/claude-code/coder" - version = "3.2.1" + version = "3.2.2" agent_id = coder_agent.example.id workdir = "/home/coder/project" model = "claude-sonnet-4@20250514"