gsd-pi 2.77.0-dev.c9c8932c6 → 2.77.0-dev.cfd69e714

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 (708) hide show
  1. package/README.md +1 -1
  2. package/dist/claude-cli-check.js +5 -1
  3. package/dist/cli-web-branch.d.ts +1 -0
  4. package/dist/cli-web-branch.js +3 -0
  5. package/dist/cli.js +24 -2
  6. package/dist/headless.js +49 -4
  7. package/dist/provider-migrations.d.ts +18 -0
  8. package/dist/provider-migrations.js +14 -0
  9. package/dist/resource-loader.d.ts +40 -0
  10. package/dist/resource-loader.js +32 -13
  11. package/dist/resources/extensions/browser-tools/capture.js +9 -0
  12. package/dist/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  13. package/dist/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  14. package/dist/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  15. package/dist/resources/extensions/browser-tools/tools/forms.js +5 -1
  16. package/dist/resources/extensions/browser-tools/tools/intent.js +5 -1
  17. package/dist/resources/extensions/claude-code-cli/readiness.js +5 -1
  18. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +495 -27
  19. package/dist/resources/extensions/github-sync/templates.js +103 -0
  20. package/dist/resources/extensions/google-search/index.js +3 -2
  21. package/dist/resources/extensions/gsd/abandon-detect.js +44 -0
  22. package/dist/resources/extensions/gsd/auto/loop.js +124 -2
  23. package/dist/resources/extensions/gsd/auto/phases.js +57 -39
  24. package/dist/resources/extensions/gsd/auto/resolve.js +24 -0
  25. package/dist/resources/extensions/gsd/auto/run-unit.js +10 -2
  26. package/dist/resources/extensions/gsd/auto/session.js +6 -2
  27. package/dist/resources/extensions/gsd/auto/turn-epoch.js +95 -0
  28. package/dist/resources/extensions/gsd/auto-dispatch.js +166 -29
  29. package/dist/resources/extensions/gsd/auto-loop.js +1 -1
  30. package/dist/resources/extensions/gsd/auto-model-selection.js +124 -4
  31. package/dist/resources/extensions/gsd/auto-post-unit.js +181 -64
  32. package/dist/resources/extensions/gsd/auto-prompts.js +372 -104
  33. package/dist/resources/extensions/gsd/auto-recovery.js +197 -48
  34. package/dist/resources/extensions/gsd/auto-start.js +107 -29
  35. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +11 -5
  36. package/dist/resources/extensions/gsd/auto-tool-tracking.js +47 -7
  37. package/dist/resources/extensions/gsd/auto-unit-closeout.js +11 -2
  38. package/dist/resources/extensions/gsd/auto-worktree.js +180 -34
  39. package/dist/resources/extensions/gsd/auto.js +80 -21
  40. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +19 -1
  41. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +209 -0
  42. package/dist/resources/extensions/gsd/bootstrap/provider-error-resume.js +5 -6
  43. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +7 -3
  44. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +127 -9
  45. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +31 -4
  46. package/dist/resources/extensions/gsd/component-loader.js +447 -0
  47. package/dist/resources/extensions/gsd/component-types.js +69 -0
  48. package/dist/resources/extensions/gsd/context-store.js +23 -7
  49. package/dist/resources/extensions/gsd/detection.js +49 -1
  50. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -17
  51. package/dist/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  52. package/dist/resources/extensions/gsd/file-lock.js +49 -9
  53. package/dist/resources/extensions/gsd/forensics.js +106 -0
  54. package/dist/resources/extensions/gsd/gate-registry.js +2 -2
  55. package/dist/resources/extensions/gsd/git-constants.js +28 -1
  56. package/dist/resources/extensions/gsd/git-self-heal.js +27 -0
  57. package/dist/resources/extensions/gsd/git-service.js +127 -2
  58. package/dist/resources/extensions/gsd/gitignore.js +1 -0
  59. package/dist/resources/extensions/gsd/gsd-db.js +6 -3
  60. package/dist/resources/extensions/gsd/guided-flow-queue.js +4 -1
  61. package/dist/resources/extensions/gsd/guided-flow.js +39 -13
  62. package/dist/resources/extensions/gsd/journal.js +17 -2
  63. package/dist/resources/extensions/gsd/memory-extractor.js +7 -1
  64. package/dist/resources/extensions/gsd/milestone-actions.js +15 -0
  65. package/dist/resources/extensions/gsd/milestone-scope-classifier.js +299 -0
  66. package/dist/resources/extensions/gsd/milestone-summary-classifier.js +37 -0
  67. package/dist/resources/extensions/gsd/model-cost-table.js +3 -0
  68. package/dist/resources/extensions/gsd/model-router.js +6 -0
  69. package/dist/resources/extensions/gsd/native-git-bridge.js +34 -4
  70. package/dist/resources/extensions/gsd/preferences-validation.js +23 -0
  71. package/dist/resources/extensions/gsd/prompt-cache-optimizer.js +4 -0
  72. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  73. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  74. package/dist/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  75. package/dist/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  76. package/dist/resources/extensions/gsd/reports.js +5 -4
  77. package/dist/resources/extensions/gsd/safety/git-checkpoint.js +11 -0
  78. package/dist/resources/extensions/gsd/service-tier.js +5 -2
  79. package/dist/resources/extensions/gsd/session-lock.js +19 -10
  80. package/dist/resources/extensions/gsd/skill-manifest.js +168 -0
  81. package/dist/resources/extensions/gsd/slice-cadence.js +238 -0
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +278 -8
  83. package/dist/resources/extensions/gsd/state-transition-matrix.js +118 -0
  84. package/dist/resources/extensions/gsd/state.js +69 -58
  85. package/dist/resources/extensions/gsd/sync-lock.js +98 -42
  86. package/dist/resources/extensions/gsd/tools/complete-slice.js +21 -0
  87. package/dist/resources/extensions/gsd/tools/complete-task.js +31 -0
  88. package/dist/resources/extensions/gsd/tools/validate-milestone.js +7 -2
  89. package/dist/resources/extensions/gsd/unit-context-composer.js +147 -0
  90. package/dist/resources/extensions/gsd/unit-context-manifest.js +370 -0
  91. package/dist/resources/extensions/gsd/uok/audit.js +18 -2
  92. package/dist/resources/extensions/gsd/uok/dispatch-envelope.js +33 -0
  93. package/dist/resources/extensions/gsd/uok/execution-graph.js +10 -0
  94. package/dist/resources/extensions/gsd/uok/gate-runner.js +53 -5
  95. package/dist/resources/extensions/gsd/uok/gitops.js +2 -1
  96. package/dist/resources/extensions/gsd/uok/loop-adapter.js +37 -10
  97. package/dist/resources/extensions/gsd/uok/parity-report.js +58 -0
  98. package/dist/resources/extensions/gsd/uok/plan-v2.js +10 -4
  99. package/dist/resources/extensions/gsd/uok/writer.js +82 -0
  100. package/dist/resources/extensions/gsd/workflow-logger.js +10 -2
  101. package/dist/resources/extensions/gsd/workflow-mcp.js +6 -0
  102. package/dist/resources/extensions/gsd/worktree-manager.js +86 -8
  103. package/dist/resources/extensions/gsd/worktree-resolver.js +86 -7
  104. package/dist/resources/extensions/gsd/worktree-telemetry.js +198 -0
  105. package/dist/resources/extensions/mcp-client/auth.js +10 -1
  106. package/dist/resources/extensions/mcp-client/index.js +121 -10
  107. package/dist/resources/extensions/ollama/index.js +5 -1
  108. package/dist/resources/extensions/remote-questions/manager.js +11 -5
  109. package/dist/resources/skills/create-skill/SKILL.md +2 -2
  110. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  111. package/dist/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  112. package/dist/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  113. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  114. package/dist/web/standalone/.next/BUILD_ID +1 -1
  115. package/dist/web/standalone/.next/app-path-routes-manifest.json +12 -12
  116. package/dist/web/standalone/.next/build-manifest.json +3 -3
  117. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  118. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  119. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  120. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  122. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/boot/route.js.nft.json +1 -1
  137. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js.nft.json +1 -1
  139. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js.nft.json +1 -1
  141. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js.nft.json +1 -1
  143. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/captures/route.js.nft.json +1 -1
  145. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/cleanup/route.js.nft.json +1 -1
  147. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/doctor/route.js.nft.json +1 -1
  149. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/export-data/route.js.nft.json +1 -1
  151. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  153. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/forensics/route.js.nft.json +1 -1
  155. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/git/route.js.nft.json +1 -1
  157. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/history/route.js.nft.json +1 -1
  159. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/hooks/route.js.nft.json +1 -1
  161. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/inspect/route.js.nft.json +1 -1
  163. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/knowledge/route.js.nft.json +1 -1
  165. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/live-state/route.js.nft.json +1 -1
  167. package/dist/web/standalone/.next/server/app/api/notifications/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/notifications/route.js.nft.json +1 -1
  169. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  170. package/dist/web/standalone/.next/server/app/api/onboarding/route.js.nft.json +1 -1
  171. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  173. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/recovery/route.js.nft.json +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  176. package/dist/web/standalone/.next/server/app/api/session/browser/route.js.nft.json +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/command/route.js.nft.json +1 -1
  179. package/dist/web/standalone/.next/server/app/api/session/events/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/session/events/route.js.nft.json +1 -1
  181. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/session/manage/route.js.nft.json +1 -1
  183. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/settings-data/route.js.nft.json +1 -1
  185. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/skill-health/route.js.nft.json +1 -1
  187. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/steer/route.js.nft.json +1 -1
  189. package/dist/web/standalone/.next/server/app/api/switch-root/route.js +1 -1
  190. package/dist/web/standalone/.next/server/app/api/switch-root/route.js.nft.json +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +1 -1
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js.nft.json +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +1 -1
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js.nft.json +1 -1
  195. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/undo/route.js.nft.json +1 -1
  197. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/visualizer/route.js.nft.json +1 -1
  199. package/dist/web/standalone/.next/server/app/index.html +1 -1
  200. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  201. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  202. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  203. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  204. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  205. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  206. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  207. package/dist/web/standalone/.next/server/chunks/1926.js +1 -0
  208. package/dist/web/standalone/.next/server/chunks/6897.js +2 -2
  209. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  210. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  211. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  213. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  214. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  215. package/dist/web/standalone/.next/static/chunks/2826.e9f5195e91f9cad2.js +11 -0
  216. package/dist/web/standalone/.next/static/chunks/{webpack-1832629448831fdc.js → webpack-2e68521d7c82f7c2.js} +1 -1
  217. package/package.json +4 -5
  218. package/packages/daemon/src/logger.ts +4 -3
  219. package/packages/mcp-server/README.md +3 -3
  220. package/packages/mcp-server/dist/env-writer.d.ts +1 -0
  221. package/packages/mcp-server/dist/env-writer.d.ts.map +1 -1
  222. package/packages/mcp-server/dist/env-writer.js +74 -6
  223. package/packages/mcp-server/dist/env-writer.js.map +1 -1
  224. package/packages/mcp-server/dist/server.d.ts +24 -0
  225. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  226. package/packages/mcp-server/dist/server.js +111 -87
  227. package/packages/mcp-server/dist/server.js.map +1 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +15 -6
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/src/env-writer.test.ts +79 -1
  232. package/packages/mcp-server/src/env-writer.ts +76 -6
  233. package/packages/mcp-server/src/mcp-server.test.ts +25 -3
  234. package/packages/mcp-server/src/readers/graph.test.ts +87 -15
  235. package/packages/mcp-server/src/secure-env-collect.test.ts +232 -237
  236. package/packages/mcp-server/src/server.ts +158 -105
  237. package/packages/mcp-server/src/workflow-tools.test.ts +85 -0
  238. package/packages/mcp-server/src/workflow-tools.ts +19 -6
  239. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  240. package/packages/native/package.json +1 -1
  241. package/packages/native/src/__tests__/_test-coverage-guard.test.mjs +98 -0
  242. package/packages/native/src/__tests__/module-compat.test.mjs +59 -27
  243. package/packages/native/src/__tests__/ps.test.mjs +14 -8
  244. package/packages/native/src/__tests__/stream-process.test.mjs +23 -2
  245. package/packages/native/src/__tests__/truncate.test.mjs +17 -2
  246. package/packages/pi-agent-core/src/agent-loop.test.ts +5 -15
  247. package/packages/pi-agent-core/src/agent.test.ts +96 -102
  248. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  249. package/packages/pi-ai/dist/models/capability-patches.d.ts.map +1 -1
  250. package/packages/pi-ai/dist/models/capability-patches.js +9 -2
  251. package/packages/pi-ai/dist/models/capability-patches.js.map +1 -1
  252. package/packages/pi-ai/dist/models/generated/index.d.ts +34 -0
  253. package/packages/pi-ai/dist/models/generated/index.d.ts.map +1 -1
  254. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts +17 -0
  255. package/packages/pi-ai/dist/models/generated/openai-codex.d.ts.map +1 -1
  256. package/packages/pi-ai/dist/models/generated/openai-codex.js +17 -0
  257. package/packages/pi-ai/dist/models/generated/openai-codex.js.map +1 -1
  258. package/packages/pi-ai/dist/models/generated/openai.d.ts +17 -0
  259. package/packages/pi-ai/dist/models/generated/openai.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/models/generated/openai.js +17 -0
  261. package/packages/pi-ai/dist/models/generated/openai.js.map +1 -1
  262. package/packages/pi-ai/dist/models.generated.test.js +43 -70
  263. package/packages/pi-ai/dist/models.generated.test.js.map +1 -1
  264. package/packages/pi-ai/dist/models.test.js +36 -11
  265. package/packages/pi-ai/dist/models.test.js.map +1 -1
  266. package/packages/pi-ai/scripts/generate-models.ts +44 -0
  267. package/packages/pi-ai/src/models/capability-patches.ts +10 -2
  268. package/packages/pi-ai/src/models/generated/openai-codex.ts +17 -0
  269. package/packages/pi-ai/src/models/generated/openai.ts +17 -0
  270. package/packages/pi-ai/src/models.generated.test.ts +46 -73
  271. package/packages/pi-ai/src/models.test.ts +48 -11
  272. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  273. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +96 -32
  274. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js +75 -12
  276. package/packages/pi-coding-agent/dist/core/agent-session-model-switch.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +99 -31
  278. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js +21 -16
  282. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.d.ts.map +1 -0
  285. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js +130 -0
  286. package/packages/pi-coding-agent/dist/core/compaction-orchestrator.test.js.map +1 -0
  287. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts +5 -0
  288. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/extensions/loader.js +61 -0
  290. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js +30 -4
  292. package/packages/pi-coding-agent/dist/core/lsp/lsp-integration.test.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js +17 -0
  294. package/packages/pi-coding-agent/dist/core/model-registry-auth-mode.test.js.map +1 -1
  295. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js +76 -18
  296. package/packages/pi-coding-agent/dist/core/resource-loader-cache-reset.test.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/core/retry-handler.d.ts.map +1 -1
  298. package/packages/pi-coding-agent/dist/core/retry-handler.js +2 -6
  299. package/packages/pi-coding-agent/dist/core/retry-handler.js.map +1 -1
  300. package/packages/pi-coding-agent/dist/core/retry-handler.test.js +5 -1
  301. package/packages/pi-coding-agent/dist/core/retry-handler.test.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts +18 -0
  303. package/packages/pi-coding-agent/dist/core/retryable-error-regex.d.ts.map +1 -0
  304. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js +18 -0
  305. package/packages/pi-coding-agent/dist/core/retryable-error-regex.js.map +1 -0
  306. package/packages/pi-coding-agent/dist/core/sdk.d.ts +1 -0
  307. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  308. package/packages/pi-coding-agent/dist/core/sdk.js +4 -1
  309. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  310. package/packages/pi-coding-agent/dist/core/sdk.test.js +19 -1
  311. package/packages/pi-coding-agent/dist/core/sdk.test.js.map +1 -1
  312. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +20 -0
  313. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/core/system-prompt.js +16 -2
  315. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/index.d.ts +1 -0
  317. package/packages/pi-coding-agent/dist/index.d.ts.map +1 -1
  318. package/packages/pi-coding-agent/dist/index.js +1 -0
  319. package/packages/pi-coding-agent/dist/index.js.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js +15 -6
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/provider-display-name.test.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +36 -5
  323. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  324. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js +20 -13
  325. package/packages/pi-coding-agent/dist/modes/interactive/components/dynamic-border.test.js.map +1 -1
  326. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +14 -5
  328. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  329. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts +7 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js +31 -9
  332. package/packages/pi-coding-agent/dist/modes/interactive/components/model-selector.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  334. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +30 -12
  335. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  336. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.d.ts.map +1 -1
  337. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js +18 -3
  338. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.js.map +1 -1
  339. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +125 -0
  340. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  341. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +2 -0
  342. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  343. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  344. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +4 -0
  345. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  346. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +105 -13
  347. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  348. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts +2 -0
  349. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.d.ts.map +1 -0
  350. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js +130 -0
  351. package/packages/pi-coding-agent/dist/tests/system-prompt-skill-filter.test.js.map +1 -0
  352. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +113 -37
  353. package/packages/pi-coding-agent/src/core/agent-session-model-switch.test.ts +89 -17
  354. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +112 -43
  355. package/packages/pi-coding-agent/src/core/compaction-orchestrator.test.ts +154 -0
  356. package/packages/pi-coding-agent/src/core/compaction-orchestrator.ts +24 -17
  357. package/packages/pi-coding-agent/src/core/extensions/loader.ts +58 -0
  358. package/packages/pi-coding-agent/src/core/lsp/lsp-integration.test.ts +35 -4
  359. package/packages/pi-coding-agent/src/core/model-registry-auth-mode.test.ts +20 -0
  360. package/packages/pi-coding-agent/src/core/resource-loader-cache-reset.test.ts +93 -28
  361. package/packages/pi-coding-agent/src/core/retry-handler.test.ts +5 -1
  362. package/packages/pi-coding-agent/src/core/retry-handler.ts +2 -8
  363. package/packages/pi-coding-agent/src/core/retryable-error-regex.ts +18 -0
  364. package/packages/pi-coding-agent/src/core/sdk.test.ts +25 -1
  365. package/packages/pi-coding-agent/src/core/sdk.ts +10 -3
  366. package/packages/pi-coding-agent/src/core/system-prompt.ts +35 -1
  367. package/packages/pi-coding-agent/src/index.ts +1 -0
  368. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/provider-display-name.test.ts +17 -7
  369. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +49 -3
  370. package/packages/pi-coding-agent/src/modes/interactive/components/dynamic-border.test.ts +26 -20
  371. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +14 -5
  372. package/packages/pi-coding-agent/src/modes/interactive/components/model-selector.ts +45 -11
  373. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +48 -9
  374. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +146 -1
  375. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.ts +20 -3
  376. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +2 -0
  377. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +119 -13
  378. package/packages/pi-coding-agent/src/tests/system-prompt-skill-filter.test.ts +157 -0
  379. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  380. package/packages/pi-tui/dist/__tests__/autocomplete.test.js +18 -8
  381. package/packages/pi-tui/dist/__tests__/autocomplete.test.js.map +1 -1
  382. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js +128 -17
  383. package/packages/pi-tui/dist/__tests__/overlay-layout.test.js.map +1 -1
  384. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js +51 -6
  385. package/packages/pi-tui/dist/__tests__/stdin-buffer.test.js.map +1 -1
  386. package/packages/pi-tui/dist/__tests__/tui.test.js +18 -30
  387. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  388. package/packages/pi-tui/dist/components/__tests__/input.test.js +10 -3
  389. package/packages/pi-tui/dist/components/__tests__/input.test.js.map +1 -1
  390. package/packages/pi-tui/dist/components/__tests__/loader.test.js +53 -9
  391. package/packages/pi-tui/dist/components/__tests__/loader.test.js.map +1 -1
  392. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js +6 -2
  393. package/packages/pi-tui/dist/components/__tests__/markdown-maxlines.test.js.map +1 -1
  394. package/packages/pi-tui/dist/components/editor.d.ts +14 -0
  395. package/packages/pi-tui/dist/components/editor.d.ts.map +1 -1
  396. package/packages/pi-tui/dist/components/editor.js +19 -0
  397. package/packages/pi-tui/dist/components/editor.js.map +1 -1
  398. package/packages/pi-tui/dist/components/image.test.js +6 -5
  399. package/packages/pi-tui/dist/components/image.test.js.map +1 -1
  400. package/packages/pi-tui/dist/editor-component.d.ts +2 -0
  401. package/packages/pi-tui/dist/editor-component.d.ts.map +1 -1
  402. package/packages/pi-tui/dist/editor-component.js.map +1 -1
  403. package/packages/pi-tui/dist/stdin-buffer.d.ts +7 -0
  404. package/packages/pi-tui/dist/stdin-buffer.d.ts.map +1 -1
  405. package/packages/pi-tui/dist/stdin-buffer.js +20 -0
  406. package/packages/pi-tui/dist/stdin-buffer.js.map +1 -1
  407. package/packages/pi-tui/src/__tests__/autocomplete.test.ts +24 -8
  408. package/packages/pi-tui/src/__tests__/overlay-layout.test.ts +140 -17
  409. package/packages/pi-tui/src/__tests__/stdin-buffer.test.ts +62 -6
  410. package/packages/pi-tui/src/__tests__/tui.test.ts +18 -37
  411. package/packages/pi-tui/src/components/__tests__/input.test.ts +19 -3
  412. package/packages/pi-tui/src/components/__tests__/loader.test.ts +112 -35
  413. package/packages/pi-tui/src/components/__tests__/markdown-maxlines.test.ts +9 -2
  414. package/packages/pi-tui/src/components/editor.ts +22 -0
  415. package/packages/pi-tui/src/components/image.test.ts +10 -5
  416. package/packages/pi-tui/src/editor-component.ts +3 -0
  417. package/packages/pi-tui/src/stdin-buffer.ts +26 -0
  418. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  419. package/packages/rpc-client/dist/rpc-client.test.js +101 -51
  420. package/packages/rpc-client/dist/rpc-client.test.js.map +1 -1
  421. package/packages/rpc-client/src/rpc-client.test.ts +109 -52
  422. package/packages/rpc-client/tsconfig.tsbuildinfo +1 -1
  423. package/scripts/install.js +15 -1
  424. package/src/resources/extensions/browser-tools/capture.ts +12 -0
  425. package/src/resources/extensions/browser-tools/tests/browser-tools-integration.test.mjs +8 -59
  426. package/src/resources/extensions/browser-tools/tests/browser-tools-unit.test.cjs +36 -24
  427. package/src/resources/extensions/browser-tools/tests/capture-sharp-optional.test.cjs +69 -71
  428. package/src/resources/extensions/browser-tools/tools/forms.ts +5 -1
  429. package/src/resources/extensions/browser-tools/tools/intent.ts +5 -1
  430. package/src/resources/extensions/claude-code-cli/readiness.ts +5 -1
  431. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +532 -29
  432. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +941 -91
  433. package/src/resources/extensions/github-sync/templates.ts +151 -0
  434. package/src/resources/extensions/github-sync/tests/cli.test.ts +76 -7
  435. package/src/resources/extensions/github-sync/tests/templates.test.ts +92 -1
  436. package/src/resources/extensions/google-search/index.ts +3 -2
  437. package/src/resources/extensions/gsd/abandon-detect.ts +62 -0
  438. package/src/resources/extensions/gsd/auto/loop.ts +142 -2
  439. package/src/resources/extensions/gsd/auto/phases.ts +62 -38
  440. package/src/resources/extensions/gsd/auto/resolve.ts +29 -0
  441. package/src/resources/extensions/gsd/auto/run-unit.ts +16 -2
  442. package/src/resources/extensions/gsd/auto/session.ts +7 -2
  443. package/src/resources/extensions/gsd/auto/turn-epoch.ts +108 -0
  444. package/src/resources/extensions/gsd/auto-dispatch.ts +176 -29
  445. package/src/resources/extensions/gsd/auto-loop.ts +1 -1
  446. package/src/resources/extensions/gsd/auto-model-selection.ts +131 -4
  447. package/src/resources/extensions/gsd/auto-post-unit.ts +193 -73
  448. package/src/resources/extensions/gsd/auto-prompts.ts +385 -93
  449. package/src/resources/extensions/gsd/auto-recovery.ts +230 -51
  450. package/src/resources/extensions/gsd/auto-start.ts +127 -9
  451. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +12 -5
  452. package/src/resources/extensions/gsd/auto-tool-tracking.ts +51 -7
  453. package/src/resources/extensions/gsd/auto-unit-closeout.ts +14 -3
  454. package/src/resources/extensions/gsd/auto-worktree.ts +190 -31
  455. package/src/resources/extensions/gsd/auto.ts +95 -23
  456. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +20 -1
  457. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +221 -0
  458. package/src/resources/extensions/gsd/bootstrap/provider-error-resume.ts +6 -6
  459. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +7 -3
  460. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +158 -9
  461. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +27 -8
  462. package/src/resources/extensions/gsd/component-loader.ts +598 -0
  463. package/src/resources/extensions/gsd/component-types.ts +362 -0
  464. package/src/resources/extensions/gsd/context-store.ts +25 -8
  465. package/src/resources/extensions/gsd/detection.ts +58 -1
  466. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -20
  467. package/src/resources/extensions/gsd/docs/preferences-reference.md +1 -1
  468. package/src/resources/extensions/gsd/file-lock.ts +84 -11
  469. package/src/resources/extensions/gsd/forensics.ts +118 -1
  470. package/src/resources/extensions/gsd/gate-registry.ts +2 -2
  471. package/src/resources/extensions/gsd/git-constants.ts +30 -1
  472. package/src/resources/extensions/gsd/git-self-heal.ts +31 -0
  473. package/src/resources/extensions/gsd/git-service.ts +150 -2
  474. package/src/resources/extensions/gsd/gitignore.ts +1 -0
  475. package/src/resources/extensions/gsd/gsd-db.ts +6 -3
  476. package/src/resources/extensions/gsd/guided-flow-queue.ts +4 -1
  477. package/src/resources/extensions/gsd/guided-flow.ts +57 -14
  478. package/src/resources/extensions/gsd/journal.ts +38 -3
  479. package/src/resources/extensions/gsd/memory-extractor.ts +11 -3
  480. package/src/resources/extensions/gsd/milestone-actions.ts +18 -0
  481. package/src/resources/extensions/gsd/milestone-scope-classifier.ts +366 -0
  482. package/src/resources/extensions/gsd/milestone-summary-classifier.ts +42 -0
  483. package/src/resources/extensions/gsd/model-cost-table.ts +3 -0
  484. package/src/resources/extensions/gsd/model-router.ts +6 -0
  485. package/src/resources/extensions/gsd/native-git-bridge.ts +34 -4
  486. package/src/resources/extensions/gsd/preferences-validation.ts +21 -0
  487. package/src/resources/extensions/gsd/prompt-cache-optimizer.ts +4 -0
  488. package/src/resources/extensions/gsd/prompts/complete-milestone.md +6 -2
  489. package/src/resources/extensions/gsd/prompts/discuss-headless.md +23 -4
  490. package/src/resources/extensions/gsd/prompts/doctor-heal.md +5 -4
  491. package/src/resources/extensions/gsd/prompts/plan-slice.md +15 -2
  492. package/src/resources/extensions/gsd/reports.ts +5 -4
  493. package/src/resources/extensions/gsd/safety/git-checkpoint.ts +15 -0
  494. package/src/resources/extensions/gsd/service-tier.ts +5 -2
  495. package/src/resources/extensions/gsd/session-lock.ts +20 -10
  496. package/src/resources/extensions/gsd/skill-manifest.ts +175 -0
  497. package/src/resources/extensions/gsd/slice-cadence.ts +299 -0
  498. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +309 -8
  499. package/src/resources/extensions/gsd/state-transition-matrix.ts +152 -0
  500. package/src/resources/extensions/gsd/state.ts +76 -66
  501. package/src/resources/extensions/gsd/sync-lock.ts +97 -39
  502. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +270 -0
  503. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +2 -1
  504. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +341 -0
  505. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +264 -0
  506. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +135 -285
  507. package/src/resources/extensions/gsd/tests/auto-mode-guards.test.ts +79 -0
  508. package/src/resources/extensions/gsd/tests/auto-model-selection-tool-poisoning.test.ts +742 -0
  509. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +78 -0
  510. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +61 -0
  511. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +93 -0
  512. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +4 -1
  513. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +8 -194
  514. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +3 -2
  515. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +2 -2
  516. package/src/resources/extensions/gsd/tests/auto-start-needs-discussion.test.ts +15 -58
  517. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +2 -2
  518. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +3 -2
  519. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +3 -2
  520. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +2 -1
  521. package/src/resources/extensions/gsd/tests/cache-staleness-regression.test.ts +17 -21
  522. package/src/resources/extensions/gsd/tests/canonical-milestone-root.test.ts +108 -0
  523. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +263 -0
  524. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +25 -0
  525. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +192 -0
  526. package/src/resources/extensions/gsd/tests/complete-slice-verification-gate.test.ts +2 -1
  527. package/src/resources/extensions/gsd/tests/complete-task.test.ts +16 -8
  528. package/src/resources/extensions/gsd/tests/component-loader.test.ts +589 -0
  529. package/src/resources/extensions/gsd/tests/component-types.test.ts +127 -0
  530. package/src/resources/extensions/gsd/tests/context-store.test.ts +79 -0
  531. package/src/resources/extensions/gsd/tests/copy-planning-artifacts-samepath.test.ts +2 -1
  532. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +50 -1
  533. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +159 -0
  534. package/src/resources/extensions/gsd/tests/db-access-guardrails.test.ts +1 -0
  535. package/src/resources/extensions/gsd/tests/derive-state-crossval.test.ts +3 -3
  536. package/src/resources/extensions/gsd/tests/derive-state-db-disk-reconcile.test.ts +40 -0
  537. package/src/resources/extensions/gsd/tests/derive-state-db.test.ts +91 -3
  538. package/src/resources/extensions/gsd/tests/derive-state.test.ts +4 -4
  539. package/src/resources/extensions/gsd/tests/discuss-slice-structured-questions.test.ts +2 -1
  540. package/src/resources/extensions/gsd/tests/discuss-tool-scope-leak.test.ts +2 -1
  541. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +5 -0
  542. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +25 -0
  543. package/src/resources/extensions/gsd/tests/dispatch-missing-task-plans.test.ts +14 -0
  544. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +3 -2
  545. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +4 -3
  546. package/src/resources/extensions/gsd/tests/empty-content-abort-loop.test.ts +4 -3
  547. package/src/resources/extensions/gsd/tests/execution-entry-missing-context-4671.test.ts +173 -0
  548. package/src/resources/extensions/gsd/tests/extension-bootstrap-isolation.test.ts +139 -129
  549. package/src/resources/extensions/gsd/tests/file-lock.test.ts +86 -12
  550. package/src/resources/extensions/gsd/tests/finalize-timeout-guard.test.ts +8 -104
  551. package/src/resources/extensions/gsd/tests/gate-state-canonicalization.test.ts +102 -0
  552. package/src/resources/extensions/gsd/tests/gate-storage.test.ts +1 -1
  553. package/src/resources/extensions/gsd/tests/google-search-stub.test.ts +14 -4
  554. package/src/resources/extensions/gsd/tests/headless-milestone-parity.test.ts +117 -0
  555. package/src/resources/extensions/gsd/tests/hook-key-parsing.test.ts +4 -55
  556. package/src/resources/extensions/gsd/tests/integration/all-milestones-complete-merge.test.ts +7 -56
  557. package/src/resources/extensions/gsd/tests/integration/auto-recovery.test.ts +20 -0
  558. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +30 -0
  559. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +18 -2
  560. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +3 -2
  561. package/src/resources/extensions/gsd/tests/integration/queue-completed-milestone-perf.test.ts +10 -4
  562. package/src/resources/extensions/gsd/tests/integration/state-machine-edge-cases.test.ts +144 -7
  563. package/src/resources/extensions/gsd/tests/integration/state-machine-live-validation.test.ts +4 -0
  564. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +2 -16
  565. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +9 -3
  566. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +6 -9
  567. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +64 -0
  568. package/src/resources/extensions/gsd/tests/knowledge.test.ts +93 -1
  569. package/src/resources/extensions/gsd/tests/mcp-client-security.test.ts +47 -0
  570. package/src/resources/extensions/gsd/tests/memory-extractor.test.ts +5 -15
  571. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +227 -55
  572. package/src/resources/extensions/gsd/tests/milestone-scope-classifier.test.ts +187 -0
  573. package/src/resources/extensions/gsd/tests/milestone-summary-classifier.test.ts +30 -0
  574. package/src/resources/extensions/gsd/tests/model-cost-table.test.ts +9 -1
  575. package/src/resources/extensions/gsd/tests/model-router.test.ts +1 -1
  576. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +6 -48
  577. package/src/resources/extensions/gsd/tests/notification-widget.test.ts +6 -3
  578. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +59 -2
  579. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +273 -130
  580. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +301 -0
  581. package/src/resources/extensions/gsd/tests/pre-execution-pause-wiring.test.ts +32 -1
  582. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +2 -1
  583. package/src/resources/extensions/gsd/tests/prompt-cache-optimizer.test.ts +12 -0
  584. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +15 -4
  585. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +54 -41
  586. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +213 -0
  587. package/src/resources/extensions/gsd/tests/queue-draft-detection.test.ts +3 -2
  588. package/src/resources/extensions/gsd/tests/queued-discuss-fast-path.test.ts +4 -5
  589. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +13 -7
  590. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +75 -2
  591. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +132 -0
  592. package/src/resources/extensions/gsd/tests/recovery-attempts-reset.test.ts +8 -40
  593. package/src/resources/extensions/gsd/tests/regex-hardening.test.ts +136 -256
  594. package/src/resources/extensions/gsd/tests/require-slice-discussion-dispatch.test.ts +170 -0
  595. package/src/resources/extensions/gsd/tests/research-milestone-composer.test.ts +114 -0
  596. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +6 -3
  597. package/src/resources/extensions/gsd/tests/rewrite-docs-abandon-detect.test.ts +195 -0
  598. package/src/resources/extensions/gsd/tests/run-uat-composer.test.ts +148 -0
  599. package/src/resources/extensions/gsd/tests/service-tier.test.ts +4 -0
  600. package/src/resources/extensions/gsd/tests/session-lock-regression.test.ts +29 -0
  601. package/src/resources/extensions/gsd/tests/sidecar-queue.test.ts +3 -2
  602. package/src/resources/extensions/gsd/tests/silent-catch-diagnostics.test.ts +55 -95
  603. package/src/resources/extensions/gsd/tests/single-writer-v3-tool-surface.test.ts +158 -0
  604. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +120 -1
  605. package/src/resources/extensions/gsd/tests/skill-manifest.test.ts +112 -0
  606. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +242 -0
  607. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +3 -2
  608. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +164 -1
  609. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +2 -1
  610. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +112 -0
  611. package/src/resources/extensions/gsd/tests/state-machine-full-walkthrough.test.ts +29 -5
  612. package/src/resources/extensions/gsd/tests/state-transition-matrix.test.ts +44 -0
  613. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +3 -3
  614. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +11 -92
  615. package/src/resources/extensions/gsd/tests/stuck-detection-coverage.test.ts +2 -2
  616. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +7 -6
  617. package/src/resources/extensions/gsd/tests/survivor-branch-complete.test.ts +102 -101
  618. package/src/resources/extensions/gsd/tests/sync-lock.test.ts +31 -0
  619. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +4 -3
  620. package/src/resources/extensions/gsd/tests/test-helpers.test.ts +98 -0
  621. package/src/resources/extensions/gsd/tests/test-helpers.ts +153 -0
  622. package/src/resources/extensions/gsd/tests/token-profile.test.ts +8 -1
  623. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +61 -1
  624. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +8 -1
  625. package/src/resources/extensions/gsd/tests/triage-resolution.test.ts +50 -2
  626. package/src/resources/extensions/gsd/tests/turn-epoch.test.ts +162 -0
  627. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +355 -0
  628. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +258 -0
  629. package/src/resources/extensions/gsd/tests/uok-contracts.test.ts +51 -0
  630. package/src/resources/extensions/gsd/tests/uok-execution-graph.test.ts +16 -0
  631. package/src/resources/extensions/gsd/tests/uok-gate-runner.test.ts +75 -0
  632. package/src/resources/extensions/gsd/tests/uok-gitops-wiring.test.ts +49 -26
  633. package/src/resources/extensions/gsd/tests/uok-loop-adapter-writer.test.ts +65 -0
  634. package/src/resources/extensions/gsd/tests/uok-parity-report.test.ts +42 -0
  635. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +19 -2
  636. package/src/resources/extensions/gsd/tests/uok-writer.test.ts +75 -0
  637. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +12 -0
  638. package/src/resources/extensions/gsd/tests/verify-artifact-tightened.test.ts +144 -80
  639. package/src/resources/extensions/gsd/tests/visualizer-critical-path.test.ts +20 -54
  640. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +342 -277
  641. package/src/resources/extensions/gsd/tests/worker-model-override.test.ts +37 -29
  642. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +226 -266
  643. package/src/resources/extensions/gsd/tests/worktree-health-monorepo.test.ts +103 -67
  644. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +92 -90
  645. package/src/resources/extensions/gsd/tests/worktree-submodule-safety.test.ts +238 -59
  646. package/src/resources/extensions/gsd/tests/worktree-sync-overwrite-loop.test.ts +113 -161
  647. package/src/resources/extensions/gsd/tests/worktree-telemetry.test.ts +210 -0
  648. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +262 -0
  649. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +186 -0
  650. package/src/resources/extensions/gsd/tests/write-gate.test.ts +7 -5
  651. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +80 -96
  652. package/src/resources/extensions/gsd/tools/complete-slice.ts +38 -0
  653. package/src/resources/extensions/gsd/tools/complete-task.ts +49 -0
  654. package/src/resources/extensions/gsd/tools/validate-milestone.ts +8 -2
  655. package/src/resources/extensions/gsd/types.ts +3 -3
  656. package/src/resources/extensions/gsd/unit-context-composer.ts +218 -0
  657. package/src/resources/extensions/gsd/unit-context-manifest.ts +574 -0
  658. package/src/resources/extensions/gsd/uok/audit.ts +20 -2
  659. package/src/resources/extensions/gsd/uok/contracts.ts +65 -0
  660. package/src/resources/extensions/gsd/uok/dispatch-envelope.ts +56 -0
  661. package/src/resources/extensions/gsd/uok/execution-graph.ts +22 -0
  662. package/src/resources/extensions/gsd/uok/gate-runner.ts +65 -5
  663. package/src/resources/extensions/gsd/uok/gitops.ts +6 -1
  664. package/src/resources/extensions/gsd/uok/loop-adapter.ts +45 -10
  665. package/src/resources/extensions/gsd/uok/parity-report.ts +84 -0
  666. package/src/resources/extensions/gsd/uok/plan-v2.ts +13 -5
  667. package/src/resources/extensions/gsd/uok/writer.ts +113 -0
  668. package/src/resources/extensions/gsd/workflow-logger.ts +22 -3
  669. package/src/resources/extensions/gsd/workflow-mcp.ts +6 -0
  670. package/src/resources/extensions/gsd/worktree-manager.ts +109 -7
  671. package/src/resources/extensions/gsd/worktree-resolver.ts +96 -9
  672. package/src/resources/extensions/gsd/worktree-telemetry.ts +322 -0
  673. package/src/resources/extensions/mcp-client/auth.ts +12 -1
  674. package/src/resources/extensions/mcp-client/index.ts +132 -11
  675. package/src/resources/extensions/mcp-client/tests/server-name-spaces.test.ts +70 -36
  676. package/src/resources/extensions/ollama/index.ts +5 -1
  677. package/src/resources/extensions/ollama/ollama-auth-mode.test.ts +123 -15
  678. package/src/resources/extensions/ollama/ollama-status-indicator.test.ts +206 -19
  679. package/src/resources/extensions/remote-questions/manager.ts +36 -4
  680. package/src/resources/extensions/remote-questions/tests/command-polling.test.ts +200 -190
  681. package/src/resources/extensions/shared/tests/interview-preview.test.ts +11 -3
  682. package/src/resources/extensions/voice/tests/linux-ready.test.ts +129 -113
  683. package/src/resources/skills/create-skill/SKILL.md +2 -2
  684. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +4 -4
  685. package/src/resources/skills/create-skill/workflows/audit-skill.md +4 -4
  686. package/src/resources/skills/create-skill/workflows/create-new-skill.md +5 -5
  687. package/dist/web/standalone/.next/server/chunks/7461.js +0 -1
  688. package/dist/web/standalone/.next/static/chunks/2826.d445fb428ef41fa1.js +0 -9
  689. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts +0 -2
  690. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.d.ts.map +0 -1
  691. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js +0 -289
  692. package/packages/pi-ai/dist/utils/oauth/oauth-providers.test.js.map +0 -1
  693. package/packages/pi-ai/src/utils/oauth/oauth-providers.test.ts +0 -363
  694. package/src/resources/extensions/gsd/tests/auto-start-model-capture.test.ts +0 -143
  695. package/src/resources/extensions/gsd/tests/complete-milestone-false-merge.test.ts +0 -157
  696. package/src/resources/extensions/gsd/tests/dashboard-model-label-ordering.test.ts +0 -107
  697. package/src/resources/extensions/gsd/tests/find-missing-summaries-closed.test.ts +0 -48
  698. package/src/resources/extensions/gsd/tests/forensics-context-persist.test.ts +0 -159
  699. package/src/resources/extensions/gsd/tests/forensics-db-completion.test.ts +0 -96
  700. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +0 -79
  701. package/src/resources/extensions/gsd/tests/forensics-hook-key-parse.test.ts +0 -74
  702. package/src/resources/extensions/gsd/tests/forensics-journal.test.ts +0 -162
  703. package/src/resources/extensions/gsd/tests/gitignore-bg-shell.test.ts +0 -38
  704. package/src/resources/extensions/gsd/tests/gsd-no-project-error.test.ts +0 -73
  705. package/src/resources/extensions/gsd/tests/idle-watchdog-stall-override.test.ts +0 -125
  706. package/src/resources/extensions/gsd/tests/import-done-milestones.test.ts +0 -42
  707. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_buildManifest.js +0 -0
  708. /package/dist/web/standalone/.next/static/{H51SzzS_EEgdBsDVhrLBv → SvCJDZPQW104bR1KnBQg1}/_ssgManifest.js +0 -0
@@ -12,8 +12,18 @@
12
12
  * - Silent failure: journal writes never throw — absence of events is the failure signal
13
13
  */
14
14
 
15
- import { appendFileSync, mkdirSync, readdirSync, readFileSync } from "node:fs";
15
+ import {
16
+ appendFileSync,
17
+ closeSync,
18
+ existsSync,
19
+ mkdirSync,
20
+ openSync,
21
+ readdirSync,
22
+ readFileSync,
23
+ } from "node:fs";
16
24
  import { join } from "node:path";
25
+ import { isStaleWrite } from "./auto/turn-epoch.js";
26
+ import { withFileLockSync } from "./file-lock.js";
17
27
  import { gsdRoot } from "./paths.js";
18
28
  import { buildAuditEnvelope, emitUokAuditEvent } from "./uok/audit.js";
19
29
  import { isUnifiedAuditEnabled } from "./uok/audit-toggle.js";
@@ -40,7 +50,17 @@ export type JournalEventType =
40
50
  | "worktree-skip"
41
51
  | "worktree-merge-start"
42
52
  | "worktree-merge-failed"
43
- | "artifact-verification-retry";
53
+ | "artifact-verification-retry"
54
+ // #4764 — worktree lifespan / divergence telemetry
55
+ | "worktree-created"
56
+ | "worktree-merged"
57
+ | "worktree-orphaned"
58
+ | "auto-exit"
59
+ | "worktree-sync"
60
+ | "canonical-root-redirect"
61
+ // #4765 — slice-cadence collapse
62
+ | "slice-merged"
63
+ | "milestone-resquash";
44
64
 
45
65
  /** A single structured event in the journal. */
46
66
  export interface JournalEntry {
@@ -84,12 +104,27 @@ export interface JournalQueryFilters {
84
104
  * Never throws — all errors are silently caught.
85
105
  */
86
106
  export function emitJournalEvent(basePath: string, entry: JournalEntry): void {
107
+ // Drop writes from a turn superseded by timeout recovery / cancellation.
108
+ // See auto/turn-epoch.ts for the full rationale.
109
+ if (isStaleWrite("journal")) return;
87
110
  try {
88
111
  const journalDir = join(gsdRoot(basePath), "journal");
89
112
  mkdirSync(journalDir, { recursive: true });
90
113
  const dateStr = entry.ts.slice(0, 10);
91
114
  const filePath = join(journalDir, `${dateStr}.jsonl`);
92
- appendFileSync(filePath, JSON.stringify(entry) + "\n");
115
+ // Ensure file exists so proper-lockfile can acquire a lock against it.
116
+ if (!existsSync(filePath)) closeSync(openSync(filePath, "a"));
117
+ // onLocked: "skip" — journal writes are best-effort. POSIX O_APPEND
118
+ // atomicity still protects small entries; the lock mainly serializes
119
+ // larger writes and gives cross-process exclusivity on platforms where
120
+ // O_APPEND semantics are weaker (Windows).
121
+ withFileLockSync(
122
+ filePath,
123
+ () => {
124
+ appendFileSync(filePath, JSON.stringify(entry) + "\n");
125
+ },
126
+ { onLocked: "skip" },
127
+ );
93
128
  } catch {
94
129
  // Silent failure — journal must never break auto-mode
95
130
  }
@@ -18,7 +18,10 @@ import type { MemoryAction } from './memory-store.js';
18
18
 
19
19
  // ─── Types ──────────────────────────────────────────────────────────────────
20
20
 
21
- export type LLMCallFn = (system: string, user: string) => Promise<string>;
21
+ export type LLMCallFn = ((system: string, user: string) => Promise<string>) & {
22
+ /** Promise resolving once the provider API key has been fetched (for tests). */
23
+ apiKeyReady?: Promise<string | undefined>;
24
+ };
22
25
 
23
26
  // ─── Concurrency Guard ──────────────────────────────────────────────────────
24
27
 
@@ -92,8 +95,9 @@ export function buildMemoryLLMCall(ctx: ExtensionContext): LLMCallFn | null {
92
95
  // which returns undefined for OAuth users (Claude Max / Claude Pro).
93
96
  // See: https://github.com/gsd-build/gsd-2/issues/2959
94
97
  const resolvedKeyPromise = ctx.modelRegistry.getApiKey(selectedModel).catch(() => undefined);
95
-
96
- return async (system: string, user: string): Promise<string> => {
98
+ // Expose on the returned fn so tests can await resolution deterministically
99
+ // (avoids arbitrary setTimeout polling for an internal microtask).
100
+ const llmCall = async (system: string, user: string): Promise<string> => {
97
101
  const { completeSimple } = await import('@gsd/pi-ai');
98
102
  const resolvedApiKey = await resolvedKeyPromise;
99
103
  const result: AssistantMessage = await completeSimple(selectedModel, {
@@ -111,6 +115,10 @@ export function buildMemoryLLMCall(ctx: ExtensionContext): LLMCallFn | null {
111
115
  .map(c => c.text);
112
116
  return textParts.join('');
113
117
  };
118
+ // Attach the in-flight API-key resolution so tests (and callers) can
119
+ // `await llmCall.apiKeyReady` rather than relying on setTimeout polling.
120
+ (llmCall as LLMCallFn & { apiKeyReady?: Promise<string | undefined> }).apiKeyReady = resolvedKeyPromise;
121
+ return llmCall;
114
122
  } catch {
115
123
  return null;
116
124
  }
@@ -23,6 +23,21 @@ import { loadQueueOrder, saveQueueOrder } from "./queue-order.js";
23
23
  import { deleteMilestone, getMilestone, isDbAvailable, updateMilestoneStatus } from "./gsd-db.js";
24
24
  import { removeWorktree } from "./worktree-manager.js";
25
25
  import { logWarning } from "./workflow-logger.js";
26
+ import { isAutoActive } from "./auto.js";
27
+
28
+ /**
29
+ * Writer-side assert for mutations that race with auto-mode's squash merge (#4704).
30
+ * Auto-mode is confirmed not to call parkMilestone/discardMilestone/unparkMilestone
31
+ * internally — these throws only surface invariant violations from new or forgotten
32
+ * call sites, which is the correct failure mode to catch loudly.
33
+ */
34
+ function assertNotAutoActive(action: string): void {
35
+ if (isAutoActive()) {
36
+ throw new Error(
37
+ `${action} cannot run while auto-mode is active. Stop auto-mode first with /gsd stop.`,
38
+ );
39
+ }
40
+ }
26
41
 
27
42
  // ─── Park ──────────────────────────────────────────────────────────────────
28
43
 
@@ -32,6 +47,7 @@ import { logWarning } from "./workflow-logger.js";
32
47
  * Returns true if successfully parked, false if milestone not found or already parked.
33
48
  */
34
49
  export function parkMilestone(basePath: string, milestoneId: string, reason: string): boolean {
50
+ assertNotAutoActive("park milestone");
35
51
  const mDir = resolveMilestonePath(basePath, milestoneId);
36
52
  if (!mDir || !existsSync(mDir)) return false;
37
53
 
@@ -74,6 +90,7 @@ export function parkMilestone(basePath: string, milestoneId: string, reason: str
74
90
  * Returns true if successfully unparked, false if milestone not found or not parked.
75
91
  */
76
92
  export function unparkMilestone(basePath: string, milestoneId: string): boolean {
93
+ assertNotAutoActive("unpark milestone");
77
94
  const mDir = resolveMilestonePath(basePath, milestoneId);
78
95
  if (!mDir || !existsSync(mDir)) return false;
79
96
 
@@ -108,6 +125,7 @@ export function unparkMilestone(basePath: string, milestoneId: string): boolean
108
125
  * Returns true if successfully discarded, false if milestone not found.
109
126
  */
110
127
  export function discardMilestone(basePath: string, milestoneId: string): boolean {
128
+ assertNotAutoActive("discard milestone");
111
129
  const mDir = resolveMilestonePath(basePath, milestoneId);
112
130
  if (!mDir || !existsSync(mDir)) return false;
113
131
 
@@ -0,0 +1,366 @@
1
+ // GSD-2 — Milestone scope classifier (#4781 / ADR-003 companion).
2
+ //
3
+ // Pure heuristics over milestone planning fields. Produces a PipelineVariant
4
+ // that downstream dispatch logic can use to shape the auto-mode sequence.
5
+ // No LLM calls, no file I/O, sub-millisecond.
6
+ //
7
+ // Distinct from `complexity-classifier.ts`, which decides *model tier*
8
+ // (light/standard/heavy) for an individual unit. This module decides
9
+ // *pipeline topology* for an entire milestone at plan-milestone time.
10
+ //
11
+ // This file ships the classifier in isolation. Dispatch-side wiring
12
+ // lands in follow-up PRs so the classification contract can be reviewed
13
+ // and tested before any behavior change reaches users.
14
+
15
+ export type PipelineVariant = "trivial" | "standard" | "complex";
16
+
17
+ export interface MilestoneScopeInput {
18
+ /** Milestone vision / elevator pitch. Free-form prose. */
19
+ vision?: string;
20
+ /** Success criteria, one per array entry. */
21
+ successCriteria?: string[];
22
+ /** Milestone title. */
23
+ title?: string;
24
+ /** Slice risks declared at plan-milestone time. */
25
+ keyRisks?: Array<{ risk?: string; whyItMatters?: string }>;
26
+ /** Definition-of-done lines. */
27
+ definitionOfDone?: string[];
28
+ /** Freeform "requirement coverage" marker. */
29
+ requirementCoverage?: string;
30
+ /** Verification hints (contract/integration/operational/uat). */
31
+ verificationContract?: string;
32
+ verificationIntegration?: string;
33
+ verificationOperational?: string;
34
+ verificationUat?: string;
35
+ }
36
+
37
+ export interface ScopeClassificationResult {
38
+ variant: PipelineVariant;
39
+ /** Short human-readable reasons, one per triggered signal. */
40
+ reasons: string[];
41
+ /** Sub-signals for telemetry / debugging. Stable across releases. */
42
+ signals: {
43
+ triggeredOverride: boolean;
44
+ complexCount: number;
45
+ trivialCount: number;
46
+ fileCountHint: number | null;
47
+ };
48
+ }
49
+
50
+ // ─── Keyword sets ─────────────────────────────────────────────────────────
51
+
52
+ /**
53
+ * Override keywords that force `standard` (at minimum) regardless of
54
+ * apparent triviality. Presence of any of these signals work that is
55
+ * either security-sensitive, irreversible, or requires runtime verification
56
+ * a "trivial" pipeline would skip.
57
+ *
58
+ * Matched as case-insensitive word-boundary substrings. Conservative — err
59
+ * on the side of including a keyword; over-classifying to `standard` costs
60
+ * units, under-classifying could ship broken auth/security/migration work.
61
+ */
62
+ const OVERRIDE_KEYWORDS: ReadonlyArray<string> = [
63
+ // Security-sensitive
64
+ "security", "auth", "authn", "authz", "authentication", "authorization",
65
+ "credential", "secret", "password", "token", "oauth", "encrypt", "decrypt",
66
+ "vulnerability", "exploit", "permission", "rbac", "acl",
67
+ // Data-migration / irreversible
68
+ "migration", "migrate", "schema change", "data migration",
69
+ "backfill", "drop column", "drop table",
70
+ // Compliance / regulatory
71
+ "compliance", "gdpr", "hipaa", "soc2", "pci",
72
+ // Infra / deploy — runtime verification needed
73
+ "deploy", "rollout", "canary", "production database",
74
+ ];
75
+
76
+ /**
77
+ * Keywords that contribute to `complex` classification on their own.
78
+ * Different from OVERRIDE_KEYWORDS in that a single match bumps to
79
+ * complex, not just to standard.
80
+ */
81
+ const COMPLEX_KEYWORDS: ReadonlyArray<string> = [
82
+ "multi-service", "distributed", "consensus", "saga", "eventual consistency",
83
+ "breaking change", "api contract change", "schema redesign",
84
+ "architect", "architecture", "refactor core",
85
+ ];
86
+
87
+ /**
88
+ * Trivial-signal keywords: presence strongly suggests a simple, contained
89
+ * deliverable. Only effective when combined with low file count / no tests
90
+ * / no override keywords.
91
+ */
92
+ const TRIVIAL_KEYWORDS: ReadonlyArray<string> = [
93
+ "single file", "one file", "static html", "static page",
94
+ "one-page", "landing page", "readme", "docs only", "typo", "rename",
95
+ "spelling", "comment", "changelog",
96
+ // Browser-only / no-build deliverable shapes (b23 forensic case).
97
+ "pure html", "browser-based", "no build step", "no build tooling",
98
+ "localstorage", "client-only", "no backend", "no server", "no backend.",
99
+ ];
100
+
101
+ // ─── Heuristics ───────────────────────────────────────────────────────────
102
+
103
+ /**
104
+ * Estimate how many distinct files the milestone will touch, based on
105
+ * explicit mentions in the input text. Returns `null` when no hint is
106
+ * discoverable — callers should treat that as "unknown, no signal."
107
+ */
108
+ function extractFileCountHint(text: string): number | null {
109
+ // Explicit phrasing: "a single file", "two files", "3 files"
110
+ const singleFileMatch = /\b(a|one|single)\s+(file|page)\b/i.test(text);
111
+ if (singleFileMatch) return 1;
112
+
113
+ const digitMatch = text.match(/\b(\d+)\s+files?\b/i);
114
+ if (digitMatch) {
115
+ const n = parseInt(digitMatch[1], 10);
116
+ if (!Number.isNaN(n)) return n;
117
+ }
118
+
119
+ const wordMatch = text.match(/\b(two|three|four|five|six|seven|eight|nine|ten)\s+files?\b/i);
120
+ if (wordMatch) {
121
+ const wordMap: Record<string, number> = {
122
+ two: 2, three: 3, four: 4, five: 5,
123
+ six: 6, seven: 7, eight: 8, nine: 9, ten: 10,
124
+ };
125
+ return wordMap[wordMatch[1].toLowerCase()] ?? null;
126
+ }
127
+
128
+ return null;
129
+ }
130
+
131
+ function escapeRegExp(value: string): string {
132
+ return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
133
+ }
134
+
135
+ function containsAnyKeyword(haystack: string, keywords: ReadonlyArray<string>): string[] {
136
+ const lower = haystack.toLowerCase();
137
+ const hits: string[] = [];
138
+ for (const kw of keywords) {
139
+ // Word-boundary match to prevent substring collisions (e.g. "auth"
140
+ // must not match "author", "api" must not match "capital"). Phrases
141
+ // containing non-word characters (hyphens, slashes) still work because
142
+ // `\b` sits at the word-char / non-word-char transition, so
143
+ // `\bbrowser-based\b` matches "browser-based" bounded by whitespace
144
+ // or punctuation on either side.
145
+ const pattern = new RegExp(String.raw`\b${escapeRegExp(kw)}\b`, "i");
146
+ if (pattern.test(lower)) hits.push(kw);
147
+ }
148
+ return hits;
149
+ }
150
+
151
+ /**
152
+ * True when `term` appears in the text without an immediately preceding
153
+ * negator (no / without / not / zero / skip) in the same clause. Used to
154
+ * keep phrases like "no backend" or "no tests" from flipping a trivial-
155
+ * class milestone to standard. Best-effort; imperfect English parsing,
156
+ * biased toward false negatives (if unsure, treats term as present —
157
+ * which routes to standard, the safe pipeline).
158
+ */
159
+ function mentionsWithoutNegation(text: string, term: string): boolean {
160
+ const lower = text.toLowerCase();
161
+ const termPattern = new RegExp(String.raw`\b${term}\b`, "gi");
162
+ const matches = Array.from(lower.matchAll(termPattern));
163
+ for (const m of matches) {
164
+ const start = m.index ?? 0;
165
+ const windowStart = Math.max(0, start - 30);
166
+ const window = lower.slice(windowStart, start);
167
+ // Negator anywhere in the 30-char lookback window counts as negation —
168
+ // covers "no backend", "without a server", "not using api", "zero
169
+ // dependencies on an api". If a sentence break intervenes between the
170
+ // negator and the term, treat as a different clause (positive mention).
171
+ const hasNegator = /(^|[^a-z0-9])(no|without|not|zero|skip(s|ping)?|drops?)\b/i.test(window);
172
+ const hasSentenceBreak = /[.;!?]/.test(window);
173
+ if (hasNegator && !hasSentenceBreak) continue;
174
+ return true;
175
+ }
176
+ return false;
177
+ }
178
+
179
+ function mentionsTests(haystack: string): boolean {
180
+ return mentionsWithoutNegation(haystack, "test")
181
+ || mentionsWithoutNegation(haystack, "tests")
182
+ || mentionsWithoutNegation(haystack, "testing")
183
+ || mentionsWithoutNegation(haystack, "spec")
184
+ || mentionsWithoutNegation(haystack, "unit test")
185
+ || mentionsWithoutNegation(haystack, "integration test");
186
+ }
187
+
188
+ function mentionsBackend(haystack: string): boolean {
189
+ return mentionsWithoutNegation(haystack, "api")
190
+ || mentionsWithoutNegation(haystack, "backend")
191
+ || mentionsWithoutNegation(haystack, "server")
192
+ || mentionsWithoutNegation(haystack, "database")
193
+ || mentionsWithoutNegation(haystack, "endpoint");
194
+ }
195
+
196
+ // ─── DB adapter ───────────────────────────────────────────────────────────
197
+
198
+ /**
199
+ * Shape adapter: convert a milestone DB row into the classifier input
200
+ * object. Keeps `milestone-scope-classifier.ts` free of DB types at the
201
+ * module boundary — callers can either use this helper or hand-build the
202
+ * input themselves (e.g. from plan-milestone tool params before insert).
203
+ */
204
+ export function milestoneRowToScopeInput(row: {
205
+ title?: string;
206
+ vision?: string;
207
+ success_criteria?: string[];
208
+ key_risks?: Array<{ risk?: string; whyItMatters?: string }>;
209
+ definition_of_done?: string[];
210
+ requirement_coverage?: string;
211
+ verification_contract?: string;
212
+ verification_integration?: string;
213
+ verification_operational?: string;
214
+ verification_uat?: string;
215
+ }): MilestoneScopeInput {
216
+ return {
217
+ title: row.title,
218
+ vision: row.vision,
219
+ successCriteria: row.success_criteria,
220
+ keyRisks: row.key_risks,
221
+ definitionOfDone: row.definition_of_done,
222
+ requirementCoverage: row.requirement_coverage,
223
+ verificationContract: row.verification_contract,
224
+ verificationIntegration: row.verification_integration,
225
+ verificationOperational: row.verification_operational,
226
+ verificationUat: row.verification_uat,
227
+ };
228
+ }
229
+
230
+ /**
231
+ * Compute the pipeline variant for a milestone by reading its planning
232
+ * fields from the DB and running the classifier. Returns `null` when
233
+ * classification is unavailable (DB closed, milestone missing, unexpected
234
+ * error) — callers MUST treat null as "run the full pipeline" so a
235
+ * classification failure never silently downshifts dispatch.
236
+ */
237
+ export async function getMilestonePipelineVariant(mid: string): Promise<PipelineVariant | null> {
238
+ try {
239
+ const { isDbAvailable, getMilestone } = await import("./gsd-db.js");
240
+ if (!isDbAvailable()) return null;
241
+ const row = getMilestone(mid);
242
+ if (!row) return null;
243
+ return classifyMilestoneScope(milestoneRowToScopeInput(row)).variant;
244
+ } catch {
245
+ return null;
246
+ }
247
+ }
248
+
249
+ // ─── Public API ───────────────────────────────────────────────────────────
250
+
251
+ /**
252
+ * Classify a milestone's pipeline variant based on its planning inputs.
253
+ *
254
+ * Precedence (matches implementation order — complex-first so that
255
+ * security-sensitive architecture refactors correctly route to complex
256
+ * rather than standard; the override hit is still recorded in
257
+ * `signals.triggeredOverride` for telemetry):
258
+ * 1. Complex-signal keyword OR ≥ 8 file hint OR architecture/refactor-core
259
+ * language → `complex`.
260
+ * 2. Override keyword → `standard` (at minimum). Prevents trivial
261
+ * misclassification of security / auth / migration work.
262
+ * 3. Trivial-signal keyword AND ≤ 2 file hint AND no tests mentioned AND
263
+ * no backend mentioned → `trivial`.
264
+ * 4. Otherwise → `standard`.
265
+ *
266
+ * Ambiguity → `standard` (today's default). Safe to run the full pipeline.
267
+ */
268
+ export function classifyMilestoneScope(input: MilestoneScopeInput): ScopeClassificationResult {
269
+ const haystack = [
270
+ input.title ?? "",
271
+ input.vision ?? "",
272
+ (input.successCriteria ?? []).join("\n"),
273
+ (input.keyRisks ?? []).map(r => `${r.risk ?? ""} ${r.whyItMatters ?? ""}`).join("\n"),
274
+ (input.definitionOfDone ?? []).join("\n"),
275
+ input.requirementCoverage ?? "",
276
+ input.verificationContract ?? "",
277
+ input.verificationIntegration ?? "",
278
+ input.verificationOperational ?? "",
279
+ input.verificationUat ?? "",
280
+ ].join("\n");
281
+
282
+ const overrideHits = containsAnyKeyword(haystack, OVERRIDE_KEYWORDS);
283
+ const complexHits = containsAnyKeyword(haystack, COMPLEX_KEYWORDS);
284
+ const trivialHits = containsAnyKeyword(haystack, TRIVIAL_KEYWORDS);
285
+ const fileCountHint = extractFileCountHint(haystack);
286
+ const hasTests = mentionsTests(haystack);
287
+ const hasBackend = mentionsBackend(haystack);
288
+
289
+ const reasons: string[] = [];
290
+
291
+ // Rule 2: complex-class signals. Evaluated before override because a
292
+ // complex + override input should land in complex, not standard.
293
+ if (complexHits.length > 0) {
294
+ reasons.push(`complex keywords: ${complexHits.slice(0, 3).join(", ")}`);
295
+ }
296
+ if (fileCountHint !== null && fileCountHint >= 8) {
297
+ reasons.push(`file count hint: ${fileCountHint}`);
298
+ }
299
+
300
+ const isComplex = complexHits.length > 0 || (fileCountHint !== null && fileCountHint >= 8);
301
+
302
+ if (isComplex) {
303
+ return {
304
+ variant: "complex",
305
+ reasons,
306
+ signals: {
307
+ triggeredOverride: overrideHits.length > 0,
308
+ complexCount: complexHits.length,
309
+ trivialCount: trivialHits.length,
310
+ fileCountHint,
311
+ },
312
+ };
313
+ }
314
+
315
+ // Rule 1: override keywords force standard.
316
+ if (overrideHits.length > 0) {
317
+ return {
318
+ variant: "standard",
319
+ reasons: [`override keywords: ${overrideHits.slice(0, 3).join(", ")}`],
320
+ signals: {
321
+ triggeredOverride: true,
322
+ complexCount: complexHits.length,
323
+ trivialCount: trivialHits.length,
324
+ fileCountHint,
325
+ },
326
+ };
327
+ }
328
+
329
+ // Rule 3: trivial signals — require ALL of: trivial-keyword, low file
330
+ // hint (or nothing suggesting high count), no test mention, no backend
331
+ // mention.
332
+ const fileCountOk = fileCountHint === null || fileCountHint <= 2;
333
+ const trivial =
334
+ trivialHits.length > 0 &&
335
+ fileCountOk &&
336
+ !hasTests &&
337
+ !hasBackend;
338
+
339
+ if (trivial) {
340
+ reasons.push(`trivial keywords: ${trivialHits.slice(0, 3).join(", ")}`);
341
+ if (fileCountHint !== null) reasons.push(`file count hint: ${fileCountHint}`);
342
+ reasons.push("no tests mentioned", "no backend mentioned");
343
+ return {
344
+ variant: "trivial",
345
+ reasons,
346
+ signals: {
347
+ triggeredOverride: false,
348
+ complexCount: complexHits.length,
349
+ trivialCount: trivialHits.length,
350
+ fileCountHint,
351
+ },
352
+ };
353
+ }
354
+
355
+ // Rule 4: fallback.
356
+ return {
357
+ variant: "standard",
358
+ reasons: reasons.length > 0 ? reasons : ["no strong signals — default"],
359
+ signals: {
360
+ triggeredOverride: overrideHits.length > 0,
361
+ complexCount: complexHits.length,
362
+ trivialCount: trivialHits.length,
363
+ fileCountHint,
364
+ },
365
+ };
366
+ }
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Shared milestone SUMMARY classifier.
3
+ *
4
+ * SUMMARY presence alone is not enough to prove milestone completion: recovery
5
+ * and blocker paths also write SUMMARY files. Keep this leaf module free of
6
+ * state/auto imports so state derivation, dispatch guards, and recovery can
7
+ * share one definition without cycles.
8
+ */
9
+
10
+ import { splitFrontmatter, parseFrontmatterMap } from "../shared/frontmatter.js";
11
+ import { isClosedStatus } from "./status-guards.js";
12
+
13
+ export type MilestoneSummaryOutcome = "success" | "failure" | "unknown";
14
+
15
+ export function classifyMilestoneSummaryContent(content: string): MilestoneSummaryOutcome {
16
+ const [fmLines] = splitFrontmatter(content);
17
+ const fm = fmLines ? parseFrontmatterMap(fmLines) : null;
18
+ const rawStatus = typeof fm?.status === "string" ? fm.status.trim().toLowerCase() : "";
19
+ if (rawStatus) {
20
+ if (isClosedStatus(rawStatus)) return "success";
21
+ if (["active", "pending", "blocked", "failed", "failure", "incomplete"].includes(rawStatus)) {
22
+ return "failure";
23
+ }
24
+ }
25
+
26
+ const failureSignal =
27
+ /(?:^|\n)\s*#\s*BLOCKER\b/i.test(content)
28
+ || /auto-mode recovery failed/i.test(content)
29
+ || /verification\s+failed/i.test(content)
30
+ || /(?:^|\n)\s*(?:status|verdict|outcome|result)\s*[:=-]\s*not complete\b/i.test(content);
31
+ if (failureSignal) return "failure";
32
+ return "unknown";
33
+ }
34
+
35
+ /**
36
+ * Legacy-compatible terminal check for state derivation.
37
+ * Unknown summaries remain terminal to preserve old handwritten SUMMARY files;
38
+ * explicit failure summaries do not.
39
+ */
40
+ export function isTerminalMilestoneSummaryContent(content: string): boolean {
41
+ return classifyMilestoneSummaryContent(content) !== "failure";
42
+ }
@@ -57,6 +57,9 @@ export const BUNDLED_COST_TABLE: ModelCostEntry[] = [
57
57
  { id: "gpt-5.3-codex-spark", inputPer1k: 0.0003, outputPer1k: 0.0012, updatedAt: "2026-03-29" },
58
58
  { id: "gpt-5.4", inputPer1k: 0.005, outputPer1k: 0.02, updatedAt: "2026-03-29" },
59
59
  { id: "gpt-5.4-mini", inputPer1k: 0.00075, outputPer1k: 0.0045, updatedAt: "2026-04-18" },
60
+ // GPT-5.5 API list price, also used for live Codex OAuth routing.
61
+ // Source: https://openai.com/api/pricing/
62
+ { id: "gpt-5.5", inputPer1k: 0.005, outputPer1k: 0.03, updatedAt: "2026-04-23" },
60
63
 
61
64
  // Google
62
65
  { id: "gemini-2.0-flash", inputPer1k: 0.0001, outputPer1k: 0.0004, updatedAt: "2025-03-15" },
@@ -109,6 +109,7 @@ export const MODEL_CAPABILITY_TIER: Record<string, ComplexityTier> = {
109
109
  "gpt-5.2-codex": "heavy",
110
110
  "gpt-5.3-codex": "heavy",
111
111
  "gpt-5.4": "heavy",
112
+ "gpt-5.5": "heavy",
112
113
  "o1": "heavy",
113
114
  "o3": "heavy",
114
115
  "o4-mini": "heavy",
@@ -144,6 +145,7 @@ const MODEL_COST_PER_1K_INPUT: Record<string, number> = {
144
145
  "gpt-5.3-codex": 0.005,
145
146
  "gpt-5.3-codex-spark": 0.0003,
146
147
  "gpt-5.4": 0.005,
148
+ "gpt-5.5": 0.005,
147
149
  "o4-mini": 0.005,
148
150
  "o4-mini-deep-research": 0.005,
149
151
  "gemini-2.0-flash": 0.0001,
@@ -187,6 +189,10 @@ export const MODEL_CAPABILITY_PROFILES: Record<string, ModelCapabilities> = {
187
189
  "gpt-5.3-codex": { coding: 94, debugging: 91, research: 74, reasoning: 89, speed: 50, longContext: 80, instruction: 89 },
188
190
  "gpt-5.3-codex-spark": { coding: 68, debugging: 58, research: 42, reasoning: 52, speed: 90, longContext: 50, instruction: 74 },
189
191
  "gpt-5.4": { coding: 95, debugging: 92, research: 88, reasoning: 94, speed: 42, longContext: 88, instruction: 92 },
192
+ // GPT-5.5 scores are relative to the existing gpt-5.4 profile and backed by
193
+ // OpenAI's 2026-04-23 published eval deltas across coding, tool use, and long context.
194
+ // Source: https://openai.com/index/introducing-gpt-5-5/
195
+ "gpt-5.5": { coding: 96, debugging: 93, research: 89, reasoning: 95, speed: 42, longContext: 90, instruction: 93 },
190
196
 
191
197
  // ── OpenAI o-series (reasoning-first) ──────────────────────────────────────
192
198
  "o1": { coding: 78, debugging: 82, research: 78, reasoning: 90, speed: 20, longContext: 65, instruction: 82 },
@@ -894,11 +894,37 @@ export function nativeResetPaths(basePath: string, paths: string[]): void {
894
894
  }
895
895
  }
896
896
 
897
+ /**
898
+ * Read `commit.gpgsign` from the repo config. Returns true only if the value
899
+ * is the literal string "true". Any other state (unset, false, error) → false.
900
+ *
901
+ * Used by nativeCommit to route signing-required commits through the git CLI,
902
+ * because the libgit2 native path does not invoke configured signers.
903
+ * (Issue #4980 CRIT-2)
904
+ */
905
+ function shouldSignCommits(basePath: string): boolean {
906
+ try {
907
+ const result = execFileSync("git", ["config", "--get", "commit.gpgsign"], {
908
+ cwd: basePath,
909
+ stdio: ["ignore", "pipe", "pipe"],
910
+ encoding: "utf-8",
911
+ env: GIT_NO_PROMPT_ENV,
912
+ }).trim();
913
+ return result === "true";
914
+ } catch {
915
+ return false;
916
+ }
917
+ }
918
+
897
919
  /**
898
920
  * Create a commit from the current index.
899
921
  * Returns the commit SHA on success, or null if nothing to commit.
900
922
  * Native: libgit2 commit create.
901
- * Fallback: `git commit --no-verify -F -`.
923
+ * Fallback: `git commit -F -` (runs hooks; honors commit.gpgsign).
924
+ *
925
+ * The fallback intentionally does NOT use --no-verify — user pre-commit /
926
+ * commit-msg / prepare-commit-msg hooks must fire on every GSD-automated
927
+ * commit. (Issue #4980 CRIT-1)
902
928
  */
903
929
  export function nativeCommit(
904
930
  basePath: string,
@@ -906,7 +932,10 @@ export function nativeCommit(
906
932
  options?: { allowEmpty?: boolean; input?: string },
907
933
  ): string | null {
908
934
  const native = loadNative();
909
- if (native) {
935
+ // libgit2's commit-create does not invoke configured GPG/SSH signers. When
936
+ // commit.gpgsign=true, route through the git CLI fallback so signing
937
+ // happens. (Issue #4980 CRIT-2)
938
+ if (native && !shouldSignCommits(basePath)) {
910
939
  try {
911
940
  return native.gitCommit(basePath, message, options?.allowEmpty);
912
941
  } catch (e) {
@@ -916,9 +945,10 @@ export function nativeCommit(
916
945
  }
917
946
  }
918
947
 
919
- // Fallback: use git commit with stdin pipe for safe multi-line messages
948
+ // Fallback / signed-commit path: use git CLI with stdin pipe for safe
949
+ // multi-line messages. Hooks run; commit.gpgsign honored.
920
950
  try {
921
- const args = ["commit", "--no-verify", "-F", "-"];
951
+ const args = ["commit", "-F", "-"];
922
952
  if (options?.allowEmpty) args.push("--allow-empty");
923
953
  const result = execFileSync("git", args, {
924
954
  cwd: basePath,