@bike4mind/cli 0.22.0 → 1.1.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 (26) hide show
  1. package/dist/{AgentHistoryStore-7zQUOxkA.mjs → AgentHistoryStore-kT9eNMRO.mjs} +8889 -7858
  2. package/dist/{ApiClient-XdY9O3nz.mjs → ApiClient-BOWpVvTq.mjs} +2 -2
  3. package/dist/{ConfigStore-8_0WsN5r.mjs → ConfigStore-DdHHCH2t.mjs} +1451 -249
  4. package/dist/{SandboxOrchestrator-BFPVpmB5.mjs → SandboxOrchestrator-BbMDgjzr.mjs} +1 -1
  5. package/dist/{SandboxOrchestrator-C8uleDn2.mjs → SandboxOrchestrator-CIegJrCj.mjs} +1 -1
  6. package/dist/{buildAgent-CvPRH2n-.mjs → buildAgent-B_kArQ_Y.mjs} +18 -9
  7. package/dist/commands/acpCommand.mjs +34 -13
  8. package/dist/commands/apiCommand.mjs +1 -1
  9. package/dist/commands/doctorCommand.mjs +1 -1
  10. package/dist/commands/envCommand.mjs +1 -1
  11. package/dist/commands/headlessCommand.mjs +73 -33
  12. package/dist/commands/mcpCommand.mjs +8 -13
  13. package/dist/commands/pluginCommand.mjs +9 -15
  14. package/dist/commands/updateCommand.mjs +1 -1
  15. package/dist/{createFile-DPv180yF-BnWFIxey.mjs → createFile-B8bur5Rb-CVzCarEA.mjs} +2 -2
  16. package/dist/{deleteFile-BdjUwUQF-B3XOJmg3.mjs → deleteFile-9B3gW_Nb-DG2sovIl.mjs} +2 -2
  17. package/dist/{globFiles-DjfDGaUK-CNR8pMRC.mjs → globFiles-CwJ8qmYo-BR5b2KvO.mjs} +3 -2
  18. package/dist/{grepSearch-BaYUfIYs-C-fxWc9G.mjs → grepSearch-BgoOOwGe-DtlV8Gn-.mjs} +4 -4
  19. package/dist/index.mjs +212 -47
  20. package/dist/{package-OZdXqn0e.mjs → package-Bqg2LSnH.mjs} +1 -1
  21. package/dist/{pathValidation-D8tjkQXE-1HwvsuYT.mjs → pathValidation-BRqf4HFX-CHwtwp3O.mjs} +7 -3
  22. package/dist/{serve-CEqSZwl6.mjs → serve-DO9Edl5S.mjs} +2 -2
  23. package/dist/types-CdIKgWWe.mjs +3 -0
  24. package/dist/{types-LyRNHOiS.mjs → types-F61_hxmG.mjs} +2 -0
  25. package/package.json +28 -28
  26. package/dist/types-CqscS34o.mjs +0 -3
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- import { t as SandboxOrchestrator } from "./SandboxOrchestrator-C8uleDn2.mjs";
2
+ import { t as SandboxOrchestrator } from "./SandboxOrchestrator-CIegJrCj.mjs";
3
3
  export { SandboxOrchestrator };
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as DEFAULT_SANDBOX_CONFIG } from "./types-LyRNHOiS.mjs";
2
+ import { t as DEFAULT_SANDBOX_CONFIG } from "./types-F61_hxmG.mjs";
3
3
  //#region src/sandbox/SandboxOrchestrator.ts
4
4
  var SandboxOrchestrator = class {
5
5
  constructor(config, runtime, proxyManager) {
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { F as loadContextFiles, J as setWebSocketToolExecutor, L as generateCliTools, M as ReActAgent, X as buildSystemPrompt, Y as getPlanModeFilePath, a as McpManager, i as AgentStore, l as OllamaBackend, n as BackgroundAgentManager, o as createSseBackend, r as SubagentOrchestrator, s as ServerLlmBackend, t as AgentHistoryStore } from "./AgentHistoryStore-7zQUOxkA.mjs";
3
- import { n as logger } from "./ConfigStore-8_0WsN5r.mjs";
2
+ import { I as generateCliTools, J as setWebSocketToolExecutor, L as wrapTools, N as ReActAgent, X as buildSystemPrompt, Y as getPlanModeFilePath, a as loadProjectContext, c as ServerLlmBackend, i as buildProjectAgentStore, n as BackgroundAgentManager, o as McpManager, r as SubagentOrchestrator, s as createSseBackend, t as AgentHistoryStore, u as OllamaBackend } from "./AgentHistoryStore-kT9eNMRO.mjs";
3
+ import { n as logger } from "./ConfigStore-DdHHCH2t.mjs";
4
4
  import { z as z$1 } from "zod";
5
5
  import WebSocket from "ws";
6
6
  //#region src/llm/NotifyingLlmBackend.ts
@@ -657,8 +657,8 @@ async function buildSandbox(input) {
657
657
  const { config, sessionId, permissionManager, checkpointStore } = input;
658
658
  const [{ createSandboxRuntime }, { SandboxOrchestrator }, { DEFAULT_SANDBOX_CONFIG }, { ProxyManager }, { ViolationLogStore }] = await Promise.all([
659
659
  import("./SandboxRuntimeAdapter-CKelGICD.mjs"),
660
- import("./SandboxOrchestrator-BFPVpmB5.mjs"),
661
- import("./types-CqscS34o.mjs"),
660
+ import("./SandboxOrchestrator-BbMDgjzr.mjs"),
661
+ import("./types-CdIKgWWe.mjs"),
662
662
  import("./ProxyManager-B1jFWL7b.mjs"),
663
663
  import("./ViolationLogStore-byEhxa2A.mjs")
664
664
  ]);
@@ -712,14 +712,21 @@ async function buildSupportingStores(input) {
712
712
  const { tools: b4mTools } = await generateCliTools(config.userId, llm, modelId, permissionManager, promptFn, agentContext, configStore, apiClient, void 0, userQuestionFn, checkpointStore, sandboxOrchestrator, additionalDirectories);
713
713
  const mcpManager = new McpManager(config);
714
714
  const builtinAgentsDir = new URL("../agents/defaults/", import.meta.url).pathname;
715
- const agentProjectDir = configStore.getProjectConfigDir();
716
- const agentStore = new AgentStore(builtinAgentsDir, agentProjectDir || process.cwd());
715
+ const agentStore = buildProjectAgentStore(builtinAgentsDir, configStore);
717
716
  const [, , contextResult] = await Promise.all([
718
717
  mcpManager.initialize(),
719
718
  agentStore.loadAgents(),
720
- loadContextFiles(agentProjectDir)
719
+ loadProjectContext(configStore)
721
720
  ]);
722
- const mcpTools = mcpManager.getTools();
721
+ const mcpTools = wrapTools(mcpManager.getTools(), {
722
+ permissionManager,
723
+ showPermissionPrompt: promptFn,
724
+ agentContext,
725
+ configStore,
726
+ apiClient,
727
+ sandboxOrchestrator,
728
+ allowedDirectories: additionalDirectories
729
+ });
723
730
  const deferredB4mToolNames = /* @__PURE__ */ new Set([
724
731
  "math_evaluate",
725
732
  "dice_roll",
@@ -754,7 +761,9 @@ async function buildSupportingStores(input) {
754
761
  showUserQuestion: userQuestionFn,
755
762
  checkpointStore,
756
763
  onSubagentUsage,
757
- historyStore
764
+ historyStore,
765
+ sandboxOrchestrator,
766
+ additionalDirectories
758
767
  });
759
768
  const backgroundManager = new BackgroundAgentManager(orchestrator);
760
769
  backgroundManager.setOnStatusChange(onBackgroundStatusChange);
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RemoteSkillSource, A as FallbackLlmBackend, C as createWriteTodosTool, D as createResumeAgentTool, E as createCoordinateTaskTool, I as PermissionManager, J as setWebSocketToolExecutor, O as createBackgroundAgentTools, Q as isReadOnlyTool, S as createTodoStore, et as CustomCommandStore, k as createAgentDelegateTool, nt as SessionStore, tt as CheckpointStore, w as createSkillTool, x as createFindDefinitionTool, y as createGetFileStructureTool } from "../AgentHistoryStore-7zQUOxkA.mjs";
3
- import { c as requireApiUrl, n as logger, t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
4
- import { t as ApiClient } from "../ApiClient-XdY9O3nz.mjs";
5
- import { a as createToolSearchTool, i as buildLlmBackend, n as buildSupportingStores, o as deferredToolRegistry, r as buildSandbox, s as NotifyingLlmBackend, t as buildAgent } from "../buildAgent-CvPRH2n-.mjs";
2
+ import { $ as CustomCommandStore, A as createAgentDelegateTool, C as createTodoStore, D as createCoordinateTaskTool, F as PermissionManager, J as setWebSocketToolExecutor, L as wrapTools, O as createResumeAgentTool, Q as RemoteSkillSource, S as createFindDefinitionTool, T as createSkillTool, b as createGetFileStructureTool, et as CheckpointStore, j as FallbackLlmBackend, k as createBackgroundAgentTools, tt as SessionStore, w as createWriteTodosTool } from "../AgentHistoryStore-kT9eNMRO.mjs";
3
+ import { n as logger, p as requireApiUrl, s as isReadOnlyTool, t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
4
+ import { t as ApiClient } from "../ApiClient-BOWpVvTq.mjs";
5
+ import { a as createToolSearchTool, i as buildLlmBackend, n as buildSupportingStores, o as deferredToolRegistry, r as buildSandbox, s as NotifyingLlmBackend, t as buildAgent } from "../buildAgent-B_kArQ_Y.mjs";
6
6
  import { randomUUID } from "crypto";
7
7
  import { existsSync, realpathSync, statSync } from "fs";
8
8
  import { isAbsolute } from "path";
@@ -634,7 +634,12 @@ var AcpServer = class {
634
634
  agentStore,
635
635
  backgroundManager,
636
636
  historyStore,
637
- sessionId: stackSessionId
637
+ sessionId: stackSessionId,
638
+ permissionManager,
639
+ agentContext,
640
+ apiClient,
641
+ sandboxOrchestrator: sandboxOrchestrator ?? void 0,
642
+ allowedDirectories: additionalDirectories
638
643
  });
639
644
  const agentToolsRef = { current: null };
640
645
  const toolSearchTool = deferredToolRegistry.size() > 0 ? createToolSearchTool(() => {
@@ -678,24 +683,40 @@ var AcpServer = class {
678
683
  };
679
684
  }
680
685
  buildCliTools(input) {
681
- const { config, orchestrator, agentStore, backgroundManager, historyStore, sessionId } = input;
686
+ const { config, orchestrator, agentStore, backgroundManager, historyStore, sessionId, permissionManager, agentContext, apiClient, sandboxOrchestrator, allowedDirectories } = input;
687
+ const cliWrapDeps = {
688
+ permissionManager,
689
+ showPermissionPrompt: this.promptFn,
690
+ agentContext,
691
+ configStore: this.configStore,
692
+ apiClient,
693
+ sandboxOrchestrator,
694
+ allowedDirectories
695
+ };
696
+ const wrappedSecurityTools = wrapTools([
697
+ createFindDefinitionTool(allowedDirectories),
698
+ createGetFileStructureTool(allowedDirectories),
699
+ ...config.preferences.enableSkillTool !== false ? [createSkillTool({
700
+ customCommandStore: this.customCommandStore,
701
+ subagentOrchestrator: orchestrator,
702
+ sessionId,
703
+ permissionManager,
704
+ promptFn: this.promptFn,
705
+ allowedDirectories
706
+ })] : []
707
+ ], cliWrapDeps);
682
708
  const tools = [
683
709
  createAgentDelegateTool(orchestrator, agentStore, sessionId, backgroundManager),
684
710
  ...createBackgroundAgentTools(backgroundManager),
685
711
  createResumeAgentTool(orchestrator, historyStore, backgroundManager),
686
712
  createWriteTodosTool(createTodoStore()),
687
- createFindDefinitionTool(),
688
- createGetFileStructureTool()
713
+ ...wrappedSecurityTools
689
714
  ];
690
- if (config.preferences.enableSkillTool !== false) tools.push(createSkillTool({
691
- customCommandStore: this.customCommandStore,
692
- subagentOrchestrator: orchestrator,
693
- sessionId
694
- }));
695
715
  if (config.preferences.enableCoordinatorMode === true) tools.push(createCoordinateTaskTool(orchestrator, agentStore, sessionId));
696
716
  return tools;
697
717
  }
698
718
  async loadCustomCommands() {
719
+ this.customCommandStore.setProjectTrusted(this.configStore.isProjectTrusted());
699
720
  try {
700
721
  await this.customCommandStore.loadCommands();
701
722
  } catch {}
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { l as resolveApiEndpoint, s as parseApiUrl, t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
2
+ import { f as parseApiUrl, m as resolveApiEndpoint, t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
3
3
  //#region src/commands/apiCommand.ts
4
4
  /**
5
5
  * External API config command (--api-url / --reset-api)
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "../package-OZdXqn0e.mjs";
2
+ import { t as version } from "../package-Bqg2LSnH.mjs";
3
3
  import { a as fetchLatestVersion, c as isNpmPrefixWritable, i as compareSemver } from "../updateChecker-CQW8bxo6.mjs";
4
4
  import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
5
5
  import { execSync } from "child_process";
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
3
3
  //#region src/commands/envCommand.ts
4
4
  /**
5
5
  * Environment switching for the `--dev` / `--prod` launch flags.
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { $ as RemoteSkillSource, A as FallbackLlmBackend, B as classifyCommandRisk, C as createWriteTodosTool, D as createResumeAgentTool, E as createCoordinateTaskTool, F as loadContextFiles, I as PermissionManager, J as setWebSocketToolExecutor, L as generateCliTools, M as ReActAgent, O as createBackgroundAgentTools, Q as isReadOnlyTool, S as createTodoStore, X as buildSystemPrompt, a as McpManager, b as createWorkItemTools, et as CustomCommandStore, i as AgentStore, k as createAgentDelegateTool, n as BackgroundAgentManager, nt as SessionStore, o as createSseBackend, r as SubagentOrchestrator, t as AgentHistoryStore, tt as CheckpointStore, w as createSkillTool, x as createFindDefinitionTool, y as createGetFileStructureTool, z as SHELL_LIKE_TOOL_COMMAND_FIELDS } from "../AgentHistoryStore-7zQUOxkA.mjs";
3
- import { c as requireApiUrl, n as logger, t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
4
- import { t as ApiClient } from "../ApiClient-XdY9O3nz.mjs";
5
- import { t as DEFAULT_SANDBOX_CONFIG } from "../types-LyRNHOiS.mjs";
2
+ import { $ as CustomCommandStore, A as createAgentDelegateTool, C as createTodoStore, D as createCoordinateTaskTool, F as PermissionManager, G as classifyCommandRisk, I as generateCliTools, J as setWebSocketToolExecutor, L as wrapTools, N as ReActAgent, O as createResumeAgentTool, Q as RemoteSkillSource, S as createFindDefinitionTool, T as createSkillTool, X as buildSystemPrompt, a as loadProjectContext, b as createGetFileStructureTool, et as CheckpointStore, i as buildProjectAgentStore, j as FallbackLlmBackend, k as createBackgroundAgentTools, n as BackgroundAgentManager, o as McpManager, r as SubagentOrchestrator, s as createSseBackend, t as AgentHistoryStore, tt as SessionStore, w as createWriteTodosTool, x as createWorkItemTools, z as SHELL_LIKE_TOOL_COMMAND_FIELDS } from "../AgentHistoryStore-kT9eNMRO.mjs";
3
+ import { n as logger, p as requireApiUrl, s as isReadOnlyTool, t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
4
+ import { t as ApiClient } from "../ApiClient-BOWpVvTq.mjs";
5
+ import { t as DEFAULT_SANDBOX_CONFIG } from "../types-F61_hxmG.mjs";
6
6
  import { r as reconstructTurnBlocks, t as WorkItemsClient } from "../WorkItemsClient-Cow6nXx7.mjs";
7
7
  import { t as createSandboxRuntime } from "../SandboxRuntimeAdapter-ChGlxSGQ.mjs";
8
- import { t as SandboxOrchestrator } from "../SandboxOrchestrator-C8uleDn2.mjs";
8
+ import { t as SandboxOrchestrator } from "../SandboxOrchestrator-CIegJrCj.mjs";
9
9
  import { t as ProxyManager } from "../ProxyManager-C1-lgzEU.mjs";
10
10
  import { randomBytes } from "crypto";
11
11
  import { v4 } from "uuid";
@@ -120,8 +120,9 @@ const HEADLESS_PERMISSION_POLICY_KEYS = [
120
120
  ];
121
121
  const RISK_RANK = {
122
122
  low: 0,
123
- medium: 1,
124
- high: 2
123
+ unclassified: 1,
124
+ medium: 2,
125
+ high: 3
125
126
  };
126
127
  function readOptionalStringArray(value, label) {
127
128
  if (value === void 0) return [];
@@ -174,6 +175,39 @@ function evaluatePermissionPolicy(policy, toolName, riskLevel) {
174
175
  reason: `policy default (${policy.defaultAction})`
175
176
  };
176
177
  }
178
+ /**
179
+ * Resolve a headless permission decision from the fixed precedence ladder:
180
+ * --dangerously-skip-permissions -> allow-once (explicit blanket override)
181
+ * a directory-grant request -> deny (widening the filesystem allow-list is
182
+ * its own decision; headless has no human to
183
+ * grant it, so fail closed - never inherit the
184
+ * originating tool's policy verdict)
185
+ * a --permission-policy -> its per-tool/per-risk verdict
186
+ * otherwise -> deny (safe default, no silent auto-approve)
187
+ * Extracted from the headless prompt closure so the ladder is unit-testable.
188
+ */
189
+ function resolveHeadlessPermissionDecision(params) {
190
+ const { dangerouslySkipPermissions, isDirectoryGrant, toolName, riskLevel, permissionPolicy } = params;
191
+ if (dangerouslySkipPermissions) return {
192
+ action: "allow-once",
193
+ reason: "dangerously-skip-permissions"
194
+ };
195
+ if (isDirectoryGrant) return {
196
+ action: "deny",
197
+ reason: "directory access not granted in headless mode"
198
+ };
199
+ if (permissionPolicy) {
200
+ const verdict = evaluatePermissionPolicy(permissionPolicy, toolName, riskLevel);
201
+ return {
202
+ action: verdict.action === "allow" ? "allow-once" : "deny",
203
+ reason: verdict.reason
204
+ };
205
+ }
206
+ return {
207
+ action: "deny",
208
+ reason: "no permission policy; default deny"
209
+ };
210
+ }
177
211
  //#endregion
178
212
  //#region src/commands/headlessCommand.ts
179
213
  /**
@@ -227,6 +261,7 @@ async function handleHeadlessCommand(options) {
227
261
  }
228
262
  permissionPolicy = parsePermissionPolicy(policyRaw);
229
263
  }
264
+ customCommandStore.setProjectTrusted(configStore.isProjectTrusted());
230
265
  try {
231
266
  await customCommandStore.loadCommands();
232
267
  } catch {}
@@ -280,28 +315,20 @@ async function handleHeadlessCommand(options) {
280
315
  const permissionManager = new PermissionManager(config.trustedTools ?? [], void 0, config.tools.disabled);
281
316
  const emit = createHeadlessEmitter(runId, (line) => process.stdout.write(line));
282
317
  const streaming = outputFormat === "stream-json";
283
- const promptFn = (toolName, args, _preview) => {
318
+ const promptFn = (toolName, args, _preview, kind) => {
284
319
  const risk = classifyToolRisk(toolName, args, permissionManager.getCategory(toolName));
285
320
  if (streaming) emit({
286
321
  type: "permission_request",
287
322
  toolName,
288
323
  risk
289
324
  });
290
- let decision;
291
- if (dangerouslySkipPermissions) decision = {
292
- action: "allow-once",
293
- reason: "dangerously-skip-permissions"
294
- };
295
- else if (permissionPolicy) {
296
- const verdict = evaluatePermissionPolicy(permissionPolicy, toolName, risk.level);
297
- decision = {
298
- action: verdict.action === "allow" ? "allow-once" : "deny",
299
- reason: verdict.reason
300
- };
301
- } else decision = {
302
- action: "deny",
303
- reason: "no permission policy; default deny"
304
- };
325
+ const decision = resolveHeadlessPermissionDecision({
326
+ dangerouslySkipPermissions,
327
+ isDirectoryGrant: kind === "directory-grant",
328
+ toolName,
329
+ riskLevel: risk.level,
330
+ permissionPolicy
331
+ });
305
332
  if (streaming) emit({
306
333
  type: "permission_decision",
307
334
  toolName,
@@ -330,15 +357,23 @@ async function handleHeadlessCommand(options) {
330
357
  };
331
358
  const { tools: b4mTools } = await generateCliTools(config.userId, llm, modelInfo.id, permissionManager, promptFn, agentContext, configStore, apiClient, void 0, userQuestionFn, checkpointStore, sandboxOrchestrator, additionalDirectories);
332
359
  const mcpManager = new McpManager(config);
333
- const projectConfigDir = configStore.getProjectConfigDir();
334
360
  const builtinAgentsDir = new URL("../agents/defaults/", import.meta.url).pathname;
335
- const agentStore = new AgentStore(builtinAgentsDir, projectConfigDir ?? process.cwd());
361
+ const agentStore = buildProjectAgentStore(builtinAgentsDir, configStore);
336
362
  const [, , contextResult] = await Promise.all([
337
363
  mcpManager.initialize(),
338
364
  agentStore.loadAgents(),
339
- loadContextFiles(projectConfigDir)
365
+ loadProjectContext(configStore)
340
366
  ]);
341
- const mcpTools = mcpManager.getTools();
367
+ const cliWrapDeps = {
368
+ permissionManager,
369
+ showPermissionPrompt: promptFn,
370
+ agentContext,
371
+ configStore,
372
+ apiClient,
373
+ sandboxOrchestrator,
374
+ allowedDirectories: additionalDirectories
375
+ };
376
+ const mcpTools = wrapTools(mcpManager.getTools(), cliWrapDeps);
342
377
  const historyStore = new AgentHistoryStore(config.preferences.subagentHistoryTtlMs ?? 36e5);
343
378
  const orchestrator = new SubagentOrchestrator({
344
379
  userId: config.userId,
@@ -353,7 +388,9 @@ async function handleHeadlessCommand(options) {
353
388
  enableParallelToolExecution: config.preferences.enableParallelToolExecution === true,
354
389
  showUserQuestion: userQuestionFn,
355
390
  checkpointStore,
356
- historyStore
391
+ historyStore,
392
+ sandboxOrchestrator,
393
+ additionalDirectories
357
394
  });
358
395
  const backgroundManager = new BackgroundAgentManager(orchestrator);
359
396
  const agentDelegateTool = createAgentDelegateTool(orchestrator, agentStore, session.id, backgroundManager);
@@ -361,15 +398,18 @@ async function handleHeadlessCommand(options) {
361
398
  const resumeAgentTool = createResumeAgentTool(orchestrator, historyStore, backgroundManager);
362
399
  const todoStore = createTodoStore();
363
400
  const writeTodosTool = createWriteTodosTool(todoStore);
364
- const findDefinitionTool = createFindDefinitionTool();
365
- const getFileStructureTool = createGetFileStructureTool();
401
+ const findDefinitionTool = wrapTools([createFindDefinitionTool(additionalDirectories)], cliWrapDeps)[0];
402
+ const getFileStructureTool = wrapTools([createGetFileStructureTool(additionalDirectories)], cliWrapDeps)[0];
366
403
  const workItemTools = config.preferences.enableWorkItemTools ? createWorkItemTools(new WorkItemsClient(apiClient)) : [];
367
404
  const enableSkillTool = config.preferences.enableSkillTool !== false;
368
- const skillTool = enableSkillTool ? createSkillTool({
405
+ const skillTool = enableSkillTool ? wrapTools([createSkillTool({
369
406
  customCommandStore,
370
407
  subagentOrchestrator: orchestrator,
371
- sessionId: session.id
372
- }) : null;
408
+ sessionId: session.id,
409
+ permissionManager,
410
+ promptFn,
411
+ allowedDirectories: additionalDirectories
412
+ })], cliWrapDeps)[0] : null;
373
413
  const cliTools = [
374
414
  agentDelegateTool,
375
415
  ...backgroundTools,
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
3
- import { t as version } from "../package-OZdXqn0e.mjs";
2
+ import { t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
3
+ import { t as version } from "../package-Bqg2LSnH.mjs";
4
4
  //#region src/commands/mcpCommand.ts
5
5
  /**
6
6
  * External MCP commands (b4m mcp list, b4m mcp add, etc.)
@@ -70,7 +70,7 @@ async function handleMcpCommand(subcommand, argv) {
70
70
  await handleDisable(config, argv.name, configStore);
71
71
  break;
72
72
  case "serve": {
73
- const { handleMcpServeCommand } = await import("../serve-CEqSZwl6.mjs");
73
+ const { handleMcpServeCommand } = await import("../serve-DO9Edl5S.mjs");
74
74
  await handleMcpServeCommand({
75
75
  http: Boolean(argv.http),
76
76
  port: typeof argv.port === "number" ? argv.port : void 0,
@@ -146,9 +146,8 @@ async function handleAdd(config, name, command, args, configStore) {
146
146
  env: {},
147
147
  enabled: true
148
148
  };
149
- config.mcpServers.push(newServer);
150
149
  try {
151
- await configStore.save(config);
150
+ await configStore.addMcpServer(newServer);
152
151
  console.log(`✅ Added MCP server "${name}"`);
153
152
  console.log("");
154
153
  console.log("Configuration saved to: ~/.bike4mind/config.json");
@@ -163,14 +162,12 @@ async function handleAdd(config, name, command, args, configStore) {
163
162
  * Remove an MCP server
164
163
  */
165
164
  async function handleRemove(config, name, configStore) {
166
- const index = config.mcpServers.findIndex((s) => s.name === name);
167
- if (index === -1) {
165
+ if (config.mcpServers.findIndex((s) => s.name === name) === -1) {
168
166
  console.error(`❌ MCP server "${name}" not found.`);
169
167
  process.exit(1);
170
168
  }
171
- config.mcpServers.splice(index, 1);
172
169
  try {
173
- await configStore.save(config);
170
+ await configStore.removeMcpServer(name);
174
171
  console.log(`✅ Removed MCP server "${name}"`);
175
172
  console.log("");
176
173
  console.log("Configuration saved to: ~/.bike4mind/config.json");
@@ -192,9 +189,8 @@ async function handleEnable(config, name, configStore) {
192
189
  console.log(`ℹ️ MCP server "${name}" is already enabled.`);
193
190
  return;
194
191
  }
195
- server.enabled = true;
196
192
  try {
197
- await configStore.save(config);
193
+ await configStore.toggleMcpServer(name, true);
198
194
  console.log(`✅ Enabled MCP server "${name}"`);
199
195
  console.log("");
200
196
  console.log("The server will connect next time you start the CLI.");
@@ -216,9 +212,8 @@ async function handleDisable(config, name, configStore) {
216
212
  console.log(`ℹ️ MCP server "${name}" is already disabled.`);
217
213
  return;
218
214
  }
219
- server.enabled = false;
220
215
  try {
221
- await configStore.save(config);
216
+ await configStore.toggleMcpServer(name, false);
222
217
  console.log(`✅ Disabled MCP server "${name}"`);
223
218
  console.log("");
224
219
  console.log("The server will not connect next time you start the CLI.");
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { n as getDefaultPluginsDir, r as isFeatureEnabled, t as PluginStore } from "../PluginStore-DwvOJ-G3.mjs";
3
- import { t as ConfigStore } from "../ConfigStore-8_0WsN5r.mjs";
3
+ import { t as ConfigStore } from "../ConfigStore-DdHHCH2t.mjs";
4
4
  import { execFileSync } from "child_process";
5
5
  import { promises } from "fs";
6
6
  import path from "path";
@@ -152,13 +152,10 @@ async function handleAdd(spec, pluginsDir, configStore) {
152
152
  continue;
153
153
  }
154
154
  const config = await configStore.load();
155
- await configStore.save({
156
- ...config,
157
- features: {
158
- ...config.features,
159
- [descriptor.configKey]: true
160
- }
161
- });
155
+ await configStore.save({ features: {
156
+ ...config.features,
157
+ [descriptor.configKey]: true
158
+ } });
162
159
  console.log(`✅ Installed ${descriptor.name}@${descriptor.version} (plugin key: ${descriptor.configKey})`);
163
160
  console.log(`Enabled feature "${descriptor.configKey}". It will load next time you start b4m.`);
164
161
  }
@@ -186,13 +183,10 @@ async function handleRemove(name, pluginsDir, configStore) {
186
183
  ], pluginsDir, "remove", plugin.name);
187
184
  if (plugin.valid) {
188
185
  const config = await configStore.load();
189
- await configStore.save({
190
- ...config,
191
- features: {
192
- ...config.features,
193
- [plugin.configKey]: false
194
- }
195
- });
186
+ await configStore.save({ features: {
187
+ ...config.features,
188
+ [plugin.configKey]: false
189
+ } });
196
190
  }
197
191
  console.log(`✅ Removed plugin ${plugin.name}${plugin.valid ? ` and disabled "${plugin.configKey}"` : ""}.`);
198
192
  }
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { t as version } from "../package-OZdXqn0e.mjs";
2
+ import { t as version } from "../package-Bqg2LSnH.mjs";
3
3
  import { c as isNpmPrefixWritable, l as setAutoUpdatePreference, n as REEXEC_GUARD_ENV, o as forceCheckForUpdate, r as checkForUpdate, s as getAutoUpdatePreference, t as INSTALL_CMD, u as shouldAttemptAutoUpdate } from "../updateChecker-CQW8bxo6.mjs";
4
4
  import { t as checkRipgrep } from "../ripgrepCheck-BmkyTK2i.mjs";
5
5
  import { execSync, spawnSync } from "child_process";
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
- import { t as assertPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
2
+ import { t as assertPathAllowed } from "./pathValidation-BRqf4HFX-CHwtwp3O.mjs";
3
3
  import { existsSync, promises } from "fs";
4
4
  import path from "path";
5
- //#region ../../b4m-core/services/dist/createFile-DPv180yF.mjs
5
+ //#region ../../b4m-core/services/dist/createFile-B8bur5Rb.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-D8tjkQXE-1HwvsuYT.mjs";
2
+ import { t as assertPathAllowed } from "./pathValidation-BRqf4HFX-CHwtwp3O.mjs";
3
3
  import { existsSync, promises, statSync } from "fs";
4
4
  import path from "path";
5
- //#region ../../b4m-core/services/dist/deleteFile-BdjUwUQF.mjs
5
+ //#region ../../b4m-core/services/dist/deleteFile-9B3gW_Nb.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-D8tjkQXE-1HwvsuYT.mjs";
2
+ import { n as isPathAllowed } from "./pathValidation-BRqf4HFX-CHwtwp3O.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-DjfDGaUK.mjs
6
+ //#region ../../b4m-core/services/dist/globFiles-CwJ8qmYo.mjs
7
7
  const DEFAULT_IGNORE_PATTERNS = [
8
8
  "**/node_modules/**",
9
9
  "**/.git/**",
@@ -24,6 +24,7 @@ async function findFiles(params, allowedDirectories) {
24
24
  const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[baseCwd, ...allowedDirectories].join(", ")}` : `Working directory: ${baseCwd}`;
25
25
  throw new Error(`Access denied: Cannot search outside allowed directories. ${dirsMsg}`);
26
26
  }
27
+ if (path.isAbsolute(pattern) || pattern.split("/").includes("..")) throw new Error("Access denied: Cannot search outside allowed directories. The pattern must be relative to the search directory.");
27
28
  const matches = await glob(pattern, {
28
29
  cwd: targetDir,
29
30
  dot: false,
@@ -1,11 +1,11 @@
1
1
  #!/usr/bin/env node
2
- import { n as isPathAllowed } from "./pathValidation-D8tjkQXE-1HwvsuYT.mjs";
2
+ import { n as isPathAllowed } from "./pathValidation-BRqf4HFX-CHwtwp3O.mjs";
3
3
  import { execFile } from "child_process";
4
4
  import { existsSync } from "fs";
5
5
  import path from "path";
6
- import { stat } from "fs/promises";
7
6
  import { promisify } from "util";
8
- //#region ../../b4m-core/services/dist/grepSearch-BaYUfIYs.mjs
7
+ import { stat } from "fs/promises";
8
+ //#region ../../b4m-core/services/dist/grepSearch-BgoOOwGe.mjs
9
9
  const execFileAsync = promisify(execFile);
10
10
  /** Cached ripgrep binary path after first resolution */
11
11
  let cachedRgPath = null;
@@ -64,7 +64,7 @@ async function searchFiles(params, allowedDirectories) {
64
64
  if (globs.length > 0) globs.forEach((glob) => {
65
65
  rgArgs.push("--glob", glob);
66
66
  });
67
- rgArgs.push(pattern, targetDir);
67
+ rgArgs.push("--", pattern, targetDir);
68
68
  let stdout;
69
69
  try {
70
70
  stdout = (await execFileAsync(rgPath, rgArgs, { maxBuffer: 52428800 })).stdout;