@bastani/atomic 0.8.25-alpha.1 → 0.8.26-alpha.1
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 +17 -0
- package/dist/builtin/intercom/CHANGELOG.md +12 -0
- package/dist/builtin/intercom/index-heavy.ts +1754 -0
- package/dist/builtin/intercom/index.ts +374 -1746
- package/dist/builtin/intercom/package.json +1 -1
- package/dist/builtin/intercom/result-renderers.ts +77 -0
- package/dist/builtin/mcp/CHANGELOG.md +16 -0
- package/dist/builtin/mcp/index.ts +151 -57
- package/dist/builtin/mcp/package.json +1 -1
- package/dist/builtin/subagents/CHANGELOG.md +12 -0
- package/dist/builtin/subagents/package.json +1 -1
- package/dist/builtin/web-access/CHANGELOG.md +12 -0
- package/dist/builtin/web-access/index-heavy.ts +2060 -0
- package/dist/builtin/web-access/index.ts +182 -2274
- package/dist/builtin/web-access/package.json +1 -1
- package/dist/builtin/web-access/result-renderers.ts +364 -0
- package/dist/builtin/workflows/CHANGELOG.md +15 -0
- package/dist/builtin/workflows/package.json +1 -1
- package/dist/builtin/workflows/src/extension/index.ts +13 -3
- package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +53 -2
- package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +12 -3
- package/dist/builtin/workflows/src/tui/inline-form-store.ts +17 -6
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +13 -0
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +7 -0
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +13 -1
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/resource-loader.d.ts.map +1 -1
- package/dist/core/resource-loader.js +17 -0
- package/dist/core/resource-loader.js.map +1 -1
- package/dist/core/timings.d.ts +9 -0
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +28 -1
- package/dist/core/timings.js.map +1 -1
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +4 -2
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/custom-message.d.ts +1 -0
- package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
- package/dist/modes/interactive/components/custom-message.js +36 -4
- package/dist/modes/interactive/components/custom-message.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +19 -7
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/intercom",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.26-alpha.1",
|
|
4
4
|
"private": true,
|
|
5
5
|
"description": "Atomic extension providing a private coordination channel between parent and child agent sessions. Fork of: https://github.com/nicobailon/pi-intercom",
|
|
6
6
|
"contributors": [
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import type { ToolDefinition } from "@bastani/atomic";
|
|
2
|
+
import { Text } from "@mariozechner/pi-tui";
|
|
3
|
+
|
|
4
|
+
type ToolResultRenderer = NonNullable<ToolDefinition["renderResult"]>;
|
|
5
|
+
type ToolRenderResultArgs = Parameters<ToolResultRenderer>;
|
|
6
|
+
type ToolRenderResult = ReturnType<ToolResultRenderer>;
|
|
7
|
+
type RenderedResult = ToolRenderResultArgs[0];
|
|
8
|
+
type TextContentBlock = Extract<RenderedResult["content"][number], { type: "text" }>;
|
|
9
|
+
|
|
10
|
+
type IntercomResultDetails = {
|
|
11
|
+
delivered?: boolean;
|
|
12
|
+
error?: boolean;
|
|
13
|
+
messageId?: string;
|
|
14
|
+
reason?: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
type ContactSupervisorResultDetails = IntercomResultDetails & {
|
|
18
|
+
structuredReplyParseError?: string;
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
function isTextContentBlock(block: RenderedResult["content"][number]): block is TextContentBlock {
|
|
22
|
+
return block.type === "text";
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function firstTextContent(result: RenderedResult): string {
|
|
26
|
+
return result.content.find(isTextContentBlock)?.text.replace(/\*\*/g, "") ?? "";
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export const renderContactSupervisorResult: ToolResultRenderer = (result, { isPartial }, theme, context) => {
|
|
30
|
+
if (isPartial) {
|
|
31
|
+
return new Text(theme.fg("warning", "Waiting for supervisor..."), 0, 0);
|
|
32
|
+
}
|
|
33
|
+
const details = result.details as ContactSupervisorResultDetails | undefined;
|
|
34
|
+
const textContent = firstTextContent(result);
|
|
35
|
+
const failed = Boolean(context.isError || details?.error === true || details?.delivered === false);
|
|
36
|
+
const parseWarning = typeof details?.structuredReplyParseError === "string";
|
|
37
|
+
let text = failed
|
|
38
|
+
? theme.fg("error", "✗ ")
|
|
39
|
+
: parseWarning
|
|
40
|
+
? theme.fg("warning", "⚠ ")
|
|
41
|
+
: theme.fg("success", "✓ ");
|
|
42
|
+
text += theme.fg(failed ? "error" : "text", textContent);
|
|
43
|
+
if (parseWarning) {
|
|
44
|
+
text += "\n" + theme.fg("warning", `Structured reply parse issue: ${details.structuredReplyParseError}`);
|
|
45
|
+
}
|
|
46
|
+
return new Text(text, 0, 0);
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const renderIntercomResult: ToolResultRenderer = (result, { isPartial }, theme, context) => {
|
|
50
|
+
if (isPartial) {
|
|
51
|
+
return new Text(theme.fg("warning", "Intercom working..."), 0, 0);
|
|
52
|
+
}
|
|
53
|
+
const details = result.details as IntercomResultDetails | undefined;
|
|
54
|
+
const failed = Boolean(context.isError || details?.error === true || details?.delivered === false);
|
|
55
|
+
let text = failed ? theme.fg("error", "✗ ") : theme.fg("success", "✓ ");
|
|
56
|
+
text += theme.fg(failed ? "error" : "text", firstTextContent(result));
|
|
57
|
+
if (details?.messageId && !context.expanded) {
|
|
58
|
+
text += theme.fg("dim", ` (${details.messageId.slice(0, 8)})`);
|
|
59
|
+
}
|
|
60
|
+
if (details?.reason && context.expanded) {
|
|
61
|
+
text += "\n" + theme.fg("dim", `Reason: ${details.reason}`);
|
|
62
|
+
}
|
|
63
|
+
return new Text(text, 0, 0);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
export function renderIntercomToolResult(name: string, args: ToolRenderResultArgs): ToolRenderResult {
|
|
67
|
+
switch (name) {
|
|
68
|
+
case "intercom":
|
|
69
|
+
return renderIntercomResult(...args);
|
|
70
|
+
case "contact_supervisor":
|
|
71
|
+
return renderContactSupervisorResult(...args);
|
|
72
|
+
default: {
|
|
73
|
+
const theme = args[2];
|
|
74
|
+
return new Text(theme.fg("error", `Result renderer not found: ${name}`), 0, 0);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -7,6 +7,22 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.8.26-alpha.1] - 2026-06-05
|
|
11
|
+
|
|
12
|
+
### Changed
|
|
13
|
+
|
|
14
|
+
- Kept MCP startup registration cheap by lazily importing the heavy MCP command, initialization, proxy-mode, and OAuth/auth-flow modules (and deferring config/cache-backed direct-tool discovery) instead of loading them on the cold extension factory path, while keeping the result renderer synchronous so restored MCP tool results still render ([#1223](https://github.com/bastani-inc/atomic/issues/1223)).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- Stopped logging a spurious "MCP initialization failed: This extension ctx is stale..." error when a session backing the captured `pi`/`ctx` is disposed (e.g. a workflow child stage session) during MCP's deferred `session_start` initialization. The deferred init now liveness-checks the captured context before and after `initializeMcp()` and treats a stale-context error as a cancellation rather than a failure. The async gap that exposed this race was introduced by the lazy-load startup change ([#1223](https://github.com/bastani-inc/atomic/issues/1223)).
|
|
19
|
+
|
|
20
|
+
## [0.8.25] - 2026-06-04
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- Promoted the 0.8.25 prerelease package version to a stable release.
|
|
25
|
+
|
|
10
26
|
## [0.8.25-alpha.1] - 2026-06-04
|
|
11
27
|
|
|
12
28
|
### Changed
|
|
@@ -1,20 +1,93 @@
|
|
|
1
1
|
import type { AgentToolUpdateCallback, ExtensionAPI, ExtensionContext, ToolInfo } from "@bastani/atomic";
|
|
2
2
|
import type { McpExtensionState } from "./state.ts";
|
|
3
|
+
import type { McpConfig } from "./types.ts";
|
|
4
|
+
import type { MetadataCache } from "./metadata-cache.ts";
|
|
3
5
|
import { Type } from "typebox";
|
|
4
|
-
import { showStatus, showTools, reconnectServers, authenticateServer, logoutServer, openMcpAuthPanel, openMcpPanel, openMcpSetup } from "./commands.ts";
|
|
5
6
|
import { loadMcpConfig } from "./config.ts";
|
|
6
|
-
import {
|
|
7
|
-
import { flushMetadataCache, initializeMcp, updateStatusBar } from "./init.ts";
|
|
8
|
-
import { loadMetadataCache } from "./metadata-cache.ts";
|
|
9
|
-
import { executeCall, executeConnect, executeDescribe, executeList, executeSearch, executeStatus, executeUiMessages } from "./proxy-modes.ts";
|
|
10
|
-
import { getConfigPathFromArgv, truncateAtWord } from "./utils.ts";
|
|
11
|
-
import { shutdownOAuth } from "./mcp-auth-flow.ts";
|
|
7
|
+
import { getConfigPathFromArgv } from "./utils.ts";
|
|
12
8
|
import { renderMcpToolResult } from "./tool-result-renderer.ts";
|
|
13
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Marker substring from the host's stale-context error (see ExtensionRunner.invalidate).
|
|
12
|
+
* A captured `pi`/`ctx` becomes stale when its backing session is disposed (e.g. a
|
|
13
|
+
* workflow child stage session, or a reload/replace) without emitting `session_shutdown`.
|
|
14
|
+
*/
|
|
15
|
+
const STALE_EXTENSION_CONTEXT_MARKER = "extension ctx is stale";
|
|
16
|
+
|
|
17
|
+
function isStaleExtensionContextError(error: unknown): boolean {
|
|
18
|
+
return error instanceof Error && error.message.includes(STALE_EXTENSION_CONTEXT_MARKER);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Probe whether a captured extension context is still active. Every `ctx` getter runs
|
|
23
|
+
* the host's `assertActive()` guard, so a cheap property read surfaces staleness without
|
|
24
|
+
* mutating anything. Returns false when the context has been invalidated by a dispose.
|
|
25
|
+
*/
|
|
26
|
+
function isContextActive(ctx: ExtensionContext): boolean {
|
|
27
|
+
try {
|
|
28
|
+
void ctx.cwd;
|
|
29
|
+
return true;
|
|
30
|
+
} catch (error) {
|
|
31
|
+
if (isStaleExtensionContextError(error)) return false;
|
|
32
|
+
throw error;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
14
36
|
export default function mcpAdapter(pi: ExtensionAPI) {
|
|
15
37
|
let state: McpExtensionState | null = null;
|
|
16
38
|
let initPromise: Promise<McpExtensionState> | null = null;
|
|
17
39
|
let lifecycleGeneration = 0;
|
|
40
|
+
let registeredDirectToolNames = new Set<string>();
|
|
41
|
+
let registeredProxyTool = false;
|
|
42
|
+
|
|
43
|
+
async function registerDirectToolsFromConfig(
|
|
44
|
+
config: McpConfig,
|
|
45
|
+
cache: MetadataCache | null,
|
|
46
|
+
): Promise<{ directToolCount: number; missingConfiguredDirectToolServers: string[] }> {
|
|
47
|
+
const [{ resolveDirectTools, createDirectToolExecutor, getMissingConfiguredDirectToolServers }, { truncateAtWord }] = await Promise.all([
|
|
48
|
+
import("./direct-tools.ts"),
|
|
49
|
+
import("./utils.ts"),
|
|
50
|
+
]);
|
|
51
|
+
const prefix = config.settings?.toolPrefix ?? "server";
|
|
52
|
+
const envRaw = process.env.MCP_DIRECT_TOOLS;
|
|
53
|
+
const directSpecs = envRaw === "__none__"
|
|
54
|
+
? []
|
|
55
|
+
: resolveDirectTools(
|
|
56
|
+
config,
|
|
57
|
+
cache,
|
|
58
|
+
prefix,
|
|
59
|
+
envRaw?.split(",").map(s => s.trim()).filter(Boolean),
|
|
60
|
+
);
|
|
61
|
+
for (const spec of directSpecs) {
|
|
62
|
+
if (registeredDirectToolNames.has(spec.prefixedName)) continue;
|
|
63
|
+
registeredDirectToolNames.add(spec.prefixedName);
|
|
64
|
+
(pi.registerTool as (tool: unknown) => unknown)({
|
|
65
|
+
name: spec.prefixedName,
|
|
66
|
+
label: `MCP: ${spec.originalName}`,
|
|
67
|
+
description: spec.description || "(no description)",
|
|
68
|
+
promptSnippet: truncateAtWord(spec.description, 100) || `MCP tool from ${spec.serverName}`,
|
|
69
|
+
parameters: Type.Unsafe((spec.inputSchema || { type: "object", properties: {} }) as never),
|
|
70
|
+
execute: createDirectToolExecutor(() => state, () => initPromise, spec),
|
|
71
|
+
renderResult: renderMcpToolResult,
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
const refreshTools = (pi as { refreshTools?: () => void }).refreshTools;
|
|
75
|
+
refreshTools?.();
|
|
76
|
+
return {
|
|
77
|
+
directToolCount: directSpecs.length,
|
|
78
|
+
missingConfiguredDirectToolServers: getMissingConfiguredDirectToolServers(config, cache),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async function registerDirectTools(nextState: McpExtensionState): Promise<{ directToolCount: number; missingConfiguredDirectToolServers: string[] }> {
|
|
83
|
+
const { loadMetadataCache } = await import("./metadata-cache.ts");
|
|
84
|
+
return registerDirectToolsFromConfig(nextState.config, loadMetadataCache());
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function shutdownOAuthFlow(): Promise<void> {
|
|
88
|
+
const { shutdownOAuth } = await import("./mcp-auth-flow.ts");
|
|
89
|
+
await shutdownOAuth();
|
|
90
|
+
}
|
|
18
91
|
|
|
19
92
|
async function shutdownState(currentState: McpExtensionState | null, reason: string): Promise<void> {
|
|
20
93
|
if (!currentState) return;
|
|
@@ -26,6 +99,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
26
99
|
|
|
27
100
|
let flushError: unknown;
|
|
28
101
|
try {
|
|
102
|
+
const { flushMetadataCache } = await import("./init.ts");
|
|
29
103
|
flushMetadataCache(currentState);
|
|
30
104
|
} catch (error) {
|
|
31
105
|
flushError = error;
|
|
@@ -47,36 +121,6 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
47
121
|
}
|
|
48
122
|
|
|
49
123
|
const earlyConfigPath = getConfigPathFromArgv();
|
|
50
|
-
const earlyConfig = loadMcpConfig(earlyConfigPath);
|
|
51
|
-
const earlyCache = loadMetadataCache();
|
|
52
|
-
const prefix = earlyConfig.settings?.toolPrefix ?? "server";
|
|
53
|
-
|
|
54
|
-
const envRaw = process.env.MCP_DIRECT_TOOLS;
|
|
55
|
-
const directSpecs = envRaw === "__none__"
|
|
56
|
-
? []
|
|
57
|
-
: resolveDirectTools(
|
|
58
|
-
earlyConfig,
|
|
59
|
-
earlyCache,
|
|
60
|
-
prefix,
|
|
61
|
-
envRaw?.split(",").map(s => s.trim()).filter(Boolean),
|
|
62
|
-
);
|
|
63
|
-
const missingConfiguredDirectToolServers = getMissingConfiguredDirectToolServers(earlyConfig, earlyCache);
|
|
64
|
-
const shouldRegisterProxyTool =
|
|
65
|
-
earlyConfig.settings?.disableProxyTool !== true
|
|
66
|
-
|| directSpecs.length === 0
|
|
67
|
-
|| missingConfiguredDirectToolServers.length > 0;
|
|
68
|
-
|
|
69
|
-
for (const spec of directSpecs) {
|
|
70
|
-
(pi.registerTool as (tool: unknown) => unknown)({
|
|
71
|
-
name: spec.prefixedName,
|
|
72
|
-
label: `MCP: ${spec.originalName}`,
|
|
73
|
-
description: spec.description || "(no description)",
|
|
74
|
-
promptSnippet: truncateAtWord(spec.description, 100) || `MCP tool from ${spec.serverName}`,
|
|
75
|
-
parameters: Type.Unsafe((spec.inputSchema || { type: "object", properties: {} }) as never),
|
|
76
|
-
execute: createDirectToolExecutor(() => state, () => initPromise, spec),
|
|
77
|
-
renderResult: renderMcpToolResult,
|
|
78
|
-
});
|
|
79
|
-
}
|
|
80
124
|
|
|
81
125
|
const getPiTools = (): ToolInfo[] => pi.getAllTools();
|
|
82
126
|
|
|
@@ -90,45 +134,89 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
90
134
|
const previousState = state;
|
|
91
135
|
state = null;
|
|
92
136
|
initPromise = null;
|
|
137
|
+
registeredDirectToolNames = new Set<string>();
|
|
93
138
|
|
|
94
139
|
try {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
140
|
+
const config = loadMcpConfig(earlyConfigPath, ctx.cwd);
|
|
141
|
+
const { loadMetadataCache } = await import("./metadata-cache.ts");
|
|
142
|
+
const directToolState = await registerDirectToolsFromConfig(config, loadMetadataCache());
|
|
143
|
+
if (
|
|
144
|
+
config.settings?.disableProxyTool !== true
|
|
145
|
+
|| directToolState.directToolCount === 0
|
|
146
|
+
|| directToolState.missingConfiguredDirectToolServers.length > 0
|
|
147
|
+
) {
|
|
148
|
+
registerProxyTool();
|
|
149
|
+
}
|
|
99
150
|
} catch (error) {
|
|
100
|
-
|
|
151
|
+
if (isStaleExtensionContextError(error)) return;
|
|
152
|
+
console.error("MCP: failed to register cached startup tools; enabling MCP proxy fallback", error);
|
|
153
|
+
registerProxyTool();
|
|
101
154
|
}
|
|
102
155
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
156
|
+
const promiseRef: { current: Promise<McpExtensionState> | null } = { current: null };
|
|
157
|
+
const promise = (async () => {
|
|
158
|
+
try {
|
|
159
|
+
await Promise.all([
|
|
160
|
+
shutdownState(previousState, "session_restart"),
|
|
161
|
+
shutdownOAuthFlow(),
|
|
162
|
+
]);
|
|
163
|
+
} catch (error) {
|
|
164
|
+
console.error("MCP: failed to shut down previous session state", error);
|
|
165
|
+
}
|
|
106
166
|
|
|
107
|
-
|
|
108
|
-
|
|
167
|
+
if (generation !== lifecycleGeneration || !isContextActive(ctx)) {
|
|
168
|
+
throw new Error("Stale MCP session initialization cancelled before startup");
|
|
169
|
+
}
|
|
109
170
|
|
|
110
|
-
|
|
111
|
-
if (generation !== lifecycleGeneration ||
|
|
171
|
+
const { initializeMcp, updateStatusBar } = await import("./init.ts");
|
|
172
|
+
if (generation !== lifecycleGeneration || !isContextActive(ctx)) {
|
|
173
|
+
throw new Error("Stale MCP session initialization cancelled before startup");
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
const nextState = await initializeMcp(pi, ctx);
|
|
177
|
+
if (generation !== lifecycleGeneration || initPromise !== promiseRef.current || !isContextActive(ctx)) {
|
|
112
178
|
try {
|
|
113
179
|
await shutdownState(nextState, "stale_session_start");
|
|
114
180
|
} catch (error) {
|
|
115
181
|
console.error("MCP: failed to clean stale session state", error);
|
|
116
182
|
}
|
|
117
|
-
|
|
183
|
+
throw new Error("Stale MCP session initialization cancelled after startup");
|
|
118
184
|
}
|
|
119
185
|
|
|
120
186
|
state = nextState;
|
|
121
187
|
updateStatusBar(nextState);
|
|
122
|
-
|
|
123
|
-
|
|
188
|
+
const directToolState = await registerDirectTools(nextState);
|
|
189
|
+
if (
|
|
190
|
+
nextState.config.settings?.disableProxyTool !== true
|
|
191
|
+
|| directToolState.directToolCount === 0
|
|
192
|
+
|| directToolState.missingConfiguredDirectToolServers.length > 0
|
|
193
|
+
) {
|
|
194
|
+
registerProxyTool();
|
|
195
|
+
}
|
|
196
|
+
if (initPromise === promiseRef.current) {
|
|
197
|
+
initPromise = null;
|
|
198
|
+
}
|
|
199
|
+
return nextState;
|
|
200
|
+
})();
|
|
201
|
+
promiseRef.current = promise;
|
|
202
|
+
initPromise = promise;
|
|
203
|
+
promise.catch((err) => {
|
|
124
204
|
if (generation !== lifecycleGeneration) {
|
|
125
205
|
return;
|
|
126
206
|
}
|
|
127
207
|
if (initPromise !== promise && initPromise !== null) {
|
|
128
208
|
return;
|
|
129
209
|
}
|
|
130
|
-
|
|
131
|
-
|
|
210
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
211
|
+
if (
|
|
212
|
+
!message.startsWith("Stale MCP session initialization cancelled") &&
|
|
213
|
+
!isStaleExtensionContextError(err)
|
|
214
|
+
) {
|
|
215
|
+
console.error("MCP initialization failed:", err);
|
|
216
|
+
}
|
|
217
|
+
if (initPromise === promise) {
|
|
218
|
+
initPromise = null;
|
|
219
|
+
}
|
|
132
220
|
});
|
|
133
221
|
});
|
|
134
222
|
|
|
@@ -137,11 +225,12 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
137
225
|
const currentState = state;
|
|
138
226
|
state = null;
|
|
139
227
|
initPromise = null;
|
|
228
|
+
registeredDirectToolNames = new Set<string>();
|
|
140
229
|
|
|
141
230
|
try {
|
|
142
231
|
await Promise.all([
|
|
143
232
|
shutdownState(currentState, "session_shutdown"),
|
|
144
|
-
|
|
233
|
+
shutdownOAuthFlow(),
|
|
145
234
|
]);
|
|
146
235
|
} catch (error) {
|
|
147
236
|
console.error("MCP: session shutdown cleanup failed", error);
|
|
@@ -165,6 +254,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
165
254
|
return;
|
|
166
255
|
}
|
|
167
256
|
|
|
257
|
+
const { showStatus, showTools, reconnectServers, logoutServer, openMcpPanel, openMcpSetup } = await import("./commands.ts");
|
|
168
258
|
const parts = args?.trim()?.split(/\s+/) ?? [];
|
|
169
259
|
const subcommand = parts[0] ?? "";
|
|
170
260
|
const targetServer = parts[1];
|
|
@@ -233,6 +323,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
233
323
|
return;
|
|
234
324
|
}
|
|
235
325
|
|
|
326
|
+
const { authenticateServer, openMcpAuthPanel } = await import("./commands.ts");
|
|
236
327
|
if (!serverName) {
|
|
237
328
|
await openMcpAuthPanel(state, pi, ctx, earlyConfigPath);
|
|
238
329
|
return;
|
|
@@ -242,11 +333,13 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
242
333
|
},
|
|
243
334
|
});
|
|
244
335
|
|
|
245
|
-
|
|
336
|
+
function registerProxyTool(): void {
|
|
337
|
+
if (registeredProxyTool) return;
|
|
338
|
+
registeredProxyTool = true;
|
|
246
339
|
(pi.registerTool as (tool: unknown) => unknown)({
|
|
247
340
|
name: "mcp",
|
|
248
341
|
label: "MCP",
|
|
249
|
-
description:
|
|
342
|
+
description: "MCP gateway for connecting to configured MCP servers, searching tools, describing schemas, and calling tools lazily after MCP initialization.",
|
|
250
343
|
promptSnippet: "MCP gateway - connect to MCP servers and call their tools",
|
|
251
344
|
parameters: Type.Object({
|
|
252
345
|
tool: Type.Optional(Type.String({ description: "Tool name to call (e.g., 'xcodebuild_list_sims')" })),
|
|
@@ -305,6 +398,7 @@ export default function mcpAdapter(pi: ExtensionAPI) {
|
|
|
305
398
|
};
|
|
306
399
|
}
|
|
307
400
|
|
|
401
|
+
const { executeCall, executeConnect, executeDescribe, executeList, executeSearch, executeStatus, executeUiMessages } = await import("./proxy-modes.ts");
|
|
308
402
|
if (params.action === "ui-messages") {
|
|
309
403
|
return executeUiMessages(state);
|
|
310
404
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/mcp",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.26-alpha.1",
|
|
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": [
|
|
@@ -2,6 +2,18 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.8.26-alpha.1] - 2026-06-05
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Bumped package version for the Atomic 0.8.26-alpha.1 prerelease.
|
|
10
|
+
|
|
11
|
+
## [0.8.25] - 2026-06-04
|
|
12
|
+
|
|
13
|
+
### Changed
|
|
14
|
+
|
|
15
|
+
- Promoted the 0.8.25 prerelease package version to a stable release.
|
|
16
|
+
|
|
5
17
|
## [0.8.25-alpha.1] - 2026-06-04
|
|
6
18
|
|
|
7
19
|
### Changed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bastani/subagents",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.26-alpha.1",
|
|
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": [
|
|
@@ -4,6 +4,18 @@ All notable changes to this project will be documented in this file.
|
|
|
4
4
|
|
|
5
5
|
## [Unreleased]
|
|
6
6
|
|
|
7
|
+
## [0.8.26-alpha.1] - 2026-06-05
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
|
|
11
|
+
- Deferred heavy search, fetch, curator, summary, provider-probing, and code-search modules until the relevant web-access tool or command is invoked, reducing default CLI startup cost ([#1223](https://github.com/bastani-inc/atomic/issues/1223)).
|
|
12
|
+
|
|
13
|
+
## [0.8.25] - 2026-06-04
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Promoted the 0.8.25 prerelease package version to a stable release.
|
|
18
|
+
|
|
7
19
|
## [0.8.25-alpha.1] - 2026-06-04
|
|
8
20
|
|
|
9
21
|
### Changed
|