weavatrix 0.1.4 → 0.2.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 (70) hide show
  1. package/README.md +138 -53
  2. package/SECURITY.md +25 -8
  3. package/package.json +2 -2
  4. package/skill/SKILL.md +92 -30
  5. package/src/analysis/architecture-contract.js +343 -0
  6. package/src/analysis/audit-debt.js +94 -0
  7. package/src/analysis/change-classification.js +509 -0
  8. package/src/analysis/cycle-route.js +14 -0
  9. package/src/analysis/dead-check.js +5 -3
  10. package/src/analysis/dead-code-review.js +245 -0
  11. package/src/analysis/dep-check-ecosystems.js +6 -0
  12. package/src/analysis/dep-check.js +40 -6
  13. package/src/analysis/dep-rules.js +12 -9
  14. package/src/analysis/duplicates.compute.js +47 -7
  15. package/src/analysis/endpoints-java.js +186 -0
  16. package/src/analysis/endpoints.js +8 -2
  17. package/src/analysis/findings.js +8 -1
  18. package/src/analysis/git-history.js +549 -0
  19. package/src/analysis/git-ref-graph.js +74 -0
  20. package/src/analysis/graph-analysis.aggregate.js +2 -2
  21. package/src/analysis/graph-analysis.edges.js +3 -0
  22. package/src/analysis/graph-analysis.summaries.js +1 -1
  23. package/src/analysis/http-contracts.js +581 -0
  24. package/src/analysis/internal-audit.collect.js +3 -2
  25. package/src/analysis/internal-audit.reach.js +52 -1
  26. package/src/analysis/internal-audit.run.js +58 -10
  27. package/src/analysis/java-source.js +36 -0
  28. package/src/analysis/package-reachability.js +39 -0
  29. package/src/analysis/static-test-reachability.js +133 -0
  30. package/src/build-graph.js +72 -13
  31. package/src/graph/build-worker.js +3 -4
  32. package/src/graph/builder/lang-js.js +71 -12
  33. package/src/graph/community.js +10 -0
  34. package/src/graph/file-lock.js +69 -0
  35. package/src/graph/freshness-probe.js +141 -0
  36. package/src/graph/graph-filter.js +28 -11
  37. package/src/graph/incremental-refresh.js +232 -0
  38. package/src/graph/internal-builder.barrels.js +169 -0
  39. package/src/graph/internal-builder.build.js +82 -11
  40. package/src/graph/internal-builder.langs.js +2 -1
  41. package/src/graph/layout.js +21 -5
  42. package/src/graph/repo-registry.js +124 -0
  43. package/src/mcp/catalog.mjs +62 -19
  44. package/src/mcp/evidence-snapshot.architecture.mjs +80 -0
  45. package/src/mcp/evidence-snapshot.common.mjs +160 -0
  46. package/src/mcp/evidence-snapshot.duplicates.mjs +217 -0
  47. package/src/mcp/evidence-snapshot.health.mjs +95 -0
  48. package/src/mcp/evidence-snapshot.inventory.mjs +148 -0
  49. package/src/mcp/evidence-snapshot.mjs +50 -0
  50. package/src/mcp/evidence-snapshot.package-graph.mjs +249 -0
  51. package/src/mcp/evidence-snapshot.structure.mjs +81 -0
  52. package/src/mcp/graph-context.mjs +100 -16
  53. package/src/mcp/graph-diff.mjs +74 -20
  54. package/src/mcp/staleness-notice.mjs +20 -0
  55. package/src/mcp/sync-evidence.mjs +418 -0
  56. package/src/mcp/sync-payload.mjs +164 -0
  57. package/src/mcp/tool-result.mjs +51 -0
  58. package/src/mcp/tools-actions.mjs +111 -30
  59. package/src/mcp/tools-architecture.mjs +144 -0
  60. package/src/mcp/tools-company.mjs +273 -0
  61. package/src/mcp/tools-graph.mjs +25 -14
  62. package/src/mcp/tools-health.mjs +336 -14
  63. package/src/mcp/tools-history.mjs +22 -0
  64. package/src/mcp/tools-impact-change.mjs +261 -0
  65. package/src/mcp/tools-impact.mjs +25 -6
  66. package/src/mcp-server.mjs +100 -17
  67. package/src/mcp-source-tools.mjs +11 -3
  68. package/src/path-classification.js +201 -0
  69. package/src/path-ignore.js +69 -0
  70. package/src/security/typosquat.js +1 -1
package/README.md CHANGED
@@ -5,8 +5,8 @@
5
5
  Grep sees text. Weavatrix sees structure. It builds a dependency graph of any local repository —
6
6
  files, symbols, and the imports/calls/inheritance connecting them — and serves it to Claude Code,
7
7
  Codex, or any MCP client: change impact, transitive dependents, health audit, clone detection,
8
- coverage mapping. **23 tools available; 21 offline tools enabled by default, including one-call
9
- repository switching. Local-first: with the defaults, no repository data leaves your machine.**
8
+ coverage mapping. **32 tools available; 29 enabled by the default offline profile. Local-first: with
9
+ the defaults, no repository data leaves your machine.**
10
10
 
11
11
  - Website: [weavatrix.com](https://weavatrix.com)
12
12
  - Source: [github.com/sergii-ziborov/weavatrix](https://github.com/sergii-ziborov/weavatrix)
@@ -23,16 +23,16 @@ answers grep can't produce:
23
23
  out before you ship.
24
24
  - *"Who calls this function?"* → `get_dependents` walks reverse edges transitively: every caller,
25
25
  importer and subclass that can feel the refactor, ranked by proximity × connectivity.
26
- - *"Did my refactor actually decouple anything?"* → `rebuild_graph` + `graph_diff` report the
27
- structural delta: new module dependencies, broken or introduced import cycles, symbols that lost
28
- their last caller.
26
+ - *"Did my refactor actually decouple anything?"* → `graph_diff base_ref=HEAD~1` builds an immutable
27
+ baseline graph without checking it out, then reports the structural delta: new module
28
+ dependencies, broken or introduced import cycles, and symbols that lost their last caller.
29
29
 
30
30
  ## Quick start
31
31
 
32
32
  Requires Node ≥ 18. One command:
33
33
 
34
34
  ```sh
35
- # Claude Code — offline default; open_repo can switch local repositories:
35
+ # Claude Code — offline default; local repository switching is available explicitly:
36
36
  claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot>
37
37
  ```
38
38
 
@@ -51,20 +51,33 @@ startup_timeout_sec = 20
51
51
  tool_timeout_sec = 60
52
52
  ```
53
53
 
54
- The default includes offline repository switching but excludes every network tool. Pass a final
55
- comma-separated capability list only to restrict or extend it:
54
+ The package has one binary and several explicit security profiles. The omitted profile is `offline`:
55
+ all local analysis plus `open_repo`, with every HTTP tool absent. Pass one profile as the final
56
+ argument when a stricter repository boundary or a network feature is wanted:
57
+
58
+ | Profile | Local repository switching | Cross-repo graph reads | OSV requests | Hosted sync / contract pull |
59
+ |---|---:|---:|---:|---:|
60
+ | `offline` (default) | Yes, only through `open_repo` | Yes, only through `trace_api_contract` | No | No |
61
+ | `pinned` | No | No | No | No |
62
+ | `osv` | Yes | Yes, only when called | Only when `refresh_advisories` is called | No |
63
+ | `hosted` / `full` | Yes | Yes, only when called | Only when called | Only when `sync_graph` or `pull_architecture_contract` is called |
56
64
 
57
65
  ```sh
58
- # Pin the registration to one repository (hide open_repo/list_known_repos):
59
- claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> graph,search,source,health,build
66
+ # Hard-pin one repository and expose no network tools:
67
+ claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> pinned
60
68
 
61
- # Add network tools while pinning one repository:
62
- claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> graph,search,source,health,build,online
69
+ # Add only explicit OSV refresh:
70
+ claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> osv
63
71
 
64
- # Add network tools and keep the default repository switching:
65
- claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> graph,search,source,health,build,retarget,online
72
+ # Enable the owner-authenticated hosted workflow:
73
+ claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot> hosted
66
74
  ```
67
75
 
76
+ Advanced registrations may still pass an exact comma-separated capability set:
77
+ `graph,search,source,health,build,retarget,crossrepo,advisories,hosted`. The former `online` capability remains
78
+ a compatibility alias for `advisories,hosted`; new registrations should use the named profiles or
79
+ the narrower capability names.
80
+
68
81
  Or clone it:
69
82
 
70
83
  ```sh
@@ -73,16 +86,18 @@ cd weavatrix && npm install
73
86
  claude mcp add -s user weavatrix -- node <path-to>/weavatrix/bin/weavatrix-mcp.mjs <repoRoot>
74
87
  ```
75
88
 
76
- - `<repoRoot>` — the repository to start with; the graph location is derived automatically
77
- (`<repoRoot-parent>/weavatrix-graphs/<repoName>/graph.json`). Pass an explicit
89
+ - `<repoRoot>` — the repository to start with; the graph location is derived automatically in the
90
+ per-user registry (`~/.weavatrix/graphs/<repository-storage-key>/graph.json`; its stable UUID is
91
+ stored beside it in `.repository-id`). Pass an explicit
78
92
  `<graph.json> <repoRoot>` pair instead if you keep graphs elsewhere.
79
93
 
80
94
  No graph yet? Ask the agent to call `rebuild_graph`; it builds the missing graph locally.
81
- `open_repo` can change the active repository and builds a missing graph automatically. A normal
95
+ With the default `offline` profile (or an explicit capability set containing `retarget`),
96
+ `open_repo` can change the active repository
97
+ and builds a missing graph automatically. A normal
82
98
  `open_repo` call also upgrades graphs created before `0.1.4` to edge metadata v2; `build:false`
83
99
  probes without building and refuses a legacy graph. Retargeting is offline but intentionally changes
84
- the filesystem boundary for subsequent tools; omit `retarget` from an explicit capability list when
85
- a registration must stay pinned to one repository.
100
+ the filesystem boundary for subsequent tools; select `pinned` when that boundary must not move.
86
101
 
87
102
  An agent skill with recipes ships in [skill/SKILL.md](skill/SKILL.md) — install as
88
103
  `~/.claude/skills/weavatrix/SKILL.md`.
@@ -91,7 +106,8 @@ An agent skill with recipes ships in [skill/SKILL.md](skill/SKILL.md) — instal
91
106
 
92
107
  **graph** — `graph_stats`, `get_node`, `get_neighbors`, `query_graph`, `god_nodes`,
93
108
  `shortest_path`, `get_community`, `list_communities`, `module_map`, `get_dependents`,
94
- `change_impact`, `graph_diff`. Runtime dependencies, TypeScript type-only coupling and language
109
+ `change_impact`, `git_history`, `graph_diff`, `get_architecture_contract`,
110
+ `prepare_change`. Runtime dependencies, TypeScript type-only coupling and language
95
111
  compile-only edges (Rust module/use, Java imports) are reported separately where that distinction
96
112
  changes the result.
97
113
 
@@ -99,32 +115,74 @@ changes the result.
99
115
  symbol's actual code in one hop), `list_endpoints` (HTTP route inventory:
100
116
  Express/Fastify/Nest/Flask/FastAPI/Go mux/Rust axum and actix-web …)
101
117
 
102
- **health** — `run_audit` (dead code, unused exports, missing/unused npm/Go/Python deps, runtime
118
+ **health** — `find_dead_code` (bounded review queue for statically unreferenced files, functions,
119
+ methods, and symbols, with confidence/evidence and explicit public/framework/dynamic caveats),
120
+ `run_audit` (unused files/exports/dependencies, missing npm/Go/Python deps, runtime
103
121
  cycles, type-only/compile-only coupling, orphans, boundary rules, offline OSV vulnerabilities + typosquat +
104
- lockfile drift), `find_duplicates` (MOSS winnowing over method bodies catches copy-paste even
122
+ lockfile drift; accepts an immutable `base_ref`, `changed_files`, and `debt: new|existing|all` for
123
+ review-scoped results), `find_duplicates` (MOSS winnowing over method bodies — catches copy-paste even
105
124
  after renames), `coverage_map` (existing coverage reports mapped onto the graph; untested hotspots
106
- ranked by connectivity — tests are never executed)
125
+ ranked by connectivity — tests are never executed), `verify_architecture`,
126
+ `explain_architecture_violation`, `propose_architecture_exception`
107
127
 
108
128
  **build** — `rebuild_graph` (reports the structural delta, keeps the prior state as
109
129
  `graph.prev.json`)
110
130
 
111
- **retarget** *(enabled by default, offline, explicit tool call)* `open_repo`, `list_known_repos`;
112
- changes the active repository boundary
131
+ For dead functions/methods/symbols, call `find_dead_code` first. Its default production-only queue
132
+ shows high/medium-confidence candidates and excludes tests, generated code, mocks, stories and docs;
133
+ use `kinds:["method"]` or a `path` prefix to narrow it. `min_confidence:"low"` explicitly includes
134
+ public APIs and framework/dynamic/reflection-sensitive candidates with their warnings. For repository
135
+ maintenance or branch debt, pair it with `run_audit category=unused debt=all` (or add an immutable
136
+ `base_ref` with `debt=new`) to cover unused files, exports and dependencies. Neither tool authorizes
137
+ deletion: inspect `read_source`, `get_dependents`, exact search, manifests/configuration and tests first.
138
+
139
+ `graph_diff` accepts `base_ref` (`HEAD~1`, `main`, `origin/main`, or another local Git ref) for a
140
+ fresh baseline comparison. Without it, the tool compares against `graph.prev.json` saved by the last
141
+ full rebuild. Either mode can be narrowed with `path`.
142
+
143
+ Graph and health calls reconcile the working graph before answering. Safe JS/TS body-only changes
144
+ reparse only the changed files plus bounded reverse importers; add/delete, export-surface, barrel,
145
+ manifest, alias, ignore/config, non-JS/TS, or unsafe merge cases deliberately fall back to a full
146
+ rebuild. The result says whether freshness was `none`, `incremental`, or `full`. Graph artifacts stay
147
+ in the per-user cache and never need to be committed to Git.
148
+
149
+ **retarget** *(included in `offline`; absent from `pinned`; every switch is an explicit local call)* —
150
+ `open_repo`, `list_known_repos`; changes the active repository boundary
151
+
152
+ **crossrepo** *(included in `offline`; absent from `pinned`; reads only registered local graphs)* —
153
+ `trace_api_contract`; reconciles the selected backend/client graphs and joins routes to client callsites
154
+
155
+ `query_graph` accepts optional `seed_files` when an architectural question must start from exact
156
+ entry points. Resolved explicit seeds are exclusive by default; set `augment_seeds:true` only when
157
+ fuzzy question-derived seeds are also wanted. Broad bootstrap/routing/authentication questions
158
+ without explicit seeds rank conventional entry points and high-level modules ahead of incidental matches.
159
+
160
+ **advisories** *(network, explicit opt-in)* — `refresh_advisories`
113
161
 
114
- **online** *(explicit opt-in — see Privacy)* — `refresh_advisories`, `sync_graph`
162
+ **hosted** *(network, explicit opt-in)* — `pull_architecture_contract`, `sync_graph`
115
163
 
116
- Quality of life: graph tools self-report staleness vs the repo HEAD; ambiguous name lookups are
164
+ Quality of life: graph/health reads auto-reconcile and expose `none` / `incremental` / `full`
165
+ freshness, with a short clean-read debounce to avoid rescanning the repository for every tool call;
166
+ ambiguous name lookups are
117
167
  disclosed instead of silently guessed; and the server **hot-reloads its watched MCP tool entry
118
168
  modules and catalog** when those files change — other MCP helpers and analysis engines require a
119
169
  reconnect.
120
170
 
121
171
  ## Signal quality and repository configuration
122
172
 
123
- Weavatrix `0.1.4` reduces the most common sources of static-analysis noise while deepening Rust and
173
+ Weavatrix `0.2.0` reduces the most common sources of static-analysis noise while deepening Rust and
124
174
  Java graphs:
125
175
 
126
176
  - In Git repositories, graph and clone scans use tracked plus non-ignored untracked files, so
127
177
  `.gitignore`-excluded build outputs such as packaged applications do not dominate findings.
178
+ - Add a repository-root `.weavatrixignore` for analysis-only exclusions that should remain tracked
179
+ in Git. It supports `*`, `**`, `?`, root-anchored `/patterns`, directory suffixes and ordered `!`
180
+ re-includes. The same file universe is used by graph building, audits and clone scanning.
181
+ - `mode: "no-tests"` and `find_duplicates(include_tests:false)` classify `test-e2e`, Cypress,
182
+ Playwright, acceptance and integration roots as tests, not only `*.test`/`*.spec` filenames.
183
+ - `benchmarks/**` and any `**/__temp/**` root are classified as non-production review surfaces and
184
+ suppressed from dead-code/clone/audit queues by default. If a benchmark is deliberate production
185
+ source, opt its narrow path back in with `.weavatrix.json` `classify.product` patterns.
128
186
  - TypeScript `import type` and type-only re-exports remain visible as compile-time coupling but do
129
187
  not inflate runtime-cycle severity. `module_map`, `change_impact` and structural diffs preserve
130
188
  that distinction. `god_nodes` ranks unique neighbors with runtime connectivity first and reports
@@ -150,6 +208,13 @@ Java graphs:
150
208
  - Duplicate output is a review queue, not a verdict: near-identical bodies are clone candidates;
151
209
  same-name/different-body pairs are divergence candidates. Read both sources and confirm the
152
210
  shared contract before consolidating code.
211
+ - `run_audit base_ref=... debt=new` compares stable finding fingerprints against a graph rebuilt
212
+ from that immutable commit. Existing debt and fixed findings are counted separately. Supplying
213
+ only `changed_files` is honestly labeled changed scope—it is never presented as proof that a
214
+ finding is new.
215
+ - `find_dead_code` exposes the symbol-level liveness evidence already used by the audit as a bounded
216
+ agent review queue. Public/exported methods, framework entries, decorators, dynamic loading and
217
+ reflection lower confidence; the result always says `REVIEW_REQUIRED` and `autoDelete:false`.
153
218
 
154
219
  `run_audit` makes incomplete security coverage explicit. OSV state is `OK` only after every
155
220
  supported pinned package/version for this repository was queried successfully. `PARTIAL` means
@@ -184,29 +249,48 @@ they change audit interpretation, not the repository or its dependency installat
184
249
  ## Privacy: local-first, offline by design
185
250
 
186
251
  Graph queries, audits, clone scans and repository switching run locally. The default capability set
187
- is `graph,search,source,health,build,retarget`: no Weavatrix HTTP requests. `open_repo` changes the
188
- active local boundary only when called. Weavatrix itself initiates outbound HTTP only from two
189
- tools; both require the explicit `online` group and a tool call:
252
+ is `graph,search,source,health,build,retarget,crossrepo`: no Weavatrix HTTP requests. `open_repo`
253
+ changes the active local boundary only when called. Select `pinned` to remove repository switching,
254
+ global repository listing, and cross-repository graph tracing too.
255
+ Weavatrix itself initiates outbound HTTP only from three tools; all are absent from `offline` and
256
+ `pinned`, and none runs merely because a profile is enabled:
190
257
 
191
258
  - `refresh_advisories` — queries [OSV.dev](https://osv.dev) with your lockfile's package
192
259
  **names + versions** (that is what an OSV query is; never source code) and caches the advisories
193
260
  in `~/.weavatrix/advisories.json`. `run_audit` then matches against that store fully offline.
194
- - `sync_graph` — constructs a versioned, allowlisted payload from `graph.json`: relative paths,
195
- symbol names and line ranges, import/dependency identifiers, edges and numeric metrics. Unknown
196
- fields are discarded; source file bodies are never read for sync or included in the payload. The
197
- endpoint is **yours**, configured via `WEAVATRIX_SYNC_URL` / `WEAVATRIX_SYNC_TOKEN`. Off by default.
198
- Sync payload v2 preserves type-only and compile-only edge metadata. Graphs built before `0.1.4` must be rebuilt
199
- once before syncing; a normal `open_repo` call performs that upgrade automatically.
200
-
201
- If `refresh_advisories` is not listed by the MCP client, that is the expected default: the
202
- registration does not include `online`. Only with the user's approval, add `online` to the final
203
- capability list (for example `graph,search,source,health,build,retarget,online`), restart/reconnect
204
- the MCP server, and then invoke `refresh_advisories`. Enabling the group does not trigger a request
205
- by itself.
206
-
207
- Capability groups (`graph`, `search`, `source`, `health`, `build`, `retarget`, `online`) are
208
- selectable through the final positional argument. Omitted caps use the safe default above; an
209
- explicit list exposes exactly the named groups.
261
+ - `pull_architecture_contract` — sends the active repository's opaque stable UUID with bearer
262
+ authentication, downloads the owner-approved target-architecture contract, validates it, and
263
+ stores the contract in the local graph cache. It sends no source, symbol, or repository path.
264
+ - `sync_graph` builds a bounded evidence snapshot locally, then sends payload v3: the v2 graph
265
+ allowlist plus module dependencies, runtime/compile-time cycles, declared boundary violations,
266
+ health findings, complexity-threshold breaches, stack identifiers, a bounded direct/transitive
267
+ dependency graph, direct package usage, and bounded clone/divergence review candidates. Local
268
+ analyzers may read repository source and manifests to derive those
269
+ facts. The wire contract has no fields for file bodies, snippets, absolute host paths, environment
270
+ values or Git remotes; unknown fields are discarded and unsafe optional path metadata is omitted.
271
+ The request also carries the normalized repository display name used by the
272
+ hosted list. The endpoint is **yours**, configured through `WEAVATRIX_SYNC_URL` and the optional
273
+ `WEAVATRIX_SYNC_TOKEN`; the feature is off by default. Pass `payload_version: 2` only for an
274
+ intentional graph-only compatibility sync—there is no silent downgrade that discards evidence.
275
+ Graphs built before `0.1.4` must be rebuilt once before syncing; V3 also refuses a stale graph so
276
+ source-derived evidence cannot be mixed with old topology.
277
+
278
+ Evidence sections carry independent `state` (`COMPLETE`, `PARTIAL`, `NOT_CHECKED`,
279
+ `NOT_APPLICABLE`, `ERROR`) and `verdict` (`PASS`, `FAIL`, `UNKNOWN`) fields plus exact
280
+ `total/returned/truncated` counts. An incomplete check is never converted into a clean zero. V3 is
281
+ deterministic: volatile timestamps are excluded and the allowlisted snapshot has a canonical SHA-256
282
+ fingerprint, so identical evidence does not manufacture a hosted revision. The client mirrors the
283
+ hosted 8 MiB / 25,000-node / 100,000-edge / 50,000-external-import safety limits before networking.
284
+
285
+ If a network tool is not listed by the MCP client, that is the expected offline default. With the
286
+ user's approval, select `osv` for advisory refresh only or `hosted` for the hosted workflow,
287
+ restart/reconnect the MCP server, and then invoke the intended tool. Enabling a profile does not
288
+ trigger a request by itself.
289
+
290
+ Profiles (`offline`, `pinned`, `osv`, `hosted`, `full`) or exact capability groups (`graph`,
291
+ `search`, `source`, `health`, `build`, `retarget`, `crossrepo`, `advisories`, `hosted`) are selectable through
292
+ the final positional argument. Omitted caps use `offline`; an explicit capability list exposes
293
+ exactly the named groups. Legacy `online` expands to `advisories,hosted` for compatibility.
210
294
 
211
295
  ## Security model
212
296
 
@@ -215,12 +299,12 @@ vulnerability findings. This is where each capability comes from and how it is c
215
299
 
216
300
  | Capability alert | Why it exists | Activation and boundary |
217
301
  |---|---|---|
218
- | Network access | `refresh_advisories` sends pinned package names and versions to OSV; `sync_graph` sends a versioned allowlist of graph metadata (relative paths, symbols and line ranges, import/dependency identifiers, edges and numeric metrics). It discards unknown graph fields and does not read source file bodies | `online` is disabled by default; each request requires a tool call, and sync additionally requires `WEAVATRIX_SYNC_URL` |
302
+ | Network access | `refresh_advisories` sends pinned package names and versions to OSV; `pull_architecture_contract` sends an opaque repository UUID and receives an owner-approved contract; `sync_graph` sends a normalized repository label plus an allowlisted graph/evidence payload. Evidence is derived locally from source and manifests, but source bodies, snippets, absolute paths, environment values, credentials and Git remotes are excluded | `offline` and `pinned` expose no network tools. `osv` exposes only advisory refresh. `hosted`/`full` expose all three; every request still requires an explicit tool call, and hosted calls require `WEAVATRIX_SYNC_URL` |
219
303
  | Shell access | Local `git` powers staleness/change impact; `rg` accelerates search; timed-out Windows child processes may be terminated | Used only by the corresponding local operation; it does not imply network access |
220
304
  | Debug / dynamic loading | Cache-busted `import()` hot-reloads watched MCP tool entry modules; `createRequire` loads package metadata and parser dependencies | Loads files from the installed package; no `eval` |
221
- | Environment access | Reads `WEAVATRIX_*` configuration; local child processes inherit the normal host environment | `WEAVATRIX_SYNC_TOKEN` is removed from every child-process and worker environment and read only by `sync_graph` |
222
- | Filesystem access | Reads the active repository, graph, lockfiles and coverage reports; writes derived graphs and advisory cache | Realpath containment blocks traversal and symlink/junction escapes. `open_repo` is an explicit offline call that changes the active boundary; omit `retarget` in a custom capability list to pin one repository. The optional malware dependency scan may inspect installed dependency caches such as GOPATH |
223
- | URL strings | Fixed OSV/documentation URLs plus a user-configured sync URL | A URL string causes no request by itself; only the two `online` tools perform requests |
305
+ | Environment access | Reads `WEAVATRIX_*` configuration; local child processes inherit the normal host environment | `WEAVATRIX_SYNC_TOKEN` is removed from every child-process and worker environment and read only by `sync_graph` / `pull_architecture_contract` |
306
+ | Filesystem access | Reads the active repository, graph, lockfiles and coverage reports; writes derived graphs and advisory/architecture caches | Realpath containment blocks traversal and symlink/junction escapes. The `pinned` profile removes `open_repo`; the default `offline` profile permits only explicit local switching. The optional malware dependency scan may inspect installed dependency caches such as GOPATH |
307
+ | URL strings | Fixed OSV/documentation URLs plus a user-configured sync URL | A URL string causes no request by itself; only the three network-profile tools perform requests |
224
308
 
225
309
  `read_source` accepts repo-relative regular files only, caps a read at 2 MB, and refuses lexical or
226
310
  realpath escapes. Graph-derived paths pass through the same boundary before analysis tools read
@@ -234,8 +318,9 @@ native compilation.
234
318
 
235
319
  ## On-disk layout
236
320
 
237
- Graphs are derived data and never live inside your repo: they go to a `weavatrix-graphs/` folder
238
- **next to** it (one folder per repo, holding `graph.json` + `graph.prev.json`).
321
+ Graphs are derived data and never live inside your repo: the global per-user registry stores them at
322
+ `~/.weavatrix/graphs/<repository-storage-key>/` (including `.repository-id`, `graph.json`, and
323
+ `graph.prev.json`).
239
324
 
240
325
  ## Development
241
326
 
package/SECURITY.md CHANGED
@@ -21,11 +21,28 @@ mitigation is available so users have a reasonable opportunity to update.
21
21
 
22
22
  ## Security boundaries
23
23
 
24
- The default MCP registration is offline. Every standard source, manifest, configuration and coverage
25
- read is canonical-path-contained within the active repository and rejects traversal plus symlink or
26
- junction escapes. The optional malware dependency scan may inspect installed dependency caches such
27
- as GOPATH. The default `retarget` capability exposes `open_repo`, an explicit offline tool call that
28
- intentionally changes the active repository; omit that group in a custom capability list to pin one
29
- boundary. The optional `online` capability contains Weavatrix's HTTP tools; `sync_graph`
30
- additionally requires a user-configured endpoint and sends only a versioned metadata allowlist,
31
- discarding unknown fields from the local graph cache.
24
+ The default `offline` MCP profile exposes no HTTP tools. Every standard source, manifest,
25
+ configuration and coverage read is canonical-path-contained within the active repository and rejects
26
+ traversal plus symlink or junction escapes. The optional malware dependency scan may inspect installed
27
+ dependency caches such as GOPATH. `offline` permits repository switching only through an explicit
28
+ local `open_repo` call; select `pinned` to remove that tool, the global repository listing, and
29
+ cross-repository API tracing, holding a hard startup-repository boundary.
30
+
31
+ Network capabilities are split by purpose. `osv` adds only `refresh_advisories`, which sends pinned
32
+ package names and versions to OSV.dev when called. `hosted` / `full` also expose `sync_graph` and
33
+ `pull_architecture_contract`; both require a user-configured endpoint, and contract pull requires
34
+ bearer authentication. The legacy `online` capability remains an alias for advisory plus hosted
35
+ networking so existing registrations do not break.
36
+
37
+ Payload v3 runs bounded local analyzers over the active repository, then sends only a strict
38
+ graph/evidence allowlist plus a normalized repository display name. That evidence can include a
39
+ bounded direct/transitive lockfile dependency graph and stable clone/divergence candidates. The
40
+ contract has no source-body,
41
+ snippet, absolute-host-path, environment, credential, Git-remote or analyzer-error fields; unknown
42
+ fields are discarded and unsafe optional path metadata is omitted. V3 rejects stale graphs,
43
+ duplicate node IDs, dangling edges and oversized payloads before any request. Graph-only payload v2
44
+ remains an explicit compatibility option and is never selected as a silent fallback.
45
+
46
+ `pull_architecture_contract` sends only the active repository's opaque stable UUID, receives an
47
+ owner-approved target contract, validates it, and caches it locally. It never sends source, symbols,
48
+ file paths, or Git metadata.
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "weavatrix",
3
- "version": "0.1.4",
3
+ "version": "0.2.0",
4
4
  "type": "module",
5
5
  "description": "Weavatrix — code graph & blast-radius MCP server for AI coding agents: change impact, transitive dependents, health audit, duplicate detection, and coverage mapping over any local repository.",
6
- "author": "Sergii Ziborov <sergii@edgehawk.io>",
6
+ "author": "Sergii Ziborov <sergii.ziborov@gmail.com>",
7
7
  "license": "MIT",
8
8
  "homepage": "https://weavatrix.com",
9
9
  "repository": {
package/skill/SKILL.md CHANGED
@@ -1,13 +1,14 @@
1
1
  ---
2
2
  name: weavatrix
3
- description: Drive the weavatrix MCP — code graph, blast-radius (get_dependents/change_impact), health audit, duplicates, coverage, endpoints — over any local repo. Use when analyzing code structure, refactor risk, dead code, dependency health, or before opening a PR.
3
+ description: Drive the weavatrix MCP — code graph, blast-radius (get_dependents/change_impact), dead-code review, health audit, duplicates, coverage, endpoints — over any local repo. Use when analyzing code structure, refactor risk, dead code, dependency health, or before opening a PR.
4
4
  ---
5
5
 
6
6
  # weavatrix MCP
7
7
 
8
8
  Structure-analysis tools over a prebuilt code graph plus the weavatrix analysis engines. The default
9
- is offline and includes `open_repo` for one-call switching between local Git repositories. A custom
10
- capability list that omits `retarget` pins the registration to its initial repository.
9
+ `offline` profile has every HTTP tool disabled and permits repository switching only through an
10
+ explicit local `open_repo` call. Use `pinned` when a shared MCP process must never change or inspect
11
+ outside its startup repository.
11
12
 
12
13
  ## Step 0 — if the tools are missing
13
14
 
@@ -15,17 +16,30 @@ Tools are named `mcp__weavatrix__…`. If none are available, ask the user to re
15
16
  (`claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot>`; Codex:
16
17
  `codex mcp add weavatrix -- npx -y weavatrix <repoRoot>`), then retry.
17
18
 
18
- If only `refresh_advisories` or `sync_graph` is missing, do not diagnose a broken installation:
19
- `online` is intentionally absent from the default capability list.
19
+ If `refresh_advisories`, `pull_architecture_contract`, or `sync_graph` is missing, do not diagnose a
20
+ broken installation: network tools are intentionally absent from `offline` and `pinned`.
21
+
22
+ Profiles use the same npm package and binary:
23
+
24
+ - `offline` (default): all local analysis and explicit `open_repo`; no HTTP tools.
25
+ - `pinned`: local analysis with no `open_repo`, no global/cross-repository graph access, and no HTTP tools.
26
+ - `osv`: `offline` plus explicit `refresh_advisories`.
27
+ - `hosted` / `full`: `osv` plus `pull_architecture_contract` and `sync_graph`.
28
+
29
+ The legacy `online` capability remains a compatibility alias for `advisories,hosted`; prefer the
30
+ named profiles for new registrations.
20
31
 
21
32
  ## Ground rules
22
33
 
23
34
  - **Evidence, not verdicts**: treat audit, hub, orphan and duplicate output as hypotheses. Confirm a
24
35
  finding in source and check framework/runtime conventions before deleting, merging or redesigning
25
36
  code. A same-name/different-body pair is a divergence candidate, not proof of duplication.
26
- - **Freshness**: every graph tool appends a staleness warning when the repo has commits newer than
27
- the graph. Act on it: `rebuild_graph`. A normal `open_repo` builds missing graphs and upgrades
28
- pre-`0.1.4` graphs to edge metadata v2; `build:false` deliberately refuses that upgrade.
37
+ - **Freshness**: graph/health calls automatically reconcile the active graph, while cross-repository
38
+ tracing reconciles every selected registered graph. Read the structured `refresh` /
39
+ `graphReconciliation` status: `none`, `incremental`, `full`, or explicitly `PARTIAL`. Use
40
+ `rebuild_graph` only when automatic reconciliation reports a fallback/error or when intentionally
41
+ changing build mode. A normal `open_repo` builds missing graphs and upgrades legacy schemas;
42
+ `build:false` deliberately refuses that upgrade.
29
43
  - **Ambiguity**: `get_node`/`get_neighbors`/`get_dependents` disclose `matched N nodes; using the
30
44
  best-connected` — read that note before trusting the answer; pass an exact node id to pin it.
31
45
  - **Runtime versus compile time**: keep runtime cycles separate from TypeScript type-only and
@@ -35,26 +49,38 @@ If only `refresh_advisories` or `sync_graph` is missing, do not diagnose a broke
35
49
  compile-time-only edges.
36
50
  - **Repository universe**: in Git repositories, graph and duplicate scans include tracked plus
37
51
  non-ignored untracked files. If an old graph still contains packaged/generated output, rebuild it
38
- before interpreting the result.
52
+ before interpreting the result. Repository-root `.weavatrixignore` applies the same tracked-file
53
+ exclusions to graph, audit and duplicate passes; use it for generated/e2e fixtures that must stay
54
+ committed. `no-tests` also recognizes Cypress, Playwright, `test-e2e`, acceptance and integration
55
+ roots. Dead-code/clone/audit review also suppresses `benchmarks/**` and `**/__temp/**` as classified
56
+ non-production surfaces. A verified production benchmark can opt back in narrowly through
57
+ `.weavatrix.json` `classify.product`, for example `{"classify":{"product":["benchmarks/core/**"]}}`.
58
+ - **Architectural queries**: for bootstrap/routing/authentication questions, inspect the returned
59
+ seeds before trusting the traversal. Pass exact repository-relative `seed_files` to `query_graph`
60
+ when the intended entry points are already known.
39
61
  - **Coverage**: `coverage_map` reads an existing report. `unavailable` means no supported report was
40
62
  found, not 0% coverage; do not rank testing risk from that state.
41
63
  - **Audit completeness**: read `checks.osv.status` and `checks.malware.status`. For OSV, `OK` is
42
64
  complete for the recorded dependency fingerprint; `PARTIAL` is incomplete or stale,
43
65
  `NOT_CHECKED` has no repository-specific result, and `ERROR` means the local check failed. Treat
44
66
  the same non-`OK` states as incomplete for malware scanning. Refresh OSV only when the user has
45
- authorized adding the optional `online` capability group to the MCP registration and then
67
+ authorized selecting the optional `osv` profile (or `advisories` capability) and then
46
68
  invoking `refresh_advisories`; enabling the group alone sends nothing.
47
69
  - **Offline by design**: scans and graph queries run in-process against local files; coverage tools
48
- read existing reports and never run tests. The ONLY network-touching tools live in the `online`
49
- capability group and run solely when explicitly called: `refresh_advisories` (queries OSV.dev with
50
- package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (pushes a
51
- versioned allowlist of graph metadata, discarding unknown fields and never reading source file
52
- bodies for sync, to a user-configured endpoint; disabled until
53
- `WEAVATRIX_SYNC_URL` is set). `online` is
54
- absent from the default capability set and must be enabled explicitly.
70
+ read existing reports and never run tests. The ONLY network-touching tools live in the optional
71
+ `advisories` / `hosted` capabilities and run solely when explicitly called:
72
+ `refresh_advisories` (queries OSV.dev with
73
+ package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (derives a
74
+ bounded evidence snapshot locally, then pushes only an allowlisted graph/evidence contract to a
75
+ user-configured endpoint; analyzers may read local source, but the wire contract has no body,
76
+ snippet, absolute-host-path or environment fields, and unknown fields are discarded; disabled until
77
+ `WEAVATRIX_SYNC_URL` is set). `pull_architecture_contract` sends only the active repository's opaque
78
+ stable UUID, downloads the owner-approved contract, validates it, and caches it locally; it requires
79
+ `WEAVATRIX_SYNC_URL` and `WEAVATRIX_SYNC_TOKEN`. All three are absent from the default profile.
55
80
  - **Repository boundary**: source reads and graph-derived paths are realpath-contained. `open_repo`
56
- intentionally changes the active boundary through an explicit offline tool call. It is available
57
- by default; omit `retarget` from a custom capability list to hide it.
81
+ intentionally changes the active boundary through an explicit offline tool call. It is included in
82
+ `offline`, absent from `pinned`, and available in a custom registration only when `retarget` is
83
+ named. Concurrent non-mutating calls retain the graph/root snapshot with which they started.
58
84
 
59
85
  ## Recipes
60
86
 
@@ -65,12 +91,37 @@ If only `refresh_advisories` or `sync_graph` is missing, do not diagnose a broke
65
91
  and untracked work, coverage attached, untested hotspots called out) → drill with `get_dependents`.
66
92
  - **Impact of a PR that is NOT checked out**: pass its changed-file list explicitly —
67
93
  `change_impact files=[…]` — same blast-radius + coverage view, no checkout.
68
- - **Validate a refactor structurally**: edit `rebuild_graph` it reports the structural delta
69
- (cycle broken? new module dependency introduced? symbols orphaned?); re-query later with
70
- `graph_diff` (optionally scoped by `path`). The semantic complement to the textual git diff.
71
- - **Health sweep**: `run_audit` (filter by `category`/`min_severity`) `find_duplicates`
72
- `coverage_map`. Inspect the source behind shortlisted findings before proposing edits.
94
+ - **Validate a refactor structurally**: call `graph_diff base_ref=HEAD~1` (or `main` / `origin/main`)
95
+ to build an immutable baseline without checkout and compare it with the current graph. Alternatively,
96
+ edit → `rebuild_graph`, then use `graph_diff` without `base_ref` to compare `graph.prev.json` with
97
+ the rebuilt graph. Either route can be scoped by `path`; look for cycle, module-dependency and
98
+ orphan drift rather than raw edge counts.
99
+ - **Health sweep**: for a branch/PR review prefer
100
+ `run_audit base_ref=<merge-base> debt=new changed_files=[…]`; for repository maintenance use
101
+ `run_audit debt=all`. Then call `find_dead_code`, `find_duplicates` and `coverage_map`. A changed-file-only audit is
102
+ scope, not proof of new debt. Inspect the source behind shortlisted findings before proposing edits.
103
+ - **Dead-code and dead-method review**: call `find_dead_code` for a bounded production-code queue of
104
+ files, functions, methods and symbols. Narrow with `path` or `kinds=["method"]`; keep the default
105
+ `min_confidence=medium` for actionable internal candidates. Use `min_confidence=low` only when the
106
+ task explicitly needs public/exported, framework, dynamic-loading or reflection-sensitive review,
107
+ and carry each returned caveat into the recommendation. Pair it with
108
+ `run_audit category=unused debt=all` (or `base_ref=<merge-base> debt=new`) for unused exports and
109
+ dependencies. Before deletion, run `read_source`, `get_dependents`, exact `search_code`, inspect
110
+ framework discovery/annotations, package scripts, CLI/Docker/manifests, generated consumers and
111
+ test-only use, then run the repository tests. `REVIEW_REQUIRED` and `autoDelete:false` are hard
112
+ safety semantics, not boilerplate. Use `.weavatrix-deps.json` entrypoints/nonRuntimeRoots only for
113
+ verified conventions.
73
114
  - **API inventory**: `list_endpoints` (including Next.js App Router, Rust axum and actix-web).
115
+ - **Cross-repository API impact**: ensure both repositories are in `list_known_repos`, then call
116
+ `trace_api_contract backend=<uuid-or-label> clients=[<uuid-or-label>]`; narrow with `method`, `path`,
117
+ or backend `changed_files`. Treat unresolved/dynamic URLs as incomplete evidence, not a clean result.
118
+ - **Target architecture before editing**: `get_architecture_contract` → `prepare_change` with the
119
+ intended files → edit and rebuild → `verify_architecture`. A missing contract returns a starter
120
+ proposal, not an automatically approved architecture. Pull an owner-approved hosted contract only
121
+ when the user selected `hosted` and explicitly asks for it.
122
+ - **Behavioral architecture**: `git_history` ranks churn × connectivity hotspots and hidden
123
+ co-change coupling from bounded local numstat history. Use it as review evidence, not proof that two
124
+ files must be merged.
74
125
  - **Find code**: `search_code` (regex + glob) → `get_node` → `read_source`.
75
126
  - **Another repo**: `list_known_repos` → `open_repo <path>`
76
127
  (builds or upgrades the graph when needed; `build:false` probes without building).
@@ -102,18 +153,29 @@ visible. `managedDependencies` documents modules provided outside the repo's Pyt
102
153
 
103
154
  ## Sync
104
155
 
105
- `sync_graph` uses allowlisted payload v2, including type-only/compile-only edge metadata but no
106
- source bodies. A graph built before `0.1.4` must be rebuilt first; normal `open_repo` does this
107
- automatically. Sync remains
108
- unavailable until the user opts into `online` and configures `WEAVATRIX_SYNC_URL`.
156
+ `sync_graph` defaults to payload v3: graph metadata plus deterministic architecture, health, stack,
157
+ package-dependency and clone-review evidence. Read each section's `state`, `verdict` and completeness counts; `PARTIAL`,
158
+ `NOT_CHECKED` and `ERROR` are unknown/incomplete, never a clean result. Architecture evidence
159
+ contains concrete runtime versus compile-time cycles, declared boundary violations and separated
160
+ runtime/type-only/compile-only module dependencies. Package evidence contains a bounded lockfile
161
+ graph with direct/transitive runtime, dev, optional and peer edges plus explicit resolution counts.
162
+ Duplicate evidence contains stable, source-free clone/divergence candidates; it never sends method
163
+ bodies or snippets. Use `payload_version: 2` only when the user explicitly wants graph-only
164
+ compatibility—Weavatrix never silently downgrades. A graph built before `0.1.4`, or one stale against
165
+ the working tree, must be rebuilt first. Sync remains unavailable until the user selects `hosted`
166
+ (or the exact `hosted` capability) and configures `WEAVATRIX_SYNC_URL`.
109
167
 
110
168
  ## Troubleshooting
111
169
 
112
- - `Graph unavailable` → `rebuild_graph`; `open_repo` can select another valid repository path unless
170
+ - `Graph unavailable` → `rebuild_graph`; normal graph/health calls automatically refresh an existing
171
+ graph and report `none`, `incremental`, or `full`. `open_repo` can select another valid repository path unless
113
172
  the registration deliberately omitted `retarget`.
114
173
  - `refresh_advisories` is unavailable → with the user's approval, re-register/reconfigure the MCP
115
- capability list to include `online`, reconnect it, and then invoke the tool. Do not enable network
174
+ with the `osv` profile, reconnect it, and then invoke the tool. Do not enable network
116
175
  access merely to turn `NOT_CHECKED` into a cosmetic green state.
176
+ - `pull_architecture_contract` / `sync_graph` is unavailable → use the `hosted` profile only after
177
+ the user chooses hosted integration; configure `WEAVATRIX_SYNC_URL` and a bearer token for contract
178
+ pull. Profile selection alone never performs a request.
117
179
  - `No coverage report` → run the repo's own tests with coverage (`vitest run --coverage`,
118
180
  `jest --coverage`, `pytest --cov --cov-report=json`, `go test -coverprofile=coverage.out`),
119
181
  then re-call.