@bike4mind/cli 0.2.29-cli-minimal-ui.18782 → 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/{chunk-23T2XGSZ.js → chunk-LBTTUQJM.js} +290 -33
- package/dist/commands/mcpCommand.js +1 -1
- package/dist/index.js +172 -412
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -7,8 +7,9 @@ import {
|
|
|
7
7
|
getSerperKey
|
|
8
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
|
|
@@ -2612,271 +2613,13 @@ var CommandHistoryStore = class {
|
|
|
2612
2613
|
};
|
|
2613
2614
|
|
|
2614
2615
|
// src/storage/CustomCommandStore.ts
|
|
2615
|
-
import fs6 from "fs/promises";
|
|
2616
|
-
import path6 from "path";
|
|
2617
|
-
import os2 from "os";
|
|
2618
|
-
|
|
2619
|
-
// src/utils/commandParser.ts
|
|
2620
|
-
import matter from "gray-matter";
|
|
2621
|
-
import { z } from "zod";
|
|
2622
|
-
|
|
2623
|
-
// src/utils/Logger.ts
|
|
2624
2616
|
import fs5 from "fs/promises";
|
|
2625
2617
|
import path5 from "path";
|
|
2626
2618
|
import os from "os";
|
|
2627
|
-
var Logger2 = class _Logger {
|
|
2628
|
-
constructor() {
|
|
2629
|
-
this.logFilePath = null;
|
|
2630
|
-
this.sessionId = null;
|
|
2631
|
-
this.fileLoggingEnabled = true;
|
|
2632
|
-
this.consoleVerbose = false;
|
|
2633
|
-
}
|
|
2634
|
-
static {
|
|
2635
|
-
this.instance = null;
|
|
2636
|
-
}
|
|
2637
|
-
static getInstance() {
|
|
2638
|
-
if (!_Logger.instance) {
|
|
2639
|
-
_Logger.instance = new _Logger();
|
|
2640
|
-
}
|
|
2641
|
-
return _Logger.instance;
|
|
2642
|
-
}
|
|
2643
|
-
/**
|
|
2644
|
-
* Initialize the logger with a session ID
|
|
2645
|
-
*/
|
|
2646
|
-
async initialize(sessionId) {
|
|
2647
|
-
this.sessionId = sessionId;
|
|
2648
|
-
const debugDir = path5.join(os.homedir(), ".bike4mind", "debug");
|
|
2649
|
-
await fs5.mkdir(debugDir, { recursive: true });
|
|
2650
|
-
this.logFilePath = path5.join(debugDir, `${sessionId}.txt`);
|
|
2651
|
-
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
2652
|
-
}
|
|
2653
|
-
/**
|
|
2654
|
-
* Set whether verbose console logging is enabled
|
|
2655
|
-
*/
|
|
2656
|
-
setVerbose(enabled) {
|
|
2657
|
-
this.consoleVerbose = enabled;
|
|
2658
|
-
}
|
|
2659
|
-
/**
|
|
2660
|
-
* Set whether file logging is enabled
|
|
2661
|
-
*/
|
|
2662
|
-
setFileLoggingEnabled(enabled) {
|
|
2663
|
-
this.fileLoggingEnabled = enabled;
|
|
2664
|
-
}
|
|
2665
|
-
/**
|
|
2666
|
-
* DEBUG level - verbose-only console, always file
|
|
2667
|
-
*/
|
|
2668
|
-
debug(message) {
|
|
2669
|
-
this.writeToFile("DEBUG", message).catch(() => {
|
|
2670
|
-
});
|
|
2671
|
-
if (this.consoleVerbose) {
|
|
2672
|
-
console.log(message);
|
|
2673
|
-
}
|
|
2674
|
-
}
|
|
2675
|
-
/**
|
|
2676
|
-
* INFO level - always shown to user
|
|
2677
|
-
*/
|
|
2678
|
-
info(message) {
|
|
2679
|
-
this.writeToFile("INFO", message).catch(() => {
|
|
2680
|
-
});
|
|
2681
|
-
console.log(message);
|
|
2682
|
-
}
|
|
2683
|
-
/**
|
|
2684
|
-
* WARN level - always shown to user
|
|
2685
|
-
*/
|
|
2686
|
-
warn(message) {
|
|
2687
|
-
this.writeToFile("WARN", message).catch(() => {
|
|
2688
|
-
});
|
|
2689
|
-
console.warn(message);
|
|
2690
|
-
}
|
|
2691
|
-
/**
|
|
2692
|
-
* ERROR level - always shown to user
|
|
2693
|
-
*/
|
|
2694
|
-
error(message, err) {
|
|
2695
|
-
this.writeToFile("ERROR", message).catch(() => {
|
|
2696
|
-
});
|
|
2697
|
-
if (err) {
|
|
2698
|
-
this.logErrorDetailsToFile(err).catch(() => {
|
|
2699
|
-
});
|
|
2700
|
-
}
|
|
2701
|
-
console.error(message);
|
|
2702
|
-
}
|
|
2703
|
-
/**
|
|
2704
|
-
* Write log entry to file
|
|
2705
|
-
*/
|
|
2706
|
-
async writeToFile(level, message) {
|
|
2707
|
-
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
2708
|
-
return;
|
|
2709
|
-
}
|
|
2710
|
-
try {
|
|
2711
|
-
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
|
|
2712
|
-
const logEntry = `[${timestamp}] [${level}] ${message}
|
|
2713
|
-
`;
|
|
2714
|
-
await fs5.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
2715
|
-
} catch (error) {
|
|
2716
|
-
console.error("File logging failed:", error);
|
|
2717
|
-
}
|
|
2718
|
-
}
|
|
2719
|
-
/**
|
|
2720
|
-
* Log error details to file
|
|
2721
|
-
*/
|
|
2722
|
-
async logErrorDetailsToFile(err) {
|
|
2723
|
-
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
2724
|
-
return;
|
|
2725
|
-
}
|
|
2726
|
-
try {
|
|
2727
|
-
if (err && typeof err === "object" && "response" in err && err.response) {
|
|
2728
|
-
const response = err.response;
|
|
2729
|
-
const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
|
|
2730
|
-
await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
|
|
2731
|
-
await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
|
|
2732
|
-
await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
|
|
2733
|
-
if (response.data) {
|
|
2734
|
-
const errorText = this.extractErrorMessage(response.data);
|
|
2735
|
-
if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
|
|
2736
|
-
await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
|
|
2737
|
-
const parsedError = this.parseHtmlError(errorText);
|
|
2738
|
-
if (parsedError) {
|
|
2739
|
-
await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
|
|
2740
|
-
}
|
|
2741
|
-
await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
|
|
2742
|
-
} else {
|
|
2743
|
-
const preview = this.truncate(errorText, 500);
|
|
2744
|
-
await this.writeToFile("ERROR", ` Response: ${preview}`);
|
|
2745
|
-
}
|
|
2746
|
-
} else {
|
|
2747
|
-
await this.writeToFile("ERROR", ` Response: (no data)`);
|
|
2748
|
-
}
|
|
2749
|
-
}
|
|
2750
|
-
if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
|
|
2751
|
-
const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
|
|
2752
|
-
await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
|
|
2753
|
-
} else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
2754
|
-
await this.writeToFile("ERROR", ` Message: ${err.message}`);
|
|
2755
|
-
}
|
|
2756
|
-
} catch (error) {
|
|
2757
|
-
}
|
|
2758
|
-
}
|
|
2759
|
-
/**
|
|
2760
|
-
* Safely stringify object, handling circular references
|
|
2761
|
-
*/
|
|
2762
|
-
safeStringify(obj) {
|
|
2763
|
-
try {
|
|
2764
|
-
return JSON.stringify(obj);
|
|
2765
|
-
} catch (error) {
|
|
2766
|
-
if (error instanceof Error && error.message.includes("circular")) {
|
|
2767
|
-
try {
|
|
2768
|
-
const seen = /* @__PURE__ */ new WeakSet();
|
|
2769
|
-
return JSON.stringify(obj, (key, value) => {
|
|
2770
|
-
if (typeof value === "object" && value !== null) {
|
|
2771
|
-
if (seen.has(value)) {
|
|
2772
|
-
return "[Circular]";
|
|
2773
|
-
}
|
|
2774
|
-
seen.add(value);
|
|
2775
|
-
}
|
|
2776
|
-
return value;
|
|
2777
|
-
});
|
|
2778
|
-
} catch {
|
|
2779
|
-
return "[Unable to stringify]";
|
|
2780
|
-
}
|
|
2781
|
-
}
|
|
2782
|
-
return "[Stringify error]";
|
|
2783
|
-
}
|
|
2784
|
-
}
|
|
2785
|
-
/**
|
|
2786
|
-
* Extract readable text from error response data
|
|
2787
|
-
*/
|
|
2788
|
-
extractErrorMessage(data) {
|
|
2789
|
-
if (Buffer.isBuffer(data)) {
|
|
2790
|
-
return data.toString("utf-8");
|
|
2791
|
-
}
|
|
2792
|
-
if (typeof data === "string") {
|
|
2793
|
-
return data;
|
|
2794
|
-
}
|
|
2795
|
-
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) {
|
|
2796
|
-
const chunks = [];
|
|
2797
|
-
for (const chunk of data._readableState.buffer) {
|
|
2798
|
-
if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
|
|
2799
|
-
chunks.push(Buffer.from(chunk.data));
|
|
2800
|
-
} else if (Buffer.isBuffer(chunk)) {
|
|
2801
|
-
chunks.push(chunk);
|
|
2802
|
-
} else if (chunk && typeof chunk === "object" && "data" in chunk) {
|
|
2803
|
-
if (Buffer.isBuffer(chunk.data)) {
|
|
2804
|
-
chunks.push(chunk.data);
|
|
2805
|
-
} else if (Array.isArray(chunk.data)) {
|
|
2806
|
-
chunks.push(Buffer.from(chunk.data));
|
|
2807
|
-
}
|
|
2808
|
-
}
|
|
2809
|
-
}
|
|
2810
|
-
if (chunks.length > 0) {
|
|
2811
|
-
return Buffer.concat(chunks).toString("utf-8");
|
|
2812
|
-
}
|
|
2813
|
-
}
|
|
2814
|
-
return this.safeStringify(data);
|
|
2815
|
-
}
|
|
2816
|
-
/**
|
|
2817
|
-
* Parse HTML error page to extract error message
|
|
2818
|
-
*/
|
|
2819
|
-
parseHtmlError(html) {
|
|
2820
|
-
const titleMatch = html.match(/<title>(.*?)<\/title>/i);
|
|
2821
|
-
const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
|
|
2822
|
-
const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
|
|
2823
|
-
if (titleMatch && titleMatch[1] !== "Error") {
|
|
2824
|
-
return titleMatch[1].trim();
|
|
2825
|
-
}
|
|
2826
|
-
if (h1Match) {
|
|
2827
|
-
return h1Match[1].trim();
|
|
2828
|
-
}
|
|
2829
|
-
if (bodyMatch) {
|
|
2830
|
-
const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
2831
|
-
return text.substring(0, 200);
|
|
2832
|
-
}
|
|
2833
|
-
return null;
|
|
2834
|
-
}
|
|
2835
|
-
/**
|
|
2836
|
-
* Truncate string to max length with ellipsis
|
|
2837
|
-
*/
|
|
2838
|
-
truncate(str, maxLength) {
|
|
2839
|
-
if (str.length <= maxLength) {
|
|
2840
|
-
return str;
|
|
2841
|
-
}
|
|
2842
|
-
return str.substring(0, maxLength) + "... [truncated]";
|
|
2843
|
-
}
|
|
2844
|
-
/**
|
|
2845
|
-
* Format bytes to human-readable size
|
|
2846
|
-
*/
|
|
2847
|
-
formatBytes(bytes) {
|
|
2848
|
-
if (bytes === 0) return "0 B";
|
|
2849
|
-
const k = 1024;
|
|
2850
|
-
const sizes = ["B", "KB", "MB", "GB"];
|
|
2851
|
-
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
2852
|
-
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
2853
|
-
}
|
|
2854
|
-
/**
|
|
2855
|
-
* Clean up old debug logs (older than 30 days)
|
|
2856
|
-
*/
|
|
2857
|
-
async cleanupOldLogs() {
|
|
2858
|
-
if (!this.fileLoggingEnabled) return;
|
|
2859
|
-
try {
|
|
2860
|
-
const debugDir = path5.join(os.homedir(), ".bike4mind", "debug");
|
|
2861
|
-
const files = await fs5.readdir(debugDir);
|
|
2862
|
-
const now = Date.now();
|
|
2863
|
-
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
2864
|
-
for (const file of files) {
|
|
2865
|
-
const filePath = path5.join(debugDir, file);
|
|
2866
|
-
const stats = await fs5.stat(filePath);
|
|
2867
|
-
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
2868
|
-
await fs5.unlink(filePath);
|
|
2869
|
-
}
|
|
2870
|
-
}
|
|
2871
|
-
} catch (error) {
|
|
2872
|
-
console.error("Failed to cleanup old logs:", error);
|
|
2873
|
-
}
|
|
2874
|
-
}
|
|
2875
|
-
};
|
|
2876
|
-
var logger = Logger2.getInstance();
|
|
2877
|
-
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
2878
2619
|
|
|
2879
2620
|
// src/utils/commandParser.ts
|
|
2621
|
+
import matter from "gray-matter";
|
|
2622
|
+
import { z } from "zod";
|
|
2880
2623
|
var flexibleString = z.union([z.string(), z.array(z.string())]).transform((val) => Array.isArray(val) ? val.join(" ") : val).optional();
|
|
2881
2624
|
var flexibleStringArray = z.union([z.string(), z.array(z.string())]).transform((val) => Array.isArray(val) ? val : [val]).optional();
|
|
2882
2625
|
function needsQuoting(value) {
|
|
@@ -3031,17 +2774,17 @@ function extractCommandName(filename) {
|
|
|
3031
2774
|
var CustomCommandStore = class {
|
|
3032
2775
|
constructor(projectRoot) {
|
|
3033
2776
|
this.commands = /* @__PURE__ */ new Map();
|
|
3034
|
-
const home =
|
|
2777
|
+
const home = os.homedir();
|
|
3035
2778
|
const root = projectRoot || process.cwd();
|
|
3036
2779
|
this.globalCommandsDirs = [
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
2780
|
+
path5.join(home, ".bike4mind", "commands"),
|
|
2781
|
+
path5.join(home, ".claude", "commands"),
|
|
2782
|
+
path5.join(home, ".claude", "skills")
|
|
3040
2783
|
];
|
|
3041
2784
|
this.projectCommandsDirs = [
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
2785
|
+
path5.join(root, ".bike4mind", "commands"),
|
|
2786
|
+
path5.join(root, ".claude", "commands"),
|
|
2787
|
+
path5.join(root, ".claude", "skills")
|
|
3045
2788
|
];
|
|
3046
2789
|
}
|
|
3047
2790
|
/**
|
|
@@ -3066,7 +2809,7 @@ var CustomCommandStore = class {
|
|
|
3066
2809
|
*/
|
|
3067
2810
|
async loadCommandsFromDirectory(directory, source) {
|
|
3068
2811
|
try {
|
|
3069
|
-
const stats = await
|
|
2812
|
+
const stats = await fs5.stat(directory);
|
|
3070
2813
|
if (!stats.isDirectory()) {
|
|
3071
2814
|
return;
|
|
3072
2815
|
}
|
|
@@ -3099,9 +2842,9 @@ var CustomCommandStore = class {
|
|
|
3099
2842
|
async findCommandFiles(directory) {
|
|
3100
2843
|
const files = [];
|
|
3101
2844
|
try {
|
|
3102
|
-
const entries = await
|
|
2845
|
+
const entries = await fs5.readdir(directory, { withFileTypes: true });
|
|
3103
2846
|
for (const entry of entries) {
|
|
3104
|
-
const fullPath =
|
|
2847
|
+
const fullPath = path5.join(directory, entry.name);
|
|
3105
2848
|
if (entry.isDirectory()) {
|
|
3106
2849
|
const subFiles = await this.findCommandFiles(fullPath);
|
|
3107
2850
|
files.push(...subFiles);
|
|
@@ -3121,14 +2864,14 @@ var CustomCommandStore = class {
|
|
|
3121
2864
|
* @param source - Source identifier ('global' or 'project')
|
|
3122
2865
|
*/
|
|
3123
2866
|
async loadCommandFile(filePath, source) {
|
|
3124
|
-
const filename =
|
|
2867
|
+
const filename = path5.basename(filePath);
|
|
3125
2868
|
const isSkillFile = filename.toLowerCase() === "skill.md";
|
|
3126
2869
|
const commandName = isSkillFile ? this.extractSkillName(filePath) : extractCommandName(filename);
|
|
3127
2870
|
if (!commandName) {
|
|
3128
2871
|
console.warn(`Invalid command filename: ${filename} (must end with .md and have valid name)`);
|
|
3129
2872
|
return;
|
|
3130
2873
|
}
|
|
3131
|
-
const fileContent = await
|
|
2874
|
+
const fileContent = await fs5.readFile(filePath, "utf-8");
|
|
3132
2875
|
const command = parseCommandFile(fileContent, filePath, commandName, source);
|
|
3133
2876
|
this.commands.set(commandName, command);
|
|
3134
2877
|
}
|
|
@@ -3140,7 +2883,7 @@ var CustomCommandStore = class {
|
|
|
3140
2883
|
* @returns Skill name or null if invalid
|
|
3141
2884
|
*/
|
|
3142
2885
|
extractSkillName(filePath) {
|
|
3143
|
-
const parentDir =
|
|
2886
|
+
const parentDir = path5.basename(path5.dirname(filePath));
|
|
3144
2887
|
return parentDir && parentDir !== "skills" ? parentDir : null;
|
|
3145
2888
|
}
|
|
3146
2889
|
/**
|
|
@@ -3202,15 +2945,15 @@ var CustomCommandStore = class {
|
|
|
3202
2945
|
*/
|
|
3203
2946
|
async createCommandFile(name, isGlobal = false) {
|
|
3204
2947
|
const targetDir = isGlobal ? this.globalCommandsDirs[0] : this.projectCommandsDirs[0];
|
|
3205
|
-
const filePath =
|
|
3206
|
-
const fileExists = await
|
|
2948
|
+
const filePath = path5.join(targetDir, `${name}.md`);
|
|
2949
|
+
const fileExists = await fs5.access(filePath).then(
|
|
3207
2950
|
() => true,
|
|
3208
2951
|
() => false
|
|
3209
2952
|
);
|
|
3210
2953
|
if (fileExists) {
|
|
3211
2954
|
throw new Error(`Command file already exists: ${filePath}`);
|
|
3212
2955
|
}
|
|
3213
|
-
await
|
|
2956
|
+
await fs5.mkdir(targetDir, { recursive: true });
|
|
3214
2957
|
const template = `---
|
|
3215
2958
|
description: ${name} command
|
|
3216
2959
|
argument-hint: [args]
|
|
@@ -3225,7 +2968,7 @@ You can use:
|
|
|
3225
2968
|
- $1, $2, etc. for positional arguments
|
|
3226
2969
|
- @filename for file references
|
|
3227
2970
|
`;
|
|
3228
|
-
await
|
|
2971
|
+
await fs5.writeFile(filePath, template, "utf-8");
|
|
3229
2972
|
return filePath;
|
|
3230
2973
|
}
|
|
3231
2974
|
};
|
|
@@ -4374,7 +4117,7 @@ import { GoogleGenerativeAI } from "@google/generative-ai";
|
|
|
4374
4117
|
import OpenAI2 from "openai";
|
|
4375
4118
|
|
|
4376
4119
|
// ../../b4m-core/packages/services/dist/src/importHistoryService/index.js
|
|
4377
|
-
import
|
|
4120
|
+
import fs6, { unlinkSync } from "fs";
|
|
4378
4121
|
import yauzl from "yauzl";
|
|
4379
4122
|
import axios3 from "axios";
|
|
4380
4123
|
|
|
@@ -6053,8 +5796,8 @@ async function processAndStoreImages(images, context) {
|
|
|
6053
5796
|
const buffer = await downloadImage(image);
|
|
6054
5797
|
const fileType = await fileTypeFromBuffer2(buffer);
|
|
6055
5798
|
const filename = `${uuidv45()}.${fileType?.ext}`;
|
|
6056
|
-
const
|
|
6057
|
-
return
|
|
5799
|
+
const path17 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
5800
|
+
return path17;
|
|
6058
5801
|
}));
|
|
6059
5802
|
}
|
|
6060
5803
|
async function updateQuestAndReturnMarkdown(storedImageUrls, context) {
|
|
@@ -7380,8 +7123,8 @@ async function processAndStoreImage(imageUrl, context) {
|
|
|
7380
7123
|
const buffer = await downloadImage2(imageUrl);
|
|
7381
7124
|
const fileType = await fileTypeFromBuffer3(buffer);
|
|
7382
7125
|
const filename = `${uuidv46()}.${fileType?.ext}`;
|
|
7383
|
-
const
|
|
7384
|
-
return
|
|
7126
|
+
const path17 = await context.imageGenerateStorage.upload(buffer, filename, {});
|
|
7127
|
+
return path17;
|
|
7385
7128
|
}
|
|
7386
7129
|
async function generateFullMask(imageBuffer) {
|
|
7387
7130
|
const sharp = (await import("sharp")).default;
|
|
@@ -9322,15 +9065,15 @@ var planetVisibilityTool = {
|
|
|
9322
9065
|
};
|
|
9323
9066
|
|
|
9324
9067
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/fileRead/index.js
|
|
9325
|
-
import { promises as
|
|
9068
|
+
import { promises as fs7 } from "fs";
|
|
9326
9069
|
import { existsSync as existsSync3, statSync as statSync4 } from "fs";
|
|
9327
|
-
import
|
|
9070
|
+
import path6 from "path";
|
|
9328
9071
|
var MAX_FILE_SIZE2 = 10 * 1024 * 1024;
|
|
9329
9072
|
async function readFileContent(params) {
|
|
9330
9073
|
const { path: filePath, encoding = "utf-8", offset = 0, limit } = params;
|
|
9331
|
-
const normalizedPath =
|
|
9332
|
-
const resolvedPath =
|
|
9333
|
-
const cwd =
|
|
9074
|
+
const normalizedPath = path6.normalize(filePath);
|
|
9075
|
+
const resolvedPath = path6.resolve(process.cwd(), normalizedPath);
|
|
9076
|
+
const cwd = path6.resolve(process.cwd());
|
|
9334
9077
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9335
9078
|
throw new Error(`Access denied: Cannot read files outside of current working directory`);
|
|
9336
9079
|
}
|
|
@@ -9348,7 +9091,7 @@ async function readFileContent(params) {
|
|
|
9348
9091
|
if (isBinary && encoding === "utf-8") {
|
|
9349
9092
|
throw new Error(`File appears to be binary. Use encoding 'base64' to read binary files, or specify a different encoding.`);
|
|
9350
9093
|
}
|
|
9351
|
-
const content = await
|
|
9094
|
+
const content = await fs7.readFile(resolvedPath, encoding);
|
|
9352
9095
|
if (typeof content === "string") {
|
|
9353
9096
|
const lines = content.split("\n");
|
|
9354
9097
|
const totalLines = lines.length;
|
|
@@ -9386,7 +9129,7 @@ ${content}`;
|
|
|
9386
9129
|
}
|
|
9387
9130
|
async function checkIfBinary(filePath) {
|
|
9388
9131
|
const buffer = Buffer.alloc(8192);
|
|
9389
|
-
const fd = await
|
|
9132
|
+
const fd = await fs7.open(filePath, "r");
|
|
9390
9133
|
try {
|
|
9391
9134
|
const { bytesRead } = await fd.read(buffer, 0, 8192, 0);
|
|
9392
9135
|
const chunk = buffer.slice(0, bytesRead);
|
|
@@ -9403,7 +9146,7 @@ var fileReadTool = {
|
|
|
9403
9146
|
context.logger.info("\u{1F4C4} FileRead: Reading file", { path: params.path });
|
|
9404
9147
|
try {
|
|
9405
9148
|
const content = await readFileContent(params);
|
|
9406
|
-
const stats = statSync4(
|
|
9149
|
+
const stats = statSync4(path6.resolve(process.cwd(), path6.normalize(params.path)));
|
|
9407
9150
|
context.logger.info("\u2705 FileRead: Success", {
|
|
9408
9151
|
path: params.path,
|
|
9409
9152
|
size: stats.size,
|
|
@@ -9447,25 +9190,25 @@ var fileReadTool = {
|
|
|
9447
9190
|
};
|
|
9448
9191
|
|
|
9449
9192
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/createFile/index.js
|
|
9450
|
-
import { promises as
|
|
9193
|
+
import { promises as fs8 } from "fs";
|
|
9451
9194
|
import { existsSync as existsSync4 } from "fs";
|
|
9452
|
-
import
|
|
9195
|
+
import path7 from "path";
|
|
9453
9196
|
async function createFile(params) {
|
|
9454
9197
|
const { path: filePath, content, createDirectories = true } = params;
|
|
9455
|
-
const normalizedPath =
|
|
9456
|
-
const resolvedPath =
|
|
9457
|
-
const cwd =
|
|
9198
|
+
const normalizedPath = path7.normalize(filePath);
|
|
9199
|
+
const resolvedPath = path7.resolve(process.cwd(), normalizedPath);
|
|
9200
|
+
const cwd = path7.resolve(process.cwd());
|
|
9458
9201
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9459
9202
|
throw new Error(`Access denied: Cannot create files outside of current working directory`);
|
|
9460
9203
|
}
|
|
9461
9204
|
const fileExists = existsSync4(resolvedPath);
|
|
9462
9205
|
const action = fileExists ? "overwritten" : "created";
|
|
9463
9206
|
if (createDirectories) {
|
|
9464
|
-
const dir =
|
|
9465
|
-
await
|
|
9207
|
+
const dir = path7.dirname(resolvedPath);
|
|
9208
|
+
await fs8.mkdir(dir, { recursive: true });
|
|
9466
9209
|
}
|
|
9467
|
-
await
|
|
9468
|
-
const stats = await
|
|
9210
|
+
await fs8.writeFile(resolvedPath, content, "utf-8");
|
|
9211
|
+
const stats = await fs8.stat(resolvedPath);
|
|
9469
9212
|
const lines = content.split("\n").length;
|
|
9470
9213
|
return `File ${action} successfully: ${filePath}
|
|
9471
9214
|
Size: ${stats.size} bytes
|
|
@@ -9476,7 +9219,7 @@ var createFileTool = {
|
|
|
9476
9219
|
implementation: (context) => ({
|
|
9477
9220
|
toolFn: async (value) => {
|
|
9478
9221
|
const params = value;
|
|
9479
|
-
const fileExists = existsSync4(
|
|
9222
|
+
const fileExists = existsSync4(path7.resolve(process.cwd(), path7.normalize(params.path)));
|
|
9480
9223
|
context.logger.info(`\u{1F4DD} CreateFile: ${fileExists ? "Overwriting" : "Creating"} file`, {
|
|
9481
9224
|
path: params.path,
|
|
9482
9225
|
size: params.content.length
|
|
@@ -9518,7 +9261,7 @@ var createFileTool = {
|
|
|
9518
9261
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/globFiles/index.js
|
|
9519
9262
|
import { glob } from "glob";
|
|
9520
9263
|
import { stat } from "fs/promises";
|
|
9521
|
-
import
|
|
9264
|
+
import path8 from "path";
|
|
9522
9265
|
var DEFAULT_IGNORE_PATTERNS2 = [
|
|
9523
9266
|
"**/node_modules/**",
|
|
9524
9267
|
"**/.git/**",
|
|
@@ -9534,7 +9277,7 @@ var DEFAULT_IGNORE_PATTERNS2 = [
|
|
|
9534
9277
|
async function findFiles(params) {
|
|
9535
9278
|
const { pattern, dir_path, case_sensitive = true, respect_git_ignore = true } = params;
|
|
9536
9279
|
const baseCwd = process.cwd();
|
|
9537
|
-
const targetDir = dir_path ?
|
|
9280
|
+
const targetDir = dir_path ? path8.resolve(baseCwd, path8.normalize(dir_path)) : baseCwd;
|
|
9538
9281
|
if (!targetDir.startsWith(baseCwd)) {
|
|
9539
9282
|
throw new Error(`Access denied: Cannot search outside of current working directory`);
|
|
9540
9283
|
}
|
|
@@ -9574,7 +9317,7 @@ async function findFiles(params) {
|
|
|
9574
9317
|
const summary = `Found ${filesWithStats.length} file(s)${truncated ? ` (showing first ${MAX_RESULTS})` : ""} matching: ${pattern}`;
|
|
9575
9318
|
const dirInfo = dir_path ? `
|
|
9576
9319
|
Directory: ${dir_path}` : "";
|
|
9577
|
-
const filesList = results.map((file) =>
|
|
9320
|
+
const filesList = results.map((file) => path8.relative(baseCwd, file.path)).join("\n");
|
|
9578
9321
|
return `${summary}${dirInfo}
|
|
9579
9322
|
|
|
9580
9323
|
${filesList}`;
|
|
@@ -9628,7 +9371,7 @@ var globFilesTool = {
|
|
|
9628
9371
|
|
|
9629
9372
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/grepSearch/index.js
|
|
9630
9373
|
import { stat as stat2 } from "fs/promises";
|
|
9631
|
-
import
|
|
9374
|
+
import path9 from "path";
|
|
9632
9375
|
import { execFile } from "child_process";
|
|
9633
9376
|
import { promisify } from "util";
|
|
9634
9377
|
import { createRequire } from "module";
|
|
@@ -9637,18 +9380,18 @@ var require2 = createRequire(import.meta.url);
|
|
|
9637
9380
|
function getRipgrepPath() {
|
|
9638
9381
|
try {
|
|
9639
9382
|
const ripgrepPath = require2.resolve("@vscode/ripgrep");
|
|
9640
|
-
const ripgrepDir =
|
|
9641
|
-
const rgBinary =
|
|
9383
|
+
const ripgrepDir = path9.dirname(ripgrepPath);
|
|
9384
|
+
const rgBinary = path9.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
|
|
9642
9385
|
return rgBinary;
|
|
9643
9386
|
} catch (error) {
|
|
9644
9387
|
throw new Error("ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services");
|
|
9645
9388
|
}
|
|
9646
9389
|
}
|
|
9647
9390
|
function isPathWithinWorkspace(targetPath, baseCwd) {
|
|
9648
|
-
const resolvedTarget =
|
|
9649
|
-
const resolvedBase =
|
|
9650
|
-
const relativePath =
|
|
9651
|
-
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);
|
|
9652
9395
|
}
|
|
9653
9396
|
function convertGlobToRipgrepGlobs(globPattern) {
|
|
9654
9397
|
if (!globPattern || globPattern === "**/*") {
|
|
@@ -9664,7 +9407,7 @@ function convertGlobToRipgrepGlobs(globPattern) {
|
|
|
9664
9407
|
async function searchFiles2(params) {
|
|
9665
9408
|
const { pattern, dir_path, include } = params;
|
|
9666
9409
|
const baseCwd = process.cwd();
|
|
9667
|
-
const targetDir = dir_path ?
|
|
9410
|
+
const targetDir = dir_path ? path9.resolve(baseCwd, dir_path) : baseCwd;
|
|
9668
9411
|
if (!isPathWithinWorkspace(targetDir, baseCwd)) {
|
|
9669
9412
|
throw new Error(`Path validation failed: "${dir_path}" resolves outside the allowed workspace directory`);
|
|
9670
9413
|
}
|
|
@@ -9726,7 +9469,7 @@ async function searchFiles2(params) {
|
|
|
9726
9469
|
if (item.type === "match") {
|
|
9727
9470
|
const match = item;
|
|
9728
9471
|
allMatches.push({
|
|
9729
|
-
filePath:
|
|
9472
|
+
filePath: path9.relative(targetDir, match.data.path.text) || path9.basename(match.data.path.text),
|
|
9730
9473
|
lineNumber: match.data.line_number,
|
|
9731
9474
|
line: match.data.lines.text.trimEnd()
|
|
9732
9475
|
// Remove trailing newline
|
|
@@ -9819,14 +9562,14 @@ var grepSearchTool = {
|
|
|
9819
9562
|
};
|
|
9820
9563
|
|
|
9821
9564
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/deleteFile/index.js
|
|
9822
|
-
import { promises as
|
|
9565
|
+
import { promises as fs9 } from "fs";
|
|
9823
9566
|
import { existsSync as existsSync5, statSync as statSync5 } from "fs";
|
|
9824
|
-
import
|
|
9567
|
+
import path10 from "path";
|
|
9825
9568
|
async function deleteFile(params) {
|
|
9826
9569
|
const { path: filePath, recursive = false } = params;
|
|
9827
|
-
const normalizedPath =
|
|
9828
|
-
const resolvedPath =
|
|
9829
|
-
const cwd =
|
|
9570
|
+
const normalizedPath = path10.normalize(filePath);
|
|
9571
|
+
const resolvedPath = path10.resolve(process.cwd(), normalizedPath);
|
|
9572
|
+
const cwd = path10.resolve(process.cwd());
|
|
9830
9573
|
if (!resolvedPath.startsWith(cwd)) {
|
|
9831
9574
|
throw new Error(`Access denied: Cannot delete files outside of current working directory`);
|
|
9832
9575
|
}
|
|
@@ -9840,10 +9583,10 @@ async function deleteFile(params) {
|
|
|
9840
9583
|
throw new Error(`Path is a directory: ${filePath}. Use recursive=true to delete directories and their contents.`);
|
|
9841
9584
|
}
|
|
9842
9585
|
if (isDirectory) {
|
|
9843
|
-
await
|
|
9586
|
+
await fs9.rm(resolvedPath, { recursive: true, force: true });
|
|
9844
9587
|
return `Directory deleted successfully: ${filePath}`;
|
|
9845
9588
|
} else {
|
|
9846
|
-
await
|
|
9589
|
+
await fs9.unlink(resolvedPath);
|
|
9847
9590
|
return `File deleted successfully: ${filePath}
|
|
9848
9591
|
Size: ${size} bytes`;
|
|
9849
9592
|
}
|
|
@@ -9853,7 +9596,7 @@ var deleteFileTool = {
|
|
|
9853
9596
|
implementation: (context) => ({
|
|
9854
9597
|
toolFn: async (value) => {
|
|
9855
9598
|
const params = value;
|
|
9856
|
-
const resolvedPath =
|
|
9599
|
+
const resolvedPath = path10.resolve(process.cwd(), path10.normalize(params.path));
|
|
9857
9600
|
const isDirectory = existsSync5(resolvedPath) && statSync5(resolvedPath).isDirectory();
|
|
9858
9601
|
context.logger.info(`\u{1F5D1}\uFE0F DeleteFile: Deleting ${isDirectory ? "directory" : "file"}`, {
|
|
9859
9602
|
path: params.path,
|
|
@@ -9979,7 +9722,7 @@ var knowledgeBaseSearchTool = {
|
|
|
9979
9722
|
|
|
9980
9723
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/bashExecute/index.js
|
|
9981
9724
|
import { spawn } from "child_process";
|
|
9982
|
-
import
|
|
9725
|
+
import path11 from "path";
|
|
9983
9726
|
var DEFAULT_TIMEOUT_MS = 6e4;
|
|
9984
9727
|
var MAX_OUTPUT_SIZE = 100 * 1024;
|
|
9985
9728
|
var DANGEROUS_PATTERNS = [
|
|
@@ -10163,7 +9906,7 @@ async function executeBashCommand(params) {
|
|
|
10163
9906
|
};
|
|
10164
9907
|
}
|
|
10165
9908
|
const baseCwd = process.cwd();
|
|
10166
|
-
const targetCwd = relativeCwd ?
|
|
9909
|
+
const targetCwd = relativeCwd ? path11.resolve(baseCwd, relativeCwd) : baseCwd;
|
|
10167
9910
|
const effectiveTimeout = Math.min(timeout, 5 * 60 * 1e3);
|
|
10168
9911
|
return new Promise((resolve3) => {
|
|
10169
9912
|
let stdout = "";
|
|
@@ -10353,9 +10096,9 @@ BLOCKED OPERATIONS:
|
|
|
10353
10096
|
};
|
|
10354
10097
|
|
|
10355
10098
|
// ../../b4m-core/packages/services/dist/src/llm/tools/implementation/editLocalFile/index.js
|
|
10356
|
-
import { promises as
|
|
10099
|
+
import { promises as fs10 } from "fs";
|
|
10357
10100
|
import { existsSync as existsSync6 } from "fs";
|
|
10358
|
-
import
|
|
10101
|
+
import path12 from "path";
|
|
10359
10102
|
import { diffLines as diffLines3 } from "diff";
|
|
10360
10103
|
function generateDiff(original, modified) {
|
|
10361
10104
|
const differences = diffLines3(original, modified);
|
|
@@ -10379,16 +10122,16 @@ function generateDiff(original, modified) {
|
|
|
10379
10122
|
}
|
|
10380
10123
|
async function editLocalFile(params) {
|
|
10381
10124
|
const { path: filePath, old_string, new_string } = params;
|
|
10382
|
-
const normalizedPath =
|
|
10383
|
-
const resolvedPath =
|
|
10384
|
-
const cwd =
|
|
10125
|
+
const normalizedPath = path12.normalize(filePath);
|
|
10126
|
+
const resolvedPath = path12.resolve(process.cwd(), normalizedPath);
|
|
10127
|
+
const cwd = path12.resolve(process.cwd());
|
|
10385
10128
|
if (!resolvedPath.startsWith(cwd)) {
|
|
10386
10129
|
throw new Error(`Access denied: Cannot edit files outside of current working directory`);
|
|
10387
10130
|
}
|
|
10388
10131
|
if (!existsSync6(resolvedPath)) {
|
|
10389
10132
|
throw new Error(`File not found: ${filePath}`);
|
|
10390
10133
|
}
|
|
10391
|
-
const currentContent = await
|
|
10134
|
+
const currentContent = await fs10.readFile(resolvedPath, "utf-8");
|
|
10392
10135
|
if (!currentContent.includes(old_string)) {
|
|
10393
10136
|
const preview = old_string.length > 100 ? old_string.substring(0, 100) + "..." : old_string;
|
|
10394
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}"`);
|
|
@@ -10398,7 +10141,7 @@ async function editLocalFile(params) {
|
|
|
10398
10141
|
throw new Error(`Found ${occurrences} occurrences of the string to replace. Please provide a more specific old_string that matches exactly one location.`);
|
|
10399
10142
|
}
|
|
10400
10143
|
const newContent = currentContent.replace(old_string, new_string);
|
|
10401
|
-
await
|
|
10144
|
+
await fs10.writeFile(resolvedPath, newContent, "utf-8");
|
|
10402
10145
|
const diffResult = generateDiff(old_string, new_string);
|
|
10403
10146
|
return `File edited successfully: ${filePath}
|
|
10404
10147
|
Changes: +${diffResult.additions} lines, -${diffResult.deletions} lines
|
|
@@ -11618,7 +11361,7 @@ async function generateFileDeletePreview(args) {
|
|
|
11618
11361
|
if (!existsSync7(args.path)) {
|
|
11619
11362
|
return `[File does not exist: ${args.path}]`;
|
|
11620
11363
|
}
|
|
11621
|
-
const stats = await import("fs/promises").then((
|
|
11364
|
+
const stats = await import("fs/promises").then((fs13) => fs13.stat(args.path));
|
|
11622
11365
|
return `[File will be deleted]
|
|
11623
11366
|
|
|
11624
11367
|
Path: ${args.path}
|
|
@@ -11909,21 +11652,21 @@ var NoOpStorage = class extends BaseStorage {
|
|
|
11909
11652
|
async upload(input, destination, options) {
|
|
11910
11653
|
return `/tmp/${destination}`;
|
|
11911
11654
|
}
|
|
11912
|
-
async download(
|
|
11655
|
+
async download(path17) {
|
|
11913
11656
|
throw new Error("Download not supported in CLI");
|
|
11914
11657
|
}
|
|
11915
|
-
async delete(
|
|
11658
|
+
async delete(path17) {
|
|
11916
11659
|
}
|
|
11917
|
-
async getSignedUrl(
|
|
11918
|
-
return `/tmp/${
|
|
11660
|
+
async getSignedUrl(path17) {
|
|
11661
|
+
return `/tmp/${path17}`;
|
|
11919
11662
|
}
|
|
11920
|
-
getPublicUrl(
|
|
11921
|
-
return `/tmp/${
|
|
11663
|
+
getPublicUrl(path17) {
|
|
11664
|
+
return `/tmp/${path17}`;
|
|
11922
11665
|
}
|
|
11923
|
-
async getPreview(
|
|
11924
|
-
return `/tmp/${
|
|
11666
|
+
async getPreview(path17) {
|
|
11667
|
+
return `/tmp/${path17}`;
|
|
11925
11668
|
}
|
|
11926
|
-
async getMetadata(
|
|
11669
|
+
async getMetadata(path17) {
|
|
11927
11670
|
return { size: 0, contentType: "application/octet-stream" };
|
|
11928
11671
|
}
|
|
11929
11672
|
};
|
|
@@ -12329,8 +12072,8 @@ function getEnvironmentName(configApiConfig) {
|
|
|
12329
12072
|
}
|
|
12330
12073
|
|
|
12331
12074
|
// src/utils/contextLoader.ts
|
|
12332
|
-
import * as
|
|
12333
|
-
import * as
|
|
12075
|
+
import * as fs11 from "fs";
|
|
12076
|
+
import * as path13 from "path";
|
|
12334
12077
|
import { homedir as homedir3 } from "os";
|
|
12335
12078
|
var CONTEXT_FILE_SIZE_LIMIT = 100 * 1024;
|
|
12336
12079
|
var PROJECT_CONTEXT_FILES = [
|
|
@@ -12351,9 +12094,9 @@ function formatFileSize2(bytes) {
|
|
|
12351
12094
|
return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
|
|
12352
12095
|
}
|
|
12353
12096
|
function tryReadContextFile(dir, filename, source) {
|
|
12354
|
-
const filePath =
|
|
12097
|
+
const filePath = path13.join(dir, filename);
|
|
12355
12098
|
try {
|
|
12356
|
-
const stats =
|
|
12099
|
+
const stats = fs11.lstatSync(filePath);
|
|
12357
12100
|
if (stats.isDirectory()) {
|
|
12358
12101
|
return null;
|
|
12359
12102
|
}
|
|
@@ -12367,7 +12110,7 @@ function tryReadContextFile(dir, filename, source) {
|
|
|
12367
12110
|
error: `${source === "global" ? "Global" : "Project"} ${filename} exceeds 100KB limit (${formatFileSize2(stats.size)})`
|
|
12368
12111
|
};
|
|
12369
12112
|
}
|
|
12370
|
-
const content =
|
|
12113
|
+
const content = fs11.readFileSync(filePath, "utf-8");
|
|
12371
12114
|
return {
|
|
12372
12115
|
filename,
|
|
12373
12116
|
content,
|
|
@@ -12419,7 +12162,7 @@ ${project.content}`;
|
|
|
12419
12162
|
}
|
|
12420
12163
|
async function loadContextFiles(projectDir) {
|
|
12421
12164
|
const errors = [];
|
|
12422
|
-
const globalDir =
|
|
12165
|
+
const globalDir = path13.join(homedir3(), ".bike4mind");
|
|
12423
12166
|
const projectDirectory = projectDir || process.cwd();
|
|
12424
12167
|
const [globalResult, projectResult] = await Promise.all([
|
|
12425
12168
|
Promise.resolve(findContextFile(globalDir, GLOBAL_CONTEXT_FILES, "global")),
|
|
@@ -12690,7 +12433,7 @@ function substituteArguments(template, args) {
|
|
|
12690
12433
|
// ../../b4m-core/packages/mcp/dist/src/client.js
|
|
12691
12434
|
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
12692
12435
|
import { Client as Client2 } from "@modelcontextprotocol/sdk/client/index.js";
|
|
12693
|
-
import
|
|
12436
|
+
import path14 from "path";
|
|
12694
12437
|
import { existsSync as existsSync8, readdirSync as readdirSync3 } from "fs";
|
|
12695
12438
|
var MCPClient = class {
|
|
12696
12439
|
// Note: This class handles MCP server communication with repository filtering
|
|
@@ -12728,21 +12471,20 @@ var MCPClient = class {
|
|
|
12728
12471
|
if (this.customCommand && this.customCommand.trim() !== "") {
|
|
12729
12472
|
command = this.customCommand;
|
|
12730
12473
|
args = this.customArgs ?? [];
|
|
12731
|
-
console.log(`[MCP] Using external command for ${this.serverName}: ${command} ${args.join(" ")}`);
|
|
12732
12474
|
} else {
|
|
12733
12475
|
const root = process.env.INIT_CWD || process.cwd();
|
|
12734
12476
|
const candidatePaths = [
|
|
12735
12477
|
// When running from SST Lambda with node_modules structure (copyFiles)
|
|
12736
|
-
|
|
12478
|
+
path14.join(root, `node_modules/@bike4mind/mcp/dist/src/${this.serverName}/index.js`),
|
|
12737
12479
|
// When running from SST Lambda deployed environment (/var/task)
|
|
12738
|
-
|
|
12480
|
+
path14.join(root, `b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12739
12481
|
// When running from SST Lambda (.sst/artifacts/mcpHandler-dev), navigate to monorepo root (3 levels up)
|
|
12740
|
-
|
|
12482
|
+
path14.join(root, `../../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12741
12483
|
// When running from packages/client (Next.js app), navigate to monorepo root (2 levels up)
|
|
12742
|
-
|
|
12484
|
+
path14.join(root, `../../b4m-core/packages/mcp/dist/src/${this.serverName}/index.js`),
|
|
12743
12485
|
// Original paths (backward compatibility)
|
|
12744
|
-
|
|
12745
|
-
|
|
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")
|
|
12746
12488
|
];
|
|
12747
12489
|
const serverScriptPath = candidatePaths.find((p) => existsSync8(p));
|
|
12748
12490
|
if (!serverScriptPath) {
|
|
@@ -13557,7 +13299,7 @@ var ServerLlmBackend = class {
|
|
|
13557
13299
|
logger.info("\u26A0\uFE0F Using fallback model list (no CLI-compatible models available)");
|
|
13558
13300
|
return this.getFallbackModels();
|
|
13559
13301
|
}
|
|
13560
|
-
logger.
|
|
13302
|
+
logger.debug(`\u{1F4CB} Loaded ${filteredModels.length} models from server`);
|
|
13561
13303
|
return filteredModels;
|
|
13562
13304
|
} catch (error) {
|
|
13563
13305
|
logger.warn(
|
|
@@ -13795,7 +13537,7 @@ import { isAxiosError as isAxiosError2 } from "axios";
|
|
|
13795
13537
|
// package.json
|
|
13796
13538
|
var package_default = {
|
|
13797
13539
|
name: "@bike4mind/cli",
|
|
13798
|
-
version: "0.2.29-cli-minimal-ui.
|
|
13540
|
+
version: "0.2.29-cli-minimal-ui.18783+9aba9e61e",
|
|
13799
13541
|
type: "module",
|
|
13800
13542
|
description: "Interactive CLI tool for Bike4Mind with ReAct agents",
|
|
13801
13543
|
license: "UNLICENSED",
|
|
@@ -13903,10 +13645,10 @@ var package_default = {
|
|
|
13903
13645
|
},
|
|
13904
13646
|
devDependencies: {
|
|
13905
13647
|
"@bike4mind/agents": "0.1.0",
|
|
13906
|
-
"@bike4mind/common": "2.50.1-cli-minimal-ui.
|
|
13907
|
-
"@bike4mind/mcp": "1.29.1-cli-minimal-ui.
|
|
13908
|
-
"@bike4mind/services": "2.48.1-cli-minimal-ui.
|
|
13909
|
-
"@bike4mind/utils": "2.5.1-cli-minimal-ui.
|
|
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",
|
|
13910
13652
|
"@types/better-sqlite3": "^7.6.13",
|
|
13911
13653
|
"@types/diff": "^5.0.9",
|
|
13912
13654
|
"@types/jsonwebtoken": "^9.0.4",
|
|
@@ -13923,7 +13665,7 @@ var package_default = {
|
|
|
13923
13665
|
optionalDependencies: {
|
|
13924
13666
|
"@vscode/ripgrep": "^1.17.0"
|
|
13925
13667
|
},
|
|
13926
|
-
gitHead: "
|
|
13668
|
+
gitHead: "9aba9e61e1fb7e03dfd87a2e777c8e0e4e16fbbd"
|
|
13927
13669
|
};
|
|
13928
13670
|
|
|
13929
13671
|
// src/config/constants.ts
|
|
@@ -14416,9 +14158,9 @@ var SubagentOrchestrator = class {
|
|
|
14416
14158
|
};
|
|
14417
14159
|
|
|
14418
14160
|
// src/agents/AgentStore.ts
|
|
14419
|
-
import
|
|
14420
|
-
import
|
|
14421
|
-
import
|
|
14161
|
+
import fs12 from "fs/promises";
|
|
14162
|
+
import path15 from "path";
|
|
14163
|
+
import os2 from "os";
|
|
14422
14164
|
import matter2 from "gray-matter";
|
|
14423
14165
|
var FULL_MODEL_ID_PREFIXES = [
|
|
14424
14166
|
"claude-",
|
|
@@ -14564,12 +14306,12 @@ var AgentStore = class {
|
|
|
14564
14306
|
constructor(builtinDir, projectRoot) {
|
|
14565
14307
|
this.agents = /* @__PURE__ */ new Map();
|
|
14566
14308
|
const root = projectRoot || process.cwd();
|
|
14567
|
-
const home =
|
|
14309
|
+
const home = os2.homedir();
|
|
14568
14310
|
this.builtinAgentsDir = builtinDir;
|
|
14569
|
-
this.globalB4MAgentsDir =
|
|
14570
|
-
this.globalClaudeAgentsDir =
|
|
14571
|
-
this.projectB4MAgentsDir =
|
|
14572
|
-
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");
|
|
14573
14315
|
}
|
|
14574
14316
|
/**
|
|
14575
14317
|
* Load all agents from all directories
|
|
@@ -14593,7 +14335,7 @@ var AgentStore = class {
|
|
|
14593
14335
|
*/
|
|
14594
14336
|
async loadAgentsFromDirectory(directory, source) {
|
|
14595
14337
|
try {
|
|
14596
|
-
const stats = await
|
|
14338
|
+
const stats = await fs12.stat(directory);
|
|
14597
14339
|
if (!stats.isDirectory()) {
|
|
14598
14340
|
return;
|
|
14599
14341
|
}
|
|
@@ -14621,9 +14363,9 @@ var AgentStore = class {
|
|
|
14621
14363
|
async findAgentFiles(directory) {
|
|
14622
14364
|
const files = [];
|
|
14623
14365
|
try {
|
|
14624
|
-
const entries = await
|
|
14366
|
+
const entries = await fs12.readdir(directory, { withFileTypes: true });
|
|
14625
14367
|
for (const entry of entries) {
|
|
14626
|
-
const fullPath =
|
|
14368
|
+
const fullPath = path15.join(directory, entry.name);
|
|
14627
14369
|
if (entry.isDirectory()) {
|
|
14628
14370
|
const subFiles = await this.findAgentFiles(fullPath);
|
|
14629
14371
|
files.push(...subFiles);
|
|
@@ -14640,10 +14382,10 @@ var AgentStore = class {
|
|
|
14640
14382
|
* Parse a single agent markdown file
|
|
14641
14383
|
*/
|
|
14642
14384
|
async parseAgentFile(filePath, source) {
|
|
14643
|
-
const content = await
|
|
14385
|
+
const content = await fs12.readFile(filePath, "utf-8");
|
|
14644
14386
|
const { data: frontmatter, content: body } = matter2(content);
|
|
14645
14387
|
const parsed = AgentFrontmatterSchema.parse(frontmatter);
|
|
14646
|
-
const name =
|
|
14388
|
+
const name = path15.basename(filePath, ".md");
|
|
14647
14389
|
const modelInput = parsed.model || DEFAULT_AGENT_MODEL;
|
|
14648
14390
|
const resolution = resolveModelAlias(modelInput, name, filePath);
|
|
14649
14391
|
if (!resolution.resolved && resolution.warning) {
|
|
@@ -14723,16 +14465,16 @@ var AgentStore = class {
|
|
|
14723
14465
|
*/
|
|
14724
14466
|
async createAgentFile(name, isGlobal = false, useClaude = true) {
|
|
14725
14467
|
const targetDir = isGlobal ? useClaude ? this.globalClaudeAgentsDir : this.globalB4MAgentsDir : useClaude ? this.projectClaudeAgentsDir : this.projectB4MAgentsDir;
|
|
14726
|
-
const filePath =
|
|
14468
|
+
const filePath = path15.join(targetDir, `${name}.md`);
|
|
14727
14469
|
try {
|
|
14728
|
-
await
|
|
14470
|
+
await fs12.access(filePath);
|
|
14729
14471
|
throw new Error(`Agent file already exists: ${filePath}`);
|
|
14730
14472
|
} catch (error) {
|
|
14731
14473
|
if (error.code !== "ENOENT") {
|
|
14732
14474
|
throw error;
|
|
14733
14475
|
}
|
|
14734
14476
|
}
|
|
14735
|
-
await
|
|
14477
|
+
await fs12.mkdir(targetDir, { recursive: true });
|
|
14736
14478
|
const template = `---
|
|
14737
14479
|
description: ${name} agent description
|
|
14738
14480
|
model: claude-3-5-haiku-20241022
|
|
@@ -14767,7 +14509,7 @@ You are a ${name} specialist. Your job is to [describe primary task].
|
|
|
14767
14509
|
## Output Format
|
|
14768
14510
|
Describe the expected output format here.
|
|
14769
14511
|
`;
|
|
14770
|
-
await
|
|
14512
|
+
await fs12.writeFile(filePath, template, "utf-8");
|
|
14771
14513
|
return filePath;
|
|
14772
14514
|
}
|
|
14773
14515
|
/**
|
|
@@ -15405,7 +15147,7 @@ function createTodoStore(onUpdate) {
|
|
|
15405
15147
|
|
|
15406
15148
|
// src/tools/findDefinitionTool.ts
|
|
15407
15149
|
import { stat as stat3 } from "fs/promises";
|
|
15408
|
-
import
|
|
15150
|
+
import path16 from "path";
|
|
15409
15151
|
import { execFile as execFile2 } from "child_process";
|
|
15410
15152
|
import { promisify as promisify2 } from "util";
|
|
15411
15153
|
import { createRequire as createRequire2 } from "module";
|
|
@@ -15426,8 +15168,8 @@ var ALL_KEYWORDS = Object.values(KIND_KEYWORDS).flat();
|
|
|
15426
15168
|
function getRipgrepPath2() {
|
|
15427
15169
|
try {
|
|
15428
15170
|
const ripgrepPath = require3.resolve("@vscode/ripgrep");
|
|
15429
|
-
const ripgrepDir =
|
|
15430
|
-
return
|
|
15171
|
+
const ripgrepDir = path16.dirname(ripgrepPath);
|
|
15172
|
+
return path16.join(ripgrepDir, "..", "bin", "rg" + (process.platform === "win32" ? ".exe" : ""));
|
|
15431
15173
|
} catch {
|
|
15432
15174
|
throw new Error(
|
|
15433
15175
|
"ripgrep is not available. Please install @vscode/ripgrep: pnpm add @vscode/ripgrep --filter @bike4mind/services"
|
|
@@ -15435,10 +15177,10 @@ function getRipgrepPath2() {
|
|
|
15435
15177
|
}
|
|
15436
15178
|
}
|
|
15437
15179
|
function isPathWithinWorkspace2(targetPath, baseCwd) {
|
|
15438
|
-
const resolvedTarget =
|
|
15439
|
-
const resolvedBase =
|
|
15440
|
-
const relativePath =
|
|
15441
|
-
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);
|
|
15442
15184
|
}
|
|
15443
15185
|
function escapeRegex(str) {
|
|
15444
15186
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
@@ -15471,7 +15213,7 @@ async function findDefinitions(params) {
|
|
|
15471
15213
|
throw new Error("symbol_name is required");
|
|
15472
15214
|
}
|
|
15473
15215
|
const baseCwd = process.cwd();
|
|
15474
|
-
const targetDir = search_path ?
|
|
15216
|
+
const targetDir = search_path ? path16.resolve(baseCwd, search_path) : baseCwd;
|
|
15475
15217
|
if (!isPathWithinWorkspace2(targetDir, baseCwd)) {
|
|
15476
15218
|
throw new Error(`Path validation failed: "${search_path}" resolves outside the allowed workspace directory`);
|
|
15477
15219
|
}
|
|
@@ -15526,7 +15268,7 @@ async function findDefinitions(params) {
|
|
|
15526
15268
|
const lineText = match.data.lines.text.trimEnd();
|
|
15527
15269
|
if (isLikelyDefinition(lineText)) {
|
|
15528
15270
|
allMatches.push({
|
|
15529
|
-
filePath:
|
|
15271
|
+
filePath: path16.relative(targetDir, match.data.path.text) || path16.basename(match.data.path.text),
|
|
15530
15272
|
lineNumber: match.data.line_number,
|
|
15531
15273
|
line: lineText
|
|
15532
15274
|
});
|
|
@@ -15719,6 +15461,7 @@ function CliApp() {
|
|
|
15719
15461
|
});
|
|
15720
15462
|
const init = useCallback2(async () => {
|
|
15721
15463
|
try {
|
|
15464
|
+
const startupLog = [];
|
|
15722
15465
|
const config = await state.configStore.load();
|
|
15723
15466
|
const history = await state.commandHistoryStore.load();
|
|
15724
15467
|
setCommandHistory(history);
|
|
@@ -15726,7 +15469,7 @@ function CliApp() {
|
|
|
15726
15469
|
await state.customCommandStore.loadCommands();
|
|
15727
15470
|
const customCommandCount = state.customCommandStore.getCommandCount();
|
|
15728
15471
|
if (customCommandCount > 0) {
|
|
15729
|
-
|
|
15472
|
+
startupLog.push(`\u{1F4DD} Loaded ${customCommandCount} custom command${customCommandCount !== 1 ? "s" : ""}`);
|
|
15730
15473
|
}
|
|
15731
15474
|
} catch (error) {
|
|
15732
15475
|
console.warn("Failed to load custom commands:", error instanceof Error ? error.message : String(error));
|
|
@@ -15747,7 +15490,7 @@ function CliApp() {
|
|
|
15747
15490
|
} else {
|
|
15748
15491
|
isAuthenticated = true;
|
|
15749
15492
|
const daysUntilExpiry = Math.floor((expiresAt.getTime() - Date.now()) / (1e3 * 60 * 60 * 24));
|
|
15750
|
-
|
|
15493
|
+
startupLog.push(`\u2705 Authenticated (expires in ${daysUntilExpiry} day${daysUntilExpiry !== 1 ? "s" : ""})`);
|
|
15751
15494
|
}
|
|
15752
15495
|
}
|
|
15753
15496
|
if (!isAuthenticated) {
|
|
@@ -15861,23 +15604,23 @@ function CliApp() {
|
|
|
15861
15604
|
state.configStore,
|
|
15862
15605
|
apiClient
|
|
15863
15606
|
);
|
|
15864
|
-
|
|
15607
|
+
startupLog.push(`\u{1F6E0}\uFE0F Loaded ${b4mTools2.length} B4M tool(s)`);
|
|
15865
15608
|
const mcpManager = new McpManager(config);
|
|
15866
15609
|
await mcpManager.initialize();
|
|
15867
15610
|
const mcpTools = mcpManager.getTools();
|
|
15868
15611
|
if (mcpTools.length > 0) {
|
|
15869
15612
|
const toolCountByServer = mcpManager.getToolCount();
|
|
15870
15613
|
const serverSummaries = toolCountByServer.map((s) => `${s.serverName} (${s.count})`).join(", ");
|
|
15871
|
-
|
|
15614
|
+
startupLog.push(`\u{1F4E1} Loaded ${mcpTools.length} MCP tool(s): ${serverSummaries}`);
|
|
15872
15615
|
} else {
|
|
15873
|
-
|
|
15616
|
+
startupLog.push(`\u{1F4E1} No MCP tools loaded`);
|
|
15874
15617
|
}
|
|
15875
15618
|
const builtinAgentsDir = new URL("./agents/defaults/", import.meta.url).pathname;
|
|
15876
15619
|
const agentProjectDir = state.configStore.getProjectConfigDir();
|
|
15877
15620
|
const agentStore = new AgentStore(builtinAgentsDir, agentProjectDir || process.cwd());
|
|
15878
15621
|
await agentStore.loadAgents();
|
|
15879
15622
|
const agentSummary = agentStore.getSummary();
|
|
15880
|
-
|
|
15623
|
+
startupLog.push(
|
|
15881
15624
|
`\u{1F916} Loaded ${agentSummary.total} agent(s): ${agentSummary.builtin} built-in, ${agentSummary.global} global, ${agentSummary.project} project`
|
|
15882
15625
|
);
|
|
15883
15626
|
const orchestrator = new SubagentOrchestrator({
|
|
@@ -15917,13 +15660,13 @@ function CliApp() {
|
|
|
15917
15660
|
cliTools.push(skillTool);
|
|
15918
15661
|
}
|
|
15919
15662
|
const allTools = [...b4mTools2, ...mcpTools, ...cliTools];
|
|
15920
|
-
|
|
15663
|
+
startupLog.push(`\u{1F4C2} Working directory: ${process.cwd()}`);
|
|
15921
15664
|
const agentNamesList = agentStore.getAgentNames().join(", ");
|
|
15922
|
-
|
|
15665
|
+
startupLog.push(`\u{1F916} Subagent delegation enabled (${agentNamesList}) + background execution`);
|
|
15923
15666
|
if (skillTool) {
|
|
15924
15667
|
const skillCount = state.customCommandStore.getCommandCount();
|
|
15925
15668
|
if (skillCount > 0) {
|
|
15926
|
-
|
|
15669
|
+
startupLog.push(`\u{1F6E0}\uFE0F Skill tool enabled (${skillCount} skills available)`);
|
|
15927
15670
|
}
|
|
15928
15671
|
}
|
|
15929
15672
|
logger.debug(
|
|
@@ -15932,13 +15675,13 @@ function CliApp() {
|
|
|
15932
15675
|
const projectDir = state.configStore.getProjectConfigDir();
|
|
15933
15676
|
const contextResult = await loadContextFiles(projectDir);
|
|
15934
15677
|
if (contextResult.globalContext) {
|
|
15935
|
-
|
|
15678
|
+
startupLog.push(`\u{1F4C4} Global context: ${contextResult.globalContext.filename}`);
|
|
15936
15679
|
}
|
|
15937
15680
|
if (contextResult.projectContext) {
|
|
15938
|
-
|
|
15681
|
+
startupLog.push(`\u{1F4C4} Project context: ${contextResult.projectContext.filename}`);
|
|
15939
15682
|
}
|
|
15940
15683
|
for (const error of contextResult.errors) {
|
|
15941
|
-
|
|
15684
|
+
startupLog.push(`\u26A0\uFE0F Context file error: ${error}`);
|
|
15942
15685
|
}
|
|
15943
15686
|
let contextSection = contextResult.mergedContent ? `
|
|
15944
15687
|
|
|
@@ -16014,8 +15757,36 @@ ${contextResult.mergedContent}` : "";
|
|
|
16014
15757
|
// Store for grouped notification turn tracking
|
|
16015
15758
|
}));
|
|
16016
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
|
+
}
|
|
16017
15788
|
setIsInitialized(true);
|
|
16018
|
-
console.log("
|
|
15789
|
+
console.log("");
|
|
16019
15790
|
} catch (error) {
|
|
16020
15791
|
console.error("Initialization error:", error);
|
|
16021
15792
|
setInitError(error instanceof Error ? error.message : "Unknown error");
|
|
@@ -17598,17 +17369,6 @@ No usage data available for the last ${USAGE_DAYS} days.`);
|
|
|
17598
17369
|
}
|
|
17599
17370
|
);
|
|
17600
17371
|
}
|
|
17601
|
-
var BANNER = `
|
|
17602
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2557 \u2588\u2588\u2557\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2557
|
|
17603
|
-
\u2588\u2588\u2554\u2550\u2550\u2588\u2588\u2557\u2588\u2588\u2551 \u2588\u2588\u2551\u2588\u2588\u2588\u2588\u2557 \u2588\u2588\u2588\u2588\u2551
|
|
17604
|
-
\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
|
|
17605
|
-
\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
|
|
17606
|
-
\u2588\u2588\u2588\u2588\u2588\u2588\u2554\u255D \u2588\u2588\u2551\u2588\u2588\u2551 \u255A\u2550\u255D \u2588\u2588\u2551
|
|
17607
|
-
\u255A\u2550\u2550\u2550\u2550\u2550\u255D \u255A\u2550\u255D\u255A\u2550\u255D \u255A\u2550\u255D
|
|
17608
|
-
`;
|
|
17609
|
-
console.log("\x1B[36m\x1B[1m%s\x1B[0m", BANNER);
|
|
17610
|
-
console.log(`\x1B[2m v${package_default.version} - AI-Powered CLI\x1B[0m`);
|
|
17611
|
-
console.log(" /help for more information\n");
|
|
17612
17372
|
var isDevMode = import.meta.url.includes("/src/") || process.env.NODE_ENV === "development";
|
|
17613
17373
|
if (isDevMode) {
|
|
17614
17374
|
logger.debug("\u{1F527} Running in development mode (using TypeScript source)\n");
|