Skip to content

[chore] Modernize tsconfig + add native TS7 type-check - #5472

Merged
bekossy merged 29 commits into
release/v0.106.1from
ts-chore/native-tsc-trial
Jul 29, 2026
Merged

[chore] Modernize tsconfig + add native TS7 type-check#5472
bekossy merged 29 commits into
release/v0.106.1from
ts-chore/native-tsc-trial

Conversation

@ardaerzin

@ardaerzin ardaerzin commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

Context

TypeScript 7 (the Go-native compiler) went GA on 2026-07-08, ~8-12x faster on large codebases with unchanged type semantics. This PR modernizes the tsconfig so the native compiler runs cleanly, types the CSS side-effect imports it (correctly) requires, and adds an opt-in native type-check script. Both apps stay at 0 errors throughout.

Two of the three parts are production-ready changes that stand on their own; the third is an opt-in dev tool. None of it touches the enforced toolchain.

Changes

1. tsconfig modernization (oss/tsconfig.json, ee/tsconfig.json). Switched to the relative-paths, no-baseUrl form:

"baseUrl": ".",
"paths": { "@/oss/*": ["src/*", ...] }        // before
"paths": { "@/oss/*": ["./src/*", ...] }       // after (baseUrl removed)

This is the modern standard form. Classic TS 5.9 accepts it (paths resolve relative to the tsconfig dir when there's no baseUrl), and it is also what TS7 requires — 7.0 removed baseUrl (TS5102) and rejects non-relative path values (TS5090). So one change satisfies both compilers.

2. CSS side-effect import typing (oss/css-modules.d.ts, ee/css-modules.d.ts). Added ambient *.css declarations per app, mirroring the existing packages/css-modules.d.ts. TS7 requires a declaration for import "x.css" (TS2882); classic tolerated it under moduleResolution: bundler. Additive and harmless to classic.

3. Opt-in native type-check. Added @typescript/native-preview (pinned) — the isolated tsgo binary. It does NOT replace the typescript@5.9 package, so typescript-eslint and next build resolve the classic compiler exactly as before. New scripts: type-check:native (tsgo) and type-check (classic — there wasn't a standalone one; type-checking only ran via next build).

The measurement

OSS, full check to zero errors: 18.1s classic → 3.7s native (~4.9x). EE native 4.3s. Less than Microsoft's headline 12x, which is on very large codebases; this is a mid-size app.

Verification (all green)

Check OSS EE
native tsgo 0 0
classic tsc 0 0
next build exit 0, types validated
lint (typescript-eslint) exit 0

The next build and lint passes are the important ones: they prove removing baseUrl does not disturb Next's own module resolver or typescript-eslint's parser, both of which read this tsconfig.

Deferred (not in this PR)

Making native the enforced gate — CI, pre-commit, and next build's internal type-check.

The hard blocker is typescript-eslint: TS7.0 shipped without a stable programmatic API (7.1 will add a new one), and npm refuses to install typescript-eslint alongside typescript@7 at all (ERESOLVE — its peer range caps below 6.1.0). So the lint job cannot move to native until 7.1. Microsoft's bridge for this transition is @typescript/typescript6 (a tsc6 binary re-exporting the 6.0 API) — see Announcing TypeScript 7.0 and typescript-eslint#12518.

Whether next build's internal type-check is also blocked is unverified — it depends on whether Next consumes the programmatic API or shells out to the tsc binary, which I did not confirm. Either way, typescript-eslint alone is sufficient reason to keep native off the enforced gate for now. This PR makes the later flip a small change; it does not attempt it.

One preview caveat: the isolated tsgo binary is currently only distributed via the nightly @typescript/native-preview channel (post-GA, the stable native compiler ships as typescript@7, whose tsc bin would collide with typescript@5.9). It's pinned to an exact version, and it sits outside every build path, so the blast radius is a local script.

Tests / notes

What to QA

Nothing user-facing. For a reviewer: cd web && pnpm type-check (classic, 0 errors) and pnpm type-check:native (tsgo, 0 errors) both pass; pnpm build-oss still succeeds.

ardaerzin added 17 commits July 22, 2026 03:13
The playwright suites are owned and type-checked by the tests workspace,
which holds the @playwright/test dependency; tests/manual scripts import
state modules that no longer exist.
- Restore Parameter, CorrectAnswer and _EvaluationScenario to lib/Types.ts
  (removed by cleanup while consumers remained)
- Re-export MetricColumnDefinition from the EvalRunDetails table barrel
- TooltipButtonProps was renamed EnhancedButtonProps; statusMap moved to
  @agenta/entity-ui/variant
- Synthesize full Parameter objects in UseApiContent
- useRunMetricData: type selection as the unwrapped value, not the atom
- Webhook builders: narrow WebhookFormValues union before field access
- filtersAtom: accept updater functions in the write signature
- Organization settings: drop stale react-query v4 useErrorBoundary and
  migrate setQueriesData to the v5 filters shape
- evaluations/utils: surface variantId from invocation metadata
- PreviewTableRow: add index signature required by InfiniteTableRowBase
Mirrors the vetted WP-4e-2a in-place fixes from fe-chore/move-evals-to-packages
(adapted to OSS import paths) plus new fixes for the component layer:

- restore PreviewTestCase to lib/Types; re-export MetricProcessor/MetricScope
- add "input" to EvaluationColumnKind (backend mapping emits it) and type the
  visibility-label column extension in buildPreviewColumns
- recharts v3 API drift in EvaluatorMetricsChart (TooltipContentProps, tuple
  radius, MetricStripEntry contextual typing)
- widen evaluationType to EvaluationRunKind; type query atoms as nullable
- latent runtime bugs typed as-is per WP-4e-2a convention (applyAggregatesToRaw,
  metricProcessor ReferenceErrors, dead metric-group branches) - flagged, not fixed
…ant id

- createPaginatedEntityStore: refreshAtom/actions.refresh accept an optional
  value or updater (bare set() still bumps the counter) - clears the
  'Expected 0 arguments' cluster across testset modals and other consumers
- EnvironmentStatus: variant.id optional; the component already guards it
…ing layers; oss tsc 347->105

Parallel per-area pass, behavior-preserving throughout (latent runtime bugs are
typed as-is with NOTE comments per the WP-4e-2a convention, not silently fixed):

- TraceSpanNode OSS<->entities dual-type: aligned at every crossing with
  documented boundary casts (16 errors -> 0); annotations field added to the
  OSS node (drawer stores attach it at runtime)
- SharedDrawers: broken SessionDrawerButton imports repaired, JSON-schema
  access typed, null-safety in SelectEvaluators/AnnotateDrawer, drawer
  payload/ref/label types aligned with runtime
- observability: extended-column types for custom antd props, TraceRow/
  SessionRow InfiniteTableRowBase conformance, traceTabsAtom updater support,
  ag-attributes selector typing at the producer
- playground/url-state: removed drifted local duplicates of package types,
  eagerAtom->atom where deps are sync, modal/store prop alignment
- onboarding/testsets/org: updater-widened widget UI atom, tour placement
  vocabulary fix, OnboardingLoader next/dynamic compat, org provider API
  types matched to the backend wire shape (settings/flags dicts)
- EvalRunDetails remainder: WP-4e-2a-vetted atom fixes adapted, recharts v3
  formatter/content signatures, stale import paths repointed

Flagged for triage (typed as-is): AddToTestsetDrawer trace draft discard/
update call missing molecule actions; orphaned SessionDrawerButton
…atterns; oss tsc 105->82

- InfiniteVirtualTable: canonical ExtendedColumnType exported from the barrel
  (three local extended-column copies repointed as aliases); pure read fn for
  columnHiddenKeys (write path reconciles versions); memo generic preservation;
  onRow/getRowProps/rowSelection.fixed aligned with antd 6
- antd v6 PopoverStylesType 'body' drops typed as-is (2 sites, existing pattern)
- React 19: JSX.Element -> ReactElement in RequireWorkflowKind
- AgentaNodeDTO: trace_id/span_id added (backend SpanDTO sends them)
- Org.default_workspace: list endpoint strips it - both lookups are latent
  dead code, typed as-is with comments
- FiltersPreview: operatorLabel is a display string, not the operator union
…windowing export

- DrillInUIContext: EditorProvider/SharedEditor slots typed with the real
  component prop types instead of a hand-written subset (root cause of the
  OSS provider assignment errors)
- InfiniteVirtualTable: rowSelection.fixed accepts antd FixedType; locale
  accepted (not yet forwarded - flagged); Editor barrel exports CodeLanguage
- workflow barrel exports WorkflowRevisionWindowing
Wave-2 parallel pass over the final ~105 OSS + 11 EE-only errors, behavior-
preserving throughout (latent bugs typed as-is with NOTE comments per the
WP-4e-2a convention):

- Evaluators/Evaluations: generic evaluator filtering, chart datum typing
- pages/evaluations: NewEvaluation modal props retyped to entities-package
  shapes (stale legacy Types imports dropped); antd 6 tabPlacement vocabulary
- Testcases/Testsets/Deployments: canonical ExtendedColumnType adoption,
  dataset-store variance via Pick<...,'hooks'>
- DrillInView/EditorViews: TMode narrowing via consts, Format|CodeLanguage
  state union, html format menu typing
- app-shell misc: services/state/pages sweep with backend-verified API types
- EE Billing + misc EE-only files

Latent bugs surfaced and typed as-is (chips filed where actionable):
workspace rename sends invalid org PATCH body; SessionInspector reads
status.code the backend never sends; axios.isCancel dead on created
instance; invite accept can interpolate undefined ids
Both apps are at zero tsc errors; flip ignoreBuildErrors to false so
next build guards the baseline. Verified: full oss and ee builds pass
with the gate on.
The OSS tracing module declared its own TraceSpan/TraceSpanNode plus four
TypeScript enums that mirrored the zod schemas in @agenta/entities. The two
were structurally equivalent but nominally incompatible, so every crossing
needed a cast (7 of them, added in #5464 as documented scar tissue).

- oss/src/services/tracing/types now owns only TraceSpanNode (entities node
  plus the annotations the drawer stores attach) and GenerationDashboardData;
  consumers import span types from @agenta/entities/trace directly, per the
  app-layer no-re-export rule
- 25 enum value usages become string literals; StatusCode values were already
  identical, SpanCategory differed only in the catch-all
- all 7 boundary casts removed

Fixes a live crash: AGE-3788 canonicalised the backend catch-all from
"undefined" to "unknown", but spanTypeStyles was still keyed "undefined" and
both consumers destructure the lookup, so any span typed "unknown" threw a
TypeError in the observability table and trace tree. The record is now keyed
by SpanCategory (exhaustive, so a new backend category fails the build) with a
fallback at both call sites.

Nullability now matches the payload: entities declares | null where the
backend sends null, so NodeNameCell/StatusRenderer/TimestampCell props and
ScannedExportRow were widened rather than cast.
…e shape

usePreviewEvaluations declared its own EvaluationRun while
@agenta/entities/evaluationRun already had the canonical zod-derived one.
The local copy over-declared requiredness (name/description/status/meta/flags
as non-null) where the schema says the backend can send null, so #5464 had to
hand-add updated_at to keep it current. Deleted it; the two importers and the
hook now take the type from the package.

Swapping surfaced drift inside @agenta/entities itself: the step-reference
shape was redeclared three times with different types. The core zod schema has
{id, slug?: string|null, version?: number|null}, while the ETL RunStep said
slug?: string and version?: STRING, and ColumnGroup.refs said id?: string.
Both now reference the exported EvaluationRunStepReference from the validated
schema. CandidateRun.status widened to match.

Scoped out, with reasons:
- PreviewTestset is NOT the entities Testset (different endpoint shape: it
  carries slug plus embedded data.testcases; entities Testset is lean
  metadata). PreviewTestCase does match Fern TestcaseOutput, but entities has
  no canonical testcase entity type to route it through yet.
- OrganizationProvider has no entities domain at all, and the response settings
  is a free-form dict while Fern's SsoProviderSettingsDto models create-input.
  Creating a domain for one interface is disproportionate.
Prep for retiring the duplicate InfiniteVirtualTable in oss/src/components
(55 files, a strict subset of the 67-file @agenta/ui copy).

The two copies had grown parallel abstractions for the same concept: the
package's ExtendedColumn/ExtendedColumnProps and an ExtendedColumnType added
to the OSS copy. Their bases were already equivalent (ColumnsType[number] IS
ColumnType | ColumnGroupType), so the package type just gained the three props
it lacked (defaultHidden, maxWidth, exportEnabled) and the OSS type is now an
alias of it.

Three files imported BOTH copies at once (TestcasesTableShell,
getObservabilityColumns, getSessionColumns); each needed only the column type
from the OSS side, so they now take it from the package. No file imports both
copies anymore.
…ta/ui

The library existed twice: 55 files in oss/src/components/InfiniteVirtualTable
(a strict subset) and the canonical 67-file copy in @agenta/ui. Fixes to
either had to be applied to both — this session alone hit that with the
rowSelection.fixed widening and the ExtendedColumnType consolidation.

- Migrated all 33 app consumers from @/oss/components/InfiniteVirtualTable to
  @agenta/ui/table (the barrel already re-exported every symbol they used).
- Deleted the 55-file OSS copy.
- Package exports ColumnVisibilityNodeMeta / ColumnVisibilityNodeMetaResolver
  (needed by a migrated consumer).

Preserved the export permission gate. The retired OSS shell computed
exportEnabled = enableExport && canExportData internally; the package shell has
no permission check and defaults enableExport=true. The two consumers that
relied on the implicit gate (EvalRunDetails/Table.tsx,
EvaluationRunsTablePOC/.../EvaluationRunsTable/index.tsx) now pass
enableExport={canExportData} explicitly. tsc could not have caught this — both
sides are boolean.

TestsetsTable needed two behavior-preserving adjustments where the package
types are wider: String(record.key) at two Set<string>/string[] lookups (keys
are UUIDs, so a no-op) and 'as never' on the invariant datasetStore generic
(mirrors DeploymentsTable).
@vercel

vercel Bot commented Jul 23, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
agenta-documentation Ready Ready Preview, Comment Jul 29, 2026 3:24pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 23, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: c05e030b-d980-484e-a19c-39ee1633261d

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch ts-chore/native-tsc-trial

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Two production-ready changes plus an opt-in fast type-checker, stacked on the
tsc-cleanup work. Both apps stay at 0 errors throughout.

1. tsconfig modernization (real change, toolchain-neutral). Switched oss/ee to
   the relative-paths, no-baseUrl form. This is the modern standard: classic
   TS 5.9 accepts it, and it is also what TS7 REQUIRES (it removed baseUrl --
   TS5102 -- and disallows non-relative path values -- TS5090).

2. CSS side-effect import typing (real change, additive). Added css-modules.d.ts
   per app, mirroring packages/css-modules.d.ts, so asset imports are typed.
   TS7 needs this (TS2882); classic tolerated untyped CSS under
   moduleResolution:bundler.

3. Opt-in native type-check. Adds @typescript/native-preview (the isolated tsgo
   binary -- does NOT replace typescript@5.9, so typescript-eslint and next build
   are untouched) and a type-check:native script. Usable today for a faster
   local loop: OSS check-to-zero 18.1s (classic) -> 3.7s (native), ~4.9x.
   Also adds a plain type-check (classic) script; there wasn't one.

Verified all four gates green with these changes:
  native tsgo: oss 0, ee 0    classic tsc: oss 0, ee 0
  next build oss: exit 0 (Next resolver handles no-baseUrl)
  lint oss (typescript-eslint): exit 0

Deferred (not in this PR): making native the ENFORCED gate (CI/pre-commit/next
build). The hard blocker is typescript-eslint: TS7.0 shipped without a stable
compiler API (7.1 will add one), and npm refuses to install typescript-eslint
alongside typescript@7 at all (ERESOLVE) -- so flipping the lint job to native
is not yet possible. Whether next build's internal type-check is also blocked
is unverified: it depends on whether Next consumes the programmatic API or
shells out to the tsc binary. This PR does not touch either gate; it makes the
later flip a small change and measures the win now.
@ardaerzin
ardaerzin force-pushed the ts-chore/native-tsc-trial branch 2 times, most recently from 9c0b856 to 6e344f2 Compare July 23, 2026 19:41
Prep for retiring the duplicate InfiniteVirtualTable in oss/src/components
(55 files, a strict subset of the 67-file @agenta/ui copy).

The two copies had grown parallel abstractions for the same concept: the
package's ExtendedColumn/ExtendedColumnProps and an ExtendedColumnType added
to the OSS copy. Their bases were already equivalent (ColumnsType[number] IS
ColumnType | ColumnGroupType), so the package type just gained the three props
it lacked (defaultHidden, maxWidth, exportEnabled) and the OSS type is now an
alias of it.

Three files imported BOTH copies at once (TestcasesTableShell,
getObservabilityColumns, getSessionColumns); each needed only the column type
from the OSS side, so they now take it from the package. No file imports both
copies anymore.
…ta/ui

The library existed twice: 55 files in oss/src/components/InfiniteVirtualTable
(a strict subset) and the canonical 67-file copy in @agenta/ui. Fixes to
either had to be applied to both — this session alone hit that with the
rowSelection.fixed widening and the ExtendedColumnType consolidation.

- Migrated all 33 app consumers from @/oss/components/InfiniteVirtualTable to
  @agenta/ui/table (the barrel already re-exported every symbol they used).
- Deleted the 55-file OSS copy.
- Package exports ColumnVisibilityNodeMeta / ColumnVisibilityNodeMetaResolver
  (needed by a migrated consumer).

Preserved the export permission gate. The retired OSS shell computed
exportEnabled = enableExport && canExportData internally; the package shell has
no permission check and defaults enableExport=true. The two consumers that
relied on the implicit gate (EvalRunDetails/Table.tsx,
EvaluationRunsTablePOC/.../EvaluationRunsTable/index.tsx) now pass
enableExport={canExportData} explicitly. tsc could not have caught this — both
sides are boolean.

TestsetsTable needed two behavior-preserving adjustments where the package
types are wider: String(record.key) at two Set<string>/string[] lookups (keys
are UUIDs, so a no-op) and 'as never' on the invariant datasetStore generic
(mirrors DeploymentsTable).
@ardaerzin
ardaerzin force-pushed the ts-chore/table-consolidation branch from 1b3be94 to 5ca6ce1 Compare July 29, 2026 12:32
ardaerzin and others added 3 commits July 29, 2026 15:35
…trial

Resolves conflicts from #5464/#5465 landing upstream: this branch carried
pre-review copies of the same span-type consolidation. Took the merged
versions of services/tracing/types and exportMatchingTraces, and accepted
the upstream deletion of the dead SessionDrawerButton.
@ardaerzin
ardaerzin changed the base branch from ts-chore/table-consolidation to release/v0.106.1 July 29, 2026 13:06
@ardaerzin
ardaerzin marked this pull request as ready for review July 29, 2026 13:08
@dosubot dosubot Bot added size:S This PR changes 10-29 lines, ignoring generated files. dev experience Improvement of the experience using the software. For instance better error messaging typescript labels Jul 29, 2026
@dosubot dosubot Bot added the lgtm This PR has been approved by a maintainer label Jul 29, 2026
@bekossy
bekossy merged commit 73f4165 into release/v0.106.1 Jul 29, 2026
9 of 11 checks passed
@github-actions

Copy link
Copy Markdown
Contributor

Railway Preview Environment

Preview URL https://gateway-production-265f.up.railway.app/w
Project agenta-oss-pr-5472
Image tag pr-5472-289123d
Status Deployed
Railway logs Open logs
Workflow logs View workflow run
Updated at 2026-07-29T15:38:34.160Z

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

Labels

dev experience Improvement of the experience using the software. For instance better error messaging lgtm This PR has been approved by a maintainer size:S This PR changes 10-29 lines, ignoring generated files. typescript

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants