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,493 @@
1
+ import { mkdtempSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { join, dirname } from 'node:path';
3
+ import { tmpdir } from 'node:os';
4
+ import { fileURLToPath } from 'node:url';
5
+
6
+ import { parseSummary } from '../files.ts';
7
+ import { deriveState } from '../state.ts';
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
10
+ const worktreePromptsDir = join(__dirname, '..', 'prompts');
11
+
12
+ /**
13
+ * Load a prompt template from the worktree prompts directory
14
+ * and apply variable substitution (mirrors loadPrompt logic).
15
+ */
16
+ function loadPromptFromWorktree(name: string, vars: Record<string, string> = {}): string {
17
+ const path = join(worktreePromptsDir, `${name}.md`);
18
+ let content = readFileSync(path, 'utf-8');
19
+ for (const [key, value] of Object.entries(vars)) {
20
+ content = content.replaceAll(`{{${key}}}`, value);
21
+ }
22
+ return content.trim();
23
+ }
24
+
25
+ const { assertEq, assertTrue, report } = createTestContext();
26
+ // ─── Fixture Helpers ───────────────────────────────────────────────────────
27
+
28
+ function createFixtureBase(): string {
29
+ const base = mkdtempSync(join(tmpdir(), 'gsd-replan-test-'));
30
+ mkdirSync(join(base, '.gsd', 'milestones'), { recursive: true });
31
+ return base;
32
+ }
33
+
34
+ function writeRoadmap(base: string, mid: string, content: string): void {
35
+ const dir = join(base, '.gsd', 'milestones', mid);
36
+ mkdirSync(dir, { recursive: true });
37
+ writeFileSync(join(dir, `${mid}-ROADMAP.md`), content);
38
+ }
39
+
40
+ function writePlan(base: string, mid: string, sid: string, content: string): void {
41
+ const dir = join(base, '.gsd', 'milestones', mid, 'slices', sid);
42
+ mkdirSync(join(dir, 'tasks'), { recursive: true });
43
+ writeFileSync(join(dir, `${sid}-PLAN.md`), content);
44
+ }
45
+
46
+ function writeTaskSummary(base: string, mid: string, sid: string, tid: string, content: string): void {
47
+ const dir = join(base, '.gsd', 'milestones', mid, 'slices', sid, 'tasks');
48
+ mkdirSync(dir, { recursive: true });
49
+ writeFileSync(join(dir, `${tid}-SUMMARY.md`), content);
50
+ }
51
+
52
+ function writeReplanFile(base: string, mid: string, sid: string, content: string): void {
53
+ const dir = join(base, '.gsd', 'milestones', mid, 'slices', sid);
54
+ mkdirSync(dir, { recursive: true });
55
+ writeFileSync(join(dir, `${sid}-REPLAN.md`), content);
56
+ }
57
+
58
+ /** Standard roadmap with one slice having no dependencies */
59
+ const ROADMAP_ONE_SLICE = `# M001: Test Milestone
60
+
61
+ **Vision:** Test vision.
62
+
63
+ ## Slices
64
+
65
+ - [ ] **S01: Test Slice** \`risk:low\` \`depends:[]\`
66
+ > After this: stuff works
67
+ `;
68
+
69
+ /** Plan with T01 done, T02 not done */
70
+ function makePlanT01DoneT02Pending(): string {
71
+ return `# S01: Test Slice
72
+
73
+ **Goal:** Do things.
74
+ **Demo:** It works.
75
+
76
+ ## Tasks
77
+
78
+ - [x] **T01: First task** \`est:15m\`
79
+ First task description.
80
+
81
+ - [ ] **T02: Second task** \`est:15m\`
82
+ Second task description.
83
+ `;
84
+ }
85
+
86
+ /** Plan with T01 and T02 done, T03 not done */
87
+ function makePlanT01T02DoneT03Pending(): string {
88
+ return `# S01: Test Slice
89
+
90
+ **Goal:** Do things.
91
+ **Demo:** It works.
92
+
93
+ ## Tasks
94
+
95
+ - [x] **T01: First task** \`est:15m\`
96
+ First task description.
97
+
98
+ - [x] **T02: Second task** \`est:15m\`
99
+ Second task description.
100
+
101
+ - [ ] **T03: Third task** \`est:15m\`
102
+ Third task description.
103
+ `;
104
+ }
105
+
106
+ /** Minimal task summary with blocker_discovered flag */
107
+ function makeTaskSummary(tid: string, blockerDiscovered: boolean): string {
108
+ return `---
109
+ id: ${tid}
110
+ parent: S01
111
+ milestone: M001
112
+ provides: []
113
+ key_files: []
114
+ key_decisions: []
115
+ patterns_established: []
116
+ observability_surfaces: []
117
+ duration: 15min
118
+ verification_result: passed
119
+ completed_at: 2025-03-10T12:00:00Z
120
+ blocker_discovered: ${blockerDiscovered}
121
+ ---
122
+
123
+ # ${tid}: Test Task
124
+
125
+ **Did something.**
126
+
127
+ ## What Happened
128
+
129
+ Work was done.
130
+ `;
131
+ }
132
+
133
+ // ═══════════════════════════════════════════════════════════════════════════
134
+ // Parser Extraction: blocker_discovered
135
+ // ═══════════════════════════════════════════════════════════════════════════
136
+
137
+ console.log('\n=== parseSummary: blocker_discovered true (string) ===');
138
+ {
139
+ const content = `---
140
+ id: T01
141
+ parent: S03
142
+ milestone: M002
143
+ blocker_discovered: true
144
+ completed_at: 2025-03-10T12:00:00Z
145
+ ---
146
+
147
+ # T01: Test Task
148
+
149
+ **One-liner.**
150
+
151
+ ## What Happened
152
+
153
+ Found a blocker.
154
+ `;
155
+
156
+ const s = parseSummary(content);
157
+ assertEq(s.frontmatter.blocker_discovered, true, 'blocker_discovered: true (string) extracts as true');
158
+ }
159
+
160
+ console.log('\n=== parseSummary: blocker_discovered false (string) ===');
161
+ {
162
+ const content = `---
163
+ id: T02
164
+ parent: S03
165
+ milestone: M002
166
+ blocker_discovered: false
167
+ completed_at: 2025-03-10T12:00:00Z
168
+ ---
169
+
170
+ # T02: Normal Task
171
+
172
+ **One-liner.**
173
+
174
+ ## What Happened
175
+
176
+ No blocker.
177
+ `;
178
+
179
+ const s = parseSummary(content);
180
+ assertEq(s.frontmatter.blocker_discovered, false, 'blocker_discovered: false extracts as false');
181
+ }
182
+
183
+ console.log('\n=== parseSummary: blocker_discovered missing (defaults to false) ===');
184
+ {
185
+ const content = `---
186
+ id: T03
187
+ parent: S03
188
+ milestone: M002
189
+ completed_at: 2025-03-10T12:00:00Z
190
+ ---
191
+
192
+ # T03: No Blocker Field
193
+
194
+ **One-liner.**
195
+
196
+ ## What Happened
197
+
198
+ No blocker field at all.
199
+ `;
200
+
201
+ const s = parseSummary(content);
202
+ assertEq(s.frontmatter.blocker_discovered, false, 'blocker_discovered missing defaults to false');
203
+ }
204
+
205
+ console.log('\n=== parseSummary: blocker_discovered true (boolean from YAML) ===');
206
+ {
207
+ // YAML parsers may deliver `true` as a boolean rather than the string "true"
208
+ // We test this via a summary that has blocker_discovered: true with no quotes
209
+ // The YAML parser in parseFrontmatterMap may return boolean true directly
210
+ const content = `---
211
+ id: T04
212
+ parent: S03
213
+ milestone: M002
214
+ blocker_discovered: true
215
+ completed_at: 2025-03-10T12:00:00Z
216
+ ---
217
+
218
+ # T04: Boolean True
219
+
220
+ **One-liner.**
221
+
222
+ ## What Happened
223
+
224
+ Blocker as boolean.
225
+ `;
226
+
227
+ const s = parseSummary(content);
228
+ assertEq(s.frontmatter.blocker_discovered, true, 'blocker_discovered: true (YAML boolean) extracts as true');
229
+ }
230
+
231
+ console.log('\n=== parseSummary: blocker_discovered with full frontmatter ===');
232
+ {
233
+ const content = `---
234
+ id: T05
235
+ parent: S03
236
+ milestone: M002
237
+ provides:
238
+ - something
239
+ requires: []
240
+ affects: []
241
+ key_files:
242
+ - files.ts
243
+ key_decisions: []
244
+ patterns_established: []
245
+ drill_down_paths: []
246
+ observability_surfaces: []
247
+ duration: 15min
248
+ verification_result: passed
249
+ completed_at: 2025-03-10T12:00:00Z
250
+ blocker_discovered: true
251
+ ---
252
+
253
+ # T05: Full Frontmatter With Blocker
254
+
255
+ **Found an architectural mismatch.**
256
+
257
+ ## What Happened
258
+
259
+ The API doesn't support what we assumed.
260
+
261
+ ## Deviations
262
+
263
+ Major deviation from plan.
264
+
265
+ ## Files Created/Modified
266
+
267
+ - \`files.ts\` — attempted changes
268
+ `;
269
+
270
+ const s = parseSummary(content);
271
+ assertEq(s.frontmatter.blocker_discovered, true, 'blocker_discovered true with full frontmatter');
272
+ assertEq(s.frontmatter.id, 'T05', 'other fields still parse correctly alongside blocker_discovered');
273
+ assertEq(s.frontmatter.duration, '15min', 'duration still parsed');
274
+ assertEq(s.frontmatter.provides[0], 'something', 'provides still parsed');
275
+ }
276
+
277
+ // ═══════════════════════════════════════════════════════════════════════════
278
+ // State Detection: replanning-slice phase
279
+ // ═══════════════════════════════════════════════════════════════════════════
280
+
281
+ // (a) blocker found + no REPLAN.md → replanning-slice
282
+ console.log('\n=== deriveState: blocker found, no REPLAN → replanning-slice ===');
283
+ {
284
+ const base = createFixtureBase();
285
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
286
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
287
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
288
+
289
+ const state = await deriveState(base);
290
+ assertEq(state.phase, 'replanning-slice', 'phase is replanning-slice when blocker found and no REPLAN.md');
291
+ assertTrue(state.nextAction.includes('T01'), 'nextAction mentions blocker task T01');
292
+ assertTrue(state.nextAction.includes('blocker_discovered'), 'nextAction mentions blocker_discovered');
293
+ assertEq(state.activeTask?.id, 'T02', 'activeTask is still T02 (the next incomplete task)');
294
+ assertTrue(state.blockers.length > 0, 'blockers array is non-empty');
295
+ rmSync(base, { recursive: true, force: true });
296
+ }
297
+
298
+ // (b) blocker found + REPLAN.md exists → executing (loop protection)
299
+ console.log('\n=== deriveState: blocker found + REPLAN exists → executing (loop protection) ===');
300
+ {
301
+ const base = createFixtureBase();
302
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
303
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
304
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
305
+ writeReplanFile(base, 'M001', 'S01', '# Replan\n\nAlready replanned.');
306
+
307
+ const state = await deriveState(base);
308
+ assertEq(state.phase, 'executing', 'phase is executing when REPLAN.md exists (loop protection)');
309
+ assertEq(state.activeTask?.id, 'T02', 'activeTask is T02');
310
+ rmSync(base, { recursive: true, force: true });
311
+ }
312
+
313
+ // (c) no blocker → executing
314
+ console.log('\n=== deriveState: no blocker in completed tasks → executing ===');
315
+ {
316
+ const base = createFixtureBase();
317
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
318
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
319
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', false));
320
+
321
+ const state = await deriveState(base);
322
+ assertEq(state.phase, 'executing', 'phase is executing when no blocker found');
323
+ assertEq(state.activeTask?.id, 'T02', 'activeTask is T02');
324
+ rmSync(base, { recursive: true, force: true });
325
+ }
326
+
327
+ // (d) multiple completed tasks, one with blocker → replanning-slice
328
+ console.log('\n=== deriveState: multiple completed tasks, one blocker → replanning-slice ===');
329
+ {
330
+ const base = createFixtureBase();
331
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
332
+ writePlan(base, 'M001', 'S01', makePlanT01T02DoneT03Pending());
333
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', false));
334
+ writeTaskSummary(base, 'M001', 'S01', 'T02', makeTaskSummary('T02', true));
335
+
336
+ const state = await deriveState(base);
337
+ assertEq(state.phase, 'replanning-slice', 'phase is replanning-slice when T02 has blocker');
338
+ assertTrue(state.nextAction.includes('T02'), 'nextAction mentions blocker task T02');
339
+ assertEq(state.activeTask?.id, 'T03', 'activeTask is T03 (next incomplete)');
340
+ rmSync(base, { recursive: true, force: true });
341
+ }
342
+
343
+ // (e) completed task with no summary file → executing (gracefully skipped)
344
+ console.log('\n=== deriveState: completed task with no summary file → executing ===');
345
+ {
346
+ const base = createFixtureBase();
347
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
348
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
349
+ // No summary file written for T01
350
+
351
+ const state = await deriveState(base);
352
+ assertEq(state.phase, 'executing', 'phase is executing when completed task has no summary');
353
+ rmSync(base, { recursive: true, force: true });
354
+ }
355
+
356
+ // ═══════════════════════════════════════════════════════════════════════════
357
+ // Prompt: replan-slice template loading and substitution
358
+ // ═══════════════════════════════════════════════════════════════════════════
359
+
360
+ console.log('\n=== prompt: replan-slice template loads and substitutes variables ===');
361
+ {
362
+ const prompt = loadPromptFromWorktree('replan-slice', {
363
+ milestoneId: 'M001',
364
+ sliceId: 'S01',
365
+ sliceTitle: 'Test Slice',
366
+ slicePath: '.gsd/milestones/M001/slices/S01',
367
+ planPath: '.gsd/milestones/M001/slices/S01/S01-PLAN.md',
368
+ inlinedContext: '## Inlined Context\n\nTest context here.',
369
+ });
370
+
371
+ assertTrue(prompt.includes('M001'), 'prompt contains milestoneId');
372
+ assertTrue(prompt.includes('S01'), 'prompt contains sliceId');
373
+ assertTrue(prompt.includes('Test Slice'), 'prompt contains sliceTitle');
374
+ assertTrue(prompt.includes('.gsd/milestones/M001/slices/S01/S01-PLAN.md'), 'prompt contains planPath');
375
+ assertTrue(prompt.includes('Test context here'), 'prompt contains inlined context');
376
+ }
377
+
378
+ console.log('\n=== prompt: replan-slice contains preserve-completed-tasks instruction ===');
379
+ {
380
+ const prompt = loadPromptFromWorktree('replan-slice', {
381
+ milestoneId: 'M001',
382
+ sliceId: 'S01',
383
+ sliceTitle: 'Test Slice',
384
+ slicePath: '.gsd/milestones/M001/slices/S01',
385
+ planPath: '.gsd/milestones/M001/slices/S01/S01-PLAN.md',
386
+ blockerTaskId: 'T01',
387
+ replanPath: '.gsd/milestones/M001/slices/S01/S01-REPLAN.md',
388
+ inlinedContext: '',
389
+ });
390
+
391
+ assertTrue(prompt.includes('Do NOT renumber or remove completed tasks'), 'prompt contains preserve-completed-tasks instruction');
392
+ assertTrue(prompt.includes('[x]'), 'prompt mentions [x] checkmarks');
393
+ assertTrue(prompt.includes('REPLAN'), 'prompt references replan output path');
394
+ assertTrue(prompt.includes('blocker_discovered'), 'prompt mentions blocker_discovered');
395
+ }
396
+
397
+ // ═══════════════════════════════════════════════════════════════════════════
398
+ // Dispatch: diagnoseExpectedArtifact for replan-slice
399
+ // ═══════════════════════════════════════════════════════════════════════════
400
+
401
+ console.log('\n=== dispatch: diagnoseExpectedArtifact returns REPLAN.md path ===');
402
+ {
403
+ // We can't import diagnoseExpectedArtifact directly (it's not exported),
404
+ // but we can verify the prompt template has the right structure and
405
+ // the state machine routes correctly. The diagnose function is integration-tested
406
+ // via the dispatch chain. We verify indirectly via state phase detection.
407
+
408
+ // Verify state correctly routes to replanning-slice phase
409
+ const base = createFixtureBase();
410
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
411
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
412
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
413
+
414
+ const state = await deriveState(base);
415
+ assertEq(state.phase, 'replanning-slice', 'dispatch: state routes to replanning-slice when blocker found');
416
+ assertTrue(state.activeSlice?.id === 'S01', 'dispatch: activeSlice is S01');
417
+ rmSync(base, { recursive: true, force: true });
418
+ }
419
+
420
+ // ═══════════════════════════════════════════════════════════════════════════
421
+ // Display Functions: unitVerb, unitPhaseLabel, peekNext entries
422
+ // ═══════════════════════════════════════════════════════════════════════════
423
+
424
+ console.log('\n=== display: replan-slice prompt template has correct unit header ===');
425
+ {
426
+ const prompt = loadPromptFromWorktree('replan-slice', {
427
+ milestoneId: 'M001',
428
+ sliceId: 'S01',
429
+ sliceTitle: 'Test Slice',
430
+ slicePath: '.gsd/milestones/M001/slices/S01',
431
+ planPath: '.gsd/milestones/M001/slices/S01/S01-PLAN.md',
432
+ blockerTaskId: 'T01',
433
+ inlinedContext: '',
434
+ });
435
+
436
+ assertTrue(prompt.includes('UNIT: Replan Slice'), 'prompt has Replan Slice unit header');
437
+ assertTrue(prompt.includes('Slice S01 replanned'), 'prompt has completion message');
438
+ }
439
+
440
+ // ═══════════════════════════════════════════════════════════════════════════
441
+ // Doctor: blocker_discovered_no_replan diagnostics
442
+ // ═══════════════════════════════════════════════════════════════════════════
443
+
444
+ import { runGSDDoctor } from '../doctor.ts';
445
+ import { createTestContext } from './test-helpers.ts';
446
+
447
+ // (a) blocker + no REPLAN.md → issue emitted
448
+ console.log('\n=== doctor: blocker + no REPLAN.md → blocker_discovered_no_replan issue ===');
449
+ {
450
+ const base = createFixtureBase();
451
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
452
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
453
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
454
+
455
+ const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
456
+ const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
457
+ assertTrue(blockerIssues.length > 0, 'doctor emits blocker_discovered_no_replan when blocker + no REPLAN');
458
+ assertTrue(blockerIssues[0]?.message.includes('T01'), 'issue message mentions the blocker task T01');
459
+ assertEq(blockerIssues[0]?.severity, 'warning', 'blocker_discovered_no_replan is warning severity');
460
+ assertEq(blockerIssues[0]?.scope, 'slice', 'blocker_discovered_no_replan has slice scope');
461
+ rmSync(base, { recursive: true, force: true });
462
+ }
463
+
464
+ // (b) blocker + REPLAN.md exists → no issue
465
+ console.log('\n=== doctor: blocker + REPLAN.md exists → no blocker_discovered_no_replan issue ===');
466
+ {
467
+ const base = createFixtureBase();
468
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
469
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
470
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', true));
471
+ writeReplanFile(base, 'M001', 'S01', '# Replan\n\nAlready replanned.');
472
+
473
+ const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
474
+ const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
475
+ assertEq(blockerIssues.length, 0, 'no blocker_discovered_no_replan when REPLAN.md exists');
476
+ rmSync(base, { recursive: true, force: true });
477
+ }
478
+
479
+ // (c) no blocker → no issue
480
+ console.log('\n=== doctor: no blocker → no blocker_discovered_no_replan issue ===');
481
+ {
482
+ const base = createFixtureBase();
483
+ writeRoadmap(base, 'M001', ROADMAP_ONE_SLICE);
484
+ writePlan(base, 'M001', 'S01', makePlanT01DoneT02Pending());
485
+ writeTaskSummary(base, 'M001', 'S01', 'T01', makeTaskSummary('T01', false));
486
+
487
+ const report = await runGSDDoctor(base, { fix: false, scope: 'M001/S01' });
488
+ const blockerIssues = report.issues.filter(i => i.code === 'blocker_discovered_no_replan');
489
+ assertEq(blockerIssues.length, 0, 'no blocker_discovered_no_replan when no blocker');
490
+ rmSync(base, { recursive: true, force: true });
491
+ }
492
+
493
+ report();
@@ -0,0 +1,106 @@
1
+ import { parseRequirementCounts } from "../files.ts";
2
+ import { mkdtempSync, mkdirSync, rmSync, writeFileSync } from "node:fs";
3
+ import { join } from "node:path";
4
+ import { tmpdir } from "node:os";
5
+ import { deriveState } from "../state.ts";
6
+ import { runGSDDoctor } from "../doctor.ts";
7
+ import { createTestContext } from './test-helpers.ts';
8
+
9
+ const { assertEq, assertTrue, report } = createTestContext();
10
+ console.log("\n=== requirement counts parser ===");
11
+ {
12
+ const counts = parseRequirementCounts(`# Requirements
13
+
14
+ ## Active
15
+
16
+ ### R001 — Foo
17
+ - Status: active
18
+
19
+ ### R002 — Bar
20
+ - Status: blocked
21
+
22
+ ## Validated
23
+
24
+ ### R010 — Baz
25
+ - Status: validated
26
+
27
+ ## Deferred
28
+
29
+ ### R020 — Qux
30
+ - Status: deferred
31
+
32
+ ## Out of Scope
33
+
34
+ ### R030 — No
35
+ - Status: out-of-scope
36
+ `);
37
+ assertEq(counts.active, 2, "counts active requirements by section");
38
+ assertEq(counts.validated, 1, "counts validated requirements");
39
+ assertEq(counts.deferred, 1, "counts deferred requirements");
40
+ assertEq(counts.outOfScope, 1, "counts out of scope requirements");
41
+ assertEq(counts.blocked, 1, "counts blocked statuses");
42
+ }
43
+
44
+ const base = mkdtempSync(join(tmpdir(), "gsd-requirements-test-"));
45
+ const gsd = join(base, ".gsd");
46
+ const mDir = join(gsd, "milestones", "M001");
47
+ const sDir = join(mDir, "slices", "S01");
48
+ const tDir = join(sDir, "tasks");
49
+ mkdirSync(tDir, { recursive: true });
50
+ writeFileSync(join(gsd, "REQUIREMENTS.md"), `# Requirements
51
+
52
+ ## Active
53
+
54
+ ### R001 — Missing owner
55
+ - Class: core-capability
56
+ - Status: active
57
+ - Description: thing
58
+ - Why it matters: thing
59
+ - Source: user
60
+ - Primary owning slice: none yet
61
+ - Supporting slices: none
62
+ - Validation: unmapped
63
+ - Notes: none
64
+
65
+ ## Validated
66
+
67
+ ## Deferred
68
+
69
+ ## Out of Scope
70
+
71
+ ## Traceability
72
+ `, "utf-8");
73
+ writeFileSync(join(mDir, "M001-ROADMAP.md"), `# M001: Demo
74
+
75
+ ## Slices
76
+ - [ ] **S01: Demo Slice** \`risk:low\` \`depends:[]\`
77
+ > After this: demo works
78
+ `, "utf-8");
79
+ writeFileSync(join(sDir, "S01-PLAN.md"), `# S01: Demo Slice
80
+
81
+ **Goal:** Demo
82
+ **Demo:** Demo
83
+
84
+ ## Must-Haves
85
+ - done
86
+
87
+ ## Tasks
88
+ - [ ] **T01: Implement thing** \`est:10m\`
89
+ Task is in progress.
90
+ `, "utf-8");
91
+
92
+ console.log("\n=== deriveState includes requirements counts ===");
93
+ {
94
+ const state = await deriveState(base);
95
+ assertTrue(state.requirements !== undefined, "state includes requirements summary");
96
+ assertEq(state.requirements?.active, 1, "state reports active requirement count");
97
+ }
98
+
99
+ console.log("\n=== doctor flags orphaned active requirement ===");
100
+ {
101
+ const report = await runGSDDoctor(base);
102
+ assertTrue(report.issues.some(issue => issue.code === "active_requirement_missing_owner"), "doctor flags missing owner");
103
+ }
104
+
105
+ rmSync(base, { recursive: true, force: true });
106
+ report();
@@ -0,0 +1,35 @@
1
+ // ESM resolve hook: .js → .ts rewriting for test environments.
2
+ // Only rewrites relative imports from our own source files — not from node_modules.
3
+ //
4
+ // Handles two patterns:
5
+ // 1. .js → .ts (pi bundler convention: source files use .js specifiers)
6
+ // 2. extensionless → .ts (some source files omit extensions in relative imports)
7
+
8
+ export function resolve(specifier, context, nextResolve) {
9
+ const parentURL = context.parentURL || '';
10
+ const isFromNodeModules = parentURL.includes('/node_modules/');
11
+ const isFromPackages = parentURL.includes('/packages/');
12
+
13
+ if (!isFromNodeModules && !isFromPackages && !specifier.startsWith('node:')) {
14
+ // Rewrite .js → .ts
15
+ if (specifier.endsWith('.js')) {
16
+ const tsSpecifier = specifier.replace(/\.js$/, '.ts');
17
+ try {
18
+ return nextResolve(tsSpecifier, context);
19
+ } catch {
20
+ // fall through to default resolution
21
+ }
22
+ }
23
+
24
+ // Try adding .ts to extensionless relative imports
25
+ if (specifier.startsWith('.') && !/\.[a-z]+$/i.test(specifier)) {
26
+ try {
27
+ return nextResolve(specifier + '.ts', context);
28
+ } catch {
29
+ // fall through to default resolution
30
+ }
31
+ }
32
+ }
33
+
34
+ return nextResolve(specifier, context);
35
+ }
@@ -0,0 +1,11 @@
1
+ // Custom ESM resolver: rewrites .js imports to .ts for node --test with TypeScript sources.
2
+ // Usage: node --import ./agent/extensions/gsd/tests/resolve-ts.mjs --test ...
3
+ //
4
+ // This is needed because pi extension source files use .js import specifiers
5
+ // (the pi runtime bundler convention), but only .ts files exist on disk.
6
+ // Node's built-in TypeScript support strips types but doesn't rewrite specifiers.
7
+
8
+ import { register } from 'node:module';
9
+ import { pathToFileURL } from 'node:url';
10
+
11
+ register(new URL('./resolve-ts-hooks.mjs', import.meta.url), pathToFileURL('./'));
@@ -0,0 +1,41 @@
1
+ import { parseRoadmap } from "../files.ts";
2
+ import { parseRoadmapSlices } from "../roadmap-slices.ts";
3
+ import { createTestContext } from './test-helpers.ts';
4
+
5
+ const { assertEq, assertTrue, report } = createTestContext();
6
+ const content = `# M003: Current
7
+
8
+ **Vision:** Build the thing.
9
+
10
+ ## Slices
11
+ - [x] **S01: First Slice** \`risk:low\` \`depends:[]\`
12
+ > After this: First demo works.
13
+ - [ ] **S02: Second Slice** \`risk:medium\` \`depends:[S01]\`
14
+ - [x] **S03: Third Slice** \`depends:[S01, S02]\`
15
+ > After this: Third demo works.
16
+
17
+ ## Boundary Map
18
+ ### S01 → S02
19
+ Produces:
20
+ foo.ts
21
+ `;
22
+
23
+ console.log("\n=== parseRoadmapSlices ===");
24
+ const slices = parseRoadmapSlices(content);
25
+ assertEq(slices.length, 3, "slice count");
26
+ assertEq(slices[0]?.id, "S01", "first id");
27
+ assertEq(slices[0]?.done, true, "first done");
28
+ assertEq(slices[0]?.demo, "First demo works.", "first demo");
29
+ assertEq(slices[1]?.depends, ["S01"], "second depends");
30
+ assertEq(slices[1]?.risk, "medium", "second risk");
31
+ assertEq(slices[2]?.risk, "low", "missing risk defaults to low");
32
+ assertEq(slices[2]?.depends, ["S01", "S02"], "third depends");
33
+
34
+ console.log("\n=== parseRoadmap integration ===");
35
+ const roadmap = parseRoadmap(content);
36
+ assertEq(roadmap.slices, slices, "parseRoadmap uses extracted slice parser");
37
+ assertEq(roadmap.title, "M003: Current", "roadmap title preserved");
38
+ assertEq(roadmap.vision, "Build the thing.", "roadmap vision preserved");
39
+ assertTrue(roadmap.boundaryMap.length === 1, "boundary map still parsed");
40
+
41
+ report();