Skip to content

chore(deps): upgrade typescript 5.9.2 to 6.0.3#10326

Open
davidfirst wants to merge 22 commits into
masterfrom
upgrade-typescript-6
Open

chore(deps): upgrade typescript 5.9.2 to 6.0.3#10326
davidfirst wants to merge 22 commits into
masterfrom
upgrade-typescript-6

Conversation

@davidfirst

Copy link
Copy Markdown
Member

Bumps typescript to the latest stable major (6.0.3). Small set of compatibility adjustments to absorb TS 6's new stricter defaults without changing behavior for downstream users on TS 5.x.

  • workspace.jsonc: bump typescript pin in root policy and in the scopes/harmony/bit variant.
  • Root tsconfig.json (repo-internal only, not shipped): add ignoreDeprecations: "6.0", set noUncheckedSideEffectImports: false, and list types: ["node", "mocha", "chai", "jest"] to restore the pre-6 auto-discovery behavior for test specs.
  • scopes/typescript/typescript/typescript.main.runtime.ts: in createCompiler, auto-inject ignoreDeprecations: "6.0" when the loaded typescript is major version ≥ 6 and the caller hasn't set it. This keeps the shipped env tsconfigs (scopes/react/react/typescript/*.json, scopes/harmony/aspect/typescript/tsconfig.json, scopes/typescript/typescript/tsconfig.default.json) untouched so they remain valid for TS 5.x consumers — TS 5.x rejects ignoreDeprecations: "6.0" with TS5103, and TS 5.x rejects moduleResolution: "bundler" + module: "commonjs".

Test plan

  • bit compile — 311/311 components compile
  • npm run lint — 0 tsc errors, 0 oxlint warnings across 2,838 files
  • CI e2e

- Bump typescript in workspace.jsonc (two locations).
- Add ignoreDeprecations, noUncheckedSideEffectImports, and explicit
  types array to root tsconfig to absorb TS 6 default changes.
- Inject ignoreDeprecations at runtime in TypescriptMain.createCompiler
  when TS 6+ is loaded, so shipped env tsconfigs stay TS 5.x-compatible.
Copilot AI review requested due to automatic review settings April 22, 2026 18:15

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the repo’s pinned TypeScript version to 6.0.3 and applies targeted configuration/runtime adjustments so the workspace can compile/lint cleanly under TS 6 while keeping shipped env tsconfigs compatible with TS 5.x consumers.

Changes:

  • Bump typescript pin from 5.9.2 → 6.0.3 in the root dependency policy and the scopes/harmony/bit variant.
  • Update the repo-root tsconfig.json with TS 6 compatibility settings (ignoreDeprecations, noUncheckedSideEffectImports, and explicit types).
  • Update TypescriptMain.createCompiler() to auto-inject ignoreDeprecations: "6.0" only when the loaded compiler is TS 6+ and the caller didn’t set it.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated no comments.

File Description
workspace.jsonc Updates the workspace dependency policy pins to TypeScript 6.0.3 (root + scopes/harmony/bit variant).
tsconfig.json Adjusts repo-internal TypeScript compiler options to accommodate TS 6 stricter defaults.
scopes/typescript/typescript/typescript.main.runtime.ts Conditionally injects ignoreDeprecations at runtime for TS 6+ to preserve TS 5.x compatibility of shipped env configs.

…EffectImports on TS 6

Capsule builds were failing with 778 implicit-any errors because TS 6
flipped 'strict' default from false to true, turning on full strict mode
for shipped env tsconfigs that relied on the TS 5 default. Extend the
runtime injection in TypescriptMain.createCompiler to also set
strict=false and noUncheckedSideEffectImports=false when those are not
explicitly configured.
Copilot AI review requested due to automatic review settings April 22, 2026 20:02

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the repo’s pinned TypeScript version to 6.0.3 and adds targeted configuration/runtime shims so Bit’s shipped TypeScript env configs remain compatible with TS 5.x consumers while the repo itself builds with TS 6.

Changes:

  • Bump typescript pin to 6.0.3 in workspace.jsonc (root + harmony/bit variant).
  • Update root tsconfig.json with TS6-related options (ignoreDeprecations, noUncheckedSideEffectImports, explicit types list).
  • Patch TypescriptMain.createCompiler() to inject TS6-only compiler options at runtime when the loaded compiler is TS 6+.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 2 comments.

File Description
workspace.jsonc Pins TypeScript to 6.0.3 in dependency policies.
tsconfig.json Adjusts repo-internal TS compiler options for TS 6 defaults/behavior.
scopes/typescript/typescript/typescript.main.runtime.ts Adds TS 6+ runtime tsconfig patching to keep shipped env tsconfigs TS 5.x compatible.

Comment thread workspace.jsonc
Comment thread scopes/typescript/typescript/typescript.main.runtime.ts Outdated
TS 6 stopped auto-discovering @types/* packages (types defaults to []).
Spec files lost their describe/it/expect globals. Extend the
createCompiler runtime injection to seed ['node', 'jest'] when
compilerOptions.types is unset — both are universally installed by Bit
envs (node env + React env both ship @types/jest, which provides
BDD-style globals).
Copilot AI review requested due to automatic review settings April 28, 2026 14:37

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the repository’s TypeScript toolchain to TS 6.0.3 and applies compatibility shims/config tweaks so TS 6’s stricter defaults don’t unintentionally change behavior (especially around deprecations, side-effect imports, and ambient type discovery).

Changes:

  • Bump typescript from 5.9.2 to 6.0.3 in workspace.jsonc (root policy + harmony/bit variant).
  • Update root tsconfig.json with TS6-focused options (ignoreDeprecations, noUncheckedSideEffectImports, explicit types).
  • Patch TypescriptMain.createCompiler() to conditionally adjust compilerOptions at runtime when running under TS 6+.

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 1 comment.

File Description
workspace.jsonc Updates TS version pin(s) to 6.0.3.
tsconfig.json Adds TS6 compilerOptions to keep repo-local typechecking consistent with prior behavior.
scopes/typescript/typescript/typescript.main.runtime.ts Adds TS6+ runtime tsconfig patching logic inside createCompiler().

Comment thread workspace.jsonc
- Refresh pnpm-lock.yaml to align with typescript@6.0.3 pin.
- Pin @types/jest in workspace.jsonc to match the explicit jest types in
  the root tsconfig.
- Skip the strict/types runtime injection when the tsconfig uses extends,
  since an inherited base config may already set these and our injection
  would silently override them.
The tsconfig-env-mismatch test was relying on the TS 5 default of
strict=false. TS 6 flipped that default to true, so the permissive
fixture started reporting strict-mode errors. Setting strict: false
explicitly makes the fixture independent of the TS version default.
Copilot AI review requested due to automatic review settings April 30, 2026 14:00

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Upgrades the repo’s pinned TypeScript version to 6.0.3 and adds targeted compatibility shims/config tweaks so the workspace and shipped Bit TypeScript envs continue to behave as before (especially around TS6’s stricter defaults).

Changes:

  • Bump TypeScript pin to 6.0.3 (root policy + scopes/harmony/bit variant) and add an explicit @types/jest pin.
  • Update root tsconfig.json to absorb TS6 defaults (ignoreDeprecations, noUncheckedSideEffectImports, explicit types list for test globals).
  • Patch TypescriptMain.createCompiler() to apply TS6-only runtime tsconfig adjustments (without breaking TS5.x consumers of shipped env tsconfigs).
  • Update an e2e fixture to explicitly set strict: false to keep the test intent stable under TS6.

Reviewed changes

Copilot reviewed 3 out of 5 changed files in this pull request and generated 1 comment.

File Description
workspace.jsonc Pins TypeScript 6.0.3 and adds @types/jest to make root tsconfig’s explicit types reproducible.
tsconfig.json Adds TS6 compatibility flags and explicitly lists global types for test files.
scopes/typescript/typescript/typescript.main.runtime.ts Injects TS6-only compilerOptions defaults at runtime to keep shipped env configs TS5-compatible.
e2e/harmony/tsconfig-env-mismatch.e2e.ts Makes the permissive fixture explicitly strict: false to keep it permissive under TS6.

Comment thread workspace.jsonc Outdated
Copilot AI review requested due to automatic review settings April 30, 2026 19:19

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated no new comments.

Comments suppressed due to low confidence (1)

workspace.jsonc:405

  • @types/jest is pinned to 26.0.20, but this workspace also pins jest to 29.3.1. Keeping Jest runtime and its type package on different majors can lead to missing/incorrect typings (especially for newer Jest APIs) and make test type-checking less reliable. Consider updating @types/jest to a 29.x version that matches the Jest major (or, if the intent is to avoid full Jest typings, document why this older major is intentionally pinned).
        "@types/mdx-js__react": "1.5.5",
        "@types/jest": "26.0.20",
        "@types/memoizee": "0.4.5",
        "@types/mime": "2.0.3",
        "@types/mini-css-extract-plugin": "2.2.0",
        "@types/minimatch": "3.0.4",
        "@types/mocha": "9.1.0",

Copilot AI review requested due to automatic review settings May 11, 2026 15:33
# Conflicts:
#	scopes/typescript/ts-server/ts-server-client.ts

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Comment thread scopes/typescript/typescript/typescript.main.runtime.ts Outdated
Copilot AI review requested due to automatic review settings May 13, 2026 13:51

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Comment thread e2e/harmony/tsconfig-env-mismatch.e2e.ts Outdated
Copilot AI review requested due to automatic review settings May 13, 2026 14:38

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated 1 comment.

Comment thread scopes/typescript/ts-server/ts-server-client.ts
Copilot AI review requested due to automatic review settings June 3, 2026 16:17

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 4 out of 5 changed files in this pull request and generated no new comments.

@davidfirst

Copy link
Copy Markdown
Member Author

Code review

Found 1 issue:

  1. The new await this.tsServer.start() in init() is wrapped in a try/catch that only logs (line 94). If start() rejects (e.g., tsserver writes to stderr before its first event — see ProcessBasedTsServer.start's stderr listener that calls reject), serverRunning stays false but this.tsServer remains non-null. The caller in check-types.cmd.ts:116 only guards if (!tsserver) throw, which doesn't fire, and then getDiagnostic uses this.tsServer?.request(...) — the optional chaining silently returns undefined and the command reports a clean type-check run. Before this PR, start() was fire-and-forget so this state was less impactful; now any startup-time stderr (which TS 6 emits more verbosely) silently nukes diagnostics. Consider either rethrowing in the catch or having the caller check isServerRunning().

// Await the server to be ready before issuing any requests, so a start() failure
// (e.g., tsserver writing to stderr) surfaces here rather than producing a write to a
// broken stdin, and so the inferred-project options below are applied to a live server.
await this.tsServer.start();
this.serverRunning = true;
// TS 6 flipped the `strict` default from false to true for inferred projects.
// Files outside any tsconfig (e.g., components whose env's tsconfig isn't included
// by the workspace config writer) would otherwise get strict-mode errors that didn't
// surface in TS 5. Pin inferred-project options to the TS 5 default to preserve behavior.
await this.setCompilerOptionsForInferredProjects({ strict: false });
const shouldOpenFiles = this.options.openFilesOnInit !== false;
if (this.files.length && shouldOpenFiles) {
const openResults = await Promise.all(
this.files.map((file) => this.open(file).catch((error: unknown) => error))
);
const failedFiles = openResults.filter((result) => result instanceof Error);
if (failedFiles.length > 0) {
this.logger.error('TsserverClient.init failed to open files:', failedFiles);
}
this.filesPreOpenedOnInit = true;
this.checkTypesIfNeeded();
}
this.logger.debug('TsserverClient.init completed');
} catch (err) {
this.logger.error('TsserverClient.init failed', err);
}

🤖 Generated with Claude Code

- If this code review was useful, please react with 👍. Otherwise, react with 👎.

…ad of auto-injected

Remove the auto-injection of ignoreDeprecations: '6.0' from the TS 6 runtime
patch. Auto-injecting hides the deprecation diagnostics TS 6 is specifically
designed to surface as preparation for TS 7, defeating the purpose of the
5 → 6 → 7 migration path.

Add ignoreDeprecations: '6.0' explicitly in each tsconfig that still needs
the bridge (workspace root, env templates, schema mocks), with a TODO(ts7)
comment documenting the technical debt — migrate moduleResolution: 'node'
to 'node16' or 'bundler' before adopting TS 7.
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (3) 📘 Rule violations (0)

Grey Divider


Action required

1. Mocha types excluded 🐞 Bug ≡ Correctness ⭐ New
Description
TypescriptMain.createCompiler() injects compilerOptions.types = ['node','jest'] for TS 6 when
types is unset, which prevents @types/mocha from contributing ambient globals even if it’s
installed. Repo spec files rely on mocha globals (e.g. after()), so TS6 compilation/typecheck
paths using this injected config will fail with missing global names.
Code

scopes/typescript/typescript/typescript.main.runtime.ts[R150-158]

+      if (!tsconfig.extends) {
+        if (compilerOptions.strict === undefined) compilerOptions.strict = false;
+        // TS 6 stopped auto-discovering @types/* packages (types defaults to []).
+        // Seed the types every Bit env installs — @types/node universally and @types/jest
+        // (provides describe/it/expect globals). Don't seed 'mocha': the React env
+        // removes @types/mocha via the `-` convention (see react.env.ts), so seeding it
+        // would make tsc fail to resolve a type package that isn't installed.
+        if (compilerOptions.types === undefined) compilerOptions.types = ['node', 'jest'];
+      }
Evidence
The TS6 patch explicitly sets compilerOptions.types to ['node','jest'], while the workspace has
@types/mocha installed and the codebase contains spec files using mocha globals like after().
With types restricted to node/jest, mocha globals are excluded and those files won’t typecheck
under TS6 in any compilation path using the injected config.

scopes/typescript/typescript/typescript.main.runtime.ts[133-158]
workspace.jsonc[375-409]
scopes/harmony/cache/cache.spec.ts[7-32]
tsconfig.json[6-12]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`TypescriptMain.createCompiler()` conditionally patches TS6+ tsconfigs by setting `compilerOptions.types` to `['node','jest']` when `types` is not provided. In TypeScript, setting `compilerOptions.types` restricts ambient type packages to *only* those listed, which excludes `@types/mocha` globals (`describe`, `it`, `before`, `after`, etc.) even if `@types/mocha` is installed.

This can break TS6 builds/typechecks for mocha-based projects/files.

### Issue Context
- The workspace installs `@types/mocha`.
- The repo contains `.spec.ts` files using mocha globals (e.g. `after()`).

### Fix Focus Areas
- scopes/typescript/typescript/typescript.main.runtime.ts[150-158]

### Suggested fix
When injecting `compilerOptions.types` for TS6, build the list dynamically based on which `@types/*` packages are actually resolvable from the current environment/capsule.

For example:
- Always include `node`.
- Include `jest` only if `@types/jest` is resolvable.
- Include `mocha` only if `@types/mocha` is resolvable.

This preserves TS5-style “auto-discovery” behavior without forcing an unavailable type package (the reason mocha was avoided for the React env).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. TS6 patch skips extends 🐞 Bug ≡ Correctness
Description
TypescriptMain.createCompiler() only injects TS6-compat defaults for strict/types when
tsconfig.extends is falsy, so configs that extend a base can still pick up TS6’s new defaults.
React env’s typescript/tsconfig.cjs.json extends typescript/tsconfig.json (which doesn’t set
strict/types), so TS6 can treat it as strict-by-default with no auto-discovered @types, causing
IDE/tsserver errors and mismatches vs Bit’s compiler behavior.
Code

scopes/typescript/typescript/typescript.main.runtime.ts[R146-156]

+      // strict and types: don't inject when the tsconfig extends a base — the base may
+      // already set these, and an explicit value here would silently override the inherited one.
+      if (!tsconfig.extends) {
+        if (compilerOptions.strict === undefined) compilerOptions.strict = false;
+        // TS 6 stopped auto-discovering @types/* packages (types defaults to []).
+        // Seed the types every Bit env installs — @types/node universally and @types/jest
+        // (provides describe/it/expect globals). Don't seed 'mocha': the React env
+        // removes @types/mocha via the `-` convention (see react.env.ts), so seeding it
+        // would make tsc fail to resolve a type package that isn't installed.
+        if (compilerOptions.types === undefined) compilerOptions.types = ['node', 'jest'];
+      }
Evidence
The TS6-compat injection is guarded by if (!tsconfig.extends), but the React env’s workspace
tsconfig uses extends and its base doesn’t define strict/types, so it will bypass the
injection and can still take TS6 defaults when TypeScript loads the config file directly (e.g.,
tsserver/IDE).

scopes/typescript/typescript/typescript.main.runtime.ts[125-157]
scopes/react/react/typescript/tsconfig.cjs.json[1-6]
scopes/react/react/typescript/tsconfig.json[1-20]
scopes/react/react/react.env.ts[606-621]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`TypescriptMain.createCompiler()` patches TS6+ defaults (`strict`, `types`) only when the raw tsconfig does **not** use `extends`. However, the repo’s React env writes `typescript/tsconfig.cjs.json` into workspaces (via `TypescriptConfigWriter`), and that file **does** use `extends` while its base does not define `strict`/`types`. With TS6, that derived config can still end up with strict-by-default and `types=[]`, reintroducing the mismatch this PR is trying to prevent.
## Issue Context
- The patch is skipped whenever `tsconfig.extends` exists.
- `scopes/react/react/typescript/tsconfig.cjs.json` extends `./tsconfig.json` and only overrides `module`.
- `scopes/react/react/typescript/tsconfig.json` doesn’t set `compilerOptions.strict` or `compilerOptions.types`.
- `ReactEnv.workspaceConfig()` writes `tsconfig.cjs.json` as the workspace tsconfig path.
## Fix Focus Areas
- scopes/typescript/typescript/typescript.main.runtime.ts[140-156]
- scopes/react/react/typescript/tsconfig.cjs.json[1-6]
- scopes/react/react/typescript/tsconfig.json[1-20]
- scopes/react/react/react.env.ts[606-621]
## Implementation direction
Pick one (or combine):
1) Make the TS6 patching logic handle `extends` safely: only inject `strict/types` when they are not explicitly set in the *effective* config (consider flattening/merging the extended config before deciding).
2) Alternatively (simpler for the React workspace config writer): add explicit `"strict": false` and an explicit `"types": [...]` to `tsconfig.cjs.json` (or to its base) so TS6 won’t fall back to new defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended

3. Orphan tsserver process 🐞 Bug ☼ Reliability
Description
TsserverClient.init() now rethrows startup failures after setting this.tsServer = null without
killing the underlying ProcessBasedTsServer process. Since ProcessBasedTsServer.start() can reject
after spawning (e.g. on any stderr output) without cleanup, this can leave an orphaned tsserver
process and leak resources.
Code

scopes/typescript/ts-server/ts-server-client.ts[R95-101]

+      // Rethrow so callers know the server didn't come up. Swallowing here would leave
+      // `this.tsServer` set but unusable, and subsequent `request()` calls would silently
+      // return undefined via optional chaining — producing false-clean check-types runs.
   this.logger.error('TsserverClient.init failed', err);
+      this.tsServer = null;
+      this.serverRunning = false;
+      throw err;
Evidence
The new init() error path explicitly nulls this.tsServer and rethrows, but the underlying start()
implementation can reject after spawning without killing the child process, making the leaked
process unreachable for cleanup.

scopes/typescript/ts-server/ts-server-client.ts[60-102]
scopes/typescript/ts-server/process-based-tsserver.ts[172-236]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`TsserverClient.init()` now awaits `ProcessBasedTsServer.start()` and rethrows on failure, but the `catch` block sets `this.tsServer = null` without terminating the spawned child process. If `start()` rejects after spawning (notably when it rejects due to any stderr output), the child process can remain running with no remaining reference to clean it up.
### Issue Context
`ProcessBasedTsServer.start()` rejects on stderr output but does not kill the process or close the readline interface in that path. With the new `init()` flow, the reference is dropped immediately, making cleanup impossible and potentially leaking processes.
### Fix Focus Areas
- scopes/typescript/ts-server/ts-server-client.ts[69-102]
- scopes/typescript/ts-server/process-based-tsserver.ts[172-236]
### Suggested fix
1. In `TsserverClient.init()` catch block, if `this.tsServer` exists, call `this.tsServer.kill()` (or a dedicated `dispose()`), then set it to null.
2. (More robust) In `ProcessBasedTsServer.start()`, on any rejection path after spawning (stderr listener, invalid JSON, etc.), perform cleanup (`kill()`, close readline) before rejecting so callers don’t have to handle partial-start cleanup themselves.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit 3ab3b28

Results up to commit N/A


🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0)


Action required
1. TS6 patch skips extends 🐞 Bug ≡ Correctness
Description
TypescriptMain.createCompiler() only injects TS6-compat defaults for strict/types when
tsconfig.extends is falsy, so configs that extend a base can still pick up TS6’s new defaults.
React env’s typescript/tsconfig.cjs.json extends typescript/tsconfig.json (which doesn’t set
strict/types), so TS6 can treat it as strict-by-default with no auto-discovered @types, causing
IDE/tsserver errors and mismatches vs Bit’s compiler behavior.
Code

scopes/typescript/typescript/typescript.main.runtime.ts[R146-156]

+      // strict and types: don't inject when the tsconfig extends a base — the base may
+      // already set these, and an explicit value here would silently override the inherited one.
+      if (!tsconfig.extends) {
+        if (compilerOptions.strict === undefined) compilerOptions.strict = false;
+        // TS 6 stopped auto-discovering @types/* packages (types defaults to []).
+        // Seed the types every Bit env installs — @types/node universally and @types/jest
+        // (provides describe/it/expect globals). Don't seed 'mocha': the React env
+        // removes @types/mocha via the `-` convention (see react.env.ts), so seeding it
+        // would make tsc fail to resolve a type package that isn't installed.
+        if (compilerOptions.types === undefined) compilerOptions.types = ['node', 'jest'];
+      }
Evidence
The TS6-compat injection is guarded by if (!tsconfig.extends), but the React env’s workspace
tsconfig uses extends and its base doesn’t define strict/types, so it will bypass the
injection and can still take TS6 defaults when TypeScript loads the config file directly (e.g.,
tsserver/IDE).

scopes/typescript/typescript/typescript.main.runtime.ts[125-157]
scopes/react/react/typescript/tsconfig.cjs.json[1-6]
scopes/react/react/typescript/tsconfig.json[1-20]
scopes/react/react/react.env.ts[606-621]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`TypescriptMain.createCompiler()` patches TS6+ defaults (`strict`, `types`) only when the raw tsconfig does **not** use `extends`. However, the repo’s React env writes `typescript/tsconfig.cjs.json` into workspaces (via `TypescriptConfigWriter`), and that file **does** use `extends` while its base does not define `strict`/`types`. With TS6, that derived config can still end up with strict-by-default and `types=[]`, reintroducing the mismatch this PR is trying to prevent.
## Issue Context
- The patch is skipped whenever `tsconfig.extends` exists.
- `scopes/react/react/typescript/tsconfig.cjs.json` extends `./tsconfig.json` and only overrides `module`.
- `scopes/react/react/typescript/tsconfig.json` doesn’t set `compilerOptions.strict` or `compilerOptions.types`.
- `ReactEnv.workspaceConfig()` writes `tsconfig.cjs.json` as the workspace tsconfig path.
## Fix Focus Areas
- scopes/typescript/typescript/typescript.main.runtime.ts[140-156]
- scopes/react/react/typescript/tsconfig.cjs.json[1-6]
- scopes/react/react/typescript/tsconfig.json[1-20]
- scopes/react/react/react.env.ts[606-621]
## Implementation direction
Pick one (or combine):
1) Make the TS6 patching logic handle `extends` safely: only inject `strict/types` when they are not explicitly set in the *effective* config (consider flattening/merging the extended config before deciding).
2) Alternatively (simpler for the React workspace config writer): add explicit `"strict": false` and an explicit `"types": [...]` to `tsconfig.cjs.json` (or to its base) so TS6 won’t fall back to new defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Remediation recommended
2. Orphan tsserver process 🐞 Bug ☼ Reliability
Description
TsserverClient.init() now rethrows startup failures after setting this.tsServer = null without
killing the underlying ProcessBasedTsServer process. Since ProcessBasedTsServer.start() can reject
after spawning (e.g. on any stderr output) without cleanup, this can leave an orphaned tsserver
process and leak resources.
Code

scopes/typescript/ts-server/ts-server-client.ts[R95-101]

+      // Rethrow so callers know the server didn't come up. Swallowing here would leave
+      // `this.tsServer` set but unusable, and subsequent `request()` calls would silently
+      // return undefined via optional chaining — producing false-clean check-types runs.
    this.logger.error('TsserverClient.init failed', err);
+      this.tsServer = null;
+      this.serverRunning = false;
+      throw err;
Evidence
The new init() error path explicitly nulls this.tsServer and rethrows, but the underlying start()
implementation can reject after spawning without killing the child process, making the leaked
process unreachable for cleanup.

scopes/typescript/ts-server/ts-server-client.ts[60-102]
scopes/typescript/ts-server/process-based-tsserver.ts[172-236]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`TsserverClient.init()` now awaits `ProcessBasedTsServer.start()` and rethrows on failure, but the `catch` block sets `this.tsServer = null` without terminating the spawned child process. If `start()` rejects after spawning (notably when it rejects due to any stderr output), the child process can remain running with no remaining reference to clean it up.
### Issue Context
`ProcessBasedTsServer.start()` rejects on stderr output but does not kill the process or close the readline interface in that path. With the new `init()` flow, the reference is dropped immediately, making cleanup impossible and potentially leaking processes.
### Fix Focus Areas
- scopes/typescript/ts-server/ts-server-client.ts[69-102]
- scopes/typescript/ts-server/process-based-tsserver.ts[172-236]
### Suggested fix
1. In `TsserverClient.init()` catch block, if `this.tsServer` exists, call `this.tsServer.kill()` (or a dedicated `dispose()`), then set it to null.
2. (More robust) In `ProcessBasedTsServer.start()`, on any rejection path after spawning (stderr listener, invalid JSON, etc.), perform cleanup (`kill()`, close readline) before rejecting so callers don’t have to handle partial-start cleanup themselves.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

env tsconfigs are loaded via require() (e.g., react.env.ts:79,
aspect.env.ts:39), which uses Node's JSON parser — no JSONC support.
The TS 7 migration comments added in the previous commit broke
`bit` startup with 'Expected property name in JSON' parse errors,
failing every CI job that boots the bit CLI.

Move the TODOs into the .ts files that load these JSONs instead,
and keep the JSON files pure JSON. The workspace root tsconfig.json
is unchanged because TypeScript parses it as JSONC (comments OK).
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit fbd8b13

Comment on lines +146 to +156
// strict and types: don't inject when the tsconfig extends a base — the base may
// already set these, and an explicit value here would silently override the inherited one.
if (!tsconfig.extends) {
if (compilerOptions.strict === undefined) compilerOptions.strict = false;
// TS 6 stopped auto-discovering @types/* packages (types defaults to []).
// Seed the types every Bit env installs — @types/node universally and @types/jest
// (provides describe/it/expect globals). Don't seed 'mocha': the React env
// removes @types/mocha via the `-` convention (see react.env.ts), so seeding it
// would make tsc fail to resolve a type package that isn't installed.
if (compilerOptions.types === undefined) compilerOptions.types = ['node', 'jest'];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Ts6 patch skips extends 🐞 Bug ≡ Correctness

TypescriptMain.createCompiler() only injects TS6-compat defaults for strict/types when
tsconfig.extends is falsy, so configs that extend a base can still pick up TS6’s new defaults.
React env’s typescript/tsconfig.cjs.json extends typescript/tsconfig.json (which doesn’t set
strict/types), so TS6 can treat it as strict-by-default with no auto-discovered @types, causing
IDE/tsserver errors and mismatches vs Bit’s compiler behavior.
Agent Prompt
## Issue description
`TypescriptMain.createCompiler()` patches TS6+ defaults (`strict`, `types`) only when the raw tsconfig does **not** use `extends`. However, the repo’s React env writes `typescript/tsconfig.cjs.json` into workspaces (via `TypescriptConfigWriter`), and that file **does** use `extends` while its base does not define `strict`/`types`. With TS6, that derived config can still end up with strict-by-default and `types=[]`, reintroducing the mismatch this PR is trying to prevent.

## Issue Context
- The patch is skipped whenever `tsconfig.extends` exists.
- `scopes/react/react/typescript/tsconfig.cjs.json` extends `./tsconfig.json` and only overrides `module`.
- `scopes/react/react/typescript/tsconfig.json` doesn’t set `compilerOptions.strict` or `compilerOptions.types`.
- `ReactEnv.workspaceConfig()` writes `tsconfig.cjs.json` as the workspace tsconfig path.

## Fix Focus Areas
- scopes/typescript/typescript/typescript.main.runtime.ts[140-156]
- scopes/react/react/typescript/tsconfig.cjs.json[1-6]
- scopes/react/react/typescript/tsconfig.json[1-20]
- scopes/react/react/react.env.ts[606-621]

## Implementation direction
Pick one (or combine):
1) Make the TS6 patching logic handle `extends` safely: only inject `strict/types` when they are not explicitly set in the *effective* config (consider flattening/merging the extended config before deciding).
2) Alternatively (simpler for the React workspace config writer): add explicit `"strict": false` and an explicit `"types": [...]` to `tsconfig.cjs.json` (or to its base) so TS6 won’t fall back to new defaults.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

…n for TS 5.x compat

The previous commits tried to make ignoreDeprecations explicit per-file in env tsconfig
JSONs. That broke shipped envs in capsule builds because capsules pin their own TypeScript
(often TS 5.x) and TS 5 rejects the value '6.0' with TS5103.

Restore the conditional runtime injection in createCompiler — it only applies when the
loaded compiler is actually TS 6+, keeping TS 5.x consumers unaffected. Document the
trade-off and the TS 7 migration TODO in the injection block itself.
@qodo-free-for-open-source-projects

qodo-free-for-open-source-projects Bot commented Jun 16, 2026

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3ab3b28

Comment on lines +150 to +158
if (!tsconfig.extends) {
if (compilerOptions.strict === undefined) compilerOptions.strict = false;
// TS 6 stopped auto-discovering @types/* packages (types defaults to []).
// Seed the types every Bit env installs — @types/node universally and @types/jest
// (provides describe/it/expect globals). Don't seed 'mocha': the React env
// removes @types/mocha via the `-` convention (see react.env.ts), so seeding it
// would make tsc fail to resolve a type package that isn't installed.
if (compilerOptions.types === undefined) compilerOptions.types = ['node', 'jest'];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Action required

1. Mocha types excluded 🐞 Bug ≡ Correctness

TypescriptMain.createCompiler() injects compilerOptions.types = ['node','jest'] for TS 6 when
types is unset, which prevents @types/mocha from contributing ambient globals even if it’s
installed. Repo spec files rely on mocha globals (e.g. after()), so TS6 compilation/typecheck
paths using this injected config will fail with missing global names.
Agent Prompt
### Issue description
`TypescriptMain.createCompiler()` conditionally patches TS6+ tsconfigs by setting `compilerOptions.types` to `['node','jest']` when `types` is not provided. In TypeScript, setting `compilerOptions.types` restricts ambient type packages to *only* those listed, which excludes `@types/mocha` globals (`describe`, `it`, `before`, `after`, etc.) even if `@types/mocha` is installed.

This can break TS6 builds/typechecks for mocha-based projects/files.

### Issue Context
- The workspace installs `@types/mocha`.
- The repo contains `.spec.ts` files using mocha globals (e.g. `after()`).

### Fix Focus Areas
- scopes/typescript/typescript/typescript.main.runtime.ts[150-158]

### Suggested fix
When injecting `compilerOptions.types` for TS6, build the list dynamically based on which `@types/*` packages are actually resolvable from the current environment/capsule.

For example:
- Always include `node`.
- Include `jest` only if `@types/jest` is resolvable.
- Include `mocha` only if `@types/mocha` is resolvable.

This preserves TS5-style “auto-discovery” behavior without forcing an unavailable type package (the reason mocha was avoided for the React env).

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants