@bike4mind/cli 0.2.60 → 0.2.61-feat-pi-intelligence-visibility.21705

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 (28) hide show
  1. package/dist/{artifactExtractor-YB2LOUUT.js → artifactExtractor-UI7MK2WJ.js} +1 -1
  2. package/dist/bashExecute-GLGLD3JD.js +379 -0
  3. package/dist/{chunk-I6CFAOBC.js → chunk-43D4HP62.js} +2 -2
  4. package/dist/{chunk-3BBKI54Z.js → chunk-BHX4ZDRS.js} +7 -7
  5. package/dist/{chunk-R5RVIU2Q.js → chunk-FIQZKJJW.js} +2 -2
  6. package/dist/{chunk-3YQJY7XO.js → chunk-HD2W2IIP.js} +20 -0
  7. package/dist/{chunk-WGZBP2RV.js → chunk-HIL7VU5N.js} +3558 -4406
  8. package/dist/chunk-LTLJRF6I.js +44 -0
  9. package/dist/{chunk-VFTGF46N.js → chunk-MRD767FA.js} +83 -10
  10. package/dist/{chunk-DSUZXGAO.js → chunk-Q4X33IU7.js} +2 -2
  11. package/dist/{chunk-E2GWB6BT.js → chunk-SLQS2YOB.js} +1 -1
  12. package/dist/commands/doctorCommand.js +1 -1
  13. package/dist/commands/headlessCommand.js +12 -11
  14. package/dist/commands/mcpCommand.js +2 -2
  15. package/dist/commands/updateCommand.js +1 -1
  16. package/dist/{create-PLDWPQDE.js → create-HVZTJCDH.js} +3 -3
  17. package/dist/createFile-6PSPLW6R.js +71 -0
  18. package/dist/deleteFile-AUSRLWIK.js +73 -0
  19. package/dist/globFiles-TSRN64N2.js +120 -0
  20. package/dist/grepSearch-634XWZOJ.js +216 -0
  21. package/dist/index.js +10 -9
  22. package/dist/{llmMarkdownGenerator-GJET3GJG.js → llmMarkdownGenerator-QT4CMIAP.js} +1 -1
  23. package/dist/{markdownGenerator-6RRUHY4M.js → markdownGenerator-VCEAQJ4R.js} +1 -1
  24. package/dist/{mementoService-NG5TZ6MH.js → mementoService-X6KHF3A5.js} +3 -3
  25. package/dist/{src-KFBFVZ7M.js → src-4SIKEV27.js} +3 -1
  26. package/dist/{src-72EECVVN.js → src-7M7IDZPJ.js} +2 -2
  27. package/dist/{subtractCredits-TVFMVBNC.js → subtractCredits-2VCKP4HK.js} +3 -3
  28. package/package.json +7 -7
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env node
2
+
3
+ // ../../b4m-core/packages/services/dist/src/llm/tools/utils/pathValidation.js
4
+ import path from "path";
5
+ import { realpathSync } from "fs";
6
+ function resolveRealPath(filePath) {
7
+ try {
8
+ return realpathSync(filePath);
9
+ } catch {
10
+ const parentDir = path.dirname(filePath);
11
+ const basename = path.basename(filePath);
12
+ if (parentDir === filePath) {
13
+ return filePath;
14
+ }
15
+ return path.join(resolveRealPath(parentDir), basename);
16
+ }
17
+ }
18
+ function isPathAllowed(filePath, allowedDirectories) {
19
+ const cwd = resolveRealPath(process.cwd());
20
+ const allAllowed = [cwd, ...(allowedDirectories || []).map((d) => resolveRealPath(d))];
21
+ const normalizedPath = path.normalize(filePath);
22
+ const logicalPath = path.isAbsolute(normalizedPath) ? normalizedPath : path.resolve(cwd, normalizedPath);
23
+ const resolvedPath = resolveRealPath(logicalPath);
24
+ for (const dir of allAllowed) {
25
+ if (resolvedPath === dir || resolvedPath.startsWith(dir + path.sep)) {
26
+ return { allowed: true, resolvedPath, matchedDirectory: dir };
27
+ }
28
+ }
29
+ return { allowed: false, resolvedPath };
30
+ }
31
+ function assertPathAllowed(filePath, allowedDirectories, operation = "access") {
32
+ const result = isPathAllowed(filePath, allowedDirectories);
33
+ if (!result.allowed) {
34
+ const cwd = process.cwd();
35
+ const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[cwd, ...allowedDirectories].join(", ")}` : `Working directory: ${cwd}`;
36
+ throw new Error(`Access denied: Cannot ${operation} files outside allowed directories. ${dirsMsg}`);
37
+ }
38
+ return result.resolvedPath;
39
+ }
40
+
41
+ export {
42
+ isPathAllowed,
43
+ assertPathAllowed
44
+ };
@@ -21,7 +21,7 @@ import {
21
21
  isGPTImageModel,
22
22
  isModelDeprecated,
23
23
  settingsMap
24
- } from "./chunk-3YQJY7XO.js";
24
+ } from "./chunk-HD2W2IIP.js";
25
25
 
26
26
  // ../../b4m-core/packages/utils/dist/src/storage/S3Storage.js
27
27
  import { S3Client, PutObjectCommand, DeleteObjectCommand, GetObjectCommand, HeadObjectCommand } from "@aws-sdk/client-s3";
@@ -6944,6 +6944,7 @@ var GPT5_MODELS = [
6944
6944
  ];
6945
6945
  var GPT5_1_MODELS = [ChatModels.GPT5_1, ChatModels.GPT5_1_CHAT_LATEST];
6946
6946
  var GPT5_2_MODELS = [ChatModels.GPT5_2, ChatModels.GPT5_2_CHAT_LATEST];
6947
+ var GPT5_4_MODELS = [ChatModels.GPT5_4, ChatModels.GPT5_4_MINI, ChatModels.GPT5_4_NANO];
6947
6948
  var effortMap = {
6948
6949
  simple: "low",
6949
6950
  contextual: "low",
@@ -7096,7 +7097,7 @@ var OpenAIBackend = class {
7096
7097
  logoFile: "OpenAI_Logo.svg",
7097
7098
  rank: 0,
7098
7099
  trainingCutoff: "2024-06-01",
7099
- description: "OpenAI's latest O-series model with enhanced reasoning capabilities and up-to-date training data through January 2025.",
7100
+ description: "OpenAI's O3 reasoning model with broad capabilities and up-to-date training data. Superseded by O4 Mini for most use cases.",
7100
7101
  isSlowModel: true
7101
7102
  },
7102
7103
  {
@@ -7186,6 +7187,73 @@ var OpenAIBackend = class {
7186
7187
  description: "OpenAI's compact reasoning model optimized for fast, cost-efficient performance with strong multimodal and agentic capabilities. Excellent for STEM tasks and coding.",
7187
7188
  isSlowModel: true
7188
7189
  },
7190
+ // GPT 5.4
7191
+ {
7192
+ id: ChatModels.GPT5_4,
7193
+ type: "text",
7194
+ name: "GPT-5.4",
7195
+ backend: ModelBackend.OpenAI,
7196
+ contextWindow: 105e4,
7197
+ max_tokens: 128e3,
7198
+ can_stream: true,
7199
+ can_think: false,
7200
+ pricing: {
7201
+ 4e5: { input: 2.5 / 1e6, output: 15 / 1e6 }
7202
+ // $2.50 / 1M Input tokens, $15.00 / 1M Output tokens
7203
+ },
7204
+ supportsVision: true,
7205
+ supportsImageVariation: false,
7206
+ supportsTools: true,
7207
+ logoFile: "OpenAI_Logo.svg",
7208
+ rank: 1,
7209
+ trainingCutoff: "2025-08-31",
7210
+ releaseDate: "2026-03-05",
7211
+ description: "OpenAI's latest and most capable GPT model. Flagship of the GPT-5 family with top-tier reasoning, creativity, and vision understanding."
7212
+ },
7213
+ {
7214
+ id: ChatModels.GPT5_4_MINI,
7215
+ type: "text",
7216
+ name: "GPT-5.4 Mini",
7217
+ backend: ModelBackend.OpenAI,
7218
+ contextWindow: 4e5,
7219
+ max_tokens: 128e3,
7220
+ can_stream: true,
7221
+ can_think: false,
7222
+ pricing: {
7223
+ 4e5: { input: 0.75 / 1e6, output: 4.5 / 1e6 }
7224
+ // $0.75 / 1M Input tokens, $4.50 / 1M Output tokens
7225
+ },
7226
+ supportsVision: true,
7227
+ supportsImageVariation: false,
7228
+ supportsTools: true,
7229
+ logoFile: "OpenAI_Logo.svg",
7230
+ rank: 1,
7231
+ trainingCutoff: "2025-08-31",
7232
+ releaseDate: "2026-03-17",
7233
+ description: "Compact GPT-5.4 variant balancing strong performance with lower cost. Great for everyday tasks needing solid reasoning and vision."
7234
+ },
7235
+ {
7236
+ id: ChatModels.GPT5_4_NANO,
7237
+ type: "text",
7238
+ name: "GPT-5.4 Nano",
7239
+ backend: ModelBackend.OpenAI,
7240
+ contextWindow: 4e5,
7241
+ max_tokens: 128e3,
7242
+ can_stream: true,
7243
+ can_think: false,
7244
+ pricing: {
7245
+ 4e5: { input: 0.2 / 1e6, output: 1.25 / 1e6 }
7246
+ // $0.20 / 1M Input tokens, $1.25 / 1M Output tokens
7247
+ },
7248
+ supportsVision: true,
7249
+ supportsImageVariation: false,
7250
+ supportsTools: true,
7251
+ logoFile: "OpenAI_Logo.svg",
7252
+ rank: 1,
7253
+ trainingCutoff: "2025-08-31",
7254
+ releaseDate: "2026-03-17",
7255
+ description: "Ultra-lightweight GPT-5.4 model optimized for speed and cost efficiency. Ideal for high-volume workloads and quick interactions."
7256
+ },
7189
7257
  // GPT 5.2
7190
7258
  {
7191
7259
  id: ChatModels.GPT5_2,
@@ -7198,7 +7266,7 @@ var OpenAIBackend = class {
7198
7266
  can_think: false,
7199
7267
  pricing: {
7200
7268
  4e5: { input: 1.75 / 1e6, output: 14 / 1e6 }
7201
- // $1.25 / 1M Input tokens, $10.00 / 1M Output tokens
7269
+ // $1.75 / 1M Input tokens, $14.00 / 1M Output tokens
7202
7270
  },
7203
7271
  supportsVision: true,
7204
7272
  supportsImageVariation: false,
@@ -7207,7 +7275,7 @@ var OpenAIBackend = class {
7207
7275
  rank: 1,
7208
7276
  trainingCutoff: "2025-08-31",
7209
7277
  releaseDate: "2025-12-12",
7210
- description: "OpenAI's latest GPT-5.2 model with enhanced reasoning, creativity, and multimodal capabilities. It's the latest model in the GPT-5 family.",
7278
+ description: "Previous-generation GPT-5 flagship with robust multimodal understanding and deep analytical capabilities.",
7211
7279
  isSlowModel: true
7212
7280
  },
7213
7281
  {
@@ -7253,7 +7321,7 @@ var OpenAIBackend = class {
7253
7321
  rank: 1,
7254
7322
  trainingCutoff: "2024-10-01",
7255
7323
  releaseDate: "2025-11-13",
7256
- description: "OpenAI's GPT-5.1 model with enhanced reasoning, creativity, and multimodal capabilities.",
7324
+ description: "Early GPT-5 series model with solid reasoning and vision support. Reliable for general-purpose tasks at competitive pricing.",
7257
7325
  isSlowModel: true
7258
7326
  },
7259
7327
  {
@@ -7588,20 +7656,22 @@ var OpenAIBackend = class {
7588
7656
  const isGPT5Model = GPT5_MODELS.includes(model);
7589
7657
  const isGPT5_1Model = GPT5_1_MODELS.includes(model);
7590
7658
  const isGPT5_2Model = GPT5_2_MODELS.includes(model);
7591
- const usesMaxCompletionTokens = isO1Model || isGPT5Model || isGPT5_1Model || isGPT5_2Model;
7659
+ const isGPT5_4Model = GPT5_4_MODELS.includes(model);
7660
+ const usesMaxCompletionTokens = isO1Model || isGPT5Model || isGPT5_1Model || isGPT5_2Model || isGPT5_4Model;
7592
7661
  const parameters = {
7593
7662
  model,
7594
7663
  messages: this.formatMessages(messages, isO1Model, model, options),
7595
7664
  temperature: options.temperature ?? 0.9
7596
7665
  };
7666
+ const supportsReasoning = REASONING_SUPPORTED_MODELS.has(model);
7597
7667
  if (usesMaxCompletionTokens) {
7598
7668
  Object.assign(parameters, {
7599
- temperature: 1,
7669
+ ...supportsReasoning && { temperature: 1 },
7600
7670
  stream: true,
7601
7671
  stream_options: { include_usage: true },
7602
7672
  ...options.maxTokens && { max_completion_tokens: options.maxTokens }
7603
7673
  });
7604
- if (REASONING_SUPPORTED_MODELS.has(model)) {
7674
+ if (supportsReasoning) {
7605
7675
  let reasoningEffort;
7606
7676
  if (options.reasoningEffort) {
7607
7677
  reasoningEffort = options.reasoningEffort;
@@ -7961,7 +8031,7 @@ var OpenAIBackend = class {
7961
8031
  formatMessages(messages, isO1Model, model, options) {
7962
8032
  const filteredMessages = isO1Model ? messages.filter((msg) => msg.role !== "system") : messages;
7963
8033
  const toolNames = options.tools?.map((tool) => tool.toolSchema.name) || [];
7964
- const isGPT5Family = GPT5_MODELS.includes(model) || GPT5_1_MODELS.includes(model) || GPT5_2_MODELS.includes(model);
8034
+ const isGPT5Family = GPT5_MODELS.includes(model) || GPT5_1_MODELS.includes(model) || GPT5_2_MODELS.includes(model) || GPT5_4_MODELS.includes(model);
7965
8035
  let systemContent;
7966
8036
  if (isGPT5Family) {
7967
8037
  systemContent = "You are a helpful assistant.";
@@ -10269,7 +10339,10 @@ var GPT5_MODELS_WITH_TOOL_SUPPORT = [
10269
10339
  ChatModels.GPT5_MINI,
10270
10340
  ChatModels.GPT5_NANO,
10271
10341
  ChatModels.GPT5_1,
10272
- ChatModels.GPT5_2
10342
+ ChatModels.GPT5_2,
10343
+ ChatModels.GPT5_4,
10344
+ ChatModels.GPT5_4_MINI,
10345
+ ChatModels.GPT5_4_NANO
10273
10346
  ];
10274
10347
  function isGPT5ModelWithToolSupport(model) {
10275
10348
  return GPT5_MODELS_WITH_TOOL_SUPPORT.includes(model);
@@ -6,12 +6,12 @@ import {
6
6
  getSettingsByNames,
7
7
  obfuscateApiKey,
8
8
  secureParameters
9
- } from "./chunk-VFTGF46N.js";
9
+ } from "./chunk-MRD767FA.js";
10
10
  import {
11
11
  ApiKeyType,
12
12
  MementoTier,
13
13
  isSupportedEmbeddingModel
14
- } from "./chunk-3YQJY7XO.js";
14
+ } from "./chunk-HD2W2IIP.js";
15
15
 
16
16
  // ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
17
17
  import { z } from "zod";
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ChatModels
4
- } from "./chunk-3YQJY7XO.js";
4
+ } from "./chunk-HD2W2IIP.js";
5
5
  import {
6
6
  DEFAULT_SANDBOX_CONFIG
7
7
  } from "./chunk-4BIBE3J7.js";
@@ -3,7 +3,7 @@ import {
3
3
  fetchLatestVersion,
4
4
  forceCheckForUpdate,
5
5
  package_default
6
- } from "../chunk-3BBKI54Z.js";
6
+ } from "../chunk-BHX4ZDRS.js";
7
7
 
8
8
  // src/commands/doctorCommand.ts
9
9
  import { execSync } from "child_process";
@@ -1,13 +1,13 @@
1
1
  #!/usr/bin/env node
2
+ import {
3
+ createSandboxRuntime
4
+ } from "../chunk-QWB6ZYY4.js";
2
5
  import {
3
6
  SandboxOrchestrator
4
7
  } from "../chunk-KQAMBXAW.js";
5
8
  import {
6
9
  ProxyManager
7
10
  } from "../chunk-G4ZGEQFT.js";
8
- import {
9
- createSandboxRuntime
10
- } from "../chunk-QWB6ZYY4.js";
11
11
  import {
12
12
  AgentStore,
13
13
  ApiClient,
@@ -36,20 +36,21 @@ import {
36
36
  isReadOnlyTool,
37
37
  loadContextFiles,
38
38
  setWebSocketToolExecutor
39
- } from "../chunk-WGZBP2RV.js";
39
+ } from "../chunk-HIL7VU5N.js";
40
40
  import "../chunk-BDQBOLYG.js";
41
- import "../chunk-DSUZXGAO.js";
41
+ import "../chunk-Q4X33IU7.js";
42
42
  import "../chunk-GQGOWACU.js";
43
- import "../chunk-R5RVIU2Q.js";
44
- import "../chunk-I6CFAOBC.js";
45
- import "../chunk-VFTGF46N.js";
43
+ import "../chunk-LTLJRF6I.js";
44
+ import "../chunk-FIQZKJJW.js";
45
+ import "../chunk-43D4HP62.js";
46
+ import "../chunk-MRD767FA.js";
46
47
  import "../chunk-PFBYGCOW.js";
47
48
  import "../chunk-BPFEGDC7.js";
48
49
  import {
49
50
  ConfigStore,
50
51
  logger
51
- } from "../chunk-E2GWB6BT.js";
52
- import "../chunk-3YQJY7XO.js";
52
+ } from "../chunk-SLQS2YOB.js";
53
+ import "../chunk-HD2W2IIP.js";
53
54
  import {
54
55
  DEFAULT_SANDBOX_CONFIG
55
56
  } from "../chunk-4BIBE3J7.js";
@@ -196,7 +197,7 @@ ${stdinContent}
196
197
  currentAgent: null,
197
198
  observationQueue: []
198
199
  };
199
- const { tools: b4mTools } = generateCliTools(
200
+ const { tools: b4mTools } = await generateCliTools(
200
201
  config.userId,
201
202
  llm,
202
203
  modelInfo.id,
@@ -1,8 +1,8 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  ConfigStore
4
- } from "../chunk-E2GWB6BT.js";
5
- import "../chunk-3YQJY7XO.js";
4
+ } from "../chunk-SLQS2YOB.js";
5
+ import "../chunk-HD2W2IIP.js";
6
6
  import "../chunk-4BIBE3J7.js";
7
7
 
8
8
  // src/commands/mcpCommand.ts
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  forceCheckForUpdate,
4
4
  package_default
5
- } from "../chunk-3BBKI54Z.js";
5
+ } from "../chunk-BHX4ZDRS.js";
6
6
 
7
7
  // src/commands/updateCommand.ts
8
8
  import { execSync } from "child_process";
@@ -2,10 +2,10 @@
2
2
  import {
3
3
  createFabFile,
4
4
  createFabFileSchema
5
- } from "./chunk-I6CFAOBC.js";
6
- import "./chunk-VFTGF46N.js";
5
+ } from "./chunk-43D4HP62.js";
6
+ import "./chunk-MRD767FA.js";
7
7
  import "./chunk-PFBYGCOW.js";
8
- import "./chunk-3YQJY7XO.js";
8
+ import "./chunk-HD2W2IIP.js";
9
9
  export {
10
10
  createFabFile,
11
11
  createFabFileSchema
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ assertPathAllowed
4
+ } from "./chunk-LTLJRF6I.js";
5
+
6
+ // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
7
+ import { promises as fs } from "fs";
8
+ import { existsSync } from "fs";
9
+ import path from "path";
10
+ async function createFile(params, allowedDirectories) {
11
+ const { path: filePath, content, createDirectories = true } = params;
12
+ const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "create");
13
+ const fileExists = existsSync(resolvedPath);
14
+ const action = fileExists ? "overwritten" : "created";
15
+ if (createDirectories) {
16
+ const dir = path.dirname(resolvedPath);
17
+ await fs.mkdir(dir, { recursive: true });
18
+ }
19
+ await fs.writeFile(resolvedPath, content, "utf-8");
20
+ const stats = await fs.stat(resolvedPath);
21
+ const lines = content.split("\n").length;
22
+ return `File ${action} successfully: ${filePath}
23
+ Size: ${stats.size} bytes
24
+ Lines: ${lines}`;
25
+ }
26
+ var createFileTool = {
27
+ name: "create_file",
28
+ implementation: (context) => ({
29
+ toolFn: async (value) => {
30
+ const params = value;
31
+ const fileExists = existsSync(path.resolve(process.cwd(), path.normalize(params.path)));
32
+ context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
33
+ path: params.path,
34
+ size: params.content.length
35
+ });
36
+ try {
37
+ const result = await createFile(params, context.allowedDirectories);
38
+ context.logger.info("\u2705 CreateFile: Success", { path: params.path });
39
+ return result;
40
+ } catch (error) {
41
+ context.logger.error("\u274C CreateFile: Failed", error);
42
+ throw error;
43
+ }
44
+ },
45
+ toolSchema: {
46
+ name: "create_file",
47
+ description: "Create a new file or overwrite an existing file with the provided content. Will create parent directories if they do not exist. Restricted to current working directory for security. Always prompts user for confirmation before writing.",
48
+ parameters: {
49
+ type: "object",
50
+ properties: {
51
+ path: {
52
+ type: "string",
53
+ description: "Path where the file should be created (relative to current working directory)"
54
+ },
55
+ content: {
56
+ type: "string",
57
+ description: "Content to write to the file"
58
+ },
59
+ createDirectories: {
60
+ type: "boolean",
61
+ description: "Create parent directories if they do not exist (default: true)"
62
+ }
63
+ },
64
+ required: ["path", "content"]
65
+ }
66
+ }
67
+ })
68
+ };
69
+ export {
70
+ createFileTool
71
+ };
@@ -0,0 +1,73 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ assertPathAllowed
4
+ } from "./chunk-LTLJRF6I.js";
5
+
6
+ // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
7
+ import { promises as fs } from "fs";
8
+ import { existsSync, statSync } from "fs";
9
+ import path from "path";
10
+ async function deleteFile(params, allowedDirectories) {
11
+ const { path: filePath, recursive = false } = params;
12
+ const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "delete");
13
+ if (!existsSync(resolvedPath)) {
14
+ throw new Error(`File or directory not found: ${filePath}`);
15
+ }
16
+ const stats = statSync(resolvedPath);
17
+ const isDirectory = stats.isDirectory();
18
+ const size = stats.size;
19
+ if (isDirectory && !recursive) {
20
+ throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
21
+ }
22
+ if (isDirectory) {
23
+ await fs.rm(resolvedPath, { recursive: true, force: true });
24
+ return `Directory deleted successfully: ${filePath}`;
25
+ } else {
26
+ await fs.unlink(resolvedPath);
27
+ return `File deleted successfully: ${filePath}
28
+ Size: ${size} bytes`;
29
+ }
30
+ }
31
+ var deleteFileTool = {
32
+ name: "delete_file",
33
+ implementation: (context) => ({
34
+ toolFn: async (value) => {
35
+ const params = value;
36
+ const resolvedPath = path.resolve(process.cwd(), path.normalize(params.path));
37
+ const isDirectory = existsSync(resolvedPath) && statSync(resolvedPath).isDirectory();
38
+ context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
39
+ path: params.path,
40
+ recursive: params.recursive
41
+ });
42
+ try {
43
+ const result = await deleteFile(params, context.allowedDirectories);
44
+ context.logger.info("\u2705 DeleteFile: Success", { path: params.path });
45
+ return result;
46
+ } catch (error) {
47
+ context.logger.error("\u274C DeleteFile: Failed", error);
48
+ throw error;
49
+ }
50
+ },
51
+ toolSchema: {
52
+ name: "delete_file",
53
+ description: "Delete a file or directory. For directories, recursive option must be enabled. Restricted to current working directory for security. Always prompts user for confirmation before deletion.",
54
+ parameters: {
55
+ type: "object",
56
+ properties: {
57
+ path: {
58
+ type: "string",
59
+ description: "Path to the file or directory to delete (relative to current working directory)"
60
+ },
61
+ recursive: {
62
+ type: "boolean",
63
+ description: "Required to delete directories and their contents (default: false). Use with caution as this will delete all files and subdirectories."
64
+ }
65
+ },
66
+ required: ["path"]
67
+ }
68
+ }
69
+ })
70
+ };
71
+ export {
72
+ deleteFileTool
73
+ };
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ isPathAllowed
4
+ } from "./chunk-LTLJRF6I.js";
5
+
6
+ // ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
7
+ import { glob } from "glob";
8
+ import { stat } from "fs/promises";
9
+ import path from "path";
10
+ var DEFAULT_IGNORE_PATTERNS = [
11
+ "**/node_modules/**",
12
+ "**/.git/**",
13
+ "**/dist/**",
14
+ "**/build/**",
15
+ "**/.next/**",
16
+ "**/coverage/**",
17
+ "**/.turbo/**",
18
+ "**/.sst/**",
19
+ "**/*.min.js",
20
+ "**/*.min.css"
21
+ ];
22
+ async function findFiles(params, allowedDirectories) {
23
+ const { pattern, dir_path, case_sensitive = true, respect_git_ignore = true } = params;
24
+ const baseCwd = process.cwd();
25
+ const targetDir = dir_path ? path.resolve(baseCwd, path.normalize(dir_path)) : baseCwd;
26
+ const validation = isPathAllowed(targetDir, allowedDirectories);
27
+ if (!validation.allowed) {
28
+ const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[baseCwd, ...allowedDirectories].join(", ")}` : `Working directory: ${baseCwd}`;
29
+ throw new Error(`Access denied: Cannot search outside allowed directories. ${dirsMsg}`);
30
+ }
31
+ const ignorePatterns = respect_git_ignore ? DEFAULT_IGNORE_PATTERNS : [];
32
+ const matches = await glob(pattern, {
33
+ cwd: targetDir,
34
+ dot: false,
35
+ // Don't match hidden files by default
36
+ ignore: ignorePatterns,
37
+ absolute: true,
38
+ nodir: true,
39
+ // Only return files, not directories
40
+ nocase: !case_sensitive,
41
+ // Case-insensitive if requested
42
+ maxDepth: 20
43
+ // Reasonable depth limit
44
+ });
45
+ if (matches.length === 0) {
46
+ return `No files found matching pattern: ${pattern}${dir_path ? ` in ${dir_path}` : ""}`;
47
+ }
48
+ const filesWithStats = [];
49
+ for (const filePath of matches) {
50
+ try {
51
+ const stats = await stat(filePath);
52
+ filesWithStats.push({
53
+ path: filePath,
54
+ mtime: stats.mtimeMs
55
+ });
56
+ } catch {
57
+ continue;
58
+ }
59
+ }
60
+ filesWithStats.sort((a, b) => b.mtime - a.mtime);
61
+ const MAX_RESULTS = 500;
62
+ const truncated = filesWithStats.length > MAX_RESULTS;
63
+ const results = truncated ? filesWithStats.slice(0, MAX_RESULTS) : filesWithStats;
64
+ const summary = `Found ${filesWithStats.length} file(s)${truncated ? ` (showing first ${MAX_RESULTS})` : ""} matching: ${pattern}`;
65
+ const dirInfo = dir_path ? `
66
+ Directory: ${dir_path}` : "";
67
+ const filesList = results.map((file) => path.relative(baseCwd, file.path)).join("\n");
68
+ return `${summary}${dirInfo}
69
+
70
+ ${filesList}`;
71
+ }
72
+ var globFilesTool = {
73
+ name: "glob_files",
74
+ implementation: (context) => ({
75
+ toolFn: async (value) => {
76
+ const params = value;
77
+ context.logger.info("\u{1F50D} GlobFiles: Finding files", {
78
+ pattern: params.pattern,
79
+ dir_path: params.dir_path || "."
80
+ });
81
+ try {
82
+ const result = await findFiles(params, context.allowedDirectories);
83
+ context.logger.info("\u2705 GlobFiles: Success");
84
+ return result;
85
+ } catch (error) {
86
+ context.logger.error("\u274C GlobFiles: Failed", error);
87
+ throw error;
88
+ }
89
+ },
90
+ toolSchema: {
91
+ name: "glob_files",
92
+ description: "Efficiently finds files matching specific glob patterns (e.g., `src/**/*.ts`, `**/*.md`), returning absolute paths sorted by modification time (newest first). Use this to locate files by name or extension when you need to discover or explore files in a project.",
93
+ parameters: {
94
+ type: "object",
95
+ properties: {
96
+ pattern: {
97
+ type: "string",
98
+ description: 'The glob pattern to match against file paths. Supports wildcards (*, **), character ranges ([abc]), and brace expansion ({ts,tsx}). Examples: "*.ts" for TypeScript files in current dir, "src/**/*.tsx" for all TSX files in src tree, "**/*.{js,ts}" for all JS/TS files.'
99
+ },
100
+ dir_path: {
101
+ type: "string",
102
+ description: "Optional: The absolute path to the directory to search in. If not specified, uses the current working directory. Must be within the current working directory."
103
+ },
104
+ case_sensitive: {
105
+ type: "boolean",
106
+ description: "Optional: Whether the pattern matching should be case-sensitive. Defaults to true. Set to false for case-insensitive matching on case-sensitive file systems."
107
+ },
108
+ respect_git_ignore: {
109
+ type: "boolean",
110
+ description: "Optional: Whether to respect common ignore patterns (node_modules, .git, dist, build, etc.). Defaults to true. Set to false to include all files."
111
+ }
112
+ },
113
+ required: ["pattern"]
114
+ }
115
+ }
116
+ })
117
+ };
118
+ export {
119
+ globFilesTool
120
+ };