fix: load agentType from DB, fix host process PATH and session resume
- Read/write agent_type column in getAllRegisteredGroups/setRegisteredGroup (was missing, causing all groups to fall back to claude-code) - Strip CLAUDECODE env var to prevent nested session detection - Add node binary path to spawned process PATH for launchd compatibility - Clear stale container-era sessions that reference /workspace/group
This commit is contained in:
@@ -15,10 +15,7 @@ import {
|
|||||||
IDLE_TIMEOUT,
|
IDLE_TIMEOUT,
|
||||||
TIMEZONE,
|
TIMEZONE,
|
||||||
} from './config.js';
|
} from './config.js';
|
||||||
import {
|
import { resolveGroupFolderPath, resolveGroupIpcPath } from './group-folder.js';
|
||||||
resolveGroupFolderPath,
|
|
||||||
resolveGroupIpcPath,
|
|
||||||
} from './group-folder.js';
|
|
||||||
import { logger } from './logger.js';
|
import { logger } from './logger.js';
|
||||||
import { readEnvFile } from './env.js';
|
import { readEnvFile } from './env.js';
|
||||||
import { RegisteredGroup } from './types.js';
|
import { RegisteredGroup } from './types.js';
|
||||||
@@ -116,8 +113,7 @@ function prepareGroupEnvironment(
|
|||||||
|
|
||||||
// Determine runner directory
|
// Determine runner directory
|
||||||
const agentType = group.agentType || 'claude-code';
|
const agentType = group.agentType || 'claude-code';
|
||||||
const runnerDirName =
|
const runnerDirName = agentType === 'codex' ? 'codex-runner' : 'agent-runner';
|
||||||
agentType === 'codex' ? 'codex-runner' : 'agent-runner';
|
|
||||||
const runnerDir = path.join(projectRoot, 'container', runnerDirName);
|
const runnerDir = path.join(projectRoot, 'container', runnerDirName);
|
||||||
|
|
||||||
// Build environment variables for the runner process
|
// Build environment variables for the runner process
|
||||||
@@ -132,8 +128,21 @@ function prepareGroupEnvironment(
|
|||||||
'CODEX_OPENAI_API_KEY',
|
'CODEX_OPENAI_API_KEY',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// Build a clean env without Claude Code nesting detection variables
|
||||||
|
const cleanEnv = { ...(process.env as Record<string, string>) };
|
||||||
|
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<string, string> = {
|
const env: Record<string, string> = {
|
||||||
...process.env as Record<string, string>,
|
...cleanEnv,
|
||||||
|
PATH: enrichedPath,
|
||||||
TZ: TIMEZONE,
|
TZ: TIMEZONE,
|
||||||
HOME: os.homedir(),
|
HOME: os.homedir(),
|
||||||
// Path configuration for the runner
|
// Path configuration for the runner
|
||||||
@@ -200,9 +209,7 @@ function prepareGroupEnvironment(
|
|||||||
'CLAUDE_THINKING_BUDGET',
|
'CLAUDE_THINKING_BUDGET',
|
||||||
'CLAUDE_EFFORT',
|
'CLAUDE_EFFORT',
|
||||||
]) {
|
]) {
|
||||||
const val =
|
const val = envVars[key as keyof typeof envVars] || process.env[key];
|
||||||
envVars[key as keyof typeof envVars] ||
|
|
||||||
process.env[key];
|
|
||||||
if (val) env[key] = val;
|
if (val) env[key] = val;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -294,9 +301,7 @@ export async function runContainerAgent(
|
|||||||
if (onOutput) {
|
if (onOutput) {
|
||||||
parseBuffer += chunk;
|
parseBuffer += chunk;
|
||||||
let startIdx: number;
|
let startIdx: number;
|
||||||
while (
|
while ((startIdx = parseBuffer.indexOf(OUTPUT_START_MARKER)) !== -1) {
|
||||||
(startIdx = parseBuffer.indexOf(OUTPUT_START_MARKER)) !== -1
|
|
||||||
) {
|
|
||||||
const endIdx = parseBuffer.indexOf(OUTPUT_END_MARKER, startIdx);
|
const endIdx = parseBuffer.indexOf(OUTPUT_END_MARKER, startIdx);
|
||||||
if (endIdx === -1) break;
|
if (endIdx === -1) break;
|
||||||
|
|
||||||
@@ -405,8 +410,7 @@ export async function runContainerAgent(
|
|||||||
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
|
||||||
const logFile = path.join(logsDir, `agent-${timestamp}.log`);
|
const logFile = path.join(logsDir, `agent-${timestamp}.log`);
|
||||||
const isVerbose =
|
const isVerbose =
|
||||||
process.env.LOG_LEVEL === 'debug' ||
|
process.env.LOG_LEVEL === 'debug' || process.env.LOG_LEVEL === 'trace';
|
||||||
process.env.LOG_LEVEL === 'trace';
|
|
||||||
|
|
||||||
const logLines = [
|
const logLines = [
|
||||||
`=== Agent Run Log ===`,
|
`=== Agent Run Log ===`,
|
||||||
|
|||||||
@@ -575,6 +575,7 @@ export function getRegisteredGroup(
|
|||||||
container_config: string | null;
|
container_config: string | null;
|
||||||
requires_trigger: number | null;
|
requires_trigger: number | null;
|
||||||
is_main: number | null;
|
is_main: number | null;
|
||||||
|
agent_type: string | null;
|
||||||
}
|
}
|
||||||
| undefined;
|
| undefined;
|
||||||
if (!row) return undefined;
|
if (!row) return undefined;
|
||||||
@@ -597,6 +598,7 @@ export function getRegisteredGroup(
|
|||||||
requiresTrigger:
|
requiresTrigger:
|
||||||
row.requires_trigger === null ? undefined : row.requires_trigger === 1,
|
row.requires_trigger === null ? undefined : row.requires_trigger === 1,
|
||||||
isMain: row.is_main === 1 ? true : undefined,
|
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}`);
|
throw new Error(`Invalid group folder "${group.folder}" for JID ${jid}`);
|
||||||
}
|
}
|
||||||
db.prepare(
|
db.prepare(
|
||||||
`INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger, is_main)
|
`INSERT OR REPLACE INTO registered_groups (jid, name, folder, trigger_pattern, added_at, container_config, requires_trigger, is_main, agent_type)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||||
).run(
|
).run(
|
||||||
jid,
|
jid,
|
||||||
group.name,
|
group.name,
|
||||||
@@ -616,6 +618,7 @@ export function setRegisteredGroup(jid: string, group: RegisteredGroup): void {
|
|||||||
group.containerConfig ? JSON.stringify(group.containerConfig) : null,
|
group.containerConfig ? JSON.stringify(group.containerConfig) : null,
|
||||||
group.requiresTrigger === undefined ? 1 : group.requiresTrigger ? 1 : 0,
|
group.requiresTrigger === undefined ? 1 : group.requiresTrigger ? 1 : 0,
|
||||||
group.isMain ? 1 : 0,
|
group.isMain ? 1 : 0,
|
||||||
|
group.agentType || 'claude-code',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,6 +632,7 @@ export function getAllRegisteredGroups(): Record<string, RegisteredGroup> {
|
|||||||
container_config: string | null;
|
container_config: string | null;
|
||||||
requires_trigger: number | null;
|
requires_trigger: number | null;
|
||||||
is_main: number | null;
|
is_main: number | null;
|
||||||
|
agent_type: string | null;
|
||||||
}>;
|
}>;
|
||||||
const result: Record<string, RegisteredGroup> = {};
|
const result: Record<string, RegisteredGroup> = {};
|
||||||
for (const row of rows) {
|
for (const row of rows) {
|
||||||
@@ -650,6 +654,7 @@ export function getAllRegisteredGroups(): Record<string, RegisteredGroup> {
|
|||||||
requiresTrigger:
|
requiresTrigger:
|
||||||
row.requires_trigger === null ? undefined : row.requires_trigger === 1,
|
row.requires_trigger === null ? undefined : row.requires_trigger === 1,
|
||||||
isMain: row.is_main === 1 ? true : undefined,
|
isMain: row.is_main === 1 ? true : undefined,
|
||||||
|
agentType: (row.agent_type as RegisteredGroup['agentType']) || undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
Reference in New Issue
Block a user