[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6F4P3MSFJS4X4JV0VB5228H":3,"skill-same:01M6F4P3MSFJS4X4JV0VB5228H":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":29,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":58,"install":59,"resources":72},"01M6F4P3MSFJS4X4JV0VB5228H","cloudflare-workers",null,"Build and deploy edge functions with Cloudflare Workers and Wrangler. Use for APIs, cron jobs, and edge middleware.","boisenoise\u002Fskills-collections","boisenoise","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F193180?v=4","01M6CDBDQK6BDN55ZMA6B6PKBM","01M6CDBDVSJ3JPTBYN26FZ7TZK",12,"MIT","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-cloudflare-workers\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"cloudflare","workers","cloudflare workers","community","2026","relevant","middleware","scripts","critical","os","platform","main","license","edge functions","security","wrangler","only","access","cron","devops-security","cron jobs","2026-11-10 10:12:30",false,"---\nname: cloudflare-workers\ndescription: Build and deploy edge functions with Cloudflare Workers and Wrangler.\n  Use for APIs, cron jobs, and edge middleware.\ncategory: devops\nrisk: critical\nsource: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\nsource_repo: BagelHole\u002FDevOps-Security-Agent-Skills\nsource_type: community\ndate_added: '2026-09-20'\nlicense: MIT\nlicense_source: https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE\ncompatibility: Requires the relevant OS\u002Fplatform tooling and privileged access where\n  noted. Docs-only; helper scripts and templates not bundled.\nmetadata:\n  author: devops-skills\n  version: '1.0'\n---\n\n# Cloudflare Workers\n\nDeploy JavaScript and TypeScript functions to Cloudflare's global edge network with sub-millisecond cold starts.\n\n## When to Use\n\n- Building lightweight APIs and microservices at the edge.\n- Adding middleware (auth, rate limiting, header injection) in front of origin servers.\n- Running cron jobs on a schedule without maintaining infrastructure.\n- Processing webhooks, image transformations, or A\u002FB testing logic.\n- Serving dynamic content from KV, D1, or R2 storage bindings.\n\n## Prerequisites\n\n- Node.js 18+ installed locally.\n- Wrangler CLI: `npm install -g wrangler`.\n- Cloudflare account (free plan supports 100,000 requests\u002Fday).\n- Authenticated: `wrangler login` or set `CLOUDFLARE_API_TOKEN`.\n\nVerify Node\u002FWrangler support, plan quotas and CPU limits for the actual account; historical numbers below are not current entitlement guarantees. Choose target account\u002Fenvironment\u002Froutes explicitly before deploy, rollback or remote dev. KV read-modify-write is non-atomic and eventually consistent; concurrent increments lose updates, repeated puts hit write limits, and TTL resets make this a sliding approximation. Use an authoritative rate limiter for security. Increasing cacheTtl does not make KV strongly consistent. waitUntil is bounded background work, not a durable job queue and does not bypass CPU limits. Bind only approved origins, strip unexpected credentials before proxying and validate incoming data before analytics egress. Inline KV\u002FD1 examples mutate on every request and must be isolated or authenticated. Scheduled helpers and analytics endpoints are placeholders, the third cron has no handler, and the Durable Object class must be re-exported from the configured entrypoint with a compatible migration type.\n\n## Quick Start\n\n```bash\n# Scaffold a new Worker project\nnpm create cloudflare@latest my-worker\ncd my-worker\n\n# Login to Cloudflare\nnpx wrangler login\n\n# Start local development server (port 8787)\nnpx wrangler dev\n\n# Deploy to production\nnpx wrangler deploy\n```\n\n## Essential Wrangler Commands\n\n```bash\n# Remote development: executes in Cloudflare and can affect bound remote resources\nnpx wrangler dev --remote\n\n# Deploy to a specific environment\nnpx wrangler deploy --env staging\n\n# Set a secret (prompts for value)\nnpx wrangler secret put API_TOKEN\nnpx wrangler secret put API_TOKEN --env staging\n\n# List secrets\nnpx wrangler secret list\n\n# Tail production logs in real time\nnpx wrangler tail\n\n# Tail with filters\nnpx wrangler tail --status=error --search=\"timeout\"\n\n# View deployment versions\nnpx wrangler deployments list\n\n# Rollback to a previous deployment\nnpx wrangler rollback\n```\n\n## Wrangler Configuration\n\n```toml\n# wrangler.toml\nname = \"my-api\"\nmain = \"src\u002Findex.ts\"\ncompatibility_date = \"2024-09-01\"\ncompatibility_flags = [\"nodejs_compat\"]\n\n# Custom routes\nroutes = [\n  { pattern = \"api.example.com\u002F*\", zone_name = \"example.com\" }\n]\n\n# Or use a workers.dev subdomain\n# workers_dev = true\n\n# Environment variables (non-secret)\n[vars]\nENVIRONMENT = \"production\"\nAPI_VERSION = \"v2\"\n\n# Staging environment override\n[env.staging]\nname = \"my-api-staging\"\nroutes = [\n  { pattern = \"api-staging.example.com\u002F*\", zone_name = \"example.com\" }\n]\n[env.staging.vars]\nENVIRONMENT = \"staging\"\n```\n\n## Worker Examples\n\n### Basic API Router\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nexport interface Env {\n  ENVIRONMENT: string;\n}\n\nexport default {\n  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise\u003CResponse> {\n    const url = new URL(request.url);\n\n    switch (url.pathname) {\n      case \"\u002F\":\n        return new Response(\"OK\", { status: 200 });\n\n      case \"\u002Fapi\u002Fhealth\":\n        return Response.json({\n          status: \"healthy\",\n          env: env.ENVIRONMENT,\n          timestamp: new Date().toISOString(),\n        });\n\n      case \"\u002Fapi\u002Fdata\":\n        if (request.method !== \"POST\") {\n          return new Response(\"Method Not Allowed\", { status: 405 });\n        }\n        const body = await request.json();\n        \u002F\u002F Process in the background after returning response\n        ctx.waitUntil(logToAnalytics(body));\n        return Response.json({ received: true });\n\n      default:\n        return new Response(\"Not Found\", { status: 404 });\n    }\n  },\n};\n\nasync function logToAnalytics(data: unknown): Promise\u003Cvoid> {\n  await fetch(\"https:\u002F\u002Fanalytics.example.com\u002Fingest\", {\n    method: \"POST\",\n    body: JSON.stringify(data),\n    headers: { \"Content-Type\": \"application\u002Fjson\" },\n  });\n}\n```\n\n### Approximate KV Counter (not an enforcement-grade rate limiter)\n\n```typescript\n\u002F\u002F src\u002Frate-limiter.ts\ninterface Env {\n  RATE_LIMIT_KV: KVNamespace;\n  ORIGIN_URL: string;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    const ip = request.headers.get(\"CF-Connecting-IP\") || \"unknown\";\n    const key = `ratelimit:${ip}`;\n    const window = 60; \u002F\u002F seconds\n    const maxRequests = 100;\n\n    const current = parseInt((await env.RATE_LIMIT_KV.get(key)) || \"0\");\n\n    if (current >= maxRequests) {\n      return new Response(\"Too Many Requests\", {\n        status: 429,\n        headers: { \"Retry-After\": String(window) },\n      });\n    }\n\n    await env.RATE_LIMIT_KV.put(key, String(current + 1), {\n      expirationTtl: window,\n    });\n\n    \u002F\u002F Forward to origin\n    const originRequest = new Request(new URL(new URL(request.url).pathname + new URL(request.url).search, env.ORIGIN_URL), request);\n    return fetch(originRequest);\n  },\n};\n```\n\n## KV Storage Binding\n\n```toml\n# wrangler.toml\n[[kv_namespaces]]\nbinding = \"MY_KV\"\nid = \"abc123def456\"\n\n# Optional preview namespace on the same binding:\n# preview_id = \"preview789\"\n```\n\n```typescript\n\u002F\u002F KV operations in a Worker\ninterface Env {\n  MY_KV: KVNamespace;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    \u002F\u002F Write with TTL\n    await env.MY_KV.put(\"session:abc\", JSON.stringify({ user: \"alice\" }), {\n      expirationTtl: 3600,\n    });\n\n    \u002F\u002F Read\n    const session = await env.MY_KV.get(\"session:abc\", \"json\");\n\n    \u002F\u002F List keys by prefix\n    const list = await env.MY_KV.list({ prefix: \"session:\", limit: 100 });\n\n    \u002F\u002F Delete\n    await env.MY_KV.delete(\"session:abc\");\n\n    return Response.json({ session, keys: list.keys.length });\n  },\n};\n```\n\n```bash\n# KV CLI operations\nnpx wrangler kv namespace create MY_KV\nnpx wrangler kv namespace list\nnpx wrangler kv key put --namespace-id=abc123 \"config:feature-flags\" '{\"darkMode\":true}'\nnpx wrangler kv key get --namespace-id=abc123 \"config:feature-flags\"\nnpx wrangler kv key list --namespace-id=abc123 --prefix=\"config:\"\n```\n\n## D1 Database Binding\n\n```toml\n# wrangler.toml\n[[d1_databases]]\nbinding = \"DB\"\ndatabase_name = \"my-app\"\ndatabase_id = \"xxxx-yyyy-zzzz\"\n```\n\n```typescript\n\u002F\u002F D1 SQL queries in a Worker\ninterface Env {\n  DB: D1Database;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    \u002F\u002F Parameterized query\n    const { results } = await env.DB.prepare(\n      \"SELECT id, name, email FROM users WHERE active = ? LIMIT ?\"\n    )\n      .bind(1, 50)\n      .all();\n\n    \u002F\u002F Insert\n    await env.DB.prepare(\"INSERT INTO users (name, email) VALUES (?, ?)\")\n      .bind(\"Alice\", \"alice@example.com\")\n      .run();\n\n    \u002F\u002F Batch multiple statements\n    await env.DB.batch([\n      env.DB.prepare(\"UPDATE users SET active = 0 WHERE last_login \u003C ?\").bind(\"2024-01-01\"),\n      env.DB.prepare(\"DELETE FROM sessions WHERE expires_at \u003C ?\").bind(Date.now()),\n    ]);\n\n    return Response.json(results);\n  },\n};\n```\n\n```bash\n# D1 CLI operations\nnpx wrangler d1 create my-app\nnpx wrangler d1 list\nnpx wrangler d1 execute my-app --command=\"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, active INTEGER DEFAULT 1)\"\nnpx wrangler d1 execute my-app --file=.\u002Fmigrations\u002F001_init.sql\nnpx wrangler d1 execute my-app --command=\"SELECT * FROM users\" --json\n```\n\n## Cron Triggers\n\n```toml\n# wrangler.toml\n[triggers]\ncrons = [\n  \"0 *\u002F6 * * *\",   # Every 6 hours\n  \"0 0 * * MON\",   # Every Monday at midnight\n  \"*\u002F15 * * * *\",  # Every 15 minutes\n]\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts — scheduled handler\nexport default {\n  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise\u003Cvoid> {\n    switch (event.cron) {\n      case \"0 *\u002F6 * * *\":\n        ctx.waitUntil(cleanupExpiredSessions(env));\n        break;\n      case \"0 0 * * MON\":\n        ctx.waitUntil(generateWeeklyReport(env));\n        break;\n    }\n  },\n\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    return new Response(\"OK\");\n  },\n};\n```\n\n## Durable Objects\n\n```toml\n# wrangler.toml\n[durable_objects]\nbindings = [\n  { name = \"COUNTER\", class_name = \"Counter\" }\n]\n\n[[migrations]]\ntag = \"v1\"\nnew_classes = [\"Counter\"]\n```\n\n```typescript\n\u002F\u002F src\u002Fcounter.ts — Durable Object class\nexport class Counter {\n  state: DurableObjectState;\n\n  constructor(state: DurableObjectState) {\n    this.state = state;\n  }\n\n  async fetch(request: Request): Promise\u003CResponse> {\n    let count = (await this.state.storage.get\u003Cnumber>(\"count\")) || 0;\n    count++;\n    await this.state.storage.put(\"count\", count);\n    return Response.json({ count });\n  }\n}\n\n\u002F\u002F src\u002Findex.ts — route to Durable Object\ninterface Env {\n  COUNTER: DurableObjectNamespace;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    const id = env.COUNTER.idFromName(\"global-counter\");\n    const stub = env.COUNTER.get(id);\n    return stub.fetch(request);\n  },\n};\n```\n\n## Custom Routing\n\n```toml\n# Route to specific zones\nroutes = [\n  { pattern = \"api.example.com\u002Fv1\u002F*\", zone_name = \"example.com\" },\n  { pattern = \"api.example.com\u002Fv2\u002F*\", zone_name = \"example.com\" },\n]\n\n# Or use custom domains (automatic SSL)\n# Dashboard: Workers > your-worker > Triggers > Custom Domains\n```\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Error 1101: Worker threw exception` | Unhandled error in fetch handler | Wrap handler in try\u002Fcatch; check `wrangler tail` for stack trace |\n| `exceeded CPU time limit` | Worker exceeds 10ms CPU (free) or 30s (paid) | Optimize code; offload work with `ctx.waitUntil()` |\n| KV reads return stale data | KV is eventually consistent (~60s) | Use `cacheTtl` option or switch to Durable Objects for strong consistency |\n| `wrangler dev` binding errors | Local bindings not configured | Use `--remote` flag or configure `preview_id` in `wrangler.toml` |\n| Secret not found in Worker | Secret set for wrong environment | Verify with `wrangler secret list --env \u003Cenv>` |\n| CORS errors from browser | Missing CORS headers in response | Add `Access-Control-Allow-Origin` headers; handle OPTIONS preflight |\n| Route not matching | Pattern does not include `\u002F*` suffix | Add `\u002F*` to catch all paths: `api.example.com\u002F*` |\n\n## Related Skills\n\n- cloudflare-pages (`cloudflare-pages`) - Frontend deployments with Pages Functions\n- cloudflare-r2 (`cloudflare-r2`) - Object storage at the edge\n- cloudflare-zero-trust (`cloudflare-zero-trust`) - Protect Worker endpoints with Access\n\n## Limitations\n\n- Infrastructure commands can disrupt services: confirm target host\u002Fscope and have backups\u002Fsnapshots before mutating state.\n- Docs-only import: upstream scripts and templates not bundled.\n\n","# Cloudflare Workers\n\nDeploy JavaScript and TypeScript functions to Cloudflare's global edge network with sub-millisecond cold starts.\n\n## When to Use\n\n- Building lightweight APIs and microservices at the edge.\n- Adding middleware (auth, rate limiting, header injection) in front of origin servers.\n- Running cron jobs on a schedule without maintaining infrastructure.\n- Processing webhooks, image transformations, or A\u002FB testing logic.\n- Serving dynamic content from KV, D1, or R2 storage bindings.\n\n## Prerequisites\n\n- Node.js 18+ installed locally.\n- Wrangler CLI: `npm install -g wrangler`.\n- Cloudflare account (free plan supports 100,000 requests\u002Fday).\n- Authenticated: `wrangler login` or set `CLOUDFLARE_API_TOKEN`.\n\nVerify Node\u002FWrangler support, plan quotas and CPU limits for the actual account; historical numbers below are not current entitlement guarantees. Choose target account\u002Fenvironment\u002Froutes explicitly before deploy, rollback or remote dev. KV read-modify-write is non-atomic and eventually consistent; concurrent increments lose updates, repeated puts hit write limits, and TTL resets make this a sliding approximation. Use an authoritative rate limiter for security. Increasing cacheTtl does not make KV strongly consistent. waitUntil is bounded background work, not a durable job queue and does not bypass CPU limits. Bind only approved origins, strip unexpected credentials before proxying and validate incoming data before analytics egress. Inline KV\u002FD1 examples mutate on every request and must be isolated or authenticated. Scheduled helpers and analytics endpoints are placeholders, the third cron has no handler, and the Durable Object class must be re-exported from the configured entrypoint with a compatible migration type.\n\n## Quick Start\n\n```bash\n# Scaffold a new Worker project\nnpm create cloudflare@latest my-worker\ncd my-worker\n\n# Login to Cloudflare\nnpx wrangler login\n\n# Start local development server (port 8787)\nnpx wrangler dev\n\n# Deploy to production\nnpx wrangler deploy\n```\n\n## Essential Wrangler Commands\n\n```bash\n# Remote development: executes in Cloudflare and can affect bound remote resources\nnpx wrangler dev --remote\n\n# Deploy to a specific environment\nnpx wrangler deploy --env staging\n\n# Set a secret (prompts for value)\nnpx wrangler secret put API_TOKEN\nnpx wrangler secret put API_TOKEN --env staging\n\n# List secrets\nnpx wrangler secret list\n\n# Tail production logs in real time\nnpx wrangler tail\n\n# Tail with filters\nnpx wrangler tail --status=error --search=\"timeout\"\n\n# View deployment versions\nnpx wrangler deployments list\n\n# Rollback to a previous deployment\nnpx wrangler rollback\n```\n\n## Wrangler Configuration\n\n```toml\n# wrangler.toml\nname = \"my-api\"\nmain = \"src\u002Findex.ts\"\ncompatibility_date = \"2024-09-01\"\ncompatibility_flags = [\"nodejs_compat\"]\n\n# Custom routes\nroutes = [\n  { pattern = \"api.example.com\u002F*\", zone_name = \"example.com\" }\n]\n\n# Or use a workers.dev subdomain\n# workers_dev = true\n\n# Environment variables (non-secret)\n[vars]\nENVIRONMENT = \"production\"\nAPI_VERSION = \"v2\"\n\n# Staging environment override\n[env.staging]\nname = \"my-api-staging\"\nroutes = [\n  { pattern = \"api-staging.example.com\u002F*\", zone_name = \"example.com\" }\n]\n[env.staging.vars]\nENVIRONMENT = \"staging\"\n```\n\n## Worker Examples\n\n### Basic API Router\n\n```typescript\n\u002F\u002F src\u002Findex.ts\nexport interface Env {\n  ENVIRONMENT: string;\n}\n\nexport default {\n  async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise\u003CResponse> {\n    const url = new URL(request.url);\n\n    switch (url.pathname) {\n      case \"\u002F\":\n        return new Response(\"OK\", { status: 200 });\n\n      case \"\u002Fapi\u002Fhealth\":\n        return Response.json({\n          status: \"healthy\",\n          env: env.ENVIRONMENT,\n          timestamp: new Date().toISOString(),\n        });\n\n      case \"\u002Fapi\u002Fdata\":\n        if (request.method !== \"POST\") {\n          return new Response(\"Method Not Allowed\", { status: 405 });\n        }\n        const body = await request.json();\n        \u002F\u002F Process in the background after returning response\n        ctx.waitUntil(logToAnalytics(body));\n        return Response.json({ received: true });\n\n      default:\n        return new Response(\"Not Found\", { status: 404 });\n    }\n  },\n};\n\nasync function logToAnalytics(data: unknown): Promise\u003Cvoid> {\n  await fetch(\"https:\u002F\u002Fanalytics.example.com\u002Fingest\", {\n    method: \"POST\",\n    body: JSON.stringify(data),\n    headers: { \"Content-Type\": \"application\u002Fjson\" },\n  });\n}\n```\n\n### Approximate KV Counter (not an enforcement-grade rate limiter)\n\n```typescript\n\u002F\u002F src\u002Frate-limiter.ts\ninterface Env {\n  RATE_LIMIT_KV: KVNamespace;\n  ORIGIN_URL: string;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    const ip = request.headers.get(\"CF-Connecting-IP\") || \"unknown\";\n    const key = `ratelimit:${ip}`;\n    const window = 60; \u002F\u002F seconds\n    const maxRequests = 100;\n\n    const current = parseInt((await env.RATE_LIMIT_KV.get(key)) || \"0\");\n\n    if (current >= maxRequests) {\n      return new Response(\"Too Many Requests\", {\n        status: 429,\n        headers: { \"Retry-After\": String(window) },\n      });\n    }\n\n    await env.RATE_LIMIT_KV.put(key, String(current + 1), {\n      expirationTtl: window,\n    });\n\n    \u002F\u002F Forward to origin\n    const originRequest = new Request(new URL(new URL(request.url).pathname + new URL(request.url).search, env.ORIGIN_URL), request);\n    return fetch(originRequest);\n  },\n};\n```\n\n## KV Storage Binding\n\n```toml\n# wrangler.toml\n[[kv_namespaces]]\nbinding = \"MY_KV\"\nid = \"abc123def456\"\n\n# Optional preview namespace on the same binding:\n# preview_id = \"preview789\"\n```\n\n```typescript\n\u002F\u002F KV operations in a Worker\ninterface Env {\n  MY_KV: KVNamespace;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    \u002F\u002F Write with TTL\n    await env.MY_KV.put(\"session:abc\", JSON.stringify({ user: \"alice\" }), {\n      expirationTtl: 3600,\n    });\n\n    \u002F\u002F Read\n    const session = await env.MY_KV.get(\"session:abc\", \"json\");\n\n    \u002F\u002F List keys by prefix\n    const list = await env.MY_KV.list({ prefix: \"session:\", limit: 100 });\n\n    \u002F\u002F Delete\n    await env.MY_KV.delete(\"session:abc\");\n\n    return Response.json({ session, keys: list.keys.length });\n  },\n};\n```\n\n```bash\n# KV CLI operations\nnpx wrangler kv namespace create MY_KV\nnpx wrangler kv namespace list\nnpx wrangler kv key put --namespace-id=abc123 \"config:feature-flags\" '{\"darkMode\":true}'\nnpx wrangler kv key get --namespace-id=abc123 \"config:feature-flags\"\nnpx wrangler kv key list --namespace-id=abc123 --prefix=\"config:\"\n```\n\n## D1 Database Binding\n\n```toml\n# wrangler.toml\n[[d1_databases]]\nbinding = \"DB\"\ndatabase_name = \"my-app\"\ndatabase_id = \"xxxx-yyyy-zzzz\"\n```\n\n```typescript\n\u002F\u002F D1 SQL queries in a Worker\ninterface Env {\n  DB: D1Database;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    \u002F\u002F Parameterized query\n    const { results } = await env.DB.prepare(\n      \"SELECT id, name, email FROM users WHERE active = ? LIMIT ?\"\n    )\n      .bind(1, 50)\n      .all();\n\n    \u002F\u002F Insert\n    await env.DB.prepare(\"INSERT INTO users (name, email) VALUES (?, ?)\")\n      .bind(\"Alice\", \"alice@example.com\")\n      .run();\n\n    \u002F\u002F Batch multiple statements\n    await env.DB.batch([\n      env.DB.prepare(\"UPDATE users SET active = 0 WHERE last_login \u003C ?\").bind(\"2024-01-01\"),\n      env.DB.prepare(\"DELETE FROM sessions WHERE expires_at \u003C ?\").bind(Date.now()),\n    ]);\n\n    return Response.json(results);\n  },\n};\n```\n\n```bash\n# D1 CLI operations\nnpx wrangler d1 create my-app\nnpx wrangler d1 list\nnpx wrangler d1 execute my-app --command=\"CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT, active INTEGER DEFAULT 1)\"\nnpx wrangler d1 execute my-app --file=.\u002Fmigrations\u002F001_init.sql\nnpx wrangler d1 execute my-app --command=\"SELECT * FROM users\" --json\n```\n\n## Cron Triggers\n\n```toml\n# wrangler.toml\n[triggers]\ncrons = [\n  \"0 *\u002F6 * * *\",   # Every 6 hours\n  \"0 0 * * MON\",   # Every Monday at midnight\n  \"*\u002F15 * * * *\",  # Every 15 minutes\n]\n```\n\n```typescript\n\u002F\u002F src\u002Findex.ts — scheduled handler\nexport default {\n  async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext): Promise\u003Cvoid> {\n    switch (event.cron) {\n      case \"0 *\u002F6 * * *\":\n        ctx.waitUntil(cleanupExpiredSessions(env));\n        break;\n      case \"0 0 * * MON\":\n        ctx.waitUntil(generateWeeklyReport(env));\n        break;\n    }\n  },\n\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    return new Response(\"OK\");\n  },\n};\n```\n\n## Durable Objects\n\n```toml\n# wrangler.toml\n[durable_objects]\nbindings = [\n  { name = \"COUNTER\", class_name = \"Counter\" }\n]\n\n[[migrations]]\ntag = \"v1\"\nnew_classes = [\"Counter\"]\n```\n\n```typescript\n\u002F\u002F src\u002Fcounter.ts — Durable Object class\nexport class Counter {\n  state: DurableObjectState;\n\n  constructor(state: DurableObjectState) {\n    this.state = state;\n  }\n\n  async fetch(request: Request): Promise\u003CResponse> {\n    let count = (await this.state.storage.get\u003Cnumber>(\"count\")) || 0;\n    count++;\n    await this.state.storage.put(\"count\", count);\n    return Response.json({ count });\n  }\n}\n\n\u002F\u002F src\u002Findex.ts — route to Durable Object\ninterface Env {\n  COUNTER: DurableObjectNamespace;\n}\n\nexport default {\n  async fetch(request: Request, env: Env): Promise\u003CResponse> {\n    const id = env.COUNTER.idFromName(\"global-counter\");\n    const stub = env.COUNTER.get(id);\n    return stub.fetch(request);\n  },\n};\n```\n\n## Custom Routing\n\n```toml\n# Route to specific zones\nroutes = [\n  { pattern = \"api.example.com\u002Fv1\u002F*\", zone_name = \"example.com\" },\n  { pattern = \"api.example.com\u002Fv2\u002F*\", zone_name = \"example.com\" },\n]\n\n# Or use custom domains (automatic SSL)\n# Dashboard: Workers > your-worker > Triggers > Custom Domains\n```\n\n## Troubleshooting\n\n| Symptom | Cause | Fix |\n|---------|-------|-----|\n| `Error 1101: Worker threw exception` | Unhandled error in fetch handler | Wrap handler in try\u002Fcatch; check `wrangler tail` for stack trace |\n| `exceeded CPU time limit` | Worker exceeds 10ms CPU (free) or 30s (paid) | Optimize code; offload work with `ctx.waitUntil()` |\n| KV reads return stale data | KV is eventually consistent (~60s) | Use `cacheTtl` option or switch to Durable Objects for strong consistency |\n| `wrangler dev` binding errors | Local bindings not configured | Use `--remote` flag or configure `preview_id` in `wrangler.toml` |\n| Secret not found in Worker | Secret set for wrong environment | Verify with `wrangler secret list --env \u003Cenv>` |\n| CORS errors from browser | Missing CORS headers in response | Add `Access-Control-Allow-Origin` headers; handle OPTIONS preflight |\n| Route not matching | Pattern does not include `\u002F*` suffix | Add `\u002F*` to catch all paths: `api.example.com\u002F*` |\n\n## Related Skills\n\n- cloudflare-pages (`cloudflare-pages`) - Frontend deployments with Pages Functions\n- cloudflare-r2 (`cloudflare-r2`) - Object storage at the edge\n- cloudflare-zero-trust (`cloudflare-zero-trust`) - Protect Worker endpoints with Access\n\n## Limitations\n\n- Infrastructure commands can disrupt services: confirm target host\u002Fscope and have backups\u002Fsnapshots before mutating state.\n- Docs-only import: upstream scripts and templates not bundled.\n\n",{"name":5,"risk":26,"source":44,"license":14,"category":45,"metadata":46,"date_added":49,"description":7,"source_repo":50,"source_type":21,"compatibility":51,"license_source":52},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","devops",{"author":47,"version":48},"devops-skills","1.0","2026-09-20","BagelHole\u002FDevOps-Security-Agent-Skills","Requires the relevant OS\u002Fplatform tooling and privileged access where noted. Docs-only; helper scripts and templates not bundled.","https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills\u002Fblob\u002Fmain\u002FLICENSE","7bf2279c8a65758319526a721d5c4b75683aec9c","skills\u002Fantigravity-cloudflare-workers",3,"https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections","https:\u002F\u002Fgithub.com\u002Fboisenoise","2026-11-10 14:20:15",{"source":8,"skillName":5,"commands":60,"prompt":70,"zipAvailable":71},[61,64,67],{"tool":62,"command":63},"npx","npx skills add boisenoise\u002Fskills-collections --skill cloudflare-workers",{"tool":65,"command":66},"bunx","bunx skills add boisenoise\u002Fskills-collections --skill cloudflare-workers",{"tool":68,"command":69},"pnpm","pnpm dlx skills add boisenoise\u002Fskills-collections --skill cloudflare-workers","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-cloudflare-workers\u002FSKILL.md",true,[],[74,99,126,152,171,194],{"skillNo":75,"name":76,"nameZh":6,"description":77,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":79,"sourceHtmlUrl":80,"categories":81,"keywords":82,"publishedAt":39},"01M6WNH92BHVFXHGPDZCPJ0AG0","web-access","Use Treg for public web or platform data only when existing search, browser and connected tools cannot cover the task, with explicit cost and data boundaries.","Apache-2.0","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-web-access\u002FSKILL.md",[],[83,35,84,85,86,87,88,89,90,91,92,34,93,94,28,26,95,96,97,98,22],"web","web access","official","development","browser","search","data","Tools","read","fetch","youtube","free tools","free","cover","normal","when",{"skillNo":100,"name":101,"nameZh":6,"description":102,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":103,"sourceHtmlUrl":104,"categories":105,"keywords":111,"publishedAt":39},"01M6WNF9XAYAB2CZDDJBAKNM93","treg","Use the Treg CLI or MCP catalog to discover, price and call authorized external tools with team-scoped credentials and a user-approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-treg\u002FSKILL.md",[106],{"categoryNo":107,"categoryName":108,"taxonomyType":109,"taxonomyTypeDesc":110},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[101,112,113,114,85,86,30,90,115,116,117,118,119,120,121,26,122,123,124,125,22],"MCP","cli","github","Budget","credentials","team","catalog","use","call","discover","external tools","with","scoped","blob",{"skillNo":127,"name":128,"nameZh":6,"description":129,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":130,"sourceHtmlUrl":131,"categories":132,"keywords":138,"publishedAt":39},"01M6WN93MEAZ4E41DYAHJRPHQT","recruit","Turn a job description into an evidence-linked candidate shortlist through Treg, with job-related ranking and optional authorized business contact enrichment.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-recruit\u002FSKILL.md",[133],{"categoryNo":134,"categoryName":135,"taxonomyType":136,"taxonomyTypeDesc":137},"01JBSEEDCAT000000000000038","人力资源","PROFESSION","适用职业",[128,114,85,30,139,140,141,142,143,144,26,145,146,147,123,148,149,150,151,125,101,22],"https","email","enrichment","business","evidence","phone","ranking","post","job description","for","person","candidate","reason",{"skillNo":153,"name":154,"nameZh":6,"description":155,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":156,"sourceHtmlUrl":157,"categories":158,"keywords":159,"publishedAt":39},"01M6WN8R5RXSMHM9B4D9FAFX42","rea-growth","Analyze a company’s public growth and content through Treg, distinguish observations from hypotheses, and produce an evidence-linked playbook within an approved budget.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-rea-growth\u002FSKILL.md",[],[160,161,162,114,85,30,163,164,139,165,115,166,167,168,143,26,169,170,125,101,22],"growth","rea","rea growth","produce","content","playbook","marketing","analyze","public","observations","company",{"skillNo":172,"name":173,"nameZh":6,"description":174,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":175,"sourceHtmlUrl":176,"categories":177,"keywords":178,"publishedAt":39},"01M6WN2EVE3RQRGWAKBT4S7YT2","make-ugc","Create original AI UGC-style product videos through Treg: research hooks, approve a licensed presenter and voice, generate clips, add captions and report costs.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-make-ugc\u002FSKILL.md",[],[179,180,114,181,85,182,30,183,184,185,186,187,26,188,189,190,191,192,193,125],"make","make ugc","research","create","Video","Captions","ads","short","hooks","head","style","niche","trending","talking-head","approve",{"skillNo":195,"name":196,"nameZh":6,"description":197,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":78,"licenseFileUrl":198,"sourceHtmlUrl":199,"categories":200,"keywords":201,"publishedAt":39},"01M6WN10ARAA63Y8K1YNGXJ2RM","lead-signals","Find and qualify public buying signals through Treg, rank fitting business accounts and optionally enrich authorized business contact information.","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FLICENSE","https:\u002F\u002Fgithub.com\u002Fboisenoise\u002Fskills-collections\u002Fblob\u002Fmain\u002Fskills\u002Fantigravity-lead-signals\u002FSKILL.md",[],[202,203,204,114,85,30,205,206,142,207,208,26,209,210,211,212,213,214,215,125],"signals","lead","lead signals","how","find","ready","as","how to","qualify","people","information","enrich","changes","funding"]