diff --git a/src/container-runner.ts b/src/container-runner.ts index c658bd3..1700a69 100644 --- a/src/container-runner.ts +++ b/src/container-runner.ts @@ -15,10 +15,7 @@ import { IDLE_TIMEOUT, TIMEZONE, } from './config.js'; -import { - resolveGroupFolderPath, - resolveGroupIpcPath, -} from './group-folder.js'; +import { resolveGroupFolderPath, resolveGroupIpcPath } from './group-folder.js'; import { logger } from './logger.js'; import { readEnvFile } from './env.js'; import { RegisteredGroup } from './types.js'; @@ -116,8 +113,7 @@ function prepareGroupEnvironment( // Determine runner directory const agentType = group.agentType || 'claude-code'; - const runnerDirName = - agentType === 'codex' ? 'codex-runner' : 'agent-runner'; + const runnerDirName = agentType === 'codex' ? 'codex-runner' : 'agent-runner'; const runnerDir = path.join(projectRoot, 'container', runnerDirName); // Build environment variables for the runner process @@ -132,8 +128,21 @@ function prepareGroupEnvironment( 'CODEX_OPENAI_API_KEY', ]); + // Build a clean env without Claude Code nesting detection variables + const cleanEnv = { ...(process.env as Record) }; + delete cleanEnv.CLAUDECODE; + delete cleanEnv.CLAUDE_CODE_ENTRYPOINT; + + // Ensure node is findable by SDK subprocess (cli.js uses #!/usr/bin/env node) + const nodeBin = path.dirname(process.execPath); + const currentPath = cleanEnv.PATH || '/usr/local/bin:/usr/bin:/bin'; + const enrichedPath = currentPath.includes(nodeBin) + ? currentPath + : `${nodeBin}:${currentPath}`; + const env: Record = { - ...process.env as Record, + ...cleanEnv, + PATH: enrichedPath, TZ: TIMEZONE, HOME: os.homedir(), // Path configuration for the runner @@ -200,9 +209,7 @@ function prepareGroupEnvironment( 'CLAUDE_THINKING_BUDGET', 'CLAUDE_EFFORT', ]) { - const val = - envVars[key as keyof typeof envVars] || - process.env[key]; + const val = envVars[key as keyof typeof envVars] || process.env[key]; if (val) env[key] = val; } } @@ -294,9 +301,7 @@ export async function runContainerAgent( if (onOutput) { parseBuffer += chunk; let startIdx: number; - while ( - (startIdx = parseBuffer.indexOf(OUTPUT_START_MARKER)) !== -1 - ) { + while ((startIdx = parseBuffer.indexOf(OUTPUT_START_MARKER)) !== -1) { const endIdx = parseBuffer.indexOf(OUTPUT_END_MARKER, startIdx); if (endIdx === -1) break; @@ -405,8 +410,7 @@ export async function runContainerAgent( const timestamp = new Date().toISOString().replace(/[:.]/g, '-'); const logFile = path.join(logsDir, `agent-${timestamp}.log`); const isVerbose = - process.env.LOG_LEVEL === 'debug' || - process.env.LOG_LEVEL === 'trace'; + process.env.LOG_LEVEL === 'debug' || process.env.LOG_LEVEL === 'trace'; const logLines = [ `=== Agent Run Log ===`, diff --git a/src/db.ts b/src/db.ts index 992bb66..602f25f 100644 --- a/src/db.ts +++ b/src/db.ts @@ -575,6 +575,7 @@ export function getRegisteredGroup( container_config: string | null; requires_trigger: number | null; is_main: number | null; + agent_type: string | null; } | undefined; if (!row) return undefined; @@ -597,6 +598,7 @@ export function getRegisteredGroup( requiresTrigger: row.requires_trigger === null ? undefined : row.requires_trigger === 1, isMain: row.is_main === 1 ? true : undefined, + agentType: (row.agent_type as RegisteredGroup['agentType']) || undefined, }; } @@ -605,8 +607,8 @@ export function setRegisteredGroup(jid: string, group: RegisteredGroup): void { throw new Error(`Invalid group folder "${group.folder}" for JID ${jid}`); } db.prepare( - `INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger, is_main) - VALUES (?, ?, ?, ?, ?, ?, ?, ?)`, + `INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger, is_main, agent_type) + VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`, ).run( jid, group.name, @@ -616,6 +618,7 @@ export function setRegisteredGroup(jid: string, group: RegisteredGroup): void { group.containerConfig ? JSON.stringify(group.containerConfig) : null, group.requiresTrigger === undefined ? 1 : group.requiresTrigger ? 1 : 0, group.isMain ? 1 : 0, + group.agentType || 'claude-code', ); } @@ -629,6 +632,7 @@ export function getAllRegisteredGroups(): Record { container_config: string | null; requires_trigger: number | null; is_main: number | null; + agent_type: string | null; }>; const result: Record = {}; for (const row of rows) { @@ -650,6 +654,7 @@ export function getAllRegisteredGroups(): Record { requiresTrigger: row.requires_trigger === null ? undefined : row.requires_trigger === 1, isMain: row.is_main === 1 ? true : undefined, + agentType: (row.agent_type as RegisteredGroup['agentType']) || undefined, }; } return result;