Commit Graph
12270 Commits
Author SHA1 Message Date
can1357 4348999768 Merge PR #8087: test(coding-agent): flush immediate before asserting tiny-title prewarm (@szavadsky) 2026-08-11 15:06:14 +02:00
can1357 d57656f283 Merge PR #8074: fix(coding-agent): display subagent registration time locally (@anatoli-tsinovoy) 2026-08-11 15:06:13 +02:00
can1357 949b251ebd Merge PR #8066: fix(prompts): disambiguate the grep tool from shell grep in the system prompt (@zhang17-24) 2026-08-11 15:06:13 +02:00
can1357 7896a58406 Merge PR #8050: fix(tui): keep pasted images when a mode command submits the draft (@fatihaziz) 2026-08-11 15:06:13 +02:00
can1357 c0ad19005b Merge PR #8018: test(coding-agent): hermeticize agent dir in claude-plugins discovery tests (@szavadsky) 2026-08-11 15:06:13 +02:00
can1357 dedddb86f5 Merge PR #7998: fix(ai): map Cursor plan rails to dashboard percents and show mo N% (@dnth) 2026-08-11 15:06:12 +02:00
can1357 66a55fb916 Merge PR #7983: fix(vibe): restore the pre-vibe toolset when switching between vibe sessions (@iskWang) 2026-08-11 15:06:12 +02:00
can1357 6592b799b3 Merge PR #7980: fix(session): attribute a run to the model that produced its output (@enieuwy) 2026-08-11 15:06:12 +02:00
can1357 19edecaa48 fix: kept out-of-order todo completions visible 2026-08-11 15:06:12 +02:00
can1357 f6d4f1e38b Merge PR #7965: fix(coding-agent): surface todo progress in the collapsed panel (@z80dev) 2026-08-11 15:06:12 +02:00
can1357 00d90809fc test: removed redundant policy-key suite 2026-08-11 15:06:11 +02:00
can1357 8504e4865f Merge PR #7945: fix(coding-agent): resolve xd:// device dispatches against device user policy first (@re2zero) 2026-08-11 15:06:11 +02:00
can1357 261eb965ac fix(task): preserved direct role alias fallback 2026-08-11 15:06:11 +02:00
can1357 0748651036 Merge PR #7910: fix(task): key subagent fallback chains off the pre-expansion model role (@enieuwy) 2026-08-11 15:06:11 +02:00
can1357 d13121fbf8 Merge PR #7856: fix(coding-agent): answer panel commands immediately during a turn (@mvid) 2026-08-11 15:06:11 +02:00
Fatih Al-Aziz 8a22872ece fix(tui): preserve mode submissions across async input 2026-08-11 16:46:45 +07:00
Fatih Al-Aziz de9ee6d412 fix(tui): preserve mode attachments across async paths 2026-08-11 16:25:20 +07:00
Fatih Al-Aziz bb42aaaced test(tui): accept follow-up attachment argument 2026-08-11 15:59:08 +07:00
Fatih Al-Aziz d194f2d76c fix(tui): honor transformed mode attachments 2026-08-11 15:52:58 +07:00
can1357 baf8a1df7e feat(coding-agent/web): expanded web search and fetching providers
- Expanded web search and fetching providers with robust parsing, authentication storage integration, and response validation.
- Added support for new configurations including SearXNG safesearch, Cloudflare AI Gateway endpoints, and dynamic Firecrawl base URLs.
- Implemented comprehensive test suites covering error handling, content filtering, and provider-specific response behaviors.
2026-08-10 11:06:22 +02:00
Slava Zavadsky 9dc734ce2c test(coding-agent): flush immediate before asserting tiny-title prewarm
Re-applies the race fix from 7b21716754 that 563f00fe31 dropped as
'unrelated': InteractiveMode.init() defers the prewarm behind setImmediate,
and init()'s own awaits are microtasks that can resolve without yielding to
the immediate queue, so asserting right after await init() races under CI's
chunked load. Flush one immediate tick before asserting.
2026-08-09 11:29:37 -04:00
Anatoli Tsinovoy 5d8214ea77 fix(coding-agent): keep lineage timezone visible 2026-08-09 16:49:13 +03:00
Anatoli Tsinovoy d725ab10c1 fix(coding-agent): display subagent registration time locally 2026-08-09 16:35:07 +03:00
left-to-right c62bce22c1 fix(prompts): disambiguate the grep tool from shell grep in the system prompt
When `{{toolRefs.grep}}` resolves to "grep", the rendered line read
"Regex search or locating targets → grep, not grep, rg, or awk" — a
self-contradiction. Match the surrounding convention ("not shell
grep") as proposed in #8032.
2026-08-09 18:05:13 +08:00
Josh Mini 66648fb518 Merge remote-tracking branch 'upstream/main' into fix/vibe-restore-toolset-on-resume 2026-08-09 12:51:42 +08:00
Josh Mini bb5bfb2c04 fix(vibe): only override the vibe snapshot when teardown lost the live toolset
The persisted pre-vibe snapshot was applied on every reconciliation that
re-entered vibe mode, including cold resumes and switches in from a non-vibe
session. Those paths build their toolset from the current CLI flags and
settings, so replacing it with a historical snapshot silently drops tools the
session was started with: resuming a session that entered vibe under
--tools read with --tools read,bash restored only read on exit.

Gate the override on the one case the snapshot exists for: the vibe -> vibe
switch, where #clearTransientModeState kept the already-reduced live set.
2026-08-09 11:23:07 +08:00
can1357 45e12e5bb7 test(mnemopi): awaited detached shared-bank flush in lock-wait test
dispose({ timeoutMs }) legitimately detaches the consolidate pass when
the shutdown budget expires mid-flight (#3641), so asserting the shared
bank flush synchronously after dispose raced the detached pass on slow
CI runners (0 calls observed on run 31287979000). Signal the flush call
through a deferred and await it after releasing the lock; the bounded
<500ms return assertion is unchanged.
2026-08-09 03:39:03 +02:00
Fatih Al-Aziz 276f1dd3b2 fix(tui): keep pasted images when a mode command submits the draft
`/goal <objective>`, `/plan <prompt>` and `/vibe <prompt>` promote the
composer draft into the first turn, but built their submission from the
draft *text* only:

    this.onInputCallback(this.startPendingSubmission({ text: objective }));

The editor-submit path in `InputController` passes
`editor.pendingImages`/`pendingImageLinks` alongside the text; these four
call sites did not. A draft holding pasted screenshots therefore reached
the model with its positional `[Image #N, WxH]` markers intact and every
image payload missing, so the agent saw markers pointing at nothing and
`read "Image #1"` resolved against an empty list.

The payload was not only dropped, it also outlived the draft: the mode
commands cleared the composer with `editor.setText("")`, which leaves
`pendingImages` attached. The orphans then rode along with whatever the
user typed next, one index off, which is how a later message can attach a
screenshot the user never re-pasted.

Measured on 259 image-bearing user messages across 10 local session logs
(v17.2.x): 36 of 37 messages submitted as a goal objective lost every
image, against 190 of 198 preserved on the ordinary submit path.

Fix:
- `#takeDraftImages()` detaches the composer's pending images and links,
  and all four mode-command submissions spread it into
  `startPendingSubmission` (`cancelPendingSubmission` already restores
  them when a submission is cancelled).
- `/goal`, `/guided-goal`, `/plan` and `/vibe` clear the draft with
  `editor.clearDraft()` instead of `editor.setText("")`, so images can
  never outlive the text they were pasted into (the streaming branch of
  `/goal` never submits, so its draft must die whole).

Tests: two regression cases in `goal-mode-integration.test.ts` assert the
objective submission carries the image and empties the composer; both
fail on the previous behaviour with `images: undefined`. The `/plan`,
`/goal` and `/guided-goal` slash stubs now model `clearDraft`.
2026-08-09 08:38:09 +07:00
can1357 6fb07028fd chore: bump version to 17.2.12 2026-08-08 20:57:55 +02:00
can1357 d85dde52c4 fix(session): fence in-flight disk work behind the terminal seal
- seal() now runs before the final dispose close() and bumps the disk
  epoch: work an event handler enqueues while dispose awaits the closing
  tail is superseded, and an already-running fenced or authoritative
  rewrite fails its commit guard at the rename fence instead of
  publishing over a file a revival reopened.
- The authoritative repair path resets the disk tail itself, escaping the
  close() serialization, and would atomically publish the emptied entry
  list; it now no-ops once sealed and commit guards also check the seal.
- Execution-time gates cover the queued title persist and fenced rewrite
  callbacks; setSessionName/appendCustomEntry attempted by a handler that
  outlives dispose are dropped and covered by the seal regression, and a
  failed atomic batch across the seal can no longer truncate the file.
2026-08-08 20:49:28 +02:00
can1357 22b5ccd978 test(coding-agent): assert exact transcript contents in seal regression
- Replaced count-only assertions with the exact ordered message set:
  revival sees only the seed, the reread holds seed + post-revive, and
  the sealed manager's late persist text appears nowhere in the file.
2026-08-08 20:08:07 +02:00
can1357 63aa8cf6f8 fix(session): seal the manager at terminal release against revival races
- AgentLifecycleManager.park() resolves as soon as dispose() returns, so
  ensureLive() may reopen the same JSONL through a new manager while a
  timed-out event handler still holds the old one; a late append reopened
  a second writer on that file and the deferred finalize then closed it.
- A post-release rewrite was worse: it persisted the emptied entry list,
  truncating the transcript on disk.
- releaseRetainedEntries() now seals the manager: appends, title changes,
  and rewrites become dropped no-ops and the append writer is closed, so
  the deferred dispose pass is in-memory only and can never touch the file.
- File-backed regression: dispose on the drain deadline, revive the JSONL
  immediately, unpark the late handler, and prove the file is byte-stable
  and the revival writer owns it exclusively.
2026-08-08 20:04:09 +02:00
can1357 31d7655477 fix(agent): re-finalize dispose after the drain deadline
- The dispose drain deadline does not cancel in-flight event handlers: one
  parked in a slow extension hook resumed after close/release, reopened the
  append writer for its late persist, and repopulated the released state.
- Track whether the drain settled; on deadline, redo the final close +
  release once the pipeline genuinely settles (hook runtime is bounded by
  the extension runner).
- Expose drainTimeoutMs on AgentSessionDisposeOptions for bounded teardown
  paths and deterministic coverage of the deadline branch.
2026-08-08 19:54:33 +02:00
can1357 b9ddc81f06 test(coding-agent): assert dispose-persisted state from the reopened file
- PR #8004 dispose() now releases the session manager in-memory transcript;
  snapcompact-budget rebuilt a session over the closed manager and the exit
  diagnostics read released entries.
- Snapcompact reopens the persisted file for its replacement session; exit
  diagnostics move to disk-backed managers and assert the exit marker from a
  reopened manager, proving actual durability.
2026-08-08 19:50:59 +02:00
can1357 cab4c4520b test(coding-agent): reopen persisted session after terminal dispose
- PR #8004 made dispose() release the session manager in-memory transcript;
  three handoff tests reused the closed manager for a replacement session.
- Reopen the persisted session file via SessionManager.open, matching
  production revival paths.
2026-08-08 19:47:10 +02:00
can1357 f87a8ecc19 Merge PR #7994: fix(session): surface empty handoff generation as failure not cancel (@roboomp) 2026-08-08 19:38:32 +02:00
can1357 afa54d87f0 Merge PR #8002: fix(web-search): parse double-encoded Z.AI results (@roboomp) 2026-08-08 19:38:32 +02:00
can1357 b2d0ade665 fix(agent): finish session disposal after event drain 2026-08-08 19:38:32 +02:00
can1357 bca8d5281b Merge PR #8004: fix(agent): release parked subagent session memory on dispose (@roboomp) 2026-08-08 19:38:32 +02:00
can1357 ba8e4dabd4 Merge PR #8014: fix(tui): bound WSL idle animation CPU (@roboomp) 2026-08-08 19:38:31 +02:00
can1357 025c1c4df6 Merge PR #8023: fix(task): record subagent model performance (@roboomp) 2026-08-08 19:38:17 +02:00
can1357 7ca140f66e fix(ai): routed policy-rejected accounts through sibling rotation
- Added account-scoped policy error detection to correctly identify Codex cyber-policy rejections.
- Updated credential storage and retry logic to route denied accounts through sibling rotation instead of bypassing it.
- Ensured coding-agent sessions exhaust all sibling accounts before falling back on cyber denials.
- Added comprehensive test coverage for credential rotation and retry behavior on policy errors.
2026-08-08 19:29:49 +02:00
roboomp 506f57fbf2 fix(task): recorded subagent model performance
Shared the parent AgentStorage handle with isolated task settings while keeping setting overrides non-persistent.

Added regression coverage for task samples reaching the shared TPS/TTFT aggregate.

Fixes #8022
2026-08-08 15:59:27 +00:00
can1357 731c051733 feat(pi-shell/minimizer): implemented length threshold and empty preservation
- Add minimum character threshold to bypass minimization for short outputs.
- Add preserve-if-empty configuration and pipeline support for filters.
- Update test fixtures and integration tests to meet length thresholds.
2026-08-08 16:27:03 +02:00
can1357 a30cbbb75d feat(hashline): implemented syntax validation and veto checks for patch application
- Add a tree-sitter syntax probe and parser veto to prevent syntax-unaware boundary repairs.
- Reject span pastes from empty named registers instead of deleting ranges.
- Reject duplicate top-level snapshot row line numbers during parsing.
- Export new syntax module symbols and add associated tests and changelog updates.
2026-08-08 16:18:34 +02:00
Slava Zavadsky 8c4fde3564 test(coding-agent): restore profile env after agent dir isolation
setAgentDir() clears OMP_PROFILE/PI_PROFILE and snapshots the agent dir,
so restoring only PI_CODING_AGENT_DIR/HOME leaks the default profile to
later tests when the suite is started under a caller-selected profile.
Capture and restore all three env vars plus HOME, then rebuild the dir
resolver via __resetDirsFromEnvForTests() (disabled-extensions pattern).

Addresses review comment on PR #8018.
2026-08-08 10:18:21 -04:00
Slava Zavadsky a06b12ff41 test(coding-agent): hermeticize agent dir in claude-plugins discovery tests
listClaudePluginRoots tests point HOME at a temp dir but left the agent
dir at the real profile (~/.omp/agent). User-scope discovery (native MCP
config via getAgentDir()/mcp.json) then read the machine's real
mcp.json, leaking its servers into loadCapability results and failing
'deduplicates a plugin alias of a directly configured MCP connection'
whenever the real agent dir contains an mcp.json.

Point the agent dir at a temp dir in beforeEach and restore the
previous value (or unset PI_CODING_AGENT_DIR) in afterEach, matching
the established pattern in mcp-profile/autolearn-discovery tests.
2026-08-08 10:10:29 -04:00
roboomp a6aa462a60 fix(tui): bounded WSL idle animation CPU
- Removed the Loader backpressure cap so slow ConPTY paints retain the documented proportional duty cycle.

- Made WSL terminal-title working state static to avoid a second periodic OSC write loop.

Fixes #8012
2026-08-08 13:17:01 +00:00
roboomp 88021b90ea fix(agent): drained in-flight session event handlers on dispose
agent-core dispatches the session's event subscriber fire-and-forget (agent.ts #emit), so a message_end/agent_end handler can still be awaiting extension/subscriber/maintenance work — and its sessionManager/agent.state append — after agent.waitForIdle() resolves. The earlier settle waited only on the core run, so a late handler could append the finished message/entries back into the disposed session and re-pin the transcript.

Track every #handleAgentEvent dispatch in #inFlightEventHandlers and drain it (alongside agent.waitForIdle) inside the bounded settle before reset/clear/release. Added a regression test using a real extension whose message_end hook blocks before persistence, asserting dispose does not release memory until the in-flight handler settles.
2026-08-08 10:26:41 +00:00
roboomp a7a32f35dd fix(agent): settled active turn before clearing session memory
dispose() only *signalled* the agent loop via abort(); it never awaited the run, so a mid-turn dispose (Ctrl-C/timeout/hard-killed subagent) could let the loop unwind after the release ran — its response/SSE interceptors re-recording wire frames into rawSseDebugBuffer and its terminal message re-appending to agent.state.messages, repopulating the disposed session with exactly the retained state the release drops.

Detach the response/SSE interceptors and await a bounded agent.waitForIdle() before the reset/clear so it lands on a quiescent session. Added a deterministic regression test that gates the active turn and asserts dispose blocks on it before clearing.
2026-08-08 10:06:55 +00:00