- Make over-context models selectable in the model picker by graying them instead of disabling them.
- Trigger automatic session compaction with the current model prior to switching when an over-context model is chosen.
The Agent Hub kill path called AgentLifecycleManager.release(), which
disposes the session and then unregisters the ref while leaving the
on-disk <id>.jsonl intact. On the next hub open, registerPersistedSubagents
rescans the transcript tree and its `if (!registry.get(id))` guard cannot
distinguish an explicit kill from a normally-parked agent, so it re-adopts
the killed id as a fresh `parked` row.
Add a `tombstone` option to release() that mirrors finalizeSubagentLifecycle's
genuine-kill path: dispose and detach the session but keep the ref registered
as terminal `aborted` instead of removing it. The kept-registered id makes the
rescan guard skip it, and the transcript stays on disk (still reachable via
history://<id>, per #5261). The hub kill button now passes tombstone: true.
Fixes#7250
The live AskDialog trusted question.question while its render helpers
(replaceTabs, renderQuestionTitle, questionTabLabel) assume a string. A
question reaching AskDialogComponent without a string question field threw
an uncaught TypeError that escaped the TUI render loop and killed the
session. The transcript renderer already normalizes the same malformed
data via normalizeRenderQuestions; the live path did not.
Normalize the questions array at dialog entry (new normalizeDialogQuestions),
coercing question/id/label to strings and options to a well-formed array,
matching the transcript path.
Fixes#7211
Track entry into tool.execute separately from tool event emission. Never-started skips retain SyntheticToolResultDetails with executed:false; in-flight aborts now use distinct interrupted metadata with execution:started so consumers do not assume no partial work occurred.
Keep both interrupt states neutral in the TUI and cover the agent metadata boundary plus rendering behavior.
Fixes#7199
A tool call aborted mid-batch to service queued steering/peer input emits a synthetic placeholder result with isError:true so the model retries it. The TUI keyed all error styling (red ✘, red frame/text) off that flag, so a normal steering skip rendered identically to a real tool failure.
Mark the skip placeholder with the existing SyntheticToolResultDetails discriminator (source: "interrupt_skipped", executed:false) and render benign skips through the neutral generic card (info glyph, dim text, neutral background), bypassing any bespoke error frame. Genuine failures keep their error styling.
Fixes#7199
- Centralized PNG conversion behind an async boundary so constructor and encoder throws become promise rejections.
- Kept live and restored Kitty image rendering interactive by omitting failed conversions.
- Added regressions for both tool-result render paths.
Fixes#7160
macOS Terminal.app consumes Option for character composition, so Alt+Up
never reaches the app and the dequeue is unreachable there. Bind Shift+Up
alongside it -- Shift is not intercepted, and the key was unbound in the
input path.
The three overlay handlers that already use shift+up for fast scroll
(scroll-view, model-hub, log-viewer) match keys directly rather than
through the manager, so they never see this binding.
Both default tables move together: the registry in config/keybindings.ts
and DEFAULT_ACTION_KEYS in custom-editor.ts, which silently shadows the
registry when they disagree.
- Wrap status line path segment labels and worktree names in file hyperlinks.
- Apply hyperlink generation using the project directory and rendered path text.
- Add the `app.live.toggle` keybinding defaulted to `Ctrl+L` to start or stop live voice mode.
- Remap the default display-reset action (`app.display.reset`) from `Ctrl+L` to `Alt+L`.
- Update the live visualizer to listen for stop keys so the toggle chord terminates active sessions.
- Implemented clipboard register management, parsing, and execution rules for CUT, COPY, and PASTE operations in the hashline engine.
- Added session-persistent clipboard state and integration across agent session execution, diff previews, and streaming tools.
- Added comprehensive validation, error messages, recovery handling, and test coverage for clipboard and block operations.
- Updated task tool execution to pin live regions and drop partial snapshots once rows commit.
- Tracked background task frozen styled rows and render timestamps to prevent clock drift on committed history.
- Added tests verifying detached and blocking task progress do not duplicate rows in scrollback.
- Implemented session stores and metadata converters to import Claude and Codex sessions into OMP.
- Added `--from-claude` and `--from-codex` CLI flags and `/resume` command arguments for foreign session resolution.
- Updated session selector components and controllers to support listing and picking external agent sessions.
- Added comprehensive unit tests and documentation covering foreign session import functionality.
GitHub Copilot's call_id|id transport (and any stream that delivers a tool's name/args before its id) makes a streamed tool-call block appear with an empty or partial id, then rewrites it in a later delta. The transcript keyed the live card by that mutable content.id, so the changed id passed the creation guard and spawned a second card: the old-id card orphaned as a blue pending preview while the new-id card took the result.
Track the streamed id per tool-call block position (reset per assistant message) and migrate the live card's id-keyed trackers (pendingTools, tool timeline, args reveal, read tracking, and the shared read group's entry) when the id changes, so the populated id reuses the existing card.
Fixes#6879
- Replaced the `XdevRegistry` class with the `XdevState` interface and pure helper functions across core and session tools.
- Updated session configurations, tool execution, and renderers to utilize canonical tool map initialization and sharing.
- Adapted unit tests and mocks to use `XdevState` and associated helper functions for permission and dispatch verification.
- branch() and navigateTree() now return the selected user message's image
parts (selectedImages/editorImages) alongside the text, extracted in marker
order by #extractUserMessageImages.
- CustomEditor.setDraft() replaces the composer draft with text plus its
pending images, so restored [Image #N] markers resolve on resubmit instead
of degrading to literal text.
- Wired all six restore call sites (selector-controller, extension-ui-controller)
through setDraft; updated rpc-subagents mocks for the new branch shape.
- Added offline regression tests for branch/navigateTree image restitution,
multi-image marker order, and text-only prompts.
- Add an LRU cache to `scanSessionFile` in `session-listing.ts` keyed by file path, stat identity, and scan mode.
- Add a match key union probe in `CustomEditor` in `custom-editor.ts` to bypass per-action lookups on plain text input.
- Add tests covering cache hits, size and mtime invalidations, and negative result caching.
Render the Advisor spend next to the primary-model cost as `$2.67 (sub) + $0.41 (adv)`, leaving the status line unchanged until an Advisor cost exists.
Record the cost from finalized advisor `message_end` events in a per-session ledger instead of deriving it from the live advisor transcript, so an in-session compaction or any other history rewrite no longer resets the reported spend. The ledger is cleared for a new session and once a different-session switch commits, and survives a switch that rolls back.
handleDraftEdit routed everything through the base editor, which reserves Ctrl+C for the parent and returns without touching the buffer, so the configured app.clear never ran and the guard's 'finish or clear the prompt' hint had no working clear key when Ctrl+C reached the guard.
handleDraftEdit now dispatches the app.clear action explicitly (onClear, falling back to clearing its own text), which empties the draft and lifts the guard without swapping the editor slot.
Fixes#6737
The draft editor renders an insertion cursor only when its focused flag is set, but ask holds TUI focus, so the preserved draft had no visible caret while it required finishing or clearing.
The input guard now mirrors its blocked state onto the draft editor each ask render (editor is the next sibling in the same container), showing the cursor while it owns input and dropping it once the draft clears.
Fixes#6737