diff --git a/lib/ai/claude_cli.js b/lib/ai/claude_cli.js index 3fa32ad..7919192 100644 --- a/lib/ai/claude_cli.js +++ b/lib/ai/claude_cli.js @@ -59,6 +59,7 @@ import { createInterface } from 'readline'; * @param {function} [opts.onEvent] Called for each normalized event * @param {string} [opts.claudeExe] Path or name of claude binary (default: CLAUDE_EXE env or 'claude') * @param {string[]} [opts.tools] Exclusive available-tools allowlist (--tools); removes built-ins + * @param {boolean} [opts.resume] Continue an existing session (--resume) vs create (--session-id) * @param {string} [opts.home] If set, overrides HOME in child env (for service-user creds) * @param {string} [opts.cwd] Working directory for the child process * @param {number} [opts.timeoutMs] Milliseconds before SIGTERM (default: 600000) @@ -73,6 +74,7 @@ export async function runClaudeTurn(opts) { mcpConfigPath, allowedTools = [], tools = [], + resume = false, onEvent, claudeExe = process.env.CLAUDE_EXE || 'claude', home = process.env.VOID_CLAUDE_HOME, @@ -89,7 +91,9 @@ export async function runClaudeTurn(opts) { '--verbose', '--include-partial-messages', '--append-system-prompt', systemPrompt, - '--session-id', sessionId, + // First turn creates the session (--session-id); later turns MUST continue + // it with --resume (reusing --session-id on an existing session errors). + ...(resume ? ['--resume', sessionId] : ['--session-id', sessionId]), ]; if (mcpConfigPath) { diff --git a/lib/api/routes/companion.js b/lib/api/routes/companion.js index 47aacb0..be0c372 100644 --- a/lib/api/routes/companion.js +++ b/lib/api/routes/companion.js @@ -52,6 +52,11 @@ spacesScopedRouter.post('/turn', const { agent, convo } = await resolveConversation(req.params.space_id); const { text, view } = req.body; + // Resume the claude session if this conversation already had turns (the CLI + // keys session history by --session-id; first turn creates it, rest --resume). + const priorTurns = (await messages.listByConversation(convo.id)).length; + const resume = priorTurns > 0; + await messages.append(convo.id, { role: 'user', body: text }); res.writeHead(200, { @@ -105,6 +110,7 @@ spacesScopedRouter.post('/turn', try { result = await runClaudeTurn({ sessionId: convo.id, + resume, systemPrompt: SYSTEM, userText: text, mcpConfigPath,