4e4e74be49
Addresses the codex review comments on #1015 plus a sweep of adjacent ACP conformance gaps surfaced while wiring them up. Tool call + diff metadata - acp-event-mapper: thread session cwd through and resolve every `ToolCallLocation` (initial args, in-flight updates, result details) to absolute paths against it; ACP requires absolute paths for client-side file mapping. - edit/modes/patch: emit the destination path for moves in the diff result so post-edit "open file" actions land on the new file. Permissions - agent-session: pass cwd into `extractPermissionLocations` and resolve raw `path`/`file`/etc. fields against it before sending `session/request_permission`. - agent-session: gate the permission wrapper on `bridge.capabilities.requestPermission && bridge.requestPermission`, matching the read/write/bash capability+method pattern. acp-agent - `authenticate`: validate `methodId` against the methods advertised by `initialize` and reject anything else, so malformed clients fail fast. - `setSessionConfigOption(MODE_CONFIG_ID)`: also emit `current_mode_update` so clients tracking `modes.currentModeId` see the same transition `session/set_mode` would produce. - Pass `runtime.notifyConfigChanged` to builtins; emit `available_commands_update` from a shared `reloadPlugins` helper reused by `/reload-plugins`, `/marketplace`, and `/plugins`. - prompt resource handling: route `resource` content with `image/*` MIME into the `images` array instead of dropping it as an opaque blob; non-image blobs still fall back to the URI placeholder. - pass session cwd to the event mapper. Builtins - model: call `runtime.notifyConfigChanged()` after a successful `setModel` so the ACP config selector reflects the new model immediately. - mcp: redact query strings and userinfo from MCP server URLs before emitting them in `/mcp list` (prevents leaking `?exaApiKey=…` style secrets); wire `manager.setAuthStorage(...)` before `prepareConfig` in `/mcp test|resources|prompts` so OAuth servers can refresh tokens. - ssh: reject non-integer `--port` values via a `^\d+$` guard instead of silently coercing through `Number.parseInt`; list project hosts first and dedupe user-scope duplicates to match capability-loader precedence. - export: reject clipboard aliases (`--copy`, `clipboard`, `copy`) before passing them to `exportToHtml` as a filename. - compact / force / move / browser: surface underlying failures via `usage(errorMessage(...))` instead of letting them crash the command. - session save|delete: route through the active SessionManager so the persist writer is consulted and stale storage references are removed. - marketplace / plugins / reload-plugins: call `runtime.reloadPlugins()` on install/uninstall/upgrade and enable/disable so slash command registries and command lists refresh consistently. - shared.usage: make async and `await runtime.output(...)` so `sessionUpdate` text is never dropped or reordered. - types: document the new `reloadPlugins` and `notifyConfigChanged` runtime hooks. bash tool - Use a shared `fireKill()` from the abort listener so `session/cancel` terminates the remote command immediately instead of waiting for the next `currentOutput()` round trip. - Race `currentOutput()` against the abort signal so a stuck `terminal/output` RPC cannot delay cancellation. - Kill the terminal before reading final output on timeout so a slow output read cannot let a timed-out command keep running past the enforced timeout. Tests - acp-agent.test: extend the existing config-option assertions to verify both `model` and `thinking_level` changes emit `config_option_update` notifications scoped to the right session. - acp-builtins.test: cover `/model` emitting both `notifyTitleChanged` and `notifyConfigChanged`; lock in the parsed `mcp add` / `ssh add` call shapes so future arg-parser regressions fail the test instead of silently writing different configs; add a `reloadPlugins` stub plus a typed `notifyConfigChanged` slot to the shared test runtime factory. - acp-stdout-hygiene.test: drain stderr in parallel and assert no JSON-RPC frame leaks onto it; terminate the spawned process so the stderr pump resolves deterministically. CHANGELOG: itemize the above under `[Unreleased] > Fixed`. CI - bun run check: clean (TS + Rust) - bun run test: 4128 pass / 689 skip / 0 fail (TS); 252 pass / 0 fail (Rust nextest) - bun run ci:test:smoke: --version / --help / `stats --help` all OK