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

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 (443) hide show
  1. package/README.md +4 -2
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +2 -2
  4. package/dist/resources/extensions/github-sync/templates.js +39 -8
  5. package/dist/resources/extensions/gsd/auto/loop.js +48 -10
  6. package/dist/resources/extensions/gsd/auto/phases.js +66 -45
  7. package/dist/resources/extensions/gsd/auto/resolve.js +17 -0
  8. package/dist/resources/extensions/gsd/auto/run-unit.js +32 -16
  9. package/dist/resources/extensions/gsd/auto-dashboard.js +51 -15
  10. package/dist/resources/extensions/gsd/auto-dispatch.js +10 -0
  11. package/dist/resources/extensions/gsd/auto-post-unit.js +10 -10
  12. package/dist/resources/extensions/gsd/auto-prompts.js +124 -2
  13. package/dist/resources/extensions/gsd/auto-recovery.js +197 -9
  14. package/dist/resources/extensions/gsd/auto-start.js +2 -3
  15. package/dist/resources/extensions/gsd/auto-supervisor.js +8 -1
  16. package/dist/resources/extensions/gsd/auto-timeout-recovery.js +2 -2
  17. package/dist/resources/extensions/gsd/auto.js +77 -5
  18. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +36 -3
  19. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +27 -20
  20. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +32 -1
  21. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +129 -1
  22. package/dist/resources/extensions/gsd/clean-root-preflight.js +42 -4
  23. package/dist/resources/extensions/gsd/commands/dispatcher.js +5 -0
  24. package/dist/resources/extensions/gsd/commands-extract-learnings.js +17 -12
  25. package/dist/resources/extensions/gsd/context-budget.js +37 -2
  26. package/dist/resources/extensions/gsd/crash-recovery.js +56 -10
  27. package/dist/resources/extensions/gsd/custom-workflow-engine.js +22 -2
  28. package/dist/resources/extensions/gsd/db/unit-dispatches.js +39 -0
  29. package/dist/resources/extensions/gsd/db-base-schema.js +18 -2
  30. package/dist/resources/extensions/gsd/db-migration-steps.js +22 -0
  31. package/dist/resources/extensions/gsd/detection.js +106 -0
  32. package/dist/resources/extensions/gsd/git-service.js +36 -4
  33. package/dist/resources/extensions/gsd/graph.js +9 -3
  34. package/dist/resources/extensions/gsd/gsd-db.js +146 -13
  35. package/dist/resources/extensions/gsd/guided-flow.js +82 -16
  36. package/dist/resources/extensions/gsd/memory-store.js +69 -12
  37. package/dist/resources/extensions/gsd/migrate/command.js +40 -1
  38. package/dist/resources/extensions/gsd/migration-auto-check.js +87 -0
  39. package/dist/resources/extensions/gsd/planning-path-scope.js +26 -0
  40. package/dist/resources/extensions/gsd/pr-evidence.js +57 -16
  41. package/dist/resources/extensions/gsd/pre-execution-checks.js +7 -0
  42. package/dist/resources/extensions/gsd/prompt-loader.js +28 -2
  43. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +19 -19
  44. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  45. package/dist/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  46. package/dist/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  47. package/dist/resources/extensions/gsd/prompts/quick-task.md +1 -5
  48. package/dist/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  49. package/dist/resources/extensions/gsd/quick.js +34 -2
  50. package/dist/resources/extensions/gsd/safety/evidence-collector.js +10 -2
  51. package/dist/resources/extensions/gsd/tools/context-mode-tool-result.js +15 -0
  52. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +5 -0
  53. package/dist/resources/extensions/gsd/tools/exec-tool.js +3 -15
  54. package/dist/resources/extensions/gsd/tools/memory-tools.js +1 -0
  55. package/dist/resources/extensions/gsd/tools/plan-slice.js +9 -0
  56. package/dist/resources/extensions/gsd/tools/plan-task.js +9 -0
  57. package/dist/resources/extensions/gsd/tools/resume-tool.js +5 -0
  58. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +1 -1
  59. package/dist/resources/extensions/gsd/unit-context-composer.js +12 -3
  60. package/dist/resources/extensions/gsd/unit-runtime.js +22 -0
  61. package/dist/resources/extensions/gsd/working-output-messages.js +64 -0
  62. package/dist/resources/extensions/gsd/worktree-manager.js +16 -14
  63. package/dist/resources/extensions/gsd/worktree-resolver.js +33 -17
  64. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  65. package/dist/web/standalone/.next/BUILD_ID +1 -1
  66. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  67. package/dist/web/standalone/.next/build-manifest.json +3 -3
  68. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  69. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  70. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  71. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  79. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  86. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  87. package/dist/web/standalone/.next/server/app/index.html +1 -1
  88. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  89. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  91. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  94. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  95. package/dist/web/standalone/.next/server/chunks/6897.js +3 -3
  96. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  97. package/dist/web/standalone/.next/server/middleware-react-loadable-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/dist/web/standalone/.next/static/chunks/{8336.6f6f30e410419aff.js → 8336.631939fb583761fa.js} +1 -1
  102. package/dist/web/standalone/.next/static/chunks/{webpack-d82dbee6356c1733.js → webpack-0481f1221120a7c6.js} +1 -1
  103. package/package.json +12 -8
  104. package/packages/contracts/package.json +1 -1
  105. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  106. package/packages/mcp-server/dist/workflow-tools.js +22 -17
  107. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  108. package/packages/mcp-server/src/workflow-tools.test.ts +75 -2
  109. package/packages/mcp-server/src/workflow-tools.ts +30 -16
  110. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  111. package/packages/native/tsconfig.tsbuildinfo +1 -1
  112. package/packages/pi-ai/dist/models/fake-model.d.ts +12 -0
  113. package/packages/pi-ai/dist/models/fake-model.d.ts.map +1 -0
  114. package/packages/pi-ai/dist/models/fake-model.js +27 -0
  115. package/packages/pi-ai/dist/models/fake-model.js.map +1 -0
  116. package/packages/pi-ai/dist/models/index.d.ts.map +1 -1
  117. package/packages/pi-ai/dist/models/index.js +8 -0
  118. package/packages/pi-ai/dist/models/index.js.map +1 -1
  119. package/packages/pi-ai/dist/providers/fake.d.ts +42 -0
  120. package/packages/pi-ai/dist/providers/fake.d.ts.map +1 -0
  121. package/packages/pi-ai/dist/providers/fake.js +319 -0
  122. package/packages/pi-ai/dist/providers/fake.js.map +1 -0
  123. package/packages/pi-ai/dist/providers/register-builtins.d.ts.map +1 -1
  124. package/packages/pi-ai/dist/providers/register-builtins.js +24 -0
  125. package/packages/pi-ai/dist/providers/register-builtins.js.map +1 -1
  126. package/packages/pi-ai/src/models/fake-model.ts +30 -0
  127. package/packages/pi-ai/src/models/index.ts +9 -0
  128. package/packages/pi-ai/src/providers/fake.ts +376 -0
  129. package/packages/pi-ai/src/providers/register-builtins.ts +23 -0
  130. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  131. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js +32 -0
  132. package/packages/pi-coding-agent/dist/core/agent-session-abort-order.test.js.map +1 -1
  133. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  134. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -0
  135. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  136. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js +76 -0
  137. package/packages/pi-coding-agent/dist/core/chat-controller-ordering.test.js.map +1 -1
  138. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts +11 -0
  139. package/packages/pi-coding-agent/dist/core/compaction/compaction.d.ts.map +1 -1
  140. package/packages/pi-coding-agent/dist/core/compaction/compaction.js +9 -0
  141. package/packages/pi-coding-agent/dist/core/compaction/compaction.js.map +1 -1
  142. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts +2 -0
  143. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.d.ts.map +1 -0
  144. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js +103 -0
  145. package/packages/pi-coding-agent/dist/core/compaction-threshold.test.js.map +1 -0
  146. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts +15 -0
  147. package/packages/pi-coding-agent/dist/core/db-snapshot.d.ts.map +1 -0
  148. package/packages/pi-coding-agent/dist/core/db-snapshot.js +66 -0
  149. package/packages/pi-coding-agent/dist/core/db-snapshot.js.map +1 -0
  150. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts +2 -0
  151. package/packages/pi-coding-agent/dist/core/db-snapshot.test.d.ts.map +1 -0
  152. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js +24 -0
  153. package/packages/pi-coding-agent/dist/core/db-snapshot.test.js.map +1 -0
  154. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts +3 -0
  155. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/core/extensions/runner.js +17 -1
  157. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js +99 -0
  159. package/packages/pi-coding-agent/dist/core/extensions/runner.test.js.map +1 -1
  160. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts +7 -0
  161. package/packages/pi-coding-agent/dist/core/extensions/types.d.ts.map +1 -1
  162. package/packages/pi-coding-agent/dist/core/extensions/types.js.map +1 -1
  163. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  164. package/packages/pi-coding-agent/dist/core/model-registry.js +5 -0
  165. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  166. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts +24 -0
  167. package/packages/pi-coding-agent/dist/core/settings-manager.d.ts.map +1 -1
  168. package/packages/pi-coding-agent/dist/core/settings-manager.js +33 -0
  169. package/packages/pi-coding-agent/dist/core/settings-manager.js.map +1 -1
  170. package/packages/pi-coding-agent/dist/core/slash-commands.d.ts.map +1 -1
  171. package/packages/pi-coding-agent/dist/core/slash-commands.js +1 -0
  172. package/packages/pi-coding-agent/dist/core/slash-commands.js.map +1 -1
  173. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js +6 -4
  174. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.js.map +1 -1
  175. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js +54 -15
  176. package/packages/pi-coding-agent/dist/modes/interactive/components/__tests__/tool-execution.test.js.map +1 -1
  177. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts +26 -0
  178. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.d.ts.map +1 -0
  179. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js +112 -0
  180. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.js.map +1 -0
  181. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts +2 -0
  182. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.d.ts.map +1 -0
  183. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js +51 -0
  184. package/packages/pi-coding-agent/dist/modes/interactive/components/adaptive-layout.test.js.map +1 -0
  185. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.d.ts.map +1 -1
  186. package/packages/pi-coding-agent/dist/modes/interactive/components/assistant-message.js.map +1 -1
  187. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  188. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +10 -9
  189. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  190. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts +3 -0
  191. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
  192. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js +11 -0
  193. package/packages/pi-coding-agent/dist/modes/interactive/components/settings-selector.js.map +1 -1
  194. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js +7 -6
  195. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.js.map +1 -1
  196. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts +17 -0
  197. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  198. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js +109 -17
  199. package/packages/pi-coding-agent/dist/modes/interactive/components/tool-execution.js.map +1 -1
  200. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.d.ts.map +1 -1
  201. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js +69 -2
  202. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.js.map +1 -1
  203. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js +93 -1
  204. package/packages/pi-coding-agent/dist/modes/interactive/controllers/chat-controller.test.js.map +1 -1
  205. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js +1 -0
  206. package/packages/pi-coding-agent/dist/modes/interactive/controllers/input-controller.test.js.map +1 -1
  207. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts +1 -0
  208. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.d.ts.map +1 -1
  209. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode-state.js.map +1 -1
  210. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts +3 -0
  211. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  212. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +26 -0
  213. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  214. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.d.ts.map +1 -1
  215. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js +20 -0
  216. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.js.map +1 -1
  217. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts +2 -0
  218. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.d.ts.map +1 -0
  219. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js +79 -0
  220. package/packages/pi-coding-agent/dist/modes/interactive/slash-command-handlers.test.js.map +1 -0
  221. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  222. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  223. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js +13 -0
  224. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  225. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts +1 -1
  226. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  227. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js +18 -1
  228. package/packages/pi-coding-agent/dist/modes/interactive/theme/theme.js.map +1 -1
  229. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  230. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js +36 -27
  231. package/packages/pi-coding-agent/dist/modes/interactive/theme/themes.js.map +1 -1
  232. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts +11 -0
  233. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.d.ts.map +1 -0
  234. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js +18 -0
  235. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.js.map +1 -0
  236. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts +2 -0
  237. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.d.ts.map +1 -0
  238. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js +48 -0
  239. package/packages/pi-coding-agent/dist/modes/interactive/tui-mode.test.js.map +1 -0
  240. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts +2 -0
  241. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.d.ts.map +1 -0
  242. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js +10 -0
  243. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage-safety-guard.test.js.map +1 -0
  244. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.d.ts.map +1 -1
  245. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js +3 -2
  246. package/packages/pi-coding-agent/dist/resources/extensions/memory/storage.js.map +1 -1
  247. package/packages/pi-coding-agent/src/core/agent-session-abort-order.test.ts +36 -0
  248. package/packages/pi-coding-agent/src/core/agent-session.ts +8 -0
  249. package/packages/pi-coding-agent/src/core/chat-controller-ordering.test.ts +89 -0
  250. package/packages/pi-coding-agent/src/core/compaction/compaction.ts +18 -0
  251. package/packages/pi-coding-agent/src/core/compaction-threshold.test.ts +121 -0
  252. package/packages/pi-coding-agent/src/core/db-snapshot.test.ts +32 -0
  253. package/packages/pi-coding-agent/src/core/db-snapshot.ts +66 -0
  254. package/packages/pi-coding-agent/src/core/extensions/runner.test.ts +110 -0
  255. package/packages/pi-coding-agent/src/core/extensions/runner.ts +19 -1
  256. package/packages/pi-coding-agent/src/core/extensions/types.ts +7 -0
  257. package/packages/pi-coding-agent/src/core/model-registry.ts +4 -0
  258. package/packages/pi-coding-agent/src/core/settings-manager.ts +51 -1
  259. package/packages/pi-coding-agent/src/core/slash-commands.ts +1 -0
  260. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/chat-frame-compaction-tone.test.ts +7 -5
  261. package/packages/pi-coding-agent/src/modes/interactive/components/__tests__/tool-execution.test.ts +78 -15
  262. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.test.ts +59 -0
  263. package/packages/pi-coding-agent/src/modes/interactive/components/adaptive-layout.ts +160 -0
  264. package/packages/pi-coding-agent/src/modes/interactive/components/assistant-message.ts +1 -0
  265. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +10 -9
  266. package/packages/pi-coding-agent/src/modes/interactive/components/settings-selector.ts +15 -0
  267. package/packages/pi-coding-agent/src/modes/interactive/components/tool-card-cleanup-and-success-runtime.test.ts +10 -9
  268. package/packages/pi-coding-agent/src/modes/interactive/components/tool-execution.ts +122 -17
  269. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.test.ts +99 -1
  270. package/packages/pi-coding-agent/src/modes/interactive/controllers/chat-controller.ts +92 -3
  271. package/packages/pi-coding-agent/src/modes/interactive/controllers/input-controller.test.ts +1 -0
  272. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode-state.ts +1 -1
  273. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +28 -0
  274. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.test.ts +95 -0
  275. package/packages/pi-coding-agent/src/modes/interactive/slash-command-handlers.ts +24 -1
  276. package/packages/pi-coding-agent/src/modes/interactive/theme/theme-schema.ts +13 -0
  277. package/packages/pi-coding-agent/src/modes/interactive/theme/theme.ts +32 -2
  278. package/packages/pi-coding-agent/src/modes/interactive/theme/themes.ts +36 -27
  279. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.test.ts +65 -0
  280. package/packages/pi-coding-agent/src/modes/interactive/tui-mode.ts +29 -0
  281. package/packages/pi-coding-agent/src/resources/extensions/memory/storage-safety-guard.test.ts +14 -0
  282. package/packages/pi-coding-agent/src/resources/extensions/memory/storage.ts +3 -2
  283. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  284. package/packages/pi-tui/dist/__tests__/style.test.d.ts +2 -0
  285. package/packages/pi-tui/dist/__tests__/style.test.d.ts.map +1 -0
  286. package/packages/pi-tui/dist/__tests__/style.test.js +63 -0
  287. package/packages/pi-tui/dist/__tests__/style.test.js.map +1 -0
  288. package/packages/pi-tui/dist/__tests__/tui.test.js +24 -3
  289. package/packages/pi-tui/dist/__tests__/tui.test.js.map +1 -1
  290. package/packages/pi-tui/dist/index.d.ts +1 -0
  291. package/packages/pi-tui/dist/index.d.ts.map +1 -1
  292. package/packages/pi-tui/dist/index.js +2 -0
  293. package/packages/pi-tui/dist/index.js.map +1 -1
  294. package/packages/pi-tui/dist/style.d.ts +41 -0
  295. package/packages/pi-tui/dist/style.d.ts.map +1 -0
  296. package/packages/pi-tui/dist/style.js +158 -0
  297. package/packages/pi-tui/dist/style.js.map +1 -0
  298. package/packages/pi-tui/dist/tui.d.ts +0 -1
  299. package/packages/pi-tui/dist/tui.d.ts.map +1 -1
  300. package/packages/pi-tui/dist/tui.js +21 -16
  301. package/packages/pi-tui/dist/tui.js.map +1 -1
  302. package/packages/pi-tui/src/__tests__/style.test.ts +76 -0
  303. package/packages/pi-tui/src/__tests__/tui.test.ts +29 -3
  304. package/packages/pi-tui/src/index.ts +9 -0
  305. package/packages/pi-tui/src/style.ts +225 -0
  306. package/packages/pi-tui/src/tui.ts +23 -16
  307. package/packages/pi-tui/tsconfig.tsbuildinfo +1 -1
  308. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts +12 -0
  309. package/pkg/dist/modes/interactive/theme/theme-schema.d.ts.map +1 -1
  310. package/pkg/dist/modes/interactive/theme/theme-schema.js +13 -0
  311. package/pkg/dist/modes/interactive/theme/theme-schema.js.map +1 -1
  312. package/pkg/dist/modes/interactive/theme/theme.d.ts +1 -1
  313. package/pkg/dist/modes/interactive/theme/theme.d.ts.map +1 -1
  314. package/pkg/dist/modes/interactive/theme/theme.js +18 -1
  315. package/pkg/dist/modes/interactive/theme/theme.js.map +1 -1
  316. package/pkg/dist/modes/interactive/theme/themes.d.ts.map +1 -1
  317. package/pkg/dist/modes/interactive/theme/themes.js +36 -27
  318. package/pkg/dist/modes/interactive/theme/themes.js.map +1 -1
  319. package/src/resources/GSD-WORKFLOW.md +2 -2
  320. package/src/resources/extensions/github-sync/templates.ts +38 -8
  321. package/src/resources/extensions/github-sync/tests/inline-code.test.ts +66 -0
  322. package/src/resources/extensions/gsd/auto/loop-deps.ts +1 -0
  323. package/src/resources/extensions/gsd/auto/loop.ts +67 -18
  324. package/src/resources/extensions/gsd/auto/phases.ts +77 -48
  325. package/src/resources/extensions/gsd/auto/resolve.ts +23 -1
  326. package/src/resources/extensions/gsd/auto/run-unit.ts +42 -15
  327. package/src/resources/extensions/gsd/auto-dashboard.ts +57 -8
  328. package/src/resources/extensions/gsd/auto-dispatch.ts +17 -0
  329. package/src/resources/extensions/gsd/auto-post-unit.ts +10 -10
  330. package/src/resources/extensions/gsd/auto-prompts.ts +133 -2
  331. package/src/resources/extensions/gsd/auto-recovery.ts +207 -7
  332. package/src/resources/extensions/gsd/auto-start.ts +7 -6
  333. package/src/resources/extensions/gsd/auto-supervisor.ts +7 -0
  334. package/src/resources/extensions/gsd/auto-timeout-recovery.ts +2 -2
  335. package/src/resources/extensions/gsd/auto.ts +92 -4
  336. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +37 -2
  337. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +27 -19
  338. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +39 -1
  339. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +135 -1
  340. package/src/resources/extensions/gsd/clean-root-preflight.ts +41 -3
  341. package/src/resources/extensions/gsd/commands/dispatcher.ts +6 -0
  342. package/src/resources/extensions/gsd/commands-extract-learnings.ts +17 -12
  343. package/src/resources/extensions/gsd/context-budget.ts +44 -2
  344. package/src/resources/extensions/gsd/crash-recovery.ts +67 -10
  345. package/src/resources/extensions/gsd/custom-workflow-engine.ts +24 -1
  346. package/src/resources/extensions/gsd/db/unit-dispatches.ts +41 -0
  347. package/src/resources/extensions/gsd/db-base-schema.ts +19 -2
  348. package/src/resources/extensions/gsd/db-migration-steps.ts +25 -0
  349. package/src/resources/extensions/gsd/detection.ts +128 -0
  350. package/src/resources/extensions/gsd/git-service.ts +46 -8
  351. package/src/resources/extensions/gsd/graph.ts +12 -5
  352. package/src/resources/extensions/gsd/gsd-db.ts +168 -13
  353. package/src/resources/extensions/gsd/guided-flow.ts +98 -16
  354. package/src/resources/extensions/gsd/memory-store.ts +77 -12
  355. package/src/resources/extensions/gsd/migrate/command.ts +47 -1
  356. package/src/resources/extensions/gsd/migration-auto-check.ts +129 -0
  357. package/src/resources/extensions/gsd/planning-path-scope.ts +35 -0
  358. package/src/resources/extensions/gsd/pr-evidence.ts +63 -5
  359. package/src/resources/extensions/gsd/pre-execution-checks.ts +7 -0
  360. package/src/resources/extensions/gsd/preferences-types.ts +1 -1
  361. package/src/resources/extensions/gsd/prompt-loader.ts +27 -2
  362. package/src/resources/extensions/gsd/prompts/complete-milestone.md +19 -19
  363. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +1 -1
  364. package/src/resources/extensions/gsd/prompts/plan-milestone.md +3 -1
  365. package/src/resources/extensions/gsd/prompts/plan-slice.md +1 -1
  366. package/src/resources/extensions/gsd/prompts/quick-task.md +1 -5
  367. package/src/resources/extensions/gsd/prompts/validate-milestone.md +2 -2
  368. package/src/resources/extensions/gsd/quick.ts +37 -2
  369. package/src/resources/extensions/gsd/safety/evidence-collector.ts +11 -2
  370. package/src/resources/extensions/gsd/tests/auto-abort-pause-regression.test.ts +7 -1
  371. package/src/resources/extensions/gsd/tests/auto-dashboard.test.ts +33 -0
  372. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +155 -5
  373. package/src/resources/extensions/gsd/tests/auto-phases-lifecycle.test.ts +56 -13
  374. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +184 -2
  375. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +88 -2
  376. package/src/resources/extensions/gsd/tests/commands-extract-learnings.test.ts +9 -0
  377. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +14 -1
  378. package/src/resources/extensions/gsd/tests/context-budget.test.ts +10 -1
  379. package/src/resources/extensions/gsd/tests/crash-handler-secondary.test.ts +55 -0
  380. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +22 -0
  381. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +112 -6
  382. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +40 -2
  383. package/src/resources/extensions/gsd/tests/db-migration-steps.integration.test.ts +428 -0
  384. package/src/resources/extensions/gsd/tests/db-schema-metadata.test.ts +2 -2
  385. package/src/resources/extensions/gsd/tests/detection.test.ts +140 -0
  386. package/src/resources/extensions/gsd/tests/dispatch-rule-coverage.test.ts +313 -0
  387. package/src/resources/extensions/gsd/tests/exec-history.test.ts +15 -0
  388. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +65 -0
  389. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-basic.md +52 -0
  390. package/src/resources/extensions/gsd/tests/fixtures/pr-body/commands-ship-empty-optionals.md +42 -0
  391. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-no-blockers.md +55 -0
  392. package/src/resources/extensions/gsd/tests/fixtures/pr-body/swarm-lane-with-blockers.md +60 -0
  393. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +10 -0
  394. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +44 -0
  395. package/src/resources/extensions/gsd/tests/has-pending-deep-stage.test.ts +33 -1
  396. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +54 -0
  397. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +234 -0
  398. package/src/resources/extensions/gsd/tests/memory-decay-factor.test.ts +90 -0
  399. package/src/resources/extensions/gsd/tests/migrate-writer-integration.test.ts +48 -0
  400. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +127 -0
  401. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +50 -0
  402. package/src/resources/extensions/gsd/tests/plan-task.test.ts +21 -0
  403. package/src/resources/extensions/gsd/tests/pr-evidence-equivalence.test.ts +102 -0
  404. package/src/resources/extensions/gsd/tests/pr-evidence-hardening.test.ts +165 -0
  405. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +38 -0
  406. package/src/resources/extensions/gsd/tests/prompt-path-audit.test.ts +40 -0
  407. package/src/resources/extensions/gsd/tests/prompt-step-ordering.test.ts +19 -0
  408. package/src/resources/extensions/gsd/tests/quick-external-gsd.test.ts +40 -0
  409. package/src/resources/extensions/gsd/tests/right-sized-workflow-prompts.test.ts +192 -0
  410. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +29 -0
  411. package/src/resources/extensions/gsd/tests/schema-v27-v28-sequence.test.ts +156 -0
  412. package/src/resources/extensions/gsd/tests/signal-handlers.test.ts +27 -0
  413. package/src/resources/extensions/gsd/tests/smart-entry-complete.test.ts +38 -0
  414. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +49 -1
  415. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +101 -2
  416. package/src/resources/extensions/gsd/tests/status-db-open.test.ts +9 -0
  417. package/src/resources/extensions/gsd/tests/unit-context-composer.test.ts +136 -4
  418. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +30 -0
  419. package/src/resources/extensions/gsd/tests/unit-runtime.test.ts +37 -0
  420. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +1 -1
  421. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +3 -0
  422. package/src/resources/extensions/gsd/tests/working-output-messages.test.ts +93 -0
  423. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +37 -6
  424. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +7 -0
  425. package/src/resources/extensions/gsd/tests/worktree-nested-git-safety.test.ts +9 -2
  426. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +63 -1
  427. package/src/resources/extensions/gsd/tests/worktree-write-gate.test.ts +179 -0
  428. package/src/resources/extensions/gsd/tools/context-mode-tool-result.ts +25 -0
  429. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +7 -7
  430. package/src/resources/extensions/gsd/tools/exec-tool.ts +4 -23
  431. package/src/resources/extensions/gsd/tools/memory-tools.ts +1 -0
  432. package/src/resources/extensions/gsd/tools/plan-slice.ts +13 -0
  433. package/src/resources/extensions/gsd/tools/plan-task.ts +10 -0
  434. package/src/resources/extensions/gsd/tools/resume-tool.ts +7 -7
  435. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +1 -1
  436. package/src/resources/extensions/gsd/unit-context-composer.ts +19 -4
  437. package/src/resources/extensions/gsd/unit-runtime.ts +25 -0
  438. package/src/resources/extensions/gsd/working-output-messages.ts +120 -0
  439. package/src/resources/extensions/gsd/worktree-manager.ts +15 -4
  440. package/src/resources/extensions/gsd/worktree-resolver.ts +36 -15
  441. package/packages/contracts/tsconfig.tsbuildinfo +0 -1
  442. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_buildManifest.js +0 -0
  443. /package/dist/web/standalone/.next/static/{bQDK5_LtkGVS64AirQgQG → -5nHJWzSdG-WkPMul_khA}/_ssgManifest.js +0 -0
@@ -0,0 +1,313 @@
1
+ // gsd-2 / dispatch rule coverage canary test
2
+ //
3
+ // Iterates DISPATCH_RULES in order against representative GSDState stubs and
4
+ // asserts that the first matching rule has the expected name and unitType
5
+ // (mirroring auto-dispatch's first-match-wins semantics). The goal is a
6
+ // canary: if a future PR adds a new rule in the wrong position and steals
7
+ // a match from an existing one, this test fails.
8
+
9
+ import test from "node:test";
10
+ import assert from "node:assert/strict";
11
+ import { mkdtempSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { tmpdir } from "node:os";
14
+
15
+ import { DISPATCH_RULES } from "../auto-dispatch.ts";
16
+ import type { DispatchContext, DispatchAction } from "../auto-dispatch.ts";
17
+ import type { GSDState } from "../types.ts";
18
+
19
+ // ─── State helpers ────────────────────────────────────────────────────────
20
+
21
+ function makeState(overrides: Partial<GSDState> = {}): GSDState {
22
+ return {
23
+ activeMilestone: { id: "M001", title: "Test Milestone" },
24
+ activeSlice: null,
25
+ activeTask: null,
26
+ phase: "pre-planning",
27
+ recentDecisions: [],
28
+ blockers: [],
29
+ nextAction: "",
30
+ registry: [],
31
+ ...overrides,
32
+ };
33
+ }
34
+
35
+ function makeCtx(basePath: string, state: GSDState, mid = "M001"): DispatchContext {
36
+ return {
37
+ basePath,
38
+ mid,
39
+ midTitle: "Test Milestone",
40
+ state,
41
+ prefs: undefined,
42
+ };
43
+ }
44
+
45
+ // ─── Disk scaffold helpers ────────────────────────────────────────────────
46
+
47
+ function writeMilestoneFile(basePath: string, mid: string, suffix: string, content = "stub\n"): void {
48
+ const dir = join(basePath, ".gsd", "milestones", mid);
49
+ mkdirSync(dir, { recursive: true });
50
+ writeFileSync(join(dir, `${mid}-${suffix}.md`), content);
51
+ }
52
+
53
+ function writeSliceFile(
54
+ basePath: string,
55
+ mid: string,
56
+ sid: string,
57
+ suffix: string,
58
+ content = "stub\n",
59
+ ): void {
60
+ const dir = join(basePath, ".gsd", "milestones", mid, "slices", sid);
61
+ mkdirSync(dir, { recursive: true });
62
+ writeFileSync(join(dir, `${sid}-${suffix}.md`), content);
63
+ }
64
+
65
+ function writeTaskPlan(basePath: string, mid: string, sid: string, tid: string): void {
66
+ const dir = join(basePath, ".gsd", "milestones", mid, "slices", sid, "tasks");
67
+ mkdirSync(dir, { recursive: true });
68
+ writeFileSync(join(dir, `${tid}-PLAN.md`), `# ${tid}\n\n## Steps\n- [ ] Step\n`);
69
+ }
70
+
71
+ // ─── Rule evaluation ──────────────────────────────────────────────────────
72
+
73
+ interface MatchEntry {
74
+ ruleName: string;
75
+ result: DispatchAction;
76
+ }
77
+
78
+ // First-match-wins semantics: walks DISPATCH_RULES in order and stops at the
79
+ // first non-null result. This mirrors the production resolver and is the
80
+ // canary against rule reordering or shadowing.
81
+ async function findFirstMatch(ctx: DispatchContext): Promise<MatchEntry | null> {
82
+ for (const rule of DISPATCH_RULES) {
83
+ const result = await rule.match(ctx);
84
+ if (result) return { ruleName: rule.name, result };
85
+ }
86
+ return null;
87
+ }
88
+
89
+ function assertMatch(
90
+ match: MatchEntry | null,
91
+ expected: { ruleName: string; action: DispatchAction["action"]; unitType?: string },
92
+ scenario: string,
93
+ ): void {
94
+ assert.ok(match, `${scenario}: no rule matched`);
95
+ assert.equal(match.ruleName, expected.ruleName, `${scenario}: matched rule mismatch`);
96
+ assert.equal(match.result.action, expected.action, `${scenario}: action mismatch`);
97
+ if (expected.action === "dispatch" && expected.unitType) {
98
+ assert.ok(
99
+ match.result.action === "dispatch" && match.result.unitType === expected.unitType,
100
+ `${scenario}: unitType mismatch (got ${
101
+ match.result.action === "dispatch" ? match.result.unitType : match.result.action
102
+ })`,
103
+ );
104
+ }
105
+ }
106
+
107
+ // ─── Tests ────────────────────────────────────────────────────────────────
108
+
109
+ test("dispatch-rule-coverage: escalating-task → stop (info)", async (t) => {
110
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-esc-"));
111
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
112
+
113
+ const ctx = makeCtx(
114
+ tmp,
115
+ makeState({
116
+ phase: "escalating-task",
117
+ activeSlice: { id: "S01", title: "Slice" },
118
+ nextAction: "Resolve escalation X",
119
+ }),
120
+ );
121
+ const match = await findFirstMatch(ctx);
122
+ assertMatch(
123
+ match,
124
+ { ruleName: "escalating-task → pause-for-escalation", action: "stop" },
125
+ "escalating-task",
126
+ );
127
+ });
128
+
129
+ test("dispatch-rule-coverage: pre-planning, no CONTEXT → discuss-milestone", async (t) => {
130
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-disc-"));
131
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
132
+
133
+ // Bare milestone dir, no CONTEXT/RESEARCH/ROADMAP files.
134
+ mkdirSync(join(tmp, ".gsd", "milestones", "M001"), { recursive: true });
135
+
136
+ const ctx = makeCtx(tmp, makeState({ phase: "pre-planning" }));
137
+ const match = await findFirstMatch(ctx);
138
+ assertMatch(
139
+ match,
140
+ {
141
+ ruleName: "pre-planning (no context) → discuss-milestone",
142
+ action: "dispatch",
143
+ unitType: "discuss-milestone",
144
+ },
145
+ "pre-planning no context",
146
+ );
147
+ });
148
+
149
+ test("dispatch-rule-coverage: pre-planning, has CONTEXT, no RESEARCH → research-milestone", async (t) => {
150
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-res-"));
151
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
152
+
153
+ writeMilestoneFile(tmp, "M001", "CONTEXT", "# Context\n");
154
+
155
+ const ctx = makeCtx(tmp, makeState({ phase: "pre-planning" }));
156
+ const match = await findFirstMatch(ctx);
157
+ assertMatch(
158
+ match,
159
+ {
160
+ ruleName: "pre-planning (no research) → research-milestone",
161
+ action: "dispatch",
162
+ unitType: "research-milestone",
163
+ },
164
+ "pre-planning no research",
165
+ );
166
+ });
167
+
168
+ test("dispatch-rule-coverage: pre-planning, has CONTEXT + RESEARCH → plan-milestone", async (t) => {
169
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-plan-m-"));
170
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
171
+
172
+ writeMilestoneFile(tmp, "M001", "CONTEXT", "# Context\n");
173
+ writeMilestoneFile(tmp, "M001", "RESEARCH", "# Research\n");
174
+
175
+ const ctx = makeCtx(tmp, makeState({ phase: "pre-planning" }));
176
+ const match = await findFirstMatch(ctx);
177
+ assertMatch(
178
+ match,
179
+ {
180
+ ruleName: "pre-planning (has research) → plan-milestone",
181
+ action: "dispatch",
182
+ unitType: "plan-milestone",
183
+ },
184
+ "pre-planning has research",
185
+ );
186
+ });
187
+
188
+ test("dispatch-rule-coverage: planning with active slice and skip_research → plan-slice", async (t) => {
189
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-plan-s-"));
190
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
191
+
192
+ writeMilestoneFile(tmp, "M001", "CONTEXT", "# Context\n");
193
+ writeMilestoneFile(tmp, "M001", "ROADMAP", "# Roadmap\n");
194
+
195
+ const state = makeState({
196
+ phase: "planning",
197
+ activeSlice: { id: "S01", title: "First Slice" },
198
+ });
199
+ const ctx: DispatchContext = {
200
+ basePath: tmp,
201
+ mid: "M001",
202
+ midTitle: "Test Milestone",
203
+ state,
204
+ // Skip slice research so the parallel/single research rules fall through.
205
+ prefs: { phases: { skip_slice_research: true } } as DispatchContext["prefs"],
206
+ };
207
+ const match = await findFirstMatch(ctx);
208
+ assertMatch(
209
+ match,
210
+ {
211
+ ruleName: "planning → plan-slice",
212
+ action: "dispatch",
213
+ unitType: "plan-slice",
214
+ },
215
+ "planning → plan-slice",
216
+ );
217
+ });
218
+
219
+ test("dispatch-rule-coverage: executing with task plan present → execute-task", async (t) => {
220
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-exec-"));
221
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
222
+
223
+ writeMilestoneFile(tmp, "M001", "CONTEXT", "# Context\n");
224
+ writeSliceFile(tmp, "M001", "S01", "PLAN", "# Plan\n");
225
+ writeTaskPlan(tmp, "M001", "S01", "T01");
226
+
227
+ const state = makeState({
228
+ phase: "executing",
229
+ activeSlice: { id: "S01", title: "First Slice" },
230
+ activeTask: { id: "T01", title: "First Task" },
231
+ });
232
+ // Disable reactive dispatch so the parallel batching rule falls through.
233
+ const ctx: DispatchContext = {
234
+ basePath: tmp,
235
+ mid: "M001",
236
+ midTitle: "Test Milestone",
237
+ state,
238
+ prefs: { reactive_execution: { enabled: false } } as DispatchContext["prefs"],
239
+ };
240
+ const match = await findFirstMatch(ctx);
241
+ assertMatch(
242
+ match,
243
+ {
244
+ ruleName: "executing → execute-task",
245
+ action: "dispatch",
246
+ unitType: "execute-task",
247
+ },
248
+ "executing → execute-task",
249
+ );
250
+ });
251
+
252
+ test("dispatch-rule-coverage: summarizing → complete-slice", async (t) => {
253
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-sum-"));
254
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
255
+
256
+ // Rule "execution-entry phase (no context)" fires for summarizing if CONTEXT
257
+ // is missing — write it so the summarizing rule wins.
258
+ writeMilestoneFile(tmp, "M001", "CONTEXT", "# Context\n");
259
+
260
+ const ctx = makeCtx(
261
+ tmp,
262
+ makeState({
263
+ phase: "summarizing",
264
+ activeSlice: { id: "S01", title: "First Slice" },
265
+ }),
266
+ );
267
+ const match = await findFirstMatch(ctx);
268
+ assertMatch(
269
+ match,
270
+ {
271
+ ruleName: "summarizing → complete-slice",
272
+ action: "dispatch",
273
+ unitType: "complete-slice",
274
+ },
275
+ "summarizing → complete-slice",
276
+ );
277
+ });
278
+
279
+ test("dispatch-rule-coverage: complete phase → stop", async (t) => {
280
+ const tmp = mkdtempSync(join(tmpdir(), "gsd-disp-cov-done-"));
281
+ t.after(() => rmSync(tmp, { recursive: true, force: true }));
282
+
283
+ const ctx = makeCtx(
284
+ tmp,
285
+ makeState({
286
+ phase: "complete",
287
+ activeMilestone: null,
288
+ lastCompletedMilestone: { id: "M001", title: "Test Milestone" },
289
+ }),
290
+ );
291
+ const match = await findFirstMatch(ctx);
292
+ assertMatch(
293
+ match,
294
+ { ruleName: "complete → stop", action: "stop" },
295
+ "complete → stop",
296
+ );
297
+ });
298
+
299
+ // ─── Ordering canary: every scenario above resolves to exactly one rule ────
300
+
301
+ test("dispatch-rule-coverage: rule registry has the expected size", () => {
302
+ // Sanity check that complements the per-state assertions: if someone adds a
303
+ // new rule, this number changes — prompting them to add a state stub above.
304
+ // Exact count is a brittle but useful canary; update when adding rules
305
+ // intentionally.
306
+ assert.equal(
307
+ DISPATCH_RULES.length,
308
+ 29,
309
+ `DISPATCH_RULES length changed (got ${DISPATCH_RULES.length}). ` +
310
+ "If you added a rule, add a state stub to dispatch-rule-coverage.test.ts " +
311
+ "and update this expected count.",
312
+ );
313
+ });
@@ -108,6 +108,21 @@ test('executeExecSearch: returns helpful empty-state message when no matches', (
108
108
  }
109
109
  });
110
110
 
111
+ test('executeExecSearch: returns disabled error when context_mode.enabled=false', () => {
112
+ const base = freshBase();
113
+ try {
114
+ writeRun(base, 'should-not-surface', { stdout: 'hidden\n' });
115
+ const result = executeExecSearch(
116
+ { query: 'hidden' },
117
+ { baseDir: base, preferences: { context_mode: { enabled: false } } },
118
+ );
119
+ assert.equal(result.isError, true);
120
+ assert.equal((result.details as { error?: string }).error, 'context_mode_disabled');
121
+ } finally {
122
+ cleanup(base);
123
+ }
124
+ });
125
+
111
126
  test('executeExecSearch: includes stdout_path and preview in details', () => {
112
127
  const base = freshBase();
113
128
  try {
@@ -7,6 +7,7 @@ import { join } from 'node:path';
7
7
  import { EXEC_DEFAULTS, runExecSandbox, type ExecSandboxOptions } from '../exec-sandbox.ts';
8
8
  import { buildExecOptions, executeGsdExec } from '../tools/exec-tool.ts';
9
9
  import { isContextModeEnabled } from '../preferences-types.ts';
10
+ import { validatePreferences } from '../preferences-validation.ts';
10
11
 
11
12
  function freshBase(): string {
12
13
  return mkdtempSync(join(tmpdir(), 'gsd-exec-test-'));
@@ -174,6 +175,52 @@ test('executeGsdExec: runs when enabled explicitly set to true', async () => {
174
175
  }
175
176
  });
176
177
 
178
+ test('executeGsdExec: forwards custom exec_env_allowlist from preferences', async () => {
179
+ const base = freshBase();
180
+ try {
181
+ const result = await executeGsdExec(
182
+ {
183
+ runtime: 'bash',
184
+ script: 'printf "allowed=%s blocked=%s\\n" "$GSD_ALLOWED" "$GSD_BLOCKED"',
185
+ },
186
+ {
187
+ baseDir: base,
188
+ preferences: {
189
+ context_mode: {
190
+ enabled: true,
191
+ exec_env_allowlist: ['GSD_ALLOWED'],
192
+ },
193
+ },
194
+ env: {
195
+ PATH: '/usr/bin:/bin',
196
+ HOME: '/tmp',
197
+ GSD_ALLOWED: 'yes',
198
+ GSD_BLOCKED: 'no',
199
+ },
200
+ },
201
+ );
202
+ assert.ok(!result.isError);
203
+ assert.match(result.content[0].text, /allowed=yes blocked=/);
204
+ assert.doesNotMatch(result.content[0].text, /blocked=no/);
205
+ } finally {
206
+ cleanup(base);
207
+ }
208
+ });
209
+
210
+ test('executeGsdExec: enforces per-call timeout override end-to-end', async () => {
211
+ const base = freshBase();
212
+ try {
213
+ const result = await executeGsdExec(
214
+ { runtime: 'bash', script: 'sleep 2', timeout_ms: 1 },
215
+ { baseDir: base, preferences: { context_mode: { enabled: true, exec_timeout_ms: 10_000 } } },
216
+ );
217
+ assert.equal(result.details.timed_out, true);
218
+ assert.equal(result.isError, true);
219
+ } finally {
220
+ cleanup(base);
221
+ }
222
+ });
223
+
177
224
  test('executeGsdExec: rejects empty script', async () => {
178
225
  const base = freshBase();
179
226
  try {
@@ -188,6 +235,24 @@ test('executeGsdExec: rejects empty script', async () => {
188
235
  }
189
236
  });
190
237
 
238
+ test('validatePreferences: rejects invalid context_mode preference values', () => {
239
+ const result = validatePreferences({
240
+ context_mode: {
241
+ enabled: 'false',
242
+ exec_timeout_ms: 999,
243
+ exec_stdout_cap_bytes: 1,
244
+ exec_digest_chars: -1,
245
+ exec_env_allowlist: ['GOOD_NAME', 'bad-name'],
246
+ },
247
+ } as any);
248
+ assert.ok(result.errors.length > 0);
249
+ assert.ok(result.errors.includes('context_mode.enabled must be a boolean'));
250
+ assert.ok(result.errors.includes('context_mode.exec_timeout_ms must be a number between 1000 and 600000'));
251
+ assert.ok(result.errors.includes('context_mode.exec_stdout_cap_bytes must be a number between 4096 and 16777216'));
252
+ assert.ok(result.errors.includes('context_mode.exec_digest_chars must be a number between 0 and 4000'));
253
+ assert.ok(result.errors.includes('context_mode.exec_env_allowlist must be an array of valid env var names'));
254
+ });
255
+
191
256
  test('isContextModeEnabled: defaults to true; only explicit false disables', () => {
192
257
  assert.equal(isContextModeEnabled(undefined), true, 'undefined prefs → on');
193
258
  assert.equal(isContextModeEnabled(null), true, 'null prefs → on');
@@ -0,0 +1,52 @@
1
+ ## TL;DR
2
+
3
+ **What:** Ship milestone M001 - Authentication
4
+ **Why:** Users need to authenticate before accessing protected resources.
5
+ **How:** Added password hash check and session token issuance.
6
+
7
+ ## What
8
+
9
+ ### S01
10
+ Implemented login flow.
11
+
12
+ ## Why
13
+
14
+ Users need to authenticate before accessing protected resources.
15
+
16
+ ## How
17
+
18
+ Added password hash check and session token issuance.
19
+
20
+ ## Linked Issue
21
+
22
+ Closes #123
23
+
24
+ ## Roadmap
25
+
26
+ - [x] **S01: Login**
27
+
28
+ ## Metrics
29
+
30
+ - **Units executed:** 3
31
+
32
+ ## Tests Run
33
+
34
+ - npm test
35
+ - npm run typecheck:extensions
36
+
37
+ ## Change Type
38
+
39
+ - [x] `feat` - New feature or capability
40
+ - [ ] `fix` - Bug fix
41
+ - [ ] `refactor` - Code restructuring
42
+ - [ ] `test` - Adding or updating tests
43
+ - [ ] `docs` - Documentation only
44
+ - [ ] `chore` - Build, CI, or tooling changes
45
+
46
+ ## Rollback And Compatibility
47
+
48
+ - Revert the merge commit.
49
+
50
+ ## AI Assistance Disclosure
51
+
52
+ This PR was prepared with AI assistance.
@@ -0,0 +1,42 @@
1
+ ## TL;DR
2
+
3
+ **What:** Ship milestone M001 - Authentication
4
+ **Why:** Milestone work is complete and ready for review.
5
+ **How:** Generated from GSD evidence and local workflow artifacts.
6
+
7
+ ## What
8
+
9
+ Milestone M001 completed.
10
+
11
+ ## Why
12
+
13
+ Milestone work is complete and ready for review.
14
+
15
+ ## How
16
+
17
+ Generated from GSD evidence and local workflow artifacts.
18
+
19
+ ## Linked Issue
20
+
21
+ Not specified. Add an issue link before marking this PR ready if CONTRIBUTING.md requires one.
22
+
23
+ ## Tests Run
24
+
25
+ - Not specified. Add exact verification commands before requesting review.
26
+
27
+ ## Change Type
28
+
29
+ - [x] `feat` - New feature or capability
30
+ - [ ] `fix` - Bug fix
31
+ - [ ] `refactor` - Code restructuring
32
+ - [ ] `test` - Adding or updating tests
33
+ - [ ] `docs` - Documentation only
34
+ - [ ] `chore` - Build, CI, or tooling changes
35
+
36
+ ## Rollback And Compatibility
37
+
38
+ - No behavior-changing rollback notes recorded.
39
+
40
+ ## AI Assistance Disclosure
41
+
42
+ This PR was prepared with AI assistance.
@@ -0,0 +1,55 @@
1
+ ## TL;DR
2
+
3
+ **What:** Ship workflow lane/writer - lane/writer
4
+ **Why:** Workflow work is complete and ready for review.
5
+ **How:** Generated by GSD GitHub Sync swarm routines from lane evidence.
6
+
7
+ ## What
8
+
9
+ ### Swarm lane
10
+ **Lane:** `lane/writer`
11
+ **Branch:** `lane/single-writer`
12
+ **Owner:** @owner
13
+ **Latest commit:** `abc1234`
14
+
15
+ ### Impact area
16
+ Single-writer UOK metadata.
17
+
18
+ ### Changed contracts
19
+ - [ ] WriterToken
20
+
21
+ ### Transition risks
22
+ - [ ] Writer token lifecycle regression
23
+
24
+ ## Why
25
+
26
+ Workflow work is complete and ready for review.
27
+
28
+ ## How
29
+
30
+ Generated by GSD GitHub Sync swarm routines from lane evidence.
31
+
32
+ ## Linked Issue
33
+
34
+ Closes #123
35
+
36
+ ## Tests Run
37
+
38
+ - npm run typecheck:extensions
39
+
40
+ ## Change Type
41
+
42
+ - [ ] `feat` - New feature or capability
43
+ - [ ] `fix` - Bug fix
44
+ - [x] `refactor` - Code restructuring
45
+ - [ ] `test` - Adding or updating tests
46
+ - [ ] `docs` - Documentation only
47
+ - [ ] `chore` - Build, CI, or tooling changes
48
+
49
+ ## Rollback And Compatibility
50
+
51
+ - Disable writer sequence enrichment
52
+
53
+ ## AI Assistance Disclosure
54
+
55
+ This PR was prepared with AI assistance.
@@ -0,0 +1,60 @@
1
+ ## TL;DR
2
+
3
+ **What:** Ship workflow lane/writer - lane/writer
4
+ **Why:** Workflow work is complete and ready for review.
5
+ **How:** Generated by GSD GitHub Sync swarm routines from lane evidence.
6
+
7
+ ## What
8
+
9
+ ### Swarm lane
10
+ **Lane:** `lane/writer`
11
+ **Branch:** `lane/single-writer`
12
+ **Owner:** @owner
13
+ **Latest commit:** `abc1234`
14
+
15
+ ### Impact area
16
+ Single-writer UOK metadata.
17
+
18
+ ### Changed contracts
19
+ - [ ] WriterToken
20
+
21
+ ### Transition risks
22
+ - [ ] Writer token lifecycle regression
23
+
24
+ ## Blockers
25
+
26
+ - Awaiting state-lane writer-sequence merge
27
+ - Parity report incomplete
28
+
29
+ ## Why
30
+
31
+ Workflow work is complete and ready for review.
32
+
33
+ ## How
34
+
35
+ Generated by GSD GitHub Sync swarm routines from lane evidence.
36
+
37
+ ## Linked Issue
38
+
39
+ Closes #123
40
+
41
+ ## Tests Run
42
+
43
+ - npm run typecheck:extensions
44
+
45
+ ## Change Type
46
+
47
+ - [ ] `feat` - New feature or capability
48
+ - [ ] `fix` - Bug fix
49
+ - [x] `refactor` - Code restructuring
50
+ - [ ] `test` - Adding or updating tests
51
+ - [ ] `docs` - Documentation only
52
+ - [ ] `chore` - Build, CI, or tooling changes
53
+
54
+ ## Rollback And Compatibility
55
+
56
+ - Disable writer sequence enrichment
57
+
58
+ ## AI Assistance Disclosure
59
+
60
+ This PR was prepared with AI assistance.
@@ -233,6 +233,16 @@ describe("getNextPendingStep", () => {
233
233
  const next = getNextPendingStep(graph);
234
234
  assert.equal(next?.id, "b");
235
235
  });
236
+
237
+ it("treats expanded dependencies as satisfied", (t) => {
238
+ const graph = makeGraph([
239
+ makeStep({ id: "iter", status: "expanded" }),
240
+ makeStep({ id: "after", dependsOn: ["iter"] }),
241
+ ]);
242
+
243
+ const next = getNextPendingStep(graph);
244
+ assert.equal(next?.id, "after");
245
+ });
236
246
  });
237
247
 
238
248
  // ─── markStepComplete ────────────────────────────────────────────────────