@bike4mind/cli 0.9.3 → 0.10.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 (41) hide show
  1. package/README.md +13 -3
  2. package/bin/bike4mind-cli.mjs +44 -1
  3. package/dist/{BubblewrapRuntime-CUD3bsgG.mjs → BubblewrapRuntime-CkL9-gnG.mjs} +1 -1
  4. package/dist/{ConfigStore-BauEpjvT.mjs → ConfigStore-aeJGqjKm.mjs} +116 -15
  5. package/dist/ProxyManager-ByuAHFMq.mjs +3 -0
  6. package/dist/{SandboxOrchestrator-C4oDqltp.mjs → SandboxOrchestrator-BS6gALNq.mjs} +1 -1
  7. package/dist/{SandboxOrchestrator-B4GcZdBc.mjs → SandboxOrchestrator-BoINxbX4.mjs} +1 -1
  8. package/dist/{SandboxRuntimeAdapter-DXa3nFOw.mjs → SandboxRuntimeAdapter-CKelGICD.mjs} +1 -1
  9. package/dist/{SandboxRuntimeAdapter-D1RUReNL.mjs → SandboxRuntimeAdapter-ChGlxSGQ.mjs} +2 -2
  10. package/dist/{SeatbeltRuntime-CTElMR9Q.mjs → SeatbeltRuntime-Qqt19cAN.mjs} +1 -1
  11. package/dist/{bashExecute-pYljpfPn-BZXHMQEl.mjs → bashExecute-B1N1lMOS-TZVDbcQ4.mjs} +1 -1
  12. package/dist/commands/apiCommand.mjs +45 -0
  13. package/dist/commands/doctorCommand.mjs +2 -2
  14. package/dist/commands/headlessCommand.mjs +6 -6
  15. package/dist/commands/mcpCommand.mjs +1 -1
  16. package/dist/commands/updateCommand.mjs +2 -2
  17. package/dist/{createFile-C1JoeuYh-metInFKd.mjs → createFile-DPv180yF-BnWFIxey.mjs} +2 -2
  18. package/dist/{deleteFile-BTberNGj-CW922hRM.mjs → deleteFile-BdjUwUQF-B3XOJmg3.mjs} +2 -2
  19. package/dist/{globFiles-Bez8QCbS-DZb6McbJ.mjs → globFiles-DjfDGaUK-CNR8pMRC.mjs} +2 -2
  20. package/dist/{grepSearch-BxucZWO8-lPRv6R6F.mjs → grepSearch-DJs-cubo-Bm0Y8oS3.mjs} +2 -2
  21. package/dist/index.mjs +258 -39
  22. package/dist/{pathValidation-CIytuhr3-Dt5dntLx.mjs → pathValidation-D8tjkQXE-1HwvsuYT.mjs} +1 -1
  23. package/dist/store-DgzCTRkN.mjs +3 -0
  24. package/dist/{tools-CpWE3Qif.mjs → tools-RdGu37Lw.mjs} +11217 -10240
  25. package/dist/types-CqscS34o.mjs +3 -0
  26. package/dist/{updateChecker-DhWcEKAu.mjs → updateChecker-CP_jeER9.mjs} +1 -1
  27. package/dist/utils-BGtSXfce.mjs +3 -0
  28. package/dist/utils-PpNti-tY.mjs +146 -0
  29. package/package.json +31 -31
  30. package/dist/ProxyManager-DIAAw902.mjs +0 -3
  31. package/dist/store-5PXzE9DM.mjs +0 -3
  32. package/dist/types-DK3P88Px.mjs +0 -3
  33. /package/dist/{ImageStore-BFp_d12J.mjs → ImageStore-BVmEG1xc.mjs} +0 -0
  34. /package/dist/{ProxyManager-BsCoxpns.mjs → ProxyManager-CV94yZUW.mjs} +0 -0
  35. /package/dist/{StderrViolationParser-BFP4bo7I.mjs → StderrViolationParser-CS43a-TP.mjs} +0 -0
  36. /package/dist/{ViolationLogStore-Dp6HF0nz.mjs → ViolationLogStore-B-plqJfn.mjs} +0 -0
  37. /package/dist/{ripgrepCheck-DIu4apVE.mjs → ripgrepCheck-BmkyTK2i.mjs} +0 -0
  38. /package/dist/{store-BonrwrMi.mjs → store-DV5s-qni.mjs} +0 -0
  39. /package/dist/{terminalSetup-DxloCowq.mjs → terminalSetup-BbJt04ZG.mjs} +0 -0
  40. /package/dist/{treeSitterEngine-Cw2LbVZT.mjs → treeSitterEngine-BRbQ9b7I.mjs} +0 -0
  41. /package/dist/{types-DBEjF9YS.mjs → types-LyRNHOiS.mjs} +0 -0
package/README.md CHANGED
@@ -386,6 +386,11 @@ tail -f ~/.bike4mind/debug/[session-id].txt
386
386
 
387
387
  This section covers the contributor workflow for hacking on the CLI from a checkout of the monorepo. For end-user installation see [Installation](#installation) above.
388
388
 
389
+ ### Prerequisites
390
+
391
+ - **Node.js 24+** and **pnpm 10+** — the repo's `engines` field requires these versions. If you use [corepack](https://nodejs.org/api/corepack.html) (bundled with Node), run `corepack enable` from the repo root and it will activate the exact pnpm version pinned in the root `package.json`.
392
+ - Native-module build tools (Python 3 + a C++ compiler) for `better-sqlite3` and `sharp` — see [Build Requirements](#build-requirements) above.
393
+
389
394
  ### How the bin resolves source vs. built code
390
395
 
391
396
  `apps/cli/bin/bike4mind-cli.mjs` auto-detects which mode to run in:
@@ -406,16 +411,21 @@ pnpm install
406
411
  # 2. Build the @bike4mind/* core packages so the CLI can import their dist/ outputs
407
412
  pnpm turbo:core:build
408
413
 
409
- # 3. Make the `b4m` and `bike4mind` commands point at this checkout
414
+ # 3. Ensure pnpm has a global bin directory (once per machine). Without this,
415
+ # `pnpm link --global` fails with ERR_PNPM_NO_GLOBAL_BIN_DIR. `pnpm setup`
416
+ # appends PNPM_HOME to your shell profile — open a new shell afterward.
417
+ pnpm setup
418
+
419
+ # 4. Make the `b4m` and `bike4mind` commands point at this checkout
410
420
  cd apps/cli
411
421
  pnpm link --global
412
422
 
413
- # 4. Verify
423
+ # 5. Verify
414
424
  which b4m
415
425
  b4m --version
416
426
  ```
417
427
 
418
- After step 3, running `b4m` anywhere on your system executes this working tree. Re-run `pnpm link --global` if you move or rename the repo.
428
+ After step 4, running `b4m` anywhere on your system executes this working tree. Re-run `pnpm link --global` if you move or rename the repo.
419
429
 
420
430
  ### Editing CLI source (`apps/cli/src/`)
421
431
 
@@ -28,6 +28,11 @@ const __filename = fileURLToPath(import.meta.url);
28
28
  const __dirname = dirname(__filename);
29
29
  const require = createRequire(import.meta.url);
30
30
 
31
+ // Read our own package.json so `--version` reports the CLI's version.
32
+ // Without an explicit argument, yargs .version() resolves the version from
33
+ // whichever package.json it discovers first, which is not necessarily ours.
34
+ const { version: cliVersion } = require('../package.json');
35
+
31
36
  // Parse CLI arguments
32
37
  const argv = await yargs(hideBin(process.argv))
33
38
  .option('verbose', {
@@ -71,6 +76,15 @@ const argv = await yargs(hideBin(process.argv))
71
76
  type: 'string',
72
77
  description: 'Add local Ollama models to the model picker (e.g. http://localhost:11434)',
73
78
  })
79
+ .option('api-url', {
80
+ type: 'string',
81
+ description: 'Set a custom API URL (self-hosted instance) and clear auth tokens, then exit',
82
+ })
83
+ .option('reset-api', {
84
+ type: 'boolean',
85
+ description: 'Reset the API URL to the Bike4Mind default and clear auth tokens, then exit',
86
+ default: false,
87
+ })
74
88
  .command('mcp', 'Manage MCP (Model Context Protocol) servers', (yargs) => {
75
89
  return yargs
76
90
  .command('list', 'List configured MCP servers', {}, async () => {
@@ -117,7 +131,7 @@ const argv = await yargs(hideBin(process.argv))
117
131
  .command('doctor', 'Run diagnostic checks on CLI installation')
118
132
  .help()
119
133
  .alias('help', 'h')
120
- .version()
134
+ .version(cliVersion)
121
135
  .alias('version', 'V')
122
136
  .parse();
123
137
 
@@ -161,6 +175,35 @@ const hasDist = existsSync(distPath);
161
175
  const isDev = process.env.NODE_ENV === 'development' ||
162
176
  (!hasDist && hasSource);
163
177
 
178
+ // Handle --api-url / --reset-api flags
179
+ // These mutate ~/.bike4mind/config.json and exit before any auth flow runs,
180
+ // so devs can recover from a misconfigured customUrl without editing JSON.
181
+ if (argv['reset-api'] || argv['api-url'] !== undefined) {
182
+ try {
183
+ let handleApiCommand;
184
+
185
+ if (isDev) {
186
+ const { register } = require('tsx/esm/api');
187
+ register();
188
+ const module = await import('../src/commands/apiCommand.ts');
189
+ handleApiCommand = module.handleApiCommand;
190
+ } else {
191
+ const module = await import('../dist/commands/apiCommand.mjs');
192
+ handleApiCommand = module.handleApiCommand;
193
+ }
194
+
195
+ if (argv['reset-api']) {
196
+ await handleApiCommand({ mode: 'reset' });
197
+ } else {
198
+ await handleApiCommand({ mode: 'set', url: argv['api-url'] });
199
+ }
200
+ process.exit(0);
201
+ } catch (error) {
202
+ console.error('Error:', error.message);
203
+ process.exit(1);
204
+ }
205
+ }
206
+
164
207
  // Handle headless mode (-p / --prompt flag)
165
208
  // Must be done after isDev detection to use correct import path
166
209
  if (argv.prompt !== undefined) {
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-D1RUReNL.mjs";
2
+ import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-ChGlxSGQ.mjs";
3
3
  import os from "os";
4
4
  //#region src/sandbox/runtime/BubblewrapRuntime.ts
5
5
  /**
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as DEFAULT_SANDBOX_CONFIG } from "./types-DBEjF9YS.mjs";
2
+ import { t as DEFAULT_SANDBOX_CONFIG } from "./types-LyRNHOiS.mjs";
3
3
  import "crypto";
4
4
  import { existsSync, promises } from "fs";
5
5
  import os, { homedir } from "os";
@@ -22,7 +22,7 @@ let CollectionType = /* @__PURE__ */ function(CollectionType) {
22
22
  return CollectionType;
23
23
  }({});
24
24
  //#endregion
25
- //#region ../../b4m-core/common/dist/api-d6gSEqLB.mjs
25
+ //#region ../../b4m-core/common/dist/api--fTBBxKG.mjs
26
26
  const extractSnippetMeta = (content) => {
27
27
  const snippetRegex = /<!--snippet-meta\s*(\{[\s\S]*?\})\s*-->[\n\s]*([\s\S]*?)(?=<!--snippet-meta|$)/g;
28
28
  const sections = [];
@@ -160,6 +160,8 @@ let HttpStatus = /* @__PURE__ */ function(HttpStatus) {
160
160
  return HttpStatus;
161
161
  }({});
162
162
  var HTTPError = class extends Error {
163
+ statusCode;
164
+ additionalInfo;
163
165
  constructor(statusCode, message, additionalInfo) {
164
166
  super(message);
165
167
  this.statusCode = statusCode;
@@ -168,6 +170,7 @@ var HTTPError = class extends Error {
168
170
  }
169
171
  };
170
172
  var InternalServerError = class extends HTTPError {
173
+ additionalInfo;
171
174
  constructor(message, additionalInfo) {
172
175
  super(500, message, additionalInfo);
173
176
  this.additionalInfo = additionalInfo;
@@ -175,6 +178,7 @@ var InternalServerError = class extends HTTPError {
175
178
  }
176
179
  };
177
180
  var NotFoundError = class extends HTTPError {
181
+ additionalInfo;
178
182
  constructor(message, additionalInfo) {
179
183
  super(404, message, additionalInfo);
180
184
  this.additionalInfo = additionalInfo;
@@ -182,6 +186,7 @@ var NotFoundError = class extends HTTPError {
182
186
  }
183
187
  };
184
188
  var UnprocessableEntityError = class extends HTTPError {
189
+ additionalInfo;
185
190
  constructor(message, additionalInfo) {
186
191
  super(422, message, additionalInfo);
187
192
  this.additionalInfo = additionalInfo;
@@ -189,6 +194,7 @@ var UnprocessableEntityError = class extends HTTPError {
189
194
  }
190
195
  };
191
196
  var BadRequestError = class extends HTTPError {
197
+ additionalInfo;
192
198
  constructor(message, additionalInfo) {
193
199
  super(400, message, additionalInfo);
194
200
  this.additionalInfo = additionalInfo;
@@ -196,6 +202,7 @@ var BadRequestError = class extends HTTPError {
196
202
  }
197
203
  };
198
204
  var UnauthorizedError = class extends HTTPError {
205
+ additionalInfo;
199
206
  constructor(message, additionalInfo) {
200
207
  super(401, message, additionalInfo);
201
208
  this.additionalInfo = additionalInfo;
@@ -203,6 +210,7 @@ var UnauthorizedError = class extends HTTPError {
203
210
  }
204
211
  };
205
212
  var ForbiddenError = class extends HTTPError {
213
+ additionalInfo;
206
214
  constructor(message, additionalInfo) {
207
215
  super(403, message, additionalInfo);
208
216
  this.additionalInfo = additionalInfo;
@@ -210,6 +218,7 @@ var ForbiddenError = class extends HTTPError {
210
218
  }
211
219
  };
212
220
  var TooManyRequestsError = class extends HTTPError {
221
+ additionalInfo;
213
222
  constructor(message, additionalInfo) {
214
223
  super(429, message, additionalInfo);
215
224
  this.additionalInfo = additionalInfo;
@@ -217,6 +226,7 @@ var TooManyRequestsError = class extends HTTPError {
217
226
  }
218
227
  };
219
228
  var CorruptedFileError = class extends HTTPError {
229
+ additionalInfo;
220
230
  constructor(fileName, fileType, corruptionDetails, additionalInfo) {
221
231
  const message = `File '${fileName}' (${fileType}) appears to be corrupted${corruptionDetails ? `: ${corruptionDetails}` : ""}. Please try uploading the file again.`;
222
232
  super(422, message, additionalInfo);
@@ -232,6 +242,8 @@ function isZodError(err) {
232
242
  * This should break the agent loop immediately and return control to the user.
233
243
  */
234
244
  var PermissionDeniedError = class extends Error {
245
+ toolName;
246
+ toolArgs;
235
247
  constructor(toolName, toolArgs) {
236
248
  super(`Permission denied for tool: ${toolName}`);
237
249
  this.toolName = toolName;
@@ -284,7 +296,7 @@ let ImageModels = /* @__PURE__ */ function(ImageModels) {
284
296
  ImageModels["FLUX_DEV"] = "flux-dev";
285
297
  ImageModels["FLUX_KONTEXT_PRO"] = "flux-kontext-pro";
286
298
  ImageModels["FLUX_KONTEXT_MAX"] = "flux-kontext-max";
287
- ImageModels["GROK_2_IMAGE"] = "grok-2-image";
299
+ ImageModels["GROK_IMAGINE_IMAGE_QUALITY"] = "grok-imagine-image-quality";
288
300
  ImageModels["GEMINI_2_5_FLASH_IMAGE"] = "gemini-2.5-flash-image";
289
301
  ImageModels["GEMINI_3_PRO_IMAGE_PREVIEW"] = "gemini-3-pro-image-preview";
290
302
  return ImageModels;
@@ -348,6 +360,7 @@ let ChatModels = /* @__PURE__ */ function(ChatModels) {
348
360
  ChatModels["CLAUDE_4_6_SONNET_BEDROCK"] = "global.anthropic.claude-sonnet-4-6";
349
361
  ChatModels["CLAUDE_4_6_OPUS_BEDROCK"] = "global.anthropic.claude-opus-4-6-v1";
350
362
  ChatModels["CLAUDE_4_7_OPUS_BEDROCK"] = "global.anthropic.claude-opus-4-7";
363
+ ChatModels["CLAUDE_4_8_OPUS_BEDROCK"] = "global.anthropic.claude-opus-4-8";
351
364
  ChatModels["CLAUDE_3_OPUS"] = "claude-3-opus-20240229";
352
365
  ChatModels["CLAUDE_3_5_HAIKU_ANTHROPIC"] = "claude-3-5-haiku-20241022";
353
366
  ChatModels["CLAUDE_3_5_SONNET_ANTHROPIC"] = "claude-3-5-sonnet-20241022";
@@ -361,6 +374,7 @@ let ChatModels = /* @__PURE__ */ function(ChatModels) {
361
374
  ChatModels["CLAUDE_4_6_SONNET"] = "claude-sonnet-4-6";
362
375
  ChatModels["CLAUDE_4_6_OPUS"] = "claude-opus-4-6";
363
376
  ChatModels["CLAUDE_4_7_OPUS"] = "claude-opus-4-7";
377
+ ChatModels["CLAUDE_4_8_OPUS"] = "claude-opus-4-8";
364
378
  ChatModels["JURASSIC2_ULTRA"] = "ai21.j2-ultra-v1";
365
379
  ChatModels["JURASSIC2_MID"] = "ai21.j2-mid-v1";
366
380
  ChatModels["GEMINI_3_1_PRO_PREVIEW"] = "gemini-3.1-pro-preview";
@@ -413,7 +427,7 @@ const REASONING_SUPPORTED_MODELS = new Set([
413
427
  * reasoning controls
414
428
  */
415
429
  const FIXED_TEMPERATURE_MODELS = new Set([
416
- ...REASONING_SUPPORTED_MODELS,
430
+ ...Array.from(REASONING_SUPPORTED_MODELS),
417
431
  "gpt-5.1-chat-latest",
418
432
  "gpt-5.2-chat-latest",
419
433
  "gpt-5.5"
@@ -422,7 +436,12 @@ const FIXED_TEMPERATURE_MODELS = new Set([
422
436
  * Models that do not accept the temperature parameter at all.
423
437
  * The API will reject requests that include temperature for these models.
424
438
  */
425
- const NO_TEMPERATURE_MODELS = new Set(["claude-opus-4-7", "global.anthropic.claude-opus-4-7"]);
439
+ const NO_TEMPERATURE_MODELS = new Set([
440
+ "claude-opus-4-7",
441
+ "global.anthropic.claude-opus-4-7",
442
+ "claude-opus-4-8",
443
+ "global.anthropic.claude-opus-4-8"
444
+ ]);
426
445
  /**
427
446
  * Bedrock-hosted Claude models that do NOT support prompt caching (`cache_control`).
428
447
  * Sending `cache_control` to these models triggers a Bedrock deserialization error:
@@ -983,6 +1002,8 @@ let ApiKeyScope = /* @__PURE__ */ function(ApiKeyScope) {
983
1002
  * radius of a sprite-spawning credential, not a billable AI key. */
984
1003
  ApiKeyScope["CC_BRIDGE"] = "cc-bridge:connect";
985
1004
  ApiKeyScope["ADMIN"] = "admin:*";
1005
+ ApiKeyScope["MARKETING_REPORTS_READ"] = "marketing-reports:read";
1006
+ ApiKeyScope["MARKETING_REPORTS_WRITE"] = "marketing-reports:write";
986
1007
  return ApiKeyScope;
987
1008
  }({});
988
1009
  /** Valid document types that can be favorited */
@@ -2578,6 +2599,7 @@ const AgentStepSchema = z.object({
2578
2599
  toolName: z.string().optional(),
2579
2600
  toolInput: z.unknown().optional(),
2580
2601
  timestamp: z.number(),
2602
+ iteration: z.number().optional(),
2581
2603
  tokenUsage: z.object({
2582
2604
  prompt: z.number(),
2583
2605
  completion: z.number(),
@@ -2651,7 +2673,8 @@ const SubagentStartedAction = z.object({
2651
2673
  agentName: z.string(),
2652
2674
  model: z.string().optional(),
2653
2675
  thoroughness: z.string().optional(),
2654
- maxIterations: z.number().optional()
2676
+ maxIterations: z.number().optional(),
2677
+ isBackground: z.boolean().optional()
2655
2678
  });
2656
2679
  const SubagentIterationStepAction = z.object({
2657
2680
  action: z.literal("subagent_iteration_step"),
@@ -2696,7 +2719,9 @@ const ReconnectResultAction = z.object({
2696
2719
  requestedAt: z.union([z.string(), z.date()])
2697
2720
  }).optional(),
2698
2721
  totalCreditsUsed: z.number().optional(),
2699
- iterationCount: z.number().optional()
2722
+ iterationCount: z.number().optional(),
2723
+ steps: z.array(AgentStepSchema).optional(),
2724
+ stepsTruncated: z.boolean().optional()
2700
2725
  });
2701
2726
  z.discriminatedUnion("action", [
2702
2727
  DataSubscribeRequestAction,
@@ -3412,7 +3437,7 @@ CommonBFLParams.extend({
3412
3437
  * XAI/Grok Image Models
3413
3438
  * Based on https://docs.x.ai/docs/guides/image-generations
3414
3439
  */
3415
- const XAI_IMAGE_MODELS = ["grok-2-image"];
3440
+ const XAI_IMAGE_MODELS = ["grok-imagine-image-quality"];
3416
3441
  /**
3417
3442
  * Gemini Image Models (Nano Banana)
3418
3443
  * Based on https://ai.google.dev/gemini-api/docs/image-generation
@@ -3644,6 +3669,8 @@ z.enum([
3644
3669
  "EnableRapidReplyDefault",
3645
3670
  "EnableLattice",
3646
3671
  "EnableLatticeDefault",
3672
+ "EnableDataLakes",
3673
+ "EnableDataLakesDefault",
3647
3674
  "RapidReplySettings",
3648
3675
  "EnableResearchEngine",
3649
3676
  "EnableResearchEngineDefault",
@@ -3727,6 +3754,8 @@ z.enum([
3727
3754
  "slackBotToken",
3728
3755
  "enforceMFA",
3729
3756
  "enableVoiceSession",
3757
+ "voiceV2Enabled",
3758
+ "elevenLabsServerApiKey",
3730
3759
  "voiceSessionAiVoice",
3731
3760
  "voiceSessionTranscriptionModel",
3732
3761
  "voiceSessionVadType",
@@ -4359,6 +4388,14 @@ const API_SERVICE_GROUPS = {
4359
4388
  {
4360
4389
  key: "voiceSessionVadEagerness",
4361
4390
  order: 5
4391
+ },
4392
+ {
4393
+ key: "voiceV2Enabled",
4394
+ order: 6
4395
+ },
4396
+ {
4397
+ key: "elevenLabsServerApiKey",
4398
+ order: 7
4362
4399
  }
4363
4400
  ]
4364
4401
  },
@@ -5006,6 +5043,25 @@ const settingsMap = {
5006
5043
  group: API_SERVICE_GROUPS.NOTEBOOK.id,
5007
5044
  order: 1
5008
5045
  }),
5046
+ EnableDataLakes: makeBooleanSetting({
5047
+ key: "EnableDataLakes",
5048
+ name: "Enable Data Lakes",
5049
+ defaultValue: false,
5050
+ description: "Server-side gate for the Data Lake capability (bulk folder ingestion). Off by default — turn on to expose the data-lake APIs and wizard.",
5051
+ category: "Experimental",
5052
+ group: API_SERVICE_GROUPS.EXPERIMENTAL.id,
5053
+ order: 88
5054
+ }),
5055
+ EnableDataLakesDefault: makeBooleanSetting({
5056
+ key: "EnableDataLakesDefault",
5057
+ name: "Data Lakes: On by default for users",
5058
+ defaultValue: false,
5059
+ description: "When enabled, Data Lakes is active for users who have never explicitly toggled it.",
5060
+ category: "Experimental",
5061
+ group: API_SERVICE_GROUPS.EXPERIMENTAL.id,
5062
+ order: 89,
5063
+ dependsOn: "EnableDataLakes"
5064
+ }),
5009
5065
  EnableQuestMaster: makeBooleanSetting({
5010
5066
  key: "EnableQuestMaster",
5011
5067
  name: "Enable Quest Master",
@@ -5938,6 +5994,25 @@ const settingsMap = {
5938
5994
  group: API_SERVICE_GROUPS.VOICE_SESSION.id,
5939
5995
  order: 9
5940
5996
  }),
5997
+ voiceV2Enabled: makeBooleanSetting({
5998
+ key: "voiceV2Enabled",
5999
+ name: "Enable Voice v2 (Model-Agnostic)",
6000
+ defaultValue: false,
6001
+ description: "Gate for the Voice v2 feature (ElevenLabs Conversational AI + any B4M reasoning model). When disabled, /api/voice/v2/sessions returns 403.",
6002
+ category: "AI",
6003
+ group: API_SERVICE_GROUPS.VOICE_SESSION.id,
6004
+ order: 10
6005
+ }),
6006
+ elevenLabsServerApiKey: makeStringSetting({
6007
+ key: "elevenLabsServerApiKey",
6008
+ name: "ElevenLabs Server API Key (Voice v2)",
6009
+ defaultValue: "",
6010
+ description: "Server-side ElevenLabs API key used by /api/voice/v2/sessions to mint Conversational AI signed URLs. Distinct from the per-user ElevenLabs key used for TTS preview.",
6011
+ isSensitive: true,
6012
+ category: "AI",
6013
+ group: API_SERVICE_GROUPS.VOICE_SESSION.id,
6014
+ order: 11
6015
+ }),
5941
6016
  voiceSessionAiVoice: makeStringSetting({
5942
6017
  key: "voiceSessionAiVoice",
5943
6018
  name: "Default Assistant Voice",
@@ -7609,18 +7684,36 @@ z$1.object({
7609
7684
  slug: z$1.string().min(2).max(60).regex(slugRegex, "Slug must be lowercase alphanumeric with hyphens (e.g. \"my-data-lake\")"),
7610
7685
  description: z$1.string().max(2e3).optional(),
7611
7686
  fileTagPrefix: z$1.string().min(2).max(30).refine((s) => s.endsWith(":"), "Tag prefix must end with \":\" (e.g. \"acme:\")"),
7612
- requiredUserTag: z$1.string().min(1).max(100).optional(),
7613
- organizationId: z$1.string().optional()
7687
+ requiredUserTag: z$1.string().min(1).max(100).optional()
7614
7688
  });
7615
7689
  z$1.object({
7616
7690
  name: z$1.string().min(1).max(200).optional(),
7617
7691
  description: z$1.string().max(2e3).optional(),
7618
- requiredUserTag: z$1.string().min(1).max(100).optional(),
7619
- status: z$1.enum(["active", "archived"]).optional()
7692
+ requiredUserTag: z$1.string().min(1).max(100).optional()
7620
7693
  });
7621
7694
  z$1.object({
7622
7695
  organizationId: z$1.string().optional(),
7623
- status: z$1.enum(["active", "archived"]).optional()
7696
+ status: z$1.enum([
7697
+ "draft",
7698
+ "active",
7699
+ "archived",
7700
+ "deleted"
7701
+ ]).optional()
7702
+ });
7703
+ const ConflictResolutionSchema = z$1.enum([
7704
+ "skip",
7705
+ "update",
7706
+ "duplicate"
7707
+ ]);
7708
+ z$1.object({
7709
+ dataLakeId: z$1.string(),
7710
+ totalFiles: z$1.number().positive(),
7711
+ totalSizeBytes: z$1.number().nonnegative(),
7712
+ conflictResolution: ConflictResolutionSchema.optional(),
7713
+ appliedTags: z$1.array(z$1.object({
7714
+ name: z$1.string(),
7715
+ strength: z$1.number()
7716
+ })).optional()
7624
7717
  });
7625
7718
  const BatchPresignedUrlFileItem = z$1.object({
7626
7719
  fileName: z$1.string().min(1),
@@ -7635,7 +7728,13 @@ const BatchPresignedUrlFileItem = z$1.object({
7635
7728
  });
7636
7729
  z$1.object({
7637
7730
  files: z$1.array(BatchPresignedUrlFileItem).min(1).max(100),
7638
- dataLakeSlug: z$1.string().optional()
7731
+ dataLakeSlug: z$1.string().optional(),
7732
+ /**
7733
+ * When uploading into a data lake batch, the batch id so each created FabFile is
7734
+ * correlated to the batch (stamped with batchId) AND appended to the batch
7735
+ * manifest. Without it the pipeline can't track batch progress.
7736
+ */
7737
+ batchId: z$1.string().optional()
7639
7738
  });
7640
7739
  const InferTaxonomyFolderEntry = z$1.object({
7641
7740
  relativePath: z$1.string(),
@@ -7661,7 +7760,9 @@ const SyncDeltaFileEntry = z$1.object({
7661
7760
  });
7662
7761
  z$1.object({
7663
7762
  dataLakeSlug: z$1.string(),
7664
- currentFiles: z$1.array(SyncDeltaFileEntry).min(1).max(1e4)
7763
+ currentFiles: z$1.array(SyncDeltaFileEntry).min(1).max(1e4),
7764
+ /** Per-request dedup policy for files whose content hash already exists. Defaults to 'skip'. */
7765
+ conflictResolution: ConflictResolutionSchema.optional()
7665
7766
  });
7666
7767
  z$1.object({
7667
7768
  dataLakeSlug: z$1.string(),
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ import { t as ProxyManager } from "./ProxyManager-CV94yZUW.mjs";
3
+ export { ProxyManager };
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { t as SandboxOrchestrator } from "./SandboxOrchestrator-B4GcZdBc.mjs";
2
+ import { t as SandboxOrchestrator } from "./SandboxOrchestrator-BoINxbX4.mjs";
3
3
  export { SandboxOrchestrator };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as DEFAULT_SANDBOX_CONFIG } from "./types-DBEjF9YS.mjs";
2
+ import { t as DEFAULT_SANDBOX_CONFIG } from "./types-LyRNHOiS.mjs";
3
3
  //#region src/sandbox/SandboxOrchestrator.ts
4
4
  var SandboxOrchestrator = class {
5
5
  constructor(config, runtime, proxyManager) {
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-D1RUReNL.mjs";
2
+ import { i as isBinaryAvailable, n as detectPlatform, r as expandPath, t as createSandboxRuntime } from "./SandboxRuntimeAdapter-ChGlxSGQ.mjs";
3
3
  export { createSandboxRuntime, detectPlatform, expandPath, isBinaryAvailable };
@@ -42,12 +42,12 @@ async function createSandboxRuntime() {
42
42
  const platform = detectPlatform();
43
43
  if (!platform) return null;
44
44
  if (platform === "darwin") {
45
- const { SeatbeltRuntime } = await import("./SeatbeltRuntime-CTElMR9Q.mjs");
45
+ const { SeatbeltRuntime } = await import("./SeatbeltRuntime-Qqt19cAN.mjs");
46
46
  const runtime = new SeatbeltRuntime();
47
47
  return runtime.isAvailable() ? runtime : null;
48
48
  }
49
49
  if (platform === "linux") {
50
- const { BubblewrapRuntime } = await import("./BubblewrapRuntime-CUD3bsgG.mjs");
50
+ const { BubblewrapRuntime } = await import("./BubblewrapRuntime-CkL9-gnG.mjs");
51
51
  const runtime = new BubblewrapRuntime();
52
52
  return runtime.isAvailable() ? runtime : null;
53
53
  }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-D1RUReNL.mjs";
2
+ import { i as isBinaryAvailable, r as expandPath } from "./SandboxRuntimeAdapter-ChGlxSGQ.mjs";
3
3
  import { mkdtempSync, writeFileSync } from "fs";
4
4
  import os from "os";
5
5
  import path from "path";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import { spawn } from "child_process";
3
3
  import path from "path";
4
- //#region ../../b4m-core/services/dist/bashExecute-pYljpfPn.mjs
4
+ //#region ../../b4m-core/services/dist/bashExecute-B1N1lMOS.mjs
5
5
  const DEFAULT_TIMEOUT_MS = 6e4;
6
6
  const MAX_OUTPUT_SIZE = 100 * 1024;
7
7
  /**
@@ -0,0 +1,45 @@
1
+ #!/usr/bin/env node
2
+ import { t as ConfigStore } from "../ConfigStore-aeJGqjKm.mjs";
3
+ //#region src/commands/apiCommand.ts
4
+ /**
5
+ * External API config command (--api-url / --reset-api)
6
+ * Runs outside the interactive CLI session, before any auth flow.
7
+ *
8
+ * - `--reset-api`: clears customUrl, falling back to the Bike4Mind default
9
+ * - `--api-url <url>`: sets a custom API URL (e.g. http://localhost:3000)
10
+ *
11
+ * Both clear auth tokens because they're bound to the old origin, and both
12
+ * exit on completion so the user can re-run `b4m` with a clean auth state.
13
+ */
14
+ async function handleApiCommand(options) {
15
+ const configStore = new ConfigStore();
16
+ if (options.mode === "set") {
17
+ const url = options.url.trim().replace(/\/+$/, "");
18
+ let parsed;
19
+ try {
20
+ parsed = new URL(url);
21
+ } catch {
22
+ console.error(`❌ Invalid URL: ${url}`);
23
+ console.error(" Example: --api-url http://localhost:3000");
24
+ process.exit(1);
25
+ }
26
+ if (parsed.protocol !== "http:" && parsed.protocol !== "https:") {
27
+ console.error(`❌ Only http:// and https:// URLs are supported (got ${parsed.protocol}//)`);
28
+ console.error(" Example: --api-url http://localhost:3000");
29
+ process.exit(1);
30
+ }
31
+ await configStore.setCustomApiUrl(url);
32
+ await configStore.clearAuthTokens();
33
+ console.log(`\n✅ API URL set to ${url}`);
34
+ console.log("🔓 Authentication cleared");
35
+ console.log("💡 Run `b4m` to authenticate against the new API.\n");
36
+ return;
37
+ }
38
+ await configStore.setCustomApiUrl(null);
39
+ await configStore.clearAuthTokens();
40
+ console.log("\n✅ API URL reset to Bike4Mind main service");
41
+ console.log("🔓 Authentication cleared");
42
+ console.log("💡 Run `b4m` to authenticate.\n");
43
+ }
44
+ //#endregion
45
+ export { handleApiCommand };
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-DhWcEKAu.mjs";
3
- import { t as checkRipgrep } from "../ripgrepCheck-DIu4apVE.mjs";
2
+ import { a as version, n as compareSemver, r as fetchLatestVersion } from "../updateChecker-CP_jeER9.mjs";
3
+ import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
4
4
  import { execSync } from "child_process";
5
5
  import { constants, existsSync, promises } from "fs";
6
6
  import { homedir } from "os";
@@ -1,10 +1,10 @@
1
1
  #!/usr/bin/env node
2
- import { C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, I as generateCliTools, M as loadContextFiles, N as getApiUrl, O as McpManager, Q as CheckpointStore, S as ApiClient, T as FallbackLlmBackend, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, b as createSkillTool, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, m as createCoordinateTaskTool, p as createWriteTodosTool, q as buildSystemPrompt, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, y as SubagentOrchestrator } from "../tools-CpWE3Qif.mjs";
3
- import { n as logger, t as ConfigStore } from "../ConfigStore-BauEpjvT.mjs";
4
- import { t as DEFAULT_SANDBOX_CONFIG } from "../types-DBEjF9YS.mjs";
5
- import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-D1RUReNL.mjs";
6
- import { t as SandboxOrchestrator } from "../SandboxOrchestrator-B4GcZdBc.mjs";
7
- import { t as ProxyManager } from "../ProxyManager-BsCoxpns.mjs";
2
+ import { C as WebSocketToolExecutor, D as ServerLlmBackend, E as WebSocketLlmBackend, F as PermissionManager, I as generateCliTools, M as loadContextFiles, N as getApiUrl, O as McpManager, Q as CheckpointStore, S as ApiClient, T as FallbackLlmBackend, W as setWebSocketToolExecutor, X as ReActAgent, Y as isReadOnlyTool, Z as CustomCommandStore, _ as createAgentDelegateTool, b as createSkillTool, d as createFindDefinitionTool, et as SessionStore, f as createTodoStore, g as BackgroundAgentManager, h as createBackgroundAgentTools, m as createCoordinateTaskTool, p as createWriteTodosTool, q as buildSystemPrompt, u as createGetFileStructureTool, v as AgentStore, w as WebSocketConnectionManager, y as SubagentOrchestrator } from "../tools-RdGu37Lw.mjs";
3
+ import { n as logger, t as ConfigStore } from "../ConfigStore-aeJGqjKm.mjs";
4
+ import { t as DEFAULT_SANDBOX_CONFIG } from "../types-LyRNHOiS.mjs";
5
+ import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-ChGlxSGQ.mjs";
6
+ import { t as SandboxOrchestrator } from "../SandboxOrchestrator-BoINxbX4.mjs";
7
+ import { t as ProxyManager } from "../ProxyManager-CV94yZUW.mjs";
8
8
  import { randomBytes } from "crypto";
9
9
  import { v4 } from "uuid";
10
10
  //#region src/commands/headlessCommand.ts
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-BauEpjvT.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-aeJGqjKm.mjs";
3
3
  //#region src/commands/mcpCommand.ts
4
4
  /**
5
5
  * External MCP commands (b4m mcp list, b4m mcp add, etc.)
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { a as version, i as forceCheckForUpdate } from "../updateChecker-DhWcEKAu.mjs";
3
- import { t as checkRipgrep } from "../ripgrepCheck-DIu4apVE.mjs";
2
+ import { a as version, i as forceCheckForUpdate } from "../updateChecker-CP_jeER9.mjs";
3
+ import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
4
4
  import { execSync } from "child_process";
5
5
  //#region src/commands/updateCommand.ts
6
6
  /**
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
2
+ import { t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
3
3
  import { existsSync, promises } from "fs";
4
4
  import path from "path";
5
- //#region ../../b4m-core/services/dist/createFile-C1JoeuYh.mjs
5
+ //#region ../../b4m-core/services/dist/createFile-DPv180yF.mjs
6
6
  async function createFile(params, allowedDirectories) {
7
7
  const { path: filePath, content, createDirectories = true } = params;
8
8
  const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "create");
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { t as assertPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
2
+ import { t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
3
3
  import { existsSync, promises, statSync } from "fs";
4
4
  import path from "path";
5
- //#region ../../b4m-core/services/dist/deleteFile-BTberNGj.mjs
5
+ //#region ../../b4m-core/services/dist/deleteFile-BdjUwUQF.mjs
6
6
  async function deleteFile(params, allowedDirectories) {
7
7
  const { path: filePath, recursive = false } = params;
8
8
  const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "delete");
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { n as isPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
2
+ import { n as isPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
3
3
  import path from "path";
4
4
  import { stat } from "fs/promises";
5
5
  import { glob } from "glob";
6
- //#region ../../b4m-core/services/dist/globFiles-Bez8QCbS.mjs
6
+ //#region ../../b4m-core/services/dist/globFiles-DjfDGaUK.mjs
7
7
  const DEFAULT_IGNORE_PATTERNS = [
8
8
  "**/node_modules/**",
9
9
  "**/.git/**",
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { n as isPathAllowed } from "./pathValidation-CIytuhr3-Dt5dntLx.mjs";
2
+ import { n as isPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
3
3
  import { execFile } from "child_process";
4
4
  import { existsSync } from "fs";
5
5
  import path from "path";
6
6
  import { stat } from "fs/promises";
7
7
  import { promisify } from "util";
8
- //#region ../../b4m-core/services/dist/grepSearch-BxucZWO8.mjs
8
+ //#region ../../b4m-core/services/dist/grepSearch-DJs-cubo.mjs
9
9
  const execFileAsync = promisify(execFile);
10
10
  /** Cached ripgrep binary path after first resolution */
11
11
  let cachedRgPath = null;