如何用 get-shit-done 的 gsd-sdk query 编程化调用 state、config、phase 命令
【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done
当你为自己的脚本、CI 任务或二次开发工具读取/写入一个 GSD 管理的项目时,需要直接操作三类数据:项目状态.planning/STATE.md(state 命令族)、配置.planning/config.json(config 命令族)、以及阶段目录与 roadmap 同步(phase 命令族)。get-shit-done 为这类调用提供了统一入口:npm 包@gsd-build/sdk中的gsd-sdk query子命令,以及 TypeScript 侧的createRegistry()编程式 API。两者走同一套注册表(registry),成功时向 stdout 输出 JSON。环境要求:Node.js ≥ 22.0.0(见 sdk/package.json 的engines字段),且目标目录是一个已用 GSD 初始化的项目(存在.planning/)。
安装 SDK 并跑通 CLI
在依赖该包的脚本所在目录安装:
npm install @gsd-build/sdkSDK README 推荐在 CI 和本地开发中用 Node 直接调用 dist 中的 CLI(等价于包的gsd-sdkbin 入口):
node ./node_modules/@gsd-build/sdk/dist/cli.js query state.json node ./node_modules/@gsd-build/sdk/dist/cli.js query roadmap.analyze先做一次最小验证——查询 STATE.md 的 frontmatter:
node ./node_modules/@gsd-build/sdk/dist/cli.js query state.json输出为 JSON 时说明 CLI、注册表、项目目录解析都正常。query state.json返回的是 STATE.md frontmatter 的重建 JSON;如果还想拿到完整项目上下文(config、state 原文、各文件存在性标志),用state load,它返回{ config, state_raw, state_exists, roadmap_exists, config_exists }。两者的区别与适用条件见下文 state 一节。
query支持的全局选项(见 sdk/src/cli.ts 的 USAGE 文本):
| 选项 | 作用 |
|---|---|
--project-dir <dir> | 指定项目目录,默认process.cwd() |
--ws <name> | 把工作路由到.planning/workstreams/<name>/(多 workstream 项目) |
--pick <field> | 从 JSON 输出中提取指定字段 |
-h/--help | 帮助;gsd-sdk query phase add --help这类写法会把--help透传给具体 handler,输出该子命令的上下文帮助 |
-v/--version | 打印gsd-sdk v<version>,可用于确认入口可用 |
命令解析:argv 如何映射到注册表 handler
gsd-sdk query接受点号(dotted)和空格两种命令形态,解析规则与 CJS 版gsd-tools.cjs的runCommand()一致(见 QUERY-HANDLERS.md 的 “gsd-sdk query routing” 一节):
normalizeQueryCommand()先把前几个 argv token 归一成「命令 + 子命令」,例如state json→state.json、init execute-phase 9→init.execute-phase(args 为['9']);resolveQueryArgv()按最长前缀匹配注册表 key。例如state update status X会命中 handlerstate.update,剩余参数为[status, X];- 单个点号 token(如
init.new-project)直接匹配;首轮未命中时会拆分点号再匹配一次; - 若仍无匹配且
GSD_QUERY_FALLBACK不是off/never/false/0,CLI 会回退 shell 调用gsd-tools.cjs(stderr 打印一条简短的 bridge 警告); - 成功时 JSON 写到 stdout。
两个例外要记牢:graphify和from-gsd2是产品决策上的CLI-only命令,不注册进 SDK registry,需要一直用node gsd-tools.cjs …调用;反向地,phases archive是 SDK-only,CJS 侧没有对应子命令。
用 query 调用 state 命令族
state 命令族管理.planning/STATE.md。完整命令清单(含 mutation 标记和别名)在 sdk/src/query/command-manifest.state.ts;docs/CLI-TOOLS.md 的 “State Commands” 一节给出了每个子命令的用途说明。
只读调用(不改文件,可放心在脚本中反复执行):
# STATE.md frontmatter 的 JSON 形式 gsd-sdk query state json # 完整项目上下文:config + state_raw + 存在性标志 gsd-sdk query state load # 读取整个 STATE.md,或只取某个 frontmatter 字段 gsd-sdk query state get gsd-sdk query state get milestone # 结构性校验(注册表中标记为只读,不属于 mutation 命令) gsd-sdk query state validate写操作调用(会持久化修改.planning/STATE.md,执行前确认项目状态;STATE.md 与 ROADMAP 的写入通过同目录.lock文件加锁,stale 锁会在持有 PID 不存在时自动清理):
# 更新单个字段 gsd-sdk query state update status X # 批量更新多个字段 gsd-sdk query state patch --phase 3 --plan 2 # 递增 plan 计数器 gsd-sdk query state advance-planmanifest 中mutation: true的还包括state.begin-phase、state.record-metric、state.update-progress、state.add-decision、state.add-blocker、state.resolve-blocker、state.record-session、state.signal-waiting、state.signal-resume、state.sync、state.prune等,参数形态与 CLI-TOOLS.md 中node gsd-tools.cjs state …的示例一一对应(CJS → SDK 的对应关系例如node gsd-tools.cjs state json→gsd-sdk query state json)。
一个安装布局相关的限制:state load内部要解析core.cjs(按 monorepo 打包路径、projectDir/.claude/get-shit-done/…、~/.claude/get-shit-done/…顺序探测)。在只安装了@gsd-build/sdk的最小布局里如果找不到core.cjs,state load会抛GSDError并附带已探测路径列表——此时改用state.json或补全安装。
用 query 调用 config 命令族
config 命令族读写.planning/config.json,注册表登记的名字与 CJS 同名(config-get、config-set、config-set-model-profile、config-ensure-section、config-new-project、config-path):
# 读取一个配置值(docs 中的示例 key 为 model_profile) gsd-sdk query config-get model_profile # 只取 config.json 的路径(纯文本输出) gsd-sdk query config-path # 设置值(key 支持点号路径) gsd-sdk query config-set model_profile "inherit"一个文档给出的真实场景是 code-review 工作流的 CLI 路由配置(见 CLI-TOOLS.md “Reviewer CLI Routing”):
gsd-sdk query config-set review.models.codex "codex exec --model gpt-5" gsd-sdk query config-set review.models.gemini "gemini -m gemini-2.5-pro" gsd-sdk query config-set review.models.opencode "opencode run --model claude-sonnet-4" gsd-sdk query config-set review.models.claude "" # 清空 — 回退到 session modelslug 会被按[a-zA-Z0-9_-]+校验,空 slug 或含路径的 slug 会被拒绝。注意密钥处理:经/gsd-settings配置的 API key 以明文写入config.json,但在所有config-set/config-get输出中会被掩码为****<后 4 位>;config.json本身即安全边界(.planning/默认被 gitignore)。
用 query 调用 phase 命令族
phase 命令族管理阶段目录、编号与 roadmap 同步。只读调用示例:
# 按编号找阶段目录 gsd-sdk query find-phase 3 # 计算插入用的下一个十进制阶段号 gsd-sdk query phase next-decimal 3 # 索引某阶段的 plans(含 wave 与状态) gsd-sdk query phase-plan-index 12 # 列出所有阶段(CJS 侧还支持 --type planned|executed|all 等过滤) gsd-sdk query phases list写操作对应 roadmap 与阶段目录的持久化修改(追加/插入/删除/完成阶段并重编号后续阶段):
gsd-sdk query phase add "Add user auth" gsd-sdk query phase insert 3 "Insert auth middleware" gsd-sdk query phase complete 3此外注册表里有几个SDK-only的阶段查询,原本要靠 shellls/find/grep拼出来的信息可以改为直接查询(见 QUERY-HANDLERS.md “Phase / plan listing (SDK-only)”):
gsd-sdk query phase.list-plans 3 gsd-sdk query phase.list-artifacts 3 --type summary gsd-sdk query plan.task-structure .planning/phases/3/.../PLAN.md用 createRegistry() 在 TypeScript 中编程式调用
不想起子进程时,@gsd-build/sdk导出createRegistry()与GSD,dispatch 走同一个 typed query 层。README 的 Quickstart 是一个可直接改造的起点:
import { GSD, createRegistry } from '@gsd-build/sdk'; const gsd = new GSD({ projectDir: process.cwd(), sessionId: 'my-run' }); const registry = createRegistry(gsd.eventStream, 'my-run'); const projectDir = process.cwd(); // state 只读 const stateRes = await registry.dispatch('state.json', [], projectDir); // config 读写 const profile = await registry.dispatch('config-get', ['model_profile'], projectDir); await registry.dispatch('config-set', ['review.models.codex', 'codex exec --model gpt-5'], projectDir); // phase 只读 const phaseRes = await registry.dispatch('phase-plan-index', ['12'], projectDir);要点:
registry.dispatch('dotted.name', args, projectDir)是统一调用形式,命令名用注册表中的点号规范名;createRegistry(eventStream, sessionId)的sessionId会随 mutation 相关事件一起透传,便于在事件流里关联会话;省略时为空;- 若走
GSDTools(gsd.createTools()),dispatch 经过 SDK Runtime Bridge:优先 native registry,子进程回退由allowFallbackToSubprocess显式控制,strictSdk模式在没有 native adapter 时直接失败,onDispatchEvent输出 dispatch mode、回退原因、耗时、结果与错误类别等可观测数据——在 CI 中做严格 SDK-only 执行时建议启用。
输出、退出码与错误判断
写脚本时的判断依据来自 QUERY-HANDLERS.md “Error handling” 与 “Dispatch Policy Module contract” 两节:
- 成功:handler 结果 JSON 写到 stdout。程序化 dispatch 的契约是
{ ok: true, stdout, stderr, exit_code: 0 };CLI 就是这层 seam 的薄适配器,直接使用该exit_code。 - 校验类错误(缺必填参数、非法 phase 等“调用方必须修输入”的情况):handler 抛
GSDError,映射为结构化 dispatch 错误,kind取值有unknown_command、native_failure、native_timeout、fallback_failure、validation_error、internal_error。 - 预期内的领域失败(文件不存在、intel 未启用、todo 缺失等“当前项目状态下操作无法完成”的情况):不抛异常,而是返回
{ data: { error: string, ... } }——调用方必须在结果存在时检查data.error。
OUT=$(gsd-sdk query config-get model_profile) echo "$OUT" # 用 --pick 只取字段: gsd-sdk query config-get model_profile --pick value两条排障规则:
- stderr 出现 bridge 警告,说明该命令没有 native handler、走了 CJS 回退。需要确定性行为时设
GSD_QUERY_FALLBACK=off(等价写法never/false/0),未注册命令会 fail fast 而不是静默回退。 - 多 workstream 项目里,
--ws <name>把.planning/路由到.planning/workstreams/<name>/;未传--ws时会回退读取GSD_WORKSTREAM环境变量,保证与gsd-tools.cjs看到同一份.planning/。
边界与限制
graphify、from-gsd2未注册进 SDK registry(依赖 Graphify/Python 栈与遗留迁移脚本),必须继续用node gsd-tools.cjs graphify …等 CLI 形式;graphify还需要config.json中graphify.enabled: true。phases archive仅 SDK 侧提供;CJSphases只有list与clear。- 会持久化写入的命令(
state update、state patch、phase add等,完整清单见QUERY_MUTATION_COMMANDS)在脚本中批量执行前应先确认目标目录;这些命令通过.lock文件避免并发写冲突,而不是静默排队。 - 命令全量对照表(CJS 顶层命令 → SDK dispatch 名、别名、CLI-only 判定)维护在 QUERY-HANDLERS.md 的 “CJS command surface vs SDK registry” 矩阵;用户侧命令语义查 docs/CLI-TOOLS.md,用户面向的
/gsd-slash 命令查 docs/COMMANDS.md。
跑通验证路径收口为一条:state.json能返回 JSON →config-get能取回期望 key →find-phase/phases list返回与.planning/磁盘实际一致的结构 → 对写命令执行后再查一次只读命令确认变更落地。
【免费下载链接】get-shit-doneA light-weight and powerful meta-prompting, context engineering and spec-driven development system for Claude Code by TÂCHES.项目地址: https://gitcode.com/GitHub_Trending/getshi/get-shit-done
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考