Skip to content

feat: add prompt composer to terminal context menu#133

Closed
mpmisha wants to merge 3 commits into
InbarR:mainfrom
mpmisha:users/mimer/feature/prompt-composer
Closed

feat: add prompt composer to terminal context menu#133
mpmisha wants to merge 3 commits into
InbarR:mainfrom
mpmisha:users/mimer/feature/prompt-composer

Conversation

@mpmisha

@mpmisha mpmisha commented Jun 14, 2026

Copy link
Copy Markdown
Contributor

What

Adds a notepad-style Prompt Composer to each terminal pane, accessible from the pane right-click context menu (📝 Prompt composer). Closes TASK-180.

image image

Why

Composing long, multi-line prompts directly in the terminal is awkward — newlines and paste are fiddly, and a stray Enter submits a half-written message. The composer is a plain modal <textarea> so users can write and edit freely, then copy or paste the whole thing into the terminal as a single block.

How it works

Three buttons in the footer:

  • 📋 Copy — write the draft to the clipboard, with transient "✓ Copied" feedback.
  • ➤ Submit — bracketed-paste the draft into the focused terminal via writePty. We do not also send Enter — the user reviews in the terminal and presses Enter themselves. Intentional:
    • avoids accidental submission of half-thought-out prompts
    • Ink-based AI CLIs (Copilot CLI, Claude Code) handle a programmatic \r after bracketed paste inconsistently
  • Close — dismiss (also bound to Esc and backdrop click).

Drafts persist per-terminal for the current session, so closing and reopening the dialog doesn't lose work. Drafts are dropped when the owning pane is closed, and the composer auto-dismisses if its target pane goes away.

Submit reuses the existing prepareClipboardPaste helper for bracketed-paste wrapping + CRLF→LF normalization (so Windows-CRLF drafts work cleanly).

Files

Added

  • src/renderer/components/PromptComposer.tsx — the modal
  • src/renderer/utils/prompt-composer.ts — pure draft-map helpers (DRY + testable)
  • tests/e2e/task-180-prompt-composer.spec.ts — 14 pure-function tests
  • backlog/tasks/task-180 - …md — Backlog task

Modified

  • src/renderer/state/terminal-store.ts — new state (promptComposerRequest, composerDrafts), open/close/setDraft actions, closeTerminal cleanup
  • src/renderer/components/TerminalPanel.tsx — context menu item between "Show prompts" and "Session summary"
  • src/renderer/App.tsx — mounts <PromptComposer />
  • src/renderer/styles/global.css.prompt-composer-* styles, matches the SessionSummary card family

Out of scope

  • Persisting drafts across app restarts (session-only by design).
  • Keyboard shortcut to open the composer (opens via context menu only for now).
  • Auto-pressing Enter after Submit (tried it, behaved inconsistently with AI CLIs; deferred).

Validation

  • npx tsc --noEmit: no new errors introduced (same 32 pre-existing errors on this branch vs. main; remaining errors are all in unrelated code paths).
  • npx vite build --config vite.renderer.config.ts: succeeds.
  • npx playwright test tests/e2e/task-180-prompt-composer.spec.ts: 14/14 pass.
  • Existing related specs (paste-wrap, smart-unwrap-on-copy) still pass.
  • Manually smoke-tested in npm start: right-click pane → composer opens → Copy & Submit both work → Esc/backdrop close → draft persists across reopen → draft cleared on pane close.
assistance: agentic-cli
type: feature
agent-tool: copilot-cli
agent-model: claude-opus-4.7
work-item: TASK-180

mpmisha and others added 2 commits June 14, 2026 10:21
Adds a notepad-style scratchpad to each terminal pane, accessible from the
pane right-click menu (📝 Prompt composer). Lets users compose long,
multi-line prompts in a real text editor before sending them - avoids the
fiddliness of editing multi-line input directly in the terminal and stops
stray Enter keys from submitting half-written messages.

The modal has three footer buttons:
- Copy:   writes the draft to the clipboard.
- Submit: bracketed-pastes the draft into the focused terminal. We do not
          also send Enter - the user reviews in the terminal and presses
          Enter themselves. Intentional: avoids accidental submission and
          Ink-based AI CLIs handle programmatic \r post-paste inconsistently.
- Close:  dismiss (also bound to Esc and backdrop click).

Drafts are per-terminal and persist for the session; they're dropped when
the owning pane closes (and the composer auto-dismisses if its target pane
goes away).

Reuses the existing prepareClipboardPaste helper for bracketed-paste
wrapping + CRLF→LF normalization (so Windows-CRLF drafts work cleanly).

Pure draft-map helpers (updateComposerDrafts, dropComposerDraft) extracted
to src/renderer/utils/prompt-composer.ts and covered by 14 focused tests in
tests/e2e/task-180-prompt-composer.spec.ts. All tests pass; tsc error count
unchanged vs main; renderer vite build succeeds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…atcher

- Bind Ctrl+Alt+P (⌘⌥P on Mac) to open the prompt composer for the
  focused pane. Ctrl+Shift+P was already taken by the command palette.
- Surface the shortcut in the pane context menu hint, the Command
  Palette ('Open Prompt Composer'), and the Shortcuts Help overlay.
- Fix matchesCombo() to also compare against event.code on Mac for
  letter/digit keys. Without this, Option+P reports event.key='π'
  (Option+R → '®', etc.) and every Cmd+Option+<letter> shortcut
  silently no-ops on Mac. Side benefit: the pre-existing Ctrl+Alt+R
  (refresh pane) and Ctrl+Alt+N (new terminal in place) bindings now
  also work on Mac.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@mpmisha

mpmisha commented Jun 14, 2026

Copy link
Copy Markdown
Contributor Author

Added a keyboard shortcut on a follow-up commit (ae5d366):

  • Ctrl+Alt+P (⌘⌥P on Mac) opens the prompt composer for the focused pane.
  • Surfaced in the pane context menu hint, Command Palette, and Shortcuts Help.
  • Also fixes matchesCombo() to compare against event.code on Mac for letter/digit keys — without this, Option+P reports event.key='π' and every Cmd+Option+<letter> shortcut silently no-ops. Side benefit: the existing Ctrl+Alt+R and Ctrl+Alt+N bindings now also work on Mac.

The prompt composer is mainly useful for drafting chat prompts for AI
CLIs; on a plain shell pane it would be a surprising surface. Hide it
in all three entry points when the focused/target pane has no
aiSessionId:

- Pane context menu item: wrapped in {aiSessionId && (...)}, same as
  'Show prompts' and 'Session summary'.
- Ctrl+Alt+P shortcut: no-ops when the focused pane isn't AI.
- Command Palette 'Open Prompt Composer' entry: conditionally included
  based on the focused pane's aiSessionId; useMemo dep added so the
  list rebuilds on focus changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@InbarR

InbarR commented Jun 14, 2026

Copy link
Copy Markdown
Owner

Thanks @mpmisha - great idea and cleanly implemented. Merged! 🎉

I built on it a bit with a few enhancements, and it'll ship in the next release. Thanks again! 🙌

@InbarR InbarR closed this Jun 14, 2026
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