@maxgfr/codeindex 2.19.0 → 2.19.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maxgfr/codeindex",
3
- "version": "2.19.0",
3
+ "version": "2.19.1",
4
4
  "description": "Self-contained, deterministic repo-indexing engine: walk + language detection + symbol/import extraction (tree-sitter AST with regex fallback) + import resolution + typed cross-file link-graph + analytics. Ships as a single zero-dependency engine.mjs that consumer tools vendor.",
5
5
  "type": "module",
6
6
  "packageManager": "pnpm@10.33.0",
@@ -1,4 +1,4 @@
1
- declare const ENGINE_VERSION = "2.19.0";
1
+ declare const ENGINE_VERSION = "2.19.1";
2
2
  declare const SCHEMA_VERSION = 4;
3
3
  declare const EXTRACTOR_VERSION = 10;
4
4
  type FileKind = "code" | "doc" | "config" | "asset" | "other";
@@ -347,7 +347,7 @@ declare function extractAst(rel: string, ext: string, content: string, opts?: {
347
347
  imports?: boolean;
348
348
  }): AstResult | undefined;
349
349
 
350
- declare const DEFAULT_GRAMMARS_URL = "https://github.com/maxgfr/codeindex/releases/download/v2.19.0/grammars-2.19.0.tar.gz";
350
+ declare const DEFAULT_GRAMMARS_URL = "https://github.com/maxgfr/codeindex/releases/download/v2.19.1/grammars-2.19.1.tar.gz";
351
351
  interface GrammarsPullTarget {
352
352
  url: string;
353
353
  sha256Url?: string;
@@ -14,7 +14,7 @@ var ENGINE_VERSION, SCHEMA_VERSION, EXTRACTOR_VERSION;
14
14
  var init_types = __esm({
15
15
  "src/types.ts"() {
16
16
  "use strict";
17
- ENGINE_VERSION = "2.19.0";
17
+ ENGINE_VERSION = "2.19.1";
18
18
  SCHEMA_VERSION = 4;
19
19
  EXTRACTOR_VERSION = 10;
20
20
  }
@@ -12539,6 +12539,7 @@ function neighborsOf(graph, target, depth = 1, kinds) {
12539
12539
  // src/delta.ts
12540
12540
  init_git();
12541
12541
  init_sort();
12542
+ init_walk();
12542
12543
  init_util();
12543
12544
  var RISK_WEIGHTS = {
12544
12545
  exportedChange: 25,
@@ -12648,6 +12649,16 @@ function computeDelta(graph, symbols, diff, depth = DEFAULT_DELTA_DEPTH) {
12648
12649
  }
12649
12650
  const changedRels = new Set(changes.filter((c2) => c2.status !== "deleted").map((c2) => c2.path));
12650
12651
  const dangling = graph.fileEdges.filter((e) => e.dangling && (e.kind === "import" || e.kind === "doc-link") && changedRels.has(e.from)).map((e) => ({ from: e.from, spec: e.to, reason: e.reason ?? "unknown" })).sort((a, b) => byStr(a.from, b.from) || byStr(a.spec, b.spec));
12652
+ const intoIgnoredTree = (from, spec) => {
12653
+ if (!spec.startsWith(".")) return false;
12654
+ const segs = from.split("/").slice(0, -1);
12655
+ for (const part of spec.split("/")) {
12656
+ if (part === "." || part === "") continue;
12657
+ if (part === "..") segs.pop();
12658
+ else segs.push(part);
12659
+ }
12660
+ return segs.some((seg) => IGNORE_DIRS.has(seg));
12661
+ };
12651
12662
  const byModule = /* @__PURE__ */ new Map();
12652
12663
  for (const c2 of changes) {
12653
12664
  if (c2.status === "deleted" || !c2.module) continue;
@@ -12717,7 +12728,9 @@ function computeDelta(graph, symbols, diff, depth = DEFAULT_DELTA_DEPTH) {
12717
12728
  score += RISK_WEIGHTS.surprise;
12718
12729
  reasons.push(`cross-community edge to ${sup.from === slug ? sup.to : sup.from} (surprising)`);
12719
12730
  }
12720
- const moduleDangling = dangling.filter((d) => moduleChanges.some((c2) => c2.path === d.from));
12731
+ const moduleDangling = dangling.filter(
12732
+ (d) => moduleChanges.some((c2) => c2.path === d.from) && !intoIgnoredTree(d.from, d.spec)
12733
+ );
12721
12734
  if (moduleDangling.length) {
12722
12735
  score += RISK_WEIGHTS.dangling;
12723
12736
  const first = moduleDangling[0];
package/src/delta.ts CHANGED
@@ -9,6 +9,7 @@ import type { Graph, ModuleNode, SymbolIndex } from "./types.js";
9
9
  import type { DiffFile, DiffSpec, Hunk } from "./git.js";
10
10
  import { isGitWorktree, resolveBaseRef, diffFiles, diffHunks, untrackedFiles } from "./git.js";
11
11
  import { byStr } from "./sort.js";
12
+ import { IGNORE_DIRS } from "./walk.js";
12
13
  import { have, sh } from "./util.js";
13
14
  import { impactOf } from "./traverse.js";
14
15
 
@@ -208,6 +209,24 @@ export function computeDelta(
208
209
  .map((e) => ({ from: e.from, spec: e.to, reason: e.reason ?? "unknown" }))
209
210
  .sort((a, b) => byStr(a.from, b.from) || byStr(a.spec, b.spec));
210
211
 
212
+ // A relative import whose target lands in a directory the walker ignores
213
+ // (vendor/, dist/, build/ …) is reported as dangling because the resolver only
214
+ // looks inside the scan — but the file is there and the import works. It is a
215
+ // blind spot in the graph, not a broken reference, so it must NOT carry the
216
+ // dangling RISK weight: a repo that vendors a dependency would otherwise take
217
+ // a permanent penalty on every change to the file that imports it. Still
218
+ // listed above, so the blind spot stays visible.
219
+ const intoIgnoredTree = (from: string, spec: string): boolean => {
220
+ if (!spec.startsWith(".")) return false;
221
+ const segs = from.split("/").slice(0, -1);
222
+ for (const part of spec.split("/")) {
223
+ if (part === "." || part === "") continue;
224
+ if (part === "..") segs.pop();
225
+ else segs.push(part);
226
+ }
227
+ return segs.some((seg) => IGNORE_DIRS.has(seg));
228
+ };
229
+
211
230
  // Group by module and score.
212
231
  const byModule = new Map<string, DeltaChange[]>();
213
232
  for (const c of changes) {
@@ -296,7 +315,9 @@ export function computeDelta(
296
315
  }
297
316
 
298
317
  // 6. Dangling imports from this module's changed files.
299
- const moduleDangling = dangling.filter((d) => moduleChanges.some((c) => c.path === d.from));
318
+ const moduleDangling = dangling.filter(
319
+ (d) => moduleChanges.some((c) => c.path === d.from) && !intoIgnoredTree(d.from, d.spec),
320
+ );
300
321
  if (moduleDangling.length) {
301
322
  score += RISK_WEIGHTS.dangling;
302
323
  const first = moduleDangling[0]!;
package/src/types.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  // Single source of truth for the engine version the bundle reports. Kept in
2
2
  // lockstep with package.json by the release pipeline. Do not edit by hand
3
3
  // outside a release.
4
- export const ENGINE_VERSION = "2.19.0";
4
+ export const ENGINE_VERSION = "2.19.1";
5
5
 
6
6
  // Bumped whenever the on-disk artifact shape changes, so a consumer can reject
7
7
  // an index written by an incompatible engine instead of misreading it. The