@bastani/atomic 0.9.5-alpha.7 → 0.9.5-alpha.9
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.
- package/CHANGELOG.md +33 -2
- package/dist/builtin/cursor/package.json +2 -2
- package/dist/builtin/intercom/CHANGELOG.md +17 -0
- package/dist/builtin/intercom/README.md +27 -21
- package/dist/builtin/intercom/broker/broker.ts +3 -6
- package/dist/builtin/intercom/broker/paths.ts +42 -5
- package/dist/builtin/intercom/broker/spawn.ts +78 -10
- package/dist/builtin/intercom/config.ts +6 -3
- package/dist/builtin/intercom/contact-supervisor-tool.ts +6 -4
- package/dist/builtin/intercom/index-heavy.ts +1 -1
- package/dist/builtin/intercom/index.ts +162 -130
- package/dist/builtin/intercom/intercom-tool.ts +9 -3
- package/dist/builtin/intercom/package.json +10 -1
- package/dist/builtin/intercom/result-renderers.ts +1 -1
- package/dist/builtin/intercom/ui/compose.ts +2 -2
- package/dist/builtin/intercom/ui/inline-message.ts +2 -2
- package/dist/builtin/intercom/ui/session-list.ts +2 -2
- package/dist/builtin/mcp/CHANGELOG.md +11 -0
- package/dist/builtin/mcp/README.md +6 -6
- package/dist/builtin/mcp/direct-tools.ts +41 -23
- package/dist/builtin/mcp/index.ts +31 -4
- package/dist/builtin/mcp/init.ts +4 -43
- package/dist/builtin/mcp/metadata-hydration.ts +37 -0
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/mcp/proxy-info-modes.ts +67 -14
- package/dist/builtin/mcp/startup-warmup.ts +98 -0
- package/dist/builtin/mcp/tool-result-renderer.ts +3 -3
- package/dist/builtin/subagents/CHANGELOG.md +18 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/subagents/src/extension/index.ts +14 -25
- package/dist/builtin/subagents/src/extension/startup-maintenance.ts +89 -0
- package/dist/builtin/subagents/src/runs/background/async-execution-common.ts +23 -18
- package/dist/builtin/subagents/src/runs/background/result-watcher.ts +20 -10
- package/dist/builtin/subagents/src/runs/background/subagent-runner-streaming.ts +13 -3
- package/dist/builtin/subagents/src/runs/foreground/execution-attempt.ts +10 -2
- package/dist/builtin/subagents/src/runs/shared/pi-spawn.ts +28 -1
- package/dist/builtin/subagents/src/tui/render-event-formatting.ts +15 -48
- package/dist/builtin/subagents/src/tui/render-layout.ts +9 -0
- package/dist/builtin/subagents/src/tui/render-widget-graph.ts +27 -25
- package/dist/builtin/subagents/src/tui/render-widget.ts +72 -66
- package/dist/builtin/subagents/src/tui/render.ts +1 -1
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/workflows/CHANGELOG.md +29 -0
- package/dist/builtin/workflows/README.md +4 -2
- package/dist/builtin/workflows/builtin/goal-artifacts.ts +3 -1
- package/dist/builtin/workflows/builtin/goal-prompts.ts +23 -2
- package/dist/builtin/workflows/builtin/goal-reducer.ts +21 -0
- package/dist/builtin/workflows/builtin/goal-review.ts +60 -6
- package/dist/builtin/workflows/builtin/goal-runner.ts +71 -22
- package/dist/builtin/workflows/builtin/goal-types.ts +7 -1
- package/dist/builtin/workflows/builtin/ralph-core.ts +52 -4
- package/dist/builtin/workflows/builtin/ralph-review-gate.ts +10 -3
- package/dist/builtin/workflows/builtin/ralph-reviewer-prompt.ts +23 -2
- package/dist/builtin/workflows/builtin/ralph-runner.ts +38 -16
- package/dist/builtin/workflows/builtin/review-convergence.ts +111 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/skills/create-spec/SKILL.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/SKILL.md +16 -13
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.md +1 -0
- package/dist/builtin/workflows/skills/impeccable/reference/adapt.native.md +58 -0
- package/dist/builtin/workflows/skills/impeccable/reference/android.md +40 -0
- package/dist/builtin/workflows/skills/impeccable/reference/animate.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.md +2 -0
- package/dist/builtin/workflows/skills/impeccable/reference/audit.native.md +139 -0
- package/dist/builtin/workflows/skills/impeccable/reference/bolder.md +69 -62
- package/dist/builtin/workflows/skills/impeccable/reference/critique.md +21 -7
- package/dist/builtin/workflows/skills/impeccable/reference/document.md +1 -1
- package/dist/builtin/workflows/skills/impeccable/reference/hooks.md +92 -0
- package/dist/builtin/workflows/skills/impeccable/reference/init.md +29 -7
- package/dist/builtin/workflows/skills/impeccable/reference/ios.md +45 -0
- package/dist/builtin/workflows/skills/impeccable/reference/layout.md +25 -1
- package/dist/builtin/workflows/skills/impeccable/reference/typeset.md +23 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context-signals.mjs +2 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/context.mjs +75 -14
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/browser/injected/index.mjs +1 -1
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/cli/main.mjs +31 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/design-system.mjs +64 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/detect-antipatterns-browser.js +118 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/engines/regex/detect-text.mjs +16 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/registry/antipatterns.mjs +66 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/rules/checks.mjs +42 -10
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/fonts.mjs +30 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/detector/shared/page.mjs +4 -6
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-admin.mjs +660 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-before-edit.mjs +516 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook-lib.mjs +1764 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/hook.mjs +61 -0
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/impeccable-config.mjs +4 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/lib/is-generated.mjs +2 -2
- package/dist/builtin/workflows/skills/impeccable/scripts/live/svelte-component.mjs +13 -16
- package/dist/builtin/workflows/skills/impeccable/scripts/live-accept.mjs +17 -11
- package/dist/builtin/workflows/skills/impeccable/scripts/live-browser.js +104 -37
- package/dist/builtin/workflows/skills/impeccable/scripts/live-wrap.mjs +9 -0
- package/dist/builtin/workflows/src/durable/backend.ts +12 -0
- package/dist/builtin/workflows/src/durable/child-primitive.ts +12 -8
- package/dist/builtin/workflows/src/durable/dbos-backend.ts +63 -2
- package/dist/builtin/workflows/src/durable/dbos-envelope.ts +28 -0
- package/dist/builtin/workflows/src/durable/resume-catalog.ts +12 -0
- package/dist/builtin/workflows/src/durable/resume-runtime.ts +5 -2
- package/dist/builtin/workflows/src/durable/stage-primitive.ts +165 -27
- package/dist/builtin/workflows/src/durable/types.ts +30 -1
- package/dist/builtin/workflows/src/engine/primitives/task.ts +1 -0
- package/dist/builtin/workflows/src/engine/run-durable-finalize.ts +1 -2
- package/dist/builtin/workflows/src/engine/run-returned-status.ts +50 -16
- package/dist/builtin/workflows/src/engine/run.ts +32 -32
- package/dist/builtin/workflows/src/engine/runtime.ts +5 -0
- package/dist/builtin/workflows/src/extension/extension-factory.ts +3 -0
- package/dist/builtin/workflows/src/extension/extension-lifecycle.ts +9 -2
- package/dist/builtin/workflows/src/extension/extension-runtime-state.ts +137 -27
- package/dist/builtin/workflows/src/extension/lifecycle-notifications.ts +22 -6
- package/dist/builtin/workflows/src/extension/public-types.ts +1 -1
- package/dist/builtin/workflows/src/extension/workflow-command-completions.ts +13 -1
- package/dist/builtin/workflows/src/extension/workflow-command-registration.ts +19 -4
- package/dist/builtin/workflows/src/extension/workflow-command-surfaces.ts +9 -0
- package/dist/builtin/workflows/src/extension/workflow-prompts.ts +2 -0
- package/dist/builtin/workflows/src/extension/workflow-run-control-command.ts +48 -23
- package/dist/builtin/workflows/src/extension/workflow-tool-control.ts +20 -8
- package/dist/builtin/workflows/src/extension/workflow-tool.ts +24 -8
- package/dist/builtin/workflows/src/runs/background/status.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-continuation.ts +13 -3
- package/dist/builtin/workflows/src/runs/foreground/executor-direct-helpers.ts +29 -8
- package/dist/builtin/workflows/src/runs/foreground/executor-hil.ts +2 -1
- package/dist/builtin/workflows/src/runs/foreground/executor-stage-factory.ts +4 -3
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-controller.ts +18 -19
- package/dist/builtin/workflows/src/runs/foreground/stage-runner-unresolved-overflow.ts +38 -0
- package/dist/builtin/workflows/src/runs/shared/worktree-git.ts +155 -20
- package/dist/builtin/workflows/src/runs/shared/worktree-types.ts +6 -0
- package/dist/builtin/workflows/src/runs/shared/worktree.ts +2 -1
- package/dist/builtin/workflows/src/shared/persistence-restore-helpers.ts +18 -1
- package/dist/builtin/workflows/src/shared/persistence-restore.ts +23 -5
- package/dist/builtin/workflows/src/shared/persistence-session-entries.ts +4 -0
- package/dist/builtin/workflows/src/shared/returned-run-status.ts +116 -0
- package/dist/builtin/workflows/src/shared/workflow-failures-decisions.ts +2 -0
- package/dist/builtin/workflows/src/tui/graph-view-render-helpers.ts +21 -3
- package/dist/builtin/workflows/src/tui/graph-view-state.ts +3 -0
- package/dist/builtin/workflows/src/tui/graph-view-types.ts +3 -0
- package/dist/builtin/workflows/src/tui/status-list.ts +22 -15
- package/dist/builtin/workflows/src/tui/workflow-attach-pane.ts +4 -4
- package/dist/bun/internal-intercom-broker.d.ts +6 -0
- package/dist/bun/internal-intercom-broker.d.ts.map +1 -0
- package/dist/bun/internal-intercom-broker.js +39 -0
- package/dist/bun/internal-intercom-broker.js.map +1 -0
- package/dist/bun/split-loader.d.ts.map +1 -1
- package/dist/bun/split-loader.js +21 -8
- package/dist/bun/split-loader.js.map +1 -1
- package/dist/core/agent-session-auto-compaction.d.ts +21 -2
- package/dist/core/agent-session-auto-compaction.d.ts.map +1 -1
- package/dist/core/agent-session-auto-compaction.js +163 -11
- package/dist/core/agent-session-auto-compaction.js.map +1 -1
- package/dist/core/agent-session-events.d.ts.map +1 -1
- package/dist/core/agent-session-events.js +10 -1
- package/dist/core/agent-session-events.js.map +1 -1
- package/dist/core/agent-session-methods.d.ts +12 -3
- package/dist/core/agent-session-methods.d.ts.map +1 -1
- package/dist/core/agent-session-methods.js.map +1 -1
- package/dist/core/agent-session-models.d.ts +2 -2
- package/dist/core/agent-session-models.d.ts.map +1 -1
- package/dist/core/agent-session-models.js.map +1 -1
- package/dist/core/agent-session-prompt.d.ts.map +1 -1
- package/dist/core/agent-session-prompt.js +1 -0
- package/dist/core/agent-session-prompt.js.map +1 -1
- package/dist/core/agent-session-retry.d.ts +2 -0
- package/dist/core/agent-session-retry.d.ts.map +1 -1
- package/dist/core/agent-session-retry.js +152 -4
- package/dist/core/agent-session-retry.js.map +1 -1
- package/dist/core/agent-session-services.d.ts +1 -0
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session-types.d.ts +15 -1
- package/dist/core/agent-session-types.d.ts.map +1 -1
- package/dist/core/agent-session-types.js.map +1 -1
- package/dist/core/agent-session.d.ts +6 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +6 -0
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/context-compaction-runner.d.ts.map +1 -1
- package/dist/core/compaction/context-compaction-runner.js +36 -20
- package/dist/core/compaction/context-compaction-runner.js.map +1 -1
- package/dist/core/copilot-anthropic-sse-repair.d.ts +23 -0
- package/dist/core/copilot-anthropic-sse-repair.d.ts.map +1 -0
- package/dist/core/copilot-anthropic-sse-repair.js +340 -0
- package/dist/core/copilot-anthropic-sse-repair.js.map +1 -0
- package/dist/core/copilot-gemini-reasoning.d.ts +16 -8
- package/dist/core/copilot-gemini-reasoning.d.ts.map +1 -1
- package/dist/core/copilot-gemini-reasoning.js +27 -22
- package/dist/core/copilot-gemini-reasoning.js.map +1 -1
- package/dist/core/copilot-hosts.d.ts +12 -0
- package/dist/core/copilot-hosts.d.ts.map +1 -0
- package/dist/core/copilot-hosts.js +33 -0
- package/dist/core/copilot-hosts.js.map +1 -0
- package/dist/core/extensions/agent-events.d.ts +1 -1
- package/dist/core/extensions/agent-events.d.ts.map +1 -1
- package/dist/core/extensions/agent-events.js.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts +8 -1
- package/dist/core/extensions/loader-virtual-modules.d.ts.map +1 -1
- package/dist/core/extensions/loader-virtual-modules.js +2 -1
- package/dist/core/extensions/loader-virtual-modules.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts +6 -0
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +72 -29
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/http-dispatcher.d.ts.map +1 -1
- package/dist/core/http-dispatcher.js +5 -5
- package/dist/core/http-dispatcher.js.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.d.ts +1 -0
- package/dist/core/openai-responses-payload-sanitizer.d.ts.map +1 -1
- package/dist/core/openai-responses-payload-sanitizer.js +24 -9
- package/dist/core/openai-responses-payload-sanitizer.js.map +1 -1
- package/dist/core/sdk-types.d.ts +2 -0
- package/dist/core/sdk-types.d.ts.map +1 -1
- package/dist/core/sdk-types.js.map +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -0
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/settings-manager-basic-accessors.d.ts +1 -0
- package/dist/core/settings-manager-basic-accessors.d.ts.map +1 -1
- package/dist/core/settings-manager-basic-accessors.js +6 -0
- package/dist/core/settings-manager-basic-accessors.js.map +1 -1
- package/dist/core/settings-types.d.ts +1 -0
- package/dist/core/settings-types.d.ts.map +1 -1
- package/dist/core/settings-types.js.map +1 -1
- package/dist/core/slash-commands.d.ts +2 -0
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +141 -0
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/index-extensions.d.ts +1 -1
- package/dist/index-extensions.d.ts.map +1 -1
- package/dist/index-extensions.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/main-deferred-startup.d.ts +12 -0
- package/dist/main-deferred-startup.d.ts.map +1 -1
- package/dist/main-deferred-startup.js +23 -2
- package/dist/main-deferred-startup.js.map +1 -1
- package/dist/main-early-input.d.ts +41 -0
- package/dist/main-early-input.d.ts.map +1 -0
- package/dist/main-early-input.js +154 -0
- package/dist/main-early-input.js.map +1 -0
- package/dist/main.d.ts +0 -6
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +20 -14
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js +0 -1
- package/dist/modes/interactive/components/chat-session-host-actions.js.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.d.ts.map +1 -1
- package/dist/modes/interactive/components/chat-session-host-events.js +15 -0
- package/dist/modes/interactive/components/chat-session-host-events.js.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-agent-events.js +25 -0
- package/dist/modes/interactive/interactive-agent-events.js.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-autocomplete.js +21 -9
- package/dist/modes/interactive/interactive-autocomplete.js.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-deferred-startup.js +41 -28
- package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -0
- package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-input-handling.js +318 -185
- package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.d.ts +12 -0
- package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-base.js +39 -0
- package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -1
- package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js +1 -1
- package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.d.ts +6 -2
- package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.d.ts +3 -0
- package/dist/modes/interactive/interactive-mode-types.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode-types.js.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-model-routing.js +3 -1
- package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-process-lifecycle.js +0 -3
- package/dist/modes/interactive/interactive-process-lifecycle.js.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-render-chat.js +36 -10
- package/dist/modes/interactive/interactive-render-chat.js.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-session-routing.js +5 -1
- package/dist/modes/interactive/interactive-session-routing.js.map +1 -1
- package/dist/modes/interactive/interactive-startup.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-startup.js +26 -22
- package/dist/modes/interactive/interactive-startup.js.map +1 -1
- package/dist/modes/interactive/theme/global-theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/global-theme.js +26 -2
- package/dist/modes/interactive/theme/global-theme.js.map +1 -1
- package/dist/utils/fs-watch.d.ts +24 -1
- package/dist/utils/fs-watch.d.ts.map +1 -1
- package/dist/utils/fs-watch.js +60 -5
- package/dist/utils/fs-watch.js.map +1 -1
- package/docs/compaction.md +8 -0
- package/docs/development.md +4 -0
- package/docs/extensions.md +5 -0
- package/docs/json.md +3 -1
- package/docs/providers.md +1 -0
- package/docs/quickstart.md +1 -1
- package/docs/rpc.md +3 -1
- package/docs/settings.md +27 -1
- package/docs/subagents.md +4 -0
- package/docs/terminal-setup.md +4 -0
- package/docs/usage.md +2 -2
- package/docs/windows.md +4 -0
- package/docs/workflows.md +21 -9
- package/npm-shrinkwrap.json +513 -23
- package/package.json +3 -2
|
@@ -72,6 +72,37 @@ async function attemptDirectAutoAuth(
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
+
interface DirectToolSelection {
|
|
76
|
+
readonly servers: ReadonlySet<string>;
|
|
77
|
+
readonly toolsByServer: ReadonlyMap<string, ReadonlySet<string>>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function parseDirectToolSelection(items: readonly string[] | undefined): DirectToolSelection {
|
|
81
|
+
const servers = new Set<string>();
|
|
82
|
+
const toolsByServer = new Map<string, Set<string>>();
|
|
83
|
+
for (const rawItem of items ?? []) {
|
|
84
|
+
const item = rawItem.replace(/\/+$/, "");
|
|
85
|
+
if (!item) continue;
|
|
86
|
+
if (!item.includes("/")) {
|
|
87
|
+
servers.add(item);
|
|
88
|
+
continue;
|
|
89
|
+
}
|
|
90
|
+
const [server, tool] = item.split("/", 2);
|
|
91
|
+
if (!server) continue;
|
|
92
|
+
if (!tool) {
|
|
93
|
+
servers.add(server);
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
if (!toolsByServer.has(server)) toolsByServer.set(server, new Set());
|
|
97
|
+
toolsByServer.get(server)!.add(tool);
|
|
98
|
+
}
|
|
99
|
+
return { servers, toolsByServer };
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
function directToolSelectionIncludes(selection: DirectToolSelection, serverName: string): boolean {
|
|
103
|
+
return selection.servers.has(serverName) || selection.toolsByServer.has(serverName);
|
|
104
|
+
}
|
|
105
|
+
|
|
75
106
|
export function resolveDirectTools(
|
|
76
107
|
config: McpConfig,
|
|
77
108
|
cache: MetadataCache | null,
|
|
@@ -83,24 +114,7 @@ export function resolveDirectTools(
|
|
|
83
114
|
|
|
84
115
|
const seenNames = new Set<string>();
|
|
85
116
|
|
|
86
|
-
const
|
|
87
|
-
const envTools = new Map<string, Set<string>>();
|
|
88
|
-
if (envOverride) {
|
|
89
|
-
for (let item of envOverride) {
|
|
90
|
-
item = item.replace(/\/+$/, "");
|
|
91
|
-
if (item.includes("/")) {
|
|
92
|
-
const [server, tool] = item.split("/", 2);
|
|
93
|
-
if (server && tool) {
|
|
94
|
-
if (!envTools.has(server)) envTools.set(server, new Set());
|
|
95
|
-
envTools.get(server)!.add(tool);
|
|
96
|
-
} else if (server) {
|
|
97
|
-
envServers.add(server);
|
|
98
|
-
}
|
|
99
|
-
} else if (item) {
|
|
100
|
-
envServers.add(item);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
117
|
+
const envSelection = parseDirectToolSelection(envOverride);
|
|
104
118
|
|
|
105
119
|
const globalDirect = config.settings?.directTools;
|
|
106
120
|
|
|
@@ -111,10 +125,10 @@ export function resolveDirectTools(
|
|
|
111
125
|
let toolFilter: true | string[] | false = false;
|
|
112
126
|
|
|
113
127
|
if (envOverride) {
|
|
114
|
-
if (
|
|
128
|
+
if (envSelection.servers.has(serverName)) {
|
|
115
129
|
toolFilter = true;
|
|
116
|
-
} else if (
|
|
117
|
-
toolFilter = [...
|
|
130
|
+
} else if (envSelection.toolsByServer.has(serverName)) {
|
|
131
|
+
toolFilter = [...envSelection.toolsByServer.get(serverName)!];
|
|
118
132
|
}
|
|
119
133
|
} else {
|
|
120
134
|
if (definition.directTools !== undefined) {
|
|
@@ -182,14 +196,18 @@ export function resolveDirectTools(
|
|
|
182
196
|
export function getMissingConfiguredDirectToolServers(
|
|
183
197
|
config: McpConfig,
|
|
184
198
|
cache: MetadataCache | null,
|
|
199
|
+
envOverride?: readonly string[],
|
|
185
200
|
): string[] {
|
|
186
201
|
const missing: string[] = [];
|
|
187
202
|
const globalDirect = config.settings?.directTools;
|
|
188
|
-
|
|
203
|
+
const envSelection = parseDirectToolSelection(envOverride);
|
|
189
204
|
for (const [serverName, definition] of Object.entries(config.mcpServers)) {
|
|
190
|
-
const
|
|
205
|
+
const hasConfiguredDirectTools = definition.directTools !== undefined
|
|
191
206
|
? !!definition.directTools
|
|
192
207
|
: !!globalDirect;
|
|
208
|
+
const hasDirectTools = envOverride
|
|
209
|
+
? directToolSelectionIncludes(envSelection, serverName)
|
|
210
|
+
: hasConfiguredDirectTools;
|
|
193
211
|
|
|
194
212
|
if (!hasDirectTools) continue;
|
|
195
213
|
|
|
@@ -39,6 +39,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
39
39
|
let lifecycleGeneration = 0;
|
|
40
40
|
let registeredDirectToolNames = new Set<string>();
|
|
41
41
|
let registeredProxyTool = false;
|
|
42
|
+
let startupWarmupCancel: (() => void) | null = null;
|
|
42
43
|
|
|
43
44
|
async function registerDirectToolsFromConfig(
|
|
44
45
|
config: McpConfig,
|
|
@@ -50,13 +51,14 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
50
51
|
]);
|
|
51
52
|
const prefix = config.settings?.toolPrefix ?? "server";
|
|
52
53
|
const envRaw = process.env.MCP_DIRECT_TOOLS;
|
|
54
|
+
const envDirectTools = envRaw?.split(",").map(s => s.trim()).filter(Boolean);
|
|
53
55
|
const directSpecs = envRaw === "__none__"
|
|
54
56
|
? []
|
|
55
57
|
: resolveDirectTools(
|
|
56
58
|
config,
|
|
57
59
|
cache,
|
|
58
60
|
prefix,
|
|
59
|
-
|
|
61
|
+
envDirectTools,
|
|
60
62
|
);
|
|
61
63
|
for (const spec of directSpecs) {
|
|
62
64
|
if (registeredDirectToolNames.has(spec.prefixedName)) continue;
|
|
@@ -75,7 +77,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
75
77
|
refreshTools?.();
|
|
76
78
|
return {
|
|
77
79
|
directToolCount: directSpecs.length,
|
|
78
|
-
missingConfiguredDirectToolServers: getMissingConfiguredDirectToolServers(config, cache),
|
|
80
|
+
missingConfiguredDirectToolServers: getMissingConfiguredDirectToolServers(config, cache, envDirectTools),
|
|
79
81
|
};
|
|
80
82
|
}
|
|
81
83
|
|
|
@@ -129,12 +131,18 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
129
131
|
type: "string",
|
|
130
132
|
});
|
|
131
133
|
|
|
134
|
+
function cancelStartupWarmup(): void {
|
|
135
|
+
startupWarmupCancel?.();
|
|
136
|
+
startupWarmupCancel = null;
|
|
137
|
+
}
|
|
138
|
+
|
|
132
139
|
pi.on("session_start", async (_event, ctx) => {
|
|
133
140
|
const generation = ++lifecycleGeneration;
|
|
134
141
|
const previousState = state;
|
|
135
142
|
state = null;
|
|
136
143
|
initPromise = null;
|
|
137
144
|
registeredDirectToolNames = new Set<string>();
|
|
145
|
+
cancelStartupWarmup();
|
|
138
146
|
|
|
139
147
|
try {
|
|
140
148
|
const config = loadMcpConfig(earlyConfigPath, ctx.cwd);
|
|
@@ -168,7 +176,10 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
168
176
|
throw new Error("Stale MCP session initialization cancelled before startup");
|
|
169
177
|
}
|
|
170
178
|
|
|
171
|
-
const { initializeMcp, updateStatusBar } = await
|
|
179
|
+
const [{ initializeMcp, updateStatusBar }, { scheduleMcpStartupWarmup }] = await Promise.all([
|
|
180
|
+
import("./init.ts"),
|
|
181
|
+
import("./startup-warmup.ts"),
|
|
182
|
+
]);
|
|
172
183
|
if (generation !== lifecycleGeneration || !isContextActive(ctx)) {
|
|
173
184
|
throw new Error("Stale MCP session initialization cancelled before startup");
|
|
174
185
|
}
|
|
@@ -193,6 +204,21 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
193
204
|
) {
|
|
194
205
|
registerProxyTool();
|
|
195
206
|
}
|
|
207
|
+
let cancelWarmup: (() => void) | null = null;
|
|
208
|
+
const warmup = scheduleMcpStartupWarmup(nextState, {
|
|
209
|
+
shouldContinue: () => generation === lifecycleGeneration && state === nextState,
|
|
210
|
+
onDirectToolsChanged: async () => {
|
|
211
|
+
if (generation !== lifecycleGeneration || state !== nextState) return;
|
|
212
|
+
await registerDirectTools(nextState);
|
|
213
|
+
},
|
|
214
|
+
onSettled: () => {
|
|
215
|
+
if (generation === lifecycleGeneration && state === nextState && startupWarmupCancel === cancelWarmup) {
|
|
216
|
+
startupWarmupCancel = null;
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
cancelWarmup = () => warmup.cancel();
|
|
221
|
+
startupWarmupCancel = cancelWarmup;
|
|
196
222
|
if (initPromise === promiseRef.current) {
|
|
197
223
|
initPromise = null;
|
|
198
224
|
}
|
|
@@ -226,6 +252,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
226
252
|
state = null;
|
|
227
253
|
initPromise = null;
|
|
228
254
|
registeredDirectToolNames = new Set<string>();
|
|
255
|
+
cancelStartupWarmup();
|
|
229
256
|
|
|
230
257
|
try {
|
|
231
258
|
await Promise.all([
|
|
@@ -409,7 +436,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
409
436
|
return executeConnect(state, params.connect);
|
|
410
437
|
}
|
|
411
438
|
if (params.describe) {
|
|
412
|
-
return executeDescribe(state, params.describe);
|
|
439
|
+
return executeDescribe(state, params.describe, params.server);
|
|
413
440
|
}
|
|
414
441
|
if (params.search) {
|
|
415
442
|
return executeSearch(state, params.search, params.regex, params.server, params.includeSchemas);
|
package/dist/builtin/mcp/init.ts
CHANGED
|
@@ -21,7 +21,6 @@ import { buildToolMetadata, totalToolCount } from "./tool-metadata.ts";
|
|
|
21
21
|
import { UiResourceHandler } from "./ui-resource-handler.ts";
|
|
22
22
|
import { openUrl, parallelLimit } from "./utils.ts";
|
|
23
23
|
import { logger } from "./logger.ts";
|
|
24
|
-
import { getMissingConfiguredDirectToolServers } from "./direct-tools.ts";
|
|
25
24
|
|
|
26
25
|
const FAILURE_BACKOFF_MS = 60 * 1000;
|
|
27
26
|
|
|
@@ -75,10 +74,7 @@ export async function initializeMcp(
|
|
|
75
74
|
const cachePath = getMetadataCachePath();
|
|
76
75
|
const cacheFileExists = existsSync(cachePath);
|
|
77
76
|
let cache = loadMetadataCache();
|
|
78
|
-
let bootstrapAll = false;
|
|
79
|
-
|
|
80
77
|
if (!cacheFileExists) {
|
|
81
|
-
bootstrapAll = true;
|
|
82
78
|
saveMetadataCache({ version: 1, servers: {} });
|
|
83
79
|
} else if (!cache) {
|
|
84
80
|
cache = { version: 1, servers: {} };
|
|
@@ -105,12 +101,10 @@ export async function initializeMcp(
|
|
|
105
101
|
}
|
|
106
102
|
}
|
|
107
103
|
|
|
108
|
-
const startupServers =
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
return mode === "keep-alive" || mode === "eager";
|
|
113
|
-
});
|
|
104
|
+
const startupServers = serverEntries.filter(([, definition]) => {
|
|
105
|
+
const mode = definition.lifecycle ?? "lazy";
|
|
106
|
+
return mode === "keep-alive" || mode === "eager";
|
|
107
|
+
});
|
|
114
108
|
|
|
115
109
|
if (ctx.hasUI && startupServers.length > 0) {
|
|
116
110
|
ctx.ui.setStatus("mcp", `MCP: connecting to ${startupServers.length} servers...`);
|
|
@@ -160,39 +154,6 @@ export async function initializeMcp(
|
|
|
160
154
|
ctx.ui.notify(msg, "info");
|
|
161
155
|
}
|
|
162
156
|
|
|
163
|
-
const envDirect = process.env.MCP_DIRECT_TOOLS;
|
|
164
|
-
if (envDirect !== "__none__") {
|
|
165
|
-
const currentCache = loadMetadataCache();
|
|
166
|
-
const missingCacheServers = getMissingConfiguredDirectToolServers(config, currentCache);
|
|
167
|
-
|
|
168
|
-
if (missingCacheServers.length > 0) {
|
|
169
|
-
const bootstrapResults = await parallelLimit(
|
|
170
|
-
missingCacheServers.filter(name => !results.some(r => r.name === name && r.connection)),
|
|
171
|
-
10,
|
|
172
|
-
async (name) => {
|
|
173
|
-
const definition = config.mcpServers[name];
|
|
174
|
-
try {
|
|
175
|
-
const connection = await manager.connect(name, definition);
|
|
176
|
-
if (connection.status === "needs-auth") {
|
|
177
|
-
return { name, ok: false };
|
|
178
|
-
}
|
|
179
|
-
const { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
|
|
180
|
-
toolMetadata.set(name, metadata);
|
|
181
|
-
updateMetadataCache(state, name);
|
|
182
|
-
return { name, ok: true };
|
|
183
|
-
} catch (error) {
|
|
184
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
185
|
-
logger.debug(`MCP: direct-tools bootstrap failed for ${name}: ${message}`);
|
|
186
|
-
return { name, ok: false };
|
|
187
|
-
}
|
|
188
|
-
},
|
|
189
|
-
);
|
|
190
|
-
const bootstrapped = bootstrapResults.filter(r => r.ok).map(r => r.name);
|
|
191
|
-
if (bootstrapped.length > 0 && ctx.hasUI) {
|
|
192
|
-
ctx.ui.notify(`MCP: direct tools for ${bootstrapped.join(", ")} will be available after restart`, "info");
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
157
|
|
|
197
158
|
lifecycle.setReconnectCallback((serverName) => {
|
|
198
159
|
updateServerMetadata(state, serverName);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { McpExtensionState } from "./state.ts";
|
|
2
|
+
import { lazyConnect, updateMetadataCache, updateServerMetadata } from "./init.ts";
|
|
3
|
+
import { parallelLimit } from "./utils.ts";
|
|
4
|
+
|
|
5
|
+
export async function hydrateServerMetadata(
|
|
6
|
+
state: McpExtensionState,
|
|
7
|
+
serverName: string,
|
|
8
|
+
): Promise<boolean> {
|
|
9
|
+
if (state.toolMetadata.has(serverName)) return true;
|
|
10
|
+
if (!state.config.mcpServers[serverName]) return false;
|
|
11
|
+
|
|
12
|
+
const connection = state.manager.getConnection(serverName);
|
|
13
|
+
if (connection?.status === "connected") {
|
|
14
|
+
updateServerMetadata(state, serverName);
|
|
15
|
+
updateMetadataCache(state, serverName);
|
|
16
|
+
return state.toolMetadata.has(serverName);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return lazyConnect(state, serverName);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export async function hydrateMissingMetadata(
|
|
23
|
+
state: McpExtensionState,
|
|
24
|
+
options?: { server?: string },
|
|
25
|
+
): Promise<void> {
|
|
26
|
+
if (options?.server) {
|
|
27
|
+
await hydrateServerMetadata(state, options.server);
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const missingServers = Object.keys(state.config.mcpServers).filter(
|
|
32
|
+
(serverName) => !state.toolMetadata.has(serverName),
|
|
33
|
+
);
|
|
34
|
+
await parallelLimit(missingServers, 10, async (serverName) => {
|
|
35
|
+
await hydrateServerMetadata(state, serverName);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/mcp",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.9",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension that adapts MCP (Model Context Protocol) servers into the coding agent. Fork of: https://github.com/nicobailon/pi-mcp-adapter",
|
|
6
6
|
"contributors": [
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import type { McpExtensionState } from "./state.ts";
|
|
2
2
|
import type { ToolMetadata } from "./types.ts";
|
|
3
|
-
import { parseUiPromptHandoff } from "./types.ts";
|
|
3
|
+
import { getServerPrefix, parseUiPromptHandoff } from "./types.ts";
|
|
4
4
|
import { getFailureAgeSeconds } from "./init.ts";
|
|
5
5
|
import { findToolByName, formatSchema } from "./tool-metadata.ts";
|
|
6
6
|
import { truncateAtWord } from "./utils.ts";
|
|
7
|
+
import { hydrateMissingMetadata } from "./metadata-hydration.ts";
|
|
7
8
|
import type { ProxyToolResult } from "./proxy-types.ts";
|
|
8
9
|
|
|
9
10
|
export function executeUiMessages(state: McpExtensionState): ProxyToolResult {
|
|
@@ -140,26 +141,73 @@ export function executeStatus(state: McpExtensionState): ProxyToolResult {
|
|
|
140
141
|
};
|
|
141
142
|
}
|
|
142
143
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
144
|
+
function findToolMetadata(
|
|
145
|
+
state: McpExtensionState,
|
|
146
|
+
toolName: string,
|
|
147
|
+
server?: string,
|
|
148
|
+
): { serverName: string; toolMeta: ToolMetadata } | null {
|
|
149
|
+
for (const [serverName, metadata] of state.toolMetadata.entries()) {
|
|
150
|
+
if (server && serverName !== server) continue;
|
|
151
|
+
const toolMeta = findToolByName(metadata, toolName);
|
|
152
|
+
if (toolMeta) return { serverName, toolMeta };
|
|
153
|
+
}
|
|
154
|
+
return null;
|
|
155
|
+
}
|
|
146
156
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
157
|
+
function normalizeToolAlias(value: string): string {
|
|
158
|
+
return value.replace(/-/g, "_");
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function prefixHydrationCandidates(state: McpExtensionState, toolName: string): string[] {
|
|
162
|
+
const prefixMode = state.config.settings?.toolPrefix ?? "server";
|
|
163
|
+
if (prefixMode === "none") return [];
|
|
164
|
+
const normalizedToolName = normalizeToolAlias(toolName);
|
|
165
|
+
return Object.keys(state.config.mcpServers)
|
|
166
|
+
.map((serverName) => ({ serverName, prefix: normalizeToolAlias(getServerPrefix(serverName, prefixMode)) }))
|
|
167
|
+
.filter(({ prefix }) => prefix.length > 0 && normalizedToolName.startsWith(`${prefix}_`))
|
|
168
|
+
.sort((a, b) => b.prefix.length - a.prefix.length)
|
|
169
|
+
.map(({ serverName }) => serverName);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
async function hydrateDescribeMetadata(state: McpExtensionState, toolName: string, server?: string): Promise<void> {
|
|
173
|
+
if (server) {
|
|
174
|
+
await hydrateMissingMetadata(state, { server });
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
const candidates = prefixHydrationCandidates(state, toolName);
|
|
179
|
+
if (candidates.length > 0) {
|
|
180
|
+
for (const candidate of candidates) {
|
|
181
|
+
await hydrateMissingMetadata(state, { server: candidate });
|
|
182
|
+
if (findToolMetadata(state, toolName, candidate)) return;
|
|
153
183
|
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if (findToolMetadata(state, toolName)) return;
|
|
188
|
+
await hydrateMissingMetadata(state);
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
export async function executeDescribe(
|
|
192
|
+
state: McpExtensionState,
|
|
193
|
+
toolName: string,
|
|
194
|
+
server?: string,
|
|
195
|
+
): Promise<ProxyToolResult> {
|
|
196
|
+
let found = findToolMetadata(state, toolName, server);
|
|
197
|
+
if (!found) {
|
|
198
|
+
await hydrateDescribeMetadata(state, toolName, server);
|
|
199
|
+
found = findToolMetadata(state, toolName, server);
|
|
154
200
|
}
|
|
155
201
|
|
|
156
|
-
if (!
|
|
202
|
+
if (!found) {
|
|
157
203
|
return {
|
|
158
204
|
content: [{ type: "text" as const, text: `Tool "${toolName}" not found. Use mcp({ search: "..." }) to search.` }],
|
|
159
205
|
details: { mode: "describe", error: "tool_not_found", requestedTool: toolName },
|
|
160
206
|
};
|
|
161
207
|
}
|
|
162
208
|
|
|
209
|
+
const { serverName, toolMeta } = found;
|
|
210
|
+
|
|
163
211
|
let text = `${toolMeta.name}\n`;
|
|
164
212
|
text += `Server: ${serverName}\n`;
|
|
165
213
|
if (toolMeta.resourceUri) {
|
|
@@ -181,13 +229,13 @@ export function executeDescribe(state: McpExtensionState, toolName: string): Pro
|
|
|
181
229
|
};
|
|
182
230
|
}
|
|
183
231
|
|
|
184
|
-
export function executeSearch(
|
|
232
|
+
export async function executeSearch(
|
|
185
233
|
state: McpExtensionState,
|
|
186
234
|
query: string,
|
|
187
235
|
regex?: boolean,
|
|
188
236
|
server?: string,
|
|
189
237
|
includeSchemas?: boolean,
|
|
190
|
-
): ProxyToolResult {
|
|
238
|
+
): Promise<ProxyToolResult> {
|
|
191
239
|
const showSchemas = includeSchemas !== false;
|
|
192
240
|
|
|
193
241
|
const matches: Array<{ server: string; tool: ToolMetadata }> = [];
|
|
@@ -213,6 +261,7 @@ export function executeSearch(
|
|
|
213
261
|
details: { mode: "search", error: "invalid_pattern", query },
|
|
214
262
|
};
|
|
215
263
|
}
|
|
264
|
+
await hydrateMissingMetadata(state, { server });
|
|
216
265
|
|
|
217
266
|
for (const [serverName, metadata] of state.toolMetadata.entries()) {
|
|
218
267
|
if (server && serverName !== server) continue;
|
|
@@ -270,7 +319,7 @@ export function executeSearch(
|
|
|
270
319
|
};
|
|
271
320
|
}
|
|
272
321
|
|
|
273
|
-
export function executeList(state: McpExtensionState, server: string): ProxyToolResult {
|
|
322
|
+
export async function executeList(state: McpExtensionState, server: string): Promise<ProxyToolResult> {
|
|
274
323
|
if (!state.config.mcpServers[server]) {
|
|
275
324
|
return {
|
|
276
325
|
content: [{ type: "text" as const, text: `Server "${server}" not found. Use mcp({}) to see available servers.` }],
|
|
@@ -278,6 +327,10 @@ export function executeList(state: McpExtensionState, server: string): ProxyTool
|
|
|
278
327
|
};
|
|
279
328
|
}
|
|
280
329
|
|
|
330
|
+
if (!state.toolMetadata.has(server)) {
|
|
331
|
+
await hydrateMissingMetadata(state, { server });
|
|
332
|
+
}
|
|
333
|
+
|
|
281
334
|
const metadata = state.toolMetadata.get(server);
|
|
282
335
|
const toolNames = metadata?.map(m => m.name) ?? [];
|
|
283
336
|
const connection = state.manager.getConnection(server);
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import type { McpExtensionState } from "./state.ts";
|
|
2
|
+
import { getMissingConfiguredDirectToolServers } from "./direct-tools.ts";
|
|
3
|
+
import { loadMetadataCache } from "./metadata-cache.ts";
|
|
4
|
+
import { buildToolMetadata } from "./tool-metadata.ts";
|
|
5
|
+
import { parallelLimit } from "./utils.ts";
|
|
6
|
+
import { logger } from "./logger.ts";
|
|
7
|
+
import { updateMetadataCache, updateStatusBar } from "./init.ts";
|
|
8
|
+
|
|
9
|
+
export interface McpStartupWarmupOptions {
|
|
10
|
+
shouldContinue?: () => boolean;
|
|
11
|
+
onDirectToolsChanged?: () => void | Promise<void>;
|
|
12
|
+
onSettled?: () => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export interface McpStartupWarmupHandle {
|
|
16
|
+
readonly promise: Promise<void>;
|
|
17
|
+
cancel(): void;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function deferToMacrotask(): Promise<void> {
|
|
21
|
+
return new Promise((resolve) => setImmediate(resolve));
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export function scheduleMcpStartupWarmup(
|
|
25
|
+
state: McpExtensionState,
|
|
26
|
+
options: McpStartupWarmupOptions = {},
|
|
27
|
+
): McpStartupWarmupHandle {
|
|
28
|
+
let cancelled = false;
|
|
29
|
+
const shouldContinue = (): boolean => !cancelled && (options.shouldContinue?.() ?? true);
|
|
30
|
+
|
|
31
|
+
const promise = (async () => {
|
|
32
|
+
await deferToMacrotask();
|
|
33
|
+
if (!shouldContinue()) return;
|
|
34
|
+
|
|
35
|
+
const envDirect = process.env.MCP_DIRECT_TOOLS;
|
|
36
|
+
if (envDirect === "__none__") return;
|
|
37
|
+
|
|
38
|
+
const envDirectTools = envDirect?.split(",").map((item) => item.trim()).filter(Boolean);
|
|
39
|
+
const missingCacheServers = getMissingConfiguredDirectToolServers(state.config, loadMetadataCache(), envDirectTools)
|
|
40
|
+
.filter((name) => state.manager.getConnection(name)?.status !== "connected");
|
|
41
|
+
if (missingCacheServers.length === 0) return;
|
|
42
|
+
|
|
43
|
+
const prefix = state.config.settings?.toolPrefix ?? "server";
|
|
44
|
+
const results = await parallelLimit(missingCacheServers, 10, async (name) => {
|
|
45
|
+
if (!shouldContinue()) return { name, ok: false };
|
|
46
|
+
const definition = state.config.mcpServers[name];
|
|
47
|
+
if (!definition) return { name, ok: false };
|
|
48
|
+
try {
|
|
49
|
+
const connection = await state.manager.connect(name, definition);
|
|
50
|
+
if (!shouldContinue()) {
|
|
51
|
+
if (state.manager.getConnection(name) === connection) {
|
|
52
|
+
await state.manager.close(name);
|
|
53
|
+
}
|
|
54
|
+
return { name, ok: false };
|
|
55
|
+
}
|
|
56
|
+
if (connection.status === "needs-auth") return { name, ok: false };
|
|
57
|
+
const { metadata } = buildToolMetadata(connection.tools, connection.resources, definition, name, prefix);
|
|
58
|
+
state.toolMetadata.set(name, metadata);
|
|
59
|
+
updateMetadataCache(state, name);
|
|
60
|
+
return { name, ok: true };
|
|
61
|
+
} catch (error) {
|
|
62
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
63
|
+
logger.debug(`MCP: background direct-tools warmup failed for ${name}: ${message}`);
|
|
64
|
+
return { name, ok: false };
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
if (!shouldContinue()) return;
|
|
69
|
+
const warmed = results.filter((result) => result.ok).map((result) => result.name);
|
|
70
|
+
if (warmed.length === 0) return;
|
|
71
|
+
updateStatusBar(state);
|
|
72
|
+
if (!shouldContinue()) return;
|
|
73
|
+
await options.onDirectToolsChanged?.();
|
|
74
|
+
if (!shouldContinue()) return;
|
|
75
|
+
if (state.ui) {
|
|
76
|
+
state.ui.notify(`MCP: direct tools for ${warmed.join(", ")} are now available`, "info");
|
|
77
|
+
}
|
|
78
|
+
})()
|
|
79
|
+
.catch((error) => {
|
|
80
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
81
|
+
logger.debug(`MCP: background startup warmup failed: ${message}`);
|
|
82
|
+
})
|
|
83
|
+
.finally(() => {
|
|
84
|
+
try {
|
|
85
|
+
options.onSettled?.();
|
|
86
|
+
} catch (error) {
|
|
87
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
88
|
+
logger.debug(`MCP: background startup warmup settled callback failed: ${message}`);
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
return {
|
|
93
|
+
promise,
|
|
94
|
+
cancel() {
|
|
95
|
+
cancelled = true;
|
|
96
|
+
},
|
|
97
|
+
};
|
|
98
|
+
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { keyText, type AgentToolResult, type ToolRenderResultOptions } from "@bastani/atomic";
|
|
2
2
|
import { Text } from "@earendil-works/pi-tui";
|
|
3
3
|
|
|
4
|
-
type McpToolResultDetails = Record<string, unknown> & { error?: unknown };
|
|
4
|
+
export type McpToolResultDetails = Record<string, unknown> & { error?: unknown };
|
|
5
5
|
type McpToolContentBlock = AgentToolResult<McpToolResultDetails>["content"][number];
|
|
6
6
|
|
|
7
7
|
interface RenderTheme {
|
|
@@ -58,7 +58,7 @@ export function renderMcpToolResult(
|
|
|
58
58
|
.map((line) => line === "…" ? theme.fg("muted", line) : theme.fg("toolOutput", line))
|
|
59
59
|
.join("\n");
|
|
60
60
|
const hint = display.truncated && !options.expanded
|
|
61
|
-
? `\n${theme.fg("muted", "
|
|
61
|
+
? `\n${theme.fg("muted", `(${keyText("app.tools.expand")} Expand)`)}`
|
|
62
62
|
: "";
|
|
63
63
|
|
|
64
64
|
return new Text(`${output}${hint}`, 0, 0);
|
|
@@ -2,6 +2,24 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.9.5-alpha.9] - 2026-07-09
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Improved subagent extension startup by deferring old-run cleanup scans, result watcher startup, and existing-result priming to macrotasks while preserving immediate `subagent` tool and slash-command registration.
|
|
10
|
+
|
|
11
|
+
### Fixed
|
|
12
|
+
|
|
13
|
+
- Fixed background async result watching on Windows to use Atomic's safe watcher path strategy and fall back to polling when native `fs.watch` would receive an unsafe or non-canonical watcher path.
|
|
14
|
+
- Fixed async/background subagent status visibility while the fullscreen workflow graph is active by publishing the live async summary through the shared status surface in addition to the below-editor widget.
|
|
15
|
+
- Fixed foreground and background subagent startup diagnostics so missing or invalid child `cwd` values are reported as working-directory problems before spawn, while runtime spawn failures include the attempted command and cwd instead of ambiguous `ENOENT` output.
|
|
16
|
+
|
|
17
|
+
## [0.9.5-alpha.8] - 2026-07-08
|
|
18
|
+
|
|
19
|
+
### Fixed
|
|
20
|
+
|
|
21
|
+
- Updated async/background subagent status widgets so running job, parallel child-agent, chain-step, and nested child rows reuse the same foreground pulsing-dot glyph treatment instead of braille spinner glyphs, while preserving counts, metadata, live-detail hints, and output paths.
|
|
22
|
+
|
|
5
23
|
## [0.9.5-alpha.5] - 2026-07-06
|
|
6
24
|
|
|
7
25
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.9.5-alpha.
|
|
3
|
+
"version": "0.9.5-alpha.9",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension for delegating tasks to subagents with chains, parallel execution, and TUI clarification. Fork of: https://github.com/nicobailon/pi-subagents",
|
|
6
6
|
"contributors": [
|