@bike4mind/cli 0.2.28 → 0.2.29-chore-upgrade-zod4.18830
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/{artifactExtractor-36XHJYOZ.js → artifactExtractor-27P4HWVG.js} +1 -1
- package/dist/{chunk-23T2XGSZ.js → chunk-32PKF3N7.js} +306 -48
- package/dist/{chunk-ZEMWV6IR.js → chunk-5N5BUX3M.js} +3 -3
- package/dist/{chunk-XJRPAAUS.js → chunk-BWPGS3D5.js} +70 -54
- package/dist/{chunk-VGYTNJXN.js → chunk-HNSRXAYI.js} +16 -16
- package/dist/{chunk-JJBDHUGY.js → chunk-SKFGGFJW.js} +2 -2
- package/dist/{chunk-UNOJBVD2.js → chunk-W3S2VCLO.js} +67 -2
- package/dist/commands/mcpCommand.js +1 -1
- package/dist/{create-NGI7IIQ4.js → create-GOET2XCC.js} +3 -3
- package/dist/index.js +476 -578
- package/dist/{llmMarkdownGenerator-JDYKJUEC.js → llmMarkdownGenerator-N5XJNQUJ.js} +1 -1
- package/dist/{markdownGenerator-QXBC2EW5.js → markdownGenerator-JLORGV26.js} +1 -1
- package/dist/{mementoService-X35OMHVC.js → mementoService-LLULBR3T.js} +3 -3
- package/dist/{src-CBU6EAO3.js → src-ATJY6LJR.js} +4 -2
- package/dist/{src-6NIYIWZD.js → src-LINT6EUA.js} +1 -1
- package/dist/{subtractCredits-RL6JVDMI.js → subtractCredits-MH2TQMAG.js} +3 -3
- package/dist/treeSitterEngine-4SGFQDY3.js +330 -0
- package/package.json +11 -9
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ While in interactive mode:
|
|
|
101
101
|
|
|
102
102
|
**Session Management:**
|
|
103
103
|
- `/save <name>` - Save current session
|
|
104
|
-
- `/
|
|
104
|
+
- `/resume` - List and resume saved sessions
|
|
105
105
|
|
|
106
106
|
**API Configuration:**
|
|
107
107
|
- `/set-api <url>` - Connect to self-hosted Bike4Mind instance
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
3
|
CurationArtifactType
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-BWPGS3D5.js";
|
|
5
5
|
|
|
6
6
|
// ../../b4m-core/packages/services/dist/src/notebookCurationService/artifactExtractor.js
|
|
7
7
|
var ARTIFACT_TAG_REGEX = /<artifact\s+(.*?)>([\s\S]*?)<\/artifact>/gi;
|
|
@@ -1,8 +1,264 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
// src/
|
|
4
|
-
import
|
|
3
|
+
// src/utils/Logger.ts
|
|
4
|
+
import fs from "fs/promises";
|
|
5
5
|
import path from "path";
|
|
6
|
+
import os from "os";
|
|
7
|
+
var Logger = class _Logger {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.logFilePath = null;
|
|
10
|
+
this.sessionId = null;
|
|
11
|
+
this.fileLoggingEnabled = true;
|
|
12
|
+
this.consoleVerbose = false;
|
|
13
|
+
}
|
|
14
|
+
static {
|
|
15
|
+
this.instance = null;
|
|
16
|
+
}
|
|
17
|
+
static getInstance() {
|
|
18
|
+
if (!_Logger.instance) {
|
|
19
|
+
_Logger.instance = new _Logger();
|
|
20
|
+
}
|
|
21
|
+
return _Logger.instance;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Initialize the logger with a session ID
|
|
25
|
+
*/
|
|
26
|
+
async initialize(sessionId) {
|
|
27
|
+
this.sessionId = sessionId;
|
|
28
|
+
const debugDir = path.join(os.homedir(), ".bike4mind", "debug");
|
|
29
|
+
await fs.mkdir(debugDir, { recursive: true });
|
|
30
|
+
this.logFilePath = path.join(debugDir, `${sessionId}.txt`);
|
|
31
|
+
await this.writeToFile("INFO", "=== CLI SESSION START ===");
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Set whether verbose console logging is enabled
|
|
35
|
+
*/
|
|
36
|
+
setVerbose(enabled) {
|
|
37
|
+
this.consoleVerbose = enabled;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Set whether file logging is enabled
|
|
41
|
+
*/
|
|
42
|
+
setFileLoggingEnabled(enabled) {
|
|
43
|
+
this.fileLoggingEnabled = enabled;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* DEBUG level - verbose-only console, always file
|
|
47
|
+
*/
|
|
48
|
+
debug(message) {
|
|
49
|
+
this.writeToFile("DEBUG", message).catch(() => {
|
|
50
|
+
});
|
|
51
|
+
if (this.consoleVerbose) {
|
|
52
|
+
console.log(message);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* INFO level - always shown to user
|
|
57
|
+
*/
|
|
58
|
+
info(message) {
|
|
59
|
+
this.writeToFile("INFO", message).catch(() => {
|
|
60
|
+
});
|
|
61
|
+
console.log(message);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* WARN level - always shown to user
|
|
65
|
+
*/
|
|
66
|
+
warn(message) {
|
|
67
|
+
this.writeToFile("WARN", message).catch(() => {
|
|
68
|
+
});
|
|
69
|
+
console.warn(message);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* ERROR level - always shown to user
|
|
73
|
+
*/
|
|
74
|
+
error(message, err) {
|
|
75
|
+
this.writeToFile("ERROR", message).catch(() => {
|
|
76
|
+
});
|
|
77
|
+
if (err) {
|
|
78
|
+
this.logErrorDetailsToFile(err).catch(() => {
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
console.error(message);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Write log entry to file
|
|
85
|
+
*/
|
|
86
|
+
async writeToFile(level, message) {
|
|
87
|
+
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
try {
|
|
91
|
+
const timestamp = (/* @__PURE__ */ new Date()).toISOString().replace("T", " ").substring(0, 19);
|
|
92
|
+
const logEntry = `[${timestamp}] [${level}] ${message}
|
|
93
|
+
`;
|
|
94
|
+
await fs.appendFile(this.logFilePath, logEntry, "utf-8");
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error("File logging failed:", error);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Log error details to file
|
|
101
|
+
*/
|
|
102
|
+
async logErrorDetailsToFile(err) {
|
|
103
|
+
if (!this.fileLoggingEnabled || !this.logFilePath) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
if (err && typeof err === "object" && "response" in err && err.response) {
|
|
108
|
+
const response = err.response;
|
|
109
|
+
const config = err && typeof err === "object" && "config" in err ? err.config : void 0;
|
|
110
|
+
await this.writeToFile("ERROR", ` Status: ${response.status} ${response.statusText || ""}`);
|
|
111
|
+
await this.writeToFile("ERROR", ` URL: ${config?.url || "unknown"}`);
|
|
112
|
+
await this.writeToFile("ERROR", ` Headers: ${this.safeStringify(response.headers)}`);
|
|
113
|
+
if (response.data) {
|
|
114
|
+
const errorText = this.extractErrorMessage(response.data);
|
|
115
|
+
if (errorText.trim().startsWith("<!DOCTYPE") || errorText.trim().startsWith("<html")) {
|
|
116
|
+
await this.writeToFile("ERROR", ` Response Type: HTML Error Page`);
|
|
117
|
+
const parsedError = this.parseHtmlError(errorText);
|
|
118
|
+
if (parsedError) {
|
|
119
|
+
await this.writeToFile("ERROR", ` Error Message: ${parsedError}`);
|
|
120
|
+
}
|
|
121
|
+
await this.writeToFile("ERROR", ` Raw HTML: ${this.truncate(errorText, 1e3)}`);
|
|
122
|
+
} else {
|
|
123
|
+
const preview = this.truncate(errorText, 500);
|
|
124
|
+
await this.writeToFile("ERROR", ` Response: ${preview}`);
|
|
125
|
+
}
|
|
126
|
+
} else {
|
|
127
|
+
await this.writeToFile("ERROR", ` Response: (no data)`);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
if (err && typeof err === "object" && "stack" in err && typeof err.stack === "string") {
|
|
131
|
+
const stackLines = err.stack.split("\n").slice(0, 5).join("\n ");
|
|
132
|
+
await this.writeToFile("ERROR", ` Stack: ${stackLines}`);
|
|
133
|
+
} else if (err && typeof err === "object" && "message" in err && typeof err.message === "string") {
|
|
134
|
+
await this.writeToFile("ERROR", ` Message: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
} catch (error) {
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Safely stringify object, handling circular references
|
|
141
|
+
*/
|
|
142
|
+
safeStringify(obj) {
|
|
143
|
+
try {
|
|
144
|
+
return JSON.stringify(obj);
|
|
145
|
+
} catch (error) {
|
|
146
|
+
if (error instanceof Error && error.message.includes("circular")) {
|
|
147
|
+
try {
|
|
148
|
+
const seen = /* @__PURE__ */ new WeakSet();
|
|
149
|
+
return JSON.stringify(obj, (key, value) => {
|
|
150
|
+
if (typeof value === "object" && value !== null) {
|
|
151
|
+
if (seen.has(value)) {
|
|
152
|
+
return "[Circular]";
|
|
153
|
+
}
|
|
154
|
+
seen.add(value);
|
|
155
|
+
}
|
|
156
|
+
return value;
|
|
157
|
+
});
|
|
158
|
+
} catch {
|
|
159
|
+
return "[Unable to stringify]";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return "[Stringify error]";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Extract readable text from error response data
|
|
167
|
+
*/
|
|
168
|
+
extractErrorMessage(data) {
|
|
169
|
+
if (Buffer.isBuffer(data)) {
|
|
170
|
+
return data.toString("utf-8");
|
|
171
|
+
}
|
|
172
|
+
if (typeof data === "string") {
|
|
173
|
+
return data;
|
|
174
|
+
}
|
|
175
|
+
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) {
|
|
176
|
+
const chunks = [];
|
|
177
|
+
for (const chunk of data._readableState.buffer) {
|
|
178
|
+
if (chunk && typeof chunk === "object" && "type" in chunk && chunk.type === "Buffer" && "data" in chunk && Array.isArray(chunk.data)) {
|
|
179
|
+
chunks.push(Buffer.from(chunk.data));
|
|
180
|
+
} else if (Buffer.isBuffer(chunk)) {
|
|
181
|
+
chunks.push(chunk);
|
|
182
|
+
} else if (chunk && typeof chunk === "object" && "data" in chunk) {
|
|
183
|
+
if (Buffer.isBuffer(chunk.data)) {
|
|
184
|
+
chunks.push(chunk.data);
|
|
185
|
+
} else if (Array.isArray(chunk.data)) {
|
|
186
|
+
chunks.push(Buffer.from(chunk.data));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (chunks.length > 0) {
|
|
191
|
+
return Buffer.concat(chunks).toString("utf-8");
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return this.safeStringify(data);
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Parse HTML error page to extract error message
|
|
198
|
+
*/
|
|
199
|
+
parseHtmlError(html) {
|
|
200
|
+
const titleMatch = html.match(/<title>(.*?)<\/title>/i);
|
|
201
|
+
const h1Match = html.match(/<h1>(.*?)<\/h1>/i);
|
|
202
|
+
const bodyMatch = html.match(/<body[^>]*>(.*?)<\/body>/is);
|
|
203
|
+
if (titleMatch && titleMatch[1] !== "Error") {
|
|
204
|
+
return titleMatch[1].trim();
|
|
205
|
+
}
|
|
206
|
+
if (h1Match) {
|
|
207
|
+
return h1Match[1].trim();
|
|
208
|
+
}
|
|
209
|
+
if (bodyMatch) {
|
|
210
|
+
const text = bodyMatch[1].replace(/<[^>]+>/g, " ").replace(/\s+/g, " ").trim();
|
|
211
|
+
return text.substring(0, 200);
|
|
212
|
+
}
|
|
213
|
+
return null;
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Truncate string to max length with ellipsis
|
|
217
|
+
*/
|
|
218
|
+
truncate(str, maxLength) {
|
|
219
|
+
if (str.length <= maxLength) {
|
|
220
|
+
return str;
|
|
221
|
+
}
|
|
222
|
+
return str.substring(0, maxLength) + "... [truncated]";
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Format bytes to human-readable size
|
|
226
|
+
*/
|
|
227
|
+
formatBytes(bytes) {
|
|
228
|
+
if (bytes === 0) return "0 B";
|
|
229
|
+
const k = 1024;
|
|
230
|
+
const sizes = ["B", "KB", "MB", "GB"];
|
|
231
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
232
|
+
return Math.round(bytes / Math.pow(k, i) * 100) / 100 + " " + sizes[i];
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Clean up old debug logs (older than 30 days)
|
|
236
|
+
*/
|
|
237
|
+
async cleanupOldLogs() {
|
|
238
|
+
if (!this.fileLoggingEnabled) return;
|
|
239
|
+
try {
|
|
240
|
+
const debugDir = path.join(os.homedir(), ".bike4mind", "debug");
|
|
241
|
+
const files = await fs.readdir(debugDir);
|
|
242
|
+
const now = Date.now();
|
|
243
|
+
const thirtyDaysAgo = now - 30 * 24 * 60 * 60 * 1e3;
|
|
244
|
+
for (const file of files) {
|
|
245
|
+
const filePath = path.join(debugDir, file);
|
|
246
|
+
const stats = await fs.stat(filePath);
|
|
247
|
+
if (stats.mtime.getTime() < thirtyDaysAgo) {
|
|
248
|
+
await fs.unlink(filePath);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
} catch (error) {
|
|
252
|
+
console.error("Failed to cleanup old logs:", error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
var logger = Logger.getInstance();
|
|
257
|
+
logger.setVerbose(process.env.B4M_VERBOSE === "1");
|
|
258
|
+
|
|
259
|
+
// src/storage/ConfigStore.ts
|
|
260
|
+
import { promises as fs2, existsSync } from "fs";
|
|
261
|
+
import path2 from "path";
|
|
6
262
|
import { homedir } from "os";
|
|
7
263
|
import { v4 as uuidv4 } from "uuid";
|
|
8
264
|
import { z } from "zod";
|
|
@@ -13,24 +269,25 @@ var AuthTokensSchema = z.object({
|
|
|
13
269
|
userId: z.string()
|
|
14
270
|
});
|
|
15
271
|
var ApiConfigSchema = z.object({
|
|
16
|
-
customUrl: z.
|
|
272
|
+
customUrl: z.url().optional()
|
|
17
273
|
});
|
|
18
274
|
var McpServerSchema = z.object({
|
|
19
275
|
name: z.string(),
|
|
20
276
|
command: z.string().optional(),
|
|
21
277
|
args: z.array(z.string()).optional(),
|
|
22
|
-
env: z.record(z.string()).
|
|
23
|
-
enabled: z.boolean().
|
|
278
|
+
env: z.record(z.string(), z.string()).prefault({}),
|
|
279
|
+
enabled: z.boolean().prefault(true)
|
|
24
280
|
});
|
|
25
281
|
var McpServersSchema = z.union([
|
|
26
282
|
// Array format (B4M native)
|
|
27
283
|
z.array(McpServerSchema),
|
|
28
284
|
// Object format (portable - compatible with Claude Code)
|
|
29
285
|
z.record(
|
|
286
|
+
z.string(),
|
|
30
287
|
z.object({
|
|
31
288
|
command: z.string().optional(),
|
|
32
289
|
args: z.array(z.string()).optional(),
|
|
33
|
-
env: z.record(z.string()).optional(),
|
|
290
|
+
env: z.record(z.string(), z.string()).optional(),
|
|
34
291
|
enabled: z.boolean().optional()
|
|
35
292
|
})
|
|
36
293
|
)
|
|
@@ -69,24 +326,24 @@ var CliConfigSchema = z.object({
|
|
|
69
326
|
maxTokens: z.number(),
|
|
70
327
|
temperature: z.number(),
|
|
71
328
|
autoSave: z.boolean(),
|
|
72
|
-
autoCompact: z.boolean().optional().
|
|
329
|
+
autoCompact: z.boolean().optional().prefault(true),
|
|
73
330
|
theme: z.enum(["light", "dark"]),
|
|
74
331
|
exportFormat: z.enum(["markdown", "json"]),
|
|
75
|
-
maxIterations: z.number().nullable().
|
|
76
|
-
enableSkillTool: z.boolean().optional().
|
|
332
|
+
maxIterations: z.number().nullable().prefault(10),
|
|
333
|
+
enableSkillTool: z.boolean().optional().prefault(true)
|
|
77
334
|
}),
|
|
78
335
|
tools: z.object({
|
|
79
336
|
enabled: z.array(z.string()),
|
|
80
337
|
disabled: z.array(z.string()),
|
|
81
|
-
config: z.record(z.any())
|
|
338
|
+
config: z.record(z.string(), z.any())
|
|
82
339
|
}),
|
|
83
|
-
trustedTools: z.array(z.string()).optional().
|
|
340
|
+
trustedTools: z.array(z.string()).optional().prefault([])
|
|
84
341
|
});
|
|
85
342
|
var ProjectConfigSchema = z.object({
|
|
86
343
|
tools: z.object({
|
|
87
344
|
enabled: z.array(z.string()).optional(),
|
|
88
345
|
denied: z.array(z.string()).optional(),
|
|
89
|
-
config: z.record(z.any()).optional()
|
|
346
|
+
config: z.record(z.string(), z.any()).optional()
|
|
90
347
|
}).optional(),
|
|
91
348
|
defaultModel: z.string().optional(),
|
|
92
349
|
mcpServers: McpServersSchema.optional(),
|
|
@@ -147,23 +404,23 @@ var DEFAULT_CONFIG = {
|
|
|
147
404
|
};
|
|
148
405
|
function findProjectConfigDir(startDir = process.cwd()) {
|
|
149
406
|
let currentDir = startDir;
|
|
150
|
-
const { root } =
|
|
407
|
+
const { root } = path2.parse(currentDir);
|
|
151
408
|
while (currentDir !== root) {
|
|
152
|
-
const gitPath =
|
|
409
|
+
const gitPath = path2.join(currentDir, ".git");
|
|
153
410
|
try {
|
|
154
411
|
if (existsSync(gitPath)) {
|
|
155
412
|
return currentDir;
|
|
156
413
|
}
|
|
157
414
|
} catch {
|
|
158
415
|
}
|
|
159
|
-
currentDir =
|
|
416
|
+
currentDir = path2.dirname(currentDir);
|
|
160
417
|
}
|
|
161
418
|
return process.cwd();
|
|
162
419
|
}
|
|
163
420
|
async function loadProjectConfig(projectDir) {
|
|
164
|
-
const configPath =
|
|
421
|
+
const configPath = path2.join(projectDir, ".bike4mind", "config.json");
|
|
165
422
|
try {
|
|
166
|
-
const data = await
|
|
423
|
+
const data = await fs2.readFile(configPath, "utf-8");
|
|
167
424
|
const rawConfig = JSON.parse(data);
|
|
168
425
|
const validated = ProjectConfigSchema.parse(rawConfig);
|
|
169
426
|
const result = {
|
|
@@ -176,7 +433,7 @@ async function loadProjectConfig(projectDir) {
|
|
|
176
433
|
return null;
|
|
177
434
|
}
|
|
178
435
|
if (error instanceof z.ZodError) {
|
|
179
|
-
console.error("Project config validation error:", error.
|
|
436
|
+
console.error("Project config validation error:", error.issues);
|
|
180
437
|
return null;
|
|
181
438
|
}
|
|
182
439
|
console.error("Failed to load project config:", error);
|
|
@@ -184,9 +441,9 @@ async function loadProjectConfig(projectDir) {
|
|
|
184
441
|
}
|
|
185
442
|
}
|
|
186
443
|
async function loadProjectLocalConfig(projectDir) {
|
|
187
|
-
const configPath =
|
|
444
|
+
const configPath = path2.join(projectDir, ".bike4mind", "local.json");
|
|
188
445
|
try {
|
|
189
|
-
const data = await
|
|
446
|
+
const data = await fs2.readFile(configPath, "utf-8");
|
|
190
447
|
const rawConfig = JSON.parse(data);
|
|
191
448
|
const validated = ProjectLocalConfigSchema.parse(rawConfig);
|
|
192
449
|
const result = {
|
|
@@ -199,7 +456,7 @@ async function loadProjectLocalConfig(projectDir) {
|
|
|
199
456
|
return null;
|
|
200
457
|
}
|
|
201
458
|
if (error instanceof z.ZodError) {
|
|
202
|
-
console.error("Project local config validation error:", error.
|
|
459
|
+
console.error("Project local config validation error:", error.issues);
|
|
203
460
|
return null;
|
|
204
461
|
}
|
|
205
462
|
console.error("Failed to load project local config:", error);
|
|
@@ -210,9 +467,9 @@ var McpJsonConfigSchema = z.object({
|
|
|
210
467
|
mcpServers: McpServersSchema
|
|
211
468
|
});
|
|
212
469
|
async function loadMcpJsonConfig(projectDir) {
|
|
213
|
-
const mcpConfigPath =
|
|
470
|
+
const mcpConfigPath = path2.join(projectDir, ".mcp.json");
|
|
214
471
|
try {
|
|
215
|
-
const data = await
|
|
472
|
+
const data = await fs2.readFile(mcpConfigPath, "utf-8");
|
|
216
473
|
const rawConfig = JSON.parse(data);
|
|
217
474
|
const validated = McpJsonConfigSchema.parse(rawConfig);
|
|
218
475
|
const servers = normalizeMcpServers(validated.mcpServers);
|
|
@@ -222,7 +479,7 @@ async function loadMcpJsonConfig(projectDir) {
|
|
|
222
479
|
return null;
|
|
223
480
|
}
|
|
224
481
|
if (error instanceof z.ZodError) {
|
|
225
|
-
console.error(".mcp.json validation error:", error.
|
|
482
|
+
console.error(".mcp.json validation error:", error.issues);
|
|
226
483
|
return null;
|
|
227
484
|
}
|
|
228
485
|
console.error("Failed to load .mcp.json:", error);
|
|
@@ -294,15 +551,15 @@ var ConfigStore = class {
|
|
|
294
551
|
constructor(configPath) {
|
|
295
552
|
this.config = null;
|
|
296
553
|
this.projectConfigDir = null;
|
|
297
|
-
this.configPath = configPath ||
|
|
554
|
+
this.configPath = configPath || path2.join(homedir(), ".bike4mind", "config.json");
|
|
298
555
|
}
|
|
299
556
|
/**
|
|
300
557
|
* Initialize config directory
|
|
301
558
|
*/
|
|
302
559
|
async init() {
|
|
303
|
-
const dir =
|
|
560
|
+
const dir = path2.dirname(this.configPath);
|
|
304
561
|
try {
|
|
305
|
-
await
|
|
562
|
+
await fs2.mkdir(dir, { recursive: true });
|
|
306
563
|
} catch (error) {
|
|
307
564
|
console.error("Failed to initialize config directory:", error);
|
|
308
565
|
throw error;
|
|
@@ -320,15 +577,15 @@ var ConfigStore = class {
|
|
|
320
577
|
let globalConfig;
|
|
321
578
|
try {
|
|
322
579
|
try {
|
|
323
|
-
const stats = await
|
|
580
|
+
const stats = await fs2.stat(this.configPath);
|
|
324
581
|
const mode = stats.mode & 511;
|
|
325
582
|
if (mode !== 384) {
|
|
326
583
|
console.warn(`\u26A0\uFE0F Config file has insecure permissions (${mode.toString(8)}). Setting to 0600...`);
|
|
327
|
-
await
|
|
584
|
+
await fs2.chmod(this.configPath, 384);
|
|
328
585
|
}
|
|
329
586
|
} catch (statError) {
|
|
330
587
|
}
|
|
331
|
-
const data = await
|
|
588
|
+
const data = await fs2.readFile(this.configPath, "utf-8");
|
|
332
589
|
const rawConfig = JSON.parse(data);
|
|
333
590
|
if (rawConfig.apiConfig && "environment" in rawConfig.apiConfig) {
|
|
334
591
|
const oldApiConfig = rawConfig.apiConfig;
|
|
@@ -364,7 +621,7 @@ var ConfigStore = class {
|
|
|
364
621
|
if (error.code === "ENOENT") {
|
|
365
622
|
globalConfig = { ...DEFAULT_CONFIG };
|
|
366
623
|
} else if (error instanceof z.ZodError) {
|
|
367
|
-
console.error("Global config validation error:", error.
|
|
624
|
+
console.error("Global config validation error:", error.issues);
|
|
368
625
|
console.error("Using default configuration");
|
|
369
626
|
globalConfig = { ...DEFAULT_CONFIG };
|
|
370
627
|
} else {
|
|
@@ -381,10 +638,10 @@ var ConfigStore = class {
|
|
|
381
638
|
projectLocalConfig = await loadProjectLocalConfig(this.projectConfigDir);
|
|
382
639
|
mcpJsonServers = await loadMcpJsonConfig(this.projectConfigDir);
|
|
383
640
|
if (projectConfig) {
|
|
384
|
-
|
|
641
|
+
logger.debug(`\u{1F4C1} Project config loaded from: ${this.projectConfigDir}/.bike4mind/`);
|
|
385
642
|
}
|
|
386
643
|
if (mcpJsonServers && mcpJsonServers.length > 0) {
|
|
387
|
-
|
|
644
|
+
logger.debug(`\u{1F4C1} Project MCP config loaded from: ${this.projectConfigDir}/.mcp.json`);
|
|
388
645
|
}
|
|
389
646
|
}
|
|
390
647
|
} else {
|
|
@@ -401,7 +658,7 @@ var ConfigStore = class {
|
|
|
401
658
|
return this.reset();
|
|
402
659
|
}
|
|
403
660
|
if (error instanceof z.ZodError) {
|
|
404
|
-
console.error("Config validation error:", error.
|
|
661
|
+
console.error("Config validation error:", error.issues);
|
|
405
662
|
console.error("Resetting to default configuration");
|
|
406
663
|
return this.reset();
|
|
407
664
|
}
|
|
@@ -438,8 +695,8 @@ var ConfigStore = class {
|
|
|
438
695
|
throw new Error("No configuration to save");
|
|
439
696
|
}
|
|
440
697
|
try {
|
|
441
|
-
await
|
|
442
|
-
await
|
|
698
|
+
await fs2.writeFile(this.configPath, JSON.stringify(this.config, null, 2), "utf-8");
|
|
699
|
+
await fs2.chmod(this.configPath, 384);
|
|
443
700
|
} catch (error) {
|
|
444
701
|
console.error("Failed to save config:", error);
|
|
445
702
|
throw error;
|
|
@@ -599,20 +856,20 @@ var ConfigStore = class {
|
|
|
599
856
|
if (!projectDir) {
|
|
600
857
|
return;
|
|
601
858
|
}
|
|
602
|
-
const configDir =
|
|
603
|
-
await
|
|
859
|
+
const configDir = path2.join(projectDir, ".bike4mind");
|
|
860
|
+
await fs2.mkdir(configDir, { recursive: true });
|
|
604
861
|
await this.ensureGitignore(projectDir);
|
|
605
862
|
}
|
|
606
863
|
/**
|
|
607
864
|
* Ensure .gitignore includes .bike4mind/local.json
|
|
608
865
|
*/
|
|
609
866
|
async ensureGitignore(projectDir) {
|
|
610
|
-
const gitignorePath =
|
|
867
|
+
const gitignorePath = path2.join(projectDir, ".gitignore");
|
|
611
868
|
const entryToAdd = ".bike4mind/local.json";
|
|
612
869
|
try {
|
|
613
870
|
let gitignoreContent = "";
|
|
614
871
|
try {
|
|
615
|
-
gitignoreContent = await
|
|
872
|
+
gitignoreContent = await fs2.readFile(gitignorePath, "utf-8");
|
|
616
873
|
} catch {
|
|
617
874
|
}
|
|
618
875
|
if (gitignoreContent.includes(entryToAdd)) {
|
|
@@ -622,7 +879,7 @@ var ConfigStore = class {
|
|
|
622
879
|
# Bike4Mind local config (developer-specific)
|
|
623
880
|
${entryToAdd}
|
|
624
881
|
`;
|
|
625
|
-
await
|
|
882
|
+
await fs2.writeFile(gitignorePath, newContent, "utf-8");
|
|
626
883
|
console.log(`\u2705 Added ${entryToAdd} to .gitignore`);
|
|
627
884
|
} catch (error) {
|
|
628
885
|
console.warn(`\u26A0\uFE0F Failed to update .gitignore:`, error);
|
|
@@ -633,10 +890,10 @@ ${entryToAdd}
|
|
|
633
890
|
*/
|
|
634
891
|
async saveProjectConfig(config, projectDir) {
|
|
635
892
|
const targetDir = projectDir || this.projectConfigDir || process.cwd();
|
|
636
|
-
const configPath =
|
|
637
|
-
await
|
|
893
|
+
const configPath = path2.join(targetDir, ".bike4mind", "config.json");
|
|
894
|
+
await fs2.mkdir(path2.dirname(configPath), { recursive: true });
|
|
638
895
|
const validated = ProjectConfigSchema.parse(config);
|
|
639
|
-
await
|
|
896
|
+
await fs2.writeFile(configPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
640
897
|
console.log(`\u2705 Saved project config to: ${configPath}`);
|
|
641
898
|
}
|
|
642
899
|
/**
|
|
@@ -644,11 +901,11 @@ ${entryToAdd}
|
|
|
644
901
|
*/
|
|
645
902
|
async saveProjectLocalConfig(config, projectDir) {
|
|
646
903
|
const targetDir = projectDir || this.projectConfigDir || process.cwd();
|
|
647
|
-
const configPath =
|
|
648
|
-
await
|
|
904
|
+
const configPath = path2.join(targetDir, ".bike4mind", "local.json");
|
|
905
|
+
await fs2.mkdir(path2.dirname(configPath), { recursive: true });
|
|
649
906
|
const validated = ProjectLocalConfigSchema.parse(config);
|
|
650
|
-
await
|
|
651
|
-
await
|
|
907
|
+
await fs2.writeFile(configPath, JSON.stringify(validated, null, 2), "utf-8");
|
|
908
|
+
await fs2.chmod(configPath, 384);
|
|
652
909
|
console.log(`\u2705 Saved project-local config to: ${configPath}`);
|
|
653
910
|
}
|
|
654
911
|
/**
|
|
@@ -672,5 +929,6 @@ ${entryToAdd}
|
|
|
672
929
|
};
|
|
673
930
|
|
|
674
931
|
export {
|
|
932
|
+
logger,
|
|
675
933
|
ConfigStore
|
|
676
934
|
};
|
|
@@ -7,11 +7,11 @@ import {
|
|
|
7
7
|
getSettingsMap,
|
|
8
8
|
getSettingsValue,
|
|
9
9
|
secureParameters
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-W3S2VCLO.js";
|
|
11
11
|
import {
|
|
12
12
|
KnowledgeType,
|
|
13
13
|
SupportedFabFileMimeTypes
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-BWPGS3D5.js";
|
|
15
15
|
|
|
16
16
|
// ../../b4m-core/packages/services/dist/src/fabFileService/create.js
|
|
17
17
|
import { z } from "zod";
|
|
@@ -20,7 +20,7 @@ var createFabFileSchema = z.object({
|
|
|
20
20
|
fileName: z.string(),
|
|
21
21
|
mimeType: z.string(),
|
|
22
22
|
fileSize: z.number(),
|
|
23
|
-
type: z.
|
|
23
|
+
type: z.enum(KnowledgeType),
|
|
24
24
|
content: z.union([z.string(), z.instanceof(Buffer)]).optional(),
|
|
25
25
|
organizationId: z.string().optional(),
|
|
26
26
|
/**
|