跳转至

cli-surface

The spex command surface — porcelain-only top level grouped by loop, machine plumbing under internal, and a three-layer help journey (help → per-command help → guide).

raw source

The spex top level is exactly the vocabulary a human or agent is meant to type — nothing more. A verb only programs call (a generated hook, a launch script) does not sit beside the verbs people learn; it lives under spex internal, out of sight. And no help probe may dead-end: from the map to one command's usage to the guide, every layer names the next.

expanded spec

Porcelain-only top level. spex help's map lists every typeable command, grouped by the loop it serves — find & read the graph, author & verify (the worker loop), dispatch & manage sessions (the manager loop), install & serve (the operator loop) — so a newcomer learns not just what exists but when each verb matters. Machine plumbing (internal trunk for the main-guard hook, internal codex-launch / internal codex-turn for the harness-adapter launch script) is namespaced under spex internal, absent from the map; its own usage text tells a stray human which porcelain they probably wanted. Consequence of the move: a stale installed pre-commit hook that still calls the old top-level token degrades to the hook's pure-git trunk fallback (advisory-safe), and is healed by npm run hooks; the deprecated spex propose alias is gone the same way — a stale post-merge hook prints one unknown-command line (advisory) until reinstalled. A demoted spelling degrades more gently than a removed one: it stays as a deprecated alias that still runs but echoes the canonical form on stderr, so a caller migrates without breakage (spex review proofspex eval <SEL> --export, after proof was demoted from a review sub-noun to the export flag of the review-proof eval read).

One verb, either drawer — the session-verb mirror. A user must never have to guess whether a session verb lives at the top level or under spex session: every promoted session verb (new · ls · watch · wait · review · merge) also answers in its namespace form (spex session reviewspex review), and every typeable session sub (reopen · done · park · ask · exit · close · send · capture · attach · rename · rawkey · prompt) also answers bare (spex sendspex session send). The mirror is an alias, never a second copy of the logic: one argv rewrite before the single dispatch normalizes either spelling to the canonical one, so --help probes, flags, and positionals all flow through the same handler (a mirrored sub's probe answers with the session entry). Hook-driven subs (state · fail · idle · commit-gate) stay namespace-only — nobody types them. The map stays porcelain: mirrored spellings add no map lines; the session entry lists the whole drawer, promoted verbs included, and states the equivalence both ways.

The three-layer help journey — each layer states what the next one is for, so the reader always has a move:

  1. spex help — the map. Also names the second layer (spex help <command>) and the guide topics.
  2. spex help <command> / spex <command> --help — ONE command's usage: syntax, flags, semantics, a see also: pointing at its sibling verbs and guide topic, and a constant footer back to the map and the guide. The --help interception still fires BEFORE any verb runs (guide's safety contract: probing watch or session new with --help must never start the verb) — what changed is that the probe now answers with that command's usage, not the whole map. Sub-namespace probes (spex session send --help) resolve to their namespace's entry; resolve/retract resolve to the remark entry they belong to.
  3. spex guide [topic] — the skill layer (guide): workflows, file formats, settings. Guide pages footer back to spex help; the split is one sentence — help answers "what do I type", guide answers "how do I work".

Dead-end rule: an unknown command, an unknown help topic, an unknown guide topic, and a bare spex internal each fail loud AND name the layer to go back to — never a silent exit.

A machine dump names its human twin: spex board's JSON is for programs, so when stdout is a tty a single stderr line — (human-readable tree: spex tree) — points the human at the readable graph. The hint is stderr-only and tty-gated, so piped or redirected spex board output stays byte-identical (the pipe contract is untouched).

The map must stay honest: every porcelain verb cli.ts dispatches appears in it (a hidden typeable verb is the bug this node exists to prevent — search and owner were exactly that), and each verb with caveats carries them in its own entry (watch says it never exits and points at wait). Cross-cutting input grammar is advertised in the entries where a user would first need it: the mention hint (@session · **node**, mentions) rides the session and issues entries, so a CLI-only user learns the grammar without ever seeing the dashboard's autocomplete. cli.ts remains the thin dispatch hub — verbs' logic lives in their own modules; help text lives in help.ts; a sibling verb's churn in the hub is that feature's, not this node's drift.