scip-query 0.4.0 → 0.4.2

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.
Files changed (92) hide show
  1. package/README.md +1 -1
  2. package/dist/{chunk-HNURMDF4.js → chunk-24LF6IZB.js} +3 -3
  3. package/dist/{chunk-IV6NZ426.js → chunk-3NJSJ7TE.js} +3 -3
  4. package/dist/{chunk-H3FPW5YN.js → chunk-43A4UCS7.js} +3 -3
  5. package/dist/{chunk-A5BGEBM7.js → chunk-5GCORUNV.js} +3 -3
  6. package/dist/{chunk-I2JM34UV.js → chunk-6CH23IAS.js} +4 -4
  7. package/dist/{chunk-5AJJGPZE.js → chunk-6ECR2FLR.js} +3 -3
  8. package/dist/{chunk-2UISVZGQ.js → chunk-6UZU7DFL.js} +3 -3
  9. package/dist/{chunk-NWCJWA36.js → chunk-7BS4CPJX.js} +5 -5
  10. package/dist/{chunk-QCYR4S6T.js → chunk-A6XLXV6W.js} +3 -3
  11. package/dist/{chunk-QGCEAVJD.js → chunk-ALUFWH3U.js} +232 -66
  12. package/dist/{chunk-CQRYLK33.js → chunk-CBIWNZZZ.js} +3 -3
  13. package/dist/{chunk-N2LH3M2P.js → chunk-DUJNJQPO.js} +3 -3
  14. package/dist/{chunk-XH56HXLC.js → chunk-EAGKJFDX.js} +3 -3
  15. package/dist/{chunk-SL674KAW.js → chunk-ELFGD5EW.js} +3 -3
  16. package/dist/{chunk-GIBETK3W.js → chunk-FVJE4MQL.js} +3 -3
  17. package/dist/{chunk-CQUNEJYM.js → chunk-GNAMV3JC.js} +3 -3
  18. package/dist/{chunk-VCOJRQPP.js → chunk-J47VSL6I.js} +3 -3
  19. package/dist/{chunk-7YBLWIXY.js → chunk-J6QXMYAQ.js} +3 -3
  20. package/dist/{chunk-2F2WH5WQ.js → chunk-JHVQB4Y5.js} +12 -12
  21. package/dist/{chunk-X3J4VPWM.js → chunk-JKXHHV4B.js} +2 -2
  22. package/dist/{chunk-4ZT7UGWW.js → chunk-KG4OFQEN.js} +3 -3
  23. package/dist/{chunk-SRELHCMG.js → chunk-KLNKDX6A.js} +4 -4
  24. package/dist/{chunk-LOVDB4C6.js → chunk-KYPXKV64.js} +3 -3
  25. package/dist/{chunk-UTRKBUCB.js → chunk-NXUIWD6K.js} +3 -3
  26. package/dist/{chunk-VU7FDTWV.js → chunk-OXX3QF24.js} +2 -2
  27. package/dist/{chunk-7HK5ZLOE.js → chunk-PCU455MX.js} +2 -2
  28. package/dist/{chunk-A4GWYETB.js → chunk-POLELLNM.js} +3 -3
  29. package/dist/{chunk-AS7N27JK.js → chunk-PU2254N2.js} +3 -3
  30. package/dist/{chunk-WNPF2I25.js → chunk-QMXSLHZP.js} +2 -2
  31. package/dist/{chunk-PGHN5UTM.js → chunk-R7HPHMRZ.js} +3 -3
  32. package/dist/{chunk-VUBLUTMU.js → chunk-RE7POFGI.js} +2 -2
  33. package/dist/{chunk-KDCQJTYW.js → chunk-RJ5GULL6.js} +2 -2
  34. package/dist/{chunk-HRDPUTIQ.js → chunk-RL74LF47.js} +2 -2
  35. package/dist/{chunk-5RKYZSQ6.js → chunk-SVLUJSY7.js} +3 -3
  36. package/dist/{chunk-D4I3ZMN5.js → chunk-SYQR4QGK.js} +3 -3
  37. package/dist/{chunk-QIXNAB5K.js → chunk-TO3L4YNK.js} +1 -2
  38. package/dist/{chunk-P42KQKJZ.js → chunk-TWVXFKJA.js} +4 -4
  39. package/dist/{chunk-MA3B3IUT.js → chunk-UJWI5CBB.js} +3 -3
  40. package/dist/{chunk-E7J7Q7UW.js → chunk-VKBOLNYN.js} +3 -3
  41. package/dist/{chunk-RIEA5DOB.js → chunk-VY2L4TP6.js} +3 -3
  42. package/dist/{chunk-A7YY7IDA.js → chunk-W46L2BXT.js} +2 -2
  43. package/dist/{chunk-VISMEWYP.js → chunk-XUVPQDXW.js} +4 -4
  44. package/dist/{chunk-ZU2AQQB5.js → chunk-Z5VSUOEE.js} +2 -2
  45. package/dist/{chunk-EOHPASDV.js → chunk-ZVZAIIB5.js} +3 -3
  46. package/dist/cli.js +516 -179
  47. package/dist/index.d.ts +18 -1
  48. package/dist/index.js +239 -70
  49. package/dist/queries/affected.js +3 -3
  50. package/dist/queries/bottlenecks.js +3 -3
  51. package/dist/queries/by-kind.js +3 -3
  52. package/dist/queries/call-graph.js +3 -3
  53. package/dist/queries/change-surface.js +3 -3
  54. package/dist/queries/code.js +3 -3
  55. package/dist/queries/complexity-hotspots.js +3 -3
  56. package/dist/queries/complexity.js +3 -3
  57. package/dist/queries/convergence.js +3 -3
  58. package/dist/queries/coupling.js +3 -3
  59. package/dist/queries/cycles.js +3 -3
  60. package/dist/queries/dataflow.js +3 -3
  61. package/dist/queries/dead.js +4 -4
  62. package/dist/queries/deep-chains.js +3 -3
  63. package/dist/queries/deps.js +3 -3
  64. package/dist/queries/diff-impact.js +2 -2
  65. package/dist/queries/drift.js +3 -3
  66. package/dist/queries/extract-candidates.js +3 -3
  67. package/dist/queries/fan.js +3 -3
  68. package/dist/queries/health.js +14 -14
  69. package/dist/queries/hierarchy.js +3 -3
  70. package/dist/queries/hotspots.js +3 -3
  71. package/dist/queries/imports.js +3 -3
  72. package/dist/queries/index.js +44 -44
  73. package/dist/queries/isolated.js +4 -4
  74. package/dist/queries/members.js +3 -3
  75. package/dist/queries/methods.js +3 -3
  76. package/dist/queries/outline.js +3 -3
  77. package/dist/queries/passthrough-candidates.js +3 -3
  78. package/dist/queries/redundant-reexports.js +4 -4
  79. package/dist/queries/refs.js +3 -3
  80. package/dist/queries/similar-chains.js +3 -3
  81. package/dist/queries/similar-files.js +3 -3
  82. package/dist/queries/similar-signatures.js +3 -3
  83. package/dist/queries/similar.js +3 -3
  84. package/dist/queries/slice.js +3 -3
  85. package/dist/queries/stale-abstractions.js +3 -3
  86. package/dist/queries/surface.js +3 -3
  87. package/dist/queries/symbols.js +3 -3
  88. package/dist/queries/system.js +3 -3
  89. package/dist/queries/trace.js +3 -3
  90. package/dist/queries/wrapper-candidates.js +3 -3
  91. package/dist/reindex-worker.js +149 -7
  92. package/package.json +7 -1
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  system
3
- } from "../chunk-A4GWYETB.js";
3
+ } from "../chunk-POLELLNM.js";
4
4
  import "../chunk-4TYLS5XX.js";
5
- import "../chunk-QGCEAVJD.js";
6
- import "../chunk-QIXNAB5K.js";
5
+ import "../chunk-ALUFWH3U.js";
6
+ import "../chunk-TO3L4YNK.js";
7
7
  export {
8
8
  system
9
9
  };
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  trace
3
- } from "../chunk-EOHPASDV.js";
3
+ } from "../chunk-ZVZAIIB5.js";
4
4
  import "../chunk-4TYLS5XX.js";
5
- import "../chunk-QGCEAVJD.js";
6
- import "../chunk-QIXNAB5K.js";
5
+ import "../chunk-ALUFWH3U.js";
6
+ import "../chunk-TO3L4YNK.js";
7
7
  export {
8
8
  trace
9
9
  };
@@ -1,8 +1,8 @@
1
1
  import {
2
2
  wrapperCandidates
3
- } from "../chunk-AS7N27JK.js";
4
- import "../chunk-QGCEAVJD.js";
5
- import "../chunk-QIXNAB5K.js";
3
+ } from "../chunk-PU2254N2.js";
4
+ import "../chunk-ALUFWH3U.js";
5
+ import "../chunk-TO3L4YNK.js";
6
6
  export {
7
7
  wrapperCandidates
8
8
  };
@@ -11,8 +11,8 @@ import {
11
11
 
12
12
  // src/reindex/index.ts
13
13
  import { execFileSync } from "child_process";
14
- import { existsSync as existsSync3, renameSync } from "fs";
15
- import { join as join3 } from "path";
14
+ import { existsSync as existsSync3, renameSync, rmSync } from "fs";
15
+ import { basename, dirname, extname as extname2, join as join3 } from "path";
16
16
 
17
17
  // src/reindex/detect.ts
18
18
  import { existsSync, readdirSync } from "fs";
@@ -390,6 +390,128 @@ function resolveDotnetProject(projectRoot2, suffixes) {
390
390
  return null;
391
391
  }
392
392
 
393
+ // src/reindex/merge.ts
394
+ import { readFileSync, writeFileSync } from "fs";
395
+ import { create } from "@bufbuild/protobuf";
396
+ import {
397
+ deserializeSCIP,
398
+ serializeSCIP,
399
+ DocumentSchema,
400
+ IndexSchema,
401
+ SymbolInformationSchema
402
+ } from "@c4312/scip";
403
+ function mergeScipIndexes(indexes) {
404
+ if (indexes.length === 0) {
405
+ throw new Error("Cannot merge zero SCIP indexes");
406
+ }
407
+ if (indexes.length === 1) {
408
+ return indexes[0];
409
+ }
410
+ const metadata = mergeMetadata(indexes);
411
+ const documents = mergeDocuments(indexes.flatMap((index) => index.documents ?? []));
412
+ const externalSymbols = mergeSymbolInfos(indexes.flatMap((index) => index.externalSymbols ?? []));
413
+ return create(IndexSchema, {
414
+ metadata,
415
+ documents,
416
+ externalSymbols
417
+ });
418
+ }
419
+ function mergeScipFiles(inputPaths, outputPath) {
420
+ if (inputPaths.length === 0) {
421
+ throw new Error("Cannot merge zero SCIP files");
422
+ }
423
+ const indexes = inputPaths.map((path) => deserializeSCIP(readFileSync(path)));
424
+ const merged = mergeScipIndexes(indexes);
425
+ writeFileSync(outputPath, Buffer.from(serializeSCIP(merged)));
426
+ return {
427
+ documentCount: merged.documents.length,
428
+ externalSymbolCount: merged.externalSymbols.length,
429
+ inputCount: inputPaths.length
430
+ };
431
+ }
432
+ function mergeMetadata(indexes) {
433
+ const first = indexes[0]?.metadata;
434
+ if (!first) {
435
+ return void 0;
436
+ }
437
+ const expectedProjectRoot = first.projectRoot;
438
+ for (const index of indexes.slice(1)) {
439
+ const actualProjectRoot = index.metadata?.projectRoot;
440
+ if (expectedProjectRoot && actualProjectRoot && actualProjectRoot !== expectedProjectRoot) {
441
+ throw new Error(
442
+ `Cannot merge SCIP indexes with different project roots: ${expectedProjectRoot} vs ${actualProjectRoot}`
443
+ );
444
+ }
445
+ }
446
+ return first;
447
+ }
448
+ function mergeDocuments(documents) {
449
+ const byPath = /* @__PURE__ */ new Map();
450
+ for (const document of documents) {
451
+ const existing = byPath.get(document.relativePath);
452
+ if (!existing) {
453
+ byPath.set(document.relativePath, document);
454
+ continue;
455
+ }
456
+ byPath.set(document.relativePath, create(DocumentSchema, {
457
+ language: existing.language || document.language,
458
+ relativePath: existing.relativePath || document.relativePath,
459
+ occurrences: [...existing.occurrences, ...document.occurrences],
460
+ symbols: mergeSymbolInfos([...existing.symbols, ...document.symbols]),
461
+ text: chooseText(existing.text, document.text),
462
+ positionEncoding: existing.positionEncoding || document.positionEncoding
463
+ }));
464
+ }
465
+ return [...byPath.values()];
466
+ }
467
+ function mergeSymbolInfos(symbols) {
468
+ const bySymbol = /* @__PURE__ */ new Map();
469
+ for (const symbol of symbols) {
470
+ const existing = bySymbol.get(symbol.symbol);
471
+ if (!existing) {
472
+ bySymbol.set(symbol.symbol, symbol);
473
+ continue;
474
+ }
475
+ bySymbol.set(symbol.symbol, create(SymbolInformationSchema, {
476
+ symbol: existing.symbol,
477
+ documentation: uniqueStrings([...existing.documentation, ...symbol.documentation]),
478
+ relationships: mergeRelationships([...existing.relationships, ...symbol.relationships]),
479
+ kind: existing.kind || symbol.kind,
480
+ displayName: existing.displayName || symbol.displayName,
481
+ enclosingSymbol: existing.enclosingSymbol || symbol.enclosingSymbol,
482
+ signatureDocumentation: existing.signatureDocumentation ?? symbol.signatureDocumentation
483
+ }));
484
+ }
485
+ return [...bySymbol.values()];
486
+ }
487
+ function mergeRelationships(relationships) {
488
+ const seen = /* @__PURE__ */ new Set();
489
+ const merged = [];
490
+ for (const relationship of relationships) {
491
+ const key = [
492
+ relationship.symbol,
493
+ relationship.isReference ? "1" : "0",
494
+ relationship.isImplementation ? "1" : "0",
495
+ relationship.isTypeDefinition ? "1" : "0",
496
+ relationship.isDefinition ? "1" : "0"
497
+ ].join("|");
498
+ if (seen.has(key)) {
499
+ continue;
500
+ }
501
+ seen.add(key);
502
+ merged.push(relationship);
503
+ }
504
+ return merged;
505
+ }
506
+ function chooseText(left, right) {
507
+ if (!left) return right;
508
+ if (!right) return left;
509
+ return left.length >= right.length ? left : right;
510
+ }
511
+ function uniqueStrings(values) {
512
+ return [...new Set(values)];
513
+ }
514
+
393
515
  // src/reindex/index.ts
394
516
  async function reindex(opts) {
395
517
  const {
@@ -425,7 +547,11 @@ async function reindex(opts) {
425
547
  ...process.env,
426
548
  NODE_OPTIONS: `--max-old-space-size=${maxHeapMb}`
427
549
  };
428
- for (const lang of languages2) {
550
+ const languageOutputs = languages2.map((language, index) => ({
551
+ language,
552
+ scipPath: languages2.length > 1 ? tempScipPath(outputScip2, language, index) : outputScip2
553
+ }));
554
+ for (const { language: lang, scipPath } of languageOutputs) {
429
555
  const config = getIndexerConfig(lang);
430
556
  const binaryLabel = describeIndexerBinary(config);
431
557
  const projectLocalBinary = resolveProjectLocalIndexerBinary(config, projectRoot2);
@@ -455,7 +581,7 @@ async function reindex(opts) {
455
581
  const indexerEnv = getIndexerExecutionEnv(config, env, resolvedBinary);
456
582
  const { binary, args } = config.indexArgs({
457
583
  projectRoot: projectRoot2,
458
- outputPath: outputScip2,
584
+ outputPath: scipPath,
459
585
  pnpmWorkspaces: opts.pnpmWorkspaces,
460
586
  indexerBinary: resolvedBinary
461
587
  });
@@ -470,10 +596,15 @@ async function reindex(opts) {
470
596
  const msg = err instanceof Error ? err.message : String(err);
471
597
  throw new Error(
472
598
  `Failed to index ${lang} with ${resolvedBinary}: ${msg}
473
- Make sure ${binaryLabel} is installed and available on PATH.`
599
+ Make sure ${binaryLabel} is installed and available on PATH.`,
600
+ { cause: err }
474
601
  );
475
602
  }
476
- moveDefaultOutputIfNeeded(config, projectRoot2, outputScip2);
603
+ moveDefaultOutputIfNeeded(config, projectRoot2, scipPath);
604
+ }
605
+ if (languageOutputs.length > 1) {
606
+ onStatus(`Merging ${languageOutputs.length} language indexes...`);
607
+ mergeScipFiles(languageOutputs.map((entry) => entry.scipPath), outputScip2);
477
608
  }
478
609
  onStatus("Converting to SQLite...");
479
610
  if (!existsSync3(outputScip2)) {
@@ -487,7 +618,13 @@ Make sure ${binaryLabel} is installed and available on PATH.`
487
618
  });
488
619
  } catch (err) {
489
620
  const msg = err instanceof Error ? err.message : String(err);
490
- throw new Error(`Failed to convert SCIP index to SQLite: ${msg}`);
621
+ throw new Error(`Failed to convert SCIP index to SQLite: ${msg}`, { cause: err });
622
+ } finally {
623
+ for (const { scipPath } of languageOutputs) {
624
+ if (scipPath !== outputScip2) {
625
+ rmSync(scipPath, { force: true });
626
+ }
627
+ }
491
628
  }
492
629
  const durationMs = Date.now() - start;
493
630
  onStatus(`Done in ${(durationMs / 1e3).toFixed(1)}s`);
@@ -502,6 +639,11 @@ function moveDefaultOutputIfNeeded(config, projectRoot2, outputScip2) {
502
639
  renameSync(defaultOutputPath, outputScip2);
503
640
  }
504
641
  }
642
+ function tempScipPath(outputScip2, language, index) {
643
+ const extension = extname2(outputScip2) || ".scip";
644
+ const stem = basename(outputScip2, extension);
645
+ return join3(dirname(outputScip2), `${stem}.${index + 1}.${language}${extension}`);
646
+ }
505
647
 
506
648
  // src/reindex-worker.ts
507
649
  var projectRoot = process.env["SCIP_REINDEX_PROJECT_ROOT"];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "scip-query",
3
- "version": "0.4.0",
3
+ "version": "0.4.2",
4
4
  "description": "Language-agnostic code intelligence CLI powered by SCIP indexes",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -60,16 +60,22 @@
60
60
  "node": ">=18.0.0"
61
61
  },
62
62
  "dependencies": {
63
+ "@bufbuild/protobuf": "^2.11.0",
64
+ "@c4312/scip": "^0.1.0",
63
65
  "better-sqlite3": "^11.7.0",
64
66
  "commander": "^13.1.0",
65
67
  "ignore": "^7.0.3"
66
68
  },
67
69
  "devDependencies": {
70
+ "@eslint/js": "^10.0.1",
68
71
  "@sourcegraph/scip-typescript": "^0.4.0",
69
72
  "@types/better-sqlite3": "^7.6.12",
70
73
  "@types/node": "^22.10.0",
74
+ "eslint": "^10.2.0",
75
+ "globals": "^17.5.0",
71
76
  "tsup": "^8.3.0",
72
77
  "typescript": "^5.7.0",
78
+ "typescript-eslint": "^8.58.1",
73
79
  "vitest": "^3.0.0"
74
80
  }
75
81
  }