docs(plans): termic CLI design#125
Conversation
60126a0 to
346726a
Compare
|
Requesting review of the spec, with particular attention to the error-path interactions. These were the judgment calls in the design, and each one is a deliberate choice that could reasonably go the other way:
Full detail in docs/plans/cli.md under "Command surface" and "Security". Pushback welcome on any of these defaults. |
|
@simion Let me know what you think. The shape follows what's worked elsewhere: the thin-CLI-into-running-app pattern is VS Code's code / Docker Desktop (and Sculptor ships exactly this for agent orchestration; Claude Code itself just grew --bg/attach verbs the same way). Protocol details lean on tmux (attach/detach, version handshake), mpv's JSON IPC (framing), and Bitcoin Core's .cookie for the local auth. Sandbox interaction is a part to pay attention to since it is a main Termic feature, plus the error-path defaults in the comment above. |
|
I see this somewhat related to our SSH issue. This could be the stepping stone to allow local agents or local CLI to control remote resources as well. |
|
Good design doc — the architecture decision (pattern 1) is correctly forced by where state actually lives, and the sandbox boundary section is the strongest part. A few things worth clarifying before implementation: 1. 2. Exit code for scope/auth failure 3. Remote/SSH scope (re: your Comment 3) 4. Production webview RPC channel Architecture and phasing are solid. The error-path defaults in your comment are all the right calls. |
|
One more angle worth covering, related to issue #59: Agent discoverability and LLM-friendly help The CLI is only useful to an agent if the agent knows it exists. Two things needed:
This is the path to the workflow in #59 without needing MCP: the agent sees |
8b35d85 to
374824a
Compare
|
Thanks — all four are now in the doc: 1. 2. Added a dedicated exit code for "refused": you reached the socket but your token was missing, wrong, or not allowed to do that. Scripts can tell it apart from a generic failure. Exact numbers get assigned in Phase 0. 3. Agreed — remote is out of scope for this design. The auth model is deliberately local-only (unix socket, peer check, 0600 token file), and nothing in the plan designs for the wire. The SSH angle was me speculating about a future the CLI unlocks, not the method we're committing to — but it's worth spelling out because it's why local-only auth isn't a dead end: the CLI is just a local binary, so machine 1 could drive machine 2 by SSH-ing over and running that machine's CLI ( 4. Clarified in the doc: the production channel is new code that copies the idea from the automation bridge (matching requests to webview replies). The debug bridge itself stays debug-only and is never used. |
|
Added a section on agent discoverability ("Agents as users"): This is the no-MCP path to #59's workflow: the agent sees |
|
The command surface is missing a few verbs that would make the CLI genuinely useful as a scripting primitive, and some of the existing names don't map well to what termic actually does. Rename suggestions:
Missing verbs:
Attach ambiguity: Rare operations as namespaced subcommands: The trio |
|
Most of this is in — thank you, the scripting-trio framing is exactly right: Adopted:
Declined, with reasons:
|
|
Agreed. @MHohlios shall we merge this? or give it to an agent directly and implement it here :D |
|
Lets merge it. I will commit the various phases as we go. It should not hurt mainline code. |
|
Secondary review before merge (this is why it's still open). Four findings, verified against the current codebase; none invalidate the architecture, but 1 and 2 affect things Phase 0 pins, so they should land in the doc first. 1. The seatbelt deny ordering is backwards, and the planned test wouldn't catch it The doc says the socket deny "must land ahead of that allow in all non-Off modes". SBPL is last-match-wins: when multiple rules match, the rule appearing later in the profile takes precedence (that's why The test plan compounds this: it asserts "the rendered profile contains the socket deny in every non-Off mode", a textual presence check that passes while the deny is ineffective. Since the doc itself calls this deny "load-bearing, NOT belt-and-braces", the test must be behavioral: from inside a caged spawn, attempt an actual connect to the socket path and assert it fails. Also note EnforceFs takes an early return (sandbox.rs:1182) with a blanket 2. Exit code 2 collides with clap The contract reserves exit 2 for "agent stopped needing input", and the CLI is clap-based (completions are "clap-generated"). Clap's default exit code for usage/parse errors is 2. A script branching on 3. The doc's own composition example is racy The pitch is 4. Sandbox monotonicity by mode is too coarse (future-phase, but record it now) The scoped-token rule says Smaller notes, take or leave:
Everything else probed held up: the code citations are accurate (sandbox.rs:1188, TERMIC_SANDBOX at 1648, runPrompt queueing, Fixes for 1 and 2 are one-liners in the doc, 3 needs a decided semantic, 4 needs a recorded caveat in the scoped-tokens paragraph. Happy to merge once those are in. Signed: secondary review by Fable (Claude), on maintainer request. |
|
Both feedback rounds are now in the doc. Plain-language summary: Earlier round:
Fresh review, all ten adopted:
Two things we found while verifying:
|
|
If you are comfortable lets merge this plan in and I will use my tokens for the first Phase and see how it goes. |
|
@MHohlios agreed and merged. Thank you 🙏 |
Design doc for a
termicCLI: drive Termic from any shell. Comments on the doc are the point of this PR.What it does
termic new fix-auth -p "fix the login redirect"from inside any registered repo: worktree + branch + agent, prompt delivered, no GUI touchedtermic list: tasks with live agent state (working / waiting / done) and diff statstermic send: prompt a task's running agent (queues if it is mid-turn);termic status: one task in depth for pollingtermic wait: block until the agent settles, sosend foo -p ".." && wait foo && diff foocomposes;send/wait/status --jsonis the scripting triotermic apply: the GUI's "send diff to main", closing the worktree lifecycle;termic project add|list|removefor non-interactive admin--wait: block until the agent settles, exit codes scripts can branch on (done vs stopped-needing-input)termic attach: the agent's terminal live in your shell, detach like tmuxtermic open,path,diff,archive: raise the GUI on a task,cd $(termic path foo), diff summary, archive--output-format text|json|stream-jsoneverywhere; stable exit-code contract, stdin prompts (-p -), shell completionsDesign
Related: #59 (built-in MCP server). This control plane is the proposed foundation for it: the planned
termic mcpsubcommand is a stdio-to-socket shim exposing the same verbs, auth, and sandbox policy to any MCP client, which covers the #59 workflow (agent provisions a task, Termic applies sandbox boundaries, control returns to the agent).