v0.21.1
v0.21.1 — npm distribution revived (zero-logic), product-layer restructure, new perf/concurrency rules, reachability contract
This release brings the npm CLI back as a thin native-binary shim, restructures the workspace into a clean product/library split, adds declaration-level eager-loading rules plus concurrency-loop rules, and machine-pins parser↔rule reachability. No public runtime behavior of the analysis engine changed except the new rules and one Go extraction fix.
npm distribution is back — as zero-logic packaging (6 packages)
npm i -g @zzop/cliinstalls the same nativezzopCLI binary GitHub Releases ships — identical subcommands, identical output.@zzop/cliis a ~90-line launcher that spawns the platform binary carried by its@zzop/cli-<platform>sub-packages; there is no separate JS implementation to drift from the native binary (the pre-0.20 JS CLI dialect is gone for good).- The 0.20 npm removal was reversed; the napi
@zzop/nativeSDK was not revived (nothing in the distribution used it — programmatic Node use = run the CLI with its JSON output). - Publishing uses npm OIDC trusted publishing (no stored token) and is resumable.
Release pipeline: secretless auto-tagging + official MCP registry
- A workspace version bump landing on
mainnow auto-tags and releases itself — CI reads the Cargo version, creates the tag, and the same run ships the release. No manual tag step. - zzop's MCP server is now auto-published to the official MCP registry (registry.modelcontextprotocol.io,
io.github.eezz4/zzop) via GitHub OIDC — discovery for the non-Claude ecosystem. Usage still needs no registration (a stdio config suffices).
New rules (4)
perf/eager-relation-declared(TS/JS) andperf/jpa-eager-fetch(Java): declaration-level eager loading — TypeORMeager: true, Sequelizeinclude: [{ all: true }], JPAFetchType.EAGER— the query-time opposite of N+1 (over-fetch on every read). Verified against real corpora with zero false positives.be-db/tx-in-loop-long-hold: a transaction wrapping a per-row loop, so lock hold time scales with row count.be-reliability/fs-in-loop-serial: awaitedfs/fs.promisescalls serialized inside a loop.
Reachability contract + a Go extraction fix it caught
- A new parser×rule capability-matrix meta-test machine-pins which parser environment projects which channels (symbols, method/loop spans, IO facts) and fails any rule whose file pattern would make it forever-silent — the "which languages/DBs can a rule actually reach" facts are no longer prose.
- Building it surfaced a real bug: Go functions whose body opened with a
//comment lost their body span, silently suppressing method/loop-scan rules (includinggo-goroutine-in-loop) on them. Fixed, with a same-class audit across every parser.
Internal
- Workspace restructured into a product layer (
packages/{cli,cli-bin,mcp,mcpb}) over an internal library layer (crates/), withcrates/hostreduced to the shared library both binaries link. Binary names, release assets, and npm package names are unchanged.
Cache note: the Go parser fingerprint bumped, so Go trees re-analyze once on first run after upgrade; all other caches survive.