Repository navigation
v0.1.14
Ship the wasm the package says it ships
The published tarballs declare wasm/ in files and contain no wasm/ at
all -- not even the committed .d.ts stub. Every browser consumer got
the engine-missing error on the first call that touched the engine,
because src/native.ts imports the glue inside a try/catch: the import
fails quietly and only the call reports.
Cause is self-inflicted by the tool. wasm-pack treats its out-dir as a
package of its own and scaffolds one, including a .gitignore whose
whole content is ''. npm honours a .gitignore nested inside a
published directory even when files lists that directory, so the single
'' stripped everything. Measured with npm pack --dry-run: zero wasm/
entries with the file, three without it.
The gate could not see it because it asked the wrong question. It
checked the working directory -- where the artifacts genuinely are --
when the question is what ends up in the package. It now asks the
packer (npm pack --dry-run --json --ignore-scripts) and fails if a
required artifact is on disk but absent from the tarball, with the
nested-ignore cause named in the message.
build:wasm now removes wasm-pack's scaffolding before anything packs.
Read the artifact where cargo actually wrote it
The NAPI copy script looked under <package>/target unconditionally. Cargo
writes elsewhere whenever CARGO_TARGET_DIR is set — a shared cache, a CI mount,
a read-only external directory — so the build produced the library and then
failed to find it, or silently copied a stale one from a previous run.
CARGO_TARGET_DIR is honoured now, resolved against the package root when it
is relative, as cargo resolves it. All fourteen scripts had the same line; an
audit reported it in ream-mcp alone.
Verified end to end, not by reading: a real cargo build redirected to a
temporary directory, the artifact copied out of it, and the package suite green
on that binary.
Keep the dev-dependency alignment, drop the workspace: protocol
The internal ranges had been rewritten to workspace:^. That resolves inside
this monorepo and nowhere else: every package CI checks out its own repository
alone and runs pnpm install, where the protocol has no workspace to point at
and fails with ERR_PNPM_WORKSPACE_PKG_NOT_FOUND before a single test runs. The
concrete ranges are back; the dev-dependency bumps that came with the same edit
are kept, and now match what the lockfile already resolved.
Name the CI workflow after the package
Every workflow already declared name: <pkg>-ci inside — twenty-eight of
twenty-nine — while the file was ci.yml almost everywhere and
<pkg>-napi-ci.yml in three places, where the -napi said nothing: half the
packages with a Rust engine did not carry it.
The file now matches the name it has always had, so one rule covers every
repository and the publish command no longer depends on remembering which
three were spelled differently.
GitHub keys run history by file path, so the runs recorded under the old name
stay reachable under it and this workflow starts a fresh history.
Run cargo with --locked in CI
Without it, cargo rewrites Cargo.lock in place when it has drifted from the
manifests — so CI resolves dependencies fresh and tests a graph nobody
committed, then the release is built from it. The workspace lock had drifted
by 382 lines before the same flag caught it locally.
Every package here commits a Cargo.lock, so --locked is meaningful: it fails
loudly instead of silently updating. Verified against the current lock before
the flag went in.
The Node side is deliberately left alone: these repositories ship no
pnpm-lock.yaml, so --frozen-lockfile has nothing to freeze against, and
resolving from the registry is what a consumer gets anyway.
Measure coverage once, not once per platform
Lint this package the way its own repository will
biome's configuration lived only at the workspace root. This package is
built from its own repository, where that file does not exist and biome
falls back to its defaults — so lint in CI has been checking a different
set of rules from lint here, and the bans this project actually cares
about were never enforced where it counts.
The config is now the package's own, and says the same thing the root one
did.
Declare what CI has to install
Each package is its own repository: pnpm install there sees only this
file, so a dependency the workspace happened to hoist locally is simply
absent in CI. --coverage needs @vitest/coverage-v8 named here, and an
optional peer a test imports has to be a devDependency as well — optional
is exactly what keeps it from being installed.
Run the gates the package already declared
Three guard-rails were configured and never reached CI, so each one was a
gate nothing ran:
tsconfig.jsonincludestests, but CI typechecked only
tsconfig.build.json— every type a test relied on went unchecked.vitest.config.tsdeclares coverage thresholds, but CI ran plain
vitest run, which does not read them.lintpointed atsrc/alone, so no test file was ever linted.
CI now runs pnpm typecheck, pnpm test:coverage and a lint that covers
tests/ as well.
Changes since v0.1.13.