fix: [AI-7743] Altimate Code chat — MCP servers not getting added (question hang)

Merged
SA
3mo ago
+117-23

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:

  1. State split. The question tool registered the pending Deferred in one copy's InstanceState pending-map, while POST /question/:id/reply looked it up in the other copy's empty map. The reply returned NotFoundError (HTTP 500) and the Deferred never resolved, so the agent loop blocked forever → "Thinking…". (GET /question returned [] for the same reason.)
  2. Event never reached the IDE webview. question.asked was published only via EventV2Bridge → GlobalBus, but the /event SSE stream the webview subscribes to is fed by the Bus wildcard PubSub (Bus.publish) — a different channel. So the webview's pendingQuestions stayed empty, the answer card's Submit resolved requestId: 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 via registerDisposer so entries don't leak across instances/tests.
  • Events: publish question.asked / replied / rejected via Bus.publish (added BusEvent mirrors) so they reach /event like every other webview-visible event.
  • Normalize the remaining relative ../question imports 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 (pendingQuestions populated, was []) and the reply resolves (HTTP 200, message=replied).
  • 55 question 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 via registerDisposer, so ask() and HTTP reply() resolve the same request; cleanup failures are logged.
    • Mirror question.asked / replied / rejected to /event via Bus.publish using BusEvent with zod schemas; mirrors are best-effort and kept off the Deferred critical path—reply()/reject() settle first, then publish.

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.