Tail appended transcript JSONL instead of rebuilding rendered history on every poll, collapse compacted history for live chat rendering, and replace synchronous session rewrites so tailers detect historical changes.
Fixes#3258
- Centralized draft state and image management by migrating fields from context to the CustomEditor component.
- Standardized transcript row construction by introducing shared helpers for background jobs, IRC traffic, and file mentions.
- Refactored redundant UI logic and helper functions into reusable utility modules to streamline message submission and component rendering.
- Standardized event handler types by consolidating lifecycle definitions into a shared module while maintaining public API stability.
Updated optimistic replay to track the replacement component handles created during transcript rebuilds, so expanded slash prompts still replace the raw replayed message.
Extended the regression test to cover the rebuild window called out in review.
Fixes#3199
Replaced raw optimistic slash-command transcript entries with the canonical user message emitted by AgentSession when prompt expansion changes the text.
Added coverage for prompt-template expansion reconciliation so the transcript keeps one expanded user message.
Fixes#3199
Tracked current-registry built-in provenance through AgentSession so plan mode
only force-activates the built-in write implementation. Extension or SDK tools
that shadow the name `write` stay inactive, preserving plan mode's read-only
contract through the built-in write/edit guard.
Added a regression that registers a shadowing write tool without built-in
provenance and verifies plan mode does not activate it.
Plan-mode entry only added `resolve` to the active toolset, so when
`tools.discoveryMode: "all"` left `write` hidden behind
`search_tool_bm25` the agent was stuck with `edit` to create the plan
file — which fails on a non-existent path and stalls the planning
turn. `#enterPlanMode` now augments the active set with both `resolve`
and `write` whenever the registry built them, matching what
`plan-mode-active.md` instructs the model to use, and `#exitPlanMode`
still restores the pre-plan toolset verbatim.
Fixes#3165
- Replaced the `/debug dump-next-request` command with an updated `/dump` command that exports LLM request context to JSON sidecar files.
- Removed persistent debug path state and manual path configuration in favor of automated generation.
- Updated session logic to handle serializing LLM request context to temporary directories.
- Refactored testing suites to remove path-based debug tests and verify dynamic request file generation.
- Stop the Esc key from aborting active background maintenance (compaction, handoff, or retry) while a subagent is focused.
- Remove "(esc to cancel)" hints from maintenance loaders when a subagent is active to avoid false affordance.
- Ensure that main-session maintenance remains cancellable via Esc when no subagent is focused.
Fixes#2819
Adds 'c copy' to the completed /btw panel footer (alongside b branch / Esc
dismiss), copying the sanitized visible answer to the clipboard. The copy
shortcut is guarded by canCopyBtw + main-editor focus + empty editor.
Shows live per-command status (plan/goal/loop/model/advisor/collab/jobs/
context/...) in the slash-command autocomplete.
Adjustments on merge:
- Exclude the two .github/pr-assets/*.png screenshots.
- Resolve the autocomplete.ts conflict keeping main's skill-command empty-prefix
boost alongside the new static-vs-display description split.
- Compute the live display description lazily — only once a command actually
matches (name or alias) — instead of for every command on each keystroke, and
guard the getter with a typeof check. getAutocompleteDescription reads live
session state, so the eager call was O(commands) work per refresh.
Emitted MCP connection lifecycle events through the startup event bus so the TUI can replace the initial connecting banner with connected, pending, or failed server state.
Added manager and interactive-mode coverage for mixed success/failure MCP startup updates.
Fixes#3150
- Added a `proseOnlyThinking` configuration setting to suppress raw code blocks in AI thinking traces.
- Implemented `formatThinkingForDisplay` utility to replace code blocks with ellipses in the UI.
- Integrated runtime toggling and live refreshing of message components via streaming reveal controllers.
- Added a live tokens-per-second indicator to the assistant thinking pulse.
- Verified logic with new unit and integration tests for thinking block presentation.
- Enabled inline prompt execution by allowing /loop to accept a trailing follow-up message.
- Added support for compound duration formats (e.g., 1h30m) within limit specifications.
- Updated logic to distinguish between limit tokens and prose to maintain backwards compatibility for unbounded loops.
- Refactored loop argument parsing to return both duration/count limits and optional string prompts.
- Added tracking for expected cache invalidations during model changes, compactions, and plan-mode transitions.
- Included `cacheMissExplainedAt` metadata in session context to prevent displaying misleading cache miss warnings in the transcript.
- Updated controller logic to reset assistant usage markers when mode-switching or performing actions that invalidate the prompt cache.
- Implemented `detectCacheInvalidation` to identify when model requests lose their prompt cache.
- Added `CacheInvalidationMarkerComponent` to display a slim notice above affected assistant turns.
- Updated `ChatTranscriptBuilder` and `EventController` to track session usage and inject markers dynamically.
- Included comprehensive test coverage for invalidation detection logic and UI rendering.
- Added a `mode` property to `CompactOptions` to allow fine-grained control over compaction strategies.
- Implemented `soft`, `remote`, and `snapcompact` submode overrides for the `/compact` command.
- Integrated `parseCompactArgs` to enable robust subcommand routing and validation, including focus instruction rejection for specific modes.
- Established a `CompactMode` registry to manage compaction strategies and verify remote availability.
- Added `#disposed` flags and guards to `StatusLineComponent` to stop async callbacks running post-dispose.
- Updated `onThemeChange` to return an unsubscribe function and registered it in `InteractiveMode`.
- Fixed schema validation for `spinnerFramesSchema` to narrower types instead of dynamic or-validation.
- Resolved settings leaks by saving and restoring `tuiTight` state in tests.
- Added regression tests verifying that pending async microtasks do not trigger updates after disposal.
- Added new `tui.tight` setting with default `false` and documented behavior.
- Added global tight-mode APIs and `setIgnoreTight` propagation across Box, Text, and Markdown.
- Handled `tui.tight` updates to refresh UI borders and trigger rerendering.
- Updated key message components to ignore tight mode selectively and preserve intended spacing.
- Added context snapshot metadata to AssistantMessage for prompt and non-message token history.
- Anchored context usage calculations on assistant snapshots and computed percent numerically.
- Updated status-line, /context, selector, and interactive mode flows to share session usage totals.
- Extended status-line cache fingerprinting and invalidation for assistant usage and prompt/tool/skill changes.
- Added LaTeX math and Mermaid allowances in terminal and final-chat prompts.
- Added inline math tokenization in TUI for $, $$, \(\), and \[\].
- Added LaTeX-to-Unicode conversion helpers and exports for math rendering.
- Fixed inline math detection to skip escaped dollars and currency-like spans.
- Removed render_mermaid from tool discovery, task definitions, and registries.
- Removed renderMermaid setting and prompt/docs references tied to the deleted tool.
- Added maxWidth and theme color options to Mermaid ASCII resolution in markdown flow.
- Re-rendered Mermaid ASCII in both directions and clipped output to available width.
- Rewrote `formatSessionDumpText` in `session-dump-format.ts` to emit the pre-16.x full dump: system-prompt prelude, model/thinking config, tool inventory with parameters, and the transcript as markdown role headings (`## User`, `## Assistant`, `### Tool Call`/`### Tool Result`), reusing `renderDelimitedThinking` for `<thinking>` blocks.
- Dropped the compact default and the `[raw]` flag from `/dump`: removed the `isRaw` parameter from `handleDumpCommand` in `command-controller.ts`, `interactive-mode.ts`, and `types.ts`, and removed the `inlineHint: "[raw]"`/`compact` plumbing in `builtin-registry.ts`.
- Updated the `formatSessionAsText` doc comment in `agent-session.ts` to describe the verbose dump shape.
- Removed the obsolete `formatSessionDumpText raw thinking` suite from `advisor.test.ts` and refreshed `session-dump-format.test.ts` to assert the verbose dump output.
- Recorded the revert in the coding-agent changelog and trimmed `/dump` from the compact transcript tool-intent-prefix entry.
- Created AdvisorRuntime and AdviseTool to drive a read-only advisor agent that delivers severity-tagged advice (nit, concern, blocker) with interruption policy and transcript delta rendering.
- Added /advisor slash command with on/off/status/dump subcommands to control advisor lifecycle and inspect advisor metrics (model, messages, tokens, cost).
- Added advisor.enabled and advisor.subagents settings to enable passive advisor review on main agent and spawned task/eval subagents.
- Implemented advisor message rendering with severity-color badges (blocker=error, concern=warning, nit=muted) in chat log and status line indicator (++ badge).
- Extended yield-queue and session-history-format to support advisor batching and optional thinking block inclusion.
- Suppressed MCP connecting and LSP startup event renders when startup.quiet is enabled.\n- Added regression coverage for quiet MCP and LSP startup event handling.\n\nFixes #2639
- Added a streamingBehavior field to submitted user inputs and threaded it through interactive mode types and controller start-up.
- Updated interactive submission dispatch to default to followUp queueing while preserving explicit steer intent when provided.
- Changed tests to verify followUp and steer queueing behavior, preventing AgentBusyError from race-window busy sessions.
When a running session changes projects via /move or resumes a session
from another cwd, applyCwdChange() reloads project settings but did not
reapply the module-level provider preferences (providers.webSearchExclude,
providers.webSearch, providers.image). The previous project's exclusions
could leak and newly-excluded providers were still used by web_search.
Reapply all three provider preferences after settings.reloadForCwd(),
mirroring the initialization logic in createAgentSession.
Closescan1357/oh-my-pi#2611 (discussion_r3411061509)
ExtensionRunner.emit shared the generic 30s EXTENSION_HANDLER_TIMEOUT_MS budget with every event, including the fire-and-forget session_shutdown teardown event extensions cannot observe. A hung third-party handler — observed on Windows with omp-discord-presence 0.1.2 waiting on a stuck Discord IPC pipe — held AgentSession.dispose() for the full window, making Ctrl+C look ignored for 30s.
session_shutdown now uses a dedicated 2s SESSION_SHUTDOWN_HANDLER_TIMEOUT_MS cap routed through a per-event handlerTimeoutForEvent() lookup so generic and shutdown budgets are independently configurable. The interactive-mode Ctrl+C path adds a defence-in-depth hard-exit: when isShuttingDown is true a fresh Ctrl+C exits with code 130 (the session JSONL has already been sync-flushed by the first press) instead of stacking another no-op shutdown() call.
Fixes#2600
Deferred MCP discovery wrote 'Connecting to MCP servers: …' straight to process.stderr while the TUI owned the terminal, overdrawing the chat input box border. onMCPConnecting now emits McpConnectingEvent on the mcp:connecting channel; InteractiveMode subscribes and renders it via showStatus (status container), mirroring the LSP-startup pattern. New mcp/startup-events.ts holds the channel, type, and formatMCPConnectingMessage.
- Added unified `omp setup speech` flow with JSON/check modes and model picker.
- Added local STT pipeline with sherpa workers, recorder/download flow, and streaming inference.
- Added local TTS pipeline with `omp say`, backend selection, and streaming vocalization.
- Replaced legacy speech settings with unified `speech`/`speechgen` configuration keys.
Reviewer flagged a race left open by the streaming guard added in #2455:
getUserInput() arms onInputCallback and schedules an 800 ms goal
continuation timer; when /goal set takes the streaming branch (or any
extension/hook starts a turn inside that window), the timer fired
unchecked. The downstream onInputCallback resolved the main waiter with
a goal-continuation submission, submitInteractiveInput called
session.promptCustomMessage without a streamingBehavior, and the same
AgentBusyError the PR set out to fix resurfaced.
Make the continuation timer streaming-aware: at fire time, bail out
when session.isStreaming || isCompacting || hasPostPromptWork is true.
Reuses the auto-submit busy check loop mode already relies on (renamed
#isLoopAutoSubmitBlocked -> #isAutoSubmitBlocked since both flows have
the same notion of 'agent is busy, do not submit'). The next agent_end
in #handleGoalSessionEvent reschedules normally.
Fixes#2454
Kept /plan <prompt> from paused plan mode on the prompted entry path while retaining the no-arg third-toggle exit.
Added regression coverage for paused plan mode resuming and submitting the prompt.
Fixes#2510
- Added an `isEmpty` getter on `AgentHubOverlayComponent` to report whether no subagent rows were loaded.
- Extended `showAgentHub` with an optional `requireContent` flag so the overlay is disposed early when empty under the double-<- path.
- Added tests for double-<- gating behavior with no subagents, with subagents, and explicit hub-open behavior.
- Moved the ctrl+p model-role cycle rendering from `showStatus` to a dedicated anchored cycle container above the editor.
- Updated InteractiveMode to rebuild the cycle container in place and auto-clear the track after 4 seconds.
- Added tests that validate no scrollback stacking, in-place replacement, and timer-based clearing behavior.