fix(host-service): seed folder trust through env wrappers
What & why
Part of #9309. Split out of #9310 so each PR carries one change (the env editor stays in #9310).
Agents are often launched as env CLAUDE_CONFIG_DIR=… claude … to run on a second Claude account. In that form folder-trust seeding fails without any message, because resolveTrustFamily only reads the first word of the command (env). Every resume of an automation run then shows the "trust this folder" dialog.
resolveTrustFamily sees through env wrappers (host-service seed-agent-trust.ts)
- A new
unwrapEnvCommandskips a leadingenv(bare or by path, e.g./usr/bin/env), its-i/-u NAME/--unset=NAMEoptions, and any leadingVAR=valuetokens. It reads both the command string andargs, because the settings parser savesenv A=1 claudeascommand: "env"plus args. A raw command string is tokenized withshell-quote(quoted values; stops at the first shell operator). This addsshell-quote1.11.0 to host-service, the version already used by desktop; the lockfile change is two lines. resolveTrustTargetapplies those inline assignments on top of{...defaultAccountEnv, ...config.env}, the same precedence as at launch.env -idrops the inherited env and-uremoves a name from it. Soenv CLAUDE_CONFIG_DIR=/p claudeseeds/p/.claude.json, not the default account's file.
Not in this PR (possible follow-ups):
resolveAgentLaunchPresetIdinpackages/sharedstill uses first-word detection.~inCLAUDE_CONFIG_DIRis not expanded before the trust-filejoin.
How I tested it
Unit tests (next to the existing ones in seed-agent-trust.test.ts):
resolveTrustFamily › sees through env wrappers and inline assignments:env CLAUDE_CONFIG_DIR=/p claude …→ claude;/usr/bin/env+ argsCODEX_HOME=/p A=1 codex→ codex; bareCLAUDE_CONFIG_DIR=/p claude→ claude;env my-agent→ null.seedAgentFolderTrust › seeds the CLAUDE_CONFIG_DIR named by an env wrapper: runs against an in-memory migrated host DB, checks the trust entry lands in the wrapper's profile.claude.json, and that the wrapper wins over a conflictingconfig.env.seedAgentFolderTrust › reads a quoted CLAUDE_CONFIG_DIR from a raw command string: a path with spaces, followed by&& true.resolveTrustTarget › env -i and -u drop the inherited CLAUDE_CONFIG_DIRand› reads env options from a raw command string: also--unset=,--ignore-environment, and-iplus a new assignment. They check resolved paths only and write no files.- The first two tests fail on
main.
Run on this branch (rebased on current main):
cd packages/host-service
bun test src/trpc/router/workspace-creation/shared/seed-agent-trust.test.ts
# 29 pass, 0 fail
bun run typecheck # tsc --noEmit, passes
biome check on the changed files is clean.
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 cubic
Part of #9309. Fixes folder-trust seeding for agents launched through env wrappers, so runs like env CLAUDE_CONFIG_DIR=/p claude ... no longer re-show the "trust this folder" dialog on every resume.
Previously resolveTrustFamily only read the first word of the command (env), so seeding was silently skipped.
resolveTrustTargetnow unwraps a leadingenv(bare or by path), its-i/-u/--unsetoptions, and inlineVAR=valueassignments, applying them on top of the default-account and config env.- Adds
shell-quotetohost-servicefor tokenizing raw command strings.
Not covered: resolveAgentLaunchPresetId in packages/shared still uses first-word detection, and ~ in CLAUDE_CONFIG_DIR is not expanded before joining the trust-file path.
Summary by CodeRabbit
- Improvements
- Workspace setup now recognizes agent providers launched through command wrappers, quoted commands, executable paths, and
.exefiles. - Agent trust settings now account for environment assignments, removed variables, and custom configuration directories when selecting trust targets. This helps trust settings match the agent’s effective launch configuration, including when wrapper options override inherited environment values.
- Workspace setup now recognizes agent providers launched through command wrappers, quoted commands, executable paths, and