diff --git a/apps/web/package.json b/apps/web/package.json
index a6076974..49df2eb2 100644
--- a/apps/web/package.json
+++ b/apps/web/package.json
@@ -52,7 +52,7 @@
"playwright": "^1.61.0",
"storybook": "^10.5.5",
"tailwindcss": "^4.1.0",
- "typescript": "^5.6.0",
+ "typescript": "^6.0.3",
"vite": "^7.0.0",
"vitest": "^3.2.7",
"vitest-browser-react": "^1.0.0"
diff --git a/apps/web/tsconfig.json b/apps/web/tsconfig.json
index d070f814..6c2c7975 100644
--- a/apps/web/tsconfig.json
+++ b/apps/web/tsconfig.json
@@ -18,10 +18,11 @@
"verbatimModuleSyntax": true,
"noEmit": true,
"types": ["vite/client", "@vitest/browser/providers/playwright"],
- // Deliberately no `baseUrl` — TypeScript 7 removed it (TS5102). Without it,
- // `paths` values resolve relative to THIS file, which the self-relative
- // "./src/*" below already assumes. Bundler resolution is separate: the "@"
- // alias is declared in vite.config.ts and vitest.config.ts.
+ // Deliberately no `baseUrl` — TypeScript 6 already rejects it (TS5101) and 7
+ // removed it outright (TS5102). Without it, `paths` values resolve relative to
+ // THIS file, which the self-relative "./src/*" below already assumes. Bundler
+ // resolution is separate: the "@" alias is declared in vite.config.ts and
+ // vitest.config.ts.
"paths": {
"@/*": ["./src/*"]
}
diff --git a/bun.lock b/bun.lock
index cbd63b74..2d948957 100644
--- a/bun.lock
+++ b/bun.lock
@@ -17,7 +17,7 @@
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-simple-import-sort": "^13.0.0",
"husky": "^9.1.7",
- "typescript": "^5.9.3",
+ "typescript": "^6.0.3",
"typescript-eslint": "^8.68.0",
"zod": "4.5.4",
},
@@ -89,7 +89,7 @@
"playwright": "^1.61.0",
"storybook": "^10.5.5",
"tailwindcss": "^4.1.0",
- "typescript": "^5.6.0",
+ "typescript": "^6.0.3",
"vite": "^7.0.0",
"vitest": "^3.2.7",
"vitest-browser-react": "^1.0.0",
@@ -127,14 +127,14 @@
"name": "@nightcore/eslint-plugin",
"version": "0.0.0",
"dependencies": {
- "@typescript-eslint/utils": "^8.61.1",
+ "@typescript-eslint/utils": "^8.68.0",
},
"devDependencies": {
"@types/node": "^22.0.0",
- "@typescript-eslint/parser": "^8.61.1",
- "@typescript-eslint/rule-tester": "^8.61.1",
+ "@typescript-eslint/parser": "^8.68.0",
+ "@typescript-eslint/rule-tester": "^8.68.0",
"tsup": "^8.5.1",
- "typescript": "^5.6.0",
+ "typescript": "^6.0.3",
"vitest": "^3.2.7",
},
"peerDependencies": {
@@ -152,7 +152,7 @@
"@types/bun": "^1.1.0",
"@types/node": "^22.0.0",
"tsup": "^8.5.1",
- "typescript": "^5.6.0",
+ "typescript": "^6.0.3",
},
},
"packages/session-fold": {
@@ -2170,7 +2170,7 @@
"typed-array-length": ["typed-array-length@1.0.8", "", { "dependencies": { "call-bind": "^1.0.9", "for-each": "^0.3.5", "gopd": "^1.2.0", "is-typed-array": "^1.1.15", "possible-typed-array-names": "^1.1.0", "reflect.getprototypeof": "^1.0.10" } }, "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g=="],
- "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
+ "typescript": ["typescript@6.0.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-y2TvuxSZPDyQakkFRPZHKFm+KKVqIisdg9/CZwm9ftvKXLP8NRWj38/ODjNbr43SsoXqNuAisEf1GdCxqWcdBw=="],
"typescript-eslint": ["typescript-eslint@8.68.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.68.0", "@typescript-eslint/parser": "8.68.0", "@typescript-eslint/typescript-estree": "8.68.0", "@typescript-eslint/utils": "8.68.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", "typescript": ">=4.8.4 <6.1.0" } }, "sha512-MHy0Y0ynqeEbx/S45+i/bBssdy3X6KNBfmJAP35GrgtNxu2TQ5K5xsFDhAnmsq1jvpdoZOPG1LGtJo0HWqYCrQ=="],
diff --git a/docs/migrations/2026-08-31-typescript.md b/docs/migrations/2026-08-31-typescript.md
new file mode 100644
index 00000000..a2182194
--- /dev/null
+++ b/docs/migrations/2026-08-31-typescript.md
@@ -0,0 +1,140 @@
+# Migration Plan: typescript 5.9.3 -> (retargeted) 6.0.3, NOT 7.0.2
+
+**Date:** 2026-08-31
+**Agent:** kirei-migrate
+**Base branch:** `deps/phase-1-safe-bumps` (PR #465, open) — plan stacks on this branch's already-refreshed `bun.lock`. Do NOT plan against `main`.
+**Target:** `typescript` `5.9.3` -> `6.0.3` (recommended, do now) — **`7.0.2` explicitly deferred, not recommended today**
+**Supersedes / relationship to Dependabot PR #418:** PR #418 proposes `5.9.3 -> 7.0.2` directly. Left untouched per instructions. This plan does **not** adopt it — see "Why not 7.0.2" below. PR #418's own CI is empirical confirmation of the blocker (see below).
+**Migration guides read:** TypeScript 6.0 announcement (devblogs.microsoft.com/typescript/announcing-typescript-6-0), TypeScript 6.0 release notes (typescriptlang.org/docs/handbook/release-notes/typescript-6-0.html), TypeScript 7.0 GA coverage (InfoQ 2026-08, Visual Studio Magazine 2026-06-22 RC coverage), typescript-eslint issue #12518 ("TypeScript 7.0.2 Support", closed not-planned), typescript-eslint issue #12123 ("TypeScript 6 Support").
+
+## Summary
+
+**Do not adopt Dependabot PR #418 (typescript 7.0.2) yet.** TypeScript 7.0 is the GA native/Go-ported compiler (shipped under the `typescript` npm package itself at major version 7, not a separate `@typescript/native-preview` package — that preview package still exists separately and is unrelated). It ships **with no classic programmatic Compiler API**: the package's root export `"."` now points at `./lib/version.cjs` (verified by unpacking the real npm tarball), which contains only:
+```js
+const { version } = require("../package.json");
+exports.version = version;
+exports.versionMajorMinor = "7.0";
+```
+Compare TypeScript 5.9.3 / 6.0.3, whose root export is `./lib/typescript.js` — the full `ts.createProgram`/`ts.createSourceFile`/`ts.SyntaxKind`/checker API. TS 7.0.2 replaces that with a new, explicitly `unstable/*`-namespaced, async/sync JSON-RPC client API (vendored `vscode-jsonrpc`) that talks to the native `tsgo` binary — a different architecture entirely, not a superset.
+
+This is fatal for this repo today because:
+1. **`typescript-eslint` (all 8.x releases through the current latest, `8.68.0`, checked live via npm on 2026-08-31) hard-excludes TypeScript 7** via peer dependency `"typescript": ">=4.8.4 <6.1.0"` on every sub-package (`typescript-eslint`, `@typescript-eslint/parser`, `@typescript-eslint/utils`, `@typescript-eslint/rule-tester`, `@typescript-eslint/typescript-estree`). A GitHub issue asking for 7.0.2 support (typescript-eslint#12518, opened GA day) was **closed as "not planned."** `eslint.config.mjs` imports `typescript-eslint` (`tseslint`) and applies it across effectively every `.ts`/`.tsx` file in the repo — so `bun run lint` (root `eslint .`) breaks repo-wide, not just at a few call sites.
+2. **This repo's own codegen has a first-party, concrete call site that hard-crashes under TS 7**: `tools/codegen/gen-settings-scope.ts:40` does `import ts from 'typescript'` and then calls `ts.createSourceFile`, `ts.ScriptTarget.Latest`, `ts.isTypeAliasDeclaration`, `ts.isTypeLiteralNode`, `ts.isPropertySignature`, `ts.isIdentifier` — none of which exist on the TS 7.0.2 root export. Under TS 7 this throws `TypeError: ts.createSourceFile is not a function` the moment `bun run codegen:settings-scope` (or `codegen:check`, which chains it) runs.
+3. `tsup --dts` (used by `packages/eslint-plugin` and `packages/harness` builds, `bun run lint:plugin`) plausibly depends on the classic Compiler API for declaration-file generation. tsup's own peer range (`typescript: ">=4.5.0"`) does nothing to protect against this — unverified in a live run, but a real additional risk on top of (1) and (2).
+4. **Empirical confirmation**: PR #418's own CI (`gh pr checks 418`) is already red — `lint · typecheck · test (Bun workspace)` **fails**, `proof` **fails**, `vitest browser coverage (apps/web)` **fails** — exactly the blast radius predicted by (1). Rust jobs pass (Rust doesn't touch the JS `typescript` package).
+5. The ecosystem itself isn't ready: Microsoft ships a separate `@typescript/typescript6` compat shim (wraps `typescript@^6` under a `tsc6` binary, `npmjs.com/package/@typescript/typescript6`) specifically so tools that still need the classic API can keep working while `tsc` itself moves to 7 — an industry-wide acknowledgment that tools like ESLint aren't ready yet, not a nightcore-specific gap.
+6. TypeScript 7.1 (expected to restore a *stable* programmatic API) has **not shipped as stable** as of this research (2026-08-31): `npm view typescript dist-tags` shows only prerelease builds (`next: 7.1.0-dev.20260831.1`), no `7.1.0` GA tag. Even once it ships, typescript-eslint would need its own follow-up release adopting the new API shape (a rewrite of `@typescript-eslint/typescript-estree`'s AST-conversion layer against an async/sync RPC client instead of an in-process object graph) — not a quick peer-range widening.
+
+**Recommended target for this migration: TypeScript `6.0.3`** — the final and only stable point release on the 6.x line (versions on npm: `6.0.0-beta`, `6.0.1-rc`, `6.0.2`, `6.0.3`, then straight to `7.0.1-rc`/`7.0.2` — there is no 6.1, 6.2, etc.; 6.x was explicitly a short transitional major to surface 7.0's deprecations as warnings first). TS 6.0.3:
+- **Is inside typescript-eslint's supported peer range** (`>=4.8.4 <6.1.0`) — confirmed via live npm peer-dependency check against both the currently-locked `8.61.1` and the latest `8.68.0`. No typescript-eslint bump is *required* to move to 6.0.3.
+- **Still ships the classic Compiler API** (`lib/typescript.js`, verified by unpacking the real 6.0.3 tarball) — `gen-settings-scope.ts` and `tsup --dts` keep working unmodified.
+- Gets most of the practical benefit of "moving off 5.9.3" (current deprecation warnings, `--stableTypeOrdering`, TC39 stage-4 lib types) without the ecosystem cliff.
+- This repo's tsconfigs are already unusually well-aligned with TS 6's new defaults (see Breaking Changes table) — the actual mechanical footprint is one config line.
+
+This is a **single-PR, mechanical + one small behavioral-verification pass** migration — not a multi-week effort. The riskiest item is a new default (`noUncheckedSideEffectImports: true`) that needs an actual `tsc -b` run to confirm it doesn't surface latent side-effect-import errors, not a design risk.
+
+## Pre-flight Requirements
+
+- Runtime: no change. `engines.node: ">=22"` in root `package.json` already exceeds TS 6.0.3's own requirement (`node >=14.17`) and TS 7.0.2's (`node >=16.20.0`) — not a blocker either way.
+- Peer deps: none need bumping to move to 6.0.3 (typescript-eslint 8.61.1, already locked, already covers `<6.1.0`).
+- Base branch state: must build on `deps/phase-1-safe-bumps` (PR #465)'s `bun.lock`, not `main`'s. Verify `git merge-base` / branch-off point before starting execution.
+
+## Breaking Changes & Call Sites (TypeScript 6.0, vs. current 5.9.3)
+
+### BC-1 — `baseUrl` deprecated as a module-resolution lookup root
+**Type:** Structural (config), trivially mechanical fix
+**What changed:** "In TypeScript 6.0, `baseUrl` is deprecated and will no longer be considered a look-up root for module resolution." (6.0 emits a warning; full removal lands in 7.0.)
+**Call site:** `apps/web/tsconfig.json` — sets `"baseUrl": "."` alongside `"paths": { "@/*": ["./src/*"] }`.
+**Fix:** Delete the `"baseUrl": "."` line, keep `paths` as-is. Under `"moduleResolution": "bundler"` (already set here), `paths` resolves relative to the tsconfig file's own directory without needing `baseUrl` — and `baseUrl` was already `"."` (the tsconfig's own directory), so this is behavior-neutral, not a real remap.
+**No other tsconfig in the repo sets `baseUrl`** (checked all 12: `tsconfig.base.json`, `apps/{docs,sidecar,web}/tsconfig.json`, `packages/{config,contracts,engine,eslint-plugin,harness,session-fold,shared,storage}/tsconfig.json`).
+
+### BC-2 — New default: `noUncheckedSideEffectImports: true`
+**Type:** Behavioral — genuinely needs a real `tsc -b` run, not just a read
+**What changed:** TS 6.0 flips this default from `false` to `true`. It flags side-effect-only imports (`import './foo'`) where TypeScript can't resolve any matching declaration for the target module.
+**Call sites:** Not enumerable by grep alone — this is a compiler-wide behavioral check across every side-effect import in `apps/web` (CSS imports, polyfill-style imports) and any Node-side package. `apps/web/tsconfig.json` already includes `"types": ["vite/client", ...]`, which should declare `*.css`/asset side-effect imports correctly, but this must be confirmed by actually running the typecheck, not assumed from reading config.
+**Fix:** Run `bunx tsc -b apps/web` and root `bun run typecheck` after the bump; if new errors appear here, they are either (a) legitimate typos/dead imports worth fixing, or (b) need a per-file `// @ts-expect-error` / ambient `.d.ts` declaration for a genuinely side-effect-only import with no types (e.g. some CSS-in-JS or global polyfill). Do not blanket-disable the flag without inspecting what it caught — this is exactly the class of check the option exists to add.
+
+### BC-3 — Other TS 6.0 hard removals / deprecations — checked, **none apply**
+Grepped the whole JS/TS tree (`apps`, `packages`, `tools`, `scripts`) for every item on the 6.0 removal/deprecation list:
+- `moduleResolution: classic` / `node` (node10) — repo uses `bundler` everywhere. Not present.
+- `module: amd/umd/systemjs/none` — repo uses `ESNext` everywhere. Not present.
+- `outFile` — not set anywhere.
+- Legacy `module Foo {}` namespace syntax — no matches.
+- Old import-assertion syntax (`assert { type: ... }`) — no matches (repo uses `verbatimModuleSyntax: true`, would already require the modern `with` keyword if this pattern existed).
+- `/// ` — no matches.
+- `tsc ` invocation style that now errors when a `tsconfig.json` is present — every `package.json` script uses `tsc -b` or bare `tsc --noEmit` (reads the config, no stray file args). Not present.
+- `downlevelIteration` — not set anywhere.
+- `esModuleInterop: false` / `allowSyntheticDefaultImports: false` (can no longer be set to `false`) — repo already sets both `true` explicitly in `tsconfig.base.json`. Already aligned.
+- `alwaysStrict: false` (no longer settable) — repo sets `strict: true` everywhere (implies `alwaysStrict: true`). Already aligned.
+- `strict`/`module`/`target`/`types` default flips — repo already explicitly sets `strict: true`, `module: "ESNext"`, `target: "ES2022"`, and an explicit `types: [...]` array in every workspace tsconfig (or `types: []` in `packages/session-fold`). The new TS 6.0 defaults for all of these already match what the repo has hand-set — zero default-reliance risk.
+- `rootDir` default change (now defaults to the tsconfig's own directory instead of being inferred from included files) — every package with `outDir`/emit sets `rootDir: "src"` explicitly already. `apps/web`, `packages/eslint-plugin`, `packages/harness` don't set `rootDir`, but all three have `noEmit: true` (or no `outDir`), so the new default has no observable effect (nothing is emitted based on it).
+
+## Interaction With CI Gates
+
+| Gate | Risk | Why |
+|---|---|---|
+| `bun run typecheck` (root `tsc -b`) | Low, but must actually run | BC-1/BC-2 above are the only live risk; project references / `--build`/incremental mode are unaffected by TS 6.0 per the release notes ("API Stability Notes" section makes no mention of project-reference changes). |
+| `bunx tsc -b packages/engine`, `bunx tsc -b apps/web` (explicit extra CI steps in `.github/workflows/ci.yml`, `bun-checks` and `rust-checks` jobs) | Low | Same as above — these are the exact commands that will surface BC-2 if it fires. |
+| `bun run lint` (`eslint .` via `typescript-eslint`) | **This is the one that matters** | Confirmed compatible: `typescript-eslint@8.61.1` (currently locked) already declares `typescript: ">=4.8.4 <6.1.0"` — 6.0.3 is inside range. No version bump strictly required, but see the typescript-eslint companion-bump recommendation below for why to do one anyway. |
+| `lint:meta` (`tools/lint-meta`, Bun-based custom rule runner) | None | Confirmed: no rule in `tools/lint-meta/rules/*.ts` imports `typescript` or `typescript-eslint` directly; the one codegen-sensitive rule (`codegen-drift.ts`) only shells out to `gen-rust-contracts.ts` (zod-only, no TS Compiler API — see codegen section below). |
+| `test:node` / `test:web` / `test:plugin` | Low | None of vitest, `@vitest/browser`, or `vitest-browser-react`'s TS handling goes through the `typescript` package's Compiler API for transforms (esbuild/oxc-based); `packages/eslint-plugin`'s `test:plugin` uses `@typescript-eslint/rule-tester`, covered by the typescript-eslint compatibility check above. |
+| `test:rust` / `cargo test` (ts-rs emit) | None | `ts-rs` is a Rust crate (`Cargo.toml: ts-rs = "12.0"`) that emits `.ts` binding files as plain text from Rust — it has zero dependency on the npm `typescript` package. Verified by `cargo test` regenerating bindings independent of the JS toolchain. |
+| File-size ratchet (`web-file-size-ratchet.ts`, `engine-file-size-ratchet.ts` in `lint:meta`) | None | Pure line-count rules over committed files; unrelated to the compiler version. |
+
+## Interaction With the Two-Way Codegen (zod<->Rust, ts-rs->TS)
+
+- **zod -> Rust** (`tools/codegen/gen-rust-contracts.ts`, gated by `lint:meta`'s `codegen-drift` rule, CI-critical): imports only `zod` + Node builtins. **Zero interaction** with the `typescript` package at any version.
+- **Rust -> TS via ts-rs** (`cargo test` regenerates `.ts` binding files under `apps/web/src/lib/generated/`, gated by `verify:drift-guard` in the Rust CI job): pure Rust-side codegen emitting text. **Zero interaction** with the npm `typescript` package.
+- **The one real interaction point**: `tools/codegen/gen-settings-scope.ts` (`bun run codegen:settings-scope`, chained inside `bun run codegen:check` as its 3rd step) *parses* the ts-rs-generated `SettingsOverride.ts` binding using the TypeScript Compiler API (`ts.createSourceFile` etc.) to derive the per-project-overridable settings keys. This is the concrete BC-2/TS-7-blocker call site described above.
+ - **Under the recommended TS 6.0.3 target: unaffected**, classic API still present.
+ - **Side note, not part of this migration's scope**: `codegen:check` (and therefore `gen-settings-scope.ts --check`) is **not currently wired into any CI job, `lint:meta` rule, or husky hook** — checked `.github/workflows/*.yml`, `tools/lint-meta/rules/*.ts`, `.husky/pre-commit`, `.husky/pre-push`, `scripts/check-rust.ts`, `scripts/verify-drift-guard.ts`. It's a manually-run generator today. This means a future TS 7 attempt wouldn't fail CI here — it would fail silently (a developer's local `bun run codegen:settings-scope` run throwing a `TypeError`) instead. Worth a follow-up ticket to wire `codegen:settings-scope --check` into `lint:meta` regardless of the TS version question, but that's out of scope for this migration.
+
+## Companion Bump: typescript-eslint / `@typescript-eslint/*`
+
+**What the new TypeScript (6.0.3) requires:** nothing — `typescript-eslint@8.61.1` (currently locked via the bounded override `@typescript-eslint/utils: ">=8.61.1 <8.62.0"` in root `package.json`) already declares peer support for `typescript: ">=4.8.4 <6.1.0"`, which covers 6.0.3.
+
+**What this migration should still do, to satisfy the stated goal of removing the override:** The override was added in the immediately-preceding commit (`07388dfa`, current HEAD of `deps/phase-1-safe-bumps`) as **deliberate scope-holding**, not a TS-compatibility guard — its own commit message says it's "held at 8.61.1 via a bounded override, matching the report's own Phase 2 entry for this exact transition," referring to `docs/deps/2026-08-31-dependency-upgrade-plan.md`'s Phase 2 entry: `@typescript-eslint/utils / parser / rule-tester: 8.61.1 -> 8.68.0 minor ... run bun run lint, bun run lint:meta, and bun run test:plugin explicitly`. That Phase 2 bump was deferred, not blocked.
+
+Since this TypeScript migration already requires a full `bun run lint` / `lint:meta` / `test:plugin` re-verification pass anyway, it is the natural vehicle to complete that deferred Phase 2 bump **in the same PR**, and then delete the override:
+1. Bump `@typescript-eslint/utils` (root override target + `packages/eslint-plugin` dependency), `@typescript-eslint/parser`, `@typescript-eslint/rule-tester` (both `packages/eslint-plugin` devDependencies) from `8.61.1` -> `8.68.0` (latest as of 2026-08-31; same peer range `>=4.8.4 <6.1.0`, confirmed compatible with the new TS 6.0.3).
+2. Bump root `typescript-eslint` (the flat-config meta-package, currently `^8.0.0`/locked `8.61.1`) to `^8.68.0` / `8.68.0` to match.
+3. Delete the `"@typescript-eslint/utils": ">=8.61.1 <8.62.0"` line from root `package.json`'s `overrides` block entirely — its scope-holding purpose is now fulfilled by an actual reviewed+verified bump, not a version freeze.
+4. Verify explicitly: `bun run lint` (full `eslint .`), `bun run lint:meta`, `bun run test:plugin` (the `@typescript-eslint/rule-tester`-based suite in `packages/eslint-plugin`) — these are the exact three checks the dependency-upgrade-plan doc already prescribed for this bump, independent of the TypeScript version question.
+
+**`@eslint/js` — confirmed NOT interacting with this migration.** It supplies base *JavaScript* recommended-rule configs (`js.configs.recommended` in `eslint.config.mjs`), which is orthogonal to `typescript-eslint`'s TypeScript-specific parser/rules. Its own drift (`^9.0.0` pinned while `eslint` itself is on v10) is a pre-existing, unrelated Phase-4 backlog item from the dependency-upgrade-plan doc — leave untouched here to keep this PR's diff scoped to the TypeScript transition.
+
+**Other `@types/*` / runners:** `@types/node`, `@types/bun` need no change (declaration-only packages, not TS-Compiler-API-version-sensitive across a single major). `tsup@8.5.1`'s own peer (`typescript: ">=4.5.0"`) is permissive and does not need a bump for 6.0.3 (it still gets the classic API). `vitest@3.2.7` has no direct `typescript` peer dependency at all (TS transform is esbuild/oxc-based, not through the `typescript` package) — no change needed.
+
+## Codemods Available
+
+None. TypeScript itself does not publish a codemod for the 5.x -> 6.0 transition (it's a config-and-defaults release, not an API-rename release); the one concrete fix (BC-1, dropping `baseUrl`) is a one-line manual edit, not codemod-worthy. TypeScript does ship `"ignoreDeprecations": "6.0"` as an escape hatch to silence 6.0's own deprecation warnings temporarily, but this repo doesn't need it — checked all tsconfigs, none carry a pre-existing `ignoreDeprecations` entry, and the one live deprecation (BC-1) has a real fix available immediately rather than a reason to suppress.
+
+## Upgrade Order
+
+1. Confirm branch base: work on top of `deps/phase-1-safe-bumps` (PR #465)'s current `bun.lock` state — do not rebase onto `main`'s older lockfile.
+2. Edit `apps/web/tsconfig.json`: remove `"baseUrl": "."` (BC-1). Keep `paths` unchanged.
+3. Bump `typescript` `^5.9.3` -> `^6.0.3` (or an exact `6.0.3` pin, matching the repo's existing pin style for `zod`) in the 4 manifests that declare it directly: root `package.json`, `apps/web/package.json`, `packages/eslint-plugin/package.json`, `packages/harness/package.json`.
+4. In the same PR: bump `@typescript-eslint/utils`, `@typescript-eslint/parser`, `@typescript-eslint/rule-tester` (`packages/eslint-plugin`) and root `typescript-eslint` to `8.68.0`; delete the `@typescript-eslint/utils` override from root `package.json`.
+5. `bun install` to refresh `bun.lock` against the above (single lockfile-affecting step covering both the TS bump and the typescript-eslint bump together, since they're interdependent — a partial lockfile refresh risks resolving them out of sync).
+6. Run, in this order, and fix forward on any red before proceeding to the next: `bun run typecheck` (root `tsc -b`) -> `bunx tsc -b packages/engine` -> `bunx tsc -b apps/web` -> `bun run lint` (includes the eslint-plugin `tsup --dts` build + `eslint .` + `lint:meta`) -> `bun run test:node` -> `bun run test:web` -> `bun run test:plugin` -> `bun run test:rust`.
+7. Manually pay closest attention to whatever `tsc -b apps/web` reports for BC-2 (`noUncheckedSideEffectImports`) — this is the one genuinely behavioral item, everything else in this plan is mechanical or already a non-issue.
+8. Do not touch Dependabot PR #418 (per instructions) — once this PR merges, Dependabot will likely re-diff its own PR against the new `6.0.3` base; leave that to happen naturally.
+
+## Verification
+
+- `bun run typecheck`, `bunx tsc -b packages/engine`, `bunx tsc -b apps/web` all clean.
+- `bun run lint` clean (eslint-plugin build + `eslint .` + `lint:meta`).
+- `bun run test:node`, `bun run test:web` (both vitest projects, including the browser project — watch for the documented mid-run dep-optimize hang trap, `reference_web_coverage_ci_freeze`, though that's a Vite/Vitest-version issue, not expected to be triggered by this TS-only bump), `bun run test:plugin`, `bun run test:rust` all green.
+- `bun run codegen:check` (manual, not CI-wired today) — run once by hand post-bump as a sanity check on `gen-settings-scope.ts`'s Compiler API usage, since this migration is exactly the kind of change that should re-touch it even though nothing currently gates it.
+- `bun run audit` still exits clean (a `typescript`/`typescript-eslint` bump is not expected to introduce new advisories, but this repo's audit gate is presently sensitive per the sibling `docs/deps/2026-08-31-dependency-upgrade-plan.md` report — worth a quick re-check since it touches `bun.lock`).
+
+## Rollback
+
+Land as its own PR stacked on `deps/phase-1-safe-bumps` (PR #465). This is a dev-tooling-only change set (typescript + typescript-eslint devDependencies, one tsconfig line, `bun.lock`) with zero production runtime code touched — rollback is a plain `git revert` of the merge commit, no data/state/migration concerns, no feature flags needed. If `bunx tsc -b apps/web` surfaces a large, unexpected `noUncheckedSideEffectImports` blast radius, the fallback is to set `"noUncheckedSideEffectImports": false` explicitly in the affected tsconfig(s) as a scoped opt-out rather than aborting the whole bump — that flag is independently toggleable and doesn't require reverting the TypeScript version itself.
+
+## Out of Scope
+
+- **TypeScript 7.0.2 (Dependabot PR #418 as filed).** Explicitly deferred — see Summary. Revisit only after both (a) TypeScript 7.1 ships stable with a restored programmatic API (not yet, only dev prereleases as of 2026-08-31), and (b) typescript-eslint ships an explicit release supporting it (currently closed not-planned on issue #12518 — watch that issue, not a date). This is a "don't do this yet" outcome for the 7.x jump specifically, not for the TypeScript package in general.
+- Wiring `codegen:settings-scope --check` into CI/`lint:meta` — a real, independently-worthwhile gap noted above, but orthogonal to this version bump.
+- The `@eslint/js` `^9.0.0` -> `^10.0.0` alignment — pre-existing, unrelated Phase-4 backlog item; confirmed no interaction with this migration.
+- Any other Phase 2/3 items from `docs/deps/2026-08-31-dependency-upgrade-plan.md` (dompurify, tauri-plugin-updater, shiki, vitest 4, vite 8, storybook 10, marked, motion, claude-agent-sdk, codex-sdk) — separate migrations, not touched here.
diff --git a/package.json b/package.json
index 7a2c457a..15c95111 100644
--- a/package.json
+++ b/package.json
@@ -67,7 +67,7 @@
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-simple-import-sort": "^13.0.0",
"husky": "^9.1.7",
- "typescript": "^5.9.3",
+ "typescript": "^6.0.3",
"typescript-eslint": "^8.68.0",
"zod": "4.5.4"
},
diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json
index 5dfec0fc..55fcbf1c 100644
--- a/packages/eslint-plugin/package.json
+++ b/packages/eslint-plugin/package.json
@@ -21,14 +21,14 @@
"test:watch": "vitest"
},
"dependencies": {
- "@typescript-eslint/utils": "^8.61.1"
+ "@typescript-eslint/utils": "^8.68.0"
},
"devDependencies": {
"@types/node": "^22.0.0",
- "@typescript-eslint/parser": "^8.61.1",
- "@typescript-eslint/rule-tester": "^8.61.1",
+ "@typescript-eslint/parser": "^8.68.0",
+ "@typescript-eslint/rule-tester": "^8.68.0",
"tsup": "^8.5.1",
- "typescript": "^5.6.0",
+ "typescript": "^6.0.3",
"vitest": "^3.2.7"
},
"peerDependencies": {
diff --git a/packages/eslint-plugin/tsconfig.json b/packages/eslint-plugin/tsconfig.json
index 03219c76..c4846887 100644
--- a/packages/eslint-plugin/tsconfig.json
+++ b/packages/eslint-plugin/tsconfig.json
@@ -1,6 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
+ // tsup 8.5.1's --dts build unconditionally injects `baseUrl: compilerOptions.baseUrl || "."`
+ // (tsup/dist/rollup.js), which TS 6 rejects with TS5101. No tsconfig here sets baseUrl.
+ // Drop this once tsup stops injecting it.
+ "ignoreDeprecations": "6.0",
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": true,
diff --git a/packages/harness/package.json b/packages/harness/package.json
index b78badfc..539a0f3e 100644
--- a/packages/harness/package.json
+++ b/packages/harness/package.json
@@ -47,6 +47,6 @@
"@types/bun": "^1.1.0",
"@types/node": "^22.0.0",
"tsup": "^8.5.1",
- "typescript": "^5.6.0"
+ "typescript": "^6.0.3"
}
}
diff --git a/packages/harness/tsconfig.json b/packages/harness/tsconfig.json
index 5d162644..75113288 100644
--- a/packages/harness/tsconfig.json
+++ b/packages/harness/tsconfig.json
@@ -1,6 +1,10 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
+ // tsup 8.5.1's --dts build unconditionally injects `baseUrl: compilerOptions.baseUrl || "."`
+ // (tsup/dist/rollup.js), which TS 6 rejects with TS5101. No tsconfig here sets baseUrl.
+ // Drop this once tsup stops injecting it.
+ "ignoreDeprecations": "6.0",
"module": "ESNext",
"moduleResolution": "bundler",
"noEmit": true,