gsd-pi 2.41.0 → 2.42.0-dev.1df898f

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 (494) hide show
  1. package/README.md +92 -29
  2. package/dist/cli-web-branch.d.ts +6 -0
  3. package/dist/cli-web-branch.js +17 -0
  4. package/dist/cli.js +18 -3
  5. package/dist/loader.js +3 -1
  6. package/dist/onboarding.js +2 -1
  7. package/dist/resource-loader.js +39 -6
  8. package/dist/resources/extensions/async-jobs/async-bash-tool.js +52 -4
  9. package/dist/resources/extensions/async-jobs/await-tool.js +5 -0
  10. package/dist/resources/extensions/async-jobs/index.js +2 -0
  11. package/dist/resources/extensions/gsd/auto/loop.js +89 -1
  12. package/dist/resources/extensions/gsd/auto/phases.js +29 -13
  13. package/dist/resources/extensions/gsd/auto/session.js +6 -0
  14. package/dist/resources/extensions/gsd/auto-dashboard.js +8 -2
  15. package/dist/resources/extensions/gsd/auto-dispatch.js +19 -2
  16. package/dist/resources/extensions/gsd/auto-post-unit.js +7 -0
  17. package/dist/resources/extensions/gsd/auto-prompts.js +3 -16
  18. package/dist/resources/extensions/gsd/auto-recovery.js +12 -4
  19. package/dist/resources/extensions/gsd/auto-start.js +16 -14
  20. package/dist/resources/extensions/gsd/auto-worktree.js +147 -13
  21. package/dist/resources/extensions/gsd/auto.js +64 -2
  22. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +199 -164
  23. package/dist/resources/extensions/gsd/bootstrap/journal-tools.js +62 -0
  24. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  25. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +25 -3
  26. package/dist/resources/extensions/gsd/bootstrap/tool-call-loop-guard.js +7 -2
  27. package/dist/resources/extensions/gsd/commands/catalog.js +40 -1
  28. package/dist/resources/extensions/gsd/commands/handlers/core.js +1 -0
  29. package/dist/resources/extensions/gsd/commands/handlers/ops.js +5 -0
  30. package/dist/resources/extensions/gsd/commands/handlers/workflow.js +146 -0
  31. package/dist/resources/extensions/gsd/context-injector.js +74 -0
  32. package/dist/resources/extensions/gsd/context-store.js +4 -3
  33. package/dist/resources/extensions/gsd/custom-execution-policy.js +47 -0
  34. package/dist/resources/extensions/gsd/custom-verification.js +145 -0
  35. package/dist/resources/extensions/gsd/custom-workflow-engine.js +164 -0
  36. package/dist/resources/extensions/gsd/dashboard-overlay.js +1 -0
  37. package/dist/resources/extensions/gsd/db-writer.js +5 -2
  38. package/dist/resources/extensions/gsd/definition-loader.js +352 -0
  39. package/dist/resources/extensions/gsd/detection.js +20 -1
  40. package/dist/resources/extensions/gsd/dev-execution-policy.js +24 -0
  41. package/dist/resources/extensions/gsd/dev-workflow-engine.js +82 -0
  42. package/dist/resources/extensions/gsd/doctor-checks.js +31 -1
  43. package/dist/resources/extensions/gsd/doctor-providers.js +10 -0
  44. package/dist/resources/extensions/gsd/doctor.js +11 -1
  45. package/dist/resources/extensions/gsd/engine-resolver.js +40 -0
  46. package/dist/resources/extensions/gsd/engine-types.js +8 -0
  47. package/dist/resources/extensions/gsd/execution-policy.js +8 -0
  48. package/dist/resources/extensions/gsd/exit-command.js +12 -2
  49. package/dist/resources/extensions/gsd/export.js +9 -13
  50. package/dist/resources/extensions/gsd/extension-manifest.json +2 -2
  51. package/dist/resources/extensions/gsd/files.js +28 -11
  52. package/dist/resources/extensions/gsd/forensics.js +94 -3
  53. package/dist/resources/extensions/gsd/git-constants.js +1 -0
  54. package/dist/resources/extensions/gsd/git-service.js +6 -2
  55. package/dist/resources/extensions/gsd/graph.js +225 -0
  56. package/dist/resources/extensions/gsd/gsd-db.js +25 -8
  57. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  58. package/dist/resources/extensions/gsd/guided-flow.js +7 -3
  59. package/dist/resources/extensions/gsd/journal.js +85 -0
  60. package/dist/resources/extensions/gsd/md-importer.js +5 -0
  61. package/dist/resources/extensions/gsd/milestone-ids.js +1 -1
  62. package/dist/resources/extensions/gsd/native-git-bridge.js +3 -2
  63. package/dist/resources/extensions/gsd/post-unit-hooks.js +24 -412
  64. package/dist/resources/extensions/gsd/preferences-types.js +2 -0
  65. package/dist/resources/extensions/gsd/preferences.js +60 -8
  66. package/dist/resources/extensions/gsd/prompt-loader.js +34 -4
  67. package/dist/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  68. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  69. package/dist/resources/extensions/gsd/prompts/discuss.md +1 -1
  70. package/dist/resources/extensions/gsd/prompts/forensics.md +12 -5
  71. package/dist/resources/extensions/gsd/prompts/queue.md +1 -1
  72. package/dist/resources/extensions/gsd/repo-identity.js +92 -7
  73. package/dist/resources/extensions/gsd/rule-registry.js +489 -0
  74. package/dist/resources/extensions/gsd/rule-types.js +6 -0
  75. package/dist/resources/extensions/gsd/run-manager.js +134 -0
  76. package/dist/resources/extensions/gsd/service-tier.js +147 -0
  77. package/dist/resources/extensions/gsd/session-lock.js +2 -2
  78. package/dist/resources/extensions/gsd/structured-data-formatter.js +2 -1
  79. package/dist/resources/extensions/gsd/templates/decisions.md +2 -2
  80. package/dist/resources/extensions/gsd/workflow-engine.js +7 -0
  81. package/dist/resources/extensions/gsd/workflow-templates.js +13 -1
  82. package/dist/resources/extensions/gsd/worktree-manager.js +20 -6
  83. package/dist/resources/extensions/gsd/worktree-resolver.js +21 -4
  84. package/dist/resources/extensions/gsd/worktree.js +2 -2
  85. package/dist/resources/extensions/mcp-client/index.js +2 -1
  86. package/dist/resources/extensions/search-the-web/tool-search.js +3 -3
  87. package/dist/resources/extensions/subagent/index.js +7 -3
  88. package/dist/resources/extensions/voice/index.js +4 -4
  89. package/dist/resources/skills/create-workflow/SKILL.md +103 -0
  90. package/dist/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  91. package/dist/resources/skills/create-workflow/references/verification-policies.md +76 -0
  92. package/dist/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  93. package/dist/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  94. package/dist/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  95. package/dist/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  96. package/dist/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  97. package/dist/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  98. package/dist/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  99. package/dist/web/standalone/.next/BUILD_ID +1 -1
  100. package/dist/web/standalone/.next/app-path-routes-manifest.json +9 -9
  101. package/dist/web/standalone/.next/build-manifest.json +4 -4
  102. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  103. package/dist/web/standalone/.next/react-loadable-manifest.json +1 -1
  104. package/dist/web/standalone/.next/required-server-files.json +3 -3
  105. package/dist/web/standalone/.next/server/app/_global-error/page.js +3 -3
  106. package/dist/web/standalone/.next/server/app/_global-error/page_client-reference-manifest.js +1 -1
  107. package/dist/web/standalone/.next/server/app/_global-error.html +2 -2
  108. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  109. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  110. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  111. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  112. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  113. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  114. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  115. package/dist/web/standalone/.next/server/app/_not-found/page.js +2 -2
  116. package/dist/web/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  117. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  118. package/dist/web/standalone/.next/server/app/_not-found.rsc +3 -3
  119. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +3 -3
  120. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  121. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +3 -3
  122. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  123. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  124. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  125. package/dist/web/standalone/.next/server/app/api/boot/route.js +1 -1
  126. package/dist/web/standalone/.next/server/app/api/boot/route_client-reference-manifest.js +1 -1
  127. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route.js +1 -1
  128. package/dist/web/standalone/.next/server/app/api/bridge-terminal/input/route_client-reference-manifest.js +1 -1
  129. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route.js +1 -1
  130. package/dist/web/standalone/.next/server/app/api/bridge-terminal/resize/route_client-reference-manifest.js +1 -1
  131. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route.js +2 -2
  132. package/dist/web/standalone/.next/server/app/api/bridge-terminal/stream/route_client-reference-manifest.js +1 -1
  133. package/dist/web/standalone/.next/server/app/api/browse-directories/route.js +1 -1
  134. package/dist/web/standalone/.next/server/app/api/browse-directories/route_client-reference-manifest.js +1 -1
  135. package/dist/web/standalone/.next/server/app/api/captures/route.js +1 -1
  136. package/dist/web/standalone/.next/server/app/api/captures/route_client-reference-manifest.js +1 -1
  137. package/dist/web/standalone/.next/server/app/api/cleanup/route.js +1 -1
  138. package/dist/web/standalone/.next/server/app/api/cleanup/route_client-reference-manifest.js +1 -1
  139. package/dist/web/standalone/.next/server/app/api/dev-mode/route.js +1 -1
  140. package/dist/web/standalone/.next/server/app/api/dev-mode/route_client-reference-manifest.js +1 -1
  141. package/dist/web/standalone/.next/server/app/api/doctor/route.js +1 -1
  142. package/dist/web/standalone/.next/server/app/api/doctor/route_client-reference-manifest.js +1 -1
  143. package/dist/web/standalone/.next/server/app/api/export-data/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/api/export-data/route_client-reference-manifest.js +1 -1
  145. package/dist/web/standalone/.next/server/app/api/files/route.js +1 -1
  146. package/dist/web/standalone/.next/server/app/api/files/route_client-reference-manifest.js +1 -1
  147. package/dist/web/standalone/.next/server/app/api/forensics/route.js +1 -1
  148. package/dist/web/standalone/.next/server/app/api/forensics/route_client-reference-manifest.js +1 -1
  149. package/dist/web/standalone/.next/server/app/api/git/route.js +1 -1
  150. package/dist/web/standalone/.next/server/app/api/git/route_client-reference-manifest.js +1 -1
  151. package/dist/web/standalone/.next/server/app/api/history/route.js +1 -1
  152. package/dist/web/standalone/.next/server/app/api/history/route_client-reference-manifest.js +1 -1
  153. package/dist/web/standalone/.next/server/app/api/hooks/route.js +1 -1
  154. package/dist/web/standalone/.next/server/app/api/hooks/route_client-reference-manifest.js +1 -1
  155. package/dist/web/standalone/.next/server/app/api/inspect/route.js +1 -1
  156. package/dist/web/standalone/.next/server/app/api/inspect/route_client-reference-manifest.js +1 -1
  157. package/dist/web/standalone/.next/server/app/api/knowledge/route.js +1 -1
  158. package/dist/web/standalone/.next/server/app/api/knowledge/route_client-reference-manifest.js +1 -1
  159. package/dist/web/standalone/.next/server/app/api/live-state/route.js +1 -1
  160. package/dist/web/standalone/.next/server/app/api/live-state/route_client-reference-manifest.js +1 -1
  161. package/dist/web/standalone/.next/server/app/api/onboarding/route.js +1 -1
  162. package/dist/web/standalone/.next/server/app/api/onboarding/route_client-reference-manifest.js +1 -1
  163. package/dist/web/standalone/.next/server/app/api/preferences/route.js +1 -1
  164. package/dist/web/standalone/.next/server/app/api/preferences/route_client-reference-manifest.js +1 -1
  165. package/dist/web/standalone/.next/server/app/api/projects/route.js +1 -1
  166. package/dist/web/standalone/.next/server/app/api/projects/route_client-reference-manifest.js +1 -1
  167. package/dist/web/standalone/.next/server/app/api/recovery/route.js +1 -1
  168. package/dist/web/standalone/.next/server/app/api/recovery/route_client-reference-manifest.js +1 -1
  169. package/dist/web/standalone/.next/server/app/api/remote-questions/route.js +5 -5
  170. package/dist/web/standalone/.next/server/app/api/remote-questions/route_client-reference-manifest.js +1 -1
  171. package/dist/web/standalone/.next/server/app/api/session/browser/route.js +1 -1
  172. package/dist/web/standalone/.next/server/app/api/session/browser/route_client-reference-manifest.js +1 -1
  173. package/dist/web/standalone/.next/server/app/api/session/command/route.js +1 -1
  174. package/dist/web/standalone/.next/server/app/api/session/command/route_client-reference-manifest.js +1 -1
  175. package/dist/web/standalone/.next/server/app/api/session/events/route.js +2 -2
  176. package/dist/web/standalone/.next/server/app/api/session/events/route_client-reference-manifest.js +1 -1
  177. package/dist/web/standalone/.next/server/app/api/session/manage/route.js +1 -1
  178. package/dist/web/standalone/.next/server/app/api/session/manage/route_client-reference-manifest.js +1 -1
  179. package/dist/web/standalone/.next/server/app/api/settings-data/route.js +1 -1
  180. package/dist/web/standalone/.next/server/app/api/settings-data/route_client-reference-manifest.js +1 -1
  181. package/dist/web/standalone/.next/server/app/api/shutdown/route.js +1 -1
  182. package/dist/web/standalone/.next/server/app/api/shutdown/route_client-reference-manifest.js +1 -1
  183. package/dist/web/standalone/.next/server/app/api/skill-health/route.js +1 -1
  184. package/dist/web/standalone/.next/server/app/api/skill-health/route_client-reference-manifest.js +1 -1
  185. package/dist/web/standalone/.next/server/app/api/steer/route.js +1 -1
  186. package/dist/web/standalone/.next/server/app/api/steer/route_client-reference-manifest.js +1 -1
  187. package/dist/web/standalone/.next/server/app/api/terminal/input/route.js +1 -1
  188. package/dist/web/standalone/.next/server/app/api/terminal/input/route_client-reference-manifest.js +1 -1
  189. package/dist/web/standalone/.next/server/app/api/terminal/resize/route.js +2 -2
  190. package/dist/web/standalone/.next/server/app/api/terminal/resize/route_client-reference-manifest.js +1 -1
  191. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route.js +2 -2
  192. package/dist/web/standalone/.next/server/app/api/terminal/sessions/route_client-reference-manifest.js +1 -1
  193. package/dist/web/standalone/.next/server/app/api/terminal/stream/route.js +4 -4
  194. package/dist/web/standalone/.next/server/app/api/terminal/stream/route_client-reference-manifest.js +1 -1
  195. package/dist/web/standalone/.next/server/app/api/terminal/upload/route.js +1 -1
  196. package/dist/web/standalone/.next/server/app/api/terminal/upload/route_client-reference-manifest.js +1 -1
  197. package/dist/web/standalone/.next/server/app/api/undo/route.js +1 -1
  198. package/dist/web/standalone/.next/server/app/api/undo/route_client-reference-manifest.js +1 -1
  199. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  200. package/dist/web/standalone/.next/server/app/api/update/route_client-reference-manifest.js +1 -1
  201. package/dist/web/standalone/.next/server/app/api/visualizer/route.js +1 -1
  202. package/dist/web/standalone/.next/server/app/api/visualizer/route_client-reference-manifest.js +1 -1
  203. package/dist/web/standalone/.next/server/app/index.html +1 -1
  204. package/dist/web/standalone/.next/server/app/index.rsc +4 -4
  205. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +2 -2
  206. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +4 -4
  207. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  208. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +3 -3
  209. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  210. package/dist/web/standalone/.next/server/app/page.js +2 -2
  211. package/dist/web/standalone/.next/server/app/page_client-reference-manifest.js +1 -1
  212. package/dist/web/standalone/.next/server/app-paths-manifest.json +9 -9
  213. package/dist/web/standalone/.next/server/chunks/229.js +3 -3
  214. package/dist/web/standalone/.next/server/chunks/471.js +3 -3
  215. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  216. package/dist/web/standalone/.next/server/middleware-react-loadable-manifest.js +1 -1
  217. package/dist/web/standalone/.next/server/middleware.js +2 -2
  218. package/dist/web/standalone/.next/server/next-font-manifest.js +1 -1
  219. package/dist/web/standalone/.next/server/next-font-manifest.json +1 -1
  220. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  221. package/dist/web/standalone/.next/server/pages/500.html +2 -2
  222. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  223. package/dist/web/standalone/.next/static/chunks/4024.c195dc1fdd2adbea.js +9 -0
  224. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-f2a7482d42a5614b.js +1 -0
  225. package/dist/web/standalone/.next/static/chunks/app/layout-a16c7a7ecdf0c2cf.js +1 -0
  226. package/dist/web/standalone/.next/static/chunks/app/page-b9367c5ae13b99c6.js +1 -0
  227. package/dist/web/standalone/.next/static/chunks/{main-app-2f2ee7b85712c2bd.js → main-app-fdab67f7802d7832.js} +1 -1
  228. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-459824ffb8c323dd.js +1 -0
  229. package/dist/web/standalone/.next/static/chunks/{webpack-9afaaebf6042a1d7.js → webpack-fa307370fcf9fb2c.js} +1 -1
  230. package/dist/web/standalone/node_modules/node-pty/build/Makefile +2 -2
  231. package/dist/web/standalone/node_modules/node-pty/build/Release/pty.node +0 -0
  232. package/dist/web/standalone/node_modules/node-pty/build/pty.target.mk +14 -14
  233. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api.target.mk +14 -14
  234. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_except.target.mk +14 -14
  235. package/dist/web/standalone/node_modules/node-pty/node-addon-api/node_addon_api_maybe.target.mk +14 -14
  236. package/dist/web/standalone/server.js +1 -1
  237. package/dist/web-mode.d.ts +4 -0
  238. package/dist/web-mode.js +69 -11
  239. package/package.json +1 -1
  240. package/packages/native/src/__tests__/text.test.mjs +33 -0
  241. package/packages/pi-agent-core/dist/agent.d.ts.map +1 -1
  242. package/packages/pi-agent-core/dist/agent.js +2 -0
  243. package/packages/pi-agent-core/dist/agent.js.map +1 -1
  244. package/packages/pi-agent-core/dist/types.d.ts +6 -0
  245. package/packages/pi-agent-core/dist/types.d.ts.map +1 -1
  246. package/packages/pi-agent-core/dist/types.js.map +1 -1
  247. package/packages/pi-agent-core/src/agent.test.ts +53 -0
  248. package/packages/pi-agent-core/src/agent.ts +3 -0
  249. package/packages/pi-agent-core/src/types.ts +6 -0
  250. package/packages/pi-agent-core/tsconfig.json +1 -1
  251. package/packages/pi-ai/dist/models.d.ts +5 -3
  252. package/packages/pi-ai/dist/models.d.ts.map +1 -1
  253. package/packages/pi-ai/dist/models.generated.d.ts +801 -1468
  254. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/models.generated.js +1135 -1588
  256. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  257. package/packages/pi-ai/dist/models.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/oauth/github-copilot.d.ts.map +1 -1
  259. package/packages/pi-ai/dist/utils/oauth/github-copilot.js +60 -2
  260. package/packages/pi-ai/dist/utils/oauth/github-copilot.js.map +1 -1
  261. package/packages/pi-ai/scripts/generate-models.ts +1543 -0
  262. package/packages/pi-ai/src/models.generated.ts +1140 -1593
  263. package/packages/pi-ai/src/models.ts +7 -4
  264. package/packages/pi-ai/src/utils/oauth/github-copilot.ts +74 -2
  265. package/packages/pi-coding-agent/dist/core/agent-session.d.ts.map +1 -1
  266. package/packages/pi-coding-agent/dist/core/agent-session.js +8 -1
  267. package/packages/pi-coding-agent/dist/core/agent-session.js.map +1 -1
  268. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts +7 -0
  269. package/packages/pi-coding-agent/dist/core/auth-storage.d.ts.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/auth-storage.js +29 -2
  271. package/packages/pi-coding-agent/dist/core/auth-storage.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/auth-storage.test.js +60 -0
  273. package/packages/pi-coding-agent/dist/core/auth-storage.test.js.map +1 -1
  274. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js +3 -1
  275. package/packages/pi-coding-agent/dist/core/discovery-cache.test.js.map +1 -1
  276. package/packages/pi-coding-agent/dist/core/extensions/loader.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/extensions/loader.js +18 -0
  278. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/lsp/client.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/lsp/client.js +23 -0
  281. package/packages/pi-coding-agent/dist/core/lsp/client.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  283. package/packages/pi-coding-agent/dist/core/model-registry.js +2 -0
  284. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  285. package/packages/pi-coding-agent/dist/core/package-manager.d.ts +6 -0
  286. package/packages/pi-coding-agent/dist/core/package-manager.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/package-manager.js +63 -11
  288. package/packages/pi-coding-agent/dist/core/package-manager.js.map +1 -1
  289. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts +9 -0
  290. package/packages/pi-coding-agent/dist/core/resource-loader.d.ts.map +1 -1
  291. package/packages/pi-coding-agent/dist/core/resource-loader.js +20 -6
  292. package/packages/pi-coding-agent/dist/core/resource-loader.js.map +1 -1
  293. package/packages/pi-coding-agent/dist/core/system-prompt.d.ts.map +1 -1
  294. package/packages/pi-coding-agent/dist/core/system-prompt.js +6 -5
  295. package/packages/pi-coding-agent/dist/core/system-prompt.js.map +1 -1
  296. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  297. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js +3 -0
  298. package/packages/pi-coding-agent/dist/modes/interactive/components/extension-editor.js.map +1 -1
  299. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.d.ts.map +1 -1
  300. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js +9 -6
  301. package/packages/pi-coding-agent/dist/modes/interactive/components/footer.js.map +1 -1
  302. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  303. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js +10 -7
  304. package/packages/pi-coding-agent/dist/modes/interactive/components/login-dialog.js.map +1 -1
  305. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  306. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +34 -10
  307. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  308. package/packages/pi-coding-agent/package.json +1 -1
  309. package/packages/pi-coding-agent/src/core/agent-session.ts +7 -1
  310. package/packages/pi-coding-agent/src/core/auth-storage.test.ts +68 -0
  311. package/packages/pi-coding-agent/src/core/auth-storage.ts +30 -2
  312. package/packages/pi-coding-agent/src/core/discovery-cache.test.ts +4 -2
  313. package/packages/pi-coding-agent/src/core/extensions/loader.ts +18 -0
  314. package/packages/pi-coding-agent/src/core/lsp/client.ts +29 -0
  315. package/packages/pi-coding-agent/src/core/model-registry.ts +3 -0
  316. package/packages/pi-coding-agent/src/core/package-manager.ts +99 -58
  317. package/packages/pi-coding-agent/src/core/resource-loader.ts +24 -6
  318. package/packages/pi-coding-agent/src/core/system-prompt.ts +6 -5
  319. package/packages/pi-coding-agent/src/modes/interactive/components/extension-editor.ts +3 -0
  320. package/packages/pi-coding-agent/src/modes/interactive/components/footer.ts +10 -6
  321. package/packages/pi-coding-agent/src/modes/interactive/components/login-dialog.ts +11 -7
  322. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +36 -11
  323. package/pkg/package.json +1 -1
  324. package/src/resources/extensions/async-jobs/async-bash-timeout.test.ts +122 -0
  325. package/src/resources/extensions/async-jobs/async-bash-tool.ts +40 -4
  326. package/src/resources/extensions/async-jobs/await-tool.test.ts +47 -0
  327. package/src/resources/extensions/async-jobs/await-tool.ts +5 -0
  328. package/src/resources/extensions/async-jobs/index.ts +1 -0
  329. package/src/resources/extensions/async-jobs/job-manager.ts +2 -0
  330. package/src/resources/extensions/gsd/auto/loop-deps.ts +5 -2
  331. package/src/resources/extensions/gsd/auto/loop.ts +101 -1
  332. package/src/resources/extensions/gsd/auto/phases.ts +31 -13
  333. package/src/resources/extensions/gsd/auto/session.ts +6 -0
  334. package/src/resources/extensions/gsd/auto/types.ts +4 -0
  335. package/src/resources/extensions/gsd/auto-dashboard.ts +9 -2
  336. package/src/resources/extensions/gsd/auto-dispatch.ts +25 -5
  337. package/src/resources/extensions/gsd/auto-post-unit.ts +8 -0
  338. package/src/resources/extensions/gsd/auto-prompts.ts +2 -18
  339. package/src/resources/extensions/gsd/auto-recovery.ts +12 -4
  340. package/src/resources/extensions/gsd/auto-start.ts +15 -13
  341. package/src/resources/extensions/gsd/auto-worktree.ts +162 -18
  342. package/src/resources/extensions/gsd/auto.ts +71 -2
  343. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +209 -162
  344. package/src/resources/extensions/gsd/bootstrap/journal-tools.ts +62 -0
  345. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  346. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +25 -4
  347. package/src/resources/extensions/gsd/bootstrap/tool-call-loop-guard.ts +9 -2
  348. package/src/resources/extensions/gsd/commands/catalog.ts +40 -1
  349. package/src/resources/extensions/gsd/commands/handlers/core.ts +1 -0
  350. package/src/resources/extensions/gsd/commands/handlers/ops.ts +5 -0
  351. package/src/resources/extensions/gsd/commands/handlers/workflow.ts +164 -0
  352. package/src/resources/extensions/gsd/context-injector.ts +100 -0
  353. package/src/resources/extensions/gsd/context-store.ts +4 -3
  354. package/src/resources/extensions/gsd/custom-execution-policy.ts +73 -0
  355. package/src/resources/extensions/gsd/custom-verification.ts +180 -0
  356. package/src/resources/extensions/gsd/custom-workflow-engine.ts +216 -0
  357. package/src/resources/extensions/gsd/dashboard-overlay.ts +1 -0
  358. package/src/resources/extensions/gsd/db-writer.ts +6 -2
  359. package/src/resources/extensions/gsd/definition-loader.ts +462 -0
  360. package/src/resources/extensions/gsd/detection.ts +20 -1
  361. package/src/resources/extensions/gsd/dev-execution-policy.ts +51 -0
  362. package/src/resources/extensions/gsd/dev-workflow-engine.ts +110 -0
  363. package/src/resources/extensions/gsd/doctor-checks.ts +32 -1
  364. package/src/resources/extensions/gsd/doctor-providers.ts +13 -0
  365. package/src/resources/extensions/gsd/doctor-types.ts +1 -0
  366. package/src/resources/extensions/gsd/doctor.ts +12 -1
  367. package/src/resources/extensions/gsd/engine-resolver.ts +57 -0
  368. package/src/resources/extensions/gsd/engine-types.ts +71 -0
  369. package/src/resources/extensions/gsd/execution-policy.ts +43 -0
  370. package/src/resources/extensions/gsd/exit-command.ts +14 -2
  371. package/src/resources/extensions/gsd/export.ts +8 -15
  372. package/src/resources/extensions/gsd/extension-manifest.json +2 -2
  373. package/src/resources/extensions/gsd/files.ts +29 -12
  374. package/src/resources/extensions/gsd/forensics.ts +101 -3
  375. package/src/resources/extensions/gsd/git-constants.ts +1 -0
  376. package/src/resources/extensions/gsd/git-service.ts +5 -5
  377. package/src/resources/extensions/gsd/gitignore.ts +1 -1
  378. package/src/resources/extensions/gsd/graph.ts +312 -0
  379. package/src/resources/extensions/gsd/gsd-db.ts +37 -8
  380. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  381. package/src/resources/extensions/gsd/guided-flow.ts +7 -3
  382. package/src/resources/extensions/gsd/journal.ts +134 -0
  383. package/src/resources/extensions/gsd/md-importer.ts +6 -0
  384. package/src/resources/extensions/gsd/milestone-ids.ts +1 -1
  385. package/src/resources/extensions/gsd/native-git-bridge.ts +3 -2
  386. package/src/resources/extensions/gsd/post-unit-hooks.ts +24 -462
  387. package/src/resources/extensions/gsd/preferences-types.ts +6 -0
  388. package/src/resources/extensions/gsd/preferences.ts +63 -6
  389. package/src/resources/extensions/gsd/prompt-loader.ts +35 -4
  390. package/src/resources/extensions/gsd/prompts/complete-milestone.md +11 -10
  391. package/src/resources/extensions/gsd/prompts/discuss-headless.md +2 -2
  392. package/src/resources/extensions/gsd/prompts/discuss.md +1 -1
  393. package/src/resources/extensions/gsd/prompts/forensics.md +12 -5
  394. package/src/resources/extensions/gsd/prompts/queue.md +1 -1
  395. package/src/resources/extensions/gsd/repo-identity.ts +95 -7
  396. package/src/resources/extensions/gsd/rule-registry.ts +599 -0
  397. package/src/resources/extensions/gsd/rule-types.ts +68 -0
  398. package/src/resources/extensions/gsd/run-manager.ts +180 -0
  399. package/src/resources/extensions/gsd/service-tier.ts +184 -0
  400. package/src/resources/extensions/gsd/session-lock.ts +2 -2
  401. package/src/resources/extensions/gsd/structured-data-formatter.ts +3 -1
  402. package/src/resources/extensions/gsd/templates/decisions.md +2 -2
  403. package/src/resources/extensions/gsd/tests/activity-log.test.ts +31 -69
  404. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +103 -120
  405. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +85 -0
  406. package/src/resources/extensions/gsd/tests/auto-secrets-gate.test.ts +2 -2
  407. package/src/resources/extensions/gsd/tests/auto-worktree-milestone-merge.test.ts +202 -0
  408. package/src/resources/extensions/gsd/tests/bundled-workflow-defs.test.ts +180 -0
  409. package/src/resources/extensions/gsd/tests/captures.test.ts +12 -1
  410. package/src/resources/extensions/gsd/tests/commands-workflow-custom.test.ts +283 -0
  411. package/src/resources/extensions/gsd/tests/context-injector.test.ts +313 -0
  412. package/src/resources/extensions/gsd/tests/context-store.test.ts +10 -5
  413. package/src/resources/extensions/gsd/tests/continue-here.test.ts +20 -20
  414. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +540 -0
  415. package/src/resources/extensions/gsd/tests/custom-verification.test.ts +382 -0
  416. package/src/resources/extensions/gsd/tests/custom-workflow-engine.test.ts +339 -0
  417. package/src/resources/extensions/gsd/tests/dashboard-custom-engine.test.ts +87 -0
  418. package/src/resources/extensions/gsd/tests/db-writer.test.ts +10 -0
  419. package/src/resources/extensions/gsd/tests/definition-loader.test.ts +778 -0
  420. package/src/resources/extensions/gsd/tests/dev-engine-wrapper.test.ts +318 -0
  421. package/src/resources/extensions/gsd/tests/doctor-completion-deferral.test.ts +15 -10
  422. package/src/resources/extensions/gsd/tests/doctor-fixlevel.test.ts +5 -4
  423. package/src/resources/extensions/gsd/tests/doctor-roadmap-summary-atomicity.test.ts +167 -0
  424. package/src/resources/extensions/gsd/tests/doctor-task-done-missing-summary-slice-loop.test.ts +174 -0
  425. package/src/resources/extensions/gsd/tests/e2e-workflow-pipeline-integration.test.ts +476 -0
  426. package/src/resources/extensions/gsd/tests/engine-interfaces-contract.test.ts +271 -0
  427. package/src/resources/extensions/gsd/tests/exit-command.test.ts +55 -0
  428. package/src/resources/extensions/gsd/tests/forensics-dedup.test.ts +48 -0
  429. package/src/resources/extensions/gsd/tests/forensics-issue-routing.test.ts +43 -0
  430. package/src/resources/extensions/gsd/tests/git-locale.test.ts +133 -0
  431. package/src/resources/extensions/gsd/tests/git-service.test.ts +44 -0
  432. package/src/resources/extensions/gsd/tests/graph-operations.test.ts +599 -0
  433. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +8 -1
  434. package/src/resources/extensions/gsd/tests/gsd-tools.test.ts +7 -7
  435. package/src/resources/extensions/gsd/tests/iterate-engine-integration.test.ts +429 -0
  436. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +513 -0
  437. package/src/resources/extensions/gsd/tests/journal-query-tool.test.ts +147 -0
  438. package/src/resources/extensions/gsd/tests/journal.test.ts +341 -0
  439. package/src/resources/extensions/gsd/tests/manifest-status.test.ts +73 -82
  440. package/src/resources/extensions/gsd/tests/md-importer.test.ts +31 -1
  441. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  442. package/src/resources/extensions/gsd/tests/milestone-id-reservation.test.ts +1 -1
  443. package/src/resources/extensions/gsd/tests/parsers.test.ts +110 -0
  444. package/src/resources/extensions/gsd/tests/preferences.test.ts +47 -25
  445. package/src/resources/extensions/gsd/tests/prompt-db.test.ts +3 -1
  446. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +61 -1
  447. package/src/resources/extensions/gsd/tests/routing-history.test.ts +11 -22
  448. package/src/resources/extensions/gsd/tests/rule-registry.test.ts +413 -0
  449. package/src/resources/extensions/gsd/tests/run-manager.test.ts +229 -0
  450. package/src/resources/extensions/gsd/tests/service-tier.test.ts +127 -0
  451. package/src/resources/extensions/gsd/tests/skill-activation.test.ts +56 -3
  452. package/src/resources/extensions/gsd/tests/skill-lifecycle.test.ts +2 -2
  453. package/src/resources/extensions/gsd/tests/stalled-tool-recovery.test.ts +102 -0
  454. package/src/resources/extensions/gsd/tests/structured-data-formatter.test.ts +4 -3
  455. package/src/resources/extensions/gsd/tests/symlink-numbered-variants.test.ts +151 -0
  456. package/src/resources/extensions/gsd/tests/tool-call-loop-guard.test.ts +45 -0
  457. package/src/resources/extensions/gsd/tests/tool-naming.test.ts +117 -0
  458. package/src/resources/extensions/gsd/tests/triage-dispatch.test.ts +6 -1
  459. package/src/resources/extensions/gsd/tests/verification-gate.test.ts +156 -263
  460. package/src/resources/extensions/gsd/tests/windows-path-normalization.test.ts +99 -0
  461. package/src/resources/extensions/gsd/tests/worktree-db-integration.test.ts +1 -0
  462. package/src/resources/extensions/gsd/tests/worktree-db.test.ts +4 -0
  463. package/src/resources/extensions/gsd/tests/worktree-health-dispatch.test.ts +135 -0
  464. package/src/resources/extensions/gsd/tests/worktree-manager.test.ts +203 -106
  465. package/src/resources/extensions/gsd/tests/worktree-resolver.test.ts +79 -5
  466. package/src/resources/extensions/gsd/tests/worktree-symlink-removal.test.ts +140 -0
  467. package/src/resources/extensions/gsd/tests/worktree-sync-milestones.test.ts +74 -0
  468. package/src/resources/extensions/gsd/types.ts +3 -0
  469. package/src/resources/extensions/gsd/workflow-engine.ts +38 -0
  470. package/src/resources/extensions/gsd/workflow-templates.ts +12 -1
  471. package/src/resources/extensions/gsd/worktree-manager.ts +21 -6
  472. package/src/resources/extensions/gsd/worktree-resolver.ts +32 -12
  473. package/src/resources/extensions/gsd/worktree.ts +2 -2
  474. package/src/resources/extensions/mcp-client/index.ts +5 -1
  475. package/src/resources/extensions/search-the-web/tool-search.ts +3 -3
  476. package/src/resources/extensions/subagent/index.ts +7 -3
  477. package/src/resources/extensions/voice/index.ts +4 -4
  478. package/src/resources/skills/create-workflow/SKILL.md +103 -0
  479. package/src/resources/skills/create-workflow/references/feature-patterns.md +128 -0
  480. package/src/resources/skills/create-workflow/references/verification-policies.md +76 -0
  481. package/src/resources/skills/create-workflow/references/yaml-schema-v1.md +46 -0
  482. package/src/resources/skills/create-workflow/templates/blog-post-pipeline.yaml +60 -0
  483. package/src/resources/skills/create-workflow/templates/code-audit.yaml +60 -0
  484. package/src/resources/skills/create-workflow/templates/release-checklist.yaml +66 -0
  485. package/src/resources/skills/create-workflow/templates/workflow-definition.yaml +32 -0
  486. package/src/resources/skills/create-workflow/workflows/create-from-scratch.md +104 -0
  487. package/src/resources/skills/create-workflow/workflows/create-from-template.md +72 -0
  488. package/dist/web/standalone/.next/static/chunks/4024.279c423e4661ece1.js +0 -9
  489. package/dist/web/standalone/.next/static/chunks/app/_not-found/page-e07acdb7dd069836.js +0 -1
  490. package/dist/web/standalone/.next/static/chunks/app/layout-745c6ed5fea5fb06.js +0 -1
  491. package/dist/web/standalone/.next/static/chunks/app/page-801b53eff6e83579.js +0 -1
  492. package/dist/web/standalone/.next/static/chunks/next/dist/client/components/builtin/global-error-e6255954dccfcf0a.js +0 -1
  493. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_buildManifest.js +0 -0
  494. /package/dist/web/standalone/.next/static/{Ute3pMouVczQyT15qrBBO → qw8qDHXOTLUXBq1vEknSz}/_ssgManifest.js +0 -0
@@ -652,6 +652,116 @@ console.log('\n=== parsePlan: new-format task entries with Files and Verify subl
652
652
  assertTrue(p.tasks[0].description.includes('Why: because we need typed plan entries'), 'Why line accumulates into description');
653
653
  }
654
654
 
655
+ console.log('\n=== parsePlan: heading-style task entries (### T01 -- Title) ===');
656
+ {
657
+ const content = `# S11: Heading Style
658
+
659
+ **Goal:** Test heading-style task parsing.
660
+ **Demo:** Parser handles heading-style task entries.
661
+
662
+ ## Tasks
663
+
664
+ ### T01 -- Implement feature
665
+
666
+ - Why: the feature is needed
667
+ - Files: \`src/feature.ts\`
668
+ - Verify: npm test
669
+
670
+ ### T02 -- Write tests \`est:1h\`
671
+
672
+ Some description for the second task.
673
+ `;
674
+
675
+ const p = parsePlan(content);
676
+ assertEq(p.tasks.length, 2, 'heading-style task count');
677
+ assertEq(p.tasks[0].id, 'T01', 'heading T01 id');
678
+ assertEq(p.tasks[0].title, 'Implement feature', 'heading T01 title');
679
+ assertEq(p.tasks[0].done, false, 'heading T01 not done (headings have no checkbox)');
680
+ assertEq(p.tasks[0].files![0], 'src/feature.ts', 'heading T01 files extracted');
681
+ assertEq(p.tasks[0].verify, 'npm test', 'heading T01 verify extracted');
682
+ assertEq(p.tasks[1].id, 'T02', 'heading T02 id');
683
+ assertEq(p.tasks[1].title, 'Write tests', 'heading T02 title');
684
+ assertEq(p.tasks[1].estimate, '1h', 'heading T02 estimate');
685
+ assertTrue(p.tasks[1].description.includes('Some description'), 'heading T02 description');
686
+ }
687
+
688
+ console.log('\n=== parsePlan: heading-style with colon separator (### T01: Title) ===');
689
+ {
690
+ const content = `# S12: Heading Colon Style
691
+
692
+ **Goal:** Test colon-separated heading tasks.
693
+ **Demo:** Parser handles colon separator.
694
+
695
+ ## Tasks
696
+
697
+ ### T01: Setup project
698
+ Basic project setup steps.
699
+
700
+ ### T02: Add CI pipeline \`est:30m\`
701
+ Configure CI.
702
+ `;
703
+
704
+ const p = parsePlan(content);
705
+ assertEq(p.tasks.length, 2, 'colon heading task count');
706
+ assertEq(p.tasks[0].id, 'T01', 'colon heading T01 id');
707
+ assertEq(p.tasks[0].title, 'Setup project', 'colon heading T01 title');
708
+ assertEq(p.tasks[1].id, 'T02', 'colon heading T02 id');
709
+ assertEq(p.tasks[1].title, 'Add CI pipeline', 'colon heading T02 title');
710
+ assertEq(p.tasks[1].estimate, '30m', 'colon heading T02 estimate');
711
+ }
712
+
713
+ console.log('\n=== parsePlan: heading-style with em-dash separator (### T01 — Title) ===');
714
+ {
715
+ const content = `# S13: Em-Dash Style
716
+
717
+ **Goal:** Test em-dash separated heading tasks.
718
+ **Demo:** Parser handles em-dash separator.
719
+
720
+ ## Tasks
721
+
722
+ ### T01 — Build the widget
723
+
724
+ Widget description.
725
+ `;
726
+
727
+ const p = parsePlan(content);
728
+ assertEq(p.tasks.length, 1, 'em-dash heading task count');
729
+ assertEq(p.tasks[0].id, 'T01', 'em-dash heading T01 id');
730
+ assertEq(p.tasks[0].title, 'Build the widget', 'em-dash heading T01 title');
731
+ }
732
+
733
+ console.log('\n=== parsePlan: mixed checkbox and heading-style tasks ===');
734
+ {
735
+ const content = `# S14: Mixed Format
736
+
737
+ **Goal:** Test mixed formats.
738
+ **Demo:** Parser handles both styles in one plan.
739
+
740
+ ## Tasks
741
+
742
+ - [ ] **T01: Checkbox task** \`est:20m\`
743
+ A checkbox-style task.
744
+
745
+ ### T02 -- Heading task \`est:15m\`
746
+
747
+ A heading-style task.
748
+
749
+ - [x] **T03: Done checkbox task** \`est:10m\`
750
+ Already completed.
751
+ `;
752
+
753
+ const p = parsePlan(content);
754
+ assertEq(p.tasks.length, 3, 'mixed format task count');
755
+ assertEq(p.tasks[0].id, 'T01', 'mixed T01 id');
756
+ assertEq(p.tasks[0].done, false, 'mixed T01 not done');
757
+ assertEq(p.tasks[1].id, 'T02', 'mixed T02 id');
758
+ assertEq(p.tasks[1].title, 'Heading task', 'mixed T02 title');
759
+ assertEq(p.tasks[1].estimate, '15m', 'mixed T02 estimate');
760
+ assertEq(p.tasks[1].done, false, 'mixed T02 not done (heading style)');
761
+ assertEq(p.tasks[2].id, 'T03', 'mixed T03 id');
762
+ assertEq(p.tasks[2].done, true, 'mixed T03 done');
763
+ }
764
+
655
765
  // ═══════════════════════════════════════════════════════════════════════════
656
766
  // parseSummary tests
657
767
  // ═══════════════════════════════════════════════════════════════════════════
@@ -249,19 +249,41 @@ test("all wizard fields together produce no errors", () => {
249
249
 
250
250
  // ── Hook config ──────────────────────────────────────────────────────────────
251
251
 
252
- test("post-unit hook max_cycles clamping", () => {
253
- assert.equal(Math.max(1, Math.min(10, Math.round(15))), 10);
254
- assert.equal(Math.max(1, Math.min(10, Math.round(0))), 1);
255
- assert.equal(Math.max(1, Math.min(10, Math.round(-5))), 1);
256
- assert.equal(Math.max(1, Math.min(10, Math.round(3))), 3);
252
+ test("post-unit hook max_cycles clamping via validatePreferences", () => {
253
+ const base = { name: "h", after: ["execute-task"], prompt: "do something" };
254
+
255
+ const { preferences: p1 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 15 }] } as any);
256
+ assert.equal(p1.post_unit_hooks![0].max_cycles, 10, "clamps to 10");
257
+
258
+ const { preferences: p2 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 0 }] } as any);
259
+ assert.equal(p2.post_unit_hooks![0].max_cycles, 1, "clamps to 1");
260
+
261
+ const { preferences: p3 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: -5 }] } as any);
262
+ assert.equal(p3.post_unit_hooks![0].max_cycles, 1, "negative clamps to 1");
263
+
264
+ const { preferences: p4 } = validatePreferences({ post_unit_hooks: [{ ...base, max_cycles: 3 }] } as any);
265
+ assert.equal(p4.post_unit_hooks![0].max_cycles, 3, "valid value passes through");
257
266
  });
258
267
 
259
- test("pre-dispatch hook action validation", () => {
260
- const valid = new Set(["modify", "skip", "replace"]);
261
- assert.ok(valid.has("modify"));
262
- assert.ok(valid.has("skip"));
263
- assert.ok(valid.has("replace"));
264
- assert.ok(!valid.has("delete"));
268
+ test("pre-dispatch hook action validation via validatePreferences", () => {
269
+ const base = { name: "h", before: ["execute-task"] };
270
+
271
+ const { preferences, errors: e1 } = validatePreferences({
272
+ pre_dispatch_hooks: [{ ...base, action: "skip" }],
273
+ } as any);
274
+ assert.equal(e1.length, 0);
275
+ assert.equal(preferences.pre_dispatch_hooks![0].action, "skip");
276
+
277
+ const { preferences: p2, errors: e2 } = validatePreferences({
278
+ pre_dispatch_hooks: [{ ...base, action: "modify", prepend: "note: " }],
279
+ } as any);
280
+ assert.equal(e2.length, 0);
281
+ assert.equal(p2.pre_dispatch_hooks![0].action, "modify");
282
+
283
+ const { errors: e3 } = validatePreferences({
284
+ pre_dispatch_hooks: [{ ...base, action: "delete" }],
285
+ } as any);
286
+ assert.ok(e3.some(e => e.includes("invalid action")));
265
287
  });
266
288
 
267
289
  // ── Model config parsing ─────────────────────────────────────────────────────
@@ -269,8 +291,8 @@ test("pre-dispatch hook action validation", () => {
269
291
  test("parses OpenRouter model config with org/model IDs and fallbacks", () => {
270
292
  const content = `---\nversion: 1\nmodels:\n research:\n model: moonshotai/kimi-k2.5\n fallbacks:\n - qwen/qwen3.5-397b-a17b\n planning:\n model: deepseek/deepseek-r1-0528\n fallbacks:\n - moonshotai/kimi-k2.5\n - deepseek/deepseek-v3.2\n execution:\n model: qwen/qwen3-coder\n fallbacks:\n - qwen/qwen3-coder-next\n---\n`;
271
293
  const prefs = parsePreferencesMarkdown(content);
272
- assert.ok(prefs);
273
- const models = prefs.models as GSDModelConfigV2;
294
+ assert.notEqual(prefs, null);
295
+ const models = prefs!.models as GSDModelConfigV2;
274
296
  const research = models.research as GSDPhaseModelConfig;
275
297
  assert.equal(research.model, "moonshotai/kimi-k2.5");
276
298
  assert.deepEqual(research.fallbacks, ["qwen/qwen3.5-397b-a17b"]);
@@ -281,8 +303,8 @@ test("parses OpenRouter model config with org/model IDs and fallbacks", () => {
281
303
  test("parses model IDs with colons (OpenRouter :free, :exacto)", () => {
282
304
  const content = `---\nmodels:\n execution:\n model: qwen/qwen3-coder\n fallbacks:\n - qwen/qwen3-coder:free\n - qwen/qwen3-coder:exacto\n---\n`;
283
305
  const prefs = parsePreferencesMarkdown(content);
284
- assert.ok(prefs);
285
- const models = prefs.models as GSDModelConfigV2;
306
+ assert.notEqual(prefs, null);
307
+ const models = prefs!.models as GSDModelConfigV2;
286
308
  const execution = models.execution as GSDPhaseModelConfig;
287
309
  assert.deepEqual(execution.fallbacks, ["qwen/qwen3-coder:free", "qwen/qwen3-coder:exacto"]);
288
310
  });
@@ -290,8 +312,8 @@ test("parses model IDs with colons (OpenRouter :free, :exacto)", () => {
290
312
  test("parses legacy string-per-phase model config", () => {
291
313
  const content = `---\nmodels:\n research: claude-opus-4-6\n execution: claude-sonnet-4-6\n---\n`;
292
314
  const prefs = parsePreferencesMarkdown(content);
293
- assert.ok(prefs);
294
- const models = prefs.models as GSDModelConfigV2;
315
+ assert.notEqual(prefs, null);
316
+ const models = prefs!.models as GSDModelConfigV2;
295
317
  assert.equal(models.research, "claude-opus-4-6");
296
318
  assert.equal(models.execution, "claude-sonnet-4-6");
297
319
  });
@@ -299,8 +321,8 @@ test("parses legacy string-per-phase model config", () => {
299
321
  test("strips inline YAML comments from values", () => {
300
322
  const content = `---\nmodels:\n execution:\n model: qwen/qwen3-coder # fast\n fallbacks:\n - minimax/minimax-m2.5 # backup\n---\n`;
301
323
  const prefs = parsePreferencesMarkdown(content);
302
- assert.ok(prefs);
303
- const models = prefs.models as GSDModelConfigV2;
324
+ assert.notEqual(prefs, null);
325
+ const models = prefs!.models as GSDModelConfigV2;
304
326
  const execution = models.execution as GSDPhaseModelConfig;
305
327
  assert.equal(execution.model, "qwen/qwen3-coder");
306
328
  assert.deepEqual(execution.fallbacks, ["minimax/minimax-m2.5"]);
@@ -309,8 +331,8 @@ test("strips inline YAML comments from values", () => {
309
331
  test("handles Windows CRLF line endings", () => {
310
332
  const content = "---\r\nmodels:\r\n execution:\r\n model: qwen/qwen3-coder\r\n---\r\n";
311
333
  const prefs = parsePreferencesMarkdown(content);
312
- assert.ok(prefs);
313
- const models = prefs.models as GSDModelConfigV2;
334
+ assert.notEqual(prefs, null);
335
+ const models = prefs!.models as GSDModelConfigV2;
314
336
  const execution = models.execution as GSDPhaseModelConfig;
315
337
  assert.equal(execution.model, "qwen/qwen3-coder");
316
338
  });
@@ -318,8 +340,8 @@ test("handles Windows CRLF line endings", () => {
318
340
  test("handles model config with explicit provider field", () => {
319
341
  const content = `---\nmodels:\n execution:\n model: claude-opus-4-6\n provider: bedrock\n fallbacks:\n - claude-sonnet-4-6\n---\n`;
320
342
  const prefs = parsePreferencesMarkdown(content);
321
- assert.ok(prefs);
322
- const models = prefs.models as GSDModelConfigV2;
343
+ assert.notEqual(prefs, null);
344
+ const models = prefs!.models as GSDModelConfigV2;
323
345
  const execution = models.execution as GSDPhaseModelConfig;
324
346
  assert.equal(execution.model, "claude-opus-4-6");
325
347
  assert.equal(execution.provider, "bedrock");
@@ -327,6 +349,6 @@ test("handles model config with explicit provider field", () => {
327
349
 
328
350
  test("handles empty models config", () => {
329
351
  const prefs = parsePreferencesMarkdown("---\nversion: 1\n---\n");
330
- assert.ok(prefs);
331
- assert.equal(prefs.models, undefined);
352
+ assert.notEqual(prefs, null);
353
+ assert.equal(prefs!.models, undefined);
332
354
  });
@@ -43,6 +43,7 @@ console.log('\n=== prompt-db: scoped decisions from DB ===');
43
43
  choice: `choice ${i}`,
44
44
  rationale: `rationale ${i}`,
45
45
  revisable: 'yes',
46
+ made_by: 'agent',
46
47
  superseded_by: null,
47
48
  });
48
49
  }
@@ -201,6 +202,7 @@ console.log('\n=== prompt-db: scoped filtering reduces content ===');
201
202
  choice: `choice ${i}`,
202
203
  rationale: `rationale ${i} with additional context`,
203
204
  revisable: 'yes',
205
+ made_by: 'agent',
204
206
  superseded_by: null,
205
207
  });
206
208
  }
@@ -269,7 +271,7 @@ console.log('\n=== prompt-db: DB helpers wrapper format matches expected pattern
269
271
  insertDecision({
270
272
  id: 'D001', when_context: 'M001/S01', scope: 'architecture',
271
273
  decision: 'use SQLite', choice: 'better-sqlite3', rationale: 'fast',
272
- revisable: 'yes', superseded_by: null,
274
+ revisable: 'yes', made_by: 'agent', superseded_by: null,
273
275
  });
274
276
 
275
277
  insertRequirement({
@@ -3,7 +3,7 @@ import { join } from "node:path";
3
3
  import { tmpdir } from "node:os";
4
4
  import { execSync } from "node:child_process";
5
5
 
6
- import { repoIdentity, externalGsdRoot, ensureGsdSymlink, validateProjectId, readRepoMeta } from "../repo-identity.ts";
6
+ import { repoIdentity, externalGsdRoot, ensureGsdSymlink, validateProjectId, readRepoMeta, isInheritedRepo } from "../repo-identity.ts";
7
7
  import { createTestContext } from "./test-helpers.ts";
8
8
 
9
9
  const { assertEq, assertTrue, report } = createTestContext();
@@ -118,6 +118,66 @@ async function main(): Promise<void> {
118
118
  delete process.env.GSD_PROJECT_ID;
119
119
  }
120
120
 
121
+ console.log("\n=== isInheritedRepo detects subdirectory of parent repo without .gsd (#1639) ===");
122
+ {
123
+ const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-parent-")));
124
+ run("git init -b main", parentRepo);
125
+ run('git config user.name "Pi Test"', parentRepo);
126
+ run('git config user.email "pi@example.com"', parentRepo);
127
+ writeFileSync(join(parentRepo, "README.md"), "# Parent\n", "utf-8");
128
+ run("git add README.md", parentRepo);
129
+ run('git commit -m "init"', parentRepo);
130
+
131
+ // Create a subdirectory — no .gsd at parent
132
+ const subdir = join(parentRepo, "newproject");
133
+ mkdirSync(subdir, { recursive: true });
134
+ assertTrue(isInheritedRepo(subdir), "subdirectory of parent repo without .gsd is inherited");
135
+
136
+ // After adding .gsd at parent, subdirectory is a legitimate child
137
+ mkdirSync(join(parentRepo, ".gsd"), { recursive: true });
138
+ assertTrue(!isInheritedRepo(subdir), "subdirectory of parent repo WITH .gsd is NOT inherited");
139
+
140
+ // The git root itself is never inherited
141
+ assertTrue(!isInheritedRepo(parentRepo), "git root is not inherited");
142
+
143
+ // A standalone repo (not a subdir) is not inherited
144
+ const standaloneRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-inherited-standalone-")));
145
+ run("git init -b main", standaloneRepo);
146
+ run('git config user.name "Pi Test"', standaloneRepo);
147
+ run('git config user.email "pi@example.com"', standaloneRepo);
148
+ assertTrue(!isInheritedRepo(standaloneRepo), "standalone repo is not inherited");
149
+
150
+ rmSync(parentRepo, { recursive: true, force: true });
151
+ rmSync(standaloneRepo, { recursive: true, force: true });
152
+ }
153
+
154
+ console.log("\n=== subdirectory of parent repo gets unique identity after git init (#1639) ===");
155
+ {
156
+ const parentRepo = realpathSync(mkdtempSync(join(tmpdir(), "gsd-identity-parent-")));
157
+ run("git init -b main", parentRepo);
158
+ run('git config user.name "Pi Test"', parentRepo);
159
+ run('git config user.email "pi@example.com"', parentRepo);
160
+ run('git remote add origin git@github.com:example/parent-project.git', parentRepo);
161
+ writeFileSync(join(parentRepo, "README.md"), "# Parent\n", "utf-8");
162
+ run("git add README.md", parentRepo);
163
+ run('git commit -m "init"', parentRepo);
164
+
165
+ const subdir = join(parentRepo, "childproject");
166
+ mkdirSync(subdir, { recursive: true });
167
+
168
+ // Before git init, subdirectory shares parent's identity
169
+ const parentIdentity = repoIdentity(parentRepo);
170
+ const subdirIdentityBefore = repoIdentity(subdir);
171
+ assertEq(subdirIdentityBefore, parentIdentity, "subdirectory shares parent identity before its own git init");
172
+
173
+ // After git init, subdirectory gets its own identity
174
+ run("git init -b main", subdir);
175
+ const subdirIdentityAfter = repoIdentity(subdir);
176
+ assertTrue(subdirIdentityAfter !== parentIdentity, "subdirectory gets unique identity after git init");
177
+
178
+ rmSync(parentRepo, { recursive: true, force: true });
179
+ }
180
+
121
181
  console.log("\n=== validateProjectId rejects invalid values ===");
122
182
  for (const invalid of ["has spaces", "path/traversal", "dot..dot", "back\\slash"]) {
123
183
  assertTrue(!validateProjectId(invalid), `validateProjectId rejects invalid value: "${invalid}"`);
@@ -1,6 +1,6 @@
1
1
  import test from "node:test";
2
2
  import assert from "node:assert/strict";
3
- import { mkdirSync, rmSync, writeFileSync, readFileSync } from "node:fs";
3
+ import { mkdirSync, rmSync } from "node:fs";
4
4
  import { join } from "node:path";
5
5
  import { tmpdir } from "node:os";
6
6
 
@@ -37,12 +37,9 @@ test("recordOutcome tracks success and failure counts", () => {
37
37
  recordOutcome("execute-task", "standard", true);
38
38
  recordOutcome("execute-task", "standard", false);
39
39
 
40
- const history = getRoutingHistory();
41
- assert.ok(history);
42
- const pattern = history.patterns["execute-task"];
43
- assert.ok(pattern);
44
- assert.equal(pattern.standard.success, 2);
45
- assert.equal(pattern.standard.fail, 1);
40
+ const history = getRoutingHistory()!;
41
+ assert.equal(history.patterns["execute-task"].standard.success, 2);
42
+ assert.equal(history.patterns["execute-task"].standard.fail, 1);
46
43
  } finally {
47
44
  cleanup(dir);
48
45
  }
@@ -54,9 +51,7 @@ test("recordOutcome tracks tag-specific patterns", () => {
54
51
  initRoutingHistory(dir);
55
52
  recordOutcome("execute-task", "light", true, ["docs"]);
56
53
 
57
- const history = getRoutingHistory();
58
- assert.ok(history);
59
- assert.ok(history.patterns["execute-task:docs"]);
54
+ const history = getRoutingHistory()!;
60
55
  assert.equal(history.patterns["execute-task:docs"].light.success, 1);
61
56
  } finally {
62
57
  cleanup(dir);
@@ -72,8 +67,7 @@ test("recordOutcome applies rolling window", () => {
72
67
  recordOutcome("execute-task", "standard", true);
73
68
  }
74
69
 
75
- const history = getRoutingHistory();
76
- assert.ok(history);
70
+ const history = getRoutingHistory()!;
77
71
  const total = history.patterns["execute-task"].standard.success +
78
72
  history.patterns["execute-task"].standard.fail;
79
73
  assert.ok(total <= 50, `total ${total} should be <= 50`);
@@ -161,8 +155,7 @@ test("recordFeedback stores feedback entries", () => {
161
155
  initRoutingHistory(dir);
162
156
  recordFeedback("execute-task", "M001/S01/T01", "standard", "over");
163
157
 
164
- const history = getRoutingHistory();
165
- assert.ok(history);
158
+ const history = getRoutingHistory()!;
166
159
  assert.equal(history.feedback.length, 1);
167
160
  assert.equal(history.feedback[0].rating, "over");
168
161
  assert.equal(history.feedback[0].tier, "standard");
@@ -177,8 +170,7 @@ test("recordFeedback 'under' increases failure count at tier", () => {
177
170
  initRoutingHistory(dir);
178
171
  recordFeedback("execute-task", "M001/S01/T01", "light", "under");
179
172
 
180
- const history = getRoutingHistory();
181
- assert.ok(history);
173
+ const history = getRoutingHistory()!;
182
174
  // "under" adds 2 (FEEDBACK_WEIGHT) failures
183
175
  assert.equal(history.patterns["execute-task"].light.fail, 2);
184
176
  } finally {
@@ -192,8 +184,7 @@ test("recordFeedback 'over' increases success count at lower tier", () => {
192
184
  initRoutingHistory(dir);
193
185
  recordFeedback("execute-task", "M001/S01/T01", "standard", "over");
194
186
 
195
- const history = getRoutingHistory();
196
- assert.ok(history);
187
+ const history = getRoutingHistory()!;
197
188
  // "over" at standard → adds 2 successes at light
198
189
  assert.equal(history.patterns["execute-task"].light.success, 2);
199
190
  } finally {
@@ -210,8 +201,7 @@ test("clearRoutingHistory resets all data", () => {
210
201
  recordOutcome("execute-task", "light", true);
211
202
  clearRoutingHistory(dir);
212
203
 
213
- const history = getRoutingHistory();
214
- assert.ok(history);
204
+ const history = getRoutingHistory()!;
215
205
  assert.deepEqual(history.patterns, {});
216
206
  assert.deepEqual(history.feedback, []);
217
207
  } finally {
@@ -231,8 +221,7 @@ test("routing history persists to disk and reloads", () => {
231
221
 
232
222
  // Reload from disk
233
223
  initRoutingHistory(dir);
234
- const history = getRoutingHistory();
235
- assert.ok(history);
224
+ const history = getRoutingHistory()!;
236
225
  assert.equal(history.patterns["execute-task"].standard.success, 2);
237
226
  } finally {
238
227
  cleanup(dir);