weavatrix 0.2.15 → 0.2.18

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 (66) hide show
  1. package/README.md +99 -13
  2. package/docs/adr/0001-v0.3-offline-online-split.md +58 -0
  3. package/docs/releases/v0.2.18.md +41 -0
  4. package/package.json +7 -2
  5. package/src/analysis/cargo-dependency-evidence.js +105 -0
  6. package/src/analysis/cargo-manifests.js +74 -0
  7. package/src/analysis/dep-check-ecosystems.js +3 -0
  8. package/src/analysis/dependency/scoped-dependencies.js +13 -7
  9. package/src/analysis/duplicates.tokenize.js +13 -6
  10. package/src/analysis/endpoints-java.js +2 -5
  11. package/src/analysis/findings.js +12 -0
  12. package/src/analysis/git-history/options.js +2 -4
  13. package/src/analysis/go-dependency-evidence.js +62 -0
  14. package/src/analysis/health-capabilities.js +1 -1
  15. package/src/analysis/hot-path-review.js +2 -4
  16. package/src/analysis/http-contracts/analysis.js +2 -0
  17. package/src/analysis/http-contracts/client-call-detection.js +1 -0
  18. package/src/analysis/http-contracts/client-call-parser.js +18 -4
  19. package/src/analysis/http-contracts/shared.js +3 -4
  20. package/src/analysis/internal-audit/dependency-health.js +15 -13
  21. package/src/analysis/internal-audit/python-manifests.js +18 -5
  22. package/src/analysis/internal-audit/repo-files.js +5 -6
  23. package/src/analysis/internal-audit/supply-chain.js +2 -0
  24. package/src/analysis/internal-audit.reach.js +14 -0
  25. package/src/analysis/internal-audit.run.js +15 -10
  26. package/src/analysis/jvm-dependency-evidence.js +102 -56
  27. package/src/analysis/jvm-manifests.js +114 -0
  28. package/src/analysis/manifests.js +0 -49
  29. package/src/analysis/source-correctness.js +2 -5
  30. package/src/analysis/structure/dependency-graph.js +3 -8
  31. package/src/analysis/transport-contracts.js +157 -0
  32. package/src/graph/builder/lang-go.js +4 -2
  33. package/src/graph/builder/lang-java.js +12 -3
  34. package/src/graph/builder/lang-rust.js +22 -3
  35. package/src/graph/freshness-probe.js +1 -1
  36. package/src/graph/internal-builder.build.js +2 -2
  37. package/src/graph/internal-builder.langs.js +19 -0
  38. package/src/graph/internal-builder.resolvers.js +18 -8
  39. package/src/graph/node-id.js +7 -0
  40. package/src/mcp/actions/advisories.mjs +2 -3
  41. package/src/mcp/architecture-bootstrap.mjs +3 -3
  42. package/src/mcp/catalog.mjs +7 -4
  43. package/src/mcp/company-contract-verdict.mjs +42 -0
  44. package/src/mcp/evidence-snapshot.common.mjs +1 -3
  45. package/src/mcp/evidence-snapshot.health.mjs +11 -4
  46. package/src/mcp/evidence-snapshot.mjs +1 -1
  47. package/src/mcp/graph-diff.mjs +2 -1
  48. package/src/mcp/tools-architecture.mjs +2 -6
  49. package/src/mcp/tools-company.mjs +28 -53
  50. package/src/mcp/tools-impact-change.mjs +3 -8
  51. package/src/mcp/tools-impact-precision.mjs +89 -0
  52. package/src/mcp/tools-impact.mjs +52 -94
  53. package/src/precision/lsp-overlay/build.js +10 -0
  54. package/src/precision/lsp-overlay/contract.js +1 -1
  55. package/src/precision/symbol-query.js +39 -0
  56. package/src/precision/typescript-provider/client.js +16 -3
  57. package/src/precision/typescript-provider/discovery.js +1 -1
  58. package/src/precision/typescript-provider/isolated-runtime.js +39 -0
  59. package/src/precision/typescript-provider/project-host.js +11 -6
  60. package/src/precision/typescript-provider/project-safety.js +5 -0
  61. package/src/security/advisory-store.js +2 -2
  62. package/src/security/installed-jvm-rust.js +46 -0
  63. package/src/security/installed.js +21 -1
  64. package/src/security/typosquat.js +15 -6
  65. package/src/util.js +13 -0
  66. package/docs/releases/v0.2.15.md +0 -37
@@ -7,6 +7,8 @@ import { join, relative } from "node:path";
7
7
  import { parseGoMod } from "../analysis/manifests.js";
8
8
  import { uniqueBy } from "../util.js";
9
9
  import { createRepoBoundary } from "../repo-path.js";
10
+ import { collectJvmRustInstalled } from "./installed-jvm-rust.js";
11
+ import { listRepoFiles, readRepoText } from "../analysis/internal-audit/repo-files.js";
10
12
 
11
13
  const pep503 = (name) => String(name).toLowerCase().replace(/[-_.]+/g, "-"); // PyPI canonical name
12
14
 
@@ -256,5 +258,23 @@ export function collectInstalled(repoPath) {
256
258
  if (!vers) merged.push(d);
257
259
  else if (!vers.has(d.version)) drift.push({ name: d.name, locked: locked.get(d.name).version, installed: d.version });
258
260
  }
259
- return { installed: dedupe([...merged, ...py, ...go]), drift };
261
+ const jvmRust = collectJvmRustInstalled(repoPath);
262
+ // The earlier fast path covers roots and immediate services. Complete the tracked repository
263
+ // universe so deeply nested Python/Go services are not silently omitted from advisory coverage.
264
+ const repositoryFiles = listRepoFiles(repoPath);
265
+ const allPython = repositoryFiles.flatMap((file) => {
266
+ const text = readRepoText(boundary, file);
267
+ if (/(^|\/)requirements[\w.-]*\.(?:txt|in)$/i.test(file) || /(^|\/)requirements\/[^/]+\.(?:txt|in)$/i.test(file)) return parseRequirements(text || "");
268
+ if (/(^|\/)poetry\.lock$/i.test(file)) return parseTomlLockPackages(text || "", "poetry-lock");
269
+ if (/(^|\/)uv\.lock$/i.test(file)) return parseTomlLockPackages(text || "", "uv-lock");
270
+ if (/(^|\/)Pipfile\.lock$/i.test(file)) { try { return parsePipfileLock(JSON.parse(text)); } catch { return []; } }
271
+ return [];
272
+ });
273
+ const allGo = repositoryFiles.flatMap((file) => {
274
+ const text = readRepoText(boundary, file) || "";
275
+ if (/(^|\/)go\.sum$/i.test(file)) return parseGoSum(text);
276
+ if (/(^|\/)go\.mod$/i.test(file)) return parseGoModPackages(text);
277
+ return [];
278
+ });
279
+ return { installed: dedupe([...merged, ...py, ...go, ...allPython, ...allGo, ...jvmRust]), drift };
260
280
  }
@@ -31,7 +31,9 @@ const KNOWN_LEGIT = new Set([
31
31
  "markdown-it", "babel-loader", "css-loader", "style-loader", "query-string",
32
32
  ]);
33
33
 
34
- const norm = (name) => String(name || "").toLowerCase().replace(/^@[^/]+\//, ""); // drop scope for the compare
34
+ const rawName = (name) => String(name || "").trim().toLowerCase();
35
+ const isScoped = (name) => /^@[^/]+\/.+/.test(name);
36
+ const unscopedTail = (name) => name.replace(/^@[^/]+\//, "");
35
37
 
36
38
  // Damerau-Levenshtein (optimal string alignment) — includes adjacent transposition.
37
39
  export function damerau(a, b) {
@@ -56,12 +58,19 @@ export function damerau(a, b) {
56
58
  // Threshold: distance 1 always; distance 2 only for names ≥8 chars (short names collide too easily).
57
59
  // Skip: exact popular names, known-legit pairs, names <4 chars.
58
60
  export function classifyTyposquat(name) {
59
- const raw = String(name || "");
60
- const n = norm(raw);
61
- if (n.length < 4 || TOP_PACKAGES.has(raw) || TOP_PACKAGES.has(n) || KNOWN_LEGIT.has(raw) || KNOWN_LEGIT.has(n)) return null;
61
+ const raw = rawName(name);
62
+ const scoped = isScoped(raw);
63
+ const tail = unscopedTail(raw);
64
+ // A package scope is an ownership boundary, not punctuation to discard.
65
+ // Comparing every scoped basename with unscoped popular names made the
66
+ // official @playwright/test package look like a one-edit misspelling of jest.
67
+ if (tail.length < 4 || TOP_PACKAGES.has(raw) || TOP_PACKAGES.has(tail)
68
+ || KNOWN_LEGIT.has(raw) || KNOWN_LEGIT.has(tail)) return null;
69
+ const candidates = [...TOP_PACKAGES].filter((top) => isScoped(top) === scoped);
70
+ const n = scoped ? raw : tail;
62
71
  let best = null;
63
- for (const top of TOP_PACKAGES) {
64
- const t = norm(top);
72
+ for (const top of candidates) {
73
+ const t = rawName(top);
65
74
  if (t === n) return null; // scope-only difference of a popular name → not a squat
66
75
  const dist = damerau(n, t);
67
76
  if (dist === 0) return null;
package/src/util.js CHANGED
@@ -16,6 +16,19 @@ export function uniqueBy(list, keyFn) {
16
16
  });
17
17
  }
18
18
 
19
+ export function lineNumberAt(text, index) {
20
+ let line = 1;
21
+ for (let offset = 0; offset < index && offset < text.length; offset++) {
22
+ if (text[offset] === "\n") line++;
23
+ }
24
+ return line;
25
+ }
26
+
27
+ export function boundedInteger(value, fallback, min, max) {
28
+ const number = Number(value);
29
+ return Number.isInteger(number) ? Math.max(min, Math.min(max, number)) : fallback;
30
+ }
31
+
19
32
  export function safeRead(path) {
20
33
  try {
21
34
  const st = statSync(path);
@@ -1,37 +0,0 @@
1
- # Weavatrix 0.2.15
2
-
3
- 0.2.15 is a focused self-audit precision release. It keeps the 38-tool MCP surface and all wire and
4
- security boundaries stable while removing false-positive dependency, dead-code, malware, and
5
- duplicate findings discovered by running Weavatrix against its own repository.
6
-
7
- ## Dependency and reachability precision
8
-
9
- - Dependency verification now respects the owning nested manifest before deciding whether an import
10
- is missing or a declaration is unused.
11
- - Framework peer dependencies and bounded package paths assembled from static string fragments are
12
- recognized without treating arbitrary runtime values as proof.
13
- - Source-owned HTML asset references participate in reachability, protecting maintained browser
14
- scripts and styles from false dead-file findings.
15
-
16
- ## Safer review queues
17
-
18
- - Malware scanning distinguishes placeholders, comments, documentation URLs, and ordinary Unicode
19
- text from executable registry/download behavior. Static heuristic evidence remains review-only and
20
- does not claim execution or compromise.
21
- - Duplicate detection suppresses policy-like numeric tables and stable ordered declarations where
22
- repeated structure carries meaning, while preserving clone evidence for executable code.
23
- - Reverse reachability, Git output parsing, ordered-member comparison, path terminology, task
24
- retrieval, and duplicate evidence now share focused owners instead of maintaining divergent copies.
25
-
26
- ## Compatibility and security
27
-
28
- - There are no MCP tool-schema, capability-profile, Hosted payload, sync-consent, or architecture
29
- contract changes in this release.
30
- - The default profile remains offline and local-first. Advisory and Hosted network capabilities
31
- remain explicit opt-ins.
32
-
33
- ## Verification
34
-
35
- The release is gated by the full Node suite, six-language fixture benchmark, six-repository semantic
36
- regression gate, release-manifest verification, packed npm and MCPB stdio checks, and npm audit. The
37
- exact counts and artifacts are recorded by the immutable GitHub release workflow.