Commit Graph
1555 Commits
Author SHA1 Message Date
metaphoricsandcan1357 8e21f4b41d fix(coding-agent): route MCP connecting banner through the render tree
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.
2026-06-14 17:24:21 +02:00
can1357 99a4e2933e fix(tui): fixed native scrollback loss for streaming assistant rows
- Tracked snapshot-safe boundaries to retain commit-stable streamed rows in scrollback.
- Computed durableBoundary from commit and snapshot ends to prevent row drop regressions.
- Updated audit-row handling so drifting durable rows were excluded from resync checks.
- Added regression tests for commit-stable and commit-unstable relayout streaming cases.
2026-06-14 17:10:35 +02:00
can1357 c031662e1b Merge remote-tracking branch 'origin/farm/71308c81/prompt-templates-in-slash-autocomplete' 2026-06-14 17:10:19 +02:00
can1357 d4f6d39d88 Merge remote-tracking branch 'origin/farm/bbef5632/fix-theme-session-export-with-custom-lig' 2026-06-14 17:10:19 +02:00
can1357 c9adcd5da5 Merge remote-tracking branch 'origin/farm/17ca1d16/defer-goal-objective-while-streaming' 2026-06-14 17:10:18 +02:00
can1357 42bd488859 Merge PR #2542: feat(coding-agent): opt-in experimental auto-learn (memory + isolated managed skills) 2026-06-14 17:09:41 +02:00
can1357 a93ceabaad Merge remote-tracking branch 'origin/farm/1b8d98f8/plan-toggle-exits-to-none' 2026-06-14 16:14:33 +02:00
can1357 b830f7912b feat: unified speech setup and introduced local STT/TTS capabilities
- 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.
2026-06-14 16:07:44 +02:00
roboomp b3e1173bb5 fix(theme): aligned export text with export surface
Derived HTML default text from the resolved export card/page surface, falling back to the derived user-message export base when themes omit export overrides.

Covered light-status custom themes whose dark userMessageBg drives derived export backgrounds.

Fixes #2516
2026-06-14 07:26:15 +00:00
roboomp 207caa3621 fix(coding-agent): drop stale goal continuation tick while streaming
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
2026-06-14 07:22:42 +00:00
roboomp 0fbe4e1535 fix(coding-agent): preserved prompted paused plan commands
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
2026-06-14 07:19:37 +00:00
roboomp af4388e059 fix(coding-agent): reserved slash command aliases
Included builtin slash-command aliases in prompt-template autocomplete reserved names so picker suggestions match interactive command resolution.
2026-06-14 07:17:38 +00:00
can1357 ff0fc74f53 feat(coding-agent/modes): implemented space-bar hold push-to-talk STT gesture
- Added a space-hold gesture state machine in CustomEditor, tracking repeated spaces, detecting holds beyond SPACE_HOLD_THRESHOLD, and firing start/end callbacks via a release timer.
- Hooked editor space-hold callbacks in InputController so STT toggles on hold start and again on release when STT is enabled.
- Added tests for space-hold start/stop behavior and updated keybinding docs to describe the hold-to-record STT workflow.
2026-06-14 08:34:56 +02:00
can1357 e2e37dcde6 fix(coding-agent): fixed stale loader recovery and updated catalog model constraints
- Stopped and cleared the working loader before auto-compaction and auto-retry.
- Ensured stale loadingAnimation is removed so agent_start recreates the Working loader.
- Set catalog model input/output costs to 0.09/0.18 and reduced maxTokens to 65536.
2026-06-14 06:59:26 +02:00
can1357 c4ef8839d5 feat(tui): added large-paste collapse flow with threshold and attachment fallback
- Added `paste.largeMenuThreshold` setting with default 100 and values 0/100/250/500/1000.
- Added `Editor.onLargePaste` and `Editor.insertPaste` to intercept oversized pastes and expand markers.
- Added threshold-based large-paste routing to show the menu and wrap oversized content for code/XML or attachment fallback.
- Added tests for large-paste interception, fallback behavior, short-paste handling, and marker expansion.
2026-06-14 05:20:55 +02:00
can1357 86245d722a fix(coding-agent): gated agent hub opening when no subagents are available
- 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.
2026-06-14 05:18:35 +02:00
can1357 0ee1b111ba fix(coding-agent): fixed duplicate model-role cycle track in chat scrollback
- 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.
2026-06-14 05:02:04 +02:00
can1357 a1d1d4c44f feat(coding-agent/modes): added shared compact divider for handoff summary
- Routed `customType: "handoff"` messages to the compact divider path in Agent Hub and UI helpers.
- Added handoff summary expansion that extracts context text and strips `<handoff-context>` wrappers.
- Refactored shared divider rendering into `SummaryDividerComponent` used by compaction and handoff messages.
2026-06-14 04:29:11 +02:00
can1357 323c666ebf fix(coding-agent): hardened left-double-tap gesture handling against bursty arrow events
- Hardened left-arrow double-tap handling with a new detector that only fires on a second tap in a 40--500ms window.
- Reused that detector for both Agent Hub opening and focused-subagent return so terminal-synthesized burst taps no longer trigger navigation.
- Added gesture tests for deliberate doubles, burst suppression, minimum-gap filtering, and focused-subagent unfocus behavior.
2026-06-14 04:27:39 +02:00
metaphorics 18ee97751a feat(coding-agent): opt-in experimental auto-learn (memory + isolated managed skills)
Add a default-off "auto-learn" loop. When `autolearn.enabled` is set, after the
agent stops a session controller nudges it to capture reusable lessons: durable
facts go to long-term memory and repeatable procedures become "managed skills" —
SKILL.md files written to an isolated ~/.omp/agent/managed-skills directory that is
discovered and surfaced like authored skills but never overwrites them.

Two tools back this:
- `manage_skill` — create/update/delete managed skills.
- `learn` — record a lesson, optionally minting/enhancing a managed skill in the
  same call (requires a hindsight/mnemopi memory backend).

The nudge is passive by default (a hidden reminder rides the next turn);
`autolearn.autoContinue` instead auto-runs one capture turn at stop, and
`autolearn.minToolCalls` (default 5) gates trivial turns. Plan/goal-mode turns and
subagents are never nudged, and the controller re-checks the live setting at fire
time so a mid-session opt-out takes effect.

Isolation & precedence: managed skills are a separate lowest-priority discovery
provider, so an authored skill of the same name wins across every provider and
custom directory regardless of third-party toggles; a disabled higher-priority
authored skill can never hide a managed one, and managed never masks an enabled
authored skill. Managed names and descriptions are sanitized on both write and
read (control/format chars, angle brackets, and Markdown fences) before they render
into the system prompt, and the SKILL.md byte cap is enforced on the final
serialized file.

Default off → zero footprint when disabled.
2026-06-14 10:45:23 +09:00
can1357 ca779a9eef Merge PR #2519: classify HTML export theme defaults by status-line luminance 2026-06-14 03:32:54 +02:00
can1357 afc0f8c2d2 Merge PR #2502: add guided-goal setup interview 2026-06-14 03:32:53 +02:00
can1357 90fe4995cf Merge PR #2513: /plan exits paused state back to mode none 2026-06-14 02:59:26 +02:00
can1357 0b4efb365d Merge PR #2524: stop AgentBusyError on plan approval and loop/goal continuations 2026-06-14 02:59:26 +02:00
can1357 98fc23899f Merge PR #2533: renumber image markers when restoring queued messages
# Conflicts:
#	packages/coding-agent/test/input-controller-compaction-image.test.ts
2026-06-14 02:59:17 +02:00
can1357 7ca0ca3b06 Merge PR #2530: restore compaction-queued messages on Alt+Up dequeue 2026-06-14 02:57:25 +02:00
can1357 83b00e79a1 Merge PR #2520: run plan-approval compaction on the plan model 2026-06-14 02:57:19 +02:00
can1357 4d01e5e703 Merge PR #2490: clean up compaction UI lifecycle 2026-06-14 02:57:18 +02:00
can1357 81bf6ee965 Merge PR #2506: glow magic keywords through cursor seam + focused shimmer 2026-06-14 02:57:08 +02:00
can1357 0c8cee3080 Merge PR #2521: clamp editor height and overlays on small terminals 2026-06-14 02:56:57 +02:00
can1357 eb5cc85eed Merge PR #2528: emit per-turn token-usage row as standalone block 2026-06-14 02:56:50 +02:00
can1357 dddfc3320c Merge PR #2526: phase-lock tool-call spinners across parallel calls 2026-06-14 02:56:44 +02:00
can1357 f66b14958d Merge PR #2489: memoize tool-result rendering 2026-06-14 02:56:37 +02:00
can1357 4fe11fcbf5 Merge PR #2481: work-aware subagent roster (role + activity) [#2478-2481] 2026-06-14 02:56:21 +02:00
roboomp f41007d7da style: bun run fix 2026-06-14 00:24:34 +00:00
roboomp 2e431c0c21 fix(coding-agent): renumber image markers when restoring queued messages
`restoreQueuedMessagesToEditor` prepended queued text but appended queued
images to `pendingImages`. Positional `[Image #N]` lookup at submit time
therefore broke whenever the editor draft already held pending image(s):
queued markers (numbered 1..K against their own image list) collided with
draft markers (1..M) and resolved to the wrong images; queued images
landing past slot M were orphaned.

Add `shiftImageMarkers(text, offset)` to `image-references.ts` and have
`restoreQueuedMessagesToEditor` walk each queued message in order,
shifting its markers by the running pending-image count (existing draft
images plus images already pulled in from earlier queued messages). Draft
markers stay untouched because draft images keep their original slots.
Paste markers are left alone — those are owned by the editor's paste store,
not the pending-image buffer, and queued message text never carries
unmaterialized `[Paste #N]` because the editor expands paste markers in
`getExpandedText()` before `onSubmit` fires.

Regression test seeds a draft image + a queued image-message in
`input-controller-compaction-image.test.ts` (per acceptance) and locks the
marker -> image mapping after restore. Unit tests for
`shiftImageMarkers` cover the WxH tail, Paste-marker passthrough, and
the zero-offset no-op.

Fixes #2531
2026-06-14 00:24:28 +00:00
can1357 24c8bb24c6 feat(session): added modular session APIs and rebuilt listing/persistence behavior
- Added session-domain modules and exports for session-entries, context, listing, loader, and migrations.
- Changed persistence to async append writes plus writeTextAtomic, removing sync line APIs.
- Added compaction-aware session context rebuild with dangling tool-call cleanup.
- Added resumable session resolution with status inference, id/stem/suffix matching, and backup recovery.
2026-06-14 02:02:53 +02:00
metaphorics 5e5e237005 feat(task): inline role specialization for spawned subagents
Add an optional `role` field to the task spawn contract, threaded end to
end through resolveSpawnItems/spawnParamsFor into the executor. A role
injects a specialization preamble into the subagent system prompt and
becomes the subagent's display name and telemetry identity (label
normalized, length capped), so delegated trees stop being clones of one
generic worker. Empty/absent roles fall back to the agent type name.

Refs #2467

Op: extend
2026-06-14 08:47:01 +09:00
metaphorics a95be2860f fix(tui): honest editor-height floor and dead-branch cleanup
Addresses Copilot + Codex review on #2521:

- computeEditorMaxHeight returned 1 on terminals too small to host both the
  editor and the chrome reserve, but the bordered editor never renders fewer
  than 3 rows (2 border + 1 content). The cap now floors at that real minimum
  (EDITOR_MIN_RENDERED_ROWS) so it no longer misreports the rows the editor
  occupies; rendering is unchanged, and the contract is documented honestly
  (reserve holds once terminalRows >= 7).
- #resolveOverlayLayout now always resolves maxHeight (?? availHeight), so the
  maxHeight !== undefined branch in effectiveHeight, the composite slice guard,
  and the number | undefined return type were dead. Tightened all three.
- Mirrored the maxHeight-default contract in the render stress oracle
  (resolveExpectedOverlayLayout + compositeExpectedOverlays) so the randomized
  sweep validates the real clipped geometry instead of the obsolete unclipped
  one; updated the oracle helper test expectation accordingly.

Editor-height tests rewritten to assert the real contract (reserve when the
terminal can host both; pinned to the bordered minimum below that).
2026-06-14 08:40:12 +09:00
metaphorics f6d69620f9 fix(coding-agent): restore compaction-queued messages on Alt+Up dequeue
restoreQueuedMessagesToEditor only drained the agent steering/follow-up
queue via session.clearQueue(), but the "Alt+Up to edit" pending-bar
hint is rendered for both that queue and ctx.compactionQueuedMessages.
Messages typed while the session was compacting -- including /skill:*
follow-ups, which the follow-up path routes to the compaction queue
before its skill check -- were advertised by the hint yet unreachable,
so Alt+Up reported "No queued messages to restore".

Drain compactionQueuedMessages alongside the agent queue, merged in the
same order the pending bar renders (session-steer, compaction-steer,
session-follow-up, compaction-follow-up). The existing text-join, image
hand-back, and abort paths operate on the merged list unchanged.
2026-06-14 08:39:18 +09:00
metaphorics 0ad4c8525c fix(coding-agent): restore model on compaction cancel and before queue flush
Addresses Codex review on #2520:

- Cancel path: `#approvePlan` returned on `compactOutcome === "cancelled"`
  without restoring the deferred pre-plan model, stranding the next turn on
  the plan model and leaking `#planModePreviousModelState`. The model
  transition now runs for the cancelled outcome too (the operator aborted
  only the compaction, not the approval) before the early return.
- Queue-flush ordering: `executeCompaction` flushes input queued during
  compaction before returning, so the post-return model switch landed after
  the queued turn began streaming (deferred one turn via #pendingModelSwitch).
  Added a `beforeFlush(outcome)` hook to `executeCompaction`/`handleCompactCommand`;
  `#approvePlan` runs the transition through it (and idempotently re-runs it
  afterward to cover the message-count short-circuit).

Tests cover the cancel restore and the before-flush ordering.
2026-06-14 08:33:10 +09:00
can1357 65880477fe docs(coding-agent/modes): documented fix for unmatched OSC 133 command markers
- Added a changelog entry describing that submitted user messages no longer pair OSC 133 command-start markers with missing end markers.
- Annotated the user-message component with guidance to avoid emitting OSC 133 command-start markers for submitted prompts.
2026-06-14 01:32:46 +02:00
can1357 ef2304aaca fix(coding-agent/modes): removed redundant OSC133 final zone marker
- Removed the unused OSC133 final zone marker constant from the user message component.
- Stopped appending the final OSC133 marker so rendered messages now end with only the shell integration close code.
2026-06-14 01:32:46 +02:00
metaphorics 67cf33ed2d fix(coding-agent): clean up compaction UI lifecycle
executeCompaction added a transcript Spacer(1) the handoff path never adds; it leaked as an orphan blank line on cancelled/failed compaction (only the OK branch cleared it via rebuildChatFromMessages). Removed it, and on the OK branch the loader is stopped + statusContainer cleared before the rebuild so the live loader no longer composites over the reconciled transcript. The finally block stays as the idempotent cancel/fail safety net.
2026-06-14 08:25:57 +09:00
metaphorics ee45472c05 fix(coding-agent): memoize tool-result rendering to stop per-frame re-shape stalls
ToolExecutionComponent.#updateDisplay() re-ran renderResult (O(result-size)) on every invalidate - spinner ticks, stream chunks, resizes, keystrokes - so large results blocked the loop for seconds and typing lagged. It now early-returns on an unchanged dirty key (result version, expanded, partial, spinner frame, image visibility, theme epoch), and theme.ts exposes getThemeEpoch() bumped on every theme swap so cached blocks re-render on theme change.
2026-06-14 08:23:57 +09:00
metaphorics 35307b60a7 fix: emit per-turn token-usage row as a standalone block
With display.showTokenUsage on, the usage row was rendered inside the
assistant block above the turn's tool blocks. Finalizing the assistant
block was therefore deferred, and the late append recommitted the
already-committed tool rows, duplicating them in scrollback (worst with
parallel tool calls).

The assistant block now always finalizes as soon as a tool-call appears,
and the usage row is emitted as a standalone finalized block below the
turn's tool blocks across all three render paths (live event-controller,
transcript rebuild, agent-hub). The now-dead setUsageInfo/#usageInfo path
on AssistantMessageComponent is removed.
2026-06-14 08:17:36 +09:00
metaphorics 34746ceaf5 fix: stop AgentBusyError on plan approval and loop/goal continuations
Plan approval dispatched the executor's first synthetic prompt without
checking whether the agent was still streaming the post-resolve
continuation (or a turn started by the approve-time compaction/clear),
surfacing "Failed to finalize approved plan: ... Agent is already
processing". Loop auto-submit and goal continuations hit the same throw
via submitInteractiveInput, which always called prompt/promptCustomMessage
without a streamingBehavior.

#approvePlan now aborts any in-flight turn before the synthetic prompt,
and submitInteractiveInput routes submissions through the steer/follow-up
queue (streamingBehavior: "followUp") when the session is streaming.
Non-streaming call shapes are unchanged. Extends the manual-/goal fix
(#2454) to the continuation and plan-approval paths.
2026-06-14 08:17:00 +09:00
metaphorics b85f599917 fix: phase-lock tool-call spinners across parallel calls
Each live ToolExecutionComponent advanced its spinner glyph from its own
per-instance start time, so concurrent tool spinners showed different
frames and read as janky. Derive the glyph from a single shared monotonic
clock (sharedSpinnerFrame) so every live block animates in lockstep; the
per-instance interval still drives requestRender. The unused
#lastSpinnerAdvanceAt anchor is removed; the todo-strike counter is
untouched.
2026-06-14 07:38:37 +09:00
metaphorics b28ad9a1dc fix(tui): clamp editor height and overlays on small terminals
Two bounded TUI overlap fixes:

- Editor max-height (coding-agent): the [6,18] clamp's floor of 6 exceeded
  available space on terminals <=18 rows, letting the editor crowd the
  transcript/status. Extracted a pure computeEditorMaxHeight(rows) with an
  EDITOR_MIN_CHROME_ROWS=4 upper bound; identical for rows >=18.
- Overlay overflow (tui): #resolveOverlayLayout left maxHeight undefined when
  the option was unset, so a tall overlay's bottom rows were dropped
  off-screen. maxHeight now defaults to availHeight so every overlay is
  sliced to fit and re-clamps on resize.
2026-06-14 06:59:58 +09:00
metaphorics 44b9d70c6f fix(coding-agent): run plan-approval compaction on the plan model
When a plan is approved via "Approve and compact context", #exitPlanMode
restored the pre-plan model before the compaction summarizer ran, so the
request cold-missed the plan model's warm prompt cache. The model switch is
now deferred: compaction runs on the plan model, and the switch to the
execution (slider) or pre-plan model happens only after a successful
compaction. A failed compaction stays on the plan model; cancellation is
unchanged. Also clears any queued plan-role model switch when deferring the
restore so it cannot later clobber the restored model.
2026-06-14 06:58:36 +09:00