gsd-pi 2.75.0-next.9c0ec0ba1 → 2.76.0-dev.b072ebb73

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 (680) hide show
  1. package/README.md +145 -125
  2. package/dist/claude-cli-check.d.ts +10 -0
  3. package/dist/claude-cli-check.js +13 -3
  4. package/dist/onboarding.d.ts +20 -1
  5. package/dist/onboarding.js +60 -25
  6. package/dist/resources/agents/researcher.md +1 -1
  7. package/dist/resources/extensions/ask-user-questions.js +6 -3
  8. package/dist/resources/extensions/claude-code-cli/readiness.js +34 -2
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +44 -2
  10. package/dist/resources/extensions/gsd/auto/phases.js +48 -6
  11. package/dist/resources/extensions/gsd/auto-artifact-paths.js +20 -0
  12. package/dist/resources/extensions/gsd/auto-dashboard.js +37 -8
  13. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +8 -2
  14. package/dist/resources/extensions/gsd/auto-dispatch.js +87 -9
  15. package/dist/resources/extensions/gsd/auto-model-selection.js +27 -6
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -5
  17. package/dist/resources/extensions/gsd/auto-prompts.js +188 -44
  18. package/dist/resources/extensions/gsd/auto-recovery.js +48 -0
  19. package/dist/resources/extensions/gsd/auto-start.js +5 -3
  20. package/dist/resources/extensions/gsd/auto-verification.js +33 -0
  21. package/dist/resources/extensions/gsd/auto-worktree.js +71 -2
  22. package/dist/resources/extensions/gsd/auto.js +25 -3
  23. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +8 -21
  24. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +45 -23
  25. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +131 -0
  26. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +29 -0
  27. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +12 -0
  28. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +22 -0
  29. package/dist/resources/extensions/gsd/bootstrap/system-context.js +84 -10
  30. package/dist/resources/extensions/gsd/commands/catalog.js +15 -7
  31. package/dist/resources/extensions/gsd/commands/handlers/core.js +58 -24
  32. package/dist/resources/extensions/gsd/commands/handlers/escalate.js +171 -0
  33. package/dist/resources/extensions/gsd/commands/handlers/onboarding.js +159 -0
  34. package/dist/resources/extensions/gsd/commands/handlers/ops.js +10 -0
  35. package/dist/resources/extensions/gsd/commands-config.js +5 -0
  36. package/dist/resources/extensions/gsd/commands-extract-learnings.js +200 -77
  37. package/dist/resources/extensions/gsd/commands-memory.js +462 -0
  38. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +39 -11
  39. package/dist/resources/extensions/gsd/custom-workflow-engine.js +74 -54
  40. package/dist/resources/extensions/gsd/db-writer.js +89 -16
  41. package/dist/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  42. package/dist/resources/extensions/gsd/doctor-environment.js +2 -1
  43. package/dist/resources/extensions/gsd/doctor-git-checks.js +50 -32
  44. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -1
  45. package/dist/resources/extensions/gsd/doctor-providers.js +51 -5
  46. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +21 -1
  47. package/dist/resources/extensions/gsd/doctor.js +7 -1
  48. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +1 -0
  49. package/dist/resources/extensions/gsd/error-classifier.js +5 -2
  50. package/dist/resources/extensions/gsd/escalation.js +321 -0
  51. package/dist/resources/extensions/gsd/graph.js +26 -0
  52. package/dist/resources/extensions/gsd/gsd-db.js +517 -32
  53. package/dist/resources/extensions/gsd/health-widget-core.js +42 -14
  54. package/dist/resources/extensions/gsd/health-widget.js +7 -4
  55. package/dist/resources/extensions/gsd/hook-emitter.js +108 -0
  56. package/dist/resources/extensions/gsd/init-wizard.js +86 -45
  57. package/dist/resources/extensions/gsd/markdown-renderer.js +5 -5
  58. package/dist/resources/extensions/gsd/memory-backfill.js +126 -0
  59. package/dist/resources/extensions/gsd/memory-embeddings.js +219 -0
  60. package/dist/resources/extensions/gsd/memory-extractor.js +78 -27
  61. package/dist/resources/extensions/gsd/memory-ingest.js +218 -0
  62. package/dist/resources/extensions/gsd/memory-relations.js +189 -0
  63. package/dist/resources/extensions/gsd/memory-source-store.js +113 -0
  64. package/dist/resources/extensions/gsd/memory-store.js +318 -6
  65. package/dist/resources/extensions/gsd/metrics.js +1 -0
  66. package/dist/resources/extensions/gsd/model-cost-table.js +1 -0
  67. package/dist/resources/extensions/gsd/model-router.js +12 -5
  68. package/dist/resources/extensions/gsd/native-git-bridge.js +121 -5
  69. package/dist/resources/extensions/gsd/notification-overlay.js +7 -22
  70. package/dist/resources/extensions/gsd/notification-widget.js +24 -39
  71. package/dist/resources/extensions/gsd/onboarding-state.js +133 -0
  72. package/dist/resources/extensions/gsd/post-execution-checks.js +27 -11
  73. package/dist/resources/extensions/gsd/pre-execution-checks.js +98 -8
  74. package/dist/resources/extensions/gsd/preferences-models.js +1 -0
  75. package/dist/resources/extensions/gsd/preferences-types.js +2 -1
  76. package/dist/resources/extensions/gsd/preferences-validation.js +42 -8
  77. package/dist/resources/extensions/gsd/prompts/add-tests.md +1 -0
  78. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  79. package/dist/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  80. package/dist/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  81. package/dist/resources/extensions/gsd/prompts/execute-task.md +16 -3
  82. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  83. package/dist/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  84. package/dist/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  85. package/dist/resources/extensions/gsd/prompts/research-slice.md +1 -0
  86. package/dist/resources/extensions/gsd/python-resolver.js +70 -0
  87. package/dist/resources/extensions/gsd/setup-catalog.js +75 -0
  88. package/dist/resources/extensions/gsd/state.js +90 -7
  89. package/dist/resources/extensions/gsd/templates/PREFERENCES.md +1 -1
  90. package/dist/resources/extensions/gsd/tools/complete-task.js +80 -0
  91. package/dist/resources/extensions/gsd/tools/memory-tools.js +331 -0
  92. package/dist/resources/extensions/gsd/tools/plan-milestone.js +37 -12
  93. package/dist/resources/extensions/gsd/tools/plan-slice.js +5 -2
  94. package/dist/resources/extensions/gsd/tools/skip-slice.js +78 -0
  95. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +14 -0
  96. package/dist/resources/extensions/gsd/uok/flags.js +1 -1
  97. package/dist/resources/extensions/gsd/verification-gate.js +2 -1
  98. package/dist/resources/extensions/gsd/workflow-manifest.js +8 -0
  99. package/dist/resources/extensions/gsd/workflow-mcp.js +1 -0
  100. package/dist/resources/extensions/gsd/workflow-projections.js +17 -15
  101. package/dist/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  102. package/dist/resources/extensions/gsd/worktree-resolver.js +42 -1
  103. package/dist/resources/extensions/remote-questions/manager.js +11 -1
  104. package/dist/resources/extensions/search-the-web/command-search-provider.js +4 -1
  105. package/dist/resources/extensions/search-the-web/native-search.js +13 -2
  106. package/dist/resources/skills/api-design/SKILL.md +190 -0
  107. package/dist/resources/skills/create-mcp-server/SKILL.md +121 -0
  108. package/dist/resources/skills/decompose-into-slices/SKILL.md +139 -0
  109. package/dist/resources/skills/dependency-upgrade/SKILL.md +158 -0
  110. package/dist/resources/skills/design-an-interface/SKILL.md +102 -0
  111. package/dist/resources/skills/forensics/SKILL.md +153 -0
  112. package/dist/resources/skills/grill-me/SKILL.md +93 -0
  113. package/dist/resources/skills/handoff/SKILL.md +121 -0
  114. package/dist/resources/skills/observability/SKILL.md +174 -0
  115. package/dist/resources/skills/security-review/SKILL.md +181 -0
  116. package/dist/resources/skills/spike-wrap-up/SKILL.md +138 -0
  117. package/dist/resources/skills/tdd/SKILL.md +112 -0
  118. package/dist/resources/skills/verify-before-complete/SKILL.md +97 -0
  119. package/dist/resources/skills/write-docs/SKILL.md +81 -0
  120. package/dist/resources/skills/write-milestone-brief/SKILL.md +135 -0
  121. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  122. package/dist/web/standalone/.next/BUILD_ID +1 -1
  123. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  124. package/dist/web/standalone/.next/build-manifest.json +3 -3
  125. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  126. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  127. package/dist/web/standalone/.next/required-server-files.json +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  136. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.rsc +2 -2
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  143. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  144. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  145. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  146. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  148. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  150. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  152. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  153. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  154. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  156. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  158. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  160. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  162. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  164. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  166. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  168. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  170. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  172. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  174. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  176. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  178. package/dist/web/standalone/.next/server/app/api/notifications/route.js +2 -2
  179. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  180. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  182. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  184. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  186. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  188. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  190. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  191. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  192. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  194. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  196. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  198. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  200. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  202. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  203. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  204. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +2 -2
  205. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  206. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  207. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  208. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  209. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  210. package/dist/web/standalone/.next/server/app/index.html +1 -1
  211. package/dist/web/standalone/.next/server/app/index.rsc +3 -3
  212. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  213. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +3 -3
  214. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  215. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +2 -2
  216. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -2
  217. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  218. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  219. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  220. package/dist/web/standalone/.next/server/chunks/7461.js +1 -0
  221. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  222. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  223. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  224. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  225. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  226. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  227. package/dist/web/standalone/.next/static/chunks/{2826.02df9631042cc18e.js → 2826.e59e8578e2e28639.js} +2 -2
  228. package/dist/web/standalone/.next/static/chunks/{2008.71ee9230ad78df21.js → 3621.fc7480022c972438.js} +2 -2
  229. package/dist/web/standalone/.next/static/chunks/app/{page-f1e30ab6bb269149.js → page-5b113fd32bc2a1c3.js} +1 -1
  230. package/dist/web/standalone/.next/static/chunks/{webpack-6c7cda3e318eedb6.js → webpack-5fc74f13a25fa1bb.js} +1 -1
  231. package/dist/web/standalone/.next/static/css/632cd626b1731d88.css +1 -0
  232. package/dist/web/standalone/server.js +1 -1
  233. package/dist/welcome-screen.js +48 -24
  234. package/package.json +1 -1
  235. package/packages/daemon/package.json +2 -2
  236. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  237. package/packages/mcp-server/dist/server.js +12 -10
  238. package/packages/mcp-server/dist/server.js.map +1 -1
  239. package/packages/mcp-server/dist/session-manager.d.ts.map +1 -1
  240. package/packages/mcp-server/dist/session-manager.js +8 -1
  241. package/packages/mcp-server/dist/session-manager.js.map +1 -1
  242. package/packages/mcp-server/dist/workflow-tools.d.ts +2 -1
  243. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  244. package/packages/mcp-server/dist/workflow-tools.js +306 -71
  245. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  246. package/packages/mcp-server/package.json +2 -2
  247. package/packages/mcp-server/src/mcp-server.test.ts +40 -4
  248. package/packages/mcp-server/src/server.ts +12 -10
  249. package/packages/mcp-server/src/session-manager.ts +10 -3
  250. package/packages/mcp-server/src/workflow-tools.test.ts +346 -1
  251. package/packages/mcp-server/src/workflow-tools.ts +359 -75
  252. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  253. package/packages/native/package.json +1 -1
  254. package/packages/pi-agent-core/dist/agent-loop.js +12 -0
  255. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  256. package/packages/pi-agent-core/dist/types.d.ts +30 -0
  257. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  258. package/packages/pi-agent-core/dist/types.js.map +1 -1
  259. package/packages/pi-agent-core/package.json +1 -1
  260. package/packages/pi-agent-core/src/agent-loop.ts +14 -0
  261. package/packages/pi-agent-core/src/types.ts +34 -0
  262. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  263. package/packages/pi-ai/dist/index.d.ts +1 -0
  264. package/packages/pi-ai/dist/index.d.ts.map +1 -1
  265. package/packages/pi-ai/dist/index.js +1 -0
  266. package/packages/pi-ai/dist/index.js.map +1 -1
  267. package/packages/pi-ai/dist/models/generated/index.d.ts +17 -0
  268. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  269. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  270. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  271. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  272. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  273. package/packages/pi-ai/dist/models.generated.test.js +1 -0
  274. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  275. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts +22 -1
  276. package/packages/pi-ai/dist/providers/amazon-bedrock.d.ts.map +1 -1
  277. package/packages/pi-ai/dist/providers/amazon-bedrock.js +40 -7
  278. package/packages/pi-ai/dist/providers/amazon-bedrock.js.map +1 -1
  279. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts +2 -0
  280. package/packages/pi-ai/dist/providers/amazon-bedrock.test.d.ts.map +1 -0
  281. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js +106 -0
  282. package/packages/pi-ai/dist/providers/amazon-bedrock.test.js.map +1 -0
  283. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +42 -1
  284. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  285. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts +2 -0
  286. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.d.ts.map +1 -0
  287. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +13 -0
  288. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -0
  289. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts +19 -0
  290. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  291. package/packages/pi-ai/dist/providers/anthropic-shared.js +25 -1
  292. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  293. package/packages/pi-ai/dist/providers/anthropic.d.ts +11 -0
  294. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  295. package/packages/pi-ai/dist/providers/anthropic.js +23 -2
  296. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  297. package/packages/pi-ai/dist/providers/api-family.d.ts +27 -0
  298. package/packages/pi-ai/dist/providers/api-family.d.ts.map +1 -0
  299. package/packages/pi-ai/dist/providers/api-family.js +47 -0
  300. package/packages/pi-ai/dist/providers/api-family.js.map +1 -0
  301. package/packages/pi-ai/dist/providers/api-family.test.d.ts +2 -0
  302. package/packages/pi-ai/dist/providers/api-family.test.d.ts.map +1 -0
  303. package/packages/pi-ai/dist/providers/api-family.test.js +101 -0
  304. package/packages/pi-ai/dist/providers/api-family.test.js.map +1 -0
  305. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  306. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +12 -2
  307. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  308. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +164 -14
  309. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  310. package/packages/pi-ai/dist/utils/oauth/google-antigravity.d.ts.map +1 -1
  311. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js +15 -3
  312. package/packages/pi-ai/dist/utils/oauth/google-antigravity.js.map +1 -1
  313. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts +2 -0
  314. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.d.ts.map +1 -0
  315. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +67 -0
  316. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -0
  317. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.d.ts.map +1 -1
  318. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js +16 -3
  319. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.js.map +1 -1
  320. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts +2 -0
  321. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.d.ts.map +1 -0
  322. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +67 -0
  323. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -0
  324. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +2 -0
  325. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +1 -0
  326. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +289 -0
  327. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +1 -0
  328. package/packages/pi-ai/dist/utils/oauth/openai-codex.d.ts.map +1 -1
  329. package/packages/pi-ai/dist/utils/oauth/openai-codex.js +12 -0
  330. package/packages/pi-ai/dist/utils/oauth/openai-codex.js.map +1 -1
  331. package/packages/pi-ai/package.json +1 -1
  332. package/packages/pi-ai/scripts/generate-models.ts +12 -0
  333. package/packages/pi-ai/src/index.ts +1 -0
  334. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  335. package/packages/pi-ai/src/models.generated.test.ts +1 -0
  336. package/packages/pi-ai/src/providers/amazon-bedrock.test.ts +164 -0
  337. package/packages/pi-ai/src/providers/amazon-bedrock.ts +41 -8
  338. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +47 -1
  339. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -0
  340. package/packages/pi-ai/src/providers/anthropic-shared.ts +30 -1
  341. package/packages/pi-ai/src/providers/anthropic.ts +25 -2
  342. package/packages/pi-ai/src/providers/api-family.test.ts +129 -0
  343. package/packages/pi-ai/src/providers/api-family.ts +57 -0
  344. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +200 -23
  345. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +12 -2
  346. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +84 -0
  347. package/packages/pi-ai/src/utils/oauth/google-antigravity.ts +15 -5
  348. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +84 -0
  349. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.ts +16 -5
  350. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +363 -0
  351. package/packages/pi-ai/src/utils/oauth/openai-codex.ts +15 -0
  352. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  353. package/packages/pi-coding-agent/dist/cli/args.d.ts +6 -0
  354. package/packages/pi-coding-agent/dist/cli/args.d.ts.map +1 -1
  355. package/packages/pi-coding-agent/dist/cli/args.js +14 -4
  356. package/packages/pi-coding-agent/dist/cli/args.js.map +1 -1
  357. package/packages/pi-coding-agent/dist/cli/args.test.d.ts +2 -0
  358. package/packages/pi-coding-agent/dist/cli/args.test.d.ts.map +1 -0
  359. package/packages/pi-coding-agent/dist/cli/args.test.js +38 -0
  360. package/packages/pi-coding-agent/dist/cli/args.test.js.map +1 -0
  361. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  362. package/packages/pi-coding-agent/dist/core/agent-session.js +25 -2
  363. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  364. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  365. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  366. package/packages/pi-coding-agent/dist/core/auth-storage.js +25 -0
  367. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  368. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +38 -0
  369. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  370. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +4 -1
  371. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  372. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts +1 -1
  373. package/packages/pi-coding-agent/dist/core/extensions/index.d.ts.map +1 -1
  374. package/packages/pi-coding-agent/dist/core/extensions/index.js.map +1 -1
  375. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  376. package/packages/pi-coding-agent/dist/core/extensions/loader.js +4 -0
  377. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  378. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +34 -2
  379. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  380. package/packages/pi-coding-agent/dist/core/extensions/runner.js +233 -0
  381. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  382. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +200 -3
  383. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  384. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  385. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts +53 -0
  386. package/packages/pi-coding-agent/dist/core/hooks-runner.d.ts.map +1 -0
  387. package/packages/pi-coding-agent/dist/core/hooks-runner.js +337 -0
  388. package/packages/pi-coding-agent/dist/core/hooks-runner.js.map +1 -0
  389. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts +2 -0
  390. package/packages/pi-coding-agent/dist/core/hooks-runner.test.d.ts.map +1 -0
  391. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +234 -0
  392. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -0
  393. package/packages/pi-coding-agent/dist/core/index.d.ts +1 -0
  394. package/packages/pi-coding-agent/dist/core/index.d.ts.map +1 -1
  395. package/packages/pi-coding-agent/dist/core/index.js +1 -0
  396. package/packages/pi-coding-agent/dist/core/index.js.map +1 -1
  397. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts +2 -0
  398. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.d.ts.map +1 -0
  399. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js +40 -0
  400. package/packages/pi-coding-agent/dist/core/model-registry-auth-header.test.js.map +1 -0
  401. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +32 -0
  402. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  403. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  404. package/packages/pi-coding-agent/dist/core/retry-handler.js +4 -1
  405. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  406. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -0
  407. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  408. package/packages/pi-coding-agent/dist/core/sdk.js +33 -5
  409. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  410. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +55 -0
  411. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  412. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  413. package/packages/pi-coding-agent/dist/index.d.ts +1 -1
  414. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  415. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  416. package/packages/pi-coding-agent/dist/main.d.ts.map +1 -1
  417. package/packages/pi-coding-agent/dist/main.js +3 -0
  418. package/packages/pi-coding-agent/dist/main.js.map +1 -1
  419. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  420. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +17 -7
  421. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  422. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  423. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +48 -34
  424. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  425. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts +4 -0
  426. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  427. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +83 -33
  428. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  429. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +1 -0
  430. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  431. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +1 -0
  432. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  433. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  434. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  435. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  436. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  437. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +13 -9
  438. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  439. package/packages/pi-coding-agent/package.json +1 -1
  440. package/packages/pi-coding-agent/src/cli/args.test.ts +44 -0
  441. package/packages/pi-coding-agent/src/cli/args.ts +21 -6
  442. package/packages/pi-coding-agent/src/core/agent-session.ts +27 -2
  443. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +42 -0
  444. package/packages/pi-coding-agent/src/core/auth-storage.ts +25 -0
  445. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +4 -1
  446. package/packages/pi-coding-agent/src/core/extensions/index.ts +16 -0
  447. package/packages/pi-coding-agent/src/core/extensions/loader.ts +5 -0
  448. package/packages/pi-coding-agent/src/core/extensions/runner.ts +353 -1
  449. package/packages/pi-coding-agent/src/core/extensions/types.ts +253 -2
  450. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +269 -0
  451. package/packages/pi-coding-agent/src/core/hooks-runner.ts +460 -0
  452. package/packages/pi-coding-agent/src/core/index.ts +10 -0
  453. package/packages/pi-coding-agent/src/core/model-registry-auth-header.test.ts +44 -0
  454. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +37 -1
  455. package/packages/pi-coding-agent/src/core/retry-handler.ts +4 -1
  456. package/packages/pi-coding-agent/src/core/sdk.ts +48 -5
  457. package/packages/pi-coding-agent/src/core/settings-manager.ts +57 -0
  458. package/packages/pi-coding-agent/src/index.ts +16 -0
  459. package/packages/pi-coding-agent/src/main.ts +4 -0
  460. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +19 -7
  461. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +53 -31
  462. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +88 -36
  463. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +1 -0
  464. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +1 -0
  465. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +13 -9
  466. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  467. package/packages/pi-tui/package.json +1 -1
  468. package/packages/rpc-client/package.json +1 -1
  469. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +1 -0
  470. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  471. package/pkg/dist/modes/interactive/theme/theme-schema.js +1 -0
  472. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  473. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  474. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  475. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  476. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  477. package/pkg/dist/modes/interactive/theme/themes.js +13 -9
  478. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  479. package/pkg/package.json +1 -1
  480. package/src/resources/agents/researcher.md +1 -1
  481. package/src/resources/extensions/ask-user-questions.ts +7 -4
  482. package/src/resources/extensions/claude-code-cli/readiness.ts +36 -2
  483. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +59 -1
  484. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +66 -0
  485. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -10
  486. package/src/resources/extensions/gsd/auto/phases.ts +52 -6
  487. package/src/resources/extensions/gsd/auto-artifact-paths.ts +20 -0
  488. package/src/resources/extensions/gsd/auto-dashboard.ts +46 -5
  489. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +15 -2
  490. package/src/resources/extensions/gsd/auto-dispatch.ts +96 -4
  491. package/src/resources/extensions/gsd/auto-model-selection.ts +37 -6
  492. package/src/resources/extensions/gsd/auto-post-unit.ts +7 -5
  493. package/src/resources/extensions/gsd/auto-prompts.ts +225 -45
  494. package/src/resources/extensions/gsd/auto-recovery.ts +47 -0
  495. package/src/resources/extensions/gsd/auto-start.ts +8 -6
  496. package/src/resources/extensions/gsd/auto-verification.ts +33 -0
  497. package/src/resources/extensions/gsd/auto-worktree.ts +81 -1
  498. package/src/resources/extensions/gsd/auto.ts +27 -2
  499. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +8 -21
  500. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +46 -24
  501. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +163 -0
  502. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +31 -0
  503. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +15 -0
  504. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +22 -0
  505. package/src/resources/extensions/gsd/bootstrap/system-context.ts +89 -10
  506. package/src/resources/extensions/gsd/commands/catalog.ts +15 -7
  507. package/src/resources/extensions/gsd/commands/handlers/core.ts +63 -27
  508. package/src/resources/extensions/gsd/commands/handlers/escalate.ts +216 -0
  509. package/src/resources/extensions/gsd/commands/handlers/onboarding.ts +196 -0
  510. package/src/resources/extensions/gsd/commands/handlers/ops.ts +10 -0
  511. package/src/resources/extensions/gsd/commands-config.ts +10 -0
  512. package/src/resources/extensions/gsd/commands-extract-learnings.ts +262 -78
  513. package/src/resources/extensions/gsd/commands-memory.ts +551 -0
  514. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +48 -11
  515. package/src/resources/extensions/gsd/custom-workflow-engine.ts +85 -60
  516. package/src/resources/extensions/gsd/db-writer.ts +91 -17
  517. package/src/resources/extensions/gsd/docs/preferences-reference.md +2 -2
  518. package/src/resources/extensions/gsd/doctor-environment.ts +2 -1
  519. package/src/resources/extensions/gsd/doctor-git-checks.ts +51 -30
  520. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -1
  521. package/src/resources/extensions/gsd/doctor-providers.ts +59 -6
  522. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +22 -1
  523. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  524. package/src/resources/extensions/gsd/doctor.ts +7 -1
  525. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +2 -0
  526. package/src/resources/extensions/gsd/error-classifier.ts +5 -2
  527. package/src/resources/extensions/gsd/escalation.ts +367 -0
  528. package/src/resources/extensions/gsd/graph.ts +33 -0
  529. package/src/resources/extensions/gsd/gsd-db.ts +617 -32
  530. package/src/resources/extensions/gsd/health-widget-core.ts +43 -14
  531. package/src/resources/extensions/gsd/health-widget.ts +7 -3
  532. package/src/resources/extensions/gsd/hook-emitter.ts +188 -0
  533. package/src/resources/extensions/gsd/init-wizard.ts +87 -54
  534. package/src/resources/extensions/gsd/markdown-renderer.ts +5 -5
  535. package/src/resources/extensions/gsd/memory-backfill.ts +140 -0
  536. package/src/resources/extensions/gsd/memory-embeddings.ts +235 -0
  537. package/src/resources/extensions/gsd/memory-extractor.ts +100 -34
  538. package/src/resources/extensions/gsd/memory-ingest.ts +286 -0
  539. package/src/resources/extensions/gsd/memory-relations.ts +240 -0
  540. package/src/resources/extensions/gsd/memory-source-store.ts +138 -0
  541. package/src/resources/extensions/gsd/memory-store.ts +377 -7
  542. package/src/resources/extensions/gsd/metrics.ts +1 -0
  543. package/src/resources/extensions/gsd/model-cost-table.ts +1 -0
  544. package/src/resources/extensions/gsd/model-router.ts +21 -5
  545. package/src/resources/extensions/gsd/native-git-bridge.ts +118 -6
  546. package/src/resources/extensions/gsd/notification-overlay.ts +9 -19
  547. package/src/resources/extensions/gsd/notification-widget.ts +25 -43
  548. package/src/resources/extensions/gsd/onboarding-state.ts +146 -0
  549. package/src/resources/extensions/gsd/post-execution-checks.ts +37 -14
  550. package/src/resources/extensions/gsd/pre-execution-checks.ts +100 -12
  551. package/src/resources/extensions/gsd/preferences-models.ts +1 -0
  552. package/src/resources/extensions/gsd/preferences-types.ts +9 -1
  553. package/src/resources/extensions/gsd/preferences-validation.ts +33 -7
  554. package/src/resources/extensions/gsd/prompts/add-tests.md +1 -0
  555. package/src/resources/extensions/gsd/prompts/complete-milestone.md +4 -1
  556. package/src/resources/extensions/gsd/prompts/complete-slice.md +2 -2
  557. package/src/resources/extensions/gsd/prompts/debug-diagnose.md +2 -0
  558. package/src/resources/extensions/gsd/prompts/execute-task.md +16 -3
  559. package/src/resources/extensions/gsd/prompts/plan-milestone.md +12 -0
  560. package/src/resources/extensions/gsd/prompts/plan-slice.md +2 -0
  561. package/src/resources/extensions/gsd/prompts/refine-slice.md +69 -0
  562. package/src/resources/extensions/gsd/prompts/research-slice.md +1 -0
  563. package/src/resources/extensions/gsd/python-resolver.ts +76 -0
  564. package/src/resources/extensions/gsd/setup-catalog.ts +105 -0
  565. package/src/resources/extensions/gsd/state.ts +95 -6
  566. package/src/resources/extensions/gsd/templates/PREFERENCES.md +1 -1
  567. package/src/resources/extensions/gsd/tests/artifact-corruption-2630.test.ts +7 -0
  568. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +49 -0
  569. package/src/resources/extensions/gsd/tests/auto-migrating-recovery.test.ts +63 -0
  570. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +95 -1
  571. package/src/resources/extensions/gsd/tests/auto-prompts-fallback.test.ts +35 -0
  572. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +123 -1
  573. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +39 -0
  574. package/src/resources/extensions/gsd/tests/bundled-skill-triggers.test.ts +54 -0
  575. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +335 -21
  576. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +6 -8
  577. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  578. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +63 -0
  579. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +42 -0
  580. package/src/resources/extensions/gsd/tests/derive-state-helpers.test.ts +8 -4
  581. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +117 -3
  582. package/src/resources/extensions/gsd/tests/enhanced-verification-integration.test.ts +5 -0
  583. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +306 -1
  584. package/src/resources/extensions/gsd/tests/escalation.test.ts +818 -0
  585. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +145 -8
  586. package/src/resources/extensions/gsd/tests/freeform-decisions.test.ts +62 -0
  587. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -1
  588. package/src/resources/extensions/gsd/tests/health-widget.test.ts +8 -2
  589. package/src/resources/extensions/gsd/tests/init-prefs-routing.test.ts +190 -0
  590. package/src/resources/extensions/gsd/tests/integration/doctor-git-symlink-cwd.test.ts +90 -0
  591. package/src/resources/extensions/gsd/tests/integration/doctor-git.test.ts +117 -0
  592. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +44 -0
  593. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +32 -1
  594. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +72 -5
  595. package/src/resources/extensions/gsd/tests/integration/integration-proof.test.ts +2 -2
  596. package/src/resources/extensions/gsd/tests/integration/test-isolation.ts +53 -0
  597. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +1 -1
  598. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +35 -0
  599. package/src/resources/extensions/gsd/tests/load-memory-block.test.ts +36 -0
  600. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  601. package/src/resources/extensions/gsd/tests/memory-embeddings.test.ts +213 -0
  602. package/src/resources/extensions/gsd/tests/memory-ingest.test.ts +153 -0
  603. package/src/resources/extensions/gsd/tests/memory-maintenance.test.ts +107 -0
  604. package/src/resources/extensions/gsd/tests/memory-relations.test.ts +175 -0
  605. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  606. package/src/resources/extensions/gsd/tests/memory-tools.test.ts +295 -0
  607. package/src/resources/extensions/gsd/tests/milestone-status-tool.test.ts +3 -2
  608. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +2 -2
  609. package/src/resources/extensions/gsd/tests/model-router.test.ts +51 -1
  610. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +59 -0
  611. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +56 -37
  612. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +1 -1
  613. package/src/resources/extensions/gsd/tests/onboarding-state.test.ts +105 -0
  614. package/src/resources/extensions/gsd/tests/plan-milestone-boundary-map-preservation.test.ts +114 -0
  615. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +4 -5
  616. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +17 -0
  617. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +105 -1
  618. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +317 -1
  619. package/src/resources/extensions/gsd/tests/progressive-planning.test.ts +539 -0
  620. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +11 -2
  621. package/src/resources/extensions/gsd/tests/projection-regression.test.ts +7 -0
  622. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +159 -8
  623. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +24 -0
  624. package/src/resources/extensions/gsd/tests/prompts-no-gitignored-test-refs.test.ts +56 -0
  625. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +41 -4
  626. package/src/resources/extensions/gsd/tests/python-resolver.test.ts +131 -0
  627. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +67 -0
  628. package/src/resources/extensions/gsd/tests/requirements.test.ts +9 -0
  629. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +153 -0
  630. package/src/resources/extensions/gsd/tests/skip-slice-cascades-tasks.test.ts +125 -0
  631. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +16 -4
  632. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +54 -0
  633. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +3 -0
  634. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +5 -0
  635. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +2 -1
  636. package/src/resources/extensions/gsd/tests/uok-flags.test.ts +1 -1
  637. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +9 -3
  638. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +35 -0
  639. package/src/resources/extensions/gsd/tests/workflow-projections.test.ts +7 -0
  640. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +97 -0
  641. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +2 -1
  642. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +77 -2
  643. package/src/resources/extensions/gsd/tools/complete-task.ts +87 -0
  644. package/src/resources/extensions/gsd/tools/memory-tools.ts +410 -0
  645. package/src/resources/extensions/gsd/tools/plan-milestone.ts +42 -8
  646. package/src/resources/extensions/gsd/tools/plan-slice.ts +6 -1
  647. package/src/resources/extensions/gsd/tools/skip-slice.ts +133 -0
  648. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +14 -0
  649. package/src/resources/extensions/gsd/types.ts +62 -0
  650. package/src/resources/extensions/gsd/uok/contracts.ts +2 -1
  651. package/src/resources/extensions/gsd/uok/flags.ts +1 -1
  652. package/src/resources/extensions/gsd/verification-gate.ts +2 -1
  653. package/src/resources/extensions/gsd/workflow-logger.ts +4 -1
  654. package/src/resources/extensions/gsd/workflow-manifest.ts +8 -0
  655. package/src/resources/extensions/gsd/workflow-mcp.ts +1 -0
  656. package/src/resources/extensions/gsd/workflow-projections.ts +18 -16
  657. package/src/resources/extensions/gsd/workflow-templates/spike.md +6 -0
  658. package/src/resources/extensions/gsd/worktree-resolver.ts +47 -1
  659. package/src/resources/extensions/remote-questions/manager.ts +13 -1
  660. package/src/resources/extensions/remote-questions/tests/remote-answer-normalization.test.ts +92 -0
  661. package/src/resources/extensions/search-the-web/command-search-provider.ts +4 -1
  662. package/src/resources/extensions/search-the-web/native-search.ts +13 -3
  663. package/src/resources/skills/api-design/SKILL.md +190 -0
  664. package/src/resources/skills/create-mcp-server/SKILL.md +121 -0
  665. package/src/resources/skills/decompose-into-slices/SKILL.md +139 -0
  666. package/src/resources/skills/dependency-upgrade/SKILL.md +158 -0
  667. package/src/resources/skills/design-an-interface/SKILL.md +102 -0
  668. package/src/resources/skills/forensics/SKILL.md +153 -0
  669. package/src/resources/skills/grill-me/SKILL.md +93 -0
  670. package/src/resources/skills/handoff/SKILL.md +121 -0
  671. package/src/resources/skills/observability/SKILL.md +174 -0
  672. package/src/resources/skills/security-review/SKILL.md +181 -0
  673. package/src/resources/skills/spike-wrap-up/SKILL.md +138 -0
  674. package/src/resources/skills/tdd/SKILL.md +112 -0
  675. package/src/resources/skills/verify-before-complete/SKILL.md +97 -0
  676. package/src/resources/skills/write-docs/SKILL.md +81 -0
  677. package/src/resources/skills/write-milestone-brief/SKILL.md +135 -0
  678. package/dist/web/standalone/.next/static/css/3e9cdadb4d23b8a4.css +0 -1
  679. /package/dist/web/standalone/.next/static/{JncJywFxCugMuXGs56m-b → pBwmOoye64ZrRp-_rf0v1}/_buildManifest.js +0 -0
  680. /package/dist/web/standalone/.next/static/{JncJywFxCugMuXGs56m-b → pBwmOoye64ZrRp-_rf0v1}/_ssgManifest.js +0 -0
@@ -15,6 +15,8 @@ import { dirname, join } from 'node:path';
15
15
  import { renderLogo } from './logo.js';
16
16
  import { agentDir } from './app-paths.js';
17
17
  import { isClaudeCliReady } from './claude-cli-check.js';
18
+ import { markOnboardingComplete, markStepCompleted, markStepSkipped, isOnboardingComplete, } from './resources/extensions/gsd/onboarding-state.js';
19
+ import { getLlmProviderIds } from './resources/extensions/gsd/setup-catalog.js';
18
20
  // ─── Constants ────────────────────────────────────────────────────────────────
19
21
  const TOOL_KEYS = [
20
22
  {
@@ -36,25 +38,17 @@ const TOOL_KEYS = [
36
38
  hint: 'voice transcription — free at console.groq.com',
37
39
  },
38
40
  ];
39
- /** Known LLM provider IDs that, if authed, mean the user doesn't need onboarding */
40
- const LLM_PROVIDER_IDS = [
41
- 'anthropic',
41
+ /**
42
+ * Known LLM provider IDs that, if authed, mean the user doesn't need onboarding.
43
+ * Sourced from the shared setup-catalog so adding a provider lands in one place.
44
+ * 'anthropic-vertex' and 'ollama' aren't in PROVIDER_REGISTRY but are still
45
+ * treated as "authed = no onboarding needed" for back-compat.
46
+ */
47
+ const LLM_PROVIDER_IDS = Array.from(new Set([
48
+ ...getLlmProviderIds(),
42
49
  'anthropic-vertex',
43
- 'claude-code',
44
- 'openai',
45
- 'github-copilot',
46
- 'openai-codex',
47
- 'google-gemini-cli',
48
- 'google-antigravity',
49
- 'google',
50
- 'groq',
51
- 'xai',
52
- 'openrouter',
53
- 'mistral',
54
50
  'ollama',
55
- 'ollama-cloud',
56
- 'custom-openai',
57
- ];
51
+ ]));
58
52
  /** API key prefix validation — loose checks to catch obvious mistakes */
59
53
  const API_KEY_PREFIXES = {
60
54
  anthropic: ['sk-ant-'],
@@ -178,6 +172,10 @@ async function runStep(p, warnLabel, fn, opts = {}) {
178
172
  export function shouldRunOnboarding(authStorage, settingsDefaultProvider) {
179
173
  if (!process.stdin.isTTY)
180
174
  return false;
175
+ // Explicit completion record wins — user has already finished onboarding (and
176
+ // our flowVersion hasn't bumped since).
177
+ if (isOnboardingComplete())
178
+ return false;
181
179
  if (settingsDefaultProvider)
182
180
  return false;
183
181
  // Check if any LLM provider has credentials
@@ -196,7 +194,7 @@ export function shouldRunOnboarding(authStorage, settingsDefaultProvider) {
196
194
  * All steps are skippable. All errors are recoverable.
197
195
  * Writes status to stderr during execution.
198
196
  */
199
- export async function runOnboarding(authStorage) {
197
+ export async function runOnboarding(authStorage, opts = {}) {
200
198
  let p;
201
199
  let pc;
202
200
  try {
@@ -209,31 +207,62 @@ export async function runOnboarding(authStorage) {
209
207
  return;
210
208
  }
211
209
  // ── Intro ─────────────────────────────────────────────────────────────────
212
- process.stderr.write(renderLogo(pc.cyan));
213
- p.intro(pc.bold('Welcome to GSD — let\'s get you set up'));
210
+ if (opts.showIntro !== false) {
211
+ process.stderr.write(renderLogo(pc.cyan));
212
+ p.intro(pc.bold('Welcome to GSD — let\'s get you set up'));
213
+ }
214
+ const completedSteps = [];
214
215
  // ── LLM Provider Selection ────────────────────────────────────────────────
215
216
  const llmResult = await runStep(p, 'LLM setup failed', () => runLlmStep(p, pc, authStorage), {
216
- cancelMessage: 'Setup cancelled — you can run /login inside GSD later.',
217
+ cancelMessage: 'Setup cancelled — you can run /gsd onboarding --resume later.',
217
218
  errorInfo: 'You can configure your LLM provider later with /login inside GSD.',
218
219
  });
219
220
  if (llmResult === STEP_CANCELLED)
220
221
  return;
221
222
  const llmConfigured = llmResult ?? false;
223
+ if (llmConfigured) {
224
+ markStepCompleted('llm');
225
+ completedSteps.push('llm');
226
+ }
227
+ else {
228
+ markStepSkipped('llm');
229
+ }
222
230
  // ── Web Search Provider ──────────────────────────────────────────────────
223
231
  const searchResult = await runStep(p, 'Web search setup failed', () => runWebSearchStep(p, pc, authStorage, llmConfigured));
224
232
  if (searchResult === STEP_CANCELLED)
225
233
  return;
226
234
  const searchConfigured = searchResult;
235
+ if (searchConfigured) {
236
+ markStepCompleted('search');
237
+ completedSteps.push('search');
238
+ }
239
+ else {
240
+ markStepSkipped('search');
241
+ }
227
242
  // ── Remote Questions ─────────────────────────────────────────────────────
228
243
  const remoteResult = await runStep(p, 'Remote questions setup failed', () => runRemoteQuestionsStep(p, pc, authStorage));
229
244
  if (remoteResult === STEP_CANCELLED)
230
245
  return;
231
246
  const remoteConfigured = remoteResult;
247
+ if (remoteConfigured) {
248
+ markStepCompleted('remote');
249
+ completedSteps.push('remote');
250
+ }
251
+ else {
252
+ markStepSkipped('remote');
253
+ }
232
254
  // ── Tool API Keys ─────────────────────────────────────────────────────────
233
255
  const toolResult = await runStep(p, 'Tool key setup failed', () => runToolKeysStep(p, pc, authStorage));
234
256
  if (toolResult === STEP_CANCELLED)
235
257
  return;
236
258
  const toolKeyCount = toolResult ?? 0;
259
+ if (toolKeyCount > 0) {
260
+ markStepCompleted('tool-keys');
261
+ completedSteps.push('tool-keys');
262
+ }
263
+ else {
264
+ markStepSkipped('tool-keys');
265
+ }
237
266
  // ── Summary ───────────────────────────────────────────────────────────────
238
267
  const summaryLines = [];
239
268
  if (llmConfigured) {
@@ -268,11 +297,17 @@ export async function runOnboarding(authStorage) {
268
297
  else {
269
298
  summaryLines.push(`${pc.dim('↷')} Tool keys: none configured`);
270
299
  }
300
+ // Persist completion record so re-entry, web boot probe, and shouldRunOnboarding
301
+ // all agree the wizard finished. Required steps drive the "complete" semantics
302
+ // in onboarding-state.ts; here we mark wizard-level completion regardless.
303
+ markOnboardingComplete(completedSteps);
304
+ summaryLines.push('');
305
+ summaryLines.push(`${pc.dim('Tip:')} re-run anytime with ${pc.cyan('/gsd onboarding')}`);
271
306
  p.note(summaryLines.join('\n'), 'Setup complete');
272
307
  p.outro(pc.dim('Launching GSD...'));
273
308
  }
274
309
  // ─── LLM Authentication Step ──────────────────────────────────────────────────
275
- async function runLlmStep(p, pc, authStorage) {
310
+ export async function runLlmStep(p, pc, authStorage) {
276
311
  // Build the OAuth provider list dynamically from what's registered
277
312
  const oauthProviders = authStorage.getOAuthProviders();
278
313
  const oauthMap = new Map(oauthProviders.map(op => [op.id, op]));
@@ -572,7 +607,7 @@ async function runCustomOpenAIFlow(p, pc, authStorage) {
572
607
  return true;
573
608
  }
574
609
  // ─── Web Search Provider Step ─────────────────────────────────────────────────
575
- async function runWebSearchStep(p, pc, authStorage, isAnthropicAuth) {
610
+ export async function runWebSearchStep(p, pc, authStorage, isAnthropicAuth) {
576
611
  // Check which LLM provider was configured
577
612
  const authed = authStorage.list().filter(id => LLM_PROVIDER_IDS.includes(id));
578
613
  const isAnthropic = isAnthropicAuth && authed.includes('anthropic');
@@ -633,7 +668,7 @@ async function runWebSearchStep(p, pc, authStorage, isAnthropicAuth) {
633
668
  return null;
634
669
  }
635
670
  // ─── Tool API Keys Step ───────────────────────────────────────────────────────
636
- async function runToolKeysStep(p, pc, authStorage) {
671
+ export async function runToolKeysStep(p, pc, authStorage) {
637
672
  // Filter to keys not already configured
638
673
  const missing = TOOL_KEYS.filter(tk => !authStorage.has(tk.provider) && !process.env[tk.envVar]);
639
674
  if (missing.length === 0)
@@ -668,7 +703,7 @@ async function runToolKeysStep(p, pc, authStorage) {
668
703
  return savedCount;
669
704
  }
670
705
  // ─── Remote Questions Step ────────────────────────────────────────────────────
671
- async function runRemoteQuestionsStep(p, pc, authStorage) {
706
+ export async function runRemoteQuestionsStep(p, pc, authStorage) {
672
707
  // Check existing config — use getCredentialsForProvider to skip empty-key entries
673
708
  const hasValidKey = (provider) => authStorage
674
709
  .getCredentialsForProvider(provider)
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  name: researcher
3
3
  description: Web researcher that finds and synthesizes current information using Brave Search
4
- tools: search-the-web, bash
4
+ tools: search-the-web, bash, capture_thought, memory_query, gsd_graph
5
5
  ---
6
6
 
7
7
  You are a web researcher. You find current, accurate information using web search and synthesize it into a clear, well-structured report.
@@ -316,10 +316,13 @@ export default function AskUserQuestions(pi) {
316
316
  lines.push(`${theme.fg("accent", q.header)}: ${theme.fg("dim", "(no answer)")}`);
317
317
  continue;
318
318
  }
319
- const answerText = answer.answers.length > 0 ? answer.answers.join(", ") : "(custom)";
319
+ const selected = answer.selected;
320
+ const answerText = Array.isArray(selected)
321
+ ? (selected.length > 0 ? selected.join(", ") : "(custom)")
322
+ : (selected || "(custom)");
320
323
  let line = `${theme.fg("success", "✓ ")}${theme.fg("accent", q.header)}: ${answerText}`;
321
- if (answer.user_note) {
322
- line += ` ${theme.fg("muted", `[note: ${answer.user_note}]`)}`;
324
+ if (answer.notes) {
325
+ line += ` ${theme.fg("muted", `[note: ${answer.notes}]`)}`;
323
326
  }
324
327
  lines.push(line);
325
328
  }
@@ -9,6 +9,38 @@
9
9
  * and check the exit code + output for an authenticated session.
10
10
  */
11
11
  import { execFileSync } from "node:child_process";
12
+ /**
13
+ * Candidate executable names for the Claude Code CLI.
14
+ *
15
+ * Keep the explicit win32 ternary selector for regression coverage (Issue #4424):
16
+ * Node's execFileSync must target `claude.cmd` directly on Windows.
17
+ */
18
+ const CLAUDE_COMMAND = process.platform === "win32" ? "claude.cmd" : "claude";
19
+ /**
20
+ * Windows installs vary: some environments expose `claude.cmd` (npm shim),
21
+ * others expose a `claude` shim on PATH (for example Git Bash wrappers).
22
+ * Try both to avoid false "not installed" results in readiness checks.
23
+ */
24
+ const CLAUDE_COMMAND_CANDIDATES = process.platform === "win32" ? [CLAUDE_COMMAND, "claude"] : [CLAUDE_COMMAND];
25
+ function execClaude(args) {
26
+ let lastError;
27
+ for (const command of CLAUDE_COMMAND_CANDIDATES) {
28
+ try {
29
+ return execFileSync(command, args, { timeout: 5_000, stdio: "pipe" });
30
+ }
31
+ catch (error) {
32
+ lastError = error;
33
+ const code = error?.code;
34
+ // Windows Git Bash can surface `.cmd` spawn failures as EINVAL instead
35
+ // of ENOENT. Treat both as "try next candidate".
36
+ if (code === "ENOENT" || code === "EINVAL") {
37
+ continue;
38
+ }
39
+ throw error;
40
+ }
41
+ }
42
+ throw lastError ?? new Error(`Claude CLI executable not found (tried: ${CLAUDE_COMMAND_CANDIDATES.join(", ")})`);
43
+ }
12
44
  let cachedBinaryPresent = null;
13
45
  let cachedAuthed = null;
14
46
  let lastCheckMs = 0;
@@ -22,7 +54,7 @@ function refreshCache() {
22
54
  lastCheckMs = now;
23
55
  // Check binary presence
24
56
  try {
25
- execFileSync("claude", ["--version"], { timeout: 5_000, stdio: "pipe" });
57
+ execClaude(["--version"]);
26
58
  cachedBinaryPresent = true;
27
59
  }
28
60
  catch {
@@ -32,7 +64,7 @@ function refreshCache() {
32
64
  }
33
65
  // Check auth status — exit code 0 with non-error output means authenticated
34
66
  try {
35
- const output = execFileSync("claude", ["auth", "status"], { timeout: 5_000, stdio: "pipe" })
67
+ const output = execClaude(["auth", "status"])
36
68
  .toString()
37
69
  .toLowerCase();
38
70
  // The CLI outputs "not logged in", "no credentials", or similar when unauthenticated
@@ -11,7 +11,9 @@ import { execSync } from "node:child_process";
11
11
  import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
12
12
  import { buildWorkflowMcpServers } from "../gsd/workflow-mcp.js";
13
13
  import { showInterviewRound } from "../shared/tui.js";
14
+ /** Label used for the free-text fallback option in single-choice elicitation questions. */
14
15
  const OTHER_OPTION_LABEL = "None of the above";
16
+ /** Regex pattern that identifies field names and descriptions that should be treated as sensitive/secure inputs. */
15
17
  const SENSITIVE_FIELD_PATTERN = /(password|passphrase|secret|token|api[_\s-]*key|private[_\s-]*key|credential)/i;
16
18
  // ---------------------------------------------------------------------------
17
19
  // Stream factory
@@ -29,6 +31,7 @@ function createAssistantStream() {
29
31
  throw new Error("Unexpected event type for final result");
30
32
  });
31
33
  }
34
+ /** Extract a human-readable error string from an SDK result message. */
32
35
  export function getResultErrorMessage(result) {
33
36
  if ("errors" in result && Array.isArray(result.errors) && result.errors.length > 0) {
34
37
  return result.errors.join("; ");
@@ -41,10 +44,13 @@ export function getResultErrorMessage(result) {
41
44
  // ---------------------------------------------------------------------------
42
45
  // Claude binary resolution
43
46
  // ---------------------------------------------------------------------------
47
+ /** Cached result of the `which`/`where claude` lookup so the shell is only spawned once per process. */
44
48
  let cachedClaudePath = null;
49
+ /** Return the shell command used to locate the `claude` binary on the given platform. */
45
50
  export function getClaudeLookupCommand(platform = process.platform) {
46
51
  return platform === "win32" ? "where claude" : "which claude";
47
52
  }
53
+ /** Extract the first line of `which`/`where` output as the resolved binary path. */
48
54
  export function parseClaudeLookupOutput(output) {
49
55
  return output
50
56
  .toString()
@@ -123,6 +129,7 @@ export function buildPromptFromContext(context) {
123
129
  }
124
130
  return parts.join("\n\n");
125
131
  }
132
+ /** Strip the `data:<mime>;base64,` prefix from a data URI, returning only the raw base64 payload. */
126
133
  function stripDataUriPrefix(value) {
127
134
  const commaIndex = value.indexOf(",");
128
135
  if (value.startsWith("data:") && commaIndex !== -1) {
@@ -130,10 +137,12 @@ function stripDataUriPrefix(value) {
130
137
  }
131
138
  return value;
132
139
  }
140
+ /** Extract the MIME type from a data URI string, or return `null` if the value is not a valid data URI. */
133
141
  function inferMimeTypeFromDataUri(value) {
134
142
  const match = /^data:([^;,]+);base64,/.exec(value);
135
143
  return match?.[1] ?? null;
136
144
  }
145
+ /** Collect all base64 image blocks from user messages in the context for inclusion in the SDK prompt. */
137
146
  export function extractImageBlocksFromContext(context) {
138
147
  const imageBlocks = [];
139
148
  for (const msg of context.messages) {
@@ -162,6 +171,7 @@ export function extractImageBlocksFromContext(context) {
162
171
  }
163
172
  return imageBlocks;
164
173
  }
174
+ /** Build the SDK query prompt, wrapping image blocks into an async iterable user message when present. */
165
175
  export function buildSdkQueryPrompt(context, textPrompt = buildPromptFromContext(context)) {
166
176
  const imageBlocks = extractImageBlocksFromContext(context);
167
177
  if (imageBlocks.length === 0) {
@@ -183,6 +193,7 @@ export function buildSdkQueryPrompt(context, textPrompt = buildPromptFromContext
183
193
  // ---------------------------------------------------------------------------
184
194
  // Error helper
185
195
  // ---------------------------------------------------------------------------
196
+ /** Build a minimal error `AssistantMessage` with the given model ID and error text. */
186
197
  function makeErrorMessage(model, errorMsg) {
187
198
  return {
188
199
  role: "assistant",
@@ -209,6 +220,7 @@ export function makeStreamExhaustedErrorMessage(model, lastTextContent) {
209
220
  }
210
221
  return message;
211
222
  }
223
+ /** Extract the string labels from an array of SDK elicitation option objects, filtering out blank entries. */
212
224
  function readElicitationChoices(options) {
213
225
  if (!Array.isArray(options))
214
226
  return [];
@@ -216,6 +228,7 @@ function readElicitationChoices(options) {
216
228
  .map((option) => (typeof option?.const === "string" ? option.const : typeof option?.title === "string" ? option.title : ""))
217
229
  .filter((option) => option.length > 0);
218
230
  }
231
+ /** Parse an SDK elicitation request into structured multiple-choice questions, or null if the schema is unsupported. */
219
232
  export function parseAskUserQuestionsElicitation(request) {
220
233
  if (request.mode && request.mode !== "form")
221
234
  return null;
@@ -265,6 +278,7 @@ export function parseAskUserQuestionsElicitation(request) {
265
278
  }
266
279
  return questions.length > 0 ? questions : null;
267
280
  }
281
+ /** Return true if the elicitation field should be treated as sensitive and rendered as a secure/password input. */
268
282
  function isSecureElicitationField(requestMessage, fieldId, field) {
269
283
  if (field.format === "password")
270
284
  return true;
@@ -283,6 +297,7 @@ function isSecureElicitationField(requestMessage, fieldId, field) {
283
297
  .toLowerCase();
284
298
  return SENSITIVE_FIELD_PATTERN.test(haystack);
285
299
  }
300
+ /** Parse an SDK elicitation request into free-text input field descriptors, or null if unsupported. */
286
301
  export function parseTextInputElicitation(request) {
287
302
  if (request.mode && request.mode !== "form")
288
303
  return null;
@@ -315,6 +330,7 @@ export function parseTextInputElicitation(request) {
315
330
  }
316
331
  return fields.length > 0 ? fields : null;
317
332
  }
333
+ /** Convert a TUI interview round result into the SDK elicitation content map. */
318
334
  export function roundResultToElicitationContent(questions, result) {
319
335
  const content = {};
320
336
  for (const question of questions) {
@@ -334,6 +350,7 @@ export function roundResultToElicitationContent(questions, result) {
334
350
  }
335
351
  return content;
336
352
  }
353
+ /** Build the dialog title string for a multiple-choice elicitation question, combining server name, header, and question text. */
337
354
  function buildElicitationPromptTitle(request, question) {
338
355
  const parts = [
339
356
  request.serverName ? `[${request.serverName}]` : "",
@@ -342,6 +359,7 @@ function buildElicitationPromptTitle(request, question) {
342
359
  ].filter((part) => part && part.trim().length > 0);
343
360
  return parts.join("\n\n");
344
361
  }
362
+ /** Drive each multiple-choice elicitation question through the extension UI's `select` dialog, collecting answers into an SDK result. */
345
363
  async function promptElicitationWithDialogs(request, questions, ui, signal) {
346
364
  const content = {};
347
365
  for (const question of questions) {
@@ -379,6 +397,7 @@ async function promptElicitationWithDialogs(request, questions, ui, signal) {
379
397
  }
380
398
  return { action: "accept", content };
381
399
  }
400
+ /** Build the dialog title string for a free-text input field, combining server name, field title, and description. */
382
401
  function buildTextInputPromptTitle(request, field) {
383
402
  const parts = [
384
403
  request.serverName ? `[${request.serverName}]` : "",
@@ -387,6 +406,7 @@ function buildTextInputPromptTitle(request, field) {
387
406
  ].filter((part) => typeof part === "string" && part.trim().length > 0);
388
407
  return parts.join("\n\n");
389
408
  }
409
+ /** Derive a placeholder hint for a free-text input field from its description, falling back to "Required" or "Leave empty to skip". */
390
410
  function buildTextInputPlaceholder(field) {
391
411
  const desc = field.description.trim();
392
412
  if (!desc)
@@ -400,6 +420,7 @@ function buildTextInputPlaceholder(field) {
400
420
  const hint = formatLine.replace(/^format:\s*/i, "").trim();
401
421
  return hint.length > 0 ? hint : field.required ? "Required" : "Leave empty to skip";
402
422
  }
423
+ /** Collect each free-text input field via the extension UI's `input` dialog, returning the filled SDK elicitation result. */
403
424
  async function promptTextInputElicitation(request, fields, ui, signal) {
404
425
  const content = {};
405
426
  for (const field of fields) {
@@ -411,6 +432,7 @@ async function promptTextInputElicitation(request, fields, ui, signal) {
411
432
  }
412
433
  return { action: "accept", content };
413
434
  }
435
+ /** Create an SDK elicitation handler that routes requests through the extension UI dialogs, or undefined if no UI is available. */
414
436
  export function createClaudeCodeElicitationHandler(ui) {
415
437
  if (!ui)
416
438
  return undefined;
@@ -485,14 +507,20 @@ export async function resolveClaudePermissionMode(env = process.env) {
485
507
  // NOTE: These helpers intentionally mirror @gsd/pi-ai anthropic-shared
486
508
  // behavior so this extension remains typecheck-stable even when the published
487
509
  // @gsd/pi-ai barrel lags behind monorepo source exports.
510
+ /** Return true for model IDs that support the adaptive thinking API (Opus 4.6/4.7, Sonnet 4.6/4.7, Haiku 4.5). */
488
511
  function modelSupportsAdaptiveThinking(modelId) {
489
512
  return (modelId.includes("opus-4-6")
490
513
  || modelId.includes("opus-4.6")
491
514
  || modelId.includes("opus-4-7")
492
515
  || modelId.includes("opus-4.7")
493
516
  || modelId.includes("sonnet-4-6")
494
- || modelId.includes("sonnet-4.6"));
517
+ || modelId.includes("sonnet-4.6")
518
+ || modelId.includes("sonnet-4-7")
519
+ || modelId.includes("sonnet-4.7")
520
+ || modelId.includes("haiku-4-5")
521
+ || modelId.includes("haiku-4.5"));
495
522
  }
523
+ /** Map a GSD thinking level to the Anthropic effort value, clamping xhigh to max for models that lack native xhigh support. */
496
524
  function mapThinkingLevelToAnthropicEffort(level, modelId) {
497
525
  switch (level) {
498
526
  case "minimal":
@@ -543,9 +571,18 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
543
571
  "Bash(pwd)",
544
572
  ...(mcpServers ? Object.keys(mcpServers).map((serverName) => `mcp__${serverName}__*`) : []),
545
573
  ];
546
- const effort = reasoning && modelSupportsAdaptiveThinking(modelId)
574
+ const supportsAdaptive = modelSupportsAdaptiveThinking(modelId);
575
+ const effort = reasoning && supportsAdaptive
547
576
  ? mapThinkingLevelToAnthropicEffort(reasoning, modelId)
548
577
  : undefined;
578
+ // Bug B: SDK requires thinking:{type:"adaptive"} alongside effort for adaptive thinking to activate.
579
+ // Bug C: SDK requires thinking:{type:"disabled"} to actually stop adaptive thinking when reasoning is off;
580
+ // omitting the field leaves the SDK in its adaptive default (or persisted session state).
581
+ const thinkingConfig = supportsAdaptive
582
+ ? effort
583
+ ? { thinking: { type: "adaptive" } }
584
+ : { thinking: { type: "disabled" } }
585
+ : undefined;
549
586
  return {
550
587
  pathToClaudeCodeExecutable: getClaudePath(),
551
588
  model: modelId,
@@ -560,10 +597,12 @@ export function buildSdkOptions(modelId, prompt, overrides, extraOptions = {}) {
560
597
  ...(allowedTools.length > 0 ? { allowedTools } : {}),
561
598
  ...(mcpServers ? { mcpServers } : {}),
562
599
  betas: (modelId.includes("sonnet") || modelId.includes("opus-4-7") || modelId.includes("opus-4.7")) ? ["context-1m-2025-08-07"] : [],
600
+ ...(thinkingConfig ?? {}),
563
601
  ...(effort ? { effort } : {}),
564
602
  ...sdkExtraOptions,
565
603
  };
566
604
  }
605
+ /** Normalise heterogeneous SDK tool-result content (string, array, or object) into a uniform `ExternalToolResultContentBlock[]`. */
567
606
  function normalizeToolResultContent(content) {
568
607
  if (typeof content === "string") {
569
608
  return [{ type: "text", text: content }];
@@ -598,6 +637,7 @@ function normalizeToolResultContent(content) {
598
637
  }
599
638
  return blocks.length > 0 ? blocks : [{ type: "text", text: "" }];
600
639
  }
640
+ /** Extract tool result payloads from an SDK synthetic user message, keyed by tool-use ID. */
601
641
  export function extractToolResultsFromSdkUserMessage(message) {
602
642
  const extracted = [];
603
643
  const seen = new Set();
@@ -642,6 +682,7 @@ export function extractToolResultsFromSdkUserMessage(message) {
642
682
  }
643
683
  return extracted;
644
684
  }
685
+ /** Attach external tool results from the SDK synthetic user message to their corresponding tool-call blocks by ID. */
645
686
  function attachExternalResultsToToolBlocks(toolBlocks, toolResultsById) {
646
687
  for (const block of toolBlocks) {
647
688
  if (block.type !== "toolCall" && block.type !== "serverToolUse")
@@ -689,6 +730,7 @@ export function streamViaClaudeCode(model, context, options) {
689
730
  void pumpSdkMessages(model, context, options, stream);
690
731
  return stream;
691
732
  }
733
+ /** Async pump that drives the Claude Agent SDK's async-iterable message stream and pushes events into `stream`. */
692
734
  async function pumpSdkMessages(model, context, options, stream) {
693
735
  const modelId = model.id;
694
736
  let builder = null;
@@ -607,6 +607,8 @@ export async function runDispatch(ic, preData, loopState) {
607
607
  prefs,
608
608
  session: s,
609
609
  structuredQuestionsAvailable,
610
+ sessionContextWindow: ctx.model?.contextWindow,
611
+ modelRegistry: ctx.modelRegistry,
610
612
  });
611
613
  if (dispatchResult.action === "stop") {
612
614
  deps.emitJournalEvent({ ts: new Date().toISOString(), flowId: ic.flowId, seq: ic.nextSeq(), eventType: "dispatch-stop", rule: dispatchResult.matchedRule, data: { reason: dispatchResult.reason } });
@@ -821,16 +823,44 @@ export async function runGuards(ic, mid) {
821
823
  if (threshold) {
822
824
  s.lastBudgetAlertLevel =
823
825
  newBudgetAlertLevel;
824
- if (threshold.pct === 100 && budgetEnforcementAction !== "none") {
826
+ // Emit Layer 2 budget_threshold event (post-plan hook recommendation).
827
+ // Extensions / Layer 0 shell hooks may return an action override.
828
+ let hookAction;
829
+ try {
830
+ const { emitBudgetThreshold } = await import("../hook-emitter.js");
831
+ const hookResult = await emitBudgetThreshold({
832
+ fraction: budgetPct,
833
+ spent: totalCost,
834
+ limit: budgetCeiling,
835
+ });
836
+ if (hookResult?.action)
837
+ hookAction = hookResult.action;
838
+ }
839
+ catch (hookErr) {
840
+ logWarning("engine", `budget_threshold hook emission failed: ${hookErr.message}`);
841
+ }
842
+ // Apply hook override to enforcement action. "continue" → "none" (no enforcement),
843
+ // "pause" and "downgrade" map to the matching enforcement path below.
844
+ let effectiveAction = budgetEnforcementAction;
845
+ if (hookAction === "continue") {
846
+ effectiveAction = "none";
847
+ }
848
+ else if (hookAction === "pause") {
849
+ effectiveAction = "pause";
850
+ }
851
+ else if (hookAction === "downgrade") {
852
+ effectiveAction = "warn";
853
+ }
854
+ if (threshold.pct === 100 && effectiveAction !== "none") {
825
855
  // 100% — special enforcement logic (halt/pause/warn)
826
856
  const msg = `Budget ceiling ${deps.formatCost(budgetCeiling)} reached (spent ${deps.formatCost(totalCost)}).`;
827
- if (budgetEnforcementAction === "halt") {
857
+ if (effectiveAction === "halt") {
828
858
  deps.sendDesktopNotification("GSD", msg, "error", "budget", basename(s.originalBasePath || s.basePath));
829
859
  await deps.stopAuto(ctx, pi, "Budget ceiling reached");
830
860
  debugLog("autoLoop", { phase: "exit", reason: "budget-halt" });
831
861
  return { action: "break", reason: "budget-halt" };
832
862
  }
833
- if (budgetEnforcementAction === "pause") {
863
+ if (effectiveAction === "pause") {
834
864
  ctx.ui.notify(`${msg} Pausing auto-mode — /gsd auto to override and continue.`, "warning");
835
865
  deps.sendDesktopNotification("GSD", msg, "warning", "budget", basename(s.originalBasePath || s.basePath));
836
866
  deps.logCmuxEvent(prefs, msg, "warning");
@@ -1171,20 +1201,23 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
1171
1201
  }
1172
1202
  }
1173
1203
  if (unitResult.status === "cancelled") {
1204
+ const errorCategory = unitResult.errorContext?.category;
1174
1205
  // Provider-error pause: pauseAuto already handled cleanup and scheduled
1175
1206
  // recovery. Don't hard-stop — just break out of the loop (#2762).
1176
- if (unitResult.errorContext?.category === "provider") {
1207
+ if (errorCategory === "provider") {
1177
1208
  await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
1178
- debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext.isTransient });
1209
+ debugLog("autoLoop", { phase: "exit", reason: "provider-pause", isTransient: unitResult.errorContext?.isTransient });
1179
1210
  return { action: "break", reason: "provider-pause" };
1180
1211
  }
1181
1212
  // Timeout category covers two distinct scenarios:
1182
1213
  // 1. Session creation timeout (120s) — transient, auto-resume with backoff
1183
1214
  // 2. Unit hard timeout (30min+) — stuck agent, pause for manual review
1215
+ // Transient session-failed covers recoverable newSession failures and should
1216
+ // pause instead of hard-stopping.
1184
1217
  // Structural errors (TypeError, is not a function) are NOT transient
1185
1218
  // and must hard-stop to avoid infinite retry loops.
1186
1219
  if (unitResult.errorContext?.isTransient &&
1187
- unitResult.errorContext?.category === "timeout") {
1220
+ errorCategory === "timeout") {
1188
1221
  const isSessionCreationTimeout = unitResult.errorContext.message?.includes("Session creation timed out");
1189
1222
  if (isSessionCreationTimeout) {
1190
1223
  consecutiveSessionTimeouts += 1;
@@ -1227,6 +1260,15 @@ export async function runUnitPhase(ic, iterData, loopState, sidecarItem) {
1227
1260
  await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
1228
1261
  return { action: "break", reason: "unit-hard-timeout" };
1229
1262
  }
1263
+ if (unitResult.errorContext?.isTransient &&
1264
+ errorCategory === "session-failed") {
1265
+ ctx.ui.notify(`Session creation failed transiently for ${unitType} ${unitId}: ${unitResult.errorContext?.message ?? "unknown"}. Pausing auto-mode (recoverable).`, "warning");
1266
+ debugLog("autoLoop", { phase: "session-start-transient-pause", unitType, unitId, category: errorCategory });
1267
+ await deps.pauseAuto(ctx, pi);
1268
+ await deps.autoCommitUnit?.(s.basePath, unitType, unitId, ctx);
1269
+ await emitCancelledUnitEnd(ic, unitType, unitId, unitStartSeq, unitResult.errorContext);
1270
+ return { action: "break", reason: "session-timeout" };
1271
+ }
1230
1272
  // All other cancelled states (structural errors, non-transient failures): hard stop
1231
1273
  if (s.currentUnit) {
1232
1274
  await deps.closeoutUnit(ctx, s.basePath, unitType, unitId, s.currentUnit.startedAt, deps.buildSnapshotOpts(unitType, unitId));
@@ -29,6 +29,16 @@ export function resolveExpectedArtifactPath(unitType, unitId, base) {
29
29
  return dir ? join(dir, buildMilestoneFileName(mid, "ROADMAP")) : null;
30
30
  }
31
31
  case "research-slice": {
32
+ // #4414: Sentinel unitId "{mid}/parallel-research" fans out across
33
+ // multiple slices. Resolve to a milestone-level placeholder path so
34
+ // blocker escalation has somewhere to write. Verification for this
35
+ // sentinel is handled directly in verifyExpectedArtifact.
36
+ if (sid === "parallel-research") {
37
+ const mdir = resolveMilestonePath(base, mid);
38
+ return mdir
39
+ ? join(mdir, buildMilestoneFileName(mid, "PARALLEL-BLOCKER"))
40
+ : null;
41
+ }
32
42
  const dir = resolveSlicePath(base, mid, sid);
33
43
  return dir ? join(dir, buildSliceFileName(sid, "RESEARCH")) : null;
34
44
  }
@@ -36,6 +46,11 @@ export function resolveExpectedArtifactPath(unitType, unitId, base) {
36
46
  const dir = resolveSlicePath(base, mid, sid);
37
47
  return dir ? join(dir, buildSliceFileName(sid, "PLAN")) : null;
38
48
  }
49
+ case "refine-slice": {
50
+ // ADR-011: refine-slice expands a sketch and writes the same PLAN.md as plan-slice.
51
+ const dir = resolveSlicePath(base, mid, sid);
52
+ return dir ? join(dir, buildSliceFileName(sid, "PLAN")) : null;
53
+ }
39
54
  case "reassess-roadmap": {
40
55
  const dir = resolveSlicePath(base, mid, sid);
41
56
  return dir ? join(dir, buildSliceFileName(sid, "ASSESSMENT")) : null;
@@ -90,9 +105,14 @@ export function diagnoseExpectedArtifact(unitType, unitId, base) {
90
105
  case "plan-milestone":
91
106
  return `${relMilestoneFile(base, mid, "ROADMAP")} (milestone roadmap)`;
92
107
  case "research-slice":
108
+ if (sid === "parallel-research") {
109
+ return `${relMilestoneFile(base, mid, "PARALLEL-BLOCKER")} (parallel slice research sentinel)`;
110
+ }
93
111
  return `${relSliceFile(base, mid, sid, "RESEARCH")} (slice research)`;
94
112
  case "plan-slice":
95
113
  return `${relSliceFile(base, mid, sid, "PLAN")} (slice plan)`;
114
+ case "refine-slice":
115
+ return `${relSliceFile(base, mid, sid, "PLAN")} (refined slice plan from sketch)`;
96
116
  case "execute-task": {
97
117
  return `Task ${tid} marked [x] in ${relSliceFile(base, mid, sid, "PLAN")} + summary written`;
98
118
  }