@mneme-ai/xray 2.150.0 → 2.152.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (42) hide show
  1. package/dist/battery/busfactor.d.ts.map +1 -1
  2. package/dist/battery/busfactor.js +24 -8
  3. package/dist/battery/busfactor.js.map +1 -1
  4. package/dist/battery/coupling.d.ts +3 -0
  5. package/dist/battery/coupling.d.ts.map +1 -0
  6. package/dist/battery/coupling.js +61 -0
  7. package/dist/battery/coupling.js.map +1 -0
  8. package/dist/battery/deps.d.ts +2 -0
  9. package/dist/battery/deps.d.ts.map +1 -1
  10. package/dist/battery/deps.js +34 -7
  11. package/dist/battery/deps.js.map +1 -1
  12. package/dist/battery/hotspots.d.ts.map +1 -1
  13. package/dist/battery/hotspots.js +54 -15
  14. package/dist/battery/hotspots.js.map +1 -1
  15. package/dist/bin.js +27 -0
  16. package/dist/bin.js.map +1 -1
  17. package/dist/bridge.d.ts +2 -0
  18. package/dist/bridge.d.ts.map +1 -0
  19. package/dist/bridge.js +89 -0
  20. package/dist/bridge.js.map +1 -0
  21. package/dist/clone.d.ts.map +1 -1
  22. package/dist/clone.js +2 -1
  23. package/dist/clone.js.map +1 -1
  24. package/dist/engine.d.ts.map +1 -1
  25. package/dist/engine.js +17 -4
  26. package/dist/engine.js.map +1 -1
  27. package/dist/gauntlet.d.ts.map +1 -1
  28. package/dist/gauntlet.js +3 -2
  29. package/dist/gauntlet.js.map +1 -1
  30. package/dist/index.d.ts +3 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +3 -0
  33. package/dist/index.js.map +1 -1
  34. package/dist/server.d.ts.map +1 -1
  35. package/dist/server.js +27 -6
  36. package/dist/server.js.map +1 -1
  37. package/dist/types.d.ts +30 -2
  38. package/dist/types.d.ts.map +1 -1
  39. package/package.json +3 -2
  40. package/public/card.js +33 -8
  41. package/public/index.html +44 -1
  42. package/public/report.html +5 -1
@@ -1 +1 @@
1
- {"version":3,"file":"busfactor.d.ts","sourceRoot":"","sources":["../../src/battery/busfactor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAsEjE"}
1
+ {"version":3,"file":"busfactor.d.ts","sourceRoot":"","sources":["../../src/battery/busfactor.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAKlD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,cAAc,CAuFjE"}
@@ -12,18 +12,38 @@ export function analyzeBusFactor(repoPath) {
12
12
  return emptyBlock("Not a git repository — authorship/bus-factor signals unavailable.");
13
13
  // One line per (commit, file): "<authorEmail>\t<file>". --no-renames keeps paths stable.
14
14
  const raw = git(repoPath, [
15
- "log", "--no-merges", "--pretty=format:C%H%x09%ae", "--name-only", "-n", "4000",
15
+ "log", "--no-merges", "--no-renames", "--pretty=format:C%H%x09%ae", "--name-only", "-n", "3000",
16
16
  ]);
17
17
  if (!raw.trim()) {
18
18
  return emptyBlock("No commit history available.");
19
19
  }
20
+ // A commit touching a huge number of files is a merge/vendoring/generated
21
+ // sweep — it does NOT signal real per-file ownership and, on monorepos like
22
+ // mattermost (22k commits), folding it makes the map explode (~120s → ~3s).
23
+ // We still count it toward author totals; we just skip it for file-ownership.
24
+ const MAX_FILES_PER_COMMIT = 100;
20
25
  const fileAuthors = new Map(); // file -> author -> commits
21
26
  const authorCommits = new Map(); // author -> total commits
22
27
  const allAuthors = new Set();
23
28
  let curAuthor = "";
29
+ let curFiles = [];
24
30
  let totalCommits = 0;
31
+ const flush = () => {
32
+ if (curAuthor && curFiles.length > 0 && curFiles.length <= MAX_FILES_PER_COMMIT) {
33
+ for (const file of curFiles) {
34
+ let m = fileAuthors.get(file);
35
+ if (!m) {
36
+ m = new Map();
37
+ fileAuthors.set(file, m);
38
+ }
39
+ m.set(curAuthor, (m.get(curAuthor) ?? 0) + 1);
40
+ }
41
+ }
42
+ curFiles = [];
43
+ };
25
44
  for (const line of raw.split("\n")) {
26
45
  if (line.startsWith("C")) {
46
+ flush();
27
47
  const tab = line.indexOf("\t");
28
48
  curAuthor = tab >= 0 ? line.slice(tab + 1).trim() : "";
29
49
  if (curAuthor) {
@@ -34,15 +54,11 @@ export function analyzeBusFactor(repoPath) {
34
54
  continue;
35
55
  }
36
56
  const file = line.trim();
37
- if (!file || SKIP_DIR.test(file) || !curAuthor)
57
+ if (!file || SKIP_DIR.test(file))
38
58
  continue;
39
- let m = fileAuthors.get(file);
40
- if (!m) {
41
- m = new Map();
42
- fileAuthors.set(file, m);
43
- }
44
- m.set(curAuthor, (m.get(curAuthor) ?? 0) + 1);
59
+ curFiles.push(file);
45
60
  }
61
+ flush();
46
62
  if (totalCommits === 0)
47
63
  return emptyBlock("No authored commits found.");
48
64
  let singleOwner = 0;
@@ -1 +1 @@
1
- {"version":3,"file":"busfactor.js","sourceRoot":"","sources":["../../src/battery/busfactor.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAG5C,MAAM,QAAQ,GAAG,oEAAoE,CAAC;AACtF,MAAM,SAAS,GAAG,GAAG,CAAC,CAAC,2EAA2E;AAElG,MAAM,UAAU,gBAAgB,CAAC,QAAgB;IAC/C,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAC,mEAAmE,CAAC,CAAC;IACjH,yFAAyF;IACzF,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,EAAE;QACxB,KAAK,EAAE,aAAa,EAAE,4BAA4B,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM;KAChF,CAAC,CAAC;IACH,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;QAChB,OAAO,UAAU,CAAC,8BAA8B,CAAC,CAAC;IACpD,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAA+B,CAAC,CAAC,4BAA4B;IACxF,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC,CAAC,0BAA0B;IAC3E,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,SAAS,GAAG,EAAE,CAAC;IACnB,IAAI,YAAY,GAAG,CAAC,CAAC;IAErB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC/B,SAAS,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvD,IAAI,SAAS,EAAE,CAAC;gBACd,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;gBAC1B,aAAa,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;gBACtE,YAAY,EAAE,CAAC;YACjB,CAAC;YACD,SAAS;QACX,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,IAAI,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS;YAAE,SAAS;QACzD,IAAI,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,CAAC,EAAE,CAAC;YAAC,CAAC,GAAG,IAAI,GAAG,EAAE,CAAC;YAAC,WAAW,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QAAC,CAAC;QACpD,CAAC,CAAC,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,YAAY,KAAK,CAAC;QAAE,OAAO,UAAU,CAAC,4BAA4B,CAAC,CAAC;IAExE,IAAI,WAAW,GAAG,CAAC,CAAC;IACpB,MAAM,OAAO,GAAmC,EAAE,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,WAAW,EAAE,CAAC;QACpC,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC;QACrB,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC;YAAC,GAAG,IAAI,CAAC,CAAC;YAAC,IAAI,CAAC,GAAG,GAAG;gBAAE,GAAG,GAAG,CAAC,CAAC;QAAC,CAAC;QAC/D,IAAI,GAAG,GAAG,CAAC;YAAE,SAAS,CAAC,8BAA8B;QACrD,MAAM,KAAK,GAAG,GAAG,GAAG,GAAG,CAAC;QACxB,IAAI,KAAK,IAAI,SAAS,EAAE,CAAC;YACvB,WAAW,EAAE,CAAC;YACd,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAE9C,MAAM,eAAe,GAAG,CAAC,GAAG,WAAW,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;IACxH,MAAM,cAAc,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC,CAAC,CAAC,cAAc,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAEtE,sEAAsE;IACtE,MAAM,MAAM,GAAG,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IACjE,IAAI,GAAG,GAAG,CAAC,EAAE,SAAS,GAAG,CAAC,CAAC;IAC3B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;QAAC,GAAG,IAAI,CAAC,CAAC;QAAC,SAAS,EAAE,CAAC;QAAC,IAAI,GAAG,IAAI,YAAY,GAAG,GAAG;YAAE,MAAM;IAAC,CAAC;IAExF,OAAO;QACL,OAAO,EAAE,UAAU,CAAC,IAAI;QACxB,kBAAkB,EAAE,eAAe,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,WAAW,GAAG,eAAe,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACrG,YAAY,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAClC,mBAAmB,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE;QACrD,SAAS;QACT,IAAI,EACF,SAAS,IAAI,CAAC;YACZ,CAAC,CAAC,+EAA+E;YACjF,CAAC,CAAC,GAAG,UAAU,CAAC,IAAI,aAAa,WAAW,6CAA6C;KAC9F,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,YAAY,EAAE,EAAE,EAAE,mBAAmB,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC;AAC7G,CAAC"}
1
+ {"version":3,"file":"busfactor.js","sourceRoot":"","sources":["../../src/battery/busfactor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { CouplingBlock } from "../types.js";
2
+ export declare function analyzeCoupling(repoPath: string, now: number, windowDays?: number): CouplingBlock;
3
+ //# sourceMappingURL=coupling.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coupling.d.ts","sourceRoot":"","sources":["../../src/battery/coupling.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,aAAa,CAwC9F"}
@@ -0,0 +1,61 @@
1
+ /**
2
+ * CHANGE-COUPLING (temporal coupling) — files that keep changing together.
3
+ *
4
+ * Research: logical/evolutionary coupling (Gall et al.; D'Ambros & Lanza;
5
+ * Zimmermann et al. "mining version histories to guide changes"). Two files
6
+ * that change together far more often than chance share a HIDDEN dependency the
7
+ * type system can't see — the classic "I fixed A but forgot B" bug source.
8
+ *
9
+ * Deterministic: from `git log --name-only` (commit/tree metadata; no blob
10
+ * fetch). confidence(A,B) = coChanges / min(changes(A), changes(B)).
11
+ * "hidden" = the two files live in different directories (non-obvious coupling).
12
+ */
13
+ import { git, isGitRepo } from "../util.js";
14
+ const SKIP_DIR = /(^|\/)(node_modules|\.git|dist|build|vendor|\.next|coverage|__pycache__|\.venv|target)(\/|$)/;
15
+ const CODE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|c|h|cpp|cc|rb|php|cs|kt|swift|scala|vue|svelte)$/i;
16
+ const dir = (p) => { const i = p.lastIndexOf("/"); return i < 0 ? "" : p.slice(0, i); };
17
+ export function analyzeCoupling(repoPath, now, windowDays = 365) {
18
+ if (!isGitRepo(repoPath))
19
+ return { windowDays, pairs: [], note: "Not a git repository — coupling history unavailable." };
20
+ const since = new Date(now - windowDays * 86_400_000).toISOString();
21
+ // \x01 between commits → recover each commit's changed-file set
22
+ const raw = git(repoPath, ["log", "--since", since, "--no-merges", "--name-only", "--pretty=format:%x01"]);
23
+ if (!raw.trim())
24
+ return { windowDays, pairs: [], note: "No commit activity in the window." };
25
+ const fileCount = new Map();
26
+ const pairCount = new Map();
27
+ for (const block of raw.split("\x01")) {
28
+ const files = [...new Set(block.split("\n").map((s) => s.trim()).filter((f) => f && !SKIP_DIR.test(f) && CODE_EXT.test(f)))];
29
+ for (const f of files)
30
+ fileCount.set(f, (fileCount.get(f) ?? 0) + 1);
31
+ if (files.length < 2 || files.length > 40)
32
+ continue; // skip lone + sweeping commits for pairing
33
+ for (let i = 0; i < files.length; i++) {
34
+ for (let j = i + 1; j < files.length; j++) {
35
+ const k = files[i] < files[j] ? files[i] + "\x00" + files[j] : files[j] + "\x00" + files[i];
36
+ pairCount.set(k, (pairCount.get(k) ?? 0) + 1);
37
+ }
38
+ }
39
+ }
40
+ const pairs = [];
41
+ for (const [k, co] of pairCount) {
42
+ if (co < 5)
43
+ continue; // need support
44
+ const [a, b] = k.split("\x00");
45
+ const conf = co / Math.min(fileCount.get(a) ?? co, fileCount.get(b) ?? co);
46
+ if (conf < 0.5)
47
+ continue; // need strength
48
+ pairs.push({ a, b, coChanges: co, confidence: Math.round(conf * 100) / 100, hidden: dir(a) !== dir(b) });
49
+ }
50
+ // hidden (cross-dir) coupling first — that's the surprising, valuable kind
51
+ pairs.sort((x, y) => Number(y.hidden) - Number(x.hidden) || y.confidence - x.confidence || y.coChanges - x.coChanges);
52
+ const top = pairs[0];
53
+ return {
54
+ windowDays,
55
+ pairs: pairs.slice(0, 15),
56
+ note: top
57
+ ? `${top.a} ⇄ ${top.b} change together ${Math.round(top.confidence * 100)}% of the time${top.hidden ? " across different directories (hidden dependency)" : ""}.`
58
+ : "No strong change-coupling detected.",
59
+ };
60
+ }
61
+ //# sourceMappingURL=coupling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coupling.js","sourceRoot":"","sources":["../../src/battery/coupling.ts"],"names":[],"mappings":"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"}
@@ -10,6 +10,8 @@ type NpmMeta = Parameters<typeof depMortality.predictMortality>[0];
10
10
  export type MetaFetcher = (pkg: string, now: number) => Promise<NpmMeta | null>;
11
11
  /** Default: fetch the public npm registry document and derive mortality inputs. */
12
12
  export declare const defaultFetcher: MetaFetcher;
13
+ /** Classify an SPDX-ish license string into a commercial-risk band. */
14
+ export declare function licenseClass(lic: string): "permissive" | "weak-copyleft" | "strong-copyleft" | "unknown";
13
15
  export declare function analyzeDeps(repoPath: string, now: number, fetcher?: MetaFetcher): Promise<DepsBlock>;
14
16
  export {};
15
17
  //# sourceMappingURL=deps.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/battery/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAIhF,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,WA4C5B,CAAC;AAcF,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,CAsC1H"}
1
+ {"version":3,"file":"deps.d.ts","sourceRoot":"","sources":["../../src/battery/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAG9C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAE7C,KAAK,OAAO,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC;AACnE,MAAM,MAAM,WAAW,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;AAIhF,mFAAmF;AACnF,eAAO,MAAM,cAAc,EAAE,WA+C5B,CAAC;AAEF,uEAAuE;AACvE,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,YAAY,GAAG,eAAe,GAAG,iBAAiB,GAAG,SAAS,CAOxG;AAcD,wBAAsB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,WAA4B,GAAG,OAAO,CAAC,SAAS,CAAC,CA+C1H"}
@@ -39,6 +39,7 @@ export const defaultFetcher = async (pkg, now) => {
39
39
  monthsSinceFeatureRelease = (now - bestAt) / MONTH_MS;
40
40
  }
41
41
  const deprecated = !!(latest && doc.versions?.[latest]?.deprecated);
42
+ const license = (latest && doc.versions?.[latest]?.license) || doc.license || "";
42
43
  return {
43
44
  name: pkg,
44
45
  latestPublishedAt: latestAt,
@@ -46,12 +47,26 @@ export const defaultFetcher = async (pkg, now) => {
46
47
  monthsSinceFeatureRelease,
47
48
  deprecated,
48
49
  maintainerCount: Array.isArray(doc.maintainers) ? doc.maintainers.length : undefined,
50
+ license,
49
51
  };
50
52
  }
51
53
  catch {
52
54
  return null;
53
55
  }
54
56
  };
57
+ /** Classify an SPDX-ish license string into a commercial-risk band. */
58
+ export function licenseClass(lic) {
59
+ const s = (lic || "").toUpperCase();
60
+ if (!s || s === "UNLICENSED" || s === "SEE LICENSE" || s.includes("CUSTOM"))
61
+ return "unknown";
62
+ if (/\bAGPL|GPL-?[23]|GPLV[23]\b/.test(s) && !s.includes("LGPL"))
63
+ return "strong-copyleft";
64
+ if (/\bLGPL|MPL|EPL|CDDL|MS-RL\b/.test(s))
65
+ return "weak-copyleft";
66
+ if (/\bMIT|ISC|BSD|APACHE|UNLICENSE|0BSD|CC0|WTFPL|ZLIB|PYTHON|BLUEOAK\b/.test(s))
67
+ return "permissive";
68
+ return "unknown";
69
+ }
55
70
  function depNames(repoPath) {
56
71
  const raw = readText(join(repoPath, "package.json"));
57
72
  if (!raw)
@@ -68,12 +83,13 @@ function depNames(repoPath) {
68
83
  export async function analyzeDeps(repoPath, now, fetcher = defaultFetcher) {
69
84
  const names = depNames(repoPath);
70
85
  const byBand = { thriving: 0, healthy: 0, watch: 0, moribund: 0, dead: 0 };
86
+ const licenses = { permissive: 0, "weak-copyleft": 0, "strong-copyleft": 0, unknown: 0 };
71
87
  const atRisk = [];
88
+ const licenseFlags = [];
72
89
  if (names.length === 0) {
73
- return { total: 0, byBand, atRisk, partial: false, note: "No package.json dependencies found (non-npm repo or no deps)." };
90
+ return { total: 0, byBand, atRisk, licenses, licenseFlags, partial: false, note: "No package.json dependencies found (non-npm repo or no deps)." };
74
91
  }
75
92
  let partial = false;
76
- // bounded concurrency to be a polite registry citizen
77
93
  const LIMIT = 8;
78
94
  for (let i = 0; i < names.length; i += LIMIT) {
79
95
  const chunk = names.slice(i, i + LIMIT);
@@ -88,20 +104,31 @@ export async function analyzeDeps(repoPath, now, fetcher = defaultFetcher) {
88
104
  if (r.band === "watch" || r.band === "moribund" || r.band === "dead") {
89
105
  atRisk.push({ name: r.package, band: r.band, probability18mo: Math.round(r.probability18mo * 100) / 100, successor: meta.knownSubstitute ?? null });
90
106
  }
107
+ const lic = meta.license ?? "";
108
+ const cls = licenseClass(lic);
109
+ licenses[cls]++;
110
+ if (cls === "strong-copyleft" || cls === "weak-copyleft") {
111
+ licenseFlags.push({ name: meta.name, license: lic || "?", class: cls });
112
+ }
91
113
  }
92
114
  }
93
115
  atRisk.sort((a, b) => b.probability18mo - a.probability18mo);
116
+ licenseFlags.sort((a, b) => (a.class === "strong-copyleft" ? -1 : 1) - (b.class === "strong-copyleft" ? -1 : 1));
94
117
  const danger = byBand.moribund + byBand.dead;
118
+ const copyleft = licenses["strong-copyleft"] + licenses["weak-copyleft"];
119
+ const parts = [];
120
+ if (danger > 0)
121
+ parts.push(`${danger} dying (moribund/dead) — plan replacements`);
122
+ if (copyleft > 0)
123
+ parts.push(`${copyleft} copyleft-licensed (commercial-use review)`);
95
124
  return {
96
125
  total: names.length,
97
126
  byBand,
98
127
  atRisk: atRisk.slice(0, 20),
128
+ licenses,
129
+ licenseFlags: licenseFlags.slice(0, 15),
99
130
  partial,
100
- note: danger > 0
101
- ? `${danger} depend<x>${danger === 1 ? "y is" : "ies are"}</x> dying (moribund/dead). Plan replacements.`.replace(/<x>|<\/x>/g, "")
102
- : partial
103
- ? "Some packages could not be reached on the npm registry (counted as unknown)."
104
- : "No dying dependencies detected.",
131
+ note: parts.length ? parts.join("; ") + "." : partial ? "Some packages could not be reached on the npm registry." : "No dying or copyleft-risk dependencies.",
105
132
  };
106
133
  }
107
134
  //# sourceMappingURL=deps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/battery/deps.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAMjC,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC;AAE7C,mFAAmF;AACnF,MAAM,CAAC,MAAM,cAAc,GAAgB,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IAC5D,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,8BAA8B,kBAAkB,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE;YACnG,OAAO,EAAE,EAAE,MAAM,EAAE,uDAAuD,EAAE;SAC7E,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,IAAI,CAAC;QACzB,MAAM,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAK5B,CAAC;QACF,MAAM,MAAM,GAAG,GAAG,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;QACxC,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;QACnD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC;QAEzF,6EAA6E;QAC7E,MAAM,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;QACjD,IAAI,yBAA6C,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACX,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;YACnE,IAAI,MAAM,GAAG,CAAC,CAAC;YACf,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;gBACjE,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,IAAI,IAAI,CAAC,KAAK,MAAM,CAAC,EAAE,CAAC;oBAChE,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBACpC,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,MAAM;wBAAE,MAAM,GAAG,CAAC,CAAC;gBACnD,CAAC;YACH,CAAC;YACD,IAAI,MAAM,GAAG,CAAC;gBAAE,yBAAyB,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,QAAQ,CAAC;QACxE,CAAC;QACD,MAAM,UAAU,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC;QACpE,OAAO;YACL,IAAI,EAAE,GAAG;YACT,iBAAiB,EAAE,QAAQ;YAC3B,iBAAiB;YACjB,yBAAyB;YACzB,UAAU;YACV,eAAe,EAAE,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;SACrF,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC,CAAC;AAEF,SAAS,QAAQ,CAAC,QAAgB;IAChC,MAAM,GAAG,GAAG,QAAQ,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC;IACrD,IAAI,CAAC,GAAG;QAAE,OAAO,EAAE,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAwF,CAAC;QACnH,MAAM,KAAK,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,YAAY,IAAI,EAAE,CAAC,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACnH,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC;IACpB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,QAAgB,EAAE,GAAW,EAAE,UAAuB,cAAc;IACpG,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;IACjC,MAAM,MAAM,GAAwB,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IAChG,MAAM,MAAM,GAAwB,EAAE,CAAC;IACvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,+DAA+D,EAAE,CAAC;IAC7H,CAAC;IAED,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,sDAAsD;IACtD,MAAM,KAAK,GAAG,CAAC,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC;QAC7C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,CAAC;QACxC,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QACrF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,EAAE,CAAC;gBAAC,OAAO,GAAG,IAAI,CAAC;gBAAC,SAAS;YAAC,CAAC;YACxC,MAAM,CAAC,GAAG,YAAY,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;YACjB,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO,IAAI,CAAC,CAAC,IAAI,KAAK,UAAU,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;gBACrE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,eAAe,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,eAAe,IAAI,IAAI,EAAE,CAAC,CAAC;YACtJ,CAAC;QACH,CAAC;IACH,CAAC;IACD,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,GAAG,CAAC,CAAC,eAAe,CAAC,CAAC;IAE7D,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,IAAI,CAAC;IAC7C,OAAO;QACL,KAAK,EAAE,KAAK,CAAC,MAAM;QACnB,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC;QAC3B,OAAO;QACP,IAAI,EACF,MAAM,GAAG,CAAC;YACR,CAAC,CAAC,GAAG,MAAM,aAAa,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,gDAAgD,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC;YACnI,CAAC,CAAC,OAAO;gBACT,CAAC,CAAC,8EAA8E;gBAChF,CAAC,CAAC,iCAAiC;KACxC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"deps.js","sourceRoot":"","sources":["../../src/battery/deps.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"hotspots.d.ts","sourceRoot":"","sources":["../../src/battery/hotspots.ts"],"names":[],"mappings":"AAmBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,aAAa,CAqC9F"}
1
+ {"version":3,"file":"hotspots.d.ts","sourceRoot":"","sources":["../../src/battery/hotspots.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAMjD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,SAAM,GAAG,aAAa,CA4D9F"}
@@ -5,16 +5,15 @@
5
5
  * that are BOTH changed often AND large/complex. This is well established —
6
6
  * code churn predicts defects (Nagappan & Ball, ICSE'05), and "hotspots" =
7
7
  * change-frequency × complexity surface the highest-ROI refactoring targets
8
- * (Tornhill, *Your Code as a Crime Scene*; D'Ambros & Lanza, evolutionary
9
- * measures). We compute it 100% deterministically:
8
+ * (Tornhill, *Your Code as a Crime Scene*; D'Ambros & Lanza). We compute it
9
+ * 100% deterministically:
10
10
  *
11
11
  * change-frequency ← `git log --name-only` over a window (no blob fetch —
12
12
  * works on a blobless clone; uses commit/tree metadata)
13
13
  * complexity proxy ← current lines-of-code of the file (HEAD blob)
14
14
  * hotspot score ← changeCount × loc, ranked
15
- *
16
- * The output answers "where do I refactor first?" — a question no secret scanner
17
- * or dependency checker answers, and one a CTO actually pays for.
15
+ * expert ← the author with the most commits to the file (who to ask)
16
+ * trend ← commits per time bucket (oldest→newest), for a sparkline
18
17
  */
19
18
  import { git, readText, isGitRepo } from "../util.js";
20
19
  import { join } from "node:path";
@@ -22,39 +21,79 @@ const SKIP_DIR = /(^|\/)(node_modules|\.git|dist|build|vendor|\.next|coverage|__
22
21
  const CODE_EXT = /\.(ts|tsx|js|jsx|mjs|cjs|py|go|rs|java|c|h|cpp|cc|rb|php|cs|kt|swift|scala|vue|svelte)$/i;
23
22
  export function analyzeHotspots(repoPath, now, windowDays = 365) {
24
23
  if (!isGitRepo(repoPath)) {
25
- return { windowDays, filesConsidered: 0, hotspots: [], note: "Not a git repository — hotspot history unavailable." };
24
+ return { windowDays, filesConsidered: 0, hotspots: [], trend: [], note: "Not a git repository — hotspot history unavailable." };
26
25
  }
27
26
  const since = new Date(now - windowDays * 86_400_000).toISOString();
28
- // empty pretty format output is just the changed file paths, one per line,
29
- // per commit. Counting occurrences = how many commits touched each file.
30
- const raw = git(repoPath, ["log", "--since", since, "--no-merges", "--name-only", "--pretty=format:"]);
27
+ // per commit: "C<TAB><email>" then changed file paths. One pass → change
28
+ // frequency per file + the dominant author per file (the "expert").
29
+ const raw = git(repoPath, ["log", "--since", since, "--no-merges", "--name-only", "--pretty=format:C%x09%ae"]);
31
30
  if (!raw.trim())
32
- return { windowDays, filesConsidered: 0, hotspots: [], note: "No commit activity in the window." };
31
+ return { windowDays, filesConsidered: 0, hotspots: [], trend: [], note: "No commit activity in the window." };
33
32
  const changes = new Map();
33
+ const authorsByFile = new Map();
34
+ let curAuthor = "";
34
35
  for (const line of raw.split("\n")) {
36
+ if (line.startsWith("C\t")) {
37
+ curAuthor = line.slice(2).trim();
38
+ continue;
39
+ }
35
40
  const f = line.trim();
36
41
  if (!f || SKIP_DIR.test(f) || !CODE_EXT.test(f))
37
42
  continue;
38
43
  changes.set(f, (changes.get(f) ?? 0) + 1);
44
+ if (curAuthor) {
45
+ let m = authorsByFile.get(f);
46
+ if (!m) {
47
+ m = new Map();
48
+ authorsByFile.set(f, m);
49
+ }
50
+ m.set(curAuthor, (m.get(curAuthor) ?? 0) + 1);
51
+ }
39
52
  }
40
53
  if (changes.size === 0)
41
- return { windowDays, filesConsidered: 0, hotspots: [], note: "No source-file changes in the window." };
42
- // join change-frequency with current size (complexity proxy). Only read LOC
43
- // for the most-changed files (bounded work).
54
+ return { windowDays, filesConsidered: 0, hotspots: [], trend: [], note: "No source-file changes in the window." };
44
55
  const ranked = [...changes.entries()].sort((a, b) => b[1] - a[1]).slice(0, 80);
45
56
  const rows = ranked.map(([file, changeCount]) => {
46
57
  const txt = readText(join(repoPath, file));
47
58
  const loc = txt ? txt.split("\n").length : 0;
48
- return { file, changes: changeCount, loc, score: changeCount * loc };
59
+ const m = authorsByFile.get(file);
60
+ let expert = "", top = 0, authors = 0;
61
+ if (m) {
62
+ authors = m.size;
63
+ for (const [a, c] of m)
64
+ if (c > top) {
65
+ top = c;
66
+ expert = a;
67
+ }
68
+ }
69
+ return { file, changes: changeCount, loc, score: changeCount * loc, expert, authors };
49
70
  }).filter((r) => r.loc > 0);
50
71
  rows.sort((a, b) => b.score - a.score);
72
+ // trend: commits per equal bucket over the window (oldest → newest)
73
+ const BUCKETS = 8;
74
+ const trend = new Array(BUCKETS).fill(0);
75
+ const winMs = windowDays * 86_400_000;
76
+ const tsRaw = git(repoPath, ["log", "--since", since, "--no-merges", "--pretty=format:%ct"]);
77
+ for (const l of tsRaw.split("\n")) {
78
+ const sec = parseInt(l.trim(), 10);
79
+ if (!Number.isFinite(sec))
80
+ continue;
81
+ const ageMs = now - sec * 1000;
82
+ let idx = BUCKETS - 1 - Math.floor((ageMs / winMs) * BUCKETS);
83
+ if (idx < 0)
84
+ idx = 0;
85
+ if (idx > BUCKETS - 1)
86
+ idx = BUCKETS - 1;
87
+ trend[idx]++;
88
+ }
51
89
  const top = rows[0];
52
90
  return {
53
91
  windowDays,
54
92
  filesConsidered: changes.size,
55
93
  hotspots: rows.slice(0, 15),
94
+ trend,
56
95
  note: top
57
- ? `Hotspot: ${top.file} — changed ${top.changes}× and ${top.loc} lines. High churn × size = where defects and refactoring ROI concentrate (behavioral code analysis).`
96
+ ? `Hotspot: ${top.file} — changed ${top.changes}× and ${top.loc} lines${top.expert ? ` (ask: ${top.expert})` : ""}. High churn × size = where defects and refactoring ROI concentrate.`
58
97
  : "No hotspots surfaced.",
59
98
  };
60
99
  }
@@ -1 +1 @@
1
- {"version":3,"file":"hotspots.js","sourceRoot":"","sources":["../../src/battery/hotspots.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hotspots.js","sourceRoot":"","sources":["../../src/battery/hotspots.ts"],"names":[],"mappings":"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"}
package/dist/bin.js CHANGED
@@ -12,13 +12,40 @@ import { buildXRay } from "./engine.js";
12
12
  import { sealXRay, verifyXRay } from "./sign.js";
13
13
  import { xrayLeaksRaw } from "./privacy.js";
14
14
  import { publishReport } from "./publish.js";
15
+ import { runBridge } from "./bridge.js";
15
16
  import { existsSync } from "node:fs";
17
+ import { spawnSync } from "node:child_process";
16
18
  function flagVal(args, name) {
17
19
  const i = args.indexOf(name);
18
20
  return i >= 0 && args[i + 1] && !args[i + 1].startsWith("--") ? args[i + 1] : undefined;
19
21
  }
20
22
  async function main() {
21
23
  const args = process.argv.slice(2);
24
+ // `bridge` — run the local agent so the website can scan local folders
25
+ if (args[0] === "bridge") {
26
+ runBridge(parseInt(flagVal(args, "--port") || process.env.XRAY_BRIDGE_PORT || "7799", 10));
27
+ return;
28
+ }
29
+ // `ci-gate` — fail CI if a changed file is a high hotspot (enterprise gate)
30
+ if (args[0] === "ci-gate") {
31
+ const path = args.find((a, i) => i > 0 && !a.startsWith("--") && a !== flagVal(args, "--changed")) || ".";
32
+ const threshold = parseInt(flagVal(args, "--threshold") || "3", 10); // top-N hotspots are "high"
33
+ const report = await buildXRay({ repoPath: path });
34
+ const top = report.hotspots.hotspots.slice(0, threshold).map((h) => h.file);
35
+ let changed = (flagVal(args, "--changed") || "").split(",").map((s) => s.trim()).filter(Boolean);
36
+ if (changed.length === 0) {
37
+ // derive from the last commit if not supplied
38
+ const r = spawnSync("git", ["diff", "--name-only", "HEAD~1", "HEAD"], { cwd: path, encoding: "utf8" });
39
+ changed = (r.stdout || "").split("\n").map((s) => s.trim()).filter(Boolean);
40
+ }
41
+ const hits = changed.filter((f) => top.includes(f));
42
+ if (hits.length) {
43
+ process.stdout.write(`⚠️ CI GATE: changed files touch top-${threshold} hotspots — review carefully:\n${hits.map((h) => " 🔥 " + h).join("\n")}\n`);
44
+ process.exit(2);
45
+ }
46
+ process.stdout.write(`✓ CI GATE: no changed file is a top-${threshold} hotspot.\n`);
47
+ return;
48
+ }
22
49
  const target = args.find((a) => !a.startsWith("--") && a !== flagVal(args, "--server") && a !== flagVal(args, "--token"));
23
50
  const asJson = args.includes("--json");
24
51
  const noSign = args.includes("--no-sign");
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runBridge(port?: number): void;
2
+ //# sourceMappingURL=bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AA6CA,wBAAgB,SAAS,CAAC,IAAI,SAAO,GAAG,IAAI,CAoC3C"}
package/dist/bridge.js ADDED
@@ -0,0 +1,89 @@
1
+ /**
2
+ * THE LOCAL BRIDGE — how the cloud website reads a LOCAL folder without the
3
+ * code ever leaving the machine.
4
+ *
5
+ * The user runs `npx @mneme-ai/xray bridge` on their own machine. It starts a
6
+ * tiny server bound to 127.0.0.1 only. The website (https://xray.mneme-ai.space)
7
+ * fetches it over localhost — browsers exempt http://localhost from mixed-content
8
+ * blocking, so an https page may call it. The bridge analyses the local path and
9
+ * returns ONLY a signed, raw-free report. The cloud server is never involved;
10
+ * the source never moves. The page renders the report exactly like a cloud scan.
11
+ *
12
+ * GET /bridge/ping → { ok, version } (the page auto-detects it)
13
+ * POST /bridge/xray { path } → build local X-Ray → raw-free gate → sign → return
14
+ */
15
+ import { createServer } from "node:http";
16
+ import { existsSync, readFileSync } from "node:fs";
17
+ import { dirname, join } from "node:path";
18
+ import { fileURLToPath } from "node:url";
19
+ import { buildXRay } from "./engine.js";
20
+ import { sealXRay } from "./sign.js";
21
+ import { xrayLeaksRaw } from "./privacy.js";
22
+ const ALLOW = [
23
+ /^https?:\/\/(localhost|127\.0\.0\.1)(:\d+)?$/,
24
+ /^https:\/\/xray\.mneme-ai\.space$/,
25
+ /^https:\/\/xray\.161\.35\.122\.73\.nip\.io$/,
26
+ ];
27
+ function version() {
28
+ try {
29
+ const p = join(dirname(fileURLToPath(import.meta.url)), "..", "package.json");
30
+ return JSON.parse(readFileSync(p, "utf8")).version ?? "0.0.0";
31
+ }
32
+ catch {
33
+ return "0.0.0";
34
+ }
35
+ }
36
+ function cors(res, origin) {
37
+ const ok = origin && ALLOW.some((re) => re.test(origin));
38
+ res.setHeader("access-control-allow-origin", ok ? origin : "https://xray.mneme-ai.space");
39
+ res.setHeader("access-control-allow-methods", "GET,POST,OPTIONS");
40
+ res.setHeader("access-control-allow-headers", "content-type");
41
+ res.setHeader("vary", "origin");
42
+ }
43
+ function json(res, status, body) {
44
+ res.writeHead(status, { "content-type": "application/json; charset=utf-8" });
45
+ res.end(JSON.stringify(body));
46
+ }
47
+ export function runBridge(port = 7799) {
48
+ const server = createServer(async (req, res) => {
49
+ cors(res, req.headers.origin);
50
+ if (req.method === "OPTIONS") {
51
+ res.writeHead(204);
52
+ res.end();
53
+ return;
54
+ }
55
+ const url = new URL(req.url || "/", "http://127.0.0.1");
56
+ if (req.method === "GET" && url.pathname === "/bridge/ping") {
57
+ return json(res, 200, { ok: true, agent: "mneme-xray-bridge", version: version() });
58
+ }
59
+ if (req.method === "POST" && url.pathname === "/bridge/xray") {
60
+ let body = "";
61
+ req.on("data", (c) => (body += c));
62
+ req.on("end", async () => {
63
+ try {
64
+ const { path } = JSON.parse(body || "{}");
65
+ if (!path || !existsSync(path))
66
+ return json(res, 400, { error: "path does not exist on this machine: " + (path || "(empty)") });
67
+ const report = await buildXRay({ repoPath: path });
68
+ if (xrayLeaksRaw(report).leaks)
69
+ return json(res, 500, { error: "internal: raw-free gate" });
70
+ const signed = sealXRay(existsSync(path) ? path : process.cwd(), report);
71
+ process.stdout.write(` ✓ local X-Ray: ${path} → grade ${report.summary.grade} (source never left this machine)\n`);
72
+ return json(res, 200, signed);
73
+ }
74
+ catch (e) {
75
+ return json(res, 500, { error: e.message.slice(0, 300) });
76
+ }
77
+ });
78
+ return;
79
+ }
80
+ json(res, 404, { error: "not found" });
81
+ });
82
+ server.listen(port, "127.0.0.1", () => {
83
+ process.stdout.write(`\n 🖥 Mneme X-Ray — LOCAL BRIDGE running at http://127.0.0.1:${port}\n` +
84
+ ` Open https://xray.mneme-ai.space → it auto-detects this bridge → scan any local folder.\n` +
85
+ ` Your source never leaves this machine. Ctrl-C to stop.\n\n`);
86
+ });
87
+ process.on("SIGINT", () => { server.close(() => process.exit(0)); });
88
+ }
89
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../src/clone.ts"],"names":[],"mappings":"AAYA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE;AAElE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAgBrD"}
1
+ {"version":3,"file":"clone.d.ts","sourceRoot":"","sources":["../src/clone.ts"],"names":[],"mappings":"AAaA,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAGvD;AAED,MAAM,WAAW,WAAW;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,IAAI,CAAA;CAAE;AAElE;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAgBrD"}