fix(host-service): honor agent config env in ACP chat sessions
What & why
Fixes #9505.
ACP chat sessions ignored the agent config they were launched with: only harness reached the chat runtime, so every chat ran on the default account's env, and custom configs that run claude/codex were rejected for chat. Two Claude accounts (separated by CLAUDE_CONFIG_DIR per agent config) could run as terminals side by side but not as chats.
Changes:
- protocol (
packages/chat): optionalagentConfigIdoncreateSessionInputSchema(additive). - chat-runtime: nullable
agent_config_idcolumn (0004_session_agent_config, generated with drizzle-kit), stored on the session row and passed inHarnessFactoryOptions. Resume without an explicit id inherits it from the replaced session / latest row for that harness session; fork and rewind copy it. - host-service:
buildChatAgentEnvlayersagentLaunchEnv(config)over the default-account env (same precedence as terminal launches; ambientANTHROPIC_*keys are still stripped, a key set in the config survives).captureSessionAccountnow sees the right config dir.chatLaunchTargetreturns the config id and letscustom*configs whose command isclaude/codexchat as that preset (local helper; sharedresolveAgentLaunchPresetIdand terminal launches untouched).sessions.resumereopens on the stored config when it still exists.
Not in this PR: the desktop chat pane's agent picker still identifies agents by preset id, so chats created from the pane UI keep using the default account (resumed ones keep their stored config). Wiring the config id through the renderer is a follow-up: #9507.
Behavior note: a CLI/host chat with --agent claude now resolves the first claude config and applies its env, matching terminal launches.
How I tested it
- New unit tests:
agentEnv.test.ts(default only / config wins incl. own key / deleted config falls back),agents.test.ts(custom claude & codex chat, customaiderdoesn't),resumeSession.test.ts(persisted, inherited on harness-only resume, null when absent). bun run lintclean,bun run typecheck42/42.bun run test: all touched suites pass. Two unrelated failures in the full run:@superset/shared"recurrence timezone math > walks a BYHOUR list that wraps past midnight" (fails identically on unmodifiedmain), and aPullRequestRuntimeManagertest that passes 48/48 in isolation (flaky).- End-to-end, on a local build of 2.0.6 + this patch (macOS arm64). There were two agent configs, each with its own
CLAUDE_CONFIG_DIR: aclaude-preset config (work account,~/.claude-a) and acustom-preset config that runsclaude(personal account,~/.claude-b). I made one chat per config withsuperset sessions create --local --workspace <ws> --agent <config id> --prompt 'Run: echo $CLAUDE_CONFIG_DIR and reply with only the output.':- Work account chat replied
~/.claude-a. Personal account chat replied~/.claude-b. Before the patch, the work chat printed the default account's dir, and creating the personal chat failed with "cannot be used with ACP chat". - Resume:
sessions closethensessions resumeon the personal chat. The new session kept the sameagentConfigIdand harness session id, its ACP process hadCLAUDE_CONFIG_DIR=~/.claude-b, and the same prompt again replied~/.claude-b. - Both chats were also checked side by side in the app with the same outputs; a redacted screenshot is available on request.
- Not related to this change: the resumed chat came back in "Ask for approval" mode, so its
echoneeded approval, while the first turn ran without a prompt.
- Work account chat replied
Checklist
- PR title follows conventional commits (
type(scope): subject) -
bun run lintandbun run typecheckpass (CI fails on lint warnings too) - "Allow edits from maintainers" is checked on fork PRs
- I have signed the CLA (the bot asks on your first PR)
🤖 Generated with Claude Code
Summary by CodeRabbit
- New Features
- Chats retain their selected agent configuration when resumed, forked, or rewound, including when multiple chats share an agent session.
- Supported custom Claude and Codex agents can launch chats with their configured environment and credentials.
- Session history discovery can use a selected agent configuration.
- Bug Fixes
- Chats without a saved configuration continue to use the default environment when reopened.
- If a saved configuration is deleted or no longer matches the session’s CLI, reopening falls back to the default and displays a notice.
- Other custom agents remain unavailable as chat launch targets.