PacketBenchDocs

pnpm scripts#

PacketBench ships no command-line binary. The scripts block in package.json is the closest thing it has to a CLI surface: 48 entries covering the dev loop, five quality gates, thirteen sidecar smoke tests, the Node-runtime fetch, the release gate and two macOS build workarounds. There is no CI, so every one of them runs on a developer's machine or it does not run at all.

This page lists every script in package.json, what each one actually executes, and when to reach for it. It also owns the "match the gate to the change" table, which decides how far up the ladder a given change has to climb.

Ordering. The table below is in source order — the order the scripts are declared in package.json — not alphabetical, so it reads the way the file reads. Composites are unpacked in the sections that follow.

Every script#

Script What it runs When to use it
dev vite — the frontend dev server on port 1420, strictPort (vite.config.ts:76-77) Rarely on its own. pnpm tauri dev invokes it as beforeDevCommand (src-tauri/tauri.conf.json:7); run it bare only to work on the UI in a plain browser
build tsc && vite build The type-check and production bundle. Also the build half of Tauri's beforeBuildCommand
preview vite preview Serve an already-built dist/ to check the production bundle without Tauri
tauri tauri Passthrough to the Tauri CLI. This is the front door for pnpm tauri dev and pnpm tauri build
lint pnpm run lint:src An alias. Type pnpm lint; it is the same run as lint:src
lint:src eslint src e2e The lint gate preflight executes. Warnings are permitted
lint:strict eslint src e2e --max-warnings=0 Checking whether the warning count has grown. No gate runs thispreflight uses lint:src, so warnings never fail a build
format prettier --write "src/**/*.{ts,tsx,css}" Formatting frontend source. Note the file set: it does not overlap format:check — see below
format:check prettier --check package.json eslint.config.js dev/local-quality-gates.md "e2e/**/*.{ts,tsx}" The first rung of preflight. Four targets only: the manifest, the ESLint config, the gate ladder document, and the e2e tests
test vitest run The unit gate. Covers src/**/*.{test,spec}.{ts,tsx} and scripts/**/*.{test,spec}.{mjs,ts} (vitest.config.ts:15)
test:watch vitest Watch mode while writing tests. Not a gate
e2e playwright test Playwright against the Vite dev server in web mode, Chromium only, Tauri IPC mocked (playwright.config.ts:9-12). Run after anything user-facing in the browser
generate:tauri-schema cd src-tauri && cargo test --test api_schema export_api_bindings -- --ignored --nocapture Regenerate src/generated/tauri-schema.ts after changing a shared DTO. Run this when check:tauri-schema fails
check:tauri-schema node scripts/check-tauri-schema.mjs The gate that asserts the committed bindings match what the Rust exporter produces right now
fetch-node node scripts/fetch-node.js Stage the pinned Node runtime for the host target into src-tauri/binaries/. Idempotent; prebundle calls it for you
fetch-node:all node scripts/fetch-node.js --all-targets Stage the runtime for all five supported Rust triples at once (scripts/fetch-node.js:10-14). Cross-target packaging work only
sidecar:install node scripts/run-pnpm-no-deprecation.mjs -C agent-sidecar install Install the sidecar's own dependencies. Run this after any production buildsidecar:prune deletes them
sidecar:build pnpm -C agent-sidecar build Compile the sidecar to agent-sidecar/dist/
sidecar:dev pnpm -C agent-sidecar dev tsc --watch for the sidecar. Run it in a second terminal while working on sidecar code
sidecar:check sidecar:installsidecar:build → the thirteen smokes, chained with && The sidecar gate. Required for anything touching agent-sidecar/, provider routing, protocol types or the supervisor
sidecar:prune node scripts/prune-sidecar.js Strip devDependencies from agent-sidecar/node_modules so the Tauri bundler picks up a production-only tree. Destructive; prebundle calls it
sidecar:smoke node agent-sidecar/test/echo-smoke.mjs Baseline: the sidecar starts and echoes
sidecar:remote-project-smoke node agent-sidecar/test/remote-project-path-smoke.mjs Remote project-path resolution
sidecar:registry-smoke node agent-sidecar/test/registry-smoke.mjs The provider registry
sidecar:protocol-smoke node agent-sidecar/test/protocol-v9-smoke.mjs Protocol v9 conformance
sidecar:session-ordering-smoke node agent-sidecar/test/session-ordering-smoke.mjs Session event ordering
sidecar:gating-smoke node agent-sidecar/test/openai-agents-gating-smoke.mjs OpenAI Agents tool gating
sidecar:anthropic-edit-correlation-smoke node agent-sidecar/test/anthropic-edit-correlation-smoke.mjs Correlating Anthropic edit events to their tool calls
sidecar:anthropic-multi-turn-smoke node agent-sidecar/test/anthropic-multi-turn-smoke.mjs Multi-turn Anthropic conversations
sidecar:mcp-config-smoke node agent-sidecar/test/mcp-config-merge-smoke.mjs MCP config merging
sidecar:mcp-trust-smoke node agent-sidecar/test/mcp-trust-smoke.mjs MCP trust state
sidecar:mcp-trust-enforcement-smoke node agent-sidecar/test/mcp-trust-enforcement-smoke.mjs MCP trust actually being enforced, not merely recorded
sidecar:remote-mcp-fromfs-smoke node agent-sidecar/test/remote-mcp-fromfs-smoke.mjs Remote MCP servers loaded from the filesystem
sidecar:anthropic-apikey-smoke node agent-sidecar/test/anthropic-apikey-smoke.mjs Anthropic API-key handling
clean:dmg-scratch node scripts/clean-dmg-scratch.mjs Detach leftover attached DMG scratch images and delete stray rw.*.dmg files. macOS-only; a no-op elsewhere (scripts/clean-dmg-scratch.mjs:21-23)
build:macos node scripts/build-macos.mjs The macOS build. Use this instead of pnpm tauri build on macOS — it retries the flaky DMG step
prebundle clean:dmg-scratchfetch-nodesidecar:installsidecar:buildsidecar:prunerelease:gate Not a script you normally type. Tauri runs it as the first half of beforeBuildCommand (src-tauri/tauri.conf.json:9)
preflight format:checklint:srctestbuild The everyday pre-commit pass. Run it before you push anything
release:gate node scripts/release-gate.mjs Pre-bundle assertions about version, icons, the staged Node binary and the sidecar tree. Runs inside every pnpm tauri build
release:gate:strict node scripts/release-gate.mjs --require-clean --require-signing --require-updater The same gate with three extra requirements turned on: a clean tree, signing configured, updater keys present (scripts/release-gate.mjs:15-21)
postinstall node scripts/run-pnpm-no-deprecation.mjs -C agent-sidecar install Automatic. Every pnpm install installs the sidecar's dependencies too
build:all pnpm sidecar:build && pnpm build Build the sidecar and the frontend in one step, without the full bundle chain
rust:check cd src-tauri && cargo check Fast backend type-check
rust:test cd src-tauri && cargo test The backend test gate. Required for changes to commands, providers, state or orchestration
release:readiness node scripts/release-readiness.mjs Executes the nine quality gates in order, then reports on signing, updater config and built artifacts
release:readiness:report node scripts/release-readiness.mjs --report-only The same report without executing the gates. --report-only implies --skip-gates (scripts/release-readiness.mjs:15-18)
check preflighte2esidecar:checkcheck:tauri-schemarust:checkrust:test Everything. Genuinely long — Playwright, thirteen sequential sidecar smokes and the full Rust suite
docs:build node scripts/build-docs.mjs Render the in-repo Markdown at docs/src/ to static HTML in docs/guide/ (scripts/build-docs.mjs:20-21)

The three rungs#

The gates form a ladder. Each rung contains the one below it, so you never need to run both.

pnpm preflight          format:check → lint:src → test → build
       │
pnpm check              preflight → e2e → sidecar:check → check:tauri-schema
       │                         → rust:check → rust:test
       │
pnpm release:readiness  those nine, executed, plus the distribution report

release-readiness.mjs declares the nine gates it executes explicitly (scripts/release-readiness.mjs:32-42) and reports check as a row derived from those results rather than executed. Running it as a tenth gate would run everything a second time. The script re-derives that relationship from package.json on every run and refuses to claim the composite if the scripts have drifted (scripts/release-readiness.mjs:22-31).

Note

pnpm check is slow enough that release-readiness.mjs defaults to a 45-minute per-gate timeout, overridable with PACKETBENCH_RELEASE_GATE_TIMEOUT_MS (scripts/release-readiness.mjs:19). That default is a fair indicator of the magnitude.

Match the gate to the change#

pnpm preflight is the floor. Climb from there according to what you touched.

Changed Also run
agent-sidecar/, provider routing, protocol types, supervisor pnpm sidecar:check
Shared contracts, generated types, persisted state, request/response payloads pnpm check:tauri-schema
Backend commands, providers, state, orchestration pnpm rust:test
Anything user-facing in the browser pnpm e2e

Release-facing work climbs the whole ladder and then runs pnpm release:readiness. dev/local-quality-gates.md is the canonical ladder document in the repository — and it is itself covered by format:check, so editing it with the wrong Prettier formatting breaks preflight.

What the composites expand to#

Composite Expansion
lint lint:src
preflight format:check, lint:src, test, build
sidecar:check sidecar:install, sidecar:build, then sidecar:smoke, sidecar:remote-project-smoke, sidecar:registry-smoke, sidecar:protocol-smoke, sidecar:session-ordering-smoke, sidecar:gating-smoke, sidecar:anthropic-edit-correlation-smoke, sidecar:anthropic-multi-turn-smoke, sidecar:mcp-config-smoke, sidecar:mcp-trust-smoke, sidecar:mcp-trust-enforcement-smoke, sidecar:remote-mcp-fromfs-smoke, sidecar:anthropic-apikey-smoke
prebundle clean:dmg-scratch, fetch-node, sidecar:install, sidecar:build, sidecar:prune, release:gate
build:all sidecar:build, build
check preflight, e2e, sidecar:check, check:tauri-schema, rust:check, rust:test
release:readiness format:check, lint:src, test, build, e2e, sidecar:check, check:tauri-schema, rust:check, rust:testcheck derived

Every chain uses &&, so the first non-zero exit stops the run. There is no --continue-on-error anywhere in the block.

Scripts you do not type#

Script Invoked by
postinstall pnpm, on every pnpm install
prebundle Tauri, as the first half of beforeBuildCommand (src-tauri/tauri.conf.json:9)
build Tauri, as the second half of the same command, and by preflight
dev Tauri, as beforeDevCommand (src-tauri/tauri.conf.json:7)
release:gate prebundle, on every pnpm tauri build
lint:src, format:check, test preflight

Sharp edges#

These bite, and they are documented rather than fixed.

format and format:check cover disjoint file sets. format writes src/**/*.{ts,tsx,css}. format:check reads package.json, eslint.config.js, dev/local-quality-gates.md and e2e/**/*.{ts,tsx}. There is no overlap at all, so running pnpm format cannot fix a format:check failure, and a format:check pass says nothing about src/. Fix the four checked targets by hand, or point Prettier at them directly.

pnpm sidecar:build fails after a production build. prune-sidecar.js runs pnpm -C agent-sidecar install --prod --ignore-scripts, which removes typescript and @types/node from the sidecar's node_modules. Re-run pnpm sidecar:install to restore them. The script header says so at scripts/prune-sidecar.js:14-24, and it catches everyone once.

Run the bare pnpm test, not vitest src. Scoping to a directory silently skips the repository fences, which are pulled in by the scripts/** glob in vitest.config.ts:15. Those fences walk the whole source tree, which is why pnpm test can fail with no test file anywhere near your change.

pnpm dev and pnpm e2e both want port 1420. Vite is configured with strictPort (vite.config.ts:76-77) and Playwright starts its own server on the same port, with reuseExistingServer on outside CI (playwright.config.ts:34-40). Locally the e2e run attaches to a dev server you already have up; set PLAYWRIGHT_PORT to separate them.

lint:strict gates nothing. preflight runs lint:src, which tolerates warnings. The 0.13.1 release recorded pnpm lint as green with nine pre-existing warnings — see Testing & gates.

build:macos, not pnpm tauri build, on macOS. bundle_dmg.sh runs a cosmetic Finder AppleScript that fails on roughly half of first attempts and abandons a mounted scratch image when it does. The wrapper builds once, detaches the leaked image and retries just the DMG step; the Rust artifacts are cached, so the retry is cheap (scripts/build-macos.mjs:5-15).

Warning

pnpm docs:build renders docs/src/ into docs/guide/ inside the PacketBench repository (scripts/build-docs.mjs:20-21). It does not build this site, which lives in a separate repository with its own generator.

  • Testing & gates — what each gate proves, and what was green at the last release
  • Build & release — the toolchain, the bundle chain and the release checklist
  • Contributing — commit conventions and the review bar these gates enforce
  • Agent orientation — the machine-readable briefing that points agents at this ladder
  • Environment variablesPACKETBENCH_RELEASE_GATE_TIMEOUT_MS and the other knobs these scripts read
  • Troubleshooting — when a gate fails for a reason that is not your change