- Synchronize tool arguments with the component state upon receipt of `tool_execution_start` to ensure visual consistency when final update events are missed.
- Terminate active argument reveal streams to prevent late ticks from overwriting valid, fully-materialized tool arguments with stale partial data.
- Add test coverage to verify that tool UI components render finalized arguments even in the absence of intermediate streaming updates.
- Remove the static "pending" hourglass icon from edit and write tool headers to reduce visual noise.
- Update multi-file status lines to use the active spinner icon directly instead of replacing a static icon, ensuring consistent liveness cues.
- Switch all UI components and tests from sharp box corners (`boxSharp`) to rounded ones (`boxRound`).
- Update `Theme` to re-export sharp junction symbols (tees and cross) under `boxRound` to ensure consistent divider rendering in rounded boxes.
- Remove outdated architectural notes regarding forced tool-choice queues in documentation.
- Removed configurable tab width support and the `display.tabWidth` setting across all packages.
- Deleted obsolete utility functions `getIndentation`, `getIndentationNoescape`, and `setDefaultTabWidth`.
- Standardized tab expansion logic to use a fixed `DEFAULT_TAB_WIDTH` globally.
- Cleaned up related configuration schemas, test suites, and internal API signatures to remove path-dependency.
- Hardened the `hashline` parameters parsing pipeline to guarantee presence of the `input` field.
- Enforced input length limits on task roles to secure against oversized payloads.
- Configured Arktype schemas to reject or delete extra, undeclared fields in task and inspect-image payloads.
- Updated mock test parameters to align with corrected success exit codes.
- Migrated all wire protocol, schema definitions, and tools validation from Zod to ArkType across multiple packages.
- Updated extension runtimes, custom tools loader, and TypeBox compatibility shim to expose and use ArkType instances.
- Added a comprehensive ArkType migration guide, validation parity tests, and helper utilities.
- Removed redundant PDF asset routing and parsing implementations from the read tool.
Merge displayed bridge-backed range and multi-range read lines into the existing hashline snapshot provenance so INS.POST anchors pass visible-line validation after ACP reads.
Fixes#2773
- 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.
- Renamed line and block patch op verbs to XCHG, DEL, and INS in parsing and formatting.
- Updated grammar and tokenizer to support XCHG.BLK, DEL.BLK, and INS.PRE/POST/HEAD/TAIL forms.
- Updated diagnostics, docs, prompts, tests, and changelog to use XCHG/DEL/INS-based operators.
- Expanded session-stats parsing to normalize legacy op aliases to compact IDs.
- 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.
- 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.
- Added transcript and assistant block version tracking for finalized segments.
- Changed committed block reuse logic to require prior finalization and same version.
- Fixed rerendering of committed finalized blocks when version values changed.
Two pathologies surfaced in the same captured failure (#2081): a subagent
spent 16 minutes hammering 205 `edit` calls (182 byte-identical no-ops)
against a file that already matched its payload, while a sibling bash
invocation persisted 7.6MB of PowerShell rich-object metadata to
`~/.omp/agent/artifacts/<id>.bash.log` from what was intended as a small
tail. Both are addressed independently here:
- Hashline executor now consults a per-ToolSession `noopLoopGuard` that
hashes the raw patch input and tracks consecutive no-ops per canonical
path. After NOOP_HARD_LIMIT (3) repeats of the same payload the soft
"byte-identical" hint escalates to a thrown ToolError, which the agent
loop surfaces as a tool failure rather than success-with-text — far
more effective at breaking the loop than the soft hint alone. A
non-noop commit (or any variant payload) resets the counter; state is
isolated per ToolSession so subagents cannot inherit each other's
history.
- OutputSink artifact-on-disk writes are now bounded by
`artifactMaxBytes` (default 4 MiB = 3 MiB head + 1 MiB rolling tail).
Once the head budget is exhausted, subsequent chunks divert into a
fixed-size tail ring; `dump()` replays the ring behind a single
`[ARTIFACT TRUNCATED: kept first … + last … of …; … elided from the
middle]` notice before closing the sink. Setting `artifactMaxBytes: 0`
restores the historical unbounded behavior. Sized comfortably above
anything a model would reasonably scroll through via the artifact URL
scheme while preventing the captured 7.6MB spray from sitting on disk.
The terminal-typing lag the reporter observed has multiple compounding
causes (transcript-render freezing is disabled on win32; the bash result
renderer lacks the per-render cache that the eval renderer already has).
Those land in a follow-up — the loop guard + artifact cap address the
root pathologies that turned the session into a multi-MB transcript in
the first place.
Fixes#2081
The streaming-spinner relocation in 61a57c1d2 re-added the trailing
"(preview)" label to expanded approval previews whenever a spinner frame
was active, breaking the #1992 contract. Expanded previews now drop the
label but keep the animated glyph so the volatile tail stays live.
- Separated non-contiguous diff regions with a single blank gap row, normalized after block-context insertion.
- Rendered gap rows as one dim ellipsis in the TUI and HTML export.
- Applied the same blank-separator dedupe and edge-trimming to hashline's compact diff preview.
non-exact patch matches warn and prefix/substring matches must preserve the discarded suffix; multi-entry edits stop at first failure and report applied vs not; ast-edit and file-mention snapshots use canonical realpath keys and re-record post-apply; notebook marker-shaped lines escaped on render; fuzzy matcher pre-normalizes once per seek; streaming preview caches text+tree per tick.
- Tracked cumulative plus/minus line changes to translate new-file context rows to old indices.
- Merged old and translated new block-boundary context rows in one pass to prevent duplicate/out-of-order rows.
- Added status.done and tool.* symbols to theme mappings and presets.
- Replaced generic success glyphs with contextual +/-, tool icons, and warnings.
- Mapped tool/task/job completions to status.done or status.enabled with icon overrides.
- Triggered runtime provider refresh after extension registration and warned on failure.
- Added tree-sitter `enclosing_block_boundaries` API with line range models.
- Added N-API `enclosingBlockBoundaries` bridge and exported JS declarations.
- Replaced matching-bracket context resolution with source-aware block context in read and diff flows.
- Passed source path through diff/read generators to surface native block boundary previews.
- Added matching-bracket utilities to locate partner lines for visible spans.
- Added read tool output to use displayContent text and startLine for bracket-aware previews.
- Added matching-bracket context rows to generateDiffString and generateUnifiedDiffString.
- Adjusted diff row insertion to deduplicate and keep contiguous changed groups together.
- Removed the mid-skip placeholder line that was output when skipping lines in the middle of a diff, relying instead on the line number jump to convey the gap. Removed the corresponding placeholder-filtering logic from the hashline diff preview that was handling these placeholders.
- Added an `insertCursorLine` helper to translate streaming insert cursors into preview line numbers.
- Implemented `buildStreamingSectionDiff` to group resolved edits by operation and emit deletions before insertions, stabilizing streamed cursor progression.
- Updated `computeHashlineSectionDiff` to use the streaming builder when `options.streaming` is enabled, while preserving existing Myers diff behavior for non-streaming paths.
- Added a session-global file mutation counter and accessor methods to tool sessions.
- Updated the write tool to bump a file's mutation version after each write.
- Updated the edit tool to use session-wide mutation versions when checking stale deferred diagnostics.
- Added a BlockResolution type and `onResolved` callback so `resolveBlockEdits` reports each anchor's resolved span for `replace block`/`delete block` edits.
- Updated patch application to return those spans on hash-match applies and omit them during drift-recovery paths where line numbers no longer align.
- Propagated the surfaced spans through the edit tool output and added/updated tests covering replace/delete block echo and drift behavior.
- Added per-path edit versioning in `EditTool` to drop stale late diagnostics after later edits.
- Added deferred diagnostics queueing through `queueDeferredDiagnostics` and late-diagnostic yield batching.
- Updated `UiHelpers` to render late diagnostic file path and summary lines in the chat transcript.
- Trimmed first-changed-line suffixes from edit path display and passed the line as a hyperlink target.
- Added middle-eliding path truncation for edit and rename file labels.
- Simplified diff-stat output to show only added/removed counts in a compact bracketed form.
- Updated `executeToolCalls` to always pass the active `toolSignal` into `tool.execute` rather than bypassing it for non-abortable tools.
- Removed the `nonAbortable` option from `AgentTool` and from the read, write, and edit tools so they can no longer opt out of abort handling.
- Documented the cancellation behavior change in the affected tool docs and package changelogs.
- Added a configurable `contentPaddingLeft` option to `renderOutputBlock` with normalized defaults.
- Updated edit renderer output blocks to disable inherited left padding and align inner-width wrapping.
- Added coverage for completed edit gutter rendering to confirm no leading space and correct frame width.
- Fixed edit/read/search/ast-edit/ast-grep outputs to resolve OSC8 links from session cwd.
- Fixed grouped-file output classification to honor headerBase and fileScope for parent path resolution.
- Fixed read and write renderers to use resolved source/resolved paths as hyperlink targets.
- Unified edit, ask, ast-edit, todo, write, and inspect outputs using framedBlock.
- Wrapped failure and warning cases in framed blocks with clearer status states.
- Standardized frame body rendering by trimming blank lines and clipping content width.
- Simplified tool execution layout by removing dynamic padding and background helpers.
- Updated edit result rendering to inline diff change statistics in the file header instead of using a separate metadata row.
- Removed the redundant standalone metadata line and removed the extra blank line before diff bodies for a tighter single-hunk display.
- Added a test asserting the header now contains +/-/hunk stats and that no extra stats row appears before the diff.
Passed options.expanded through the edit call preview renderer so approval previews can lift the streaming diff tail window and hide the preview label.
Added regression coverage for collapsed versus expanded edit preview rendering.
Fixes#1992
- Replaced `¶path#hash` prefix with `[path#hash]` delimiters across parser, tokenizer, and grammar.
- Updated prompts, docs, and recovery paths to the new bracketed form.
- Added optional `AgentTool.matcherDigest(args)` hook so tools can expose plain source text instead of wire-encoded arguments to TTSR rule matchers.
- Implemented `matcherDigest` on edit (all modes: hashline, patch, apply_patch, replace) and write tools, stripping patch prefixes and JSON escaping.
- Added `TtsrManager.checkSnapshot()` to replace the scoped buffer with a tool digest rather than appending raw deltas.
- Fixed TTSR conditions never matching streamed edit/write calls whose wire format obscured real content.
- Added `DiagnosticsLedger` to track diagnostics already surfaced per file, suppressing repeats within a session.
- Wired dedup into both edit and write tools via a `transformDiagnostics` hook on the writethrough pipeline.
- Added `lsp.diagnosticsDeduplicate` setting (default: true) to control the behavior.
- Preserved hidden tmux overlays in live viewport while keeping native scrollback intact during forced renders.
- Adjusted forced-render handling so pure appends preserve full scrollback and return viewport repaint on equal-size diffs.
- Capped streaming edit diff previews to a fixed trailing window and reported hidden hunk counts.
- Updated tmux and regression tests to validate hidden overlays, nativeText frame sources, and scrollback retention.
- Removed stream preview height tracking and simplified tool call rendering to always invalidate the content box.
- Updated hashline preview diffing to route section edits through shared apply/resolve logic and partial streaming parsing.
- Allowed previews to accept live content-hash matches immediately when snapshot records are missing.
- Enabled stale-tag recovery from the snapshot store for anchor-scoped edits and added coverage for snapshot-capture behavior and session-mismatch failures.
- Added a `skipHashValidation` flag to hashline diff options and skipped section hash checks when it is set.
- Updated streaming edit preview generation to set `skipHashValidation` while streaming is active.
- Added streaming preview tests asserting stale hash errors are suppressed during streaming and surfaced after completion.
- Removed `trimTrailingPartialLine` from hashline preview path, as the streaming-tolerant parser already handles partial ops correctly; trimming stripped the sole payload of single-op patches, collapsing the preview to "No changes."
- Broadened trailing-section error suppression to apply during streaming regardless of section count, preventing transient mid-typed ops from wiping stable prior frames.
- Added `replace block N:` syntax in grammar/parser/tokenizer/types, emitting `kind: "block"` edits with empty-body checks.
- Added block-resolution in hashline apply/recovery, wiring `BlockResolver` to resolve edits with throw/drop unresolved behavior.
- Added native `blockRangeAt` support and exported block range/options types through pi-ast, pi-natives, and JS bindings.
- Added coding-agent resolver wiring plus internal visibility/exports updates and new parser, patcher, and setup-wizard tests.
- Introduced a shared missingSnapshotTagMessage helper and reused it from both hashline patcher and preview validation.
- Required snapshot tags in preview hashline sections for all edits, including head/tail inserts, so preview failures now match apply-time rejections.
- Updated TUI width calculation to strip ANSI escapes before grapheme splitting, preserving styled ZWJ emoji width behavior.
- Replaced snapshot internals with full-file records and removed contiguous/sparse snapshot APIs.
- Added file-hash normalization, computed `computeFileHash`, and updated grammar/messages to 4-hex tags.
- Simplified recovery by checking whole-file hashes first, then applying merge-replay fallback after mismatches.
- Updated coding-agent tools to use `record`/`recordFileSnapshot` and skip hash headers for unsnapshotted large files.
- Expanded patcher and snapshot tests to verify 4-hex anchors, hash deduplication, and cache-capped behavior.
- Redesigned hashline patch syntax from anchor-based (`A-B:`) to hunk-header format (`@@ A..B @@`) with unified-diff compatibility.
- Removed `autoDropPureInsertDuplicates` option and simplified apply behavior to preserve duplicated boundary and context lines.
- Changed repeat operator from `^A-B` to `&A..B` and range separator from `-` to `..` for consistency with hunk-header syntax.
- Added image resizing and dimension notes to eval tool output; improved write tool hashline header sanitation for legacy formats.
- Removed 521 lines of boundary-duplicate absorption code and simplified parser to auto-convert bare body rows and unified-diff contamination.
- Replaced 4-hex content-derived file hashes with 3-hex opaque tags minted by InMemorySnapshotStore, making tags session-bound pointers rather than content fingerprints.
- Removed lru-cache dependency; replaced LRU-bounded per-path rings with a flat 4096-slot global ring using a scrambled permutation to prevent LLM tag extrapolation.
- Made SnapshotStore required in Patcher (was optional); tag resolution now drives stale-anchor detection instead of recomputing hashes at apply time.
- Changed literal payload sigil from `|` to `+` and accepted `^A` shorthand for `^A-A`; added lenient recovery for bare bodies, lone `-` rows, and overlapping bare/concrete block pairs.