Skip to content

tui: composer editing depth — up-arrow prompt history, kill-ring, undo #1563

Description

@KvFxKaido

What

Three editor capabilities the composer lost (or never regained) in the silvery migration:

  1. Prompt history recall — Up/Down arrow at the composer cycles through previously submitted prompts. This existed pre-migration (createInputHistory in cli/tui-input.ts) but is now test-only: nothing wires it into the silvery TextArea. For a "repo you run by chatting" product, recalling and editing your last prompt is table stakes.
  2. Kill-ring — Ctrl+K/Ctrl+U/Ctrl+W kills accumulate into a ring, Ctrl+Y yanks, Alt+Y cycles. Silvery's TextArea owns the readline chords today (per the comment in resolveComposerShortcut, cli/silvery/surface.tsx), but kill-without-yank is half a feature.
  3. Undo/redo — coalesced undo in the composer (typing bursts group into one undo step; kills/pastes are their own steps).

Design reference

pi-tui (earendil-works/pi, packages/tui) ships all three as small framework-independent modules: kill-ring.ts, undo-stack.ts, word-navigation.ts. Worth cribbing the semantics (kill accumulation rules — consecutive kills append, any other edit breaks the chain; undo coalescing boundaries) regardless of which layer implements them.

Layering question (decide first)

Each item lands either in silvery (upstream PR/request — it owns TextArea key handling) or in our layer (a controlled-component wrapper that intercepts keys before TextArea). History recall is probably ours regardless (the history store is session state — persisted prompts live in the session store, and seeding across restarts should Just Work via the same path cli/tui-history.ts uses for transcript seeding). Kill-ring and undo want to live wherever the text-mutation primitives live, which today is silvery.

Constraint: whatever the split, don't reintroduce a parallel hand-rolled key parser — cli/tui-input.ts's 500-line input engine is orphaned precisely because silvery owns parsing now. Intercept at the useInput/props layer, not raw stdin (exception precedent: bridgeSilveryCompletionKey for Tab, which is already flagged for deletion when focus scopes land — don't grow that pattern).

Acceptance

  • Up-arrow with an empty composer recalls the previous prompt; Down returns toward the draft; a non-empty draft is preserved when cycling starts. History persists across CLI restarts for the same repo session.
  • Ctrl+K/U/W kills feed a ring; Ctrl+Y yanks the head; consecutive kills accumulate.
  • Undo restores coherent steps, not per-keystroke churn.
  • Covered in the FakeStdin/FakeStdout harness (cli/tests/silvery-tui-p0.test.mjs pattern) — assert on emitted composer content, not helpers.

Related: #1530 (adoption track), #1562 (IME — both touch composer input routing; sequence so they don't conflict).

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions