- Introduce `@oh-my-pi/omptype` as a new ArkType-compatible schema validation package featuring a lazy JIT runtime, JSON Schema emission, and compatibility adapters.
- Replace `arktype` across workspace packages and test utilities with `@oh-my-pi/omptype`.
- Add benchmark suites, tests, and documentation for the new validation engine and adapters.
- Update workspace build, test runner, and release configurations to include the new package.
- Added the `xd://` virtual device protocol (`internal-urls/xd-protocol.ts`, `tools/xdev.ts`): tools declaring `loadMode: "discoverable"` are unmounted from the request tools array and driven via `read xd://` (list/docs+schema) and `write xd://<tool>` (execute), gated by the `tools.xdev` setting (default on) and inlined into the system prompt.
- Merged the `irc`, `job`, and `launch` tools into a single `hub` tool (`tools/hub/`, `async/job-manager.ts`): messaging keeps `send`/`inbox`/`list`, job control maps to `wait`/`cancel`/`jobs`, process supervision keeps `start`/`logs`/`stop`/`restart`/`describe` with `ps`, and the unified `wait` races background jobs against peer messages; SDK `IrcTool`/`JobTool`/`LaunchTool` are replaced by `HubTool`.
- Removed the hidden `resolve` tool in favor of the `xd://resolve`/`xd://reject`/`xd://propose` resolution devices, auto-including `write` whenever a deferrable tool or plan mode is present.
- Removed the BM25 tool-discovery system: the `search_tool_bm25` tool, the `tool-discovery` module, the `tools.discoveryMode`/`mcp.discoveryMode`/`mcp.discoveryDefaultServers`/`tools.essentialOverride` settings, per-tool MCP selection, and the `mcp_tool_selection` message type.
- Unified tool presentation on `ToolLoadMode` (`essential`|`discoverable`), replacing the custom-tool `xdev?: boolean` opt-out; custom, extension, MCP, RPC host, image-generation, and TTS tools now default to `discoverable`, and added a `satisfies` predicate to `SoftToolRequirement`.
- Removed the standalone `ssh` command tool and `ssh/ssh-executor` (the `ssh://` read/write/search protocol stays), and made `--tools` address hidden built-ins.
- Updated collab-web to render `xd://` dispatches and `hub` op families, dropped the `search_tool_bm25`/`ssh`/`report-finding` renderers, refreshed tool docs and prompts, and migrated the affected tests and changelogs.
- Normalized completed image_generation_call results into assistant image blocks.
- Persisted image bytes through the session blob store and rendered them in live, replay, ACP, proxy, telemetry, and HTML paths.
- Added response normalization, persistence, and TUI rendering regressions.
Fixes#4768
Plan mode records idle IRC deliveries into context without waking a turn,
so an 'irc send await:true' sender was stranded until its wait timeout:
delivery reported injected but no reply could ever be generated. Extend the
existing ephemeral side-channel auto-reply (previously only for mid-turn
recipients with async execution disabled) to the idle plan-mode case — the
second situation where a real reply turn cannot happen in time. No primary
turn is woken; plan-mode convergence stays user-driven.
The deliverIrcMessage eligibility change itself rode in the previous commit
(same-file hunks); this commit carries the bus doc and the regression test:
an awaited idle IRC message in plan mode resolves the sender's bus waiter
via the side-channel reply while the primary loop stays asleep.
Plan-mode convergence (call `ask` or `resolve`) was enforced on only the
non-synthetic `prompt()` return. Every other turn-ending path — `agent.continue()`
drains, the IRC idle wake, and advisor steer delivery — settles via `agent_end`
and bypassed it, so advisor/IRC/follow-on traffic could keep the agent producing
non-converging turns indefinitely (the prompt() recovery wait never returns while
continuations run, and agent-core re-drains late steering/asides before agent_end).
Suppress non-user producers in plan mode: `#routeAdvice` preserves the advisor
card (visible + persisted, no turn) and the idle IRC paths (`deliverIrcMessage`,
`#resumeStrandedIrcAsides`) record into context without waking a turn. User
steers/follow-ups are untouched and still resume planning.
Enforce the decision at the universal `agent_end` terminal settle via a
bounded-retry counter: a plan-mode turn that stops without `ask`/`resolve` gets
the reminder plus a provider-neutral `required` choice (both tools stay
available), up to a fixed cap, then yields to the user. A non-decision tool
answer (e.g. `read`) does not reset the cap, so it cannot loop or silently end
plan mode un-converged; `ask`/`resolve`, a fresh user prompt, or plan-mode exit
reset the counter. Todo-completion reminders are gated off in plan mode so they
cannot re-wake a turn the cap intends to yield. Removes the now-redundant
post-`prompt()` enforcement to keep a single policy.
Op: correct
Restores: spec:plan-mode turns must converge to ask/resolve or yield after bounded reminders