@hung319/opencode-hive 1.5.1 → 1.5.6
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/index.js
CHANGED
|
@@ -235,410 +235,6 @@ var require_dist = __commonJS((exports) => {
|
|
|
235
235
|
exports.default = AgentBooster;
|
|
236
236
|
});
|
|
237
237
|
|
|
238
|
-
// ../../node_modules/.bun/@ast-grep+napi-linux-x64-musl@0.41.1/node_modules/@ast-grep/napi-linux-x64-musl/ast-grep-napi.linux-x64-musl.node
|
|
239
|
-
var require_ast_grep_napi_linux_x64_musl = __commonJS((exports, module) => {
|
|
240
|
-
module.exports = __require("./ast-grep-napi.linux-x64-musl-qnd01z8b.node");
|
|
241
|
-
});
|
|
242
|
-
|
|
243
|
-
// ../../node_modules/.bun/@ast-grep+napi-linux-x64-gnu@0.41.1/node_modules/@ast-grep/napi-linux-x64-gnu/ast-grep-napi.linux-x64-gnu.node
|
|
244
|
-
var require_ast_grep_napi_linux_x64_gnu = __commonJS((exports, module) => {
|
|
245
|
-
module.exports = __require("./ast-grep-napi.linux-x64-gnu-qdwfscvp.node");
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// ../../node_modules/.bun/@ast-grep+napi@0.41.1/node_modules/@ast-grep/napi/index.js
|
|
249
|
-
var require_napi = __commonJS((exports, module) => {
|
|
250
|
-
var __filename = "/home/runner/work/agent-hive/agent-hive/node_modules/.bun/@ast-grep+napi@0.41.1/node_modules/@ast-grep/napi/index.js";
|
|
251
|
-
var { createRequire: createRequire2 } = __require("node:module");
|
|
252
|
-
__require = createRequire2(__filename);
|
|
253
|
-
var { readFileSync: readFileSync5 } = __require("node:fs");
|
|
254
|
-
var nativeBinding = null;
|
|
255
|
-
var loadErrors = [];
|
|
256
|
-
var isMusl = () => {
|
|
257
|
-
let musl = false;
|
|
258
|
-
if (process.platform === "linux") {
|
|
259
|
-
musl = isMuslFromFilesystem();
|
|
260
|
-
if (musl === null) {
|
|
261
|
-
musl = isMuslFromReport();
|
|
262
|
-
}
|
|
263
|
-
if (musl === null) {
|
|
264
|
-
musl = isMuslFromChildProcess();
|
|
265
|
-
}
|
|
266
|
-
}
|
|
267
|
-
return musl;
|
|
268
|
-
};
|
|
269
|
-
var isFileMusl = (f) => f.includes("libc.musl-") || f.includes("ld-musl-");
|
|
270
|
-
var isMuslFromFilesystem = () => {
|
|
271
|
-
try {
|
|
272
|
-
return readFileSync5("/usr/bin/ldd", "utf-8").includes("musl");
|
|
273
|
-
} catch {
|
|
274
|
-
return null;
|
|
275
|
-
}
|
|
276
|
-
};
|
|
277
|
-
var isMuslFromReport = () => {
|
|
278
|
-
let report = null;
|
|
279
|
-
if (typeof process.report?.getReport === "function") {
|
|
280
|
-
process.report.excludeNetwork = true;
|
|
281
|
-
report = process.report.getReport();
|
|
282
|
-
}
|
|
283
|
-
if (!report) {
|
|
284
|
-
return null;
|
|
285
|
-
}
|
|
286
|
-
if (report.header && report.header.glibcVersionRuntime) {
|
|
287
|
-
return false;
|
|
288
|
-
}
|
|
289
|
-
if (Array.isArray(report.sharedObjects)) {
|
|
290
|
-
if (report.sharedObjects.some(isFileMusl)) {
|
|
291
|
-
return true;
|
|
292
|
-
}
|
|
293
|
-
}
|
|
294
|
-
return false;
|
|
295
|
-
};
|
|
296
|
-
var isMuslFromChildProcess = () => {
|
|
297
|
-
try {
|
|
298
|
-
return __require("child_process").execSync("ldd --version", { encoding: "utf8" }).includes("musl");
|
|
299
|
-
} catch (e) {
|
|
300
|
-
return false;
|
|
301
|
-
}
|
|
302
|
-
};
|
|
303
|
-
function requireNative() {
|
|
304
|
-
if (process.env.NAPI_RS_NATIVE_LIBRARY_PATH) {
|
|
305
|
-
try {
|
|
306
|
-
nativeBinding = __require(process.env.NAPI_RS_NATIVE_LIBRARY_PATH);
|
|
307
|
-
} catch (err) {
|
|
308
|
-
loadErrors.push(err);
|
|
309
|
-
}
|
|
310
|
-
} else if (process.platform === "android") {
|
|
311
|
-
if (process.arch === "arm64") {
|
|
312
|
-
try {
|
|
313
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.android-arm64.node");})();
|
|
314
|
-
} catch (e) {
|
|
315
|
-
loadErrors.push(e);
|
|
316
|
-
}
|
|
317
|
-
try {
|
|
318
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-android-arm64");})();
|
|
319
|
-
} catch (e) {
|
|
320
|
-
loadErrors.push(e);
|
|
321
|
-
}
|
|
322
|
-
} else if (process.arch === "arm") {
|
|
323
|
-
try {
|
|
324
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.android-arm-eabi.node");})();
|
|
325
|
-
} catch (e) {
|
|
326
|
-
loadErrors.push(e);
|
|
327
|
-
}
|
|
328
|
-
try {
|
|
329
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-android-arm-eabi");})();
|
|
330
|
-
} catch (e) {
|
|
331
|
-
loadErrors.push(e);
|
|
332
|
-
}
|
|
333
|
-
} else {
|
|
334
|
-
loadErrors.push(new Error(`Unsupported architecture on Android ${process.arch}`));
|
|
335
|
-
}
|
|
336
|
-
} else if (process.platform === "win32") {
|
|
337
|
-
if (process.arch === "x64") {
|
|
338
|
-
try {
|
|
339
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.win32-x64-msvc.node");})();
|
|
340
|
-
} catch (e) {
|
|
341
|
-
loadErrors.push(e);
|
|
342
|
-
}
|
|
343
|
-
try {
|
|
344
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-win32-x64-msvc");})();
|
|
345
|
-
} catch (e) {
|
|
346
|
-
loadErrors.push(e);
|
|
347
|
-
}
|
|
348
|
-
} else if (process.arch === "ia32") {
|
|
349
|
-
try {
|
|
350
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.win32-ia32-msvc.node");})();
|
|
351
|
-
} catch (e) {
|
|
352
|
-
loadErrors.push(e);
|
|
353
|
-
}
|
|
354
|
-
try {
|
|
355
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-win32-ia32-msvc");})();
|
|
356
|
-
} catch (e) {
|
|
357
|
-
loadErrors.push(e);
|
|
358
|
-
}
|
|
359
|
-
} else if (process.arch === "arm64") {
|
|
360
|
-
try {
|
|
361
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.win32-arm64-msvc.node");})();
|
|
362
|
-
} catch (e) {
|
|
363
|
-
loadErrors.push(e);
|
|
364
|
-
}
|
|
365
|
-
try {
|
|
366
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-win32-arm64-msvc");})();
|
|
367
|
-
} catch (e) {
|
|
368
|
-
loadErrors.push(e);
|
|
369
|
-
}
|
|
370
|
-
} else {
|
|
371
|
-
loadErrors.push(new Error(`Unsupported architecture on Windows: ${process.arch}`));
|
|
372
|
-
}
|
|
373
|
-
} else if (process.platform === "darwin") {
|
|
374
|
-
try {
|
|
375
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.darwin-universal.node");})();
|
|
376
|
-
} catch (e) {
|
|
377
|
-
loadErrors.push(e);
|
|
378
|
-
}
|
|
379
|
-
try {
|
|
380
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-darwin-universal");})();
|
|
381
|
-
} catch (e) {
|
|
382
|
-
loadErrors.push(e);
|
|
383
|
-
}
|
|
384
|
-
if (process.arch === "x64") {
|
|
385
|
-
try {
|
|
386
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.darwin-x64.node");})();
|
|
387
|
-
} catch (e) {
|
|
388
|
-
loadErrors.push(e);
|
|
389
|
-
}
|
|
390
|
-
try {
|
|
391
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-darwin-x64");})();
|
|
392
|
-
} catch (e) {
|
|
393
|
-
loadErrors.push(e);
|
|
394
|
-
}
|
|
395
|
-
} else if (process.arch === "arm64") {
|
|
396
|
-
try {
|
|
397
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.darwin-arm64.node");})();
|
|
398
|
-
} catch (e) {
|
|
399
|
-
loadErrors.push(e);
|
|
400
|
-
}
|
|
401
|
-
try {
|
|
402
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-darwin-arm64");})();
|
|
403
|
-
} catch (e) {
|
|
404
|
-
loadErrors.push(e);
|
|
405
|
-
}
|
|
406
|
-
} else {
|
|
407
|
-
loadErrors.push(new Error(`Unsupported architecture on macOS: ${process.arch}`));
|
|
408
|
-
}
|
|
409
|
-
} else if (process.platform === "freebsd") {
|
|
410
|
-
if (process.arch === "x64") {
|
|
411
|
-
try {
|
|
412
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.freebsd-x64.node");})();
|
|
413
|
-
} catch (e) {
|
|
414
|
-
loadErrors.push(e);
|
|
415
|
-
}
|
|
416
|
-
try {
|
|
417
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-freebsd-x64");})();
|
|
418
|
-
} catch (e) {
|
|
419
|
-
loadErrors.push(e);
|
|
420
|
-
}
|
|
421
|
-
} else if (process.arch === "arm64") {
|
|
422
|
-
try {
|
|
423
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.freebsd-arm64.node");})();
|
|
424
|
-
} catch (e) {
|
|
425
|
-
loadErrors.push(e);
|
|
426
|
-
}
|
|
427
|
-
try {
|
|
428
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-freebsd-arm64");})();
|
|
429
|
-
} catch (e) {
|
|
430
|
-
loadErrors.push(e);
|
|
431
|
-
}
|
|
432
|
-
} else {
|
|
433
|
-
loadErrors.push(new Error(`Unsupported architecture on FreeBSD: ${process.arch}`));
|
|
434
|
-
}
|
|
435
|
-
} else if (process.platform === "linux") {
|
|
436
|
-
if (process.arch === "x64") {
|
|
437
|
-
if (isMusl()) {
|
|
438
|
-
try {
|
|
439
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-x64-musl.node");})();
|
|
440
|
-
} catch (e) {
|
|
441
|
-
loadErrors.push(e);
|
|
442
|
-
}
|
|
443
|
-
try {
|
|
444
|
-
return require_ast_grep_napi_linux_x64_musl();
|
|
445
|
-
} catch (e) {
|
|
446
|
-
loadErrors.push(e);
|
|
447
|
-
}
|
|
448
|
-
} else {
|
|
449
|
-
try {
|
|
450
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-x64-gnu.node");})();
|
|
451
|
-
} catch (e) {
|
|
452
|
-
loadErrors.push(e);
|
|
453
|
-
}
|
|
454
|
-
try {
|
|
455
|
-
return require_ast_grep_napi_linux_x64_gnu();
|
|
456
|
-
} catch (e) {
|
|
457
|
-
loadErrors.push(e);
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
|
-
} else if (process.arch === "arm64") {
|
|
461
|
-
if (isMusl()) {
|
|
462
|
-
try {
|
|
463
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm64-musl.node");})();
|
|
464
|
-
} catch (e) {
|
|
465
|
-
loadErrors.push(e);
|
|
466
|
-
}
|
|
467
|
-
try {
|
|
468
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm64-musl");})();
|
|
469
|
-
} catch (e) {
|
|
470
|
-
loadErrors.push(e);
|
|
471
|
-
}
|
|
472
|
-
} else {
|
|
473
|
-
try {
|
|
474
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm64-gnu.node");})();
|
|
475
|
-
} catch (e) {
|
|
476
|
-
loadErrors.push(e);
|
|
477
|
-
}
|
|
478
|
-
try {
|
|
479
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm64-gnu");})();
|
|
480
|
-
} catch (e) {
|
|
481
|
-
loadErrors.push(e);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
} else if (process.arch === "arm") {
|
|
485
|
-
if (isMusl()) {
|
|
486
|
-
try {
|
|
487
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm-musleabihf.node");})();
|
|
488
|
-
} catch (e) {
|
|
489
|
-
loadErrors.push(e);
|
|
490
|
-
}
|
|
491
|
-
try {
|
|
492
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm-musleabihf");})();
|
|
493
|
-
} catch (e) {
|
|
494
|
-
loadErrors.push(e);
|
|
495
|
-
}
|
|
496
|
-
} else {
|
|
497
|
-
try {
|
|
498
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm-gnueabihf.node");})();
|
|
499
|
-
} catch (e) {
|
|
500
|
-
loadErrors.push(e);
|
|
501
|
-
}
|
|
502
|
-
try {
|
|
503
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm-gnueabihf");})();
|
|
504
|
-
} catch (e) {
|
|
505
|
-
loadErrors.push(e);
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
} else if (process.arch === "riscv64") {
|
|
509
|
-
if (isMusl()) {
|
|
510
|
-
try {
|
|
511
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-riscv64-musl.node");})();
|
|
512
|
-
} catch (e) {
|
|
513
|
-
loadErrors.push(e);
|
|
514
|
-
}
|
|
515
|
-
try {
|
|
516
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-riscv64-musl");})();
|
|
517
|
-
} catch (e) {
|
|
518
|
-
loadErrors.push(e);
|
|
519
|
-
}
|
|
520
|
-
} else {
|
|
521
|
-
try {
|
|
522
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-riscv64-gnu.node");})();
|
|
523
|
-
} catch (e) {
|
|
524
|
-
loadErrors.push(e);
|
|
525
|
-
}
|
|
526
|
-
try {
|
|
527
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-riscv64-gnu");})();
|
|
528
|
-
} catch (e) {
|
|
529
|
-
loadErrors.push(e);
|
|
530
|
-
}
|
|
531
|
-
}
|
|
532
|
-
} else if (process.arch === "ppc64") {
|
|
533
|
-
try {
|
|
534
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-ppc64-gnu.node");})();
|
|
535
|
-
} catch (e) {
|
|
536
|
-
loadErrors.push(e);
|
|
537
|
-
}
|
|
538
|
-
try {
|
|
539
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-ppc64-gnu");})();
|
|
540
|
-
} catch (e) {
|
|
541
|
-
loadErrors.push(e);
|
|
542
|
-
}
|
|
543
|
-
} else if (process.arch === "s390x") {
|
|
544
|
-
try {
|
|
545
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-s390x-gnu.node");})();
|
|
546
|
-
} catch (e) {
|
|
547
|
-
loadErrors.push(e);
|
|
548
|
-
}
|
|
549
|
-
try {
|
|
550
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-s390x-gnu");})();
|
|
551
|
-
} catch (e) {
|
|
552
|
-
loadErrors.push(e);
|
|
553
|
-
}
|
|
554
|
-
} else {
|
|
555
|
-
loadErrors.push(new Error(`Unsupported architecture on Linux: ${process.arch}`));
|
|
556
|
-
}
|
|
557
|
-
} else if (process.platform === "openharmony") {
|
|
558
|
-
if (process.arch === "arm64") {
|
|
559
|
-
try {
|
|
560
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm64-ohos.node");})();
|
|
561
|
-
} catch (e) {
|
|
562
|
-
loadErrors.push(e);
|
|
563
|
-
}
|
|
564
|
-
try {
|
|
565
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm64-ohos");})();
|
|
566
|
-
} catch (e) {
|
|
567
|
-
loadErrors.push(e);
|
|
568
|
-
}
|
|
569
|
-
} else if (process.arch === "x64") {
|
|
570
|
-
try {
|
|
571
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-x64-ohos.node");})();
|
|
572
|
-
} catch (e) {
|
|
573
|
-
loadErrors.push(e);
|
|
574
|
-
}
|
|
575
|
-
try {
|
|
576
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-x64-ohos");})();
|
|
577
|
-
} catch (e) {
|
|
578
|
-
loadErrors.push(e);
|
|
579
|
-
}
|
|
580
|
-
} else if (process.arch === "arm") {
|
|
581
|
-
try {
|
|
582
|
-
return (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.linux-arm-ohos.node");})();
|
|
583
|
-
} catch (e) {
|
|
584
|
-
loadErrors.push(e);
|
|
585
|
-
}
|
|
586
|
-
try {
|
|
587
|
-
return (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-linux-arm-ohos");})();
|
|
588
|
-
} catch (e) {
|
|
589
|
-
loadErrors.push(e);
|
|
590
|
-
}
|
|
591
|
-
} else {
|
|
592
|
-
loadErrors.push(new Error(`Unsupported architecture on OpenHarmony: ${process.arch}`));
|
|
593
|
-
}
|
|
594
|
-
} else {
|
|
595
|
-
loadErrors.push(new Error(`Unsupported OS: ${process.platform}, architecture: ${process.arch}`));
|
|
596
|
-
}
|
|
597
|
-
}
|
|
598
|
-
nativeBinding = requireNative();
|
|
599
|
-
if (!nativeBinding || process.env.NAPI_RS_FORCE_WASI) {
|
|
600
|
-
try {
|
|
601
|
-
nativeBinding = (()=>{throw new Error("Cannot require module "+"./ast-grep-napi.wasi.cjs");})();
|
|
602
|
-
} catch (err) {
|
|
603
|
-
if (process.env.NAPI_RS_FORCE_WASI) {
|
|
604
|
-
loadErrors.push(err);
|
|
605
|
-
}
|
|
606
|
-
}
|
|
607
|
-
if (!nativeBinding) {
|
|
608
|
-
try {
|
|
609
|
-
nativeBinding = (()=>{throw new Error("Cannot require module "+"@ast-grep/napi-wasm32-wasi");})();
|
|
610
|
-
} catch (err) {
|
|
611
|
-
if (process.env.NAPI_RS_FORCE_WASI) {
|
|
612
|
-
loadErrors.push(err);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
if (!nativeBinding) {
|
|
618
|
-
if (loadErrors.length > 0) {
|
|
619
|
-
throw new Error(`Cannot find native binding. ` + `npm has a bug related to optional dependencies (https://github.com/npm/cli/issues/4828). ` + "Please try `npm i` again after removing both package-lock.json and node_modules directory.", { cause: loadErrors });
|
|
620
|
-
}
|
|
621
|
-
throw new Error(`Failed to load native binding`);
|
|
622
|
-
}
|
|
623
|
-
module.exports = nativeBinding;
|
|
624
|
-
module.exports.SgNode = nativeBinding.SgNode;
|
|
625
|
-
module.exports.SgRoot = nativeBinding.SgRoot;
|
|
626
|
-
module.exports.findInFiles = nativeBinding.findInFiles;
|
|
627
|
-
module.exports.kind = nativeBinding.kind;
|
|
628
|
-
module.exports.Lang = nativeBinding.Lang;
|
|
629
|
-
module.exports.parse = nativeBinding.parse;
|
|
630
|
-
module.exports.parseAsync = nativeBinding.parseAsync;
|
|
631
|
-
module.exports.parseFiles = nativeBinding.parseFiles;
|
|
632
|
-
module.exports.pattern = nativeBinding.pattern;
|
|
633
|
-
module.exports.registerDynamicLanguage = nativeBinding.registerDynamicLanguage;
|
|
634
|
-
module.exports.css = nativeBinding.css;
|
|
635
|
-
module.exports.html = nativeBinding.html;
|
|
636
|
-
module.exports.js = nativeBinding.js;
|
|
637
|
-
module.exports.jsx = nativeBinding.jsx;
|
|
638
|
-
module.exports.ts = nativeBinding.ts;
|
|
639
|
-
module.exports.tsx = nativeBinding.tsx;
|
|
640
|
-
});
|
|
641
|
-
|
|
642
238
|
// src/utils/context-compression.ts
|
|
643
239
|
var exports_context_compression = {};
|
|
644
240
|
__export(exports_context_compression, {
|
|
@@ -854,8 +450,8 @@ var init_context_compression = __esm(() => {
|
|
|
854
450
|
});
|
|
855
451
|
|
|
856
452
|
// src/index.ts
|
|
857
|
-
import * as
|
|
858
|
-
import * as
|
|
453
|
+
import * as path11 from "path";
|
|
454
|
+
import * as os4 from "os";
|
|
859
455
|
|
|
860
456
|
// ../../node_modules/.bun/zod@4.1.8/node_modules/zod/v4/classic/external.js
|
|
861
457
|
var exports_external = {};
|
|
@@ -18208,485 +17804,52 @@ var hiveVectorStatusTool = tool({
|
|
|
18208
17804
|
}
|
|
18209
17805
|
});
|
|
18210
17806
|
|
|
18211
|
-
// src/tools/
|
|
17807
|
+
// src/tools/hive-doctor.ts
|
|
17808
|
+
import { execSync as execSync2 } from "child_process";
|
|
18212
17809
|
import * as fs5 from "fs";
|
|
18213
|
-
|
|
18214
|
-
|
|
18215
|
-
|
|
18216
|
-
|
|
18217
|
-
|
|
18218
|
-
|
|
18219
|
-
|
|
18220
|
-
|
|
18221
|
-
|
|
18222
|
-
|
|
18223
|
-
|
|
18224
|
-
|
|
18225
|
-
|
|
18226
|
-
console.log("[ast-grep] Native NAPI initialized successfully");
|
|
18227
|
-
} catch (error45) {
|
|
18228
|
-
console.warn("[ast-grep] Failed to load @ast-grep/napi:", error45 instanceof Error ? error45.message : error45);
|
|
18229
|
-
astGrepModule = null;
|
|
17810
|
+
import * as path6 from "path";
|
|
17811
|
+
async function checkPackage(packageName) {
|
|
17812
|
+
try {
|
|
17813
|
+
const packageJsonPath = __require.resolve(`${packageName}/package.json`, {
|
|
17814
|
+
paths: [
|
|
17815
|
+
process.cwd(),
|
|
17816
|
+
path6.join(process.cwd(), "node_modules"),
|
|
17817
|
+
path6.join(process.cwd(), "packages/opencode-hive/node_modules")
|
|
17818
|
+
]
|
|
17819
|
+
});
|
|
17820
|
+
if (fs5.existsSync(packageJsonPath)) {
|
|
17821
|
+
const pkg = JSON.parse(fs5.readFileSync(packageJsonPath, "utf-8"));
|
|
17822
|
+
return { installed: true, version: pkg.version };
|
|
18230
17823
|
}
|
|
18231
|
-
}
|
|
18232
|
-
|
|
17824
|
+
} catch {}
|
|
17825
|
+
return { installed: false };
|
|
18233
17826
|
}
|
|
18234
|
-
|
|
18235
|
-
|
|
18236
|
-
|
|
18237
|
-
|
|
18238
|
-
|
|
18239
|
-
|
|
18240
|
-
|
|
18241
|
-
|
|
18242
|
-
|
|
18243
|
-
|
|
18244
|
-
|
|
18245
|
-
|
|
18246
|
-
- Finding correct syntax kind names
|
|
18247
|
-
- Understanding code structure`,
|
|
18248
|
-
args: {
|
|
18249
|
-
code: tool.schema.string().describe("The code to analyze"),
|
|
18250
|
-
language: tool.schema.string().describe("Programming language (typescript, javascript, python, rust, go, java, etc.)"),
|
|
18251
|
-
format: tool.schema.enum(["cst", "pattern"]).default("cst").describe("Output format")
|
|
18252
|
-
},
|
|
18253
|
-
async execute({ code, language, format }) {
|
|
18254
|
-
await initAstGrep();
|
|
18255
|
-
if (!astGrepModule) {
|
|
18256
|
-
return JSON.stringify({
|
|
18257
|
-
success: false,
|
|
18258
|
-
error: "@ast-grep/napi not available",
|
|
18259
|
-
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18260
|
-
}, null, 2);
|
|
18261
|
-
}
|
|
17827
|
+
function checkCliTool(tool3) {
|
|
17828
|
+
try {
|
|
17829
|
+
const result = execSync2(tool3.command, { stdio: "pipe", timeout: 5000 });
|
|
17830
|
+
const output = result.toString().trim();
|
|
17831
|
+
const versionMatch = output.match(/(\d+\.\d+\.\d+)/);
|
|
17832
|
+
return {
|
|
17833
|
+
...tool3,
|
|
17834
|
+
installed: true,
|
|
17835
|
+
version: versionMatch ? versionMatch[1] : output.slice(0, 50)
|
|
17836
|
+
};
|
|
17837
|
+
} catch {
|
|
17838
|
+
const npxCmd = tool3.command.split(" ")[0];
|
|
18262
17839
|
try {
|
|
18263
|
-
|
|
18264
|
-
|
|
18265
|
-
|
|
18266
|
-
|
|
18267
|
-
|
|
18268
|
-
python: "Python",
|
|
18269
|
-
rust: "Rust",
|
|
18270
|
-
go: "Go",
|
|
18271
|
-
java: "Java",
|
|
18272
|
-
c: "C",
|
|
18273
|
-
cpp: "Cpp",
|
|
18274
|
-
csharp: "CSharp"
|
|
18275
|
-
};
|
|
18276
|
-
const lang = langMap[language.toLowerCase()] || language;
|
|
18277
|
-
const Lang = astGrepModule.Lang;
|
|
18278
|
-
if (!Lang || !Lang[lang]) {
|
|
18279
|
-
return JSON.stringify({
|
|
18280
|
-
success: false,
|
|
18281
|
-
error: `Unsupported language: ${language}`,
|
|
18282
|
-
availableLanguages: Object.keys(langMap)
|
|
18283
|
-
}, null, 2);
|
|
18284
|
-
}
|
|
18285
|
-
if (format === "pattern") {
|
|
18286
|
-
return JSON.stringify({
|
|
18287
|
-
success: true,
|
|
18288
|
-
format: "pattern",
|
|
18289
|
-
language,
|
|
18290
|
-
example: {
|
|
18291
|
-
match: "AwaitExpression",
|
|
18292
|
-
kind: "Use kind to match AST node types",
|
|
18293
|
-
pattern: "Use pattern for code templates"
|
|
18294
|
-
}
|
|
18295
|
-
}, null, 2);
|
|
18296
|
-
}
|
|
18297
|
-
const parse5 = astGrepModule.parse;
|
|
18298
|
-
const ast = parse5(Lang[lang], code);
|
|
18299
|
-
const root = ast.root();
|
|
18300
|
-
const dump = (node, depth = 0) => {
|
|
18301
|
-
if (!node)
|
|
18302
|
-
return null;
|
|
18303
|
-
return {
|
|
18304
|
-
kind: node.kind(),
|
|
18305
|
-
text: node.text(),
|
|
18306
|
-
children: node.children().map((child) => dump(child, depth + 1))
|
|
18307
|
-
};
|
|
17840
|
+
execSync2(`npx -y ${npxCmd} --version`, { stdio: "pipe", timeout: 1e4 });
|
|
17841
|
+
return {
|
|
17842
|
+
...tool3,
|
|
17843
|
+
installed: true,
|
|
17844
|
+
version: "via npx"
|
|
18308
17845
|
};
|
|
18309
|
-
|
|
18310
|
-
|
|
18311
|
-
|
|
18312
|
-
|
|
18313
|
-
tree: dump(root)
|
|
18314
|
-
}, null, 2);
|
|
18315
|
-
} catch (error45) {
|
|
18316
|
-
return JSON.stringify({
|
|
18317
|
-
success: false,
|
|
18318
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18319
|
-
}, null, 2);
|
|
18320
|
-
}
|
|
18321
|
-
}
|
|
18322
|
-
});
|
|
18323
|
-
var astGrepTestMatchCodeRuleTool = tool({
|
|
18324
|
-
description: `Test a code against an ast-grep YAML rule.
|
|
18325
|
-
|
|
18326
|
-
This is useful to test a rule before using it in a project.
|
|
18327
|
-
|
|
18328
|
-
**Parameters:**
|
|
18329
|
-
- code: The code to test against the rule
|
|
18330
|
-
- yaml: The ast-grep YAML rule to test
|
|
18331
|
-
|
|
18332
|
-
**Returns:**
|
|
18333
|
-
- Whether the rule matched
|
|
18334
|
-
- Matched nodes with locations`,
|
|
18335
|
-
args: {
|
|
18336
|
-
code: tool.schema.string().describe("The code to test against the rule"),
|
|
18337
|
-
yaml: tool.schema.string().describe("The ast-grep YAML rule to search")
|
|
18338
|
-
},
|
|
18339
|
-
async execute({ code, yaml }) {
|
|
18340
|
-
await initAstGrep();
|
|
18341
|
-
if (!astGrepModule) {
|
|
18342
|
-
return JSON.stringify({
|
|
18343
|
-
success: false,
|
|
18344
|
-
error: "@ast-grep/napi not available",
|
|
18345
|
-
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18346
|
-
}, null, 2);
|
|
18347
|
-
}
|
|
18348
|
-
try {
|
|
18349
|
-
const parse5 = astGrepModule.parse;
|
|
18350
|
-
const Lang = astGrepModule.Lang;
|
|
18351
|
-
const ast = parse5(Lang.TypeScript, code);
|
|
18352
|
-
const root = ast.root();
|
|
18353
|
-
return JSON.stringify({
|
|
18354
|
-
success: true,
|
|
18355
|
-
matched: false,
|
|
18356
|
-
note: "YAML rule testing requires @ast-grep/cli. Use ast_grep_find_code for pattern-based search.",
|
|
18357
|
-
example: {
|
|
18358
|
-
pattern: "console.log($ARG)",
|
|
18359
|
-
description: "Match console.log with any argument"
|
|
18360
|
-
}
|
|
18361
|
-
}, null, 2);
|
|
18362
|
-
} catch (error45) {
|
|
18363
|
-
return JSON.stringify({
|
|
18364
|
-
success: false,
|
|
18365
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18366
|
-
}, null, 2);
|
|
18367
|
-
}
|
|
18368
|
-
}
|
|
18369
|
-
});
|
|
18370
|
-
var astGrepFindCodeTool = tool({
|
|
18371
|
-
description: `Find code in a project folder that matches the given ast-grep pattern.
|
|
18372
|
-
|
|
18373
|
-
Pattern is good for simple and single-AST node result. For more complex usage, use ast_grep_scan_code.
|
|
18374
|
-
|
|
18375
|
-
**Parameters:**
|
|
18376
|
-
- project_folder: The absolute path to the project folder
|
|
18377
|
-
- pattern: The ast-grep pattern to search for (e.g., 'console.log($ARG)', '$VAR = $VALUE')
|
|
18378
|
-
- language: Optional - programming language filter
|
|
18379
|
-
|
|
18380
|
-
**Pattern Examples:**
|
|
18381
|
-
- 'console.log($ARG)' - Match console.log with any argument
|
|
18382
|
-
- '$VAR = $VALUE' - Match any assignment
|
|
18383
|
-
- 'function $NAME($PARAMS) { $BODY }' - Match function declarations`,
|
|
18384
|
-
args: {
|
|
18385
|
-
project_folder: tool.schema.string().describe("The absolute path to the project folder"),
|
|
18386
|
-
pattern: tool.schema.string().describe("The ast-grep pattern to search for"),
|
|
18387
|
-
language: tool.schema.string().optional().describe("Programming language filter (typescript, javascript, python, etc.)")
|
|
18388
|
-
},
|
|
18389
|
-
async execute({ project_folder, pattern, language }) {
|
|
18390
|
-
await initAstGrep();
|
|
18391
|
-
if (!astGrepModule) {
|
|
18392
|
-
return JSON.stringify({
|
|
18393
|
-
success: false,
|
|
18394
|
-
error: "@ast-grep/napi not available",
|
|
18395
|
-
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18396
|
-
}, null, 2);
|
|
18397
|
-
}
|
|
18398
|
-
try {
|
|
18399
|
-
if (!fs5.existsSync(project_folder)) {
|
|
18400
|
-
return JSON.stringify({
|
|
18401
|
-
success: false,
|
|
18402
|
-
error: `Path not found: ${project_folder}`
|
|
18403
|
-
}, null, 2);
|
|
18404
|
-
}
|
|
18405
|
-
const langMap = {
|
|
18406
|
-
typescript: "TypeScript",
|
|
18407
|
-
javascript: "JavaScript",
|
|
18408
|
-
tsx: "Tsx",
|
|
18409
|
-
jsx: "Jsx",
|
|
18410
|
-
python: "Python",
|
|
18411
|
-
rust: "Rust",
|
|
18412
|
-
go: "Go",
|
|
18413
|
-
java: "Java"
|
|
17846
|
+
} catch {
|
|
17847
|
+
return {
|
|
17848
|
+
...tool3,
|
|
17849
|
+
installed: false
|
|
18414
17850
|
};
|
|
18415
|
-
const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
|
|
18416
|
-
const Lang = astGrepModule.Lang;
|
|
18417
|
-
if (!Lang[lang]) {
|
|
18418
|
-
return JSON.stringify({
|
|
18419
|
-
success: false,
|
|
18420
|
-
error: `Unsupported language: ${language}`
|
|
18421
|
-
}, null, 2);
|
|
18422
|
-
}
|
|
18423
|
-
const findInFiles = astGrepModule.findInFiles;
|
|
18424
|
-
const results = [];
|
|
18425
|
-
await findInFiles(Lang[lang], {
|
|
18426
|
-
paths: [project_folder],
|
|
18427
|
-
matcher: { rule: { pattern } }
|
|
18428
|
-
}, (err, node) => {
|
|
18429
|
-
if (err) {
|
|
18430
|
-
console.warn("[ast-grep] Search error:", err);
|
|
18431
|
-
return;
|
|
18432
|
-
}
|
|
18433
|
-
if (node) {
|
|
18434
|
-
const text = node.text();
|
|
18435
|
-
const range = node.range();
|
|
18436
|
-
results.push({
|
|
18437
|
-
file: node.filename() || "unknown",
|
|
18438
|
-
line: range ? range.start.index : 0,
|
|
18439
|
-
column: range ? range.start.column : 0,
|
|
18440
|
-
matched: text.slice(0, 100)
|
|
18441
|
-
});
|
|
18442
|
-
}
|
|
18443
|
-
});
|
|
18444
|
-
return JSON.stringify({
|
|
18445
|
-
success: true,
|
|
18446
|
-
count: results.length,
|
|
18447
|
-
matches: results.slice(0, 50)
|
|
18448
|
-
}, null, 2);
|
|
18449
|
-
} catch (error45) {
|
|
18450
|
-
return JSON.stringify({
|
|
18451
|
-
success: false,
|
|
18452
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18453
|
-
}, null, 2);
|
|
18454
17851
|
}
|
|
18455
17852
|
}
|
|
18456
|
-
});
|
|
18457
|
-
var astGrepScanCodeTool = tool({
|
|
18458
|
-
description: `Analyze TypeScript/JS code for common bugs, performance issues and best practices.
|
|
18459
|
-
|
|
18460
|
-
Uses AST-based analysis for precise detection without false positives. Essential for maintaining code quality and preventing runtime errors.
|
|
18461
|
-
|
|
18462
|
-
**Detects:**
|
|
18463
|
-
- Type safety violations
|
|
18464
|
-
- Loose object types
|
|
18465
|
-
- Incorrect async patterns
|
|
18466
|
-
- Import style issues
|
|
18467
|
-
- Common bugs
|
|
18468
|
-
|
|
18469
|
-
**Parameters:**
|
|
18470
|
-
- project_folder: Optional - path to scan (defaults to current directory)`,
|
|
18471
|
-
args: {
|
|
18472
|
-
project_folder: tool.schema.string().optional().describe("Path to scan (defaults to current directory)")
|
|
18473
|
-
},
|
|
18474
|
-
async execute({ project_folder }) {
|
|
18475
|
-
await initAstGrep();
|
|
18476
|
-
if (!astGrepModule) {
|
|
18477
|
-
return JSON.stringify({
|
|
18478
|
-
success: false,
|
|
18479
|
-
error: "@ast-grep/napi not available",
|
|
18480
|
-
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18481
|
-
}, null, 2);
|
|
18482
|
-
}
|
|
18483
|
-
try {
|
|
18484
|
-
const scanPath = project_folder || process.cwd();
|
|
18485
|
-
if (!fs5.existsSync(scanPath)) {
|
|
18486
|
-
return JSON.stringify({
|
|
18487
|
-
success: false,
|
|
18488
|
-
error: `Path not found: ${scanPath}`
|
|
18489
|
-
}, null, 2);
|
|
18490
|
-
}
|
|
18491
|
-
const bugPatterns = [
|
|
18492
|
-
{ pattern: "await Promise.all($ARR)", severity: "warning", message: "Check if Promise.all is used correctly with async operations" },
|
|
18493
|
-
{ pattern: "JSON.parse($STR)", severity: "info", message: "Consider adding try-catch for JSON.parse" },
|
|
18494
|
-
{ pattern: "$VAR == $VAL", severity: "warning", message: "Use === instead of == for strict equality" }
|
|
18495
|
-
];
|
|
18496
|
-
const issues = [];
|
|
18497
|
-
const Lang = astGrepModule.Lang;
|
|
18498
|
-
const findInFiles = astGrepModule.findInFiles;
|
|
18499
|
-
for (const bug of bugPatterns) {
|
|
18500
|
-
await findInFiles(Lang.TypeScript, {
|
|
18501
|
-
paths: [scanPath],
|
|
18502
|
-
matcher: { rule: { pattern: bug.pattern } }
|
|
18503
|
-
}, (err, node) => {
|
|
18504
|
-
if (err || !node)
|
|
18505
|
-
return;
|
|
18506
|
-
issues.push({
|
|
18507
|
-
file: node.filename() || "unknown",
|
|
18508
|
-
line: node.range()?.start.index || 0,
|
|
18509
|
-
severity: bug.severity,
|
|
18510
|
-
message: bug.message,
|
|
18511
|
-
pattern: bug.pattern
|
|
18512
|
-
});
|
|
18513
|
-
});
|
|
18514
|
-
}
|
|
18515
|
-
return JSON.stringify({
|
|
18516
|
-
success: true,
|
|
18517
|
-
scanned: scanPath,
|
|
18518
|
-
issuesFound: issues.length,
|
|
18519
|
-
issues: issues.slice(0, 20),
|
|
18520
|
-
summary: issues.length === 0 ? "No common issues detected" : `Found ${issues.length} potential issues`
|
|
18521
|
-
}, null, 2);
|
|
18522
|
-
} catch (error45) {
|
|
18523
|
-
return JSON.stringify({
|
|
18524
|
-
success: false,
|
|
18525
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18526
|
-
}, null, 2);
|
|
18527
|
-
}
|
|
18528
|
-
}
|
|
18529
|
-
});
|
|
18530
|
-
var astGrepRewriteCodeTool = tool({
|
|
18531
|
-
description: `Transform and refactor code using AST-based find-and-replace patterns.
|
|
18532
|
-
|
|
18533
|
-
Use metavariables ($VAR, $$$VARS) in both pattern and replacement.
|
|
18534
|
-
|
|
18535
|
-
**Example:** Find 'console.log($ARG)' and replace with 'logger.info($ARG)'
|
|
18536
|
-
|
|
18537
|
-
**Parameters:**
|
|
18538
|
-
- project_folder: Path to the project folder
|
|
18539
|
-
- pattern: AST pattern to find
|
|
18540
|
-
- replacement: Replacement pattern
|
|
18541
|
-
- language: Programming language (defaults to TypeScript)`,
|
|
18542
|
-
args: {
|
|
18543
|
-
project_folder: tool.schema.string().describe("Path to the project folder"),
|
|
18544
|
-
pattern: tool.schema.string().describe("AST pattern to find"),
|
|
18545
|
-
replacement: tool.schema.string().describe("Replacement pattern"),
|
|
18546
|
-
language: tool.schema.string().optional().default("TypeScript").describe("Programming language")
|
|
18547
|
-
},
|
|
18548
|
-
async execute({ project_folder, pattern, replacement, language }) {
|
|
18549
|
-
await initAstGrep();
|
|
18550
|
-
if (!astGrepModule) {
|
|
18551
|
-
return JSON.stringify({
|
|
18552
|
-
success: false,
|
|
18553
|
-
error: "@ast-grep/napi not available",
|
|
18554
|
-
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18555
|
-
}, null, 2);
|
|
18556
|
-
}
|
|
18557
|
-
try {
|
|
18558
|
-
if (!fs5.existsSync(project_folder)) {
|
|
18559
|
-
return JSON.stringify({
|
|
18560
|
-
success: false,
|
|
18561
|
-
error: `Path not found: ${project_folder}`
|
|
18562
|
-
}, null, 2);
|
|
18563
|
-
}
|
|
18564
|
-
const Lang = astGrepModule.Lang;
|
|
18565
|
-
if (!Lang[language]) {
|
|
18566
|
-
return JSON.stringify({
|
|
18567
|
-
success: false,
|
|
18568
|
-
error: `Unsupported language: ${language}`
|
|
18569
|
-
}, null, 2);
|
|
18570
|
-
}
|
|
18571
|
-
return JSON.stringify({
|
|
18572
|
-
success: true,
|
|
18573
|
-
operation: "info",
|
|
18574
|
-
message: "Full rewrite requires @ast-grep/cli with config file",
|
|
18575
|
-
suggestion: "Use ast_grep_find_code to find matches, then hive_code_edit for individual replacements",
|
|
18576
|
-
parameters: {
|
|
18577
|
-
projectFolder: project_folder,
|
|
18578
|
-
pattern,
|
|
18579
|
-
replacement,
|
|
18580
|
-
language
|
|
18581
|
-
}
|
|
18582
|
-
}, null, 2);
|
|
18583
|
-
} catch (error45) {
|
|
18584
|
-
return JSON.stringify({
|
|
18585
|
-
success: false,
|
|
18586
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18587
|
-
}, null, 2);
|
|
18588
|
-
}
|
|
18589
|
-
}
|
|
18590
|
-
});
|
|
18591
|
-
var astGrepAnalyzeImportsTool = tool({
|
|
18592
|
-
description: `Analyze import statements and dependencies in your codebase.
|
|
18593
|
-
|
|
18594
|
-
Choose "usage" to see which imports are actually used (great for refactoring), or "discovery" to explore all imports and identifiers in the code (great for understanding structure).
|
|
18595
|
-
|
|
18596
|
-
**Parameters:**
|
|
18597
|
-
- mode: "usage" (default) shows where imports are used, "discovery" shows all imports
|
|
18598
|
-
- path: Specific directory or file to analyze (defaults to current directory)`,
|
|
18599
|
-
args: {
|
|
18600
|
-
mode: tool.schema.enum(["usage", "discovery"]).default("usage").describe("Analysis mode"),
|
|
18601
|
-
path: tool.schema.string().optional().describe("Directory or file to analyze")
|
|
18602
|
-
},
|
|
18603
|
-
async execute({ mode, path: path6 }) {
|
|
18604
|
-
await initAstGrep();
|
|
18605
|
-
if (!astGrepModule) {
|
|
18606
|
-
return JSON.stringify({
|
|
18607
|
-
success: false,
|
|
18608
|
-
error: "@ast-grep/napi not available"
|
|
18609
|
-
}, null, 2);
|
|
18610
|
-
}
|
|
18611
|
-
try {
|
|
18612
|
-
const analyzePath = path6 || process.cwd();
|
|
18613
|
-
if (!fs5.existsSync(analyzePath)) {
|
|
18614
|
-
return JSON.stringify({
|
|
18615
|
-
success: false,
|
|
18616
|
-
error: `Path not found: ${analyzePath}`
|
|
18617
|
-
}, null, 2);
|
|
18618
|
-
}
|
|
18619
|
-
const Lang = astGrepModule.Lang;
|
|
18620
|
-
const findInFiles = astGrepModule.findInFiles;
|
|
18621
|
-
const imports = {};
|
|
18622
|
-
await findInFiles(Lang.TypeScript, {
|
|
18623
|
-
paths: [analyzePath],
|
|
18624
|
-
matcher: { rule: { kind: "import_statement" } }
|
|
18625
|
-
}, (err, node) => {
|
|
18626
|
-
if (err || !node)
|
|
18627
|
-
return;
|
|
18628
|
-
const text = node.text();
|
|
18629
|
-
const match = text.match(/from ['"]([^'"]+)['"]/);
|
|
18630
|
-
if (match) {
|
|
18631
|
-
const module = match[1];
|
|
18632
|
-
const file2 = node.filename() || "unknown";
|
|
18633
|
-
if (!imports[module]) {
|
|
18634
|
-
imports[module] = [];
|
|
18635
|
-
}
|
|
18636
|
-
if (!imports[module].includes(file2)) {
|
|
18637
|
-
imports[module].push(file2);
|
|
18638
|
-
}
|
|
18639
|
-
}
|
|
18640
|
-
});
|
|
18641
|
-
if (mode === "usage") {
|
|
18642
|
-
return JSON.stringify({
|
|
18643
|
-
success: true,
|
|
18644
|
-
mode: "usage",
|
|
18645
|
-
imports: Object.entries(imports).map(([module, files]) => ({
|
|
18646
|
-
module,
|
|
18647
|
-
importCount: 1,
|
|
18648
|
-
filesCount: files.length
|
|
18649
|
-
})),
|
|
18650
|
-
note: "Full usage analysis requires @ast-grep/cli"
|
|
18651
|
-
}, null, 2);
|
|
18652
|
-
}
|
|
18653
|
-
return JSON.stringify({
|
|
18654
|
-
success: true,
|
|
18655
|
-
mode: "discovery",
|
|
18656
|
-
totalModules: Object.keys(imports).length,
|
|
18657
|
-
imports: Object.entries(imports).map(([module, files]) => ({
|
|
18658
|
-
module,
|
|
18659
|
-
importCount: files.length,
|
|
18660
|
-
files: files.slice(0, 5)
|
|
18661
|
-
}))
|
|
18662
|
-
}, null, 2);
|
|
18663
|
-
} catch (error45) {
|
|
18664
|
-
return JSON.stringify({
|
|
18665
|
-
success: false,
|
|
18666
|
-
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18667
|
-
}, null, 2);
|
|
18668
|
-
}
|
|
18669
|
-
}
|
|
18670
|
-
});
|
|
18671
|
-
|
|
18672
|
-
// src/tools/hive-doctor.ts
|
|
18673
|
-
import * as fs6 from "fs";
|
|
18674
|
-
import * as path6 from "path";
|
|
18675
|
-
async function checkPackage(packageName) {
|
|
18676
|
-
try {
|
|
18677
|
-
const packageJsonPath = __require.resolve(`${packageName}/package.json`, {
|
|
18678
|
-
paths: [
|
|
18679
|
-
process.cwd(),
|
|
18680
|
-
path6.join(process.cwd(), "node_modules"),
|
|
18681
|
-
path6.join(process.cwd(), "packages/opencode-hive/node_modules")
|
|
18682
|
-
]
|
|
18683
|
-
});
|
|
18684
|
-
if (fs6.existsSync(packageJsonPath)) {
|
|
18685
|
-
const pkg = JSON.parse(fs6.readFileSync(packageJsonPath, "utf-8"));
|
|
18686
|
-
return { installed: true, version: pkg.version };
|
|
18687
|
-
}
|
|
18688
|
-
} catch {}
|
|
18689
|
-
return { installed: false };
|
|
18690
17853
|
}
|
|
18691
17854
|
function checkOptimizations() {
|
|
18692
17855
|
const checks3 = [];
|
|
@@ -18696,9 +17859,9 @@ function checkOptimizations() {
|
|
|
18696
17859
|
];
|
|
18697
17860
|
let config2 = null;
|
|
18698
17861
|
for (const configPath of configPaths) {
|
|
18699
|
-
if (
|
|
17862
|
+
if (fs5.existsSync(configPath)) {
|
|
18700
17863
|
try {
|
|
18701
|
-
const content =
|
|
17864
|
+
const content = fs5.readFileSync(configPath, "utf-8");
|
|
18702
17865
|
config2 = JSON.parse(content.replace(/\\/g, ""));
|
|
18703
17866
|
break;
|
|
18704
17867
|
} catch {}
|
|
@@ -18729,26 +17892,30 @@ function checkOptimizations() {
|
|
|
18729
17892
|
recommendation: sandboxConfig === "none" ? "Enable Docker sandbox for isolated test environments" : undefined
|
|
18730
17893
|
});
|
|
18731
17894
|
const disabledMcps = config2?.disableMcps || [];
|
|
18732
|
-
const hasAstGrep = !disabledMcps.includes("ast_grep");
|
|
18733
|
-
checks3.push({
|
|
18734
|
-
name: "nativeAstGrep",
|
|
18735
|
-
enabled: hasAstGrep,
|
|
18736
|
-
recommendation: !hasAstGrep ? "Enable native ast-grep for fast AST analysis" : undefined
|
|
18737
|
-
});
|
|
18738
17895
|
const hasPareSearch = !disabledMcps.includes("pare_search");
|
|
18739
17896
|
checks3.push({
|
|
18740
17897
|
name: "pareSearch",
|
|
18741
17898
|
enabled: hasPareSearch,
|
|
18742
17899
|
recommendation: !hasPareSearch ? "Enable pare_search for structured ripgrep output (65-95% token reduction)" : undefined
|
|
18743
17900
|
});
|
|
17901
|
+
const hasVeil = !disabledMcps.includes("veil");
|
|
17902
|
+
checks3.push({
|
|
17903
|
+
name: "veil",
|
|
17904
|
+
enabled: hasVeil,
|
|
17905
|
+
recommendation: !hasVeil ? "Enable veil for code discovery and intelligent retrieval" : undefined
|
|
17906
|
+
});
|
|
18744
17907
|
return checks3;
|
|
18745
17908
|
}
|
|
18746
|
-
function generateRecommendations(dependencies, optimizations) {
|
|
17909
|
+
function generateRecommendations(dependencies, cliTools, optimizations) {
|
|
18747
17910
|
const recommendations = [];
|
|
18748
17911
|
const missingRequired = dependencies.filter((d) => d.required && !d.installed);
|
|
18749
17912
|
if (missingRequired.length > 0) {
|
|
18750
17913
|
recommendations.push(`Missing required packages: ${missingRequired.map((d) => d.name).join(", ")}`);
|
|
18751
17914
|
}
|
|
17915
|
+
const missingCliTools = cliTools.filter((t) => !t.installed);
|
|
17916
|
+
if (missingCliTools.length > 0) {
|
|
17917
|
+
recommendations.push(`⚠️ Missing CLI tools: ${missingCliTools.map((t) => t.name).join(", ")}`, `Install with: ${missingCliTools.map((t) => `npx -y ${t.command}`).join(" | ")}`);
|
|
17918
|
+
}
|
|
18752
17919
|
const disabledOptimizations = optimizations.filter((o) => !o.enabled && o.recommendation);
|
|
18753
17920
|
for (const opt of disabledOptimizations) {
|
|
18754
17921
|
if (opt.recommendation) {
|
|
@@ -18756,11 +17923,11 @@ function generateRecommendations(dependencies, optimizations) {
|
|
|
18756
17923
|
}
|
|
18757
17924
|
}
|
|
18758
17925
|
if (recommendations.length === 0) {
|
|
18759
|
-
recommendations.push("System is
|
|
17926
|
+
recommendations.push("✅ System is healthy! All checks passed.");
|
|
18760
17927
|
}
|
|
18761
17928
|
return recommendations;
|
|
18762
17929
|
}
|
|
18763
|
-
function generateQuickFixes(dependencies, optimizations) {
|
|
17930
|
+
function generateQuickFixes(dependencies, cliTools, optimizations) {
|
|
18764
17931
|
const fixes = [];
|
|
18765
17932
|
const missingPackages = dependencies.filter((d) => !d.installed && !d.required);
|
|
18766
17933
|
for (const pkg of missingPackages) {
|
|
@@ -18769,6 +17936,13 @@ function generateQuickFixes(dependencies, optimizations) {
|
|
|
18769
17936
|
description: `Install ${pkg.name}`
|
|
18770
17937
|
});
|
|
18771
17938
|
}
|
|
17939
|
+
const missingTools = cliTools.filter((t) => !t.installed);
|
|
17940
|
+
for (const tool3 of missingTools) {
|
|
17941
|
+
fixes.push({
|
|
17942
|
+
command: `npx -y ${tool3.command}`,
|
|
17943
|
+
description: `Install ${tool3.name} via npx`
|
|
17944
|
+
});
|
|
17945
|
+
}
|
|
18772
17946
|
if (optimizations.find((o) => o.name === "snip" && !o.enabled)) {
|
|
18773
17947
|
fixes.push({
|
|
18774
17948
|
command: 'Add to ~/.config/opencode/agent_hive.json: { "snip": { "enabled": true } }',
|
|
@@ -18783,13 +17957,14 @@ function generateQuickFixes(dependencies, optimizations) {
|
|
|
18783
17957
|
}
|
|
18784
17958
|
return fixes;
|
|
18785
17959
|
}
|
|
18786
|
-
function calculateStatus(dependencies, optimizations) {
|
|
17960
|
+
function calculateStatus(dependencies, cliTools, optimizations) {
|
|
18787
17961
|
const missingRequired = dependencies.filter((d) => d.required && !d.installed);
|
|
18788
17962
|
if (missingRequired.length > 0) {
|
|
18789
17963
|
return "issues";
|
|
18790
17964
|
}
|
|
17965
|
+
const missingTools = cliTools.filter((t) => !t.installed);
|
|
18791
17966
|
const disabledCount = optimizations.filter((o) => !o.enabled).length;
|
|
18792
|
-
if (disabledCount > 2) {
|
|
17967
|
+
if (missingTools.length > 0 || disabledCount > 2) {
|
|
18793
17968
|
return "warning";
|
|
18794
17969
|
}
|
|
18795
17970
|
return "healthy";
|
|
@@ -18799,8 +17974,9 @@ var hiveDoctorTool = tool({
|
|
|
18799
17974
|
|
|
18800
17975
|
**What it checks:**
|
|
18801
17976
|
1. Dependencies - Optional packages installed and working
|
|
18802
|
-
2.
|
|
18803
|
-
3.
|
|
17977
|
+
2. CLI Tools - dora, auto-cr, etc. available via npx
|
|
17978
|
+
3. Optimizations - Features enabled in config
|
|
17979
|
+
4. Recommendations - Suggestions for improvements
|
|
18804
17980
|
|
|
18805
17981
|
**Use when:**
|
|
18806
17982
|
- Setting up Hive for the first time
|
|
@@ -18810,27 +17986,55 @@ var hiveDoctorTool = tool({
|
|
|
18810
17986
|
|
|
18811
17987
|
**Example output:**
|
|
18812
17988
|
- healthy: All checks pass
|
|
18813
|
-
- warning: Some optimizations disabled
|
|
17989
|
+
- warning: Some optimizations disabled or CLI tools missing
|
|
18814
17990
|
- issues: Missing required packages`,
|
|
18815
17991
|
args: {},
|
|
18816
17992
|
async execute() {
|
|
18817
17993
|
const dependencyChecks = [
|
|
18818
17994
|
{ name: "agent-booster", package: "@sparkleideas/agent-booster", required: false },
|
|
18819
17995
|
{ name: "vector-memory", package: "@sparkleideas/memory", required: false },
|
|
18820
|
-
{ name: "ast-grep NAPI", package: "@ast-grep/napi", required: false },
|
|
18821
17996
|
{ name: "pare-search", package: "@paretools/search", required: false },
|
|
18822
17997
|
{ name: "context7", package: "@upstash/context7-mcp", required: false },
|
|
18823
17998
|
{ name: "Exa search", package: "exa-mcp-server", required: false }
|
|
18824
17999
|
];
|
|
18825
|
-
for (const dep of dependencyChecks) {
|
|
18826
|
-
const result2 = await checkPackage(dep.package);
|
|
18827
|
-
dep.installed = result2.installed;
|
|
18828
|
-
dep.version = result2.version;
|
|
18000
|
+
for (const dep of dependencyChecks) {
|
|
18001
|
+
const result2 = await checkPackage(dep.package);
|
|
18002
|
+
dep.installed = result2.installed;
|
|
18003
|
+
dep.version = result2.version;
|
|
18004
|
+
}
|
|
18005
|
+
const cliToolChecks = [
|
|
18006
|
+
{
|
|
18007
|
+
name: "dora",
|
|
18008
|
+
command: "@butttons/dora",
|
|
18009
|
+
description: "SCIP-based code navigation",
|
|
18010
|
+
installCommand: "npx -y @butttons/dora"
|
|
18011
|
+
},
|
|
18012
|
+
{
|
|
18013
|
+
name: "auto-cr",
|
|
18014
|
+
command: "auto-cr-cmd",
|
|
18015
|
+
description: "SWC-based automated code review",
|
|
18016
|
+
installCommand: "npx -y auto-cr-cmd"
|
|
18017
|
+
},
|
|
18018
|
+
{
|
|
18019
|
+
name: "veil",
|
|
18020
|
+
command: "@ushiradineth/veil",
|
|
18021
|
+
description: "Code discovery and retrieval",
|
|
18022
|
+
installCommand: "npx -y @ushiradineth/veil"
|
|
18023
|
+
},
|
|
18024
|
+
{
|
|
18025
|
+
name: "scip-typescript",
|
|
18026
|
+
command: "@sourcegraph/scip-typescript",
|
|
18027
|
+
description: "TypeScript SCIP indexer (for dora)",
|
|
18028
|
+
installCommand: "npx -y @sourcegraph/scip-typescript"
|
|
18029
|
+
}
|
|
18030
|
+
];
|
|
18031
|
+
for (const tool3 of cliToolChecks) {
|
|
18032
|
+
checkCliTool(tool3);
|
|
18829
18033
|
}
|
|
18830
18034
|
const optimizationChecks = checkOptimizations();
|
|
18831
|
-
const recommendations = generateRecommendations(dependencyChecks, optimizationChecks);
|
|
18832
|
-
const quickFixes = generateQuickFixes(dependencyChecks, optimizationChecks);
|
|
18833
|
-
const status = calculateStatus(dependencyChecks, optimizationChecks);
|
|
18035
|
+
const recommendations = generateRecommendations(dependencyChecks, cliToolChecks, optimizationChecks);
|
|
18036
|
+
const quickFixes = generateQuickFixes(dependencyChecks, cliToolChecks, optimizationChecks);
|
|
18037
|
+
const status = calculateStatus(dependencyChecks, cliToolChecks, optimizationChecks);
|
|
18834
18038
|
const result = {
|
|
18835
18039
|
status,
|
|
18836
18040
|
timestamp: new Date().toISOString(),
|
|
@@ -18840,6 +18044,12 @@ var hiveDoctorTool = tool({
|
|
|
18840
18044
|
installed: dependencyChecks.filter((d) => d.installed).length,
|
|
18841
18045
|
packages: dependencyChecks
|
|
18842
18046
|
},
|
|
18047
|
+
cliTools: {
|
|
18048
|
+
total: cliToolChecks.length,
|
|
18049
|
+
available: cliToolChecks.filter((t) => t.installed).length,
|
|
18050
|
+
tools: cliToolChecks,
|
|
18051
|
+
missing: cliToolChecks.filter((t) => !t.installed).map((t) => t.name)
|
|
18052
|
+
},
|
|
18843
18053
|
optimizations: {
|
|
18844
18054
|
total: optimizationChecks.length,
|
|
18845
18055
|
enabled: optimizationChecks.filter((o) => o.enabled).length,
|
|
@@ -18857,12 +18067,11 @@ var hiveDoctorQuickTool = tool({
|
|
|
18857
18067
|
|
|
18858
18068
|
**Returns:**
|
|
18859
18069
|
- healthy: All systems go
|
|
18860
|
-
- warning: Some optimizations disabled
|
|
18070
|
+
- warning: Some CLI tools missing or optimizations disabled
|
|
18861
18071
|
- issues: Action required`,
|
|
18862
18072
|
args: {},
|
|
18863
18073
|
async execute() {
|
|
18864
18074
|
const keyPackages = [
|
|
18865
|
-
"@ast-grep/napi",
|
|
18866
18075
|
"@sparkleideas/agent-booster",
|
|
18867
18076
|
"@paretools/search"
|
|
18868
18077
|
];
|
|
@@ -18878,494 +18087,955 @@ var hiveDoctorQuickTool = tool({
|
|
|
18878
18087
|
return JSON.stringify({
|
|
18879
18088
|
status: healthy ? "healthy" : "warning",
|
|
18880
18089
|
packages: results,
|
|
18881
|
-
runFullCheck: "Use hive_doctor for detailed analysis"
|
|
18090
|
+
runFullCheck: "Use hive_doctor for detailed analysis with CLI tool checks"
|
|
18882
18091
|
}, null, 2);
|
|
18883
18092
|
}
|
|
18884
18093
|
});
|
|
18885
18094
|
|
|
18886
18095
|
// src/tools/dora.ts
|
|
18887
|
-
import { execSync as
|
|
18096
|
+
import { execSync as execSync3 } from "child_process";
|
|
18888
18097
|
function checkDoraStatus() {
|
|
18889
18098
|
try {
|
|
18890
|
-
const output =
|
|
18099
|
+
const output = execSync3("dora --version", { encoding: "utf-8" });
|
|
18100
|
+
const version2 = output.trim();
|
|
18101
|
+
const indexExists = __require("fs").existsSync(".dora/dora.db");
|
|
18102
|
+
return { installed: true, version: version2, indexed: indexExists };
|
|
18103
|
+
} catch {
|
|
18104
|
+
return { installed: false, indexed: false };
|
|
18105
|
+
}
|
|
18106
|
+
}
|
|
18107
|
+
function runDoraCommand(args2) {
|
|
18108
|
+
try {
|
|
18109
|
+
const output = execSync3(`dora ${args2.join(" ")}`, {
|
|
18110
|
+
encoding: "utf-8",
|
|
18111
|
+
maxBuffer: 10 * 1024 * 1024
|
|
18112
|
+
});
|
|
18113
|
+
return { success: true, output };
|
|
18114
|
+
} catch (error45) {
|
|
18115
|
+
return { success: false, error: error45.message || "Command failed" };
|
|
18116
|
+
}
|
|
18117
|
+
}
|
|
18118
|
+
var doraStatusTool = tool({
|
|
18119
|
+
description: `Check dora installation status and index state.
|
|
18120
|
+
|
|
18121
|
+
**Returns:**
|
|
18122
|
+
- installed: Whether dora CLI is available
|
|
18123
|
+
- version: Dora version
|
|
18124
|
+
- indexed: Whether codebase has been indexed
|
|
18125
|
+
|
|
18126
|
+
**Requirements:**
|
|
18127
|
+
- Install dora: \`bun install -g @butttons/dora\`
|
|
18128
|
+
- Install SCIP indexer: \`npm install -g @sourcegraph/scip-typescript\`
|
|
18129
|
+
- Initialize: \`dora init && dora index\`
|
|
18130
|
+
|
|
18131
|
+
**Note:** Indexing is required once per codebase. After that, dora works instantly.`,
|
|
18132
|
+
args: {},
|
|
18133
|
+
async execute() {
|
|
18134
|
+
const status = checkDoraStatus();
|
|
18135
|
+
if (!status.installed) {
|
|
18136
|
+
return JSON.stringify({
|
|
18137
|
+
status: "not_installed",
|
|
18138
|
+
message: "Dora CLI not found",
|
|
18139
|
+
installation: {
|
|
18140
|
+
step1: "bun install -g @butttons/dora",
|
|
18141
|
+
step2: "npm install -g @sourcegraph/scip-typescript",
|
|
18142
|
+
step3: "dora init && dora index"
|
|
18143
|
+
}
|
|
18144
|
+
}, null, 2);
|
|
18145
|
+
}
|
|
18146
|
+
if (!status.indexed) {
|
|
18147
|
+
return JSON.stringify({
|
|
18148
|
+
status: "not_indexed",
|
|
18149
|
+
version: status.version,
|
|
18150
|
+
message: "Codebase not indexed",
|
|
18151
|
+
nextStep: "Run: dora init && dora index"
|
|
18152
|
+
}, null, 2);
|
|
18153
|
+
}
|
|
18154
|
+
return JSON.stringify({
|
|
18155
|
+
status: "ready",
|
|
18156
|
+
version: status.version,
|
|
18157
|
+
indexed: true,
|
|
18158
|
+
message: "Dora is ready"
|
|
18159
|
+
}, null, 2);
|
|
18160
|
+
}
|
|
18161
|
+
});
|
|
18162
|
+
var doraSymbolTool = tool({
|
|
18163
|
+
description: `Find symbol definitions using dora (SCIP-based).
|
|
18164
|
+
|
|
18165
|
+
**Parameters:**
|
|
18166
|
+
- name: Symbol name to search for
|
|
18167
|
+
- kind: Filter by symbol kind (function, class, method, etc.)
|
|
18168
|
+
|
|
18169
|
+
**Example:**
|
|
18170
|
+
\`\`\`
|
|
18171
|
+
dora_symbol({ name: "getUserById" })
|
|
18172
|
+
\`\`\`
|
|
18173
|
+
|
|
18174
|
+
**Note:** Requires dora to be installed and indexed.`,
|
|
18175
|
+
args: {
|
|
18176
|
+
name: tool.schema.string().describe("Symbol name to search for"),
|
|
18177
|
+
kind: tool.schema.string().optional().describe("Filter by symbol kind (function, class, method, etc.)")
|
|
18178
|
+
},
|
|
18179
|
+
async execute({ name, kind }) {
|
|
18180
|
+
const status = checkDoraStatus();
|
|
18181
|
+
if (!status.installed || !status.indexed) {
|
|
18182
|
+
return JSON.stringify({
|
|
18183
|
+
success: false,
|
|
18184
|
+
error: "Dora not ready. Run dora_status first.",
|
|
18185
|
+
hint: "Install and index: dora init && dora index"
|
|
18186
|
+
}, null, 2);
|
|
18187
|
+
}
|
|
18188
|
+
const args2 = ["symbol", name];
|
|
18189
|
+
if (kind) {
|
|
18190
|
+
args2.push("--kind", kind);
|
|
18191
|
+
}
|
|
18192
|
+
const result = runDoraCommand(args2);
|
|
18193
|
+
if (!result.success) {
|
|
18194
|
+
return JSON.stringify({
|
|
18195
|
+
success: false,
|
|
18196
|
+
error: result.error,
|
|
18197
|
+
hint: "Symbol may not exist or not indexed"
|
|
18198
|
+
}, null, 2);
|
|
18199
|
+
}
|
|
18200
|
+
return JSON.stringify({
|
|
18201
|
+
success: true,
|
|
18202
|
+
symbol: name,
|
|
18203
|
+
output: result.output
|
|
18204
|
+
}, null, 2);
|
|
18205
|
+
}
|
|
18206
|
+
});
|
|
18207
|
+
var doraFileTool = tool({
|
|
18208
|
+
description: `Get file dependencies and information using dora.
|
|
18209
|
+
|
|
18210
|
+
**Parameters:**
|
|
18211
|
+
- path: File path to analyze
|
|
18212
|
+
|
|
18213
|
+
**Example:**
|
|
18214
|
+
\`\`\`
|
|
18215
|
+
dora_file({ path: "src/index.ts" })
|
|
18216
|
+
\`\`\`
|
|
18217
|
+
|
|
18218
|
+
**Returns:** File metadata, exports, and dependencies.`,
|
|
18219
|
+
args: {
|
|
18220
|
+
path: tool.schema.string().describe("File path to analyze")
|
|
18221
|
+
},
|
|
18222
|
+
async execute({ path: path7 }) {
|
|
18223
|
+
const status = checkDoraStatus();
|
|
18224
|
+
if (!status.installed || !status.indexed) {
|
|
18225
|
+
return JSON.stringify({
|
|
18226
|
+
success: false,
|
|
18227
|
+
error: "Dora not ready. Run dora_status first."
|
|
18228
|
+
}, null, 2);
|
|
18229
|
+
}
|
|
18230
|
+
const result = runDoraCommand(["file", path7]);
|
|
18231
|
+
if (!result.success) {
|
|
18232
|
+
return JSON.stringify({
|
|
18233
|
+
success: false,
|
|
18234
|
+
error: result.error,
|
|
18235
|
+
hint: "File may not exist or not indexed"
|
|
18236
|
+
}, null, 2);
|
|
18237
|
+
}
|
|
18238
|
+
return JSON.stringify({
|
|
18239
|
+
success: true,
|
|
18240
|
+
path: path7,
|
|
18241
|
+
output: result.output
|
|
18242
|
+
}, null, 2);
|
|
18243
|
+
}
|
|
18244
|
+
});
|
|
18245
|
+
var doraReferencesTool = tool({
|
|
18246
|
+
description: `Find all references to a symbol using dora.
|
|
18247
|
+
|
|
18248
|
+
**Parameters:**
|
|
18249
|
+
- name: Symbol name to find references for
|
|
18250
|
+
|
|
18251
|
+
**Example:**
|
|
18252
|
+
\`\`\`
|
|
18253
|
+
dora_references({ name: "UserService" })
|
|
18254
|
+
\`\`\`
|
|
18255
|
+
|
|
18256
|
+
**Note:** Returns all usages across the codebase.`,
|
|
18257
|
+
args: {
|
|
18258
|
+
name: tool.schema.string().describe("Symbol name to find references for")
|
|
18259
|
+
},
|
|
18260
|
+
async execute({ name }) {
|
|
18261
|
+
const status = checkDoraStatus();
|
|
18262
|
+
if (!status.installed || !status.indexed) {
|
|
18263
|
+
return JSON.stringify({
|
|
18264
|
+
success: false,
|
|
18265
|
+
error: "Dora not ready. Run dora_status first."
|
|
18266
|
+
}, null, 2);
|
|
18267
|
+
}
|
|
18268
|
+
const result = runDoraCommand(["references", name]);
|
|
18269
|
+
if (!result.success) {
|
|
18270
|
+
return JSON.stringify({
|
|
18271
|
+
success: false,
|
|
18272
|
+
error: result.error
|
|
18273
|
+
}, null, 2);
|
|
18274
|
+
}
|
|
18275
|
+
return JSON.stringify({
|
|
18276
|
+
success: true,
|
|
18277
|
+
symbol: name,
|
|
18278
|
+
output: result.output
|
|
18279
|
+
}, null, 2);
|
|
18280
|
+
}
|
|
18281
|
+
});
|
|
18282
|
+
var doraCyclesTool = tool({
|
|
18283
|
+
description: `Detect circular dependencies in the codebase using dora.
|
|
18284
|
+
|
|
18285
|
+
**Example:**
|
|
18286
|
+
\`\`\`
|
|
18287
|
+
dora_cycles()
|
|
18288
|
+
\`\`\`
|
|
18289
|
+
|
|
18290
|
+
**Returns:** List of circular dependency paths if found.`,
|
|
18291
|
+
args: {},
|
|
18292
|
+
async execute() {
|
|
18293
|
+
const status = checkDoraStatus();
|
|
18294
|
+
if (!status.installed || !status.indexed) {
|
|
18295
|
+
return JSON.stringify({
|
|
18296
|
+
success: false,
|
|
18297
|
+
error: "Dora not ready. Run dora_status first."
|
|
18298
|
+
}, null, 2);
|
|
18299
|
+
}
|
|
18300
|
+
const result = runDoraCommand(["cycles"]);
|
|
18301
|
+
if (!result.success) {
|
|
18302
|
+
return JSON.stringify({
|
|
18303
|
+
success: false,
|
|
18304
|
+
error: result.error
|
|
18305
|
+
}, null, 2);
|
|
18306
|
+
}
|
|
18307
|
+
return JSON.stringify({
|
|
18308
|
+
success: true,
|
|
18309
|
+
cycles: result.output
|
|
18310
|
+
}, null, 2);
|
|
18311
|
+
}
|
|
18312
|
+
});
|
|
18313
|
+
var doraUnusedTool = tool({
|
|
18314
|
+
description: `Find unused/dead code in the codebase using dora.
|
|
18315
|
+
|
|
18316
|
+
**Example:**
|
|
18317
|
+
\`\`\`
|
|
18318
|
+
dora_unused()
|
|
18319
|
+
\`\`\`
|
|
18320
|
+
|
|
18321
|
+
**Returns:** List of symbols with zero references.`,
|
|
18322
|
+
args: {},
|
|
18323
|
+
async execute() {
|
|
18324
|
+
const status = checkDoraStatus();
|
|
18325
|
+
if (!status.installed || !status.indexed) {
|
|
18326
|
+
return JSON.stringify({
|
|
18327
|
+
success: false,
|
|
18328
|
+
error: "Dora not ready. Run dora_status first."
|
|
18329
|
+
}, null, 2);
|
|
18330
|
+
}
|
|
18331
|
+
const result = runDoraCommand(["unused"]);
|
|
18332
|
+
if (!result.success) {
|
|
18333
|
+
return JSON.stringify({
|
|
18334
|
+
success: false,
|
|
18335
|
+
error: result.error
|
|
18336
|
+
}, null, 2);
|
|
18337
|
+
}
|
|
18338
|
+
return JSON.stringify({
|
|
18339
|
+
success: true,
|
|
18340
|
+
unused: result.output
|
|
18341
|
+
}, null, 2);
|
|
18342
|
+
}
|
|
18343
|
+
});
|
|
18344
|
+
|
|
18345
|
+
// src/tools/auto-cr.ts
|
|
18346
|
+
import { execSync as execSync4 } from "child_process";
|
|
18347
|
+
import * as fs6 from "fs";
|
|
18348
|
+
function checkAutoCrStatus() {
|
|
18349
|
+
try {
|
|
18350
|
+
const output = execSync4("auto-cr-cmd --version", { encoding: "utf-8" });
|
|
18891
18351
|
const version2 = output.trim();
|
|
18892
|
-
|
|
18893
|
-
return { installed: true, version: version2, indexed: indexExists };
|
|
18352
|
+
return { installed: true, version: version2 };
|
|
18894
18353
|
} catch {
|
|
18895
|
-
return { installed: false
|
|
18354
|
+
return { installed: false };
|
|
18896
18355
|
}
|
|
18897
18356
|
}
|
|
18898
|
-
function
|
|
18357
|
+
function runAutoCr(args2) {
|
|
18899
18358
|
try {
|
|
18900
|
-
const
|
|
18359
|
+
const allArgs = [...args2, "--output", "json"];
|
|
18360
|
+
const output = execSync4(`auto-cr-cmd ${allArgs.join(" ")}`, {
|
|
18901
18361
|
encoding: "utf-8",
|
|
18902
|
-
maxBuffer:
|
|
18362
|
+
maxBuffer: 50 * 1024 * 1024
|
|
18903
18363
|
});
|
|
18904
|
-
|
|
18364
|
+
try {
|
|
18365
|
+
const json2 = JSON.parse(output);
|
|
18366
|
+
return { success: true, output, json: json2 };
|
|
18367
|
+
} catch {
|
|
18368
|
+
return { success: true, output };
|
|
18369
|
+
}
|
|
18905
18370
|
} catch (error45) {
|
|
18906
|
-
|
|
18371
|
+
const stderr = error45.stderr || "";
|
|
18372
|
+
const stdout = error45.stdout || "";
|
|
18373
|
+
const combined = stdout + stderr;
|
|
18374
|
+
try {
|
|
18375
|
+
const json2 = JSON.parse(combined);
|
|
18376
|
+
return { success: true, output: combined, json: json2 };
|
|
18377
|
+
} catch {
|
|
18378
|
+
return { success: false, error: combined || error45.message };
|
|
18379
|
+
}
|
|
18907
18380
|
}
|
|
18908
18381
|
}
|
|
18909
|
-
var
|
|
18910
|
-
description: `Check
|
|
18382
|
+
var autoCrStatusTool = tool({
|
|
18383
|
+
description: `Check auto-cr-cmd installation status.
|
|
18911
18384
|
|
|
18912
18385
|
**Returns:**
|
|
18913
|
-
- installed: Whether
|
|
18914
|
-
- version:
|
|
18915
|
-
-
|
|
18916
|
-
|
|
18917
|
-
**Requirements:**
|
|
18918
|
-
- Install dora: \`bun install -g @butttons/dora\`
|
|
18919
|
-
- Install SCIP indexer: \`npm install -g @sourcegraph/scip-typescript\`
|
|
18920
|
-
- Initialize: \`dora init && dora index\`
|
|
18386
|
+
- installed: Whether auto-cr-cmd is available
|
|
18387
|
+
- version: Auto-CR version
|
|
18388
|
+
- ready: Whether it's ready to scan
|
|
18921
18389
|
|
|
18922
|
-
**
|
|
18390
|
+
**Installation:**
|
|
18391
|
+
\`\`\`bash
|
|
18392
|
+
npm install auto-cr-cmd
|
|
18393
|
+
# or
|
|
18394
|
+
pnpm add auto-cr-cmd
|
|
18395
|
+
\`\`\``,
|
|
18923
18396
|
args: {},
|
|
18924
18397
|
async execute() {
|
|
18925
|
-
const status =
|
|
18398
|
+
const status = checkAutoCrStatus();
|
|
18926
18399
|
if (!status.installed) {
|
|
18927
18400
|
return JSON.stringify({
|
|
18928
18401
|
status: "not_installed",
|
|
18929
|
-
message: "
|
|
18930
|
-
installation:
|
|
18931
|
-
step1: "bun install -g @butttons/dora",
|
|
18932
|
-
step2: "npm install -g @sourcegraph/scip-typescript",
|
|
18933
|
-
step3: "dora init && dora index"
|
|
18934
|
-
}
|
|
18402
|
+
message: "auto-cr-cmd not found",
|
|
18403
|
+
installation: "npm install auto-cr-cmd"
|
|
18935
18404
|
}, null, 2);
|
|
18936
18405
|
}
|
|
18937
|
-
|
|
18406
|
+
return JSON.stringify({
|
|
18407
|
+
status: "ready",
|
|
18408
|
+
version: status.version,
|
|
18409
|
+
message: "Auto-CR is ready to scan",
|
|
18410
|
+
rules: [
|
|
18411
|
+
"no-deep-relative-imports",
|
|
18412
|
+
"no-circular-dependencies",
|
|
18413
|
+
"no-swallowed-errors",
|
|
18414
|
+
"no-catastrophic-regex",
|
|
18415
|
+
"no-deep-clone-in-loop",
|
|
18416
|
+
"no-n2-array-lookup"
|
|
18417
|
+
]
|
|
18418
|
+
}, null, 2);
|
|
18419
|
+
}
|
|
18420
|
+
});
|
|
18421
|
+
var autoCrScanTool = tool({
|
|
18422
|
+
description: `Scan directory for code issues using auto-cr (SWC-based static analysis).
|
|
18423
|
+
|
|
18424
|
+
**Parameters:**
|
|
18425
|
+
- path: Directory path to scan (defaults to ./src)
|
|
18426
|
+
- language: Output language (en/zh, defaults to en)
|
|
18427
|
+
|
|
18428
|
+
**Rules detected:**
|
|
18429
|
+
- no-deep-relative-imports: Import paths exceeding depth limit
|
|
18430
|
+
- no-circular-dependencies: Circular module dependencies
|
|
18431
|
+
- no-swallowed-errors: try-catch blocks that swallow errors
|
|
18432
|
+
- no-catastrophic-regex: Potentially catastrophic regex patterns
|
|
18433
|
+
- no-deep-clone-in-loop: Performance anti-patterns
|
|
18434
|
+
- no-n2-array-lookup: O(n²) array operations
|
|
18435
|
+
|
|
18436
|
+
**Example:**
|
|
18437
|
+
\`\`\`
|
|
18438
|
+
auto_cr_scan({ path: "./src" })
|
|
18439
|
+
\`\`\``,
|
|
18440
|
+
args: {
|
|
18441
|
+
path: tool.schema.string().optional().default("./src").describe("Directory path to scan"),
|
|
18442
|
+
language: tool.schema.string().optional().default("en").describe("Output language (en or zh)")
|
|
18443
|
+
},
|
|
18444
|
+
async execute({ path: path7, language }) {
|
|
18445
|
+
const status = checkAutoCrStatus();
|
|
18446
|
+
if (!status.installed) {
|
|
18938
18447
|
return JSON.stringify({
|
|
18939
|
-
|
|
18940
|
-
|
|
18941
|
-
|
|
18942
|
-
|
|
18448
|
+
success: false,
|
|
18449
|
+
error: "auto-cr-cmd not installed",
|
|
18450
|
+
hint: "npm install auto-cr-cmd"
|
|
18451
|
+
}, null, 2);
|
|
18452
|
+
}
|
|
18453
|
+
if (!fs6.existsSync(path7)) {
|
|
18454
|
+
return JSON.stringify({
|
|
18455
|
+
success: false,
|
|
18456
|
+
error: `Path not found: ${path7}`
|
|
18457
|
+
}, null, 2);
|
|
18458
|
+
}
|
|
18459
|
+
const result = runAutoCr(["--language", language, path7]);
|
|
18460
|
+
if (!result.success && !result.json) {
|
|
18461
|
+
return JSON.stringify({
|
|
18462
|
+
success: false,
|
|
18463
|
+
error: result.error || "Scan failed"
|
|
18464
|
+
}, null, 2);
|
|
18465
|
+
}
|
|
18466
|
+
if (result.json) {
|
|
18467
|
+
const { summary, files, notifications } = result.json;
|
|
18468
|
+
return JSON.stringify({
|
|
18469
|
+
success: true,
|
|
18470
|
+
scanned: path7,
|
|
18471
|
+
summary: {
|
|
18472
|
+
filesScanned: summary?.scannedFiles || 0,
|
|
18473
|
+
filesWithErrors: summary?.filesWithErrors || 0,
|
|
18474
|
+
filesWithWarnings: summary?.filesWithWarnings || 0,
|
|
18475
|
+
totalViolations: summary?.violationTotals?.total || 0
|
|
18476
|
+
},
|
|
18477
|
+
files: files?.map((f) => ({
|
|
18478
|
+
path: f.filePath,
|
|
18479
|
+
violations: f.totalViolations,
|
|
18480
|
+
errors: f.severityCounts?.error || 0,
|
|
18481
|
+
warnings: f.severityCounts?.warning || 0,
|
|
18482
|
+
details: f.violations?.map((v) => ({
|
|
18483
|
+
rule: v.ruleName,
|
|
18484
|
+
severity: v.severity,
|
|
18485
|
+
message: v.message,
|
|
18486
|
+
line: v.line
|
|
18487
|
+
}))
|
|
18488
|
+
})),
|
|
18489
|
+
notifications: notifications || []
|
|
18943
18490
|
}, null, 2);
|
|
18944
18491
|
}
|
|
18945
18492
|
return JSON.stringify({
|
|
18946
|
-
|
|
18947
|
-
|
|
18948
|
-
|
|
18949
|
-
message: "Dora is ready"
|
|
18493
|
+
success: true,
|
|
18494
|
+
scanned: path7,
|
|
18495
|
+
rawOutput: result.output
|
|
18950
18496
|
}, null, 2);
|
|
18951
18497
|
}
|
|
18952
18498
|
});
|
|
18953
|
-
var
|
|
18954
|
-
description: `
|
|
18499
|
+
var autoCrDiffTool = tool({
|
|
18500
|
+
description: `Scan git diff output for code issues using auto-cr.
|
|
18501
|
+
|
|
18502
|
+
**Use case:** Run in CI to check only changed files.
|
|
18503
|
+
|
|
18504
|
+
**Example:**
|
|
18505
|
+
\`\`\`bash
|
|
18506
|
+
git diff --name-only -z | xargs -0 auto-cr-cmd --stdin --output json
|
|
18507
|
+
\`\`\`
|
|
18508
|
+
|
|
18509
|
+
**Note:** This tool requires git diff output piped via stdin.`,
|
|
18510
|
+
args: {
|
|
18511
|
+
language: tool.schema.string().optional().default("en").describe("Output language (en or zh)")
|
|
18512
|
+
},
|
|
18513
|
+
async execute({ language }) {
|
|
18514
|
+
const status = checkAutoCrStatus();
|
|
18515
|
+
if (!status.installed) {
|
|
18516
|
+
return JSON.stringify({
|
|
18517
|
+
success: false,
|
|
18518
|
+
error: "auto-cr-cmd not installed",
|
|
18519
|
+
hint: "npm install auto-cr-cmd"
|
|
18520
|
+
}, null, 2);
|
|
18521
|
+
}
|
|
18522
|
+
return JSON.stringify({
|
|
18523
|
+
success: true,
|
|
18524
|
+
message: "Use git diff with auto-cr directly",
|
|
18525
|
+
example: "git diff --name-only -z | xargs -0 npx auto-cr-cmd --stdin --output json"
|
|
18526
|
+
}, null, 2);
|
|
18527
|
+
}
|
|
18528
|
+
});
|
|
18529
|
+
var autoCrRulesTool = tool({
|
|
18530
|
+
description: `List available auto-cr rules and their descriptions.
|
|
18531
|
+
|
|
18532
|
+
**Returns:** All built-in rules with descriptions.`,
|
|
18533
|
+
args: {},
|
|
18534
|
+
async execute() {
|
|
18535
|
+
const rules = [
|
|
18536
|
+
{
|
|
18537
|
+
name: "no-deep-relative-imports",
|
|
18538
|
+
severity: "error",
|
|
18539
|
+
description: "Import paths should not exceed maximum depth",
|
|
18540
|
+
example: "Use path aliases (@shared/utils) instead of ../../../../shared/utils"
|
|
18541
|
+
},
|
|
18542
|
+
{
|
|
18543
|
+
name: "no-circular-dependencies",
|
|
18544
|
+
severity: "warning",
|
|
18545
|
+
description: "Detect circular module dependencies",
|
|
18546
|
+
example: "A imports B, B imports A creates a cycle"
|
|
18547
|
+
},
|
|
18548
|
+
{
|
|
18549
|
+
name: "no-swallowed-errors",
|
|
18550
|
+
severity: "warning",
|
|
18551
|
+
description: "try-catch blocks that swallow errors without rethrowing",
|
|
18552
|
+
example: "catch (e) {} without logging or rethrowing"
|
|
18553
|
+
},
|
|
18554
|
+
{
|
|
18555
|
+
name: "no-catastrophic-regex",
|
|
18556
|
+
severity: "error",
|
|
18557
|
+
description: "Potentially catastrophic regex backtracking",
|
|
18558
|
+
example: "Regex with nested quantifiers that can hang"
|
|
18559
|
+
},
|
|
18560
|
+
{
|
|
18561
|
+
name: "no-deep-clone-in-loop",
|
|
18562
|
+
severity: "warning",
|
|
18563
|
+
description: "Performance: deep clone operations inside loops",
|
|
18564
|
+
example: "for loop calling JSON.parse(JSON.stringify())"
|
|
18565
|
+
},
|
|
18566
|
+
{
|
|
18567
|
+
name: "no-n2-array-lookup",
|
|
18568
|
+
severity: "warning",
|
|
18569
|
+
description: "O(n²) array operations",
|
|
18570
|
+
example: "Nested for loops accessing array elements"
|
|
18571
|
+
}
|
|
18572
|
+
];
|
|
18573
|
+
return JSON.stringify({
|
|
18574
|
+
success: true,
|
|
18575
|
+
rules,
|
|
18576
|
+
totalRules: rules.length
|
|
18577
|
+
}, null, 2);
|
|
18578
|
+
}
|
|
18579
|
+
});
|
|
18580
|
+
|
|
18581
|
+
// src/tools/ast-grep-native.ts
|
|
18582
|
+
import * as fs7 from "fs";
|
|
18583
|
+
var astGrepModule = null;
|
|
18584
|
+
var astGrepInitPromise = null;
|
|
18585
|
+
async function initAstGrep() {
|
|
18586
|
+
if (astGrepModule !== null) {
|
|
18587
|
+
return;
|
|
18588
|
+
}
|
|
18589
|
+
if (astGrepInitPromise !== null) {
|
|
18590
|
+
await astGrepInitPromise;
|
|
18591
|
+
return;
|
|
18592
|
+
}
|
|
18593
|
+
astGrepInitPromise = (async () => {
|
|
18594
|
+
try {
|
|
18595
|
+
astGrepModule = await import("@ast-grep/napi");
|
|
18596
|
+
console.log("[ast-grep] Native NAPI initialized successfully");
|
|
18597
|
+
} catch (error45) {
|
|
18598
|
+
console.warn("[ast-grep] Failed to load @ast-grep/napi:", error45 instanceof Error ? error45.message : error45);
|
|
18599
|
+
astGrepModule = null;
|
|
18600
|
+
}
|
|
18601
|
+
})();
|
|
18602
|
+
await astGrepInitPromise;
|
|
18603
|
+
}
|
|
18604
|
+
var astGrepDumpSyntaxTreeTool = tool({
|
|
18605
|
+
description: `Dump code's syntax structure or dump a query's pattern structure.
|
|
18955
18606
|
|
|
18956
|
-
|
|
18957
|
-
- name: Symbol name to search for
|
|
18958
|
-
- kind: Filter by symbol kind (function, class, method, etc.)
|
|
18607
|
+
This is useful to discover correct syntax kind and syntax tree structure. Call it when debugging a rule.
|
|
18959
18608
|
|
|
18960
|
-
**
|
|
18961
|
-
|
|
18962
|
-
|
|
18963
|
-
|
|
18609
|
+
**Parameters:**
|
|
18610
|
+
- code: The code you need
|
|
18611
|
+
- language: Programming language (typescript, javascript, python, rust, go, java, etc.)
|
|
18612
|
+
- format: Output format - 'cst' (concrete syntax tree) or 'pattern' (to inspect rule patterns)
|
|
18964
18613
|
|
|
18965
|
-
**
|
|
18614
|
+
**Use when:**
|
|
18615
|
+
- Debugging AST patterns
|
|
18616
|
+
- Finding correct syntax kind names
|
|
18617
|
+
- Understanding code structure`,
|
|
18966
18618
|
args: {
|
|
18967
|
-
|
|
18968
|
-
|
|
18619
|
+
code: tool.schema.string().describe("The code to analyze"),
|
|
18620
|
+
language: tool.schema.string().describe("Programming language (typescript, javascript, python, rust, go, java, etc.)"),
|
|
18621
|
+
format: tool.schema.enum(["cst", "pattern"]).default("cst").describe("Output format")
|
|
18969
18622
|
},
|
|
18970
|
-
async execute({
|
|
18971
|
-
|
|
18972
|
-
if (!
|
|
18623
|
+
async execute({ code, language, format }) {
|
|
18624
|
+
await initAstGrep();
|
|
18625
|
+
if (!astGrepModule) {
|
|
18973
18626
|
return JSON.stringify({
|
|
18974
18627
|
success: false,
|
|
18975
|
-
error: "
|
|
18976
|
-
hint: "Install
|
|
18628
|
+
error: "@ast-grep/napi not available",
|
|
18629
|
+
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
18977
18630
|
}, null, 2);
|
|
18978
18631
|
}
|
|
18979
|
-
|
|
18980
|
-
|
|
18981
|
-
|
|
18982
|
-
|
|
18983
|
-
|
|
18984
|
-
|
|
18632
|
+
try {
|
|
18633
|
+
const langMap = {
|
|
18634
|
+
typescript: "TypeScript",
|
|
18635
|
+
javascript: "JavaScript",
|
|
18636
|
+
tsx: "Tsx",
|
|
18637
|
+
jsx: "Jsx",
|
|
18638
|
+
python: "Python",
|
|
18639
|
+
rust: "Rust",
|
|
18640
|
+
go: "Go",
|
|
18641
|
+
java: "Java",
|
|
18642
|
+
c: "C",
|
|
18643
|
+
cpp: "Cpp",
|
|
18644
|
+
csharp: "CSharp"
|
|
18645
|
+
};
|
|
18646
|
+
const lang = langMap[language.toLowerCase()] || language;
|
|
18647
|
+
const Lang = astGrepModule.Lang;
|
|
18648
|
+
if (!Lang || !Lang[lang]) {
|
|
18649
|
+
return JSON.stringify({
|
|
18650
|
+
success: false,
|
|
18651
|
+
error: `Unsupported language: ${language}`,
|
|
18652
|
+
availableLanguages: Object.keys(langMap)
|
|
18653
|
+
}, null, 2);
|
|
18654
|
+
}
|
|
18655
|
+
if (format === "pattern") {
|
|
18656
|
+
return JSON.stringify({
|
|
18657
|
+
success: true,
|
|
18658
|
+
format: "pattern",
|
|
18659
|
+
language,
|
|
18660
|
+
example: {
|
|
18661
|
+
match: "AwaitExpression",
|
|
18662
|
+
kind: "Use kind to match AST node types",
|
|
18663
|
+
pattern: "Use pattern for code templates"
|
|
18664
|
+
}
|
|
18665
|
+
}, null, 2);
|
|
18666
|
+
}
|
|
18667
|
+
const parse5 = astGrepModule.parse;
|
|
18668
|
+
const ast = parse5(Lang[lang], code);
|
|
18669
|
+
const root = ast.root();
|
|
18670
|
+
const dump = (node, depth = 0) => {
|
|
18671
|
+
if (!node)
|
|
18672
|
+
return null;
|
|
18673
|
+
return {
|
|
18674
|
+
kind: node.kind(),
|
|
18675
|
+
text: node.text(),
|
|
18676
|
+
children: node.children().map((child) => dump(child, depth + 1))
|
|
18677
|
+
};
|
|
18678
|
+
};
|
|
18679
|
+
return JSON.stringify({
|
|
18680
|
+
success: true,
|
|
18681
|
+
format: "cst",
|
|
18682
|
+
language,
|
|
18683
|
+
tree: dump(root)
|
|
18684
|
+
}, null, 2);
|
|
18685
|
+
} catch (error45) {
|
|
18985
18686
|
return JSON.stringify({
|
|
18986
18687
|
success: false,
|
|
18987
|
-
error:
|
|
18988
|
-
hint: "Symbol may not exist or not indexed"
|
|
18688
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
18989
18689
|
}, null, 2);
|
|
18990
18690
|
}
|
|
18991
|
-
return JSON.stringify({
|
|
18992
|
-
success: true,
|
|
18993
|
-
symbol: name,
|
|
18994
|
-
output: result.output
|
|
18995
|
-
}, null, 2);
|
|
18996
18691
|
}
|
|
18997
18692
|
});
|
|
18998
|
-
var
|
|
18999
|
-
description: `
|
|
18693
|
+
var astGrepTestMatchCodeRuleTool = tool({
|
|
18694
|
+
description: `Test a code against an ast-grep YAML rule.
|
|
19000
18695
|
|
|
19001
|
-
|
|
19002
|
-
- path: File path to analyze
|
|
18696
|
+
This is useful to test a rule before using it in a project.
|
|
19003
18697
|
|
|
19004
|
-
**
|
|
19005
|
-
|
|
19006
|
-
|
|
19007
|
-
\`\`\`
|
|
18698
|
+
**Parameters:**
|
|
18699
|
+
- code: The code to test against the rule
|
|
18700
|
+
- yaml: The ast-grep YAML rule to test
|
|
19008
18701
|
|
|
19009
|
-
**Returns:**
|
|
18702
|
+
**Returns:**
|
|
18703
|
+
- Whether the rule matched
|
|
18704
|
+
- Matched nodes with locations`,
|
|
19010
18705
|
args: {
|
|
19011
|
-
|
|
18706
|
+
code: tool.schema.string().describe("The code to test against the rule"),
|
|
18707
|
+
yaml: tool.schema.string().describe("The ast-grep YAML rule to search")
|
|
19012
18708
|
},
|
|
19013
|
-
async execute({
|
|
19014
|
-
|
|
19015
|
-
if (!
|
|
18709
|
+
async execute({ code, yaml }) {
|
|
18710
|
+
await initAstGrep();
|
|
18711
|
+
if (!astGrepModule) {
|
|
19016
18712
|
return JSON.stringify({
|
|
19017
18713
|
success: false,
|
|
19018
|
-
error: "
|
|
18714
|
+
error: "@ast-grep/napi not available",
|
|
18715
|
+
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
19019
18716
|
}, null, 2);
|
|
19020
18717
|
}
|
|
19021
|
-
|
|
19022
|
-
|
|
18718
|
+
try {
|
|
18719
|
+
const parse5 = astGrepModule.parse;
|
|
18720
|
+
const Lang = astGrepModule.Lang;
|
|
18721
|
+
const ast = parse5(Lang.TypeScript, code);
|
|
18722
|
+
const root = ast.root();
|
|
18723
|
+
return JSON.stringify({
|
|
18724
|
+
success: true,
|
|
18725
|
+
matched: false,
|
|
18726
|
+
note: "YAML rule testing requires @ast-grep/cli. Use ast_grep_find_code for pattern-based search.",
|
|
18727
|
+
example: {
|
|
18728
|
+
pattern: "console.log($ARG)",
|
|
18729
|
+
description: "Match console.log with any argument"
|
|
18730
|
+
}
|
|
18731
|
+
}, null, 2);
|
|
18732
|
+
} catch (error45) {
|
|
19023
18733
|
return JSON.stringify({
|
|
19024
18734
|
success: false,
|
|
19025
|
-
error:
|
|
19026
|
-
hint: "File may not exist or not indexed"
|
|
18735
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
19027
18736
|
}, null, 2);
|
|
19028
18737
|
}
|
|
19029
|
-
return JSON.stringify({
|
|
19030
|
-
success: true,
|
|
19031
|
-
path: path7,
|
|
19032
|
-
output: result.output
|
|
19033
|
-
}, null, 2);
|
|
19034
18738
|
}
|
|
19035
18739
|
});
|
|
19036
|
-
var
|
|
19037
|
-
description: `Find
|
|
18740
|
+
var astGrepFindCodeTool = tool({
|
|
18741
|
+
description: `Find code in a project folder that matches the given ast-grep pattern.
|
|
19038
18742
|
|
|
19039
|
-
|
|
19040
|
-
- name: Symbol name to find references for
|
|
18743
|
+
Pattern is good for simple and single-AST node result. For more complex usage, use ast_grep_scan_code.
|
|
19041
18744
|
|
|
19042
|
-
**
|
|
19043
|
-
|
|
19044
|
-
|
|
19045
|
-
|
|
18745
|
+
**Parameters:**
|
|
18746
|
+
- project_folder: The absolute path to the project folder
|
|
18747
|
+
- pattern: The ast-grep pattern to search for (e.g., 'console.log($ARG)', '$VAR = $VALUE')
|
|
18748
|
+
- language: Optional - programming language filter
|
|
19046
18749
|
|
|
19047
|
-
**
|
|
18750
|
+
**Pattern Examples:**
|
|
18751
|
+
- 'console.log($ARG)' - Match console.log with any argument
|
|
18752
|
+
- '$VAR = $VALUE' - Match any assignment
|
|
18753
|
+
- 'function $NAME($PARAMS) { $BODY }' - Match function declarations`,
|
|
19048
18754
|
args: {
|
|
19049
|
-
|
|
18755
|
+
project_folder: tool.schema.string().describe("The absolute path to the project folder"),
|
|
18756
|
+
pattern: tool.schema.string().describe("The ast-grep pattern to search for"),
|
|
18757
|
+
language: tool.schema.string().optional().describe("Programming language filter (typescript, javascript, python, etc.)")
|
|
19050
18758
|
},
|
|
19051
|
-
async execute({
|
|
19052
|
-
|
|
19053
|
-
if (!
|
|
19054
|
-
return JSON.stringify({
|
|
19055
|
-
success: false,
|
|
19056
|
-
error: "Dora not ready. Run dora_status first."
|
|
19057
|
-
}, null, 2);
|
|
19058
|
-
}
|
|
19059
|
-
const result = runDoraCommand(["references", name]);
|
|
19060
|
-
if (!result.success) {
|
|
18759
|
+
async execute({ project_folder, pattern, language }) {
|
|
18760
|
+
await initAstGrep();
|
|
18761
|
+
if (!astGrepModule) {
|
|
19061
18762
|
return JSON.stringify({
|
|
19062
18763
|
success: false,
|
|
19063
|
-
error:
|
|
18764
|
+
error: "@ast-grep/napi not available",
|
|
18765
|
+
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
19064
18766
|
}, null, 2);
|
|
19065
18767
|
}
|
|
19066
|
-
|
|
19067
|
-
|
|
19068
|
-
|
|
19069
|
-
|
|
19070
|
-
|
|
19071
|
-
|
|
19072
|
-
}
|
|
19073
|
-
|
|
19074
|
-
|
|
19075
|
-
|
|
19076
|
-
|
|
19077
|
-
|
|
19078
|
-
|
|
19079
|
-
|
|
19080
|
-
|
|
19081
|
-
|
|
19082
|
-
|
|
19083
|
-
|
|
19084
|
-
|
|
19085
|
-
|
|
18768
|
+
try {
|
|
18769
|
+
if (!fs7.existsSync(project_folder)) {
|
|
18770
|
+
return JSON.stringify({
|
|
18771
|
+
success: false,
|
|
18772
|
+
error: `Path not found: ${project_folder}`
|
|
18773
|
+
}, null, 2);
|
|
18774
|
+
}
|
|
18775
|
+
const langMap = {
|
|
18776
|
+
typescript: "TypeScript",
|
|
18777
|
+
javascript: "JavaScript",
|
|
18778
|
+
tsx: "Tsx",
|
|
18779
|
+
jsx: "Jsx",
|
|
18780
|
+
python: "Python",
|
|
18781
|
+
rust: "Rust",
|
|
18782
|
+
go: "Go",
|
|
18783
|
+
java: "Java"
|
|
18784
|
+
};
|
|
18785
|
+
const lang = language ? langMap[language.toLowerCase()] || language : "TypeScript";
|
|
18786
|
+
const Lang = astGrepModule.Lang;
|
|
18787
|
+
if (!Lang[lang]) {
|
|
18788
|
+
return JSON.stringify({
|
|
18789
|
+
success: false,
|
|
18790
|
+
error: `Unsupported language: ${language}`
|
|
18791
|
+
}, null, 2);
|
|
18792
|
+
}
|
|
18793
|
+
const findInFiles = astGrepModule.findInFiles;
|
|
18794
|
+
const results = [];
|
|
18795
|
+
await findInFiles(Lang[lang], {
|
|
18796
|
+
paths: [project_folder],
|
|
18797
|
+
matcher: { rule: { pattern } }
|
|
18798
|
+
}, (err, node) => {
|
|
18799
|
+
if (err) {
|
|
18800
|
+
console.warn("[ast-grep] Search error:", err);
|
|
18801
|
+
return;
|
|
18802
|
+
}
|
|
18803
|
+
if (node) {
|
|
18804
|
+
const text = node.text();
|
|
18805
|
+
const range = node.range();
|
|
18806
|
+
results.push({
|
|
18807
|
+
file: node.filename() || "unknown",
|
|
18808
|
+
line: range ? range.start.index : 0,
|
|
18809
|
+
column: range ? range.start.column : 0,
|
|
18810
|
+
matched: text.slice(0, 100)
|
|
18811
|
+
});
|
|
18812
|
+
}
|
|
18813
|
+
});
|
|
19086
18814
|
return JSON.stringify({
|
|
19087
|
-
success:
|
|
19088
|
-
|
|
18815
|
+
success: true,
|
|
18816
|
+
count: results.length,
|
|
18817
|
+
matches: results.slice(0, 50)
|
|
19089
18818
|
}, null, 2);
|
|
19090
|
-
}
|
|
19091
|
-
const result = runDoraCommand(["cycles"]);
|
|
19092
|
-
if (!result.success) {
|
|
18819
|
+
} catch (error45) {
|
|
19093
18820
|
return JSON.stringify({
|
|
19094
18821
|
success: false,
|
|
19095
|
-
error:
|
|
18822
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
19096
18823
|
}, null, 2);
|
|
19097
18824
|
}
|
|
19098
|
-
return JSON.stringify({
|
|
19099
|
-
success: true,
|
|
19100
|
-
cycles: result.output
|
|
19101
|
-
}, null, 2);
|
|
19102
18825
|
}
|
|
19103
18826
|
});
|
|
19104
|
-
var
|
|
19105
|
-
description: `
|
|
18827
|
+
var astGrepScanCodeTool = tool({
|
|
18828
|
+
description: `Analyze TypeScript/JS code for common bugs, performance issues and best practices.
|
|
19106
18829
|
|
|
19107
|
-
|
|
19108
|
-
\`\`\`
|
|
19109
|
-
dora_unused()
|
|
19110
|
-
\`\`\`
|
|
18830
|
+
Uses AST-based analysis for precise detection without false positives. Essential for maintaining code quality and preventing runtime errors.
|
|
19111
18831
|
|
|
19112
|
-
**
|
|
19113
|
-
|
|
19114
|
-
|
|
19115
|
-
|
|
19116
|
-
|
|
18832
|
+
**Detects:**
|
|
18833
|
+
- Type safety violations
|
|
18834
|
+
- Loose object types
|
|
18835
|
+
- Incorrect async patterns
|
|
18836
|
+
- Import style issues
|
|
18837
|
+
- Common bugs
|
|
18838
|
+
|
|
18839
|
+
**Parameters:**
|
|
18840
|
+
- project_folder: Optional - path to scan (defaults to current directory)`,
|
|
18841
|
+
args: {
|
|
18842
|
+
project_folder: tool.schema.string().optional().describe("Path to scan (defaults to current directory)")
|
|
18843
|
+
},
|
|
18844
|
+
async execute({ project_folder }) {
|
|
18845
|
+
await initAstGrep();
|
|
18846
|
+
if (!astGrepModule) {
|
|
19117
18847
|
return JSON.stringify({
|
|
19118
18848
|
success: false,
|
|
19119
|
-
error: "
|
|
18849
|
+
error: "@ast-grep/napi not available",
|
|
18850
|
+
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
19120
18851
|
}, null, 2);
|
|
19121
18852
|
}
|
|
19122
|
-
|
|
19123
|
-
|
|
18853
|
+
try {
|
|
18854
|
+
const scanPath = project_folder || process.cwd();
|
|
18855
|
+
if (!fs7.existsSync(scanPath)) {
|
|
18856
|
+
return JSON.stringify({
|
|
18857
|
+
success: false,
|
|
18858
|
+
error: `Path not found: ${scanPath}`
|
|
18859
|
+
}, null, 2);
|
|
18860
|
+
}
|
|
18861
|
+
const bugPatterns = [
|
|
18862
|
+
{ pattern: "await Promise.all($ARR)", severity: "warning", message: "Check if Promise.all is used correctly with async operations" },
|
|
18863
|
+
{ pattern: "JSON.parse($STR)", severity: "info", message: "Consider adding try-catch for JSON.parse" },
|
|
18864
|
+
{ pattern: "$VAR == $VAL", severity: "warning", message: "Use === instead of == for strict equality" }
|
|
18865
|
+
];
|
|
18866
|
+
const issues = [];
|
|
18867
|
+
const Lang = astGrepModule.Lang;
|
|
18868
|
+
const findInFiles = astGrepModule.findInFiles;
|
|
18869
|
+
for (const bug of bugPatterns) {
|
|
18870
|
+
await findInFiles(Lang.TypeScript, {
|
|
18871
|
+
paths: [scanPath],
|
|
18872
|
+
matcher: { rule: { pattern: bug.pattern } }
|
|
18873
|
+
}, (err, node) => {
|
|
18874
|
+
if (err || !node)
|
|
18875
|
+
return;
|
|
18876
|
+
issues.push({
|
|
18877
|
+
file: node.filename() || "unknown",
|
|
18878
|
+
line: node.range()?.start.index || 0,
|
|
18879
|
+
severity: bug.severity,
|
|
18880
|
+
message: bug.message,
|
|
18881
|
+
pattern: bug.pattern
|
|
18882
|
+
});
|
|
18883
|
+
});
|
|
18884
|
+
}
|
|
19124
18885
|
return JSON.stringify({
|
|
19125
|
-
success:
|
|
19126
|
-
|
|
18886
|
+
success: true,
|
|
18887
|
+
scanned: scanPath,
|
|
18888
|
+
issuesFound: issues.length,
|
|
18889
|
+
issues: issues.slice(0, 20),
|
|
18890
|
+
summary: issues.length === 0 ? "No common issues detected" : `Found ${issues.length} potential issues`
|
|
19127
18891
|
}, null, 2);
|
|
19128
|
-
}
|
|
19129
|
-
return JSON.stringify({
|
|
19130
|
-
success: true,
|
|
19131
|
-
unused: result.output
|
|
19132
|
-
}, null, 2);
|
|
19133
|
-
}
|
|
19134
|
-
});
|
|
19135
|
-
|
|
19136
|
-
// src/tools/auto-cr.ts
|
|
19137
|
-
import { execSync as execSync3 } from "child_process";
|
|
19138
|
-
import * as fs7 from "fs";
|
|
19139
|
-
function checkAutoCrStatus() {
|
|
19140
|
-
try {
|
|
19141
|
-
const output = execSync3("auto-cr-cmd --version", { encoding: "utf-8" });
|
|
19142
|
-
const version2 = output.trim();
|
|
19143
|
-
return { installed: true, version: version2 };
|
|
19144
|
-
} catch {
|
|
19145
|
-
return { installed: false };
|
|
19146
|
-
}
|
|
19147
|
-
}
|
|
19148
|
-
function runAutoCr(args2) {
|
|
19149
|
-
try {
|
|
19150
|
-
const allArgs = [...args2, "--output", "json"];
|
|
19151
|
-
const output = execSync3(`auto-cr-cmd ${allArgs.join(" ")}`, {
|
|
19152
|
-
encoding: "utf-8",
|
|
19153
|
-
maxBuffer: 50 * 1024 * 1024
|
|
19154
|
-
});
|
|
19155
|
-
try {
|
|
19156
|
-
const json2 = JSON.parse(output);
|
|
19157
|
-
return { success: true, output, json: json2 };
|
|
19158
|
-
} catch {
|
|
19159
|
-
return { success: true, output };
|
|
19160
|
-
}
|
|
19161
|
-
} catch (error45) {
|
|
19162
|
-
const stderr = error45.stderr || "";
|
|
19163
|
-
const stdout = error45.stdout || "";
|
|
19164
|
-
const combined = stdout + stderr;
|
|
19165
|
-
try {
|
|
19166
|
-
const json2 = JSON.parse(combined);
|
|
19167
|
-
return { success: true, output: combined, json: json2 };
|
|
19168
|
-
} catch {
|
|
19169
|
-
return { success: false, error: combined || error45.message };
|
|
19170
|
-
}
|
|
19171
|
-
}
|
|
19172
|
-
}
|
|
19173
|
-
var autoCrStatusTool = tool({
|
|
19174
|
-
description: `Check auto-cr-cmd installation status.
|
|
19175
|
-
|
|
19176
|
-
**Returns:**
|
|
19177
|
-
- installed: Whether auto-cr-cmd is available
|
|
19178
|
-
- version: Auto-CR version
|
|
19179
|
-
- ready: Whether it's ready to scan
|
|
19180
|
-
|
|
19181
|
-
**Installation:**
|
|
19182
|
-
\`\`\`bash
|
|
19183
|
-
npm install auto-cr-cmd
|
|
19184
|
-
# or
|
|
19185
|
-
pnpm add auto-cr-cmd
|
|
19186
|
-
\`\`\``,
|
|
19187
|
-
args: {},
|
|
19188
|
-
async execute() {
|
|
19189
|
-
const status = checkAutoCrStatus();
|
|
19190
|
-
if (!status.installed) {
|
|
18892
|
+
} catch (error45) {
|
|
19191
18893
|
return JSON.stringify({
|
|
19192
|
-
|
|
19193
|
-
|
|
19194
|
-
installation: "npm install auto-cr-cmd"
|
|
18894
|
+
success: false,
|
|
18895
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
19195
18896
|
}, null, 2);
|
|
19196
18897
|
}
|
|
19197
|
-
return JSON.stringify({
|
|
19198
|
-
status: "ready",
|
|
19199
|
-
version: status.version,
|
|
19200
|
-
message: "Auto-CR is ready to scan",
|
|
19201
|
-
rules: [
|
|
19202
|
-
"no-deep-relative-imports",
|
|
19203
|
-
"no-circular-dependencies",
|
|
19204
|
-
"no-swallowed-errors",
|
|
19205
|
-
"no-catastrophic-regex",
|
|
19206
|
-
"no-deep-clone-in-loop",
|
|
19207
|
-
"no-n2-array-lookup"
|
|
19208
|
-
]
|
|
19209
|
-
}, null, 2);
|
|
19210
18898
|
}
|
|
19211
18899
|
});
|
|
19212
|
-
var
|
|
19213
|
-
description: `
|
|
18900
|
+
var astGrepRewriteCodeTool = tool({
|
|
18901
|
+
description: `Transform and refactor code using AST-based find-and-replace patterns.
|
|
19214
18902
|
|
|
19215
|
-
|
|
19216
|
-
- path: Directory path to scan (defaults to ./src)
|
|
19217
|
-
- language: Output language (en/zh, defaults to en)
|
|
18903
|
+
Use metavariables ($VAR, $$$VARS) in both pattern and replacement.
|
|
19218
18904
|
|
|
19219
|
-
**
|
|
19220
|
-
- no-deep-relative-imports: Import paths exceeding depth limit
|
|
19221
|
-
- no-circular-dependencies: Circular module dependencies
|
|
19222
|
-
- no-swallowed-errors: try-catch blocks that swallow errors
|
|
19223
|
-
- no-catastrophic-regex: Potentially catastrophic regex patterns
|
|
19224
|
-
- no-deep-clone-in-loop: Performance anti-patterns
|
|
19225
|
-
- no-n2-array-lookup: O(n²) array operations
|
|
18905
|
+
**Example:** Find 'console.log($ARG)' and replace with 'logger.info($ARG)'
|
|
19226
18906
|
|
|
19227
|
-
**
|
|
19228
|
-
|
|
19229
|
-
|
|
19230
|
-
|
|
18907
|
+
**Parameters:**
|
|
18908
|
+
- project_folder: Path to the project folder
|
|
18909
|
+
- pattern: AST pattern to find
|
|
18910
|
+
- replacement: Replacement pattern
|
|
18911
|
+
- language: Programming language (defaults to TypeScript)`,
|
|
19231
18912
|
args: {
|
|
19232
|
-
|
|
19233
|
-
|
|
18913
|
+
project_folder: tool.schema.string().describe("Path to the project folder"),
|
|
18914
|
+
pattern: tool.schema.string().describe("AST pattern to find"),
|
|
18915
|
+
replacement: tool.schema.string().describe("Replacement pattern"),
|
|
18916
|
+
language: tool.schema.string().optional().default("TypeScript").describe("Programming language")
|
|
19234
18917
|
},
|
|
19235
|
-
async execute({
|
|
19236
|
-
|
|
19237
|
-
if (!
|
|
19238
|
-
return JSON.stringify({
|
|
19239
|
-
success: false,
|
|
19240
|
-
error: "auto-cr-cmd not installed",
|
|
19241
|
-
hint: "npm install auto-cr-cmd"
|
|
19242
|
-
}, null, 2);
|
|
19243
|
-
}
|
|
19244
|
-
if (!fs7.existsSync(path7)) {
|
|
18918
|
+
async execute({ project_folder, pattern, replacement, language }) {
|
|
18919
|
+
await initAstGrep();
|
|
18920
|
+
if (!astGrepModule) {
|
|
19245
18921
|
return JSON.stringify({
|
|
19246
18922
|
success: false,
|
|
19247
|
-
error:
|
|
18923
|
+
error: "@ast-grep/napi not available",
|
|
18924
|
+
hint: "Install @ast-grep/napi or use MCP-based ast_grep"
|
|
19248
18925
|
}, null, 2);
|
|
19249
18926
|
}
|
|
19250
|
-
|
|
19251
|
-
|
|
18927
|
+
try {
|
|
18928
|
+
if (!fs7.existsSync(project_folder)) {
|
|
18929
|
+
return JSON.stringify({
|
|
18930
|
+
success: false,
|
|
18931
|
+
error: `Path not found: ${project_folder}`
|
|
18932
|
+
}, null, 2);
|
|
18933
|
+
}
|
|
18934
|
+
const Lang = astGrepModule.Lang;
|
|
18935
|
+
if (!Lang[language]) {
|
|
18936
|
+
return JSON.stringify({
|
|
18937
|
+
success: false,
|
|
18938
|
+
error: `Unsupported language: ${language}`
|
|
18939
|
+
}, null, 2);
|
|
18940
|
+
}
|
|
19252
18941
|
return JSON.stringify({
|
|
19253
|
-
success:
|
|
19254
|
-
|
|
18942
|
+
success: true,
|
|
18943
|
+
operation: "info",
|
|
18944
|
+
message: "Full rewrite requires @ast-grep/cli with config file",
|
|
18945
|
+
suggestion: "Use ast_grep_find_code to find matches, then hive_code_edit for individual replacements",
|
|
18946
|
+
parameters: {
|
|
18947
|
+
projectFolder: project_folder,
|
|
18948
|
+
pattern,
|
|
18949
|
+
replacement,
|
|
18950
|
+
language
|
|
18951
|
+
}
|
|
19255
18952
|
}, null, 2);
|
|
19256
|
-
}
|
|
19257
|
-
if (result.json) {
|
|
19258
|
-
const { summary, files, notifications } = result.json;
|
|
18953
|
+
} catch (error45) {
|
|
19259
18954
|
return JSON.stringify({
|
|
19260
|
-
success:
|
|
19261
|
-
|
|
19262
|
-
summary: {
|
|
19263
|
-
filesScanned: summary?.scannedFiles || 0,
|
|
19264
|
-
filesWithErrors: summary?.filesWithErrors || 0,
|
|
19265
|
-
filesWithWarnings: summary?.filesWithWarnings || 0,
|
|
19266
|
-
totalViolations: summary?.violationTotals?.total || 0
|
|
19267
|
-
},
|
|
19268
|
-
files: files?.map((f) => ({
|
|
19269
|
-
path: f.filePath,
|
|
19270
|
-
violations: f.totalViolations,
|
|
19271
|
-
errors: f.severityCounts?.error || 0,
|
|
19272
|
-
warnings: f.severityCounts?.warning || 0,
|
|
19273
|
-
details: f.violations?.map((v) => ({
|
|
19274
|
-
rule: v.ruleName,
|
|
19275
|
-
severity: v.severity,
|
|
19276
|
-
message: v.message,
|
|
19277
|
-
line: v.line
|
|
19278
|
-
}))
|
|
19279
|
-
})),
|
|
19280
|
-
notifications: notifications || []
|
|
18955
|
+
success: false,
|
|
18956
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
19281
18957
|
}, null, 2);
|
|
19282
18958
|
}
|
|
19283
|
-
return JSON.stringify({
|
|
19284
|
-
success: true,
|
|
19285
|
-
scanned: path7,
|
|
19286
|
-
rawOutput: result.output
|
|
19287
|
-
}, null, 2);
|
|
19288
18959
|
}
|
|
19289
18960
|
});
|
|
19290
|
-
var
|
|
19291
|
-
description: `
|
|
19292
|
-
|
|
19293
|
-
**Use case:** Run in CI to check only changed files.
|
|
18961
|
+
var astGrepAnalyzeImportsTool = tool({
|
|
18962
|
+
description: `Analyze import statements and dependencies in your codebase.
|
|
19294
18963
|
|
|
19295
|
-
|
|
19296
|
-
\`\`\`bash
|
|
19297
|
-
git diff --name-only -z | xargs -0 auto-cr-cmd --stdin --output json
|
|
19298
|
-
\`\`\`
|
|
18964
|
+
Choose "usage" to see which imports are actually used (great for refactoring), or "discovery" to explore all imports and identifiers in the code (great for understanding structure).
|
|
19299
18965
|
|
|
19300
|
-
**
|
|
18966
|
+
**Parameters:**
|
|
18967
|
+
- mode: "usage" (default) shows where imports are used, "discovery" shows all imports
|
|
18968
|
+
- path: Specific directory or file to analyze (defaults to current directory)`,
|
|
19301
18969
|
args: {
|
|
19302
|
-
|
|
18970
|
+
mode: tool.schema.enum(["usage", "discovery"]).default("usage").describe("Analysis mode"),
|
|
18971
|
+
path: tool.schema.string().optional().describe("Directory or file to analyze")
|
|
19303
18972
|
},
|
|
19304
|
-
async execute({
|
|
19305
|
-
|
|
19306
|
-
if (!
|
|
18973
|
+
async execute({ mode, path: path7 }) {
|
|
18974
|
+
await initAstGrep();
|
|
18975
|
+
if (!astGrepModule) {
|
|
19307
18976
|
return JSON.stringify({
|
|
19308
18977
|
success: false,
|
|
19309
|
-
error: "
|
|
19310
|
-
hint: "npm install auto-cr-cmd"
|
|
18978
|
+
error: "@ast-grep/napi not available"
|
|
19311
18979
|
}, null, 2);
|
|
19312
18980
|
}
|
|
19313
|
-
|
|
19314
|
-
|
|
19315
|
-
|
|
19316
|
-
|
|
19317
|
-
|
|
19318
|
-
|
|
19319
|
-
});
|
|
19320
|
-
var autoCrRulesTool = tool({
|
|
19321
|
-
description: `List available auto-cr rules and their descriptions.
|
|
19322
|
-
|
|
19323
|
-
**Returns:** All built-in rules with descriptions.`,
|
|
19324
|
-
args: {},
|
|
19325
|
-
async execute() {
|
|
19326
|
-
const rules = [
|
|
19327
|
-
{
|
|
19328
|
-
name: "no-deep-relative-imports",
|
|
19329
|
-
severity: "error",
|
|
19330
|
-
description: "Import paths should not exceed maximum depth",
|
|
19331
|
-
example: "Use path aliases (@shared/utils) instead of ../../../../shared/utils"
|
|
19332
|
-
},
|
|
19333
|
-
{
|
|
19334
|
-
name: "no-circular-dependencies",
|
|
19335
|
-
severity: "warning",
|
|
19336
|
-
description: "Detect circular module dependencies",
|
|
19337
|
-
example: "A imports B, B imports A creates a cycle"
|
|
19338
|
-
},
|
|
19339
|
-
{
|
|
19340
|
-
name: "no-swallowed-errors",
|
|
19341
|
-
severity: "warning",
|
|
19342
|
-
description: "try-catch blocks that swallow errors without rethrowing",
|
|
19343
|
-
example: "catch (e) {} without logging or rethrowing"
|
|
19344
|
-
},
|
|
19345
|
-
{
|
|
19346
|
-
name: "no-catastrophic-regex",
|
|
19347
|
-
severity: "error",
|
|
19348
|
-
description: "Potentially catastrophic regex backtracking",
|
|
19349
|
-
example: "Regex with nested quantifiers that can hang"
|
|
19350
|
-
},
|
|
19351
|
-
{
|
|
19352
|
-
name: "no-deep-clone-in-loop",
|
|
19353
|
-
severity: "warning",
|
|
19354
|
-
description: "Performance: deep clone operations inside loops",
|
|
19355
|
-
example: "for loop calling JSON.parse(JSON.stringify())"
|
|
19356
|
-
},
|
|
19357
|
-
{
|
|
19358
|
-
name: "no-n2-array-lookup",
|
|
19359
|
-
severity: "warning",
|
|
19360
|
-
description: "O(n²) array operations",
|
|
19361
|
-
example: "Nested for loops accessing array elements"
|
|
18981
|
+
try {
|
|
18982
|
+
const analyzePath = path7 || process.cwd();
|
|
18983
|
+
if (!fs7.existsSync(analyzePath)) {
|
|
18984
|
+
return JSON.stringify({
|
|
18985
|
+
success: false,
|
|
18986
|
+
error: `Path not found: ${analyzePath}`
|
|
18987
|
+
}, null, 2);
|
|
19362
18988
|
}
|
|
19363
|
-
|
|
19364
|
-
|
|
19365
|
-
|
|
19366
|
-
|
|
19367
|
-
|
|
19368
|
-
|
|
18989
|
+
const Lang = astGrepModule.Lang;
|
|
18990
|
+
const findInFiles = astGrepModule.findInFiles;
|
|
18991
|
+
const imports = {};
|
|
18992
|
+
await findInFiles(Lang.TypeScript, {
|
|
18993
|
+
paths: [analyzePath],
|
|
18994
|
+
matcher: { rule: { kind: "import_statement" } }
|
|
18995
|
+
}, (err, node) => {
|
|
18996
|
+
if (err || !node)
|
|
18997
|
+
return;
|
|
18998
|
+
const text = node.text();
|
|
18999
|
+
const match = text.match(/from ['"]([^'"]+)['"]/);
|
|
19000
|
+
if (match) {
|
|
19001
|
+
const module = match[1];
|
|
19002
|
+
const file2 = node.filename() || "unknown";
|
|
19003
|
+
if (!imports[module]) {
|
|
19004
|
+
imports[module] = [];
|
|
19005
|
+
}
|
|
19006
|
+
if (!imports[module].includes(file2)) {
|
|
19007
|
+
imports[module].push(file2);
|
|
19008
|
+
}
|
|
19009
|
+
}
|
|
19010
|
+
});
|
|
19011
|
+
if (mode === "usage") {
|
|
19012
|
+
return JSON.stringify({
|
|
19013
|
+
success: true,
|
|
19014
|
+
mode: "usage",
|
|
19015
|
+
imports: Object.entries(imports).map(([module, files]) => ({
|
|
19016
|
+
module,
|
|
19017
|
+
importCount: 1,
|
|
19018
|
+
filesCount: files.length
|
|
19019
|
+
})),
|
|
19020
|
+
note: "Full usage analysis requires @ast-grep/cli"
|
|
19021
|
+
}, null, 2);
|
|
19022
|
+
}
|
|
19023
|
+
return JSON.stringify({
|
|
19024
|
+
success: true,
|
|
19025
|
+
mode: "discovery",
|
|
19026
|
+
totalModules: Object.keys(imports).length,
|
|
19027
|
+
imports: Object.entries(imports).map(([module, files]) => ({
|
|
19028
|
+
module,
|
|
19029
|
+
importCount: files.length,
|
|
19030
|
+
files: files.slice(0, 5)
|
|
19031
|
+
}))
|
|
19032
|
+
}, null, 2);
|
|
19033
|
+
} catch (error45) {
|
|
19034
|
+
return JSON.stringify({
|
|
19035
|
+
success: false,
|
|
19036
|
+
error: error45 instanceof Error ? error45.message : String(error45)
|
|
19037
|
+
}, null, 2);
|
|
19038
|
+
}
|
|
19369
19039
|
}
|
|
19370
19040
|
});
|
|
19371
19041
|
|
|
@@ -20696,12 +20366,6 @@ var grepAppMcp = {
|
|
|
20696
20366
|
oauth: false
|
|
20697
20367
|
};
|
|
20698
20368
|
|
|
20699
|
-
// src/mcp/ast-grep.ts
|
|
20700
|
-
var astGrepMcp = {
|
|
20701
|
-
type: "local",
|
|
20702
|
-
command: ["npx", "-y", "@notprolands/ast-grep-mcp"]
|
|
20703
|
-
};
|
|
20704
|
-
|
|
20705
20369
|
// src/mcp/pare-search.ts
|
|
20706
20370
|
var pareSearchMcp = {
|
|
20707
20371
|
type: "local",
|
|
@@ -20714,14 +20378,20 @@ var veilMcp = {
|
|
|
20714
20378
|
command: ["npx", "-y", "@ushiradineth/veil@latest", "mcp", "server"]
|
|
20715
20379
|
};
|
|
20716
20380
|
|
|
20381
|
+
// src/mcp/ast-grep.ts
|
|
20382
|
+
var astGrepMcp = {
|
|
20383
|
+
type: "local",
|
|
20384
|
+
command: ["npx", "-y", "@notprolands/ast-grep-mcp"]
|
|
20385
|
+
};
|
|
20386
|
+
|
|
20717
20387
|
// src/mcp/index.ts
|
|
20718
20388
|
var allBuiltinMcps = {
|
|
20719
20389
|
websearch: websearchMcp,
|
|
20720
20390
|
context7: context7Mcp,
|
|
20721
20391
|
grep_app: grepAppMcp,
|
|
20722
|
-
ast_grep: astGrepMcp,
|
|
20723
20392
|
pare_search: pareSearchMcp,
|
|
20724
|
-
veil: veilMcp
|
|
20393
|
+
veil: veilMcp,
|
|
20394
|
+
ast_grep: astGrepMcp
|
|
20725
20395
|
};
|
|
20726
20396
|
var createBuiltinMcps = (disabledMcps = []) => {
|
|
20727
20397
|
const disabled = new Set(disabledMcps);
|
|
@@ -20753,7 +20423,7 @@ import * as fs11 from "fs";
|
|
|
20753
20423
|
import * as path8 from "path";
|
|
20754
20424
|
import { existsSync as existsSync52 } from "fs";
|
|
20755
20425
|
import { join as join92, sep } from "path";
|
|
20756
|
-
import { execSync as
|
|
20426
|
+
import { execSync as execSync5 } from "child_process";
|
|
20757
20427
|
var __create2 = Object.create;
|
|
20758
20428
|
var __getProtoOf2 = Object.getPrototypeOf;
|
|
20759
20429
|
var __defProp2 = Object.defineProperty;
|
|
@@ -21607,8 +21277,7 @@ var DEFAULT_HIVE_CONFIG = {
|
|
|
21607
21277
|
enabled: false,
|
|
21608
21278
|
indexPath: path7.join(os3.homedir(), ".config", "opencode", "hive", "vector-index"),
|
|
21609
21279
|
dimensions: 384
|
|
21610
|
-
}
|
|
21611
|
-
autoInstallDeps: true
|
|
21280
|
+
}
|
|
21612
21281
|
};
|
|
21613
21282
|
var HIVE_DIR = ".hive";
|
|
21614
21283
|
var FEATURES_DIR = "features";
|
|
@@ -27619,10 +27288,10 @@ class DockerSandboxService {
|
|
|
27619
27288
|
static ensureContainer(worktreePath, image) {
|
|
27620
27289
|
const name = this.containerName(worktreePath);
|
|
27621
27290
|
try {
|
|
27622
|
-
|
|
27291
|
+
execSync5(`docker inspect --format='{{.State.Running}}' ${name}`, { stdio: "pipe" });
|
|
27623
27292
|
return name;
|
|
27624
27293
|
} catch {
|
|
27625
|
-
|
|
27294
|
+
execSync5(`docker run -d --name ${name} -v ${worktreePath}:/app -w /app ${image} tail -f /dev/null`, { stdio: "pipe" });
|
|
27626
27295
|
return name;
|
|
27627
27296
|
}
|
|
27628
27297
|
}
|
|
@@ -27633,12 +27302,12 @@ class DockerSandboxService {
|
|
|
27633
27302
|
static stopContainer(worktreePath) {
|
|
27634
27303
|
const name = this.containerName(worktreePath);
|
|
27635
27304
|
try {
|
|
27636
|
-
|
|
27305
|
+
execSync5(`docker rm -f ${name}`, { stdio: "ignore" });
|
|
27637
27306
|
} catch {}
|
|
27638
27307
|
}
|
|
27639
27308
|
static isDockerAvailable() {
|
|
27640
27309
|
try {
|
|
27641
|
-
|
|
27310
|
+
execSync5("docker info", { stdio: "ignore" });
|
|
27642
27311
|
return true;
|
|
27643
27312
|
} catch {
|
|
27644
27313
|
return false;
|
|
@@ -28218,183 +27887,6 @@ function buildCompactionPrompt() {
|
|
|
28218
27887
|
return COMPACTION_RESUME_PROMPT;
|
|
28219
27888
|
}
|
|
28220
27889
|
|
|
28221
|
-
// src/utils/dep-installer.ts
|
|
28222
|
-
import { execSync as execSync5 } from "child_process";
|
|
28223
|
-
import * as path11 from "path";
|
|
28224
|
-
import * as os4 from "os";
|
|
28225
|
-
var PLUGIN_TOOLS = [
|
|
28226
|
-
{
|
|
28227
|
-
name: "btca",
|
|
28228
|
-
npmPackage: "btca-cli",
|
|
28229
|
-
installCommand: ["npm", "install", "-g", "btca-cli"],
|
|
28230
|
-
verifyCommand: "btca --version",
|
|
28231
|
-
description: "Bluetooth Classic Audio control",
|
|
28232
|
-
required: false
|
|
28233
|
-
},
|
|
28234
|
-
{
|
|
28235
|
-
name: "dora",
|
|
28236
|
-
npmPackage: "@butttons/dora",
|
|
28237
|
-
installCommand: ["npm", "install", "-g", "@butttons/dora"],
|
|
28238
|
-
verifyCommand: "dora --version",
|
|
28239
|
-
description: "SCIP-based code navigation",
|
|
28240
|
-
required: false
|
|
28241
|
-
},
|
|
28242
|
-
{
|
|
28243
|
-
name: "auto-cr",
|
|
28244
|
-
npmPackage: "auto-cr-cmd",
|
|
28245
|
-
installCommand: ["npm", "install", "-g", "auto-cr-cmd"],
|
|
28246
|
-
verifyCommand: "auto-cr-cmd --version",
|
|
28247
|
-
description: "SWC-based automated code review",
|
|
28248
|
-
required: false
|
|
28249
|
-
},
|
|
28250
|
-
{
|
|
28251
|
-
name: "scip-typescript",
|
|
28252
|
-
npmPackage: "@sourcegraph/scip-typescript",
|
|
28253
|
-
installCommand: ["npm", "install", "-g", "@sourcegraph/scip-typescript"],
|
|
28254
|
-
verifyCommand: "scip-typescript --version",
|
|
28255
|
-
description: "TypeScript SCIP indexer (for dora)",
|
|
28256
|
-
required: false
|
|
28257
|
-
},
|
|
28258
|
-
{
|
|
28259
|
-
name: "typescript-language-server",
|
|
28260
|
-
npmPackage: "typescript-language-server",
|
|
28261
|
-
installCommand: ["npm", "install", "-g", "typescript-language-server", "typescript"],
|
|
28262
|
-
verifyCommand: "typescript-language-server --version",
|
|
28263
|
-
description: "TypeScript/JavaScript LSP server",
|
|
28264
|
-
required: false
|
|
28265
|
-
},
|
|
28266
|
-
{
|
|
28267
|
-
name: "pyright",
|
|
28268
|
-
npmPackage: "pyright",
|
|
28269
|
-
installCommand: ["pip", "install", "pyright"],
|
|
28270
|
-
verifyCommand: "pyright --version",
|
|
28271
|
-
description: "Python LSP server",
|
|
28272
|
-
required: false
|
|
28273
|
-
}
|
|
28274
|
-
];
|
|
28275
|
-
|
|
28276
|
-
class DependencyInstaller {
|
|
28277
|
-
installDir;
|
|
28278
|
-
cache = new Map;
|
|
28279
|
-
cacheTimeout = 60000;
|
|
28280
|
-
constructor(installDir) {
|
|
28281
|
-
this.installDir = installDir || path11.join(os4.homedir(), ".local");
|
|
28282
|
-
}
|
|
28283
|
-
getBinDir() {
|
|
28284
|
-
return path11.join(this.installDir, "bin");
|
|
28285
|
-
}
|
|
28286
|
-
commandExists(cmd) {
|
|
28287
|
-
try {
|
|
28288
|
-
execSync5(`which ${cmd}`, { stdio: "ignore" });
|
|
28289
|
-
return true;
|
|
28290
|
-
} catch {
|
|
28291
|
-
return false;
|
|
28292
|
-
}
|
|
28293
|
-
}
|
|
28294
|
-
verifyTool(config2) {
|
|
28295
|
-
try {
|
|
28296
|
-
execSync5(config2.verifyCommand, { stdio: "ignore", timeout: 5000 });
|
|
28297
|
-
return true;
|
|
28298
|
-
} catch {
|
|
28299
|
-
return false;
|
|
28300
|
-
}
|
|
28301
|
-
}
|
|
28302
|
-
async install(config2) {
|
|
28303
|
-
console.log(`[dep-installer] Installing ${config2.name}...`);
|
|
28304
|
-
try {
|
|
28305
|
-
const [cmd, ...args2] = config2.installCommand;
|
|
28306
|
-
const fullCmd = `${cmd} ${args2.join(" ")}`;
|
|
28307
|
-
execSync5(fullCmd, {
|
|
28308
|
-
stdio: "inherit",
|
|
28309
|
-
timeout: 120000,
|
|
28310
|
-
env: {
|
|
28311
|
-
...process.env,
|
|
28312
|
-
...cmd === "npm" ? { npm_config_prefix: this.installDir } : {}
|
|
28313
|
-
}
|
|
28314
|
-
});
|
|
28315
|
-
const verified = this.verifyTool(config2);
|
|
28316
|
-
if (verified) {
|
|
28317
|
-
console.log(`[dep-installer] ✓ ${config2.name} installed successfully`);
|
|
28318
|
-
this.cache.set(config2.name, { installed: true, checked: Date.now() });
|
|
28319
|
-
return { success: true, output: `${config2.name} installed and verified` };
|
|
28320
|
-
} else {
|
|
28321
|
-
return { success: false, error: "Installation completed but verification failed" };
|
|
28322
|
-
}
|
|
28323
|
-
} catch (error45) {
|
|
28324
|
-
console.warn(`[dep-installer] ✗ ${config2.name} installation failed: ${error45.message}`);
|
|
28325
|
-
return { success: false, error: error45.message };
|
|
28326
|
-
}
|
|
28327
|
-
}
|
|
28328
|
-
isInstalled(toolName) {
|
|
28329
|
-
const cached2 = this.cache.get(toolName);
|
|
28330
|
-
if (cached2 && Date.now() - cached2.checked < this.cacheTimeout) {
|
|
28331
|
-
return cached2.installed;
|
|
28332
|
-
}
|
|
28333
|
-
const config2 = PLUGIN_TOOLS.find((t) => t.name === toolName);
|
|
28334
|
-
if (!config2)
|
|
28335
|
-
return false;
|
|
28336
|
-
const installed = this.verifyTool(config2);
|
|
28337
|
-
this.cache.set(toolName, { installed, checked: Date.now() });
|
|
28338
|
-
return installed;
|
|
28339
|
-
}
|
|
28340
|
-
getStatus() {
|
|
28341
|
-
return PLUGIN_TOOLS.map((config2) => ({
|
|
28342
|
-
name: config2.name,
|
|
28343
|
-
installed: this.isInstalled(config2.name),
|
|
28344
|
-
description: config2.description,
|
|
28345
|
-
required: config2.required
|
|
28346
|
-
}));
|
|
28347
|
-
}
|
|
28348
|
-
async ensureRequired() {
|
|
28349
|
-
const installed = [];
|
|
28350
|
-
const missing = [];
|
|
28351
|
-
const errors3 = {};
|
|
28352
|
-
for (const config2 of PLUGIN_TOOLS) {
|
|
28353
|
-
if (config2.required && !this.isInstalled(config2.name)) {
|
|
28354
|
-
const result = await this.install(config2);
|
|
28355
|
-
if (result.success) {
|
|
28356
|
-
installed.push(config2.name);
|
|
28357
|
-
} else {
|
|
28358
|
-
missing.push(config2.name);
|
|
28359
|
-
errors3[config2.name] = result.error || "Installation failed";
|
|
28360
|
-
}
|
|
28361
|
-
}
|
|
28362
|
-
}
|
|
28363
|
-
return { installed, missing, errors: errors3 };
|
|
28364
|
-
}
|
|
28365
|
-
async installAll() {
|
|
28366
|
-
const success2 = [];
|
|
28367
|
-
const failed = {};
|
|
28368
|
-
for (const config2 of PLUGIN_TOOLS) {
|
|
28369
|
-
if (!this.isInstalled(config2.name)) {
|
|
28370
|
-
const result = await this.install(config2);
|
|
28371
|
-
if (result.success) {
|
|
28372
|
-
success2.push(config2.name);
|
|
28373
|
-
} else {
|
|
28374
|
-
failed[config2.name] = result.error || "Installation failed";
|
|
28375
|
-
}
|
|
28376
|
-
} else {
|
|
28377
|
-
success2.push(config2.name);
|
|
28378
|
-
}
|
|
28379
|
-
}
|
|
28380
|
-
return { success: success2, failed };
|
|
28381
|
-
}
|
|
28382
|
-
async installTool(toolName) {
|
|
28383
|
-
const config2 = PLUGIN_TOOLS.find((t) => t.name === toolName);
|
|
28384
|
-
if (!config2) {
|
|
28385
|
-
return { success: false, error: `Unknown tool: ${toolName}. Available: ${PLUGIN_TOOLS.map((t) => t.name).join(", ")}` };
|
|
28386
|
-
}
|
|
28387
|
-
if (this.isInstalled(toolName)) {
|
|
28388
|
-
return { success: true, output: `${toolName} is already installed` };
|
|
28389
|
-
}
|
|
28390
|
-
return this.install(config2);
|
|
28391
|
-
}
|
|
28392
|
-
}
|
|
28393
|
-
var dependencyInstaller = new DependencyInstaller;
|
|
28394
|
-
async function ensurePluginDeps() {
|
|
28395
|
-
dependencyInstaller.ensureRequired().catch(console.error);
|
|
28396
|
-
}
|
|
28397
|
-
|
|
28398
27890
|
// src/index.ts
|
|
28399
27891
|
function formatSkillsXml(skills) {
|
|
28400
27892
|
if (skills.length === 0)
|
|
@@ -28420,7 +27912,7 @@ async function buildAutoLoadedSkillsContent(agentName, configService, projectRoo
|
|
|
28420
27912
|
if (autoLoadSkills.length === 0) {
|
|
28421
27913
|
return "";
|
|
28422
27914
|
}
|
|
28423
|
-
const homeDir = process.env.HOME ||
|
|
27915
|
+
const homeDir = process.env.HOME || os4.homedir();
|
|
28424
27916
|
const skillTemplates = [];
|
|
28425
27917
|
for (const skillId of autoLoadSkills) {
|
|
28426
27918
|
const builtinSkill = BUILTIN_SKILLS.find((entry) => entry.name === skillId);
|
|
@@ -28502,14 +27994,11 @@ var plugin = async (ctx) => {
|
|
|
28502
27994
|
const disabledMcps = configService.getDisabledMcps();
|
|
28503
27995
|
const disabledSkills = configService.getDisabledSkills();
|
|
28504
27996
|
const builtinMcps = createBuiltinMcps(disabledMcps);
|
|
28505
|
-
if (configService.get().autoInstallDeps !== false) {
|
|
28506
|
-
ensurePluginDeps();
|
|
28507
|
-
}
|
|
28508
27997
|
const filteredSkills = getFilteredSkills(disabledSkills);
|
|
28509
27998
|
const effectiveAutoLoadSkills = configService.getAgentConfig("zetta").autoLoadSkills ?? [];
|
|
28510
27999
|
const worktreeService = new WorktreeService({
|
|
28511
28000
|
baseDir: directory,
|
|
28512
|
-
hiveDir:
|
|
28001
|
+
hiveDir: path11.join(directory, ".hive")
|
|
28513
28002
|
});
|
|
28514
28003
|
const isOmoSlimEnabled = () => {
|
|
28515
28004
|
return configService.isOmoSlimEnabled();
|
|
@@ -28536,7 +28025,7 @@ var plugin = async (ctx) => {
|
|
|
28536
28025
|
};
|
|
28537
28026
|
const checkBlocked = (feature) => {
|
|
28538
28027
|
const fs12 = __require("fs");
|
|
28539
|
-
const blockedPath =
|
|
28028
|
+
const blockedPath = path11.join(directory, ".hive", "features", feature, "BLOCKED");
|
|
28540
28029
|
if (fs12.existsSync(blockedPath)) {
|
|
28541
28030
|
const reason = fs12.readFileSync(blockedPath, "utf-8").trim();
|
|
28542
28031
|
return `⛔ BLOCKED by Beekeeper
|
|
@@ -28690,9 +28179,9 @@ To unblock: Remove .hive/features/${feature}/BLOCKED`;
|
|
|
28690
28179
|
spec: specContent,
|
|
28691
28180
|
workerPrompt
|
|
28692
28181
|
});
|
|
28693
|
-
const hiveDir =
|
|
28182
|
+
const hiveDir = path11.join(directory, ".hive");
|
|
28694
28183
|
const workerPromptPath = writeWorkerPromptFile(feature, task, workerPrompt, hiveDir);
|
|
28695
|
-
const relativePromptPath = normalizePath(
|
|
28184
|
+
const relativePromptPath = normalizePath(path11.relative(directory, workerPromptPath));
|
|
28696
28185
|
const PREVIEW_MAX_LENGTH = 200;
|
|
28697
28186
|
const workerPromptPreview = workerPrompt.length > PREVIEW_MAX_LENGTH ? workerPrompt.slice(0, PREVIEW_MAX_LENGTH) + "..." : workerPrompt;
|
|
28698
28187
|
const taskToolPrompt = `Follow instructions in @${relativePromptPath}`;
|
|
@@ -29100,7 +28589,7 @@ ${snapshot}
|
|
|
29100
28589
|
if (sandboxConfig.mode !== "none") {
|
|
29101
28590
|
const workdir = output.args?.workdir;
|
|
29102
28591
|
if (workdir) {
|
|
29103
|
-
const hiveWorktreeBase =
|
|
28592
|
+
const hiveWorktreeBase = path11.join(directory, ".hive", ".worktrees");
|
|
29104
28593
|
if (workdir.startsWith(hiveWorktreeBase)) {
|
|
29105
28594
|
const wrapped = DockerSandboxService.wrapCommand(workdir, finalCommand, sandboxConfig);
|
|
29106
28595
|
output.args.command = wrapped;
|
|
@@ -29169,12 +28658,6 @@ ${snapshot}
|
|
|
29169
28658
|
hive_vector_search: hiveVectorSearchTool,
|
|
29170
28659
|
hive_vector_add: hiveVectorAddTool,
|
|
29171
28660
|
hive_vector_status: hiveVectorStatusTool,
|
|
29172
|
-
ast_grep_dump_syntax_tree: astGrepDumpSyntaxTreeTool,
|
|
29173
|
-
ast_grep_test_match_code_rule: astGrepTestMatchCodeRuleTool,
|
|
29174
|
-
ast_grep_find_code: astGrepFindCodeTool,
|
|
29175
|
-
ast_grep_scan_code: astGrepScanCodeTool,
|
|
29176
|
-
ast_grep_rewrite_code: astGrepRewriteCodeTool,
|
|
29177
|
-
ast_grep_analyze_imports: astGrepAnalyzeImportsTool,
|
|
29178
28661
|
hive_doctor: hiveDoctorTool,
|
|
29179
28662
|
hive_doctor_quick: hiveDoctorQuickTool,
|
|
29180
28663
|
dora_status: doraStatusTool,
|
|
@@ -29187,6 +28670,12 @@ ${snapshot}
|
|
|
29187
28670
|
auto_cr_scan: autoCrScanTool,
|
|
29188
28671
|
auto_cr_diff: autoCrDiffTool,
|
|
29189
28672
|
auto_cr_rules: autoCrRulesTool,
|
|
28673
|
+
ast_grep_dump_syntax_tree: astGrepDumpSyntaxTreeTool,
|
|
28674
|
+
ast_grep_test_match_code_rule: astGrepTestMatchCodeRuleTool,
|
|
28675
|
+
ast_grep_find_code: astGrepFindCodeTool,
|
|
28676
|
+
ast_grep_scan_code: astGrepScanCodeTool,
|
|
28677
|
+
ast_grep_rewrite_code: astGrepRewriteCodeTool,
|
|
28678
|
+
ast_grep_analyze_imports: astGrepAnalyzeImportsTool,
|
|
29190
28679
|
hive_skill: createHiveSkillTool(filteredSkills),
|
|
29191
28680
|
hive_feature_create: tool({
|
|
29192
28681
|
description: "Create a new feature and set it as active",
|