@bike4mind/cli 0.2.29-cli-resume-command.18763 → 0.2.29-cli-minimal-ui.18783
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{artifactExtractor-36XHJYOZ.js → artifactExtractor-7Z2TM2RR.js} +1 -1
- package/dist/{chunk-VGYTNJXN.js → chunk-4XFX3V4G.js} +2 -2
- package/dist/{chunk-JJBDHUGY.js → chunk-G7PAI2YH.js} +2 -2
- package/dist/{chunk-UNOJBVD2.js → chunk-HDIXO6H3.js} +1 -1
- package/dist/{chunk-23T2XGSZ.js → chunk-LBTTUQJM.js} +290 -33
- package/dist/{chunk-ZEMWV6IR.js → chunk-MDG22DS7.js} +2 -2
- package/dist/{chunk-XJRPAAUS.js → chunk-ODYASVT6.js} +15 -2
- package/dist/commands/mcpCommand.js +1 -1
- package/dist/{create-NGI7IIQ4.js → create-45ZV3EJT.js} +3 -3
- package/dist/index.js +206 -441
- package/dist/{llmMarkdownGenerator-JDYKJUEC.js → llmMarkdownGenerator-4HLWASZ4.js} +1 -1
- package/dist/{markdownGenerator-QXBC2EW5.js → markdownGenerator-2Y3GWJYH.js} +1 -1
- package/dist/{mementoService-X35OMHVC.js → mementoService-OVWA5PPV.js} +3 -3
- package/dist/{src-CBU6EAO3.js → src-V6E375BJ.js} +2 -2
- package/dist/{src-6NIYIWZD.js → src-Z6YUBFWA.js} +1 -1
- package/dist/{subtractCredits-RL6JVDMI.js → subtractCredits-KGQCY6KQ.js} +3 -3
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -5,16 +5,17 @@ import {
|
|
|
5
5
|
getEffectiveApiKey,
|
|
6
6
|
getOpenWeatherKey,
|
|
7
7
|
getSerperKey
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-4XFX3V4G.js";
|
|
9
9
|
import {
|
|
10
|
-
ConfigStore
|
|
11
|
-
|
|
10
|
+
ConfigStore,
|
|
11
|
+
logger
|
|
12
|
+
} from "./chunk-LBTTUQJM.js";
|
|
12
13
|
import {
|
|
13
14
|
selectActiveBackgroundAgents,
|
|
14
15
|
useCliStore
|
|
15
16
|
} from "./chunk-TVW4ZESU.js";
|
|
16
|
-
import "./chunk-
|
|
17
|
-
import "./chunk-
|
|
17
|
+
import "./chunk-G7PAI2YH.js";
|
|
18
|
+
import "./chunk-MDG22DS7.js";
|
|
18
19
|
import {
|
|
19
20
|
BFLImageService,
|
|
20
21
|
BaseStorage,
|
|
@@ -26,7 +27,7 @@ import {
|
|
|
26
27
|
OpenAIBackend,
|
|
27
28
|
OpenAIImageService,
|
|
28
29
|
XAIImageService
|
|
29
|
-
} from "./chunk-
|
|
30
|
+
} from "./chunk-HDIXO6H3.js";
|
|
30
31
|
import {
|
|
31
32
|
AiEvents,
|
|
32
33
|
ApiKeyEvents,
|
|
@@ -82,7 +83,7 @@ import {
|
|
|
82
83
|
XAI_IMAGE_MODELS,
|
|
83
84
|
b4mLLMTools,
|
|
84
85
|
getMcpProviderMetadata
|
|
85
|
-
} from "./chunk-
|
|
86
|
+
} from "./chunk-ODYASVT6.js";
|
|
86
87
|
import {
|
|
87
88
|
Logger
|
|
88
89
|
} from "./chunk-OCYRD7D6.js";
|
|
@@ -1113,11 +1114,11 @@ function InputPrompt({
|
|
|
1113
1114
|
}
|
|
1114
1115
|
};
|
|
1115
1116
|
const getPlaceholder = () => {
|
|
1116
|
-
if (disabled) return "
|
|
1117
|
+
if (disabled) return "";
|
|
1117
1118
|
if (isBashMode) return "Enter shell command to execute...";
|
|
1118
1119
|
return "Type your message, /help for commands, @file to reference, or ! for bash";
|
|
1119
1120
|
};
|
|
1120
|
-
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: isBashMode ? "yellow" : "cyan" }, isBashMode ? "$ " : "> "), /* @__PURE__ */ React5.createElement(
|
|
1121
|
+
return /* @__PURE__ */ React5.createElement(Box4, { flexDirection: "column" }, /* @__PURE__ */ React5.createElement(Box4, null, /* @__PURE__ */ React5.createElement(Text5, { bold: true, color: disabled ? "gray" : isBashMode ? "yellow" : "cyan", dimColor: disabled }, isBashMode ? "$ " : "> "), /* @__PURE__ */ React5.createElement(
|
|
1121
1122
|
CustomTextInput,
|
|
1122
1123
|
{
|
|
1123
1124
|
key: inputKey.current,
|
|
@@ -1140,7 +1141,7 @@ import React6 from "react";
|
|
|
1140
1141
|
import { Box as Box5, Text as Text6 } from "ink";
|
|
1141
1142
|
import Spinner from "ink-spinner";
|
|
1142
1143
|
var ThoughtStream = React6.memo(function ThoughtStream2({ isThinking }) {
|
|
1143
|
-
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column"
|
|
1144
|
+
return /* @__PURE__ */ React6.createElement(Box5, { flexDirection: "column" }, isThinking && /* @__PURE__ */ React6.createElement(Box5, null, /* @__PURE__ */ React6.createElement(Text6, { color: "yellow" }, /* @__PURE__ */ React6.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React6.createElement(Text6, null, " Thinking...")));
|
|
1144
1145
|
});
|
|
1145
1146
|
|
|
1146
1147
|
// src/components/AgentThinking.tsx
|
|
@@ -1708,33 +1709,21 @@ function truncateValue(value, maxLength) {
|
|
|
1708
1709
|
}
|
|
1709
1710
|
return str.slice(0, maxLength) + "...";
|
|
1710
1711
|
}
|
|
1711
|
-
function getRoleDisplay(role) {
|
|
1712
|
-
switch (role) {
|
|
1713
|
-
case "user":
|
|
1714
|
-
return { color: "cyan", label: "\u{1F464} You" };
|
|
1715
|
-
case "system":
|
|
1716
|
-
return { color: "gray", label: "\u2139\uFE0F System" };
|
|
1717
|
-
default:
|
|
1718
|
-
return { color: "green", label: "\u{1F916} Assistant" };
|
|
1719
|
-
}
|
|
1720
|
-
}
|
|
1721
1712
|
var MessageItem = React14.memo(function MessageItem2({ message }) {
|
|
1722
1713
|
const isUser = message.role === "user";
|
|
1723
|
-
|
|
1724
|
-
const roleDisplay = getRoleDisplay(message.role);
|
|
1725
|
-
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column", marginBottom: 1 }, !isContinuation && /* @__PURE__ */ React14.createElement(Box13, null, /* @__PURE__ */ React14.createElement(Text13, { bold: true, color: roleDisplay.color }, roleDisplay.label), isUser && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, " \u2022 ", new Date(message.timestamp).toLocaleTimeString())), isUser && message.content && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, { backgroundColor: "whiteBright", color: "black" }, " ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.length > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true, bold: true }, "\u{1F527} Agent Reasoning Trace (", message.metadata.steps.filter((s) => s.type === "action").length, " ", "tools used, ", message.metadata.steps.length, " total steps)", message.metadata.tokenUsage && ` \u2022 ${message.metadata.tokenUsage.total} tokens`), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, "Step types: ", message.metadata.steps.map((s) => s.type).join(", ")), message.metadata.steps.map((step, idx) => {
|
|
1714
|
+
return /* @__PURE__ */ React14.createElement(Box13, { flexDirection: "column" }, isUser && message.content && /* @__PURE__ */ React14.createElement(Box13, { marginBottom: 1 }, /* @__PURE__ */ React14.createElement(Text13, { backgroundColor: "whiteBright", color: "black" }, "\u276F ", message.content, " ")), !isUser && message.metadata?.steps && message.metadata.steps.filter((s) => ["thought", "action"].includes(s.type)).length > 0 && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, flexDirection: "column", marginBottom: 1 }, message.metadata.steps.map((step, idx) => {
|
|
1726
1715
|
if (step.type === "thought") {
|
|
1727
|
-
return /* @__PURE__ */ React14.createElement(Box13, { key: idx,
|
|
1716
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "blue" }, "\u{1F4AD} Thought:"), /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` ${step.content}`));
|
|
1728
1717
|
}
|
|
1729
1718
|
if (step.type === "action") {
|
|
1730
1719
|
const toolName = step.metadata?.toolName || "unknown";
|
|
1731
1720
|
const toolInput = step.metadata?.toolInput;
|
|
1732
1721
|
const observationStep = message.metadata?.steps?.[idx + 1];
|
|
1733
1722
|
const result = observationStep?.type === "observation" ? observationStep.content : null;
|
|
1734
|
-
return /* @__PURE__ */ React14.createElement(Box13, { key: idx,
|
|
1723
|
+
return /* @__PURE__ */ React14.createElement(Box13, { key: idx, marginTop: 1, flexDirection: "column" }, /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u{1F527} ", toolName), toolInput && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Input: ${truncateValue(toolInput, 100)}`), result && /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, ` Result: ${truncateValue(result, 200)}`));
|
|
1735
1724
|
}
|
|
1736
1725
|
return null;
|
|
1737
|
-
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2,
|
|
1726
|
+
}).filter(Boolean)), !isUser && message.content !== "..." && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2, marginBottom: 1 }, message.metadata?.permissionDenied ? /* @__PURE__ */ React14.createElement(Text13, { color: "yellow" }, "\u26A0\uFE0F ", message.content) : /* @__PURE__ */ React14.createElement(MarkdownRenderer, { content: message.content })), message.metadata?.tokenUsage && (!message.metadata.steps || message.metadata.steps.length === 0) && /* @__PURE__ */ React14.createElement(Box13, { paddingLeft: 2 }, /* @__PURE__ */ React14.createElement(Text13, { dimColor: true }, `${message.metadata.tokenUsage.total} tokens`)));
|
|
1738
1727
|
});
|
|
1739
1728
|
|
|
1740
1729
|
// src/utils/processFileReferences.ts
|
|
@@ -2164,7 +2153,7 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
2164
2153
|
{
|
|
2165
2154
|
items,
|
|
2166
2155
|
onSelect: handleSelectionSelect,
|
|
2167
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 },
|
|
2156
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, label))
|
|
2168
2157
|
}
|
|
2169
2158
|
), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to cancel")));
|
|
2170
2159
|
}
|
|
@@ -2177,7 +2166,7 @@ function SessionSelector({ sessions, currentSession, onSelect, onCancel }) {
|
|
|
2177
2166
|
{
|
|
2178
2167
|
items: confirmationItems,
|
|
2179
2168
|
onSelect: handleConfirmationSelect,
|
|
2180
|
-
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 },
|
|
2169
|
+
itemComponent: ({ isSelected, label }) => /* @__PURE__ */ React19.createElement(Box18, null, /* @__PURE__ */ React19.createElement(Text18, { color: isSelected ? "cyan" : void 0 }, label))
|
|
2181
2170
|
}
|
|
2182
2171
|
), /* @__PURE__ */ React19.createElement(Box18, { marginTop: 1 }, /* @__PURE__ */ React19.createElement(Text18, { dimColor: true }, "Use \u2191\u2193 arrows to navigate, Enter to select, Esc to go back")));
|
|
2183
2172
|
}
|
|
@@ -2624,271 +2613,13 @@ var CommandHistoryStore = class {
|
|
|
2624
2613
|
};
|
|
2625
2614
|
|
|
2626
2615
|
// src/storage/CustomCommandStore.ts
|
|
2627
|
-
import fs6 from "fs/promises";
|
|
2628
|
-
import path6 from "path";
|
|
2629
|
-
import os2 from "os";
|
|
2630
|
-
|
|
2631
|
-
// src/utils/commandParser.ts
|
|
2632
|
-
import matter from "gray-matter";
|
|
2633
|
-
import { z } from "zod";
|
|
2634
|
-
|
|
2635
|
-
// src/utils/Logger.ts
|
|
2636
2616
|
import fs5 from "fs/promises";
|
|
2637
2617
|
import path5 from "path";
|
|
2638
2618
|
import os from "os";
|
|
2639
|
-
var Logger2 = class _Logger {
|
|
2640
|
-
constructor() {
|
|
2641
|
-
this.logFilePath = null;
|
|
2642
|
-
this.sessionId = null;
|
|
2643
|
-
this.fileLoggingEnabled = true;
|
|
2644
|
-
this.consoleVerbose = false;
|
|
2645
|
-
}
|
|
2646
|
-
static {
|
|
2647
|
-
this.instance = null;
|
|
2648
|
-
}
|
|
2649
|
-
static getInstance() {
|
|
2650
|
-
if (!_Logger.instance) {
|
|
2651
|
-
_Logger.instance = new _Logger();
|
|
2652
|
-
}
|
|
2653
|
-
return _Logger.instance;
|
|
2654
|
-
}
|
|
2655
|
-
/**
|
|
2656
|
-
* Initialize the logger with a session ID
|
|
2657
|
-
*/
|
|
2658
|
-
async initialize(sessionId) {
|
|
2659
|
-
this.sessionId = sessionId;
|
|
2660
|
-
const debugDir = path5.join(os.homedir(), ".bike4mind", "debug");
|
|
2661
|
-
await fs5.mkdir(debugDir, { recursive: true });
|
|
2662
|
-
this.logFilePath = path5.join(debugDir, `${sessionId}.txt`);
|
|
2663
|
-
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
2664
|
-
}
|
|
2665
|
-
/**
|
|
2666
|
-
* Set whether verbose console logging is enabled
|
|
2667
|
-
*/
|
|
2668
|
-
setVerbose(enabled) {
|
|
2669
|
-
this.consoleVerbose = enabled;
|
|
2670
|
-
}
|
|
2671
|
-
/**
|
|
2672
|
-
* Set whether file logging is enabled
|
|
2673
|
-
*/
|
|
2674
|
-
setFileLoggingEnabled(enabled) {
|
|
2675
|
-
this.fileLoggingEnabled = enabled;
|
|
2676
|
-
}
|
|
2677
|
-
/**
|
|
2678
|
-
* DEBUG level - verbose-only console, always file
|
|
2679
|
-
*/
|
|
2680
|
-
debug(message) {
|
|
2681
|
-
this.writeToFile("DEBUG", message).catch(() => {
|
|
2682
|
-
});
|
|
2683
|
-
if (this.consoleVerbose) {
|
|
2684
|
-
console.log(message);
|
|
2685
|
-
}
|
|
2686
|
-
}
|
|
2687
|
-
/**
|
|
2688
|
-
* INFO level - always shown to user
|
|
2689
|
-
*/
|
|
2690
|
-
info(message) {
|
|
2691
|
-
this.writeToFile("INFO", message).catch(() => {
|
|
2692
|
-
});
|
|
2693
|
-
console.log(message);
|
|
2694
|
-
}
|
|
2695
|
-
/**
|
|
2696
|
-
* WARN level - always shown to user
|
|
2697
|
-
*/
|
|
2698
|
-
warn(message) {
|
|
2699
|
-
this.writeToFile("WARN", message).catch(() => {
|
|
2700
|
-
});
|
|
2701
|
-
console.warn(message);
|
|
2702
|
-
}
|
|
2703
|
-
/**
|
|
2704
|
-
* ERROR level - always shown to user
|
|
2705
|
-
*/
|
|
2706
|
-
error(message, err) {
|
|
2707
|
-
this.writeToFile("ERROR", message).catch(() => {
|
|
2708
|
-
});
|
|
2709
|
-
if (err) {
|
|
2710
|
-
this.logErrorDetailsToFile(err).catch(() => {
|
|
2711
|
-
});
|
|
2712
|
-
}
|
|
2713
|
-
console.error(message);
|
|
2714
|
-
}
|
|
2715
|
-
/**
|
|
2716
|
-
* Write log entry to file
|
|
2717
|
-
*/
|
|
2718
|
-
async writeToFile(level, message) {
|
|
2719
|
-
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
2720
|
-
return;
|
|
2721
|
-
}
|
|
2722
|
-
try {
|
|
2723
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
|
|
2724
|
-
const logEntry = `[${timestamp}] [${level}] ${message}
|
|
2725
|
-
`;
|
|
2726
|
-
await fs5.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
2727
|
-
} catch (error) {
|
|
2728
|
-
console.error("File logging failed:", error);
|
|
2729
|
-
}
|
|
2730
|
-
}
|
|
2731
|
-
/**
|
|
2732
|
-
* Log error details to file
|
|
2733
|
-
*/
|
|
2734
|
-
async logErrorDetailsToFile(err) {
|
|
2735
|
-
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
2736
|
-
return;
|
|
2737
|
-
}
|
|
2738
|
-
try {
|
|
2739
|
-
if (err && typeof err === "object" && "response" in err && err.response) {
|
|
2740
|
-
const response = err.response;
|
|
2741
|
-
const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
|
|
2742
|
-
await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
|
|
2743
|
-
await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
|
|
2744
|
-
await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
|
|
2745
|
-
if (response.data) {
|
|
2746
|
-
const errorText = this.extractErrorMessage(response.data);
|
|
2747
|
-
if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
|
|
2748
|
-
await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
|
|
2749
|
-
const parsedError = this.parseHtmlError(errorText);
|
|
2750
|
-
if (parsedError) {
|
|
2751
|
-
await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
|
|
2752
|
-
}
|
|
2753
|
-
await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
|
|
2754
|
-
} else {
|
|
2755
|
-
const preview = this.truncate(errorText, 500);
|
|
2756
|
-
await this.writeToFile("ERROR", ` Response: ${preview}`);
|
|
2757
|
-
}
|
|
2758
|
-
} else {
|
|
2759
|
-
await this.writeToFile("ERROR", ` Response: (no data)`);
|
|
2760
|
-
}
|
|
2761
|
-
}
|
|
2762
|
-
if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
|
|
2763
|
-
const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
|
|
2764
|
-
await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
|
|
2765
|
-
} else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
2766
|
-
await this.writeToFile("ERROR", ` Message: ${err.message}`);
|
|
2767
|
-
}
|
|
2768
|
-
} catch (error) {
|
|
2769
|
-
}
|
|
2770
|
-
}
|
|
2771
|
-
/**
|
|
2772
|
-
* Safely stringify object, handling circular references
|
|
2773
|
-
*/
|
|
2774
|
-
safeStringify(obj) {
|
|
2775
|
-
try {
|
|
2776
|
-
return JSON.stringify(obj);
|
|
2777
|
-
} catch (error) {
|
|
2778
|
-
if (error instanceof Error && error.message.includes("circular")) {
|
|
2779
|
-
try {
|
|
2780
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
2781
|
-
return JSON.stringify(obj, (key, value) => {
|
|
2782
|
-
if (typeof value === "object" && value !== null) {
|
|
2783
|
-
if (seen.has(value)) {
|
|
2784
|
-
return "[Circular]";
|
|
2785
|
-
}
|
|
2786
|
-
seen.add(value);
|
|
2787
|
-
}
|
|
2788
|
-
return value;
|
|
2789
|
-
});
|
|
2790
|
-
} catch {
|
|
2791
|
-
return "[Unable to stringify]";
|
|
2792
|
-
}
|
|
2793
|
-
}
|
|
2794
|
-
return "[Stringify error]";
|
|
2795
|
-
}
|
|
2796
|
-
}
|
|
2797
|
-
/**
|
|
2798
|
-
* Extract readable text from error response data
|
|
2799
|
-
*/
|
|
2800
|
-
extractErrorMessage(data) {
|
|
2801
|
-
if (Buffer.isBuffer(data)) {
|
|
2802
|
-
return data.toString("utf-8");
|
|
2803
|
-
}
|
|
2804
|
-
if (typeof data === "string") {
|
|
2805
|
-
return data;
|
|
2806
|
-
}
|
|
2807
|
-
if (data && typeof data === "object" && "_readableState" in data && data._readableState && typeof data._readableState === "object" && "buffer" in data._readableState && Array.isArray(data._readableState.buffer) && data._readableState.buffer.length > 0) {
|
|
2808
|
-
const chunks = [];
|
|
2809
|
-
for (const chunk of data._readableState.buffer) {
|
|
2810
|
-
if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
|
|
2811
|
-
chunks.push(Buffer.from(chunk.data));
|
|
2812
|
-
} else if (Buffer.isBuffer(chunk)) {
|
|
2813
|
-
chunks.push(chunk);
|
|
2814
|
-
} else if (chunk && typeof chunk === "object" && "data" in chunk) {
|
|
2815
|
-
if (Buffer.isBuffer(chunk.data)) {
|
|
2816
|
-
chunks.push(chunk.data);
|
|
2817
|
-
} else if (Array.isArray(chunk.data)) {
|
|
2818
|
-
chunks.push(Buffer.from(chunk.data));
|
|
2819
|
-
}
|
|
2820
|
-
}
|
|
2821
|
-
}
|
|
2822
|
-
if (chunks.length > 0) {
|
|
2823
|
-
return Buffer.concat(chunks).toString("utf-8");
|
|
2824
|
-
}
|
|
2825
|
-
}
|
|
2826
|
-
return this.safeStringify(data);
|
|
2827
|
-
}
|
|
2828
|
-
/**
|
|
2829
|
-
* Parse HTML error page to extract error message
|
|
2830
|
-
*/
|
|
2831
|
-
parseHtmlError(html) {
|
|
2832
|
-
const titleMatch = html.match(/<title>(.*?)<\/title>/i);
|
|
2833
|
-
const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
|
|
2834
|
-
const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
|
|
2835
|
-
if (titleMatch && titleMatch[1] !== "Error") {
|
|
2836
|
-
return titleMatch[1].trim();
|
|
2837
|
-
}
|
|
2838
|
-
if (h1Match) {
|
|
2839
|
-
return h1Match[1].trim();
|
|
2840
|
-
}
|
|
2841
|
-
if (bodyMatch) {
|
|
2842
|
-
const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
2843
|
-
return text.substring(0, 200);
|
|
2844
|
-
}
|
|
2845
|
-
return null;
|
|
2846
|
-
}
|
|
2847
|
-
/**
|
|
2848
|
-
* Truncate string to max length with ellipsis
|
|
2849
|
-
*/
|
|
2850
|
-
truncate(str, maxLength) {
|
|
2851
|
-
if (str.length <= maxLength) {
|
|
2852
|
-
return str;
|
|
2853
|
-
}
|
|
2854
|
-
return str.substring(0, maxLength) + "... [truncated]";
|
|
2855
|
-
}
|
|
2856
|
-
/**
|
|
2857
|
-
* Format bytes to human-readable size
|
|
2858
|
-
*/
|
|
2859
|
-
formatBytes(bytes) {
|
|
2860
|
-
if (bytes === 0) return "0 B";
|
|
2861
|
-
const k = 1024;
|
|
2862
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
2863
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
2864
|
-
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
2865
|
-
}
|
|
2866
|
-
/**
|
|
2867
|
-
* Clean up old debug logs (older than 30 days)
|
|
2868
|
-
*/
|
|
2869
|
-
async cleanupOldLogs() {
|
|
2870
|
-
if (!this.fileLoggingEnabled) return;
|
|
2871
|
-
try {
|
|
2872
|
-
const debugDir = path5.join(os.homedir(), ".bike4mind", "debug");
|
|
2873
|
-
const files = await fs5.readdir(debugDir);
|
|
2874
|
-
const now = Date.now();
|
|
2875
|
-
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
2876
|
-
for (const file of files) {
|
|
2877
|
-
const filePath = path5.join(debugDir, file);
|
|
2878
|
-
const stats = await fs5.stat(filePath);
|
|
2879
|
-
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
2880
|
-
await fs5.unlink(filePath);
|
|
2881
|
-
}
|
|
2882
|
-
}
|
|
2883
|
-
} catch (error) {
|
|
2884
|
-
console.error("Failed to cleanup old logs:", error);
|
|
2885
|
-
}
|
|
2886
|
-
}
|
|
2887
|
-
};
|
|
2888
|
-
var logger = Logger2.getInstance();
|
|
2889
|
-
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
2890
2619
|
|
|
2891
2620
|
// src/utils/commandParser.ts
|
|
2621
|
+
import matter from "gray-matter";
|
|
2622
|
+
import { z } from "zod";
|
|
2892
2623
|
var flexibleString = z.union([z.string(), z.array(z.string())]).transform((val) => Array.isArray(val) ? val.join(" ") : val).optional();
|
|
2893
2624
|
var flexibleStringArray = z.union([z.string(), z.array(z.string())]).transform((val) => Array.isArray(val) ? val : [val]).optional();
|
|
2894
2625
|
function needsQuoting(value) {
|
|
@@ -3043,17 +2774,17 @@ function extractCommandName(filename) {
|
|
|
3043
2774
|
var CustomCommandStore = class {
|
|
3044
2775
|
constructor(projectRoot) {
|
|
3045
2776
|
this.commands = /* @__PURE__ */ new Map();
|
|
3046
|
-
const home =
|
|
2777
|
+
const home = os.homedir();
|
|
3047
2778
|
const root = projectRoot || process.cwd();
|
|
3048
2779
|
this.globalCommandsDirs = [
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
|
|
2780
|
+
path5.join(home, ".bike4mind", "commands"),
|
|
2781
|
+
path5.join(home, ".claude", "commands"),
|
|
2782
|
+
path5.join(home, ".claude", "skills")
|
|
3052
2783
|
];
|
|
3053
2784
|
this.projectCommandsDirs = [
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
2785
|
+
path5.join(root, ".bike4mind", "commands"),
|
|
2786
|
+
path5.join(root, ".claude", "commands"),
|
|
2787
|
+
path5.join(root, ".claude", "skills")
|
|
3057
2788
|
];
|
|
3058
2789
|
}
|
|
3059
2790
|
/**
|
|
@@ -3078,7 +2809,7 @@ var CustomCommandStore = class {
|
|
|
3078
2809
|
*/
|
|
3079
2810
|
async loadCommandsFromDirectory(directory, source) {
|
|
3080
2811
|
try {
|
|
3081
|
-
const stats = await
|
|
2812
|
+
const stats = await fs5.stat(directory);
|
|
3082
2813
|
if (!stats.isDirectory()) {
|
|
3083
2814
|
return;
|
|
3084
2815
|
}
|
|
@@ -3111,9 +2842,9 @@ var CustomCommandStore = class {
|
|
|
3111
2842
|
async findCommandFiles(directory) {
|
|
3112
2843
|
const files = [];
|
|
3113
2844
|
try {
|
|
3114
|
-
const entries = await
|
|
2845
|
+
const entries = await fs5.readdir(directory, { withFileTypes: true });
|
|
3115
2846
|
for (const entry of entries) {
|
|
3116
|
-
const fullPath =
|
|
2847
|
+
const fullPath = path5.join(directory, entry.name);
|
|
3117
2848
|
if (entry.isDirectory()) {
|
|
3118
2849
|
const subFiles = await this.findCommandFiles(fullPath);
|
|
3119
2850
|
files.push(...subFiles);
|
|
@@ -3133,14 +2864,14 @@ var CustomCommandStore = class {
|
|
|
3133
2864
|
* @param source - Source identifier ('global' or 'project')
|
|
3134
2865
|
*/
|
|
3135
2866
|
async loadCommandFile(filePath, source) {
|
|
3136
|
-
const filename =
|
|
2867
|
+
const filename = path5.basename(filePath);
|
|
3137
2868
|
const isSkillFile = filename.toLowerCase() === "skill.md";
|
|
3138
2869
|
const commandName = isSkillFile ? this.extractSkillName(filePath) : extractCommandName(filename);
|
|
3139
2870
|
if (!commandName) {
|
|
3140
2871
|
console.warn(`Invalid command filename: ${filename} (must end with .md and have valid name)`);
|
|
3141
2872
|
return;
|
|
3142
2873
|
}
|
|
3143
|
-
const fileContent = await
|
|
2874
|
+
const fileContent = await fs5.readFile(filePath, "utf-8");
|
|
3144
2875
|
const command = parseCommandFile(fileContent, filePath, commandName, source);
|
|
3145
2876
|
this.commands.set(commandName, command);
|
|
3146
2877
|
}
|
|
@@ -3152,7 +2883,7 @@ var CustomCommandStore = class {
|
|
|
3152
2883
|
* @returns Skill name or null if invalid
|
|
3153
2884
|
*/
|
|
3154
2885
|
extractSkillName(filePath) {
|
|
3155
|
-
const parentDir =
|
|
2886
|
+
const parentDir = path5.basename(path5.dirname(filePath));
|
|
3156
2887
|
return parentDir && parentDir !== "skills" ? parentDir : null;
|
|
3157
2888
|
}
|
|
3158
2889
|
/**
|
|
@@ -3214,15 +2945,15 @@ var CustomCommandStore = class {
|
|
|
3214
2945
|
*/
|
|
3215
2946
|
async createCommandFile(name, isGlobal = false) {
|
|
3216
2947
|
const targetDir = isGlobal ? this.globalCommandsDirs[0] : this.projectCommandsDirs[0];
|
|
3217
|
-
const filePath =
|
|
3218
|
-
const fileExists = await
|
|
2948
|
+
const filePath = path5.join(targetDir, `${name}.md`);
|
|
2949
|
+
const fileExists = await fs5.access(filePath).then(
|
|
3219
2950
|
() => true,
|
|
3220
2951
|
() => false
|
|
3221
2952
|
);
|
|
3222
2953
|
if (fileExists) {
|
|
3223
2954
|
throw new Error(`Command file already exists: ${filePath}`);
|
|
3224
2955
|
}
|
|
3225
|
-
await
|
|
2956
|
+
await fs5.mkdir(targetDir, { recursive: true });
|
|
3226
2957
|
const template = `---
|
|
3227
2958
|
description: ${name} command
|
|
3228
2959
|
argument-hint: [args]
|
|
@@ -3237,7 +2968,7 @@ You can use:
|
|
|
3237
2968
|
- $1, $2, etc. for positional arguments
|
|
3238
2969
|
- @filename for file references
|
|
3239
2970
|
`;
|
|
3240
|
-
await
|
|
2971
|
+
await fs5.writeFile(filePath, template, "utf-8");
|
|
3241
2972
|
return filePath;
|
|
3242
2973
|
}
|
|
3243
2974
|
};
|
|
@@ -4386,7 +4117,7 @@ import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
|
4386
4117
|
import OpenAI2 from "openai";
|
|
4387
4118
|
|
|
4388
4119
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
|
|
4389
|
-
import
|
|
4120
|
+
import fs6, { unlinkSync } from "fs";
|
|
4390
4121
|
import yauzl from "yauzl";
|
|
4391
4122
|
import axios3 from "axios";
|
|
4392
4123
|
|
|
@@ -6065,8 +5796,8 @@ async function processAndStoreImages(images, context) {
|
|
|
6065
5796
|
const buffer = await downloadImage(image);
|
|
6066
5797
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
6067
5798
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
6068
|
-
const
|
|
6069
|
-
return
|
|
5799
|
+
const path17 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5800
|
+
return path17;
|
|
6070
5801
|
}));
|
|
6071
5802
|
}
|
|
6072
5803
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -7392,8 +7123,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
7392
7123
|
const buffer = await downloadImage2(imageUrl);
|
|
7393
7124
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
7394
7125
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
7395
|
-
const
|
|
7396
|
-
return
|
|
7126
|
+
const path17 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
7127
|
+
return path17;
|
|
7397
7128
|
}
|
|
7398
7129
|
async function generateFullMask(imageBuffer) {
|
|
7399
7130
|
const sharp = (await import("sharp")).default;
|
|
@@ -9334,15 +9065,15 @@ var planetVisibilityTool = {
|
|
|
9334
9065
|
};
|
|
9335
9066
|
|
|
9336
9067
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
9337
|
-
import { promises as
|
|
9068
|
+
import { promises as fs7 } from "fs";
|
|
9338
9069
|
import { existsSync as existsSync3, statSync as statSync4 } from "fs";
|
|
9339
|
-
import
|
|
9070
|
+
import path6 from "path";
|
|
9340
9071
|
var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
|
|
9341
9072
|
async function readFileContent(params) {
|
|
9342
9073
|
const { path: filePath, encoding = "utf-8", offset = 0, limit } = params;
|
|
9343
|
-
const normalizedPath =
|
|
9344
|
-
const resolvedPath =
|
|
9345
|
-
const cwd =
|
|
9074
|
+
const normalizedPath = path6.normalize(filePath);
|
|
9075
|
+
const resolvedPath = path6.resolve(process.cwd(), normalizedPath);
|
|
9076
|
+
const cwd = path6.resolve(process.cwd());
|
|
9346
9077
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9347
9078
|
throw new Error(`Access denied: Cannot read files outside of current working directory`);
|
|
9348
9079
|
}
|
|
@@ -9360,7 +9091,7 @@ async function readFileContent(params) {
|
|
|
9360
9091
|
if (isBinary && encoding === "utf-8") {
|
|
9361
9092
|
throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
|
|
9362
9093
|
}
|
|
9363
|
-
const content = await
|
|
9094
|
+
const content = await fs7.readFile(resolvedPath, encoding);
|
|
9364
9095
|
if (typeof content === "string") {
|
|
9365
9096
|
const lines = content.split("\n");
|
|
9366
9097
|
const totalLines = lines.length;
|
|
@@ -9398,7 +9129,7 @@ ${content}`;
|
|
|
9398
9129
|
}
|
|
9399
9130
|
async function checkIfBinary(filePath) {
|
|
9400
9131
|
const buffer = Buffer.alloc(8192);
|
|
9401
|
-
const fd = await
|
|
9132
|
+
const fd = await fs7.open(filePath, "r");
|
|
9402
9133
|
try {
|
|
9403
9134
|
const { bytesRead } = await fd.read(buffer, 0, 8192, 0);
|
|
9404
9135
|
const chunk = buffer.slice(0, bytesRead);
|
|
@@ -9415,7 +9146,7 @@ var fileReadTool = {
|
|
|
9415
9146
|
context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
|
|
9416
9147
|
try {
|
|
9417
9148
|
const content = await readFileContent(params);
|
|
9418
|
-
const stats = statSync4(
|
|
9149
|
+
const stats = statSync4(path6.resolve(process.cwd(), path6.normalize(params.path)));
|
|
9419
9150
|
context.logger.info("\u2705 FileRead: Success", {
|
|
9420
9151
|
path: params.path,
|
|
9421
9152
|
size: stats.size,
|
|
@@ -9459,25 +9190,25 @@ var fileReadTool = {
|
|
|
9459
9190
|
};
|
|
9460
9191
|
|
|
9461
9192
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
|
|
9462
|
-
import { promises as
|
|
9193
|
+
import { promises as fs8 } from "fs";
|
|
9463
9194
|
import { existsSync as existsSync4 } from "fs";
|
|
9464
|
-
import
|
|
9195
|
+
import path7 from "path";
|
|
9465
9196
|
async function createFile(params) {
|
|
9466
9197
|
const { path: filePath, content, createDirectories = true } = params;
|
|
9467
|
-
const normalizedPath =
|
|
9468
|
-
const resolvedPath =
|
|
9469
|
-
const cwd =
|
|
9198
|
+
const normalizedPath = path7.normalize(filePath);
|
|
9199
|
+
const resolvedPath = path7.resolve(process.cwd(), normalizedPath);
|
|
9200
|
+
const cwd = path7.resolve(process.cwd());
|
|
9470
9201
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9471
9202
|
throw new Error(`Access denied: Cannot create files outside of current working directory`);
|
|
9472
9203
|
}
|
|
9473
9204
|
const fileExists = existsSync4(resolvedPath);
|
|
9474
9205
|
const action = fileExists ? "overwritten" : "created";
|
|
9475
9206
|
if (createDirectories) {
|
|
9476
|
-
const dir =
|
|
9477
|
-
await
|
|
9207
|
+
const dir = path7.dirname(resolvedPath);
|
|
9208
|
+
await fs8.mkdir(dir, { recursive: true });
|
|
9478
9209
|
}
|
|
9479
|
-
await
|
|
9480
|
-
const stats = await
|
|
9210
|
+
await fs8.writeFile(resolvedPath, content, "utf-8");
|
|
9211
|
+
const stats = await fs8.stat(resolvedPath);
|
|
9481
9212
|
const lines = content.split("\n").length;
|
|
9482
9213
|
return `File ${action} successfully: ${filePath}
|
|
9483
9214
|
Size: ${stats.size} bytes
|
|
@@ -9488,7 +9219,7 @@ var createFileTool = {
|
|
|
9488
9219
|
implementation: (context) => ({
|
|
9489
9220
|
toolFn: async (value) => {
|
|
9490
9221
|
const params = value;
|
|
9491
|
-
const fileExists = existsSync4(
|
|
9222
|
+
const fileExists = existsSync4(path7.resolve(process.cwd(), path7.normalize(params.path)));
|
|
9492
9223
|
context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
|
|
9493
9224
|
path: params.path,
|
|
9494
9225
|
size: params.content.length
|
|
@@ -9530,7 +9261,7 @@ var createFileTool = {
|
|
|
9530
9261
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
|
|
9531
9262
|
import { glob } from "glob";
|
|
9532
9263
|
import { stat } from "fs/promises";
|
|
9533
|
-
import
|
|
9264
|
+
import path8 from "path";
|
|
9534
9265
|
var DEFAULT_IGNORE_PATTERNS2 = [
|
|
9535
9266
|
"**/node_modules/**",
|
|
9536
9267
|
"**/.git/**",
|
|
@@ -9546,7 +9277,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
|
|
|
9546
9277
|
async function findFiles(params) {
|
|
9547
9278
|
const { pattern, dir_path, case_sensitive = true, respect_git_ignore = true } = params;
|
|
9548
9279
|
const baseCwd = process.cwd();
|
|
9549
|
-
const targetDir = dir_path ?
|
|
9280
|
+
const targetDir = dir_path ? path8.resolve(baseCwd, path8.normalize(dir_path)) : baseCwd;
|
|
9550
9281
|
if (!targetDir.startsWith(baseCwd)) {
|
|
9551
9282
|
throw new Error(`Access denied: Cannot search outside of current working directory`);
|
|
9552
9283
|
}
|
|
@@ -9586,7 +9317,7 @@ async function findFiles(params) {
|
|
|
9586
9317
|
const summary = `Found ${filesWithStats.length} file(s)${truncated ? ` (showing first ${MAX_RESULTS})` : ""} matching: ${pattern}`;
|
|
9587
9318
|
const dirInfo = dir_path ? `
|
|
9588
9319
|
Directory: ${dir_path}` : "";
|
|
9589
|
-
const filesList = results.map((file) =>
|
|
9320
|
+
const filesList = results.map((file) => path8.relative(baseCwd, file.path)).join("\n");
|
|
9590
9321
|
return `${summary}${dirInfo}
|
|
9591
9322
|
|
|
9592
9323
|
${filesList}`;
|
|
@@ -9640,7 +9371,7 @@ var globFilesTool = {
|
|
|
9640
9371
|
|
|
9641
9372
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
|
|
9642
9373
|
import { stat as stat2 } from "fs/promises";
|
|
9643
|
-
import
|
|
9374
|
+
import path9 from "path";
|
|
9644
9375
|
import { execFile } from "child_process";
|
|
9645
9376
|
import { promisify } from "util";
|
|
9646
9377
|
import { createRequire } from "module";
|
|
@@ -9649,18 +9380,18 @@ var require2 = createRequire(import.meta.url);
|
|
|
9649
9380
|
function getRipgrepPath() {
|
|
9650
9381
|
try {
|
|
9651
9382
|
const ripgrepPath = require2.resolve("@vscode/ripgrep");
|
|
9652
|
-
const ripgrepDir =
|
|
9653
|
-
const rgBinary =
|
|
9383
|
+
const ripgrepDir = path9.dirname(ripgrepPath);
|
|
9384
|
+
const rgBinary = path9.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
|
|
9654
9385
|
return rgBinary;
|
|
9655
9386
|
} catch (error) {
|
|
9656
9387
|
throw new Error("ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services");
|
|
9657
9388
|
}
|
|
9658
9389
|
}
|
|
9659
9390
|
function isPathWithinWorkspace(targetPath, baseCwd) {
|
|
9660
|
-
const resolvedTarget =
|
|
9661
|
-
const resolvedBase =
|
|
9662
|
-
const relativePath =
|
|
9663
|
-
return !relativePath.startsWith("..") && !
|
|
9391
|
+
const resolvedTarget = path9.resolve(targetPath);
|
|
9392
|
+
const resolvedBase = path9.resolve(baseCwd);
|
|
9393
|
+
const relativePath = path9.relative(resolvedBase, resolvedTarget);
|
|
9394
|
+
return !relativePath.startsWith("..") && !path9.isAbsolute(relativePath);
|
|
9664
9395
|
}
|
|
9665
9396
|
function convertGlobToRipgrepGlobs(globPattern) {
|
|
9666
9397
|
if (!globPattern || globPattern === "**/*") {
|
|
@@ -9676,7 +9407,7 @@ function convertGlobToRipgrepGlobs(globPattern) {
|
|
|
9676
9407
|
async function searchFiles2(params) {
|
|
9677
9408
|
const { pattern, dir_path, include } = params;
|
|
9678
9409
|
const baseCwd = process.cwd();
|
|
9679
|
-
const targetDir = dir_path ?
|
|
9410
|
+
const targetDir = dir_path ? path9.resolve(baseCwd, dir_path) : baseCwd;
|
|
9680
9411
|
if (!isPathWithinWorkspace(targetDir, baseCwd)) {
|
|
9681
9412
|
throw new Error(`Path validation failed: "${dir_path}" resolves outside the allowed workspace directory`);
|
|
9682
9413
|
}
|
|
@@ -9738,7 +9469,7 @@ async function searchFiles2(params) {
|
|
|
9738
9469
|
if (item.type === "match") {
|
|
9739
9470
|
const match = item;
|
|
9740
9471
|
allMatches.push({
|
|
9741
|
-
filePath:
|
|
9472
|
+
filePath: path9.relative(targetDir, match.data.path.text) || path9.basename(match.data.path.text),
|
|
9742
9473
|
lineNumber: match.data.line_number,
|
|
9743
9474
|
line: match.data.lines.text.trimEnd()
|
|
9744
9475
|
// Remove trailing newline
|
|
@@ -9831,14 +9562,14 @@ var grepSearchTool = {
|
|
|
9831
9562
|
};
|
|
9832
9563
|
|
|
9833
9564
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
|
|
9834
|
-
import { promises as
|
|
9565
|
+
import { promises as fs9 } from "fs";
|
|
9835
9566
|
import { existsSync as existsSync5, statSync as statSync5 } from "fs";
|
|
9836
|
-
import
|
|
9567
|
+
import path10 from "path";
|
|
9837
9568
|
async function deleteFile(params) {
|
|
9838
9569
|
const { path: filePath, recursive = false } = params;
|
|
9839
|
-
const normalizedPath =
|
|
9840
|
-
const resolvedPath =
|
|
9841
|
-
const cwd =
|
|
9570
|
+
const normalizedPath = path10.normalize(filePath);
|
|
9571
|
+
const resolvedPath = path10.resolve(process.cwd(), normalizedPath);
|
|
9572
|
+
const cwd = path10.resolve(process.cwd());
|
|
9842
9573
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9843
9574
|
throw new Error(`Access denied: Cannot delete files outside of current working directory`);
|
|
9844
9575
|
}
|
|
@@ -9852,10 +9583,10 @@ async function deleteFile(params) {
|
|
|
9852
9583
|
throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
|
|
9853
9584
|
}
|
|
9854
9585
|
if (isDirectory) {
|
|
9855
|
-
await
|
|
9586
|
+
await fs9.rm(resolvedPath, { recursive: true, force: true });
|
|
9856
9587
|
return `Directory deleted successfully: ${filePath}`;
|
|
9857
9588
|
} else {
|
|
9858
|
-
await
|
|
9589
|
+
await fs9.unlink(resolvedPath);
|
|
9859
9590
|
return `File deleted successfully: ${filePath}
|
|
9860
9591
|
Size: ${size} bytes`;
|
|
9861
9592
|
}
|
|
@@ -9865,7 +9596,7 @@ var deleteFileTool = {
|
|
|
9865
9596
|
implementation: (context) => ({
|
|
9866
9597
|
toolFn: async (value) => {
|
|
9867
9598
|
const params = value;
|
|
9868
|
-
const resolvedPath =
|
|
9599
|
+
const resolvedPath = path10.resolve(process.cwd(), path10.normalize(params.path));
|
|
9869
9600
|
const isDirectory = existsSync5(resolvedPath) && statSync5(resolvedPath).isDirectory();
|
|
9870
9601
|
context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
|
|
9871
9602
|
path: params.path,
|
|
@@ -9991,7 +9722,7 @@ var knowledgeBaseSearchTool = {
|
|
|
9991
9722
|
|
|
9992
9723
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/bashExecute/index.js
|
|
9993
9724
|
import { spawn } from "child_process";
|
|
9994
|
-
import
|
|
9725
|
+
import path11 from "path";
|
|
9995
9726
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
9996
9727
|
var MAX_OUTPUT_SIZE = 100 * 1024;
|
|
9997
9728
|
var DANGEROUS_PATTERNS = [
|
|
@@ -10175,7 +9906,7 @@ async function executeBashCommand(params) {
|
|
|
10175
9906
|
};
|
|
10176
9907
|
}
|
|
10177
9908
|
const baseCwd = process.cwd();
|
|
10178
|
-
const targetCwd = relativeCwd ?
|
|
9909
|
+
const targetCwd = relativeCwd ? path11.resolve(baseCwd, relativeCwd) : baseCwd;
|
|
10179
9910
|
const effectiveTimeout = Math.min(timeout, 5 * 60 * 1e3);
|
|
10180
9911
|
return new Promise((resolve3) => {
|
|
10181
9912
|
let stdout = "";
|
|
@@ -10365,9 +10096,9 @@ BLOCKED OPERATIONS:
|
|
|
10365
10096
|
};
|
|
10366
10097
|
|
|
10367
10098
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editLocalFile/index.js
|
|
10368
|
-
import { promises as
|
|
10099
|
+
import { promises as fs10 } from "fs";
|
|
10369
10100
|
import { existsSync as existsSync6 } from "fs";
|
|
10370
|
-
import
|
|
10101
|
+
import path12 from "path";
|
|
10371
10102
|
import { diffLines as diffLines3 } from "diff";
|
|
10372
10103
|
function generateDiff(original, modified) {
|
|
10373
10104
|
const differences = diffLines3(original, modified);
|
|
@@ -10391,16 +10122,16 @@ function generateDiff(original, modified) {
|
|
|
10391
10122
|
}
|
|
10392
10123
|
async function editLocalFile(params) {
|
|
10393
10124
|
const { path: filePath, old_string, new_string } = params;
|
|
10394
|
-
const normalizedPath =
|
|
10395
|
-
const resolvedPath =
|
|
10396
|
-
const cwd =
|
|
10125
|
+
const normalizedPath = path12.normalize(filePath);
|
|
10126
|
+
const resolvedPath = path12.resolve(process.cwd(), normalizedPath);
|
|
10127
|
+
const cwd = path12.resolve(process.cwd());
|
|
10397
10128
|
if (!resolvedPath.startsWith(cwd)) {
|
|
10398
10129
|
throw new Error(`Access denied: Cannot edit files outside of current working directory`);
|
|
10399
10130
|
}
|
|
10400
10131
|
if (!existsSync6(resolvedPath)) {
|
|
10401
10132
|
throw new Error(`File not found: ${filePath}`);
|
|
10402
10133
|
}
|
|
10403
|
-
const currentContent = await
|
|
10134
|
+
const currentContent = await fs10.readFile(resolvedPath, "utf-8");
|
|
10404
10135
|
if (!currentContent.includes(old_string)) {
|
|
10405
10136
|
const preview = old_string.length > 100 ? old_string.substring(0, 100) + "..." : old_string;
|
|
10406
10137
|
throw new Error(`String to replace not found in file. Make sure the old_string matches exactly (including whitespace and line endings). Searched for: "${preview}"`);
|
|
@@ -10410,7 +10141,7 @@ async function editLocalFile(params) {
|
|
|
10410
10141
|
throw new Error(`Found ${occurrences} occurrences of the string to replace. Please provide a more specific old_string that matches exactly one location.`);
|
|
10411
10142
|
}
|
|
10412
10143
|
const newContent = currentContent.replace(old_string, new_string);
|
|
10413
|
-
await
|
|
10144
|
+
await fs10.writeFile(resolvedPath, newContent, "utf-8");
|
|
10414
10145
|
const diffResult = generateDiff(old_string, new_string);
|
|
10415
10146
|
return `File edited successfully: ${filePath}
|
|
10416
10147
|
Changes: +${diffResult.additions} lines, -${diffResult.deletions} lines
|
|
@@ -11630,7 +11361,7 @@ async function generateFileDeletePreview(args) {
|
|
|
11630
11361
|
if (!existsSync7(args.path)) {
|
|
11631
11362
|
return `[File does not exist: ${args.path}]`;
|
|
11632
11363
|
}
|
|
11633
|
-
const stats = await import("fs/promises").then((
|
|
11364
|
+
const stats = await import("fs/promises").then((fs13) => fs13.stat(args.path));
|
|
11634
11365
|
return `[File will be deleted]
|
|
11635
11366
|
|
|
11636
11367
|
Path: ${args.path}
|
|
@@ -11921,21 +11652,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
11921
11652
|
async upload(input, destination, options) {
|
|
11922
11653
|
return `/tmp/${destination}`;
|
|
11923
11654
|
}
|
|
11924
|
-
async download(
|
|
11655
|
+
async download(path17) {
|
|
11925
11656
|
throw new Error("Download not supported in CLI");
|
|
11926
11657
|
}
|
|
11927
|
-
async delete(
|
|
11658
|
+
async delete(path17) {
|
|
11928
11659
|
}
|
|
11929
|
-
async getSignedUrl(
|
|
11930
|
-
return `/tmp/${
|
|
11660
|
+
async getSignedUrl(path17) {
|
|
11661
|
+
return `/tmp/${path17}`;
|
|
11931
11662
|
}
|
|
11932
|
-
getPublicUrl(
|
|
11933
|
-
return `/tmp/${
|
|
11663
|
+
getPublicUrl(path17) {
|
|
11664
|
+
return `/tmp/${path17}`;
|
|
11934
11665
|
}
|
|
11935
|
-
async getPreview(
|
|
11936
|
-
return `/tmp/${
|
|
11666
|
+
async getPreview(path17) {
|
|
11667
|
+
return `/tmp/${path17}`;
|
|
11937
11668
|
}
|
|
11938
|
-
async getMetadata(
|
|
11669
|
+
async getMetadata(path17) {
|
|
11939
11670
|
return { size: 0, contentType: "application/octet-stream" };
|
|
11940
11671
|
}
|
|
11941
11672
|
};
|
|
@@ -12341,8 +12072,8 @@ function getEnvironmentName(configApiConfig) {
|
|
|
12341
12072
|
}
|
|
12342
12073
|
|
|
12343
12074
|
// src/utils/contextLoader.ts
|
|
12344
|
-
import * as
|
|
12345
|
-
import * as
|
|
12075
|
+
import * as fs11 from "fs";
|
|
12076
|
+
import * as path13 from "path";
|
|
12346
12077
|
import { homedir as homedir3 } from "os";
|
|
12347
12078
|
var CONTEXT_FILE_SIZE_LIMIT = 100 * 1024;
|
|
12348
12079
|
var PROJECT_CONTEXT_FILES = [
|
|
@@ -12363,9 +12094,9 @@ function formatFileSize2(bytes) {
|
|
|
12363
12094
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
12364
12095
|
}
|
|
12365
12096
|
function tryReadContextFile(dir, filename, source) {
|
|
12366
|
-
const filePath =
|
|
12097
|
+
const filePath = path13.join(dir, filename);
|
|
12367
12098
|
try {
|
|
12368
|
-
const stats =
|
|
12099
|
+
const stats = fs11.lstatSync(filePath);
|
|
12369
12100
|
if (stats.isDirectory()) {
|
|
12370
12101
|
return null;
|
|
12371
12102
|
}
|
|
@@ -12379,7 +12110,7 @@ function tryReadContextFile(dir, filename, source) {
|
|
|
12379
12110
|
error: `${source === "global" ? "Global" : "Project"} ${filename} exceeds 100KB limit (${formatFileSize2(stats.size)})`
|
|
12380
12111
|
};
|
|
12381
12112
|
}
|
|
12382
|
-
const content =
|
|
12113
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
12383
12114
|
return {
|
|
12384
12115
|
filename,
|
|
12385
12116
|
content,
|
|
@@ -12431,7 +12162,7 @@ ${project.content}`;
|
|
|
12431
12162
|
}
|
|
12432
12163
|
async function loadContextFiles(projectDir) {
|
|
12433
12164
|
const errors = [];
|
|
12434
|
-
const globalDir =
|
|
12165
|
+
const globalDir = path13.join(homedir3(), ".bike4mind");
|
|
12435
12166
|
const projectDirectory = projectDir || process.cwd();
|
|
12436
12167
|
const [globalResult, projectResult] = await Promise.all([
|
|
12437
12168
|
Promise.resolve(findContextFile(globalDir, GLOBAL_CONTEXT_FILES, "global")),
|
|
@@ -12702,7 +12433,7 @@ function substituteArguments(template, args) {
|
|
|
12702
12433
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
12703
12434
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
12704
12435
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
12705
|
-
import
|
|
12436
|
+
import path14 from "path";
|
|
12706
12437
|
import { existsSync as existsSync8, readdirSync as readdirSync3 } from "fs";
|
|
12707
12438
|
var MCPClient = class {
|
|
12708
12439
|
// Note: This class handles MCP server communication with repository filtering
|
|
@@ -12740,21 +12471,20 @@ var MCPClient = class {
|
|
|
12740
12471
|
if (this.customCommand && this.customCommand.trim() !== "") {
|
|
12741
12472
|
command = this.customCommand;
|
|
12742
12473
|
args = this.customArgs ?? [];
|
|
12743
|
-
console.log(`[MCP] Using external command for ${this.serverName}: ${command} ${args.join(" ")}`);
|
|
12744
12474
|
} else {
|
|
12745
12475
|
const root = process.env.INIT_CWD || process.cwd();
|
|
12746
12476
|
const candidatePaths = [
|
|
12747
12477
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
12748
|
-
|
|
12478
|
+
path14.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
12749
12479
|
// When running from SST Lambda deployed environment (/var/task)
|
|
12750
|
-
|
|
12480
|
+
path14.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12751
12481
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
12752
|
-
|
|
12482
|
+
path14.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12753
12483
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
12754
|
-
|
|
12484
|
+
path14.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12755
12485
|
// Original paths (backward compatibility)
|
|
12756
|
-
|
|
12757
|
-
|
|
12486
|
+
path14.join(root, `/b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12487
|
+
path14.join(root, "core", "mcp", "servers", this.serverName, "dist", "index.js")
|
|
12758
12488
|
];
|
|
12759
12489
|
const serverScriptPath = candidatePaths.find((p) => existsSync8(p));
|
|
12760
12490
|
if (!serverScriptPath) {
|
|
@@ -13569,7 +13299,7 @@ var ServerLlmBackend = class {
|
|
|
13569
13299
|
logger.info("\u26A0\uFE0F Using fallback model list (no CLI-compatible models available)");
|
|
13570
13300
|
return this.getFallbackModels();
|
|
13571
13301
|
}
|
|
13572
|
-
logger.
|
|
13302
|
+
logger.debug(`\u{1F4CB} Loaded ${filteredModels.length} models from server`);
|
|
13573
13303
|
return filteredModels;
|
|
13574
13304
|
} catch (error) {
|
|
13575
13305
|
logger.warn(
|
|
@@ -13807,7 +13537,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13807
13537
|
// package.json
|
|
13808
13538
|
var package_default = {
|
|
13809
13539
|
name: "@bike4mind/cli",
|
|
13810
|
-
version: "0.2.29-cli-
|
|
13540
|
+
version: "0.2.29-cli-minimal-ui.18783+9aba9e61e",
|
|
13811
13541
|
type: "module",
|
|
13812
13542
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13813
13543
|
license: "UNLICENSED",
|
|
@@ -13915,10 +13645,10 @@ var package_default = {
|
|
|
13915
13645
|
},
|
|
13916
13646
|
devDependencies: {
|
|
13917
13647
|
"@bike4mind/agents": "0.1.0",
|
|
13918
|
-
"@bike4mind/common": "2.50.1-cli-
|
|
13919
|
-
"@bike4mind/mcp": "1.29.1-cli-
|
|
13920
|
-
"@bike4mind/services": "2.48.1-cli-
|
|
13921
|
-
"@bike4mind/utils": "2.5.1-cli-
|
|
13648
|
+
"@bike4mind/common": "2.50.1-cli-minimal-ui.18783+9aba9e61e",
|
|
13649
|
+
"@bike4mind/mcp": "1.29.1-cli-minimal-ui.18783+9aba9e61e",
|
|
13650
|
+
"@bike4mind/services": "2.48.1-cli-minimal-ui.18783+9aba9e61e",
|
|
13651
|
+
"@bike4mind/utils": "2.5.1-cli-minimal-ui.18783+9aba9e61e",
|
|
13922
13652
|
"@types/better-sqlite3": "^7.6.13",
|
|
13923
13653
|
"@types/diff": "^5.0.9",
|
|
13924
13654
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13935,7 +13665,7 @@ var package_default = {
|
|
|
13935
13665
|
optionalDependencies: {
|
|
13936
13666
|
"@vscode/ripgrep": "^1.17.0"
|
|
13937
13667
|
},
|
|
13938
|
-
gitHead: "
|
|
13668
|
+
gitHead: "9aba9e61e1fb7e03dfd87a2e777c8e0e4e16fbbd"
|
|
13939
13669
|
};
|
|
13940
13670
|
|
|
13941
13671
|
// src/config/constants.ts
|
|
@@ -14428,9 +14158,9 @@ var SubagentOrchestrator = class {
|
|
|
14428
14158
|
};
|
|
14429
14159
|
|
|
14430
14160
|
// src/agents/AgentStore.ts
|
|
14431
|
-
import
|
|
14432
|
-
import
|
|
14433
|
-
import
|
|
14161
|
+
import fs12 from "fs/promises";
|
|
14162
|
+
import path15 from "path";
|
|
14163
|
+
import os2 from "os";
|
|
14434
14164
|
import matter2 from "gray-matter";
|
|
14435
14165
|
var FULL_MODEL_ID_PREFIXES = [
|
|
14436
14166
|
"claude-",
|
|
@@ -14576,12 +14306,12 @@ var AgentStore = class {
|
|
|
14576
14306
|
constructor(builtinDir, projectRoot) {
|
|
14577
14307
|
this.agents = /* @__PURE__ */ new Map();
|
|
14578
14308
|
const root = projectRoot || process.cwd();
|
|
14579
|
-
const home =
|
|
14309
|
+
const home = os2.homedir();
|
|
14580
14310
|
this.builtinAgentsDir = builtinDir;
|
|
14581
|
-
this.globalB4MAgentsDir =
|
|
14582
|
-
this.globalClaudeAgentsDir =
|
|
14583
|
-
this.projectB4MAgentsDir =
|
|
14584
|
-
this.projectClaudeAgentsDir =
|
|
14311
|
+
this.globalB4MAgentsDir = path15.join(home, ".bike4mind", "agents");
|
|
14312
|
+
this.globalClaudeAgentsDir = path15.join(home, ".claude", "agents");
|
|
14313
|
+
this.projectB4MAgentsDir = path15.join(root, ".bike4mind", "agents");
|
|
14314
|
+
this.projectClaudeAgentsDir = path15.join(root, ".claude", "agents");
|
|
14585
14315
|
}
|
|
14586
14316
|
/**
|
|
14587
14317
|
* Load all agents from all directories
|
|
@@ -14605,7 +14335,7 @@ var AgentStore = class {
|
|
|
14605
14335
|
*/
|
|
14606
14336
|
async loadAgentsFromDirectory(directory, source) {
|
|
14607
14337
|
try {
|
|
14608
|
-
const stats = await
|
|
14338
|
+
const stats = await fs12.stat(directory);
|
|
14609
14339
|
if (!stats.isDirectory()) {
|
|
14610
14340
|
return;
|
|
14611
14341
|
}
|
|
@@ -14633,9 +14363,9 @@ var AgentStore = class {
|
|
|
14633
14363
|
async findAgentFiles(directory) {
|
|
14634
14364
|
const files = [];
|
|
14635
14365
|
try {
|
|
14636
|
-
const entries = await
|
|
14366
|
+
const entries = await fs12.readdir(directory, { withFileTypes: true });
|
|
14637
14367
|
for (const entry of entries) {
|
|
14638
|
-
const fullPath =
|
|
14368
|
+
const fullPath = path15.join(directory, entry.name);
|
|
14639
14369
|
if (entry.isDirectory()) {
|
|
14640
14370
|
const subFiles = await this.findAgentFiles(fullPath);
|
|
14641
14371
|
files.push(...subFiles);
|
|
@@ -14652,10 +14382,10 @@ var AgentStore = class {
|
|
|
14652
14382
|
* Parse a single agent markdown file
|
|
14653
14383
|
*/
|
|
14654
14384
|
async parseAgentFile(filePath, source) {
|
|
14655
|
-
const content = await
|
|
14385
|
+
const content = await fs12.readFile(filePath, "utf-8");
|
|
14656
14386
|
const { data: frontmatter, content: body } = matter2(content);
|
|
14657
14387
|
const parsed = AgentFrontmatterSchema.parse(frontmatter);
|
|
14658
|
-
const name =
|
|
14388
|
+
const name = path15.basename(filePath, ".md");
|
|
14659
14389
|
const modelInput = parsed.model || DEFAULT_AGENT_MODEL;
|
|
14660
14390
|
const resolution = resolveModelAlias(modelInput, name, filePath);
|
|
14661
14391
|
if (!resolution.resolved && resolution.warning) {
|
|
@@ -14735,16 +14465,16 @@ var AgentStore = class {
|
|
|
14735
14465
|
*/
|
|
14736
14466
|
async createAgentFile(name, isGlobal = false, useClaude = true) {
|
|
14737
14467
|
const targetDir = isGlobal ? useClaude ? this.globalClaudeAgentsDir : this.globalB4MAgentsDir : useClaude ? this.projectClaudeAgentsDir : this.projectB4MAgentsDir;
|
|
14738
|
-
const filePath =
|
|
14468
|
+
const filePath = path15.join(targetDir, `${name}.md`);
|
|
14739
14469
|
try {
|
|
14740
|
-
await
|
|
14470
|
+
await fs12.access(filePath);
|
|
14741
14471
|
throw new Error(`Agent file already exists: ${filePath}`);
|
|
14742
14472
|
} catch (error) {
|
|
14743
14473
|
if (error.code !== "ENOENT") {
|
|
14744
14474
|
throw error;
|
|
14745
14475
|
}
|
|
14746
14476
|
}
|
|
14747
|
-
await
|
|
14477
|
+
await fs12.mkdir(targetDir, { recursive: true });
|
|
14748
14478
|
const template = `---
|
|
14749
14479
|
description: ${name} agent description
|
|
14750
14480
|
model: claude-3-5-haiku-20241022
|
|
@@ -14779,7 +14509,7 @@ You are a ${name} specialist. Your job is to [describe primary task].
|
|
|
14779
14509
|
## Output Format
|
|
14780
14510
|
Describe the expected output format here.
|
|
14781
14511
|
`;
|
|
14782
|
-
await
|
|
14512
|
+
await fs12.writeFile(filePath, template, "utf-8");
|
|
14783
14513
|
return filePath;
|
|
14784
14514
|
}
|
|
14785
14515
|
/**
|
|
@@ -15417,7 +15147,7 @@ function createTodoStore(onUpdate) {
|
|
|
15417
15147
|
|
|
15418
15148
|
// src/tools/findDefinitionTool.ts
|
|
15419
15149
|
import { stat as stat3 } from "fs/promises";
|
|
15420
|
-
import
|
|
15150
|
+
import path16 from "path";
|
|
15421
15151
|
import { execFile as execFile2 } from "child_process";
|
|
15422
15152
|
import { promisify as promisify2 } from "util";
|
|
15423
15153
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -15438,8 +15168,8 @@ var ALL_KEYWORDS = Object.values(KIND_KEYWORDS).flat();
|
|
|
15438
15168
|
function getRipgrepPath2() {
|
|
15439
15169
|
try {
|
|
15440
15170
|
const ripgrepPath = require3.resolve("@vscode/ripgrep");
|
|
15441
|
-
const ripgrepDir =
|
|
15442
|
-
return
|
|
15171
|
+
const ripgrepDir = path16.dirname(ripgrepPath);
|
|
15172
|
+
return path16.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
|
|
15443
15173
|
} catch {
|
|
15444
15174
|
throw new Error(
|
|
15445
15175
|
"ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services"
|
|
@@ -15447,10 +15177,10 @@ function getRipgrepPath2() {
|
|
|
15447
15177
|
}
|
|
15448
15178
|
}
|
|
15449
15179
|
function isPathWithinWorkspace2(targetPath, baseCwd) {
|
|
15450
|
-
const resolvedTarget =
|
|
15451
|
-
const resolvedBase =
|
|
15452
|
-
const relativePath =
|
|
15453
|
-
return !relativePath.startsWith("..") && !
|
|
15180
|
+
const resolvedTarget = path16.resolve(targetPath);
|
|
15181
|
+
const resolvedBase = path16.resolve(baseCwd);
|
|
15182
|
+
const relativePath = path16.relative(resolvedBase, resolvedTarget);
|
|
15183
|
+
return !relativePath.startsWith("..") && !path16.isAbsolute(relativePath);
|
|
15454
15184
|
}
|
|
15455
15185
|
function escapeRegex(str) {
|
|
15456
15186
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -15483,7 +15213,7 @@ async function findDefinitions(params) {
|
|
|
15483
15213
|
throw new Error("symbol_name is required");
|
|
15484
15214
|
}
|
|
15485
15215
|
const baseCwd = process.cwd();
|
|
15486
|
-
const targetDir = search_path ?
|
|
15216
|
+
const targetDir = search_path ? path16.resolve(baseCwd, search_path) : baseCwd;
|
|
15487
15217
|
if (!isPathWithinWorkspace2(targetDir, baseCwd)) {
|
|
15488
15218
|
throw new Error(`Path validation failed: "${search_path}" resolves outside the allowed workspace directory`);
|
|
15489
15219
|
}
|
|
@@ -15538,7 +15268,7 @@ async function findDefinitions(params) {
|
|
|
15538
15268
|
const lineText = match.data.lines.text.trimEnd();
|
|
15539
15269
|
if (isLikelyDefinition(lineText)) {
|
|
15540
15270
|
allMatches.push({
|
|
15541
|
-
filePath:
|
|
15271
|
+
filePath: path16.relative(targetDir, match.data.path.text) || path16.basename(match.data.path.text),
|
|
15542
15272
|
lineNumber: match.data.line_number,
|
|
15543
15273
|
line: lineText
|
|
15544
15274
|
});
|
|
@@ -15731,6 +15461,7 @@ function CliApp() {
|
|
|
15731
15461
|
});
|
|
15732
15462
|
const init = useCallback2(async () => {
|
|
15733
15463
|
try {
|
|
15464
|
+
const startupLog = [];
|
|
15734
15465
|
const config = await state.configStore.load();
|
|
15735
15466
|
const history = await state.commandHistoryStore.load();
|
|
15736
15467
|
setCommandHistory(history);
|
|
@@ -15738,7 +15469,7 @@ function CliApp() {
|
|
|
15738
15469
|
await state.customCommandStore.loadCommands();
|
|
15739
15470
|
const customCommandCount = state.customCommandStore.getCommandCount();
|
|
15740
15471
|
if (customCommandCount > 0) {
|
|
15741
|
-
|
|
15472
|
+
startupLog.push(`\u{1F4DD} Loaded ${customCommandCount} custom command${customCommandCount !== 1 ? "s" : ""}`);
|
|
15742
15473
|
}
|
|
15743
15474
|
} catch (error) {
|
|
15744
15475
|
console.warn("Failed to load custom commands:", error instanceof Error ? error.message : String(error));
|
|
@@ -15759,7 +15490,7 @@ function CliApp() {
|
|
|
15759
15490
|
} else {
|
|
15760
15491
|
isAuthenticated = true;
|
|
15761
15492
|
const daysUntilExpiry = Math.floor((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
|
|
15762
|
-
|
|
15493
|
+
startupLog.push(`\u2705 Authenticated (expires in ${daysUntilExpiry} day${daysUntilExpiry !== 1 ? "s" : ""})`);
|
|
15763
15494
|
}
|
|
15764
15495
|
}
|
|
15765
15496
|
if (!isAuthenticated) {
|
|
@@ -15873,22 +15604,23 @@ function CliApp() {
|
|
|
15873
15604
|
state.configStore,
|
|
15874
15605
|
apiClient
|
|
15875
15606
|
);
|
|
15876
|
-
|
|
15607
|
+
startupLog.push(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
|
|
15877
15608
|
const mcpManager = new McpManager(config);
|
|
15878
15609
|
await mcpManager.initialize();
|
|
15879
15610
|
const mcpTools = mcpManager.getTools();
|
|
15880
15611
|
if (mcpTools.length > 0) {
|
|
15881
|
-
const
|
|
15882
|
-
|
|
15612
|
+
const toolCountByServer = mcpManager.getToolCount();
|
|
15613
|
+
const serverSummaries = toolCountByServer.map((s) => `${s.serverName} (${s.count})`).join(", ");
|
|
15614
|
+
startupLog.push(`\u{1F4E1} Loaded ${mcpTools.length} MCP tool(s): ${serverSummaries}`);
|
|
15883
15615
|
} else {
|
|
15884
|
-
|
|
15616
|
+
startupLog.push(`\u{1F4E1} No MCP tools loaded`);
|
|
15885
15617
|
}
|
|
15886
15618
|
const builtinAgentsDir = new URL("./agents/defaults/", import.meta.url).pathname;
|
|
15887
15619
|
const agentProjectDir = state.configStore.getProjectConfigDir();
|
|
15888
15620
|
const agentStore = new AgentStore(builtinAgentsDir, agentProjectDir || process.cwd());
|
|
15889
15621
|
await agentStore.loadAgents();
|
|
15890
15622
|
const agentSummary = agentStore.getSummary();
|
|
15891
|
-
|
|
15623
|
+
startupLog.push(
|
|
15892
15624
|
`\u{1F916} Loaded ${agentSummary.total} agent(s): ${agentSummary.builtin} built-in, ${agentSummary.global} global, ${agentSummary.project} project`
|
|
15893
15625
|
);
|
|
15894
15626
|
const orchestrator = new SubagentOrchestrator({
|
|
@@ -15928,13 +15660,13 @@ function CliApp() {
|
|
|
15928
15660
|
cliTools.push(skillTool);
|
|
15929
15661
|
}
|
|
15930
15662
|
const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
|
|
15931
|
-
|
|
15663
|
+
startupLog.push(`\u{1F4C2} Working directory: ${process.cwd()}`);
|
|
15932
15664
|
const agentNamesList = agentStore.getAgentNames().join(", ");
|
|
15933
|
-
|
|
15665
|
+
startupLog.push(`\u{1F916} Subagent delegation enabled (${agentNamesList}) + background execution`);
|
|
15934
15666
|
if (skillTool) {
|
|
15935
15667
|
const skillCount = state.customCommandStore.getCommandCount();
|
|
15936
15668
|
if (skillCount > 0) {
|
|
15937
|
-
|
|
15669
|
+
startupLog.push(`\u{1F6E0}\uFE0F Skill tool enabled (${skillCount} skills available)`);
|
|
15938
15670
|
}
|
|
15939
15671
|
}
|
|
15940
15672
|
logger.debug(
|
|
@@ -15943,13 +15675,13 @@ function CliApp() {
|
|
|
15943
15675
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
15944
15676
|
const contextResult = await loadContextFiles(projectDir);
|
|
15945
15677
|
if (contextResult.globalContext) {
|
|
15946
|
-
|
|
15678
|
+
startupLog.push(`\u{1F4C4} Global context: ${contextResult.globalContext.filename}`);
|
|
15947
15679
|
}
|
|
15948
15680
|
if (contextResult.projectContext) {
|
|
15949
|
-
|
|
15681
|
+
startupLog.push(`\u{1F4C4} Project context: ${contextResult.projectContext.filename}`);
|
|
15950
15682
|
}
|
|
15951
15683
|
for (const error of contextResult.errors) {
|
|
15952
|
-
|
|
15684
|
+
startupLog.push(`\u26A0\uFE0F Context file error: ${error}`);
|
|
15953
15685
|
}
|
|
15954
15686
|
let contextSection = contextResult.mergedContent ? `
|
|
15955
15687
|
|
|
@@ -16025,8 +15757,36 @@ ${contextResult.mergedContent}` : "";
|
|
|
16025
15757
|
// Store for grouped notification turn tracking
|
|
16026
15758
|
}));
|
|
16027
15759
|
setStoreSession(newSession);
|
|
15760
|
+
const bannerLines = [
|
|
15761
|
+
{ text: "\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557", ansi: "\x1B[36m\x1B[1m" },
|
|
15762
|
+
{ text: "\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551", ansi: "\x1B[36m\x1B[1m" },
|
|
15763
|
+
{ text: "\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551", ansi: "\x1B[36m\x1B[1m" },
|
|
15764
|
+
{ text: "\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551", ansi: "\x1B[36m\x1B[1m" },
|
|
15765
|
+
{ text: "\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551", ansi: "\x1B[36m\x1B[1m" },
|
|
15766
|
+
{ text: "\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D", ansi: "\x1B[36m\x1B[1m" },
|
|
15767
|
+
{ text: "", ansi: "" },
|
|
15768
|
+
{ text: `v${package_default.version} - AI-Powered CLI`, ansi: "\x1B[2m" },
|
|
15769
|
+
{ text: "/help for more information", ansi: "\x1B[2m" }
|
|
15770
|
+
];
|
|
15771
|
+
const bannerWidth = 30;
|
|
15772
|
+
const termWidth = process.stdout.columns || 80;
|
|
15773
|
+
const rightColWidth = termWidth - bannerWidth - 2;
|
|
15774
|
+
const truncate = (str, max) => {
|
|
15775
|
+
if (str.length > max) return str.slice(0, max - 1) + "\u2026";
|
|
15776
|
+
return str;
|
|
15777
|
+
};
|
|
15778
|
+
const totalLines = Math.max(bannerLines.length, startupLog.length);
|
|
15779
|
+
for (let i = 0; i < totalLines; i++) {
|
|
15780
|
+
const banner = bannerLines[i];
|
|
15781
|
+
const leftText = banner?.text || "";
|
|
15782
|
+
const leftAnsi = banner?.ansi || "";
|
|
15783
|
+
const right = startupLog[i] || "";
|
|
15784
|
+
const coloredLeft = leftText ? `${leftAnsi}${leftText}\x1B[0m` : "";
|
|
15785
|
+
const gap = " ".repeat(bannerWidth - leftText.length + 2);
|
|
15786
|
+
console.log(coloredLeft + gap + truncate(right, rightColWidth));
|
|
15787
|
+
}
|
|
16028
15788
|
setIsInitialized(true);
|
|
16029
|
-
console.log("
|
|
15789
|
+
console.log("");
|
|
16030
15790
|
} catch (error) {
|
|
16031
15791
|
console.error("Initialization error:", error);
|
|
16032
15792
|
setInitError(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -16700,7 +16460,24 @@ Project Configuration:
|
|
|
16700
16460
|
Custom Commands:
|
|
16701
16461
|
/commands - List all custom commands
|
|
16702
16462
|
/commands:new <name> - Create a new custom command
|
|
16703
|
-
/commands:reload - Reload custom commands from disk
|
|
16463
|
+
/commands:reload - Reload custom commands from disk
|
|
16464
|
+
|
|
16465
|
+
Keyboard Shortcuts:
|
|
16466
|
+
Ctrl+C - Press twice to exit
|
|
16467
|
+
Esc - Abort current operation
|
|
16468
|
+
Shift+Tab - Toggle auto-accept edits
|
|
16469
|
+
Ctrl+U - Clear current line
|
|
16470
|
+
Ctrl+K - Clear from cursor to end of line
|
|
16471
|
+
Ctrl+W - Delete word before cursor
|
|
16472
|
+
Ctrl+A - Move cursor to beginning
|
|
16473
|
+
Ctrl+E - Move cursor to end
|
|
16474
|
+
Ctrl+B / \u2190 - Move cursor left
|
|
16475
|
+
Ctrl+F / \u2192 - Move cursor right
|
|
16476
|
+
Ctrl+D - Delete character at cursor
|
|
16477
|
+
Ctrl+L - Clear input
|
|
16478
|
+
\u2191 / \u2193 - Navigate history / autocomplete
|
|
16479
|
+
Tab - Accept autocomplete suggestion
|
|
16480
|
+
Shift+Cmd+Click - Open links in browser${hasCustomCommands ? "\n\n\u{1F4DD} Custom Commands Available:" : ""}${hasCustomCommands ? customCommands.map((cmd) => {
|
|
16704
16481
|
const source = cmd.source === "global" ? "\u{1F3E0}" : "\u{1F4C1}";
|
|
16705
16482
|
const argHint = cmd.argumentHint ? ` ${cmd.argumentHint}` : "";
|
|
16706
16483
|
return `
|
|
@@ -16741,7 +16518,6 @@ Custom Commands:
|
|
|
16741
16518
|
const handleSessionSelect = async (selectedSession) => {
|
|
16742
16519
|
setState((prev) => ({ ...prev, sessionSelector: null }));
|
|
16743
16520
|
if (!selectedSession) {
|
|
16744
|
-
console.log("\u274C Session selection cancelled");
|
|
16745
16521
|
return;
|
|
16746
16522
|
}
|
|
16747
16523
|
const loadedSession = await state.sessionStore.load(selectedSession.id);
|
|
@@ -17593,17 +17369,6 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
17593
17369
|
}
|
|
17594
17370
|
);
|
|
17595
17371
|
}
|
|
17596
|
-
var BANNER = `
|
|
17597
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557
|
|
17598
|
-
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551
|
|
17599
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D\u2588\u2588\u2588\u2588\u2588\u2588\u2588\u2551\u2588\u2588\u2554\u2588\u2588\u2588\u2588\u2554\u2588\u2588\u2551
|
|
17600
|
-
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u255A\u2550\u2550\u2550\u2550\u2588\u2588\u2551\u2588\u2588\u2551\u255A\u2588\u2588\u2554\u255D\u2588\u2588\u2551
|
|
17601
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551
|
|
17602
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
17603
|
-
`;
|
|
17604
|
-
console.log("\x1B[36m\x1B[1m%s\x1B[0m", BANNER);
|
|
17605
|
-
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m`);
|
|
17606
|
-
console.log(" /help for more information\n");
|
|
17607
17372
|
var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "development";
|
|
17608
17373
|
if (isDevMode) {
|
|
17609
17374
|
logger.debug("\u{1F527} Running in development mode (using TypeScript source)\n");
|