get-tbd 0.1.28 → 0.1.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,7 +24,7 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
24
24
 
25
25
  | Tool / Package | Version | Check For Updates |
26
26
  | --- | --- | --- |
27
- | **Node.js** | 24 (LTS "Krypton") | [nodejs.org/releases](https://nodejs.org/en/about/previous-releases) — Node 24 Active LTS until Oct 2026. **Node 26 Current** shipped 2026-05-05 (Temporal API enabled by default, V8 14.6, Undici 8.0). **Node 20 went EOL 2026-03-24.** Node 26 is the last release on the old two-major-per-year cadence; starting v27, all majors become LTS (one per year). |
27
+ | **Node.js** | 24 (LTS Krypton) | [nodejs.org/releases](https://nodejs.org/en/about/previous-releases) — Node 24 Active LTS until Oct 2026. **Node 26 Current** shipped 2026-05-05 (Temporal API enabled by default, V8 14.6, Undici 8.0). **Node 20 went EOL 2026-03-24.** Node 26 is the last release on the old two-major-per-year cadence; starting v27, all majors become LTS (one per year). |
28
28
  | **pnpm** | ^11.0.0 (11.2.x too recent) | [github.com/pnpm/pnpm/releases](https://github.com/pnpm/pnpm/releases) — **Pinned to 11.0.0 (2026-04-28) per the 14-day rule**; 11.2.0/11.2.2 shipped 2026-05-20/21 (1–2 days old today). Breaking changes: pure ESM (requires **Node 22+**); SQLite-based store (`$STORE/index.db`); **`minimumReleaseAge` defaults to 1440 minutes (1 day)** for supply-chain hygiene; **`blockExoticSubdeps` defaults to `true`**; `onlyBuiltDependencies`/`neverBuiltDependencies` removed and replaced by **`allowBuilds`**; `patchedDependencies` format simplified; experimental Rust-based `@pnpm/pacquet` engine arrives in 11.2+. v11.1 added `pnpm audit signatures`, `pnpm bugs`, `pnpm owner`. |
29
29
  | **TypeScript** | ^6.0.3 | [github.com/microsoft/TypeScript/releases](https://github.com/microsoft/TypeScript/releases) — **6.0.3 stable** (shipped 2026-03-23). 6.0 is the last JavaScript-based release; `strict: true` is now the default, ESM is the default module system, ~9 compiler settings flipped defaults. **TS 7.0 Beta** (Project Corsa, Go rewrite) shipped 2026-04-21 as `@typescript/native-preview` (binary: `tsgo`); claims ~10× type-check speed and ~3× less memory. Stable expected mid-to-late 2026. Do not adopt `tsgo` for production builds yet. |
30
30
  | **tsdown** | ^0.22.0 | [github.com/rolldown/tsdown/releases](https://github.com/rolldown/tsdown/releases) — 0.22.0 (2026-05-07). Has not reached 1.0; incremental 0.20→0.22 releases since Feb 2026; no deprecations. Requires Node.js 20.19+. |
@@ -32,8 +32,8 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
32
32
  | **@changesets/cli** | ^2.31.0 | [github.com/changesets/changesets/releases](https://github.com/changesets/changesets/releases) — 2.31.0 latest. No native Bun support added. |
33
33
  | **@types/node** | ^24.0.0 | [@types/node npm](https://www.npmjs.com/package/@types/node) — Track Node.js major version. @types/node@25.x available; @types/node@26.x will follow Node 26. |
34
34
  | **actions/checkout** | v6 | [github.com/actions/checkout/releases](https://github.com/actions/checkout/releases) — v6.0.2 (2026-01-09). Credentials now stored in `$RUNNER_TEMP` rather than `.git/config`; Node 24 runtime; requires runner ≥ 2.327.1. |
35
- | **actions/setup-node** | v6 | [github.com/actions/setup-node/releases](https://github.com/actions/setup-node/releases) — Supports Node 24 by default. **Note GitHub's 2026-06-02 deadline forcing Node.js 20 actions to Node.js 24.** |
36
- | **pnpm/action-setup** | v6 | [github.com/pnpm/action-setup/releases](https://github.com/pnpm/action-setup/releases) — **v6 required for pnpm 11+ support.** v4 (previously documented) does not handle pnpm 11's ESM-only distribution correctly. |
35
+ | **actions/setup-node** | v6 | [github.com/actions/setup-node/releases](https://github.com/actions/setup-node/releases) — Supports Node 24 by default. **Note GitHubs 2026-06-02 deadline forcing Node.js 20 actions to Node.js 24.** |
36
+ | **pnpm/action-setup** | v6 | [github.com/pnpm/action-setup/releases](https://github.com/pnpm/action-setup/releases) — **v6 required for pnpm 11+ support.** v4 (previously documented) does not handle pnpm 11s ESM-only distribution correctly. |
37
37
  | **changesets/action** | v1 | [github.com/changesets/action](https://github.com/changesets/action) — Still v1. No v2. |
38
38
  | **lefthook** | ^2.1.5 (2.1.7/2.1.8 too recent) | [github.com/evilmartians/lefthook/releases](https://github.com/evilmartians/lefthook/releases) — **Pinned to 2.1.5 (2026-04-06) per the 14-day rule**; 2.1.7/2.1.8 both shipped 2026-05-19. Patch-level since 2.1.1. v2 still excludes regexp `exclude` and `skip_output` from v1. |
39
39
  | **npm-check-updates** | ^22.0.0 (22.2.0 too recent) | [npmjs.com/package/npm-check-updates](https://www.npmjs.com/package/npm-check-updates) — **Major version jump from 19 to 22.** **Pinned to 22.0.0 (2026-04-25) per the 14-day rule**; 22.2.0 (2026-05-12) is 10 days old today. Now pure ESM; named imports only (`import { run } from 'npm-check-updates'`); `.ncurc.js` with `module.exports` no longer works in `"type": "module"` projects (use `.ncurc.cjs`). **Ships `--cooldown <days>` to refuse versions younger than the specified age** — primary enforcement for the 14-day package-age rule. See [Supply-Chain Mitigation](#supply-chain-mitigation). |
@@ -47,7 +47,7 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
47
47
  | **picocolors** | ^1.1.1 | [npmjs.com/package/picocolors](https://www.npmjs.com/package/picocolors) — Last release October 2024. Stable; no changes expected. |
48
48
  | **dotenv** | ^17.4.2 | [npmjs.com/package/dotenv](https://www.npmjs.com/package/dotenv) — Stable. **Prefer Node.js native `--env-file` for Node ≥20.6** (production-ready since Node 24 LTS); use dotenv only when you need variable expansion, multiline values, or custom precedence logic. |
49
49
  | **atomically** | ^2.1.1 | [npmjs.com/package/atomically](https://www.npmjs.com/package/atomically) — 2.1.1 (2026-02-08). Still maintained. |
50
- | **yaml** | ^2.8.4 | [npmjs.com/package/yaml](https://www.npmjs.com/package/yaml) — 2.8.4 (2026-05-02). v3.0.0-1 is tagged "next" (pre-release) — do not adopt yet. |
50
+ | **yaml** | ^2.8.4 | [npmjs.com/package/yaml](https://www.npmjs.com/package/yaml) — 2.8.4 (2026-05-02). v3.0.0-1 is tagged next (pre-release) — do not adopt yet. |
51
51
  | **@vitest/coverage-v8** | ^4.1.7 | [npmjs.com/package/@vitest/coverage-v8](https://www.npmjs.com/package/@vitest/coverage-v8) — Track Vitest version. |
52
52
 
53
53
  ### Reminders When Updating
@@ -75,8 +75,8 @@ author: Joshua Levy (github.com/jlevy) with LLM assistance
75
75
 
76
76
  6. **Review “Open Research Questions”** section for any resolved items
77
77
 
78
- 7. **Honor the 14-day package-age rule** when bumping versions in code examples. See
79
- [Supply-Chain Mitigation](#supply-chain-mitigation) — versions cited here should
78
+ 7. **Honor the 14-day package-age rule** when bumping versions in code examples.
79
+ See [Supply-Chain Mitigation](#supply-chain-mitigation) — versions cited here should
80
80
  be ≥14 days old at the time the table is updated, except where a clearly-noted
81
81
  security exception applies.
82
82
 
@@ -154,20 +154,20 @@ recommendations from the TypeScript and JavaScript ecosystem maintainers.
154
154
 
155
155
  - `pnpm deploy` command enables isolated production deployments for Docker
156
156
 
157
- - **pnpm 11 (shipped 2026-04-28)** adds significant supply-chain hardening
158
- defaults: `minimumReleaseAge: 1440` (1 day) and `blockExoticSubdeps: true`.
159
- We recommend overriding `minimumReleaseAge` to 14 days — see
157
+ - **pnpm 11 (shipped 2026-04-28)** adds significant supply-chain hardening defaults:
158
+ `minimumReleaseAge: 1440` (1 day) and `blockExoticSubdeps: true`. We recommend
159
+ overriding `minimumReleaseAge` to 14 days — see
160
160
  [Supply-Chain Mitigation](#supply-chain-mitigation).
161
161
 
162
- - **pnpm 11 is pure ESM and requires Node.js 22+.** Lifecycle script gating
163
- has moved from `onlyBuiltDependencies`/`neverBuiltDependencies` to
164
- **`allowBuilds`** (an explicit allowlist).
162
+ - **pnpm 11 is pure ESM and requires Node.js 22+.** Lifecycle script gating has moved
163
+ from `onlyBuiltDependencies`/`neverBuiltDependencies` to **`allowBuilds`** (an
164
+ explicit allowlist).
165
165
 
166
- - The store is now a single SQLite database (`$STORE/index.db`) for faster
167
- cache reads; this is invisible to users but matters for CI cache configs.
166
+ - The store is now a single SQLite database (`$STORE/index.db`) for faster cache reads;
167
+ this is invisible to users but matters for CI cache configs.
168
168
 
169
- **Assessment**: pnpm remains the consensus choice for TypeScript monorepos, with
170
- pnpm 11 adding meaningful supply-chain defaults and faster store I/O.
169
+ **Assessment**: pnpm remains the consensus choice for TypeScript monorepos, with pnpm 11
170
+ adding meaningful supply-chain defaults and faster store I/O.
171
171
 
172
172
  **Key Configuration** (`pnpm-workspace.yaml`):
173
173
 
@@ -1118,15 +1118,15 @@ Vite’s transformation pipeline.
1118
1118
 
1119
1119
  - Visual regression testing (added in Vitest 4.0)
1120
1120
 
1121
- - **Vitest 4.1 (Mar 2026)** added Vite 8 support, test tags for organizing tests,
1122
- and extended chai-style assertions for mocking. Vitest now reuses the
1123
- installed Vite instead of bundling a separate dependency.
1121
+ - **Vitest 4.1 (Mar 2026)** added Vite 8 support, test tags for organizing tests, and
1122
+ extended chai-style assertions for mocking.
1123
+ Vitest now reuses the installed Vite instead of bundling a separate dependency.
1124
1124
 
1125
- - **`coverage.all` was removed in v4** — use `coverage.include` and
1126
- `coverage.exclude` to control which files are reported.
1125
+ - **`coverage.all` was removed in v4** — use `coverage.include` and `coverage.exclude`
1126
+ to control which files are reported.
1127
1127
 
1128
- - **Vitest 5.0.0-beta** is in pre-release (requires Node 22+ and Vite 6.4+).
1129
- Stay on 4.1.x for production until stable.
1128
+ - **Vitest 5.0.0-beta** is in pre-release (requires Node 22+ and Vite 6.4+). Stay on
1129
+ 4.1.x for production until stable.
1130
1130
 
1131
1131
  **Installation**:
1132
1132
 
@@ -1809,8 +1809,8 @@ pnpm add -Dw npm-check-updates
1809
1809
 
1810
1810
  - Pure ESM. Named imports only: `import { run } from 'npm-check-updates'`. Default
1811
1811
  exports no longer work.
1812
- - Config files: `.ncurc.js` with `module.exports` no longer works in
1813
- `"type": "module"` projects. Use `.ncurc.cjs`.
1812
+ - Config files: `.ncurc.js` with `module.exports` no longer works in `"type": "module"`
1813
+ projects. Use `.ncurc.cjs`.
1814
1814
  - Node.js requirement: `^20.19.0 || ^22.12.0 || >=24.0.0`.
1815
1815
 
1816
1816
  **Upgrade Targets Explained**:
@@ -2536,237 +2536,19 @@ than discovering them when users try to use the library in browser/edge contexts
2536
2536
 
2537
2537
  ## Supply-Chain Mitigation
2538
2538
 
2539
- > **Sync note**: this section is normative and is duplicated **verbatim** in both
2540
- > `bun-monorepo-patterns.md` and `pnpm-monorepo-patterns.md`. When you change one,
2541
- > change the other in the same commit. Tooling-specific commands (e.g.
2542
- > `bun audit` vs. `pnpm audit`) are called out inline.
2539
+ Supply-chain hardening applies to **every repo, not just new monorepos**, so the full
2540
+ policy and hands-on enforcement now live in a standalone guideline:
2541
+ **`tbd guidelines supply-chain-hardening`**. It covers the cross-ecosystem 14-day
2542
+ cool-off plus the Node/pnpm/Bun specifics lifecycle-script allowlists, lockfile
2543
+ discipline, `npm-check-updates --cooldown 14`, the CI audit gate, and the
2544
+ `check-package-age` pre-push guard.
2545
+ Deeper background and the named-incident watch list:
2546
+ <https://github.com/jlevy/supply-chain-hardening>.
2543
2547
 
2544
- Modern TypeScript supply-chain attacks land through fresh package versions — a
2545
- maintainer's npm token is compromised, malware is published as a patch release, and
2546
- the registry yanks it 1–10 days later once detection catches up. The
2547
- **Shai-Hulud 2.0** campaign of May 2026 compromised 170+ npm packages this way, and
2548
- similar campaigns ran through 2025 (`debug`, `chalk`, `ansi-styles` lookalikes;
2549
- `expr-eval` post-install RCE). pnpm shipped `minimumReleaseAge` as a default in
2550
- v11.0 (1 day). Bun ships a built-in trusted-dependency allowlist and `bun audit`.
2551
- The settings below are stricter than the ecosystem defaults and intentionally so.
2552
-
2553
- ### The 14-day package-age rule
2554
-
2555
- **Never install or upgrade to a package version less than 14 days old.**
2556
-
2557
- Why 14 days specifically:
2558
-
2559
- - **Detection window**: most malicious publishes are reported and yanked within
2560
- 3–7 days; 14 days gives a generous buffer past that median.
2561
- - **Patch-level releases ship dangerous code more often**: many compromises arrive
2562
- as `1.2.3 → 1.2.4` patch bumps. A trailing window neutralizes the entire class
2563
- of "fresh patch is malicious" attacks regardless of which dependency moved.
2564
- - **Cheap to enforce, cheap to wait**: there is essentially no business cost to
2565
- waiting 14 days on a routine upgrade, and the upside is large.
2566
-
2567
- Scope:
2568
-
2569
- - Applies to **`dependencies`, `devDependencies`, `peerDependencies`, and
2570
- `optionalDependencies`** alike. devDependencies (bundlers, linters, test
2571
- runners) have historically been *more* dangerous than runtime deps because
2572
- they execute with full developer privileges on every install.
2573
- - Applies to **transitive dependencies** to the extent the package manager
2574
- enforces it (see below). Direct deps are the primary control point.
2575
- - Applies to **upgrades and new installs**. Existing pins resolved before this
2576
- policy was adopted are grandfathered until their next planned upgrade.
2577
-
2578
- Exception process: if a security patch within the 14-day window is needed —
2579
- e.g., a CVE patch published yesterday that fixes a vulnerability you are
2580
- exposed to — the exception **must** be documented in the upgrade commit message
2581
- or PR description, including:
2582
-
2583
- - The CVE ID (or vulnerability description if no CVE yet).
2584
- - A link to the upstream release notes.
2585
- - A reviewer sign-off line (`Reviewed-by: …`).
2586
-
2587
- No exception is "trivial" — even a `prettier` patch is in scope. The whole
2588
- point of the rule is that we don't trust ourselves to spot-judge which fresh
2589
- versions are safe.
2590
-
2591
- ### Enforcement: pnpm
2592
-
2593
- pnpm 11 ships **`minimumReleaseAge`** as a config setting (default 1440 minutes
2594
- = 1 day). Override it to 14 days in `.npmrc` or `pnpm-workspace.yaml`:
2595
-
2596
- ```ini
2597
- # .npmrc
2598
- # 14 days in minutes (14 * 24 * 60).
2599
- minimum-release-age=20160
2600
- ```
2601
-
2602
- ```yaml
2603
- # pnpm-workspace.yaml
2604
- minimumReleaseAge: 20160
2605
- ```
2606
-
2607
- pnpm will refuse to resolve to any version published less than that long ago.
2608
- Use a per-package allowlist exception (`minimumReleaseAgeExclude`) only with
2609
- the documented exception process above.
2610
-
2611
- pnpm 11 also defaults **`blockExoticSubdeps`** to `true` (blocks transitive
2612
- dependencies installed from non-registry sources like `github:`, `git+ssh://`,
2613
- or arbitrary URLs). Keep this default on.
2614
-
2615
- Lifecycle script hygiene in pnpm 11 uses the new **`allowBuilds`** allowlist
2616
- (replacing `onlyBuiltDependencies` / `neverBuiltDependencies`). Declare the
2617
- exact packages allowed to run install scripts:
2618
-
2619
- ```yaml
2620
- # pnpm-workspace.yaml
2621
- allowBuilds:
2622
- - esbuild
2623
- - sharp
2624
- ```
2625
-
2626
- Everything not in this list runs without `postinstall`/`preinstall`/`install`
2627
- scripts. This is the single most important mitigation pnpm gives you out of
2628
- the box.
2629
-
2630
- `pnpm audit` and `pnpm audit signatures` (added in 11.1) provide vulnerability
2631
- and provenance checks:
2632
-
2633
- ```bash
2634
- pnpm audit --audit-level=moderate
2635
- pnpm audit signatures
2636
- ```
2637
-
2638
- ### Enforcement: cross-tool tooling
2639
-
2640
- **`npm-check-updates --cooldown`** is the upgrade-time check, complementing
2641
- pnpm's resolution-time `minimumReleaseAge`. Use it in scripts even on
2642
- pnpm-managed projects:
2643
-
2644
- ```bash
2645
- # Refuse any candidate version younger than 14 days
2646
- pnpm dlx npm-check-updates --cooldown 14
2647
-
2648
- # Interactive upgrade with the 14-day filter applied
2649
- pnpm dlx npm-check-updates --cooldown 14 --target minor --interactive
2650
-
2651
- # CI-style check: exits non-zero if upgrades are available
2652
- pnpm dlx npm-check-updates --cooldown 14 --errorLevel 2
2653
- ```
2654
-
2655
- **Direct registry query** (when in doubt about a specific version):
2656
-
2657
- ```bash
2658
- # Show all publish times for a package
2659
- npm view typescript time
2660
-
2661
- # Show the time of a specific version
2662
- npm view typescript time.6.0.3
2663
- ```
2664
-
2665
- If `npm view <pkg> time.<version>` reports less than 14 days ago, **wait**.
2666
-
2667
- ### Enforcement: lockfile discipline
2668
-
2669
- - **Always commit `pnpm-lock.yaml`**.
2670
- - **Use `pnpm install --frozen-lockfile` in CI** so any drift between
2671
- `package.json` and `pnpm-lock.yaml` fails the build instead of silently
2672
- resolving to fresh versions.
2673
- - **Never run `pnpm update` (or `pnpm install` on a fresh `node_modules` with
2674
- an unpinned `package.json`) without lockfile review.** Treat lockfile diffs
2675
- the same as code diffs.
2676
- - In a monorepo, **a single root `pnpm-lock.yaml`** is the source of truth;
2677
- per-package lockfiles are an anti-pattern.
2678
-
2679
- ### Enforcement: provenance and signatures
2680
-
2681
- - Prefer dependencies that publish with [npm provenance attestations](https://docs.npmjs.com/generating-provenance-statements).
2682
- Major projects (TypeScript, Vitest, Prettier, ESLint, etc.) ship these.
2683
- - Run `pnpm audit signatures` in CI on a periodic basis to catch tampered
2684
- packages.
2685
-
2686
- ### Sample CI gate
2687
-
2688
- Add this job to the CI workflow alongside lint/test:
2689
-
2690
- ```yaml
2691
- audit:
2692
- runs-on: ubuntu-latest
2693
- steps:
2694
- - uses: actions/checkout@v6
2695
- - uses: pnpm/action-setup@v6
2696
- with:
2697
- run_install: false
2698
- - uses: actions/setup-node@v6
2699
- with:
2700
- node-version: 24
2701
- cache: pnpm
2702
- - run: pnpm install --frozen-lockfile
2703
- - name: Vulnerability audit
2704
- run: pnpm audit --audit-level=moderate
2705
- - name: Signature audit
2706
- run: pnpm audit signatures
2707
- - name: Package-age check
2708
- run: pnpm dlx npm-check-updates --cooldown 14 --errorLevel 0
2709
- # errorLevel 0 logs but doesn't fail — flip to 2 once you've cleared
2710
- # the existing backlog.
2711
- ```
2712
-
2713
- ### Recommended local script
2714
-
2715
- Drop a `scripts/check-package-age.mjs` one-liner in the repo that a pre-push
2716
- hook can call:
2717
-
2718
- ```ts
2719
- #!/usr/bin/env tsx
2720
- // Refuses to commit if any direct dependency in package.json was published
2721
- // less than COOLDOWN_DAYS ago. Intended for the pre-push hook.
2722
- import pkg from '../package.json' with { type: 'json' };
2723
-
2724
- const COOLDOWN_MS = 14 * 24 * 60 * 60 * 1000;
2725
- const now = Date.now();
2726
- const all = { ...pkg.dependencies, ...pkg.devDependencies };
2727
-
2728
- let violations = 0;
2729
- for (const [name, spec] of Object.entries(all)) {
2730
- const version = String(spec).replace(/^[\^~=<>]+/, '');
2731
- const meta = await (await fetch(`https://registry.npmjs.org/${name}`)).json();
2732
- const publishedAt = meta.time?.[version];
2733
- if (!publishedAt) continue;
2734
- const ageMs = now - new Date(publishedAt).getTime();
2735
- if (ageMs < COOLDOWN_MS) {
2736
- const days = (ageMs / 86_400_000).toFixed(1);
2737
- console.error(`✗ ${name}@${version} is only ${days} days old (< 14)`);
2738
- violations++;
2739
- }
2740
- }
2741
- process.exit(violations > 0 ? 1 : 0);
2742
- ```
2743
-
2744
- Wire it into lefthook:
2745
-
2746
- ```yaml
2747
- pre-push:
2748
- commands:
2749
- package-age:
2750
- glob: "package.json"
2751
- run: pnpm tsx scripts/check-package-age.ts
2752
- ```
2753
-
2754
- ### Exception bookkeeping
2755
-
2756
- When you take an exception, leave a one-line marker in `package.json` adjacent
2757
- to the pin:
2758
-
2759
- ```jsonc
2760
- {
2761
- "devDependencies": {
2762
- // Exception: CVE-2026-XXXX patch within 14d window. Reviewed 2026-05-21.
2763
- "vitest": "4.1.7"
2764
- }
2765
- }
2766
- ```
2767
-
2768
- (JSON strict-parsers will reject `//` comments — use a JSONC-aware tool or
2769
- move the note to a `README.md` / `CHANGELOG.md` entry instead.)
2548
+ **pnpm specifics**: set `minimumReleaseAge: 20160` (14 days) in `pnpm-workspace.yaml`
2549
+ (pnpm 11 defaults to 1 day), declare lifecycle-eligible packages via `allowBuilds`, keep
2550
+ `blockExoticSubdeps` on, and run `pnpm audit` + `pnpm audit signatures` in CI with
2551
+ `pnpm install --frozen-lockfile`.
2770
2552
 
2771
2553
  * * *
2772
2554
 
@@ -2805,87 +2587,87 @@ move the note to a `README.md` / `CHANGELOG.md` entry instead.)
2805
2587
  ## Best Practices
2806
2588
 
2807
2589
  1. **Follow the 14-day package-age rule** for every dependency install and upgrade.
2808
- See [Supply-Chain Mitigation](#supply-chain-mitigation). Set
2809
- `minimumReleaseAge: 20160` (14 days in minutes) in pnpm config; use
2810
- `ncu --cooldown 14`; declare lifecycle-script-eligible packages via
2811
- `allowBuilds`; run `pnpm audit` and `pnpm audit signatures` in CI; commit
2812
- `pnpm-lock.yaml` and use `pnpm install --frozen-lockfile` in CI.
2590
+ See [Supply-Chain Mitigation](#supply-chain-mitigation).
2591
+ Set `minimumReleaseAge: 20160` (14 days in minutes) in pnpm config; use
2592
+ `ncu --cooldown 14`; declare lifecycle-script-eligible packages via `allowBuilds`;
2593
+ run `pnpm audit` and `pnpm audit signatures` in CI; commit `pnpm-lock.yaml` and use
2594
+ `pnpm install --frozen-lockfile` in CI.
2813
2595
 
2814
2596
  2. **Scope your package names**: Use `@org/package-name` format for easier GitHub
2815
2597
  Packages integration and namespace clarity.
2816
2598
 
2817
- 2. **Structure for splitting**: Organize internal code (`core/`, `cli/`, `adapters/`) to
2599
+ 3. **Structure for splitting**: Organize internal code (`core/`, `cli/`, `adapters/`) to
2818
2600
  make future package splits painless.
2819
2601
 
2820
- 3. **Use subpath exports from day one**: Define `./cli`, `./adapter` exports even in
2602
+ 4. **Use subpath exports from day one**: Define `./cli`, `./adapter` exports even in
2821
2603
  v0.1 to stabilize the API surface.
2822
2604
 
2823
- 4. **Types first in exports**: Always put `"types"` condition before `"default"` in
2605
+ 5. **Types first in exports**: Always put `"types"` condition before `"default"` in
2824
2606
  export conditions.
2825
2607
 
2826
- 5. **Optional peer deps for integrations**: Don’t force SDK dependencies on users who
2608
+ 6. **Optional peer deps for integrations**: Don’t force SDK dependencies on users who
2827
2609
  don’t need them.
2828
2610
 
2829
- 6. **Validate before publish**: Run publint in CI and before every release.
2611
+ 7. **Validate before publish**: Run publint in CI and before every release.
2830
2612
 
2831
- 7. **Changeset per PR**: Require changesets for user-facing changes to maintain accurate
2613
+ 8. **Changeset per PR**: Require changesets for user-facing changes to maintain accurate
2832
2614
  changelogs.
2833
2615
 
2834
- 8. **Lock your tooling versions**: Pin exact versions in `packageManager` field and CI
2616
+ 9. **Lock your tooling versions**: Pin exact versions in `packageManager` field and CI
2835
2617
  configurations.
2836
2618
 
2837
- 9. **Test both ESM and CJS**: Ensure both module formats work correctly, especially for
2838
- CLI tools.
2619
+ 10. **Test both ESM and CJS**: Ensure both module formats work correctly, especially for
2620
+ CLI tools.
2839
2621
 
2840
- 10. **Keep the monorepo root private**: The root `package.json` should have
2622
+ 11. **Keep the monorepo root private**: The root `package.json` should have
2841
2623
  `"private": true` and only contain workspace tooling.
2842
2624
 
2843
- 11. **Use type-aware ESLint**: Configure `recommendedTypeChecked` for comprehensive bug
2625
+ 12. **Use type-aware ESLint**: Configure `recommendedTypeChecked` for comprehensive bug
2844
2626
  detection, especially promise safety rules.
2845
2627
  See Appendix C for detailed configuration.
2846
2628
 
2847
- 12. **Enforce code style consistency**: Use `curly: 'all'` and `brace-style: '1tbs'` to
2629
+ 13. **Enforce code style consistency**: Use `curly: 'all'` and `brace-style: '1tbs'` to
2848
2630
  prevent subtle bugs and improve readability.
2849
2631
 
2850
- 13. **Use fast pre-commit hooks**: Run formatting and linting with auto-fix on staged
2632
+ 14. **Use fast pre-commit hooks**: Run formatting and linting with auto-fix on staged
2851
2633
  files only. Target 2-5 seconds total.
2852
2634
  Use lefthook for better monorepo support.
2853
2635
 
2854
- 14. **Cache test results by commit hash**: In pre-push hooks, skip test runs if the
2636
+ 15. **Cache test results by commit hash**: In pre-push hooks, skip test runs if the
2855
2637
  current commit has already passed tests.
2856
2638
  This makes repeated pushes instant.
2857
2639
 
2858
- 15. **Use structured upgrade scripts**: Add `upgrade:check`, `upgrade`, and
2640
+ 16. **Use structured upgrade scripts**: Add `upgrade:check`, `upgrade`, and
2859
2641
  `upgrade:major` scripts to make dependency updates consistent and safe.
2860
2642
  Separate minor/patch from major upgrades.
2861
2643
 
2862
- 16. **Separate format and lint script variants**: Provide `format`/`format:check` and
2644
+ 17. **Separate format and lint script variants**: Provide `format`/`format:check` and
2863
2645
  `lint`/`lint:check` scripts.
2864
2646
  Use `--fix` variants for local development and `--check`/zero-warnings variants for
2865
2647
  CI.
2866
2648
 
2867
- 17. **Run format before lint in builds**: The `build` script should run `format` then
2649
+ 18. **Run format before lint in builds**: The `build` script should run `format` then
2868
2650
  `lint:check` to ensure formatting is applied before linting.
2869
2651
 
2870
- 18. **Use dynamic git-based versioning**: Inject version at build time using
2652
+ 19. **Use dynamic git-based versioning**: Inject version at build time using
2871
2653
  `X.Y.Z-dev.N.hash` format.
2872
2654
  This provides traceability during development without manual version bumps.
2873
2655
  See “Dynamic Git-Based Versioning” section for implementation.
2874
2656
 
2875
- 19. **Run CLI from source during development**: Use the dual-script pattern with tsx to
2657
+ 20. **Run CLI from source during development**: Use the dual-script pattern with tsx to
2876
2658
  run CLI commands directly from TypeScript source.
2877
2659
  Provide a separate `:bin` script for verifying the built output.
2878
2660
  This eliminates “did I forget to build?”
2879
2661
  confusion.
2880
2662
 
2881
- 20. **Use CJS bootstrap for CLI startup**: Enable Node.js compile cache via a CJS
2663
+ 21. **Use CJS bootstrap for CLI startup**: Enable Node.js compile cache via a CJS
2882
2664
  bootstrap file that runs before ESM module loading.
2883
2665
  This significantly improves repeated CLI invocation times on Node.js 22.8+.
2884
2666
 
2885
- 21. **Bundle CLI dependencies**: Use tsdown’s `noExternal` to bundle runtime deps into
2667
+ 22. **Bundle CLI dependencies**: Use tsdown’s `noExternal` to bundle runtime deps into
2886
2668
  the CLI binary for faster startup (no `node_modules` resolution at runtime).
2887
2669
 
2888
- 22. **Add guard tests for node-free core**: If your library entry point should be
2670
+ 23. **Add guard tests for node-free core**: If your library entry point should be
2889
2671
  node-free, add automated tests that verify no `node:` imports leak into the public
2890
2672
  API surface.
2891
2673
 
@@ -2898,51 +2680,52 @@ move the note to a `README.md` / `CHANGELOG.md` entry instead.)
2898
2680
  Monitor for announcements that may affect best practices.
2899
2681
 
2900
2682
  2. ~~**TypeScript 6.0**~~: **SHIPPED** 2026-03-23 (currently 6.0.3). The last
2901
- JavaScript-based release. `strict: true` is now the default, ESM is the
2902
- default module system, and ~9 compiler settings flipped defaults. Adopt for
2903
- the codebase; review `tsconfig.base.json` for now-redundant flag declarations.
2683
+ JavaScript-based release.
2684
+ `strict: true` is now the default, ESM is the default module system, and ~9 compiler
2685
+ settings flipped defaults.
2686
+ Adopt for the codebase; review `tsconfig.base.json` for now-redundant flag
2687
+ declarations.
2904
2688
 
2905
2689
  3. **TypeScript 7.0 (Project Corsa, Go rewrite)**: Beta shipped 2026-04-21 as
2906
- `@typescript/native-preview` (binary `tsgo`). Claims ~10× type-check speed
2907
- and ~3× less memory; passes 95%+ of the test suite. Available in
2908
- Visual Studio 2026 18.6 Insiders by default. **Do not adopt for production
2909
- builds yet** — wait for stable (expected mid-to-late 2026). Monitor for
2910
- tsdown/Vitest compatibility announcements.
2690
+ `@typescript/native-preview` (binary `tsgo`). Claims ~10× type-check speed and ~3×
2691
+ less memory; passes 95%+ of the test suite.
2692
+ Available in Visual Studio 2026 18.6 Insiders by default.
2693
+ **Do not adopt for production builds yet** — wait for stable (expected mid-to-late
2694
+ 2026). Monitor for tsdown/Vitest compatibility announcements.
2911
2695
 
2912
2696
  4. **Native TypeScript Execution**: TypeScript 5.8+ supports `--erasableSyntaxOnly`,
2913
- enabling direct execution in Node.js 23.6+ without transpilation. With
2914
- TypeScript 6.0 stable and Node 24 LTS, this is increasingly viable for
2915
- scripts. Monitor for broader tooling adoption (linters, coverage tools).
2916
-
2917
- 5. ~~**ESLint v10**~~: **SHIPPED** 2026-02-06. `.eslintrc.*` configuration is
2918
- completely removed — flat config (`eslint.config.js`) is the only supported
2919
- format. Download size reduced 11 MB → 9.4 MB. Minimum Node.js v20.19.0.
2920
- ESLint 9.x EOL is 2026-08-06 — migrate now.
2921
-
2922
- 6. ~~**pnpm 11**~~: **SHIPPED** 2026-04-28 (currently 11.2.2). Breaking changes:
2923
- pure ESM (requires Node 22+), SQLite-based store, `minimumReleaseAge` default
2924
- (1 day), `blockExoticSubdeps` default `true`, `allowBuilds` replacing
2925
- `onlyBuiltDependencies`. Experimental Rust-based `@pnpm/pacquet` engine in
2926
- 11.2+. Migrate via the pnpm 11 migration guide; bump
2927
- `pnpm/action-setup` to v6 in CI.
2928
-
2929
- 7. ~~**Zod 4**~~: **SHIPPED** (currently 4.4.3). 14× faster string parsing,
2930
- faster array parsing, 6. faster object parsing vs Zod 3; core bundle
2931
- 2.3× smaller; new `@zod/mini` (~1.9 KB gzipped) for tree-shakable frontend
2932
- validation. Migration from Zod 3 required — see
2697
+ enabling direct execution in Node.js 23.6+ without transpilation.
2698
+ With TypeScript 6.0 stable and Node 24 LTS, this is increasingly viable for scripts.
2699
+ Monitor for broader tooling adoption (linters, coverage tools).
2700
+
2701
+ 5. ~~**ESLint v10**~~: **SHIPPED** 2026-02-06. `.eslintrc.*` configuration is completely
2702
+ removed — flat config (`eslint.config.js`) is the only supported format.
2703
+ Download size reduced 11 MB → 9.4 MB. Minimum Node.js v20.19.0. ESLint 9.x EOL is
2704
+ 2026-08-06 — migrate now.
2705
+
2706
+ 6. ~~**pnpm 11**~~: **SHIPPED** 2026-04-28 (currently 11.2.2). Breaking changes: pure
2707
+ ESM (requires Node 22+), SQLite-based store, `minimumReleaseAge` default (1 day),
2708
+ `blockExoticSubdeps` default `true`, `allowBuilds` replacing `onlyBuiltDependencies`.
2709
+ Experimental Rust-based `@pnpm/pacquet` engine in 11.2+. Migrate via the pnpm 11
2710
+ migration guide; bump `pnpm/action-setup` to v6 in CI.
2711
+
2712
+ 7. ~~**Zod 4**~~: **SHIPPED** (currently 4.4.3). 14× faster string parsing, 7× faster
2713
+ array parsing, 6. faster object parsing vs Zod 3; core bundle 2.3× smaller; new
2714
+ `@zod/mini` (~1.9 KB gzipped) for tree-shakable frontend validation.
2715
+ Migration from Zod 3 required see
2933
2716
  [zod.dev/v4/changelog](https://zod.dev/v4/changelog).
2934
2717
 
2935
- 8. **Commander 15 (ESM-only)**: Commander 15 ships May 2026, requires
2936
- Node v22.12.0+, drops CJS. Commander 14 moves to maintenance (security
2937
- only) until May 2027. Upgrade path for CLI tools using Commander.
2718
+ 8. **Commander 15 (ESM-only)**: Commander 15 ships May 2026, requires Node v22.12.0+,
2719
+ drops CJS. Commander 14 moves to maintenance (security only) until May 2027. Upgrade
2720
+ path for CLI tools using Commander.
2938
2721
 
2939
- 9. **`dotenv` vs Node `--env-file`**: Node 20.6+ has built-in `--env-file`
2940
- support, and with Node 24 LTS it is production-ready. Most new projects
2941
- should default to `--env-file` and reserve `dotenv` for advanced needs
2942
- (variable expansion, multiline values, custom precedence logic).
2722
+ 9. **`dotenv` vs Node `--env-file`**: Node 20.6+ has built-in `--env-file` support, and
2723
+ with Node 24 LTS it is production-ready.
2724
+ Most new projects should default to `--env-file` and reserve `dotenv` for advanced
2725
+ needs (variable expansion, multiline values, custom precedence logic).
2943
2726
 
2944
- 10. **Vitest 5**: 5.0.0-beta.3 in pre-release; requires Node 22+ and
2945
- Vite 6.4+. Stable not yet shipped. Stay on 4.1.x for now.
2727
+ 10. **Vitest 5**: 5.0.0-beta.3 in pre-release; requires Node 22+ and Vite 6.4+. Stable
2728
+ not yet shipped. Stay on 4.1.x for now.
2946
2729
 
2947
2730
  * * *
2948
2731
 
@@ -3170,8 +2953,8 @@ ready for public release.
3170
2953
  ```
3171
2954
 
3172
2955
  All pinned versions above are ≥14 days old as of 2026-05-21 per the
3173
- [Supply-Chain Mitigation](#supply-chain-mitigation) policy. Newer releases exist
3174
- (`pnpm` 11.2.2, `lefthook` 2.1.8, `npm-check-updates` 22.2.0,
2956
+ [Supply-Chain Mitigation](#supply-chain-mitigation) policy.
2957
+ Newer releases exist (`pnpm` 11.2.2, `lefthook` 2.1.8, `npm-check-updates` 22.2.0,
3175
2958
  `publint` 0.3.21, `vitest` 4.1.7) but were too fresh at this document update.
3176
2959
  Bump on the next refresh once the 14-day window has elapsed.
3177
2960