@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.
- package/dist/{artifactExtractor-YB2LOUUT.js → artifactExtractor-UI7MK2WJ.js} +1 -1
- package/dist/bashExecute-GLGLD3JD.js +379 -0
- package/dist/{chunk-I6CFAOBC.js → chunk-43D4HP62.js} +2 -2
- package/dist/{chunk-3BBKI54Z.js → chunk-BHX4ZDRS.js} +7 -7
- package/dist/{chunk-R5RVIU2Q.js → chunk-FIQZKJJW.js} +2 -2
- package/dist/{chunk-3YQJY7XO.js → chunk-HD2W2IIP.js} +20 -0
- package/dist/{chunk-WGZBP2RV.js → chunk-HIL7VU5N.js} +3558 -4406
- package/dist/chunk-LTLJRF6I.js +44 -0
- package/dist/{chunk-VFTGF46N.js → chunk-MRD767FA.js} +83 -10
- package/dist/{chunk-DSUZXGAO.js → chunk-Q4X33IU7.js} +2 -2
- package/dist/{chunk-E2GWB6BT.js → chunk-SLQS2YOB.js} +1 -1
- package/dist/commands/doctorCommand.js +1 -1
- package/dist/commands/headlessCommand.js +12 -11
- package/dist/commands/mcpCommand.js +2 -2
- package/dist/commands/updateCommand.js +1 -1
- package/dist/{create-PLDWPQDE.js → create-HVZTJCDH.js} +3 -3
- package/dist/createFile-6PSPLW6R.js +71 -0
- package/dist/deleteFile-AUSRLWIK.js +73 -0
- package/dist/globFiles-TSRN64N2.js +120 -0
- package/dist/grepSearch-634XWZOJ.js +216 -0
- package/dist/index.js +10 -9
- package/dist/{llmMarkdownGenerator-GJET3GJG.js → llmMarkdownGenerator-QT4CMIAP.js} +1 -1
- package/dist/{markdownGenerator-6RRUHY4M.js → markdownGenerator-VCEAQJ4R.js} +1 -1
- package/dist/{mementoService-NG5TZ6MH.js → mementoService-X6KHF3A5.js} +3 -3
- package/dist/{src-KFBFVZ7M.js → src-4SIKEV27.js} +3 -1
- package/dist/{src-72EECVVN.js → src-7M7IDZPJ.js} +2 -2
- package/dist/{subtractCredits-TVFMVBNC.js → subtractCredits-2VCKP4HK.js} +3 -3
- 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-
|
|
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
|
|
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.
|
|
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: "
|
|
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: "
|
|
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
|
|
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 (
|
|
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-
|
|
9
|
+
} from "./chunk-MRD767FA.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
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,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-
|
|
39
|
+
} from "../chunk-HIL7VU5N.js";
|
|
40
40
|
import "../chunk-BDQBOLYG.js";
|
|
41
|
-
import "../chunk-
|
|
41
|
+
import "../chunk-Q4X33IU7.js";
|
|
42
42
|
import "../chunk-GQGOWACU.js";
|
|
43
|
-
import "../chunk-
|
|
44
|
-
import "../chunk-
|
|
45
|
-
import "../chunk-
|
|
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-
|
|
52
|
-
import "../chunk-
|
|
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,
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-43D4HP62.js";
|
|
6
|
+
import "./chunk-MRD767FA.js";
|
|
7
7
|
import "./chunk-PFBYGCOW.js";
|
|
8
|
-
import "./chunk-
|
|
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
|
+
};
|