@bike4mind/cli 0.2.25-cli-file-read-offset.18530 → 0.2.25-cli-file-read-offset.18541
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -0
- package/dist/{artifactExtractor-UWINLSHU.js → artifactExtractor-YLJA25ZH.js} +1 -1
- package/dist/{chunk-7L7YVDTP.js → chunk-CRG4F6FD.js} +1 -10
- package/dist/{chunk-AHVXP2NS.js → chunk-ETQCFCFT.js} +2 -2
- package/dist/{chunk-6ZSQC2VF.js → chunk-KGERFIL4.js} +1 -1
- package/dist/{chunk-U4GFPBS7.js → chunk-QDD3PG2I.js} +2 -2
- package/dist/{chunk-LPM3TSSU.js → chunk-TNLRJZRH.js} +2 -2
- package/dist/{create-OUHPA36R.js → create-RL7FTI2P.js} +3 -3
- package/dist/index.js +444 -80
- package/dist/{llmMarkdownGenerator-H5KBHEND.js → llmMarkdownGenerator-3SUOXGY3.js} +1 -1
- package/dist/{markdownGenerator-XVDGKPVZ.js → markdownGenerator-FYG7VXYP.js} +1 -1
- package/dist/{mementoService-NW6AADXH.js → mementoService-I6G6GHMI.js} +3 -3
- package/dist/{src-C6D5BBNC.js → src-7VD2AB4G.js} +1 -1
- package/dist/{src-YVHC5322.js → src-NJXYCMQ4.js} +2 -2
- package/dist/{subtractCredits-YLWP2W6I.js → subtractCredits-G43YXKVF.js} +3 -3
- package/package.json +6 -6
package/README.md
CHANGED
|
@@ -183,6 +183,7 @@ export SERPER_API_KEY="your-key-here"
|
|
|
183
183
|
- ✅ `current_datetime` - No API key needed
|
|
184
184
|
- ✅ `prompt_enhancement` - No API key needed
|
|
185
185
|
- ✅ `bash_execute` - No API key needed
|
|
186
|
+
- ✅ `recent_changes` - No API key needed (git-based file search by modification time)
|
|
186
187
|
- 🔑 `weather_info` - Requires `toolApiKeys.openweather`
|
|
187
188
|
- 🔑 `web_search` - Requires `toolApiKeys.serper`
|
|
188
189
|
- 🔑 `deep_research` - Requires `toolApiKeys.serper`
|
|
@@ -264,6 +265,36 @@ You can also run any MCP server via npx or custom executables:
|
|
|
264
265
|
|
|
265
266
|
**Note:** Internal MCP servers must be built and available in the `b4m-core/packages/mcp/dist/src/` directory. The CLI will automatically find them if you're running from the monorepo. For Docker-based servers, ensure Docker is installed and the image is accessible.
|
|
266
267
|
|
|
268
|
+
## Git-Aware Code Search
|
|
269
|
+
|
|
270
|
+
The CLI includes a `recent_changes` tool that uses git history to find recently modified files. This significantly speeds up debugging by narrowing the search space to recently changed code.
|
|
271
|
+
|
|
272
|
+
### Use Cases
|
|
273
|
+
|
|
274
|
+
- **Recent bug debugging:** "I just broke something, can you help fix it?"
|
|
275
|
+
- **Understanding feature development:** "What did we change for the new dashboard?"
|
|
276
|
+
- **Finding active development areas:** "What are we actively working on?"
|
|
277
|
+
- **Code review prep:** "What changed since last release?"
|
|
278
|
+
|
|
279
|
+
### Parameters
|
|
280
|
+
|
|
281
|
+
- `since` - Time range to search (default: "7 days ago")
|
|
282
|
+
- Examples: "2 hours ago", "3 days ago", "2025-01-01"
|
|
283
|
+
- `path` - Filter to specific directory (default: entire repo)
|
|
284
|
+
- Examples: "src/components", "apps/client", "**/*.test.ts"
|
|
285
|
+
- `limit` - Maximum files to return (default: 50)
|
|
286
|
+
- `include_stats` - Show lines added/removed (default: false)
|
|
287
|
+
|
|
288
|
+
### How It Works
|
|
289
|
+
|
|
290
|
+
The tool uses `git log` to track file modifications and returns:
|
|
291
|
+
- Files sorted by activity (most commits first)
|
|
292
|
+
- Commit messages for context
|
|
293
|
+
- Optional statistics showing lines changed
|
|
294
|
+
- Filtered results based on time and path
|
|
295
|
+
|
|
296
|
+
**Performance benefit:** Instead of searching 50+ files (5-10 minutes), find the 3 relevant files in ~30 seconds.
|
|
297
|
+
|
|
267
298
|
## Context Files
|
|
268
299
|
|
|
269
300
|
The CLI supports loading project-specific instructions from context files, similar to CLAUDE.md in Claude Code. These files provide persistent instructions that are automatically included in the agent's system prompt.
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CurationArtifactType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-CRG4F6FD.js";
|
|
5
5
|
|
|
6
6
|
// ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
|
|
7
7
|
var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
|
|
@@ -303,17 +303,8 @@ var b4mLLMTools = z5.enum([
|
|
|
303
303
|
"sunrise_sunset",
|
|
304
304
|
"iss_tracker",
|
|
305
305
|
"planet_visibility",
|
|
306
|
-
// File operation tools
|
|
307
|
-
"file_read",
|
|
308
|
-
"create_file",
|
|
309
|
-
"edit_local_file",
|
|
310
|
-
"glob_files",
|
|
311
|
-
"grep_search",
|
|
312
|
-
"delete_file",
|
|
313
306
|
// Knowledge base search
|
|
314
|
-
"search_knowledge_base"
|
|
315
|
-
// Shell execution
|
|
316
|
-
"bash_execute"
|
|
307
|
+
"search_knowledge_base"
|
|
317
308
|
]);
|
|
318
309
|
var B4MLLMToolsList = b4mLLMTools.options.map((tool) => tool);
|
|
319
310
|
var RechartsChartTypeSchema = z5.enum([
|
|
@@ -6,12 +6,12 @@ import {
|
|
|
6
6
|
getSettingsByNames,
|
|
7
7
|
obfuscateApiKey,
|
|
8
8
|
secureParameters
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-KGERFIL4.js";
|
|
10
10
|
import {
|
|
11
11
|
ApiKeyType,
|
|
12
12
|
MementoTier,
|
|
13
13
|
isSupportedEmbeddingModel
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-CRG4F6FD.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/apiKeyService/get.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-KGERFIL4.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-CRG4F6FD.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import {
|
|
3
3
|
BadRequestError,
|
|
4
4
|
secureParameters
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-KGERFIL4.js";
|
|
6
6
|
import {
|
|
7
7
|
CompletionApiUsageTransaction,
|
|
8
8
|
GenericCreditDeductTransaction,
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
TextGenerationUsageTransaction,
|
|
13
13
|
TransferCreditTransaction,
|
|
14
14
|
VideoGenerationUsageTransaction
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-CRG4F6FD.js";
|
|
16
16
|
|
|
17
17
|
// ../../b4m-core/packages/services/dist/src/creditService/subtractCredits.js
|
|
18
18
|
import { z } from "zod";
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
createFabFile,
|
|
4
4
|
createFabFileSchema
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-QDD3PG2I.js";
|
|
6
|
+
import "./chunk-KGERFIL4.js";
|
|
7
|
+
import "./chunk-CRG4F6FD.js";
|
|
8
8
|
import "./chunk-OCYRD7D6.js";
|
|
9
9
|
export {
|
|
10
10
|
createFabFile,
|
package/dist/index.js
CHANGED
|
@@ -5,15 +5,15 @@ import {
|
|
|
5
5
|
getEffectiveApiKey,
|
|
6
6
|
getOpenWeatherKey,
|
|
7
7
|
getSerperKey
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-ETQCFCFT.js";
|
|
9
9
|
import {
|
|
10
10
|
ConfigStore
|
|
11
11
|
} from "./chunk-23T2XGSZ.js";
|
|
12
12
|
import {
|
|
13
13
|
useCliStore
|
|
14
14
|
} from "./chunk-EIDW3VBS.js";
|
|
15
|
-
import "./chunk-
|
|
16
|
-
import "./chunk-
|
|
15
|
+
import "./chunk-TNLRJZRH.js";
|
|
16
|
+
import "./chunk-QDD3PG2I.js";
|
|
17
17
|
import {
|
|
18
18
|
BFLImageService,
|
|
19
19
|
BaseStorage,
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
OpenAIBackend,
|
|
26
26
|
OpenAIImageService,
|
|
27
27
|
XAIImageService
|
|
28
|
-
} from "./chunk-
|
|
28
|
+
} from "./chunk-KGERFIL4.js";
|
|
29
29
|
import {
|
|
30
30
|
AiEvents,
|
|
31
31
|
ApiKeyEvents,
|
|
@@ -81,7 +81,7 @@ import {
|
|
|
81
81
|
XAI_IMAGE_MODELS,
|
|
82
82
|
b4mLLMTools,
|
|
83
83
|
getMcpProviderMetadata
|
|
84
|
-
} from "./chunk-
|
|
84
|
+
} from "./chunk-CRG4F6FD.js";
|
|
85
85
|
import {
|
|
86
86
|
Logger
|
|
87
87
|
} from "./chunk-OCYRD7D6.js";
|
|
@@ -976,7 +976,7 @@ function InputPrompt({
|
|
|
976
976
|
setFileSelectedIndex(0);
|
|
977
977
|
}, [filteredFiles]);
|
|
978
978
|
useInput2(
|
|
979
|
-
(
|
|
979
|
+
(input, key) => {
|
|
980
980
|
if (fileAutocomplete?.active && filteredFiles.length > 0) {
|
|
981
981
|
if (key.upArrow) {
|
|
982
982
|
setFileSelectedIndex((prev) => prev > 0 ? prev - 1 : filteredFiles.length - 1);
|
|
@@ -1981,7 +1981,7 @@ import SelectInput4 from "ink-select-input";
|
|
|
1981
1981
|
function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
1982
1982
|
const [step, setStep] = useState6("selection");
|
|
1983
1983
|
const [selectedSession, setSelectedSession] = useState6(null);
|
|
1984
|
-
useInput7((
|
|
1984
|
+
useInput7((_input, key) => {
|
|
1985
1985
|
if (key.escape) {
|
|
1986
1986
|
if (step === "confirmation") {
|
|
1987
1987
|
setStep("selection");
|
|
@@ -1992,12 +1992,29 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
1992
1992
|
}
|
|
1993
1993
|
});
|
|
1994
1994
|
const hasUnsavedWork = currentSession && currentSession.messages.length > 0;
|
|
1995
|
+
const formatTimeAgo = (timestamp) => {
|
|
1996
|
+
const now = /* @__PURE__ */ new Date();
|
|
1997
|
+
const then = new Date(timestamp);
|
|
1998
|
+
const diffMs = now.getTime() - then.getTime();
|
|
1999
|
+
const diffMins = Math.floor(diffMs / 6e4);
|
|
2000
|
+
const diffHours = Math.floor(diffMs / 36e5);
|
|
2001
|
+
const diffDays = Math.floor(diffMs / 864e5);
|
|
2002
|
+
if (diffMins < 60) {
|
|
2003
|
+
return `${diffMins}m`;
|
|
2004
|
+
} else if (diffHours < 24) {
|
|
2005
|
+
return `${diffHours}h`;
|
|
2006
|
+
} else {
|
|
2007
|
+
return `${diffDays}d`;
|
|
2008
|
+
}
|
|
2009
|
+
};
|
|
1995
2010
|
const items = sessions.map((session, index) => {
|
|
1996
|
-
const
|
|
1997
|
-
const
|
|
2011
|
+
const userMessages = session.messages.filter((msg) => msg.role === "user");
|
|
2012
|
+
const lastUserMessage = userMessages[userMessages.length - 1];
|
|
2013
|
+
const preview = lastUserMessage ? lastUserMessage.content.slice(0, 50).replace(/\n/g, " ") + (lastUserMessage.content.length > 50 ? "..." : "") : "No messages";
|
|
2014
|
+
const timeAgo = formatTimeAgo(session.updatedAt);
|
|
1998
2015
|
return {
|
|
1999
|
-
|
|
2000
|
-
|
|
2016
|
+
key: session.id,
|
|
2017
|
+
label: `[${index + 1}] ${preview} (${timeAgo})`,
|
|
2001
2018
|
value: session
|
|
2002
2019
|
};
|
|
2003
2020
|
});
|
|
@@ -2237,6 +2254,9 @@ var SessionStore = class {
|
|
|
2237
2254
|
* Save a session to disk
|
|
2238
2255
|
*/
|
|
2239
2256
|
async save(session) {
|
|
2257
|
+
if (session.messages.length === 0) {
|
|
2258
|
+
throw new Error("Cannot save session with no messages");
|
|
2259
|
+
}
|
|
2240
2260
|
await this.init();
|
|
2241
2261
|
const filePath = path3.join(this.basePath, `${session.id}.json`);
|
|
2242
2262
|
try {
|
|
@@ -2279,13 +2299,14 @@ var SessionStore = class {
|
|
|
2279
2299
|
}
|
|
2280
2300
|
/**
|
|
2281
2301
|
* List all saved sessions
|
|
2302
|
+
* @param limit - Optional limit on number of sessions to return (returns most recent)
|
|
2282
2303
|
*/
|
|
2283
|
-
async list() {
|
|
2304
|
+
async list(limit) {
|
|
2284
2305
|
await this.init();
|
|
2285
2306
|
try {
|
|
2286
2307
|
const files = await fs3.readdir(this.basePath);
|
|
2287
2308
|
const jsonFiles = files.filter((f) => f.endsWith(".json"));
|
|
2288
|
-
const
|
|
2309
|
+
const sessionsWithFiles = await Promise.all(
|
|
2289
2310
|
jsonFiles.map(async (file) => {
|
|
2290
2311
|
const filePath = path3.join(this.basePath, file);
|
|
2291
2312
|
const data = await fs3.readFile(filePath, "utf-8");
|
|
@@ -2296,10 +2317,23 @@ var SessionStore = class {
|
|
|
2296
2317
|
}
|
|
2297
2318
|
return msg;
|
|
2298
2319
|
});
|
|
2299
|
-
return session;
|
|
2320
|
+
return { session, filePath };
|
|
2300
2321
|
})
|
|
2301
2322
|
);
|
|
2302
|
-
|
|
2323
|
+
const validSessions = [];
|
|
2324
|
+
for (const { session, filePath } of sessionsWithFiles) {
|
|
2325
|
+
if (session.messages.length === 0) {
|
|
2326
|
+
try {
|
|
2327
|
+
await fs3.unlink(filePath);
|
|
2328
|
+
} catch (error) {
|
|
2329
|
+
console.error(`Failed to delete empty session ${session.id}:`, error);
|
|
2330
|
+
}
|
|
2331
|
+
} else {
|
|
2332
|
+
validSessions.push(session);
|
|
2333
|
+
}
|
|
2334
|
+
}
|
|
2335
|
+
const sorted = validSessions.sort((a, b) => new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime());
|
|
2336
|
+
return limit ? sorted.slice(0, limit) : sorted;
|
|
2303
2337
|
} catch (error) {
|
|
2304
2338
|
console.error("Failed to list sessions:", error);
|
|
2305
2339
|
return [];
|
|
@@ -10178,8 +10212,343 @@ var editLocalFileTool = {
|
|
|
10178
10212
|
})
|
|
10179
10213
|
};
|
|
10180
10214
|
|
|
10215
|
+
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/recentChanges/index.js
|
|
10216
|
+
import { spawn as spawn2 } from "child_process";
|
|
10217
|
+
var DEFAULT_SINCE = "7 days ago";
|
|
10218
|
+
var DEFAULT_LIMIT = 50;
|
|
10219
|
+
var DEFAULT_INCLUDE_STATS = false;
|
|
10220
|
+
function parseStatusLine(line) {
|
|
10221
|
+
const results = [];
|
|
10222
|
+
if (line.length < 4)
|
|
10223
|
+
return results;
|
|
10224
|
+
const indexStatus = line[0];
|
|
10225
|
+
const workTreeStatus = line[1];
|
|
10226
|
+
const filePath = line.slice(3);
|
|
10227
|
+
const typeMap = {
|
|
10228
|
+
M: "modified",
|
|
10229
|
+
A: "added",
|
|
10230
|
+
D: "deleted",
|
|
10231
|
+
R: "renamed",
|
|
10232
|
+
C: "copied"
|
|
10233
|
+
};
|
|
10234
|
+
if (indexStatus !== " " && indexStatus !== "?") {
|
|
10235
|
+
results.push({
|
|
10236
|
+
path: filePath,
|
|
10237
|
+
status: "staged",
|
|
10238
|
+
type: typeMap[indexStatus] || "modified"
|
|
10239
|
+
});
|
|
10240
|
+
}
|
|
10241
|
+
if (workTreeStatus !== " " && workTreeStatus !== "?") {
|
|
10242
|
+
results.push({
|
|
10243
|
+
path: filePath,
|
|
10244
|
+
status: "unstaged",
|
|
10245
|
+
type: typeMap[workTreeStatus] || "modified"
|
|
10246
|
+
});
|
|
10247
|
+
}
|
|
10248
|
+
if (indexStatus === "?" && workTreeStatus === "?") {
|
|
10249
|
+
results.push({
|
|
10250
|
+
path: filePath,
|
|
10251
|
+
status: "untracked",
|
|
10252
|
+
type: "added"
|
|
10253
|
+
});
|
|
10254
|
+
}
|
|
10255
|
+
return results;
|
|
10256
|
+
}
|
|
10257
|
+
async function getWorkingTreeChanges(filterPath) {
|
|
10258
|
+
const args = ["status", "--porcelain"];
|
|
10259
|
+
if (filterPath) {
|
|
10260
|
+
args.push("--", filterPath);
|
|
10261
|
+
}
|
|
10262
|
+
return new Promise((resolve3) => {
|
|
10263
|
+
const proc = spawn2("git", args, {
|
|
10264
|
+
cwd: process.cwd(),
|
|
10265
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
10266
|
+
});
|
|
10267
|
+
let stdout = "";
|
|
10268
|
+
proc.stdout.on("data", (data) => {
|
|
10269
|
+
stdout += data.toString();
|
|
10270
|
+
});
|
|
10271
|
+
proc.on("close", (exitCode) => {
|
|
10272
|
+
if (exitCode !== 0) {
|
|
10273
|
+
resolve3([]);
|
|
10274
|
+
return;
|
|
10275
|
+
}
|
|
10276
|
+
const files = stdout.split("\n").filter((line) => line.length > 0).flatMap(parseStatusLine);
|
|
10277
|
+
resolve3(files);
|
|
10278
|
+
});
|
|
10279
|
+
proc.on("error", () => {
|
|
10280
|
+
resolve3([]);
|
|
10281
|
+
});
|
|
10282
|
+
});
|
|
10283
|
+
}
|
|
10284
|
+
async function getRecentChanges(params) {
|
|
10285
|
+
const { since = DEFAULT_SINCE, path: filterPath, limit = DEFAULT_LIMIT, include_stats = DEFAULT_INCLUDE_STATS } = params;
|
|
10286
|
+
const args = ["log", `--since=${since}`, "--name-only", "--pretty=format:"];
|
|
10287
|
+
if (filterPath) {
|
|
10288
|
+
args.push("--", filterPath);
|
|
10289
|
+
}
|
|
10290
|
+
return new Promise((resolve3) => {
|
|
10291
|
+
const proc = spawn2("git", args, {
|
|
10292
|
+
cwd: process.cwd(),
|
|
10293
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
10294
|
+
});
|
|
10295
|
+
let stdout = "";
|
|
10296
|
+
let stderr = "";
|
|
10297
|
+
proc.stdout.on("data", (data) => {
|
|
10298
|
+
stdout += data.toString();
|
|
10299
|
+
});
|
|
10300
|
+
proc.stderr.on("data", (data) => {
|
|
10301
|
+
stderr += data.toString();
|
|
10302
|
+
});
|
|
10303
|
+
proc.on("close", async (exitCode) => {
|
|
10304
|
+
const workingTree = await getWorkingTreeChanges(filterPath);
|
|
10305
|
+
if (exitCode !== 0) {
|
|
10306
|
+
resolve3({
|
|
10307
|
+
files: [],
|
|
10308
|
+
workingTree,
|
|
10309
|
+
timeRange: since,
|
|
10310
|
+
totalFiles: 0,
|
|
10311
|
+
error: stderr || "Git command failed"
|
|
10312
|
+
});
|
|
10313
|
+
return;
|
|
10314
|
+
}
|
|
10315
|
+
const files = stdout.split("\n").filter((line) => line.trim().length > 0).reduce((acc, filePath) => {
|
|
10316
|
+
const existing = acc.find((f) => f.path === filePath);
|
|
10317
|
+
if (existing) {
|
|
10318
|
+
existing.changes++;
|
|
10319
|
+
} else {
|
|
10320
|
+
acc.push({ path: filePath, changes: 1 });
|
|
10321
|
+
}
|
|
10322
|
+
return acc;
|
|
10323
|
+
}, []);
|
|
10324
|
+
files.sort((a, b) => b.changes - a.changes);
|
|
10325
|
+
const limitedFiles = files.slice(0, limit);
|
|
10326
|
+
if (include_stats && limitedFiles.length > 0) {
|
|
10327
|
+
const filesWithStats = await getFileStats(limitedFiles, since, filterPath);
|
|
10328
|
+
resolve3({
|
|
10329
|
+
files: filesWithStats,
|
|
10330
|
+
workingTree,
|
|
10331
|
+
timeRange: since,
|
|
10332
|
+
totalFiles: files.length
|
|
10333
|
+
});
|
|
10334
|
+
} else {
|
|
10335
|
+
resolve3({
|
|
10336
|
+
files: limitedFiles,
|
|
10337
|
+
workingTree,
|
|
10338
|
+
timeRange: since,
|
|
10339
|
+
totalFiles: files.length
|
|
10340
|
+
});
|
|
10341
|
+
}
|
|
10342
|
+
});
|
|
10343
|
+
proc.on("error", async (error) => {
|
|
10344
|
+
const workingTree = await getWorkingTreeChanges(filterPath);
|
|
10345
|
+
resolve3({
|
|
10346
|
+
files: [],
|
|
10347
|
+
workingTree,
|
|
10348
|
+
timeRange: since,
|
|
10349
|
+
totalFiles: 0,
|
|
10350
|
+
error: `Failed to execute git command: ${error.message}`
|
|
10351
|
+
});
|
|
10352
|
+
});
|
|
10353
|
+
});
|
|
10354
|
+
}
|
|
10355
|
+
async function getFileStats(files, since, filterPath) {
|
|
10356
|
+
const args = ["log", `--since=${since}`, "--numstat", "--pretty=format:"];
|
|
10357
|
+
if (filterPath) {
|
|
10358
|
+
args.push("--", filterPath);
|
|
10359
|
+
}
|
|
10360
|
+
return new Promise((resolve3) => {
|
|
10361
|
+
const proc = spawn2("git", args, {
|
|
10362
|
+
cwd: process.cwd(),
|
|
10363
|
+
stdio: ["ignore", "pipe", "pipe"]
|
|
10364
|
+
});
|
|
10365
|
+
let stdout = "";
|
|
10366
|
+
proc.stdout.on("data", (data) => {
|
|
10367
|
+
stdout += data.toString();
|
|
10368
|
+
});
|
|
10369
|
+
proc.on("close", () => {
|
|
10370
|
+
const stats = /* @__PURE__ */ new Map();
|
|
10371
|
+
stdout.split("\n").forEach((line) => {
|
|
10372
|
+
const match = line.match(/^(\d+)\s+(\d+)\s+(.+)$/);
|
|
10373
|
+
if (match) {
|
|
10374
|
+
const [, additions, deletions, filePath] = match;
|
|
10375
|
+
const existing = stats.get(filePath);
|
|
10376
|
+
if (existing) {
|
|
10377
|
+
existing.additions += parseInt(additions, 10);
|
|
10378
|
+
existing.deletions += parseInt(deletions, 10);
|
|
10379
|
+
} else {
|
|
10380
|
+
stats.set(filePath, {
|
|
10381
|
+
additions: parseInt(additions, 10),
|
|
10382
|
+
deletions: parseInt(deletions, 10)
|
|
10383
|
+
});
|
|
10384
|
+
}
|
|
10385
|
+
}
|
|
10386
|
+
});
|
|
10387
|
+
const result = files.map((file) => {
|
|
10388
|
+
const stat3 = stats.get(file.path);
|
|
10389
|
+
if (stat3) {
|
|
10390
|
+
return { ...file, ...stat3 };
|
|
10391
|
+
}
|
|
10392
|
+
return file;
|
|
10393
|
+
});
|
|
10394
|
+
resolve3(result);
|
|
10395
|
+
});
|
|
10396
|
+
proc.on("error", () => {
|
|
10397
|
+
resolve3(files);
|
|
10398
|
+
});
|
|
10399
|
+
});
|
|
10400
|
+
}
|
|
10401
|
+
function formatResult2(result) {
|
|
10402
|
+
const parts = [];
|
|
10403
|
+
if (result.error) {
|
|
10404
|
+
parts.push(`Error: ${result.error}`);
|
|
10405
|
+
parts.push("");
|
|
10406
|
+
parts.push("Make sure you are running this command in a git repository.");
|
|
10407
|
+
if (result.workingTree.length > 0) {
|
|
10408
|
+
parts.push("");
|
|
10409
|
+
parts.push(formatWorkingTree(result.workingTree));
|
|
10410
|
+
}
|
|
10411
|
+
return parts.join("\n");
|
|
10412
|
+
}
|
|
10413
|
+
if (result.workingTree.length > 0) {
|
|
10414
|
+
parts.push(formatWorkingTree(result.workingTree));
|
|
10415
|
+
parts.push("");
|
|
10416
|
+
}
|
|
10417
|
+
parts.push(`Recently committed files (${result.timeRange}):`);
|
|
10418
|
+
parts.push("");
|
|
10419
|
+
if (result.files.length === 0) {
|
|
10420
|
+
parts.push("No files changed in this time period.");
|
|
10421
|
+
} else {
|
|
10422
|
+
result.files.forEach((file, index) => {
|
|
10423
|
+
const stats = file.additions !== void 0 && file.deletions !== void 0 ? ` (+${file.additions}/-${file.deletions})` : "";
|
|
10424
|
+
parts.push(`${index + 1}. ${file.path} (${file.changes} commits)${stats}`);
|
|
10425
|
+
});
|
|
10426
|
+
if (result.totalFiles > result.files.length) {
|
|
10427
|
+
parts.push("");
|
|
10428
|
+
parts.push(`Showing ${result.files.length} of ${result.totalFiles} changed files.`);
|
|
10429
|
+
parts.push(`Use the 'limit' parameter to see more files.`);
|
|
10430
|
+
}
|
|
10431
|
+
}
|
|
10432
|
+
return parts.join("\n");
|
|
10433
|
+
}
|
|
10434
|
+
function formatWorkingTree(workingTree) {
|
|
10435
|
+
const parts = [];
|
|
10436
|
+
const staged = workingTree.filter((f) => f.status === "staged");
|
|
10437
|
+
const unstaged = workingTree.filter((f) => f.status === "unstaged");
|
|
10438
|
+
const untracked = workingTree.filter((f) => f.status === "untracked");
|
|
10439
|
+
parts.push("Working tree changes:");
|
|
10440
|
+
if (staged.length > 0) {
|
|
10441
|
+
parts.push("");
|
|
10442
|
+
parts.push(` Staged (${staged.length}):`);
|
|
10443
|
+
staged.forEach((f) => parts.push(` ${f.type}: ${f.path}`));
|
|
10444
|
+
}
|
|
10445
|
+
if (unstaged.length > 0) {
|
|
10446
|
+
parts.push("");
|
|
10447
|
+
parts.push(` Unstaged (${unstaged.length}):`);
|
|
10448
|
+
unstaged.forEach((f) => parts.push(` ${f.type}: ${f.path}`));
|
|
10449
|
+
}
|
|
10450
|
+
if (untracked.length > 0) {
|
|
10451
|
+
parts.push("");
|
|
10452
|
+
parts.push(` Untracked (${untracked.length}):`);
|
|
10453
|
+
untracked.forEach((f) => parts.push(` ${f.path}`));
|
|
10454
|
+
}
|
|
10455
|
+
return parts.join("\n");
|
|
10456
|
+
}
|
|
10457
|
+
var recentChangesTool = {
|
|
10458
|
+
name: "recent_changes",
|
|
10459
|
+
implementation: (context) => ({
|
|
10460
|
+
toolFn: async (value) => {
|
|
10461
|
+
const params = value;
|
|
10462
|
+
context.logger.info("RecentChanges: Getting recently changed files", {
|
|
10463
|
+
since: params.since || DEFAULT_SINCE,
|
|
10464
|
+
path: params.path || "all",
|
|
10465
|
+
limit: params.limit || DEFAULT_LIMIT,
|
|
10466
|
+
include_stats: params.include_stats || DEFAULT_INCLUDE_STATS
|
|
10467
|
+
});
|
|
10468
|
+
if (context.onStart) {
|
|
10469
|
+
await context.onStart("recent_changes", {
|
|
10470
|
+
since: params.since,
|
|
10471
|
+
path: params.path
|
|
10472
|
+
});
|
|
10473
|
+
}
|
|
10474
|
+
try {
|
|
10475
|
+
const result = await getRecentChanges(params);
|
|
10476
|
+
const formattedResult = formatResult2(result);
|
|
10477
|
+
context.logger.info("RecentChanges: Retrieved file changes", {
|
|
10478
|
+
totalFiles: result.totalFiles,
|
|
10479
|
+
displayedFiles: result.files.length,
|
|
10480
|
+
error: result.error
|
|
10481
|
+
});
|
|
10482
|
+
if (context.onFinish) {
|
|
10483
|
+
await context.onFinish("recent_changes", {
|
|
10484
|
+
totalFiles: result.totalFiles,
|
|
10485
|
+
displayedFiles: result.files.length
|
|
10486
|
+
});
|
|
10487
|
+
}
|
|
10488
|
+
return formattedResult;
|
|
10489
|
+
} catch (error) {
|
|
10490
|
+
context.logger.error("RecentChanges: Failed to get changes", error);
|
|
10491
|
+
if (context.onFinish) {
|
|
10492
|
+
await context.onFinish("recent_changes", {
|
|
10493
|
+
error: error instanceof Error ? error.message : "Unknown error"
|
|
10494
|
+
});
|
|
10495
|
+
}
|
|
10496
|
+
throw error;
|
|
10497
|
+
}
|
|
10498
|
+
},
|
|
10499
|
+
toolSchema: {
|
|
10500
|
+
name: "recent_changes",
|
|
10501
|
+
description: `Get a list of recently changed files in the git repository, including uncommitted working tree changes (staged, unstaged, and untracked files) plus committed changes sorted by activity. This tool is extremely useful for:
|
|
10502
|
+
|
|
10503
|
+
- **Debugging recent issues**: "Something broke after my last commit" \u2192 See exactly what changed
|
|
10504
|
+
- **Understanding active development**: "What are we working on?" \u2192 See most active files and current work-in-progress
|
|
10505
|
+
- **Code review preparation**: "What changed since last release?" \u2192 Get comprehensive file list
|
|
10506
|
+
- **Feature context**: "What files are part of the new dashboard?" \u2192 Filter by path
|
|
10507
|
+
- **Current work-in-progress**: See staged, unstaged, and untracked files alongside commit history
|
|
10508
|
+
|
|
10509
|
+
The tool combines git status (working tree) with git log (commit history) to give a complete picture of recent activity. Working tree changes are shown first, followed by committed files ranked by number of commits (most active first).
|
|
10510
|
+
|
|
10511
|
+
**Time Range Examples:**
|
|
10512
|
+
- "7 days ago" (default)
|
|
10513
|
+
- "2 hours ago"
|
|
10514
|
+
- "3 weeks ago"
|
|
10515
|
+
- "2025-01-01"
|
|
10516
|
+
- "yesterday"
|
|
10517
|
+
|
|
10518
|
+
**Path Filter Examples:**
|
|
10519
|
+
- "src/components" - Only files in components directory
|
|
10520
|
+
- "apps/client" - Only client app files
|
|
10521
|
+
- "**/*.test.ts" - Only test files (use glob patterns)
|
|
10522
|
+
|
|
10523
|
+
**Performance:** Very fast (< 1 second) since it only queries git metadata, not file contents.`,
|
|
10524
|
+
parameters: {
|
|
10525
|
+
type: "object",
|
|
10526
|
+
properties: {
|
|
10527
|
+
since: {
|
|
10528
|
+
type: "string",
|
|
10529
|
+
description: 'Time range for changes (default: "7 days ago"). Examples: "2 hours ago", "3 weeks ago", "2025-01-01", "yesterday".'
|
|
10530
|
+
},
|
|
10531
|
+
path: {
|
|
10532
|
+
type: "string",
|
|
10533
|
+
description: 'Optional path filter to limit results to specific directory or pattern. Examples: "src/components", "apps/client", "**/*.test.ts".'
|
|
10534
|
+
},
|
|
10535
|
+
limit: {
|
|
10536
|
+
type: "number",
|
|
10537
|
+
description: "Maximum number of files to return (default: 50). Files are sorted by activity (most commits first)."
|
|
10538
|
+
},
|
|
10539
|
+
include_stats: {
|
|
10540
|
+
type: "boolean",
|
|
10541
|
+
description: "Include lines added/removed statistics for each file (default: false). Note: This makes the command slightly slower."
|
|
10542
|
+
}
|
|
10543
|
+
},
|
|
10544
|
+
required: []
|
|
10545
|
+
}
|
|
10546
|
+
}
|
|
10547
|
+
})
|
|
10548
|
+
};
|
|
10549
|
+
|
|
10181
10550
|
// ../../b4m-core/packages/services/dist/src/llm/tools/index.js
|
|
10182
|
-
var
|
|
10551
|
+
var b4mTools = {
|
|
10183
10552
|
dice_roll: diceRollTool,
|
|
10184
10553
|
weather_info: weatherTool,
|
|
10185
10554
|
image_generation: imageGenerationTool,
|
|
@@ -10202,18 +10571,23 @@ var tools = {
|
|
|
10202
10571
|
sunrise_sunset: sunriseSunsetTool,
|
|
10203
10572
|
iss_tracker: issTrackerTool,
|
|
10204
10573
|
planet_visibility: planetVisibilityTool,
|
|
10574
|
+
// Knowledge base search
|
|
10575
|
+
search_knowledge_base: knowledgeBaseSearchTool
|
|
10576
|
+
};
|
|
10577
|
+
var cliOnlyTools = {
|
|
10578
|
+
// File operation tools
|
|
10205
10579
|
file_read: fileReadTool,
|
|
10206
10580
|
create_file: createFileTool,
|
|
10207
10581
|
edit_local_file: editLocalFileTool,
|
|
10208
10582
|
glob_files: globFilesTool,
|
|
10209
10583
|
grep_search: grepSearchTool,
|
|
10210
10584
|
delete_file: deleteFileTool,
|
|
10211
|
-
// Knowledge base search
|
|
10212
|
-
search_knowledge_base: knowledgeBaseSearchTool,
|
|
10213
10585
|
// Shell execution
|
|
10214
|
-
bash_execute: bashExecuteTool
|
|
10586
|
+
bash_execute: bashExecuteTool,
|
|
10587
|
+
// Git operations
|
|
10588
|
+
recent_changes: recentChangesTool
|
|
10215
10589
|
};
|
|
10216
|
-
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model) => {
|
|
10590
|
+
var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorage, statusUpdate, onStart, onFinish, llm, config, model, tools = b4mTools) => {
|
|
10217
10591
|
const context = {
|
|
10218
10592
|
userId,
|
|
10219
10593
|
user,
|
|
@@ -10234,9 +10608,9 @@ var generateTools = (userId, user, logger2, { db }, storage, imageGenerateStorag
|
|
|
10234
10608
|
};
|
|
10235
10609
|
var ATLASSIAN_RECONNECT_MESSAGE = "\u26A0\uFE0F Your Atlassian connection has expired.\n\nPlease reconnect your Atlassian account in Settings > Connected Apps to continue using Confluence and Jira tools.";
|
|
10236
10610
|
var generateMcpTools = async (mcpData) => {
|
|
10237
|
-
let
|
|
10611
|
+
let tools;
|
|
10238
10612
|
try {
|
|
10239
|
-
|
|
10613
|
+
tools = await mcpData.getTools();
|
|
10240
10614
|
} catch (error) {
|
|
10241
10615
|
const errorName = error instanceof Error ? error.name : "";
|
|
10242
10616
|
if (errorName === "AtlassianReconnectRequiredError") {
|
|
@@ -10245,12 +10619,12 @@ var generateMcpTools = async (mcpData) => {
|
|
|
10245
10619
|
}
|
|
10246
10620
|
throw error;
|
|
10247
10621
|
}
|
|
10248
|
-
const toolList = Array.isArray(
|
|
10249
|
-
if (!Array.isArray(
|
|
10250
|
-
console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(
|
|
10622
|
+
const toolList = Array.isArray(tools) ? tools : tools?.tools || [];
|
|
10623
|
+
if (!Array.isArray(tools)) {
|
|
10624
|
+
console.warn(`MCP server ${mcpData.serverName} returned unexpected tools payload:`, JSON.stringify(tools));
|
|
10251
10625
|
}
|
|
10252
10626
|
if (!Array.isArray(toolList)) {
|
|
10253
|
-
throw new Error(`Expected getTools() to return an array, but got ${typeof
|
|
10627
|
+
throw new Error(`Expected getTools() to return an array, but got ${typeof tools}`);
|
|
10254
10628
|
}
|
|
10255
10629
|
const result = toolList.map((item) => {
|
|
10256
10630
|
const { name: originalToolName, ...rest } = item;
|
|
@@ -10589,7 +10963,8 @@ var LOCAL_TOOLS = [
|
|
|
10589
10963
|
"dice_roll",
|
|
10590
10964
|
"math_evaluate",
|
|
10591
10965
|
"current_datetime",
|
|
10592
|
-
"bash_execute"
|
|
10966
|
+
"bash_execute",
|
|
10967
|
+
"recent_changes"
|
|
10593
10968
|
];
|
|
10594
10969
|
function isServerTool(toolName) {
|
|
10595
10970
|
return SERVER_TOOLS.includes(toolName);
|
|
@@ -10615,11 +10990,11 @@ async function executeTool(toolName, input, apiClient, localToolFn) {
|
|
|
10615
10990
|
}
|
|
10616
10991
|
|
|
10617
10992
|
// src/utils/shellRunner.ts
|
|
10618
|
-
import { spawn as
|
|
10993
|
+
import { spawn as spawn3 } from "child_process";
|
|
10619
10994
|
async function runShellCommand(options) {
|
|
10620
10995
|
const { command, cwd, timeoutMs, env, stdin } = options;
|
|
10621
10996
|
return new Promise((resolve3) => {
|
|
10622
|
-
const child =
|
|
10997
|
+
const child = spawn3("bash", ["-c", command], {
|
|
10623
10998
|
cwd,
|
|
10624
10999
|
env,
|
|
10625
11000
|
stdio: ["pipe", "pipe", "pipe"]
|
|
@@ -11048,37 +11423,21 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
11048
11423
|
adminSettings: mockAdminSettings
|
|
11049
11424
|
}
|
|
11050
11425
|
};
|
|
11051
|
-
const
|
|
11426
|
+
const enabledB4mToolNames = [
|
|
11052
11427
|
// Local-only tools (no external API keys needed)
|
|
11053
|
-
dice_roll
|
|
11054
|
-
math_evaluate
|
|
11055
|
-
current_datetime
|
|
11056
|
-
prompt_enhancement
|
|
11057
|
-
// File operation tools (CLI-specific, local execution)
|
|
11058
|
-
file_read: {},
|
|
11059
|
-
create_file: {},
|
|
11060
|
-
edit_local_file: {},
|
|
11061
|
-
glob_files: {},
|
|
11062
|
-
grep_search: {},
|
|
11063
|
-
delete_file: {},
|
|
11064
|
-
// Shell execution (always requires permission)
|
|
11065
|
-
bash_execute: {},
|
|
11428
|
+
"dice_roll",
|
|
11429
|
+
"math_evaluate",
|
|
11430
|
+
"current_datetime",
|
|
11431
|
+
"prompt_enhancement",
|
|
11066
11432
|
// Server-side tools (executed via /api/ai/v1/tools Lambda)
|
|
11067
|
-
|
|
11068
|
-
|
|
11069
|
-
|
|
11070
|
-
|
|
11071
|
-
|
|
11072
|
-
|
|
11073
|
-
|
|
11074
|
-
|
|
11075
|
-
// image_generation: undefined,
|
|
11076
|
-
// edit_image: undefined,
|
|
11077
|
-
// mermaid_chart: undefined,
|
|
11078
|
-
// recharts: undefined,
|
|
11079
|
-
// edit_file: undefined,
|
|
11080
|
-
// deep_research: undefined,
|
|
11081
|
-
};
|
|
11433
|
+
"weather_info",
|
|
11434
|
+
"web_search",
|
|
11435
|
+
"web_fetch"
|
|
11436
|
+
];
|
|
11437
|
+
const filteredB4mTools = Object.fromEntries(
|
|
11438
|
+
enabledB4mToolNames.filter((name) => name in b4mTools).map((name) => [name, b4mTools[name]])
|
|
11439
|
+
);
|
|
11440
|
+
const tools_to_generate = { ...filteredB4mTools, ...cliOnlyTools };
|
|
11082
11441
|
const toolsMap = generateTools(
|
|
11083
11442
|
userId,
|
|
11084
11443
|
user,
|
|
@@ -11091,17 +11450,18 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
11091
11450
|
onStart,
|
|
11092
11451
|
onFinish,
|
|
11093
11452
|
llm,
|
|
11094
|
-
|
|
11095
|
-
model
|
|
11453
|
+
{},
|
|
11454
|
+
model,
|
|
11455
|
+
tools_to_generate
|
|
11096
11456
|
);
|
|
11097
|
-
let
|
|
11457
|
+
let tools = Object.entries(toolsMap).map(
|
|
11098
11458
|
([_, tool]) => wrapToolWithPermission(tool, permissionManager, showPermissionPrompt, agentContext, configStore, apiClient)
|
|
11099
11459
|
);
|
|
11100
11460
|
if (toolFilter) {
|
|
11101
11461
|
const { allowedTools, deniedTools } = toolFilter;
|
|
11102
11462
|
const normalizedAllowed = allowedTools?.map(normalizeToolName);
|
|
11103
11463
|
const normalizedDenied = deniedTools?.map(normalizeToolName);
|
|
11104
|
-
|
|
11464
|
+
tools = tools.filter((tool) => {
|
|
11105
11465
|
const toolName = tool.toolSchema.name;
|
|
11106
11466
|
if (normalizedDenied && normalizedDenied.includes(toolName)) {
|
|
11107
11467
|
return false;
|
|
@@ -11112,7 +11472,7 @@ function generateCliTools(userId, llm, model, permissionManager, showPermissionP
|
|
|
11112
11472
|
return true;
|
|
11113
11473
|
});
|
|
11114
11474
|
}
|
|
11115
|
-
return { tools
|
|
11475
|
+
return { tools, agentContext };
|
|
11116
11476
|
}
|
|
11117
11477
|
|
|
11118
11478
|
// src/utils/PermissionManager.ts
|
|
@@ -11490,9 +11850,9 @@ var TokenCounter = class {
|
|
|
11490
11850
|
* Count tokens in tool schemas.
|
|
11491
11851
|
* Tool schemas are sent as part of the API call and consume context.
|
|
11492
11852
|
*/
|
|
11493
|
-
countToolSchemaTokens(
|
|
11494
|
-
if (
|
|
11495
|
-
const schemaText =
|
|
11853
|
+
countToolSchemaTokens(tools) {
|
|
11854
|
+
if (tools.length === 0) return 0;
|
|
11855
|
+
const schemaText = tools.map(
|
|
11496
11856
|
({ toolSchema }) => `Tool: ${toolSchema.name}
|
|
11497
11857
|
Description: ${toolSchema.description}
|
|
11498
11858
|
Parameters: ${JSON.stringify(toolSchema.parameters)}`
|
|
@@ -11794,14 +12154,14 @@ var McpManager = class {
|
|
|
11794
12154
|
getTools: async () => client.tools,
|
|
11795
12155
|
callTool: async (name, args) => client.callTool(name, args)
|
|
11796
12156
|
};
|
|
11797
|
-
const
|
|
12157
|
+
const tools = await generateMcpTools(mcpData);
|
|
11798
12158
|
this.servers.set(serverConfig.name, {
|
|
11799
12159
|
name: serverConfig.name,
|
|
11800
12160
|
client,
|
|
11801
|
-
tools
|
|
12161
|
+
tools
|
|
11802
12162
|
});
|
|
11803
12163
|
this.connectionStates.set(serverConfig.name, "connected");
|
|
11804
|
-
logger.debug(`\u2705 Connected to ${serverConfig.name} (${
|
|
12164
|
+
logger.debug(`\u2705 Connected to ${serverConfig.name} (${tools.length} tools)`);
|
|
11805
12165
|
} catch (error) {
|
|
11806
12166
|
this.connectionStates.set(serverConfig.name, "failed");
|
|
11807
12167
|
logger.debug(`\u274C Failed to connect to ${serverConfig.name}: ${error}`);
|
|
@@ -12686,7 +13046,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
12686
13046
|
// package.json
|
|
12687
13047
|
var package_default = {
|
|
12688
13048
|
name: "@bike4mind/cli",
|
|
12689
|
-
version: "0.2.25-cli-file-read-offset.
|
|
13049
|
+
version: "0.2.25-cli-file-read-offset.18541+a5717c121",
|
|
12690
13050
|
type: "module",
|
|
12691
13051
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
12692
13052
|
license: "UNLICENSED",
|
|
@@ -12794,10 +13154,10 @@ var package_default = {
|
|
|
12794
13154
|
},
|
|
12795
13155
|
devDependencies: {
|
|
12796
13156
|
"@bike4mind/agents": "0.1.0",
|
|
12797
|
-
"@bike4mind/common": "2.47.2-cli-file-read-offset.
|
|
12798
|
-
"@bike4mind/mcp": "1.28.1-cli-file-read-offset.
|
|
12799
|
-
"@bike4mind/services": "2.45.2-cli-file-read-offset.
|
|
12800
|
-
"@bike4mind/utils": "2.3.4-cli-file-read-offset.
|
|
13157
|
+
"@bike4mind/common": "2.47.2-cli-file-read-offset.18541+a5717c121",
|
|
13158
|
+
"@bike4mind/mcp": "1.28.1-cli-file-read-offset.18541+a5717c121",
|
|
13159
|
+
"@bike4mind/services": "2.45.2-cli-file-read-offset.18541+a5717c121",
|
|
13160
|
+
"@bike4mind/utils": "2.3.4-cli-file-read-offset.18541+a5717c121",
|
|
12801
13161
|
"@types/better-sqlite3": "^7.6.13",
|
|
12802
13162
|
"@types/diff": "^5.0.9",
|
|
12803
13163
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -12814,7 +13174,7 @@ var package_default = {
|
|
|
12814
13174
|
optionalDependencies: {
|
|
12815
13175
|
"@vscode/ripgrep": "^1.17.0"
|
|
12816
13176
|
},
|
|
12817
|
-
gitHead: "
|
|
13177
|
+
gitHead: "a5717c121a35ad3b958b4f8471fe5a3b94781c42"
|
|
12818
13178
|
};
|
|
12819
13179
|
|
|
12820
13180
|
// src/config/constants.ts
|
|
@@ -14099,7 +14459,7 @@ function CliApp() {
|
|
|
14099
14459
|
currentAgent: null,
|
|
14100
14460
|
observationQueue: []
|
|
14101
14461
|
};
|
|
14102
|
-
const { tools:
|
|
14462
|
+
const { tools: b4mTools2 } = generateCliTools(
|
|
14103
14463
|
config.userId,
|
|
14104
14464
|
llm,
|
|
14105
14465
|
modelInfo.id,
|
|
@@ -14109,7 +14469,7 @@ function CliApp() {
|
|
|
14109
14469
|
state.configStore,
|
|
14110
14470
|
apiClient
|
|
14111
14471
|
);
|
|
14112
|
-
console.log(`\u{1F6E0}\uFE0F Loaded ${
|
|
14472
|
+
console.log(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
|
|
14113
14473
|
const mcpManager = new McpManager(config);
|
|
14114
14474
|
await mcpManager.initialize();
|
|
14115
14475
|
const mcpTools = mcpManager.getTools();
|
|
@@ -14151,7 +14511,7 @@ function CliApp() {
|
|
|
14151
14511
|
if (skillTool) {
|
|
14152
14512
|
cliTools.push(skillTool);
|
|
14153
14513
|
}
|
|
14154
|
-
const allTools = [...
|
|
14514
|
+
const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
|
|
14155
14515
|
console.log(`\u{1F4C2} Working directory: ${process.cwd()}`);
|
|
14156
14516
|
console.log(`\u{1F916} Subagent delegation enabled (explore, plan, review)`);
|
|
14157
14517
|
if (skillTool) {
|
|
@@ -14161,7 +14521,7 @@ function CliApp() {
|
|
|
14161
14521
|
}
|
|
14162
14522
|
}
|
|
14163
14523
|
logger.debug(
|
|
14164
|
-
`Total tools available to agent: ${allTools.length} (${
|
|
14524
|
+
`Total tools available to agent: ${allTools.length} (${b4mTools2.length} B4M + ${mcpTools.length} MCP + ${cliTools.length} CLI)`
|
|
14165
14525
|
);
|
|
14166
14526
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
14167
14527
|
const contextResult = await loadContextFiles(projectDir);
|
|
@@ -14846,13 +15206,17 @@ Custom Commands:
|
|
|
14846
15206
|
console.log("No active session to save");
|
|
14847
15207
|
return;
|
|
14848
15208
|
}
|
|
15209
|
+
if (state.session.messages.length === 0) {
|
|
15210
|
+
console.log("\u274C Cannot save session with no messages");
|
|
15211
|
+
return;
|
|
15212
|
+
}
|
|
14849
15213
|
const sessionName = args.join(" ") || state.session.name;
|
|
14850
15214
|
state.session.name = sessionName;
|
|
14851
15215
|
await state.sessionStore.save(state.session);
|
|
14852
15216
|
console.log(`\u2705 Session saved as "${sessionName}"`);
|
|
14853
15217
|
break;
|
|
14854
15218
|
case "sessions": {
|
|
14855
|
-
const sessions = await state.sessionStore.list();
|
|
15219
|
+
const sessions = await state.sessionStore.list(20);
|
|
14856
15220
|
if (sessions.length === 0) {
|
|
14857
15221
|
console.log("\n\u{1F4DA} No saved sessions found.");
|
|
14858
15222
|
console.log("\u{1F4A1} Use /save <name> to save your current session.\n");
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
findMostSimilarMemento,
|
|
4
4
|
getRelevantMementos
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-ETQCFCFT.js";
|
|
6
|
+
import "./chunk-KGERFIL4.js";
|
|
7
|
+
import "./chunk-CRG4F6FD.js";
|
|
8
8
|
import "./chunk-OCYRD7D6.js";
|
|
9
9
|
export {
|
|
10
10
|
findMostSimilarMemento,
|
|
@@ -132,8 +132,8 @@ import {
|
|
|
132
132
|
validateMermaidSyntax,
|
|
133
133
|
warmUpSettingsCache,
|
|
134
134
|
withRetry
|
|
135
|
-
} from "./chunk-
|
|
136
|
-
import "./chunk-
|
|
135
|
+
} from "./chunk-KGERFIL4.js";
|
|
136
|
+
import "./chunk-CRG4F6FD.js";
|
|
137
137
|
import {
|
|
138
138
|
Logger,
|
|
139
139
|
NotificationDeduplicator,
|
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
import {
|
|
3
3
|
SubtractCreditsSchema,
|
|
4
4
|
subtractCredits
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
7
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-TNLRJZRH.js";
|
|
6
|
+
import "./chunk-KGERFIL4.js";
|
|
7
|
+
import "./chunk-CRG4F6FD.js";
|
|
8
8
|
import "./chunk-OCYRD7D6.js";
|
|
9
9
|
export {
|
|
10
10
|
SubtractCreditsSchema,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bike4mind/cli",
|
|
3
|
-
"version": "0.2.25-cli-file-read-offset.
|
|
3
|
+
"version": "0.2.25-cli-file-read-offset.18541+a5717c121",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -108,10 +108,10 @@
|
|
|
108
108
|
},
|
|
109
109
|
"devDependencies": {
|
|
110
110
|
"@bike4mind/agents": "0.1.0",
|
|
111
|
-
"@bike4mind/common": "2.47.2-cli-file-read-offset.
|
|
112
|
-
"@bike4mind/mcp": "1.28.1-cli-file-read-offset.
|
|
113
|
-
"@bike4mind/services": "2.45.2-cli-file-read-offset.
|
|
114
|
-
"@bike4mind/utils": "2.3.4-cli-file-read-offset.
|
|
111
|
+
"@bike4mind/common": "2.47.2-cli-file-read-offset.18541+a5717c121",
|
|
112
|
+
"@bike4mind/mcp": "1.28.1-cli-file-read-offset.18541+a5717c121",
|
|
113
|
+
"@bike4mind/services": "2.45.2-cli-file-read-offset.18541+a5717c121",
|
|
114
|
+
"@bike4mind/utils": "2.3.4-cli-file-read-offset.18541+a5717c121",
|
|
115
115
|
"@types/better-sqlite3": "^7.6.13",
|
|
116
116
|
"@types/diff": "^5.0.9",
|
|
117
117
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -128,5 +128,5 @@
|
|
|
128
128
|
"optionalDependencies": {
|
|
129
129
|
"@vscode/ripgrep": "^1.17.0"
|
|
130
130
|
},
|
|
131
|
-
"gitHead": "
|
|
131
|
+
"gitHead": "a5717c121a35ad3b958b4f8471fe5a3b94781c42"
|
|
132
132
|
}
|