resolveWorkerSpawnCmd no longer pins the host-entry worker cwd to the
install dir; the subprocess inherits the agent cwd (or the package root
under the bun-test fallback). Update the chdir rationale accordingly.
The matcher compares selector ids case-insensitively, but the lock's
bundled-catalog lookup was exact-case: Anthropic/Claude-Opus-5 exact-
matched OpenRouter's flat id while getBundledModel("Anthropic", ...)
missed, silently re-enabling the aggregator shadow the lock exists to
prevent. Scan the named provider's bundled ids case-insensitively.
- Add the `providers.cacheRetention` setting to control prompt-cache retention options per request.
- Forward configured cache retention preferences through the settings-aware stream function.
- Update documentation and test coverage for long cache retention behaviors.
organizeImports sorts the type GeneratedProvider specifier ahead of the named imports, and the formatter collapses the preferred-match arrow chain to one line. Both are biome safe fixes; no behavior change. Resolves the two biome errors that were leaving the 8833 branch's check gate red.
Apply the same recursive placeholder expansion used by native MCP configs before extension-package servers are validated and surfaced. This prevents stdio credentials and remote headers from reaching servers as literal placeholders.\n\nSolves: Extension-package MCP environment expansion\nTests: bun test packages/coding-agent/test/discovery/omp-plugins.test.ts
Keep host-specific secret injection in the maintained plugin layer instead
of carrying a behavioral divergence in the OMP fork.
Solves: Unwanted fork maintenance for MCP injection
Tests: Reverts only drycode/oh-my-pi PR #1
Claude marketplace plugins may reference runtime secrets in stdio
server environment values. Resolve those placeholders after plugin-root
substitution so child processes receive credentials instead of literal
template strings.
Solves: Stdio MCP credentials remain unexpanded
Tests: Claude plugin discovery tests; coding-agent check; live CH auth
The idle watchdog aborts the request signal and cursor.ts closes
the Connect stream, so there is no in-flight server exec to race.
Unmarked MCP/todo blocks can continue once every emitted call has
a matching result, same as HTTP/2 RST.
Workers spawned via resolveWorkerSpawnCmd ran with cwd anchored at the CLI
install directory and shared the agent's foreground process group. Terminal
cwd heuristics such as kitty's new_tab_with_cwd read the newest process in
that group, so new terminal tabs opened in
~/.bun/install/global/node_modules/@oh-my-pi/pi-coding-agent/dist while any
worker was alive. Spawn workers with the absolute host entry and inherit the
agent cwd instead; the bun-test fallback branch keeps its cwd-relative form.
browseHtmlPage wrapped its navigations in untilAborted(signal) but awaited
applyViewport, applyStealthPatches, and the finally-block page.close() raw.
When the shared headless daemon or the page target dies mid-setup, those
puppeteer calls never settle: the search hard timeout fires into a signal
with no listener at those await points, the provider promise hangs past
SEARCH_HARD_TIMEOUT_MS, and the turn never ends (only kill -9 recovers).
- Wrap applyViewport/applyStealthPatches in untilAborted(signal) so the
existing hard timeout can abort a dead-session setup.
- Bound the teardown page.close() with a fresh 5s deadline; .catch() only
covers rejection, not a hang, and the caller signal may already be fired.
Fixes#8865
The exact-echo check used accent-insensitive compare, but the collision
suffix path was a case-sensitive startsWith. AuthLoader-3 vs authloader
therefore leaked through as a real description.
The first HUD commit hid Name: Name. The cause was earlier: task
name was copied into identity.label, which became progress.description
and skipped generateTaskLabel. Keep the handle for id allocation, but
only treat eval label as a real UI description so the tiny-model
summary can run.