gsd-pi 2.82.0-dev.c22380fc3 → 2.82.0-dev.dfbc5f58f

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 (287) hide show
  1. package/README.md +4 -3
  2. package/dist/resources/.managed-resources-content-hash +1 -1
  3. package/dist/resources/GSD-WORKFLOW.md +10 -1
  4. package/dist/resources/extensions/claude-code-cli/partial-builder.js +2 -1
  5. package/dist/resources/extensions/cmux/index.js +5 -0
  6. package/dist/resources/extensions/gsd/auto/infra-errors.js +9 -3
  7. package/dist/resources/extensions/gsd/auto/loop.js +5 -5
  8. package/dist/resources/extensions/gsd/auto/orchestrator.js +11 -0
  9. package/dist/resources/extensions/gsd/auto/phases.js +8 -1
  10. package/dist/resources/extensions/gsd/auto/workflow-memory-pressure.js +12 -0
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +13 -6
  12. package/dist/resources/extensions/gsd/auto-model-selection.js +2 -0
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +233 -127
  14. package/dist/resources/extensions/gsd/auto-prompts.js +2 -2
  15. package/dist/resources/extensions/gsd/auto-recovery.js +31 -1
  16. package/dist/resources/extensions/gsd/auto-start.js +85 -12
  17. package/dist/resources/extensions/gsd/auto-verification.js +28 -22
  18. package/dist/resources/extensions/gsd/auto-worktree.js +111 -1
  19. package/dist/resources/extensions/gsd/auto.js +30 -3
  20. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +4 -1
  21. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +9 -8
  22. package/dist/resources/extensions/gsd/bootstrap/subagent-input.js +21 -9
  23. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +16 -2
  24. package/dist/resources/extensions/gsd/clean-root-preflight.js +170 -8
  25. package/dist/resources/extensions/gsd/commands/catalog.js +4 -1
  26. package/dist/resources/extensions/gsd/commands/handlers/core.js +37 -0
  27. package/dist/resources/extensions/gsd/commands-bootstrap.js +5 -0
  28. package/dist/resources/extensions/gsd/crash-recovery.js +31 -5
  29. package/dist/resources/extensions/gsd/db/unit-dispatches.js +3 -2
  30. package/dist/resources/extensions/gsd/dispatch-guard.js +2 -2
  31. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +28 -11
  32. package/dist/resources/extensions/gsd/doctor.js +2 -28
  33. package/dist/resources/extensions/gsd/export-html.js +27 -425
  34. package/dist/resources/extensions/gsd/git-service.js +39 -1
  35. package/dist/resources/extensions/gsd/gsd-db.js +1 -0
  36. package/dist/resources/extensions/gsd/guided-flow.js +6 -0
  37. package/dist/resources/extensions/gsd/migrate/parsers.js +10 -0
  38. package/dist/resources/extensions/gsd/milestone-actions.js +11 -4
  39. package/dist/resources/extensions/gsd/native-git-bridge.js +48 -12
  40. package/dist/resources/extensions/gsd/post-execution-checks.js +73 -2
  41. package/dist/resources/extensions/gsd/pre-execution-checks.js +28 -1
  42. package/dist/resources/extensions/gsd/prompt-loader.js +1 -1
  43. package/dist/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  44. package/dist/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  45. package/dist/resources/extensions/gsd/state-reconciliation/drift/merge-state.js +6 -1
  46. package/dist/resources/extensions/gsd/status-guards.js +4 -0
  47. package/dist/resources/extensions/gsd/templates/plan.md +8 -5
  48. package/dist/resources/extensions/gsd/templates/task-plan.md +4 -2
  49. package/dist/resources/extensions/gsd/tools/complete-milestone.js +6 -8
  50. package/dist/resources/extensions/gsd/tools/complete-slice.js +6 -8
  51. package/dist/resources/extensions/gsd/tools/plan-milestone.js +7 -1
  52. package/dist/resources/extensions/gsd/tools/plan-slice.js +89 -14
  53. package/dist/resources/extensions/gsd/unit-context-manifest.js +32 -10
  54. package/dist/resources/extensions/gsd/validation.js +23 -1
  55. package/dist/resources/extensions/gsd/verification-gate.js +68 -7
  56. package/dist/resources/extensions/gsd/verification-verdict.js +26 -0
  57. package/dist/resources/extensions/gsd/workflow-projections.js +6 -8
  58. package/dist/resources/extensions/gsd/worktree-lifecycle.js +33 -8
  59. package/dist/resources/extensions/shared/html-shell.js +388 -0
  60. package/dist/resources/extensions/subagent/index.js +448 -78
  61. package/dist/resources/extensions/subagent/launch.js +77 -0
  62. package/dist/resources/extensions/subagent/run-store.js +148 -0
  63. package/dist/resources/extensions/visual-brief/artifact-policy.js +29 -0
  64. package/dist/resources/extensions/visual-brief/extension-manifest.json +8 -0
  65. package/dist/resources/extensions/visual-brief/index.js +5 -0
  66. package/dist/resources/extensions/visual-brief/page-contract.js +124 -0
  67. package/dist/resources/extensions/visual-brief/prompts.js +140 -0
  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 +12 -12
  71. package/dist/web/standalone/.next/build-manifest.json +3 -3
  72. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  73. package/dist/web/standalone/.next/react-loadable-manifest.json +3 -3
  74. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  75. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  76. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  78. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  84. package/dist/web/standalone/.next/server/app/_not-found/page.js.nft.json +1 -1
  85. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  87. package/dist/web/standalone/.next/server/app/_not-found.rsc +4 -7
  88. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +4 -7
  89. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  90. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +4 -5
  91. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  92. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  93. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -5
  94. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  95. package/dist/web/standalone/.next/server/app/index.html +1 -1
  96. package/dist/web/standalone/.next/server/app/index.rsc +4 -7
  97. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  98. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -7
  99. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  100. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +4 -5
  101. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +2 -5
  102. package/dist/web/standalone/.next/server/app/page.js +2 -2
  103. package/dist/web/standalone/.next/server/app/page.js.nft.json +1 -1
  104. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  105. package/dist/web/standalone/.next/server/app-paths-manifest.json +12 -12
  106. package/dist/web/standalone/.next/server/chunks/4266.js +2 -0
  107. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  108. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  109. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  110. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  111. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  112. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  113. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  114. package/dist/web/standalone/.next/static/chunks/2973.33f26573894b6153.js +2 -0
  115. package/dist/web/standalone/.next/static/chunks/{8359.e059d86b255fce1c.js → 8359.7eb3bb8f8ecf4c01.js} +2 -2
  116. package/dist/web/standalone/.next/static/chunks/app/layout-8c10ec293ae0f1d5.js +1 -0
  117. package/dist/web/standalone/.next/static/chunks/{webpack-de742b64187e13fe.js → webpack-9a4db269f9ed63ad.js} +1 -1
  118. package/dist/web/standalone/.next/static/css/746ee28c929d1880.css +1 -0
  119. package/package.json +4 -4
  120. package/packages/mcp-server/src/workflow-tools.test.ts +1 -1
  121. package/packages/native/tsconfig.json +2 -1
  122. package/packages/native/tsconfig.tsbuildinfo +1 -1
  123. package/packages/pi-ai/dist/providers/openai-codex-responses.d.ts.map +1 -1
  124. package/packages/pi-ai/dist/providers/openai-codex-responses.js +82 -1
  125. package/packages/pi-ai/dist/providers/openai-codex-responses.js.map +1 -1
  126. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts +2 -0
  127. package/packages/pi-ai/dist/providers/openai-codex-responses.test.d.ts.map +1 -0
  128. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js +52 -0
  129. package/packages/pi-ai/dist/providers/openai-codex-responses.test.js.map +1 -0
  130. package/packages/pi-ai/dist/providers/simple-options.d.ts +2 -4
  131. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  132. package/packages/pi-ai/dist/providers/simple-options.js +5 -6
  133. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  134. package/packages/pi-ai/dist/providers/simple-options.test.d.ts +2 -0
  135. package/packages/pi-ai/dist/providers/simple-options.test.d.ts.map +1 -0
  136. package/packages/pi-ai/dist/providers/simple-options.test.js +50 -0
  137. package/packages/pi-ai/dist/providers/simple-options.test.js.map +1 -0
  138. package/packages/pi-ai/src/providers/openai-codex-responses.test.ts +63 -0
  139. package/packages/pi-ai/src/providers/openai-codex-responses.ts +91 -1
  140. package/packages/pi-ai/src/providers/simple-options.test.ts +60 -0
  141. package/packages/pi-ai/src/providers/simple-options.ts +5 -6
  142. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  143. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts +2 -0
  144. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.d.ts.map +1 -0
  145. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js +66 -0
  146. package/packages/pi-coding-agent/dist/core/agent-session-thinking-level.test.js.map +1 -0
  147. package/packages/pi-coding-agent/dist/core/agent-session.js +1 -1
  148. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  149. package/packages/pi-coding-agent/src/core/agent-session-thinking-level.test.ts +79 -0
  150. package/packages/pi-coding-agent/src/core/agent-session.ts +1 -1
  151. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  152. package/src/resources/GSD-WORKFLOW.md +10 -1
  153. package/src/resources/extensions/claude-code-cli/partial-builder.ts +2 -1
  154. package/src/resources/extensions/claude-code-cli/tests/partial-builder.test.ts +19 -2
  155. package/src/resources/extensions/cmux/index.ts +6 -0
  156. package/src/resources/extensions/gsd/auto/contracts.ts +14 -6
  157. package/src/resources/extensions/gsd/auto/infra-errors.ts +9 -3
  158. package/src/resources/extensions/gsd/auto/loop.ts +8 -5
  159. package/src/resources/extensions/gsd/auto/orchestrator.ts +11 -0
  160. package/src/resources/extensions/gsd/auto/phases.ts +7 -1
  161. package/src/resources/extensions/gsd/auto/workflow-memory-pressure.ts +13 -0
  162. package/src/resources/extensions/gsd/auto-dispatch.ts +14 -6
  163. package/src/resources/extensions/gsd/auto-model-selection.ts +2 -1
  164. package/src/resources/extensions/gsd/auto-post-unit.ts +266 -139
  165. package/src/resources/extensions/gsd/auto-prompts.ts +2 -2
  166. package/src/resources/extensions/gsd/auto-recovery.ts +29 -0
  167. package/src/resources/extensions/gsd/auto-start.ts +92 -9
  168. package/src/resources/extensions/gsd/auto-verification.ts +36 -34
  169. package/src/resources/extensions/gsd/auto-worktree.ts +119 -1
  170. package/src/resources/extensions/gsd/auto.ts +32 -3
  171. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +6 -1
  172. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +9 -8
  173. package/src/resources/extensions/gsd/bootstrap/subagent-input.ts +19 -7
  174. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +19 -3
  175. package/src/resources/extensions/gsd/clean-root-preflight.ts +174 -8
  176. package/src/resources/extensions/gsd/commands/catalog.ts +4 -1
  177. package/src/resources/extensions/gsd/commands/handlers/core.ts +40 -0
  178. package/src/resources/extensions/gsd/commands-bootstrap.ts +10 -0
  179. package/src/resources/extensions/gsd/crash-recovery.ts +30 -4
  180. package/src/resources/extensions/gsd/db/unit-dispatches.ts +4 -3
  181. package/src/resources/extensions/gsd/dispatch-guard.ts +2 -2
  182. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +25 -13
  183. package/src/resources/extensions/gsd/doctor.ts +2 -27
  184. package/src/resources/extensions/gsd/export-html.ts +27 -427
  185. package/src/resources/extensions/gsd/git-service.ts +45 -1
  186. package/src/resources/extensions/gsd/gsd-db.ts +3 -0
  187. package/src/resources/extensions/gsd/guided-flow.ts +6 -0
  188. package/src/resources/extensions/gsd/migrate/parsers.ts +11 -0
  189. package/src/resources/extensions/gsd/milestone-actions.ts +10 -4
  190. package/src/resources/extensions/gsd/native-git-bridge.ts +54 -12
  191. package/src/resources/extensions/gsd/post-execution-checks.ts +87 -2
  192. package/src/resources/extensions/gsd/pre-execution-checks.ts +32 -1
  193. package/src/resources/extensions/gsd/prompt-loader.ts +1 -1
  194. package/src/resources/extensions/gsd/prompts/plan-slice.md +3 -3
  195. package/src/resources/extensions/gsd/prompts/refine-slice.md +1 -1
  196. package/src/resources/extensions/gsd/state-reconciliation/drift/merge-state.ts +8 -1
  197. package/src/resources/extensions/gsd/status-guards.ts +5 -0
  198. package/src/resources/extensions/gsd/templates/plan.md +8 -5
  199. package/src/resources/extensions/gsd/templates/task-plan.md +4 -2
  200. package/src/resources/extensions/gsd/tests/auto-deterministic-error-classification-4973.test.ts +116 -0
  201. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +54 -0
  202. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +80 -1
  203. package/src/resources/extensions/gsd/tests/auto-paused-ui-cleanup.test.ts +6 -6
  204. package/src/resources/extensions/gsd/tests/auto-post-unit-step-message.test.ts +12 -1
  205. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +15 -1
  206. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +1 -0
  207. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +69 -1
  208. package/src/resources/extensions/gsd/tests/brief-command.test.ts +89 -0
  209. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +107 -2
  210. package/src/resources/extensions/gsd/tests/closeout-git-deferral.test.ts +16 -0
  211. package/src/resources/extensions/gsd/tests/complete-milestone.test.ts +4 -1
  212. package/src/resources/extensions/gsd/tests/complete-task.test.ts +3 -1
  213. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +43 -2
  214. package/src/resources/extensions/gsd/tests/deep-project-auto-loop.test.ts +59 -2
  215. package/src/resources/extensions/gsd/tests/dispatch-complete-milestone-guard.test.ts +39 -0
  216. package/src/resources/extensions/gsd/tests/dispatch-guard.test.ts +27 -0
  217. package/src/resources/extensions/gsd/tests/evidence-cross-ref.test.ts +38 -0
  218. package/src/resources/extensions/gsd/tests/export-html-enhancements.test.ts +8 -0
  219. package/src/resources/extensions/gsd/tests/guided-flow.test.ts +21 -0
  220. package/src/resources/extensions/gsd/tests/hook-model-resolution.test.ts +5 -0
  221. package/src/resources/extensions/gsd/tests/infra-error.test.ts +2 -2
  222. package/src/resources/extensions/gsd/tests/infra-errors-cooldown.test.ts +9 -0
  223. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +20 -0
  224. package/src/resources/extensions/gsd/tests/integration/git-service.test.ts +103 -1
  225. package/src/resources/extensions/gsd/tests/integration/state-machine-runtime-failures.test.ts +6 -1
  226. package/src/resources/extensions/gsd/tests/migrate-validator-parsers.test.ts +24 -1
  227. package/src/resources/extensions/gsd/tests/native-git-bridge-exec-fallback.test.ts +63 -2
  228. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +121 -1
  229. package/src/resources/extensions/gsd/tests/park-db-sync.test.ts +55 -1
  230. package/src/resources/extensions/gsd/tests/plan-milestone.test.ts +26 -0
  231. package/src/resources/extensions/gsd/tests/plan-slice.test.ts +225 -1
  232. package/src/resources/extensions/gsd/tests/plan-task.test.ts +17 -0
  233. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +79 -1
  234. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +86 -0
  235. package/src/resources/extensions/gsd/tests/post-unit-git-failure.test.ts +1 -1
  236. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +53 -0
  237. package/src/resources/extensions/gsd/tests/prompt-loader.test.ts +23 -0
  238. package/src/resources/extensions/gsd/tests/remediation-completion-guard.test.ts +46 -2
  239. package/src/resources/extensions/gsd/tests/session-switch-abort-misclassification.test.ts +10 -0
  240. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +31 -1
  241. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +64 -1
  242. package/src/resources/extensions/gsd/tests/summary-render-parity.test.ts +7 -3
  243. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +86 -7
  244. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +110 -1
  245. package/src/resources/extensions/gsd/tests/verification-verdict.test.ts +78 -0
  246. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +1 -1
  247. package/src/resources/extensions/gsd/tests/workflow-memory-pressure.test.ts +21 -1
  248. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +1 -1
  249. package/src/resources/extensions/gsd/tests/worktree-git-pathspec.test.ts +39 -0
  250. package/src/resources/extensions/gsd/tests/worktree-journal-events.test.ts +64 -12
  251. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +54 -0
  252. package/src/resources/extensions/gsd/tools/complete-milestone.ts +8 -10
  253. package/src/resources/extensions/gsd/tools/complete-slice.ts +6 -8
  254. package/src/resources/extensions/gsd/tools/plan-milestone.ts +5 -1
  255. package/src/resources/extensions/gsd/tools/plan-slice.ts +98 -12
  256. package/src/resources/extensions/gsd/types.ts +1 -1
  257. package/src/resources/extensions/gsd/unit-context-manifest.ts +47 -11
  258. package/src/resources/extensions/gsd/validation.ts +23 -1
  259. package/src/resources/extensions/gsd/verification-gate.ts +78 -6
  260. package/src/resources/extensions/gsd/verification-verdict.ts +47 -0
  261. package/src/resources/extensions/gsd/workflow-projections.ts +6 -8
  262. package/src/resources/extensions/gsd/worktree-lifecycle.ts +41 -8
  263. package/src/resources/extensions/shared/html-shell.ts +412 -0
  264. package/src/resources/extensions/subagent/index.ts +567 -103
  265. package/src/resources/extensions/subagent/launch.ts +131 -0
  266. package/src/resources/extensions/subagent/run-store.ts +218 -0
  267. package/src/resources/extensions/subagent/tests/launch.test.ts +115 -0
  268. package/src/resources/extensions/subagent/tests/run-store.test.ts +111 -0
  269. package/src/resources/extensions/visual-brief/artifact-policy.ts +41 -0
  270. package/src/resources/extensions/visual-brief/extension-manifest.json +8 -0
  271. package/src/resources/extensions/visual-brief/index.ts +8 -0
  272. package/src/resources/extensions/visual-brief/page-contract.ts +136 -0
  273. package/src/resources/extensions/visual-brief/prompts.ts +183 -0
  274. package/src/resources/extensions/visual-brief/tests/visual-brief.test.ts +212 -0
  275. package/dist/web/standalone/.next/server/chunks/5822.js +0 -2
  276. package/dist/web/standalone/.next/static/chunks/2556.0527fea66e123b7f.js +0 -1
  277. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +0 -1
  278. package/dist/web/standalone/.next/static/css/54ec2745c1da488b.css +0 -1
  279. package/dist/web/standalone/.next/static/css/de70bee13400563f.css +0 -1
  280. package/dist/web/standalone/.next/static/media/4cf2300e9c8272f7-s.p.woff2 +0 -0
  281. package/dist/web/standalone/.next/static/media/747892c23ea88013-s.woff2 +0 -0
  282. package/dist/web/standalone/.next/static/media/8d697b304b401681-s.woff2 +0 -0
  283. package/dist/web/standalone/.next/static/media/93f479601ee12b01-s.p.woff2 +0 -0
  284. package/dist/web/standalone/.next/static/media/9610d9e46709d722-s.woff2 +0 -0
  285. package/dist/web/standalone/.next/static/media/ba015fad6dcf6784-s.woff2 +0 -0
  286. /package/dist/web/standalone/.next/static/{Wop3A7KRGyR06H3rla_1- → q0WYuDVbHeFFYbdd-fei2}/_buildManifest.js +0 -0
  287. /package/dist/web/standalone/.next/static/{Wop3A7KRGyR06H3rla_1- → q0WYuDVbHeFFYbdd-fei2}/_ssgManifest.js +0 -0
@@ -0,0 +1,131 @@
1
+ // GSD-2 + Subagent launch contract and child process safety helpers.
2
+
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ import { SessionManager } from "@gsd/pi-coding-agent";
6
+ import type { AgentConfig } from "./agents.js";
7
+
8
+ export const SUBAGENT_CHILD_ENV_VAR = "GSD_SUBAGENT_CHILD";
9
+ export const SUBAGENT_CHILD_ENV_VALUE = "1";
10
+
11
+ export type SubagentContextMode = "fresh" | "fork";
12
+
13
+ export type SubagentSessionArgs =
14
+ | { mode: "fresh" }
15
+ | { mode: "fork"; sessionFile: string; sessionDir?: string };
16
+
17
+ export interface SubagentParentSessionManager {
18
+ getSessionFile(): string | undefined;
19
+ getLeafId(): string | null;
20
+ getSessionDir(): string;
21
+ }
22
+
23
+ export interface SubagentLaunchInput {
24
+ agent: AgentConfig;
25
+ task: string;
26
+ tmpPromptPath: string | null;
27
+ modelOverride?: string;
28
+ contextMode?: SubagentContextMode;
29
+ parentSessionManager?: SubagentParentSessionManager;
30
+ session?: SubagentSessionArgs;
31
+ cwd?: string;
32
+ defaultCwd: string;
33
+ }
34
+
35
+ export interface SubagentLaunchPlan {
36
+ args: string[];
37
+ env: NodeJS.ProcessEnv;
38
+ cwd: string;
39
+ session: SubagentSessionArgs;
40
+ }
41
+
42
+ export function isSubagentChildProcess(env: NodeJS.ProcessEnv = process.env): boolean {
43
+ return env[SUBAGENT_CHILD_ENV_VAR] === SUBAGENT_CHILD_ENV_VALUE;
44
+ }
45
+
46
+ export function buildSubagentProcessEnv(env: NodeJS.ProcessEnv = process.env): NodeJS.ProcessEnv {
47
+ return {
48
+ ...env,
49
+ [SUBAGENT_CHILD_ENV_VAR]: SUBAGENT_CHILD_ENV_VALUE,
50
+ };
51
+ }
52
+
53
+ export function buildShellEnvAssignments(env: NodeJS.ProcessEnv = process.env): string[] {
54
+ const value = env[SUBAGENT_CHILD_ENV_VAR];
55
+ return value ? [`${SUBAGENT_CHILD_ENV_VAR}=${JSON.stringify(value)}`] : [];
56
+ }
57
+
58
+ export function buildSubagentProcessArgs(
59
+ agent: AgentConfig,
60
+ task: string,
61
+ tmpPromptPath: string | null,
62
+ modelOverride?: string,
63
+ session: SubagentSessionArgs = { mode: "fresh" },
64
+ ): string[] {
65
+ const args: string[] = ["--mode", "json", "-p"];
66
+ if (session.mode === "fork") {
67
+ args.push("--session", session.sessionFile);
68
+ if (session.sessionDir) args.push("--session-dir", session.sessionDir);
69
+ } else {
70
+ args.push("--no-session");
71
+ }
72
+ const effectiveModel = modelOverride ?? agent.model;
73
+ if (effectiveModel) args.push("--model", effectiveModel);
74
+ if (agent.tools && agent.tools.length > 0) args.push("--tools", agent.tools.join(","));
75
+ if (tmpPromptPath) args.push("--append-system-prompt", tmpPromptPath);
76
+ args.push(`Task: ${task}`);
77
+ return args;
78
+ }
79
+
80
+ export function resolveSubagentSessionArgs(
81
+ contextMode: SubagentContextMode = "fresh",
82
+ parentSessionManager?: SubagentParentSessionManager,
83
+ ): SubagentSessionArgs {
84
+ if (contextMode === "fresh") return { mode: "fresh" };
85
+
86
+ if (!parentSessionManager) {
87
+ throw new Error("Forked subagent context requires a parent session manager.");
88
+ }
89
+
90
+ const parentSessionFile = parentSessionManager.getSessionFile();
91
+ if (!parentSessionFile) {
92
+ throw new Error("Forked subagent context requires a persisted parent session file; current session is in-memory.");
93
+ }
94
+ if (!fs.existsSync(parentSessionFile)) {
95
+ throw new Error(`Forked subagent context could not read parent session file: ${parentSessionFile}`);
96
+ }
97
+
98
+ const leafId = parentSessionManager.getLeafId();
99
+ if (!leafId) {
100
+ throw new Error("Forked subagent context requires a parent session leaf to branch from.");
101
+ }
102
+
103
+ const sessionDir = parentSessionManager.getSessionDir?.();
104
+ const parentSession = SessionManager.open(parentSessionFile, sessionDir);
105
+ const childSessionFile = parentSession.createBranchedSession(leafId);
106
+ if (!childSessionFile) {
107
+ throw new Error("Forked subagent context could not create a branched child session.");
108
+ }
109
+
110
+ return {
111
+ mode: "fork",
112
+ sessionFile: childSessionFile,
113
+ ...(sessionDir ? { sessionDir: path.resolve(sessionDir) } : {}),
114
+ };
115
+ }
116
+
117
+ export function createSubagentLaunchPlan(input: SubagentLaunchInput): SubagentLaunchPlan {
118
+ const session = input.session ?? resolveSubagentSessionArgs(input.contextMode ?? "fresh", input.parentSessionManager);
119
+ return {
120
+ args: buildSubagentProcessArgs(
121
+ input.agent,
122
+ input.task,
123
+ input.tmpPromptPath,
124
+ input.modelOverride,
125
+ session,
126
+ ),
127
+ env: buildSubagentProcessEnv(),
128
+ cwd: input.cwd ?? input.defaultCwd,
129
+ session,
130
+ };
131
+ }
@@ -0,0 +1,218 @@
1
+ // GSD-2 + Durable subagent run status, tracking names, and result artifact store.
2
+
3
+ import * as fs from "node:fs";
4
+ import * as path from "node:path";
5
+ import { randomInt } from "node:crypto";
6
+ import { getAgentDir } from "@gsd/pi-coding-agent";
7
+
8
+ export type SubagentRunMode = "single" | "parallel" | "chain";
9
+ export type SubagentRunStatus = "queued" | "running" | "succeeded" | "failed" | "interrupted";
10
+
11
+ export interface SubagentChildArtifact {
12
+ index: number;
13
+ agent: string;
14
+ trackingName?: string;
15
+ task: string;
16
+ status: SubagentRunStatus;
17
+ exitCode?: number;
18
+ cwd?: string;
19
+ sessionFile?: string;
20
+ startedAt?: string;
21
+ completedAt?: string;
22
+ output?: string;
23
+ stderr?: string;
24
+ errorMessage?: string;
25
+ stopReason?: string;
26
+ model?: string;
27
+ usage?: {
28
+ input: number;
29
+ output: number;
30
+ cacheRead: number;
31
+ cacheWrite: number;
32
+ cost: number;
33
+ contextTokens: number;
34
+ turns: number;
35
+ };
36
+ merge?: {
37
+ success: boolean;
38
+ appliedPatches: string[];
39
+ failedPatches: string[];
40
+ error?: string;
41
+ };
42
+ }
43
+
44
+ export interface SubagentRunRecord {
45
+ schemaVersion: 1;
46
+ runId: string;
47
+ mode: SubagentRunMode;
48
+ contextMode: "fresh" | "fork";
49
+ status: SubagentRunStatus;
50
+ cwd: string;
51
+ startedAt: string;
52
+ updatedAt: string;
53
+ completedAt?: string;
54
+ children: SubagentChildArtifact[];
55
+ failure?: {
56
+ type: "child-failed" | "merge-failed" | "interrupted" | "launch-failed";
57
+ message: string;
58
+ };
59
+ }
60
+
61
+ export function defaultSubagentRunStoreDir(): string {
62
+ return path.join(getAgentDir(), "subagent-runs");
63
+ }
64
+
65
+ const TRACKING_ADJECTIVES = [
66
+ "amber",
67
+ "bright",
68
+ "calm",
69
+ "clear",
70
+ "crisp",
71
+ "daring",
72
+ "keen",
73
+ "lucky",
74
+ "quiet",
75
+ "steady",
76
+ "swift",
77
+ "vivid",
78
+ ] as const;
79
+
80
+ const TRACKING_NOUNS = [
81
+ "anchor",
82
+ "atlas",
83
+ "beacon",
84
+ "canvas",
85
+ "compass",
86
+ "forge",
87
+ "harbor",
88
+ "lantern",
89
+ "ledger",
90
+ "mesa",
91
+ "quartz",
92
+ "ridge",
93
+ "signal",
94
+ "summit",
95
+ "vector",
96
+ "vista",
97
+ ] as const;
98
+
99
+ export function createSubagentTrackingName(existingNames: ReadonlySet<string> = new Set()): string {
100
+ const maxCombinations = TRACKING_ADJECTIVES.length * TRACKING_NOUNS.length;
101
+ for (let attempt = 0; attempt < maxCombinations * 2; attempt++) {
102
+ const adjective = TRACKING_ADJECTIVES[randomInt(TRACKING_ADJECTIVES.length)];
103
+ const noun = TRACKING_NOUNS[randomInt(TRACKING_NOUNS.length)];
104
+ const name = `${adjective}-${noun}`;
105
+ if (!existingNames.has(name)) return name;
106
+ }
107
+
108
+ let suffix = existingNames.size + 1;
109
+ while (existingNames.has(`agent-${suffix}`)) suffix++;
110
+ return `agent-${suffix}`;
111
+ }
112
+
113
+ export class SubagentRunStore {
114
+ private readonly baseDir: string;
115
+
116
+ constructor(baseDir: string = defaultSubagentRunStoreDir()) {
117
+ this.baseDir = baseDir;
118
+ }
119
+
120
+ getBaseDir(): string {
121
+ return this.baseDir;
122
+ }
123
+
124
+ create(record: SubagentRunRecord): SubagentRunRecord {
125
+ this.write(record);
126
+ return record;
127
+ }
128
+
129
+ get(runId: string): SubagentRunRecord | null {
130
+ const filePath = this.pathFor(runId);
131
+ if (!fs.existsSync(filePath)) return null;
132
+ try {
133
+ const parsed = JSON.parse(fs.readFileSync(filePath, "utf-8")) as Partial<SubagentRunRecord>;
134
+ if (
135
+ !parsed ||
136
+ typeof parsed !== "object" ||
137
+ typeof parsed.runId !== "string" ||
138
+ typeof parsed.updatedAt !== "string" ||
139
+ !Array.isArray(parsed.children)
140
+ ) {
141
+ return null;
142
+ }
143
+ return parsed as SubagentRunRecord;
144
+ } catch {
145
+ return null;
146
+ }
147
+ }
148
+
149
+ update(runId: string, updater: (record: SubagentRunRecord) => SubagentRunRecord): SubagentRunRecord {
150
+ const current = this.get(runId);
151
+ if (!current) throw new Error(`Subagent run not found: ${runId}`);
152
+ const next = updater({
153
+ ...current,
154
+ children: current.children.map((child) => ({ ...child })),
155
+ });
156
+ next.updatedAt = new Date().toISOString();
157
+ this.write(next);
158
+ return next;
159
+ }
160
+
161
+ list(): SubagentRunRecord[] {
162
+ if (!fs.existsSync(this.baseDir)) return [];
163
+ return fs.readdirSync(this.baseDir)
164
+ .filter((name) => name.endsWith(".json"))
165
+ .map((name) => this.get(path.basename(name, ".json")))
166
+ .filter((record): record is SubagentRunRecord => record !== null)
167
+ .sort((a, b) => b.updatedAt.localeCompare(a.updatedAt));
168
+ }
169
+
170
+ private pathFor(runId: string): string {
171
+ const safeRunId = runId.replace(/[^a-zA-Z0-9._-]/g, "_");
172
+ return path.join(this.baseDir, `${safeRunId}.json`);
173
+ }
174
+
175
+ private write(record: SubagentRunRecord): void {
176
+ fs.mkdirSync(this.baseDir, { recursive: true });
177
+ const filePath = this.pathFor(record.runId);
178
+ const tmpPath = `${filePath}.${process.pid}.${Date.now()}.tmp`;
179
+ fs.writeFileSync(tmpPath, `${JSON.stringify(record, null, 2)}\n`, "utf-8");
180
+ fs.renameSync(tmpPath, filePath);
181
+ }
182
+ }
183
+
184
+ export function createInitialRunRecord(input: {
185
+ runId: string;
186
+ mode: SubagentRunMode;
187
+ contextMode: "fresh" | "fork";
188
+ cwd: string;
189
+ children: Array<{ agent: string; trackingName?: string; task: string; cwd?: string }>;
190
+ now?: string;
191
+ }): SubagentRunRecord {
192
+ const now = input.now ?? new Date().toISOString();
193
+ return {
194
+ schemaVersion: 1,
195
+ runId: input.runId,
196
+ mode: input.mode,
197
+ contextMode: input.contextMode,
198
+ status: "running",
199
+ cwd: input.cwd,
200
+ startedAt: now,
201
+ updatedAt: now,
202
+ children: input.children.map((child, index) => ({
203
+ index,
204
+ agent: child.agent,
205
+ trackingName: child.trackingName,
206
+ task: child.task,
207
+ cwd: child.cwd,
208
+ status: "queued",
209
+ })),
210
+ };
211
+ }
212
+
213
+ export function deriveRunStatus(children: readonly SubagentChildArtifact[]): SubagentRunStatus {
214
+ if (children.some((child) => child.status === "interrupted")) return "interrupted";
215
+ if (children.some((child) => child.status === "failed")) return "failed";
216
+ if (children.length > 0 && children.every((child) => child.status === "succeeded")) return "succeeded";
217
+ return "running";
218
+ }
@@ -0,0 +1,115 @@
1
+ // GSD-2 + Subagent launch module regression tests.
2
+
3
+ import assert from "node:assert/strict";
4
+ import { mkdtempSync, rmSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { describe, it, afterEach } from "node:test";
8
+
9
+ import { SessionManager } from "@gsd/pi-coding-agent";
10
+ import subagentExtension from "../index.js";
11
+ import type { AgentConfig } from "../agents.js";
12
+ import {
13
+ SUBAGENT_CHILD_ENV_VAR,
14
+ SUBAGENT_CHILD_ENV_VALUE,
15
+ buildSubagentProcessEnv,
16
+ createSubagentLaunchPlan,
17
+ isSubagentChildProcess,
18
+ resolveSubagentSessionArgs,
19
+ } from "../launch.js";
20
+
21
+ function makeAgent(overrides: Partial<AgentConfig> = {}): AgentConfig {
22
+ return {
23
+ name: "test-agent",
24
+ description: "A test agent",
25
+ systemPrompt: "",
26
+ source: "project",
27
+ filePath: "test-agent.md",
28
+ tools: ["read", "write"],
29
+ ...overrides,
30
+ };
31
+ }
32
+
33
+ function makeAssistantMessage() {
34
+ return {
35
+ role: "assistant",
36
+ content: [{ type: "text", text: "ok" }],
37
+ usage: {
38
+ input: 1,
39
+ output: 1,
40
+ cacheRead: 0,
41
+ cacheWrite: 0,
42
+ total: 2,
43
+ cost: { total: 0 },
44
+ },
45
+ } as any;
46
+ }
47
+
48
+ describe("subagent launch module", () => {
49
+ let dir: string | undefined;
50
+
51
+ afterEach(() => {
52
+ if (dir) rmSync(dir, { recursive: true, force: true });
53
+ dir = undefined;
54
+ });
55
+
56
+ it("builds fresh child process args with child environment", () => {
57
+ const agent = makeAgent({ model: "local-model" });
58
+ const plan = createSubagentLaunchPlan({
59
+ agent,
60
+ task: "inspect the API",
61
+ tmpPromptPath: "/tmp/prompt.md",
62
+ defaultCwd: "/repo",
63
+ });
64
+
65
+ assert.ok(plan.args.includes("--no-session"));
66
+ assert.equal(plan.args.includes("--session"), false);
67
+ assert.equal(plan.env[SUBAGENT_CHILD_ENV_VAR], SUBAGENT_CHILD_ENV_VALUE);
68
+ assert.equal(plan.cwd, "/repo");
69
+ assert.deepEqual(plan.session, { mode: "fresh" });
70
+ assert.deepEqual(plan.args.slice(plan.args.indexOf("--tools"), plan.args.indexOf("--tools") + 2), ["--tools", "read,write"]);
71
+ });
72
+
73
+ it("creates a real branched session for forked context", () => {
74
+ dir = mkdtempSync(join(tmpdir(), "gsd-subagent-launch-"));
75
+ const manager = SessionManager.create(dir, dir);
76
+ manager.appendMessage({ role: "user", content: [{ type: "text", text: "hello" }] } as any);
77
+ manager.appendMessage(makeAssistantMessage());
78
+
79
+ const session = resolveSubagentSessionArgs("fork", manager);
80
+
81
+ assert.equal(session.mode, "fork");
82
+ assert.ok(session.sessionFile);
83
+ assert.notEqual(session.sessionFile, manager.getSessionFile());
84
+ assert.equal(session.sessionDir, dir);
85
+ });
86
+
87
+ it("fails forked context loudly without a persisted parent session", () => {
88
+ const manager = SessionManager.inMemory("/repo");
89
+ assert.throws(
90
+ () => resolveSubagentSessionArgs("fork", manager),
91
+ /persisted parent session file/,
92
+ );
93
+ });
94
+
95
+ it("marks child env and suppresses recursive tool registration", () => {
96
+ const env = buildSubagentProcessEnv({});
97
+ assert.equal(isSubagentChildProcess(env), true);
98
+
99
+ const previous = process.env[SUBAGENT_CHILD_ENV_VAR];
100
+ process.env[SUBAGENT_CHILD_ENV_VAR] = SUBAGENT_CHILD_ENV_VALUE;
101
+ const calls: string[] = [];
102
+ try {
103
+ subagentExtension({
104
+ on: () => calls.push("on"),
105
+ registerCommand: () => calls.push("command"),
106
+ registerTool: () => calls.push("tool"),
107
+ } as any);
108
+ } finally {
109
+ if (previous === undefined) delete process.env[SUBAGENT_CHILD_ENV_VAR];
110
+ else process.env[SUBAGENT_CHILD_ENV_VAR] = previous;
111
+ }
112
+
113
+ assert.deepEqual(calls, []);
114
+ });
115
+ });
@@ -0,0 +1,111 @@
1
+ // GSD-2 + Subagent durable run-store tests.
2
+
3
+ import assert from "node:assert/strict";
4
+ import { mkdtempSync, rmSync } from "node:fs";
5
+ import { tmpdir } from "node:os";
6
+ import { join } from "node:path";
7
+ import { afterEach, describe, it } from "node:test";
8
+
9
+ import {
10
+ SubagentRunStore,
11
+ createInitialRunRecord,
12
+ createSubagentTrackingName,
13
+ deriveRunStatus,
14
+ } from "../run-store.js";
15
+
16
+ describe("SubagentRunStore", () => {
17
+ let dir: string | undefined;
18
+
19
+ afterEach(() => {
20
+ if (dir) rmSync(dir, { recursive: true, force: true });
21
+ dir = undefined;
22
+ });
23
+
24
+ it("persists launch and successful completion evidence", () => {
25
+ dir = mkdtempSync(join(tmpdir(), "gsd-subagent-runs-"));
26
+ const store = new SubagentRunStore(dir);
27
+ store.create(createInitialRunRecord({
28
+ runId: "run-1",
29
+ mode: "single",
30
+ contextMode: "fresh",
31
+ cwd: "/repo",
32
+ children: [{ agent: "scout", trackingName: "clear-beacon", task: "inspect" }],
33
+ now: "2026-01-01T00:00:00.000Z",
34
+ }));
35
+
36
+ store.update("run-1", (record) => ({
37
+ ...record,
38
+ status: "succeeded",
39
+ completedAt: "2026-01-01T00:00:01.000Z",
40
+ children: [{
41
+ ...record.children[0],
42
+ status: "succeeded",
43
+ exitCode: 0,
44
+ output: "done",
45
+ }],
46
+ }));
47
+
48
+ const loaded = store.get("run-1");
49
+ assert.equal(loaded?.status, "succeeded");
50
+ assert.equal(loaded?.children[0]?.trackingName, "clear-beacon");
51
+ assert.equal(loaded?.children[0]?.output, "done");
52
+ assert.equal(store.list()[0]?.runId, "run-1");
53
+ });
54
+
55
+ it("generates unique tracking names for child agents", () => {
56
+ const names = new Set<string>();
57
+ for (let i = 0; i < 24; i++) {
58
+ const name = createSubagentTrackingName(names);
59
+ assert.match(name, /^[a-z]+-[a-z]+$|^agent-\d+$/);
60
+ assert.equal(names.has(name), false);
61
+ names.add(name);
62
+ }
63
+ });
64
+
65
+ it("persists failed and interrupted child evidence", () => {
66
+ dir = mkdtempSync(join(tmpdir(), "gsd-subagent-runs-"));
67
+ const store = new SubagentRunStore(dir);
68
+ store.create(createInitialRunRecord({
69
+ runId: "run-2",
70
+ mode: "parallel",
71
+ contextMode: "fork",
72
+ cwd: "/repo",
73
+ children: [
74
+ { agent: "tester", task: "verify" },
75
+ { agent: "reviewer", task: "review" },
76
+ ],
77
+ }));
78
+
79
+ store.update("run-2", (record) => ({
80
+ ...record,
81
+ status: "interrupted",
82
+ children: [
83
+ {
84
+ ...record.children[0],
85
+ status: "failed",
86
+ exitCode: 1,
87
+ errorMessage: "verification failed",
88
+ },
89
+ {
90
+ ...record.children[1],
91
+ status: "interrupted",
92
+ exitCode: 1,
93
+ stopReason: "aborted",
94
+ },
95
+ ],
96
+ failure: { type: "interrupted", message: "run aborted" },
97
+ }));
98
+
99
+ const loaded = store.get("run-2");
100
+ assert.equal(loaded?.status, "interrupted");
101
+ assert.equal(loaded?.children[0]?.errorMessage, "verification failed");
102
+ assert.equal(loaded?.children[1]?.stopReason, "aborted");
103
+ assert.equal(loaded?.failure?.type, "interrupted");
104
+ });
105
+
106
+ it("derives failed and interrupted status from child artifacts", () => {
107
+ assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "failed" }]), "failed");
108
+ assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "interrupted" }]), "interrupted");
109
+ assert.equal(deriveRunStatus([{ index: 0, agent: "a", task: "t", status: "succeeded" }]), "succeeded");
110
+ });
111
+ });
@@ -0,0 +1,41 @@
1
+ // GSD-2 + Visual Brief artifact policy
2
+
3
+ import { join } from "node:path";
4
+ import { getAgentDir } from "@gsd/pi-coding-agent";
5
+
6
+ export interface VisualBriefArtifactPolicy {
7
+ outputDir: string;
8
+ filenameStyle: string;
9
+ fileShape: string;
10
+ openers: readonly string[];
11
+ failureBehavior: string;
12
+ }
13
+
14
+ export function getVisualBriefOutputDir(agentDir: string = getAgentDir()): string {
15
+ return join(agentDir, "diagrams");
16
+ }
17
+
18
+ export function createVisualBriefArtifactPolicy(outputDir: string): VisualBriefArtifactPolicy {
19
+ return {
20
+ outputDir,
21
+ filenameStyle: "Use a descriptive kebab-case filename ending in .html.",
22
+ fileShape: "Produce one self-contained responsive HTML file with embedded CSS and minimal JavaScript.",
23
+ openers: [
24
+ "macOS: open",
25
+ "Linux: xdg-open",
26
+ "Windows: cmd /c start",
27
+ ],
28
+ failureBehavior: "If opening fails, report the absolute file path.",
29
+ };
30
+ }
31
+
32
+ export function formatArtifactPolicy(policy: VisualBriefArtifactPolicy): string {
33
+ return [
34
+ `- Create the output directory if it does not exist: ${policy.outputDir}`,
35
+ `- ${policy.filenameStyle}`,
36
+ `- ${policy.fileShape}`,
37
+ "- Open the result in a browser when the local platform has an opener available.",
38
+ ...policy.openers.map((opener) => ` - ${opener}`),
39
+ `- ${policy.failureBehavior}`,
40
+ ].join("\n");
41
+ }
@@ -0,0 +1,8 @@
1
+ {
2
+ "id": "visual-brief",
3
+ "name": "Visual Brief",
4
+ "version": "1.0.0",
5
+ "description": "Prompt contracts backing /gsd brief visual HTML briefs",
6
+ "tier": "bundled",
7
+ "requires": { "platform": ">=2.29.0" }
8
+ }
@@ -0,0 +1,8 @@
1
+ // GSD-2 + Visual Brief bundled extension marker
2
+
3
+ import type { ExtensionAPI } from "@gsd/pi-coding-agent";
4
+
5
+ export default function visualBrief(_pi: ExtensionAPI) {
6
+ // Visual Brief is invoked through /gsd brief. This module keeps the bundled
7
+ // extension discoverable without adding a second top-level slash command.
8
+ }