Console editing without new crates#
The optional i --runtime console frontend (also used by scripts/start.sh) now owns terminal input and redraws the editable row after background output. Approval policy and mode control are optional plugins. The old 1,024-line core constraint is historical; see docs/wasm.md. No third-party crate, Unicode table package, stty subprocess, or runtime Python dependency was added. The existing ctrlc dependency also handles termination signals for orderly cleanup.
Input#
See composer.md for pending clipboard images (Ctrl-V) and folded long/multiline text. Images wait for Enter and allow an optional caption.
- UTF-8 scalar boundaries for insert, Backspace, Delete, Left and Right.
- Home/End or Ctrl-A/Ctrl-E; Ctrl-U clears the draft; Ctrl-K deletes its suffix.
- Up/Down recalls up to 50 submissions and restores an unsubmitted draft.
Approval responses and /mode control commands are excluded from history; history is memory-only.
- Enter submits. A terminal supporting bracketed paste inserts pasted newlines
without submitting them. Newlines/tabs appear as \n/\t in the editable row, but the actual task retains them. Other pasted control characters are removed.
- In the main console, a leading
/opens the supported-command menu with descriptions. Prefix typing filters; Up/Down selects; Tab or Enter only fills a candidate. Press Enter again with the menu closed to execute, or Escape to dismiss it./modecompletesask,auto,status. Pending approval commands appear only when there is a pending request. Slash characters inside prose do not open the menu. /helpand the menu use the same platform-filteredweb/commands.jsoncatalog as the browser. Unknown commands, multiline slash commands and invalid arguments on argumentless commands never become model tasks or steering instructions. The old rawireadline fallback retains Tab prefix completion, not the full popup; its help no longer advertises placeholder setup/language/session operations or a fake resume action.- Ctrl-D on an empty draft closes input (the current task can finish); with a
nonempty draft it deletes at the cursor. Ctrl-C aborts the current task/console.
- The interactive draft is limited to 64 KiB. Oversized pastes are rejected as a
whole, not truncated or executed as separate commands. OS process-argument limits can impose a smaller submission limit, particularly on Windows.
The input viewport is one row and scrolls horizontally. Chinese/full-width characters occupy two cells; ASCII and the supported Latin range occupy one. Unsupported glyphs, including emoji, combining marks and format controls, are shown as ASCII Unicode escapes only in the editable row; their underlying text is retained for submission. Deletion is by Unicode scalar, not grapheme. This is deliberately not a complete Unicode width/grapheme implementation; ambiguous-width terminal settings and unusual fonts can still differ. Completed output lines can display those glyphs normally because the terminal lays them out.
Approval modes#
Use /mode ask (default), /mode auto, or /mode to inspect the current mode. Console --yolo (alias --dangerously-skip-permissions; old --yes removed) selects initial auto but can be revoked with /mode ask. Auto is not a sandbox or a policy bypass: a custom approval worker can still ask or deny. A pending question still needs an explicit answer after a mode switch. Mode changes apply to subsequent requests, not already-started actions. See replaceable approval contract.
Output, fallback and cleanup#
Interactive editing requires stdin, stdout and stderr to be terminals and TERM not to be dumb. Interactive stdout/stderr are displayed together through stderr; redirected/piped operation keeps separate streams and line-based stdin. The optional Markdown renderer can transform stdout even without a TTY; set NO_COLOR=1 or TERM=dumb to disable Markdown rendering. The standalone core's Task: prompt is still system line input, not this optional editor.
Reader threads use bounded queues. One console loop owns drawing and preserves the draft across backend messages. UTF-8 is decoded incrementally per stream; backend terminal control characters are escaped rather than executed. Partial output is visible as a clipped prefix until a newline/EOF commits it. Very long unterminated output is broken into bounded lines. Authenticated stderr approval markers are still handled separately; visual text alone cannot grant approval.
macOS/Linux use the system termios/ioctl APIs; Windows uses console modes and virtual-terminal input/output (a VT-capable Windows console is required). Saved modes are restored on normal exits, errors and handled interruption/termination. SIGKILL, process crashes and panic=abort cannot run cleanup; use the terminal's reset action if an abnormal exit leaves raw mode active. Job-control suspension, full grapheme editing and every terminal's resize/reflow behavior are not promised.
Local validation uses macOS arm64 pseudo-terminals with committed UTF-8 input, not an automated OS IME candidate-window test. Linux/Windows execution is not claimed from that result; Linux/macOS PTY checks and Windows builds/tests are configured in CI. No paid model requests are needed:
cargo build --workspace --features bundled --locked
python3 scripts/check_console.pyThe PTY check covers Chinese deletion/cursor positions, insertion, history, paste without accidental submission, concurrent split UTF-8 output, inert backend escape sequences, authenticated approval, live mode switching, not bypassing a pending approval, resize, and terminal-mode restoration on exit, Ctrl-C, SIGTERM and backend startup failure.