@bike4mind/cli 0.2.34 → 0.2.35-fix-reply-disappears-on-refresh.20009
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/bin/bike4mind-cli.mjs +11 -0
- package/dist/{chunk-RGWBOKBB.js → chunk-552ZZZ6B.js} +6 -6
- package/dist/{chunk-ZFVDH4DU.js → chunk-PXLQHH5U.js} +54 -3
- package/dist/commands/doctorCommand.js +1 -1
- package/dist/commands/mcpCommand.js +1 -1
- package/dist/commands/updateCommand.js +1 -1
- package/dist/index.js +279 -116
- package/package.json +6 -6
package/bin/bike4mind-cli.mjs
CHANGED
|
@@ -46,6 +46,11 @@ const argv = await yargs(hideBin(process.argv))
|
|
|
46
46
|
description: 'Disable loading project-specific configuration (.bike4mind/)',
|
|
47
47
|
default: false,
|
|
48
48
|
})
|
|
49
|
+
.option('add-dir', {
|
|
50
|
+
type: 'array',
|
|
51
|
+
description: 'Add additional directories for file access (can be used multiple times)',
|
|
52
|
+
string: true,
|
|
53
|
+
})
|
|
49
54
|
.command('mcp', 'Manage MCP (Model Context Protocol) servers', (yargs) => {
|
|
50
55
|
return yargs
|
|
51
56
|
.command('list', 'List configured MCP servers', {}, async () => {
|
|
@@ -109,6 +114,12 @@ if (argv['debug-stream']) {
|
|
|
109
114
|
if (argv['no-project-config']) {
|
|
110
115
|
process.env.B4M_NO_PROJECT_CONFIG = '1';
|
|
111
116
|
}
|
|
117
|
+
if (argv['add-dir'] && argv['add-dir'].length > 0) {
|
|
118
|
+
// Resolve paths to absolute and pass via environment variable
|
|
119
|
+
const { resolve } = await import('path');
|
|
120
|
+
const resolvedDirs = argv['add-dir'].map(d => resolve(d));
|
|
121
|
+
process.env.B4M_ADDITIONAL_DIRS = JSON.stringify(resolvedDirs);
|
|
122
|
+
}
|
|
112
123
|
|
|
113
124
|
// Auto-detect environment: prefer production mode when dist exists
|
|
114
125
|
const distPath = join(__dirname, '../dist/index.js');
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
// package.json
|
|
4
4
|
var package_default = {
|
|
5
5
|
name: "@bike4mind/cli",
|
|
6
|
-
version: "0.2.
|
|
6
|
+
version: "0.2.35-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
7
7
|
type: "module",
|
|
8
8
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
9
9
|
license: "UNLICENSED",
|
|
@@ -114,10 +114,10 @@ var package_default = {
|
|
|
114
114
|
},
|
|
115
115
|
devDependencies: {
|
|
116
116
|
"@bike4mind/agents": "0.1.0",
|
|
117
|
-
"@bike4mind/common": "2.56.
|
|
118
|
-
"@bike4mind/mcp": "1.32.
|
|
119
|
-
"@bike4mind/services": "2.53.
|
|
120
|
-
"@bike4mind/utils": "2.9.
|
|
117
|
+
"@bike4mind/common": "2.56.1-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
118
|
+
"@bike4mind/mcp": "1.32.4-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
119
|
+
"@bike4mind/services": "2.53.1-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
120
|
+
"@bike4mind/utils": "2.9.2-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
121
121
|
"@types/better-sqlite3": "^7.6.13",
|
|
122
122
|
"@types/diff": "^5.0.9",
|
|
123
123
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -138,7 +138,7 @@ var package_default = {
|
|
|
138
138
|
optionalDependencies: {
|
|
139
139
|
"@vscode/ripgrep": "^1.17.0"
|
|
140
140
|
},
|
|
141
|
-
gitHead: "
|
|
141
|
+
gitHead: "3d2fae3ac3f2b2cd7d12279e4f610b073002b96d"
|
|
142
142
|
};
|
|
143
143
|
|
|
144
144
|
// src/utils/updateChecker.ts
|
|
@@ -398,7 +398,8 @@ var CliConfigSchema = z.object({
|
|
|
398
398
|
config: z.record(z.string(), z.any())
|
|
399
399
|
}),
|
|
400
400
|
trustedTools: z.array(z.string()).optional().prefault([]),
|
|
401
|
-
sandbox: SandboxConfigSchema.optional()
|
|
401
|
+
sandbox: SandboxConfigSchema.optional(),
|
|
402
|
+
additionalDirectories: z.array(z.string()).optional().prefault([])
|
|
402
403
|
});
|
|
403
404
|
var ProjectConfigSchema = z.object({
|
|
404
405
|
tools: z.object({
|
|
@@ -418,7 +419,8 @@ var ProjectConfigSchema = z.object({
|
|
|
418
419
|
enableSkillTool: z.boolean().optional(),
|
|
419
420
|
enableDynamicAgentCreation: z.boolean().optional()
|
|
420
421
|
}).optional(),
|
|
421
|
-
sandbox: PartialSandboxConfigSchema
|
|
422
|
+
sandbox: PartialSandboxConfigSchema,
|
|
423
|
+
additionalDirectories: z.array(z.string()).optional()
|
|
422
424
|
});
|
|
423
425
|
var ProjectLocalConfigSchema = z.object({
|
|
424
426
|
trustedTools: z.array(z.string()).optional(),
|
|
@@ -465,8 +467,10 @@ var DEFAULT_CONFIG = {
|
|
|
465
467
|
// Web-only tools
|
|
466
468
|
config: {}
|
|
467
469
|
},
|
|
468
|
-
trustedTools: []
|
|
470
|
+
trustedTools: [],
|
|
469
471
|
// No tools trusted by default
|
|
472
|
+
additionalDirectories: []
|
|
473
|
+
// No additional directories by default
|
|
470
474
|
};
|
|
471
475
|
function findProjectConfigDir(startDir = process.cwd()) {
|
|
472
476
|
let currentDir = startDir;
|
|
@@ -1017,6 +1021,53 @@ ${entryToAdd}
|
|
|
1017
1021
|
}
|
|
1018
1022
|
return loadProjectLocalConfig(this.projectConfigDir);
|
|
1019
1023
|
}
|
|
1024
|
+
/**
|
|
1025
|
+
* Add a directory to the allowed directories list
|
|
1026
|
+
* Persists to global config
|
|
1027
|
+
*/
|
|
1028
|
+
async addDirectory(dirPath) {
|
|
1029
|
+
const config = await this.load();
|
|
1030
|
+
if (!config.additionalDirectories) {
|
|
1031
|
+
config.additionalDirectories = [];
|
|
1032
|
+
}
|
|
1033
|
+
const resolvedPath = path2.resolve(dirPath);
|
|
1034
|
+
if (!config.additionalDirectories.includes(resolvedPath)) {
|
|
1035
|
+
config.additionalDirectories.push(resolvedPath);
|
|
1036
|
+
await this.save(config);
|
|
1037
|
+
}
|
|
1038
|
+
}
|
|
1039
|
+
/**
|
|
1040
|
+
* Remove a directory from the allowed directories list
|
|
1041
|
+
*/
|
|
1042
|
+
async removeDirectory(dirPath) {
|
|
1043
|
+
const config = await this.load();
|
|
1044
|
+
if (config.additionalDirectories) {
|
|
1045
|
+
const resolvedPath = path2.resolve(dirPath);
|
|
1046
|
+
config.additionalDirectories = config.additionalDirectories.filter((d) => path2.resolve(d) !== resolvedPath);
|
|
1047
|
+
await this.save(config);
|
|
1048
|
+
}
|
|
1049
|
+
}
|
|
1050
|
+
/**
|
|
1051
|
+
* Get all additional directories (merged from global + project configs)
|
|
1052
|
+
* Returns resolved absolute paths
|
|
1053
|
+
*/
|
|
1054
|
+
async getAdditionalDirectories() {
|
|
1055
|
+
const config = await this.load();
|
|
1056
|
+
const dirs = /* @__PURE__ */ new Set();
|
|
1057
|
+
if (config.additionalDirectories) {
|
|
1058
|
+
for (const dir of config.additionalDirectories) {
|
|
1059
|
+
dirs.add(path2.resolve(dir));
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
const projectConfig = await this.loadRawProjectConfig();
|
|
1063
|
+
if (projectConfig?.additionalDirectories) {
|
|
1064
|
+
const projectRoot = this.projectConfigDir || process.cwd();
|
|
1065
|
+
for (const dir of projectConfig.additionalDirectories) {
|
|
1066
|
+
dirs.add(path2.resolve(projectRoot, dir));
|
|
1067
|
+
}
|
|
1068
|
+
}
|
|
1069
|
+
return Array.from(dirs);
|
|
1070
|
+
}
|
|
1020
1071
|
};
|
|
1021
1072
|
|
|
1022
1073
|
export {
|
package/dist/index.js
CHANGED
|
@@ -25,11 +25,11 @@ import "./chunk-BDQBOLYG.js";
|
|
|
25
25
|
import {
|
|
26
26
|
ConfigStore,
|
|
27
27
|
logger
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-PXLQHH5U.js";
|
|
29
29
|
import {
|
|
30
30
|
checkForUpdate,
|
|
31
31
|
package_default
|
|
32
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-552ZZZ6B.js";
|
|
33
33
|
import {
|
|
34
34
|
selectActiveBackgroundAgents,
|
|
35
35
|
useCliStore
|
|
@@ -102,6 +102,9 @@ import React22, { useState as useState11, useEffect as useEffect7, useCallback a
|
|
|
102
102
|
import { render, Box as Box21, Text as Text21, useApp, useInput as useInput10 } from "ink";
|
|
103
103
|
import { execSync } from "child_process";
|
|
104
104
|
import { randomBytes as randomBytes5 } from "crypto";
|
|
105
|
+
import { existsSync as existsSync13, promises as fs15 } from "fs";
|
|
106
|
+
import { homedir as homedir4 } from "os";
|
|
107
|
+
import path20 from "path";
|
|
105
108
|
import { v4 as uuidv413 } from "uuid";
|
|
106
109
|
|
|
107
110
|
// src/components/App.tsx
|
|
@@ -835,6 +838,20 @@ var COMMANDS = [
|
|
|
835
838
|
{
|
|
836
839
|
name: "sandbox:violations:clear",
|
|
837
840
|
description: "Clear all recorded sandbox violations"
|
|
841
|
+
},
|
|
842
|
+
{
|
|
843
|
+
name: "add-dir",
|
|
844
|
+
description: "Add a directory for file access",
|
|
845
|
+
args: "<path>"
|
|
846
|
+
},
|
|
847
|
+
{
|
|
848
|
+
name: "remove-dir",
|
|
849
|
+
description: "Remove a directory from file access",
|
|
850
|
+
args: "<path>"
|
|
851
|
+
},
|
|
852
|
+
{
|
|
853
|
+
name: "dirs",
|
|
854
|
+
description: "List all accessible directories"
|
|
838
855
|
}
|
|
839
856
|
];
|
|
840
857
|
function getAllCommandNames() {
|
|
@@ -2626,6 +2643,7 @@ import { Box as Box20, Text as Text20 } from "ink";
|
|
|
2626
2643
|
import Spinner3 from "ink-spinner";
|
|
2627
2644
|
import jwt from "jsonwebtoken";
|
|
2628
2645
|
import open from "open";
|
|
2646
|
+
import axios2 from "axios";
|
|
2629
2647
|
|
|
2630
2648
|
// src/auth/OAuthClient.ts
|
|
2631
2649
|
import axios from "axios";
|
|
@@ -2737,6 +2755,33 @@ var OAuthClient = class {
|
|
|
2737
2755
|
};
|
|
2738
2756
|
|
|
2739
2757
|
// src/components/LoginFlow.tsx
|
|
2758
|
+
function extractErrorMessage(err) {
|
|
2759
|
+
if (axios2.isAxiosError(err)) {
|
|
2760
|
+
if (err.response?.data) {
|
|
2761
|
+
const data = err.response.data;
|
|
2762
|
+
const serverMsg = data.error_description || data.error || data.message;
|
|
2763
|
+
if (serverMsg) {
|
|
2764
|
+
return `${serverMsg} (HTTP ${err.response.status})`;
|
|
2765
|
+
}
|
|
2766
|
+
return `Server returned HTTP ${err.response.status}`;
|
|
2767
|
+
}
|
|
2768
|
+
if (err.code === "ECONNREFUSED") {
|
|
2769
|
+
const url = err.config?.baseURL || "server";
|
|
2770
|
+
return `Could not connect to ${url} - is the server running?`;
|
|
2771
|
+
}
|
|
2772
|
+
if (err.code === "ENOTFOUND") {
|
|
2773
|
+
return `Could not resolve hostname: ${err.config?.baseURL || "unknown"}`;
|
|
2774
|
+
}
|
|
2775
|
+
if (err.code === "ETIMEDOUT" || err.code === "ECONNABORTED") {
|
|
2776
|
+
return "Connection timed out - server may be unreachable";
|
|
2777
|
+
}
|
|
2778
|
+
return err.message || `Network error (${err.code || "unknown"})`;
|
|
2779
|
+
}
|
|
2780
|
+
if (err instanceof Error) {
|
|
2781
|
+
return err.message || "Unknown error occurred";
|
|
2782
|
+
}
|
|
2783
|
+
return "Unknown error occurred";
|
|
2784
|
+
}
|
|
2740
2785
|
function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, onError }) {
|
|
2741
2786
|
const [status, setStatus] = useState10("initiating");
|
|
2742
2787
|
const [deviceFlow, setDeviceFlow] = useState10(null);
|
|
@@ -2770,9 +2815,9 @@ function LoginFlow({ apiUrl = "http://localhost:3000", configStore, onSuccess, o
|
|
|
2770
2815
|
setTimeout(() => onSuccess(), 1500);
|
|
2771
2816
|
} catch (err) {
|
|
2772
2817
|
setStatus("error");
|
|
2773
|
-
const errorMessage = err
|
|
2818
|
+
const errorMessage = extractErrorMessage(err);
|
|
2774
2819
|
setError(errorMessage);
|
|
2775
|
-
onError(
|
|
2820
|
+
onError(new Error(errorMessage));
|
|
2776
2821
|
}
|
|
2777
2822
|
};
|
|
2778
2823
|
runLoginFlow();
|
|
@@ -4435,6 +4480,7 @@ function buildCoreSystemPrompt(contextSection, config) {
|
|
|
4435
4480
|
let agentDirectoryContext = "";
|
|
4436
4481
|
let skillsSection = "";
|
|
4437
4482
|
let dynamicAgentSection = "";
|
|
4483
|
+
let directoriesSection = "";
|
|
4438
4484
|
if (typeof contextSection === "string") {
|
|
4439
4485
|
projectContextSection = contextSection;
|
|
4440
4486
|
if (config) {
|
|
@@ -4468,6 +4514,21 @@ ${config.contextContent}`;
|
|
|
4468
4514
|
if (config.enableDynamicAgentCreation) {
|
|
4469
4515
|
dynamicAgentSection = buildDynamicAgentPromptSection();
|
|
4470
4516
|
}
|
|
4517
|
+
if (config.additionalDirectories && config.additionalDirectories.length > 0) {
|
|
4518
|
+
directoriesSection = `
|
|
4519
|
+
|
|
4520
|
+
## Additional Allowed Directories
|
|
4521
|
+
|
|
4522
|
+
In addition to the working directory (${process.cwd()}), you have read/write access to these directories:
|
|
4523
|
+
${config.additionalDirectories.map((d) => `- ${d}`).join("\n")}
|
|
4524
|
+
|
|
4525
|
+
To access files in additional directories, pass the full path to the 'dir_path' parameter of file tools:
|
|
4526
|
+
- ${TOOL_GREP_SEARCH}(pattern="...", dir_path="/path/to/additional/dir")
|
|
4527
|
+
- ${TOOL_GLOB_FILES}(pattern="**/*.ts", dir_path="/path/to/additional/dir")
|
|
4528
|
+
- ${TOOL_FILE_READ}(path="/path/to/additional/dir/file.ts")
|
|
4529
|
+
|
|
4530
|
+
When the user asks about content in an additional directory, search there first using the dir_path parameter.`;
|
|
4531
|
+
}
|
|
4471
4532
|
}
|
|
4472
4533
|
return `You are an autonomous AI assistant with access to tools. Your job is to help users by taking action and solving problems proactively.
|
|
4473
4534
|
|
|
@@ -4557,7 +4618,7 @@ EXAMPLES:
|
|
|
4557
4618
|
- "what packages installed?" \u2192 ${TOOL_GLOB_FILES} "**/package.json" \u2192 ${TOOL_FILE_READ}
|
|
4558
4619
|
- "find all components using React hooks" \u2192 ${TOOL_SUBAGENT_DELEGATE}(task="find all components using React hooks", type="explore")
|
|
4559
4620
|
|
|
4560
|
-
Remember: Use context from previous messages to understand follow-up questions.${projectContextSection}${skillsSection}`;
|
|
4621
|
+
Remember: Use context from previous messages to understand follow-up questions.${directoriesSection}${projectContextSection}${skillsSection}`;
|
|
4561
4622
|
}
|
|
4562
4623
|
function buildDynamicAgentPromptSection() {
|
|
4563
4624
|
return `
|
|
@@ -4608,7 +4669,7 @@ You have access to the '${TOOL_CREATE_DYNAMIC_AGENT}' tool, which lets you creat
|
|
|
4608
4669
|
|
|
4609
4670
|
// src/utils/toolsAdapter.ts
|
|
4610
4671
|
import { rmSync } from "fs";
|
|
4611
|
-
import
|
|
4672
|
+
import path14 from "path";
|
|
4612
4673
|
|
|
4613
4674
|
// ../../b4m-core/packages/services/dist/src/referService/generateCodes.js
|
|
4614
4675
|
import { randomBytes } from "crypto";
|
|
@@ -5050,7 +5111,7 @@ var incrementUserCounterSchema = z27.object({
|
|
|
5050
5111
|
});
|
|
5051
5112
|
|
|
5052
5113
|
// ../../b4m-core/packages/services/dist/src/countersService/sendSlackReport.js
|
|
5053
|
-
import
|
|
5114
|
+
import axios3 from "axios";
|
|
5054
5115
|
|
|
5055
5116
|
// ../../b4m-core/packages/services/dist/src/countersService/aiInsights.js
|
|
5056
5117
|
import OpenAI from "openai";
|
|
@@ -5064,7 +5125,7 @@ import OpenAI2 from "openai";
|
|
|
5064
5125
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
|
|
5065
5126
|
import fs7, { unlinkSync as unlinkSync2 } from "fs";
|
|
5066
5127
|
import yauzl from "yauzl";
|
|
5067
|
-
import
|
|
5128
|
+
import axios4 from "axios";
|
|
5068
5129
|
|
|
5069
5130
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/importOpenaiHistory.js
|
|
5070
5131
|
import { z as z28 } from "zod";
|
|
@@ -6346,7 +6407,7 @@ var researchTaskRetrySchema = z120.object({
|
|
|
6346
6407
|
});
|
|
6347
6408
|
|
|
6348
6409
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/processDiscoveredLinks.js
|
|
6349
|
-
import
|
|
6410
|
+
import axios5 from "axios";
|
|
6350
6411
|
import { z as z121 } from "zod";
|
|
6351
6412
|
import plimit from "p-limit";
|
|
6352
6413
|
import pLimit2 from "p-limit";
|
|
@@ -6357,7 +6418,7 @@ var researchTaskProcessDiscoveredLinksSchema = z121.object({
|
|
|
6357
6418
|
// ../../b4m-core/packages/services/dist/src/researchTaskService/downloadRelevantLinks.js
|
|
6358
6419
|
import { z as z122 } from "zod";
|
|
6359
6420
|
import plimit2 from "p-limit";
|
|
6360
|
-
import
|
|
6421
|
+
import axios6 from "axios";
|
|
6361
6422
|
import { fileTypeFromBuffer } from "file-type";
|
|
6362
6423
|
var researchTaskDownloadRelevantLinksSchema = z122.object({
|
|
6363
6424
|
id: z122.string()
|
|
@@ -6736,7 +6797,7 @@ var weatherTool = {
|
|
|
6736
6797
|
};
|
|
6737
6798
|
|
|
6738
6799
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/imageGeneration/index.js
|
|
6739
|
-
import
|
|
6800
|
+
import axios7 from "axios";
|
|
6740
6801
|
import { fileTypeFromBuffer as fileTypeFromBuffer2 } from "file-type";
|
|
6741
6802
|
import { v4 as uuidv45 } from "uuid";
|
|
6742
6803
|
async function downloadImage(url) {
|
|
@@ -6744,7 +6805,7 @@ async function downloadImage(url) {
|
|
|
6744
6805
|
const base64Data = url.split(",")[1];
|
|
6745
6806
|
return Buffer.from(base64Data, "base64");
|
|
6746
6807
|
}
|
|
6747
|
-
const response = await
|
|
6808
|
+
const response = await axios7.get(url, { responseType: "arraybuffer" });
|
|
6748
6809
|
return response.data;
|
|
6749
6810
|
}
|
|
6750
6811
|
async function processAndStoreImages(images, context) {
|
|
@@ -8135,7 +8196,7 @@ Return only the edited content without any markdown code blocks or explanations.
|
|
|
8135
8196
|
};
|
|
8136
8197
|
|
|
8137
8198
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/imageEdit/index.js
|
|
8138
|
-
import
|
|
8199
|
+
import axios8 from "axios";
|
|
8139
8200
|
import { fileTypeFromBuffer as fileTypeFromBuffer3 } from "file-type";
|
|
8140
8201
|
import { v4 as uuidv46 } from "uuid";
|
|
8141
8202
|
var EDIT_SUPPORTED_MODELS = [
|
|
@@ -8152,10 +8213,10 @@ async function downloadImage2(url) {
|
|
|
8152
8213
|
return Buffer.from(base64Data, "base64");
|
|
8153
8214
|
}
|
|
8154
8215
|
try {
|
|
8155
|
-
const response = await
|
|
8216
|
+
const response = await axios8.get(url, { responseType: "arraybuffer", timeout: 3e4 });
|
|
8156
8217
|
return response.data;
|
|
8157
8218
|
} catch (error) {
|
|
8158
|
-
if (
|
|
8219
|
+
if (axios8.isAxiosError(error)) {
|
|
8159
8220
|
if (error.response?.status === 403 || error.response?.status === 404) {
|
|
8160
8221
|
throw new Error(`Image URL is expired or inaccessible. Please use a file ID from the workbench or a recently generated image URL. Original error: ${error.message}`);
|
|
8161
8222
|
}
|
|
@@ -8313,7 +8374,7 @@ Please select a supported edit model in your image settings modal.`;
|
|
|
8313
8374
|
} catch (error) {
|
|
8314
8375
|
console.error("[ERROR] BFL image editing failed:", error);
|
|
8315
8376
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
8316
|
-
if (
|
|
8377
|
+
if (axios8.isAxiosError(error)) {
|
|
8317
8378
|
const status = error.response?.status;
|
|
8318
8379
|
const responseData = error.response?.data;
|
|
8319
8380
|
if (status === 403) {
|
|
@@ -8353,7 +8414,7 @@ Please check your BFL API key in settings and ensure it is configured correctly.
|
|
|
8353
8414
|
} catch (error) {
|
|
8354
8415
|
console.error("[ERROR] Gemini image editing failed:", error);
|
|
8355
8416
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
8356
|
-
if (
|
|
8417
|
+
if (axios8.isAxiosError(error)) {
|
|
8357
8418
|
const status = error.response?.status;
|
|
8358
8419
|
const responseData = error.response?.data;
|
|
8359
8420
|
if (status === 403 || status === 401) {
|
|
@@ -8387,7 +8448,7 @@ Please check your BFL API key in settings and ensure it is configured correctly.
|
|
|
8387
8448
|
} catch (error) {
|
|
8388
8449
|
console.error("[ERROR] OpenAI image editing failed:", error);
|
|
8389
8450
|
const errorMessage = error instanceof Error ? error.message : "Unknown error";
|
|
8390
|
-
if (
|
|
8451
|
+
if (axios8.isAxiosError(error)) {
|
|
8391
8452
|
const status = error.response?.status;
|
|
8392
8453
|
const responseData = error.response?.data;
|
|
8393
8454
|
if (status === 403 || status === 401) {
|
|
@@ -10134,16 +10195,50 @@ var planetVisibilityTool = {
|
|
|
10134
10195
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
10135
10196
|
import { promises as fs8 } from "fs";
|
|
10136
10197
|
import { existsSync as existsSync5, statSync as statSync4 } from "fs";
|
|
10198
|
+
|
|
10199
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/utils/pathValidation.js
|
|
10137
10200
|
import path8 from "path";
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10201
|
+
import { realpathSync as realpathSync2 } from "fs";
|
|
10202
|
+
function resolveRealPath(filePath) {
|
|
10203
|
+
try {
|
|
10204
|
+
return realpathSync2(filePath);
|
|
10205
|
+
} catch {
|
|
10206
|
+
const parentDir = path8.dirname(filePath);
|
|
10207
|
+
const basename2 = path8.basename(filePath);
|
|
10208
|
+
if (parentDir === filePath) {
|
|
10209
|
+
return filePath;
|
|
10210
|
+
}
|
|
10211
|
+
return path8.join(resolveRealPath(parentDir), basename2);
|
|
10212
|
+
}
|
|
10213
|
+
}
|
|
10214
|
+
function isPathAllowed(filePath, allowedDirectories) {
|
|
10215
|
+
const cwd = resolveRealPath(process.cwd());
|
|
10216
|
+
const allAllowed = [cwd, ...(allowedDirectories || []).map((d) => resolveRealPath(d))];
|
|
10141
10217
|
const normalizedPath = path8.normalize(filePath);
|
|
10142
|
-
const
|
|
10143
|
-
const
|
|
10144
|
-
|
|
10145
|
-
|
|
10218
|
+
const logicalPath = path8.isAbsolute(normalizedPath) ? normalizedPath : path8.resolve(cwd, normalizedPath);
|
|
10219
|
+
const resolvedPath = resolveRealPath(logicalPath);
|
|
10220
|
+
for (const dir of allAllowed) {
|
|
10221
|
+
if (resolvedPath === dir || resolvedPath.startsWith(dir + path8.sep)) {
|
|
10222
|
+
return { allowed: true, resolvedPath, matchedDirectory: dir };
|
|
10223
|
+
}
|
|
10146
10224
|
}
|
|
10225
|
+
return { allowed: false, resolvedPath };
|
|
10226
|
+
}
|
|
10227
|
+
function assertPathAllowed(filePath, allowedDirectories, operation = "access") {
|
|
10228
|
+
const result = isPathAllowed(filePath, allowedDirectories);
|
|
10229
|
+
if (!result.allowed) {
|
|
10230
|
+
const cwd = process.cwd();
|
|
10231
|
+
const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[cwd, ...allowedDirectories].join(", ")}` : `Working directory: ${cwd}`;
|
|
10232
|
+
throw new Error(`Access denied: Cannot ${operation} files outside allowed directories. ${dirsMsg}`);
|
|
10233
|
+
}
|
|
10234
|
+
return result.resolvedPath;
|
|
10235
|
+
}
|
|
10236
|
+
|
|
10237
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
10238
|
+
var MAX_FILE_SIZE3 = 10 * 1024 * 1024;
|
|
10239
|
+
async function readFileContent(params, allowedDirectories) {
|
|
10240
|
+
const { path: filePath, encoding = "utf-8", offset = 0, limit } = params;
|
|
10241
|
+
const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "read");
|
|
10147
10242
|
if (!existsSync5(resolvedPath)) {
|
|
10148
10243
|
throw new Error(`File not found: ${filePath}`);
|
|
10149
10244
|
}
|
|
@@ -10212,8 +10307,9 @@ var fileReadTool = {
|
|
|
10212
10307
|
const params = value;
|
|
10213
10308
|
context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
|
|
10214
10309
|
try {
|
|
10215
|
-
const content = await readFileContent(params);
|
|
10216
|
-
const
|
|
10310
|
+
const content = await readFileContent(params, context.allowedDirectories);
|
|
10311
|
+
const { resolvedPath: validatedPath } = isPathAllowed(params.path, context.allowedDirectories);
|
|
10312
|
+
const stats = statSync4(validatedPath);
|
|
10217
10313
|
context.logger.info("\u2705 FileRead: Success", {
|
|
10218
10314
|
path: params.path,
|
|
10219
10315
|
size: stats.size,
|
|
@@ -10260,14 +10356,9 @@ var fileReadTool = {
|
|
|
10260
10356
|
import { promises as fs9 } from "fs";
|
|
10261
10357
|
import { existsSync as existsSync6 } from "fs";
|
|
10262
10358
|
import path9 from "path";
|
|
10263
|
-
async function createFile(params) {
|
|
10359
|
+
async function createFile(params, allowedDirectories) {
|
|
10264
10360
|
const { path: filePath, content, createDirectories = true } = params;
|
|
10265
|
-
const
|
|
10266
|
-
const resolvedPath = path9.resolve(process.cwd(), normalizedPath);
|
|
10267
|
-
const cwd = path9.resolve(process.cwd());
|
|
10268
|
-
if (!resolvedPath.startsWith(cwd)) {
|
|
10269
|
-
throw new Error(`Access denied: Cannot create files outside of current working directory`);
|
|
10270
|
-
}
|
|
10361
|
+
const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "create");
|
|
10271
10362
|
const fileExists = existsSync6(resolvedPath);
|
|
10272
10363
|
const action = fileExists ? "overwritten" : "created";
|
|
10273
10364
|
if (createDirectories) {
|
|
@@ -10292,7 +10383,7 @@ var createFileTool = {
|
|
|
10292
10383
|
size: params.content.length
|
|
10293
10384
|
});
|
|
10294
10385
|
try {
|
|
10295
|
-
const result = await createFile(params);
|
|
10386
|
+
const result = await createFile(params, context.allowedDirectories);
|
|
10296
10387
|
context.logger.info("\u2705 CreateFile: Success", { path: params.path });
|
|
10297
10388
|
return result;
|
|
10298
10389
|
} catch (error) {
|
|
@@ -10341,12 +10432,14 @@ var DEFAULT_IGNORE_PATTERNS = [
|
|
|
10341
10432
|
"**/*.min.js",
|
|
10342
10433
|
"**/*.min.css"
|
|
10343
10434
|
];
|
|
10344
|
-
async function findFiles(params) {
|
|
10435
|
+
async function findFiles(params, allowedDirectories) {
|
|
10345
10436
|
const { pattern, dir_path, case_sensitive = true, respect_git_ignore = true } = params;
|
|
10346
10437
|
const baseCwd = process.cwd();
|
|
10347
10438
|
const targetDir = dir_path ? path10.resolve(baseCwd, path10.normalize(dir_path)) : baseCwd;
|
|
10348
|
-
|
|
10349
|
-
|
|
10439
|
+
const validation = isPathAllowed(targetDir, allowedDirectories);
|
|
10440
|
+
if (!validation.allowed) {
|
|
10441
|
+
const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[baseCwd, ...allowedDirectories].join(", ")}` : `Working directory: ${baseCwd}`;
|
|
10442
|
+
throw new Error(`Access denied: Cannot search outside allowed directories. ${dirsMsg}`);
|
|
10350
10443
|
}
|
|
10351
10444
|
const ignorePatterns = respect_git_ignore ? DEFAULT_IGNORE_PATTERNS : [];
|
|
10352
10445
|
const matches = await glob(pattern, {
|
|
@@ -10399,7 +10492,7 @@ var globFilesTool = {
|
|
|
10399
10492
|
dir_path: params.dir_path || "."
|
|
10400
10493
|
});
|
|
10401
10494
|
try {
|
|
10402
|
-
const result = await findFiles(params);
|
|
10495
|
+
const result = await findFiles(params, context.allowedDirectories);
|
|
10403
10496
|
context.logger.info("\u2705 GlobFiles: Success");
|
|
10404
10497
|
return result;
|
|
10405
10498
|
} catch (error) {
|
|
@@ -10475,12 +10568,6 @@ function getRipgrepPath() {
|
|
|
10475
10568
|
throw new Error("ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services");
|
|
10476
10569
|
}
|
|
10477
10570
|
}
|
|
10478
|
-
function isPathWithinWorkspace(targetPath, baseCwd) {
|
|
10479
|
-
const resolvedTarget = path11.resolve(targetPath);
|
|
10480
|
-
const resolvedBase = path11.resolve(baseCwd);
|
|
10481
|
-
const relativePath = path11.relative(resolvedBase, resolvedTarget);
|
|
10482
|
-
return !relativePath.startsWith("..") && !path11.isAbsolute(relativePath);
|
|
10483
|
-
}
|
|
10484
10571
|
function convertGlobToRipgrepGlobs(globPattern) {
|
|
10485
10572
|
if (!globPattern || globPattern === "**/*") {
|
|
10486
10573
|
return [];
|
|
@@ -10492,12 +10579,14 @@ function convertGlobToRipgrepGlobs(globPattern) {
|
|
|
10492
10579
|
}
|
|
10493
10580
|
return [globPattern];
|
|
10494
10581
|
}
|
|
10495
|
-
async function searchFiles2(params) {
|
|
10582
|
+
async function searchFiles2(params, allowedDirectories) {
|
|
10496
10583
|
const { pattern, dir_path, include } = params;
|
|
10497
10584
|
const baseCwd = process.cwd();
|
|
10498
10585
|
const targetDir = dir_path ? path11.resolve(baseCwd, dir_path) : baseCwd;
|
|
10499
|
-
|
|
10500
|
-
|
|
10586
|
+
const validation = isPathAllowed(targetDir, allowedDirectories);
|
|
10587
|
+
if (!validation.allowed) {
|
|
10588
|
+
const dirsMsg = allowedDirectories && allowedDirectories.length > 0 ? `Allowed directories: ${[baseCwd, ...allowedDirectories].join(", ")}` : `Working directory: ${baseCwd}`;
|
|
10589
|
+
throw new Error(`Path validation failed: "${dir_path}" resolves outside allowed directories. ${dirsMsg}`);
|
|
10501
10590
|
}
|
|
10502
10591
|
try {
|
|
10503
10592
|
const stats = await stat2(targetDir);
|
|
@@ -10616,7 +10705,7 @@ var grepSearchTool = {
|
|
|
10616
10705
|
include: params.include || "**/*"
|
|
10617
10706
|
});
|
|
10618
10707
|
try {
|
|
10619
|
-
const result = await searchFiles2(params);
|
|
10708
|
+
const result = await searchFiles2(params, context.allowedDirectories);
|
|
10620
10709
|
context.logger.info("\u2705 GrepSearch: Success");
|
|
10621
10710
|
return result;
|
|
10622
10711
|
} catch (error) {
|
|
@@ -10653,14 +10742,9 @@ var grepSearchTool = {
|
|
|
10653
10742
|
import { promises as fs10 } from "fs";
|
|
10654
10743
|
import { existsSync as existsSync8, statSync as statSync5 } from "fs";
|
|
10655
10744
|
import path12 from "path";
|
|
10656
|
-
async function deleteFile(params) {
|
|
10745
|
+
async function deleteFile(params, allowedDirectories) {
|
|
10657
10746
|
const { path: filePath, recursive = false } = params;
|
|
10658
|
-
const
|
|
10659
|
-
const resolvedPath = path12.resolve(process.cwd(), normalizedPath);
|
|
10660
|
-
const cwd = path12.resolve(process.cwd());
|
|
10661
|
-
if (!resolvedPath.startsWith(cwd)) {
|
|
10662
|
-
throw new Error(`Access denied: Cannot delete files outside of current working directory`);
|
|
10663
|
-
}
|
|
10747
|
+
const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "delete");
|
|
10664
10748
|
if (!existsSync8(resolvedPath)) {
|
|
10665
10749
|
throw new Error(`File or directory not found: ${filePath}`);
|
|
10666
10750
|
}
|
|
@@ -10691,7 +10775,7 @@ var deleteFileTool = {
|
|
|
10691
10775
|
recursive: params.recursive
|
|
10692
10776
|
});
|
|
10693
10777
|
try {
|
|
10694
|
-
const result = await deleteFile(params);
|
|
10778
|
+
const result = await deleteFile(params, context.allowedDirectories);
|
|
10695
10779
|
context.logger.info("\u2705 DeleteFile: Success", { path: params.path });
|
|
10696
10780
|
return result;
|
|
10697
10781
|
} catch (error) {
|
|
@@ -14555,7 +14639,6 @@ function parseQuery(query) {
|
|
|
14555
14639
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editLocalFile/index.js
|
|
14556
14640
|
import { promises as fs11 } from "fs";
|
|
14557
14641
|
import { existsSync as existsSync9 } from "fs";
|
|
14558
|
-
import path14 from "path";
|
|
14559
14642
|
import { diffLines as diffLines3 } from "diff";
|
|
14560
14643
|
function generateDiff(original, modified) {
|
|
14561
14644
|
const differences = diffLines3(original, modified);
|
|
@@ -14577,14 +14660,9 @@ function generateDiff(original, modified) {
|
|
|
14577
14660
|
});
|
|
14578
14661
|
return { additions, deletions, diff: diffString.trim() };
|
|
14579
14662
|
}
|
|
14580
|
-
async function editLocalFile(params) {
|
|
14663
|
+
async function editLocalFile(params, allowedDirectories) {
|
|
14581
14664
|
const { path: filePath, old_string, new_string } = params;
|
|
14582
|
-
const
|
|
14583
|
-
const resolvedPath = path14.resolve(process.cwd(), normalizedPath);
|
|
14584
|
-
const cwd = path14.resolve(process.cwd());
|
|
14585
|
-
if (!resolvedPath.startsWith(cwd)) {
|
|
14586
|
-
throw new Error(`Access denied: Cannot edit files outside of current working directory`);
|
|
14587
|
-
}
|
|
14665
|
+
const resolvedPath = assertPathAllowed(filePath, allowedDirectories, "edit");
|
|
14588
14666
|
if (!existsSync9(resolvedPath)) {
|
|
14589
14667
|
throw new Error(`File not found: ${filePath}`);
|
|
14590
14668
|
}
|
|
@@ -14617,7 +14695,7 @@ var editLocalFileTool = {
|
|
|
14617
14695
|
newStringLength: params.new_string.length
|
|
14618
14696
|
});
|
|
14619
14697
|
try {
|
|
14620
|
-
const result = await editLocalFile(params);
|
|
14698
|
+
const result = await editLocalFile(params, context.allowedDirectories);
|
|
14621
14699
|
context.logger.info("\u2705 EditLocalFile: Success", { path: params.path });
|
|
14622
14700
|
return result;
|
|
14623
14701
|
} catch (error) {
|
|
@@ -15170,7 +15248,7 @@ var cliOnlyTools = {
|
|
|
15170
15248
|
// Interactive tools
|
|
15171
15249
|
ask_user_question: askUserQuestionTool
|
|
15172
15250
|
};
|
|
15173
|
-
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools) => {
|
|
15251
|
+
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, imageProcessorLambdaName, tools = b4mTools, allowedDirectories) => {
|
|
15174
15252
|
const context = {
|
|
15175
15253
|
userId,
|
|
15176
15254
|
user,
|
|
@@ -15183,7 +15261,8 @@ var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorag
|
|
|
15183
15261
|
onFinish,
|
|
15184
15262
|
llm,
|
|
15185
15263
|
model,
|
|
15186
|
-
imageProcessorLambdaName
|
|
15264
|
+
imageProcessorLambdaName,
|
|
15265
|
+
allowedDirectories
|
|
15187
15266
|
};
|
|
15188
15267
|
return Object.entries(tools).reduce((acc, [key, tool]) => ({
|
|
15189
15268
|
...acc,
|
|
@@ -16041,7 +16120,7 @@ import { fromZodError } from "zod-validation-error";
|
|
|
16041
16120
|
var BUILT_IN_TOOL_SET = new Set(b4mLLMTools.options);
|
|
16042
16121
|
|
|
16043
16122
|
// ../../b4m-core/packages/services/dist/src/llm/ImageGeneration.js
|
|
16044
|
-
import
|
|
16123
|
+
import axios9 from "axios";
|
|
16045
16124
|
import { fileTypeFromBuffer as fileTypeFromBuffer4 } from "file-type";
|
|
16046
16125
|
import { v4 as uuidv47 } from "uuid";
|
|
16047
16126
|
import { z as z141 } from "zod";
|
|
@@ -16063,7 +16142,7 @@ var ImageGenerationBodySchema = OpenAIImageGenerationInput.extend({
|
|
|
16063
16142
|
});
|
|
16064
16143
|
|
|
16065
16144
|
// ../../b4m-core/packages/services/dist/src/llm/VideoGeneration.js
|
|
16066
|
-
import
|
|
16145
|
+
import axios10 from "axios";
|
|
16067
16146
|
import { v4 as uuidv48 } from "uuid";
|
|
16068
16147
|
import { z as z142 } from "zod";
|
|
16069
16148
|
import { fromZodError as fromZodError3 } from "zod-validation-error";
|
|
@@ -16079,7 +16158,7 @@ var VideoGenerationBodySchema = z142.object({
|
|
|
16079
16158
|
});
|
|
16080
16159
|
|
|
16081
16160
|
// ../../b4m-core/packages/services/dist/src/llm/ImageEdit.js
|
|
16082
|
-
import
|
|
16161
|
+
import axios11 from "axios";
|
|
16083
16162
|
import { fileTypeFromBuffer as fileTypeFromBuffer5 } from "file-type";
|
|
16084
16163
|
import { v4 as uuidv49 } from "uuid";
|
|
16085
16164
|
import { z as z143 } from "zod";
|
|
@@ -16189,7 +16268,7 @@ async function generateFileDeletePreview(args) {
|
|
|
16189
16268
|
if (!existsSync10(args.path)) {
|
|
16190
16269
|
return `[File does not exist: ${args.path}]`;
|
|
16191
16270
|
}
|
|
16192
|
-
const stats = await import("fs/promises").then((
|
|
16271
|
+
const stats = await import("fs/promises").then((fs16) => fs16.stat(args.path));
|
|
16193
16272
|
return `[File will be deleted]
|
|
16194
16273
|
|
|
16195
16274
|
Path: ${args.path}
|
|
@@ -16538,7 +16617,7 @@ function wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, a
|
|
|
16538
16617
|
let isSandboxed = false;
|
|
16539
16618
|
let sandboxedArgs = args;
|
|
16540
16619
|
if (toolName === "bash_execute" && args?.command && sandboxOrchestrator) {
|
|
16541
|
-
const cwd = args.cwd ?
|
|
16620
|
+
const cwd = args.cwd ? path14.resolve(process.cwd(), args.cwd) : process.cwd();
|
|
16542
16621
|
const decision = sandboxOrchestrator.shouldSandbox(args.command, cwd);
|
|
16543
16622
|
if (decision.type === "blocked") {
|
|
16544
16623
|
sandboxOrchestrator.recordBlocked();
|
|
@@ -16784,7 +16863,7 @@ function wrapToolWithCheckpointing(tool, checkpointStore) {
|
|
|
16784
16863
|
const filePath = args?.path;
|
|
16785
16864
|
if (filePath) {
|
|
16786
16865
|
try {
|
|
16787
|
-
await checkpointStore.createCheckpoint(toolName, [filePath], `before-${toolName}-${
|
|
16866
|
+
await checkpointStore.createCheckpoint(toolName, [filePath], `before-${toolName}-${path14.basename(filePath)}`);
|
|
16788
16867
|
} catch {
|
|
16789
16868
|
}
|
|
16790
16869
|
}
|
|
@@ -16816,7 +16895,7 @@ function normalizeToolName(toolName) {
|
|
|
16816
16895
|
}
|
|
16817
16896
|
return TOOL_NAME_MAPPING[toolName] || toolName;
|
|
16818
16897
|
}
|
|
16819
|
-
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient, toolFilter, showUserQuestion, checkpointStore, sandboxOrchestrator) {
|
|
16898
|
+
function generateCliTools(userId, llm, model, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient, toolFilter, showUserQuestion, checkpointStore, sandboxOrchestrator, allowedDirectories) {
|
|
16820
16899
|
if (showUserQuestion) {
|
|
16821
16900
|
setShowUserQuestionFn(showUserQuestion);
|
|
16822
16901
|
}
|
|
@@ -16876,7 +16955,8 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
16876
16955
|
model,
|
|
16877
16956
|
void 0,
|
|
16878
16957
|
// imageProcessorLambdaName (not needed for CLI)
|
|
16879
|
-
tools_to_generate
|
|
16958
|
+
tools_to_generate,
|
|
16959
|
+
allowedDirectories
|
|
16880
16960
|
);
|
|
16881
16961
|
let tools = Object.entries(toolsMap).map(([_, tool]) => {
|
|
16882
16962
|
const permissionWrapped = wrapToolWithPermission(
|
|
@@ -17087,7 +17167,7 @@ function getEnvironmentName(configApiConfig) {
|
|
|
17087
17167
|
|
|
17088
17168
|
// src/utils/contextLoader.ts
|
|
17089
17169
|
import * as fs12 from "fs";
|
|
17090
|
-
import * as
|
|
17170
|
+
import * as path15 from "path";
|
|
17091
17171
|
import { homedir as homedir3 } from "os";
|
|
17092
17172
|
var CONTEXT_FILE_SIZE_LIMIT = 100 * 1024;
|
|
17093
17173
|
var PROJECT_CONTEXT_FILES = [
|
|
@@ -17108,7 +17188,7 @@ function formatFileSize2(bytes) {
|
|
|
17108
17188
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
17109
17189
|
}
|
|
17110
17190
|
function tryReadContextFile(dir, filename, source) {
|
|
17111
|
-
const filePath =
|
|
17191
|
+
const filePath = path15.join(dir, filename);
|
|
17112
17192
|
try {
|
|
17113
17193
|
const stats = fs12.lstatSync(filePath);
|
|
17114
17194
|
if (stats.isDirectory()) {
|
|
@@ -17176,7 +17256,7 @@ ${project.content}`;
|
|
|
17176
17256
|
}
|
|
17177
17257
|
async function loadContextFiles(projectDir) {
|
|
17178
17258
|
const errors = [];
|
|
17179
|
-
const globalDir =
|
|
17259
|
+
const globalDir = path15.join(homedir3(), ".bike4mind");
|
|
17180
17260
|
const projectDirectory = projectDir || process.cwd();
|
|
17181
17261
|
const [globalResult, projectResult] = await Promise.all([
|
|
17182
17262
|
Promise.resolve(findContextFile(globalDir, GLOBAL_CONTEXT_FILES, "global")),
|
|
@@ -17447,7 +17527,7 @@ function substituteArguments(template, args) {
|
|
|
17447
17527
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
17448
17528
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
17449
17529
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
17450
|
-
import
|
|
17530
|
+
import path16 from "path";
|
|
17451
17531
|
import { existsSync as existsSync11, readdirSync as readdirSync3 } from "fs";
|
|
17452
17532
|
var MCPClient = class {
|
|
17453
17533
|
// Note: This class handles MCP server communication with repository filtering
|
|
@@ -17489,16 +17569,16 @@ var MCPClient = class {
|
|
|
17489
17569
|
const root = process.env.INIT_CWD || process.cwd();
|
|
17490
17570
|
const candidatePaths = [
|
|
17491
17571
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
17492
|
-
|
|
17572
|
+
path16.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
17493
17573
|
// When running from SST Lambda deployed environment (/var/task)
|
|
17494
|
-
|
|
17574
|
+
path16.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
17495
17575
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
17496
|
-
|
|
17576
|
+
path16.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
17497
17577
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
17498
|
-
|
|
17578
|
+
path16.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
17499
17579
|
// Original paths (backward compatibility)
|
|
17500
|
-
|
|
17501
|
-
|
|
17580
|
+
path16.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
17581
|
+
path16.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
17502
17582
|
];
|
|
17503
17583
|
const serverScriptPath = candidatePaths.find((p) => existsSync11(p));
|
|
17504
17584
|
if (!serverScriptPath) {
|
|
@@ -18842,12 +18922,12 @@ var WebSocketToolExecutor = class {
|
|
|
18842
18922
|
};
|
|
18843
18923
|
|
|
18844
18924
|
// src/auth/ApiClient.ts
|
|
18845
|
-
import
|
|
18925
|
+
import axios12 from "axios";
|
|
18846
18926
|
var ApiClient = class {
|
|
18847
18927
|
constructor(baseURL = "http://localhost:3000", configStore) {
|
|
18848
18928
|
this.configStore = configStore || new ConfigStore();
|
|
18849
18929
|
this.oauthClient = new OAuthClient(baseURL);
|
|
18850
|
-
this.client =
|
|
18930
|
+
this.client = axios12.create({
|
|
18851
18931
|
baseURL,
|
|
18852
18932
|
headers: {
|
|
18853
18933
|
"Content-Type": "application/json"
|
|
@@ -19445,7 +19525,7 @@ var SubagentOrchestrator = class {
|
|
|
19445
19525
|
|
|
19446
19526
|
// src/agents/AgentStore.ts
|
|
19447
19527
|
import fs13 from "fs/promises";
|
|
19448
|
-
import
|
|
19528
|
+
import path17 from "path";
|
|
19449
19529
|
import os2 from "os";
|
|
19450
19530
|
import matter2 from "gray-matter";
|
|
19451
19531
|
var FULL_MODEL_ID_PREFIXES = [
|
|
@@ -19595,10 +19675,10 @@ var AgentStore = class {
|
|
|
19595
19675
|
const root = projectRoot || process.cwd();
|
|
19596
19676
|
const home = os2.homedir();
|
|
19597
19677
|
this.builtinAgentsDir = builtinDir;
|
|
19598
|
-
this.globalB4MAgentsDir =
|
|
19599
|
-
this.globalClaudeAgentsDir =
|
|
19600
|
-
this.projectB4MAgentsDir =
|
|
19601
|
-
this.projectClaudeAgentsDir =
|
|
19678
|
+
this.globalB4MAgentsDir = path17.join(home, ".bike4mind", "agents");
|
|
19679
|
+
this.globalClaudeAgentsDir = path17.join(home, ".claude", "agents");
|
|
19680
|
+
this.projectB4MAgentsDir = path17.join(root, ".bike4mind", "agents");
|
|
19681
|
+
this.projectClaudeAgentsDir = path17.join(root, ".claude", "agents");
|
|
19602
19682
|
}
|
|
19603
19683
|
/**
|
|
19604
19684
|
* Load all agents from all directories
|
|
@@ -19652,7 +19732,7 @@ var AgentStore = class {
|
|
|
19652
19732
|
try {
|
|
19653
19733
|
const entries = await fs13.readdir(directory, { withFileTypes: true });
|
|
19654
19734
|
for (const entry of entries) {
|
|
19655
|
-
const fullPath =
|
|
19735
|
+
const fullPath = path17.join(directory, entry.name);
|
|
19656
19736
|
if (entry.isDirectory()) {
|
|
19657
19737
|
const subFiles = await this.findAgentFiles(fullPath);
|
|
19658
19738
|
files.push(...subFiles);
|
|
@@ -19672,7 +19752,7 @@ var AgentStore = class {
|
|
|
19672
19752
|
const content = await fs13.readFile(filePath, "utf-8");
|
|
19673
19753
|
const { data: frontmatter, content: body } = matter2(content);
|
|
19674
19754
|
const parsed = AgentFrontmatterSchema.parse(frontmatter);
|
|
19675
|
-
const name =
|
|
19755
|
+
const name = path17.basename(filePath, ".md");
|
|
19676
19756
|
const modelInput = parsed.model || DEFAULT_AGENT_MODEL;
|
|
19677
19757
|
const resolution = resolveModelAlias(modelInput, name, filePath);
|
|
19678
19758
|
if (!resolution.resolved && resolution.warning) {
|
|
@@ -19753,7 +19833,7 @@ var AgentStore = class {
|
|
|
19753
19833
|
*/
|
|
19754
19834
|
async createAgentFile(name, isGlobal = false, useClaude = true) {
|
|
19755
19835
|
const targetDir = isGlobal ? useClaude ? this.globalClaudeAgentsDir : this.globalB4MAgentsDir : useClaude ? this.projectClaudeAgentsDir : this.projectB4MAgentsDir;
|
|
19756
|
-
const filePath =
|
|
19836
|
+
const filePath = path17.join(targetDir, `${name}.md`);
|
|
19757
19837
|
try {
|
|
19758
19838
|
await fs13.access(filePath);
|
|
19759
19839
|
throw new Error(`Agent file already exists: ${filePath}`);
|
|
@@ -20582,7 +20662,7 @@ function createTodoStore(onUpdate) {
|
|
|
20582
20662
|
|
|
20583
20663
|
// src/tools/findDefinitionTool.ts
|
|
20584
20664
|
import { stat as stat3 } from "fs/promises";
|
|
20585
|
-
import
|
|
20665
|
+
import path18 from "path";
|
|
20586
20666
|
import { execFile as execFile2 } from "child_process";
|
|
20587
20667
|
import { promisify as promisify2 } from "util";
|
|
20588
20668
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -20603,19 +20683,19 @@ var ALL_KEYWORDS = Object.values(KIND_KEYWORDS).flat();
|
|
|
20603
20683
|
function getRipgrepPath2() {
|
|
20604
20684
|
try {
|
|
20605
20685
|
const ripgrepPath = require3.resolve("@vscode/ripgrep");
|
|
20606
|
-
const ripgrepDir =
|
|
20607
|
-
return
|
|
20686
|
+
const ripgrepDir = path18.dirname(ripgrepPath);
|
|
20687
|
+
return path18.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
|
|
20608
20688
|
} catch {
|
|
20609
20689
|
throw new Error(
|
|
20610
20690
|
"ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services"
|
|
20611
20691
|
);
|
|
20612
20692
|
}
|
|
20613
20693
|
}
|
|
20614
|
-
function
|
|
20615
|
-
const resolvedTarget =
|
|
20616
|
-
const resolvedBase =
|
|
20617
|
-
const relativePath =
|
|
20618
|
-
return !relativePath.startsWith("..") && !
|
|
20694
|
+
function isPathWithinWorkspace(targetPath, baseCwd) {
|
|
20695
|
+
const resolvedTarget = path18.resolve(targetPath);
|
|
20696
|
+
const resolvedBase = path18.resolve(baseCwd);
|
|
20697
|
+
const relativePath = path18.relative(resolvedBase, resolvedTarget);
|
|
20698
|
+
return !relativePath.startsWith("..") && !path18.isAbsolute(relativePath);
|
|
20619
20699
|
}
|
|
20620
20700
|
function escapeRegex(str) {
|
|
20621
20701
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -20648,8 +20728,8 @@ async function findDefinitions(params) {
|
|
|
20648
20728
|
throw new Error("symbol_name is required");
|
|
20649
20729
|
}
|
|
20650
20730
|
const baseCwd = process.cwd();
|
|
20651
|
-
const targetDir = search_path ?
|
|
20652
|
-
if (!
|
|
20731
|
+
const targetDir = search_path ? path18.resolve(baseCwd, search_path) : baseCwd;
|
|
20732
|
+
if (!isPathWithinWorkspace(targetDir, baseCwd)) {
|
|
20653
20733
|
throw new Error(`Path validation failed: "${search_path}" resolves outside the allowed workspace directory`);
|
|
20654
20734
|
}
|
|
20655
20735
|
try {
|
|
@@ -20703,7 +20783,7 @@ async function findDefinitions(params) {
|
|
|
20703
20783
|
const lineText = match.data.lines.text.trimEnd();
|
|
20704
20784
|
if (isLikelyDefinition(lineText)) {
|
|
20705
20785
|
allMatches.push({
|
|
20706
|
-
filePath:
|
|
20786
|
+
filePath: path18.relative(targetDir, match.data.path.text) || path18.basename(match.data.path.text),
|
|
20707
20787
|
lineNumber: match.data.line_number,
|
|
20708
20788
|
line: lineText
|
|
20709
20789
|
});
|
|
@@ -20782,7 +20862,7 @@ function createFindDefinitionTool() {
|
|
|
20782
20862
|
|
|
20783
20863
|
// src/tools/getFileStructure/index.ts
|
|
20784
20864
|
import { existsSync as existsSync12, promises as fs14, statSync as statSync6 } from "fs";
|
|
20785
|
-
import
|
|
20865
|
+
import path19 from "path";
|
|
20786
20866
|
|
|
20787
20867
|
// src/tools/getFileStructure/formatter.ts
|
|
20788
20868
|
var SECTIONS = [
|
|
@@ -20826,7 +20906,7 @@ function createGetFileStructureTool() {
|
|
|
20826
20906
|
const params = value;
|
|
20827
20907
|
try {
|
|
20828
20908
|
const cwd = process.cwd();
|
|
20829
|
-
const resolvedPath =
|
|
20909
|
+
const resolvedPath = path19.resolve(cwd, params.path);
|
|
20830
20910
|
if (!resolvedPath.startsWith(cwd)) {
|
|
20831
20911
|
return "Error: Access denied - cannot read files outside of current working directory";
|
|
20832
20912
|
}
|
|
@@ -20840,7 +20920,7 @@ function createGetFileStructureTool() {
|
|
|
20840
20920
|
if (stats.size > MAX_FILE_SIZE4) {
|
|
20841
20921
|
return `Error: File too large (${(stats.size / 1024 / 1024).toFixed(2)}MB). Max: ${MAX_FILE_SIZE4 / 1024 / 1024}MB`;
|
|
20842
20922
|
}
|
|
20843
|
-
const ext =
|
|
20923
|
+
const ext = path19.extname(resolvedPath).toLowerCase();
|
|
20844
20924
|
const { getLanguageForExtension, parseFileStructure, getSupportedLanguages } = await import("./treeSitterEngine-4SGFQDY3.js");
|
|
20845
20925
|
const languageId = getLanguageForExtension(ext);
|
|
20846
20926
|
if (!languageId) {
|
|
@@ -20911,7 +20991,8 @@ function CliApp() {
|
|
|
20911
20991
|
backgroundManager: null,
|
|
20912
20992
|
sandboxOrchestrator: null,
|
|
20913
20993
|
wsManager: null,
|
|
20914
|
-
checkpointStore: null
|
|
20994
|
+
checkpointStore: null,
|
|
20995
|
+
additionalDirectories: []
|
|
20915
20996
|
});
|
|
20916
20997
|
const [isInitialized, setIsInitialized] = useState11(false);
|
|
20917
20998
|
const [initError, setInitError] = useState11(null);
|
|
@@ -21005,6 +21086,9 @@ function CliApp() {
|
|
|
21005
21086
|
try {
|
|
21006
21087
|
const startupLog = [];
|
|
21007
21088
|
const config = await state.configStore.load();
|
|
21089
|
+
const configDirs = await state.configStore.getAdditionalDirectories();
|
|
21090
|
+
const flagDirs = process.env.B4M_ADDITIONAL_DIRS ? JSON.parse(process.env.B4M_ADDITIONAL_DIRS) : [];
|
|
21091
|
+
const additionalDirectories = [.../* @__PURE__ */ new Set([...configDirs, ...flagDirs])];
|
|
21008
21092
|
const history = await state.commandHistoryStore.load();
|
|
21009
21093
|
setCommandHistory(history);
|
|
21010
21094
|
try {
|
|
@@ -21243,7 +21327,8 @@ function CliApp() {
|
|
|
21243
21327
|
// toolFilter
|
|
21244
21328
|
userQuestionFn,
|
|
21245
21329
|
checkpointStore,
|
|
21246
|
-
sandboxOrchestrator
|
|
21330
|
+
sandboxOrchestrator,
|
|
21331
|
+
additionalDirectories
|
|
21247
21332
|
);
|
|
21248
21333
|
startupLog.push(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
|
|
21249
21334
|
const mcpManager = new McpManager(config);
|
|
@@ -21315,6 +21400,9 @@ function CliApp() {
|
|
|
21315
21400
|
}
|
|
21316
21401
|
const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
|
|
21317
21402
|
startupLog.push(`\u{1F4C2} Working directory: ${process.cwd()}`);
|
|
21403
|
+
if (additionalDirectories.length > 0) {
|
|
21404
|
+
startupLog.push(`\u{1F4C1} Additional directories: ${additionalDirectories.length}`);
|
|
21405
|
+
}
|
|
21318
21406
|
const agentNamesList = agentStore.getAgentNames().join(", ");
|
|
21319
21407
|
startupLog.push(`\u{1F916} Subagent delegation enabled (${agentNamesList}) + background execution`);
|
|
21320
21408
|
if (skillTool) {
|
|
@@ -21345,7 +21433,8 @@ function CliApp() {
|
|
|
21345
21433
|
agentStore,
|
|
21346
21434
|
customCommands: state.customCommandStore.getAllCommands(),
|
|
21347
21435
|
enableSkillTool,
|
|
21348
|
-
enableDynamicAgentCreation: config.preferences.enableDynamicAgentCreation === true
|
|
21436
|
+
enableDynamicAgentCreation: config.preferences.enableDynamicAgentCreation === true,
|
|
21437
|
+
additionalDirectories
|
|
21349
21438
|
});
|
|
21350
21439
|
const maxIterations = config.preferences.maxIterations === null ? 999999 : config.preferences.maxIterations;
|
|
21351
21440
|
const agent = new ReActAgent({
|
|
@@ -21411,8 +21500,10 @@ function CliApp() {
|
|
|
21411
21500
|
// Store sandbox orchestrator for /sandbox commands
|
|
21412
21501
|
wsManager,
|
|
21413
21502
|
// WebSocket connection manager (null if using SSE fallback)
|
|
21414
|
-
checkpointStore
|
|
21503
|
+
checkpointStore,
|
|
21415
21504
|
// File change checkpointing for undo/restore
|
|
21505
|
+
additionalDirectories
|
|
21506
|
+
// Store additional directories for file access
|
|
21416
21507
|
}));
|
|
21417
21508
|
setStoreSession(newSession);
|
|
21418
21509
|
const bannerLines = [
|
|
@@ -21688,7 +21779,8 @@ function CliApp() {
|
|
|
21688
21779
|
contextContent: state.contextContent,
|
|
21689
21780
|
agentStore: state.agentStore || void 0,
|
|
21690
21781
|
customCommands: state.customCommandStore.getAllCommands(),
|
|
21691
|
-
enableSkillTool: config?.preferences.enableSkillTool !== false
|
|
21782
|
+
enableSkillTool: config?.preferences.enableSkillTool !== false,
|
|
21783
|
+
additionalDirectories: state.additionalDirectories
|
|
21692
21784
|
});
|
|
21693
21785
|
const contextUsage = tokenCounter2.countSessionTokens(activeSession, systemPrompt);
|
|
21694
21786
|
if (contextUsage.totalTokens >= threshold) {
|
|
@@ -22730,7 +22822,8 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
22730
22822
|
contextContent: state.contextContent,
|
|
22731
22823
|
agentStore: state.agentStore || void 0,
|
|
22732
22824
|
customCommands: commands,
|
|
22733
|
-
enableSkillTool: state.config?.preferences.enableSkillTool !== false
|
|
22825
|
+
enableSkillTool: state.config?.preferences.enableSkillTool !== false,
|
|
22826
|
+
additionalDirectories: state.additionalDirectories
|
|
22734
22827
|
});
|
|
22735
22828
|
const usage = tokenCounter2.countSessionTokens(state.session, systemPrompt);
|
|
22736
22829
|
const totalWithTools = usage.totalTokens + mcpToolsTokens;
|
|
@@ -23164,6 +23257,76 @@ Allowed domains (${domains.length}):`);
|
|
|
23164
23257
|
console.log("");
|
|
23165
23258
|
break;
|
|
23166
23259
|
}
|
|
23260
|
+
case "add-dir": {
|
|
23261
|
+
let dirPath = args.join(" ").trim();
|
|
23262
|
+
if (!dirPath) {
|
|
23263
|
+
console.log("Usage: /add-dir <path>");
|
|
23264
|
+
console.log("\nExample:");
|
|
23265
|
+
console.log(" /add-dir /path/to/directory");
|
|
23266
|
+
console.log(" /add-dir ~/codes/my-project");
|
|
23267
|
+
break;
|
|
23268
|
+
}
|
|
23269
|
+
if (dirPath.startsWith("~/")) {
|
|
23270
|
+
dirPath = path20.join(homedir4(), dirPath.slice(2));
|
|
23271
|
+
} else if (dirPath === "~") {
|
|
23272
|
+
dirPath = homedir4();
|
|
23273
|
+
}
|
|
23274
|
+
const resolvedPath = path20.resolve(dirPath);
|
|
23275
|
+
if (!existsSync13(resolvedPath)) {
|
|
23276
|
+
console.log(`\u274C Directory does not exist: ${resolvedPath}`);
|
|
23277
|
+
break;
|
|
23278
|
+
}
|
|
23279
|
+
const dirStat = await fs15.stat(resolvedPath);
|
|
23280
|
+
if (!dirStat.isDirectory()) {
|
|
23281
|
+
console.log(`\u274C Path is not a directory: ${resolvedPath}`);
|
|
23282
|
+
break;
|
|
23283
|
+
}
|
|
23284
|
+
await state.configStore.addDirectory(resolvedPath);
|
|
23285
|
+
setState((prev) => ({
|
|
23286
|
+
...prev,
|
|
23287
|
+
additionalDirectories: [...prev.additionalDirectories || [], resolvedPath]
|
|
23288
|
+
}));
|
|
23289
|
+
console.log(`\u2705 Added directory: ${resolvedPath}`);
|
|
23290
|
+
console.log(" File tools now have access to this directory.");
|
|
23291
|
+
break;
|
|
23292
|
+
}
|
|
23293
|
+
case "remove-dir": {
|
|
23294
|
+
let removeDir = args.join(" ").trim();
|
|
23295
|
+
if (!removeDir) {
|
|
23296
|
+
console.log("Usage: /remove-dir <path>");
|
|
23297
|
+
break;
|
|
23298
|
+
}
|
|
23299
|
+
if (removeDir.startsWith("~/")) {
|
|
23300
|
+
removeDir = path20.join(homedir4(), removeDir.slice(2));
|
|
23301
|
+
} else if (removeDir === "~") {
|
|
23302
|
+
removeDir = homedir4();
|
|
23303
|
+
}
|
|
23304
|
+
const resolvedRemovePath = path20.resolve(removeDir);
|
|
23305
|
+
await state.configStore.removeDirectory(resolvedRemovePath);
|
|
23306
|
+
setState((prev) => ({
|
|
23307
|
+
...prev,
|
|
23308
|
+
additionalDirectories: (prev.additionalDirectories || []).filter((d) => path20.resolve(d) !== resolvedRemovePath)
|
|
23309
|
+
}));
|
|
23310
|
+
console.log(`\u2705 Removed directory: ${resolvedRemovePath}`);
|
|
23311
|
+
break;
|
|
23312
|
+
}
|
|
23313
|
+
case "dirs": {
|
|
23314
|
+
const additionalDirs = await state.configStore.getAdditionalDirectories();
|
|
23315
|
+
const cwd = process.cwd();
|
|
23316
|
+
console.log("\n\u{1F4C2} Accessible Directories:\n");
|
|
23317
|
+
console.log(` \u{1F4C1} Working directory: ${cwd}`);
|
|
23318
|
+
if (additionalDirs.length > 0) {
|
|
23319
|
+
console.log("\n \u{1F4C1} Additional directories:");
|
|
23320
|
+
additionalDirs.forEach((d) => {
|
|
23321
|
+
console.log(` ${d}`);
|
|
23322
|
+
});
|
|
23323
|
+
} else {
|
|
23324
|
+
console.log("\n No additional directories configured.");
|
|
23325
|
+
console.log(" Use /add-dir <path> or --add-dir <path> flag to add directories.");
|
|
23326
|
+
}
|
|
23327
|
+
console.log("");
|
|
23328
|
+
break;
|
|
23329
|
+
}
|
|
23167
23330
|
case "sandbox:violations": {
|
|
23168
23331
|
const vStore = state.sandboxOrchestrator?.getViolationStore();
|
|
23169
23332
|
if (!vStore) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.35-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -111,10 +111,10 @@
|
|
|
111
111
|
},
|
|
112
112
|
"devDependencies": {
|
|
113
113
|
"@bike4mind/agents": "0.1.0",
|
|
114
|
-
"@bike4mind/common": "2.56.
|
|
115
|
-
"@bike4mind/mcp": "1.32.
|
|
116
|
-
"@bike4mind/services": "2.53.
|
|
117
|
-
"@bike4mind/utils": "2.9.
|
|
114
|
+
"@bike4mind/common": "2.56.1-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
115
|
+
"@bike4mind/mcp": "1.32.4-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
116
|
+
"@bike4mind/services": "2.53.1-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
117
|
+
"@bike4mind/utils": "2.9.2-fix-reply-disappears-on-refresh.20009+3d2fae3ac",
|
|
118
118
|
"@types/better-sqlite3": "^7.6.13",
|
|
119
119
|
"@types/diff": "^5.0.9",
|
|
120
120
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -135,5 +135,5 @@
|
|
|
135
135
|
"optionalDependencies": {
|
|
136
136
|
"@vscode/ripgrep": "^1.17.0"
|
|
137
137
|
},
|
|
138
|
-
"gitHead": "
|
|
138
|
+
"gitHead": "3d2fae3ac3f2b2cd7d12279e4f610b073002b96d"
|
|
139
139
|
}
|