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
- 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.
Snapshot this.ctx.sessionManager.getSessionId() for the tan clone's local://
mapping instead of session.sessionId. The two diverge after /fresh or a
provider session override, and the Windows short-root fallback keys
%TEMP%/omp-local/<id> off the session-manager id used by the parent's
large-paste writes and '/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' reads, so the mismatched id left attachments
unreachable.
Diverge the mocked session id from the manager id in the regression test so
it pins the session-manager id.
Fixes#6971
(cherry picked from commit 1efcd22326d76fdb8b50c0977a836c892e80ab76)
Capture the parent artifacts directory and session ID when /tan dispatches
instead of resolving them through the mutable interactive SessionManager.
This keeps background tan '/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' reads pinned to the dispatching transcript
after the user switches or resumes another session.
Extend the regression test to switch the mocked interactive session before
the background job starts and assert the original local mapping is retained.
Fixes#6971
(cherry picked from commit e05db428eabd5087e4b2b4a462f47927c0628e72)
TanCommandController.start nests the tan clone at
<parent-artifacts>/Tan-<id>.jsonl, so the clone's session manager derived
its own artifacts dir and hence local root <parent-artifacts>/Tan-<id>/local.
Its sdk.createAgentSession call omitted localProtocolOptions, unlike the
task-subagent path which inherits the parent's mapping, so parent-session
'/data/workspaces/can1357__oh-my-pi__6971/.omp-session/2026-07-29T06-08-45-283Z_019fac7d-5ee3-7000-a7aa-16fe9394fdc9/local' attachments (pasted files, generated references) were unreadable.
Thread the parent session manager's localProtocolOptions into the tan clone
so local:// resolves against <parent-artifacts>/local.
Fixes#6971
(cherry picked from commit 1ded46e182fc24f9f57d8e9a907aaad58f790783)
- 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.
/usage, /session, /advisor status, /jobs, /changelog, /context, and
/memory view mounted their finalized panel immediately via ctx.present()
instead of ctx.presentCommandOutput(), the streaming-deferral path added in
#5427 for /tools and /mcp. When invoked mid-turn, the panel landed above a
still-growing live block and the append-only scrollback contract recommitted
it lower down, so it appeared twice in native scrollback.
Route all six large command panels through presentCommandOutput() so they
defer until agent_end, matching /tools and /mcp.
Fixes#6767
computeNonMessageBreakdown estimated Skills tokens from the unfiltered
session.skills registry and subtracted that from the first system-prompt
block, which only ever contained the rendered (filtered) skills. Hidden
explicit-only skills (hide/disable-model-invocation) and all skills when
the read tool was absent inflated Skills and clamped System prompt to 0.
Add a renderedSkills helper mirroring buildSystemPrompt's filter and use
it for the Skills estimate so the category split matches the provider
prompt.
Fixes#6498
- Add `pinSessionOAuthAccount` storage method and active account flag to the auth storage API.
- Introduce session account selector component, controller logic, and interactive mode delegation.
- Implement the `/session pin` builtin slash command with text listing and account pinning capabilities.
- Add unit tests covering session account selection, component navigation, and command handling.
Scheduling agent.continue() inside navigateTree started a post-prompt
task before the interactive /tree handler rebuilt its transcript, so a
fast provider's agent_start/turn_start could render against the stale
pre-rebuild UI and then be clobbered by renderInitialMessages.
navigateTree now reports the commit via askReanswerCommitted instead of
resuming, and SelectorController.showTreeSelector calls the new
AgentSession.resumeAfterAskReanswer() only after renderInitialMessages +
reloadTodos, so the resumed turn always renders against the rebuilt
transcript.
Addresses chatgpt-codex-connector review on #6484.
Fixes#6483
- Pinned displaceable snapshots like hub waiting polls and todo lists to the viewport during active execution.
- Prevented unpinned spinner ticks from repeatedly committing mutating rows to native scrollback and force-sealing blocks.
Moved vocalizer interruption from agent_start to user message_start so agentLoopContinue preserves queued speech.
Expanded regression coverage for continuation starts and user prompt boundaries.
Fixes#6375