- Added a check to restore the live "Working..." loader when streaming events occur after a transient status overlay clears the UI.
- Updated `ensureLoadingAnimation` to re-attach the animation to the status container if it is missing.
- Updated `formatReadHashlineHeader` to use `path.basename` instead of the full path.
- Applied the new formatter across record and display functions in the read tool.
- Added and updated tests to verify that hashline headers now contain only the filename for nested files.
- Added a check to promote the context model before triggering mid-turn compaction.
- Prevented unnecessary compaction during long tool loops that cross threshold limits by enabling window expansion instead.
- Implemented a monitoring system to identify Gemini model runaway behavior during thinking steps using consecutive header detection.
- Introduced a configurable tool-call reminder prompt to inject corrective context when reasoning stalls.
- Added session-level logic to automatically interrupt and prune stalled assistant turns from the conversation history.
- Provided comprehensive test coverage for the detection logic and stream interruption scenarios.
- Renamed the `find` and `search` tools to `glob` and `grep` respectively across the codebase to improve command clarity.
- Implemented full-stack support for the renamed tools, including CLI arguments, system prompts, SDK exports, and tool registration.
- Added automated migration logic in `settings` to transform legacy `find` and `search` configuration keys to their new equivalents.
- Updated the `collab-web` renderer registry to ensure backwards compatibility with legacy tool outputs.
- Removed the enforced minimum length for the `items` array in the tool schema to prevent unnecessary validation errors on operations that ignore the field.
- Added tests to verify schema acceptance of empty `items` arrays and confirmed that runtime errors are still correctly thrown for empty inputs during specific operations like `append`.
- Implemented file deletion (`REM`) and movement (`MV`) operations within the hashline grammar and parser.
- Added filesystem support for executing delete and move commands while maintaining snapshot history migration.
- Integrated file operation detection and parsing logic into the coding agent and patcher components.
- Added comprehensive integration tests and documentation for the new file-level operation syntax.
- Added a `worktree.base` setting to allow users to specify a custom directory for agent-managed git worktrees.
- Updated the `worktree` command to ensure settings are initialized before operations to respect the configured base path.
- Enhanced directory resolution logic to support `~` expansion and enforce absolute paths for worktree environments.
- Relocated json-parse (repairJson/parseJsonWithRepair/parseStreamingJson/
parseStreamingJsonThrottled) into @oh-my-pi/pi-utils; repointed all
ai/agent/coding-agent import sites to @oh-my-pi/pi-utils.
- readSseJson now recovers a truncated or lightly malformed final SSE event
through the shared streaming parser, removing the bespoke scanJsonState/
getClosingSuffix/isJsonTruncated scanner from stream.ts.
- Dropped the @oh-my-pi/pi-ai/utils/json-parse legacy bundled-plugin registry
entry; the symbols are exposed via the @oh-my-pi/pi-utils barrel.
- Moved json-parse tests into packages/utils/test.
- Centralized JSON parsing and stream processing logic by moving utilities from `packages/ai` to the shared `@oh-my-pi/pi-utils` package.
- Standardized import paths for JSON parsing and streaming across the agent, ai, and coding-agent packages.
- Refactored SSE stream handling to use consolidated `parseStreamingJson` logic and introduced robust error recovery for malformed container-shaped tail events.
- Cleaned up legacy bundled registry references and updated related module exports and tests to reflect the new utility structure.
The post-maintenance headroom guard returned residualTokens < triggerContextTokens
as a secondary check after the recovery-band test. When stale/tool-output pruning
already drove the trigger (postMaintenanceContextTokens) below the band before this
pass, that strict-less comparison made a residual which merely held the line at/under
the band report a false no-progress, suppressing a valid auto-continue and emitting a
spurious warning even though the next turn could no longer re-trip threshold compaction.
The recovery band sits strictly under the compaction threshold, so reaching it already
guarantees the next turn cannot re-trip. Make the band authoritative (residual <= band)
and drop the trigger argument. Adds a regression covering the sub-band trigger case.
(cherry picked from commit 31cf2dc7a30c4134f7a351d61065eca76543f154)
Addresses PR #3412 review (roboomp blocking + codex P2 + Copilot nits):
- The overflow/incomplete retry no longer reuses the COMPACTION_RECOVERY_BAND
hysteresis. Reusing it required residual context below 0.8×threshold, which
turned a recoverable overflow (e.g. 150k on a 200k window, under the ~170k
threshold) into a manual dead-end. Add #compactionCreatedRetryFit, which
measures the rebuilt prompt against the usable fit budget
(contextWindow - effectiveReserveTokens) and is evaluated AFTER the failed
assistant is dropped, so the just-failed turn is excluded.
- The threshold auto-continue keeps the stricter recovery-band check
(#compactionCreatedHeadroom) — that path is the snapcompact thrash guard.
- Split the no-progress warning so each path warns on its own signal.
- Alias errorIsFromBeforeCompaction as assistantPredatesCompaction in the
threshold-usage path for clarity; de-duplicate the rationale comment.
Adds two regression tests (recoverable overflow retries; non-fitting overflow
pauses + warns), mutation-verified against the band-vs-fit split.
(cherry picked from commit f8cf45b2740f04d8776a84521ba563b779d65b25)
prepareCompaction keeps the most-recent turn verbatim (findCutPoint never
cuts at tool results), so when that single turn already exceeds the
compaction threshold the rewritten context stays above threshold. The
context-full / snapcompact auto-compaction success tail scheduled the
agent-authored auto-continue (and the overflow/incomplete retry)
unconditionally, so the next agent_end re-entered #checkCompaction over
the same oversized tail and re-fired forever.
This is the residual loop left after #3247 capped snapcompact's own frame
projection: once #computeSnapcompactMaxFrames drops the frame cap below
one frame, snapcompact is skipped and the context-full summarizer path
still creates no headroom, so the loop persists on that path.
- #runAutoCompaction now gates the continuation and the overflow/
incomplete retry on a post-maintenance headroom check
(#compactionCreatedHeadroom), reusing the shake recovery-band
hysteresis from #2275 (consolidated as the shared
COMPACTION_RECOVERY_BAND). When a pass frees too little it pauses
automatic maintenance and emits a single warning instead of looping.
- The post-turn threshold check ignores an assistant's stale
pre-compaction usage so the scheduled auto-continue can't re-trip on
the kept assistant's old high token count.
Adds a regression test covering the no-headroom (pause + warn, no
continuation) and headroom (auto-continue, no warn) paths; both
assertions are mutation-verified against the guard.
(cherry picked from commit 6fcbbe2b3075827ee621acaee8efa2c586eedd3e)