weavatrix 0.2.8 → 0.2.10
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 +100 -32
- package/SECURITY.md +30 -7
- package/docs/releases/v0.2.10.md +53 -0
- package/package.json +3 -3
- package/skill/SKILL.md +89 -33
- package/src/analysis/duplicate-groups.js +11 -2
- package/src/analysis/endpoints.js +209 -9
- package/src/graph/builder/lang-java-calls.js +142 -0
- package/src/graph/builder/lang-java.js +13 -0
- package/src/graph/internal-builder.build.js +4 -2
- package/src/mcp/catalog.mjs +16 -13
- 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-architecture.mjs +48 -15
- 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
|
@@ -1,21 +1,33 @@
|
|
|
1
1
|
# Weavatrix
|
|
2
2
|
|
|
3
|
-
**
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
3
|
+
**Local repository intelligence for AI coding agents — understand the application quickly, then change it with evidence.**
|
|
4
|
+
|
|
5
|
+
Weavatrix builds a reusable living graph of any local repository: files, symbols, imports, calls,
|
|
6
|
+
inheritance, health findings, clone families and Git-history coupling. It gives Claude Code, Codex,
|
|
7
|
+
or any MCP client a bounded map for fast application understanding and lower repeated context, then
|
|
8
|
+
reuses the same graph for change impact, Health, dead-code review, duplicates, history and intended-
|
|
9
|
+
architecture safeguards. Text search is included as a supporting source check, not the product core.
|
|
10
|
+
**38 tools available; 34 enabled by the default offline profile. Local-first: with
|
|
9
11
|
the defaults, no repository data leaves your machine.**
|
|
10
12
|
|
|
11
13
|
- Website: [weavatrix.com](https://weavatrix.com)
|
|
12
14
|
- Source: [github.com/sergii-ziborov/weavatrix](https://github.com/sergii-ziborov/weavatrix)
|
|
13
15
|
- npm: [`weavatrix`](https://www.npmjs.com/package/weavatrix) — `npx -y weavatrix <repoRoot>`
|
|
14
16
|
|
|
17
|
+
## One graph, many views
|
|
18
|
+
|
|
19
|
+
The 38 MCP methods are not one linear workflow. They project the same reusable graph into the
|
|
20
|
+
smallest view needed for a task: repository and build state; modules, communities, hubs, neighbors
|
|
21
|
+
and paths; exact symbols and bounded source context; endpoint and cross-repository API flow; symbol
|
|
22
|
+
and change-set blast radius; graph revision and behavioral Git history; Health, dependencies,
|
|
23
|
+
vulnerabilities, dead code, clones, coverage and hot paths; proof-carrying change verification;
|
|
24
|
+
intended-architecture contracts and ratchets; local multi-repository work; and explicit,
|
|
25
|
+
preview-confirmed Hosted exchange.
|
|
26
|
+
|
|
15
27
|
## Why
|
|
16
28
|
|
|
17
|
-
An AI agent editing code without
|
|
18
|
-
answers
|
|
29
|
+
An AI agent editing code without architecture, health and history evidence is refactoring blind.
|
|
30
|
+
Weavatrix answers questions a text index cannot:
|
|
19
31
|
|
|
20
32
|
- *"What breaks if I change this?"* → `change_impact` diffs your branch (staged, unstaged and
|
|
21
33
|
untracked included), maps the changed files and symbols onto the graph, and lists everything that
|
|
@@ -28,6 +40,9 @@ answers grep can't produce:
|
|
|
28
40
|
- *"Did my refactor actually decouple anything?"* → `graph_diff base_ref=HEAD~1` builds an immutable
|
|
29
41
|
baseline graph without checking it out, then reports the structural delta: new module
|
|
30
42
|
dependencies, broken or introduced import cycles, and symbols that lost their last caller.
|
|
43
|
+
- *"Where is the repo rotting or repeating itself?"* → `run_audit`, `find_dead_code`,
|
|
44
|
+
`find_duplicates`, `hot_path_review` and `git_history` combine deterministic findings, graph
|
|
45
|
+
connectivity and co-change evidence instead of treating a matching string as an architecture fact.
|
|
31
46
|
|
|
32
47
|
- *"Is this change actually safe?"* -> `verified_change` accepts the task plus current diff/files and
|
|
33
48
|
returns one proof-carrying `PASS`, `BLOCKED`, or `UNKNOWN`: compact edit contexts, exact-symbol
|
|
@@ -67,7 +82,7 @@ argument when a stricter repository boundary or a network feature is wanted:
|
|
|
67
82
|
| `offline` (default) | Yes, only through `open_repo` | Yes, only through `trace_api_contract` | No | No |
|
|
68
83
|
| `pinned` | No | No | No | No |
|
|
69
84
|
| `osv` | Yes | Yes, only when called | Only when `refresh_advisories` is called | No |
|
|
70
|
-
| `hosted` / `full` | Yes | Yes, only when called | Only when called |
|
|
85
|
+
| `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
86
|
|
|
72
87
|
```sh
|
|
73
88
|
# Hard-pin one repository and expose no network tools:
|
|
@@ -125,7 +140,7 @@ confirmed by its bundled `typescript-language-server` + TypeScript runtime to `E
|
|
|
125
140
|
`CONFLICT` means evidence disagrees. `graph_stats` reports the provenance breakdown and the semantic
|
|
126
141
|
provider's `COMPLETE`, `PARTIAL`, `UNAVAILABLE`, or `OFF` state; `OFF` means precision was explicitly
|
|
127
142
|
disabled and only static evidence is active. Java and Rust language-server providers are not bundled
|
|
128
|
-
in 0.2.
|
|
143
|
+
in 0.2.9: their edges never become `EXACT_LSP`, even when a mixed repository reports a complete
|
|
129
144
|
TypeScript/JavaScript overlay.
|
|
130
145
|
|
|
131
146
|
The bounded JS/TS provider is enabled by default for new graphs. Set `WEAVATRIX_PRECISION=off`
|
|
@@ -133,21 +148,28 @@ before starting the MCP server for parser-only operation from the first build, o
|
|
|
133
148
|
`precision:"off"` to `rebuild_graph` / `open_repo`. The MCPB installer exposes the same `lsp` / `off`
|
|
134
149
|
choice as **TypeScript/JavaScript semantic precision**.
|
|
135
150
|
|
|
136
|
-
**search / source** — `search_code` (ripgrep-backed, pure-Node fallback
|
|
151
|
+
**search / source** — `search_code` (ripgrep-backed, pure-Node fallback, with repository-relative
|
|
152
|
+
path globs on Windows/macOS/Linux), `read_source` (a
|
|
137
153
|
symbol's actual code in one hop), `context_bundle` (definition plus grouped inbound/outbound
|
|
138
|
-
containers, exact re-export sites
|
|
154
|
+
containers, exact re-export sites, call-site/target provenance and bounded excerpts around decisive
|
|
155
|
+
edges), `inspect_symbol` (one exact
|
|
139
156
|
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
|
|
157
|
+
Express/Fastify/Nest/Flask/FastAPI/Go mux/Rust axum and actix-web, including nested Express
|
|
158
|
+
`router.use(...)` mount composition, declaration/reachability counts and mount provenance),
|
|
159
|
+
`trace_endpoint` (one exact composed route → handler → bounded production call graph with call-site excerpts)
|
|
141
160
|
|
|
142
161
|
**health** — `find_dead_code` (bounded review queue for statically unreferenced and test-only files,
|
|
143
162
|
functions, methods, and symbols, with evidence tiers, completed/remaining verification and explicit
|
|
144
163
|
public/framework/dynamic caveats),
|
|
145
|
-
`run_audit` (unused files/exports/dependencies with per-finding manifest/indexed-source/script/config verification
|
|
164
|
+
`run_audit` (unused files/exports/dependencies with per-finding manifest/indexed-source/script/config verification;
|
|
165
|
+
`category:dependencies` isolates missing/unused/duplicate declarations, unresolved imports and lockfile drift,
|
|
146
166
|
missing npm/Go/Python deps, runtime
|
|
147
167
|
cycles, type-only/compile-only coupling, orphans, boundary rules, offline OSV vulnerabilities + typosquat +
|
|
148
168
|
lockfile drift; accepts an immutable `base_ref`, `changed_files`, and `debt: new|existing|all` for
|
|
149
|
-
review-scoped results
|
|
150
|
-
|
|
169
|
+
review-scoped results; production paths are the default and `include_classified:true` opts into
|
|
170
|
+
test/generated/docs evidence), `find_duplicates` (MOSS winnowing over method bodies — catches copy-paste even
|
|
171
|
+
after renames and can inspect strict small clones down to 12 tokens; homogeneous router boilerplate
|
|
172
|
+
is suppressed unless `include_boilerplate:true`), `coverage_map` (existing coverage reports mapped onto the graph; untested hotspots
|
|
151
173
|
ranked by connectivity — tests are never executed), `hot_path_review` (bounded local-cost evidence
|
|
152
174
|
with separate graph/test risk), `verify_architecture`,
|
|
153
175
|
`explain_architecture_violation`, `propose_architecture_exception`
|
|
@@ -197,24 +219,59 @@ not CFG, value-propagation, or taint analysis.
|
|
|
197
219
|
|
|
198
220
|
`query_graph` accepts optional `seed_files` when an architectural question must start from exact
|
|
199
221
|
entry points. Resolved explicit seeds are exclusive by default; set `augment_seeds:true` only when
|
|
200
|
-
question-derived seeds are also wanted.
|
|
222
|
+
question-derived seeds are also wanted. A code-shaped identifier such as `startMitigate` is treated
|
|
223
|
+
as a stronger bounded seed than surrounding words such as controller/service/flow; all exact
|
|
224
|
+
same-name declarations are retained instead of adding unrelated concept seeds. Broad
|
|
225
|
+
bootstrap/tool-execution/routing questions rank
|
|
201
226
|
conventional executables and graph-declared production entry points ahead of site, documentation, benchmark
|
|
202
227
|
and fixture matches. Production-first classification also applies during traversal, so unrelated
|
|
203
228
|
tests/generated/docs/benchmarks do not leak back from a production seed; name a class in the
|
|
204
229
|
question or set `include_classified:true` to include it. Unreferenced unmatched constant/field leaves
|
|
205
230
|
are hidden unless `include_low_signal:true`. Broad ranking remains orientation evidence; use
|
|
206
|
-
`seed_files` when the intended entry point is already known.
|
|
231
|
+
`seed_files`, an exact endpoint, or `inspect_symbol` when the intended entry point is already known.
|
|
232
|
+
Instruction words such as “REST”, “path”, and “inspect” do not become fuzzy code seeds.
|
|
207
233
|
|
|
208
234
|
**advisories** *(network, explicit opt-in)* — `refresh_advisories`
|
|
209
235
|
|
|
210
|
-
**hosted** *(
|
|
236
|
+
**hosted** *(explicit opt-in; preview is local, send/pull are networked)* — `preview_sync`,
|
|
237
|
+
`pull_architecture_contract`, `sync_graph`. `preview_sync` performs no request and returns the destination,
|
|
238
|
+
repository UUID, exact payload fields/sections/size/hash and a short-lived confirmation token for
|
|
239
|
+
the cached payload. `sync_graph` sends only with both that token and `dry_run:false`; its legacy
|
|
240
|
+
dry-run form remains a no-network compatibility alias.
|
|
211
241
|
|
|
212
242
|
Quality of life: graph/health reads auto-reconcile and expose `none` / `incremental` / `full`
|
|
213
243
|
freshness, with a short clean-read debounce to avoid rescanning the repository for every tool call;
|
|
214
244
|
ambiguous name lookups are
|
|
215
245
|
disclosed instead of silently guessed; and the server **hot-reloads its watched MCP tool entry
|
|
216
246
|
modules and catalog** when those files change — other MCP helpers and analysis engines require a
|
|
217
|
-
reconnect.
|
|
247
|
+
reconnect. Every MCP response also carries local, transient `_meta["weavatrix/metrics"]` with elapsed
|
|
248
|
+
time, output bytes/token estimate, graph freshness/revision/update and graph-cache status. These
|
|
249
|
+
metrics are not persisted or transmitted by Weavatrix.
|
|
250
|
+
|
|
251
|
+
### 0.2.9 correctness, signal, and consent patch
|
|
252
|
+
|
|
253
|
+
- Express endpoint inventory composes nested imported `router.use(...)` mounts, so a local route such
|
|
254
|
+
as `/:attackId/startMitigate` is reported with its reachable `/warRoom/attack` prefix, declared vs
|
|
255
|
+
reachable counts and the exact static mount chain. `trace_endpoint` continues from that route into
|
|
256
|
+
the bounded call graph and call-site excerpts.
|
|
257
|
+
- `context_bundle` keeps the call-site file/line separate from the target definition and adds bounded
|
|
258
|
+
excerpts around decisive edges instead of stopping inside a long leading comment.
|
|
259
|
+
- `search_code` applies documented repository-relative path globs correctly when ripgrep runs on
|
|
260
|
+
Windows. Broad `query_graph` prompts no longer turn generic REST/instruction words into noisy
|
|
261
|
+
configuration-file seeds, and code-shaped identifiers outrank generic controller/service/flow
|
|
262
|
+
concepts.
|
|
263
|
+
- `run_audit` is production-first by default while retaining explicit access to classified evidence;
|
|
264
|
+
`category:dependencies` provides a focused dependency-health slice;
|
|
265
|
+
duplicate review suppresses homogeneous Express router boilerplate unless requested.
|
|
266
|
+
- the separate no-network `preview_sync` produces the exact payload approval artifact; `sync_graph`
|
|
267
|
+
requires that preview followed by an exact short-lived confirmation token,
|
|
268
|
+
validates the configured destination, requires HTTPS outside loopback, and never networks during
|
|
269
|
+
preview. Contract-pull HTTP failures expose actionable auth/not-found/not-ready states.
|
|
270
|
+
- Every MCP call exposes transient local execution/output/freshness metrics without collection or
|
|
271
|
+
egress. The public site, privacy/security pages, package metadata and license presentation now
|
|
272
|
+
describe the same 38-tool/34-offline surface and the same network boundary.
|
|
273
|
+
|
|
274
|
+
Full patch notes: [docs/releases/v0.2.9.md](docs/releases/v0.2.9.md).
|
|
218
275
|
|
|
219
276
|
### 0.2.8 trust and precision patch
|
|
220
277
|
|
|
@@ -397,9 +454,11 @@ Java graphs:
|
|
|
397
454
|
- Java class/interface/enum/record/annotation declarations retain their symbol kind; methods and
|
|
398
455
|
constructors are linked to their declaring type with visibility metadata. Internal
|
|
399
456
|
`extends`/`implements` relationships and resolvable type references link to real declarations.
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
457
|
+
Field, parameter, local and static receiver types resolve project-internal cross-file calls;
|
|
458
|
+
overloads are selected by arity and ambiguous/external targets fail closed. Imports are
|
|
459
|
+
compile-only; call/reference/heritage edges contribute impact. Maven/Gradle Java trees use
|
|
460
|
+
package-aware communities instead of one giant `src` bucket. External or synthetic placeholder
|
|
461
|
+
types are not created merely to inflate graph counts.
|
|
403
462
|
- Dependency checks resolve the nearest workspace manifest and `tsconfig`/`jsconfig` aliases,
|
|
404
463
|
account for framework-owned runtime peers such as Next.js + `react-dom`, and recognize Next.js
|
|
405
464
|
App Router route exports as endpoints.
|
|
@@ -492,20 +551,27 @@ Weavatrix itself initiates outbound HTTP only from three tools; all are absent f
|
|
|
492
551
|
- `pull_architecture_contract` — sends the active repository's opaque stable UUID with bearer
|
|
493
552
|
authentication, downloads the owner-approved target-architecture contract, validates it, and
|
|
494
553
|
stores the contract in the local graph cache. It sends no source, symbol, or repository path.
|
|
495
|
-
- `
|
|
554
|
+
- `preview_sync` — builds a bounded evidence snapshot locally without sending anything. The preview
|
|
555
|
+
shows the destination host/path, normalized repository name, opaque UUID,
|
|
556
|
+
payload version, exact top-level fields, included sections, node/link/byte counts and canonical
|
|
557
|
+
SHA-256 hash. A `sync_graph` call with `dry_run:false` and its exact short-lived `confirm_token` sends
|
|
558
|
+
the cached payload to the same destination. A token alone does not send while the default dry-run
|
|
559
|
+
remains active. It
|
|
560
|
+
sends payload v3: the v2 graph
|
|
496
561
|
allowlist plus module dependencies, runtime/compile-time cycles, declared boundary violations,
|
|
497
562
|
health findings, complexity-threshold breaches, stack identifiers, a bounded direct/transitive
|
|
498
563
|
dependency graph, direct package usage, and bounded clone/divergence review candidates. Local
|
|
499
564
|
analyzers may read repository source and manifests to derive those
|
|
500
565
|
facts. The wire contract has no fields for file bodies, snippets, absolute host paths, environment
|
|
501
566
|
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
|
|
567
|
+
The confirmed request also carries the normalized repository display name used by the
|
|
503
568
|
hosted list. The endpoint is **yours**, configured through `WEAVATRIX_SYNC_URL` and the optional
|
|
504
569
|
`WEAVATRIX_SYNC_TOKEN`; the feature is off by default. Pass `payload_version: 2` only for an
|
|
505
570
|
intentional graph-only compatibility sync—there is no silent downgrade that discards evidence.
|
|
506
571
|
Graphs that predate current typed-edge/provenance metadata must be rebuilt once before V3 sync;
|
|
507
572
|
V3 also refuses a stale graph so
|
|
508
|
-
source-derived evidence cannot be mixed with old topology.
|
|
573
|
+
source-derived evidence cannot be mixed with old topology. HTTPS is required except for an
|
|
574
|
+
explicitly configured loopback endpoint; embedded URL credentials and fragments are rejected.
|
|
509
575
|
|
|
510
576
|
Evidence sections carry independent `state` (`COMPLETE`, `PARTIAL`, `NOT_CHECKED`,
|
|
511
577
|
`NOT_APPLICABLE`, `ERROR`) and `verdict` (`PASS`, `FAIL`, `UNKNOWN`) fields plus exact
|
|
@@ -531,7 +597,7 @@ vulnerability findings. This is where each capability comes from and how it is c
|
|
|
531
597
|
|
|
532
598
|
| Capability alert | Why it exists | Activation and boundary |
|
|
533
599
|
|---|---|---|
|
|
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
|
|
600
|
+
| 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
601
|
| 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
602
|
| 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
603
|
| 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 +650,10 @@ loader) behind the thin stdio entry `src/mcp-server.mjs`.
|
|
|
584
650
|
- **Wrapper-aware API contracts** shipped in 0.2.2: persistent/ad-hoc configuration,
|
|
585
651
|
conservative discovery, cross-repository handler liveness and explicit unknown states. The next
|
|
586
652
|
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
|
-
|
|
653
|
+
- **Hosted architecture workbench** at
|
|
654
|
+
[app.weavatrix.com](https://app.weavatrix.com) is an access-controlled preview for
|
|
655
|
+
owner-authenticated source-free evidence and revision history. Its UI and backend evolve
|
|
656
|
+
independently from the public MCP release; local use remains fully optional.
|
|
591
657
|
- **Semantic precision bridge** shipped for TypeScript/JavaScript in 0.2.4: a bounded, revision-bound
|
|
592
658
|
local overlay validates references with the bundled language server while the parser graph remains
|
|
593
659
|
the fallback. Java and Rust providers are not bundled yet and stay explicitly `UNAVAILABLE`.
|
|
@@ -603,4 +669,6 @@ The public alignment note for the fixed cross-product release sequence is in
|
|
|
603
669
|
|
|
604
670
|
## License
|
|
605
671
|
|
|
606
|
-
[MIT](LICENSE) © 2026 Sergii Ziborov
|
|
672
|
+
The Weavatrix source in this repository is [MIT licensed](LICENSE) © 2026 Sergii Ziborov.
|
|
673
|
+
Third-party dependencies retain their own licenses. See the public
|
|
674
|
+
[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,53 @@
|
|
|
1
|
+
# Weavatrix 0.2.10
|
|
2
|
+
|
|
3
|
+
## Broad graph workflows without losing graph depth
|
|
4
|
+
|
|
5
|
+
0.2.10 is a graph-quality, positioning and agent-routing patch. It does not narrow Weavatrix to text search, a
|
|
6
|
+
single blast-radius tool, or three fixed workflows. The package, MCP registry metadata, portable
|
|
7
|
+
MCPB, skill, README and public site now describe one reusable graph exposed through 38 methods and
|
|
8
|
+
many task-specific projections: module/community/hub navigation, exact symbols and paths, local and
|
|
9
|
+
cross-repository API flow, symbol/diff impact, structural and behavioral history, Health,
|
|
10
|
+
dependencies, vulnerability evidence, dead code, clones, coverage, hot paths, proof-carrying change
|
|
11
|
+
verification, intended-architecture ratchets, local multi-repository work and explicit Hosted
|
|
12
|
+
governance.
|
|
13
|
+
|
|
14
|
+
The skill's intent router now maps each independent scenario to the smallest sufficient graph view or
|
|
15
|
+
analysis before lower-level source search. `module_map` is explicitly the first unfamiliar-repository
|
|
16
|
+
orientation view, `run_audit` is the core production-first Health review, and `verified_change` is
|
|
17
|
+
explicitly the pre-commit proof-carrying safeguard. Text search remains a useful source check, not the
|
|
18
|
+
product center.
|
|
19
|
+
|
|
20
|
+
## Java call graph and Repo Lens baseline
|
|
21
|
+
|
|
22
|
+
- Java field, parameter, local and static receiver types now resolve project-internal cross-file
|
|
23
|
+
method calls. Overloads are selected by argument arity; ambiguous methods and external or
|
|
24
|
+
same-basename impostor types fail closed. Call-site lines remain available to bounded context and
|
|
25
|
+
endpoint traces, while hub ranking continues to count unique neighbors rather than occurrences.
|
|
26
|
+
- A release regression test now asserts that the default offline catalog retains all 21 portable
|
|
27
|
+
repository-analysis methods inherited from Repo Lens. Its Electron-only `app_action` and
|
|
28
|
+
`app_job_status` process-control bridge is not misrepresented as an analyzer method: rebuild,
|
|
29
|
+
audit, advisory refresh, duplicate review and coverage generation/mapping retain direct bounded
|
|
30
|
+
MCP paths, while the persistent Electron job journal remains app-specific orchestration.
|
|
31
|
+
- The skill routes every one of the 38 current methods into a concrete scenario, so graph, history,
|
|
32
|
+
Health, duplicates, dead code and architecture governance remain first-class product surfaces.
|
|
33
|
+
- The unconfigured-architecture starter now proposes product-code territories only: tests, docs,
|
|
34
|
+
benchmarks, generated files and repository configs are filtered out, while direct source-root
|
|
35
|
+
files are grouped without overlapping deeper modules. It remains a source-free owner-review
|
|
36
|
+
proposal and is never saved or enforced automatically.
|
|
37
|
+
|
|
38
|
+
## Compatibility and data boundary
|
|
39
|
+
|
|
40
|
+
Tool names, MCP schemas, result envelopes and Hosted sync payloads are unchanged. Java graph nodes
|
|
41
|
+
and edges gain additive local `parameter_count` and `javaResolution` evidence; existing readers can
|
|
42
|
+
ignore those fields, and the Hosted payload allowlist remains unchanged. The default profile still
|
|
43
|
+
exposes 34 local tools and no HTTP tools. Hosted remains separately opt-in, preview-confirmed and
|
|
44
|
+
wire-compatible with payload v3.
|
|
45
|
+
|
|
46
|
+
## Verification
|
|
47
|
+
|
|
48
|
+
- Full Node suite: 506 tests, 503 passed, 3 platform skips, 0 failed.
|
|
49
|
+
- Six-language, cross-repository, framework and MCP lifecycle benchmark: `PASS`.
|
|
50
|
+
- Six available real-repository baselines, including the Java call-graph case: 6/6 `PASS`.
|
|
51
|
+
- Release metadata consistency and JSON syntax: `PASS`.
|
|
52
|
+
- Repo Lens portable analyzer parity: 21/21 methods present in the default offline profile.
|
|
53
|
+
- Hosted API and sync-payload schemas are unchanged.
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weavatrix",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.10",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "
|
|
5
|
+
"description": "Local repository intelligence MCP for AI coding agents: reusable architecture graph for fast application understanding, Health, dead code, clones, history, blast radius and architecture safeguards.",
|
|
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.10.md",
|
|
30
30
|
"README.md",
|
|
31
31
|
"SECURITY.md",
|
|
32
32
|
"LICENSE"
|
package/skill/SKILL.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: weavatrix
|
|
3
|
-
description:
|
|
3
|
+
description: "Use the Weavatrix MCP as a reusable local repository-intelligence layer: understand unfamiliar applications with a bounded code graph, reduce repeated context, review Health, dead code, duplicates and history, trace endpoints and blast radius, enforce target architecture, and verify changes before a PR."
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# weavatrix MCP
|
|
@@ -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,38 +24,89 @@ 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.
|
|
31
31
|
|
|
32
32
|
## Intent router
|
|
33
33
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
- **
|
|
46
|
-
|
|
47
|
-
- **Inspect
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
34
|
+
Weavatrix is not one report or three fixed workflows. Its 38 methods expose different bounded views
|
|
35
|
+
and analyses over the same reusable graph. Start from the task and choose the smallest sufficient
|
|
36
|
+
projection; expand only when the answer requires it.
|
|
37
|
+
|
|
38
|
+
### Graph views and application understanding
|
|
39
|
+
|
|
40
|
+
- **Confirm repository, graph freshness and build mode**: `graph_stats`; use `rebuild_graph` only for
|
|
41
|
+
a reported fallback/error or an intentional mode/precision change.
|
|
42
|
+
- **Switch or inventory local repositories**: `list_known_repos` -> `open_repo` -> `graph_stats`.
|
|
43
|
+
- **See production module topology**: `module_map`; use this first for a large unfamiliar application.
|
|
44
|
+
- **See discovered communities and their members**: `list_communities` -> `get_community`.
|
|
45
|
+
- **Find high-coupling hubs**: `god_nodes`; repeated call sites do not inflate unique connectivity.
|
|
46
|
+
- **Inspect one graph entity**: `get_node`; pass an exact node ID when labels are ambiguous.
|
|
47
|
+
- **Inspect direct one-hop relations**: `get_neighbors`; do not confuse it with transitive impact.
|
|
48
|
+
- **Prove a path between two concepts**: `shortest_path`.
|
|
49
|
+
- **Explore an unknown entry point or architectural question**: `query_graph`; pin `seed_files` when
|
|
50
|
+
known, and keep its broad result as orientation evidence.
|
|
51
|
+
- **Inspect one exact symbol deeply**: `context_bundle` for the bounded edit workset;
|
|
52
|
+
`inspect_symbol` for the raw point query and on-demand JS/TS reference evidence.
|
|
53
|
+
- **Confirm graph evidence in source**: `read_source`; use `search_code` only for a narrow regex/glob
|
|
54
|
+
check. Search is supporting evidence, not the repository-intelligence layer.
|
|
55
|
+
|
|
56
|
+
### Runtime, API and change scenarios
|
|
57
|
+
|
|
58
|
+
- **Inventory HTTP routes**: `list_endpoints` for declared/reachable composed paths and mount proof.
|
|
59
|
+
- **Trace one endpoint through the application**: `trace_endpoint` for route -> handler -> bounded
|
|
60
|
+
downstream call flow with edge-centered excerpts.
|
|
61
|
+
- **Trace an API contract across repositories**: `list_known_repos` -> `trace_api_contract` with an
|
|
62
|
+
explicit backend/client set; inspect each graph reconciliation state before using the verdict.
|
|
63
|
+
- **Measure one symbol's transitive blast radius**: `get_dependents`.
|
|
64
|
+
- **Review the current branch, diff, or external patch**: `change_impact`.
|
|
65
|
+
- **Compare structural graph revisions**: `graph_diff base_ref=<merge-base>` for module edges, cycles,
|
|
66
|
+
orphans and lost callers; without `base_ref`, compare the last rebuild snapshots.
|
|
67
|
+
- **Use behavioral history**: `git_history` for churn x connectivity, hidden co-change and expected
|
|
68
|
+
test/source coupling from bounded local Git numstat evidence.
|
|
69
|
+
- **Plan and verify a serious change or pre-commit gate**: `verified_change phase=plan` -> edit ->
|
|
70
|
+
`verified_change phase=verify base_ref=<same-ref>`. It composes exact context, impact, graph,
|
|
71
|
+
architecture, duplicate, optional API and test proof into one PASS/BLOCKED/UNKNOWN envelope.
|
|
72
|
+
|
|
73
|
+
### Health, debt and testing scenarios
|
|
74
|
+
|
|
75
|
+
- **Run a whole-repository Health review**: `run_audit debt=all`.
|
|
76
|
+
- **Gate only newly introduced branch debt**: `run_audit base_ref=<merge-base> debt=new`; old debt in
|
|
77
|
+
a changed file remains existing.
|
|
78
|
+
- **Review dependency declarations/imports**: `run_audit category=dependencies`; it includes missing,
|
|
79
|
+
unused, duplicate, unresolved-import and lockfile-drift evidence without relabelling identities.
|
|
80
|
+
- **Refresh vulnerability evidence when explicitly authorized**: `refresh_advisories`, then
|
|
81
|
+
`run_audit category=vulnerability`. `NOT_CHECKED` is unknown, never clean.
|
|
82
|
+
- **Review dead files, functions, methods and symbols**: `find_dead_code`; every result remains a
|
|
83
|
+
review candidate with framework/dynamic/public-API caveats, never an auto-delete verdict.
|
|
84
|
+
- **Review clone families or same-name divergence**: `find_duplicates`; framework router boilerplate
|
|
85
|
+
is suppressed unless explicitly requested.
|
|
86
|
+
- **Map measured coverage or honest static test reachability**: `coverage_map`; unavailable measured
|
|
87
|
+
coverage is not 0%.
|
|
88
|
+
- **Prioritize local performance-review candidates**: `hot_path_review`; confirm with a profiler or
|
|
89
|
+
benchmark before changing runtime behavior.
|
|
90
|
+
|
|
91
|
+
### Intended architecture and Hosted governance
|
|
92
|
+
|
|
93
|
+
- **Read or establish intended architecture**: `get_architecture_contract`. A returned starter is a
|
|
94
|
+
product-code-only territory proposal (not tests, docs, benchmarks, generated output or repository
|
|
95
|
+
configs), not automatically approved policy.
|
|
96
|
+
- **Select rules before editing**: `prepare_change`; **enforce the ratchet after editing**:
|
|
97
|
+
`verify_architecture`.
|
|
98
|
+
- **Understand or request an exception**: `explain_architecture_violation` ->
|
|
99
|
+
`propose_architecture_exception`; proposals never mutate policy automatically.
|
|
100
|
+
- **Pull an owner-approved Hosted target**: `pull_architecture_contract` only in an explicitly enabled
|
|
101
|
+
Hosted profile.
|
|
102
|
+
- **Review exactly what Hosted sync would send**: `preview_sync`; only an approved
|
|
103
|
+
`sync_graph dry_run=false confirm_token=...` may send that exact bounded payload.
|
|
104
|
+
|
|
105
|
+
Across every scenario, treat `PARTIAL`, `UNAVAILABLE`, `OFF`, `NOT_CHECKED`, `ERROR`, or capped
|
|
106
|
+
evidence as incomplete rather than success. Java and Rust exact language-server providers are not
|
|
107
|
+
bundled, so their edges never become `EXACT_LSP` even when a mixed repository has a complete
|
|
108
|
+
TypeScript/JavaScript overlay. Java receiver-type call edges are parser-resolved and explicitly
|
|
109
|
+
`INFERRED`; they improve cross-file flow without claiming compiler-exact overload or dynamic dispatch.
|
|
59
110
|
|
|
60
111
|
## Ground rules
|
|
61
112
|
|
|
@@ -117,8 +168,8 @@ Start from the task, not from the complete tool list:
|
|
|
117
168
|
ONLY network-touching tools live in the optional
|
|
118
169
|
`advisories` / `hosted` capabilities and run solely when explicitly called:
|
|
119
170
|
`refresh_advisories` (queries OSV.dev with
|
|
120
|
-
package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (
|
|
121
|
-
|
|
171
|
+
package names + versions so `run_audit` has fresh vulnerability data) and `sync_graph` (pushes only
|
|
172
|
+
the exact allowlisted graph/evidence contract previously serialized by local-only `preview_sync` to a
|
|
122
173
|
user-configured endpoint; analyzers may read local source, but the wire contract has no body,
|
|
123
174
|
snippet, absolute-host-path or environment fields, and unknown fields are discarded; disabled until
|
|
124
175
|
`WEAVATRIX_SYNC_URL` is set). `pull_architecture_contract` sends only the active repository's opaque
|
|
@@ -175,7 +226,9 @@ Start from the task, not from the complete tool list:
|
|
|
175
226
|
`REVIEW_REQUIRED` and `autoDelete:false` are hard
|
|
176
227
|
safety semantics, not boilerplate. Use `.weavatrix-deps.json` entrypoints/nonRuntimeRoots only for
|
|
177
228
|
verified conventions.
|
|
178
|
-
- **API inventory**: `list_endpoints` (including Next.js App Router, Rust axum and
|
|
229
|
+
- **API inventory**: `list_endpoints` (including mount provenance, Next.js App Router, Rust axum and
|
|
230
|
+
actix-web). When one exact route is known, use `trace_endpoint` for its composed mount chain,
|
|
231
|
+
handler and bounded production call graph instead of broad natural-language traversal.
|
|
179
232
|
- **Cross-repository API impact**: ensure both repositories are in `list_known_repos`, then call
|
|
180
233
|
`trace_api_contract backend=<uuid-or-label> clients=[<uuid-or-label>]`; narrow with `method`, `path`,
|
|
181
234
|
or backend `changed_files`. `path` may be a segment-aligned fragment (`/query` can select
|
|
@@ -237,7 +290,10 @@ visible. `managedDependencies` documents modules provided outside the repo's Pyt
|
|
|
237
290
|
|
|
238
291
|
## Sync
|
|
239
292
|
|
|
240
|
-
`
|
|
293
|
+
Call `preview_sync` first. It validates the configured destination and serializes payload v3 locally,
|
|
294
|
+
returning the repository UUID, exact fields/sections, counts, bytes, hash and short-lived confirmation
|
|
295
|
+
token without networking. After explicit approval, call `sync_graph dry_run=false` with that token.
|
|
296
|
+
Payload v3 contains graph metadata plus deterministic architecture, health, stack,
|
|
241
297
|
package-dependency and clone-review evidence. Read each section's `state`, `verdict` and completeness counts; `PARTIAL`,
|
|
242
298
|
`NOT_CHECKED` and `ERROR` are unknown/incomplete, never a clean result. Architecture evidence
|
|
243
299
|
contains concrete runtime versus compile-time cycles, declared boundary violations and separated
|
|
@@ -257,7 +313,7 @@ the working tree, must be rebuilt first. Sync remains unavailable until the user
|
|
|
257
313
|
- `refresh_advisories` is unavailable → with the user's approval, re-register/reconfigure the MCP
|
|
258
314
|
with the `osv` profile, reconnect it, and then invoke the tool. Do not enable network
|
|
259
315
|
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
|
|
316
|
+
- `preview_sync` / `pull_architecture_contract` / `sync_graph` is unavailable → use the `hosted` profile only after
|
|
261
317
|
the user chooses hosted integration; configure `WEAVATRIX_SYNC_URL` and a bearer token for contract
|
|
262
318
|
pull. Profile selection alone never performs a request.
|
|
263
319
|
- `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)
|