@bike4mind/cli 0.9.3 → 0.10.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/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-DPWN3-0c.mjs} +60 -8
  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 +19 -18
  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-_X4rUM4L.mjs} +11132 -10244
  25. package/dist/types-CqscS34o.mjs +3 -0
  26. package/dist/{updateChecker-DhWcEKAu.mjs → updateChecker-C3DYG0Gn.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:
@@ -2578,6 +2597,7 @@ const AgentStepSchema = z.object({
2578
2597
  toolName: z.string().optional(),
2579
2598
  toolInput: z.unknown().optional(),
2580
2599
  timestamp: z.number(),
2600
+ iteration: z.number().optional(),
2581
2601
  tokenUsage: z.object({
2582
2602
  prompt: z.number(),
2583
2603
  completion: z.number(),
@@ -2651,7 +2671,8 @@ const SubagentStartedAction = z.object({
2651
2671
  agentName: z.string(),
2652
2672
  model: z.string().optional(),
2653
2673
  thoroughness: z.string().optional(),
2654
- maxIterations: z.number().optional()
2674
+ maxIterations: z.number().optional(),
2675
+ isBackground: z.boolean().optional()
2655
2676
  });
2656
2677
  const SubagentIterationStepAction = z.object({
2657
2678
  action: z.literal("subagent_iteration_step"),
@@ -2696,7 +2717,9 @@ const ReconnectResultAction = z.object({
2696
2717
  requestedAt: z.union([z.string(), z.date()])
2697
2718
  }).optional(),
2698
2719
  totalCreditsUsed: z.number().optional(),
2699
- iterationCount: z.number().optional()
2720
+ iterationCount: z.number().optional(),
2721
+ steps: z.array(AgentStepSchema).optional(),
2722
+ stepsTruncated: z.boolean().optional()
2700
2723
  });
2701
2724
  z.discriminatedUnion("action", [
2702
2725
  DataSubscribeRequestAction,
@@ -3412,7 +3435,7 @@ CommonBFLParams.extend({
3412
3435
  * XAI/Grok Image Models
3413
3436
  * Based on https://docs.x.ai/docs/guides/image-generations
3414
3437
  */
3415
- const XAI_IMAGE_MODELS = ["grok-2-image"];
3438
+ const XAI_IMAGE_MODELS = ["grok-imagine-image-quality"];
3416
3439
  /**
3417
3440
  * Gemini Image Models (Nano Banana)
3418
3441
  * Based on https://ai.google.dev/gemini-api/docs/image-generation
@@ -3727,6 +3750,8 @@ z.enum([
3727
3750
  "slackBotToken",
3728
3751
  "enforceMFA",
3729
3752
  "enableVoiceSession",
3753
+ "voiceV2Enabled",
3754
+ "elevenLabsServerApiKey",
3730
3755
  "voiceSessionAiVoice",
3731
3756
  "voiceSessionTranscriptionModel",
3732
3757
  "voiceSessionVadType",
@@ -4359,6 +4384,14 @@ const API_SERVICE_GROUPS = {
4359
4384
  {
4360
4385
  key: "voiceSessionVadEagerness",
4361
4386
  order: 5
4387
+ },
4388
+ {
4389
+ key: "voiceV2Enabled",
4390
+ order: 6
4391
+ },
4392
+ {
4393
+ key: "elevenLabsServerApiKey",
4394
+ order: 7
4362
4395
  }
4363
4396
  ]
4364
4397
  },
@@ -5938,6 +5971,25 @@ const settingsMap = {
5938
5971
  group: API_SERVICE_GROUPS.VOICE_SESSION.id,
5939
5972
  order: 9
5940
5973
  }),
5974
+ voiceV2Enabled: makeBooleanSetting({
5975
+ key: "voiceV2Enabled",
5976
+ name: "Enable Voice v2 (Model-Agnostic)",
5977
+ defaultValue: false,
5978
+ description: "Gate for the Voice v2 feature (ElevenLabs Conversational AI + any B4M reasoning model). When disabled, /api/voice/v2/sessions returns 403.",
5979
+ category: "AI",
5980
+ group: API_SERVICE_GROUPS.VOICE_SESSION.id,
5981
+ order: 10
5982
+ }),
5983
+ elevenLabsServerApiKey: makeStringSetting({
5984
+ key: "elevenLabsServerApiKey",
5985
+ name: "ElevenLabs Server API Key (Voice v2)",
5986
+ defaultValue: "",
5987
+ 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.",
5988
+ isSensitive: true,
5989
+ category: "AI",
5990
+ group: API_SERVICE_GROUPS.VOICE_SESSION.id,
5991
+ order: 11
5992
+ }),
5941
5993
  voiceSessionAiVoice: makeStringSetting({
5942
5994
  key: "voiceSessionAiVoice",
5943
5995
  name: "Default Assistant Voice",
@@ -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-DPWN3-0c.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-C3DYG0Gn.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-_X4rUM4L.mjs";
3
+ import { n as logger, t as ConfigStore } from "../ConfigStore-DPWN3-0c.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-DPWN3-0c.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-C3DYG0Gn.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;