Skip to content

CLI Reference

Lex edited this page Aug 21, 2026 · 3 revisions

CLI Reference

The specgit CLI has ten commands. The human story is issuefinish; setup installs agent entry points; bind/unbind/accept are machine aliases for scripts. All evaluation is evidence-derived and fail-closed.

Command summary

Command Purpose Network Exit codes
specgit init Create the project policy (spec_git/policy.yaml) and generate the harness gh (protection probe) 0 · 2 · 3
specgit setup Install agent entry points (opencode commands / portable skills) no 0 · 2 · 3
specgit issue One-command delivery bootstrap (issues, branch, draft PR, record, commit, push) yes 0 · 2 · 3
specgit pr Repair the PR binding (auto-discover by head branch, or bind explicitly) yes 0 · 2 · 3
specgit finish The verdict — full evaluation against git + forge evidence yes 0 · 1 · 2 · 3
specgit bind Create/update the delivery record .specgit.yaml — script alias no 0 · 2 · 3
specgit unbind Delete the delivery record — script alias (requires --yes) no 0 · 2
specgit status Local evidence only (record, policy, git facts, drift) no 0 · 2 · 3
specgit accept Same evaluation as finish — script/CI alias yes 0 · 1 · 2 · 3
specgit doctor Probe prerequisites (git, repo, origin, forge CLI, policy) forge auth only 0 · 3

Plus --version and --help (exit 0; usage errors exit 2).

Exit-code contract

Code Meaning
0 Success / accepted — all gates passed with evidence
1 Rejected with complete evidence — all evidence gathered, ≥1 gate failed
2 Usage error — bad flags, invalid arguments
3 Fail-closed unknown — evidence could not be gathered (record/policy missing or invalid, forge CLI missing or unauthenticated, transport failure, not a git repo). Exception: status reports a missing record as the healthy pre-binding state — exit 0, state unbound
130 Interruption exception — Ctrl-C during an interactive prompt; stderr prints Interrupted., no JSON envelope. Treat as "interrupted, no verdict"

1 vs 3 is contractual: 1 = evidence gathered and it says no; 3 = no verdict possible. Automation must branch on codes, never on phrasing.

The --json envelope

Available on every command. stdout becomes exactly one JSON document; all human-readable text goes to stderr (the single exception is the 130 interruption path, which emits no envelope).

{
  "tool": "specgit",
  "version": "1.0.0",
  "command": "accept",
  "status": "rejected",
  "exit": 1,
  "state": "bound",
  "verdict": {
    "accepted": false,
    "gates": [
      { "id": "closing", "status": "fail", "code": "closing_refs_incomplete",
        "detail": { "missing": [124] },
        "fix": "Add \"Closes #124\" to the PR body" }
    ],
    "evidence": { "repo": "LeXwDeX/SpecGit", "branch": "feat/123-login",
                  "context": { "kind": "branch" }, "pr": 42, "prHead": "abc123…" }
  },
  "errors": [
    { "severity": "error", "code": "closing_refs_incomplete",
      "message": "PR 42 does not close issue #124", "target": "pr:42",
      "fix": "Add \"Closes #124\" to the PR body" }
  ]
}
  • statusok | rejected | unknown | error
  • exit — the numeric exit code (0 | 1 | 2 | 3)
  • stateunbound | draft | bound | accepted | rejected | unknown
  • verdict.gates[] — one entry per evaluated gate with id, status, failure code, structured detail, and a fix
  • verdict.evidence — the facts the verdict was derived from
  • errors[] — diagnostics with severity, code, message, target, fix

Environment variables

Variable Meaning
SPECGIT_GH Path to the gh executable (default: gh on PATH)
SPECGIT_GH_TIMEOUT_MS Per-call gh timeout, default 15000 ms; timeout ⇒ gh_transport (exit 3)
SPECGIT_GLAB Path to the glab executable (default: glab on PATH)
SPECGIT_GLAB_TIMEOUT_MS Per-call glab timeout, default 15000 ms; timeout ⇒ glab_transport (exit 3)

No tokens are ever read from the environment — authentication is your existing gh/glab session. Standard NO_COLOR/CI detection also applies.

Command notes

  • init: write-once policy (re-run exits 2 policy_exists; --force rebuilds). Flags: --required-check <name> (repeatable), --gitlab-host <hostname>, --language en|zh, --protect / --no-protect. Non-destructive: validates before mutating, rolls back partial harness writes, merges hooks never overwrites them.
  • setup: --tool opencode | generic | all (omit to auto-detect).
  • issue: arguments are quoted titles (create) or pure numbers (reuse); re-run resumes idempotently. Titles: <type>: <english title> with a fixed type whitelist.
  • finish / accept: identical evaluation and exit codes; CI runs specgit finish --json.
  • status: zero network; a missing record is exit 0 with state unbound, an invalid record is exit 3.
  • doctor: probes git → repository → origin → forge CLI present → forge CLI authenticated → policy.

Language configuration

language: en|zh in spec_git/policy.yaml (specgit init --language zh) selects the language of issue/PR scaffolds, the managed guidance block, and success-path stderr prose. Never localized: exit codes, --json fields, diagnostic codes, closing references (Closes #n), branch names (always ASCII — a non-ASCII title falls back to feat/123-issue123).


命令参考

specgit CLI 共十个命令。人的主线是 issuefinishsetup 安装 agent 入口;bind/unbind/accept 是给脚本用的机器别名。所有评估都基于证据推导,且 fail-closed。

命令总览

命令 用途 网络 退出码
specgit init 创建项目策略(spec_git/policy.yaml)并生成验收护栏 gh(保护探测) 0 · 2 · 3
specgit setup 安装 agent 入口(opencode 命令 / 通用 skills) 0 · 2 · 3
specgit issue 一条命令引导交付(issue、分支、draft PR、记录、commit、push) 0 · 2 · 3
specgit pr 修复 PR 绑定(按 head 分支自动发现,或显式绑定) 0 · 2 · 3
specgit finish 裁决 —— 基于 git + forge 证据的完整评估 0 · 1 · 2 · 3
specgit bind 创建/更新交付记录 .specgit.yaml —— 脚本别名 0 · 2 · 3
specgit unbind 删除交付记录 —— 脚本别名(需要 --yes 0 · 2
specgit status 仅本地证据(记录、策略、git 事实、漂移) 0 · 2 · 3
specgit accept finish 相同的评估 —— 脚本/CI 别名 0 · 1 · 2 · 3
specgit doctor 探测前置条件(git、仓库、origin、forge CLI、策略) 仅 forge 认证 0 · 3

另有 --version--help(退出 0;用法错误退出 2)。

退出码契约

退出码 含义
0 成功 / accepted —— 所有门禁都凭证据通过
1 Rejected(拒绝),附完整证据 —— 证据已全部收集,至少一个门禁失败
2 用法错误 —— 非法参数
3 Fail-closed unknown(未知) —— 证据无法收集(记录/策略缺失或无效、forge CLI 缺失或未认证、传输失败、不在 git 仓库中)。例外:status缺失的记录视为健康的未绑定状态 —— 退出 0,state 为 unbound
130 中断例外 —— 交互提示期间按 Ctrl-C;stderr 输出 Interrupted.,不输出 JSON envelope。视为"已中断,无结论"

13 的区别是契约性的:1 = 证据收集到了且结论是否;3 = 无法得出结论。自动化必须按退出码分支,不能按措辞判断。

--json envelope

所有命令都支持。stdout 恰好输出一个 JSON 文档;所有人类可读文本走 stderr(唯一例外是 130 中断路径,不输出 envelope)。字段含义见英文部分的示例:statusok/rejected/unknown/error)、exit(数字退出码)、stateunbound/draft/bound/accepted/rejected/unknown)、verdict.gates[](每个门禁一条:idstatus、失败 code、结构化 detail、修复建议 fix)、verdict.evidence(结论依据的事实)、errors[](诊断项)。

环境变量

变量 含义
SPECGIT_GH gh 可执行文件路径(默认 PATH 上的 gh
SPECGIT_GH_TIMEOUT_MS 每次 gh 调用超时,默认 15000 ms;超时 ⇒ gh_transport(退出 3)
SPECGIT_GLAB glab 可执行文件路径(默认 PATH 上的 glab
SPECGIT_GLAB_TIMEOUT_MS 每次 glab 调用超时,默认 15000 ms;超时 ⇒ glab_transport(退出 3)

不会从环境变量读取任何 token —— 认证沿用你已有的 gh/glab 会话。同时支持标准的 NO_COLOR/CI 检测。

命令要点

  • init:策略文件只写一次(重复运行退出 2 policy_exists--force 重建)。参数:--required-check <name>(可重复)、--gitlab-host <hostname>--language en|zh--protect / --no-protect。非破坏性:先验证再改动,中途失败回滚,hooks 只合并不覆盖。
  • setup--tool opencode | generic | all(省略时自动检测)。
  • issue:参数是带引号的标题(新建)或纯数字(复用);重跑幂等续跑。标题格式 <type>: <english title>,type 有固定白名单。
  • finish / accept:评估与退出码完全相同;CI 中运行的是 specgit finish --json
  • status:零网络调用;记录缺失退出 0(state unbound),记录无效退出 3
  • doctor:探测顺序 git → 仓库 → origin → forge CLI 存在 → forge CLI 已认证 → 策略文件。

语言配置

spec_git/policy.yaml 中的 language: en|zh(或 specgit init --language zh)决定 issue/PR 脚手架、受管指引区块和成功路径 stderr 文案的语言。永不本地化的部分:退出码、--json 字段名、诊断 code、关闭引用(Closes #n)、分支名(始终 ASCII —— 非 ASCII 标题回退为 feat/123-issue123)。

Clone this wiki locally