70bf21e064
Deploy (to testing) and Test Playground Preview Worker / Deploy Playground Preview Worker (testing) (push) Has been skipped
Deploy Workers Shared Staging / Deploy Workers Shared Staging (push) Failing after 0s
Prerelease / build (push) Has been skipped
Handle Changesets / Handle Changesets (push) Has been cancelled
Semgrep OSS scan / semgrep-oss (push) Has been cancelled
4.9 KiB
4.9 KiB
Wrangler — Agent Guide
Wrangler-specific context only. See root AGENTS.md for monorepo conventions.
Overview
Main CLI for Cloudflare Workers. ~2k-line yargs command tree in src/index.ts. Entry point is src/cli.ts (NOT src/index.ts).
Structure
src/— CLI sourcesrc/__tests__/— Unit tests, helpers insrc/__tests__/helpers/e2e/— E2E tests, requires Cloudflare credentialsbin/wrangler.js— Shim that spawns Node to runwrangler-dist/cli.js, forwarding stdio and IPCbin/cf-wrangler.js—cf-wranglerdelegate entrypoint. Owns verb dispatch, argv parsing (parseCfWranglerArgs), and theStartDevOptionsliteral; hands off torunCfWranglerDevfromwrangler-dist/cli.jsin-process (no re-spawn — the parent tool owns the Node runtime)src/cf-wrangler/— Thecf-wranglerdelegate entrypoint (see below)templates/— Worker templates
Entry Points
src/cli.ts— Build entry AND library API surface (dual-purpose). Callsmain()when run directly; re-exports./apiwhen imported as library. Also re-exportsparseCfWranglerArgs,parseCfWranglerBuildArgs,ArgParseError,runCfWranglerDev, andrunCfWranglerBuildfor thecf-wranglerbin to call in-process.src/index.ts— Yargs CLI tree builder (large file). Exportsmain(). NOT the package entry point despite the name.src/api/index.ts— Public programmatic API barrel.src/cf-wrangler/— Thecf-wranglerdelegate entrypoint, an experimental escape hatch for projects that can't use@cloudflare/vite-plugin. It exposesdev+ four flags (--mode,--port,--host,--local) andbuild+--mode; the wrangler config file is found via wrangler's standard discovery (no--configflag). It is NOT a separate package and does NOT use theunstable_devtest harness. It shares its spawn contract (verb dispatch, flag vocabulary, exit-2 feature detection) with the siblingcf-vitedelegate in@cloudflare/vite-plugin.bin/cf-wrangler.jsowns verb dispatch, argv parsing, and theStartDevOptionsliteral;src/cf-wrangler/dev.ts(exported asrunCfWranglerDev) wrapsstartDevin the experimental-flags context and waits for teardown.src/cf-wrangler/build.ts(exported asrunCfWranglerBuild) runs the Build Output API path used bywrangler build --experimental-new-config --experimental-cf-build-output, producing.cloudflare/output/v0.src/cf-wrangler/args.ts(exported asparseCfWranglerArgs,parseCfWranglerBuildArgs, andArgParseError) does the strict argv parse. The "unknown subcommand" error doubles as a feature-detection signal for the parent CLI.
Conventions (Wrangler-Specific)
- No
console.*— useloggersingleton - No
__dirname/__filename— usegetBasePath() - No global
fetch— use undici's fetch - No direct Cloudflare REST API calls — use the Cloudflare TypeScript SDK
telemetryMessagevalues forUserError-compatible errors must be static, safe labels. Do not usetelemetryMessage: trueunless the user-facing message cannot include user input, file paths, resource names, IDs, secret names, raw API messages, or command input. Even when safe,telemetryMessage: trueis usually less useful because user-facing copy is harder to group and parse than a stable telemetry label.- Format
telemetryMessagevalues as lower-case phrases:<service or area> <command or sub-area> <failure>, for examplekv namespace binding not found in config,r2 object put file not found, orpages deploy project name missing. - Keep the service/area first and the failure last so telemetry groups consistently. Prefer stable categories over user-facing copy; telemetry labels should not change just because CLI wording changes.
Build
- tsup: single entry
src/cli.ts→wrangler-dist/cli.js package.jsonmainpoints atwrangler-dist/cli.js- Custom
embedWorkersPlugin()bundles Worker templates via esbuild for tests
Testing
- Pool:
"forks"(not threads) — heavy global mocking runWrangler(cmd)callsmain()in-process (no subprocess)- MSW for API mocking — pre-built handlers per API domain in
src/__tests__/helpers/msw/ - Shared helpers:
runInTempDir(),mockAccountId(),mockApiToken(),mockConfirm(),mockPrompt(),mockSelect(),captureRequestsFrom() - Unit timeout: 50s, retry: 0. Note: wrangler's
vitest.config.mtsdoes NOT usemergeConfigwithvitest.shared.ts, so shared defaults (timeouts, retry, etc.) are not inherited — they must be set explicitly in the wrangler config. - E2E timeout: 90s, bail: 1, singleThread
globals: truefor vitest globals- Output normalization via
normalizeString()pipeline
Anti-Patterns
- Test files use
.test.ts(not.spec.ts) - Never import
expectfrom vitest — use test context({ expect }) => {}- When adding
expectas a parameter to helper functions, check ALL call sites (e.g., acrossdeployments.test.ts,versions.test.ts)
- When adding