@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.
Files changed (49) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/dist/builtin/intercom/CHANGELOG.md +12 -0
  3. package/dist/builtin/intercom/index-heavy.ts +1754 -0
  4. package/dist/builtin/intercom/index.ts +374 -1746
  5. package/dist/builtin/intercom/package.json +1 -1
  6. package/dist/builtin/intercom/result-renderers.ts +77 -0
  7. package/dist/builtin/mcp/CHANGELOG.md +16 -0
  8. package/dist/builtin/mcp/index.ts +151 -57
  9. package/dist/builtin/mcp/package.json +1 -1
  10. package/dist/builtin/subagents/CHANGELOG.md +12 -0
  11. package/dist/builtin/subagents/package.json +1 -1
  12. package/dist/builtin/web-access/CHANGELOG.md +12 -0
  13. package/dist/builtin/web-access/index-heavy.ts +2060 -0
  14. package/dist/builtin/web-access/index.ts +182 -2274
  15. package/dist/builtin/web-access/package.json +1 -1
  16. package/dist/builtin/web-access/result-renderers.ts +364 -0
  17. package/dist/builtin/workflows/CHANGELOG.md +15 -0
  18. package/dist/builtin/workflows/package.json +1 -1
  19. package/dist/builtin/workflows/src/extension/index.ts +13 -3
  20. package/dist/builtin/workflows/src/runs/foreground/stage-runner.ts +53 -2
  21. package/dist/builtin/workflows/src/tui/inline-form-overlay.ts +12 -3
  22. package/dist/builtin/workflows/src/tui/inline-form-store.ts +17 -6
  23. package/dist/core/agent-session-services.d.ts.map +1 -1
  24. package/dist/core/agent-session-services.js +13 -0
  25. package/dist/core/agent-session-services.js.map +1 -1
  26. package/dist/core/extensions/loader.d.ts.map +1 -1
  27. package/dist/core/extensions/loader.js +7 -0
  28. package/dist/core/extensions/loader.js.map +1 -1
  29. package/dist/core/extensions/types.d.ts +13 -1
  30. package/dist/core/extensions/types.d.ts.map +1 -1
  31. package/dist/core/extensions/types.js.map +1 -1
  32. package/dist/core/resource-loader.d.ts.map +1 -1
  33. package/dist/core/resource-loader.js +17 -0
  34. package/dist/core/resource-loader.js.map +1 -1
  35. package/dist/core/timings.d.ts +9 -0
  36. package/dist/core/timings.d.ts.map +1 -1
  37. package/dist/core/timings.js +28 -1
  38. package/dist/core/timings.js.map +1 -1
  39. package/dist/main.d.ts.map +1 -1
  40. package/dist/main.js +4 -2
  41. package/dist/main.js.map +1 -1
  42. package/dist/modes/interactive/components/custom-message.d.ts +1 -0
  43. package/dist/modes/interactive/components/custom-message.d.ts.map +1 -1
  44. package/dist/modes/interactive/components/custom-message.js +36 -4
  45. package/dist/modes/interactive/components/custom-message.js.map +1 -1
  46. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  47. package/dist/modes/interactive/interactive-mode.js +19 -7
  48. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  49. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bastani/intercom",
3
- "version": "0.8.25-alpha.1",
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 { buildProxyDescription, createDirectToolExecutor, getMissingConfiguredDirectToolServers, resolveDirectTools } from "./direct-tools.ts";
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
- await Promise.all([
96
- shutdownState(previousState, "session_restart"),
97
- shutdownOAuth(),
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
- console.error("MCP: failed to shut down previous session state", error);
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
- if (generation !== lifecycleGeneration) {
104
- return;
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
- const promise = initializeMcp(pi, ctx);
108
- initPromise = promise;
167
+ if (generation !== lifecycleGeneration || !isContextActive(ctx)) {
168
+ throw new Error("Stale MCP session initialization cancelled before startup");
169
+ }
109
170
 
110
- promise.then(async (nextState) => {
111
- if (generation !== lifecycleGeneration || initPromise !== promise) {
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
- return;
183
+ throw new Error("Stale MCP session initialization cancelled after startup");
118
184
  }
119
185
 
120
186
  state = nextState;
121
187
  updateStatusBar(nextState);
122
- initPromise = null;
123
- }).catch(err => {
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
- console.error("MCP initialization failed:", err);
131
- initPromise = null;
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
- shutdownOAuth(),
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
- if (shouldRegisterProxyTool) {
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: buildProxyDescription(earlyConfig, earlyCache, directSpecs),
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.25-alpha.1",
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.25-alpha.1",
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