@coderule/mcp 2.1.0 → 2.2.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/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,128 @@ ${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
+ const bushBuffer = await withDeadline2(
2459
+ runtime.clients.sync.downloadSnapshotBush(currentHash),
2460
+ deadline
2461
+ );
2462
+ await mkdir(dirname(filePath), { recursive: true });
2463
+ await writeFile(filePath, Buffer.from(bushBuffer));
2464
+ runtime.logger.info(
2465
+ {
2466
+ filePath,
2467
+ snapshotHash: currentHash,
2468
+ bytes: bushBuffer.byteLength
2469
+ },
2470
+ "HDF5 bush file saved"
2471
+ );
2472
+ const skill = await withDeadline2(
2473
+ runtime.clients.sync.getHdf5BushReaderSkill(),
2474
+ deadline
2475
+ );
2476
+ return {
2477
+ content: [
2478
+ {
2479
+ type: "text",
2480
+ text: `HDF5 bush saved to ${filePath} (${bushBuffer.byteLength} bytes, snapshot ${currentHash}).
2481
+
2482
+ ${skill}`
2483
+ }
2484
+ ]
2485
+ };
2486
+ }
2487
+ if (status.status === "FAILED") {
2488
+ while (Date.now() < deadline) {
2489
+ if (isLocalStable()) break;
2490
+ await sleep3(250);
2491
+ }
2492
+ if (!isLocalStable()) break;
2493
+ currentHash = computeSnapshot(runtime.filesRepo).snapshotHash;
2494
+ continue;
2495
+ }
2496
+ runtime.outbox.enqueueSnapshot(runtime.config.rootId, 0);
2497
+ } catch {
2498
+ }
2499
+ const newHash = computeSnapshot(runtime.filesRepo).snapshotHash;
2500
+ if (newHash !== currentHash) {
2501
+ currentHash = newHash;
2502
+ continue;
2503
+ }
2504
+ await sleep3(500);
2505
+ }
2506
+ const statusText = formatStatus(
2507
+ await collectIndexingStatus(runtime, runner)
2508
+ );
2509
+ return {
2510
+ content: [
2511
+ {
2512
+ type: "text",
2513
+ text: `Snapshot not READY before deadline (last status: ${lastStatus ?? "unknown"}). Current status:
2514
+
2515
+ ${statusText}`
2516
+ }
2517
+ ],
2518
+ isError: true
2519
+ };
2520
+ }
2521
+ );
2400
2522
  return server;
2401
2523
  }
2402
2524