@bike4mind/cli 0.2.36-perf-6916-parallel-cli-init.20075 → 0.2.36-perf-6916-parallel-cli-init.20076

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.
@@ -3,7 +3,7 @@
3
3
  // package.json
4
4
  var package_default = {
5
5
  name: "@bike4mind/cli",
6
- version: "0.2.36-perf-6916-parallel-cli-init.20075+a6ccd6e72",
6
+ version: "0.2.36-perf-6916-parallel-cli-init.20076+e20331ff9",
7
7
  type: "module",
8
8
  description: "Interactive CLI tool for Bike4Mind with ReAct agents",
9
9
  license: "UNLICENSED",
@@ -114,10 +114,10 @@ var package_default = {
114
114
  },
115
115
  devDependencies: {
116
116
  "@bike4mind/agents": "0.1.0",
117
- "@bike4mind/common": "2.57.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
118
- "@bike4mind/mcp": "1.32.5-perf-6916-parallel-cli-init.20075+a6ccd6e72",
119
- "@bike4mind/services": "2.54.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
120
- "@bike4mind/utils": "2.10.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
117
+ "@bike4mind/common": "2.57.1-perf-6916-parallel-cli-init.20076+e20331ff9",
118
+ "@bike4mind/mcp": "1.32.5-perf-6916-parallel-cli-init.20076+e20331ff9",
119
+ "@bike4mind/services": "2.54.1-perf-6916-parallel-cli-init.20076+e20331ff9",
120
+ "@bike4mind/utils": "2.10.1-perf-6916-parallel-cli-init.20076+e20331ff9",
121
121
  "@types/better-sqlite3": "^7.6.13",
122
122
  "@types/diff": "^5.0.9",
123
123
  "@types/jsonwebtoken": "^9.0.4",
@@ -138,7 +138,7 @@ var package_default = {
138
138
  optionalDependencies: {
139
139
  "@vscode/ripgrep": "^1.17.0"
140
140
  },
141
- gitHead: "a6ccd6e721ffb49ffb8d1c5184cb36b90104d736"
141
+ gitHead: "e20331ff98a10af0f0841179b1d0d4f4980b8620"
142
142
  };
143
143
 
144
144
  // src/utils/updateChecker.ts
@@ -15442,6 +15442,11 @@ var McpManager = class {
15442
15442
  this.connectionStates = /* @__PURE__ */ new Map();
15443
15443
  /** Per-server deferred promise resolved once the background connection is ready */
15444
15444
  this.connectionReady = /* @__PURE__ */ new Map();
15445
+ /**
15446
+ * Serializes background cache saves so concurrent writes don't race.
15447
+ * JSON.stringify is evaluated at run-time, always capturing the latest cache state.
15448
+ */
15449
+ this.backgroundSaveQueue = Promise.resolve();
15445
15450
  this.config = config;
15446
15451
  }
15447
15452
  /** Subscribe to background connection state changes for live UI updates. */
@@ -15462,6 +15467,14 @@ var McpManager = class {
15462
15467
  }
15463
15468
  logger.debug(`\u{1F4E1} Initializing ${enabledServers.length} MCP server(s)...`);
15464
15469
  const cache = await this.loadCache();
15470
+ const configuredNames = new Set(this.config.mcpServers.map((s) => s.name));
15471
+ let pruned = false;
15472
+ for (const name of Object.keys(cache.servers)) {
15473
+ if (!configuredNames.has(name)) {
15474
+ delete cache.servers[name];
15475
+ pruned = true;
15476
+ }
15477
+ }
15465
15478
  const eagerConnections = [];
15466
15479
  for (const serverConfig of enabledServers) {
15467
15480
  const configHash = this.hashServerConfig(serverConfig);
@@ -15476,6 +15489,8 @@ var McpManager = class {
15476
15489
  if (eagerConnections.length > 0) {
15477
15490
  await Promise.allSettled(eagerConnections);
15478
15491
  await this.saveCache(cache);
15492
+ } else if (pruned) {
15493
+ await this.saveCache(cache);
15479
15494
  }
15480
15495
  const connected = [...this.connectionStates.values()].filter((s) => s === "connected").length;
15481
15496
  const pending = [...this.connectionStates.values()].filter((s) => s === "connecting").length;
@@ -15496,14 +15511,12 @@ var McpManager = class {
15496
15511
  resolveReady = res;
15497
15512
  rejectReady = rej;
15498
15513
  });
15514
+ promise.catch(() => {
15515
+ });
15499
15516
  this.connectionReady.set(serverConfig.name, { resolve: resolveReady, reject: rejectReady, promise });
15500
15517
  const callTool = async (name, args) => {
15501
15518
  await promise;
15502
- const instance = this.servers.get(serverConfig.name);
15503
- if (!instance?.client) {
15504
- throw new Error(`MCP server "${serverConfig.name}" failed to connect`);
15505
- }
15506
- return instance.client.callTool(name, args);
15519
+ return this.servers.get(serverConfig.name).client.callTool(name, args);
15507
15520
  };
15508
15521
  const tools = generateMcpToolsFromCache(serverConfig.name, entry.tools, callTool);
15509
15522
  this.servers.set(serverConfig.name, { name: serverConfig.name, client: null, tools });
@@ -15524,8 +15537,7 @@ var McpManager = class {
15524
15537
  this.onStateChange?.();
15525
15538
  logger.debug(`\u2705 Background connection to ${serverConfig.name} established`);
15526
15539
  this.writeCacheEntry(cache, serverConfig, client.tools);
15527
- this.saveCache(cache).catch(() => {
15528
- });
15540
+ this.scheduleBackgroundSave(cache);
15529
15541
  }).catch((err) => {
15530
15542
  this.connectionStates.set(serverConfig.name, "failed");
15531
15543
  this.connectionReady.get(serverConfig.name)?.reject(err);
@@ -15566,6 +15578,9 @@ var McpManager = class {
15566
15578
  const mcpData = {
15567
15579
  serverName: serverConfig.name,
15568
15580
  getTools: async () => client.tools,
15581
+ // any: generateMcpTools accepts a loose duck-type; MCPClient.callTool return type
15582
+ // doesn't match the internal interface exactly, but runtime behaviour is correct.
15583
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
15569
15584
  callTool: async (name, args) => client.callTool(name, args)
15570
15585
  };
15571
15586
  const tools = await generateMcpTools(mcpData);
@@ -15591,6 +15606,15 @@ var McpManager = class {
15591
15606
  logger.debug(`\u26A0\uFE0F Failed to save MCP schema cache: ${error}`);
15592
15607
  }
15593
15608
  }
15609
+ /**
15610
+ * Enqueue a background cache save. Saves are serialized so concurrent background
15611
+ * connections can't interleave writes and lose each other's entries. JSON.stringify
15612
+ * is evaluated when the queued write runs, so it always captures the latest state.
15613
+ */
15614
+ scheduleBackgroundSave(cache) {
15615
+ this.backgroundSaveQueue = this.backgroundSaveQueue.then(() => this.saveCache(cache)).catch(() => {
15616
+ });
15617
+ }
15594
15618
  writeCacheEntry(cache, serverConfig, rawTools) {
15595
15619
  cache.servers[serverConfig.name] = {
15596
15620
  configHash: this.hashServerConfig(serverConfig),
@@ -3,7 +3,7 @@ import {
3
3
  fetchLatestVersion,
4
4
  forceCheckForUpdate,
5
5
  package_default
6
- } from "../chunk-XOKF6LMI.js";
6
+ } from "../chunk-AVTI7WL7.js";
7
7
 
8
8
  // src/commands/doctorCommand.ts
9
9
  import { execSync } from "child_process";
@@ -36,7 +36,7 @@ import {
36
36
  isReadOnlyTool,
37
37
  loadContextFiles,
38
38
  setWebSocketToolExecutor
39
- } from "../chunk-O33MWOVJ.js";
39
+ } from "../chunk-BUHNUPZ7.js";
40
40
  import "../chunk-BDQBOLYG.js";
41
41
  import "../chunk-CWQT33O7.js";
42
42
  import "../chunk-GQGOWACU.js";
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  forceCheckForUpdate,
4
4
  package_default
5
- } from "../chunk-XOKF6LMI.js";
5
+ } from "../chunk-AVTI7WL7.js";
6
6
 
7
7
  // src/commands/updateCommand.ts
8
8
  import { execSync } from "child_process";
package/dist/index.js CHANGED
@@ -46,7 +46,7 @@ import {
46
46
  setWebSocketToolExecutor,
47
47
  substituteArguments,
48
48
  warmFileCache
49
- } from "./chunk-O33MWOVJ.js";
49
+ } from "./chunk-BUHNUPZ7.js";
50
50
  import "./chunk-BDQBOLYG.js";
51
51
  import "./chunk-CWQT33O7.js";
52
52
  import "./chunk-GQGOWACU.js";
@@ -62,7 +62,7 @@ import {
62
62
  import {
63
63
  checkForUpdate,
64
64
  package_default
65
- } from "./chunk-XOKF6LMI.js";
65
+ } from "./chunk-AVTI7WL7.js";
66
66
  import {
67
67
  selectActiveBackgroundAgents,
68
68
  useCliStore
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.2.36-perf-6916-parallel-cli-init.20075+a6ccd6e72",
3
+ "version": "0.2.36-perf-6916-parallel-cli-init.20076+e20331ff9",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
@@ -111,10 +111,10 @@
111
111
  },
112
112
  "devDependencies": {
113
113
  "@bike4mind/agents": "0.1.0",
114
- "@bike4mind/common": "2.57.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
115
- "@bike4mind/mcp": "1.32.5-perf-6916-parallel-cli-init.20075+a6ccd6e72",
116
- "@bike4mind/services": "2.54.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
117
- "@bike4mind/utils": "2.10.1-perf-6916-parallel-cli-init.20075+a6ccd6e72",
114
+ "@bike4mind/common": "2.57.1-perf-6916-parallel-cli-init.20076+e20331ff9",
115
+ "@bike4mind/mcp": "1.32.5-perf-6916-parallel-cli-init.20076+e20331ff9",
116
+ "@bike4mind/services": "2.54.1-perf-6916-parallel-cli-init.20076+e20331ff9",
117
+ "@bike4mind/utils": "2.10.1-perf-6916-parallel-cli-init.20076+e20331ff9",
118
118
  "@types/better-sqlite3": "^7.6.13",
119
119
  "@types/diff": "^5.0.9",
120
120
  "@types/jsonwebtoken": "^9.0.4",
@@ -135,5 +135,5 @@
135
135
  "optionalDependencies": {
136
136
  "@vscode/ripgrep": "^1.17.0"
137
137
  },
138
- "gitHead": "a6ccd6e721ffb49ffb8d1c5184cb36b90104d736"
138
+ "gitHead": "e20331ff98a10af0f0841179b1d0d4f4980b8620"
139
139
  }