gsd-pi 2.80.0-dev.8b3a59f5c → 2.80.0-dev.b0acf17e9

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 (659) hide show
  1. package/README.md +4 -2
  2. package/dist/claude-cli-check.d.ts +30 -0
  3. package/dist/claude-cli-check.js +18 -7
  4. package/dist/cli.js +0 -19
  5. package/dist/headless-query.d.ts +10 -0
  6. package/dist/headless-query.js +6 -4
  7. package/dist/loader-entrypoint.d.ts +8 -0
  8. package/dist/loader-entrypoint.js +27 -0
  9. package/dist/loader.js +2 -11
  10. package/dist/mcp-server.d.ts +1 -0
  11. package/dist/mcp-server.js +6 -3
  12. package/dist/resources/.managed-resources-content-hash +1 -1
  13. package/dist/resources/GSD-WORKFLOW.md +2 -2
  14. package/dist/resources/extensions/claude-code-cli/readiness.js +18 -7
  15. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  16. package/dist/resources/extensions/github-sync/sync.js +4 -1
  17. package/dist/resources/extensions/gsd/auto/loop.js +103 -9
  18. package/dist/resources/extensions/gsd/auto/phases.js +240 -139
  19. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +22 -30
  21. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  22. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  23. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  24. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  25. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  26. package/dist/resources/extensions/gsd/auto-post-unit.js +103 -86
  27. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  28. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  29. package/dist/resources/extensions/gsd/auto-start.js +240 -15
  30. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  31. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  32. package/dist/resources/extensions/gsd/auto-worktree.js +165 -28
  33. package/dist/resources/extensions/gsd/auto.js +165 -45
  34. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +99 -10
  35. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +50 -37
  36. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +35 -10
  37. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +36 -20
  38. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +10 -1
  39. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +12 -4
  40. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +11 -3
  41. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +1 -1
  42. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +319 -54
  43. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  44. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  45. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  46. package/dist/resources/extensions/gsd/commands/handlers/ops.js +2 -2
  47. package/dist/resources/extensions/gsd/commands-config.js +1 -1
  48. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  49. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  50. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  51. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -1
  52. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  53. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  54. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  55. package/dist/resources/extensions/gsd/detection.js +106 -0
  56. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  57. package/dist/resources/extensions/gsd/git-service.js +73 -5
  58. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  59. package/dist/resources/extensions/gsd/guided-flow.js +143 -48
  60. package/dist/resources/extensions/gsd/init-wizard.js +4 -1
  61. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  62. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  63. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  64. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  65. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  66. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  67. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  68. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  69. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  70. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  71. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  72. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  73. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  74. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  75. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  76. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  77. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  78. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  79. package/dist/resources/extensions/gsd/quick.js +34 -2
  80. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  81. package/dist/resources/extensions/gsd/slice-cadence.js +45 -2
  82. package/dist/resources/extensions/gsd/slice-parallel-orchestrator.js +15 -9
  83. package/dist/resources/extensions/gsd/tools/complete-task.js +1 -1
  84. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  85. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  86. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  87. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  88. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  89. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  90. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  91. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  92. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  93. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  94. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  95. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  96. package/dist/resources/extensions/gsd/worktree-resolver.js +90 -22
  97. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  98. package/dist/web/standalone/.next/BUILD_ID +1 -1
  99. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  100. package/dist/web/standalone/.next/build-manifest.json +3 -3
  101. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  102. package/dist/web/standalone/.next/react-loadable-manifest.json +2 -2
  103. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  104. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  105. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  113. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  114. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/index.html +1 -1
  122. package/dist/web/standalone/.next/server/app/index.rsc +2 -2
  123. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  124. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +2 -2
  125. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  126. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  127. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  128. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  130. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  132. package/dist/web/standalone/.next/server/middleware.js +3 -3
  133. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  134. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  135. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  136. package/dist/web/standalone/.next/static/chunks/8359.e059d86b255fce1c.js +10 -0
  137. package/dist/web/standalone/.next/static/chunks/app/{page-fab3ebb85b006001.js → page-752f1e2ebdaa3e45.js} +1 -1
  138. package/dist/web/standalone/.next/static/chunks/{webpack-0481f1221120a7c6.js → webpack-de742b64187e13fe.js} +1 -1
  139. package/dist/welcome-screen.d.ts +2 -0
  140. package/dist/welcome-screen.js +9 -7
  141. package/package.json +6 -4
  142. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  143. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  144. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  145. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  146. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  147. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  148. package/packages/native/tsconfig.tsbuildinfo +1 -1
  149. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  150. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  151. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  152. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  153. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  154. package/packages/pi-agent-core/dist/agent.js +2 -0
  155. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  156. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  157. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  158. package/packages/pi-agent-core/dist/index.js +2 -0
  159. package/packages/pi-agent-core/dist/index.js.map +1 -1
  160. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  161. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  162. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  163. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  164. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  165. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  166. package/packages/pi-agent-core/dist/types.js.map +1 -1
  167. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  168. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  169. package/packages/pi-agent-core/src/agent.ts +8 -0
  170. package/packages/pi-agent-core/src/index.ts +2 -0
  171. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  172. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  173. package/packages/pi-agent-core/src/types.ts +14 -0
  174. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  175. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +35 -13
  176. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  177. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js +21 -11
  178. package/packages/pi-ai/dist/providers/anthropic-bearer-auth.test.js.map +1 -1
  179. package/packages/pi-ai/dist/providers/anthropic.d.ts +7 -0
  180. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  181. package/packages/pi-ai/dist/providers/anthropic.js +9 -7
  182. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  183. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +23 -14
  184. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -1
  185. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js +48 -21
  186. package/packages/pi-ai/dist/utils/oauth/github-copilot.test.js.map +1 -1
  187. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js +22 -21
  188. package/packages/pi-ai/dist/utils/oauth/google-antigravity.test.js.map +1 -1
  189. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js +22 -21
  190. package/packages/pi-ai/dist/utils/oauth/google-gemini-cli.test.js.map +1 -1
  191. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +39 -25
  192. package/packages/pi-ai/src/providers/anthropic-bearer-auth.test.ts +26 -22
  193. package/packages/pi-ai/src/providers/anthropic.ts +22 -9
  194. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +34 -21
  195. package/packages/pi-ai/src/utils/oauth/github-copilot.test.ts +56 -22
  196. package/packages/pi-ai/src/utils/oauth/google-antigravity.test.ts +24 -28
  197. package/packages/pi-ai/src/utils/oauth/google-gemini-cli.test.ts +24 -28
  198. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  199. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  200. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  201. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  202. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  204. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  205. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  206. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +35 -1
  208. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  209. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  210. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  211. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  212. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  213. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  214. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  215. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  216. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  217. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  218. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  219. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  220. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  221. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  222. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  223. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  224. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  225. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  226. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  227. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  228. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  229. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  231. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  233. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +41 -3
  235. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  237. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  238. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  240. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  241. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  242. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  243. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  244. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  246. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  248. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  249. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  250. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  251. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  252. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  253. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  254. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  255. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  256. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  257. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js +22 -56
  258. package/packages/pi-coding-agent/dist/core/tools/bash-spawn-windows.test.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts +1 -0
  260. package/packages/pi-coding-agent/dist/core/tools/bash.d.ts.map +1 -1
  261. package/packages/pi-coding-agent/dist/core/tools/bash.js +3 -1
  262. package/packages/pi-coding-agent/dist/core/tools/bash.js.map +1 -1
  263. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts +2 -0
  264. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  265. package/packages/pi-coding-agent/dist/core/tools/edit.js +12 -1
  266. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  267. package/packages/pi-coding-agent/dist/core/tools/find.d.ts +2 -0
  268. package/packages/pi-coding-agent/dist/core/tools/find.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/tools/find.js +14 -6
  270. package/packages/pi-coding-agent/dist/core/tools/find.js.map +1 -1
  271. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts +2 -0
  272. package/packages/pi-coding-agent/dist/core/tools/grep.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/tools/grep.js +12 -3
  274. package/packages/pi-coding-agent/dist/core/tools/grep.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts +2 -0
  276. package/packages/pi-coding-agent/dist/core/tools/hashline-read.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js +3 -1
  278. package/packages/pi-coding-agent/dist/core/tools/hashline-read.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/index.d.ts +2 -1
  280. package/packages/pi-coding-agent/dist/core/tools/index.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/core/tools/index.js +1 -0
  282. package/packages/pi-coding-agent/dist/core/tools/index.js.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts +2 -0
  284. package/packages/pi-coding-agent/dist/core/tools/ls.d.ts.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/tools/ls.js +10 -3
  286. package/packages/pi-coding-agent/dist/core/tools/ls.js.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -0
  288. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/tools/read.js +3 -1
  290. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js +7 -62
  292. package/packages/pi-coding-agent/dist/core/tools/spawn-shell-windows.test.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts +2 -0
  294. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.d.ts.map +1 -0
  295. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js +115 -0
  296. package/packages/pi-coding-agent/dist/core/tools/tool-target-metadata.test.js.map +1 -0
  297. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts +19 -0
  298. package/packages/pi-coding-agent/dist/core/tools/tool-target.d.ts.map +1 -0
  299. package/packages/pi-coding-agent/dist/core/tools/tool-target.js +20 -0
  300. package/packages/pi-coding-agent/dist/core/tools/tool-target.js.map +1 -0
  301. package/packages/pi-coding-agent/dist/core/tools/write.d.ts +4 -0
  302. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/core/tools/write.js +9 -1
  304. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  306. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  307. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +114 -22
  308. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  309. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +2 -2
  310. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -1
  311. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  312. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  313. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  314. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +2 -1
  315. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  316. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  317. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  318. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +6 -0
  319. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  320. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +177 -19
  321. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  322. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  323. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +33 -6
  324. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  325. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +71 -0
  326. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  327. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  328. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  329. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  330. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  331. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  332. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  333. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +21 -0
  334. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -1
  335. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  336. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  337. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +28 -0
  338. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  339. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  340. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  341. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  342. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  343. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  344. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  345. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +41 -1
  346. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  347. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  348. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  349. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  350. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  351. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  352. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  353. package/packages/pi-coding-agent/src/core/extensions/types.ts +44 -2
  354. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  355. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  356. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  357. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  358. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  359. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  360. package/packages/pi-coding-agent/src/core/tools/bash-spawn-windows.test.ts +22 -66
  361. package/packages/pi-coding-agent/src/core/tools/bash.ts +4 -1
  362. package/packages/pi-coding-agent/src/core/tools/edit.ts +13 -1
  363. package/packages/pi-coding-agent/src/core/tools/find.ts +15 -6
  364. package/packages/pi-coding-agent/src/core/tools/grep.ts +13 -3
  365. package/packages/pi-coding-agent/src/core/tools/hashline-read.ts +4 -1
  366. package/packages/pi-coding-agent/src/core/tools/index.ts +8 -0
  367. package/packages/pi-coding-agent/src/core/tools/ls.ts +11 -3
  368. package/packages/pi-coding-agent/src/core/tools/read.ts +4 -1
  369. package/packages/pi-coding-agent/src/core/tools/spawn-shell-windows.test.ts +11 -72
  370. package/packages/pi-coding-agent/src/core/tools/tool-target-metadata.test.ts +127 -0
  371. package/packages/pi-coding-agent/src/core/tools/tool-target.ts +48 -0
  372. package/packages/pi-coding-agent/src/core/tools/write.ts +14 -2
  373. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  374. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +144 -22
  375. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +2 -2
  376. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  377. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +2 -1
  378. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  379. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +208 -19
  380. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +75 -0
  381. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +41 -8
  382. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  383. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  384. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +25 -0
  385. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +31 -0
  386. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  387. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  388. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  389. package/packages/pi-tui/dist/tui.js +18 -8
  390. package/packages/pi-tui/dist/tui.js.map +1 -1
  391. package/packages/pi-tui/src/tui.ts +20 -8
  392. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  393. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  394. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  395. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  396. package/src/resources/GSD-WORKFLOW.md +2 -2
  397. package/src/resources/extensions/claude-code-cli/readiness.ts +25 -7
  398. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  399. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  400. package/src/resources/extensions/github-sync/sync.ts +8 -1
  401. package/src/resources/extensions/github-sync/tests/sync-source.test.ts +6 -18
  402. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  403. package/src/resources/extensions/gsd/auto/loop.ts +134 -16
  404. package/src/resources/extensions/gsd/auto/phases.ts +328 -200
  405. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  406. package/src/resources/extensions/gsd/auto/run-unit.ts +28 -30
  407. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  408. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  409. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  410. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  411. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  412. package/src/resources/extensions/gsd/auto-post-unit.ts +116 -88
  413. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  414. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  415. package/src/resources/extensions/gsd/auto-start.ts +293 -21
  416. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  417. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  418. package/src/resources/extensions/gsd/auto-worktree.ts +199 -30
  419. package/src/resources/extensions/gsd/auto.ts +216 -40
  420. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +120 -8
  421. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +51 -37
  422. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +35 -10
  423. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +38 -19
  424. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +11 -1
  425. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +13 -4
  426. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +12 -3
  427. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +1 -1
  428. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +369 -54
  429. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  430. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  431. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  432. package/src/resources/extensions/gsd/commands/handlers/ops.ts +4 -2
  433. package/src/resources/extensions/gsd/commands-config.ts +1 -1
  434. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  435. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  436. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  437. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -1
  438. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  439. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  440. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  441. package/src/resources/extensions/gsd/detection.ts +128 -0
  442. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  443. package/src/resources/extensions/gsd/git-service.ts +87 -10
  444. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  445. package/src/resources/extensions/gsd/guided-flow.ts +169 -55
  446. package/src/resources/extensions/gsd/init-wizard.ts +5 -1
  447. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  448. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  449. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  450. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  451. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  452. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  453. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  454. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  455. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  456. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  457. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  458. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  459. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  460. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  462. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  464. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  465. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  466. package/src/resources/extensions/gsd/quick.ts +37 -2
  467. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  468. package/src/resources/extensions/gsd/slice-cadence.ts +49 -2
  469. package/src/resources/extensions/gsd/slice-parallel-orchestrator.ts +23 -9
  470. package/src/resources/extensions/gsd/tests/agent-end-retry.test.ts +59 -89
  471. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +47 -172
  472. package/src/resources/extensions/gsd/tests/artifacts-table-preserved-on-cache-invalidate.test.ts +0 -35
  473. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +35 -9
  474. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +433 -11
  475. package/src/resources/extensions/gsd/tests/auto-model-selection.test.ts +80 -59
  476. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +3 -47
  477. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +76 -18
  478. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +160 -11
  479. package/src/resources/extensions/gsd/tests/auto-pr-bugs.test.ts +54 -95
  480. package/src/resources/extensions/gsd/tests/auto-project-root-env.test.ts +67 -26
  481. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  482. package/src/resources/extensions/gsd/tests/auto-remediate-slice-status.test.ts +32 -30
  483. package/src/resources/extensions/gsd/tests/auto-start-bootstrap-await-3420.test.ts +32 -128
  484. package/src/resources/extensions/gsd/tests/auto-start-clean-runtime-db-gated.test.ts +20 -54
  485. package/src/resources/extensions/gsd/tests/auto-start-cold-db-bootstrap.test.ts +20 -30
  486. package/src/resources/extensions/gsd/tests/auto-start-index-lock.test.ts +17 -29
  487. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +138 -0
  488. package/src/resources/extensions/gsd/tests/auto-start-time-persistence.test.ts +21 -39
  489. package/src/resources/extensions/gsd/tests/auto-start-worktree-db-path.test.ts +15 -24
  490. package/src/resources/extensions/gsd/tests/auto-thinking-restore.test.ts +44 -29
  491. package/src/resources/extensions/gsd/tests/auto-warning-noise-regression.test.ts +39 -51
  492. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +159 -213
  493. package/src/resources/extensions/gsd/tests/bootstrap-derive-state-db-open.test.ts +15 -32
  494. package/src/resources/extensions/gsd/tests/browser-teardown.test.ts +0 -41
  495. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  496. package/src/resources/extensions/gsd/tests/clear-stale-autostart.test.ts +34 -27
  497. package/src/resources/extensions/gsd/tests/cmux.test.ts +42 -53
  498. package/src/resources/extensions/gsd/tests/cold-resume-db-reopen.test.ts +39 -61
  499. package/src/resources/extensions/gsd/tests/commands-config.test.ts +26 -19
  500. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  501. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  502. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  503. package/src/resources/extensions/gsd/tests/complete-task-normalize-lists.test.ts +29 -33
  504. package/src/resources/extensions/gsd/tests/completed-units-metrics-sync.test.ts +45 -108
  505. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  506. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  507. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +90 -31
  508. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  509. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  510. package/src/resources/extensions/gsd/tests/cwd-fallback-hardening.test.ts +138 -0
  511. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +4 -68
  512. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +4 -9
  513. package/src/resources/extensions/gsd/tests/deferred-milestone-dir-4996.test.ts +14 -65
  514. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  515. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +44 -37
  516. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +58 -40
  517. package/src/resources/extensions/gsd/tests/dispatch-guard-closed-status.test.ts +25 -15
  518. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  519. package/src/resources/extensions/gsd/tests/dispatcher-stuck-planning.test.ts +35 -17
  520. package/src/resources/extensions/gsd/tests/error-success-mask.test.ts +16 -21
  521. package/src/resources/extensions/gsd/tests/est-annotation-timeout.test.ts +15 -82
  522. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  523. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  524. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  525. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  526. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  527. package/src/resources/extensions/gsd/tests/flat-rate-routing-guard.test.ts +2 -20
  528. package/src/resources/extensions/gsd/tests/frontmatter-parse-noise.test.ts +18 -26
  529. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  530. package/src/resources/extensions/gsd/tests/init-skip-git.test.ts +9 -12
  531. package/src/resources/extensions/gsd/tests/integration/auto-worktree-milestone-merge.test.ts +35 -0
  532. package/src/resources/extensions/gsd/tests/integration/git-locale.test.ts +31 -20
  533. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +66 -0
  534. package/src/resources/extensions/gsd/tests/integration/milestone-transition-worktree.test.ts +0 -47
  535. package/src/resources/extensions/gsd/tests/interactive-routing-bypass.test.ts +60 -202
  536. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +13 -56
  537. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  538. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  539. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  540. package/src/resources/extensions/gsd/tests/lazy-pi-tui-import.test.ts +44 -6
  541. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  542. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +21 -35
  543. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  544. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  545. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  546. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  547. package/src/resources/extensions/gsd/tests/milestone-transition-state-rebuild.test.ts +79 -98
  548. package/src/resources/extensions/gsd/tests/model-unittype-mapping.test.ts +70 -278
  549. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  550. package/src/resources/extensions/gsd/tests/needs-remediation-revalidation.test.ts +37 -30
  551. package/src/resources/extensions/gsd/tests/note-captures-executed.test.ts +32 -28
  552. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  554. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  555. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  556. package/src/resources/extensions/gsd/tests/phantom-ghost-detection.test.ts +24 -37
  557. package/src/resources/extensions/gsd/tests/phantom-milestone-default-queued.test.ts +9 -24
  558. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +91 -75
  559. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  560. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  561. package/src/resources/extensions/gsd/tests/post-unit-state-rebuild.test.ts +36 -22
  562. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +36 -30
  563. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  564. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +20 -22
  565. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +130 -32
  566. package/src/resources/extensions/gsd/tests/project-root-cwd-crash.test.ts +18 -36
  567. package/src/resources/extensions/gsd/tests/projection-no-plan-overwrite.test.ts +35 -73
  568. package/src/resources/extensions/gsd/tests/prompt-budget-enforcement.test.ts +76 -138
  569. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  570. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  571. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +70 -106
  572. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +59 -161
  573. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +33 -29
  574. package/src/resources/extensions/gsd/tests/queue-auto-guard.test.ts +22 -196
  575. package/src/resources/extensions/gsd/tests/quick-auto-guard.test.ts +23 -93
  576. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  577. package/src/resources/extensions/gsd/tests/quick-turn-end-cleanup.test.ts +50 -79
  578. package/src/resources/extensions/gsd/tests/reassess-default-optin.test.ts +27 -13
  579. package/src/resources/extensions/gsd/tests/remote-questions.test.ts +151 -251
  580. package/src/resources/extensions/gsd/tests/resource-loader-import-path.test.ts +41 -29
  581. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +58 -69
  582. package/src/resources/extensions/gsd/tests/resume-dispatch-worktree.test.ts +32 -164
  583. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  584. package/src/resources/extensions/gsd/tests/run-uat-replay-cap.test.ts +57 -41
  585. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  586. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  587. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  588. package/src/resources/extensions/gsd/tests/session-model-override.test.ts +14 -9
  589. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  590. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  591. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +44 -42
  592. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  593. package/src/resources/extensions/gsd/tests/skip-slice-state-rebuild.test.ts +56 -24
  594. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +51 -11
  595. package/src/resources/extensions/gsd/tests/slice-cadence.test.ts +23 -0
  596. package/src/resources/extensions/gsd/tests/slice-context-injection.test.ts +66 -50
  597. package/src/resources/extensions/gsd/tests/slice-parallel-orchestrator.test.ts +68 -107
  598. package/src/resources/extensions/gsd/tests/slice-sequence-insert.test.ts +115 -42
  599. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +21 -59
  600. package/src/resources/extensions/gsd/tests/smart-entry-draft.test.ts +25 -116
  601. package/src/resources/extensions/gsd/tests/sqlite-unavailable-gate.test.ts +21 -57
  602. package/src/resources/extensions/gsd/tests/stale-dirlistcache-4648.test.ts +29 -76
  603. package/src/resources/extensions/gsd/tests/stale-lockfile-recovery.test.ts +33 -24
  604. package/src/resources/extensions/gsd/tests/stale-slice-rows.test.ts +39 -30
  605. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  606. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  607. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  608. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +35 -40
  609. package/src/resources/extensions/gsd/tests/stop-auto-merge-back.test.ts +36 -45
  610. package/src/resources/extensions/gsd/tests/stop-auto-race-null-unit.test.ts +14 -102
  611. package/src/resources/extensions/gsd/tests/subagent-model-dispatch.test.ts +78 -232
  612. package/src/resources/extensions/gsd/tests/sync-worktree-skip-current.test.ts +32 -35
  613. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  614. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  615. package/src/resources/extensions/gsd/tests/token-profile.test.ts +84 -309
  616. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  617. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +134 -341
  618. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  619. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +8 -25
  620. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  621. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  622. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -99
  623. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +43 -36
  624. package/src/resources/extensions/gsd/tests/visualizer-data.test.ts +84 -444
  625. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  626. package/src/resources/extensions/gsd/tests/workflow-logger-wiring.test.ts +44 -189
  627. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -57
  628. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  629. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  630. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  631. package/src/resources/extensions/gsd/tests/worktree-db-same-file.test.ts +21 -44
  632. package/src/resources/extensions/gsd/tests/worktree-expected-warnings.test.ts +27 -26
  633. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +38 -6
  634. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  635. package/src/resources/extensions/gsd/tests/worktree-main-branch.test.ts +20 -18
  636. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  637. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  638. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  639. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  640. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +203 -4
  641. package/src/resources/extensions/gsd/tests/zero-slice-roadmap-guided.test.ts +19 -13
  642. package/src/resources/extensions/gsd/tools/complete-task.ts +1 -1
  643. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  644. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  645. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  646. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  647. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  648. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  649. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  650. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  651. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  652. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  653. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  654. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  655. package/src/resources/extensions/gsd/worktree-resolver.ts +119 -20
  656. package/src/resources/skills/create-gsd-extension/templates/templates.test.ts +86 -40
  657. package/dist/web/standalone/.next/static/chunks/8336.631939fb583761fa.js +0 -10
  658. /package/dist/web/standalone/.next/static/{k-MDjzPMF62Rg1-FR437h → naNyn5ToUBzCQtuLbEYXC}/_buildManifest.js +0 -0
  659. /package/dist/web/standalone/.next/static/{k-MDjzPMF62Rg1-FR437h → naNyn5ToUBzCQtuLbEYXC}/_ssgManifest.js +0 -0
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: System prompt and hidden context bootstrap for GSD sessions.
1
3
  import { existsSync, readFileSync, unlinkSync } from "node:fs";
2
4
  import { join } from "node:path";
3
5
 
@@ -21,6 +23,11 @@ import { toPosixPath } from "../../shared/mod.js";
21
23
  import { autoEnableCmuxPreferences } from "../commands-cmux.js";
22
24
  import { gsdHome } from "../gsd-home.js";
23
25
 
26
+ const DEFAULT_CONTEXT_MESSAGE_MAX_CHARS = 4_000;
27
+ const DEFAULT_KNOWLEDGE_MAX_CHARS = 12_000;
28
+ const DEFAULT_CODEBASE_MAX_CHARS = 8_000;
29
+ const MIN_CONTEXT_MESSAGE_MAX_CHARS = 1_000;
30
+ const MIN_KNOWLEDGE_MAX_CHARS = 1_000;
24
31
 
25
32
  /**
26
33
  * Bundled skill triggers — resolved dynamically at runtime instead of
@@ -158,8 +165,6 @@ export async function buildBeforeAgentStartResult(
158
165
  logWarning("bootstrap", `decisions backfill failed: ${(e as Error).message}`);
159
166
  }
160
167
 
161
- const memoryBlock = await loadMemoryBlock(event.prompt ?? "");
162
-
163
168
  let newSkillsBlock = "";
164
169
  if (hasSkillSnapshot()) {
165
170
  const newSkills = detectNewSkills();
@@ -190,11 +195,10 @@ export async function buildBeforeAgentStartResult(
190
195
  if (rawContent) {
191
196
  // Cap injection size to ~2 000 tokens to avoid bloating every request.
192
197
  // Full map is always available at .gsd/CODEBASE.md.
193
- const MAX_CODEBASE_CHARS = 8_000;
194
198
  const generatedMatch = rawContent.match(/Generated: (\S+)/);
195
199
  const generatedAt = generatedMatch?.[1] ?? "unknown";
196
- const content = rawContent.length > MAX_CODEBASE_CHARS
197
- ? rawContent.slice(0, MAX_CODEBASE_CHARS) + "\n\n*(truncated — see .gsd/CODEBASE.md for full map)*"
200
+ const content = rawContent.length > DEFAULT_CODEBASE_MAX_CHARS
201
+ ? rawContent.slice(0, DEFAULT_CODEBASE_MAX_CHARS) + "\n\n*(truncated — see .gsd/CODEBASE.md for full map)*"
198
202
  : rawContent;
199
203
  codebaseBlock = `\n\n[PROJECT CODEBASE — File structure and descriptions (generated ${generatedAt}, auto-refreshed when GSD detects tracked file changes; use /gsd codebase stats for status)]\n\n${content}`;
200
204
  }
@@ -206,6 +210,9 @@ export async function buildBeforeAgentStartResult(
206
210
  warnDeprecatedAgentInstructions();
207
211
 
208
212
  const injection = await buildGuidedExecuteContextInjection(event.prompt, process.cwd());
213
+ const memoryBlock = await loadMemoryBlock(event.prompt ?? "", {
214
+ includePromptRelevant: !(injection && isLowEntropyResumePrompt(event.prompt ?? "")),
215
+ });
209
216
 
210
217
  // Re-inject forensics context on follow-up turns (#2941)
211
218
  const forensicsInjection = !injection ? buildForensicsContextInjection(process.cwd(), event.prompt) : null;
@@ -218,12 +225,9 @@ export async function buildBeforeAgentStartResult(
218
225
  : "";
219
226
 
220
227
  // memoryBlock is FTS-queried against the user prompt and changes per call.
221
- // Removing it from `fullSystem` keeps the system-prompt cache breakpoint
222
- // stable across calls the only scoped goal of this fix. The pi-ai
223
- // Anthropic adapter additionally cache-marks the last user turn, so the
224
- // memoryBlock injected via the context message may itself be cached up to
225
- // that boundary; that's orthogonal and unchanged from prior behavior. The
226
- // load-bearing win here is preserving the system+tools cache hit. (#5019)
228
+ // Keeping it out of `fullSystem` preserves provider prompt-cache stability
229
+ // for the static system/tool prefix. The dynamic memory block rides the
230
+ // volatile context message instead. (#5019)
227
231
  const fullSystem = `${event.systemPrompt}\n\n[SYSTEM CONTEXT — GSD]\n\n${systemContent}${preferenceBlock}${knowledgeBlock}${codebaseBlock}${newSkillsBlock}${worktreeBlock}${subagentModelBlock}`;
228
232
 
229
233
  stopContextTimer({
@@ -255,21 +259,55 @@ export function buildContextMessage(opts: {
255
259
  injection: string | null;
256
260
  forensicsInjection: string | null;
257
261
  }): { customType: string; content: string; display: false } | null {
258
- const memoryContent = opts.memoryBlock.trim();
262
+ const contextCharLimit = getContextMessageCharLimit();
263
+ const memoryContent = markMemoryContextSupplied(opts.memoryBlock.trim());
259
264
  if (opts.injection) {
260
- const content = memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection;
265
+ const content = limitContextMessageContent(
266
+ memoryContent ? `${memoryContent}\n\n${opts.injection}` : opts.injection,
267
+ contextCharLimit,
268
+ );
261
269
  return { customType: "gsd-guided-context", content, display: false as const };
262
270
  }
263
271
  if (opts.forensicsInjection) {
264
- const content = memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection;
272
+ const content = limitContextMessageContent(
273
+ memoryContent ? `${memoryContent}\n\n${opts.forensicsInjection}` : opts.forensicsInjection,
274
+ contextCharLimit,
275
+ );
265
276
  return { customType: "gsd-forensics", content, display: false as const };
266
277
  }
267
278
  if (memoryContent) {
268
- return { customType: "gsd-memory", content: memoryContent, display: false as const };
279
+ return {
280
+ customType: "gsd-memory",
281
+ content: limitContextMessageContent(memoryContent, contextCharLimit),
282
+ display: false as const,
283
+ };
269
284
  }
270
285
  return null;
271
286
  }
272
287
 
288
+ function getContextMessageCharLimit(): number | null {
289
+ const raw = process.env.PI_GSD_CONTEXT_MAX_CHARS;
290
+ if (!raw) return DEFAULT_CONTEXT_MESSAGE_MAX_CHARS;
291
+ if (raw === "0") return null;
292
+ const parsed = Number(raw);
293
+ if (!Number.isFinite(parsed) || parsed < MIN_CONTEXT_MESSAGE_MAX_CHARS) {
294
+ return DEFAULT_CONTEXT_MESSAGE_MAX_CHARS;
295
+ }
296
+ return Math.floor(parsed);
297
+ }
298
+
299
+ function limitContextMessageContent(content: string, limit: number | null): string {
300
+ if (!limit || content.length <= limit) return content;
301
+ const suffix = "\n\n[GSD Context Truncated]\nFull context is available from the referenced .gsd files and tools; read on demand only if this excerpt lacks required evidence.";
302
+ const headBudget = Math.max(0, limit - suffix.length);
303
+ return `${content.slice(0, headBudget).trimEnd()}${suffix}`;
304
+ }
305
+
306
+ function markMemoryContextSupplied(memoryContent: string): string {
307
+ if (!memoryContent) return "";
308
+ return `[GSD Context Metadata]\n- Memory supplied: yes\n\n${memoryContent}`;
309
+ }
310
+
273
311
  /**
274
312
  * ADR-013 step 4 — auto-injection parity for the memories table.
275
313
  *
@@ -288,7 +326,10 @@ export function buildContextMessage(opts: {
288
326
  * with a token-budget cap. Failures degrade gracefully — the function never
289
327
  * throws and returns "" so the system prompt construction continues.
290
328
  */
291
- export async function loadMemoryBlock(userPrompt: string): Promise<string> {
329
+ export async function loadMemoryBlock(
330
+ userPrompt: string,
331
+ opts: { includePromptRelevant?: boolean } = {},
332
+ ): Promise<string> {
292
333
  try {
293
334
  const { formatMemoriesForPrompt, getActiveMemoriesRanked, queryMemoriesRanked } = await import("../memory-store.js");
294
335
 
@@ -310,7 +351,7 @@ export async function loadMemoryBlock(userPrompt: string): Promise<string> {
310
351
 
311
352
  let relevant: typeof allRanked = [];
312
353
  const trimmed = userPrompt.trim();
313
- if (trimmed) {
354
+ if (trimmed && opts.includePromptRelevant !== false) {
314
355
  const hits = queryMemoriesRanked({ query: trimmed, k: QUERY_K });
315
356
  relevant = hits.map((h) => h.memory).filter((m) => !criticalIds.has(m.id));
316
357
  }
@@ -362,14 +403,37 @@ export function loadKnowledgeBlock(gsdHomeDir: string, cwd: string): { block: st
362
403
  }
363
404
 
364
405
  const parts: string[] = [];
365
- if (globalKnowledge) parts.push(`## Global Knowledge\n\n${globalKnowledge}`);
366
- if (projectKnowledge) parts.push(`## Project Knowledge\n\n${projectKnowledge}`);
406
+ if (globalKnowledge) {
407
+ parts.push(`## Global Knowledge\nSource: \`${globalKnowledgePath}\`\n\n${globalKnowledge}`);
408
+ }
409
+ if (projectKnowledge) {
410
+ parts.push(`## Project Knowledge\nSource: \`${knowledgePath}\`\n\n${projectKnowledge}`);
411
+ }
412
+ const body = limitKnowledgeBlock(parts.join("\n\n"), getKnowledgeCharLimit());
367
413
  return {
368
- block: `\n\n[KNOWLEDGE — Rules, patterns, and lessons learned]\n\n${parts.join("\n\n")}`,
414
+ block: `\n\n[KNOWLEDGE — Rules, patterns, and lessons learned]\n\n${body}`,
369
415
  globalSizeKb,
370
416
  };
371
417
  }
372
418
 
419
+ function getKnowledgeCharLimit(): number | null {
420
+ const raw = process.env.PI_GSD_KNOWLEDGE_MAX_CHARS;
421
+ if (!raw) return DEFAULT_KNOWLEDGE_MAX_CHARS;
422
+ if (raw === "0") return null;
423
+ const parsed = Number(raw);
424
+ if (!Number.isFinite(parsed) || parsed < MIN_KNOWLEDGE_MAX_CHARS) {
425
+ return DEFAULT_KNOWLEDGE_MAX_CHARS;
426
+ }
427
+ return Math.floor(parsed);
428
+ }
429
+
430
+ function limitKnowledgeBlock(content: string, limit: number | null): string {
431
+ if (!limit || content.length <= limit) return content;
432
+ const suffix = "\n\n[Knowledge Truncated]\nFull KNOWLEDGE.md content remains available at the source path(s) above; read on demand only if this excerpt lacks a required rule.";
433
+ const headBudget = Math.max(0, limit - suffix.length);
434
+ return `${content.slice(0, headBudget).trimEnd()}${suffix}`;
435
+ }
436
+
373
437
  function buildWorktreeContextBlock(): string {
374
438
  const worktreeName = getActiveWorktreeName();
375
439
  const worktreeMainCwd = getWorktreeOriginalCwd();
@@ -423,6 +487,11 @@ function buildWorktreeContextBlock(): string {
423
487
  */
424
488
  const RESUME_INTENT_PATTERNS = /^(continue|resume|ok|go|go ahead|proceed|keep going|carry on|next|yes|yeah|yep|sure|do it|let's go|pick up where you left off)$/;
425
489
 
490
+ export function isLowEntropyResumePrompt(prompt: string): boolean {
491
+ const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
492
+ return RESUME_INTENT_PATTERNS.test(trimmed);
493
+ }
494
+
426
495
  async function buildGuidedExecuteContextInjection(prompt: string, basePath: string): Promise<string | null> {
427
496
  const ensureStateDbOpen = async () => {
428
497
  const { ensureDbOpen } = await import("./dynamic-tools.js");
@@ -452,8 +521,7 @@ async function buildGuidedExecuteContextInjection(prompt: string, basePath: stri
452
521
  // control/help/diagnostic prompts with unrelated execution context.
453
522
  // Phase-gated: only fire during "executing" to avoid misrouting during
454
523
  // replanning, gate evaluation, or other non-execution phases.
455
- const trimmed = prompt.trim().toLowerCase().replace(/[.!?,]+$/g, "");
456
- if (RESUME_INTENT_PATTERNS.test(trimmed)) {
524
+ if (isLowEntropyResumePrompt(prompt)) {
457
525
  await ensureStateDbOpen();
458
526
  const state = await deriveState(basePath);
459
527
  if (state.phase === "executing" && state.activeTask && state.activeMilestone && state.activeSlice) {
@@ -3,13 +3,13 @@
3
3
  *
4
4
  * #2909: Adds a fast-path git status check before milestone completion merges.
5
5
  * When the working tree is dirty the user is warned and changes are auto-stashed
6
- * so the merge can proceed cleanly. After the merge completes, postflightPopStash
7
- * restores the stashed changes.
6
+ * so the merge can proceed cleanly. After the merge completes, postflightPopStash
7
+ * restores the stashed changes and reports whether manual recovery is needed.
8
8
  *
9
9
  * Design constraints (from Trek-e approval):
10
10
  * - Warn the user before stashing (no silent surprises)
11
11
  * - git stash push / git stash pop only — no custom stash management layer
12
- * - Stash/pop errors are logged but MUST NOT block the merge
12
+ * - Stash/pop errors are logged but MUST NOT block the merge itself
13
13
  * - Fast-path status check — clean trees pay no extra cost
14
14
  */
15
15
 
@@ -21,10 +21,41 @@ import { nativeHasChanges } from "./native-git-bridge.js";
21
21
  export interface PreflightResult {
22
22
  /** true when a stash was pushed and postflightPopStash should be called */
23
23
  stashPushed: boolean;
24
+ /** Unique marker embedded in the stash message for targeted restoration */
25
+ stashMarker?: string;
24
26
  /** human-readable summary of what happened (empty string for clean trees) */
25
27
  summary: string;
26
28
  }
27
29
 
30
+ export interface PostflightResult {
31
+ restored: boolean;
32
+ needsManualRecovery: boolean;
33
+ message: string;
34
+ stashRef?: string;
35
+ }
36
+
37
+ function findPreflightStashRef(basePath: string, milestoneId: string, stashMarker?: string): string | null {
38
+ const markerPrefix = `gsd-preflight-stash:${milestoneId}:`;
39
+ let fallbackRef: string | null = null;
40
+ try {
41
+ const list = execFileSync("git", ["stash", "list", "--format=%gd%x00%s"], {
42
+ cwd: basePath,
43
+ stdio: ["ignore", "pipe", "pipe"],
44
+ encoding: "utf-8",
45
+ env: GIT_NO_PROMPT_ENV,
46
+ });
47
+ for (const line of list.split("\n")) {
48
+ const [ref, subject] = line.split("\x00");
49
+ if (!ref || !subject) continue;
50
+ if (stashMarker && subject.includes(stashMarker)) return ref;
51
+ if (!fallbackRef && subject.includes(markerPrefix)) fallbackRef = ref;
52
+ }
53
+ } catch (err) {
54
+ logWarning("preflight", `stash list failed before restore: ${err instanceof Error ? err.message : String(err)}`);
55
+ }
56
+ return fallbackRef;
57
+ }
58
+
28
59
  /**
29
60
  * Check the working tree for dirty files before a milestone merge.
30
61
  *
@@ -62,7 +93,8 @@ export function preflightCleanRoot(
62
93
 
63
94
  // Push the stash
64
95
  try {
65
- execFileSync("git", ["stash", "push", "--include-untracked", "-m", "gsd-preflight-stash"], {
96
+ const stashMarker = `gsd-preflight-stash:${milestoneId}:${process.pid}:${Date.now()}:${process.hrtime.bigint().toString(36)}`;
97
+ execFileSync("git", ["stash", "push", "--include-untracked", "-m", `gsd-preflight-stash [${stashMarker}]`], {
66
98
  cwd: basePath,
67
99
  stdio: ["ignore", "pipe", "pipe"],
68
100
  encoding: "utf-8",
@@ -70,6 +102,7 @@ export function preflightCleanRoot(
70
102
  });
71
103
  return {
72
104
  stashPushed: true,
105
+ stashMarker,
73
106
  summary: `Stashed uncommitted changes before merge (milestone ${milestoneId}).`,
74
107
  };
75
108
  } catch (err) {
@@ -86,26 +119,56 @@ export function preflightCleanRoot(
86
119
  *
87
120
  * Only called when preflightCleanRoot returned stashPushed=true.
88
121
  * Any pop error (e.g. conflict) is logged and notified but does NOT throw —
89
- * the merge already completed successfully.
122
+ * the merge already completed successfully. Callers must treat
123
+ * needsManualRecovery=true as a dirty workspace stop, not a clean completion.
90
124
  */
91
125
  export function postflightPopStash(
92
126
  basePath: string,
93
127
  milestoneId: string,
128
+ stashMarker: string | undefined,
94
129
  notify: (message: string, level: "info" | "warning" | "error") => void,
95
- ): void {
130
+ ): PostflightResult {
131
+ let stashRef: string | null = null;
96
132
  try {
97
- execFileSync("git", ["stash", "pop"], {
133
+ stashRef = findPreflightStashRef(basePath, milestoneId, stashMarker);
134
+ if (!stashRef) {
135
+ const msg = `No matching GSD preflight stash found for milestone ${milestoneId}; leaving stash list untouched.`;
136
+ logWarning("preflight", msg);
137
+ notify(msg, "warning");
138
+ return {
139
+ restored: false,
140
+ needsManualRecovery: true,
141
+ message: msg,
142
+ };
143
+ }
144
+ execFileSync("git", ["stash", "pop", stashRef], {
98
145
  cwd: basePath,
99
146
  stdio: ["ignore", "pipe", "pipe"],
100
147
  encoding: "utf-8",
101
148
  env: GIT_NO_PROMPT_ENV,
102
149
  });
103
- notify(`Restored stashed changes after milestone ${milestoneId} merge.`, "info");
150
+ const msg = `Restored stashed changes after milestone ${milestoneId} merge.`;
151
+ notify(msg, "info");
152
+ return {
153
+ restored: true,
154
+ needsManualRecovery: false,
155
+ message: msg,
156
+ stashRef,
157
+ };
104
158
  } catch (err) {
105
159
  // Pop conflicts mean the merged code collides with the stashed changes.
106
160
  // Log a warning — the user needs to resolve manually, but the merge succeeded.
107
- const msg = `git stash pop failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. Run "git stash pop" manually to restore your changes.`;
161
+ const restoreHint = stashRef
162
+ ? `Run "git stash pop ${stashRef}" or "git stash apply ${stashRef}" manually to restore the correct stash.`
163
+ : `Run "git stash list" to find the matching GSD preflight stash before restoring manually.`;
164
+ const msg = `git stash pop ${stashRef ?? ""}`.trim() + ` failed after merge of milestone ${milestoneId}: ${err instanceof Error ? err.message : String(err)}. ${restoreHint}`;
108
165
  logWarning("preflight", msg);
109
166
  notify(msg, "warning");
167
+ return {
168
+ restored: false,
169
+ needsManualRecovery: true,
170
+ message: msg,
171
+ ...(stashRef ? { stashRef } : {}),
172
+ };
110
173
  }
111
174
  }
@@ -45,5 +45,11 @@ export async function handleGSDCommand(
45
45
 
46
46
  if (handled) return;
47
47
 
48
+ if (trimmed.includes(" ")) {
49
+ const { handleDo } = await import("../commands-do.js");
50
+ await handleDo(trimmed, ctx, pi);
51
+ return;
52
+ }
53
+
48
54
  ctx.ui.notify(`Unknown: /gsd ${trimmed}. Run /gsd help for available commands.`, "warning");
49
55
  }
@@ -1,3 +1,5 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Handles operational /gsd subcommands.
1
3
  import type { ExtensionAPI, ExtensionCommandContext } from "@gsd/pi-coding-agent";
2
4
 
3
5
  import { enableDebug } from "../../debug-logger.js";
@@ -15,7 +17,7 @@ import { handleRemote } from "../../../remote-questions/mod.js";
15
17
  import { handleShip } from "../../commands-ship.js";
16
18
  import { handleSessionReport } from "../../commands-session-report.js";
17
19
  import { handlePrBranch } from "../../commands-pr-branch.js";
18
- import { projectRoot } from "../context.js";
20
+ import { currentDirectoryRoot, projectRoot } from "../context.js";
19
21
 
20
22
  export async function handleOpsCommand(trimmed: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<boolean> {
21
23
  if (trimmed === "init") {
@@ -117,7 +119,7 @@ export async function handleOpsCommand(trimmed: string, ctx: ExtensionCommandCon
117
119
  return true;
118
120
  }
119
121
  if (trimmed === "triage") {
120
- await handleTriage(ctx, pi, process.cwd());
122
+ await handleTriage(ctx, pi, currentDirectoryRoot());
121
123
  return true;
122
124
  }
123
125
  if (trimmed === "config") {
@@ -23,7 +23,7 @@ export const TOOL_KEYS = [
23
23
  { id: "groq", env: "GROQ_API_KEY", label: "Groq Voice", hint: "console.groq.com" },
24
24
  ] as const;
25
25
 
26
- function getStoredToolKey(auth: AuthStorage, providerId: string): string | undefined {
26
+ export function getStoredToolKey(auth: AuthStorage, providerId: string): string | undefined {
27
27
  const creds = auth.getCredentialsForProvider(providerId);
28
28
  const cred = creds.find((c) => c.type === "api_key" && c.key);
29
29
  return cred?.type === "api_key" ? cred.key : undefined;
@@ -26,6 +26,15 @@ import { isAutoActive, checkRemoteAutoSession } from "./auto.js";
26
26
  import { getAutoWorktreePath } from "./auto-worktree.js";
27
27
  import { currentDirectoryRoot, projectRoot } from "./commands/context.js";
28
28
  import { loadPrompt } from "./prompt-loader.js";
29
+ import {
30
+ buildDoctorHealIssuePayload,
31
+ buildDoctorHealSummary,
32
+ buildWorkflowDispatchContent,
33
+ } from "./workflow-protocol.js";
34
+ import {
35
+ restoreGsdWorkflowTools,
36
+ scopeGsdWorkflowToolsForDispatch,
37
+ } from "./bootstrap/register-hooks.js";
29
38
 
30
39
  const UPDATE_REGISTRY_URL = "https://registry.npmjs.org/gsd-pi/latest";
31
40
  const UPDATE_FETCH_TIMEOUT_MS = 5000;
@@ -72,18 +81,23 @@ export function dispatchDoctorHeal(pi: ExtensionAPI, scope: string | undefined,
72
81
  const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(gsdHome(), "agent", "GSD-WORKFLOW.md");
73
82
  const workflow = readFileSync(workflowPath, "utf-8");
74
83
  const prompt = loadPrompt("doctor-heal", {
75
- doctorSummary: reportText,
76
- structuredIssues,
84
+ doctorSummary: buildDoctorHealSummary(reportText),
85
+ structuredIssues: buildDoctorHealIssuePayload(structuredIssues),
77
86
  scopeLabel: scope ?? "active milestone / blocking scope",
78
87
  doctorCommandSuffix: scope ? ` ${scope}` : "",
79
88
  });
80
89
 
81
- const content = `Read the following GSD workflow protocol and execute exactly.\n\n${workflow}\n\n## Your Task\n\n${prompt}`;
90
+ const content = buildWorkflowDispatchContent({ workflow, workflowPath, task: prompt });
91
+ const savedTools = scopeGsdWorkflowToolsForDispatch(pi);
82
92
 
83
- pi.sendMessage(
84
- { customType: "gsd-doctor-heal", content, display: false },
85
- { triggerTurn: true },
86
- );
93
+ try {
94
+ pi.sendMessage(
95
+ { customType: "gsd-doctor-heal", content, display: false },
96
+ { triggerTurn: true },
97
+ );
98
+ } finally {
99
+ restoreGsdWorkflowTools(pi, savedTools);
100
+ }
87
101
  }
88
102
 
89
103
  /** Parse doctor command args into structured flags and positionals (pure, no I/O). */
@@ -258,15 +272,20 @@ export async function handleTriage(ctx: ExtensionCommandContext, pi: ExtensionAP
258
272
 
259
273
  const workflowPath = process.env.GSD_WORKFLOW_PATH ?? join(gsdHome(), "agent", "GSD-WORKFLOW.md");
260
274
  const workflow = readFileSync(workflowPath, "utf-8");
275
+ const savedTools = scopeGsdWorkflowToolsForDispatch(pi);
261
276
 
262
- pi.sendMessage(
263
- {
264
- customType: "gsd-triage",
265
- content: `Read the following GSD workflow protocol and execute exactly.\n\n${workflow}\n\n## Your Task\n\n${prompt}`,
266
- display: false,
267
- },
268
- { triggerTurn: true },
269
- );
277
+ try {
278
+ pi.sendMessage(
279
+ {
280
+ customType: "gsd-triage",
281
+ content: buildWorkflowDispatchContent({ workflow, workflowPath, task: prompt }),
282
+ display: false,
283
+ },
284
+ { triggerTurn: true },
285
+ );
286
+ } finally {
287
+ restoreGsdWorkflowTools(pi, savedTools);
288
+ }
270
289
  }
271
290
 
272
291
  export async function handleSteer(change: string, ctx: ExtensionCommandContext, pi: ExtensionAPI): Promise<void> {
@@ -8,7 +8,12 @@
8
8
  * @see D001 (module location), D002 (200K fallback), D003 (section-boundary truncation)
9
9
  */
10
10
 
11
- import { type TokenProvider, getCharsPerToken } from "./token-counter.js";
11
+ import {
12
+ type TokenProvider,
13
+ getCharsPerToken,
14
+ isAccurateCountingAvailable,
15
+ countTokensSync,
16
+ } from "./token-counter.js";
12
17
 
13
18
  // ─── Budget ratio constants ──────────────────────────────────────────────────
14
19
  // Percentages of total context window allocated to each budget category.
@@ -32,6 +37,24 @@ const DEFAULT_CONTEXT_WINDOW = 200_000;
32
37
  /** Conservative effective context for Claude Code subscription routing (#4676) */
33
38
  const CLAUDE_CODE_EFFECTIVE_CONTEXT_WINDOW = 200_000;
34
39
 
40
+ /**
41
+ * Cached empirical chars-per-token from a tiktoken probe, keyed by provider.
42
+ * countTokensSync's fallback path is provider-aware, so we cache per-provider
43
+ * to preserve that distinction once the encoder warms. The cl100k_base encoder
44
+ * itself gives a stable ratio for ASCII English so a single probe per provider
45
+ * key is sufficient. Empty map means "not yet probed" or "encoder unavailable".
46
+ */
47
+ const _empiricalCharsPerTokenByProvider = new Map<string, number>();
48
+
49
+ /**
50
+ * Test hook — clears the empirical chars-per-token cache so test cases that
51
+ * assert against the static char-ratio fallback aren't polluted by a prior
52
+ * tiktoken-warmed run in the same process. Production code must not call this.
53
+ */
54
+ export function _resetEmpiricalCacheForTest(): void {
55
+ _empiricalCharsPerTokenByProvider.clear();
56
+ }
57
+
35
58
  /** Percentage of context consumed before suggesting a continue-here checkpoint */
36
59
  const CONTINUE_THRESHOLD_PERCENT = 70;
37
60
 
@@ -101,7 +124,26 @@ export interface MinimalPreferences {
101
124
  export function computeBudgets(contextWindow: number, provider?: TokenProvider): BudgetAllocation {
102
125
  const effectiveWindow = contextWindow > 0 ? contextWindow : DEFAULT_CONTEXT_WINDOW;
103
126
  const charsPerToken = provider ? getCharsPerToken(provider) : CHARS_PER_TOKEN;
104
- const totalChars = effectiveWindow * charsPerToken;
127
+
128
+ // Prefer the tiktoken encoder for total-char estimation when it has been
129
+ // warmed (initTokenCounter resolved). The cl100k_base ratio is stable for
130
+ // ASCII English, so probe once per provider and cache — computeBudgets is
131
+ // called multiple times per prompt build and the probe encode is otherwise
132
+ // wasted work.
133
+ let totalChars: number;
134
+ if (isAccurateCountingAvailable()) {
135
+ const providerKey = provider ?? "__default__";
136
+ let empirical = _empiricalCharsPerTokenByProvider.get(providerKey);
137
+ if (empirical === undefined) {
138
+ const probe = "the quick brown fox jumps over the lazy dog ".repeat(64);
139
+ const probeTokens = countTokensSync(probe, provider);
140
+ empirical = probeTokens > 0 ? probe.length / probeTokens : charsPerToken;
141
+ _empiricalCharsPerTokenByProvider.set(providerKey, empirical);
142
+ }
143
+ totalChars = effectiveWindow * empirical;
144
+ } else {
145
+ totalChars = effectiveWindow * charsPerToken;
146
+ }
105
147
 
106
148
  return {
107
149
  summaryBudgetChars: Math.floor(totalChars * SUMMARY_RATIO),
@@ -38,6 +38,7 @@ import { _getAdapter, isDbAvailable } from "./gsd-db.js";
38
38
  import { gsdRoot, normalizeRealPath } from "./paths.js";
39
39
  import { atomicWriteSync } from "./atomic-write.js";
40
40
  import { effectiveLockFile } from "./session-lock.js";
41
+ import { isInFlightRuntimePhase, listUnitRuntimeRecords, type AutoUnitRuntimeRecord } from "./unit-runtime.js";
41
42
 
42
43
  export interface LockData {
43
44
  pid: number;
@@ -103,10 +104,40 @@ function getLatestDispatchForWorker(workerId: string):
103
104
  return row ?? null;
104
105
  }
105
106
 
106
- function workerToLockData(worker: AutoWorkerRow): LockData {
107
+ function latestInFlightRuntimeRecord(basePath: string): AutoUnitRuntimeRecord | null {
108
+ const records = listUnitRuntimeRecords(basePath).filter((record) =>
109
+ isInFlightRuntimePhase(record.phase),
110
+ );
111
+ if (records.length === 0) return null;
112
+ return records.sort((a, b) => {
113
+ const bTime = b.updatedAt || b.startedAt || 0;
114
+ const aTime = a.updatedAt || a.startedAt || 0;
115
+ return bTime - aTime;
116
+ })[0] ?? null;
117
+ }
118
+
119
+ function runtimeRecordToLockData(worker: AutoWorkerRow, record: AutoUnitRuntimeRecord, sessionFile?: string): LockData {
120
+ const startedAt = Number.isFinite(record.startedAt)
121
+ ? new Date(record.startedAt).toISOString()
122
+ : worker.started_at;
123
+ return {
124
+ pid: worker.pid,
125
+ startedAt: worker.started_at,
126
+ unitType: record.unitType,
127
+ unitId: record.unitId,
128
+ unitStartedAt: startedAt,
129
+ sessionFile,
130
+ };
131
+ }
132
+
133
+ function workerToLockData(basePath: string, worker: AutoWorkerRow): LockData {
107
134
  const dispatch = getLatestDispatchForWorker(worker.worker_id);
108
135
  const sessionFile =
109
136
  getRuntimeKv<string>("worker", worker.worker_id, SESSION_FILE_KV_KEY) ?? undefined;
137
+ if (!dispatch) {
138
+ const runtimeRecord = latestInFlightRuntimeRecord(basePath);
139
+ if (runtimeRecord) return runtimeRecordToLockData(worker, runtimeRecord, sessionFile);
140
+ }
110
141
  return {
111
142
  pid: worker.pid,
112
143
  startedAt: worker.started_at,
@@ -204,7 +235,7 @@ export function readCrashLock(basePath: string): LockData | null {
204
235
  try {
205
236
  const projectRoot = normalizeRealPath(basePath);
206
237
  const stale = findStaleWorkerForProject(projectRoot);
207
- if (stale) return workerToLockData(stale);
238
+ if (stale) return workerToLockData(basePath, stale);
208
239
  } catch {
209
240
  // Fall through to the legacy lock-file compatibility path.
210
241
  }
@@ -260,25 +291,48 @@ export function formatCrashInfo(lock: LockData): string {
260
291
  */
261
292
  export function emitCrashRecoveredUnitEnd(basePath: string, lock: LockData): void {
262
293
  if (!lock.unitType || !lock.unitId || lock.unitType === "starting") return;
294
+ emitOpenUnitEndForUnit(basePath, lock.unitType, lock.unitId, "crash-recovered");
295
+ }
263
296
 
297
+ export function emitOpenUnitEndForUnit(
298
+ basePath: string,
299
+ unitType: string,
300
+ unitId: string,
301
+ status: string,
302
+ errorContext?: { message: string; category: string; stopReason?: string; isTransient?: boolean; retryAfterMs?: number },
303
+ ): boolean {
264
304
  try {
265
305
  const all = queryJournal(basePath);
266
306
 
267
307
  const starts = all.filter(
268
- (e) => e.eventType === "unit-start" && e.data?.unitId === lock.unitId,
308
+ (e) =>
309
+ e.eventType === "unit-start" &&
310
+ e.data?.unitType === unitType &&
311
+ e.data?.unitId === unitId,
269
312
  );
270
- if (starts.length === 0) return;
313
+ if (starts.length === 0) return false;
271
314
 
272
- const lastStart = starts[starts.length - 1];
315
+ const lastStart = [...starts].reverse().find((start) => {
316
+ return !all.some(
317
+ (e) =>
318
+ e.eventType === "unit-end" &&
319
+ e.data?.unitType === unitType &&
320
+ e.data?.unitId === unitId &&
321
+ e.causedBy?.flowId === start.flowId &&
322
+ e.causedBy?.seq === start.seq,
323
+ );
324
+ });
325
+ if (!lastStart) return false;
273
326
 
274
327
  const alreadyClosed = all.some(
275
328
  (e) =>
276
329
  e.eventType === "unit-end" &&
277
- e.data?.unitId === lock.unitId &&
330
+ e.data?.unitType === unitType &&
331
+ e.data?.unitId === unitId &&
278
332
  e.causedBy?.flowId === lastStart.flowId &&
279
333
  e.causedBy?.seq === lastStart.seq,
280
334
  );
281
- if (alreadyClosed) return;
335
+ if (alreadyClosed) return false;
282
336
 
283
337
  const maxSeq = all
284
338
  .filter((e) => e.flowId === lastStart.flowId)
@@ -290,15 +344,18 @@ export function emitCrashRecoveredUnitEnd(basePath: string, lock: LockData): voi
290
344
  seq: maxSeq + 1,
291
345
  eventType: "unit-end",
292
346
  data: {
293
- unitType: lock.unitType,
294
- unitId: lock.unitId,
295
- status: "crash-recovered",
347
+ unitType,
348
+ unitId,
349
+ status,
296
350
  artifactVerified: false,
351
+ ...(errorContext ? { errorContext } : {}),
297
352
  },
298
353
  causedBy: { flowId: lastStart.flowId, seq: lastStart.seq },
299
354
  });
355
+ return true;
300
356
  } catch {
301
357
  // Never throw from crash recovery path.
358
+ return false;
302
359
  }
303
360
  }
304
361