docs(i18n): add Simplified Chinese user docs (#4105)

This commit is contained in:
Eric Chan 2026-04-13 19:57:41 +08:00 committed by GitHub
parent 2c75425916
commit 843b72e7c1
23 changed files with 5721 additions and 0 deletions

View file

@ -6,6 +6,8 @@ Welcome to the GSD documentation. This covers everything from getting started to
Guides for installing, configuring, and using GSD day-to-day. Located in [`user-docs/`](./user-docs/).
Simplified Chinese translation: [`zh-CN/`](./zh-CN/).
| Guide | Description |
|-------|-------------|
| [Getting Started](./user-docs/getting-started.md) | Installation, first run, and basic usage |

32
docs/zh-CN/README.md Normal file
View file

@ -0,0 +1,32 @@
# GSD 文档
欢迎使用 GSD 文档。这里涵盖了从快速开始到高级配置、自动模式内部机制,以及如何基于 Pi SDK 扩展 GSD 的内容。
> 本目录是主文档的简体中文翻译。目前优先覆盖 `docs/user-docs/` 这套用户手册;如中英文内容有差异,请以英文原文为准。
## 用户文档
用于安装、配置和日常使用 GSD 的指南。文件位于 [`user-docs/`](./user-docs/)。
| 指南 | 说明 |
|------|------|
| [快速开始](./user-docs/getting-started.md) | 安装、首次运行和基础使用 |
| [自动模式](./user-docs/auto-mode.md) | 自主执行如何工作,包括状态机、崩溃恢复和引导控制 |
| [命令参考](./user-docs/commands.md) | 所有命令、键盘快捷键和 CLI 参数 |
| [远程提问](./user-docs/remote-questions.md) | 用于无头自动模式的 Discord、Slack 和 Telegram 集成 |
| [配置](./user-docs/configuration.md) | 偏好设置、模型选择、Git 设置和 Token 配置 |
| [提供商设置](./user-docs/providers.md) | OpenRouter、Ollama、LM Studio、vLLM 以及所有受支持提供商的分步配置 |
| [自定义模型](./user-docs/custom-models.md) | 高级模型配置,包括 `models.json` 结构、兼容标志和覆盖项 |
| [Token 优化](./user-docs/token-optimization.md) | Token 配置、上下文压缩、复杂度路由和自适应学习 |
| [动态模型路由](./user-docs/dynamic-model-routing.md) | 基于复杂度的模型选择、成本表、升级策略和预算压力 |
| [捕获与分流](./user-docs/captures-triage.md) | 自动模式中的随手记录,以及自动分流处理 |
| [工作流可视化器](./user-docs/visualizer.md) | 用于查看进度、依赖、指标和时间线的交互式 TUI 叠层 |
| [成本管理](./user-docs/cost-management.md) | 预算上限、成本跟踪、成本预测和执行策略 |
| [Git 策略](./user-docs/git-strategy.md) | 工作树隔离、分支模型和合并行为 |
| [并行编排](./user-docs/parallel-orchestration.md) | 通过隔离的工作线程和协调机制同时运行多个 milestones |
| [团队协作](./user-docs/working-in-teams.md) | 唯一 milestone ID、`.gitignore` 设置和共享规划产物 |
| [技能](./user-docs/skills.md) | 内置技能、技能发现和自定义技能编写 |
| [从 v1 迁移](./user-docs/migration.md) | 将 `.planning` 目录迁移到新的 `.gsd` 格式 |
| [故障排查](./user-docs/troubleshooting.md) | 常见问题、`/gsd doctor``/gsd forensics` 和恢复流程 |
| [Web 界面](./user-docs/web-interface.md) | 通过 `gsd --web` 使用基于浏览器的项目管理界面 |
| [VS Code 扩展](../../vscode-extension/README.md) | 聊天参与者、侧边栏仪表板以及 VS Code 的 RPC 集成 |

View file

@ -0,0 +1,301 @@
# 自动模式
自动模式是 GSD 的自主执行引擎。运行 `/gsd auto`,然后离开;回来时你会看到已经构建好的软件,以及干净的 git 历史。
## 工作原理
自动模式本质上是一个**由磁盘文件驱动的状态机**。它会读取 `.gsd/STATE.md`,确定下一个工作单元,创建一个新的 agent 会话,把所有相关上下文预先内联到一个聚焦 prompt 中,再让 LLM 执行。LLM 完成后,自动模式会再次读取磁盘状态,并派发下一个工作单元。
### 执行循环
每个 slice 都会自动经历以下阶段:
```
Plan (with integrated research) → Execute (per task) → Complete → Reassess Roadmap → Next Slice
↓ (all slices done)
Validate Milestone → Complete Milestone
```
- **Plan**:巡检代码库、研究相关文档,把 slice 分解成带 must-have 的 task
- **Execute**:在新的上下文窗口中逐个执行 task
- **Complete**:写 summary、UAT 脚本、标记 roadmap、提交代码
- **Reassess**:检查 roadmap 是否仍然合理
- **Validate Milestone**:在所有 slices 完成后做一致性校验,把 roadmap 的成功标准与实际结果对照,避免在封板前漏掉关键缺口
## 关键特性
### 每个单元都用全新会话
每个 task、research 阶段和 planning 步骤都会得到一个干净的上下文窗口。没有历史垃圾堆积,也不会因为上下文膨胀导致质量下降。派发 prompt 中已经包含 task plan、历史 summary、依赖上下文、决策记录等必要信息因此 LLM 一开始就能对齐,而不必先花工具调用去读文件。
### 预加载上下文
派发 prompt 会精心组装以下内容:
| 内联产物 | 用途 |
|----------|------|
| Task plan | 告诉 agent 要构建什么 |
| Slice plan | 说明当前 task 在整体中的位置 |
| 历史 task summaries | 告诉 agent 已经完成了什么 |
| 依赖 summary | 提供跨 slice 上下文 |
| Roadmap 摘要 | 说明整体方向 |
| Decisions register | 提供架构上下文 |
具体内联多少内容由你的 [token profile](./token-optimization.md) 控制。`budget` 模式只内联最少上下文,`quality` 模式则把所有内容都内联进去。
### Git 隔离
GSD 支持三种 milestone 隔离模式(通过偏好设置中的 `git.isolation` 配置):
- **`worktree`**(默认):每个 milestone 都运行在 `.gsd/worktrees/<MID>/` 下自己的 git worktree 中,分支名为 `milestone/<MID>`。所有 slice 工作都顺序提交,不需要切分支,也不会在 milestone 内部产生合并冲突。milestone 完成后,再整体 squash merge 回主分支,形成一个干净提交。
- **`branch`**:工作发生在项目根目录下的 `milestone/<MID>` 分支上。适合子模块较多、worktree 表现不佳的仓库。
- **`none`**:直接在当前分支工作。没有 worktree也没有 milestone 分支。适合文件隔离会破坏开发工具的热重载场景。
详见 [Git 策略](./git-strategy.md)。
### 并行执行
当项目里存在彼此独立的 milestones 时,可以同时运行它们。每个 milestone 都拥有自己的 worker 进程和 worktree。配置与用法见 [并行编排](./parallel-orchestration.md)。
### 崩溃恢复
自动模式会用锁文件跟踪当前工作单元。如果会话中途退出,下一次执行 `/gsd auto` 时,会读取残留的会话文件,从所有已经落盘的工具调用中综合生成一份恢复简报,然后带着完整上下文继续执行。
**Headless 自动重启v2.26** 当运行 `gsd headless auto`崩溃会触发带指数退避的自动重启5s → 10s → 30s 上限,默认最多 3 次)。通过 `--max-restarts N` 配置。SIGINT/SIGTERM 不会触发重启。结合崩溃恢复机制,这让真正的“跑一夜直到完成”成为可能。
### Provider 错误恢复
GSD 会对 provider 错误分类,并在安全时自动恢复:
| 错误类型 | 示例 | 动作 |
|----------|------|------|
| **限流** | 429、`too many requests` | 按 `retry-after` 头等待,或默认 60 秒后自动恢复 |
| **服务端错误** | 500、502、503、`overloaded``api_error` | 30 秒后自动恢复 |
| **永久错误** | `unauthorized``invalid key``billing` | 无限期暂停,等待人工恢复 |
对临时性错误通常不需要人工介入,系统会短暂暂停后自动继续。
### 增量记忆v2.26
GSD 会维护一个 `KNOWLEDGE.md` 文件作为项目特有规则、模式和经验的追加式记录。agent 在每个工作单元开始时都会读取它;当发现反复出现的问题、非显而易见的模式或未来会话需要遵循的规则时,也会把内容追加进去。这样一来,自动模式就有了跨会话、跨上下文窗口的持久记忆。
### 上下文压力监视器v2.26
当上下文使用达到 70% 时GSD 会向 agent 发送收尾信号,提醒它优先完成可持久化的输出(例如提交、写 summary避免在 task 中途因为上下文打满而什么都没来得及落盘。
### 有意义的提交信息v2.26
提交信息不是通用的 “complete task”而是从 task summary 生成的。每条提交消息都反映了真正完成了什么,因此 `git log` 看起来更像一份高质量的变更日志。
### 卡死检测v2.39
GSD 使用滑动窗口分析来检测卡死循环。它不只是简单地统计“同一单元是否重复派发两次”,而是会分析近期派发历史中的重复模式,因此既能发现单点重复,也能发现 A→B→A→B 这样的循环。一旦检测到GSD 会先带着更深的诊断 prompt 重试一次;如果仍然失败,自动模式就会停止,并指出它原本期待的具体文件,便于你介入。
这种滑动窗口方法能降低合法重试场景(例如可自动修复的 verification 失败)的误报,同时更快抓到真正的卡死循环。
### 事后取证v2.40
`/gsd forensics` 是一个面向自动模式失败分析的全访问 GSD 调试器,提供:
- **异常检测**:对卡死循环、成本尖峰、超时、产物缺失和崩溃做结构化识别,并标注严重级别
- **单元追踪**:最近 10 次单元执行,包含错误细节和执行时长
- **指标分析**成本、token 数量和执行时间拆分
- **Doctor 集成**:把 `/gsd doctor` 中的结构性健康问题一起纳入
- **LLM 引导调查**:启动一个拥有完整工具访问权限的 agent 会话来调查根因
```
/gsd forensics [optional problem description]
```
更多诊断方式见 [故障排查](./troubleshooting.md)。
### 超时监管
三层超时机制可以防止会话失控:
| 超时类型 | 默认值 | 行为 |
|----------|--------|------|
| Soft | 20 分钟 | 警告 LLM 应该开始收尾 |
| Idle | 10 分钟 | 检测停滞并介入 |
| Hard | 30 分钟 | 暂停自动模式 |
恢复引导会提醒 LLM 在真正超时前尽量完成可持久化输出。配置方式如下:
```yaml
auto_supervisor:
soft_timeout_minutes: 20
idle_timeout_minutes: 10
hard_timeout_minutes: 30
```
### 成本跟踪
每个工作单元的 token 使用量和成本都会被记录并按阶段、slice 和模型拆分。仪表板会显示运行总量和预测值。预算上限可以在超支前主动暂停自动模式。
详见 [成本管理](./cost-management.md)。
### 自适应重规划
每完成一个 sliceroadmap 都会重新评估。如果最新工作暴露出会改变计划的新信息,后续 slices 就会在继续前被重新排序、添加或删除。`balanced``budget` token profile 可以跳过这一阶段。
### 验证强制执行v2.26
你可以配置 shell 命令,让它们在每个 task 执行后自动运行:
```yaml
verification_commands:
- npm run lint
- npm run test
verification_auto_fix: true # 默认开启自动重试修复
verification_max_retries: 2 # 最大重试次数(默认 2
```
一旦失败agent 会看到 verification 输出并尝试自动修复后重试,再决定是否继续。这意味着代码质量门禁是靠机制强制执行,而不是靠 LLM“自觉遵守”。
### Slice 讨论门v2.26
如果你希望每个 slice 开始前都先经过人工确认:
```yaml
require_slice_discussion: true
```
自动模式会在每个 slice 开始前暂停,并把 slice 上下文展示出来供你讨论。确认后才继续执行。适用于高风险项目,尤其是你希望 agent 开始构建前先复核计划的时候。
### HTML 报告v2.26
每当 milestone 完成后GSD 都会在 `.gsd/reports/` 中自动生成一个自包含的 HTML 报告。报告包括项目摘要、进度树、slice 依赖图SVG DAG、成本 / Token 柱状图、执行时间线、变更日志和知识库。没有外部依赖,所有 CSS 和 JS 都会内联。
```yaml
auto_report: true # 默认开启
```
你也可以随时手动执行 `/gsd export --html` 生成报告,或通过 `/gsd export --html --all`v2.28)为所有 milestones 一次性生成报告。
### 故障恢复强化v2.28
v2.28 通过多项机制强化了自动模式的可靠性原子文件写入可避免崩溃时损坏文件OAuth 拉取超时30 秒避免无限挂起RPC 子进程退出能被检测并报告blob 垃圾回收可防止磁盘无限增长。结合已有的崩溃恢复和 headless 自动重启,自动模式可以真正支持“扔在那里跑一晚上”的场景。
### 流水线架构v2.40
自动循环采用的是线性阶段流水线,而非递归派发。每轮迭代都经过明确的阶段:
1. **Pre-Dispatch**:校验状态、检查守卫、解析模型偏好
2. **Dispatch**:使用聚焦 prompt 执行当前单元
3. **Post-Unit**:关闭该单元、更新缓存、执行清理
4. **Verification**可选验证门lint、test 等)
5. **Stuck Detection**:滑动窗口模式分析
这种线性流程更容易调试,占用更少内存(没有递归调用栈),也使错误恢复更清晰,因为每个阶段都有明确的入口和出口条件。
### 实时健康可见性v2.40
`/gsd doctor` 发现的问题现在会实时出现在三个地方:
- **Dashboard widget**:健康指示器,显示问题数量和严重级别
- **Workflow visualizer**:状态面板中展示问题
- **HTML reports**:生成报告时带出完整健康信息
问题按严重程度分为:`error`(阻塞自动模式)、`warning`(不阻塞)和 `info`(提示性质)。自动模式会在派发时检查健康状态,并可在关键问题出现时主动暂停。
### Prompt 中的技能激活v2.39
配置好的技能会被自动解析并注入派发 prompt。agent 会收到一个 “Available Skills” 区块,列出当前上下文匹配的技能,来源包括:
- `always_use_skills`:始终注入
- `prefer_skills`:以偏好形式注入
- `skill_rules`:根据 `when` 条件做条件激活
技能路由偏好详见 [配置](./configuration.md)。
## 控制自动模式
### 启动
```
/gsd auto
```
### 暂停
**Escape**。对话会被保留,你可以继续和 agent 交互、查看状态,或者稍后恢复。
### 恢复
```
/gsd auto
```
自动模式会读取磁盘状态,并从中断处继续。
### 停止
```
/gsd stop
```
优雅地停止自动模式。这个命令也可以从另一个终端执行。
### 引导
```
/gsd steer
```
在不中断流水线的情况下,强制修改计划文档。修改会在下一个阶段边界生效。
### 捕获
```
/gsd capture "add rate limiting to API endpoints"
```
随手记录想法不打断当前执行。Captures 会在 tasks 之间自动 triage。详见 [捕获与分流](./captures-triage.md)。
### 可视化
```
/gsd visualize
```
打开工作流可视化器,交互式查看进度、依赖、指标和时间线。详见 [工作流可视化器](./visualizer.md)。
## 仪表板
`Ctrl+Alt+G``/gsd status` 会显示实时进度:
- 当前 milestone、slice 和 task
- 自动模式的已运行时间和当前阶段
- 每个单元的成本与 token 拆分
- 成本预测
- 已完成和进行中的单元
- 待 triage 的 capture 数量(如果存在)
- 并行 worker 状态(运行并行 milestones 时显示,也包含 80% 预算预警)
## 跳过阶段
Token profile 可以通过跳过某些阶段来降低成本:
| 阶段 | `budget` | `balanced` | `quality` |
|------|----------|------------|-----------|
| Milestone Research | 跳过 | 执行 | 执行 |
| Slice Research | 跳过 | 跳过 | 执行 |
| Reassess Roadmap | 跳过 | 执行 | 执行 |
更多细节见 [Token 优化](./token-optimization.md)。
## 动态模型路由
启用后,自动模式会为简单工作单元(例如 slice completion、UAT自动选择更便宜的模型并把昂贵模型保留给复杂工作例如重规划或架构 task。详见 [动态模型路由](./dynamic-model-routing.md)。
## 响应式 Task 执行v2.38
当在偏好中设置 `reactive_execution: true`GSD 会从 task plan 中的 IO 注解推导依赖图。互不冲突的 tasks没有共享文件读写会通过 subagents 并行派发,而存在依赖的 tasks 则等待前驱完成。
```yaml
reactive_execution: true # 默认关闭
```
依赖图推导是纯函数且确定性的:它会解析 ready-set、检测冲突和死锁并做相应防护。并行批次中的 verification 结果会被沿用,因此某些 tasks 如果已经通过验证,后续同一 slice 中其他 tasks 完成时就不需要再次验证。
这套实现位于 `reactive-graph.ts`负责图推导、ready-set 解析、冲突 / 死锁检测),并集成到了 `auto-dispatch.ts``auto-prompts.ts`

View file

@ -0,0 +1,84 @@
# 捕获与分流
*引入于 v2.19.0*
Captures 允许你在自动模式执行过程中随手记录想法而不必打断当前流程。你可以把新想法、bug 或范围变更记录下来,让 GSD 在 tasks 之间的自然间隙中进行分流处理。
## 快速开始
在自动模式运行期间(或任何时候):
```
/gsd capture "add rate limiting to the API endpoints"
/gsd capture "the auth flow should support OAuth, not just JWT"
```
这些 capture 会追加到 `.gsd/CAPTURES.md`,并在 tasks 之间自动参与 triage。
## 工作原理
### 流程
```
capture → triage → confirm → resolve → resume
```
1. **Capture**`/gsd capture "thought"` 会带着时间戳和唯一 ID 追加到 `.gsd/CAPTURES.md`
2. **Triage**:在 tasks 之间的自然衔接点(`handleAgentEnd`GSD 会检测待处理 capture 并进行分类
3. **Confirm**:向用户展示建议的处理方式,由用户确认或调整
4. **Resolve**:应用该处理方案(插入 task、触发重规划、延期等
5. **Resume**:自动模式继续运行
### 分类类型
每条 capture 都会被分类到以下五种类型之一:
| 类型 | 含义 | 处理方式 |
|------|------|----------|
| `quick-task` | 小型、可独立完成的修复 | 立即以内联 quick task 执行 |
| `inject` | 当前 slice 需要新增 task | 将 task 注入当前活跃的 slice plan |
| `defer` | 重要但不紧急 | 延后到 roadmap reassessment 时处理 |
| `replan` | 改变当前实现路径 | 带着 capture 上下文触发 slice replan |
| `note` | 仅供记录,不需要动作 | 记录并确认,不修改计划 |
### 自动分流
在自动模式下triage 会在 tasks 之间自动触发。triage prompt 会收到:
- 所有待处理 captures
- 当前 slice plan
- 当前活跃 roadmap
LLM 会对每条 capture 进行分类并给出建议处理方案。会修改计划的处理方式(`inject``replan`)需要用户确认。
### 手动分流
你也可以随时手动触发 triage
```
/gsd triage
```
这在你积累了多条 capture并希望在下一个自然间隙之前先处理掉它们时很有用。
## 仪表板集成
当有待 triage 的 capture 时,进度组件会显示一个待处理数量徽标。无论是在 `Ctrl+Alt+G` 仪表板里,还是自动模式进度组件里,都能看到这个提示。
## 上下文注入
Capture 上下文会自动注入到:
- **Replan-slice prompts**:让重规划知道是什么触发了它
- **Reassess-roadmap prompts**:让被延后的 capture 也会影响 roadmap 决策
## Worktree 感知
Captures 总是写回**原始项目根目录**下的 `.gsd/CAPTURES.md`,而不是 worktree 的本地副本。这样从 steering 终端记录的内容,也能被运行在 worktree 里的自动模式会话看到。
## 命令
| 命令 | 说明 |
|------|------|
| `/gsd capture "text"` | 记录一个想法(单词时引号可省略) |
| `/gsd triage` | 手动触发待处理 captures 的 triage |

View file

@ -0,0 +1,177 @@
# Claude Code 认证合规性研究
日期2026-04-10
## 执行摘要
Anthropic 当前公开的指导原则边界非常清晰:
- Anthropic 自家的原生应用,包括 Claude Code可以使用 Claude 订阅认证。
- 第三方工具应优先通过 Claude Console 或受支持云 provider 的 API key 进行认证。
- 任何伪装身份、绕过订阅限制转发第三方流量、或以其他方式违反 Anthropic 条款的应用,都被明确禁止。
对于 GSD2安全路径应当是
1. 把本地 Claude Code 视为一个外部、已认证的运行时。
2. 永远不要让 GSD 用户通过 GSD 托管的 Anthropic OAuth 去登录 Claude 订阅。
3. 永远不要把 Claude.ai 的订阅 OAuth 凭据交换成 bearer token然后冒充 Claude Code 直接调用 Anthropic API。
4. 如果 GSD 需要直接访问 Anthropic API则必须要求使用 Claude Console API key、Bedrock、Vertex 或其他被明确支持的 provider 路径。
## Anthropic 明确允许的内容
### 1. Claude Code 本身可以使用 Claude 订阅认证
Anthropic 帮助中心说明Claude Pro / Max 用户应安装 Claude Code运行 `claude`,并“使用与你登录 Claude 相同的凭据”完成登录。文档还指出,这样会把订阅直接连接到 Claude Code并且 `/login` 是切换账户类型的方式。Team / Enterprise 文章对组织账号也给出了同样流程。
对 GSD2 的含义:
- 允许用户在真正的 `claude` CLI 内部完成认证,是符合 Anthropic 文档流程的
- 检测 `claude auth status`,然后通过本地 CLI 或官方 Claude Code SDK 路由工作,是风险最低的方案
### 2. Claude Code 同时支持订阅 OAuth 和 API 凭据
Anthropic 的 Claude Code 文档说明,支持的认证类型包括 Claude.ai 凭据、Claude API 凭据、Azure Auth、Bedrock Auth 和 Vertex Auth。文档还定义了认证优先级
1. cloud provider 凭据
2. `ANTHROPIC_AUTH_TOKEN`
3. `ANTHROPIC_API_KEY`
4. `apiKeyHelper`
5. 来自 `/login` 的订阅 OAuth
对 GSD2 的含义:
- 如果 GSD2 是通过 shell 调用或嵌入 Claude Code那么它应尊重 Claude Code 自己的凭据选择逻辑,而不是再发明一套平行的 Anthropic OAuth 流程
- 对需要动态短期凭据、但又不希望把原始 API key 交给工具的组织来说,`apiKeyHelper` 是一个干净的企业级出口
### 3. Anthropic 的商业使用可通过 API keys 和受支持的云 provider 实现
Anthropic 的商业条款约束的是 API keys 及其相关 Anthropic 服务,包括供客户构建给终端用户使用的产品。面向团队的认证文档推荐使用 Claude for Teams / Enterprise、Claude Console、Bedrock、Vertex 或 Microsoft Foundry。
对 GSD2 的含义:
- 如果 GSD2 作为一个产品面向用户提供 Anthropic 能力,那么任何直接 Anthropic 访问都应走商业认证路径,而不是复用订阅 token
## Anthropic 明确警告的内容
Anthropic 当前的 “Logging in to your Claude account” 文章给出了最清晰的表述:
- 订阅计划仅适用于 Anthropic 原生应用的日常使用,包括 Claude Web、桌面端、移动端和 Claude Code
- 对第三方工具(包括开源项目),“首选方式”是通过 Claude Console 或受支持云 provider 的 API key 认证
- 如果你正在为他人构建产品、应用或工具,应使用 Claude Console API key 或受支持云 provider 的认证方式
- 任何伪装身份、绕过订阅限制转发第三方流量、或以其他方式违反条款的工具,都被禁止
Anthropic 的消费条款还额外加入两项限制:
- 用户不得把账户登录信息、API keys 或账户凭据分享给他人
- 除非是通过 Anthropic API key 访问服务,或者 Anthropic 明确允许,否则用户不得通过自动化或非人工方式访问这些服务
对 GSD2 的含义:
- 由 GSD 托管的 Anthropic 订阅 OAuth 流程属于高风险
- 在 GSD 自己的 API client 中复用用户 Claude 订阅凭据属于高风险
- 任何会让 Anthropic 误以为请求来自 Claude Code、但实际上来自 GSD 基础设施的流程,都越界了
## 当前 GSD2 发现
### 低风险 / 已对齐的部分
- `src/resources/extensions/claude-code-cli/index.ts`
`claude-code` 注册成 `externalCli` provider并通过 Anthropic 官方的 `@anthropic-ai/claude-agent-sdk` 路由
- `src/resources/extensions/claude-code-cli/readiness.ts`
只通过 `claude --version``claude auth status` 检查本地 CLI 是否存在以及认证状态
- `src/onboarding.ts`
TUI onboarding 已移除 Anthropic 浏览器 OAuth并把本地 Claude Code 路由标记为符合 TOS 的路径
- `src/cli.ts`
当检测到本地 CLI 可用时,会把用户从 `anthropic` 迁移到 `claude-code`
这些方向是正确的,因为此时 GSD 使用的是用户自己本地安装的 Claude Code作为已认证的 Anthropic surface。
### 中高风险部分 —— 已解决
所有 Anthropic OAuth 代码路径都已被移除:
- `packages/pi-ai/src/utils/oauth/anthropic.ts` —— **已删除**,不再实现 Anthropic OAuth 流程
- `packages/pi-ai/src/utils/oauth/index.ts` —— **已更新**,内置注册表中移除了 `anthropicOAuthProvider`
- `src/web/onboarding-service.ts` —— **已更新**,将 Anthropic 标记为 `supportsOAuth: false`
- `packages/daemon/src/orchestrator.ts` —— **已更新**,去掉 OAuth token refresh改为要求 `ANTHROPIC_API_KEY` 环境变量
- `packages/pi-ai/src/providers/anthropic.ts` —— **已更新**,移除 OAuth client 分支,`isOAuthToken` 始终返回 false
## 针对 GSD2 的建议策略
将下面内容作为仓库规则:
- Claude 订阅认证只允许存在于 Anthropic 自有 surface 中:
- `claude` CLI
- 基于本地已认证 Claude Code 安装的 Claude Code SDK
- 其他 Anthropic 文档明确支持的原生流程
- GSD2 不得为终端用户实现自己的 Anthropic 订阅 OAuth 流程
- GSD2 不得持久化 Anthropic 订阅 OAuth token供后续 API 调用使用
- GSD2 不得使用由 GSD 获取的订阅 OAuth tokens 来发送 Anthropic API 流量
- GSD2 可以支持 Anthropic 直接访问,但仅限以下方式:
- `ANTHROPIC_API_KEY`
- 保存在 auth storage 中的 Claude Console API keys
- `apiKeyHelper`
- Bedrock / Vertex / Foundry
- 本地 Claude Code provider
## 推荐实现方案
### 方案 A安全的最小合规清理
1. 从内置 OAuth provider 注册表中移除 Anthropic
2. 把 Web onboarding 中的 Anthropic 改为只支持 API key
3. 当 `claude auth status` 成功时,继续保留 `claude-code` 作为推荐路径
4. 增加明确的 UI 文案:
- “Claude 订阅用户:请登录本地 Claude Code app / CLI而不是 GSD。”
5. 阻止任何把 Anthropic OAuth 凭据转换成 GSD 托管请求 API 认证的迁移或代码路径
这是让仓库与 Anthropic 当前公开指导对齐的最快路径。
### 方案 B企业级安全的 Anthropic 支持
把 Anthropic 支持拆分成三种清晰模式:
- `claude-code`
只使用本地已认证的 `claude` 运行时
- `anthropic-api`
使用 Console API keys 或 `apiKeyHelper`
- `anthropic-cloud`
使用 Bedrock、Vertex 或 Foundry
然后彻底移除任何模糊的 `anthropic` 浏览器登录路径。
这是长期最好的 UX因为它清晰地区分了
- 基于订阅的原生使用
- 基于 API 计费的使用
- 通过云路由的使用
## 具体仓库后续动作 —— 已完成
1. ~~删除或禁用 `packages/pi-ai/src/utils/oauth/anthropic.ts`。~~ **已完成** —— 文件已删除
2. ~~从 `packages/pi-ai/src/utils/oauth/index.ts` 中移除 `anthropicOAuthProvider`。~~ **已完成**
3. ~~修改 `src/web/onboarding-service.ts`,让 Anthropic 不再声称支持 OAuth。~~ **已完成**
4. ~~审查 `packages/daemon/src/orchestrator.ts` 以及其他把 Anthropic OAuth access token 当作 API 凭据使用的调用方。~~ **已完成** —— daemon 现在要求 `ANTHROPIC_API_KEY`
5. ~~更新文档 / UI 文案:直接 API 使用优先 `anthropic-api`,订阅使用优先 `claude-code`。~~ **已完成** —— `providers.md``getting-started.md` 已更新
6. 添加测试,防止 Anthropic 订阅 OAuth 通过 onboarding / provider registry 被重新引入 —— **TODO**
## 决策规则
如果某个拟议中的 GSD2 特性需要访问 Anthropic先问一个问题
“GSD 是以 GSD 的身份调用 Anthropic还是 GSD 只是把工作委派给用户本地已认证的 Claude Code 运行时?”
- 如果 GSD 是以 GSD 的身份调用 Anthropic必须要求 API key 或受支持的云认证
- 如果 GSD 只是委派给本地 Claude Code可以接受前提是 GSD 自身不会拦截、生成或重放订阅凭据
## 审查过的来源
- Anthropic Help Center: “Logging in to your Claude account”
- Anthropic Help Center: “Using Claude Code with your Pro or Max plan”
- Anthropic Help Center: “Use Claude Code with your Team or Enterprise plan”
- Anthropic Help Center: “Managing API key environment variables in Claude Code”
- Anthropic Help Center: “API Key Best Practices: Keeping Your Keys Safe and Secure”
- Claude Code Docsgetting started / authentication / team / settings / IAM
- Anthropic Commercial Terms of Service
- Anthropic Consumer Terms of Service
- Anthropic Usage Policy

View file

@ -0,0 +1,308 @@
# 命令参考
## 会话命令
| 命令 | 说明 |
|------|------|
| `/gsd` | Step mode一次执行一个工作单元并在每步之间暂停 |
| `/gsd next` | 显式 Step mode`/gsd` 相同) |
| `/gsd auto` | 自动模式research、plan、execute、commit然后重复 |
| `/gsd quick` | 在不经过完整 planning 开销的情况下,执行一个带 GSD 保证的 quick task原子提交、状态跟踪 |
| `/gsd stop` | 优雅地停止自动模式 |
| `/gsd pause` | 暂停自动模式(保留状态,可用 `/gsd auto` 恢复) |
| `/gsd steer` | 在执行过程中强制修改 plan 文档 |
| `/gsd discuss` | 讨论架构和决策(可与自动模式并行使用) |
| `/gsd status` | 进度仪表板 |
| `/gsd widget` | 循环切换仪表板组件full / small / min / off |
| `/gsd queue` | 给未来 milestones 排队和重排(自动模式中也安全) |
| `/gsd capture` | 随手记录一个想法,不打断当前流程(自动模式中可用) |
| `/gsd triage` | 手动触发待处理 captures 的 triage |
| `/gsd dispatch` | 直接派发一个指定阶段research、plan、execute、complete、reassess、uat、replan |
| `/gsd history` | 查看执行历史(支持 `--cost``--phase``--model` 过滤) |
| `/gsd forensics` | 全访问 GSD 调试器:用于分析自动模式失败,支持结构化异常检测、单元追踪和 LLM 引导的根因分析 |
| `/gsd cleanup` | 清理 GSD 状态文件和过期 worktrees |
| `/gsd visualize` | 打开工作流可视化器(进度、依赖、指标、时间线) |
| `/gsd export --html` | 为当前或已完成的 milestone 生成自包含 HTML 报告 |
| `/gsd export --html --all` | 一次性为所有 milestones 生成回顾报告 |
| `/gsd update` | 在会话内更新到最新版本 |
| `/gsd knowledge` | 添加持久化项目知识(规则、模式或经验) |
| `/gsd fast` | 为支持的模型切换 service tier优先级 API 路由) |
| `/gsd rate` | 评价上一个单元所用模型层级over / ok / under帮助改进自适应路由 |
| `/gsd changelog` | 查看分类后的发行说明 |
| `/gsd logs` | 浏览活动日志、调试日志和指标 |
| `/gsd remote` | 控制远程自动模式 |
| `/gsd help` | 查看所有 GSD 子命令的分类参考及说明 |
## 配置与诊断
| 命令 | 说明 |
|------|------|
| `/gsd prefs` | 模型选择、超时和预算上限 |
| `/gsd mode` | 切换工作流模式solo / team同时应用与 milestone ID、git 提交行为和文档相关的协调默认值 |
| `/gsd config` | 重新运行 provider 配置向导LLM provider + 工具 key |
| `/gsd keys` | API key 管理器列出、添加、移除、测试、轮换、doctor |
| `/gsd doctor` | 运行时健康检查与自动修复;问题会实时显示在 widget、visualizer 和 HTML reports 中v2.40 |
| `/gsd inspect` | 查看 SQLite DB 诊断信息 |
| `/gsd init` | 项目初始化向导:检测、配置并 bootstrap `.gsd/` |
| `/gsd setup` | 查看全局 setup 状态和配置 |
| `/gsd skill-health` | 技能生命周期仪表板使用统计、成功率、token 趋势、过期告警 |
| `/gsd skill-health <name>` | 查看某个 skill 的详细信息 |
| `/gsd skill-health --declining` | 只显示被标记为表现下降的 skills |
| `/gsd skill-health --stale N` | 显示 N 天以上未使用的 skills |
| `/gsd hooks` | 查看已配置的 post-unit 和 pre-dispatch hooks |
| `/gsd run-hook` | 手动触发一个指定 hook |
| `/gsd migrate` | 将 v1 的 `.planning` 目录迁移到 `.gsd` 格式 |
## Milestone 管理
| 命令 | 说明 |
|------|------|
| `/gsd new-milestone` | 创建一个新的 milestone |
| `/gsd skip` | 阻止某个工作单元被自动模式派发 |
| `/gsd undo` | 回退上一个已完成单元 |
| `/gsd undo-task` | 重置某个特定 task 的完成状态DB + markdown |
| `/gsd reset-slice` | 重置某个 slice 及其所有 tasksDB + markdown |
| `/gsd park` | Park 一个 milestone不删除只跳过 |
| `/gsd unpark` | 重新激活一个已 park 的 milestone |
| Discard milestone | 在 `/gsd` 向导的 “Milestone actions” → “Discard” 中可用 |
## 并行编排
| 命令 | 说明 |
|------|------|
| `/gsd parallel start` | 分析可并行性、确认后启动 workers |
| `/gsd parallel status` | 显示所有 workers 的状态、进度和成本 |
| `/gsd parallel stop [MID]` | 停止所有 workers或停止某个指定 milestone 的 worker |
| `/gsd parallel pause [MID]` | 暂停所有 workers或暂停某个指定 worker |
| `/gsd parallel resume [MID]` | 恢复已暂停的 workers |
| `/gsd parallel merge [MID]` | 把已完成的 milestones 合并回 main |
完整文档见 [并行编排](./parallel-orchestration.md)。
## Workflow Templatesv2.42
| 命令 | 说明 |
|------|------|
| `/gsd start` | 启动一个 workflow templatebugfix、spike、feature、hotfix、refactor、security-audit、dep-upgrade、full-project |
| `/gsd start resume` | 恢复一个进行中的 workflow |
| `/gsd templates` | 列出可用 workflow templates |
| `/gsd templates info <name>` | 查看某个 template 的详细信息 |
## 自定义 Workflowsv2.42
| 命令 | 说明 |
|------|------|
| `/gsd workflow new` | 创建一个新的 workflow definition通过 skill |
| `/gsd workflow run <name>` | 创建一个 run 并启动自动模式 |
| `/gsd workflow list` | 列出 workflow runs |
| `/gsd workflow validate <name>` | 校验一个 workflow YAML definition |
| `/gsd workflow pause` | 暂停自定义 workflow 的自动模式 |
| `/gsd workflow resume` | 恢复已暂停的自定义 workflow 自动模式 |
## 扩展
| 命令 | 说明 |
|------|------|
| `/gsd extensions list` | 列出所有扩展及其状态 |
| `/gsd extensions enable <id>` | 启用一个被禁用的扩展 |
| `/gsd extensions disable <id>` | 禁用一个扩展 |
| `/gsd extensions info <id>` | 查看扩展详情 |
## cmux 集成
| 命令 | 说明 |
|------|------|
| `/gsd cmux status` | 显示 cmux 检测结果、prefs 和能力 |
| `/gsd cmux on` | 启用 cmux 集成 |
| `/gsd cmux off` | 禁用 cmux 集成 |
| `/gsd cmux notifications on/off` | 切换 cmux 桌面通知 |
| `/gsd cmux sidebar on/off` | 切换 cmux 侧边栏元数据 |
| `/gsd cmux splits on/off` | 切换 cmux subagent 可视化分屏 |
## GitHub Syncv2.39
| 命令 | 说明 |
|------|------|
| `/github-sync bootstrap` | 初始配置:根据当前 `.gsd/` 状态创建 GitHub Milestones、Issues 和 draft PRs |
| `/github-sync status` | 显示同步映射数量milestones、slices、tasks |
在偏好设置里启用 `github.enabled: true`。要求已安装并认证 `gh` CLI。同步映射会保存在 `.gsd/.github-sync.json`
## Git 命令
| 命令 | 说明 |
|------|------|
| `/worktree``/wt` | Git worktree 生命周期管理create、switch、merge、remove |
## 会话管理
| 命令 | 说明 |
|------|------|
| `/clear` | 启动一个新会话(`/new` 的别名) |
| `/exit` | 优雅退出,会在退出前保存会话状态 |
| `/kill` | 立即终止 GSD 进程 |
| `/model` | 切换当前 active model |
| `/login` | 登录一个 LLM provider |
| `/thinking` | 在会话中切换 thinking level |
| `/voice` | 切换实时语音转文字macOS、Linux |
## 键盘快捷键
| 快捷键 | 动作 |
|--------|------|
| `Ctrl+Alt+G` | 切换 dashboard overlay |
| `Ctrl+Alt+V` | 切换语音转录 |
| `Ctrl+Alt+B` | 显示后台 shell 进程 |
| `Ctrl+V` / `Alt+V` | 从剪贴板粘贴图片(截图 → vision 输入) |
| `Escape` | 暂停自动模式(保留对话) |
> **注意:** 在不支持 Kitty keyboard protocol 的终端中(如 macOS Terminal.app、JetBrains IDEs界面会显示 slash-command 形式的回退命令,而不是 `Ctrl+Alt` 快捷键。
>
> **提示:** 如果 `Ctrl+V` 被终端拦截(例如 Warp可改用 `Alt+V` 粘贴剪贴板图片。
## CLI 参数
| 参数 | 说明 |
|------|------|
| `gsd` | 启动新的交互式会话 |
| `gsd --continue``-c` | 恢复当前目录最近一次会话 |
| `gsd --model <id>` | 为当前会话覆盖默认模型 |
| `gsd --print "msg"``-p` | 单次 prompt 模式(无 TUI |
| `gsd --mode <text\|json\|rpc\|mcp>` | 非交互使用时的输出模式 |
| `gsd --list-models [search]` | 列出可用模型并退出 |
| `gsd --web [path]` | 启动基于浏览器的 Web 界面(可选项目路径) |
| `gsd --worktree``-w`[name] | 在 git worktree 中启动会话(未指定时自动生成名称) |
| `gsd --no-session` | 禁用会话持久化 |
| `gsd --extension <path>` | 加载一个额外扩展(可重复) |
| `gsd --append-system-prompt <text>` | 向 system prompt 末尾追加文本 |
| `gsd --tools <list>` | 启用的工具列表,逗号分隔 |
| `gsd --version``-v` | 输出版本并退出 |
| `gsd --help``-h` | 输出帮助并退出 |
| `gsd sessions` | 交互式会话选择器:列出当前目录所有保存的会话并选择一个恢复 |
| `gsd --debug` | 启用结构化 JSONL 诊断日志,用于排查 dispatch 和 state 问题 |
| `gsd config` | 配置搜索和文档工具所需的全局 API keys保存到 `~/.gsd/agent/auth.json`,对所有项目生效)。见 [Global API Keys](./configuration.md#global-api-keys-gsd-config)。 |
| `gsd update` | 更新到最新版本 |
| `gsd headless new-milestone` | 根据上下文文件创建新的 milestoneheadless无需 TUI |
## Headless 模式
`gsd headless` 可在无 TUI 的情况下运行 `/gsd` 命令,适合 CI、cron job 和脚本自动化。它会在 RPC 模式下启动一个子进程,自动回应交互式提示、检测完成状态,并用有意义的退出码退出。
```bash
# 运行自动模式(默认)
gsd headless
# 运行一个单元
gsd headless next
# 即时 JSON 快照,无需 LLM约 50ms
gsd headless query
# 用于 CI 的超时参数
gsd headless --timeout 600000 auto
# 强制指定一个 phase
gsd headless dispatch plan
# 根据上下文文件创建新 milestone并启动自动模式
gsd headless new-milestone --context brief.md --auto
# 用内联文本创建 milestone
gsd headless new-milestone --context-text "Build a REST API with auth"
# 从 stdin 管道输入上下文
echo "Build a CLI tool" | gsd headless new-milestone --context -
```
| 参数 | 说明 |
|------|------|
| `--timeout N` | 总超时(毫秒),默认 `300000` / 5 分钟 |
| `--max-restarts N` | 崩溃时自动重启并指数退避(默认 3。设为 0 可关闭 |
| `--json` | 以 JSONL 形式把所有事件流式输出到 stdout |
| `--model ID` | 覆盖 headless 会话使用的模型 |
| `--context <file>` | 给 `new-milestone` 提供上下文文件(用 `-` 表示 stdin |
| `--context-text <text>` | 给 `new-milestone` 提供内联上下文文本 |
| `--auto` | 在创建 milestone 后直接接续自动模式 |
**退出码:** `0` 表示完成,`1` 表示错误或超时,`2` 表示被阻塞。
任何 `/gsd` 子命令都可以作为位置参数使用,例如:`gsd headless status``gsd headless doctor``gsd headless dispatch execute` 等。
### `gsd headless query`
它会返回单个 JSON 对象,包含完整项目快照,无需 LLM 会话,也无需 RPC 子进程,响应几乎即时(约 50ms。这是 orchestration 工具和脚本检查 GSD 状态的推荐方式。
```bash
gsd headless query | jq '.state.phase'
# "executing"
gsd headless query | jq '.next'
# {"action":"dispatch","unitType":"execute-task","unitId":"M001/S01/T03"}
gsd headless query | jq '.cost.total'
# 4.25
```
**输出结构:**
```json
{
"state": {
"phase": "executing",
"activeMilestone": { "id": "M001", "title": "..." },
"activeSlice": { "id": "S01", "title": "..." },
"activeTask": { "id": "T01", "title": "..." },
"registry": [{ "id": "M001", "status": "active" }, ...],
"progress": { "milestones": { "done": 0, "total": 2 }, "slices": { "done": 1, "total": 3 } },
"blockers": []
},
"next": {
"action": "dispatch",
"unitType": "execute-task",
"unitId": "M001/S01/T01"
},
"cost": {
"workers": [{ "milestoneId": "M001", "cost": 1.50, "state": "running", ... }],
"total": 1.50
}
}
```
<a id="mcp-server-mode"></a>
## MCP Server 模式
`gsd --mode mcp` 会通过 stdin/stdout 将 GSD 作为一个 [Model Context Protocol](https://modelcontextprotocol.io) server 运行。这会把所有 GSD 工具read、write、edit、bash 等)暴露给外部 AI 客户端,例如 Claude Desktop、VS Code Copilot以及任何兼容 MCP 的宿主。
```bash
# 以 MCP server 模式启动 GSD
gsd --mode mcp
```
服务会注册 agent 会话中的全部工具,并把 MCP 的 `tools/list``tools/call` 请求映射到 GSD 的工具定义上。连接会一直保持,直到底层 transport 关闭。
## 会话内更新
`/gsd update` 会检查 npm 上是否有更新版本,并在不离开当前会话的情况下完成安装。
```bash
/gsd update
# Current version: v2.36.0
# Checking npm registry...
# Updated to v2.37.0. Restart GSD to use the new version.
```
如果已经是最新版本,它会给出提示且不做任何操作。
## 导出
`/gsd export` 用于导出 milestone 工作报告。
```bash
# 为当前 active milestone 生成 HTML 报告
/gsd export --html
# 一次性为所有 milestones 生成回顾报告
/gsd export --html --all
```
报告会保存到 `.gsd/reports/`,并生成一个可浏览的 `index.html`,链接到所有已生成的快照。

View file

@ -0,0 +1,852 @@
# 配置
GSD 偏好设置保存在 `~/.gsd/PREFERENCES.md`(全局)或 `.gsd/PREFERENCES.md`(项目级)中。可以通过 `/gsd prefs` 进行交互式管理。
## `/gsd prefs` 命令
| 命令 | 说明 |
|------|------|
| `/gsd prefs` | 打开全局偏好设置向导(默认) |
| `/gsd prefs global` | 全局偏好设置交互向导(`~/.gsd/PREFERENCES.md` |
| `/gsd prefs project` | 项目偏好设置交互向导(`.gsd/PREFERENCES.md` |
| `/gsd prefs status` | 显示当前偏好文件、合并后的值以及 skill 解析状态 |
| `/gsd prefs wizard` | `/gsd prefs global` 的别名 |
| `/gsd prefs setup` | `/gsd prefs wizard` 的别名;若偏好文件不存在会自动创建 |
| `/gsd prefs import-claude` | 将 Claude marketplace plugins 和 skills 以命名空间化的 GSD 组件形式导入 |
| `/gsd prefs import-claude global` | 导入到全局作用域 |
| `/gsd prefs import-claude project` | 导入到项目作用域 |
## 偏好文件格式
偏好设置使用 markdown 文件中的 YAML frontmatter
```yaml
---
version: 1
models:
research: claude-sonnet-4-6
planning: claude-opus-4-6
execution: claude-sonnet-4-6
completion: claude-sonnet-4-6
skill_discovery: suggest
auto_supervisor:
soft_timeout_minutes: 20
idle_timeout_minutes: 10
hard_timeout_minutes: 30
budget_ceiling: 50.00
token_profile: balanced
---
```
## 全局与项目偏好
| 作用域 | 路径 | 适用范围 |
|--------|------|----------|
| 全局 | `~/.gsd/PREFERENCES.md` | 所有项目 |
| 项目 | `.gsd/PREFERENCES.md` | 仅当前项目 |
**合并规则:**
- **标量字段**`skill_discovery``budget_ceiling`):如果项目级定义了,则项目级优先
- **数组字段**`always_use_skills` 等):拼接,顺序为全局在前、项目在后
- **对象字段**`models``git``auto_supervisor`):浅合并,项目级按 key 覆盖
<a id="global-api-keys-gsd-config"></a>
## 全局 API Keys`/gsd config`
工具 API keys 会全局保存在 `~/.gsd/agent/auth.json` 中,并自动应用到所有项目。只需用 `/gsd config` 配置一次,无需在每个项目里维护 `.env`
```bash
/gsd config
```
这会打开一个交互式向导,显示哪些 key 已配置、哪些仍缺失。你可以选择一个工具并输入相应的 key。
### 支持的 keys
| 工具 | 环境变量 | 用途 | 获取地址 |
|------|----------|------|----------|
| Tavily Search | `TAVILY_API_KEY` | 为非 Anthropic models 提供 Web 搜索 | [tavily.com/app/api-keys](https://tavily.com/app/api-keys) |
| Brave Search | `BRAVE_API_KEY` | 为非 Anthropic models 提供 Web 搜索 | [brave.com/search/api](https://brave.com/search/api) |
| Context7 Docs | `CONTEXT7_API_KEY` | 库文档检索 | [context7.com/dashboard](https://context7.com/dashboard) |
### 工作方式
1. `/gsd config` 会把 keys 保存到 `~/.gsd/agent/auth.json`
2. 每次会话启动时,`loadToolApiKeys()` 都会读取该文件并设置环境变量
3. 这些 keys 对所有项目生效,无需单独配置
4. 环境变量(例如 `export BRAVE_API_KEY=...`)优先级高于保存下来的 keys
5. Anthropic models 不需要 Brave/Tavily因为它们自带 Web 搜索
## MCP Servers
GSD 可以连接配置在项目文件中的外部 MCP servers。这适合接入本地工具、内部 API、自托管服务或者那些未作为 GSD 原生扩展内置的集成。
### 配置文件位置
GSD 会从以下项目本地路径读取 MCP client 配置:
- `.mcp.json`
- `.gsd/mcp.json`
如果两个文件都存在,会按 server 名称做合并,先找到的定义优先。通常建议:
- 把你愿意提交到仓库的共享 MCP 配置放在 `.mcp.json`
- 把仅本机使用、不希望共享的 MCP 配置放在 `.gsd/mcp.json`
### 支持的 transport
| Transport | 配置形状 | 适用场景 |
|-----------|----------|----------|
| `stdio` | `command` + 可选 `args``env``cwd` | 启动本地 MCP server 进程 |
| `http` | `url` | 连接到已经运行中的 MCP server |
### 示例stdio server
```json
{
"mcpServers": {
"my-server": {
"type": "stdio",
"command": "/absolute/path/to/python3",
"args": ["/absolute/path/to/server.py"],
"env": {
"API_URL": "http://localhost:8000"
}
}
}
}
```
### 示例HTTP server
```json
{
"mcpServers": {
"my-http-server": {
"url": "http://localhost:8080/mcp"
}
}
}
```
### 验证一个 server
添加配置后,可以在 GSD 会话中这样验证:
```text
mcp_servers
mcp_discover(server="my-server")
mcp_call(server="my-server", tool="<tool_name>", args={...})
```
推荐验证顺序:
1. `mcp_servers`:确认 GSD 能看到配置文件并正确解析 server 条目
2. `mcp_discover`:确认 server 进程能启动,并能响应 `tools/list`
3. `mcp_call`:确认至少有一个真实 tool 可以成功调用
### 说明
- 尽量为本地可执行文件和脚本使用绝对路径
- 对于 `stdio` servers优先在 MCP 配置里显式设置需要的环境变量,而不是依赖交互式 shell profile
- GSD 和 `gsd-mcp-server` 都会自动加载保存在 `~/.gsd/agent/auth.json` 中的 model / tool keys因此 MCP 配置可以安全地通过 `${ENV_VAR}` 占位符引用这些值,而不必提交原始凭据
- 如果某个 server 是团队共享且适合提交到仓库,通常更适合放在 `.mcp.json`
- 如果某个 server 依赖本机路径、个人服务或本地 secrets更适合放在 `.gsd/mcp.json`
## 环境变量
| 变量 | 默认值 | 说明 |
|------|--------|------|
| `GSD_HOME` | `~/.gsd` | 全局 GSD 目录。除非单独覆盖否则其它路径都从这里派生。影响偏好、skills、sessions 以及项目状态。v2.39 |
| `GSD_PROJECT_ID` | (自动哈希) | 覆盖自动生成的项目身份哈希。这样项目状态会写入 `$GSD_HOME/projects/<GSD_PROJECT_ID>/`,而不是计算出的哈希目录。适用于 CI/CD 或多个克隆共享状态。v2.39 |
| `GSD_STATE_DIR` | `$GSD_HOME` | 项目状态根目录。控制 `projects/<repo-hash>/` 的创建位置。对项目状态的优先级高于 `GSD_HOME`。 |
| `GSD_CODING_AGENT_DIR` | `$GSD_HOME/agent` | agent 目录,包含托管资源、扩展和 auth。对 agent 相关路径的优先级高于 `GSD_HOME`。 |
| `GSD_ALLOWED_COMMAND_PREFIXES` | (内置列表) | 允许用于 `!command` 值解析的命令前缀,逗号分隔。会覆盖 settings.json 中的 `allowedCommandPrefixes`。见 [自定义模型:命令允许列表](custom-models.md#command-allowlist)。 |
| `GSD_FETCH_ALLOWED_URLS` | (无) | 对 `fetch_page` URL block 免检的 hostnames逗号分隔。会覆盖 settings.json 中的 `fetchAllowedUrls`。见 [URL Blocking](#url-blocking-fetch_page)。 |
## 全部设置
### `models`
按阶段选择 model。每个 key 都可以是一个 model 字符串,或者是带 fallbacks 的对象。
```yaml
models:
research: claude-sonnet-4-6
planning:
model: claude-opus-4-6
fallbacks:
- openrouter/z-ai/glm-5
execution: claude-sonnet-4-6
execution_simple: claude-haiku-4-5-20250414
completion: claude-sonnet-4-6
subagent: claude-sonnet-4-6
```
**阶段键:** `research``planning``execution``execution_simple``completion``subagent`
- `execution_simple`:用于被 [complexity router](./token-optimization.md#complexity-based-task-routing) 判断为 “simple” 的 task
- `subagent`:委派给 subagent 的 task 所使用的 modelscout、researcher、worker
- 指定 provider使用 `provider/model` 格式(例如 `bedrock/claude-sonnet-4-6`),或者在对象格式里额外写 `provider` 字段
- 省略某个 key 时,会使用当前 active model
### 自定义 Model 定义(`models.json`
你可以在 `~/.gsd/agent/models.json` 里定义自定义 models 和 providers。这允许你添加默认注册表里没有的 models适合自托管 endpointsOllama、vLLM、LM Studio、微调模型、代理或者刚发布的新 provider。
GSD 读取 `models.json` 的顺序如下:
1. `~/.gsd/agent/models.json`主位置GSD
2. `~/.pi/agent/models.json`回退位置Pi
3. 如果两者都不存在,则创建 `~/.gsd/agent/models.json`
**本地 modelsOllama的快速示例**
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"models": [
{ "id": "llama3.1:8b" },
{ "id": "qwen2.5-coder:7b" }
]
}
}
}
```
每次打开 `/model` 时,这个文件都会重新加载,无需重启。
关于 provider 配置、model overrides、OpenAI compatibility 和更多高级示例,见 [自定义模型指南](./custom-models.md)。
**带 fallbacks 的示例:**
```yaml
models:
planning:
model: claude-opus-4-6
fallbacks:
- openrouter/z-ai/glm-5
- openrouter/moonshotai/kimi-k2.5
provider: bedrock # 可选:固定到某个 provider
```
当某个 model 切换失败provider 不可用、被限流、额度耗尽GSD 会自动尝试 `fallbacks` 列表中的下一个 model。
### Community Provider Extensions
对于 GSD 未内置的 providers社区扩展可以添加完整 provider 支持,包括正确的 model 定义、thinking format 配置以及交互式 API key 设置。
| 扩展 | Provider | Models | 安装命令 |
|------|----------|--------|----------|
| [`pi-dashscope`](https://www.npmjs.com/package/pi-dashscope) | Alibaba DashScopeModelStudio | Qwen3、GLM-5、MiniMax M2.5、Kimi K2.5 | `gsd install npm:pi-dashscope` |
对于 DashScope models更推荐使用社区扩展而不是内置的 `alibaba-coding-plan` provider因为前者会走正确的 OpenAI-compatible endpoint并包含适配 thinking mode 的 per-model compatibility flags。
### `token_profile`
负责协调 model 选择、阶段跳过和上下文压缩。详见 [Token 优化](./token-optimization.md)。
可选值:`budget``balanced`(默认)、`quality`
| 配置 | 行为 |
|------|------|
| `budget` | 跳过 research + reassessment 阶段,优先使用便宜模型 |
| `balanced` | 默认行为:所有阶段运行,使用标准模型选择 |
| `quality` | 所有阶段运行,优先更高质量模型 |
### `phases`
对自动模式中哪些阶段运行做细粒度控制:
```yaml
phases:
skip_research: false # 跳过 milestone 级 research
skip_reassess: false # 在每个 slice 后跳过 roadmap reassessment
skip_slice_research: true # 跳过每个 slice 的 research
reassess_after_slice: true # 每个 slice 后执行 roadmap reassessmentreassessment 的前提)
require_slice_discussion: false # 每个 slice 前暂停,等待讨论
```
这些值通常由 `token_profile` 自动设置,但也可以显式覆盖。
> **注意:** Roadmap reassessment 需要显式设置 `reassess_after_slice: true`。如果没有它,无论 `skip_reassess` 怎么配reassessment 都不会运行。
### `skill_discovery`
控制 GSD 在自动模式中如何发现并应用 skills。
| 值 | 行为 |
|----|------|
| `auto` | 自动查找并应用 skills |
| `suggest` | 在 research 阶段识别到 skills但不自动安装默认 |
| `off` | 关闭 skill discovery |
### `auto_supervisor`
自动模式监督器使用的超时阈值:
```yaml
auto_supervisor:
model: claude-sonnet-4-6 # 可选supervisor 使用的 model默认当前 active model
soft_timeout_minutes: 20 # 提醒 LLM 收尾
idle_timeout_minutes: 10 # 检测停滞
hard_timeout_minutes: 30 # 暂停自动模式
```
### `budget_ceiling`
自动模式期间允许消耗的最大美元金额。不需要 `$`,直接填数字:
```yaml
budget_ceiling: 50.00
```
### `budget_enforcement`
预算上限的执行方式:
| 值 | 行为 |
|----|------|
| `warn` | 记录警告,但继续运行 |
| `pause` | 暂停自动模式(设置 ceiling 时的默认值) |
| `halt` | 彻底停止自动模式 |
### `context_pause_threshold`
上下文窗口使用率达到多少0-100自动模式会暂停并进行 checkpoint。设为 `0` 可关闭。
```yaml
context_pause_threshold: 80 # 在上下文使用达到 80% 时暂停
```
默认值:`0`(关闭)
### `uat_dispatch`
在 slice 完成后自动运行 UATUser Acceptance Test
```yaml
uat_dispatch: true
```
### Verificationv2.26
配置在每次 task 执行后自动运行的 shell 命令。若失败,会先尝试自动修复重试,再决定是否继续。
```yaml
verification_commands:
- npm run lint
- npm run test
verification_auto_fix: true # 失败时自动重试修复默认true
verification_max_retries: 2 # 最大重试次数默认2
```
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `verification_commands` | string[] | `[]` | task 执行后要运行的 shell 命令 |
| `verification_auto_fix` | boolean | `true` | verification 失败时是否自动重试 |
| `verification_max_retries` | number | `2` | 自动修复重试的最大次数 |
<a id="url-blocking-fetch_page"></a>
### URL Blocking`fetch_page`
`fetch_page` 工具默认会阻止访问私有网络和内部网络地址,以防 SSRFserver-side request forgery。这能防止 agent 被诱导去访问内部服务、云 metadata endpoint 或本地文件。
**默认会被拦截:**
| 类别 | 示例 |
|------|------|
| 私有 IP 段 | `10.x.x.x``172.16-31.x.x``192.168.x.x``127.x.x.x` |
| Link-local / 云 metadata | `169.254.x.x`AWS/GCP instance metadata |
| 云 metadata hostname | `metadata.google.internal``instance-data` |
| Localhost | `localhost`(任意端口) |
| 非 HTTP 协议 | `file://``ftp://` |
| IPv6 私有地址段 | `::1``fc00:``fd``fe80:` |
公共 URL例如 `https://example.com``http://8.8.8.8`)不受影响。
**允许特定内部主机:**
如果你确实需要 agent 访问内网 URL例如自托管文档、VPN 后的内部 API可以在全局设置 `~/.gsd/agent/settings.json` 中添加 `fetchAllowedUrls`
```json
{
"fetchAllowedUrls": ["internal-docs.company.com", "192.168.1.50"]
}
```
或者设置 `GSD_FETCH_ALLOWED_URLS` 环境变量(逗号分隔)。环境变量优先级高于 settings.json
```bash
export GSD_FETCH_ALLOWED_URLS="internal-docs.company.com,192.168.1.50"
```
被允许的 hostname 会绕过 blocklist 检查。但协议限制依然有效,也就是说 `file://``ftp://` 仍然不能加入 allowlist。
> **注意:** 这是一个仅全局生效的设置。项目级 settings.json 不能覆盖 URL allowlist以防克隆下来的仓库把 `fetch_page` 指向内部基础设施。
### `auto_report`v2.26
在 milestone 完成后自动生成 HTML 报告:
```yaml
auto_report: true # 默认true
```
报告会以自包含 HTML 文件的形式写入 `.gsd/reports/`,所有 CSS / JS 都内嵌。
### `unique_milestone_ids`
为 milestone IDs 添加随机后缀,以避免团队协作中的 ID 冲突:
```yaml
unique_milestone_ids: true
# 输出示例M001-eh88as而不是 M001
```
### `git`
Git 行为配置。所有字段都是可选的:
```yaml
git:
auto_push: false # 提交后推送到远程
push_branches: false # 推送 milestone 分支到远程
remote: origin # git remote 名称
snapshots: true # 长 task 执行期间做 WIP snapshot commits
pre_merge_check: auto # worktree merge 前执行检查true / false / "auto"
commit_type: feat # 覆盖 conventional commit 前缀
main_branch: main # 主分支名称
merge_strategy: squash # worktree 分支合并方式:"squash" 或 "merge"
isolation: worktree # git isolation"worktree"、"branch" 或 "none"
commit_docs: true # 是否把 .gsd/ 产物提交到 git设为 false 时仅保留本地)
manage_gitignore: true # 设为 false 时GSD 不再修改 .gitignore
worktree_post_create: .gsd/hooks/post-worktree-create # worktree 创建后执行的脚本
auto_pr: false # milestone 完成时自动创建 PR要求 push_branches
pr_target_branch: develop # 自动创建 PR 的目标分支默认main branch
```
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `auto_push` | boolean | `false` | 提交后推送到远程 |
| `push_branches` | boolean | `false` | 把 milestone 分支推送到远程 |
| `remote` | string | `"origin"` | Git remote 名称 |
| `snapshots` | boolean | `true` | 长 task 期间做 WIP snapshot commits |
| `pre_merge_check` | bool/string | `"auto"` | merge 前是否执行检查(`true` / `false` / `"auto"` |
| `commit_type` | string | (自动推断) | 覆盖 conventional commit 前缀(`feat``fix``refactor``docs``test``chore``perf``ci``build``style` |
| `main_branch` | string | `"main"` | 主分支名称 |
| `merge_strategy` | string | `"squash"` | worktree 分支合并方式:`"squash"`(合并为单个提交)或 `"merge"`(保留单独提交) |
| `isolation` | string | `"worktree"` | 自动模式隔离方式:`"worktree"`(独立目录)、`"branch"`(直接在项目根目录工作,适合子模块多的仓库)、`"none"`(无隔离,直接提交到当前分支) |
| `commit_docs` | boolean | `true` | 是否把 `.gsd/` planning 产物提交到 git。设为 `false` 则仅保留本地 |
| `manage_gitignore` | boolean | `true` | 设为 `false`GSD 将完全不修改 `.gitignore`,不会添加基础规则,也不会做自愈 |
| `worktree_post_create` | string | (无) | worktree 创建后执行的脚本。环境变量中会传入 `SOURCE_DIR``WORKTREE_DIR` |
| `auto_pr` | boolean | `false` | milestone 完成时自动创建 pull request。要求 `auto_push: true` 且已安装认证 `gh` CLI |
| `pr_target_branch` | string | main branch | 自动创建 PR 的目标分支,例如 `develop``qa`。未设置时默认回退到 `main_branch` |
#### `git.worktree_post_create`
在 worktree 创建后执行脚本(自动模式和手动 `/worktree` 都适用)。适合复制 `.env`、建立资源目录软链,或者执行那些 worktree 不会继承的 setup 步骤。
```yaml
git:
worktree_post_create: .gsd/hooks/post-worktree-create
```
脚本会收到两个环境变量:
- `SOURCE_DIR`:原始项目根目录
- `WORKTREE_DIR`:新创建的 worktree 路径
示例 hook`.gsd/hooks/post-worktree-create`
```bash
#!/bin/bash
# Copy environment files and symlink assets into the new worktree
cp "$SOURCE_DIR/.env" "$WORKTREE_DIR/.env"
cp "$SOURCE_DIR/.env.local" "$WORKTREE_DIR/.env.local" 2>/dev/null || true
ln -sf "$SOURCE_DIR/assets" "$WORKTREE_DIR/assets"
```
路径既可以是绝对路径,也可以相对项目根目录。脚本有 30 秒超时限制。失败不会中断流程GSD 会记录告警后继续。
<a id="gitauto_pr"></a>
#### `git.auto_pr`
在 milestone 完成时自动创建 pull request。适用于 Gitflow 或分支工作流团队,在合并到目标分支前通过 PR 做审查。
```yaml
git:
auto_push: true
auto_pr: true
pr_target_branch: develop # 或 qa、staging 等
```
**要求:**
- `auto_push: true`:创建 PR 前必须先把 milestone 分支推送到远程
- 已安装并认证 [`gh` CLI](https://cli.github.com/)`gh auth login`
**工作方式:**
1. milestone 完成后GSD 先把 worktree squash merge 回主分支
2. 如果 `auto_push: true`,把主分支推送到远程
3. 把 milestone 分支推送到远程
4. 通过 `gh pr create` 从 milestone 分支向 `pr_target_branch` 创建 PR
如果没有设置 `pr_target_branch`PR 会默认指向 `main_branch`或者自动检测出的主分支。PR 创建失败不会中断流程GSD 会记录日志后继续。
### `github`v2.39
GitHub 同步配置。启用后GSD 会自动把 milestones、slices 和 tasks 同步到 GitHub Issues、PRs 和 Milestones。
```yaml
github:
enabled: true
repo: "owner/repo" # 省略时从 git remote 自动检测
labels: [gsd, auto-generated] # 应用到创建出的 issues / PRs 的标签
project: "Project ID" # 可选的 GitHub Project board
```
| 字段 | 类型 | 默认值 | 说明 |
|------|------|--------|------|
| `enabled` | boolean | `false` | 是否启用 GitHub 同步 |
| `repo` | string | (自动检测) | `owner/repo` 格式的 GitHub 仓库名 |
| `labels` | string[] | `[]` | 创建的 issues / PRs 要附加的标签 |
| `project` | string | (无) | GitHub Project ID用于接入 Project board |
**要求:**
- 已安装并认证 `gh` CLI`gh auth login`
- 同步映射会保存在 `.gsd/.github-sync.json`
- 具备速率限制感知:当 GitHub API rate limit 偏低时会跳过同步
**命令:**
- `/github-sync bootstrap`:初始化配置并执行同步
- `/github-sync status`:显示同步映射数量
### `notifications`
控制 GSD 在自动模式中发出哪些通知:
```yaml
notifications:
enabled: true
on_complete: true # 单元完成时通知
on_error: true # 出错时通知
on_budget: true # 预算阈值通知
on_milestone: true # milestone 完成时通知
on_attention: true # 需要人工介入时通知
```
**macOS 通知方式:** GSD 会优先使用 [`terminal-notifier`](https://github.com/julienXX/terminal-notifier),不可用时回退到 `osascript`。建议安装 `terminal-notifier`,获得更稳定的通知体验:
```bash
brew install terminal-notifier
```
原因:`osascript display notification` 的通知权限是算在你的终端应用Ghostty、iTerm2 等)上的,而这些应用在 System Settings → Notifications 中未必被允许。`terminal-notifier` 会注册成独立 App并在首次使用时主动请求通知权限。如果通知异常见 [故障排查macOS 上通知不显示](troubleshooting.md#notifications-not-appearing-on-macos)。
### `remote_questions`
把交互式问题路由到 Slack 或 Discord以支持 headless 自动模式:
```yaml
remote_questions:
channel: slack # 或 discord
channel_id: "C1234567890"
timeout_minutes: 15 # 问题超时1-30 分钟)
poll_interval_seconds: 10 # 轮询间隔2-30 秒)
```
### `post_unit_hooks`
在特定单元完成后触发的自定义 hooks
```yaml
post_unit_hooks:
- name: code-review
after: [execute-task]
prompt: "Review the code changes for quality and security issues."
model: claude-opus-4-6 # 可选:覆盖 model
max_cycles: 1 # 每次触发最多执行几轮1-10默认 1
artifact: REVIEW.md # 可选:若该文件已存在则跳过
retry_on: NEEDS-REWORK.md # 可选:若生成该文件,则回退并重跑触发单元
agent: review-agent # 可选:指定使用哪个 agent 定义
enabled: true # 可选:保留配置但临时禁用
```
`after` 可识别的 unit types 包括:`research-milestone``plan-milestone``research-slice``plan-slice``execute-task``complete-slice``replan-slice``reassess-roadmap``run-uat`
**Prompt 占位符:** `{milestoneId}``{sliceId}``{taskId}` 会自动替换成当前上下文值。
### `pre_dispatch_hooks`
在 dispatch 前拦截某个单元。支持三种动作:
**Modify**:在单元 prompt 前后拼接文本
```yaml
pre_dispatch_hooks:
- name: add-standards
before: [execute-task]
action: modify
prepend: "Follow our coding standards document."
append: "Run linting after changes."
```
**Skip**:完全跳过该单元
```yaml
pre_dispatch_hooks:
- name: skip-research
before: [research-slice]
action: skip
skip_if: RESEARCH.md # 可选:仅当该文件存在时才跳过
```
**Replace**:完全替换该单元 prompt
```yaml
pre_dispatch_hooks:
- name: custom-execute
before: [execute-task]
action: replace
prompt: "Execute the task using TDD methodology."
unit_type: execute-task-tdd # 可选:覆盖 unit type 标签
model: claude-opus-4-6 # 可选:覆盖 model
```
所有 pre-dispatch hooks 都支持 `enabled: true/false`,用于开关而不删除配置。
### `always_use_skills` / `prefer_skills` / `avoid_skills`
Skill 路由偏好:
```yaml
always_use_skills:
- debug-like-expert
prefer_skills:
- frontend-design
avoid_skills: []
```
Skills 既可以写裸名称(去 `~/.agents/skills/``.agents/skills/` 查找),也可以写绝对路径。
### `skill_rules`
基于人类可读触发条件的情景化 skill 路由:
```yaml
skill_rules:
- when: task involves authentication
use: [clerk]
- when: frontend styling work
prefer: [frontend-design]
- when: working with legacy code
avoid: [aggressive-refactor]
```
### `custom_instructions`
附加到每个会话上的持久指令:
```yaml
custom_instructions:
- "Always use TypeScript strict mode"
- "Prefer functional patterns over classes"
```
如果是项目特有知识(模式、坑点、经验),请优先放到 `.gsd/KNOWLEDGE.md` 中,因为它会自动注入每个 agent prompt。你也可以通过 `/gsd knowledge rule|pattern|lesson <description>` 添加。
### `RUNTIME.md`运行时上下文v2.39
你可以在 `.gsd/RUNTIME.md` 中声明项目级运行时上下文。这个文件会内联进 task execution prompt让 agent 能准确知道运行环境,而不必靠猜测路径或 URL。
**位置:** `.gsd/RUNTIME.md`
**示例:**
```markdown
# Runtime Context
## API Endpoints
- Main API: https://api.example.com
- Cache: redis://localhost:6379
## Environment Variables
- DEPLOYMENT_ENV: staging
- DB_POOL_SIZE: 20
## Local Services
- PostgreSQL: localhost:5432
- Redis: localhost:6379
```
适合放在这里的信息,是那些执行时需要知道、但又不属于 `DECISIONS.md`(架构)或 `KNOWLEDGE.md`(规则 / 模式的内容。典型例子包括API base URL、服务端口、部署目标以及环境特有配置。
### `dynamic_routing`
基于复杂度的 model 路由。详见 [动态模型路由](./dynamic-model-routing.md)。
```yaml
dynamic_routing:
enabled: true
capability_routing: true # 按 task capability 评分 modelsv2.59
tier_models:
light: claude-haiku-4-5
standard: claude-sonnet-4-6
heavy: claude-opus-4-6
escalate_on_failure: true
budget_pressure: true
cross_provider: true
```
### `context_management`v2.59
控制自动模式会话中的 observation masking 和 tool result truncation。可在不增加 LLM 开销的前提下,减少 compaction 之间的上下文膨胀。
```yaml
context_management:
observation_masking: true # 用占位符替换旧 tool result默认true
observation_mask_turns: 8 # 保留最近 N 个 user turn 的结果1-50默认8
compaction_threshold_percent: 0.70 # 在 70% 上下文使用率处触发 compaction0.5-0.95默认0.70
tool_result_max_chars: 800 # 单个 tool result 的最大字符数200-10000默认800
```
### `service_tier`v2.42
OpenAI 支持模型的 service tier 偏好。可通过 `/gsd fast` 切换。
| 值 | 行为 |
|----|------|
| `"priority"` | Priority tier2 倍成本,更快响应 |
| `"flex"` | Flex tier0.5 倍成本,更慢响应 |
| (未设置) | 默认 tier |
```yaml
service_tier: priority
```
### `forensics_dedup`v2.43
可选启用:在 `/gsd forensics` 提交 issue 之前,先搜索现有 issues 和 PRs。会额外消耗一些 AI tokens。
```yaml
forensics_dedup: true # 默认false
```
### `show_token_cost`v2.44
可选启用:在 footer 中显示每次 prompt 和累计会话的 token 成本。
```yaml
show_token_cost: true # 默认false
```
### `auto_visualize`
在 milestone 完成后自动显示工作流可视化器:
```yaml
auto_visualize: true
```
详见 [工作流可视化器](./visualizer.md)。
### `parallel`
同时运行多个 milestones。默认关闭。
```yaml
parallel:
enabled: false # 总开关
max_workers: 2 # 并发 workers 数1-4
budget_ceiling: 50.00 # 聚合成本上限(美元)
merge_strategy: "per-milestone" # "per-slice" 或 "per-milestone"
auto_merge: "confirm" # "auto"、"confirm" 或 "manual"
```
完整细节见 [并行编排](./parallel-orchestration.md)。
## 完整示例
```yaml
---
version: 1
# Model selection
models:
research: openrouter/deepseek/deepseek-r1
planning:
model: claude-opus-4-6
fallbacks:
- openrouter/z-ai/glm-5
execution: claude-sonnet-4-6
execution_simple: claude-haiku-4-5-20250414
completion: claude-sonnet-4-6
# Token optimization
token_profile: balanced
# Dynamic model routing
dynamic_routing:
enabled: true
escalate_on_failure: true
budget_pressure: true
# Budget
budget_ceiling: 25.00
budget_enforcement: pause
context_pause_threshold: 80
# Supervision
auto_supervisor:
soft_timeout_minutes: 15
hard_timeout_minutes: 25
# Git
git:
auto_push: true
merge_strategy: squash
isolation: worktree # "worktree", "branch", or "none"
commit_docs: true
# Skills
skill_discovery: suggest
skill_staleness_days: 60 # Skills unused for N days get deprioritized (0 = disabled)
always_use_skills:
- debug-like-expert
skill_rules:
- when: task involves authentication
use: [clerk]
# Notifications
notifications:
on_complete: false
on_milestone: true
on_attention: true
# Visualizer
auto_visualize: true
# Service tier
service_tier: priority # "priority" or "flex" (for /gsd fast)
# Diagnostics
forensics_dedup: true # deduplicate before filing forensics issues
show_token_cost: true # show per-prompt cost in footer
# Hooks
post_unit_hooks:
- name: code-review
after: [execute-task]
prompt: "Review {sliceId}/{taskId} for quality and security."
artifact: REVIEW.md
---
```

View file

@ -0,0 +1,94 @@
# 成本管理
GSD 会跟踪自动模式中每个派发工作单元的 Token 使用量和成本。这些数据会驱动仪表板、预算约束以及成本预测。
## 成本跟踪
每个工作单元的指标都会被自动记录:
- **Token 数量**input、output、cache read、cache write、total
- **成本**:每个单元的美元成本
- **耗时**:真实墙钟时间
- **工具调用数**:工具调用次数
- **消息数量**assistant 与 user 消息数
数据保存在 `.gsd/metrics.json` 中,并且可跨会话持续存在。
### 查看成本
**仪表板**:按 `Ctrl+Alt+G` 或执行 `/gsd status` 可查看实时成本拆分。
**可用聚合维度:**
- 按阶段research、planning、execution、completion、reassessment
- 按 sliceM001/S01、M001/S02 等)
- 按模型(哪些模型最耗预算)
- 项目总计
## 预算上限
可以为单个项目设置最大支出:
```yaml
---
version: 1
budget_ceiling: 50.00
---
```
### 执行模式
控制触达预算上限后会发生什么:
```yaml
budget_enforcement: pause # 设置 ceiling 后的默认值
```
| 模式 | 行为 |
|------|------|
| `warn` | 记录警告,但继续执行 |
| `pause` | 暂停自动模式,等待用户动作 |
| `halt` | 直接停止自动模式 |
## 成本预测
当至少完成两个 slices 后GSD 会预测剩余成本:
```
Projected remaining: $12.40 ($6.20/slice avg × 2 remaining)
```
预测基于已完成工作的每-slice 平均成本。如果预算上限已触达,结果中还会附带一条警告。
## 预算压力与模型降级
当预算接近上限时,[复杂度路由器](./token-optimization.md#budget-pressure)会自动把模型分配降到更便宜的层级。这是一个渐进过程:
- **已使用 < 50%**:不调整
- **已使用 50-75%**standard task 降为 light
- **已使用 75-90%**:同样降级,但更激进
- **已使用 > 90%**:几乎所有 task 都降级,只有 heavy task 仍保留在 standard
这样可以把预算尽量均匀地分摊到剩余工作中,而不是过早在几个复杂 task 上耗尽。
## Token 配置与成本
`token_profile` 偏好会直接影响成本:
| 配置 | 常见节省幅度 | 方式 |
|------|--------------|------|
| `budget` | 40-60% | 更便宜的模型、跳过部分阶段、最小上下文 |
| `balanced` | 10-20% | 默认模型、跳过 slice research、标准上下文 |
| `quality` | 0%(基线) | 完整模型、完整阶段、完整上下文 |
更多细节见 [Token 优化](./token-optimization.md)。
## 建议
- 先用 `balanced` 配置,并设置一个较宽松的 `budget_ceiling` 来建立成本基线
- 完成几个 slices 后查看 `/gsd status`,确认每个 slice 的平均成本
- 对于已知流程、重复性高的工作,切换到 `budget` 配置
- 只有在做架构决策时才建议使用 `quality`
- 可以通过按阶段选模型,只在 planning 使用 Opus而在 execution 保持 Sonnet
- 开启 `dynamic_routing`,让简单 task 自动下沉到更便宜的模型,详见 [动态模型路由](./dynamic-model-routing.md)
- 使用 `/gsd visualize` 的 Metrics 标签页查看预算具体花在了哪里

View file

@ -0,0 +1,378 @@
# 自定义模型
通过 `~/.gsd/agent/models.json` 添加自定义 providers 和 modelsOllama、vLLM、LM Studio、代理等
## 目录
- [最小示例](#minimal-example)
- [完整示例](#full-example)
- [支持的 API](#supported-apis)
- [Provider 配置](#provider-configuration)
- [Model 配置](#model-configuration)
- [覆盖内置 Providers](#overriding-built-in-providers)
- [按 model 覆盖](#per-model-overrides)
- [OpenAI 兼容性](#openai-compatibility)
<a id="minimal-example"></a>
## 最小示例
对于本地 modelsOllama、LM Studio、vLLM每个 model 只要求提供 `id`
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"models": [
{ "id": "llama3.1:8b" },
{ "id": "qwen2.5-coder:7b" }
]
}
}
}
```
`apiKey` 在 schema 中是必填,但 Ollama 会忽略它,因此任意值都可以。
有些 OpenAI-compatible server 不支持推理模型使用的 `developer` role。对于这类 provider需要把 `compat.supportsDeveloperRole` 设为 `false`,这样 GSD 会改用 `system` message 发送 system prompt。如果该 server 同时也不支持 `reasoning_effort`,还应把 `compat.supportsReasoningEffort` 也设为 `false`
你可以在 provider 级别设置 `compat`,让它应用到该 provider 下的所有 models也可以在 model 级别单独覆盖某个 model。这个设置常见于 Ollama、vLLM、SGLang 以及类似的 OpenAI-compatible server。
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
},
"models": [
{
"id": "gpt-oss:20b",
"reasoning": true
}
]
}
}
}
```
<a id="full-example"></a>
## 完整示例
当你需要显式覆盖默认值时,可以写成更完整的配置:
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"models": [
{
"id": "llama3.1:8b",
"name": "Llama 3.1 8B (Local)",
"reasoning": false,
"input": ["text"],
"contextWindow": 128000,
"maxTokens": 32000,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}
```
每次打开 `/model` 时,这个文件都会重新加载。可以在会话过程中直接编辑,无需重启。
<a id="supported-apis"></a>
## 支持的 API
| API | 说明 |
|-----|------|
| `openai-completions` | OpenAI Chat Completions兼容性最好 |
| `openai-responses` | OpenAI Responses API |
| `anthropic-messages` | Anthropic Messages API |
| `google-generative-ai` | Google Generative AI |
`api` 可以设置在 provider 级别(作为该 provider 下所有 models 的默认值),也可以设置在 model 级别(覆盖单个 model
<a id="provider-configuration"></a>
## Provider 配置
| 字段 | 说明 |
|------|------|
| `baseUrl` | API endpoint URL |
| `api` | API 类型(见上) |
| `apiKey` | API key见下方值解析 |
| `headers` | 自定义请求头(见下方值解析) |
| `authHeader` | 设为 `true` 时,自动添加 `Authorization: Bearer <apiKey>` |
| `models` | model 配置数组 |
| `modelOverrides` | 针对该 provider 的内置 models 做按 model 覆盖 |
<a id="value-resolution"></a>
### 值解析
`apiKey``headers` 支持三种写法:
- **Shell 命令:** `"!command"`,执行后读取 stdout
```json
"apiKey": "!security find-generic-password -ws 'anthropic'"
"apiKey": "!op read 'op://vault/item/credential'"
```
- **环境变量:** 取对应环境变量的值
```json
"apiKey": "MY_API_KEY"
```
- **字面量:** 直接使用
```json
"apiKey": "sk-..."
```
<a id="command-allowlist"></a>
#### 命令允许列表
Shell 命令(`!command`)只能执行一组已知的凭据工具。只有以下前缀开头的命令才会被允许:
`pass``op``aws``gcloud``vault``security``gpg``bw``gopass``lpass`
不在列表中的命令会被阻止,最终该值会解析为 `undefined`。同时会向 stderr 输出一条警告。
为了防止注入,命令参数中的 shell 操作符(`;``|``&`、`` ` ``、`$`、`>`、`<`)同样会被阻止。
**自定义允许列表:**
如果你使用的凭据工具不在默认列表中,可以在全局设置(`~/.gsd/agent/settings.json`)里覆盖:
```json
{
"allowedCommandPrefixes": ["pass", "op", "sops", "doppler", "mycli"]
}
```
这会完全替换默认列表,因此如果你还想保留默认命令,需要一起写进去。
你也可以设置 `GSD_ALLOWED_COMMAND_PREFIXES` 环境变量(逗号分隔)。环境变量优先级高于 settings.json
```bash
export GSD_ALLOWED_COMMAND_PREFIXES="pass,op,sops,doppler"
```
> **注意:** 这是一个仅全局生效的设置。项目级 settings.json`<project>/.gsd/settings.json`)不能覆盖命令 allowlist以防克隆下来的仓库提升命令执行权限。
### 自定义 Headers
```json
{
"providers": {
"custom-proxy": {
"baseUrl": "https://proxy.example.com/v1",
"apiKey": "MY_API_KEY",
"api": "anthropic-messages",
"headers": {
"x-portkey-api-key": "PORTKEY_API_KEY",
"x-secret": "!op read 'op://vault/item/secret'"
},
"models": [...]
}
}
}
```
<a id="model-configuration"></a>
## Model 配置
| 字段 | 必填 | 默认值 | 说明 |
|------|------|--------|------|
| `id` | 是 | — | Model 标识符(会原样传给 API |
| `name` | 否 | `id` | 可读的 model 标签,用于匹配(例如 `--model` 模糊匹配)并显示在详情 / 状态文字里 |
| `api` | 否 | provider 的 `api` | 为这个 model 覆盖 provider 的 API 类型 |
| `reasoning` | 否 | `false` | 是否支持扩展 thinking |
| `input` | 否 | `["text"]` | 输入类型:`["text"]``["text", "image"]` |
| `contextWindow` | 否 | `128000` | 上下文窗口大小tokens |
| `maxTokens` | 否 | `16384` | 最大输出 tokens |
| `cost` | 否 | 全为 0 | `{"input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0}`(每百万 tokens |
| `compat` | 否 | provider 的 `compat` | OpenAI 兼容性覆盖项。如果 provider 和 model 两边都配置了,会合并 |
当前行为:
- `/model``--list-models` 都是按 model `id` 列出条目
- 配置里的 `name` 会用于 model 匹配,以及详情 / 状态文本展示
<a id="overriding-built-in-providers"></a>
## 覆盖内置 Providers
如果你想把某个内置 provider 经由代理路由出去,但又不想重新定义全部 models可以这样写
```json
{
"providers": {
"anthropic": {
"baseUrl": "https://my-proxy.example.com/v1"
}
}
}
```
这样所有内置 Anthropic models 仍然可用。已有的 OAuth 或 API key 认证也会继续生效。
如果你想把自定义 models 合并进某个内置 provider就同时提供 `models` 数组:
```json
{
"providers": {
"anthropic": {
"baseUrl": "https://my-proxy.example.com/v1",
"apiKey": "ANTHROPIC_API_KEY",
"api": "anthropic-messages",
"models": [...]
}
}
}
```
合并规则如下:
- 内置 models 会保留
- 自定义 models 会按 `id` 在该 provider 下执行 upsert
- 如果某个自定义 model 的 `id` 与内置 model 相同,自定义 model 会替换那个内置 model
- 如果某个自定义 model 的 `id` 是新的,它会作为新增条目并列出现
<a id="per-model-overrides"></a>
## 按 model 覆盖
如果你只想修改某些特定的内置 model而不想替换整个 provider 的 model 列表,可以使用 `modelOverrides`
```json
{
"providers": {
"openrouter": {
"modelOverrides": {
"anthropic/claude-sonnet-4": {
"name": "Claude Sonnet 4 (Bedrock Route)",
"compat": {
"openRouterRouting": {
"only": ["amazon-bedrock"]
}
}
}
}
}
}
}
```
`modelOverrides` 支持的字段包括:`name``reasoning``input``cost`(可部分覆盖)、`contextWindow``maxTokens``headers``compat`
行为说明:
- `modelOverrides` 只会应用到内置 provider 的 models 上
- 未知的 model ID 会被忽略
- 可以把 provider 级别的 `baseUrl` / `headers``modelOverrides` 组合使用
- 如果某个 provider 同时定义了 `models`,那么自定义 models 会在应用完内置覆盖后再合并;如果它的 `id` 与已覆盖的内置 model 相同,最终会以自定义 model 为准
<a id="openai-compatibility"></a>
## OpenAI 兼容性
对于只部分兼容 OpenAI 的 providers可通过 `compat` 字段修正行为。
- provider 级别的 `compat` 会作为该 provider 下所有 models 的默认值
- model 级别的 `compat` 会覆盖该 model 的 provider 级别设置
```json
{
"providers": {
"local-llm": {
"baseUrl": "http://localhost:8080/v1",
"api": "openai-completions",
"compat": {
"supportsUsageInStreaming": false,
"maxTokensField": "max_tokens"
},
"models": [...]
}
}
}
```
| 字段 | 说明 |
|------|------|
| `supportsStore` | Provider 是否支持 `store` 字段 |
| `supportsDeveloperRole` | 是否使用 `developer` 而非 `system` role |
| `supportsReasoningEffort` | 是否支持 `reasoning_effort` 参数 |
| `reasoningEffortMap` | 把 GSD 的 thinking levels 映射到 provider 专属 `reasoning_effort` 值 |
| `supportsUsageInStreaming` | 是否支持 `stream_options: { include_usage: true }`(默认 `true` |
| `maxTokensField` | 使用 `max_completion_tokens` 还是 `max_tokens` |
| `requiresToolResultName` | tool result message 中是否必须包含 `name` |
| `requiresAssistantAfterToolResult` | tool result 之后、user message 之前是否需要插入 assistant message |
| `requiresThinkingAsText` | 是否把 thinking block 转成纯文本 |
| `thinkingFormat` | 使用 `reasoning_effort``zai``qwen``qwen-chat-template` 的 thinking 参数格式 |
| `supportsStrictMode` | 是否在 tool definitions 中包含 `strict` 字段 |
| `openRouterRouting` | 传给 OpenRouter 的路由配置,用于 model/provider 选择 |
| `vercelGatewayRouting` | Vercel AI Gateway 的路由配置,用于 provider 选择(`only``order` |
`qwen` 使用顶层 `enable_thinking`。对于要求 `chat_template_kwargs.enable_thinking` 的本地 Qwen-compatible server请使用 `qwen-chat-template`
示例:
```json
{
"providers": {
"openrouter": {
"baseUrl": "https://openrouter.ai/api/v1",
"apiKey": "OPENROUTER_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "openrouter/anthropic/claude-3.5-sonnet",
"name": "OpenRouter Claude 3.5 Sonnet",
"compat": {
"openRouterRouting": {
"order": ["anthropic"],
"fallbacks": ["openai"]
}
}
}
]
}
}
}
```
Vercel AI Gateway 示例:
```json
{
"providers": {
"vercel-ai-gateway": {
"baseUrl": "https://ai-gateway.vercel.sh/v1",
"apiKey": "AI_GATEWAY_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "moonshotai/kimi-k2.5",
"name": "Kimi K2.5 (Fireworks via Vercel)",
"reasoning": true,
"input": ["text", "image"],
"cost": { "input": 0.6, "output": 3, "cacheRead": 0, "cacheWrite": 0 },
"contextWindow": 262144,
"maxTokens": 262144,
"compat": {
"vercelGatewayRouting": {
"only": ["fireworks", "novita"],
"order": ["fireworks", "novita"]
}
}
}
]
}
}
}
```

View file

@ -0,0 +1,287 @@
# 动态模型路由
*引入于 v2.19.0。Capability scoring 引入于 v2.52.0。*
动态模型路由会为简单工作自动选择更便宜的模型,并把昂贵模型留给复杂 task。这样在有成本上限的套餐下通常可以减少 20-50% 的 token 消耗,同时在关键位置保持质量。
从 v2.52.0 开始router 使用 **capability-aware scoring**,为每个 task 选择最合适的 model而不只是简单挑选该 tier 里最便宜的。
## 工作原理
自动模式派发的每个工作单元都会经过一个两阶段流水线:
**阶段 1复杂度分类**:先把工作划分到某个 tierlight / standard / heavy
**阶段 2能力评分**:在符合该 tier 的候选 models 里,根据它们的能力和 task 需求的匹配程度进行排序。
核心规则是:**只允许降级,不允许升级**。用户在偏好设置中配置的 model 始终是上限router 不会把它升级到比你配置更强的 model。
| Tier | 典型工作 | 默认模型级别 |
|------|----------|--------------|
| **Light** | slice completion、UAT、hooks | Haiku 级 |
| **Standard** | research、planning、execution、milestone completion | Sonnet 级 |
| **Heavy** | replan、roadmap reassessment、复杂 execution | Opus 级 |
## 启用方式
动态路由默认关闭。可在偏好设置中开启:
```yaml
---
version: 1
dynamic_routing:
enabled: true
---
```
## 配置
```yaml
dynamic_routing:
enabled: true
tier_models: # 可选:为每个 tier 显式指定 model
light: claude-haiku-4-5
standard: claude-sonnet-4-6
heavy: claude-opus-4-6
escalate_on_failure: true # task 失败时提升 tier默认true
budget_pressure: true # 接近预算上限时自动降级默认true
cross_provider: true # 可跨 provider 选择 model默认true
hooks: true # 是否对 post-unit hooks 也应用路由默认true
capability_routing: true # 在 tier 内启用 capability scoring默认true
```
### `tier_models`
覆盖每个 tier 默认使用的 model。如果省略router 会使用内置 capability mapping它已经知道一些常见 model 家族的大致定位:
- **Light** `claude-haiku-4-5``gpt-4o-mini``gemini-2.0-flash`
- **Standard** `claude-sonnet-4-6``gpt-4o``gemini-2.5-pro`
- **Heavy** `claude-opus-4-6``gpt-4.5-preview``gemini-2.5-pro`
### `escalate_on_failure`
当 task 在某个 tier 上失败时router 会在重试时提升到下一层Light → Standard → Heavy。这样可以避免便宜模型在其实需要更强推理能力的工作上浪费重试次数。
### `budget_pressure`
当预算接近上限时router 会逐步降低 tier
| 已使用预算 | 影响 |
|------------|------|
| < 50% | 不调整 |
| 50-75% | Standard → Light |
| 75-90% | 更激进地降级 |
| > 90% | 几乎所有工作都 → Light只有 Heavy 保持在 Standard |
### `cross_provider`
开启后router 可以从你的主 provider 之外选择 model。它会使用内置成本表在每个 tier 里找到最便宜的 model。要求目标 provider 已经正确配置。
### `capability_routing`
开启后默认truerouter 会通过 capability scoring 在某个 tier 内选出“最适合”的 model而不是永远只选最便宜的那个。设为 `false` 可恢复到纯 cheapest-in-tier 行为:
```yaml
dynamic_routing:
enabled: true
capability_routing: false # 关闭评分,改用 tier 内最便宜的 model
```
## Capability Profiles
每个 model 都有一个内置的 **capability profile**,它是一个 7 维评分0-100表示该 model 在不同 task 类型下的能力强弱:
| 维度 | 含义 |
|------|------|
| `coding` | 代码生成和实现准确性 |
| `debugging` | 诊断与修复错误的能力 |
| `research` | 信息综合与主题探索能力 |
| `reasoning` | 多步逻辑推理能力 |
| `speed` | 延迟与吞吐(可视为能力深度的反向维度) |
| `longContext` | 处理大代码库和长文档的能力 |
| `instruction` | 精确遵循结构化指令的能力 |
目前 9 个 models 带有内置 profile`claude-opus-4-6``claude-sonnet-4-6``claude-haiku-4-5``gpt-4o``gpt-4o-mini``gemini-2.5-pro``gemini-2.0-flash``deepseek-chat``o3`
没有内置 profile 的 models 会收到**全维度均为 50** 的默认分数。这是一个冷启动策略:未知模型可以参与竞争,但不会凭空占优。从用户角度看,这类模型的路由行为和 capability scoring 引入前保持一致。
**这些 profiles 是启发式排序,不是 benchmark。** 它们表达的是大致的相对优势,而不是经过严格验证的 benchmark 结果。如果你很了解某个 model可通过用户覆盖项见下文修正这些分值。
## 评分方式
tier 内的路由流程如下:
```
classify complexity tier
filter eligible models for tier
fire before_model_select hook (optional override)
capability score eligible models
select winner (or first eligible if scoring is disabled)
```
**评分公式:** 各能力维度的加权平均
```
score = Σ(weight × capability) / Σ(weights)
```
**Task requirements** 是动态的,不同 unit types 对维度的权重不同:
| Unit Type | 核心维度 |
|-----------|----------|
| `execute-task` | coding (0.9)、instruction (0.7)、speed (0.3) |
| `research-*` | research (0.9)、longContext (0.7)、reasoning (0.5) |
| `plan-*` | reasoning (0.9)、coding (0.5) |
| `replan-slice` | reasoning (0.9)、debugging (0.6)、coding (0.5) |
| `complete-slice``run-uat` | instruction (0.8)、speed (0.7) |
对于 `execute-task`router 还会进一步根据 task metadata 微调需求:
- 带有 `docs``config``readme` 等 tag提高 instruction 权重
- 包含 `concurrency``compatibility` 等关键词:提高 debugging 和 reasoning 权重
- 包含 `migration``architecture` 等关键词:提高 reasoning 和 coding 权重
- 文件数较多≥6或估计行数较大≥500提高 coding 和 reasoning 权重
**平分时的决策:** 当两个 models 的得分相差不超过 2 分时,优先选择更便宜的那个。如果成本也相同,则按 model ID 字典序打破平局(确定性结果)。
## 用户覆盖
如果你对某个 model 的能力认知比内置 profile 更准确,可以通过 `models` 配置里的 `modelOverrides` 修正:
```json
{
"providers": {
"anthropic": {
"modelOverrides": {
"claude-sonnet-4-6": {
"capabilities": {
"debugging": 90,
"research": 85
}
}
}
}
}
}
```
这些覆盖会与内置默认值进行**深度合并**:你只需覆盖指定维度,未指定的维度仍保留内置值。
**典型用法:** 如果你发现某个 model 在某一类工作上持续优于内置 profile就覆盖对应维度把 router 更积极地引导到该 model。
## 详细输出
开启 verbose mode 时router 会把自己的路由决策打印出来。如果使用了 capability scoring日志会包含完整评分拆分
```
Dynamic routing [S]: claude-sonnet-4-6 (capability-scored) — claude-sonnet-4-6: 82.3, gpt-4o: 78.1, deepseek-chat: 72.0
```
如果只使用了 tier 级路由(例如评分被禁用、只有一个符合条件的 model或命中了路由守卫
```
Dynamic routing [S]: claude-sonnet-4-6 (standard complexity, multiple steps)
```
路由决策中的 `selectionMethod` 字段会说明采用了哪种路径:
- `"capability-scored"`:使用 capability scoring 选出了最终 model
- `"tier-only"`:使用了 tier 内最便宜的 model或显式固定值
## 扩展 Hook
扩展可以通过 `before_model_select` hook 拦截并覆盖 model 选择。
Hook 触发时机在 **tier 过滤之后**(已知符合条件的 models但在 **capability scoring 之前**尚未计算分数。Hook 可以完全接管选择,也可以返回 `undefined`,让 scoring 按默认逻辑继续。
**注册处理器:**
```typescript
pi.on("before_model_select", async (event) => {
const { unitType, unitId, classification, taskMetadata, eligibleModels, phaseConfig } = event;
// 自定义路由策略research 一律优先用 gemini
if (unitType.startsWith("research-")) {
const gemini = eligibleModels.find(id => id.includes("gemini"));
if (gemini) return { modelId: gemini };
}
// 返回 undefined让 capability scoring 继续
return undefined;
});
```
**事件负载:**
| 字段 | 类型 | 说明 |
|------|------|------|
| `unitType` | `string` | 当前派发单元类型(例如 `"execute-task"` |
| `unitId` | `string` | 此次单元派发的唯一标识符 |
| `classification` | `{ tier, reason, downgraded }` | 复杂度分类结果 |
| `taskMetadata` | `Record<string, unknown> \| undefined` | 从单元 plan 中提取出的 task 元数据 |
| `eligibleModels` | `string[]` | 符合该 tier 的 models |
| `phaseConfig` | `{ primary, fallbacks } \| undefined` | 用户为该 phase 配置的 model |
**返回值:** `{ modelId: string }` 表示覆盖默认选择;返回 `undefined` 表示交给 capability scoring。
**第一个覆盖者生效:** 如果多个扩展都注册了处理器,第一个返回非 `undefined` 的处理器获胜,后续处理器不会再被调用。
## 复杂度分类
工作单元通过纯启发式规则分类,不涉及 LLM 调用,耗时通常低于 1ms。
### Unit Type 默认值
| Unit Type | 默认 Tier |
|-----------|-----------|
| `complete-slice``run-uat` | Light |
| `research-*``plan-*``complete-milestone` | Standard |
| `execute-task` | Standard可被 task 分析升级) |
| `replan-slice``reassess-roadmap` | Heavy |
| `hook/*` | Light |
### Task Plan 分析
对于 `execute-task` 单元,分类器会分析 task plan
| 信号 | 简单 → Light | 复杂 → Heavy |
|------|--------------|--------------|
| Step 数量 | ≤ 3 | ≥ 8 |
| 文件数 | ≤ 3 | ≥ 8 |
| 描述长度 | < 500 chars | > 2000 chars |
| 代码块数 | — | ≥ 5 |
| 复杂度关键词 | 无 | 有 |
**复杂度关键词:** `research``investigate``refactor``migrate``integrate``complex``architect``redesign``security``performance``concurrent``parallel``distributed``backward compat`
### 自适应学习
路由历史(`.gsd/routing-history.json`)会按 unit type 和 tier 记录成功 / 失败情况。如果某种模式下某个 tier 的失败率超过 20%,未来相似分类会自动上调一个 tier。用户反馈`over` / `under` / `ok`)的权重是自动结果的 2 倍。
## 与 Token Profile 的关系
动态路由和 token profile 是互补的:
- **Token profiles**`budget` / `balanced` / `quality`)控制阶段跳过和上下文压缩
- **Dynamic routing** 控制每个工作单元在对应 phase 内的 model 选择
两者同时开启时token profile 负责给出基础模型集dynamic routing 再在这些基础之上做进一步优化。`budget` token profile + dynamic routing 组合能带来最大的成本节省。
## 成本表
Router 内置了一张常见 models 的成本表,用于跨 provider 成本比较。成本单位都是每百万 tokensinput / output
| Model | Input | Output |
|-------|-------|--------|
| claude-haiku-4-5 | $0.80 | $4.00 |
| claude-sonnet-4-6 | $3.00 | $15.00 |
| claude-opus-4-6 | $15.00 | $75.00 |
| gpt-4o-mini | $0.15 | $0.60 |
| gpt-4o | $2.50 | $10.00 |
| gemini-2.0-flash | $0.10 | $0.40 |
这张成本表仅用于比较,实际计费仍然来自你所使用的 provider。

View file

@ -0,0 +1,473 @@
# GSD 快速开始
GSD 是一个 AI 编程代理,负责规划、执行、验证和交付,让你可以把注意力放在“要构建什么”上。本指南会带你完成 macOS、Windows 和 Linux 的安装,并启动你的第一个会话。
---
## 前置条件
| 要求 | 最低版本 | 推荐版本 |
|------|----------|----------|
| **[Node.js](https://nodejs.org/)** | 22.0.0 | 24 LTS |
| **[Git](https://git-scm.com/)** | 2.20+ | 最新版 |
| **LLM API key** | 任意受支持提供商 | AnthropicClaude |
如果你还没有安装 Node.js 或 Git请按下面对应操作系统的步骤进行。
---
## 按操作系统安装
### macOS
> **下载链接:** [Node.js](https://nodejs.org/) | [Git](https://git-scm.com/download/mac) | [Homebrew](https://brew.sh/)
**第 1 步:安装 Homebrew**(如果已安装可跳过):
```bash
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
```
**第 2 步:安装 Node.js 和 Git**
```bash
brew install node git
```
**第 3 步:验证依赖已安装:**
```bash
node --version # 应输出 v22.x 或更高
git --version # 应输出 2.20+
```
**第 4 步:安装 GSD**
```bash
npm install -g gsd-pi
```
**第 5 步:设置你的 LLM provider**
```bash
# 选项 A设置环境变量推荐 Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
# 选项 B使用内置配置向导
gsd config
```
如果想永久保存这个 key把 export 语句写入 `~/.zshrc`
```bash
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.zshrc
source ~/.zshrc
```
所有 20+ provider 的完整配置方式请见 [提供商设置指南](./providers.md)。
**第 6 步:启动 GSD**
```bash
cd ~/my-project # 进入任意项目目录
gsd # 启动一个会话
```
**第 7 步:确认一切正常:**
```bash
gsd --version # 输出已安装版本
```
进入会话后,输入 `/model` 以确认你的 LLM 已成功连接。
> **Apple Silicon PATH 修复:** 如果安装后找不到 `gsd`,可能是 npm 的全局 bin 目录没有加入 PATH
> ```bash
> echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.zshrc
> source ~/.zshrc
> ```
> **oh-my-zsh 冲突:** oh-my-zsh 的 git 插件定义了 `alias gsd='git svn dcommit'`。可在 `~/.zshrc` 中加入 `unalias gsd 2>/dev/null`,或者改用 `gsd-cli`
---
### Windows
> **下载链接:** [Node.js](https://nodejs.org/) | [Git for Windows](https://git-scm.com/download/win) | [Windows Terminal](https://aka.ms/terminal)
#### 选项 A使用 winget推荐 Windows 10/11
**第 1 步:安装 Node.js 和 Git**
```powershell
winget install OpenJS.NodeJS.LTS
winget install Git.Git
```
**第 2 步:重启终端**(关闭并重新打开 PowerShell 或 Windows Terminal
**第 3 步:验证依赖已安装:**
```powershell
node --version # 应输出 v22.x 或更高
git --version # 应输出 2.20+
```
**第 4 步:安装 GSD**
```powershell
npm install -g gsd-pi
```
**第 5 步:设置你的 LLM provider**
```powershell
# 选项 A设置环境变量仅当前会话
$env:ANTHROPIC_API_KEY = "sk-ant-..."
# 选项 B使用内置配置向导
gsd config
```
如果要永久保存该 key可在系统设置的环境变量中添加或者执行
```powershell
[System.Environment]::SetEnvironmentVariable("ANTHROPIC_API_KEY", "sk-ant-...", "User")
```
所有 20+ provider 的完整配置方式请见 [提供商设置指南](./providers.md)。
**第 6 步:启动 GSD**
```powershell
cd C:\Users\you\my-project # 进入任意项目目录
gsd # 启动一个会话
```
**第 7 步:确认一切正常:**
```powershell
gsd --version # 输出已安装版本
```
进入会话后,输入 `/model` 以确认你的 LLM 已成功连接。
#### 选项 B手动安装
1. 下载并安装 [Node.js LTS](https://nodejs.org/),安装时勾选 **“Add to PATH”**
2. 下载并安装 [Git for Windows](https://git-scm.com/download/win),使用默认选项
3. 打开一个**新的**终端,然后继续执行上面的第 3-7 步
> **Windows 提示:**
> - 建议使用 **Windows Terminal****PowerShell**体验最佳。Command Prompt 也能用,但颜色支持较弱。
> - 如果 `gsd` 无法识别先重启终端。Windows 需要新开终端才能读取更新后的 PATH。
> - **WSL2** 也可用,安装 WSL 后,在发行版内部按 Linux 说明继续。
---
### Linux
> **下载链接:** [Node.js](https://nodejs.org/) | [Git](https://git-scm.com/download/linux) | [nvm](https://github.com/nvm-sh/nvm)
先确认你的发行版,然后按对应步骤安装。
#### Ubuntu / Debian
**第 1 步:安装 Node.js 和 Git**
```bash
curl -fsSL https://deb.nodesource.com/setup_24.x | sudo -E bash -
sudo apt-get install -y nodejs git
```
#### Fedora / RHEL / CentOS
**第 1 步:安装 Node.js 和 Git**
```bash
curl -fsSL https://rpm.nodesource.com/setup_24.x | sudo bash -
sudo dnf install -y nodejs git
```
#### Arch Linux
**第 1 步:安装 Node.js 和 Git**
```bash
sudo pacman -S nodejs npm git
```
#### 使用 nvm任意发行版
**第 1 步:先安装 nvm再安装 Node.js**
```bash
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.0/install.sh | bash
source ~/.bashrc # 或 ~/.zshrc
nvm install 24
nvm use 24
```
#### 所有发行版:第 2-7 步
**第 2 步:验证依赖已安装:**
```bash
node --version # 应输出 v22.x 或更高
git --version # 应输出 2.20+
```
**第 3 步:安装 GSD**
```bash
npm install -g gsd-pi
```
**第 4 步:设置你的 LLM provider**
```bash
# 选项 A设置环境变量推荐 Anthropic
export ANTHROPIC_API_KEY="sk-ant-..."
# 选项 B使用内置配置向导
gsd config
```
如果想永久保存这个 key把 export 语句写到 `~/.bashrc`(或 `~/.zshrc`)中:
```bash
echo 'export ANTHROPIC_API_KEY="sk-ant-..."' >> ~/.bashrc
source ~/.bashrc
```
所有 20+ provider 的完整配置方式请见 [提供商设置指南](./providers.md)。
**第 5 步:启动 GSD**
```bash
cd ~/my-project # 进入任意项目目录
gsd # 启动一个会话
```
**第 6 步:确认一切正常:**
```bash
gsd --version # 输出已安装版本
```
进入会话后,输入 `/model` 以确认你的 LLM 已成功连接。
> **`npm install -g` 遇到权限错误?** 不要用 `sudo npm`。应改为修复 npm 的全局目录:
> ```bash
> mkdir -p ~/.npm-global
> npm config set prefix '~/.npm-global'
> echo 'export PATH="$HOME/.npm-global/bin:$PATH"' >> ~/.bashrc
> source ~/.bashrc
> npm install -g gsd-pi
> ```
---
### Docker任意操作系统
> **下载链接:** [Docker Desktop](https://www.docker.com/products/docker-desktop/)
如果你不想在宿主机安装 Node.js可以在隔离沙箱中运行 GSD。
**第 1 步:安装 Docker Desktop**(要求 4.58+)。
**第 2 步:克隆 GSD 仓库:**
```bash
git clone https://github.com/gsd-build/gsd-2.git
cd gsd-2/docker
```
**第 3 步:创建并进入沙箱:**
```bash
docker sandbox create --template . --name gsd-sandbox
docker sandbox exec -it gsd-sandbox bash
```
**第 4 步:设置 API key 并运行 GSD**
```bash
export ANTHROPIC_API_KEY="sk-ant-..."
gsd auto "implement the feature described in issue #42"
```
完整的配置、资源限制和 compose 文件请见 [Docker Sandbox 文档](../../../docker/README.md)。
---
## 安装之后
### 选择模型
完成 provider 设置后GSD 会自动选择一个默认模型。你可以在会话中随时切换:
```
/model
```
也可以在偏好设置中按阶段配置模型,详见 [配置](./configuration.md)。
---
## 两种工作方式
### 步骤模式 — `/gsd`
在会话内输入 `/gsd`。GSD 会一次执行一个工作单元,并在每一步之间暂停,通过向导展示刚完成了什么、下一步是什么。
- **没有 `.gsd/` 目录**:启动讨论流程,先收集你的项目愿景
- **已有 milestone但没有 roadmap**:讨论或研究该 milestone
- **roadmap 已存在,仍有待完成的 slices**:规划下一个 slice 或执行一个 task
- **进行到一半的 task**:从上次停下的地方继续
步骤模式会让你始终留在回路中,在每一步之间查看和确认输出。
### 自动模式 — `/gsd auto`
输入 `/gsd auto` 后就可以离开。GSD 会自主完成 research、planning、execution、verification、commit并持续推进每个 slice直到 milestone 完成。
```
/gsd auto
```
完整细节请见 [自动模式](./auto-mode.md)。
---
## 推荐工作流:两个终端
一个终端跑自动模式,另一个终端负责引导和干预。
**终端 1让它构建**
```bash
gsd
/gsd auto
```
**终端 2在它工作时进行引导**
```bash
gsd
/gsd discuss # 讨论架构决策
/gsd status # 查看进度
/gsd queue # 排队下一个 milestone
```
两个终端都会读写同一套 `.gsd/` 文件。你在终端 2 里做出的决策,会在下一个阶段边界被自动拾取。
---
## GSD 如何组织工作
```
Milestone → 一个可交付版本4-10 个 slice
Slice → 一个可演示的垂直能力1-7 个 task
Task → 一个适合单个上下文窗口的工作单元
```
铁律是:**一个 task 必须能装进一个上下文窗口。** 装不下,就说明它应该拆成两个 task。
所有状态都保存在 `.gsd/` 中:
```
.gsd/
PROJECT.md — 项目当前是什么
REQUIREMENTS.md — 需求契约
DECISIONS.md — 追加式架构决策记录
KNOWLEDGE.md — 跨会话规则与模式
STATE.md — 一眼可见的状态摘要
milestones/
M001/
M001-ROADMAP.md — 带依赖关系的 slice 计划
slices/
S01/
S01-PLAN.md — task 拆解
S01-SUMMARY.md — 实际发生了什么
```
---
## VS Code 扩展
GSD 也提供 VS Code 扩展。你可以从扩展市场安装publisher: FluxLabs或者在 VS Code 扩展面板中直接搜索 “GSD”
- **`@gsd` 聊天参与者**:在 VS Code Chat 中直接与 agent 对话
- **侧边栏仪表板**显示连接状态、模型信息、Token 使用量
- **完整命令面板**:启动 / 停止 agent、切换模型、导出会话
CLI`gsd-pi`)需要先安装好,扩展会通过 RPC 与其连接。
---
## Web 界面
GSD 也提供一个基于浏览器的可视化项目管理界面:
```bash
gsd --web
```
详见 [Web 界面](./web-interface.md)。
---
## 恢复会话
```bash
gsd --continue # 或 gsd -c
```
会恢复当前目录最近一次会话。
浏览所有保存过的会话:
```bash
gsd sessions
```
---
## 更新 GSD
GSD 每 24 小时检查一次更新,并在启动时提示。你也可以手动更新:
```bash
npm update -g gsd-pi
```
或者在会话中执行:
```
/gsd update
```
---
## 快速排障
| 问题 | 解决方式 |
|------|----------|
| `command not found: gsd` | 把 npm 全局 bin 目录加入 PATH见上面的系统说明 |
| `gsd` 实际执行了 `git svn dcommit` | oh-my-zsh 冲突,执行 `unalias gsd` 或改用 `gsd-cli` |
| `npm install -g gsd-pi` 权限错误 | 修复 npm prefix见 Linux 说明)或改用 nvm |
| 无法连接到 LLM | 用 `gsd config` 检查 API key并确认网络可用 |
| `gsd` 启动时卡住 | 检查 Node.js 版本:`node --version`(需要 22+ |
更多问题见 [故障排查](./troubleshooting.md)。
---
## 下一步
- [自动模式](./auto-mode.md):深入理解自主执行
- [配置](./configuration.md):模型选择、超时和预算
- [命令参考](./commands.md):所有命令和快捷键
- [提供商设置](./providers.md):每个 provider 的详细配置
- [团队协作](./working-in-teams.md):多开发者工作流

View file

@ -0,0 +1,186 @@
# Git 策略
GSD 使用 git 来实现 milestone 隔离,以及每个 milestone 内部的顺序提交。你可以通过 **isolation mode** 控制工作发生在哪里。整个策略是自动化的,你不需要手工管理分支。
## 隔离模式
GSD 支持三种隔离模式,通过 `git.isolation` 偏好设置:
| 模式 | 工作目录 | 分支 | 适用场景 |
|------|----------|------|----------|
| `worktree`(默认) | `.gsd/worktrees/<MID>/` | `milestone/<MID>` | 大多数项目milestones 之间文件完全隔离 |
| `branch` | 项目根目录 | `milestone/<MID>` | 子模块较多、worktree 表现不佳的仓库 |
| `none` | 项目根目录 | 当前分支(不建 milestone 分支) | 热重载工作流中,文件隔离会破坏开发工具的场景 |
### `worktree` 模式(默认)
每个 milestone 都会在 `.gsd/worktrees/<MID>/` 下拥有自己的 git worktree对应一个 `milestone/<MID>` 分支。所有执行都发生在该 worktree 中。完成后worktree 会被 squash merge 回主分支,形成一个干净的提交,然后清理对应 worktree 和分支。
这提供了完整的文件隔离,某个 milestone 的变更不会干扰你的主工作副本。
### `branch` 模式
工作直接在项目根目录中的 `milestone/<MID>` 分支上进行,不会创建 worktree。完成后该分支会被合并回主分支是 squash merge 还是普通 merge 由 `merge_strategy` 控制)。
当 worktree 会带来问题时使用它,例如:子模块较多的仓库、包含硬编码路径的仓库、或者 worktree symlink 表现异常的环境。
### `none` 模式
工作直接发生在当前分支。没有 worktree也没有 milestone 分支。GSD 依然会按顺序提交,并使用 conventional commit message但不会提供分支级隔离。
适用于热重载工作流中“文件隔离会破坏开发工具”的情况(例如只能监视项目根目录的文件监听器),或者很小的项目里不值得承担分支开销的情况。
## 分支模型worktree 模式)
```
main ─────────────────────────────────────────────────────────
│ ↑
└── milestone/M001 (worktree) ────────────────────────┘
commit: feat: core types
commit: feat: markdown parser
commit: feat: file writer
commit: docs: workflow docs
...
→ squash-merged to main as single commit
```
**branch 模式** 下,流程相同,只是工作发生在项目根目录而不是独立的 worktree 目录。
**none 模式** 下,提交直接落到当前分支,不会创建 milestone 分支,也不需要合并步骤。
### 并行 worktrees
如果启用了 [并行编排](./parallel-orchestration.md),多个 milestones 可以同时运行在各自独立的 worktree 中:
```
main ──────────────────────────────────────────────────────────
│ ↑ ↑
├── milestone/M002 (worktree) ─────────┘ │
│ commit: feat: auth types │
│ commit: feat: JWT middleware │
│ → squash-merged first │
│ │
└── milestone/M003 (worktree) ────────────────────────┘
commit: feat: dashboard layout
commit: feat: chart components
→ squash-merged second
```
每个 worktree 都工作在自己的分支和自己的提交历史上。为了避免冲突,合并会顺序进行。
### 关键特性
- **单分支顺序提交**:没有按 slice 单独分支,也不会在单个 milestone 内产生合并冲突
- **Squash merge 到主分支**:在 worktree 和 branch 模式下,所有提交最终都会以一个干净的提交压缩到主分支(可通过 `merge_strategy` 配置)
### 提交格式
提交使用 conventional commit 格式,并在 trailer 中带上 GSD 元数据:
```
feat: core type definitions
GSD-Task: M001/S01/T01
feat: markdown parser for plan files
GSD-Task: M001/S01/T02
```
## Worktree 管理
以下特性仅适用于 **worktree 模式**
### 自动(自动模式)
自动模式会自动创建并管理 worktrees
1. milestone 启动时,在 `.gsd/worktrees/<MID>/` 创建 worktree并切到 `milestone/<MID>` 分支
2. 将 `.gsd/milestones/` 下的规划产物复制到该 worktree
3. 所有执行都发生在 worktree 内部
4. milestone 完成后,把该 worktree squash merge 回集成分支
5. 删除 worktree 和对应分支
### 手动
使用 `/worktree`(或 `/wt`)命令手动管理 worktree
```
/worktree create
/worktree switch
/worktree merge
/worktree remove
```
## 工作流模式
如果不想逐个配置 git 设置,可以通过 `mode` 获得一组更合理的默认值:
```yaml
mode: solo # 个人项目自动推送、squash、简单 ID
mode: team # 共享仓库:唯一 ID、推送分支、预合并检查
```
| 设置 | `solo` | `team` |
|---|---|---|
| `git.auto_push` | `true` | `false` |
| `git.push_branches` | `false` | `true` |
| `git.pre_merge_check` | `false` | `true` |
| `git.merge_strategy` | `"squash"` | `"squash"` |
| `git.isolation` | `"worktree"` | `"worktree"` |
| `git.commit_docs` | `true` | `true` |
| `unique_milestone_ids` | `false` | `true` |
Mode 默认值的优先级最低,任何显式偏好设置都会覆盖它们。例如,`mode: solo` 配合 `git.auto_push: false`,就表示除了自动推送以外,其它行为都沿用 solo 的默认配置。
已有但未设置 `mode` 的配置会保持原样,不会被自动注入新默认值。
## Git 偏好设置
可以在偏好设置中配置 git 行为:
```yaml
git:
auto_push: false # 提交后推送
push_branches: false # 推送 milestone 分支
remote: origin
snapshots: false # WIP 快照提交
pre_merge_check: false # 合并前校验
commit_type: feat # 覆盖提交类型前缀
main_branch: main # 主分支名称
commit_docs: true # 将 .gsd/ 提交到 git
isolation: worktree # "worktree"、"branch" 或 "none"
auto_pr: false # milestone 完成时自动创建 PR
pr_target_branch: develop # PR 目标分支(默认 main
```
### 自动创建 Pull Request
对于使用 Gitflow 或分支工作流的团队GSD 可以在 milestone 完成时自动创建 pull request
```yaml
git:
auto_push: true
auto_pr: true
pr_target_branch: develop
```
这样会把 milestone 分支推送到远程,并创建一个目标分支为 `develop`(或你指定的其它分支)的 PR。要求已安装并认证 `gh` CLI。详见 [git.auto_pr](./configuration.md#gitauto_pr)。
### `commit_docs: false`
当设置为 `false`GSD 会把 `.gsd/` 添加到 `.gitignore`,所有规划产物只保留在本地。适合只有部分成员使用 GSD 的团队,或者公司要求仓库保持干净的场景。
## 自愈能力
GSD 内置了对常见 git 问题的自动恢复:
- **Detached HEAD**:自动重新附着到正确分支
- **过期锁文件**:移除崩溃进程残留的 `index.lock`
- **孤儿 worktree**:检测并提供清理废弃 worktree 的选项(仅 worktree 模式)
可通过 `/gsd doctor` 手动检查 git 健康状态。
## 原生 Git 操作
从 v2.16 起GSD 在派发热路径中的读密集 git 操作改用 libgit2 原生绑定。这消除了每次派发周期中约 70 次进程拉起,从而提升了自动模式吞吐量。

View file

@ -0,0 +1,48 @@
# 从 v1 迁移
如果你有仍在使用原始 Get Shit Donev1`.planning` 目录结构的项目,可以把它们迁移到 GSD-2 的 `.gsd` 格式。
## 运行迁移
```bash
# 在项目目录内执行
/gsd migrate
# 或者显式指定路径
/gsd migrate ~/projects/my-old-project
```
## 会迁移什么
迁移工具会:
- 解析旧版的 `PROJECT.md``ROADMAP.md``REQUIREMENTS.md`、phase 目录、计划、总结和研究文档
- 将 phases 映射为 slices、plans 映射为 tasks、milestones 映射为 milestones
- 保留完成状态(`[x]` 阶段保持已完成,原有 summary 会被带过来)
- 将研究文件整合进新的目录结构
- 在真正写入前先展示预览
- 可选运行一次由 agent 驱动的结果审查,以做质量保证
## 支持的格式
迁移器可处理多种 v1 文档变体:
- 按 milestone 分段、带 `<details>` 块的 roadmap
- 粗体 phase 条目
- 列表格式的 requirements
- 十进制 phase 编号
- 跨不同 milestones 重复的 phase 编号
## 前提条件
如果项目有 `ROADMAP.md` 来描述 milestone 结构,迁移效果最好。没有的话,系统会根据 `phases/` 目录推断 milestones。
## 迁移后
迁移完成后,用下面的命令检查输出结果:
```bash
/gsd doctor
```
它会检查 `.gsd/` 的完整性,并标出任何结构性问题。

View file

@ -0,0 +1,75 @@
# 在 macOS 上通过 Homebrew 固定 Node.js LTS 版本
如果你是通过 Homebrew 安装 Node.js`brew install node`),那你跟踪的是**当前最新正式版本**,其中可能包含奇数版本的开发分支(例如 23.x、25.x。这些版本并不是 LTS可能带来破坏性变更或稳定性问题。
GSD 要求 Node.js **v22 或更高版本**,并且在 **LTS偶数版本** 上运行效果最好。本指南展示如何用 Homebrew 固定到 Node 24 LTS。
## 检查当前版本
```bash
node --version
```
如果输出的是奇数主版本号(例如 `v23.x``v25.x`),说明你当前使用的是开发版。
## 安装 Node 24 LTS
Homebrew 为 LTS 版本提供了带版本号的 formula
```bash
# 取消当前版本(可能不是 LTS的链接
brew unlink node
# 安装 Node 24 LTS
brew install node@24
# 将它设为默认版本
brew link --overwrite node@24
```
验证:
```bash
node --version
# 应显示 v24.x.x
```
## 为什么要固定到 LTS
- **稳定性**LTS 版本会在 30 个月内持续收到 bug 修复和安全更新
- **兼容性**:包括 GSD 在内的 npm 包通常都会优先测试 LTS 版本
- **可预期**`brew upgrade` 不会把你突然升级到不稳定的开发版
## 防止误升级
默认情况下,`brew upgrade` 会升级所有包,这可能让你离开固定版本。可以把对应 formula pin 住:
```bash
brew pin node@24
```
如果以后想取消固定:
```bash
brew unpin node@24
```
## 在多个版本之间切换
如果你需要同时使用多个 Node 版本(例如 22 和 24更推荐使用版本管理器
- **[nvm](https://github.com/nvm-sh/nvm)**`nvm install 24 && nvm use 24`
- **[fnm](https://github.com/Schniz/fnm)**`fnm install 24 && fnm use 24`(更快,基于 Rust
- **[mise](https://mise.jdx.dev/)**`mise use node@24`(多语言版本管理器)
这些工具允许你通过 `.node-version``.nvmrc` 为不同项目设置独立的 Node 版本。
## 验证 GSD 是否正常工作
固定版本后,执行:
```bash
node --version # v24.x.x
npm install -g gsd-pi
gsd --version
```

View file

@ -0,0 +1,310 @@
# 并行 Milestone 编排
在隔离的 git worktrees 中同时运行多个 milestones。每个 milestone 都拥有自己的 worker 进程、自己的分支和自己的上下文窗口;同时还会有一个 coordinator 跟踪进度、执行预算限制并保持整体同步。
> **状态:** 该功能默认处于 `parallel.enabled: false`。属于显式 opt-in对现有用户零影响。
## 快速开始
1. 在偏好设置中开启并行模式:
```yaml
---
parallel:
enabled: true
max_workers: 2
---
```
2. 启动并行执行:
```
/gsd parallel start
```
GSD 会扫描所有 milestones检查依赖与文件重叠给出一份可并行性报告并为符合条件的 milestones 启动 workers。
3. 监控进度:
```
/gsd parallel status
```
4. 完成后停止:
```
/gsd parallel stop
```
## 工作原理
### 架构
```
┌─────────────────────────────────────────────────────────┐
│ Coordinator你的 GSD 会话) │
│ │
│ 职责: │
│ - 可并行性分析(依赖 + 文件重叠) │
│ - Worker 启动与生命周期管理 │
│ - 全部 workers 的预算跟踪 │
│ - 派发控制信号pause / resume / stop
│ - 会话状态监控 │
│ - Merge 对账 │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Worker 1 │ │ Worker 2 │ │ Worker 3 │ ... │
│ │ M001 │ │ M003 │ │ M005 │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │ │ │ │
│ ▼ ▼ ▼ │
│ .gsd/worktrees/ .gsd/worktrees/ .gsd/worktrees/ │
│ M001/ M003/ M005/ │
│ (milestone/ (milestone/ (milestone/ │
│ M001 branch) M003 branch) M005 branch) │
└─────────────────────────────────────────────────────────┘
```
### Worker 隔离
每个 worker 都是一个完全隔离的独立 `gsd` 进程:
| 资源 | 隔离方式 |
|------|----------|
| **文件系统** | Git worktree每个 worker 都有自己的 checkout |
| **Git 分支** | `milestone/<MID>`:每个 milestone 一条分支 |
| **状态推导** | 通过 `GSD_MILESTONE_LOCK` 环境变量,让 `deriveState()` 只看到被分配的 milestone |
| **上下文窗口** | 独立进程:每个 worker 都有自己的 agent sessions |
| **指标** | 每个 worktree 都有自己的 `.gsd/metrics.json` |
| **崩溃恢复** | 每个 worktree 都有自己的 `.gsd/auto.lock` |
### 协调方式
Workers 和 coordinator 通过基于文件的 IPC 通信:
- **会话状态文件**`.gsd/parallel/<MID>.status.json`worker 写入 heartbeatcoordinator 读取
- **信号文件**`.gsd/parallel/<MID>.signal.json`coordinator 写信号worker 消费
- **原子写入**:使用写临时文件再 rename 的方式,避免读到半成品
## 可并行性分析
在真正启动并行执行之前GSD 会先检查哪些 milestones 可以安全并发运行。
### 规则
1. **未完成**:已完成的 milestones 会被跳过
2. **依赖满足**:所有 `dependsOn` 指向的 milestones 都必须已处于 `complete`
3. **文件重叠检查**:如果多个 milestones 会触碰同一批文件,会给出警告(但仍可执行)
### 示例报告
```
# Parallel Eligibility Report
## Eligible for Parallel Execution (2)
- **M002** — Auth System
All dependencies satisfied.
- **M003** — Dashboard UI
All dependencies satisfied.
## Ineligible (2)
- **M001** — Core Types
Already complete.
- **M004** — API Integration
Blocked by incomplete dependencies: M002.
## File Overlap Warnings (1)
- **M002** <-> **M003** — 2 shared file(s):
- `src/types.ts`
- `src/middleware.ts`
```
文件重叠只是警告,不是阻断条件。因为两个 milestones 会运行在各自独立的 worktree 中,它们不会在文件系统层面互相干扰。真正的冲突会在 merge 阶段被检测和处理。
## 配置
把下面内容加到 `~/.gsd/PREFERENCES.md``.gsd/PREFERENCES.md`
```yaml
---
parallel:
enabled: false # 总开关默认false
max_workers: 2 # 并发 workers 数1-4默认2
budget_ceiling: 50.00 # 聚合成本上限(美元,可选)
merge_strategy: "per-milestone" # 何时 merge"per-slice" 或 "per-milestone"
auto_merge: "confirm" # "auto"、"confirm" 或 "manual"
---
```
### 配置参考
| Key | 类型 | 默认值 | 说明 |
|-----|------|--------|------|
| `enabled` | boolean | `false` | 总开关。只有设为 `true``/gsd parallel` 命令才可用。 |
| `max_workers` | number1-4 | `2` | 最大并发 worker 进程数。值越高,内存与 API 预算消耗也越高。 |
| `budget_ceiling` | number | 无 | 所有 workers 的聚合美元预算上限。达到后不会再派发新单元。 |
| `merge_strategy` | `"per-slice"``"per-milestone"` | `"per-milestone"` | worktree 变更何时回合并到主分支。Per-milestone 会等整个 milestone 完成后再合并。 |
| `auto_merge` | `"auto"``"confirm"``"manual"` | `"confirm"` | merge-back 策略。`confirm` 会在合并前询问;`manual` 要求显式执行 `/gsd parallel merge`。 |
## 命令
| 命令 | 说明 |
|------|------|
| `/gsd parallel start` | 分析可并行性、确认并启动 workers |
| `/gsd parallel status` | 显示所有 workers 的状态、已完成单元和成本 |
| `/gsd parallel stop` | 停止所有 workers发送 SIGTERM |
| `/gsd parallel stop M002` | 停止某个指定 milestone 的 worker |
| `/gsd parallel pause` | 暂停所有 workers完成当前单元后等待 |
| `/gsd parallel pause M002` | 暂停某个指定 worker |
| `/gsd parallel resume` | 恢复所有已暂停 workers |
| `/gsd parallel resume M002` | 恢复某个指定 worker |
| `/gsd parallel merge` | 把所有已完成 milestones 合并回 main |
| `/gsd parallel merge M002` | 只把某个指定 milestone 合并回 main |
## 信号生命周期
Coordinator 通过信号和 workers 通信:
```
Coordinator Worker
│ │
├── sendSignal("pause") ──→ │
│ ├── consumeSignal()
│ ├── pauseAuto()
│ │ (完成当前单元后等待)
│ │
├── sendSignal("resume") ─→ │
│ ├── consumeSignal()
│ ├── 继续 dispatch loop
│ │
├── sendSignal("stop") ───→ │
│ + SIGTERM ────────────→ │
│ ├── consumeSignal() or SIGTERM handler
│ ├── stopAuto()
│ └── 进程退出
```
Workers 会在单元之间检查信号(位于 `handleAgentEnd`)。在 stop 场景下coordinator 还会额外发送 `SIGTERM` 来提高响应速度。
## Merge 对账
当 milestones 完成后,它们在 worktree 中的改动需要 merge 回主分支。
### Merge 顺序
- **顺序合并**(默认):按 milestone ID 顺序合并M001 在 M002 之前)
- **按完成顺序合并**:按照 milestones 实际完成的先后顺序合并
### 冲突处理
1. `.gsd/` 状态文件(如 `STATE.md``metrics.json`)会**自动解决**,默认接受 milestone 分支版本
2. 代码冲突则会**停止并报告**。合并会暂停,并显示哪些文件冲突。你需要手动解决后,再执行 `/gsd parallel merge <MID>` 重试
### 示例
```
/gsd parallel merge
# Merge Results
- **M002** — merged successfully (pushed)
- **M003** — CONFLICT (2 file(s)):
- `src/types.ts`
- `src/middleware.ts`
Resolve conflicts manually and run `/gsd parallel merge M003` to retry.
```
## 预算管理
当设置了 `budget_ceiling`coordinator 会跟踪所有 workers 的聚合成本:
- 成本会从每个 worker 的 session status 中汇总
- 达到上限后coordinator 会向 workers 发出停止信号
- 每个 worker 仍会独立遵守项目级 `budget_ceiling` 偏好
## 健康监控
### Doctor 集成
`/gsd doctor` 能检测并行会话相关问题:
- **过期的并行会话**worker 进程已经死亡但没有清理干净。Doctor 会检查 `.gsd/parallel/*.status.json` 中记录的 PID 和 heartbeat发现失效后自动清理。
可以执行 `/gsd doctor --fix` 自动清理。
### 过期检测
满足以下任一条件时,会话会被视为 stale
- Worker PID 已经不存在(通过 `process.kill(pid, 0)` 检查)
- 最近一次 heartbeat 超过 30 秒
Coordinator 会在 `refreshWorkerStatuses()` 中执行 stale detection并自动移除已经死亡的会话。
## 安全模型
| 安全层 | 保护内容 |
|--------|----------|
| **Feature flag** | 默认 `parallel.enabled: false`,不影响现有用户 |
| **可并行性分析** | 启动前检查依赖和文件重叠 |
| **Worker 隔离** | 独立进程、worktrees、分支、上下文窗口 |
| **`GSD_MILESTONE_LOCK`** | 每个 worker 在状态推导时只能看到自己的 milestone |
| **`GSD_PARALLEL_WORKER`** | Worker 不能再嵌套启动新的并行会话 |
| **预算上限** | 跨所有 workers 执行聚合成本限制 |
| **信号式关闭** | 通过文件信号 + SIGTERM 优雅停止 |
| **Doctor 集成** | 检测并清理孤儿会话 |
| **冲突感知 merge** | 遇到代码冲突时停止;`.gsd/` 状态冲突自动解决 |
## 文件布局
```
.gsd/
├── parallel/ # Coordinator ↔ worker IPC
│ ├── M002.status.json # Worker heartbeat + progress
│ ├── M002.signal.json # Coordinator → worker signals
│ ├── M003.status.json
│ └── M003.signal.json
├── worktrees/ # Git worktrees每个 milestone 一个)
│ ├── M002/ # M002 的隔离 checkout
│ │ ├── .gsd/ # M002 自己的状态文件
│ │ │ ├── auto.lock
│ │ │ ├── metrics.json
│ │ │ └── milestones/
│ │ └── src/ # M002 的工作副本
│ └── M003/
│ └── ...
└── ...
```
`.gsd/parallel/``.gsd/worktrees/` 都会被 gitignore因为它们只是运行时协调文件永远不会提交。
## 故障排查
### “Parallel mode is not enabled”
在偏好设置里加入 `parallel.enabled: true`
### “No milestones are eligible for parallel execution”
说明所有 milestones 要么已完成,要么被依赖阻塞。可通过 `/gsd queue` 查看 milestone 状态和依赖链。
### Worker 崩溃后如何恢复
Workers 会自动把状态持久化到磁盘。如果某个 worker 进程死亡coordinator 会通过 heartbeat 超时检测到死掉的 PID并把该 worker 标记为 crashed。重启后worker 会从磁盘状态继续崩溃恢复、worktree 重入和 completed-unit 跟踪都会延续之前的状态。
1. 执行 `/gsd doctor --fix` 清理 stale sessions
2. 执行 `/gsd parallel status` 查看当前状态
3. 重新执行 `/gsd parallel start`,为剩余 milestones 启动新的 workers
### 并行执行完成后发生 merge 冲突
1. 执行 `/gsd parallel merge` 查看哪些 milestones 存在冲突
2. 在 `.gsd/worktrees/<MID>/` 对应的 worktree 中手动解决冲突
3. 执行 `/gsd parallel merge <MID>` 重试
### Workers 看起来卡住了
先检查是否触达了预算上限:`/gsd parallel status` 会显示每个 worker 的成本。继续执行的话,提升 `parallel.budget_ceiling` 或直接移除它。

View file

@ -0,0 +1,677 @@
# Provider 设置指南
这是一份覆盖 GSD 所有受支持 LLM providers 的分步配置指南。如果你已经运行过 onboarding 向导(`gsd config`)并选择了 provider很可能已经配置完成可以在会话中用 `/model` 检查。
## 目录
- [快速参考](#quick-reference)
- [内置 Providers](#built-in-providers)
- [AnthropicClaude](#anthropic-claude)
- [OpenAI](#openai)
- [Google Gemini](#google-gemini)
- [OpenRouter](#openrouter)
- [Groq](#groq)
- [xAIGrok](#xai-grok)
- [Mistral](#mistral)
- [GitHub Copilot](#github-copilot)
- [Amazon Bedrock](#amazon-bedrock)
- [Vertex AI 上的 Anthropic](#anthropic-on-vertex-ai)
- [Azure OpenAI](#azure-openai)
- [本地 Providers](#local-providers)
- [Ollama](#ollama)
- [LM Studio](#lm-studio)
- [vLLM](#vllm)
- [SGLang](#sglang)
- [自定义 OpenAI-Compatible Endpoints](#custom-openai-compatible-endpoints)
- [常见坑点](#common-pitfalls)
- [验证你的配置](#verifying-your-setup)
<a id="quick-reference"></a>
## 快速参考
| Provider | 认证方式 | 环境变量 | 配置文件 |
|----------|----------|----------|----------|
| Anthropic | API key | `ANTHROPIC_API_KEY` | — |
| OpenAI | API key | `OPENAI_API_KEY` | — |
| Google Gemini | API key | `GEMINI_API_KEY` | — |
| OpenRouter | API key | `OPENROUTER_API_KEY` | 可选 `models.json` |
| Groq | API key | `GROQ_API_KEY` | — |
| xAI | API key | `XAI_API_KEY` | — |
| Mistral | API key | `MISTRAL_API_KEY` | — |
| GitHub Copilot | OAuth | `GH_TOKEN` | — |
| Amazon Bedrock | IAM credentials | `AWS_PROFILE``AWS_ACCESS_KEY_ID` | — |
| Vertex AI | ADC | `GOOGLE_APPLICATION_CREDENTIALS` | — |
| Azure OpenAI | API key | `AZURE_OPENAI_API_KEY` | — |
| Ollama | 无(本地) | — | 需要 `models.json` |
| LM Studio | 无(本地) | — | 需要 `models.json` |
| vLLM / SGLang | 无(本地) | — | 需要 `models.json` |
---
<a id="built-in-providers"></a>
## 内置 Providers
内置 providers 的 models 已经预注册在 GSD 里。你只需要提供认证信息。
<a id="anthropic-claude"></a>
### AnthropicClaude
**推荐。** Anthropic models 集成最深,支持内置 Web 搜索、extended thinking 和 prompt caching。
**选项 AAPI key推荐**
```bash
export ANTHROPIC_API_KEY="sk-ant-..."
```
或者运行 `gsd config`,在提示时粘贴 key。
**获取 key** [console.anthropic.com/settings/keys](https://console.anthropic.com/settings/keys)
**选项 BClaude Code CLI**
如果你有 Claude Pro 或 Max 订阅,可以通过 Anthropic 官方的 Claude Code CLI 完成认证。安装后执行 `claude` 登录,随后 GSD 会自动检测并经由该通道路由:
```bash
# 安装 Claude Code CLI见 https://docs.anthropic.com/en/docs/claude-code
claude
# 按提示登录,然后启动 GSD
gsd
```
GSD 会检测你本地的 Claude Code 安装,并把它作为已认证的 Anthropic surface 使用。这是 Anthropic 订阅用户符合 TOS 的方式GSD 不会直接处理你的订阅凭据。
> **注意:** GSD 不支持 Anthropic 的浏览器 OAuth 登录。请改用 API key 或 Claude Code CLI。
**选项 C在 Claude Code 里直接用 Claude Pro / Max 订阅跑 GSD**
如果你已经有 Claude Pro / Max 订阅,并希望直接在 Claude Code 里使用 GSD 的 planning、execution 和 milestone orchestration而不是切到单独终端那么可以把 GSD 接成一个 MCP server。这样 Claude Code 就能通过 [Model Context Protocol](https://modelcontextprotocol.io) 使用 GSD 的完整 workflow 工具集,在你现有 Claude plan 的驱动下获得 GSD 的结构化项目管理能力。
**自动配置(推荐)**
当 GSD 在启动时检测到 Claude Code model它会自动在项目根目录写入一个带有 GSD workflow MCP server 配置的 `.mcp.json` 文件。无需手动步骤,只要以 Claude Code 作为 provider 启动一次 GSD配置就会自动生成。
你也可以在 GSD 会话中手动触发:
```bash
/gsd mcp init
```
这会在项目的 `.mcp.json` 中写入(或更新)`gsd-workflow` 条目。Claude Code 会在下一次启动会话时自动发现这个文件。
**手动配置**
如果你更希望自己配置,可以把 GSD 加到项目的 `.mcp.json` 中:
```json
{
"mcpServers": {
"gsd": {
"command": "npx",
"args": ["gsd-mcp-server"],
"env": {
"GSD_CLI_PATH": "/path/to/gsd"
}
}
}
}
```
如果 `gsd-mcp-server` 已经全局安装:
```json
{
"mcpServers": {
"gsd": {
"command": "gsd-mcp-server"
}
}
}
```
你也可以把这段配置写到 `~/.claude/settings.json``mcpServers` 中,让 GSD 在所有项目中都可用。
**暴露了什么**
MCP server 会暴露 GSD 的完整 workflow 工具面milestone planning、task completion、slice 管理、roadmap reassessment、journal 查询等。会话管理工具(`gsd_execute``gsd_status``gsd_result``gsd_cancel`)允许 Claude Code 启动并监控 GSD 自动模式会话。完整工具列表见 [命令 → MCP Server 模式](./commands.md#mcp-server-mode)。
**验证连接**
在 GSD 会话里检查 MCP server 是否可达:
```bash
/gsd mcp status
```
<a id="openai"></a>
### OpenAI
```bash
export OPENAI_API_KEY="sk-..."
```
或者运行 `gsd config`,选择 “Paste an API key” 然后选择 “OpenAI”。
**获取 key** [platform.openai.com/api-keys](https://platform.openai.com/api-keys)
<a id="google-gemini"></a>
### Google Gemini
```bash
export GEMINI_API_KEY="..."
```
**获取 key** [aistudio.google.com/app/apikey](https://aistudio.google.com/app/apikey)
<a id="openrouter"></a>
### OpenRouter
OpenRouter 通过单个 API key 聚合了多个 providers 的 200+ models。
**第 1 步:获取 API key**
访问 [openrouter.ai/keys](https://openrouter.ai/keys) 创建一个 key。
**第 2 步:设置 key**
```bash
export OPENROUTER_API_KEY="sk-or-..."
```
或者运行 `gsd config`,选择 “Paste an API key” 然后选择 “OpenRouter”。
**第 3 步:切换到 OpenRouter model**
在 GSD 会话中输入 `/model` 并选择一个 OpenRouter model。OpenRouter models 都以 `openrouter/` 为前缀(例如 `openrouter/anthropic/claude-sonnet-4`)。
**可选:通过 `models.json` 添加自定义 OpenRouter models**
如果你想使用不在内置列表中的 model可把它写进 `~/.gsd/agent/models.json`
```json
{
"providers": {
"openrouter": {
"baseUrl": "https://openrouter.ai/api/v1",
"apiKey": "OPENROUTER_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "meta-llama/llama-3.3-70b",
"name": "Llama 3.3 70B (OpenRouter)",
"reasoning": false,
"input": ["text"],
"contextWindow": 131072,
"maxTokens": 32768,
"cost": { "input": 0.3, "output": 0.3, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}
```
注意:这里的 `apiKey` 字段写的是**环境变量名**,不是字面 key。GSD 会自动解析它。你也可以改用字面值或 shell 命令(见 [值解析](./custom-models.md#value-resolution))。
**可选:路由到指定上游 provider**
你可以通过 `modelOverrides` 控制 OpenRouter 实际选用哪个上游 provider
```json
{
"providers": {
"openrouter": {
"modelOverrides": {
"anthropic/claude-sonnet-4": {
"compat": {
"openRouterRouting": {
"only": ["amazon-bedrock"]
}
}
}
}
}
}
}
```
<a id="groq"></a>
### Groq
```bash
export GROQ_API_KEY="gsk_..."
```
**获取 key** [console.groq.com/keys](https://console.groq.com/keys)
<a id="xai-grok"></a>
### xAIGrok
```bash
export XAI_API_KEY="xai-..."
```
**获取 key** [console.x.ai](https://console.x.ai)
<a id="mistral"></a>
### Mistral
```bash
export MISTRAL_API_KEY="..."
```
**获取 key** [console.mistral.ai/api-keys](https://console.mistral.ai/api-keys)
<a id="github-copilot"></a>
### GitHub Copilot
使用 OAuth通过浏览器登录
```bash
gsd config
# 选择 "Sign in with your browser" → "GitHub Copilot"
```
要求你拥有有效的 GitHub Copilot 订阅。
<a id="amazon-bedrock"></a>
### Amazon Bedrock
Bedrock 使用 AWS IAM 凭据,而不是 API key。下面任意一种都可以
```bash
# 选项 1命名 profile
export AWS_PROFILE="my-profile"
# 选项 2IAM keys
export AWS_ACCESS_KEY_ID="AKIA..."
export AWS_SECRET_ACCESS_KEY="..."
export AWS_REGION="us-east-1"
# 选项 3Bedrock API keybearer token
export AWS_BEARER_TOKEN_BEDROCK="..."
```
ECS task roles 和 IRSAKubernetes也会被自动检测。
<a id="anthropic-on-vertex-ai"></a>
### Vertex AI 上的 Anthropic
使用 Google Cloud Application Default Credentials
```bash
gcloud auth application-default login
export ANTHROPIC_VERTEX_PROJECT_ID="my-project-id"
```
或者设置 `GOOGLE_CLOUD_PROJECT`,并确保 ADC 凭据存在于 `~/.config/gcloud/application_default_credentials.json`
<a id="azure-openai"></a>
### Azure OpenAI
```bash
export AZURE_OPENAI_API_KEY="..."
```
---
<a id="local-providers"></a>
## 本地 Providers
本地 providers 运行在你的机器上。因为 GSD 需要知道 endpoint URL 和可用 models所以它们都要求配置 `models.json`
**配置文件位置:** `~/.gsd/agent/models.json`
每次打开 `/model` 时,这个文件都会自动重新加载,无需重启。
<a id="ollama"></a>
### Ollama
**第 1 步:安装并启动 Ollama**
```bash
# macOS
brew install ollama
ollama serve
# 或前往 https://ollama.com 下载
```
**第 2 步:拉取一个 model**
```bash
ollama pull llama3.1:8b
ollama pull qwen2.5-coder:7b
```
**第 3 步:创建 `~/.gsd/agent/models.json`**
```json
{
"providers": {
"ollama": {
"baseUrl": "http://localhost:11434/v1",
"api": "openai-completions",
"apiKey": "ollama",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
},
"models": [
{ "id": "llama3.1:8b" },
{ "id": "qwen2.5-coder:7b" }
]
}
}
}
```
`apiKey` 是 schema 的必填字段,但 Ollama 会忽略它,因此任意值都可以。
**第 4 步:选择 model**
在 GSD 里输入 `/model`,然后选择你的 Ollama model。
**Ollama 提示:**
- Ollama 不支持 `developer` role也不支持 `reasoning_effort`,因此请始终设置 `compat.supportsDeveloperRole: false``compat.supportsReasoningEffort: false`
- 如果得到空响应,先检查 `ollama serve` 是否正在运行,以及 model 是否已经 pull 下来
- 如果未显式指定,`contextWindow``maxTokens` 默认分别为 128K / 16K。若模型能力不同请手动覆盖
<a id="lm-studio"></a>
### LM Studio
**第 1 步:安装 LM Studio**
访问 [lmstudio.ai](https://lmstudio.ai) 下载。
**第 2 步:启动本地 server**
在 LM Studio 中进入 “Local Server” 标签页,加载一个 model然后点击 “Start Server”。默认端口为 1234。
**第 3 步:创建 `~/.gsd/agent/models.json`**
```json
{
"providers": {
"lm-studio": {
"baseUrl": "http://localhost:1234/v1",
"api": "openai-completions",
"apiKey": "lm-studio",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
},
"models": [
{
"id": "your-model-name",
"name": "My Local Model",
"contextWindow": 32768,
"maxTokens": 4096
}
]
}
}
}
```
`your-model-name` 替换成 LM Studio server 标签页中显示的 model 标识符。
**LM Studio 提示:**
- `models.json` 里的 model `id` 必须与 LM Studio server API 返回的值完全一致
- LM Studio 默认端口是 1234如果你改了端口也要同步修改 `baseUrl`
- 如果模型支持更大的上下文,记得上调 `contextWindow``maxTokens`
<a id="vllm"></a>
### vLLM
```json
{
"providers": {
"vllm": {
"baseUrl": "http://localhost:8000/v1",
"api": "openai-completions",
"apiKey": "vllm",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false,
"supportsUsageInStreaming": false
},
"models": [
{
"id": "meta-llama/Llama-3.1-8B-Instruct",
"contextWindow": 128000,
"maxTokens": 16384
}
]
}
}
}
```
model `id` 必须与 `vllm serve` 启动时传入的 `--model` 参数完全一致。
<a id="sglang"></a>
### SGLang
```json
{
"providers": {
"sglang": {
"baseUrl": "http://localhost:30000/v1",
"api": "openai-completions",
"apiKey": "sglang",
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
},
"models": [
{
"id": "meta-llama/Llama-3.1-8B-Instruct"
}
]
}
}
}
```
---
<a id="custom-openai-compatible-endpoints"></a>
## 自定义 OpenAI-Compatible Endpoints
任何实现了 OpenAI Chat Completions API 的 server 都可以和 GSD 配合使用。这包括代理LiteLLM、Portkey、Helicone、自托管推理服务以及新出现的 providers。
**最快路径:使用 onboarding 向导**
```bash
gsd config
# 选择 "Paste an API key" → "Custom (OpenAI-compatible)"
# 输入base URL、API key、model ID
```
这会自动帮你写好 `~/.gsd/agent/models.json`
**手动配置:**
```json
{
"providers": {
"my-provider": {
"baseUrl": "https://my-endpoint.example.com/v1",
"apiKey": "MY_PROVIDER_API_KEY",
"api": "openai-completions",
"models": [
{
"id": "model-id-here",
"name": "Friendly Model Name",
"reasoning": false,
"input": ["text"],
"contextWindow": 128000,
"maxTokens": 16384,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}
```
**添加自定义 headers常见于代理**
```json
{
"providers": {
"litellm-proxy": {
"baseUrl": "https://litellm.example.com/v1",
"apiKey": "MY_API_KEY",
"api": "openai-completions",
"headers": {
"x-custom-header": "value"
},
"models": [...]
}
}
}
```
**支持 thinking mode 的 Qwen models**
对于 Qwen-compatible servers可用 `thinkingFormat` 打开 thinking mode
```json
{
"compat": {
"thinkingFormat": "qwen",
"supportsDeveloperRole": false
}
}
```
如果该 server 要求 `chat_template_kwargs.enable_thinking`,请改用 `"qwen-chat-template"`
关于 `compat` 字段、`modelOverrides`、值解析和高级配置的完整说明,见 [自定义模型](./custom-models.md)。
---
<a id="common-pitfalls"></a>
## 常见坑点
### 使用有效 key 仍提示 “Authentication failed”
**原因:** key 虽然设在 shell 中,但 GSD 看不到。
**解决:** 确认你是在同一个终端里 `export` 了该环境变量并运行 `gsd`。或者直接用 `gsd config` 把 key 保存进 `~/.gsd/agent/auth.json`,这样就能跨会话持久化。
### OpenRouter models 没出现在 `/model`
**原因:** 没有设置 `OPENROUTER_API_KEY`,因此 GSD 会隐藏 OpenRouter models。
**解决:** 设置 key 并重启 GSD
```bash
export OPENROUTER_API_KEY="sk-or-..."
gsd
```
### Ollama 返回空响应
**原因:** Ollama server 没有运行,或者对应 model 尚未 pull。
**解决:**
```bash
# 确认 server 正在运行
curl http://localhost:11434/v1/models
# 如果 model 缺失则先 pull
ollama pull llama3.1:8b
```
### LM Studio model ID 不匹配
**原因:** `models.json` 中的 `id` 和 LM Studio 实际通过 API 暴露的值不一致。
**解决:** 去 LM Studio 的 server 标签页查看精确的 model 标识符。它通常会包含文件名或量化后缀(例如 `lmstudio-community/Meta-Llama-3.1-8B-Instruct-GGUF`)。
### 本地 models 报 `developer` role 错误
**原因:** 大多数本地推理 server 不支持 OpenAI 的 `developer` message role。
**解决:** 在 provider 配置里添加 `compat.supportsDeveloperRole: false`。这样 GSD 会改用 `system` message
```json
{
"compat": {
"supportsDeveloperRole": false,
"supportsReasoningEffort": false
}
}
```
### 本地 models 报 `stream_options` 错误
**原因:** 部分 server 不支持 `stream_options: { include_usage: true }`
**解决:** 添加 `compat.supportsUsageInStreaming: false`
```json
{
"compat": {
"supportsUsageInStreaming": false
}
}
```
### 报 “apiKey is required” 校验错误
**原因:** `models.json` schema 规定:只要定义了 `models`,就必须存在 `apiKey`
**解决:** 对于不需要认证的本地 server填一个占位值即可
```json
"apiKey": "not-needed"
```
### 自定义 models 的成本显示为 `$0.00`
这是**预期行为**。GSD 对自定义 models 的默认成本就是 0。如果你想获得准确的成本跟踪需要自己填写 `cost` 字段:
```json
"cost": { "input": 0.15, "output": 0.60, "cacheRead": 0.015, "cacheWrite": 0.19 }
```
这些值的单位都是每百万 tokens。
---
<a id="verifying-your-setup"></a>
## 验证你的配置
完成 provider 配置后:
1. **启动 GSD**
```bash
gsd
```
2. **检查可用 models**
```
/model
```
列表里应该能看到该 provider 的 models。
3. **切换到对应 model**
`/model` 选择器中选中它。
4. **发送一条测试消息:**
输入任意内容,确认 model 可以正常响应。
如果 model 没有出现,请检查:
- 当前 shell 中是否设置了对应环境变量
- `models.json` 是否是合法 JSON可执行 `cat ~/.gsd/agent/models.json | python3 -m json.tool`
- 本地 providers 的 server 是否已经运行
如果还需要更多帮助,请查看 [故障排查](./troubleshooting.md),或者在会话中运行 `/gsd doctor`

View file

@ -0,0 +1,161 @@
# 远程提问
在无头自动模式下运行时,远程提问允许 GSD 通过 Slack、Discord 或 Telegram 请求用户输入。当 GSD 遇到需要人工判断的决策点时,它会把问题发到你配置好的频道,并轮询等待响应。
## 设置
### Discord
```
/gsd remote discord
```
配置向导会:
1. 询问你的 Discord bot token
2. 通过 Discord API 验证该 token
3. 列出 bot 当前加入的服务器(或让你选择)
4. 列出所选服务器中的文本频道
5. 发送一条测试消息以确认权限
6. 把配置保存到 `~/.gsd/PREFERENCES.md`
**Bot 要求:**
- 需要一个带 token 的 Discord bot application来自 [Discord Developer Portal](https://discord.com/developers/applications)
- Bot 必须以以下权限加入目标服务器:
- Send Messages
- Read Message History
- Add Reactions
- View Channel
- 必须设置 `DISCORD_BOT_TOKEN` 环境变量(配置向导会帮你处理)
### Slack
```
/gsd remote slack
```
配置向导会:
1. 询问你的 Slack bot token`xoxb-...`
2. 验证该 token
3. 列出 bot 可访问的频道(也支持手动输入 ID
4. 发送一条测试消息确认权限
5. 保存配置
**Bot 要求:**
- 需要一个带 bot token 的 Slack app来自 [Slack API](https://api.slack.com/apps)
- Bot 必须已加入目标频道
- 公共 / 私有频道常见需要的 scope`chat:write``reactions:read``reactions:write``channels:read``groups:read``channels:history``groups:history`
### Telegram
```
/gsd remote telegram
```
配置向导会:
1. 询问你的 Telegram bot token来自 [@BotFather](https://t.me/BotFather)
2. 通过 Telegram API 验证该 token
3. 询问 chat ID群聊或私聊
4. 发送测试消息以确认权限
5. 保存配置
**Bot 要求:**
- 需要一个来自 [@BotFather](https://t.me/BotFather) 的 Telegram bot token
- Bot 必须已加入目标群聊(或者直接与 bot 私聊)
- 必须设置 `TELEGRAM_BOT_TOKEN` 环境变量
## 配置
远程提问配置保存在 `~/.gsd/PREFERENCES.md`
```yaml
remote_questions:
channel: discord # 或 slack 或 telegram
channel_id: "1234567890123456789"
timeout_minutes: 5 # 1-30默认 5
poll_interval_seconds: 5 # 2-30默认 5
```
## 工作原理
1. GSD 在自动模式过程中遇到一个决策点
2. 问题会以富文本 embedDiscord或 Block Kit 消息Slack的形式发送到你配置的频道
3. GSD 按设定的间隔轮询响应
4. 你可以通过以下方式回复:
- **添加数字表情回应**1⃣、2⃣ 等),适用于单问题提示
- **回复消息内容**,可以是数字(`1`)、逗号分隔数字(`1,3`)或自由文本
5. GSD 读取到响应后继续执行
6. 提示消息上会追加一个 ✅ 反应,表示已收到
### 响应格式
**单个问题:**
- 用数字表情回应(适用于单问题提示)
- 回复一个数字:`2`
- 回复自由文本(会作为用户备注记录)
**多个问题:**
- 用分号回复:`1;2;custom text`
- 用换行回复(每行一个答案)
### 超时
如果在 `timeout_minutes` 内没有收到响应提示会超时GSD 将带着超时结果继续执行。LLM 会根据当前上下文处理超时,通常是做一个保守默认选择,或者暂停自动模式。
## 命令
| 命令 | 说明 |
|------|------|
| `/gsd remote` | 显示远程提问菜单和当前状态 |
| `/gsd remote slack` | 配置 Slack 集成 |
| `/gsd remote discord` | 配置 Discord 集成 |
| `/gsd remote status` | 显示当前配置和最近一次提示状态 |
| `/gsd remote disconnect` | 移除远程提问配置 |
## Discord 与 Slack 功能对比
| 功能 | Discord | Slack |
|------|---------|-------|
| 富文本消息格式 | Embeds with fields | Block Kit |
| 用 reaction 回答 | ✅(单问题) | ✅(单问题) |
| 线程式回复 | Message replies | Thread replies |
| 日志中的消息 URL | ✅ | ✅ |
| 已收到应答的确认 | ✅ 收到后加 reaction | ✅ 收到后加 reaction |
| 多问题支持 | 文本回复(分号 / 换行) | 文本回复(分号 / 换行) |
| 提示中的上下文来源 | ✅footer | ✅context block |
| 服务器 / 频道选择器 | ✅(交互式) | ✅(交互式 + 手动兜底) |
| Token 验证 | ✅ | ✅ |
| 配置阶段测试消息 | ✅ | ✅ |
## 故障排查
### “Remote auth failed”
- 确认 bot token 正确且未过期
- 对 Discord确认 bot 仍然在目标服务器内
- 对 Slack确认 bot token 以 `xoxb-` 开头
### “Could not send to channel”
- 确认 bot 在目标频道拥有 Send Messages 权限
- 对 Discord检查 Server Settings 中 bot 对应角色的权限
- 对 Slack确认 bot 已加入频道(`/invite @botname`
### 未检测到响应
- 确认你是在**回复该提示消息**,而不是单独发了一条新消息
- 对 reactions只有单问题提示上的数字表情1⃣-5会被识别
- 检查 `timeout_minutes` 是否足够长,能覆盖你的响应时间
### 频道 ID 格式
- **Slack**9-12 位大写字母数字字符(例如 `C0123456789`
- **Discord**17-20 位纯数字 snowflake ID例如 `1234567890123456789`
- 在 Discord 中开启 Developer ModeSettings → Advanced后可以复制频道 ID

View file

@ -0,0 +1,195 @@
# 技能
技能Skills是当当前 task 匹配时由 GSD 加载的专用指令集。它们为 LLM 提供领域化指导,例如编码模式、框架惯用法、测试策略和工具使用方式。
Skills 遵循开放的 [Agent Skills 标准](https://agentskills.io/),并且**不是 GSD 专属格式**。它们同样适用于 Claude Code、OpenAI Codex、Cursor、GitHub Copilot、Windsurf 以及其他 40+ agent。
## 技能目录
GSD 会按优先级顺序从两个位置读取技能:
| 位置 | 范围 | 说明 |
|------|------|------|
| `~/.agents/skills/` | 全局 | 对所有项目和所有兼容 agent 共享 |
| `.agents/skills/`(项目根目录) | 项目级 | 项目专用技能,可提交到版本控制 |
如果出现同名技能,全局技能优先于项目技能。
> **从 `~/.gsd/agent/skills/` 迁移:** 升级后首次启动时GSD 会自动把旧版 `~/.gsd/agent/skills/` 中的技能复制到 `~/.agents/skills/`。旧目录会保留,以兼容旧流程。
## 安装技能
技能通过 [skills.sh CLI](https://skills.sh) 安装:
```bash
# 交互式:选择要安装的技能以及目标 agent
npx skills add dpearson2699/swift-ios-skills
# 非交互方式安装指定技能
npx skills add dpearson2699/swift-ios-skills --skill swift-concurrency --skill swiftui-patterns -y
# 安装仓库中的全部技能
npx skills add dpearson2699/swift-ios-skills --all
# 检查更新
npx skills check
# 更新已安装技能
npx skills update
```
### 入门技能目录
在执行 `gsd init`GSD 会检测项目技术栈并推荐合适的技能包。对于 brownfield 项目,检测是自动的;对于 greenfield 项目,则由用户选择技术栈。
这个精选目录维护在 `src/resources/extensions/gsd/skill-catalog.ts`。每一条目都会把一个技术栈映射到一个 skills.sh 仓库,以及其中的具体技能名称。
#### 可用技能包
**Swift检测到任意 Swift 项目,例如 `Package.swift``.xcodeproj`**
- **SwiftUI**布局、导航、动画、手势、Liquid Glass
- **Swift Core**Swift 语言、并发、Codable、Charts、Testing、SwiftData
**iOS仅当 `.xcodeproj` 目标通过 `SDKROOT` 指向 `iphoneos` 时):**
- **iOS App Frameworks**App Intents、Widgets、StoreKit、MapKit、Live Activities
- **iOS Data Frameworks**CloudKit、HealthKit、MusicKit、WeatherKit、Contacts
- **iOS AI & ML**Core ML、Vision、端侧 AI、语音识别
- **iOS Engineering**网络、安全、可访问性、本地化、Instruments
- **iOS Hardware**Bluetooth、CoreMotion、NFC、PencilKit、RealityKit
- **iOS Platform**CallKit、EnergyKit、HomeKit、SharePlay、PermissionKit
**Web**
- **React & Web Frontend**React 最佳实践、Web 设计、组合模式
- **React Native**:跨平台移动开发模式
- **Frontend Design & UX**:前端设计与可访问性
**语言:**
- **Rust**Rust 模式与最佳实践
- **Python**Python 模式与最佳实践
- **Go**Go 模式与最佳实践
**通用:**
- **Document Handling**PDF、DOCX、XLSX、PPTX 的创建和处理
### 维护目录
技能目录定义位于 [`src/resources/extensions/gsd/skill-catalog.ts`](../../../src/resources/extensions/gsd/skill-catalog.ts)。新增或更新一个技能包时:
1. 在 `SKILL_CATALOG` 数组中新增一个 `SkillPack` 条目,包含 `repo``skills` 和匹配条件
2. 基于语言检测做匹配时,使用 `matchLanguages`(取值来自 `detection.ts` 中的 `LANGUAGE_MAP`
3. 基于 Xcode 平台做匹配时,使用 `matchXcodePlatforms`(例如 `["iphoneos"]`,取自 `project.pbxproj` 中的 `SDKROOT`
4. 基于文件存在与否做匹配时,使用 `matchFiles`(对照 `detection.ts` 中的 `PROJECT_FILES`
5. 如果这个技能包需要在 greenfield 选项中出现,把它加入 `GREENFIELD_STACKS`
6. 如果多个技能包共享同一个 `repo`,它们会被合并为一次 `npx skills add` 调用
## 技能发现
`skill_discovery` 偏好控制 GSD 在自动模式中如何发现技能:
| 模式 | 行为 |
|------|------|
| `auto` | 自动查找并应用技能 |
| `suggest` | 识别技能,但需要确认(默认) |
| `off` | 关闭技能发现 |
## 技能偏好
你可以通过偏好设置控制使用哪些技能:
```yaml
---
version: 1
always_use_skills:
- debug-like-expert
prefer_skills:
- frontend-design
avoid_skills:
- security-docker
skill_rules:
- when: task involves Clerk authentication
use: [clerk]
- when: frontend styling work
prefer: [frontend-design]
---
```
### 解析顺序
技能可以通过以下几种方式引用:
1. **裸名称**:例如 `frontend-design`,会扫描 `~/.agents/skills/` 和项目内的 `.agents/skills/`
2. **绝对路径**:例如 `/Users/you/.agents/skills/my-skill/SKILL.md`
3. **目录路径**:例如 `~/custom-skills/my-skill`,会在其中查找 `SKILL.md`
全局技能(`~/.agents/skills/`)优先于项目技能(`.agents/skills/`)。
## 自定义技能
你可以通过新增一个包含 `SKILL.md` 的目录来创建自己的技能:
```
~/.agents/skills/my-skill/
SKILL.md — 给 LLM 的指令
references/ — 可选参考文件
```
`SKILL.md` 中写的是当技能启用时LLM 应遵循的指令。参考文件可由技能按需加载。
### 项目本地技能
如果想为某个项目提供专用指导,可以把技能放在项目里:
```
.agents/skills/my-project-skill/
SKILL.md
```
项目本地技能可以提交到版本控制中,让团队成员共享同一套技能。
## 技能生命周期管理
GSD 会跨自动模式会话跟踪技能表现,并提供健康度数据,帮助你持续维护技能质量。
### 技能遥测
每个自动模式工作单元都会记录哪些技能可用、哪些技能实际加载。这些数据和现有的 token / 成本数据一起存入 `metrics.json`
### 技能健康度面板
通过 `/gsd skill-health` 查看技能表现:
```
/gsd skill-health # 总览表名称、使用次数、成功率、token、趋势、最近使用时间
/gsd skill-health rust-core # 查看单个技能的详细信息
/gsd skill-health --stale 30 # 查看 30+ 天未使用的技能
/gsd skill-health --declining # 查看成功率在下降的技能
```
该面板会标出可能需要关注的技能:
- **最近 10 次使用的成功率低于 70%**
- **Token 使用量比上一个窗口上升 20% 以上**
- **过期技能**:超过设定阈值未使用
### 过期检测
长时间未使用的技能会被标记为 stale并可自动降低优先级
```yaml
---
skill_staleness_days: 60 # 默认 60设为 0 表示关闭
---
```
过期技能会被排除在自动匹配之外,但仍然可以通过 `read` 显式调用。
### Heal-Skill单元后分析
如果把它配置为 post-unit hookGSD 可以分析 agent 在执行中是否偏离了某个技能的指令。如果检测到明显漂移(例如 API 模式过时、指导错误),它会把建议修复写到 `.gsd/skill-review-queue.md`,供人工审核。
一个关键设计原则是:技能**永远不会被自动修改**。研究表明,人工策展的技能明显优于自动生成技能,因此保留人工审核是必要的。

View file

@ -0,0 +1,373 @@
# Token 优化
*引入于 v2.17.0*
GSD 2.17 引入了一套协同工作的 token 优化系统,在大多数工作负载下可以在不牺牲输出质量的前提下,将 token 使用降低 40-60%。这套系统由三部分构成:**token profiles**、**context compression** 和 **基于复杂度的 task 路由**
## Token Profiles
Token profile 是一个单一偏好项,用来统一协调 model 选择、阶段跳过和上下文压缩级别。在偏好设置中这样配置:
```yaml
---
version: 1
token_profile: balanced
---
```
可用的 profile 有三个:
### `budget`:最大节省(降低 40-60%
面向成本敏感型工作流。它会使用更便宜的 models跳过可选阶段并把 dispatch 上下文压缩到最低必要程度。
| 维度 | 设置 |
|------|------|
| Planning model | Sonnet |
| Execution model | Sonnet |
| Simple task model | Haiku |
| Completion model | Haiku |
| Subagent model | Haiku |
| Milestone research | **跳过** |
| Slice research | **跳过** |
| Roadmap reassessment | **跳过** |
| Context inline level | **Minimal**:丢弃 decisions、requirements、额外 templates |
适合:原型开发、小项目、已充分理解的代码库、强调成本控制的迭代。
### `balanced`:智能默认值(默认)
默认 profile。保留关键阶段跳过那些对大多数项目边际收益不高的阶段并采用标准级别的上下文压缩。
| 维度 | 设置 |
|------|------|
| Planning model | 用户默认值 |
| Execution model | 用户默认值 |
| Simple task model | 用户默认值 |
| Completion model | 用户默认值 |
| Subagent model | Sonnet |
| Milestone research | 执行 |
| Slice research | **跳过** |
| Roadmap reassessment | 执行 |
| Context inline level | **Standard**:保留关键上下文,丢弃低信号附加内容 |
适合:大多数项目、日常开发。
### `quality`:完整上下文(不压缩)
所有阶段都会运行。所有上下文产物都会被内联。没有捷径。
| 维度 | 设置 |
|------|------|
| 所有 models | 用户配置的默认值 |
| 所有阶段 | 执行 |
| Context inline level | **Full**:全部内联 |
适合:复杂架构、需要深度 research 的 greenfield 项目、关键生产环境工作。
## Context Compression
每个 token profile 都会映射到一个 **inline level**,它控制在 dispatch prompt 里预加载多少上下文:
| Profile | Inline Level | 包含内容 |
|---------|--------------|----------|
| `budget` | `minimal` | Task plan、关键历史 summaries截断。不包含 decisions register、requirements、UAT template、secrets manifest。 |
| `balanced` | `standard` | Task plan、历史 summaries、slice plan、roadmap 摘要。不包含部分辅助 templates。 |
| `quality` | `full` | 全部内容:所有 plans、summaries、decisions、requirements、templates 和根文件。 |
### 压缩如何工作
Dispatch prompt builder 接受一个 `inlineLevel` 参数。在不同级别下,特定产物会被按规则裁剪:
**Minimal 级别的裁剪:**
- `buildExecuteTaskPrompt`:丢弃 decisions template并把历史 summaries 截断到只保留最近一个
- `buildPlanMilestonePrompt`:丢弃 `PROJECT.md``REQUIREMENTS.md`、decisions 以及 `secrets-manifest` 等补充 templates
- `buildCompleteSlicePrompt`:丢弃 requirements 和 UAT template 的内联
- `buildCompleteMilestonePrompt`:丢弃根级 GSD 文件内联
- `buildReassessRoadmapPrompt`:丢弃 project、requirements 和 decisions 文件
这些裁剪是累积式的:`standard` 会丢掉一部分,`minimal` 会丢掉更多;`full` 则保留全部上下文(也就是 v2.17 之前的行为)。
### 覆盖 Inline Level
Inline level 由 `token_profile` 推导而来。如果你想独立于 profile 控制阶段行为,请使用 `phases` 偏好设置:
```yaml
---
version: 1
token_profile: budget
phases:
skip_research: false # 覆盖:即使是 budget也执行 research
---
```
显式设置的 `phases` 总是优先于 profile 默认值。
<a id="complexity-based-task-routing"></a>
## 基于复杂度的 Task 路由
当启用 dynamic routing 时GSD 会根据复杂度对每个 task 做分类,并将其路由到合适的 model tier。简单的文档修复会使用更便宜的模型而复杂的架构工作会获得所需的推理能力。
> **前提条件:** Dynamic routing 需要在偏好设置里显式配置 `models`。如果没有 `models`routing 会被跳过,所有 phases 都会使用会话启动时的 model。Token profiles 会自动设置 `models`
> **上限行为:** 当 dynamic routing 启用时,每个 phase 中配置的 model 充当的是**上限**而不是固定绑定。Router 可以为更简单的工作降级到更便宜的 model但绝不会超过你配置的 model。
### 分类如何工作
Tasks 会通过分析 task plan 来分类:
| 信号 | Simple | Standard | Complex |
|------|--------|----------|---------|
| Step 数量 | ≤ 3 | 4-7 | ≥ 8 |
| 文件数 | ≤ 3 | 4-7 | ≥ 8 |
| 描述长度 | < 500 chars | 500-2000 | > 2000 chars |
| 代码块数 | — | — | ≥ 5 |
| 信号词 | 无 | 任意出现 | — |
**会阻止判定为 simple 的信号词:** `research``investigate``refactor``migrate``integrate``complex``architect``redesign``security``performance``concurrent``parallel``distributed``backward compat``migration``architecture``concurrency``compatibility`
空 plan 或格式错误的 plan 会默认归类到 `standard`(偏保守的选择)。
### Unit Type 默认值
非 task 单元也有内置的 tier 分配:
| Unit Type | 默认 Tier |
|-----------|-----------|
| `complete-slice``run-uat` | Light |
| `research-*``plan-*``execute-task``complete-milestone` | Standard |
| `replan-slice``reassess-roadmap` | Heavy |
| `hook/*` | Light |
### Model 路由
每个 tier 会映射到某类 model 配置:
| Tier | 对应 Model Phase Key | 常见 Model |
|------|----------------------|------------|
| Light | `completion` | Haikubudget/ 用户默认值 |
| Standard | `execution` | Sonnet / 用户默认值 |
| Heavy | `execution` | Opus / 用户默认值 |
如果配置了 `execution_simple`simple tasks 会优先使用它。`budget` profile 会自动把该键设为 Haiku。
<a id="budget-pressure"></a>
### 预算压力
当接近预算上限时,分类器会自动降低 tier
| 已使用预算 | 影响 |
|------------|------|
| < 50% | 不调整 |
| 50-75% | Standard → Light |
| 75-90% | Standard → Light |
| > 90% | 除 Heavy 之外全部 → LightHeavy → Standard |
这种逐步降级方式能尽量把最复杂工作的模型质量保留下来,同时随着预算逼近上限逐步降低成本。
## 自适应学习Routing History
GSD 会随着时间推移记录每个 tier 分配的成功 / 失败情况,并据此调整未来的分类。它默认自动生效,并持久化在 `.gsd/routing-history.json` 中。
### 工作方式
1. 每个工作单元完成后,系统会把结果(成功 / 失败)记录到对应的 unit type 和 tier 上
2. 结果会按 pattern 跟踪,例如 `execute-task``execute-task:docs`,并维护最近 50 条的滚动窗口
3. 如果某个 pattern 下某个 tier 的失败率超过 20%,未来相同 pattern 的分类会自动上调一个 tier
4. 系统也支持更细粒度的 tag pattern例如 `execute-task:test``execute-task:frontend`
### 用户反馈
你可以通过 `/gsd rate` 为最近完成的工作单元提交反馈:
```
/gsd rate over # model 太强了,下次更倾向便宜一点
/gsd rate ok # model 选得合适,不调整
/gsd rate under # model 太弱了,下次更倾向强一点
```
这些反馈的权重是自动结果的 2 倍。要求 dynamic routing 已启用(最近完成的单元必须带有 tier 数据)。
### 数据管理
```bash
# Routing history 按项目存储
.gsd/routing-history.json
# 清空历史以重置自适应学习
# (通过 routing-history 模块 API 完成)
```
反馈数组最多保留 200 条。每个 pattern 的结果统计使用 50 条滚动窗口,以防陈旧数据长期主导判断。
## 配置示例
### 成本优先配置
```yaml
---
version: 1
token_profile: budget
budget_ceiling: 25.00
models:
execution_simple: claude-haiku-4-5-20250414
---
```
### 使用自定义 Models 的平衡配置
```yaml
---
version: 1
token_profile: balanced
models:
planning:
model: claude-opus-4-6
fallbacks:
- openrouter/z-ai/glm-5
execution: claude-sonnet-4-6
---
```
### 面向关键工作的高质量配置
```yaml
---
version: 1
token_profile: quality
models:
planning: claude-opus-4-6
execution: claude-opus-4-6
---
```
### 按阶段覆盖
`token_profile` 会设置默认值,但显式偏好始终优先:
```yaml
---
version: 1
token_profile: budget
phases:
skip_research: false # 覆盖:保留 milestone research
models:
planning: claude-opus-4-6 # 覆盖:即使是 budget profileplanning 也用 Opus
---
```
## 这些机制如何协同
```
PREFERENCES.md
└─ token_profile: balanced
├─ resolveProfileDefaults() → model 默认值 + phase 跳过默认值
├─ resolveInlineLevel() → standard
│ └─ prompt builders 根据 level 决定纳入哪些上下文
├─ classifyUnitComplexity() → 路由到 execution / execution_simple model
│ ├─ task plan 分析steps、files、signals
│ ├─ unit type 默认值
│ ├─ budget pressure 调整
│ ├─ 从 routing-history.json 做自适应学习
│ └─ capability scoring`capability_routing: true` 时)
│ └─ 7 维 model profile × task requirement vectors
└─ context_management
├─ observation maskingbefore_provider_request hook
├─ tool result truncationtool_result_max_chars
└─ phase handoff anchors注入 prompt builders
```
Profile 会在 dispatch pipeline 的起点解析一次,并一路向下流动。每一层上,显式偏好都优先于 profile 默认值。
## Observation Masking
*引入于 v2.59.0*
在自动模式会话中tool results 会不断堆积在会话历史里并占用上下文窗口。Observation masking 会在每次 LLM 调用前,把早于最近 N 个 user turns 的 tool result 内容替换成轻量占位符。这样可以在**不增加任何 LLM 开销**的前提下减少 token 使用:不需要额外总结调用,也不会带来额外延迟。
Observation masking 在自动模式中默认开启。可通过偏好设置控制:
```yaml
context_management:
observation_masking: true # 默认true设为 false 可关闭)
observation_mask_turns: 8 # 保留最近 8 个 user turns 内的结果范围1-50
tool_result_max_chars: 800 # 单个 tool result 超过该长度时进行截断
```
### 工作方式
1. 每次 provider request 之前,`before_provider_request` hook 会检查 messages 数组
2. 早于阈值的 tool results`toolResult``bashExecution`)会被替换成 `[result masked — within summarized history]`
3. 最近的 tool results仍在保留窗口内会完整保留
4. 所有 assistant 和 user messages 始终保留,只有 tool result 内容会被 masking
它与现有的 compaction 系统配套masking 负责减少两次 compaction 之间的上下文压力,而 compaction 负责在窗口填满时执行完整上下文重置。
### Tool Result Truncation
单个 tool result 如果超过 `tool_result_max_chars`(默认 800会被加上 `…[truncated]` 标记后截断。这可以防止某一次特别大的工具输出独占上下文窗口。
## Phase Handoff Anchors
*引入于 v2.59.0*
当自动模式在 phases 之间切换research → planning → execution系统会把结构化 JSON anchors 写到 `.gsd/milestones/<mid>/anchors/<phase>.json`。下游 prompt builders 会自动注入这些 anchors让下一阶段继承前一阶段的意图、决策、阻塞点和下一步而不必重新从 artifact 文件里推断。
这能减少上下文漂移,也就是企业级 agent 失败案例中最常见的一类问题agent 在 phase 边界上丢失了之前的决策脉络。
Anchors 会在 `research-milestone``research-slice``plan-milestone``plan-slice` 成功完成后自动写入,不需要任何配置。
## Prompt Compression
*引入于 v2.29.0*
GSD 可以在退回到 section-boundary truncation 之前,先做确定性的 prompt compression。这样在上下文超预算时可以保留更多信息。
### 压缩策略
在偏好设置中配置:
```yaml
---
version: 1
compression_strategy: compress
---
```
可用策略有两个:
| 策略 | 行为 | 默认适用对象 |
|------|------|--------------|
| `truncate` | 在边界处整段丢弃 sectionv2.29 之前的行为) | `quality` profile |
| `compress` | 先做启发式文本压缩,如果仍超预算,再截断 | `budget``balanced` profiles |
Compression 会确定性地去掉冗余空白、缩短啰嗦表达、去重重复内容并删除低信息量样板文本,不涉及任何 LLM 调用。
### 上下文选择
控制文件如何内联进 prompt
```yaml
---
version: 1
context_selection: smart
---
```
| 模式 | 行为 | 默认适用对象 |
|------|------|--------------|
| `full` | 内联完整文件 | `balanced``quality` profiles |
| `smart` | 对大文件(>3KB使用 TF-IDF 语义分块,只纳入相关部分 | `budget` profile |
### 结构化数据压缩
`budget``balanced` 的 inline level 下decisions 和 requirements 会被格式化成更紧凑的表示方式,相比完整 markdown tables 可节省 30-50% tokens。
### Summary Distillation
如果某个 slice 有 3 个以上依赖 summary且总量超过 summary 预算GSD 会先提取结构化核心数据(`provides``requires``key_files``key_decisions`),丢弃冗长 prose 段落,然后才会退回到 section-boundary truncation。
### Cache Hit Rate Tracking
指标账本现在会为每个工作单元记录 `cacheHitRate`(输入 tokens 中来自缓存的比例),并提供 `aggregateCacheHitRate()` 用于统计整场会话的缓存表现。

View file

@ -0,0 +1,434 @@
# 故障排查
## `/gsd doctor`
内置诊断工具会校验 `.gsd/` 的完整性:
```
/gsd doctor
```
它会检查:
- 文件结构和命名约定
- roadmap ↔ slice ↔ task 的引用完整性
- 完成状态是否一致
- Git worktree 健康状态(仅 worktree 和 branch 模式none 模式跳过)
- 过期锁文件和孤儿运行时记录
## 常见问题
### 自动模式在同一个单元上循环
**症状:** 同一个工作单元(例如 `research-slice``plan-slice`)被反复派发,直到触发 dispatch 上限。
**原因:**
- 崩溃后的缓存过期:内存中的文件列表没有反映新产物
- LLM 没有生成预期的 artifact 文件
**解决:** 先运行 `/gsd doctor` 修复状态,然后执行 `/gsd auto` 恢复。如果问题持续存在,检查预期 artifact 文件是否确实已经写到磁盘。
### 自动模式因 “Loop detected” 停止
**原因:** 同一个单元连续两次没有生成预期 artifact。
**解决:** 检查 task plan 是否足够清晰。如果 plan 存在歧义,先手动澄清,再执行 `/gsd auto` 恢复。
### Worktree 中出现了错误文件
**症状:** Planning 产物或代码被写到了错误目录。
**原因:** LLM 把内容写回了主仓库,而不是 worktree。
**解决:** 该问题已在 v2.14+ 修复。如果你仍在旧版本,请更新。现在 dispatch prompt 已包含明确的工作目录指令。
### 安装后出现 `command not found: gsd`
**症状:** `npm install -g gsd-pi` 成功,但系统找不到 `gsd`
**原因:** npm 的全局 bin 目录没有加入 shell 的 `$PATH`
**解决:**
```bash
# 找出 npm 安装二进制的目录
npm prefix -g
# 输出:/opt/homebrewApple Silicon或 /usr/localIntel Mac
# 如果缺失,把 bin 目录加入 PATH
echo 'export PATH="$(npm prefix -g)/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
```
**临时方案:** 直接执行 `npx gsd-pi`,或使用 `$(npm prefix -g)/bin/gsd`
**常见原因:**
- **Homebrew Node**:理论上 `/opt/homebrew/bin` 应该在 PATH 里,但如果 shell profile 没有初始化 Homebrew就可能缺失
- **版本管理器nvm、fnm、mise**:全局 bin 路径是按版本区分的,需确保版本管理器正确初始化
- **oh-my-zsh**`gitfast` 插件会把 `gsd` alias 到 `git svn dcommit`。可通过 `alias gsd` 检查,并在需要时取消 alias
### `npm install -g gsd-pi` 失败
**常见原因:**
- 缺少 workspace packages已在 v2.10.4+ 修复
- Linux 上 `postinstall` 卡住Playwright `--with-deps` 触发 sudo已在 v2.3.6+ 修复
- Node.js 版本过低:要求 ≥ 22.0.0
### 自动模式中的 provider 错误
**症状:** 自动模式因为 provider 错误暂停(限流、服务端错误、认证失败)。
**GSD 的处理方式v2.26**
| 错误类型 | 自动恢复? | 延迟 |
|----------|------------|------|
| Rate limit429、`too many requests` | ✅ 是 | `retry-after` 头或默认 60 秒 |
| Server error500、502、503、`overloaded` | ✅ 是 | 30 秒 |
| Auth / billing`unauthorized``invalid key` | ❌ 否 | 需要手动恢复 |
对于瞬时错误GSD 会短暂停顿后自动继续。对于永久性错误,建议配置 fallback models
```yaml
models:
execution:
model: claude-sonnet-4-6
fallbacks:
- openrouter/minimax/minimax-m2.5
```
**Headless 模式:** `gsd headless auto` 在进程崩溃时会自动重启整个进程(默认 3 次,带指数退避)。与 provider 错误自动恢复配合后,能支持真正的夜间无人值守运行。
常见的 provider 配置问题role 错误、streaming 错误、model ID 不匹配)见 [Provider 设置指南:常见坑点](./providers.md#common-pitfalls)。
### 达到预算上限
**症状:** 自动模式因 “Budget ceiling reached” 暂停。
**解决:** 提高偏好设置中的 `budget_ceiling`,或者切换到 `budget` token profile 降低每个工作单元成本,然后再执行 `/gsd auto` 恢复。
### 过期锁文件
**症状:** 自动模式无法启动,提示另一个会话正在运行。
**解决:** GSD 会自动检测过期锁:如果持有锁的 PID 已死亡,则在下次 `/gsd auto` 时清理并重新获取锁。它也会处理 `proper-lockfile` 崩溃后遗留的 `.gsd.lock/` 目录。如果自动恢复失败,可手动删除 `.gsd/auto.lock``.gsd.lock/`
```bash
rm -f .gsd/auto.lock
rm -rf "$(dirname .gsd)/.gsd.lock"
```
### Git merge 冲突
**症状:** Worktree merge 在 `.gsd/` 文件上失败。
**解决:** GSD 会自动解决 `.gsd/` 运行时文件上的冲突。对于代码文件的内容冲突LLM 会先获得一次 fix-merge 会话进行自动修复;若失败,则需要手动解决。
### Pre-dispatch 提示 milestone integration branch 已不存在
**症状:** 自动模式或 `/gsd doctor` 报告某个 milestone 记录的 integration branch 已经不在 git 中。
**这意味着什么:** 该 milestone 的 `.gsd/milestones/<MID>/<MID>-META.json` 里仍然记录着启动时的 branch但该 branch 之后被重命名或删除了。
**当前行为:**
- 如果 GSD 能确定性地恢复到一个安全 branch就不会再直接 hard-stop 自动模式
- 安全回退的顺序是:
- 显式配置且存在的 `git.main_branch`
- 仓库自动检测到的默认 integration branch例如 `main``master`
- 在这种情况下,`/gsd doctor` 会给出 warning`/gsd doctor fix` 会把过期的 metadata 改写为当前有效 branch
- 如果无法确定安全回退 branchGSD 仍会阻止继续运行
**解决:**
- 先执行 `/gsd doctor fix`,在安全回退很明显时自动改写过期 metadata
- 如果 GSD 仍然阻塞,则请重新创建缺失 branch或更新 git 偏好设置,让 `git.main_branch` 指向一个真实存在的 branch
### 写 `.gsd/` 文件时出现瞬时 `EBUSY` / `EPERM` / `EACCES`
**症状:** 在 Windows 上,自动模式或 doctor 在更新 `.gsd/` 文件时偶发 `EBUSY``EPERM``EACCES`
**原因:** 杀毒软件、索引器、编辑器或文件监视器可能会在 GSD 执行原子 rename 的瞬间,短暂锁住目标文件或临时文件。
**当前行为:** GSD 现在会对这类瞬时 rename 失败做短时、有上界的退避重试;这样既能覆盖短暂锁竞争,也不会因为真正的文件系统问题而无限挂起。
**解决:**
- 重新执行操作;大多数瞬时锁竞争会很快自行解除
- 如果错误持续,关闭可能占用该文件的工具后再试
- 如果反复失败,运行 `/gsd doctor`,确认仓库状态依旧健康,并记录具体路径与错误码
### Node v24 Web 启动失败
**症状:** 在 Node v24 上执行 `gsd --web` 时,报 `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`
**原因:** Node v24 修改了对 `node_modules` 的 type stripping 行为,导致 Next.js Web 构建失败。
**解决:** 已在 v2.42.0+ 修复(#1864)。升级到最新版本。
### 孤儿 Web server 进程
**症状:** `gsd --web` 因端口 3000 已被占用而失败,但实际上并没有运行中的 GSD 会话。
**原因:** 上一次 Web server 退出时未能清理进程。
**解决:** 已在 v2.42.0+ 修复。现在 GSD 会自动清理过期的 Web server 进程。如果你还在旧版本,可手动终止孤儿进程:`lsof -ti:3000 | xargs kill`
### 非 JS 项目被 worktree health check 阻挡
**症状:** 在不使用 Node.js 的项目(例如 Rust、Go、Pythonworktree health check 失败或阻塞自动模式。
**原因:** 在 v2.42.0 之前worktree health check 只识别 JavaScript 生态。
**解决:** 已在 v2.42.0+ 修复(#1860)。现在 health check 已支持 17+ 生态。升级到最新版本。
### 德语 / 非英语 locale 下的 git 错误
**症状:** 当系统 locale 不是英语例如德语Git 命令失败或输出异常。
**原因:** GSD 之前假设 git 输出永远是英文。
**解决:** 已在 v2.42.0+ 修复。现在所有 git 命令都会强制 `LC_ALL=C`,从而无论系统 locale 如何,都保证 git 输出一致为英文。
## MCP Client 问题
### `mcp_servers` 显示没有已配置 servers
**症状:** `mcp_servers` 报告没有配置任何 server。
**常见原因:**
- 当前项目里不存在 `.mcp.json``.gsd/mcp.json`
- 配置文件不是合法 JSON
- 你是在另一个项目目录中配置的 server但当前启动 GSD 的目录不同
**解决:**
- 把 server 配置加到 `.mcp.json``.gsd/mcp.json`
- 确认文件能被正常解析为 JSON
- 重新执行 `mcp_servers(refresh=true)`
### `mcp_discover` 超时
**症状:** `mcp_discover` 因超时失败。
**常见原因:**
- Server 进程启动了,但没有完成 MCP 握手
- 配置的命令指向一个启动时会卡住的脚本
- Server 正在等待某个不可用依赖或后端服务
**解决:**
- 在 GSD 外部直接运行该命令,确认 server 能真正启动
- 检查后端 URL 或依赖服务是否可达
- 如果是本地自定义 server确认它使用的是 MCP SDK 或正确的 stdio 协议实现
### `mcp_discover` 报 connection closed
**症状:** `mcp_discover` 立即失败,并提示连接被关闭。
**常见原因:**
- 可执行文件路径错误
- 脚本路径错误
- 缺失运行时依赖
- Server 在响应前就崩溃了
**解决:**
- 确认 `command``args` 路径正确且尽量使用绝对路径
- 手动运行命令,查看导入 / 运行时错误
- 检查配置中的解释器或运行时在当前机器上是否存在
### `mcp_call` 因缺少必填参数失败
**症状:** MCP tool 已成功发现,但调用时因缺少必填字段而校验失败。
**常见原因:**
- 调用形状写错了
- 目标 server 的 tool schema 已更新
- 你调用的是旧 server 定义或旧分支构建
**解决:**
- 重新执行 `mcp_discover(server="name")`,确认实际要求的参数名
- 按 `mcp_call(server="name", tool="tool_name", args={...})` 的形式调用
- 如果你正在开发 GSD 本身,在 schema 变更后重新执行 `npm run build`
### 本地 stdio server 手动可用,但在 GSD 中不可用
**症状:** 手动执行 server 命令没有问题,但 GSD 连接不上。
**常见原因:**
- Server 依赖某些 GSD 不会继承的 shell 状态
- 相对路径只有在另一个 working directory 中才成立
- 需要的环境变量存在于你的 shell 中,但没有写进 MCP 配置
**解决:**
- 对 `command` 和脚本参数都使用绝对路径
- 把所需环境变量写进 MCP 配置的 `env`
- 有必要时,在 server 定义里显式设置 `cwd`
### Session lock 被另一个终端中的 `/gsd` 抢走
**症状:** 在第二个终端运行 `/gsd`step mode正在运行的自动模式会话失去了锁。
**解决:** 已在 v2.36.0 修复。现在裸 `/gsd` 不会再从运行中的自动模式会话手里抢 session lock。升级到最新版本。
### Worktree 中的提交落到了 main而不是 `milestone/<MID>` 分支
**症状:** 自动模式在 worktree 中提交时,最终落在了 `main`,而不是 `milestone/<MID>`
**解决:** 已在 v2.37.1 修复。现在 dispatch 前会重新校正 CWD并在失败时清理过期 merge 状态。升级到最新版本。
### Extension loader 因 subpath export 错误而失败
**症状:** 扩展加载时报 `Cannot find module`,并且错误信息引用了 npm subpath exports。
**原因:** Extension loader 中的动态导入过去无法解析 npm subpath exports例如 `@pkg/foo/bar`)。
**解决:** 已在 v2.38+ 修复。现在 extension loader 会自动解析 npm subpath exports并为动态导入创建 `node_modules` symlink。升级到最新版本。
## 恢复流程
### 重置自动模式状态
```bash
rm .gsd/auto.lock
rm .gsd/completed-units.json
```
然后执行 `/gsd auto`,从当前磁盘状态重新开始。
### 重置路由历史
如果自适应模型路由给出了糟糕的结果,可以清空路由历史:
```bash
rm .gsd/routing-history.json
```
### 完整重建状态
```
/gsd doctor
```
Doctor 会从磁盘上的 plan 和 roadmap 文件重建 `STATE.md`,并修复检测到的不一致项。
## 获取帮助
- **GitHub Issues** [github.com/gsd-build/GSD-2/issues](https://github.com/gsd-build/GSD-2/issues)
- **Dashboard** `Ctrl+Alt+G``/gsd status`,查看实时诊断信息
- **Forensics** `/gsd forensics`,用于对自动模式失败做结构化事后分析
- **Session logs** `.gsd/activity/` 中包含用于崩溃取证的 JSONL 会话转储
## iTerm2 专属问题
### Ctrl+Alt 快捷键触发了错误动作(例如 Ctrl+Alt+G 打开了外部编辑器,而不是 GSD dashboard
**症状:** 按下 Ctrl+Alt+G 后会触发外部编辑器提示Ctrl+G而不是 GSD dashboard。其它 Ctrl+Alt 快捷键也表现得像它们对应的 Ctrl-only 快捷键。
**原因:** iTerm2 默认的 Left Option Key 设置是 “Normal”这会吞掉 Ctrl+Alt 组合中的 Alt 修饰键。终端实际只收到了 Ctrl所以 Ctrl+Alt+G 最终变成 Ctrl+G。
**解决:** 在 iTerm2 中进入 **Profiles → Keys → General**,把 **Left Option Key** 改成 **Esc+**。这样 Alt / Option 会发送 escape 前缀,终端应用就能正确识别 Ctrl+Alt 快捷键。
## Windows 专属问题
### Windows 上 LSP 返回 ENOENTMSYS2 / Git Bash
**症状:** LSP 初始化因 `ENOENT` 失败,或者把 `/c/Users/...` 这类 POSIX 路径错误地解析为 `C:\Users\...`
**原因:** MSYS2 / Git Bash 中的 `which` 命令返回的是 POSIX 风格路径,而 Node.js 的 `spawn()` 无法正确解析。
**解决:** 已在 v2.29+ 修复Windows 现在改用 `where.exe`。升级到最新版本。
### 构建 WXT / 浏览器扩展时出现 EBUSY
**症状:** 构建浏览器扩展时出现 `EBUSY: resource busy or locked, rmdir .output/chrome-mv3`
**原因:** Chromium 浏览器仍然从构建输出目录加载着该扩展,导致目录无法删除。
**解决:** 关闭浏览器中的该扩展,或者在 WXT 配置里使用不同的 `outDirTemplate`,避开被锁住的目录。
## 数据库问题
### “GSD database is not available”
**症状:** `gsd_decision_save`(及其别名 `gsd_save_decision`)、`gsd_requirement_update`(及其别名 `gsd_update_requirement`)或 `gsd_summary_save`(及其别名 `gsd_save_summary`)报这个错误。
**原因:** SQLite 数据库未初始化。这个问题会出现在 v2.29 之前的手动 `/gsd` 会话(非自动模式)中。
**解决:** 已在 v2.29+ 修复。现在数据库会在第一次 tool call 时自动初始化。升级到最新版本。
## Verification 问题
### Verification gate 因 shell 语法错误失败
**症状:** 在 verification 阶段出现 `stderr: /bin/sh: 1: Syntax error: "(" unexpected`
**原因:** 某个描述性字符串(例如 `All 10 checks pass (build, lint)`)被误当成 shell 命令执行。这通常发生在 task plans 的 `verify:` 字段里写了 prose而不是实际命令。
**解决:** 已在 v2.29+ 修复,现在偏好命令会先通过 `isLikelyCommand()` 过滤。请确保偏好中的 `verification_commands` 只包含合法 shell 命令,而不是文字描述。
## LSPLanguage Server Protocol
### “LSP isn't available in this workspace”
GSD 会根据项目文件自动检测 language servers例如 `package.json` → TypeScript、`Cargo.toml` → Rust、`go.mod` → Go。如果没有检测到 serveragent 会跳过 LSP 功能。
**查看状态:**
```
lsp status
```
它会显示哪些 servers 已经激活;如果一个都没找到,也会说明原因,包括发现了哪些项目标记、但缺失了哪些 server 命令。
**常见修复方式:**
| 项目类型 | 安装命令 |
|----------|----------|
| TypeScript / JavaScript | `npm install -g typescript-language-server typescript` |
| Python | `pip install pyright``pip install python-lsp-server` |
| Rust | `rustup component add rust-analyzer` |
| Go | `go install golang.org/x/tools/gopls@latest` |
安装完成后,执行 `lsp reload` 即可重新检测,无需重启 GSD。
## Notifications
<a id="notifications-not-appearing-on-macos"></a>
### macOS 上通知不显示
**症状:** 偏好中已设置 `notifications.enabled: true`,但自动模式期间没有任何桌面通知(没有 milestone 完成提示、预算预警或错误通知),同时日志里也没有报错。
**原因:** GSD 在 macOS 上会把 `osascript display notification` 作为回退方案。这个命令的通知归属你的终端应用Ghostty、iTerm2、Alacritty、Kitty、Warp 等)。如果该终端应用在 System Settings → Notifications 中没有权限macOS 会静默丢弃通知,而 `osascript` 仍然返回 0不会报错。
很多终端应用只有在成功送出过至少一条通知后,才会出现在通知设置面板里,这就形成了“先能通知,系统才给你配置通知”的鸡生蛋蛋生鸡问题。
**推荐修复方式:** 安装 `terminal-notifier`,它会注册为独立的 Notification Center 应用:
```bash
brew install terminal-notifier
```
GSD 在检测到 `terminal-notifier` 可用时会自动优先使用它。首次使用时macOS 会弹出通知权限请求,这是预期行为。
**替代修复方式:** 进入 **System Settings → Notifications**,为你的终端应用启用通知。如果终端应用不在列表中,可以先在 Terminal.app 中手动发送一条测试通知,注册出 “Script Editor”
```bash
osascript -e 'display notification "test" with title "GSD"'
```
**验证:** 完成任一修复后,用下面命令测试:
```bash
terminal-notifier -title "GSD" -message "working!" -sound Glass
```

View file

@ -0,0 +1,104 @@
# 工作流可视化器
*引入于 v2.19.0*
工作流可视化器是一个全屏 TUI 叠层视图,以交互式四标签页的形式展示项目进度、依赖关系、成本指标和执行时间线。
## 打开可视化器
```
/gsd visualize
```
或者配置为在 milestone 完成后自动显示:
```yaml
auto_visualize: true
```
## 标签页
可通过 `Tab``1`-`4` 或方向键切换标签页。
### 1. 进度
以树状视图展示 milestones、slices 和 tasks 的完成状态:
```
M001: User Management 3/6 tasks ⏳
✅ S01: Auth module 3/3 tasks
✅ T01: Core types
✅ T02: JWT middleware
✅ T03: Login flow
⏳ S02: User dashboard 1/2 tasks
✅ T01: Layout component
⬜ T02: Profile page
⬜ S03: Admin panel 0/1 tasks
```
已完成项显示勾选,进行中项显示转圈,待处理项显示空框。每一层级也会显示 task 数量和完成百分比。
如果某个 milestone 经过 discussion 阶段,还会显示**讨论状态**,用于表明需求是否已经记录,以及讨论停留在哪个状态。
### 2. 依赖
用 ASCII 依赖图展示 slices 之间的关系:
```
S01 ──→ S02 ──→ S04
└───→ S03 ──↗
```
它会把 roadmap 中的 `depends:` 字段可视化出来,便于快速判断哪些 slices 被阻塞、哪些可以继续推进。
### 3. 指标
通过柱状图展示成本和 Token 使用情况:
- **按阶段**research、planning、execution、completion、reassessment
- **按 slice**:每个 slice 的成本以及累计总额
- **按模型**:哪些模型消耗了最多预算
数据来自 `.gsd/metrics.json`
### 4. 时间线
按时间顺序展示执行历史,包括:
- 单元类型和 ID
- 开始 / 结束时间戳
- 持续时间
- 使用的模型
- Token 数量
条目按执行时间排序,因此可以看到自动模式的完整派发历史。
## 控制
| 按键 | 动作 |
|------|------|
| `Tab` | 下一个标签页 |
| `Shift+Tab` | 上一个标签页 |
| `1`-`4` | 直接跳转到标签页 |
| `↑` / `↓` | 在当前标签页内滚动 |
| `Escape` / `q` | 关闭可视化器 |
## 自动刷新
可视化器每 2 秒从磁盘刷新一次数据,因此即使它和自动模式会话同时打开,也能保持最新状态。
## HTML 导出v2.26
如果需要在终端外部分享报告,可以使用 `/gsd export --html`。它会在 `.gsd/reports/` 中生成一个自包含的 HTML 文件,包含与 TUI 可视化器相同的数据进度树、依赖图SVG DAG、成本 / Token 柱状图、执行时间线、变更日志和知识库。所有 CSS 和 JS 都会内联,无外部依赖,也可以在任意浏览器中打印为 PDF。
自动生成的 `index.html` 会集中列出所有报告,并显示跨 milestones 的推进指标。
```yaml
auto_report: true # 在 milestone 完成后自动生成(默认开启)
```
## 配置
```yaml
auto_visualize: true # 在 milestone 完成后显示可视化器
```

View file

@ -0,0 +1,67 @@
# Web 界面
> 新增于 v2.41.0
GSD 提供了基于浏览器的 Web 界面,用于项目管理、实时进度监控以及多项目支持。
## 快速开始
```bash
gsd --web
```
这会启动一个本地 Web 服务器,并在默认浏览器中打开 GSD 仪表板。
### CLI 参数v2.42.0
```bash
gsd --web --host 0.0.0.0 --port 8080 --allowed-origins "https://example.com"
```
| 参数 | 默认值 | 说明 |
|------|--------|------|
| `--host` | `localhost` | Web 服务器监听地址 |
| `--port` | `3000` | Web 服务器端口 |
| `--allowed-origins` | (无) | 允许的 CORS 来源列表,逗号分隔 |
## 功能
- **项目管理**:在可视化仪表板中查看 milestones、slices 和 tasks
- **实时进度**:通过 server-sent events 在自动模式执行期间推送状态更新
- **多项目支持**:通过 `?project=` URL 参数,在单个浏览器标签页中管理多个项目
- **切换项目根目录**:无需重启服务器即可在 Web UI 中切换项目目录v2.44
- **首次引导流程**:可在浏览器中完成 API key 设置和 provider 配置
- **模型选择**:直接从 Web UI 切换模型和 provider
## 架构
Web 界面基于 Next.js 构建,并通过桥接服务与 GSD 后端通信。每个项目都会拥有自己的 bridge 实例,以便在并发会话中保持隔离。
关键组件:
- `ProjectBridgeService`:按项目分配的命令路由和 SSE 订阅服务
- `getProjectBridgeServiceForCwd()`:根据项目路径返回独立实例的注册表
- `resolveProjectCwd()`:从请求 URL 中读取 `?project=`,若不存在则回退到 `GSD_WEB_PROJECT_CWD`
## 配置
默认情况下Web 服务器监听在 `localhost:3000`。如需覆盖,可使用 `--host``--port``--allowed-origins`(见上面的 CLI 参数)。
### 环境变量
| 变量 | 说明 |
|------|------|
| `GSD_WEB_PROJECT_CWD` | 当未指定 `?project=` 时使用的默认项目路径 |
## Node v24 兼容性
Node v24 对类型剥离type stripping做了破坏性改动曾导致 Web 启动时报 `ERR_UNSUPPORTED_NODE_MODULES_TYPE_STRIPPING`。该问题已在 v2.42.0+ 中修复(#1864)。如果你仍然遇到这个错误,请升级 GSD。
## 认证令牌持久化
从 v2.42.0 起Web UI 会把认证令牌持久化到 `sessionStorage`,因此页面刷新后不会丢失登录态(#1877)。在此之前,每次刷新都需要重新认证。
## 平台说明
- **Windows**:由于 Next.js webpack 在系统目录上会触发 EPERM 问题Windows 下会跳过 Web 构建。CLI 仍然可完整使用。
- **macOS / Linux**:完整支持。

View file

@ -0,0 +1,103 @@
# 团队协作
GSD 支持多人并行工作流,让多个开发者可以同时在同一个仓库中工作。
## 设置
### 1. 启用 Team Mode
为团队使用配置 GSD 的最简单方法,是在项目偏好中设置 `mode: team`。这会一次性开启唯一 milestone ID、推送分支和预合并检查
```yaml
# .gsd/PREFERENCES.md项目级提交到 git
---
version: 1
mode: team
---
```
这相当于手动设置 `unique_milestone_ids: true``git.push_branches: true``git.pre_merge_check: true` 以及其他适合团队协作的默认值。你仍然可以覆盖单个选项,例如如果团队偏好自动推送,也可以在 `mode: team` 基础上再加 `git.auto_push: true`
你也可以不使用 mode而是单独配置每一项设置详见 [Git 策略](git-strategy.md))。
### 2. 配置 `.gitignore`
共享规划产物milestones、roadmaps、decisions同时把运行时文件保留在本地
```bash
# ── GSD运行时 / 临时文件(按开发者、按会话隔离)──────
.gsd/auto.lock
.gsd/completed-units.json
.gsd/STATE.md
.gsd/metrics.json
.gsd/activity/
.gsd/runtime/
.gsd/worktrees/
.gsd/milestones/**/continue.md
.gsd/milestones/**/*-CONTINUE.md
```
**会共享的内容**(提交到 git
- `.gsd/PREFERENCES.md`:项目偏好
- `.gsd/PROJECT.md`:持续维护的项目描述
- `.gsd/REQUIREMENTS.md`:需求契约
- `.gsd/DECISIONS.md`:架构决策
- `.gsd/milestones/`roadmaps、plans、summaries 和 research
**仅保留本地的内容**gitignore
- 锁文件、指标、状态缓存、运行时记录、worktrees、活动日志
### 3. 提交偏好设置
```bash
git add .gsd/PREFERENCES.md
git commit -m "chore: enable GSD team workflow"
```
## `commit_docs: false`
如果团队里只有部分成员使用 GSD或者公司策略要求仓库保持干净
```yaml
git:
commit_docs: false
```
这会把整个 `.gsd/` 加入 `.gitignore`,让所有产物都保留在本地。这样使用 GSD 的开发者仍然能获得结构化规划的好处,而不会影响不使用 GSD 的同事。
## 迁移现有项目
如果你当前项目里对 `.gsd/` 做了整目录忽略:
1. 确保当前没有进行中的 milestones工作区状态干净
2. 按上面的选择性规则更新 `.gitignore`
3. 在 `.gsd/PREFERENCES.md` 中添加 `unique_milestone_ids: true`
4. 如有需要,重命名现有 milestones 以使用唯一 ID
```
I have turned on unique milestone ids, please update all old milestone
ids to use this new format e.g. M001-abc123 where abc123 is a random
6 char lowercase alpha numeric string. Update all references in all
.gsd file contents, file names and directory names. Validate your work
once done to ensure referential integrity.
```
5. 提交修改
## 并行开发
多个开发者可以同时对不同 milestones 运行自动模式。每个开发者都会:
- 获得自己的 worktree`.gsd/worktrees/<MID>/`,已加入 gitignore
- 在独立的 `milestone/<MID>` 分支上工作
- 独立地 squash merge 回主分支
milestone 依赖可以通过 `M00X-CONTEXT.md` frontmatter 声明:
```yaml
---
depends_on: [M001-eh88as]
---
```
GSD 会强制要求上游依赖 milestone 先完成,之后才会启动下游工作。