agent: TermInput — composer + slash commands
Ported from app.js's `renderTermInput`/`handleSlashCommand`/
`completeSlash`: prompt + auto-growing textarea, Enter sends (Shift+Enter
newline), Tab cycles slash-command completion. Same command set
(/help, /clear, /cancel, /compact, /model, /effort, /new-session,
/logout), same routes (`api/cancel`, `api/compact`, `api/new-session`,
`api/logout`, `send`) via new `lib/termActions.ts` (same `{ok, detail}`
shape as modelEffort.ts's POST helper).
One deliberate UX change: `/new-session` and `/logout` used to pop the
old shadow-DOM `themedConfirm` modal before firing — this rewrite's
destructive actions all avoid that widget family already (SidePanel,
useConfirmClick), and a modal doesn't fit a text-input flow anyway.
Typing the command once arms it (a local note explains what confirming
does); typing it again fires it — a keyboard-native two-step confirm.
`/help`/`/clear` need to reach into LiveStream's row list (local-only
echo rows, never sent anywhere) without lifting that state up to Root —
`useLiveStream` gained `pushLocalNote`/`clearLocal`, exposed off
`LiveStream` via `forwardRef`+`useImperativeHandle` (preact/compat),
same shape as app.js's old `termAPI` object but scoped as a ref handle
instead of a module-level variable.
Screenshot-verified end to end: typed "/help" + Enter into a real
mounted composer, confirmed the textarea clears and the local note rows
(command list) append to the live pane.
This commit is contained in:
parent
190d810762
commit
d9249a36bf
5 changed files with 249 additions and 9 deletions
|
|
@ -35,6 +35,13 @@ export interface UseLiveStreamResult {
|
|||
hasMore: boolean;
|
||||
loadingMore: boolean;
|
||||
loadMore: () => void;
|
||||
/** Append a local-only note row (TermInput's `/help` output, error
|
||||
* feedback on a failed slash-command POST) — never sent anywhere,
|
||||
* purely a client-side echo. */
|
||||
pushLocalNote: (text: string) => void;
|
||||
/** Wipe the local view only (server-side history is untouched) —
|
||||
* TermInput's `/clear`. */
|
||||
clearLocal: () => void;
|
||||
}
|
||||
|
||||
function appendRow(rows: StreamRow[], row: StreamRow): StreamRow[] {
|
||||
|
|
@ -179,5 +186,14 @@ export function useLiveStream(opts: UseLiveStreamOptions = {}): UseLiveStreamRes
|
|||
}
|
||||
}
|
||||
|
||||
return { rows, hasMore, loadingMore, loadMore };
|
||||
const localKeyRef = useRef(0);
|
||||
function pushLocalNote(text: string) {
|
||||
localKeyRef.current += 1;
|
||||
setRows((prev) => appendRow(prev, { key: `local-${localKeyRef.current}`, cssClass: 'note', fromHistory: false, text }));
|
||||
}
|
||||
function clearLocal() {
|
||||
setRows([]);
|
||||
}
|
||||
|
||||
return { rows, hasMore, loadingMore, loadMore, pushLocalNote, clearLocal };
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue