@opengsd/gsd-pi 1.0.2-dev.e70300c → 1.0.2-dev.fb7ddf1

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 (480) hide show
  1. package/README.md +63 -12
  2. package/dist/headless-answers.js +2 -1
  3. package/dist/headless-events.d.ts +1 -0
  4. package/dist/headless-events.js +8 -1
  5. package/dist/onboarding.js +22 -3
  6. package/dist/resource-loader.d.ts +7 -0
  7. package/dist/resource-loader.js +44 -9
  8. package/dist/resources/.managed-resources-content-hash +1 -1
  9. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +34 -11
  10. package/dist/resources/extensions/context7/index.js +12 -2
  11. package/dist/resources/extensions/get-secrets-from-user.js +16 -16
  12. package/dist/resources/extensions/google-cli/index.js +30 -0
  13. package/dist/resources/extensions/google-cli/models.js +55 -0
  14. package/dist/resources/extensions/google-cli/package.json +11 -0
  15. package/dist/resources/extensions/google-cli/readiness.js +12 -0
  16. package/dist/resources/extensions/google-cli/stream-adapter.js +191 -0
  17. package/dist/resources/extensions/gsd/auto/loop.js +81 -1
  18. package/dist/resources/extensions/gsd/auto/orchestrator.js +4 -2
  19. package/dist/resources/extensions/gsd/auto/phases.js +38 -1
  20. package/dist/resources/extensions/gsd/auto/run-unit.js +8 -0
  21. package/dist/resources/extensions/gsd/auto/session.js +3 -0
  22. package/dist/resources/extensions/gsd/auto-dispatch.js +17 -7
  23. package/dist/resources/extensions/gsd/auto-post-unit.js +65 -16
  24. package/dist/resources/extensions/gsd/auto-prompts.js +5 -236
  25. package/dist/resources/extensions/gsd/auto-recovery.js +10 -5
  26. package/dist/resources/extensions/gsd/auto-start.js +232 -49
  27. package/dist/resources/extensions/gsd/auto-tool-tracking.js +2 -1
  28. package/dist/resources/extensions/gsd/auto-verification.js +14 -2
  29. package/dist/resources/extensions/gsd/auto-worktree.js +34 -1
  30. package/dist/resources/extensions/gsd/auto.js +40 -2
  31. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +4 -3
  32. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +7 -2
  33. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +39 -5
  34. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +107 -27
  35. package/dist/resources/extensions/gsd/bootstrap/system-context.js +3 -27
  36. package/dist/resources/extensions/gsd/bootstrap/tool-search-shim.js +4 -4
  37. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +1 -1
  38. package/dist/resources/extensions/gsd/closeout-recovery.js +7 -1
  39. package/dist/resources/extensions/gsd/commands/handlers/auto.js +9 -1
  40. package/dist/resources/extensions/gsd/commands-handlers.js +3 -0
  41. package/dist/resources/extensions/gsd/commands-usage.js +105 -1
  42. package/dist/resources/extensions/gsd/config-overlay.js +20 -14
  43. package/dist/resources/extensions/gsd/context-overlay.js +22 -16
  44. package/dist/resources/extensions/gsd/dashboard-overlay.js +10 -23
  45. package/dist/resources/extensions/gsd/doctor-engine-checks.js +87 -0
  46. package/dist/resources/extensions/gsd/doctor-git-checks.js +70 -5
  47. package/dist/resources/extensions/gsd/doctor-providers.js +54 -24
  48. package/dist/resources/extensions/gsd/doctor.js +7 -2
  49. package/dist/resources/extensions/gsd/git-conflict-state.js +26 -1
  50. package/dist/resources/extensions/gsd/guided-flow.js +5 -6
  51. package/dist/resources/extensions/gsd/key-manager.js +45 -13
  52. package/dist/resources/extensions/gsd/mcp-filter.js +57 -18
  53. package/dist/resources/extensions/gsd/mcp-project-config.js +15 -9
  54. package/dist/resources/extensions/gsd/migration-auto-check.js +5 -1
  55. package/dist/resources/extensions/gsd/milestone-actions.js +3 -0
  56. package/dist/resources/extensions/gsd/milestone-reopen-events.js +28 -0
  57. package/dist/resources/extensions/gsd/notification-overlay.js +8 -9
  58. package/dist/resources/extensions/gsd/parallel-merge.js +6 -4
  59. package/dist/resources/extensions/gsd/parallel-monitor-overlay.js +15 -13
  60. package/dist/resources/extensions/gsd/post-execution-checks.js +5 -4
  61. package/dist/resources/extensions/gsd/preferences-skills.js +11 -4
  62. package/dist/resources/extensions/gsd/preferences.js +14 -2
  63. package/dist/resources/extensions/gsd/prompt-loader.js +2 -0
  64. package/dist/resources/extensions/gsd/prompts/discuss.md +4 -2
  65. package/dist/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  66. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  67. package/dist/resources/extensions/gsd/prompts/system.md +3 -20
  68. package/dist/resources/extensions/gsd/queue-reorder-ui.js +28 -18
  69. package/dist/resources/extensions/gsd/repo-identity.js +36 -6
  70. package/dist/resources/extensions/gsd/repository-registry.js +3 -1
  71. package/dist/resources/extensions/gsd/safety/evidence-collector.js +13 -6
  72. package/dist/resources/extensions/gsd/skill-activation.js +233 -0
  73. package/dist/resources/extensions/gsd/skill-catalog.data.js +820 -0
  74. package/dist/resources/extensions/gsd/skill-catalog.install.js +179 -0
  75. package/dist/resources/extensions/gsd/skill-catalog.js +5 -1028
  76. package/dist/resources/extensions/gsd/skill-discovery.js +121 -79
  77. package/dist/resources/extensions/gsd/skill-scope.js +52 -0
  78. package/dist/resources/extensions/gsd/skill-telemetry.js +6 -39
  79. package/dist/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  80. package/dist/resources/extensions/gsd/skills.js +60 -0
  81. package/dist/resources/extensions/gsd/state-reconciliation/drift/artifact-db.js +351 -0
  82. package/dist/resources/extensions/gsd/state-reconciliation/index.js +41 -0
  83. package/dist/resources/extensions/gsd/state-reconciliation/registry.js +4 -0
  84. package/dist/resources/extensions/gsd/tools/complete-task.js +9 -0
  85. package/dist/resources/extensions/gsd/tools/exec-tool.js +42 -8
  86. package/dist/resources/extensions/gsd/tools/workflow-tool-executors.js +63 -2
  87. package/dist/resources/extensions/gsd/tui/render-kit.js +51 -0
  88. package/dist/resources/extensions/gsd/unit-context-manifest.js +35 -26
  89. package/dist/resources/extensions/gsd/user-input-boundary.js +1 -1
  90. package/dist/resources/extensions/gsd/vision-ask.js +22 -0
  91. package/dist/resources/extensions/gsd/visualizer-overlay.js +8 -36
  92. package/dist/resources/extensions/gsd/worktree-lifecycle.js +24 -3
  93. package/dist/resources/extensions/gsd/worktree-state-projection.js +29 -0
  94. package/dist/resources/extensions/search-the-web/native-search.js +57 -8
  95. package/dist/resources/extensions/shared/confirm-ui.js +9 -6
  96. package/dist/resources/extensions/shared/dialog-frame.js +42 -0
  97. package/dist/resources/extensions/shared/interview-ui.js +42 -30
  98. package/dist/resources/extensions/shared/next-action-ui.js +6 -6
  99. package/dist/resources/extensions/subagent/index.js +8 -15
  100. package/dist/resources/shared/package-manager-detection.js +36 -0
  101. package/dist/resources/skills/agent-browser/SKILL.md +1 -1
  102. package/dist/resources/skills/api-design/SKILL.md +1 -1
  103. package/dist/resources/skills/code-optimizer/SKILL.md +6 -11
  104. package/dist/resources/skills/create-gsd-extension/SKILL.md +1 -1
  105. package/dist/resources/skills/create-mcp-server/SKILL.md +1 -1
  106. package/dist/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  107. package/dist/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  108. package/dist/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  109. package/dist/resources/skills/decompose-into-slices/SKILL.md +3 -3
  110. package/dist/resources/skills/dependency-upgrade/SKILL.md +1 -1
  111. package/dist/resources/skills/forensics/SKILL.md +2 -2
  112. package/dist/resources/skills/grill-me/SKILL.md +1 -1
  113. package/dist/resources/skills/handoff/SKILL.md +1 -1
  114. package/dist/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  115. package/dist/resources/skills/observability/SKILL.md +1 -1
  116. package/dist/resources/skills/security-review/SKILL.md +1 -1
  117. package/dist/resources/skills/spike-wrap-up/SKILL.md +1 -1
  118. package/dist/resources/skills/tdd/SKILL.md +1 -1
  119. package/dist/resources/skills/write-docs/SKILL.md +1 -1
  120. package/dist/resources/skills/write-milestone-brief/SKILL.md +1 -1
  121. package/dist/update-check.d.ts +6 -2
  122. package/dist/update-check.js +7 -3
  123. package/dist/web/standalone/.next/BUILD_ID +1 -1
  124. package/dist/web/standalone/.next/app-path-routes-manifest.json +8 -8
  125. package/dist/web/standalone/.next/build-manifest.json +2 -2
  126. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  127. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  128. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  129. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  130. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  131. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  132. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  133. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  134. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  135. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  136. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  137. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  138. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  139. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  140. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  141. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  142. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  143. package/dist/web/standalone/.next/server/app/api/update/route.js +1 -1
  144. package/dist/web/standalone/.next/server/app/index.html +1 -1
  145. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  146. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  147. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  148. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  149. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  150. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  151. package/dist/web/standalone/.next/server/app-paths-manifest.json +8 -8
  152. package/dist/web/standalone/.next/server/chunks/1834.js +2 -2
  153. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  154. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  155. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  156. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  157. package/dist/web/standalone/node_modules/node-pty/build/Makefile +1 -1
  158. package/package.json +5 -2
  159. package/packages/cloud-mcp-gateway/package.json +2 -2
  160. package/packages/contracts/dist/rpc.test.js +5 -0
  161. package/packages/contracts/dist/rpc.test.js.map +1 -1
  162. package/packages/contracts/dist/workflow.d.ts +15 -0
  163. package/packages/contracts/dist/workflow.d.ts.map +1 -1
  164. package/packages/contracts/dist/workflow.js +16 -0
  165. package/packages/contracts/dist/workflow.js.map +1 -1
  166. package/packages/contracts/dist/workflow.test.js +1 -0
  167. package/packages/contracts/dist/workflow.test.js.map +1 -1
  168. package/packages/contracts/package.json +1 -1
  169. package/packages/daemon/package.json +4 -4
  170. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts +1 -0
  171. package/packages/gsd-agent-core/dist/session/agent-session-extensions.d.ts.map +1 -1
  172. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js +22 -8
  173. package/packages/gsd-agent-core/dist/session/agent-session-extensions.js.map +1 -1
  174. package/packages/gsd-agent-core/package.json +5 -5
  175. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts +12 -0
  176. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.d.ts.map +1 -0
  177. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js +45 -0
  178. package/packages/gsd-agent-modes/dist/modes/interactive/components/dialog-container.js.map +1 -0
  179. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts +3 -2
  180. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.d.ts.map +1 -1
  181. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js +11 -11
  182. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-editor.js.map +1 -1
  183. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts +3 -3
  184. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.d.ts.map +1 -1
  185. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js +13 -11
  186. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-input.js.map +1 -1
  187. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts +3 -3
  188. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.d.ts.map +1 -1
  189. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js +12 -10
  190. package/packages/gsd-agent-modes/dist/modes/interactive/components/extension-selector.js.map +1 -1
  191. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts +1 -0
  192. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.d.ts.map +1 -1
  193. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js +1 -0
  194. package/packages/gsd-agent-modes/dist/modes/interactive/components/index.js.map +1 -1
  195. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts +1 -1
  196. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  197. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js +2 -2
  198. package/packages/gsd-agent-modes/dist/modes/interactive/components/login-dialog.js.map +1 -1
  199. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts +6 -1
  200. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.d.ts.map +1 -1
  201. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js +9 -6
  202. package/packages/gsd-agent-modes/dist/modes/interactive/components/oauth-selector.js.map +1 -1
  203. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.d.ts.map +1 -1
  204. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js +3 -1
  205. package/packages/gsd-agent-modes/dist/modes/interactive/components/tool-execution.js.map +1 -1
  206. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.d.ts.map +1 -1
  207. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js +0 -2
  208. package/packages/gsd-agent-modes/dist/modes/interactive/components/transcript-design.js.map +1 -1
  209. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts +1 -0
  210. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.d.ts.map +1 -1
  211. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js +1 -0
  212. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode-class-constants.js.map +1 -1
  213. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  214. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js +2 -1
  215. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-mode.js.map +1 -1
  216. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts +3 -0
  217. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.d.ts.map +1 -1
  218. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js +144 -2
  219. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-auth.js.map +1 -1
  220. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.d.ts.map +1 -1
  221. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js +2 -14
  222. package/packages/gsd-agent-modes/dist/modes/interactive/interactive-selectors-session.js.map +1 -1
  223. package/packages/gsd-agent-modes/package.json +7 -7
  224. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  225. package/packages/mcp-server/dist/server.js +7 -1
  226. package/packages/mcp-server/dist/server.js.map +1 -1
  227. package/packages/mcp-server/dist/workflow-tools.d.ts +13 -1
  228. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  229. package/packages/mcp-server/dist/workflow-tools.js +47 -8
  230. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  231. package/packages/mcp-server/package.json +3 -3
  232. package/packages/native/package.json +1 -1
  233. package/packages/pi-agent-core/dist/agent-loop.js +16 -14
  234. package/packages/pi-agent-core/dist/agent-loop.js.map +1 -1
  235. package/packages/pi-agent-core/dist/harness/skills.d.ts.map +1 -1
  236. package/packages/pi-agent-core/dist/harness/skills.js +6 -0
  237. package/packages/pi-agent-core/dist/harness/skills.js.map +1 -1
  238. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts +7 -0
  239. package/packages/pi-agent-core/dist/harness/system-prompt.d.ts.map +1 -1
  240. package/packages/pi-agent-core/dist/harness/system-prompt.js +7 -0
  241. package/packages/pi-agent-core/dist/harness/system-prompt.js.map +1 -1
  242. package/packages/pi-agent-core/package.json +1 -1
  243. package/packages/pi-ai/dist/models.generated.d.ts +48 -206
  244. package/packages/pi-ai/dist/models.generated.d.ts.map +1 -1
  245. package/packages/pi-ai/dist/models.generated.js +67 -220
  246. package/packages/pi-ai/dist/models.generated.js.map +1 -1
  247. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  248. package/packages/pi-ai/dist/providers/anthropic.js +50 -0
  249. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  250. package/packages/pi-ai/dist/providers/openai-responses-shared.d.ts.map +1 -1
  251. package/packages/pi-ai/dist/providers/openai-responses-shared.js +28 -4
  252. package/packages/pi-ai/dist/providers/openai-responses-shared.js.map +1 -1
  253. package/packages/pi-ai/dist/types.d.ts +2 -0
  254. package/packages/pi-ai/dist/types.d.ts.map +1 -1
  255. package/packages/pi-ai/dist/types.js.map +1 -1
  256. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js +29 -1
  257. package/packages/pi-ai/dist/utils/tests/tool-search-shim.test.js.map +1 -1
  258. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts +4 -1
  259. package/packages/pi-ai/dist/utils/tool-search-shim.d.ts.map +1 -1
  260. package/packages/pi-ai/dist/utils/tool-search-shim.js +58 -10
  261. package/packages/pi-ai/dist/utils/tool-search-shim.js.map +1 -1
  262. package/packages/pi-ai/dist/utils/tool-shims.d.ts +1 -1
  263. package/packages/pi-ai/dist/utils/tool-shims.d.ts.map +1 -1
  264. package/packages/pi-ai/dist/utils/tool-shims.js.map +1 -1
  265. package/packages/pi-ai/package.json +1 -1
  266. package/packages/pi-coding-agent/README.md +1 -1
  267. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts +2 -2
  268. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.d.ts.map +1 -1
  269. package/packages/pi-coding-agent/dist/core/extensions/extension-upstream-types.js.map +1 -1
  270. package/packages/pi-coding-agent/dist/core/extensions/loader.js +1 -1
  271. package/packages/pi-coding-agent/dist/core/extensions/loader.js.map +1 -1
  272. package/packages/pi-coding-agent/dist/core/extensions/runner.d.ts.map +1 -1
  273. package/packages/pi-coding-agent/dist/core/extensions/runner.js +8 -2
  274. package/packages/pi-coding-agent/dist/core/extensions/runner.js.map +1 -1
  275. package/packages/pi-coding-agent/dist/core/skills.d.ts +3 -0
  276. package/packages/pi-coding-agent/dist/core/skills.d.ts.map +1 -1
  277. package/packages/pi-coding-agent/dist/core/skills.js +3 -0
  278. package/packages/pi-coding-agent/dist/core/skills.js.map +1 -1
  279. package/packages/pi-coding-agent/dist/core/tools/edit.d.ts.map +1 -1
  280. package/packages/pi-coding-agent/dist/core/tools/edit.js +5 -7
  281. package/packages/pi-coding-agent/dist/core/tools/edit.js.map +1 -1
  282. package/packages/pi-coding-agent/dist/core/tools/read.d.ts +2 -2
  283. package/packages/pi-coding-agent/dist/core/tools/read.d.ts.map +1 -1
  284. package/packages/pi-coding-agent/dist/core/tools/read.js +5 -4
  285. package/packages/pi-coding-agent/dist/core/tools/read.js.map +1 -1
  286. package/packages/pi-coding-agent/dist/core/tools/write.d.ts.map +1 -1
  287. package/packages/pi-coding-agent/dist/core/tools/write.js +0 -1
  288. package/packages/pi-coding-agent/dist/core/tools/write.js.map +1 -1
  289. package/packages/pi-coding-agent/package.json +8 -8
  290. package/packages/pi-tui/package.json +1 -1
  291. package/packages/rpc-client/package.json +2 -2
  292. package/pkg/package.json +1 -1
  293. package/scripts/install/detect-existing.js +17 -3
  294. package/scripts/install/npm-global.js +103 -33
  295. package/scripts/install.js +1 -0
  296. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +36 -11
  297. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +86 -19
  298. package/src/resources/extensions/context7/index.ts +15 -2
  299. package/src/resources/extensions/get-secrets-from-user.ts +17 -16
  300. package/src/resources/extensions/google-cli/index.ts +34 -0
  301. package/src/resources/extensions/google-cli/models.ts +57 -0
  302. package/src/resources/extensions/google-cli/package.json +11 -0
  303. package/src/resources/extensions/google-cli/readiness.ts +15 -0
  304. package/src/resources/extensions/google-cli/stream-adapter.ts +245 -0
  305. package/src/resources/extensions/gsd/auto/loop.ts +96 -1
  306. package/src/resources/extensions/gsd/auto/orchestrator.ts +4 -2
  307. package/src/resources/extensions/gsd/auto/phases.ts +47 -1
  308. package/src/resources/extensions/gsd/auto/run-unit.ts +10 -0
  309. package/src/resources/extensions/gsd/auto/session.ts +3 -0
  310. package/src/resources/extensions/gsd/auto-dispatch.ts +31 -11
  311. package/src/resources/extensions/gsd/auto-post-unit.ts +101 -18
  312. package/src/resources/extensions/gsd/auto-prompts.ts +4 -284
  313. package/src/resources/extensions/gsd/auto-recovery.ts +10 -7
  314. package/src/resources/extensions/gsd/auto-start.ts +307 -56
  315. package/src/resources/extensions/gsd/auto-tool-tracking.ts +3 -1
  316. package/src/resources/extensions/gsd/auto-verification.ts +18 -2
  317. package/src/resources/extensions/gsd/auto-worktree.ts +45 -1
  318. package/src/resources/extensions/gsd/auto.ts +50 -2
  319. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +4 -3
  320. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +9 -4
  321. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +42 -5
  322. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +124 -25
  323. package/src/resources/extensions/gsd/bootstrap/system-context.ts +3 -28
  324. package/src/resources/extensions/gsd/bootstrap/tool-search-shim.ts +4 -4
  325. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +1 -1
  326. package/src/resources/extensions/gsd/closeout-recovery.ts +6 -1
  327. package/src/resources/extensions/gsd/commands/handlers/auto.ts +9 -1
  328. package/src/resources/extensions/gsd/commands-handlers.ts +2 -0
  329. package/src/resources/extensions/gsd/commands-usage.ts +110 -5
  330. package/src/resources/extensions/gsd/config-overlay.ts +19 -16
  331. package/src/resources/extensions/gsd/context-overlay.ts +24 -19
  332. package/src/resources/extensions/gsd/dashboard-overlay.ts +14 -27
  333. package/src/resources/extensions/gsd/doctor-engine-checks.ts +99 -0
  334. package/src/resources/extensions/gsd/doctor-git-checks.ts +72 -5
  335. package/src/resources/extensions/gsd/doctor-providers.ts +55 -27
  336. package/src/resources/extensions/gsd/doctor-types.ts +2 -0
  337. package/src/resources/extensions/gsd/doctor.ts +7 -2
  338. package/src/resources/extensions/gsd/git-conflict-state.ts +25 -1
  339. package/src/resources/extensions/gsd/guided-flow.ts +5 -6
  340. package/src/resources/extensions/gsd/key-manager.ts +57 -14
  341. package/src/resources/extensions/gsd/mcp-filter.ts +64 -17
  342. package/src/resources/extensions/gsd/mcp-project-config.ts +24 -9
  343. package/src/resources/extensions/gsd/migration-auto-check.ts +6 -0
  344. package/src/resources/extensions/gsd/milestone-actions.ts +2 -0
  345. package/src/resources/extensions/gsd/milestone-reopen-events.ts +28 -0
  346. package/src/resources/extensions/gsd/notification-overlay.ts +12 -11
  347. package/src/resources/extensions/gsd/parallel-merge.ts +6 -4
  348. package/src/resources/extensions/gsd/parallel-monitor-overlay.ts +16 -12
  349. package/src/resources/extensions/gsd/post-execution-checks.ts +7 -4
  350. package/src/resources/extensions/gsd/preferences-skills.ts +11 -4
  351. package/src/resources/extensions/gsd/preferences.ts +17 -2
  352. package/src/resources/extensions/gsd/prompt-loader.ts +2 -0
  353. package/src/resources/extensions/gsd/prompts/discuss.md +4 -2
  354. package/src/resources/extensions/gsd/prompts/gate-evaluate.md +1 -1
  355. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +2 -0
  356. package/src/resources/extensions/gsd/prompts/system.md +3 -20
  357. package/src/resources/extensions/gsd/queue-reorder-ui.ts +29 -20
  358. package/src/resources/extensions/gsd/repo-identity.ts +35 -7
  359. package/src/resources/extensions/gsd/repository-registry.ts +3 -1
  360. package/src/resources/extensions/gsd/safety/evidence-collector.ts +13 -6
  361. package/src/resources/extensions/gsd/skill-activation.ts +292 -0
  362. package/src/resources/extensions/gsd/skill-catalog.data.ts +858 -0
  363. package/src/resources/extensions/gsd/skill-catalog.install.ts +205 -0
  364. package/src/resources/extensions/gsd/skill-catalog.ts +16 -1087
  365. package/src/resources/extensions/gsd/skill-discovery.ts +134 -78
  366. package/src/resources/extensions/gsd/skill-scope.ts +63 -0
  367. package/src/resources/extensions/gsd/skill-telemetry.ts +6 -40
  368. package/src/resources/extensions/gsd/skills/gsd-headless/SKILL.md +1 -1
  369. package/src/resources/extensions/gsd/skills.ts +75 -0
  370. package/src/resources/extensions/gsd/state-reconciliation/drift/artifact-db.ts +499 -0
  371. package/src/resources/extensions/gsd/state-reconciliation/index.ts +40 -0
  372. package/src/resources/extensions/gsd/state-reconciliation/registry.ts +8 -0
  373. package/src/resources/extensions/gsd/state-reconciliation/types.ts +30 -0
  374. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +328 -2
  375. package/src/resources/extensions/gsd/tests/auto-orchestrator.test.ts +75 -0
  376. package/src/resources/extensions/gsd/tests/auto-post-unit-artifact-diagnostic.test.ts +28 -2
  377. package/src/resources/extensions/gsd/tests/auto-post-unit-evidence-crossref-4909.test.ts +30 -0
  378. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +41 -0
  379. package/src/resources/extensions/gsd/tests/auto-retry-mcp-churn-fixes.test.ts +24 -0
  380. package/src/resources/extensions/gsd/tests/auto-start-orphan-bootstrap.test.ts +436 -0
  381. package/src/resources/extensions/gsd/tests/auto-worktree-untracked-content.test.ts +53 -0
  382. package/src/resources/extensions/gsd/tests/closeout-recovery.test.ts +15 -0
  383. package/src/resources/extensions/gsd/tests/collect-from-manifest.test.ts +31 -0
  384. package/src/resources/extensions/gsd/tests/commands-context.test.ts +5 -3
  385. package/src/resources/extensions/gsd/tests/commands-dispatcher-workspace-git.test.ts +15 -2
  386. package/src/resources/extensions/gsd/tests/commands-usage.test.ts +97 -0
  387. package/src/resources/extensions/gsd/tests/complete-slice-reopen-handoff.test.ts +40 -3
  388. package/src/resources/extensions/gsd/tests/context-chart.test.ts +9 -0
  389. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +64 -0
  390. package/src/resources/extensions/gsd/tests/dashboard-overlay.test.ts +25 -0
  391. package/src/resources/extensions/gsd/tests/discord-invite-links.test.ts +1 -0
  392. package/src/resources/extensions/gsd/tests/discuss-prompt.test.ts +4 -2
  393. package/src/resources/extensions/gsd/tests/discuss-tool-scoping.test.ts +1 -1
  394. package/src/resources/extensions/gsd/tests/doctor-empty-worktree.test.ts +71 -1
  395. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +105 -0
  396. package/src/resources/extensions/gsd/tests/doctor-scope-db-unavailable.test.ts +101 -1
  397. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +30 -0
  398. package/src/resources/extensions/gsd/tests/guided-discuss-milestone-prompt-rendering.test.ts +6 -0
  399. package/src/resources/extensions/gsd/tests/headless-answers.test.ts +22 -3
  400. package/src/resources/extensions/gsd/tests/integration/parallel-merge.test.ts +43 -0
  401. package/src/resources/extensions/gsd/tests/interactive-tool-idle-exemption.test.ts +8 -0
  402. package/src/resources/extensions/gsd/tests/key-manager.test.ts +23 -4
  403. package/src/resources/extensions/gsd/tests/mcp-filter.test.ts +19 -1
  404. package/src/resources/extensions/gsd/tests/mcp-project-config.test.ts +24 -0
  405. package/src/resources/extensions/gsd/tests/migration-auto-check.test.ts +56 -1
  406. package/src/resources/extensions/gsd/tests/notification-overlay.test.ts +6 -1
  407. package/src/resources/extensions/gsd/tests/orphaned-worktree-audit.test.ts +70 -10
  408. package/src/resources/extensions/gsd/tests/parallel-monitor-overlay.test.ts +7 -1
  409. package/src/resources/extensions/gsd/tests/park-milestone.test.ts +9 -0
  410. package/src/resources/extensions/gsd/tests/post-exec-retry-bypass.test.ts +127 -10
  411. package/src/resources/extensions/gsd/tests/post-execution-checks.test.ts +44 -0
  412. package/src/resources/extensions/gsd/tests/post-unit-retry-on-orchestrator-bridge.test.ts +93 -0
  413. package/src/resources/extensions/gsd/tests/project-relocation-recovery.test.ts +101 -0
  414. package/src/resources/extensions/gsd/tests/queue-reorder-ui.test.ts +46 -0
  415. package/src/resources/extensions/gsd/tests/register-extension-guard.test.ts +116 -11
  416. package/src/resources/extensions/gsd/tests/repo-identity-worktree.test.ts +27 -0
  417. package/src/resources/extensions/gsd/tests/repository-registry.test.ts +30 -1
  418. package/src/resources/extensions/gsd/tests/show-config-command.test.ts +4 -0
  419. package/src/resources/extensions/gsd/tests/skill-discovery.test.ts +111 -0
  420. package/src/resources/extensions/gsd/tests/skill-scope-auto.test.ts +67 -0
  421. package/src/resources/extensions/gsd/tests/skills.test.ts +55 -0
  422. package/src/resources/extensions/gsd/tests/start-auto-detached.test.ts +13 -2
  423. package/src/resources/extensions/gsd/tests/state-reconciliation-drift.test.ts +303 -0
  424. package/src/resources/extensions/gsd/tests/token-tool-gating.test.ts +67 -1
  425. package/src/resources/extensions/gsd/tests/tool-param-optionality.test.ts +24 -1
  426. package/src/resources/extensions/gsd/tests/tui-border-assertions.ts +28 -0
  427. package/src/resources/extensions/gsd/tests/tui-render-kit.test.ts +14 -0
  428. package/src/resources/extensions/gsd/tests/unit-context-manifest.test.ts +18 -0
  429. package/src/resources/extensions/gsd/tests/user-input-boundary.test.ts +26 -0
  430. package/src/resources/extensions/gsd/tests/vision-ask.test.ts +23 -0
  431. package/src/resources/extensions/gsd/tests/visualizer-overlay.test.ts +6 -1
  432. package/src/resources/extensions/gsd/tests/workflow-mcp-auto-prep.test.ts +133 -0
  433. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +82 -0
  434. package/src/resources/extensions/gsd/tests/workspace-git-preflight.test.ts +16 -1
  435. package/src/resources/extensions/gsd/tests/worktree-lifecycle.test.ts +28 -0
  436. package/src/resources/extensions/gsd/tests/worktree-state-projection.test.ts +38 -1
  437. package/src/resources/extensions/gsd/tests/write-gate-planning-unit.test.ts +10 -0
  438. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +45 -1
  439. package/src/resources/extensions/gsd/tools/complete-task.ts +9 -0
  440. package/src/resources/extensions/gsd/tools/exec-tool.ts +42 -10
  441. package/src/resources/extensions/gsd/tools/workflow-tool-executors.ts +82 -5
  442. package/src/resources/extensions/gsd/tui/render-kit.ts +82 -0
  443. package/src/resources/extensions/gsd/unit-context-manifest.ts +37 -26
  444. package/src/resources/extensions/gsd/user-input-boundary.ts +1 -1
  445. package/src/resources/extensions/gsd/vision-ask.ts +28 -0
  446. package/src/resources/extensions/gsd/visualizer-overlay.ts +12 -40
  447. package/src/resources/extensions/gsd/worktree-lifecycle.ts +37 -2
  448. package/src/resources/extensions/gsd/worktree-state-projection.ts +33 -0
  449. package/src/resources/extensions/search-the-web/native-search.ts +60 -8
  450. package/src/resources/extensions/shared/confirm-ui.ts +8 -12
  451. package/src/resources/extensions/shared/dialog-frame.ts +71 -0
  452. package/src/resources/extensions/shared/interview-ui.ts +43 -42
  453. package/src/resources/extensions/shared/next-action-ui.ts +6 -6
  454. package/src/resources/extensions/shared/tests/confirm-ui.test.ts +57 -0
  455. package/src/resources/extensions/shared/tests/interview-ui-border.test.ts +163 -0
  456. package/src/resources/extensions/shared/tests/next-action-ui-hasui.test.ts +55 -0
  457. package/src/resources/extensions/subagent/index.ts +8 -15
  458. package/src/resources/shared/package-manager-detection.ts +39 -0
  459. package/src/resources/skills/agent-browser/SKILL.md +1 -1
  460. package/src/resources/skills/api-design/SKILL.md +1 -1
  461. package/src/resources/skills/code-optimizer/SKILL.md +6 -11
  462. package/src/resources/skills/create-gsd-extension/SKILL.md +1 -1
  463. package/src/resources/skills/create-mcp-server/SKILL.md +1 -1
  464. package/src/resources/skills/create-skill/references/gsd-skill-ecosystem.md +1 -1
  465. package/src/resources/skills/create-skill/workflows/verify-skill.md +2 -10
  466. package/src/resources/skills/debug-like-expert/references/when-to-research.md +1 -5
  467. package/src/resources/skills/decompose-into-slices/SKILL.md +3 -3
  468. package/src/resources/skills/dependency-upgrade/SKILL.md +1 -1
  469. package/src/resources/skills/forensics/SKILL.md +2 -2
  470. package/src/resources/skills/grill-me/SKILL.md +1 -1
  471. package/src/resources/skills/handoff/SKILL.md +1 -1
  472. package/src/resources/skills/make-interfaces-feel-better/SKILL.md +1 -1
  473. package/src/resources/skills/observability/SKILL.md +1 -1
  474. package/src/resources/skills/security-review/SKILL.md +1 -1
  475. package/src/resources/skills/spike-wrap-up/SKILL.md +1 -1
  476. package/src/resources/skills/tdd/SKILL.md +1 -1
  477. package/src/resources/skills/write-docs/SKILL.md +1 -1
  478. package/src/resources/skills/write-milestone-brief/SKILL.md +1 -1
  479. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_buildManifest.js +0 -0
  480. /package/dist/web/standalone/.next/static/{szb-HAt0IoSx3docUZO-E → tH1tnDYt1E0hK9Ien73Z0}/_ssgManifest.js +0 -0
@@ -0,0 +1,28 @@
1
+ import { join } from "node:path";
2
+
3
+ import { gsdRoot } from "./paths.js";
4
+ import { readEvents } from "./workflow-events.js";
5
+
6
+ export function latestExplicitReopenAt(basePath: string, milestoneId: string): string | null {
7
+ const root = gsdRoot(basePath);
8
+ const candidates = [
9
+ join(root, "event-log.jsonl"),
10
+ join(root, `event-log-${milestoneId}.jsonl.archived`),
11
+ ];
12
+
13
+ let latest: string | null = null;
14
+ for (const file of candidates) {
15
+ for (const event of readEvents(file)) {
16
+ const eventMilestoneId = (event.params as { milestoneId?: unknown }).milestoneId;
17
+ if (event.cmd !== "reopen-milestone" || eventMilestoneId !== milestoneId) continue;
18
+ if (!latest || event.ts > latest) latest = event.ts;
19
+ }
20
+ }
21
+ return latest;
22
+ }
23
+
24
+ export function isAfter(value: string | null | undefined, cutoff: string | null): boolean {
25
+ if (!cutoff) return true;
26
+ if (!value) return true;
27
+ return Date.parse(value) > Date.parse(cutoff);
28
+ }
@@ -15,7 +15,7 @@ import {
15
15
  import { formattedShortcutPair } from "./shortcut-defs.js";
16
16
  import {
17
17
  padRightVisible,
18
- renderFrame,
18
+ renderDialogFrame,
19
19
  renderKeyHints,
20
20
  rightAlign,
21
21
  wrapVisibleText,
@@ -200,13 +200,20 @@ export class GSDNotificationOverlay {
200
200
  availableRows,
201
201
  Math.max(1, Math.floor((terminalRows * OVERLAY_MAX_HEIGHT_PERCENT) / 100)),
202
202
  );
203
- const maxVisibleRows = Math.max(5, overlayRows - 2);
203
+ const maxVisibleRows = Math.max(5, overlayRows - 4);
204
204
  const visibleContentRows = Math.min(content.length, maxVisibleRows);
205
205
  const maxScroll = Math.max(0, content.length - visibleContentRows);
206
206
  this.scrollOffset = Math.min(this.scrollOffset, maxScroll);
207
207
  const visibleContent = content.slice(this.scrollOffset, this.scrollOffset + visibleContentRows);
208
-
209
- const lines = renderFrame(this.theme, visibleContent, width);
208
+ const footer = renderKeyHints(
209
+ this.theme,
210
+ ["↑/↓ scroll", "f filter", "c clear", `Esc/${formattedShortcutPair("notifications")} close`],
211
+ Math.max(1, width - 4),
212
+ );
213
+ const lines = renderDialogFrame(this.theme, "Notifications", visibleContent, width, {
214
+ footer,
215
+ scroll: { offset: this.scrollOffset, visibleRows: visibleContentRows, totalRows: content.length },
216
+ });
210
217
 
211
218
  this.cachedWidth = width;
212
219
  this.cachedLines = lines;
@@ -256,8 +263,6 @@ export class GSDNotificationOverlay {
256
263
  const blank = () => row("");
257
264
  const hr = () => row(th.fg("dim", "─".repeat(contentWidth)));
258
265
 
259
- // Header
260
- const title = th.fg("accent", th.bold("Notifications"));
261
266
  const filterLabel = this.filter === "all"
262
267
  ? th.fg("dim", "all")
263
268
  : th.fg(
@@ -269,15 +274,11 @@ export class GSDNotificationOverlay {
269
274
  );
270
275
  const count = `${this.filteredEntries.length} entries`;
271
276
  lines.push(row(rightAlign(
272
- `${title} ${th.fg("dim", "filter:")} ${filterLabel}`,
277
+ `${th.fg("dim", "filter:")} ${filterLabel}`,
273
278
  th.fg("dim", count),
274
279
  contentWidth,
275
280
  )));
276
281
  lines.push(hr());
277
-
278
- // Controls
279
- const closeShortcut = formattedShortcutPair("notifications");
280
- lines.push(row(renderKeyHints(th, ["↑/↓ scroll", "f filter", "c clear", `Esc/${closeShortcut} close`], contentWidth)));
281
282
  lines.push(blank());
282
283
 
283
284
  // Entries
@@ -154,12 +154,13 @@ export async function mergeCompletedMilestone(
154
154
  // to read it from. Only use the worktree path when git actually knows
155
155
  // about it (`getAutoWorktreePath` returns non-null). When the directory
156
156
  // exists on disk but isn't a registered git worktree (e.g. a stale
157
- // session-status marker dir), fall back to the project root and let the
158
- // standalone's mode detection pick branch-mode or skipped using the
159
- // un-registered dir as `worktreeBasePath` would cause `getCurrentBranch`
160
- // to fail with a "Worktree HEAD diverged" error.
157
+ // session-status marker dir), recover through branch mode from the project
158
+ // root. Letting worktree-mode run from the project root can auto-commit
159
+ // overlapping root files to the integration branch before the squash merge,
160
+ // creating a synthetic conflict.
161
161
  const registeredWtPath = getAutoWorktreePath(basePath, milestoneId);
162
162
  const worktreeBasePath = registeredWtPath ?? basePath;
163
+ const isolationModeOverride = registeredWtPath ? undefined : "branch";
163
164
 
164
165
  let result: MergeStandaloneResult;
165
166
  try {
@@ -167,6 +168,7 @@ export async function mergeCompletedMilestone(
167
168
  originalBasePath: basePath,
168
169
  worktreeBasePath,
169
170
  milestoneId,
171
+ isolationModeOverride,
170
172
  // Parallel context never runs with degraded isolation — workers only
171
173
  // exist when isolation succeeded. Pass `false` explicitly so the
172
174
  // standalone's degraded-skip branch is not reached.
@@ -13,6 +13,7 @@ import { formattedShortcutPair } from "./shortcut-defs.js";
13
13
  import { resolveGsdPathContract } from "./paths.js";
14
14
  import {
15
15
  renderBar,
16
+ renderDialogFrame,
16
17
  renderKeyHints,
17
18
  renderProgressBar,
18
19
  safeLine,
@@ -378,19 +379,18 @@ export class ParallelMonitorOverlay {
378
379
  const t = this.theme;
379
380
  const lines: string[] = [];
380
381
  const w = Math.max(1, width);
382
+ const contentWidth = Math.max(1, w - 4);
381
383
 
382
- // Header
383
384
  const totalCost = this.workers.reduce((s, wk) => s + wk.cost, 0);
384
385
  const aliveCount = this.workers.filter((wk) => wk.alive).length;
385
386
  const now = new Date().toLocaleTimeString();
386
387
 
387
- lines.push(t.bold(t.fg("accent", " GSD Parallel Monitor ")));
388
388
  lines.push(
389
389
  t.fg("muted", ` ${now} │ ${aliveCount}/${this.workers.length} alive │ Total: `) +
390
390
  t.bold(`$${totalCost.toFixed(2)}`) +
391
391
  t.fg("muted", " │ 5s refresh"),
392
392
  );
393
- lines.push(renderBar(t, w));
393
+ lines.push(renderBar(t, contentWidth));
394
394
 
395
395
  if (this.workers.length === 0) {
396
396
  lines.push("");
@@ -444,7 +444,7 @@ export class ParallelMonitorOverlay {
444
444
  lines.push(` ${t.fg("muted", "slices")} ${chips.join(" ")}`);
445
445
 
446
446
  // Task progress bar
447
- const barWidth = Math.max(6, Math.min(25, w - 32));
447
+ const barWidth = Math.max(6, Math.min(25, contentWidth - 32));
448
448
  const bar = renderProgressBar(t, wk.doneTasks, wk.totalTasks, barWidth, {
449
449
  filledChar: "█",
450
450
  emptyChar: "░",
@@ -466,7 +466,7 @@ export class ParallelMonitorOverlay {
466
466
 
467
467
  // Event feed
468
468
  lines.push("");
469
- lines.push(renderBar(t, w));
469
+ lines.push(renderBar(t, contentWidth));
470
470
  lines.push(` ${t.bold("Recent Events")}`);
471
471
 
472
472
  if (this.events.length === 0) {
@@ -478,7 +478,6 @@ export class ParallelMonitorOverlay {
478
478
  }
479
479
  }
480
480
 
481
- // Footer
482
481
  lines.push("");
483
482
  const allDone = this.workers.length > 0 && this.workers.every((wk) => !wk.alive);
484
483
  if (allDone) {
@@ -491,17 +490,22 @@ export class ParallelMonitorOverlay {
491
490
  }
492
491
  lines.push(` ${t.bold("Total: $" + this.workers.reduce((s, wk) => s + wk.cost, 0).toFixed(2))}`);
493
492
  }
494
- lines.push(renderKeyHints(t, [`ESC/q/${formattedShortcutPair("parallel")} close`, "↑↓ scroll"], w));
495
493
 
496
494
  // Apply scroll — use terminal rows as height estimate
497
495
  const termHeight = process.stdout.rows || 40;
498
- const maxScroll = Math.max(0, lines.length - termHeight);
496
+ const maxBodyRows = Math.max(1, Math.min(lines.length, termHeight - 12));
497
+ const maxScroll = Math.max(0, lines.length - maxBodyRows);
499
498
  this.scrollOffset = Math.min(Math.max(this.scrollOffset, 0), maxScroll);
500
499
  const visible = lines
501
- .slice(this.scrollOffset, this.scrollOffset + termHeight)
502
- .map((line) => safeLine(line, w));
503
- this.cachedLines = visible;
500
+ .slice(this.scrollOffset, this.scrollOffset + maxBodyRows)
501
+ .map((line) => safeLine(line, contentWidth));
502
+ const footer = renderKeyHints(t, [`ESC/q/${formattedShortcutPair("parallel")} close`, "↑↓ scroll"], contentWidth);
503
+
504
+ this.cachedLines = renderDialogFrame(t, "GSD Parallel Monitor", visible, w, {
505
+ footer,
506
+ scroll: { offset: this.scrollOffset, visibleRows: maxBodyRows, totalRows: lines.length },
507
+ });
504
508
  this.cachedWidth = width;
505
- return visible;
509
+ return this.cachedLines;
506
510
  }
507
511
  }
@@ -318,10 +318,13 @@ export function checkImportResolution(
318
318
  const imports = extractRelativeImports(source);
319
319
 
320
320
  for (const { importPath, lineNum } of imports) {
321
- // React Router generated +types modules may not exist on disk during
322
- // post-exec checks (generated during framework build). Don't block task
323
- // completion on these imports.
324
- if (/^\.{1,2}\/\+types\//.test(importPath)) {
321
+ // Framework-generated type modules may not exist on disk during post-exec
322
+ // checks (typically generated during framework builds/typegen). Don't
323
+ // block task completion on these imports.
324
+ if (
325
+ /^\.{1,2}\/\+types\//.test(importPath) ||
326
+ /^(?:\.{1,2}\/)+(?:[^/]+\/)*\$types(?:$|\/)/.test(importPath)
327
+ ) {
325
328
  continue;
326
329
  }
327
330
 
@@ -23,10 +23,17 @@ import { validatePreferences } from "./preferences-validation.js";
23
23
  export type { GSDSkillRule, SkillDiscoveryMode, SkillResolution, SkillResolutionReport } from "./preferences-types.js";
24
24
 
25
25
  /**
26
- * Known skill directories, in priority order.
27
- * GSD bundled skills live in ~/.gsd/agent/skills/ and win name collisions.
28
- * User-global and project-local ecosystem directories remain available as
29
- * read-only discovery sources, followed by Claude Code compatibility paths.
26
+ * Known skill directories for **preference reference resolution** (bare skill names).
27
+ *
28
+ * Search order (first match wins):
29
+ * 1. ~/.gsd/agent/skills/ (GSD bundled)
30
+ * 2. ~/.agents/skills/ (ecosystem global)
31
+ * 3. .agents/skills/ (project ecosystem)
32
+ * 4. ~/.claude/skills/ and .claude/skills/ (Claude Code compatibility)
33
+ *
34
+ * Note: the ResourceLoader catalog uses PackageManager precedence instead —
35
+ * project `.gsd/skills` and `.agents/skills` can override bundled GSD skills
36
+ * on name collision. See docs/dev/what-is-pi/09-the-customization-stack.md.
30
37
  */
31
38
  export function getSkillSearchDirs(cwd: string): Array<{ dir: string; method: SkillResolution["method"] }> {
32
39
  const dirs: Array<{ dir: string; method: SkillResolution["method"] }> = [
@@ -570,9 +570,14 @@ function mergePreDispatchHooks(
570
570
 
571
571
  // ─── System Prompt Rendering ──────────────────────────────────────────────────
572
572
 
573
- export function renderPreferencesForSystemPrompt(preferences: GSDPreferences, resolutions?: Map<string, SkillResolution>): string {
573
+ export function renderPreferencesForSystemPrompt(
574
+ preferences: GSDPreferences,
575
+ resolutions?: Map<string, SkillResolution>,
576
+ options?: { includeResolvedPaths?: boolean },
577
+ ): string {
574
578
  const validated = validatePreferences(preferences);
575
579
  const lines: string[] = ["## GSD Skill Preferences"];
580
+ const includeResolvedPaths = options?.includeResolvedPaths ?? true;
576
581
 
577
582
  if (validated.errors.length > 0) {
578
583
  lines.push("- Validation: some preference values were ignored because they were invalid.");
@@ -589,7 +594,17 @@ export function renderPreferencesForSystemPrompt(preferences: GSDPreferences, re
589
594
  "- Current user instructions still override these defaults.",
590
595
  );
591
596
 
592
- const fmt = (ref: string) => resolutions ? formatSkillRef(ref, resolutions) : ref;
597
+ const fmt = (ref: string) => {
598
+ if (!resolutions) return ref;
599
+ if (!includeResolvedPaths) {
600
+ const resolution = resolutions.get(ref);
601
+ if (!resolution || resolution.method === "unresolved") {
602
+ return `${ref} (⚠ not found — check skill name or path)`;
603
+ }
604
+ return ref;
605
+ }
606
+ return formatSkillRef(ref, resolutions);
607
+ };
593
608
 
594
609
  if (preferences.always_use_skills && preferences.always_use_skills.length > 0) {
595
610
  lines.push("- Always use these skills when relevant:");
@@ -22,6 +22,7 @@ import { join, dirname } from "node:path";
22
22
  import { fileURLToPath } from "node:url";
23
23
  import { logWarning } from "./workflow-logger.js";
24
24
  import { gsdHome } from "./gsd-home.js";
25
+ import { chooseVisionAskVariant } from "./vision-ask.js";
25
26
 
26
27
  type ExistsFn = (path: string) => boolean;
27
28
 
@@ -184,6 +185,7 @@ export function loadPrompt(name: string, vars: Record<string, string> = {}): str
184
185
  planTemplatePath: join(getTemplatesDir(), "plan.md"),
185
186
  taskPlanTemplatePath: join(getTemplatesDir(), "task-plan.md"),
186
187
  taskSummaryTemplatePath: join(getTemplatesDir(), "task-summary.md"),
188
+ visionAsk: chooseVisionAskVariant(),
187
189
  skillActivation: "If a `GSD Skill Preferences` block is present in system context, use it and the `<available_skills>` catalog in your system prompt to decide which skills to load and follow for this unit, without relaxing required verification or artifact rules.",
188
190
  ...vars,
189
191
  };
@@ -1,8 +1,10 @@
1
1
  {{preamble}}
2
2
 
3
- Ask: "What's the vision?" once, then use the reply as vision input.
3
+ Ask exactly this once: "{{visionAsk}}" Then use the user's reply as vision input.
4
4
 
5
- **Special handling:** If the **user's** message is status, branch state, clarification, or any other non-project-description, treat it as vision input and proceed instead of repeating "What's the vision?" Do **not** treat the system preamble above (e.g. "New milestone M00X.") as vision input — wait for the user.
5
+ The opener is intentionally variable so GSD feels alive across project starts. Keep it natural, easy to answer, and assistant/developer shaped: plain language, light guidance, no corporate wording, no roleplay.
6
+
7
+ **Special handling:** If the **user's** message is status, branch state, clarification, or any other non-project-description, treat it as vision input and proceed instead of repeating the opener. Do **not** treat the system preamble above (e.g. "New milestone M00X.") as vision input — wait for the user.
6
8
 
7
9
  ## Reflection Step
8
10
 
@@ -35,7 +35,7 @@ You are evaluating **quality gates in parallel** for this slice. Each gate is an
35
35
  2. **Wait for all subagents** to complete.
36
36
  3. **Verify each gate wrote its result** by checking that `gsd_save_gate_result` was called for each gate ID.
37
37
  - Call it **directly** — do **not** use `ToolSearch` (it is not available in GSD).
38
- - Inside Claude Code use `mcp__gsd-workflow__gsd_save_gate_result`; otherwise use `gsd_save_gate_result`.
38
+ - Inside Claude Code use the active MCP-scoped workflow name for `gsd_save_gate_result`; otherwise use `gsd_save_gate_result`.
39
39
  - Always pass all required fields (camelCase): `milestoneId`, `sliceId`, `gateId`, `verdict`, `rationale`. Never call with an empty `{}` object.
40
40
  4. **Report the batch outcome** — which gates passed, which flagged concerns, and which were omitted as not applicable.
41
41
 
@@ -4,6 +4,8 @@ Discuss milestone {{milestoneId}} ("{{milestoneTitle}}"). Identify real gray are
4
4
 
5
5
  **Structured questions available: {{structuredQuestionsAvailable}}**
6
6
 
7
+ **Conversation opener:** For the first user-facing question round, if you need a broad starting question, use: "{{visionAsk}}" Pair it with investigation-shaped follow-ups. Keep the tone natural and easy to answer, like an assistant/developer helping the user shape the next piece of work.
8
+
7
9
  {{inlinedTemplates}}
8
10
 
9
11
  ---
@@ -19,9 +19,7 @@ Leave the project ready for the next agent to understand and continue. Artifacts
19
19
 
20
20
  ## Skills
21
21
 
22
- GSD ships with bundled skills. When the task matches, load the relevant skill file with `read` before starting. Use bare skill names; GSD resolves paths.
23
-
24
- {{bundledSkillsTable}}
22
+ GSD ships with bundled skills. Installed skills are listed in `<available_skills>` in your system prompt — load the relevant skill file with `read` using the path shown there before starting matching work. Use bare skill names in preferences; GSD resolves paths.
25
23
 
26
24
  ## Hard Rules
27
25
 
@@ -122,18 +120,7 @@ Templates are in `{{templatesDir}}`.
122
120
 
123
121
  **Browser verification:** Verify frontend work against a running app. Discovery: `browser_find`/`browser_snapshot_refs`. Action: refs/selectors -> `browser_batch`. Verification: `browser_assert`. Diagnostics: `browser_diff` -> console/network logs -> full inspection as last resort. Retry only with a new hypothesis.
124
122
 
125
- ### Anti-patterns never do these
126
-
127
- - Never use `cat` to read a file you might edit; use `read`.
128
- - Never `grep` for a function definition when `lsp` go-to-definition is available.
129
- - Never poll servers with `sleep` loops; use `bg_shell wait_for_ready`.
130
- - Never background with `bash` + `&`; use `bg_shell start`.
131
- - Never use `bg_shell output` for status; use `digest`.
132
- - Never read files one-by-one to understand a subsystem; use `rg` or `scout` first.
133
- - Never guess library APIs; use `get_library_docs`.
134
- - Never ask the user to run/check/set something you can do.
135
- - Never await stale async jobs after editing source; cancel then re-run.
136
- - Never query `.gsd/gsd.db` directly via `sqlite3`, `better-sqlite3`, or `node -e require('better-sqlite3')`; the engine owns a single-writer WAL connection. Use `gsd_milestone_status`, `gsd_journal_query`, or other `gsd_*` tools.
123
+ **Database:** Never query `.gsd/gsd.db` directly via `sqlite3`, `better-sqlite3`, or `node -e require('better-sqlite3')`; the engine owns a single-writer WAL connection. Use `gsd_milestone_status`, `gsd_journal_query`, or other `gsd_*` tools.
137
124
 
138
125
  ### Ask vs infer
139
126
 
@@ -173,8 +160,4 @@ Fix root causes, not symptoms. If applying temporary mitigation, label it and pr
173
160
  - When debugging, stay curious. Problems are puzzles. Say what's interesting about the failure before reaching for fixes.
174
161
  - After completing a task, give a brief summary and 2-4 numbered next-step options; last option is always "Other". Omit the list for strict output formats.
175
162
 
176
- Good narration: "Three existing handlers follow a middleware pattern - using that instead of a custom wrapper."
177
- Good narration: "Tests pass. Running slice-level verification."
178
- Good narration: "I need the task-plan template first, then I'll compare the existing T01 and T02 plans."
179
- Bad narration: "Reading the file now." / "Let me check this." / "I'll look at the tests next."
180
- Bad narration: "Need create plan artifact likely requires template maybe read existing task plans."
163
+ Good narration states a decision or finding: "Three handlers follow a middleware pattern - using that instead of a custom wrapper." Bad narration just announces the next call ("Reading the file now.") or emits compressed planner notes ("Need create plan artifact maybe read existing plans.").
@@ -11,9 +11,9 @@
11
11
  import type { ExtensionContext } from "@gsd/pi-coding-agent";
12
12
  import { type Theme } from "@gsd/pi-coding-agent";
13
13
  import { Key, matchesKey, truncateToWidth, type TUI } from "@gsd/pi-tui";
14
- import { makeUI } from "../shared/tui.js";
15
14
  import { GLYPH } from "../shared/mod.js";
16
15
  import { validateQueueOrder, type DependencyValidation } from "./queue-order.js";
16
+ import { renderDialogFrame, renderKeyHints } from "./tui/render-kit.js";
17
17
 
18
18
  export interface ReorderItem {
19
19
  id: string;
@@ -45,6 +45,7 @@ export async function showQueueReorder(
45
45
  let grabbed = false;
46
46
  let scrollOffset = 0;
47
47
  let cachedLines: string[] | undefined;
48
+ let cachedWidth: number | undefined;
48
49
  let validation: DependencyValidation;
49
50
 
50
51
  // Mutable deps map — tracks removals during this session
@@ -66,6 +67,7 @@ export async function showQueueReorder(
66
67
 
67
68
  function refresh() {
68
69
  cachedLines = undefined;
70
+ cachedWidth = undefined;
69
71
  tui.requestRender();
70
72
  }
71
73
 
@@ -151,17 +153,15 @@ export async function showQueueReorder(
151
153
  }
152
154
 
153
155
  function render(width: number): string[] {
154
- if (cachedLines) return cachedLines;
156
+ if (cachedLines && cachedWidth === width) return cachedLines;
155
157
 
156
- const ui = makeUI(theme, width);
158
+ const contentWidth = Math.max(1, width - 4);
157
159
  const lines: string[] = [];
158
160
  const queueRows: string[] = [];
159
- const push = (...rows: string[][]) => { for (const r of rows) lines.push(...r); };
160
- const add = (s: string) => truncateToWidth(s, width);
161
+ const add = (s: string) => truncateToWidth(s, contentWidth);
161
162
  let cursorQueueRow = 0;
162
163
 
163
- const headerText = grabbed ? " Queue Reorder Moving Item" : " Queue Reorder";
164
- push(ui.bar(), ui.blank(), ui.header(headerText), ui.blank());
164
+ const headerText = grabbed ? "Queue Reorder - Moving Item" : "Queue Reorder";
165
165
 
166
166
  // Completed milestones (dimmed)
167
167
  if (completed.length > 0) {
@@ -170,7 +170,7 @@ export async function showQueueReorder(
170
170
  const label = m.title && m.title !== m.id ? `${m.id} ${m.title}` : m.id;
171
171
  lines.push(add(` ${theme.fg("dim", `${GLYPH.statusDone} ${label}`)}`));
172
172
  }
173
- push(ui.blank());
173
+ lines.push("");
174
174
  }
175
175
 
176
176
  // Pending milestones
@@ -223,7 +223,7 @@ export async function showQueueReorder(
223
223
  // Removed deps feedback
224
224
  const trailingLines: string[] = [];
225
225
  if (removedDeps.length > 0) {
226
- trailingLines.push(...ui.blank());
226
+ trailingLines.push("");
227
227
  for (const r of removedDeps) {
228
228
  trailingLines.push(add(` ${theme.fg("success", `${GLYPH.statusDone} Removed: ${r.milestone} depends_on ${r.dep}`)}`));
229
229
  }
@@ -232,12 +232,10 @@ export async function showQueueReorder(
232
232
  // Circular warning
233
233
  const circ = validation.violations.find(v => v.type === 'circular');
234
234
  if (circ) {
235
- trailingLines.push(...ui.blank());
235
+ trailingLines.push("");
236
236
  trailingLines.push(add(` ${theme.fg("error", `${GLYPH.statusWarning} ${circ.message}`)}`));
237
237
  }
238
238
 
239
- trailingLines.push(...ui.blank());
240
-
241
239
  // Hints — context-sensitive based on grab state
242
240
  const hints: string[] = [];
243
241
  if (grabbed) {
@@ -256,10 +254,9 @@ export async function showQueueReorder(
256
254
  }
257
255
  hints.push("esc");
258
256
 
259
- trailingLines.push(...ui.hints(hints), ...ui.bar());
260
-
261
257
  const maxOverlayRows = Math.max(10, process.stdout.rows ? Math.floor(process.stdout.rows * 0.8) : 24);
262
- const availableQueueRows = Math.max(1, maxOverlayRows - lines.length - trailingLines.length);
258
+ const frameRows = 4;
259
+ const availableQueueRows = Math.max(1, maxOverlayRows - frameRows - lines.length - trailingLines.length);
263
260
  const maxScroll = Math.max(0, queueRows.length - availableQueueRows);
264
261
  if (cursorQueueRow < scrollOffset) {
265
262
  scrollOffset = cursorQueueRow;
@@ -268,13 +265,25 @@ export async function showQueueReorder(
268
265
  }
269
266
  scrollOffset = Math.min(Math.max(scrollOffset, 0), maxScroll);
270
267
 
271
- lines.push(...queueRows.slice(scrollOffset, scrollOffset + availableQueueRows), ...trailingLines);
272
-
273
- cachedLines = lines;
274
- return lines;
268
+ const queueStartRow = lines.length;
269
+ const visibleQueueRows = queueRows.slice(scrollOffset, scrollOffset + availableQueueRows);
270
+ lines.push(...visibleQueueRows, ...trailingLines);
271
+
272
+ cachedLines = renderDialogFrame(theme, headerText, lines, width, {
273
+ footer: renderKeyHints(theme, hints, contentWidth),
274
+ scroll: {
275
+ offset: scrollOffset,
276
+ visibleRows: availableQueueRows,
277
+ totalRows: queueRows.length,
278
+ trackOffset: queueStartRow,
279
+ trackRows: visibleQueueRows.length,
280
+ },
281
+ });
282
+ cachedWidth = width;
283
+ return cachedLines;
275
284
  }
276
285
 
277
- return { render, invalidate: () => { cachedLines = undefined; }, handleInput };
286
+ return { render, invalidate: () => { cachedLines = undefined; cachedWidth = undefined; }, handleInput };
278
287
  }, {
279
288
  overlay: true,
280
289
  overlayOptions: { width: "70%", minWidth: 50, maxHeight: "80%", anchor: "center" },
@@ -16,6 +16,7 @@ import {
16
16
  resolveExternalStateProjectGsdFromWorktreePath,
17
17
  resolveExternalStateProjectIdentityFromWorktreePath,
18
18
  } from "./worktree-root.js";
19
+ import { logWarning } from "./workflow-logger.js";
19
20
 
20
21
 
21
22
  // ─── Repo Metadata ───────────────────────────────────────────────────────────
@@ -188,10 +189,12 @@ function isProjectGsd(gsdPath: string): boolean {
188
189
  // ─── Repo Identity ──────────────────────────────────────────────────────────
189
190
 
190
191
  /**
191
- * Get the git remote URL for "origin", or "" if no remote is configured.
192
+ * Get the git remote URL for "origin", or:
193
+ * - "" when git cleanly reports no remote
194
+ * - null when git command failed (transient/unknown)
192
195
  * Uses `git config` rather than `git remote get-url` for broader compat.
193
196
  */
194
- function getRemoteUrl(basePath: string): string {
197
+ function getRemoteUrl(basePath: string): string | null {
195
198
  try {
196
199
  return execFileSync("git", ["config", "--get", "remote.origin.url"], {
197
200
  cwd: basePath,
@@ -199,8 +202,24 @@ function getRemoteUrl(basePath: string): string {
199
202
  stdio: ["ignore", "pipe", "ignore"],
200
203
  timeout: 5_000,
201
204
  }).trim();
202
- } catch {
203
- return "";
205
+ } catch (error) {
206
+ const status = typeof error === "object" && error !== null && "status" in error
207
+ ? (error as { status?: number }).status
208
+ : undefined;
209
+ if (status === 1) {
210
+ try {
211
+ if (existsSync(join(resolveGitCommonDir(basePath), "config"))) return "";
212
+ } catch {
213
+ // Fall through to report unknown git/config failures.
214
+ }
215
+ }
216
+
217
+ // Keep transient git failures distinct from "no remote configured".
218
+ logWarning("state", "repo-identity: failed to resolve remote.origin.url", {
219
+ basePath,
220
+ error: String(error),
221
+ });
222
+ return null;
204
223
  }
205
224
  }
206
225
 
@@ -300,6 +319,15 @@ export function repoIdentity(basePath: string): string {
300
319
  // This makes moves transparent for repos with remotes (#2750).
301
320
  return createHash("sha256").update(remoteUrl).digest("hex").slice(0, 12);
302
321
  }
322
+ if (remoteUrl === null) {
323
+ // Unknown remote status (transient git failure): prefer persisted identity.
324
+ const markerRoot = resolveGitRoot(basePath);
325
+ const markerId = readGsdIdMarker(markerRoot);
326
+ if (markerId) {
327
+ const markerPath = join(process.env.GSD_STATE_DIR || gsdHome(), "projects", markerId);
328
+ if (hasProjectState(markerPath) || readRepoMeta(markerPath)) return markerId;
329
+ }
330
+ }
303
331
  // Local-only repo: include git root since there's no remote to anchor identity.
304
332
  const root = resolveGitRoot(basePath);
305
333
  const input = `\n${root}`;
@@ -315,8 +343,7 @@ export function repoIdentity(basePath: string): string {
315
343
  * otherwise `~/.gsd/projects/<hash>`.
316
344
  */
317
345
  export function externalGsdRoot(basePath: string): string {
318
- const base = process.env.GSD_STATE_DIR || gsdHome();
319
- return join(base, "projects", repoIdentity(basePath));
346
+ return resolveExternalPathWithRecovery(basePath).path;
320
347
  }
321
348
 
322
349
  /**
@@ -495,6 +522,7 @@ function resolveExternalPathWithRecovery(projectPath: string): { path: string; i
495
522
  }
496
523
  // Clean up old directory after successful migration.
497
524
  try { rmSync(markerPath, { recursive: true, force: true }); } catch { /* non-fatal */ }
525
+ writeGsdIdMarker(projectPath, computedId);
498
526
  } catch {
499
527
  // If migration fails, just point at the old directory.
500
528
  return { path: markerPath, identity: markerId };
@@ -596,7 +624,7 @@ function ensureGsdSymlinkCore(projectPath: string): { path: string; identity: st
596
624
  // Write repo metadata once so cleanup commands can identify this directory later.
597
625
  // Skip refresh for external-state worktrees — parent store already has metadata.
598
626
  if (!(isGsdWorktreePath(projectPath) && resolveExternalStateProjectGsdFromWorktreePath(projectPath))) {
599
- writeRepoMeta(externalPath, getRemoteUrl(projectPath), resolveGitRoot(projectPath));
627
+ writeRepoMeta(externalPath, getRemoteUrl(projectPath) ?? "", resolveGitRoot(projectPath));
600
628
  }
601
629
 
602
630
  const replaceWithSymlink = (): { path: string; identity: string } => {
@@ -77,7 +77,9 @@ export function createRepositoryRegistry(
77
77
  workspacePrefs?: WorkspacePreferences,
78
78
  ): RepositoryRegistry {
79
79
  const contract = resolveGsdPathContract(basePath);
80
- const projectRoot = resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.projectRoot;
80
+ const projectRoot = contract.isWorktree
81
+ ? resolveGitWorkingTreeRoot(contract.workRoot) ?? contract.projectRoot
82
+ : contract.projectRoot;
81
83
  const mode = workspacePrefs?.mode ?? "project";
82
84
  const repoMap = new Map<string, RegisteredRepository>();
83
85
 
@@ -51,15 +51,15 @@ export interface FileEditEvidence {
51
51
  export type EvidenceEntry = BashEvidence | FileWriteEvidence | FileEditEvidence;
52
52
 
53
53
  const EXECUTION_TOOL_NAMES = new Set([
54
- "bash",
55
- "Bash",
56
- "PowerShell",
57
54
  "async_bash",
55
+ "bash",
56
+ "exec_command",
57
+ "functions.exec_command",
58
58
  "gsd_exec",
59
59
  "gsd_exec_search",
60
- "mcp__gsd-workflow__gsd_exec",
61
- "mcp__gsd-workflow__gsd_exec_search",
60
+ "powershell",
62
61
  ]);
62
+ const MCP_EXECUTION_TOOL_RE = /^mcp__.+__gsd_exec(?:_search)?$/;
63
63
 
64
64
  // ─── Module State ───────────────────────────────────────────────────────────
65
65
 
@@ -89,6 +89,13 @@ export function getFilePaths(): string[] {
89
89
  .map(e => e.path);
90
90
  }
91
91
 
92
+ /** True when a tool name represents a shell/command execution surface. */
93
+ export function isExecutionToolName(name: unknown): boolean {
94
+ if (typeof name !== "string") return false;
95
+ const normalized = name.trim().toLowerCase();
96
+ return EXECUTION_TOOL_NAMES.has(normalized) || MCP_EXECUTION_TOOL_RE.test(normalized);
97
+ }
98
+
92
99
  // ─── Persistence (Bug #4385 — evidence must survive session restarts) ────────
93
100
 
94
101
  /**
@@ -199,7 +206,7 @@ export function clearEvidenceFromDisk(
199
206
  * Exit codes and output are filled in by recordToolResult after execution.
200
207
  */
201
208
  export function recordToolCall(toolCallId: string, toolName: string, input: Record<string, unknown>): void {
202
- if (EXECUTION_TOOL_NAMES.has(toolName)) {
209
+ if (isExecutionToolName(toolName)) {
203
210
  unitEvidence.push({
204
211
  kind: "bash",
205
212
  toolCallId,