@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.
- package/README.md +13 -3
- package/bin/bike4mind-cli.mjs +44 -1
- package/dist/{BubblewrapRuntime-CUD3bsgG.mjs → BubblewrapRuntime-CkL9-gnG.mjs} +1 -1
- package/dist/{ConfigStore-BauEpjvT.mjs → ConfigStore-aeJGqjKm.mjs} +116 -15
- package/dist/ProxyManager-ByuAHFMq.mjs +3 -0
- package/dist/{SandboxOrchestrator-C4oDqltp.mjs → SandboxOrchestrator-BS6gALNq.mjs} +1 -1
- package/dist/{SandboxOrchestrator-B4GcZdBc.mjs → SandboxOrchestrator-BoINxbX4.mjs} +1 -1
- package/dist/{SandboxRuntimeAdapter-DXa3nFOw.mjs → SandboxRuntimeAdapter-CKelGICD.mjs} +1 -1
- package/dist/{SandboxRuntimeAdapter-D1RUReNL.mjs → SandboxRuntimeAdapter-ChGlxSGQ.mjs} +2 -2
- package/dist/{SeatbeltRuntime-CTElMR9Q.mjs → SeatbeltRuntime-Qqt19cAN.mjs} +1 -1
- package/dist/{bashExecute-pYljpfPn-BZXHMQEl.mjs → bashExecute-B1N1lMOS-TZVDbcQ4.mjs} +1 -1
- package/dist/commands/apiCommand.mjs +45 -0
- package/dist/commands/doctorCommand.mjs +2 -2
- package/dist/commands/headlessCommand.mjs +6 -6
- package/dist/commands/mcpCommand.mjs +1 -1
- package/dist/commands/updateCommand.mjs +2 -2
- package/dist/{createFile-C1JoeuYh-metInFKd.mjs → createFile-DPv180yF-BnWFIxey.mjs} +2 -2
- package/dist/{deleteFile-BTberNGj-CW922hRM.mjs → deleteFile-BdjUwUQF-B3XOJmg3.mjs} +2 -2
- package/dist/{globFiles-Bez8QCbS-DZb6McbJ.mjs → globFiles-DjfDGaUK-CNR8pMRC.mjs} +2 -2
- package/dist/{grepSearch-BxucZWO8-lPRv6R6F.mjs → grepSearch-DJs-cubo-Bm0Y8oS3.mjs} +2 -2
- package/dist/index.mjs +258 -39
- package/dist/{pathValidation-CIytuhr3-Dt5dntLx.mjs → pathValidation-D8tjkQXE-1HwvsuYT.mjs} +1 -1
- package/dist/store-DgzCTRkN.mjs +3 -0
- package/dist/{tools-CpWE3Qif.mjs → tools-RdGu37Lw.mjs} +11217 -10240
- package/dist/types-CqscS34o.mjs +3 -0
- package/dist/{updateChecker-DhWcEKAu.mjs → updateChecker-CP_jeER9.mjs} +1 -1
- package/dist/utils-BGtSXfce.mjs +3 -0
- package/dist/utils-PpNti-tY.mjs +146 -0
- package/package.json +31 -31
- package/dist/ProxyManager-DIAAw902.mjs +0 -3
- package/dist/store-5PXzE9DM.mjs +0 -3
- package/dist/types-DK3P88Px.mjs +0 -3
- /package/dist/{ImageStore-BFp_d12J.mjs → ImageStore-BVmEG1xc.mjs} +0 -0
- /package/dist/{ProxyManager-BsCoxpns.mjs → ProxyManager-CV94yZUW.mjs} +0 -0
- /package/dist/{StderrViolationParser-BFP4bo7I.mjs → StderrViolationParser-CS43a-TP.mjs} +0 -0
- /package/dist/{ViolationLogStore-Dp6HF0nz.mjs → ViolationLogStore-B-plqJfn.mjs} +0 -0
- /package/dist/{ripgrepCheck-DIu4apVE.mjs → ripgrepCheck-BmkyTK2i.mjs} +0 -0
- /package/dist/{store-BonrwrMi.mjs → store-DV5s-qni.mjs} +0 -0
- /package/dist/{terminalSetup-DxloCowq.mjs → terminalSetup-BbJt04ZG.mjs} +0 -0
- /package/dist/{treeSitterEngine-Cw2LbVZT.mjs → treeSitterEngine-BRbQ9b7I.mjs} +0 -0
- /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.
|
|
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
|
-
#
|
|
423
|
+
# 5. Verify
|
|
414
424
|
which b4m
|
|
415
425
|
b4m --version
|
|
416
426
|
```
|
|
417
427
|
|
|
418
|
-
After step
|
|
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
|
|
package/bin/bike4mind-cli.mjs
CHANGED
|
@@ -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-
|
|
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-
|
|
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
|
|
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["
|
|
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([
|
|
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-
|
|
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([
|
|
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(),
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { t as DEFAULT_SANDBOX_CONFIG } from "./types-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
3
|
-
import { t as checkRipgrep } from "../ripgrepCheck-
|
|
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-
|
|
3
|
-
import { n as logger, t as ConfigStore } from "../ConfigStore-
|
|
4
|
-
import { t as DEFAULT_SANDBOX_CONFIG } from "../types-
|
|
5
|
-
import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-
|
|
6
|
-
import { t as SandboxOrchestrator } from "../SandboxOrchestrator-
|
|
7
|
-
import { t as ProxyManager } from "../ProxyManager-
|
|
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,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { a as version, i as forceCheckForUpdate } from "../updateChecker-
|
|
3
|
-
import { t as checkRipgrep } from "../ripgrepCheck-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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-
|
|
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;
|