cmd

package
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 3, 2026 License: MIT Imports: 30 Imported by: 0

Documentation

Overview

Package cmd implements specd's CLI commands, one file per command (RunInit, RunNext, RunVerify, and so on), dispatched through the command-name-to-handler table in registry.go. Each handler parses its already-tokenized internal/cli.Args, applies command-specific validation, and calls into internal/core for the actual state/spec mutation — keeping domain logic out of the command layer.

helpers.go centralizes the shared exit/usage/error-line conventions so every command produces a consistent CLI and JSON-mode contract.

Index

Constants

This section is empty.

Variables

View Source
var Registry = []Command{
	{"init", RunInit},
	{"handshake", RunHandshake},
	{"new", RunNew},
	{"approve", RunApprove},
	{"decision", RunDecision},
	{"midreq", RunMidreq},
	{"memory", RunMemory},
	{"brain", RunBrain},
	{"pinky", RunPinky},
	{"next", RunNext},
	{"verify", RunVerify},
	{"task", RunTask},
	{"status", RunStatus},
	{"context", RunContext},
	{"check", RunCheck},
	{"report", RunReport},
	{"waves", RunWaves},
}

Registry lists every dispatchable command in help-display order.

Functions

func Dispatch

func Dispatch(command string, args cli.Args) (int, bool)

Dispatch runs the handler registered for command. It returns (exitCode, true) when the command is known, or (0, false) when it is not — letting the caller render the unknown-command help path.

func NewServeHandler

func NewServeHandler(root, slug string) http.Handler

NewServeHandler builds the read-only, browser-native dashboard handler for a project. It is multi-spec: GET `/` renders an index of every spec under the project, GET `/s/<slug>` renders that spec's live report HTML (the same markup as `specd report --format html`), GET `/api/report?spec=<slug>` returns the JSON ReportData, and `/events` mounts the reused frontier SSE stream for live updates. The `slug` argument is the default spec used when no `?spec=` query is supplied (and the default link target on the index). Every response is rebuilt from disk per request so the view always reflects current state, and the handler exposes no mutating routes: non-GET methods get 405 and a missing spec yields 404. It is the unit of behaviour the serve tests exercise without binding a port.

func RunApprove

func RunApprove(args cli.Args) int

RunApprove implements `specd approve`. Under the spec lock it handles three cases in order: clearing an awaiting-approval gate, accepting a verifying spec as complete (enforcing the acceptance-criteria gate when configured), or advancing a planning-phase spec to the next status — printing the result as JSON or human-readable text.

func RunBrain

func RunBrain(args cli.Args) int

RunBrain implements `specd brain`, dispatching to the start/run/status/step/ why/directive/pause/resume/cancel/checkpoint/compact/clear/ledger subcommands that drive Brain orchestration sessions for a single spec or, with --program, a whole multi-spec program.

func RunCheck

func RunCheck(args cli.Args) int

RunCheck implements `specd check`: it loads the spec's artifacts and state, runs the gate pipeline (or, with --schema/--schema-only, just regenerates or validates the schema), and renders the resulting violations and warnings as JSON or human-readable text.

func RunContext

func RunContext(args cli.Args) int

RunContext implements `specd context`: it builds the phase-appropriate briefing (purpose, load list, skill, focus, and next action), the measured context manifest, and any active gate/blocker/uncovered-requirement signals for a spec, optionally persisting a context snapshot (--snapshot), and renders the result as JSON or human-readable text.

func RunDecision

func RunDecision(args cli.Args) int

RunDecision implements `specd decision`: under the spec lock it appends a new architecture decision record (auto-numbered ADR-NNN) with the given decision text to the spec's decisions.md, optionally noting a superseded ADR via --supersedes.

func RunHandshake

func RunHandshake(args cli.Args) int

RunHandshake implements `specd handshake`, dispatching to the "bootstrap" subcommand (a machine-readable startup oracle for host agents) and the "policy" subcommand (effective subagent/orchestration/sandbox policy plus any violations, optionally scoped to a spec).

func RunInit

func RunInit(args cli.Args) int

RunInit implements `specd init`. It runs the workspace onboarding flow (scaffolding .specd, applying packs, probing/registering MCP integrations) via the default init executor and onboarding runtime.

func RunMCP

func RunMCP(args cli.Args) int

RunMCP starts the native MCP stdio server. It is a thin JSON-RPC 2.0 transport over the existing command handlers — no new business logic, no network, no LLM calls. Tool calls re-dispatch through the same cmd.Dispatch the CLI uses, so every read-safe and state-mutating command is reachable by an MCP host.

It is handled like help/version (in main.run, not via the dispatch Registry): the server is not itself a spec-scoped command and must not be exposed as a tool.

func RunMemory

func RunMemory(args cli.Args) int

RunMemory implements `specd memory <slug> <add|promote>`. The "add" subcommand appends a new pattern entry to the spec's memory.md; "promote" lifts an existing entry into the shared steering/memory.md once it has been observed in at least the configured threshold of specs (or with --force).

func RunMidreq

func RunMidreq(args cli.Args) int

RunMidreq implements `specd midreq`: under the spec lock it bumps the spec's turn counter, appends a mid-spec requirement-change entry (verbatim input, interpretation, impact, and changes made) to mid-requirements.md, and, for high or critical impact, sets the awaiting-approval gate so work stops until the revised plan is approved.

func RunNew

func RunNew(args cli.Args) int

RunNew implements `specd new`: it validates the slug, refuses to overwrite an existing spec, materializes the six spec artifacts from templates (seeding requirements.md with --from, if given), writes the initial state.json (optionally starting in orchestrated mode with --orchestrated), and prints the next step.

func RunNext

func RunNext(args cli.Args) int

RunNext implements `specd next`, the scheduler-facing query for what work to do next on a spec. With --dispatch it delegates to runDispatch; otherwise it loads the spec's task DAG and, after checking the awaiting-approval gate, either reports the full runnable frontier (--all) or the single next runnable task — printed as JSON (--json) or as human-readable task detail (title, role, why, files, contract, acceptance, verify command, and dependencies). RunNext is read-only: it never mutates state.Tasks.

func RunPinky

func RunPinky(args cli.Args) int

RunPinky implements `specd pinky`, the worker-facing command a Pinky agent uses to claim a dispatched mission and report back on it: claim, brief, heartbeat, progress, query, block, report, checkpoint, suspend, resume, release, and inbox/status subcommands.

func RunReport

func RunReport(args cli.Args) int

RunReport implements `specd report`. It dispatches to the --history, --diff, --serve, --watch, and --pr-summary modes; with none of those flags it loads the spec and renders the static report (Markdown, HTML, or Prometheus metrics) to stdout or, with --out, to a file.

func RunStatus

func RunStatus(args cli.Args) int

RunStatus implements `specd status`. With --program it reports program-level status; with no slug it lists every spec's status summary; given a slug it prints (or, with --set-mode/--recommend, mutates or advises on) that spec's detailed status, tasks counts, wave graph, blockers, and next action.

func RunTask

func RunTask(args cli.Args) int

RunTask implements `specd task`: it validates the requested --status transition for a task, then either delegates "complete" to core.CompleteTask's integrity-checked path or, under the spec lock, mutates the task's status/blocker/annotation directly, persisting both state.json and tasks.md.

func RunVerify

func RunVerify(args cli.Args) int

RunVerify implements `specd verify`. With --criterion it records a pass/fail acceptance-criterion result; otherwise it runs a task's declared verify command under the spec lock (selecting a sandbox runner, applying --revert-on-fail recovery on failure, and recording telemetry), persists the resulting VerificationRecord to state, and prints the outcome.

func RunWaves

func RunWaves(args cli.Args) int

RunWaves implements `specd waves`: it loads the spec's task DAG and prints the wave-by-wave task graph, the critical path, and any blockers, as JSON (--json) or as the human-readable wave graph.

Types

type ArtifactChange

type ArtifactChange struct {
	Path   string `json:"path"`   // repo-relative path
	Status string `json:"status"` // "added" | "modified" | "deleted" | "renamed"
}

ArtifactChange is one artifact file that changed between two git refs.

type Command

type Command struct {
	Name string
	Run  func(cli.Args) int
}

Command binds a CLI command name to its handler. The user-facing metadata (summary, usage, flags, exit codes, examples) lives in core.Commands, which is what `specd help` renders. Registry is the single dispatch source consumed by main.go. A parity test (registry_test.go) asserts Registry and core.Commands never drift — adding a command requires an entry in both, so help can never silently omit a dispatchable command and vice versa.

`help` and `version` are intentionally absent: they are handled in main.run before dispatch (they are not spec-scoped command handlers).

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL