Restricted MSYS and WSL drive alias normalization to forward-slash roots so native Windows root-relative paths like \d\logs stay on the current drive.
Fixes#2634
Mapped MSYS and WSL drive aliases before bash cwd validation and brush filesystem resolution so cd, stat-style tests, and tool cwd handling agree on Windows.
Fixes#2634
- Added `WorkerInbox` and `installWorkerInbox(port)` to queue worker messages before bind.
- Added `consumeWorkerInbox()` to replay buffered messages and clear one active inbox.
- Added buffered inbox consumption in JS and tab worker transports before direct message handlers.
- Normalized worker selector arguments to the `__omp_worker_*` naming across workers and tests.
- Added an `interruptible` field to AgentTool and documented when it is honored.
- Updated immediate-mode tool execution to poll steering during in-flight interruptible calls and abort them when steering is queued.
- Marked the coding `job` tool as interruptible and added tests covering mid-wait aborts versus boundary-only steering drain.
- Updated `init` handling to build a single-phase list from `items` when `list` is absent, using `phase` if provided or defaulting to `Tasks`.
- Kept the existing init validation behavior by emitting `Missing list for init operation` only when neither `list` nor `items` was supplied.
- Added tests for flattened init forms, including implicit phase defaulting, explicit phase use, and the missing-input error case.
- Added model-to-syntax mapping in catalog with preferred tool-call syntax API.
- Added `ToolExample` typing and `ToolCallSyntax` exports across tool/grammar interfaces.
- Added syntax-aware tool example rendering through provider-specific grammar invocations.
- Added `exampleSyntax` context flow and example metadata so rendered prompts include examples.
- Added a `truncateFrom` option to `TreeListOptions` supporting `start` and `end` modes, defaulting to `end`.
- Updated `renderTreeList` to compute candidate items and summary placement based on truncation direction.
- Set the todo list renderer to use start-side truncation so collapsed todo output shows the tail entries first.
- Tracked seen-line provenance in snapshots and propagated it from read/search/ast-grep rows.
- Rejected hashline edits on unseen lines before patching, throwing unseen-line errors.
- Rejected single-line block anchors in strict mode and dropped them in unresolved lenient mode.
- Trimmed one-sided keeper-echo duplicates during multi-line replacements with warning output.
- agent-loop: raise repetition-detection floor to 180 chars and clear thinking
replay anchors when collapsing a detected loop.
- providers/google: ignore empty text parts, retain terminal thoughtSignatures,
and stop function-call signatures clobbering the prior block.
- autolearn: capture goal-mode at the turn boundary; harden managed-skill writes
against hard-links/symlinks (O_NOFOLLOW + nlink); refuse minting managed skills
whose name an authored skill already claims.
- eager tasks: thread agentKind through the session so a custom top-level agentId
still gets always-mode delegation; split Eager Tasks prompt into hard vs soft.
- title-generator: race the online title model against a local tiny-model fallback.
- eager-todo: keep the soft reminder aligned with the todo init schema.
- mcp/stdio: keep close() detaching the read loop instead of awaiting it.
- stream loop: fix collapsing and tool-call thought-signature handling.
- Added unified `omp setup speech` flow with JSON/check modes and model picker.
- Added local STT pipeline with sherpa workers, recorder/download flow, and streaming inference.
- Added local TTS pipeline with `omp say`, backend selection, and streaming vocalization.
- Replaced legacy speech settings with unified `speech`/`speechgen` configuration keys.
Unwrap bracketed [path#TAG] headers at the top of WriteTool.execute() so internal-URL detection, plan-mode guard, plan path resolution, and ACP bridge routing all see the same filesystem target. Without this, ['/data/workspaces/can1357__oh-my-pi__2472/.omp-session/2026-06-13T20-19-47-341Z_019ec2a3-fc0d-7000-b1e6-25831d3c3ec5/local/scratch.md' slipped past isInternalUrlPath() and was bridged to the editor instead of staying on disk as a session-local artifact.\n\nFixes #2472
- learn (mnemopi): `rememberScoped` returns undefined when the retain failed
(closed DB / disk error). The tool ignored it and reported "Lesson stored"
(and could still mint a skill), silently losing the lesson. Mirror
`mnemopiBackend.save` and fail loudly when no id is returned.
- manage_skill: enforce the action/field contract in the schema via a cross-field
refine (create/update require description+body; delete needs only name) instead
of relying solely on a runtime throw in execute. Kept as a refine, not a
discriminated union, so the wire schema stays a single root object — both
strict structured-output mode and the Anthropic tool-schema builder require
that.
Addresses review threads on PR #2542 (threads 19, 14).
The `manage_skill`/`learn` force-include and `isToolAllowed` gates only
checked `autolearn.enabled`, not session depth. A subagent created with an
explicit `tools:[...]` whitelist (which runs `approvalMode: "yolo"`) would
silently gain write-capable tools that can mutate `~/.omp/agent/managed-skills`.
The auto-learn controller only runs for top-level sessions, so gate both the
force-include and `isToolAllowed` for `manage_skill`/`learn` to `taskDepth === 0`.
Also tidies the gating test file: drop a module-level `Bun.env` mutation that
was never restored (the test runner skips the Python preflight already) and a
no-op `afterEach` homedir spy in a block that never mocks homedir. Adds a
subagent-exclusion test.
Addresses review threads on PR #2542 (threads 2, 3, 8, 16).
- Added a smart poll-wait mode to AsyncJobManager with per-owner escalation ladder logic and a reset timer for idle pauses.
- Updated job polling to use the adaptive wait when `async.pollWaitDuration` is `smart` and to record poll completion timing for subsequent waits.
- Expanded async job settings and tests so `smart` is the default option and escalation, reset, and owner isolation behavior are covered.
The `learn` tool previously required a `hindsight`/`mnemopi` backend. It now
also works when `memory.backend` is `local` (the file-based rollout backend):
lessons append to a `learned.md` under the project's memory root, kept separate
from the consolidation artifacts so a consolidation pass never clobbers them,
and are injected into future sessions alongside the memory summary.
- memories: `saveLearnedLesson` (newest-first, deduped, count- and per-field
size-capped, secret-redacted, injection-neutralized) with per-path write
serialization; `buildMemoryToolDeveloperInstructions` reads `learned.md` and
shares one injection budget with the summary; `redactSecrets` extended with
GitHub/npm/Slack/Google token prefixes.
- local backend: implements `save()`; status reports `writable: true`.
- learn tool: `local` execute branch; `createIf`/`isToolAllowed`/auto-include
and the standing guidance extended to `local`; local saves tier as a `write`
approval.
- read-path prompt: renders the learned-lessons block when present.
- Lessons are injection-neutralized and secret-redacted on BOTH write and read
(they render unescaped into the system prompt).
Also moves the auto-learn CHANGELOG entry out of the released [15.12.6] section
(a cherry-pick artifact) back under [Unreleased] and notes the local backend.
Tests: local storage (format, dedup, cap, redaction incl. provider/delimiter-
split tokens, concurrency), read-back (with/without summary, off-gating, raw
hand-edited file), tool gating + write-approval tiering.
Add a default-off "auto-learn" loop. When `autolearn.enabled` is set, after the
agent stops a session controller nudges it to capture reusable lessons: durable
facts go to long-term memory and repeatable procedures become "managed skills" —
SKILL.md files written to an isolated ~/.omp/agent/managed-skills directory that is
discovered and surfaced like authored skills but never overwrites them.
Two tools back this:
- `manage_skill` — create/update/delete managed skills.
- `learn` — record a lesson, optionally minting/enhancing a managed skill in the
same call (requires a hindsight/mnemopi memory backend).
The nudge is passive by default (a hidden reminder rides the next turn);
`autolearn.autoContinue` instead auto-runs one capture turn at stop, and
`autolearn.minToolCalls` (default 5) gates trivial turns. Plan/goal-mode turns and
subagents are never nudged, and the controller re-checks the live setting at fire
time so a mid-session opt-out takes effect.
Isolation & precedence: managed skills are a separate lowest-priority discovery
provider, so an authored skill of the same name wins across every provider and
custom directory regardless of third-party toggles; a disabled higher-priority
authored skill can never hide a managed one, and managed never masks an enabled
authored skill. Managed names and descriptions are sanitized on both write and
read (control/format chars, angle brackets, and Markdown fences) before they render
into the system prompt, and the SKILL.md byte cap is enforced on the final
serialized file.
Default off → zero footprint when disabled.
- Added session-domain modules and exports for session-entries, context, listing, loader, and migrations.
- Changed persistence to async append writes plus writeTextAtomic, removing sync line APIs.
- Added compaction-aware session context rebuild with dangling tool-call cleanup.
- Added resumable session resolution with status inference, id/stem/suffix matching, and backup recovery.
Add a display-only `activity` field to AgentRef plus `setActivity`, fed
from the subagent progress chokepoint with a short gist of the agent's
latest intent (or current tool). Render it in the `irc list` output, the
subagent peer roster, and the TUI peer card, beside the role-derived
display name. setActivity emits no event — the roster reads on demand —
so the per-tool-call rate stays off the registry listener path. Peers
with no activity render without a dangling clause.
Refs #2470
Op: extend
When a spawner with remaining depth capacity spawns generic role-less
workers (a task/quick_task spawn without a `role`, or the same agent
cloned >=2x all without roles), TaskTool.execute appends a non-blocking
advisory steering it toward tailored specialists. Gated on DepthCapacity
so a leaf at max recursion is never nudged; the task-tool depth gate is
extracted into a shared `canSpawnAtDepth` helper reused by both the tool
gate and the advisory.
Refs #2469
Op: extend
- Added a reusable notice constant for executable write operations.
- Appended the executable notice to write-result output whenever a file was made executable.
- Extended gateway stream control to pass abort signals and onCancel into encodeStream.
- Added optional cancellation control parameters to provider encodeStream handlers.
- Stopped provider stream loops on cancellation and suppressed SSE completion/error output after abort.
- Added a regression test verifying reader.cancel triggers onCancel and aborts upstream request.
- Added cmux browser mode options and resolved mode selection from env and app flags.
- Added cmux tab operations for navigation, JS execution, observations, and screenshots.
- Added CMUX socket client messaging with auth, timeouts, and ordered request dispatch.
- Updated browser docs and examples to describe cmux behavior, selectors, and API limits.
- Added getActiveModel support to session/tool interfaces for propagating active model objects.
- Added model capability helpers to flag WebP-unfriendly Ollama backends for image resize options.
- Updated image normalization and loading to auto-disable/reencode WebP when model constraints require it.
Concurrent omp --session restores after an unclean shutdown crashed
in SqliteAuthCredentialStore.#initializeSchema() with
SQLITE_BUSY_RECOVERY because the multi-statement schema run installed
PRAGMA busy_timeout=5000 AFTER PRAGMA journal_mode=WAL, the first
lock-taking statement during WAL recovery. Bun's default busy_timeout
is 0, so the lock conflict surfaces immediately.
- packages/ai/src/auth-storage.ts: hoisted PRAGMA busy_timeout to a
standalone first statement, dropped it from the multi-statement
schema run, wrapped SqliteAuthCredentialStore.open() in a 4-attempt
exponential-backoff retry loop on the SQLITE_BUSY family, and the
exhausted-retry error now includes the DB path. Exported
isSqliteBusyError(err) (matches code prefix 'SQLITE_BUSY').
- packages/coding-agent/src/session/agent-storage.ts: same hoist and
the existing retry loop now uses isSqliteBusyError so
SQLITE_BUSY_RECOVERY / _SNAPSHOT / _TIMEOUT also trigger backoff.
- Hoisted busy_timeout before journal_mode=WAL in every other shared
SQLite open path: history-storage, autoresearch/storage,
memories/storage, github-cache, report-tool-issue (auto-QA),
catalog/model-cache; stats/db.ts now sets busy_timeout at all.
- packages/ai/test/auth-storage-sqlite-busy.test.ts pins the contract:
isSqliteBusyError matches every BUSY extended code (rejects
SQLITE_LOCKED, non-errors, strings); open() leaves the connection in
WAL mode (proves busy_timeout ran before journal_mode); open() retries
through synthetic SQLITE_BUSY_RECOVERY; non-BUSY errors (SQLITE_CORRUPT)
short-circuit; exhausted retries throw an error mentioning the DB path
with exactly 3 sleeps for a 4-attempt budget.
Fixes#2421
Format multi-line, tab-indented AST patterns by collapsing whitespace
to single spaces, preventing them from distorting the single-line status
description in the UI.
- Added optional `useless` flags to tool result types and payload builders.
- Added `pruneUseless` and `dropUeless` options to control uneventful result pruning.
- Changed compaction and shake passes to prune or ignore non-error useless tool results.
- Changed conversation serialization to omit useless toolCall/toolResult pairs from output.
- Added coverage for useless tagging, pruning, and serialization behavior.
- Added `packages/collab-web/src/tool-render/`: a per-tool React renderer suite (one view per built-in tool) with common `ToolView` chrome, a `tv-` CSS design system, a registry, and an `<omp-tool-view>` web-component wrapper (`element.tsx`, `standalone.tsx`).
- Switched collab-web transcript `ToolCard` to the per-tool renderers instead of the generic args/result JSON dump, and threaded a `ToolRenderHost` through `Transcript`/`AgentDrawer`/`app.tsx` so task-card agent chips drill into the matching subagent drawer.
- Added `scripts/build-tool-views.ts` plus the `build:tool-views` script bundling the renderers (React included, `</script` escaped) into the gitignored `coding-agent/src/export/html/tool-views.generated.js`.
- Modernized the coding-agent HTML export chrome in `template.html/css/js` to the tool-card design language and added the `<template-tool-views/>` injection point.
- Showed the standard done checkmark for completed rows in the `job` tool renderer; its changelog line shares a changed run with the restyle entries.
- The session-operations doc gained two adjacent lines; the subagent-transcript one belongs to the upcoming /share commit but is inseparable from the tool-view line.
- Changed collapsed progress rendering to keep the most recent live agents visible, adding a summary line for folded-away rows.
- Updated collapsed result rendering to preserve failed and aborted agents in the visible set while trimming other completions.
- Refreshed job polling text to document waiting on all running jobs when `poll` is omitted and added tests for both collapsed progress and result display behavior.
Individual conflict resolution now bypasses the LSP writethrough to prevent formatting from corrupting other unresolved marker blocks and to avoid noisy diagnostics in partially resolved files.
- Recomputed `tools.discoveryMode: "auto"` in the deferred MCP closure in `sdk.ts` once the real tool count is known: a toolset crossing the threshold now flips discovery on, registers and activates `search_tool_bm25`, and skips `activateAll` instead of force-activating every MCP tool.
- Guarded the deferred MCP task against disposed sessions: added `AgentSession.isDisposed` and `enableMCPDiscovery()`, and the late connect now calls `disconnectAll()` instead of refreshing tools onto a dead session.
- Cleared `#fastPathKey`/`#fastPathItems` in `AssistantMessageComponent.invalidate()` so theme/symbol changes rebuild reused Markdown children instead of keeping stale captured themes.
- Memoized unusable read summaries as a `false` sentinel in `read.ts` so the per-session LRU no longer retains full sources of unsummarizable files.
- Broadened `HAS_REF_DEF` in `markdown.ts` to match backslash-escaped reference labels (`[a\]b]: x`) and cleared frozen stream-lex state on blank `setText()`.
- Added regression tests: deferred auto-discovery flip and mid-connect dispose (`sdk-mcp-auto-discovery.test.ts` + `many-tools-mcp.ts` fixture), fast-path child rebuild on invalidate, and escaped-ref-def incremental-lex equivalence.
- Added `ToolRenderer.provisionalPendingPreview` in `renderers.ts` and consulted it from `ToolExecutionComponent.isTranscriptBlockCommitStable`, replacing the 15.11.6 blanket gate that marked every collapsed pending preview commit-unstable.
- Marked only the tail-window previews the result render re-anchors as provisional: the edit streamed-diff tail (`edit/renderer.ts`), bash/ssh command caps (`createShellRenderer`, `sshToolRenderer`), and eval cells with interleaved outputs (`evalToolRenderer`).
- Restored mid-stream scrollback commits for every other pending preview, so tool calls taller than the viewport (e.g. a task call's context/assignment markdown) no longer read as cut off until the result lands.
- Added a regression test in `tool-live-region-scrollback.test.ts` scroll-appending a tall collapsed streaming task call into native scrollback mid-stream.