gsd-pi 2.80.0-dev.c5f2443b3 → 2.80.0-dev.d4fc28e6b

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 (580) hide show
  1. package/README.md +4 -2
  2. package/dist/cli.js +0 -19
  3. package/dist/resources/.managed-resources-content-hash +1 -1
  4. package/dist/resources/GSD-WORKFLOW.md +2 -2
  5. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +29 -0
  6. package/dist/resources/extensions/github-sync/templates.js +39 -8
  7. package/dist/resources/extensions/gsd/auto/loop.js +119 -18
  8. package/dist/resources/extensions/gsd/auto/phases.js +212 -135
  9. package/dist/resources/extensions/gsd/auto/resolve.js +29 -0
  10. package/dist/resources/extensions/gsd/auto/run-unit.js +41 -45
  11. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  12. package/dist/resources/extensions/gsd/auto/workflow-dispatch-claim.js +33 -1
  13. package/dist/resources/extensions/gsd/auto/workflow-worker-heartbeat.js +9 -1
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  15. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  16. package/dist/resources/extensions/gsd/auto-dispatch.js +26 -0
  17. package/dist/resources/extensions/gsd/auto-post-unit.js +27 -14
  18. package/dist/resources/extensions/gsd/auto-prompts.js +214 -17
  19. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  20. package/dist/resources/extensions/gsd/auto-start.js +199 -9
  21. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  22. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  23. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  24. package/dist/resources/extensions/gsd/auto.js +95 -27
  25. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +103 -3
  26. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  27. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  28. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  29. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  30. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  31. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  32. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +330 -55
  33. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  34. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  35. package/dist/resources/extensions/gsd/clean-root-preflight.js +65 -9
  36. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  37. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  38. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  39. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  40. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  41. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  42. package/dist/resources/extensions/gsd/db/unit-dispatches.js +92 -0
  43. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  44. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  45. package/dist/resources/extensions/gsd/detection.js +106 -0
  46. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  47. package/dist/resources/extensions/gsd/git-service.js +36 -4
  48. package/dist/resources/extensions/gsd/graph.js +9 -3
  49. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  50. package/dist/resources/extensions/gsd/guided-flow.js +129 -44
  51. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  52. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  53. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  54. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  55. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  56. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  57. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  58. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  59. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  60. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  61. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  62. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  63. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  64. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  65. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  66. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  67. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  68. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  70. package/dist/resources/extensions/gsd/quick.js +34 -2
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  72. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  73. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  74. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  75. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  76. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  77. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  78. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  79. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  80. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  81. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  82. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  83. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  84. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  85. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  86. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  87. package/dist/web/standalone/.next/BUILD_ID +1 -1
  88. package/dist/web/standalone/.next/app-path-routes-manifest.json +11 -11
  89. package/dist/web/standalone/.next/build-manifest.json +3 -3
  90. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  91. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  92. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  93. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  97. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  99. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  101. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  102. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  103. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  104. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  105. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  106. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  107. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  108. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  109. package/dist/web/standalone/.next/server/app/index.html +1 -1
  110. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  116. package/dist/web/standalone/.next/server/app-paths-manifest.json +11 -11
  117. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  118. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  119. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  120. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  121. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  122. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  123. package/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  124. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  125. package/dist/welcome-screen.d.ts +2 -0
  126. package/dist/welcome-screen.js +9 -7
  127. package/package.json +12 -8
  128. package/packages/contracts/package.json +1 -1
  129. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  130. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  131. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  132. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  133. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  134. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  135. package/packages/native/tsconfig.tsbuildinfo +1 -1
  136. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  137. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  138. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  139. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  140. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  141. package/packages/pi-agent-core/dist/agent.js +2 -0
  142. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  143. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  144. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  145. package/packages/pi-agent-core/dist/index.js +2 -0
  146. package/packages/pi-agent-core/dist/index.js.map +1 -1
  147. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  148. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  149. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  150. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  151. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  152. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  153. package/packages/pi-agent-core/dist/types.js.map +1 -1
  154. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  155. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  156. package/packages/pi-agent-core/src/agent.ts +8 -0
  157. package/packages/pi-agent-core/src/index.ts +2 -0
  158. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  159. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  160. package/packages/pi-agent-core/src/types.ts +14 -0
  161. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  162. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  163. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  164. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  165. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  166. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  167. package/packages/pi-ai/dist/models/index.js +8 -0
  168. package/packages/pi-ai/dist/models/index.js.map +1 -1
  169. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  170. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  171. package/packages/pi-ai/dist/providers/fake.js +319 -0
  172. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  173. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  174. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  175. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  176. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  177. package/packages/pi-ai/src/models/index.ts +9 -0
  178. package/packages/pi-ai/src/providers/fake.ts +376 -0
  179. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  180. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  181. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  182. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  184. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  186. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  188. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
  190. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  192. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  193. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  194. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  195. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  196. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  197. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  198. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  199. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  200. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  201. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  202. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  203. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  204. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  205. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  206. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  207. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  208. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  209. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +5 -0
  211. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/core/extensions/runner.js +20 -7
  213. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +102 -3
  215. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  216. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  217. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  218. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  219. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  220. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  221. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  222. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  223. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  224. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  225. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  226. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  227. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  228. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  229. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  231. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  233. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  234. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  235. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  236. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  237. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  238. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  239. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  240. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  241. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  242. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  243. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  244. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  245. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  246. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  247. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  248. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  249. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  250. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  251. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  252. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  253. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  254. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  255. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  256. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  257. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  258. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  259. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  260. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  261. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  262. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  263. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  264. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  265. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  266. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  267. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
  269. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +109 -17
  271. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +69 -2
  274. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
  276. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  277. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  278. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  280. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  281. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  283. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +26 -0
  285. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  288. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  290. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  291. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  292. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  293. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  294. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  295. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  296. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  298. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  301. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  303. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  304. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  305. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  306. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  307. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  308. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  309. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  310. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  311. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  312. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  313. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  314. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  315. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  316. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  317. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  318. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  319. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  320. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  321. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  322. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
  323. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  324. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  325. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  326. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  327. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  328. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +113 -3
  329. package/packages/pi-coding-agent/src/core/extensions/runner.ts +24 -6
  330. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  331. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  332. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  333. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  334. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  335. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  336. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  337. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  338. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  339. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  340. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  341. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  342. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  343. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  344. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  345. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  346. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  347. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
  348. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
  349. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
  350. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  351. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  352. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
  353. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  354. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  355. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  356. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  357. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  358. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  359. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  360. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  361. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  362. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  363. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  364. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  365. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  366. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  367. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  368. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  369. package/packages/pi-tui/dist/index.d.ts +1 -0
  370. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  371. package/packages/pi-tui/dist/index.js +2 -0
  372. package/packages/pi-tui/dist/index.js.map +1 -1
  373. package/packages/pi-tui/dist/style.d.ts +41 -0
  374. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  375. package/packages/pi-tui/dist/style.js +158 -0
  376. package/packages/pi-tui/dist/style.js.map +1 -0
  377. package/packages/pi-tui/dist/tui.d.ts +0 -1
  378. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  379. package/packages/pi-tui/dist/tui.js +21 -16
  380. package/packages/pi-tui/dist/tui.js.map +1 -1
  381. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  382. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  383. package/packages/pi-tui/src/index.ts +9 -0
  384. package/packages/pi-tui/src/style.ts +225 -0
  385. package/packages/pi-tui/src/tui.ts +23 -16
  386. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  387. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  388. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  389. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  390. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  391. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  392. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  393. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  394. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  395. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  396. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  397. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  398. package/src/resources/GSD-WORKFLOW.md +2 -2
  399. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +30 -0
  400. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +26 -0
  401. package/src/resources/extensions/github-sync/templates.ts +38 -8
  402. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  403. package/src/resources/extensions/gsd/auto/loop-deps.ts +3 -2
  404. package/src/resources/extensions/gsd/auto/loop.ts +151 -26
  405. package/src/resources/extensions/gsd/auto/phases.ts +289 -196
  406. package/src/resources/extensions/gsd/auto/resolve.ts +42 -1
  407. package/src/resources/extensions/gsd/auto/run-unit.ts +52 -44
  408. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  409. package/src/resources/extensions/gsd/auto/workflow-dispatch-claim.ts +63 -1
  410. package/src/resources/extensions/gsd/auto/workflow-worker-heartbeat.ts +14 -1
  411. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  412. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  413. package/src/resources/extensions/gsd/auto-dispatch.ts +33 -0
  414. package/src/resources/extensions/gsd/auto-post-unit.ts +28 -14
  415. package/src/resources/extensions/gsd/auto-prompts.ts +228 -16
  416. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  417. package/src/resources/extensions/gsd/auto-start.ts +237 -15
  418. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  419. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  420. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  421. package/src/resources/extensions/gsd/auto.ts +110 -22
  422. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +119 -2
  423. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  424. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  425. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  426. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  427. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  428. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  429. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +386 -55
  430. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  431. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  432. package/src/resources/extensions/gsd/clean-root-preflight.ts +72 -9
  433. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  434. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  435. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  436. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  437. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  438. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  439. package/src/resources/extensions/gsd/db/unit-dispatches.ts +107 -0
  440. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  441. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  442. package/src/resources/extensions/gsd/detection.ts +128 -0
  443. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  444. package/src/resources/extensions/gsd/git-service.ts +46 -8
  445. package/src/resources/extensions/gsd/graph.ts +12 -5
  446. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  447. package/src/resources/extensions/gsd/guided-flow.ts +150 -51
  448. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  449. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  450. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  451. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  452. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  453. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  454. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  455. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  456. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  457. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  458. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  459. package/src/resources/extensions/gsd/prompts/complete-milestone.md +21 -19
  460. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  461. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  462. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  463. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  464. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  465. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  466. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  467. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  468. package/src/resources/extensions/gsd/quick.ts +37 -2
  469. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  470. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  471. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  472. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  473. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +516 -15
  474. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  475. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  476. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  477. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +97 -2
  478. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  479. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  480. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  481. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  482. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  483. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  484. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  485. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  486. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +117 -7
  487. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  488. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  489. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  490. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  491. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  492. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  493. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  494. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  495. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  496. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  497. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  498. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  499. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  500. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  501. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  502. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  503. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  504. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  505. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  506. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  507. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  508. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  509. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  510. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  511. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  512. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  513. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  514. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  515. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  516. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  517. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  518. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  519. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  520. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  521. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  522. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  523. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  524. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  525. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  526. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  527. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  528. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  529. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  530. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  531. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  532. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  533. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  534. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +77 -0
  535. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +166 -0
  536. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  537. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
  538. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  539. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  540. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  541. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  542. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  543. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  544. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  545. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  546. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +80 -1
  547. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  548. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  549. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  550. package/src/resources/extensions/gsd/tests/workflow-dispatch-claim.test.ts +142 -0
  551. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  552. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  553. package/src/resources/extensions/gsd/tests/workflow-worker-heartbeat.test.ts +32 -1
  554. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  555. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  556. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  557. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  558. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  559. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  560. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  561. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  562. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  563. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  564. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  565. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  566. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  567. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  568. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  569. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  570. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  571. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  572. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  573. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  574. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  575. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  576. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  577. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  578. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  579. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_buildManifest.js +0 -0
  580. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → cWaxzf-sdbSSbbwYu8q7a}/_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) {
@@ -1,10 +1,12 @@
1
- import { copyFileSync, existsSync, mkdirSync, readFileSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
1
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, realpathSync, renameSync, unlinkSync, writeFileSync } from "node:fs";
2
2
  import { isAbsolute, join, relative, resolve, sep } from "node:path";
3
3
 
4
4
  import { minimatch } from "minimatch";
5
5
 
6
+ import { getIsolationMode } from "../preferences.js";
6
7
  import type { ToolsPolicy } from "../unit-context-manifest.js";
7
8
  import { logWarning } from "../workflow-logger.js";
9
+ import { isGsdWorktreePath, resolveWorktreeProjectRoot } from "../worktree-root.js";
8
10
 
9
11
  /**
10
12
  * Regex matching milestone CONTEXT.md file names in both legacy M001
@@ -882,3 +884,135 @@ export function shouldBlockPlanningUnit(
882
884
  // avoids breaking gsd_* MCP tools or future safe additions.
883
885
  return { block: false };
884
886
  }
887
+
888
+ // ─── Worktree isolation write gate (#5199) ────────────────────────────────
889
+ //
890
+ // When `git.isolation: worktree` is configured, the per-unit commit pipeline
891
+ // only runs inside the auto-mode loop (`auto-post-unit.ts`). If the LLM
892
+ // authors code at the project root before auto-mode is started, those writes
893
+ // land in the working tree but never reach a commit — they're silently
894
+ // orphaned outside git history. This guard blocks those writes at the
895
+ // tool_call seam so the agent receives a clear error instead.
896
+
897
+ const WORKTREE_GATE_BOOTSTRAP_UNITS = new Set([
898
+ "discuss-milestone",
899
+ "plan-milestone",
900
+ "init",
901
+ ]);
902
+
903
+ function realpathOrResolve(p: string): string {
904
+ const abs = resolve(p);
905
+ try {
906
+ return realpathSync(abs);
907
+ } catch {
908
+ // Path doesn't exist (yet) — realpath the deepest existing ancestor so
909
+ // platforms where /tmp -> /private/tmp don't break containment checks.
910
+ let dir = abs;
911
+ const tail: string[] = [];
912
+ while (dir && dir !== resolve(dir, "..")) {
913
+ try {
914
+ const real = realpathSync(dir);
915
+ return tail.length ? join(real, ...tail.reverse()) : real;
916
+ } catch {
917
+ const idx = dir.lastIndexOf(sep);
918
+ if (idx <= 0) break;
919
+ tail.push(dir.slice(idx + 1));
920
+ dir = dir.slice(0, idx) || sep;
921
+ }
922
+ }
923
+ return abs;
924
+ }
925
+ }
926
+
927
+ function isPathContained(target: string, container: string): boolean {
928
+ if (target === container) return true;
929
+ return target.startsWith(container.endsWith(sep) ? container : container + sep);
930
+ }
931
+
932
+ /**
933
+ * Block planning-write tool calls that would land code at the project root
934
+ * while `git.isolation: worktree` is in effect and auto-mode hasn't created
935
+ * (or flipped cwd into) the milestone worktree.
936
+ *
937
+ * Pure / unit-testable. Callers in `register-hooks.ts` supply the resolved
938
+ * project root and current auto liveness; this function does no I/O beyond
939
+ * realpath resolution.
940
+ *
941
+ * Allow rules (in order):
942
+ * 1. Tool isn't a planning-write (write/edit/multi_edit/notebook_edit).
943
+ * 2. `GSD_DISABLE_WORKTREE_WRITE_GUARD=1` self-hosting bypass.
944
+ * 3. Isolation mode is not "worktree".
945
+ * 4. Active unit is a bootstrap unit (discuss-milestone/plan-milestone/init).
946
+ * 5. Target is inside `<projectRoot>/.gsd/worktrees/` (a real worktree).
947
+ * 6. Target is inside `<projectRoot>/.gsd/` and isn't masquerading as a
948
+ * worktrees sibling (rejects the `.gsd/worktrees-extra/…` prefix trick).
949
+ * 7. Auto is live AND `effectiveBasePath` is itself a `.gsd/worktrees/…` path.
950
+ *
951
+ * Otherwise: block with a message that points the agent at `/gsd` to start
952
+ * auto-mode.
953
+ */
954
+ export function shouldBlockWorktreeWrite(
955
+ toolName: string,
956
+ targetPath: string,
957
+ effectiveBasePath: string,
958
+ isAutoLive: boolean,
959
+ currentUnitType?: string | null,
960
+ ): { block: boolean; reason?: string } {
961
+ const tool = canonicalToolName(toolName);
962
+ if (!PLANNING_WRITE_TOOLS.has(tool)) return { block: false };
963
+ if (process.env.GSD_DISABLE_WORKTREE_WRITE_GUARD === "1") return { block: false };
964
+ if (getIsolationMode(effectiveBasePath) !== "worktree") return { block: false };
965
+ if (currentUnitType && WORKTREE_GATE_BOOTSTRAP_UNITS.has(currentUnitType)) return { block: false };
966
+
967
+ if (!targetPath) {
968
+ return {
969
+ block: true,
970
+ reason: [
971
+ `HARD BLOCK: ${tool} called with empty path while \`git.isolation: worktree\` is configured`,
972
+ `and auto-mode is not active. Refusing to allow writes that cannot be located.`,
973
+ ].join(" "),
974
+ };
975
+ }
976
+
977
+ // Resolve the target relative to the project root, then realpath to defeat
978
+ // symlink-based escapes and prefix tricks (e.g. .gsd/worktrees-extra/).
979
+ const projectRoot = resolveWorktreeProjectRoot(effectiveBasePath);
980
+ const absTarget = isAbsolute(targetPath) ? targetPath : resolve(projectRoot, targetPath);
981
+ const realTarget = realpathOrResolve(absTarget);
982
+ const realRoot = realpathOrResolve(projectRoot);
983
+ const realGsd = realpathOrResolve(join(projectRoot, ".gsd"));
984
+ const realWorktreesDir = realpathOrResolve(join(projectRoot, ".gsd", "worktrees"));
985
+
986
+ // Allow writes inside the legitimate worktrees subtree.
987
+ if (isPathContained(realTarget, realWorktreesDir)) return { block: false };
988
+
989
+ // Allow writes to .gsd/ planning artifacts, but reject siblings whose name
990
+ // starts with "worktrees" (the worktrees-extra prefix trick — case 4).
991
+ if (isPathContained(realTarget, realGsd)) {
992
+ const rel = relative(realGsd, realTarget);
993
+ const firstSeg = rel.split(/[\/\\]/)[0] ?? "";
994
+ if (!firstSeg.startsWith("worktrees")) return { block: false };
995
+ // fall through: looks like worktrees<something> sibling — block
996
+ }
997
+
998
+ // Auto is live and the caller is operating inside a worktree path —
999
+ // host tool's write happens in worktree context; let it through.
1000
+ if (isAutoLive && isGsdWorktreePath(effectiveBasePath)) return { block: false };
1001
+
1002
+ // Block. Provide enough context that the agent can self-correct.
1003
+ const displayTarget = isPathContained(realTarget, realRoot)
1004
+ ? relative(realRoot, realTarget) || "."
1005
+ : realTarget;
1006
+ return {
1007
+ block: true,
1008
+ reason: [
1009
+ `HARD BLOCK: Worktree isolation is configured (\`git.isolation: worktree\`) but auto-mode is`,
1010
+ `not running and the target "${displayTarget}" is not inside \`.gsd/worktrees/<MID>/\`.`,
1011
+ `Code edits at the project root would be lost — only the auto-mode commit pipeline`,
1012
+ `(auto-post-unit) commits work, and it never runs outside the loop.`,
1013
+ `Required action: start auto-mode with \`/gsd\` so the milestone worktree is created,`,
1014
+ `then write inside it. To disable this guard for self-hosting development, set`,
1015
+ `GSD_DISABLE_WORKTREE_WRITE_GUARD=1.`,
1016
+ ].join(" "),
1017
+ };
1018
+ }
@@ -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
  }
@@ -222,14 +222,19 @@ Using the \`write\` tool, persist the full structured report to
222
222
  LEARNINGS.md is the full, cited audit trail. Write it first — subsequent steps
223
223
  feed from its content.
224
224
 
225
- ### Step 3 — Optionally pre-query the memory store for semantic duplicates
225
+ ### Step 3 — Run one bounded duplicate check
226
226
 
227
- Before persisting any extracted item in Steps 4–6, you may call
228
- \`memory_query\` with 2–3 keywords from the item to check whether the
229
- memory store already holds a semantically equivalent entry at high
230
- confidence. Skip those items in their respective steps. The memory store
231
- is the single source of truth for cross-session durable knowledge — no
232
- other persistence call is part of this flow.
227
+ Before persisting extracted items in Steps 4–6, do at most one duplicate-check
228
+ pass for the durable Decisions, Lessons, and Patterns from this milestone. Use
229
+ the already-written LEARNINGS.md content and call \`memory_query\` once with a
230
+ compact keyword summary for the whole batch. If that result clearly shows a
231
+ semantically equivalent high-confidence memory for an item, mark only that item
232
+ as already captured and skip it in its respective persistence step.
233
+
234
+ Do not re-read milestone artefacts or repeat memory queries category-by-category
235
+ after this point. The memory store is the single source of truth for
236
+ cross-session durable knowledge — no other persistence call is part of this
237
+ flow.
233
238
 
234
239
  ### Step 4 — Persist Patterns via \`capture_thought\`
235
240
 
@@ -268,11 +273,11 @@ later projection back to a human-visible decisions register stays lossless
268
273
 
269
274
  ### Step 7 — Deduplication rule (applies to Steps 4, 5, 6)
270
275
 
271
- Before each \`capture_thought\` call, optionally call \`memory_query\` with 2–3
272
- keywords from the entry. If a semantically equivalent memory is returned at
273
- high confidence, skip the capture entirely. Prefer skipping a near-duplicate
274
- over creating a second slightly-different row — redundancy degrades the
275
- signal.
276
+ Use only the duplicate-check result from Step 3. If that bounded check returned
277
+ a semantically equivalent memory at high confidence for an extracted item, skip
278
+ the capture entirely. Otherwise, persist the item once via \`capture_thought\`.
279
+ Prefer skipping a near-duplicate over creating a second slightly-different row
280
+ — redundancy degrades the signal.
276
281
 
277
282
  ### Step 8 — Surprises stay only in LEARNINGS.md
278
283
 
@@ -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> {