Kotoba

Where to start

What Kotoba isWho she is and where she runs, in one page
InstallingOne package, two commands
First runA key, a model, her first words
The approval gateHow she asks before she acts
The two voice modesLocal voice, or the agent tunnel
The soul fileChange who she is
RoadmapWhat grows next, and what was cut on purpose

Or a section

↑↓ move openesc close124 pages
All pages

The web app7 of 12

The Terminal panel

About 3 minutes to read

On this page

The Terminal panel is a read-only record of what she did. It is not a shell.

Screenshot placeholder: the Terminal panel in the left rail — three step cards, each with a coloured type chip (BASH, PYTHON, MCP), a monospace command line, a status disc on the right, and one card expanded to show a dark console block with a "Hide full output" pill under it.

There is nothing to type into

The panel renders a list of step cards and nothing else. It has no input, no prompt and no command box (components/panels/TerminalPanel.tsx:115-149). You cannot run a command from the browser.

Everything on it is something she ran, and everything she runs goes through the approval gate before it runs. That gate is the approval card described in The approval card, not this panel.

The panel opens itself when a work run starts (CompanionExperience.tsx:244), and the terminal button in the dock pulses while she is working with the panel shut.

What a card shows

Each card is one tool call (TerminalPanel.tsx:70-113):

  • A type chip. Eight kinds, each with its own colour and icon (TerminalPanel.tsx:19-29): bash, python, web, file, mcp, skill, memory, tool.
  • The action, in monospace, on one line, with the full text as a tooltip.
  • A status mark, or a spinner while it is still running.
  • A console block with the output, on a dark ground tinted by the outcome.
  • Show full output, when there is more than the card is showing.

The seven endings

A tick is the narrowest claim on the panel: the command ran and the process reported success. Every other way a row can end has its own mark (TerminalPanel.tsx:31-38):

MarkMeaningTooltip
spinnerstill running
greenran and finished cleanlyran and finished cleanly
× redran and failedran and failed
greynever ran — the reason is belownever ran — the reason is below
greystopped while it was runningstopped while it was running
yellowwaiting for your approval — it hasn't runwaiting for your approval — it hasn't run
? greyit ended, but nothing said howit ended, but nothing said how

A refusal and an interruption are deliberately grey. Neither is a fault, and painting your own "No" red would report your decision as a malfunction (TerminalPanel.tsx:1-10).

The ending is told, never inferred (lib/store.ts:60-71). A non-zero exit, a command killed at its timeout and an action you refused all return non-empty text, so reading "did it return anything" once gave all three a green tick. An outcome this build has never heard of is unknown, and never ok — a mark nobody chose must look like one.

That rule is pinned by a test that drives the real store through all of it, including the case where a deferred command is completed minutes later from outside the turn (tests/terminal-status.test.mjs).

Show full output

The card's summary line is the backend's own, unwidened. When the tool returned more than that, a Show full output pill appears and opens the rest in the same console block (TerminalPanel.tsx:63-68, 100-110).

This exists because a 23-line directory listing reached the card as one line of 18 characters, and nothing on screen could tell a right answer from a confident wrong one (tests/terminal-full-output.test.mjs:1-9). The control appears only when there is genuinely more to show — the comparison is made after the same tidying the summary gets, so exit=0 framing alone does not count as "more".

Tool output reaches the DOM as a text child and never as markup. There is no dangerouslySetInnerHTML anywhere in the panel, and a test asserts it (tests/terminal-full-output.test.mjs:56-57).

What the panel keeps

The last 200 rows (lib/store.ts:226). Older rows are dropped.

Everything is cleared when the call ends (lib/store.ts:293-296). The panel is a live record of the current call, not an archive. If you need what a command produced after the fact, the artefact it wrote is in Files.