gsd-pi 2.76.0 → 2.77.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (536) hide show
  1. package/README.md +45 -25
  2. package/dist/claude-cli-check.js +32 -3
  3. package/dist/mcp-server.d.ts +7 -0
  4. package/dist/mcp-server.js +35 -1
  5. package/dist/onboarding.js +45 -0
  6. package/dist/resource-loader.d.ts +1 -1
  7. package/dist/resource-loader.js +2 -8
  8. package/dist/resources/agents/researcher.md +1 -1
  9. package/dist/resources/extensions/claude-code-cli/readiness.js +31 -8
  10. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +77 -17
  11. package/dist/resources/extensions/gsd/auto/loop.js +9 -0
  12. package/dist/resources/extensions/gsd/auto/phases.js +104 -11
  13. package/dist/resources/extensions/gsd/auto/run-unit.js +38 -2
  14. package/dist/resources/extensions/gsd/auto/session.js +22 -1
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -3
  16. package/dist/resources/extensions/gsd/auto-model-selection.js +53 -16
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +25 -2
  18. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  19. package/dist/resources/extensions/gsd/auto-recovery.js +32 -1
  20. package/dist/resources/extensions/gsd/auto-start.js +58 -57
  21. package/dist/resources/extensions/gsd/auto-verification.js +33 -0
  22. package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
  23. package/dist/resources/extensions/gsd/auto.js +70 -28
  24. package/dist/resources/extensions/gsd/blocked-models.js +68 -0
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +93 -1
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
  27. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
  28. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +3 -0
  29. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
  30. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +52 -6
  31. package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -23
  32. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  33. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  34. package/dist/resources/extensions/gsd/commands-extract-learnings.js +54 -89
  35. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  36. package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
  37. package/dist/resources/extensions/gsd/complexity-classifier.js +5 -3
  38. package/dist/resources/extensions/gsd/db-writer.js +88 -16
  39. package/dist/resources/extensions/gsd/doctor-git-checks.js +23 -29
  40. package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
  41. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
  42. package/dist/resources/extensions/gsd/error-classifier.js +31 -3
  43. package/dist/resources/extensions/gsd/exec-history.js +120 -0
  44. package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
  45. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  46. package/dist/resources/extensions/gsd/gsd-db.js +168 -23
  47. package/dist/resources/extensions/gsd/guided-flow.js +190 -1
  48. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  49. package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
  50. package/dist/resources/extensions/gsd/init-wizard.js +15 -1
  51. package/dist/resources/extensions/gsd/key-manager.js +28 -0
  52. package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
  53. package/dist/resources/extensions/gsd/memory-store.js +19 -0
  54. package/dist/resources/extensions/gsd/model-router.js +36 -3
  55. package/dist/resources/extensions/gsd/pre-execution-checks.js +44 -9
  56. package/dist/resources/extensions/gsd/preferences-types.js +9 -0
  57. package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
  58. package/dist/resources/extensions/gsd/preferences.js +17 -17
  59. package/dist/resources/extensions/gsd/prompt-loader.js +22 -7
  60. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  61. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  62. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  63. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  64. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  65. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -2
  66. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  67. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  68. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
  69. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  70. package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
  71. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  72. package/dist/resources/extensions/gsd/state.js +43 -4
  73. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  74. package/dist/resources/extensions/gsd/tools/complete-milestone.js +16 -10
  75. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
  76. package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
  77. package/dist/resources/extensions/gsd/tools/memory-tools.js +26 -1
  78. package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
  79. package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
  80. package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
  81. package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  82. package/dist/resources/extensions/gsd/worktree-resolver.js +50 -10
  83. package/dist/resources/extensions/search-the-web/command-search-provider.js +5 -4
  84. package/dist/resources/extensions/search-the-web/native-search.js +45 -13
  85. package/dist/resources/skills/api-design/SKILL.md +190 -0
  86. package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
  87. package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
  88. package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
  89. package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
  90. package/dist/resources/skills/forensics/SKILL.md +153 -0
  91. package/dist/resources/skills/grill-me/SKILL.md +93 -0
  92. package/dist/resources/skills/handoff/SKILL.md +121 -0
  93. package/dist/resources/skills/observability/SKILL.md +174 -0
  94. package/dist/resources/skills/security-review/SKILL.md +181 -0
  95. package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
  96. package/dist/resources/skills/tdd/SKILL.md +112 -0
  97. package/dist/resources/skills/verify-before-complete/SKILL.md +98 -0
  98. package/dist/resources/skills/write-docs/SKILL.md +82 -0
  99. package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
  100. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  101. package/dist/web/standalone/.next/BUILD_ID +1 -1
  102. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  103. package/dist/web/standalone/.next/build-manifest.json +2 -2
  104. package/dist/web/standalone/.next/required-server-files.json +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/index.html +1 -1
  122. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  129. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  130. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/middleware-manifest.json +1 -1
  132. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  133. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  134. package/dist/web/standalone/server.js +1 -1
  135. package/dist/welcome-screen.js +6 -1
  136. package/dist/wizard.js +2 -0
  137. package/package.json +1 -1
  138. package/packages/daemon/package.json +2 -2
  139. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  140. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  141. package/packages/mcp-server/dist/remote-questions.js +732 -0
  142. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  143. package/packages/mcp-server/dist/server.d.ts +7 -0
  144. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  145. package/packages/mcp-server/dist/server.js +70 -8
  146. package/packages/mcp-server/dist/server.js.map +1 -1
  147. package/packages/mcp-server/dist/session-manager.d.ts +14 -0
  148. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  149. package/packages/mcp-server/dist/session-manager.js +49 -1
  150. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  151. package/packages/mcp-server/dist/workflow-tools.d.ts +1 -1
  152. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  153. package/packages/mcp-server/dist/workflow-tools.js +163 -25
  154. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  155. package/packages/mcp-server/package.json +4 -3
  156. package/packages/mcp-server/src/mcp-server.test.ts +67 -0
  157. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  158. package/packages/mcp-server/src/remote-questions.ts +916 -0
  159. package/packages/mcp-server/src/server.ts +89 -14
  160. package/packages/mcp-server/src/session-manager.ts +43 -1
  161. package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
  162. package/packages/mcp-server/src/workflow-tools.ts +215 -43
  163. package/packages/mcp-server/tsconfig.test.json +19 -0
  164. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  165. package/packages/native/package.json +1 -1
  166. package/packages/pi-agent-core/dist/agent-loop.js +12 -0
  167. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  168. package/packages/pi-agent-core/dist/types.d.ts +30 -0
  169. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  170. package/packages/pi-agent-core/dist/types.js.map +1 -1
  171. package/packages/pi-agent-core/package.json +1 -1
  172. package/packages/pi-agent-core/src/agent-loop.ts +14 -0
  173. package/packages/pi-agent-core/src/types.ts +34 -0
  174. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  175. package/packages/pi-ai/dist/models/custom.d.ts +38 -0
  176. package/packages/pi-ai/dist/models/custom.d.ts.map +1 -1
  177. package/packages/pi-ai/dist/models/custom.js +41 -0
  178. package/packages/pi-ai/dist/models/custom.js.map +1 -1
  179. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  180. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  181. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
  182. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
  183. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
  184. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
  185. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  186. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  187. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  188. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  189. package/packages/pi-ai/dist/providers/anthropic.js +13 -4
  190. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  191. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  192. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  193. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  194. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  195. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  196. package/packages/pi-ai/dist/providers/openai-completions.js +60 -15
  197. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  198. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  199. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  200. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  201. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  202. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts +17 -0
  203. package/packages/pi-ai/dist/providers/think-tag-parser.d.ts.map +1 -0
  204. package/packages/pi-ai/dist/providers/think-tag-parser.js +75 -0
  205. package/packages/pi-ai/dist/providers/think-tag-parser.js.map +1 -0
  206. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts +2 -0
  207. package/packages/pi-ai/dist/providers/think-tag-parser.test.d.ts.map +1 -0
  208. package/packages/pi-ai/dist/providers/think-tag-parser.test.js +41 -0
  209. package/packages/pi-ai/dist/providers/think-tag-parser.test.js.map +1 -0
  210. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  211. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
  212. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  213. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
  214. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  215. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  216. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
  217. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  218. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
  219. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
  220. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
  221. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
  222. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  223. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
  224. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  225. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
  226. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
  227. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
  228. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
  229. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
  230. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
  231. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
  232. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
  233. package/packages/pi-ai/package.json +1 -1
  234. package/packages/pi-ai/src/models/custom.ts +42 -0
  235. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  236. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
  237. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  238. package/packages/pi-ai/src/providers/anthropic.ts +15 -4
  239. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  240. package/packages/pi-ai/src/providers/openai-completions.ts +57 -16
  241. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  242. package/packages/pi-ai/src/providers/think-tag-parser.test.ts +44 -0
  243. package/packages/pi-ai/src/providers/think-tag-parser.ts +94 -0
  244. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
  245. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
  246. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
  247. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
  248. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
  249. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
  250. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
  251. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  252. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +3 -2
  253. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  254. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +2 -0
  255. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  256. package/packages/pi-coding-agent/dist/core/agent-session.js +32 -2
  257. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  258. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  259. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  262. package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
  263. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  264. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +35 -2
  265. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
  267. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +205 -2
  269. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
  272. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
  273. package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
  274. package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
  275. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
  276. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
  277. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
  278. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
  279. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  282. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts +3 -1
  284. package/packages/pi-coding-agent/dist/core/model-discovery.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/model-discovery.js +92 -12
  286. package/packages/pi-coding-agent/dist/core/model-discovery.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/model-discovery.test.js +16 -1
  288. package/packages/pi-coding-agent/dist/core/model-discovery.test.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
  292. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  294. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  295. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  296. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  297. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js +61 -1
  298. package/packages/pi-coding-agent/dist/core/model-registry-discovery.test.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/core/model-registry.d.ts +5 -0
  300. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  301. package/packages/pi-coding-agent/dist/core/model-registry.js +90 -10
  302. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
  304. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
  305. package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
  306. package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
  307. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
  308. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
  309. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
  310. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
  311. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/session-manager.js +10 -6
  313. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/session-manager.test.js +45 -1
  315. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
  317. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  319. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  320. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  321. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js +13 -7
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/provider-manager.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  335. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  336. package/packages/pi-coding-agent/package.json +1 -1
  337. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +3 -2
  338. package/packages/pi-coding-agent/src/core/agent-session.ts +38 -2
  339. package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
  340. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  341. package/packages/pi-coding-agent/src/core/extensions/runner.ts +351 -0
  342. package/packages/pi-coding-agent/src/core/extensions/types.ts +258 -0
  343. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
  344. package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
  345. package/packages/pi-coding-agent/src/core/index.ts +10 -0
  346. package/packages/pi-coding-agent/src/core/model-discovery.test.ts +19 -0
  347. package/packages/pi-coding-agent/src/core/model-discovery.ts +99 -12
  348. package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
  349. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  350. package/packages/pi-coding-agent/src/core/model-registry-discovery.test.ts +75 -0
  351. package/packages/pi-coding-agent/src/core/model-registry.ts +102 -10
  352. package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
  353. package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
  354. package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -1
  355. package/packages/pi-coding-agent/src/core/session-manager.ts +10 -6
  356. package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
  357. package/packages/pi-coding-agent/src/index.ts +16 -0
  358. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
  359. package/packages/pi-coding-agent/src/modes/interactive/components/provider-manager.ts +16 -7
  360. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
  361. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  362. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  363. package/packages/pi-tui/package.json +1 -1
  364. package/packages/rpc-client/package.json +1 -1
  365. package/pkg/package.json +1 -1
  366. package/scripts/link-workspace-packages.cjs +1 -0
  367. package/src/resources/agents/researcher.md +1 -1
  368. package/src/resources/extensions/claude-code-cli/readiness.ts +32 -8
  369. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +78 -17
  370. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +149 -5
  371. package/src/resources/extensions/gsd/auto/loop-deps.ts +14 -0
  372. package/src/resources/extensions/gsd/auto/loop.ts +9 -0
  373. package/src/resources/extensions/gsd/auto/phases.ts +131 -10
  374. package/src/resources/extensions/gsd/auto/run-unit.ts +40 -2
  375. package/src/resources/extensions/gsd/auto/session.ts +35 -2
  376. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -3
  377. package/src/resources/extensions/gsd/auto-model-selection.ts +71 -15
  378. package/src/resources/extensions/gsd/auto-post-unit.ts +29 -3
  379. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  380. package/src/resources/extensions/gsd/auto-recovery.ts +26 -1
  381. package/src/resources/extensions/gsd/auto-start.ts +60 -68
  382. package/src/resources/extensions/gsd/auto-verification.ts +33 -0
  383. package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
  384. package/src/resources/extensions/gsd/auto.ts +73 -28
  385. package/src/resources/extensions/gsd/blocked-models.ts +98 -0
  386. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -1
  387. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
  388. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
  389. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +5 -0
  390. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
  391. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +54 -6
  392. package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -26
  393. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  394. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  395. package/src/resources/extensions/gsd/commands-extract-learnings.ts +55 -90
  396. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  397. package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
  398. package/src/resources/extensions/gsd/complexity-classifier.ts +5 -3
  399. package/src/resources/extensions/gsd/db-writer.ts +88 -17
  400. package/src/resources/extensions/gsd/doctor-git-checks.ts +23 -27
  401. package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
  402. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
  403. package/src/resources/extensions/gsd/error-classifier.ts +36 -3
  404. package/src/resources/extensions/gsd/exec-history.ts +153 -0
  405. package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
  406. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  407. package/src/resources/extensions/gsd/gsd-db.ts +186 -23
  408. package/src/resources/extensions/gsd/guided-flow.ts +222 -1
  409. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  410. package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
  411. package/src/resources/extensions/gsd/init-wizard.ts +15 -1
  412. package/src/resources/extensions/gsd/journal.ts +2 -1
  413. package/src/resources/extensions/gsd/key-manager.ts +28 -0
  414. package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
  415. package/src/resources/extensions/gsd/memory-store.ts +26 -0
  416. package/src/resources/extensions/gsd/model-router.ts +42 -1
  417. package/src/resources/extensions/gsd/pre-execution-checks.ts +46 -10
  418. package/src/resources/extensions/gsd/preferences-types.ts +46 -0
  419. package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
  420. package/src/resources/extensions/gsd/preferences.ts +17 -17
  421. package/src/resources/extensions/gsd/prompt-loader.ts +30 -7
  422. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  423. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  424. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  425. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  426. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  427. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -2
  428. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  429. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -0
  430. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
  431. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  432. package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
  433. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  434. package/src/resources/extensions/gsd/state.ts +45 -4
  435. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +188 -2
  436. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
  437. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  438. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +49 -0
  439. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +141 -0
  440. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +33 -3
  441. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +38 -0
  442. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +23 -0
  443. package/src/resources/extensions/gsd/tests/blocked-models.test.ts +98 -0
  444. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
  445. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  446. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +68 -66
  447. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
  448. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +61 -1
  449. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  450. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  451. package/src/resources/extensions/gsd/tests/complexity-classifier.test.ts +3 -3
  452. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  453. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
  454. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
  455. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +148 -3
  456. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  457. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
  458. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  459. package/src/resources/extensions/gsd/tests/exec-history.test.ts +237 -0
  460. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
  461. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
  462. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +40 -9
  463. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
  464. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +447 -1
  465. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
  466. package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +11 -0
  467. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +78 -0
  468. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +1 -0
  469. package/src/resources/extensions/gsd/tests/integration/gitignore-tracked-gsd.test.ts +1 -0
  470. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +30 -0
  471. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
  472. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
  473. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  474. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +37 -0
  475. package/src/resources/extensions/gsd/tests/key-manager.test.ts +9 -0
  476. package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
  477. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  478. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +12 -0
  479. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  480. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  481. package/src/resources/extensions/gsd/tests/plan-gate-failed-doctor-heal-hint.test.ts +37 -0
  482. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
  483. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  484. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +356 -0
  485. package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
  486. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  487. package/src/resources/extensions/gsd/tests/prompt-loader-extension-dir.test.ts +49 -0
  488. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +103 -4
  489. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  490. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  491. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +230 -0
  492. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  493. package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
  494. package/src/resources/extensions/gsd/tests/schema-v21-sequence.test.ts +413 -0
  495. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  496. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  497. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  498. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  499. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
  500. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -3
  501. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  502. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +35 -0
  503. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +6 -1
  504. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +78 -5
  505. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  506. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
  507. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  508. package/src/resources/extensions/gsd/tools/complete-milestone.ts +15 -9
  509. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
  510. package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
  511. package/src/resources/extensions/gsd/tools/memory-tools.ts +31 -1
  512. package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
  513. package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
  514. package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
  515. package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
  516. package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  517. package/src/resources/extensions/gsd/worktree-resolver.ts +54 -9
  518. package/src/resources/extensions/search-the-web/command-search-provider.ts +5 -4
  519. package/src/resources/extensions/search-the-web/native-search.ts +48 -12
  520. package/src/resources/skills/api-design/SKILL.md +190 -0
  521. package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
  522. package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
  523. package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
  524. package/src/resources/skills/design-an-interface/SKILL.md +102 -0
  525. package/src/resources/skills/forensics/SKILL.md +153 -0
  526. package/src/resources/skills/grill-me/SKILL.md +93 -0
  527. package/src/resources/skills/handoff/SKILL.md +121 -0
  528. package/src/resources/skills/observability/SKILL.md +174 -0
  529. package/src/resources/skills/security-review/SKILL.md +181 -0
  530. package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
  531. package/src/resources/skills/tdd/SKILL.md +112 -0
  532. package/src/resources/skills/verify-before-complete/SKILL.md +98 -0
  533. package/src/resources/skills/write-docs/SKILL.md +82 -0
  534. package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
  535. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_buildManifest.js +0 -0
  536. /package/dist/web/standalone/.next/static/{ssX7BLv3Dw9Fb4CtrCGeR → pV-mPo7rYGb5JBC09C8GG}/_ssgManifest.js +0 -0
@@ -16,8 +16,30 @@ import { existsSync, unlinkSync } from "node:fs";
16
16
  import { randomUUID } from "node:crypto";
17
17
  import { join } from "node:path";
18
18
  import { debugLog } from "./debug-logger.js";
19
- import { MergeConflictError } from "./git-service.js";
20
19
  import { emitJournalEvent } from "./journal.js";
20
+ // ─── Path Helpers ──────────────────────────────────────────────────────────
21
+ /**
22
+ * Worktree marker segment — present in any path produced by worktreePath().
23
+ * Used to strip the worktree suffix and recover the project root (#3729).
24
+ */
25
+ const WORKTREE_MARKER = "/.gsd/worktrees/";
26
+ /**
27
+ * Resolve the project root from session path state.
28
+ *
29
+ * Prefers `originalBasePath` (always the project root when set), but falls
30
+ * back to `basePath` when `originalBasePath` is falsy (e.g. fresh AutoSession
31
+ * with default empty string). If `basePath` itself is inside a worktree
32
+ * directory (contains `/.gsd/worktrees/`), strip that suffix to recover the
33
+ * actual project root — preventing double-nested worktree paths (#3729).
34
+ */
35
+ export function resolveProjectRoot(originalBasePath, basePath) {
36
+ let resolved = originalBasePath || basePath;
37
+ const markerIdx = resolved.indexOf(WORKTREE_MARKER);
38
+ if (markerIdx !== -1) {
39
+ resolved = resolved.slice(0, markerIdx);
40
+ }
41
+ return resolved;
42
+ }
21
43
  // ─── WorktreeResolver ──────────────────────────────────────────────────────
22
44
  export class WorktreeResolver {
23
45
  s;
@@ -33,11 +55,11 @@ export class WorktreeResolver {
33
55
  }
34
56
  /** Original project root — always the non-worktree path. */
35
57
  get projectRoot() {
36
- return this.s.originalBasePath || this.s.basePath;
58
+ return resolveProjectRoot(this.s.originalBasePath, this.s.basePath);
37
59
  }
38
60
  /** Path for auto.lock file — same as the old lockBase(). */
39
61
  get lockPath() {
40
- return this.s.originalBasePath || this.s.basePath;
62
+ return resolveProjectRoot(this.s.originalBasePath, this.s.basePath);
41
63
  }
42
64
  // ── Private Helpers ────────────────────────────────────────────────────
43
65
  rebuildGitService() {
@@ -99,7 +121,10 @@ export class WorktreeResolver {
99
121
  });
100
122
  return;
101
123
  }
102
- const basePath = this.s.originalBasePath || this.s.basePath;
124
+ // Resolve the project root for worktree operations via shared helper.
125
+ // Handles the case where originalBasePath is falsy and basePath is itself
126
+ // a worktree path — prevents double-nested worktree paths (#3729).
127
+ const basePath = resolveProjectRoot(this.s.originalBasePath, this.s.basePath);
103
128
  debugLog("WorktreeResolver", {
104
129
  action: "enterMilestone",
105
130
  milestoneId,
@@ -429,11 +454,13 @@ export class WorktreeResolver {
429
454
  /* best-effort */
430
455
  }
431
456
  }
432
- // Re-throw MergeConflictError so the auto loop can detect real code
433
- // conflicts and stop instead of retrying forever (#2330).
434
- if (err instanceof MergeConflictError) {
435
- throw err;
436
- }
457
+ // Restore state before re-throwing so callers always get a consistent
458
+ // session (#4380).
459
+ this.restoreToProjectRoot();
460
+ // Re-throw: MergeConflictError stops the auto loop (#2330); non-conflict
461
+ // errors (permission denied, filesystem failures) must also propagate so
462
+ // broken states are diagnosable (#4380).
463
+ throw err;
437
464
  }
438
465
  // Always restore basePath and rebuild — whether merge succeeded or failed
439
466
  this.restoreToProjectRoot();
@@ -500,6 +527,8 @@ export class WorktreeResolver {
500
527
  error: msg,
501
528
  });
502
529
  ctx.notify(`Milestone merge failed (branch mode): ${msg}`, "warning");
530
+ // Re-throw all errors so callers can apply their own recovery logic (#4380).
531
+ throw err;
503
532
  }
504
533
  }
505
534
  // ── Merge and Enter Next ───────────────────────────────────────────────
@@ -516,7 +545,18 @@ export class WorktreeResolver {
516
545
  currentMilestoneId,
517
546
  nextMilestoneId,
518
547
  });
519
- this.mergeAndExit(currentMilestoneId, ctx);
548
+ try {
549
+ this.mergeAndExit(currentMilestoneId, ctx);
550
+ }
551
+ catch (err) {
552
+ // mergeAndExit emits a warning and restores state when it fails during
553
+ // merge/cleanup. But if it throws before recovery runs (e.g., in
554
+ // validateMilestoneId or emitJournalEvent), basePath won't be restored
555
+ // to projectRoot — re-throw so we don't enter the next milestone with
556
+ // the current one unmerged.
557
+ if (this.s.basePath !== this.projectRoot)
558
+ throw err;
559
+ }
520
560
  this.enterMilestone(nextMilestoneId, ctx);
521
561
  }
522
562
  }
@@ -7,7 +7,7 @@
7
7
  *
8
8
  * All provider logic lives in provider.ts (S01) — this is pure UI wiring.
9
9
  */
10
- import { isAnthropicApi } from '@gsd/pi-ai';
10
+ import { supportsNativeWebSearch } from './native-search.js';
11
11
  import { getTavilyApiKey, getBraveApiKey, getOllamaApiKey, getSearchProviderPreference, setSearchProviderPreference, resolveSearchProvider, } from './provider.js';
12
12
  const VALID_PREFERENCES = ['tavily', 'brave', 'ollama', 'auto'];
13
13
  function keyStatus(provider) {
@@ -72,9 +72,10 @@ export function registerSearchProviderCommand(pi) {
72
72
  }
73
73
  setSearchProviderPreference(chosen);
74
74
  const effective = resolveSearchProvider();
75
- // Gate on api (#4478 / ADR-012): covers claude-code, anthropic-vertex, and
76
- // other Anthropic-fronting transports not just the plain `anthropic` provider.
77
- const isAnthropic = isAnthropicApi(ctx.model);
75
+ // Gate on api shape + provider allowlist: the info note must match the
76
+ // actual runtime behavior in native-search.ts. Claude served via copilot
77
+ // / minimax / kimi is anthropic-shaped but does NOT run native search.
78
+ const isAnthropic = supportsNativeWebSearch(ctx.model);
78
79
  const nativeNote = isAnthropic ? '\nNote: Native Anthropic web search is also active (automatic, no API key needed).' : '';
79
80
  ctx.ui.notify(`Search provider set to ${chosen}. Effective provider: ${effective ?? 'none (no API keys)'}${nativeNote}`, 'info');
80
81
  },
@@ -12,6 +12,38 @@ export const BRAVE_TOOL_NAMES = ["search-the-web", "search_and_read"];
12
12
  export const CUSTOM_SEARCH_TOOL_NAMES = ["search-the-web", "search_and_read", "google_search"];
13
13
  /** Thinking block types that require signature validation by the API */
14
14
  const THINKING_TYPES = new Set(["thinking", "redacted_thinking"]);
15
+ /**
16
+ * Providers whose Anthropic-Messages endpoint is known to accept the native
17
+ * `web_search_20250305` server tool. Anthropic-shaped transports NOT in this
18
+ * set (github-copilot, minimax, kimi-coding, opencode, vercel-ai-gateway,
19
+ * etc.) route Claude or Claude-compatible models through the Messages API
20
+ * but do NOT expose the server-side search tool — injecting it yields a
21
+ * 400 "unsupported_value" from their endpoints (regression from #4492).
22
+ *
23
+ * Keep this allowlist tight — err on the side of custom/Brave search rather
24
+ * than a runtime 400. Add a provider here only after confirming its endpoint
25
+ * accepts the tool type.
26
+ */
27
+ const NATIVE_WEB_SEARCH_PROVIDERS = new Set([
28
+ "anthropic",
29
+ "claude-code",
30
+ "anthropic-vertex",
31
+ "vercel-ai-gateway",
32
+ ]);
33
+ /**
34
+ * True when the model is an Anthropic-shaped transport AND the provider is
35
+ * known to accept the native `web_search_20250305` tool. Gate both on api
36
+ * shape (#4478 / ADR-012) and on provider identity (#444 regression guard
37
+ * and #4492 scope correction) — provider-level discrimination is legitimate
38
+ * per ADR-012 for credential/behavior differences that api shape can't
39
+ * express.
40
+ */
41
+ export function supportsNativeWebSearch(model) {
42
+ if (!isAnthropicApi(model))
43
+ return false;
44
+ const provider = model?.provider;
45
+ return typeof provider === "string" && NATIVE_WEB_SEARCH_PROVIDERS.has(provider);
46
+ }
15
47
  /**
16
48
  * Maximum number of native web searches allowed per session (agent unit).
17
49
  * The Anthropic API's `max_uses` is per-request — it resets on each API call.
@@ -76,10 +108,11 @@ export function registerNativeSearchHooks(pi) {
76
108
  pi.on("model_select", async (event, ctx) => {
77
109
  modelSelectFired = true;
78
110
  const wasAnthropic = isAnthropicProvider;
79
- // Gate on `api` not `provider` (#4478 / ADR-012): covers claude-code OAuth,
80
- // anthropic-vertex, and Vercel-gateway-hosted Anthropic all serve the
81
- // Messages API and accept the native web_search tool.
82
- isAnthropicProvider = isAnthropicApi(event.model);
111
+ // Gate on api shape AND provider allowlist: direct Anthropic, claude-code
112
+ // OAuth, and anthropic-vertex accept `web_search_20250305`; copilot /
113
+ // minimax / kimi / opencode route Claude-compat models through the same
114
+ // wire protocol but reject the server-side tool (#4492 regression).
115
+ isAnthropicProvider = supportsNativeWebSearch(event.model);
83
116
  const hasBrave = !!process.env.BRAVE_API_KEY;
84
117
  // When Anthropic (and not preferring Brave): disable custom search tools —
85
118
  // native web_search is server-side and more reliable.
@@ -120,20 +153,19 @@ export function registerNativeSearchHooks(pi) {
120
153
  // modelsAreEqual suppresses model_select AND the SDK doesn't pass model.
121
154
  const eventModel = event.model;
122
155
  let isAnthropic;
123
- if (eventModel?.api) {
124
- // Preferred path: gate on wire protocol (#4478 / ADR-012).
125
- isAnthropic = isAnthropicApi(eventModel);
126
- }
127
- else if (eventModel?.provider) {
128
- // Fallback for event shapes that carry provider but not api — only plain
129
- // `anthropic` maps unambiguously without the api field. Other Anthropic
130
- // transports will arrive via the modelSelectFired or model-name branch.
131
- isAnthropic = eventModel.provider === "anthropic";
156
+ if (eventModel?.api || eventModel?.provider) {
157
+ // Preferred path: gate on api shape + provider allowlist. Both fields
158
+ // are authoritative when present — do NOT fall back to the model-name
159
+ // heuristic, which would misclassify copilot-served Claude as Anthropic
160
+ // (#444 regression) or minimax-served Claude-compat as Anthropic (#4492).
161
+ isAnthropic = supportsNativeWebSearch(eventModel);
132
162
  }
133
163
  else if (modelSelectFired) {
134
164
  isAnthropic = isAnthropicProvider;
135
165
  }
136
166
  else {
167
+ // Last resort: session-restore paths where the SDK doesn't pass model.
168
+ // The model-name prefix is best-effort and assumes direct Anthropic.
137
169
  const modelName = typeof payload.model === "string" ? payload.model : "";
138
170
  isAnthropic = modelName.startsWith("claude-");
139
171
  }
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: api-design
3
+ description: Design or review an HTTP/REST/GraphQL API for versioning, pagination, error shapes, idempotency, auth, and evolvability. Use when asked to "design an API", "shape the endpoints", "design the schema", "add a new endpoint", "review this API", or when building/modifying a public or internal HTTP surface. Complements `design-an-interface` (which is interface-agnostic) by covering HTTP-specific concerns like status codes, cache headers, and breaking-change management.
4
+ ---
5
+
6
+ <objective>
7
+ Shape an HTTP or GraphQL API so callers get predictable, evolvable, and honest semantics. The deliverable is a concrete endpoint/schema sketch with: URL or operation names, method/verb, request shape, response shape, error shape, auth model, pagination strategy, and versioning stance. Optimize for "clients that exist in 2 years" over "client that's easy to write today".
8
+ </objective>
9
+
10
+ <context>
11
+ GSD-2 has `design-an-interface` for general module-interface design; this skill is the HTTP/GraphQL specialization. REST and GraphQL carry baggage — status codes, verbs, nullability, pagination — that a generic interface-design discussion glosses over.
12
+
13
+ Invocation points:
14
+ - Adding a new public API endpoint
15
+ - Redesigning an internal API boundary between services
16
+ - Code review of a PR that introduces HTTP handlers
17
+ - A slice whose acceptance criteria include "the API works"
18
+ - A GraphQL schema change
19
+ </context>
20
+
21
+ <core_principle>
22
+ **CALLERS OUTLIVE YOUR ASSUMPTIONS.** An API you ship today has to keep working when your internals change, when the mobile app version two is still in use, and when a third party integrates against it. Design for extension, not just for the current caller.
23
+
24
+ **HONEST STATUS CODES.** 200 OK with `{"error": "not found"}` is a lie. 404 says not found. Use the HTTP semantics the protocol offers — HTTP clients, caches, and intermediaries rely on them.
25
+
26
+ **PAGINATION IS NON-OPTIONAL.** Any list endpoint that doesn't paginate will eventually get a request for "all records" that kills your database.
27
+ </core_principle>
28
+
29
+ <process>
30
+
31
+ ## Step 1: Gather the contract
32
+
33
+ Answer, or ask (one round, 1–3 questions):
34
+
35
+ 1. **Who are the callers?** Internal service / mobile app / public third-party / same-repo frontend.
36
+ 2. **What's the versioning stance?** None / URL-path (`/v1/`) / header-based / GraphQL schema evolution.
37
+ 3. **Auth model?** Public / API key / OAuth / session cookie / mTLS / none-but-internal-only.
38
+ 4. **Idempotency expectation?** Is a retry safe? Required?
39
+ 5. **Consistency model?** Read-your-writes, eventual, serializable?
40
+
41
+ ## Step 2: Resource and operation naming
42
+
43
+ ### REST
44
+
45
+ - Nouns not verbs in URLs: `POST /users`, not `POST /createUser`.
46
+ - Plural resources: `/users/42`, not `/user/42`.
47
+ - Nested only when the relationship is hierarchical and the child has no independent identity: `/users/42/sessions/3`. Otherwise flat: `/sessions/3?userId=42`.
48
+ - Use subresources for actions that don't fit CRUD: `POST /users/42:deactivate` (colon syntax) or `POST /users/42/actions/deactivate`.
49
+
50
+ ### GraphQL
51
+
52
+ - Queries are nouns; mutations are verbs: `user(id)`, `createUser(input)`, `deactivateUser(id)`.
53
+ - Group related mutations under an input type: `createUser(input: CreateUserInput!)`.
54
+ - Return the affected object plus any derived/computed fields from mutations — lets clients avoid a refetch.
55
+
56
+ ## Step 3: Methods and status codes
57
+
58
+ ### REST
59
+
60
+ | Method | Intent | Idempotent? | Default success |
61
+ |---|---|---|---|
62
+ | GET | Read | Yes | 200, or 304 if conditional |
63
+ | POST | Create or non-idempotent action | No | 201 with `Location` on create, 200 on action |
64
+ | PUT | Replace (full-object) | Yes | 200 with body, or 204 |
65
+ | PATCH | Partial update | No (usually) | 200 with body |
66
+ | DELETE | Remove | Yes | 204 |
67
+
68
+ Errors:
69
+ - 400: caller screwed up the request shape
70
+ - 401: no/invalid auth
71
+ - 403: authed but not allowed
72
+ - 404: resource doesn't exist
73
+ - 409: conflict (version mismatch, unique constraint)
74
+ - 410: gone (vs 404 when the resource previously existed and you want to signal that)
75
+ - 422: validation failed
76
+ - 429: rate-limited — include `Retry-After`
77
+ - 500: genuinely unexpected server error
78
+ - 503: service down or overloaded — include `Retry-After`
79
+
80
+ Never 200-with-error-body. Never 500 for a 4xx cause.
81
+
82
+ ### GraphQL
83
+
84
+ - Top-level errors (`errors[]`) for transport-level failures. Domain errors (validation, not-found, forbidden) go in the typed return — use a union or result type.
85
+ - Partial results are expected; design the schema so `null` on a field is meaningful, not a signal of generic failure.
86
+
87
+ ## Step 4: Pagination
88
+
89
+ - **Cursor-based by default.** Opaque cursor string, `limit`, return `nextCursor` when more exists. Scales, stable under writes.
90
+ - **Offset-based only when:** dataset is small, user needs jump-to-page semantics (admin tables), and you're willing to accept stability drift.
91
+ - **Never "return everything"** as default. Put a hard upper bound on `limit` (e.g., 200).
92
+ - GraphQL: use Relay-style connections (`edges`, `pageInfo`) if the ecosystem expects it; otherwise a simpler `{items, nextCursor}` is fine.
93
+
94
+ ## Step 5: Error shape
95
+
96
+ Standardize one shape and use it everywhere. Example REST:
97
+
98
+ ```json
99
+ {
100
+ "error": {
101
+ "code": "user_not_found",
102
+ "message": "No user with id 42",
103
+ "details": { "userId": 42 },
104
+ "requestId": "req_abc123"
105
+ }
106
+ }
107
+ ```
108
+
109
+ - `code` is machine-readable; stable; documented.
110
+ - `message` is human-readable; can change.
111
+ - `details` carries structured context.
112
+ - `requestId` lets callers report bugs.
113
+
114
+ Errors don't leak stack traces, file paths, or internal queries.
115
+
116
+ ## Step 6: Idempotency, caching, concurrency
117
+
118
+ - **Idempotency keys** for POST operations that mustn't double-execute on retry. Caller passes `Idempotency-Key: <uuid>`; server dedupes for a window.
119
+ - **ETags** for GET + conditional updates (`If-Match` on PUT/PATCH).
120
+ - **Cache-Control** on GETs that are safely cacheable.
121
+ - **Optimistic concurrency:** when multiple writers collide, 409 with the current state. Don't silently clobber.
122
+
123
+ ## Step 7: Versioning and evolution
124
+
125
+ - **Additive changes are free:** new optional fields, new endpoints, new optional query params.
126
+ - **Breaking changes need a plan:** path-versioned (`/v2/`), sunset headers on `/v1/`, deprecation window communicated. Or, for GraphQL, `@deprecated` on fields with a migration note.
127
+ - **Document the contract:** OpenAPI/GraphQL SDL. Keep it in the repo. Make it part of the PR that introduces the change.
128
+
129
+ ## Step 8: Review or write it up
130
+
131
+ If this is a review, produce findings in the same shape as `security-review` / `review` — file:line, category, recommendation.
132
+
133
+ If this is a new design, produce:
134
+
135
+ ```markdown
136
+ ## <API name>
137
+
138
+ ### Scope
139
+ <what the API is for, who calls it>
140
+
141
+ ### Endpoints / Operations
142
+ - `POST /users` — create user. Request: `{email, name}`. Response 201: `{id, email, name, createdAt}` + `Location: /users/<id>`. Errors: 409 email taken, 422 invalid.
143
+ - ...
144
+
145
+ ### Auth
146
+ <model + where to put the credential>
147
+
148
+ ### Pagination
149
+ <cursor shape, max limit>
150
+
151
+ ### Error shape
152
+ <one canonical shape>
153
+
154
+ ### Idempotency / concurrency
155
+ <rules>
156
+
157
+ ### Versioning
158
+ <stance + how breaking changes will be handled>
159
+
160
+ ### OpenAPI / SDL
161
+ <link or inline>
162
+ ```
163
+
164
+ Append architectural decisions to `.gsd/DECISIONS.md`.
165
+
166
+ </process>
167
+
168
+ <anti_patterns>
169
+
170
+ - **200 OK with `{"error": "..."}`.** Lies to caches, proxies, retry libraries.
171
+ - **Unbounded list endpoints.** `GET /users` without a `limit` cap will bite you.
172
+ - **Offset pagination at scale.** Drifts under writes; slow at high offsets.
173
+ - **Free-form error messages with no code.** Machine callers can't branch on prose.
174
+ - **Breaking changes in-place.** Callers break; versioning exists for a reason.
175
+ - **Ignoring idempotency on retriable POSTs.** Double-charges, duplicate records.
176
+ - **Auth checks at the handler only, not the service layer.** Defense in depth.
177
+
178
+ </anti_patterns>
179
+
180
+ <success_criteria>
181
+
182
+ - [ ] Every endpoint/operation has named request, response, and error shapes.
183
+ - [ ] Status codes match HTTP semantics — no 200-with-error.
184
+ - [ ] List endpoints paginate; max limit is documented.
185
+ - [ ] A single error shape is used everywhere, with a machine-readable code.
186
+ - [ ] Versioning stance is stated — even if the answer is "additive only for now."
187
+ - [ ] OpenAPI/SDL reflects the design and lives in the repo.
188
+ - [ ] Decisions appear in `.gsd/DECISIONS.md`.
189
+
190
+ </success_criteria>
@@ -0,0 +1,121 @@
1
+ ---
2
+ name: create-mcp-server
3
+ description: Build, iterate, and evaluate Model Context Protocol (MCP) servers that expose external services as tools an LLM can call. Use when asked to "build an MCP server", "create an MCP tool", "wrap this API as MCP", "expose X to Claude", or when extending GSD with custom tool integrations. Covers research, schema/tool design, error handling, pagination, testing via MCP Inspector, and producing a 10-question eval set that proves the server actually enables real work.
4
+ ---
5
+
6
+ <objective>
7
+ Produce a high-quality MCP server that an LLM can actually use — not one that merely parses spec-compliant. Quality is measured by how well the server enables real-world task completion, which means the tool descriptions, error messages, and pagination behave under model reasoning, not just at the wire level.
8
+ </objective>
9
+
10
+ <context>
11
+ GSD-2 consumes MCP heavily — see `src/resources/extensions/mcp-client/`, `src/resources/extensions/gsd/mcp-project-config.ts`, `src/resources/extensions/gsd/workflow-mcp.ts`, and `/gsd mcp` commands. Users frequently want to extend GSD with project-specific MCP servers (internal APIs, data sources, domain tools). This skill fills the authoring gap between "MCP exists" and "I have a working server."
12
+
13
+ Invocation points:
14
+ - User describes a service or API they want an LLM to reach
15
+ - `/gsd mcp init` scaffolds config but there's a tool integration to build
16
+ - Replacing a hand-rolled extension with a standard MCP server
17
+ </context>
18
+
19
+ <core_principle>
20
+ **THE QUALITY METRIC IS TASK COMPLETION, NOT SCHEMA VALIDITY.** A server that lists 30 tools with cryptic names and empty descriptions passes the protocol but fails the point. The tool description is the only thing an LLM has to decide whether to call it — write it like documentation for a stranger under time pressure.
21
+
22
+ **DESIGN FOR THE MODEL, NOT THE API.** A raw REST endpoint is rarely the right tool. Group, filter, and pre-shape responses so the model gets what it needs to reason, not a 40KB JSON blob it has to summarize. Fewer, deeper tools beat many, shallow ones.
23
+ </core_principle>
24
+
25
+ <process>
26
+
27
+ ## Step 1: Research and scope
28
+
29
+ 1. **Study modern MCP design.** Read the latest MCP protocol docs (not training data — fetch them). Read 2–3 reference implementations to see current patterns.
30
+ 2. **Pick a framework.** TypeScript is the default — the reference SDK is the most mature. Python is fine for data-heavy or ML adjacencies.
31
+ 3. **Analyze the target API.** Map the external service's endpoints, auth, rate limits, pagination, error shapes. Identify what a human workflow on top of it actually looks like — that's the cut line for tool design.
32
+ 4. **Produce a brief.** One page: what the server does, who calls it, the 5–10 tools you plan to expose, and the top 3 design trade-offs. Confirm with the user.
33
+
34
+ ## Step 2: Set up the project
35
+
36
+ Skeleton:
37
+
38
+ ```text
39
+ server/
40
+ src/
41
+ index.ts # MCP entry point — stdio or sse transport
42
+ client.ts # API client with auth, retries, typed errors
43
+ tools/ # one file per tool, or grouped by domain
44
+ pagination.ts # shared cursor handling
45
+ errors.ts # MCP-friendly error formatting
46
+ package.json # @modelcontextprotocol/sdk as dep
47
+ tsconfig.json
48
+ README.md # how to run, env vars, rate-limit notes
49
+ evals.xml # 10 eval questions (Phase 4)
50
+ ```
51
+
52
+ Core infrastructure goes first: API client with typed errors, pagination helpers, consistent retry/timeout behavior. Do not inline these per tool.
53
+
54
+ ## Step 3: Implement tools
55
+
56
+ For each tool:
57
+
58
+ 1. **Name:** verb-noun, lowercase, snake_case. `search_issues`, `get_customer`, `create_deployment`. Not `do_thing` or `api_v2_post`.
59
+ 2. **Description (frontmatter):** 2–4 sentences. State what the tool does, when to use it, when NOT to use it, and any required fields or quirks. This is the model's entire interface to the tool — write it carefully.
60
+ 3. **Input schema (JSON Schema):** required fields marked, every field has a description, enums enumerated, examples included for free-form strings.
61
+ 4. **Output shape:** typed, minimal, decision-ready. If the raw API returns 40 fields and only 6 matter for follow-up calls, return 6.
62
+ 5. **Error handling:** never return raw HTTP errors. Translate to human-readable messages: "Rate limit exceeded (retry in 30s)", "Authorization expired", "No record found for ID X". Include the action the caller should take next.
63
+ 6. **Pagination:** expose cursors explicitly. Do not leak "page N of M" into the model — leak "more results available, pass `cursor: abc123` to continue."
64
+
65
+ ## Step 4: Build and test with MCP Inspector
66
+
67
+ 1. Run the server under MCP Inspector. Verify it registers, every tool lists with its description, inputs schema-validate, outputs shape correctly.
68
+ 2. Call every tool at least once manually through the Inspector UI. Check error paths.
69
+ 3. Fix any "looks fine in isolation, breaks under the Inspector's framing" issues.
70
+
71
+ ## Step 5: Produce the eval set
72
+
73
+ Write 10 evaluation questions in `evals.xml` that exercise the server end-to-end. Each question should require 2+ tool calls and at least one decision the model has to make based on earlier output. Cover:
74
+
75
+ - Happy path (2–3 questions)
76
+ - Error recovery (2 questions — "the first call failed, what next?")
77
+ - Pagination (1 question)
78
+ - Decision under partial information (2–3 questions)
79
+ - Cross-tool composition (1–2 questions)
80
+
81
+ Format:
82
+
83
+ ```xml
84
+ <evals>
85
+ <eval id="1">
86
+ <question>...user request...</question>
87
+ <expected>...concrete observable answer or tool-call sequence...</expected>
88
+ </eval>
89
+ </evals>
90
+ ```
91
+
92
+ Run the evals. If the model can't complete them, the server — not the model — needs work. Iterate on descriptions, error messages, and tool granularity.
93
+
94
+ ## Step 6: Wire into GSD
95
+
96
+ Write the project's `.mcp.json` entry using `/gsd mcp init` as a starting point. Document env vars and startup in README.md. If the server is globally useful, suggest the user file it as a durable skill via `spike-wrap-up` or publish it.
97
+
98
+ </process>
99
+
100
+ <anti_patterns>
101
+
102
+ - **One-to-one REST mapping.** If the API has 30 endpoints, you likely want 6 tools.
103
+ - **Empty or auto-generated descriptions.** "Calls the /users endpoint" tells the model nothing it can reason with.
104
+ - **Raw error passthrough.** `{"error": "500"}` is useless. Translate.
105
+ - **Page-based pagination leaked as "page 1 of 5".** Use opaque cursors.
106
+ - **Skipping the Inspector.** If you didn't run it under the Inspector, you didn't test it.
107
+ - **No evals.** Without evals you have no signal on whether real task completion works.
108
+
109
+ </anti_patterns>
110
+
111
+ <success_criteria>
112
+
113
+ - [ ] Every tool has a description that could guide a cold-start model correctly.
114
+ - [ ] Errors are translated to actionable, human-readable messages.
115
+ - [ ] Pagination uses opaque cursors; no leaked page numbers.
116
+ - [ ] `evals.xml` has 10 questions; the model completes ≥8 without handholding.
117
+ - [ ] MCP Inspector test passes cleanly.
118
+ - [ ] README documents env, startup, and rate-limit behavior.
119
+ - [ ] Server is reachable from GSD via `.mcp.json` entry.
120
+
121
+ </success_criteria>