Skip to content

feat(ui): launch an agent with selected terminal text as context - #358

Merged
forketyfork merged 6 commits into
mainfrom
feat/selection-agent-context
Aug 15, 2026
Merged

feat(ui): launch an agent with selected terminal text as context#358
forketyfork merged 6 commits into
mainfrom
feat/selection-agent-context

Conversation

@forketyfork

@forketyfork forketyfork commented Aug 15, 2026

Copy link
Copy Markdown
Owner

Issue

There was no way to hand terminal output to an AI agent as context without manually copying and pasting it. Building this also surfaced problems in the adjacent, pre-existing "send diff comments to agent" feature, which shares its pending-delivery mechanism with the new flow:

  • sendCommentsToAgent compared a newline-terminated PTY input string against the bare agent name, so AgentKind.fromString never matched — "send to agent" was broken for claude/codex/gemini.
  • The pending-send delivery mechanism dropped a queued send entirely once its deadline passed without a confirmed agent match, instead of guaranteeing delivery like the previous implementation did.
  • The selection-agent context preview silently truncated at 4 lines while the full, unbounded selection was sent to the agent, with no indication anything was cut.
  • A leftover diagnostic log.warn dump fired on every modal open.
  • The new pending-send state machine and the relative --log-dir resolution path had no test coverage.
  • Minor UX gaps: a whitespace-only selection silently no-oped instead of giving feedback; the agent dropdown didn't restore prompt focus after closing; texture-creation errors were collapsed into an opaque error.LabelTextureFailed.

Solution

  • Releasing a text selection in a terminal shows a bottom-right "Launch agent" pill.
  • Clicking it opens a centered modal (selection_agent_overlay.zig) to pick an agent (Claude/Codex/Gemini), review the selected context, and write instructions.
  • Launching queues a LaunchAgentWithContext action; the runtime spawns a new terminal in the source session's working directory and defers sending the composed prompt until the target agent is confirmed running via drainPendingSessionSends, a generalized pending-send state machine that also now backs the pre-existing diff-comments-to-agent flow (documented as ADR-015).
  • Diff-comment agent matching now uses the bare agent name; the newline is appended only for the PTY write.
  • drainPendingSessionSends now sends anyway once the deadline passes instead of dropping the queued text.
  • The context preview shows a "+N more lines not shown" indicator when it truncates.
  • Removed the leftover diagnostic logging.
  • Added test coverage for drainPendingSessionSends (missing/dead session, deadline-based delivery) and for relative --log-dir resolution.
  • Whitespace-only selection now clears visibly instead of silently no-opping; the agent dropdown restores prompt focus after closing (keyboard and mouse); texture-creation errors now propagate the real error.

Context

Documented as ADR-015 in docs/ARCHITECTURE.md.

Test plan

  • Select terminal text, click "Launch agent", pick each of Claude/Codex/Gemini, and confirm the new session spawns in the correct cwd with the composed prompt delivered once the agent starts.
  • With a selection longer than 4 non-blank lines, confirm the preview shows a "+N more lines not shown" indicator.
  • Open the diff overlay (⌘D), write comments, and send them to a running claude/codex/gemini session — confirm delivery (previously broken for all three).
  • Open the agent dropdown in the selection-agent modal, pick an item via keyboard and via mouse, and confirm the prompt field regains focus (blinking caret) in both cases.
  • Select only whitespace and click "Launch agent" — confirm the pill/selection clears instead of doing nothing visible.

Issue: Add a way to select terminal output and hand it to a new AI
agent session as context, generalizing the existing "send diff
comments to agent" pending-delivery mechanism to cover both flows.
A follow-up code review then found a P0 regression the same diff
introduced in the pre-existing diff-comments flow, a delivery-guarantee
regression, an unbounded context preview, missing tests, and a leftover
debug-logging block.

Solution: Selection release shows a "Launch agent" pill; the modal
(selection_agent_overlay.zig) lets the user pick an agent, review the
selection, and write instructions, then queues a LaunchAgentWithContext
action. The runtime spawns the session and defers sending the prompt
until the target agent is confirmed running (drainPendingSessionSends),
falling back to sending anyway at a deadline instead of dropping
silently. The review fixes: match agent names without the PTY newline
(fixes send-to-agent for claude/codex/gemini), show a "+N more lines"
indicator when the context preview truncates, drop leftover diagnostic
logging, restore prompt focus after the agent dropdown closes, and add
test coverage for drainPendingSessionSends and relative --log-dir
resolution.
@forketyfork
forketyfork marked this pull request as ready for review August 15, 2026 12:25
Issue: The selection-agent-context review (P0/P1 already fixed in the
base branch) also flagged five P2 structural issues: two runtime
handlers half-adopting SpawnSessionContext instead of taking it
directly, nine call sites manually pairing selection-menu invalidation
with terminal layout changes instead of one structural choke point,
two new UI actions carrying a raw session slot index instead of the
stable-ID pattern the pending-send mechanism already uses, hand-rolled
modal chrome duplicated between two dialog components, and a "resolve
a Pin to a cell" branch duplicated four times.

Solution: handleExternalSpawnRequest and handleLaunchAgentWithContext
now take a single *const SpawnSessionContext built once per frame.
applyTerminalLayout/applyTerminalLayoutIfSizeChanged now invalidate
selection menus internally, so every call site gets it for free instead
of relying on a paired call. OpenSelectionAgentAction and
LaunchAgentWithContextAction now carry the source session's stable id,
resolved back to a slot via findSessionIndexById() when handled, so a
grid reindex between queuing and handling can't retarget the wrong
terminal. A new ui/components/modal_frame.zig extracts the shared
scrim+panel rendering and Escape/Cmd+W dismiss check used by
confirm_dialog and selection_agent_overlay. session_interaction.zig
gains a single pinToCoords() helper for resolving a Pin to (x, y) in
whichever page is visible, replacing four inline copies of the same
viewport/active branch.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a selection-to-agent workflow integrated through the UI action pipeline and runtime session management.

Changes:

  • Adds a selection pill and agent-launch modal.
  • Generalizes deferred prompt delivery and repairs diff-comment delivery.
  • Adds documentation, tests, logging-path handling, and rendering fixes.

Validation: Not run during this review.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/ui/types.zig Adds selection-agent actions.
src/ui/session_view_state.zig Tracks selection-pill state.
src/ui/mod.zig Exports the new overlay.
src/ui/components/session_interaction.zig Implements pill interaction and positioning.
src/ui/components/selection_agent_overlay.zig Implements the agent-launch modal.
src/ui/components/glyph_badge.zig Supports custom badge colors.
src/ui/components/diff_overlay.zig Repairs agent command delivery and clipping.
src/main.zig Registers overlay tests.
src/logging.zig Resolves relative log directories.
src/c.zig Exposes SDL clip-state API.
src/app/runtime.zig Spawns agents and manages deferred sends.
README.md Documents selection-to-agent behavior.
docs/ARCHITECTURE.md Adds component documentation and ADR-015.
Suppressed comments (2)

src/ui/components/selection_agent_overlay.zig:262

  • This default branch consumes SDL lifecycle events while the modal is open. UiRoot.handleEvent causes the runtime to skip its event switch for every consumed event, so quit/close, resize, focus, and window-destroy events never reach their handlers. Consume the remaining input events explicitly, but return false for unrelated events as the other overlays do.
            else => return true,

src/ui/components/selection_agent_overlay.zig:214

  • SDL_EVENT_TEXT_INPUT is still inserted while the agent dropdown owns focus. Pressing a printable key with the dropdown open first hits the dropdown's key-down branch, then the corresponding text-input event silently modifies the prompt even though prompt_focused is false. Ignore text input until prompt focus is restored.
            c.SDL_EVENT_TEXT_INPUT => {
                _ = self.prompt.insert(self.allocator, std.mem.span(event.text.text), host.now_ms);
                return true;
            },

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/ui/components/selection_agent_overlay.zig Outdated
Comment thread src/ui/components/selection_agent_overlay.zig
Comment thread docs/ARCHITECTURE.md Outdated
Comment thread src/app/runtime.zig
Issue: Automated review on the selection-agent-context PR flagged four
problems: the context preview box was too short to show the new "more
lines" overflow indicator, the prompt field never rendered a highlight
for Cmd+A select-all, ADR-015 described a toast-and-drop deadline
behavior that no longer matches the implementation, and the deadline
delivery test used a fabricated session whose sendInput silently
no-ops, so it couldn't actually catch a regression that dropped the
payload.

Solution: grow context_height to fit five rows instead of four; draw a
selection highlight behind the wrapped prompt lines when select_all is
set, matching the (highlight-only, caret still blinks) pattern already
used in search_utils.zig and diff_overlay.zig; correct the ADR-015
prose to describe the detected-agent-first, send-anyway-at-deadline
behavior; and rewrite the deadline test to back the fabricated session
with a real pipe standing in for the PTY, asserting the exact bytes
written to the other end.
…to refactor/selection-agent-followups

# Conflicts:
#	docs/ARCHITECTURE.md
…lowups

refactor(ui): apply the remaining code-review structural cleanups
@forketyfork
forketyfork merged commit 1398723 into main Aug 15, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants