diff --git a/docs/adr/0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md b/docs/adr/0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md index 0b83b91d..ca1712d4 100644 --- a/docs/adr/0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md +++ b/docs/adr/0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md @@ -1,5 +1,5 @@ --- -status: accepted, partly superseded by ADR-0055 (pnpm installs and runs the scripts, Vite+ runs the tasks instead of Turborepo, and type-aware lint runs on Vite+'s bundled tsgolint instead of tsrslint; tsrs still typechecks) +status: accepted, partly superseded by ADR-0055 (pnpm installs and runs the scripts, Vite+ runs the tasks instead of Turborepo, and tsrs's own linter replaces tsrslint as the type-aware lint backend, through a pnpm override instead of `scripts/link-tsrslint.sh`; tsrs still typechecks) --- # Bun installs and runs scripts, tsrs typechecks, and Vitest stays on Node diff --git a/docs/adr/0055-vite-plus-and-pnpm.md b/docs/adr/0055-vite-plus-and-pnpm.md index 4606fe12..c7479ac5 100644 --- a/docs/adr/0055-vite-plus-and-pnpm.md +++ b/docs/adr/0055-vite-plus-and-pnpm.md @@ -4,24 +4,24 @@ status: accepted # pnpm installs, and Vite+ checks, lints, formats and runs the tasks -The repo installs with pnpm again, and its toolchain is Vite+ (`vite-plus`): `vp check` formats, lints and runs the type-aware lint once at the root, `vp run` runs every package's tasks and caches them, and `vp staged` with `.vite-hooks/` replaces lint-staged and Husky. This replaces [ADR-0028](0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md)'s Bun, Turborepo and tsrslint; each package's typecheck stays `effect-tsgo tsrs`, for the Effect diagnostics that `vp check`'s type-check does not run. +The repo installs with pnpm again, and its toolchain is Vite+ (`vite-plus`): `vp check` formats, lints and runs the type-aware lint (on tsrs's linter) once at the root, `vp run` runs every package's tasks and caches them, and `vp staged` with `.vite-hooks/` replaces lint-staged and Husky. This replaces [ADR-0028](0028-bun-for-installs-and-scripts-and-tsrs-for-typecheck.md)'s Bun and Turborepo, and `scripts/link-tsrslint.sh`, which made tsrslint oxlint's type-aware backend; each package's typecheck stays `effect-tsgo tsrs`, for the Effect diagnostics that `vp check`'s type-check does not run. - **pnpm** (`packageManager`, `mise.toml`): `pnpm-workspace.yaml` holds the workspace, the patched dependencies, the packages allowed to run install scripts (`allowBuilds`: the pnpm list from before ADR-0028, with `core-js-pure` still blocked and `just-bash`'s optional compressors now blocked too, as ADR-0028 found they serve only its Node command line; `typescript`, which Bun had to trust for the effect-tsgo patch, needs no entry under pnpm) and the exemptions from pnpm's default minimum release age of a day. Workspace dependencies stay plain `"*"` for npm's production install of the root (`pi install git:…`), so `linkWorkspacePackages` links them. `dedupePeers` tells peer variants apart by their peers' versions alone: without it the server had two `@cloudflare/computer`s, and `infra` two `alchemy`s (one per `ws`, which an override now holds at one version), and their typechecks failed. - **One config** (`vite.config.ts` at the root): the lint rules, the anti-slop plugins and every package's own rules (as `lint.overrides` by path; Vite+ reads no nested lint or format config), the format settings and the staged-file rules. `vp check` runs at the root, not per package: it lints the whole repo in one process. - **Tasks** (`packages/config/src/tasks.ts`, passed to `run.tasks` by each package's `vite.config.ts`): `typecheck` and `test`. Vite Task records the files each task reads and replays a task none of whose inputs changed, so a change to a package's source reruns its dependents' tasks without Turborepo's `transit` node or `apps/web/turbo.json`'s hand-listed inputs. A cached task runs in a clean environment, so `test` names the variables that change what a test checks (`CI`, the live tests' and benchmarks' switches, `UPDATE_SNAPSHOT`) and passes the rest through untracked. `test` is `vitest run`, not `vp test`: Vite Task runs a `vp test` inside the `vp` that started it, with that copy's Vitest, and a `vp` that is not the project's (mise's `npm:vite-plus`) gives the workerd projects a second Vitest, which `@cloudflare/vitest-plugin`'s worker cannot reach. -- **Versions**: `vite-plus` 1.4.0, the last release that bundles Vitest 5.0.5; 1.5 and 1.6 bundle 5.1, under which the workerd tests fail (docs/development/dependencies.md). Overrides make every `vite` Vite+'s core and every `vitest` 5.0.5. Vite+ 1.4.0 bundles oxlint 1.89, oxfmt 0.74 and tsgolint 7.0.2004, older than the 1.91, 0.76 and tsrslint they replace; oxfmt 0.74 wraps three signatures differently, reformatted with the switch. +- **Versions**: `vite-plus` 1.4.0, the last release that bundles Vitest 5.0.5; 1.5 and 1.6 bundle 5.1, under which the workerd tests fail (docs/development/dependencies.md). Overrides make every `vite` Vite+'s core and every `vitest` 5.0.5. Vite+ 1.4.0 bundles oxlint 1.89 and oxfmt 0.74, older than the 1.91 and 0.76 they replace (tsrs's linter, which speaks tsgolint 7.0.2005's protocol, runs under 1.89); oxfmt 0.74 wraps three signatures differently, reformatted with the switch. - **CI** sets up with `voidzero-dev/setup-vp`, which installs the Vite+ of the root `package.json` (so its `vp` runs the project's copy), Node and pnpm, and caches pnpm's store. Each check part restores and saves its Vite Task cache (`node_modules/.vite/task-cache`) under a rolling key and clears it past 1 GiB, since Vite Task never evicts. Measured on an 8-core Apple Silicon laptop (2026-11-12), warm caches: -- **Lint**: `vp lint` over the whole repo, type-aware with type-check, 16 s wall, 48 s of CPU, 3.6 GB peak memory (ADR-0028's tsrslint, one package after another: 18–24 s, 19 s, 0.47 GB). +- **Lint**: `vp lint` over the whole repo, type-aware with type-check, on tsrs 0.24's linter: 7–8 s wall, 15 s of CPU, 0.9–1.0 GB peak memory (two runs); on tsrslint 0.1.6: 9–10 s, 13–14 s, 1.5–2.1 GB; on Vite+'s own tsgolint 7.0.2004: 16 s, 48 s, 3.6 GB (ADR-0028's tsrslint, one package after another: 18–24 s, 19 s, 0.47 GB). - **Typecheck**: `vp run -r typecheck`, 7–11 s uncached; 0.9 s when every task replays. - **Tests**: `vp run -r test`, 4 min uncached; 1 min when only the tasks that modify their own inputs (`@cloudpid/mcp`'s import-rule test plants files) and `@cloudpid/sandbox-image`'s, which is uncached, run again. - **Install** with a warm store and no `node_modules`, `prepare` included: 5.1 s wall, 1.1 s of user CPU (ADR-0028: Bun 0.85 s, pnpm 2.4 s, before `prepare`'s `vp config`). ## Consequences -- The type-aware lint is tsgolint again, not tsrslint: Vite+ sets `OXLINT_TSGOLINT_PATH` to its own `oxlint-tsgolint` and ignores `node_modules/.bin/tsgolint`. It takes more memory than tsrslint in one process, but runs once rather than per package. `scripts/link-tsrslint.sh` and `@maschwenk/tsrslint` are gone. +- The type-aware lint runs on tsrs's own linter (`tsrs-lint`, `tsrs --lint`, since tsrs 0.21: tsgolint's headless protocol and its 61 type-aware rules), which replaces tsrslint, its predecessor outside tsrs. Vite+ sets `OXLINT_TSGOLINT_PATH` to the `bin/tsgolint` of its own `oxlint-tsgolint` and ignores `node_modules/.bin`, so `scripts/link-tsrslint.sh` is gone, and a pnpm override makes `oxlint-tsgolint` the repo's `tools/tsrs-lint-shim`, whose `bin/tsgolint.js` loads the root `tsrs` package's `tsrs-lint`. It rests on where Vite+ looks for its backend (docs/development/dependencies.md says what to check on an upgrade). The shim has no `package.json`, or `effect-tsgo patch` finds it as Vite+'s `oxlint-tsgolint` and fails `prepare` looking for tsgolint's platform binary. The `tsrs` package is the linter only: `effect-tsgo tsrs` typechecks with the Effect-patched tsrs that `@effect/tsgo` ships. It goes once `effect-tsgo --tsrs-lint vp lint` (`@effect/tsgo` 0.68 and later: Vite+'s lint on the Effect-patched tsrs, with the Effect rules, and no shim) can run, which needs oxlint 1.91 or later, so a Vite+ past 1.4.0 (`Versions`). The shim does not run on Windows, where Vite+ looks for `tsgolint.exe` or `tsgolint.cmd` in `.bin`, not the `.js` the shim is; tsrs itself ships for macOS, Linux (glibc and musl) and Windows. - Run the project's own `vp`: `pnpm exec vp`, the root scripts, or the standalone global CLI from vite.plus, which hands a command to the project's copy. mise's `npm:vite-plus` is a second copy of the whole toolchain. - Turborepo's CI pruning is gone; the Vite Task cache is experimental in CI (Vite+'s docs say so) and is bounded by size instead. - On macOS, Vite Task runs a cached task's system coreutils as uutils' to record what it reads. The tests that probe the host for GNU coreutils check `--version` for `(GNU coreutils)`, and `@cloudpid/sandbox-image`'s `test` is uncached, since its memory-guard tests fail under uutils. Linux is unaffected. @@ -34,4 +34,5 @@ Measured on an 8-core Apple Silicon laptop (2026-11-12), warm caches: - **Keeping Bun with Vite+.** Vite+ supports Bun, but the owner chose pnpm; Bun's install speed was most of ADR-0028's case for it, and pnpm's global virtual store is available where it matters, on the Container. - **Keeping Turborepo with Vite+'s lint and format.** Turborepo's `transit` node and hand-listed inputs were what Vite Task's file tracking does by itself, and one task runner is one less tool. - **Vite+ 1.6 with Vitest 5.1.** The workerd tests fail under Vitest 5.1 (dependencies.md); 1.4.0 holds Vitest at 5.0.5 until that is fixed. -- **tsrslint behind `vp lint`** (an override of `oxlint-tsgolint` with a package that runs tsrslint). Possible, but a shim around a shim; one lint over the repo already costs about what the per-package tsrslint runs did. +- **Vite+'s own tsgolint**, with nothing to keep in step with Vite+. One lint over the repo on it took 16 s and 3.6 GB against tsrs's 7–8 s and 1.0 GB at most, and needs no shim, but ADR-0028 chose a linter on tsrs for that cost, and the shim is one file. +- **tsrslint** (`@maschwenk/tsrslint`) behind the same shim. It worked (9–10 s, 2.1 GB at most), but tsrs now ships the same port itself, and its author means to fold tsrslint into it. diff --git a/docs/development/dependencies.md b/docs/development/dependencies.md index af59e86c..706cd4c6 100644 --- a/docs/development/dependencies.md +++ b/docs/development/dependencies.md @@ -6,6 +6,7 @@ Some dependencies carry a patch (`patches/`) or an exact pin. When upgrading one | ------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `@cloudflare/vitest-plugin` | `patches/@cloudflare__vitest-plugin@1.5.1.patch` | Keeps the module snapshot it sends a reused worker under workerd's 32 MiB WebSocket message limit, past which the worker dies with `1009 Message is too large` ([cloudflare/workers-sdk#16349](https://github.com/cloudflare/workers-sdk/issues/16349)). Drop it once #16349 is fixed. | | `vite-plus`, `vitest` | exact `1.4.0` (`vite-plus`) in the root `package.json` and `apps/web`; exact `5.0.5` (`vitest`) at the root and in the packages whose test plugins peer it; the `vite` and `vitest` `overrides` in `pnpm-workspace.yaml` (`@voidzero-dev/vite-plus-core@1.4.0`, `5.0.5`) | Vite+ bundles its own Vitest (1.4.0 bundles 5.0.5; 1.5 and later bundle 5.1), so `vite-plus`, the `vite` override and `vitest` move together. Vitest is held below 5.1: under 5.1.0 the workerd pool delays a timer a Durable Object request sets (`setImmediate`, `setTimeout(0)`) until a later request to an object awaits a real timer, so an Effect fiber forked in a request (Effect's scheduler starts it with `setImmediate`) starts late: a Session reports itself idle only at its next request, and `apps/server/src/session/admission.workerd.test.ts` ("Stop waits for it"), `host.workerd.test.ts` and `import.workerd.test.ts` fail. Bisected on its own (5.0.5 with the same workerd, `@cloudflare/vitest-plugin`, Effect and pi-durable delivers them at once); deployed workerd is unaffected. Before lifting it, check that a `setImmediate` set in a `runInDurableObject` callback runs before the next no-op `runInDurableObject` returns, and rerun those three files. | +| `tsrs`, `oxlint-tsgolint` | exact `0.24.0-ts7.1.0-beta` (`tsrs`) in the root `package.json` (0.25 was under pnpm's day-old minimum release age when it was pinned); `oxlint-tsgolint` overridden to `link:./tools/tsrs-lint-shim` in `pnpm-workspace.yaml` | Vite+'s type-aware lint backend is tsrs's own linter, `tsrs-lint`, through the shim (`tools/tsrs-lint-shim/bin/tsgolint.js`; [ADR-0055](../adr/0055-vite-plus-and-pnpm.md) → Consequences). This `tsrs` is the linter only; the typecheck is `effect-tsgo tsrs`, the tsrs that `@effect/tsgo` ships, whatever this pin says. When upgrading `vite-plus` or `tsrs`, check that `pnpm exec vp lint` on a file with a type error and a floating promise still reports both (`typescript(TS2322)`, `no-floating-promises`): a Vite+ that looks for its backend elsewhere fails with `Error running tsgolint`, and a tsrs that speaks a newer tsgolint protocol than Vite+'s oxlint may not be understood. It does not run on Windows, where Vite+ looks for `tsgolint.exe` or `.cmd` instead. Drop the override, the shim and `tsrs` once `effect-tsgo --tsrs-lint vp lint` runs (`@effect/tsgo` 0.68 and later, with oxlint 1.91 or later). | | `ws` | exact `8.22.1`, an `overrides` entry in `pnpm-workspace.yaml` | One `ws` for every package: `@earendil-works/chord` pins `8.21.0` and the rest resolve 8.22, and each `ws` is a peer variant of `alchemy`, whose two copies then fail `infra`'s typecheck (a union of two `AlchemyContext`s). Drop it once chord allows 8.22, or move it with the newest `ws` chord allows. | | `@cloudflare/computer` | `patches/@cloudflare__computer@0.9.0.patch` | Adds `Workspace.remount()`, which `updateSkills` runs: computer checks a mount's version only at a Workspace's first index ([`../architecture/workspace.md`](../architecture/workspace.md) → _The Skill set_). Drop it once computer can index a mount again; rerun `apps/server/src/workspace/skills.workerd.test.ts` either way. Also update the `bash` routing lists if the Worker Shell changed ([`workers.md`](workers.md) → _The Workspace DO_). | | `@cloudflare/computer`, computerd | read for the file-change signal | The file-change signal ([`../architecture/container.md`](../architecture/container.md) → _File-change signals_) reads computer's change-log tables (`apps/server/src/workspace/change-log.ts`) and span names (`notify.ts`), and needs computerd's `setxattr` on its mount to stay a no-op the kernel reports. When upgrading either, rerun `src/workspace/notify.workerd.test.ts` and `notify.test.ts`, and recheck by hand as that section's _Limits_ says. | diff --git a/package.json b/package.json index c2c09d2f..268c93c7 100644 --- a/package.json +++ b/package.json @@ -26,6 +26,7 @@ "@commitlint/config-conventional": "21.2.4", "@effect/tsgo": "0.64.1", "skills": "^1.7.6", + "tsrs": "0.24.0-ts7.1.0-beta", "typescript": "^7.0.2", "vite-plus": "1.4.0", "vitest": "5.0.5" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index dfe7b315..18bf53af 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -167,6 +167,7 @@ overrides: vite@*: npm:@voidzero-dev/vite-plus-core@1.4.0 vitest@*: 5.0.5 ws: 8.22.1 + oxlint-tsgolint: link:./tools/tsrs-lint-shim patchedDependencies: '@alchemy.run/cloudflare@2.0.0-beta.85': 42560d88385a37a4a65b7d0f3d0f4746d76477154fea680e52ae463e3f9f326c @@ -193,6 +194,9 @@ importers: skills: specifier: ^1.7.6 version: 1.7.6 + tsrs: + specifier: 0.24.0-ts7.1.0-beta + version: 0.24.0-ts7.1.0-beta typescript: specifier: ^7.0.2 version: 7.0.2 @@ -2254,36 +2258,6 @@ packages: cpu: [x64] os: [win32] - '@oxlint-tsgolint/darwin-arm64@7.0.2004': - resolution: {integrity: sha512-uJk3ttju7Lz+Nv8WG4CsLyewoL1qf/Ny8S8OksJ7Bm/F14Tc9gMfW6arM1PCc57IzH/X/I79YsCWTgxX1FKibQ==} - cpu: [arm64] - os: [darwin] - - '@oxlint-tsgolint/darwin-x64@7.0.2004': - resolution: {integrity: sha512-0BFfHTzDxNDFPcu0UZAXT6CyCJHAXM0dZveyDb4KEHa2qF/DSnOKOrmvK/wFuFol9kvijbGM9JfuOsor+zWXRw==} - cpu: [x64] - os: [darwin] - - '@oxlint-tsgolint/linux-arm64@7.0.2004': - resolution: {integrity: sha512-TAehQc+qdRXyDN3nl/r/3/oPrBVrbtrDeGMkFyG6mf+XphpoJ2lAMVFLclyvrVZCw02RbKROjyw8h72XwQQHcw==} - cpu: [arm64] - os: [linux] - - '@oxlint-tsgolint/linux-x64@7.0.2004': - resolution: {integrity: sha512-LPunZvm6ZbWPfHMAyfZf9ci3HHvNEzLejO8zdqO3GoVGoSEHqqufHUD7+OgeatVSaJP7uXDJ2HaNOHIoH7go4Q==} - cpu: [x64] - os: [linux] - - '@oxlint-tsgolint/win32-arm64@7.0.2004': - resolution: {integrity: sha512-FVWplzDImWhiuawnIZVETaQecv4GWom6Jv4Fx2xj7hhXXDZ5okEgiw1gTCImHTIQsi2ycC5oSxVwrn69bMh7iw==} - cpu: [arm64] - os: [win32] - - '@oxlint-tsgolint/win32-x64@7.0.2004': - resolution: {integrity: sha512-7PsxuUx11Ry9DYTWcljTzRbmZY9B6O9fFFfZV+aodQEMy6pfRT3fhoQRv9PtGN/89z1pPz3nFKrsFm6WqNtX7w==} - cpu: [x64] - os: [win32] - '@oxlint/binding-android-arm-eabi@1.89.0': resolution: {integrity: sha512-Pflpba5F3gRAQ12sWglRxvWTHEdAusNDvmi4Y5N1T5SY1AGkM7AixOnET8qkrnLJ/F32qAlNokO6eCknT8tmnw==} engines: {node: ^20.19.0 || >=22.12.0} @@ -3637,6 +3611,52 @@ packages: '@tokenizer/token@0.3.0': resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + '@tsrs/darwin-arm64@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-GxGPRieCGIXevJgGlbne9pRqkfAN+VmBQvBHWWcF8rXLNX9yCxYo78/a7Auqjf723b4eFTlM5mgkclUit/Fu9w==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [darwin] + + '@tsrs/darwin-x64@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-TrXdOyEq++blyYp6KphoHGmsGxAn1flYzjm0peLEI3c88z1UQa+pKkcuPgZ6FOxTW6fSaT9572n21kz+0bWi/g==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [darwin] + + '@tsrs/linux-arm64-gnu@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-Ph5NK0vnaR4gnBW2LgrZsUPx4mKF+9tCQUYZFOHmny6SMojSsm/5GCiBu0sHZEZhmyIqq8UbineUEA7T0QImnw==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@tsrs/linux-arm64-musl@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-vjgx8wGuAVSOPLlb2eVQpQVolImZa7vsH/1kvYOaokcP/KZXVUmHzgroxK0t9gxJ0SXvT4VKNjWZ+t+4tDNu1A==} + engines: {node: '>=16.20.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@tsrs/linux-x64-gnu@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-tj1SNWBnJoBUzU2zrD18tUu3h6o36FXQGPpmIXsADHSfU5H9pVQdK/QzPIO76rb72P7foXHluE+xGTXXf8nNaA==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@tsrs/linux-x64-musl@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-sizu0EdGw9ITqEaZKg60TDhDk5PXT9RzVkCdesBjk/BZhS0BVU2cRhvoRBmDbk+2vCUgW14j+Otg3tl+002qNQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@tsrs/win32-x64@0.24.0-ts7.1.0-beta': + resolution: {integrity: sha512-WAbzgd5JBOauQ/oL6DTdGEh09tM/q8tlGAcRORskhPK7eIQVVa8Js2pc7DVW0XokWTSADeD9v6HKtU2Ge0r/fQ==} + engines: {node: '>=16.20.0'} + cpu: [x64] + os: [win32] + '@types/aria-query@5.0.4': resolution: {integrity: sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==} @@ -5574,10 +5594,6 @@ packages: vite-plus: optional: true - oxlint-tsgolint@7.0.2004: - resolution: {integrity: sha512-vQ9WDF3fiZJvRdSDosNOflerOCOpwol6vWzVDxW76RcU19cjTh7engvkHLvmv+tzedR8fAiJUVUGr6IVZdkzXQ==} - hasBin: true - oxlint@1.89.0: resolution: {integrity: sha512-a25hkfo61okGPvJz432fRIPoxlKtNnOVy9w4rzrmGgNm4iVTPwpSQlmdqNWnp6p9QyyPVfAZRgnf5XvSBZFk/A==} engines: {node: ^20.19.0 || >=22.12.0} @@ -6155,6 +6171,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsrs@0.24.0-ts7.1.0-beta: + resolution: {integrity: sha512-Iy7q93qfRHcI0Y31IKx6fCsDQCsSjtrT01PIgOVolBXPJTMdm84oH1pEYyAMPQ/SnRqWDSWI8wEUHbv6e9TmHA==} + engines: {node: '>=16.20.0'} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -7996,24 +8017,6 @@ snapshots: '@oxfmt/binding-win32-x64-msvc@0.74.0': optional: true - '@oxlint-tsgolint/darwin-arm64@7.0.2004': - optional: true - - '@oxlint-tsgolint/darwin-x64@7.0.2004': - optional: true - - '@oxlint-tsgolint/linux-arm64@7.0.2004': - optional: true - - '@oxlint-tsgolint/linux-x64@7.0.2004': - optional: true - - '@oxlint-tsgolint/win32-arm64@7.0.2004': - optional: true - - '@oxlint-tsgolint/win32-x64@7.0.2004': - optional: true - '@oxlint/binding-android-arm-eabi@1.89.0': optional: true @@ -9199,6 +9202,27 @@ snapshots: '@tokenizer/token@0.3.0': {} + '@tsrs/darwin-arm64@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/darwin-x64@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/linux-arm64-gnu@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/linux-arm64-musl@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/linux-x64-gnu@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/linux-x64-musl@0.24.0-ts7.1.0-beta': + optional: true + + '@tsrs/win32-x64@0.24.0-ts7.1.0-beta': + optional: true + '@types/aria-query@5.0.4': {} '@types/chai@5.2.3': @@ -11166,16 +11190,7 @@ snapshots: '@oxfmt/binding-win32-x64-msvc': 0.74.0 vite-plus: 1.4.0(@opentelemetry/api@1.10.0)(@types/node@26.6.6)(@vitest/ui@5.0.5)(esbuild@0.28.2)(happy-dom@21.0.4)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.1) - oxlint-tsgolint@7.0.2004: - optionalDependencies: - '@oxlint-tsgolint/darwin-arm64': 7.0.2004 - '@oxlint-tsgolint/darwin-x64': 7.0.2004 - '@oxlint-tsgolint/linux-arm64': 7.0.2004 - '@oxlint-tsgolint/linux-x64': 7.0.2004 - '@oxlint-tsgolint/win32-arm64': 7.0.2004 - '@oxlint-tsgolint/win32-x64': 7.0.2004 - - oxlint@1.89.0(oxlint-tsgolint@7.0.2004)(vite-plus@1.4.0): + oxlint@1.89.0(oxlint-tsgolint@tools+tsrs-lint-shim)(vite-plus@1.4.0): optionalDependencies: '@oxlint/binding-android-arm-eabi': 1.89.0 '@oxlint/binding-android-arm64': 1.89.0 @@ -11196,7 +11211,7 @@ snapshots: '@oxlint/binding-win32-arm64-msvc': 1.89.0 '@oxlint/binding-win32-ia32-msvc': 1.89.0 '@oxlint/binding-win32-x64-msvc': 1.89.0 - oxlint-tsgolint: 7.0.2004 + oxlint-tsgolint: link:tools/tsrs-lint-shim vite-plus: 1.4.0(@opentelemetry/api@1.10.0)(@types/node@26.6.6)(@vitest/ui@5.0.5)(esbuild@0.28.2)(happy-dom@21.0.4)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.1) p-retry@4.6.2: @@ -11970,6 +11985,16 @@ snapshots: tslib@2.8.1: {} + tsrs@0.24.0-ts7.1.0-beta: + optionalDependencies: + '@tsrs/darwin-arm64': 0.24.0-ts7.1.0-beta + '@tsrs/darwin-x64': 0.24.0-ts7.1.0-beta + '@tsrs/linux-arm64-gnu': 0.24.0-ts7.1.0-beta + '@tsrs/linux-arm64-musl': 0.24.0-ts7.1.0-beta + '@tsrs/linux-x64-gnu': 0.24.0-ts7.1.0-beta + '@tsrs/linux-x64-musl': 0.24.0-ts7.1.0-beta + '@tsrs/win32-x64': 0.24.0-ts7.1.0-beta + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -12146,8 +12171,8 @@ snapshots: '@vitest/spy': 5.0.5 '@vitest/utils': 5.0.5 oxfmt: 0.74.0(vite-plus@1.4.0) - oxlint: 1.89.0(oxlint-tsgolint@7.0.2004)(vite-plus@1.4.0) - oxlint-tsgolint: 7.0.2004 + oxlint: 1.89.0(oxlint-tsgolint@tools+tsrs-lint-shim)(vite-plus@1.4.0) + oxlint-tsgolint: link:tools/tsrs-lint-shim vite: '@voidzero-dev/vite-plus-core@1.4.0(@types/node@26.6.6)(esbuild@0.28.2)(jiti@2.7.0)(typescript@7.0.2)(yaml@2.9.1)' vitest: 5.0.5(@opentelemetry/api@1.10.0)(@types/node@26.6.6)(@vitest/browser-preview@5.0.5)(@vitest/ui@5.0.5)(@voidzero-dev/vite-plus-core@1.4.0)(happy-dom@21.0.4) optionalDependencies: diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index f7cbb547..85f3dce8 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -37,6 +37,8 @@ overrides: # One `ws` for every package: chord pins 8.21.0 and the rest resolve 8.22, and each `ws` is a peer variant of alchemy, # whose two copies then fail the typecheck of `infra` (`AlchemyContext | AlchemyContext`). ws: 8.22.1 + # Vite+'s type-aware lint backend runs tsrs's linter instead of tsgolint (tools/tsrs-lint-shim/bin/tsgolint.js). + oxlint-tsgolint: link:./tools/tsrs-lint-shim # Vite+'s core stands in for `vite`, and packages that peer an older `vite` or `vitest` accept it (`vp migrate`'s rule). peerDependencyRules: diff --git a/tools/tsrs-lint-shim/bin/tsgolint.js b/tools/tsrs-lint-shim/bin/tsgolint.js new file mode 100755 index 00000000..b38d8a97 --- /dev/null +++ b/tools/tsrs-lint-shim/bin/tsgolint.js @@ -0,0 +1,19 @@ +#!/usr/bin/env node +// Vite+'s type-aware lint backend, run as tsrs's own linter (`tsrs-lint`, tsrs's port of tsgolint's headless mode and +// rules) instead of tsgolint (docs/adr/0055-vite-plus-and-pnpm.md → Consequences). `vp lint` and `vp check` run the +// `bin/tsgolint` of the `oxlint-tsgolint` they resolve, from the working directory first and then from `vite-plus`, and +// set `OXLINT_TSGOLINT_PATH` to it themselves, so `pnpm-workspace.yaml`'s overrides make this directory that package (no +// workspace package declares `oxlint-tsgolint`, which would take its place). It has no `package.json` on purpose: +// `effect-tsgo patch` (the root `prepare`) looks for Vite+'s `oxlint-tsgolint` by its `package.json`, and would then fail +// the install looking for tsgolint's platform binary, which this replaces. +import { readFileSync } from "node:fs"; +import { createRequire } from "node:module"; +import { dirname, join } from "node:path"; +import { pathToFileURL } from "node:url"; + +// The `tsrs` package's `tsrs-lint` command, by its `bin` entry, run in this process: it reads `process.argv` from its +// third entry on, as this script's are. +const manifest = createRequire(import.meta.url).resolve("tsrs/package.json"); +const { bin } = JSON.parse(readFileSync(manifest, "utf8")); + +await import(pathToFileURL(join(dirname(manifest), bin["tsrs-lint"])).href);