- Replaced single-provider preferences with ordered priority lists for web search and image generation.
- Added a `MultiSelectSubmenu` component supporting toggle and reordering interactions in settings.
- Implemented migration logic to convert legacy single-provider preferences into ordered priority lists.
- Updated setup wizard scenes, image generation fallback logic, and search provider chains to use priority lists.
Gated the read.renderMarkdown opt-in at read time (details tagging) instead
of inside the renderer. The renderer gate silently flipped every
protocol-supplied text/markdown read (skill://, pr://, issue://, history://,
rule://, omp://, agent://, vault://, local://, memory://, ssh://) from the
formatted markdown cell to the raw code cell when the setting was off, which
regressed default TUI behavior. Local file tagging now happens only when the
setting is enabled, so the default render path is byte-identical to the
pre-setting behavior while opt-in previews still work end-to-end.
Also inlined the tautological isMarkdownContentPath wrapper, pinned the
widened prose-summary bypass (.mdx stays verbatim when prose summaries are
off) with a test, and documented it under Changed in the changelog.
Tested the shell-control guard against the raw command: whitespace
normalization collapsed newlines/CR before the guard ran, so
'git status\nrm file.txt' rode a 'git *' allow rule while bash executed
both lines. Honored tool-owned allow/prompt policies in yolo mode so
per-command prompt rules were no longer silently discarded under the
default approvalMode. Added precision regression tests through the real
matcher (separators, subshells, redirects, env prefixes, path/quoting
variants) that fail on the unfixed head.
When FIRECRAWL_API_KEY is not set, fall back to Firecrawl keyless mode
(omit Authorization header). Auto-chain still requires a credential via
isAvailable; explicit webSearch: firecrawl works keyless via
isExplicitlyAvailable returning true.
Closes https://github.com/can1357/oh-my-pi/issues/4332
- Implemented native UTF-16 text processing in Rust diff module with support for unpaired surrogates.
- Removed `similar` crate from Rust workspace and `diff` npm package from coding-agent, hashline, and natives.
- Removed jsdiff fallback wrappers and `isWellFormed()` guards from TypeScript diff implementations.
- Added comprehensive test suite for native diff functions covering random inputs and edge cases including surrogates and emoji.
- Renamed model `codex-auto-review` to `gpt-5.3-codex-spark` with updated pricing and context window.
- logger-multiprocess asserted the UTC day (toISOString) while DailyRotateFile names files with the LOCAL date, failing nightly between 00:00 and 02:00 local (UTC+2); the per-pid rotation-file invariant now matches any dated name.
- kimi-code k3 bundled compat moved to thinkingFormat 'kimi' with the catalog regen; the K3 named-tool-choice downgrade gate keys on provider/id/baseUrl, so only the stale precondition needed updating.
A for:"ready" wait woke on any terminal state, but reported timedOut:false even
when readiness was never observed — the only success signal on the wait result —
so callers could chain work against a dead process. Split the wake predicate
from the ready-observed check: the wait still wakes on a terminal exit, but
timedOut now reflects whether readiness was actually observed (readyAt, live
ready, or a running daemon with no ready spec).
Fixes#6303
The model-facing start content reported when a process exited before readiness,
but launchRenderResult rebuilt the interactive result solely from structured
details and dropped that explanation. Mirror the terminal-without-readyAt
condition in the TUI start renderer and add a renderer contract test.
Fixes#6303
readyAt/readyMatch belong to the exited generation but were only reset by
#launch, which runs after the restart backoff delay. During the "restarting"
window the sticky-marker predicate from the prior commit therefore reported a
dead service as ready, letting start and for:"ready" waits race it. Clear both
markers when #settle enters "restarting"; #launch re-sets them once the new
child is up. Adds a regression test that observes the backoff window.
Fixes#6303
hub start and for:"ready" waits polled the live daemon state, so a process
that flipped starting→ready→exited within one 50ms poll interval was only
ever observed as "exited" and the wait blocked for the full readiness
timeout — despite #markReady durably recording readyAt. A pre-ready exit
had the same failure since terminal states only woke the wait during broker
shutdown.
Wake both waits on readyAt !== undefined || terminalState(state); readyTimedOut
= !ready then falls out. The start renderer reports "Process exited before
readiness was observed." for a pre-ready exit. Adds two regression tests that
hang to their caps on the old code.
Fixes#6303
clampTimeout resolved the per-tool default (bash 300s) whenever the agent
omitted `timeout` and only enforced the tool's own min/max, so the
tools.maxTimeout global ceiling — applied solely in sdk.ts on explicitly
numeric args — was bypassed on the common default-fallback path.
Thread maxTimeout into clampTimeout so the resolved effective timeout,
including the default path, is capped before the per-tool floor/ceiling
apply. Explicit values below the cap still win; maxTimeout <= 0 stays
no-cap. Applied at every call site (bash, eval, browser, debug, lsp,
fetch, and the session-level bash executor), and the bash clamp notice
now names the global ceiling when it is the binding limit.
Fixes#6294
- Removed the once wrapper from Puppeteer's request emitter on first fire so it cannot leak into later runs.
- Added regression coverage asserting a fired once handler leaves zero residual request listeners.
Fixes#6004
- Removed run-scoped Puppeteer request handlers and disabled interception on every browser.run exit path.
- Recycled workers when bounded interception cleanup cannot restore the tab, with raw CDP recovery for held requests.
- Added live Chromium coverage for held requests, normal traffic restoration, and thrown setup calls.
Fixes#6004
- Added bare `eN`/`@eN` regex to `parseAriaRefSelector` so agents can copy refs straight from snapshot output.
- Applied ref resolution to `press`, `screenshot`, `drag`, `select`, and `uploadFile` action handlers.
- Fixed `#select` to assign the full option set first then read back, avoiding double-counting when unselecting mid-loop.
- Validated the openai-codex credential origin against the registry storage that supplies the bearer, closing the OAuth-leak path when authStorage and modelRegistry diverge.
- Added a regression test covering the mismatched storage case.
Fixes#6001
- Routed Codex web search through configured Responses base URLs, API keys, and headers while preserving the official OAuth backend.
- Refused OAuth leakage to custom endpoints and stopped explicitly selected providers from silently falling back.
- Added transport, safety, and fail-closed regression coverage.
Fixes#6001
- Reported the spawned PTY child PID through the native start callback.
- Replaced broker PID-file polling with the authoritative spawn event.
- Covered finite PTY startup without the legacy handoff in integration tests.
Fixes#5996
Resolved tool interruptibility from each call's raw arguments so mixed-operation tools can keep side-effecting calls non-interruptible.
Restricted the unified hub to interrupt passive waits and followed logs while preserving start, send, and lifecycle operation results.
Fixes#5995
- 33d66643d removed the process-local URL response cache (#5803) but left
two fetch-kagi-toggle tests asserting the old reuse contract.
- Deleted the obsolete repeated-read reuse test (refetch behavior is
covered by fetch-raw-mode and search-url-paths regressions) and kept
the offset/limit selector contract without the no-network assertion.
- Replaced the losing Bun.sleep with an unrefed timeout cleared in a finally block.
- Added regression coverage that verifies prompt wheel acknowledgements leave no timer behind.
Fixes#5905
- Released tab.scroll after two seconds when a queued wheel event waits on a busy renderer acknowledgement.
- Preserved immediate dispatch failures and added regression coverage for both outcomes.
Fixes#5905