chore(lint): reject chained type assertions in package source

Merged
OK
9d ago
+219-32

What and why

  • New repo-local oxlint plugin in scripts/oxlint-plugin/, loaded through jsPlugins. Its one rule, e2e/no-chained-type-assertions, is on for packages/*/src/**.
    • Adapted from dmmulroy/anti-slop (MIT). The license sits next to the rule.
    • The rest of that rule set misfires here: blank-line spacing, the conditional spread that exactOptionalPropertyTypes needs, and blanket typeof/unknown bans.
  • x as unknown as T turns off TypeScript's overlap check. 14 of the 16 hits in src are fixed:
    • internal/ai-trace.ts:225: six casts dropped. The structural event views are now checked against the AI SDK types, as the comment above them claims.
    • agent/error.ts, internal/errors.ts: the cross-realm error guards narrow with in instead of casting.
    • internal/source.ts: stack frame groups are checked instead of cast.
    • oauth/device-code.ts:145: the RFC 8628 poll cast raw JSON to TokenResponse. Both token paths now go through one zod parseTokens in oauth/token-endpoint.ts.
  • Two hits keep the double cast, each with a reasoned disable comment: the phantom RedactedNode brand mint and the EngineHandle built key by key.
  • @oxlint/plugins is a root devDependency pinned to oxlint's version (1.83.0). Dependabot's dev-tooling group moves the two together.
  • Tests are out of scope (195 hits, mostly fakes).
"jsPlugins": [{ "name": "e2e", "specifier": "./scripts/oxlint-plugin/index.ts" }],
"overrides": [{ "files": ["packages/*/src/**"], "rules": { "e2e/no-chained-type-assertions": "error" } }]

Verified

Ran it locally: yes

  • oxlint on a planted (process.env as unknown as { n: number }).n: it fires in packages/e2e/src and stays quiet in packages/e2e/tests.

    packages/e2e/src/planted-lint-probe.ts:1:25: error e2e(no-chained-type-assertions): Chained assertions skip the compiler check. ...
    
  • After type stripping, observation.ts, manifest.ts, read-semantics.ts, ai-trace.ts and openai.ts emit the same JS as main.

  • requestTokens against a local server answering null:

    mainthis branch
    TypeError: Cannot read properties of nullOAuthError FLOW_FAILED
  • Testbed suite on the built packages: 78 passed.

Checklist

  • Changeset added (pnpm changeset) for any change to a published package, or the change is testbed, docs, or CI only.
  • Breaking change: title carries !, the changeset body names what breaks and what replaces it, and the deprecation warning landed a window earlier (stability policy in CONTRIBUTING.md).
  • Docs updated in the same PR: the docs/**/*.mdx page for the behavior, and skills/e2e/ if the skill describes it.
  • Contract change: emitted .d.ts reviewed, tests/types/sdk-types.ts updated; wire change edits the schema and both fixtures.
  • Engine contract change (e2e/engine): changesets for e2e, @e2e-dev/web, and @e2e-dev/mobile.