gsd-pi 2.10.12 → 2.12.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 (504) hide show
  1. package/dist/bundled-extension-paths.d.ts +2 -0
  2. package/dist/bundled-extension-paths.js +10 -0
  3. package/dist/loader.js +45 -28
  4. package/dist/onboarding.js +100 -0
  5. package/dist/resource-loader.js +12 -3
  6. package/dist/resources/GSD-WORKFLOW.md +661 -0
  7. package/dist/resources/agents/researcher.md +29 -0
  8. package/dist/resources/agents/scout.md +56 -0
  9. package/dist/resources/agents/worker.md +31 -0
  10. package/dist/resources/extensions/ask-user-questions.ts +289 -0
  11. package/dist/resources/extensions/async-jobs/async-bash-tool.ts +211 -0
  12. package/dist/resources/extensions/async-jobs/await-tool.ts +101 -0
  13. package/dist/resources/extensions/async-jobs/cancel-job-tool.ts +34 -0
  14. package/dist/resources/extensions/async-jobs/index.ts +133 -0
  15. package/dist/resources/extensions/async-jobs/job-manager.ts +211 -0
  16. package/dist/resources/extensions/bg-shell/index.ts +3179 -0
  17. package/dist/resources/extensions/browser-tools/BROWSER-TOOLS-V2-PROPOSAL.md +1277 -0
  18. package/dist/resources/extensions/browser-tools/capture.ts +165 -0
  19. package/dist/resources/extensions/browser-tools/core.d.ts +205 -0
  20. package/dist/resources/extensions/browser-tools/core.js +1057 -0
  21. package/dist/resources/extensions/browser-tools/evaluate-helpers.ts +184 -0
  22. package/dist/resources/extensions/browser-tools/index.ts +51 -0
  23. package/dist/resources/extensions/browser-tools/lifecycle.ts +270 -0
  24. package/dist/resources/extensions/browser-tools/package.json +24 -0
  25. package/dist/resources/extensions/browser-tools/refs.ts +264 -0
  26. package/dist/resources/extensions/browser-tools/settle.ts +197 -0
  27. package/dist/resources/extensions/browser-tools/state.ts +408 -0
  28. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +652 -0
  29. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +614 -0
  30. package/dist/resources/extensions/browser-tools/tools/assertions.ts +342 -0
  31. package/dist/resources/extensions/browser-tools/tools/forms.ts +801 -0
  32. package/dist/resources/extensions/browser-tools/tools/inspection.ts +492 -0
  33. package/dist/resources/extensions/browser-tools/tools/intent.ts +614 -0
  34. package/dist/resources/extensions/browser-tools/tools/interaction.ts +865 -0
  35. package/dist/resources/extensions/browser-tools/tools/navigation.ts +232 -0
  36. package/dist/resources/extensions/browser-tools/tools/pages.ts +303 -0
  37. package/dist/resources/extensions/browser-tools/tools/refs.ts +541 -0
  38. package/dist/resources/extensions/browser-tools/tools/screenshot.ts +83 -0
  39. package/dist/resources/extensions/browser-tools/tools/session.ts +400 -0
  40. package/dist/resources/extensions/browser-tools/tools/wait.ts +247 -0
  41. package/dist/resources/extensions/browser-tools/utils.ts +660 -0
  42. package/dist/resources/extensions/context7/index.ts +428 -0
  43. package/dist/resources/extensions/context7/package.json +11 -0
  44. package/dist/resources/extensions/get-secrets-from-user.ts +625 -0
  45. package/dist/resources/extensions/google-search/index.ts +336 -0
  46. package/dist/resources/extensions/google-search/package.json +9 -0
  47. package/dist/resources/extensions/gsd/activity-log.ts +116 -0
  48. package/dist/resources/extensions/gsd/auto.ts +3732 -0
  49. package/dist/resources/extensions/gsd/commands.ts +544 -0
  50. package/dist/resources/extensions/gsd/crash-recovery.ts +105 -0
  51. package/dist/resources/extensions/gsd/dashboard-overlay.ts +564 -0
  52. package/dist/resources/extensions/gsd/dispatch-guard.ts +78 -0
  53. package/dist/resources/extensions/gsd/docs/preferences-reference.md +278 -0
  54. package/dist/resources/extensions/gsd/doctor.ts +766 -0
  55. package/dist/resources/extensions/gsd/exit-command.ts +18 -0
  56. package/dist/resources/extensions/gsd/files.ts +857 -0
  57. package/dist/resources/extensions/gsd/git-service.ts +904 -0
  58. package/dist/resources/extensions/gsd/gitignore.ts +200 -0
  59. package/dist/resources/extensions/gsd/guided-flow.ts +1054 -0
  60. package/dist/resources/extensions/gsd/index.ts +735 -0
  61. package/dist/resources/extensions/gsd/metrics.ts +374 -0
  62. package/dist/resources/extensions/gsd/migrate/command.ts +218 -0
  63. package/dist/resources/extensions/gsd/migrate/index.ts +42 -0
  64. package/dist/resources/extensions/gsd/migrate/parser.ts +323 -0
  65. package/dist/resources/extensions/gsd/migrate/parsers.ts +624 -0
  66. package/dist/resources/extensions/gsd/migrate/preview.ts +48 -0
  67. package/dist/resources/extensions/gsd/migrate/transformer.ts +346 -0
  68. package/dist/resources/extensions/gsd/migrate/types.ts +370 -0
  69. package/dist/resources/extensions/gsd/migrate/validator.ts +55 -0
  70. package/dist/resources/extensions/gsd/migrate/writer.ts +539 -0
  71. package/dist/resources/extensions/gsd/native-git-bridge.ts +181 -0
  72. package/dist/resources/extensions/gsd/native-parser-bridge.ts +135 -0
  73. package/dist/resources/extensions/gsd/observability-validator.ts +408 -0
  74. package/dist/resources/extensions/gsd/package.json +11 -0
  75. package/dist/resources/extensions/gsd/paths.ts +339 -0
  76. package/dist/resources/extensions/gsd/post-unit-hooks.ts +449 -0
  77. package/dist/resources/extensions/gsd/preferences.ts +988 -0
  78. package/dist/resources/extensions/gsd/prompt-loader.ts +92 -0
  79. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +25 -0
  80. package/dist/resources/extensions/gsd/prompts/complete-slice.md +27 -0
  81. package/dist/resources/extensions/gsd/prompts/discuss.md +237 -0
  82. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +29 -0
  83. package/dist/resources/extensions/gsd/prompts/execute-task.md +63 -0
  84. package/dist/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -0
  85. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +5 -0
  86. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +61 -0
  87. package/dist/resources/extensions/gsd/prompts/guided-execute-task.md +3 -0
  88. package/dist/resources/extensions/gsd/prompts/guided-plan-milestone.md +29 -0
  89. package/dist/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -0
  90. package/dist/resources/extensions/gsd/prompts/guided-research-slice.md +13 -0
  91. package/dist/resources/extensions/gsd/prompts/guided-resume-task.md +1 -0
  92. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +78 -0
  93. package/dist/resources/extensions/gsd/prompts/plan-slice.md +55 -0
  94. package/dist/resources/extensions/gsd/prompts/queue.md +100 -0
  95. package/dist/resources/extensions/gsd/prompts/reassess-roadmap.md +48 -0
  96. package/dist/resources/extensions/gsd/prompts/replan-slice.md +39 -0
  97. package/dist/resources/extensions/gsd/prompts/research-milestone.md +37 -0
  98. package/dist/resources/extensions/gsd/prompts/research-slice.md +28 -0
  99. package/dist/resources/extensions/gsd/prompts/review-migration.md +66 -0
  100. package/dist/resources/extensions/gsd/prompts/run-uat.md +109 -0
  101. package/dist/resources/extensions/gsd/prompts/system.md +190 -0
  102. package/dist/resources/extensions/gsd/prompts/worktree-merge.md +123 -0
  103. package/dist/resources/extensions/gsd/roadmap-slices.ts +50 -0
  104. package/dist/resources/extensions/gsd/session-forensics.ts +500 -0
  105. package/dist/resources/extensions/gsd/skill-discovery.ts +137 -0
  106. package/dist/resources/extensions/gsd/state.ts +569 -0
  107. package/dist/resources/extensions/gsd/templates/context.md +76 -0
  108. package/dist/resources/extensions/gsd/templates/decisions.md +8 -0
  109. package/dist/resources/extensions/gsd/templates/milestone-summary.md +73 -0
  110. package/dist/resources/extensions/gsd/templates/plan.md +131 -0
  111. package/dist/resources/extensions/gsd/templates/preferences.md +23 -0
  112. package/dist/resources/extensions/gsd/templates/project.md +31 -0
  113. package/dist/resources/extensions/gsd/templates/reassessment.md +28 -0
  114. package/dist/resources/extensions/gsd/templates/requirements.md +81 -0
  115. package/dist/resources/extensions/gsd/templates/research.md +46 -0
  116. package/dist/resources/extensions/gsd/templates/roadmap.md +118 -0
  117. package/dist/resources/extensions/gsd/templates/secrets-manifest.md +22 -0
  118. package/dist/resources/extensions/gsd/templates/slice-context.md +58 -0
  119. package/dist/resources/extensions/gsd/templates/slice-summary.md +99 -0
  120. package/dist/resources/extensions/gsd/templates/state.md +19 -0
  121. package/dist/resources/extensions/gsd/templates/task-plan.md +52 -0
  122. package/dist/resources/extensions/gsd/templates/task-summary.md +57 -0
  123. package/dist/resources/extensions/gsd/templates/uat.md +54 -0
  124. package/dist/resources/extensions/gsd/tests/activity-log-prune.test.ts +297 -0
  125. package/dist/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
  126. package/dist/resources/extensions/gsd/tests/auto-draft-pause.test.ts +109 -0
  127. package/dist/resources/extensions/gsd/tests/auto-preflight.test.ts +45 -0
  128. package/dist/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +196 -0
  129. package/dist/resources/extensions/gsd/tests/auto-supervisor.test.mjs +53 -0
  130. package/dist/resources/extensions/gsd/tests/collect-from-manifest.test.ts +469 -0
  131. package/dist/resources/extensions/gsd/tests/complete-milestone.test.ts +200 -0
  132. package/dist/resources/extensions/gsd/tests/cost-projection.test.ts +134 -0
  133. package/dist/resources/extensions/gsd/tests/derive-state-deps.test.ts +312 -0
  134. package/dist/resources/extensions/gsd/tests/derive-state-draft.test.ts +299 -0
  135. package/dist/resources/extensions/gsd/tests/derive-state.test.ts +660 -0
  136. package/dist/resources/extensions/gsd/tests/discuss-prompt.test.ts +27 -0
  137. package/dist/resources/extensions/gsd/tests/dispatch-guard.test.ts +91 -0
  138. package/dist/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +170 -0
  139. package/dist/resources/extensions/gsd/tests/doctor.test.ts +594 -0
  140. package/dist/resources/extensions/gsd/tests/draft-promotion.test.ts +169 -0
  141. package/dist/resources/extensions/gsd/tests/exit-command.test.ts +50 -0
  142. package/dist/resources/extensions/gsd/tests/git-service.test.ts +1788 -0
  143. package/dist/resources/extensions/gsd/tests/idle-recovery.test.ts +577 -0
  144. package/dist/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +580 -0
  145. package/dist/resources/extensions/gsd/tests/manifest-status.test.ts +283 -0
  146. package/dist/resources/extensions/gsd/tests/metrics-io.test.ts +176 -0
  147. package/dist/resources/extensions/gsd/tests/metrics.test.ts +188 -0
  148. package/dist/resources/extensions/gsd/tests/migrate-command.test.ts +369 -0
  149. package/dist/resources/extensions/gsd/tests/migrate-parser.test.ts +757 -0
  150. package/dist/resources/extensions/gsd/tests/migrate-transformer.test.ts +635 -0
  151. package/dist/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +414 -0
  152. package/dist/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +297 -0
  153. package/dist/resources/extensions/gsd/tests/migrate-writer.test.ts +398 -0
  154. package/dist/resources/extensions/gsd/tests/must-have-parser.test.ts +291 -0
  155. package/dist/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
  156. package/dist/resources/extensions/gsd/tests/next-milestone-id.test.ts +66 -0
  157. package/dist/resources/extensions/gsd/tests/orphaned-branch.test.ts +353 -0
  158. package/dist/resources/extensions/gsd/tests/parsers.test.ts +1664 -0
  159. package/dist/resources/extensions/gsd/tests/plan-milestone.test.ts +133 -0
  160. package/dist/resources/extensions/gsd/tests/plan-quality-validator.test.ts +363 -0
  161. package/dist/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
  162. package/dist/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
  163. package/dist/resources/extensions/gsd/tests/queue-draft-detection.test.ts +126 -0
  164. package/dist/resources/extensions/gsd/tests/reassess-prompt.test.ts +142 -0
  165. package/dist/resources/extensions/gsd/tests/regex-hardening.test.ts +281 -0
  166. package/dist/resources/extensions/gsd/tests/remote-questions.test.ts +155 -0
  167. package/dist/resources/extensions/gsd/tests/remote-status.test.ts +99 -0
  168. package/dist/resources/extensions/gsd/tests/replan-slice.test.ts +493 -0
  169. package/dist/resources/extensions/gsd/tests/requirements.test.ts +106 -0
  170. package/dist/resources/extensions/gsd/tests/resolve-ts-hooks.mjs +35 -0
  171. package/dist/resources/extensions/gsd/tests/resolve-ts.mjs +11 -0
  172. package/dist/resources/extensions/gsd/tests/roadmap-slices.test.ts +41 -0
  173. package/dist/resources/extensions/gsd/tests/run-uat.test.ts +316 -0
  174. package/dist/resources/extensions/gsd/tests/secure-env-collect.test.ts +185 -0
  175. package/dist/resources/extensions/gsd/tests/smart-entry-draft.test.ts +123 -0
  176. package/dist/resources/extensions/gsd/tests/test-helpers.ts +61 -0
  177. package/dist/resources/extensions/gsd/tests/unique-milestone-ids.test.ts +219 -0
  178. package/dist/resources/extensions/gsd/tests/unit-runtime.test.ts +234 -0
  179. package/dist/resources/extensions/gsd/tests/workspace-index.test.ts +75 -0
  180. package/dist/resources/extensions/gsd/tests/worktree-integration.test.ts +234 -0
  181. package/dist/resources/extensions/gsd/tests/worktree-manager.test.ts +141 -0
  182. package/dist/resources/extensions/gsd/tests/worktree.test.ts +597 -0
  183. package/dist/resources/extensions/gsd/tests/write-gate.test.ts +122 -0
  184. package/dist/resources/extensions/gsd/types.ts +296 -0
  185. package/dist/resources/extensions/gsd/unit-runtime.ts +184 -0
  186. package/dist/resources/extensions/gsd/workspace-index.ts +189 -0
  187. package/dist/resources/extensions/gsd/worktree-command.ts +845 -0
  188. package/dist/resources/extensions/gsd/worktree-manager.ts +459 -0
  189. package/dist/resources/extensions/gsd/{worktree.js → worktree.ts} +92 -61
  190. package/dist/resources/extensions/mac-tools/index.ts +852 -0
  191. package/dist/resources/extensions/mac-tools/swift-cli/Package.swift +22 -0
  192. package/dist/resources/extensions/mac-tools/swift-cli/Sources/main.swift +1318 -0
  193. package/dist/resources/extensions/mcporter/index.ts +429 -0
  194. package/dist/resources/extensions/remote-questions/config.ts +81 -0
  195. package/dist/resources/extensions/remote-questions/discord-adapter.ts +128 -0
  196. package/dist/resources/extensions/remote-questions/format.ts +163 -0
  197. package/dist/resources/extensions/remote-questions/manager.ts +192 -0
  198. package/dist/resources/extensions/remote-questions/remote-command.ts +361 -0
  199. package/dist/resources/extensions/remote-questions/slack-adapter.ts +92 -0
  200. package/dist/resources/extensions/remote-questions/status.ts +31 -0
  201. package/dist/resources/extensions/remote-questions/store.ts +77 -0
  202. package/dist/resources/extensions/remote-questions/types.ts +75 -0
  203. package/dist/resources/extensions/search-the-web/cache.ts +78 -0
  204. package/dist/resources/extensions/search-the-web/command-search-provider.ts +99 -0
  205. package/dist/resources/extensions/search-the-web/format.ts +258 -0
  206. package/dist/resources/extensions/search-the-web/http.ts +238 -0
  207. package/dist/resources/extensions/search-the-web/index.ts +65 -0
  208. package/dist/resources/extensions/search-the-web/native-search.ts +165 -0
  209. package/dist/resources/extensions/search-the-web/provider.ts +136 -0
  210. package/dist/resources/extensions/search-the-web/tavily.ts +116 -0
  211. package/dist/resources/extensions/search-the-web/tool-fetch-page.ts +581 -0
  212. package/dist/resources/extensions/search-the-web/tool-llm-context.ts +620 -0
  213. package/dist/resources/extensions/search-the-web/tool-search.ts +635 -0
  214. package/dist/resources/extensions/search-the-web/url-utils.ts +91 -0
  215. package/dist/resources/extensions/shared/bundled-extension-paths.ts +11 -0
  216. package/dist/resources/extensions/shared/confirm-ui.ts +126 -0
  217. package/dist/resources/extensions/shared/interview-ui.ts +613 -0
  218. package/dist/resources/extensions/shared/next-action-ui.ts +197 -0
  219. package/dist/resources/extensions/shared/progress-widget.ts +282 -0
  220. package/dist/resources/extensions/shared/terminal.ts +23 -0
  221. package/dist/resources/extensions/shared/thinking-widget.ts +107 -0
  222. package/dist/resources/extensions/shared/ui.ts +400 -0
  223. package/dist/resources/extensions/shared/wizard-ui.ts +551 -0
  224. package/dist/resources/extensions/slash-commands/audit.ts +88 -0
  225. package/dist/resources/extensions/slash-commands/clear.ts +10 -0
  226. package/dist/resources/extensions/slash-commands/create-extension.ts +297 -0
  227. package/dist/resources/extensions/slash-commands/create-slash-command.ts +234 -0
  228. package/dist/resources/extensions/slash-commands/index.ts +12 -0
  229. package/dist/resources/extensions/subagent/agents.ts +126 -0
  230. package/dist/resources/extensions/subagent/index.ts +1072 -0
  231. package/dist/resources/extensions/subagent/isolation.ts +498 -0
  232. package/dist/resources/extensions/ttsr/index.ts +163 -0
  233. package/dist/resources/extensions/ttsr/rule-loader.ts +121 -0
  234. package/dist/resources/extensions/ttsr/ttsr-interrupt.md +6 -0
  235. package/dist/resources/extensions/ttsr/ttsr-manager.ts +430 -0
  236. package/dist/resources/extensions/universal-config/discovery.ts +78 -0
  237. package/dist/resources/extensions/universal-config/format.ts +160 -0
  238. package/dist/resources/extensions/universal-config/index.ts +118 -0
  239. package/dist/resources/extensions/universal-config/package.json +11 -0
  240. package/dist/resources/extensions/universal-config/scanners.ts +579 -0
  241. package/dist/resources/extensions/universal-config/tests/discovery.test.ts +111 -0
  242. package/dist/resources/extensions/universal-config/tests/format.test.ts +111 -0
  243. package/dist/resources/extensions/universal-config/tests/scanners.test.ts +438 -0
  244. package/dist/resources/extensions/universal-config/tools.ts +60 -0
  245. package/dist/resources/extensions/universal-config/types.ts +116 -0
  246. package/dist/resources/extensions/voice/index.ts +271 -0
  247. package/dist/resources/extensions/voice/speech-recognizer.py +504 -0
  248. package/dist/resources/extensions/voice/speech-recognizer.swift +154 -0
  249. package/dist/resources/skills/debug-like-expert/SKILL.md +231 -0
  250. package/dist/resources/skills/debug-like-expert/references/debugging-mindset.md +253 -0
  251. package/dist/resources/skills/debug-like-expert/references/hypothesis-testing.md +373 -0
  252. package/dist/resources/skills/debug-like-expert/references/investigation-techniques.md +337 -0
  253. package/dist/resources/skills/debug-like-expert/references/verification-patterns.md +425 -0
  254. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +361 -0
  255. package/dist/resources/skills/frontend-design/SKILL.md +45 -0
  256. package/dist/resources/skills/github-workflows/SKILL.md +92 -0
  257. package/dist/resources/skills/github-workflows/references/gh/SKILL.md +255 -0
  258. package/dist/resources/skills/github-workflows/references/gh/references/issue-stories.md +204 -0
  259. package/dist/resources/skills/github-workflows/references/gh/references/labels.md +170 -0
  260. package/dist/resources/skills/github-workflows/references/gh/references/milestones.md +158 -0
  261. package/dist/resources/skills/github-workflows/references/gh/references/projects-v2.md +177 -0
  262. package/dist/resources/skills/github-workflows/references/gh/scripts/experiment_cleanup.py +191 -0
  263. package/dist/resources/skills/github-workflows/references/gh/scripts/github_project_setup.py +799 -0
  264. package/dist/resources/skills/github-workflows/references/gh/tests/__init__.py +0 -0
  265. package/dist/resources/skills/github-workflows/references/gh/tests/test_github_project_setup.py +608 -0
  266. package/dist/resources/skills/swiftui/SKILL.md +208 -0
  267. package/dist/resources/skills/swiftui/references/animations.md +921 -0
  268. package/dist/resources/skills/swiftui/references/architecture.md +1561 -0
  269. package/dist/resources/skills/swiftui/references/layout-system.md +1186 -0
  270. package/dist/resources/skills/swiftui/references/navigation.md +1492 -0
  271. package/dist/resources/skills/swiftui/references/networking-async.md +214 -0
  272. package/dist/resources/skills/swiftui/references/performance.md +1706 -0
  273. package/dist/resources/skills/swiftui/references/platform-integration.md +204 -0
  274. package/dist/resources/skills/swiftui/references/state-management.md +1443 -0
  275. package/dist/resources/skills/swiftui/references/swiftdata.md +297 -0
  276. package/dist/resources/skills/swiftui/references/testing-debugging.md +247 -0
  277. package/dist/resources/skills/swiftui/references/uikit-appkit-interop.md +218 -0
  278. package/dist/resources/skills/swiftui/workflows/add-feature.md +191 -0
  279. package/dist/resources/skills/swiftui/workflows/build-new-app.md +311 -0
  280. package/dist/resources/skills/swiftui/workflows/debug-swiftui.md +192 -0
  281. package/dist/resources/skills/swiftui/workflows/optimize-performance.md +197 -0
  282. package/dist/resources/skills/swiftui/workflows/ship-app.md +203 -0
  283. package/dist/resources/skills/swiftui/workflows/write-tests.md +235 -0
  284. package/dist/wizard.js +1 -0
  285. package/package.json +8 -6
  286. package/packages/native/dist/fd/index.d.ts +1 -0
  287. package/packages/native/dist/fd/index.js +1 -0
  288. package/packages/native/dist/grep/index.d.ts +2 -1
  289. package/packages/native/dist/grep/index.js +1 -0
  290. package/packages/native/src/__tests__/fd.test.mjs +35 -0
  291. package/packages/native/src/__tests__/grep.test.mjs +26 -9
  292. package/packages/native/src/fd/index.ts +1 -0
  293. package/packages/native/src/grep/index.ts +3 -2
  294. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  295. package/packages/pi-agent-core/dist/agent-loop.js +169 -55
  296. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  297. package/packages/pi-agent-core/dist/agent.d.ts +13 -1
  298. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  299. package/packages/pi-agent-core/dist/agent.js +16 -0
  300. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  301. package/packages/pi-agent-core/dist/types.d.ts +91 -1
  302. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  303. package/packages/pi-agent-core/dist/types.js.map +1 -1
  304. package/packages/pi-agent-core/src/agent-loop.ts +273 -63
  305. package/packages/pi-agent-core/src/agent.ts +24 -0
  306. package/packages/pi-agent-core/src/types.ts +98 -0
  307. package/packages/pi-ai/dist/env-api-keys.js +2 -0
  308. package/packages/pi-ai/dist/env-api-keys.js.map +1 -1
  309. package/packages/pi-ai/dist/models.generated.d.ts +314 -0
  310. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/models.generated.js +236 -0
  312. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  313. package/packages/pi-ai/dist/providers/google-gemini-cli.d.ts.map +1 -1
  314. package/packages/pi-ai/dist/providers/google-gemini-cli.js +6 -0
  315. package/packages/pi-ai/dist/providers/google-gemini-cli.js.map +1 -1
  316. package/packages/pi-ai/dist/providers/openai-completions.d.ts.map +1 -1
  317. package/packages/pi-ai/dist/providers/openai-completions.js +2 -0
  318. package/packages/pi-ai/dist/providers/openai-completions.js.map +1 -1
  319. package/packages/pi-ai/dist/types.d.ts +1 -1
  320. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  321. package/packages/pi-ai/dist/types.js.map +1 -1
  322. package/packages/pi-ai/src/env-api-keys.ts +2 -0
  323. package/packages/pi-ai/src/models.generated.ts +236 -0
  324. package/packages/pi-ai/src/providers/google-gemini-cli.ts +8 -0
  325. package/packages/pi-ai/src/providers/openai-completions.ts +3 -0
  326. package/packages/pi-ai/src/types.ts +2 -1
  327. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/cli/args.js +1 -0
  329. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +26 -0
  331. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  332. package/packages/pi-coding-agent/dist/core/agent-session.js +137 -22
  333. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  334. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +20 -0
  335. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  336. package/packages/pi-coding-agent/dist/core/auth-storage.js +43 -0
  337. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  338. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts +51 -0
  339. package/packages/pi-coding-agent/dist/core/fallback-resolver.d.ts.map +1 -0
  340. package/packages/pi-coding-agent/dist/core/fallback-resolver.js +119 -0
  341. package/packages/pi-coding-agent/dist/core/fallback-resolver.js.map +1 -0
  342. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts +2 -0
  343. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.d.ts.map +1 -0
  344. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js +183 -0
  345. package/packages/pi-coding-agent/dist/core/fallback-resolver.test.js.map +1 -0
  346. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  347. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  348. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  349. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  350. package/packages/pi-coding-agent/dist/core/model-resolver.d.ts.map +1 -1
  351. package/packages/pi-coding-agent/dist/core/model-resolver.js +1 -0
  352. package/packages/pi-coding-agent/dist/core/model-resolver.js.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/session-manager.d.ts +12 -1
  354. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/session-manager.js +37 -1
  356. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts +2 -0
  358. package/packages/pi-coding-agent/dist/core/session-manager.test.d.ts.map +1 -0
  359. package/packages/pi-coding-agent/dist/core/session-manager.test.js +61 -0
  360. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -0
  361. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  362. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  363. package/packages/pi-coding-agent/dist/core/settings-manager.js +47 -0
  364. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  365. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  366. package/packages/pi-coding-agent/dist/core/tools/find.js +1 -0
  367. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  368. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +6 -15
  370. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  371. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts +18 -1
  372. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  373. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +46 -4
  374. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +25 -2
  377. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  378. package/packages/pi-coding-agent/src/cli/args.ts +1 -0
  379. package/packages/pi-coding-agent/src/core/agent-session.ts +167 -22
  380. package/packages/pi-coding-agent/src/core/auth-storage.ts +45 -0
  381. package/packages/pi-coding-agent/src/core/fallback-resolver.test.ts +229 -0
  382. package/packages/pi-coding-agent/src/core/fallback-resolver.ts +165 -0
  383. package/packages/pi-coding-agent/src/core/index.ts +1 -0
  384. package/packages/pi-coding-agent/src/core/model-resolver.ts +1 -0
  385. package/packages/pi-coding-agent/src/core/session-manager.test.ts +65 -0
  386. package/packages/pi-coding-agent/src/core/session-manager.ts +51 -1
  387. package/packages/pi-coding-agent/src/core/settings-manager.ts +66 -0
  388. package/packages/pi-coding-agent/src/core/tools/find.ts +1 -0
  389. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +6 -16
  390. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +49 -4
  391. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -2
  392. package/packages/pi-tui/dist/autocomplete.d.ts.map +1 -1
  393. package/packages/pi-tui/dist/autocomplete.js +3 -4
  394. package/packages/pi-tui/dist/autocomplete.js.map +1 -1
  395. package/packages/pi-tui/dist/components/editor.d.ts +7 -0
  396. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  397. package/packages/pi-tui/dist/components/editor.js +57 -50
  398. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  399. package/packages/pi-tui/src/autocomplete.ts +3 -5
  400. package/packages/pi-tui/src/components/editor.ts +70 -49
  401. package/pkg/dist/core/export-html/ansi-to-html.d.ts +22 -0
  402. package/pkg/dist/core/export-html/ansi-to-html.d.ts.map +1 -0
  403. package/pkg/dist/core/export-html/ansi-to-html.js +249 -0
  404. package/pkg/dist/core/export-html/ansi-to-html.js.map +1 -0
  405. package/pkg/dist/core/export-html/index.d.ts +37 -0
  406. package/pkg/dist/core/export-html/index.d.ts.map +1 -0
  407. package/pkg/dist/core/export-html/index.js +223 -0
  408. package/pkg/dist/core/export-html/index.js.map +1 -0
  409. package/pkg/dist/core/export-html/template.css +971 -0
  410. package/pkg/dist/core/export-html/template.html +54 -0
  411. package/pkg/dist/core/export-html/template.js +1583 -0
  412. package/pkg/dist/core/export-html/tool-renderer.d.ts +38 -0
  413. package/pkg/dist/core/export-html/tool-renderer.d.ts.map +1 -0
  414. package/pkg/dist/core/export-html/tool-renderer.js +70 -0
  415. package/pkg/dist/core/export-html/tool-renderer.js.map +1 -0
  416. package/pkg/dist/core/export-html/vendor/highlight.min.js +1213 -0
  417. package/pkg/dist/core/export-html/vendor/marked.min.js +6 -0
  418. package/scripts/postinstall.js +30 -17
  419. package/src/resources/extensions/bg-shell/index.ts +51 -7
  420. package/src/resources/extensions/gsd/activity-log.ts +61 -14
  421. package/src/resources/extensions/gsd/auto.ts +288 -19
  422. package/src/resources/extensions/gsd/commands.ts +9 -3
  423. package/src/resources/extensions/gsd/dashboard-overlay.ts +55 -12
  424. package/src/resources/extensions/gsd/docs/preferences-reference.md +25 -0
  425. package/src/resources/extensions/gsd/doctor.ts +60 -3
  426. package/src/resources/extensions/gsd/files.ts +45 -1
  427. package/src/resources/extensions/gsd/git-service.ts +46 -41
  428. package/src/resources/extensions/gsd/guided-flow.ts +81 -9
  429. package/src/resources/extensions/gsd/index.ts +62 -1
  430. package/src/resources/extensions/gsd/native-git-bridge.ts +181 -0
  431. package/src/resources/extensions/gsd/paths.ts +35 -4
  432. package/src/resources/extensions/gsd/post-unit-hooks.ts +449 -0
  433. package/src/resources/extensions/gsd/preferences.ts +232 -1
  434. package/src/resources/extensions/gsd/prompt-loader.ts +45 -3
  435. package/src/resources/extensions/gsd/prompts/complete-milestone.md +1 -1
  436. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -3
  437. package/src/resources/extensions/gsd/prompts/discuss.md +10 -8
  438. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  439. package/src/resources/extensions/gsd/prompts/guided-complete-slice.md +3 -1
  440. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +3 -1
  441. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +3 -1
  442. package/src/resources/extensions/gsd/prompts/guided-execute-task.md +3 -1
  443. package/src/resources/extensions/gsd/prompts/guided-plan-milestone.md +4 -2
  444. package/src/resources/extensions/gsd/prompts/guided-plan-slice.md +3 -1
  445. package/src/resources/extensions/gsd/prompts/guided-research-slice.md +3 -1
  446. package/src/resources/extensions/gsd/prompts/plan-milestone.md +9 -12
  447. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -3
  448. package/src/resources/extensions/gsd/prompts/queue.md +3 -1
  449. package/src/resources/extensions/gsd/prompts/research-milestone.md +1 -1
  450. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -1
  451. package/src/resources/extensions/gsd/state.ts +130 -18
  452. package/src/resources/extensions/gsd/templates/context.md +1 -1
  453. package/src/resources/extensions/gsd/templates/state.md +3 -3
  454. package/src/resources/extensions/gsd/tests/activity-log-save.test.ts +127 -0
  455. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +5 -1
  456. package/src/resources/extensions/gsd/tests/doctor.test.ts +115 -1
  457. package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +6 -2
  458. package/src/resources/extensions/gsd/tests/git-service.test.ts +35 -35
  459. package/src/resources/extensions/gsd/tests/idle-recovery.test.ts +8 -8
  460. package/src/resources/extensions/gsd/tests/integration-mixed-milestones.test.ts +4 -1
  461. package/src/resources/extensions/gsd/tests/network-error-fallback.test.ts +54 -0
  462. package/src/resources/extensions/gsd/tests/orphaned-branch.test.ts +5 -5
  463. package/src/resources/extensions/gsd/tests/post-unit-hooks.test.ts +297 -0
  464. package/src/resources/extensions/gsd/tests/preferences-hooks.test.ts +226 -0
  465. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +12 -0
  466. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +6 -0
  467. package/src/resources/extensions/gsd/tests/worktree-integration.test.ts +4 -4
  468. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +4 -4
  469. package/src/resources/extensions/gsd/tests/worktree.test.ts +19 -19
  470. package/src/resources/extensions/gsd/types.ts +109 -0
  471. package/src/resources/extensions/gsd/worktree-manager.ts +72 -13
  472. package/src/resources/extensions/gsd/worktree.ts +5 -4
  473. package/src/resources/extensions/search-the-web/command-search-provider.ts +8 -4
  474. package/src/resources/extensions/search-the-web/native-search.ts +32 -23
  475. package/src/resources/extensions/search-the-web/provider.ts +19 -2
  476. package/src/resources/extensions/search-the-web/tool-fetch-page.ts +62 -0
  477. package/src/resources/extensions/search-the-web/tool-llm-context.ts +62 -3
  478. package/src/resources/extensions/search-the-web/tool-search.ts +62 -3
  479. package/src/resources/extensions/shared/bundled-extension-paths.ts +11 -0
  480. package/src/resources/extensions/subagent/index.ts +2 -1
  481. package/src/resources/skills/github-workflows/SKILL.md +5 -0
  482. package/dist/resources/extensions/gsd/git-service.d.ts +0 -225
  483. package/dist/resources/extensions/gsd/git-service.js +0 -756
  484. package/dist/resources/extensions/gsd/preferences.d.ts +0 -122
  485. package/dist/resources/extensions/gsd/preferences.js +0 -616
  486. package/dist/resources/extensions/gsd/worktree.d.ts +0 -106
  487. package/dist/resources/extensions/remote-questions/config.d.ts +0 -14
  488. package/dist/resources/extensions/remote-questions/config.js +0 -68
  489. package/dist/resources/extensions/remote-questions/discord-adapter.d.ts +0 -17
  490. package/dist/resources/extensions/remote-questions/discord-adapter.js +0 -118
  491. package/dist/resources/extensions/remote-questions/format.d.ts +0 -38
  492. package/dist/resources/extensions/remote-questions/format.js +0 -119
  493. package/dist/resources/extensions/remote-questions/manager.d.ts +0 -23
  494. package/dist/resources/extensions/remote-questions/manager.js +0 -161
  495. package/dist/resources/extensions/remote-questions/remote-command.d.ts +0 -6
  496. package/dist/resources/extensions/remote-questions/remote-command.js +0 -358
  497. package/dist/resources/extensions/remote-questions/slack-adapter.d.ts +0 -15
  498. package/dist/resources/extensions/remote-questions/slack-adapter.js +0 -82
  499. package/dist/resources/extensions/remote-questions/status.d.ts +0 -9
  500. package/dist/resources/extensions/remote-questions/status.js +0 -25
  501. package/dist/resources/extensions/remote-questions/store.d.ts +0 -11
  502. package/dist/resources/extensions/remote-questions/store.js +0 -66
  503. package/dist/resources/extensions/remote-questions/types.d.ts +0 -68
  504. package/dist/resources/extensions/remote-questions/types.js +0 -4
@@ -0,0 +1,594 @@
1
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync, existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { tmpdir } from "node:os";
4
+
5
+ import { formatDoctorReport, runGSDDoctor, summarizeDoctorIssues, filterDoctorIssues, selectDoctorScope, validateTitle } from "../doctor.js";
6
+ import { createTestContext } from './test-helpers.ts';
7
+
8
+ const { assertEq, assertTrue, report } = createTestContext();
9
+ const tmpBase = mkdtempSync(join(tmpdir(), "gsd-doctor-test-"));
10
+ const gsd = join(tmpBase, ".gsd");
11
+ const mDir = join(gsd, "milestones", "M001");
12
+ const sDir = join(mDir, "slices", "S01");
13
+ const tDir = join(sDir, "tasks");
14
+ mkdirSync(tDir, { recursive: true });
15
+
16
+ writeFileSync(join(mDir, "M001-ROADMAP.md"), `# M001: Test Milestone
17
+
18
+ ## Slices
19
+ - [ ] **S01: Demo Slice** \`risk:low\` \`depends:[]\`
20
+ > After this: demo works
21
+ `);
22
+
23
+ writeFileSync(join(sDir, "S01-PLAN.md"), `# S01: Demo Slice
24
+
25
+ **Goal:** Demo
26
+ **Demo:** Demo
27
+
28
+ ## Must-Haves
29
+ - done
30
+
31
+ ## Tasks
32
+ - [x] **T01: Implement thing** \`est:10m\`
33
+ Task is complete.
34
+ `);
35
+
36
+ writeFileSync(join(tDir, "T01-SUMMARY.md"), `---
37
+ id: T01
38
+ parent: S01
39
+ milestone: M001
40
+ provides: []
41
+ requires: []
42
+ affects: []
43
+ key_files: []
44
+ key_decisions: []
45
+ patterns_established: []
46
+ observability_surfaces: []
47
+ drill_down_paths: []
48
+ duration: 10m
49
+ verification_result: passed
50
+ completed_at: 2026-03-09T00:00:00Z
51
+ ---
52
+
53
+ # T01: Implement thing
54
+
55
+ **Done**
56
+
57
+ ## What Happened
58
+ Implemented.
59
+
60
+ ## Diagnostics
61
+ - log
62
+ `);
63
+
64
+ async function main(): Promise<void> {
65
+ console.log("\n=== doctor diagnose ===");
66
+ {
67
+ const report = await runGSDDoctor(tmpBase, { fix: false });
68
+ assertTrue(!report.ok, "report is not ok when completion artifacts are missing");
69
+ assertTrue(report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_summary"), "detects missing slice summary");
70
+ assertTrue(report.issues.some(issue => issue.code === "all_tasks_done_missing_slice_uat"), "detects missing slice UAT");
71
+ }
72
+
73
+ console.log("\n=== doctor formatting ===");
74
+ {
75
+ const report = await runGSDDoctor(tmpBase, { fix: false });
76
+ const summary = summarizeDoctorIssues(report.issues);
77
+ assertEq(summary.errors, 2, "two blocking errors in summary");
78
+ const scoped = filterDoctorIssues(report.issues, { scope: "M001/S01", includeWarnings: true });
79
+ assertTrue(scoped.length >= 2, "scope filter keeps slice issues");
80
+ const text = formatDoctorReport(report, { scope: "M001/S01", includeWarnings: true, maxIssues: 5 });
81
+ assertTrue(text.includes("Scope: M001/S01"), "formatted report shows scope");
82
+ assertTrue(text.includes("Top issue types:"), "formatted report shows grouped issue types");
83
+ }
84
+
85
+ console.log("\n=== doctor default scope ===");
86
+ {
87
+ const scope = await selectDoctorScope(tmpBase);
88
+ assertEq(scope, "M001/S01", "default doctor scope targets the active slice");
89
+ }
90
+
91
+ console.log("\n=== doctor fix ===");
92
+ {
93
+ const report = await runGSDDoctor(tmpBase, { fix: true });
94
+ if (report.fixesApplied.length < 3) console.error(report);
95
+ assertTrue(report.fixesApplied.length >= 3, "applies multiple fixes");
96
+ assertTrue(existsSync(join(sDir, "S01-SUMMARY.md")), "creates placeholder slice summary");
97
+ assertTrue(existsSync(join(sDir, "S01-UAT.md")), "creates placeholder UAT");
98
+
99
+ const plan = readFileSync(join(sDir, "S01-PLAN.md"), "utf-8");
100
+ assertTrue(plan.includes("- [x] **T01:"), "marks task checkbox done");
101
+
102
+ const roadmap = readFileSync(join(mDir, "M001-ROADMAP.md"), "utf-8");
103
+ assertTrue(roadmap.includes("- [x] **S01:"), "marks slice checkbox done");
104
+
105
+ const state = readFileSync(join(gsd, "STATE.md"), "utf-8");
106
+ assertTrue(state.includes("# GSD State"), "writes state file");
107
+ }
108
+
109
+ rmSync(tmpBase, { recursive: true, force: true });
110
+
111
+ // ─── Milestone summary detection: missing summary ──────────────────────
112
+ console.log("\n=== doctor detects missing milestone summary ===");
113
+ {
114
+ const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-test-"));
115
+ const msGsd = join(msBase, ".gsd");
116
+ const msMDir = join(msGsd, "milestones", "M001");
117
+ const msSDir = join(msMDir, "slices", "S01");
118
+ const msTDir = join(msSDir, "tasks");
119
+ mkdirSync(msTDir, { recursive: true });
120
+
121
+ // Roadmap with ALL slices [x] — milestone is complete by slice status
122
+ writeFileSync(join(msMDir, "M001-ROADMAP.md"), `# M001: Test Milestone
123
+
124
+ ## Slices
125
+ - [x] **S01: Done Slice** \`risk:low\` \`depends:[]\`
126
+ > After this: done
127
+ `);
128
+
129
+ // Slice has plan with all tasks done
130
+ writeFileSync(join(msSDir, "S01-PLAN.md"), `# S01: Done Slice
131
+
132
+ **Goal:** Done
133
+ **Demo:** Done
134
+
135
+ ## Tasks
136
+ - [x] **T01: Done Task** \`est:10m\`
137
+ Done.
138
+ `);
139
+
140
+ // Task summary exists
141
+ writeFileSync(join(msTDir, "T01-SUMMARY.md"), `---
142
+ id: T01
143
+ parent: S01
144
+ milestone: M001
145
+ ---
146
+ # T01: Done
147
+ **Done**
148
+ ## What Happened
149
+ Done.
150
+ `);
151
+
152
+ // Slice summary exists (so slice-level checks pass)
153
+ writeFileSync(join(msSDir, "S01-SUMMARY.md"), `---
154
+ id: S01
155
+ parent: M001
156
+ ---
157
+ # S01: Done
158
+ `);
159
+
160
+ // Slice UAT exists (so slice-level checks pass)
161
+ writeFileSync(join(msSDir, "S01-UAT.md"), `# S01 UAT\nDone.\n`);
162
+
163
+ // NO milestone summary — this is the condition we're detecting
164
+
165
+ const report = await runGSDDoctor(msBase, { fix: false });
166
+ assertTrue(
167
+ report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
168
+ "detects missing milestone summary when all slices are done"
169
+ );
170
+ const msIssue = report.issues.find(issue => issue.code === "all_slices_done_missing_milestone_summary");
171
+ assertEq(msIssue?.scope, "milestone", "milestone summary issue has scope 'milestone'");
172
+ assertEq(msIssue?.severity, "warning", "milestone summary issue has severity 'warning'");
173
+ assertEq(msIssue?.unitId, "M001", "milestone summary issue unitId is 'M001'");
174
+ assertTrue(msIssue?.message?.includes("SUMMARY") ?? false, "milestone summary issue message mentions SUMMARY");
175
+
176
+ rmSync(msBase, { recursive: true, force: true });
177
+ }
178
+
179
+ // ─── Milestone summary detection: summary present (no false positive) ──
180
+ console.log("\n=== doctor does NOT flag milestone with summary ===");
181
+ {
182
+ const msBase = mkdtempSync(join(tmpdir(), "gsd-doctor-ms-ok-test-"));
183
+ const msGsd = join(msBase, ".gsd");
184
+ const msMDir = join(msGsd, "milestones", "M001");
185
+ const msSDir = join(msMDir, "slices", "S01");
186
+ const msTDir = join(msSDir, "tasks");
187
+ mkdirSync(msTDir, { recursive: true });
188
+
189
+ // Roadmap with ALL slices [x]
190
+ writeFileSync(join(msMDir, "M001-ROADMAP.md"), `# M001: Test Milestone
191
+
192
+ ## Slices
193
+ - [x] **S01: Done Slice** \`risk:low\` \`depends:[]\`
194
+ > After this: done
195
+ `);
196
+
197
+ writeFileSync(join(msSDir, "S01-PLAN.md"), `# S01: Done Slice
198
+
199
+ **Goal:** Done
200
+ **Demo:** Done
201
+
202
+ ## Tasks
203
+ - [x] **T01: Done Task** \`est:10m\`
204
+ Done.
205
+ `);
206
+
207
+ writeFileSync(join(msTDir, "T01-SUMMARY.md"), `---
208
+ id: T01
209
+ parent: S01
210
+ milestone: M001
211
+ ---
212
+ # T01: Done
213
+ **Done**
214
+ ## What Happened
215
+ Done.
216
+ `);
217
+
218
+ writeFileSync(join(msSDir, "S01-SUMMARY.md"), `---
219
+ id: S01
220
+ parent: M001
221
+ ---
222
+ # S01: Done
223
+ `);
224
+
225
+ writeFileSync(join(msSDir, "S01-UAT.md"), `# S01 UAT\nDone.\n`);
226
+
227
+ // Milestone summary EXISTS
228
+ writeFileSync(join(msMDir, "M001-SUMMARY.md"), `# M001 Summary\n\nMilestone complete.`);
229
+
230
+ const report = await runGSDDoctor(msBase, { fix: false });
231
+ assertTrue(
232
+ !report.issues.some(issue => issue.code === "all_slices_done_missing_milestone_summary"),
233
+ "does NOT report missing milestone summary when summary exists"
234
+ );
235
+
236
+ rmSync(msBase, { recursive: true, force: true });
237
+ }
238
+
239
+ // ─── blocker_discovered_no_replan detection ────────────────────────────
240
+ console.log("\n=== doctor detects blocker_discovered_no_replan ===");
241
+ {
242
+ const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-test-"));
243
+ const bGsd = join(bBase, ".gsd");
244
+ const bMDir = join(bGsd, "milestones", "M001");
245
+ const bSDir = join(bMDir, "slices", "S01");
246
+ const bTDir = join(bSDir, "tasks");
247
+ mkdirSync(bTDir, { recursive: true });
248
+
249
+ writeFileSync(join(bMDir, "M001-ROADMAP.md"), `# M001: Test Milestone
250
+
251
+ ## Slices
252
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
253
+ > After this: stuff works
254
+ `);
255
+
256
+ writeFileSync(join(bSDir, "S01-PLAN.md"), `# S01: Test Slice
257
+
258
+ **Goal:** Test
259
+ **Demo:** Test
260
+
261
+ ## Tasks
262
+ - [x] **T01: First task** \`est:10m\`
263
+ First task.
264
+
265
+ - [ ] **T02: Second task** \`est:10m\`
266
+ Second task.
267
+ `);
268
+
269
+ // Task summary with blocker_discovered: true
270
+ writeFileSync(join(bTDir, "T01-SUMMARY.md"), `---
271
+ id: T01
272
+ parent: S01
273
+ milestone: M001
274
+ provides: []
275
+ key_files: []
276
+ key_decisions: []
277
+ patterns_established: []
278
+ observability_surfaces: []
279
+ duration: 10m
280
+ verification_result: passed
281
+ completed_at: 2026-03-10T00:00:00Z
282
+ blocker_discovered: true
283
+ ---
284
+
285
+ # T01: First task
286
+
287
+ **Found a blocker.**
288
+
289
+ ## What Happened
290
+
291
+ Discovered an issue.
292
+ `);
293
+
294
+ // No REPLAN.md — should trigger the issue
295
+ const report = await runGSDDoctor(bBase, { fix: false });
296
+ const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
297
+ assertTrue(blockerIssues.length > 0, "detects blocker_discovered_no_replan");
298
+ assertEq(blockerIssues[0]?.severity, "warning", "blocker issue has warning severity");
299
+ assertEq(blockerIssues[0]?.scope, "slice", "blocker issue has slice scope");
300
+ assertTrue(blockerIssues[0]?.message?.includes("T01") ?? false, "blocker issue message mentions T01");
301
+ assertTrue(blockerIssues[0]?.message?.includes("S01") ?? false, "blocker issue message mentions S01");
302
+
303
+ rmSync(bBase, { recursive: true, force: true });
304
+ }
305
+
306
+ // ─── blocker_discovered with REPLAN.md (no false positive) ─────────────
307
+ console.log("\n=== doctor does NOT flag blocker when REPLAN.md exists ===");
308
+ {
309
+ const bBase = mkdtempSync(join(tmpdir(), "gsd-doctor-blocker-ok-test-"));
310
+ const bGsd = join(bBase, ".gsd");
311
+ const bMDir = join(bGsd, "milestones", "M001");
312
+ const bSDir = join(bMDir, "slices", "S01");
313
+ const bTDir = join(bSDir, "tasks");
314
+ mkdirSync(bTDir, { recursive: true });
315
+
316
+ writeFileSync(join(bMDir, "M001-ROADMAP.md"), `# M001: Test Milestone
317
+
318
+ ## Slices
319
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
320
+ > After this: stuff works
321
+ `);
322
+
323
+ writeFileSync(join(bSDir, "S01-PLAN.md"), `# S01: Test Slice
324
+
325
+ **Goal:** Test
326
+ **Demo:** Test
327
+
328
+ ## Tasks
329
+ - [x] **T01: First task** \`est:10m\`
330
+ First task.
331
+
332
+ - [ ] **T02: Second task** \`est:10m\`
333
+ Second task.
334
+ `);
335
+
336
+ writeFileSync(join(bTDir, "T01-SUMMARY.md"), `---
337
+ id: T01
338
+ parent: S01
339
+ milestone: M001
340
+ blocker_discovered: true
341
+ completed_at: 2026-03-10T00:00:00Z
342
+ ---
343
+
344
+ # T01: First task
345
+
346
+ **Found a blocker.**
347
+
348
+ ## What Happened
349
+
350
+ Discovered an issue.
351
+ `);
352
+
353
+ // REPLAN.md exists — should NOT trigger
354
+ writeFileSync(join(bSDir, "S01-REPLAN.md"), `# Replan\n\nAlready replanned.`);
355
+
356
+ const report = await runGSDDoctor(bBase, { fix: false });
357
+ const blockerIssues = report.issues.filter(i => i.code === "blocker_discovered_no_replan");
358
+ assertEq(blockerIssues.length, 0, "no blocker_discovered_no_replan when REPLAN.md exists");
359
+
360
+ rmSync(bBase, { recursive: true, force: true });
361
+ }
362
+
363
+ // ─── Must-have verification: all addressed → no issue ─────────────────
364
+ console.log("\n=== doctor: done task with must-haves all addressed → no issue ===");
365
+ {
366
+ const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-ok-"));
367
+ const mhGsd = join(mhBase, ".gsd");
368
+ const mhMDir = join(mhGsd, "milestones", "M001");
369
+ const mhSDir = join(mhMDir, "slices", "S01");
370
+ const mhTDir = join(mhSDir, "tasks");
371
+ mkdirSync(mhTDir, { recursive: true });
372
+
373
+ writeFileSync(join(mhMDir, "M001-ROADMAP.md"), `# M001: Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
374
+ writeFileSync(join(mhSDir, "S01-PLAN.md"), `# S01: Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [x] **T01: Implement** \`est:10m\`\n Done.\n`);
375
+
376
+ // Task plan with must-haves
377
+ writeFileSync(join(mhTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Must-Haves\n\n- [ ] \`parseWidgets\` function exported\n- [ ] Unit tests pass with zero failures\n`);
378
+
379
+ // Summary mentioning both must-haves
380
+ writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nAdded parseWidgets function. Unit tests pass with zero failures.\n`);
381
+
382
+ const report = await runGSDDoctor(mhBase, { fix: false });
383
+ assertTrue(
384
+ !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
385
+ "no must-have issue when all must-haves are addressed"
386
+ );
387
+
388
+ rmSync(mhBase, { recursive: true, force: true });
389
+ }
390
+
391
+ // ─── Must-have verification: not addressed → warning fired ───────────
392
+ console.log("\n=== doctor: done task with must-haves NOT addressed → warning ===");
393
+ {
394
+ const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-fail-"));
395
+ const mhGsd = join(mhBase, ".gsd");
396
+ const mhMDir = join(mhGsd, "milestones", "M001");
397
+ const mhSDir = join(mhMDir, "slices", "S01");
398
+ const mhTDir = join(mhSDir, "tasks");
399
+ mkdirSync(mhTDir, { recursive: true });
400
+
401
+ writeFileSync(join(mhMDir, "M001-ROADMAP.md"), `# M001: Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
402
+ writeFileSync(join(mhSDir, "S01-PLAN.md"), `# S01: Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [x] **T01: Implement** \`est:10m\`\n Done.\n`);
403
+
404
+ // Task plan with 3 must-haves
405
+ writeFileSync(join(mhTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Must-Haves\n\n- [ ] \`parseWidgets\` function exported\n- [ ] \`countWidgets\` utility added\n- [ ] Full regression suite passes\n`);
406
+
407
+ // Summary mentions only parseWidgets — the other two are missing
408
+ writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nAdded parseWidgets function.\n`);
409
+
410
+ const report = await runGSDDoctor(mhBase, { fix: false });
411
+ const mhIssue = report.issues.find(i => i.code === "task_done_must_haves_not_verified");
412
+ assertTrue(!!mhIssue, "must-have issue is fired when summary doesn't address all must-haves");
413
+ assertEq(mhIssue?.severity, "warning", "must-have issue is warning severity");
414
+ assertEq(mhIssue?.scope, "task", "must-have issue scope is task");
415
+ assertTrue(mhIssue?.message?.includes("3 must-haves") ?? false, "message mentions total must-have count");
416
+ assertTrue(mhIssue?.message?.includes("only 1") ?? false, "message mentions addressed count");
417
+ assertEq(mhIssue?.fixable, false, "must-have issue is not fixable");
418
+
419
+ rmSync(mhBase, { recursive: true, force: true });
420
+ }
421
+
422
+ // ─── Must-have verification: no task plan → no issue ─────────────────
423
+ console.log("\n=== doctor: done task with no task plan file → no issue ===");
424
+ {
425
+ const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-noplan-"));
426
+ const mhGsd = join(mhBase, ".gsd");
427
+ const mhMDir = join(mhGsd, "milestones", "M001");
428
+ const mhSDir = join(mhMDir, "slices", "S01");
429
+ const mhTDir = join(mhSDir, "tasks");
430
+ mkdirSync(mhTDir, { recursive: true });
431
+
432
+ writeFileSync(join(mhMDir, "M001-ROADMAP.md"), `# M001: Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
433
+ writeFileSync(join(mhSDir, "S01-PLAN.md"), `# S01: Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [x] **T01: Implement** \`est:10m\`\n Done.\n`);
434
+
435
+ // NO task plan file — just a summary
436
+ writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
437
+
438
+ const report = await runGSDDoctor(mhBase, { fix: false });
439
+ assertTrue(
440
+ !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
441
+ "no must-have issue when task plan file doesn't exist"
442
+ );
443
+
444
+ rmSync(mhBase, { recursive: true, force: true });
445
+ }
446
+
447
+ // ─── Must-have verification: plan exists but no Must-Haves section → no issue
448
+ console.log("\n=== doctor: done task with plan but no Must-Haves section → no issue ===");
449
+ {
450
+ const mhBase = mkdtempSync(join(tmpdir(), "gsd-doctor-mh-nosect-"));
451
+ const mhGsd = join(mhBase, ".gsd");
452
+ const mhMDir = join(mhGsd, "milestones", "M001");
453
+ const mhSDir = join(mhMDir, "slices", "S01");
454
+ const mhTDir = join(mhSDir, "tasks");
455
+ mkdirSync(mhTDir, { recursive: true });
456
+
457
+ writeFileSync(join(mhMDir, "M001-ROADMAP.md"), `# M001: Test\n\n## Slices\n- [ ] **S01: Slice** \`risk:low\` \`depends:[]\`\n > After this: done\n`);
458
+ writeFileSync(join(mhSDir, "S01-PLAN.md"), `# S01: Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [x] **T01: Implement** \`est:10m\`\n Done.\n`);
459
+
460
+ // Task plan with NO Must-Haves section
461
+ writeFileSync(join(mhTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Steps\n\n1. Do the thing.\n\n## Verification\n\n- Run tests.\n`);
462
+
463
+ writeFileSync(join(mhTDir, "T01-SUMMARY.md"), `---\nid: T01\nparent: S01\nmilestone: M001\n---\n# T01: Implement\n\n## What Happened\nDone.\n`);
464
+
465
+ const report = await runGSDDoctor(mhBase, { fix: false });
466
+ assertTrue(
467
+ !report.issues.some(i => i.code === "task_done_must_haves_not_verified"),
468
+ "no must-have issue when task plan has no Must-Haves section"
469
+ );
470
+
471
+ rmSync(mhBase, { recursive: true, force: true });
472
+ }
473
+
474
+ // ─── validateTitle: em dash and slash detection ────────────────────────
475
+ console.log("\n=== validateTitle: returns null for clean titles ===");
476
+ {
477
+ assertEq(validateTitle("Foundation"), null, "clean title passes");
478
+ assertEq(validateTitle("Build Core Systems"), null, "clean title with spaces passes");
479
+ assertEq(validateTitle("API v2 Integration"), null, "clean title with version passes");
480
+ assertEq(validateTitle(""), null, "empty title passes");
481
+ }
482
+
483
+ console.log("\n=== validateTitle: detects em dash ===");
484
+ {
485
+ const result = validateTitle("Foundation — Build Core");
486
+ assertTrue(result !== null, "detects em dash in title");
487
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
488
+ }
489
+
490
+ console.log("\n=== validateTitle: detects en dash ===");
491
+ {
492
+ const result = validateTitle("Phase 1 – Phase 2");
493
+ assertTrue(result !== null, "detects en dash in title");
494
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash for en dash");
495
+ }
496
+
497
+ console.log("\n=== validateTitle: detects forward slash ===");
498
+ {
499
+ const result = validateTitle("Client/Server");
500
+ assertTrue(result !== null, "detects forward slash in title");
501
+ assertTrue(result!.includes("forward slash"), "message mentions forward slash");
502
+ }
503
+
504
+ console.log("\n=== validateTitle: detects both em dash and slash ===");
505
+ {
506
+ const result = validateTitle("Client — Server/API");
507
+ assertTrue(result !== null, "detects both delimiters");
508
+ assertTrue(result!.includes("em/en dash"), "message mentions em/en dash");
509
+ assertTrue(result!.includes("forward slash"), "message mentions forward slash");
510
+ }
511
+
512
+ // ─── doctor detects delimiter_in_title for milestone ───────────────────
513
+ console.log("\n=== doctor detects em dash in milestone title ===");
514
+ {
515
+ const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-test-"));
516
+ const dtGsd = join(dtBase, ".gsd");
517
+ const dtMDir = join(dtGsd, "milestones", "M001");
518
+ const dtSDir = join(dtMDir, "slices", "S01");
519
+ const dtTDir = join(dtSDir, "tasks");
520
+ mkdirSync(dtTDir, { recursive: true });
521
+
522
+ // Roadmap with em dash in milestone title
523
+ writeFileSync(join(dtMDir, "M001-ROADMAP.md"), `# M001: Foundation — Build Core\n\n## Slices\n- [ ] **S01: Demo Slice** \`risk:low\` \`depends:[]\`\n > After this: demo works\n`);
524
+ writeFileSync(join(dtSDir, "S01-PLAN.md"), `# S01: Demo Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [ ] **T01: Implement** \`est:10m\`\n Task.\n`);
525
+ writeFileSync(join(dtTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Steps\n\n1. Do the thing.\n`);
526
+
527
+ const report = await runGSDDoctor(dtBase, { fix: false });
528
+ const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
529
+ assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for milestone with em dash");
530
+ const milestoneIssue = dtIssues.find(i => i.scope === "milestone");
531
+ assertTrue(milestoneIssue !== undefined, "delimiter issue has milestone scope");
532
+ assertEq(milestoneIssue?.severity, "warning", "delimiter issue has warning severity");
533
+ assertEq(milestoneIssue?.unitId, "M001", "delimiter issue unitId is M001");
534
+ assertTrue(milestoneIssue?.message?.includes("em/en dash") ?? false, "issue message mentions em/en dash");
535
+ assertEq(milestoneIssue?.fixable, false, "delimiter issue is not auto-fixable");
536
+
537
+ rmSync(dtBase, { recursive: true, force: true });
538
+ }
539
+
540
+ // ─── doctor detects delimiter_in_title for slice ────────────────────────
541
+ console.log("\n=== doctor detects em dash in slice title ===");
542
+ {
543
+ const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-slice-"));
544
+ const dtGsd = join(dtBase, ".gsd");
545
+ const dtMDir = join(dtGsd, "milestones", "M001");
546
+ const dtSDir = join(dtMDir, "slices", "S01");
547
+ const dtTDir = join(dtSDir, "tasks");
548
+ mkdirSync(dtTDir, { recursive: true });
549
+
550
+ // Roadmap with em dash in slice title (milestone title is clean)
551
+ writeFileSync(join(dtMDir, "M001-ROADMAP.md"), `# M001: Clean Milestone\n\n## Slices\n- [ ] **S01: Core — Foundation** \`risk:low\` \`depends:[]\`\n > After this: demo works\n`);
552
+ writeFileSync(join(dtSDir, "S01-PLAN.md"), `# S01: Core — Foundation\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [ ] **T01: Implement** \`est:10m\`\n Task.\n`);
553
+ writeFileSync(join(dtTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Steps\n\n1. Do the thing.\n`);
554
+
555
+ const report = await runGSDDoctor(dtBase, { fix: false });
556
+ const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
557
+ assertTrue(dtIssues.length >= 1, "detects delimiter_in_title for slice with em dash");
558
+ const sliceIssue = dtIssues.find(i => i.scope === "slice");
559
+ assertTrue(sliceIssue !== undefined, "delimiter issue has slice scope");
560
+ assertEq(sliceIssue?.severity, "warning", "slice delimiter issue has warning severity");
561
+ assertEq(sliceIssue?.unitId, "M001/S01", "slice delimiter issue unitId is M001/S01");
562
+
563
+ rmSync(dtBase, { recursive: true, force: true });
564
+ }
565
+
566
+ // ─── doctor does NOT flag clean titles ──────────────────────────────────
567
+ console.log("\n=== doctor does NOT flag milestone with clean title ===");
568
+ {
569
+ const dtBase = mkdtempSync(join(tmpdir(), "gsd-doctor-dt-clean-"));
570
+ const dtGsd = join(dtBase, ".gsd");
571
+ const dtMDir = join(dtGsd, "milestones", "M001");
572
+ const dtSDir = join(dtMDir, "slices", "S01");
573
+ const dtTDir = join(dtSDir, "tasks");
574
+ mkdirSync(dtTDir, { recursive: true });
575
+
576
+ // Roadmap with clean titles (no delimiters)
577
+ writeFileSync(join(dtMDir, "M001-ROADMAP.md"), `# M001: Foundation Build Core\n\n## Slices\n- [ ] **S01: Demo Slice** \`risk:low\` \`depends:[]\`\n > After this: demo works\n`);
578
+ writeFileSync(join(dtSDir, "S01-PLAN.md"), `# S01: Demo Slice\n\n**Goal:** Demo\n**Demo:** Demo\n\n## Tasks\n- [ ] **T01: Implement** \`est:10m\`\n Task.\n`);
579
+ writeFileSync(join(dtTDir, "T01-PLAN.md"), `# T01: Implement\n\n## Steps\n\n1. Do the thing.\n`);
580
+
581
+ const report = await runGSDDoctor(dtBase, { fix: false });
582
+ const dtIssues = report.issues.filter(i => i.code === "delimiter_in_title");
583
+ assertEq(dtIssues.length, 0, "no delimiter_in_title issues for clean titles");
584
+
585
+ rmSync(dtBase, { recursive: true, force: true });
586
+ }
587
+
588
+ report();
589
+ }
590
+
591
+ main().catch((error) => {
592
+ console.error(error);
593
+ process.exit(1);
594
+ });