@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
@@ -5,11 +5,20 @@
5
5
  import { createRequire } from 'module'
6
6
  import { dirname, join } from 'path'
7
7
  import { fileURLToPath } from 'url'
8
+ import { detectPackageManager } from './npm-global.js'
8
9
 
9
10
  const require = createRequire(import.meta.url)
10
11
  const { GSD_PI_BRAND } = require(join(dirname(fileURLToPath(import.meta.url)), '..', 'lib', 'logo.cjs'))
11
12
 
12
13
  export function parseInstalledVersion(npmListJson) {
14
+ if (Array.isArray(npmListJson)) {
15
+ for (const entry of npmListJson) {
16
+ const found = parseInstalledVersion(entry)
17
+ if (found) return found
18
+ }
19
+ return null
20
+ }
21
+
13
22
  if (!npmListJson || typeof npmListJson !== 'object') return null
14
23
 
15
24
  const direct = npmListJson.dependencies?.['@opengsd/gsd-pi']?.version
@@ -30,6 +39,10 @@ export function parseInstalledVersion(npmListJson) {
30
39
  return walk(npmListJson)
31
40
  }
32
41
 
42
+ function getPackageManagerBin(packageManager) {
43
+ return process.platform === 'win32' ? `${packageManager}.cmd` : packageManager
44
+ }
45
+
33
46
  /**
34
47
  * Decide install action for non-interactive or pre-prompt routing.
35
48
  */
@@ -39,11 +52,12 @@ export function compareActions({ installed, yesMode }) {
39
52
  return 'prompt'
40
53
  }
41
54
 
42
- export async function detectInstalledVersion() {
55
+ export async function detectInstalledVersion(options = {}) {
43
56
  const { execFileSync } = await import('child_process')
44
- const npm = process.platform === 'win32' ? 'npm.cmd' : 'npm'
57
+ const packageManager = options.packageManager ?? detectPackageManager()
58
+ const bin = getPackageManagerBin(packageManager)
45
59
  try {
46
- const raw = execFileSync(npm, ['list', '-g', '@opengsd/gsd-pi', '--json'], {
60
+ const raw = execFileSync(bin, ['list', '-g', '@opengsd/gsd-pi', '--json'], {
47
61
  encoding: 'utf-8',
48
62
  stdio: ['ignore', 'pipe', 'pipe'],
49
63
  timeout: 30_000,
@@ -1,14 +1,61 @@
1
1
  import { execFileSync, spawn } from 'child_process'
2
- import { join } from 'path'
2
+ import { homedir } from 'os'
3
+ import { join, resolve as resolvePath, sep } from 'path'
3
4
 
4
- function getNpm() {
5
- return process.platform === 'win32' ? 'npm.cmd' : 'npm'
5
+ const PACKAGE_MANAGERS = new Set(['npm', 'pnpm'])
6
+
7
+ function normalizePackageManager(value) {
8
+ return PACKAGE_MANAGERS.has(value) ? value : 'npm'
9
+ }
10
+
11
+ function hasPnpmPath(value = '') {
12
+ const normalized = value.replace(/\\/g, '/').toLowerCase()
13
+ return (
14
+ normalized.includes('/.pnpm/') ||
15
+ normalized.endsWith('/pnpm') ||
16
+ normalized.endsWith('/pnpm.cjs') ||
17
+ normalized.endsWith('/pnpm.js')
18
+ )
19
+ }
20
+
21
+ function pathStartsWith(pathValue = '', dir) {
22
+ if (!pathValue) return false
23
+ const resolvedPath = resolvePath(pathValue)
24
+ const resolvedDir = resolvePath(dir)
25
+ return resolvedPath === resolvedDir || resolvedPath.startsWith(resolvedDir + sep)
26
+ }
27
+
28
+ function hasPnpmBinPath(env, argv1) {
29
+ const pnpmBinDirs = []
30
+ if (env.PNPM_HOME) pnpmBinDirs.push(env.PNPM_HOME)
31
+ pnpmBinDirs.push(join(homedir(), 'Library', 'pnpm'))
32
+ pnpmBinDirs.push(join(homedir(), '.local', 'share', 'pnpm'))
33
+
34
+ return pnpmBinDirs.some((dir) => pathStartsWith(argv1, dir) || pathStartsWith(env.npm_execpath, dir))
35
+ }
36
+
37
+ export function detectPackageManager(env = process.env, argv1 = process.argv[1]) {
38
+ const userAgent = env.npm_config_user_agent || ''
39
+ if (userAgent.startsWith('pnpm/')) return 'pnpm'
40
+ // Installer runs under npm during npm install; keep that context authoritative.
41
+ if (userAgent.startsWith('npm/')) return 'npm'
42
+
43
+ if (hasPnpmPath(env.npm_execpath || '')) return 'pnpm'
44
+ if (hasPnpmPath(argv1 || '')) return 'pnpm'
45
+ if (hasPnpmBinPath(env, argv1)) return 'pnpm'
46
+
47
+ return 'npm'
48
+ }
49
+
50
+ function getPackageManagerBin(packageManager) {
51
+ const bin = normalizePackageManager(packageManager)
52
+ return process.platform === 'win32' ? `${bin}.cmd` : bin
6
53
  }
7
54
 
8
- const NPM_OUTPUT_LIMIT = 64 * 1024
55
+ const PM_OUTPUT_LIMIT = 64 * 1024
9
56
 
10
- function runNpm(args) {
11
- return execFileSync(getNpm(), args, {
57
+ function runPackageManager(packageManager, args) {
58
+ return execFileSync(getPackageManagerBin(packageManager), args, {
12
59
  encoding: 'utf-8',
13
60
  stdio: ['ignore', 'pipe', 'pipe'],
14
61
  timeout: 120_000,
@@ -16,30 +63,30 @@ function runNpm(args) {
16
63
  }).trim()
17
64
  }
18
65
 
19
- function formatNpmFailure(result) {
66
+ function formatPackageManagerFailure(packageManager, result) {
20
67
  const output = `${result.stderr}\n${result.stdout}`.trim()
21
68
  const meaningful = output
22
69
  .split('\n')
23
- .filter((line) => !line.includes('npm warn') && !line.includes('npm WARN') && line.trim())
70
+ .filter((line) => line.trim() && !/^(?:npm\s+warn|warn)\b/i.test(line.trim()))
24
71
  .slice(-3)
25
72
  .join('; ')
26
- return meaningful || result.error?.message || 'npm install failed'
73
+ return meaningful || result.error?.message || `${packageManager} install failed`
27
74
  }
28
75
 
29
76
  function appendLimited(value, chunk) {
30
- if (value.length >= NPM_OUTPUT_LIMIT) return value
31
- return value + chunk.slice(0, NPM_OUTPUT_LIMIT - value.length)
77
+ if (value.length >= PM_OUTPUT_LIMIT) return value
78
+ return value + chunk.slice(0, PM_OUTPUT_LIMIT - value.length)
32
79
  }
33
80
 
34
- function runNpmAsync(args, {
81
+ function runPackageManagerAsync(packageManager, args, {
35
82
  captureStdout = false,
36
83
  cwd,
37
84
  timeout = 300_000,
38
85
  } = {}) {
39
- const npm = getNpm()
86
+ const bin = getPackageManagerBin(packageManager)
40
87
 
41
88
  return new Promise((resolve) => {
42
- const child = spawn(npm, args, {
89
+ const child = spawn(bin, args, {
43
90
  cwd,
44
91
  shell: process.platform === 'win32',
45
92
  stdio: ['ignore', captureStdout ? 'pipe' : 'ignore', 'pipe'],
@@ -85,7 +132,7 @@ function runNpmAsync(args, {
85
132
  ok: false,
86
133
  stdout,
87
134
  stderr,
88
- error: new Error(`npm ${args.join(' ')} timed out after ${timeout}ms`),
135
+ error: new Error(`${packageManager} ${args.join(' ')} timed out after ${timeout}ms`),
89
136
  })
90
137
  return
91
138
  }
@@ -100,20 +147,35 @@ function runNpmAsync(args, {
100
147
  ok: false,
101
148
  stdout,
102
149
  stderr,
103
- error: new Error(`npm ${args.join(' ')} failed with ${reason}`),
150
+ error: new Error(`${packageManager} ${args.join(' ')} failed with ${reason}`),
104
151
  })
105
152
  })
106
153
  })
107
154
  }
108
155
 
109
- export function getGlobalPaths() {
110
- const prefix = runNpm(['prefix', '-g'])
111
- const root = runNpm(['root', '-g'])
156
+ export function getGlobalPaths(options = {}) {
157
+ const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
158
+
159
+ if (packageManager === 'pnpm') {
160
+ const binDir = runPackageManager(packageManager, ['bin', '-g'])
161
+ const root = runPackageManager(packageManager, ['root', '-g'])
162
+ return {
163
+ prefix: binDir,
164
+ root,
165
+ binDir,
166
+ packageRoot: join(root, '@opengsd', 'gsd-pi'),
167
+ packageManager,
168
+ }
169
+ }
170
+
171
+ const prefix = runPackageManager(packageManager, ['prefix', '-g'])
172
+ const root = runPackageManager(packageManager, ['root', '-g'])
112
173
  return {
113
174
  prefix,
114
175
  root,
115
176
  binDir: process.platform === 'win32' ? prefix : join(prefix, 'bin'),
116
177
  packageRoot: join(root, '@opengsd', 'gsd-pi'),
178
+ packageManager,
117
179
  }
118
180
  }
119
181
 
@@ -121,33 +183,41 @@ export function getLocalPackageRoot(cwd = process.cwd()) {
121
183
  return join(cwd, 'node_modules', '@opengsd', 'gsd-pi')
122
184
  }
123
185
 
124
- export async function installGlobalPackage(version) {
125
- const result = await runNpmAsync([
126
- 'install',
127
- '-g',
128
- '--ignore-scripts',
129
- `@opengsd/gsd-pi@${version}`,
130
- ])
186
+ export async function installGlobalPackage(version, options = {}) {
187
+ const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
188
+ const packageSpec = `@opengsd/gsd-pi@${version}`
189
+ const installArgs = packageManager === 'pnpm'
190
+ ? ['add', '-g', '--ignore-scripts', packageSpec]
191
+ : ['install', '-g', '--ignore-scripts', packageSpec]
192
+
193
+ const result = await runPackageManagerAsync(packageManager, installArgs)
131
194
  if (!result.ok) {
132
- throw new Error(formatNpmFailure(result))
195
+ throw new Error(formatPackageManagerFailure(packageManager, result))
133
196
  }
134
- const rootResult = await runNpmAsync(['root', '-g'], {
197
+ const rootResult = await runPackageManagerAsync(packageManager, ['root', '-g'], {
135
198
  captureStdout: true,
136
199
  timeout: 120_000,
137
200
  })
138
201
  if (!rootResult.ok) {
139
- throw new Error(formatNpmFailure(rootResult))
202
+ throw new Error(formatPackageManagerFailure(packageManager, rootResult))
140
203
  }
141
204
  return join(rootResult.stdout.trim(), '@opengsd', 'gsd-pi')
142
205
  }
143
206
 
144
- export async function installLocalPackage(version, cwd = process.cwd()) {
145
- const result = await runNpmAsync(
146
- ['install', '--ignore-scripts', `@opengsd/gsd-pi@${version}`],
207
+ export async function installLocalPackage(version, cwd = process.cwd(), options = {}) {
208
+ const packageManager = normalizePackageManager(options.packageManager ?? detectPackageManager())
209
+ const packageSpec = `@opengsd/gsd-pi@${version}`
210
+ const installArgs = packageManager === 'pnpm'
211
+ ? ['add', '--ignore-scripts', packageSpec]
212
+ : ['install', '--ignore-scripts', packageSpec]
213
+
214
+ const result = await runPackageManagerAsync(
215
+ packageManager,
216
+ installArgs,
147
217
  { cwd },
148
218
  )
149
219
  if (!result.ok) {
150
- throw new Error(formatNpmFailure(result))
220
+ throw new Error(formatPackageManagerFailure(packageManager, result))
151
221
  }
152
222
  return getLocalPackageRoot(cwd)
153
223
  }
@@ -71,6 +71,7 @@ if (HAS_HELP) {
71
71
 
72
72
  ${colors.yellow}Usage:${colors.reset}
73
73
  npx @opengsd/gsd-pi@latest Install GSD-Pi globally (recommended)
74
+ pnpm dlx @opengsd/gsd-pi@latest Install GSD-Pi globally with pnpm
74
75
  npx @opengsd/gsd-pi@latest --local Install to current project (advanced)
75
76
 
76
77
  ${colors.yellow}Options:${colors.reset}
@@ -29,7 +29,7 @@ import { dirname, join } from "node:path";
29
29
  import { PartialMessageBuilder, ZERO_USAGE, mapUsage } from "./partial-builder.js";
30
30
  import { buildWorkflowMcpServers, resolveWorkflowMcpProjectRoot } from "../gsd/workflow-mcp.js";
31
31
  import { loadProjectGSDPreferences } from "../gsd/preferences.js";
32
- import { discoverMcpServerNames, computeMcpDisallowedTools } from "../gsd/mcp-filter.js";
32
+ import { discoverMcpServerNames, discoverWorkflowMcpServerName, computeMcpDisallowedTools } from "../gsd/mcp-filter.js";
33
33
  import { showInterviewRound, type Question, type RoundResult } from "../shared/tui.js";
34
34
  import type {
35
35
  SDKAssistantMessage,
@@ -59,6 +59,10 @@ type ToolCallWithExternalResult = ToolCall & {
59
59
  externalResult?: ExternalToolResultPayload;
60
60
  };
61
61
 
62
+ interface PromptToolContextOptions {
63
+ workflowMcpServerName?: string | null;
64
+ }
65
+
62
66
  /** `SimpleStreamOptions` extended with an optional extension UI context for elicitation dialogs. */
63
67
  interface ClaudeCodeStreamOptions extends SimpleStreamOptions {
64
68
  extensionUIContext?: ExtensionUIContext;
@@ -331,7 +335,7 @@ function extractMessageText(msg: { role: string; content: unknown }): string {
331
335
  * user turns in its own output. XML tags read as document structure and
332
336
  * don't get mirrored in free text.
333
337
  */
334
- export function buildPromptFromContext(context: Context): string {
338
+ export function buildPromptFromContext(context: Context, toolContext: PromptToolContextOptions = {}): string {
335
339
  const hasContent = Boolean(context.systemPrompt) || context.messages.some((m) => extractMessageText(m));
336
340
  if (!hasContent) return "";
337
341
 
@@ -339,6 +343,14 @@ export function buildPromptFromContext(context: Context): string {
339
343
  "Respond only to the final user message below. " +
340
344
  "Do not emit <user_message>, <assistant_message>, or <prior_system_context> tags in your response.",
341
345
  ];
346
+ const workflowToolLine = toolContext.workflowMcpServerName
347
+ ? "- GSD workflow tools (gsd_exec, gsd_slice_complete, gsd_task_complete, gsd_plan_slice, gsd_save_gate_result, etc.) " +
348
+ `are MCP tools — call them as mcp__${toolContext.workflowMcpServerName}__<tool_name> ` +
349
+ `(e.g. mcp__${toolContext.workflowMcpServerName}__gsd_exec, mcp__${toolContext.workflowMcpServerName}__gsd_save_gate_result)\n`
350
+ : "- GSD workflow MCP tools are unavailable in this Claude Code run.\n";
351
+ const toolSearchLine = toolContext.workflowMcpServerName
352
+ ? "- ToolSearch is NOT available — never use it to discover tools; invoke the MCP tool directly\n"
353
+ : "- ToolSearch is NOT available — never use it to discover tools\n";
342
354
 
343
355
  // The prior system context lists pi-native tool names (lowercase: bash, read, gsd_exec, etc.)
344
356
  // but this process runs inside Claude Code where tool names differ. Inject a remapping note
@@ -349,10 +361,8 @@ export function buildPromptFromContext(context: Context): string {
349
361
  "You are running inside Claude Code. Use these exact tool names — do not use lowercase or pi-native names:\n" +
350
362
  "- Shell commands: 'Bash' (not 'bash')\n" +
351
363
  "- File operations: 'Read', 'Write', 'Edit', 'Glob', 'Grep' (PascalCase, not lowercase)\n" +
352
- "- GSD workflow tools (gsd_exec, gsd_slice_complete, gsd_task_complete, gsd_plan_slice, gsd_save_gate_result, etc.) " +
353
- "are MCP tools — call them as mcp__gsd-workflow__<tool_name> " +
354
- "(e.g. mcp__gsd-workflow__gsd_exec, mcp__gsd-workflow__gsd_save_gate_result)\n" +
355
- "- ToolSearch is NOT available — never use it to discover tools; invoke the MCP tool directly\n" +
364
+ workflowToolLine +
365
+ toolSearchLine +
356
366
  "</tool_context>",
357
367
  );
358
368
 
@@ -1441,6 +1451,16 @@ function mapThinkingLevelToAnthropicEffort(level: ThinkingLevel | undefined, mod
1441
1451
  }
1442
1452
  }
1443
1453
 
1454
+ function workflowMcpServerNameFromAllowedTools(allowedTools: unknown): string | undefined {
1455
+ if (!Array.isArray(allowedTools)) return undefined;
1456
+ for (const toolName of allowedTools) {
1457
+ if (typeof toolName !== "string") continue;
1458
+ const match = /^mcp__(.+)__\*$/.exec(toolName);
1459
+ if (match?.[1]) return match[1];
1460
+ }
1461
+ return undefined;
1462
+ }
1463
+
1444
1464
  /**
1445
1465
  * Build the options object passed to the Claude Agent SDK's `query()` call.
1446
1466
  *
@@ -1468,16 +1488,19 @@ export function buildSdkOptions(
1468
1488
 
1469
1489
  const preferences = loadProjectGSDPreferences(projectRoot);
1470
1490
  const mcpConfig = preferences?.preferences.claude_code_mcp;
1471
- const workflowServerName = mcpServers ? Object.keys(mcpServers)[0] : undefined;
1472
1491
 
1473
1492
  // Always discover project MCPs — needed for both duplicate detection and filtering.
1474
1493
  const discovered = discoverMcpServerNames(projectRoot);
1494
+ const injectedWorkflowServerName = mcpServers ? Object.keys(mcpServers)[0] : undefined;
1495
+ const projectWorkflowServerName = discoverWorkflowMcpServerName(projectRoot);
1496
+ const workflowServerName = projectWorkflowServerName ?? injectedWorkflowServerName;
1475
1497
 
1476
1498
  // If the workflow MCP is already declared in the project's .mcp.json or
1477
1499
  // .claude/settings.json, do not inject it again via mcpServers. Passing the
1478
1500
  // same server name from two sources causes a duplicate registration conflict
1479
1501
  // that prevents the MCP server from loading (tools become unavailable).
1480
- const workflowAlreadyInProject = workflowServerName !== undefined && discovered.includes(workflowServerName);
1502
+ const workflowAlreadyInProject = projectWorkflowServerName !== undefined
1503
+ || (injectedWorkflowServerName !== undefined && discovered.includes(injectedWorkflowServerName));
1481
1504
  let filteredMcpServers = workflowAlreadyInProject ? undefined : mcpServers;
1482
1505
  let extraDisallowedTools: string[] = [];
1483
1506
  let workflowExplicitlyBlocked = false;
@@ -1847,8 +1870,6 @@ async function pumpSdkMessages(
1847
1870
  options.signal.addEventListener("abort", () => controller.abort(), { once: true });
1848
1871
  }
1849
1872
 
1850
- const prompt = buildPromptFromContext(context);
1851
- const queryPrompt = buildSdkQueryPrompt(context, prompt);
1852
1873
  const permissionMode = await resolveClaudePermissionMode();
1853
1874
  const uiContext = (options as ClaudeCodeStreamOptions | undefined)?.extensionUIContext;
1854
1875
  const onExternalToolCall = (options as ClaudeCodeStreamOptions | undefined)?.onExternalToolCall;
@@ -1862,7 +1883,7 @@ async function pumpSdkMessages(
1862
1883
  ({ behavior: "allow", toolUseID: opts.toolUseID }));
1863
1884
  const sdkOpts = buildSdkOptions(
1864
1885
  modelId,
1865
- prompt,
1886
+ "",
1866
1887
  { permissionMode },
1867
1888
  {
1868
1889
  cwd,
@@ -1875,6 +1896,10 @@ async function pumpSdkMessages(
1875
1896
  : {}),
1876
1897
  },
1877
1898
  );
1899
+ const prompt = buildPromptFromContext(context, {
1900
+ workflowMcpServerName: workflowMcpServerNameFromAllowedTools(sdkOpts.allowedTools),
1901
+ });
1902
+ const queryPrompt = buildSdkQueryPrompt(context, prompt);
1878
1903
 
1879
1904
  const queryResult = sdk.query({
1880
1905
  prompt: queryPrompt,
@@ -407,6 +407,30 @@ describe("stream-adapter — no transcript fabrication (#4102)", () => {
407
407
  const prompt = buildPromptFromContext(context);
408
408
  assert.equal(prompt, "", "empty context must not emit a bare directive");
409
409
  });
410
+
411
+ test("buildPromptFromContext uses the active workflow MCP server name", () => {
412
+ const context: Context = {
413
+ messages: [{ role: "user", content: "Check status" } as Message],
414
+ };
415
+
416
+ const prompt = buildPromptFromContext(context, { workflowMcpServerName: "custom-workflow" });
417
+
418
+ assert.ok(prompt.includes("mcp__custom-workflow__<tool_name>"));
419
+ assert.ok(prompt.includes("mcp__custom-workflow__gsd_exec"));
420
+ assert.ok(!prompt.includes("mcp__gsd-workflow__<tool_name>"));
421
+ });
422
+
423
+ test("buildPromptFromContext does not advertise workflow MCP tools when unavailable", () => {
424
+ const context: Context = {
425
+ messages: [{ role: "user", content: "Check status" } as Message],
426
+ };
427
+
428
+ const prompt = buildPromptFromContext(context);
429
+
430
+ assert.ok(prompt.includes("GSD workflow MCP tools are unavailable"));
431
+ assert.ok(!prompt.includes("mcp__gsd-workflow__<tool_name>"));
432
+ assert.ok(!prompt.includes("mcp__gsd-workflow__gsd_exec"));
433
+ });
410
434
  });
411
435
 
412
436
  describe("stream-adapter — Claude Code external tool results", () => {
@@ -921,18 +945,21 @@ describe("stream-adapter — session persistence (#2859)", () => {
921
945
  }
922
946
  });
923
947
 
924
- test("buildSdkOptions prefers custom workflow MCP question tools over native AskUserQuestion", () => {
925
- const restore = setWorkflowMcpEnv({
926
- GSD_WORKFLOW_MCP_COMMAND: "node",
948
+ test("buildSdkOptions prefers custom workflow MCP question tools over native AskUserQuestion", () => {
949
+ const restore = setWorkflowMcpEnv({
950
+ GSD_WORKFLOW_MCP_COMMAND: "node",
927
951
  GSD_WORKFLOW_MCP_NAME: "custom-workflow",
928
952
  GSD_WORKFLOW_MCP_ARGS: JSON.stringify(["packages/mcp-server/dist/cli.js"]),
929
- GSD_WORKFLOW_MCP_ENV: JSON.stringify({ GSD_CLI_PATH: "/tmp/gsd" }),
930
- GSD_WORKFLOW_MCP_CWD: "/tmp/project",
931
- });
932
- try {
953
+ GSD_WORKFLOW_MCP_ENV: JSON.stringify({ GSD_CLI_PATH: "/tmp/gsd" }),
954
+ GSD_WORKFLOW_MCP_CWD: "/tmp/project",
955
+ });
956
+ const originalCwd = process.cwd();
957
+ const emptyDir = mkdtempSync(join(tmpdir(), "claude-mcp-custom-inject-"));
958
+ try {
959
+ process.chdir(emptyDir);
933
960
 
934
- const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
935
- const mcpServers = options.mcpServers as Record<string, any>;
961
+ const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
962
+ const mcpServers = options.mcpServers as Record<string, any>;
936
963
  assert.ok(mcpServers?.["custom-workflow"], "expected custom workflow server config");
937
964
  assert.deepEqual(options.disallowedTools, ["AskUserQuestion"]);
938
965
  assert.deepEqual(options.allowedTools, [
@@ -945,12 +972,14 @@ describe("stream-adapter — session persistence (#2859)", () => {
945
972
  "Agent",
946
973
  "WebFetch",
947
974
  "WebSearch",
948
- "mcp__custom-workflow__*",
949
- ]);
950
- } finally {
951
- restore();
952
- }
953
- });
975
+ "mcp__custom-workflow__*",
976
+ ]);
977
+ } finally {
978
+ process.chdir(originalCwd);
979
+ rmSync(emptyDir, { recursive: true, force: true });
980
+ restore();
981
+ }
982
+ });
954
983
 
955
984
  test("buildSdkOptions auto-discovers bundled MCP server even without env hints", () => {
956
985
  // Use setWorkflowMcpEnv with no values to save current state;
@@ -1059,7 +1088,7 @@ describe("stream-adapter — session persistence (#2859)", () => {
1059
1088
  }
1060
1089
  });
1061
1090
 
1062
- test("buildSdkOptions does not inject workflow MCP when already declared in project .mcp.json (avoids duplicate registration)", () => {
1091
+ test("buildSdkOptions does not inject workflow MCP when already declared in project .mcp.json (avoids duplicate registration)", () => {
1063
1092
  const restore = setWorkflowMcpEnv({
1064
1093
  GSD_WORKFLOW_MCP_COMMAND: "node",
1065
1094
  GSD_WORKFLOW_MCP_NAME: "gsd-workflow",
@@ -1089,10 +1118,48 @@ describe("stream-adapter — session persistence (#2859)", () => {
1089
1118
  process.chdir(originalCwd);
1090
1119
  rmSync(projectDir, { recursive: true, force: true });
1091
1120
  restore();
1092
- }
1093
- });
1121
+ }
1122
+ });
1123
+
1124
+ test("buildSdkOptions uses project-declared custom workflow MCP namespace", () => {
1125
+ const restore = setWorkflowMcpEnv({
1126
+ GSD_WORKFLOW_MCP_COMMAND: "node",
1127
+ GSD_WORKFLOW_MCP_NAME: "gsd-workflow",
1128
+ GSD_WORKFLOW_MCP_ARGS: JSON.stringify(["packages/mcp-server/dist/cli.js"]),
1129
+ GSD_WORKFLOW_MCP_ENV: JSON.stringify({ GSD_CLI_PATH: "/tmp/gsd" }),
1130
+ GSD_WORKFLOW_MCP_CWD: "/tmp/project",
1131
+ });
1132
+ const originalCwd = process.cwd();
1133
+ const projectDir = mkdtempSync(join(tmpdir(), "claude-mcp-custom-project-"));
1134
+ try {
1135
+ writeFileSync(
1136
+ join(projectDir, ".mcp.json"),
1137
+ JSON.stringify({
1138
+ mcpServers: {
1139
+ "custom-workflow": {
1140
+ command: "node",
1141
+ args: ["custom-cli.js"],
1142
+ env: { GSD_WORKFLOW_PROJECT_ROOT: projectDir },
1143
+ },
1144
+ },
1145
+ }),
1146
+ );
1147
+ process.chdir(projectDir);
1148
+ const options = buildSdkOptions("claude-sonnet-4-20250514", "test");
1149
+ assert.equal(options.mcpServers, undefined, "should not inject default workflow MCP when project declares a workflow server");
1150
+ const allowedTools = options.allowedTools as string[];
1151
+ assert.ok(allowedTools.includes("mcp__custom-workflow__*"), "allowedTools must use the project workflow namespace");
1152
+ assert.ok(!allowedTools.includes("mcp__gsd-workflow__*"), "allowedTools must not advertise the absent default namespace");
1153
+ const disallowedTools = options.disallowedTools as string[];
1154
+ assert.ok(disallowedTools.includes("AskUserQuestion"), "AskUserQuestion should be suppressed when workflow is available");
1155
+ } finally {
1156
+ process.chdir(originalCwd);
1157
+ rmSync(projectDir, { recursive: true, force: true });
1158
+ restore();
1159
+ }
1160
+ });
1094
1161
 
1095
- test("buildSdkOptions preserves runtime callbacks such as onElicitation", () => {
1162
+ test("buildSdkOptions preserves runtime callbacks such as onElicitation", () => {
1096
1163
  const restore = setWorkflowMcpEnv({});
1097
1164
  const onElicitation = async () => ({ action: "decline" as const });
1098
1165
  try {
@@ -132,6 +132,19 @@ function formatLibraryList(libs: C7Library[], query: string): string {
132
132
  return lines.join("\n");
133
133
  }
134
134
 
135
+ function getFirstTextContent(result: { content?: unknown }): string | undefined {
136
+ const content = result.content;
137
+ if (!Array.isArray(content)) return undefined;
138
+ const textBlock = content.find(
139
+ (block: unknown) =>
140
+ typeof block === "object" &&
141
+ block !== null &&
142
+ (block as { type?: unknown }).type === "text" &&
143
+ typeof (block as { text?: unknown }).text === "string",
144
+ ) as { text: string } | undefined;
145
+ return textBlock?.text.trim() || undefined;
146
+ }
147
+
135
148
  // ─── Tool details types ───────────────────────────────────────────────────────
136
149
 
137
150
  interface ResolveDetails {
@@ -234,7 +247,7 @@ export default function (pi: ExtensionAPI) {
234
247
  const d = result.details as ResolveDetails | undefined;
235
248
  if (isPartial) return new Text(theme.fg("warning", "Searching Context7..."), 0, 0);
236
249
  if ((result as any).isError || d?.error) {
237
- return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
250
+ return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
238
251
  }
239
252
  let text = theme.fg("success", `${d?.resultCount ?? 0} ${d?.resultCount === 1 ? "library" : "libraries"} found`);
240
253
  if (d?.cached) text += theme.fg("dim", " (cached)");
@@ -389,7 +402,7 @@ export default function (pi: ExtensionAPI) {
389
402
 
390
403
  if (isPartial) return new Text(theme.fg("warning", "Fetching documentation..."), 0, 0);
391
404
  if ((result as any).isError || d?.error) {
392
- return new Text(theme.fg("error", `Error: ${d?.error ?? "unknown"}`), 0, 0);
405
+ return new Text(theme.fg("error", `Error: ${d?.error ?? getFirstTextContent(result) ?? "unknown"}`), 0, 0);
393
406
  }
394
407
 
395
408
  let text = theme.fg("success", `${(d?.charCount ?? 0).toLocaleString()} chars`);
@@ -13,6 +13,7 @@ import { resolve } from "node:path";
13
13
  import type { ExtensionAPI, Theme } from "@gsd/pi-coding-agent";
14
14
  import { Editor, type EditorTheme, Key, matchesKey, Text, truncateToWidth, wrapTextWithAnsi } from "@gsd/pi-tui";
15
15
  import { Type } from "@sinclair/typebox";
16
+ import { renderSharedDialogFrame } from "./shared/dialog-frame.js";
16
17
  import { makeUI } from "./shared/tui.js";
17
18
  import { maskEditorLine, type ProgressStatus } from "./shared/mod.js";
18
19
  import { parseSecretsManifest, formatSecretsManifest } from "./gsd/files.js";
@@ -43,6 +44,10 @@ function maskPreview(value: string): string {
43
44
  return `${value.slice(0, 4)}${"*".repeat(Math.max(4, value.length - 8))}${value.slice(-4)}`;
44
45
  }
45
46
 
47
+ function dialogContentWidth(width: number): number {
48
+ return width < 4 ? Math.max(1, width) : Math.max(1, width - 4);
49
+ }
50
+
46
51
  function shellEscapeSingle(value: string): string {
47
52
  return `'${value.replace(/'/g, `'\\''`)}'`;
48
53
  }
@@ -168,10 +173,10 @@ async function collectOneSecret(
168
173
 
169
174
  function render(width: number): string[] {
170
175
  if (cachedLines) return cachedLines;
176
+ const contentWidth = dialogContentWidth(width);
171
177
  const lines: string[] = [];
172
- const add = (s: string) => lines.push(truncateToWidth(s, width));
178
+ const add = (s: string) => lines.push(truncateToWidth(s, contentWidth));
173
179
 
174
- add(theme.fg("accent", "─".repeat(width)));
175
180
  add(theme.fg("dim", ` Page ${pageIndex + 1}/${totalPages} · Secure Env Setup`));
176
181
  lines.push("");
177
182
 
@@ -187,7 +192,7 @@ async function collectOneSecret(
187
192
  for (let g = 0; g < guidance.length; g++) {
188
193
  const prefix = ` ${g + 1}. `;
189
194
  const step = guidance[g] as string;
190
- const wrappedLines = wrapTextWithAnsi(step, width - 4);
195
+ const wrappedLines = wrapTextWithAnsi(step, Math.max(1, contentWidth - 4));
191
196
  for (let w = 0; w < wrappedLines.length; w++) {
192
197
  const indent = w === 0 ? prefix : " ".repeat(prefix.length);
193
198
  lines.push(theme.fg("dim", `${indent}${wrappedLines[w]}`));
@@ -205,16 +210,15 @@ async function collectOneSecret(
205
210
 
206
211
  // Editor
207
212
  add(theme.fg("muted", " Enter value:"));
208
- for (const line of editor.render(width - 2)) {
213
+ for (const line of editor.render(Math.max(1, contentWidth - 2))) {
209
214
  add(theme.fg("text", maskEditorLine(line)));
210
215
  }
211
216
 
212
217
  lines.push("");
213
- add(theme.fg("dim", ` enter to confirm | ctrl+s or esc to skip | esc cancels`));
214
- add(theme.fg("accent", "─".repeat(width)));
218
+ const footer = theme.fg("dim", " enter to confirm | ctrl+s or esc to skip | esc cancels");
215
219
 
216
- cachedLines = lines;
217
- return lines;
220
+ cachedLines = renderSharedDialogFrame(theme, "Secure Env Setup", lines, width, { footer });
221
+ return cachedLines;
218
222
  }
219
223
 
220
224
  return {
@@ -286,13 +290,11 @@ export async function showSecretsSummary(
286
290
  function render(width: number): string[] {
287
291
  if (cachedLines) return cachedLines;
288
292
 
289
- const ui = makeUI(theme, width);
293
+ const contentWidth = dialogContentWidth(width);
294
+ const ui = makeUI(theme, contentWidth);
290
295
  const lines: string[] = [];
291
296
  const push = (...rows: string[][]) => { for (const r of rows) lines.push(...r); };
292
297
 
293
- push(ui.bar());
294
- push(ui.blank());
295
- push(ui.header(" Secrets Summary"));
296
298
  push(ui.blank());
297
299
 
298
300
  for (const entry of entries) {
@@ -314,11 +316,10 @@ export async function showSecretsSummary(
314
316
  }
315
317
 
316
318
  push(ui.blank());
317
- push(ui.hints(["any key to continue"]));
318
- push(ui.bar());
319
+ const footer = ui.hints(["any key to continue"])[0] ?? "";
319
320
 
320
- cachedLines = lines;
321
- return lines;
321
+ cachedLines = renderSharedDialogFrame(theme, "Secrets Summary", lines, width, { footer });
322
+ return cachedLines;
322
323
  }
323
324
 
324
325
  return {