- Updated collectPayload to accept intervening blank lines as empty payload when requirePayload is true and no payload has been collected yet.
- Added a fallback path alongside the HL_EDIT_SEP check so blank insertions without a separator are tolerated as required-payload op payload lines.
- Updated hashline splitting to skip emitting a section when a path header has no following operations.
- Added a trimmed non-empty check so only sections with diff content are returned.
- Added tests for duplicate and trailing headers to ensure empty header-only chunks are silently dropped.
- Updated `collectPayload` to treat blank lines inside a payload run as empty entries when subsequent payload text is present.
- Added lookahead-based end-of-run detection so blank lines before a non-payload operation remain section separators.
- Added tests verifying blank-line recovery inside payloads and non-consumption of trailing blanks between hashline sections.
- Updated the hashline mismatch error to describe anchor mismatches against the current file.
- Rewrote hashline tool instructions to clarify insert payload rules, anchor usage, and avoidance of fabricated hashes.
- Expanded stale-edit detection and tests to recognize the revised anchor-mismatch rejection wording.
- Removed export leakage by demoting many helper and const symbols to module-local scope.
- Renamed underscore-prefixed internals and cache fields, then updated related references and `satisfies never` checks.
- Deleted obsolete logic branches and helpers, including harmony-stream interruption flow and unused benchmark runtime helpers.
- Updated Biome config and manifests by broadening lint coverage and removing an unused `@napi-rs/cli` dev dependency.
- Adjusted tests and utilities to use renamed test helpers and remove redundant private test-only helpers/locals.
- Updated hashline section parsing to accept headers with any leading `@` characters, normalizing them to the path before validation.
- Updated the hashline grammar and fallback errors to use canonical `@@ PATH` section headers.
- Added coverage for mixed `@@` and `@@@` headers across multiple file sections in hashline parsing tests.
- Replaced `===== ... =====` eval cell headers with `*** Begin ` / `*** End ` markers; legacy format remains renderable in HTML exports.
- Replaced hashline patch grammar with `*** Begin Patch` / `*** End Patch` envelope; old inputs without the envelope are still accepted.
- Extracted `sniffEvalLanguage` into a shared `sniff.ts` module reused by the parser and tool.
- Added `docs/ERRATA-GPT5-HARMONY.md` and `scripts/session-stats/harmony_backtest.py` documenting and backtesting the GPT-5 Harmony-header leak defect.
- Dropped the `modify` edit type and its `< ANCHORTEXT` / `+ ANCHORTEXT` syntax.
- Removed associated parser rules, regex patterns, apply logic, and tests.
- Deleted the "Append WITHIN a line" example from the prompt docs.
- Updated the hashline grammar to require a full `LID .. LID` range for block operations.
- Enhanced `parseRange` to reject single-anchor syntax and malformed ranges, and to require duplicated anchors for one-line edits.
- Reworked hashline prompt examples/tests accordingly and added coverage for single-anchor delete/replace forms.
- Removed hashline anchor auto-rebase logic, including the ±5-line rebase window and `tryRebaseAnchor` fallback.
- Validation now reports hash mismatches directly as hard `HashMismatch` entries and surfaces them via `HashlineMismatchError` without mutating anchor lines.
- Updated the changelog to document anchor auto-rebase removal and the immediate re-read recovery behavior.
- Implemented hashline stale-anchor recovery using cached reads and a 3-way merge fallback.
- Updated hashline execution and preflight checks to retry mismatched anchors through cache recovery.
- Added file-read cache support with per-session LRU snapshots and contiguous/sparse record APIs.
- Integrated read and search tools with the shared cache to record candidate lines for recovery.
- Added tests for stale-anchor recovery flows and FileReadCache session, null, overlap, and eviction behavior.
- Extended boundary duplicate absorption to single structural closing lines (`}`, `)`, `]`) for replacement groups.
- Added delimiter-balance validation so a boundary line drops only when the kept payload matches expected counts.
- Enabled default single-line structural boundary absorption for pure inserts while keeping multi-line absorbs gated by `autoDropPureInsertDuplicates`.
- Added a new `edit.hashlineAutoDropPureInsertDuplicates` boolean setting with default `false` for hashline edits.
- Threaded the setting through tool execution contexts so hashline previews and execution honor the configured option.
- Changed pure-insert duplicate boundary absorption to run only when enabled and added tests for default-disabled and enabled behavior.
- Extended hashline pure-insert absorption to auto-drop 2+ duplicated boundary lines at ANCHOR, BOF, and EOF inserts.
- Surfaced a warning when pure-insert boundary lines are auto-dropped.
- Wrapped hashline execution by merging same-path input sections into one combined section in execution order.
- Applied a new hashline regression test that validates sequential sections against the same file use the original snapshot even when anchors shift beyond rebase limits.
- Added a `= A..B` hashline rule and adjacent-edge guidance to the tool prompt.
- Added `HashlineReplacementGroup` and `HashlineDeleteEdit` with helpers to find anchor-target lines.
- Added `findReplacementGroup()` and duplicate-boundary absorption to normalize edits with synthetic deletes and warnings.
- Added normalization flow into `applyHashlineEdits` before bucketing, and added duplicate-boundary edge-case tests.
- Updated `CHANGELOG.md` with Added and Fixed unreleased notes for hashline boundary-line behavior.
- Added inline hashline parse and apply support for `<` prepend and `+` append operations with prefix+suffix edits.
- Added fail-fast behavior to reject inline modify ops combined with delete or replace on same line.
- Renamed HASHLINE_* and mode symbols to HL_* in prompt tooling, read/search checks, and prompt templates.
- Standardized separators to `PI_HL_SEP`/`HL_EDIT_SEP` and fixed `HL_BODY_SEP='|'`, updating parser formatting behavior.
- Updated benchmark subtype constants and python cleanup test setup to use HL_* values and AgentRegistry mock failure injection.
- Added configurable hashline separator support via `PI_HASHLINE_SEP` with `|` fallback.
- Replaced hardcoded `|` payload markers with `{{hsep}}`/`$HSEP$` in prompts, grammar, and parsing.
- Updated payload parsing to strip shared separator prefixes while preserving whitespace-only prefixes.
- Replaced `resolveLarkLidPlaceholders` with `resolveHashlineGrammarPlaceholders` and added a compatibility alias.
- Updated `collectPayload` to accept a warnings accumulator, detect doubled payload prefixes, and strip one extra leading `|` when all payload lines used the doubled form.
- Changed `parseHashlineWithWarnings` to return collected parser warnings instead of an empty list.
- Added tests confirming auto-stripping, single-line `|` preservation, and mixed-prefix payload behavior.
- Centralized `line-hash.ts` hash regex sources and resolved `atom.lark` via `resolveLarkLidPlaceholders`.
- Expanded `computeLineHash` to emit `>[a-z]` and `[a-z]<` hashes for brace-context anchors.
- Replaced atom/hashline parsers' hard-coded lid regex with shared `HASHLINE_HASH_RE_SRC` and lax counterparts.
- Removed `\\TEXT` continuation handling in atom rewrites and switched multi-line replacements to `+TEXT`.
- Added brace-body insertion warning when `@Lid` on `{`-ending lines inserts at non-body-safe indent.
- Suppressed duplicate auto-rebase warnings and kept unmatched `-`/`+` ranges separate in compact previews.
- Allowed bare `LidA..LidB` to recover a missing-range-delete typo and accepted `|` as a legacy range replacement separator while validating ranges and replacement text.
- Enabled indented hashline statements to parse as replacement edits and added a preflight pass that validates all atom sections before any file write occurs.
- Updated hash-mismatch messaging, prompt wording, and tests to reflect hash-only rebase candidates and the new range/section behaviors.
- Added atom edit support for Lid ranges, before-anchor inserts, and no-op Lid=TEXT success handling.
- Expanded hashline recovery to scan shifted hashes, match unique alternates, and emit ±5 anchor-shift hints.
- Added edit failure categorization with per-category counts, percentages, and detailed report lines.
- Added regression coverage for shifted-hash recovery, range continuation, cursor shorthand, and split-file atom ops.
- Updated atom mode diff output to use path-prefixed preview text and removed the explicit summary header.
- Changed hashline preview generation to truncate unchanged runs by direct slicing and reduced placeholder spacing for line prefixes.
- Updated hashline preview expectations in tests to match the new compact unchanged-line formatting.
Drop three pieces of well-intentioned-but-fragile string mangling that
were quietly mutating model edit content:
- `maybeAutocorrectEscapedTabIndentation` in both hashline and atom edit
modes (plus the `PI_HASHLINE_AUTOCORRECT_ESCAPED_TABS` env toggle and
`isEscapedTabAutocorrectEnabled` helper). Literal `\\t` in edit content
is now preserved verbatim.
- `maybeWarnSuspiciousUnicodeEscapePlaceholder` and the
`runHashlinePreflightSanitizers` wrapper. The warning was misleading:
it flagged `\\uDDDD` as suspicious without distinguishing intentional
literal text from a likely-malformed escape, and it was the only
remaining caller.
- The hand-rolled JSON-unescape fallback in
`decodePartialJsonStringFragment` (renderer.ts). The fallback used
`String.fromCharCode` (mishandling lone surrogates) and only covered a
subset of JSON escapes, so the same fragment decoded one way mid-stream
and a different way after `JSON.parse` succeeded. Now we trim a
trailing partial `\\u`/odd-backslash escape and surface the raw
fragment if `JSON.parse` still fails.
- Updated `read` selector parsing for file and URL reads to accept optional leading `L` and `+` count-style ranges.
- Adjusted truncation notices and schema/help text to emit and suggest `sel` offsets without the `L` prefix, including continuation and suggestion messages.
- Updated hashline/output parsing and related tests to recognize the new `sel` formatting in truncation notices.
- Updated `formatMatchLine` to emit `*` for matched lines, a leading space for context, and a `|` anchor/content separator.
- Revised grep/hashline mismatch messages and prompts to describe the new marker and separator format.
- Aligned affected atom and hashline tests with the updated match-line prefixes and separators.
- Added `sed` atom editing with `g`, `i`, and `F` flags, path/anchor parsing, and conflict handling updates.
- Changed hashline and grep/read output to `LINE+ID|content` with `>` match prefixes and `:` context prefixes.
- Fixed atom anchor parsing for path-qualified locs, hyphenated single anchors, and content hints after `|` or `:`.
- Updated prompts, changelog, and tests to document and validate the new hashline and `sed` formats.
- Added auto-rebasing for stale atom and hashline anchors within ±2 lines, with warning diagnostics.
- Removed atom range-locator support and dropped `between` ops, updating docs/tests for `sub` over `set` nudges.
- Changed no-op handling to track unchanged hashline edits and emit contextual hints for unchanged ranges.
- Expanded Anthropic strict error handling to retry on schema-too-complex and compiled-grammar-too-large errors.
- Added anchor-retargeting warning checks and updated edit tests to expect locator and range-locator rejections.
- Updated python tool-call fixtures by adding `title` to executed-cell payloads and adjusting related test expectations.
- Adjusted hashline tests to expect colon-prefixed anchors in format, diff preview, and parse assertions.
- Updated ast-edit test regexes and split logic to parse colon-delimited hashline prefixes.
- Expanded hashline and chunk bigram tables to 647 entries and moved chunk checksums to a 40-item namespace.
- Changed hashline anchors from `LINE#ID`/`:` to concatenated `LINEID`\t forms across parsing and tool outputs.
- Removed line-number padding and routed diff/read/grep/renderer output through raw numbers, tabs, and `toDisplayLine` formatting.
- Renamed atom ops to `pre`/`post`, removed `ins`, and updated schemas, prompts, and tests for new insertion behavior.
- Added `examples` support to `StringEnum` schemas and propagated it to tool metadata.
- Added concise descriptions and example values across coding-agent tool schemas for clearer guidance.
- Documented the new StringEnum examples capability in `packages/ai/CHANGELOG.md`.
- Cast `real` to `HASHLINE_BIGRAMS` elements in `staleBigramFor` test setup.
- Aligned hashline and chunk token handling to `HASHLINE_BIGRAMS` in `computeLineHash` and parsing regexes.
- Removed hashline file-level `move`/`delete` options from schemas and execution so edits are in-place updates only.
- Hardened hashline prefix parsing to reject non-bigram IDs, preventing false stripping of `#` comment lines.
- Updated `read()`/prompt wording so raw reads skip prefixes and examples now show anchors like `123#th`.
- Updated hashline chunk tests for new `HASHLINE_BIGRAMS` IDs and replaced stale hash constants.
The previous mismatch text ('1 line has changed since last read. Use
the updated LINE#ID references shown below.') reads like a successful
edit followed by an informational note. Providers whose tool-result
plumbing does not surface `isError: true` to the model (e.g. Qwen via
the OpenAI-completions shim, where mitmproxy traces show the model only
receives the content text) treat the response as a success and proceed
with stale state.
Reword the message to start with 'Edit rejected:' and explicitly state
'The edit was NOT applied' so the failure is unambiguous in plaintext.
The structural payload (>>> markers, updated LINE#IDs) is unchanged.
Fixes#742
The hashline prefix stripping logic uses an "all-or-nothing" heuristic:
it only strips N#XX: anchors when every non-empty line carries one.
When the Read tool truncation notice (e.g. [Showing lines 1-300 of
332. Use sel=L301 to continue]) is present in content passed to the
Edit or Write tool, that marker line breaks the heuristic, causing ALL
anchors to be written to disk verbatim. On subsequent reads, those
persisted anchors get double-prefixed (1#NX:1#BQ:---), compounding
the corruption.
This can happen when the AI model pastes Read tool output (including
the truncation marker) back into an Edit/Write call. While this is
arguably a model-level issue, the toolchain should be resilient against
it rather than silently corrupting files.
Changes:
- Add READ_TRUNCATION_NOTICE_RE to detect Read tool truncation markers
- Update collectLinePrefixStats to exclude truncation marker lines from
the non-empty line count so they no longer break the stripping heuristic
- Add stripLeadingHashlinePrefixes helper for recursive stripping of
nested/double-prefixed anchors (handles already-corrupted content)
- Add filterTruncationNotices helper to remove truncation marker lines
- Update both stripNewLinePrefixes and stripHashlinePrefixes to filter
truncation markers and use recursive anchor stripping
- Add 5 new test cases covering truncation markers and nested anchors
- Refactored chunk tree initialization to use explicit prologue/epilogue byte boundaries instead of None values.
- Extracted chunk resolution logic to use split_selector_crc_and_region() helper for improved code reuse.
- Reorganized package.json exports across multiple modules (autoresearch, cli, dap, edit, modes) for better API surface clarity.
- Updated test expectations for Go receiver method rendering and chunk selector formats to match refactored output.
- Consolidated notebook conversion logic and removed unused _createErrorToolResult helper function.
- Improved leading trivia preservation in chunk edits by detecting and maintaining line prefix whitespace.
- Reorganized edit tool from `patch/` to `edit/` directory with dedicated mode subdirectories (chunk, patch, hashline, replace).
- Replaced line-scoped edit operations with substring-based `find` parameter and added `replace_body` operation for preserving signatures.
- Added chunk focus modes (Expanded, Collapsed, Container) and focused rendering to display only touched chunks and adjacent siblings.
- Implemented notebook (ipynb) language support with virtual source conversion and cell-based chunk parsing.
- Enhanced chunk edit error messages with consistent checksum mismatch reporting and improved chunk selector auto-resolution.
- Extracted edit mode implementations into separate modules with improved helper functions and LSP integration for diagnostics.
- Renamed hashline operation types for clarity: append->append_at, prepend->prepend_at, append_eof->append_file, prepend_bof->prepend_file.
- Updated all operation type references in patch implementation, tests, and documentation to reflect new naming convention.
- Restructured hashline tool documentation with hierarchical sections and simplified examples for improved clarity.
- Consolidated validation rules and added explicit warning about invalid anchors and operation/field combinations.
- Added autoresearch extension with autonomous experiment loop supporting init, run, and log experiment tools for metric-driven optimization.
- Added widget placement system enabling extensions to position UI components above or below the editor via ExtensionWidgetOptions.
- Added dashboard controller with interactive overlay for viewing experiment results, metrics, and progress with keyboard navigation.
- Removed auto-correction logic for off-by-one range edits in hashline editor to preserve user intent in patch operations.
- Added state reconstruction utilities to parse autoresearch.jsonl logs and rebuild experiment state across sessions.
- Added comprehensive type definitions and helper utilities for metric parsing, ASI validation, and process management.
- Changed bash interceptor configuration from boolean flags to customizable pattern-based rules array.
- Clarified hashline range replace semantics: end parameter is now strictly exclusive boundary.
- Fixed bash interceptor to apply built-in default rules when no custom patterns are configured.
- Updated hashline range validation and calculations to enforce exclusive end semantics throughout.
- Added auto-reconnect capability for MCP servers with SSE stream monitoring and exponential retry backoff.
- Added tool-level reconnect handling for retriable connection errors (ECONNREFUSED, ECONNRESET, 404/502/503).
- Added `/mcp reconnect <name>` command for manual MCP server recovery.
- Improved reconnect robustness by aborting retries when MCP configuration changes via epoch checking.
- Extended transport reconnect handling to all transport types (stdio, HTTP/SSE) with unified onClose logic.
- Added comprehensive test coverage for MCPManager reconnect behavior and tool-level abort propagation.
- Added line hashes to compact diff preview for unchanged and added lines to enable integrity verification.
- Modified compact diff preview to track line number synchronization between old and new files when processing insertions and deletions.
- Fixed line number parsing in compact diff preview to handle variable-width line number fields with leading whitespace.
- Extracted parsing and formatting logic into dedicated functions (parseNumberedDiffLine, formatCompactHashlineLine, syncOldLineCounters, syncNewLineCounters) for maintainability.
- Updated 4 test cases to verify line hash generation, line number synchronization, and handling of variable-width fields.