After the node early-return, narrow workdir back to string via
resolvedWorkdir for gateway/sandbox paths. Update
buildExecApprovalPendingToolResult and buildApprovalPendingMessage
to accept string | undefined for cwd since node execution may omit it.
When exec runs with host=node and no explicit cwd is provided, the
gateway was injecting its own process.cwd() as the default working
directory. In cross-platform setups (e.g. Linux gateway + Windows node),
this gateway-local path does not exist on the node, causing
"SYSTEM_RUN_DENIED: approval requires an existing canonical cwd".
This change detects when no explicit workdir was provided (neither via
the tool call params.workdir nor via agent defaults.cwd) and passes
undefined instead of the gateway cwd. This lets the remote node use its
own default working directory.
Changes:
- bash-tools.exec.ts: Track whether workdir was explicitly provided;
when host=node and no explicit workdir, pass undefined instead of
gateway process.cwd()
- bash-tools.exec-host-node.ts: Accept workdir as string | undefined;
only send cwd to system.run.prepare when defined
- bash-tools.exec-approval-request.ts: Accept workdir as
string | undefined in HostExecApprovalParams
Fixes#58934
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When a skill constructs a compound command via a shell wrapper
(e.g. `sh -c "cat SKILL.md && gog-wrapper calendar events"`),
the allowlist check was comparing `/bin/sh` instead of the actual
target binaries, causing the entire command to be silently rejected.
This adds recursive inline command evaluation that:
- Detects chain operators (&&, ||, ;) in the -c payload
- Parses each sub-command independently via analyzeShellCommand
- Evaluates every sub-command against the allowlist
- Preserves per-sub-command segmentSatisfiedBy for accurate tracking
- Limits recursion depth to 3 to prevent abuse
- Skips recursion on Windows (no POSIX shell semantics)
Closes#57377
Co-authored-by: WZBbiao <wangzhenbiao326@gmail.com>
Keeps untrusted workspace channel metadata from overriding setup/login resolution for built-in channels. Workspace channel entries are only eligible during setup when the plugin is already explicitly trusted in config.
- Track discovered origin on channel catalog entries and add a setup-time catalog lookup that excludes workspace discoveries when needed
- Add resolver regression coverage for untrusted shadowing and trusted workspace overrides
Thanks @mappel-nv
* fix(agents): pin subagent gateway calls to admin scope to prevent scope-upgrade pairing failures
callSubagentGateway forwards params to callGateway without explicit scopes,
so callGatewayLeastPrivilege negotiates the minimum scope per method
independently. The first connection pairs the device at a lower tier and
every subsequent higher-tier call triggers a scope-upgrade handshake that
headless gateway-client connections cannot complete interactively
(close 1008 "pairing required").
Pin callSubagentGateway to operator.admin so the device is paired at the
ceiling scope on the very first (silent, local-loopback) handshake, avoiding
any subsequent scope-upgrade negotiation entirely.
Fixes#59428
* fix: pin admin-only subagent gateway scopes (#59555) (thanks @openperf)
---------
Co-authored-by: Ayaan Zaidi <hi@obviy.us>