gsd-pi 2.76.0-dev.82e249f7b → 2.76.0-dev.97f5583d9

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 (271) hide show
  1. package/dist/claude-cli-check.js +32 -3
  2. package/dist/mcp-server.d.ts +7 -0
  3. package/dist/mcp-server.js +35 -1
  4. package/dist/resource-loader.d.ts +1 -1
  5. package/dist/resource-loader.js +2 -8
  6. package/dist/resources/extensions/claude-code-cli/readiness.js +4 -3
  7. package/dist/resources/extensions/claude-code-cli/stream-adapter.js +77 -17
  8. package/dist/resources/extensions/gsd/auto/phases.js +42 -1
  9. package/dist/resources/extensions/gsd/auto/run-unit.js +27 -0
  10. package/dist/resources/extensions/gsd/auto/session.js +12 -0
  11. package/dist/resources/extensions/gsd/auto-dispatch.js +16 -3
  12. package/dist/resources/extensions/gsd/auto-model-selection.js +1 -1
  13. package/dist/resources/extensions/gsd/auto-post-unit.js +25 -2
  14. package/dist/resources/extensions/gsd/auto-prompts.js +14 -0
  15. package/dist/resources/extensions/gsd/auto-recovery.js +13 -0
  16. package/dist/resources/extensions/gsd/auto-start.js +27 -18
  17. package/dist/resources/extensions/gsd/auto-worktree.js +51 -53
  18. package/dist/resources/extensions/gsd/auto.js +55 -27
  19. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +17 -1
  20. package/dist/resources/extensions/gsd/bootstrap/db-tools.js +39 -9
  21. package/dist/resources/extensions/gsd/bootstrap/exec-tools.js +93 -0
  22. package/dist/resources/extensions/gsd/bootstrap/register-extension.js +2 -0
  23. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +51 -5
  24. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +34 -2
  25. package/dist/resources/extensions/gsd/clean-root-preflight.js +93 -0
  26. package/dist/resources/extensions/gsd/commands-prefs-wizard.js +968 -23
  27. package/dist/resources/extensions/gsd/compaction-snapshot.js +121 -0
  28. package/dist/resources/extensions/gsd/error-classifier.js +10 -3
  29. package/dist/resources/extensions/gsd/exec-history.js +120 -0
  30. package/dist/resources/extensions/gsd/exec-sandbox.js +258 -0
  31. package/dist/resources/extensions/gsd/gsd-db.js +115 -7
  32. package/dist/resources/extensions/gsd/guided-flow.js +189 -0
  33. package/dist/resources/extensions/gsd/health-widget.js +4 -1
  34. package/dist/resources/extensions/gsd/init-wizard.js +15 -1
  35. package/dist/resources/extensions/gsd/key-manager.js +6 -0
  36. package/dist/resources/extensions/gsd/model-router.js +36 -3
  37. package/dist/resources/extensions/gsd/pre-execution-checks.js +35 -9
  38. package/dist/resources/extensions/gsd/preferences-types.js +9 -0
  39. package/dist/resources/extensions/gsd/preferences-validation.js +83 -0
  40. package/dist/resources/extensions/gsd/preferences.js +17 -17
  41. package/dist/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  42. package/dist/resources/extensions/gsd/prompts/discuss.md +29 -2
  43. package/dist/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  44. package/dist/resources/extensions/gsd/safety/evidence-collector.js +96 -0
  45. package/dist/resources/extensions/gsd/safety/file-change-validator.js +13 -5
  46. package/dist/resources/extensions/gsd/safety/safety-harness.js +5 -1
  47. package/dist/resources/extensions/gsd/token-counter.js +22 -5
  48. package/dist/resources/extensions/gsd/tools/exec-search-tool.js +59 -0
  49. package/dist/resources/extensions/gsd/tools/exec-tool.js +126 -0
  50. package/dist/resources/extensions/gsd/tools/resume-tool.js +23 -0
  51. package/dist/resources/extensions/gsd/uok/plan-v2.js +20 -3
  52. package/dist/resources/extensions/gsd/workflow-mcp.js +3 -0
  53. package/dist/resources/skills/verify-before-complete/SKILL.md +2 -1
  54. package/dist/resources/skills/write-docs/SKILL.md +2 -1
  55. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  56. package/dist/web/standalone/.next/BUILD_ID +1 -1
  57. package/dist/web/standalone/.next/app-path-routes-manifest.json +10 -10
  58. package/dist/web/standalone/.next/build-manifest.json +2 -2
  59. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  60. package/dist/web/standalone/.next/required-server-files.json +1 -1
  61. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  62. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  69. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  70. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  76. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  77. package/dist/web/standalone/.next/server/app/index.html +1 -1
  78. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  79. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  80. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  81. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  82. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  83. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  84. package/dist/web/standalone/.next/server/app-paths-manifest.json +10 -10
  85. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  86. package/dist/web/standalone/.next/server/middleware-manifest.json +5 -5
  87. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  88. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  89. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  90. package/dist/web/standalone/server.js +1 -1
  91. package/package.json +1 -1
  92. package/packages/mcp-server/dist/remote-questions.d.ts +45 -0
  93. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -0
  94. package/packages/mcp-server/dist/remote-questions.js +732 -0
  95. package/packages/mcp-server/dist/remote-questions.js.map +1 -0
  96. package/packages/mcp-server/dist/server.d.ts +7 -0
  97. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  98. package/packages/mcp-server/dist/server.js +41 -4
  99. package/packages/mcp-server/dist/server.js.map +1 -1
  100. package/packages/mcp-server/dist/workflow-tools.d.ts.map +1 -1
  101. package/packages/mcp-server/dist/workflow-tools.js +64 -25
  102. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  103. package/packages/mcp-server/package.json +2 -1
  104. package/packages/mcp-server/src/mcp-server.test.ts +30 -0
  105. package/packages/mcp-server/src/remote-questions.test.ts +294 -0
  106. package/packages/mcp-server/src/remote-questions.ts +916 -0
  107. package/packages/mcp-server/src/server.ts +62 -10
  108. package/packages/mcp-server/src/workflow-tools.test.ts +146 -1
  109. package/packages/mcp-server/src/workflow-tools.ts +84 -43
  110. package/packages/mcp-server/tsconfig.test.json +19 -0
  111. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  112. package/packages/pi-ai/dist/providers/anthropic-auth.test.js +1 -1
  113. package/packages/pi-ai/dist/providers/anthropic-auth.test.js.map +1 -1
  114. package/packages/pi-ai/dist/providers/anthropic-shared.d.ts.map +1 -1
  115. package/packages/pi-ai/dist/providers/anthropic-shared.js +27 -4
  116. package/packages/pi-ai/dist/providers/anthropic-shared.js.map +1 -1
  117. package/packages/pi-ai/dist/providers/anthropic.d.ts.map +1 -1
  118. package/packages/pi-ai/dist/providers/anthropic.js +8 -3
  119. package/packages/pi-ai/dist/providers/anthropic.js.map +1 -1
  120. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts +2 -0
  121. package/packages/pi-ai/dist/providers/minimax-tool-name.test.d.ts.map +1 -0
  122. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js +80 -0
  123. package/packages/pi-ai/dist/providers/minimax-tool-name.test.js.map +1 -0
  124. package/packages/pi-ai/dist/providers/simple-options.d.ts +10 -0
  125. package/packages/pi-ai/dist/providers/simple-options.d.ts.map +1 -1
  126. package/packages/pi-ai/dist/providers/simple-options.js +16 -1
  127. package/packages/pi-ai/dist/providers/simple-options.js.map +1 -1
  128. package/packages/pi-ai/src/providers/anthropic-auth.test.ts +1 -1
  129. package/packages/pi-ai/src/providers/anthropic-shared.ts +26 -5
  130. package/packages/pi-ai/src/providers/anthropic.ts +9 -3
  131. package/packages/pi-ai/src/providers/minimax-tool-name.test.ts +98 -0
  132. package/packages/pi-ai/src/providers/simple-options.ts +17 -1
  133. package/packages/pi-ai/tsconfig.tsbuildinfo +1 -1
  134. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts +2 -0
  135. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.d.ts.map +1 -0
  136. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js +203 -0
  137. package/packages/pi-coding-agent/dist/core/model-registry-custom-caps.test.js.map +1 -0
  138. package/packages/pi-coding-agent/dist/core/model-registry.d.ts.map +1 -1
  139. package/packages/pi-coding-agent/dist/core/model-registry.js +14 -0
  140. package/packages/pi-coding-agent/dist/core/model-registry.js.map +1 -1
  141. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts +2 -0
  142. package/packages/pi-coding-agent/dist/core/redact-secrets.d.ts.map +1 -0
  143. package/packages/pi-coding-agent/dist/core/redact-secrets.js +49 -0
  144. package/packages/pi-coding-agent/dist/core/redact-secrets.js.map +1 -0
  145. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts +2 -0
  146. package/packages/pi-coding-agent/dist/core/redact-secrets.test.d.ts.map +1 -0
  147. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js +67 -0
  148. package/packages/pi-coding-agent/dist/core/redact-secrets.test.js.map +1 -0
  149. package/packages/pi-coding-agent/dist/core/session-manager.d.ts.map +1 -1
  150. package/packages/pi-coding-agent/dist/core/session-manager.js +9 -5
  151. package/packages/pi-coding-agent/dist/core/session-manager.js.map +1 -1
  152. package/packages/pi-coding-agent/dist/core/session-manager.test.js +25 -1
  153. package/packages/pi-coding-agent/dist/core/session-manager.test.js.map +1 -1
  154. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts +1 -1
  155. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.d.ts.map +1 -1
  156. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js +5 -4
  157. package/packages/pi-coding-agent/dist/modes/interactive/components/chat-frame.js.map +1 -1
  158. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts +7 -6
  159. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.d.ts.map +1 -1
  160. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js +29 -21
  161. package/packages/pi-coding-agent/dist/modes/interactive/components/skill-invocation-message.js.map +1 -1
  162. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  163. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js +13 -1
  164. package/packages/pi-coding-agent/dist/modes/interactive/interactive-mode.js.map +1 -1
  165. package/packages/pi-coding-agent/src/core/model-registry-custom-caps.test.ts +245 -0
  166. package/packages/pi-coding-agent/src/core/model-registry.ts +16 -0
  167. package/packages/pi-coding-agent/src/core/redact-secrets.test.ts +86 -0
  168. package/packages/pi-coding-agent/src/core/redact-secrets.ts +58 -0
  169. package/packages/pi-coding-agent/src/core/session-manager.test.ts +36 -1
  170. package/packages/pi-coding-agent/src/core/session-manager.ts +9 -5
  171. package/packages/pi-coding-agent/src/modes/interactive/components/chat-frame.ts +6 -6
  172. package/packages/pi-coding-agent/src/modes/interactive/components/skill-invocation-message.ts +36 -22
  173. package/packages/pi-coding-agent/src/modes/interactive/interactive-mode.ts +13 -1
  174. package/packages/pi-coding-agent/tsconfig.tsbuildinfo +1 -1
  175. package/src/resources/extensions/claude-code-cli/readiness.ts +4 -3
  176. package/src/resources/extensions/claude-code-cli/stream-adapter.ts +78 -17
  177. package/src/resources/extensions/claude-code-cli/tests/stream-adapter.test.ts +149 -5
  178. package/src/resources/extensions/gsd/auto/loop-deps.ts +13 -0
  179. package/src/resources/extensions/gsd/auto/phases.ts +66 -1
  180. package/src/resources/extensions/gsd/auto/run-unit.ts +29 -0
  181. package/src/resources/extensions/gsd/auto/session.ts +22 -0
  182. package/src/resources/extensions/gsd/auto-dispatch.ts +16 -3
  183. package/src/resources/extensions/gsd/auto-model-selection.ts +1 -1
  184. package/src/resources/extensions/gsd/auto-post-unit.ts +29 -3
  185. package/src/resources/extensions/gsd/auto-prompts.ts +28 -1
  186. package/src/resources/extensions/gsd/auto-recovery.ts +15 -0
  187. package/src/resources/extensions/gsd/auto-start.ts +29 -19
  188. package/src/resources/extensions/gsd/auto-worktree.ts +62 -63
  189. package/src/resources/extensions/gsd/auto.ts +58 -27
  190. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +23 -1
  191. package/src/resources/extensions/gsd/bootstrap/db-tools.ts +40 -9
  192. package/src/resources/extensions/gsd/bootstrap/exec-tools.ts +109 -0
  193. package/src/resources/extensions/gsd/bootstrap/register-extension.ts +2 -0
  194. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +53 -5
  195. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +35 -2
  196. package/src/resources/extensions/gsd/clean-root-preflight.ts +111 -0
  197. package/src/resources/extensions/gsd/commands-prefs-wizard.ts +898 -32
  198. package/src/resources/extensions/gsd/compaction-snapshot.ts +165 -0
  199. package/src/resources/extensions/gsd/error-classifier.ts +10 -3
  200. package/src/resources/extensions/gsd/exec-history.ts +153 -0
  201. package/src/resources/extensions/gsd/exec-sandbox.ts +326 -0
  202. package/src/resources/extensions/gsd/gsd-db.ts +122 -7
  203. package/src/resources/extensions/gsd/guided-flow.ts +221 -0
  204. package/src/resources/extensions/gsd/health-widget.ts +3 -1
  205. package/src/resources/extensions/gsd/init-wizard.ts +15 -1
  206. package/src/resources/extensions/gsd/journal.ts +2 -1
  207. package/src/resources/extensions/gsd/key-manager.ts +6 -0
  208. package/src/resources/extensions/gsd/model-router.ts +42 -1
  209. package/src/resources/extensions/gsd/pre-execution-checks.ts +36 -10
  210. package/src/resources/extensions/gsd/preferences-types.ts +46 -0
  211. package/src/resources/extensions/gsd/preferences-validation.ts +79 -0
  212. package/src/resources/extensions/gsd/preferences.ts +17 -17
  213. package/src/resources/extensions/gsd/prompts/discuss-headless.md +8 -0
  214. package/src/resources/extensions/gsd/prompts/discuss.md +29 -2
  215. package/src/resources/extensions/gsd/prompts/parallel-research-slices.md +5 -2
  216. package/src/resources/extensions/gsd/safety/evidence-collector.ts +119 -0
  217. package/src/resources/extensions/gsd/safety/file-change-validator.ts +17 -4
  218. package/src/resources/extensions/gsd/safety/safety-harness.ts +9 -0
  219. package/src/resources/extensions/gsd/tests/auto-loop.test.ts +119 -1
  220. package/src/resources/extensions/gsd/tests/auto-paused-session-validation.test.ts +12 -0
  221. package/src/resources/extensions/gsd/tests/auto-recovery.test.ts +49 -0
  222. package/src/resources/extensions/gsd/tests/clean-root-preflight.test.ts +186 -0
  223. package/src/resources/extensions/gsd/tests/compaction-snapshot.test.ts +123 -0
  224. package/src/resources/extensions/gsd/tests/complete-slice.test.ts +2 -2
  225. package/src/resources/extensions/gsd/tests/complete-task.test.ts +2 -2
  226. package/src/resources/extensions/gsd/tests/custom-engine-loop-integration.test.ts +2 -0
  227. package/src/resources/extensions/gsd/tests/doctor-providers.test.ts +31 -0
  228. package/src/resources/extensions/gsd/tests/double-merge-guard.test.ts +1 -1
  229. package/src/resources/extensions/gsd/tests/ensure-db-open.test.ts +1 -1
  230. package/src/resources/extensions/gsd/tests/escalation.test.ts +1 -1
  231. package/src/resources/extensions/gsd/tests/exec-history.test.ts +124 -0
  232. package/src/resources/extensions/gsd/tests/exec-sandbox.test.ts +210 -0
  233. package/src/resources/extensions/gsd/tests/file-change-validator.test.ts +58 -0
  234. package/src/resources/extensions/gsd/tests/gsd-db.test.ts +152 -1
  235. package/src/resources/extensions/gsd/tests/init-wizard.test.ts +27 -0
  236. package/src/resources/extensions/gsd/tests/isolation-none-branch-guard.test.ts +1 -1
  237. package/src/resources/extensions/gsd/tests/issue-4540-regressions.test.ts +288 -0
  238. package/src/resources/extensions/gsd/tests/journal-integration.test.ts +2 -0
  239. package/src/resources/extensions/gsd/tests/key-manager.test.ts +7 -0
  240. package/src/resources/extensions/gsd/tests/md-importer.test.ts +1 -1
  241. package/src/resources/extensions/gsd/tests/memory-store.test.ts +2 -2
  242. package/src/resources/extensions/gsd/tests/parallel-research-dispatch.test.ts +19 -0
  243. package/src/resources/extensions/gsd/tests/pre-exec-backtick-strip.test.ts +14 -0
  244. package/src/resources/extensions/gsd/tests/pre-exec-gate-loop.test.ts +272 -0
  245. package/src/resources/extensions/gsd/tests/pre-execution-checks.test.ts +234 -0
  246. package/src/resources/extensions/gsd/tests/preferences.test.ts +110 -0
  247. package/src/resources/extensions/gsd/tests/prefs-wizard-coverage.test.ts +44 -0
  248. package/src/resources/extensions/gsd/tests/provider-errors.test.ts +48 -0
  249. package/src/resources/extensions/gsd/tests/ready-phrase-no-files-4573.test.ts +388 -0
  250. package/src/resources/extensions/gsd/tests/restore-tools-after-discuss.test.ts +9 -3
  251. package/src/resources/extensions/gsd/tests/safety-harness-false-positives.test.ts +205 -0
  252. package/src/resources/extensions/gsd/tests/save-gate-result-render.test.ts +95 -0
  253. package/src/resources/extensions/gsd/tests/session-start-footer.test.ts +32 -40
  254. package/src/resources/extensions/gsd/tests/stash-queued-context-files.test.ts +56 -0
  255. package/src/resources/extensions/gsd/tests/token-counter.test.ts +105 -1
  256. package/src/resources/extensions/gsd/tests/tool-compatibility.test.ts +107 -0
  257. package/src/resources/extensions/gsd/tests/uok-plan-v2-wiring.test.ts +23 -0
  258. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +65 -2
  259. package/src/resources/extensions/gsd/tests/write-gate.test.ts +64 -0
  260. package/src/resources/extensions/gsd/tests/zombie-gsd-state.test.ts +3 -1
  261. package/src/resources/extensions/gsd/token-counter.ts +22 -5
  262. package/src/resources/extensions/gsd/tools/exec-search-tool.ts +81 -0
  263. package/src/resources/extensions/gsd/tools/exec-tool.ts +183 -0
  264. package/src/resources/extensions/gsd/tools/resume-tool.ts +40 -0
  265. package/src/resources/extensions/gsd/uok/plan-v2.ts +26 -3
  266. package/src/resources/extensions/gsd/workflow-logger.ts +3 -1
  267. package/src/resources/extensions/gsd/workflow-mcp.ts +3 -0
  268. package/src/resources/skills/verify-before-complete/SKILL.md +2 -1
  269. package/src/resources/skills/write-docs/SKILL.md +2 -1
  270. /package/dist/web/standalone/.next/static/{ecSsu49rxxcpbNmVP4mLD → lLdDRDspgYzfz0bJAmUSz}/_buildManifest.js +0 -0
  271. /package/dist/web/standalone/.next/static/{ecSsu49rxxcpbNmVP4mLD → lLdDRDspgYzfz0bJAmUSz}/_ssgManifest.js +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remote-questions.js","sourceRoot":"","sources":["../src/remote-questions.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Remote Questions — self-contained MCP-server adapter\n *\n * Mirrors the routing logic from src/resources/extensions/ask-user-questions.ts\n * but without any dependency on @gsd/pi-coding-agent or the main src/ tree.\n * All channel adapters (Discord, Slack, Telegram), config resolution, HTTP\n * calls, and polling are inlined here so packages/mcp-server remains a\n * standalone package.\n *\n * Entry points consumed by server.ts:\n * isRemoteConfigured() — cheap synchronous config check\n * tryRemoteQuestions(...) — dispatch + poll + return result\n */\n\nimport { readFileSync } from 'node:fs';\nimport { homedir } from 'node:os';\nimport { join } from 'node:path';\nimport { randomUUID } from 'node:crypto';\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\ntype RemoteChannel = 'slack' | 'discord' | 'telegram';\n\ninterface QuestionOption {\n label: string;\n description: string;\n}\n\nexport interface RemoteQuestion {\n id: string;\n header: string;\n question: string;\n options: QuestionOption[];\n allowMultiple?: boolean;\n}\n\ninterface RemotePrompt {\n id: string;\n channel: RemoteChannel;\n createdAt: number;\n timeoutAt: number;\n pollIntervalMs: number;\n questions: RemoteQuestion[];\n context: { source: string };\n}\n\ninterface RemotePromptRef {\n id: string;\n channel: RemoteChannel;\n messageId: string;\n channelId: string;\n threadTs?: string;\n threadUrl?: string;\n}\n\ninterface RemoteAnswer {\n answers: Record<string, { answers: string[]; user_note?: string }>;\n}\n\nexport interface RemoteToolResult {\n content: Array<{ type: 'text'; text: string }>;\n details?: Record<string, unknown>;\n}\n\ninterface ResolvedConfig {\n channel: RemoteChannel;\n channelId: string;\n timeoutMs: number;\n pollIntervalMs: number;\n token: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst PER_REQUEST_TIMEOUT_MS = 15_000;\nconst DISCORD_API = 'https://discord.com/api/v10';\nconst SLACK_API = 'https://slack.com/api';\nconst TELEGRAM_API = 'https://api.telegram.org';\n\nconst DISCORD_NUMBER_EMOJIS = ['1️⃣', '2️⃣', '3️⃣', '4️⃣', '5️⃣'];\nconst SLACK_NUMBER_REACTION_NAMES = ['one', 'two', 'three', 'four', 'five'];\n\nconst DEFAULT_TIMEOUT_MINUTES = 5;\nconst DEFAULT_POLL_INTERVAL_SECONDS = 5;\nconst MIN_TIMEOUT_MINUTES = 1;\nconst MAX_TIMEOUT_MINUTES = 30;\nconst MIN_POLL_INTERVAL_SECONDS = 2;\nconst MAX_POLL_INTERVAL_SECONDS = 30;\n\nconst CHANNEL_ID_PATTERNS: Record<RemoteChannel, RegExp> = {\n slack: /^[A-Z0-9]{9,12}$/,\n discord: /^\\d{17,20}$/,\n telegram: /^-?\\d{5,20}$/,\n};\n\nconst ENV_KEYS: Record<RemoteChannel, string> = {\n slack: 'SLACK_BOT_TOKEN',\n discord: 'DISCORD_BOT_TOKEN',\n telegram: 'TELEGRAM_BOT_TOKEN',\n};\n\n// ---------------------------------------------------------------------------\n// Config resolution — reads ~/.gsd/PREFERENCES.md YAML frontmatter\n// ---------------------------------------------------------------------------\n\nfunction clampNumber(value: unknown, fallback: number, min: number, max: number): number {\n const n = typeof value === 'number' ? value : Number(value);\n if (!Number.isFinite(n)) return fallback;\n return Math.max(min, Math.min(max, n));\n}\n\n/**\n * Minimal YAML frontmatter reader. Handles:\n * ---\n * key: value\n * nested_key:\n * child: value\n * ---\n * Sufficient for the flat remote_questions config block.\n */\nfunction parseSimpleFrontmatter(content: string): Record<string, unknown> {\n const match = content.match(/^---\\r?\\n([\\s\\S]*?)\\r?\\n---/m);\n if (!match) return {};\n\n const yaml = match[1];\n const result: Record<string, unknown> = {};\n let currentSection: string | null = null;\n const sectionData: Record<string, Record<string, unknown>> = {};\n\n for (const rawLine of yaml.split('\\n')) {\n const line = rawLine.replace(/\\r$/, '');\n if (!line.trim() || line.trim().startsWith('#')) continue;\n\n // Top-level key (no indent)\n const topMatch = line.match(/^([a-zA-Z_][a-zA-Z0-9_]*):\\s*(.*)$/);\n if (topMatch) {\n currentSection = topMatch[1];\n const val = topMatch[2].trim();\n if (val) {\n result[currentSection] = parseSimpleScalar(val);\n currentSection = null; // scalar, no children\n } else {\n sectionData[currentSection] = {};\n result[currentSection] = sectionData[currentSection];\n }\n continue;\n }\n\n // Indented child key\n const childMatch = line.match(/^\\s+([a-zA-Z_][a-zA-Z0-9_]*):\\s*(.*)$/);\n if (childMatch && currentSection && sectionData[currentSection]) {\n const childKey = childMatch[1];\n const childVal = childMatch[2].trim();\n sectionData[currentSection][childKey] = parseSimpleScalar(childVal);\n }\n }\n\n return result;\n}\n\nfunction parseSimpleScalar(raw: string): string | number | boolean | null {\n const s = raw.replace(/^[\"']|[\"']$/g, '').trim();\n if (s === 'true') return true;\n if (s === 'false') return false;\n if (s === 'null' || s === '~') return null;\n const n = Number(s);\n if (s !== '' && !Number.isNaN(n)) return n;\n return s;\n}\n\nfunction loadPreferencesFromFile(path: string): Record<string, unknown> | null {\n try {\n const content = readFileSync(path, 'utf-8');\n return parseSimpleFrontmatter(content);\n } catch {\n return null;\n }\n}\n\nfunction resolveRemoteConfig(): ResolvedConfig | null {\n const gsdHome = process.env['GSD_HOME'] ?? join(homedir(), '.gsd');\n const globalPath = join(gsdHome, 'PREFERENCES.md');\n\n const prefs = loadPreferencesFromFile(globalPath);\n if (!prefs) return null;\n\n const rq = prefs['remote_questions'] as Record<string, unknown> | undefined;\n if (!rq || !rq['channel'] || !rq['channel_id']) return null;\n\n const channel = String(rq['channel']) as RemoteChannel;\n if (channel !== 'slack' && channel !== 'discord' && channel !== 'telegram') return null;\n\n const channelId = String(rq['channel_id']);\n if (!CHANNEL_ID_PATTERNS[channel].test(channelId)) return null;\n\n const token = process.env[ENV_KEYS[channel]];\n if (!token) return null;\n\n const timeoutMs = clampNumber(rq['timeout_minutes'], DEFAULT_TIMEOUT_MINUTES, MIN_TIMEOUT_MINUTES, MAX_TIMEOUT_MINUTES) * 60 * 1000;\n const pollIntervalMs = clampNumber(rq['poll_interval_seconds'], DEFAULT_POLL_INTERVAL_SECONDS, MIN_POLL_INTERVAL_SECONDS, MAX_POLL_INTERVAL_SECONDS) * 1000;\n\n return { channel, channelId, timeoutMs, pollIntervalMs, token };\n}\n\n/**\n * Cheap synchronous check — does not make any HTTP requests.\n */\nexport function isRemoteConfigured(): boolean {\n return resolveRemoteConfig() !== null;\n}\n\n// ---------------------------------------------------------------------------\n// HTTP helper\n// ---------------------------------------------------------------------------\n\nasync function apiRequest(\n url: string,\n method: 'GET' | 'POST' | 'PUT' | 'DELETE',\n body: unknown,\n authScheme: 'Bearer' | 'Bot',\n authToken: string,\n errorLabel: string,\n): Promise<unknown> {\n const headers: Record<string, string> = {\n Authorization: `${authScheme} ${authToken}`,\n };\n\n const init: RequestInit = {\n method,\n headers,\n signal: AbortSignal.timeout(PER_REQUEST_TIMEOUT_MS),\n };\n\n if (body !== undefined) {\n headers['Content-Type'] = 'application/json';\n init.body = JSON.stringify(body);\n }\n\n const response = await fetch(url, init);\n\n if (response.status === 204) return {};\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n const safeText = text.length > 200 ? text.slice(0, 200) + '\\u2026' : text;\n throw new Error(`${errorLabel} HTTP ${response.status}: ${safeText}`);\n }\n\n return response.json();\n}\n\n// ---------------------------------------------------------------------------\n// Payload formatting\n// ---------------------------------------------------------------------------\n\nfunction formatForDiscord(prompt: RemotePrompt): { embeds: unknown[]; reactionEmojis: string[] } {\n const reactionEmojis: string[] = [];\n const embeds = prompt.questions.map((q, questionIndex) => {\n const supportsReactions = prompt.questions.length === 1;\n const optionLines = q.options.map((opt, i) => {\n const emoji = DISCORD_NUMBER_EMOJIS[i] ?? `${i + 1}.`;\n if (supportsReactions && DISCORD_NUMBER_EMOJIS[i]) reactionEmojis.push(DISCORD_NUMBER_EMOJIS[i]);\n return `${emoji} **${opt.label}** — ${opt.description}`;\n });\n\n const footerParts: string[] = [];\n if (supportsReactions) {\n footerParts.push(q.allowMultiple\n ? 'Reply with comma-separated choices (`1,3`) or react with matching numbers'\n : 'Reply with a number or react with the matching number');\n } else {\n footerParts.push(`Question ${questionIndex + 1}/${prompt.questions.length} — reply with one line per question or use semicolons`);\n }\n footerParts.push(`Source: ${prompt.context.source}`);\n\n return {\n title: q.header,\n description: q.question,\n color: 0x7c3aed,\n fields: [{ name: 'Options', value: optionLines.join('\\n') }],\n footer: { text: footerParts.join(' · ') },\n };\n });\n\n return { embeds, reactionEmojis };\n}\n\nfunction formatForSlack(prompt: RemotePrompt): unknown[] {\n const blocks: unknown[] = [\n { type: 'header', text: { type: 'plain_text', text: 'GSD needs your input' } },\n ];\n\n if (prompt.questions.length > 1) {\n blocks.push({\n type: 'context',\n elements: [{ type: 'mrkdwn', text: 'Reply once in thread using one line per question or semicolons (`1; 2; custom note`).' }],\n });\n }\n\n for (const q of prompt.questions) {\n const supportsReactions = prompt.questions.length === 1;\n blocks.push({ type: 'section', text: { type: 'mrkdwn', text: `*${q.header}*\\n${q.question}` } });\n blocks.push({\n type: 'section',\n text: { type: 'mrkdwn', text: q.options.map((opt, i) => `${i + 1}. *${opt.label}* — ${opt.description}`).join('\\n') },\n });\n blocks.push({\n type: 'context',\n elements: [{\n type: 'mrkdwn',\n text: prompt.questions.length > 1\n ? (q.allowMultiple ? 'For this question, use comma-separated numbers (`1,3`) or free text.' : 'For this question, use one number (`1`) or free text.')\n : (q.allowMultiple\n ? (supportsReactions ? 'Reply in thread with comma-separated numbers (`1,3`) or react with matching number emoji.' : 'Reply in thread with comma-separated numbers (`1,3`) or free text.')\n : (supportsReactions ? 'Reply in thread with a number (`1`) or react with the matching number emoji.' : 'Reply in thread with a number (`1`) or free text.')),\n }],\n });\n blocks.push({ type: 'divider' });\n }\n\n return blocks;\n}\n\nfunction formatForTelegram(prompt: RemotePrompt): { text: string; parse_mode: 'HTML'; reply_markup?: unknown } {\n const escape = (s: string) => s.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n const lines: string[] = ['<b>GSD needs your input</b>', ''];\n\n for (let qi = 0; qi < prompt.questions.length; qi++) {\n const q = prompt.questions[qi];\n lines.push(`<b>${escape(q.header)}</b>`);\n lines.push(escape(q.question));\n lines.push('');\n for (let i = 0; i < q.options.length; i++) {\n lines.push(`${i + 1}. <b>${escape(q.options[i].label)}</b> — ${escape(q.options[i].description)}`);\n }\n lines.push('');\n if (prompt.questions.length === 1) {\n lines.push(q.allowMultiple ? 'Reply with comma-separated numbers (1,3) or free text.' : 'Reply with a number or tap a button below.');\n } else {\n lines.push(`Question ${qi + 1}/${prompt.questions.length} — reply with one line per question or use semicolons.`);\n }\n if (qi < prompt.questions.length - 1) lines.push('');\n }\n\n const result: { text: string; parse_mode: 'HTML'; reply_markup?: unknown } = {\n text: lines.join('\\n'),\n parse_mode: 'HTML',\n };\n\n if (prompt.questions.length === 1 && prompt.questions[0].options.length <= 5) {\n result.reply_markup = {\n inline_keyboard: prompt.questions[0].options.map((opt, i) => [{\n text: `${i + 1}. ${opt.label}`,\n callback_data: `${prompt.id}:${i}`,\n }]),\n };\n }\n\n return result;\n}\n\n// ---------------------------------------------------------------------------\n// Response parsing\n// ---------------------------------------------------------------------------\n\nfunction parseAnswerForQuestion(text: string, q: RemoteQuestion): { answers: string[]; user_note?: string } {\n if (!text) return { answers: [], user_note: 'No response provided' };\n\n if (/^[\\d,\\s]+$/.test(text)) {\n const nums = text\n .split(',')\n .map((s) => parseInt(s.trim(), 10))\n .filter((n) => !Number.isNaN(n) && n >= 1 && n <= q.options.length);\n if (nums.length > 0) {\n const selected = nums.map((n) => q.options[n - 1].label);\n return { answers: q.allowMultiple ? selected : [selected[0]] };\n }\n }\n\n const single = parseInt(text, 10);\n if (!Number.isNaN(single) && single >= 1 && single <= q.options.length) {\n return { answers: [q.options[single - 1].label] };\n }\n\n const truncated = text.length > 500 ? text.slice(0, 500) + '\\u2026' : text;\n return { answers: [], user_note: truncated };\n}\n\nfunction parseTextReply(text: string, questions: RemoteQuestion[]): RemoteAnswer {\n const answers: RemoteAnswer['answers'] = {};\n const trimmed = text.trim();\n\n if (questions.length === 1) {\n answers[questions[0].id] = parseAnswerForQuestion(trimmed, questions[0]);\n return { answers };\n }\n\n const parts = trimmed.includes(';')\n ? trimmed.split(';').map((s) => s.trim()).filter(Boolean)\n : trimmed.split('\\n').map((s) => s.trim()).filter(Boolean);\n\n for (let i = 0; i < questions.length; i++) {\n answers[questions[i].id] = parseAnswerForQuestion(parts[i] ?? '', questions[i]);\n }\n\n return { answers };\n}\n\nfunction parseDiscordReactions(\n reactions: Array<{ emoji: string; count: number }>,\n questions: RemoteQuestion[],\n): RemoteAnswer {\n const answers: RemoteAnswer['answers'] = {};\n if (questions.length !== 1) {\n for (const q of questions) {\n answers[q.id] = { answers: [], user_note: 'Discord reactions are only supported for single-question prompts' };\n }\n return { answers };\n }\n\n const q = questions[0];\n const picked = reactions\n .filter((r) => DISCORD_NUMBER_EMOJIS.includes(r.emoji) && r.count > 0)\n .map((r) => q.options[DISCORD_NUMBER_EMOJIS.indexOf(r.emoji)]?.label)\n .filter((l): l is string => Boolean(l));\n\n answers[q.id] = picked.length > 0\n ? { answers: q.allowMultiple ? picked : [picked[0]] }\n : { answers: [], user_note: 'No clear response via reactions' };\n\n return { answers };\n}\n\nfunction parseSlackReactions(reactionNames: string[], questions: RemoteQuestion[]): RemoteAnswer {\n const answers: RemoteAnswer['answers'] = {};\n if (questions.length !== 1) {\n for (const q of questions) {\n answers[q.id] = { answers: [], user_note: 'Slack reactions are only supported for single-question prompts' };\n }\n return { answers };\n }\n\n const q = questions[0];\n const picked = reactionNames\n .filter((name) => SLACK_NUMBER_REACTION_NAMES.includes(name))\n .map((name) => q.options[SLACK_NUMBER_REACTION_NAMES.indexOf(name)]?.label)\n .filter((l): l is string => Boolean(l));\n\n answers[q.id] = picked.length > 0\n ? { answers: q.allowMultiple ? picked : [picked[0]] }\n : { answers: [], user_note: 'No clear response via reactions' };\n\n return { answers };\n}\n\nfunction parseTelegramCallbackData(callbackData: string, questions: RemoteQuestion[], promptId: string): RemoteAnswer | null {\n const pattern = new RegExp(`^${promptId.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&')}:(\\\\d+)$`);\n const match = callbackData.match(pattern);\n if (match && questions.length === 1) {\n const idx = parseInt(match[1], 10);\n const q = questions[0];\n if (idx >= 0 && idx < q.options.length) {\n return { answers: { [q.id]: { answers: [q.options[idx].label] } } };\n }\n }\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Channel adapters\n// ---------------------------------------------------------------------------\n\ninterface DispatchResult {\n ref: RemotePromptRef;\n}\n\n// --- Discord ---\n\nasync function discordValidate(token: string, channelId: string): Promise<{ botUserId: string; guildId: string | null }> {\n const meRes = await apiRequest(`${DISCORD_API}/users/@me`, 'GET', undefined, 'Bot', token, 'Discord API') as Record<string, unknown>;\n if (!meRes['id']) throw new Error('Discord auth failed: invalid token');\n const botUserId = String(meRes['id']);\n\n let guildId: string | null = null;\n try {\n const chanRes = await apiRequest(`${DISCORD_API}/channels/${channelId}`, 'GET', undefined, 'Bot', token, 'Discord API') as Record<string, unknown>;\n if (chanRes['guild_id']) guildId = String(chanRes['guild_id']);\n } catch { /* non-fatal */ }\n\n return { botUserId, guildId };\n}\n\nasync function discordSend(prompt: RemotePrompt, token: string, channelId: string, guildId: string | null): Promise<DispatchResult> {\n const { embeds, reactionEmojis } = formatForDiscord(prompt);\n const res = await apiRequest(\n `${DISCORD_API}/channels/${channelId}/messages`,\n 'POST',\n { content: '**GSD needs your input** — reply to this message with your answer', embeds },\n 'Bot', token, 'Discord API',\n ) as Record<string, unknown>;\n\n if (!res['id']) throw new Error(`Discord send failed: ${JSON.stringify(res)}`);\n const messageId = String(res['id']);\n\n if (prompt.questions.length === 1) {\n for (const emoji of reactionEmojis) {\n try {\n await apiRequest(`${DISCORD_API}/channels/${channelId}/messages/${messageId}/reactions/${encodeURIComponent(emoji)}/@me`, 'PUT', undefined, 'Bot', token, 'Discord API');\n } catch { /* best-effort */ }\n }\n }\n\n const threadUrl = guildId ? `https://discord.com/channels/${guildId}/${channelId}/${messageId}` : undefined;\n return { ref: { id: prompt.id, channel: 'discord', messageId, channelId, threadUrl } };\n}\n\nasync function discordPoll(prompt: RemotePrompt, ref: RemotePromptRef, token: string, botUserId: string): Promise<RemoteAnswer | null> {\n // Try reactions first for single-question prompts\n if (prompt.questions.length === 1) {\n const reactions: Array<{ emoji: string; count: number }> = [];\n for (const emoji of DISCORD_NUMBER_EMOJIS) {\n try {\n const users = await apiRequest(\n `${DISCORD_API}/channels/${ref.channelId}/messages/${ref.messageId}/reactions/${encodeURIComponent(emoji)}`,\n 'GET', undefined, 'Bot', token, 'Discord API',\n ) as unknown[];\n if (Array.isArray(users)) {\n const humanUsers = users.filter((u) => (u as Record<string, unknown>)['id'] !== botUserId);\n if (humanUsers.length > 0) reactions.push({ emoji, count: humanUsers.length });\n }\n } catch (err) {\n const msg = String((err as Error).message ?? '');\n if (msg.includes('HTTP 404')) continue;\n if (msg.includes('HTTP 401') || msg.includes('HTTP 403')) throw err;\n }\n }\n if (reactions.length > 0) return parseDiscordReactions(reactions, prompt.questions);\n }\n\n // Try text replies\n const messages = await apiRequest(\n `${DISCORD_API}/channels/${ref.channelId}/messages?after=${ref.messageId}&limit=10`,\n 'GET', undefined, 'Bot', token, 'Discord API',\n ) as unknown[];\n\n if (!Array.isArray(messages)) return null;\n\n const replies = messages.filter((m) => {\n const msg = m as Record<string, unknown>;\n const author = msg['author'] as Record<string, unknown> | undefined;\n const msgRef = msg['message_reference'] as Record<string, unknown> | undefined;\n return author?.['id'] && author['id'] !== botUserId && msgRef?.['message_id'] === ref.messageId && msg['content'];\n });\n\n if (replies.length === 0) return null;\n const first = replies[0] as Record<string, unknown>;\n return parseTextReply(String(first['content']), prompt.questions);\n}\n\nasync function discordAcknowledge(ref: RemotePromptRef, token: string): Promise<void> {\n try {\n await apiRequest(\n `${DISCORD_API}/channels/${ref.channelId}/messages/${ref.messageId}/reactions/${encodeURIComponent('✅')}/@me`,\n 'PUT', undefined, 'Bot', token, 'Discord API',\n );\n } catch { /* best-effort */ }\n}\n\n// --- Slack ---\n\nasync function slackValidate(token: string): Promise<string> {\n const res = await apiRequest(`${SLACK_API}/auth.test`, 'GET', undefined, 'Bearer', token, 'Slack API') as Record<string, unknown>;\n if (!res['ok']) throw new Error(`Slack auth failed: ${res['error'] ?? 'invalid token'}`);\n return String(res['user_id'] ?? '');\n}\n\nasync function slackSend(prompt: RemotePrompt, token: string, channelId: string): Promise<DispatchResult> {\n const res = await apiRequest(\n `${SLACK_API}/chat.postMessage`,\n 'POST',\n { channel: channelId, text: 'GSD needs your input', blocks: formatForSlack(prompt) },\n 'Bearer', token, 'Slack API',\n ) as Record<string, unknown>;\n\n if (!res['ok']) throw new Error(`Slack postMessage failed: ${res['error'] ?? 'unknown'}`);\n\n const ts = String(res['ts']);\n const channel = String(res['channel']);\n\n if (prompt.questions.length === 1) {\n const reactionNames = SLACK_NUMBER_REACTION_NAMES.slice(0, prompt.questions[0].options.length);\n for (const name of reactionNames) {\n try {\n await apiRequest(`${SLACK_API}/reactions.add`, 'POST', { channel, timestamp: ts, name }, 'Bearer', token, 'Slack API');\n } catch { /* best-effort */ }\n }\n }\n\n return {\n ref: {\n id: prompt.id,\n channel: 'slack',\n messageId: ts,\n threadTs: ts,\n channelId: channel,\n threadUrl: `https://slack.com/archives/${channel}/p${ts.replace('.', '')}`,\n },\n };\n}\n\nasync function slackPoll(prompt: RemotePrompt, ref: RemotePromptRef, token: string, botUserId: string): Promise<RemoteAnswer | null> {\n // Check reactions for single-question prompts\n if (prompt.questions.length === 1) {\n const qs = new URLSearchParams({ channel: ref.channelId, timestamp: ref.messageId, full: 'true' }).toString();\n const res = await apiRequest(`${SLACK_API}/reactions.get?${qs}`, 'GET', undefined, 'Bearer', token, 'Slack API') as Record<string, unknown>;\n\n if (res['ok']) {\n const message = (res['message'] ?? {}) as { reactions?: Array<{ name?: string; count?: number; users?: string[] }> };\n const reactions = Array.isArray(message.reactions) ? message.reactions : [];\n const picked = reactions\n .filter((r) => r.name && SLACK_NUMBER_REACTION_NAMES.includes(r.name))\n .filter((r) => {\n const count = Number(r.count ?? 0);\n const users = Array.isArray(r.users) ? r.users.map(String) : [];\n const botIncluded = botUserId ? users.includes(botUserId) : false;\n return count > (botIncluded ? 1 : 0);\n })\n .map((r) => String(r.name));\n\n if (picked.length > 0) return parseSlackReactions(picked, prompt.questions);\n }\n }\n\n // Check thread replies\n const qs = new URLSearchParams({ channel: ref.channelId, ts: ref.threadTs!, limit: '20' }).toString();\n const res = await apiRequest(`${SLACK_API}/conversations.replies?${qs}`, 'GET', undefined, 'Bearer', token, 'Slack API') as Record<string, unknown>;\n\n if (!res['ok']) return null;\n\n const messages = (res['messages'] ?? []) as Array<{ user?: string; text?: string; ts: string }>;\n const userReplies = messages.filter((m) => m.ts !== ref.threadTs && m.user && m.user !== botUserId && m.text);\n if (userReplies.length === 0) return null;\n\n return parseTextReply(String(userReplies[0].text), prompt.questions);\n}\n\nasync function slackAcknowledge(ref: RemotePromptRef, token: string): Promise<void> {\n try {\n await apiRequest(\n `${SLACK_API}/reactions.add`,\n 'POST',\n { channel: ref.channelId, timestamp: ref.messageId, name: 'white_check_mark' },\n 'Bearer', token, 'Slack API',\n );\n } catch { /* best-effort */ }\n}\n\n// --- Telegram ---\n\nasync function telegramValidate(token: string): Promise<number> {\n const res = await apiRequest(`${TELEGRAM_API}/bot${token}/getMe`, 'GET', undefined, 'Bearer', token, 'Telegram API') as Record<string, unknown>;\n const result = res['result'] as Record<string, unknown> | undefined;\n if (!res['ok'] || !result?.['id']) throw new Error('Telegram auth failed: invalid bot token');\n return result['id'] as number;\n}\n\nasync function telegramSend(prompt: RemotePrompt, token: string, chatId: string): Promise<DispatchResult> {\n const payload = formatForTelegram(prompt);\n const params: Record<string, unknown> = { chat_id: chatId, text: payload.text, parse_mode: payload.parse_mode };\n if (payload.reply_markup) params['reply_markup'] = payload.reply_markup;\n\n const res = await apiRequest(`${TELEGRAM_API}/bot${token}/sendMessage`, 'POST', params, 'Bearer', token, 'Telegram API') as Record<string, unknown>;\n const result = res['result'] as Record<string, unknown> | undefined;\n if (!res['ok'] || !result?.['message_id']) throw new Error(`Telegram sendMessage failed: ${JSON.stringify(res)}`);\n\n const messageId = String(result['message_id']);\n // Build public URL only for public channels (negative IDs are private groups)\n const isPublic = !chatId.startsWith('-');\n const messageUrl = isPublic ? `https://t.me/${chatId.replace('@', '')}/${messageId}` : undefined;\n\n return { ref: { id: prompt.id, channel: 'telegram', messageId, channelId: chatId, threadUrl: messageUrl } };\n}\n\nasync function telegramPoll(\n prompt: RemotePrompt,\n ref: RemotePromptRef,\n token: string,\n botUserId: number,\n lastUpdateId: { value: number },\n): Promise<RemoteAnswer | null> {\n const params: Record<string, unknown> = {\n offset: lastUpdateId.value + 1,\n timeout: 0,\n allowed_updates: ['message', 'callback_query'],\n };\n\n const res = await apiRequest(`${TELEGRAM_API}/bot${token}/getUpdates`, 'POST', params, 'Bearer', token, 'Telegram API') as Record<string, unknown>;\n if (!res['ok'] || !Array.isArray(res['result'])) return null;\n\n for (const update of res['result'] as Record<string, unknown>[]) {\n if ((update['update_id'] as number) > lastUpdateId.value) {\n lastUpdateId.value = update['update_id'] as number;\n }\n\n // Callback query (inline keyboard button press)\n if (update['callback_query']) {\n const cq = update['callback_query'] as Record<string, unknown>;\n const msg = cq['message'] as Record<string, unknown> | undefined;\n const from = cq['from'] as Record<string, unknown> | undefined;\n if (msg && String((msg['chat'] as Record<string, unknown>)?.['id']) === ref.channelId &&\n String(msg['message_id']) === ref.messageId && from?.['id'] !== botUserId) {\n // Dismiss loading spinner\n try {\n await apiRequest(`${TELEGRAM_API}/bot${token}/answerCallbackQuery`, 'POST', { callback_query_id: cq['id'] }, 'Bearer', token, 'Telegram API');\n } catch { /* best-effort */ }\n const callbackData = cq['data'] ? String(cq['data']) : null;\n if (callbackData) {\n const parsed = parseTelegramCallbackData(callbackData, prompt.questions, prompt.id);\n if (parsed) return parsed;\n }\n }\n }\n\n // Text message reply\n if (update['message']) {\n const msg = update['message'] as Record<string, unknown>;\n const from = msg['from'] as Record<string, unknown> | undefined;\n if (String((msg['chat'] as Record<string, unknown>)?.['id']) === ref.channelId &&\n from?.['id'] !== botUserId && msg['text']) {\n return parseTextReply(String(msg['text']), prompt.questions);\n }\n }\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Polling loop\n// ---------------------------------------------------------------------------\n\nfunction sleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve) => {\n if (signal?.aborted) return resolve();\n const timer = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n const onAbort = () => { clearTimeout(timer); resolve(); };\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\ninterface ChannelState {\n botUserId: string | number;\n guildId?: string | null; // Discord only\n lastUpdateId?: { value: number }; // Telegram only\n}\n\nasync function pollUntilDone(\n config: ResolvedConfig,\n prompt: RemotePrompt,\n ref: RemotePromptRef,\n state: ChannelState,\n signal?: AbortSignal,\n): Promise<RemoteAnswer | null> {\n while (Date.now() < prompt.timeoutAt && !signal?.aborted) {\n try {\n let answer: RemoteAnswer | null = null;\n\n if (config.channel === 'discord') {\n answer = await discordPoll(prompt, ref, config.token, String(state.botUserId));\n } else if (config.channel === 'slack') {\n answer = await slackPoll(prompt, ref, config.token, String(state.botUserId));\n } else {\n answer = await telegramPoll(prompt, ref, config.token, state.botUserId as number, state.lastUpdateId!);\n }\n\n if (answer) return answer;\n } catch {\n // Non-fatal poll error — wait and retry\n }\n\n await sleep(prompt.pollIntervalMs, signal);\n }\n\n return null;\n}\n\n// ---------------------------------------------------------------------------\n// Public entry point\n// ---------------------------------------------------------------------------\n\nfunction buildPrompt(questions: RemoteQuestion[], config: ResolvedConfig): RemotePrompt {\n const createdAt = Date.now();\n return {\n id: randomUUID(),\n channel: config.channel,\n createdAt,\n timeoutAt: createdAt + config.timeoutMs,\n pollIntervalMs: config.pollIntervalMs,\n context: { source: 'ask_user_questions' },\n questions: questions.map((q) => ({\n id: q.id,\n header: q.header,\n question: q.question,\n options: q.options,\n allowMultiple: q.allowMultiple ?? false,\n })),\n };\n}\n\nfunction formatForTool(answer: RemoteAnswer): Record<string, { answers: string[] }> {\n const out: Record<string, { answers: string[] }> = {};\n for (const [id, data] of Object.entries(answer.answers)) {\n const list = [...data.answers];\n if (data.user_note) list.push(`user_note: ${data.user_note}`);\n out[id] = { answers: list };\n }\n return out;\n}\n\n/**\n * Dispatch questions to the configured remote channel and wait for a response.\n *\n * Returns null when no remote channel is configured.\n * Returns a tool result shaped like { content, details } on success or\n * timeout — callers should check details.timed_out before trusting the result.\n */\nexport async function tryRemoteQuestions(\n questions: RemoteQuestion[],\n signal?: AbortSignal,\n): Promise<RemoteToolResult | null> {\n const config = resolveRemoteConfig();\n if (!config) return null;\n\n const prompt = buildPrompt(questions, config);\n\n // Validate auth and send the prompt\n let ref: RemotePromptRef;\n let state: ChannelState;\n\n try {\n if (config.channel === 'discord') {\n const { botUserId, guildId } = await discordValidate(config.token, config.channelId);\n state = { botUserId, guildId };\n const dispatch = await discordSend(prompt, config.token, config.channelId, guildId);\n ref = dispatch.ref;\n } else if (config.channel === 'slack') {\n const botUserId = await slackValidate(config.token);\n state = { botUserId };\n const dispatch = await slackSend(prompt, config.token, config.channelId);\n ref = dispatch.ref;\n } else {\n const botUserId = await telegramValidate(config.token);\n state = { botUserId, lastUpdateId: { value: 0 } };\n const dispatch = await telegramSend(prompt, config.token, config.channelId);\n ref = dispatch.ref;\n }\n } catch (err) {\n return {\n content: [{ type: 'text', text: `Remote questions failed (${config.channel}): ${(err as Error).message}` }],\n details: { remote: true, channel: config.channel, error: true, status: 'failed' },\n };\n }\n\n const answer = await pollUntilDone(config, prompt, ref, state, signal);\n\n if (!answer) {\n const timedOut = !signal?.aborted;\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n timed_out: timedOut,\n channel: config.channel,\n prompt_id: prompt.id,\n timeout_minutes: config.timeoutMs / 60000,\n thread_url: ref.threadUrl ?? null,\n message: `User did not respond within ${config.timeoutMs / 60000} minutes.`,\n }),\n }],\n details: {\n remote: true,\n channel: config.channel,\n timed_out: timedOut,\n promptId: prompt.id,\n threadUrl: ref.threadUrl ?? null,\n status: signal?.aborted ? 'cancelled' : 'timed_out',\n },\n };\n }\n\n // Best-effort acknowledgement\n try {\n if (config.channel === 'discord') await discordAcknowledge(ref, config.token);\n else if (config.channel === 'slack') await slackAcknowledge(ref, config.token);\n } catch { /* best-effort */ }\n\n return {\n content: [{ type: 'text', text: JSON.stringify({ answers: formatForTool(answer) }) }],\n details: {\n remote: true,\n channel: config.channel,\n timed_out: false,\n promptId: prompt.id,\n threadUrl: ref.threadUrl ?? null,\n questions,\n status: 'answered',\n },\n };\n}\n"]}
@@ -11,6 +11,13 @@
11
11
  * src/mcp-server.ts in the main package).
12
12
  */
13
13
  import type { SessionManager } from './session-manager.js';
14
+ /**
15
+ * Race a promise against a timeout. Rejects with a typed error on timeout so
16
+ * callers can return a specific MCP error response rather than hanging.
17
+ *
18
+ * @param timeoutMs - override for testing; defaults to ELICIT_TIMEOUT_MS
19
+ */
20
+ export declare function withElicitTimeout<T>(promise: Promise<T>, label: string, timeoutMs?: number): Promise<T>;
14
21
  interface ElicitRequestFormParams {
15
22
  mode?: 'form';
16
23
  message: string;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AA4I3D,UAAU,uBAAuB;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE;QACf,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACpE;AAED,UAAU,iBAAiB;IACzB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,EAAE,YAAY,KAAK,OAAO,CAAC,OAAO,CAAC,GACjF,OAAO,CAAC;IACX,MAAM,EAAE;QACN,WAAW,CACT,MAAM,EAAE,6BAA6B,GAAG,uBAAuB,EAC/D,OAAO,CAAC,EAAE,OAAO,GAChB,OAAO,CAAC,4BAA4B,CAAC,CAAC;KAC1C,CAAC;IACF,OAAO,CAAC,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3C,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB;AAED,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,UAAU,eAAe;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,qBAAqB,EAAE,CAAC;IACjC,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAMD,KAAK,4BAA4B,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,EAAE,CAAC;AAEzE,UAAU,4BAA4B;IACpC,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,QAAQ,CAAC;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,4BAA4B,CAAC,CAAC;CACxD;AAED,UAAU,6BAA6B;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE;QACf,IAAI,EAAE,QAAQ,CAAC;QACf,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC;QACpD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;CACH;AAiCD,wBAAgB,kCAAkC,CAAC,SAAS,EAAE,eAAe,EAAE,GAAG,6BAA6B,CAiD9G;AAED,wBAAgB,kCAAkC,CAChD,SAAS,EAAE,eAAe,EAAE,EAC5B,MAAM,EAAE,4BAA4B,GACnC,MAAM,CAkBR;AAMD;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,cAAc,EAAE,cAAc,GAAG,OAAO,CAAC;IAC7E,MAAM,EAAE,iBAAiB,CAAC;CAC3B,CAAC,CAgiBD"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -13,6 +13,7 @@
13
13
  import { readFile, readdir, stat } from 'node:fs/promises';
14
14
  import { join, resolve } from 'node:path';
15
15
  import { z } from 'zod';
16
+ import { isRemoteConfigured, tryRemoteQuestions } from './remote-questions.js';
16
17
  import { readProgress } from './readers/state.js';
17
18
  import { readRoadmap } from './readers/roadmap.js';
18
19
  import { readHistory } from './readers/metrics.js';
@@ -29,6 +30,26 @@ import { applySecrets, checkExistingEnvKeys, detectDestination } from './env-wri
29
30
  const MCP_PKG = '@modelcontextprotocol/sdk';
30
31
  const SERVER_NAME = 'gsd';
31
32
  const SERVER_VERSION = '2.53.0';
33
+ /** User-interaction timeout — generous but bounded so elicitation can't hang indefinitely (#4586). */
34
+ const ELICIT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes
35
+ /**
36
+ * Race a promise against a timeout. Rejects with a typed error on timeout so
37
+ * callers can return a specific MCP error response rather than hanging.
38
+ *
39
+ * @param timeoutMs - override for testing; defaults to ELICIT_TIMEOUT_MS
40
+ */
41
+ export async function withElicitTimeout(promise, label, timeoutMs = ELICIT_TIMEOUT_MS) {
42
+ let timer;
43
+ const timeout = new Promise((_, reject) => {
44
+ timer = setTimeout(() => reject(new Error(`${label} timed out after ${timeoutMs / 60000} minutes — no user response received`)), timeoutMs);
45
+ });
46
+ try {
47
+ return await Promise.race([promise, timeout]);
48
+ }
49
+ finally {
50
+ clearTimeout(timer);
51
+ }
52
+ }
32
53
  // ---------------------------------------------------------------------------
33
54
  // Tool result helpers
34
55
  // ---------------------------------------------------------------------------
@@ -375,13 +396,29 @@ export async function createMcpServer(sessionManager) {
375
396
  })).describe('Provide 2-3 mutually exclusive choices. Put the recommended option first and suffix its label with "(Recommended)". Do not include an "Other" option for single-select questions.'),
376
397
  allowMultiple: z.boolean().optional().describe('If true, the user can select multiple options. No "None of the above" option is added.'),
377
398
  })).describe('Questions to show the user. Prefer 1 and do not exceed 3.'),
378
- }, async (args) => {
399
+ }, async (args, extra) => {
379
400
  const { questions } = args;
380
401
  try {
381
402
  const validationError = validateAskUserQuestionsPayload(questions);
382
403
  if (validationError)
383
404
  return errorContent(validationError);
384
- const elicitation = await server.server.elicitInput(buildAskUserQuestionsElicitRequest(questions));
405
+ // Delegate to remote-questions manager when a remote channel is configured
406
+ // (Discord, Slack, Telegram). This path is the only one reachable for
407
+ // Claude Code-under-gsd sessions, which have no local TUI.
408
+ if (isRemoteConfigured()) {
409
+ const remoteResult = await tryRemoteQuestions(questions, extra?.signal);
410
+ if (remoteResult) {
411
+ const details = remoteResult.details;
412
+ if (details?.['timed_out'] || details?.['error']) {
413
+ // Surface timeout/error as plain text so the LLM knows to retry
414
+ return textContent(remoteResult.content[0]?.text ?? 'Remote questions timed out or failed');
415
+ }
416
+ return textContent(remoteResult.content[0]?.text ?? '');
417
+ }
418
+ // resolveRemoteConfig() returned null between isRemoteConfigured() and
419
+ // tryRemoteQuestions() (e.g. env var was cleared) — fall through to local.
420
+ }
421
+ const elicitation = await withElicitTimeout(server.server.elicitInput(buildAskUserQuestionsElicitRequest(questions)), 'ask_user_questions');
385
422
  if (elicitation.action !== 'accept' || !elicitation.content) {
386
423
  return textContent('ask_user_questions was cancelled before receiving a response');
387
424
  }
@@ -439,14 +476,14 @@ export async function createMcpServer(sessionManager) {
439
476
  // Don't mark as required — empty string = skip
440
477
  }
441
478
  // (3) Elicit input from the MCP client
442
- const elicitation = await server.server.elicitInput({
479
+ const elicitation = await withElicitTimeout(server.server.elicitInput({
443
480
  message: `Enter values for ${pendingKeys.length} environment variable(s). Values are written directly to the project and never shown to the AI.`,
444
481
  requestedSchema: {
445
482
  type: 'object',
446
483
  properties,
447
484
  required,
448
485
  },
449
- });
486
+ }), 'secure_env_collect');
450
487
  if (elicitation.action !== 'accept' || !elicitation.content) {
451
488
  return textContent('secure_env_collect was cancelled by user.');
452
489
  }
@@ -1 +1 @@
1
- {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP Server — registers GSD orchestration, project-state, and workflow tools.\n *\n * Session tools (6): gsd_execute, gsd_status, gsd_result, gsd_cancel, gsd_query, gsd_resolve_blocker\n * Interactive tools (2): ask_user_questions, secure_env_collect via MCP form elicitation\n * Read-only tools (6): gsd_progress, gsd_roadmap, gsd_history, gsd_doctor, gsd_captures, gsd_knowledge\n * Workflow tools (29): headless-safe planning, metadata persistence, replanning, completion, validation, reassessment, gate result, status, and journal tools\n *\n * Uses dynamic imports for @modelcontextprotocol/sdk because TS Node16\n * cannot resolve the SDK's subpath exports statically (same pattern as\n * src/mcp-server.ts in the main package).\n */\n\nimport { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { z } from 'zod';\nimport type { SessionManager } from './session-manager.js';\nimport { readProgress } from './readers/state.js';\nimport { readRoadmap } from './readers/roadmap.js';\nimport { readHistory } from './readers/metrics.js';\nimport { readCaptures } from './readers/captures.js';\nimport { readKnowledge } from './readers/knowledge.js';\nimport { buildGraph, writeGraph, writeSnapshot, graphStatus, graphQuery, graphDiff } from './readers/graph.js';\nimport { resolveGsdRoot } from './readers/paths.js';\nimport { runDoctorLite } from './readers/doctor-lite.js';\nimport { registerWorkflowTools, validateProjectDir } from './workflow-tools.js';\nimport { applySecrets, checkExistingEnvKeys, detectDestination } from './env-writer.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MCP_PKG = '@modelcontextprotocol/sdk';\nconst SERVER_NAME = 'gsd';\nconst SERVER_VERSION = '2.53.0';\n\n// ---------------------------------------------------------------------------\n// Tool result helpers\n// ---------------------------------------------------------------------------\n\n/** Wrap a JSON-serializable value as MCP tool content. */\nfunction jsonContent(data: unknown): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }] };\n}\n\n/** Return an MCP error response. */\nfunction errorContent(message: string): { isError: true; content: Array<{ type: 'text'; text: string }> } {\n return { isError: true, content: [{ type: 'text' as const, text: message }] };\n}\n\n/** Return raw text content without JSON wrapping. */\nfunction textContent(text: string): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text }] };\n}\n\n// ---------------------------------------------------------------------------\n// gsd_query filesystem reader\n// ---------------------------------------------------------------------------\n\n/**\n * Normalized query categories for {@link readProjectState}.\n *\n * Maps user-supplied query strings (or empty) to the set of fields we return.\n * Accepts common synonyms so the MCP client can pass intuitive values.\n */\nconst QUERY_FIELDS = {\n all: ['state', 'project', 'requirements', 'milestones'] as const,\n state: ['state'] as const,\n status: ['state'] as const,\n project: ['project'] as const,\n requirements: ['requirements'] as const,\n milestones: ['milestones'] as const,\n} as const;\n\ntype QueryCategory = keyof typeof QUERY_FIELDS;\ntype ProjectStateField = (typeof QUERY_FIELDS)[QueryCategory][number];\n\nfunction normalizeQuery(query: string | undefined): QueryCategory {\n const key = (query ?? 'all').trim().toLowerCase();\n if (key in QUERY_FIELDS) return key as QueryCategory;\n return 'all';\n}\n\nasync function readProjectState(projectDir: string, query: string | undefined): Promise<Record<string, unknown>> {\n const gsdDir = join(resolve(projectDir), '.gsd');\n const category = normalizeQuery(query);\n const wanted = new Set<ProjectStateField>(QUERY_FIELDS[category]);\n\n const result: Record<string, unknown> = {\n projectDir: resolve(projectDir),\n query: category,\n };\n\n if (wanted.has('state')) {\n try {\n result.state = await readFile(join(gsdDir, 'STATE.md'), 'utf-8');\n } catch {\n result.state = null;\n }\n }\n\n if (wanted.has('project')) {\n try {\n result.project = await readFile(join(gsdDir, 'PROJECT.md'), 'utf-8');\n } catch {\n result.project = null;\n }\n }\n\n if (wanted.has('requirements')) {\n try {\n result.requirements = await readFile(join(gsdDir, 'REQUIREMENTS.md'), 'utf-8');\n } catch {\n result.requirements = null;\n }\n }\n\n if (wanted.has('milestones')) {\n const milestonesDir = join(gsdDir, 'milestones');\n try {\n const entries = await readdir(milestonesDir, { withFileTypes: true });\n const milestones: Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }> = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const mDir = join(milestonesDir, entry.name);\n const hasRoadmap = await fileExists(join(mDir, `${entry.name}-ROADMAP.md`));\n const hasSummary = await fileExists(join(mDir, `${entry.name}-SUMMARY.md`));\n milestones.push({ id: entry.name, hasRoadmap, hasSummary });\n }\n result.milestones = milestones;\n } catch {\n result.milestones = [];\n }\n }\n\n return result;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// MCP Server type — minimal interface for the dynamically-imported McpServer\n// ---------------------------------------------------------------------------\n\ninterface ElicitResult {\n action: 'accept' | 'decline' | 'cancel';\n content?: Record<string, string | number | boolean | string[]>;\n}\n\ninterface ElicitRequestFormParams {\n mode?: 'form';\n message: string;\n requestedSchema: {\n type: 'object';\n properties: Record<string, Record<string, unknown>>;\n required?: string[];\n };\n}\n\n/**\n * Handler extra — the second argument passed by McpServer.tool handlers.\n * Contains an AbortSignal scoped to the JSON-RPC request (cancelled when\n * the client cancels the `tools/call`) plus other per-request metadata.\n * Tools that can actually be stopped mid-flight should honour `signal`.\n */\nexport interface McpToolExtra {\n signal?: AbortSignal;\n requestId?: string | number;\n sendNotification?: (notification: unknown) => void | Promise<void>;\n}\n\ninterface McpServerInstance {\n tool(\n name: string,\n description: string,\n params: Record<string, unknown>,\n handler: (args: Record<string, unknown>, extra?: McpToolExtra) => Promise<unknown>,\n ): unknown;\n server: {\n elicitInput(\n params: AskUserQuestionsElicitRequest | ElicitRequestFormParams,\n options?: unknown,\n ): Promise<AskUserQuestionsElicitResult>;\n };\n connect(transport: unknown): Promise<void>;\n close(): Promise<void>;\n}\n\ninterface AskUserQuestionOption {\n label: string;\n description: string;\n}\n\ninterface AskUserQuestion {\n id: string;\n header: string;\n question: string;\n options: AskUserQuestionOption[];\n allowMultiple?: boolean;\n}\n\ninterface AskUserQuestionsParams {\n questions: AskUserQuestion[];\n}\n\ntype AskUserQuestionsContentValue = string | number | boolean | string[];\n\ninterface AskUserQuestionsElicitResult {\n action: 'accept' | 'decline' | 'cancel';\n content?: Record<string, AskUserQuestionsContentValue>;\n}\n\ninterface AskUserQuestionsElicitRequest {\n mode: 'form';\n message: string;\n requestedSchema: {\n type: 'object';\n properties: Record<string, Record<string, unknown>>;\n required?: string[];\n };\n}\n\nconst OTHER_OPTION_LABEL = 'None of the above';\n\nfunction normalizeAskUserQuestionsNote(value: AskUserQuestionsContentValue | undefined): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction normalizeAskUserQuestionsAnswers(\n value: AskUserQuestionsContentValue | undefined,\n allowMultiple: boolean,\n): string[] {\n if (allowMultiple) {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n }\n\n return typeof value === 'string' && value.length > 0 ? [value] : [];\n}\n\nfunction validateAskUserQuestionsPayload(questions: AskUserQuestion[]): string | null {\n if (questions.length === 0 || questions.length > 3) {\n return 'Error: questions must contain 1-3 items';\n }\n\n for (const question of questions) {\n if (!question.options || question.options.length === 0) {\n return `Error: ask_user_questions requires non-empty options for every question (question \"${question.id}\" has none)`;\n }\n }\n\n return null;\n}\n\nexport function buildAskUserQuestionsElicitRequest(questions: AskUserQuestion[]): AskUserQuestionsElicitRequest {\n const properties: Record<string, Record<string, unknown>> = {};\n const required = questions.map((question) => question.id);\n\n for (const question of questions) {\n if (question.allowMultiple) {\n properties[question.id] = {\n type: 'array',\n title: question.header,\n description: question.question,\n minItems: 1,\n maxItems: question.options.length,\n items: {\n anyOf: question.options.map((option) => ({\n const: option.label,\n title: option.label,\n })),\n },\n };\n continue;\n }\n\n properties[question.id] = {\n type: 'string',\n title: question.header,\n description: question.question,\n oneOf: [...question.options, { label: OTHER_OPTION_LABEL, description: 'Choose this when the listed options do not fit.' }].map((option) => ({\n const: option.label,\n title: option.label,\n })),\n };\n\n properties[`${question.id}__note`] = {\n type: 'string',\n title: `${question.header} Note`,\n description: `Optional note for \"${OTHER_OPTION_LABEL}\".`,\n maxLength: 500,\n };\n }\n\n return {\n mode: 'form',\n message: 'Please answer the following question(s). For single-select questions, choose \"None of the above\" and add a note if the provided options do not fit.',\n requestedSchema: {\n type: 'object',\n properties,\n required,\n },\n };\n}\n\nexport function formatAskUserQuestionsElicitResult(\n questions: AskUserQuestion[],\n result: AskUserQuestionsElicitResult,\n): string {\n const answers: Record<string, { answers: string[] }> = {};\n const content = result.content ?? {};\n\n for (const question of questions) {\n const answerList = normalizeAskUserQuestionsAnswers(content[question.id], !!question.allowMultiple);\n\n if (!question.allowMultiple && answerList[0] === OTHER_OPTION_LABEL) {\n const note = normalizeAskUserQuestionsNote(content[`${question.id}__note`]);\n if (note) {\n answerList.push(`user_note: ${note}`);\n }\n }\n\n answers[question.id] = { answers: answerList };\n }\n\n return JSON.stringify({ answers });\n}\n\n// ---------------------------------------------------------------------------\n// createMcpServer\n// ---------------------------------------------------------------------------\n\n/**\n * Create and configure an MCP server with session, read-only, and workflow tools.\n *\n * Returns the McpServer instance — call `connect(transport)` to start serving.\n * Uses dynamic imports for the MCP SDK to avoid TS subpath resolution issues.\n */\nexport async function createMcpServer(sessionManager: SessionManager): Promise<{\n server: McpServerInstance;\n}> {\n // Dynamic import — same workaround as src/mcp-server.ts\n const mcpMod = await import(`${MCP_PKG}/server/mcp.js`);\n const McpServer = mcpMod.McpServer;\n\n const server: McpServerInstance = new McpServer(\n { name: SERVER_NAME, version: SERVER_VERSION },\n { capabilities: { tools: {}, elicitation: {} } },\n );\n\n // -----------------------------------------------------------------------\n // gsd_execute — start a new GSD auto-mode session.\n //\n // If the JSON-RPC request is aborted while the session is starting (or\n // immediately after), we cancel the session so we don't leak a background\n // RpcClient process. Once the session is running the caller should use\n // `gsd_cancel` to stop it via sessionId.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_execute',\n 'Start a GSD auto-mode session for a project directory. Returns a sessionId for tracking.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n command: z.string().optional().describe('Command to send (default: \"/gsd auto\")'),\n model: z.string().optional().describe('Model ID override'),\n bare: z.boolean().optional().describe('Run in bare mode (skip user config)'),\n },\n async (args: Record<string, unknown>, extra?: McpToolExtra) => {\n const { projectDir, command, model, bare } = args as {\n projectDir: string; command?: string; model?: string; bare?: boolean;\n };\n try {\n const sessionId = await sessionManager.startSession(projectDir, { command, model, bare });\n\n // If the client aborted while startSession was running, cancel the\n // newly-created session rather than leaving an orphaned process.\n if (extra?.signal?.aborted) {\n await sessionManager.cancelSession(sessionId).catch(() => { /* swallow */ });\n return errorContent('gsd_execute aborted by client before returning');\n }\n\n return jsonContent({ sessionId, status: 'started' });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_status — poll session status\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_status',\n 'Get the current status of a GSD session including progress, recent events, and pending blockers.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n const session = sessionManager.getSession(sessionId);\n if (!session) return errorContent(`Session not found: ${sessionId}`);\n\n const durationMs = Date.now() - session.startTime;\n const toolCallCount = session.events.filter(\n (e) => (e as Record<string, unknown>).type === 'tool_use' ||\n (e as Record<string, unknown>).type === 'tool_execution_start'\n ).length;\n\n return jsonContent({\n status: session.status,\n progress: {\n eventCount: session.events.length,\n toolCalls: toolCallCount,\n },\n recentEvents: session.events.slice(-10),\n pendingBlocker: session.pendingBlocker\n ? {\n id: session.pendingBlocker.id,\n method: session.pendingBlocker.method,\n message: session.pendingBlocker.message,\n }\n : null,\n cost: session.cost,\n durationMs,\n });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_result — get accumulated session result\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_result',\n 'Get the result of a GSD session. Returns partial results if the session is still running.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n const result = sessionManager.getResult(sessionId);\n return jsonContent(result);\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_cancel — cancel a running session\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_cancel',\n 'Cancel a running GSD session. Aborts the current operation and stops the process.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n await sessionManager.cancelSession(sessionId);\n return jsonContent({ cancelled: true });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_query — read project state from filesystem (no session needed).\n //\n // `query` is optional: when omitted the tool returns all fields (STATE.md,\n // PROJECT.md, requirements, milestone listing). Accepted narrow values:\n // \"state\" / \"status\", \"project\", \"requirements\", \"milestones\", \"all\".\n // Unknown values fall back to \"all\" for forward-compatibility.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_query',\n 'Query GSD project state from the filesystem. By default returns STATE.md, PROJECT.md, requirements, and milestone listing. Pass `query` to narrow the response (accepted: \"state\"/\"status\", \"project\", \"requirements\", \"milestones\", \"all\"). Does not require an active session.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n query: z\n .enum(['all', 'state', 'status', 'project', 'requirements', 'milestones'])\n .optional()\n .describe('Narrow the response to a single field (default: \"all\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, query } = args as { projectDir: string; query?: string };\n try {\n const validated = validateProjectDir(projectDir);\n const state = await readProjectState(validated, query);\n return jsonContent(state);\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_resolve_blocker — resolve a pending blocker\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_resolve_blocker',\n 'Resolve a pending blocker in a GSD session by sending a response to the UI request.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n response: z.string().describe('Response to send for the pending blocker'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId, response } = args as { sessionId: string; response: string };\n try {\n await sessionManager.resolveBlocker(sessionId, response);\n return jsonContent({ resolved: true });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // ask_user_questions — structured user input via MCP form elicitation\n // -----------------------------------------------------------------------\n server.tool(\n 'ask_user_questions',\n 'Request user input for one to three short questions and wait for the response. Single-select questions include a free-form \"None of the above\" path. Multi-select questions allow multiple choices.',\n {\n questions: z.array(z.object({\n id: z.string().describe('Stable identifier for mapping answers (snake_case)'),\n header: z.string().describe('Short header label shown in the UI (12 or fewer chars)'),\n question: z.string().describe('Single-sentence prompt shown to the user'),\n options: z.array(z.object({\n label: z.string().describe('User-facing label (1-5 words)'),\n description: z.string().describe('One short sentence explaining impact/tradeoff if selected'),\n })).describe('Provide 2-3 mutually exclusive choices. Put the recommended option first and suffix its label with \"(Recommended)\". Do not include an \"Other\" option for single-select questions.'),\n allowMultiple: z.boolean().optional().describe('If true, the user can select multiple options. No \"None of the above\" option is added.'),\n })).describe('Questions to show the user. Prefer 1 and do not exceed 3.'),\n },\n async (args: Record<string, unknown>) => {\n const { questions } = args as unknown as AskUserQuestionsParams;\n try {\n const validationError = validateAskUserQuestionsPayload(questions);\n if (validationError) return errorContent(validationError);\n\n const elicitation = await server.server.elicitInput(buildAskUserQuestionsElicitRequest(questions));\n if (elicitation.action !== 'accept' || !elicitation.content) {\n return textContent('ask_user_questions was cancelled before receiving a response');\n }\n\n return textContent(formatAskUserQuestionsElicitResult(questions, elicitation));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // secure_env_collect — collect secrets via MCP form elicitation\n // -----------------------------------------------------------------------\n server.tool(\n 'secure_env_collect',\n 'Collect environment variables securely via form input. Values are written directly to .env (or Vercel/Convex) and NEVER appear in tool output — only key names and applied/skipped status are returned. Use this instead of asking users to manually edit .env files or paste secrets into chat.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n keys: z.array(z.object({\n key: z.string().describe('Env var name, e.g. OPENAI_API_KEY'),\n hint: z.string().optional().describe('Format hint shown to user, e.g. \"starts with sk-\"'),\n guidance: z.array(z.string()).optional().describe('Step-by-step instructions for obtaining this key'),\n })).min(1).describe('Environment variables to collect'),\n destination: z.enum(['dotenv', 'vercel', 'convex']).optional().describe('Where to write secrets. Auto-detected from project files if omitted.'),\n envFilePath: z.string().optional().describe('Path to .env file (dotenv only). Defaults to .env in projectDir.'),\n environment: z.enum(['development', 'preview', 'production']).optional().describe('Target environment (vercel/convex only)'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, keys, destination, envFilePath, environment } = args as {\n projectDir: string;\n keys: Array<{ key: string; hint?: string; guidance?: string[] }>;\n destination?: 'dotenv' | 'vercel' | 'convex';\n envFilePath?: string;\n environment?: 'development' | 'preview' | 'production';\n };\n\n try {\n const resolvedProjectDir = validateProjectDir(projectDir);\n const resolvedEnvPath = resolve(resolvedProjectDir, envFilePath ?? '.env');\n\n // (1) Check which keys already exist\n const allKeyNames = keys.map((k) => k.key);\n const existingKeys = await checkExistingEnvKeys(allKeyNames, resolvedEnvPath);\n const existingSet = new Set(existingKeys);\n const pendingKeys = keys.filter((k) => !existingSet.has(k.key));\n\n // If all keys already exist, return immediately\n if (pendingKeys.length === 0) {\n const lines = existingKeys.map((k) => `• ${k}: already set`);\n return textContent(`All ${existingKeys.length} key(s) already set.\\n${lines.join('\\n')}`);\n }\n\n // (2) Build elicitation form — one string field per pending key\n const properties: Record<string, Record<string, unknown>> = {};\n const required: string[] = [];\n\n for (const item of pendingKeys) {\n const descParts: string[] = [];\n if (item.hint) descParts.push(`Format: ${item.hint}`);\n if (item.guidance && item.guidance.length > 0) {\n descParts.push('How to get this:');\n item.guidance.forEach((step, i) => descParts.push(`${i + 1}. ${step}`));\n }\n descParts.push('Leave empty to skip.');\n\n properties[item.key] = {\n type: 'string',\n title: item.key,\n description: descParts.join('\\n'),\n };\n // Don't mark as required — empty string = skip\n }\n\n // (3) Elicit input from the MCP client\n const elicitation = await server.server.elicitInput({\n message: `Enter values for ${pendingKeys.length} environment variable(s). Values are written directly to the project and never shown to the AI.`,\n requestedSchema: {\n type: 'object',\n properties,\n required,\n },\n });\n\n if (elicitation.action !== 'accept' || !elicitation.content) {\n return textContent('secure_env_collect was cancelled by user.');\n }\n\n // (4) Separate provided vs skipped from form response\n const provided: Array<{ key: string; value: string }> = [];\n const skipped: string[] = [];\n\n for (const item of pendingKeys) {\n const raw = elicitation.content[item.key];\n const value = typeof raw === 'string' ? raw.trim() : '';\n if (value.length > 0) {\n provided.push({ key: item.key, value });\n } else {\n skipped.push(item.key);\n }\n }\n\n // (5) Auto-detect destination if not specified\n const resolvedDestination = destination ?? detectDestination(resolvedProjectDir);\n\n // (6) Write secrets to destination\n const { applied, errors } = await applySecrets(provided, resolvedDestination, {\n envFilePath: resolvedEnvPath,\n environment,\n });\n\n // (7) Build result — NEVER include secret values\n const lines: string[] = [\n `destination: ${resolvedDestination}${!destination ? ' (auto-detected)' : ''}${environment ? ` (${environment})` : ''}`,\n ];\n for (const k of applied) lines.push(`✓ ${k}: applied`);\n for (const k of skipped) lines.push(`• ${k}: skipped`);\n for (const k of existingKeys) lines.push(`• ${k}: already set`);\n for (const e of errors) lines.push(`✗ ${e}`);\n\n return errors.length > 0 && applied.length === 0\n ? errorContent(lines.join('\\n'))\n : textContent(lines.join('\\n'));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // =======================================================================\n // READ-ONLY TOOLS — no session required, pure filesystem reads\n // =======================================================================\n\n // -----------------------------------------------------------------------\n // gsd_progress — structured project progress metrics\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_progress',\n 'Get structured project progress: active milestone/slice/task, phase, completion counts, blockers, and next action. No session required — reads directly from .gsd/ on disk.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir } = args as { projectDir: string };\n try {\n return jsonContent(readProgress(validateProjectDir(projectDir)));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_roadmap — milestone/slice/task structure with status\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_roadmap',\n 'Get the full project roadmap structure: milestones with their slices, tasks, status, risk, and dependencies. Optionally filter to a single milestone. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n milestoneId: z.string().optional().describe('Filter to a specific milestone (e.g. \"M001\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, milestoneId } = args as { projectDir: string; milestoneId?: string };\n try {\n return jsonContent(readRoadmap(validateProjectDir(projectDir), milestoneId));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_history — execution history with cost/token metrics\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_history',\n 'Get execution history with cost, token usage, model, and duration per unit. Returns totals across all units. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n limit: z.number().optional().describe('Max entries to return (most recent first). Default: all.'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, limit } = args as { projectDir: string; limit?: number };\n try {\n return jsonContent(readHistory(validateProjectDir(projectDir), limit));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_doctor — lightweight structural health check\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_doctor',\n 'Run a lightweight structural health check on the .gsd/ directory. Checks for missing files, status inconsistencies, and orphaned state. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n scope: z.string().optional().describe('Limit checks to a specific milestone (e.g. \"M001\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, scope } = args as { projectDir: string; scope?: string };\n try {\n return jsonContent(runDoctorLite(validateProjectDir(projectDir), scope));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_captures — pending captures and ideas\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_captures',\n 'Get captured ideas and thoughts from CAPTURES.md with triage status. Filter by pending, actionable, or all. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n filter: z.enum(['all', 'pending', 'actionable']).optional().describe('Filter captures (default: \"all\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, filter } = args as { projectDir: string; filter?: 'all' | 'pending' | 'actionable' };\n try {\n return jsonContent(readCaptures(validateProjectDir(projectDir), filter ?? 'all'));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_knowledge — project knowledge base\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_knowledge',\n 'Get the project knowledge base: rules, patterns, and lessons learned accumulated during development. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir } = args as { projectDir: string };\n try {\n return jsonContent(readKnowledge(validateProjectDir(projectDir)));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_graph — knowledge graph for GSD projects\n //\n // Modes:\n // build Parse .gsd/ artifacts and write graph.json atomically.\n // query Search the graph for nodes matching a term (BFS, budget-trimmed).\n // status Check whether graph.json exists and whether it is stale (>24h).\n // diff Compare graph.json with the last build snapshot.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_graph',\n [\n 'Manage the GSD project knowledge graph. No session required.',\n '',\n 'Modes:',\n ' build Parse .gsd/ artifacts (STATE.md, milestone ROADMAPs, slice PLANs,',\n ' KNOWLEDGE.md) and write .gsd/graphs/graph.json atomically.',\n ' query Search graph nodes by term (BFS from seed matches, budget-trimmed).',\n ' Returns matching nodes and reachable edges within the token budget.',\n ' status Show whether graph.json exists, its age, node/edge counts, and',\n ' whether it is stale (built more than 24 hours ago).',\n ' diff Compare current graph.json with .last-build-snapshot.json.',\n ' Returns added, removed, and changed nodes and edges.',\n ].join('\\n'),\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n mode: z.enum(['build', 'query', 'status', 'diff']).describe(\n 'Operation: build | query | status | diff',\n ),\n term: z.string().optional().describe('Search term for query mode (case-insensitive)'),\n budget: z.number().optional().describe('Token budget for query mode (default: 4000)'),\n snapshot: z.boolean().optional().describe('Write snapshot before build (for future diff)'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir: rawProjectDir, mode, term, budget, snapshot } = args as {\n projectDir: string;\n mode: 'build' | 'query' | 'status' | 'diff';\n term?: string;\n budget?: number;\n snapshot?: boolean;\n };\n\n try {\n const projectDir = validateProjectDir(rawProjectDir);\n const gsdRoot = resolveGsdRoot(projectDir);\n\n switch (mode) {\n case 'build': {\n if (snapshot) {\n await writeSnapshot(gsdRoot).catch(() => { /* best-effort */ });\n }\n const graph = await buildGraph(projectDir);\n await writeGraph(gsdRoot, graph);\n return jsonContent({\n built: true,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n builtAt: graph.builtAt,\n });\n }\n\n case 'query': {\n const result = await graphQuery(projectDir, term ?? '', budget);\n return jsonContent(result);\n }\n\n case 'status': {\n const result = await graphStatus(projectDir);\n return jsonContent(result);\n }\n\n case 'diff': {\n const result = await graphDiff(projectDir);\n return jsonContent(result);\n }\n }\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n registerWorkflowTools(server);\n\n return { server };\n}\n"]}
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP Server — registers GSD orchestration, project-state, and workflow tools.\n *\n * Session tools (6): gsd_execute, gsd_status, gsd_result, gsd_cancel, gsd_query, gsd_resolve_blocker\n * Interactive tools (2): ask_user_questions, secure_env_collect via MCP form elicitation\n * Read-only tools (6): gsd_progress, gsd_roadmap, gsd_history, gsd_doctor, gsd_captures, gsd_knowledge\n * Workflow tools (29): headless-safe planning, metadata persistence, replanning, completion, validation, reassessment, gate result, status, and journal tools\n *\n * Uses dynamic imports for @modelcontextprotocol/sdk because TS Node16\n * cannot resolve the SDK's subpath exports statically (same pattern as\n * src/mcp-server.ts in the main package).\n */\n\nimport { readFile, readdir, stat } from 'node:fs/promises';\nimport { join, resolve } from 'node:path';\nimport { z } from 'zod';\nimport type { SessionManager } from './session-manager.js';\nimport { isRemoteConfigured, tryRemoteQuestions } from './remote-questions.js';\nimport { readProgress } from './readers/state.js';\nimport { readRoadmap } from './readers/roadmap.js';\nimport { readHistory } from './readers/metrics.js';\nimport { readCaptures } from './readers/captures.js';\nimport { readKnowledge } from './readers/knowledge.js';\nimport { buildGraph, writeGraph, writeSnapshot, graphStatus, graphQuery, graphDiff } from './readers/graph.js';\nimport { resolveGsdRoot } from './readers/paths.js';\nimport { runDoctorLite } from './readers/doctor-lite.js';\nimport { registerWorkflowTools, validateProjectDir } from './workflow-tools.js';\nimport { applySecrets, checkExistingEnvKeys, detectDestination } from './env-writer.js';\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\nconst MCP_PKG = '@modelcontextprotocol/sdk';\nconst SERVER_NAME = 'gsd';\nconst SERVER_VERSION = '2.53.0';\n\n/** User-interaction timeout — generous but bounded so elicitation can't hang indefinitely (#4586). */\nconst ELICIT_TIMEOUT_MS = 10 * 60 * 1000; // 10 minutes\n\n/**\n * Race a promise against a timeout. Rejects with a typed error on timeout so\n * callers can return a specific MCP error response rather than hanging.\n *\n * @param timeoutMs - override for testing; defaults to ELICIT_TIMEOUT_MS\n */\nexport async function withElicitTimeout<T>(\n promise: Promise<T>,\n label: string,\n timeoutMs = ELICIT_TIMEOUT_MS,\n): Promise<T> {\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_, reject) => {\n timer = setTimeout(\n () => reject(new Error(`${label} timed out after ${timeoutMs / 60000} minutes — no user response received`)),\n timeoutMs,\n );\n });\n try {\n return await Promise.race([promise, timeout]);\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ---------------------------------------------------------------------------\n// Tool result helpers\n// ---------------------------------------------------------------------------\n\n/** Wrap a JSON-serializable value as MCP tool content. */\nfunction jsonContent(data: unknown): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }] };\n}\n\n/** Return an MCP error response. */\nfunction errorContent(message: string): { isError: true; content: Array<{ type: 'text'; text: string }> } {\n return { isError: true, content: [{ type: 'text' as const, text: message }] };\n}\n\n/** Return raw text content without JSON wrapping. */\nfunction textContent(text: string): { content: Array<{ type: 'text'; text: string }> } {\n return { content: [{ type: 'text' as const, text }] };\n}\n\n// ---------------------------------------------------------------------------\n// gsd_query filesystem reader\n// ---------------------------------------------------------------------------\n\n/**\n * Normalized query categories for {@link readProjectState}.\n *\n * Maps user-supplied query strings (or empty) to the set of fields we return.\n * Accepts common synonyms so the MCP client can pass intuitive values.\n */\nconst QUERY_FIELDS = {\n all: ['state', 'project', 'requirements', 'milestones'] as const,\n state: ['state'] as const,\n status: ['state'] as const,\n project: ['project'] as const,\n requirements: ['requirements'] as const,\n milestones: ['milestones'] as const,\n} as const;\n\ntype QueryCategory = keyof typeof QUERY_FIELDS;\ntype ProjectStateField = (typeof QUERY_FIELDS)[QueryCategory][number];\n\nfunction normalizeQuery(query: string | undefined): QueryCategory {\n const key = (query ?? 'all').trim().toLowerCase();\n if (key in QUERY_FIELDS) return key as QueryCategory;\n return 'all';\n}\n\nasync function readProjectState(projectDir: string, query: string | undefined): Promise<Record<string, unknown>> {\n const gsdDir = join(resolve(projectDir), '.gsd');\n const category = normalizeQuery(query);\n const wanted = new Set<ProjectStateField>(QUERY_FIELDS[category]);\n\n const result: Record<string, unknown> = {\n projectDir: resolve(projectDir),\n query: category,\n };\n\n if (wanted.has('state')) {\n try {\n result.state = await readFile(join(gsdDir, 'STATE.md'), 'utf-8');\n } catch {\n result.state = null;\n }\n }\n\n if (wanted.has('project')) {\n try {\n result.project = await readFile(join(gsdDir, 'PROJECT.md'), 'utf-8');\n } catch {\n result.project = null;\n }\n }\n\n if (wanted.has('requirements')) {\n try {\n result.requirements = await readFile(join(gsdDir, 'REQUIREMENTS.md'), 'utf-8');\n } catch {\n result.requirements = null;\n }\n }\n\n if (wanted.has('milestones')) {\n const milestonesDir = join(gsdDir, 'milestones');\n try {\n const entries = await readdir(milestonesDir, { withFileTypes: true });\n const milestones: Array<{ id: string; hasRoadmap: boolean; hasSummary: boolean }> = [];\n for (const entry of entries) {\n if (!entry.isDirectory()) continue;\n const mDir = join(milestonesDir, entry.name);\n const hasRoadmap = await fileExists(join(mDir, `${entry.name}-ROADMAP.md`));\n const hasSummary = await fileExists(join(mDir, `${entry.name}-SUMMARY.md`));\n milestones.push({ id: entry.name, hasRoadmap, hasSummary });\n }\n result.milestones = milestones;\n } catch {\n result.milestones = [];\n }\n }\n\n return result;\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n try {\n await stat(path);\n return true;\n } catch {\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// MCP Server type — minimal interface for the dynamically-imported McpServer\n// ---------------------------------------------------------------------------\n\ninterface ElicitResult {\n action: 'accept' | 'decline' | 'cancel';\n content?: Record<string, string | number | boolean | string[]>;\n}\n\ninterface ElicitRequestFormParams {\n mode?: 'form';\n message: string;\n requestedSchema: {\n type: 'object';\n properties: Record<string, Record<string, unknown>>;\n required?: string[];\n };\n}\n\n/**\n * Handler extra — the second argument passed by McpServer.tool handlers.\n * Contains an AbortSignal scoped to the JSON-RPC request (cancelled when\n * the client cancels the `tools/call`) plus other per-request metadata.\n * Tools that can actually be stopped mid-flight should honour `signal`.\n */\nexport interface McpToolExtra {\n signal?: AbortSignal;\n requestId?: string | number;\n sendNotification?: (notification: unknown) => void | Promise<void>;\n}\n\ninterface McpServerInstance {\n tool(\n name: string,\n description: string,\n params: Record<string, unknown>,\n handler: (args: Record<string, unknown>, extra?: McpToolExtra) => Promise<unknown>,\n ): unknown;\n server: {\n elicitInput(\n params: AskUserQuestionsElicitRequest | ElicitRequestFormParams,\n options?: unknown,\n ): Promise<AskUserQuestionsElicitResult>;\n };\n connect(transport: unknown): Promise<void>;\n close(): Promise<void>;\n}\n\ninterface AskUserQuestionOption {\n label: string;\n description: string;\n}\n\ninterface AskUserQuestion {\n id: string;\n header: string;\n question: string;\n options: AskUserQuestionOption[];\n allowMultiple?: boolean;\n}\n\ninterface AskUserQuestionsParams {\n questions: AskUserQuestion[];\n}\n\ntype AskUserQuestionsContentValue = string | number | boolean | string[];\n\ninterface AskUserQuestionsElicitResult {\n action: 'accept' | 'decline' | 'cancel';\n content?: Record<string, AskUserQuestionsContentValue>;\n}\n\ninterface AskUserQuestionsElicitRequest {\n mode: 'form';\n message: string;\n requestedSchema: {\n type: 'object';\n properties: Record<string, Record<string, unknown>>;\n required?: string[];\n };\n}\n\nconst OTHER_OPTION_LABEL = 'None of the above';\n\nfunction normalizeAskUserQuestionsNote(value: AskUserQuestionsContentValue | undefined): string {\n return typeof value === 'string' ? value.trim() : '';\n}\n\nfunction normalizeAskUserQuestionsAnswers(\n value: AskUserQuestionsContentValue | undefined,\n allowMultiple: boolean,\n): string[] {\n if (allowMultiple) {\n return Array.isArray(value) ? value.filter((item): item is string => typeof item === 'string') : [];\n }\n\n return typeof value === 'string' && value.length > 0 ? [value] : [];\n}\n\nfunction validateAskUserQuestionsPayload(questions: AskUserQuestion[]): string | null {\n if (questions.length === 0 || questions.length > 3) {\n return 'Error: questions must contain 1-3 items';\n }\n\n for (const question of questions) {\n if (!question.options || question.options.length === 0) {\n return `Error: ask_user_questions requires non-empty options for every question (question \"${question.id}\" has none)`;\n }\n }\n\n return null;\n}\n\nexport function buildAskUserQuestionsElicitRequest(questions: AskUserQuestion[]): AskUserQuestionsElicitRequest {\n const properties: Record<string, Record<string, unknown>> = {};\n const required = questions.map((question) => question.id);\n\n for (const question of questions) {\n if (question.allowMultiple) {\n properties[question.id] = {\n type: 'array',\n title: question.header,\n description: question.question,\n minItems: 1,\n maxItems: question.options.length,\n items: {\n anyOf: question.options.map((option) => ({\n const: option.label,\n title: option.label,\n })),\n },\n };\n continue;\n }\n\n properties[question.id] = {\n type: 'string',\n title: question.header,\n description: question.question,\n oneOf: [...question.options, { label: OTHER_OPTION_LABEL, description: 'Choose this when the listed options do not fit.' }].map((option) => ({\n const: option.label,\n title: option.label,\n })),\n };\n\n properties[`${question.id}__note`] = {\n type: 'string',\n title: `${question.header} Note`,\n description: `Optional note for \"${OTHER_OPTION_LABEL}\".`,\n maxLength: 500,\n };\n }\n\n return {\n mode: 'form',\n message: 'Please answer the following question(s). For single-select questions, choose \"None of the above\" and add a note if the provided options do not fit.',\n requestedSchema: {\n type: 'object',\n properties,\n required,\n },\n };\n}\n\nexport function formatAskUserQuestionsElicitResult(\n questions: AskUserQuestion[],\n result: AskUserQuestionsElicitResult,\n): string {\n const answers: Record<string, { answers: string[] }> = {};\n const content = result.content ?? {};\n\n for (const question of questions) {\n const answerList = normalizeAskUserQuestionsAnswers(content[question.id], !!question.allowMultiple);\n\n if (!question.allowMultiple && answerList[0] === OTHER_OPTION_LABEL) {\n const note = normalizeAskUserQuestionsNote(content[`${question.id}__note`]);\n if (note) {\n answerList.push(`user_note: ${note}`);\n }\n }\n\n answers[question.id] = { answers: answerList };\n }\n\n return JSON.stringify({ answers });\n}\n\n// ---------------------------------------------------------------------------\n// createMcpServer\n// ---------------------------------------------------------------------------\n\n/**\n * Create and configure an MCP server with session, read-only, and workflow tools.\n *\n * Returns the McpServer instance — call `connect(transport)` to start serving.\n * Uses dynamic imports for the MCP SDK to avoid TS subpath resolution issues.\n */\nexport async function createMcpServer(sessionManager: SessionManager): Promise<{\n server: McpServerInstance;\n}> {\n // Dynamic import — same workaround as src/mcp-server.ts\n const mcpMod = await import(`${MCP_PKG}/server/mcp.js`);\n const McpServer = mcpMod.McpServer;\n\n const server: McpServerInstance = new McpServer(\n { name: SERVER_NAME, version: SERVER_VERSION },\n { capabilities: { tools: {}, elicitation: {} } },\n );\n\n // -----------------------------------------------------------------------\n // gsd_execute — start a new GSD auto-mode session.\n //\n // If the JSON-RPC request is aborted while the session is starting (or\n // immediately after), we cancel the session so we don't leak a background\n // RpcClient process. Once the session is running the caller should use\n // `gsd_cancel` to stop it via sessionId.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_execute',\n 'Start a GSD auto-mode session for a project directory. Returns a sessionId for tracking.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n command: z.string().optional().describe('Command to send (default: \"/gsd auto\")'),\n model: z.string().optional().describe('Model ID override'),\n bare: z.boolean().optional().describe('Run in bare mode (skip user config)'),\n },\n async (args: Record<string, unknown>, extra?: McpToolExtra) => {\n const { projectDir, command, model, bare } = args as {\n projectDir: string; command?: string; model?: string; bare?: boolean;\n };\n try {\n const sessionId = await sessionManager.startSession(projectDir, { command, model, bare });\n\n // If the client aborted while startSession was running, cancel the\n // newly-created session rather than leaving an orphaned process.\n if (extra?.signal?.aborted) {\n await sessionManager.cancelSession(sessionId).catch(() => { /* swallow */ });\n return errorContent('gsd_execute aborted by client before returning');\n }\n\n return jsonContent({ sessionId, status: 'started' });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_status — poll session status\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_status',\n 'Get the current status of a GSD session including progress, recent events, and pending blockers.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n const session = sessionManager.getSession(sessionId);\n if (!session) return errorContent(`Session not found: ${sessionId}`);\n\n const durationMs = Date.now() - session.startTime;\n const toolCallCount = session.events.filter(\n (e) => (e as Record<string, unknown>).type === 'tool_use' ||\n (e as Record<string, unknown>).type === 'tool_execution_start'\n ).length;\n\n return jsonContent({\n status: session.status,\n progress: {\n eventCount: session.events.length,\n toolCalls: toolCallCount,\n },\n recentEvents: session.events.slice(-10),\n pendingBlocker: session.pendingBlocker\n ? {\n id: session.pendingBlocker.id,\n method: session.pendingBlocker.method,\n message: session.pendingBlocker.message,\n }\n : null,\n cost: session.cost,\n durationMs,\n });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_result — get accumulated session result\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_result',\n 'Get the result of a GSD session. Returns partial results if the session is still running.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n const result = sessionManager.getResult(sessionId);\n return jsonContent(result);\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_cancel — cancel a running session\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_cancel',\n 'Cancel a running GSD session. Aborts the current operation and stops the process.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId } = args as { sessionId: string };\n try {\n await sessionManager.cancelSession(sessionId);\n return jsonContent({ cancelled: true });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_query — read project state from filesystem (no session needed).\n //\n // `query` is optional: when omitted the tool returns all fields (STATE.md,\n // PROJECT.md, requirements, milestone listing). Accepted narrow values:\n // \"state\" / \"status\", \"project\", \"requirements\", \"milestones\", \"all\".\n // Unknown values fall back to \"all\" for forward-compatibility.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_query',\n 'Query GSD project state from the filesystem. By default returns STATE.md, PROJECT.md, requirements, and milestone listing. Pass `query` to narrow the response (accepted: \"state\"/\"status\", \"project\", \"requirements\", \"milestones\", \"all\"). Does not require an active session.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n query: z\n .enum(['all', 'state', 'status', 'project', 'requirements', 'milestones'])\n .optional()\n .describe('Narrow the response to a single field (default: \"all\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, query } = args as { projectDir: string; query?: string };\n try {\n const validated = validateProjectDir(projectDir);\n const state = await readProjectState(validated, query);\n return jsonContent(state);\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_resolve_blocker — resolve a pending blocker\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_resolve_blocker',\n 'Resolve a pending blocker in a GSD session by sending a response to the UI request.',\n {\n sessionId: z.string().describe('Session ID returned from gsd_execute'),\n response: z.string().describe('Response to send for the pending blocker'),\n },\n async (args: Record<string, unknown>) => {\n const { sessionId, response } = args as { sessionId: string; response: string };\n try {\n await sessionManager.resolveBlocker(sessionId, response);\n return jsonContent({ resolved: true });\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // ask_user_questions — structured user input via MCP form elicitation\n // -----------------------------------------------------------------------\n server.tool(\n 'ask_user_questions',\n 'Request user input for one to three short questions and wait for the response. Single-select questions include a free-form \"None of the above\" path. Multi-select questions allow multiple choices.',\n {\n questions: z.array(z.object({\n id: z.string().describe('Stable identifier for mapping answers (snake_case)'),\n header: z.string().describe('Short header label shown in the UI (12 or fewer chars)'),\n question: z.string().describe('Single-sentence prompt shown to the user'),\n options: z.array(z.object({\n label: z.string().describe('User-facing label (1-5 words)'),\n description: z.string().describe('One short sentence explaining impact/tradeoff if selected'),\n })).describe('Provide 2-3 mutually exclusive choices. Put the recommended option first and suffix its label with \"(Recommended)\". Do not include an \"Other\" option for single-select questions.'),\n allowMultiple: z.boolean().optional().describe('If true, the user can select multiple options. No \"None of the above\" option is added.'),\n })).describe('Questions to show the user. Prefer 1 and do not exceed 3.'),\n },\n async (args: Record<string, unknown>, extra?: McpToolExtra) => {\n const { questions } = args as unknown as AskUserQuestionsParams;\n try {\n const validationError = validateAskUserQuestionsPayload(questions);\n if (validationError) return errorContent(validationError);\n\n // Delegate to remote-questions manager when a remote channel is configured\n // (Discord, Slack, Telegram). This path is the only one reachable for\n // Claude Code-under-gsd sessions, which have no local TUI.\n if (isRemoteConfigured()) {\n const remoteResult = await tryRemoteQuestions(questions, extra?.signal);\n if (remoteResult) {\n const details = remoteResult.details as Record<string, unknown> | undefined;\n if (details?.['timed_out'] || details?.['error']) {\n // Surface timeout/error as plain text so the LLM knows to retry\n return textContent(remoteResult.content[0]?.text ?? 'Remote questions timed out or failed');\n }\n return textContent(remoteResult.content[0]?.text ?? '');\n }\n // resolveRemoteConfig() returned null between isRemoteConfigured() and\n // tryRemoteQuestions() (e.g. env var was cleared) — fall through to local.\n }\n\n const elicitation = await withElicitTimeout(\n server.server.elicitInput(buildAskUserQuestionsElicitRequest(questions)),\n 'ask_user_questions',\n );\n if (elicitation.action !== 'accept' || !elicitation.content) {\n return textContent('ask_user_questions was cancelled before receiving a response');\n }\n\n return textContent(formatAskUserQuestionsElicitResult(questions, elicitation));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // secure_env_collect — collect secrets via MCP form elicitation\n // -----------------------------------------------------------------------\n server.tool(\n 'secure_env_collect',\n 'Collect environment variables securely via form input. Values are written directly to .env (or Vercel/Convex) and NEVER appear in tool output — only key names and applied/skipped status are returned. Use this instead of asking users to manually edit .env files or paste secrets into chat.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n keys: z.array(z.object({\n key: z.string().describe('Env var name, e.g. OPENAI_API_KEY'),\n hint: z.string().optional().describe('Format hint shown to user, e.g. \"starts with sk-\"'),\n guidance: z.array(z.string()).optional().describe('Step-by-step instructions for obtaining this key'),\n })).min(1).describe('Environment variables to collect'),\n destination: z.enum(['dotenv', 'vercel', 'convex']).optional().describe('Where to write secrets. Auto-detected from project files if omitted.'),\n envFilePath: z.string().optional().describe('Path to .env file (dotenv only). Defaults to .env in projectDir.'),\n environment: z.enum(['development', 'preview', 'production']).optional().describe('Target environment (vercel/convex only)'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, keys, destination, envFilePath, environment } = args as {\n projectDir: string;\n keys: Array<{ key: string; hint?: string; guidance?: string[] }>;\n destination?: 'dotenv' | 'vercel' | 'convex';\n envFilePath?: string;\n environment?: 'development' | 'preview' | 'production';\n };\n\n try {\n const resolvedProjectDir = validateProjectDir(projectDir);\n const resolvedEnvPath = resolve(resolvedProjectDir, envFilePath ?? '.env');\n\n // (1) Check which keys already exist\n const allKeyNames = keys.map((k) => k.key);\n const existingKeys = await checkExistingEnvKeys(allKeyNames, resolvedEnvPath);\n const existingSet = new Set(existingKeys);\n const pendingKeys = keys.filter((k) => !existingSet.has(k.key));\n\n // If all keys already exist, return immediately\n if (pendingKeys.length === 0) {\n const lines = existingKeys.map((k) => `• ${k}: already set`);\n return textContent(`All ${existingKeys.length} key(s) already set.\\n${lines.join('\\n')}`);\n }\n\n // (2) Build elicitation form — one string field per pending key\n const properties: Record<string, Record<string, unknown>> = {};\n const required: string[] = [];\n\n for (const item of pendingKeys) {\n const descParts: string[] = [];\n if (item.hint) descParts.push(`Format: ${item.hint}`);\n if (item.guidance && item.guidance.length > 0) {\n descParts.push('How to get this:');\n item.guidance.forEach((step, i) => descParts.push(`${i + 1}. ${step}`));\n }\n descParts.push('Leave empty to skip.');\n\n properties[item.key] = {\n type: 'string',\n title: item.key,\n description: descParts.join('\\n'),\n };\n // Don't mark as required — empty string = skip\n }\n\n // (3) Elicit input from the MCP client\n const elicitation = await withElicitTimeout(\n server.server.elicitInput({\n message: `Enter values for ${pendingKeys.length} environment variable(s). Values are written directly to the project and never shown to the AI.`,\n requestedSchema: {\n type: 'object',\n properties,\n required,\n },\n }),\n 'secure_env_collect',\n );\n\n if (elicitation.action !== 'accept' || !elicitation.content) {\n return textContent('secure_env_collect was cancelled by user.');\n }\n\n // (4) Separate provided vs skipped from form response\n const provided: Array<{ key: string; value: string }> = [];\n const skipped: string[] = [];\n\n for (const item of pendingKeys) {\n const raw = elicitation.content[item.key];\n const value = typeof raw === 'string' ? raw.trim() : '';\n if (value.length > 0) {\n provided.push({ key: item.key, value });\n } else {\n skipped.push(item.key);\n }\n }\n\n // (5) Auto-detect destination if not specified\n const resolvedDestination = destination ?? detectDestination(resolvedProjectDir);\n\n // (6) Write secrets to destination\n const { applied, errors } = await applySecrets(provided, resolvedDestination, {\n envFilePath: resolvedEnvPath,\n environment,\n });\n\n // (7) Build result — NEVER include secret values\n const lines: string[] = [\n `destination: ${resolvedDestination}${!destination ? ' (auto-detected)' : ''}${environment ? ` (${environment})` : ''}`,\n ];\n for (const k of applied) lines.push(`✓ ${k}: applied`);\n for (const k of skipped) lines.push(`• ${k}: skipped`);\n for (const k of existingKeys) lines.push(`• ${k}: already set`);\n for (const e of errors) lines.push(`✗ ${e}`);\n\n return errors.length > 0 && applied.length === 0\n ? errorContent(lines.join('\\n'))\n : textContent(lines.join('\\n'));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // =======================================================================\n // READ-ONLY TOOLS — no session required, pure filesystem reads\n // =======================================================================\n\n // -----------------------------------------------------------------------\n // gsd_progress — structured project progress metrics\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_progress',\n 'Get structured project progress: active milestone/slice/task, phase, completion counts, blockers, and next action. No session required — reads directly from .gsd/ on disk.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir } = args as { projectDir: string };\n try {\n return jsonContent(readProgress(validateProjectDir(projectDir)));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_roadmap — milestone/slice/task structure with status\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_roadmap',\n 'Get the full project roadmap structure: milestones with their slices, tasks, status, risk, and dependencies. Optionally filter to a single milestone. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n milestoneId: z.string().optional().describe('Filter to a specific milestone (e.g. \"M001\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, milestoneId } = args as { projectDir: string; milestoneId?: string };\n try {\n return jsonContent(readRoadmap(validateProjectDir(projectDir), milestoneId));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_history — execution history with cost/token metrics\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_history',\n 'Get execution history with cost, token usage, model, and duration per unit. Returns totals across all units. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n limit: z.number().optional().describe('Max entries to return (most recent first). Default: all.'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, limit } = args as { projectDir: string; limit?: number };\n try {\n return jsonContent(readHistory(validateProjectDir(projectDir), limit));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_doctor — lightweight structural health check\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_doctor',\n 'Run a lightweight structural health check on the .gsd/ directory. Checks for missing files, status inconsistencies, and orphaned state. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n scope: z.string().optional().describe('Limit checks to a specific milestone (e.g. \"M001\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, scope } = args as { projectDir: string; scope?: string };\n try {\n return jsonContent(runDoctorLite(validateProjectDir(projectDir), scope));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_captures — pending captures and ideas\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_captures',\n 'Get captured ideas and thoughts from CAPTURES.md with triage status. Filter by pending, actionable, or all. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n filter: z.enum(['all', 'pending', 'actionable']).optional().describe('Filter captures (default: \"all\")'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir, filter } = args as { projectDir: string; filter?: 'all' | 'pending' | 'actionable' };\n try {\n return jsonContent(readCaptures(validateProjectDir(projectDir), filter ?? 'all'));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_knowledge — project knowledge base\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_knowledge',\n 'Get the project knowledge base: rules, patterns, and lessons learned accumulated during development. No session required.',\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir } = args as { projectDir: string };\n try {\n return jsonContent(readKnowledge(validateProjectDir(projectDir)));\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n // -----------------------------------------------------------------------\n // gsd_graph — knowledge graph for GSD projects\n //\n // Modes:\n // build Parse .gsd/ artifacts and write graph.json atomically.\n // query Search the graph for nodes matching a term (BFS, budget-trimmed).\n // status Check whether graph.json exists and whether it is stale (>24h).\n // diff Compare graph.json with the last build snapshot.\n // -----------------------------------------------------------------------\n server.tool(\n 'gsd_graph',\n [\n 'Manage the GSD project knowledge graph. No session required.',\n '',\n 'Modes:',\n ' build Parse .gsd/ artifacts (STATE.md, milestone ROADMAPs, slice PLANs,',\n ' KNOWLEDGE.md) and write .gsd/graphs/graph.json atomically.',\n ' query Search graph nodes by term (BFS from seed matches, budget-trimmed).',\n ' Returns matching nodes and reachable edges within the token budget.',\n ' status Show whether graph.json exists, its age, node/edge counts, and',\n ' whether it is stale (built more than 24 hours ago).',\n ' diff Compare current graph.json with .last-build-snapshot.json.',\n ' Returns added, removed, and changed nodes and edges.',\n ].join('\\n'),\n {\n projectDir: z.string().describe('Absolute path to the project directory'),\n mode: z.enum(['build', 'query', 'status', 'diff']).describe(\n 'Operation: build | query | status | diff',\n ),\n term: z.string().optional().describe('Search term for query mode (case-insensitive)'),\n budget: z.number().optional().describe('Token budget for query mode (default: 4000)'),\n snapshot: z.boolean().optional().describe('Write snapshot before build (for future diff)'),\n },\n async (args: Record<string, unknown>) => {\n const { projectDir: rawProjectDir, mode, term, budget, snapshot } = args as {\n projectDir: string;\n mode: 'build' | 'query' | 'status' | 'diff';\n term?: string;\n budget?: number;\n snapshot?: boolean;\n };\n\n try {\n const projectDir = validateProjectDir(rawProjectDir);\n const gsdRoot = resolveGsdRoot(projectDir);\n\n switch (mode) {\n case 'build': {\n if (snapshot) {\n await writeSnapshot(gsdRoot).catch(() => { /* best-effort */ });\n }\n const graph = await buildGraph(projectDir);\n await writeGraph(gsdRoot, graph);\n return jsonContent({\n built: true,\n nodeCount: graph.nodes.length,\n edgeCount: graph.edges.length,\n builtAt: graph.builtAt,\n });\n }\n\n case 'query': {\n const result = await graphQuery(projectDir, term ?? '', budget);\n return jsonContent(result);\n }\n\n case 'status': {\n const result = await graphStatus(projectDir);\n return jsonContent(result);\n }\n\n case 'diff': {\n const result = await graphDiff(projectDir);\n return jsonContent(result);\n }\n }\n } catch (err) {\n return errorContent(err instanceof Error ? err.message : String(err));\n }\n },\n );\n\n registerWorkflowTools(server);\n\n return { server };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgSH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CA+BnG;AAkID,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrE;AA6FD,UAAU,aAAa;IACrB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3D,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,mBAAmB,6tBAoCtB,CAAC;AAilBX,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAqkBjE"}
1
+ {"version":3,"file":"workflow-tools.d.ts","sourceRoot":"","sources":["../src/workflow-tools.ts"],"names":[],"mappings":"AAAA;;GAEG;AAgSH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,GAAE,MAAM,CAAC,UAAwB,GAAG,MAAM,CA+BnG;AAkID,4CAA4C;AAC5C,wBAAgB,sBAAsB,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAiBrE;AA6FD,UAAU,aAAa;IACrB,IAAI,CACF,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,GAC3D,OAAO,CAAC;CACZ;AAED,eAAO,MAAM,mBAAmB,6tBAoCtB,CAAC;AAknBX,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CA6kBjE"}