weavatrix 0.3.2 → 0.3.3
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 +15 -0
- package/SECURITY.md +18 -2
- package/docs/releases/v0.3.3.md +25 -0
- package/package.json +2 -1
- package/src/graph/internal-builder.langs.js +12 -4
- package/src/graph/parser-artifact-boundary.js +56 -0
package/README.md
CHANGED
|
@@ -413,6 +413,21 @@ metrics are not persisted or transmitted by Weavatrix. If a source checkout's pa
|
|
|
413
413
|
while an old daemon remains alive, `initialize`, `tools/list`, and tool calls fail loudly with
|
|
414
414
|
`STALE_RUNTIME` until the client reconnects; the opt-out is reserved for deliberate development.
|
|
415
415
|
|
|
416
|
+
### 0.3.3 parser supply-chain boundary
|
|
417
|
+
|
|
418
|
+
- Before compiling parser WASM, Core now requires the package-pinned `web-tree-sitter` runtime and
|
|
419
|
+
each selected `tree-sitter-wasms` grammar to resolve inside its dependency directory and match a
|
|
420
|
+
release-pinned SHA-256 allowlist. Repository paths, URLs, symlinks and custom parser locations are
|
|
421
|
+
rejected; a mismatch fails the graph build.
|
|
422
|
+
- This bounds the upstream Emscripten dynamic-module loader even though its generated code contains
|
|
423
|
+
`eval` glue for EM_ASM/EM_JS side modules. Weavatrix loads only its known local runtime and grammar
|
|
424
|
+
artifacts; it does not load a parser or grammar from the analyzed repository.
|
|
425
|
+
- Supply-chain documentation now distinguishes the Apache-2.0 license declared by
|
|
426
|
+
`typescript@5.9.3` from the W3C agreement reproduced for one specification in its third-party
|
|
427
|
+
notices. Conservative dependency scanners may still surface that component notice for review.
|
|
428
|
+
|
|
429
|
+
Full patch notes: [docs/releases/v0.3.3.md](docs/releases/v0.3.3.md).
|
|
430
|
+
|
|
416
431
|
### 0.3.2 exact impact over oversized diffs
|
|
417
432
|
|
|
418
433
|
- `change_impact` now recovers a bounded per-file unified diff when one large asset exceeds the
|
package/SECURITY.md
CHANGED
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
| Version | Supported |
|
|
6
6
|
|---|---|
|
|
7
|
-
| `0.
|
|
8
|
-
| `0.2.
|
|
7
|
+
| `0.3.x` | Yes |
|
|
8
|
+
| `0.2.x` and older | Upgrade to the latest release |
|
|
9
9
|
|
|
10
10
|
Security fixes are provided for the latest published version of Weavatrix. Upgrade before reporting
|
|
11
11
|
an issue that may already be resolved.
|
|
@@ -56,6 +56,22 @@ bounded graph-work drain, and closes or tree-terminates TLS/tsserver before exit
|
|
|
56
56
|
Set `WEAVATRIX_PRECISION=off` before server startup (or select `off` in the MCPB semantic-precision
|
|
57
57
|
setting) to keep new graphs parser-only from their first build.
|
|
58
58
|
|
|
59
|
+
The parser runtime and language grammars are also exact package-pinned dependencies. Before compiling
|
|
60
|
+
WASM, Weavatrix requires the runtime and every selected grammar to resolve inside their dependency
|
|
61
|
+
directories and match a release-pinned SHA-256 allowlist. Repository paths, URLs, symlinks and custom
|
|
62
|
+
`runtimeWasm`/`wasmDir` overrides cannot enter this path. This specifically bounds the generated
|
|
63
|
+
Emscripten dynamic-module loader in `web-tree-sitter`: although upstream contains `eval` glue for
|
|
64
|
+
EM_ASM/EM_JS side-module exports, Weavatrix supplies only its known local runtime and grammar artifacts.
|
|
65
|
+
An integrity mismatch fails the graph build instead of silently falling back to an unverified parser.
|
|
66
|
+
|
|
67
|
+
Dependency scanners should distinguish a package's declared license from component notices.
|
|
68
|
+
`typescript@5.9.3` declares `Apache-2.0`; its `ThirdPartyNoticeText.txt` also reproduces the W3C Community
|
|
69
|
+
Final Specification Agreement for the Web Background Synchronization specification. That attribution
|
|
70
|
+
does not change the npm package's declared license, but conservative scanners may report the embedded
|
|
71
|
+
notice separately. `web-tree-sitter@0.25.10` declares MIT; its generated loader is covered by the
|
|
72
|
+
artifact boundary above. These observations are security evidence, not a request to suppress third-party
|
|
73
|
+
scanner warnings or legal advice.
|
|
74
|
+
|
|
59
75
|
`verified_change` is read-only by default. Its optional targeted-test step can execute only an
|
|
60
76
|
existing `package.json` script whose name matches the bounded test/check/verify allowlist. The call
|
|
61
77
|
must set `run_tests:true` and the server operator must separately set
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Weavatrix 0.3.3
|
|
2
|
+
|
|
3
|
+
0.3.3 hardens the portable parser boundary after reviewing two conservative
|
|
4
|
+
third-party supply-chain alerts.
|
|
5
|
+
|
|
6
|
+
`web-tree-sitter@0.25.10` is MIT-licensed, but its generated Emscripten loader
|
|
7
|
+
contains `eval` support for EM_ASM/EM_JS exports in dynamic side modules. The
|
|
8
|
+
same generated path remains in `web-tree-sitter@0.26.11`; changing the version
|
|
9
|
+
would not remove the signal. Weavatrix now verifies the exact SHA-256 of the
|
|
10
|
+
package-owned runtime and every selected `tree-sitter-wasms@0.1.13` grammar
|
|
11
|
+
before compilation. Parser artifacts must resolve inside their pinned package
|
|
12
|
+
directories. Repository paths, URLs, symlink escapes and custom runtime or
|
|
13
|
+
grammar locations are rejected, and an integrity mismatch fails closed.
|
|
14
|
+
|
|
15
|
+
The release also documents a separate license-classification alert.
|
|
16
|
+
`typescript@5.9.3` declares `Apache-2.0`. Its third-party notice reproduces the
|
|
17
|
+
W3C Community Final Specification Agreement for the Web Background
|
|
18
|
+
Synchronization specification; conservative scanners can identify that
|
|
19
|
+
component notice as non-permissive even though it is not the package's declared
|
|
20
|
+
license. Weavatrix keeps the notice visible and does not suppress the external
|
|
21
|
+
scanner finding.
|
|
22
|
+
|
|
23
|
+
The public site now presents the product boundary directly: the 34-tool MIT,
|
|
24
|
+
network-free Core and the separately licensed 39-tool Online overlay, including
|
|
25
|
+
managed Cloud and customer-hosted Enterprise availability.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weavatrix",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"type": "module",
|
|
5
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>",
|
|
@@ -36,6 +36,7 @@
|
|
|
36
36
|
"docs/releases/v0.3.0.md",
|
|
37
37
|
"docs/releases/v0.3.1.md",
|
|
38
38
|
"docs/releases/v0.3.2.md",
|
|
39
|
+
"docs/releases/v0.3.3.md",
|
|
39
40
|
"docs/releases/v0.2.19.md",
|
|
40
41
|
"README.md",
|
|
41
42
|
"SECURITY.md",
|
|
@@ -10,6 +10,7 @@ import { createRequire } from "node:module";
|
|
|
10
10
|
import { isPathInside } from "../repo-path.js";
|
|
11
11
|
import { childProcessEnv } from "../child-env.js";
|
|
12
12
|
import { filterWeavatrixIgnored } from "../path-ignore.js";
|
|
13
|
+
import {trustedGrammarWasm, trustedRuntimeWasm} from './parser-artifact-boundary.js'
|
|
13
14
|
import LANG_JS from "./builder/lang-js.js";
|
|
14
15
|
import LANG_PY from "./builder/lang-python.js";
|
|
15
16
|
import LANG_GO from "./builder/lang-go.js";
|
|
@@ -24,7 +25,6 @@ const { Parser, Language, Query } = require("web-tree-sitter");
|
|
|
24
25
|
|
|
25
26
|
const WTS_DIR = dirname(require.resolve("web-tree-sitter"));
|
|
26
27
|
const NODE_MODULES = dirname(WTS_DIR);
|
|
27
|
-
const DEFAULT_RUNTIME_WASM = join(WTS_DIR, "tree-sitter.wasm");
|
|
28
28
|
const DEFAULT_WASM_DIR = join(NODE_MODULES, "tree-sitter-wasms", "out");
|
|
29
29
|
|
|
30
30
|
// ---- language registry (derived from the per-language modules) ----
|
|
@@ -61,11 +61,19 @@ const _langs = {};
|
|
|
61
61
|
// in the repo get compiled. The heavy WASMs (rust ~3MB, c_sharp ~4MB) cost seconds to compile — a tax
|
|
62
62
|
// a JS-only repo must never pay. Omit `wanted` to load everything (old behavior).
|
|
63
63
|
async function ensureParser(opts = {}, wanted = null) {
|
|
64
|
-
if (
|
|
64
|
+
if (opts.runtimeWasm != null || opts.wasmDir != null) {
|
|
65
|
+
throw new Error('custom parser artifacts are not supported; Weavatrix loads only pinned package-owned WASM')
|
|
66
|
+
}
|
|
67
|
+
if (!_ready) {
|
|
68
|
+
const runtimeWasm = trustedRuntimeWasm(WTS_DIR)
|
|
69
|
+
_ready = Parser.init({ locateFile: () => runtimeWasm });
|
|
70
|
+
}
|
|
65
71
|
await _ready;
|
|
66
|
-
const wasmDir = opts.wasmDir || DEFAULT_WASM_DIR;
|
|
67
72
|
const list = wanted ? GRAMMARS.filter((g) => wanted.has(g)) : GRAMMARS;
|
|
68
|
-
for (const g of list) if (!_langs[g]) {
|
|
73
|
+
for (const g of list) if (!_langs[g]) {
|
|
74
|
+
const grammarWasm = trustedGrammarWasm(DEFAULT_WASM_DIR, g)
|
|
75
|
+
try { _langs[g] = await Language.load(grammarWasm); } catch { _langs[g] = null; }
|
|
76
|
+
}
|
|
69
77
|
return _langs;
|
|
70
78
|
}
|
|
71
79
|
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {createHash} from 'node:crypto'
|
|
2
|
+
import {readFileSync, realpathSync, statSync} from 'node:fs'
|
|
3
|
+
import {join} from 'node:path'
|
|
4
|
+
import {isPathInside} from '../repo-path.js'
|
|
5
|
+
|
|
6
|
+
// Exact SHA-256 allowlist for the parser artifacts shipped by the package-pinned
|
|
7
|
+
// web-tree-sitter@0.25.10 and tree-sitter-wasms@0.1.13 dependencies. npm integrity
|
|
8
|
+
// protects installation; this second boundary detects replacement or redirection
|
|
9
|
+
// before Emscripten compiles a runtime or dynamic language module.
|
|
10
|
+
const RUNTIME_SHA256 = 'f38dcc4b43b818f9a0785bc1c6d5611a75ac4cdd428ff3f02757c34ca4e46d7f'
|
|
11
|
+
const GRAMMAR_SHA256 = Object.freeze({
|
|
12
|
+
javascript: '63812b9e275d26851264734868d27a1656bd44a2ef6eb3e85e6b03728c595ab5',
|
|
13
|
+
typescript: '8515404dceed38e1ed86aa34b09fcf3379fff1b4ff9dd3967bcd6d1eb5ac3d8f',
|
|
14
|
+
tsx: '6aa3b2c70e76f5d48eafef1093e9c4de383e13f2fdde2f4e9b98a378f6a8f1b6',
|
|
15
|
+
python: '9056d0fb0c337810d019fae350e8167786119da98f0f282aceae7ab89ee8253b',
|
|
16
|
+
go: '9963ca89b616eaf04b08a43bc1fb0f07b85395bec313330851f1f1ead2f755b6',
|
|
17
|
+
java: '637aac4415fb39a211a4f4292d63c66b5ce9c32fa2cd35464af4f681d91b9a1f',
|
|
18
|
+
c_sharp: '6266a7e32d68a3459104d994dc848df15d5672b0ea8e86d327274b694f8e6991',
|
|
19
|
+
rust: '4409921a70d0aa5bec7d1d7ce809a557a8ee1cf6ace901e3ac6a76e62cfea903',
|
|
20
|
+
html: '11b3405c1543fb012f5ed7f8ee73125076dce8b168301e1e787e4c717da6b456',
|
|
21
|
+
css: '5fc615467b1b98420ed7517e5bf9e1f88468132dd903d842dfb13714f6a1cb0c',
|
|
22
|
+
})
|
|
23
|
+
|
|
24
|
+
export function verifyParserArtifact({file, root, sha256, label = 'parser artifact'}) {
|
|
25
|
+
let rootReal, fileReal
|
|
26
|
+
try {
|
|
27
|
+
rootReal = realpathSync.native(root)
|
|
28
|
+
fileReal = realpathSync.native(file)
|
|
29
|
+
} catch {
|
|
30
|
+
throw new Error(`${label} is missing or cannot be resolved`)
|
|
31
|
+
}
|
|
32
|
+
if (!isPathInside(rootReal, fileReal) || !statSync(fileReal).isFile()) {
|
|
33
|
+
throw new Error(`${label} resolves outside its pinned package directory`)
|
|
34
|
+
}
|
|
35
|
+
const actual = createHash('sha256').update(readFileSync(fileReal)).digest('hex')
|
|
36
|
+
if (actual !== sha256) throw new Error(`${label} failed the pinned SHA-256 integrity check`)
|
|
37
|
+
return fileReal
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export function trustedRuntimeWasm(wtsDir) {
|
|
41
|
+
return verifyParserArtifact({
|
|
42
|
+
file: join(wtsDir, 'tree-sitter.wasm'), root: wtsDir,
|
|
43
|
+
sha256: RUNTIME_SHA256, label: 'web-tree-sitter runtime',
|
|
44
|
+
})
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function trustedGrammarWasm(wasmDir, grammar) {
|
|
48
|
+
const sha256 = GRAMMAR_SHA256[grammar]
|
|
49
|
+
if (!sha256) throw new Error(`unsupported tree-sitter grammar: ${grammar}`)
|
|
50
|
+
return verifyParserArtifact({
|
|
51
|
+
file: join(wasmDir, `tree-sitter-${grammar}.wasm`), root: wasmDir,
|
|
52
|
+
sha256, label: `tree-sitter ${grammar} grammar`,
|
|
53
|
+
})
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const TRUSTED_GRAMMARS = Object.freeze(Object.keys(GRAMMAR_SHA256))
|