diff --git a/.gitignore b/.gitignore index d063c3d..74679ed 100644 --- a/.gitignore +++ b/.gitignore @@ -8,3 +8,11 @@ web/styled-system/ # Playwright MCP writes screenshots here during manual verification .playwright-mcp/ profiles.png + +# Bun resolves fresh rather than reading package-lock.json, so a committed +# bun.lock would drift from it silently — measured at 5 transitive packages. +# package-lock.json is canonical: `npm ci` gates CI, and npm trusted publishing +# (OIDC + provenance) keeps the npm CLI in the release path permanently. +# Bun stays a first-class RUNTIME — `bun run`, `bunx` — just not the installer. +bun.lock +bun.lockb diff --git a/AGENTS.md b/AGENTS.md index d8e1e79..2671fc3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -53,6 +53,7 @@ runtime assertions and is checked by `tsc`. `npm run typecheck` runs it. | `src/composition/**` | Five composition roots: `launch-root` (hot path), `config-root`, `doctor-root`, `ui-root`, `web-root`. | | `bin/swisscode.js` | Published entry shim. Plain JS, never compiled, imports exactly `../dist/cli.js`. | | `test/**` | `.ts`, run from source, never compiled, never packed. | +| `web/**` | An npm WORKSPACE (`@swisscode/web`, private). Owns the browser-only devDeps — vite, panda, preact, `@types/react-dom`. Ships as built assets inside the swisscode package, never as its own release. | ## Hard invariants @@ -196,6 +197,17 @@ neutral `LaunchIntent` is missing something — propose that instead. ## Useful facts +- **`package-lock.json` is the only lockfile. Install with npm.** `bun install` + does not read it and resolves fresh — measured drift of 5 transitive packages + — and `bun publish` has no OIDC/provenance, so the npm CLI is permanently in + the release path (`publish.yml`). `bun.lock` is gitignored. +- **Bun is a first-class RUNTIME, not the installer.** `bun run