{"owner":"cloudflare","repo":"workers-sdk","hasSkills":true,"hasMcp":false,"mcpConfig":null,"found":["AGENTS.md","CLAUDE.md"],"skills":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to AI coding agents working in this repository.\n\n## Project Overview\n\nThis is the **Cloudflare Workers SDK** monorepo containing tools and libraries for developing, testing, and deploying applications on Cloudflare. The main components are Wrangler (CLI), Miniflare (local dev simulator), and Create Cloudflare (project scaffolding).\n\n## Development Commands\n\n**Package Management:**\n\n- Use `pnpm` - never use npm or yarn\n- `pnpm install` - Install dependencies for all packages\n- `pnpm build` - Build all packages (uses Turbo for caching)\n\n**Testing:**\n\n- `pnpm test:ci` - Run tests in CI mode\n- `pnpm test:e2e` - Run end-to-end tests (requires Cloudflare credentials)\n- `pnpm test -F <package> \"pattern\"` - Run a single test by name pattern\n\n**Code Quality:**\n\n- `pnpm check` - Run all checks (lint, type, format)\n- `pnpm fix` - Auto-fix linting issues and format code\n\n**Working with Specific Packages:**\n\n- `pnpm run build --filter <package-name>` - Build specific package\n- `pnpm run test:ci --filter <package-name>` - Test specific package\n- `pnpm --filter <package> test:watch` - Watch mode for a specific package\n\n## Architecture Overview\n\n**Core Tools:**\n\n- `packages/wrangler/` - Main CLI tool for Workers development and deployment\n- `packages/miniflare/` - Local development simulator powered by workerd runtime\n- `packages/create-cloudflare/` - Project scaffolding CLI (C3)\n- `packages/vite-plugin-cloudflare/` - Vite plugin for Cloudflare Workers\n\n**Development & Testing:**\n\n- `packages/vitest-pool-workers/` - Vitest integration for testing Workers in actual runtime\n- `packages/chrome-devtools-patches/` - Modified Chrome DevTools for Workers debugging\n\n**Shared Libraries:**\n\n- `packages/pages-shared/` - Code shared between Wrangler and Cloudflare Pages\n- `packages/workers-shared/` - Code shared between Wrangler and Workers Assets\n- `packages/workers-utils/` - Utility package for common Worker operations\n- `packages/workflows-shared/` - Internal Cloudflare Workflows functionality\n- `packages/containers-shared/` - Shared container functionality\n- `packages/unenv-preset/` - Cloudflare preset for unenv (Node.js polyfills)\n- `packages/cli/` - SDK for building workers-sdk CLIs\n- `packages/kv-asset-handler/` - KV-based asset handling for Workers Sites\n\n**Build System:**\n\n- Turbo (turborepo) orchestrates builds across packages\n- TypeScript compilation with shared configs in `packages/workers-tsconfig/`\n- Shared lint config in `packages/lint-config-shared/`\n- Dependency management via pnpm catalog system\n\n## WHERE TO LOOK\n\n| Task                                           | Location                                                              | Notes                                                                                                                                                                        |\n| ---------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Add/modify a CLI command                       | `packages/wrangler/src/`                                              | Commands registered in `src/index.ts` (2k+ line yargs tree)                                                                                                                  |\n| Change local dev behavior                      | `packages/miniflare/src/`                                             | `src/index.ts` is the main `Miniflare` class                                                                                                                                 |\n| Modify Workers runtime simulation              | `packages/miniflare/src/workers/`                                     | ~30 embedded worker scripts, built via `worker:` virtual imports                                                                                                             |\n| Add a test fixture                             | `fixtures/`                                                           | Each fixture is a full workspace member with own `package.json`                                                                                                              |\n| Shared config types/validation                 | `packages/workers-utils/src/config/`                                  | `validation.ts` is the config normalizer (large file)                                                                                                                        |\n| Test helpers (runInTempDir, seed, mockConsole) | `packages/workers-utils/src/test-helpers/`                            | Shared across wrangler, miniflare, others                                                                                                                                    |\n| Cloudflare API mocks for tests                 | `packages/wrangler/src/__tests__/helpers/msw/`                        | MSW handlers per API domain                                                                                                                                                  |\n| CI workflows                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the primary gate                                                                                                                                     |\n| Build/deploy scripts                           | `tools/deployments/`                                                  | Validation + deployment helpers, run via `esbuild-register`                                                                                                                  |\n| Deploy/versions-upload validation              | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | `validateWorkerProps()` for sync checks, `preUploadApiChecks()` for API checks (service metadata, config diff, secrets, workflows). All new pre-upload validation goes here. |\n| Changeset config and rules                     | `.changeset/README.md`                                                | Must read before creating changesets                                                                                                                                         |\n\n## Development Guidelines\n\n**Requirements:**\n\n- Node.js >= 20\n- pnpm\n\n**Code Style:**\n\n- TypeScript with strict mode\n- Use `import type { X }` for type-only imports (`@typescript-eslint/consistent-type-imports`)\n- No `any` (`@typescript-eslint/no-explicit-any`)\n- No non-null assertions (`!`)\n- No floating promises - must be awaited or explicitly voided (`@typescript-eslint/no-floating-promises`)\n- Always use curly braces for control flow (`curly: error`)\n- Use `node:` prefix for Node.js imports (`import/enforce-node-protocol-usage`)\n- Prefix unused variables with `_`\n- No `.only()` in tests (`no-only-tests/no-only-tests`)\n- Prefer `function` declarations over `const` arrow function assignments for named/exported functions\n- ESLint disable comments must use double-dash separator: `// eslint-disable-next-line rule-name -- reason here`\n- Never modify generated files directly — modify the generator or config, then regenerate\n- Format with oxfmt - run `pnpm prettify` in the workspace root before committing\n- All changes to published packages require a changeset (see below)\n\n**Formatting (oxfmt):**\n\n- Tabs (not spaces), double quotes, semicolons, trailing commas (es5)\n- Import order enforced: builtins → third-party → parent → sibling → index → types\n- `sortPackageJson` option sorts package.json keys\n\n**Security:**\n\n- Custom ESLint rule `workers-sdk/no-unsafe-command-execution`: no template literals or string concatenation in `exec`/`spawn`/`execFile` calls (command injection prevention, CWE-78). Disabled in test files only.\n\n**Dependencies:**\n\n- Packages must bundle deps into distributables; runtime `dependencies` are forbidden except for an explicit allowlist\n- External (non-bundled) deps must be declared in `scripts/deps.ts` with `EXTERNAL_DEPENDENCIES` and a comment explaining why\n- After updating dependencies, always run `pnpm i` to also update the package lock file\n\n**Testing Standards:**\n\n- Unit tests with Vitest for all packages\n- Fixture tests in `/fixtures` directory for filesystem/Worker scenarios\n- E2E tests require real Cloudflare account credentials\n- Use `vitest-pool-workers` for testing actual Workers runtime behavior\n- Shared vitest config (`vitest.shared.ts`): 50s timeouts, `retry: 1`, `restoreMocks: true`\n- Vitest 4 pool config: use `maxWorkers: 1` instead of the removed `poolOptions.forks.singleFork: true` when tests must run sequentially\n- **`expect` must come from test context** — never `import { expect } from \"vitest\"`:\n  - Use destructured test context: `it(\"name\", ({ expect }) => { ... })`\n  - For helper functions that need `expect`, pass it as a parameter with type `ExpectStatic`\n  - Always use `import type` for `ExpectStatic`: `import { beforeAll, type ExpectStatic, test } from \"vitest\"`\n  - When test context is unavailable (e.g. setup files), use `node:assert` instead\n  - E2E vitest configs do NOT set `globals: true` — this rule is critical there; forgetting `{ expect }` in the callback causes `ReferenceError` at runtime\n- When changing user-facing strings or output messages, update corresponding test snapshots\n- New test fixtures in `vitest-pool-workers-examples/` must include a `tsconfig.json`\n- Test fixtures serve as user-facing recipes — use clean patterns, avoid type casting where possible\n- Use the `runInTmpDir()` utility instead of mocking filesystem operations. Real filesystem operations are preferred over mocking. The utility creates isolated temporary directories, handles cleanup automatically in `afterEach` hooks, and allows tests to write actual files and assert against them\n- Use the `mockConsoleMethods()` helper to capture stdout/stderr. Use the pattern `const std = mockConsoleMethods()` in test setup, then access captured output via `std.out`, `std.err`, `std.warn` properties. Assert against captured output using `expect(std.out).toMatchInlineSnapshot()`\n- Run specific wrangler test files locally using `pnpm -w test:ci -F wrangler -- [test-file-name]` (e.g. `pnpm -w test:ci -F wrangler -- r2.test.ts`)\n\n**Git Workflow:**\n\n- Check you are not on main before committing. Create a new branch for your work from main if needed.\n- Clean commit history required before first review\n- Don't squash commits after review\n- Never commit without changesets for user-facing changes\n- PR template requirements: Remove \"Fixes #...\" line when no relevant issue exists, keep all checkboxes (don't delete unchecked ones)\n\n**Creating Pull Requests:**\n\n- Always use the PR template from `.github/PULL_REQUEST_TEMPLATE.md` - do not replace it with your own format\n- Fill in the template: replace the issue link placeholder, add description, check appropriate boxes\n- Keep all checkboxes in the template (don't delete unchecked ones)\n- PR title format: `[package name] description` (e.g. `[wrangler] Fix bug in dev command`)\n- If the change doesn't require a changeset, add the `no-changeset-required` label\n- CI validates the PR description (see `tools/deployments/validate-pr-description.ts`). The description **must** include:\n  - A checked (`[x]`) test checkbox — either \"Tests included/updated\", or one of the justification checkboxes with a non-empty explanation\n  - A checked (`[x]`) documentation checkbox — either a Cloudflare docs PR/issue link, or \"Documentation not necessary because:\" with a non-empty explanation\n  - A changeset file (or the `no-changeset-required` label)\n\n**Pre-Submission Checklist:**\n\n- Run `pnpm check` (lint + type-check + format) locally before pushing — do not rely on CI to catch lint errors\n- Run `pnpm prettify` to ensure formatting is correct\n\n## Key Locations\n\n- `/fixtures` - Test fixtures and example applications (each a workspace member)\n- `/packages/wrangler/src` - Main Wrangler CLI source code\n- `/packages/miniflare/src` - Miniflare source\n- `/tools` - Build scripts and deployment utilities (run via `esbuild-register`, no build step)\n- `turbo.json` - Turbo build configuration\n- `pnpm-workspace.yaml` - Workspace configuration (~156 workspace members)\n\n## Testing Strategy\n\n**Package-specific tests:** Most packages have their own test suites\n**Integration tests:** Use fixtures to test real-world scenarios\n**E2E tests:** Test against actual Cloudflare services (requires auth)\n**Workers runtime tests:** Use vitest-pool-workers for workerd-specific behavior\n\nRun `pnpm check` before submitting changes to ensure all quality gates pass.\n\n## Changesets\n\nEvery change to package code requires a changeset or it will not trigger a release. Read `.changeset/README.md` before creating changesets.\n\n**Changeset Format:**\n\nThe changeset descriptions can either use conventional commit prefixes (e.g., \"fix: remove unused option\") or\nstart with a capital letter and describe the change directly (e.g., \"Remove unused option\" not\").\n\n**Changeset Rules:**\n\n- Major versions for `wrangler` are currently **forbidden**\n- `patch`: bug fixes; `minor`: new features, deprecations, experimental breaking changes; `major`: stable breaking changes only\n- No h1/h2/h3 headers in changeset descriptions (changelog uses h3)\n- Config examples must use `wrangler.json` (JSONC), not `wrangler.toml`\n- Separate changesets for distinct changes; do not lump unrelated changes\n- Focus on user-facing impact; reference the public-facing package, not internal implementation packages\n- If the change collects more analytics, it should be a minor even though there is no user-visible change\n\n## Anti-Patterns\n\nThese are explicitly forbidden across the repo:\n\n- **npm/yarn** → use pnpm\n- **`any` type** → properly type everything\n- **Non-null assertions (`!`)** → use type narrowing\n- **Floating promises** → await or void explicitly\n- **Missing curly braces** → always brace control flow\n- **`console.*` in wrangler** → use the `logger` singleton\n- **Direct Cloudflare REST API calls** → use the Cloudflare TypeScript SDK\n- **Named imports from `ci-info`** → use default import (`import ci from \"ci-info\"`)\n- **Runtime dependencies** → bundle deps; external deps need explicit allowlist entry\n- **Committing to main** → always work on a branch\n- **Trivial/obvious code comments** → don't add comments that restate what the code does; comments should explain \"why\", not \"what\"\n- **Duplicating types/constants across packages** → export from the owning package and import where needed\n\n## Subdirectory Knowledge\n\nPackages with their own AGENTS.md for deeper context:\n\n- `packages/wrangler/AGENTS.md` - CLI architecture, command structure, test patterns\n- `packages/miniflare/AGENTS.md` - Worker simulation, embedded workers, build system\n- `packages/vite-plugin-cloudflare/AGENTS.md` - Plugin architecture, playground setup\n- `packages/create-cloudflare/AGENTS.md` - Scaffolding, template system\n- `packages/vitest-pool-workers/AGENTS.md` - 3-context architecture, cloudflare:test module\n- `packages/workers-utils/AGENTS.md` - Shared config validation, test helpers\n\nWhen making architectural changes to a package (renaming files, adding entry points, changing build output), update the relevant AGENTS.md to reflect the new structure.\n\n## Cloudflare Workers Specifics\n\n- When removing or modifying scheduled functions in Cloudflare Workers, remember to update both the code in the Worker file and the corresponding cron trigger in the `wrangler.jsonc` configuration file.\n\n## Adding Native Node.js Module Support (unenv-preset)\n\n- The authoritative source for Node.js module compatibility flags and dates is the workerd repository's `compatibility-date.capnp` file at https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp.\n- If the module is marked as `$experimental` in workerd (no `$impliedByAfterDate`), follow the pattern used by other experimental modules in `preset.ts`.\n- The pattern for adding a new module override involves:\n  - Creating a `get<Module>Overrides()` function similar to existing ones (e.g., `getVmOverrides()`)\n  - Adding the override to `getCloudflarePreset()` and spreading into `dynamicNativeModules` and `dynamicHybridModules`\n  - Adding tests to `packages/wrangler/e2e/unenv-preset/preset.test.ts`\n  - Adding test functions to `packages/wrangler/e2e/unenv-preset/worker/index.ts`\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\nSee @AGENTS.md\n"},"files":{"AGENTS.md":"# AGENTS.md\n\nThis file provides guidance to AI coding agents working in this repository.\n\n## Project Overview\n\nThis is the **Cloudflare Workers SDK** monorepo containing tools and libraries for developing, testing, and deploying applications on Cloudflare. The main components are Wrangler (CLI), Miniflare (local dev simulator), and Create Cloudflare (project scaffolding).\n\n## Development Commands\n\n**Package Management:**\n\n- Use `pnpm` - never use npm or yarn\n- `pnpm install` - Install dependencies for all packages\n- `pnpm build` - Build all packages (uses Turbo for caching)\n\n**Testing:**\n\n- `pnpm test:ci` - Run tests in CI mode\n- `pnpm test:e2e` - Run end-to-end tests (requires Cloudflare credentials)\n- `pnpm test -F <package> \"pattern\"` - Run a single test by name pattern\n\n**Code Quality:**\n\n- `pnpm check` - Run all checks (lint, type, format)\n- `pnpm fix` - Auto-fix linting issues and format code\n\n**Working with Specific Packages:**\n\n- `pnpm run build --filter <package-name>` - Build specific package\n- `pnpm run test:ci --filter <package-name>` - Test specific package\n- `pnpm --filter <package> test:watch` - Watch mode for a specific package\n\n## Architecture Overview\n\n**Core Tools:**\n\n- `packages/wrangler/` - Main CLI tool for Workers development and deployment\n- `packages/miniflare/` - Local development simulator powered by workerd runtime\n- `packages/create-cloudflare/` - Project scaffolding CLI (C3)\n- `packages/vite-plugin-cloudflare/` - Vite plugin for Cloudflare Workers\n\n**Development & Testing:**\n\n- `packages/vitest-pool-workers/` - Vitest integration for testing Workers in actual runtime\n- `packages/chrome-devtools-patches/` - Modified Chrome DevTools for Workers debugging\n\n**Shared Libraries:**\n\n- `packages/pages-shared/` - Code shared between Wrangler and Cloudflare Pages\n- `packages/workers-shared/` - Code shared between Wrangler and Workers Assets\n- `packages/workers-utils/` - Utility package for common Worker operations\n- `packages/workflows-shared/` - Internal Cloudflare Workflows functionality\n- `packages/containers-shared/` - Shared container functionality\n- `packages/unenv-preset/` - Cloudflare preset for unenv (Node.js polyfills)\n- `packages/cli/` - SDK for building workers-sdk CLIs\n- `packages/kv-asset-handler/` - KV-based asset handling for Workers Sites\n\n**Build System:**\n\n- Turbo (turborepo) orchestrates builds across packages\n- TypeScript compilation with shared configs in `packages/workers-tsconfig/`\n- Shared lint config in `packages/lint-config-shared/`\n- Dependency management via pnpm catalog system\n\n## WHERE TO LOOK\n\n| Task                                           | Location                                                              | Notes                                                                                                                                                                        |\n| ---------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Add/modify a CLI command                       | `packages/wrangler/src/`                                              | Commands registered in `src/index.ts` (2k+ line yargs tree)                                                                                                                  |\n| Change local dev behavior                      | `packages/miniflare/src/`                                             | `src/index.ts` is the main `Miniflare` class                                                                                                                                 |\n| Modify Workers runtime simulation              | `packages/miniflare/src/workers/`                                     | ~30 embedded worker scripts, built via `worker:` virtual imports                                                                                                             |\n| Add a test fixture                             | `fixtures/`                                                           | Each fixture is a full workspace member with own `package.json`                                                                                                              |\n| Shared config types/validation                 | `packages/workers-utils/src/config/`                                  | `validation.ts` is the config normalizer (large file)                                                                                                                        |\n| Test helpers (runInTempDir, seed, mockConsole) | `packages/workers-utils/src/test-helpers/`                            | Shared across wrangler, miniflare, others                                                                                                                                    |\n| Cloudflare API mocks for tests                 | `packages/wrangler/src/__tests__/helpers/msw/`                        | MSW handlers per API domain                                                                                                                                                  |\n| CI workflows                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the primary gate                                                                                                                                     |\n| Build/deploy scripts                           | `tools/deployments/`                                                  | Validation + deployment helpers, run via `esbuild-register`                                                                                                                  |\n| Deploy/versions-upload validation              | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | `validateWorkerProps()` for sync checks, `preUploadApiChecks()` for API checks (service metadata, config diff, secrets, workflows). All new pre-upload validation goes here. |\n| Changeset config and rules                     | `.changeset/README.md`                                                | Must read before creating changesets                                                                                                                                         |\n\n## Development Guidelines\n\n**Requirements:**\n\n- Node.js >= 20\n- pnpm\n\n**Code Style:**\n\n- TypeScript with strict mode\n- Use `import type { X }` for type-only imports (`@typescript-eslint/consistent-type-imports`)\n- No `any` (`@typescript-eslint/no-explicit-any`)\n- No non-null assertions (`!`)\n- No floating promises - must be awaited or explicitly voided (`@typescript-eslint/no-floating-promises`)\n- Always use curly braces for control flow (`curly: error`)\n- Use `node:` prefix for Node.js imports (`import/enforce-node-protocol-usage`)\n- Prefix unused variables with `_`\n- No `.only()` in tests (`no-only-tests/no-only-tests`)\n- Prefer `function` declarations over `const` arrow function assignments for named/exported functions\n- ESLint disable comments must use double-dash separator: `// eslint-disable-next-line rule-name -- reason here`\n- Never modify generated files directly — modify the generator or config, then regenerate\n- Format with oxfmt - run `pnpm prettify` in the workspace root before committing\n- All changes to published packages require a changeset (see below)\n\n**Formatting (oxfmt):**\n\n- Tabs (not spaces), double quotes, semicolons, trailing commas (es5)\n- Import order enforced: builtins → third-party → parent → sibling → index → types\n- `sortPackageJson` option sorts package.json keys\n\n**Security:**\n\n- Custom ESLint rule `workers-sdk/no-unsafe-command-execution`: no template literals or string concatenation in `exec`/`spawn`/`execFile` calls (command injection prevention, CWE-78). Disabled in test files only.\n\n**Dependencies:**\n\n- Packages must bundle deps into distributables; runtime `dependencies` are forbidden except for an explicit allowlist\n- External (non-bundled) deps must be declared in `scripts/deps.ts` with `EXTERNAL_DEPENDENCIES` and a comment explaining why\n- After updating dependencies, always run `pnpm i` to also update the package lock file\n\n**Testing Standards:**\n\n- Unit tests with Vitest for all packages\n- Fixture tests in `/fixtures` directory for filesystem/Worker scenarios\n- E2E tests require real Cloudflare account credentials\n- Use `vitest-pool-workers` for testing actual Workers runtime behavior\n- Shared vitest config (`vitest.shared.ts`): 50s timeouts, `retry: 1`, `restoreMocks: true`\n- Vitest 4 pool config: use `maxWorkers: 1` instead of the removed `poolOptions.forks.singleFork: true` when tests must run sequentially\n- **`expect` must come from test context** — never `import { expect } from \"vitest\"`:\n  - Use destructured test context: `it(\"name\", ({ expect }) => { ... })`\n  - For helper functions that need `expect`, pass it as a parameter with type `ExpectStatic`\n  - Always use `import type` for `ExpectStatic`: `import { beforeAll, type ExpectStatic, test } from \"vitest\"`\n  - When test context is unavailable (e.g. setup files), use `node:assert` instead\n  - E2E vitest configs do NOT set `globals: true` — this rule is critical there; forgetting `{ expect }` in the callback causes `ReferenceError` at runtime\n- When changing user-facing strings or output messages, update corresponding test snapshots\n- New test fixtures in `vitest-pool-workers-examples/` must include a `tsconfig.json`\n- Test fixtures serve as user-facing recipes — use clean patterns, avoid type casting where possible\n- Use the `runInTmpDir()` utility instead of mocking filesystem operations. Real filesystem operations are preferred over mocking. The utility creates isolated temporary directories, handles cleanup automatically in `afterEach` hooks, and allows tests to write actual files and assert against them\n- Use the `mockConsoleMethods()` helper to capture stdout/stderr. Use the pattern `const std = mockConsoleMethods()` in test setup, then access captured output via `std.out`, `std.err`, `std.warn` properties. Assert against captured output using `expect(std.out).toMatchInlineSnapshot()`\n- Run specific wrangler test files locally using `pnpm -w test:ci -F wrangler -- [test-file-name]` (e.g. `pnpm -w test:ci -F wrangler -- r2.test.ts`)\n\n**Git Workflow:**\n\n- Check you are not on main before committing. Create a new branch for your work from main if needed.\n- Clean commit history required before first review\n- Don't squash commits after review\n- Never commit without changesets for user-facing changes\n- PR template requirements: Remove \"Fixes #...\" line when no relevant issue exists, keep all checkboxes (don't delete unchecked ones)\n\n**Creating Pull Requests:**\n\n- Always use the PR template from `.github/PULL_REQUEST_TEMPLATE.md` - do not replace it with your own format\n- Fill in the template: replace the issue link placeholder, add description, check appropriate boxes\n- Keep all checkboxes in the template (don't delete unchecked ones)\n- PR title format: `[package name] description` (e.g. `[wrangler] Fix bug in dev command`)\n- If the change doesn't require a changeset, add the `no-changeset-required` label\n- CI validates the PR description (see `tools/deployments/validate-pr-description.ts`). The description **must** include:\n  - A checked (`[x]`) test checkbox — either \"Tests included/updated\", or one of the justification checkboxes with a non-empty explanation\n  - A checked (`[x]`) documentation checkbox — either a Cloudflare docs PR/issue link, or \"Documentation not necessary because:\" with a non-empty explanation\n  - A changeset file (or the `no-changeset-required` label)\n\n**Pre-Submission Checklist:**\n\n- Run `pnpm check` (lint + type-check + format) locally before pushing — do not rely on CI to catch lint errors\n- Run `pnpm prettify` to ensure formatting is correct\n\n## Key Locations\n\n- `/fixtures` - Test fixtures and example applications (each a workspace member)\n- `/packages/wrangler/src` - Main Wrangler CLI source code\n- `/packages/miniflare/src` - Miniflare source\n- `/tools` - Build scripts and deployment utilities (run via `esbuild-register`, no build step)\n- `turbo.json` - Turbo build configuration\n- `pnpm-workspace.yaml` - Workspace configuration (~156 workspace members)\n\n## Testing Strategy\n\n**Package-specific tests:** Most packages have their own test suites\n**Integration tests:** Use fixtures to test real-world scenarios\n**E2E tests:** Test against actual Cloudflare services (requires auth)\n**Workers runtime tests:** Use vitest-pool-workers for workerd-specific behavior\n\nRun `pnpm check` before submitting changes to ensure all quality gates pass.\n\n## Changesets\n\nEvery change to package code requires a changeset or it will not trigger a release. Read `.changeset/README.md` before creating changesets.\n\n**Changeset Format:**\n\nThe changeset descriptions can either use conventional commit prefixes (e.g., \"fix: remove unused option\") or\nstart with a capital letter and describe the change directly (e.g., \"Remove unused option\" not\").\n\n**Changeset Rules:**\n\n- Major versions for `wrangler` are currently **forbidden**\n- `patch`: bug fixes; `minor`: new features, deprecations, experimental breaking changes; `major`: stable breaking changes only\n- No h1/h2/h3 headers in changeset descriptions (changelog uses h3)\n- Config examples must use `wrangler.json` (JSONC), not `wrangler.toml`\n- Separate changesets for distinct changes; do not lump unrelated changes\n- Focus on user-facing impact; reference the public-facing package, not internal implementation packages\n- If the change collects more analytics, it should be a minor even though there is no user-visible change\n\n## Anti-Patterns\n\nThese are explicitly forbidden across the repo:\n\n- **npm/yarn** → use pnpm\n- **`any` type** → properly type everything\n- **Non-null assertions (`!`)** → use type narrowing\n- **Floating promises** → await or void explicitly\n- **Missing curly braces** → always brace control flow\n- **`console.*` in wrangler** → use the `logger` singleton\n- **Direct Cloudflare REST API calls** → use the Cloudflare TypeScript SDK\n- **Named imports from `ci-info`** → use default import (`import ci from \"ci-info\"`)\n- **Runtime dependencies** → bundle deps; external deps need explicit allowlist entry\n- **Committing to main** → always work on a branch\n- **Trivial/obvious code comments** → don't add comments that restate what the code does; comments should explain \"why\", not \"what\"\n- **Duplicating types/constants across packages** → export from the owning package and import where needed\n\n## Subdirectory Knowledge\n\nPackages with their own AGENTS.md for deeper context:\n\n- `packages/wrangler/AGENTS.md` - CLI architecture, command structure, test patterns\n- `packages/miniflare/AGENTS.md` - Worker simulation, embedded workers, build system\n- `packages/vite-plugin-cloudflare/AGENTS.md` - Plugin architecture, playground setup\n- `packages/create-cloudflare/AGENTS.md` - Scaffolding, template system\n- `packages/vitest-pool-workers/AGENTS.md` - 3-context architecture, cloudflare:test module\n- `packages/workers-utils/AGENTS.md` - Shared config validation, test helpers\n\nWhen making architectural changes to a package (renaming files, adding entry points, changing build output), update the relevant AGENTS.md to reflect the new structure.\n\n## Cloudflare Workers Specifics\n\n- When removing or modifying scheduled functions in Cloudflare Workers, remember to update both the code in the Worker file and the corresponding cron trigger in the `wrangler.jsonc` configuration file.\n\n## Adding Native Node.js Module Support (unenv-preset)\n\n- The authoritative source for Node.js module compatibility flags and dates is the workerd repository's `compatibility-date.capnp` file at https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp.\n- If the module is marked as `$experimental` in workerd (no `$impliedByAfterDate`), follow the pattern used by other experimental modules in `preset.ts`.\n- The pattern for adding a new module override involves:\n  - Creating a `get<Module>Overrides()` function similar to existing ones (e.g., `getVmOverrides()`)\n  - Adding the override to `getCloudflarePreset()` and spreading into `dynamicNativeModules` and `dynamicHybridModules`\n  - Adding tests to `packages/wrangler/e2e/unenv-preset/preset.test.ts`\n  - Adding test functions to `packages/wrangler/e2e/unenv-preset/worker/index.ts`\n","CLAUDE.md":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\nSee @AGENTS.md\n"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","title":"AGENTS.md","content":"# AGENTS.md\n\nThis file provides guidance to AI coding agents working in this repository.\n\n## Project Overview\n\nThis is the **Cloudflare Workers SDK** monorepo containing tools and libraries for developing, testing, and deploying applications on Cloudflare. The main components are Wrangler (CLI), Miniflare (local dev simulator), and Create Cloudflare (project scaffolding).\n\n## Development Commands\n\n**Package Management:**\n\n- Use `pnpm` - never use npm or yarn\n- `pnpm install` - Install dependencies for all packages\n- `pnpm build` - Build all packages (uses Turbo for caching)\n\n**Testing:**\n\n- `pnpm test:ci` - Run tests in CI mode\n- `pnpm test:e2e` - Run end-to-end tests (requires Cloudflare credentials)\n- `pnpm test -F <package> \"pattern\"` - Run a single test by name pattern\n\n**Code Quality:**\n\n- `pnpm check` - Run all checks (lint, type, format)\n- `pnpm fix` - Auto-fix linting issues and format code\n\n**Working with Specific Packages:**\n\n- `pnpm run build --filter <package-name>` - Build specific package\n- `pnpm run test:ci --filter <package-name>` - Test specific package\n- `pnpm --filter <package> test:watch` - Watch mode for a specific package\n\n## Architecture Overview\n\n**Core Tools:**\n\n- `packages/wrangler/` - Main CLI tool for Workers development and deployment\n- `packages/miniflare/` - Local development simulator powered by workerd runtime\n- `packages/create-cloudflare/` - Project scaffolding CLI (C3)\n- `packages/vite-plugin-cloudflare/` - Vite plugin for Cloudflare Workers\n\n**Development & Testing:**\n\n- `packages/vitest-pool-workers/` - Vitest integration for testing Workers in actual runtime\n- `packages/chrome-devtools-patches/` - Modified Chrome DevTools for Workers debugging\n\n**Shared Libraries:**\n\n- `packages/pages-shared/` - Code shared between Wrangler and Cloudflare Pages\n- `packages/workers-shared/` - Code shared between Wrangler and Workers Assets\n- `packages/workers-utils/` - Utility package for common Worker operations\n- `packages/workflows-shared/` - Internal Cloudflare Workflows functionality\n- `packages/containers-shared/` - Shared container functionality\n- `packages/unenv-preset/` - Cloudflare preset for unenv (Node.js polyfills)\n- `packages/cli/` - SDK for building workers-sdk CLIs\n- `packages/kv-asset-handler/` - KV-based asset handling for Workers Sites\n\n**Build System:**\n\n- Turbo (turborepo) orchestrates builds across packages\n- TypeScript compilation with shared configs in `packages/workers-tsconfig/`\n- Shared lint config in `packages/lint-config-shared/`\n- Dependency management via pnpm catalog system\n\n## WHERE TO LOOK\n\n| Task                                           | Location                                                              | Notes                                                                                                                                                                        |\n| ---------------------------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| Add/modify a CLI command                       | `packages/wrangler/src/`                                              | Commands registered in `src/index.ts` (2k+ line yargs tree)                                                                                                                  |\n| Change local dev behavior                      | `packages/miniflare/src/`                                             | `src/index.ts` is the main `Miniflare` class                                                                                                                                 |\n| Modify Workers runtime simulation              | `packages/miniflare/src/workers/`                                     | ~30 embedded worker scripts, built via `worker:` virtual imports                                                                                                             |\n| Add a test fixture                             | `fixtures/`                                                           | Each fixture is a full workspace member with own `package.json`                                                                                                              |\n| Shared config types/validation                 | `packages/workers-utils/src/config/`                                  | `validation.ts` is the config normalizer (large file)                                                                                                                        |\n| Test helpers (runInTempDir, seed, mockConsole) | `packages/workers-utils/src/test-helpers/`                            | Shared across wrangler, miniflare, others                                                                                                                                    |\n| Cloudflare API mocks for tests                 | `packages/wrangler/src/__tests__/helpers/msw/`                        | MSW handlers per API domain                                                                                                                                                  |\n| CI workflows                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the primary gate                                                                                                                                     |\n| Build/deploy scripts                           | `tools/deployments/`                                                  | Validation + deployment helpers, run via `esbuild-register`                                                                                                                  |\n| Deploy/versions-upload validation              | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | `validateWorkerProps()` for sync checks, `preUploadApiChecks()` for API checks (service metadata, config diff, secrets, workflows). All new pre-upload validation goes here. |\n| Changeset config and rules                     | `.changeset/README.md`                                                | Must read before creating changesets                                                                                                                                         |\n\n## Development Guidelines\n\n**Requirements:**\n\n- Node.js >= 20\n- pnpm\n\n**Code Style:**\n\n- TypeScript with strict mode\n- Use `import type { X }` for type-only imports (`@typescript-eslint/consistent-type-imports`)\n- No `any` (`@typescript-eslint/no-explicit-any`)\n- No non-null assertions (`!`)\n- No floating promises - must be awaited or explicitly voided (`@typescript-eslint/no-floating-promises`)\n- Always use curly braces for control flow (`curly: error`)\n- Use `node:` prefix for Node.js imports (`import/enforce-node-protocol-usage`)\n- Prefix unused variables with `_`\n- No `.only()` in tests (`no-only-tests/no-only-tests`)\n- Prefer `function` declarations over `const` arrow function assignments for named/exported functions\n- ESLint disable comments must use double-dash separator: `// eslint-disable-next-line rule-name -- reason here`\n- Never modify generated files directly — modify the generator or config, then regenerate\n- Format with oxfmt - run `pnpm prettify` in the workspace root before committing\n- All changes to published packages require a changeset (see below)\n\n**Formatting (oxfmt):**\n\n- Tabs (not spaces), double quotes, semicolons, trailing commas (es5)\n- Import order enforced: builtins → third-party → parent → sibling → index → types\n- `sortPackageJson` option sorts package.json keys\n\n**Security:**\n\n- Custom ESLint rule `workers-sdk/no-unsafe-command-execution`: no template literals or string concatenation in `exec`/`spawn`/`execFile` calls (command injection prevention, CWE-78). Disabled in test files only.\n\n**Dependencies:**\n\n- Packages must bundle deps into distributables; runtime `dependencies` are forbidden except for an explicit allowlist\n- External (non-bundled) deps must be declared in `scripts/deps.ts` with `EXTERNAL_DEPENDENCIES` and a comment explaining why\n- After updating dependencies, always run `pnpm i` to also update the package lock file\n\n**Testing Standards:**\n\n- Unit tests with Vitest for all packages\n- Fixture tests in `/fixtures` directory for filesystem/Worker scenarios\n- E2E tests require real Cloudflare account credentials\n- Use `vitest-pool-workers` for testing actual Workers runtime behavior\n- Shared vitest config (`vitest.shared.ts`): 50s timeouts, `retry: 1`, `restoreMocks: true`\n- Vitest 4 pool config: use `maxWorkers: 1` instead of the removed `poolOptions.forks.singleFork: true` when tests must run sequentially\n- **`expect` must come from test context** — never `import { expect } from \"vitest\"`:\n  - Use destructured test context: `it(\"name\", ({ expect }) => { ... })`\n  - For helper functions that need `expect`, pass it as a parameter with type `ExpectStatic`\n  - Always use `import type` for `ExpectStatic`: `import { beforeAll, type ExpectStatic, test } from \"vitest\"`\n  - When test context is unavailable (e.g. setup files), use `node:assert` instead\n  - E2E vitest configs do NOT set `globals: true` — this rule is critical there; forgetting `{ expect }` in the callback causes `ReferenceError` at runtime\n- When changing user-facing strings or output messages, update corresponding test snapshots\n- New test fixtures in `vitest-pool-workers-examples/` must include a `tsconfig.json`\n- Test fixtures serve as user-facing recipes — use clean patterns, avoid type casting where possible\n- Use the `runInTmpDir()` utility instead of mocking filesystem operations. Real filesystem operations are preferred over mocking. The utility creates isolated temporary directories, handles cleanup automatically in `afterEach` hooks, and allows tests to write actual files and assert against them\n- Use the `mockConsoleMethods()` helper to capture stdout/stderr. Use the pattern `const std = mockConsoleMethods()` in test setup, then access captured output via `std.out`, `std.err`, `std.warn` properties. Assert against captured output using `expect(std.out).toMatchInlineSnapshot()`\n- Run specific wrangler test files locally using `pnpm -w test:ci -F wrangler -- [test-file-name]` (e.g. `pnpm -w test:ci -F wrangler -- r2.test.ts`)\n\n**Git Workflow:**\n\n- Check you are not on main before committing. Create a new branch for your work from main if needed.\n- Clean commit history required before first review\n- Don't squash commits after review\n- Never commit without changesets for user-facing changes\n- PR template requirements: Remove \"Fixes #...\" line when no relevant issue exists, keep all checkboxes (don't delete unchecked ones)\n\n**Creating Pull Requests:**\n\n- Always use the PR template from `.github/PULL_REQUEST_TEMPLATE.md` - do not replace it with your own format\n- Fill in the template: replace the issue link placeholder, add description, check appropriate boxes\n- Keep all checkboxes in the template (don't delete unchecked ones)\n- PR title format: `[package name] description` (e.g. `[wrangler] Fix bug in dev command`)\n- If the change doesn't require a changeset, add the `no-changeset-required` label\n- CI validates the PR description (see `tools/deployments/validate-pr-description.ts`). The description **must** include:\n  - A checked (`[x]`) test checkbox — either \"Tests included/updated\", or one of the justification checkboxes with a non-empty explanation\n  - A checked (`[x]`) documentation checkbox — either a Cloudflare docs PR/issue link, or \"Documentation not necessary because:\" with a non-empty explanation\n  - A changeset file (or the `no-changeset-required` label)\n\n**Pre-Submission Checklist:**\n\n- Run `pnpm check` (lint + type-check + format) locally before pushing — do not rely on CI to catch lint errors\n- Run `pnpm prettify` to ensure formatting is correct\n\n## Key Locations\n\n- `/fixtures` - Test fixtures and example applications (each a workspace member)\n- `/packages/wrangler/src` - Main Wrangler CLI source code\n- `/packages/miniflare/src` - Miniflare source\n- `/tools` - Build scripts and deployment utilities (run via `esbuild-register`, no build step)\n- `turbo.json` - Turbo build configuration\n- `pnpm-workspace.yaml` - Workspace configuration (~156 workspace members)\n\n## Testing Strategy\n\n**Package-specific tests:** Most packages have their own test suites\n**Integration tests:** Use fixtures to test real-world scenarios\n**E2E tests:** Test against actual Cloudflare services (requires auth)\n**Workers runtime tests:** Use vitest-pool-workers for workerd-specific behavior\n\nRun `pnpm check` before submitting changes to ensure all quality gates pass.\n\n## Changesets\n\nEvery change to package code requires a changeset or it will not trigger a release. Read `.changeset/README.md` before creating changesets.\n\n**Changeset Format:**\n\nThe changeset descriptions can either use conventional commit prefixes (e.g., \"fix: remove unused option\") or\nstart with a capital letter and describe the change directly (e.g., \"Remove unused option\" not\").\n\n**Changeset Rules:**\n\n- Major versions for `wrangler` are currently **forbidden**\n- `patch`: bug fixes; `minor`: new features, deprecations, experimental breaking changes; `major`: stable breaking changes only\n- No h1/h2/h3 headers in changeset descriptions (changelog uses h3)\n- Config examples must use `wrangler.json` (JSONC), not `wrangler.toml`\n- Separate changesets for distinct changes; do not lump unrelated changes\n- Focus on user-facing impact; reference the public-facing package, not internal implementation packages\n- If the change collects more analytics, it should be a minor even though there is no user-visible change\n\n## Anti-Patterns\n\nThese are explicitly forbidden across the repo:\n\n- **npm/yarn** → use pnpm\n- **`any` type** → properly type everything\n- **Non-null assertions (`!`)** → use type narrowing\n- **Floating promises** → await or void explicitly\n- **Missing curly braces** → always brace control flow\n- **`console.*` in wrangler** → use the `logger` singleton\n- **Direct Cloudflare REST API calls** → use the Cloudflare TypeScript SDK\n- **Named imports from `ci-info`** → use default import (`import ci from \"ci-info\"`)\n- **Runtime dependencies** → bundle deps; external deps need explicit allowlist entry\n- **Committing to main** → always work on a branch\n- **Trivial/obvious code comments** → don't add comments that restate what the code does; comments should explain \"why\", not \"what\"\n- **Duplicating types/constants across packages** → export from the owning package and import where needed\n\n## Subdirectory Knowledge\n\nPackages with their own AGENTS.md for deeper context:\n\n- `packages/wrangler/AGENTS.md` - CLI architecture, command structure, test patterns\n- `packages/miniflare/AGENTS.md` - Worker simulation, embedded workers, build system\n- `packages/vite-plugin-cloudflare/AGENTS.md` - Plugin architecture, playground setup\n- `packages/create-cloudflare/AGENTS.md` - Scaffolding, template system\n- `packages/vitest-pool-workers/AGENTS.md` - 3-context architecture, cloudflare:test module\n- `packages/workers-utils/AGENTS.md` - Shared config validation, test helpers\n\nWhen making architectural changes to a package (renaming files, adding entry points, changing build output), update the relevant AGENTS.md to reflect the new structure.\n\n## Cloudflare Workers Specifics\n\n- When removing or modifying scheduled functions in Cloudflare Workers, remember to update both the code in the Worker file and the corresponding cron trigger in the `wrangler.jsonc` configuration file.\n\n## Adding Native Node.js Module Support (unenv-preset)\n\n- The authoritative source for Node.js module compatibility flags and dates is the workerd repository's `compatibility-date.capnp` file at https://github.com/cloudflare/workerd/blob/main/src/workerd/io/compatibility-date.capnp.\n- If the module is marked as `$experimental` in workerd (no `$impliedByAfterDate`), follow the pattern used by other experimental modules in `preset.ts`.\n- The pattern for adding a new module override involves:\n  - Creating a `get<Module>Overrides()` function similar to existing ones (e.g., `getVmOverrides()`)\n  - Adding the override to `getCloudflarePreset()` and spreading into `dynamicNativeModules` and `dynamicHybridModules`\n  - Adding tests to `packages/wrangler/e2e/unenv-preset/preset.test.ts`\n  - Adding test functions to `packages/wrangler/e2e/unenv-preset/worker/index.ts`\n","category":"root","tokens":4155},{"name":"CLAUDE.md","path":"CLAUDE.md","title":"CLAUDE.md","content":"# CLAUDE.md\n\nThis file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.\n\nSee @AGENTS.md\n","category":"root","tokens":33}]}