weavatrix 0.2.8 → 0.2.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +82 -27
- package/SECURITY.md +30 -7
- package/docs/releases/v0.2.9.md +123 -0
- package/package.json +3 -3
- package/skill/SKILL.md +12 -7
- package/src/analysis/duplicate-groups.js +11 -2
- package/src/analysis/endpoints.js +209 -9
- package/src/mcp/catalog.mjs +13 -10
- package/src/mcp/evidence-snapshot.package-graph.mjs +257 -3
- package/src/mcp/graph-context.mjs +36 -1
- package/src/mcp/tools-actions.mjs +170 -36
- package/src/mcp/tools-context.mjs +25 -8
- package/src/mcp/tools-endpoints.mjs +162 -0
- package/src/mcp/tools-graph.mjs +1 -1
- package/src/mcp/tools-health.mjs +70 -41
- package/src/mcp/tools-source.mjs +3 -3
- package/src/mcp-server.mjs +30 -2
- package/src/mcp-source-tools.mjs +10 -7
- package/docs/releases/v0.2.8.md +0 -82
package/README.md
CHANGED
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
**Code graph & blast-radius MCP server for AI coding agents.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
Codex, or any MCP client
|
|
8
|
-
coverage mapping.
|
|
5
|
+
Weavatrix builds and compares the living architecture of any local repository: files, symbols,
|
|
6
|
+
imports, calls, inheritance, health findings, clone families and Git-history coupling. It serves that
|
|
7
|
+
evidence to Claude Code, Codex, or any MCP client for change impact, transitive dependents, health
|
|
8
|
+
audit, clone detection and coverage mapping. Text search is included as a convenience, not the product
|
|
9
|
+
core. **38 tools available; 34 enabled by the default offline profile. Local-first: with
|
|
9
10
|
the defaults, no repository data leaves your machine.**
|
|
10
11
|
|
|
11
12
|
- Website: [weavatrix.com](https://weavatrix.com)
|
|
@@ -14,8 +15,8 @@ the defaults, no repository data leaves your machine.**
|
|
|
14
15
|
|
|
15
16
|
## Why
|
|
16
17
|
|
|
17
|
-
An AI agent editing code without
|
|
18
|
-
answers
|
|
18
|
+
An AI agent editing code without architecture, health and history evidence is refactoring blind.
|
|
19
|
+
Weavatrix answers questions a text index cannot:
|
|
19
20
|
|
|
20
21
|
- *"What breaks if I change this?"* → `change_impact` diffs your branch (staged, unstaged and
|
|
21
22
|
untracked included), maps the changed files and symbols onto the graph, and lists everything that
|
|
@@ -28,6 +29,9 @@ answers grep can't produce:
|
|
|
28
29
|
- *"Did my refactor actually decouple anything?"* → `graph_diff base_ref=HEAD~1` builds an immutable
|
|
29
30
|
baseline graph without checking it out, then reports the structural delta: new module
|
|
30
31
|
dependencies, broken or introduced import cycles, and symbols that lost their last caller.
|
|
32
|
+
- *"Where is the repo rotting or repeating itself?"* → `run_audit`, `find_dead_code`,
|
|
33
|
+
`find_duplicates`, `hot_path_review` and `git_history` combine deterministic findings, graph
|
|
34
|
+
connectivity and co-change evidence instead of treating a matching string as an architecture fact.
|
|
31
35
|
|
|
32
36
|
- *"Is this change actually safe?"* -> `verified_change` accepts the task plus current diff/files and
|
|
33
37
|
returns one proof-carrying `PASS`, `BLOCKED`, or `UNKNOWN`: compact edit contexts, exact-symbol
|
|
@@ -67,7 +71,7 @@ argument when a stricter repository boundary or a network feature is wanted:
|
|
|
67
71
|
| `offline` (default) | Yes, only through `open_repo` | Yes, only through `trace_api_contract` | No | No |
|
|
68
72
|
| `pinned` | No | No | No | No |
|
|
69
73
|
| `osv` | Yes | Yes, only when called | Only when `refresh_advisories` is called | No |
|
|
70
|
-
| `hosted` / `full` | Yes | Yes, only when called | Only when called |
|
|
74
|
+
| `hosted` / `full` | Yes | Yes, only when called | Only when called | `preview_sync` is local; only `sync_graph` or `pull_architecture_contract` can make a request |
|
|
71
75
|
|
|
72
76
|
```sh
|
|
73
77
|
# Hard-pin one repository and expose no network tools:
|
|
@@ -125,7 +129,7 @@ confirmed by its bundled `typescript-language-server` + TypeScript runtime to `E
|
|
|
125
129
|
`CONFLICT` means evidence disagrees. `graph_stats` reports the provenance breakdown and the semantic
|
|
126
130
|
provider's `COMPLETE`, `PARTIAL`, `UNAVAILABLE`, or `OFF` state; `OFF` means precision was explicitly
|
|
127
131
|
disabled and only static evidence is active. Java and Rust language-server providers are not bundled
|
|
128
|
-
in 0.2.
|
|
132
|
+
in 0.2.9: their edges never become `EXACT_LSP`, even when a mixed repository reports a complete
|
|
129
133
|
TypeScript/JavaScript overlay.
|
|
130
134
|
|
|
131
135
|
The bounded JS/TS provider is enabled by default for new graphs. Set `WEAVATRIX_PRECISION=off`
|
|
@@ -133,21 +137,28 @@ before starting the MCP server for parser-only operation from the first build, o
|
|
|
133
137
|
`precision:"off"` to `rebuild_graph` / `open_repo`. The MCPB installer exposes the same `lsp` / `off`
|
|
134
138
|
choice as **TypeScript/JavaScript semantic precision**.
|
|
135
139
|
|
|
136
|
-
**search / source** — `search_code` (ripgrep-backed, pure-Node fallback
|
|
140
|
+
**search / source** — `search_code` (ripgrep-backed, pure-Node fallback, with repository-relative
|
|
141
|
+
path globs on Windows/macOS/Linux), `read_source` (a
|
|
137
142
|
symbol's actual code in one hop), `context_bundle` (definition plus grouped inbound/outbound
|
|
138
|
-
containers, exact re-export sites
|
|
143
|
+
containers, exact re-export sites, call-site/target provenance and bounded excerpts around decisive
|
|
144
|
+
edges), `inspect_symbol` (one exact
|
|
139
145
|
bounded TS/JS reference query, logical containers, impact and source excerpts), `list_endpoints` (HTTP route inventory:
|
|
140
|
-
Express/Fastify/Nest/Flask/FastAPI/Go mux/Rust axum and actix-web
|
|
146
|
+
Express/Fastify/Nest/Flask/FastAPI/Go mux/Rust axum and actix-web, including nested Express
|
|
147
|
+
`router.use(...)` mount composition, declaration/reachability counts and mount provenance),
|
|
148
|
+
`trace_endpoint` (one exact composed route → handler → bounded production call graph with call-site excerpts)
|
|
141
149
|
|
|
142
150
|
**health** — `find_dead_code` (bounded review queue for statically unreferenced and test-only files,
|
|
143
151
|
functions, methods, and symbols, with evidence tiers, completed/remaining verification and explicit
|
|
144
152
|
public/framework/dynamic caveats),
|
|
145
|
-
`run_audit` (unused files/exports/dependencies with per-finding manifest/indexed-source/script/config verification
|
|
153
|
+
`run_audit` (unused files/exports/dependencies with per-finding manifest/indexed-source/script/config verification;
|
|
154
|
+
`category:dependencies` isolates missing/unused/duplicate declarations, unresolved imports and lockfile drift,
|
|
146
155
|
missing npm/Go/Python deps, runtime
|
|
147
156
|
cycles, type-only/compile-only coupling, orphans, boundary rules, offline OSV vulnerabilities + typosquat +
|
|
148
157
|
lockfile drift; accepts an immutable `base_ref`, `changed_files`, and `debt: new|existing|all` for
|
|
149
|
-
review-scoped results
|
|
150
|
-
|
|
158
|
+
review-scoped results; production paths are the default and `include_classified:true` opts into
|
|
159
|
+
test/generated/docs evidence), `find_duplicates` (MOSS winnowing over method bodies — catches copy-paste even
|
|
160
|
+
after renames and can inspect strict small clones down to 12 tokens; homogeneous router boilerplate
|
|
161
|
+
is suppressed unless `include_boilerplate:true`), `coverage_map` (existing coverage reports mapped onto the graph; untested hotspots
|
|
151
162
|
ranked by connectivity — tests are never executed), `hot_path_review` (bounded local-cost evidence
|
|
152
163
|
with separate graph/test risk), `verify_architecture`,
|
|
153
164
|
`explain_architecture_violation`, `propose_architecture_exception`
|
|
@@ -197,24 +208,59 @@ not CFG, value-propagation, or taint analysis.
|
|
|
197
208
|
|
|
198
209
|
`query_graph` accepts optional `seed_files` when an architectural question must start from exact
|
|
199
210
|
entry points. Resolved explicit seeds are exclusive by default; set `augment_seeds:true` only when
|
|
200
|
-
question-derived seeds are also wanted.
|
|
211
|
+
question-derived seeds are also wanted. A code-shaped identifier such as `startMitigate` is treated
|
|
212
|
+
as a stronger bounded seed than surrounding words such as controller/service/flow; all exact
|
|
213
|
+
same-name declarations are retained instead of adding unrelated concept seeds. Broad
|
|
214
|
+
bootstrap/tool-execution/routing questions rank
|
|
201
215
|
conventional executables and graph-declared production entry points ahead of site, documentation, benchmark
|
|
202
216
|
and fixture matches. Production-first classification also applies during traversal, so unrelated
|
|
203
217
|
tests/generated/docs/benchmarks do not leak back from a production seed; name a class in the
|
|
204
218
|
question or set `include_classified:true` to include it. Unreferenced unmatched constant/field leaves
|
|
205
219
|
are hidden unless `include_low_signal:true`. Broad ranking remains orientation evidence; use
|
|
206
|
-
`seed_files` when the intended entry point is already known.
|
|
220
|
+
`seed_files`, an exact endpoint, or `inspect_symbol` when the intended entry point is already known.
|
|
221
|
+
Instruction words such as “REST”, “path”, and “inspect” do not become fuzzy code seeds.
|
|
207
222
|
|
|
208
223
|
**advisories** *(network, explicit opt-in)* — `refresh_advisories`
|
|
209
224
|
|
|
210
|
-
**hosted** *(
|
|
225
|
+
**hosted** *(explicit opt-in; preview is local, send/pull are networked)* — `preview_sync`,
|
|
226
|
+
`pull_architecture_contract`, `sync_graph`. `preview_sync` performs no request and returns the destination,
|
|
227
|
+
repository UUID, exact payload fields/sections/size/hash and a short-lived confirmation token for
|
|
228
|
+
the cached payload. `sync_graph` sends only with both that token and `dry_run:false`; its legacy
|
|
229
|
+
dry-run form remains a no-network compatibility alias.
|
|
211
230
|
|
|
212
231
|
Quality of life: graph/health reads auto-reconcile and expose `none` / `incremental` / `full`
|
|
213
232
|
freshness, with a short clean-read debounce to avoid rescanning the repository for every tool call;
|
|
214
233
|
ambiguous name lookups are
|
|
215
234
|
disclosed instead of silently guessed; and the server **hot-reloads its watched MCP tool entry
|
|
216
235
|
modules and catalog** when those files change — other MCP helpers and analysis engines require a
|
|
217
|
-
reconnect.
|
|
236
|
+
reconnect. Every MCP response also carries local, transient `_meta["weavatrix/metrics"]` with elapsed
|
|
237
|
+
time, output bytes/token estimate, graph freshness/revision/update and graph-cache status. These
|
|
238
|
+
metrics are not persisted or transmitted by Weavatrix.
|
|
239
|
+
|
|
240
|
+
### 0.2.9 correctness, signal, and consent patch
|
|
241
|
+
|
|
242
|
+
- Express endpoint inventory composes nested imported `router.use(...)` mounts, so a local route such
|
|
243
|
+
as `/:attackId/startMitigate` is reported with its reachable `/warRoom/attack` prefix, declared vs
|
|
244
|
+
reachable counts and the exact static mount chain. `trace_endpoint` continues from that route into
|
|
245
|
+
the bounded call graph and call-site excerpts.
|
|
246
|
+
- `context_bundle` keeps the call-site file/line separate from the target definition and adds bounded
|
|
247
|
+
excerpts around decisive edges instead of stopping inside a long leading comment.
|
|
248
|
+
- `search_code` applies documented repository-relative path globs correctly when ripgrep runs on
|
|
249
|
+
Windows. Broad `query_graph` prompts no longer turn generic REST/instruction words into noisy
|
|
250
|
+
configuration-file seeds, and code-shaped identifiers outrank generic controller/service/flow
|
|
251
|
+
concepts.
|
|
252
|
+
- `run_audit` is production-first by default while retaining explicit access to classified evidence;
|
|
253
|
+
`category:dependencies` provides a focused dependency-health slice;
|
|
254
|
+
duplicate review suppresses homogeneous Express router boilerplate unless requested.
|
|
255
|
+
- the separate no-network `preview_sync` produces the exact payload approval artifact; `sync_graph`
|
|
256
|
+
requires that preview followed by an exact short-lived confirmation token,
|
|
257
|
+
validates the configured destination, requires HTTPS outside loopback, and never networks during
|
|
258
|
+
preview. Contract-pull HTTP failures expose actionable auth/not-found/not-ready states.
|
|
259
|
+
- Every MCP call exposes transient local execution/output/freshness metrics without collection or
|
|
260
|
+
egress. The public site, privacy/security pages, package metadata and license presentation now
|
|
261
|
+
describe the same 38-tool/34-offline surface and the same network boundary.
|
|
262
|
+
|
|
263
|
+
Full patch notes: [docs/releases/v0.2.9.md](docs/releases/v0.2.9.md).
|
|
218
264
|
|
|
219
265
|
### 0.2.8 trust and precision patch
|
|
220
266
|
|
|
@@ -492,20 +538,27 @@ Weavatrix itself initiates outbound HTTP only from three tools; all are absent f
|
|
|
492
538
|
- `pull_architecture_contract` — sends the active repository's opaque stable UUID with bearer
|
|
493
539
|
authentication, downloads the owner-approved target-architecture contract, validates it, and
|
|
494
540
|
stores the contract in the local graph cache. It sends no source, symbol, or repository path.
|
|
495
|
-
- `
|
|
541
|
+
- `preview_sync` — builds a bounded evidence snapshot locally without sending anything. The preview
|
|
542
|
+
shows the destination host/path, normalized repository name, opaque UUID,
|
|
543
|
+
payload version, exact top-level fields, included sections, node/link/byte counts and canonical
|
|
544
|
+
SHA-256 hash. A `sync_graph` call with `dry_run:false` and its exact short-lived `confirm_token` sends
|
|
545
|
+
the cached payload to the same destination. A token alone does not send while the default dry-run
|
|
546
|
+
remains active. It
|
|
547
|
+
sends payload v3: the v2 graph
|
|
496
548
|
allowlist plus module dependencies, runtime/compile-time cycles, declared boundary violations,
|
|
497
549
|
health findings, complexity-threshold breaches, stack identifiers, a bounded direct/transitive
|
|
498
550
|
dependency graph, direct package usage, and bounded clone/divergence review candidates. Local
|
|
499
551
|
analyzers may read repository source and manifests to derive those
|
|
500
552
|
facts. The wire contract has no fields for file bodies, snippets, absolute host paths, environment
|
|
501
553
|
values or Git remotes; unknown fields are discarded and unsafe optional path metadata is omitted.
|
|
502
|
-
The request also carries the normalized repository display name used by the
|
|
554
|
+
The confirmed request also carries the normalized repository display name used by the
|
|
503
555
|
hosted list. The endpoint is **yours**, configured through `WEAVATRIX_SYNC_URL` and the optional
|
|
504
556
|
`WEAVATRIX_SYNC_TOKEN`; the feature is off by default. Pass `payload_version: 2` only for an
|
|
505
557
|
intentional graph-only compatibility sync—there is no silent downgrade that discards evidence.
|
|
506
558
|
Graphs that predate current typed-edge/provenance metadata must be rebuilt once before V3 sync;
|
|
507
559
|
V3 also refuses a stale graph so
|
|
508
|
-
source-derived evidence cannot be mixed with old topology.
|
|
560
|
+
source-derived evidence cannot be mixed with old topology. HTTPS is required except for an
|
|
561
|
+
explicitly configured loopback endpoint; embedded URL credentials and fragments are rejected.
|
|
509
562
|
|
|
510
563
|
Evidence sections carry independent `state` (`COMPLETE`, `PARTIAL`, `NOT_CHECKED`,
|
|
511
564
|
`NOT_APPLICABLE`, `ERROR`) and `verdict` (`PASS`, `FAIL`, `UNKNOWN`) fields plus exact
|
|
@@ -531,7 +584,7 @@ vulnerability findings. This is where each capability comes from and how it is c
|
|
|
531
584
|
|
|
532
585
|
| Capability alert | Why it exists | Activation and boundary |
|
|
533
586
|
|---|---|---|
|
|
534
|
-
| 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
|
|
587
|
+
| 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; confirmed `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. Sync defaults to a no-network dry-run and then requires both `dry_run:false` and its exact short-lived token; hosted calls require `WEAVATRIX_SYNC_URL`, and non-loopback hosted endpoints require HTTPS |
|
|
535
588
|
| Shell access | Local `git` powers staleness/change impact; `rg` accelerates search; the bundled TLS/tsserver process supplies bounded JS/TS semantic evidence; timed-out Windows child trees may be terminated; `verified_change` can optionally run an existing package test/check/verify script | The semantic provider never invokes repository code. Test execution separately requires `run_tests:true` plus `WEAVATRIX_ALLOW_TEST_RUNS=1`, rejects arbitrary commands and shell-sensitive arguments, and should be enabled only for trusted repository scripts |
|
|
536
589
|
| 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` |
|
|
537
590
|
| Environment access | Reads `WEAVATRIX_*` configuration; ordinary local helpers inherit a credential-stripped environment, while TLS/tsserver receives only allowlisted OS/temp/locale values and a constrained executable path | `WEAVATRIX_SYNC_TOKEN` is removed from every child-process and worker environment. TLS/tsserver also receives no registry/proxy/cloud credentials or `NODE_OPTIONS` |
|
|
@@ -584,10 +637,10 @@ loader) behind the thin stdio entry `src/mcp-server.mjs`.
|
|
|
584
637
|
- **Wrapper-aware API contracts** shipped in 0.2.2: persistent/ad-hoc configuration,
|
|
585
638
|
conservative discovery, cross-repository handler liveness and explicit unknown states. The next
|
|
586
639
|
hosted increment joins privacy-safe contract identities across separately synced services.
|
|
587
|
-
- **Hosted architecture workbench**
|
|
588
|
-
[app.weavatrix.com](https://app.weavatrix.com)
|
|
589
|
-
|
|
590
|
-
|
|
640
|
+
- **Hosted architecture workbench** at
|
|
641
|
+
[app.weavatrix.com](https://app.weavatrix.com) is an access-controlled preview for
|
|
642
|
+
owner-authenticated source-free evidence and revision history. Its UI and backend evolve
|
|
643
|
+
independently from the public MCP release; local use remains fully optional.
|
|
591
644
|
- **Semantic precision bridge** shipped for TypeScript/JavaScript in 0.2.4: a bounded, revision-bound
|
|
592
645
|
local overlay validates references with the bundled language server while the parser graph remains
|
|
593
646
|
the fallback. Java and Rust providers are not bundled yet and stay explicitly `UNAVAILABLE`.
|
|
@@ -603,4 +656,6 @@ The public alignment note for the fixed cross-product release sequence is in
|
|
|
603
656
|
|
|
604
657
|
## License
|
|
605
658
|
|
|
606
|
-
[MIT](LICENSE) © 2026 Sergii Ziborov
|
|
659
|
+
The Weavatrix source in this repository is [MIT licensed](LICENSE) © 2026 Sergii Ziborov.
|
|
660
|
+
Third-party dependencies retain their own licenses. See the public
|
|
661
|
+
[license page](https://weavatrix.com/license) for the same notice.
|
package/SECURITY.md
CHANGED
|
@@ -2,8 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## Supported versions
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
| Version | Supported |
|
|
6
|
+
|---|---|
|
|
7
|
+
| `0.2.9.x` | Yes |
|
|
8
|
+
| `0.2.8` and older | Upgrade to the latest release |
|
|
9
|
+
|
|
10
|
+
Security fixes are provided for the latest published version of Weavatrix. Upgrade before reporting
|
|
11
|
+
an issue that may already be resolved.
|
|
7
12
|
|
|
8
13
|
## Reporting a vulnerability
|
|
9
14
|
|
|
@@ -61,10 +66,25 @@ scripts are repository-controlled code and may have arbitrary side effects, so e
|
|
|
61
66
|
for repositories and scripts you trust.
|
|
62
67
|
|
|
63
68
|
Network capabilities are split by purpose. `osv` adds only `refresh_advisories`, which sends pinned
|
|
64
|
-
package names and versions to OSV.dev when called. `hosted` / `full` also expose
|
|
65
|
-
`
|
|
66
|
-
bearer authentication. The legacy `online`
|
|
67
|
-
networking so existing registrations do not break.
|
|
69
|
+
package names and versions to OSV.dev when called. `hosted` / `full` also expose the local-only
|
|
70
|
+
`preview_sync` plus networked `sync_graph` and `pull_architecture_contract`; the network tools require
|
|
71
|
+
a user-configured endpoint, and contract pull requires bearer authentication. The legacy `online`
|
|
72
|
+
capability remains an alias for advisory plus hosted networking so existing registrations do not break.
|
|
73
|
+
|
|
74
|
+
`preview_sync` is the first half of a two-step consent boundary. It constructs the strict allowlisted
|
|
75
|
+
payload locally but has no network path. It displays the configured hostname/path, normalized
|
|
76
|
+
repository name, opaque repository UUID, payload version, included sections, node/link/byte counts
|
|
77
|
+
and canonical SHA-256 hash. Sending requires `sync_graph` with both `dry_run:false` and the exact
|
|
78
|
+
confirmation token for that cached payload and destination; the token
|
|
79
|
+
expires after five minutes and is stored only in process memory. A token with the default dry-run,
|
|
80
|
+
or an incorrect/expired token, does not send. Sync rejects
|
|
81
|
+
embedded URL credentials and fragments and requires HTTPS except for explicit loopback development
|
|
82
|
+
endpoints. Query parameters may be used by a configured endpoint but are not echoed in previews or
|
|
83
|
+
errors.
|
|
84
|
+
|
|
85
|
+
Every MCP response includes transient local `_meta["weavatrix/metrics"]` timing, output-size/token
|
|
86
|
+
estimate, graph freshness/revision/update and graph-cache status. Weavatrix does not persist, aggregate
|
|
87
|
+
or transmit these measurements; they are response evidence for the caller, not product telemetry.
|
|
68
88
|
|
|
69
89
|
Payload v3 runs bounded local analyzers over the active repository, then sends only a strict
|
|
70
90
|
graph/evidence allowlist plus a normalized repository display name. That evidence can include a
|
|
@@ -77,4 +97,7 @@ remains an explicit compatibility option and is never selected as a silent fallb
|
|
|
77
97
|
|
|
78
98
|
`pull_architecture_contract` sends only the active repository's opaque stable UUID, receives an
|
|
79
99
|
owner-approved target contract, validates it, and caches it locally. It never sends source, symbols,
|
|
80
|
-
file paths, or Git metadata.
|
|
100
|
+
file paths, or Git metadata. It applies the same HTTPS-outside-loopback and embedded-credential URL
|
|
101
|
+
rules before sending bearer authentication. Authentication, forbidden, not-found and repository-not-ready responses
|
|
102
|
+
are reported as distinct states so a missing registration or contract is not presented as an opaque
|
|
103
|
+
HTTP failure.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
# Weavatrix 0.2.9
|
|
2
|
+
|
|
3
|
+
## Correctness, signal, and consent
|
|
4
|
+
|
|
5
|
+
0.2.9 is a focused MCP correctness release driven by dogfooding on a 10,000-node JavaScript REST
|
|
6
|
+
service. It fixes cases where broad repository orientation was useful but precision tools handed an
|
|
7
|
+
agent incomplete paths, mismatched call-site provenance, or noisy review queues.
|
|
8
|
+
|
|
9
|
+
## Composed Express routes
|
|
10
|
+
|
|
11
|
+
`list_endpoints` now follows relative ESM/CommonJS router imports and nested `router.use(...)`
|
|
12
|
+
mounts. A handler declared as `/:attackId/startMitigate` below `/warRoom` and `/attack` is reported as
|
|
13
|
+
`/warRoom/attack/:attackId/startMitigate` while retaining its local declaration path. The inventory
|
|
14
|
+
separates declaration and reachable-route counts, labels local versus statically composed evidence,
|
|
15
|
+
and returns the exact mount files, lines and prefixes.
|
|
16
|
+
|
|
17
|
+
Composition is intentionally bounded. Dynamic mount expressions that cannot be resolved statically
|
|
18
|
+
remain local-path evidence rather than guessed full routes.
|
|
19
|
+
|
|
20
|
+
The new `trace_endpoint` tool resolves one exact composed route, binds its handler without silently
|
|
21
|
+
choosing among same-name symbols, and traverses a bounded production-only call graph with excerpts at
|
|
22
|
+
the actual edge lines. On the dogfood route it recovered router mount provenance, controller:268,
|
|
23
|
+
service, messaging and task calls in one graph-anchored response.
|
|
24
|
+
|
|
25
|
+
## Edge-centered source context
|
|
26
|
+
|
|
27
|
+
`context_bundle` now keeps two facts separate:
|
|
28
|
+
|
|
29
|
+
- the file and line containing an outbound call;
|
|
30
|
+
- the target symbol's definition file.
|
|
31
|
+
|
|
32
|
+
The compact source bundle prioritizes the definition and bounded excerpts around decisive inbound and
|
|
33
|
+
outbound edge lines. Long Swagger/JSDoc comments at the beginning of a controller therefore no longer
|
|
34
|
+
consume the only excerpt before the real service call.
|
|
35
|
+
|
|
36
|
+
## Search and retrieval signal
|
|
37
|
+
|
|
38
|
+
- Ripgrep-backed `search_code` runs from the repository root, so documented relative globs such as
|
|
39
|
+
`services/attack/**` behave consistently on Windows, macOS, and Linux.
|
|
40
|
+
- Broad `query_graph` prompts discard generic REST/instruction terms before fuzzy seeding and use a
|
|
41
|
+
smaller automatic seed set. When prose contains a code-shaped identifier such as `startMitigate`,
|
|
42
|
+
its exact same-name declarations are exclusive automatic seeds; generic controller/service/flow
|
|
43
|
+
words cannot add unrelated modules. Exact files, endpoints, and symbols remain the preferred
|
|
44
|
+
precision path.
|
|
45
|
+
|
|
46
|
+
## Production-first review queues
|
|
47
|
+
|
|
48
|
+
- `run_audit` suppresses findings whose evidence is entirely in tests, generated output, docs,
|
|
49
|
+
benchmarks, fixtures, mocks, or stories. `include_classified:true` restores the full diagnostic
|
|
50
|
+
view; mixed production/non-production evidence remains visible by default.
|
|
51
|
+
- `run_audit category=dependencies` projects missing, unused and duplicate declarations, unresolved
|
|
52
|
+
imports and lockfile drift into one dependency-health review without relabelling their native
|
|
53
|
+
deterministic finding identities.
|
|
54
|
+
- `find_duplicates` suppresses groups made entirely of router boilerplate by default.
|
|
55
|
+
`include_boilerplate:true` restores them for framework-template review.
|
|
56
|
+
- Incomplete OSV coverage remains explicit as `NOT_CHECKED`; this release does not turn missing
|
|
57
|
+
advisory data into a clean security verdict.
|
|
58
|
+
|
|
59
|
+
## Preview-confirm graph sync
|
|
60
|
+
|
|
61
|
+
`preview_sync` and `sync_graph` are now a two-step consent flow:
|
|
62
|
+
|
|
63
|
+
1. `preview_sync` builds and validates the strict payload allowlist locally and has no network path.
|
|
64
|
+
2. Display the destination, repository identity, exact top-level fields, payload
|
|
65
|
+
version/sections/size/hash and return a short-lived confirmation token.
|
|
66
|
+
3. `sync_graph` sends only the exact cached payload when it supplies both `dry_run:false` and that token
|
|
67
|
+
within five minutes. A token alone remains a no-network dry-run.
|
|
68
|
+
|
|
69
|
+
Incorrect or expired tokens never send. Sync also rejects embedded URL credentials/fragments and
|
|
70
|
+
requires HTTPS except for loopback development endpoints. URL query values are not echoed in previews
|
|
71
|
+
or errors.
|
|
72
|
+
|
|
73
|
+
`pull_architecture_contract` applies the same HTTPS-outside-loopback and embedded-credential URL
|
|
74
|
+
rules before sending bearer authentication. It now distinguishes authentication, forbidden,
|
|
75
|
+
repository-not-registered, endpoint-not-found, repository-not-ready and general HTTP failures.
|
|
76
|
+
Hosted's `REPOSITORY_NOT_FOUND` response is therefore no longer confused with a wrong endpoint;
|
|
77
|
+
`NOT_CONFIGURED` explicitly means sync/authentication succeeded but no target contract was saved.
|
|
78
|
+
|
|
79
|
+
## Per-call metrics without telemetry
|
|
80
|
+
|
|
81
|
+
Every MCP response carries transient local `_meta["weavatrix/metrics"]`: duration, text/structured
|
|
82
|
+
bytes, estimated output tokens, graph freshness/revision/update and graph-cache status. These values
|
|
83
|
+
are returned to the caller only; Weavatrix does not persist, aggregate or transmit them.
|
|
84
|
+
|
|
85
|
+
## Public contract alignment
|
|
86
|
+
|
|
87
|
+
The README, package manifests, public home page, privacy policy, security policy, and new public
|
|
88
|
+
license/security pages now describe the same 38-tool surface, 34-tool offline default, preview-confirm
|
|
89
|
+
sync behavior, and source/data boundary. The optional Hosted workbench is described as an
|
|
90
|
+
independently evolving access-controlled preview. Payload v3 is unchanged, so existing Hosted storage,
|
|
91
|
+
history and evidence readers remain wire-compatible; Hosted contract tests validate v1/v2/v3.
|
|
92
|
+
|
|
93
|
+
## Compatibility
|
|
94
|
+
|
|
95
|
+
The release adds `trace_endpoint` to the local source surface and `preview_sync` to the explicit
|
|
96
|
+
Hosted surface, taking the catalog from 36 to 38 tools and the default offline profile from 33 to 34.
|
|
97
|
+
Existing offline, pinned, osv, hosted, full and legacy online capability names remain valid.
|
|
98
|
+
`sync_graph` retains its no-network dry-run compatibility form, but `preview_sync` is the canonical
|
|
99
|
+
approval step for new clients.
|
|
100
|
+
|
|
101
|
+
## Verification
|
|
102
|
+
|
|
103
|
+
- Full Node suite: 502 tests, 499 passed, 3 platform skips, 0 failed.
|
|
104
|
+
- Deterministic six-language, cross-repository, framework-convention and MCP lifecycle benchmark:
|
|
105
|
+
`PASS`.
|
|
106
|
+
- Real pinned corpus: 6 of 6 repositories `PASS` across TypeScript, JavaScript, Python, Go, Java and
|
|
107
|
+
Rust.
|
|
108
|
+
- Release metadata consistency: `PASS`; production npm audit: 0 vulnerabilities; npm 0.2.9 package
|
|
109
|
+
dry-run: 154 files, 413,993 bytes.
|
|
110
|
+
- Portable MCPB: manifest validation `PASS`; archive built at 6.7 MiB
|
|
111
|
+
(`5a5def22491bc0777c882c314b12be7153d56d29`). The local archive is unsigned.
|
|
112
|
+
- Direct `controller-rest-api` dogfood: 1,076 indexed files and 989 reachable composed endpoints;
|
|
113
|
+
public and internal composed
|
|
114
|
+
`startMitigate` routes found; documented attack glob returned real matches; context preserved
|
|
115
|
+
`controller:268 → service` with the call excerpt; production-first audit retained the manually
|
|
116
|
+
confirmed missing `mongodb` declaration and explicit `OSV NOT_CHECKED`; 2 router-only clone groups
|
|
117
|
+
were separated from 60 default groups; exact identifier seeding returned only controller, service
|
|
118
|
+
and messaging declarations.
|
|
119
|
+
|
|
120
|
+
Focused regressions cover nested Express mounts, call-site/target provenance and edge excerpts,
|
|
121
|
+
Windows path globs, generic REST and exact-identifier seed handling, production-first audit filtering,
|
|
122
|
+
router boilerplate suppression, no-network sync previews, confirmation-token mismatch, URL redaction,
|
|
123
|
+
and actionable contract 404 state.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weavatrix",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Weavatrix —
|
|
5
|
+
"description": "Weavatrix — architecture graph, health, clone and history MCP server for AI coding agents: blast radius, dependency audit, graph diff and coverage over any local repository.",
|
|
6
6
|
"author": "Sergii Ziborov <sergii.ziborov@gmail.com>",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"homepage": "https://weavatrix.com",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"skill",
|
|
27
27
|
"scripts/run-agent-task-benchmark.mjs",
|
|
28
28
|
"docs/agent-task-benchmark.md",
|
|
29
|
-
"docs/releases/v0.2.
|
|
29
|
+
"docs/releases/v0.2.9.md",
|
|
30
30
|
"README.md",
|
|
31
31
|
"SECURITY.md",
|
|
32
32
|
"LICENSE"
|
package/skill/SKILL.md
CHANGED
|
@@ -16,7 +16,7 @@ Tools are named `mcp__weavatrix__…`. If none are available, ask the user to re
|
|
|
16
16
|
(`claude mcp add -s user weavatrix -- npx -y weavatrix <repoRoot>`; Codex:
|
|
17
17
|
`codex mcp add weavatrix -- npx -y weavatrix <repoRoot>`), then retry.
|
|
18
18
|
|
|
19
|
-
If `refresh_advisories`, `pull_architecture_contract`, or `sync_graph` is missing, do not diagnose a
|
|
19
|
+
If `refresh_advisories`, `preview_sync`, `pull_architecture_contract`, or `sync_graph` is missing, do not diagnose a
|
|
20
20
|
broken installation: network tools are intentionally absent from `offline` and `pinned`.
|
|
21
21
|
|
|
22
22
|
Profiles use the same npm package and binary:
|
|
@@ -24,7 +24,7 @@ Profiles use the same npm package and binary:
|
|
|
24
24
|
- `offline` (default): all local analysis and explicit `open_repo`; no HTTP tools.
|
|
25
25
|
- `pinned`: local analysis with no `open_repo`, no global/cross-repository graph access, and no HTTP tools.
|
|
26
26
|
- `osv`: `offline` plus explicit `refresh_advisories`.
|
|
27
|
-
- `hosted` / `full`: `osv` plus `pull_architecture_contract` and `sync_graph`.
|
|
27
|
+
- `hosted` / `full`: `osv` plus local-only `preview_sync`, `pull_architecture_contract` and `sync_graph`.
|
|
28
28
|
|
|
29
29
|
The legacy `online` capability remains a compatibility alias for `advisories,hosted`; prefer the
|
|
30
30
|
named profiles for new registrations.
|
|
@@ -117,8 +117,8 @@ Start from the task, not from the complete tool list:
|
|
|
117
117
|
ONLY network-touching tools live in the optional
|
|
118
118
|
`advisories` / `hosted` capabilities and run solely when explicitly called:
|
|
119
119
|
`refresh_advisories` (queries OSV.dev with
|
|
120
|
-
package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (
|
|
121
|
-
|
|
120
|
+
package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (pushes only
|
|
121
|
+
the exact allowlisted graph/evidence contract previously serialized by local-only `preview_sync` to a
|
|
122
122
|
user-configured endpoint; analyzers may read local source, but the wire contract has no body,
|
|
123
123
|
snippet, absolute-host-path or environment fields, and unknown fields are discarded; disabled until
|
|
124
124
|
`WEAVATRIX_SYNC_URL` is set). `pull_architecture_contract` sends only the active repository's opaque
|
|
@@ -175,7 +175,9 @@ Start from the task, not from the complete tool list:
|
|
|
175
175
|
`REVIEW_REQUIRED` and `autoDelete:false` are hard
|
|
176
176
|
safety semantics, not boilerplate. Use `.weavatrix-deps.json` entrypoints/nonRuntimeRoots only for
|
|
177
177
|
verified conventions.
|
|
178
|
-
- **API inventory**: `list_endpoints` (including Next.js App Router, Rust axum and
|
|
178
|
+
- **API inventory**: `list_endpoints` (including mount provenance, Next.js App Router, Rust axum and
|
|
179
|
+
actix-web). When one exact route is known, use `trace_endpoint` for its composed mount chain,
|
|
180
|
+
handler and bounded production call graph instead of broad natural-language traversal.
|
|
179
181
|
- **Cross-repository API impact**: ensure both repositories are in `list_known_repos`, then call
|
|
180
182
|
`trace_api_contract backend=<uuid-or-label> clients=[<uuid-or-label>]`; narrow with `method`, `path`,
|
|
181
183
|
or backend `changed_files`. `path` may be a segment-aligned fragment (`/query` can select
|
|
@@ -237,7 +239,10 @@ visible. `managedDependencies` documents modules provided outside the repo's Pyt
|
|
|
237
239
|
|
|
238
240
|
## Sync
|
|
239
241
|
|
|
240
|
-
`
|
|
242
|
+
Call `preview_sync` first. It validates the configured destination and serializes payload v3 locally,
|
|
243
|
+
returning the repository UUID, exact fields/sections, counts, bytes, hash and short-lived confirmation
|
|
244
|
+
token without networking. After explicit approval, call `sync_graph dry_run=false` with that token.
|
|
245
|
+
Payload v3 contains graph metadata plus deterministic architecture, health, stack,
|
|
241
246
|
package-dependency and clone-review evidence. Read each section's `state`, `verdict` and completeness counts; `PARTIAL`,
|
|
242
247
|
`NOT_CHECKED` and `ERROR` are unknown/incomplete, never a clean result. Architecture evidence
|
|
243
248
|
contains concrete runtime versus compile-time cycles, declared boundary violations and separated
|
|
@@ -257,7 +262,7 @@ the working tree, must be rebuilt first. Sync remains unavailable until the user
|
|
|
257
262
|
- `refresh_advisories` is unavailable → with the user's approval, re-register/reconfigure the MCP
|
|
258
263
|
with the `osv` profile, reconnect it, and then invoke the tool. Do not enable network
|
|
259
264
|
access merely to turn `NOT_CHECKED` into a cosmetic green state.
|
|
260
|
-
- `pull_architecture_contract` / `sync_graph` is unavailable → use the `hosted` profile only after
|
|
265
|
+
- `preview_sync` / `pull_architecture_contract` / `sync_graph` is unavailable → use the `hosted` profile only after
|
|
261
266
|
the user chooses hosted integration; configure `WEAVATRIX_SYNC_URL` and a bearer token for contract
|
|
262
267
|
pull. Profile selection alone never performs a request.
|
|
263
268
|
- `No coverage report` → run the repo's own tests with coverage (`vitest run --coverage`,
|
|
@@ -37,6 +37,13 @@ function groupPairs(data, settings) {
|
|
|
37
37
|
}).sort((a, b) => b.tokens - a.tokens)
|
|
38
38
|
}
|
|
39
39
|
|
|
40
|
+
export function isFrameworkBoilerplateCloneGroup(group) {
|
|
41
|
+
const members = Array.isArray(group?.members) ? group.members : []
|
|
42
|
+
if (members.length < 2) return false
|
|
43
|
+
return members.every((member) => /(?:^|\/)\w[^/]*\.router\.[cm]?[jt]s$/i.test(String(member.file || '').replace(/\\/g, '/'))
|
|
44
|
+
&& /^(?:router|routes)\(?\)?$/i.test(String(member.label || '').trim()))
|
|
45
|
+
}
|
|
46
|
+
|
|
40
47
|
export function analyzeDuplicateGroups(repoRoot, graphPath, args = {}) {
|
|
41
48
|
const settings = {
|
|
42
49
|
simMin: Math.min(100, Math.max(50, Number(args.min_similarity) || 80)),
|
|
@@ -44,11 +51,13 @@ export function analyzeDuplicateGroups(repoRoot, graphPath, args = {}) {
|
|
|
44
51
|
mode: args.mode === 'strict' ? 'strict' : 'renamed',
|
|
45
52
|
skipTests: args.include_tests !== true,
|
|
46
53
|
includeClassified: args.include_classified === true || args.include_non_product === true,
|
|
54
|
+
includeBoilerplate: args.include_boilerplate === true,
|
|
47
55
|
}
|
|
48
56
|
const data = computeDuplicates(repoRoot, graphPath, {includeStrings: args.include_strings === true, minTokens: settings.tokMin})
|
|
49
|
-
const
|
|
57
|
+
const allGroups = groupPairs(data, settings)
|
|
58
|
+
const groups = settings.includeBoilerplate ? allGroups : allGroups.filter((group) => !isFrameworkBoilerplateCloneGroup(group))
|
|
50
59
|
const suppressed = (data.frags || []).filter((fragment) => !eligible(fragment, settings)).length
|
|
51
|
-
return {settings, groups, suppressed}
|
|
60
|
+
return {settings, groups, suppressed, boilerplateSuppressed: allGroups.length - groups.length}
|
|
52
61
|
}
|
|
53
62
|
|
|
54
63
|
const digest = (value) => createHash('sha256').update(value).digest('hex').slice(0, 20)
|