@bike4mind/cli 0.18.4 → 0.20.0

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 (41) hide show
  1. package/LICENSE +17 -3
  2. package/README.md +204 -35
  3. package/bin/bike4mind-cli.mjs +137 -24
  4. package/bin/hearth-hook.mjs +292 -0
  5. package/dist/AgentHistoryStore-C8uUKjjC.mjs +35512 -0
  6. package/dist/ApiClient-B_CQrUiF.mjs +277 -0
  7. package/dist/{ConfigStore-Cq20962p.mjs → ConfigStore-DD3DcC3-.mjs} +6256 -3911
  8. package/dist/{ImageStore-BVmEG1xc.mjs → ImageStore-kVo-oHoS.mjs} +2 -2
  9. package/dist/PluginStore-DwvOJ-G3.mjs +206 -0
  10. package/dist/ProxyManager-Bqr7Lmsd.mjs +3 -0
  11. package/dist/{ProxyManager-CV94yZUW.mjs → ProxyManager-C5H0pUyK.mjs} +2 -2
  12. package/dist/{SandboxOrchestrator-BS6gALNq.mjs → SandboxOrchestrator-BFPVpmB5.mjs} +1 -1
  13. package/dist/{SandboxOrchestrator-BoINxbX4.mjs → SandboxOrchestrator-C8uleDn2.mjs} +7 -7
  14. package/dist/ShellSessionManager-6o8KZzl1-vrbPAUTq.mjs +252 -0
  15. package/dist/{ViolationLogStore-B-plqJfn.mjs → ViolationLogStore-byEhxa2A.mjs} +1 -1
  16. package/dist/WorkItemsClient-Cow6nXx7.mjs +382 -0
  17. package/dist/{bashExecute-B1N1lMOS-TZVDbcQ4.mjs → bashExecute-CrdPpBqk-DCATrE-D.mjs} +116 -16
  18. package/dist/buildAgent-mVuXU_H4.mjs +824 -0
  19. package/dist/commands/acpCommand.mjs +798 -0
  20. package/dist/commands/apiCommand.mjs +14 -16
  21. package/dist/commands/doctorCommand.mjs +5 -5
  22. package/dist/commands/envCommand.mjs +1 -1
  23. package/dist/commands/headlessCommand.mjs +272 -76
  24. package/dist/commands/mcpCommand.mjs +14 -1
  25. package/dist/commands/pluginCommand.mjs +232 -0
  26. package/dist/commands/updateCommand.mjs +10 -9
  27. package/dist/{grepSearch-DJs-cubo-Bm0Y8oS3.mjs → grepSearch-BaYUfIYs-C-fxWc9G.mjs} +3 -3
  28. package/dist/index.mjs +3281 -2322
  29. package/dist/{package-CBaK53NX.mjs → package-BqKSCbso.mjs} +1 -1
  30. package/dist/serve-CuF0I5en.mjs +772 -0
  31. package/dist/store-BG3e54c8.mjs +3 -0
  32. package/dist/{store-DV5s-qni.mjs → store-CvjTpQPs.mjs} +70 -3
  33. package/dist/{terminalSetup-BbJt04ZG.mjs → terminalSetup-DjXAwpDy.mjs} +2 -3
  34. package/dist/{treeSitterEngine-BRbQ9b7I.mjs → treeSitterEngine-QBE3YkmG.mjs} +51 -1
  35. package/dist/{updateChecker-C8xsNY2L.mjs → updateChecker-CQW8bxo6.mjs} +10 -10
  36. package/package.json +48 -43
  37. package/dist/BackgroundAgentManager-DOesheMD.mjs +0 -27171
  38. package/dist/ProxyManager-ByuAHFMq.mjs +0 -3
  39. package/dist/store-DgzCTRkN.mjs +0 -3
  40. package/dist/utils-Cdktpk_k.mjs +0 -158
  41. package/dist/utils-DEizxshI.mjs +0 -3
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { o as useCliStore } from "./store-CvjTpQPs.mjs";
3
+ export { useCliStore };
@@ -2,19 +2,24 @@
2
2
  import { create } from "zustand";
3
3
  //#region src/store/index.ts
4
4
  /** Active job statuses (jobs still in progress) */
5
- const ACTIVE_STATUSES = new Set(["running", "queued"]);
5
+ const ACTIVE_STATUSES = /* @__PURE__ */ new Set(["running", "queued"]);
6
6
  const INTERACTION_MODE_CYCLE = [
7
7
  "normal",
8
8
  "auto-accept",
9
9
  "plan"
10
10
  ];
11
11
  function nextInteractionMode(current) {
12
- return INTERACTION_MODE_CYCLE[(INTERACTION_MODE_CYCLE.indexOf(current) + 1) % INTERACTION_MODE_CYCLE.length];
12
+ const idx = INTERACTION_MODE_CYCLE.indexOf(current);
13
+ return INTERACTION_MODE_CYCLE[(idx + 1) % INTERACTION_MODE_CYCLE.length];
13
14
  }
14
15
  /** Check if a job status is active (running or queued) */
15
16
  function isActiveStatus(status) {
16
17
  return ACTIVE_STATUSES.has(status);
17
18
  }
19
+ /** A shell session is active only while running; all other states are terminal. */
20
+ function isActiveShellStatus(status) {
21
+ return status === "running";
22
+ }
18
23
  const useCliStore = create((set) => ({
19
24
  session: null,
20
25
  setSession: (session) => set({ session }),
@@ -26,6 +31,28 @@ const useCliStore = create((set) => ({
26
31
  updatedAt: (/* @__PURE__ */ new Date()).toISOString()
27
32
  } };
28
33
  }),
34
+ recordSubagentUsage: ({ agentName, tokens, credits }) => set((state) => {
35
+ if (!state.session) return state;
36
+ const metadata = state.session.metadata;
37
+ const perAgent = agentName ? metadata.subagentUsage?.[agentName] : void 0;
38
+ return { session: {
39
+ ...state.session,
40
+ metadata: {
41
+ ...metadata,
42
+ subagentCalls: (metadata.subagentCalls || 0) + 1,
43
+ subagentTokens: (metadata.subagentTokens || 0) + tokens,
44
+ subagentCost: (metadata.subagentCost || 0) + (credits || 0),
45
+ ...agentName ? { subagentUsage: {
46
+ ...metadata.subagentUsage,
47
+ [agentName]: {
48
+ calls: (perAgent?.calls || 0) + 1,
49
+ tokens: (perAgent?.tokens || 0) + tokens,
50
+ credits: (perAgent?.credits || 0) + (credits || 0)
51
+ }
52
+ } } : {}
53
+ }
54
+ } };
55
+ }),
29
56
  pendingMessages: [],
30
57
  addPendingMessage: (message) => set((state) => ({ pendingMessages: [...state.pendingMessages, message] })),
31
58
  updatePendingMessage: (index, message) => set((state) => {
@@ -160,6 +187,31 @@ const useCliStore = create((set) => ({
160
187
  return { backgroundAgents: [...state.backgroundAgents, job] };
161
188
  }),
162
189
  cleanupCompletedBackgroundAgents: () => set((state) => ({ backgroundAgents: state.backgroundAgents.filter((j) => isActiveStatus(j.status)) })),
190
+ liveSubagentUsage: {},
191
+ updateLiveSubagentUsage: (runId, agentName, tokens, credits) => set((state) => ({ liveSubagentUsage: {
192
+ ...state.liveSubagentUsage,
193
+ [runId]: {
194
+ agentName,
195
+ tokens,
196
+ credits
197
+ }
198
+ } })),
199
+ removeLiveSubagentUsage: (runId) => set((state) => {
200
+ if (!(runId in state.liveSubagentUsage)) return state;
201
+ const { [runId]: _removed, ...rest } = state.liveSubagentUsage;
202
+ return { liveSubagentUsage: rest };
203
+ }),
204
+ backgroundShells: [],
205
+ upsertBackgroundShell: (session) => set((state) => {
206
+ const existing = state.backgroundShells.findIndex((s) => s.id === session.id);
207
+ if (existing >= 0) {
208
+ const updated = [...state.backgroundShells];
209
+ updated[existing] = session;
210
+ return { backgroundShells: updated };
211
+ }
212
+ return { backgroundShells: [...state.backgroundShells, session] };
213
+ }),
214
+ cleanupCompletedBackgroundShells: () => set((state) => ({ backgroundShells: state.backgroundShells.filter((s) => isActiveShellStatus(s.status)) })),
163
215
  completedGroupNotifications: [],
164
216
  addCompletedGroupNotification: (notification, groupDescription) => set((state) => ({ completedGroupNotifications: [...state.completedGroupNotifications, {
165
217
  notification,
@@ -178,5 +230,20 @@ const useCliStore = create((set) => ({
178
230
  }));
179
231
  /** Select only active (running or queued) background agents */
180
232
  const selectActiveBackgroundAgents = (state) => state.backgroundAgents.filter((j) => isActiveStatus(j.status));
233
+ /** Sum live token usage across all currently-running spawned agents */
234
+ const selectLiveSubagentTokens = (state) => Object.values(state.liveSubagentUsage).reduce((sum, u) => sum + u.tokens, 0);
235
+ /** Sum live credit usage across all currently-running spawned agents */
236
+ const selectLiveSubagentCredits = (state) => Object.values(state.liveSubagentUsage).reduce((sum, u) => sum + u.credits, 0);
237
+ const EMPTY_SHELLS = [];
238
+ /** Select only running background shell sessions */
239
+ const selectActiveBackgroundShells = (state) => {
240
+ const active = state.backgroundShells.filter((s) => isActiveShellStatus(s.status));
241
+ return active.length === 0 ? EMPTY_SHELLS : active;
242
+ };
243
+ /** Select only terminal (exited/killed/timed_out) background shell sessions */
244
+ const selectCompletedBackgroundShells = (state) => {
245
+ const completed = state.backgroundShells.filter((s) => !isActiveShellStatus(s.status));
246
+ return completed.length === 0 ? EMPTY_SHELLS : completed;
247
+ };
181
248
  //#endregion
182
- export { useCliStore as n, selectActiveBackgroundAgents as t };
249
+ export { selectLiveSubagentTokens as a, selectLiveSubagentCredits as i, selectActiveBackgroundShells as n, useCliStore as o, selectCompletedBackgroundShells as r, selectActiveBackgroundAgents as t };
@@ -109,7 +109,7 @@ function detectTerminal() {
109
109
  };
110
110
  }
111
111
  /**
112
- * VS Code keybindings.json entry for Shift+Enter \x1b[13;2u (Kitty protocol)
112
+ * VS Code keybindings.json entry for Shift+Enter -> \x1b[13;2u (Kitty protocol)
113
113
  */
114
114
  const VSCODE_KEYBINDING = {
115
115
  key: "shift+enter",
@@ -156,7 +156,7 @@ Restart your VS Code terminal for the change to take effect.`
156
156
  };
157
157
  }
158
158
  /**
159
- * Alacritty config entry for Shift+Enter Kitty protocol sequence.
159
+ * Alacritty config entry for Shift+Enter -> Kitty protocol sequence.
160
160
  */
161
161
  const ALACRITTY_TOML_SNIPPET = `
162
162
  # B4M CLI: Shift+Enter sends Kitty-protocol sequence for newline
@@ -242,7 +242,6 @@ async function runTerminalSetup() {
242
242
  case "unknown":
243
243
  console.log(getManualInstructions(terminal));
244
244
  console.log();
245
- break;
246
245
  }
247
246
  console.log("Universal newline methods (work in all terminals):");
248
247
  console.log(" • Option/Alt + Enter — insert newline");
@@ -308,5 +308,55 @@ function getSupportedLanguages() {
308
308
  function getLanguageForExtension(ext) {
309
309
  return EXTENSION_TO_LANGUAGE[ext] || null;
310
310
  }
311
+ /** Collect the byte spans of every `comment` node in the tree (depth-first). */
312
+ function collectCommentSpans(root) {
313
+ const spans = [];
314
+ const stack = [root];
315
+ while (stack.length) {
316
+ const node = stack.pop();
317
+ if (!node) continue;
318
+ if (node.type === "comment") {
319
+ spans.push([node.startIndex, node.endIndex]);
320
+ continue;
321
+ }
322
+ for (const child of node.children) if (child) stack.push(child);
323
+ }
324
+ return spans;
325
+ }
326
+ /**
327
+ * Return `sourceCode` with comment text removed via tree-sitter, or `null` when the
328
+ * extension is unsupported or the source fails to parse - the caller then falls back
329
+ * to whitespace-only normalization (comments preserved), so worst case is "no reduction,"
330
+ * never "wrong content." Only `comment` AST nodes are excised; Python docstrings are
331
+ * `string` expression nodes (semantically live via `__doc__`) and are deliberately kept.
332
+ * Whitespace normalization is intentionally NOT done here - the caller owns that so the
333
+ * fallback and AST paths share one normalizer.
334
+ */
335
+ async function stripComments(sourceCode, ext) {
336
+ const languageId = getLanguageForExtension(ext);
337
+ if (!languageId) return null;
338
+ try {
339
+ await ensureInitialized();
340
+ const language = await loadLanguage(languageId);
341
+ const parser = new TreeSitter.Parser();
342
+ let tree = null;
343
+ try {
344
+ parser.setLanguage(language);
345
+ tree = parser.parse(sourceCode);
346
+ if (!tree) return null;
347
+ const spans = collectCommentSpans(tree.rootNode);
348
+ if (spans.length === 0) return sourceCode;
349
+ spans.sort((a, b) => b[0] - a[0]);
350
+ let result = sourceCode;
351
+ for (const [start, end] of spans) result = result.slice(0, start) + result.slice(end);
352
+ return result;
353
+ } finally {
354
+ tree?.delete();
355
+ parser.delete();
356
+ }
357
+ } catch {
358
+ return null;
359
+ }
360
+ }
311
361
  //#endregion
312
- export { getLanguageForExtension, getSupportedLanguages, parseFileStructure };
362
+ export { getLanguageForExtension, getSupportedLanguages, parseFileStructure, stripComments };
@@ -11,7 +11,7 @@ import axios from "axios";
11
11
  * Used by the startup banner, `b4m update`, and `b4m doctor` commands.
12
12
  */
13
13
  const CACHE_FILE = path.join(homedir(), ".bike4mind", "update-check.json");
14
- const CACHE_TTL_MS = 1440 * 60 * 1e3;
14
+ const CACHE_TTL_MS = 864e5;
15
15
  const NPM_REGISTRY_URL = "https://registry.npmjs.org/@bike4mind/cli/latest";
16
16
  const FETCH_TIMEOUT_MS = 5e3;
17
17
  /**
@@ -28,10 +28,10 @@ const INSTALL_CMD = "npm install -g @bike4mind/cli@latest";
28
28
  const REEXEC_GUARD_ENV = "B4M_UPDATED_REEXEC";
29
29
  /**
30
30
  * Check whether the global npm prefix is writable by the current user.
31
- * When it isn't (e.g. Homebrew/system node), `npm install -g` needs sudo
32
- * which an unattended auto-updater cannot provide so callers should fall
31
+ * When it isn't (e.g. Homebrew/system node), `npm install -g` needs sudo -
32
+ * which an unattended auto-updater cannot provide - so callers should fall
33
33
  * back to a manual-update notice instead of attempting a silent install.
34
- * Non-throwing returns false on any error.
34
+ * Non-throwing - returns false on any error.
35
35
  *
36
36
  * Pass `prefix` to reuse an already-resolved `npm config get prefix` (each
37
37
  * `execSync` is ~50-200ms); omit it and the prefix is resolved internally.
@@ -83,17 +83,17 @@ async function getAutoUpdatePreference() {
83
83
  /**
84
84
  * Persist the user's `autoUpdate` choice (`true` = always, `false` = never).
85
85
  *
86
- * Writes the **global** config file directly the mirror of how
87
- * `getAutoUpdatePreference()` reads it rather than routing through
88
- * `ConfigStore.save()`. `ConfigStore.load()` merges global project local,
86
+ * Writes the **global** config file directly - the mirror of how
87
+ * `getAutoUpdatePreference()` reads it - rather than routing through
88
+ * `ConfigStore.save()`. `ConfigStore.load()` merges global -> project -> local,
89
89
  * and `ConfigStore.save()` writes that merged result back to the global path;
90
90
  * answering "Always"/"Never" inside a project would therefore bake the
91
- * project's other overrides (model, theme, temperature, ) into the user's
91
+ * project's other overrides (model, theme, temperature, ...) into the user's
92
92
  * global config as a silent side effect. This call fires during the bin
93
93
  * bootstrap any time an update is available, so that blast radius is
94
94
  * unacceptable. A direct read-merge-write of only `preferences.autoUpdate`
95
95
  * avoids it. If the on-disk file is schema-incomplete, the next
96
- * `ConfigStore.load()` backfills defaults harmlessly exactly as
96
+ * `ConfigStore.load()` backfills defaults harmlessly - exactly as
97
97
  * `getAutoUpdatePreference` already tolerates a partial file. Best-effort:
98
98
  * a failure is swallowed (we simply ask again next launch rather than blocking).
99
99
  */
@@ -168,7 +168,7 @@ async function writeCache(cache) {
168
168
  }
169
169
  /**
170
170
  * Check for updates using cache when fresh.
171
- * Non-throwing returns null on any error.
171
+ * Non-throwing - returns null on any error.
172
172
  */
173
173
  async function checkForUpdate(currentVersion) {
174
174
  try {
package/package.json CHANGED
@@ -1,16 +1,16 @@
1
1
  {
2
2
  "name": "@bike4mind/cli",
3
- "version": "0.18.4",
3
+ "version": "0.20.0",
4
4
  "type": "module",
5
5
  "description": "Interactive CLI tool for Bike4Mind with ReAct agents",
6
6
  "license": "UNLICENSED",
7
7
  "author": "Bike4Mind",
8
8
  "repository": {
9
9
  "type": "git",
10
- "url": "git+https://github.com/bike4mind/lumina5.git"
10
+ "url": "git+https://github.com/Bike4Mind/bike4mind.git"
11
11
  },
12
- "homepage": "https://github.com/bike4mind/lumina5#readme",
13
- "bugs": "https://github.com/bike4mind/lumina5/issues",
12
+ "homepage": "https://github.com/bike4mind/bike4mind#readme",
13
+ "bugs": "https://github.com/bike4mind/bike4mind/issues",
14
14
  "publishConfig": {
15
15
  "access": "public"
16
16
  },
@@ -34,16 +34,17 @@
34
34
  "node": ">=24.0.0"
35
35
  },
36
36
  "dependencies": {
37
- "@anthropic-ai/sdk": "^0.97.1",
38
- "@aws-sdk/client-apigatewaymanagementapi": "^3.1069.0",
39
- "@aws-sdk/client-bedrock-runtime": "^3.1069.0",
40
- "@aws-sdk/client-cloudwatch": "^3.1069.0",
41
- "@aws-sdk/client-lambda": "^3.1069.0",
42
- "@aws-sdk/client-s3": "^3.1069.0",
43
- "@aws-sdk/client-sqs": "^3.1069.0",
44
- "@aws-sdk/client-transcribe": "^3.1069.0",
45
- "@aws-sdk/credential-provider-node": "^3.972.56",
46
- "@aws-sdk/s3-request-presigner": "^3.1069.0",
37
+ "@agentclientprotocol/sdk": "1.2.1",
38
+ "@anthropic-ai/sdk": "^0.111.0",
39
+ "@aws-sdk/client-apigatewaymanagementapi": "^3.1080.0",
40
+ "@aws-sdk/client-bedrock-runtime": "^3.1080.0",
41
+ "@aws-sdk/client-cloudwatch": "^3.1080.0",
42
+ "@aws-sdk/client-lambda": "^3.1080.0",
43
+ "@aws-sdk/client-s3": "^3.1080.0",
44
+ "@aws-sdk/client-sqs": "^3.1080.0",
45
+ "@aws-sdk/client-transcribe": "^3.1080.0",
46
+ "@aws-sdk/credential-provider-node": "^3.972.63",
47
+ "@aws-sdk/s3-request-presigner": "^3.1080.0",
47
48
  "@casl/ability": "^6.8.1",
48
49
  "@google/genai": "^1.46.0",
49
50
  "@joplin/turndown-plugin-gfm": "^1.0.67",
@@ -51,32 +52,32 @@
51
52
  "@modelcontextprotocol/sdk": "1.29.0",
52
53
  "@octokit/rest": "^22.0.1",
53
54
  "@opensearch-project/opensearch": "2.11.0",
54
- "@smithy/node-http-handler": "^4.8.0",
55
+ "@smithy/node-http-handler": "^4.9.3",
55
56
  "async-mutex": "^0.5.0",
56
- "axios": "1.16.1",
57
+ "axios": "1.18.0",
57
58
  "bcryptjs": "^3.0.2",
58
- "better-sqlite3": "^12.10.0",
59
+ "better-sqlite3": "^13.0.1",
59
60
  "cheerio": "1.2.0",
60
61
  "chess.js": "^1.0.0-beta.8",
61
62
  "cli-highlight": "^2.1.11",
62
- "csv-parse": "^6.2.1",
63
- "dayjs": "^1.11.20",
63
+ "csv-parse": "^7.0.1",
64
+ "dayjs": "^1.11.21",
64
65
  "diff": "^9.0.0",
65
66
  "dotenv": "^17.4.2",
66
- "eventsource-parser": "^3.0.8",
67
- "exceljs": "^4.4.0",
67
+ "eventsource-parser": "^3.1.0",
68
68
  "fdir": "^6.5.0",
69
69
  "file-type": "^22.0.1",
70
- "fuse.js": "^7.3.0",
70
+ "fuse.js": "^7.4.2",
71
71
  "fzf": "^0.5.2",
72
72
  "glob": "^13.0.6",
73
73
  "gray-matter": "^4.0.3",
74
- "ignore": "^7.0.5",
75
- "ink": "^7.0.3",
74
+ "ignore": "^7.0.6",
75
+ "ink": "^7.1.0",
76
76
  "ink-select-input": "^6.2.0",
77
77
  "ink-spinner": "^5.0.0",
78
78
  "ink-text-input": "^6.0.0",
79
79
  "jsonwebtoken": "^9.0.3",
80
+ "jszip": "^3.10.1",
80
81
  "lodash": "^4.18.1",
81
82
  "mammoth": "^1.12.0",
82
83
  "marked": "^15.0.11",
@@ -85,56 +86,60 @@
85
86
  "mongoose": "^8.24.1",
86
87
  "ollama": "^0.6.3",
87
88
  "open": "^11.0.0",
88
- "openai": "^6.38.0",
89
+ "openai": "^6.46.0",
89
90
  "p-limit": "^7.3.0",
90
- "picomatch": "^4.0.3",
91
+ "picomatch": "^4.0.5",
91
92
  "qrcode": "^1.5.4",
92
- "react": "^19.2.6",
93
- "sharp": "^0.34.5",
93
+ "react": "^19.2.7",
94
+ "sharp": "^0.35.3",
95
+ "shell-quote": "^1.10.0",
94
96
  "speakeasy": "^2.0.0",
95
97
  "tiktoken": "^1.0.22",
98
+ "tldts": "^7.4.8",
96
99
  "tree-sitter-wasms": "^0.1.13",
97
100
  "turndown": "^7.2.4",
98
101
  "undici": "^7.28.0",
99
102
  "unpdf": "^1.6.2",
100
- "uuid": "^13.0.2",
103
+ "uuid": "^14.0.1",
101
104
  "voyageai": "^0.4.0",
102
105
  "web-tree-sitter": "0.25.10",
103
106
  "ws": "^8.21.0",
104
107
  "xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
105
108
  "yargs": "^18.0.0",
106
- "yauzl": "^3.3.0",
109
+ "yauzl": "^3.4.0",
107
110
  "zod": "^4.4.3",
108
111
  "zod-validation-error": "^5.0.0",
109
112
  "zustand": "^5.0.13",
110
- "@bike4mind/fab-pipeline": "0.4.8",
111
- "@bike4mind/llm-adapters": "0.9.0",
112
- "@bike4mind/observability": "0.2.0"
113
+ "@bike4mind/hearth": "0.2.0"
113
114
  },
114
115
  "devDependencies": {
115
116
  "@types/better-sqlite3": "^7.6.13",
116
117
  "@types/jsonwebtoken": "^9.0.4",
117
118
  "@types/node": "^24.0.0",
118
119
  "@types/picomatch": "^4.0.3",
119
- "@types/react": "^19.2.15",
120
+ "@types/react": "^19.2.17",
121
+ "@types/shell-quote": "^1.7.5",
120
122
  "@types/ws": "^8.18.1",
121
123
  "@types/yargs": "^17.0.35",
122
124
  "ink-testing-library": "^4.0.0",
123
- "tsdown": "^0.22.2",
124
- "tsx": "^4.22.3",
125
+ "tsdown": "^0.22.3",
126
+ "tsx": "^4.23.0",
125
127
  "typescript": "^5.9.3",
126
- "vitest": "^4.1.9",
127
- "@bike4mind/agents": "0.18.2",
128
- "@bike4mind/common": "2.119.0",
129
- "@bike4mind/mcp": "1.40.2",
130
- "@bike4mind/services": "2.103.0",
131
- "@bike4mind/utils": "2.27.0"
128
+ "vitest": "^4.1.10",
129
+ "@bike4mind/agents": "0.20.0",
130
+ "@bike4mind/common": "4.0.0",
131
+ "@bike4mind/fab-pipeline": "1.0.0",
132
+ "@bike4mind/llm-adapters": "0.11.0",
133
+ "@bike4mind/mcp": "1.41.1",
134
+ "@bike4mind/observability": "0.2.0",
135
+ "@bike4mind/services": "4.0.0",
136
+ "@bike4mind/utils": "3.1.0"
132
137
  },
133
138
  "optionalDependencies": {
134
139
  "@vscode/ripgrep": "^1.18.0"
135
140
  },
136
141
  "scripts": {
137
- "dev": "tsx src/index.tsx",
142
+ "dev": "B4M_SOURCE_MODE=1 tsx src/index.tsx",
138
143
  "build": "tsdown",
139
144
  "typecheck": "tsc --noEmit",
140
145
  "typecheck:native": "tsgo --noEmit --types node",