Commit Graph

8613 Commits

Author SHA1 Message Date
can1357 686008b056 Merge PR #4544: fix(tui): avoid auto-linked token rate format (@roboomp) 2026-07-05 12:44:17 +02:00
can1357 9d4ce0af68 Merge PR #4563: fix(tool): preserve bash pipeline output (@roboomp) 2026-07-05 12:44:17 +02:00
can1357 3e1808e2b5 fix(agent): handle installed legacy dependency reloads 2026-07-05 12:44:17 +02:00
can1357 b3ee269e4e Merge PR #4568: fix(agent): reload edited legacy Pi modules (@roboomp) 2026-07-05 12:44:17 +02:00
can1357 4225f4bc44 fix legacy resource loader forwarding 2026-07-05 12:44:16 +02:00
can1357 dec882a766 Merge PR #4569: fix(agent): restore legacy DefaultResourceLoader shim (@roboomp) 2026-07-05 12:44:16 +02:00
can1357 2eb5995bc5 fix(coding-agent): complete legacy pi-ai catalog re-exports 2026-07-05 12:44:16 +02:00
can1357 3a584fec88 Merge PR #4585: fix(coding-agent): re-export calculateCost + siblings from legacy pi-ai shim (@roboomp) 2026-07-05 12:44:16 +02:00
can1357 1f4fde556f Merge PR #4581: fix(advisor): clamp default thinking against the resolved model (@roboomp) 2026-07-05 12:44:16 +02:00
can1357 d4283d242c fix(session): preserve explicit sessions with consumed drafts 2026-07-05 12:44:15 +02:00
can1357 ecded0afe5 Merge PR #4572: fix(session): drop empty session file on close when no messages and no draft (@roboomp) 2026-07-05 12:44:15 +02:00
can1357 cb05bd1455 Merge PR #4602: fix(tui): scope autocomplete in slash command arguments (@roboomp) 2026-07-05 12:44:15 +02:00
roboomp 1fcdc4f882 fix(tui): preserved autocomplete for no-arg slash prompts
- Propagated builtin allowArgs metadata into TUI autocomplete entries.

- Let no-arg slash-looking prompts fall through to prompt-composer completions while keeping argument-capable commands scoped.

- Added regressions for /settings @ and /settings #copy.
2026-07-05 09:05:45 +00:00
roboomp ed63b62889 fix(tui): scoped autocomplete to slash command arguments
- Stopped prompt-composer # actions and @ file references from claiming submitted slash-command argument text without explicit argument completions.

- Added provider regression tests for /rename title arguments and explicit command argument completions.

Fixes #4600
2026-07-05 08:52:32 +00:00
roboomp 4f8b0394ca fix(agent): restored legacy DefaultResourceLoader shim
Added a DefaultResourceLoader compatibility adapter for legacy pi package-root imports and translated resourceLoader into OMP session discovery options so noExtensions/noSkills are preserved for subagents.

Added a regression test covering the loader snapshot and createAgentSession translation path.

Fixes #4567
2026-07-05 02:57:52 +00:00
roboomp 45deb2098d fix(agent): reloaded legacy bare dependency children
Included ESM extension-local bare dependency entries in the legacy extension graph so their relative children receive the same mtime cache-bust rewrite as extension source modules.

Skipped CommonJS dependency entries to preserve native Bun CJS default import behavior.

Added a regression test for a local node_modules ESM dependency whose unchanged entry re-exports an edited helper.

Fixes #4565
2026-07-05 02:53:28 +00:00
roboomp 5203fce696 fix(coding-agent): re-exported relocated catalog symbols from legacy pi-ai shim
`calculateCost`, `modelsAreEqual`, and `getBundledProviders` moved from the
`@oh-my-pi/pi-ai` barrel to `@oh-my-pi/pi-catalog/models` in the catalog
split (1b9d9d0851). The legacy-extension pi-ai root shim already bridged
`getBundledModel`/`getBundledModels` back under their old `getModel`/
`getModels` names but never re-exported the other relocated symbols, so any
legacy extension importing `calculateCost` from `@oh-my-pi/pi-ai` failed
plugin validation at install time with `Export named 'calculateCost' not
found in module '.../legacy-pi-ai-shim.ts'`.

Bridge all three symbols through the shim so pre-split legacy extensions
load again. Add regression tests that load fixtures importing
`calculateCost`, `modelsAreEqual`, and `getBundledProviders` from
`@oh-my-pi/pi-ai` and assert identity against the catalog implementations.

Fixes #4584
2026-07-05 02:03:41 +00:00
Jagrav Naik 27d2109ca3 fix(session-selector): Backspace on empty search deletes session
macOS laptops have no dedicated Forward Delete key. Fn+Backspace is the
only way to send \e[3~, and many macOS terminals (Terminal.app, some
iTerm2 profiles) deliver \x7f for that combo instead — so the keystroke
landed in the search box, not the delete handler, making session deletion
unreachable for those users.

Add a Backspace-on-empty-search handler alongside the existing Delete
check. With a typed query, Backspace stays bound to the search Input so
users can still edit their filter text. The existing confirmation dialog
guards against accidents.

Footer hint updated: [Del delete] -> [Del/⌫ delete].
2026-07-04 21:16:40 -04:00
roboomp a1f60f6584 fix(advisor): clamped advisor default thinking against the resolved model
`#resolveAdvisorRuntimeDescriptors` hardcoded `ThinkingLevel.Medium` when
no thinking suffix was configured. For reasoning models with no
controllable effort surface (`devin-agent`: `reasoning: true`,
`thinking: undefined` — Cascade selects effort by routing to sibling
model ids, not a wire param), that default tripped
`requireSupportedEffort` on the first advisor prompt with an empty
`Supported efforts:` list, disabling the advisor session-wide.

Route the default through `resolveThinkingLevelForModel(model, level)`
which preserves explicit `off`, clamps a concrete effort into the
model's supported range, and returns `undefined` for reasoning models
without controllable efforts — falling back to `Inherit` so no effort is
sent while reasoning stays enabled. Matches the `auto`-path fix
(`clampAutoThinkingEffort`) and the Autonomous Memory clamp
(`clampThinkingLevelForModel`).

Fixes #4579
2026-07-05 00:46:01 +00:00
roboomp 170cf59cf7 fix(session): treated mode_change as draft-only metadata
`plan.defaultOnStartup` records a `mode_change` before the composer restores its draft; without this the draft-cleanup arm check treats the file as durable and the metadata-only JSONL leak reappears for default-plan sessions.

Added a regression case that drives a model_change + mode_change + draft-clear cycle and asserts the session file is dropped on close().

Fixes #4571
2026-07-04 23:18:28 +00:00
roboomp a3557222f1 fix(session): kept explicit empty sessions on close
Limit empty-session close cleanup to files whose draft sidecar lifecycle
materialized an otherwise startup-metadata-only session. Direct
ensureOnDisk() callers now remain discoverable even when they have no
user/assistant messages yet, and handoff custom_message entries survive
close before the next user turn.

Added regression coverage for resumed draft cleanup, ACP-style explicit
ensureOnDisk() records, and handoff custom messages.

Fixes #4571
2026-07-04 22:38:15 +00:00
roboomp 903900edc9 fix(session): dropped empty session file on close when no messages and no draft
`SessionManager.saveDraft(text)` calls `ensureOnDisk()` so the draft
sidecar has a parent JSONL. A follow-up `saveDraft("")` only unlinks
the sidecar — the session file was left behind, and `#shouldHaveSessionFile()`
could not prune it once the load path latched `#fileIsCurrent` and
`#forceFileCreation` to true. Each draft-then-clear-then-exit cycle
leaked a ~500–750 B zombie into `~/.omp/agent/sessions/<cwd>/`
containing only the title slot, session header, and a handful of
`model_change`/`mode_change`/`thinking_level_change` entries.

`close()` now calls `#dropIfEmptyAndNoDraft()` after draining the
writer: when the file exists, holds no user/assistant messages, and
no draft sidecar is present, it removes the session file and its
artifacts directory via `deleteSessionWithArtifacts`. Real conversations,
sessions with a saved draft still on disk (needed for `--resume`), and
never-materialized sessions are untouched.

Fixes #4571
2026-07-04 22:25:56 +00:00
roboomp 65cd063d90 fix(agent): refreshed legacy pi graph hooks
Collected the current extension graph on every load and registered supplemental Bun hooks for modules added after the first import.

Preserved exact-path filters by tracking covered realpaths per entry instead of widening hooks to unrelated files.

Added a regression test for an entry-only extension that later adds helper and leaf modules, then reloads an edited leaf.

Fixes #4565
2026-07-04 20:56:38 +00:00
roboomp 2049c72b94 fix(agent): propagated mtime through legacy extension graph
Threaded the current load's mtime tag through rewriteExtensionPackageImports, rewriteExtensionBareImports, and a new relative-graph pass so ./helper.ts, #alias/*, and extension-local bare deps all rekey per reload.

Added a toGraphImportSpecifier helper that emits bare POSIX paths with ?mtime on POSIX and keeps file:// URLs on Windows/bundled targets, matching the entry loader.

Added a regression test covering same-process relative-helper reload freshness through the public loader.

Fixes #4565
2026-07-04 20:44:56 +00:00
roboomp d510851593 fix(agent): reloaded edited legacy pi modules
Loaded legacy Pi extension entries through raw POSIX filesystem specifiers so Bun keys the cache-busting mtime query.

Allowed the extension graph onLoad hook to match and normalize the mtime query before rewriting source.

Added a regression test covering same-process reload freshness and clean fileURLToPath-derived paths.

Fixes #4565
2026-07-04 20:26:27 +00:00
roboomp b1ef7ce6aa fix(tool): kept bash fixup compatibility shim
Restored the exported bash-command-fixup subpath and bundled legacy registry entry while keeping BashTool from using the rewrite.

Fixes #4562
2026-07-04 20:23:43 +00:00
roboomp 281a01a2a0 fix(tool): removed unused bash fixup wrapper
Deleted the coding-agent wrapper and tests for the stripTrailingHeadTail command rewrite now that BashTool executes pipelines as written.

Fixes #4562
2026-07-04 20:16:30 +00:00
roboomp f59352f5ed docs(changelog): moved bash pipeline fix to Unreleased
The #4562 entry was accidentally inserted under the already-published 16.3.6 section.

Fixes #4562
2026-07-04 19:45:56 +00:00
roboomp 6a1ea9bf27 fix(tool): preserved bash pipeline output
Removed the bash tool execution-path rewrite that stripped trailing head/tail pipeline stages before running commands.

Added regression coverage for short-reading final pipeline stages.

Fixes #4562
2026-07-04 19:40:31 +00:00
roboomp 55e2b473aa fix(tui): avoided auto-linked token rate format
Rendered the status-line token rate as an explicit tok/s unit so Ghostty no longer auto-detects the numeric value as a URL.

Added a regression test for the token_rate segment rendering contract.

Fixes #4541
2026-07-04 17:42:56 +00:00
can1357 38565c58cb test(coding-agent): updated job poll displacement tests to use TranscriptContainer
- Replaced manual Container stubs with TranscriptContainer instances in test fixtures.
- Updated test context initialization to utilize the actual container implementation for chat message tracking.
2026-07-04 14:48:41 +02:00
can1357 78126d925c test(ci): kept messagePersistenceKey call strict in event-controller
Reverted the defensive typeof guard; the assistant component contract guarantees the method, and test doubles now mock it. Keeping the production call strict avoids masking broken mocks or silently skipping persistence-key recovery.
2026-07-04 14:41:22 +02:00
can1357 53e8a8b807 test(ci): fixed event-controller and auth-storage test failures
- Mocked messagePersistenceKey in event-controller-error-banner.test.ts and safe-guarded it in event-controller.ts to prevent TypeError.
- Updated thinking loop retry test expectations to handle new dynamic recoveredErrors structure.
- Updated schema version assertions in auth-storage-email-dedupe.test.ts to v5, preserving v6 for future schema test.
- Simulated scrollback commitment in event-controller-message-start.test.ts by rendering container and committing rows before advancing timers.
2026-07-04 14:21:01 +02:00
can1357 98f6e9f004 chore: bump version to 16.3.6 2026-07-04 14:00:53 +02:00
can1357 e8d1ab005e test(coding-agent): verified transcript component streaming and state management
- Added comprehensive unit tests for `TranscriptContainer` to verify uncommitted block tracking.
- Created integration tests ensuring `AssistantMessageComponent` correctly streams thinking and answer content into scrollback.
- Added tests verifying that expanded tool evaluation output records rows correctly without duplication after settling.
- Updated `AssistantMessageComponent` test suite to cover table streaming scenarios in the unsettled tail.
2026-07-04 12:15:23 +02:00
can1357 10043a5990 feat(coding-agent): gated block lifecycle and state transitions
- Enforced strict history protection by gating ephemeral block removal on uncommitted state across controllers and UI components.
- Optimized settled-row calculations using explicit mermaid fence detection and improved scrollback integrity.
- Refactored transience management to target only actively streaming blocks, preventing redundant label rendering.
- Implemented persistent compaction for auto-retry errors and enabled consistent terminal title updates during session renaming.
2026-07-04 12:13:34 +02:00
can1357 0cdd0a09b8 refactor(coding-agent): consolidated session title update logic
- Moved terminal title update logic to a single listener onSessionNameChanged.
- Removed redundant setSessionTerminalTitle calls from ExtensionUiController, InputController, and InteractiveMode.
- Ensured consistent side-effect execution for terminal titles and editor accents across all session name change triggers.
2026-07-04 12:13:34 +02:00
can1357 71dd8c8e81 refactor(coding-agent/modes): updated abort reason rendering logic
- Refactored abort reason handling to rely on shouldRenderAbortReason instead of isSilentAbort.
- Updated documentation to clarify that both silent and user-interrupt aborts yield no label.
2026-07-04 11:37:54 +02:00
can1357 6b90d34924 Merge remote-tracking branch 'origin/farm/96461c96/fix-browser-cmux-pending-unhandled-rejection' 2026-07-04 11:27:29 +02:00
can1357 141244ab21 Merge remote-tracking branch 'origin/farm/1f0795db/guard-write-render-content' 2026-07-04 11:27:12 +02:00
can1357 42fc4e6b0a refactor(agent): unified transcript block finalization logic
- Replaced commit-based stability checks with a unified `isTranscriptBlockFinalized` tracking mechanism.
- Removed deprecated provisional rendering configuration and flags across tool and renderer interfaces.
- Standardized native scrollback boundary logic to pin at the first unfinalized block using settled row verification.
- Updated and refactored test suites to validate block finalization and settled row boundaries instead of deprecated commit stability methods.
2026-07-04 11:22:05 +02:00
can1357 6e2bba871e feat(agent): implemented automated retry recovery and transcript compaction
- Introduced an automated retry recovery system to track, manage, and persist recovered error states within agent sessions.
- Enabled compact transcript rendering for recovered auto-retry errors by removing heuristic commit machinery.
- Improved raw read tracking and provenance in the ReadTool to support refined file snapshot recording and hashline editing.
- Excluded recovered assistant messages from default model context and updated event controllers to handle retry recovery life cycles.
2026-07-04 11:22:04 +02:00
can1357 d5e9084e65 refactor: restructured audit logic and render boundary tracking
- Removed complex snapshot caching and volatile/stable state tracking logic.
- Replaced multi-zone audit logic with streamlined tail-sample checks.
- Simplified render boundaries by deriving a single final boundary from the live region.
- Eliminated redundant audit state management and auxiliary safe-end interfaces.
2026-07-04 09:50:20 +02:00
roboomp 8bd40a6db9 test(browser): restored cmux release mocks after each test
The cmux release regression tests install spies on CmuxSocketClient.prototype. Bun keeps those spies active across later browser-* files unless the file restores them explicitly, so browser-cmux-socket.test could stop exercising the real socket client depending on order.

Restore all Bun test mocks in afterEach after draining any test tabs, preserving mocked cleanup while preventing cross-file pollution.

Fixes #4499
2026-07-04 06:29:41 +00:00
roboomp a6a8258945 fix(browser): propagate cmux tab-close into the run body, not only the caller
Codex review of #4502 flagged that a bare `.catch(() => undefined)`
neutralizes the unhandledRejection but leaves the affected `runInTab`
call blocked inside `runCmuxCode` until timeout when the in-flight
code does not make another cmux socket request (e.g. `await
wait(60_000)`). `releaseTab` was signaling the run only by rejecting
an orphaned promise.

Wire the tab-close event all the way into the cmux run body:

- `PendingRun` gains a `closeAc: AbortController` that `releaseTab`
  aborts BEFORE calling `pending.reject`. `wait(...)` (via
  `waitForBrowserRun` -> `untilAborted`), in-flight cmux socket calls
  (via CmuxTab's `#request` -> `untilAborted`), and facade proxies
  (via `bindBrowserRunFacade`) all consume the composed signal, so
  the run body unwinds within a microtask instead of blocking to its
  own timeout.
- `runInTabWithSnapshot`'s cmux branch composes `closeAc.signal` into
  the run's signal (`AbortSignal.any([opts.signal, closeAc.signal])`)
  and now publishes `runCmuxCode(...)`'s outcome to the shared
  `promise` via `.then(resolve, reject)` and returns `await promise`.
  Both branches thus await the same promise, so `pending.reject`
  always has an attached handler (removing the original crash) AND
  the caller sees `Tab "..." was closed` immediately instead of
  waiting on the run's timeout.
- Drop the defensive `promise.catch(() => undefined)` — the promise
  is now actively consumed on both backends.

The new regression test adds a second case that exercises the
reviewer's exact scenario (`await wait(60_000);`) and asserts:
1. `pending.closeAc.signal.aborted` flips from `false` to `true`
   across `releaseTab`, with the tab-close error as its reason.
2. The awaited `runInTab(...)` rejects with `Tab "..." was closed`.
3. No `unhandledRejection` fires.

Verified locally by temporarily removing `closeAc.abort(...)` in
`releaseTab` — the new assertions fail; restoring it makes them pass.

Fixes #4499
2026-07-04 06:24:45 +00:00
roboomp 3622094e91 fix(browser): swallowed cmux tab-close rejection to prevent session crash
The cmux branch of `runInTabWithSnapshot` awaits `runCmuxCode(...)`
directly and never awaits/`.catch`es the `Promise.withResolvers()`
promise it stashes on `tab.pending`. When `releaseTab` walks pending
runs and calls `pending.reject(new ToolError("Tab ... was closed"))`
(a sibling subagent's `browser close --all`, session-scoped reap, etc.),
that orphaned promise had zero handlers and Bun surfaced the rejection
as `unhandledRejection`, which the CLI's top-level handler treats as
fatal — killing every other tab and subagent sharing the process, not
just the affected run.

Attach a no-op `.catch(() => undefined)` to the promise immediately
after creation. Inert for the worker branch (which still awaits the
same promise via `raceWithTimeout`, and attaching a second handler is
safe) and neutralizes the orphan on the cmux branch.

Adds a regression test that drives real `acquireBrowser` /
`acquireTab` / `runInTab` / `releaseTab` against a mocked
`CmuxSocketClient`, races `releaseTab` against an in-flight cmux run,
and asserts no `unhandledRejection` fires.

Fixes #4499
2026-07-04 06:06:18 +00:00
roboomp 74a8289404 fix(coding-agent): guarded write renderer content
Coerced runtime write content before preview rendering so truthy non-string transcript values cannot crash CR normalization, line counting, or highlighting.

Added regression coverage for pending write calls and merged write results with non-string runtime content.

Fixes #4495
2026-07-04 05:22:21 +00:00
can1357 fef9b62334 chore: bump version to 16.3.5 2026-07-04 05:19:15 +02:00
can1357 3046718695 chore: update chanelogs 2026-07-04 05:16:58 +02:00
can1357 3dec7ac12c Merge remote-tracking branch 'origin/farm/99fd01f3/fix-linux-tiny-cuda-runtime' 2026-07-04 05:15:18 +02:00