gsd-pi 2.78.1-dev.e9d88a536 → 2.78.1-dev.eccf86e27

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 (212) hide show
  1. package/README.md +5 -7
  2. package/dist/help-text.js +1 -1
  3. package/dist/resource-loader.js +6 -1
  4. package/dist/resources/.managed-resources-content-hash +1 -1
  5. package/dist/resources/extensions/gsd/auto/detect-stuck.js +41 -5
  6. package/dist/resources/extensions/gsd/auto/loop.js +235 -36
  7. package/dist/resources/extensions/gsd/auto/phases.js +14 -7
  8. package/dist/resources/extensions/gsd/auto/session.js +36 -0
  9. package/dist/resources/extensions/gsd/auto-dispatch.js +49 -4
  10. package/dist/resources/extensions/gsd/auto-post-unit.js +26 -12
  11. package/dist/resources/extensions/gsd/auto-worktree.js +185 -201
  12. package/dist/resources/extensions/gsd/auto.js +139 -49
  13. package/dist/resources/extensions/gsd/bootstrap/agent-end-recovery.js +1 -1
  14. package/dist/resources/extensions/gsd/bootstrap/register-hooks.js +26 -20
  15. package/dist/resources/extensions/gsd/bootstrap/write-gate.js +67 -55
  16. package/dist/resources/extensions/gsd/crash-recovery.js +160 -47
  17. package/dist/resources/extensions/gsd/db/auto-workers.js +227 -0
  18. package/dist/resources/extensions/gsd/db/command-queue.js +105 -0
  19. package/dist/resources/extensions/gsd/db/milestone-leases.js +210 -0
  20. package/dist/resources/extensions/gsd/db/runtime-kv.js +91 -0
  21. package/dist/resources/extensions/gsd/db/unit-dispatches.js +322 -0
  22. package/dist/resources/extensions/gsd/db-writer.js +96 -16
  23. package/dist/resources/extensions/gsd/delegation-policy.js +155 -0
  24. package/dist/resources/extensions/gsd/docs/COORDINATION.md +42 -0
  25. package/dist/resources/extensions/gsd/doctor-proactive.js +4 -0
  26. package/dist/resources/extensions/gsd/doctor-runtime-checks.js +22 -6
  27. package/dist/resources/extensions/gsd/doctor.js +12 -2
  28. package/dist/resources/extensions/gsd/gsd-db.js +355 -3
  29. package/dist/resources/extensions/gsd/guided-flow-queue.js +1 -1
  30. package/dist/resources/extensions/gsd/guided-flow.js +116 -26
  31. package/dist/resources/extensions/gsd/interrupted-session.js +18 -15
  32. package/dist/resources/extensions/gsd/metrics.js +287 -1
  33. package/dist/resources/extensions/gsd/paths.js +79 -8
  34. package/dist/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  35. package/dist/resources/extensions/gsd/prompts/execute-task.md +3 -3
  36. package/dist/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
  37. package/dist/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
  38. package/dist/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
  39. package/dist/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
  40. package/dist/resources/extensions/gsd/state.js +21 -6
  41. package/dist/resources/extensions/gsd/templates/project.md +10 -0
  42. package/dist/resources/extensions/gsd/workflow-mcp.js +2 -2
  43. package/dist/resources/extensions/gsd/workspace.js +59 -0
  44. package/dist/resources/extensions/gsd/worktree-resolver.js +79 -2
  45. package/dist/resources/extensions/gsd/write-intercept.js +3 -3
  46. package/dist/tsconfig.extensions.tsbuildinfo +1 -1
  47. package/dist/web/standalone/.next/BUILD_ID +1 -1
  48. package/dist/web/standalone/.next/app-path-routes-manifest.json +14 -14
  49. package/dist/web/standalone/.next/build-manifest.json +2 -2
  50. package/dist/web/standalone/.next/prerender-manifest.json +3 -3
  51. package/dist/web/standalone/.next/required-server-files.json +1 -1
  52. package/dist/web/standalone/.next/server/app/_global-error.html +1 -1
  53. package/dist/web/standalone/.next/server/app/_global-error.rsc +1 -1
  54. package/dist/web/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  55. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error/__PAGE__.segment.rsc +1 -1
  56. package/dist/web/standalone/.next/server/app/_global-error.segments/_global-error.segment.rsc +1 -1
  57. package/dist/web/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  58. package/dist/web/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  59. package/dist/web/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  60. package/dist/web/standalone/.next/server/app/_not-found.html +1 -1
  61. package/dist/web/standalone/.next/server/app/_not-found.rsc +1 -1
  62. package/dist/web/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  63. package/dist/web/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  64. package/dist/web/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  65. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  66. package/dist/web/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  67. package/dist/web/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  68. package/dist/web/standalone/.next/server/app/index.html +1 -1
  69. package/dist/web/standalone/.next/server/app/index.rsc +1 -1
  70. package/dist/web/standalone/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  71. package/dist/web/standalone/.next/server/app/index.segments/_full.segment.rsc +1 -1
  72. package/dist/web/standalone/.next/server/app/index.segments/_head.segment.rsc +1 -1
  73. package/dist/web/standalone/.next/server/app/index.segments/_index.segment.rsc +1 -1
  74. package/dist/web/standalone/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  75. package/dist/web/standalone/.next/server/app-paths-manifest.json +14 -14
  76. package/dist/web/standalone/.next/server/middleware-build-manifest.js +1 -1
  77. package/dist/web/standalone/.next/server/pages/404.html +1 -1
  78. package/dist/web/standalone/.next/server/pages/500.html +1 -1
  79. package/dist/web/standalone/.next/server/server-reference-manifest.json +1 -1
  80. package/dist/web/standalone/server.js +1 -1
  81. package/package.json +1 -1
  82. package/packages/mcp-server/README.md +2 -11
  83. package/packages/mcp-server/dist/remote-questions.d.ts +27 -0
  84. package/packages/mcp-server/dist/remote-questions.d.ts.map +1 -1
  85. package/packages/mcp-server/dist/remote-questions.js +28 -0
  86. package/packages/mcp-server/dist/remote-questions.js.map +1 -1
  87. package/packages/mcp-server/dist/server.d.ts +28 -0
  88. package/packages/mcp-server/dist/server.d.ts.map +1 -1
  89. package/packages/mcp-server/dist/server.js +94 -4
  90. package/packages/mcp-server/dist/server.js.map +1 -1
  91. package/packages/mcp-server/dist/workflow-tools.js.map +1 -1
  92. package/packages/mcp-server/src/mcp-server.test.ts +226 -0
  93. package/packages/mcp-server/src/remote-questions.test.ts +103 -0
  94. package/packages/mcp-server/src/remote-questions.ts +35 -0
  95. package/packages/mcp-server/src/server.ts +129 -6
  96. package/packages/mcp-server/src/workflow-tools.ts +1 -1
  97. package/packages/mcp-server/tsconfig.tsbuildinfo +1 -1
  98. package/src/resources/extensions/gsd/auto/detect-stuck.ts +37 -5
  99. package/src/resources/extensions/gsd/auto/loop.ts +263 -41
  100. package/src/resources/extensions/gsd/auto/phases.ts +15 -7
  101. package/src/resources/extensions/gsd/auto/session.ts +40 -0
  102. package/src/resources/extensions/gsd/auto-dispatch.ts +63 -4
  103. package/src/resources/extensions/gsd/auto-post-unit.ts +27 -12
  104. package/src/resources/extensions/gsd/auto-worktree.ts +218 -225
  105. package/src/resources/extensions/gsd/auto.ts +166 -43
  106. package/src/resources/extensions/gsd/bootstrap/agent-end-recovery.ts +1 -1
  107. package/src/resources/extensions/gsd/bootstrap/register-hooks.ts +26 -21
  108. package/src/resources/extensions/gsd/bootstrap/tests/write-gate-basepath.test.ts +103 -0
  109. package/src/resources/extensions/gsd/bootstrap/write-gate.ts +80 -55
  110. package/src/resources/extensions/gsd/crash-recovery.ts +177 -43
  111. package/src/resources/extensions/gsd/db/auto-workers.ts +273 -0
  112. package/src/resources/extensions/gsd/db/command-queue.ts +149 -0
  113. package/src/resources/extensions/gsd/db/milestone-leases.ts +274 -0
  114. package/src/resources/extensions/gsd/db/runtime-kv.ts +127 -0
  115. package/src/resources/extensions/gsd/db/unit-dispatches.ts +446 -0
  116. package/src/resources/extensions/gsd/db-writer.ts +113 -17
  117. package/src/resources/extensions/gsd/delegation-policy.ts +197 -0
  118. package/src/resources/extensions/gsd/docs/COORDINATION.md +42 -0
  119. package/src/resources/extensions/gsd/doctor-proactive.ts +4 -0
  120. package/src/resources/extensions/gsd/doctor-runtime-checks.ts +24 -6
  121. package/src/resources/extensions/gsd/doctor.ts +10 -2
  122. package/src/resources/extensions/gsd/gsd-db.ts +354 -3
  123. package/src/resources/extensions/gsd/guided-flow-queue.ts +1 -1
  124. package/src/resources/extensions/gsd/guided-flow.ts +152 -26
  125. package/src/resources/extensions/gsd/interrupted-session.ts +19 -12
  126. package/src/resources/extensions/gsd/metrics.ts +321 -1
  127. package/src/resources/extensions/gsd/paths.ts +67 -8
  128. package/src/resources/extensions/gsd/prompts/complete-slice.md +4 -4
  129. package/src/resources/extensions/gsd/prompts/execute-task.md +3 -3
  130. package/src/resources/extensions/gsd/prompts/guided-discuss-milestone.md +8 -1
  131. package/src/resources/extensions/gsd/prompts/guided-discuss-project.md +22 -7
  132. package/src/resources/extensions/gsd/prompts/guided-discuss-requirements.md +6 -2
  133. package/src/resources/extensions/gsd/prompts/guided-discuss-slice.md +8 -1
  134. package/src/resources/extensions/gsd/state.ts +44 -6
  135. package/src/resources/extensions/gsd/templates/project.md +10 -0
  136. package/src/resources/extensions/gsd/tests/auto-discuss-milestone-deadlock-4973.test.ts +14 -14
  137. package/src/resources/extensions/gsd/tests/auto-loop-no-copy-artifacts.test.ts +72 -0
  138. package/src/resources/extensions/gsd/tests/auto-loop-symlink-worktree.test.ts +190 -0
  139. package/src/resources/extensions/gsd/tests/auto-session-scope.test.ts +331 -0
  140. package/src/resources/extensions/gsd/tests/auto-workers.test.ts +105 -0
  141. package/src/resources/extensions/gsd/tests/auto-worktree-registry.test.ts +176 -0
  142. package/src/resources/extensions/gsd/tests/command-queue.test.ts +141 -0
  143. package/src/resources/extensions/gsd/tests/crash-recovery-via-db.test.ts +203 -0
  144. package/src/resources/extensions/gsd/tests/crash-recovery.test.ts +169 -59
  145. package/src/resources/extensions/gsd/tests/db-writer-path-containment.test.ts +152 -0
  146. package/src/resources/extensions/gsd/tests/db-writer-root-artifact.test.ts +221 -0
  147. package/src/resources/extensions/gsd/tests/db-writer-scope.test.ts +230 -0
  148. package/src/resources/extensions/gsd/tests/delegation-policy.test.ts +151 -0
  149. package/src/resources/extensions/gsd/tests/detect-stuck-respects-retry.test.ts +173 -0
  150. package/src/resources/extensions/gsd/tests/dispatch-backgroundable-annotation.test.ts +55 -0
  151. package/src/resources/extensions/gsd/tests/draft-promotion.test.ts +3 -23
  152. package/src/resources/extensions/gsd/tests/gate-1b-orphan-discrimination.test.ts +193 -0
  153. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound-corrections.test.ts +246 -0
  154. package/src/resources/extensions/gsd/tests/gate-1b-recovery-bound.test.ts +218 -0
  155. package/src/resources/extensions/gsd/tests/gsd-db-failed-open-restore.test.ts +117 -0
  156. package/src/resources/extensions/gsd/tests/gsd-db-workspace-scope.test.ts +226 -0
  157. package/src/resources/extensions/gsd/tests/gsd-root-canonical.test.ts +66 -0
  158. package/src/resources/extensions/gsd/tests/gsd-root-home-guard.test.ts +68 -5
  159. package/src/resources/extensions/gsd/tests/guided-flow-prompt-consolidation.test.ts +4 -4
  160. package/src/resources/extensions/gsd/tests/integration/auto-worktree.test.ts +22 -12
  161. package/src/resources/extensions/gsd/tests/integration/doctor-proactive.test.ts +24 -10
  162. package/src/resources/extensions/gsd/tests/integration/doctor-runtime.test.ts +35 -23
  163. package/src/resources/extensions/gsd/tests/integration/workspace-collapse-integration.test.ts +369 -0
  164. package/src/resources/extensions/gsd/tests/interrupted-session-auto.test.ts +72 -25
  165. package/src/resources/extensions/gsd/tests/interrupted-session-ui.test.ts +72 -25
  166. package/src/resources/extensions/gsd/tests/memory-pressure-stuck-state.test.ts +9 -6
  167. package/src/resources/extensions/gsd/tests/metrics-atomic-merge.test.ts +222 -0
  168. package/src/resources/extensions/gsd/tests/metrics-lock-hardening.test.ts +400 -0
  169. package/src/resources/extensions/gsd/tests/metrics-lock-not-acquired.test.ts +141 -0
  170. package/src/resources/extensions/gsd/tests/metrics-lock-retry-sleep.test.ts +287 -0
  171. package/src/resources/extensions/gsd/tests/metrics-prune-cache-invalidation.test.ts +149 -0
  172. package/src/resources/extensions/gsd/tests/metrics-scope.test.ts +378 -0
  173. package/src/resources/extensions/gsd/tests/milestone-leases.test.ts +152 -0
  174. package/src/resources/extensions/gsd/tests/originalbase-path-comparison.test.ts +329 -0
  175. package/src/resources/extensions/gsd/tests/parallel-milestone-isolation.test.ts +106 -0
  176. package/src/resources/extensions/gsd/tests/path-cache-decoupled.test.ts +209 -0
  177. package/src/resources/extensions/gsd/tests/path-normalization-unified.test.ts +175 -0
  178. package/src/resources/extensions/gsd/tests/paths-cache.test.ts +170 -0
  179. package/src/resources/extensions/gsd/tests/paused-session-via-db.test.ts +119 -0
  180. package/src/resources/extensions/gsd/tests/pending-autostart-scope.test.ts +120 -0
  181. package/src/resources/extensions/gsd/tests/pipeline-variant-dispatch.test.ts +58 -0
  182. package/src/resources/extensions/gsd/tests/preferences-worktree-sync.test.ts +3 -17
  183. package/src/resources/extensions/gsd/tests/prompt-contracts.test.ts +150 -7
  184. package/src/resources/extensions/gsd/tests/register-hooks-depth-verification.test.ts +138 -16
  185. package/src/resources/extensions/gsd/tests/resume-missing-worktree-warning.test.ts +209 -0
  186. package/src/resources/extensions/gsd/tests/runtime-kv.test.ts +120 -0
  187. package/src/resources/extensions/gsd/tests/skipped-validation-completion.test.ts +133 -28
  188. package/src/resources/extensions/gsd/tests/skipped-validation-db-atomicity.test.ts +17 -0
  189. package/src/resources/extensions/gsd/tests/stuck-state-via-db.test.ts +134 -0
  190. package/src/resources/extensions/gsd/tests/sync-layer-scope.test.ts +434 -0
  191. package/src/resources/extensions/gsd/tests/teardown-chdir-failure-clears-registry.test.ts +162 -0
  192. package/src/resources/extensions/gsd/tests/teardown-cleanup-parity.test.ts +98 -0
  193. package/src/resources/extensions/gsd/tests/teardown-failure-clears-registry.test.ts +186 -0
  194. package/src/resources/extensions/gsd/tests/tool-invocation-error-loop-break.test.ts +1 -1
  195. package/src/resources/extensions/gsd/tests/unit-dispatches.test.ts +247 -0
  196. package/src/resources/extensions/gsd/tests/validate-milestone.test.ts +41 -1
  197. package/src/resources/extensions/gsd/tests/validator-scope-parity.test.ts +239 -0
  198. package/src/resources/extensions/gsd/tests/workflow-mcp.test.ts +2 -2
  199. package/src/resources/extensions/gsd/tests/workflow-tool-executors.test.ts +9 -15
  200. package/src/resources/extensions/gsd/tests/workspace.test.ts +196 -0
  201. package/src/resources/extensions/gsd/tests/write-gate-predicates.test.ts +35 -35
  202. package/src/resources/extensions/gsd/tests/write-gate.test.ts +94 -71
  203. package/src/resources/extensions/gsd/tests/write-intercept.test.ts +1 -1
  204. package/src/resources/extensions/gsd/workflow-mcp.ts +2 -2
  205. package/src/resources/extensions/gsd/workspace.ts +95 -0
  206. package/src/resources/extensions/gsd/worktree-resolver.ts +78 -2
  207. package/src/resources/extensions/gsd/write-intercept.ts +3 -3
  208. package/src/resources/extensions/gsd/tests/auto-lock-creation.test.ts +0 -213
  209. package/src/resources/extensions/gsd/tests/auto-stale-lock-self-kill.test.ts +0 -87
  210. package/src/resources/extensions/gsd/tests/stop-auto-remote.test.ts +0 -159
  211. /package/dist/web/standalone/.next/static/{oZGTPvJBQX_IDKKnuV8Bt → Y5UeGFkXTYM9WIQOWHkot}/_buildManifest.js +0 -0
  212. /package/dist/web/standalone/.next/static/{oZGTPvJBQX_IDKKnuV8Bt → Y5UeGFkXTYM9WIQOWHkot}/_ssgManifest.js +0 -0
@@ -1 +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 (err) {\n // Auth errors (401/403) mean the configured token is invalid or\n // revoked — re-throw so the caller can surface a useful error\n // immediately instead of silently spinning until the timeout.\n // Network/transient errors keep the retry behaviour.\n const msg = String((err as Error)?.message ?? err);\n if (msg.includes('HTTP 401') || msg.includes('HTTP 403')) {\n throw err;\n }\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 let answer: RemoteAnswer | null;\n try {\n answer = await pollUntilDone(config, prompt, ref, state, signal);\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 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"]}
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 (err) {\n // Auth errors (401/403) mean the configured token is invalid or\n // revoked — re-throw so the caller can surface a useful error\n // immediately instead of silently spinning until the timeout.\n // Network/transient errors keep the retry behaviour.\n const msg = String((err as Error)?.message ?? err);\n if (msg.includes('HTTP 401') || msg.includes('HTTP 403')) {\n throw err;\n }\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 * Normalize a `RemoteAnswer` into the `RoundResult` shape the GSD\n * discussion-gate hook reads from `tool_result` `details.response`. Mirrors\n * `src/resources/extensions/remote-questions/manager.ts:toRoundResultResponse`\n * and the local-path helper `buildAskUserQuestionsRoundResult` in server.ts.\n * Without this, the remote channel (Discord / Slack / Telegram) would have\n * the same gate-stuck problem as the local elicitation path. See #5267.\n *\n * `questions` is required so the multi-select contract is preserved: a\n * `allowMultiple` question with a single selection must still surface\n * `selected: [label]` so consumers reading `selected.includes(...)` keep\n * working. Falling back to length-based inference (the previous behavior)\n * silently demoted single-pick multi-select answers to strings.\n */\nexport function toRoundResultResponse(\n answer: RemoteAnswer,\n questions: RemoteQuestion[],\n): {\n endInterview: false;\n answers: Record<string, { selected: string | string[]; notes: string }>;\n} {\n const allowMultipleById = new Map<string, boolean>();\n for (const q of questions) allowMultipleById.set(q.id, q.allowMultiple ?? false);\n\n const normalized: Record<string, { selected: string | string[]; notes: string }> = {};\n for (const [id, data] of Object.entries(answer.answers)) {\n const list = data.answers ?? [];\n const allowMultiple = allowMultipleById.get(id) ?? false;\n const selected: string | string[] = allowMultiple ? list : (list[0] ?? '');\n normalized[id] = { selected, notes: data.user_note ?? '' };\n }\n return { endInterview: false, answers: normalized };\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 let answer: RemoteAnswer | null;\n try {\n answer = await pollUntilDone(config, prompt, ref, state, signal);\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 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 response: toRoundResultResponse(answer, questions),\n status: 'answered',\n },\n };\n}\n"]}
@@ -75,8 +75,34 @@ interface AskUserQuestionsElicitRequest {
75
75
  required?: string[];
76
76
  };
77
77
  }
78
+ /**
79
+ * Structured payload mirrored to the MCP `structuredContent` field on
80
+ * `ask_user_questions` results. Mirrors the `LocalResultDetails` shape that
81
+ * src/resources/extensions/ask-user-questions.ts already produces, so the
82
+ * GSD discussion-gate hook in register-hooks.ts can treat the MCP path
83
+ * identically to the in-process extension path. Without this, the bridge
84
+ * surfaces `details = undefined` and the gate hook's
85
+ * `if (details?.cancelled || !details?.response)` branch HARD-BLOCKs every
86
+ * user answer, including successful confirmations. See #5267.
87
+ */
88
+ interface AskUserQuestionsRoundResultAnswer {
89
+ selected: string | string[];
90
+ notes: string;
91
+ }
92
+ interface AskUserQuestionsRoundResult {
93
+ endInterview: false;
94
+ answers: Record<string, AskUserQuestionsRoundResultAnswer>;
95
+ }
78
96
  export declare function buildAskUserQuestionsElicitRequest(questions: AskUserQuestion[]): AskUserQuestionsElicitRequest;
79
97
  export declare function formatAskUserQuestionsElicitResult(questions: AskUserQuestion[], result: AskUserQuestionsElicitResult): string;
98
+ /**
99
+ * Normalize an MCP elicitation form result into the `RoundResult` shape the
100
+ * GSD discussion-gate hook reads from `tool_result` `details.response`. The
101
+ * elicitation `content` map carries `{ [id]: label, [id]__note?: string }`;
102
+ * the hook expects `{ answers: { [id]: { selected, notes } } }`. Mirrored into
103
+ * `structuredContent` by `askUserQuestionsHandler`. See #5267.
104
+ */
105
+ export declare function buildAskUserQuestionsRoundResult(questions: AskUserQuestion[], result: AskUserQuestionsElicitResult): AskUserQuestionsRoundResult;
80
106
  interface AskUserQuestionsHandlerDeps {
81
107
  elicitInput(params: AskUserQuestionsElicitRequest): Promise<AskUserQuestionsElicitResult>;
82
108
  isRemoteConfigured(): boolean;
@@ -99,12 +125,14 @@ type ToolContent = {
99
125
  type: 'text';
100
126
  text: string;
101
127
  }>;
128
+ structuredContent?: Record<string, unknown>;
102
129
  } | {
103
130
  isError: true;
104
131
  content: Array<{
105
132
  type: 'text';
106
133
  text: string;
107
134
  }>;
135
+ structuredContent?: Record<string, unknown>;
108
136
  };
109
137
  export declare function secureEnvCollectHandler(args: Record<string, unknown>, elicitInput: ElicitInputFn): Promise<ToolContent>;
110
138
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"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"}
@@ -298,6 +298,34 @@ export function formatAskUserQuestionsElicitResult(questions, result) {
298
298
  }
299
299
  return JSON.stringify({ answers });
300
300
  }
301
+ /**
302
+ * Normalize an MCP elicitation form result into the `RoundResult` shape the
303
+ * GSD discussion-gate hook reads from `tool_result` `details.response`. The
304
+ * elicitation `content` map carries `{ [id]: label, [id]__note?: string }`;
305
+ * the hook expects `{ answers: { [id]: { selected, notes } } }`. Mirrored into
306
+ * `structuredContent` by `askUserQuestionsHandler`. See #5267.
307
+ */
308
+ export function buildAskUserQuestionsRoundResult(questions, result) {
309
+ const answers = {};
310
+ const content = result.content ?? {};
311
+ for (const question of questions) {
312
+ if (question.allowMultiple) {
313
+ const list = normalizeAskUserQuestionsAnswers(content[question.id], true);
314
+ answers[question.id] = { selected: list, notes: '' };
315
+ continue;
316
+ }
317
+ const list = normalizeAskUserQuestionsAnswers(content[question.id], false);
318
+ const selected = list[0] ?? '';
319
+ const notes = selected === OTHER_OPTION_LABEL
320
+ ? normalizeAskUserQuestionsNote(content[`${question.id}__note`])
321
+ : '';
322
+ answers[question.id] = { selected, notes };
323
+ }
324
+ // `endInterview: false` mirrors the local extension's `RoundResult` shape and
325
+ // matches the remote path's `toRoundResultResponse` so register-hooks reads
326
+ // identical payloads regardless of channel. See peer review #5267-Q2.
327
+ return { endInterview: false, answers };
328
+ }
301
329
  function isLocalElicitFallbackError(err) {
302
330
  if (!(err instanceof Error))
303
331
  return false;
@@ -313,6 +341,18 @@ function isLocalElicitFallbackError(err) {
313
341
  function formatErrorMessage(err) {
314
342
  return err instanceof Error ? err.message : String(err);
315
343
  }
344
+ /**
345
+ * Defensive guard for the `details.response` payload from `tryRemoteQuestions`.
346
+ * Accepts only an object with a plain `answers` map; anything else (null,
347
+ * stringified JSON, missing) falls back to `null` so the gate hook routes
348
+ * the cancel branch instead of crashing on `details.response.answers[id]`.
349
+ */
350
+ function isRoundResultLike(value) {
351
+ if (!value || typeof value !== 'object')
352
+ return false;
353
+ const answers = value['answers'];
354
+ return !!answers && typeof answers === 'object' && !Array.isArray(answers);
355
+ }
316
356
  export async function askUserQuestionsHandler(questions, extra, deps) {
317
357
  try {
318
358
  const validationError = validateAskUserQuestionsPayload(questions);
@@ -326,7 +366,15 @@ export async function askUserQuestionsHandler(questions, extra, deps) {
326
366
  try {
327
367
  const elicitation = await withElicitTimeout(deps.elicitInput(buildAskUserQuestionsElicitRequest(questions)), 'ask_user_questions');
328
368
  if (elicitation.action === 'accept' && elicitation.content) {
329
- return textContent(formatAskUserQuestionsElicitResult(questions, elicitation));
369
+ const structured = {
370
+ questions,
371
+ response: buildAskUserQuestionsRoundResult(questions, elicitation),
372
+ cancelled: false,
373
+ };
374
+ return {
375
+ content: [{ type: 'text', text: formatAskUserQuestionsElicitResult(questions, elicitation) }],
376
+ structuredContent: structured,
377
+ };
330
378
  }
331
379
  }
332
380
  catch (err) {
@@ -351,14 +399,56 @@ export async function askUserQuestionsHandler(questions, extra, deps) {
351
399
  if (remoteResult) {
352
400
  const details = remoteResult.details;
353
401
  if (details?.['timed_out'] || details?.['error']) {
354
- return textContent(remoteResult.content[0]?.text ?? 'Remote questions timed out or failed');
402
+ // Mirror the timeout/error into structuredContent so the gate hook's
403
+ // `details?.cancelled || !details?.response` branch fires correctly
404
+ // (gate stays pending, model re-asks) instead of silently dropping
405
+ // because no `details` made it across the MCP wire. See #5267.
406
+ const failedStructured = {
407
+ questions,
408
+ response: null,
409
+ cancelled: true,
410
+ };
411
+ return {
412
+ content: [{ type: 'text', text: remoteResult.content[0]?.text ?? 'Remote questions timed out or failed' }],
413
+ structuredContent: failedStructured,
414
+ };
355
415
  }
356
- return textContent(remoteResult.content[0]?.text ?? '');
416
+ // Successful remote answer — surface the normalized RoundResult that
417
+ // remote-questions.ts attached to `details.response` so the gate hook
418
+ // sees `details.response.answers[id].selected` on this path too.
419
+ // A malformed `response` (failing isRoundResultLike) is reported as
420
+ // an explicit cancellation rather than a silent `cancelled: false`
421
+ // with `response: null` — the latter would lie to any consumer that
422
+ // reads `structuredContent.cancelled` independently of `.response`.
423
+ const hasValidResponse = isRoundResultLike(details?.['response']);
424
+ const acceptedStructured = hasValidResponse
425
+ ? {
426
+ questions,
427
+ response: details['response'],
428
+ cancelled: false,
429
+ }
430
+ : {
431
+ questions,
432
+ response: null,
433
+ cancelled: true,
434
+ };
435
+ return {
436
+ content: [{ type: 'text', text: remoteResult.content[0]?.text ?? '' }],
437
+ structuredContent: acceptedStructured,
438
+ };
357
439
  }
358
440
  }
359
441
  if (localElicitError)
360
442
  throw localElicitError;
361
- return textContent('ask_user_questions was cancelled before receiving a response');
443
+ const cancelledStructured = {
444
+ questions,
445
+ response: null,
446
+ cancelled: true,
447
+ };
448
+ return {
449
+ content: [{ type: 'text', text: 'ask_user_questions was cancelled before receiving a response' }],
450
+ structuredContent: cancelledStructured,
451
+ };
362
452
  }
363
453
  catch (err) {
364
454
  return errorContent(err instanceof Error ? err.message : String(err));