{ /* The TypeScript configuration, succeeding `jsconfig.json`. Deliberately a translation of what was already there rather than a fresh start: every option below that existed in jsconfig carries its old value, so the first day of the migration checks exactly what the last day before it checked. The four additions are marked. `jsconfig.json` is left in place for now and is inert — TypeScript ignores it wherever a `tsconfig.json` sits beside it. It is removed in the final phase, once nothing is asking for it. */ "compilerOptions": { "baseUrl": ".", "paths": { "@/*": ["./src/*"] }, "jsx": "react-jsx", "module": "esnext", "moduleResolution": "bundler", "lib": ["esnext", "dom", "dom.iterable"], "target": "esnext", /* Vite builds; this config only ever checks. Stating it means no stray output can appear next to a source file if anyone runs `tsc` directly. */ "noEmit": true, /* The two that make an incremental migration possible. `allowJs` lets a `.ts` file and a `.js` file import each other with no ceremony, so files can be converted one at a time instead of in one unreviewable commit; `checkJs` keeps the JSDoc-typed JavaScript under the same scrutiny it has had all along, so nothing is lost in the meantime. Both go away at the end of the migration, not before. */ "allowJs": true, "checkJs": true, /* NEW. esbuild compiles each file on its own and cannot see across them, so a construct that needs whole-program knowledge — re-exporting a type as if it were a value, most often — works under `tsc` and breaks in the bundle. This makes tsc refuse what esbuild could not have done anyway. */ "isolatedModules": true, /* NEW. macOS does not distinguish `Button` from `button`; CI does. Without this, a mis-cased import is a green local build and a red pipeline. */ "forceConsistentCasingInFileNames": true, "skipLibCheck": true, "allowSyntheticDefaultImports": true, "esModuleInterop": true, "resolveJsonModule": true, /* CHANGED, from `[]`. The empty list suppressed every ambient type package, which is why `import.meta.env` and `import.meta.glob` — Vite build-time APIs, absent from the standard `ImportMeta` — were reported as errors in eight places across the app. Named explicitly rather than left to default, because the default pulls in EVERYTHING under node_modules/@types, and `@types/node` is installed. In browser code that would make `setTimeout` return a `NodeJS.Timeout` instead of a number, which is wrong and quietly infectious: three components store a timer handle in a `useRef` and would be typed against a runtime they do not run on. Node's types belong to `vite.config.js` and `scripts/`, neither of which this project includes. */ "types": ["vite/client"], /* Off for now, and turned on a flag at a time later in the migration — `noImplicitAny`, then `strictNullChecks`, then the rest. Enabling it here would bury the ~70 real errors this project already has under several hundred more, and the point of going file by file is that each step is small enough to read. */ "strict": false }, "include": ["src/**/*"], /* Unchanged from jsconfig, and temporary. These three trees hold the densest logic in the app — the transport layer, every hook, and the vendored UI primitives — and none of it has ever been checked. Each exclusion is removed by the phase that converts the tree behind it, so the error count rises deliberately and in one identifiable place at a time. Note that excluding a file only keeps it out of the root set: one that an included file imports is still checked, which is why errors from `src/api` and `src/lib` already show up today. */ "exclude": ["node_modules", "dist", "src/components/ui", "src/api", "src/lib"] }