{"owner":"cloudflare","repo":"workers-sdk","hasSkills":true,"totalSkillsCount":65,"totalTokensCount":50199,"categories":["anthropic-skill","root-instruction","claude-rule","plugin-manifest"],"hasMcp":false,"mcpConfig":null,"found":[".github/skills/issue-review.md",".opencode/skills/local-explorer/SKILL.md",".opencode/skills/local-explorer/assets/local-explorer-diagram.md","AGENTS.md","CLAUDE.md","packages/build-output-utils/README.md","packages/chrome-devtools-patches/README.md","packages/cli/README.md","packages/codemods/README.md","packages/config/README.md","packages/containers-shared/README.md","packages/create-cloudflare/AGENTS.md","packages/create-cloudflare/README.md","packages/create-cloudflare/e2e/README.md","packages/create-cloudflare/templates/django/py/README.md","packages/create-cloudflare/templates/fastapi/py/README.md","packages/create-cloudflare/templates/flask/py/README.md","packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md","packages/create-cloudflare/templates/hello-world-durable-object/py/README.md","packages/create-cloudflare/templates/hello-world-with-assets/py/README.md","packages/create-cloudflare/templates/hello-world/py/README.md","packages/create-cloudflare/templates/openapi/ts/README.md","packages/create-cloudflare/templates/react-router/ts/README.md","packages/format-errors/README.md","packages/kv-asset-handler/README.md","packages/local-explorer-ui/README.md","packages/miniflare/AGENTS.md","packages/miniflare/README.md","packages/miniflare/src/plugins/core/proxy/README.md","packages/miniflare/src/workers/README.md","packages/miniflare/src/workers/cache/README.md","packages/mock-npm-registry/README.md","packages/pages-functions/README.md","packages/pages-shared/README.md","packages/quick-edit-extension/README.md","packages/quick-edit/README.md","packages/runtime-types/README.md","packages/shared-ast-primitives/README.md","packages/solarflare-theme/README.md","packages/turbo-r2-archive/README.md","packages/unenv-preset/README.md","packages/vite-plugin-cloudflare/AGENTS.md","packages/vite-plugin-cloudflare/README.md","packages/vite-plugin-cloudflare/e2e/README.md","packages/vite-plugin-cloudflare/playground/additional-modules/README.md","packages/vite-plugin-cloudflare/tsconfig.plugin.json","packages/vitest-plugin/AGENTS.md","packages/vitest-plugin/README.md","packages/vitest-plugin/src/worker/lib/README.md","packages/vitest-plugin/test/README.md","packages/workers-auth/AGENTS.md","packages/workers-auth/README.md","packages/workers-playground/README.md","packages/workers-shared/README.md","packages/workers-shared/asset-worker/README.md","packages/workers-shared/router-worker/README.md","packages/workers-utils/AGENTS.md","packages/workers-utils/README.md","packages/workers-utils/src/config/README.md","packages/workflows-shared/README.md","packages/wrangler/AGENTS.md","packages/wrangler/README.md","packages/wrangler/e2e/README.md","packages/wrangler/src/pages/README.md","tools/README.md"],"skills":{".github/skills/issue-review.md":"---\nname: github-issue-review\ndescription: Triage a GitHub issue on cloudflare/workers-sdk. Assesses quality, identifies the component, checks for duplicates, and recommends next steps.\n---\n\n# GitHub Issue Triage Skill\n\nThis skill triages a GitHub issue to assess its quality, identify the affected component, and recommend next steps for the maintainers.\n\n**Important:** This skill runs without bash or network access. All analysis is based on the pre-fetched issue data in `context.json`. Use only `read`, `glob`, `grep`, `edit`, and `write` tools.\n\n## Input\n\nPre-fetched issue data at `data/<issue_number>/context.json` containing the full issue details from the GitHub API (title, body, comments, labels, author, dates).\n\n## Triage Process\n\nPerform the following steps in order. **Stop and skip to Output as soon as you have sufficient evidence for a recommendation.**\n\n### Step 1: Load Issue Details\n\nRead the pre-fetched `context.json` file using the `read` tool.\n\nExtract and note:\n\n- Title and description\n- Issue type (bug report vs feature request vs question)\n- Product/component affected\n- Version reported against (if any)\n- Operating system (if any)\n- Reproduction steps or reproduction link (if any)\n- Error messages (if any)\n- Comment count and any relevant comment content\n- Labels currently applied\n- Issue age (created date) and last activity date\n- `state_reason` if the issue is already closed\n\n### Step 2: Check for Closeable Issues\n\nCheck each of the following categories in order. **STOP at the first match** and skip to Output.\n\n> **Note:** The `state_reason` values in this section (`completed`, `not_planned`) are informational — they indicate the appropriate GitHub close reason for maintainer reference. They are not captured as a field in the output report.\n\n#### 2a: Spam or Junk\n\nRecommend **CLOSE** (state_reason: `not_planned`, no comment needed) if:\n\n- The body contains random characters, test text, or nonsensical content (e.g. \"bhhg\", \"ssssssssss\", \"aloll\")\n- The issue is clearly spam (e.g. loan advertisements, SEO spam, unrelated product promotions)\n- The issue is a blank/empty test issue (e.g. title is \"test\" with no meaningful body)\n- The body is entirely empty or contains only template headers with no content filled in\n\n#### 2b: Reporter Confirmed Resolved\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The reporter explicitly confirmed the issue is resolved in comments\n- The reporter said they found a workaround and no longer need a fix\n- A maintainer indicated it should be closed in comments\n\n#### 2c: Already Fixed in a Prior Release\n\nRecommend **CLOSE** (state_reason: `completed`) if, based on references within the issue comments or linked PRs:\n\n- A comment references a PR or release that addresses this issue\n- The issue describes a bug that was fixed in a version newer than the reporter's version\n- The issue's symptoms match a fix described in a linked PR or comment\n\nWhen closing, cite the specific PR number and release version if known.\n\n**Template:**\n\n> This issue has been fixed in PR #XXXX, which was released in **wrangler X.Y.Z** (or the relevant package version). Please update and let us know if you're still seeing the issue.\n\nOr for older issues where the fix can't be pinpointed:\n\n> This is a fairly old issue, and from testing with the latest version, it appears to have been resolved. I'm going to close it for now — if you're still running into problems on the latest version, feel free to open a new issue with more details and we can investigate further.\n\n#### 2d: Duplicate\n\nRecommend **CLOSE** (state_reason: `not_planned`) if a comment or linked reference in the issue identifies it as a duplicate of another issue — for example, a maintainer has already commented pointing to a canonical issue, or the reporter themselves links to an existing report.\n\nWhen closing, link to the canonical issue.\n\n**Template:**\n\n> Closing as a duplicate of #XXXX. Please follow that issue for updates.\n\nIf the duplicate is in another repo:\n\n> I'm closing this as a duplicate of <owner/repo>#XXXX, which is where this is being tracked.\n\n#### 2e: Not workers-sdk / Wrong Repo\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes Workers **runtime** behavior (fetch API quirks, V8 issues, compatibility flags, crypto APIs) — belongs in [cloudflare/workerd](https://github.com/cloudflare/workerd)\n- The issue is about a third-party framework (Nuxt, SvelteKit, Remix, Hono, React Router) and the bug is in that framework's code, not in Wrangler or the Vite plugin\n- The issue is about an upstream tool (esbuild, Bun, Vite core) rather than Cloudflare's integration\n- The issue is an account/billing/abuse problem — belongs in Cloudflare Support\n\n**Templates:**\n\nFor framework issues:\n\n> It looks like this issue is coming from <framework>, rather than from workers-sdk. I'd recommend opening an issue on that project's repo: <link>. If it turns out to be a workers-sdk issue after all, feel free to open a new issue here with more details.\n\nFor runtime issues:\n\n> This looks like a Workers runtime issue rather than a tooling issue. The right place to track this is [cloudflare/workerd](https://github.com/cloudflare/workerd) — could a maintainer transfer this issue there?\n\n(Set Action field to: \"Transfer to cloudflare/workerd, then post this comment.\")\n\nFor account/support issues:\n\n> Unfortunately, we're unable to provide support for account-level issues via GitHub. Please contact Cloudflare Support at https://dash.cloudflare.com/?to=/:account/support or the email address mentioned in the error message.\n\n#### 2f: Stale / No Response\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue has the `awaiting-response:reporter` or `needs-reproduction` label AND the last activity was >30 days ago\n- The issue is >12 months old with no activity in the last 6 months\n- A maintainer asked for a reproduction or clarification and the reporter never responded\n\n**Template:**\n\n> We haven't heard from you in a while so I'm going to close this issue for now. If you're still running into problems, feel free to open a new issue with more details and we can investigate further.\n\nFor very old issues:\n\n> This is a very old issue so I'm going to close it for now. If you're still running into problems on the latest version, feel free to comment with more details and we can investigate further.\n\n#### 2g: Transient Platform Issue\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The issue describes a one-time API error (500, 503, auth failures) that appears to have been a service incident\n- Multiple users reported the same error around the same time, and it has since stopped\n- The error is from Cloudflare's API (not from Wrangler itself) and there's no way to fix it in workers-sdk\n\n**Template:**\n\n> This was a transient API issue, and should be resolved now. If you're still seeing this error, please open a new issue with the latest details and we can investigate further.\n\nOr for old transient issues:\n\n> This appears to have been a transient server-side API issue. Similar reports were caused by Cloudflare API incidents that have since been resolved. I'm going to close this for now.\n\n#### 2h: User Error / Misunderstanding\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes expected behavior that the reporter misunderstands\n- The issue is caused by incorrect configuration, wrong SQL syntax, or misuse of an API\n- The fix is a documentation pointer rather than a code change\n\nWhen closing, explain the correct approach and link to relevant documentation. Be helpful, not dismissive.\n\n**Template:**\n\n> This isn't a bug — <brief explanation of the correct behavior>. You can find more details in the docs: <link>. I'm going to close this for now, but feel free to ask on our [Discord](https://discord.cloudflare.com) if you have more questions.\n\n#### 2i: Breaking Change\n\nRecommend **KEEP OPEN** if:\n\n- The requested change would be a breaking change in the current major version\n\nThe issue should remain open as a tracking item. Do not close it — the team hasn't decided against the change, it's deferred to a future major version.\n\n**Suggested labels:** `breaking-change`\n\n**Template:**\n\n> Changing this behavior at this stage would be a breaking change, so it will need to wait for the next major version. I've added the `breaking-change` label to track this.\n\n(Set Action field to: \"Apply `breaking-change` label, then post this comment.\")\n\n#### 2j: Won't Fix / By Design\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The behavior is intentional and documented\n- The team has explicitly decided not to implement this feature\n- The cost/complexity of the change outweighs the benefit\n\n**Templates:**\n\nFor design decisions:\n\n> This is intentional behavior — <brief explanation>. I don't think we're likely to change this in the near future, but we appreciate the feedback.\n\nFor feature requests that won't happen:\n\n> Thanks for the suggestion. We don't intend to implement this right now, but it may be revisited in future. <Optional: brief explanation of why, or pointer to an alternative approach.>\n\n#### 2k: Feature Superseded / Deprecated\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The requested feature has been implemented via a different mechanism than proposed\n- The issue relates to a deprecated feature that has a replacement\n- A newer feature or package addresses the underlying need\n\n**Template:**\n\n> This has been addressed by <feature/package>. <Brief explanation of how it solves the original request.> I'm going to close this for now.\n\n### Step 3: Check for Insufficient Information\n\nIf the issue wasn't caught by Step 2, recommend **NEEDS MORE INFO** if:\n\n- Bug report has no reproduction steps or link (the bug template requires one)\n- Bug report is missing version information\n- The description is too vague to act on (e.g. \"it doesn't work\" with no details)\n- The error message is missing or truncated\n\n**Template:**\n\n> Thanks for reporting this. Could you provide <specific missing information>? In particular:\n>\n> - <specific question 1>\n> - <specific question 2>\n>\n> A minimal reproduction (a GitHub repo or link we can clone and run) would also help us investigate. Without more details, we won't be able to look into this.\n\n**Suggested label:** `awaiting-response:reporter` (and optionally `needs-reproduction`)\n\n**STOP HERE if** the issue clearly needs more info. Skip to Output.\n\n### Step 4: Identify Component\n\nMap the issue to a package based on labels, title, and body content:\n\n| Signal                                                                           | Package                                         |\n| -------------------------------------------------------------------------------- | ----------------------------------------------- |\n| `package:wrangler` label, wrangler CLI commands, `wrangler.toml`/`wrangler.json` | `packages/wrangler`                             |\n| `package:miniflare` label, local dev simulation                                  | `packages/miniflare`                            |\n| `product:d1` label, D1 database, `d1 execute`, migrations                        | `packages/wrangler` (D1 code is in wrangler)    |\n| `package:vitest` label, worker tests, `vitest-plugin`                            | `packages/vitest-plugin`                        |\n| `package:vite-plugin` label, vite dev, `@cloudflare/vite-plugin`                 | `packages/vite-plugin-cloudflare`               |\n| `package:c3` label, `create-cloudflare`, project scaffolding                     | `packages/create-cloudflare`                    |\n| `product:pages` label, Pages deployment, `_routes.json`, `_headers`              | `packages/wrangler` (Pages code is in wrangler) |\n| `feature:workers-assets` label, static asset serving                             | `packages/wrangler`                             |\n| `product:containers` label, container registry                                   | `packages/wrangler`                             |\n| `product:workflows` label, Workflows API                                         | `packages/wrangler`                             |\n| `feature:workers-builds` label                                                   | Workers Builds (may be internal)                |\n| `python` label, Python Workers                                                   | `packages/wrangler`                             |\n| `product:workers-for-platforms` label, dispatch namespaces                       | `packages/wrangler`                             |\n| `package:kv-asset-handler` label                                                 | `packages/kv-asset-handler`                     |\n| `feature:types` label, `wrangler types` command                                  | `packages/wrangler`                             |\n| R2, KV, Queues, Durable Objects, Vectorize bindings                              | `packages/wrangler`                             |\n| `node-compat`/`nodejs-compat` label, Node.js APIs                                | May be workerd or wrangler depending on context |\n| Workers runtime behavior (not tooling)                                           | Likely belongs in cloudflare/workerd            |\n| Cloudflare dashboard, API behavior                                               | Likely a platform issue, not workers-sdk        |\n\n### Step 5: Assess Reproducibility and Severity\n\nFor **bug reports**, evaluate:\n\n- **Has reproduction?** Does the issue include a minimal repro link or clear steps?\n- **Severity estimate:** Is this a crash, data loss, incorrect behavior, or cosmetic issue?\n- **Scope:** Does it affect all users or a specific configuration?\n- **Workaround available?** Did the reporter or comments mention one?\n- **Version gap:** Is the reporter on an old version? Could updating fix this?\n\nFor **feature requests**, evaluate:\n\n- **Clarity:** Is the proposed solution clearly described?\n- **Use case:** Is the motivation explained?\n- **Scope:** Small enhancement vs large new feature?\n- **Existing alternatives:** Is there already a way to achieve this (even if less convenient)?\n\n## Output Format\n\n**How the output is used:** `report.md` is posted verbatim as a maintainer-facing triage comment on the issue (attributed to an automated bot), and the labels in `summary.json` are applied automatically. Because of this:\n\n- Write `report.md` for maintainers, not the reporter. The **Suggested Comment** section is a _draft_ for a maintainer to send to the reporter — it is **not** posted automatically, so do not phrase the surrounding report as though a reply has already been made.\n- Only put labels in the **Suggested Labels** fields that already exist in the repository. If unsure whether a label exists, omit it rather than guess — non-existent labels are dropped before applying, so inventing labels only weakens the report's accuracy.\n\n### Report Directory Structure\n\n```\n./data/<issue_number>/\n├── report.md          # Full detailed report\n└── summary.json       # Structured JSON summary\n```\n\n### Output Step 1: Write Full Report\n\nWrite the full report to `./data/<issue_number>/report.md`:\n\n```markdown\n# Issue Triage: <owner/repo>#<number>\n\n## Summary\n\n<One-line summary of the issue>\n\n## Classification\n\n- **Type:** <Bug | Feature Request | Question | Discussion>\n- **Component:** <package name or \"unknown\">\n- **Severity:** <Critical | High | Medium | Low | N/A>\n- **Has Reproduction:** <Yes (with link) | No | N/A>\n- **Quality:** <Complete | Partial | Incomplete>\n\n## Findings\n\n- **Created:** <date>\n- **Author:** <username>\n- **Version:** <reported version, or \"not specified\">\n- **Labels:** <labels, or \"none\">\n- **Comments:** <count>\n\n### Analysis\n\n<2-5 bullet points covering what you found — component identification,\nreproducibility assessment, severity reasoning, staleness indicators,\nduplicate candidates. Only include what's relevant.>\n\n## Recommendation\n\n**Status:** <CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\n\n**Reasoning:** <2-3 sentences explaining why>\n\n**Action:** <What a maintainer should do next>\n\n**Suggested Labels:** <labels to add, if any. Use existing repo labels only.>\n\n### Suggested Comment\n\n> <The exact comment to post on the issue. Follow the templates above for the\n> matching closure category. Key principles:\n>\n> - Always offer an escape hatch (\"feel free to open a new issue\")\n> - Link to specific PRs, releases, or docs when available\n> - Be concise for straightforward closures, detailed for design decisions\n> - Never be dismissive or snarky, even for spam (just close silently) or user error\n> - For NEEDS MORE INFO, ask specific questions (not generic \"please provide more details\")\n>   Omit this section entirely for spam (close without comment) or if no comment is needed.>\n```\n\n### Output Step 2: Write Summary File\n\nWrite a machine-readable summary as **JSON** to `./data/<issue_number>/summary.json`. This file is parsed by the triage workflow (to build the dashboard payload and apply labels), so it must be valid JSON with exactly these keys:\n\n```json\n{\n  \"issueNumber\": <issue_number as a number>,\n  \"title\": \"<issue title, with emoji/template prefixes like 'Bug:' removed>\",\n  \"githubUrl\": \"https://github.com/<owner>/<repo>/issues/<issue_number>\",\n  \"recommendation\": \"<CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\",\n  \"difficulty\": \"<easy | medium | hard | n/a>\",\n  \"reasoning\": \"<brief reasoning, 1-2 sentences>\",\n  \"suggestedAction\": \"<brief description of next steps>\",\n  \"hasSuggestedComment\": <true if a Suggested Comment section is present in the report, false otherwise>,\n  \"suggestedLabels\": [\"<label>\", \"...\"]\n}\n```\n\n**Key definitions:**\n\n- **issueNumber**: The issue number as a JSON number (not a string).\n- **title**: Issue title with any emoji prefixes (e.g. \"🐛 Bug:\") or template prefixes removed.\n- **githubUrl**: Full URL to the issue.\n- **recommendation**: One of `CLOSE`, `KEEP OPEN`, `NEEDS MORE INFO`, `NEEDS VERIFICATION`.\n- **difficulty**: Estimated fix difficulty — `easy`, `medium`, `hard`, or `n/a` (for feature requests or closures).\n- **reasoning**: Brief summary of why (1-2 sentences).\n- **suggestedAction**: Brief description of next steps.\n- **hasSuggestedComment**: Boolean — `true` if the report includes a Suggested Comment, `false` otherwise.\n- **suggestedLabels**: JSON array of labels to apply, matching the **Suggested Labels** field in the report. Use existing repo labels only (see above). Use an empty array `[]` if there are no labels to apply.\n\n**CRITICAL:** Write valid, parseable JSON only (no trailing commas, no comments, no surrounding markdown fences). Because JSON strings are escaped, `reasoning`/`suggestedAction` may safely contain any punctuation.\n",".opencode/skills/local-explorer/SKILL.md":"---\nname: local-explorer\ndescription: How to add products/resources to the local explorer or local API. Use when implementing new local APIs, or UI routes under packages/miniflare/src/workers/local-explorer or packages/local-explorer-ui.\n---\n\n# Cloudflare Local Explorer Products\n\nUse this skill when adding a new product or resource type to the local API and/or local explorer.\n\n## Start Here\n\nRead these files before editing:\n\n- `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`\n- `packages/miniflare/src/plugins/core/explorer.ts`\n- `packages/miniflare/src/plugins/core/types.ts`\n- One existing resource implementation in `packages/miniflare/src/workers/local-explorer/resources/`, preferably the product most similar to the new one\n- One matching test in `packages/miniflare/test/plugins/local-explorer/`\n\nIf there are UI changes, also read:\n\n- `packages/local-explorer-ui/src/components/Sidebar.tsx`\n- Existing route files under `packages/local-explorer-ui/src/routes/`\n- Existing product e2e tests under `packages/local-explorer-ui/src/__e2e__/`\n\n## Workflow\n\n1. Add the API surface to `packages/miniflare/scripts/openapi-filter-config.ts`.\n2. Generate Miniflare's filtered spec and backend types from a full Cloudflare OpenAPI spec:\n\n```bash\nOPENAPI_INPUT_PATH=<path-to-full-openapi-spec> pnpm --dir packages/miniflare generate:api\n```\n\n3. Inspect `packages/miniflare/src/workers/local-explorer/openapi.local.json` and generated types. If the generated schemas include fields local explorer will not support, add ignores in `openapi-filter-config.ts` and regenerate.\n4. The explorer worker should have access to all user resource bindings. Ensure `proxyBindings` include bindings to the new product and that `getExplorerServices()` exposes any extra bindings the explorer worker needs. Wire product bindings through `constructExplorerBindingMap()` and `constructExplorerWorkerOpts()` in `packages/miniflare/src/plugins/core/explorer.ts`.\n5. Add or extend resource binding metadata in `packages/miniflare/src/plugins/core/types.ts`.\n6. Implement handlers in `packages/miniflare/src/workers/local-explorer/resources/<product>.ts`. Make sure to account for cross-instance aggregation, if applicable.\n7. Register Hono routes in `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`.\n8. Validate request bodies and query params with generated Zod schemas from `generated/zod.gen.ts` using `validateRequestBody()` and `validateQuery()`.\n9. Return Cloudflare API envelope responses using `wrapResponse()` and `errorResponse()` from `common.ts` unless an existing endpoint for that product uses a different response shape.\n10. Add Miniflare tests in `packages/miniflare/test/plugins/local-explorer/<product>.spec.ts`.\n11. Regenerate the UI API client:\n\n```bash\npnpm --dir packages/local-explorer-ui build\n```\n\n12. Add UI routes/components. Use Kumo components for new UI. See https://github.com/cloudflare/kumo/blob/main/AGENTS.md.\n13. Add Playwright e2e tests under `packages/local-explorer-ui/src/__e2e__/<product>/` for new visible product flows.\n\n## OpenAPI Rules\n\n- Do not edit generated files like `packages/miniflare/src/workers/local-explorer/openapi.local.json` or `packages/miniflare/src/workers/local-explorer/generated/` directly.\n- Prefer upstream Cloudflare API paths when a public API exists.\n- Use `extensions.paths` in `openapi-filter-config.ts` only for local-only APIs or APIs that do not exist in the public Cloudflare API.\n- Add ignores for unsupported params, headers, request body properties, and response fields rather than pretending to support them.\n\n## Backend Patterns\n\n- Local list endpoints such as listing KV namespaces should not implement pagination as this may require cross-instance aggregation. Pagination should be supported when targeting individual resources, such as listing KV keys within a specific namespace.\n- For cross-worker aggregation, use `aggregateListResults()`, `getPeerUrlsIfAggregating()`, and `fetchFromPeer()` from `aggregation.ts`; do not hand-roll peer discovery. Add tests for both local-only behavior and aggregated behavior when the product can span multiple instances.\n- If an API needs direct filesystem access, call through the loopback service (`c.env.MINIFLARE_LOOPBACK`) to a Node.js endpoint. The local explorer API runs inside workerd, so it cannot access the host filesystem directly.\n- If an endpoint needs metadata that is not available on the runtime binding itself, put that metadata in `BindingIdMap` and pass it through `CoreBindings.JSON_LOCAL_EXPLORER_BINDING_MAP`.\n- If a product should appear in `/api/local/workers`, add it to `WorkerResourceBindings` and populate it in `constructExplorerWorkerOpts()`.\n\n## UI Patterns\n\n- The UI API client is generated from `packages/miniflare/src/workers/local-explorer/openapi.local.json` into `packages/local-explorer-ui/src/api/generated/`.\n- Sidebar resources come from `/api/local/workers`; update `LocalExplorerWorkerBindings` usage and `Sidebar.tsx` when the product should appear in navigation.\n- Add route files under `packages/local-explorer-ui/src/routes/`. TanStack Router regenerates `src/routeTree.gen.ts` during UI build/dev.\n- Preserve worker selection by carrying the `worker` search param through product links when following sidebar patterns.\n- Use Kumo for new UI components wherever possible. Do not introduce a parallel component system.\n- Do not use tailwindCSS color tokens, use Kumo color tokens instead.\n",".opencode/skills/local-explorer/assets/local-explorer-diagram.md":"```mermaid\nflowchart TB\n\tClient[\"client\"] --> Incoming[\"incoming request\"]\n\tIncoming --> EntryA[\"entry worker\"]\n\tEntryA -->|/cdn-cgi/explorer| ExplorerA[\"explorer worker<br/>(Hono)\"]\n\n\tsubgraph Runtime[\"running Miniflare instances\"]\n\t\tdirection LR\n\n\t\tsubgraph A[\"miniflare A\"]\n\t\t\tdirection TB\n\t\t\tEntryA\n\t\t\tExplorerA\n\t\t\tFrontend[\"frontend<br/>(TanStack Router + React)\"]\n\t\t\tUserWorker[\"user worker\"]\n\t\t\tKV[\"KV, R2, D1\"]\n\t\t\tWrapper[\"wrapped<br/>DO/Workflow class\"]\n\n\t\t\tEntryA --> UserWorker\n\t\t\tExplorerA -->|disk service to serve assets| Frontend\n\t\t\tExplorerA -->|binding| KV\n\t\t\tExplorerA -->|binding| Wrapper\n\t\t\tUserWorker -->|binding| KV\n\t\t\tUserWorker -->|binding| Wrapper\n\t\tend\n\n\t\tsubgraph B[\"miniflare B\"]\n\t\t\tdirection TB\n\t\t\tEntryB[\"entry worker\"]\n\t\t\tExplorerB[\"explorer worker\"]\n\t\t\tEtc[\"etc.\"]\n\n\t\t\tEntryB --> ExplorerB\n\t\t\tExplorerB --> Etc\n\t\tend\n\tend\n\n\tFrontend -->|fetch /cdn-cgi/explorer/api| Incoming\n\tExplorerA -->|fetch /cdn-cgi/explorer/api/resource with NO_AGGREGATE_HEADER| EntryB\n\n\tsubgraph FS[\"filesystem\"]\n\t\tRegistry[\"dev registry\"]\n\t\tDOState[\".wrangler/state/durable-objects<br/>(list DOs, delete workflows, etc.)\"]\n\tend\n\n\tExplorerA -->|node loopback binding| FS\n\n\tclassDef miniflareA stroke:#f08c00,fill:#fff7ed,color:#1e1e1e;\n\tclassDef userResource stroke:#1971c2,fill:#eff6ff,color:#1e1e1e;\n\tclassDef entry stroke:#e03131,fill:#fff5f5,color:#1e1e1e;\n\tclassDef neutral stroke:#1e1e1e,fill:#ffffff,color:#1e1e1e;\n\n\tclass EntryA entry;\n\tclass ExplorerA,Frontend,Wrapper miniflareA;\n\tclass UserWorker,KV userResource;\n\tclass Client,Incoming,Runtime,FS,Registry,DOState,EntryB,ExplorerB,Etc neutral;\n```\n","AGENTS.md":"# AGENTS.md\n\nThis file helps AI coding agents work effectively in the Cloudflare Workers SDK\nmonorepo. Prefer authoritative configuration and documentation over copying\ndetails into this file: copied versions, rule lists, and counts become stale.\n\n## Start Here\n\n- Use `pnpm`, not npm or yarn.\n- Use the Node.js and pnpm versions declared in `package.json`.\n- Install dependencies with `pnpm install`.\n- Run commands from the workspace root unless package documentation says\n  otherwise.\n- Before changing a package, read its `AGENTS.md` if it has one.\n- Do not edit generated files directly. Change their source or generator and\n  regenerate them.\n\n## Common Commands\n\nThe root `package.json` is authoritative for available scripts.\n\n- `pnpm build` — build the workspace with Turbo.\n- `pnpm test:ci` — run tests in CI mode.\n- `pnpm test:e2e` — run end-to-end tests; many require Cloudflare credentials.\n- `pnpm check` — run the repository's validation, lint, type, and format checks.\n- `pnpm fix` — apply supported lint and formatting fixes.\n- `pnpm prettify` — format files with oxfmt.\n- `pnpm run <script> --filter <package>` — run a Turbo task for one package.\n- `pnpm -w test:ci -F <package> -- <test-file>` — run a package's specific test\n  file when its test configuration supports it.\n\nPrefer the narrowest relevant test while developing, then run the broader\npackage checks appropriate to the change. Do not run credentialed E2E tests\nunless the task and environment support them.\n\n## Repository Map\n\n| Task                                        | Location                                                              | Notes                                                         |\n| ------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |\n| Add or modify a Wrangler command            | `packages/wrangler/src/`                                              | Commands are registered from `src/index.ts`.                  |\n| Change local development behavior           | `packages/miniflare/src/`                                             | `src/index.ts` contains the main `Miniflare` class.           |\n| Modify embedded runtime workers             | `packages/miniflare/src/workers/`                                     | Worker scripts use `worker:` virtual imports.                 |\n| Change project scaffolding                  | `packages/create-cloudflare/`                                         | Templates and framework support live here.                    |\n| Change the Vite integration                 | `packages/vite-plugin-cloudflare/`                                    | Includes package-specific playgrounds.                        |\n| Change the Vitest integration               | `packages/vitest-plugin/`                                             | Vitest integration for tests running in workerd.              |\n| Change shared config handling               | `packages/workers-utils/src/config/`                                  | Shared types, normalization, and validation.                  |\n| Use shared test helpers                     | `packages/workers-utils/src/test-helpers/`                            | Includes temporary-directory and console helpers.             |\n| Change deploy or versions-upload validation | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | Keep deploy and versions-upload behavior aligned.             |\n| Add a fixture                               | `fixtures/`                                                           | Fixtures are workspace members with their own `package.json`. |\n| Change CI                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the main test workflow.               |\n| Change deployment tooling                   | `tools/deployments/`                                                  | Scripts run directly through `esbuild-register`.              |\n| Create a changeset                          | `.changeset/README.md`                                                | Read this file before deciding whether one is required.       |\n\nTurbo orchestrates workspace tasks. Shared TypeScript configuration lives in\n`packages/workers-tsconfig/`; lint and formatting behavior is defined by\n`.oxlintrc.jsonc`, `.oxfmtrc.jsonc`, and `packages/lint-config-shared/`.\n\n## Cross-Tool Development Features\n\nWrangler, the Vite plugin, and the Vitest plugin are all consumers of the\nWorkers development platform. A development feature is not complete merely\nbecause it works through one of them.\n\nImplement development features in Miniflare wherever possible so that every\nconsumer benefits from the same behavior. Keep the integration layers in\nWrangler, the Vite plugin, and the Vitest plugin thin instead of implementing\nequivalent behavior independently in each tool. If Miniflare is not the\nappropriate layer, put shared behavior in the lowest suitable shared package.\n\nWhen adding or changing development functionality:\n\n- assess its impact on Miniflare, Wrangler, the Vite plugin, and the Vitest\n  plugin;\n- update shared configuration types, validation, and runtime behavior where\n  applicable;\n- add coverage at the shared implementation layer; add consumer-specific tests\n  when the consumer's integration or behavior is affected;\n- document intentional differences or unsupported consumers in the change and\n  pull request.\n\n## Implementation Conventions\n\nThe checked-in configuration is authoritative. Run `pnpm check` rather than\nrelying on a duplicated list of every enforced rule. In particular:\n\n- Keep TypeScript strictly typed. Avoid `any`, non-null assertions, and floating\n  promises.\n- Use type-only imports where appropriate and `node:` prefixes for Node.js\n  built-ins.\n- Prefer function declarations for named or exported functions.\n- Add well-formatted JSDoc to exported or public functions and to functions whose\n  purpose is not evident, including useful tags such as `@param` and `@returns`\n  where appropriate.\n- Comments should explain why; do not add comments that merely restate code.\n- Lint-disable comments require a reason after `--`.\n- In Wrangler, use the logger rather than calling `console.*` directly, except\n  inside the logger implementation.\n- For Cloudflare v4 API calls, prefer the existing request helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult`. Reuse or inject\n  these helpers in shared packages rather than adding the `cloudflare` package\n  solely for a simple request. Use the Cloudflare TypeScript SDK when its\n  generated API surface or behavior is materially useful.\n- Import `ci-info` through its default export.\n\noxfmt determines whitespace, quoting, import order, and package.json sorting.\nDo not reproduce those rules manually; run `pnpm prettify`.\n\n## Dependencies and Security\n\n- Packages normally bundle their dependencies. The repository validator in\n  `tools/deployments/validate-package-dependencies.ts` is authoritative.\n- A package that must leave a dependency external declares it in that package's\n  `scripts/deps.ts` as part of `EXTERNAL_DEPENDENCIES`, with an explanation.\n- After changing dependencies, run `pnpm install` so that the lockfile is\n  updated.\n- Do not build shell commands with interpolated or concatenated untrusted input.\n  The custom `workers-sdk/no-unsafe-command-execution` oxlint rule enforces the\n  repository's command-execution constraints.\n\n## Testing Conventions\n\n- Use Vitest for unit and integration tests.\n- Use fixtures for filesystem and Worker scenarios; treat fixtures as\n  user-facing examples and keep them clear and realistic.\n- Use the Vitest plugin when behavior must be tested in workerd.\n- In Vitest tests, obtain `expect` from the test context rather than importing\n  it from `vitest`. Pass `ExpectStatic` to helpers that need it; use\n  `node:assert` where test context is unavailable.\n- Prefer `runInTempDir()` and real filesystem operations over filesystem mocks.\n- Use `mockConsoleMethods()` to capture output and assert against its `out`,\n  `err`, and `warn` properties.\n- Update relevant snapshots when changing user-facing output.\n- New examples under `fixtures/vitest-plugin-examples/` need a\n  `tsconfig.json`.\n\nThe shared defaults are defined in `vitest.shared.ts`; package configurations\nmay override them.\n\n## Changes and Pull Requests\n\n- Work on a branch rather than committing directly to `main`.\n- Read `.changeset/README.md` to determine whether a changeset is required and\n  how to write it. Do not assume every package-code change needs one.\n- Use `.github/PULL_REQUEST_TEMPLATE.md` when preparing a pull request.\n- The PR description requirements are enforced by\n  `tools/deployments/validate-pr-description.ts`; treat that validator and the\n  template as authoritative.\n- Use the repository's established `[package] description` PR-title style.\n- Run the relevant tests and checks locally before pushing.\n\n## Package-Specific Guidance\n\nMany packages provide their own `AGENTS.md`. Locate and read the closest\napplicable file before making changes. When a change makes guidance inaccurate,\nupdate that file in the same change. Put package-specific knowledge in the\npackage's file; keep this root file focused on repository-wide workflow and\nnavigation.\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","packages/build-output-utils/README.md":"# `@cloudflare/build-output-utils`\n\nUtilities for reading and writing the Build Output Specification directory (`.cloudflare/output/`).\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/chrome-devtools-patches/README.md":"# Workers Devtools\n\nThis package contains a Workers specific version of Chrome Devtools that is used by the Wrangler dev command and other applications. It is a customized fork of Chrome DevTools specifically tailored for debugging Cloudflare Workers. This package provides Worker-specific functionality through carefully maintained patches on top of Chrome DevTools.\n\n## Overview\n\nThis package is used across multiple Cloudflare products:\n\n- Workers Playground (`workers-playground`)\n- Quick Editor (`@cloudflare/quick-edit`)\n- Wrangler CLI via the `InspectorProxy`\n\n## Features\n\nOur customized DevTools implementation provides:\n\n- Source code viewing and live updates\n- Network request inspection\n- Worker-specific UI optimizations\n\n## Development\n\nWe maintain this fork by applying patches on top of Chrome DevTools. These patches need to be periodically rebased as Chrome DevTools evolves.\n\n**Key Development Tasks:**\n\n- Generating patches from our customizations\n- Rebasing patches onto new Chrome DevTools versions\n- Testing functionality across all integration points\n\n## Updating DevTools\n\nWe perform quarterly updates to stay current with upstream Chrome DevTools. The update process involves:\n\n1. Cloning the devtools-frontend repo\n2. Applying our existing patches\n3. Rebasing onto the latest Chrome DevTools\n4. Regenerating patches\n5. Thorough testing across all integration points\n\n**For detailed instructions on updating DevTools, please refer to our internal documentation on keeping devtools up-to-date.**\n\n## Testing\n\nTwo methods are available for testing updates:\n\n**Local Development:**\n\n- Build and serve DevTools locally\n- Test against local Playground instance\n- Make targeted fixes as needed\n\n**Preview Builds:**\n\nOn any pull request to the repo on GitHub, you can add the `preview:chrome-devtools-patches` label to trigger a preview build of the DevTools frontend. This is useful because it will allow you to manually test your changes in a live environment, and with one-click.\n\nOnce the preview is built, you will see a comment on the PR with a link to the live URL.\n\n## Acceptance Criteria\n\nOur DevTools implementation must maintain full functionality across:\n\n- Console operations (logging, errors, filters)\n- Source code viewing and debugging\n- Network request inspection\n- Worker-specific UI customizations\n\n## Contributing\n\nWhen making changes:\n\n- Keep patches minimal and targeted\n- Prefer CSS-based UI modifications\n- Test thoroughly across all integration points\n- Document any new patches or modifications\n\n## Deployment\n\nThis package is deployed as a Cloudflare Workers + Assets project. The static DevTools frontend is served directly from Workers Assets, configured via `wrangler.jsonc`.\n\nDeployments are managed by GitHub Actions:\n\n- deploy-previews.yml:\n  - Runs on any PR that has the `preview:chrome-devtools-patches` label.\n  - Uploads a preview version (without activating it in production) via `wrangler versions upload`.\n  - The preview URL is posted as a comment on the PR.\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production via `wrangler deploy`.\n  - Production is accessible via the custom domain [https://devtools.devprod.cloudflare.dev/].\n","packages/cli/README.md":"# Cloudflare CLI\n\n> Internal utility package for workers-sdk. Not intended for external use — APIs may change without notice.\n\nAll things related to rendering the CLI for workers-sdk.\n","packages/codemods/README.md":"# `@cloudflare/codemods`\n\nCodemods for upgrading Cloudflare developer projects.\n\nRun a codemod by name:\n\n```sh\nnpx @cloudflare/codemods vitest:v3-to-v4\n```\n\nAvailable codemods:\n\n- `wrangler-to-cf` - migrate a Wrangler configuration to the new `cf`\n  configuration format\n- `vitest:v3-to-v4` — migrate `@cloudflare/vitest-pool-workers` configuration from\n  Vitest v3 to v4\n- `vitest:pool-workers-to-vitest-plugin` — rename `@cloudflare/vitest-pool-workers`\n  to `@cloudflare/vitest-plugin` v1\n\nUse `--dry-run` to list changes without writing them, `--cwd <path>` to target\nanother project, or repeat `--files <glob>` to restrict the files considered.\nWhen the target is inside a Git worktree, the worktree must be clean. Use\n`--force` to bypass this safety check.\n\nTo migrate a Wrangler project with the default Vite bundler:\n\n```sh\nnpx @cloudflare/codemods wrangler-to-cf --cwd ./path/to/project\n```\n\nThe CLI detects a single root `wrangler.json`, `wrangler.jsonc`, or `wrangler.toml`. Pass `--config <path>` to select another file, or pass `--bundler wrangler` to retain Wrangler-specific tooling configuration. For this codemod, `--files` filters the selected Wrangler config and skips the migration when it does not match.\n\n## Programmatic usage\n\nCodemods can also be run from JavaScript or TypeScript:\n\n```ts\nimport { runCodemod } from \"@cloudflare/codemods\";\n\nconst { changedFiles } = await runCodemod(\"vitest:v3-to-v4\", {\n\tcwd: process.cwd(),\n\tdryRun: false,\n});\n```\n\n`runCodemod` accepts the same codemod names and aliases as the CLI. Its context also accepts optional `files` and `force` fields corresponding to the CLI flags, and setting `dryRun` lists changed files without writing them. It returns a `CodemodResult` containing `changedFiles` and rejects if the codemod cannot be run. The CLI's clean-worktree check also applies to programmatic runs.\n\n### Migrate Wrangler config to cf\n\nPass the exact Wrangler config file to `migrateWranglerToCf`:\n\n```ts\nimport { migrateWranglerToCf } from \"@cloudflare/codemods\";\n\nconst result = await migrateWranglerToCf(\"./wrangler.jsonc\", {\n\tbundler: \"vite\",\n});\n```\n\nThe options object and all of its fields are optional. The defaults are the Vite bundler, writes enabled, dirty-worktree protection enabled, and automatic dependency installation enabled. The migration installs `cf` when missing, installs `@cloudflare/vite-plugin@beta` when Vite is selected and the plugin is missing or incompatible, and upgrades Wrangler when generated Wrangler tooling requires a newer version. The Vite plugin dependency remains set to the `beta` dist tag in `package.json`; package manager installation updates the project's lockfile. Project-managed Vite plugin specifiers such as `workspace:` and `catalog:` are preserved; incompatible or unverified versions require a manual update. Set `installDependencies` to `false` to prevent dependency changes; required dependencies are then returned as blocking follow-ups. The migration always creates `cloudflare.config.ts`; selecting the Wrangler bundler also creates `wrangler.config.ts` when Wrangler-specific tooling config exists. Existing target files are never overwritten. Inspect `result.followUps` when `result.status` is `needs-intervention`.\n","packages/config/README.md":"# `@cloudflare/config`\n\nDefinitions and utilities for configuring Cloudflare Workers and related products.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/containers-shared/README.md":"# @cloudflare/containers-shared\n\nInternal shared container functionality for Cloudflare Workers SDK.\n\n## Internal Use Only\n\nThis package is published only for internal use.\n\nDo not depend on this package directly from external projects. It is not a\npublic SDK, it does not provide a stable API surface, and any function, type,\nexport, behavior, or file path contained in this package may change or be\nremoved at any time without notice.\n\nNo semver compatibility is promised for consumers outside Cloudflare's own\nWorkers SDK packages.\n\n- Cloudchamber/Containers API client\n- Utils for constructing and running docker commands\n- SSH transport shared by Wrangler and cf (OpenSSH and stdio proxy modes)\n- Managed registry image list/delete operations shared by Wrangler and cf\n","packages/create-cloudflare/AGENTS.md":"# AGENTS.md — Create Cloudflare (C3)\n\n## OVERVIEW\n\nProject scaffolding CLI for Cloudflare Workers. Main source entry: `src/cli.ts`. Bin entry: `bin/c3.js` (Node.js version gate shim).\n\n## STRUCTURE\n\n- `bin/c3.js` — Bin shim that checks Node.js version before requiring `dist/cli.js`\n- `src/cli.ts` — Main entry. Exports `main(argv)` for programmatic use\n- `templates/` — Scaffolding templates (excluded from linting and most formatting)\n- `src/wrangler/` — Wrangler config, login, and account helpers\n- `src/cf/` — Helpers for projects configured by `cloudflare.config.ts`, which use the `cf` CLI instead of Wrangler (detected with `usesCfCli`)\n- `scripts/build.ts` — esbuild-based build → `dist/cli.js`\n\n## BUILD\n\n- esbuild bundles `src/cli.ts` as CJS → `dist/cli.js`\n- `package.json` `main` and `exports[\".\"]` point at `dist/cli.js`; `bin` points at `bin/c3.js`\n- `bin/c3.js` is a plain CommonJS shim that gates on Node.js version (read from `package.json` `engines.node`) before requiring `dist/cli.js`\n\n## CONVENTIONS\n\n- `no-console: error` — use project's logging utilities\n- Templates excluded from linting (except `c3.ts` files within templates)\n- Templates excluded from formatting (except hello-world templates)\n\n## TESTING\n\n- E2E tests run across pnpm/npm (yarn/bun also supported but not in CI), Linux/Windows\n- Own vitest setup: mocks `log-update` and `@cloudflare/cli-shared-helpers/streams`\n- CI has experimental matrix for framework testing\n- Framework CI uses case shards within one test file (three normal, two experimental), controlled by `E2E_FRAMEWORK_SHARD`. Preserve coverage across every shard and keep shard selections in the test's Turbo cache inputs.\n- Whole-framework tests retain one retry for transient failures in external registries, generators, and runtime startup. Per-case allowances live in `e2e/tests/frameworks/test-config.ts`; `E2E_TEST_RETRIES=0` disables retries for local investigations. Keep recovered attempts visible in retry reports and fix their causes before reducing allowances.\n- Python/UV installed in CI for Python framework E2E tests\n","packages/create-cloudflare/README.md":"# create-cloudflare\n\nA CLI for creating and deploying new applications to [Cloudflare](https://developers.cloudflare.com/).\n\nFor more details on how to use the create-cloudflare CLI (C3) please visit the [official C3 documentation](https://developers.cloudflare.com/pages/get-started/c3).\n\n### Community\n\n- Join us [on Discord](https://discord.cloudflare.com)\n- File an issue [on GitHub](https://github.com/cloudflare/workers-sdk/issues/new/choose)\n","packages/create-cloudflare/e2e/README.md":"# C3 E2E tests\n\nThis directory contains the e2e tests and helpers for C3.\n\n## Running tests locally\n\nThere are three groups of tests:\n\n- CLI - general tests against the C3 CLI tool, such as interactive prompts\n- Workers - tests of the non-framework C3 templates such as `hello-world-durable-object-with-assets-ts`.\n- Frameworks - tests of the framework C3 templates, such as `astro:workers`, `qwik:pages`, etc.\n\n- To run all the tests locally you can do run the following from the root of the monorepo:\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare\n  ```\n\n  This command will actually run the `test:e2e` turbo task in the `create-cloudflare` package, which will also ensure that any dependencies have been built correctly first.\n\n- To run just one group of tests (pass the group name to underlying command):\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare -- workers\n  ```\n\n  You can choose from `cli`, `workers` or `frameworks`.\n\nThe tests that run can be controlled by combining any of the following environment variables:\n\n- `E2E_EXPERIMENTAL` - whether to run the tests in experimental mode - without this variable only non-experimental tests are run.\n- `E2E_TEST_PM` + `E2E_TEST_PM_VERSION` - which package manager to simulate in the tests - without these variables the tests simulate `pnpm`.\n- `E2E_RUN_DEPLOY_TESTS` - whether to ask C3 to deploy generated projects and run tests against the deployed version - if this is not set to `\"true\"`, generated projects are only tested locally.\n- `CLOUDFLARE_API_TOKEN` - the API token to use in tests that connect to Cloudflare - without this variable tests that require Cloudflare access are skipped.\n- `E2E_FRAMEWORK_SHARD` - optional framework case shard in the form `index/count`, with a one-based index. Invalid values fail the run. Without it, all matching cases are collected, including skipped cases.\n- `E2E_TEST_RETRIES` - optional non-negative integer override for framework whole-test retries. Framework tests retain one whole-test retry because they exercise external registries, generators, and runtime startup. Cases can override this allowance in `test-config.ts`. Set this to `0` when investigating a failure or measuring first-attempt reliability. Readiness polling within each attempt is unchanged.\n\n### Running a framework shard\n\nAll framework cases live in one file, so Vitest's file sharding cannot divide this suite. CI runs three case shards per normal package-manager entry and two shards for experimental pnpm. Each runner retains Vitest's default limit of five concurrent tests.\n\nTo reproduce a shard locally, run:\n\n```bash\nE2E_FRAMEWORK_SHARD=1/3 pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nCases are sorted by their full names and distributed round-robin after applying the framework filter and excluding quarantined or unsupported cases. New frameworks and variants are assigned automatically. Use the same package manager, package-manager version, experimental mode, filter, and shard count as CI to reproduce its selection.\n\nThe existing required framework checks wait for every framework shard. Failed, cancelled, or skipped shard jobs fail these checks; deliberately skipped test steps still succeed when framework coverage is not requested.\n\nCI publishes per-attempt logs, Vitest's `results.json`, Turbo summaries, and a retry report. The reported Vitest test duration includes waiting for a concurrency slot, hooks, and all attempts, so use the job/Turbo task duration to measure the critical path. Cached test replays are excluded from retry reports.\n\nTreat a recovered attempt as evidence of a reliability problem, even when CI passes. Keep the single retry while addressing the cause; reduce an allowance only after repeated fresh runs support doing so. A repeatable regression should fail the check, and another attempt should not be used to hide it.\n\nEach attempt shares an absolute package-manager cache across its child processes, outside the generated project. This prevents C3's Git initialization from committing cache contents while isolating concurrent installs. The fixture removes both the project and its cache after the attempt. Wrangler's test configuration uses an automatically assigned inspector port to avoid collisions between concurrent preview sessions.\n\n### Running in experimental mode\n\nC3 can be run in experimental mode, by passing `--experimental` to it as a CLI argument. By default the tests will run in non-experimental mode.\nTo run the tests in experimental mode, simply pass `E2E_EXPERIMENTAL=true` as an environment variable.\n\nFor example, to run the \"cli\" group in experimental mode:\n\n```bash\nE2E_EXPERIMENTAL=true pnpm test:e2e -F create-cloudflare -- cli\n```\n\n> This experimental environment variable can be combined with the package manager environment variables below.\n\n### Running against different package managers\n\nC3 supports running sub-commands and installs using a range of package managers. By default the tests will run agains `pnpm`.\nTo run the tests using a different package manager, simply pass `E2E_TEST_PM` and `E2E_TEST_PM_VERSION` as environment variables.\n\nFor example, to run the \"workers\" group using yarn@1.22.22.\n\n```bash\nE2E_TEST_PM=yarn E2E_TEST_PM_VERSION=1.22.22 pnpm test:e2e -F create-cloudflare -- workers\n```\n\n> These package manager environment variables can be combined with the experimental environment variable above.\n\n### Running Workers templates individually\n\nTo run the e2e tests against a specific Worker template (or group of Worker template variants), provide the `E2E_WORKER_TEMPLATE_TO_TEST` environment variable.\n\nWorker template names and their variants are delimited by colons (`:`).\nIf no colon is specified then all variants will be run for the matching template name.\n\nFor example to only run the python version of the `hello-world-durable-objects` template:\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-durable-object:python pnpm test:e2e -F create-cloudflare -- workers\n```\n\nTo run all the `hello-world-with-assets` variants (`js`, `python`, `ts`):\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-with-assets pnpm test:e2e -F create-cloudflare -- workers\n```\n\n### Running Web frameworks templates individually\n\nTo run the e2e tests against a specific Web framework (or group of Worker template variants), provide the `E2E_FRAMEWORK_TEMPLATE_TO_TEST` environment variable.\n\nFramework templates and their variants (`pages` or `workers`) are delimited by colons (`:`).\nIf no colon is specified in the filter then all variants will be run for the matching template.\n\nFor example to only run the `workers` version of the `react-router` framework:\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=react-router:workers pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nTo run all the `qwik` framework variants (`pages`, `workers`):\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=qwik pnpm test:e2e -F create-cloudflare -- frameworks\n```\n","packages/create-cloudflare/templates/django/py/README.md":"# Django on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/fastapi/py/README.md":"# FastAPI on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/flask/py/README.md":"# Flask on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world-durable-object/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world-with-assets/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/openapi/ts/README.md":"# Cloudflare Workers OpenAPI 3.1\n\nThis is a Cloudflare Worker with OpenAPI 3.1 using [chanfana](https://github.com/cloudflare/chanfana) and [Hono](https://github.com/honojs/hono).\n\nThis is an example project made to be used as a quick start into building OpenAPI compliant Workers that generates the\n`openapi.json` schema automatically from code and validates the incoming request to the defined parameters or request body.\n\n## Get started\n\n1. Sign up for [Cloudflare Workers](https://workers.dev). The free tier is more than enough for most use cases.\n2. Clone this project and install dependencies with `npm install`\n3. Run `wrangler login` to login to your Cloudflare account in wrangler\n4. Run `wrangler deploy` to publish the API to Cloudflare Workers\n\n## Project structure\n\n1. Your main router is defined in `src/index.ts`.\n2. Each endpoint has its own file in `src/endpoints/`.\n3. For more information read the [chanfana documentation](https://chanfana.pages.dev/) and [Hono documentation](https://hono.dev/docs).\n\n## Development\n\n1. Run `wrangler dev` to start a local instance of the API.\n2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints.\n3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface.\n","packages/create-cloudflare/templates/react-router/ts/README.md":"# Welcome to React Router!\n\nA modern, production-ready template for building full-stack React applications using React Router.\n\n## Features\n\n- 🚀 Server-side rendering\n- ⚡️ Hot Module Replacement (HMR)\n- 📦 Asset bundling and optimization\n- 🔄 Data loading and mutations\n- 🔒 TypeScript by default\n- 🎉 TailwindCSS for styling\n- 📖 [React Router docs](https://reactrouter.com/)\n\n## Getting Started\n\n### Installation\n\nInstall the dependencies:\n\n```bash\nnpm install\n```\n\n### Development\n\nStart the development server with HMR:\n\n```bash\nnpm run dev\n```\n\nYour application will be available at `http://localhost:5173`.\n\n## Previewing the Production Build\n\nPreview the production build locally:\n\n```bash\nnpm run preview\n```\n\n## Building for Production\n\nCreate a production build:\n\n```bash\nnpm run build\n```\n\n## Deployment\n\nDeployment is done using the Wrangler CLI.\n\nTo build and deploy directly to production:\n\n```sh\nnpm run deploy\n```\n\nTo deploy a preview URL:\n\n```sh\nnpx wrangler versions upload\n```\n\nYou can then promote a version to production after verification or roll it out progressively.\n\n```sh\nnpx wrangler versions deploy\n```\n\n## Styling\n\nThis template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.\n\n---\n\nBuilt with ❤️ using React Router.\n","packages/format-errors/README.md":"# format-errors\n\nA Worker that will nicely format errors, optionally inflating with source context if available.\n\n<table>\n     <tr><td><img src=\"./images/service-worker.png\"></td><td><img src=\"./images/modules-worker.png\"></td></tr>\n</table>\n\n## Why is this needed?\n\nIn development, it's nice to have good error messages to help when debugging, and ideally the logic for that shouldn't be bundled into your user Worker. This Worker is ~50kb when gzipped, which doesn't add _that_ much, but there's still a benefit to keeping it separate from the user Worker. Additionally, in environments where we're unable to bundle complex Workers, this error formatting Worker allows for the display of useful errors where otherwise only a stack trace would be available.\n\n## How does it work?\n\nFundamentally, this is based on [Youch](https://github.com/poppinss/youch) and [StackTracey](https://github.com/xpl/stacktracey). Neither of these projects are designed to be run in the Workers environment (although StackTracey does have support for running in the browser), and so both have been vendored in and modified. These modifications aren't upstreamable, since they involve things like changing how Youch detects node-internal modules and changing how sources are loaded.\n\n### Youch changes:\n\n- **\"internal\" module detection:** By default, Youch recognises modules with a prefix of `node:` to be internal modules. Instead, `format-error`s recognises modules with a prefix of `.internal` as internal modules.\n- **source loading:** Youch loads sources at error-page generation time, `format-error`s loads sources at error-page viewing time.\n- **cookies:** `format-error`s doesn't handle cookies.\n\n### Stacktracey changes:\n\n- **browser detection:** `format-error`s always reports itself to be running inside a browser, but removes references to browser globals like `window`.\n- **table rendering:** To remove the `as-table` dependency, `format-error` doesn't implement Stacktracey's `asTable` method, which Youch doesn't use.\n\n## How can you get a formatted error page?\n\nThe first thing you'll need is an error. `format-errors` requires input conforming to the `Payload` interface below, and will reject invalid input at runtime:\n\n```ts\nexport interface JsonError {\n\tmessage?: string;\n\tname?: string;\n\tstack?: string;\n\tcause?: JsonError;\n}\nexport interface Payload {\n\turl?: string;\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\terror?: JsonError;\n}\n```\n\nTo call `format-errors` (assuming it's hosted at `https://format-errors.example.com`), send a `POST` request to `https://format-errors.example.com` with a body containing a serialised `Payload` object. `format-errors` will parse your input, pass it to Youch, and generate an HTML page which will be sent back as the response to the `POST` request.\n\nIf you don't need source context, you can stop there! However, if you'd like to get rid of the \"Missing sources\" message, there's a bit more complexity.\n\n> _Why can't I just pass sources to `format-error` in the request body?_\n>\n> Often your sources won't be available at the location where your error is thrown. You may have access to a sourcemap, but your running code probably doesn't have access to your source code in serialised format. As such, this package is geared towards supporting use cases where you have access to your sources at the time of _viewing_ the generated error page (i.e. in-browser editors).\n\nA requirement of passing sources to `format-errors` is that the generated HTML error page needs to be embedded in an iframe. Once you've done that, you can start passing sources from the embedder of the iframe into the generated HTML error page.\n\nAssuming `iframeEl` is a reference to the iframe which embeds the generated error page, here's an example of how you could pass sources to the generated error page:\n\n```ts\nconst encoder = new TextEncoder();\nconst channel = new MessageChannel();\n\niframeEl.addEventListener(\"load\", () => {\n\tiframeEl.contentWindow?.postMessage(\"PORT\", \"*\", [channel.port2]);\n});\n\nchannel.port1.onmessage = (data) => {\n\tif (data.type === \"RequestSources\") {\n\t\tconst message = {\n\t\t\ttype: \"SourcesLoaded\",\n\t\t\tbody: {\n\t\t\t\tfiles: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpath: \"index.js\",\n\t\t\t\t\t\tcontents: encoder.encode(\"console.log('hi')\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinternalLines: 0,\n\t\t\t},\n\t\t};\n\t\tchannel.port1.postMessage(\n\t\t\tmessage,\n\t\t\tmessage.body.files.map((f) => f.contents.buffer)\n\t\t);\n\t}\n};\n```\n\nThe interface is fairly simple. The embedder passes a `MessagePort` to the iframe on load, over which the error page requests sources. Of note: this does not currently support sourcemaps, and it's assumed that the lines within your error stack trace map to the exact line in your source.\n\nThere's one exception to that, to support _very_ limited source transformations, in the `internalLines` property. If you pass a value for `internalLines`, the error page will act as if any error messages from line numbers _below_ `internalLines` are internal, and shouldn't be surfaced to the user. Line numbers in error messages will be remapped so that it appears the user-visible source starts at line `0`, rather than line `internalLines`.\n","packages/kv-asset-handler/README.md":"# @cloudflare/kv-asset-handler\n\n[![npm](https://img.shields.io/npm/v/@cloudflare/kv-asset-handler.svg)](https://www.npmjs.com/package/@cloudflare/kv-asset-handler) &nbsp;\n[![Run npm tests](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml) &nbsp;\n[![Lint Markdown](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml) &nbsp;\n\n`kv-asset-handler` is an open-source library for managing the retrieval of static assets from [Workers KV](https://developers.cloudflare.com/workers/runtime-apis/kv) inside of a [Cloudflare Workers](https://workers.dev) function. `kv-asset-handler` is designed for use with [Workers Sites](https://developers.cloudflare.com/workers/platform/sites), a feature included in [Wrangler](https://github.com/cloudflare/wrangler), our command-line tool for deploying Workers projects.\n\n`kv-asset-handler` runs as part of a Cloudflare Workers function, so it allows you to customize _how_ and _when_ your static assets are loaded, as well as customize how those assets behave before they're sent to the client.\n\nMost users and sites will not need these customizations, and just want to serve their statically built applications. For that simple use-case, you can check out [Cloudflare Pages](https://pages.cloudflare.com), our batteries-included approach to deploying static sites on Cloudflare's edge network. Workers Sites was designed as a precursor to Cloudflare Pages, so check out Pages if you just want to deploy your static site without any special customizations!\n\nFor users who _do_ want to customize their assets, and want to build complex experiences on top of their static assets, `kv-asset-handler` (and the default [Workers Sites template](https://github.com/cloudflare/worker-sites-template), which is provided for use with Wrangler + Workers Sites) allows you to customize caching behavior, headers, and anything else about how your Workers function loads the static assets for your site stored in Workers KV.\n\nThe Cloudflare Workers Discord server is an active place where Workers users get help, share feedback, and collaborate on making our platform better. The `#workers` channel in particular is a great place to chat about `kv-asset-handler`, and building cool experiences for your users using these tools! If you have questions, want to share what you're working on, or give feedback, [join us in Discord and say hello](https://discord.cloudflare.com)!\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [`getAssetFromKV`](#getassetfromkv)\n  - [Example](#example)\n  * [Return](#return)\n  * [Optional Arguments](#optional-arguments)\n    - [`mapRequestToAsset`](#maprequesttoasset)\n    - [Example](#example-1)\n    - [`cacheControl`](#cachecontrol)\n      - [`browserTTL`](#browserttl)\n      - [`edgeTTL`](#edgettl)\n      - [`bypassCache`](#bypasscache)\n    - [`ASSET_NAMESPACE` (required for ES Modules)](#asset_namespace-required-for-es-modules)\n    - [`ASSET_MANIFEST` (required for ES Modules)](#asset_manifest-required-for-es-modules)\n    - [`defaultETag`](#defaultetag-optional)\n\n* [Helper functions](#helper-functions)\n  - [`mapRequestToAsset`](#maprequesttoasset-1)\n  - [`serveSinglePageApp`](#servesinglepageapp)\n* [Cache revalidation and etags](#cache-revalidation-and-etags)\n\n## Installation\n\nAdd this package to your `package.json` by running this in the root of your\nproject's directory:\n\n```\nnpm i @cloudflare/kv-asset-handler\n```\n\n## Usage\n\nThis package was designed to work with [Worker Sites](https://workers.cloudflare.com/sites).\n\n## `getAssetFromKV`\n\ngetAssetFromKV(Evt) => Promise<Response>\n\n`getAssetFromKV` is an async function that takes an `Evt` object (containing a `Request` and a [`waitUntil`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#waituntil)) and returns a `Response` object if the request matches an asset in KV, otherwise it will throw a `KVError`.\n\n#### Example\n\nThis example checks for the existence of a value in KV, and returns it if it's there, and returns a 404 if it is not. It also serves index.html from `/`.\n\n### Return\n\n`getAssetFromKV` returns a `Promise<Response>` with `Response` being the body of the asset requested.\n\nKnown errors to be thrown are:\n\n- MethodNotAllowedError\n- NotFoundError\n- InternalError\n\n#### ES Modules\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\nconst assetManifest = JSON.parse(manifestJSON);\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tif (request.url.includes(\"/docs\")) {\n\t\t\ttry {\n\t\t\t\treturn await getAssetFromKV(\n\t\t\t\t\t{\n\t\t\t\t\t\trequest,\n\t\t\t\t\t\twaitUntil(promise) {\n\t\t\t\t\t\t\treturn ctx.waitUntil(promise);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t\t\t\t\t\tASSET_MANIFEST: assetManifest,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else {\n\t\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t\t}\n\t\t\t}\n\t\t} else return fetch(request);\n\t},\n};\n```\n\n#### Service Worker\n\n```js\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\naddEventListener(\"fetch\", (event) => {\n\tevent.respondWith(handleEvent(event));\n});\n\nasync function handleEvent(event) {\n\tif (event.request.url.includes(\"/docs\")) {\n\t\ttry {\n\t\t\treturn await getAssetFromKV(event);\n\t\t} catch (e) {\n\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t// ...\n\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t// ...\n\t\t\t} else {\n\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t}\n\t\t}\n\t} else return fetch(event.request);\n}\n```\n\n### Optional Arguments\n\nYou can customize the behavior of `getAssetFromKV` by passing the following properties as an object into the second argument.\n\n```\ngetAssetFromKV(event, { mapRequestToAsset: ... })\n```\n\n#### `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nMaps the incoming request to the value that will be looked up in Cloudflare's KV\n\nBy default, mapRequestToAsset is set to the exported function [`mapRequestToAsset`](#maprequesttoasset-1). This works for most static site generators, but you can customize this behavior by passing your own function as `mapRequestToAsset`. The function should take a `Request` object as its only argument, and return a new `Request` object with an updated path to be looked up in the asset manifest/KV.\n\nFor SPA mapping pass in the [`serveSinglePageApp`](#servesinglepageapp) function\n\n#### Example\n\nStrip `/docs` from any incoming request before looking up an asset in Cloudflare's KV.\n\n```js\nimport { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'\n...\nconst customKeyModifier = request => {\n  let url = request.url\n  //custom key mapping optional\n  url = url.replace('/docs', '').replace(/^\\/+/, '')\n  return mapRequestToAsset(new Request(url, request))\n}\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: customKeyModifier })\n```\n\n#### `cacheControl`\n\ntype: object\n\n`cacheControl` allows you to configure options for both the Cloudflare Cache accessed by your Worker, and the browser cache headers sent along with your Workers' responses. The default values are as follows:\n\n```javascript\nlet cacheControl = {\n\tbrowserTTL: null, // do not set cache control ttl on responses\n\tedgeTTL: 2 * 60 * 60 * 24, // 2 days\n\tbypassCache: false, // do not bypass Cloudflare's cache\n};\n```\n\n##### `browserTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response returned from the Worker. By default set to `null` which will not add the header at all.\n\n##### `edgeTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response used as the edge cache key. By default set to 2 days (`2 * 60 * 60 * 24`). When null will not cache on the edge at all.\n\n##### `bypassCache`\n\ntype: boolean\n\nDetermines whether to cache requests on Cloudflare's edge cache. By default set to `false` (recommended for production builds). Useful for development when you need to eliminate the cache's effect on testing.\n\n#### `ASSET_NAMESPACE` (required for ES Modules)\n\ntype: KV Namespace Binding\n\nThe binding name to the KV Namespace populated with key/value entries of files for the Worker to serve. By default, Workers Sites uses a [binding to a Workers KV Namespace](https://developers.cloudflare.com/workers/reference/storage/api/#namespaces) named `__STATIC_CONTENT`.\n\nIt is further assumed that this namespace consists of static assets such as HTML, CSS, JavaScript, or image files, keyed off of a relative path that roughly matches the assumed URL pathname of the incoming request.\n\nIn ES Modules format, this argument is required, and can be gotten from `env`.\n\n##### ES Module\n\n```js\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t}\n);\n```\n\n##### Service Worker\n\n```\nreturn getAssetFromKV(event, { ASSET_NAMESPACE: MY_NAMESPACE })\n```\n\n#### `ASSET_MANIFEST` (required for ES Modules)\n\ntype: text blob (JSON formatted) or object\n\nThe mapping of requested file path to the key stored on Cloudflare.\n\nWorkers Sites with Wrangler bundles up a text blob that maps request paths to content-hashed keys that are generated by Wrangler as a cache-busting measure. If this option/binding is not present, the function will fallback to using the raw pathname to look up your asset in KV. If, for whatever reason, you have rolled your own implementation of this, you can include your own by passing a stringified JSON object where the keys are expected paths, and the values are the expected keys in your KV namespace.\n\nIn ES Modules format, this argument is required, and can be imported.\n\n##### ES Module\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nlet manifest = JSON.parse(manifestJSON);\nmanifest[\"index.html\"] = \"index.special.html\";\n\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_MANIFEST: manifest,\n\t\t// ...\n\t}\n);\n```\n\n##### Service Worker\n\n```\nlet assetManifest = { \"index.html\": \"index.special.html\" }\nreturn getAssetFromKV(event, { ASSET_MANIFEST: assetManifest })\n```\n\n#### `defaultMimeType` (optional)\n\ntype: string\n\nThis is the mime type that will be used for files with unrecognized or missing extensions. The default value is `'text/plain'`.\n\nIf you are serving a static site and would like to use extensionless HTML files instead of index.html files, set this to `'text/html'`.\n\n#### `defaultDocument` (optional)\n\ntype: string\n\nThis is the default document that will be concatenated for requests ends in `'/'` or without a valid mime type like `'/about'` or `'/about.me'`. The default value is `'index.html'`.\n\n#### `defaultETag` (optional)\n\ntype: `'strong' | 'weak'`\n\nThis determines the format of the response [ETag header](https://developer.mozilla.org/docs/Web/HTTP/Headers/ETag). If the resource is in the cache, the ETag will always be weakened before being returned.\nThe default value is `'strong'`.\n\n# Helper functions\n\n## `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nThe default function for mapping incoming requests to keys in Cloudflare's KV.\n\nTakes any path that ends in `/` or evaluates to an HTML file and appends `index.html` or `/index.html` for lookup in your Workers KV namespace.\n\n## `serveSinglePageApp`\n\nserveSinglePageApp(Request) => Request\n\nA custom handler for mapping requests to a single root: `index.html`. The most common use case is single-page applications - frameworks with in-app routing - such as React Router, VueJS, etc. It takes zero arguments.\n\n```js\nimport { getAssetFromKV, serveSinglePageApp } from '@cloudflare/kv-asset-handler'\n...\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: serveSinglePageApp })\n```\n\n# Cache revalidation and etags\n\nAll responses served from cache (including those with `cf-cache-status: MISS`) include an `etag` response header that identifies the version of the resource. The `etag` value is identical to the path key used in the `ASSET_MANIFEST`. It is updated each time an asset changes and looks like this: `etag: <filename>.<hash of file contents>.<extension>` (ex. `etag: index.54321.html`).\n\nResources served with an `etag` allow browsers to use the `if-none-match` request header to make conditional requests for that resource in the future. This has two major benefits:\n\n- When a request's `if-none-match` value matches the `etag` of the resource in Cloudflare cache, Cloudflare will send a `304 Not Modified` response without a body, saving bandwidth.\n- Changes to a file on the server are immediately reflected in the browser - even when the cache control directive `max-age` is unexpired.\n\n#### Disable the `etag`\n\nTo turn `etags` **off**, you must bypass cache:\n\n```js\n/* Turn etags off */\nlet cacheControl = {\n\tbypassCache: true,\n};\n```\n\n#### Syntax and comparison context\n\n`kv-asset-handler` sets and evaluates etags as [strong validators](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#Strong_validation). To preserve `etag` integrity, the format of the value deviates from the [RFC2616 recommendation to enclose the `etag` with quotation marks](https://tools.ietf.org/html/rfc2616#section-3.11). This is intentional. Cloudflare cache applies the `W/` prefix to all `etags` that use quoted-strings -- a process that converts the `etag` to a \"weak validator\" when served to a client.\n","packages/local-explorer-ui/README.md":"# Local explorer UI\n\nThis package contains the UI for the local dev data explorer.\nThe built output will be bundled into Miniflare and served by Miniflare at `/cdn-cgi/explorer`.\n\n# API\n\nThis fetches data from an API running in Miniflare at`/cdn-cgi/explorer/api`.\n\nThe API client is generated from the OpenAPI spec in `packages/miniflare/src/workers/local-explorer/openapi.local.json`.\n\n## API Type Generation\n\nThe API client code is auto-generated from the OpenAPI spec using [`@hey-api/openapi-ts`](https://heyapi.dev/).\n\n**Configuration:** `openapi-ts.config.ts`\n\n**Input:** `packages/miniflare/src/workers/local-explorer/openapi.local.json`\n\n**Output:** `src/api/generated/`\n\nThe generated code includes:\n\n- TypeScript types for all API request/response schemas\n- A type-safe SDK client for making API calls\n\n### When does generation run?\n\n| Command        | Behavior                                               |\n| -------------- | ------------------------------------------------------ |\n| `pnpm install` | Runs `openapi-ts` in `postinstall` to generate types   |\n| `pnpm build`   | Runs `openapi-ts` before building                      |\n| `pnpm dev`     | Watches for spec changes and regenerates automatically |\n| `pnpm dev:ui`  | Same as `dev` - watches for spec changes               |\n\nIn development, the `openapi-ts --watch` process runs concurrently with Vite, automatically regenerating the client when the OpenAPI spec changes.\n\n# Developing\n\n`pnpm run dev` in this directory.\n\nOr to run a specific worker against the UI:\n\n1. Run a worker (`fixtures/worker-with-resources`) using Wrangler or Vite, making sure it is running at `localhost:8787`.\n2. Run this package with `pnpm run dev:ui`, which will spin up a dev server for just the UI using Vite.\n","packages/miniflare/AGENTS.md":"# Miniflare — Agent Guide\n\n## Overview\n\nLocal dev simulator for Cloudflare Workers, powered by workerd runtime. Main class `Miniflare` in `src/index.ts`.\n\n## Structure\n\n- `src/index.ts` — Main `Miniflare` class, server setup, plugin orchestration, all exports\n- `src/workers/` — ~30 embedded worker scripts (D1, KV, R2, caches, etc.), built via `worker:` virtual import scheme\n- `src/workers/d1/entry.worker.ts` — D1-specific HTTP/RPC entrypoint; selects a database using binding props and adapts RPC queries to the database worker's HTTP protocol\n- `src/workers/d1/database.worker.ts` — local D1 SQLite execution, transactions, metadata, and export; protocol schemas shared with the entrypoint live in `src/workers/d1/schemas.ts`\n- `src/workers/d1/export.ts` — shared local export pragma recognition and dedicated RPC export adaptation; keeps the legacy export response separate from ordinary query contracts\n- `src/workers/shared/` — Shared utilities across embedded workers\n- `src/workers/core/dev-registry-proxy.worker.ts` — Proxy worker for cross-process service bindings via debug port RPC\n- `src/workers/core/dev-registry-proxy-shared.worker.ts` — Shared proxy logic (registry Map, DO proxy class, tail serializers)\n- `src/shared/dev-registry.ts` — Filesystem-based worker registry (chokidar watch, heartbeat, stale cleanup)\n- `src/shared/persist-root-lock.ts` — Token-safe startup serialisation for shared persistent storage\n- `src/shared/DEV_REGISTRY.md` — Full architecture doc for the dev registry\n- `src/runtime/config/generated/workerd.ts` — Generated workerd Cap'n Proto config types\n- `test/` — Tests (`.spec.ts` naming, NOT `.test.ts`)\n- `test/test-shared/` — Shared test utilities\n- `scripts/build.mjs` — Custom esbuild build script\n\n## Build\n\n- Custom `scripts/build.mjs` bundles `src/index.ts` as CJS → `dist/src/index.js`\n- Also compiles ~30 embedded worker scripts via `worker:...` virtual import scheme — each triggers a nested esbuild sub-build producing standalone ESM worker scripts\n- Build outputs: `dist/`, `worker-metafiles/`\n- Release builds set `SOURCEMAPS=false` to omit package source maps; ordinary builds keep them for debugging. Non-watch builds clean `dist/` before compiling so maps from an earlier build cannot leak into a release. This does not disable user Worker source maps.\n\n## Lint Status (Transitional)\n\n- Many shared ESLint rules temporarily DISABLED: `no-explicit-any`, `consistent-type-imports`, `no-shadow`, `no-floating-promises`, others\n- Comment in config: \"temporarily enabled while we transition Miniflare to use the standard workers-sdk eslint config\"\n- `no-console: error` is on, except for `src/workers/` and `scripts/`\n\n## TypeScript\n\n- Does NOT extend shared `@cloudflare/workers-tsconfig` — has its own full config\n- Uses `experimentalDecorators`\n- Path aliases: `miniflare:shared`, `miniflare:zod`\n- `declaration: true` (emits .d.ts)\n\n## Testing\n\n- Test files use `.spec.ts` (NOT `.test.ts`)\n- `pool: \"forks\"`, `maxWorkers: 1` (limits test files to one worker)\n- Does NOT extend `vitest.shared.ts` — own full vitest config\n- Timeouts: 30s test, 30s hook\n- `globals: true`\n- Factory pattern: `miniflareTest(opts, handler?)` creates instance in `beforeAll`, disposes in `afterAll`\n- `useDispose(mf)` / `disposeWithRetry()` — exponential backoff for Windows EPERM file locking\n- `useServer()` — temp HTTP server with auto-cleanup\n- `TestLog` — captures log entries by level\n\n## Generated Files\n\n- `src/runtime/config/generated/workerd.ts` — generated Cap'n Proto types, do not edit directly\n- `src/workers/local-explorer/openapi.local.json` — generated from `scripts/openapi-filter-config.ts`, modify the config not the output\n\n## Version Pinning\n\n- Miniflare minor version must match workerd minor version\n- `tools/deployments/changeset-version.ts` enforces this: if changeset bumps miniflare minor beyond workerd's, it converts to patch\n","packages/miniflare/README.md":"# 🔥 Miniflare\n\n**Miniflare** is a simulator for developing and testing\n[**Cloudflare Workers**](https://workers.cloudflare.com/), powered by\n[`workerd`](https://github.com/cloudflare/workerd).\n\n> :warning: Miniflare is a lower level API designed for tools creators, for\n> locally developing Workers use tools built on top of Miniflare such\n> as [Wrangler](../wrangler/README.md) or the [Cloudflare Vite plugin](../vite-plugin-cloudflare/README.md).\n\n## Quick Start\n\n```shell\n$ npm install miniflare --save-dev\n```\n\n```js\nimport { Miniflare } from \"miniflare\";\n\n// Create a new Miniflare instance, starting a workerd server\nconst mf = new Miniflare({\n\tscript: `addEventListener(\"fetch\", (event) => {\n    event.respondWith(new Response(\"Hello Miniflare!\"));\n  })`,\n});\n\n// Send a request to the workerd server, the host is ignored\nconst response = await mf.dispatchFetch(\"http://localhost:8787/\");\nconsole.log(await response.text()); // Hello Miniflare!\n\n// Cleanup Miniflare, shutting down the workerd server\nawait mf.dispose();\n```\n\n## API\n\n### `type Awaitable<T>`\n\n`T | Promise<T>`\n\nRepresents a value that can be `await`ed. Used in callback types to allow\n`Promise`s to be returned if necessary.\n\n### `type Json`\n\n`string | number | boolean | null | Record<string, Json> | Json[]`\n\nRepresents a JSON-serialisable value.\n\n### `type ModuleRuleType`\n\n`\"ESModule\" | \"CommonJS\" | \"Text\" | \"Data\" | \"CompiledWasm\"`\n\nRepresents how a module's contents should be interpreted.\n\n- `\"ESModule\"`: interpret as\n  [ECMAScript module](https://tc39.es/ecma262/#sec-modules)\n- `\"CommonJS\"`: interpret as\n  [CommonJS module](https://nodejs.org/api/modules.html#modules-commonjs-modules)\n- `\"Text\"`: interpret as UTF8-encoded data, expose in runtime with\n  `string`-typed `default` export\n- `\"Data\"`: interpret as arbitrary binary data, expose in runtime with\n  `ArrayBuffer`-typed `default` export\n- `\"CompiledWasm\"`: interpret as binary WebAssembly module data, expose in\n  runtime with `WebAssembly.Module`-typed `default` export\n\n### `interface ModuleDefinition`\n\nRepresents a manually defined module.\n\n- `type: ModuleRuleType`\n\n  How this module's contents should be interpreted.\n\n- `path: string`\n\n  Path of this module. The module's \"name\" will be obtained by converting this\n  to a relative path. The original path will be used to read `contents` if it's\n  omitted.\n\n- `contents?: string | Uint8Array`\n\n  Contents override for this module. Binary data should be passed as\n  `Uint8Array`s. If omitted, will be read from `path`.\n\n### `interface ModuleRule`\n\nRepresents a rule for identifying the `ModuleRuleType` of automatically located\nmodules.\n\n- `type: ModuleRuleType`\n\n  How to interpret modules that match the `include` patterns.\n\n- `include: string[]`\n\n  Glob patterns to match located module paths against (e.g. `[\"**/*.txt\"]`).\n\n- `fallthrough?: boolean`\n\n  If `true`, ignore any further rules of this `type`. This is useful for\n  disabling the built-in `ESModule` and `CommonJS` rules that match `*.mjs` and\n  `*.js`/`*.cjs` files respectively.\n\n### `enum LogLevel`\n\n`NONE, ERROR, WARN, INFO, DEBUG, VERBOSE`\n\nControls which messages Miniflare logs. All messages at or below the selected\nlevel will be logged.\n\n### `interface LogOptions`\n\n- `prefix?: string`\n\n  String to add before the level prefix when logging messages. Defaults to `mf`.\n\n- `suffix?: string`\n\n  String to add after the level prefix when logging messages.\n\n### `class Log`\n\n- `constructor(level?: LogLevel, opts?: LogOptions)`\n\n  Creates a new logger that logs all messages at or below the specified level to\n  the `console`.\n\n- `error(message: Error)`\n\n  Logs a message at the `ERROR` level. If the constructed log `level` is less\n  than `ERROR`, `throw`s the `message` instead.\n\n- `warn(message: string)`\n\n  Logs a message at the `WARN` level.\n\n- `info(message: string)`\n\n  Logs a message at the `INFO` level.\n\n- `debug(message: string)`\n\n  Logs a message at the `DEBUG` level.\n\n- `verbose(message: string)`\n\n  Logs a message at the `VERBOSE` level.\n\n### `class NoOpLog extends Log`\n\n- `constructor()`\n\n  Creates a new logger that logs nothing to the `console`, and always `throw`s\n  `message`s logged at the `ERROR` level.\n\n### `interface QueueProducerOptions`\n\n- `queueName: string`\n\n  The name of the queue where messages will be sent by the producer.\n\n- `deliveryDelay?: number`\n\n  Default number of seconds to delay the delivery of messages to consumers.\n  Value between `0` (no delay) and `42300` (12 hours).\n\n### `interface QueueConsumerOptions`\n\n- `maxBatchSize?: number`\n\n  Maximum number of messages allowed in each batch. Defaults to `5`.\n\n- `maxBatchTimeout?: number`\n\n  Maximum number of seconds to wait for a full batch. If a message is sent, and\n  this timeout elapses, a partial batch will be dispatched. Defaults to `1`.\n\n- `maxRetries?: number`\n\n  Maximum number of times to retry dispatching a message, if handling it throws,\n  or it is explicitly retried. Defaults to `2`.\n\n- `deadLetterQueue?: string`\n\n  Name of another Queue to send a message on if it fails processing after\n  `maxRetries`. If this isn't specified, failed messages will be discarded.\n\n- `retryDelay?: number`\n\n  Number of seconds to delay the (re-)delivery of messages by default. Value\n  between `0` (no delay) and `42300` (12 hours).\n\n### `interface WorkerOptions`\n\nOptions for an individual Worker/\"nanoservice\". All bindings are accessible on\nthe global scope in service-worker format Workers, or via the 2nd `env`\nparameter in module format Workers.\n\n### `interface WorkflowOptions`\n\n- `name: string`\n\n  The name of the Workflow.\n\n- `className: string`\n\n  The name of the class exported from the Worker that implements the `WorkflowEntrypoint`.\n\n- `scriptName?`: string\n\n  The name of the script that includes the `WorkflowEntrypoint`. This is optional because it defaults to the current script if not set.\n\n#### Core\n\n- `name?: string`\n\n  Unique name for this worker. Only required if multiple `workers` are\n  specified.\n\n- `unsafeRegisterWorker?: boolean`\n\n  Whether to advertise this Worker in the dev registry configured by\n  `unsafeDevRegistryPath`. Defaults to `true`.\n\n- `rootPath?: string`\n\n  Path against which all other path options for this Worker are resolved\n  relative to. This path is itself resolved relative to the `rootPath` from\n  `SharedOptions` if multiple workers are specified. Defaults to the current\n  working directory.\n\n- `script?: string`\n\n  JavaScript code for this worker. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set. If it does have\n  imports, `scriptPath` must also be set so Miniflare knows where to resolve\n  them relative to.\n\n- `scriptPath?: string`\n\n  Path of JavaScript entrypoint. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set.\n\n- `modules?: boolean | ModuleDefinition[]`\n  - If `true`, Miniflare will treat `script`/`scriptPath` as an ES Module and\n    automatically locate transitive module dependencies according to\n    `modulesRules`. Note that automatic location is not perfect: if the\n    specifier to a dynamic `import()` or `require()` is not a string literal, an\n    exception will be thrown.\n\n  - If set to an array, modules can be defined manually. Transitive dependencies\n    must also be defined. Note the first module must be the entrypoint and have\n    type `\"ESModule\"`.\n\n- `modulesRoot?: string`\n\n  If `modules` is set to `true` or an array, modules' \"name\"s will be their\n  `path`s relative to this value. This ensures file paths in stack traces are\n  correct.\n\n<!-- prettier-ignore-start -->\n<!-- (for disabling `;` insertion in `js` code block) -->\n\n- `modulesRules?: ModuleRule[]`\n\n  Rules for identifying the `ModuleRuleType` of automatically located modules\n  when `modules: true` is set. Note the following default rules are always\n  included at the end:\n\n  ```js\n  [\n    { type: \"ESModule\", include: [\"**/*.mjs\"] },\n    { type: \"CommonJS\", include: [\"**/*.js\", \"**/*.cjs\"] },\n  ]\n  ```\n\n  > If `script` and `scriptPath` are set, and `modules` is set to an array,\n  > `modules` takes priority for a Worker's code, followed by `script`, then\n  > `scriptPath`.\n\n<!-- prettier-ignore-end -->\n\n- `compatibilityDate?: string`\n\n  [Compatibility date](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker. Defaults to a date far in the past.\n\n- `compatibilityFlags?: string[]`\n\n  [Compatibility flags](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker.\n\n- `bindings?: Record<string, Json>`\n\n  Record mapping binding name to arbitrary JSON-serialisable values to inject as\n  bindings into this Worker.\n\n- `wasmBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing binary WebAssembly module data\n  to inject as `WebAssembly.Module` bindings into this Worker.\n\n- `textBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing UTF8-encoded data to inject as\n  `string` bindings into this Worker.\n\n- `dataBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing arbitrary binary data to\n  inject as `ArrayBuffer` bindings into this Worker.\n\n- `serviceBindings?: Record<string, string | typeof kCurrentWorker | { name: string | typeof kCurrentWorker, entrypoint?: string } | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>>`\n\n  Record mapping binding name to service designators to inject as\n  `{ fetch: typeof fetch }`\n  [service bindings](https://developers.cloudflare.com/workers/platform/bindings/about-service-bindings/)\n  into this Worker.\n  - If the designator is a `string`, requests will be dispatched to the Worker\n    with that `name`.\n  - If the designator is `(await import(\"miniflare\")).kCurrentWorker`, requests\n    will be dispatched to the Worker defining the binding.\n  - If the designator is an object of the form `{ name: ..., entrypoint: ... }`,\n    requests will be dispatched to the entrypoint named `entrypoint` in the\n    Worker named `name`. The `entrypoint` defaults to `default`, meaning\n    `{ name: \"a\" }` is the same as `\"a\"`. If `name` is\n    `(await import(\"miniflare\")).kCurrentWorker`, requests will be dispatched to\n    the Worker defining the binding.\n  - If the designator is an object of the form `{ network: { ... } }`, where\n    `network` is a\n    [`workerd` `Network` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L555-L598),\n    requests will be dispatched according to the `fetch`ed URL.\n  - If the designator is an object of the form `{ external: { ... } }` where\n    `external` is a\n    [`workerd` `ExternalServer` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L504-L553),\n    requests will be dispatched to the specified remote server.\n  - If the designator is an object of the form `{ disk: { ... } }` where `disk`\n    is a\n    [`workerd` `DiskDirectory` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L600-L643),\n    requests will be dispatched to an HTTP service backed by an on-disk\n    directory.\n  - If the designator is an object of the form `{ node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> }`, requests will be dispatched to your custom Node handler. This allows you to access data and functions defined in Node.js from your Worker using Node.js `req` and `res` objects. Note, `miniflare` will be the `Miniflare` instance dispatching the request.\n  - If the designator is a function with the signature `(request: Request, miniflare: Miniflare) => Response`, requests will be dispatched to your custom\n    fetch handler. This allows you to access data and functions defined in Node.js\n    from your Worker using fetch `Request` and `Response` objects. Note, `miniflare` will be the `Miniflare` instance\n    dispatching the request.\n\n- `outboundService?: string | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>`\n\n  Dispatch this Worker's global `fetch()` and `connect()` requests to the\n  configured service. Service designators follow the same rules above for\n  `serviceBindings`.\n\n- `routes?: string[]`\n\n  Array of route patterns for this Worker. These follow the same\n  [routing rules](https://developers.cloudflare.com/workers/platform/triggers/routes/#matching-behavior)\n  as deployed Workers. If no routes match, Miniflare will fallback to the Worker\n  defined first.\n\n#### Cache\n\n- `cacheAPI?: boolean`\n\n  If `false`, default and named caches will be disabled. The Cache API will\n  still be available, it just won't cache anything.\n\n#### Durable Objects\n\n- `durableObjects?: Record<string, string | { className: string, scriptName?: string, useSQLite?: boolean }>`\n\n  Record mapping binding name to Durable Object class designators to inject as\n  `DurableObjectNamespace` bindings into this Worker.\n  - If the designator is a `string`, it should be the name of a `class` exported\n    by this Worker.\n  - If the designator is an object, and `scriptName` is `undefined`, `className`\n    should be the name of a `class` exported by this Worker.\n  - Otherwise, `className` should be the name of a `class` exported by the\n    Worker with a `name` of `scriptName`.\n  - To use the Durable Object SQLite API you must pass `useSQLite: true`.\n\n#### KV\n\n- `kvNamespaces?: Record<string, string> | string[]`\n\n  Record mapping binding name to KV namespace IDs to inject as `KVNamespace`\n  bindings into this Worker. Different Workers may bind to the same namespace ID\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and KV namespace ID are assumed to be the same.\n\n- `sitePath?: string`\n\n  Path to serve Workers Sites files from. If set, `__STATIC_CONTENT` and\n  `__STATIC_CONTENT_MANIFEST` bindings will be injected into this Worker. In\n  modules mode, `__STATIC_CONTENT_MANIFEST` will also be exposed as a module\n  with a `string`-typed `default` export, containing the JSON-stringified\n  manifest. Note Workers Sites files are never cached in Miniflare.\n\n- `siteInclude?: string[]`\n\n  If set, only files with paths matching these glob patterns will be served.\n\n- `siteExclude?: string[]`\n\n  If set, only files with paths _not_ matching these glob patterns will be\n  served.\n  - `assetsPath?: string`\n\n  Path to serve Workers assets from.\n  - `assetsKVBindingName?: string`\n    Name of the binding to the KV namespace that the assets are in. If `assetsPath` is set, this binding will be injected into this Worker.\n\n  - `assetsManifestBindingName?: string`\n    Name of the binding to an `ArrayBuffer` containing the binary-encoded assets manifest. If `assetsPath` is set, this binding will be injected into this Worker.\n\n#### R2\n\n- `r2Buckets?: Record<string, string> | string[]`\n\n  Record mapping binding name to R2 bucket names to inject as `R2Bucket`\n  bindings into this Worker. Different Workers may bind to the same bucket name\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and bucket name are assumed to be the same.\n\n#### D1\n\n- `d1Databases?: Record<string, string> | string[]`\n\n  Record mapping binding name to D1 database IDs to inject as `D1Database`\n  bindings into this Worker. Note binding names starting with `__D1_BETA__` are\n  injected as `Fetcher` bindings instead, and must be wrapped with a facade to\n  provide the expected `D1Database` API. Different Workers may bind to the same\n  database ID with different binding names. If a `string[]` of binding names is\n  specified, the binding name and database ID are assumed to be the same.\n\n#### Queues\n\n- `queueProducers?: Record<string, QueueProducerOptions> | string[]`\n\n  Record mapping binding name to queue options to inject as `WorkerQueue` bindings\n  into this Worker. Different Workers may bind to the same queue name with\n  different binding names. If a `string[]` of binding names is specified, the\n  binding name and queue name (part of the queue options) are assumed to be the same.\n\n- `queueConsumers?: Record<string, QueueConsumerOptions> | string[]`\n\n  Record mapping queue name to consumer options. Messages enqueued on the\n  corresponding queues will be dispatched to this Worker. Note each queue can\n  have at most one consumer. If a `string[]` of queue names is specified,\n  default consumer options will be used.\n\n#### Assets\n\n- `directory?: string`\n  Path to serve Workers static asset files from.\n\n- `binding?: string`\n  Binding name to inject as a `Fetcher` binding to allow access to static assets from within the Worker.\n\n- `assetConfig?: { html_handling?: HTMLHandlingOptions, not_found_handling?: NotFoundHandlingOptions, base_path?: string }`\n  Configuration for file-based asset routing - see [docs](https://developers.cloudflare.com/workers/static-assets/routing/#routing-configuration) for options\n\n#### Pipelines\n\n- `pipelines?: Record<string, PipelineOptions> | string[]`\n\n  Record mapping binding name to a Pipeline. Different workers may bind to the same Pipeline with different bindings\n  names. If a `string[]` of pipeline names, the binding and Pipeline name are assumed to be the same.\n\n#### Workflows\n\n- `workflows?: WorkflowOptions[]`\n  Configuration for one or more Workflows in your project.\n\n#### Browser Run\n\n- `browserRendering: BrowserRenderingOptions`\n\n#### Analytics Engine, Sending Email, Vectorize and Workers for Platforms\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n#### Workers AI\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n### `interface SharedOptions`\n\nOptions shared between all Workers/\"nanoservices\".\n\n#### Core\n\n- `rootPath?: string`\n\n  Path against which all other path options for this instance are resolved\n  relative to. Defaults to the current working directory.\n\n- `host?: string`\n\n  Hostname that the `workerd` server should listen on. Defaults to `127.0.0.1`.\n\n- `port?: number`\n\n  Port that the `workerd` server should listen on. Tries to default to `8787`,\n  but falls back to a random free port if this is in use. Note if a manually\n  specified port is in use, Miniflare throws an error, rather than attempting to\n  find a free port.\n\n- `https?: boolean`\n\n  If `true`, start an HTTPS server using a pre-generated self-signed certificate\n  for `localhost`. Note this certificate is not valid for any other hostnames or\n  IP addresses. If you need to access the HTTPS server from another device,\n  you'll need to generate your own certificate and use the other `https*`\n  options below.\n\n  ```shell\n  $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem\n  ```\n\n  ```js\n  import fs from \"node:fs\";\n\n  new Miniflare({\n  \thttpsKey: fs.readFileSync(\"key.pem\", \"utf8\"),\n  \thttpsCert: fs.readFileSync(\"cert.pem\", \"utf8\"),\n  });\n  ```\n\n- `httpsKey?: string`\n\n  When `httpsCert` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded private key.\n\n- `httpsCert?: string`\n\n  When `httpsKey` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded certificate chain.\n\n- `inspectorPort?: number`\n\n  Port that `workerd` should start a DevTools inspector server on. Visit\n  `chrome://inspect` in a Chromium-based browser to connect to this. This can be\n  used to see detailed `console.log`s, profile CPU usage, and will eventually\n  allow step-through debugging.\n\n- `verbose?: boolean`\n\n  Enable `workerd`'s `--verbose` flag for verbose logging. This can be used to\n  see simplified `console.log`s.\n\n- `log?: Log`\n\n  Logger implementation for Miniflare's errors, warnings and informative\n  messages.\n\n- `upstream?: string`\n\n  URL to use as the origin for incoming requests. If specified, all incoming\n  `request.url`s will be rewritten to start with this string. This is especially\n  useful when testing Workers that act as a proxy, and not as origins\n  themselves.\n\n  When `upstream` is set, the `Host` header is rewritten to match the upstream\n  server. To preserve the original hostname, Miniflare adds an\n  `MF-Original-Hostname` header containing the original `Host` value:\n\n  ```js\n  export default {\n  \tasync fetch(request) {\n  \t\t// When upstream is set, Host header contains the upstream hostname\n  \t\tconst upstreamHost = request.headers.get(\"Host\");\n  \t\t// Original hostname is preserved in MF-Original-Hostname\n  \t\tconst originalHost = request.headers.get(\"MF-Original-Hostname\");\n  \t\treturn new Response(\n  \t\t\t`Original: ${originalHost}, Upstream: ${upstreamHost}`\n  \t\t);\n  \t},\n  };\n  ```\n\n- `cf?: boolean | string | Record<string, any>`\n\n  Controls the object returned from incoming `Request`'s `cf` property.\n  - If set to a falsy value, an object with default placeholder values will be\n    used\n  - If set to an object, that object will be used\n  - If set to `true`, a real `cf` object will be fetched from a trusted\n    Cloudflare endpoint and cached in `node_modules/.mf` for 30 days\n  - If set to a `string`, a real `cf` object will be fetched and cached at the\n    provided path for 30 days\n\n- `unsafeDevRegistryPath?: string`\n\n  Path to the dev registry directory. This allows Miniflare to automatically\n  discover external services and Durable Objects running on another Miniflare\n  instance and connect them. Workers are advertised by default; set\n  `unsafeRegisterWorker` to `false` to opt out.\n\n- `unsafeDevRegistryDurableObjectProxy?: boolean`\n\n  If `true`, Miniflare will automatically proxy requests to Durable Objects\n  bound to external services and register all Workers' Durable Objects in the dev registry.\n\n- `unsafeHandleDevRegistryUpdate?: (registry: WorkerRegistry) => void`\n\n  Callback invoked when the dev registry is updated with changes to bound services.\n  Receives a copy of the updated registry object. Useful for reacting to external\n  service changes during development.\n\n- `unsafeRuntimeEnv?: Record<string, string>`\n\n  Extra environment variables to set on the spawned `workerd` subprocess.\n  Merged on top of `process.env` and Miniflare's own defaults — most notably\n  `TZ=UTC`, which Miniflare sets to match the production Cloudflare runtime so\n  that `Date` and `Intl` APIs inside the Worker observe UTC during local\n  development. Use this option to override those defaults, for example to test\n  timezone-dependent code with `unsafeRuntimeEnv: { TZ: \"Europe/London\" }`.\n\n- `containerEngine?: string | { localDocker: { socketPath: string, containerEgressInterceptorImage?: string } }`\n\n  Configuration used to connect to the container engine for any Workers that\n  define containers. If a `string` is provided, it is used as the local Docker\n  socket path (e.g. `\"unix:///var/run/docker.sock\"`).\n\n#### Persistence\n\n- `resourcePersistencePath?: string`\n\n  Path to the root directory under which all resource data (Cache, Durable\n  Objects, KV, R2, D1, Workflows, etc.) is persisted. Each resource persists to\n  a subdirectory named after its plugin (e.g. `<resourcePersistencePath>/kv`).\n  When unset, persistence is disabled and data is stored in an ephemeral\n  temporary directory that is cleared on `dispose()`.\n\n- `resourceTmpPath?: string`\n\n  Path to the temporary directory used by plugins that need one (e.g. email\n  logs). Falls back to a subdirectory of Miniflare's own temporary directory if\n  not set.\n\n#### Analytics Engine, Sending Email, Vectorize, Workers AI and Workers for Platforms\n\n_Not yet supported_\n\n### `type MiniflareOptions`\n\n`SharedOptions & (WorkerOptions | { workers: WorkerOptions[] })`\n\nMiniflare accepts either a single Worker configuration or multiple Worker\nconfigurations in the `workers` array. When specifying an array of Workers, the\nfirst Worker is designated the entrypoint and will receive all incoming HTTP\nrequests. Some options are shared between all workers and should always be\ndefined at the top-level.\n\n### `class Miniflare`\n\n- `constructor(opts: MiniflareOptions)`\n\n  Creates a Miniflare instance and starts a new `workerd` HTTP server\n  listening on the configured `host` and `port`.\n\n- `setOptions(opts: MiniflareOptions)`\n\n  Updates the configuration for this Miniflare instance and restarts the\n  `workerd` server. Note unlike Miniflare 2, this does _not_ merge the new\n  configuration with the old configuration. Note that calling this function will\n  invalidate any existing values returned by the `Miniflare#get*()` methods,\n  preventing them from being used.\n\n- `ready: Promise<URL>`\n\n  Returns a `Promise` that resolves with a `http` `URL` to the `workerd` server\n  once it has started and is able to accept requests.\n\n- `dispatchFetch(input: RequestInfo, init?: RequestInit): Promise<Response>`\n\n  Sends a HTTP request to the `workerd` server, dispatching a `fetch` event in\n  the entrypoint Worker. Returns a `Promise` that resolves with the response.\n  Note that this implicitly waits for the `ready` `Promise` to resolve, there's\n  no need to do that yourself first. Additionally, the host of the request's URL\n  is always ignored and replaced with the `workerd` server's.\n\n- `dispatchConnect(options?: { protocol?: \"tcp\"; workerName?: string; port?: number }): Promise<net.Socket>`\n- `dispatchConnect(options: { protocol: \"udp\"; workerName?: string; port?: number }): Promise<dgram.Socket>`\n\n  Opens a connection to a Worker's `connect()` trigger and returns a Node.js\n  `net.Socket` for TCP or `dgram.Socket` for UDP. TCP is used when `protocol` is\n  omitted. This implicitly waits for the runtime to start and connects to the\n  trigger's allocated port when its configured port is `0`. If `workerName` is\n  omitted, the entrypoint Worker is selected. If `port` is omitted, the selected\n  Worker must have exactly one trigger for the selected protocol. Calling\n  `dispose()` closes any sockets opened by this method.\n\n- `getBindings<Env extends Record<string, unknown> = Record<string, unknown>>(workerName?: string): Promise<Env>`\n\n  Returns a `Promise` that resolves with a record mapping binding names to\n  bindings, for all bindings in the Worker with the specified `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getWorker(workerName?: string): Promise<Fetcher>`\n\n  Returns a `Promise` that resolves with a\n  [`Fetcher`](https://workers-types.pages.dev/experimental/#Fetcher) pointing to\n  the specified `workerName`. If `workerName` is not specified, defaults to the\n  entrypoint Worker. Note this `Fetcher` uses the experimental\n  [`service_binding_extra_handlers`](https://github.com/cloudflare/workerd/blob/1d9158af7ca1389474982c76ace9e248320bec77/src/workerd/io/compatibility-date.capnp#L290-L297)\n  compatibility flag to expose\n  [`scheduled()`](https://workers-types.pages.dev/experimental/#Fetcher.scheduled)\n  and [`queue()`](https://workers-types.pages.dev/experimental/#Fetcher.queue)\n  methods for dispatching `scheduled` and `queue` events.\n\n- `getCaches(): Promise<CacheStorage>`\n\n  Returns a `Promise` that resolves with the\n  [`CacheStorage`](https://developers.cloudflare.com/workers/runtime-apis/cache/)\n  instance of the entrypoint Worker. This means if `cacheAPI: false` is set on\n  the entrypoint, calling methods on the resolved value won't do anything.\n\n- `getD1Database(bindingName: string, workerName?: string): Promise<D1Database>`\n\n  Returns a `Promise` that resolves with the\n  [`D1Database`](https://developers.cloudflare.com/d1/platform/client-api/)\n  instance corresponding to the specified `bindingName` of `workerName`. Note\n  `bindingName` must not begin with `__D1_BETA__`. If `workerName` is not\n  specified, defaults to the entrypoint Worker.\n\n- `getDurableObjectNamespace(bindingName: string, workerName?: string): Promise<DurableObjectNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`DurableObjectNamespace`](https://developers.cloudflare.com/workers/runtime-apis/durable-objects/#access-a-durable-object-from-a-worker)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getKVNamespace(bindingName: string, workerName?: string): Promise<KVNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`KVNamespace`](https://developers.cloudflare.com/workers/runtime-apis/kv/)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getQueueProducer<Body>(bindingName: string, workerName?: string): Promise<Queue<Body>>`\n\n  Returns a `Promise` that resolves with the\n  [`Queue`](https://developers.cloudflare.com/queues/platform/javascript-apis/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `getR2Bucket(bindingName: string, workerName?: string): Promise<R2Bucket>`\n\n  Returns a `Promise` that resolves with the\n  [`R2Bucket`](https://developers.cloudflare.com/r2/api/workers/workers-api-reference/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `dispose(): Promise<void>`\n\n  Cleans up the Miniflare instance, and shuts down the `workerd` server. Note\n  that after this is called, `Miniflare#setOptions()` and\n  `Miniflare#dispatchFetch()` cannot be called. Additionally, calling this\n  function will invalidate any values returned by the `Miniflare#get*()`\n  methods, preventing them from being used.\n\n- `getCf(): Promise<Record<string, any>>`\n\n  Returns the same object returned from incoming `Request`'s `cf` property. This\n  object depends on the `cf` property from `SharedOptions`.\n\n## Configuration\n\n### Local `workerd`\n\nYou can override the `workerd` binary being used by miniflare with a your own local build by setting the `MINIFLARE_WORKERD_PATH` environment variable.\n\nFor example:\n\n```shell\n$ export MINIFLARE_WORKERD_PATH=\"<WORKERD_REPO_DIR>/bazel-bin/src/workerd/server/workerd\"\n```\n\nFor debugging purposes, you can also set `MINIFLARE_WORKERD_CONFIG_DEBUG=<file_path>` which will dump the workerd config to the specified file path.\n","packages/miniflare/src/plugins/core/proxy/README.md":"# Miniflare API Proxy\n\nMiniflare provides methods for accessing bindings from Node.js, outside a\n`workerd` process. These are implemented by an API proxy that proxies accesses\nand calls to properties and methods over HTTP calls. The directory implements\nthe client for this. The server is implemented as a Durable Object in\n[`src/workers/core/proxy.worker.ts`](../../../workers/core/proxy.worker.ts).\n\nUsing a Durable Object allows us to share references containing I/O objects like\nstreams across requests. The Durable Object contains a \"heap\", mapping addresses\nto references. The \"heap\" is initialised with `globalThis` and `env`.\n\nThe proxy client builds proxies for each object on the heap. Accessing a\nproperty on a proxy will result in a synchronous `GET` operation to the proxy\nserver. If the property is not a method, the value will be serialised back to\nthe client. Note this may involve putting more references on the \"heap\".\n\nIf the property is a method, the client will return a function from the access.\nFuture accesses to the same property key will return the same function without\nthe synchronous `GET` operation. Calling this function will serialise all the\narguments, then perform a synchronous `CALL` operation on the target, and the\nreturn value will be serialised back to the client. If this function returns a\n`Promise`, it will be stored on the \"heap\", and a reference returned. An\nasynchronous `GET` operation will then be performed to resolve the `Promise`,\nand serialise the result. If a function returns a `Promise` once, all future\ncalls will send asynchronous `CALL` operations instead, that resolve the\n`Promise` without an additional round trip.\n\nIf the function call had `ReadableStream` arguments, the first will be sent\nunbuffered after the rest of the arguments. All function calls with\n`ReadableStream` or `Blob` arguments are assumed to be asynchronous. This\nassumption is required as synchronous operations block the main thread and\nprevent chunks from `ReadableStream`s being read.\n\nIf the function call threw, or returned a `Promise` that rejected, the error\nwill be serialised and re-thrown/rejected in the client. Note that the stack\ntrace will be updated to reflect the calling location in the client, not the\nserver.\n\nTo prevent unbounded growth of the \"heap\", all proxies are registered with a\n`FinalizationRegistry`. When the proxy is garbage collected, a `FREE` operation\nwill remove the corresponding \"heap\" entry allowing it to be garbage collected\non the server too.\n\nWhen `workerd` is restarted with `Miniflare#setOptions()` or stopped with\n`Miniflare#dispose()`, all proxies are _poisoned_. Once a proxy is poisoned, it\ncannot be used, and must be recreated. Poisoned proxies are unregistered from\nthe `FinalizationRegistry` too, as the addresses they point too will be invalid\nand shouldn't be freed again.\n","packages/miniflare/src/workers/README.md":"# Miniflare Workers\n\nThis directory contains code for Workers used internally by Miniflare. Files\nending in `*.worker.ts` will be type-checked under\n`@cloudflare/workers-types/experimental`, instead of `@types/node`.\n\nIt also contains dependencies (i.e. header/binding names, other constants and\ntypes) shared between Workers and the Node.js components of Miniflare. These\nmust type check under both typing environments.\n","packages/miniflare/src/workers/cache/README.md":"# The Cache API\n\nThe Cache API within `workerd` is _extremely_ lenient with errors, and will work\nwith a service that doesn't fully support the expected API. This is what it\n_should_ behave like:\n\n## .add()\n\nUnimplemented in the runtime\n\n## .addAll()\n\nUnimplemented in the runtime\n\n## .match()\n\n`workerd` guarantees:\n\n- The method will always be `GET`\n- The request headers will include `Cache-Control: only-if-cached` (which\n  Miniflare ignores)\n- The request headers will include `Cf-Cache-Namespaces` if this is a namespaced\n  cache (i.e. `caches.open(...)`) `workerd` expects:\n- The `Cf-Cache-Status` header to be present with the value:\n  - `MISS` if it's a cache miss, in which case the rest of the response is\n    ignored by `workerd`\n  - `HIT` if it's a cache hit, in which case `workerd` sends the response on to\n    the user, including the full headers and full body\n\n## .put()\n\n`workerd` guarantees:\n\n- The method will always be `PUT`, and the cache key method will always be `GET`\n- The headers will be the headers of the cache key, and the URL will be the URL\n  of the cache key\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The body contains the serialised response for storage\n  - The serialised response will never: - Have a `206` status code - Have a\n    `Vary: *` header - Have a `304` status code `workerd` expects:\n- A `204` (success) or `413` (failure) response code. It doesn't do anything\n  with either\n\n## .delete()\n\n`workerd` guarantees:\n\n- The method will always be `PURGE`, and the cache key method will always be\n  `GET`\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The header `X-Real-IP` will be set to `127.0.0.1`\n- The remaining headers will be the cache key headers `workerd` expects:\n- Status `200` on success\n- Status `404` on failure\n- Status `429` on rate limit (which will throw in the user worker)\n","packages/mock-npm-registry/README.md":"# mock-npm-registry\n\nThis internal package can be used in tests by othe packages to set up a mock local npm registry, publish locally built copies of the packages and their dependencies, then install those packages into test fixtures.\n\n## Usage\n\nA good example is the vitest-plugin e2e tests. See packages/vitest-plugin/test/global-setup.ts\n\n```ts\nexport default async function ({ provide }: GlobalSetupContext) {\n\tconst stop = await startMockNpmRegistry(\"@cloudflare/vitest-plugin\");\n\n\t// Create temporary directory\n\tconst projectPath = await createTestProject();\n\texecSync(\"pnpm install\", { cwd: projectPath, stdio: \"ignore\" });\n\n\tprovide(\"tmpPoolInstallationPath\", projectPath);\n```\n\nHere you can see that in Vitest global setup file, we are calling `startMockNpmRegistry()`.\nWe pass in the `@cloudflare/vitest-plugin` package name, which will ensure that this package\n(and all its local dependencies, such as Wrangler, Miniflare, etc) is built and published to the mock registry.\n\nWe then create a temporary test project that has a dependency on `@cloudflare/vitest-plugin`\nand then run `pnpm install`, which will install the locally published packages.\n\nThe path to this temporary test project is provided to tests.\n\n## Debugging\n\nIf you are having problems with the mock npm registry, you can get additional debug logging by setting the `NODE_DEBUG` environment variable.\n\n```env\nNODE_DEBUG=mock-npm-registry\n```\n","packages/pages-functions/README.md":"# `@cloudflare/pages-functions`\n\n`@cloudflare/pages-functions` compiles a [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/functions/) `functions/` directory into a single [Cloudflare Worker](https://developers.cloudflare.com/workers/) bundle. It provides both a command-line interface and a programmatic API for build tools.\n\nThe package discovers file-based routes, bundles their handlers into an ES module Worker, collects imported Wasm, text, and binary modules, and returns Pages routing metadata through its programmatic API.\n\n> [!WARNING]\n> Pages Functions are not recommended for new development. Build new applications and new server-side functionality with Workers instead. This package is intended to support existing Pages Functions projects and help migrate them incrementally to Workers.\n\n## Installation\n\nInstall the package as a development dependency:\n\n```sh\nnpm install --save-dev @cloudflare/pages-functions\n```\n\n## CLI\n\nCompile the default `functions/` directory into `dist/`:\n\n```sh\nnpx @cloudflare/pages-functions build\n```\n\nTo specify the input and output directories:\n\n```sh\nnpx @cloudflare/pages-functions build ./functions --outdir ./dist/worker\n```\n\nThe command writes the following files:\n\n- `index.js`: the compiled ES module Worker\n- `index.js.map`: the source map, when `--sourcemap` is used\n- Imported Wasm, text, binary, and `assets:` modules required by the Worker\n\nThe generated Worker contains its own router and does not require a `_routes.json` file. To produce one (for example when deploying to Pages), pass `--routes-output <path>`. Pages deployment tools such as Wrangler generate this file on their own and do not need it from the CLI.\n\nThe command only builds the Worker. It does not deploy it or create deployment configuration. By default, the generated Worker falls back to `env.ASSETS.fetch()` when no Function route handles a request, so the deployment must provide an `ASSETS` binding or select another binding with `--fallback-service`.\n\nRuntime-native imports such as `node:*` and `cloudflare:*` are not automatically excluded from the bundle. Pass them through with repeatable `--external` options when the surrounding Worker build or runtime provides them:\n\n```sh\nnpx @cloudflare/pages-functions build --external \"node:*\" --external \"cloudflare:*\"\n```\n\n### CLI options\n\n| Option                      | Description                                            | Default     |\n| --------------------------- | ------------------------------------------------------ | ----------- |\n| `[directory]`               | Pages Functions directory                              | `functions` |\n| `--outdir <path>`           | Output directory                                       | `dist`      |\n| `--minify`                  | Minify the Worker bundle                               | Disabled    |\n| `--sourcemap`               | Generate an external source map                        | Disabled    |\n| `--fallback-service <name>` | Fetcher binding used when no route handles the request | `ASSETS`    |\n| `--external <module>`       | Exclude a module from the bundle; may be repeated      | None        |\n| `--routes-output <path>`    | Write the generated `_routes.json` spec to this path   | Not written |\n| `-h`, `--help`              | Display usage information                              |             |\n| `-v`, `--version`           | Display the package version                            |             |\n\n## Programmatic API\n\nUse `buildPagesFunctions()` when integrating the compiler into another build tool:\n\n```ts\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nconst result = await buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/worker\",\n\tsourcemap: true,\n});\n\nconsole.log(result.entryPointPath);\nconsole.log(result.routesJSON);\n```\n\n`buildPagesFunctions()` returns the generated routing specification as `routesJSON` but does not write a `_routes.json` file. Consumers such as Wrangler can use this metadata when deploying to Pages.\n\n### Build options\n\n| Option                  | Type       | Description                                               | Default           |\n| ----------------------- | ---------- | --------------------------------------------------------- | ----------------- |\n| `functionsDirectory`    | `string`   | Pages Functions directory to compile                      | Required          |\n| `outputDirectory`       | `string`   | Directory for `index.js` and collected modules            | Required          |\n| `assetsOutputDirectory` | `string`   | Directory for files referenced by `assets:` imports       | `outputDirectory` |\n| `fallbackService`       | `string`   | Fetcher binding used when no route handles the request    | `ASSETS`          |\n| `minify`                | `boolean`  | Minify the Worker bundle                                  | `false`           |\n| `sourcemap`             | `boolean`  | Generate an external source map                           | `false`           |\n| `external`              | `string[]` | Module specifiers to exclude from the bundle              | `undefined`       |\n| `routesDescription`     | `string`   | Description included in the returned routes specification | `undefined`       |\n| `metafile`              | `boolean`  | Include the esbuild metafile in the result                | `false`           |\n\n### Build result\n\n`buildPagesFunctions()` returns:\n\n| Property                | Description                                           |\n| ----------------------- | ----------------------------------------------------- |\n| `entryPointPath`        | Absolute path to the generated `index.js`             |\n| `bundleType`            | Always `\"esm\"`                                        |\n| `modules`               | Collected Wasm, text, and binary modules              |\n| `dependencies`          | Inputs included in the generated bundle               |\n| `sourceMapPath`         | Absolute source map path when source maps are enabled |\n| `routesJSON`            | Generated `_routes.json` data                         |\n| `filepathRoutingConfig` | Discovered Pages Functions routes and base URL        |\n| `metafile`              | esbuild metafile when requested                       |\n\nThe package also exports lower-level route discovery, generation, optimization, and validation helpers for tooling authors. Their TypeScript declarations are included with the package.\n\n## Migrate to Workers\n\n[Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/) supports deploying front-end assets and Worker code together. Workers also provides access to more Cloudflare platform features than Pages Functions. New routes and application logic should therefore be written in a Worker rather than added to an existing `functions/` directory.\n\nFor an existing Pages Functions project, you can compile the old Functions during the Worker build and delegate requests to them from your Worker. This lets you migrate one route at a time.\n\nFor example, configure Wrangler to compile the legacy `functions/` directory before it bundles the Worker:\n\n```jsonc\n{\n\t\"$schema\": \"./node_modules/wrangler/config-schema.json\",\n\t\"name\": \"my-worker\",\n\t\"main\": \"./src/index.js\",\n\t// Preserve the compatibility date and flags from your Pages project.\n\t\"compatibility_date\": \"<YOUR_EXISTING_COMPATIBILITY_DATE>\",\n\t\"assets\": {\n\t\t\"directory\": \"./dist/client\",\n\t\t\"binding\": \"ASSETS\",\n\t\t\"run_worker_first\": true,\n\t},\n\t\"build\": {\n\t\t\"command\": \"npx @cloudflare/pages-functions build ./functions --outdir ./dist/pages-functions --external \\\"node:*\\\" --external \\\"cloudflare:*\\\"\",\n\t\t\"watch_dir\": [\"./functions\", \"./src\"],\n\t},\n}\n```\n\nAdjust `assets.directory` and combine the build command with your existing front-end build command as needed. Preserve any compatibility flags used by the Pages project. The `--external` options leave runtime-native imports for Wrangler to process. The `ASSETS` binding is required by the compiler's default fallback behavior. `run_worker_first` ensures the Worker can run Pages Functions routes and middleware before falling back to static assets.\n\nImport the compiled handler from your Worker, handle new or migrated routes first, and use the old Pages Functions handler as a fallback:\n\n```js\nimport legacyPagesFunctions from \"../dist/pages-functions/index.js\";\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tconst url = new URL(request.url);\n\n\t\tif (url.pathname === \"/api/new-route\") {\n\t\t\treturn new Response(\"Handled by the Worker\");\n\t\t}\n\n\t\treturn legacyPagesFunctions.fetch(request, env, ctx);\n\t},\n};\n```\n\nThis ordering means Pages Functions middleware does not run for routes handled directly by the Worker. Migrate authentication, authorization, logging, and other applicable middleware to the Worker before moving routes that depend on it.\n\nAs routes are migrated, remove their files from `functions/` and implement them directly in the Worker. Once no legacy Pages Functions remain, remove the compiler build step and import.\n\nIf the legacy Functions use `assets:` imports, the imported assets must be written into the directory configured by `assets.directory`. The CLI writes them beneath its output directory, so use the programmatic API to select separate Worker and asset outputs:\n\n```js\n// scripts/build-pages-functions.mjs\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nawait buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/pages-functions\",\n\tassetsOutputDirectory: \"./dist/client\",\n\texternal: [\"node:*\", \"cloudflare:*\"],\n});\n```\n\nThen set `build.command` to `node ./scripts/build-pages-functions.mjs`. The `assets:` integration always uses the `ASSETS` binding, even when a different general fallback service is configured.\n\nWorkers do not use Pages `_routes.json` metadata. Configure [Workers Static Assets routing](https://developers.cloudflare.com/workers/static-assets/routing/) explicitly, especially if the Pages project used custom `_routes.json` rules or middleware. See the complete [Pages-to-Workers migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) for bindings, assets, compatibility settings, and deployment changes.\n\n## Contributing\n\nSee the Workers SDK [contributing guide](../../CONTRIBUTING.md) for repository setup and contribution requirements.\n\nFrom the repository root, install dependencies and run package tasks with:\n\n```sh\npnpm install\npnpm run build --filter @cloudflare/pages-functions\npnpm run check:type --filter @cloudflare/pages-functions\npnpm run test:ci --filter @cloudflare/pages-functions\npnpm run dev --filter @cloudflare/pages-functions\n```\n\nThe `dev` task watches this package's implementation; it does not watch an end-user Pages Functions project.\n\nBefore submitting changes, run:\n\n```sh\npnpm prettify\npnpm check\n```\n\n## License\n\nLicensed under either the [Apache 2.0 license](../../LICENSE-APACHE) or the [MIT license](../../LICENSE-MIT) at your option.\n","packages/pages-shared/README.md":"# `@cloudflare/pages-shared`\n\nThis is a package that is used internally to power Wrangler and Cloudflare Pages. It contains all the code that is shared between these clients (and possibly any other in the future e.g. the dashboard).\n\nCode should be written so that it can be run in almost any environment (e.g. Deno, Node, browser, Workers), but note that there's currently a bit of weirdness here for `asset-server`, hence the `environment-polyfills` piece.\n\n> [!NOTE]\n> Since code in this package is used by the Pages infrastructure, it is important that PRs are given careful review with regards to how they could cause a failure in production.\n> Ideally, there should be comprehensive tests for changes being made to give extra confidence about the behavior.\n","packages/quick-edit-extension/README.md":"# Quick Edit VS Code Extension\n\nThe code in this package is used by the `quick-edit` package, which in turn is used in the `workers-playground` package.\nTo debug this package locally check out the [Quick Edit package README](../quick-edit/README.md).\n","packages/quick-edit/README.md":"# VSCode for Web\n\nThis package contains Cloudflare's fork of VSCode for Web, to support web editing of Workers. This package contains code and setup for building VSCode for Web.\n\nThe code in this package is used by the `workers-playground` package.\n\n## Developing\n\nNote: Currently it's not possible to run VSCode's dev server to develop patches. This is because of a limitation with the `wrangler dev` file server for Workers Assets and the number of assets that would be watched locally.\n\n## Building\n\n- Use Node.js 22\n  - VSCode's build process requires this\n- Run `pnpm install`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run setup`\n  - installs dependencies\n  - clones VSCode (currently v1.102.1)\n  - applies the patches specified in `./patches`\n  - symlinks the top level packages within `workers-sdk`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run custom:build`\n  - This takes up to 15 mins to run\n  - It's not `build` because it would then run when people run the top level `pnpm run build` to build other packages in the repository.\n\n## Debugging\n\n- Change the `quickEditHost` constant in [workers-playground/src/QuickEditor/VSCodeEditor.tsx](../workers-playground/src/QuickEditor/VSCodeEditor.tsx) to http://localhost:8787\n- Run the following in parallel:\n  - `pnpm -F workers-playground dev` -> `http://localhost:5173`\n  - `pnpm -F \"@cloudflare/quick-edit\" exec wrangler dev` -> `http://localhost:8787`\n- Get a user token to connect to a preview Worker\n  - Navigate to https://playground-testing.devprod.cloudflare.dev/\n  - This will respond with a `error code: 522` response, which is expected\n  - Grab the `user` cookie from the 522 response\n- Open http://localhost:5173/playground\n  - Open the devtools and add the `user` cookie from the previous step to this site\n  - Refresh the page and play around with the editor\n\n## Deployment\n\nDeployments are managed by GitHub Actions:\n\n- deploy-pages-previews.yml:\n  - Runs on any PR that has the `preview:quick-edit` label.\n  - Deploys a preview, which can then be accessed via [https://<SHA>.quick-edit-cny.pages.dev/].\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production, which can then be accessed via [https://quick-edit-cny.pages.dev/].\n\n## Patching VSCode\n\nIf you need to add additional patches to VSCode, ensure you've run `pnpm run setup`. Then:\n\n1. Make your changes in the checked out VSCode in `vendor/vscode`.\n2. Commit your changes with `git commit -m \"YOUR MESSAGE\" --no-verify` (run this in the `vendor/vscode` directory).\n3. Prepare a new series of patches for VSCode with (again, run in the `vendor/vscode` directory) `git format-patch -o ../../packages/quick-edit/patches base`.\n\n## Modifying VSCode settings\n\nIf you need to change VSCode's configuration, open the `packages/quick-edit/src/index.ts` file.\n\nThe `WORKBENCH_WEB_CONFIGURATION` object contains VSCode's setup config, but the property `configurationDefaults` is most relevant, since it lets you set defaults for any VSCode settings. The format is exactly the same as VSCode's `settings.json` file.\n\n## Embedding VSCode\n\n> [!WARNING]\n> Cloudflare does not officially support embedding this version of VSCode in third-party contexts—use at your own risk! This documentation is aimed at people inside Cloudflare embedding this package.\n\nThe primary purpose of the patches we apply to VSCode is to allow the visible filesystem within VSCode to be controllable from the outside (by a web page that embeds the editor). You can refer to `packages/workers-playground/src/QuickEditor/VSCodeEditor.tsx` as a reference implementation.\n\nTo communicate with VSCode, a web page needs to load the deployed editor in an iframe:\n\n```html\n<iframe\n\tsrc=\"https://quick-edit.devprod.cloudflare.dev?worker=$worker&theme=dark\"\n></iframe>\n```\n\nThe `$worker` query parameter should be set to the path of the to-be-edited Worker on the virtual filesystem. The protocol used for the virtual filesystem is `cfs`, so it should look like `cfs:/my-worker-name`.\n\nTo load files into the VSCode filesystem and react to changes from within VSCode, you need to send over a `MessagePort`:\n\n```ts\nimport { Channel } from \"@cloudflare/workers-editor-shared\";\nimport type {\n\tFromQuickEditMessage,\n\tToQuickEditMessage,\n\tWorkerLoadedMessage,\n\tWrappedChannel,\n} from \"@cloudflare/workers-editor-shared\";\n\nconst editor; // Acquire a reference to the iframe DOM element somehow. This will depend on the frontend framework in use.\n\nconst channel = Channel<ToQuickEditMessage, FromQuickEditMessage>(\n\tnew MessageChannel()\n);\n\neditor.addEventListener(\"load\", () => {\n\teditor.contentWindow.postMessage(\"PORT\", \"*\", [channel.remote]);\n});\n\n// When you have the initial contents of the Worker (loaded from an API, perhaps)\nchannel.postMessage({\n\ttype: \"WorkerLoaded\",\n\tbody: {\n\t\t// Refer to the WorkerLoaded type for details\n\t},\n});\n\nchannel.onMessage((message) => {\n\t// message is of type SetEntryPoint, UpdateFile, CreateFile, or DeleteFile\n\t// Refer to @cloudflare/workers-editor-shared for details\n});\n```\n","packages/runtime-types/README.md":"# `@cloudflare/runtime-types`\n\nUtilities for generating Cloudflare Workers runtime types from compatibility dates and flags.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/shared-ast-primitives/README.md":"# `@cloudflare/shared-ast-primitives`\n\nInternal AST-manipulation primitives shared across Cloudflare Workers SDK codemods.\n\nThis package wraps [`recast`](https://github.com/benjamn/recast) with a small set of\nhelpers (`parseJs`, `parseTs`, `parseFile`, `transformFile`, `mergeObjectProperties`)\nused by C3 and autoconfig to transform user project files. It is private and not published.\n\n## Developing\n\nWriting codemods often requires trial and error. The package ships a dedicated dev workflow so you can iterate on transforms in isolation without writing throw-away scripts.\n\n### Commands\n\n| Command         | Description                                                |\n| --------------- | ---------------------------------------------------------- |\n| `pnpm dev`      | Run `src/dev.ts` in watch mode (hot-reloads on every save) |\n| `pnpm dev:once` | Run `src/dev.ts` once without watching                     |\n\n### Workflow\n\n1. **Edit `dev-snippets/test.ts`** — put whatever source code you want to transform into this file. It is the default input used by the dev script. You can add more files under `dev-snippets/` and reference them from `src/dev.ts`.\n\n2. **Edit `testCodemod()` in `src/dev.ts`** — this is your sandbox. Call `testTransform()` with the path to your snippet and a [`recast` visitor](https://github.com/benjamn/recast) that describes the transform:\n\n   ```ts\n   const testCodemod = () => {\n   \ttestTransform(\"../dev-snippets/test.ts\", {\n   \t\tvisitIdentifier(n) {\n   \t\t\tn.node.name = \"MyNewName\";\n   \t\t\treturn false;\n   \t\t},\n   \t});\n   };\n   ```\n\n3. **Run `pnpm dev`** — the transformed code is printed to the console and written to `dev-snippets-outputs/test.ts` (gitignored). Inspect the output file to verify the transform behaves as expected.\n\n### `testTransform(filePath, methods)`\n\nMirrors the production `transformFile()` API but instead of silently writing in place it:\n\n- Prints the transformed source to the console\n- Writes the result to the corresponding path under `dev-snippets-outputs/`\n\nThe `filePath` argument must point to a file inside `dev-snippets/`; paths outside that directory are rejected.\n","packages/solarflare-theme/README.md":"# Solarflare Theme\n\nThe Solarflare theme is an official VSCode theme for utilization with a modified VSCode for Web in the Cloudflare dashboard.\n","packages/turbo-r2-archive/README.md":"# Turbo R2 Archive\n\n[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/jacobMGEvans/Turbo-R2-Archive)\n\n## Overview\n\nThis is a Worker that will act as an event server for caching TurboRepo artifacts. Compliant with the TurboRepo API, for remote caching, it will store the cache artifacts in a Cloudflare R2 bucket and purge the R2 Objects on a schedule, using [R2 Object lifecycle rules](https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/). This allows for all the benefits of remote caching TurboRepo artifacts on Cloudflare's edge network.\n\nThis will require a Cloudflare account, with a zone and R2.\n\n## Environment Variables\n\nUtilizing `.env` file to store the variables for Turborepo API & Worker. The `.env` file should be in the root of the project directory. The `.env` file should contain the following variables. Be sure to add the `.env` file to `.gitignore` to prevent it from being committed to the repository.\n\nThe commands are ran with `dotenv` cli `npx dotenv -- npx turbo <command>` to inject the environment variables into the command process environment.\n\n```bash\nTURBO_API=<baseURL> # https://something.com\nTURBO_TEAM=<value> # team_whatever it has to start with prefix team_\nTURBO_TOKEN=<value> # whatever is set in the worker secret\nTURBO_REMOTE_CACHE_SIGNATURE_KEY=<value> # needs to be the same for every one using the same cache\n```\n\n## Turbo Project Config\n\nTo utilize the `TURBO_REMOTE_CACHE_SIGNATURE_KEY` which will increase the security of the remote cache, the project config will need to be updated to include the following:\n\n```json\n{\n\t\"remoteCache\": { \"signature\": true }\n}\n```\n\n## Worker Configuration\n\n```jsonc\n{\n\t\"r2_buckets\": [\n\t\t{\n\t\t\t\"binding\": \"R2_ARTIFACT_ARCHIVE\", // The binding name for the bucket, used in the Worker i.e. env.R2_ARTIFACT_ARCHIVE.get(<key>)\n\t\t\t\"bucket_name\": \"turbo-cache\", // bucket name when looking for objects in dashboard\n\t\t\t\"preview_bucket_name\": \"turbo-cache-preview\",\n\t\t},\n\t],\n}\n```\n\nThe endpoints are protected by a bearer token. The token is stored as a secret in the Worker. The token can be set with the following command:\n\n```bash\necho <VALUE> | wrangler secret put TURBO_TOKEN\n```\n\n<!-- Add the setting up the R2 bucket & Object Rules -->\n\n### Manual Cache Purge\n\nThe cache can also be purged manually by sending a `POST` request to the `<baseURL>/artifacts/manual-cache-bust` endpoint. This can be done with the following command:\n\n```bash\nhttps -A bearer -a <TURBO_TOKEN> POST <baseURL>/artifacts/manual-cache-bust\n```\n\n## How can I develop & test locally?\n\nThis project is primarily self-service and is meant to be forked and modified to fit your needs. The following instructions will help you get started.\n\n### Running the Worker Locally\n\nThe Worker can be run, locally with the `package.json` script `start`:\n\n```bash\nnpm run start\n```\n\n### TurboRepo Testing Local Server\n\nWell since we are already using Cloudflare, let's keep that going. `cloudflared` allows for creating a tunnel to your `http://127.0.0.1:8787` and exposing it to the internet. This will allow others direct their TurboRepo to the local dev server by setting`TURBO_API` to `<host>`.\nThe command to create a tunnel looks like:\n\n```bash\ncloudflared tunnel --hostname <host> --url http://127.0.0.1:8787/ --name r2-archive (or whatever you want to name it)\n```\n\n## How can I deploy this?\n\nFork this repo, have a Cloudflare account, and run the following command:\n\n```bash\nnpm run deploy\n```\n\nYou now have a TurboRepo API compliant event server that will cache artifacts on Cloudflare's edge network.\n","packages/unenv-preset/README.md":"# @cloudflare/unenv-preset\n\n[unenv](https://github.com/unjs/unenv) preset for cloudflare.\n\nunenv provides polyfills to add [Node.js](https://nodejs.org/) compatibility for any JavaScript runtime, including browsers and edge workers.\n\n## Usage\n\n```ts\nimport { cloudflare } from \"@cloudflare/unenv-preset\";\nimport { defineEnv } from \"unenv\";\n\nconst { env } = defineEnv({\n\tpresets: [cloudflare],\n});\n\nconst { alias, inject, external, polyfill } = env;\n```\n\nSee the unenv [README](https://github.com/unjs/unenv/blob/main/README.md) for more details.\n\n## Tests\n\nThis package is tested via wrangler e2e tests.\n","packages/vite-plugin-cloudflare/AGENTS.md":"# AGENTS.md — vite-plugin-cloudflare\n\n## OVERVIEW\n\nVite plugin for Cloudflare Workers development. Exports `cloudflare()` plugin factory from `src/index.ts`. ESM-only output.\n\n## STRUCTURE\n\n- `src/index.ts` — Plugin factory\n- `src/cf-vite.ts` — `cf-vite` delegate binary entry (see below)\n- `bin/cf-vite` — shebang shim that dynamic-imports `dist/cf-vite.mjs`\n- `src/workers/` — 4 internal worker entries: `asset-worker`, `router-worker`, `runner-worker`, `vite-proxy-worker`\n- `playground/` — ~47 playground apps, each a workspace member (nested workspace under this package)\n- `e2e/` — E2E tests with Playwright\n- `__tests__/` — Unit tests use `.spec.ts` naming\n\n## BUILD\n\n- Only package using `tsdown` as build tool\n- Outputs ESM (`.mjs`) to `dist/index.mjs`\n- `src/cf-vite.ts` is a second top-level tsdown entry, bundled to `dist/cf-vite.mjs` (no dts)\n- Also bundles 4 internal worker scripts from `src/workers/*/index.ts` as separate neutral-platform outputs to `dist/workers/`\n- Release builds set `SOURCEMAPS=false` to omit the plugin's JavaScript and declaration maps. Normal builds retain maps for debugging; the setting does not change source maps for applications built with the plugin.\n\n## cf-vite DELEGATE BINARY (experimental / internal)\n\n`bin/cf-vite` is an experimental, internal delegate binary spawned by\nCloudflare's \"cf-dev\" parent process — NOT part of the plugin's public\nAPI and not meant for direct end-user invocation. It is the sibling of\n`wrangler`'s `cf-wrangler` binary, and the two MUST keep a shared spawn\ncontract so the parent can drive either impl interchangeably.\n\n- **Verb dispatch.** `cf-vite <verb> [flags]`. `dev` and `build` are the\n  verbs today; future verbs (`deploy`) follow the same shape.\n  Unknown/missing verbs exit `2` (this doubles as the parent's\n  version-detection signal — no JSON handshake).\n- **Shared flag vocabulary (`dev`).** For `dev`, only `--mode`, `--port`,\n  `--host`, `--local` are accepted, mirroring `cf-wrangler` exactly.\n  Parsed with `node:util.parseArgs` strict mode → unknown flags exit `2`.\n  Do NOT add flags here unless `cf-wrangler` grows them too. (There is no\n  `--config` flag: the wrangler config is discovered by `cloudflare()`\n  itself.)\n- **`build`** `cf-vite build` runs Vite's full multi-environment\n  app build via `createBuilder().buildApp()` (NOT the legacy\n  single-environment `build()` helper, which would skip the plugin's\n  worker/build-output orchestration — mirrors Vite's own `vite build`\n  CLI). It accepts only `--mode` (`--port`/`--host`/`--local` don't apply to\n  a build and exit `2`). Preview build context is supplied through\n  `CLOUDFLARE_PREVIEW_BUILD`, which also works when a framework runs Vite as\n  part of its own build command.\n- **Build Output Specification is the core build pipeline.** Every build emits\n  Build Output; there is no feature flag or legacy output-config path. Preview\n  reads Workers and Containers exclusively from that output. The v2 plugin\n  always installs its build-output plugin, so `cf-vite` does not need the\n  internal force-build-output flag used by v1.\n- **Caller identity.** `main()` sets `CLOUDFLARE_VITE_CLI_DISPLAY_NAME=cf`\n  before Vite loads the user's config. `resolvePluginConfig` reads this through\n  `getCliDisplayName()` so shared services can use `cf` in actionable messages;\n  direct Vite plugin use defaults to `Wrangler`. This is an internal bridge,\n  not a `.env`-file knob.\n- **`dev`** `cf-vite dev` boots Vite via `createServer()`\n  against the user's own `vite.config.ts` (which must include\n  `cloudflare()`). Plugin-owned flags are bridged via env vars the plugin\n  already reads (`--local` → `CLOUDFLARE_VITE_FORCE_LOCAL`); Vite-owned\n  flags go through inline config (`--port`/`--host` → `server.*`,\n  `--mode` → `mode`).\n- **`--local`** forces remote bindings off. There is no plugin env knob\n  for `remoteBindings` other than `CLOUDFLARE_VITE_FORCE_LOCAL`, which\n  `resolvePluginConfig` in `plugin-config.ts` honours by overriding the\n  `remoteBindings` config option. Keep that override in sync if the flag\n  semantics change.\n- **Hotkeys differ by design.** `cf-vite` uses Vite's own\n  `bindCLIShortcuts` (`h`/`r`/`q`/…), not wrangler's hotkey set. The\n  parent process should not assume identical hotkey UX across delegates.\n- **Exit codes.** `0` graceful, `2` unknown verb / argv parse error,\n  `130` SIGINT, `143` SIGTERM.\n\n## CONVENTIONS\n\n- Playground directory `worker-♫/` has unicode in name (intentional)\n\n## TESTING\n\n- Unit tests: `.spec.ts` in `__tests__/`\n- E2E tests: `.test.ts` in `e2e/`, own vitest config\n- Playground tests: Playwright-based, tested across Vite 7/8 in CI\n- Playground request helpers (`playground/__test-utils__/responses.ts`):\n  - `getTextResponse()` / `getJsonResponse()` issue a request with browser\n    navigation headers (`Sec-Fetch-Mode: navigate` et al), which the asset and\n    router workers branch on. Default to these.\n  - They use undici's low-level `request()` rather than `fetch()`\n    **deliberately**. The Fetch spec requires implementations to set\n    `Sec-Fetch-Mode` from the request's `mode` (\"append the Fetch metadata\n    headers\"), so `fetch()` overwrites whatever the caller passed with `cors`\n    before the request leaves the process (`appendFetchMetadata` in undici).\n    `Sec-Fetch-Dest`/`-Site`/`-User` are unimplemented there, so they survive —\n    which is why only `Sec-Fetch-Mode` breaks and it is easy to miss. That one\n    decides whether the asset worker applies `not_found_handling`.\n  - This is permanent, not a bug to wait out: no Fetch-based API can send\n    `Sec-Fetch-Mode: navigate`, and `fetch(url, { mode: \"navigate\" })` is\n    rejected by the `Request` constructor. Do not \"simplify\" these back to\n    `fetch()`; `spa-with-api`'s \"via `getTextResponse()`\" test exists to catch\n    exactly that regression (it is the only playground whose compat date enables\n    `SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING`).\n  - `getResponse()` drives a real `page.goto()` and returns a Playwright\n    `Response`. Only use it when the assertion needs the browser. Anything\n    routed through Playwright can outlive a timed-out test and surface as an\n    unhandled rejection, which fails the whole run rather than one test.\n  - `WAIT_FOR_OPTIONS` (`playground/__test-utils__/index.ts`) must stay\n    comfortably below the test timeout, otherwise `vi.waitFor()` never gets to\n    report the assertion that was actually failing.\n- `playground/vitest.config.e2e.ts` inherits the repo-wide timeouts and\n  `retry: 1` from the root `vitest.shared.ts`. It spreads `configShared.test`\n  rather than using `mergeConfig()`, which concatenates arrays and would\n  silently enable the shared `default` reporter alongside `dot`.\n","packages/vite-plugin-cloudflare/README.md":"# `@cloudflare/vite-plugin`\n\nThe Cloudflare Vite plugin enables a full-featured integration between [Vite](https://vite.dev/) and the [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/).\nYour Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications.\n\n```ts\n// vite.config.ts\n\nimport { defineConfig } from \"vite\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\n\nexport default defineConfig({\n  plugins: [cloudflare()],\n});\n```\n\n## Documentation\n\nFull documentation can be found [here](https://developers.cloudflare.com/workers/vite-plugin/).\n\n## Features\n\n- Uses the Vite [Environment API](https://vite.dev/guide/api-environment) to integrate Vite with the Workers runtime\n- Provides direct access to [Workers runtime APIs](https://developers.cloudflare.com/workers/runtime-apis/) and [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/)\n- Builds your front-end assets for deployment to Cloudflare, enabling you to build static sites, SPAs, and full-stack applications\n- Official support for [TanStack Start](https://tanstack.com/start/) and [React Router v8](https://reactrouter.com/) with server-side rendering\n- Leverages Vite's hot module replacement for consistently fast updates\n- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment\n\n## Use cases\n\n- [TanStack Start](https://tanstack.com/start/)\n- [React Router v8](https://reactrouter.com/)\n- Support for more full-stack frameworks is coming soon\n- Static sites, such as single-page applications, with or without an integrated backend API\n- Standalone Workers\n- Multi-Worker applications\n","packages/vite-plugin-cloudflare/e2e/README.md":"# vite-plugin e2e tests\n\nThis directory contains e2e tests that give more confidence that the plugin will work in real world scenarios outside the comfort of this monorepo.\n\nIn general, these tests create test projects by copying a fixture from the `fixtures` directory into a temporary directory and then installing the local builds of the plugin along with its dependencies.\n\n## Running the tests\n\nSimply use turbo to run the tests from the root of the monorepo.\nThis will also ensure that the required dependencies have all been built before running the tests.\n\nYou will need to provide CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN for the Workers AI tests to pass.\n\n```sh\nCLOUDFLARE_ACCOUNT_ID=xxxx CLOUDFLARE_API_TOKEN=yyyy pnpm test:e2e -F @cloudflare/vite-plugin\n```\n\n## Developing e2e tests\n\nThese tests use a mock npm registry where the built plugin has been published.\n\nThe registry is booted up and loaded with the local build of the plugin and its local dependencies in the global-setup.ts file that runs once at the start of the e2e test run, and the server is killed and its caches removed at the end of the test run. The mock npm registry will delegate to the standard public npm registry for non-local dependency requests (e.g. vite, typescript, etc).\n\nThere is a `seed()` helper to setup a clean copy of a fixture outside of the monorepo so that it can be isolated from any other dependencies in the project.\n\nThe simplest test looks like:\n\n```ts\nconst projectPath = await seed(\"basic\", { pm: \"pnpm\" });\n\ntest(\"can serve a Worker request\", async ({ expect, seed, runLongLived }) => {\n\tconst proc = await runLongLived(\"npm\", \"dev\", projectPath);\n\tconst url = await waitForReady(proc);\n\texpect(await fetchJson(url + \"/api/\")).toEqual({ name: \"Cloudflare\" });\n});\n```\n\n- The `seed()` helper creates a `beforeAll()` block:\n  - make a copy of the named fixture into a temporary directory,\n  - updates the vite-plugin dependency in the package.json to match the local version\n  - runs `npm install` (or equivalent package manager command) in the temporary project - the dependencies are installed from the mock npm registry mentioned above.\n  - returns the path to the directory containing the copy (`projectPath` above)\n- The `seed()` helper also creates an `afterAll()` block:\n  - the temporary directory will be deleted at the end of the test.\n- The `runCommand()` helper simply executes a one-shot command and resolves when it has exited. You can use this to install the dependencies of the fixture from the mock npm registry.\n- The `runLongLived()` helper runs an npm script (from the package.json scripts section) and returns an object that can be used to monitor its output. The process will be killed at the end of the test.\n- The `waitForReady()` helper will resolve when a `vite dev` long lived process has output a ready message, from which it will parse the url that can be fetched in the test.\n- The `fetchJson()` helper makes an Undici fetch to the url parsing the response into JSON. It will retry every 250ms for up to 10 secs to minimize flakes.\n\n## Debugging e2e tests\n\nYou can control the logging and cleanup via environment variables:\n\n- Keep the temporary directory after the tests have completed: `CLOUDFLARE_VITE_E2E_KEEP_TEMP_DIRS=true`\n- See debug logs for the tests: `NODE_DEBUG=vite-plugin:test`\n- See debug logs for the mock npm registry: `NODE_DEBUG=mock-npm-registry`\n- See debug logs for Vite: `DEBUG=\"vite:*\"`\n","packages/vite-plugin-cloudflare/playground/additional-modules/README.md":"# Additional Modules\n\nThe modules directory contains the following example files:\n\n- `bin-example.bin` - a TTF file for the Inter font with the extension changed to `.bin`\n- `html-example.html` - a Hello World HTML document\n- `text-example.txt` - a simple text file\n- `wasm-example.wasm` - a compiled WebAssembly file that exports an `add` function\n\nThe WebAssembly is generated from the following C code:\n\n```c\n#include <stdint.h>\n\nint32_t add(int32_t a, int32_t b) {\n    return a + b;\n}\n```\n","packages/vite-plugin-cloudflare/tsconfig.plugin.json":"{\n\t\"extends\": \"@cloudflare/workers-tsconfig/worker.json\",\n\t\"compilerOptions\": {\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true\n\t},\n\t\"include\": [\"src\"],\n\t\"exclude\": [\"src/workers\", \"src/__tests__/fixtures\"]\n}\n","packages/vitest-plugin/AGENTS.md":"# vitest-plugin — Agent Guide\n\n> Custom Vitest pool for running Worker tests inside the actual workerd runtime.\n> Do NOT repeat root AGENTS.md content (pnpm, changesets, code style, etc.).\n\n## THREE-CONTEXT ARCHITECTURE\n\n### 1. Pool (`src/pool/index.ts`)\n\n- Runs in Node.js Vitest process\n- Main export (`exports[\".\"]`), built as ESM (`.mjs`)\n- Orchestrates test execution\n\n### 2. Config (`src/pool/config.ts`)\n\n- Runs in Node.js, part of the pool bundle (no separate package export)\n- Validates pool options (`WorkersPoolOptionsSchema`) and resolves the project's\n  Worker configuration into Miniflare options\n- `src/pool/plugin.ts` provides the `cloudflareTest()` Vite plugin, which injects\n  `cloudflare:test` resolution and sets resolve conditions (`workerd`, `worker`, `browser`)\n\n### 3. Worker (`src/worker/index.ts`)\n\n- Runs inside workerd runtime\n- NOT exported via package.json — internal entry\n- Contains HACK: monkeypatches VitestExecutor to access singleton\n- Has direct cross-package source import into `miniflare/src/workers/core/devalue`\n\n## WORKER CONFIGURATION SOURCES\n\n`parseCustomPoolOptions()` in `src/pool/config.ts` resolves at most one configuration\nfile into a normalised `Config`, then shares every downstream step (remote proxy\nsession, `unstable_getMiniflareWorkerOptions()`, `main`, defines, module rules, tails):\n\n- `wrangler: { configPath, environment }` — a Wrangler configuration file, via\n  `wrangler.unstable_readConfig()`\n- `experimental: { newConfig }` — a `cloudflare.config.ts`, via `src/pool/new-config.ts`\n  (`@cloudflare/config`'s `loadAndParseConfig()` → `convertToWranglerConfig()` →\n  `normalizeAndValidateConfig()`). Mirrors `@cloudflare/vite-plugin`'s\n  `experimental.newConfig`. `ctx.mode` comes from `project.vite.config.mode`.\n\nThe two are mutually exclusive. Whichever is used, the resolved path, config format and\nWorker name are recorded on `options.resolvedConfig` for the pool to consume — never\nre-read the config file from disk.\n\n## BUILD\n\n`tsdown.config.ts` defines 2 separate builds (all ESM):\n\n1. pool — `src/pool/index.ts` → `dist/pool` (emits type declarations)\n2. worker + libs — `src/worker/index.ts` plus `src/worker/lib` and `src/worker/node` → `dist/worker`\n\nTypes entry `types/cloudflare-test.d.ts` is hand-written (NOT generated from source).\n\n## THE `cloudflare:test` MODULE\n\nTests inside workerd import from `cloudflare:test`:\n\n```ts\nimport { env, fetchMock, SELF } from \"cloudflare:test\";\n```\n\nResolved by custom Vite plugin (`@cloudflare/vitest-plugin:config`) that re-exports from `cloudflare:test-internal` (runtime-provided).\n\n## CONVENTIONS\n\n- `expect` must come from test context: `it(\"name\", ({ expect }) => {})` — never `import { expect } from \"vitest\"`\n- Tests use `.test.ts` naming\n- Excludes `*.worker.test.ts` from vitest config\n\n## TESTING\n\n- Does NOT extend `vitest.shared.ts`\n- Hook timeout: 60s, retry: 2\n- Global setup starts mock npm registry, installs local package to temp dir\n- Test helper: custom `test` fixture with `tmpPath`, `seed()`, `vitestRun()`, `vitestDev()`\n- Fixtures in `fixtures/vitest-plugin-examples/` (20+ sub-fixtures testing KV, R2, D1, DO, Queues, `cloudflare.config.ts`, etc.)\n- Skipped on Windows CI due to flakiness\n","packages/vitest-plugin/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2FREADME.md -->","packages/vitest-plugin/src/worker/lib/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Fsrc%2Fworker%2Flib%2FREADME.md -->","packages/vitest-plugin/test/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Ftest%2FREADME.md -->","packages/workers-auth/AGENTS.md":"# AGENTS.md — workers-auth\n\nOAuth-2.0-with-PKCE flow against Cloudflare's `dash.cloudflare.com` (or staging /\ncustom-overridden) endpoints. Used by wrangler and (in future) other Cloudflare\nCLIs. Internal-only — published as `prerelease: true`.\n\n## STRUCTURE\n\n- `src/pkce.ts` — PKCE code-verifier / code-challenge generation (RFC 7636)\n- `src/errors.ts` — `ErrorOAuth2` class hierarchy + `toErrorClass` mapper\n- `src/generate-auth-url.ts` — authorize URL builder\n- `src/generate-random-state.ts` — CSRF state generator\n- `src/env-vars.ts` — `WRANGLER_*` and `CLOUDFLARE_AUTH_*` env-var getters\n- `src/account-id.ts` — `validateAccountId(id, source)`, applied to every user-supplied account ID (`CLOUDFLARE_ACCOUNT_ID`, the consumer's `account_id` config field) before it reaches an API URL path\n- `src/access.ts` — Cloudflare Access detection + service-token / `cloudflared` headers\n- `src/config-file/auth.ts` — the `AuthConfigStorage` / `UserAuthConfig` storage contract (interfaces only). The default plaintext credential implementation lives alongside the credential-store layer at `src/credential-store/file-store.ts` (see \"Credential storage\" below). The core `src/core/auth-config-file.ts` (`createAuthConfigFileHelpers({getConfigPath, format})`) and `src/core/file-storage.ts` (`createFileStorage(format, getPath)`) build the per-profile path helpers and non-credential file stores; each CLI descriptor (`src/wrangler/auth-config-file.ts`, `src/cf/auth-config-file.ts`) binds them to its config dir + `FileFormat` and re-exports `createTomlFileStorage` / `createJsonFileStorage`, `getAuthConfigFilePath`, etc. from its entrypoint. See \"CORE LAYER\" below.\n- `src/config-file/temporary.ts` — `TemporaryAccountStorage` / `TemporaryPreviewAccount` storage contract for the temporary-preview-account flow\n- `src/config-file/index.ts` — generic `ConfigStorage<T>` interface shared by the auth and temporary-account contracts\n- `src/state.ts` — `readStoredAuthState()` + `StoredAuthState` shape\n- `src/token-exchange.ts` — auth-code → token + refresh-token rotation + `fetchAuthToken`\n- `src/callback-server.ts` — local HTTP server for the OAuth callback (listens on the host/port from the consumer's `redirectUri`)\n- `src/device-flow.ts` — `getOauthTokenViaDeviceFlow(options, ctx)`: the OAuth 2.0 Device Authorization Grant (RFC 8628) used by `login({device: true})` when the browser cannot reach the local callback URL. No callback server; prints the verification URL + user code and polls `/oauth2/token`. Every user-facing string is parameterised by `ctx.cliDisplayName` / `ctx.deviceLoginCommand` so the module carries no per-CLI branding. Both endpoints' bodies are narrowed before use (`asDeviceAuthorizationResponse`, `pollDeviceToken`'s `DevicePollResult`) rather than cast — an intermediary's envelope or a 2xx without a grant must produce a reportable `unexpected`/unusable-response error, never `undefined` arithmetic. `slow_down` / 5xx / 429 / unparseable bodies keep the loop alive; the last such failure is reported in place of the generic timeout if the deadline passes\n- `src/generate-device-auth-url.ts` — `generateVerificationUrl` (fallback `verification_uri_complete` builder for servers that omit it, RFC 8628 §3.3.1) + `assertTrustedVerificationUrl`, which rejects any server-supplied verification URL that is not `https:` on exactly the resolved auth domain (with no embedded credentials) before it is printed or handed to `openInBrowser` — the device flow is the only place this package opens a URL it did not build itself (RFC 8628 §5.4, remote phishing)\n- `src/flow.ts` — `createOAuthFlow(ctx)` factory wiring everything together\n- `src/context.ts` — `OAuthFlowContext` interface (DI surface)\n- `src/credential-store/` — opt-in OS-keyring-backed credential persistence (see below)\n- `src/test-helpers/` — MSW handlers for consumers' tests (`@cloudflare/workers-auth/test-helpers`)\n\n### Credential storage (`src/credential-store/`)\n\nPluggable credential persistence layer that consumers can wire into the\nOAuth flow via `ctx.storageFactory`. Default backend is the plaintext\nTOML file (`FileCredentialStore`); an opt-in `EncryptedFileCredentialStore`\nwrites AES-256-GCM-encrypted credentials to a sibling `.enc` file using a\nkey held in the OS keyring. Every store is profile-aware: the file path,\nthe encrypted `.enc` path, and the keyring account name are all derived from\n`resolveAuthProfileBaseName(profile)` (default profile → environment-based\nname; named profile → the profile name), so each auth profile gets its own\nfiles and its own encryption key.\n\n- `interface.ts` — `CredentialStore` interface (extends `AuthConfigStorage` with `kind` and `describe()`)\n- `file-store.ts` — `FileCredentialStore` (plaintext TOML, default)\n- `encrypted-file-store.ts` — `EncryptedFileCredentialStore` + plaintext-TOML migration\n- `crypto.ts` — AES-256-GCM `encryptString` / `decryptString` helpers\n- `resolver.ts` — `createCredentialStorageContext({...})` factory; returns `{ storageFactory, getActiveStore }` (both take an optional `profile`) for the consumer to plug into `createOAuthFlow` (as `ctx.storageFactory`) and `whoami`-style reporting respectively\n- `state.ts` — module-level per-session resolver flags (one-time warnings, the Windows install-failed latch)\n- `key-providers/` — per-platform OS-keyring backends that store only the 32-byte encryption key (never the credential blob itself, so the macOS Keychain 2.5 KB item limit is never a concern):\n  - `interface.ts` — `KeyProvider` interface\n  - `mac-security.ts` — `/usr/bin/security` shell-out\n  - `linux-secret-tool.ts` — `secret-tool` shell-out (probes `libsecret-tools`)\n  - `napi-keyring.ts` — `@napi-rs/keyring` wincred binding on Windows\n  - `lazy-installer.ts` — Windows-only `npm install @napi-rs/keyring` on first opt-in\n  - `factory.ts` — `resolveKeyProvider(serviceName)` picks the right per-platform implementation\n  - `shared.ts` — account-name derivation + keyring JSON envelope encoding\n\n## DI SURFACE\n\n`createOAuthFlow(ctx)` accepts a context object:\n\n- `logger` — drop-in replacement for wrangler's logger singleton\n- `isNonInteractiveOrCI()` — whether to suppress interactive prompts\n- `openInBrowser(url)` — opens the browser to the OAuth authorize URL\n- `hasEnvCredentials()` — short-circuits refresh logic when env-based auth is set\n- `clientId` (required) — the consumer's registered OAuth app ID; `string` or\n  `() => string` for lazy (e.g. env-driven prod/staging) resolution\n- `consent` (required) — the consumer's branded granted/denied consent pages\n- `cliDisplayName` (required) — the consumer's branded name (`\"Wrangler\"`, `\"cf\"`),\n  interpolated into the device flow's \"To authorize \\<name\\>…\" copy\n- `deviceLoginCommand` (required) — the command that restarts the device flow\n  (`\"wrangler login --device\"`), quoted when a device code is denied, expires,\n  or the flow times out\n- `redirectUri` (required) — the registered redirect URI / local callback URL.\n  The callback server's listen host/port and route path are all derived from it\n  (per-call bind overrides via `LoginProps.callbackHost`/`callbackPort`)\n- `storageFactory` (required) — maps an auth profile to the consumer's\n  `AuthConfigStorage` token-persistence backend. The flow calls it with the\n  active profile on every credential access. For keyring opt-in, pass the\n  `storageFactory` from `createCredentialStorageContext(...)` rather than a raw\n  file store, so both the active profile and the encrypted-file / plaintext\n  choice are re-resolved on every credential operation.\n- `purgeOnLoginOrLogout?()` — invalidate consumer-side caches after login/logout\n- `generateAuthUrl?` / `generateRandomState?` — test overrides for deterministic\n  snapshot tests (defaults pull from `./generate-auth-url` / `./generate-random-state`)\n\n`clientId`, `consent`, `cliDisplayName`, `deviceLoginCommand`, `redirectUri`, and\n`storageFactory` are consumer-specific, so they are required rather than\ndefaulted here. Wrangler's values live in the in-package wrangler layer\n(`src/wrangler/`, see below) rather than in the `wrangler` package itself.\n\nThe wrangler layer (`src/wrangler/index.ts`, `createWranglerAuth`) wires the\ncredential-storage layer once via `createCredentialStorageContext(...)` and\nexposes the resulting `getActiveStore` (called with the active profile) as\n`getCredentialStore()` for `whoami`-style code that wants to surface the active\nstorage location.\n\n## CORE LAYER (`src/core/`) + PER-CLI DESCRIPTORS (`src/wrangler/`, `src/cf/`)\n\nThe whole CLI-facing auth layer (the machinery that used to live in\n`packages/wrangler/src/user/`) is **CLI-agnostic** and shared by every\nCloudflare CLI built on this package. It lives in `src/core/`:\n\n- `factory.ts` — `createCloudflareAuth(descriptor, ctx)`: OAuth flow wiring,\n  credential storage, config cache (`@cloudflare/workers-utils`'\n  `createConfigCache`), account selection (`fetchInternalBase` with the token\n  the flow already holds), login / logout / refresh, and `requireAuth`. Imports\n  only `@cloudflare/workers-utils`.\n- `types.ts` — `AuthContext` (the injected primitives: `logger`, optional\n  `temporaryAccountLogger` for temporary-account notices, `userAgent`, interactive\n  `prompt` / `select`, `isNoDefaultValueProvidedError`) and\n  `CliDescriptor` (everything that varies per CLI: `cliName` (the executable),\n  `displayName` (branded name used in prose), auth command names\n  (`login` / `logout` / `whoami` / `createProfile` / `deviceLogin`),\n  `keyringServiceName`,\n  `clientId`, `consent`, `redirectUri`, `useDeviceFlowByDefault`,\n  `getConfigPath`, `fileFormat`,\n  `accountCachePrefix`, `cacheNamespace`, `getConfigFileLabel`,\n  `getDefaultScopeKeys`, …).\n- `file-storage.ts` (`createFileStorage(format, getPath)`), `auth-config-file.ts`\n  (`createAuthConfigFileHelpers({getConfigPath, format})`), `preferences.ts`\n  (`createPreferences(getConfigPath)`), `profile-store.ts`\n  (`createCloudflareProfileStore`), `keyring-preference.ts`\n  (`createKeyringPreference`), `scopes.ts` (shared Cloudflare scope catalog),\n  `file-format.ts`, `temporary-terms.ts`.\n\n**File format** is the `FileFormat` axis (`src/core/file-format.ts`): a simple\n`\"toml\" | \"json\"` union (the value doubles as the file extension) plus\n`parseFile` / `stringifyFile` helpers. It's threaded through `createFileStorage`\nand the credential store (`FileCredentialStore` / `EncryptedFileCredentialStore`\n/ `resolver.ts` all take an optional `format`, defaulting to `\"toml\"` so wrangler\nis unchanged; the encrypted `.enc` sibling is format-independent). Wrangler uses\n`\"toml\"`; cf uses `\"json\"`.\n\nEach CLI is a thin **descriptor + entrypoint**:\n\n- `src/wrangler/` → `@cloudflare/workers-auth/wrangler`: `WRANGLER_CLI`\n  (TOML, wrangler's global config dir, wrangler's OAuth app / `\"wrangler\"`\n  keyring service) + `createWranglerAuth(ctx) = createCloudflareAuth(WRANGLER_CLI, ctx)`.\n  Re-exports everything wrangler's `src/user/*` imports (`createTomlFileStorage`,\n  `readUserPreferences`, `createWranglerProfileStore`, `setKeyringPreference`,\n  scopes, `getClientIdFromEnv`, `OAUTH_CALLBACK_URL`, …) — no re-export shim\n  files remain in `wrangler/src/user/`.\n- `src/cf/` → `@cloudflare/workers-auth/cf`: `CF_CLI` (JSON files under\n  `~/.config/cloudflare`, the `\"cloudflare\"` keyring service, `CLOUDFLARE_CLIENT_ID`)\n  - `createCfAuth(ctx)`. OAuth-app values (client ID `cbca97e7-…`, callback port\n    8877, `cf-oauth-consent-*` pages, scoped-token-only auth) mirror the `cf`\n    CLI's registration, and device authorization is its default interactive\n    login flow. cf carries its own scope policy (`src/cf/scopes.ts`): the raw\n    client registration is kept separate from the known-grantable catalog used\n    for validation and types, and sensitive requestable scopes can be excluded\n    from login defaults. Requestable scopes must both appear in the client\n    registration and resolve in the consent service's Bach catalog; registered\n    exceptions stay explicit negative regressions. Retain separately verified,\n    grandfathered legacy scopes and registration order.\n    This is distinct from wrangler's smaller `src/core/scopes.ts` key →\n    description map, so cf does not re-export `DefaultScopes`.\n\n## CONVENTIONS\n\n- License: dual MIT/Apache-2.0. Files derived from\n  [BitySA/oauth2-auth-code-pkce](https://github.com/BitySA/oauth2-auth-code-pkce)\n  carry the Apache-2.0 header.\n- No `console.*` — use the injected `ctx.logger`. Temporary-account notices\n  (terms notice, proof-of-work, \"Temporary account ready\") go through the\n  `temporaryAccountLogger` instead, so a CLI can keep them off stdout.\n- No global `fetch` — use undici's `fetch`.\n- `UserError` instances must carry stable `telemetryMessage` labels\n  (`<area> <sub-area> <failure>`, e.g. `user oauth invalid scope`).\n  These labels are part of the telemetry contract — preserve them verbatim.\n- No direct Cloudflare REST API calls. This package talks to OAuth endpoints\n  (`/oauth2/auth`, `/oauth2/token`, `/oauth2/revoke`) only.\n- OAuth callback server listens on the host/port derived from the consumer's\n  required `ctx.redirectUri`; override the bind address per-call via\n  `LoginProps.callbackHost` / `callbackPort`.\n\n## BUILD\n\n- tsup: two entry points — `src/index.ts` and `src/test-helpers/index.ts`\n- ESM-only output to `dist/`\n- `@cloudflare/*`, `undici`, `msw`, and `vitest` are kept external\n\n## CREDENTIAL STORAGE NOTES\n\n- The encrypted file uses `AES-256-GCM` via `node:crypto` (no third-party\n  crypto deps). The 12-byte IV is generated fresh per write; the 16-byte\n  GCM auth tag is verified on every read.\n- The keyring entry holds only a 32-byte AES key wrapped in a small JSON\n  envelope (`{v, key, created}`). It's well under the macOS Keychain ~2.5 KB\n  per-item limit no matter how the credential schema grows.\n- `@napi-rs/keyring` (the Windows backend's native binding) is installed\n  lazily on first opt-in via `npm install` into `<configPath>/native/keyring/`,\n  where `configPath` is the consumer-provided global config directory (see\n  `getConfigPath` below) — so each CLI's binding lives under its own config dir.\n  Pinned to `PINNED_KEYRING_VERSION` so CI users running\n  `npm install -g @napi-rs/keyring` by hand get the same version as the\n  lazy-install path.\n- The credential files (`.toml` / `.enc`) and the keyring install dir are all\n  rooted at the consumer's config directory. `@cloudflare/workers-auth` never\n  resolves that path itself (wrangler and a future `cf` CLI use different global\n  config paths); instead the consumer passes `getConfigPath: () => string` into\n  `createCredentialStorageContext`, and the path helpers\n  (`getAuthConfigFilePath` / `getEncryptedAuthConfigFilePath` /\n  `getKeyringInstallDir`) and store constructors all take it explicitly.\n- The consumer's `createCredentialStorageContext` call captures `serviceName`,\n  `getConfigPath`, `isKeyringEnabled`, `logger`, `isNonInteractiveOrCI`, and\n  `loginCommand` in a closure. The returned `storageFactory(profile)` re-resolves\n  the active store on every call so the active profile, `--use-keyring` /\n  `--no-use-keyring`, and the `CLOUDFLARE_AUTH_USE_KEYRING` env var all take\n  effect without rebuilding the OAuth flow. Per-session memoization flags\n  (`hasWarnedAboutKeyringFallback`, `installFailedThisSession`, ...) still\n  live at module scope in `state.ts`; tests use\n  `resetCredentialStorageState` to clear them between cases and\n  `setKeyProviderFactoryForTesting` to swap in stubs.\n","packages/workers-auth/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-auth%2FREADME.md -->","packages/workers-playground/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-playground%2FREADME.md -->","packages/workers-shared/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2FREADME.md -->","packages/workers-shared/asset-worker/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Fasset-worker%2FREADME.md -->","packages/workers-shared/router-worker/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Frouter-worker%2FREADME.md -->","packages/workers-utils/AGENTS.md":"# AGENTS.md — workers-utils\n\n## OVERVIEW\n\nShared utility package used across wrangler, miniflare, and others. Two main areas: config validation and test helpers.\n\n## STRUCTURE\n\n- `src/config/` — Configuration types, validation, normalization\n  - `validation.ts` — The config normalizer (large file). Central to all wrangler config processing.\n  - `environment.ts` — Environment/config field definitions (many deprecated fields)\n  - `config.ts` — Config types\n- `src/test-helpers/` — Shared test utilities used across packages\n- `src/types.ts` — Shared type definitions\n\n## KEY EXPORTS\n\n### Config\n\n- Validation pipeline normalizes wrangler.json/toml into typed config objects\n- Used by wrangler for all config loading\n\n### D1 migrations\n\n- `getD1MigrationFiles({ projectPath, migrationsDir, migrationsPattern })` — shared glob-based discovery used by Wrangler and the Vitest plugin. Honour `migrations_pattern` rather than recursively collecting every `.sql` file.\n\n### Shared runtime utilities\n\n- `createConfigCache(logger)` — file-backed JSON config cache (node_modules/.cache or `.wrangler/cache`). Generic mechanism; the consumer passes its logger (this package has no logger singleton). Both `wrangler` (`src/config-cache.ts`) and `@cloudflare/workers-auth` build their own instances.\n- `openInBrowser(url, logger)` — opens the `open` package with a graceful copy-paste fallback when no browser opener is available. Logger is a parameter, not imported.\n- `isInteractive()` / `isNonInteractiveOrCI()` / `isCI()` — TTY / CI detection (the TTY check is inlined here to avoid a cycle back through `@cloudflare/cli-shared-helpers`). `isCI()` keys off CI specifically (ignoring TTY), for behaviour like redacting account names in public CI logs. These read `ci-info`, which is bundled into consumers' distributables. Because a bundled `ci-info` is an unmockable separate instance (and reads the real environment), consumers that need to fake CI in their tests mock **this package's** exports rather than `ci-info` — e.g. wrangler's `vitest.setup.ts` mocks `@cloudflare/workers-utils` so `isInteractive`/`isNonInteractiveOrCI`/`isCI` delegate to the mockable `ci-info`, which reaches both wrangler-source and bundled `@cloudflare/workers-auth` consumers (since `@cloudflare/*` is external in workers-auth's bundle).\n\n### Test Helpers\n\n- `runInTempDir()` — Creates temp dir, chdir's into it, stubs HOME/XDG_CONFIG_HOME, cleans up\n- `seed(files)` — Writes `Record<string, string>` of path->content into temp dir\n- `writeWranglerConfig()` / `readWranglerConfig()` — Mock wrangler config files (TOML, JSON, JSONC)\n- `mockConsoleMethods()` — Spies on console, returns normalized output with `.debug`, `.out`, `.info`, `.err`, `.warn`\n- `normalizeString()` — Multi-stage pipeline: strips timings, thin spaces, temp dirs, normalizes slashes/cwd/dates/tables/error markers/byte values, and scrubs the OAuth authorize URL's random `state` / `code_challenge` query params to `<OAUTH_STATE>` / `<OAUTH_CODE_CHALLENGE>` (so login-URL snapshots stay deterministic without mocking the URL builder)\n\n## NOTES\n\n- `validation.ts` is the largest single file in the monorepo after generated code — changes here affect all config processing\n- Many deprecated fields in `environment.ts` — check `@deprecated` annotations before modifying\n- Test helpers imported as `@cloudflare/workers-utils/test-helpers` across packages\n","packages/workers-utils/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2FREADME.md -->","packages/workers-utils/src/config/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2Fsrc%2Fconfig%2FREADME.md -->","packages/workflows-shared/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkflows-shared%2FREADME.md -->","packages/wrangler/AGENTS.md":"# Wrangler — Agent Guide\n\nWrangler-specific context only. See root `AGENTS.md` for monorepo conventions.\n\n## Overview\n\nMain CLI for Cloudflare Workers. ~2k-line yargs command tree in `src/index.ts`. Entry point is `src/cli.ts` (NOT `src/index.ts`).\n\n## Structure\n\n- `src/` — CLI source\n- `src/__tests__/` — Unit tests, helpers in `src/__tests__/helpers/`\n- `e2e/` — E2E tests, requires Cloudflare credentials\n- `bin/wrangler.js` — Shim that spawns Node to run `wrangler-dist/cli.js`, forwarding stdio and IPC\n- `bin/cf-wrangler.js` — `cf-wrangler` delegate entrypoint. Owns verb dispatch, argv parsing (`parseCfWranglerArgs`), and the `StartDevOptions` literal; hands off to `runCfWranglerDev` from `wrangler-dist/cli.js` in-process (no re-spawn — the parent tool owns the Node runtime)\n- `src/containers/ssh.ts` — Thin command adapter; SSH options, authorization request, and transport live in `@cloudflare/containers-shared/src/ssh.ts`, shared with cf.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint (see below)\n- `src/containers/images.ts` — Command adapter; registry image operations live in `containers-shared/src/registry-images.ts`, shared with cf.\n- `templates/` — Worker templates\n\n## Entry Points\n\n- `src/cli.ts` — Build entry AND library API surface (dual-purpose). Calls `main()` when run directly; re-exports `./api` when imported as library. Also re-exports `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, `ArgParseError`, `runCfWranglerDev`, and `runCfWranglerBuild` for the `cf-wrangler` bin to call in-process.\n- `src/index.ts` — Yargs CLI tree builder (large file). Exports `main()`. NOT the package entry point despite the name.\n- `src/api/index.ts` — Public programmatic API barrel.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint, an experimental escape hatch for projects that can't use `@cloudflare/vite-plugin`. It exposes `dev` + four flags (`--mode`, `--port`, `--host`, `--local`) and `build` + `--mode`; the wrangler config file is found via wrangler's standard discovery (no `--config` flag). Preview build context is supplied through `CLOUDFLARE_PREVIEW_BUILD`, matching framework-owned build commands. It is NOT a separate package and does NOT use the `unstable_dev` test harness. It shares its spawn contract (verb dispatch, flag vocabulary, exit-2 feature detection) with the sibling `cf-vite` delegate in `@cloudflare/vite-plugin`. `bin/cf-wrangler.js` owns verb dispatch, argv parsing, and the `StartDevOptions` literal; `src/cf-wrangler/dev.ts` (exported as `runCfWranglerDev`) wraps `startDev` in the experimental-flags context and waits for teardown. `src/cf-wrangler/build.ts` (exported as `runCfWranglerBuild`) runs the Build Output Specification path used by `wrangler build --experimental-new-config --experimental-cf-build-output`, producing `.cloudflare/output/v0`. `src/cf-wrangler/args.ts` (exported as `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, and `ArgParseError`) does the strict argv parse. The \"unknown subcommand\" error doubles as a feature-detection signal for the parent CLI.\n\n## Conventions (Wrangler-Specific)\n\n- No `console.*` — use `logger` singleton\n- No `__dirname` / `__filename` — use `getBasePath()`\n- No global `fetch` — use undici's fetch\n- Route Cloudflare v4 API calls through the existing `cfetch` helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult` when possible;\n  do not use global or undici `fetch` directly. Prefer these helpers over\n  adding or passing the `cloudflare` package solely for a simple request, and\n  use the Cloudflare TypeScript SDK when its generated API surface or behavior\n  is materially useful.\n- `telemetryMessage` values for `UserError`-compatible errors must be static, safe labels. Do not use `telemetryMessage: true` unless 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: true` is usually less useful because user-facing copy is harder to group and parse than a stable telemetry label.\n- Format `telemetryMessage` values as lower-case phrases: `<service or area> <command or sub-area> <failure>`, for example `kv namespace binding not found in config`, `r2 object put file not found`, or `pages deploy project name missing`.\n- 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.\n\n## Build\n\n- tsup: single entry `src/cli.ts` → `wrangler-dist/cli.js`\n- `package.json` `main` points at `wrangler-dist/cli.js`\n- Custom `embedWorkersPlugin()` bundles Worker templates via esbuild for tests\n\n## Testing\n\n- Pool: `\"forks\"` (not threads) — heavy global mocking\n- `runWrangler(cmd)` calls `main()` in-process (no subprocess)\n- MSW for API mocking — pre-built handlers per API domain in `src/__tests__/helpers/msw/`\n- Shared helpers: `runInTempDir()`, `mockAccountId()`, `mockApiToken()`, `mockConfirm()`, `mockPrompt()`, `mockSelect()`, `captureRequestsFrom()`\n- Unit timeout: 50s, retry: 0. Note: wrangler's `vitest.config.mts` does NOT use `mergeConfig` with `vitest.shared.ts`, so shared defaults (timeouts, retry, etc.) are not inherited — they must be set explicitly in the wrangler config.\n- E2E timeout: 90s, bail: 1, singleThread\n- `globals: true` for vitest globals\n- Output normalization via `normalizeString()` pipeline\n\n## Anti-Patterns\n\n- Test files use `.test.ts` (not `.spec.ts`)\n- Never import `expect` from vitest — use test context `({ expect }) => {}`\n  - When adding `expect` as a parameter to helper functions, check ALL call sites (e.g., across `deployments.test.ts`, `versions.test.ts`)\n","packages/wrangler/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2FREADME.md -->","packages/wrangler/e2e/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fe2e%2FREADME.md -->","packages/wrangler/src/pages/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fsrc%2Fpages%2FREADME.md -->","tools/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=tools%2FREADME.md -->"},"files":{".github/skills/issue-review.md":"---\nname: github-issue-review\ndescription: Triage a GitHub issue on cloudflare/workers-sdk. Assesses quality, identifies the component, checks for duplicates, and recommends next steps.\n---\n\n# GitHub Issue Triage Skill\n\nThis skill triages a GitHub issue to assess its quality, identify the affected component, and recommend next steps for the maintainers.\n\n**Important:** This skill runs without bash or network access. All analysis is based on the pre-fetched issue data in `context.json`. Use only `read`, `glob`, `grep`, `edit`, and `write` tools.\n\n## Input\n\nPre-fetched issue data at `data/<issue_number>/context.json` containing the full issue details from the GitHub API (title, body, comments, labels, author, dates).\n\n## Triage Process\n\nPerform the following steps in order. **Stop and skip to Output as soon as you have sufficient evidence for a recommendation.**\n\n### Step 1: Load Issue Details\n\nRead the pre-fetched `context.json` file using the `read` tool.\n\nExtract and note:\n\n- Title and description\n- Issue type (bug report vs feature request vs question)\n- Product/component affected\n- Version reported against (if any)\n- Operating system (if any)\n- Reproduction steps or reproduction link (if any)\n- Error messages (if any)\n- Comment count and any relevant comment content\n- Labels currently applied\n- Issue age (created date) and last activity date\n- `state_reason` if the issue is already closed\n\n### Step 2: Check for Closeable Issues\n\nCheck each of the following categories in order. **STOP at the first match** and skip to Output.\n\n> **Note:** The `state_reason` values in this section (`completed`, `not_planned`) are informational — they indicate the appropriate GitHub close reason for maintainer reference. They are not captured as a field in the output report.\n\n#### 2a: Spam or Junk\n\nRecommend **CLOSE** (state_reason: `not_planned`, no comment needed) if:\n\n- The body contains random characters, test text, or nonsensical content (e.g. \"bhhg\", \"ssssssssss\", \"aloll\")\n- The issue is clearly spam (e.g. loan advertisements, SEO spam, unrelated product promotions)\n- The issue is a blank/empty test issue (e.g. title is \"test\" with no meaningful body)\n- The body is entirely empty or contains only template headers with no content filled in\n\n#### 2b: Reporter Confirmed Resolved\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The reporter explicitly confirmed the issue is resolved in comments\n- The reporter said they found a workaround and no longer need a fix\n- A maintainer indicated it should be closed in comments\n\n#### 2c: Already Fixed in a Prior Release\n\nRecommend **CLOSE** (state_reason: `completed`) if, based on references within the issue comments or linked PRs:\n\n- A comment references a PR or release that addresses this issue\n- The issue describes a bug that was fixed in a version newer than the reporter's version\n- The issue's symptoms match a fix described in a linked PR or comment\n\nWhen closing, cite the specific PR number and release version if known.\n\n**Template:**\n\n> This issue has been fixed in PR #XXXX, which was released in **wrangler X.Y.Z** (or the relevant package version). Please update and let us know if you're still seeing the issue.\n\nOr for older issues where the fix can't be pinpointed:\n\n> This is a fairly old issue, and from testing with the latest version, it appears to have been resolved. I'm going to close it for now — if you're still running into problems on the latest version, feel free to open a new issue with more details and we can investigate further.\n\n#### 2d: Duplicate\n\nRecommend **CLOSE** (state_reason: `not_planned`) if a comment or linked reference in the issue identifies it as a duplicate of another issue — for example, a maintainer has already commented pointing to a canonical issue, or the reporter themselves links to an existing report.\n\nWhen closing, link to the canonical issue.\n\n**Template:**\n\n> Closing as a duplicate of #XXXX. Please follow that issue for updates.\n\nIf the duplicate is in another repo:\n\n> I'm closing this as a duplicate of <owner/repo>#XXXX, which is where this is being tracked.\n\n#### 2e: Not workers-sdk / Wrong Repo\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes Workers **runtime** behavior (fetch API quirks, V8 issues, compatibility flags, crypto APIs) — belongs in [cloudflare/workerd](https://github.com/cloudflare/workerd)\n- The issue is about a third-party framework (Nuxt, SvelteKit, Remix, Hono, React Router) and the bug is in that framework's code, not in Wrangler or the Vite plugin\n- The issue is about an upstream tool (esbuild, Bun, Vite core) rather than Cloudflare's integration\n- The issue is an account/billing/abuse problem — belongs in Cloudflare Support\n\n**Templates:**\n\nFor framework issues:\n\n> It looks like this issue is coming from <framework>, rather than from workers-sdk. I'd recommend opening an issue on that project's repo: <link>. If it turns out to be a workers-sdk issue after all, feel free to open a new issue here with more details.\n\nFor runtime issues:\n\n> This looks like a Workers runtime issue rather than a tooling issue. The right place to track this is [cloudflare/workerd](https://github.com/cloudflare/workerd) — could a maintainer transfer this issue there?\n\n(Set Action field to: \"Transfer to cloudflare/workerd, then post this comment.\")\n\nFor account/support issues:\n\n> Unfortunately, we're unable to provide support for account-level issues via GitHub. Please contact Cloudflare Support at https://dash.cloudflare.com/?to=/:account/support or the email address mentioned in the error message.\n\n#### 2f: Stale / No Response\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue has the `awaiting-response:reporter` or `needs-reproduction` label AND the last activity was >30 days ago\n- The issue is >12 months old with no activity in the last 6 months\n- A maintainer asked for a reproduction or clarification and the reporter never responded\n\n**Template:**\n\n> We haven't heard from you in a while so I'm going to close this issue for now. If you're still running into problems, feel free to open a new issue with more details and we can investigate further.\n\nFor very old issues:\n\n> This is a very old issue so I'm going to close it for now. If you're still running into problems on the latest version, feel free to comment with more details and we can investigate further.\n\n#### 2g: Transient Platform Issue\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The issue describes a one-time API error (500, 503, auth failures) that appears to have been a service incident\n- Multiple users reported the same error around the same time, and it has since stopped\n- The error is from Cloudflare's API (not from Wrangler itself) and there's no way to fix it in workers-sdk\n\n**Template:**\n\n> This was a transient API issue, and should be resolved now. If you're still seeing this error, please open a new issue with the latest details and we can investigate further.\n\nOr for old transient issues:\n\n> This appears to have been a transient server-side API issue. Similar reports were caused by Cloudflare API incidents that have since been resolved. I'm going to close this for now.\n\n#### 2h: User Error / Misunderstanding\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes expected behavior that the reporter misunderstands\n- The issue is caused by incorrect configuration, wrong SQL syntax, or misuse of an API\n- The fix is a documentation pointer rather than a code change\n\nWhen closing, explain the correct approach and link to relevant documentation. Be helpful, not dismissive.\n\n**Template:**\n\n> This isn't a bug — <brief explanation of the correct behavior>. You can find more details in the docs: <link>. I'm going to close this for now, but feel free to ask on our [Discord](https://discord.cloudflare.com) if you have more questions.\n\n#### 2i: Breaking Change\n\nRecommend **KEEP OPEN** if:\n\n- The requested change would be a breaking change in the current major version\n\nThe issue should remain open as a tracking item. Do not close it — the team hasn't decided against the change, it's deferred to a future major version.\n\n**Suggested labels:** `breaking-change`\n\n**Template:**\n\n> Changing this behavior at this stage would be a breaking change, so it will need to wait for the next major version. I've added the `breaking-change` label to track this.\n\n(Set Action field to: \"Apply `breaking-change` label, then post this comment.\")\n\n#### 2j: Won't Fix / By Design\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The behavior is intentional and documented\n- The team has explicitly decided not to implement this feature\n- The cost/complexity of the change outweighs the benefit\n\n**Templates:**\n\nFor design decisions:\n\n> This is intentional behavior — <brief explanation>. I don't think we're likely to change this in the near future, but we appreciate the feedback.\n\nFor feature requests that won't happen:\n\n> Thanks for the suggestion. We don't intend to implement this right now, but it may be revisited in future. <Optional: brief explanation of why, or pointer to an alternative approach.>\n\n#### 2k: Feature Superseded / Deprecated\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The requested feature has been implemented via a different mechanism than proposed\n- The issue relates to a deprecated feature that has a replacement\n- A newer feature or package addresses the underlying need\n\n**Template:**\n\n> This has been addressed by <feature/package>. <Brief explanation of how it solves the original request.> I'm going to close this for now.\n\n### Step 3: Check for Insufficient Information\n\nIf the issue wasn't caught by Step 2, recommend **NEEDS MORE INFO** if:\n\n- Bug report has no reproduction steps or link (the bug template requires one)\n- Bug report is missing version information\n- The description is too vague to act on (e.g. \"it doesn't work\" with no details)\n- The error message is missing or truncated\n\n**Template:**\n\n> Thanks for reporting this. Could you provide <specific missing information>? In particular:\n>\n> - <specific question 1>\n> - <specific question 2>\n>\n> A minimal reproduction (a GitHub repo or link we can clone and run) would also help us investigate. Without more details, we won't be able to look into this.\n\n**Suggested label:** `awaiting-response:reporter` (and optionally `needs-reproduction`)\n\n**STOP HERE if** the issue clearly needs more info. Skip to Output.\n\n### Step 4: Identify Component\n\nMap the issue to a package based on labels, title, and body content:\n\n| Signal                                                                           | Package                                         |\n| -------------------------------------------------------------------------------- | ----------------------------------------------- |\n| `package:wrangler` label, wrangler CLI commands, `wrangler.toml`/`wrangler.json` | `packages/wrangler`                             |\n| `package:miniflare` label, local dev simulation                                  | `packages/miniflare`                            |\n| `product:d1` label, D1 database, `d1 execute`, migrations                        | `packages/wrangler` (D1 code is in wrangler)    |\n| `package:vitest` label, worker tests, `vitest-plugin`                            | `packages/vitest-plugin`                        |\n| `package:vite-plugin` label, vite dev, `@cloudflare/vite-plugin`                 | `packages/vite-plugin-cloudflare`               |\n| `package:c3` label, `create-cloudflare`, project scaffolding                     | `packages/create-cloudflare`                    |\n| `product:pages` label, Pages deployment, `_routes.json`, `_headers`              | `packages/wrangler` (Pages code is in wrangler) |\n| `feature:workers-assets` label, static asset serving                             | `packages/wrangler`                             |\n| `product:containers` label, container registry                                   | `packages/wrangler`                             |\n| `product:workflows` label, Workflows API                                         | `packages/wrangler`                             |\n| `feature:workers-builds` label                                                   | Workers Builds (may be internal)                |\n| `python` label, Python Workers                                                   | `packages/wrangler`                             |\n| `product:workers-for-platforms` label, dispatch namespaces                       | `packages/wrangler`                             |\n| `package:kv-asset-handler` label                                                 | `packages/kv-asset-handler`                     |\n| `feature:types` label, `wrangler types` command                                  | `packages/wrangler`                             |\n| R2, KV, Queues, Durable Objects, Vectorize bindings                              | `packages/wrangler`                             |\n| `node-compat`/`nodejs-compat` label, Node.js APIs                                | May be workerd or wrangler depending on context |\n| Workers runtime behavior (not tooling)                                           | Likely belongs in cloudflare/workerd            |\n| Cloudflare dashboard, API behavior                                               | Likely a platform issue, not workers-sdk        |\n\n### Step 5: Assess Reproducibility and Severity\n\nFor **bug reports**, evaluate:\n\n- **Has reproduction?** Does the issue include a minimal repro link or clear steps?\n- **Severity estimate:** Is this a crash, data loss, incorrect behavior, or cosmetic issue?\n- **Scope:** Does it affect all users or a specific configuration?\n- **Workaround available?** Did the reporter or comments mention one?\n- **Version gap:** Is the reporter on an old version? Could updating fix this?\n\nFor **feature requests**, evaluate:\n\n- **Clarity:** Is the proposed solution clearly described?\n- **Use case:** Is the motivation explained?\n- **Scope:** Small enhancement vs large new feature?\n- **Existing alternatives:** Is there already a way to achieve this (even if less convenient)?\n\n## Output Format\n\n**How the output is used:** `report.md` is posted verbatim as a maintainer-facing triage comment on the issue (attributed to an automated bot), and the labels in `summary.json` are applied automatically. Because of this:\n\n- Write `report.md` for maintainers, not the reporter. The **Suggested Comment** section is a _draft_ for a maintainer to send to the reporter — it is **not** posted automatically, so do not phrase the surrounding report as though a reply has already been made.\n- Only put labels in the **Suggested Labels** fields that already exist in the repository. If unsure whether a label exists, omit it rather than guess — non-existent labels are dropped before applying, so inventing labels only weakens the report's accuracy.\n\n### Report Directory Structure\n\n```\n./data/<issue_number>/\n├── report.md          # Full detailed report\n└── summary.json       # Structured JSON summary\n```\n\n### Output Step 1: Write Full Report\n\nWrite the full report to `./data/<issue_number>/report.md`:\n\n```markdown\n# Issue Triage: <owner/repo>#<number>\n\n## Summary\n\n<One-line summary of the issue>\n\n## Classification\n\n- **Type:** <Bug | Feature Request | Question | Discussion>\n- **Component:** <package name or \"unknown\">\n- **Severity:** <Critical | High | Medium | Low | N/A>\n- **Has Reproduction:** <Yes (with link) | No | N/A>\n- **Quality:** <Complete | Partial | Incomplete>\n\n## Findings\n\n- **Created:** <date>\n- **Author:** <username>\n- **Version:** <reported version, or \"not specified\">\n- **Labels:** <labels, or \"none\">\n- **Comments:** <count>\n\n### Analysis\n\n<2-5 bullet points covering what you found — component identification,\nreproducibility assessment, severity reasoning, staleness indicators,\nduplicate candidates. Only include what's relevant.>\n\n## Recommendation\n\n**Status:** <CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\n\n**Reasoning:** <2-3 sentences explaining why>\n\n**Action:** <What a maintainer should do next>\n\n**Suggested Labels:** <labels to add, if any. Use existing repo labels only.>\n\n### Suggested Comment\n\n> <The exact comment to post on the issue. Follow the templates above for the\n> matching closure category. Key principles:\n>\n> - Always offer an escape hatch (\"feel free to open a new issue\")\n> - Link to specific PRs, releases, or docs when available\n> - Be concise for straightforward closures, detailed for design decisions\n> - Never be dismissive or snarky, even for spam (just close silently) or user error\n> - For NEEDS MORE INFO, ask specific questions (not generic \"please provide more details\")\n>   Omit this section entirely for spam (close without comment) or if no comment is needed.>\n```\n\n### Output Step 2: Write Summary File\n\nWrite a machine-readable summary as **JSON** to `./data/<issue_number>/summary.json`. This file is parsed by the triage workflow (to build the dashboard payload and apply labels), so it must be valid JSON with exactly these keys:\n\n```json\n{\n  \"issueNumber\": <issue_number as a number>,\n  \"title\": \"<issue title, with emoji/template prefixes like 'Bug:' removed>\",\n  \"githubUrl\": \"https://github.com/<owner>/<repo>/issues/<issue_number>\",\n  \"recommendation\": \"<CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\",\n  \"difficulty\": \"<easy | medium | hard | n/a>\",\n  \"reasoning\": \"<brief reasoning, 1-2 sentences>\",\n  \"suggestedAction\": \"<brief description of next steps>\",\n  \"hasSuggestedComment\": <true if a Suggested Comment section is present in the report, false otherwise>,\n  \"suggestedLabels\": [\"<label>\", \"...\"]\n}\n```\n\n**Key definitions:**\n\n- **issueNumber**: The issue number as a JSON number (not a string).\n- **title**: Issue title with any emoji prefixes (e.g. \"🐛 Bug:\") or template prefixes removed.\n- **githubUrl**: Full URL to the issue.\n- **recommendation**: One of `CLOSE`, `KEEP OPEN`, `NEEDS MORE INFO`, `NEEDS VERIFICATION`.\n- **difficulty**: Estimated fix difficulty — `easy`, `medium`, `hard`, or `n/a` (for feature requests or closures).\n- **reasoning**: Brief summary of why (1-2 sentences).\n- **suggestedAction**: Brief description of next steps.\n- **hasSuggestedComment**: Boolean — `true` if the report includes a Suggested Comment, `false` otherwise.\n- **suggestedLabels**: JSON array of labels to apply, matching the **Suggested Labels** field in the report. Use existing repo labels only (see above). Use an empty array `[]` if there are no labels to apply.\n\n**CRITICAL:** Write valid, parseable JSON only (no trailing commas, no comments, no surrounding markdown fences). Because JSON strings are escaped, `reasoning`/`suggestedAction` may safely contain any punctuation.\n",".opencode/skills/local-explorer/SKILL.md":"---\nname: local-explorer\ndescription: How to add products/resources to the local explorer or local API. Use when implementing new local APIs, or UI routes under packages/miniflare/src/workers/local-explorer or packages/local-explorer-ui.\n---\n\n# Cloudflare Local Explorer Products\n\nUse this skill when adding a new product or resource type to the local API and/or local explorer.\n\n## Start Here\n\nRead these files before editing:\n\n- `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`\n- `packages/miniflare/src/plugins/core/explorer.ts`\n- `packages/miniflare/src/plugins/core/types.ts`\n- One existing resource implementation in `packages/miniflare/src/workers/local-explorer/resources/`, preferably the product most similar to the new one\n- One matching test in `packages/miniflare/test/plugins/local-explorer/`\n\nIf there are UI changes, also read:\n\n- `packages/local-explorer-ui/src/components/Sidebar.tsx`\n- Existing route files under `packages/local-explorer-ui/src/routes/`\n- Existing product e2e tests under `packages/local-explorer-ui/src/__e2e__/`\n\n## Workflow\n\n1. Add the API surface to `packages/miniflare/scripts/openapi-filter-config.ts`.\n2. Generate Miniflare's filtered spec and backend types from a full Cloudflare OpenAPI spec:\n\n```bash\nOPENAPI_INPUT_PATH=<path-to-full-openapi-spec> pnpm --dir packages/miniflare generate:api\n```\n\n3. Inspect `packages/miniflare/src/workers/local-explorer/openapi.local.json` and generated types. If the generated schemas include fields local explorer will not support, add ignores in `openapi-filter-config.ts` and regenerate.\n4. The explorer worker should have access to all user resource bindings. Ensure `proxyBindings` include bindings to the new product and that `getExplorerServices()` exposes any extra bindings the explorer worker needs. Wire product bindings through `constructExplorerBindingMap()` and `constructExplorerWorkerOpts()` in `packages/miniflare/src/plugins/core/explorer.ts`.\n5. Add or extend resource binding metadata in `packages/miniflare/src/plugins/core/types.ts`.\n6. Implement handlers in `packages/miniflare/src/workers/local-explorer/resources/<product>.ts`. Make sure to account for cross-instance aggregation, if applicable.\n7. Register Hono routes in `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`.\n8. Validate request bodies and query params with generated Zod schemas from `generated/zod.gen.ts` using `validateRequestBody()` and `validateQuery()`.\n9. Return Cloudflare API envelope responses using `wrapResponse()` and `errorResponse()` from `common.ts` unless an existing endpoint for that product uses a different response shape.\n10. Add Miniflare tests in `packages/miniflare/test/plugins/local-explorer/<product>.spec.ts`.\n11. Regenerate the UI API client:\n\n```bash\npnpm --dir packages/local-explorer-ui build\n```\n\n12. Add UI routes/components. Use Kumo components for new UI. See https://github.com/cloudflare/kumo/blob/main/AGENTS.md.\n13. Add Playwright e2e tests under `packages/local-explorer-ui/src/__e2e__/<product>/` for new visible product flows.\n\n## OpenAPI Rules\n\n- Do not edit generated files like `packages/miniflare/src/workers/local-explorer/openapi.local.json` or `packages/miniflare/src/workers/local-explorer/generated/` directly.\n- Prefer upstream Cloudflare API paths when a public API exists.\n- Use `extensions.paths` in `openapi-filter-config.ts` only for local-only APIs or APIs that do not exist in the public Cloudflare API.\n- Add ignores for unsupported params, headers, request body properties, and response fields rather than pretending to support them.\n\n## Backend Patterns\n\n- Local list endpoints such as listing KV namespaces should not implement pagination as this may require cross-instance aggregation. Pagination should be supported when targeting individual resources, such as listing KV keys within a specific namespace.\n- For cross-worker aggregation, use `aggregateListResults()`, `getPeerUrlsIfAggregating()`, and `fetchFromPeer()` from `aggregation.ts`; do not hand-roll peer discovery. Add tests for both local-only behavior and aggregated behavior when the product can span multiple instances.\n- If an API needs direct filesystem access, call through the loopback service (`c.env.MINIFLARE_LOOPBACK`) to a Node.js endpoint. The local explorer API runs inside workerd, so it cannot access the host filesystem directly.\n- If an endpoint needs metadata that is not available on the runtime binding itself, put that metadata in `BindingIdMap` and pass it through `CoreBindings.JSON_LOCAL_EXPLORER_BINDING_MAP`.\n- If a product should appear in `/api/local/workers`, add it to `WorkerResourceBindings` and populate it in `constructExplorerWorkerOpts()`.\n\n## UI Patterns\n\n- The UI API client is generated from `packages/miniflare/src/workers/local-explorer/openapi.local.json` into `packages/local-explorer-ui/src/api/generated/`.\n- Sidebar resources come from `/api/local/workers`; update `LocalExplorerWorkerBindings` usage and `Sidebar.tsx` when the product should appear in navigation.\n- Add route files under `packages/local-explorer-ui/src/routes/`. TanStack Router regenerates `src/routeTree.gen.ts` during UI build/dev.\n- Preserve worker selection by carrying the `worker` search param through product links when following sidebar patterns.\n- Use Kumo for new UI components wherever possible. Do not introduce a parallel component system.\n- Do not use tailwindCSS color tokens, use Kumo color tokens instead.\n",".opencode/skills/local-explorer/assets/local-explorer-diagram.md":"```mermaid\nflowchart TB\n\tClient[\"client\"] --> Incoming[\"incoming request\"]\n\tIncoming --> EntryA[\"entry worker\"]\n\tEntryA -->|/cdn-cgi/explorer| ExplorerA[\"explorer worker<br/>(Hono)\"]\n\n\tsubgraph Runtime[\"running Miniflare instances\"]\n\t\tdirection LR\n\n\t\tsubgraph A[\"miniflare A\"]\n\t\t\tdirection TB\n\t\t\tEntryA\n\t\t\tExplorerA\n\t\t\tFrontend[\"frontend<br/>(TanStack Router + React)\"]\n\t\t\tUserWorker[\"user worker\"]\n\t\t\tKV[\"KV, R2, D1\"]\n\t\t\tWrapper[\"wrapped<br/>DO/Workflow class\"]\n\n\t\t\tEntryA --> UserWorker\n\t\t\tExplorerA -->|disk service to serve assets| Frontend\n\t\t\tExplorerA -->|binding| KV\n\t\t\tExplorerA -->|binding| Wrapper\n\t\t\tUserWorker -->|binding| KV\n\t\t\tUserWorker -->|binding| Wrapper\n\t\tend\n\n\t\tsubgraph B[\"miniflare B\"]\n\t\t\tdirection TB\n\t\t\tEntryB[\"entry worker\"]\n\t\t\tExplorerB[\"explorer worker\"]\n\t\t\tEtc[\"etc.\"]\n\n\t\t\tEntryB --> ExplorerB\n\t\t\tExplorerB --> Etc\n\t\tend\n\tend\n\n\tFrontend -->|fetch /cdn-cgi/explorer/api| Incoming\n\tExplorerA -->|fetch /cdn-cgi/explorer/api/resource with NO_AGGREGATE_HEADER| EntryB\n\n\tsubgraph FS[\"filesystem\"]\n\t\tRegistry[\"dev registry\"]\n\t\tDOState[\".wrangler/state/durable-objects<br/>(list DOs, delete workflows, etc.)\"]\n\tend\n\n\tExplorerA -->|node loopback binding| FS\n\n\tclassDef miniflareA stroke:#f08c00,fill:#fff7ed,color:#1e1e1e;\n\tclassDef userResource stroke:#1971c2,fill:#eff6ff,color:#1e1e1e;\n\tclassDef entry stroke:#e03131,fill:#fff5f5,color:#1e1e1e;\n\tclassDef neutral stroke:#1e1e1e,fill:#ffffff,color:#1e1e1e;\n\n\tclass EntryA entry;\n\tclass ExplorerA,Frontend,Wrapper miniflareA;\n\tclass UserWorker,KV userResource;\n\tclass Client,Incoming,Runtime,FS,Registry,DOState,EntryB,ExplorerB,Etc neutral;\n```\n","AGENTS.md":"# AGENTS.md\n\nThis file helps AI coding agents work effectively in the Cloudflare Workers SDK\nmonorepo. Prefer authoritative configuration and documentation over copying\ndetails into this file: copied versions, rule lists, and counts become stale.\n\n## Start Here\n\n- Use `pnpm`, not npm or yarn.\n- Use the Node.js and pnpm versions declared in `package.json`.\n- Install dependencies with `pnpm install`.\n- Run commands from the workspace root unless package documentation says\n  otherwise.\n- Before changing a package, read its `AGENTS.md` if it has one.\n- Do not edit generated files directly. Change their source or generator and\n  regenerate them.\n\n## Common Commands\n\nThe root `package.json` is authoritative for available scripts.\n\n- `pnpm build` — build the workspace with Turbo.\n- `pnpm test:ci` — run tests in CI mode.\n- `pnpm test:e2e` — run end-to-end tests; many require Cloudflare credentials.\n- `pnpm check` — run the repository's validation, lint, type, and format checks.\n- `pnpm fix` — apply supported lint and formatting fixes.\n- `pnpm prettify` — format files with oxfmt.\n- `pnpm run <script> --filter <package>` — run a Turbo task for one package.\n- `pnpm -w test:ci -F <package> -- <test-file>` — run a package's specific test\n  file when its test configuration supports it.\n\nPrefer the narrowest relevant test while developing, then run the broader\npackage checks appropriate to the change. Do not run credentialed E2E tests\nunless the task and environment support them.\n\n## Repository Map\n\n| Task                                        | Location                                                              | Notes                                                         |\n| ------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |\n| Add or modify a Wrangler command            | `packages/wrangler/src/`                                              | Commands are registered from `src/index.ts`.                  |\n| Change local development behavior           | `packages/miniflare/src/`                                             | `src/index.ts` contains the main `Miniflare` class.           |\n| Modify embedded runtime workers             | `packages/miniflare/src/workers/`                                     | Worker scripts use `worker:` virtual imports.                 |\n| Change project scaffolding                  | `packages/create-cloudflare/`                                         | Templates and framework support live here.                    |\n| Change the Vite integration                 | `packages/vite-plugin-cloudflare/`                                    | Includes package-specific playgrounds.                        |\n| Change the Vitest integration               | `packages/vitest-plugin/`                                             | Vitest integration for tests running in workerd.              |\n| Change shared config handling               | `packages/workers-utils/src/config/`                                  | Shared types, normalization, and validation.                  |\n| Use shared test helpers                     | `packages/workers-utils/src/test-helpers/`                            | Includes temporary-directory and console helpers.             |\n| Change deploy or versions-upload validation | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | Keep deploy and versions-upload behavior aligned.             |\n| Add a fixture                               | `fixtures/`                                                           | Fixtures are workspace members with their own `package.json`. |\n| Change CI                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the main test workflow.               |\n| Change deployment tooling                   | `tools/deployments/`                                                  | Scripts run directly through `esbuild-register`.              |\n| Create a changeset                          | `.changeset/README.md`                                                | Read this file before deciding whether one is required.       |\n\nTurbo orchestrates workspace tasks. Shared TypeScript configuration lives in\n`packages/workers-tsconfig/`; lint and formatting behavior is defined by\n`.oxlintrc.jsonc`, `.oxfmtrc.jsonc`, and `packages/lint-config-shared/`.\n\n## Cross-Tool Development Features\n\nWrangler, the Vite plugin, and the Vitest plugin are all consumers of the\nWorkers development platform. A development feature is not complete merely\nbecause it works through one of them.\n\nImplement development features in Miniflare wherever possible so that every\nconsumer benefits from the same behavior. Keep the integration layers in\nWrangler, the Vite plugin, and the Vitest plugin thin instead of implementing\nequivalent behavior independently in each tool. If Miniflare is not the\nappropriate layer, put shared behavior in the lowest suitable shared package.\n\nWhen adding or changing development functionality:\n\n- assess its impact on Miniflare, Wrangler, the Vite plugin, and the Vitest\n  plugin;\n- update shared configuration types, validation, and runtime behavior where\n  applicable;\n- add coverage at the shared implementation layer; add consumer-specific tests\n  when the consumer's integration or behavior is affected;\n- document intentional differences or unsupported consumers in the change and\n  pull request.\n\n## Implementation Conventions\n\nThe checked-in configuration is authoritative. Run `pnpm check` rather than\nrelying on a duplicated list of every enforced rule. In particular:\n\n- Keep TypeScript strictly typed. Avoid `any`, non-null assertions, and floating\n  promises.\n- Use type-only imports where appropriate and `node:` prefixes for Node.js\n  built-ins.\n- Prefer function declarations for named or exported functions.\n- Add well-formatted JSDoc to exported or public functions and to functions whose\n  purpose is not evident, including useful tags such as `@param` and `@returns`\n  where appropriate.\n- Comments should explain why; do not add comments that merely restate code.\n- Lint-disable comments require a reason after `--`.\n- In Wrangler, use the logger rather than calling `console.*` directly, except\n  inside the logger implementation.\n- For Cloudflare v4 API calls, prefer the existing request helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult`. Reuse or inject\n  these helpers in shared packages rather than adding the `cloudflare` package\n  solely for a simple request. Use the Cloudflare TypeScript SDK when its\n  generated API surface or behavior is materially useful.\n- Import `ci-info` through its default export.\n\noxfmt determines whitespace, quoting, import order, and package.json sorting.\nDo not reproduce those rules manually; run `pnpm prettify`.\n\n## Dependencies and Security\n\n- Packages normally bundle their dependencies. The repository validator in\n  `tools/deployments/validate-package-dependencies.ts` is authoritative.\n- A package that must leave a dependency external declares it in that package's\n  `scripts/deps.ts` as part of `EXTERNAL_DEPENDENCIES`, with an explanation.\n- After changing dependencies, run `pnpm install` so that the lockfile is\n  updated.\n- Do not build shell commands with interpolated or concatenated untrusted input.\n  The custom `workers-sdk/no-unsafe-command-execution` oxlint rule enforces the\n  repository's command-execution constraints.\n\n## Testing Conventions\n\n- Use Vitest for unit and integration tests.\n- Use fixtures for filesystem and Worker scenarios; treat fixtures as\n  user-facing examples and keep them clear and realistic.\n- Use the Vitest plugin when behavior must be tested in workerd.\n- In Vitest tests, obtain `expect` from the test context rather than importing\n  it from `vitest`. Pass `ExpectStatic` to helpers that need it; use\n  `node:assert` where test context is unavailable.\n- Prefer `runInTempDir()` and real filesystem operations over filesystem mocks.\n- Use `mockConsoleMethods()` to capture output and assert against its `out`,\n  `err`, and `warn` properties.\n- Update relevant snapshots when changing user-facing output.\n- New examples under `fixtures/vitest-plugin-examples/` need a\n  `tsconfig.json`.\n\nThe shared defaults are defined in `vitest.shared.ts`; package configurations\nmay override them.\n\n## Changes and Pull Requests\n\n- Work on a branch rather than committing directly to `main`.\n- Read `.changeset/README.md` to determine whether a changeset is required and\n  how to write it. Do not assume every package-code change needs one.\n- Use `.github/PULL_REQUEST_TEMPLATE.md` when preparing a pull request.\n- The PR description requirements are enforced by\n  `tools/deployments/validate-pr-description.ts`; treat that validator and the\n  template as authoritative.\n- Use the repository's established `[package] description` PR-title style.\n- Run the relevant tests and checks locally before pushing.\n\n## Package-Specific Guidance\n\nMany packages provide their own `AGENTS.md`. Locate and read the closest\napplicable file before making changes. When a change makes guidance inaccurate,\nupdate that file in the same change. Put package-specific knowledge in the\npackage's file; keep this root file focused on repository-wide workflow and\nnavigation.\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","packages/build-output-utils/README.md":"# `@cloudflare/build-output-utils`\n\nUtilities for reading and writing the Build Output Specification directory (`.cloudflare/output/`).\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/chrome-devtools-patches/README.md":"# Workers Devtools\n\nThis package contains a Workers specific version of Chrome Devtools that is used by the Wrangler dev command and other applications. It is a customized fork of Chrome DevTools specifically tailored for debugging Cloudflare Workers. This package provides Worker-specific functionality through carefully maintained patches on top of Chrome DevTools.\n\n## Overview\n\nThis package is used across multiple Cloudflare products:\n\n- Workers Playground (`workers-playground`)\n- Quick Editor (`@cloudflare/quick-edit`)\n- Wrangler CLI via the `InspectorProxy`\n\n## Features\n\nOur customized DevTools implementation provides:\n\n- Source code viewing and live updates\n- Network request inspection\n- Worker-specific UI optimizations\n\n## Development\n\nWe maintain this fork by applying patches on top of Chrome DevTools. These patches need to be periodically rebased as Chrome DevTools evolves.\n\n**Key Development Tasks:**\n\n- Generating patches from our customizations\n- Rebasing patches onto new Chrome DevTools versions\n- Testing functionality across all integration points\n\n## Updating DevTools\n\nWe perform quarterly updates to stay current with upstream Chrome DevTools. The update process involves:\n\n1. Cloning the devtools-frontend repo\n2. Applying our existing patches\n3. Rebasing onto the latest Chrome DevTools\n4. Regenerating patches\n5. Thorough testing across all integration points\n\n**For detailed instructions on updating DevTools, please refer to our internal documentation on keeping devtools up-to-date.**\n\n## Testing\n\nTwo methods are available for testing updates:\n\n**Local Development:**\n\n- Build and serve DevTools locally\n- Test against local Playground instance\n- Make targeted fixes as needed\n\n**Preview Builds:**\n\nOn any pull request to the repo on GitHub, you can add the `preview:chrome-devtools-patches` label to trigger a preview build of the DevTools frontend. This is useful because it will allow you to manually test your changes in a live environment, and with one-click.\n\nOnce the preview is built, you will see a comment on the PR with a link to the live URL.\n\n## Acceptance Criteria\n\nOur DevTools implementation must maintain full functionality across:\n\n- Console operations (logging, errors, filters)\n- Source code viewing and debugging\n- Network request inspection\n- Worker-specific UI customizations\n\n## Contributing\n\nWhen making changes:\n\n- Keep patches minimal and targeted\n- Prefer CSS-based UI modifications\n- Test thoroughly across all integration points\n- Document any new patches or modifications\n\n## Deployment\n\nThis package is deployed as a Cloudflare Workers + Assets project. The static DevTools frontend is served directly from Workers Assets, configured via `wrangler.jsonc`.\n\nDeployments are managed by GitHub Actions:\n\n- deploy-previews.yml:\n  - Runs on any PR that has the `preview:chrome-devtools-patches` label.\n  - Uploads a preview version (without activating it in production) via `wrangler versions upload`.\n  - The preview URL is posted as a comment on the PR.\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production via `wrangler deploy`.\n  - Production is accessible via the custom domain [https://devtools.devprod.cloudflare.dev/].\n","packages/cli/README.md":"# Cloudflare CLI\n\n> Internal utility package for workers-sdk. Not intended for external use — APIs may change without notice.\n\nAll things related to rendering the CLI for workers-sdk.\n","packages/codemods/README.md":"# `@cloudflare/codemods`\n\nCodemods for upgrading Cloudflare developer projects.\n\nRun a codemod by name:\n\n```sh\nnpx @cloudflare/codemods vitest:v3-to-v4\n```\n\nAvailable codemods:\n\n- `wrangler-to-cf` - migrate a Wrangler configuration to the new `cf`\n  configuration format\n- `vitest:v3-to-v4` — migrate `@cloudflare/vitest-pool-workers` configuration from\n  Vitest v3 to v4\n- `vitest:pool-workers-to-vitest-plugin` — rename `@cloudflare/vitest-pool-workers`\n  to `@cloudflare/vitest-plugin` v1\n\nUse `--dry-run` to list changes without writing them, `--cwd <path>` to target\nanother project, or repeat `--files <glob>` to restrict the files considered.\nWhen the target is inside a Git worktree, the worktree must be clean. Use\n`--force` to bypass this safety check.\n\nTo migrate a Wrangler project with the default Vite bundler:\n\n```sh\nnpx @cloudflare/codemods wrangler-to-cf --cwd ./path/to/project\n```\n\nThe CLI detects a single root `wrangler.json`, `wrangler.jsonc`, or `wrangler.toml`. Pass `--config <path>` to select another file, or pass `--bundler wrangler` to retain Wrangler-specific tooling configuration. For this codemod, `--files` filters the selected Wrangler config and skips the migration when it does not match.\n\n## Programmatic usage\n\nCodemods can also be run from JavaScript or TypeScript:\n\n```ts\nimport { runCodemod } from \"@cloudflare/codemods\";\n\nconst { changedFiles } = await runCodemod(\"vitest:v3-to-v4\", {\n\tcwd: process.cwd(),\n\tdryRun: false,\n});\n```\n\n`runCodemod` accepts the same codemod names and aliases as the CLI. Its context also accepts optional `files` and `force` fields corresponding to the CLI flags, and setting `dryRun` lists changed files without writing them. It returns a `CodemodResult` containing `changedFiles` and rejects if the codemod cannot be run. The CLI's clean-worktree check also applies to programmatic runs.\n\n### Migrate Wrangler config to cf\n\nPass the exact Wrangler config file to `migrateWranglerToCf`:\n\n```ts\nimport { migrateWranglerToCf } from \"@cloudflare/codemods\";\n\nconst result = await migrateWranglerToCf(\"./wrangler.jsonc\", {\n\tbundler: \"vite\",\n});\n```\n\nThe options object and all of its fields are optional. The defaults are the Vite bundler, writes enabled, dirty-worktree protection enabled, and automatic dependency installation enabled. The migration installs `cf` when missing, installs `@cloudflare/vite-plugin@beta` when Vite is selected and the plugin is missing or incompatible, and upgrades Wrangler when generated Wrangler tooling requires a newer version. The Vite plugin dependency remains set to the `beta` dist tag in `package.json`; package manager installation updates the project's lockfile. Project-managed Vite plugin specifiers such as `workspace:` and `catalog:` are preserved; incompatible or unverified versions require a manual update. Set `installDependencies` to `false` to prevent dependency changes; required dependencies are then returned as blocking follow-ups. The migration always creates `cloudflare.config.ts`; selecting the Wrangler bundler also creates `wrangler.config.ts` when Wrangler-specific tooling config exists. Existing target files are never overwritten. Inspect `result.followUps` when `result.status` is `needs-intervention`.\n","packages/config/README.md":"# `@cloudflare/config`\n\nDefinitions and utilities for configuring Cloudflare Workers and related products.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/containers-shared/README.md":"# @cloudflare/containers-shared\n\nInternal shared container functionality for Cloudflare Workers SDK.\n\n## Internal Use Only\n\nThis package is published only for internal use.\n\nDo not depend on this package directly from external projects. It is not a\npublic SDK, it does not provide a stable API surface, and any function, type,\nexport, behavior, or file path contained in this package may change or be\nremoved at any time without notice.\n\nNo semver compatibility is promised for consumers outside Cloudflare's own\nWorkers SDK packages.\n\n- Cloudchamber/Containers API client\n- Utils for constructing and running docker commands\n- SSH transport shared by Wrangler and cf (OpenSSH and stdio proxy modes)\n- Managed registry image list/delete operations shared by Wrangler and cf\n","packages/create-cloudflare/AGENTS.md":"# AGENTS.md — Create Cloudflare (C3)\n\n## OVERVIEW\n\nProject scaffolding CLI for Cloudflare Workers. Main source entry: `src/cli.ts`. Bin entry: `bin/c3.js` (Node.js version gate shim).\n\n## STRUCTURE\n\n- `bin/c3.js` — Bin shim that checks Node.js version before requiring `dist/cli.js`\n- `src/cli.ts` — Main entry. Exports `main(argv)` for programmatic use\n- `templates/` — Scaffolding templates (excluded from linting and most formatting)\n- `src/wrangler/` — Wrangler config, login, and account helpers\n- `src/cf/` — Helpers for projects configured by `cloudflare.config.ts`, which use the `cf` CLI instead of Wrangler (detected with `usesCfCli`)\n- `scripts/build.ts` — esbuild-based build → `dist/cli.js`\n\n## BUILD\n\n- esbuild bundles `src/cli.ts` as CJS → `dist/cli.js`\n- `package.json` `main` and `exports[\".\"]` point at `dist/cli.js`; `bin` points at `bin/c3.js`\n- `bin/c3.js` is a plain CommonJS shim that gates on Node.js version (read from `package.json` `engines.node`) before requiring `dist/cli.js`\n\n## CONVENTIONS\n\n- `no-console: error` — use project's logging utilities\n- Templates excluded from linting (except `c3.ts` files within templates)\n- Templates excluded from formatting (except hello-world templates)\n\n## TESTING\n\n- E2E tests run across pnpm/npm (yarn/bun also supported but not in CI), Linux/Windows\n- Own vitest setup: mocks `log-update` and `@cloudflare/cli-shared-helpers/streams`\n- CI has experimental matrix for framework testing\n- Framework CI uses case shards within one test file (three normal, two experimental), controlled by `E2E_FRAMEWORK_SHARD`. Preserve coverage across every shard and keep shard selections in the test's Turbo cache inputs.\n- Whole-framework tests retain one retry for transient failures in external registries, generators, and runtime startup. Per-case allowances live in `e2e/tests/frameworks/test-config.ts`; `E2E_TEST_RETRIES=0` disables retries for local investigations. Keep recovered attempts visible in retry reports and fix their causes before reducing allowances.\n- Python/UV installed in CI for Python framework E2E tests\n","packages/create-cloudflare/README.md":"# create-cloudflare\n\nA CLI for creating and deploying new applications to [Cloudflare](https://developers.cloudflare.com/).\n\nFor more details on how to use the create-cloudflare CLI (C3) please visit the [official C3 documentation](https://developers.cloudflare.com/pages/get-started/c3).\n\n### Community\n\n- Join us [on Discord](https://discord.cloudflare.com)\n- File an issue [on GitHub](https://github.com/cloudflare/workers-sdk/issues/new/choose)\n","packages/create-cloudflare/e2e/README.md":"# C3 E2E tests\n\nThis directory contains the e2e tests and helpers for C3.\n\n## Running tests locally\n\nThere are three groups of tests:\n\n- CLI - general tests against the C3 CLI tool, such as interactive prompts\n- Workers - tests of the non-framework C3 templates such as `hello-world-durable-object-with-assets-ts`.\n- Frameworks - tests of the framework C3 templates, such as `astro:workers`, `qwik:pages`, etc.\n\n- To run all the tests locally you can do run the following from the root of the monorepo:\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare\n  ```\n\n  This command will actually run the `test:e2e` turbo task in the `create-cloudflare` package, which will also ensure that any dependencies have been built correctly first.\n\n- To run just one group of tests (pass the group name to underlying command):\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare -- workers\n  ```\n\n  You can choose from `cli`, `workers` or `frameworks`.\n\nThe tests that run can be controlled by combining any of the following environment variables:\n\n- `E2E_EXPERIMENTAL` - whether to run the tests in experimental mode - without this variable only non-experimental tests are run.\n- `E2E_TEST_PM` + `E2E_TEST_PM_VERSION` - which package manager to simulate in the tests - without these variables the tests simulate `pnpm`.\n- `E2E_RUN_DEPLOY_TESTS` - whether to ask C3 to deploy generated projects and run tests against the deployed version - if this is not set to `\"true\"`, generated projects are only tested locally.\n- `CLOUDFLARE_API_TOKEN` - the API token to use in tests that connect to Cloudflare - without this variable tests that require Cloudflare access are skipped.\n- `E2E_FRAMEWORK_SHARD` - optional framework case shard in the form `index/count`, with a one-based index. Invalid values fail the run. Without it, all matching cases are collected, including skipped cases.\n- `E2E_TEST_RETRIES` - optional non-negative integer override for framework whole-test retries. Framework tests retain one whole-test retry because they exercise external registries, generators, and runtime startup. Cases can override this allowance in `test-config.ts`. Set this to `0` when investigating a failure or measuring first-attempt reliability. Readiness polling within each attempt is unchanged.\n\n### Running a framework shard\n\nAll framework cases live in one file, so Vitest's file sharding cannot divide this suite. CI runs three case shards per normal package-manager entry and two shards for experimental pnpm. Each runner retains Vitest's default limit of five concurrent tests.\n\nTo reproduce a shard locally, run:\n\n```bash\nE2E_FRAMEWORK_SHARD=1/3 pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nCases are sorted by their full names and distributed round-robin after applying the framework filter and excluding quarantined or unsupported cases. New frameworks and variants are assigned automatically. Use the same package manager, package-manager version, experimental mode, filter, and shard count as CI to reproduce its selection.\n\nThe existing required framework checks wait for every framework shard. Failed, cancelled, or skipped shard jobs fail these checks; deliberately skipped test steps still succeed when framework coverage is not requested.\n\nCI publishes per-attempt logs, Vitest's `results.json`, Turbo summaries, and a retry report. The reported Vitest test duration includes waiting for a concurrency slot, hooks, and all attempts, so use the job/Turbo task duration to measure the critical path. Cached test replays are excluded from retry reports.\n\nTreat a recovered attempt as evidence of a reliability problem, even when CI passes. Keep the single retry while addressing the cause; reduce an allowance only after repeated fresh runs support doing so. A repeatable regression should fail the check, and another attempt should not be used to hide it.\n\nEach attempt shares an absolute package-manager cache across its child processes, outside the generated project. This prevents C3's Git initialization from committing cache contents while isolating concurrent installs. The fixture removes both the project and its cache after the attempt. Wrangler's test configuration uses an automatically assigned inspector port to avoid collisions between concurrent preview sessions.\n\n### Running in experimental mode\n\nC3 can be run in experimental mode, by passing `--experimental` to it as a CLI argument. By default the tests will run in non-experimental mode.\nTo run the tests in experimental mode, simply pass `E2E_EXPERIMENTAL=true` as an environment variable.\n\nFor example, to run the \"cli\" group in experimental mode:\n\n```bash\nE2E_EXPERIMENTAL=true pnpm test:e2e -F create-cloudflare -- cli\n```\n\n> This experimental environment variable can be combined with the package manager environment variables below.\n\n### Running against different package managers\n\nC3 supports running sub-commands and installs using a range of package managers. By default the tests will run agains `pnpm`.\nTo run the tests using a different package manager, simply pass `E2E_TEST_PM` and `E2E_TEST_PM_VERSION` as environment variables.\n\nFor example, to run the \"workers\" group using yarn@1.22.22.\n\n```bash\nE2E_TEST_PM=yarn E2E_TEST_PM_VERSION=1.22.22 pnpm test:e2e -F create-cloudflare -- workers\n```\n\n> These package manager environment variables can be combined with the experimental environment variable above.\n\n### Running Workers templates individually\n\nTo run the e2e tests against a specific Worker template (or group of Worker template variants), provide the `E2E_WORKER_TEMPLATE_TO_TEST` environment variable.\n\nWorker template names and their variants are delimited by colons (`:`).\nIf no colon is specified then all variants will be run for the matching template name.\n\nFor example to only run the python version of the `hello-world-durable-objects` template:\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-durable-object:python pnpm test:e2e -F create-cloudflare -- workers\n```\n\nTo run all the `hello-world-with-assets` variants (`js`, `python`, `ts`):\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-with-assets pnpm test:e2e -F create-cloudflare -- workers\n```\n\n### Running Web frameworks templates individually\n\nTo run the e2e tests against a specific Web framework (or group of Worker template variants), provide the `E2E_FRAMEWORK_TEMPLATE_TO_TEST` environment variable.\n\nFramework templates and their variants (`pages` or `workers`) are delimited by colons (`:`).\nIf no colon is specified in the filter then all variants will be run for the matching template.\n\nFor example to only run the `workers` version of the `react-router` framework:\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=react-router:workers pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nTo run all the `qwik` framework variants (`pages`, `workers`):\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=qwik pnpm test:e2e -F create-cloudflare -- frameworks\n```\n","packages/create-cloudflare/templates/django/py/README.md":"# Django on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/fastapi/py/README.md":"# FastAPI on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/flask/py/README.md":"# Flask on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world-durable-object/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world-with-assets/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/hello-world/py/README.md":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","packages/create-cloudflare/templates/openapi/ts/README.md":"# Cloudflare Workers OpenAPI 3.1\n\nThis is a Cloudflare Worker with OpenAPI 3.1 using [chanfana](https://github.com/cloudflare/chanfana) and [Hono](https://github.com/honojs/hono).\n\nThis is an example project made to be used as a quick start into building OpenAPI compliant Workers that generates the\n`openapi.json` schema automatically from code and validates the incoming request to the defined parameters or request body.\n\n## Get started\n\n1. Sign up for [Cloudflare Workers](https://workers.dev). The free tier is more than enough for most use cases.\n2. Clone this project and install dependencies with `npm install`\n3. Run `wrangler login` to login to your Cloudflare account in wrangler\n4. Run `wrangler deploy` to publish the API to Cloudflare Workers\n\n## Project structure\n\n1. Your main router is defined in `src/index.ts`.\n2. Each endpoint has its own file in `src/endpoints/`.\n3. For more information read the [chanfana documentation](https://chanfana.pages.dev/) and [Hono documentation](https://hono.dev/docs).\n\n## Development\n\n1. Run `wrangler dev` to start a local instance of the API.\n2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints.\n3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface.\n","packages/create-cloudflare/templates/react-router/ts/README.md":"# Welcome to React Router!\n\nA modern, production-ready template for building full-stack React applications using React Router.\n\n## Features\n\n- 🚀 Server-side rendering\n- ⚡️ Hot Module Replacement (HMR)\n- 📦 Asset bundling and optimization\n- 🔄 Data loading and mutations\n- 🔒 TypeScript by default\n- 🎉 TailwindCSS for styling\n- 📖 [React Router docs](https://reactrouter.com/)\n\n## Getting Started\n\n### Installation\n\nInstall the dependencies:\n\n```bash\nnpm install\n```\n\n### Development\n\nStart the development server with HMR:\n\n```bash\nnpm run dev\n```\n\nYour application will be available at `http://localhost:5173`.\n\n## Previewing the Production Build\n\nPreview the production build locally:\n\n```bash\nnpm run preview\n```\n\n## Building for Production\n\nCreate a production build:\n\n```bash\nnpm run build\n```\n\n## Deployment\n\nDeployment is done using the Wrangler CLI.\n\nTo build and deploy directly to production:\n\n```sh\nnpm run deploy\n```\n\nTo deploy a preview URL:\n\n```sh\nnpx wrangler versions upload\n```\n\nYou can then promote a version to production after verification or roll it out progressively.\n\n```sh\nnpx wrangler versions deploy\n```\n\n## Styling\n\nThis template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.\n\n---\n\nBuilt with ❤️ using React Router.\n","packages/format-errors/README.md":"# format-errors\n\nA Worker that will nicely format errors, optionally inflating with source context if available.\n\n<table>\n     <tr><td><img src=\"./images/service-worker.png\"></td><td><img src=\"./images/modules-worker.png\"></td></tr>\n</table>\n\n## Why is this needed?\n\nIn development, it's nice to have good error messages to help when debugging, and ideally the logic for that shouldn't be bundled into your user Worker. This Worker is ~50kb when gzipped, which doesn't add _that_ much, but there's still a benefit to keeping it separate from the user Worker. Additionally, in environments where we're unable to bundle complex Workers, this error formatting Worker allows for the display of useful errors where otherwise only a stack trace would be available.\n\n## How does it work?\n\nFundamentally, this is based on [Youch](https://github.com/poppinss/youch) and [StackTracey](https://github.com/xpl/stacktracey). Neither of these projects are designed to be run in the Workers environment (although StackTracey does have support for running in the browser), and so both have been vendored in and modified. These modifications aren't upstreamable, since they involve things like changing how Youch detects node-internal modules and changing how sources are loaded.\n\n### Youch changes:\n\n- **\"internal\" module detection:** By default, Youch recognises modules with a prefix of `node:` to be internal modules. Instead, `format-error`s recognises modules with a prefix of `.internal` as internal modules.\n- **source loading:** Youch loads sources at error-page generation time, `format-error`s loads sources at error-page viewing time.\n- **cookies:** `format-error`s doesn't handle cookies.\n\n### Stacktracey changes:\n\n- **browser detection:** `format-error`s always reports itself to be running inside a browser, but removes references to browser globals like `window`.\n- **table rendering:** To remove the `as-table` dependency, `format-error` doesn't implement Stacktracey's `asTable` method, which Youch doesn't use.\n\n## How can you get a formatted error page?\n\nThe first thing you'll need is an error. `format-errors` requires input conforming to the `Payload` interface below, and will reject invalid input at runtime:\n\n```ts\nexport interface JsonError {\n\tmessage?: string;\n\tname?: string;\n\tstack?: string;\n\tcause?: JsonError;\n}\nexport interface Payload {\n\turl?: string;\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\terror?: JsonError;\n}\n```\n\nTo call `format-errors` (assuming it's hosted at `https://format-errors.example.com`), send a `POST` request to `https://format-errors.example.com` with a body containing a serialised `Payload` object. `format-errors` will parse your input, pass it to Youch, and generate an HTML page which will be sent back as the response to the `POST` request.\n\nIf you don't need source context, you can stop there! However, if you'd like to get rid of the \"Missing sources\" message, there's a bit more complexity.\n\n> _Why can't I just pass sources to `format-error` in the request body?_\n>\n> Often your sources won't be available at the location where your error is thrown. You may have access to a sourcemap, but your running code probably doesn't have access to your source code in serialised format. As such, this package is geared towards supporting use cases where you have access to your sources at the time of _viewing_ the generated error page (i.e. in-browser editors).\n\nA requirement of passing sources to `format-errors` is that the generated HTML error page needs to be embedded in an iframe. Once you've done that, you can start passing sources from the embedder of the iframe into the generated HTML error page.\n\nAssuming `iframeEl` is a reference to the iframe which embeds the generated error page, here's an example of how you could pass sources to the generated error page:\n\n```ts\nconst encoder = new TextEncoder();\nconst channel = new MessageChannel();\n\niframeEl.addEventListener(\"load\", () => {\n\tiframeEl.contentWindow?.postMessage(\"PORT\", \"*\", [channel.port2]);\n});\n\nchannel.port1.onmessage = (data) => {\n\tif (data.type === \"RequestSources\") {\n\t\tconst message = {\n\t\t\ttype: \"SourcesLoaded\",\n\t\t\tbody: {\n\t\t\t\tfiles: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpath: \"index.js\",\n\t\t\t\t\t\tcontents: encoder.encode(\"console.log('hi')\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinternalLines: 0,\n\t\t\t},\n\t\t};\n\t\tchannel.port1.postMessage(\n\t\t\tmessage,\n\t\t\tmessage.body.files.map((f) => f.contents.buffer)\n\t\t);\n\t}\n};\n```\n\nThe interface is fairly simple. The embedder passes a `MessagePort` to the iframe on load, over which the error page requests sources. Of note: this does not currently support sourcemaps, and it's assumed that the lines within your error stack trace map to the exact line in your source.\n\nThere's one exception to that, to support _very_ limited source transformations, in the `internalLines` property. If you pass a value for `internalLines`, the error page will act as if any error messages from line numbers _below_ `internalLines` are internal, and shouldn't be surfaced to the user. Line numbers in error messages will be remapped so that it appears the user-visible source starts at line `0`, rather than line `internalLines`.\n","packages/kv-asset-handler/README.md":"# @cloudflare/kv-asset-handler\n\n[![npm](https://img.shields.io/npm/v/@cloudflare/kv-asset-handler.svg)](https://www.npmjs.com/package/@cloudflare/kv-asset-handler) &nbsp;\n[![Run npm tests](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml) &nbsp;\n[![Lint Markdown](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml) &nbsp;\n\n`kv-asset-handler` is an open-source library for managing the retrieval of static assets from [Workers KV](https://developers.cloudflare.com/workers/runtime-apis/kv) inside of a [Cloudflare Workers](https://workers.dev) function. `kv-asset-handler` is designed for use with [Workers Sites](https://developers.cloudflare.com/workers/platform/sites), a feature included in [Wrangler](https://github.com/cloudflare/wrangler), our command-line tool for deploying Workers projects.\n\n`kv-asset-handler` runs as part of a Cloudflare Workers function, so it allows you to customize _how_ and _when_ your static assets are loaded, as well as customize how those assets behave before they're sent to the client.\n\nMost users and sites will not need these customizations, and just want to serve their statically built applications. For that simple use-case, you can check out [Cloudflare Pages](https://pages.cloudflare.com), our batteries-included approach to deploying static sites on Cloudflare's edge network. Workers Sites was designed as a precursor to Cloudflare Pages, so check out Pages if you just want to deploy your static site without any special customizations!\n\nFor users who _do_ want to customize their assets, and want to build complex experiences on top of their static assets, `kv-asset-handler` (and the default [Workers Sites template](https://github.com/cloudflare/worker-sites-template), which is provided for use with Wrangler + Workers Sites) allows you to customize caching behavior, headers, and anything else about how your Workers function loads the static assets for your site stored in Workers KV.\n\nThe Cloudflare Workers Discord server is an active place where Workers users get help, share feedback, and collaborate on making our platform better. The `#workers` channel in particular is a great place to chat about `kv-asset-handler`, and building cool experiences for your users using these tools! If you have questions, want to share what you're working on, or give feedback, [join us in Discord and say hello](https://discord.cloudflare.com)!\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [`getAssetFromKV`](#getassetfromkv)\n  - [Example](#example)\n  * [Return](#return)\n  * [Optional Arguments](#optional-arguments)\n    - [`mapRequestToAsset`](#maprequesttoasset)\n    - [Example](#example-1)\n    - [`cacheControl`](#cachecontrol)\n      - [`browserTTL`](#browserttl)\n      - [`edgeTTL`](#edgettl)\n      - [`bypassCache`](#bypasscache)\n    - [`ASSET_NAMESPACE` (required for ES Modules)](#asset_namespace-required-for-es-modules)\n    - [`ASSET_MANIFEST` (required for ES Modules)](#asset_manifest-required-for-es-modules)\n    - [`defaultETag`](#defaultetag-optional)\n\n* [Helper functions](#helper-functions)\n  - [`mapRequestToAsset`](#maprequesttoasset-1)\n  - [`serveSinglePageApp`](#servesinglepageapp)\n* [Cache revalidation and etags](#cache-revalidation-and-etags)\n\n## Installation\n\nAdd this package to your `package.json` by running this in the root of your\nproject's directory:\n\n```\nnpm i @cloudflare/kv-asset-handler\n```\n\n## Usage\n\nThis package was designed to work with [Worker Sites](https://workers.cloudflare.com/sites).\n\n## `getAssetFromKV`\n\ngetAssetFromKV(Evt) => Promise<Response>\n\n`getAssetFromKV` is an async function that takes an `Evt` object (containing a `Request` and a [`waitUntil`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#waituntil)) and returns a `Response` object if the request matches an asset in KV, otherwise it will throw a `KVError`.\n\n#### Example\n\nThis example checks for the existence of a value in KV, and returns it if it's there, and returns a 404 if it is not. It also serves index.html from `/`.\n\n### Return\n\n`getAssetFromKV` returns a `Promise<Response>` with `Response` being the body of the asset requested.\n\nKnown errors to be thrown are:\n\n- MethodNotAllowedError\n- NotFoundError\n- InternalError\n\n#### ES Modules\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\nconst assetManifest = JSON.parse(manifestJSON);\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tif (request.url.includes(\"/docs\")) {\n\t\t\ttry {\n\t\t\t\treturn await getAssetFromKV(\n\t\t\t\t\t{\n\t\t\t\t\t\trequest,\n\t\t\t\t\t\twaitUntil(promise) {\n\t\t\t\t\t\t\treturn ctx.waitUntil(promise);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t\t\t\t\t\tASSET_MANIFEST: assetManifest,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else {\n\t\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t\t}\n\t\t\t}\n\t\t} else return fetch(request);\n\t},\n};\n```\n\n#### Service Worker\n\n```js\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\naddEventListener(\"fetch\", (event) => {\n\tevent.respondWith(handleEvent(event));\n});\n\nasync function handleEvent(event) {\n\tif (event.request.url.includes(\"/docs\")) {\n\t\ttry {\n\t\t\treturn await getAssetFromKV(event);\n\t\t} catch (e) {\n\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t// ...\n\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t// ...\n\t\t\t} else {\n\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t}\n\t\t}\n\t} else return fetch(event.request);\n}\n```\n\n### Optional Arguments\n\nYou can customize the behavior of `getAssetFromKV` by passing the following properties as an object into the second argument.\n\n```\ngetAssetFromKV(event, { mapRequestToAsset: ... })\n```\n\n#### `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nMaps the incoming request to the value that will be looked up in Cloudflare's KV\n\nBy default, mapRequestToAsset is set to the exported function [`mapRequestToAsset`](#maprequesttoasset-1). This works for most static site generators, but you can customize this behavior by passing your own function as `mapRequestToAsset`. The function should take a `Request` object as its only argument, and return a new `Request` object with an updated path to be looked up in the asset manifest/KV.\n\nFor SPA mapping pass in the [`serveSinglePageApp`](#servesinglepageapp) function\n\n#### Example\n\nStrip `/docs` from any incoming request before looking up an asset in Cloudflare's KV.\n\n```js\nimport { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'\n...\nconst customKeyModifier = request => {\n  let url = request.url\n  //custom key mapping optional\n  url = url.replace('/docs', '').replace(/^\\/+/, '')\n  return mapRequestToAsset(new Request(url, request))\n}\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: customKeyModifier })\n```\n\n#### `cacheControl`\n\ntype: object\n\n`cacheControl` allows you to configure options for both the Cloudflare Cache accessed by your Worker, and the browser cache headers sent along with your Workers' responses. The default values are as follows:\n\n```javascript\nlet cacheControl = {\n\tbrowserTTL: null, // do not set cache control ttl on responses\n\tedgeTTL: 2 * 60 * 60 * 24, // 2 days\n\tbypassCache: false, // do not bypass Cloudflare's cache\n};\n```\n\n##### `browserTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response returned from the Worker. By default set to `null` which will not add the header at all.\n\n##### `edgeTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response used as the edge cache key. By default set to 2 days (`2 * 60 * 60 * 24`). When null will not cache on the edge at all.\n\n##### `bypassCache`\n\ntype: boolean\n\nDetermines whether to cache requests on Cloudflare's edge cache. By default set to `false` (recommended for production builds). Useful for development when you need to eliminate the cache's effect on testing.\n\n#### `ASSET_NAMESPACE` (required for ES Modules)\n\ntype: KV Namespace Binding\n\nThe binding name to the KV Namespace populated with key/value entries of files for the Worker to serve. By default, Workers Sites uses a [binding to a Workers KV Namespace](https://developers.cloudflare.com/workers/reference/storage/api/#namespaces) named `__STATIC_CONTENT`.\n\nIt is further assumed that this namespace consists of static assets such as HTML, CSS, JavaScript, or image files, keyed off of a relative path that roughly matches the assumed URL pathname of the incoming request.\n\nIn ES Modules format, this argument is required, and can be gotten from `env`.\n\n##### ES Module\n\n```js\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t}\n);\n```\n\n##### Service Worker\n\n```\nreturn getAssetFromKV(event, { ASSET_NAMESPACE: MY_NAMESPACE })\n```\n\n#### `ASSET_MANIFEST` (required for ES Modules)\n\ntype: text blob (JSON formatted) or object\n\nThe mapping of requested file path to the key stored on Cloudflare.\n\nWorkers Sites with Wrangler bundles up a text blob that maps request paths to content-hashed keys that are generated by Wrangler as a cache-busting measure. If this option/binding is not present, the function will fallback to using the raw pathname to look up your asset in KV. If, for whatever reason, you have rolled your own implementation of this, you can include your own by passing a stringified JSON object where the keys are expected paths, and the values are the expected keys in your KV namespace.\n\nIn ES Modules format, this argument is required, and can be imported.\n\n##### ES Module\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nlet manifest = JSON.parse(manifestJSON);\nmanifest[\"index.html\"] = \"index.special.html\";\n\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_MANIFEST: manifest,\n\t\t// ...\n\t}\n);\n```\n\n##### Service Worker\n\n```\nlet assetManifest = { \"index.html\": \"index.special.html\" }\nreturn getAssetFromKV(event, { ASSET_MANIFEST: assetManifest })\n```\n\n#### `defaultMimeType` (optional)\n\ntype: string\n\nThis is the mime type that will be used for files with unrecognized or missing extensions. The default value is `'text/plain'`.\n\nIf you are serving a static site and would like to use extensionless HTML files instead of index.html files, set this to `'text/html'`.\n\n#### `defaultDocument` (optional)\n\ntype: string\n\nThis is the default document that will be concatenated for requests ends in `'/'` or without a valid mime type like `'/about'` or `'/about.me'`. The default value is `'index.html'`.\n\n#### `defaultETag` (optional)\n\ntype: `'strong' | 'weak'`\n\nThis determines the format of the response [ETag header](https://developer.mozilla.org/docs/Web/HTTP/Headers/ETag). If the resource is in the cache, the ETag will always be weakened before being returned.\nThe default value is `'strong'`.\n\n# Helper functions\n\n## `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nThe default function for mapping incoming requests to keys in Cloudflare's KV.\n\nTakes any path that ends in `/` or evaluates to an HTML file and appends `index.html` or `/index.html` for lookup in your Workers KV namespace.\n\n## `serveSinglePageApp`\n\nserveSinglePageApp(Request) => Request\n\nA custom handler for mapping requests to a single root: `index.html`. The most common use case is single-page applications - frameworks with in-app routing - such as React Router, VueJS, etc. It takes zero arguments.\n\n```js\nimport { getAssetFromKV, serveSinglePageApp } from '@cloudflare/kv-asset-handler'\n...\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: serveSinglePageApp })\n```\n\n# Cache revalidation and etags\n\nAll responses served from cache (including those with `cf-cache-status: MISS`) include an `etag` response header that identifies the version of the resource. The `etag` value is identical to the path key used in the `ASSET_MANIFEST`. It is updated each time an asset changes and looks like this: `etag: <filename>.<hash of file contents>.<extension>` (ex. `etag: index.54321.html`).\n\nResources served with an `etag` allow browsers to use the `if-none-match` request header to make conditional requests for that resource in the future. This has two major benefits:\n\n- When a request's `if-none-match` value matches the `etag` of the resource in Cloudflare cache, Cloudflare will send a `304 Not Modified` response without a body, saving bandwidth.\n- Changes to a file on the server are immediately reflected in the browser - even when the cache control directive `max-age` is unexpired.\n\n#### Disable the `etag`\n\nTo turn `etags` **off**, you must bypass cache:\n\n```js\n/* Turn etags off */\nlet cacheControl = {\n\tbypassCache: true,\n};\n```\n\n#### Syntax and comparison context\n\n`kv-asset-handler` sets and evaluates etags as [strong validators](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#Strong_validation). To preserve `etag` integrity, the format of the value deviates from the [RFC2616 recommendation to enclose the `etag` with quotation marks](https://tools.ietf.org/html/rfc2616#section-3.11). This is intentional. Cloudflare cache applies the `W/` prefix to all `etags` that use quoted-strings -- a process that converts the `etag` to a \"weak validator\" when served to a client.\n","packages/local-explorer-ui/README.md":"# Local explorer UI\n\nThis package contains the UI for the local dev data explorer.\nThe built output will be bundled into Miniflare and served by Miniflare at `/cdn-cgi/explorer`.\n\n# API\n\nThis fetches data from an API running in Miniflare at`/cdn-cgi/explorer/api`.\n\nThe API client is generated from the OpenAPI spec in `packages/miniflare/src/workers/local-explorer/openapi.local.json`.\n\n## API Type Generation\n\nThe API client code is auto-generated from the OpenAPI spec using [`@hey-api/openapi-ts`](https://heyapi.dev/).\n\n**Configuration:** `openapi-ts.config.ts`\n\n**Input:** `packages/miniflare/src/workers/local-explorer/openapi.local.json`\n\n**Output:** `src/api/generated/`\n\nThe generated code includes:\n\n- TypeScript types for all API request/response schemas\n- A type-safe SDK client for making API calls\n\n### When does generation run?\n\n| Command        | Behavior                                               |\n| -------------- | ------------------------------------------------------ |\n| `pnpm install` | Runs `openapi-ts` in `postinstall` to generate types   |\n| `pnpm build`   | Runs `openapi-ts` before building                      |\n| `pnpm dev`     | Watches for spec changes and regenerates automatically |\n| `pnpm dev:ui`  | Same as `dev` - watches for spec changes               |\n\nIn development, the `openapi-ts --watch` process runs concurrently with Vite, automatically regenerating the client when the OpenAPI spec changes.\n\n# Developing\n\n`pnpm run dev` in this directory.\n\nOr to run a specific worker against the UI:\n\n1. Run a worker (`fixtures/worker-with-resources`) using Wrangler or Vite, making sure it is running at `localhost:8787`.\n2. Run this package with `pnpm run dev:ui`, which will spin up a dev server for just the UI using Vite.\n","packages/miniflare/AGENTS.md":"# Miniflare — Agent Guide\n\n## Overview\n\nLocal dev simulator for Cloudflare Workers, powered by workerd runtime. Main class `Miniflare` in `src/index.ts`.\n\n## Structure\n\n- `src/index.ts` — Main `Miniflare` class, server setup, plugin orchestration, all exports\n- `src/workers/` — ~30 embedded worker scripts (D1, KV, R2, caches, etc.), built via `worker:` virtual import scheme\n- `src/workers/d1/entry.worker.ts` — D1-specific HTTP/RPC entrypoint; selects a database using binding props and adapts RPC queries to the database worker's HTTP protocol\n- `src/workers/d1/database.worker.ts` — local D1 SQLite execution, transactions, metadata, and export; protocol schemas shared with the entrypoint live in `src/workers/d1/schemas.ts`\n- `src/workers/d1/export.ts` — shared local export pragma recognition and dedicated RPC export adaptation; keeps the legacy export response separate from ordinary query contracts\n- `src/workers/shared/` — Shared utilities across embedded workers\n- `src/workers/core/dev-registry-proxy.worker.ts` — Proxy worker for cross-process service bindings via debug port RPC\n- `src/workers/core/dev-registry-proxy-shared.worker.ts` — Shared proxy logic (registry Map, DO proxy class, tail serializers)\n- `src/shared/dev-registry.ts` — Filesystem-based worker registry (chokidar watch, heartbeat, stale cleanup)\n- `src/shared/persist-root-lock.ts` — Token-safe startup serialisation for shared persistent storage\n- `src/shared/DEV_REGISTRY.md` — Full architecture doc for the dev registry\n- `src/runtime/config/generated/workerd.ts` — Generated workerd Cap'n Proto config types\n- `test/` — Tests (`.spec.ts` naming, NOT `.test.ts`)\n- `test/test-shared/` — Shared test utilities\n- `scripts/build.mjs` — Custom esbuild build script\n\n## Build\n\n- Custom `scripts/build.mjs` bundles `src/index.ts` as CJS → `dist/src/index.js`\n- Also compiles ~30 embedded worker scripts via `worker:...` virtual import scheme — each triggers a nested esbuild sub-build producing standalone ESM worker scripts\n- Build outputs: `dist/`, `worker-metafiles/`\n- Release builds set `SOURCEMAPS=false` to omit package source maps; ordinary builds keep them for debugging. Non-watch builds clean `dist/` before compiling so maps from an earlier build cannot leak into a release. This does not disable user Worker source maps.\n\n## Lint Status (Transitional)\n\n- Many shared ESLint rules temporarily DISABLED: `no-explicit-any`, `consistent-type-imports`, `no-shadow`, `no-floating-promises`, others\n- Comment in config: \"temporarily enabled while we transition Miniflare to use the standard workers-sdk eslint config\"\n- `no-console: error` is on, except for `src/workers/` and `scripts/`\n\n## TypeScript\n\n- Does NOT extend shared `@cloudflare/workers-tsconfig` — has its own full config\n- Uses `experimentalDecorators`\n- Path aliases: `miniflare:shared`, `miniflare:zod`\n- `declaration: true` (emits .d.ts)\n\n## Testing\n\n- Test files use `.spec.ts` (NOT `.test.ts`)\n- `pool: \"forks\"`, `maxWorkers: 1` (limits test files to one worker)\n- Does NOT extend `vitest.shared.ts` — own full vitest config\n- Timeouts: 30s test, 30s hook\n- `globals: true`\n- Factory pattern: `miniflareTest(opts, handler?)` creates instance in `beforeAll`, disposes in `afterAll`\n- `useDispose(mf)` / `disposeWithRetry()` — exponential backoff for Windows EPERM file locking\n- `useServer()` — temp HTTP server with auto-cleanup\n- `TestLog` — captures log entries by level\n\n## Generated Files\n\n- `src/runtime/config/generated/workerd.ts` — generated Cap'n Proto types, do not edit directly\n- `src/workers/local-explorer/openapi.local.json` — generated from `scripts/openapi-filter-config.ts`, modify the config not the output\n\n## Version Pinning\n\n- Miniflare minor version must match workerd minor version\n- `tools/deployments/changeset-version.ts` enforces this: if changeset bumps miniflare minor beyond workerd's, it converts to patch\n","packages/miniflare/README.md":"# 🔥 Miniflare\n\n**Miniflare** is a simulator for developing and testing\n[**Cloudflare Workers**](https://workers.cloudflare.com/), powered by\n[`workerd`](https://github.com/cloudflare/workerd).\n\n> :warning: Miniflare is a lower level API designed for tools creators, for\n> locally developing Workers use tools built on top of Miniflare such\n> as [Wrangler](../wrangler/README.md) or the [Cloudflare Vite plugin](../vite-plugin-cloudflare/README.md).\n\n## Quick Start\n\n```shell\n$ npm install miniflare --save-dev\n```\n\n```js\nimport { Miniflare } from \"miniflare\";\n\n// Create a new Miniflare instance, starting a workerd server\nconst mf = new Miniflare({\n\tscript: `addEventListener(\"fetch\", (event) => {\n    event.respondWith(new Response(\"Hello Miniflare!\"));\n  })`,\n});\n\n// Send a request to the workerd server, the host is ignored\nconst response = await mf.dispatchFetch(\"http://localhost:8787/\");\nconsole.log(await response.text()); // Hello Miniflare!\n\n// Cleanup Miniflare, shutting down the workerd server\nawait mf.dispose();\n```\n\n## API\n\n### `type Awaitable<T>`\n\n`T | Promise<T>`\n\nRepresents a value that can be `await`ed. Used in callback types to allow\n`Promise`s to be returned if necessary.\n\n### `type Json`\n\n`string | number | boolean | null | Record<string, Json> | Json[]`\n\nRepresents a JSON-serialisable value.\n\n### `type ModuleRuleType`\n\n`\"ESModule\" | \"CommonJS\" | \"Text\" | \"Data\" | \"CompiledWasm\"`\n\nRepresents how a module's contents should be interpreted.\n\n- `\"ESModule\"`: interpret as\n  [ECMAScript module](https://tc39.es/ecma262/#sec-modules)\n- `\"CommonJS\"`: interpret as\n  [CommonJS module](https://nodejs.org/api/modules.html#modules-commonjs-modules)\n- `\"Text\"`: interpret as UTF8-encoded data, expose in runtime with\n  `string`-typed `default` export\n- `\"Data\"`: interpret as arbitrary binary data, expose in runtime with\n  `ArrayBuffer`-typed `default` export\n- `\"CompiledWasm\"`: interpret as binary WebAssembly module data, expose in\n  runtime with `WebAssembly.Module`-typed `default` export\n\n### `interface ModuleDefinition`\n\nRepresents a manually defined module.\n\n- `type: ModuleRuleType`\n\n  How this module's contents should be interpreted.\n\n- `path: string`\n\n  Path of this module. The module's \"name\" will be obtained by converting this\n  to a relative path. The original path will be used to read `contents` if it's\n  omitted.\n\n- `contents?: string | Uint8Array`\n\n  Contents override for this module. Binary data should be passed as\n  `Uint8Array`s. If omitted, will be read from `path`.\n\n### `interface ModuleRule`\n\nRepresents a rule for identifying the `ModuleRuleType` of automatically located\nmodules.\n\n- `type: ModuleRuleType`\n\n  How to interpret modules that match the `include` patterns.\n\n- `include: string[]`\n\n  Glob patterns to match located module paths against (e.g. `[\"**/*.txt\"]`).\n\n- `fallthrough?: boolean`\n\n  If `true`, ignore any further rules of this `type`. This is useful for\n  disabling the built-in `ESModule` and `CommonJS` rules that match `*.mjs` and\n  `*.js`/`*.cjs` files respectively.\n\n### `enum LogLevel`\n\n`NONE, ERROR, WARN, INFO, DEBUG, VERBOSE`\n\nControls which messages Miniflare logs. All messages at or below the selected\nlevel will be logged.\n\n### `interface LogOptions`\n\n- `prefix?: string`\n\n  String to add before the level prefix when logging messages. Defaults to `mf`.\n\n- `suffix?: string`\n\n  String to add after the level prefix when logging messages.\n\n### `class Log`\n\n- `constructor(level?: LogLevel, opts?: LogOptions)`\n\n  Creates a new logger that logs all messages at or below the specified level to\n  the `console`.\n\n- `error(message: Error)`\n\n  Logs a message at the `ERROR` level. If the constructed log `level` is less\n  than `ERROR`, `throw`s the `message` instead.\n\n- `warn(message: string)`\n\n  Logs a message at the `WARN` level.\n\n- `info(message: string)`\n\n  Logs a message at the `INFO` level.\n\n- `debug(message: string)`\n\n  Logs a message at the `DEBUG` level.\n\n- `verbose(message: string)`\n\n  Logs a message at the `VERBOSE` level.\n\n### `class NoOpLog extends Log`\n\n- `constructor()`\n\n  Creates a new logger that logs nothing to the `console`, and always `throw`s\n  `message`s logged at the `ERROR` level.\n\n### `interface QueueProducerOptions`\n\n- `queueName: string`\n\n  The name of the queue where messages will be sent by the producer.\n\n- `deliveryDelay?: number`\n\n  Default number of seconds to delay the delivery of messages to consumers.\n  Value between `0` (no delay) and `42300` (12 hours).\n\n### `interface QueueConsumerOptions`\n\n- `maxBatchSize?: number`\n\n  Maximum number of messages allowed in each batch. Defaults to `5`.\n\n- `maxBatchTimeout?: number`\n\n  Maximum number of seconds to wait for a full batch. If a message is sent, and\n  this timeout elapses, a partial batch will be dispatched. Defaults to `1`.\n\n- `maxRetries?: number`\n\n  Maximum number of times to retry dispatching a message, if handling it throws,\n  or it is explicitly retried. Defaults to `2`.\n\n- `deadLetterQueue?: string`\n\n  Name of another Queue to send a message on if it fails processing after\n  `maxRetries`. If this isn't specified, failed messages will be discarded.\n\n- `retryDelay?: number`\n\n  Number of seconds to delay the (re-)delivery of messages by default. Value\n  between `0` (no delay) and `42300` (12 hours).\n\n### `interface WorkerOptions`\n\nOptions for an individual Worker/\"nanoservice\". All bindings are accessible on\nthe global scope in service-worker format Workers, or via the 2nd `env`\nparameter in module format Workers.\n\n### `interface WorkflowOptions`\n\n- `name: string`\n\n  The name of the Workflow.\n\n- `className: string`\n\n  The name of the class exported from the Worker that implements the `WorkflowEntrypoint`.\n\n- `scriptName?`: string\n\n  The name of the script that includes the `WorkflowEntrypoint`. This is optional because it defaults to the current script if not set.\n\n#### Core\n\n- `name?: string`\n\n  Unique name for this worker. Only required if multiple `workers` are\n  specified.\n\n- `unsafeRegisterWorker?: boolean`\n\n  Whether to advertise this Worker in the dev registry configured by\n  `unsafeDevRegistryPath`. Defaults to `true`.\n\n- `rootPath?: string`\n\n  Path against which all other path options for this Worker are resolved\n  relative to. This path is itself resolved relative to the `rootPath` from\n  `SharedOptions` if multiple workers are specified. Defaults to the current\n  working directory.\n\n- `script?: string`\n\n  JavaScript code for this worker. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set. If it does have\n  imports, `scriptPath` must also be set so Miniflare knows where to resolve\n  them relative to.\n\n- `scriptPath?: string`\n\n  Path of JavaScript entrypoint. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set.\n\n- `modules?: boolean | ModuleDefinition[]`\n  - If `true`, Miniflare will treat `script`/`scriptPath` as an ES Module and\n    automatically locate transitive module dependencies according to\n    `modulesRules`. Note that automatic location is not perfect: if the\n    specifier to a dynamic `import()` or `require()` is not a string literal, an\n    exception will be thrown.\n\n  - If set to an array, modules can be defined manually. Transitive dependencies\n    must also be defined. Note the first module must be the entrypoint and have\n    type `\"ESModule\"`.\n\n- `modulesRoot?: string`\n\n  If `modules` is set to `true` or an array, modules' \"name\"s will be their\n  `path`s relative to this value. This ensures file paths in stack traces are\n  correct.\n\n<!-- prettier-ignore-start -->\n<!-- (for disabling `;` insertion in `js` code block) -->\n\n- `modulesRules?: ModuleRule[]`\n\n  Rules for identifying the `ModuleRuleType` of automatically located modules\n  when `modules: true` is set. Note the following default rules are always\n  included at the end:\n\n  ```js\n  [\n    { type: \"ESModule\", include: [\"**/*.mjs\"] },\n    { type: \"CommonJS\", include: [\"**/*.js\", \"**/*.cjs\"] },\n  ]\n  ```\n\n  > If `script` and `scriptPath` are set, and `modules` is set to an array,\n  > `modules` takes priority for a Worker's code, followed by `script`, then\n  > `scriptPath`.\n\n<!-- prettier-ignore-end -->\n\n- `compatibilityDate?: string`\n\n  [Compatibility date](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker. Defaults to a date far in the past.\n\n- `compatibilityFlags?: string[]`\n\n  [Compatibility flags](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker.\n\n- `bindings?: Record<string, Json>`\n\n  Record mapping binding name to arbitrary JSON-serialisable values to inject as\n  bindings into this Worker.\n\n- `wasmBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing binary WebAssembly module data\n  to inject as `WebAssembly.Module` bindings into this Worker.\n\n- `textBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing UTF8-encoded data to inject as\n  `string` bindings into this Worker.\n\n- `dataBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing arbitrary binary data to\n  inject as `ArrayBuffer` bindings into this Worker.\n\n- `serviceBindings?: Record<string, string | typeof kCurrentWorker | { name: string | typeof kCurrentWorker, entrypoint?: string } | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>>`\n\n  Record mapping binding name to service designators to inject as\n  `{ fetch: typeof fetch }`\n  [service bindings](https://developers.cloudflare.com/workers/platform/bindings/about-service-bindings/)\n  into this Worker.\n  - If the designator is a `string`, requests will be dispatched to the Worker\n    with that `name`.\n  - If the designator is `(await import(\"miniflare\")).kCurrentWorker`, requests\n    will be dispatched to the Worker defining the binding.\n  - If the designator is an object of the form `{ name: ..., entrypoint: ... }`,\n    requests will be dispatched to the entrypoint named `entrypoint` in the\n    Worker named `name`. The `entrypoint` defaults to `default`, meaning\n    `{ name: \"a\" }` is the same as `\"a\"`. If `name` is\n    `(await import(\"miniflare\")).kCurrentWorker`, requests will be dispatched to\n    the Worker defining the binding.\n  - If the designator is an object of the form `{ network: { ... } }`, where\n    `network` is a\n    [`workerd` `Network` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L555-L598),\n    requests will be dispatched according to the `fetch`ed URL.\n  - If the designator is an object of the form `{ external: { ... } }` where\n    `external` is a\n    [`workerd` `ExternalServer` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L504-L553),\n    requests will be dispatched to the specified remote server.\n  - If the designator is an object of the form `{ disk: { ... } }` where `disk`\n    is a\n    [`workerd` `DiskDirectory` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L600-L643),\n    requests will be dispatched to an HTTP service backed by an on-disk\n    directory.\n  - If the designator is an object of the form `{ node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> }`, requests will be dispatched to your custom Node handler. This allows you to access data and functions defined in Node.js from your Worker using Node.js `req` and `res` objects. Note, `miniflare` will be the `Miniflare` instance dispatching the request.\n  - If the designator is a function with the signature `(request: Request, miniflare: Miniflare) => Response`, requests will be dispatched to your custom\n    fetch handler. This allows you to access data and functions defined in Node.js\n    from your Worker using fetch `Request` and `Response` objects. Note, `miniflare` will be the `Miniflare` instance\n    dispatching the request.\n\n- `outboundService?: string | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>`\n\n  Dispatch this Worker's global `fetch()` and `connect()` requests to the\n  configured service. Service designators follow the same rules above for\n  `serviceBindings`.\n\n- `routes?: string[]`\n\n  Array of route patterns for this Worker. These follow the same\n  [routing rules](https://developers.cloudflare.com/workers/platform/triggers/routes/#matching-behavior)\n  as deployed Workers. If no routes match, Miniflare will fallback to the Worker\n  defined first.\n\n#### Cache\n\n- `cacheAPI?: boolean`\n\n  If `false`, default and named caches will be disabled. The Cache API will\n  still be available, it just won't cache anything.\n\n#### Durable Objects\n\n- `durableObjects?: Record<string, string | { className: string, scriptName?: string, useSQLite?: boolean }>`\n\n  Record mapping binding name to Durable Object class designators to inject as\n  `DurableObjectNamespace` bindings into this Worker.\n  - If the designator is a `string`, it should be the name of a `class` exported\n    by this Worker.\n  - If the designator is an object, and `scriptName` is `undefined`, `className`\n    should be the name of a `class` exported by this Worker.\n  - Otherwise, `className` should be the name of a `class` exported by the\n    Worker with a `name` of `scriptName`.\n  - To use the Durable Object SQLite API you must pass `useSQLite: true`.\n\n#### KV\n\n- `kvNamespaces?: Record<string, string> | string[]`\n\n  Record mapping binding name to KV namespace IDs to inject as `KVNamespace`\n  bindings into this Worker. Different Workers may bind to the same namespace ID\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and KV namespace ID are assumed to be the same.\n\n- `sitePath?: string`\n\n  Path to serve Workers Sites files from. If set, `__STATIC_CONTENT` and\n  `__STATIC_CONTENT_MANIFEST` bindings will be injected into this Worker. In\n  modules mode, `__STATIC_CONTENT_MANIFEST` will also be exposed as a module\n  with a `string`-typed `default` export, containing the JSON-stringified\n  manifest. Note Workers Sites files are never cached in Miniflare.\n\n- `siteInclude?: string[]`\n\n  If set, only files with paths matching these glob patterns will be served.\n\n- `siteExclude?: string[]`\n\n  If set, only files with paths _not_ matching these glob patterns will be\n  served.\n  - `assetsPath?: string`\n\n  Path to serve Workers assets from.\n  - `assetsKVBindingName?: string`\n    Name of the binding to the KV namespace that the assets are in. If `assetsPath` is set, this binding will be injected into this Worker.\n\n  - `assetsManifestBindingName?: string`\n    Name of the binding to an `ArrayBuffer` containing the binary-encoded assets manifest. If `assetsPath` is set, this binding will be injected into this Worker.\n\n#### R2\n\n- `r2Buckets?: Record<string, string> | string[]`\n\n  Record mapping binding name to R2 bucket names to inject as `R2Bucket`\n  bindings into this Worker. Different Workers may bind to the same bucket name\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and bucket name are assumed to be the same.\n\n#### D1\n\n- `d1Databases?: Record<string, string> | string[]`\n\n  Record mapping binding name to D1 database IDs to inject as `D1Database`\n  bindings into this Worker. Note binding names starting with `__D1_BETA__` are\n  injected as `Fetcher` bindings instead, and must be wrapped with a facade to\n  provide the expected `D1Database` API. Different Workers may bind to the same\n  database ID with different binding names. If a `string[]` of binding names is\n  specified, the binding name and database ID are assumed to be the same.\n\n#### Queues\n\n- `queueProducers?: Record<string, QueueProducerOptions> | string[]`\n\n  Record mapping binding name to queue options to inject as `WorkerQueue` bindings\n  into this Worker. Different Workers may bind to the same queue name with\n  different binding names. If a `string[]` of binding names is specified, the\n  binding name and queue name (part of the queue options) are assumed to be the same.\n\n- `queueConsumers?: Record<string, QueueConsumerOptions> | string[]`\n\n  Record mapping queue name to consumer options. Messages enqueued on the\n  corresponding queues will be dispatched to this Worker. Note each queue can\n  have at most one consumer. If a `string[]` of queue names is specified,\n  default consumer options will be used.\n\n#### Assets\n\n- `directory?: string`\n  Path to serve Workers static asset files from.\n\n- `binding?: string`\n  Binding name to inject as a `Fetcher` binding to allow access to static assets from within the Worker.\n\n- `assetConfig?: { html_handling?: HTMLHandlingOptions, not_found_handling?: NotFoundHandlingOptions, base_path?: string }`\n  Configuration for file-based asset routing - see [docs](https://developers.cloudflare.com/workers/static-assets/routing/#routing-configuration) for options\n\n#### Pipelines\n\n- `pipelines?: Record<string, PipelineOptions> | string[]`\n\n  Record mapping binding name to a Pipeline. Different workers may bind to the same Pipeline with different bindings\n  names. If a `string[]` of pipeline names, the binding and Pipeline name are assumed to be the same.\n\n#### Workflows\n\n- `workflows?: WorkflowOptions[]`\n  Configuration for one or more Workflows in your project.\n\n#### Browser Run\n\n- `browserRendering: BrowserRenderingOptions`\n\n#### Analytics Engine, Sending Email, Vectorize and Workers for Platforms\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n#### Workers AI\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n### `interface SharedOptions`\n\nOptions shared between all Workers/\"nanoservices\".\n\n#### Core\n\n- `rootPath?: string`\n\n  Path against which all other path options for this instance are resolved\n  relative to. Defaults to the current working directory.\n\n- `host?: string`\n\n  Hostname that the `workerd` server should listen on. Defaults to `127.0.0.1`.\n\n- `port?: number`\n\n  Port that the `workerd` server should listen on. Tries to default to `8787`,\n  but falls back to a random free port if this is in use. Note if a manually\n  specified port is in use, Miniflare throws an error, rather than attempting to\n  find a free port.\n\n- `https?: boolean`\n\n  If `true`, start an HTTPS server using a pre-generated self-signed certificate\n  for `localhost`. Note this certificate is not valid for any other hostnames or\n  IP addresses. If you need to access the HTTPS server from another device,\n  you'll need to generate your own certificate and use the other `https*`\n  options below.\n\n  ```shell\n  $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem\n  ```\n\n  ```js\n  import fs from \"node:fs\";\n\n  new Miniflare({\n  \thttpsKey: fs.readFileSync(\"key.pem\", \"utf8\"),\n  \thttpsCert: fs.readFileSync(\"cert.pem\", \"utf8\"),\n  });\n  ```\n\n- `httpsKey?: string`\n\n  When `httpsCert` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded private key.\n\n- `httpsCert?: string`\n\n  When `httpsKey` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded certificate chain.\n\n- `inspectorPort?: number`\n\n  Port that `workerd` should start a DevTools inspector server on. Visit\n  `chrome://inspect` in a Chromium-based browser to connect to this. This can be\n  used to see detailed `console.log`s, profile CPU usage, and will eventually\n  allow step-through debugging.\n\n- `verbose?: boolean`\n\n  Enable `workerd`'s `--verbose` flag for verbose logging. This can be used to\n  see simplified `console.log`s.\n\n- `log?: Log`\n\n  Logger implementation for Miniflare's errors, warnings and informative\n  messages.\n\n- `upstream?: string`\n\n  URL to use as the origin for incoming requests. If specified, all incoming\n  `request.url`s will be rewritten to start with this string. This is especially\n  useful when testing Workers that act as a proxy, and not as origins\n  themselves.\n\n  When `upstream` is set, the `Host` header is rewritten to match the upstream\n  server. To preserve the original hostname, Miniflare adds an\n  `MF-Original-Hostname` header containing the original `Host` value:\n\n  ```js\n  export default {\n  \tasync fetch(request) {\n  \t\t// When upstream is set, Host header contains the upstream hostname\n  \t\tconst upstreamHost = request.headers.get(\"Host\");\n  \t\t// Original hostname is preserved in MF-Original-Hostname\n  \t\tconst originalHost = request.headers.get(\"MF-Original-Hostname\");\n  \t\treturn new Response(\n  \t\t\t`Original: ${originalHost}, Upstream: ${upstreamHost}`\n  \t\t);\n  \t},\n  };\n  ```\n\n- `cf?: boolean | string | Record<string, any>`\n\n  Controls the object returned from incoming `Request`'s `cf` property.\n  - If set to a falsy value, an object with default placeholder values will be\n    used\n  - If set to an object, that object will be used\n  - If set to `true`, a real `cf` object will be fetched from a trusted\n    Cloudflare endpoint and cached in `node_modules/.mf` for 30 days\n  - If set to a `string`, a real `cf` object will be fetched and cached at the\n    provided path for 30 days\n\n- `unsafeDevRegistryPath?: string`\n\n  Path to the dev registry directory. This allows Miniflare to automatically\n  discover external services and Durable Objects running on another Miniflare\n  instance and connect them. Workers are advertised by default; set\n  `unsafeRegisterWorker` to `false` to opt out.\n\n- `unsafeDevRegistryDurableObjectProxy?: boolean`\n\n  If `true`, Miniflare will automatically proxy requests to Durable Objects\n  bound to external services and register all Workers' Durable Objects in the dev registry.\n\n- `unsafeHandleDevRegistryUpdate?: (registry: WorkerRegistry) => void`\n\n  Callback invoked when the dev registry is updated with changes to bound services.\n  Receives a copy of the updated registry object. Useful for reacting to external\n  service changes during development.\n\n- `unsafeRuntimeEnv?: Record<string, string>`\n\n  Extra environment variables to set on the spawned `workerd` subprocess.\n  Merged on top of `process.env` and Miniflare's own defaults — most notably\n  `TZ=UTC`, which Miniflare sets to match the production Cloudflare runtime so\n  that `Date` and `Intl` APIs inside the Worker observe UTC during local\n  development. Use this option to override those defaults, for example to test\n  timezone-dependent code with `unsafeRuntimeEnv: { TZ: \"Europe/London\" }`.\n\n- `containerEngine?: string | { localDocker: { socketPath: string, containerEgressInterceptorImage?: string } }`\n\n  Configuration used to connect to the container engine for any Workers that\n  define containers. If a `string` is provided, it is used as the local Docker\n  socket path (e.g. `\"unix:///var/run/docker.sock\"`).\n\n#### Persistence\n\n- `resourcePersistencePath?: string`\n\n  Path to the root directory under which all resource data (Cache, Durable\n  Objects, KV, R2, D1, Workflows, etc.) is persisted. Each resource persists to\n  a subdirectory named after its plugin (e.g. `<resourcePersistencePath>/kv`).\n  When unset, persistence is disabled and data is stored in an ephemeral\n  temporary directory that is cleared on `dispose()`.\n\n- `resourceTmpPath?: string`\n\n  Path to the temporary directory used by plugins that need one (e.g. email\n  logs). Falls back to a subdirectory of Miniflare's own temporary directory if\n  not set.\n\n#### Analytics Engine, Sending Email, Vectorize, Workers AI and Workers for Platforms\n\n_Not yet supported_\n\n### `type MiniflareOptions`\n\n`SharedOptions & (WorkerOptions | { workers: WorkerOptions[] })`\n\nMiniflare accepts either a single Worker configuration or multiple Worker\nconfigurations in the `workers` array. When specifying an array of Workers, the\nfirst Worker is designated the entrypoint and will receive all incoming HTTP\nrequests. Some options are shared between all workers and should always be\ndefined at the top-level.\n\n### `class Miniflare`\n\n- `constructor(opts: MiniflareOptions)`\n\n  Creates a Miniflare instance and starts a new `workerd` HTTP server\n  listening on the configured `host` and `port`.\n\n- `setOptions(opts: MiniflareOptions)`\n\n  Updates the configuration for this Miniflare instance and restarts the\n  `workerd` server. Note unlike Miniflare 2, this does _not_ merge the new\n  configuration with the old configuration. Note that calling this function will\n  invalidate any existing values returned by the `Miniflare#get*()` methods,\n  preventing them from being used.\n\n- `ready: Promise<URL>`\n\n  Returns a `Promise` that resolves with a `http` `URL` to the `workerd` server\n  once it has started and is able to accept requests.\n\n- `dispatchFetch(input: RequestInfo, init?: RequestInit): Promise<Response>`\n\n  Sends a HTTP request to the `workerd` server, dispatching a `fetch` event in\n  the entrypoint Worker. Returns a `Promise` that resolves with the response.\n  Note that this implicitly waits for the `ready` `Promise` to resolve, there's\n  no need to do that yourself first. Additionally, the host of the request's URL\n  is always ignored and replaced with the `workerd` server's.\n\n- `dispatchConnect(options?: { protocol?: \"tcp\"; workerName?: string; port?: number }): Promise<net.Socket>`\n- `dispatchConnect(options: { protocol: \"udp\"; workerName?: string; port?: number }): Promise<dgram.Socket>`\n\n  Opens a connection to a Worker's `connect()` trigger and returns a Node.js\n  `net.Socket` for TCP or `dgram.Socket` for UDP. TCP is used when `protocol` is\n  omitted. This implicitly waits for the runtime to start and connects to the\n  trigger's allocated port when its configured port is `0`. If `workerName` is\n  omitted, the entrypoint Worker is selected. If `port` is omitted, the selected\n  Worker must have exactly one trigger for the selected protocol. Calling\n  `dispose()` closes any sockets opened by this method.\n\n- `getBindings<Env extends Record<string, unknown> = Record<string, unknown>>(workerName?: string): Promise<Env>`\n\n  Returns a `Promise` that resolves with a record mapping binding names to\n  bindings, for all bindings in the Worker with the specified `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getWorker(workerName?: string): Promise<Fetcher>`\n\n  Returns a `Promise` that resolves with a\n  [`Fetcher`](https://workers-types.pages.dev/experimental/#Fetcher) pointing to\n  the specified `workerName`. If `workerName` is not specified, defaults to the\n  entrypoint Worker. Note this `Fetcher` uses the experimental\n  [`service_binding_extra_handlers`](https://github.com/cloudflare/workerd/blob/1d9158af7ca1389474982c76ace9e248320bec77/src/workerd/io/compatibility-date.capnp#L290-L297)\n  compatibility flag to expose\n  [`scheduled()`](https://workers-types.pages.dev/experimental/#Fetcher.scheduled)\n  and [`queue()`](https://workers-types.pages.dev/experimental/#Fetcher.queue)\n  methods for dispatching `scheduled` and `queue` events.\n\n- `getCaches(): Promise<CacheStorage>`\n\n  Returns a `Promise` that resolves with the\n  [`CacheStorage`](https://developers.cloudflare.com/workers/runtime-apis/cache/)\n  instance of the entrypoint Worker. This means if `cacheAPI: false` is set on\n  the entrypoint, calling methods on the resolved value won't do anything.\n\n- `getD1Database(bindingName: string, workerName?: string): Promise<D1Database>`\n\n  Returns a `Promise` that resolves with the\n  [`D1Database`](https://developers.cloudflare.com/d1/platform/client-api/)\n  instance corresponding to the specified `bindingName` of `workerName`. Note\n  `bindingName` must not begin with `__D1_BETA__`. If `workerName` is not\n  specified, defaults to the entrypoint Worker.\n\n- `getDurableObjectNamespace(bindingName: string, workerName?: string): Promise<DurableObjectNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`DurableObjectNamespace`](https://developers.cloudflare.com/workers/runtime-apis/durable-objects/#access-a-durable-object-from-a-worker)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getKVNamespace(bindingName: string, workerName?: string): Promise<KVNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`KVNamespace`](https://developers.cloudflare.com/workers/runtime-apis/kv/)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getQueueProducer<Body>(bindingName: string, workerName?: string): Promise<Queue<Body>>`\n\n  Returns a `Promise` that resolves with the\n  [`Queue`](https://developers.cloudflare.com/queues/platform/javascript-apis/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `getR2Bucket(bindingName: string, workerName?: string): Promise<R2Bucket>`\n\n  Returns a `Promise` that resolves with the\n  [`R2Bucket`](https://developers.cloudflare.com/r2/api/workers/workers-api-reference/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `dispose(): Promise<void>`\n\n  Cleans up the Miniflare instance, and shuts down the `workerd` server. Note\n  that after this is called, `Miniflare#setOptions()` and\n  `Miniflare#dispatchFetch()` cannot be called. Additionally, calling this\n  function will invalidate any values returned by the `Miniflare#get*()`\n  methods, preventing them from being used.\n\n- `getCf(): Promise<Record<string, any>>`\n\n  Returns the same object returned from incoming `Request`'s `cf` property. This\n  object depends on the `cf` property from `SharedOptions`.\n\n## Configuration\n\n### Local `workerd`\n\nYou can override the `workerd` binary being used by miniflare with a your own local build by setting the `MINIFLARE_WORKERD_PATH` environment variable.\n\nFor example:\n\n```shell\n$ export MINIFLARE_WORKERD_PATH=\"<WORKERD_REPO_DIR>/bazel-bin/src/workerd/server/workerd\"\n```\n\nFor debugging purposes, you can also set `MINIFLARE_WORKERD_CONFIG_DEBUG=<file_path>` which will dump the workerd config to the specified file path.\n","packages/miniflare/src/plugins/core/proxy/README.md":"# Miniflare API Proxy\n\nMiniflare provides methods for accessing bindings from Node.js, outside a\n`workerd` process. These are implemented by an API proxy that proxies accesses\nand calls to properties and methods over HTTP calls. The directory implements\nthe client for this. The server is implemented as a Durable Object in\n[`src/workers/core/proxy.worker.ts`](../../../workers/core/proxy.worker.ts).\n\nUsing a Durable Object allows us to share references containing I/O objects like\nstreams across requests. The Durable Object contains a \"heap\", mapping addresses\nto references. The \"heap\" is initialised with `globalThis` and `env`.\n\nThe proxy client builds proxies for each object on the heap. Accessing a\nproperty on a proxy will result in a synchronous `GET` operation to the proxy\nserver. If the property is not a method, the value will be serialised back to\nthe client. Note this may involve putting more references on the \"heap\".\n\nIf the property is a method, the client will return a function from the access.\nFuture accesses to the same property key will return the same function without\nthe synchronous `GET` operation. Calling this function will serialise all the\narguments, then perform a synchronous `CALL` operation on the target, and the\nreturn value will be serialised back to the client. If this function returns a\n`Promise`, it will be stored on the \"heap\", and a reference returned. An\nasynchronous `GET` operation will then be performed to resolve the `Promise`,\nand serialise the result. If a function returns a `Promise` once, all future\ncalls will send asynchronous `CALL` operations instead, that resolve the\n`Promise` without an additional round trip.\n\nIf the function call had `ReadableStream` arguments, the first will be sent\nunbuffered after the rest of the arguments. All function calls with\n`ReadableStream` or `Blob` arguments are assumed to be asynchronous. This\nassumption is required as synchronous operations block the main thread and\nprevent chunks from `ReadableStream`s being read.\n\nIf the function call threw, or returned a `Promise` that rejected, the error\nwill be serialised and re-thrown/rejected in the client. Note that the stack\ntrace will be updated to reflect the calling location in the client, not the\nserver.\n\nTo prevent unbounded growth of the \"heap\", all proxies are registered with a\n`FinalizationRegistry`. When the proxy is garbage collected, a `FREE` operation\nwill remove the corresponding \"heap\" entry allowing it to be garbage collected\non the server too.\n\nWhen `workerd` is restarted with `Miniflare#setOptions()` or stopped with\n`Miniflare#dispose()`, all proxies are _poisoned_. Once a proxy is poisoned, it\ncannot be used, and must be recreated. Poisoned proxies are unregistered from\nthe `FinalizationRegistry` too, as the addresses they point too will be invalid\nand shouldn't be freed again.\n","packages/miniflare/src/workers/README.md":"# Miniflare Workers\n\nThis directory contains code for Workers used internally by Miniflare. Files\nending in `*.worker.ts` will be type-checked under\n`@cloudflare/workers-types/experimental`, instead of `@types/node`.\n\nIt also contains dependencies (i.e. header/binding names, other constants and\ntypes) shared between Workers and the Node.js components of Miniflare. These\nmust type check under both typing environments.\n","packages/miniflare/src/workers/cache/README.md":"# The Cache API\n\nThe Cache API within `workerd` is _extremely_ lenient with errors, and will work\nwith a service that doesn't fully support the expected API. This is what it\n_should_ behave like:\n\n## .add()\n\nUnimplemented in the runtime\n\n## .addAll()\n\nUnimplemented in the runtime\n\n## .match()\n\n`workerd` guarantees:\n\n- The method will always be `GET`\n- The request headers will include `Cache-Control: only-if-cached` (which\n  Miniflare ignores)\n- The request headers will include `Cf-Cache-Namespaces` if this is a namespaced\n  cache (i.e. `caches.open(...)`) `workerd` expects:\n- The `Cf-Cache-Status` header to be present with the value:\n  - `MISS` if it's a cache miss, in which case the rest of the response is\n    ignored by `workerd`\n  - `HIT` if it's a cache hit, in which case `workerd` sends the response on to\n    the user, including the full headers and full body\n\n## .put()\n\n`workerd` guarantees:\n\n- The method will always be `PUT`, and the cache key method will always be `GET`\n- The headers will be the headers of the cache key, and the URL will be the URL\n  of the cache key\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The body contains the serialised response for storage\n  - The serialised response will never: - Have a `206` status code - Have a\n    `Vary: *` header - Have a `304` status code `workerd` expects:\n- A `204` (success) or `413` (failure) response code. It doesn't do anything\n  with either\n\n## .delete()\n\n`workerd` guarantees:\n\n- The method will always be `PURGE`, and the cache key method will always be\n  `GET`\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The header `X-Real-IP` will be set to `127.0.0.1`\n- The remaining headers will be the cache key headers `workerd` expects:\n- Status `200` on success\n- Status `404` on failure\n- Status `429` on rate limit (which will throw in the user worker)\n","packages/mock-npm-registry/README.md":"# mock-npm-registry\n\nThis internal package can be used in tests by othe packages to set up a mock local npm registry, publish locally built copies of the packages and their dependencies, then install those packages into test fixtures.\n\n## Usage\n\nA good example is the vitest-plugin e2e tests. See packages/vitest-plugin/test/global-setup.ts\n\n```ts\nexport default async function ({ provide }: GlobalSetupContext) {\n\tconst stop = await startMockNpmRegistry(\"@cloudflare/vitest-plugin\");\n\n\t// Create temporary directory\n\tconst projectPath = await createTestProject();\n\texecSync(\"pnpm install\", { cwd: projectPath, stdio: \"ignore\" });\n\n\tprovide(\"tmpPoolInstallationPath\", projectPath);\n```\n\nHere you can see that in Vitest global setup file, we are calling `startMockNpmRegistry()`.\nWe pass in the `@cloudflare/vitest-plugin` package name, which will ensure that this package\n(and all its local dependencies, such as Wrangler, Miniflare, etc) is built and published to the mock registry.\n\nWe then create a temporary test project that has a dependency on `@cloudflare/vitest-plugin`\nand then run `pnpm install`, which will install the locally published packages.\n\nThe path to this temporary test project is provided to tests.\n\n## Debugging\n\nIf you are having problems with the mock npm registry, you can get additional debug logging by setting the `NODE_DEBUG` environment variable.\n\n```env\nNODE_DEBUG=mock-npm-registry\n```\n","packages/pages-functions/README.md":"# `@cloudflare/pages-functions`\n\n`@cloudflare/pages-functions` compiles a [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/functions/) `functions/` directory into a single [Cloudflare Worker](https://developers.cloudflare.com/workers/) bundle. It provides both a command-line interface and a programmatic API for build tools.\n\nThe package discovers file-based routes, bundles their handlers into an ES module Worker, collects imported Wasm, text, and binary modules, and returns Pages routing metadata through its programmatic API.\n\n> [!WARNING]\n> Pages Functions are not recommended for new development. Build new applications and new server-side functionality with Workers instead. This package is intended to support existing Pages Functions projects and help migrate them incrementally to Workers.\n\n## Installation\n\nInstall the package as a development dependency:\n\n```sh\nnpm install --save-dev @cloudflare/pages-functions\n```\n\n## CLI\n\nCompile the default `functions/` directory into `dist/`:\n\n```sh\nnpx @cloudflare/pages-functions build\n```\n\nTo specify the input and output directories:\n\n```sh\nnpx @cloudflare/pages-functions build ./functions --outdir ./dist/worker\n```\n\nThe command writes the following files:\n\n- `index.js`: the compiled ES module Worker\n- `index.js.map`: the source map, when `--sourcemap` is used\n- Imported Wasm, text, binary, and `assets:` modules required by the Worker\n\nThe generated Worker contains its own router and does not require a `_routes.json` file. To produce one (for example when deploying to Pages), pass `--routes-output <path>`. Pages deployment tools such as Wrangler generate this file on their own and do not need it from the CLI.\n\nThe command only builds the Worker. It does not deploy it or create deployment configuration. By default, the generated Worker falls back to `env.ASSETS.fetch()` when no Function route handles a request, so the deployment must provide an `ASSETS` binding or select another binding with `--fallback-service`.\n\nRuntime-native imports such as `node:*` and `cloudflare:*` are not automatically excluded from the bundle. Pass them through with repeatable `--external` options when the surrounding Worker build or runtime provides them:\n\n```sh\nnpx @cloudflare/pages-functions build --external \"node:*\" --external \"cloudflare:*\"\n```\n\n### CLI options\n\n| Option                      | Description                                            | Default     |\n| --------------------------- | ------------------------------------------------------ | ----------- |\n| `[directory]`               | Pages Functions directory                              | `functions` |\n| `--outdir <path>`           | Output directory                                       | `dist`      |\n| `--minify`                  | Minify the Worker bundle                               | Disabled    |\n| `--sourcemap`               | Generate an external source map                        | Disabled    |\n| `--fallback-service <name>` | Fetcher binding used when no route handles the request | `ASSETS`    |\n| `--external <module>`       | Exclude a module from the bundle; may be repeated      | None        |\n| `--routes-output <path>`    | Write the generated `_routes.json` spec to this path   | Not written |\n| `-h`, `--help`              | Display usage information                              |             |\n| `-v`, `--version`           | Display the package version                            |             |\n\n## Programmatic API\n\nUse `buildPagesFunctions()` when integrating the compiler into another build tool:\n\n```ts\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nconst result = await buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/worker\",\n\tsourcemap: true,\n});\n\nconsole.log(result.entryPointPath);\nconsole.log(result.routesJSON);\n```\n\n`buildPagesFunctions()` returns the generated routing specification as `routesJSON` but does not write a `_routes.json` file. Consumers such as Wrangler can use this metadata when deploying to Pages.\n\n### Build options\n\n| Option                  | Type       | Description                                               | Default           |\n| ----------------------- | ---------- | --------------------------------------------------------- | ----------------- |\n| `functionsDirectory`    | `string`   | Pages Functions directory to compile                      | Required          |\n| `outputDirectory`       | `string`   | Directory for `index.js` and collected modules            | Required          |\n| `assetsOutputDirectory` | `string`   | Directory for files referenced by `assets:` imports       | `outputDirectory` |\n| `fallbackService`       | `string`   | Fetcher binding used when no route handles the request    | `ASSETS`          |\n| `minify`                | `boolean`  | Minify the Worker bundle                                  | `false`           |\n| `sourcemap`             | `boolean`  | Generate an external source map                           | `false`           |\n| `external`              | `string[]` | Module specifiers to exclude from the bundle              | `undefined`       |\n| `routesDescription`     | `string`   | Description included in the returned routes specification | `undefined`       |\n| `metafile`              | `boolean`  | Include the esbuild metafile in the result                | `false`           |\n\n### Build result\n\n`buildPagesFunctions()` returns:\n\n| Property                | Description                                           |\n| ----------------------- | ----------------------------------------------------- |\n| `entryPointPath`        | Absolute path to the generated `index.js`             |\n| `bundleType`            | Always `\"esm\"`                                        |\n| `modules`               | Collected Wasm, text, and binary modules              |\n| `dependencies`          | Inputs included in the generated bundle               |\n| `sourceMapPath`         | Absolute source map path when source maps are enabled |\n| `routesJSON`            | Generated `_routes.json` data                         |\n| `filepathRoutingConfig` | Discovered Pages Functions routes and base URL        |\n| `metafile`              | esbuild metafile when requested                       |\n\nThe package also exports lower-level route discovery, generation, optimization, and validation helpers for tooling authors. Their TypeScript declarations are included with the package.\n\n## Migrate to Workers\n\n[Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/) supports deploying front-end assets and Worker code together. Workers also provides access to more Cloudflare platform features than Pages Functions. New routes and application logic should therefore be written in a Worker rather than added to an existing `functions/` directory.\n\nFor an existing Pages Functions project, you can compile the old Functions during the Worker build and delegate requests to them from your Worker. This lets you migrate one route at a time.\n\nFor example, configure Wrangler to compile the legacy `functions/` directory before it bundles the Worker:\n\n```jsonc\n{\n\t\"$schema\": \"./node_modules/wrangler/config-schema.json\",\n\t\"name\": \"my-worker\",\n\t\"main\": \"./src/index.js\",\n\t// Preserve the compatibility date and flags from your Pages project.\n\t\"compatibility_date\": \"<YOUR_EXISTING_COMPATIBILITY_DATE>\",\n\t\"assets\": {\n\t\t\"directory\": \"./dist/client\",\n\t\t\"binding\": \"ASSETS\",\n\t\t\"run_worker_first\": true,\n\t},\n\t\"build\": {\n\t\t\"command\": \"npx @cloudflare/pages-functions build ./functions --outdir ./dist/pages-functions --external \\\"node:*\\\" --external \\\"cloudflare:*\\\"\",\n\t\t\"watch_dir\": [\"./functions\", \"./src\"],\n\t},\n}\n```\n\nAdjust `assets.directory` and combine the build command with your existing front-end build command as needed. Preserve any compatibility flags used by the Pages project. The `--external` options leave runtime-native imports for Wrangler to process. The `ASSETS` binding is required by the compiler's default fallback behavior. `run_worker_first` ensures the Worker can run Pages Functions routes and middleware before falling back to static assets.\n\nImport the compiled handler from your Worker, handle new or migrated routes first, and use the old Pages Functions handler as a fallback:\n\n```js\nimport legacyPagesFunctions from \"../dist/pages-functions/index.js\";\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tconst url = new URL(request.url);\n\n\t\tif (url.pathname === \"/api/new-route\") {\n\t\t\treturn new Response(\"Handled by the Worker\");\n\t\t}\n\n\t\treturn legacyPagesFunctions.fetch(request, env, ctx);\n\t},\n};\n```\n\nThis ordering means Pages Functions middleware does not run for routes handled directly by the Worker. Migrate authentication, authorization, logging, and other applicable middleware to the Worker before moving routes that depend on it.\n\nAs routes are migrated, remove their files from `functions/` and implement them directly in the Worker. Once no legacy Pages Functions remain, remove the compiler build step and import.\n\nIf the legacy Functions use `assets:` imports, the imported assets must be written into the directory configured by `assets.directory`. The CLI writes them beneath its output directory, so use the programmatic API to select separate Worker and asset outputs:\n\n```js\n// scripts/build-pages-functions.mjs\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nawait buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/pages-functions\",\n\tassetsOutputDirectory: \"./dist/client\",\n\texternal: [\"node:*\", \"cloudflare:*\"],\n});\n```\n\nThen set `build.command` to `node ./scripts/build-pages-functions.mjs`. The `assets:` integration always uses the `ASSETS` binding, even when a different general fallback service is configured.\n\nWorkers do not use Pages `_routes.json` metadata. Configure [Workers Static Assets routing](https://developers.cloudflare.com/workers/static-assets/routing/) explicitly, especially if the Pages project used custom `_routes.json` rules or middleware. See the complete [Pages-to-Workers migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) for bindings, assets, compatibility settings, and deployment changes.\n\n## Contributing\n\nSee the Workers SDK [contributing guide](../../CONTRIBUTING.md) for repository setup and contribution requirements.\n\nFrom the repository root, install dependencies and run package tasks with:\n\n```sh\npnpm install\npnpm run build --filter @cloudflare/pages-functions\npnpm run check:type --filter @cloudflare/pages-functions\npnpm run test:ci --filter @cloudflare/pages-functions\npnpm run dev --filter @cloudflare/pages-functions\n```\n\nThe `dev` task watches this package's implementation; it does not watch an end-user Pages Functions project.\n\nBefore submitting changes, run:\n\n```sh\npnpm prettify\npnpm check\n```\n\n## License\n\nLicensed under either the [Apache 2.0 license](../../LICENSE-APACHE) or the [MIT license](../../LICENSE-MIT) at your option.\n","packages/pages-shared/README.md":"# `@cloudflare/pages-shared`\n\nThis is a package that is used internally to power Wrangler and Cloudflare Pages. It contains all the code that is shared between these clients (and possibly any other in the future e.g. the dashboard).\n\nCode should be written so that it can be run in almost any environment (e.g. Deno, Node, browser, Workers), but note that there's currently a bit of weirdness here for `asset-server`, hence the `environment-polyfills` piece.\n\n> [!NOTE]\n> Since code in this package is used by the Pages infrastructure, it is important that PRs are given careful review with regards to how they could cause a failure in production.\n> Ideally, there should be comprehensive tests for changes being made to give extra confidence about the behavior.\n","packages/quick-edit-extension/README.md":"# Quick Edit VS Code Extension\n\nThe code in this package is used by the `quick-edit` package, which in turn is used in the `workers-playground` package.\nTo debug this package locally check out the [Quick Edit package README](../quick-edit/README.md).\n","packages/quick-edit/README.md":"# VSCode for Web\n\nThis package contains Cloudflare's fork of VSCode for Web, to support web editing of Workers. This package contains code and setup for building VSCode for Web.\n\nThe code in this package is used by the `workers-playground` package.\n\n## Developing\n\nNote: Currently it's not possible to run VSCode's dev server to develop patches. This is because of a limitation with the `wrangler dev` file server for Workers Assets and the number of assets that would be watched locally.\n\n## Building\n\n- Use Node.js 22\n  - VSCode's build process requires this\n- Run `pnpm install`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run setup`\n  - installs dependencies\n  - clones VSCode (currently v1.102.1)\n  - applies the patches specified in `./patches`\n  - symlinks the top level packages within `workers-sdk`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run custom:build`\n  - This takes up to 15 mins to run\n  - It's not `build` because it would then run when people run the top level `pnpm run build` to build other packages in the repository.\n\n## Debugging\n\n- Change the `quickEditHost` constant in [workers-playground/src/QuickEditor/VSCodeEditor.tsx](../workers-playground/src/QuickEditor/VSCodeEditor.tsx) to http://localhost:8787\n- Run the following in parallel:\n  - `pnpm -F workers-playground dev` -> `http://localhost:5173`\n  - `pnpm -F \"@cloudflare/quick-edit\" exec wrangler dev` -> `http://localhost:8787`\n- Get a user token to connect to a preview Worker\n  - Navigate to https://playground-testing.devprod.cloudflare.dev/\n  - This will respond with a `error code: 522` response, which is expected\n  - Grab the `user` cookie from the 522 response\n- Open http://localhost:5173/playground\n  - Open the devtools and add the `user` cookie from the previous step to this site\n  - Refresh the page and play around with the editor\n\n## Deployment\n\nDeployments are managed by GitHub Actions:\n\n- deploy-pages-previews.yml:\n  - Runs on any PR that has the `preview:quick-edit` label.\n  - Deploys a preview, which can then be accessed via [https://<SHA>.quick-edit-cny.pages.dev/].\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production, which can then be accessed via [https://quick-edit-cny.pages.dev/].\n\n## Patching VSCode\n\nIf you need to add additional patches to VSCode, ensure you've run `pnpm run setup`. Then:\n\n1. Make your changes in the checked out VSCode in `vendor/vscode`.\n2. Commit your changes with `git commit -m \"YOUR MESSAGE\" --no-verify` (run this in the `vendor/vscode` directory).\n3. Prepare a new series of patches for VSCode with (again, run in the `vendor/vscode` directory) `git format-patch -o ../../packages/quick-edit/patches base`.\n\n## Modifying VSCode settings\n\nIf you need to change VSCode's configuration, open the `packages/quick-edit/src/index.ts` file.\n\nThe `WORKBENCH_WEB_CONFIGURATION` object contains VSCode's setup config, but the property `configurationDefaults` is most relevant, since it lets you set defaults for any VSCode settings. The format is exactly the same as VSCode's `settings.json` file.\n\n## Embedding VSCode\n\n> [!WARNING]\n> Cloudflare does not officially support embedding this version of VSCode in third-party contexts—use at your own risk! This documentation is aimed at people inside Cloudflare embedding this package.\n\nThe primary purpose of the patches we apply to VSCode is to allow the visible filesystem within VSCode to be controllable from the outside (by a web page that embeds the editor). You can refer to `packages/workers-playground/src/QuickEditor/VSCodeEditor.tsx` as a reference implementation.\n\nTo communicate with VSCode, a web page needs to load the deployed editor in an iframe:\n\n```html\n<iframe\n\tsrc=\"https://quick-edit.devprod.cloudflare.dev?worker=$worker&theme=dark\"\n></iframe>\n```\n\nThe `$worker` query parameter should be set to the path of the to-be-edited Worker on the virtual filesystem. The protocol used for the virtual filesystem is `cfs`, so it should look like `cfs:/my-worker-name`.\n\nTo load files into the VSCode filesystem and react to changes from within VSCode, you need to send over a `MessagePort`:\n\n```ts\nimport { Channel } from \"@cloudflare/workers-editor-shared\";\nimport type {\n\tFromQuickEditMessage,\n\tToQuickEditMessage,\n\tWorkerLoadedMessage,\n\tWrappedChannel,\n} from \"@cloudflare/workers-editor-shared\";\n\nconst editor; // Acquire a reference to the iframe DOM element somehow. This will depend on the frontend framework in use.\n\nconst channel = Channel<ToQuickEditMessage, FromQuickEditMessage>(\n\tnew MessageChannel()\n);\n\neditor.addEventListener(\"load\", () => {\n\teditor.contentWindow.postMessage(\"PORT\", \"*\", [channel.remote]);\n});\n\n// When you have the initial contents of the Worker (loaded from an API, perhaps)\nchannel.postMessage({\n\ttype: \"WorkerLoaded\",\n\tbody: {\n\t\t// Refer to the WorkerLoaded type for details\n\t},\n});\n\nchannel.onMessage((message) => {\n\t// message is of type SetEntryPoint, UpdateFile, CreateFile, or DeleteFile\n\t// Refer to @cloudflare/workers-editor-shared for details\n});\n```\n","packages/runtime-types/README.md":"# `@cloudflare/runtime-types`\n\nUtilities for generating Cloudflare Workers runtime types from compatibility dates and flags.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","packages/shared-ast-primitives/README.md":"# `@cloudflare/shared-ast-primitives`\n\nInternal AST-manipulation primitives shared across Cloudflare Workers SDK codemods.\n\nThis package wraps [`recast`](https://github.com/benjamn/recast) with a small set of\nhelpers (`parseJs`, `parseTs`, `parseFile`, `transformFile`, `mergeObjectProperties`)\nused by C3 and autoconfig to transform user project files. It is private and not published.\n\n## Developing\n\nWriting codemods often requires trial and error. The package ships a dedicated dev workflow so you can iterate on transforms in isolation without writing throw-away scripts.\n\n### Commands\n\n| Command         | Description                                                |\n| --------------- | ---------------------------------------------------------- |\n| `pnpm dev`      | Run `src/dev.ts` in watch mode (hot-reloads on every save) |\n| `pnpm dev:once` | Run `src/dev.ts` once without watching                     |\n\n### Workflow\n\n1. **Edit `dev-snippets/test.ts`** — put whatever source code you want to transform into this file. It is the default input used by the dev script. You can add more files under `dev-snippets/` and reference them from `src/dev.ts`.\n\n2. **Edit `testCodemod()` in `src/dev.ts`** — this is your sandbox. Call `testTransform()` with the path to your snippet and a [`recast` visitor](https://github.com/benjamn/recast) that describes the transform:\n\n   ```ts\n   const testCodemod = () => {\n   \ttestTransform(\"../dev-snippets/test.ts\", {\n   \t\tvisitIdentifier(n) {\n   \t\t\tn.node.name = \"MyNewName\";\n   \t\t\treturn false;\n   \t\t},\n   \t});\n   };\n   ```\n\n3. **Run `pnpm dev`** — the transformed code is printed to the console and written to `dev-snippets-outputs/test.ts` (gitignored). Inspect the output file to verify the transform behaves as expected.\n\n### `testTransform(filePath, methods)`\n\nMirrors the production `transformFile()` API but instead of silently writing in place it:\n\n- Prints the transformed source to the console\n- Writes the result to the corresponding path under `dev-snippets-outputs/`\n\nThe `filePath` argument must point to a file inside `dev-snippets/`; paths outside that directory are rejected.\n","packages/solarflare-theme/README.md":"# Solarflare Theme\n\nThe Solarflare theme is an official VSCode theme for utilization with a modified VSCode for Web in the Cloudflare dashboard.\n","packages/turbo-r2-archive/README.md":"# Turbo R2 Archive\n\n[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/jacobMGEvans/Turbo-R2-Archive)\n\n## Overview\n\nThis is a Worker that will act as an event server for caching TurboRepo artifacts. Compliant with the TurboRepo API, for remote caching, it will store the cache artifacts in a Cloudflare R2 bucket and purge the R2 Objects on a schedule, using [R2 Object lifecycle rules](https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/). This allows for all the benefits of remote caching TurboRepo artifacts on Cloudflare's edge network.\n\nThis will require a Cloudflare account, with a zone and R2.\n\n## Environment Variables\n\nUtilizing `.env` file to store the variables for Turborepo API & Worker. The `.env` file should be in the root of the project directory. The `.env` file should contain the following variables. Be sure to add the `.env` file to `.gitignore` to prevent it from being committed to the repository.\n\nThe commands are ran with `dotenv` cli `npx dotenv -- npx turbo <command>` to inject the environment variables into the command process environment.\n\n```bash\nTURBO_API=<baseURL> # https://something.com\nTURBO_TEAM=<value> # team_whatever it has to start with prefix team_\nTURBO_TOKEN=<value> # whatever is set in the worker secret\nTURBO_REMOTE_CACHE_SIGNATURE_KEY=<value> # needs to be the same for every one using the same cache\n```\n\n## Turbo Project Config\n\nTo utilize the `TURBO_REMOTE_CACHE_SIGNATURE_KEY` which will increase the security of the remote cache, the project config will need to be updated to include the following:\n\n```json\n{\n\t\"remoteCache\": { \"signature\": true }\n}\n```\n\n## Worker Configuration\n\n```jsonc\n{\n\t\"r2_buckets\": [\n\t\t{\n\t\t\t\"binding\": \"R2_ARTIFACT_ARCHIVE\", // The binding name for the bucket, used in the Worker i.e. env.R2_ARTIFACT_ARCHIVE.get(<key>)\n\t\t\t\"bucket_name\": \"turbo-cache\", // bucket name when looking for objects in dashboard\n\t\t\t\"preview_bucket_name\": \"turbo-cache-preview\",\n\t\t},\n\t],\n}\n```\n\nThe endpoints are protected by a bearer token. The token is stored as a secret in the Worker. The token can be set with the following command:\n\n```bash\necho <VALUE> | wrangler secret put TURBO_TOKEN\n```\n\n<!-- Add the setting up the R2 bucket & Object Rules -->\n\n### Manual Cache Purge\n\nThe cache can also be purged manually by sending a `POST` request to the `<baseURL>/artifacts/manual-cache-bust` endpoint. This can be done with the following command:\n\n```bash\nhttps -A bearer -a <TURBO_TOKEN> POST <baseURL>/artifacts/manual-cache-bust\n```\n\n## How can I develop & test locally?\n\nThis project is primarily self-service and is meant to be forked and modified to fit your needs. The following instructions will help you get started.\n\n### Running the Worker Locally\n\nThe Worker can be run, locally with the `package.json` script `start`:\n\n```bash\nnpm run start\n```\n\n### TurboRepo Testing Local Server\n\nWell since we are already using Cloudflare, let's keep that going. `cloudflared` allows for creating a tunnel to your `http://127.0.0.1:8787` and exposing it to the internet. This will allow others direct their TurboRepo to the local dev server by setting`TURBO_API` to `<host>`.\nThe command to create a tunnel looks like:\n\n```bash\ncloudflared tunnel --hostname <host> --url http://127.0.0.1:8787/ --name r2-archive (or whatever you want to name it)\n```\n\n## How can I deploy this?\n\nFork this repo, have a Cloudflare account, and run the following command:\n\n```bash\nnpm run deploy\n```\n\nYou now have a TurboRepo API compliant event server that will cache artifacts on Cloudflare's edge network.\n","packages/unenv-preset/README.md":"# @cloudflare/unenv-preset\n\n[unenv](https://github.com/unjs/unenv) preset for cloudflare.\n\nunenv provides polyfills to add [Node.js](https://nodejs.org/) compatibility for any JavaScript runtime, including browsers and edge workers.\n\n## Usage\n\n```ts\nimport { cloudflare } from \"@cloudflare/unenv-preset\";\nimport { defineEnv } from \"unenv\";\n\nconst { env } = defineEnv({\n\tpresets: [cloudflare],\n});\n\nconst { alias, inject, external, polyfill } = env;\n```\n\nSee the unenv [README](https://github.com/unjs/unenv/blob/main/README.md) for more details.\n\n## Tests\n\nThis package is tested via wrangler e2e tests.\n","packages/vite-plugin-cloudflare/AGENTS.md":"# AGENTS.md — vite-plugin-cloudflare\n\n## OVERVIEW\n\nVite plugin for Cloudflare Workers development. Exports `cloudflare()` plugin factory from `src/index.ts`. ESM-only output.\n\n## STRUCTURE\n\n- `src/index.ts` — Plugin factory\n- `src/cf-vite.ts` — `cf-vite` delegate binary entry (see below)\n- `bin/cf-vite` — shebang shim that dynamic-imports `dist/cf-vite.mjs`\n- `src/workers/` — 4 internal worker entries: `asset-worker`, `router-worker`, `runner-worker`, `vite-proxy-worker`\n- `playground/` — ~47 playground apps, each a workspace member (nested workspace under this package)\n- `e2e/` — E2E tests with Playwright\n- `__tests__/` — Unit tests use `.spec.ts` naming\n\n## BUILD\n\n- Only package using `tsdown` as build tool\n- Outputs ESM (`.mjs`) to `dist/index.mjs`\n- `src/cf-vite.ts` is a second top-level tsdown entry, bundled to `dist/cf-vite.mjs` (no dts)\n- Also bundles 4 internal worker scripts from `src/workers/*/index.ts` as separate neutral-platform outputs to `dist/workers/`\n- Release builds set `SOURCEMAPS=false` to omit the plugin's JavaScript and declaration maps. Normal builds retain maps for debugging; the setting does not change source maps for applications built with the plugin.\n\n## cf-vite DELEGATE BINARY (experimental / internal)\n\n`bin/cf-vite` is an experimental, internal delegate binary spawned by\nCloudflare's \"cf-dev\" parent process — NOT part of the plugin's public\nAPI and not meant for direct end-user invocation. It is the sibling of\n`wrangler`'s `cf-wrangler` binary, and the two MUST keep a shared spawn\ncontract so the parent can drive either impl interchangeably.\n\n- **Verb dispatch.** `cf-vite <verb> [flags]`. `dev` and `build` are the\n  verbs today; future verbs (`deploy`) follow the same shape.\n  Unknown/missing verbs exit `2` (this doubles as the parent's\n  version-detection signal — no JSON handshake).\n- **Shared flag vocabulary (`dev`).** For `dev`, only `--mode`, `--port`,\n  `--host`, `--local` are accepted, mirroring `cf-wrangler` exactly.\n  Parsed with `node:util.parseArgs` strict mode → unknown flags exit `2`.\n  Do NOT add flags here unless `cf-wrangler` grows them too. (There is no\n  `--config` flag: the wrangler config is discovered by `cloudflare()`\n  itself.)\n- **`build`** `cf-vite build` runs Vite's full multi-environment\n  app build via `createBuilder().buildApp()` (NOT the legacy\n  single-environment `build()` helper, which would skip the plugin's\n  worker/build-output orchestration — mirrors Vite's own `vite build`\n  CLI). It accepts only `--mode` (`--port`/`--host`/`--local` don't apply to\n  a build and exit `2`). Preview build context is supplied through\n  `CLOUDFLARE_PREVIEW_BUILD`, which also works when a framework runs Vite as\n  part of its own build command.\n- **Build Output Specification is the core build pipeline.** Every build emits\n  Build Output; there is no feature flag or legacy output-config path. Preview\n  reads Workers and Containers exclusively from that output. The v2 plugin\n  always installs its build-output plugin, so `cf-vite` does not need the\n  internal force-build-output flag used by v1.\n- **Caller identity.** `main()` sets `CLOUDFLARE_VITE_CLI_DISPLAY_NAME=cf`\n  before Vite loads the user's config. `resolvePluginConfig` reads this through\n  `getCliDisplayName()` so shared services can use `cf` in actionable messages;\n  direct Vite plugin use defaults to `Wrangler`. This is an internal bridge,\n  not a `.env`-file knob.\n- **`dev`** `cf-vite dev` boots Vite via `createServer()`\n  against the user's own `vite.config.ts` (which must include\n  `cloudflare()`). Plugin-owned flags are bridged via env vars the plugin\n  already reads (`--local` → `CLOUDFLARE_VITE_FORCE_LOCAL`); Vite-owned\n  flags go through inline config (`--port`/`--host` → `server.*`,\n  `--mode` → `mode`).\n- **`--local`** forces remote bindings off. There is no plugin env knob\n  for `remoteBindings` other than `CLOUDFLARE_VITE_FORCE_LOCAL`, which\n  `resolvePluginConfig` in `plugin-config.ts` honours by overriding the\n  `remoteBindings` config option. Keep that override in sync if the flag\n  semantics change.\n- **Hotkeys differ by design.** `cf-vite` uses Vite's own\n  `bindCLIShortcuts` (`h`/`r`/`q`/…), not wrangler's hotkey set. The\n  parent process should not assume identical hotkey UX across delegates.\n- **Exit codes.** `0` graceful, `2` unknown verb / argv parse error,\n  `130` SIGINT, `143` SIGTERM.\n\n## CONVENTIONS\n\n- Playground directory `worker-♫/` has unicode in name (intentional)\n\n## TESTING\n\n- Unit tests: `.spec.ts` in `__tests__/`\n- E2E tests: `.test.ts` in `e2e/`, own vitest config\n- Playground tests: Playwright-based, tested across Vite 7/8 in CI\n- Playground request helpers (`playground/__test-utils__/responses.ts`):\n  - `getTextResponse()` / `getJsonResponse()` issue a request with browser\n    navigation headers (`Sec-Fetch-Mode: navigate` et al), which the asset and\n    router workers branch on. Default to these.\n  - They use undici's low-level `request()` rather than `fetch()`\n    **deliberately**. The Fetch spec requires implementations to set\n    `Sec-Fetch-Mode` from the request's `mode` (\"append the Fetch metadata\n    headers\"), so `fetch()` overwrites whatever the caller passed with `cors`\n    before the request leaves the process (`appendFetchMetadata` in undici).\n    `Sec-Fetch-Dest`/`-Site`/`-User` are unimplemented there, so they survive —\n    which is why only `Sec-Fetch-Mode` breaks and it is easy to miss. That one\n    decides whether the asset worker applies `not_found_handling`.\n  - This is permanent, not a bug to wait out: no Fetch-based API can send\n    `Sec-Fetch-Mode: navigate`, and `fetch(url, { mode: \"navigate\" })` is\n    rejected by the `Request` constructor. Do not \"simplify\" these back to\n    `fetch()`; `spa-with-api`'s \"via `getTextResponse()`\" test exists to catch\n    exactly that regression (it is the only playground whose compat date enables\n    `SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING`).\n  - `getResponse()` drives a real `page.goto()` and returns a Playwright\n    `Response`. Only use it when the assertion needs the browser. Anything\n    routed through Playwright can outlive a timed-out test and surface as an\n    unhandled rejection, which fails the whole run rather than one test.\n  - `WAIT_FOR_OPTIONS` (`playground/__test-utils__/index.ts`) must stay\n    comfortably below the test timeout, otherwise `vi.waitFor()` never gets to\n    report the assertion that was actually failing.\n- `playground/vitest.config.e2e.ts` inherits the repo-wide timeouts and\n  `retry: 1` from the root `vitest.shared.ts`. It spreads `configShared.test`\n  rather than using `mergeConfig()`, which concatenates arrays and would\n  silently enable the shared `default` reporter alongside `dot`.\n","packages/vite-plugin-cloudflare/README.md":"# `@cloudflare/vite-plugin`\n\nThe Cloudflare Vite plugin enables a full-featured integration between [Vite](https://vite.dev/) and the [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/).\nYour Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications.\n\n```ts\n// vite.config.ts\n\nimport { defineConfig } from \"vite\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\n\nexport default defineConfig({\n  plugins: [cloudflare()],\n});\n```\n\n## Documentation\n\nFull documentation can be found [here](https://developers.cloudflare.com/workers/vite-plugin/).\n\n## Features\n\n- Uses the Vite [Environment API](https://vite.dev/guide/api-environment) to integrate Vite with the Workers runtime\n- Provides direct access to [Workers runtime APIs](https://developers.cloudflare.com/workers/runtime-apis/) and [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/)\n- Builds your front-end assets for deployment to Cloudflare, enabling you to build static sites, SPAs, and full-stack applications\n- Official support for [TanStack Start](https://tanstack.com/start/) and [React Router v8](https://reactrouter.com/) with server-side rendering\n- Leverages Vite's hot module replacement for consistently fast updates\n- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment\n\n## Use cases\n\n- [TanStack Start](https://tanstack.com/start/)\n- [React Router v8](https://reactrouter.com/)\n- Support for more full-stack frameworks is coming soon\n- Static sites, such as single-page applications, with or without an integrated backend API\n- Standalone Workers\n- Multi-Worker applications\n","packages/vite-plugin-cloudflare/e2e/README.md":"# vite-plugin e2e tests\n\nThis directory contains e2e tests that give more confidence that the plugin will work in real world scenarios outside the comfort of this monorepo.\n\nIn general, these tests create test projects by copying a fixture from the `fixtures` directory into a temporary directory and then installing the local builds of the plugin along with its dependencies.\n\n## Running the tests\n\nSimply use turbo to run the tests from the root of the monorepo.\nThis will also ensure that the required dependencies have all been built before running the tests.\n\nYou will need to provide CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN for the Workers AI tests to pass.\n\n```sh\nCLOUDFLARE_ACCOUNT_ID=xxxx CLOUDFLARE_API_TOKEN=yyyy pnpm test:e2e -F @cloudflare/vite-plugin\n```\n\n## Developing e2e tests\n\nThese tests use a mock npm registry where the built plugin has been published.\n\nThe registry is booted up and loaded with the local build of the plugin and its local dependencies in the global-setup.ts file that runs once at the start of the e2e test run, and the server is killed and its caches removed at the end of the test run. The mock npm registry will delegate to the standard public npm registry for non-local dependency requests (e.g. vite, typescript, etc).\n\nThere is a `seed()` helper to setup a clean copy of a fixture outside of the monorepo so that it can be isolated from any other dependencies in the project.\n\nThe simplest test looks like:\n\n```ts\nconst projectPath = await seed(\"basic\", { pm: \"pnpm\" });\n\ntest(\"can serve a Worker request\", async ({ expect, seed, runLongLived }) => {\n\tconst proc = await runLongLived(\"npm\", \"dev\", projectPath);\n\tconst url = await waitForReady(proc);\n\texpect(await fetchJson(url + \"/api/\")).toEqual({ name: \"Cloudflare\" });\n});\n```\n\n- The `seed()` helper creates a `beforeAll()` block:\n  - make a copy of the named fixture into a temporary directory,\n  - updates the vite-plugin dependency in the package.json to match the local version\n  - runs `npm install` (or equivalent package manager command) in the temporary project - the dependencies are installed from the mock npm registry mentioned above.\n  - returns the path to the directory containing the copy (`projectPath` above)\n- The `seed()` helper also creates an `afterAll()` block:\n  - the temporary directory will be deleted at the end of the test.\n- The `runCommand()` helper simply executes a one-shot command and resolves when it has exited. You can use this to install the dependencies of the fixture from the mock npm registry.\n- The `runLongLived()` helper runs an npm script (from the package.json scripts section) and returns an object that can be used to monitor its output. The process will be killed at the end of the test.\n- The `waitForReady()` helper will resolve when a `vite dev` long lived process has output a ready message, from which it will parse the url that can be fetched in the test.\n- The `fetchJson()` helper makes an Undici fetch to the url parsing the response into JSON. It will retry every 250ms for up to 10 secs to minimize flakes.\n\n## Debugging e2e tests\n\nYou can control the logging and cleanup via environment variables:\n\n- Keep the temporary directory after the tests have completed: `CLOUDFLARE_VITE_E2E_KEEP_TEMP_DIRS=true`\n- See debug logs for the tests: `NODE_DEBUG=vite-plugin:test`\n- See debug logs for the mock npm registry: `NODE_DEBUG=mock-npm-registry`\n- See debug logs for Vite: `DEBUG=\"vite:*\"`\n","packages/vite-plugin-cloudflare/playground/additional-modules/README.md":"# Additional Modules\n\nThe modules directory contains the following example files:\n\n- `bin-example.bin` - a TTF file for the Inter font with the extension changed to `.bin`\n- `html-example.html` - a Hello World HTML document\n- `text-example.txt` - a simple text file\n- `wasm-example.wasm` - a compiled WebAssembly file that exports an `add` function\n\nThe WebAssembly is generated from the following C code:\n\n```c\n#include <stdint.h>\n\nint32_t add(int32_t a, int32_t b) {\n    return a + b;\n}\n```\n","packages/vite-plugin-cloudflare/tsconfig.plugin.json":"{\n\t\"extends\": \"@cloudflare/workers-tsconfig/worker.json\",\n\t\"compilerOptions\": {\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true\n\t},\n\t\"include\": [\"src\"],\n\t\"exclude\": [\"src/workers\", \"src/__tests__/fixtures\"]\n}\n","packages/vitest-plugin/AGENTS.md":"# vitest-plugin — Agent Guide\n\n> Custom Vitest pool for running Worker tests inside the actual workerd runtime.\n> Do NOT repeat root AGENTS.md content (pnpm, changesets, code style, etc.).\n\n## THREE-CONTEXT ARCHITECTURE\n\n### 1. Pool (`src/pool/index.ts`)\n\n- Runs in Node.js Vitest process\n- Main export (`exports[\".\"]`), built as ESM (`.mjs`)\n- Orchestrates test execution\n\n### 2. Config (`src/pool/config.ts`)\n\n- Runs in Node.js, part of the pool bundle (no separate package export)\n- Validates pool options (`WorkersPoolOptionsSchema`) and resolves the project's\n  Worker configuration into Miniflare options\n- `src/pool/plugin.ts` provides the `cloudflareTest()` Vite plugin, which injects\n  `cloudflare:test` resolution and sets resolve conditions (`workerd`, `worker`, `browser`)\n\n### 3. Worker (`src/worker/index.ts`)\n\n- Runs inside workerd runtime\n- NOT exported via package.json — internal entry\n- Contains HACK: monkeypatches VitestExecutor to access singleton\n- Has direct cross-package source import into `miniflare/src/workers/core/devalue`\n\n## WORKER CONFIGURATION SOURCES\n\n`parseCustomPoolOptions()` in `src/pool/config.ts` resolves at most one configuration\nfile into a normalised `Config`, then shares every downstream step (remote proxy\nsession, `unstable_getMiniflareWorkerOptions()`, `main`, defines, module rules, tails):\n\n- `wrangler: { configPath, environment }` — a Wrangler configuration file, via\n  `wrangler.unstable_readConfig()`\n- `experimental: { newConfig }` — a `cloudflare.config.ts`, via `src/pool/new-config.ts`\n  (`@cloudflare/config`'s `loadAndParseConfig()` → `convertToWranglerConfig()` →\n  `normalizeAndValidateConfig()`). Mirrors `@cloudflare/vite-plugin`'s\n  `experimental.newConfig`. `ctx.mode` comes from `project.vite.config.mode`.\n\nThe two are mutually exclusive. Whichever is used, the resolved path, config format and\nWorker name are recorded on `options.resolvedConfig` for the pool to consume — never\nre-read the config file from disk.\n\n## BUILD\n\n`tsdown.config.ts` defines 2 separate builds (all ESM):\n\n1. pool — `src/pool/index.ts` → `dist/pool` (emits type declarations)\n2. worker + libs — `src/worker/index.ts` plus `src/worker/lib` and `src/worker/node` → `dist/worker`\n\nTypes entry `types/cloudflare-test.d.ts` is hand-written (NOT generated from source).\n\n## THE `cloudflare:test` MODULE\n\nTests inside workerd import from `cloudflare:test`:\n\n```ts\nimport { env, fetchMock, SELF } from \"cloudflare:test\";\n```\n\nResolved by custom Vite plugin (`@cloudflare/vitest-plugin:config`) that re-exports from `cloudflare:test-internal` (runtime-provided).\n\n## CONVENTIONS\n\n- `expect` must come from test context: `it(\"name\", ({ expect }) => {})` — never `import { expect } from \"vitest\"`\n- Tests use `.test.ts` naming\n- Excludes `*.worker.test.ts` from vitest config\n\n## TESTING\n\n- Does NOT extend `vitest.shared.ts`\n- Hook timeout: 60s, retry: 2\n- Global setup starts mock npm registry, installs local package to temp dir\n- Test helper: custom `test` fixture with `tmpPath`, `seed()`, `vitestRun()`, `vitestDev()`\n- Fixtures in `fixtures/vitest-plugin-examples/` (20+ sub-fixtures testing KV, R2, D1, DO, Queues, `cloudflare.config.ts`, etc.)\n- Skipped on Windows CI due to flakiness\n","packages/vitest-plugin/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2FREADME.md -->","packages/vitest-plugin/src/worker/lib/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Fsrc%2Fworker%2Flib%2FREADME.md -->","packages/vitest-plugin/test/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Ftest%2FREADME.md -->","packages/workers-auth/AGENTS.md":"# AGENTS.md — workers-auth\n\nOAuth-2.0-with-PKCE flow against Cloudflare's `dash.cloudflare.com` (or staging /\ncustom-overridden) endpoints. Used by wrangler and (in future) other Cloudflare\nCLIs. Internal-only — published as `prerelease: true`.\n\n## STRUCTURE\n\n- `src/pkce.ts` — PKCE code-verifier / code-challenge generation (RFC 7636)\n- `src/errors.ts` — `ErrorOAuth2` class hierarchy + `toErrorClass` mapper\n- `src/generate-auth-url.ts` — authorize URL builder\n- `src/generate-random-state.ts` — CSRF state generator\n- `src/env-vars.ts` — `WRANGLER_*` and `CLOUDFLARE_AUTH_*` env-var getters\n- `src/account-id.ts` — `validateAccountId(id, source)`, applied to every user-supplied account ID (`CLOUDFLARE_ACCOUNT_ID`, the consumer's `account_id` config field) before it reaches an API URL path\n- `src/access.ts` — Cloudflare Access detection + service-token / `cloudflared` headers\n- `src/config-file/auth.ts` — the `AuthConfigStorage` / `UserAuthConfig` storage contract (interfaces only). The default plaintext credential implementation lives alongside the credential-store layer at `src/credential-store/file-store.ts` (see \"Credential storage\" below). The core `src/core/auth-config-file.ts` (`createAuthConfigFileHelpers({getConfigPath, format})`) and `src/core/file-storage.ts` (`createFileStorage(format, getPath)`) build the per-profile path helpers and non-credential file stores; each CLI descriptor (`src/wrangler/auth-config-file.ts`, `src/cf/auth-config-file.ts`) binds them to its config dir + `FileFormat` and re-exports `createTomlFileStorage` / `createJsonFileStorage`, `getAuthConfigFilePath`, etc. from its entrypoint. See \"CORE LAYER\" below.\n- `src/config-file/temporary.ts` — `TemporaryAccountStorage` / `TemporaryPreviewAccount` storage contract for the temporary-preview-account flow\n- `src/config-file/index.ts` — generic `ConfigStorage<T>` interface shared by the auth and temporary-account contracts\n- `src/state.ts` — `readStoredAuthState()` + `StoredAuthState` shape\n- `src/token-exchange.ts` — auth-code → token + refresh-token rotation + `fetchAuthToken`\n- `src/callback-server.ts` — local HTTP server for the OAuth callback (listens on the host/port from the consumer's `redirectUri`)\n- `src/device-flow.ts` — `getOauthTokenViaDeviceFlow(options, ctx)`: the OAuth 2.0 Device Authorization Grant (RFC 8628) used by `login({device: true})` when the browser cannot reach the local callback URL. No callback server; prints the verification URL + user code and polls `/oauth2/token`. Every user-facing string is parameterised by `ctx.cliDisplayName` / `ctx.deviceLoginCommand` so the module carries no per-CLI branding. Both endpoints' bodies are narrowed before use (`asDeviceAuthorizationResponse`, `pollDeviceToken`'s `DevicePollResult`) rather than cast — an intermediary's envelope or a 2xx without a grant must produce a reportable `unexpected`/unusable-response error, never `undefined` arithmetic. `slow_down` / 5xx / 429 / unparseable bodies keep the loop alive; the last such failure is reported in place of the generic timeout if the deadline passes\n- `src/generate-device-auth-url.ts` — `generateVerificationUrl` (fallback `verification_uri_complete` builder for servers that omit it, RFC 8628 §3.3.1) + `assertTrustedVerificationUrl`, which rejects any server-supplied verification URL that is not `https:` on exactly the resolved auth domain (with no embedded credentials) before it is printed or handed to `openInBrowser` — the device flow is the only place this package opens a URL it did not build itself (RFC 8628 §5.4, remote phishing)\n- `src/flow.ts` — `createOAuthFlow(ctx)` factory wiring everything together\n- `src/context.ts` — `OAuthFlowContext` interface (DI surface)\n- `src/credential-store/` — opt-in OS-keyring-backed credential persistence (see below)\n- `src/test-helpers/` — MSW handlers for consumers' tests (`@cloudflare/workers-auth/test-helpers`)\n\n### Credential storage (`src/credential-store/`)\n\nPluggable credential persistence layer that consumers can wire into the\nOAuth flow via `ctx.storageFactory`. Default backend is the plaintext\nTOML file (`FileCredentialStore`); an opt-in `EncryptedFileCredentialStore`\nwrites AES-256-GCM-encrypted credentials to a sibling `.enc` file using a\nkey held in the OS keyring. Every store is profile-aware: the file path,\nthe encrypted `.enc` path, and the keyring account name are all derived from\n`resolveAuthProfileBaseName(profile)` (default profile → environment-based\nname; named profile → the profile name), so each auth profile gets its own\nfiles and its own encryption key.\n\n- `interface.ts` — `CredentialStore` interface (extends `AuthConfigStorage` with `kind` and `describe()`)\n- `file-store.ts` — `FileCredentialStore` (plaintext TOML, default)\n- `encrypted-file-store.ts` — `EncryptedFileCredentialStore` + plaintext-TOML migration\n- `crypto.ts` — AES-256-GCM `encryptString` / `decryptString` helpers\n- `resolver.ts` — `createCredentialStorageContext({...})` factory; returns `{ storageFactory, getActiveStore }` (both take an optional `profile`) for the consumer to plug into `createOAuthFlow` (as `ctx.storageFactory`) and `whoami`-style reporting respectively\n- `state.ts` — module-level per-session resolver flags (one-time warnings, the Windows install-failed latch)\n- `key-providers/` — per-platform OS-keyring backends that store only the 32-byte encryption key (never the credential blob itself, so the macOS Keychain 2.5 KB item limit is never a concern):\n  - `interface.ts` — `KeyProvider` interface\n  - `mac-security.ts` — `/usr/bin/security` shell-out\n  - `linux-secret-tool.ts` — `secret-tool` shell-out (probes `libsecret-tools`)\n  - `napi-keyring.ts` — `@napi-rs/keyring` wincred binding on Windows\n  - `lazy-installer.ts` — Windows-only `npm install @napi-rs/keyring` on first opt-in\n  - `factory.ts` — `resolveKeyProvider(serviceName)` picks the right per-platform implementation\n  - `shared.ts` — account-name derivation + keyring JSON envelope encoding\n\n## DI SURFACE\n\n`createOAuthFlow(ctx)` accepts a context object:\n\n- `logger` — drop-in replacement for wrangler's logger singleton\n- `isNonInteractiveOrCI()` — whether to suppress interactive prompts\n- `openInBrowser(url)` — opens the browser to the OAuth authorize URL\n- `hasEnvCredentials()` — short-circuits refresh logic when env-based auth is set\n- `clientId` (required) — the consumer's registered OAuth app ID; `string` or\n  `() => string` for lazy (e.g. env-driven prod/staging) resolution\n- `consent` (required) — the consumer's branded granted/denied consent pages\n- `cliDisplayName` (required) — the consumer's branded name (`\"Wrangler\"`, `\"cf\"`),\n  interpolated into the device flow's \"To authorize \\<name\\>…\" copy\n- `deviceLoginCommand` (required) — the command that restarts the device flow\n  (`\"wrangler login --device\"`), quoted when a device code is denied, expires,\n  or the flow times out\n- `redirectUri` (required) — the registered redirect URI / local callback URL.\n  The callback server's listen host/port and route path are all derived from it\n  (per-call bind overrides via `LoginProps.callbackHost`/`callbackPort`)\n- `storageFactory` (required) — maps an auth profile to the consumer's\n  `AuthConfigStorage` token-persistence backend. The flow calls it with the\n  active profile on every credential access. For keyring opt-in, pass the\n  `storageFactory` from `createCredentialStorageContext(...)` rather than a raw\n  file store, so both the active profile and the encrypted-file / plaintext\n  choice are re-resolved on every credential operation.\n- `purgeOnLoginOrLogout?()` — invalidate consumer-side caches after login/logout\n- `generateAuthUrl?` / `generateRandomState?` — test overrides for deterministic\n  snapshot tests (defaults pull from `./generate-auth-url` / `./generate-random-state`)\n\n`clientId`, `consent`, `cliDisplayName`, `deviceLoginCommand`, `redirectUri`, and\n`storageFactory` are consumer-specific, so they are required rather than\ndefaulted here. Wrangler's values live in the in-package wrangler layer\n(`src/wrangler/`, see below) rather than in the `wrangler` package itself.\n\nThe wrangler layer (`src/wrangler/index.ts`, `createWranglerAuth`) wires the\ncredential-storage layer once via `createCredentialStorageContext(...)` and\nexposes the resulting `getActiveStore` (called with the active profile) as\n`getCredentialStore()` for `whoami`-style code that wants to surface the active\nstorage location.\n\n## CORE LAYER (`src/core/`) + PER-CLI DESCRIPTORS (`src/wrangler/`, `src/cf/`)\n\nThe whole CLI-facing auth layer (the machinery that used to live in\n`packages/wrangler/src/user/`) is **CLI-agnostic** and shared by every\nCloudflare CLI built on this package. It lives in `src/core/`:\n\n- `factory.ts` — `createCloudflareAuth(descriptor, ctx)`: OAuth flow wiring,\n  credential storage, config cache (`@cloudflare/workers-utils`'\n  `createConfigCache`), account selection (`fetchInternalBase` with the token\n  the flow already holds), login / logout / refresh, and `requireAuth`. Imports\n  only `@cloudflare/workers-utils`.\n- `types.ts` — `AuthContext` (the injected primitives: `logger`, optional\n  `temporaryAccountLogger` for temporary-account notices, `userAgent`, interactive\n  `prompt` / `select`, `isNoDefaultValueProvidedError`) and\n  `CliDescriptor` (everything that varies per CLI: `cliName` (the executable),\n  `displayName` (branded name used in prose), auth command names\n  (`login` / `logout` / `whoami` / `createProfile` / `deviceLogin`),\n  `keyringServiceName`,\n  `clientId`, `consent`, `redirectUri`, `useDeviceFlowByDefault`,\n  `getConfigPath`, `fileFormat`,\n  `accountCachePrefix`, `cacheNamespace`, `getConfigFileLabel`,\n  `getDefaultScopeKeys`, …).\n- `file-storage.ts` (`createFileStorage(format, getPath)`), `auth-config-file.ts`\n  (`createAuthConfigFileHelpers({getConfigPath, format})`), `preferences.ts`\n  (`createPreferences(getConfigPath)`), `profile-store.ts`\n  (`createCloudflareProfileStore`), `keyring-preference.ts`\n  (`createKeyringPreference`), `scopes.ts` (shared Cloudflare scope catalog),\n  `file-format.ts`, `temporary-terms.ts`.\n\n**File format** is the `FileFormat` axis (`src/core/file-format.ts`): a simple\n`\"toml\" | \"json\"` union (the value doubles as the file extension) plus\n`parseFile` / `stringifyFile` helpers. It's threaded through `createFileStorage`\nand the credential store (`FileCredentialStore` / `EncryptedFileCredentialStore`\n/ `resolver.ts` all take an optional `format`, defaulting to `\"toml\"` so wrangler\nis unchanged; the encrypted `.enc` sibling is format-independent). Wrangler uses\n`\"toml\"`; cf uses `\"json\"`.\n\nEach CLI is a thin **descriptor + entrypoint**:\n\n- `src/wrangler/` → `@cloudflare/workers-auth/wrangler`: `WRANGLER_CLI`\n  (TOML, wrangler's global config dir, wrangler's OAuth app / `\"wrangler\"`\n  keyring service) + `createWranglerAuth(ctx) = createCloudflareAuth(WRANGLER_CLI, ctx)`.\n  Re-exports everything wrangler's `src/user/*` imports (`createTomlFileStorage`,\n  `readUserPreferences`, `createWranglerProfileStore`, `setKeyringPreference`,\n  scopes, `getClientIdFromEnv`, `OAUTH_CALLBACK_URL`, …) — no re-export shim\n  files remain in `wrangler/src/user/`.\n- `src/cf/` → `@cloudflare/workers-auth/cf`: `CF_CLI` (JSON files under\n  `~/.config/cloudflare`, the `\"cloudflare\"` keyring service, `CLOUDFLARE_CLIENT_ID`)\n  - `createCfAuth(ctx)`. OAuth-app values (client ID `cbca97e7-…`, callback port\n    8877, `cf-oauth-consent-*` pages, scoped-token-only auth) mirror the `cf`\n    CLI's registration, and device authorization is its default interactive\n    login flow. cf carries its own scope policy (`src/cf/scopes.ts`): the raw\n    client registration is kept separate from the known-grantable catalog used\n    for validation and types, and sensitive requestable scopes can be excluded\n    from login defaults. Requestable scopes must both appear in the client\n    registration and resolve in the consent service's Bach catalog; registered\n    exceptions stay explicit negative regressions. Retain separately verified,\n    grandfathered legacy scopes and registration order.\n    This is distinct from wrangler's smaller `src/core/scopes.ts` key →\n    description map, so cf does not re-export `DefaultScopes`.\n\n## CONVENTIONS\n\n- License: dual MIT/Apache-2.0. Files derived from\n  [BitySA/oauth2-auth-code-pkce](https://github.com/BitySA/oauth2-auth-code-pkce)\n  carry the Apache-2.0 header.\n- No `console.*` — use the injected `ctx.logger`. Temporary-account notices\n  (terms notice, proof-of-work, \"Temporary account ready\") go through the\n  `temporaryAccountLogger` instead, so a CLI can keep them off stdout.\n- No global `fetch` — use undici's `fetch`.\n- `UserError` instances must carry stable `telemetryMessage` labels\n  (`<area> <sub-area> <failure>`, e.g. `user oauth invalid scope`).\n  These labels are part of the telemetry contract — preserve them verbatim.\n- No direct Cloudflare REST API calls. This package talks to OAuth endpoints\n  (`/oauth2/auth`, `/oauth2/token`, `/oauth2/revoke`) only.\n- OAuth callback server listens on the host/port derived from the consumer's\n  required `ctx.redirectUri`; override the bind address per-call via\n  `LoginProps.callbackHost` / `callbackPort`.\n\n## BUILD\n\n- tsup: two entry points — `src/index.ts` and `src/test-helpers/index.ts`\n- ESM-only output to `dist/`\n- `@cloudflare/*`, `undici`, `msw`, and `vitest` are kept external\n\n## CREDENTIAL STORAGE NOTES\n\n- The encrypted file uses `AES-256-GCM` via `node:crypto` (no third-party\n  crypto deps). The 12-byte IV is generated fresh per write; the 16-byte\n  GCM auth tag is verified on every read.\n- The keyring entry holds only a 32-byte AES key wrapped in a small JSON\n  envelope (`{v, key, created}`). It's well under the macOS Keychain ~2.5 KB\n  per-item limit no matter how the credential schema grows.\n- `@napi-rs/keyring` (the Windows backend's native binding) is installed\n  lazily on first opt-in via `npm install` into `<configPath>/native/keyring/`,\n  where `configPath` is the consumer-provided global config directory (see\n  `getConfigPath` below) — so each CLI's binding lives under its own config dir.\n  Pinned to `PINNED_KEYRING_VERSION` so CI users running\n  `npm install -g @napi-rs/keyring` by hand get the same version as the\n  lazy-install path.\n- The credential files (`.toml` / `.enc`) and the keyring install dir are all\n  rooted at the consumer's config directory. `@cloudflare/workers-auth` never\n  resolves that path itself (wrangler and a future `cf` CLI use different global\n  config paths); instead the consumer passes `getConfigPath: () => string` into\n  `createCredentialStorageContext`, and the path helpers\n  (`getAuthConfigFilePath` / `getEncryptedAuthConfigFilePath` /\n  `getKeyringInstallDir`) and store constructors all take it explicitly.\n- The consumer's `createCredentialStorageContext` call captures `serviceName`,\n  `getConfigPath`, `isKeyringEnabled`, `logger`, `isNonInteractiveOrCI`, and\n  `loginCommand` in a closure. The returned `storageFactory(profile)` re-resolves\n  the active store on every call so the active profile, `--use-keyring` /\n  `--no-use-keyring`, and the `CLOUDFLARE_AUTH_USE_KEYRING` env var all take\n  effect without rebuilding the OAuth flow. Per-session memoization flags\n  (`hasWarnedAboutKeyringFallback`, `installFailedThisSession`, ...) still\n  live at module scope in `state.ts`; tests use\n  `resetCredentialStorageState` to clear them between cases and\n  `setKeyProviderFactoryForTesting` to swap in stubs.\n","packages/workers-auth/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-auth%2FREADME.md -->","packages/workers-playground/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-playground%2FREADME.md -->","packages/workers-shared/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2FREADME.md -->","packages/workers-shared/asset-worker/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Fasset-worker%2FREADME.md -->","packages/workers-shared/router-worker/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Frouter-worker%2FREADME.md -->","packages/workers-utils/AGENTS.md":"# AGENTS.md — workers-utils\n\n## OVERVIEW\n\nShared utility package used across wrangler, miniflare, and others. Two main areas: config validation and test helpers.\n\n## STRUCTURE\n\n- `src/config/` — Configuration types, validation, normalization\n  - `validation.ts` — The config normalizer (large file). Central to all wrangler config processing.\n  - `environment.ts` — Environment/config field definitions (many deprecated fields)\n  - `config.ts` — Config types\n- `src/test-helpers/` — Shared test utilities used across packages\n- `src/types.ts` — Shared type definitions\n\n## KEY EXPORTS\n\n### Config\n\n- Validation pipeline normalizes wrangler.json/toml into typed config objects\n- Used by wrangler for all config loading\n\n### D1 migrations\n\n- `getD1MigrationFiles({ projectPath, migrationsDir, migrationsPattern })` — shared glob-based discovery used by Wrangler and the Vitest plugin. Honour `migrations_pattern` rather than recursively collecting every `.sql` file.\n\n### Shared runtime utilities\n\n- `createConfigCache(logger)` — file-backed JSON config cache (node_modules/.cache or `.wrangler/cache`). Generic mechanism; the consumer passes its logger (this package has no logger singleton). Both `wrangler` (`src/config-cache.ts`) and `@cloudflare/workers-auth` build their own instances.\n- `openInBrowser(url, logger)` — opens the `open` package with a graceful copy-paste fallback when no browser opener is available. Logger is a parameter, not imported.\n- `isInteractive()` / `isNonInteractiveOrCI()` / `isCI()` — TTY / CI detection (the TTY check is inlined here to avoid a cycle back through `@cloudflare/cli-shared-helpers`). `isCI()` keys off CI specifically (ignoring TTY), for behaviour like redacting account names in public CI logs. These read `ci-info`, which is bundled into consumers' distributables. Because a bundled `ci-info` is an unmockable separate instance (and reads the real environment), consumers that need to fake CI in their tests mock **this package's** exports rather than `ci-info` — e.g. wrangler's `vitest.setup.ts` mocks `@cloudflare/workers-utils` so `isInteractive`/`isNonInteractiveOrCI`/`isCI` delegate to the mockable `ci-info`, which reaches both wrangler-source and bundled `@cloudflare/workers-auth` consumers (since `@cloudflare/*` is external in workers-auth's bundle).\n\n### Test Helpers\n\n- `runInTempDir()` — Creates temp dir, chdir's into it, stubs HOME/XDG_CONFIG_HOME, cleans up\n- `seed(files)` — Writes `Record<string, string>` of path->content into temp dir\n- `writeWranglerConfig()` / `readWranglerConfig()` — Mock wrangler config files (TOML, JSON, JSONC)\n- `mockConsoleMethods()` — Spies on console, returns normalized output with `.debug`, `.out`, `.info`, `.err`, `.warn`\n- `normalizeString()` — Multi-stage pipeline: strips timings, thin spaces, temp dirs, normalizes slashes/cwd/dates/tables/error markers/byte values, and scrubs the OAuth authorize URL's random `state` / `code_challenge` query params to `<OAUTH_STATE>` / `<OAUTH_CODE_CHALLENGE>` (so login-URL snapshots stay deterministic without mocking the URL builder)\n\n## NOTES\n\n- `validation.ts` is the largest single file in the monorepo after generated code — changes here affect all config processing\n- Many deprecated fields in `environment.ts` — check `@deprecated` annotations before modifying\n- Test helpers imported as `@cloudflare/workers-utils/test-helpers` across packages\n","packages/workers-utils/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2FREADME.md -->","packages/workers-utils/src/config/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2Fsrc%2Fconfig%2FREADME.md -->","packages/workflows-shared/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkflows-shared%2FREADME.md -->","packages/wrangler/AGENTS.md":"# Wrangler — Agent Guide\n\nWrangler-specific context only. See root `AGENTS.md` for monorepo conventions.\n\n## Overview\n\nMain CLI for Cloudflare Workers. ~2k-line yargs command tree in `src/index.ts`. Entry point is `src/cli.ts` (NOT `src/index.ts`).\n\n## Structure\n\n- `src/` — CLI source\n- `src/__tests__/` — Unit tests, helpers in `src/__tests__/helpers/`\n- `e2e/` — E2E tests, requires Cloudflare credentials\n- `bin/wrangler.js` — Shim that spawns Node to run `wrangler-dist/cli.js`, forwarding stdio and IPC\n- `bin/cf-wrangler.js` — `cf-wrangler` delegate entrypoint. Owns verb dispatch, argv parsing (`parseCfWranglerArgs`), and the `StartDevOptions` literal; hands off to `runCfWranglerDev` from `wrangler-dist/cli.js` in-process (no re-spawn — the parent tool owns the Node runtime)\n- `src/containers/ssh.ts` — Thin command adapter; SSH options, authorization request, and transport live in `@cloudflare/containers-shared/src/ssh.ts`, shared with cf.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint (see below)\n- `src/containers/images.ts` — Command adapter; registry image operations live in `containers-shared/src/registry-images.ts`, shared with cf.\n- `templates/` — Worker templates\n\n## Entry Points\n\n- `src/cli.ts` — Build entry AND library API surface (dual-purpose). Calls `main()` when run directly; re-exports `./api` when imported as library. Also re-exports `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, `ArgParseError`, `runCfWranglerDev`, and `runCfWranglerBuild` for the `cf-wrangler` bin to call in-process.\n- `src/index.ts` — Yargs CLI tree builder (large file). Exports `main()`. NOT the package entry point despite the name.\n- `src/api/index.ts` — Public programmatic API barrel.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint, an experimental escape hatch for projects that can't use `@cloudflare/vite-plugin`. It exposes `dev` + four flags (`--mode`, `--port`, `--host`, `--local`) and `build` + `--mode`; the wrangler config file is found via wrangler's standard discovery (no `--config` flag). Preview build context is supplied through `CLOUDFLARE_PREVIEW_BUILD`, matching framework-owned build commands. It is NOT a separate package and does NOT use the `unstable_dev` test harness. It shares its spawn contract (verb dispatch, flag vocabulary, exit-2 feature detection) with the sibling `cf-vite` delegate in `@cloudflare/vite-plugin`. `bin/cf-wrangler.js` owns verb dispatch, argv parsing, and the `StartDevOptions` literal; `src/cf-wrangler/dev.ts` (exported as `runCfWranglerDev`) wraps `startDev` in the experimental-flags context and waits for teardown. `src/cf-wrangler/build.ts` (exported as `runCfWranglerBuild`) runs the Build Output Specification path used by `wrangler build --experimental-new-config --experimental-cf-build-output`, producing `.cloudflare/output/v0`. `src/cf-wrangler/args.ts` (exported as `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, and `ArgParseError`) does the strict argv parse. The \"unknown subcommand\" error doubles as a feature-detection signal for the parent CLI.\n\n## Conventions (Wrangler-Specific)\n\n- No `console.*` — use `logger` singleton\n- No `__dirname` / `__filename` — use `getBasePath()`\n- No global `fetch` — use undici's fetch\n- Route Cloudflare v4 API calls through the existing `cfetch` helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult` when possible;\n  do not use global or undici `fetch` directly. Prefer these helpers over\n  adding or passing the `cloudflare` package solely for a simple request, and\n  use the Cloudflare TypeScript SDK when its generated API surface or behavior\n  is materially useful.\n- `telemetryMessage` values for `UserError`-compatible errors must be static, safe labels. Do not use `telemetryMessage: true` unless 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: true` is usually less useful because user-facing copy is harder to group and parse than a stable telemetry label.\n- Format `telemetryMessage` values as lower-case phrases: `<service or area> <command or sub-area> <failure>`, for example `kv namespace binding not found in config`, `r2 object put file not found`, or `pages deploy project name missing`.\n- 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.\n\n## Build\n\n- tsup: single entry `src/cli.ts` → `wrangler-dist/cli.js`\n- `package.json` `main` points at `wrangler-dist/cli.js`\n- Custom `embedWorkersPlugin()` bundles Worker templates via esbuild for tests\n\n## Testing\n\n- Pool: `\"forks\"` (not threads) — heavy global mocking\n- `runWrangler(cmd)` calls `main()` in-process (no subprocess)\n- MSW for API mocking — pre-built handlers per API domain in `src/__tests__/helpers/msw/`\n- Shared helpers: `runInTempDir()`, `mockAccountId()`, `mockApiToken()`, `mockConfirm()`, `mockPrompt()`, `mockSelect()`, `captureRequestsFrom()`\n- Unit timeout: 50s, retry: 0. Note: wrangler's `vitest.config.mts` does NOT use `mergeConfig` with `vitest.shared.ts`, so shared defaults (timeouts, retry, etc.) are not inherited — they must be set explicitly in the wrangler config.\n- E2E timeout: 90s, bail: 1, singleThread\n- `globals: true` for vitest globals\n- Output normalization via `normalizeString()` pipeline\n\n## Anti-Patterns\n\n- Test files use `.test.ts` (not `.spec.ts`)\n- Never import `expect` from vitest — use test context `({ expect }) => {}`\n  - When adding `expect` as a parameter to helper functions, check ALL call sites (e.g., across `deployments.test.ts`, `versions.test.ts`)\n","packages/wrangler/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2FREADME.md -->","packages/wrangler/e2e/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fe2e%2FREADME.md -->","packages/wrangler/src/pages/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fsrc%2Fpages%2FREADME.md -->","tools/README.md":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=tools%2FREADME.md -->"},"items":[{"name":"AGENTS.md","path":"AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/AGENTS.md","title":"AI Agent Protocol & Instructions","category":"root-instruction","format":"markdown","content":"# AGENTS.md\n\nThis file helps AI coding agents work effectively in the Cloudflare Workers SDK\nmonorepo. Prefer authoritative configuration and documentation over copying\ndetails into this file: copied versions, rule lists, and counts become stale.\n\n## Start Here\n\n- Use `pnpm`, not npm or yarn.\n- Use the Node.js and pnpm versions declared in `package.json`.\n- Install dependencies with `pnpm install`.\n- Run commands from the workspace root unless package documentation says\n  otherwise.\n- Before changing a package, read its `AGENTS.md` if it has one.\n- Do not edit generated files directly. Change their source or generator and\n  regenerate them.\n\n## Common Commands\n\nThe root `package.json` is authoritative for available scripts.\n\n- `pnpm build` — build the workspace with Turbo.\n- `pnpm test:ci` — run tests in CI mode.\n- `pnpm test:e2e` — run end-to-end tests; many require Cloudflare credentials.\n- `pnpm check` — run the repository's validation, lint, type, and format checks.\n- `pnpm fix` — apply supported lint and formatting fixes.\n- `pnpm prettify` — format files with oxfmt.\n- `pnpm run <script> --filter <package>` — run a Turbo task for one package.\n- `pnpm -w test:ci -F <package> -- <test-file>` — run a package's specific test\n  file when its test configuration supports it.\n\nPrefer the narrowest relevant test while developing, then run the broader\npackage checks appropriate to the change. Do not run credentialed E2E tests\nunless the task and environment support them.\n\n## Repository Map\n\n| Task                                        | Location                                                              | Notes                                                         |\n| ------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |\n| Add or modify a Wrangler command            | `packages/wrangler/src/`                                              | Commands are registered from `src/index.ts`.                  |\n| Change local development behavior           | `packages/miniflare/src/`                                             | `src/index.ts` contains the main `Miniflare` class.           |\n| Modify embedded runtime workers             | `packages/miniflare/src/workers/`                                     | Worker scripts use `worker:` virtual imports.                 |\n| Change project scaffolding                  | `packages/create-cloudflare/`                                         | Templates and framework support live here.                    |\n| Change the Vite integration                 | `packages/vite-plugin-cloudflare/`                                    | Includes package-specific playgrounds.                        |\n| Change the Vitest integration               | `packages/vitest-plugin/`                                             | Vitest integration for tests running in workerd.              |\n| Change shared config handling               | `packages/workers-utils/src/config/`                                  | Shared types, normalization, and validation.                  |\n| Use shared test helpers                     | `packages/workers-utils/src/test-helpers/`                            | Includes temporary-directory and console helpers.             |\n| Change deploy or versions-upload validation | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | Keep deploy and versions-upload behavior aligned.             |\n| Add a fixture                               | `fixtures/`                                                           | Fixtures are workspace members with their own `package.json`. |\n| Change CI                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the main test workflow.               |\n| Change deployment tooling                   | `tools/deployments/`                                                  | Scripts run directly through `esbuild-register`.              |\n| Create a changeset                          | `.changeset/README.md`                                                | Read this file before deciding whether one is required.       |\n\nTurbo orchestrates workspace tasks. Shared TypeScript configuration lives in\n`packages/workers-tsconfig/`; lint and formatting behavior is defined by\n`.oxlintrc.jsonc`, `.oxfmtrc.jsonc`, and `packages/lint-config-shared/`.\n\n## Cross-Tool Development Features\n\nWrangler, the Vite plugin, and the Vitest plugin are all consumers of the\nWorkers development platform. A development feature is not complete merely\nbecause it works through one of them.\n\nImplement development features in Miniflare wherever possible so that every\nconsumer benefits from the same behavior. Keep the integration layers in\nWrangler, the Vite plugin, and the Vitest plugin thin instead of implementing\nequivalent behavior independently in each tool. If Miniflare is not the\nappropriate layer, put shared behavior in the lowest suitable shared package.\n\nWhen adding or changing development functionality:\n\n- assess its impact on Miniflare, Wrangler, the Vite plugin, and the Vitest\n  plugin;\n- update shared configuration types, validation, and runtime behavior where\n  applicable;\n- add coverage at the shared implementation layer; add consumer-specific tests\n  when the consumer's integration or behavior is affected;\n- document intentional differences or unsupported consumers in the change and\n  pull request.\n\n## Implementation Conventions\n\nThe checked-in configuration is authoritative. Run `pnpm check` rather than\nrelying on a duplicated list of every enforced rule. In particular:\n\n- Keep TypeScript strictly typed. Avoid `any`, non-null assertions, and floating\n  promises.\n- Use type-only imports where appropriate and `node:` prefixes for Node.js\n  built-ins.\n- Prefer function declarations for named or exported functions.\n- Add well-formatted JSDoc to exported or public functions and to functions whose\n  purpose is not evident, including useful tags such as `@param` and `@returns`\n  where appropriate.\n- Comments should explain why; do not add comments that merely restate code.\n- Lint-disable comments require a reason after `--`.\n- In Wrangler, use the logger rather than calling `console.*` directly, except\n  inside the logger implementation.\n- For Cloudflare v4 API calls, prefer the existing request helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult`. Reuse or inject\n  these helpers in shared packages rather than adding the `cloudflare` package\n  solely for a simple request. Use the Cloudflare TypeScript SDK when its\n  generated API surface or behavior is materially useful.\n- Import `ci-info` through its default export.\n\noxfmt determines whitespace, quoting, import order, and package.json sorting.\nDo not reproduce those rules manually; run `pnpm prettify`.\n\n## Dependencies and Security\n\n- Packages normally bundle their dependencies. The repository validator in\n  `tools/deployments/validate-package-dependencies.ts` is authoritative.\n- A package that must leave a dependency external declares it in that package's\n  `scripts/deps.ts` as part of `EXTERNAL_DEPENDENCIES`, with an explanation.\n- After changing dependencies, run `pnpm install` so that the lockfile is\n  updated.\n- Do not build shell commands with interpolated or concatenated untrusted input.\n  The custom `workers-sdk/no-unsafe-command-execution` oxlint rule enforces the\n  repository's command-execution constraints.\n\n## Testing Conventions\n\n- Use Vitest for unit and integration tests.\n- Use fixtures for filesystem and Worker scenarios; treat fixtures as\n  user-facing examples and keep them clear and realistic.\n- Use the Vitest plugin when behavior must be tested in workerd.\n- In Vitest tests, obtain `expect` from the test context rather than importing\n  it from `vitest`. Pass `ExpectStatic` to helpers that need it; use\n  `node:assert` where test context is unavailable.\n- Prefer `runInTempDir()` and real filesystem operations over filesystem mocks.\n- Use `mockConsoleMethods()` to capture output and assert against its `out`,\n  `err`, and `warn` properties.\n- Update relevant snapshots when changing user-facing output.\n- New examples under `fixtures/vitest-plugin-examples/` need a\n  `tsconfig.json`.\n\nThe shared defaults are defined in `vitest.shared.ts`; package configurations\nmay override them.\n\n## Changes and Pull Requests\n\n- Work on a branch rather than committing directly to `main`.\n- Read `.changeset/README.md` to determine whether a changeset is required and\n  how to write it. Do not assume every package-code change needs one.\n- Use `.github/PULL_REQUEST_TEMPLATE.md` when preparing a pull request.\n- The PR description requirements are enforced by\n  `tools/deployments/validate-pr-description.ts`; treat that validator and the\n  template as authoritative.\n- Use the repository's established `[package] description` PR-title style.\n- Run the relevant tests and checks locally before pushing.\n\n## Package-Specific Guidance\n\nMany packages provide their own `AGENTS.md`. Locate and read the closest\napplicable file before making changes. When a change makes guidance inaccurate,\nupdate that file in the same change. Put package-specific knowledge in the\npackage's file; keep this root file focused on repository-wide workflow and\nnavigation.\n","isInternal":false,"tokens":1851,"sizeBytes":9450},{"name":"CLAUDE.md","path":"CLAUDE.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/CLAUDE.md","title":"Claude Agent Guidelines & System Prompt","category":"claude-rule","format":"markdown","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","isInternal":false,"tokens":33,"sizeBytes":132},{"name":"issue-review.md","path":".github/skills/issue-review.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/.github/skills/issue-review.md","title":"github-issue-review","category":"anthropic-skill","format":"markdown","content":"---\nname: github-issue-review\ndescription: Triage a GitHub issue on cloudflare/workers-sdk. Assesses quality, identifies the component, checks for duplicates, and recommends next steps.\n---\n\n# GitHub Issue Triage Skill\n\nThis skill triages a GitHub issue to assess its quality, identify the affected component, and recommend next steps for the maintainers.\n\n**Important:** This skill runs without bash or network access. All analysis is based on the pre-fetched issue data in `context.json`. Use only `read`, `glob`, `grep`, `edit`, and `write` tools.\n\n## Input\n\nPre-fetched issue data at `data/<issue_number>/context.json` containing the full issue details from the GitHub API (title, body, comments, labels, author, dates).\n\n## Triage Process\n\nPerform the following steps in order. **Stop and skip to Output as soon as you have sufficient evidence for a recommendation.**\n\n### Step 1: Load Issue Details\n\nRead the pre-fetched `context.json` file using the `read` tool.\n\nExtract and note:\n\n- Title and description\n- Issue type (bug report vs feature request vs question)\n- Product/component affected\n- Version reported against (if any)\n- Operating system (if any)\n- Reproduction steps or reproduction link (if any)\n- Error messages (if any)\n- Comment count and any relevant comment content\n- Labels currently applied\n- Issue age (created date) and last activity date\n- `state_reason` if the issue is already closed\n\n### Step 2: Check for Closeable Issues\n\nCheck each of the following categories in order. **STOP at the first match** and skip to Output.\n\n> **Note:** The `state_reason` values in this section (`completed`, `not_planned`) are informational — they indicate the appropriate GitHub close reason for maintainer reference. They are not captured as a field in the output report.\n\n#### 2a: Spam or Junk\n\nRecommend **CLOSE** (state_reason: `not_planned`, no comment needed) if:\n\n- The body contains random characters, test text, or nonsensical content (e.g. \"bhhg\", \"ssssssssss\", \"aloll\")\n- The issue is clearly spam (e.g. loan advertisements, SEO spam, unrelated product promotions)\n- The issue is a blank/empty test issue (e.g. title is \"test\" with no meaningful body)\n- The body is entirely empty or contains only template headers with no content filled in\n\n#### 2b: Reporter Confirmed Resolved\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The reporter explicitly confirmed the issue is resolved in comments\n- The reporter said they found a workaround and no longer need a fix\n- A maintainer indicated it should be closed in comments\n\n#### 2c: Already Fixed in a Prior Release\n\nRecommend **CLOSE** (state_reason: `completed`) if, based on references within the issue comments or linked PRs:\n\n- A comment references a PR or release that addresses this issue\n- The issue describes a bug that was fixed in a version newer than the reporter's version\n- The issue's symptoms match a fix described in a linked PR or comment\n\nWhen closing, cite the specific PR number and release version if known.\n\n**Template:**\n\n> This issue has been fixed in PR #XXXX, which was released in **wrangler X.Y.Z** (or the relevant package version). Please update and let us know if you're still seeing the issue.\n\nOr for older issues where the fix can't be pinpointed:\n\n> This is a fairly old issue, and from testing with the latest version, it appears to have been resolved. I'm going to close it for now — if you're still running into problems on the latest version, feel free to open a new issue with more details and we can investigate further.\n\n#### 2d: Duplicate\n\nRecommend **CLOSE** (state_reason: `not_planned`) if a comment or linked reference in the issue identifies it as a duplicate of another issue — for example, a maintainer has already commented pointing to a canonical issue, or the reporter themselves links to an existing report.\n\nWhen closing, link to the canonical issue.\n\n**Template:**\n\n> Closing as a duplicate of #XXXX. Please follow that issue for updates.\n\nIf the duplicate is in another repo:\n\n> I'm closing this as a duplicate of <owner/repo>#XXXX, which is where this is being tracked.\n\n#### 2e: Not workers-sdk / Wrong Repo\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes Workers **runtime** behavior (fetch API quirks, V8 issues, compatibility flags, crypto APIs) — belongs in [cloudflare/workerd](https://github.com/cloudflare/workerd)\n- The issue is about a third-party framework (Nuxt, SvelteKit, Remix, Hono, React Router) and the bug is in that framework's code, not in Wrangler or the Vite plugin\n- The issue is about an upstream tool (esbuild, Bun, Vite core) rather than Cloudflare's integration\n- The issue is an account/billing/abuse problem — belongs in Cloudflare Support\n\n**Templates:**\n\nFor framework issues:\n\n> It looks like this issue is coming from <framework>, rather than from workers-sdk. I'd recommend opening an issue on that project's repo: <link>. If it turns out to be a workers-sdk issue after all, feel free to open a new issue here with more details.\n\nFor runtime issues:\n\n> This looks like a Workers runtime issue rather than a tooling issue. The right place to track this is [cloudflare/workerd](https://github.com/cloudflare/workerd) — could a maintainer transfer this issue there?\n\n(Set Action field to: \"Transfer to cloudflare/workerd, then post this comment.\")\n\nFor account/support issues:\n\n> Unfortunately, we're unable to provide support for account-level issues via GitHub. Please contact Cloudflare Support at https://dash.cloudflare.com/?to=/:account/support or the email address mentioned in the error message.\n\n#### 2f: Stale / No Response\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue has the `awaiting-response:reporter` or `needs-reproduction` label AND the last activity was >30 days ago\n- The issue is >12 months old with no activity in the last 6 months\n- A maintainer asked for a reproduction or clarification and the reporter never responded\n\n**Template:**\n\n> We haven't heard from you in a while so I'm going to close this issue for now. If you're still running into problems, feel free to open a new issue with more details and we can investigate further.\n\nFor very old issues:\n\n> This is a very old issue so I'm going to close it for now. If you're still running into problems on the latest version, feel free to comment with more details and we can investigate further.\n\n#### 2g: Transient Platform Issue\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The issue describes a one-time API error (500, 503, auth failures) that appears to have been a service incident\n- Multiple users reported the same error around the same time, and it has since stopped\n- The error is from Cloudflare's API (not from Wrangler itself) and there's no way to fix it in workers-sdk\n\n**Template:**\n\n> This was a transient API issue, and should be resolved now. If you're still seeing this error, please open a new issue with the latest details and we can investigate further.\n\nOr for old transient issues:\n\n> This appears to have been a transient server-side API issue. Similar reports were caused by Cloudflare API incidents that have since been resolved. I'm going to close this for now.\n\n#### 2h: User Error / Misunderstanding\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes expected behavior that the reporter misunderstands\n- The issue is caused by incorrect configuration, wrong SQL syntax, or misuse of an API\n- The fix is a documentation pointer rather than a code change\n\nWhen closing, explain the correct approach and link to relevant documentation. Be helpful, not dismissive.\n\n**Template:**\n\n> This isn't a bug — <brief explanation of the correct behavior>. You can find more details in the docs: <link>. I'm going to close this for now, but feel free to ask on our [Discord](https://discord.cloudflare.com) if you have more questions.\n\n#### 2i: Breaking Change\n\nRecommend **KEEP OPEN** if:\n\n- The requested change would be a breaking change in the current major version\n\nThe issue should remain open as a tracking item. Do not close it — the team hasn't decided against the change, it's deferred to a future major version.\n\n**Suggested labels:** `breaking-change`\n\n**Template:**\n\n> Changing this behavior at this stage would be a breaking change, so it will need to wait for the next major version. I've added the `breaking-change` label to track this.\n\n(Set Action field to: \"Apply `breaking-change` label, then post this comment.\")\n\n#### 2j: Won't Fix / By Design\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The behavior is intentional and documented\n- The team has explicitly decided not to implement this feature\n- The cost/complexity of the change outweighs the benefit\n\n**Templates:**\n\nFor design decisions:\n\n> This is intentional behavior — <brief explanation>. I don't think we're likely to change this in the near future, but we appreciate the feedback.\n\nFor feature requests that won't happen:\n\n> Thanks for the suggestion. We don't intend to implement this right now, but it may be revisited in future. <Optional: brief explanation of why, or pointer to an alternative approach.>\n\n#### 2k: Feature Superseded / Deprecated\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The requested feature has been implemented via a different mechanism than proposed\n- The issue relates to a deprecated feature that has a replacement\n- A newer feature or package addresses the underlying need\n\n**Template:**\n\n> This has been addressed by <feature/package>. <Brief explanation of how it solves the original request.> I'm going to close this for now.\n\n### Step 3: Check for Insufficient Information\n\nIf the issue wasn't caught by Step 2, recommend **NEEDS MORE INFO** if:\n\n- Bug report has no reproduction steps or link (the bug template requires one)\n- Bug report is missing version information\n- The description is too vague to act on (e.g. \"it doesn't work\" with no details)\n- The error message is missing or truncated\n\n**Template:**\n\n> Thanks for reporting this. Could you provide <specific missing information>? In particular:\n>\n> - <specific question 1>\n> - <specific question 2>\n>\n> A minimal reproduction (a GitHub repo or link we can clone and run) would also help us investigate. Without more details, we won't be able to look into this.\n\n**Suggested label:** `awaiting-response:reporter` (and optionally `needs-reproduction`)\n\n**STOP HERE if** the issue clearly needs more info. Skip to Output.\n\n### Step 4: Identify Component\n\nMap the issue to a package based on labels, title, and body content:\n\n| Signal                                                                           | Package                                         |\n| -------------------------------------------------------------------------------- | ----------------------------------------------- |\n| `package:wrangler` label, wrangler CLI commands, `wrangler.toml`/`wrangler.json` | `packages/wrangler`                             |\n| `package:miniflare` label, local dev simulation                                  | `packages/miniflare`                            |\n| `product:d1` label, D1 database, `d1 execute`, migrations                        | `packages/wrangler` (D1 code is in wrangler)    |\n| `package:vitest` label, worker tests, `vitest-plugin`                            | `packages/vitest-plugin`                        |\n| `package:vite-plugin` label, vite dev, `@cloudflare/vite-plugin`                 | `packages/vite-plugin-cloudflare`               |\n| `package:c3` label, `create-cloudflare`, project scaffolding                     | `packages/create-cloudflare`                    |\n| `product:pages` label, Pages deployment, `_routes.json`, `_headers`              | `packages/wrangler` (Pages code is in wrangler) |\n| `feature:workers-assets` label, static asset serving                             | `packages/wrangler`                             |\n| `product:containers` label, container registry                                   | `packages/wrangler`                             |\n| `product:workflows` label, Workflows API                                         | `packages/wrangler`                             |\n| `feature:workers-builds` label                                                   | Workers Builds (may be internal)                |\n| `python` label, Python Workers                                                   | `packages/wrangler`                             |\n| `product:workers-for-platforms` label, dispatch namespaces                       | `packages/wrangler`                             |\n| `package:kv-asset-handler` label                                                 | `packages/kv-asset-handler`                     |\n| `feature:types` label, `wrangler types` command                                  | `packages/wrangler`                             |\n| R2, KV, Queues, Durable Objects, Vectorize bindings                              | `packages/wrangler`                             |\n| `node-compat`/`nodejs-compat` label, Node.js APIs                                | May be workerd or wrangler depending on context |\n| Workers runtime behavior (not tooling)                                           | Likely belongs in cloudflare/workerd            |\n| Cloudflare dashboard, API behavior                                               | Likely a platform issue, not workers-sdk        |\n\n### Step 5: Assess Reproducibility and Severity\n\nFor **bug reports**, evaluate:\n\n- **Has reproduction?** Does the issue include a minimal repro link or clear steps?\n- **Severity estimate:** Is this a crash, data loss, incorrect behavior, or cosmetic issue?\n- **Scope:** Does it affect all users or a specific configuration?\n- **Workaround available?** Did the reporter or comments mention one?\n- **Version gap:** Is the reporter on an old version? Could updating fix this?\n\nFor **feature requests**, evaluate:\n\n- **Clarity:** Is the proposed solution clearly described?\n- **Use case:** Is the motivation explained?\n- **Scope:** Small enhancement vs large new feature?\n- **Existing alternatives:** Is there already a way to achieve this (even if less convenient)?\n\n## Output Format\n\n**How the output is used:** `report.md` is posted verbatim as a maintainer-facing triage comment on the issue (attributed to an automated bot), and the labels in `summary.json` are applied automatically. Because of this:\n\n- Write `report.md` for maintainers, not the reporter. The **Suggested Comment** section is a _draft_ for a maintainer to send to the reporter — it is **not** posted automatically, so do not phrase the surrounding report as though a reply has already been made.\n- Only put labels in the **Suggested Labels** fields that already exist in the repository. If unsure whether a label exists, omit it rather than guess — non-existent labels are dropped before applying, so inventing labels only weakens the report's accuracy.\n\n### Report Directory Structure\n\n```\n./data/<issue_number>/\n├── report.md          # Full detailed report\n└── summary.json       # Structured JSON summary\n```\n\n### Output Step 1: Write Full Report\n\nWrite the full report to `./data/<issue_number>/report.md`:\n\n```markdown\n# Issue Triage: <owner/repo>#<number>\n\n## Summary\n\n<One-line summary of the issue>\n\n## Classification\n\n- **Type:** <Bug | Feature Request | Question | Discussion>\n- **Component:** <package name or \"unknown\">\n- **Severity:** <Critical | High | Medium | Low | N/A>\n- **Has Reproduction:** <Yes (with link) | No | N/A>\n- **Quality:** <Complete | Partial | Incomplete>\n\n## Findings\n\n- **Created:** <date>\n- **Author:** <username>\n- **Version:** <reported version, or \"not specified\">\n- **Labels:** <labels, or \"none\">\n- **Comments:** <count>\n\n### Analysis\n\n<2-5 bullet points covering what you found — component identification,\nreproducibility assessment, severity reasoning, staleness indicators,\nduplicate candidates. Only include what's relevant.>\n\n## Recommendation\n\n**Status:** <CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\n\n**Reasoning:** <2-3 sentences explaining why>\n\n**Action:** <What a maintainer should do next>\n\n**Suggested Labels:** <labels to add, if any. Use existing repo labels only.>\n\n### Suggested Comment\n\n> <The exact comment to post on the issue. Follow the templates above for the\n> matching closure category. Key principles:\n>\n> - Always offer an escape hatch (\"feel free to open a new issue\")\n> - Link to specific PRs, releases, or docs when available\n> - Be concise for straightforward closures, detailed for design decisions\n> - Never be dismissive or snarky, even for spam (just close silently) or user error\n> - For NEEDS MORE INFO, ask specific questions (not generic \"please provide more details\")\n>   Omit this section entirely for spam (close without comment) or if no comment is needed.>\n```\n\n### Output Step 2: Write Summary File\n\nWrite a machine-readable summary as **JSON** to `./data/<issue_number>/summary.json`. This file is parsed by the triage workflow (to build the dashboard payload and apply labels), so it must be valid JSON with exactly these keys:\n\n```json\n{\n  \"issueNumber\": <issue_number as a number>,\n  \"title\": \"<issue title, with emoji/template prefixes like 'Bug:' removed>\",\n  \"githubUrl\": \"https://github.com/<owner>/<repo>/issues/<issue_number>\",\n  \"recommendation\": \"<CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\",\n  \"difficulty\": \"<easy | medium | hard | n/a>\",\n  \"reasoning\": \"<brief reasoning, 1-2 sentences>\",\n  \"suggestedAction\": \"<brief description of next steps>\",\n  \"hasSuggestedComment\": <true if a Suggested Comment section is present in the report, false otherwise>,\n  \"suggestedLabels\": [\"<label>\", \"...\"]\n}\n```\n\n**Key definitions:**\n\n- **issueNumber**: The issue number as a JSON number (not a string).\n- **title**: Issue title with any emoji prefixes (e.g. \"🐛 Bug:\") or template prefixes removed.\n- **githubUrl**: Full URL to the issue.\n- **recommendation**: One of `CLOSE`, `KEEP OPEN`, `NEEDS MORE INFO`, `NEEDS VERIFICATION`.\n- **difficulty**: Estimated fix difficulty — `easy`, `medium`, `hard`, or `n/a` (for feature requests or closures).\n- **reasoning**: Brief summary of why (1-2 sentences).\n- **suggestedAction**: Brief description of next steps.\n- **hasSuggestedComment**: Boolean — `true` if the report includes a Suggested Comment, `false` otherwise.\n- **suggestedLabels**: JSON array of labels to apply, matching the **Suggested Labels** field in the report. Use existing repo labels only (see above). Use an empty array `[]` if there are no labels to apply.\n\n**CRITICAL:** Write valid, parseable JSON only (no trailing commas, no comments, no surrounding markdown fences). Because JSON strings are escaped, `reasoning`/`suggestedAction` may safely contain any punctuation.\n","frontmatter":{"name":"github-issue-review","description":"Triage a GitHub issue on cloudflare/workers-sdk. Assesses quality, identifies the component, checks for duplicates, and recommends next steps."},"isInternal":false,"tokens":4157,"sizeBytes":18843},{"name":"local-explorer-diagram.md","path":".opencode/skills/local-explorer/assets/local-explorer-diagram.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/.opencode/skills/local-explorer/assets/local-explorer-diagram.md","title":"Assets Skill","category":"anthropic-skill","format":"markdown","content":"```mermaid\nflowchart TB\n\tClient[\"client\"] --> Incoming[\"incoming request\"]\n\tIncoming --> EntryA[\"entry worker\"]\n\tEntryA -->|/cdn-cgi/explorer| ExplorerA[\"explorer worker<br/>(Hono)\"]\n\n\tsubgraph Runtime[\"running Miniflare instances\"]\n\t\tdirection LR\n\n\t\tsubgraph A[\"miniflare A\"]\n\t\t\tdirection TB\n\t\t\tEntryA\n\t\t\tExplorerA\n\t\t\tFrontend[\"frontend<br/>(TanStack Router + React)\"]\n\t\t\tUserWorker[\"user worker\"]\n\t\t\tKV[\"KV, R2, D1\"]\n\t\t\tWrapper[\"wrapped<br/>DO/Workflow class\"]\n\n\t\t\tEntryA --> UserWorker\n\t\t\tExplorerA -->|disk service to serve assets| Frontend\n\t\t\tExplorerA -->|binding| KV\n\t\t\tExplorerA -->|binding| Wrapper\n\t\t\tUserWorker -->|binding| KV\n\t\t\tUserWorker -->|binding| Wrapper\n\t\tend\n\n\t\tsubgraph B[\"miniflare B\"]\n\t\t\tdirection TB\n\t\t\tEntryB[\"entry worker\"]\n\t\t\tExplorerB[\"explorer worker\"]\n\t\t\tEtc[\"etc.\"]\n\n\t\t\tEntryB --> ExplorerB\n\t\t\tExplorerB --> Etc\n\t\tend\n\tend\n\n\tFrontend -->|fetch /cdn-cgi/explorer/api| Incoming\n\tExplorerA -->|fetch /cdn-cgi/explorer/api/resource with NO_AGGREGATE_HEADER| EntryB\n\n\tsubgraph FS[\"filesystem\"]\n\t\tRegistry[\"dev registry\"]\n\t\tDOState[\".wrangler/state/durable-objects<br/>(list DOs, delete workflows, etc.)\"]\n\tend\n\n\tExplorerA -->|node loopback binding| FS\n\n\tclassDef miniflareA stroke:#f08c00,fill:#fff7ed,color:#1e1e1e;\n\tclassDef userResource stroke:#1971c2,fill:#eff6ff,color:#1e1e1e;\n\tclassDef entry stroke:#e03131,fill:#fff5f5,color:#1e1e1e;\n\tclassDef neutral stroke:#1e1e1e,fill:#ffffff,color:#1e1e1e;\n\n\tclass EntryA entry;\n\tclass ExplorerA,Frontend,Wrapper miniflareA;\n\tclass UserWorker,KV userResource;\n\tclass Client,Incoming,Runtime,FS,Registry,DOState,EntryB,ExplorerB,Etc neutral;\n```\n","isInternal":false,"tokens":509,"sizeBytes":1617},{"name":"SKILL.md","path":".opencode/skills/local-explorer/SKILL.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/.opencode/skills/local-explorer/SKILL.md","title":"local-explorer","category":"anthropic-skill","format":"markdown","content":"---\nname: local-explorer\ndescription: How to add products/resources to the local explorer or local API. Use when implementing new local APIs, or UI routes under packages/miniflare/src/workers/local-explorer or packages/local-explorer-ui.\n---\n\n# Cloudflare Local Explorer Products\n\nUse this skill when adding a new product or resource type to the local API and/or local explorer.\n\n## Start Here\n\nRead these files before editing:\n\n- `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`\n- `packages/miniflare/src/plugins/core/explorer.ts`\n- `packages/miniflare/src/plugins/core/types.ts`\n- One existing resource implementation in `packages/miniflare/src/workers/local-explorer/resources/`, preferably the product most similar to the new one\n- One matching test in `packages/miniflare/test/plugins/local-explorer/`\n\nIf there are UI changes, also read:\n\n- `packages/local-explorer-ui/src/components/Sidebar.tsx`\n- Existing route files under `packages/local-explorer-ui/src/routes/`\n- Existing product e2e tests under `packages/local-explorer-ui/src/__e2e__/`\n\n## Workflow\n\n1. Add the API surface to `packages/miniflare/scripts/openapi-filter-config.ts`.\n2. Generate Miniflare's filtered spec and backend types from a full Cloudflare OpenAPI spec:\n\n```bash\nOPENAPI_INPUT_PATH=<path-to-full-openapi-spec> pnpm --dir packages/miniflare generate:api\n```\n\n3. Inspect `packages/miniflare/src/workers/local-explorer/openapi.local.json` and generated types. If the generated schemas include fields local explorer will not support, add ignores in `openapi-filter-config.ts` and regenerate.\n4. The explorer worker should have access to all user resource bindings. Ensure `proxyBindings` include bindings to the new product and that `getExplorerServices()` exposes any extra bindings the explorer worker needs. Wire product bindings through `constructExplorerBindingMap()` and `constructExplorerWorkerOpts()` in `packages/miniflare/src/plugins/core/explorer.ts`.\n5. Add or extend resource binding metadata in `packages/miniflare/src/plugins/core/types.ts`.\n6. Implement handlers in `packages/miniflare/src/workers/local-explorer/resources/<product>.ts`. Make sure to account for cross-instance aggregation, if applicable.\n7. Register Hono routes in `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`.\n8. Validate request bodies and query params with generated Zod schemas from `generated/zod.gen.ts` using `validateRequestBody()` and `validateQuery()`.\n9. Return Cloudflare API envelope responses using `wrapResponse()` and `errorResponse()` from `common.ts` unless an existing endpoint for that product uses a different response shape.\n10. Add Miniflare tests in `packages/miniflare/test/plugins/local-explorer/<product>.spec.ts`.\n11. Regenerate the UI API client:\n\n```bash\npnpm --dir packages/local-explorer-ui build\n```\n\n12. Add UI routes/components. Use Kumo components for new UI. See https://github.com/cloudflare/kumo/blob/main/AGENTS.md.\n13. Add Playwright e2e tests under `packages/local-explorer-ui/src/__e2e__/<product>/` for new visible product flows.\n\n## OpenAPI Rules\n\n- Do not edit generated files like `packages/miniflare/src/workers/local-explorer/openapi.local.json` or `packages/miniflare/src/workers/local-explorer/generated/` directly.\n- Prefer upstream Cloudflare API paths when a public API exists.\n- Use `extensions.paths` in `openapi-filter-config.ts` only for local-only APIs or APIs that do not exist in the public Cloudflare API.\n- Add ignores for unsupported params, headers, request body properties, and response fields rather than pretending to support them.\n\n## Backend Patterns\n\n- Local list endpoints such as listing KV namespaces should not implement pagination as this may require cross-instance aggregation. Pagination should be supported when targeting individual resources, such as listing KV keys within a specific namespace.\n- For cross-worker aggregation, use `aggregateListResults()`, `getPeerUrlsIfAggregating()`, and `fetchFromPeer()` from `aggregation.ts`; do not hand-roll peer discovery. Add tests for both local-only behavior and aggregated behavior when the product can span multiple instances.\n- If an API needs direct filesystem access, call through the loopback service (`c.env.MINIFLARE_LOOPBACK`) to a Node.js endpoint. The local explorer API runs inside workerd, so it cannot access the host filesystem directly.\n- If an endpoint needs metadata that is not available on the runtime binding itself, put that metadata in `BindingIdMap` and pass it through `CoreBindings.JSON_LOCAL_EXPLORER_BINDING_MAP`.\n- If a product should appear in `/api/local/workers`, add it to `WorkerResourceBindings` and populate it in `constructExplorerWorkerOpts()`.\n\n## UI Patterns\n\n- The UI API client is generated from `packages/miniflare/src/workers/local-explorer/openapi.local.json` into `packages/local-explorer-ui/src/api/generated/`.\n- Sidebar resources come from `/api/local/workers`; update `LocalExplorerWorkerBindings` usage and `Sidebar.tsx` when the product should appear in navigation.\n- Add route files under `packages/local-explorer-ui/src/routes/`. TanStack Router regenerates `src/routeTree.gen.ts` during UI build/dev.\n- Preserve worker selection by carrying the `worker` search param through product links when following sidebar patterns.\n- Use Kumo for new UI components wherever possible. Do not introduce a parallel component system.\n- Do not use tailwindCSS color tokens, use Kumo color tokens instead.\n","frontmatter":{"name":"local-explorer","description":"How to add products/resources to the local explorer or local API. Use when implementing new local APIs, or UI routes under packages/miniflare/src/workers/local-explorer or packages/local-explorer-ui."},"isInternal":false,"tokens":1206,"sizeBytes":5475},{"name":"AGENTS.md","path":"packages/create-cloudflare/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/AGENTS.md","title":"Create-cloudflare Skill","category":"anthropic-skill","format":"markdown","content":"# AGENTS.md — Create Cloudflare (C3)\n\n## OVERVIEW\n\nProject scaffolding CLI for Cloudflare Workers. Main source entry: `src/cli.ts`. Bin entry: `bin/c3.js` (Node.js version gate shim).\n\n## STRUCTURE\n\n- `bin/c3.js` — Bin shim that checks Node.js version before requiring `dist/cli.js`\n- `src/cli.ts` — Main entry. Exports `main(argv)` for programmatic use\n- `templates/` — Scaffolding templates (excluded from linting and most formatting)\n- `src/wrangler/` — Wrangler config, login, and account helpers\n- `src/cf/` — Helpers for projects configured by `cloudflare.config.ts`, which use the `cf` CLI instead of Wrangler (detected with `usesCfCli`)\n- `scripts/build.ts` — esbuild-based build → `dist/cli.js`\n\n## BUILD\n\n- esbuild bundles `src/cli.ts` as CJS → `dist/cli.js`\n- `package.json` `main` and `exports[\".\"]` point at `dist/cli.js`; `bin` points at `bin/c3.js`\n- `bin/c3.js` is a plain CommonJS shim that gates on Node.js version (read from `package.json` `engines.node`) before requiring `dist/cli.js`\n\n## CONVENTIONS\n\n- `no-console: error` — use project's logging utilities\n- Templates excluded from linting (except `c3.ts` files within templates)\n- Templates excluded from formatting (except hello-world templates)\n\n## TESTING\n\n- E2E tests run across pnpm/npm (yarn/bun also supported but not in CI), Linux/Windows\n- Own vitest setup: mocks `log-update` and `@cloudflare/cli-shared-helpers/streams`\n- CI has experimental matrix for framework testing\n- Framework CI uses case shards within one test file (three normal, two experimental), controlled by `E2E_FRAMEWORK_SHARD`. Preserve coverage across every shard and keep shard selections in the test's Turbo cache inputs.\n- Whole-framework tests retain one retry for transient failures in external registries, generators, and runtime startup. Per-case allowances live in `e2e/tests/frameworks/test-config.ts`; `E2E_TEST_RETRIES=0` disables retries for local investigations. Keep recovered attempts visible in retry reports and fix their causes before reducing allowances.\n- Python/UV installed in CI for Python framework E2E tests\n","isInternal":false,"tokens":520,"sizeBytes":2106},{"name":"AGENTS.md","path":"packages/miniflare/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/miniflare/AGENTS.md","title":"Miniflare Skill","category":"anthropic-skill","format":"markdown","content":"# Miniflare — Agent Guide\n\n## Overview\n\nLocal dev simulator for Cloudflare Workers, powered by workerd runtime. Main class `Miniflare` in `src/index.ts`.\n\n## Structure\n\n- `src/index.ts` — Main `Miniflare` class, server setup, plugin orchestration, all exports\n- `src/workers/` — ~30 embedded worker scripts (D1, KV, R2, caches, etc.), built via `worker:` virtual import scheme\n- `src/workers/d1/entry.worker.ts` — D1-specific HTTP/RPC entrypoint; selects a database using binding props and adapts RPC queries to the database worker's HTTP protocol\n- `src/workers/d1/database.worker.ts` — local D1 SQLite execution, transactions, metadata, and export; protocol schemas shared with the entrypoint live in `src/workers/d1/schemas.ts`\n- `src/workers/d1/export.ts` — shared local export pragma recognition and dedicated RPC export adaptation; keeps the legacy export response separate from ordinary query contracts\n- `src/workers/shared/` — Shared utilities across embedded workers\n- `src/workers/core/dev-registry-proxy.worker.ts` — Proxy worker for cross-process service bindings via debug port RPC\n- `src/workers/core/dev-registry-proxy-shared.worker.ts` — Shared proxy logic (registry Map, DO proxy class, tail serializers)\n- `src/shared/dev-registry.ts` — Filesystem-based worker registry (chokidar watch, heartbeat, stale cleanup)\n- `src/shared/persist-root-lock.ts` — Token-safe startup serialisation for shared persistent storage\n- `src/shared/DEV_REGISTRY.md` — Full architecture doc for the dev registry\n- `src/runtime/config/generated/workerd.ts` — Generated workerd Cap'n Proto config types\n- `test/` — Tests (`.spec.ts` naming, NOT `.test.ts`)\n- `test/test-shared/` — Shared test utilities\n- `scripts/build.mjs` — Custom esbuild build script\n\n## Build\n\n- Custom `scripts/build.mjs` bundles `src/index.ts` as CJS → `dist/src/index.js`\n- Also compiles ~30 embedded worker scripts via `worker:...` virtual import scheme — each triggers a nested esbuild sub-build producing standalone ESM worker scripts\n- Build outputs: `dist/`, `worker-metafiles/`\n- Release builds set `SOURCEMAPS=false` to omit package source maps; ordinary builds keep them for debugging. Non-watch builds clean `dist/` before compiling so maps from an earlier build cannot leak into a release. This does not disable user Worker source maps.\n\n## Lint Status (Transitional)\n\n- Many shared ESLint rules temporarily DISABLED: `no-explicit-any`, `consistent-type-imports`, `no-shadow`, `no-floating-promises`, others\n- Comment in config: \"temporarily enabled while we transition Miniflare to use the standard workers-sdk eslint config\"\n- `no-console: error` is on, except for `src/workers/` and `scripts/`\n\n## TypeScript\n\n- Does NOT extend shared `@cloudflare/workers-tsconfig` — has its own full config\n- Uses `experimentalDecorators`\n- Path aliases: `miniflare:shared`, `miniflare:zod`\n- `declaration: true` (emits .d.ts)\n\n## Testing\n\n- Test files use `.spec.ts` (NOT `.test.ts`)\n- `pool: \"forks\"`, `maxWorkers: 1` (limits test files to one worker)\n- Does NOT extend `vitest.shared.ts` — own full vitest config\n- Timeouts: 30s test, 30s hook\n- `globals: true`\n- Factory pattern: `miniflareTest(opts, handler?)` creates instance in `beforeAll`, disposes in `afterAll`\n- `useDispose(mf)` / `disposeWithRetry()` — exponential backoff for Windows EPERM file locking\n- `useServer()` — temp HTTP server with auto-cleanup\n- `TestLog` — captures log entries by level\n\n## Generated Files\n\n- `src/runtime/config/generated/workerd.ts` — generated Cap'n Proto types, do not edit directly\n- `src/workers/local-explorer/openapi.local.json` — generated from `scripts/openapi-filter-config.ts`, modify the config not the output\n\n## Version Pinning\n\n- Miniflare minor version must match workerd minor version\n- `tools/deployments/changeset-version.ts` enforces this: if changeset bumps miniflare minor beyond workerd's, it converts to patch\n","isInternal":false,"tokens":975,"sizeBytes":3947},{"name":"AGENTS.md","path":"packages/vite-plugin-cloudflare/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vite-plugin-cloudflare/AGENTS.md","title":"Vite-plugin-cloudflare Skill","category":"anthropic-skill","format":"markdown","content":"# AGENTS.md — vite-plugin-cloudflare\n\n## OVERVIEW\n\nVite plugin for Cloudflare Workers development. Exports `cloudflare()` plugin factory from `src/index.ts`. ESM-only output.\n\n## STRUCTURE\n\n- `src/index.ts` — Plugin factory\n- `src/cf-vite.ts` — `cf-vite` delegate binary entry (see below)\n- `bin/cf-vite` — shebang shim that dynamic-imports `dist/cf-vite.mjs`\n- `src/workers/` — 4 internal worker entries: `asset-worker`, `router-worker`, `runner-worker`, `vite-proxy-worker`\n- `playground/` — ~47 playground apps, each a workspace member (nested workspace under this package)\n- `e2e/` — E2E tests with Playwright\n- `__tests__/` — Unit tests use `.spec.ts` naming\n\n## BUILD\n\n- Only package using `tsdown` as build tool\n- Outputs ESM (`.mjs`) to `dist/index.mjs`\n- `src/cf-vite.ts` is a second top-level tsdown entry, bundled to `dist/cf-vite.mjs` (no dts)\n- Also bundles 4 internal worker scripts from `src/workers/*/index.ts` as separate neutral-platform outputs to `dist/workers/`\n- Release builds set `SOURCEMAPS=false` to omit the plugin's JavaScript and declaration maps. Normal builds retain maps for debugging; the setting does not change source maps for applications built with the plugin.\n\n## cf-vite DELEGATE BINARY (experimental / internal)\n\n`bin/cf-vite` is an experimental, internal delegate binary spawned by\nCloudflare's \"cf-dev\" parent process — NOT part of the plugin's public\nAPI and not meant for direct end-user invocation. It is the sibling of\n`wrangler`'s `cf-wrangler` binary, and the two MUST keep a shared spawn\ncontract so the parent can drive either impl interchangeably.\n\n- **Verb dispatch.** `cf-vite <verb> [flags]`. `dev` and `build` are the\n  verbs today; future verbs (`deploy`) follow the same shape.\n  Unknown/missing verbs exit `2` (this doubles as the parent's\n  version-detection signal — no JSON handshake).\n- **Shared flag vocabulary (`dev`).** For `dev`, only `--mode`, `--port`,\n  `--host`, `--local` are accepted, mirroring `cf-wrangler` exactly.\n  Parsed with `node:util.parseArgs` strict mode → unknown flags exit `2`.\n  Do NOT add flags here unless `cf-wrangler` grows them too. (There is no\n  `--config` flag: the wrangler config is discovered by `cloudflare()`\n  itself.)\n- **`build`** `cf-vite build` runs Vite's full multi-environment\n  app build via `createBuilder().buildApp()` (NOT the legacy\n  single-environment `build()` helper, which would skip the plugin's\n  worker/build-output orchestration — mirrors Vite's own `vite build`\n  CLI). It accepts only `--mode` (`--port`/`--host`/`--local` don't apply to\n  a build and exit `2`). Preview build context is supplied through\n  `CLOUDFLARE_PREVIEW_BUILD`, which also works when a framework runs Vite as\n  part of its own build command.\n- **Build Output Specification is the core build pipeline.** Every build emits\n  Build Output; there is no feature flag or legacy output-config path. Preview\n  reads Workers and Containers exclusively from that output. The v2 plugin\n  always installs its build-output plugin, so `cf-vite` does not need the\n  internal force-build-output flag used by v1.\n- **Caller identity.** `main()` sets `CLOUDFLARE_VITE_CLI_DISPLAY_NAME=cf`\n  before Vite loads the user's config. `resolvePluginConfig` reads this through\n  `getCliDisplayName()` so shared services can use `cf` in actionable messages;\n  direct Vite plugin use defaults to `Wrangler`. This is an internal bridge,\n  not a `.env`-file knob.\n- **`dev`** `cf-vite dev` boots Vite via `createServer()`\n  against the user's own `vite.config.ts` (which must include\n  `cloudflare()`). Plugin-owned flags are bridged via env vars the plugin\n  already reads (`--local` → `CLOUDFLARE_VITE_FORCE_LOCAL`); Vite-owned\n  flags go through inline config (`--port`/`--host` → `server.*`,\n  `--mode` → `mode`).\n- **`--local`** forces remote bindings off. There is no plugin env knob\n  for `remoteBindings` other than `CLOUDFLARE_VITE_FORCE_LOCAL`, which\n  `resolvePluginConfig` in `plugin-config.ts` honours by overriding the\n  `remoteBindings` config option. Keep that override in sync if the flag\n  semantics change.\n- **Hotkeys differ by design.** `cf-vite` uses Vite's own\n  `bindCLIShortcuts` (`h`/`r`/`q`/…), not wrangler's hotkey set. The\n  parent process should not assume identical hotkey UX across delegates.\n- **Exit codes.** `0` graceful, `2` unknown verb / argv parse error,\n  `130` SIGINT, `143` SIGTERM.\n\n## CONVENTIONS\n\n- Playground directory `worker-♫/` has unicode in name (intentional)\n\n## TESTING\n\n- Unit tests: `.spec.ts` in `__tests__/`\n- E2E tests: `.test.ts` in `e2e/`, own vitest config\n- Playground tests: Playwright-based, tested across Vite 7/8 in CI\n- Playground request helpers (`playground/__test-utils__/responses.ts`):\n  - `getTextResponse()` / `getJsonResponse()` issue a request with browser\n    navigation headers (`Sec-Fetch-Mode: navigate` et al), which the asset and\n    router workers branch on. Default to these.\n  - They use undici's low-level `request()` rather than `fetch()`\n    **deliberately**. The Fetch spec requires implementations to set\n    `Sec-Fetch-Mode` from the request's `mode` (\"append the Fetch metadata\n    headers\"), so `fetch()` overwrites whatever the caller passed with `cors`\n    before the request leaves the process (`appendFetchMetadata` in undici).\n    `Sec-Fetch-Dest`/`-Site`/`-User` are unimplemented there, so they survive —\n    which is why only `Sec-Fetch-Mode` breaks and it is easy to miss. That one\n    decides whether the asset worker applies `not_found_handling`.\n  - This is permanent, not a bug to wait out: no Fetch-based API can send\n    `Sec-Fetch-Mode: navigate`, and `fetch(url, { mode: \"navigate\" })` is\n    rejected by the `Request` constructor. Do not \"simplify\" these back to\n    `fetch()`; `spa-with-api`'s \"via `getTextResponse()`\" test exists to catch\n    exactly that regression (it is the only playground whose compat date enables\n    `SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING`).\n  - `getResponse()` drives a real `page.goto()` and returns a Playwright\n    `Response`. Only use it when the assertion needs the browser. Anything\n    routed through Playwright can outlive a timed-out test and surface as an\n    unhandled rejection, which fails the whole run rather than one test.\n  - `WAIT_FOR_OPTIONS` (`playground/__test-utils__/index.ts`) must stay\n    comfortably below the test timeout, otherwise `vi.waitFor()` never gets to\n    report the assertion that was actually failing.\n- `playground/vitest.config.e2e.ts` inherits the repo-wide timeouts and\n  `retry: 1` from the root `vitest.shared.ts`. It spreads `configShared.test`\n  rather than using `mergeConfig()`, which concatenates arrays and would\n  silently enable the shared `default` reporter alongside `dot`.\n","isInternal":false,"tokens":1792,"sizeBytes":6788},{"name":"AGENTS.md","path":"packages/vitest-plugin/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vitest-plugin/AGENTS.md","title":"Vitest-plugin Skill","category":"anthropic-skill","format":"markdown","content":"# vitest-plugin — Agent Guide\n\n> Custom Vitest pool for running Worker tests inside the actual workerd runtime.\n> Do NOT repeat root AGENTS.md content (pnpm, changesets, code style, etc.).\n\n## THREE-CONTEXT ARCHITECTURE\n\n### 1. Pool (`src/pool/index.ts`)\n\n- Runs in Node.js Vitest process\n- Main export (`exports[\".\"]`), built as ESM (`.mjs`)\n- Orchestrates test execution\n\n### 2. Config (`src/pool/config.ts`)\n\n- Runs in Node.js, part of the pool bundle (no separate package export)\n- Validates pool options (`WorkersPoolOptionsSchema`) and resolves the project's\n  Worker configuration into Miniflare options\n- `src/pool/plugin.ts` provides the `cloudflareTest()` Vite plugin, which injects\n  `cloudflare:test` resolution and sets resolve conditions (`workerd`, `worker`, `browser`)\n\n### 3. Worker (`src/worker/index.ts`)\n\n- Runs inside workerd runtime\n- NOT exported via package.json — internal entry\n- Contains HACK: monkeypatches VitestExecutor to access singleton\n- Has direct cross-package source import into `miniflare/src/workers/core/devalue`\n\n## WORKER CONFIGURATION SOURCES\n\n`parseCustomPoolOptions()` in `src/pool/config.ts` resolves at most one configuration\nfile into a normalised `Config`, then shares every downstream step (remote proxy\nsession, `unstable_getMiniflareWorkerOptions()`, `main`, defines, module rules, tails):\n\n- `wrangler: { configPath, environment }` — a Wrangler configuration file, via\n  `wrangler.unstable_readConfig()`\n- `experimental: { newConfig }` — a `cloudflare.config.ts`, via `src/pool/new-config.ts`\n  (`@cloudflare/config`'s `loadAndParseConfig()` → `convertToWranglerConfig()` →\n  `normalizeAndValidateConfig()`). Mirrors `@cloudflare/vite-plugin`'s\n  `experimental.newConfig`. `ctx.mode` comes from `project.vite.config.mode`.\n\nThe two are mutually exclusive. Whichever is used, the resolved path, config format and\nWorker name are recorded on `options.resolvedConfig` for the pool to consume — never\nre-read the config file from disk.\n\n## BUILD\n\n`tsdown.config.ts` defines 2 separate builds (all ESM):\n\n1. pool — `src/pool/index.ts` → `dist/pool` (emits type declarations)\n2. worker + libs — `src/worker/index.ts` plus `src/worker/lib` and `src/worker/node` → `dist/worker`\n\nTypes entry `types/cloudflare-test.d.ts` is hand-written (NOT generated from source).\n\n## THE `cloudflare:test` MODULE\n\nTests inside workerd import from `cloudflare:test`:\n\n```ts\nimport { env, fetchMock, SELF } from \"cloudflare:test\";\n```\n\nResolved by custom Vite plugin (`@cloudflare/vitest-plugin:config`) that re-exports from `cloudflare:test-internal` (runtime-provided).\n\n## CONVENTIONS\n\n- `expect` must come from test context: `it(\"name\", ({ expect }) => {})` — never `import { expect } from \"vitest\"`\n- Tests use `.test.ts` naming\n- Excludes `*.worker.test.ts` from vitest config\n\n## TESTING\n\n- Does NOT extend `vitest.shared.ts`\n- Hook timeout: 60s, retry: 2\n- Global setup starts mock npm registry, installs local package to temp dir\n- Test helper: custom `test` fixture with `tmpPath`, `seed()`, `vitestRun()`, `vitestDev()`\n- Fixtures in `fixtures/vitest-plugin-examples/` (20+ sub-fixtures testing KV, R2, D1, DO, Queues, `cloudflare.config.ts`, etc.)\n- Skipped on Windows CI due to flakiness\n","isInternal":false,"tokens":855,"sizeBytes":3254},{"name":"AGENTS.md","path":"packages/workers-auth/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-auth/AGENTS.md","title":"Workers-auth Skill","category":"anthropic-skill","format":"markdown","content":"# AGENTS.md — workers-auth\n\nOAuth-2.0-with-PKCE flow against Cloudflare's `dash.cloudflare.com` (or staging /\ncustom-overridden) endpoints. Used by wrangler and (in future) other Cloudflare\nCLIs. Internal-only — published as `prerelease: true`.\n\n## STRUCTURE\n\n- `src/pkce.ts` — PKCE code-verifier / code-challenge generation (RFC 7636)\n- `src/errors.ts` — `ErrorOAuth2` class hierarchy + `toErrorClass` mapper\n- `src/generate-auth-url.ts` — authorize URL builder\n- `src/generate-random-state.ts` — CSRF state generator\n- `src/env-vars.ts` — `WRANGLER_*` and `CLOUDFLARE_AUTH_*` env-var getters\n- `src/account-id.ts` — `validateAccountId(id, source)`, applied to every user-supplied account ID (`CLOUDFLARE_ACCOUNT_ID`, the consumer's `account_id` config field) before it reaches an API URL path\n- `src/access.ts` — Cloudflare Access detection + service-token / `cloudflared` headers\n- `src/config-file/auth.ts` — the `AuthConfigStorage` / `UserAuthConfig` storage contract (interfaces only). The default plaintext credential implementation lives alongside the credential-store layer at `src/credential-store/file-store.ts` (see \"Credential storage\" below). The core `src/core/auth-config-file.ts` (`createAuthConfigFileHelpers({getConfigPath, format})`) and `src/core/file-storage.ts` (`createFileStorage(format, getPath)`) build the per-profile path helpers and non-credential file stores; each CLI descriptor (`src/wrangler/auth-config-file.ts`, `src/cf/auth-config-file.ts`) binds them to its config dir + `FileFormat` and re-exports `createTomlFileStorage` / `createJsonFileStorage`, `getAuthConfigFilePath`, etc. from its entrypoint. See \"CORE LAYER\" below.\n- `src/config-file/temporary.ts` — `TemporaryAccountStorage` / `TemporaryPreviewAccount` storage contract for the temporary-preview-account flow\n- `src/config-file/index.ts` — generic `ConfigStorage<T>` interface shared by the auth and temporary-account contracts\n- `src/state.ts` — `readStoredAuthState()` + `StoredAuthState` shape\n- `src/token-exchange.ts` — auth-code → token + refresh-token rotation + `fetchAuthToken`\n- `src/callback-server.ts` — local HTTP server for the OAuth callback (listens on the host/port from the consumer's `redirectUri`)\n- `src/device-flow.ts` — `getOauthTokenViaDeviceFlow(options, ctx)`: the OAuth 2.0 Device Authorization Grant (RFC 8628) used by `login({device: true})` when the browser cannot reach the local callback URL. No callback server; prints the verification URL + user code and polls `/oauth2/token`. Every user-facing string is parameterised by `ctx.cliDisplayName` / `ctx.deviceLoginCommand` so the module carries no per-CLI branding. Both endpoints' bodies are narrowed before use (`asDeviceAuthorizationResponse`, `pollDeviceToken`'s `DevicePollResult`) rather than cast — an intermediary's envelope or a 2xx without a grant must produce a reportable `unexpected`/unusable-response error, never `undefined` arithmetic. `slow_down` / 5xx / 429 / unparseable bodies keep the loop alive; the last such failure is reported in place of the generic timeout if the deadline passes\n- `src/generate-device-auth-url.ts` — `generateVerificationUrl` (fallback `verification_uri_complete` builder for servers that omit it, RFC 8628 §3.3.1) + `assertTrustedVerificationUrl`, which rejects any server-supplied verification URL that is not `https:` on exactly the resolved auth domain (with no embedded credentials) before it is printed or handed to `openInBrowser` — the device flow is the only place this package opens a URL it did not build itself (RFC 8628 §5.4, remote phishing)\n- `src/flow.ts` — `createOAuthFlow(ctx)` factory wiring everything together\n- `src/context.ts` — `OAuthFlowContext` interface (DI surface)\n- `src/credential-store/` — opt-in OS-keyring-backed credential persistence (see below)\n- `src/test-helpers/` — MSW handlers for consumers' tests (`@cloudflare/workers-auth/test-helpers`)\n\n### Credential storage (`src/credential-store/`)\n\nPluggable credential persistence layer that consumers can wire into the\nOAuth flow via `ctx.storageFactory`. Default backend is the plaintext\nTOML file (`FileCredentialStore`); an opt-in `EncryptedFileCredentialStore`\nwrites AES-256-GCM-encrypted credentials to a sibling `.enc` file using a\nkey held in the OS keyring. Every store is profile-aware: the file path,\nthe encrypted `.enc` path, and the keyring account name are all derived from\n`resolveAuthProfileBaseName(profile)` (default profile → environment-based\nname; named profile → the profile name), so each auth profile gets its own\nfiles and its own encryption key.\n\n- `interface.ts` — `CredentialStore` interface (extends `AuthConfigStorage` with `kind` and `describe()`)\n- `file-store.ts` — `FileCredentialStore` (plaintext TOML, default)\n- `encrypted-file-store.ts` — `EncryptedFileCredentialStore` + plaintext-TOML migration\n- `crypto.ts` — AES-256-GCM `encryptString` / `decryptString` helpers\n- `resolver.ts` — `createCredentialStorageContext({...})` factory; returns `{ storageFactory, getActiveStore }` (both take an optional `profile`) for the consumer to plug into `createOAuthFlow` (as `ctx.storageFactory`) and `whoami`-style reporting respectively\n- `state.ts` — module-level per-session resolver flags (one-time warnings, the Windows install-failed latch)\n- `key-providers/` — per-platform OS-keyring backends that store only the 32-byte encryption key (never the credential blob itself, so the macOS Keychain 2.5 KB item limit is never a concern):\n  - `interface.ts` — `KeyProvider` interface\n  - `mac-security.ts` — `/usr/bin/security` shell-out\n  - `linux-secret-tool.ts` — `secret-tool` shell-out (probes `libsecret-tools`)\n  - `napi-keyring.ts` — `@napi-rs/keyring` wincred binding on Windows\n  - `lazy-installer.ts` — Windows-only `npm install @napi-rs/keyring` on first opt-in\n  - `factory.ts` — `resolveKeyProvider(serviceName)` picks the right per-platform implementation\n  - `shared.ts` — account-name derivation + keyring JSON envelope encoding\n\n## DI SURFACE\n\n`createOAuthFlow(ctx)` accepts a context object:\n\n- `logger` — drop-in replacement for wrangler's logger singleton\n- `isNonInteractiveOrCI()` — whether to suppress interactive prompts\n- `openInBrowser(url)` — opens the browser to the OAuth authorize URL\n- `hasEnvCredentials()` — short-circuits refresh logic when env-based auth is set\n- `clientId` (required) — the consumer's registered OAuth app ID; `string` or\n  `() => string` for lazy (e.g. env-driven prod/staging) resolution\n- `consent` (required) — the consumer's branded granted/denied consent pages\n- `cliDisplayName` (required) — the consumer's branded name (`\"Wrangler\"`, `\"cf\"`),\n  interpolated into the device flow's \"To authorize \\<name\\>…\" copy\n- `deviceLoginCommand` (required) — the command that restarts the device flow\n  (`\"wrangler login --device\"`), quoted when a device code is denied, expires,\n  or the flow times out\n- `redirectUri` (required) — the registered redirect URI / local callback URL.\n  The callback server's listen host/port and route path are all derived from it\n  (per-call bind overrides via `LoginProps.callbackHost`/`callbackPort`)\n- `storageFactory` (required) — maps an auth profile to the consumer's\n  `AuthConfigStorage` token-persistence backend. The flow calls it with the\n  active profile on every credential access. For keyring opt-in, pass the\n  `storageFactory` from `createCredentialStorageContext(...)` rather than a raw\n  file store, so both the active profile and the encrypted-file / plaintext\n  choice are re-resolved on every credential operation.\n- `purgeOnLoginOrLogout?()` — invalidate consumer-side caches after login/logout\n- `generateAuthUrl?` / `generateRandomState?` — test overrides for deterministic\n  snapshot tests (defaults pull from `./generate-auth-url` / `./generate-random-state`)\n\n`clientId`, `consent`, `cliDisplayName`, `deviceLoginCommand`, `redirectUri`, and\n`storageFactory` are consumer-specific, so they are required rather than\ndefaulted here. Wrangler's values live in the in-package wrangler layer\n(`src/wrangler/`, see below) rather than in the `wrangler` package itself.\n\nThe wrangler layer (`src/wrangler/index.ts`, `createWranglerAuth`) wires the\ncredential-storage layer once via `createCredentialStorageContext(...)` and\nexposes the resulting `getActiveStore` (called with the active profile) as\n`getCredentialStore()` for `whoami`-style code that wants to surface the active\nstorage location.\n\n## CORE LAYER (`src/core/`) + PER-CLI DESCRIPTORS (`src/wrangler/`, `src/cf/`)\n\nThe whole CLI-facing auth layer (the machinery that used to live in\n`packages/wrangler/src/user/`) is **CLI-agnostic** and shared by every\nCloudflare CLI built on this package. It lives in `src/core/`:\n\n- `factory.ts` — `createCloudflareAuth(descriptor, ctx)`: OAuth flow wiring,\n  credential storage, config cache (`@cloudflare/workers-utils`'\n  `createConfigCache`), account selection (`fetchInternalBase` with the token\n  the flow already holds), login / logout / refresh, and `requireAuth`. Imports\n  only `@cloudflare/workers-utils`.\n- `types.ts` — `AuthContext` (the injected primitives: `logger`, optional\n  `temporaryAccountLogger` for temporary-account notices, `userAgent`, interactive\n  `prompt` / `select`, `isNoDefaultValueProvidedError`) and\n  `CliDescriptor` (everything that varies per CLI: `cliName` (the executable),\n  `displayName` (branded name used in prose), auth command names\n  (`login` / `logout` / `whoami` / `createProfile` / `deviceLogin`),\n  `keyringServiceName`,\n  `clientId`, `consent`, `redirectUri`, `useDeviceFlowByDefault`,\n  `getConfigPath`, `fileFormat`,\n  `accountCachePrefix`, `cacheNamespace`, `getConfigFileLabel`,\n  `getDefaultScopeKeys`, …).\n- `file-storage.ts` (`createFileStorage(format, getPath)`), `auth-config-file.ts`\n  (`createAuthConfigFileHelpers({getConfigPath, format})`), `preferences.ts`\n  (`createPreferences(getConfigPath)`), `profile-store.ts`\n  (`createCloudflareProfileStore`), `keyring-preference.ts`\n  (`createKeyringPreference`), `scopes.ts` (shared Cloudflare scope catalog),\n  `file-format.ts`, `temporary-terms.ts`.\n\n**File format** is the `FileFormat` axis (`src/core/file-format.ts`): a simple\n`\"toml\" | \"json\"` union (the value doubles as the file extension) plus\n`parseFile` / `stringifyFile` helpers. It's threaded through `createFileStorage`\nand the credential store (`FileCredentialStore` / `EncryptedFileCredentialStore`\n/ `resolver.ts` all take an optional `format`, defaulting to `\"toml\"` so wrangler\nis unchanged; the encrypted `.enc` sibling is format-independent). Wrangler uses\n`\"toml\"`; cf uses `\"json\"`.\n\nEach CLI is a thin **descriptor + entrypoint**:\n\n- `src/wrangler/` → `@cloudflare/workers-auth/wrangler`: `WRANGLER_CLI`\n  (TOML, wrangler's global config dir, wrangler's OAuth app / `\"wrangler\"`\n  keyring service) + `createWranglerAuth(ctx) = createCloudflareAuth(WRANGLER_CLI, ctx)`.\n  Re-exports everything wrangler's `src/user/*` imports (`createTomlFileStorage`,\n  `readUserPreferences`, `createWranglerProfileStore`, `setKeyringPreference`,\n  scopes, `getClientIdFromEnv`, `OAUTH_CALLBACK_URL`, …) — no re-export shim\n  files remain in `wrangler/src/user/`.\n- `src/cf/` → `@cloudflare/workers-auth/cf`: `CF_CLI` (JSON files under\n  `~/.config/cloudflare`, the `\"cloudflare\"` keyring service, `CLOUDFLARE_CLIENT_ID`)\n  - `createCfAuth(ctx)`. OAuth-app values (client ID `cbca97e7-…`, callback port\n    8877, `cf-oauth-consent-*` pages, scoped-token-only auth) mirror the `cf`\n    CLI's registration, and device authorization is its default interactive\n    login flow. cf carries its own scope policy (`src/cf/scopes.ts`): the raw\n    client registration is kept separate from the known-grantable catalog used\n    for validation and types, and sensitive requestable scopes can be excluded\n    from login defaults. Requestable scopes must both appear in the client\n    registration and resolve in the consent service's Bach catalog; registered\n    exceptions stay explicit negative regressions. Retain separately verified,\n    grandfathered legacy scopes and registration order.\n    This is distinct from wrangler's smaller `src/core/scopes.ts` key →\n    description map, so cf does not re-export `DefaultScopes`.\n\n## CONVENTIONS\n\n- License: dual MIT/Apache-2.0. Files derived from\n  [BitySA/oauth2-auth-code-pkce](https://github.com/BitySA/oauth2-auth-code-pkce)\n  carry the Apache-2.0 header.\n- No `console.*` — use the injected `ctx.logger`. Temporary-account notices\n  (terms notice, proof-of-work, \"Temporary account ready\") go through the\n  `temporaryAccountLogger` instead, so a CLI can keep them off stdout.\n- No global `fetch` — use undici's `fetch`.\n- `UserError` instances must carry stable `telemetryMessage` labels\n  (`<area> <sub-area> <failure>`, e.g. `user oauth invalid scope`).\n  These labels are part of the telemetry contract — preserve them verbatim.\n- No direct Cloudflare REST API calls. This package talks to OAuth endpoints\n  (`/oauth2/auth`, `/oauth2/token`, `/oauth2/revoke`) only.\n- OAuth callback server listens on the host/port derived from the consumer's\n  required `ctx.redirectUri`; override the bind address per-call via\n  `LoginProps.callbackHost` / `callbackPort`.\n\n## BUILD\n\n- tsup: two entry points — `src/index.ts` and `src/test-helpers/index.ts`\n- ESM-only output to `dist/`\n- `@cloudflare/*`, `undici`, `msw`, and `vitest` are kept external\n\n## CREDENTIAL STORAGE NOTES\n\n- The encrypted file uses `AES-256-GCM` via `node:crypto` (no third-party\n  crypto deps). The 12-byte IV is generated fresh per write; the 16-byte\n  GCM auth tag is verified on every read.\n- The keyring entry holds only a 32-byte AES key wrapped in a small JSON\n  envelope (`{v, key, created}`). It's well under the macOS Keychain ~2.5 KB\n  per-item limit no matter how the credential schema grows.\n- `@napi-rs/keyring` (the Windows backend's native binding) is installed\n  lazily on first opt-in via `npm install` into `<configPath>/native/keyring/`,\n  where `configPath` is the consumer-provided global config directory (see\n  `getConfigPath` below) — so each CLI's binding lives under its own config dir.\n  Pinned to `PINNED_KEYRING_VERSION` so CI users running\n  `npm install -g @napi-rs/keyring` by hand get the same version as the\n  lazy-install path.\n- The credential files (`.toml` / `.enc`) and the keyring install dir are all\n  rooted at the consumer's config directory. `@cloudflare/workers-auth` never\n  resolves that path itself (wrangler and a future `cf` CLI use different global\n  config paths); instead the consumer passes `getConfigPath: () => string` into\n  `createCredentialStorageContext`, and the path helpers\n  (`getAuthConfigFilePath` / `getEncryptedAuthConfigFilePath` /\n  `getKeyringInstallDir`) and store constructors all take it explicitly.\n- The consumer's `createCredentialStorageContext` call captures `serviceName`,\n  `getConfigPath`, `isKeyringEnabled`, `logger`, `isNonInteractiveOrCI`, and\n  `loginCommand` in a closure. The returned `storageFactory(profile)` re-resolves\n  the active store on every call so the active profile, `--use-keyring` /\n  `--no-use-keyring`, and the `CLOUDFLARE_AUTH_USE_KEYRING` env var all take\n  effect without rebuilding the OAuth flow. Per-session memoization flags\n  (`hasWarnedAboutKeyringFallback`, `installFailedThisSession`, ...) still\n  live at module scope in `state.ts`; tests use\n  `resetCredentialStorageState` to clear them between cases and\n  `setKeyProviderFactoryForTesting` to swap in stubs.\n","isInternal":false,"tokens":3917,"sizeBytes":15636},{"name":"AGENTS.md","path":"packages/workers-utils/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-utils/AGENTS.md","title":"Workers-utils Skill","category":"anthropic-skill","format":"markdown","content":"# AGENTS.md — workers-utils\n\n## OVERVIEW\n\nShared utility package used across wrangler, miniflare, and others. Two main areas: config validation and test helpers.\n\n## STRUCTURE\n\n- `src/config/` — Configuration types, validation, normalization\n  - `validation.ts` — The config normalizer (large file). Central to all wrangler config processing.\n  - `environment.ts` — Environment/config field definitions (many deprecated fields)\n  - `config.ts` — Config types\n- `src/test-helpers/` — Shared test utilities used across packages\n- `src/types.ts` — Shared type definitions\n\n## KEY EXPORTS\n\n### Config\n\n- Validation pipeline normalizes wrangler.json/toml into typed config objects\n- Used by wrangler for all config loading\n\n### D1 migrations\n\n- `getD1MigrationFiles({ projectPath, migrationsDir, migrationsPattern })` — shared glob-based discovery used by Wrangler and the Vitest plugin. Honour `migrations_pattern` rather than recursively collecting every `.sql` file.\n\n### Shared runtime utilities\n\n- `createConfigCache(logger)` — file-backed JSON config cache (node_modules/.cache or `.wrangler/cache`). Generic mechanism; the consumer passes its logger (this package has no logger singleton). Both `wrangler` (`src/config-cache.ts`) and `@cloudflare/workers-auth` build their own instances.\n- `openInBrowser(url, logger)` — opens the `open` package with a graceful copy-paste fallback when no browser opener is available. Logger is a parameter, not imported.\n- `isInteractive()` / `isNonInteractiveOrCI()` / `isCI()` — TTY / CI detection (the TTY check is inlined here to avoid a cycle back through `@cloudflare/cli-shared-helpers`). `isCI()` keys off CI specifically (ignoring TTY), for behaviour like redacting account names in public CI logs. These read `ci-info`, which is bundled into consumers' distributables. Because a bundled `ci-info` is an unmockable separate instance (and reads the real environment), consumers that need to fake CI in their tests mock **this package's** exports rather than `ci-info` — e.g. wrangler's `vitest.setup.ts` mocks `@cloudflare/workers-utils` so `isInteractive`/`isNonInteractiveOrCI`/`isCI` delegate to the mockable `ci-info`, which reaches both wrangler-source and bundled `@cloudflare/workers-auth` consumers (since `@cloudflare/*` is external in workers-auth's bundle).\n\n### Test Helpers\n\n- `runInTempDir()` — Creates temp dir, chdir's into it, stubs HOME/XDG_CONFIG_HOME, cleans up\n- `seed(files)` — Writes `Record<string, string>` of path->content into temp dir\n- `writeWranglerConfig()` / `readWranglerConfig()` — Mock wrangler config files (TOML, JSON, JSONC)\n- `mockConsoleMethods()` — Spies on console, returns normalized output with `.debug`, `.out`, `.info`, `.err`, `.warn`\n- `normalizeString()` — Multi-stage pipeline: strips timings, thin spaces, temp dirs, normalizes slashes/cwd/dates/tables/error markers/byte values, and scrubs the OAuth authorize URL's random `state` / `code_challenge` query params to `<OAUTH_STATE>` / `<OAUTH_CODE_CHALLENGE>` (so login-URL snapshots stay deterministic without mocking the URL builder)\n\n## NOTES\n\n- `validation.ts` is the largest single file in the monorepo after generated code — changes here affect all config processing\n- Many deprecated fields in `environment.ts` — check `@deprecated` annotations before modifying\n- Test helpers imported as `@cloudflare/workers-utils/test-helpers` across packages\n","isInternal":false,"tokens":807,"sizeBytes":3437},{"name":"AGENTS.md","path":"packages/wrangler/AGENTS.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/wrangler/AGENTS.md","title":"Wrangler Skill","category":"anthropic-skill","format":"markdown","content":"# Wrangler — Agent Guide\n\nWrangler-specific context only. See root `AGENTS.md` for monorepo conventions.\n\n## Overview\n\nMain CLI for Cloudflare Workers. ~2k-line yargs command tree in `src/index.ts`. Entry point is `src/cli.ts` (NOT `src/index.ts`).\n\n## Structure\n\n- `src/` — CLI source\n- `src/__tests__/` — Unit tests, helpers in `src/__tests__/helpers/`\n- `e2e/` — E2E tests, requires Cloudflare credentials\n- `bin/wrangler.js` — Shim that spawns Node to run `wrangler-dist/cli.js`, forwarding stdio and IPC\n- `bin/cf-wrangler.js` — `cf-wrangler` delegate entrypoint. Owns verb dispatch, argv parsing (`parseCfWranglerArgs`), and the `StartDevOptions` literal; hands off to `runCfWranglerDev` from `wrangler-dist/cli.js` in-process (no re-spawn — the parent tool owns the Node runtime)\n- `src/containers/ssh.ts` — Thin command adapter; SSH options, authorization request, and transport live in `@cloudflare/containers-shared/src/ssh.ts`, shared with cf.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint (see below)\n- `src/containers/images.ts` — Command adapter; registry image operations live in `containers-shared/src/registry-images.ts`, shared with cf.\n- `templates/` — Worker templates\n\n## Entry Points\n\n- `src/cli.ts` — Build entry AND library API surface (dual-purpose). Calls `main()` when run directly; re-exports `./api` when imported as library. Also re-exports `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, `ArgParseError`, `runCfWranglerDev`, and `runCfWranglerBuild` for the `cf-wrangler` bin to call in-process.\n- `src/index.ts` — Yargs CLI tree builder (large file). Exports `main()`. NOT the package entry point despite the name.\n- `src/api/index.ts` — Public programmatic API barrel.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint, an experimental escape hatch for projects that can't use `@cloudflare/vite-plugin`. It exposes `dev` + four flags (`--mode`, `--port`, `--host`, `--local`) and `build` + `--mode`; the wrangler config file is found via wrangler's standard discovery (no `--config` flag). Preview build context is supplied through `CLOUDFLARE_PREVIEW_BUILD`, matching framework-owned build commands. It is NOT a separate package and does NOT use the `unstable_dev` test harness. It shares its spawn contract (verb dispatch, flag vocabulary, exit-2 feature detection) with the sibling `cf-vite` delegate in `@cloudflare/vite-plugin`. `bin/cf-wrangler.js` owns verb dispatch, argv parsing, and the `StartDevOptions` literal; `src/cf-wrangler/dev.ts` (exported as `runCfWranglerDev`) wraps `startDev` in the experimental-flags context and waits for teardown. `src/cf-wrangler/build.ts` (exported as `runCfWranglerBuild`) runs the Build Output Specification path used by `wrangler build --experimental-new-config --experimental-cf-build-output`, producing `.cloudflare/output/v0`. `src/cf-wrangler/args.ts` (exported as `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, and `ArgParseError`) does the strict argv parse. The \"unknown subcommand\" error doubles as a feature-detection signal for the parent CLI.\n\n## Conventions (Wrangler-Specific)\n\n- No `console.*` — use `logger` singleton\n- No `__dirname` / `__filename` — use `getBasePath()`\n- No global `fetch` — use undici's fetch\n- Route Cloudflare v4 API calls through the existing `cfetch` helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult` when possible;\n  do not use global or undici `fetch` directly. Prefer these helpers over\n  adding or passing the `cloudflare` package solely for a simple request, and\n  use the Cloudflare TypeScript SDK when its generated API surface or behavior\n  is materially useful.\n- `telemetryMessage` values for `UserError`-compatible errors must be static, safe labels. Do not use `telemetryMessage: true` unless 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: true` is usually less useful because user-facing copy is harder to group and parse than a stable telemetry label.\n- Format `telemetryMessage` values as lower-case phrases: `<service or area> <command or sub-area> <failure>`, for example `kv namespace binding not found in config`, `r2 object put file not found`, or `pages deploy project name missing`.\n- 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.\n\n## Build\n\n- tsup: single entry `src/cli.ts` → `wrangler-dist/cli.js`\n- `package.json` `main` points at `wrangler-dist/cli.js`\n- Custom `embedWorkersPlugin()` bundles Worker templates via esbuild for tests\n\n## Testing\n\n- Pool: `\"forks\"` (not threads) — heavy global mocking\n- `runWrangler(cmd)` calls `main()` in-process (no subprocess)\n- MSW for API mocking — pre-built handlers per API domain in `src/__tests__/helpers/msw/`\n- Shared helpers: `runInTempDir()`, `mockAccountId()`, `mockApiToken()`, `mockConfirm()`, `mockPrompt()`, `mockSelect()`, `captureRequestsFrom()`\n- Unit timeout: 50s, retry: 0. Note: wrangler's `vitest.config.mts` does NOT use `mergeConfig` with `vitest.shared.ts`, so shared defaults (timeouts, retry, etc.) are not inherited — they must be set explicitly in the wrangler config.\n- E2E timeout: 90s, bail: 1, singleThread\n- `globals: true` for vitest globals\n- Output normalization via `normalizeString()` pipeline\n\n## Anti-Patterns\n\n- Test files use `.test.ts` (not `.spec.ts`)\n- Never import `expect` from vitest — use test context `({ expect }) => {}`\n  - When adding `expect` as a parameter to helper functions, check ALL call sites (e.g., across `deployments.test.ts`, `versions.test.ts`)\n","isInternal":false,"tokens":1490,"sizeBytes":5779},{"name":"README.md","path":"packages/build-output-utils/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/build-output-utils/README.md","title":"build-output-utils Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/build-output-utils`\n\nUtilities for reading and writing the Build Output Specification directory (`.cloudflare/output/`).\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","isInternal":false,"tokens":43,"sizeBytes":220},{"name":"README.md","path":"packages/chrome-devtools-patches/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/chrome-devtools-patches/README.md","title":"chrome-devtools-patches Documentation","category":"plugin-manifest","format":"markdown","content":"# Workers Devtools\n\nThis package contains a Workers specific version of Chrome Devtools that is used by the Wrangler dev command and other applications. It is a customized fork of Chrome DevTools specifically tailored for debugging Cloudflare Workers. This package provides Worker-specific functionality through carefully maintained patches on top of Chrome DevTools.\n\n## Overview\n\nThis package is used across multiple Cloudflare products:\n\n- Workers Playground (`workers-playground`)\n- Quick Editor (`@cloudflare/quick-edit`)\n- Wrangler CLI via the `InspectorProxy`\n\n## Features\n\nOur customized DevTools implementation provides:\n\n- Source code viewing and live updates\n- Network request inspection\n- Worker-specific UI optimizations\n\n## Development\n\nWe maintain this fork by applying patches on top of Chrome DevTools. These patches need to be periodically rebased as Chrome DevTools evolves.\n\n**Key Development Tasks:**\n\n- Generating patches from our customizations\n- Rebasing patches onto new Chrome DevTools versions\n- Testing functionality across all integration points\n\n## Updating DevTools\n\nWe perform quarterly updates to stay current with upstream Chrome DevTools. The update process involves:\n\n1. Cloning the devtools-frontend repo\n2. Applying our existing patches\n3. Rebasing onto the latest Chrome DevTools\n4. Regenerating patches\n5. Thorough testing across all integration points\n\n**For detailed instructions on updating DevTools, please refer to our internal documentation on keeping devtools up-to-date.**\n\n## Testing\n\nTwo methods are available for testing updates:\n\n**Local Development:**\n\n- Build and serve DevTools locally\n- Test against local Playground instance\n- Make targeted fixes as needed\n\n**Preview Builds:**\n\nOn any pull request to the repo on GitHub, you can add the `preview:chrome-devtools-patches` label to trigger a preview build of the DevTools frontend. This is useful because it will allow you to manually test your changes in a live environment, and with one-click.\n\nOnce the preview is built, you will see a comment on the PR with a link to the live URL.\n\n## Acceptance Criteria\n\nOur DevTools implementation must maintain full functionality across:\n\n- Console operations (logging, errors, filters)\n- Source code viewing and debugging\n- Network request inspection\n- Worker-specific UI customizations\n\n## Contributing\n\nWhen making changes:\n\n- Keep patches minimal and targeted\n- Prefer CSS-based UI modifications\n- Test thoroughly across all integration points\n- Document any new patches or modifications\n\n## Deployment\n\nThis package is deployed as a Cloudflare Workers + Assets project. The static DevTools frontend is served directly from Workers Assets, configured via `wrangler.jsonc`.\n\nDeployments are managed by GitHub Actions:\n\n- deploy-previews.yml:\n  - Runs on any PR that has the `preview:chrome-devtools-patches` label.\n  - Uploads a preview version (without activating it in production) via `wrangler versions upload`.\n  - The preview URL is posted as a comment on the PR.\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production via `wrangler deploy`.\n  - Production is accessible via the custom domain [https://devtools.devprod.cloudflare.dev/].\n","isInternal":false,"tokens":665,"sizeBytes":3305},{"name":"README.md","path":"packages/cli/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/cli/README.md","title":"cli Documentation","category":"plugin-manifest","format":"markdown","content":"# Cloudflare CLI\n\n> Internal utility package for workers-sdk. Not intended for external use — APIs may change without notice.\n\nAll things related to rendering the CLI for workers-sdk.\n","isInternal":false,"tokens":36,"sizeBytes":186},{"name":"README.md","path":"packages/codemods/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/codemods/README.md","title":"codemods Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/codemods`\n\nCodemods for upgrading Cloudflare developer projects.\n\nRun a codemod by name:\n\n```sh\nnpx @cloudflare/codemods vitest:v3-to-v4\n```\n\nAvailable codemods:\n\n- `wrangler-to-cf` - migrate a Wrangler configuration to the new `cf`\n  configuration format\n- `vitest:v3-to-v4` — migrate `@cloudflare/vitest-pool-workers` configuration from\n  Vitest v3 to v4\n- `vitest:pool-workers-to-vitest-plugin` — rename `@cloudflare/vitest-pool-workers`\n  to `@cloudflare/vitest-plugin` v1\n\nUse `--dry-run` to list changes without writing them, `--cwd <path>` to target\nanother project, or repeat `--files <glob>` to restrict the files considered.\nWhen the target is inside a Git worktree, the worktree must be clean. Use\n`--force` to bypass this safety check.\n\nTo migrate a Wrangler project with the default Vite bundler:\n\n```sh\nnpx @cloudflare/codemods wrangler-to-cf --cwd ./path/to/project\n```\n\nThe CLI detects a single root `wrangler.json`, `wrangler.jsonc`, or `wrangler.toml`. Pass `--config <path>` to select another file, or pass `--bundler wrangler` to retain Wrangler-specific tooling configuration. For this codemod, `--files` filters the selected Wrangler config and skips the migration when it does not match.\n\n## Programmatic usage\n\nCodemods can also be run from JavaScript or TypeScript:\n\n```ts\nimport { runCodemod } from \"@cloudflare/codemods\";\n\nconst { changedFiles } = await runCodemod(\"vitest:v3-to-v4\", {\n\tcwd: process.cwd(),\n\tdryRun: false,\n});\n```\n\n`runCodemod` accepts the same codemod names and aliases as the CLI. Its context also accepts optional `files` and `force` fields corresponding to the CLI flags, and setting `dryRun` lists changed files without writing them. It returns a `CodemodResult` containing `changedFiles` and rejects if the codemod cannot be run. The CLI's clean-worktree check also applies to programmatic runs.\n\n### Migrate Wrangler config to cf\n\nPass the exact Wrangler config file to `migrateWranglerToCf`:\n\n```ts\nimport { migrateWranglerToCf } from \"@cloudflare/codemods\";\n\nconst result = await migrateWranglerToCf(\"./wrangler.jsonc\", {\n\tbundler: \"vite\",\n});\n```\n\nThe options object and all of its fields are optional. The defaults are the Vite bundler, writes enabled, dirty-worktree protection enabled, and automatic dependency installation enabled. The migration installs `cf` when missing, installs `@cloudflare/vite-plugin@beta` when Vite is selected and the plugin is missing or incompatible, and upgrades Wrangler when generated Wrangler tooling requires a newer version. The Vite plugin dependency remains set to the `beta` dist tag in `package.json`; package manager installation updates the project's lockfile. Project-managed Vite plugin specifiers such as `workspace:` and `catalog:` are preserved; incompatible or unverified versions require a manual update. Set `installDependencies` to `false` to prevent dependency changes; required dependencies are then returned as blocking follow-ups. The migration always creates `cloudflare.config.ts`; selecting the Wrangler bundler also creates `wrangler.config.ts` when Wrangler-specific tooling config exists. Existing target files are never overwritten. Inspect `result.followUps` when `result.status` is `needs-intervention`.\n","isInternal":false,"tokens":794,"sizeBytes":3243},{"name":"README.md","path":"packages/config/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/config/README.md","title":"config Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/config`\n\nDefinitions and utilities for configuring Cloudflare Workers and related products.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","isInternal":false,"tokens":35,"sizeBytes":191},{"name":"README.md","path":"packages/containers-shared/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/containers-shared/README.md","title":"containers-shared Documentation","category":"plugin-manifest","format":"markdown","content":"# @cloudflare/containers-shared\n\nInternal shared container functionality for Cloudflare Workers SDK.\n\n## Internal Use Only\n\nThis package is published only for internal use.\n\nDo not depend on this package directly from external projects. It is not a\npublic SDK, it does not provide a stable API surface, and any function, type,\nexport, behavior, or file path contained in this package may change or be\nremoved at any time without notice.\n\nNo semver compatibility is promised for consumers outside Cloudflare's own\nWorkers SDK packages.\n\n- Cloudchamber/Containers API client\n- Utils for constructing and running docker commands\n- SSH transport shared by Wrangler and cf (OpenSSH and stdio proxy modes)\n- Managed registry image list/delete operations shared by Wrangler and cf\n","isInternal":false,"tokens":157,"sizeBytes":774},{"name":"README.md","path":"packages/create-cloudflare/e2e/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/e2e/README.md","title":"e2e Documentation","category":"plugin-manifest","format":"markdown","content":"# C3 E2E tests\n\nThis directory contains the e2e tests and helpers for C3.\n\n## Running tests locally\n\nThere are three groups of tests:\n\n- CLI - general tests against the C3 CLI tool, such as interactive prompts\n- Workers - tests of the non-framework C3 templates such as `hello-world-durable-object-with-assets-ts`.\n- Frameworks - tests of the framework C3 templates, such as `astro:workers`, `qwik:pages`, etc.\n\n- To run all the tests locally you can do run the following from the root of the monorepo:\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare\n  ```\n\n  This command will actually run the `test:e2e` turbo task in the `create-cloudflare` package, which will also ensure that any dependencies have been built correctly first.\n\n- To run just one group of tests (pass the group name to underlying command):\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare -- workers\n  ```\n\n  You can choose from `cli`, `workers` or `frameworks`.\n\nThe tests that run can be controlled by combining any of the following environment variables:\n\n- `E2E_EXPERIMENTAL` - whether to run the tests in experimental mode - without this variable only non-experimental tests are run.\n- `E2E_TEST_PM` + `E2E_TEST_PM_VERSION` - which package manager to simulate in the tests - without these variables the tests simulate `pnpm`.\n- `E2E_RUN_DEPLOY_TESTS` - whether to ask C3 to deploy generated projects and run tests against the deployed version - if this is not set to `\"true\"`, generated projects are only tested locally.\n- `CLOUDFLARE_API_TOKEN` - the API token to use in tests that connect to Cloudflare - without this variable tests that require Cloudflare access are skipped.\n- `E2E_FRAMEWORK_SHARD` - optional framework case shard in the form `index/count`, with a one-based index. Invalid values fail the run. Without it, all matching cases are collected, including skipped cases.\n- `E2E_TEST_RETRIES` - optional non-negative integer override for framework whole-test retries. Framework tests retain one whole-test retry because they exercise external registries, generators, and runtime startup. Cases can override this allowance in `test-config.ts`. Set this to `0` when investigating a failure or measuring first-attempt reliability. Readiness polling within each attempt is unchanged.\n\n### Running a framework shard\n\nAll framework cases live in one file, so Vitest's file sharding cannot divide this suite. CI runs three case shards per normal package-manager entry and two shards for experimental pnpm. Each runner retains Vitest's default limit of five concurrent tests.\n\nTo reproduce a shard locally, run:\n\n```bash\nE2E_FRAMEWORK_SHARD=1/3 pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nCases are sorted by their full names and distributed round-robin after applying the framework filter and excluding quarantined or unsupported cases. New frameworks and variants are assigned automatically. Use the same package manager, package-manager version, experimental mode, filter, and shard count as CI to reproduce its selection.\n\nThe existing required framework checks wait for every framework shard. Failed, cancelled, or skipped shard jobs fail these checks; deliberately skipped test steps still succeed when framework coverage is not requested.\n\nCI publishes per-attempt logs, Vitest's `results.json`, Turbo summaries, and a retry report. The reported Vitest test duration includes waiting for a concurrency slot, hooks, and all attempts, so use the job/Turbo task duration to measure the critical path. Cached test replays are excluded from retry reports.\n\nTreat a recovered attempt as evidence of a reliability problem, even when CI passes. Keep the single retry while addressing the cause; reduce an allowance only after repeated fresh runs support doing so. A repeatable regression should fail the check, and another attempt should not be used to hide it.\n\nEach attempt shares an absolute package-manager cache across its child processes, outside the generated project. This prevents C3's Git initialization from committing cache contents while isolating concurrent installs. The fixture removes both the project and its cache after the attempt. Wrangler's test configuration uses an automatically assigned inspector port to avoid collisions between concurrent preview sessions.\n\n### Running in experimental mode\n\nC3 can be run in experimental mode, by passing `--experimental` to it as a CLI argument. By default the tests will run in non-experimental mode.\nTo run the tests in experimental mode, simply pass `E2E_EXPERIMENTAL=true` as an environment variable.\n\nFor example, to run the \"cli\" group in experimental mode:\n\n```bash\nE2E_EXPERIMENTAL=true pnpm test:e2e -F create-cloudflare -- cli\n```\n\n> This experimental environment variable can be combined with the package manager environment variables below.\n\n### Running against different package managers\n\nC3 supports running sub-commands and installs using a range of package managers. By default the tests will run agains `pnpm`.\nTo run the tests using a different package manager, simply pass `E2E_TEST_PM` and `E2E_TEST_PM_VERSION` as environment variables.\n\nFor example, to run the \"workers\" group using yarn@1.22.22.\n\n```bash\nE2E_TEST_PM=yarn E2E_TEST_PM_VERSION=1.22.22 pnpm test:e2e -F create-cloudflare -- workers\n```\n\n> These package manager environment variables can be combined with the experimental environment variable above.\n\n### Running Workers templates individually\n\nTo run the e2e tests against a specific Worker template (or group of Worker template variants), provide the `E2E_WORKER_TEMPLATE_TO_TEST` environment variable.\n\nWorker template names and their variants are delimited by colons (`:`).\nIf no colon is specified then all variants will be run for the matching template name.\n\nFor example to only run the python version of the `hello-world-durable-objects` template:\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-durable-object:python pnpm test:e2e -F create-cloudflare -- workers\n```\n\nTo run all the `hello-world-with-assets` variants (`js`, `python`, `ts`):\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-with-assets pnpm test:e2e -F create-cloudflare -- workers\n```\n\n### Running Web frameworks templates individually\n\nTo run the e2e tests against a specific Web framework (or group of Worker template variants), provide the `E2E_FRAMEWORK_TEMPLATE_TO_TEST` environment variable.\n\nFramework templates and their variants (`pages` or `workers`) are delimited by colons (`:`).\nIf no colon is specified in the filter then all variants will be run for the matching template.\n\nFor example to only run the `workers` version of the `react-router` framework:\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=react-router:workers pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nTo run all the `qwik` framework variants (`pages`, `workers`):\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=qwik pnpm test:e2e -F create-cloudflare -- frameworks\n```\n","isInternal":false,"tokens":1524,"sizeBytes":6910},{"name":"README.md","path":"packages/create-cloudflare/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/README.md","title":"create-cloudflare Documentation","category":"plugin-manifest","format":"markdown","content":"# create-cloudflare\n\nA CLI for creating and deploying new applications to [Cloudflare](https://developers.cloudflare.com/).\n\nFor more details on how to use the create-cloudflare CLI (C3) please visit the [official C3 documentation](https://developers.cloudflare.com/pages/get-started/c3).\n\n### Community\n\n- Join us [on Discord](https://discord.cloudflare.com)\n- File an issue [on GitHub](https://github.com/cloudflare/workers-sdk/issues/new/choose)\n","isInternal":false,"tokens":100,"sizeBytes":449},{"name":"README.md","path":"packages/create-cloudflare/templates/django/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/django/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"# Django on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","isInternal":false,"tokens":48,"sizeBytes":192},{"name":"README.md","path":"packages/create-cloudflare/templates/fastapi/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/fastapi/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"# FastAPI on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","isInternal":false,"tokens":49,"sizeBytes":193},{"name":"README.md","path":"packages/create-cloudflare/templates/flask/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/flask/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"# Flask on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n","isInternal":false,"tokens":48,"sizeBytes":191},{"name":"README.md","path":"packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","isInternal":false,"tokens":167,"sizeBytes":756},{"name":"README.md","path":"packages/create-cloudflare/templates/hello-world-durable-object/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/hello-world-durable-object/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","isInternal":false,"tokens":167,"sizeBytes":756},{"name":"README.md","path":"packages/create-cloudflare/templates/hello-world-with-assets/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/hello-world-with-assets/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","isInternal":false,"tokens":167,"sizeBytes":756},{"name":"README.md","path":"packages/create-cloudflare/templates/hello-world/py/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/hello-world/py/README.md","title":"py Documentation","category":"plugin-manifest","format":"markdown","content":"## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n","isInternal":false,"tokens":166,"sizeBytes":751},{"name":"README.md","path":"packages/create-cloudflare/templates/openapi/ts/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/openapi/ts/README.md","title":"ts Documentation","category":"plugin-manifest","format":"markdown","content":"# Cloudflare Workers OpenAPI 3.1\n\nThis is a Cloudflare Worker with OpenAPI 3.1 using [chanfana](https://github.com/cloudflare/chanfana) and [Hono](https://github.com/honojs/hono).\n\nThis is an example project made to be used as a quick start into building OpenAPI compliant Workers that generates the\n`openapi.json` schema automatically from code and validates the incoming request to the defined parameters or request body.\n\n## Get started\n\n1. Sign up for [Cloudflare Workers](https://workers.dev). The free tier is more than enough for most use cases.\n2. Clone this project and install dependencies with `npm install`\n3. Run `wrangler login` to login to your Cloudflare account in wrangler\n4. Run `wrangler deploy` to publish the API to Cloudflare Workers\n\n## Project structure\n\n1. Your main router is defined in `src/index.ts`.\n2. Each endpoint has its own file in `src/endpoints/`.\n3. For more information read the [chanfana documentation](https://chanfana.pages.dev/) and [Hono documentation](https://hono.dev/docs).\n\n## Development\n\n1. Run `wrangler dev` to start a local instance of the API.\n2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints.\n3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface.\n","isInternal":false,"tokens":322,"sizeBytes":1343},{"name":"README.md","path":"packages/create-cloudflare/templates/react-router/ts/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/create-cloudflare/templates/react-router/ts/README.md","title":"ts Documentation","category":"plugin-manifest","format":"markdown","content":"# Welcome to React Router!\n\nA modern, production-ready template for building full-stack React applications using React Router.\n\n## Features\n\n- 🚀 Server-side rendering\n- ⚡️ Hot Module Replacement (HMR)\n- 📦 Asset bundling and optimization\n- 🔄 Data loading and mutations\n- 🔒 TypeScript by default\n- 🎉 TailwindCSS for styling\n- 📖 [React Router docs](https://reactrouter.com/)\n\n## Getting Started\n\n### Installation\n\nInstall the dependencies:\n\n```bash\nnpm install\n```\n\n### Development\n\nStart the development server with HMR:\n\n```bash\nnpm run dev\n```\n\nYour application will be available at `http://localhost:5173`.\n\n## Previewing the Production Build\n\nPreview the production build locally:\n\n```bash\nnpm run preview\n```\n\n## Building for Production\n\nCreate a production build:\n\n```bash\nnpm run build\n```\n\n## Deployment\n\nDeployment is done using the Wrangler CLI.\n\nTo build and deploy directly to production:\n\n```sh\nnpm run deploy\n```\n\nTo deploy a preview URL:\n\n```sh\nnpx wrangler versions upload\n```\n\nYou can then promote a version to production after verification or roll it out progressively.\n\n```sh\nnpx wrangler versions deploy\n```\n\n## Styling\n\nThis template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.\n\n---\n\nBuilt with ❤️ using React Router.\n","isInternal":false,"tokens":312,"sizeBytes":1379},{"name":"README.md","path":"packages/format-errors/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/format-errors/README.md","title":"format-errors Documentation","category":"plugin-manifest","format":"markdown","content":"# format-errors\n\nA Worker that will nicely format errors, optionally inflating with source context if available.\n\n<table>\n     <tr><td><img src=\"./images/service-worker.png\"></td><td><img src=\"./images/modules-worker.png\"></td></tr>\n</table>\n\n## Why is this needed?\n\nIn development, it's nice to have good error messages to help when debugging, and ideally the logic for that shouldn't be bundled into your user Worker. This Worker is ~50kb when gzipped, which doesn't add _that_ much, but there's still a benefit to keeping it separate from the user Worker. Additionally, in environments where we're unable to bundle complex Workers, this error formatting Worker allows for the display of useful errors where otherwise only a stack trace would be available.\n\n## How does it work?\n\nFundamentally, this is based on [Youch](https://github.com/poppinss/youch) and [StackTracey](https://github.com/xpl/stacktracey). Neither of these projects are designed to be run in the Workers environment (although StackTracey does have support for running in the browser), and so both have been vendored in and modified. These modifications aren't upstreamable, since they involve things like changing how Youch detects node-internal modules and changing how sources are loaded.\n\n### Youch changes:\n\n- **\"internal\" module detection:** By default, Youch recognises modules with a prefix of `node:` to be internal modules. Instead, `format-error`s recognises modules with a prefix of `.internal` as internal modules.\n- **source loading:** Youch loads sources at error-page generation time, `format-error`s loads sources at error-page viewing time.\n- **cookies:** `format-error`s doesn't handle cookies.\n\n### Stacktracey changes:\n\n- **browser detection:** `format-error`s always reports itself to be running inside a browser, but removes references to browser globals like `window`.\n- **table rendering:** To remove the `as-table` dependency, `format-error` doesn't implement Stacktracey's `asTable` method, which Youch doesn't use.\n\n## How can you get a formatted error page?\n\nThe first thing you'll need is an error. `format-errors` requires input conforming to the `Payload` interface below, and will reject invalid input at runtime:\n\n```ts\nexport interface JsonError {\n\tmessage?: string;\n\tname?: string;\n\tstack?: string;\n\tcause?: JsonError;\n}\nexport interface Payload {\n\turl?: string;\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\terror?: JsonError;\n}\n```\n\nTo call `format-errors` (assuming it's hosted at `https://format-errors.example.com`), send a `POST` request to `https://format-errors.example.com` with a body containing a serialised `Payload` object. `format-errors` will parse your input, pass it to Youch, and generate an HTML page which will be sent back as the response to the `POST` request.\n\nIf you don't need source context, you can stop there! However, if you'd like to get rid of the \"Missing sources\" message, there's a bit more complexity.\n\n> _Why can't I just pass sources to `format-error` in the request body?_\n>\n> Often your sources won't be available at the location where your error is thrown. You may have access to a sourcemap, but your running code probably doesn't have access to your source code in serialised format. As such, this package is geared towards supporting use cases where you have access to your sources at the time of _viewing_ the generated error page (i.e. in-browser editors).\n\nA requirement of passing sources to `format-errors` is that the generated HTML error page needs to be embedded in an iframe. Once you've done that, you can start passing sources from the embedder of the iframe into the generated HTML error page.\n\nAssuming `iframeEl` is a reference to the iframe which embeds the generated error page, here's an example of how you could pass sources to the generated error page:\n\n```ts\nconst encoder = new TextEncoder();\nconst channel = new MessageChannel();\n\niframeEl.addEventListener(\"load\", () => {\n\tiframeEl.contentWindow?.postMessage(\"PORT\", \"*\", [channel.port2]);\n});\n\nchannel.port1.onmessage = (data) => {\n\tif (data.type === \"RequestSources\") {\n\t\tconst message = {\n\t\t\ttype: \"SourcesLoaded\",\n\t\t\tbody: {\n\t\t\t\tfiles: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpath: \"index.js\",\n\t\t\t\t\t\tcontents: encoder.encode(\"console.log('hi')\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinternalLines: 0,\n\t\t\t},\n\t\t};\n\t\tchannel.port1.postMessage(\n\t\t\tmessage,\n\t\t\tmessage.body.files.map((f) => f.contents.buffer)\n\t\t);\n\t}\n};\n```\n\nThe interface is fairly simple. The embedder passes a `MessagePort` to the iframe on load, over which the error page requests sources. Of note: this does not currently support sourcemaps, and it's assumed that the lines within your error stack trace map to the exact line in your source.\n\nThere's one exception to that, to support _very_ limited source transformations, in the `internalLines` property. If you pass a value for `internalLines`, the error page will act as if any error messages from line numbers _below_ `internalLines` are internal, and shouldn't be surfaced to the user. Line numbers in error messages will be remapped so that it appears the user-visible source starts at line `0`, rather than line `internalLines`.\n","isInternal":false,"tokens":1161,"sizeBytes":5147},{"name":"README.md","path":"packages/kv-asset-handler/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/kv-asset-handler/README.md","title":"kv-asset-handler Documentation","category":"plugin-manifest","format":"markdown","content":"# @cloudflare/kv-asset-handler\n\n[![npm](https://img.shields.io/npm/v/@cloudflare/kv-asset-handler.svg)](https://www.npmjs.com/package/@cloudflare/kv-asset-handler) &nbsp;\n[![Run npm tests](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/test.yml) &nbsp;\n[![Lint Markdown](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml/badge.svg)](https://github.com/cloudflare/kv-asset-handler/actions/workflows/lint.yml) &nbsp;\n\n`kv-asset-handler` is an open-source library for managing the retrieval of static assets from [Workers KV](https://developers.cloudflare.com/workers/runtime-apis/kv) inside of a [Cloudflare Workers](https://workers.dev) function. `kv-asset-handler` is designed for use with [Workers Sites](https://developers.cloudflare.com/workers/platform/sites), a feature included in [Wrangler](https://github.com/cloudflare/wrangler), our command-line tool for deploying Workers projects.\n\n`kv-asset-handler` runs as part of a Cloudflare Workers function, so it allows you to customize _how_ and _when_ your static assets are loaded, as well as customize how those assets behave before they're sent to the client.\n\nMost users and sites will not need these customizations, and just want to serve their statically built applications. For that simple use-case, you can check out [Cloudflare Pages](https://pages.cloudflare.com), our batteries-included approach to deploying static sites on Cloudflare's edge network. Workers Sites was designed as a precursor to Cloudflare Pages, so check out Pages if you just want to deploy your static site without any special customizations!\n\nFor users who _do_ want to customize their assets, and want to build complex experiences on top of their static assets, `kv-asset-handler` (and the default [Workers Sites template](https://github.com/cloudflare/worker-sites-template), which is provided for use with Wrangler + Workers Sites) allows you to customize caching behavior, headers, and anything else about how your Workers function loads the static assets for your site stored in Workers KV.\n\nThe Cloudflare Workers Discord server is an active place where Workers users get help, share feedback, and collaborate on making our platform better. The `#workers` channel in particular is a great place to chat about `kv-asset-handler`, and building cool experiences for your users using these tools! If you have questions, want to share what you're working on, or give feedback, [join us in Discord and say hello](https://discord.cloudflare.com)!\n\n- [Installation](#installation)\n- [Usage](#usage)\n- [`getAssetFromKV`](#getassetfromkv)\n  - [Example](#example)\n  * [Return](#return)\n  * [Optional Arguments](#optional-arguments)\n    - [`mapRequestToAsset`](#maprequesttoasset)\n    - [Example](#example-1)\n    - [`cacheControl`](#cachecontrol)\n      - [`browserTTL`](#browserttl)\n      - [`edgeTTL`](#edgettl)\n      - [`bypassCache`](#bypasscache)\n    - [`ASSET_NAMESPACE` (required for ES Modules)](#asset_namespace-required-for-es-modules)\n    - [`ASSET_MANIFEST` (required for ES Modules)](#asset_manifest-required-for-es-modules)\n    - [`defaultETag`](#defaultetag-optional)\n\n* [Helper functions](#helper-functions)\n  - [`mapRequestToAsset`](#maprequesttoasset-1)\n  - [`serveSinglePageApp`](#servesinglepageapp)\n* [Cache revalidation and etags](#cache-revalidation-and-etags)\n\n## Installation\n\nAdd this package to your `package.json` by running this in the root of your\nproject's directory:\n\n```\nnpm i @cloudflare/kv-asset-handler\n```\n\n## Usage\n\nThis package was designed to work with [Worker Sites](https://workers.cloudflare.com/sites).\n\n## `getAssetFromKV`\n\ngetAssetFromKV(Evt) => Promise<Response>\n\n`getAssetFromKV` is an async function that takes an `Evt` object (containing a `Request` and a [`waitUntil`](https://developers.cloudflare.com/workers/runtime-apis/fetch-event#waituntil)) and returns a `Response` object if the request matches an asset in KV, otherwise it will throw a `KVError`.\n\n#### Example\n\nThis example checks for the existence of a value in KV, and returns it if it's there, and returns a 404 if it is not. It also serves index.html from `/`.\n\n### Return\n\n`getAssetFromKV` returns a `Promise<Response>` with `Response` being the body of the asset requested.\n\nKnown errors to be thrown are:\n\n- MethodNotAllowedError\n- NotFoundError\n- InternalError\n\n#### ES Modules\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\nconst assetManifest = JSON.parse(manifestJSON);\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tif (request.url.includes(\"/docs\")) {\n\t\t\ttry {\n\t\t\t\treturn await getAssetFromKV(\n\t\t\t\t\t{\n\t\t\t\t\t\trequest,\n\t\t\t\t\t\twaitUntil(promise) {\n\t\t\t\t\t\t\treturn ctx.waitUntil(promise);\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\t{\n\t\t\t\t\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t\t\t\t\t\tASSET_MANIFEST: assetManifest,\n\t\t\t\t\t}\n\t\t\t\t);\n\t\t\t} catch (e) {\n\t\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t\t// ...\n\t\t\t\t} else {\n\t\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t\t}\n\t\t\t}\n\t\t} else return fetch(request);\n\t},\n};\n```\n\n#### Service Worker\n\n```js\nimport {\n\tgetAssetFromKV,\n\tMethodNotAllowedError,\n\tNotFoundError,\n} from \"@cloudflare/kv-asset-handler\";\n\naddEventListener(\"fetch\", (event) => {\n\tevent.respondWith(handleEvent(event));\n});\n\nasync function handleEvent(event) {\n\tif (event.request.url.includes(\"/docs\")) {\n\t\ttry {\n\t\t\treturn await getAssetFromKV(event);\n\t\t} catch (e) {\n\t\t\tif (e instanceof NotFoundError) {\n\t\t\t\t// ...\n\t\t\t} else if (e instanceof MethodNotAllowedError) {\n\t\t\t\t// ...\n\t\t\t} else {\n\t\t\t\treturn new Response(\"An unexpected error occurred\", { status: 500 });\n\t\t\t}\n\t\t}\n\t} else return fetch(event.request);\n}\n```\n\n### Optional Arguments\n\nYou can customize the behavior of `getAssetFromKV` by passing the following properties as an object into the second argument.\n\n```\ngetAssetFromKV(event, { mapRequestToAsset: ... })\n```\n\n#### `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nMaps the incoming request to the value that will be looked up in Cloudflare's KV\n\nBy default, mapRequestToAsset is set to the exported function [`mapRequestToAsset`](#maprequesttoasset-1). This works for most static site generators, but you can customize this behavior by passing your own function as `mapRequestToAsset`. The function should take a `Request` object as its only argument, and return a new `Request` object with an updated path to be looked up in the asset manifest/KV.\n\nFor SPA mapping pass in the [`serveSinglePageApp`](#servesinglepageapp) function\n\n#### Example\n\nStrip `/docs` from any incoming request before looking up an asset in Cloudflare's KV.\n\n```js\nimport { getAssetFromKV, mapRequestToAsset } from '@cloudflare/kv-asset-handler'\n...\nconst customKeyModifier = request => {\n  let url = request.url\n  //custom key mapping optional\n  url = url.replace('/docs', '').replace(/^\\/+/, '')\n  return mapRequestToAsset(new Request(url, request))\n}\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: customKeyModifier })\n```\n\n#### `cacheControl`\n\ntype: object\n\n`cacheControl` allows you to configure options for both the Cloudflare Cache accessed by your Worker, and the browser cache headers sent along with your Workers' responses. The default values are as follows:\n\n```javascript\nlet cacheControl = {\n\tbrowserTTL: null, // do not set cache control ttl on responses\n\tedgeTTL: 2 * 60 * 60 * 24, // 2 days\n\tbypassCache: false, // do not bypass Cloudflare's cache\n};\n```\n\n##### `browserTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response returned from the Worker. By default set to `null` which will not add the header at all.\n\n##### `edgeTTL`\n\ntype: number | null\nnullable: true\n\nSets the `Cache-Control: max-age` header on the response used as the edge cache key. By default set to 2 days (`2 * 60 * 60 * 24`). When null will not cache on the edge at all.\n\n##### `bypassCache`\n\ntype: boolean\n\nDetermines whether to cache requests on Cloudflare's edge cache. By default set to `false` (recommended for production builds). Useful for development when you need to eliminate the cache's effect on testing.\n\n#### `ASSET_NAMESPACE` (required for ES Modules)\n\ntype: KV Namespace Binding\n\nThe binding name to the KV Namespace populated with key/value entries of files for the Worker to serve. By default, Workers Sites uses a [binding to a Workers KV Namespace](https://developers.cloudflare.com/workers/reference/storage/api/#namespaces) named `__STATIC_CONTENT`.\n\nIt is further assumed that this namespace consists of static assets such as HTML, CSS, JavaScript, or image files, keyed off of a relative path that roughly matches the assumed URL pathname of the incoming request.\n\nIn ES Modules format, this argument is required, and can be gotten from `env`.\n\n##### ES Module\n\n```js\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_NAMESPACE: env.__STATIC_CONTENT,\n\t}\n);\n```\n\n##### Service Worker\n\n```\nreturn getAssetFromKV(event, { ASSET_NAMESPACE: MY_NAMESPACE })\n```\n\n#### `ASSET_MANIFEST` (required for ES Modules)\n\ntype: text blob (JSON formatted) or object\n\nThe mapping of requested file path to the key stored on Cloudflare.\n\nWorkers Sites with Wrangler bundles up a text blob that maps request paths to content-hashed keys that are generated by Wrangler as a cache-busting measure. If this option/binding is not present, the function will fallback to using the raw pathname to look up your asset in KV. If, for whatever reason, you have rolled your own implementation of this, you can include your own by passing a stringified JSON object where the keys are expected paths, and the values are the expected keys in your KV namespace.\n\nIn ES Modules format, this argument is required, and can be imported.\n\n##### ES Module\n\n```js\nimport manifestJSON from \"__STATIC_CONTENT_MANIFEST\";\nlet manifest = JSON.parse(manifestJSON);\nmanifest[\"index.html\"] = \"index.special.html\";\n\nreturn getAssetFromKV(\n\t{\n\t\trequest,\n\t\twaitUntil(promise) {\n\t\t\treturn ctx.waitUntil(promise);\n\t\t},\n\t},\n\t{\n\t\tASSET_MANIFEST: manifest,\n\t\t// ...\n\t}\n);\n```\n\n##### Service Worker\n\n```\nlet assetManifest = { \"index.html\": \"index.special.html\" }\nreturn getAssetFromKV(event, { ASSET_MANIFEST: assetManifest })\n```\n\n#### `defaultMimeType` (optional)\n\ntype: string\n\nThis is the mime type that will be used for files with unrecognized or missing extensions. The default value is `'text/plain'`.\n\nIf you are serving a static site and would like to use extensionless HTML files instead of index.html files, set this to `'text/html'`.\n\n#### `defaultDocument` (optional)\n\ntype: string\n\nThis is the default document that will be concatenated for requests ends in `'/'` or without a valid mime type like `'/about'` or `'/about.me'`. The default value is `'index.html'`.\n\n#### `defaultETag` (optional)\n\ntype: `'strong' | 'weak'`\n\nThis determines the format of the response [ETag header](https://developer.mozilla.org/docs/Web/HTTP/Headers/ETag). If the resource is in the cache, the ETag will always be weakened before being returned.\nThe default value is `'strong'`.\n\n# Helper functions\n\n## `mapRequestToAsset`\n\nmapRequestToAsset(Request) => Request\n\nThe default function for mapping incoming requests to keys in Cloudflare's KV.\n\nTakes any path that ends in `/` or evaluates to an HTML file and appends `index.html` or `/index.html` for lookup in your Workers KV namespace.\n\n## `serveSinglePageApp`\n\nserveSinglePageApp(Request) => Request\n\nA custom handler for mapping requests to a single root: `index.html`. The most common use case is single-page applications - frameworks with in-app routing - such as React Router, VueJS, etc. It takes zero arguments.\n\n```js\nimport { getAssetFromKV, serveSinglePageApp } from '@cloudflare/kv-asset-handler'\n...\nlet asset = await getAssetFromKV(event, { mapRequestToAsset: serveSinglePageApp })\n```\n\n# Cache revalidation and etags\n\nAll responses served from cache (including those with `cf-cache-status: MISS`) include an `etag` response header that identifies the version of the resource. The `etag` value is identical to the path key used in the `ASSET_MANIFEST`. It is updated each time an asset changes and looks like this: `etag: <filename>.<hash of file contents>.<extension>` (ex. `etag: index.54321.html`).\n\nResources served with an `etag` allow browsers to use the `if-none-match` request header to make conditional requests for that resource in the future. This has two major benefits:\n\n- When a request's `if-none-match` value matches the `etag` of the resource in Cloudflare cache, Cloudflare will send a `304 Not Modified` response without a body, saving bandwidth.\n- Changes to a file on the server are immediately reflected in the browser - even when the cache control directive `max-age` is unexpired.\n\n#### Disable the `etag`\n\nTo turn `etags` **off**, you must bypass cache:\n\n```js\n/* Turn etags off */\nlet cacheControl = {\n\tbypassCache: true,\n};\n```\n\n#### Syntax and comparison context\n\n`kv-asset-handler` sets and evaluates etags as [strong validators](https://developer.mozilla.org/en-US/docs/Web/HTTP/Conditional_requests#Strong_validation). To preserve `etag` integrity, the format of the value deviates from the [RFC2616 recommendation to enclose the `etag` with quotation marks](https://tools.ietf.org/html/rfc2616#section-3.11). This is intentional. Cloudflare cache applies the `W/` prefix to all `etags` that use quoted-strings -- a process that converts the `etag` to a \"weak validator\" when served to a client.\n","isInternal":false,"tokens":3279,"sizeBytes":13747},{"name":"README.md","path":"packages/local-explorer-ui/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/local-explorer-ui/README.md","title":"local-explorer-ui Documentation","category":"plugin-manifest","format":"markdown","content":"# Local explorer UI\n\nThis package contains the UI for the local dev data explorer.\nThe built output will be bundled into Miniflare and served by Miniflare at `/cdn-cgi/explorer`.\n\n# API\n\nThis fetches data from an API running in Miniflare at`/cdn-cgi/explorer/api`.\n\nThe API client is generated from the OpenAPI spec in `packages/miniflare/src/workers/local-explorer/openapi.local.json`.\n\n## API Type Generation\n\nThe API client code is auto-generated from the OpenAPI spec using [`@hey-api/openapi-ts`](https://heyapi.dev/).\n\n**Configuration:** `openapi-ts.config.ts`\n\n**Input:** `packages/miniflare/src/workers/local-explorer/openapi.local.json`\n\n**Output:** `src/api/generated/`\n\nThe generated code includes:\n\n- TypeScript types for all API request/response schemas\n- A type-safe SDK client for making API calls\n\n### When does generation run?\n\n| Command        | Behavior                                               |\n| -------------- | ------------------------------------------------------ |\n| `pnpm install` | Runs `openapi-ts` in `postinstall` to generate types   |\n| `pnpm build`   | Runs `openapi-ts` before building                      |\n| `pnpm dev`     | Watches for spec changes and regenerates automatically |\n| `pnpm dev:ui`  | Same as `dev` - watches for spec changes               |\n\nIn development, the `openapi-ts --watch` process runs concurrently with Vite, automatically regenerating the client when the OpenAPI spec changes.\n\n# Developing\n\n`pnpm run dev` in this directory.\n\nOr to run a specific worker against the UI:\n\n1. Run a worker (`fixtures/worker-with-resources`) using Wrangler or Vite, making sure it is running at `localhost:8787`.\n2. Run this package with `pnpm run dev:ui`, which will spin up a dev server for just the UI using Vite.\n","isInternal":false,"tokens":409,"sizeBytes":1770},{"name":"README.md","path":"packages/miniflare/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/miniflare/README.md","title":"miniflare Documentation","category":"plugin-manifest","format":"markdown","content":"# 🔥 Miniflare\n\n**Miniflare** is a simulator for developing and testing\n[**Cloudflare Workers**](https://workers.cloudflare.com/), powered by\n[`workerd`](https://github.com/cloudflare/workerd).\n\n> :warning: Miniflare is a lower level API designed for tools creators, for\n> locally developing Workers use tools built on top of Miniflare such\n> as [Wrangler](../wrangler/README.md) or the [Cloudflare Vite plugin](../vite-plugin-cloudflare/README.md).\n\n## Quick Start\n\n```shell\n$ npm install miniflare --save-dev\n```\n\n```js\nimport { Miniflare } from \"miniflare\";\n\n// Create a new Miniflare instance, starting a workerd server\nconst mf = new Miniflare({\n\tscript: `addEventListener(\"fetch\", (event) => {\n    event.respondWith(new Response(\"Hello Miniflare!\"));\n  })`,\n});\n\n// Send a request to the workerd server, the host is ignored\nconst response = await mf.dispatchFetch(\"http://localhost:8787/\");\nconsole.log(await response.text()); // Hello Miniflare!\n\n// Cleanup Miniflare, shutting down the workerd server\nawait mf.dispose();\n```\n\n## API\n\n### `type Awaitable<T>`\n\n`T | Promise<T>`\n\nRepresents a value that can be `await`ed. Used in callback types to allow\n`Promise`s to be returned if necessary.\n\n### `type Json`\n\n`string | number | boolean | null | Record<string, Json> | Json[]`\n\nRepresents a JSON-serialisable value.\n\n### `type ModuleRuleType`\n\n`\"ESModule\" | \"CommonJS\" | \"Text\" | \"Data\" | \"CompiledWasm\"`\n\nRepresents how a module's contents should be interpreted.\n\n- `\"ESModule\"`: interpret as\n  [ECMAScript module](https://tc39.es/ecma262/#sec-modules)\n- `\"CommonJS\"`: interpret as\n  [CommonJS module](https://nodejs.org/api/modules.html#modules-commonjs-modules)\n- `\"Text\"`: interpret as UTF8-encoded data, expose in runtime with\n  `string`-typed `default` export\n- `\"Data\"`: interpret as arbitrary binary data, expose in runtime with\n  `ArrayBuffer`-typed `default` export\n- `\"CompiledWasm\"`: interpret as binary WebAssembly module data, expose in\n  runtime with `WebAssembly.Module`-typed `default` export\n\n### `interface ModuleDefinition`\n\nRepresents a manually defined module.\n\n- `type: ModuleRuleType`\n\n  How this module's contents should be interpreted.\n\n- `path: string`\n\n  Path of this module. The module's \"name\" will be obtained by converting this\n  to a relative path. The original path will be used to read `contents` if it's\n  omitted.\n\n- `contents?: string | Uint8Array`\n\n  Contents override for this module. Binary data should be passed as\n  `Uint8Array`s. If omitted, will be read from `path`.\n\n### `interface ModuleRule`\n\nRepresents a rule for identifying the `ModuleRuleType` of automatically located\nmodules.\n\n- `type: ModuleRuleType`\n\n  How to interpret modules that match the `include` patterns.\n\n- `include: string[]`\n\n  Glob patterns to match located module paths against (e.g. `[\"**/*.txt\"]`).\n\n- `fallthrough?: boolean`\n\n  If `true`, ignore any further rules of this `type`. This is useful for\n  disabling the built-in `ESModule` and `CommonJS` rules that match `*.mjs` and\n  `*.js`/`*.cjs` files respectively.\n\n### `enum LogLevel`\n\n`NONE, ERROR, WARN, INFO, DEBUG, VERBOSE`\n\nControls which messages Miniflare logs. All messages at or below the selected\nlevel will be logged.\n\n### `interface LogOptions`\n\n- `prefix?: string`\n\n  String to add before the level prefix when logging messages. Defaults to `mf`.\n\n- `suffix?: string`\n\n  String to add after the level prefix when logging messages.\n\n### `class Log`\n\n- `constructor(level?: LogLevel, opts?: LogOptions)`\n\n  Creates a new logger that logs all messages at or below the specified level to\n  the `console`.\n\n- `error(message: Error)`\n\n  Logs a message at the `ERROR` level. If the constructed log `level` is less\n  than `ERROR`, `throw`s the `message` instead.\n\n- `warn(message: string)`\n\n  Logs a message at the `WARN` level.\n\n- `info(message: string)`\n\n  Logs a message at the `INFO` level.\n\n- `debug(message: string)`\n\n  Logs a message at the `DEBUG` level.\n\n- `verbose(message: string)`\n\n  Logs a message at the `VERBOSE` level.\n\n### `class NoOpLog extends Log`\n\n- `constructor()`\n\n  Creates a new logger that logs nothing to the `console`, and always `throw`s\n  `message`s logged at the `ERROR` level.\n\n### `interface QueueProducerOptions`\n\n- `queueName: string`\n\n  The name of the queue where messages will be sent by the producer.\n\n- `deliveryDelay?: number`\n\n  Default number of seconds to delay the delivery of messages to consumers.\n  Value between `0` (no delay) and `42300` (12 hours).\n\n### `interface QueueConsumerOptions`\n\n- `maxBatchSize?: number`\n\n  Maximum number of messages allowed in each batch. Defaults to `5`.\n\n- `maxBatchTimeout?: number`\n\n  Maximum number of seconds to wait for a full batch. If a message is sent, and\n  this timeout elapses, a partial batch will be dispatched. Defaults to `1`.\n\n- `maxRetries?: number`\n\n  Maximum number of times to retry dispatching a message, if handling it throws,\n  or it is explicitly retried. Defaults to `2`.\n\n- `deadLetterQueue?: string`\n\n  Name of another Queue to send a message on if it fails processing after\n  `maxRetries`. If this isn't specified, failed messages will be discarded.\n\n- `retryDelay?: number`\n\n  Number of seconds to delay the (re-)delivery of messages by default. Value\n  between `0` (no delay) and `42300` (12 hours).\n\n### `interface WorkerOptions`\n\nOptions for an individual Worker/\"nanoservice\". All bindings are accessible on\nthe global scope in service-worker format Workers, or via the 2nd `env`\nparameter in module format Workers.\n\n### `interface WorkflowOptions`\n\n- `name: string`\n\n  The name of the Workflow.\n\n- `className: string`\n\n  The name of the class exported from the Worker that implements the `WorkflowEntrypoint`.\n\n- `scriptName?`: string\n\n  The name of the script that includes the `WorkflowEntrypoint`. This is optional because it defaults to the current script if not set.\n\n#### Core\n\n- `name?: string`\n\n  Unique name for this worker. Only required if multiple `workers` are\n  specified.\n\n- `unsafeRegisterWorker?: boolean`\n\n  Whether to advertise this Worker in the dev registry configured by\n  `unsafeDevRegistryPath`. Defaults to `true`.\n\n- `rootPath?: string`\n\n  Path against which all other path options for this Worker are resolved\n  relative to. This path is itself resolved relative to the `rootPath` from\n  `SharedOptions` if multiple workers are specified. Defaults to the current\n  working directory.\n\n- `script?: string`\n\n  JavaScript code for this worker. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set. If it does have\n  imports, `scriptPath` must also be set so Miniflare knows where to resolve\n  them relative to.\n\n- `scriptPath?: string`\n\n  Path of JavaScript entrypoint. If this is a service worker format Worker, it\n  must not have any imports. If this is a modules format Worker, it must not\n  have any _npm_ imports, and `modules: true` must be set.\n\n- `modules?: boolean | ModuleDefinition[]`\n  - If `true`, Miniflare will treat `script`/`scriptPath` as an ES Module and\n    automatically locate transitive module dependencies according to\n    `modulesRules`. Note that automatic location is not perfect: if the\n    specifier to a dynamic `import()` or `require()` is not a string literal, an\n    exception will be thrown.\n\n  - If set to an array, modules can be defined manually. Transitive dependencies\n    must also be defined. Note the first module must be the entrypoint and have\n    type `\"ESModule\"`.\n\n- `modulesRoot?: string`\n\n  If `modules` is set to `true` or an array, modules' \"name\"s will be their\n  `path`s relative to this value. This ensures file paths in stack traces are\n  correct.\n\n<!-- prettier-ignore-start -->\n<!-- (for disabling `;` insertion in `js` code block) -->\n\n- `modulesRules?: ModuleRule[]`\n\n  Rules for identifying the `ModuleRuleType` of automatically located modules\n  when `modules: true` is set. Note the following default rules are always\n  included at the end:\n\n  ```js\n  [\n    { type: \"ESModule\", include: [\"**/*.mjs\"] },\n    { type: \"CommonJS\", include: [\"**/*.js\", \"**/*.cjs\"] },\n  ]\n  ```\n\n  > If `script` and `scriptPath` are set, and `modules` is set to an array,\n  > `modules` takes priority for a Worker's code, followed by `script`, then\n  > `scriptPath`.\n\n<!-- prettier-ignore-end -->\n\n- `compatibilityDate?: string`\n\n  [Compatibility date](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker. Defaults to a date far in the past.\n\n- `compatibilityFlags?: string[]`\n\n  [Compatibility flags](https://developers.cloudflare.com/workers/platform/compatibility-dates/)\n  to use for this Worker.\n\n- `bindings?: Record<string, Json>`\n\n  Record mapping binding name to arbitrary JSON-serialisable values to inject as\n  bindings into this Worker.\n\n- `wasmBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing binary WebAssembly module data\n  to inject as `WebAssembly.Module` bindings into this Worker.\n\n- `textBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing UTF8-encoded data to inject as\n  `string` bindings into this Worker.\n\n- `dataBlobBindings?: Record<string, string>`\n\n  Record mapping binding name to paths containing arbitrary binary data to\n  inject as `ArrayBuffer` bindings into this Worker.\n\n- `serviceBindings?: Record<string, string | typeof kCurrentWorker | { name: string | typeof kCurrentWorker, entrypoint?: string } | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>>`\n\n  Record mapping binding name to service designators to inject as\n  `{ fetch: typeof fetch }`\n  [service bindings](https://developers.cloudflare.com/workers/platform/bindings/about-service-bindings/)\n  into this Worker.\n  - If the designator is a `string`, requests will be dispatched to the Worker\n    with that `name`.\n  - If the designator is `(await import(\"miniflare\")).kCurrentWorker`, requests\n    will be dispatched to the Worker defining the binding.\n  - If the designator is an object of the form `{ name: ..., entrypoint: ... }`,\n    requests will be dispatched to the entrypoint named `entrypoint` in the\n    Worker named `name`. The `entrypoint` defaults to `default`, meaning\n    `{ name: \"a\" }` is the same as `\"a\"`. If `name` is\n    `(await import(\"miniflare\")).kCurrentWorker`, requests will be dispatched to\n    the Worker defining the binding.\n  - If the designator is an object of the form `{ network: { ... } }`, where\n    `network` is a\n    [`workerd` `Network` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L555-L598),\n    requests will be dispatched according to the `fetch`ed URL.\n  - If the designator is an object of the form `{ external: { ... } }` where\n    `external` is a\n    [`workerd` `ExternalServer` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L504-L553),\n    requests will be dispatched to the specified remote server.\n  - If the designator is an object of the form `{ disk: { ... } }` where `disk`\n    is a\n    [`workerd` `DiskDirectory` struct](https://github.com/cloudflare/workerd/blob/bdbd6075c7c53948050c52d22f2dfa37bf376253/src/workerd/server/workerd.capnp#L600-L643),\n    requests will be dispatched to an HTTP service backed by an on-disk\n    directory.\n  - If the designator is an object of the form `{ node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> }`, requests will be dispatched to your custom Node handler. This allows you to access data and functions defined in Node.js from your Worker using Node.js `req` and `res` objects. Note, `miniflare` will be the `Miniflare` instance dispatching the request.\n  - If the designator is a function with the signature `(request: Request, miniflare: Miniflare) => Response`, requests will be dispatched to your custom\n    fetch handler. This allows you to access data and functions defined in Node.js\n    from your Worker using fetch `Request` and `Response` objects. Note, `miniflare` will be the `Miniflare` instance\n    dispatching the request.\n\n- `outboundService?: string | { network: Network } | { external: ExternalServer } | { disk: DiskDirectory } | { node: (req: http.IncomingMessage, res: http.ServerResponse, miniflare: Miniflare) => Awaitable<void> } | (request: Request, miniflare: Miniflare) => Awaitable<Response>`\n\n  Dispatch this Worker's global `fetch()` and `connect()` requests to the\n  configured service. Service designators follow the same rules above for\n  `serviceBindings`.\n\n- `routes?: string[]`\n\n  Array of route patterns for this Worker. These follow the same\n  [routing rules](https://developers.cloudflare.com/workers/platform/triggers/routes/#matching-behavior)\n  as deployed Workers. If no routes match, Miniflare will fallback to the Worker\n  defined first.\n\n#### Cache\n\n- `cacheAPI?: boolean`\n\n  If `false`, default and named caches will be disabled. The Cache API will\n  still be available, it just won't cache anything.\n\n#### Durable Objects\n\n- `durableObjects?: Record<string, string | { className: string, scriptName?: string, useSQLite?: boolean }>`\n\n  Record mapping binding name to Durable Object class designators to inject as\n  `DurableObjectNamespace` bindings into this Worker.\n  - If the designator is a `string`, it should be the name of a `class` exported\n    by this Worker.\n  - If the designator is an object, and `scriptName` is `undefined`, `className`\n    should be the name of a `class` exported by this Worker.\n  - Otherwise, `className` should be the name of a `class` exported by the\n    Worker with a `name` of `scriptName`.\n  - To use the Durable Object SQLite API you must pass `useSQLite: true`.\n\n#### KV\n\n- `kvNamespaces?: Record<string, string> | string[]`\n\n  Record mapping binding name to KV namespace IDs to inject as `KVNamespace`\n  bindings into this Worker. Different Workers may bind to the same namespace ID\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and KV namespace ID are assumed to be the same.\n\n- `sitePath?: string`\n\n  Path to serve Workers Sites files from. If set, `__STATIC_CONTENT` and\n  `__STATIC_CONTENT_MANIFEST` bindings will be injected into this Worker. In\n  modules mode, `__STATIC_CONTENT_MANIFEST` will also be exposed as a module\n  with a `string`-typed `default` export, containing the JSON-stringified\n  manifest. Note Workers Sites files are never cached in Miniflare.\n\n- `siteInclude?: string[]`\n\n  If set, only files with paths matching these glob patterns will be served.\n\n- `siteExclude?: string[]`\n\n  If set, only files with paths _not_ matching these glob patterns will be\n  served.\n  - `assetsPath?: string`\n\n  Path to serve Workers assets from.\n  - `assetsKVBindingName?: string`\n    Name of the binding to the KV namespace that the assets are in. If `assetsPath` is set, this binding will be injected into this Worker.\n\n  - `assetsManifestBindingName?: string`\n    Name of the binding to an `ArrayBuffer` containing the binary-encoded assets manifest. If `assetsPath` is set, this binding will be injected into this Worker.\n\n#### R2\n\n- `r2Buckets?: Record<string, string> | string[]`\n\n  Record mapping binding name to R2 bucket names to inject as `R2Bucket`\n  bindings into this Worker. Different Workers may bind to the same bucket name\n  with different binding names. If a `string[]` of binding names is specified,\n  the binding name and bucket name are assumed to be the same.\n\n#### D1\n\n- `d1Databases?: Record<string, string> | string[]`\n\n  Record mapping binding name to D1 database IDs to inject as `D1Database`\n  bindings into this Worker. Note binding names starting with `__D1_BETA__` are\n  injected as `Fetcher` bindings instead, and must be wrapped with a facade to\n  provide the expected `D1Database` API. Different Workers may bind to the same\n  database ID with different binding names. If a `string[]` of binding names is\n  specified, the binding name and database ID are assumed to be the same.\n\n#### Queues\n\n- `queueProducers?: Record<string, QueueProducerOptions> | string[]`\n\n  Record mapping binding name to queue options to inject as `WorkerQueue` bindings\n  into this Worker. Different Workers may bind to the same queue name with\n  different binding names. If a `string[]` of binding names is specified, the\n  binding name and queue name (part of the queue options) are assumed to be the same.\n\n- `queueConsumers?: Record<string, QueueConsumerOptions> | string[]`\n\n  Record mapping queue name to consumer options. Messages enqueued on the\n  corresponding queues will be dispatched to this Worker. Note each queue can\n  have at most one consumer. If a `string[]` of queue names is specified,\n  default consumer options will be used.\n\n#### Assets\n\n- `directory?: string`\n  Path to serve Workers static asset files from.\n\n- `binding?: string`\n  Binding name to inject as a `Fetcher` binding to allow access to static assets from within the Worker.\n\n- `assetConfig?: { html_handling?: HTMLHandlingOptions, not_found_handling?: NotFoundHandlingOptions, base_path?: string }`\n  Configuration for file-based asset routing - see [docs](https://developers.cloudflare.com/workers/static-assets/routing/#routing-configuration) for options\n\n#### Pipelines\n\n- `pipelines?: Record<string, PipelineOptions> | string[]`\n\n  Record mapping binding name to a Pipeline. Different workers may bind to the same Pipeline with different bindings\n  names. If a `string[]` of pipeline names, the binding and Pipeline name are assumed to be the same.\n\n#### Workflows\n\n- `workflows?: WorkflowOptions[]`\n  Configuration for one or more Workflows in your project.\n\n#### Browser Run\n\n- `browserRendering: BrowserRenderingOptions`\n\n#### Analytics Engine, Sending Email, Vectorize and Workers for Platforms\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n#### Workers AI\n\n_Not yet supported_\n\nIf you need support for these locally, consider using the `serviceBindings`\noption to mock them out.\n\n### `interface SharedOptions`\n\nOptions shared between all Workers/\"nanoservices\".\n\n#### Core\n\n- `rootPath?: string`\n\n  Path against which all other path options for this instance are resolved\n  relative to. Defaults to the current working directory.\n\n- `host?: string`\n\n  Hostname that the `workerd` server should listen on. Defaults to `127.0.0.1`.\n\n- `port?: number`\n\n  Port that the `workerd` server should listen on. Tries to default to `8787`,\n  but falls back to a random free port if this is in use. Note if a manually\n  specified port is in use, Miniflare throws an error, rather than attempting to\n  find a free port.\n\n- `https?: boolean`\n\n  If `true`, start an HTTPS server using a pre-generated self-signed certificate\n  for `localhost`. Note this certificate is not valid for any other hostnames or\n  IP addresses. If you need to access the HTTPS server from another device,\n  you'll need to generate your own certificate and use the other `https*`\n  options below.\n\n  ```shell\n  $ openssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem\n  ```\n\n  ```js\n  import fs from \"node:fs\";\n\n  new Miniflare({\n  \thttpsKey: fs.readFileSync(\"key.pem\", \"utf8\"),\n  \thttpsCert: fs.readFileSync(\"cert.pem\", \"utf8\"),\n  });\n  ```\n\n- `httpsKey?: string`\n\n  When `httpsCert` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded private key.\n\n- `httpsCert?: string`\n\n  When `httpsKey` is also specified, starts an HTTPS server using the value of\n  this option as the PEM encoded certificate chain.\n\n- `inspectorPort?: number`\n\n  Port that `workerd` should start a DevTools inspector server on. Visit\n  `chrome://inspect` in a Chromium-based browser to connect to this. This can be\n  used to see detailed `console.log`s, profile CPU usage, and will eventually\n  allow step-through debugging.\n\n- `verbose?: boolean`\n\n  Enable `workerd`'s `--verbose` flag for verbose logging. This can be used to\n  see simplified `console.log`s.\n\n- `log?: Log`\n\n  Logger implementation for Miniflare's errors, warnings and informative\n  messages.\n\n- `upstream?: string`\n\n  URL to use as the origin for incoming requests. If specified, all incoming\n  `request.url`s will be rewritten to start with this string. This is especially\n  useful when testing Workers that act as a proxy, and not as origins\n  themselves.\n\n  When `upstream` is set, the `Host` header is rewritten to match the upstream\n  server. To preserve the original hostname, Miniflare adds an\n  `MF-Original-Hostname` header containing the original `Host` value:\n\n  ```js\n  export default {\n  \tasync fetch(request) {\n  \t\t// When upstream is set, Host header contains the upstream hostname\n  \t\tconst upstreamHost = request.headers.get(\"Host\");\n  \t\t// Original hostname is preserved in MF-Original-Hostname\n  \t\tconst originalHost = request.headers.get(\"MF-Original-Hostname\");\n  \t\treturn new Response(\n  \t\t\t`Original: ${originalHost}, Upstream: ${upstreamHost}`\n  \t\t);\n  \t},\n  };\n  ```\n\n- `cf?: boolean | string | Record<string, any>`\n\n  Controls the object returned from incoming `Request`'s `cf` property.\n  - If set to a falsy value, an object with default placeholder values will be\n    used\n  - If set to an object, that object will be used\n  - If set to `true`, a real `cf` object will be fetched from a trusted\n    Cloudflare endpoint and cached in `node_modules/.mf` for 30 days\n  - If set to a `string`, a real `cf` object will be fetched and cached at the\n    provided path for 30 days\n\n- `unsafeDevRegistryPath?: string`\n\n  Path to the dev registry directory. This allows Miniflare to automatically\n  discover external services and Durable Objects running on another Miniflare\n  instance and connect them. Workers are advertised by default; set\n  `unsafeRegisterWorker` to `false` to opt out.\n\n- `unsafeDevRegistryDurableObjectProxy?: boolean`\n\n  If `true`, Miniflare will automatically proxy requests to Durable Objects\n  bound to external services and register all Workers' Durable Objects in the dev registry.\n\n- `unsafeHandleDevRegistryUpdate?: (registry: WorkerRegistry) => void`\n\n  Callback invoked when the dev registry is updated with changes to bound services.\n  Receives a copy of the updated registry object. Useful for reacting to external\n  service changes during development.\n\n- `unsafeRuntimeEnv?: Record<string, string>`\n\n  Extra environment variables to set on the spawned `workerd` subprocess.\n  Merged on top of `process.env` and Miniflare's own defaults — most notably\n  `TZ=UTC`, which Miniflare sets to match the production Cloudflare runtime so\n  that `Date` and `Intl` APIs inside the Worker observe UTC during local\n  development. Use this option to override those defaults, for example to test\n  timezone-dependent code with `unsafeRuntimeEnv: { TZ: \"Europe/London\" }`.\n\n- `containerEngine?: string | { localDocker: { socketPath: string, containerEgressInterceptorImage?: string } }`\n\n  Configuration used to connect to the container engine for any Workers that\n  define containers. If a `string` is provided, it is used as the local Docker\n  socket path (e.g. `\"unix:///var/run/docker.sock\"`).\n\n#### Persistence\n\n- `resourcePersistencePath?: string`\n\n  Path to the root directory under which all resource data (Cache, Durable\n  Objects, KV, R2, D1, Workflows, etc.) is persisted. Each resource persists to\n  a subdirectory named after its plugin (e.g. `<resourcePersistencePath>/kv`).\n  When unset, persistence is disabled and data is stored in an ephemeral\n  temporary directory that is cleared on `dispose()`.\n\n- `resourceTmpPath?: string`\n\n  Path to the temporary directory used by plugins that need one (e.g. email\n  logs). Falls back to a subdirectory of Miniflare's own temporary directory if\n  not set.\n\n#### Analytics Engine, Sending Email, Vectorize, Workers AI and Workers for Platforms\n\n_Not yet supported_\n\n### `type MiniflareOptions`\n\n`SharedOptions & (WorkerOptions | { workers: WorkerOptions[] })`\n\nMiniflare accepts either a single Worker configuration or multiple Worker\nconfigurations in the `workers` array. When specifying an array of Workers, the\nfirst Worker is designated the entrypoint and will receive all incoming HTTP\nrequests. Some options are shared between all workers and should always be\ndefined at the top-level.\n\n### `class Miniflare`\n\n- `constructor(opts: MiniflareOptions)`\n\n  Creates a Miniflare instance and starts a new `workerd` HTTP server\n  listening on the configured `host` and `port`.\n\n- `setOptions(opts: MiniflareOptions)`\n\n  Updates the configuration for this Miniflare instance and restarts the\n  `workerd` server. Note unlike Miniflare 2, this does _not_ merge the new\n  configuration with the old configuration. Note that calling this function will\n  invalidate any existing values returned by the `Miniflare#get*()` methods,\n  preventing them from being used.\n\n- `ready: Promise<URL>`\n\n  Returns a `Promise` that resolves with a `http` `URL` to the `workerd` server\n  once it has started and is able to accept requests.\n\n- `dispatchFetch(input: RequestInfo, init?: RequestInit): Promise<Response>`\n\n  Sends a HTTP request to the `workerd` server, dispatching a `fetch` event in\n  the entrypoint Worker. Returns a `Promise` that resolves with the response.\n  Note that this implicitly waits for the `ready` `Promise` to resolve, there's\n  no need to do that yourself first. Additionally, the host of the request's URL\n  is always ignored and replaced with the `workerd` server's.\n\n- `dispatchConnect(options?: { protocol?: \"tcp\"; workerName?: string; port?: number }): Promise<net.Socket>`\n- `dispatchConnect(options: { protocol: \"udp\"; workerName?: string; port?: number }): Promise<dgram.Socket>`\n\n  Opens a connection to a Worker's `connect()` trigger and returns a Node.js\n  `net.Socket` for TCP or `dgram.Socket` for UDP. TCP is used when `protocol` is\n  omitted. This implicitly waits for the runtime to start and connects to the\n  trigger's allocated port when its configured port is `0`. If `workerName` is\n  omitted, the entrypoint Worker is selected. If `port` is omitted, the selected\n  Worker must have exactly one trigger for the selected protocol. Calling\n  `dispose()` closes any sockets opened by this method.\n\n- `getBindings<Env extends Record<string, unknown> = Record<string, unknown>>(workerName?: string): Promise<Env>`\n\n  Returns a `Promise` that resolves with a record mapping binding names to\n  bindings, for all bindings in the Worker with the specified `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getWorker(workerName?: string): Promise<Fetcher>`\n\n  Returns a `Promise` that resolves with a\n  [`Fetcher`](https://workers-types.pages.dev/experimental/#Fetcher) pointing to\n  the specified `workerName`. If `workerName` is not specified, defaults to the\n  entrypoint Worker. Note this `Fetcher` uses the experimental\n  [`service_binding_extra_handlers`](https://github.com/cloudflare/workerd/blob/1d9158af7ca1389474982c76ace9e248320bec77/src/workerd/io/compatibility-date.capnp#L290-L297)\n  compatibility flag to expose\n  [`scheduled()`](https://workers-types.pages.dev/experimental/#Fetcher.scheduled)\n  and [`queue()`](https://workers-types.pages.dev/experimental/#Fetcher.queue)\n  methods for dispatching `scheduled` and `queue` events.\n\n- `getCaches(): Promise<CacheStorage>`\n\n  Returns a `Promise` that resolves with the\n  [`CacheStorage`](https://developers.cloudflare.com/workers/runtime-apis/cache/)\n  instance of the entrypoint Worker. This means if `cacheAPI: false` is set on\n  the entrypoint, calling methods on the resolved value won't do anything.\n\n- `getD1Database(bindingName: string, workerName?: string): Promise<D1Database>`\n\n  Returns a `Promise` that resolves with the\n  [`D1Database`](https://developers.cloudflare.com/d1/platform/client-api/)\n  instance corresponding to the specified `bindingName` of `workerName`. Note\n  `bindingName` must not begin with `__D1_BETA__`. If `workerName` is not\n  specified, defaults to the entrypoint Worker.\n\n- `getDurableObjectNamespace(bindingName: string, workerName?: string): Promise<DurableObjectNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`DurableObjectNamespace`](https://developers.cloudflare.com/workers/runtime-apis/durable-objects/#access-a-durable-object-from-a-worker)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getKVNamespace(bindingName: string, workerName?: string): Promise<KVNamespace>`\n\n  Returns a `Promise` that resolves with the\n  [`KVNamespace`](https://developers.cloudflare.com/workers/runtime-apis/kv/)\n  instance corresponding to the specified `bindingName` of `workerName`. If\n  `workerName` is not specified, defaults to the entrypoint Worker.\n\n- `getQueueProducer<Body>(bindingName: string, workerName?: string): Promise<Queue<Body>>`\n\n  Returns a `Promise` that resolves with the\n  [`Queue`](https://developers.cloudflare.com/queues/platform/javascript-apis/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `getR2Bucket(bindingName: string, workerName?: string): Promise<R2Bucket>`\n\n  Returns a `Promise` that resolves with the\n  [`R2Bucket`](https://developers.cloudflare.com/r2/api/workers/workers-api-reference/)\n  producer instance corresponding to the specified `bindingName` of\n  `workerName`. If `workerName` is not specified, defaults to the entrypoint\n  Worker.\n\n- `dispose(): Promise<void>`\n\n  Cleans up the Miniflare instance, and shuts down the `workerd` server. Note\n  that after this is called, `Miniflare#setOptions()` and\n  `Miniflare#dispatchFetch()` cannot be called. Additionally, calling this\n  function will invalidate any values returned by the `Miniflare#get*()`\n  methods, preventing them from being used.\n\n- `getCf(): Promise<Record<string, any>>`\n\n  Returns the same object returned from incoming `Request`'s `cf` property. This\n  object depends on the `cf` property from `SharedOptions`.\n\n## Configuration\n\n### Local `workerd`\n\nYou can override the `workerd` binary being used by miniflare with a your own local build by setting the `MINIFLARE_WORKERD_PATH` environment variable.\n\nFor example:\n\n```shell\n$ export MINIFLARE_WORKERD_PATH=\"<WORKERD_REPO_DIR>/bazel-bin/src/workerd/server/workerd\"\n```\n\nFor debugging purposes, you can also set `MINIFLARE_WORKERD_CONFIG_DEBUG=<file_path>` which will dump the workerd config to the specified file path.\n","isInternal":false,"tokens":7612,"sizeBytes":30991},{"name":"README.md","path":"packages/miniflare/src/plugins/core/proxy/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/miniflare/src/plugins/core/proxy/README.md","title":"proxy Documentation","category":"plugin-manifest","format":"markdown","content":"# Miniflare API Proxy\n\nMiniflare provides methods for accessing bindings from Node.js, outside a\n`workerd` process. These are implemented by an API proxy that proxies accesses\nand calls to properties and methods over HTTP calls. The directory implements\nthe client for this. The server is implemented as a Durable Object in\n[`src/workers/core/proxy.worker.ts`](../../../workers/core/proxy.worker.ts).\n\nUsing a Durable Object allows us to share references containing I/O objects like\nstreams across requests. The Durable Object contains a \"heap\", mapping addresses\nto references. The \"heap\" is initialised with `globalThis` and `env`.\n\nThe proxy client builds proxies for each object on the heap. Accessing a\nproperty on a proxy will result in a synchronous `GET` operation to the proxy\nserver. If the property is not a method, the value will be serialised back to\nthe client. Note this may involve putting more references on the \"heap\".\n\nIf the property is a method, the client will return a function from the access.\nFuture accesses to the same property key will return the same function without\nthe synchronous `GET` operation. Calling this function will serialise all the\narguments, then perform a synchronous `CALL` operation on the target, and the\nreturn value will be serialised back to the client. If this function returns a\n`Promise`, it will be stored on the \"heap\", and a reference returned. An\nasynchronous `GET` operation will then be performed to resolve the `Promise`,\nand serialise the result. If a function returns a `Promise` once, all future\ncalls will send asynchronous `CALL` operations instead, that resolve the\n`Promise` without an additional round trip.\n\nIf the function call had `ReadableStream` arguments, the first will be sent\nunbuffered after the rest of the arguments. All function calls with\n`ReadableStream` or `Blob` arguments are assumed to be asynchronous. This\nassumption is required as synchronous operations block the main thread and\nprevent chunks from `ReadableStream`s being read.\n\nIf the function call threw, or returned a `Promise` that rejected, the error\nwill be serialised and re-thrown/rejected in the client. Note that the stack\ntrace will be updated to reflect the calling location in the client, not the\nserver.\n\nTo prevent unbounded growth of the \"heap\", all proxies are registered with a\n`FinalizationRegistry`. When the proxy is garbage collected, a `FREE` operation\nwill remove the corresponding \"heap\" entry allowing it to be garbage collected\non the server too.\n\nWhen `workerd` is restarted with `Miniflare#setOptions()` or stopped with\n`Miniflare#dispose()`, all proxies are _poisoned_. Once a proxy is poisoned, it\ncannot be used, and must be recreated. Poisoned proxies are unregistered from\nthe `FinalizationRegistry` too, as the addresses they point too will be invalid\nand shouldn't be freed again.\n","isInternal":false,"tokens":634,"sizeBytes":2860},{"name":"README.md","path":"packages/miniflare/src/workers/cache/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/miniflare/src/workers/cache/README.md","title":"cache Documentation","category":"plugin-manifest","format":"markdown","content":"# The Cache API\n\nThe Cache API within `workerd` is _extremely_ lenient with errors, and will work\nwith a service that doesn't fully support the expected API. This is what it\n_should_ behave like:\n\n## .add()\n\nUnimplemented in the runtime\n\n## .addAll()\n\nUnimplemented in the runtime\n\n## .match()\n\n`workerd` guarantees:\n\n- The method will always be `GET`\n- The request headers will include `Cache-Control: only-if-cached` (which\n  Miniflare ignores)\n- The request headers will include `Cf-Cache-Namespaces` if this is a namespaced\n  cache (i.e. `caches.open(...)`) `workerd` expects:\n- The `Cf-Cache-Status` header to be present with the value:\n  - `MISS` if it's a cache miss, in which case the rest of the response is\n    ignored by `workerd`\n  - `HIT` if it's a cache hit, in which case `workerd` sends the response on to\n    the user, including the full headers and full body\n\n## .put()\n\n`workerd` guarantees:\n\n- The method will always be `PUT`, and the cache key method will always be `GET`\n- The headers will be the headers of the cache key, and the URL will be the URL\n  of the cache key\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The body contains the serialised response for storage\n  - The serialised response will never: - Have a `206` status code - Have a\n    `Vary: *` header - Have a `304` status code `workerd` expects:\n- A `204` (success) or `413` (failure) response code. It doesn't do anything\n  with either\n\n## .delete()\n\n`workerd` guarantees:\n\n- The method will always be `PURGE`, and the cache key method will always be\n  `GET`\n- The headers will include `Cf-Cache-Namespaces` if this is a namespaced cache\n  (i.e. `caches.open(...)`)\n- The header `X-Real-IP` will be set to `127.0.0.1`\n- The remaining headers will be the cache key headers `workerd` expects:\n- Status `200` on success\n- Status `404` on failure\n- Status `429` on rate limit (which will throw in the user worker)\n","isInternal":false,"tokens":547,"sizeBytes":1963},{"name":"README.md","path":"packages/miniflare/src/workers/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/miniflare/src/workers/README.md","title":"workers Documentation","category":"plugin-manifest","format":"markdown","content":"# Miniflare Workers\n\nThis directory contains code for Workers used internally by Miniflare. Files\nending in `*.worker.ts` will be type-checked under\n`@cloudflare/workers-types/experimental`, instead of `@types/node`.\n\nIt also contains dependencies (i.e. header/binding names, other constants and\ntypes) shared between Workers and the Node.js components of Miniflare. These\nmust type check under both typing environments.\n","isInternal":false,"tokens":96,"sizeBytes":421},{"name":"README.md","path":"packages/mock-npm-registry/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/mock-npm-registry/README.md","title":"mock-npm-registry Documentation","category":"plugin-manifest","format":"markdown","content":"# mock-npm-registry\n\nThis internal package can be used in tests by othe packages to set up a mock local npm registry, publish locally built copies of the packages and their dependencies, then install those packages into test fixtures.\n\n## Usage\n\nA good example is the vitest-plugin e2e tests. See packages/vitest-plugin/test/global-setup.ts\n\n```ts\nexport default async function ({ provide }: GlobalSetupContext) {\n\tconst stop = await startMockNpmRegistry(\"@cloudflare/vitest-plugin\");\n\n\t// Create temporary directory\n\tconst projectPath = await createTestProject();\n\texecSync(\"pnpm install\", { cwd: projectPath, stdio: \"ignore\" });\n\n\tprovide(\"tmpPoolInstallationPath\", projectPath);\n```\n\nHere you can see that in Vitest global setup file, we are calling `startMockNpmRegistry()`.\nWe pass in the `@cloudflare/vitest-plugin` package name, which will ensure that this package\n(and all its local dependencies, such as Wrangler, Miniflare, etc) is built and published to the mock registry.\n\nWe then create a temporary test project that has a dependency on `@cloudflare/vitest-plugin`\nand then run `pnpm install`, which will install the locally published packages.\n\nThe path to this temporary test project is provided to tests.\n\n## Debugging\n\nIf you are having problems with the mock npm registry, you can get additional debug logging by setting the `NODE_DEBUG` environment variable.\n\n```env\nNODE_DEBUG=mock-npm-registry\n```\n","isInternal":false,"tokens":317,"sizeBytes":1419},{"name":"README.md","path":"packages/pages-functions/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/pages-functions/README.md","title":"pages-functions Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/pages-functions`\n\n`@cloudflare/pages-functions` compiles a [Cloudflare Pages Functions](https://developers.cloudflare.com/pages/functions/) `functions/` directory into a single [Cloudflare Worker](https://developers.cloudflare.com/workers/) bundle. It provides both a command-line interface and a programmatic API for build tools.\n\nThe package discovers file-based routes, bundles their handlers into an ES module Worker, collects imported Wasm, text, and binary modules, and returns Pages routing metadata through its programmatic API.\n\n> [!WARNING]\n> Pages Functions are not recommended for new development. Build new applications and new server-side functionality with Workers instead. This package is intended to support existing Pages Functions projects and help migrate them incrementally to Workers.\n\n## Installation\n\nInstall the package as a development dependency:\n\n```sh\nnpm install --save-dev @cloudflare/pages-functions\n```\n\n## CLI\n\nCompile the default `functions/` directory into `dist/`:\n\n```sh\nnpx @cloudflare/pages-functions build\n```\n\nTo specify the input and output directories:\n\n```sh\nnpx @cloudflare/pages-functions build ./functions --outdir ./dist/worker\n```\n\nThe command writes the following files:\n\n- `index.js`: the compiled ES module Worker\n- `index.js.map`: the source map, when `--sourcemap` is used\n- Imported Wasm, text, binary, and `assets:` modules required by the Worker\n\nThe generated Worker contains its own router and does not require a `_routes.json` file. To produce one (for example when deploying to Pages), pass `--routes-output <path>`. Pages deployment tools such as Wrangler generate this file on their own and do not need it from the CLI.\n\nThe command only builds the Worker. It does not deploy it or create deployment configuration. By default, the generated Worker falls back to `env.ASSETS.fetch()` when no Function route handles a request, so the deployment must provide an `ASSETS` binding or select another binding with `--fallback-service`.\n\nRuntime-native imports such as `node:*` and `cloudflare:*` are not automatically excluded from the bundle. Pass them through with repeatable `--external` options when the surrounding Worker build or runtime provides them:\n\n```sh\nnpx @cloudflare/pages-functions build --external \"node:*\" --external \"cloudflare:*\"\n```\n\n### CLI options\n\n| Option                      | Description                                            | Default     |\n| --------------------------- | ------------------------------------------------------ | ----------- |\n| `[directory]`               | Pages Functions directory                              | `functions` |\n| `--outdir <path>`           | Output directory                                       | `dist`      |\n| `--minify`                  | Minify the Worker bundle                               | Disabled    |\n| `--sourcemap`               | Generate an external source map                        | Disabled    |\n| `--fallback-service <name>` | Fetcher binding used when no route handles the request | `ASSETS`    |\n| `--external <module>`       | Exclude a module from the bundle; may be repeated      | None        |\n| `--routes-output <path>`    | Write the generated `_routes.json` spec to this path   | Not written |\n| `-h`, `--help`              | Display usage information                              |             |\n| `-v`, `--version`           | Display the package version                            |             |\n\n## Programmatic API\n\nUse `buildPagesFunctions()` when integrating the compiler into another build tool:\n\n```ts\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nconst result = await buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/worker\",\n\tsourcemap: true,\n});\n\nconsole.log(result.entryPointPath);\nconsole.log(result.routesJSON);\n```\n\n`buildPagesFunctions()` returns the generated routing specification as `routesJSON` but does not write a `_routes.json` file. Consumers such as Wrangler can use this metadata when deploying to Pages.\n\n### Build options\n\n| Option                  | Type       | Description                                               | Default           |\n| ----------------------- | ---------- | --------------------------------------------------------- | ----------------- |\n| `functionsDirectory`    | `string`   | Pages Functions directory to compile                      | Required          |\n| `outputDirectory`       | `string`   | Directory for `index.js` and collected modules            | Required          |\n| `assetsOutputDirectory` | `string`   | Directory for files referenced by `assets:` imports       | `outputDirectory` |\n| `fallbackService`       | `string`   | Fetcher binding used when no route handles the request    | `ASSETS`          |\n| `minify`                | `boolean`  | Minify the Worker bundle                                  | `false`           |\n| `sourcemap`             | `boolean`  | Generate an external source map                           | `false`           |\n| `external`              | `string[]` | Module specifiers to exclude from the bundle              | `undefined`       |\n| `routesDescription`     | `string`   | Description included in the returned routes specification | `undefined`       |\n| `metafile`              | `boolean`  | Include the esbuild metafile in the result                | `false`           |\n\n### Build result\n\n`buildPagesFunctions()` returns:\n\n| Property                | Description                                           |\n| ----------------------- | ----------------------------------------------------- |\n| `entryPointPath`        | Absolute path to the generated `index.js`             |\n| `bundleType`            | Always `\"esm\"`                                        |\n| `modules`               | Collected Wasm, text, and binary modules              |\n| `dependencies`          | Inputs included in the generated bundle               |\n| `sourceMapPath`         | Absolute source map path when source maps are enabled |\n| `routesJSON`            | Generated `_routes.json` data                         |\n| `filepathRoutingConfig` | Discovered Pages Functions routes and base URL        |\n| `metafile`              | esbuild metafile when requested                       |\n\nThe package also exports lower-level route discovery, generation, optimization, and validation helpers for tooling authors. Their TypeScript declarations are included with the package.\n\n## Migrate to Workers\n\n[Workers Static Assets](https://developers.cloudflare.com/workers/static-assets/) supports deploying front-end assets and Worker code together. Workers also provides access to more Cloudflare platform features than Pages Functions. New routes and application logic should therefore be written in a Worker rather than added to an existing `functions/` directory.\n\nFor an existing Pages Functions project, you can compile the old Functions during the Worker build and delegate requests to them from your Worker. This lets you migrate one route at a time.\n\nFor example, configure Wrangler to compile the legacy `functions/` directory before it bundles the Worker:\n\n```jsonc\n{\n\t\"$schema\": \"./node_modules/wrangler/config-schema.json\",\n\t\"name\": \"my-worker\",\n\t\"main\": \"./src/index.js\",\n\t// Preserve the compatibility date and flags from your Pages project.\n\t\"compatibility_date\": \"<YOUR_EXISTING_COMPATIBILITY_DATE>\",\n\t\"assets\": {\n\t\t\"directory\": \"./dist/client\",\n\t\t\"binding\": \"ASSETS\",\n\t\t\"run_worker_first\": true,\n\t},\n\t\"build\": {\n\t\t\"command\": \"npx @cloudflare/pages-functions build ./functions --outdir ./dist/pages-functions --external \\\"node:*\\\" --external \\\"cloudflare:*\\\"\",\n\t\t\"watch_dir\": [\"./functions\", \"./src\"],\n\t},\n}\n```\n\nAdjust `assets.directory` and combine the build command with your existing front-end build command as needed. Preserve any compatibility flags used by the Pages project. The `--external` options leave runtime-native imports for Wrangler to process. The `ASSETS` binding is required by the compiler's default fallback behavior. `run_worker_first` ensures the Worker can run Pages Functions routes and middleware before falling back to static assets.\n\nImport the compiled handler from your Worker, handle new or migrated routes first, and use the old Pages Functions handler as a fallback:\n\n```js\nimport legacyPagesFunctions from \"../dist/pages-functions/index.js\";\n\nexport default {\n\tasync fetch(request, env, ctx) {\n\t\tconst url = new URL(request.url);\n\n\t\tif (url.pathname === \"/api/new-route\") {\n\t\t\treturn new Response(\"Handled by the Worker\");\n\t\t}\n\n\t\treturn legacyPagesFunctions.fetch(request, env, ctx);\n\t},\n};\n```\n\nThis ordering means Pages Functions middleware does not run for routes handled directly by the Worker. Migrate authentication, authorization, logging, and other applicable middleware to the Worker before moving routes that depend on it.\n\nAs routes are migrated, remove their files from `functions/` and implement them directly in the Worker. Once no legacy Pages Functions remain, remove the compiler build step and import.\n\nIf the legacy Functions use `assets:` imports, the imported assets must be written into the directory configured by `assets.directory`. The CLI writes them beneath its output directory, so use the programmatic API to select separate Worker and asset outputs:\n\n```js\n// scripts/build-pages-functions.mjs\nimport { buildPagesFunctions } from \"@cloudflare/pages-functions\";\n\nawait buildPagesFunctions({\n\tfunctionsDirectory: \"./functions\",\n\toutputDirectory: \"./dist/pages-functions\",\n\tassetsOutputDirectory: \"./dist/client\",\n\texternal: [\"node:*\", \"cloudflare:*\"],\n});\n```\n\nThen set `build.command` to `node ./scripts/build-pages-functions.mjs`. The `assets:` integration always uses the `ASSETS` binding, even when a different general fallback service is configured.\n\nWorkers do not use Pages `_routes.json` metadata. Configure [Workers Static Assets routing](https://developers.cloudflare.com/workers/static-assets/routing/) explicitly, especially if the Pages project used custom `_routes.json` rules or middleware. See the complete [Pages-to-Workers migration guide](https://developers.cloudflare.com/workers/static-assets/migration-guides/migrate-from-pages/) for bindings, assets, compatibility settings, and deployment changes.\n\n## Contributing\n\nSee the Workers SDK [contributing guide](../../CONTRIBUTING.md) for repository setup and contribution requirements.\n\nFrom the repository root, install dependencies and run package tasks with:\n\n```sh\npnpm install\npnpm run build --filter @cloudflare/pages-functions\npnpm run check:type --filter @cloudflare/pages-functions\npnpm run test:ci --filter @cloudflare/pages-functions\npnpm run dev --filter @cloudflare/pages-functions\n```\n\nThe `dev` task watches this package's implementation; it does not watch an end-user Pages Functions project.\n\nBefore submitting changes, run:\n\n```sh\npnpm prettify\npnpm check\n```\n\n## License\n\nLicensed under either the [Apache 2.0 license](../../LICENSE-APACHE) or the [MIT license](../../LICENSE-MIT) at your option.\n","isInternal":false,"tokens":2238,"sizeBytes":11081},{"name":"README.md","path":"packages/pages-shared/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/pages-shared/README.md","title":"pages-shared Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/pages-shared`\n\nThis is a package that is used internally to power Wrangler and Cloudflare Pages. It contains all the code that is shared between these clients (and possibly any other in the future e.g. the dashboard).\n\nCode should be written so that it can be run in almost any environment (e.g. Deno, Node, browser, Workers), but note that there's currently a bit of weirdness here for `asset-server`, hence the `environment-polyfills` piece.\n\n> [!NOTE]\n> Since code in this package is used by the Pages infrastructure, it is important that PRs are given careful review with regards to how they could cause a failure in production.\n> Ideally, there should be comprehensive tests for changes being made to give extra confidence about the behavior.\n","isInternal":false,"tokens":164,"sizeBytes":763},{"name":"README.md","path":"packages/quick-edit-extension/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/quick-edit-extension/README.md","title":"quick-edit-extension Documentation","category":"plugin-manifest","format":"markdown","content":"# Quick Edit VS Code Extension\n\nThe code in this package is used by the `quick-edit` package, which in turn is used in the `workers-playground` package.\nTo debug this package locally check out the [Quick Edit package README](../quick-edit/README.md).\n","isInternal":false,"tokens":57,"sizeBytes":251},{"name":"README.md","path":"packages/quick-edit/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/quick-edit/README.md","title":"quick-edit Documentation","category":"plugin-manifest","format":"markdown","content":"# VSCode for Web\n\nThis package contains Cloudflare's fork of VSCode for Web, to support web editing of Workers. This package contains code and setup for building VSCode for Web.\n\nThe code in this package is used by the `workers-playground` package.\n\n## Developing\n\nNote: Currently it's not possible to run VSCode's dev server to develop patches. This is because of a limitation with the `wrangler dev` file server for Workers Assets and the number of assets that would be watched locally.\n\n## Building\n\n- Use Node.js 22\n  - VSCode's build process requires this\n- Run `pnpm install`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run setup`\n  - installs dependencies\n  - clones VSCode (currently v1.102.1)\n  - applies the patches specified in `./patches`\n  - symlinks the top level packages within `workers-sdk`\n- Run `pnpm -F \"@cloudflare/quick-edit\" run custom:build`\n  - This takes up to 15 mins to run\n  - It's not `build` because it would then run when people run the top level `pnpm run build` to build other packages in the repository.\n\n## Debugging\n\n- Change the `quickEditHost` constant in [workers-playground/src/QuickEditor/VSCodeEditor.tsx](../workers-playground/src/QuickEditor/VSCodeEditor.tsx) to http://localhost:8787\n- Run the following in parallel:\n  - `pnpm -F workers-playground dev` -> `http://localhost:5173`\n  - `pnpm -F \"@cloudflare/quick-edit\" exec wrangler dev` -> `http://localhost:8787`\n- Get a user token to connect to a preview Worker\n  - Navigate to https://playground-testing.devprod.cloudflare.dev/\n  - This will respond with a `error code: 522` response, which is expected\n  - Grab the `user` cookie from the 522 response\n- Open http://localhost:5173/playground\n  - Open the devtools and add the `user` cookie from the previous step to this site\n  - Refresh the page and play around with the editor\n\n## Deployment\n\nDeployments are managed by GitHub Actions:\n\n- deploy-pages-previews.yml:\n  - Runs on any PR that has the `preview:quick-edit` label.\n  - Deploys a preview, which can then be accessed via [https://<SHA>.quick-edit-cny.pages.dev/].\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production, which can then be accessed via [https://quick-edit-cny.pages.dev/].\n\n## Patching VSCode\n\nIf you need to add additional patches to VSCode, ensure you've run `pnpm run setup`. Then:\n\n1. Make your changes in the checked out VSCode in `vendor/vscode`.\n2. Commit your changes with `git commit -m \"YOUR MESSAGE\" --no-verify` (run this in the `vendor/vscode` directory).\n3. Prepare a new series of patches for VSCode with (again, run in the `vendor/vscode` directory) `git format-patch -o ../../packages/quick-edit/patches base`.\n\n## Modifying VSCode settings\n\nIf you need to change VSCode's configuration, open the `packages/quick-edit/src/index.ts` file.\n\nThe `WORKBENCH_WEB_CONFIGURATION` object contains VSCode's setup config, but the property `configurationDefaults` is most relevant, since it lets you set defaults for any VSCode settings. The format is exactly the same as VSCode's `settings.json` file.\n\n## Embedding VSCode\n\n> [!WARNING]\n> Cloudflare does not officially support embedding this version of VSCode in third-party contexts—use at your own risk! This documentation is aimed at people inside Cloudflare embedding this package.\n\nThe primary purpose of the patches we apply to VSCode is to allow the visible filesystem within VSCode to be controllable from the outside (by a web page that embeds the editor). You can refer to `packages/workers-playground/src/QuickEditor/VSCodeEditor.tsx` as a reference implementation.\n\nTo communicate with VSCode, a web page needs to load the deployed editor in an iframe:\n\n```html\n<iframe\n\tsrc=\"https://quick-edit.devprod.cloudflare.dev?worker=$worker&theme=dark\"\n></iframe>\n```\n\nThe `$worker` query parameter should be set to the path of the to-be-edited Worker on the virtual filesystem. The protocol used for the virtual filesystem is `cfs`, so it should look like `cfs:/my-worker-name`.\n\nTo load files into the VSCode filesystem and react to changes from within VSCode, you need to send over a `MessagePort`:\n\n```ts\nimport { Channel } from \"@cloudflare/workers-editor-shared\";\nimport type {\n\tFromQuickEditMessage,\n\tToQuickEditMessage,\n\tWorkerLoadedMessage,\n\tWrappedChannel,\n} from \"@cloudflare/workers-editor-shared\";\n\nconst editor; // Acquire a reference to the iframe DOM element somehow. This will depend on the frontend framework in use.\n\nconst channel = Channel<ToQuickEditMessage, FromQuickEditMessage>(\n\tnew MessageChannel()\n);\n\neditor.addEventListener(\"load\", () => {\n\teditor.contentWindow.postMessage(\"PORT\", \"*\", [channel.remote]);\n});\n\n// When you have the initial contents of the Worker (loaded from an API, perhaps)\nchannel.postMessage({\n\ttype: \"WorkerLoaded\",\n\tbody: {\n\t\t// Refer to the WorkerLoaded type for details\n\t},\n});\n\nchannel.onMessage((message) => {\n\t// message is of type SetEntryPoint, UpdateFile, CreateFile, or DeleteFile\n\t// Refer to @cloudflare/workers-editor-shared for details\n});\n```\n","isInternal":false,"tokens":1238,"sizeBytes":5107},{"name":"README.md","path":"packages/runtime-types/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/runtime-types/README.md","title":"runtime-types Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/runtime-types`\n\nUtilities for generating Cloudflare Workers runtime types from compatibility dates and flags.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n","isInternal":false,"tokens":38,"sizeBytes":209},{"name":"README.md","path":"packages/shared-ast-primitives/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/shared-ast-primitives/README.md","title":"shared-ast-primitives Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/shared-ast-primitives`\n\nInternal AST-manipulation primitives shared across Cloudflare Workers SDK codemods.\n\nThis package wraps [`recast`](https://github.com/benjamn/recast) with a small set of\nhelpers (`parseJs`, `parseTs`, `parseFile`, `transformFile`, `mergeObjectProperties`)\nused by C3 and autoconfig to transform user project files. It is private and not published.\n\n## Developing\n\nWriting codemods often requires trial and error. The package ships a dedicated dev workflow so you can iterate on transforms in isolation without writing throw-away scripts.\n\n### Commands\n\n| Command         | Description                                                |\n| --------------- | ---------------------------------------------------------- |\n| `pnpm dev`      | Run `src/dev.ts` in watch mode (hot-reloads on every save) |\n| `pnpm dev:once` | Run `src/dev.ts` once without watching                     |\n\n### Workflow\n\n1. **Edit `dev-snippets/test.ts`** — put whatever source code you want to transform into this file. It is the default input used by the dev script. You can add more files under `dev-snippets/` and reference them from `src/dev.ts`.\n\n2. **Edit `testCodemod()` in `src/dev.ts`** — this is your sandbox. Call `testTransform()` with the path to your snippet and a [`recast` visitor](https://github.com/benjamn/recast) that describes the transform:\n\n   ```ts\n   const testCodemod = () => {\n   \ttestTransform(\"../dev-snippets/test.ts\", {\n   \t\tvisitIdentifier(n) {\n   \t\t\tn.node.name = \"MyNewName\";\n   \t\t\treturn false;\n   \t\t},\n   \t});\n   };\n   ```\n\n3. **Run `pnpm dev`** — the transformed code is printed to the console and written to `dev-snippets-outputs/test.ts` (gitignored). Inspect the output file to verify the transform behaves as expected.\n\n### `testTransform(filePath, methods)`\n\nMirrors the production `transformFile()` API but instead of silently writing in place it:\n\n- Prints the transformed source to the console\n- Writes the result to the corresponding path under `dev-snippets-outputs/`\n\nThe `filePath` argument must point to a file inside `dev-snippets/`; paths outside that directory are rejected.\n","isInternal":false,"tokens":490,"sizeBytes":2145},{"name":"README.md","path":"packages/solarflare-theme/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/solarflare-theme/README.md","title":"solarflare-theme Documentation","category":"plugin-manifest","format":"markdown","content":"# Solarflare Theme\n\nThe Solarflare theme is an official VSCode theme for utilization with a modified VSCode for Web in the Cloudflare dashboard.\n","isInternal":false,"tokens":30,"sizeBytes":145},{"name":"README.md","path":"packages/turbo-r2-archive/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/turbo-r2-archive/README.md","title":"turbo-r2-archive Documentation","category":"plugin-manifest","format":"markdown","content":"# Turbo R2 Archive\n\n[![Deploy to Cloudflare Workers](https://deploy.workers.cloudflare.com/button)](https://deploy.workers.cloudflare.com/?url=https://github.com/jacobMGEvans/Turbo-R2-Archive)\n\n## Overview\n\nThis is a Worker that will act as an event server for caching TurboRepo artifacts. Compliant with the TurboRepo API, for remote caching, it will store the cache artifacts in a Cloudflare R2 bucket and purge the R2 Objects on a schedule, using [R2 Object lifecycle rules](https://blog.cloudflare.com/introducing-object-lifecycle-management-for-cloudflare-r2/). This allows for all the benefits of remote caching TurboRepo artifacts on Cloudflare's edge network.\n\nThis will require a Cloudflare account, with a zone and R2.\n\n## Environment Variables\n\nUtilizing `.env` file to store the variables for Turborepo API & Worker. The `.env` file should be in the root of the project directory. The `.env` file should contain the following variables. Be sure to add the `.env` file to `.gitignore` to prevent it from being committed to the repository.\n\nThe commands are ran with `dotenv` cli `npx dotenv -- npx turbo <command>` to inject the environment variables into the command process environment.\n\n```bash\nTURBO_API=<baseURL> # https://something.com\nTURBO_TEAM=<value> # team_whatever it has to start with prefix team_\nTURBO_TOKEN=<value> # whatever is set in the worker secret\nTURBO_REMOTE_CACHE_SIGNATURE_KEY=<value> # needs to be the same for every one using the same cache\n```\n\n## Turbo Project Config\n\nTo utilize the `TURBO_REMOTE_CACHE_SIGNATURE_KEY` which will increase the security of the remote cache, the project config will need to be updated to include the following:\n\n```json\n{\n\t\"remoteCache\": { \"signature\": true }\n}\n```\n\n## Worker Configuration\n\n```jsonc\n{\n\t\"r2_buckets\": [\n\t\t{\n\t\t\t\"binding\": \"R2_ARTIFACT_ARCHIVE\", // The binding name for the bucket, used in the Worker i.e. env.R2_ARTIFACT_ARCHIVE.get(<key>)\n\t\t\t\"bucket_name\": \"turbo-cache\", // bucket name when looking for objects in dashboard\n\t\t\t\"preview_bucket_name\": \"turbo-cache-preview\",\n\t\t},\n\t],\n}\n```\n\nThe endpoints are protected by a bearer token. The token is stored as a secret in the Worker. The token can be set with the following command:\n\n```bash\necho <VALUE> | wrangler secret put TURBO_TOKEN\n```\n\n<!-- Add the setting up the R2 bucket & Object Rules -->\n\n### Manual Cache Purge\n\nThe cache can also be purged manually by sending a `POST` request to the `<baseURL>/artifacts/manual-cache-bust` endpoint. This can be done with the following command:\n\n```bash\nhttps -A bearer -a <TURBO_TOKEN> POST <baseURL>/artifacts/manual-cache-bust\n```\n\n## How can I develop & test locally?\n\nThis project is primarily self-service and is meant to be forked and modified to fit your needs. The following instructions will help you get started.\n\n### Running the Worker Locally\n\nThe Worker can be run, locally with the `package.json` script `start`:\n\n```bash\nnpm run start\n```\n\n### TurboRepo Testing Local Server\n\nWell since we are already using Cloudflare, let's keep that going. `cloudflared` allows for creating a tunnel to your `http://127.0.0.1:8787` and exposing it to the internet. This will allow others direct their TurboRepo to the local dev server by setting`TURBO_API` to `<host>`.\nThe command to create a tunnel looks like:\n\n```bash\ncloudflared tunnel --hostname <host> --url http://127.0.0.1:8787/ --name r2-archive (or whatever you want to name it)\n```\n\n## How can I deploy this?\n\nFork this repo, have a Cloudflare account, and run the following command:\n\n```bash\nnpm run deploy\n```\n\nYou now have a TurboRepo API compliant event server that will cache artifacts on Cloudflare's edge network.\n","isInternal":false,"tokens":901,"sizeBytes":3673},{"name":"README.md","path":"packages/unenv-preset/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/unenv-preset/README.md","title":"unenv-preset Documentation","category":"plugin-manifest","format":"markdown","content":"# @cloudflare/unenv-preset\n\n[unenv](https://github.com/unjs/unenv) preset for cloudflare.\n\nunenv provides polyfills to add [Node.js](https://nodejs.org/) compatibility for any JavaScript runtime, including browsers and edge workers.\n\n## Usage\n\n```ts\nimport { cloudflare } from \"@cloudflare/unenv-preset\";\nimport { defineEnv } from \"unenv\";\n\nconst { env } = defineEnv({\n\tpresets: [cloudflare],\n});\n\nconst { alias, inject, external, polyfill } = env;\n```\n\nSee the unenv [README](https://github.com/unjs/unenv/blob/main/README.md) for more details.\n\n## Tests\n\nThis package is tested via wrangler e2e tests.\n","isInternal":false,"tokens":159,"sizeBytes":604},{"name":"README.md","path":"packages/vite-plugin-cloudflare/e2e/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vite-plugin-cloudflare/e2e/README.md","title":"e2e Documentation","category":"plugin-manifest","format":"markdown","content":"# vite-plugin e2e tests\n\nThis directory contains e2e tests that give more confidence that the plugin will work in real world scenarios outside the comfort of this monorepo.\n\nIn general, these tests create test projects by copying a fixture from the `fixtures` directory into a temporary directory and then installing the local builds of the plugin along with its dependencies.\n\n## Running the tests\n\nSimply use turbo to run the tests from the root of the monorepo.\nThis will also ensure that the required dependencies have all been built before running the tests.\n\nYou will need to provide CLOUDFLARE_ACCOUNT_ID and CLOUDFLARE_API_TOKEN for the Workers AI tests to pass.\n\n```sh\nCLOUDFLARE_ACCOUNT_ID=xxxx CLOUDFLARE_API_TOKEN=yyyy pnpm test:e2e -F @cloudflare/vite-plugin\n```\n\n## Developing e2e tests\n\nThese tests use a mock npm registry where the built plugin has been published.\n\nThe registry is booted up and loaded with the local build of the plugin and its local dependencies in the global-setup.ts file that runs once at the start of the e2e test run, and the server is killed and its caches removed at the end of the test run. The mock npm registry will delegate to the standard public npm registry for non-local dependency requests (e.g. vite, typescript, etc).\n\nThere is a `seed()` helper to setup a clean copy of a fixture outside of the monorepo so that it can be isolated from any other dependencies in the project.\n\nThe simplest test looks like:\n\n```ts\nconst projectPath = await seed(\"basic\", { pm: \"pnpm\" });\n\ntest(\"can serve a Worker request\", async ({ expect, seed, runLongLived }) => {\n\tconst proc = await runLongLived(\"npm\", \"dev\", projectPath);\n\tconst url = await waitForReady(proc);\n\texpect(await fetchJson(url + \"/api/\")).toEqual({ name: \"Cloudflare\" });\n});\n```\n\n- The `seed()` helper creates a `beforeAll()` block:\n  - make a copy of the named fixture into a temporary directory,\n  - updates the vite-plugin dependency in the package.json to match the local version\n  - runs `npm install` (or equivalent package manager command) in the temporary project - the dependencies are installed from the mock npm registry mentioned above.\n  - returns the path to the directory containing the copy (`projectPath` above)\n- The `seed()` helper also creates an `afterAll()` block:\n  - the temporary directory will be deleted at the end of the test.\n- The `runCommand()` helper simply executes a one-shot command and resolves when it has exited. You can use this to install the dependencies of the fixture from the mock npm registry.\n- The `runLongLived()` helper runs an npm script (from the package.json scripts section) and returns an object that can be used to monitor its output. The process will be killed at the end of the test.\n- The `waitForReady()` helper will resolve when a `vite dev` long lived process has output a ready message, from which it will parse the url that can be fetched in the test.\n- The `fetchJson()` helper makes an Undici fetch to the url parsing the response into JSON. It will retry every 250ms for up to 10 secs to minimize flakes.\n\n## Debugging e2e tests\n\nYou can control the logging and cleanup via environment variables:\n\n- Keep the temporary directory after the tests have completed: `CLOUDFLARE_VITE_E2E_KEEP_TEMP_DIRS=true`\n- See debug logs for the tests: `NODE_DEBUG=vite-plugin:test`\n- See debug logs for the mock npm registry: `NODE_DEBUG=mock-npm-registry`\n- See debug logs for Vite: `DEBUG=\"vite:*\"`\n","isInternal":false,"tokens":788,"sizeBytes":3455},{"name":"README.md","path":"packages/vite-plugin-cloudflare/playground/additional-modules/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vite-plugin-cloudflare/playground/additional-modules/README.md","title":"additional-modules Documentation","category":"plugin-manifest","format":"markdown","content":"# Additional Modules\n\nThe modules directory contains the following example files:\n\n- `bin-example.bin` - a TTF file for the Inter font with the extension changed to `.bin`\n- `html-example.html` - a Hello World HTML document\n- `text-example.txt` - a simple text file\n- `wasm-example.wasm` - a compiled WebAssembly file that exports an `add` function\n\nThe WebAssembly is generated from the following C code:\n\n```c\n#include <stdint.h>\n\nint32_t add(int32_t a, int32_t b) {\n    return a + b;\n}\n```\n","isInternal":false,"tokens":126,"sizeBytes":493},{"name":"README.md","path":"packages/vite-plugin-cloudflare/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vite-plugin-cloudflare/README.md","title":"vite-plugin-cloudflare Documentation","category":"plugin-manifest","format":"markdown","content":"# `@cloudflare/vite-plugin`\n\nThe Cloudflare Vite plugin enables a full-featured integration between [Vite](https://vite.dev/) and the [Workers runtime](https://developers.cloudflare.com/workers/runtime-apis/).\nYour Worker code runs inside [workerd](https://github.com/cloudflare/workerd), matching the production behavior as closely as possible and providing confidence as you develop and deploy your applications.\n\n```ts\n// vite.config.ts\n\nimport { defineConfig } from \"vite\";\nimport { cloudflare } from \"@cloudflare/vite-plugin\";\n\nexport default defineConfig({\n  plugins: [cloudflare()],\n});\n```\n\n## Documentation\n\nFull documentation can be found [here](https://developers.cloudflare.com/workers/vite-plugin/).\n\n## Features\n\n- Uses the Vite [Environment API](https://vite.dev/guide/api-environment) to integrate Vite with the Workers runtime\n- Provides direct access to [Workers runtime APIs](https://developers.cloudflare.com/workers/runtime-apis/) and [bindings](https://developers.cloudflare.com/workers/runtime-apis/bindings/)\n- Builds your front-end assets for deployment to Cloudflare, enabling you to build static sites, SPAs, and full-stack applications\n- Official support for [TanStack Start](https://tanstack.com/start/) and [React Router v8](https://reactrouter.com/) with server-side rendering\n- Leverages Vite's hot module replacement for consistently fast updates\n- Supports `vite preview` for previewing your build output in the Workers runtime prior to deployment\n\n## Use cases\n\n- [TanStack Start](https://tanstack.com/start/)\n- [React Router v8](https://reactrouter.com/)\n- Support for more full-stack frameworks is coming soon\n- Static sites, such as single-page applications, with or without an integrated backend API\n- Standalone Workers\n- Multi-Worker applications\n","isInternal":false,"tokens":392,"sizeBytes":1788},{"name":"tsconfig.plugin.json","path":"packages/vite-plugin-cloudflare/tsconfig.plugin.json","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vite-plugin-cloudflare/tsconfig.plugin.json","title":"vite-plugin-cloudflare Plugin Manifest","category":"plugin-manifest","format":"json","content":"{\n\t\"extends\": \"@cloudflare/workers-tsconfig/worker.json\",\n\t\"compilerOptions\": {\n\t\t\"declaration\": true,\n\t\t\"declarationMap\": true\n\t},\n\t\"include\": [\"src\"],\n\t\"exclude\": [\"src/workers\", \"src/__tests__/fixtures\"]\n}\n","frontmatter":{"extends":"@cloudflare/workers-tsconfig/worker.json","compilerOptions":{"declaration":true,"declarationMap":true},"include":["src"],"exclude":["src/workers","src/__tests__/fixtures"]},"isInternal":false,"tokens":63,"sizeBytes":209},{"name":"README.md","path":"packages/vitest-plugin/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vitest-plugin/README.md","title":"vitest-plugin Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2FREADME.md -->","isInternal":false,"tokens":178,"sizeBytes":794},{"name":"README.md","path":"packages/vitest-plugin/src/worker/lib/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vitest-plugin/src/worker/lib/README.md","title":"lib Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Fsrc%2Fworker%2Flib%2FREADME.md -->","isInternal":false,"tokens":171,"sizeBytes":735},{"name":"README.md","path":"packages/vitest-plugin/test/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/vitest-plugin/test/README.md","title":"test Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fvitest-plugin%2Ftest%2FREADME.md -->","isInternal":false,"tokens":149,"sizeBytes":688},{"name":"README.md","path":"packages/workers-auth/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-auth/README.md","title":"workers-auth Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-auth%2FREADME.md -->","isInternal":false,"tokens":347,"sizeBytes":1353},{"name":"README.md","path":"packages/workers-playground/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-playground/README.md","title":"workers-playground Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-playground%2FREADME.md -->","isInternal":false,"tokens":316,"sizeBytes":1512},{"name":"README.md","path":"packages/workers-shared/asset-worker/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-shared/asset-worker/README.md","title":"asset-worker Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Fasset-worker%2FREADME.md -->","isInternal":false,"tokens":47,"sizeBytes":221},{"name":"README.md","path":"packages/workers-shared/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-shared/README.md","title":"workers-shared Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2FREADME.md -->","isInternal":false,"tokens":354,"sizeBytes":1728},{"name":"README.md","path":"packages/workers-shared/router-worker/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-shared/router-worker/README.md","title":"router-worker Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-shared%2Frouter-worker%2FREADME.md -->","isInternal":false,"tokens":42,"sizeBytes":209},{"name":"README.md","path":"packages/workers-utils/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-utils/README.md","title":"workers-utils Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2FREADME.md -->","isInternal":false,"tokens":47,"sizeBytes":231},{"name":"README.md","path":"packages/workers-utils/src/config/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workers-utils/src/config/README.md","title":"config Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkers-utils%2Fsrc%2Fconfig%2FREADME.md -->","isInternal":false,"tokens":1576,"sizeBytes":7732},{"name":"README.md","path":"packages/workflows-shared/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/workflows-shared/README.md","title":"workflows-shared Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fworkflows-shared%2FREADME.md -->","isInternal":false,"tokens":38,"sizeBytes":189},{"name":"README.md","path":"packages/wrangler/e2e/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/wrangler/e2e/README.md","title":"e2e Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fe2e%2FREADME.md -->","isInternal":false,"tokens":2020,"sizeBytes":7866},{"name":"README.md","path":"packages/wrangler/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/wrangler/README.md","title":"wrangler Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2FREADME.md -->","isInternal":false,"tokens":725,"sizeBytes":2996},{"name":"README.md","path":"packages/wrangler/src/pages/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/packages/wrangler/src/pages/README.md","title":"pages Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=packages%2Fwrangler%2Fsrc%2Fpages%2FREADME.md -->","isInternal":false,"tokens":86,"sizeBytes":428},{"name":"README.md","path":"tools/README.md","rawUrl":"https://raw.githubusercontent.com/cloudflare/workers-sdk/HEAD/tools/README.md","title":"tools Documentation","category":"plugin-manifest","format":"markdown","content":"<!-- Skill available on-demand via /api/skills/cloudflare/workers-sdk?path=tools%2FREADME.md -->","isInternal":false,"tokens":452,"sizeBytes":1896}],"systemPromptSnippet":"<yakaai_skills repo=\"cloudflare/workers-sdk\">\n<!-- File: AGENTS.md (Tokens: ~1851 | Category: root-instruction) -->\n# AGENTS.md\n\nThis file helps AI coding agents work effectively in the Cloudflare Workers SDK\nmonorepo. Prefer authoritative configuration and documentation over copying\ndetails into this file: copied versions, rule lists, and counts become stale.\n\n## Start Here\n\n- Use `pnpm`, not npm or yarn.\n- Use the Node.js and pnpm versions declared in `package.json`.\n- Install dependencies with `pnpm install`.\n- Run commands from the workspace root unless package documentation says\n  otherwise.\n- Before changing a package, read its `AGENTS.md` if it has one.\n- Do not edit generated files directly. Change their source or generator and\n  regenerate them.\n\n## Common Commands\n\nThe root `package.json` is authoritative for available scripts.\n\n- `pnpm build` — build the workspace with Turbo.\n- `pnpm test:ci` — run tests in CI mode.\n- `pnpm test:e2e` — run end-to-end tests; many require Cloudflare credentials.\n- `pnpm check` — run the repository's validation, lint, type, and format checks.\n- `pnpm fix` — apply supported lint and formatting fixes.\n- `pnpm prettify` — format files with oxfmt.\n- `pnpm run <script> --filter <package>` — run a Turbo task for one package.\n- `pnpm -w test:ci -F <package> -- <test-file>` — run a package's specific test\n  file when its test configuration supports it.\n\nPrefer the narrowest relevant test while developing, then run the broader\npackage checks appropriate to the change. Do not run credentialed E2E tests\nunless the task and environment support them.\n\n## Repository Map\n\n| Task                                        | Location                                                              | Notes                                                         |\n| ------------------------------------------- | --------------------------------------------------------------------- | ------------------------------------------------------------- |\n| Add or modify a Wrangler command            | `packages/wrangler/src/`                                              | Commands are registered from `src/index.ts`.                  |\n| Change local development behavior           | `packages/miniflare/src/`                                             | `src/index.ts` contains the main `Miniflare` class.           |\n| Modify embedded runtime workers             | `packages/miniflare/src/workers/`                                     | Worker scripts use `worker:` virtual imports.                 |\n| Change project scaffolding                  | `packages/create-cloudflare/`                                         | Templates and framework support live here.                    |\n| Change the Vite integration                 | `packages/vite-plugin-cloudflare/`                                    | Includes package-specific playgrounds.                        |\n| Change the Vitest integration               | `packages/vitest-plugin/`                                             | Vitest integration for tests running in workerd.              |\n| Change shared config handling               | `packages/workers-utils/src/config/`                                  | Shared types, normalization, and validation.                  |\n| Use shared test helpers                     | `packages/workers-utils/src/test-helpers/`                            | Includes temporary-directory and console helpers.             |\n| Change deploy or versions-upload validation | `packages/deploy-helpers/src/deploy/helpers/validate-worker-props.ts` | Keep deploy and versions-upload behavior aligned.             |\n| Add a fixture                               | `fixtures/`                                                           | Fixtures are workspace members with their own `package.json`. |\n| Change CI                                   | `.github/workflows/`                                                  | `test-and-check.yml` is the main test workflow.               |\n| Change deployment tooling                   | `tools/deployments/`                                                  | Scripts run directly through `esbuild-register`.              |\n| Create a changeset                          | `.changeset/README.md`                                                | Read this file before deciding whether one is required.       |\n\nTurbo orchestrates workspace tasks. Shared TypeScript configuration lives in\n`packages/workers-tsconfig/`; lint and formatting behavior is defined by\n`.oxlintrc.jsonc`, `.oxfmtrc.jsonc`, and `packages/lint-config-shared/`.\n\n## Cross-Tool Development Features\n\nWrangler, the Vite plugin, and the Vitest plugin are all consumers of the\nWorkers development platform. A development feature is not complete merely\nbecause it works through one of them.\n\nImplement development features in Miniflare wherever possible so that every\nconsumer benefits from the same behavior. Keep the integration layers in\nWrangler, the Vite plugin, and the Vitest plugin thin instead of implementing\nequivalent behavior independently in each tool. If Miniflare is not the\nappropriate layer, put shared behavior in the lowest suitable shared package.\n\nWhen adding or changing development functionality:\n\n- assess its impact on Miniflare, Wrangler, the Vite plugin, and the Vitest\n  plugin;\n- update shared configuration types, validation, and runtime behavior where\n  applicable;\n- add coverage at the shared implementation layer; add consumer-specific tests\n  when the consumer's integration or behavior is affected;\n- document intentional differences or unsupported consumers in the change and\n  pull request.\n\n## Implementation Conventions\n\nThe checked-in configuration is authoritative. Run `pnpm check` rather than\nrelying on a duplicated list of every enforced rule. In particular:\n\n- Keep TypeScript strictly typed. Avoid `any`, non-null assertions, and floating\n  promises.\n- Use type-only imports where appropriate and `node:` prefixes for Node.js\n  built-ins.\n- Prefer function declarations for named or exported functions.\n- Add well-formatted JSDoc to exported or public functions and to functions whose\n  purpose is not evident, including useful tags such as `@param` and `@returns`\n  where appropriate.\n- Comments should explain why; do not add comments that merely restate code.\n- Lint-disable comments require a reason after `--`.\n- In Wrangler, use the logger rather than calling `console.*` directly, except\n  inside the logger implementation.\n- For Cloudflare v4 API calls, prefer the existing request helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult`. Reuse or inject\n  these helpers in shared packages rather than adding the `cloudflare` package\n  solely for a simple request. Use the Cloudflare TypeScript SDK when its\n  generated API surface or behavior is materially useful.\n- Import `ci-info` through its default export.\n\noxfmt determines whitespace, quoting, import order, and package.json sorting.\nDo not reproduce those rules manually; run `pnpm prettify`.\n\n## Dependencies and Security\n\n- Packages normally bundle their dependencies. The repository validator in\n  `tools/deployments/validate-package-dependencies.ts` is authoritative.\n- A package that must leave a dependency external declares it in that package's\n  `scripts/deps.ts` as part of `EXTERNAL_DEPENDENCIES`, with an explanation.\n- After changing dependencies, run `pnpm install` so that the lockfile is\n  updated.\n- Do not build shell commands with interpolated or concatenated untrusted input.\n  The custom `workers-sdk/no-unsafe-command-execution` oxlint rule enforces the\n  repository's command-execution constraints.\n\n## Testing Conventions\n\n- Use Vitest for unit and integration tests.\n- Use fixtures for filesystem and Worker scenarios; treat fixtures as\n  user-facing examples and keep them clear and realistic.\n- Use the Vitest plugin when behavior must be tested in workerd.\n- In Vitest tests, obtain `expect` from the test context rather than importing\n  it from `vitest`. Pass `ExpectStatic` to helpers that need it; use\n  `node:assert` where test context is unavailable.\n- Prefer `runInTempDir()` and real filesystem operations over filesystem mocks.\n- Use `mockConsoleMethods()` to capture output and assert against its `out`,\n  `err`, and `warn` properties.\n- Update relevant snapshots when changing user-facing output.\n- New examples under `fixtures/vitest-plugin-examples/` need a\n  `tsconfig.json`.\n\nThe shared defaults are defined in `vitest.shared.ts`; package configurations\nmay override them.\n\n## Changes and Pull Requests\n\n- Work on a branch rather than committing directly to `main`.\n- Read `.changeset/README.md` to determine whether a changeset is required and\n  how to write it. Do not assume every package-code change needs one.\n- Use `.github/PULL_REQUEST_TEMPLATE.md` when preparing a pull request.\n- The PR description requirements are enforced by\n  `tools/deployments/validate-pr-description.ts`; treat that validator and the\n  template as authoritative.\n- Use the repository's established `[package] description` PR-title style.\n- Run the relevant tests and checks locally before pushing.\n\n## Package-Specific Guidance\n\nMany packages provide their own `AGENTS.md`. Locate and read the closest\napplicable file before making changes. When a change makes guidance inaccurate,\nupdate that file in the same change. Put package-specific knowledge in the\npackage's file; keep this root file focused on repository-wide workflow and\nnavigation.\n\n<!-- File: CLAUDE.md (Tokens: ~33 | Category: claude-rule) -->\n# 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\n<!-- File: .github/skills/issue-review.md (Tokens: ~4157 | Category: anthropic-skill) -->\n---\nname: github-issue-review\ndescription: Triage a GitHub issue on cloudflare/workers-sdk. Assesses quality, identifies the component, checks for duplicates, and recommends next steps.\n---\n\n# GitHub Issue Triage Skill\n\nThis skill triages a GitHub issue to assess its quality, identify the affected component, and recommend next steps for the maintainers.\n\n**Important:** This skill runs without bash or network access. All analysis is based on the pre-fetched issue data in `context.json`. Use only `read`, `glob`, `grep`, `edit`, and `write` tools.\n\n## Input\n\nPre-fetched issue data at `data/<issue_number>/context.json` containing the full issue details from the GitHub API (title, body, comments, labels, author, dates).\n\n## Triage Process\n\nPerform the following steps in order. **Stop and skip to Output as soon as you have sufficient evidence for a recommendation.**\n\n### Step 1: Load Issue Details\n\nRead the pre-fetched `context.json` file using the `read` tool.\n\nExtract and note:\n\n- Title and description\n- Issue type (bug report vs feature request vs question)\n- Product/component affected\n- Version reported against (if any)\n- Operating system (if any)\n- Reproduction steps or reproduction link (if any)\n- Error messages (if any)\n- Comment count and any relevant comment content\n- Labels currently applied\n- Issue age (created date) and last activity date\n- `state_reason` if the issue is already closed\n\n### Step 2: Check for Closeable Issues\n\nCheck each of the following categories in order. **STOP at the first match** and skip to Output.\n\n> **Note:** The `state_reason` values in this section (`completed`, `not_planned`) are informational — they indicate the appropriate GitHub close reason for maintainer reference. They are not captured as a field in the output report.\n\n#### 2a: Spam or Junk\n\nRecommend **CLOSE** (state_reason: `not_planned`, no comment needed) if:\n\n- The body contains random characters, test text, or nonsensical content (e.g. \"bhhg\", \"ssssssssss\", \"aloll\")\n- The issue is clearly spam (e.g. loan advertisements, SEO spam, unrelated product promotions)\n- The issue is a blank/empty test issue (e.g. title is \"test\" with no meaningful body)\n- The body is entirely empty or contains only template headers with no content filled in\n\n#### 2b: Reporter Confirmed Resolved\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The reporter explicitly confirmed the issue is resolved in comments\n- The reporter said they found a workaround and no longer need a fix\n- A maintainer indicated it should be closed in comments\n\n#### 2c: Already Fixed in a Prior Release\n\nRecommend **CLOSE** (state_reason: `completed`) if, based on references within the issue comments or linked PRs:\n\n- A comment references a PR or release that addresses this issue\n- The issue describes a bug that was fixed in a version newer than the reporter's version\n- The issue's symptoms match a fix described in a linked PR or comment\n\nWhen closing, cite the specific PR number and release version if known.\n\n**Template:**\n\n> This issue has been fixed in PR #XXXX, which was released in **wrangler X.Y.Z** (or the relevant package version). Please update and let us know if you're still seeing the issue.\n\nOr for older issues where the fix can't be pinpointed:\n\n> This is a fairly old issue, and from testing with the latest version, it appears to have been resolved. I'm going to close it for now — if you're still running into problems on the latest version, feel free to open a new issue with more details and we can investigate further.\n\n#### 2d: Duplicate\n\nRecommend **CLOSE** (state_reason: `not_planned`) if a comment or linked reference in the issue identifies it as a duplicate of another issue — for example, a maintainer has already commented pointing to a canonical issue, or the reporter themselves links to an existing report.\n\nWhen closing, link to the canonical issue.\n\n**Template:**\n\n> Closing as a duplicate of #XXXX. Please follow that issue for updates.\n\nIf the duplicate is in another repo:\n\n> I'm closing this as a duplicate of <owner/repo>#XXXX, which is where this is being tracked.\n\n#### 2e: Not workers-sdk / Wrong Repo\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes Workers **runtime** behavior (fetch API quirks, V8 issues, compatibility flags, crypto APIs) — belongs in [cloudflare/workerd](https://github.com/cloudflare/workerd)\n- The issue is about a third-party framework (Nuxt, SvelteKit, Remix, Hono, React Router) and the bug is in that framework's code, not in Wrangler or the Vite plugin\n- The issue is about an upstream tool (esbuild, Bun, Vite core) rather than Cloudflare's integration\n- The issue is an account/billing/abuse problem — belongs in Cloudflare Support\n\n**Templates:**\n\nFor framework issues:\n\n> It looks like this issue is coming from <framework>, rather than from workers-sdk. I'd recommend opening an issue on that project's repo: <link>. If it turns out to be a workers-sdk issue after all, feel free to open a new issue here with more details.\n\nFor runtime issues:\n\n> This looks like a Workers runtime issue rather than a tooling issue. The right place to track this is [cloudflare/workerd](https://github.com/cloudflare/workerd) — could a maintainer transfer this issue there?\n\n(Set Action field to: \"Transfer to cloudflare/workerd, then post this comment.\")\n\nFor account/support issues:\n\n> Unfortunately, we're unable to provide support for account-level issues via GitHub. Please contact Cloudflare Support at https://dash.cloudflare.com/?to=/:account/support or the email address mentioned in the error message.\n\n#### 2f: Stale / No Response\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue has the `awaiting-response:reporter` or `needs-reproduction` label AND the last activity was >30 days ago\n- The issue is >12 months old with no activity in the last 6 months\n- A maintainer asked for a reproduction or clarification and the reporter never responded\n\n**Template:**\n\n> We haven't heard from you in a while so I'm going to close this issue for now. If you're still running into problems, feel free to open a new issue with more details and we can investigate further.\n\nFor very old issues:\n\n> This is a very old issue so I'm going to close it for now. If you're still running into problems on the latest version, feel free to comment with more details and we can investigate further.\n\n#### 2g: Transient Platform Issue\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The issue describes a one-time API error (500, 503, auth failures) that appears to have been a service incident\n- Multiple users reported the same error around the same time, and it has since stopped\n- The error is from Cloudflare's API (not from Wrangler itself) and there's no way to fix it in workers-sdk\n\n**Template:**\n\n> This was a transient API issue, and should be resolved now. If you're still seeing this error, please open a new issue with the latest details and we can investigate further.\n\nOr for old transient issues:\n\n> This appears to have been a transient server-side API issue. Similar reports were caused by Cloudflare API incidents that have since been resolved. I'm going to close this for now.\n\n#### 2h: User Error / Misunderstanding\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The issue describes expected behavior that the reporter misunderstands\n- The issue is caused by incorrect configuration, wrong SQL syntax, or misuse of an API\n- The fix is a documentation pointer rather than a code change\n\nWhen closing, explain the correct approach and link to relevant documentation. Be helpful, not dismissive.\n\n**Template:**\n\n> This isn't a bug — <brief explanation of the correct behavior>. You can find more details in the docs: <link>. I'm going to close this for now, but feel free to ask on our [Discord](https://discord.cloudflare.com) if you have more questions.\n\n#### 2i: Breaking Change\n\nRecommend **KEEP OPEN** if:\n\n- The requested change would be a breaking change in the current major version\n\nThe issue should remain open as a tracking item. Do not close it — the team hasn't decided against the change, it's deferred to a future major version.\n\n**Suggested labels:** `breaking-change`\n\n**Template:**\n\n> Changing this behavior at this stage would be a breaking change, so it will need to wait for the next major version. I've added the `breaking-change` label to track this.\n\n(Set Action field to: \"Apply `breaking-change` label, then post this comment.\")\n\n#### 2j: Won't Fix / By Design\n\nRecommend **CLOSE** (state_reason: `not_planned`) if:\n\n- The behavior is intentional and documented\n- The team has explicitly decided not to implement this feature\n- The cost/complexity of the change outweighs the benefit\n\n**Templates:**\n\nFor design decisions:\n\n> This is intentional behavior — <brief explanation>. I don't think we're likely to change this in the near future, but we appreciate the feedback.\n\nFor feature requests that won't happen:\n\n> Thanks for the suggestion. We don't intend to implement this right now, but it may be revisited in future. <Optional: brief explanation of why, or pointer to an alternative approach.>\n\n#### 2k: Feature Superseded / Deprecated\n\nRecommend **CLOSE** (state_reason: `completed`) if:\n\n- The requested feature has been implemented via a different mechanism than proposed\n- The issue relates to a deprecated feature that has a replacement\n- A newer feature or package addresses the underlying need\n\n**Template:**\n\n> This has been addressed by <feature/package>. <Brief explanation of how it solves the original request.> I'm going to close this for now.\n\n### Step 3: Check for Insufficient Information\n\nIf the issue wasn't caught by Step 2, recommend **NEEDS MORE INFO** if:\n\n- Bug report has no reproduction steps or link (the bug template requires one)\n- Bug report is missing version information\n- The description is too vague to act on (e.g. \"it doesn't work\" with no details)\n- The error message is missing or truncated\n\n**Template:**\n\n> Thanks for reporting this. Could you provide <specific missing information>? In particular:\n>\n> - <specific question 1>\n> - <specific question 2>\n>\n> A minimal reproduction (a GitHub repo or link we can clone and run) would also help us investigate. Without more details, we won't be able to look into this.\n\n**Suggested label:** `awaiting-response:reporter` (and optionally `needs-reproduction`)\n\n**STOP HERE if** the issue clearly needs more info. Skip to Output.\n\n### Step 4: Identify Component\n\nMap the issue to a package based on labels, title, and body content:\n\n| Signal                                                                           | Package                                         |\n| -------------------------------------------------------------------------------- | ----------------------------------------------- |\n| `package:wrangler` label, wrangler CLI commands, `wrangler.toml`/`wrangler.json` | `packages/wrangler`                             |\n| `package:miniflare` label, local dev simulation                                  | `packages/miniflare`                            |\n| `product:d1` label, D1 database, `d1 execute`, migrations                        | `packages/wrangler` (D1 code is in wrangler)    |\n| `package:vitest` label, worker tests, `vitest-plugin`                            | `packages/vitest-plugin`                        |\n| `package:vite-plugin` label, vite dev, `@cloudflare/vite-plugin`                 | `packages/vite-plugin-cloudflare`               |\n| `package:c3` label, `create-cloudflare`, project scaffolding                     | `packages/create-cloudflare`                    |\n| `product:pages` label, Pages deployment, `_routes.json`, `_headers`              | `packages/wrangler` (Pages code is in wrangler) |\n| `feature:workers-assets` label, static asset serving                             | `packages/wrangler`                             |\n| `product:containers` label, container registry                                   | `packages/wrangler`                             |\n| `product:workflows` label, Workflows API                                         | `packages/wrangler`                             |\n| `feature:workers-builds` label                                                   | Workers Builds (may be internal)                |\n| `python` label, Python Workers                                                   | `packages/wrangler`                             |\n| `product:workers-for-platforms` label, dispatch namespaces                       | `packages/wrangler`                             |\n| `package:kv-asset-handler` label                                                 | `packages/kv-asset-handler`                     |\n| `feature:types` label, `wrangler types` command                                  | `packages/wrangler`                             |\n| R2, KV, Queues, Durable Objects, Vectorize bindings                              | `packages/wrangler`                             |\n| `node-compat`/`nodejs-compat` label, Node.js APIs                                | May be workerd or wrangler depending on context |\n| Workers runtime behavior (not tooling)                                           | Likely belongs in cloudflare/workerd            |\n| Cloudflare dashboard, API behavior                                               | Likely a platform issue, not workers-sdk        |\n\n### Step 5: Assess Reproducibility and Severity\n\nFor **bug reports**, evaluate:\n\n- **Has reproduction?** Does the issue include a minimal repro link or clear steps?\n- **Severity estimate:** Is this a crash, data loss, incorrect behavior, or cosmetic issue?\n- **Scope:** Does it affect all users or a specific configuration?\n- **Workaround available?** Did the reporter or comments mention one?\n- **Version gap:** Is the reporter on an old version? Could updating fix this?\n\nFor **feature requests**, evaluate:\n\n- **Clarity:** Is the proposed solution clearly described?\n- **Use case:** Is the motivation explained?\n- **Scope:** Small enhancement vs large new feature?\n- **Existing alternatives:** Is there already a way to achieve this (even if less convenient)?\n\n## Output Format\n\n**How the output is used:** `report.md` is posted verbatim as a maintainer-facing triage comment on the issue (attributed to an automated bot), and the labels in `summary.json` are applied automatically. Because of this:\n\n- Write `report.md` for maintainers, not the reporter. The **Suggested Comment** section is a _draft_ for a maintainer to send to the reporter — it is **not** posted automatically, so do not phrase the surrounding report as though a reply has already been made.\n- Only put labels in the **Suggested Labels** fields that already exist in the repository. If unsure whether a label exists, omit it rather than guess — non-existent labels are dropped before applying, so inventing labels only weakens the report's accuracy.\n\n### Report Directory Structure\n\n```\n./data/<issue_number>/\n├── report.md          # Full detailed report\n└── summary.json       # Structured JSON summary\n```\n\n### Output Step 1: Write Full Report\n\nWrite the full report to `./data/<issue_number>/report.md`:\n\n```markdown\n# Issue Triage: <owner/repo>#<number>\n\n## Summary\n\n<One-line summary of the issue>\n\n## Classification\n\n- **Type:** <Bug | Feature Request | Question | Discussion>\n- **Component:** <package name or \"unknown\">\n- **Severity:** <Critical | High | Medium | Low | N/A>\n- **Has Reproduction:** <Yes (with link) | No | N/A>\n- **Quality:** <Complete | Partial | Incomplete>\n\n## Findings\n\n- **Created:** <date>\n- **Author:** <username>\n- **Version:** <reported version, or \"not specified\">\n- **Labels:** <labels, or \"none\">\n- **Comments:** <count>\n\n### Analysis\n\n<2-5 bullet points covering what you found — component identification,\nreproducibility assessment, severity reasoning, staleness indicators,\nduplicate candidates. Only include what's relevant.>\n\n## Recommendation\n\n**Status:** <CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\n\n**Reasoning:** <2-3 sentences explaining why>\n\n**Action:** <What a maintainer should do next>\n\n**Suggested Labels:** <labels to add, if any. Use existing repo labels only.>\n\n### Suggested Comment\n\n> <The exact comment to post on the issue. Follow the templates above for the\n> matching closure category. Key principles:\n>\n> - Always offer an escape hatch (\"feel free to open a new issue\")\n> - Link to specific PRs, releases, or docs when available\n> - Be concise for straightforward closures, detailed for design decisions\n> - Never be dismissive or snarky, even for spam (just close silently) or user error\n> - For NEEDS MORE INFO, ask specific questions (not generic \"please provide more details\")\n>   Omit this section entirely for spam (close without comment) or if no comment is needed.>\n```\n\n### Output Step 2: Write Summary File\n\nWrite a machine-readable summary as **JSON** to `./data/<issue_number>/summary.json`. This file is parsed by the triage workflow (to build the dashboard payload and apply labels), so it must be valid JSON with exactly these keys:\n\n```json\n{\n  \"issueNumber\": <issue_number as a number>,\n  \"title\": \"<issue title, with emoji/template prefixes like 'Bug:' removed>\",\n  \"githubUrl\": \"https://github.com/<owner>/<repo>/issues/<issue_number>\",\n  \"recommendation\": \"<CLOSE | KEEP OPEN | NEEDS MORE INFO | NEEDS VERIFICATION>\",\n  \"difficulty\": \"<easy | medium | hard | n/a>\",\n  \"reasoning\": \"<brief reasoning, 1-2 sentences>\",\n  \"suggestedAction\": \"<brief description of next steps>\",\n  \"hasSuggestedComment\": <true if a Suggested Comment section is present in the report, false otherwise>,\n  \"suggestedLabels\": [\"<label>\", \"...\"]\n}\n```\n\n**Key definitions:**\n\n- **issueNumber**: The issue number as a JSON number (not a string).\n- **title**: Issue title with any emoji prefixes (e.g. \"🐛 Bug:\") or template prefixes removed.\n- **githubUrl**: Full URL to the issue.\n- **recommendation**: One of `CLOSE`, `KEEP OPEN`, `NEEDS MORE INFO`, `NEEDS VERIFICATION`.\n- **difficulty**: Estimated fix difficulty — `easy`, `medium`, `hard`, or `n/a` (for feature requests or closures).\n- **reasoning**: Brief summary of why (1-2 sentences).\n- **suggestedAction**: Brief description of next steps.\n- **hasSuggestedComment**: Boolean — `true` if the report includes a Suggested Comment, `false` otherwise.\n- **suggestedLabels**: JSON array of labels to apply, matching the **Suggested Labels** field in the report. Use existing repo labels only (see above). Use an empty array `[]` if there are no labels to apply.\n\n**CRITICAL:** Write valid, parseable JSON only (no trailing commas, no comments, no surrounding markdown fences). Because JSON strings are escaped, `reasoning`/`suggestedAction` may safely contain any punctuation.\n\n<!-- File: .opencode/skills/local-explorer/assets/local-explorer-diagram.md (Tokens: ~509 | Category: anthropic-skill) -->\n```mermaid\nflowchart TB\n\tClient[\"client\"] --> Incoming[\"incoming request\"]\n\tIncoming --> EntryA[\"entry worker\"]\n\tEntryA -->|/cdn-cgi/explorer| ExplorerA[\"explorer worker<br/>(Hono)\"]\n\n\tsubgraph Runtime[\"running Miniflare instances\"]\n\t\tdirection LR\n\n\t\tsubgraph A[\"miniflare A\"]\n\t\t\tdirection TB\n\t\t\tEntryA\n\t\t\tExplorerA\n\t\t\tFrontend[\"frontend<br/>(TanStack Router + React)\"]\n\t\t\tUserWorker[\"user worker\"]\n\t\t\tKV[\"KV, R2, D1\"]\n\t\t\tWrapper[\"wrapped<br/>DO/Workflow class\"]\n\n\t\t\tEntryA --> UserWorker\n\t\t\tExplorerA -->|disk service to serve assets| Frontend\n\t\t\tExplorerA -->|binding| KV\n\t\t\tExplorerA -->|binding| Wrapper\n\t\t\tUserWorker -->|binding| KV\n\t\t\tUserWorker -->|binding| Wrapper\n\t\tend\n\n\t\tsubgraph B[\"miniflare B\"]\n\t\t\tdirection TB\n\t\t\tEntryB[\"entry worker\"]\n\t\t\tExplorerB[\"explorer worker\"]\n\t\t\tEtc[\"etc.\"]\n\n\t\t\tEntryB --> ExplorerB\n\t\t\tExplorerB --> Etc\n\t\tend\n\tend\n\n\tFrontend -->|fetch /cdn-cgi/explorer/api| Incoming\n\tExplorerA -->|fetch /cdn-cgi/explorer/api/resource with NO_AGGREGATE_HEADER| EntryB\n\n\tsubgraph FS[\"filesystem\"]\n\t\tRegistry[\"dev registry\"]\n\t\tDOState[\".wrangler/state/durable-objects<br/>(list DOs, delete workflows, etc.)\"]\n\tend\n\n\tExplorerA -->|node loopback binding| FS\n\n\tclassDef miniflareA stroke:#f08c00,fill:#fff7ed,color:#1e1e1e;\n\tclassDef userResource stroke:#1971c2,fill:#eff6ff,color:#1e1e1e;\n\tclassDef entry stroke:#e03131,fill:#fff5f5,color:#1e1e1e;\n\tclassDef neutral stroke:#1e1e1e,fill:#ffffff,color:#1e1e1e;\n\n\tclass EntryA entry;\n\tclass ExplorerA,Frontend,Wrapper miniflareA;\n\tclass UserWorker,KV userResource;\n\tclass Client,Incoming,Runtime,FS,Registry,DOState,EntryB,ExplorerB,Etc neutral;\n```\n\n<!-- File: .opencode/skills/local-explorer/SKILL.md (Tokens: ~1206 | Category: anthropic-skill) -->\n---\nname: local-explorer\ndescription: How to add products/resources to the local explorer or local API. Use when implementing new local APIs, or UI routes under packages/miniflare/src/workers/local-explorer or packages/local-explorer-ui.\n---\n\n# Cloudflare Local Explorer Products\n\nUse this skill when adding a new product or resource type to the local API and/or local explorer.\n\n## Start Here\n\nRead these files before editing:\n\n- `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`\n- `packages/miniflare/src/plugins/core/explorer.ts`\n- `packages/miniflare/src/plugins/core/types.ts`\n- One existing resource implementation in `packages/miniflare/src/workers/local-explorer/resources/`, preferably the product most similar to the new one\n- One matching test in `packages/miniflare/test/plugins/local-explorer/`\n\nIf there are UI changes, also read:\n\n- `packages/local-explorer-ui/src/components/Sidebar.tsx`\n- Existing route files under `packages/local-explorer-ui/src/routes/`\n- Existing product e2e tests under `packages/local-explorer-ui/src/__e2e__/`\n\n## Workflow\n\n1. Add the API surface to `packages/miniflare/scripts/openapi-filter-config.ts`.\n2. Generate Miniflare's filtered spec and backend types from a full Cloudflare OpenAPI spec:\n\n```bash\nOPENAPI_INPUT_PATH=<path-to-full-openapi-spec> pnpm --dir packages/miniflare generate:api\n```\n\n3. Inspect `packages/miniflare/src/workers/local-explorer/openapi.local.json` and generated types. If the generated schemas include fields local explorer will not support, add ignores in `openapi-filter-config.ts` and regenerate.\n4. The explorer worker should have access to all user resource bindings. Ensure `proxyBindings` include bindings to the new product and that `getExplorerServices()` exposes any extra bindings the explorer worker needs. Wire product bindings through `constructExplorerBindingMap()` and `constructExplorerWorkerOpts()` in `packages/miniflare/src/plugins/core/explorer.ts`.\n5. Add or extend resource binding metadata in `packages/miniflare/src/plugins/core/types.ts`.\n6. Implement handlers in `packages/miniflare/src/workers/local-explorer/resources/<product>.ts`. Make sure to account for cross-instance aggregation, if applicable.\n7. Register Hono routes in `packages/miniflare/src/workers/local-explorer/explorer.worker.ts`.\n8. Validate request bodies and query params with generated Zod schemas from `generated/zod.gen.ts` using `validateRequestBody()` and `validateQuery()`.\n9. Return Cloudflare API envelope responses using `wrapResponse()` and `errorResponse()` from `common.ts` unless an existing endpoint for that product uses a different response shape.\n10. Add Miniflare tests in `packages/miniflare/test/plugins/local-explorer/<product>.spec.ts`.\n11. Regenerate the UI API client:\n\n```bash\npnpm --dir packages/local-explorer-ui build\n```\n\n12. Add UI routes/components. Use Kumo components for new UI. See https://github.com/cloudflare/kumo/blob/main/AGENTS.md.\n13. Add Playwright e2e tests under `packages/local-explorer-ui/src/__e2e__/<product>/` for new visible product flows.\n\n## OpenAPI Rules\n\n- Do not edit generated files like `packages/miniflare/src/workers/local-explorer/openapi.local.json` or `packages/miniflare/src/workers/local-explorer/generated/` directly.\n- Prefer upstream Cloudflare API paths when a public API exists.\n- Use `extensions.paths` in `openapi-filter-config.ts` only for local-only APIs or APIs that do not exist in the public Cloudflare API.\n- Add ignores for unsupported params, headers, request body properties, and response fields rather than pretending to support them.\n\n## Backend Patterns\n\n- Local list endpoints such as listing KV namespaces should not implement pagination as this may require cross-instance aggregation. Pagination should be supported when targeting individual resources, such as listing KV keys within a specific namespace.\n- For cross-worker aggregation, use `aggregateListResults()`, `getPeerUrlsIfAggregating()`, and `fetchFromPeer()` from `aggregation.ts`; do not hand-roll peer discovery. Add tests for both local-only behavior and aggregated behavior when the product can span multiple instances.\n- If an API needs direct filesystem access, call through the loopback service (`c.env.MINIFLARE_LOOPBACK`) to a Node.js endpoint. The local explorer API runs inside workerd, so it cannot access the host filesystem directly.\n- If an endpoint needs metadata that is not available on the runtime binding itself, put that metadata in `BindingIdMap` and pass it through `CoreBindings.JSON_LOCAL_EXPLORER_BINDING_MAP`.\n- If a product should appear in `/api/local/workers`, add it to `WorkerResourceBindings` and populate it in `constructExplorerWorkerOpts()`.\n\n## UI Patterns\n\n- The UI API client is generated from `packages/miniflare/src/workers/local-explorer/openapi.local.json` into `packages/local-explorer-ui/src/api/generated/`.\n- Sidebar resources come from `/api/local/workers`; update `LocalExplorerWorkerBindings` usage and `Sidebar.tsx` when the product should appear in navigation.\n- Add route files under `packages/local-explorer-ui/src/routes/`. TanStack Router regenerates `src/routeTree.gen.ts` during UI build/dev.\n- Preserve worker selection by carrying the `worker` search param through product links when following sidebar patterns.\n- Use Kumo for new UI components wherever possible. Do not introduce a parallel component system.\n- Do not use tailwindCSS color tokens, use Kumo color tokens instead.\n\n<!-- File: packages/create-cloudflare/AGENTS.md (Tokens: ~520 | Category: anthropic-skill) -->\n# AGENTS.md — Create Cloudflare (C3)\n\n## OVERVIEW\n\nProject scaffolding CLI for Cloudflare Workers. Main source entry: `src/cli.ts`. Bin entry: `bin/c3.js` (Node.js version gate shim).\n\n## STRUCTURE\n\n- `bin/c3.js` — Bin shim that checks Node.js version before requiring `dist/cli.js`\n- `src/cli.ts` — Main entry. Exports `main(argv)` for programmatic use\n- `templates/` — Scaffolding templates (excluded from linting and most formatting)\n- `src/wrangler/` — Wrangler config, login, and account helpers\n- `src/cf/` — Helpers for projects configured by `cloudflare.config.ts`, which use the `cf` CLI instead of Wrangler (detected with `usesCfCli`)\n- `scripts/build.ts` — esbuild-based build → `dist/cli.js`\n\n## BUILD\n\n- esbuild bundles `src/cli.ts` as CJS → `dist/cli.js`\n- `package.json` `main` and `exports[\".\"]` point at `dist/cli.js`; `bin` points at `bin/c3.js`\n- `bin/c3.js` is a plain CommonJS shim that gates on Node.js version (read from `package.json` `engines.node`) before requiring `dist/cli.js`\n\n## CONVENTIONS\n\n- `no-console: error` — use project's logging utilities\n- Templates excluded from linting (except `c3.ts` files within templates)\n- Templates excluded from formatting (except hello-world templates)\n\n## TESTING\n\n- E2E tests run across pnpm/npm (yarn/bun also supported but not in CI), Linux/Windows\n- Own vitest setup: mocks `log-update` and `@cloudflare/cli-shared-helpers/streams`\n- CI has experimental matrix for framework testing\n- Framework CI uses case shards within one test file (three normal, two experimental), controlled by `E2E_FRAMEWORK_SHARD`. Preserve coverage across every shard and keep shard selections in the test's Turbo cache inputs.\n- Whole-framework tests retain one retry for transient failures in external registries, generators, and runtime startup. Per-case allowances live in `e2e/tests/frameworks/test-config.ts`; `E2E_TEST_RETRIES=0` disables retries for local investigations. Keep recovered attempts visible in retry reports and fix their causes before reducing allowances.\n- Python/UV installed in CI for Python framework E2E tests\n\n<!-- File: packages/miniflare/AGENTS.md (Tokens: ~975 | Category: anthropic-skill) -->\n# Miniflare — Agent Guide\n\n## Overview\n\nLocal dev simulator for Cloudflare Workers, powered by workerd runtime. Main class `Miniflare` in `src/index.ts`.\n\n## Structure\n\n- `src/index.ts` — Main `Miniflare` class, server setup, plugin orchestration, all exports\n- `src/workers/` — ~30 embedded worker scripts (D1, KV, R2, caches, etc.), built via `worker:` virtual import scheme\n- `src/workers/d1/entry.worker.ts` — D1-specific HTTP/RPC entrypoint; selects a database using binding props and adapts RPC queries to the database worker's HTTP protocol\n- `src/workers/d1/database.worker.ts` — local D1 SQLite execution, transactions, metadata, and export; protocol schemas shared with the entrypoint live in `src/workers/d1/schemas.ts`\n- `src/workers/d1/export.ts` — shared local export pragma recognition and dedicated RPC export adaptation; keeps the legacy export response separate from ordinary query contracts\n- `src/workers/shared/` — Shared utilities across embedded workers\n- `src/workers/core/dev-registry-proxy.worker.ts` — Proxy worker for cross-process service bindings via debug port RPC\n- `src/workers/core/dev-registry-proxy-shared.worker.ts` — Shared proxy logic (registry Map, DO proxy class, tail serializers)\n- `src/shared/dev-registry.ts` — Filesystem-based worker registry (chokidar watch, heartbeat, stale cleanup)\n- `src/shared/persist-root-lock.ts` — Token-safe startup serialisation for shared persistent storage\n- `src/shared/DEV_REGISTRY.md` — Full architecture doc for the dev registry\n- `src/runtime/config/generated/workerd.ts` — Generated workerd Cap'n Proto config types\n- `test/` — Tests (`.spec.ts` naming, NOT `.test.ts`)\n- `test/test-shared/` — Shared test utilities\n- `scripts/build.mjs` — Custom esbuild build script\n\n## Build\n\n- Custom `scripts/build.mjs` bundles `src/index.ts` as CJS → `dist/src/index.js`\n- Also compiles ~30 embedded worker scripts via `worker:...` virtual import scheme — each triggers a nested esbuild sub-build producing standalone ESM worker scripts\n- Build outputs: `dist/`, `worker-metafiles/`\n- Release builds set `SOURCEMAPS=false` to omit package source maps; ordinary builds keep them for debugging. Non-watch builds clean `dist/` before compiling so maps from an earlier build cannot leak into a release. This does not disable user Worker source maps.\n\n## Lint Status (Transitional)\n\n- Many shared ESLint rules temporarily DISABLED: `no-explicit-any`, `consistent-type-imports`, `no-shadow`, `no-floating-promises`, others\n- Comment in config: \"temporarily enabled while we transition Miniflare to use the standard workers-sdk eslint config\"\n- `no-console: error` is on, except for `src/workers/` and `scripts/`\n\n## TypeScript\n\n- Does NOT extend shared `@cloudflare/workers-tsconfig` — has its own full config\n- Uses `experimentalDecorators`\n- Path aliases: `miniflare:shared`, `miniflare:zod`\n- `declaration: true` (emits .d.ts)\n\n## Testing\n\n- Test files use `.spec.ts` (NOT `.test.ts`)\n- `pool: \"forks\"`, `maxWorkers: 1` (limits test files to one worker)\n- Does NOT extend `vitest.shared.ts` — own full vitest config\n- Timeouts: 30s test, 30s hook\n- `globals: true`\n- Factory pattern: `miniflareTest(opts, handler?)` creates instance in `beforeAll`, disposes in `afterAll`\n- `useDispose(mf)` / `disposeWithRetry()` — exponential backoff for Windows EPERM file locking\n- `useServer()` — temp HTTP server with auto-cleanup\n- `TestLog` — captures log entries by level\n\n## Generated Files\n\n- `src/runtime/config/generated/workerd.ts` — generated Cap'n Proto types, do not edit directly\n- `src/workers/local-explorer/openapi.local.json` — generated from `scripts/openapi-filter-config.ts`, modify the config not the output\n\n## Version Pinning\n\n- Miniflare minor version must match workerd minor version\n- `tools/deployments/changeset-version.ts` enforces this: if changeset bumps miniflare minor beyond workerd's, it converts to patch\n\n<!-- File: packages/vite-plugin-cloudflare/AGENTS.md (Tokens: ~1792 | Category: anthropic-skill) -->\n# AGENTS.md — vite-plugin-cloudflare\n\n## OVERVIEW\n\nVite plugin for Cloudflare Workers development. Exports `cloudflare()` plugin factory from `src/index.ts`. ESM-only output.\n\n## STRUCTURE\n\n- `src/index.ts` — Plugin factory\n- `src/cf-vite.ts` — `cf-vite` delegate binary entry (see below)\n- `bin/cf-vite` — shebang shim that dynamic-imports `dist/cf-vite.mjs`\n- `src/workers/` — 4 internal worker entries: `asset-worker`, `router-worker`, `runner-worker`, `vite-proxy-worker`\n- `playground/` — ~47 playground apps, each a workspace member (nested workspace under this package)\n- `e2e/` — E2E tests with Playwright\n- `__tests__/` — Unit tests use `.spec.ts` naming\n\n## BUILD\n\n- Only package using `tsdown` as build tool\n- Outputs ESM (`.mjs`) to `dist/index.mjs`\n- `src/cf-vite.ts` is a second top-level tsdown entry, bundled to `dist/cf-vite.mjs` (no dts)\n- Also bundles 4 internal worker scripts from `src/workers/*/index.ts` as separate neutral-platform outputs to `dist/workers/`\n- Release builds set `SOURCEMAPS=false` to omit the plugin's JavaScript and declaration maps. Normal builds retain maps for debugging; the setting does not change source maps for applications built with the plugin.\n\n## cf-vite DELEGATE BINARY (experimental / internal)\n\n`bin/cf-vite` is an experimental, internal delegate binary spawned by\nCloudflare's \"cf-dev\" parent process — NOT part of the plugin's public\nAPI and not meant for direct end-user invocation. It is the sibling of\n`wrangler`'s `cf-wrangler` binary, and the two MUST keep a shared spawn\ncontract so the parent can drive either impl interchangeably.\n\n- **Verb dispatch.** `cf-vite <verb> [flags]`. `dev` and `build` are the\n  verbs today; future verbs (`deploy`) follow the same shape.\n  Unknown/missing verbs exit `2` (this doubles as the parent's\n  version-detection signal — no JSON handshake).\n- **Shared flag vocabulary (`dev`).** For `dev`, only `--mode`, `--port`,\n  `--host`, `--local` are accepted, mirroring `cf-wrangler` exactly.\n  Parsed with `node:util.parseArgs` strict mode → unknown flags exit `2`.\n  Do NOT add flags here unless `cf-wrangler` grows them too. (There is no\n  `--config` flag: the wrangler config is discovered by `cloudflare()`\n  itself.)\n- **`build`** `cf-vite build` runs Vite's full multi-environment\n  app build via `createBuilder().buildApp()` (NOT the legacy\n  single-environment `build()` helper, which would skip the plugin's\n  worker/build-output orchestration — mirrors Vite's own `vite build`\n  CLI). It accepts only `--mode` (`--port`/`--host`/`--local` don't apply to\n  a build and exit `2`). Preview build context is supplied through\n  `CLOUDFLARE_PREVIEW_BUILD`, which also works when a framework runs Vite as\n  part of its own build command.\n- **Build Output Specification is the core build pipeline.** Every build emits\n  Build Output; there is no feature flag or legacy output-config path. Preview\n  reads Workers and Containers exclusively from that output. The v2 plugin\n  always installs its build-output plugin, so `cf-vite` does not need the\n  internal force-build-output flag used by v1.\n- **Caller identity.** `main()` sets `CLOUDFLARE_VITE_CLI_DISPLAY_NAME=cf`\n  before Vite loads the user's config. `resolvePluginConfig` reads this through\n  `getCliDisplayName()` so shared services can use `cf` in actionable messages;\n  direct Vite plugin use defaults to `Wrangler`. This is an internal bridge,\n  not a `.env`-file knob.\n- **`dev`** `cf-vite dev` boots Vite via `createServer()`\n  against the user's own `vite.config.ts` (which must include\n  `cloudflare()`). Plugin-owned flags are bridged via env vars the plugin\n  already reads (`--local` → `CLOUDFLARE_VITE_FORCE_LOCAL`); Vite-owned\n  flags go through inline config (`--port`/`--host` → `server.*`,\n  `--mode` → `mode`).\n- **`--local`** forces remote bindings off. There is no plugin env knob\n  for `remoteBindings` other than `CLOUDFLARE_VITE_FORCE_LOCAL`, which\n  `resolvePluginConfig` in `plugin-config.ts` honours by overriding the\n  `remoteBindings` config option. Keep that override in sync if the flag\n  semantics change.\n- **Hotkeys differ by design.** `cf-vite` uses Vite's own\n  `bindCLIShortcuts` (`h`/`r`/`q`/…), not wrangler's hotkey set. The\n  parent process should not assume identical hotkey UX across delegates.\n- **Exit codes.** `0` graceful, `2` unknown verb / argv parse error,\n  `130` SIGINT, `143` SIGTERM.\n\n## CONVENTIONS\n\n- Playground directory `worker-♫/` has unicode in name (intentional)\n\n## TESTING\n\n- Unit tests: `.spec.ts` in `__tests__/`\n- E2E tests: `.test.ts` in `e2e/`, own vitest config\n- Playground tests: Playwright-based, tested across Vite 7/8 in CI\n- Playground request helpers (`playground/__test-utils__/responses.ts`):\n  - `getTextResponse()` / `getJsonResponse()` issue a request with browser\n    navigation headers (`Sec-Fetch-Mode: navigate` et al), which the asset and\n    router workers branch on. Default to these.\n  - They use undici's low-level `request()` rather than `fetch()`\n    **deliberately**. The Fetch spec requires implementations to set\n    `Sec-Fetch-Mode` from the request's `mode` (\"append the Fetch metadata\n    headers\"), so `fetch()` overwrites whatever the caller passed with `cors`\n    before the request leaves the process (`appendFetchMetadata` in undici).\n    `Sec-Fetch-Dest`/`-Site`/`-User` are unimplemented there, so they survive —\n    which is why only `Sec-Fetch-Mode` breaks and it is easy to miss. That one\n    decides whether the asset worker applies `not_found_handling`.\n  - This is permanent, not a bug to wait out: no Fetch-based API can send\n    `Sec-Fetch-Mode: navigate`, and `fetch(url, { mode: \"navigate\" })` is\n    rejected by the `Request` constructor. Do not \"simplify\" these back to\n    `fetch()`; `spa-with-api`'s \"via `getTextResponse()`\" test exists to catch\n    exactly that regression (it is the only playground whose compat date enables\n    `SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING`).\n  - `getResponse()` drives a real `page.goto()` and returns a Playwright\n    `Response`. Only use it when the assertion needs the browser. Anything\n    routed through Playwright can outlive a timed-out test and surface as an\n    unhandled rejection, which fails the whole run rather than one test.\n  - `WAIT_FOR_OPTIONS` (`playground/__test-utils__/index.ts`) must stay\n    comfortably below the test timeout, otherwise `vi.waitFor()` never gets to\n    report the assertion that was actually failing.\n- `playground/vitest.config.e2e.ts` inherits the repo-wide timeouts and\n  `retry: 1` from the root `vitest.shared.ts`. It spreads `configShared.test`\n  rather than using `mergeConfig()`, which concatenates arrays and would\n  silently enable the shared `default` reporter alongside `dot`.\n\n<!-- File: packages/vitest-plugin/AGENTS.md (Tokens: ~855 | Category: anthropic-skill) -->\n# vitest-plugin — Agent Guide\n\n> Custom Vitest pool for running Worker tests inside the actual workerd runtime.\n> Do NOT repeat root AGENTS.md content (pnpm, changesets, code style, etc.).\n\n## THREE-CONTEXT ARCHITECTURE\n\n### 1. Pool (`src/pool/index.ts`)\n\n- Runs in Node.js Vitest process\n- Main export (`exports[\".\"]`), built as ESM (`.mjs`)\n- Orchestrates test execution\n\n### 2. Config (`src/pool/config.ts`)\n\n- Runs in Node.js, part of the pool bundle (no separate package export)\n- Validates pool options (`WorkersPoolOptionsSchema`) and resolves the project's\n  Worker configuration into Miniflare options\n- `src/pool/plugin.ts` provides the `cloudflareTest()` Vite plugin, which injects\n  `cloudflare:test` resolution and sets resolve conditions (`workerd`, `worker`, `browser`)\n\n### 3. Worker (`src/worker/index.ts`)\n\n- Runs inside workerd runtime\n- NOT exported via package.json — internal entry\n- Contains HACK: monkeypatches VitestExecutor to access singleton\n- Has direct cross-package source import into `miniflare/src/workers/core/devalue`\n\n## WORKER CONFIGURATION SOURCES\n\n`parseCustomPoolOptions()` in `src/pool/config.ts` resolves at most one configuration\nfile into a normalised `Config`, then shares every downstream step (remote proxy\nsession, `unstable_getMiniflareWorkerOptions()`, `main`, defines, module rules, tails):\n\n- `wrangler: { configPath, environment }` — a Wrangler configuration file, via\n  `wrangler.unstable_readConfig()`\n- `experimental: { newConfig }` — a `cloudflare.config.ts`, via `src/pool/new-config.ts`\n  (`@cloudflare/config`'s `loadAndParseConfig()` → `convertToWranglerConfig()` →\n  `normalizeAndValidateConfig()`). Mirrors `@cloudflare/vite-plugin`'s\n  `experimental.newConfig`. `ctx.mode` comes from `project.vite.config.mode`.\n\nThe two are mutually exclusive. Whichever is used, the resolved path, config format and\nWorker name are recorded on `options.resolvedConfig` for the pool to consume — never\nre-read the config file from disk.\n\n## BUILD\n\n`tsdown.config.ts` defines 2 separate builds (all ESM):\n\n1. pool — `src/pool/index.ts` → `dist/pool` (emits type declarations)\n2. worker + libs — `src/worker/index.ts` plus `src/worker/lib` and `src/worker/node` → `dist/worker`\n\nTypes entry `types/cloudflare-test.d.ts` is hand-written (NOT generated from source).\n\n## THE `cloudflare:test` MODULE\n\nTests inside workerd import from `cloudflare:test`:\n\n```ts\nimport { env, fetchMock, SELF } from \"cloudflare:test\";\n```\n\nResolved by custom Vite plugin (`@cloudflare/vitest-plugin:config`) that re-exports from `cloudflare:test-internal` (runtime-provided).\n\n## CONVENTIONS\n\n- `expect` must come from test context: `it(\"name\", ({ expect }) => {})` — never `import { expect } from \"vitest\"`\n- Tests use `.test.ts` naming\n- Excludes `*.worker.test.ts` from vitest config\n\n## TESTING\n\n- Does NOT extend `vitest.shared.ts`\n- Hook timeout: 60s, retry: 2\n- Global setup starts mock npm registry, installs local package to temp dir\n- Test helper: custom `test` fixture with `tmpPath`, `seed()`, `vitestRun()`, `vitestDev()`\n- Fixtures in `fixtures/vitest-plugin-examples/` (20+ sub-fixtures testing KV, R2, D1, DO, Queues, `cloudflare.config.ts`, etc.)\n- Skipped on Windows CI due to flakiness\n\n<!-- File: packages/workers-auth/AGENTS.md (Tokens: ~3917 | Category: anthropic-skill) -->\n# AGENTS.md — workers-auth\n\nOAuth-2.0-with-PKCE flow against Cloudflare's `dash.cloudflare.com` (or staging /\ncustom-overridden) endpoints. Used by wrangler and (in future) other Cloudflare\nCLIs. Internal-only — published as `prerelease: true`.\n\n## STRUCTURE\n\n- `src/pkce.ts` — PKCE code-verifier / code-challenge generation (RFC 7636)\n- `src/errors.ts` — `ErrorOAuth2` class hierarchy + `toErrorClass` mapper\n- `src/generate-auth-url.ts` — authorize URL builder\n- `src/generate-random-state.ts` — CSRF state generator\n- `src/env-vars.ts` — `WRANGLER_*` and `CLOUDFLARE_AUTH_*` env-var getters\n- `src/account-id.ts` — `validateAccountId(id, source)`, applied to every user-supplied account ID (`CLOUDFLARE_ACCOUNT_ID`, the consumer's `account_id` config field) before it reaches an API URL path\n- `src/access.ts` — Cloudflare Access detection + service-token / `cloudflared` headers\n- `src/config-file/auth.ts` — the `AuthConfigStorage` / `UserAuthConfig` storage contract (interfaces only). The default plaintext credential implementation lives alongside the credential-store layer at `src/credential-store/file-store.ts` (see \"Credential storage\" below). The core `src/core/auth-config-file.ts` (`createAuthConfigFileHelpers({getConfigPath, format})`) and `src/core/file-storage.ts` (`createFileStorage(format, getPath)`) build the per-profile path helpers and non-credential file stores; each CLI descriptor (`src/wrangler/auth-config-file.ts`, `src/cf/auth-config-file.ts`) binds them to its config dir + `FileFormat` and re-exports `createTomlFileStorage` / `createJsonFileStorage`, `getAuthConfigFilePath`, etc. from its entrypoint. See \"CORE LAYER\" below.\n- `src/config-file/temporary.ts` — `TemporaryAccountStorage` / `TemporaryPreviewAccount` storage contract for the temporary-preview-account flow\n- `src/config-file/index.ts` — generic `ConfigStorage<T>` interface shared by the auth and temporary-account contracts\n- `src/state.ts` — `readStoredAuthState()` + `StoredAuthState` shape\n- `src/token-exchange.ts` — auth-code → token + refresh-token rotation + `fetchAuthToken`\n- `src/callback-server.ts` — local HTTP server for the OAuth callback (listens on the host/port from the consumer's `redirectUri`)\n- `src/device-flow.ts` — `getOauthTokenViaDeviceFlow(options, ctx)`: the OAuth 2.0 Device Authorization Grant (RFC 8628) used by `login({device: true})` when the browser cannot reach the local callback URL. No callback server; prints the verification URL + user code and polls `/oauth2/token`. Every user-facing string is parameterised by `ctx.cliDisplayName` / `ctx.deviceLoginCommand` so the module carries no per-CLI branding. Both endpoints' bodies are narrowed before use (`asDeviceAuthorizationResponse`, `pollDeviceToken`'s `DevicePollResult`) rather than cast — an intermediary's envelope or a 2xx without a grant must produce a reportable `unexpected`/unusable-response error, never `undefined` arithmetic. `slow_down` / 5xx / 429 / unparseable bodies keep the loop alive; the last such failure is reported in place of the generic timeout if the deadline passes\n- `src/generate-device-auth-url.ts` — `generateVerificationUrl` (fallback `verification_uri_complete` builder for servers that omit it, RFC 8628 §3.3.1) + `assertTrustedVerificationUrl`, which rejects any server-supplied verification URL that is not `https:` on exactly the resolved auth domain (with no embedded credentials) before it is printed or handed to `openInBrowser` — the device flow is the only place this package opens a URL it did not build itself (RFC 8628 §5.4, remote phishing)\n- `src/flow.ts` — `createOAuthFlow(ctx)` factory wiring everything together\n- `src/context.ts` — `OAuthFlowContext` interface (DI surface)\n- `src/credential-store/` — opt-in OS-keyring-backed credential persistence (see below)\n- `src/test-helpers/` — MSW handlers for consumers' tests (`@cloudflare/workers-auth/test-helpers`)\n\n### Credential storage (`src/credential-store/`)\n\nPluggable credential persistence layer that consumers can wire into the\nOAuth flow via `ctx.storageFactory`. Default backend is the plaintext\nTOML file (`FileCredentialStore`); an opt-in `EncryptedFileCredentialStore`\nwrites AES-256-GCM-encrypted credentials to a sibling `.enc` file using a\nkey held in the OS keyring. Every store is profile-aware: the file path,\nthe encrypted `.enc` path, and the keyring account name are all derived from\n`resolveAuthProfileBaseName(profile)` (default profile → environment-based\nname; named profile → the profile name), so each auth profile gets its own\nfiles and its own encryption key.\n\n- `interface.ts` — `CredentialStore` interface (extends `AuthConfigStorage` with `kind` and `describe()`)\n- `file-store.ts` — `FileCredentialStore` (plaintext TOML, default)\n- `encrypted-file-store.ts` — `EncryptedFileCredentialStore` + plaintext-TOML migration\n- `crypto.ts` — AES-256-GCM `encryptString` / `decryptString` helpers\n- `resolver.ts` — `createCredentialStorageContext({...})` factory; returns `{ storageFactory, getActiveStore }` (both take an optional `profile`) for the consumer to plug into `createOAuthFlow` (as `ctx.storageFactory`) and `whoami`-style reporting respectively\n- `state.ts` — module-level per-session resolver flags (one-time warnings, the Windows install-failed latch)\n- `key-providers/` — per-platform OS-keyring backends that store only the 32-byte encryption key (never the credential blob itself, so the macOS Keychain 2.5 KB item limit is never a concern):\n  - `interface.ts` — `KeyProvider` interface\n  - `mac-security.ts` — `/usr/bin/security` shell-out\n  - `linux-secret-tool.ts` — `secret-tool` shell-out (probes `libsecret-tools`)\n  - `napi-keyring.ts` — `@napi-rs/keyring` wincred binding on Windows\n  - `lazy-installer.ts` — Windows-only `npm install @napi-rs/keyring` on first opt-in\n  - `factory.ts` — `resolveKeyProvider(serviceName)` picks the right per-platform implementation\n  - `shared.ts` — account-name derivation + keyring JSON envelope encoding\n\n## DI SURFACE\n\n`createOAuthFlow(ctx)` accepts a context object:\n\n- `logger` — drop-in replacement for wrangler's logger singleton\n- `isNonInteractiveOrCI()` — whether to suppress interactive prompts\n- `openInBrowser(url)` — opens the browser to the OAuth authorize URL\n- `hasEnvCredentials()` — short-circuits refresh logic when env-based auth is set\n- `clientId` (required) — the consumer's registered OAuth app ID; `string` or\n  `() => string` for lazy (e.g. env-driven prod/staging) resolution\n- `consent` (required) — the consumer's branded granted/denied consent pages\n- `cliDisplayName` (required) — the consumer's branded name (`\"Wrangler\"`, `\"cf\"`),\n  interpolated into the device flow's \"To authorize \\<name\\>…\" copy\n- `deviceLoginCommand` (required) — the command that restarts the device flow\n  (`\"wrangler login --device\"`), quoted when a device code is denied, expires,\n  or the flow times out\n- `redirectUri` (required) — the registered redirect URI / local callback URL.\n  The callback server's listen host/port and route path are all derived from it\n  (per-call bind overrides via `LoginProps.callbackHost`/`callbackPort`)\n- `storageFactory` (required) — maps an auth profile to the consumer's\n  `AuthConfigStorage` token-persistence backend. The flow calls it with the\n  active profile on every credential access. For keyring opt-in, pass the\n  `storageFactory` from `createCredentialStorageContext(...)` rather than a raw\n  file store, so both the active profile and the encrypted-file / plaintext\n  choice are re-resolved on every credential operation.\n- `purgeOnLoginOrLogout?()` — invalidate consumer-side caches after login/logout\n- `generateAuthUrl?` / `generateRandomState?` — test overrides for deterministic\n  snapshot tests (defaults pull from `./generate-auth-url` / `./generate-random-state`)\n\n`clientId`, `consent`, `cliDisplayName`, `deviceLoginCommand`, `redirectUri`, and\n`storageFactory` are consumer-specific, so they are required rather than\ndefaulted here. Wrangler's values live in the in-package wrangler layer\n(`src/wrangler/`, see below) rather than in the `wrangler` package itself.\n\nThe wrangler layer (`src/wrangler/index.ts`, `createWranglerAuth`) wires the\ncredential-storage layer once via `createCredentialStorageContext(...)` and\nexposes the resulting `getActiveStore` (called with the active profile) as\n`getCredentialStore()` for `whoami`-style code that wants to surface the active\nstorage location.\n\n## CORE LAYER (`src/core/`) + PER-CLI DESCRIPTORS (`src/wrangler/`, `src/cf/`)\n\nThe whole CLI-facing auth layer (the machinery that used to live in\n`packages/wrangler/src/user/`) is **CLI-agnostic** and shared by every\nCloudflare CLI built on this package. It lives in `src/core/`:\n\n- `factory.ts` — `createCloudflareAuth(descriptor, ctx)`: OAuth flow wiring,\n  credential storage, config cache (`@cloudflare/workers-utils`'\n  `createConfigCache`), account selection (`fetchInternalBase` with the token\n  the flow already holds), login / logout / refresh, and `requireAuth`. Imports\n  only `@cloudflare/workers-utils`.\n- `types.ts` — `AuthContext` (the injected primitives: `logger`, optional\n  `temporaryAccountLogger` for temporary-account notices, `userAgent`, interactive\n  `prompt` / `select`, `isNoDefaultValueProvidedError`) and\n  `CliDescriptor` (everything that varies per CLI: `cliName` (the executable),\n  `displayName` (branded name used in prose), auth command names\n  (`login` / `logout` / `whoami` / `createProfile` / `deviceLogin`),\n  `keyringServiceName`,\n  `clientId`, `consent`, `redirectUri`, `useDeviceFlowByDefault`,\n  `getConfigPath`, `fileFormat`,\n  `accountCachePrefix`, `cacheNamespace`, `getConfigFileLabel`,\n  `getDefaultScopeKeys`, …).\n- `file-storage.ts` (`createFileStorage(format, getPath)`), `auth-config-file.ts`\n  (`createAuthConfigFileHelpers({getConfigPath, format})`), `preferences.ts`\n  (`createPreferences(getConfigPath)`), `profile-store.ts`\n  (`createCloudflareProfileStore`), `keyring-preference.ts`\n  (`createKeyringPreference`), `scopes.ts` (shared Cloudflare scope catalog),\n  `file-format.ts`, `temporary-terms.ts`.\n\n**File format** is the `FileFormat` axis (`src/core/file-format.ts`): a simple\n`\"toml\" | \"json\"` union (the value doubles as the file extension) plus\n`parseFile` / `stringifyFile` helpers. It's threaded through `createFileStorage`\nand the credential store (`FileCredentialStore` / `EncryptedFileCredentialStore`\n/ `resolver.ts` all take an optional `format`, defaulting to `\"toml\"` so wrangler\nis unchanged; the encrypted `.enc` sibling is format-independent). Wrangler uses\n`\"toml\"`; cf uses `\"json\"`.\n\nEach CLI is a thin **descriptor + entrypoint**:\n\n- `src/wrangler/` → `@cloudflare/workers-auth/wrangler`: `WRANGLER_CLI`\n  (TOML, wrangler's global config dir, wrangler's OAuth app / `\"wrangler\"`\n  keyring service) + `createWranglerAuth(ctx) = createCloudflareAuth(WRANGLER_CLI, ctx)`.\n  Re-exports everything wrangler's `src/user/*` imports (`createTomlFileStorage`,\n  `readUserPreferences`, `createWranglerProfileStore`, `setKeyringPreference`,\n  scopes, `getClientIdFromEnv`, `OAUTH_CALLBACK_URL`, …) — no re-export shim\n  files remain in `wrangler/src/user/`.\n- `src/cf/` → `@cloudflare/workers-auth/cf`: `CF_CLI` (JSON files under\n  `~/.config/cloudflare`, the `\"cloudflare\"` keyring service, `CLOUDFLARE_CLIENT_ID`)\n  - `createCfAuth(ctx)`. OAuth-app values (client ID `cbca97e7-…`, callback port\n    8877, `cf-oauth-consent-*` pages, scoped-token-only auth) mirror the `cf`\n    CLI's registration, and device authorization is its default interactive\n    login flow. cf carries its own scope policy (`src/cf/scopes.ts`): the raw\n    client registration is kept separate from the known-grantable catalog used\n    for validation and types, and sensitive requestable scopes can be excluded\n    from login defaults. Requestable scopes must both appear in the client\n    registration and resolve in the consent service's Bach catalog; registered\n    exceptions stay explicit negative regressions. Retain separately verified,\n    grandfathered legacy scopes and registration order.\n    This is distinct from wrangler's smaller `src/core/scopes.ts` key →\n    description map, so cf does not re-export `DefaultScopes`.\n\n## CONVENTIONS\n\n- License: dual MIT/Apache-2.0. Files derived from\n  [BitySA/oauth2-auth-code-pkce](https://github.com/BitySA/oauth2-auth-code-pkce)\n  carry the Apache-2.0 header.\n- No `console.*` — use the injected `ctx.logger`. Temporary-account notices\n  (terms notice, proof-of-work, \"Temporary account ready\") go through the\n  `temporaryAccountLogger` instead, so a CLI can keep them off stdout.\n- No global `fetch` — use undici's `fetch`.\n- `UserError` instances must carry stable `telemetryMessage` labels\n  (`<area> <sub-area> <failure>`, e.g. `user oauth invalid scope`).\n  These labels are part of the telemetry contract — preserve them verbatim.\n- No direct Cloudflare REST API calls. This package talks to OAuth endpoints\n  (`/oauth2/auth`, `/oauth2/token`, `/oauth2/revoke`) only.\n- OAuth callback server listens on the host/port derived from the consumer's\n  required `ctx.redirectUri`; override the bind address per-call via\n  `LoginProps.callbackHost` / `callbackPort`.\n\n## BUILD\n\n- tsup: two entry points — `src/index.ts` and `src/test-helpers/index.ts`\n- ESM-only output to `dist/`\n- `@cloudflare/*`, `undici`, `msw`, and `vitest` are kept external\n\n## CREDENTIAL STORAGE NOTES\n\n- The encrypted file uses `AES-256-GCM` via `node:crypto` (no third-party\n  crypto deps). The 12-byte IV is generated fresh per write; the 16-byte\n  GCM auth tag is verified on every read.\n- The keyring entry holds only a 32-byte AES key wrapped in a small JSON\n  envelope (`{v, key, created}`). It's well under the macOS Keychain ~2.5 KB\n  per-item limit no matter how the credential schema grows.\n- `@napi-rs/keyring` (the Windows backend's native binding) is installed\n  lazily on first opt-in via `npm install` into `<configPath>/native/keyring/`,\n  where `configPath` is the consumer-provided global config directory (see\n  `getConfigPath` below) — so each CLI's binding lives under its own config dir.\n  Pinned to `PINNED_KEYRING_VERSION` so CI users running\n  `npm install -g @napi-rs/keyring` by hand get the same version as the\n  lazy-install path.\n- The credential files (`.toml` / `.enc`) and the keyring install dir are all\n  rooted at the consumer's config directory. `@cloudflare/workers-auth` never\n  resolves that path itself (wrangler and a future `cf` CLI use different global\n  config paths); instead the consumer passes `getConfigPath: () => string` into\n  `createCredentialStorageContext`, and the path helpers\n  (`getAuthConfigFilePath` / `getEncryptedAuthConfigFilePath` /\n  `getKeyringInstallDir`) and store constructors all take it explicitly.\n- The consumer's `createCredentialStorageContext` call captures `serviceName`,\n  `getConfigPath`, `isKeyringEnabled`, `logger`, `isNonInteractiveOrCI`, and\n  `loginCommand` in a closure. The returned `storageFactory(profile)` re-resolves\n  the active store on every call so the active profile, `--use-keyring` /\n  `--no-use-keyring`, and the `CLOUDFLARE_AUTH_USE_KEYRING` env var all take\n  effect without rebuilding the OAuth flow. Per-session memoization flags\n  (`hasWarnedAboutKeyringFallback`, `installFailedThisSession`, ...) still\n  live at module scope in `state.ts`; tests use\n  `resetCredentialStorageState` to clear them between cases and\n  `setKeyProviderFactoryForTesting` to swap in stubs.\n\n<!-- File: packages/workers-utils/AGENTS.md (Tokens: ~807 | Category: anthropic-skill) -->\n# AGENTS.md — workers-utils\n\n## OVERVIEW\n\nShared utility package used across wrangler, miniflare, and others. Two main areas: config validation and test helpers.\n\n## STRUCTURE\n\n- `src/config/` — Configuration types, validation, normalization\n  - `validation.ts` — The config normalizer (large file). Central to all wrangler config processing.\n  - `environment.ts` — Environment/config field definitions (many deprecated fields)\n  - `config.ts` — Config types\n- `src/test-helpers/` — Shared test utilities used across packages\n- `src/types.ts` — Shared type definitions\n\n## KEY EXPORTS\n\n### Config\n\n- Validation pipeline normalizes wrangler.json/toml into typed config objects\n- Used by wrangler for all config loading\n\n### D1 migrations\n\n- `getD1MigrationFiles({ projectPath, migrationsDir, migrationsPattern })` — shared glob-based discovery used by Wrangler and the Vitest plugin. Honour `migrations_pattern` rather than recursively collecting every `.sql` file.\n\n### Shared runtime utilities\n\n- `createConfigCache(logger)` — file-backed JSON config cache (node_modules/.cache or `.wrangler/cache`). Generic mechanism; the consumer passes its logger (this package has no logger singleton). Both `wrangler` (`src/config-cache.ts`) and `@cloudflare/workers-auth` build their own instances.\n- `openInBrowser(url, logger)` — opens the `open` package with a graceful copy-paste fallback when no browser opener is available. Logger is a parameter, not imported.\n- `isInteractive()` / `isNonInteractiveOrCI()` / `isCI()` — TTY / CI detection (the TTY check is inlined here to avoid a cycle back through `@cloudflare/cli-shared-helpers`). `isCI()` keys off CI specifically (ignoring TTY), for behaviour like redacting account names in public CI logs. These read `ci-info`, which is bundled into consumers' distributables. Because a bundled `ci-info` is an unmockable separate instance (and reads the real environment), consumers that need to fake CI in their tests mock **this package's** exports rather than `ci-info` — e.g. wrangler's `vitest.setup.ts` mocks `@cloudflare/workers-utils` so `isInteractive`/`isNonInteractiveOrCI`/`isCI` delegate to the mockable `ci-info`, which reaches both wrangler-source and bundled `@cloudflare/workers-auth` consumers (since `@cloudflare/*` is external in workers-auth's bundle).\n\n### Test Helpers\n\n- `runInTempDir()` — Creates temp dir, chdir's into it, stubs HOME/XDG_CONFIG_HOME, cleans up\n- `seed(files)` — Writes `Record<string, string>` of path->content into temp dir\n- `writeWranglerConfig()` / `readWranglerConfig()` — Mock wrangler config files (TOML, JSON, JSONC)\n- `mockConsoleMethods()` — Spies on console, returns normalized output with `.debug`, `.out`, `.info`, `.err`, `.warn`\n- `normalizeString()` — Multi-stage pipeline: strips timings, thin spaces, temp dirs, normalizes slashes/cwd/dates/tables/error markers/byte values, and scrubs the OAuth authorize URL's random `state` / `code_challenge` query params to `<OAUTH_STATE>` / `<OAUTH_CODE_CHALLENGE>` (so login-URL snapshots stay deterministic without mocking the URL builder)\n\n## NOTES\n\n- `validation.ts` is the largest single file in the monorepo after generated code — changes here affect all config processing\n- Many deprecated fields in `environment.ts` — check `@deprecated` annotations before modifying\n- Test helpers imported as `@cloudflare/workers-utils/test-helpers` across packages\n\n<!-- File: packages/wrangler/AGENTS.md (Tokens: ~1490 | Category: anthropic-skill) -->\n# Wrangler — Agent Guide\n\nWrangler-specific context only. See root `AGENTS.md` for monorepo conventions.\n\n## Overview\n\nMain CLI for Cloudflare Workers. ~2k-line yargs command tree in `src/index.ts`. Entry point is `src/cli.ts` (NOT `src/index.ts`).\n\n## Structure\n\n- `src/` — CLI source\n- `src/__tests__/` — Unit tests, helpers in `src/__tests__/helpers/`\n- `e2e/` — E2E tests, requires Cloudflare credentials\n- `bin/wrangler.js` — Shim that spawns Node to run `wrangler-dist/cli.js`, forwarding stdio and IPC\n- `bin/cf-wrangler.js` — `cf-wrangler` delegate entrypoint. Owns verb dispatch, argv parsing (`parseCfWranglerArgs`), and the `StartDevOptions` literal; hands off to `runCfWranglerDev` from `wrangler-dist/cli.js` in-process (no re-spawn — the parent tool owns the Node runtime)\n- `src/containers/ssh.ts` — Thin command adapter; SSH options, authorization request, and transport live in `@cloudflare/containers-shared/src/ssh.ts`, shared with cf.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint (see below)\n- `src/containers/images.ts` — Command adapter; registry image operations live in `containers-shared/src/registry-images.ts`, shared with cf.\n- `templates/` — Worker templates\n\n## Entry Points\n\n- `src/cli.ts` — Build entry AND library API surface (dual-purpose). Calls `main()` when run directly; re-exports `./api` when imported as library. Also re-exports `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, `ArgParseError`, `runCfWranglerDev`, and `runCfWranglerBuild` for the `cf-wrangler` bin to call in-process.\n- `src/index.ts` — Yargs CLI tree builder (large file). Exports `main()`. NOT the package entry point despite the name.\n- `src/api/index.ts` — Public programmatic API barrel.\n- `src/cf-wrangler/` — The `cf-wrangler` delegate entrypoint, an experimental escape hatch for projects that can't use `@cloudflare/vite-plugin`. It exposes `dev` + four flags (`--mode`, `--port`, `--host`, `--local`) and `build` + `--mode`; the wrangler config file is found via wrangler's standard discovery (no `--config` flag). Preview build context is supplied through `CLOUDFLARE_PREVIEW_BUILD`, matching framework-owned build commands. It is NOT a separate package and does NOT use the `unstable_dev` test harness. It shares its spawn contract (verb dispatch, flag vocabulary, exit-2 feature detection) with the sibling `cf-vite` delegate in `@cloudflare/vite-plugin`. `bin/cf-wrangler.js` owns verb dispatch, argv parsing, and the `StartDevOptions` literal; `src/cf-wrangler/dev.ts` (exported as `runCfWranglerDev`) wraps `startDev` in the experimental-flags context and waits for teardown. `src/cf-wrangler/build.ts` (exported as `runCfWranglerBuild`) runs the Build Output Specification path used by `wrangler build --experimental-new-config --experimental-cf-build-output`, producing `.cloudflare/output/v0`. `src/cf-wrangler/args.ts` (exported as `parseCfWranglerArgs`, `parseCfWranglerBuildArgs`, and `ArgParseError`) does the strict argv parse. The \"unknown subcommand\" error doubles as a feature-detection signal for the parent CLI.\n\n## Conventions (Wrangler-Specific)\n\n- No `console.*` — use `logger` singleton\n- No `__dirname` / `__filename` — use `getBasePath()`\n- No global `fetch` — use undici's fetch\n- Route Cloudflare v4 API calls through the existing `cfetch` helpers such as\n  `fetchResult`, `fetchListResult`, and `fetchPagedListResult` when possible;\n  do not use global or undici `fetch` directly. Prefer these helpers over\n  adding or passing the `cloudflare` package solely for a simple request, and\n  use the Cloudflare TypeScript SDK when its generated API surface or behavior\n  is materially useful.\n- `telemetryMessage` values for `UserError`-compatible errors must be static, safe labels. Do not use `telemetryMessage: true` unless 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: true` is usually less useful because user-facing copy is harder to group and parse than a stable telemetry label.\n- Format `telemetryMessage` values as lower-case phrases: `<service or area> <command or sub-area> <failure>`, for example `kv namespace binding not found in config`, `r2 object put file not found`, or `pages deploy project name missing`.\n- 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.\n\n## Build\n\n- tsup: single entry `src/cli.ts` → `wrangler-dist/cli.js`\n- `package.json` `main` points at `wrangler-dist/cli.js`\n- Custom `embedWorkersPlugin()` bundles Worker templates via esbuild for tests\n\n## Testing\n\n- Pool: `\"forks\"` (not threads) — heavy global mocking\n- `runWrangler(cmd)` calls `main()` in-process (no subprocess)\n- MSW for API mocking — pre-built handlers per API domain in `src/__tests__/helpers/msw/`\n- Shared helpers: `runInTempDir()`, `mockAccountId()`, `mockApiToken()`, `mockConfirm()`, `mockPrompt()`, `mockSelect()`, `captureRequestsFrom()`\n- Unit timeout: 50s, retry: 0. Note: wrangler's `vitest.config.mts` does NOT use `mergeConfig` with `vitest.shared.ts`, so shared defaults (timeouts, retry, etc.) are not inherited — they must be set explicitly in the wrangler config.\n- E2E timeout: 90s, bail: 1, singleThread\n- `globals: true` for vitest globals\n- Output normalization via `normalizeString()` pipeline\n\n## Anti-Patterns\n\n- Test files use `.test.ts` (not `.spec.ts`)\n- Never import `expect` from vitest — use test context `({ expect }) => {}`\n  - When adding `expect` as a parameter to helper functions, check ALL call sites (e.g., across `deployments.test.ts`, `versions.test.ts`)\n\n<!-- File: packages/build-output-utils/README.md (Tokens: ~43 | Category: plugin-manifest) -->\n# `@cloudflare/build-output-utils`\n\nUtilities for reading and writing the Build Output Specification directory (`.cloudflare/output/`).\n\nThis is not yet stable enough for external use — APIs may change without notice.\n\n<!-- File: packages/chrome-devtools-patches/README.md (Tokens: ~665 | Category: plugin-manifest) -->\n# Workers Devtools\n\nThis package contains a Workers specific version of Chrome Devtools that is used by the Wrangler dev command and other applications. It is a customized fork of Chrome DevTools specifically tailored for debugging Cloudflare Workers. This package provides Worker-specific functionality through carefully maintained patches on top of Chrome DevTools.\n\n## Overview\n\nThis package is used across multiple Cloudflare products:\n\n- Workers Playground (`workers-playground`)\n- Quick Editor (`@cloudflare/quick-edit`)\n- Wrangler CLI via the `InspectorProxy`\n\n## Features\n\nOur customized DevTools implementation provides:\n\n- Source code viewing and live updates\n- Network request inspection\n- Worker-specific UI optimizations\n\n## Development\n\nWe maintain this fork by applying patches on top of Chrome DevTools. These patches need to be periodically rebased as Chrome DevTools evolves.\n\n**Key Development Tasks:**\n\n- Generating patches from our customizations\n- Rebasing patches onto new Chrome DevTools versions\n- Testing functionality across all integration points\n\n## Updating DevTools\n\nWe perform quarterly updates to stay current with upstream Chrome DevTools. The update process involves:\n\n1. Cloning the devtools-frontend repo\n2. Applying our existing patches\n3. Rebasing onto the latest Chrome DevTools\n4. Regenerating patches\n5. Thorough testing across all integration points\n\n**For detailed instructions on updating DevTools, please refer to our internal documentation on keeping devtools up-to-date.**\n\n## Testing\n\nTwo methods are available for testing updates:\n\n**Local Development:**\n\n- Build and serve DevTools locally\n- Test against local Playground instance\n- Make targeted fixes as needed\n\n**Preview Builds:**\n\nOn any pull request to the repo on GitHub, you can add the `preview:chrome-devtools-patches` label to trigger a preview build of the DevTools frontend. This is useful because it will allow you to manually test your changes in a live environment, and with one-click.\n\nOnce the preview is built, you will see a comment on the PR with a link to the live URL.\n\n## Acceptance Criteria\n\nOur DevTools implementation must maintain full functionality across:\n\n- Console operations (logging, errors, filters)\n- Source code viewing and debugging\n- Network request inspection\n- Worker-specific UI customizations\n\n## Contributing\n\nWhen making changes:\n\n- Keep patches minimal and targeted\n- Prefer CSS-based UI modifications\n- Test thoroughly across all integration points\n- Document any new patches or modifications\n\n## Deployment\n\nThis package is deployed as a Cloudflare Workers + Assets project. The static DevTools frontend is served directly from Workers Assets, configured via `wrangler.jsonc`.\n\nDeployments are managed by GitHub Actions:\n\n- deploy-previews.yml:\n  - Runs on any PR that has the `preview:chrome-devtools-patches` label.\n  - Uploads a preview version (without activating it in production) via `wrangler versions upload`.\n  - The preview URL is posted as a comment on the PR.\n- changesets.yml:\n  - Runs when a \"Version Packages\" PR, containing a changeset that touches this package, is merged to `main`.\n  - Deploys this package to production via `wrangler deploy`.\n  - Production is accessible via the custom domain [https://devtools.devprod.cloudflare.dev/].\n\n<!-- File: packages/cli/README.md (Tokens: ~36 | Category: plugin-manifest) -->\n# Cloudflare CLI\n\n> Internal utility package for workers-sdk. Not intended for external use — APIs may change without notice.\n\nAll things related to rendering the CLI for workers-sdk.\n\n<!-- File: packages/codemods/README.md (Tokens: ~794 | Category: plugin-manifest) -->\n# `@cloudflare/codemods`\n\nCodemods for upgrading Cloudflare developer projects.\n\nRun a codemod by name:\n\n```sh\nnpx @cloudflare/codemods vitest:v3-to-v4\n```\n\nAvailable codemods:\n\n- `wrangler-to-cf` - migrate a Wrangler configuration to the new `cf`\n  configuration format\n- `vitest:v3-to-v4` — migrate `@cloudflare/vitest-pool-workers` configuration from\n  Vitest v3 to v4\n- `vitest:pool-workers-to-vitest-plugin` — rename `@cloudflare/vitest-pool-workers`\n  to `@cloudflare/vitest-plugin` v1\n\nUse `--dry-run` to list changes without writing them, `--cwd <path>` to target\nanother project, or repeat `--files <glob>` to restrict the files considered.\nWhen the target is inside a Git worktree, the worktree must be clean. Use\n`--force` to bypass this safety check.\n\nTo migrate a Wrangler project with the default Vite bundler:\n\n```sh\nnpx @cloudflare/codemods wrangler-to-cf --cwd ./path/to/project\n```\n\nThe CLI detects a single root `wrangler.json`, `wrangler.jsonc`, or `wrangler.toml`. Pass `--config <path>` to select another file, or pass `--bundler wrangler` to retain Wrangler-specific tooling configuration. For this codemod, `--files` filters the selected Wrangler config and skips the migration when it does not match.\n\n## Programmatic usage\n\nCodemods can also be run from JavaScript or TypeScript:\n\n```ts\nimport { runCodemod } from \"@cloudflare/codemods\";\n\nconst { changedFiles } = await runCodemod(\"vitest:v3-to-v4\", {\n\tcwd: process.cwd(),\n\tdryRun: false,\n});\n```\n\n`runCodemod` accepts the same codemod names and aliases as the CLI. Its context also accepts optional `files` and `force` fields corresponding to the CLI flags, and setting `dryRun` lists changed files without writing them. It returns a `CodemodResult` containing `changedFiles` and rejects if the codemod cannot be run. The CLI's clean-worktree check also applies to programmatic runs.\n\n### Migrate Wrangler config to cf\n\nPass the exact Wrangler config file to `migrateWranglerToCf`:\n\n```ts\nimport { migrateWranglerToCf } from \"@cloudflare/codemods\";\n\nconst result = await migrateWranglerToCf(\"./wrangler.jsonc\", {\n\tbundler: \"vite\",\n});\n```\n\nThe options object and all of its fields are optional. The defaults are the Vite bundler, writes enabled, dirty-worktree protection enabled, and automatic dependency installation enabled. The migration installs `cf` when missing, installs `@cloudflare/vite-plugin@beta` when Vite is selected and the plugin is missing or incompatible, and upgrades Wrangler when generated Wrangler tooling requires a newer version. The Vite plugin dependency remains set to the `beta` dist tag in `package.json`; package manager installation updates the project's lockfile. Project-managed Vite plugin specifiers such as `workspace:` and `catalog:` are preserved; incompatible or unverified versions require a manual update. Set `installDependencies` to `false` to prevent dependency changes; required dependencies are then returned as blocking follow-ups. The migration always creates `cloudflare.config.ts`; selecting the Wrangler bundler also creates `wrangler.config.ts` when Wrangler-specific tooling config exists. Existing target files are never overwritten. Inspect `result.followUps` when `result.status` is `needs-intervention`.\n\n<!-- File: packages/config/README.md (Tokens: ~35 | Category: plugin-manifest) -->\n# `@cloudflare/config`\n\nDefinitions and utilities for configuring Cloudflare Workers and related products.\n\nThis is not yet stable enough for external use — APIs may change without notice.\n\n<!-- File: packages/containers-shared/README.md (Tokens: ~157 | Category: plugin-manifest) -->\n# @cloudflare/containers-shared\n\nInternal shared container functionality for Cloudflare Workers SDK.\n\n## Internal Use Only\n\nThis package is published only for internal use.\n\nDo not depend on this package directly from external projects. It is not a\npublic SDK, it does not provide a stable API surface, and any function, type,\nexport, behavior, or file path contained in this package may change or be\nremoved at any time without notice.\n\nNo semver compatibility is promised for consumers outside Cloudflare's own\nWorkers SDK packages.\n\n- Cloudchamber/Containers API client\n- Utils for constructing and running docker commands\n- SSH transport shared by Wrangler and cf (OpenSSH and stdio proxy modes)\n- Managed registry image list/delete operations shared by Wrangler and cf\n\n<!-- File: packages/create-cloudflare/e2e/README.md (Tokens: ~1524 | Category: plugin-manifest) -->\n# C3 E2E tests\n\nThis directory contains the e2e tests and helpers for C3.\n\n## Running tests locally\n\nThere are three groups of tests:\n\n- CLI - general tests against the C3 CLI tool, such as interactive prompts\n- Workers - tests of the non-framework C3 templates such as `hello-world-durable-object-with-assets-ts`.\n- Frameworks - tests of the framework C3 templates, such as `astro:workers`, `qwik:pages`, etc.\n\n- To run all the tests locally you can do run the following from the root of the monorepo:\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare\n  ```\n\n  This command will actually run the `test:e2e` turbo task in the `create-cloudflare` package, which will also ensure that any dependencies have been built correctly first.\n\n- To run just one group of tests (pass the group name to underlying command):\n\n  ```bash\n  pnpm test:e2e -F create-cloudflare -- workers\n  ```\n\n  You can choose from `cli`, `workers` or `frameworks`.\n\nThe tests that run can be controlled by combining any of the following environment variables:\n\n- `E2E_EXPERIMENTAL` - whether to run the tests in experimental mode - without this variable only non-experimental tests are run.\n- `E2E_TEST_PM` + `E2E_TEST_PM_VERSION` - which package manager to simulate in the tests - without these variables the tests simulate `pnpm`.\n- `E2E_RUN_DEPLOY_TESTS` - whether to ask C3 to deploy generated projects and run tests against the deployed version - if this is not set to `\"true\"`, generated projects are only tested locally.\n- `CLOUDFLARE_API_TOKEN` - the API token to use in tests that connect to Cloudflare - without this variable tests that require Cloudflare access are skipped.\n- `E2E_FRAMEWORK_SHARD` - optional framework case shard in the form `index/count`, with a one-based index. Invalid values fail the run. Without it, all matching cases are collected, including skipped cases.\n- `E2E_TEST_RETRIES` - optional non-negative integer override for framework whole-test retries. Framework tests retain one whole-test retry because they exercise external registries, generators, and runtime startup. Cases can override this allowance in `test-config.ts`. Set this to `0` when investigating a failure or measuring first-attempt reliability. Readiness polling within each attempt is unchanged.\n\n### Running a framework shard\n\nAll framework cases live in one file, so Vitest's file sharding cannot divide this suite. CI runs three case shards per normal package-manager entry and two shards for experimental pnpm. Each runner retains Vitest's default limit of five concurrent tests.\n\nTo reproduce a shard locally, run:\n\n```bash\nE2E_FRAMEWORK_SHARD=1/3 pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nCases are sorted by their full names and distributed round-robin after applying the framework filter and excluding quarantined or unsupported cases. New frameworks and variants are assigned automatically. Use the same package manager, package-manager version, experimental mode, filter, and shard count as CI to reproduce its selection.\n\nThe existing required framework checks wait for every framework shard. Failed, cancelled, or skipped shard jobs fail these checks; deliberately skipped test steps still succeed when framework coverage is not requested.\n\nCI publishes per-attempt logs, Vitest's `results.json`, Turbo summaries, and a retry report. The reported Vitest test duration includes waiting for a concurrency slot, hooks, and all attempts, so use the job/Turbo task duration to measure the critical path. Cached test replays are excluded from retry reports.\n\nTreat a recovered attempt as evidence of a reliability problem, even when CI passes. Keep the single retry while addressing the cause; reduce an allowance only after repeated fresh runs support doing so. A repeatable regression should fail the check, and another attempt should not be used to hide it.\n\nEach attempt shares an absolute package-manager cache across its child processes, outside the generated project. This prevents C3's Git initialization from committing cache contents while isolating concurrent installs. The fixture removes both the project and its cache after the attempt. Wrangler's test configuration uses an automatically assigned inspector port to avoid collisions between concurrent preview sessions.\n\n### Running in experimental mode\n\nC3 can be run in experimental mode, by passing `--experimental` to it as a CLI argument. By default the tests will run in non-experimental mode.\nTo run the tests in experimental mode, simply pass `E2E_EXPERIMENTAL=true` as an environment variable.\n\nFor example, to run the \"cli\" group in experimental mode:\n\n```bash\nE2E_EXPERIMENTAL=true pnpm test:e2e -F create-cloudflare -- cli\n```\n\n> This experimental environment variable can be combined with the package manager environment variables below.\n\n### Running against different package managers\n\nC3 supports running sub-commands and installs using a range of package managers. By default the tests will run agains `pnpm`.\nTo run the tests using a different package manager, simply pass `E2E_TEST_PM` and `E2E_TEST_PM_VERSION` as environment variables.\n\nFor example, to run the \"workers\" group using yarn@1.22.22.\n\n```bash\nE2E_TEST_PM=yarn E2E_TEST_PM_VERSION=1.22.22 pnpm test:e2e -F create-cloudflare -- workers\n```\n\n> These package manager environment variables can be combined with the experimental environment variable above.\n\n### Running Workers templates individually\n\nTo run the e2e tests against a specific Worker template (or group of Worker template variants), provide the `E2E_WORKER_TEMPLATE_TO_TEST` environment variable.\n\nWorker template names and their variants are delimited by colons (`:`).\nIf no colon is specified then all variants will be run for the matching template name.\n\nFor example to only run the python version of the `hello-world-durable-objects` template:\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-durable-object:python pnpm test:e2e -F create-cloudflare -- workers\n```\n\nTo run all the `hello-world-with-assets` variants (`js`, `python`, `ts`):\n\n```bash\nE2E_WORKER_TEMPLATE_TO_TEST=hello-world-with-assets pnpm test:e2e -F create-cloudflare -- workers\n```\n\n### Running Web frameworks templates individually\n\nTo run the e2e tests against a specific Web framework (or group of Worker template variants), provide the `E2E_FRAMEWORK_TEMPLATE_TO_TEST` environment variable.\n\nFramework templates and their variants (`pages` or `workers`) are delimited by colons (`:`).\nIf no colon is specified in the filter then all variants will be run for the matching template.\n\nFor example to only run the `workers` version of the `react-router` framework:\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=react-router:workers pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\nTo run all the `qwik` framework variants (`pages`, `workers`):\n\n```bash\nE2E_FRAMEWORK_TEMPLATE_TO_TEST=qwik pnpm test:e2e -F create-cloudflare -- frameworks\n```\n\n<!-- File: packages/create-cloudflare/README.md (Tokens: ~100 | Category: plugin-manifest) -->\n# create-cloudflare\n\nA CLI for creating and deploying new applications to [Cloudflare](https://developers.cloudflare.com/).\n\nFor more details on how to use the create-cloudflare CLI (C3) please visit the [official C3 documentation](https://developers.cloudflare.com/pages/get-started/c3).\n\n### Community\n\n- Join us [on Discord](https://discord.cloudflare.com)\n- File an issue [on GitHub](https://github.com/cloudflare/workers-sdk/issues/new/choose)\n\n<!-- File: packages/create-cloudflare/templates/django/py/README.md (Tokens: ~48 | Category: plugin-manifest) -->\n# Django on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n\n<!-- File: packages/create-cloudflare/templates/fastapi/py/README.md (Tokens: ~49 | Category: plugin-manifest) -->\n# FastAPI on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n\n<!-- File: packages/create-cloudflare/templates/flask/py/README.md (Tokens: ~48 | Category: plugin-manifest) -->\n# Flask on Cloudflare Workers\n\nInstall dependencies and start local development with uv:\n\n```sh\nuv sync\nuv run pywrangler dev\n```\n\nDeploy the Worker with:\n\n```sh\nuv run pywrangler deploy\n```\n\n<!-- File: packages/create-cloudflare/templates/hello-world-durable-object-with-assets/py/README.md (Tokens: ~167 | Category: plugin-manifest) -->\n## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n\n<!-- File: packages/create-cloudflare/templates/hello-world-durable-object/py/README.md (Tokens: ~167 | Category: plugin-manifest) -->\n## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n\n<!-- File: packages/create-cloudflare/templates/hello-world-with-assets/py/README.md (Tokens: ~167 | Category: plugin-manifest) -->\n## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml file with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n\n<!-- File: packages/create-cloudflare/templates/hello-world/py/README.md (Tokens: ~166 | Category: plugin-manifest) -->\n## Usage\n\nYou can run the Worker defined by your new project by executing `wrangler dev` in this\ndirectory. This will start up an HTTP server and will allow you to iterate on your\nWorker without having to restart `wrangler`.\n\n### Types and autocomplete\n\nThis project also includes a pyproject.toml with some requirements which\nset up autocomplete and type hints for this Python Workers project.\n\nTo get these installed you'll need `uv`, which you can install by following\nhttps://docs.astral.sh/uv/getting-started/installation/.\n\nOnce `uv` is installed, you can run the following:\n\n```\nuv venv\nuv sync\n```\n\nThen point your editor's Python plugin at the `.venv` directory. You should then have working\nautocomplete and type information in your editor.\n\n<!-- File: packages/create-cloudflare/templates/openapi/ts/README.md (Tokens: ~322 | Category: plugin-manifest) -->\n# Cloudflare Workers OpenAPI 3.1\n\nThis is a Cloudflare Worker with OpenAPI 3.1 using [chanfana](https://github.com/cloudflare/chanfana) and [Hono](https://github.com/honojs/hono).\n\nThis is an example project made to be used as a quick start into building OpenAPI compliant Workers that generates the\n`openapi.json` schema automatically from code and validates the incoming request to the defined parameters or request body.\n\n## Get started\n\n1. Sign up for [Cloudflare Workers](https://workers.dev). The free tier is more than enough for most use cases.\n2. Clone this project and install dependencies with `npm install`\n3. Run `wrangler login` to login to your Cloudflare account in wrangler\n4. Run `wrangler deploy` to publish the API to Cloudflare Workers\n\n## Project structure\n\n1. Your main router is defined in `src/index.ts`.\n2. Each endpoint has its own file in `src/endpoints/`.\n3. For more information read the [chanfana documentation](https://chanfana.pages.dev/) and [Hono documentation](https://hono.dev/docs).\n\n## Development\n\n1. Run `wrangler dev` to start a local instance of the API.\n2. Open `http://localhost:8787/` in your browser to see the Swagger interface where you can try the endpoints.\n3. Changes made in the `src/` folder will automatically trigger the server to reload, you only need to refresh the Swagger interface.\n\n<!-- File: packages/create-cloudflare/templates/react-router/ts/README.md (Tokens: ~312 | Category: plugin-manifest) -->\n# Welcome to React Router!\n\nA modern, production-ready template for building full-stack React applications using React Router.\n\n## Features\n\n- 🚀 Server-side rendering\n- ⚡️ Hot Module Replacement (HMR)\n- 📦 Asset bundling and optimization\n- 🔄 Data loading and mutations\n- 🔒 TypeScript by default\n- 🎉 TailwindCSS for styling\n- 📖 [React Router docs](https://reactrouter.com/)\n\n## Getting Started\n\n### Installation\n\nInstall the dependencies:\n\n```bash\nnpm install\n```\n\n### Development\n\nStart the development server with HMR:\n\n```bash\nnpm run dev\n```\n\nYour application will be available at `http://localhost:5173`.\n\n## Previewing the Production Build\n\nPreview the production build locally:\n\n```bash\nnpm run preview\n```\n\n## Building for Production\n\nCreate a production build:\n\n```bash\nnpm run build\n```\n\n## Deployment\n\nDeployment is done using the Wrangler CLI.\n\nTo build and deploy directly to production:\n\n```sh\nnpm run deploy\n```\n\nTo deploy a preview URL:\n\n```sh\nnpx wrangler versions upload\n```\n\nYou can then promote a version to production after verification or roll it out progressively.\n\n```sh\nnpx wrangler versions deploy\n```\n\n## Styling\n\nThis template comes with [Tailwind CSS](https://tailwindcss.com/) already configured for a simple default starting experience. You can use whatever CSS framework you prefer.\n\n---\n\nBuilt with ❤️ using React Router.\n\n<!-- File: packages/format-errors/README.md (Tokens: ~1161 | Category: plugin-manifest) -->\n# format-errors\n\nA Worker that will nicely format errors, optionally inflating with source context if available.\n\n<table>\n     <tr><td><img src=\"./images/service-worker.png\"></td><td><img src=\"./images/modules-worker.png\"></td></tr>\n</table>\n\n## Why is this needed?\n\nIn development, it's nice to have good error messages to help when debugging, and ideally the logic for that shouldn't be bundled into your user Worker. This Worker is ~50kb when gzipped, which doesn't add _that_ much, but there's still a benefit to keeping it separate from the user Worker. Additionally, in environments where we're unable to bundle complex Workers, this error formatting Worker allows for the display of useful errors where otherwise only a stack trace would be available.\n\n## How does it work?\n\nFundamentally, this is based on [Youch](https://github.com/poppinss/youch) and [StackTracey](https://github.com/xpl/stacktracey). Neither of these projects are designed to be run in the Workers environment (although StackTracey does have support for running in the browser), and so both have been vendored in and modified. These modifications aren't upstreamable, since they involve things like changing how Youch detects node-internal modules and changing how sources are loaded.\n\n### Youch changes:\n\n- **\"internal\" module detection:** By default, Youch recognises modules with a prefix of `node:` to be internal modules. Instead, `format-error`s recognises modules with a prefix of `.internal` as internal modules.\n- **source loading:** Youch loads sources at error-page generation time, `format-error`s loads sources at error-page viewing time.\n- **cookies:** `format-error`s doesn't handle cookies.\n\n### Stacktracey changes:\n\n- **browser detection:** `format-error`s always reports itself to be running inside a browser, but removes references to browser globals like `window`.\n- **table rendering:** To remove the `as-table` dependency, `format-error` doesn't implement Stacktracey's `asTable` method, which Youch doesn't use.\n\n## How can you get a formatted error page?\n\nThe first thing you'll need is an error. `format-errors` requires input conforming to the `Payload` interface below, and will reject invalid input at runtime:\n\n```ts\nexport interface JsonError {\n\tmessage?: string;\n\tname?: string;\n\tstack?: string;\n\tcause?: JsonError;\n}\nexport interface Payload {\n\turl?: string;\n\tmethod?: string;\n\theaders?: Record<string, string>;\n\terror?: JsonError;\n}\n```\n\nTo call `format-errors` (assuming it's hosted at `https://format-errors.example.com`), send a `POST` request to `https://format-errors.example.com` with a body containing a serialised `Payload` object. `format-errors` will parse your input, pass it to Youch, and generate an HTML page which will be sent back as the response to the `POST` request.\n\nIf you don't need source context, you can stop there! However, if you'd like to get rid of the \"Missing sources\" message, there's a bit more complexity.\n\n> _Why can't I just pass sources to `format-error` in the request body?_\n>\n> Often your sources won't be available at the location where your error is thrown. You may have access to a sourcemap, but your running code probably doesn't have access to your source code in serialised format. As such, this package is geared towards supporting use cases where you have access to your sources at the time of _viewing_ the generated error page (i.e. in-browser editors).\n\nA requirement of passing sources to `format-errors` is that the generated HTML error page needs to be embedded in an iframe. Once you've done that, you can start passing sources from the embedder of the iframe into the generated HTML error page.\n\nAssuming `iframeEl` is a reference to the iframe which embeds the generated error page, here's an example of how you could pass sources to the generated error page:\n\n```ts\nconst encoder = new TextEncoder();\nconst channel = new MessageChannel();\n\niframeEl.addEventListener(\"load\", () => {\n\tiframeEl.contentWindow?.postMessage(\"PORT\", \"*\", [channel.port2]);\n});\n\nchannel.port1.onmessage = (data) => {\n\tif (data.type === \"RequestSources\") {\n\t\tconst message = {\n\t\t\ttype: \"SourcesLoaded\",\n\t\t\tbody: {\n\t\t\t\tfiles: [\n\t\t\t\t\t{\n\t\t\t\t\t\tpath: \"index.js\",\n\t\t\t\t\t\tcontents: encoder.encode(\"console.log('hi')\"),\n\t\t\t\t\t},\n\t\t\t\t],\n\t\t\t\tinternalLines: 0,\n\t\t\t},\n\t\t};\n\t\tchannel.port1.postMessage(\n\t\t\tmessage,\n\t\t\tmessage.body.files.map((f) => f.contents.buffer)\n\t\t);\n\t}\n};\n```\n\nThe interface is fairly simple. The embedder passes a `MessagePort` to the iframe on load, over which the error page requests sources. Of note: this does not currently support sourcemaps, and it's assumed that the lines within your error stack trace map to the exact line in your source.\n\nThere's one exception to that, to support _very_ limited source transformations, in the `internalLines` property. If you pass a value for `internalLines`, the error page will act as if any error messages from line numbers _below_ `internalLines` are internal, and shouldn't be surfaced to the user. Line numbers in error messages will be remapped so that it appears the user-visible source starts at line `0`, rather than line `internalLines`.\n\n<!-- ... +35 more modular skills available via /api/skills/cloudflare/workers-sdk?path={path} -->\n</yakaai_skills>"}