@coderule/mcp 2.1.0 → 2.2.1
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/mcp-cli.cjs +139 -0
- package/dist/mcp-cli.cjs.map +1 -1
- package/dist/mcp-cli.js +141 -2
- package/dist/mcp-cli.js.map +1 -1
- package/package.json +2 -2
package/dist/mcp-cli.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import fs5 from 'fs/promises';
|
|
3
|
-
import path2 from 'path';
|
|
2
|
+
import fs5, { mkdir, writeFile } from 'fs/promises';
|
|
3
|
+
import path2, { dirname } from 'path';
|
|
4
4
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
5
5
|
import { createHash } from 'crypto';
|
|
6
6
|
import envPaths from 'env-paths';
|
|
@@ -2397,6 +2397,145 @@ ${statusText}`;
|
|
|
2397
2397
|
return { content: [{ type: "text", text }] };
|
|
2398
2398
|
}
|
|
2399
2399
|
);
|
|
2400
|
+
server.registerTool(
|
|
2401
|
+
"dump_bush",
|
|
2402
|
+
{
|
|
2403
|
+
title: "Dump Raw Index (Debug)",
|
|
2404
|
+
description: "Debug tool. Downloads the raw HDF5 bush file for the current snapshot and saves it to the specified path. Returns an HDF5 bush reader skill with format documentation and Python code examples.",
|
|
2405
|
+
inputSchema: {
|
|
2406
|
+
filePath: z.string().min(1, "File path is required").refine((p) => p.endsWith(".h5"), "File must have .h5 extension").describe(
|
|
2407
|
+
"Full file name to save (use base dir + any name with .h5 extension), e.g. /tmp/snapshot.h5"
|
|
2408
|
+
)
|
|
2409
|
+
},
|
|
2410
|
+
annotations: {
|
|
2411
|
+
readOnlyHint: false,
|
|
2412
|
+
destructiveHint: false,
|
|
2413
|
+
idempotentHint: true,
|
|
2414
|
+
openWorldHint: true
|
|
2415
|
+
}
|
|
2416
|
+
},
|
|
2417
|
+
async ({ filePath }) => {
|
|
2418
|
+
const deadline = Date.now() + runtime.config.maxQueryWaitMs;
|
|
2419
|
+
while (Date.now() < deadline) {
|
|
2420
|
+
if (isLocalStable()) break;
|
|
2421
|
+
await sleep3(250);
|
|
2422
|
+
}
|
|
2423
|
+
if (!isLocalStable()) {
|
|
2424
|
+
const statusText2 = formatStatus(
|
|
2425
|
+
await collectIndexingStatus(runtime, runner)
|
|
2426
|
+
);
|
|
2427
|
+
return {
|
|
2428
|
+
content: [
|
|
2429
|
+
{
|
|
2430
|
+
type: "text",
|
|
2431
|
+
text: `Indexer not ready (local hashing/dirty). Current status:
|
|
2432
|
+
|
|
2433
|
+
${statusText2}`
|
|
2434
|
+
}
|
|
2435
|
+
],
|
|
2436
|
+
isError: true
|
|
2437
|
+
};
|
|
2438
|
+
}
|
|
2439
|
+
let currentHash = computeSnapshot(runtime.filesRepo).snapshotHash;
|
|
2440
|
+
let lastStatus;
|
|
2441
|
+
while (Date.now() < deadline) {
|
|
2442
|
+
if (!isLocalStable()) {
|
|
2443
|
+
while (Date.now() < deadline) {
|
|
2444
|
+
if (isLocalStable()) break;
|
|
2445
|
+
await sleep3(250);
|
|
2446
|
+
}
|
|
2447
|
+
if (!isLocalStable()) break;
|
|
2448
|
+
currentHash = computeSnapshot(runtime.filesRepo).snapshotHash;
|
|
2449
|
+
continue;
|
|
2450
|
+
}
|
|
2451
|
+
try {
|
|
2452
|
+
const status = await withDeadline2(
|
|
2453
|
+
runtime.clients.sync.checkSnapshotStatus(currentHash),
|
|
2454
|
+
deadline
|
|
2455
|
+
);
|
|
2456
|
+
lastStatus = status.status;
|
|
2457
|
+
if (status.status === "READY") {
|
|
2458
|
+
try {
|
|
2459
|
+
const bushBuffer = await withDeadline2(
|
|
2460
|
+
runtime.clients.sync.downloadSnapshotBush(currentHash),
|
|
2461
|
+
deadline
|
|
2462
|
+
);
|
|
2463
|
+
await mkdir(dirname(filePath), { recursive: true });
|
|
2464
|
+
await writeFile(filePath, Buffer.from(bushBuffer));
|
|
2465
|
+
runtime.logger.info(
|
|
2466
|
+
{
|
|
2467
|
+
filePath,
|
|
2468
|
+
snapshotHash: currentHash,
|
|
2469
|
+
bytes: bushBuffer.byteLength
|
|
2470
|
+
},
|
|
2471
|
+
"HDF5 bush file saved"
|
|
2472
|
+
);
|
|
2473
|
+
const skill = await withDeadline2(
|
|
2474
|
+
runtime.clients.sync.getHdf5BushReaderSkill(),
|
|
2475
|
+
deadline
|
|
2476
|
+
);
|
|
2477
|
+
return {
|
|
2478
|
+
content: [
|
|
2479
|
+
{
|
|
2480
|
+
type: "text",
|
|
2481
|
+
text: `HDF5 bush saved to ${filePath} (${bushBuffer.byteLength} bytes, snapshot ${currentHash}).
|
|
2482
|
+
|
|
2483
|
+
${skill}`
|
|
2484
|
+
}
|
|
2485
|
+
]
|
|
2486
|
+
};
|
|
2487
|
+
} catch (error) {
|
|
2488
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
2489
|
+
runtime.logger.error(
|
|
2490
|
+
{ err: error, snapshotHash: currentHash },
|
|
2491
|
+
"Bush download failed"
|
|
2492
|
+
);
|
|
2493
|
+
return {
|
|
2494
|
+
content: [
|
|
2495
|
+
{
|
|
2496
|
+
type: "text",
|
|
2497
|
+
text: `Failed to download bush for snapshot ${currentHash}: ${message}`
|
|
2498
|
+
}
|
|
2499
|
+
],
|
|
2500
|
+
isError: true
|
|
2501
|
+
};
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
if (status.status === "FAILED") {
|
|
2505
|
+
while (Date.now() < deadline) {
|
|
2506
|
+
if (isLocalStable()) break;
|
|
2507
|
+
await sleep3(250);
|
|
2508
|
+
}
|
|
2509
|
+
if (!isLocalStable()) break;
|
|
2510
|
+
currentHash = computeSnapshot(runtime.filesRepo).snapshotHash;
|
|
2511
|
+
continue;
|
|
2512
|
+
}
|
|
2513
|
+
runtime.outbox.enqueueSnapshot(runtime.config.rootId, 0);
|
|
2514
|
+
} catch {
|
|
2515
|
+
}
|
|
2516
|
+
const newHash = computeSnapshot(runtime.filesRepo).snapshotHash;
|
|
2517
|
+
if (newHash !== currentHash) {
|
|
2518
|
+
currentHash = newHash;
|
|
2519
|
+
continue;
|
|
2520
|
+
}
|
|
2521
|
+
await sleep3(500);
|
|
2522
|
+
}
|
|
2523
|
+
const statusText = formatStatus(
|
|
2524
|
+
await collectIndexingStatus(runtime, runner)
|
|
2525
|
+
);
|
|
2526
|
+
return {
|
|
2527
|
+
content: [
|
|
2528
|
+
{
|
|
2529
|
+
type: "text",
|
|
2530
|
+
text: `Snapshot not READY before deadline (last status: ${lastStatus ?? "unknown"}). Current status:
|
|
2531
|
+
|
|
2532
|
+
${statusText}`
|
|
2533
|
+
}
|
|
2534
|
+
],
|
|
2535
|
+
isError: true
|
|
2536
|
+
};
|
|
2537
|
+
}
|
|
2538
|
+
);
|
|
2400
2539
|
return server;
|
|
2401
2540
|
}
|
|
2402
2541
|
|