cmd

package
v0.2.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: 33 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},
	{"review", RunReview},
	{"eval", RunEval},
	{"promote", RunPromote},
	{"conductor", RunConductor},
	{"orchestrate", RunOrchestrate},
	{"submit", RunSubmit},
	{"deploy", RunDeploy},
	{"observe", RunObserve},
	{"ingest", RunIngest},
	{"report", RunReport},
	{"waves", RunWaves},
	{"harness", RunHarness},
	{"dashboard", RunDashboard},
	{"migrate", RunMigrate},
}

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 NewDashboardHandler added in v0.2.0

func NewDashboardHandler(root, slug, mode string) http.Handler

NewDashboardHandler builds the unified dashboard handler. GET `/` renders the aggregate dashboard; GET `/s/<slug>` renders one spec's report (reusing the serve markup); GET `/api/dashboard` returns the JSON projection; `/events` mounts the shared SSE stream. Every response is rebuilt from disk per request and there are no mutating routes: non-GET → 405, missing spec → 404.

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 RecommendConductorHandoff added in v0.2.0

func RecommendConductorHandoff(state *core.State) core.ConductorHandoffRecommendation

RecommendConductorHandoff wraps the core recommendation, substituting the concrete spec slug into the rationale placeholder.

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 RunConductor added in v0.2.0

func RunConductor(args cli.Args) int

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 RunDashboard added in v0.2.0

func RunDashboard(args cli.Args) int

RunDashboard implements `specd dashboard` (V11/P6.2): the unified, read-only project dashboard. It renders every spec's status, orchestrator waves, conductor sessions, eval trends, cost, and escalations — plus the shared harness bundle — from local state and ledgers only, with zero outbound network. It is a project-wide alias over the `serve` machinery: the home page is the aggregate dashboard rather than a bare spec index, and it reuses the same SSE live-update stream, per-spec report routes, and loopback bind.

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 RunDeploy added in v0.2.0

func RunDeploy(args cli.Args) int

RunDeploy implements `specd deploy` (V9/P5.1): the evidence-gated deploy driver runner and its rollback. The bare form refuses unless the spec is complete, required gates are recorded green, and (for production or an approval-required plan) a human deploy approval exists; then it runs the plan's steps sequenced through the shared sandboxed exec path, appending every result to deploy.jsonl. `deploy rollback` replays the recorded inverse chain in reverse. No CD logic is embedded — steps are operator-authored commands.

func RunEval added in v0.2.0

func RunEval(args cli.Args) int

RunEval dispatches the eval command. Subcommands `init` and `trend` are selected by the second positional; the bare form scores the spec against its rubric. Scoring is deterministic (invariant 6/7): the same rubric and artifacts always yield the same score; only the recorded timestamp varies.

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 RunHarness added in v0.2.0

func RunHarness(args cli.Args) int

RunHarness implements `specd harness` (V11/P6.1): sharing the configured policy (guardrails, deploy templates, roles, routing) as a versioned team asset over stdlib-exec git. `push` bundles the current policy and pushes it; `pull` imports a bundle with SHA256 pinning, refuses to clobber local modifications without --force, and quarantines every imported executable `command` artifact until it is explicitly enabled. `list` shows the bundle and quarantine; `enable` installs one quarantined artifact and records the decision.

func RunIngest added in v0.2.0

func RunIngest(args cli.Args) int

RunIngest implements `specd ingest` (V10/P5.3): `ingest new <slug> --path <dir>` validates the path, writes a deterministic inventory.json (countable facts only — the binary never reads legacy semantics), and scaffolds an ingestion-flavored spec. The `specd-ingest` skill teaches the agent to reverse-engineer requirements/design/tasks; the `ingest` gate then enforces that every inventoried file is mapped or waived.

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 RunMigrate added in v0.2.0

func RunMigrate(args cli.Args) int

RunMigrate implements `specd migrate` (V12/P6.4): the documented, idempotent one-shot that moves a v0.1.x project onto v0.2.0. It rewrites every spec's state at the current schema version (the v5→v6 migration is otherwise silent on first load) and reports which additive policy blocks are available to adopt. It never writes policy content, so a migrated repo keeps the new gates default-off. Running it twice is a no-op.

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 RunObserve added in v0.2.0

func RunObserve(args cli.Args) int

RunObserve implements `specd observe` (V9/P5.2): the offline `correlate` transform (the core feature — CI pipes an exported error payload in) and the optional localhost `--listen` HTTP receiver. Both deterministically attribute an error to a spec and append an evidenced entry to that spec's mid-requirements.md, gating high/critical impact for human approval.

func RunOrchestrate added in v0.2.0

func RunOrchestrate(args cli.Args) int

RunOrchestrate surfaces and resolves auto-escalations (V7/P3.2). `status` prints the current escalation record and the advisory conductor-handoff recommendation; `resume --override` is the human override path that clears the escalation so orchestration may proceed. The binary never auto-clears an escalation and never auto-switches mode — resolution is always an explicit human action (invariant: never auto-switch).

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 RunPromote added in v0.2.0

func RunPromote(args cli.Args) int

RunPromote converts a prototype spec to a full spec after a passing eval. The evidence string is mandatory — micro-approval never bypasses the evidence discipline (invariant 5).

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 RunReview added in v0.2.0

func RunReview(args cli.Args) int

RunReview implements `specd review`. The bare form scaffolds review_report.md (mandatory sections + verdict skeleton) and prints the read-only reviewer brief; `review checklist` deterministically extracts a human review checklist from design.md + tasks.md (extraction only, zero interpretation).

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 RunSubmit added in v0.2.0

func RunSubmit(args cli.Args) int

RunSubmit implements `specd submit` (V7/P3.4): it validates that every gate is green for the spec (optionally scoped to a wave bundle), generates the deterministic PR summary, and streams it on stdin to the operator-configured `submit.command` run through the shared sandboxed exec path with a scrubbed env. No git/GitHub logic is embedded. A non-zero command exit is exit 1 with no partial state — the summary is regenerated from state, never persisted mid-run.

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