fix: [AI-7743] Altimate Code chat — MCP servers not getting added (question hang)
Summary
Fixes AI-7743 — in Altimate Code chat, /discover-and-add-mcps showed the "which MCP / what scope" question, but after the user answered it the chat sat on "Thinking…" forever and the MCP server was never added.
Root cause
After the v1.17.9 upstream merge (effect@4), src/question/index.ts is bundled as two separate module instances. Proven: a module-scoped id logged from the question tool's ask() differs from the one logged in the HTTP reply() route; normalizing every importer to @/question did not make Bun dedupe it. Each copy ran its own makeRuntime runtime, which broke the flow in two independent ways:
- State split. The
questiontool registered the pendingDeferredin one copy'sInstanceStatepending-map, whilePOST /question/:id/replylooked it up in the other copy's empty map. The reply returnedNotFoundError(HTTP 500) and theDeferrednever resolved, so the agent loop blocked forever → "Thinking…". (GET /questionreturned[]for the same reason.) - Event never reached the IDE webview.
question.askedwas published only viaEventV2Bridge→GlobalBus, but the/eventSSE stream the webview subscribes to is fed by the Bus wildcard PubSub (Bus.publish) — a different channel. So the webview'spendingQuestionsstayed empty, the answer card's Submit resolvedrequestId: undefined, and submitting did nothing.
Either half alone produces the reported "answer the question → nothing happens".
Fix (all in question/index.ts + import cleanup)
- State: anchor the pending-question registry on
globalThis(keyed by instance directory) so all module copies share one map. Restore per-instance cleanup viaregisterDisposerso entries don't leak across instances/tests. - Events: publish
question.asked/replied/rejectedviaBus.publish(addedBusEventmirrors) so they reach/eventlike every other webview-visible event. - Normalize the remaining relative
../questionimports to@/question.
Verification
End-to-end in Docker code-server (VS Code extension + real UI):
/discover-and-add-mcps→ question card renders → answer Yes / Project → ✅ datamate added to.altimate-code/altimate-code.json(enabled: true) and the chat shows the success summary.- Confirmed the webview now receives the event (
pendingQuestionspopulated, was[]) and the reply resolves (HTTP 200,message=replied). 55question unit tests pass (test/question,test/tool/question,test/release-validation/question-937*,test/cli/run/question.shared).
No changes were needed in the vscode-altimate-mcp-server extension.
🤖 Generated with Claude Code
Summary by cubic
Fixes AI-7743: answering the MCP add question in /discover-and-add-mcps no longer hangs. Question state is shared across bundled module copies, and events reach the webview without blocking resolution so the MCP server is added.
- Bug Fixes
- Share the pending-question registry on
globalThis(keyed by instance directory) with per-instance cleanup viaregisterDisposer, soask()and HTTPreply()resolve the same request; cleanup failures are logged. - Mirror
question.asked/replied/rejectedto/eventviaBus.publishusingBusEventwithzodschemas; mirrors are best-effort and kept off the Deferred critical path—reply()/reject()settle first, then publish.
- Share the pending-question registry on
Summary by CodeRabbit
-
New Features
- Forwarded question lifecycle events (asked, replied, rejected) to the IDE webview event stream.
- Standardized question handling so it’s shared consistently across modules within the same running application instance.
-
Bug Fixes
- Pending questions are now properly cleaned up when an instance is disposed.
- Any still-pending questions are automatically rejected instead of remaining unresolved.