mindgraph-mcp 0.14.9 → 0.15.0
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 +2 -2
- package/dist/cli.js +625 -170
- package/dist/index.js +120 -59
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -28,6 +28,38 @@ var import_stdio = require("@modelcontextprotocol/sdk/server/stdio.js");
|
|
|
28
28
|
var import_types = require("@modelcontextprotocol/sdk/types.js");
|
|
29
29
|
var import_mindgraph2 = require("mindgraph");
|
|
30
30
|
|
|
31
|
+
// src/hook-env.ts
|
|
32
|
+
var import_node_crypto = __toESM(require("crypto"));
|
|
33
|
+
var import_node_fs = __toESM(require("fs"));
|
|
34
|
+
var import_node_os = __toESM(require("os"));
|
|
35
|
+
var import_node_path = __toESM(require("path"));
|
|
36
|
+
function stableAgentId() {
|
|
37
|
+
let user = "user";
|
|
38
|
+
try {
|
|
39
|
+
user = import_node_os.default.userInfo().username || "user";
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
const digest = import_node_crypto.default.createHash("sha256").update(`${user}@${import_node_os.default.hostname()}`).digest("hex").slice(0, 12);
|
|
43
|
+
return `u-${digest}`;
|
|
44
|
+
}
|
|
45
|
+
function hookEnvPath(dir) {
|
|
46
|
+
return import_node_path.default.join(dir || import_node_path.default.join(import_node_os.default.homedir(), ".mindgraph"), "hooks.json");
|
|
47
|
+
}
|
|
48
|
+
function loadHookEnv(dir) {
|
|
49
|
+
try {
|
|
50
|
+
const raw = import_node_fs.default.readFileSync(hookEnvPath(dir), "utf8");
|
|
51
|
+
const parsed = JSON.parse(raw);
|
|
52
|
+
return {
|
|
53
|
+
baseUrl: typeof parsed.baseUrl === "string" ? parsed.baseUrl : void 0,
|
|
54
|
+
apiKey: typeof parsed.apiKey === "string" ? parsed.apiKey : void 0,
|
|
55
|
+
agentId: typeof parsed.agentId === "string" ? parsed.agentId : void 0,
|
|
56
|
+
orgId: typeof parsed.orgId === "string" ? parsed.orgId : void 0
|
|
57
|
+
};
|
|
58
|
+
} catch {
|
|
59
|
+
return {};
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
31
63
|
// src/error-detail.ts
|
|
32
64
|
var import_mindgraph = require("mindgraph");
|
|
33
65
|
function errorDetail(e) {
|
|
@@ -37,14 +69,31 @@ function errorDetail(e) {
|
|
|
37
69
|
}
|
|
38
70
|
return e instanceof Error ? e.message : String(e);
|
|
39
71
|
}
|
|
72
|
+
var CONFLICT_STATE_KEYS = [
|
|
73
|
+
"current_version",
|
|
74
|
+
"current_epoch",
|
|
75
|
+
"lease_expires_at",
|
|
76
|
+
"lease_owner_agent_id"
|
|
77
|
+
];
|
|
78
|
+
function conflictState(e) {
|
|
79
|
+
if (!(e instanceof import_mindgraph.MindGraphError) || !e.body || typeof e.body !== "object") {
|
|
80
|
+
return {};
|
|
81
|
+
}
|
|
82
|
+
const body = e.body;
|
|
83
|
+
const lifted = {};
|
|
84
|
+
for (const key of CONFLICT_STATE_KEYS) {
|
|
85
|
+
if (body[key] !== void 0) lifted[key] = body[key];
|
|
86
|
+
}
|
|
87
|
+
return lifted;
|
|
88
|
+
}
|
|
40
89
|
|
|
41
90
|
// src/codegraph.ts
|
|
42
91
|
var import_node_child_process = require("child_process");
|
|
43
|
-
var
|
|
92
|
+
var import_node_fs2 = require("fs");
|
|
44
93
|
var import_promises = require("fs/promises");
|
|
45
|
-
var
|
|
46
|
-
var
|
|
47
|
-
var
|
|
94
|
+
var import_node_os2 = require("os");
|
|
95
|
+
var import_node_path2 = require("path");
|
|
96
|
+
var import_node_crypto2 = require("crypto");
|
|
48
97
|
function unavailabilityCaveats(reason, message) {
|
|
49
98
|
const caveats = [message || "codegraph status failed"];
|
|
50
99
|
if (reason === "absent") {
|
|
@@ -57,14 +106,14 @@ function unavailabilityCaveats(reason, message) {
|
|
|
57
106
|
var DEFAULT_TIMEOUT_MS = 5e3;
|
|
58
107
|
var DEFAULT_STATUS_TTL_MS = 6e4;
|
|
59
108
|
var MAX_OUTPUT_BYTES = 5 * 1024 * 1024;
|
|
60
|
-
function normalizePath(
|
|
61
|
-
return
|
|
109
|
+
function normalizePath(path3) {
|
|
110
|
+
return path3.replaceAll("\\", "/").replace(/^\.\//, "");
|
|
62
111
|
}
|
|
63
112
|
function normalizeSignature(signature) {
|
|
64
113
|
return signature.replace(/\s+/g, " ").trim();
|
|
65
114
|
}
|
|
66
|
-
function languageFromPath(
|
|
67
|
-
const extension = (0,
|
|
115
|
+
function languageFromPath(path3) {
|
|
116
|
+
const extension = (0, import_node_path2.extname)(path3).toLowerCase();
|
|
68
117
|
return {
|
|
69
118
|
".c": "c",
|
|
70
119
|
".cc": "cpp",
|
|
@@ -113,30 +162,30 @@ function normalizeRemote(remote) {
|
|
|
113
162
|
}
|
|
114
163
|
}
|
|
115
164
|
function pathContains(root, candidate) {
|
|
116
|
-
const child = (0,
|
|
117
|
-
return child === "" || child !== ".." && !child.startsWith(`..${
|
|
165
|
+
const child = (0, import_node_path2.relative)(root, candidate);
|
|
166
|
+
return child === "" || child !== ".." && !child.startsWith(`..${import_node_path2.sep}`) && !(0, import_node_path2.isAbsolute)(child);
|
|
118
167
|
}
|
|
119
168
|
function nearestExistingDirectory(candidate) {
|
|
120
|
-
let current = (0,
|
|
169
|
+
let current = (0, import_node_path2.resolve)(candidate);
|
|
121
170
|
for (; ; ) {
|
|
122
|
-
if ((0,
|
|
171
|
+
if ((0, import_node_fs2.existsSync)(current)) {
|
|
123
172
|
try {
|
|
124
|
-
return (0,
|
|
173
|
+
return (0, import_node_fs2.statSync)(current).isDirectory() ? current : (0, import_node_path2.dirname)(current);
|
|
125
174
|
} catch {
|
|
126
175
|
}
|
|
127
176
|
}
|
|
128
|
-
const parent = (0,
|
|
177
|
+
const parent = (0, import_node_path2.dirname)(current);
|
|
129
178
|
if (parent === current) return current;
|
|
130
179
|
current = parent;
|
|
131
180
|
}
|
|
132
181
|
}
|
|
133
182
|
function findWorkspaceFile(start, explicit) {
|
|
134
|
-
if (explicit) return (0,
|
|
135
|
-
let current = (0,
|
|
183
|
+
if (explicit) return (0, import_node_path2.resolve)(start, explicit);
|
|
184
|
+
let current = (0, import_node_path2.resolve)(start);
|
|
136
185
|
for (; ; ) {
|
|
137
|
-
const candidate = (0,
|
|
138
|
-
if ((0,
|
|
139
|
-
const parent = (0,
|
|
186
|
+
const candidate = (0, import_node_path2.join)(current, ".mindgraph", "workspace.json");
|
|
187
|
+
if ((0, import_node_fs2.existsSync)(candidate)) return candidate;
|
|
188
|
+
const parent = (0, import_node_path2.dirname)(current);
|
|
140
189
|
if (parent === current) return void 0;
|
|
141
190
|
current = parent;
|
|
142
191
|
}
|
|
@@ -223,7 +272,7 @@ var CodegraphAdapter = class {
|
|
|
223
272
|
async resolveRepository(repo, fallbackSpaceUid) {
|
|
224
273
|
const configured = await this.resolveRepositories(fallbackSpaceUid);
|
|
225
274
|
const selected = repo && configured.find((candidate) => candidate.repoId === repo) || repo && configured.find(
|
|
226
|
-
(candidate) => candidate.repoRoot === repo || (0,
|
|
275
|
+
(candidate) => candidate.repoRoot === repo || (0, import_node_path2.basename)(candidate.repoRoot) === repo
|
|
227
276
|
) || (!repo ? [...configured].sort((a, b) => b.repoRoot.length - a.repoRoot.length).find((candidate) => pathContains(candidate.repoRoot, this.cwd)) : void 0) || (!repo && configured.length === 1 ? configured[0] : void 0);
|
|
228
277
|
if (selected) {
|
|
229
278
|
return !repo && this.env.MINDGRAPH_REPO_ID ? this.resolveRepositoryIdentity(
|
|
@@ -233,8 +282,8 @@ var CodegraphAdapter = class {
|
|
|
233
282
|
) : selected;
|
|
234
283
|
}
|
|
235
284
|
const requestedRoot = repo || this.env.MINDGRAPH_REPO_ROOT || this.cwd;
|
|
236
|
-
const requestedPath = await (0, import_promises.realpath)((0,
|
|
237
|
-
() => (0,
|
|
285
|
+
const requestedPath = await (0, import_promises.realpath)((0, import_node_path2.resolve)(this.cwd, requestedRoot)).catch(
|
|
286
|
+
() => (0, import_node_path2.resolve)(this.cwd, requestedRoot)
|
|
238
287
|
);
|
|
239
288
|
const repoRoot = await this.gitRoot(requestedPath) ?? requestedPath;
|
|
240
289
|
return this.resolveRepositoryIdentity(
|
|
@@ -255,7 +304,7 @@ var CodegraphAdapter = class {
|
|
|
255
304
|
);
|
|
256
305
|
}
|
|
257
306
|
async resolveRepositoryIdentity(root, explicitRepoId, spaceUid) {
|
|
258
|
-
const repoRoot = await (0, import_promises.realpath)(root).catch(() => (0,
|
|
307
|
+
const repoRoot = await (0, import_promises.realpath)(root).catch(() => (0, import_node_path2.resolve)(root));
|
|
259
308
|
const cacheKey = `${repoRoot}\0${explicitRepoId ?? ""}\0${spaceUid ?? ""}`;
|
|
260
309
|
const cached = this.identityCache.get(cacheKey);
|
|
261
310
|
if (cached) return cached;
|
|
@@ -285,20 +334,20 @@ var CodegraphAdapter = class {
|
|
|
285
334
|
this.env
|
|
286
335
|
).catch(() => "");
|
|
287
336
|
if (!rawCommonDir.trim()) {
|
|
288
|
-
return `local:${(0,
|
|
337
|
+
return `local:${(0, import_node_path2.basename)(repoRoot)}`;
|
|
289
338
|
}
|
|
290
|
-
const commonDir = (0,
|
|
291
|
-
const identityDir = (0,
|
|
292
|
-
const identityFile = (0,
|
|
339
|
+
const commonDir = (0, import_node_path2.resolve)(repoRoot, rawCommonDir.trim());
|
|
340
|
+
const identityDir = (0, import_node_path2.join)(commonDir, "mindgraph");
|
|
341
|
+
const identityFile = (0, import_node_path2.join)(identityDir, "repository-id");
|
|
293
342
|
try {
|
|
294
|
-
const existing = (0,
|
|
343
|
+
const existing = (0, import_node_fs2.readFileSync)(identityFile, "utf8").trim();
|
|
295
344
|
if (existing) return existing;
|
|
296
345
|
} catch {
|
|
297
346
|
}
|
|
298
|
-
(0,
|
|
299
|
-
const generated = (0,
|
|
347
|
+
(0, import_node_fs2.mkdirSync)(identityDir, { recursive: true, mode: 448 });
|
|
348
|
+
const generated = (0, import_node_crypto2.randomUUID)();
|
|
300
349
|
try {
|
|
301
|
-
(0,
|
|
350
|
+
(0, import_node_fs2.writeFileSync)(identityFile, `${generated}
|
|
302
351
|
`, {
|
|
303
352
|
encoding: "utf8",
|
|
304
353
|
flag: "wx",
|
|
@@ -307,7 +356,7 @@ var CodegraphAdapter = class {
|
|
|
307
356
|
return generated;
|
|
308
357
|
} catch (cause) {
|
|
309
358
|
if (cause.code !== "EEXIST") throw cause;
|
|
310
|
-
const winner = (0,
|
|
359
|
+
const winner = (0, import_node_fs2.readFileSync)(identityFile, "utf8").trim();
|
|
311
360
|
if (!winner) throw new Error(`empty repository identity file: ${identityFile}`);
|
|
312
361
|
return winner;
|
|
313
362
|
}
|
|
@@ -320,7 +369,7 @@ var CodegraphAdapter = class {
|
|
|
320
369
|
Math.min(this.timeoutMs, 2e3),
|
|
321
370
|
this.env
|
|
322
371
|
).catch(() => "");
|
|
323
|
-
return raw.trim() ? (0,
|
|
372
|
+
return raw.trim() ? (0, import_node_path2.resolve)(start, raw.trim()) : void 0;
|
|
324
373
|
}
|
|
325
374
|
async availability(repository) {
|
|
326
375
|
const cached = this.statusCache.get(repository.repoRoot);
|
|
@@ -437,7 +486,7 @@ var CodegraphAdapter = class {
|
|
|
437
486
|
return this.resolveRepository(ref.repo || defaultRepo, fallbackSpaceUid);
|
|
438
487
|
}
|
|
439
488
|
if (ref.path) {
|
|
440
|
-
const requested = (0,
|
|
489
|
+
const requested = (0, import_node_path2.isAbsolute)(ref.path) ? (0, import_node_path2.resolve)(ref.path) : (0, import_node_path2.resolve)(this.cwd, ref.path);
|
|
441
490
|
const absolute = await (0, import_promises.realpath)(requested).catch(() => requested);
|
|
442
491
|
const configured = await this.resolveRepositories(fallbackSpaceUid);
|
|
443
492
|
const defining = [...configured].sort((a, b) => b.repoRoot.length - a.repoRoot.length).find((candidate) => pathContains(candidate.repoRoot, absolute));
|
|
@@ -514,19 +563,19 @@ var CodegraphAdapter = class {
|
|
|
514
563
|
}
|
|
515
564
|
configuredRepositories() {
|
|
516
565
|
const configured = [];
|
|
517
|
-
if (this.workspaceFile && (0,
|
|
566
|
+
if (this.workspaceFile && (0, import_node_fs2.existsSync)(this.workspaceFile)) {
|
|
518
567
|
try {
|
|
519
568
|
const parsed = JSON.parse(
|
|
520
|
-
(0,
|
|
569
|
+
(0, import_node_fs2.readFileSync)(this.workspaceFile, "utf8")
|
|
521
570
|
);
|
|
522
571
|
if (parsed.v === 1 && Array.isArray(parsed.repositories)) {
|
|
523
|
-
const configDirectory = (0,
|
|
524
|
-
const base = (0,
|
|
572
|
+
const configDirectory = (0, import_node_path2.dirname)(this.workspaceFile);
|
|
573
|
+
const base = (0, import_node_path2.basename)(configDirectory) === ".mindgraph" ? (0, import_node_path2.dirname)(configDirectory) : configDirectory;
|
|
525
574
|
for (const repository of parsed.repositories) {
|
|
526
575
|
if (!repository || typeof repository.root !== "string") continue;
|
|
527
576
|
configured.push({
|
|
528
577
|
repoId: typeof repository.repo_id === "string" ? repository.repo_id : void 0,
|
|
529
|
-
repoRoot: (0,
|
|
578
|
+
repoRoot: (0, import_node_path2.resolve)(base, repository.root),
|
|
530
579
|
spaceUid: typeof repository.space_uid === "string" ? repository.space_uid : void 0
|
|
531
580
|
});
|
|
532
581
|
}
|
|
@@ -541,7 +590,7 @@ var CodegraphAdapter = class {
|
|
|
541
590
|
for (const [repoId, config] of Object.entries(parsed)) {
|
|
542
591
|
configured.push({
|
|
543
592
|
repoId,
|
|
544
|
-
repoRoot: (0,
|
|
593
|
+
repoRoot: (0, import_node_path2.resolve)(
|
|
545
594
|
this.cwd,
|
|
546
595
|
typeof config === "string" ? config : config.root
|
|
547
596
|
),
|
|
@@ -569,9 +618,9 @@ var CodegraphAdapter = class {
|
|
|
569
618
|
const hits = await this.runJson(args);
|
|
570
619
|
let candidates = hits.map(asNode).map(toCandidate).filter((item) => item !== null);
|
|
571
620
|
if (ref.path) {
|
|
572
|
-
const absolutePath = (0,
|
|
621
|
+
const absolutePath = (0, import_node_path2.isAbsolute)(ref.path) ? await (0, import_promises.realpath)(ref.path).catch(() => ref.path) : void 0;
|
|
573
622
|
const wanted = normalizePath(
|
|
574
|
-
absolutePath ? (0,
|
|
623
|
+
absolutePath ? (0, import_node_path2.relative)(repository.repoRoot, absolutePath) : ref.path
|
|
575
624
|
);
|
|
576
625
|
candidates = candidates.filter((candidate) => candidate.path === wanted);
|
|
577
626
|
}
|
|
@@ -672,7 +721,7 @@ var CodegraphAdapter = class {
|
|
|
672
721
|
const candidates = [
|
|
673
722
|
this.env.MINDGRAPH_CODEGRAPH_BIN,
|
|
674
723
|
"codegraph",
|
|
675
|
-
(0,
|
|
724
|
+
(0, import_node_path2.resolve)((0, import_node_os2.homedir)(), ".local", "bin", "codegraph")
|
|
676
725
|
].filter((candidate, index, all) => {
|
|
677
726
|
return Boolean(candidate) && all.indexOf(candidate) === index;
|
|
678
727
|
});
|
|
@@ -1219,9 +1268,9 @@ function primaryUids(value) {
|
|
|
1219
1268
|
}
|
|
1220
1269
|
|
|
1221
1270
|
// src/sync-tool.ts
|
|
1222
|
-
var
|
|
1223
|
-
var
|
|
1224
|
-
var
|
|
1271
|
+
var import_node_crypto3 = __toESM(require("crypto"));
|
|
1272
|
+
var import_node_fs3 = __toESM(require("fs"));
|
|
1273
|
+
var import_node_path3 = __toESM(require("path"));
|
|
1225
1274
|
var ok2 = (data) => ({
|
|
1226
1275
|
content: [{ type: "text", text: JSON.stringify(data, null, 2) }]
|
|
1227
1276
|
});
|
|
@@ -1298,25 +1347,25 @@ var SYNC_TOOL = {
|
|
|
1298
1347
|
}
|
|
1299
1348
|
};
|
|
1300
1349
|
function safePath(root, candidate) {
|
|
1301
|
-
const absolute =
|
|
1302
|
-
const relative2 =
|
|
1303
|
-
if (relative2.startsWith("..") ||
|
|
1350
|
+
const absolute = import_node_path3.default.resolve(root, candidate);
|
|
1351
|
+
const relative2 = import_node_path3.default.relative(root, absolute);
|
|
1352
|
+
if (relative2.startsWith("..") || import_node_path3.default.isAbsolute(relative2)) {
|
|
1304
1353
|
throw new Error(`path escapes repository root: ${candidate}`);
|
|
1305
1354
|
}
|
|
1306
1355
|
return absolute;
|
|
1307
1356
|
}
|
|
1308
1357
|
function markdownFiles(target) {
|
|
1309
|
-
if (!
|
|
1310
|
-
const stat =
|
|
1358
|
+
if (!import_node_fs3.default.existsSync(target)) return [];
|
|
1359
|
+
const stat = import_node_fs3.default.statSync(target);
|
|
1311
1360
|
if (stat.isFile()) return target.endsWith(".md") ? [target] : [];
|
|
1312
1361
|
if (!stat.isDirectory()) return [];
|
|
1313
|
-
return
|
|
1362
|
+
return import_node_fs3.default.readdirSync(target, { withFileTypes: true }).flatMap((entry) => markdownFiles(import_node_path3.default.join(target, entry.name)));
|
|
1314
1363
|
}
|
|
1315
1364
|
function fileDescriptor(root, absolute) {
|
|
1316
|
-
const content =
|
|
1365
|
+
const content = import_node_fs3.default.readFileSync(absolute, "utf8");
|
|
1317
1366
|
return {
|
|
1318
|
-
logical_path:
|
|
1319
|
-
content_hash:
|
|
1367
|
+
logical_path: import_node_path3.default.relative(root, absolute).split(import_node_path3.default.sep).join("/"),
|
|
1368
|
+
content_hash: import_node_crypto3.default.createHash("sha256").update(content).digest("hex"),
|
|
1320
1369
|
bytes: Buffer.byteLength(content),
|
|
1321
1370
|
content
|
|
1322
1371
|
};
|
|
@@ -1381,7 +1430,7 @@ async function handleSyncTool(client2, args) {
|
|
|
1381
1430
|
}
|
|
1382
1431
|
if (action === "status" && request.logical_path && request.file_present !== false) {
|
|
1383
1432
|
const absolute = safePath(root, String(request.logical_path));
|
|
1384
|
-
request.file_present =
|
|
1433
|
+
request.file_present = import_node_fs3.default.existsSync(absolute);
|
|
1385
1434
|
if (request.file_present && !request.content_hash) {
|
|
1386
1435
|
request.content_hash = fileDescriptor(root, absolute).content_hash;
|
|
1387
1436
|
}
|
|
@@ -2441,6 +2490,18 @@ async function handleTool(client2, name, args) {
|
|
|
2441
2490
|
].includes(action);
|
|
2442
2491
|
return attach ? await attachCodeRefsToToolResult(client2, result, args) : result;
|
|
2443
2492
|
} catch (e) {
|
|
2493
|
+
const lifted = conflictState(e);
|
|
2494
|
+
if (Object.keys(lifted).length > 0) {
|
|
2495
|
+
return {
|
|
2496
|
+
content: [
|
|
2497
|
+
{
|
|
2498
|
+
type: "text",
|
|
2499
|
+
text: JSON.stringify({ error: errorDetail(e), ...lifted })
|
|
2500
|
+
}
|
|
2501
|
+
],
|
|
2502
|
+
isError: true
|
|
2503
|
+
};
|
|
2504
|
+
}
|
|
2444
2505
|
return err3(errorDetail(e));
|
|
2445
2506
|
}
|
|
2446
2507
|
}
|
|
@@ -3876,7 +3937,7 @@ async function readGovernedResource(client2, uri, governanceConfig) {
|
|
|
3876
3937
|
// src/index.ts
|
|
3877
3938
|
var API_KEY = process.env.MINDGRAPH_API_KEY;
|
|
3878
3939
|
var BASE_URL = process.env.MINDGRAPH_BASE_URL || "https://api.mindgraph.cloud";
|
|
3879
|
-
var AGENT_ID = process.env.MINDGRAPH_AGENT_ID ||
|
|
3940
|
+
var AGENT_ID = process.env.MINDGRAPH_AGENT_ID || loadHookEnv().agentId || stableAgentId();
|
|
3880
3941
|
var ORG_ID = process.env.MINDGRAPH_ORG_ID;
|
|
3881
3942
|
var PROFILE = process.env.MINDGRAPH_PROFILE || "general";
|
|
3882
3943
|
var HARNESS = process.env.MINDGRAPH_HARNESS || "generic";
|
|
@@ -3998,7 +4059,7 @@ if (PROFILE === "coding") {
|
|
|
3998
4059
|
var server = new import_server.Server(
|
|
3999
4060
|
{
|
|
4000
4061
|
name: "mindgraph",
|
|
4001
|
-
version: "0.
|
|
4062
|
+
version: "0.15.0"
|
|
4002
4063
|
},
|
|
4003
4064
|
{
|
|
4004
4065
|
capabilities: {
|
|
@@ -4212,7 +4273,7 @@ async function main() {
|
|
|
4212
4273
|
const transport = new import_stdio.StdioServerTransport();
|
|
4213
4274
|
await server.connect(transport);
|
|
4214
4275
|
console.error(
|
|
4215
|
-
`MindGraph MCP server
|
|
4276
|
+
`MindGraph MCP server v${"0.15.0"} running on stdio (${BASE_URL})`
|
|
4216
4277
|
);
|
|
4217
4278
|
}
|
|
4218
4279
|
main().catch((error) => {
|