[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6NZ2Y4GNKZP5VVTCYBJSF2K":3,"skill-same:01M6NZ2Y4GNKZP5VVTCYBJSF2K":71},{"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":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":29,"commitSha":52,"skillDirectory":53,"forksCount":13,"repositoryHtmlUrl":54,"repositoryHomepageUrl":6,"ownerHtmlUrl":55,"ownerBlogUrl":6,"ownerDescription":6,"updatedAt":56,"install":57,"resources":70},"01M6NZ2Y4GNKZP5VVTCYBJSF2K","cloudflare-workers",null,"Build and deploy edge functions with Cloudflare Workers and Wrangler. Use for APIs, cron jobs, and edge middleware.","duc-duy-1612\u002FOnline-Delivery-Systems-Web","duc-duy-1612","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F192231384?v=4","01M6NSDKQQDKVTHZ8DZMZ1VYY6","01M6NSDKW8DDVTQHBT1HBDDJPT",0,"MIT","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fcloudflare-workers\u002FSKILL.md",[],[18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"cloudflare","cloudflare workers","workers","for","security","relevant","middleware","scripts","critical","os","platform","main","community","edge functions","only","access","cron","devops-security","cron jobs","wrangler","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\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# Local development with remote bindings (KV, D1, R2)\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### Middleware: Rate Limiting with KV\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(env.ORIGIN_URL + new URL(request.url).pathname, 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# Preview namespace for local dev\n[[kv_namespaces]]\nbinding = \"MY_KV\"\nid = \"abc123def456\"\npreview_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\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# Local development with remote bindings (KV, D1, R2)\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### Middleware: Rate Limiting with KV\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(env.ORIGIN_URL + new URL(request.url).pathname, 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# Preview namespace for local dev\n[[kv_namespaces]]\nbinding = \"MY_KV\"\nid = \"abc123def456\"\npreview_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":43,"license":14,"category":44,"metadata":45,"date_added":48,"description":7,"source_repo":49,"source_type":30,"compatibility":50,"license_source":51},"https:\u002F\u002Fgithub.com\u002FBagelHole\u002FDevOps-Security-Agent-Skills","devops",{"author":46,"version":47},"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","f3312ba749561b6159f477dbfc9313c875d40a56",".agents\u002Fskills_archive\u002Fcloudflare-workers","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612","2026-10-25 23:50:58",{"source":8,"skillName":5,"commands":58,"prompt":68,"zipAvailable":69},[59,62,65],{"tool":60,"command":61},"npx","npx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill cloudflare-workers",{"tool":63,"command":64},"bunx","bunx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill cloudflare-workers",{"tool":66,"command":67},"pnpm","pnpm dlx skills add duc-duy-1612\u002FOnline-Delivery-Systems-Web --skill cloudflare-workers","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fcloudflare-workers\u002FSKILL.md",true,[],[72,95,119,144,172,196],{"skillNo":73,"name":74,"nameZh":6,"description":75,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":76,"categories":77,"keywords":83,"publishedAt":38},"01M6Q0FA5FZ410Z33Z3TFQ4DBA","zero-trust","Implement zero-trust network architecture. Configure identity-based access, micro-segmentation, and continuous verification. Use when implementing modern security architectures.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzero-trust\u002FSKILL.md",[78],{"categoryNo":79,"categoryName":80,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000011","运维与部署","SCENARIO","使用场景",[84,85,86,87,88,89,74,90,35,33,91,32,30,29,92,26,93,25,23,94],"ZeRO","trust","zero trust","architecture","assessment","verification","segmentation","configure","active","scope","implementing",{"skillNo":96,"name":97,"nameZh":6,"description":98,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":38},"01M6Q0F1YZJW3KX5FBKEVZ8CV4","zcode-delegate","Delegate coding tasks to the Z.AI ZCode CLI only when the user explicitly requests it, while the orchestrator retains review and landing responsibility.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fzcode-delegate\u002FSKILL.md",[],[102,103,104,105,106,107,108,109,110,111,112,113,114,32,115,30,116,117,26,118],"delegate","zcode","zcode delegate","review","cli","orchestration","tasks","run","Bash","model","node","read","orchestrator","files","desktop app","app","agent-orchestration",{"skillNo":120,"name":121,"nameZh":6,"description":122,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":123,"categories":124,"keywords":125,"publishedAt":38},"01M6Q0ETK41VGNMYEXW0T00AJN","youtube-transcript","Fetch YouTube transcripts through DeepAPI or local fallback tooling and save clean text output.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript\u002FSKILL.md",[],[126,127,128,129,130,131,132,133,134,135,136,137,138,30,29,139,140,141,142,143],"transcript","youtube transcript","youtube","safe","github","codex","research","license","https","text","fetch","tooling","clean","local","output","deepapi","youtube transcripts","blob",{"skillNo":145,"name":146,"nameZh":6,"description":147,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":148,"categories":149,"keywords":161,"publishedAt":38},"01M6Q0EPPH2PVMDW40017F8WX0","youtube-transcript-skills","Fetch YouTube video transcripts, search videos\u002Fchannels, browse channels, and extract playlists via the getyoutubetranscript.com API - free tier, no card required.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-transcript-skills\u002FSKILL.md",[150,153,156],{"categoryNo":151,"categoryName":152,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000010","后端与接口",{"categoryNo":154,"categoryName":155,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000016","图像与多媒体",{"categoryNo":157,"categoryName":158,"taxonomyType":159,"taxonomyTypeDesc":160},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[126,127,128,162,129,163,130,131,133,164,165,166,167,136,168,30,29,169,170,171],"youtube transcript skills","gemini","search","api","Video","browse","api-integration","free","card","channels",{"skillNo":173,"name":174,"nameZh":6,"description":175,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":176,"categories":177,"keywords":182,"publishedAt":38},"01M6Q0EAB96PX83W5PTE8A0R8D","youtube-notetaker","Turn YouTube talks into local study notes with slides, transcripts, editable annotations, and a markdown-backed viewer.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-notetaker\u002FSKILL.md",[178,181],{"categoryNo":179,"categoryName":180,"taxonomyType":81,"taxonomyTypeDesc":82},"01JBSEEDCAT000000000000003","演示文稿",{"categoryNo":154,"categoryName":155,"taxonomyType":81,"taxonomyTypeDesc":82},[128,183,184,106,129,185,186,187,188,133,166,189,190,191,192,29,193,139,194,195],"youtube notetaker","notetaker","workflow","official","notes","code","markdown","slides","annotations","README","study","dair-academy","viewer",{"skillNo":197,"name":198,"nameZh":6,"description":199,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":6,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":200,"categories":201,"keywords":203,"publishedAt":38},"01M6Q0E55F0GW5MX48V8HXS8B5","youtube-full","Fetch YouTube transcripts, search videos, browse channels, and extract playlists via TranscriptAPI — no yt-dlp, no Google API key, works from any cloud server.","https:\u002F\u002Fgithub.com\u002Fduc-duy-1612\u002FOnline-Delivery-Systems-Web\u002Fblob\u002Fmain\u002F.agents\u002Fskills_archive\u002Fyoutube-full\u002FSKILL.md",[202],{"categoryNo":151,"categoryName":152,"taxonomyType":81,"taxonomyTypeDesc":82},[204,128,205,206,129,163,164,207,208,165,166,167,136,209,168,30,29,169,210,142],"youtube full","full","google","server","dlp","credits","automatic"]