Repository navigation
packages: wolfi import batch 4 — node (eslint, lerna, json-server, serve) - #370
Conversation
Fourth batch from `pkgmgr import-wolfi` — node CLI tools. Node installs from
the npm registry by name+version (cf. typescript-language-server), so these
have no Source: build.sh runs `npm install -g --prefix=$OUTPUT_DIR/usr
<name>@$MINIMAL_ARG_VERSION`, with base+node build_deps, coreutils+node runtime,
a needs{dns,internet} block, and outputs = console-script bins + node_modules.
Each builds clean and passes every `minimal check` at 0 TODOs.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 12 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (8)
📝 WalkthroughWalkthroughThis PR adds build specifications and install scripts for four new npm-based packages: eslint (10.6.0), json-server (0.17.4), lerna (9.0.7), and serve (14.2.6). Each package includes a build.ncl spec and a build.sh script performing global npm installs. ChangesNew npm package build specs
Estimated code review effort: 2 (Simple) | ~10 minutes Suggested reviewers: 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
| }, | ||
| outputs = { | ||
| json-server = { glob = "usr/bin/json-server" } | OutputBin, | ||
| node_modules = { glob = "usr/lib/node_modules/**", allow_executable = true } | OutputData, |
There was a problem hiding this comment.
I dont think a global node_modules is gonna go so well, particularly if someone uses node vs node-lts
| }, | ||
| outputs = { | ||
| lerna = { glob = "usr/bin/lerna" } | OutputBin, | ||
| node_modules = { glob = "usr/lib/node_modules/**", allow_executable = true } | OutputData, |
twitchyliquid64 flagged the global usr/lib/node_modules output — it overlaps the node/node-lts runtime's ownership of that path and welds the tool to one node variant. Install each tool into a package-private prefix (usr/libexec/<pkg>) and expose the bins as relative symlinks on PATH (../libexec/<pkg>/bin/<tool>). The inner `#!/usr/bin/env node` shebang is served by coreutils(env)+node, so no shell is needed and runtime_deps=[coreutils, node] stays correct — matching what pnpm and bash-language-server already ship. (Deliberately NOT a `#!/bin/sh` wrapper, which would need bash in the runtime closure and fail at runtime with "bad interpreter" while still passing minimal check.) Build-proven all 4: usr/bin/<tool> resolves through libexec to the node script; zero leak into usr/lib/node_modules. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Good catch — fixed in The bins are exposed as relative symlinks on PATH ( Build-proven all four: Follow-ups (separate PRs): fixing the |
Follows Tom's review on #370 — "I dont think a global `node_modules` is gonna go so well, particularly if someone uses `node` vs `node-lts`". The collision half of that was already handled: vlt installs into a private `usr/libexec/vlt` prefix with relative PATH symlinks, never the shared `usr/lib/node_modules` the node runtime owns. But the variant question the comment raises was still answered by the importer's hardcoded default rather than by evidence. The evidence says LTS: - vlt's own CI tests Node 22.x ONLY (`node-version: '^22.22.0'` and `[22.x]`); `engines` says `>=22.22.0`. Our node-lts is 24.14.1 and node is 25.8.2 — neither is 22.x, but LTS is two majors closer to what upstream actually tests against. - pnpm is the closest analogue in this repo (a package manager, a node CLI, same shape of package) and it is on node-lts, per #97/#98: the node most users and hosting providers run is whatever ships with current LTS. node-lts ships its own npm, so it serves the build (`npm ci`) and the runtime (`#!/usr/bin/env node`) both — no split between build_deps and runtime_deps. Rebuilt and re-checked on the min path: 15/15 Pass.
…ominimal#564) * vlt: package the vlt package manager from npm (BSD-2-Clause-Patent) vlt 1.0.1 shipped today (vltpkg/vltpkg). Seeded with `pkgmgr import npm vlt` and refined by hand for the two things discovery mode can't know. Why this one is unusually clean to package: the published tarball has **zero dependencies**. `npm ci` against the committed lockfile installs exactly one package, pinned by version + integrity — no transitive tree, no native addons, no compile step. `npm audit` in-build reports 0 vulnerabilities across the whole 2-package graph. Two changes on top of the generated files: - **Bins enumerated, not globbed.** The importer emits `bins = { glob = "usr/bin/*" }`, which trips the `enumerate bins` checker for any package with a handful of bins — vlt has five (`vlt`, plus the documented shorthands `vlr`/`vlx` and their variants). The npm registry metadata lists them exactly, so nothing had to be inferred. Fixing this in the importer is pkgmgr-rs follow-up work, not a one-off. - **Real standalone tests.** The generated package had none, and `standalone tests...Pass` is what the checker reports for a package with zero tests — so "Pass" out of the box meant nothing. Added three that exercise the artifact rather than the build inputs: * `version_is_exact` — string equality against `%{version}`, not `--version | grep`. vlt's usage banner also carries the version, so a grep would pass on a build where `--version` is broken and only usage prints. * `companion_bins_work` — all four shorthands. They are PATH symlinks into the private libexec prefix; a broken relative link fails here and nowhere else. * `reads_a_manifest` — `vlt pkg get name` against a fixture package.json. Real offline work through the bundled JS; a truncated install still prints `--version` and fails this. Mutation-tested: flipping the expected version to `0.0.0-mutant` turns the suite red with `version_is_exact ... had exit code 1`, so these can fail for the reason they exist. **No `source_provenance`, deliberately.** vlt's vuln identity is its npm package name. minimal-supply-chain routes a node-flavored package with no provenance to `pkg:npm/<name>` (`scan.rs::npm_purl_for_node_package`) where the OSV/GHSA npm advisories resolve. Declaring `GithubRepo vltpkg/vltpkg` would move it onto the repo-purl arm, where GHSA's npm advisories — keyed by package name, not repo — would stop matching. Absent is correct here. Built and checked with the min-native path (`min package build` side-op + `min check`), 15/15 Pass. * vlt: build and run against node-lts, not node Follows Tom's review on gominimal#370 — "I dont think a global `node_modules` is gonna go so well, particularly if someone uses `node` vs `node-lts`". The collision half of that was already handled: vlt installs into a private `usr/libexec/vlt` prefix with relative PATH symlinks, never the shared `usr/lib/node_modules` the node runtime owns. But the variant question the comment raises was still answered by the importer's hardcoded default rather than by evidence. The evidence says LTS: - vlt's own CI tests Node 22.x ONLY (`node-version: '^22.22.0'` and `[22.x]`); `engines` says `>=22.22.0`. Our node-lts is 24.14.1 and node is 25.8.2 — neither is 22.x, but LTS is two majors closer to what upstream actually tests against. - pnpm is the closest analogue in this repo (a package manager, a node CLI, same shape of package) and it is on node-lts, per gominimal#97/gominimal#98: the node most users and hosting providers run is whatever ships with current LTS. node-lts ships its own npm, so it serves the build (`npm ci`) and the runtime (`#!/usr/bin/env node`) both — no split between build_deps and runtime_deps. Rebuilt and re-checked on the min path: 15/15 Pass. * vlt: record why this is a registry artifact, not a source build AGENTS.md requires a prebuilt fallback be called out explicitly. The reason here is not "nobody tried" — source IS published (7.4 MB tarball, 48 real TypeScript workspaces), it just cannot be built with a toolchain we have. Measured against the extracted tarball: npm -> EUNSUPPORTEDPROTOCOL: Unsupported URL Type "catalog:" pnpm -> ERR_PNPM_CATALOG_ENTRY_NOT_FOUND_FOR_SPEC Dependency specs use the `catalog:` protocol with the catalog declared in `vlt.json`; pnpm supports catalogs but reads pnpm-workspace.yaml. The only lockfile is `vlt-lock.json` (vlt's own format), and `package.json` has no `workspaces` key, so neither tool can see the monorepo layout. Upstream CI agrees: setup-vlt@v1 then `vlt install`. The published package declares `bin: null`, no deps, and one script — `prepack: vlt-build-prepack`. Building vlt from source requires vlt. That bootstrap cycle is the "required toolchain genuinely isn't packaged yet" case AGENTS.md carves out; breaking it means a two-stage vlt-bootstrap -> vlt pair in the gawk-bootstrap shape, worth doing if vlt becomes load-bearing and not before. Comment-only. Rebuilt and re-checked: 15/15 Pass.
…, sccache, …) (gominimal#371) * packages: add 10 CLI tools (wolfi import batch 5) — HELD until gominimal#367-370 merge High-star single-binary CLIs from `pkgmgr import-wolfi`: go: dive, lazydocker, esbuild, croc, restic, gitleaks, sops rust: sccache, tealdeer (→ tldr), dua Each builds clean + passes every `minimal check` at 0 TODOs. Sources mirrored to gs://minimal-staging-archives. NOT pushed / no PR yet — staged on this branch to open once batches 1-4 (gominimal#367-gominimal#370) land. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * restic: fix ver/help smoke test — restic uses the `version` subcommand Buildbot: `restic --version` → "unknown flag: --version". restic exposes its version via the `restic version` subcommand, not a `--version` flag. Regenerated with the fixed importer, which now probes both forms (`restic --version 2>/dev/null || restic version`). Passes every check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * gitleaks, lazydocker, tealdeer: address CR review - gitleaks: fix the version ldflag target. Upstream .goreleaser.yml stamps `github.com/zricethezav/gitleaks/v8/version.Version` — the module path kept the original zricethezav org (despite the GitHub org rename) and the var lives in the `version` package, not `cmd`. The old wrong path was silently ignored by the linker, leaving the version unstamped. Verified 8.30.1 embeds now. - lazydocker: drop `-X main.buildSource=wolfiRelease` — we build from source, so that origin label (printed by --version) was inaccurate. - tealdeer: license_spdx Apache-2.0 → "MIT OR Apache-2.0" (v1.8.1 Cargo.toml declares the dual license and ships both LICENSE-MIT and LICENSE-APACHE). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ominimal#438) Retrofit bash-language-server, typescript-language-server, and pyright off the global usr/lib/node_modules onto the private-libexec method (twitchyliquid64's gominimal#370 review): a tool's usr/lib/node_modules/** output overlaps the node/node-lts runtime's ownership of that path and welds it to one node variant. Each now installs into usr/libexec/<pkg> and exposes its bins as relative symlinks on PATH — the inner `#!/usr/bin/env node` shebang is served by coreutils(env)+node, so runtime_deps=[coreutils, node] stays correct (a `#!/bin/sh` wrapper would need bash in the closure and fail at runtime while still passing minimal check). Build-proven; all bins verified as symlinks resolving into libexec, no global leak — including typescript-language-server's THREE bins (itself + tsc/tsserver from the pinned typescript@5.9.3) and pyright's two. Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
…ominimal#751) (gominimal#753) * node packages: private libexec prefixes + a guard against a second npm (gominimal#751) Two follow-ups to gominimal#752: 1. cf, wrangler, next, mermaid-cli and capy installed into the shared usr/lib/node_modules, the tree the node runtime's own npm lives in (Tom's gominimal#370 warning). They now install into usr/libexec/<pkg> with relative usr/bin symlinks, like vlt and pnpm. A `test -e` on each link fails the build if an upstream bin is renamed, rather than shipping a dangling link. mermaid-cli's wrapper and next's sharp/test paths follow the move. 2. node-runtime-guard (BLOCKING, as Karl suggested in gominimal#751). It evaluates the whole catalog on amd64 and arm64 and rejects: - outputs under usr/lib/node_modules; - runtime deps that carry a node runtime's npm; - packages on `node` rather than `node-lts`. A dump failure exits 2 and fails the check, so an unverified run cannot go green. Full-catalog dry run: - main: FAILS 20 packages (34 flavor, 19 runtime-npm, 5 shared-tree). - main + gominimal#752 + this: PASSES all 531 packages. This check is red until gominimal#752 lands. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * AGENTS.md: document the Node pattern the guard enforces The rules that node-runtime-guard enforces are now written down where package authors and agents look first: - node-lts, not node; - interpreter-only at runtime; - a private libexec prefix, with a worked build.sh and build.ncl. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> * node-runtime-guard: catch broad globs; align AGENTS.md; capy output name (review) Addresses Karl's review on gominimal#753: - shared-tree now also rejects a broad recursive glob (`usr/**`, `usr/lib/**`, `**`) whose literal prefix is an ancestor of usr/lib/node_modules, in any package that BUILDS with a node runtime. Such a glob would capture an npm install and ship it. Non-node packages are exempt, so the 11 C libraries using `usr/**` are untouched. - Synthetic cases: usr/**, usr/lib/** and ** are flagged; usr/bin/*, usr/lib/*.so, usr/share/** and a C lib's usr/** are not. - Full catalog: main still fails the same 20 packages; with gominimal#752 it passes all 531. - AGENTS.md now claims only what the guard checks: build and runtime deps. node-lts for test_deps is stated as convention, since `minimal dump` has no tests to check. - capy: rename the output node_modules -> libexec to match the other four, and drop the stale "same shape as cf's node_modules" comment. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Fourth batch from
pkgmgr import-wolfi— node CLI tools. Node is a different shape from the tarball-built families: Minimal installs node CLIs from the npm registry by name+version (cf. typescript-language-server), not from a github source — so these have noSource, theynpm install -gat build time.What's here (4 packages, all build + pass every
minimal checkat 0 TODOs)@nxaddons)How they're produced
npm install -g --prefix="$OUTPUT_DIR/usr" <name>@$MINIMAL_ARG_VERSION.base+nodebuild_deps,coreutils+noderuntime_deps, aneeds = { dns, internet }block for the npm fetch, andbuild_args { include version }.usr/bin/<tool>is a symlink intonode_modules) +node_modules(allow_executable— some packages ship native.nodeaddons). Read from a verified build.Reviewer notes (surfaced, not hidden)
source_provenance— node packages install from the npm registry, not a pinned github tarball, so there's no'GithubRepoprovenance for vuln-scanning (matches Minimal's existing node packages like typescript-language-server). Worth a follow-up: an npm PURL for scan coverage.typescript). These 4 resolve their own deps vianpm install; the generated build.sh installs the single named package, and the import surfaces a reviewer note to add peers if a tool needs them.🤖 Generated with Claude Code
Summary by CodeRabbit
eslint,json-server,lerna, andserve.