docs: update Run feature docs for the tmux+PTY terminal (was stream-json)

- README.md: replace stream-json bullet with tmux+PTY description
- ARCHITECTURE.md: update /run Workspace page section to reflect PTY transport, xterm.js, and ccam lanes shell
- docs/API.md: replace stream-json endpoint docs with /api/run/*+/ws-pty/:runId PTY endpoint docs
- docs/LANES.md: add "Attaching a real terminal to a lane" section for ccam lanes shell; update lane "start" action docs and /run Workspace description
- Remove stale references: run_stream, run_input_ack, conversation/headless modes, RunConsole components
This commit is contained in:
2026-08-12 15:35:57 +07:00
parent 6709f9a192
commit 31af7aefbf
4 changed files with 31 additions and 44 deletions
+10 -17
View File
@@ -309,7 +309,7 @@ The dashboard web UI merges lanes and runs into a single **Workspace** page acce
- **Header** — the page title and four counters (`lanes`, `running`, `needs you`, `dead`), plus Add lane. The `needs you` and `dead` counters appear only when they are non-zero, so a quiet header means nothing is waiting on a human.
- **Detail panel** — the selected lane's declared stage, its inferred stage when detection leads, a full-width pipeline map, and a legend naming all five node states plus the dashed-amber inferred treatment.
- **Console** — `RunSetup`, `RunConsole` and `RunHistory` behind a disclosure that **starts collapsed**. Watching lanes is the default posture; driving one is the exception. Collapsing hides the console with CSS and never unmounts it, so a live run keeps its rendered history and scroll position.
- **Terminal** — a real interactive terminal (xterm.js) displaying the tmux session's PTY output, with full support for interactive commands, editors, and pagers. A live run keeps its rendered history and scroll position when scrolling.
- **Lane grid** — one card per lane, 1 column, 2 at `md`, 3 at `xl`. Each card carries the lane id, liveness dot and status, title, declared stage with a progress bar and time-on-stage, the `auto:` chip when detection leads, the kind and CI tags, the working-copy facts from `GET /api/lanes/:id/git`, the needs-you banner, and the action row.
Run history is per lane, queryable via `GET /api/run/history?laneId=<n>`.
@@ -433,6 +433,10 @@ or from the dashboard: the pipeline-template select next to the lane's title in
Switching re-resolves the lane's existing declared `stage` against the new node list. A stage the old template knew may resolve to nothing in the new one; the switch warns when that happens (both CLI and UI), and the next `ccam stage` fixes it.
## Attaching a real terminal to a lane
`ccam lanes shell` attaches a real terminal to the exact tmux session the dashboard's Start/Resume buttons use for this lane (`ccam-lane-<id>`), creating it if it doesn't exist yet. Type `claude` inside it like any normal terminal session — the dashboard's Workspace terminal view is just another client attached to the same tmux session, so both stay in sync live.
**In practice you never have to pick correctly at creation.** The template only has to match whichever skill is actually driving the lane, and the skill enforces that itself: `ship-feature-lane` runs `ccam lanes pipeline ship-feature` and `ship-feature` runs `ccam lanes pipeline default` before their first `ccam stage` call — a no-op if the lane is already on that template, a self-correction if it isn't. A human chatting with the lane never needs to open the picker; whichever skill gets invoked decides the template.
The dashboard renders every node in the pipeline in one of five **states**:
@@ -931,28 +935,17 @@ The web UI and CLI provide these actions on a lane:
### start
Launch a new Claude Code session bound to the lane. If the lane has a recorded `session_id` from a previous run, you can resume it instead with `--resume`.
Start a tmux-backed run attached to the lane. The Workspace page's "Start Run" button calls `POST /api/run` with the lane's id; you can also attach from a real terminal using `ccam lanes shell`.
```bash
curl -X POST http://localhost:4820/api/lanes/5/start \
curl -X POST http://localhost:4820/api/run \
-H "Content-Type: application/json" \
-d '{"prompt": "continue the work", "resume": true}'
-d '{"laneId": 5, "prompt": "continue the work"}'
```
`mode` accepts the same two values as `POST /api/run` — `"conversation"` (the
default: multi-turn, `message` keeps working) or `"headless"` (one shot, the
prompt goes in argv and the process exits when the turn finishes). Unlike
`POST /api/run`, an unknown value is refused with `400 EBADMODE` rather than
silently treated as a conversation.
The `prompt` field is optional — if omitted, the tmux session is created/attached with no initial input, and you type into the terminal directly. Returns `{ runId, tmuxSessionName, cwd, ... }`. The same tmux session persists across attach/detach cycles, so you can switch between the browser Workspace and `ccam lanes shell` seamlessly.
**A finished run releases its lane.** When the child truly exits — normally,
non-zero, killed, or never spawned at all — the lane's `run_id` is cleared, its
status returns to `idle`, and the change is broadcast as `lane_update`. So a
lane never sits at `running` behind a dead run, and `message` reports
`409 ENORUN` instead of targeting one. Runs started this way are recorded with
the lane's id and are listable via `GET /api/run/history?laneId=<n>`.
Currently the `prompt` field does not populate the input field in the UI (see "Known limitations" below).
**A killed run releases the lane.** When the tmux session is terminated (from the terminal, browser stop button, or external `kill`), the lane's `run_id` is cleared, its status returns to `idle`, and the change is broadcast as `lane_update`. Runs are recorded with the lane's id and are listable via `GET /api/run/history?laneId=<n>`.
### message