gsd-pi 2.80.0-dev.2848d9009 → 2.80.0-dev.3065f7bfa

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 (377) hide show
  1. package/README.md +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/extensions/gsd/auto/loop.js +32 -1
  4. package/dist/resources/extensions/gsd/auto/phases.js +178 -108
  5. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  6. package/dist/resources/extensions/gsd/auto/run-unit.js +20 -30
  7. package/dist/resources/extensions/gsd/auto/session.js +8 -0
  8. package/dist/resources/extensions/gsd/auto-direct-dispatch.js +5 -32
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -0
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +17 -4
  11. package/dist/resources/extensions/gsd/auto-prompts.js +103 -16
  12. package/dist/resources/extensions/gsd/auto-recovery.js +43 -1
  13. package/dist/resources/extensions/gsd/auto-start.js +197 -6
  14. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  15. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  16. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  17. package/dist/resources/extensions/gsd/auto.js +86 -26
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +42 -2
  19. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +49 -36
  20. package/dist/resources/extensions/gsd/bootstrap/dynamic-tools.js +15 -5
  21. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +33 -20
  22. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +7 -1
  23. package/dist/resources/extensions/gsd/bootstrap/memory-tools.js +9 -3
  24. package/dist/resources/extensions/gsd/bootstrap/query-tools.js +8 -2
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +259 -28
  26. package/dist/resources/extensions/gsd/bootstrap/system-context.js +82 -23
  27. package/dist/resources/extensions/gsd/clean-root-preflight.js +24 -6
  28. package/dist/resources/extensions/gsd/commands-handlers.js +23 -9
  29. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  30. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  31. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  32. package/dist/resources/extensions/gsd/db-base-schema.js +4 -2
  33. package/dist/resources/extensions/gsd/db-migration-steps.js +6 -0
  34. package/dist/resources/extensions/gsd/ecosystem/gsd-extension-api.js +2 -0
  35. package/dist/resources/extensions/gsd/git-service.js +36 -4
  36. package/dist/resources/extensions/gsd/gsd-db.js +46 -13
  37. package/dist/resources/extensions/gsd/guided-flow.js +99 -38
  38. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  39. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  40. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  41. package/dist/resources/extensions/gsd/native-git-bridge.js +32 -8
  42. package/dist/resources/extensions/gsd/orphan-stash-audit.js +101 -0
  43. package/dist/resources/extensions/gsd/parallel-orchestrator.js +13 -3
  44. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  45. package/dist/resources/extensions/gsd/pre-execution-checks.js +22 -0
  46. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  47. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  48. package/dist/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  49. package/dist/resources/extensions/gsd/prompts/execute-task.md +4 -2
  50. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  51. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  52. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  53. package/dist/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  54. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  55. package/dist/resources/extensions/gsd/quick.js +34 -2
  56. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  57. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  58. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  59. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  60. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  61. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  62. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  63. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  64. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  65. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  66. package/dist/resources/extensions/gsd/workflow-protocol.js +131 -0
  67. package/dist/resources/extensions/gsd/worktree-resolver.js +68 -21
  68. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  69. package/dist/web/standalone/.next/BUILD_ID +1 -1
  70. package/dist/web/standalone/.next/app-path-routes-manifest.json +15 -15
  71. package/dist/web/standalone/.next/build-manifest.json +2 -2
  72. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  73. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.html +1 -1
  90. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  95. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  96. package/dist/web/standalone/.next/server/app-paths-manifest.json +15 -15
  97. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  98. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  99. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  100. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  101. package/package.json +3 -3
  102. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  103. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  104. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  105. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  106. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  107. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  108. package/packages/native/tsconfig.tsbuildinfo +1 -1
  109. package/packages/pi-agent-core/dist/agent-loop.d.ts.map +1 -1
  110. package/packages/pi-agent-core/dist/agent-loop.js +4 -1
  111. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  112. package/packages/pi-agent-core/dist/agent.d.ts +5 -0
  113. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  114. package/packages/pi-agent-core/dist/agent.js +2 -0
  115. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  116. package/packages/pi-agent-core/dist/index.d.ts +1 -0
  117. package/packages/pi-agent-core/dist/index.d.ts.map +1 -1
  118. package/packages/pi-agent-core/dist/index.js +2 -0
  119. package/packages/pi-agent-core/dist/index.js.map +1 -1
  120. package/packages/pi-agent-core/dist/token-audit.d.ts +47 -0
  121. package/packages/pi-agent-core/dist/token-audit.d.ts.map +1 -0
  122. package/packages/pi-agent-core/dist/token-audit.js +221 -0
  123. package/packages/pi-agent-core/dist/token-audit.js.map +1 -0
  124. package/packages/pi-agent-core/dist/types.d.ts +9 -0
  125. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  126. package/packages/pi-agent-core/dist/types.js.map +1 -1
  127. package/packages/pi-agent-core/src/agent-loop.test.ts +128 -0
  128. package/packages/pi-agent-core/src/agent-loop.ts +4 -1
  129. package/packages/pi-agent-core/src/agent.ts +8 -0
  130. package/packages/pi-agent-core/src/index.ts +2 -0
  131. package/packages/pi-agent-core/src/token-audit.test.ts +189 -0
  132. package/packages/pi-agent-core/src/token-audit.ts +287 -0
  133. package/packages/pi-agent-core/src/types.ts +14 -0
  134. package/packages/pi-agent-core/tsconfig.tsbuildinfo +1 -1
  135. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  136. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  137. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js +18 -0
  138. package/packages/pi-coding-agent/dist/core/agent-session-tool-refresh.test.js.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/agent-session.d.ts +12 -0
  140. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  141. package/packages/pi-coding-agent/dist/core/agent-session.js +44 -7
  142. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  143. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +3 -1
  144. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  145. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  146. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  147. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  148. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  149. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  150. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  151. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  152. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  153. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  154. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  155. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  156. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  157. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  158. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  159. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  160. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  161. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/extensions/loader.js +8 -0
  163. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
  165. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/extensions/runner.js +6 -6
  167. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +5 -3
  169. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +39 -1
  171. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  172. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  173. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js +2 -0
  174. package/packages/pi-coding-agent/dist/core/hooks-runner.test.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts +2 -0
  176. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.d.ts.map +1 -0
  177. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js +46 -0
  178. package/packages/pi-coding-agent/dist/core/sdk-tool-filter.test.js.map +1 -0
  179. package/packages/pi-coding-agent/dist/core/sdk.d.ts +10 -2
  180. package/packages/pi-coding-agent/dist/core/sdk.d.ts.map +1 -1
  181. package/packages/pi-coding-agent/dist/core/sdk.js +74 -2
  182. package/packages/pi-coding-agent/dist/core/sdk.js.map +1 -1
  183. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +20 -0
  184. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  185. package/packages/pi-coding-agent/dist/core/settings-manager.js +25 -0
  186. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/core/skill-tool.test.js +22 -0
  188. package/packages/pi-coding-agent/dist/core/skill-tool.test.js.map +1 -1
  189. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts +6 -7
  190. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  191. package/packages/pi-coding-agent/dist/core/system-prompt.js +2 -3
  192. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  193. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +1 -0
  194. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  195. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +3 -0
  196. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  197. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  198. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +13 -5
  199. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +53 -0
  201. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  202. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +3 -0
  204. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  206. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  207. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  208. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  209. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  210. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  211. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  212. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  213. package/packages/pi-coding-agent/src/core/agent-session-tool-refresh.test.ts +25 -0
  214. package/packages/pi-coding-agent/src/core/agent-session.ts +48 -7
  215. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +3 -1
  216. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  217. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  218. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  219. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  220. package/packages/pi-coding-agent/src/core/extensions/loader.ts +10 -0
  221. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +5 -3
  222. package/packages/pi-coding-agent/src/core/extensions/runner.ts +8 -5
  223. package/packages/pi-coding-agent/src/core/extensions/types.ts +42 -1
  224. package/packages/pi-coding-agent/src/core/hooks-runner.test.ts +2 -0
  225. package/packages/pi-coding-agent/src/core/sdk-tool-filter.test.ts +60 -0
  226. package/packages/pi-coding-agent/src/core/sdk.ts +85 -3
  227. package/packages/pi-coding-agent/src/core/settings-manager.ts +39 -1
  228. package/packages/pi-coding-agent/src/core/skill-tool.test.ts +28 -0
  229. package/packages/pi-coding-agent/src/core/system-prompt.ts +8 -10
  230. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +4 -0
  231. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +56 -0
  232. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +22 -7
  233. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +3 -0
  234. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  235. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  236. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  237. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  238. package/packages/pi-tui/dist/tui.js +18 -8
  239. package/packages/pi-tui/dist/tui.js.map +1 -1
  240. package/packages/pi-tui/src/tui.ts +20 -8
  241. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  242. package/src/resources/extensions/gsd/auto/loop-deps.ts +2 -2
  243. package/src/resources/extensions/gsd/auto/loop.ts +50 -8
  244. package/src/resources/extensions/gsd/auto/phases.ts +251 -172
  245. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  246. package/src/resources/extensions/gsd/auto/run-unit.ts +25 -30
  247. package/src/resources/extensions/gsd/auto/session.ts +8 -0
  248. package/src/resources/extensions/gsd/auto-direct-dispatch.ts +8 -34
  249. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -0
  250. package/src/resources/extensions/gsd/auto-post-unit.ts +18 -4
  251. package/src/resources/extensions/gsd/auto-prompts.ts +112 -15
  252. package/src/resources/extensions/gsd/auto-recovery.ts +54 -0
  253. package/src/resources/extensions/gsd/auto-start.ts +230 -9
  254. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  255. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  256. package/src/resources/extensions/gsd/auto-worktree.ts +123 -0
  257. package/src/resources/extensions/gsd/auto.ts +98 -21
  258. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +49 -1
  259. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +50 -36
  260. package/src/resources/extensions/gsd/bootstrap/dynamic-tools.ts +16 -5
  261. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +34 -19
  262. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +8 -1
  263. package/src/resources/extensions/gsd/bootstrap/memory-tools.ts +10 -3
  264. package/src/resources/extensions/gsd/bootstrap/query-tools.ts +9 -2
  265. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +305 -28
  266. package/src/resources/extensions/gsd/bootstrap/system-context.ts +90 -22
  267. package/src/resources/extensions/gsd/clean-root-preflight.ts +32 -7
  268. package/src/resources/extensions/gsd/commands-handlers.ts +34 -15
  269. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  270. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  271. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  272. package/src/resources/extensions/gsd/db-base-schema.ts +4 -2
  273. package/src/resources/extensions/gsd/db-migration-steps.ts +8 -0
  274. package/src/resources/extensions/gsd/ecosystem/gsd-extension-api.ts +3 -0
  275. package/src/resources/extensions/gsd/git-service.ts +46 -8
  276. package/src/resources/extensions/gsd/gsd-db.ts +50 -13
  277. package/src/resources/extensions/gsd/guided-flow.ts +123 -45
  278. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  279. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  280. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  281. package/src/resources/extensions/gsd/native-git-bridge.ts +39 -6
  282. package/src/resources/extensions/gsd/orphan-stash-audit.ts +117 -0
  283. package/src/resources/extensions/gsd/parallel-orchestrator.ts +13 -3
  284. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  285. package/src/resources/extensions/gsd/pre-execution-checks.ts +23 -0
  286. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  287. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  288. package/src/resources/extensions/gsd/prompts/complete-milestone.md +16 -13
  289. package/src/resources/extensions/gsd/prompts/complete-slice.md +1 -1
  290. package/src/resources/extensions/gsd/prompts/execute-task.md +4 -2
  291. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  292. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  293. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  294. package/src/resources/extensions/gsd/prompts/replan-slice.md +2 -2
  295. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  296. package/src/resources/extensions/gsd/quick.ts +37 -2
  297. package/src/resources/extensions/gsd/tests/artifact-retry-cap.test.ts +2 -2
  298. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +417 -10
  299. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  300. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +14 -1
  301. package/src/resources/extensions/gsd/tests/auto-wrapup-inflight-guard.test.ts +168 -6
  302. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +15 -6
  303. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  304. package/src/resources/extensions/gsd/tests/complete-milestone-excerpt.test.ts +31 -0
  305. package/src/resources/extensions/gsd/tests/complete-slice-composer.test.ts +3 -2
  306. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  307. package/src/resources/extensions/gsd/tests/context-store.test.ts +7 -1
  308. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  309. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  310. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +5 -1
  311. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  312. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  313. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  314. package/src/resources/extensions/gsd/tests/execute-task-rendering.test.ts +5 -2
  315. package/src/resources/extensions/gsd/tests/fast-forward-reused-milestone-branch.test.ts +219 -0
  316. package/src/resources/extensions/gsd/tests/finalize-survivor-branch.test.ts +132 -0
  317. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  318. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +6 -3
  319. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +239 -1
  320. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +32 -0
  321. package/src/resources/extensions/gsd/tests/knowledge.test.ts +47 -0
  322. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  323. package/src/resources/extensions/gsd/tests/merge-conflict-stops-loop.test.ts +1 -0
  324. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  325. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  326. package/src/resources/extensions/gsd/tests/milestone-merge-stash-restore.test.ts +242 -0
  327. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +34 -2
  328. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +3 -0
  329. package/src/resources/extensions/gsd/tests/orphan-merge-bootstrap.test.ts +133 -0
  330. package/src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts +201 -0
  331. package/src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts +113 -0
  332. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  333. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  334. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +45 -5
  335. package/src/resources/extensions/gsd/tests/prompt-duplication-cuts.test.ts +230 -0
  336. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  337. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  338. package/src/resources/extensions/gsd/tests/query-tools-db-open.test.ts +3 -3
  339. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  340. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +38 -17
  341. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  342. package/src/resources/extensions/gsd/tests/select-resumable-milestone.test.ts +96 -0
  343. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +106 -0
  344. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  345. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +20 -0
  346. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  347. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +55 -0
  348. package/src/resources/extensions/gsd/tests/state-corruption-2945.test.ts +1 -0
  349. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  350. package/src/resources/extensions/gsd/tests/system-context-memory.test.ts +112 -0
  351. package/src/resources/extensions/gsd/tests/system-context-message-routing.test.ts +7 -9
  352. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +291 -0
  353. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  354. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  355. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  356. package/src/resources/extensions/gsd/tests/unstructured-continue-context-injection.test.ts +5 -4
  357. package/src/resources/extensions/gsd/tests/workflow-protocol-excerpt.test.ts +99 -0
  358. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  359. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +1 -0
  360. package/src/resources/extensions/gsd/tests/worktree-path-injection.test.ts +22 -19
  361. package/src/resources/extensions/gsd/tests/worktree-project-root-degrade.test.ts +66 -0
  362. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +167 -4
  363. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  364. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  365. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  366. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  367. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  368. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  369. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  370. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  371. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  372. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  373. package/src/resources/extensions/gsd/workflow-protocol.ts +160 -0
  374. package/src/resources/extensions/gsd/worktree-resolver.ts +85 -19
  375. package/src/resources/extensions/gsd/tests/phases-merge-error-stops-auto.test.ts +0 -97
  376. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → O2WvnXROue6l7nAp_4dhC}/_buildManifest.js +0 -0
  377. /package/dist/web/standalone/.next/static/{vaQ47E8aNlbbNEDoeME6G → O2WvnXROue6l7nAp_4dhC}/_ssgManifest.js +0 -0
@@ -0,0 +1,201 @@
1
+ // GSD-2 + src/resources/extensions/gsd/tests/orphan-stash-audit.test.ts
2
+ // Regression: orphaned gsd-preflight-stash entries from completed milestones
3
+ // must be auto-applied at startup so the user's pre-merge work returns.
4
+
5
+ import { describe, test, beforeEach, afterEach } from "node:test";
6
+ import assert from "node:assert/strict";
7
+ import { execFileSync } from "node:child_process";
8
+ import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync } from "node:fs";
9
+ import { tmpdir } from "node:os";
10
+ import { join } from "node:path";
11
+
12
+ import {
13
+ auditOrphanedPreflightStashes,
14
+ _isAlreadyRestoredApplyError,
15
+ } from "../orphan-stash-audit.js";
16
+
17
+ function git(cwd: string, ...args: string[]): string {
18
+ return execFileSync("git", args, {
19
+ cwd,
20
+ stdio: ["ignore", "pipe", "pipe"],
21
+ encoding: "utf-8",
22
+ env: {
23
+ ...process.env,
24
+ GIT_TERMINAL_PROMPT: "0",
25
+ GIT_AUTHOR_NAME: "test",
26
+ GIT_AUTHOR_EMAIL: "test@example.com",
27
+ GIT_COMMITTER_NAME: "test",
28
+ GIT_COMMITTER_EMAIL: "test@example.com",
29
+ },
30
+ });
31
+ }
32
+
33
+ function pushPreflightStash(repo: string, milestoneId: string, fileName: string, content: string): string {
34
+ writeFileSync(join(repo, fileName), content);
35
+ const marker = `gsd-preflight-stash:${milestoneId}:42:1700000000000:abcd`;
36
+ git(repo, "stash", "push", "--include-untracked", "-m", `gsd-preflight-stash [${marker}]`);
37
+ return marker;
38
+ }
39
+
40
+ describe("auditOrphanedPreflightStashes", () => {
41
+ let repo: string;
42
+
43
+ beforeEach(() => {
44
+ repo = mkdtempSync(join(tmpdir(), "orphan-stash-audit-"));
45
+ git(repo, "init", "-q");
46
+ git(repo, "config", "user.email", "test@example.com");
47
+ git(repo, "config", "user.name", "test");
48
+ writeFileSync(join(repo, "seed.txt"), "seed\n");
49
+ git(repo, "add", "seed.txt");
50
+ git(repo, "commit", "-q", "-m", "initial");
51
+ });
52
+
53
+ afterEach(() => {
54
+ if (repo && existsSync(repo)) {
55
+ rmSync(repo, { recursive: true, force: true });
56
+ }
57
+ });
58
+
59
+ test("returns empty result when there are no stashes", () => {
60
+ const result = auditOrphanedPreflightStashes(repo, () => true);
61
+ assert.deepEqual(result, { applied: [], warnings: [] });
62
+ });
63
+
64
+ test("applies an orphan preflight stash when its milestone is complete", () => {
65
+ pushPreflightStash(repo, "M002", "leftover.txt", "lost work\n");
66
+
67
+ // Verify the file is gone (stashed away) before the audit runs.
68
+ assert.equal(existsSync(join(repo, "leftover.txt")), false, "stash push must remove the file");
69
+
70
+ const result = auditOrphanedPreflightStashes(repo, (id) => id === "M002");
71
+
72
+ assert.equal(result.applied.length, 1, "expected exactly one stash applied");
73
+ assert.equal(result.applied[0].milestoneId, "M002");
74
+ assert.match(result.applied[0].stashRef, /^stash@\{\d+\}$/);
75
+ assert.equal(result.warnings.length, 0);
76
+
77
+ // The user's pre-merge content must be back in the working tree.
78
+ assert.equal(existsSync(join(repo, "leftover.txt")), true);
79
+ assert.equal(readFileSync(join(repo, "leftover.txt"), "utf-8"), "lost work\n");
80
+
81
+ // The stash entry must remain (apply, not pop) so the user has a backup.
82
+ const list = git(repo, "stash", "list");
83
+ assert.match(list, /gsd-preflight-stash:M002:/);
84
+ });
85
+
86
+ test("ignores stashes whose milestone is not complete", () => {
87
+ pushPreflightStash(repo, "M003", "wip.txt", "still-working\n");
88
+
89
+ const result = auditOrphanedPreflightStashes(repo, () => false);
90
+
91
+ assert.deepEqual(result, { applied: [], warnings: [] });
92
+ // File stays stashed.
93
+ assert.equal(existsSync(join(repo, "wip.txt")), false);
94
+ });
95
+
96
+ test("ignores non-gsd stash entries", () => {
97
+ writeFileSync(join(repo, "manual.txt"), "manual\n");
98
+ git(repo, "stash", "push", "--include-untracked", "-m", "user manual stash");
99
+
100
+ const result = auditOrphanedPreflightStashes(repo, () => true);
101
+
102
+ assert.deepEqual(result, { applied: [], warnings: [] });
103
+ });
104
+
105
+ test("collects a warning when the completion callback throws", () => {
106
+ pushPreflightStash(repo, "M004", "danger.txt", "boom\n");
107
+
108
+ const result = auditOrphanedPreflightStashes(repo, () => {
109
+ throw new Error("db unavailable");
110
+ });
111
+
112
+ assert.equal(result.applied.length, 0);
113
+ assert.equal(result.warnings.length, 1);
114
+ assert.match(result.warnings[0], /Could not determine completion status for M004/);
115
+ assert.match(result.warnings[0], /db unavailable/);
116
+ });
117
+
118
+ test("collects a warning when stash apply fails (conflicting working tree)", () => {
119
+ // Push a stash containing a change to seed.txt; then dirty seed.txt with
120
+ // a conflicting modification before the audit runs so apply fails.
121
+ writeFileSync(join(repo, "seed.txt"), "stashed\n");
122
+ const marker = `gsd-preflight-stash:M005:42:1700:zz`;
123
+ git(repo, "stash", "push", "-m", `gsd-preflight-stash [${marker}]`);
124
+
125
+ // Dirty the working tree so apply will conflict.
126
+ writeFileSync(join(repo, "seed.txt"), "conflicting modification\n");
127
+
128
+ const result = auditOrphanedPreflightStashes(repo, () => true);
129
+
130
+ assert.equal(result.applied.length, 0);
131
+ assert.equal(result.warnings.length, 1);
132
+ assert.match(result.warnings[0], /Could not apply orphaned preflight stash/);
133
+ assert.match(result.warnings[0], /M005/);
134
+ assert.match(result.warnings[0], /git stash apply/);
135
+
136
+ const list = git(repo, "stash", "list");
137
+ assert.match(list, /gsd-preflight-stash:M005:/);
138
+ });
139
+
140
+ test("returns empty result when basePath is not a git repo", () => {
141
+ const nonRepo = mkdtempSync(join(tmpdir(), "orphan-stash-not-repo-"));
142
+ try {
143
+ const result = auditOrphanedPreflightStashes(nonRepo, () => true);
144
+ assert.deepEqual(result, { applied: [], warnings: [] });
145
+ } finally {
146
+ rmSync(nonRepo, { recursive: true, force: true });
147
+ }
148
+ });
149
+
150
+ test("repeat run is a silent no-op when files were already restored (peer-review regression)", () => {
151
+ // Codex peer review caught: the first audit applies the stash and the
152
+ // file appears in the working tree. The stash entry stays in `git stash
153
+ // list` (apply, not pop). On the next audit, `git stash apply` exits
154
+ // non-zero with "already exists, no checkout" because the untracked file
155
+ // already exists. The original code surfaced that as a warning every
156
+ // startup. The fix detects that error and treats it as the idempotent
157
+ // steady state.
158
+ pushPreflightStash(repo, "M002", "leftover.txt", "lost work\n");
159
+
160
+ const first = auditOrphanedPreflightStashes(repo, () => true);
161
+ assert.equal(first.applied.length, 1, "first run applies");
162
+ assert.equal(first.warnings.length, 0);
163
+
164
+ const second = auditOrphanedPreflightStashes(repo, () => true);
165
+ assert.equal(second.applied.length, 0, "second run skips silently");
166
+ assert.equal(
167
+ second.warnings.length,
168
+ 0,
169
+ "second run must NOT warn — files are already restored from first run",
170
+ );
171
+ });
172
+ });
173
+
174
+ test("_isAlreadyRestoredApplyError detects the git stash apply already-exists error", () => {
175
+ // Real-world stderr produced by git when an --include-untracked stash is
176
+ // applied while the file already exists in the working tree.
177
+ const realError: { stderr: string } = {
178
+ stderr: "leftover.txt already exists, no checkout\nCould not restore untracked files from stash entry\n",
179
+ };
180
+ assert.equal(_isAlreadyRestoredApplyError(realError), true);
181
+
182
+ // Buffer-form stderr (when encoding is not set explicitly).
183
+ const bufErr = { stderr: Buffer.from("foo.ts already exists, no checkout\n") };
184
+ assert.equal(_isAlreadyRestoredApplyError(bufErr), true);
185
+
186
+ // Some Node versions surface the message in err.message.
187
+ const messageOnly = new Error("Command failed: git stash apply\nfoo.ts already exists, no checkout");
188
+ assert.equal(_isAlreadyRestoredApplyError(messageOnly), true);
189
+
190
+ // Unrelated errors must NOT be classified as already-restored.
191
+ const realConflict: { stderr: string } = {
192
+ stderr: "CONFLICT (content): Merge conflict in lib/models.ts\n",
193
+ };
194
+ assert.equal(_isAlreadyRestoredApplyError(realConflict), false);
195
+
196
+ // Defensive null/undefined handling.
197
+ assert.equal(_isAlreadyRestoredApplyError(null), false);
198
+ assert.equal(_isAlreadyRestoredApplyError(undefined), false);
199
+ assert.equal(_isAlreadyRestoredApplyError("not an error"), false);
200
+ assert.equal(_isAlreadyRestoredApplyError({}), false);
201
+ });
@@ -0,0 +1,113 @@
1
+ // GSD-2 + src/resources/extensions/gsd/tests/parallel-orchestrator-fast-forward.test.ts
2
+ // Regression: parallel-orchestrator's `_createMilestoneWorktree` must
3
+ // fast-forward a reused milestone branch onto integration before creating
4
+ // the worktree, matching the behavior added to the auto-mode path in
5
+ // commit 8996cb68e (#5549 post-merge audit, R3).
6
+
7
+ import { describe, test, beforeEach, afterEach } from "node:test";
8
+ import assert from "node:assert/strict";
9
+ import { execFileSync } from "node:child_process";
10
+ import { mkdtempSync, rmSync, writeFileSync, mkdirSync } from "node:fs";
11
+ import { tmpdir } from "node:os";
12
+ import { join } from "node:path";
13
+
14
+ import { _createMilestoneWorktree } from "../parallel-orchestrator.js";
15
+
16
+ const NO_PROMPT_ENV = {
17
+ ...process.env,
18
+ GIT_TERMINAL_PROMPT: "0",
19
+ GIT_AUTHOR_NAME: "test",
20
+ GIT_AUTHOR_EMAIL: "test@example.com",
21
+ GIT_COMMITTER_NAME: "test",
22
+ GIT_COMMITTER_EMAIL: "test@example.com",
23
+ };
24
+
25
+ function git(cwd: string, ...args: string[]): string {
26
+ return execFileSync("git", args, {
27
+ cwd,
28
+ stdio: ["ignore", "pipe", "pipe"],
29
+ encoding: "utf-8",
30
+ env: NO_PROMPT_ENV,
31
+ });
32
+ }
33
+
34
+ function rev(cwd: string, ref: string): string {
35
+ return git(cwd, "rev-parse", ref).trim();
36
+ }
37
+
38
+ describe("_createMilestoneWorktree fast-forwards reused milestone branches (#5549 R3)", () => {
39
+ let repo: string;
40
+
41
+ beforeEach(() => {
42
+ repo = mkdtempSync(join(tmpdir(), "parallel-orch-ff-"));
43
+ git(repo, "init", "-q", "-b", "main");
44
+ git(repo, "config", "user.email", "test@example.com");
45
+ git(repo, "config", "user.name", "test");
46
+ writeFileSync(join(repo, "seed.txt"), "seed\n");
47
+ git(repo, "add", "seed.txt");
48
+ git(repo, "commit", "-q", "-m", "initial");
49
+ // Minimal .gsd/ structure so syncGsdStateToWorktree doesn't crash on a
50
+ // bare repo. We don't care if it copies anything — only that the FF ran.
51
+ mkdirSync(join(repo, ".gsd"), { recursive: true });
52
+ });
53
+
54
+ afterEach(() => {
55
+ rmSync(repo, { recursive: true, force: true });
56
+ });
57
+
58
+ test("reused milestone branch behind main is fast-forwarded before worktree creation", () => {
59
+ // Worker N drained M001 in a previous run, leaving milestone/M001 forked
60
+ // from old main. Worker N+1 picks up M002 — but the milestone/M002 branch
61
+ // was created from old main in a sibling run, so it's now N commits behind.
62
+ git(repo, "branch", "milestone/M002");
63
+ const m002Initial = rev(repo, "milestone/M002");
64
+
65
+ writeFileSync(join(repo, "seed.txt"), "main moved forward\n");
66
+ git(repo, "add", "seed.txt");
67
+ git(repo, "commit", "-q", "-m", "main advanced");
68
+ const mainTip = rev(repo, "main");
69
+
70
+ assert.notEqual(m002Initial, mainTip, "main must be ahead before the test");
71
+
72
+ // _createMilestoneWorktree may throw inside createWorktree/syncGsdStateToWorktree
73
+ // (e.g. if the worktree-manager has stricter requirements than this minimal
74
+ // repo provides). The fast-forward runs BEFORE those calls, so the branch
75
+ // ref should have moved regardless. Catch and assert on observable state.
76
+ try {
77
+ _createMilestoneWorktree(repo, "M002");
78
+ } catch {
79
+ // Fine — we only care that FF executed.
80
+ }
81
+
82
+ assert.equal(
83
+ rev(repo, "milestone/M002"),
84
+ mainTip,
85
+ "milestone/M002 must be fast-forwarded to main's tip before worktree is built",
86
+ );
87
+ });
88
+
89
+ test("diverged milestone branch is NOT touched (would lose work)", () => {
90
+ git(repo, "checkout", "-q", "-b", "milestone/M002");
91
+ writeFileSync(join(repo, "wip.txt"), "milestone-only work\n");
92
+ git(repo, "add", "wip.txt");
93
+ git(repo, "commit", "-q", "-m", "M002 work");
94
+ const m002Tip = rev(repo, "milestone/M002");
95
+
96
+ git(repo, "checkout", "-q", "main");
97
+ writeFileSync(join(repo, "seed.txt"), "main moved forward\n");
98
+ git(repo, "add", "seed.txt");
99
+ git(repo, "commit", "-q", "-m", "main advanced");
100
+
101
+ try {
102
+ _createMilestoneWorktree(repo, "M002");
103
+ } catch {
104
+ // ignored
105
+ }
106
+
107
+ assert.equal(
108
+ rev(repo, "milestone/M002"),
109
+ m002Tip,
110
+ "diverged milestone branch must NOT be touched — would lose committed work",
111
+ );
112
+ });
113
+ });
@@ -172,6 +172,56 @@ test('handlePlanSlice rejects invalid payloads', async () => {
172
172
  }
173
173
  });
174
174
 
175
+ test('handlePlanSlice rejects absolute task IO paths outside the active worktree', async () => {
176
+ const base = makeTmpBase();
177
+ openDatabase(join(base, '.gsd', 'gsd.db'));
178
+
179
+ try {
180
+ seedParentSlice();
181
+ const outside = join(tmpdir(), 'outside-checkout', 'index.html');
182
+ const result = await handlePlanSlice({
183
+ ...validParams(),
184
+ tasks: [
185
+ {
186
+ ...validParams().tasks[0],
187
+ inputs: [outside],
188
+ expectedOutput: [outside],
189
+ },
190
+ ],
191
+ }, base);
192
+
193
+ assert.ok('error' in result);
194
+ assert.match(result.error, /validation failed: tasks\[0\]\.inputs contains absolute path outside working directory/);
195
+ assert.equal(getSliceTasks('M001', 'S02').length, 0, 'invalid planning IO must not persist tasks');
196
+ } finally {
197
+ cleanup(base);
198
+ }
199
+ });
200
+
201
+ test('handlePlanSlice accepts absolute task IO paths inside the active worktree', async () => {
202
+ const base = makeTmpBase();
203
+ openDatabase(join(base, '.gsd', 'gsd.db'));
204
+
205
+ try {
206
+ seedParentSlice();
207
+ const inside = join(base, 'index.html');
208
+ const result = await handlePlanSlice({
209
+ ...validParams(),
210
+ tasks: [
211
+ {
212
+ ...validParams().tasks[0],
213
+ inputs: [inside],
214
+ expectedOutput: [inside],
215
+ },
216
+ ],
217
+ }, base);
218
+
219
+ assert.ok(!('error' in result), `unexpected error: ${'error' in result ? result.error : ''}`);
220
+ } finally {
221
+ cleanup(base);
222
+ }
223
+ });
224
+
175
225
  test('handlePlanSlice rejects missing parent slice', async () => {
176
226
  const base = makeTmpBase();
177
227
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -79,6 +79,27 @@ test('handlePlanTask rejects invalid payloads', async () => {
79
79
  }
80
80
  });
81
81
 
82
+ test('handlePlanTask rejects absolute task IO paths outside the active worktree', async () => {
83
+ const base = makeTmpBase();
84
+ openDatabase(join(base, '.gsd', 'gsd.db'));
85
+
86
+ try {
87
+ seedParent();
88
+ const outside = join(tmpdir(), 'outside-checkout', 'index.html');
89
+ const result = await handlePlanTask({
90
+ ...validParams(),
91
+ inputs: [outside],
92
+ expectedOutput: [outside],
93
+ }, base);
94
+
95
+ assert.ok('error' in result);
96
+ assert.match(result.error, /validation failed: inputs contains absolute path outside working directory/);
97
+ assert.equal(getTask('M001', 'S02', 'T02'), null, 'invalid planning IO must not persist the task');
98
+ } finally {
99
+ cleanup(base);
100
+ }
101
+ });
102
+
82
103
  test('handlePlanTask rejects missing parent slice', async () => {
83
104
  const base = makeTmpBase();
84
105
  openDatabase(join(base, '.gsd', 'gsd.db'));
@@ -1,3 +1,6 @@
1
+ // Project/App: GSD-2
2
+ // File Purpose: Unit tests for pre-execution validation checks.
3
+
1
4
  /**
2
5
  * pre-execution-checks.test.ts — Unit tests for pre-execution validation checks.
3
6
  *
@@ -1542,6 +1545,27 @@ describe("checkFilePathConsistency directory inputs (#4446)", () => {
1542
1545
  assert.equal(results[0].blocking, true);
1543
1546
  });
1544
1547
 
1548
+ test("runtime directory annotation is skipped as a pre-execution file dependency", (t) => {
1549
+ const tempDir = join(tmpdir(), `pre-exec-dir-runtime-${Date.now()}`);
1550
+ mkdirSync(tempDir, { recursive: true });
1551
+ t.after(() => rmSync(tempDir, { recursive: true, force: true }));
1552
+
1553
+ const tasks = [
1554
+ createTask({
1555
+ id: "T02",
1556
+ inputs: ["entries/ directory (runtime)"],
1557
+ expected_output: ["src/commands/delete.ts", "src/index.ts"],
1558
+ }),
1559
+ ];
1560
+
1561
+ const results = checkFilePathConsistency(tasks, tempDir);
1562
+ assert.deepEqual(
1563
+ results,
1564
+ [],
1565
+ "Runtime-only directory inputs are created during command execution, not required before the task starts",
1566
+ );
1567
+ });
1568
+
1545
1569
  test("tilde-prefixed input is matched against $HOME, not the project basePath", (t) => {
1546
1570
  const fakeHome = join(tmpdir(), `pre-exec-tilde-home-${Date.now()}`);
1547
1571
  const projectDir = join(tmpdir(), `pre-exec-tilde-proj-${Date.now()}`);
@@ -1597,6 +1621,20 @@ describe("checkTaskOrdering directory inputs (#4446)", () => {
1597
1621
  "Directory reference should not be treated as reading a file created later",
1598
1622
  );
1599
1623
  });
1624
+
1625
+ test("runtime directory annotation does not produce an ordering violation", () => {
1626
+ const tasks = [
1627
+ createTask({
1628
+ id: "T02",
1629
+ sequence: 0,
1630
+ inputs: ["entries/ directory (runtime)"],
1631
+ expected_output: [],
1632
+ }),
1633
+ ];
1634
+
1635
+ const results = checkTaskOrdering(tasks, "/tmp");
1636
+ assert.deepEqual(results, []);
1637
+ });
1600
1638
  });
1601
1639
 
1602
1640
  // ─── Regression Tests: checkTaskOrdering false positive for pre-execution refs (#4071) ──
@@ -1781,7 +1819,7 @@ describe("checkFilePathConsistency completed-task output exemption (#4071)", ()
1781
1819
  );
1782
1820
  });
1783
1821
 
1784
- test("pending task at higher index still causes a missing-file error", (t) => {
1822
+ test("pending task at higher index does NOT cause a duplicate consistency error (ordering check handles it)", (t) => {
1785
1823
  const tempDir = join(tmpdir(), `pre-exec-fc-pending-${Date.now()}`);
1786
1824
  mkdirSync(tempDir, { recursive: true });
1787
1825
  t.after(() => rmSync(tempDir, { recursive: true, force: true }));
@@ -1803,14 +1841,16 @@ describe("checkFilePathConsistency completed-task output exemption (#4071)", ()
1803
1841
  }),
1804
1842
  ];
1805
1843
 
1844
+ // checkFilePathConsistency suppresses the error here because checkTaskOrdering
1845
+ // will fire a more precise "sequence violation" error for the same file.
1846
+ // The combined output of runPreExecutionChecks still flags the issue — just
1847
+ // once, via the ordering check, instead of twice.
1806
1848
  const results = checkFilePathConsistency(tasks, tempDir);
1807
1849
  assert.equal(
1808
1850
  results.length,
1809
- 1,
1810
- "pending task at higher index must still be flagged the file is not available yet",
1851
+ 0,
1852
+ "consistency check must not duplicate what the ordering check already reports",
1811
1853
  );
1812
- assert.equal(results[0].blocking, true);
1813
- assert.equal(results[0].target, "artifacts/output.json");
1814
1854
  });
1815
1855
  });
1816
1856