- workspace: tty7-cli joins default-members, so a bare root cargo test runs it
- run --keep files the pane into its workspace via TabCreate (and refuses to
keep a pane no workspace would list); --ws help says what it really does
- server start|stop|restart|logs refuse -m instead of silently acting locally
- server start kills the spawned process when it never opens its endpoints
- -m over a down link is refused instead of redialing with auto auth
- capture help tells the truth: raw ANSI bytes, last ring segment by default
- a missed exit-code probe exits 1 with a stderr note, not a fabricated code
- TTY7_SOCKET is honored: control dials it, the pane endpoint is its sibling
- attach's success JSON says attached, not detached_from
- e2e daemons ride a KILL_ON_JOB_CLOSE Job Object on Windows, so a hard-killed
harness cannot leak servers
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JPaaZVK7rfQPKyrymzsYv
StubBackend is gone; RealBackend lazily opens a ControlClient for control
ops and a PaneClient for pane ops. Backend::spawn_shell now returns the
daemon-assigned pane id, so every creating verb (new, tab new, split)
spawns first and seeds the tree op with the real id — client-side pane-id
allocation is deleted. Live end to end: ls, ws/tab/pane verbs, new, send
(attach-input-detach), capture (observer replay; --scrollback = whole
ring, default = the ring's last segment), procs, run (streams output,
passes the child's exit code through, --keep leaves the pane), events
(human lines or NDJSON), agents, status, machine ls, and doctor's server
half (reachability, dialect, status, links). tty7 server start|stop|
restart|logs manage a sibling/PATH/TTY7_SERVER_EXE tty7-server. -m routes
both channels over the local server's link, resolved against Routes by
key or bare host; jump/proxy-chained keys are refused with the reason.
Interactive attach stays stubbed for the next slice. A harness-free e2e
suite drives the compiled tty7.exe against an isolated real server.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JPaaZVK7rfQPKyrymzsYv
The thin console CLI from docs/cli-design.md, transport-free for now:
- clap grammar for the full documented surface: ws/tab/pane/machine/server
nouns, the hot-path top-level verbs (ls/attach/run/new/split/send/capture/
procs/agents/events/status/doctor), global -m/--json/-q, `run -- <cmd...>`,
and bare `tty7 [path]` parsing as the GUI launcher stub.
- tmux-style addressing (%42 pane, @7 machine-wide tab ordinal or @<uuid>,
workspace by name / id / unique id prefix) with implicit-context fallback
to TTY7_PANE / TTY7_WS and a "not inside a tty7 shell" error naming the fix.
- Backend trait as the integration seam: control() speaks real
tty7_core::daemon::control ControlRequest/ReplyOk values, plus declared
pane-side entry points (spawn_shell/send_input/capture/procs/attach_pane/
run/events). StubBackend fails loudly until the transport client lands;
MockBackend asserts the exact request shapes every structural verb builds.
- Plain aligned tables and trees for ls/tree/pane ls, one JSON object per
command under --json. Exit codes: 0 ok, 1 failed, 2 usage (clap default).
agents/status/machine ls stay stubbed: they need ControlRequest::AgentStates/
Status/Routes, which another slice is adding; ws stop and server start/stop
likewise wait on their mechanisms rather than inventing protocol.
Build/test this package alone (cargo build -p tty7-cli): its bin is named
tty7 and collides with the GUI bin until that one is renamed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014JPaaZVK7rfQPKyrymzsYv