gsd-pi 2.75.0-dev.063e5a3 → 2.75.0-dev.b6ad8c5f7

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 (718) hide show
  1. package/README.md +186 -149
  2. package/dist/claude-cli-check.d.ts +10 -0
  3. package/dist/claude-cli-check.js +13 -3
  4. package/dist/headless-events.d.ts +1 -1
  5. package/dist/headless-events.js +5 -2
  6. package/dist/headless.js +5 -6
  7. package/dist/loader.js +0 -0
  8. package/dist/onboarding.d.ts +20 -1
  9. package/dist/onboarding.js +99 -39
  10. package/dist/resources/extensions/ask-user-questions.js +17 -5
  11. package/dist/resources/extensions/claude-code-cli/models.js +9 -0
  12. package/dist/resources/extensions/claude-code-cli/readiness.js +12 -2
  13. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +76 -4
  14. package/dist/resources/extensions/gsd/auto/detect-stuck.js +9 -0
  15. package/dist/resources/extensions/gsd/auto/loop.js +67 -4
  16. package/dist/resources/extensions/gsd/auto/phases.js +70 -47
  17. package/dist/resources/extensions/gsd/auto/resolve.js +1 -1
  18. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -1
  19. package/dist/resources/extensions/gsd/auto/session.js +5 -0
  20. package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
  21. package/dist/resources/extensions/gsd/auto-dashboard.js +15 -7
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +112 -6
  23. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  24. package/dist/resources/extensions/gsd/auto-model-selection.js +11 -3
  25. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -8
  26. package/dist/resources/extensions/gsd/auto-prompts.js +173 -39
  27. package/dist/resources/extensions/gsd/auto-recovery.js +57 -0
  28. package/dist/resources/extensions/gsd/auto-start.js +5 -3
  29. package/dist/resources/extensions/gsd/auto-verification.js +3 -3
  30. package/dist/resources/extensions/gsd/auto-worktree.js +55 -1
  31. package/dist/resources/extensions/gsd/auto.js +57 -25
  32. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
  33. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
  34. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
  35. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
  36. package/dist/resources/extensions/gsd/commands/catalog.js +81 -9
  37. package/dist/resources/extensions/gsd/commands/handlers/core.js +64 -24
  38. package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
  39. package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +199 -0
  40. package/dist/resources/extensions/gsd/commands/handlers/ops.js +16 -0
  41. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +228 -29
  42. package/dist/resources/extensions/gsd/commands-cmux.js +5 -2
  43. package/dist/resources/extensions/gsd/commands-config.js +5 -0
  44. package/dist/resources/extensions/gsd/commands-debug.js +388 -0
  45. package/dist/resources/extensions/gsd/commands-do.js +1 -0
  46. package/dist/resources/extensions/gsd/commands-extract-learnings.js +233 -75
  47. package/dist/resources/extensions/gsd/commands-handlers.js +21 -2
  48. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +40 -12
  49. package/dist/resources/extensions/gsd/commands-scan.js +94 -0
  50. package/dist/resources/extensions/gsd/commands-workflow-templates.js +101 -2
  51. package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
  52. package/dist/resources/extensions/gsd/db-writer.js +1 -0
  53. package/dist/resources/extensions/gsd/debug-session-store.js +238 -0
  54. package/dist/resources/extensions/gsd/definition-loader.js +7 -0
  55. package/dist/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  56. package/dist/resources/extensions/gsd/doctor-environment.js +2 -1
  57. package/dist/resources/extensions/gsd/doctor-git-checks.js +5 -1
  58. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
  59. package/dist/resources/extensions/gsd/doctor-providers.js +48 -20
  60. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -4
  61. package/dist/resources/extensions/gsd/doctor.js +7 -1
  62. package/dist/resources/extensions/gsd/error-classifier.js +6 -3
  63. package/dist/resources/extensions/gsd/escalation.js +321 -0
  64. package/dist/resources/extensions/gsd/forensics.js +26 -29
  65. package/dist/resources/extensions/gsd/git-service.js +0 -1
  66. package/dist/resources/extensions/gsd/graph.js +26 -2
  67. package/dist/resources/extensions/gsd/gsd-db.js +254 -29
  68. package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
  69. package/dist/resources/extensions/gsd/health-widget.js +7 -4
  70. package/dist/resources/extensions/gsd/init-wizard.js +86 -45
  71. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -5
  72. package/dist/resources/extensions/gsd/metrics.js +1 -0
  73. package/dist/resources/extensions/gsd/model-cost-table.js +3 -1
  74. package/dist/resources/extensions/gsd/model-router.js +16 -6
  75. package/dist/resources/extensions/gsd/native-git-bridge.js +137 -5
  76. package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
  77. package/dist/resources/extensions/gsd/notification-widget.js +24 -39
  78. package/dist/resources/extensions/gsd/notifications.js +4 -0
  79. package/dist/resources/extensions/gsd/onboarding-state.js +133 -0
  80. package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
  81. package/dist/resources/extensions/gsd/pre-execution-checks.js +97 -4
  82. package/dist/resources/extensions/gsd/preferences-models.js +1 -0
  83. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  84. package/dist/resources/extensions/gsd/preferences-validation.js +42 -8
  85. package/dist/resources/extensions/gsd/preferences.js +10 -10
  86. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  87. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  88. package/dist/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  89. package/dist/resources/extensions/gsd/prompts/execute-task.md +12 -0
  90. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  91. package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  92. package/dist/resources/extensions/gsd/prompts/scan.md +79 -0
  93. package/dist/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  94. package/dist/resources/extensions/gsd/python-resolver.js +70 -0
  95. package/dist/resources/extensions/gsd/run-manager.js +37 -17
  96. package/dist/resources/extensions/gsd/setup-catalog.js +75 -0
  97. package/dist/resources/extensions/gsd/state.js +47 -3
  98. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  99. package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
  100. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
  101. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
  102. package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
  103. package/dist/resources/extensions/gsd/uok/flags.js +7 -7
  104. package/dist/resources/extensions/gsd/uok/kernel.js +8 -3
  105. package/dist/resources/extensions/gsd/verification-gate.js +2 -1
  106. package/dist/resources/extensions/gsd/workflow-dispatch.js +64 -0
  107. package/dist/resources/extensions/gsd/workflow-install.js +327 -0
  108. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -0
  109. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -6
  110. package/dist/resources/extensions/gsd/workflow-plugins.js +346 -0
  111. package/dist/resources/extensions/gsd/workflow-projections.js +17 -15
  112. package/dist/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  113. package/dist/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  114. package/dist/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  115. package/dist/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  116. package/dist/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  117. package/dist/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  118. package/dist/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  119. package/dist/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  120. package/dist/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  121. package/dist/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  122. package/dist/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  123. package/dist/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  124. package/dist/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  125. package/dist/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  126. package/dist/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  127. package/dist/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  128. package/dist/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  129. package/dist/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  130. package/dist/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  131. package/dist/resources/extensions/gsd/workflow-templates/release.md +118 -0
  132. package/dist/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  133. package/dist/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  134. package/dist/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  135. package/dist/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  136. package/dist/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  137. package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
  138. package/dist/resources/extensions/remote-questions/commands.js +380 -0
  139. package/dist/resources/extensions/remote-questions/manager.js +39 -5
  140. package/dist/resources/extensions/remote-questions/telegram-adapter.js +79 -4
  141. package/dist/resources/extensions/shared/interview-ui.js +189 -1
  142. package/dist/resources/extensions/shared/layout-utils.js +17 -0
  143. package/dist/resources/extensions/shared/rtk-shared.js +47 -0
  144. package/dist/resources/extensions/shared/rtk.js +3 -46
  145. package/dist/resources/skills/create-workflow/SKILL.md +33 -6
  146. package/dist/rtk-shared.d.ts +10 -0
  147. package/dist/rtk-shared.js +47 -0
  148. package/dist/rtk.d.ts +2 -6
  149. package/dist/rtk.js +3 -48
  150. package/dist/shared/workspace-types.d.ts +52 -0
  151. package/dist/shared/workspace-types.js +1 -0
  152. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  153. package/dist/update-check.d.ts +10 -0
  154. package/dist/update-check.js +24 -3
  155. package/dist/web/standalone/.next/BUILD_ID +1 -1
  156. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  157. package/dist/web/standalone/.next/build-manifest.json +3 -3
  158. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  159. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  160. package/dist/web/standalone/.next/required-server-files.json +1 -1
  161. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  162. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  163. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  164. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  165. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  166. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  167. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  168. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  169. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  170. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  172. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  173. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  174. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  175. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  176. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  177. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  178. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  179. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  186. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  201. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  203. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  204. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  205. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  206. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  207. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  208. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  209. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  210. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  211. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  212. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  213. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  214. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  215. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  216. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  217. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  218. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  219. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  220. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  221. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  222. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  223. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  224. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  225. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  226. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  227. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  228. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  229. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  230. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  231. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  232. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  233. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  234. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  235. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  236. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  237. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  238. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  239. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  240. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  241. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  242. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  243. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  244. package/dist/web/standalone/.next/server/app/index.html +1 -1
  245. package/dist/web/standalone/.next/server/app/index.rsc +3 -3
  246. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  247. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  248. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  249. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  250. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  251. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  252. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  253. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  254. package/dist/web/standalone/.next/server/chunks/7461.js +1 -0
  255. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  256. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  257. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  258. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  259. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  260. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  261. package/dist/web/standalone/.next/static/chunks/2826.e59e8578e2e28639.js +9 -0
  262. package/dist/web/standalone/.next/static/chunks/{2008.71ee9230ad78df21.js → 3621.fc7480022c972438.js} +2 -2
  263. package/dist/web/standalone/.next/static/chunks/app/{page-f1e30ab6bb269149.js → page-5b113fd32bc2a1c3.js} +1 -1
  264. package/dist/web/standalone/.next/static/chunks/{webpack-b868033a5834586d.js → webpack-5fc74f13a25fa1bb.js} +1 -1
  265. package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
  266. package/dist/web/standalone/server.js +1 -1
  267. package/dist/welcome-screen.js +48 -24
  268. package/dist/wizard.js +2 -2
  269. package/dist/worktree-cli.d.ts +6 -5
  270. package/dist/worktree-cli.js +23 -7
  271. package/package.json +3 -3
  272. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  273. package/packages/native/tsconfig.tsbuildinfo +1 -1
  274. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  275. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  276. package/packages/pi-ai/dist/models/capability-patches.js +3 -2
  277. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  278. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts +68 -0
  279. package/packages/pi-ai/dist/models/generated/amazon-bedrock.d.ts.map +1 -1
  280. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js +68 -0
  281. package/packages/pi-ai/dist/models/generated/amazon-bedrock.js.map +1 -1
  282. package/packages/pi-ai/dist/models/generated/anthropic.d.ts +17 -0
  283. package/packages/pi-ai/dist/models/generated/anthropic.d.ts.map +1 -1
  284. package/packages/pi-ai/dist/models/generated/anthropic.js +17 -0
  285. package/packages/pi-ai/dist/models/generated/anthropic.js.map +1 -1
  286. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts +17 -0
  287. package/packages/pi-ai/dist/models/generated/google-antigravity.d.ts.map +1 -1
  288. package/packages/pi-ai/dist/models/generated/google-antigravity.js +17 -0
  289. package/packages/pi-ai/dist/models/generated/google-antigravity.js.map +1 -1
  290. package/packages/pi-ai/dist/models/generated/groq.d.ts +0 -153
  291. package/packages/pi-ai/dist/models/generated/groq.d.ts.map +1 -1
  292. package/packages/pi-ai/dist/models/generated/groq.js +0 -153
  293. package/packages/pi-ai/dist/models/generated/groq.js.map +1 -1
  294. package/packages/pi-ai/dist/models/generated/index.d.ts +136 -153
  295. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  296. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  297. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  298. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  299. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  300. package/packages/pi-ai/dist/models/generated/openrouter.d.ts +17 -0
  301. package/packages/pi-ai/dist/models/generated/openrouter.d.ts.map +1 -1
  302. package/packages/pi-ai/dist/models/generated/openrouter.js +17 -0
  303. package/packages/pi-ai/dist/models/generated/openrouter.js.map +1 -1
  304. package/packages/pi-ai/dist/models.generated.test.js +17 -0
  305. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  306. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
  307. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  308. package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -6
  309. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  310. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
  311. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
  312. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
  313. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
  314. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
  315. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  316. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +20 -1
  317. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/providers/anthropic-shared.js +32 -2
  319. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  320. package/packages/pi-ai/dist/providers/anthropic-shared.test.js +12 -1
  321. package/packages/pi-ai/dist/providers/anthropic-shared.test.js.map +1 -1
  322. package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
  323. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  324. package/packages/pi-ai/dist/providers/anthropic.js +18 -1
  325. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  326. package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  327. package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
  328. package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  329. package/packages/pi-ai/package.json +1 -1
  330. package/packages/pi-ai/scripts/generate-models.ts +50 -0
  331. package/packages/pi-ai/src/models/capability-patches.ts +5 -2
  332. package/packages/pi-ai/src/models/generated/amazon-bedrock.ts +68 -0
  333. package/packages/pi-ai/src/models/generated/anthropic.ts +17 -0
  334. package/packages/pi-ai/src/models/generated/google-antigravity.ts +17 -0
  335. package/packages/pi-ai/src/models/generated/groq.ts +0 -153
  336. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  337. package/packages/pi-ai/src/models/generated/openrouter.ts +17 -0
  338. package/packages/pi-ai/src/models.generated.test.ts +17 -0
  339. package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
  340. package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -7
  341. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
  342. package/packages/pi-ai/src/providers/anthropic-shared.test.ts +15 -1
  343. package/packages/pi-ai/src/providers/anthropic-shared.ts +36 -3
  344. package/packages/pi-ai/src/providers/anthropic.ts +19 -1
  345. package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
  346. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  347. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts +2 -0
  348. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.d.ts.map +1 -0
  349. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +38 -0
  350. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -0
  351. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +14 -0
  352. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  353. package/packages/pi-coding-agent/dist/core/auth-storage.js +34 -0
  354. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  355. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +74 -0
  356. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +4 -1
  358. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  359. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
  360. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  361. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/sdk.js +32 -0
  363. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +2 -2
  365. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  366. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  367. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +17 -7
  368. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  369. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  370. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
  371. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  372. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
  373. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +83 -33
  375. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  376. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  377. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  378. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +77 -0
  379. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  380. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -66
  381. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  382. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +1 -75
  383. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  384. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts +1 -1
  385. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  386. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +192 -24
  387. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  388. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +56 -0
  389. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +83 -0
  390. package/packages/pi-coding-agent/src/core/auth-storage.ts +35 -0
  391. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +4 -1
  392. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
  393. package/packages/pi-coding-agent/src/core/sdk.ts +41 -0
  394. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +2 -2
  395. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +19 -7
  396. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
  397. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +88 -36
  398. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +83 -0
  399. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +2 -83
  400. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +208 -27
  401. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  402. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  403. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  404. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +70 -0
  405. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -0
  406. package/pkg/dist/modes/interactive/theme/theme-schema.js +77 -0
  407. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -0
  408. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -66
  409. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  410. package/pkg/dist/modes/interactive/theme/theme.js +1 -75
  411. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  412. package/pkg/dist/modes/interactive/theme/themes.d.ts +1 -1
  413. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  414. package/pkg/dist/modes/interactive/theme/themes.js +192 -24
  415. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  416. package/src/resources/extensions/ask-user-questions.ts +24 -6
  417. package/src/resources/extensions/claude-code-cli/models.ts +9 -0
  418. package/src/resources/extensions/claude-code-cli/readiness.ts +13 -2
  419. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +94 -4
  420. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +84 -0
  421. package/src/resources/extensions/gsd/auto/detect-stuck.ts +10 -0
  422. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  423. package/src/resources/extensions/gsd/auto/loop.ts +109 -3
  424. package/src/resources/extensions/gsd/auto/phases.ts +94 -60
  425. package/src/resources/extensions/gsd/auto/resolve.ts +1 -1
  426. package/src/resources/extensions/gsd/auto/run-unit.ts +11 -1
  427. package/src/resources/extensions/gsd/auto/session.ts +7 -0
  428. package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
  429. package/src/resources/extensions/gsd/auto-dashboard.ts +21 -4
  430. package/src/resources/extensions/gsd/auto-dispatch.ts +123 -5
  431. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  432. package/src/resources/extensions/gsd/auto-model-selection.ts +14 -3
  433. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -8
  434. package/src/resources/extensions/gsd/auto-prompts.ts +201 -40
  435. package/src/resources/extensions/gsd/auto-recovery.ts +63 -1
  436. package/src/resources/extensions/gsd/auto-start.ts +8 -6
  437. package/src/resources/extensions/gsd/auto-verification.ts +3 -3
  438. package/src/resources/extensions/gsd/auto-worktree.ts +65 -0
  439. package/src/resources/extensions/gsd/auto.ts +61 -28
  440. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
  441. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
  442. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
  443. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  444. package/src/resources/extensions/gsd/commands/catalog.ts +74 -9
  445. package/src/resources/extensions/gsd/commands/handlers/core.ts +69 -27
  446. package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
  447. package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +262 -0
  448. package/src/resources/extensions/gsd/commands/handlers/ops.ts +16 -0
  449. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +279 -29
  450. package/src/resources/extensions/gsd/commands-cmux.ts +6 -2
  451. package/src/resources/extensions/gsd/commands-config.ts +10 -0
  452. package/src/resources/extensions/gsd/commands-debug.ts +484 -0
  453. package/src/resources/extensions/gsd/commands-do.ts +1 -0
  454. package/src/resources/extensions/gsd/commands-extract-learnings.ts +295 -76
  455. package/src/resources/extensions/gsd/commands-handlers.ts +19 -2
  456. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +49 -12
  457. package/src/resources/extensions/gsd/commands-scan.ts +125 -0
  458. package/src/resources/extensions/gsd/commands-workflow-templates.ts +129 -2
  459. package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
  460. package/src/resources/extensions/gsd/db-writer.ts +3 -0
  461. package/src/resources/extensions/gsd/debug-session-store.ts +377 -0
  462. package/src/resources/extensions/gsd/definition-loader.ts +7 -0
  463. package/src/resources/extensions/gsd/docs/preferences-reference.md +9 -9
  464. package/src/resources/extensions/gsd/doctor-environment.ts +2 -1
  465. package/src/resources/extensions/gsd/doctor-git-checks.ts +5 -1
  466. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
  467. package/src/resources/extensions/gsd/doctor-providers.ts +52 -22
  468. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +23 -4
  469. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  470. package/src/resources/extensions/gsd/doctor.ts +7 -1
  471. package/src/resources/extensions/gsd/error-classifier.ts +6 -3
  472. package/src/resources/extensions/gsd/escalation.ts +367 -0
  473. package/src/resources/extensions/gsd/forensics.ts +25 -29
  474. package/src/resources/extensions/gsd/git-service.ts +0 -1
  475. package/src/resources/extensions/gsd/graph.ts +33 -3
  476. package/src/resources/extensions/gsd/gsd-db.ts +306 -29
  477. package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
  478. package/src/resources/extensions/gsd/health-widget.ts +7 -3
  479. package/src/resources/extensions/gsd/init-wizard.ts +87 -54
  480. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -5
  481. package/src/resources/extensions/gsd/metrics.ts +1 -0
  482. package/src/resources/extensions/gsd/model-cost-table.ts +3 -1
  483. package/src/resources/extensions/gsd/model-router.ts +25 -6
  484. package/src/resources/extensions/gsd/native-git-bridge.ts +134 -6
  485. package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
  486. package/src/resources/extensions/gsd/notification-widget.ts +25 -43
  487. package/src/resources/extensions/gsd/notifications.ts +6 -0
  488. package/src/resources/extensions/gsd/onboarding-state.ts +146 -0
  489. package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
  490. package/src/resources/extensions/gsd/pre-execution-checks.ts +98 -8
  491. package/src/resources/extensions/gsd/preferences-models.ts +1 -0
  492. package/src/resources/extensions/gsd/preferences-types.ts +10 -2
  493. package/src/resources/extensions/gsd/preferences-validation.ts +33 -7
  494. package/src/resources/extensions/gsd/preferences.ts +10 -10
  495. package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  496. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +25 -0
  497. package/src/resources/extensions/gsd/prompts/debug-session-manager.md +80 -0
  498. package/src/resources/extensions/gsd/prompts/execute-task.md +12 -0
  499. package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  500. package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  501. package/src/resources/extensions/gsd/prompts/scan.md +79 -0
  502. package/src/resources/extensions/gsd/prompts/workflow-oneshot.md +26 -0
  503. package/src/resources/extensions/gsd/python-resolver.ts +76 -0
  504. package/src/resources/extensions/gsd/run-manager.ts +53 -19
  505. package/src/resources/extensions/gsd/setup-catalog.ts +105 -0
  506. package/src/resources/extensions/gsd/state.ts +50 -2
  507. package/src/resources/extensions/gsd/templates/PREFERENCES.md +7 -7
  508. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +1 -34
  509. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
  510. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +45 -31
  511. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +63 -0
  512. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +12 -0
  513. package/src/resources/extensions/gsd/tests/auto-prompts-fallback.test.ts +35 -0
  514. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
  515. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
  516. package/src/resources/extensions/gsd/tests/autocomplete-regressions-1675.test.ts +39 -0
  517. package/src/resources/extensions/gsd/tests/commands-do.test.ts +48 -0
  518. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +333 -21
  519. package/src/resources/extensions/gsd/tests/commands-scan.test.ts +351 -0
  520. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +8 -6
  521. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +6 -8
  522. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  523. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
  524. package/src/resources/extensions/gsd/tests/debug-command-handler.test.ts +905 -0
  525. package/src/resources/extensions/gsd/tests/debug-command-lifecycle.integration.test.ts +1229 -0
  526. package/src/resources/extensions/gsd/tests/debug-session-store.test.ts +565 -0
  527. package/src/resources/extensions/gsd/tests/discuss-milestone-structured-questions.test.ts +64 -0
  528. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +67 -0
  529. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +62 -18
  530. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
  531. package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
  532. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +29 -12
  533. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +106 -0
  534. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +74 -0
  535. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +0 -4
  536. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
  537. package/src/resources/extensions/gsd/tests/health-widget.test.ts +8 -2
  538. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +190 -0
  539. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +39 -0
  540. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
  541. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +68 -1
  542. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +109 -11
  543. package/src/resources/extensions/gsd/tests/integration/idle-recovery.test.ts +51 -0
  544. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +2 -2
  545. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  546. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +171 -1
  547. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  548. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  549. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
  550. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
  551. package/src/resources/extensions/gsd/tests/model-router.test.ts +51 -1
  552. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
  553. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
  554. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
  555. package/src/resources/extensions/gsd/tests/onboarding-handler-loader.test.ts +41 -0
  556. package/src/resources/extensions/gsd/tests/onboarding-state.test.ts +105 -0
  557. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +114 -0
  558. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +4 -5
  559. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
  560. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
  561. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +275 -6
  562. package/src/resources/extensions/gsd/tests/preferences.test.ts +69 -1
  563. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
  564. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +11 -2
  565. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
  566. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +27 -0
  567. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
  568. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +1 -1
  569. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +33 -0
  570. package/src/resources/extensions/gsd/tests/python-resolver.test.ts +131 -0
  571. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +67 -0
  572. package/src/resources/extensions/gsd/tests/remote-notification-from-desktop.test.ts +107 -0
  573. package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
  574. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
  575. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
  576. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
  577. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
  578. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +15 -0
  579. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
  580. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +2 -1
  581. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +31 -1
  582. package/src/resources/extensions/gsd/tests/uok-kernel-path.test.ts +166 -0
  583. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +35 -0
  584. package/src/resources/extensions/gsd/tests/workflow-install.test.ts +113 -0
  585. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +15 -6
  586. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  587. package/src/resources/extensions/gsd/tests/workflow-plugins.test.ts +310 -0
  588. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
  589. package/src/resources/extensions/gsd/tests/workflow-templates.test.ts +8 -2
  590. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
  591. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
  592. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  593. package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
  594. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
  595. package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
  596. package/src/resources/extensions/gsd/types.ts +62 -0
  597. package/src/resources/extensions/gsd/unit-runtime.ts +1 -0
  598. package/src/resources/extensions/gsd/uok/contracts.ts +2 -1
  599. package/src/resources/extensions/gsd/uok/flags.ts +7 -7
  600. package/src/resources/extensions/gsd/uok/kernel.ts +16 -4
  601. package/src/resources/extensions/gsd/verification-gate.ts +2 -1
  602. package/src/resources/extensions/gsd/workflow-dispatch.ts +106 -0
  603. package/src/resources/extensions/gsd/workflow-install.ts +423 -0
  604. package/src/resources/extensions/gsd/workflow-manifest.ts +8 -0
  605. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -6
  606. package/src/resources/extensions/gsd/workflow-plugins.ts +403 -0
  607. package/src/resources/extensions/gsd/workflow-projections.ts +18 -16
  608. package/src/resources/extensions/gsd/workflow-templates/accessibility-audit.md +88 -0
  609. package/src/resources/extensions/gsd/workflow-templates/api-breaking-change.md +117 -0
  610. package/src/resources/extensions/gsd/workflow-templates/bugfix.md +1 -0
  611. package/src/resources/extensions/gsd/workflow-templates/changelog-gen.md +82 -0
  612. package/src/resources/extensions/gsd/workflow-templates/ci-bootstrap.md +144 -0
  613. package/src/resources/extensions/gsd/workflow-templates/dead-code.md +81 -0
  614. package/src/resources/extensions/gsd/workflow-templates/dep-upgrade.md +1 -0
  615. package/src/resources/extensions/gsd/workflow-templates/docs-sync.yaml +76 -0
  616. package/src/resources/extensions/gsd/workflow-templates/env-audit.yaml +88 -0
  617. package/src/resources/extensions/gsd/workflow-templates/full-project.md +1 -0
  618. package/src/resources/extensions/gsd/workflow-templates/hotfix.md +1 -0
  619. package/src/resources/extensions/gsd/workflow-templates/issue-triage.md +84 -0
  620. package/src/resources/extensions/gsd/workflow-templates/observability-setup.md +133 -0
  621. package/src/resources/extensions/gsd/workflow-templates/onboarding-check.md +74 -0
  622. package/src/resources/extensions/gsd/workflow-templates/performance-audit.md +125 -0
  623. package/src/resources/extensions/gsd/workflow-templates/pr-review.md +67 -0
  624. package/src/resources/extensions/gsd/workflow-templates/pr-triage.md +83 -0
  625. package/src/resources/extensions/gsd/workflow-templates/refactor.md +1 -0
  626. package/src/resources/extensions/gsd/workflow-templates/registry.json +184 -0
  627. package/src/resources/extensions/gsd/workflow-templates/release.md +118 -0
  628. package/src/resources/extensions/gsd/workflow-templates/rename-symbol.yaml +99 -0
  629. package/src/resources/extensions/gsd/workflow-templates/security-audit.md +1 -0
  630. package/src/resources/extensions/gsd/workflow-templates/small-feature.md +1 -0
  631. package/src/resources/extensions/gsd/workflow-templates/spike.md +1 -0
  632. package/src/resources/extensions/gsd/workflow-templates/test-backfill.yaml +73 -0
  633. package/src/resources/extensions/gsd/workflow-templates.ts +7 -0
  634. package/src/resources/extensions/gsd/workspace-index.ts +9 -4
  635. package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
  636. package/src/resources/extensions/remote-questions/commands.ts +480 -0
  637. package/src/resources/extensions/remote-questions/manager.ts +49 -4
  638. package/src/resources/extensions/remote-questions/telegram-adapter.ts +86 -4
  639. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +246 -0
  640. package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
  641. package/src/resources/extensions/remote-questions/tests/telegram-commands.test.ts +267 -0
  642. package/src/resources/extensions/shared/interview-ui.ts +195 -1
  643. package/src/resources/extensions/shared/layout-utils.ts +26 -0
  644. package/src/resources/extensions/shared/rtk-shared.ts +58 -0
  645. package/src/resources/extensions/shared/rtk.ts +12 -52
  646. package/src/resources/extensions/shared/tests/interview-preview.test.ts +177 -0
  647. package/src/resources/extensions/shared/tests/preview-layout.test.ts +120 -0
  648. package/src/resources/skills/create-workflow/SKILL.md +33 -6
  649. package/dist/web/standalone/.next/static/chunks/2826.dd3dc8bbd3025fa5.js +0 -9
  650. package/dist/web/standalone/.next/static/css/f6e8833d46e738d8.css +0 -1
  651. package/packages/native/dist/ps/types.d.ts +0 -5
  652. package/packages/native/dist/ps/types.js +0 -2
  653. package/packages/native/src/ps/types.ts +0 -5
  654. package/packages/pi-ai/node_modules/@smithy/node-http-handler/LICENSE +0 -201
  655. package/packages/pi-ai/node_modules/@smithy/node-http-handler/README.md +0 -9
  656. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-cjs/index.js +0 -762
  657. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/build-abort-error.js +0 -19
  658. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/constants.js +0 -1
  659. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/get-transformed-headers.js +0 -9
  660. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/index.js +0 -3
  661. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http-handler.js +0 -230
  662. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-manager.js +0 -87
  663. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-connection-pool.js +0 -32
  664. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/node-http2-handler.js +0 -169
  665. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/readable.mock.js +0 -21
  666. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/server.mock.js +0 -88
  667. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-connection-timeout.js +0 -36
  668. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-request-timeout.js +0 -21
  669. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-keep-alive.js +0 -22
  670. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/set-socket-timeout.js +0 -23
  671. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/collector.js +0 -8
  672. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/index.js +0 -41
  673. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/stream-collector/readable.mock.js +0 -21
  674. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/timing.js +0 -4
  675. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-es/write-request-body.js +0 -63
  676. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/build-abort-error.d.ts +0 -10
  677. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/constants.d.ts +0 -5
  678. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/get-transformed-headers.d.ts +0 -4
  679. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/index.d.ts +0 -3
  680. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http-handler.d.ts +0 -46
  681. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-manager.d.ts +0 -24
  682. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-connection-pool.d.ts +0 -12
  683. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/node-http2-handler.d.ts +0 -63
  684. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/readable.mock.d.ts +0 -13
  685. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/server.mock.d.ts +0 -12
  686. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-connection-timeout.d.ts +0 -2
  687. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-request-timeout.d.ts +0 -6
  688. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-keep-alive.d.ts +0 -6
  689. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/set-socket-timeout.d.ts +0 -2
  690. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/collector.d.ts +0 -5
  691. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/index.d.ts +0 -6
  692. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/stream-collector/readable.mock.d.ts +0 -13
  693. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/timing.d.ts +0 -8
  694. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/build-abort-error.d.ts +0 -10
  695. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/constants.d.ts +0 -5
  696. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/get-transformed-headers.d.ts +0 -4
  697. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/index.d.ts +0 -3
  698. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http-handler.d.ts +0 -46
  699. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-manager.d.ts +0 -24
  700. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-connection-pool.d.ts +0 -12
  701. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/node-http2-handler.d.ts +0 -63
  702. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/readable.mock.d.ts +0 -13
  703. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/server.mock.d.ts +0 -12
  704. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-connection-timeout.d.ts +0 -2
  705. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-request-timeout.d.ts +0 -6
  706. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-keep-alive.d.ts +0 -6
  707. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/set-socket-timeout.d.ts +0 -2
  708. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/collector.d.ts +0 -5
  709. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/index.d.ts +0 -6
  710. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/stream-collector/readable.mock.d.ts +0 -13
  711. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/timing.d.ts +0 -8
  712. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/ts3.4/write-request-body.d.ts +0 -12
  713. package/packages/pi-ai/node_modules/@smithy/node-http-handler/dist-types/write-request-body.d.ts +0 -12
  714. package/packages/pi-ai/node_modules/@smithy/node-http-handler/package.json +0 -68
  715. package/packages/pi-ai/oauth.d.ts +0 -1
  716. package/packages/pi-ai/oauth.js +0 -1
  717. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → J2z3GMC9QtSLr7gyoM38c}/_buildManifest.js +0 -0
  718. /package/dist/web/standalone/.next/static/{j7IBD35UgrL2b298GLK3V → J2z3GMC9QtSLr7gyoM38c}/_ssgManifest.js +0 -0
@@ -15,6 +15,9 @@ const autoSrc = readFileSync(autoPath, "utf-8");
15
15
  const runUnitPath = join(import.meta.dirname, "..", "auto", "run-unit.ts");
16
16
  const runUnitSrc = readFileSync(runUnitPath, "utf-8");
17
17
 
18
+ const registerHooksPath = join(import.meta.dirname, "..", "bootstrap", "register-hooks.ts");
19
+ const registerHooksSrc = readFileSync(registerHooksPath, "utf-8");
20
+
18
21
  describe("#3512: gsd-auto-wrapup must not interrupt in-flight tool calls", () => {
19
22
  test("soft timeout wrapup gates triggerTurn on getInFlightToolCount() === 0", () => {
20
23
  // The soft timeout sendMessage must NOT use a hardcoded `triggerTurn: true`.
@@ -70,6 +73,42 @@ describe("#3512: gsd-auto-wrapup must not interrupt in-flight tool calls", () =>
70
73
  });
71
74
  });
72
75
 
76
+ describe("#4276: pending/skipped tools stay visible to auto-mode hooks", () => {
77
+ test("tool_call handler marks GSD tools in-flight before execution_start", () => {
78
+ const startMarker = 'pi.on("tool_call", async (event, ctx) => {';
79
+ const endMarker = 'pi.on("tool_result", async (event) => {';
80
+ const toolCallSection = registerHooksSrc.slice(
81
+ registerHooksSrc.indexOf(startMarker),
82
+ registerHooksSrc.indexOf(endMarker),
83
+ );
84
+
85
+ assert.ok(toolCallSection.length > 0, "Could not locate tool_call handler section");
86
+ assert.ok(
87
+ toolCallSection.includes("markToolStart(event.toolCallId, event.toolName)"),
88
+ "tool_call handler must mark tools pending before tool_execution_start fires",
89
+ );
90
+ });
91
+
92
+ test("tool_result handler clears pending tools and records queued-skip errors", () => {
93
+ const startMarker = 'pi.on("tool_result", async (event) => {';
94
+ const endMarker = 'pi.on("tool_execution_start", async (event) => {';
95
+ const toolResultSection = registerHooksSrc.slice(
96
+ registerHooksSrc.indexOf(startMarker),
97
+ registerHooksSrc.indexOf(endMarker),
98
+ );
99
+
100
+ assert.ok(toolResultSection.length > 0, "Could not locate tool_result handler section");
101
+ assert.ok(
102
+ toolResultSection.includes("markToolEnd(event.toolCallId)"),
103
+ "tool_result handler must clear pending tool tracking even when execution hooks never fire",
104
+ );
105
+ assert.ok(
106
+ toolResultSection.includes("recordToolInvocationError(event.toolName, errorText)"),
107
+ "tool_result handler must surface queued-skip errors for GSD tools",
108
+ );
109
+ });
110
+ });
111
+
73
112
  describe("#3512: pauseAuto and stopAuto must flush queued follow-up messages", () => {
74
113
  test("stopAuto calls clearQueue()", () => {
75
114
  // stopAuto must flush queued messages to prevent late async_job_result
@@ -44,6 +44,14 @@ test("/gsd description includes discuss", () => {
44
44
  );
45
45
  });
46
46
 
47
+ test("/gsd description includes debug", () => {
48
+ const pi = createMockPi();
49
+ registerGSDCommand(pi as any);
50
+
51
+ const gsd = pi.commands.get("gsd");
52
+ assert.ok(gsd.description.includes("debug"), "description should include debug");
53
+ });
54
+
47
55
  test("/gsd next completions include --debug", () => {
48
56
  const pi = createMockPi();
49
57
  registerGSDCommand(pi as any);
@@ -54,6 +62,18 @@ test("/gsd next completions include --debug", () => {
54
62
  assert.ok(debug, "next --debug should appear in completions");
55
63
  });
56
64
 
65
+ test("/gsd debug completions include list|status|continue|--diagnose", () => {
66
+ const pi = createMockPi();
67
+ registerGSDCommand(pi as any);
68
+
69
+ const gsd = pi.commands.get("gsd");
70
+ const completions = gsd.getArgumentCompletions("debug ");
71
+ const values = completions.map((c: any) => c.value);
72
+ for (const expected of ["debug list", "debug status", "debug continue", "debug --diagnose"]) {
73
+ assert.ok(values.includes(expected), `missing completion: ${expected}`);
74
+ }
75
+ });
76
+
57
77
  test("/gsd widget completions include full|small|min|off", () => {
58
78
  const pi = createMockPi();
59
79
  registerGSDCommand(pi as any);
@@ -66,6 +86,25 @@ test("/gsd widget completions include full|small|min|off", () => {
66
86
  }
67
87
  });
68
88
 
89
+ test("/gsd logs completions still include debug after adding /gsd debug", () => {
90
+ const pi = createMockPi();
91
+ registerGSDCommand(pi as any);
92
+
93
+ const gsd = pi.commands.get("gsd");
94
+ const completions = gsd.getArgumentCompletions("logs ");
95
+ const values = completions.map((c: any) => c.value);
96
+ assert.ok(values.includes("logs debug"), "logs debug completion should remain available");
97
+ });
98
+
99
+ test("/gsd help full includes /gsd debug command", async () => {
100
+ const ctx = createMockCtx();
101
+
102
+ await handleGSDCommand("help full", ctx as any, {} as any);
103
+
104
+ const helpText = ctx.notifications.map((n) => n.message).join("\n");
105
+ assert.match(helpText, /\/gsd debug\s+Create\/list\/continue persistent debug sessions/);
106
+ });
107
+
69
108
  test("bare /gsd skip shows usage and does not fall through to unknown-command warning", async () => {
70
109
  const ctx = createMockCtx();
71
110
 
@@ -40,6 +40,8 @@ const ROUTES: Route[] = [
40
40
  { keywords: ["backlog", "parking lot", "later", "someday"], command: "backlog" },
41
41
  { keywords: ["add tests", "write tests", "generate tests", "test coverage"], command: "add-tests" },
42
42
  { keywords: ["next", "step", "next step", "what's next"], command: "next" },
43
+ { keywords: ["logs", "debug logs", "log files"], command: "logs" },
44
+ { keywords: ["debug", "debug session", "investigate", "troubleshoot", "diagnose issue"], command: "debug" },
43
45
  ];
44
46
 
45
47
  interface MatchResult {
@@ -120,8 +122,54 @@ test("/gsd do: prefers longer keyword match", () => {
120
122
  assert.ok(match.score >= 12);
121
123
  });
122
124
 
125
+ test("/gsd do: routes debug troubleshooting intent to debug", () => {
126
+ const match = matchRoute("debug this flaky oauth callback");
127
+ assert.ok(match);
128
+ assert.equal(match.command, "debug");
129
+ });
130
+
131
+ test("/gsd do: keeps 'debug logs' routed to logs (longer keyword wins)", () => {
132
+ const match = matchRoute("show me debug logs for today");
133
+ assert.ok(match);
134
+ assert.equal(match.command, "logs");
135
+ });
136
+
123
137
  test("/gsd do: routes 'session report' to session-report", () => {
124
138
  const match = matchRoute("show me the session report");
125
139
  assert.ok(match);
126
140
  assert.equal(match.command, "session-report");
127
141
  });
142
+
143
+ test("/gsd do: routes 'diagnose issue' to debug (not doctor)", () => {
144
+ // 'diagnose issue' is an explicit keyword on the debug route to distinguish
145
+ // session-level issue diagnosis from /gsd doctor health checks.
146
+ const match = matchRoute("diagnose issue with oauth callback");
147
+ assert.ok(match);
148
+ assert.equal(match.command, "debug");
149
+ });
150
+
151
+ test("/gsd do: routes 'investigate flaky test' to debug", () => {
152
+ const match = matchRoute("investigate flaky test in CI");
153
+ assert.ok(match);
154
+ assert.equal(match.command, "debug");
155
+ });
156
+
157
+ test("/gsd do: 'debug logs' keyword wins over bare 'debug' (longer keyword precedence)", () => {
158
+ // 'debug logs' (10 chars) > 'debug' (5 chars)
159
+ const logsMatch = matchRoute("debug logs for the last run");
160
+ assert.ok(logsMatch);
161
+ assert.equal(logsMatch.command, "logs");
162
+ assert.ok(logsMatch.score >= 10, `expected score >= 10, got ${logsMatch.score}`);
163
+
164
+ // Bare 'debug' without 'logs' should still route to debug.
165
+ const debugMatch = matchRoute("debug the payment timeout issue");
166
+ assert.ok(debugMatch);
167
+ assert.equal(debugMatch.command, "debug");
168
+ });
169
+
170
+ test("/gsd do: 'diagnose' alone routes to doctor (health check), not debug", () => {
171
+ // 'diagnose' maps to the doctor route; 'diagnose issue' maps to debug.
172
+ const match = matchRoute("diagnose my project");
173
+ assert.ok(match);
174
+ assert.equal(match.command, "doctor");
175
+ });
@@ -1,15 +1,19 @@
1
1
  import { describe, it, beforeEach, afterEach } from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdirSync, writeFileSync, rmSync } from "node:fs";
4
- import { join } from "node:path";
3
+ import { mkdirSync, writeFileSync, rmSync, readFileSync } from "node:fs";
4
+ import { join, dirname } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
  import { randomUUID } from "node:crypto";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const __dirname = dirname(fileURLToPath(import.meta.url));
7
10
 
8
11
  import {
9
12
  parseExtractLearningsArgs,
10
13
  buildLearningsOutputPath,
11
14
  resolvePhaseArtifacts,
12
15
  buildExtractLearningsPrompt,
16
+ buildExtractionStepsBlock,
13
17
  buildFrontmatter,
14
18
  extractProjectName,
15
19
  } from "../commands-extract-learnings.js";
@@ -66,26 +70,38 @@ describe("resolvePhaseArtifacts", () => {
66
70
  rmSync(tmpBase, { recursive: true, force: true });
67
71
  });
68
72
 
69
- it("finds required PLAN and SUMMARY when both present", () => {
70
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# M001 Plan content", "utf-8");
73
+ it("finds required ROADMAP and SUMMARY when both present", () => {
74
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# M001 Roadmap content", "utf-8");
71
75
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# M001 Summary content", "utf-8");
72
76
 
73
77
  const result = resolvePhaseArtifacts(tmpBase, "M001");
74
- assert.equal(result.plan, join(tmpBase, "M001-PLAN.md"));
78
+ assert.equal(result.roadmap, join(tmpBase, "M001-ROADMAP.md"));
75
79
  assert.equal(result.summary, join(tmpBase, "M001-SUMMARY.md"));
76
80
  assert.deepEqual(result.missingRequired, []);
77
81
  });
78
82
 
79
- it("reports missing PLAN as missingRequired", () => {
83
+ it("reports missing ROADMAP as missingRequired (regression for #4429)", () => {
80
84
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
81
85
 
82
86
  const result = resolvePhaseArtifacts(tmpBase, "M001");
83
- assert.ok(result.missingRequired.includes("M001-PLAN.md"));
84
- assert.equal(result.plan, null);
87
+ assert.ok(result.missingRequired.includes("M001-ROADMAP.md"));
88
+ assert.equal(result.roadmap, null);
89
+ });
90
+
91
+ it("does NOT require M001-PLAN.md (regression for #4429 — milestones use ROADMAP)", () => {
92
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
93
+ writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
94
+
95
+ const result = resolvePhaseArtifacts(tmpBase, "M001");
96
+ assert.ok(
97
+ !result.missingRequired.includes("M001-PLAN.md"),
98
+ "PLAN.md must not be demanded at milestone scope",
99
+ );
100
+ assert.deepEqual(result.missingRequired, []);
85
101
  });
86
102
 
87
103
  it("reports missing SUMMARY as missingRequired", () => {
88
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# Plan", "utf-8");
104
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
89
105
 
90
106
  const result = resolvePhaseArtifacts(tmpBase, "M001");
91
107
  assert.ok(result.missingRequired.includes("M001-SUMMARY.md"));
@@ -95,12 +111,12 @@ describe("resolvePhaseArtifacts", () => {
95
111
  it("reports both required files missing when neither present", () => {
96
112
  const result = resolvePhaseArtifacts(tmpBase, "M001");
97
113
  assert.equal(result.missingRequired.length, 2);
98
- assert.ok(result.missingRequired.includes("M001-PLAN.md"));
114
+ assert.ok(result.missingRequired.includes("M001-ROADMAP.md"));
99
115
  assert.ok(result.missingRequired.includes("M001-SUMMARY.md"));
100
116
  });
101
117
 
102
118
  it("finds optional VERIFICATION when present", () => {
103
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# Plan", "utf-8");
119
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
104
120
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
105
121
  writeFileSync(join(tmpBase, "M001-VERIFICATION.md"), "# Verification", "utf-8");
106
122
 
@@ -109,7 +125,7 @@ describe("resolvePhaseArtifacts", () => {
109
125
  });
110
126
 
111
127
  it("returns null for optional VERIFICATION when absent", () => {
112
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# Plan", "utf-8");
128
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
113
129
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
114
130
 
115
131
  const result = resolvePhaseArtifacts(tmpBase, "M001");
@@ -117,7 +133,7 @@ describe("resolvePhaseArtifacts", () => {
117
133
  });
118
134
 
119
135
  it("finds optional UAT when present", () => {
120
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# Plan", "utf-8");
136
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
121
137
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
122
138
  writeFileSync(join(tmpBase, "M001-UAT.md"), "# UAT", "utf-8");
123
139
 
@@ -126,7 +142,7 @@ describe("resolvePhaseArtifacts", () => {
126
142
  });
127
143
 
128
144
  it("returns null for optional UAT when absent, no error", () => {
129
- writeFileSync(join(tmpBase, "M001-PLAN.md"), "# Plan", "utf-8");
145
+ writeFileSync(join(tmpBase, "M001-ROADMAP.md"), "# Roadmap", "utf-8");
130
146
  writeFileSync(join(tmpBase, "M001-SUMMARY.md"), "# Summary", "utf-8");
131
147
 
132
148
  const result = resolvePhaseArtifacts(tmpBase, "M001");
@@ -144,7 +160,7 @@ describe("buildExtractLearningsPrompt", () => {
144
160
  milestoneName: "Test Milestone",
145
161
  outputPath: "/project/.gsd/milestones/M001/M001-LEARNINGS.md",
146
162
  relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
147
- planContent: "# Plan content",
163
+ roadmapContent: "# Roadmap content",
148
164
  summaryContent: "# Summary content",
149
165
  verificationContent: null,
150
166
  uatContent: null,
@@ -162,7 +178,7 @@ describe("buildExtractLearningsPrompt", () => {
162
178
  milestoneName: "Test Milestone",
163
179
  outputPath: "/out/M001-LEARNINGS.md",
164
180
  relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
165
- planContent: "# Plan",
181
+ roadmapContent: "# Roadmap",
166
182
  summaryContent: "# Summary",
167
183
  verificationContent: null,
168
184
  uatContent: null,
@@ -176,13 +192,13 @@ describe("buildExtractLearningsPrompt", () => {
176
192
  assert.ok(result.includes("Surprises"));
177
193
  });
178
194
 
179
- it("includes plan and summary content", () => {
195
+ it("includes roadmap and summary content", () => {
180
196
  const result = buildExtractLearningsPrompt({
181
197
  milestoneId: "M001",
182
198
  milestoneName: "Test Milestone",
183
199
  outputPath: "/out/M001-LEARNINGS.md",
184
200
  relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
185
- planContent: "PLAN_CONTENT_UNIQUE_123",
201
+ roadmapContent: "ROADMAP_CONTENT_UNIQUE_123",
186
202
  summaryContent: "SUMMARY_CONTENT_UNIQUE_456",
187
203
  verificationContent: null,
188
204
  uatContent: null,
@@ -190,7 +206,7 @@ describe("buildExtractLearningsPrompt", () => {
190
206
  projectName: "MyProject",
191
207
  });
192
208
 
193
- assert.ok(result.includes("PLAN_CONTENT_UNIQUE_123"));
209
+ assert.ok(result.includes("ROADMAP_CONTENT_UNIQUE_123"));
194
210
  assert.ok(result.includes("SUMMARY_CONTENT_UNIQUE_456"));
195
211
  });
196
212
 
@@ -200,7 +216,7 @@ describe("buildExtractLearningsPrompt", () => {
200
216
  milestoneName: "Test Milestone",
201
217
  outputPath: "/out/M001-LEARNINGS.md",
202
218
  relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
203
- planContent: "# Plan",
219
+ roadmapContent: "# Roadmap",
204
220
  summaryContent: "# Summary",
205
221
  verificationContent: "VERIFICATION_UNIQUE_789",
206
222
  uatContent: "UAT_UNIQUE_012",
@@ -218,7 +234,7 @@ describe("buildExtractLearningsPrompt", () => {
218
234
  milestoneName: "Test Milestone",
219
235
  outputPath: "/out/M001-LEARNINGS.md",
220
236
  relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
221
- planContent: "# Plan",
237
+ roadmapContent: "# Roadmap",
222
238
  summaryContent: "# Summary",
223
239
  verificationContent: null,
224
240
  uatContent: null,
@@ -228,6 +244,64 @@ describe("buildExtractLearningsPrompt", () => {
228
244
 
229
245
  assert.ok(result.includes("M001-VERIFICATION.md"));
230
246
  });
247
+
248
+ it("does NOT reference phantom capture_thought tool (regression for #4429)", () => {
249
+ const result = buildExtractLearningsPrompt({
250
+ milestoneId: "M001",
251
+ milestoneName: "Test Milestone",
252
+ outputPath: "/out/M001-LEARNINGS.md",
253
+ relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
254
+ roadmapContent: "# Roadmap",
255
+ summaryContent: "# Summary",
256
+ verificationContent: null,
257
+ uatContent: null,
258
+ missingArtifacts: [],
259
+ projectName: "MyProject",
260
+ });
261
+
262
+ assert.ok(
263
+ !result.includes("capture_thought"),
264
+ "prompt must not advertise the non-existent capture_thought tool",
265
+ );
266
+ });
267
+
268
+ it("does NOT reference phantom gsd_graph tool (regression for #4429)", () => {
269
+ const result = buildExtractLearningsPrompt({
270
+ milestoneId: "M001",
271
+ milestoneName: "Test Milestone",
272
+ outputPath: "/out/M001-LEARNINGS.md",
273
+ relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
274
+ roadmapContent: "# Roadmap",
275
+ summaryContent: "# Summary",
276
+ verificationContent: null,
277
+ uatContent: null,
278
+ missingArtifacts: [],
279
+ projectName: "MyProject",
280
+ });
281
+
282
+ assert.ok(
283
+ !result.includes("gsd_graph"),
284
+ "prompt must not advertise the non-existent gsd_graph tool",
285
+ );
286
+ });
287
+
288
+ it("source-attribution example references ROADMAP.md, not PLAN.md (regression for #4429)", () => {
289
+ const result = buildExtractLearningsPrompt({
290
+ milestoneId: "M001",
291
+ milestoneName: "Test Milestone",
292
+ outputPath: "/out/M001-LEARNINGS.md",
293
+ relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
294
+ roadmapContent: "# Roadmap",
295
+ summaryContent: "# Summary",
296
+ verificationContent: null,
297
+ uatContent: null,
298
+ missingArtifacts: [],
299
+ projectName: "MyProject",
300
+ });
301
+
302
+ assert.ok(result.includes("M001-ROADMAP.md/Architecture Decisions"));
303
+ assert.ok(!result.includes("M001-PLAN.md/Architecture Decisions"));
304
+ });
231
305
  });
232
306
 
233
307
  // ─── buildFrontmatter ─────────────────────────────────────────────────────────
@@ -338,3 +412,241 @@ describe("extractProjectName", () => {
338
412
  assert.equal(result, tmpBase.split("/").at(-1));
339
413
  });
340
414
  });
415
+
416
+ // ─── buildExtractionStepsBlock ────────────────────────────────────────────────
417
+ //
418
+ // The steps block is the single source of truth for how learnings are routed
419
+ // into KNOWLEDGE.md and the DECISIONS DB. Both the manual /gsd extract-learnings
420
+ // path and the auto complete-milestone path render it verbatim, so every
421
+ // structural assertion below protects both paths at once.
422
+
423
+ describe("buildExtractionStepsBlock", () => {
424
+ const ctx = {
425
+ milestoneId: "M042",
426
+ outputPath: "/project/.gsd/milestones/M042/M042-LEARNINGS.md",
427
+ relativeOutputPath: ".gsd/milestones/M042/M042-LEARNINGS.md",
428
+ };
429
+
430
+ it("declares itself as the structured extraction procedure", () => {
431
+ const block = buildExtractionStepsBlock(ctx);
432
+ assert.ok(block.includes("Structured Learnings Extraction"));
433
+ });
434
+
435
+ it("instructs the LLM to write LEARNINGS.md at the given relative path", () => {
436
+ const block = buildExtractionStepsBlock(ctx);
437
+ assert.ok(block.includes(ctx.relativeOutputPath));
438
+ assert.ok(block.includes("YAML frontmatter"));
439
+ });
440
+
441
+ it("covers all four extraction categories", () => {
442
+ const block = buildExtractionStepsBlock(ctx);
443
+ assert.ok(block.includes("Decisions"));
444
+ assert.ok(block.includes("Lessons"));
445
+ assert.ok(block.includes("Patterns"));
446
+ assert.ok(block.includes("Surprises"));
447
+ });
448
+
449
+ it("requires a Source attribution for every item", () => {
450
+ const block = buildExtractionStepsBlock(ctx);
451
+ assert.ok(block.includes("Source:"));
452
+ assert.ok(block.includes("M042-ROADMAP.md"));
453
+ });
454
+
455
+ it("points the LLM at .gsd/KNOWLEDGE.md for append", () => {
456
+ const block = buildExtractionStepsBlock(ctx);
457
+ assert.ok(block.includes(".gsd/KNOWLEDGE.md"));
458
+ });
459
+
460
+ it("covers the missing-file case with the canonical KNOWLEDGE.md template", () => {
461
+ const block = buildExtractionStepsBlock(ctx);
462
+ assert.ok(block.includes("If the file does not exist yet, create it first"));
463
+ // Canonical column headers must be inlined so the LLM does not have to guess.
464
+ assert.ok(block.includes("| # | Scope | Rule | Why | Added |"));
465
+ assert.ok(block.includes("| # | Pattern | Where | Notes |"));
466
+ assert.ok(block.includes("| # | What Happened | Root Cause | Fix | Scope |"));
467
+ });
468
+
469
+ it("specifies the exact Patterns row format with milestone scope", () => {
470
+ const block = buildExtractionStepsBlock(ctx);
471
+ assert.ok(block.includes("| P<NNN>"));
472
+ assert.ok(block.includes(`| ${ctx.milestoneId} |`));
473
+ });
474
+
475
+ it("specifies the exact Lessons row format with milestone scope", () => {
476
+ const block = buildExtractionStepsBlock(ctx);
477
+ assert.ok(block.includes("| L<NNN>"));
478
+ });
479
+
480
+ it("enforces zero-padded three-digit IDs", () => {
481
+ const block = buildExtractionStepsBlock(ctx);
482
+ assert.ok(/zero[- ]pad/i.test(block));
483
+ assert.ok(block.includes("three digits") || block.includes("3 digits"));
484
+ });
485
+
486
+ it("instructs append-only behaviour (no edits to existing rows)", () => {
487
+ const block = buildExtractionStepsBlock(ctx);
488
+ assert.ok(block.includes("Append-only"));
489
+ });
490
+
491
+ it("uses em-dash as the placeholder for unknown column values", () => {
492
+ const block = buildExtractionStepsBlock(ctx);
493
+ assert.ok(block.includes("—"));
494
+ assert.ok(!block.includes("N/A"));
495
+ });
496
+
497
+ it("forbids modifications to the Rules table", () => {
498
+ const block = buildExtractionStepsBlock(ctx);
499
+ assert.ok(/do not.*rules/i.test(block.toLowerCase()) || block.includes("Do NOT modify"));
500
+ assert.ok(block.includes("## Rules"));
501
+ });
502
+
503
+ it("routes Decisions through the gsd_save_decision MCP tool", () => {
504
+ const block = buildExtractionStepsBlock(ctx);
505
+ assert.ok(block.includes("gsd_save_decision"));
506
+ assert.ok(block.includes("`scope`"));
507
+ assert.ok(block.includes("`decision`"));
508
+ assert.ok(block.includes("`choice`"));
509
+ assert.ok(block.includes("`rationale`"));
510
+ assert.ok(block.includes("`made_by`"));
511
+ });
512
+
513
+ it("forbids direct edits to DECISIONS.md (DB-authoritative)", () => {
514
+ const block = buildExtractionStepsBlock(ctx);
515
+ assert.ok(/never edit.+decisions\.md/i.test(block));
516
+ });
517
+
518
+ it("keeps Surprises milestone-local (not in KNOWLEDGE.md, no tool call)", () => {
519
+ const block = buildExtractionStepsBlock(ctx);
520
+ assert.ok(block.includes("Surprises stay only in LEARNINGS.md"));
521
+ });
522
+
523
+ it("enforces a deduplication rule across all persistence steps", () => {
524
+ const block = buildExtractionStepsBlock(ctx);
525
+ assert.ok(/deduplication/i.test(block) || /dedup/i.test(block));
526
+ assert.ok(/semantically equivalent/i.test(block));
527
+ assert.ok(/skip/i.test(block));
528
+ });
529
+
530
+ it("does NOT reference the non-existent capture_thought tool (#4429 regression)", () => {
531
+ const block = buildExtractionStepsBlock(ctx);
532
+ assert.ok(!block.includes("capture_thought"));
533
+ });
534
+
535
+ it("does NOT reference the non-existent gsd_graph tool (#4429 regression)", () => {
536
+ const block = buildExtractionStepsBlock(ctx);
537
+ assert.ok(!block.includes("gsd_graph"));
538
+ });
539
+
540
+ it("substitutes the milestone ID into every placeholder callout", () => {
541
+ const block = buildExtractionStepsBlock({
542
+ milestoneId: "M999",
543
+ outputPath: "/p/.gsd/milestones/M999/M999-LEARNINGS.md",
544
+ relativeOutputPath: ".gsd/milestones/M999/M999-LEARNINGS.md",
545
+ });
546
+ assert.ok(!block.includes("M042"));
547
+ assert.ok(block.includes("M999"));
548
+ });
549
+ });
550
+
551
+ // ─── buildExtractLearningsPrompt composition ──────────────────────────────────
552
+
553
+ describe("buildExtractLearningsPrompt composes the steps block", () => {
554
+ it("embeds the exact buildExtractionStepsBlock output for the same context", () => {
555
+ const shared = {
556
+ milestoneId: "M007",
557
+ outputPath: "/p/.gsd/milestones/M007/M007-LEARNINGS.md",
558
+ relativeOutputPath: ".gsd/milestones/M007/M007-LEARNINGS.md",
559
+ };
560
+ const expected = buildExtractionStepsBlock(shared);
561
+ const prompt = buildExtractLearningsPrompt({
562
+ ...shared,
563
+ milestoneName: "Composition",
564
+ roadmapContent: "# Roadmap body",
565
+ summaryContent: "# Summary body",
566
+ verificationContent: null,
567
+ uatContent: null,
568
+ missingArtifacts: [],
569
+ projectName: "TestProj",
570
+ });
571
+
572
+ assert.ok(prompt.includes(expected));
573
+ });
574
+
575
+ it("no longer contains the orphan-file disclaimer from the previous revision", () => {
576
+ const prompt = buildExtractLearningsPrompt({
577
+ milestoneId: "M001",
578
+ milestoneName: "Test",
579
+ outputPath: "/out/M001-LEARNINGS.md",
580
+ relativeOutputPath: ".gsd/milestones/M001/M001-LEARNINGS.md",
581
+ roadmapContent: "# Roadmap",
582
+ summaryContent: "# Summary",
583
+ verificationContent: null,
584
+ uatContent: null,
585
+ missingArtifacts: [],
586
+ projectName: "P",
587
+ });
588
+
589
+ assert.ok(!prompt.includes("no automated pipeline currently consumes it"));
590
+ });
591
+ });
592
+
593
+ // ─── complete-milestone.md loadPrompt round-trip ─────────────────────────────
594
+
595
+ describe("complete-milestone loadPrompt round-trip (#4429)", () => {
596
+ it("substitutes {{extractLearningsSteps}} end-to-end via prompt-loader", async () => {
597
+ const { loadPrompt } = await import("../prompt-loader.js");
598
+ const stepsBlock = buildExtractionStepsBlock({
599
+ milestoneId: "M123",
600
+ outputPath: "/p/.gsd/milestones/M123/M123-LEARNINGS.md",
601
+ relativeOutputPath: ".gsd/milestones/M123/M123-LEARNINGS.md",
602
+ });
603
+
604
+ const rendered = loadPrompt("complete-milestone", {
605
+ workingDirectory: "/p",
606
+ milestoneId: "M123",
607
+ milestoneTitle: "Test Milestone",
608
+ roadmapPath: ".gsd/milestones/M123/M123-ROADMAP.md",
609
+ inlinedContext: "(inlined context stub)",
610
+ milestoneSummaryPath: "/p/.gsd/milestones/M123/M123-SUMMARY.md",
611
+ extractLearningsSteps: stepsBlock,
612
+ });
613
+
614
+ // Placeholder must be gone — real content must be in.
615
+ assert.ok(!rendered.includes("{{extractLearningsSteps}}"));
616
+ assert.ok(rendered.includes("Structured Learnings Extraction"));
617
+ assert.ok(rendered.includes("gsd_save_decision"));
618
+ assert.ok(rendered.includes("M123"));
619
+ });
620
+ });
621
+
622
+ // ─── complete-milestone.md template wiring ────────────────────────────────────
623
+
624
+ describe("complete-milestone.md template wiring (#4429)", () => {
625
+ const promptPath = join(
626
+ __dirname,
627
+ "..",
628
+ "prompts",
629
+ "complete-milestone.md",
630
+ );
631
+
632
+ it("declares the {{extractLearningsSteps}} placeholder", () => {
633
+ const content = readFileSync(promptPath, "utf-8");
634
+ assert.ok(content.includes("{{extractLearningsSteps}}"));
635
+ });
636
+
637
+ it("no longer contains the deprecated ad-hoc KNOWLEDGE.md step", () => {
638
+ const content = readFileSync(promptPath, "utf-8");
639
+ assert.ok(
640
+ !content.includes("Review all slice summaries for cross-cutting lessons, patterns, or gotchas"),
641
+ "the pre-#4429 one-sentence step 12 must be removed",
642
+ );
643
+ });
644
+
645
+ it("keeps the milestone-completion commit instruction after the placeholder", () => {
646
+ const content = readFileSync(promptPath, "utf-8");
647
+ const placeholderIdx = content.indexOf("{{extractLearningsSteps}}");
648
+ const commitIdx = content.indexOf("Do not commit manually");
649
+ assert.ok(placeholderIdx > 0);
650
+ assert.ok(commitIdx > placeholderIdx, "commit instruction must come after extraction block");
651
+ });
652
+ });