Skip to content

feat(codemode): add built-in static code validators#9

Open
AntoniTok wants to merge 4 commits into
mattzcarey:codemode-validator-kindle-v2from
AntoniTok:codemode-static-validator
Open

feat(codemode): add built-in static code validators#9
AntoniTok wants to merge 4 commits into
mattzcarey:codemode-validator-kindle-v2from
AntoniTok:codemode-static-validator

Conversation

@AntoniTok

Copy link
Copy Markdown

feat(codemode): add built-in static code validators

Stacked on cloudflare#1750. Base this PR on that branch; it retargets to main once cloudflare#1750 merges.

Summary

  • add two built-in validateCode validators on top of the pluggable API from feat(codemode): add pluggable runtime validators cloudflare/agents#1750
  • syntaxValidator() — reject code that cannot parse (invalid JS, or TS-only syntax the executor can't run)
  • semanticValidator() — reject code that parses but references things that don't exist:
    • unknown connectors: a bare identifier that is not a configured connector, the built-in codemode provider, or an ambient global
    • unknown methods: a call to a method a configured connector does not expose (opt-out via checkMethods: false)
  • detection uses the Oxc parser + semantic analyzer compiled to zero-import WASM (workerd-oxc), so it runs inside the Workers runtime with no external service
  • reject-only, matching feat(codemode): add pluggable runtime validators cloudflare/agents#1750's contract; rejections return bounded, model-actionable diagnostics (message, source location, suggestion)

Why

Generated code currently only fails once the DynamicWorkerExecutor isolate has started, and normalize.ts even swallows its own parse failure and ships unparseable code onward. These validators move the obvious "this cannot run" cases ahead of that cost — no execution is created for code that was never going to run.

API

import {
  createCodemodeRuntime,
  syntaxValidator,
  semanticValidator
} from "@cloudflare/codemode";

const runtime = createCodemodeRuntime({
  ctx: this.ctx,
  executor,
  connectors,
  validators: [syntaxValidator(), semanticValidator()]
});
  • syntaxValidator({ name?, language?: "js" | "ts", maxIssues? }) — parses as JS by default (the executor runs plain JS with no type-strip step)
  • semanticValidator({ name?, allowedGlobals?, checkMethods?, maxIssues? })allowedGlobals lists extra injected identifiers (e.g. custom provider names)

Both are validateCode-only, so per cloudflare#1750 they are not recorded as resume-required.

Notes

  • Ambient globals: the analyzer is per-file with no ambient environment, so it reports JSON/Math/fetch/etc. as unresolved. The validator subtracts a curated set of standard JS + Workers globals (AMBIENT_SANDBOX_GLOBALS) plus the codemode provider.
  • Conservative method checking: only direct <connector>.<method>() and static <connector>["<method>"]() calls on a genuine connector global are checked; local variables that shadow a connector name, dynamic access, and empty-descriptor connectors are skipped to avoid false positives.

Verification

  • pnpm run check — sherif, export checks, oxfmt, oxlint, all 104 projects typecheck
  • pnpm --filter @cloudflare/codemode test
    • 432 unit tests (incl. exhaustive L1/L2A/L2B battery + complex realistic multi-connector programs)
    • 48 durable runtime tests (rejected code returns status: "error", executionId: "", creates no execution; valid code still executes)

New dependency

Adds workerd-oxc to @cloudflare/codemode — prebuilt zero-import .wasm (no native/FFI), same Oxc engine the repo already uses for fmt/lint, active only inside workerd. Flagging per the "ask before adding package dependencies" guideline.

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.

1 participant