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
@@ -205,6 +205,19 @@ export async function nextDecisionId() {
205
205
  return 'D001';
206
206
  }
207
207
  }
208
+ /** Synchronous variant for use inside db.transaction(). */
209
+ function nextDecisionIdSync(adapter) {
210
+ if (!adapter)
211
+ return 'D001';
212
+ const row = adapter
213
+ .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM decisions')
214
+ .get();
215
+ const maxNum = row ? row['max_num'] : null;
216
+ if (maxNum == null || isNaN(maxNum))
217
+ return 'D001';
218
+ const next = maxNum + 1;
219
+ return `D${String(next).padStart(3, '0')}`;
220
+ }
208
221
  // ─── Next Requirement ID ─────────────────────────────────────────────────
209
222
  /**
210
223
  * Compute the next requirement ID from the current DB state.
@@ -318,32 +331,44 @@ export async function saveRequirementToDb(fields, basePath) {
318
331
  throw err;
319
332
  }
320
333
  }
334
+ // ─── Async Mutex for Decision Saves ───────────────────────────────────────
335
+ //
336
+ // Serializes the entire saveDecisionToDb operation (ID generation + DB upsert
337
+ // + file read + markdown regeneration + file write) so that parallel callers
338
+ // cannot interleave and produce a last-writer-wins race on DECISIONS.md.
339
+ let _decisionSaveLock = Promise.resolve();
340
+ /** Reset the mutex — only for tests. */
341
+ export function _resetDecisionSaveLock() {
342
+ _decisionSaveLock = Promise.resolve();
343
+ }
321
344
  /**
322
345
  * Save a new decision to DB and regenerate DECISIONS.md.
323
346
  * Auto-assigns the next ID via nextDecisionId().
324
347
  *
325
- * The ID computation (SELECT MAX) and insert are wrapped in a single
326
- * transaction to prevent parallel tool calls from computing the same ID
327
- * and silently overwriting each other (#3326, #3339, #3459).
348
+ * Concurrency: uses an async mutex (promise chain) to serialize the entire
349
+ * operation — ID generation, DB upsert, file read, markdown regeneration,
350
+ * and file write — preventing parallel callers from overwriting each other's
351
+ * output (last-writer-wins race condition).
328
352
  *
329
353
  * Returns the assigned ID.
330
354
  */
331
355
  export async function saveDecisionToDb(fields, basePath) {
356
+ // Serialize via async mutex: each call waits for the previous one to
357
+ // complete before starting, preventing interleaved DB + file writes.
358
+ let release;
359
+ const prev = _decisionSaveLock;
360
+ _decisionSaveLock = new Promise(r => { release = r; });
361
+ try {
362
+ await prev;
363
+ }
364
+ catch {
365
+ // Previous call failed — proceed regardless; the lock chain must continue.
366
+ }
332
367
  try {
333
368
  const db = await import('./gsd-db.js');
334
- // Atomic ID assignment + insert inside a transaction to prevent
335
- // parallel calls from racing on the same MAX(id) value.
369
+ const adapter = db._getAdapter();
336
370
  const id = db.transaction(() => {
337
- const adapter = db._getAdapter();
338
- if (!adapter)
339
- throw new GSDError(GSD_STALE_STATE, "gsd-db: No database open");
340
- const row = adapter
341
- .prepare('SELECT MAX(CAST(SUBSTR(id, 2) AS INTEGER)) as max_num FROM decisions')
342
- .get();
343
- const maxNum = row ? row['max_num'] : null;
344
- const nextId = (maxNum == null || isNaN(maxNum))
345
- ? 'D001'
346
- : `D${String(maxNum + 1).padStart(3, '0')}`;
371
+ const nextId = nextDecisionIdSync(adapter);
347
372
  db.upsertDecision({
348
373
  id: nextId,
349
374
  when_context: fields.when_context ?? '',
@@ -353,12 +378,12 @@ export async function saveDecisionToDb(fields, basePath) {
353
378
  rationale: fields.rationale,
354
379
  revisable: fields.revisable ?? 'Yes',
355
380
  made_by: fields.made_by ?? 'agent',
381
+ source: fields.source ?? 'discussion',
356
382
  superseded_by: null,
357
383
  });
358
384
  return nextId;
359
385
  });
360
386
  // Fetch all decisions (including superseded for the full register)
361
- const adapter = db._getAdapter();
362
387
  let allDecisions = [];
363
388
  if (adapter) {
364
389
  const rows = adapter.prepare('SELECT * FROM decisions ORDER BY seq').all();
@@ -433,12 +458,60 @@ export async function saveDecisionToDb(fields, basePath) {
433
458
  invalidateStateCache();
434
459
  clearPathCache();
435
460
  clearParseCache();
461
+ // ADR-013 dual-write: keep the memory store in sync with every decision
462
+ // persisted via the legacy gsd_save_decision path. Without this, prompts
463
+ // that still call gsd_save_decision (discuss.md, plan-milestone.md,
464
+ // guided-plan-slice.md, et al. during the deprecation window) would
465
+ // create decisions rows invisible to memory_query and loadMemoryBlock.
466
+ // Best-effort — never throw, never roll back the decision on failure.
467
+ try {
468
+ const { createMemory } = await import('./memory-store.js');
469
+ const decisionText = (fields.decision ?? '').trim();
470
+ const choiceText = (fields.choice ?? '').trim();
471
+ const rationaleText = (fields.rationale ?? '').trim();
472
+ const contentParts = [];
473
+ if (decisionText)
474
+ contentParts.push(decisionText);
475
+ if (choiceText)
476
+ contentParts.push(`Chose: ${choiceText}.`);
477
+ if (rationaleText)
478
+ contentParts.push(`Rationale: ${rationaleText}.`);
479
+ const content = contentParts.join(' ').slice(0, 600);
480
+ if (content) {
481
+ createMemory({
482
+ category: 'architecture',
483
+ content,
484
+ scope: fields.scope || 'project',
485
+ confidence: 0.85,
486
+ structuredFields: {
487
+ sourceDecisionId: id,
488
+ when_context: fields.when_context ?? '',
489
+ scope: fields.scope,
490
+ decision: fields.decision,
491
+ choice: fields.choice,
492
+ rationale: fields.rationale,
493
+ made_by: fields.made_by ?? 'agent',
494
+ revisable: fields.revisable ?? '',
495
+ },
496
+ });
497
+ }
498
+ }
499
+ catch (mirrorErr) {
500
+ logError('manifest', 'memory-store mirror write failed (non-fatal)', {
501
+ fn: 'saveDecisionToDb',
502
+ decisionId: id,
503
+ error: String(mirrorErr.message),
504
+ });
505
+ }
436
506
  return { id };
437
507
  }
438
508
  catch (err) {
439
509
  logError('manifest', 'saveDecisionToDb failed', { fn: 'saveDecisionToDb', error: String(err.message) });
440
510
  throw err;
441
511
  }
512
+ finally {
513
+ release();
514
+ }
442
515
  }
443
516
  /**
444
517
  * Extract a milestone/slice reference from a deferral decision.
@@ -130,7 +130,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
130
130
  - `auto_push`: boolean — automatically push commits to the remote after committing. Default: `false`.
131
131
  - `push_branches`: boolean — push the milestone branch to the remote after commits. Default: `false`.
132
132
  - `remote`: string — git remote name to push to. Default: `"origin"`.
133
- - `snapshots`: boolean — create snapshot commits (WIP saves) during long-running tasks. Default: `true`.
133
+ - `snapshots`: boolean — create WIP snapshot commits (e.g. pre-dispatch and stale-uncommitted-changes safety commits emitted by the doctor). Set to `false` to suppress all doctor-initiated `gsd snapshot:` commits. Default: `true`.
134
134
  - `pre_merge_check`: boolean or `"auto"` — run pre-merge checks before merging a worktree back to the integration branch. `true` always runs, `false` never runs, `"auto"` runs when CI is detected. Default: `"auto"`.
135
135
  - `commit_type`: string — override the conventional commit type prefix. Must be one of: `feat`, `fix`, `refactor`, `docs`, `test`, `chore`, `perf`, `ci`, `build`, `style`. Default: inferred from diff content.
136
136
  - `main_branch`: string — the primary branch name for new git repos (e.g., `"main"`, `"master"`, `"trunk"`). Also used by `getMainBranch()` as the preferred branch when auto-detection is ambiguous. Default: `"main"`.
@@ -201,7 +201,7 @@ Setting `prefer_skills: []` does **not** disable skill discovery — it just mea
201
201
  - `model_policy.enabled`: boolean — enforce policy filtering before model capability scoring. Default: `true`.
202
202
  - `execution_graph.enabled`: boolean — enable DAG scheduler facade/adapters for execution. Default: `true`.
203
203
  - `gitops.enabled`: boolean — persist turn-level git transaction records. Default: `true`.
204
- - `gitops.turn_action`: `"commit"` | `"snapshot"` | `"status-only"` — turn transaction mode. Default: `"status-only"`.
204
+ - `gitops.turn_action`: `"commit"` | `"snapshot"` | `"status-only"` — turn transaction mode. Default: `"commit"` (per-task atomic commits).
205
205
  - `gitops.turn_push`: boolean — whether turn transactions should include push intent metadata. Default: `false`.
206
206
  - `audit_unified.enabled`: boolean — dual-write unified audit envelope events. Default: `true`.
207
207
  - `plan_v2.enabled`: boolean — enable bounded clarify/research/draft/compile planning flow. Default: `true`.
@@ -11,6 +11,7 @@
11
11
  import { existsSync, readFileSync, statSync } from "node:fs";
12
12
  import { execSync } from "node:child_process";
13
13
  import { join } from "node:path";
14
+ import { detectPythonExecutable } from "./python-resolver.js";
14
15
  // ── Constants ──────────────────────────────────────────────────────────────
15
16
  /** Default dev server ports to scan for conflicts. */
16
17
  const DEFAULT_DEV_PORTS = [3000, 3001, 4000, 5000, 5173, 8000, 8080, 8888];
@@ -350,7 +351,7 @@ function checkProjectTools(basePath) {
350
351
  }
351
352
  // Check for Python if pyproject.toml or requirements.txt exists
352
353
  if (existsSync(join(basePath, "pyproject.toml")) || existsSync(join(basePath, "requirements.txt"))) {
353
- if (!commandExists("python3", basePath) && !commandExists("python", basePath)) {
354
+ if (detectPythonExecutable() === null) {
354
355
  results.push({
355
356
  name: "python",
356
357
  status: "warning",
@@ -2,7 +2,7 @@ import { existsSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs
2
2
  import { join, sep } from "node:path";
3
3
  import { loadFile } from "./files.js";
4
4
  import { parseRoadmap as parseLegacyRoadmap } from "./parsers-legacy.js";
5
- import { isDbAvailable, getMilestoneSlices } from "./gsd-db.js";
5
+ import { isDbAvailable, getMilestone } from "./gsd-db.js";
6
6
  import { resolveMilestoneFile } from "./paths.js";
7
7
  import { deriveState, isMilestoneComplete } from "./state.js";
8
8
  import { listWorktrees, resolveGitDir, worktreesDir } from "./worktree-manager.js";
@@ -34,6 +34,35 @@ function isDoctorArtifactOnly(dirPath) {
34
34
  return false;
35
35
  }
36
36
  }
37
+ function normalizePathForComparison(path) {
38
+ const resolved = existsSync(path) ? realpathSync(path) : path;
39
+ const normalized = resolved
40
+ .replaceAll("\\", "/")
41
+ .replace(/^\/\/\?\//, "")
42
+ .replace(/\/+$/, "");
43
+ return process.platform === "win32" ? normalized.toLowerCase() : normalized;
44
+ }
45
+ function isSameOrNestedPath(candidate, container) {
46
+ const normalizedCandidate = normalizePathForComparison(candidate);
47
+ const normalizedContainer = normalizePathForComparison(container);
48
+ return normalizedCandidate === normalizedContainer ||
49
+ normalizedCandidate.startsWith(`${normalizedContainer}/`);
50
+ }
51
+ async function isCompletedMilestoneTerminal(basePath, milestoneId) {
52
+ const summaryPath = resolveMilestoneFile(basePath, milestoneId, "SUMMARY");
53
+ if (!summaryPath)
54
+ return false;
55
+ if (isDbAvailable()) {
56
+ const milestone = getMilestone(milestoneId);
57
+ return !!milestone && milestone.status === "complete";
58
+ }
59
+ const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
60
+ const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
61
+ if (!roadmapContent)
62
+ return false;
63
+ const roadmap = parseLegacyRoadmap(roadmapContent);
64
+ return isMilestoneComplete(roadmap);
65
+ }
37
66
  export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix, isolationMode = "none") {
38
67
  // Degrade gracefully if not a git repo
39
68
  if (!nativeIsRepo(basePath)) {
@@ -53,23 +82,9 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
53
82
  // Extract milestone ID from branch name "milestone/M001" → "M001"
54
83
  const milestoneId = wt.branch.replace(/^milestone\//, "");
55
84
  const milestoneEntry = state.registry.find(m => m.id === milestoneId);
56
- // Check if milestone is complete via roadmap
57
- let isComplete = false;
58
- if (milestoneEntry) {
59
- if (isDbAvailable()) {
60
- const dbSlices = getMilestoneSlices(milestoneId);
61
- isComplete = dbSlices.length > 0 && dbSlices.every(s => s.status === "complete");
62
- }
63
- else {
64
- const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
65
- const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
66
- if (roadmapContent) {
67
- const roadmap = parseLegacyRoadmap(roadmapContent);
68
- isComplete = isMilestoneComplete(roadmap);
69
- }
70
- }
71
- // When DB unavailable and no roadmap, isComplete stays false
72
- }
85
+ const isComplete = milestoneEntry
86
+ ? await isCompletedMilestoneTerminal(basePath, milestoneId)
87
+ : false;
73
88
  if (isComplete) {
74
89
  issues.push({
75
90
  severity: "warning",
@@ -84,8 +99,14 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
84
99
  // pattern in removeWorktree() (#1946). Without this, git cannot
85
100
  // remove the worktree and the doctor enters a deadlock where it
86
101
  // detects the orphan every run but never cleans it up.
87
- const cwd = process.cwd();
88
- if (wt.path === cwd || cwd.startsWith(wt.path + sep)) {
102
+ let cwd = basePath;
103
+ try {
104
+ cwd = process.cwd();
105
+ }
106
+ catch {
107
+ cwd = basePath;
108
+ }
109
+ if (isSameOrNestedPath(cwd, wt.path)) {
89
110
  try {
90
111
  process.chdir(basePath);
91
112
  }
@@ -116,17 +137,10 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
116
137
  const milestoneId = branch.replace(/^milestone\//, "");
117
138
  const roadmapPath = resolveMilestoneFile(basePath, milestoneId, "ROADMAP");
118
139
  let branchMilestoneComplete = false;
119
- if (isDbAvailable()) {
120
- const dbSlices = getMilestoneSlices(milestoneId);
121
- branchMilestoneComplete = dbSlices.length > 0 && dbSlices.every(s => s.status === "complete");
122
- }
123
- else {
124
- const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
125
- if (!roadmapContent)
126
- continue;
127
- const roadmap = parseLegacyRoadmap(roadmapContent);
128
- branchMilestoneComplete = isMilestoneComplete(roadmap);
129
- }
140
+ const roadmapContent = roadmapPath ? await loadFile(roadmapPath) : null;
141
+ if (!roadmapContent)
142
+ continue;
143
+ branchMilestoneComplete = await isCompletedMilestoneTerminal(basePath, milestoneId);
130
144
  if (branchMilestoneComplete) {
131
145
  issues.push({
132
146
  severity: "info",
@@ -365,8 +379,12 @@ export async function checkGitHealth(basePath, issues, fixesApplied, shouldFix,
365
379
  // auto-commit a safety snapshot so work isn't lost.
366
380
  try {
367
381
  const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
382
+ // `git.snapshots: false` is the canonical toggle that disables WIP
383
+ // snapshot commits — honour it here as well so both the proactive gate
384
+ // and the doctor-run path stay consistent (#4420).
385
+ const snapshotsEnabled = prefs.git?.snapshots !== false;
368
386
  const thresholdMinutes = prefs.stale_commit_threshold_minutes ?? 30;
369
- if (thresholdMinutes > 0) {
387
+ if (snapshotsEnabled && thresholdMinutes > 0) {
370
388
  const dirty = nativeHasChanges(basePath);
371
389
  if (dirty) {
372
390
  const branch = nativeGetCurrentBranch(basePath);
@@ -238,8 +238,11 @@ export async function preDispatchHealthGate(basePath) {
238
238
  try {
239
239
  if (nativeIsRepo(basePath)) {
240
240
  const prefs = loadEffectiveGSDPreferences()?.preferences ?? {};
241
+ // `git.snapshots: false` is the canonical toggle that disables WIP
242
+ // snapshot commits — honour it before touching the threshold path (#4420).
243
+ const snapshotsEnabled = prefs.git?.snapshots !== false;
241
244
  const thresholdMinutes = prefs.stale_commit_threshold_minutes ?? 30;
242
- if (thresholdMinutes > 0 && nativeHasChanges(basePath)) {
245
+ if (snapshotsEnabled && thresholdMinutes > 0 && nativeHasChanges(basePath)) {
243
246
  const branch = nativeGetCurrentBranch(basePath);
244
247
  const lastEpoch = nativeLastCommitEpoch(basePath, branch || "HEAD");
245
248
  const nowEpoch = Math.floor(Date.now() / 1000);
@@ -10,8 +10,8 @@
10
10
  * - Remote questions channel if configured (Slack/Discord/Telegram token)
11
11
  * - Optional search/tool integrations (Brave, Tavily, Jina, Context7)
12
12
  */
13
- import { existsSync } from "node:fs";
14
- import { join } from "node:path";
13
+ import { existsSync, readFileSync } from "node:fs";
14
+ import { delimiter, join } from "node:path";
15
15
  import { AuthStorage } from "@gsd/pi-coding-agent";
16
16
  import { getEnvApiKey } from "@gsd/pi-ai";
17
17
  import { loadEffectiveGSDPreferences } from "./preferences.js";
@@ -47,7 +47,8 @@ function modelToProviderId(model) {
47
47
  return null;
48
48
  // Explicit provider prefix (e.g. "openrouter/deepseek-r1")
49
49
  if (model.includes("/")) {
50
- const prefix = model.split("/")[0].toLowerCase();
50
+ const rawPrefix = model.split("/")[0];
51
+ const prefix = rawPrefix.toLowerCase();
51
52
  // Map known prefixes to registry IDs
52
53
  const prefixMap = {
53
54
  "anthropic-vertex": "anthropic-vertex",
@@ -62,6 +63,7 @@ function modelToProviderId(model) {
62
63
  };
63
64
  if (prefixMap[prefix])
64
65
  return prefixMap[prefix];
66
+ return rawPrefix;
65
67
  }
66
68
  const lower = model.toLowerCase();
67
69
  if (lower.startsWith("claude"))
@@ -136,8 +138,49 @@ function isCliBinaryInPath(providerId) {
136
138
  const binary = CLI_BINARY_MAP[providerId];
137
139
  if (!binary)
138
140
  return false;
139
- const pathDirs = (process.env.PATH ?? "").split(":");
140
- return pathDirs.some(dir => dir && existsSync(join(dir, binary)));
141
+ const pathDirs = (process.env.PATH ?? "").split(delimiter).filter(Boolean);
142
+ // On Windows, command shims are commonly installed as .cmd/.exe/.bat/.com.
143
+ // Scan PATHEXT candidates in addition to the bare binary name.
144
+ const executableNames = [binary];
145
+ if (process.platform === "win32") {
146
+ const rawPathExt = process.env.PATHEXT
147
+ ?.split(";")
148
+ .map(ext => ext.trim())
149
+ .filter(Boolean) ?? [];
150
+ const normalizedPathExt = rawPathExt.map(ext => ext.startsWith(".") ? ext.toLowerCase() : `.${ext.toLowerCase()}`);
151
+ const defaultExt = [".exe", ".cmd", ".bat", ".com"];
152
+ for (const ext of [...normalizedPathExt, ...defaultExt]) {
153
+ const candidate = `${binary}${ext}`;
154
+ if (!executableNames.includes(candidate))
155
+ executableNames.push(candidate);
156
+ }
157
+ }
158
+ return pathDirs.some(dir => executableNames.some(name => existsSync(join(dir, name))));
159
+ }
160
+ function modelsJsonPaths() {
161
+ const home = process.env.HOME ?? "~";
162
+ return [
163
+ join(home, ".gsd", "agent", "models.json"),
164
+ // Keep parity with custom-provider discovery during auto bootstrap.
165
+ join(home, ".pi", "agent", "models.json"),
166
+ ];
167
+ }
168
+ function hasModelsJsonApiKey(providerId) {
169
+ for (const path of modelsJsonPaths()) {
170
+ if (!existsSync(path))
171
+ continue;
172
+ try {
173
+ const parsed = JSON.parse(readFileSync(path, "utf-8"));
174
+ const apiKey = parsed.providers?.[providerId]?.apiKey;
175
+ if (typeof apiKey === "string" && apiKey.trim().length > 0) {
176
+ return true;
177
+ }
178
+ }
179
+ catch {
180
+ // Malformed models.json should not break the dashboard health check.
181
+ }
182
+ }
183
+ return false;
141
184
  }
142
185
  function resolveKey(providerId) {
143
186
  const info = PROVIDER_REGISTRY.find(p => p.id === providerId);
@@ -182,6 +225,9 @@ function resolveKey(providerId) {
182
225
  if (info?.envVar && process.env[info.envVar]) {
183
226
  return { found: true, source: "env", backedOff: false };
184
227
  }
228
+ if (hasModelsJsonApiKey(providerId)) {
229
+ return { found: true, source: "models.json", backedOff: false };
230
+ }
185
231
  return { found: false, source: "none", backedOff: false };
186
232
  }
187
233
  // ── Individual check groups ────────────────────────────────────────────────────
@@ -6,7 +6,7 @@ import { deriveState } from "./state.js";
6
6
  import { saveFile } from "./files.js";
7
7
  import { nativeIsRepo, nativeForEachRef, nativeUpdateRef } from "./native-git-bridge.js";
8
8
  import { readCrashLock, isLockProcessAlive, clearLock } from "./crash-recovery.js";
9
- import { ensureGitignore } from "./gitignore.js";
9
+ import { ensureGitignore, isGsdGitignored } from "./gitignore.js";
10
10
  import { readAllSessionStatuses, isSessionStale, removeSessionStatus } from "./session-status-io.js";
11
11
  import { recoverFailedMigration } from "./migrate-external.js";
12
12
  import { splitCompletedKey } from "./forensics.js";
@@ -350,6 +350,26 @@ export async function checkRuntimeHealth(basePath, issues, fixesApplied, shouldF
350
350
  fixable: false,
351
351
  });
352
352
  }
353
+ // ── Symlinked .gsd without .gitignore entry (#4423) ──
354
+ // When `.gsd` is a symlink AND not gitignored, `git add -A -- :!.gsd/...`
355
+ // pathspecs fail with "beyond a symbolic link". Without self-heal this
356
+ // silently drops new user files during auto-commit.
357
+ if (nativeIsRepo(basePath) && !isGsdGitignored(basePath)) {
358
+ issues.push({
359
+ severity: "warning",
360
+ code: "symlinked_gsd_unignored",
361
+ scope: "project",
362
+ unitId: "project",
363
+ message: ".gsd is a symlink to external state but is not listed in .gitignore. This causes git pathspec exclusions to fail and can lead to silently dropped new files during auto-commit. Add `.gsd` to .gitignore.",
364
+ file: ".gitignore",
365
+ fixable: true,
366
+ });
367
+ if (shouldFix("symlinked_gsd_unignored")) {
368
+ const modified = ensureGitignore(basePath);
369
+ if (modified)
370
+ fixesApplied.push("added .gsd to .gitignore (symlinked external state)");
371
+ }
372
+ }
353
373
  }
354
374
  }
355
375
  }
@@ -154,8 +154,14 @@ function auditRequirements(content) {
154
154
  const owner = block.match(/^-\s+Primary owning slice:\s+(.+)$/m)?.[1]?.trim().toLowerCase() ?? "";
155
155
  const notes = block.match(/^-\s+Notes:\s+(.+)$/m)?.[1]?.trim().toLowerCase() ?? "";
156
156
  if (status === "active" && (!owner || owner === "none" || owner === "none yet")) {
157
+ // #4414: Downgrade to warning. A newly-created requirement has
158
+ // primary_owner='' by default until the planning agent wires it to
159
+ // a slice via gsd_requirement_update. Flagging this as an error
160
+ // during normal planning is noisy — the real failure mode is when
161
+ // it persists past milestone completion, which is covered by other
162
+ // audits. Keep the signal but don't treat it as a blocker.
157
163
  issues.push({
158
- severity: "error",
164
+ severity: "warning",
159
165
  code: "active_requirement_missing_owner",
160
166
  scope: "project",
161
167
  unitId: requirementId,
@@ -101,6 +101,7 @@ export function createGSDExtensionAPI(pi, sharedHandlers) {
101
101
  // ── Event emission ─────────────────────────────────────────────────
102
102
  emitBeforeModelSelect: (...args) => pi.emitBeforeModelSelect(...args),
103
103
  emitAdjustToolSet: (...args) => pi.emitAdjustToolSet(...args),
104
+ emitExtensionEvent: (...args) => pi.emitExtensionEvent(...args),
104
105
  // ── Tool / command / shortcut / flag registration ──────────────────
105
106
  registerTool: ((tool) => pi.registerTool(tool)),
106
107
  registerCommand: (...args) => pi.registerCommand(...args),
@@ -19,7 +19,10 @@ export function resetRetryState(state) {
19
19
  }
20
20
  // ── Classification ──────────────────────────────────────────────────────────
21
21
  const PERMANENT_RE = /auth|unauthorized|forbidden|invalid.*key|invalid.*api|billing|quota exceeded|account/i;
22
- const RATE_LIMIT_RE = /rate.?limit|too many requests|429/i;
22
+ // Include provider-specific quota-window phrasing like:
23
+ // - "You've hit your limit"
24
+ // - "usage limit" / "quota reached"
25
+ const RATE_LIMIT_RE = /rate.?limit|too many requests|429|hit your limit|usage limit|quota (?:reached|hit)|limit.*resets?/i;
23
26
  // OpenRouter affordability-style quota errors should be treated as transient
24
27
  // so core retry logic can lower maxTokens and continue in-session.
25
28
  const AFFORDABILITY_RE = /requires more credits|can only afford|insufficient credits|not enough credits|fewer max_tokens/i;
@@ -36,7 +39,7 @@ const RESET_DELAY_RE = /reset in (\d+)s/i;
36
39
  *
37
40
  * Classification order:
38
41
  * 1. Permanent (auth/billing/quota) — unless also rate-limited
39
- * 2. Rate limit (429, rate.?limit, too many requests)
42
+ * 2. Rate limit (429, rate.?limit, too many requests, hit-your-limit/quota-window phrasing)
40
43
  * 3. Network (ECONNRESET, ETIMEDOUT, socket hang up, fetch failed, dns)
41
44
  * 4. Stream truncation (malformed JSON from mid-stream cut)
42
45
  * 5. Server (500/502/503, overloaded, server_error)