What
Three editor capabilities the composer lost (or never regained) in the silvery migration:
- 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.
- 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.
- 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).
What
Three editor capabilities the composer lost (or never regained) in the silvery migration:
createInputHistoryincli/tui-input.ts) but is now test-only: nothing wires it into the silveryTextArea. For a "repo you run by chatting" product, recalling and editing your last prompt is table stakes.TextAreaowns the readline chords today (per the comment inresolveComposerShortcut,cli/silvery/surface.tsx), but kill-without-yank is half a feature.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
TextAreakey handling) or in our layer (a controlled-component wrapper that intercepts keys beforeTextArea). 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 pathcli/tui-history.tsuses 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 theuseInput/props layer, not raw stdin (exception precedent:bridgeSilveryCompletionKeyfor Tab, which is already flagged for deletion when focus scopes land — don't grow that pattern).Acceptance
cli/tests/silvery-tui-p0.test.mjspattern) — assert on emitted composer content, not helpers.Related: #1530 (adoption track), #1562 (IME — both touch composer input routing; sequence so they don't conflict).