opencodekit 0.15.3 → 0.15.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +1 -1
- package/dist/template/.opencode/AGENTS.md +209 -77
- package/dist/template/.opencode/agent/plan.md +4 -0
- package/dist/template/.opencode/command/cloudflare.md +70 -0
- package/dist/template/.opencode/package.json +1 -1
- package/dist/template/.opencode/skill/cloudflare/SKILL.md +233 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/README.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/api.md +100 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/configuration.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/gotchas.md +59 -0
- package/dist/template/.opencode/skill/cloudflare/references/agents-sdk/patterns.md +89 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-gateway/README.md +695 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/api.md +38 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/configuration.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/gotchas.md +41 -0
- package/dist/template/.opencode/skill/cloudflare/references/ai-search/patterns.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/api.md +27 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/configuration.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/gotchas.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/analytics-engine/patterns.md +36 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/README.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/api.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/configuration.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/gotchas.md +28 -0
- package/dist/template/.opencode/skill/cloudflare/references/api/patterns.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/README.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/api.md +78 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/configuration.md +128 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/gotchas.md +51 -0
- package/dist/template/.opencode/skill/cloudflare/references/api-shield/patterns.md +145 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/api.md +50 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/configuration.md +53 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/gotchas.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/argo-smart-routing/patterns.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/configuration.md +58 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/gotchas.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/bindings/patterns.md +37 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/README.md +71 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/api.md +168 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/configuration.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/gotchas.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/bot-management/patterns.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/api.md +54 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/configuration.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/gotchas.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/browser-rendering/patterns.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/c3/README.md +264 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/README.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/api.md +176 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/configuration.md +164 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/gotchas.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/cache-reserve/patterns.md +180 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/api.md +43 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/configuration.md +56 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/gotchas.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/containers/patterns.md +40 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/README.md +85 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/api.md +198 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/configuration.md +151 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/gotchas.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/cron-triggers/patterns.md +122 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/README.md +92 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/api.md +141 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/gotchas.md +70 -0
- package/dist/template/.opencode/skill/cloudflare/references/d1/patterns.md +144 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/README.md +34 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/api.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/configuration.md +67 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/gotchas.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/ddos/patterns.md +158 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/api.md +89 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/configuration.md +116 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/gotchas.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/do-storage/patterns.md +112 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/README.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/api.md +152 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/configuration.md +148 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/gotchas.md +158 -0
- package/dist/template/.opencode/skill/cloudflare/references/durable-objects/patterns.md +255 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/api.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/configuration.md +63 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/gotchas.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-routing/patterns.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/email-workers/README.md +598 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/api.md +137 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/configuration.md +133 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/gotchas.md +184 -0
- package/dist/template/.opencode/skill/cloudflare/references/hyperdrive/patterns.md +176 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/configuration.md +45 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/gotchas.md +23 -0
- package/dist/template/.opencode/skill/cloudflare/references/images/patterns.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/README.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/api.md +114 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/configuration.md +92 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/gotchas.md +117 -0
- package/dist/template/.opencode/skill/cloudflare/references/kv/patterns.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/README.md +64 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/api.md +144 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/configuration.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/gotchas.md +187 -0
- package/dist/template/.opencode/skill/cloudflare/references/miniflare/patterns.md +211 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/README.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/api.md +240 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/gotchas.md +171 -0
- package/dist/template/.opencode/skill/cloudflare/references/network-interconnect/patterns.md +171 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/api.md +51 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/configuration.md +60 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/gotchas.md +36 -0
- package/dist/template/.opencode/skill/cloudflare/references/observability/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/README.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/api.md +200 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/configuration.md +228 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/gotchas.md +161 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages/patterns.md +145 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/README.md +57 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/api.md +201 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/configuration.md +159 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/gotchas.md +151 -0
- package/dist/template/.opencode/skill/cloudflare/references/pages-functions/patterns.md +190 -0
- package/dist/template/.opencode/skill/cloudflare/references/pipelines/README.md +664 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/README.md +107 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/api.md +194 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/configuration.md +216 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/gotchas.md +223 -0
- package/dist/template/.opencode/skill/cloudflare/references/pulumi/patterns.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/README.md +69 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/api.md +138 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/configuration.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/gotchas.md +112 -0
- package/dist/template/.opencode/skill/cloudflare/references/queues/patterns.md +155 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/README.md +61 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/api.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/configuration.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/gotchas.md +94 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2/patterns.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/README.md +18 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/api.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/configuration.md +39 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/gotchas.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-data-catalog/patterns.md +46 -0
- package/dist/template/.opencode/skill/cloudflare/references/r2-sql/README.md +512 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/README.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/api.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/configuration.md +63 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/gotchas.md +75 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtime-sfu/patterns.md +102 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/README.md +81 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/api.md +164 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/configuration.md +147 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/gotchas.md +172 -0
- package/dist/template/.opencode/skill/cloudflare/references/realtimekit/patterns.md +155 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/README.md +90 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/api.md +178 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/configuration.md +131 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/gotchas.md +156 -0
- package/dist/template/.opencode/skill/cloudflare/references/sandbox/patterns.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/README.md +58 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/api.md +182 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/configuration.md +140 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/gotchas.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/secrets-store/patterns.md +218 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/README.md +91 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/api.md +139 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/configuration.md +129 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/gotchas.md +87 -0
- package/dist/template/.opencode/skill/cloudflare/references/smart-placement/patterns.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/README.md +15 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/api.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/configuration.md +33 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/gotchas.md +21 -0
- package/dist/template/.opencode/skill/cloudflare/references/snippets/patterns.md +34 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/api.md +24 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/configuration.md +43 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/gotchas.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/spectrum/patterns.md +40 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/configuration.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/gotchas.md +44 -0
- package/dist/template/.opencode/skill/cloudflare/references/static-assets/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/README.md +103 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/api.md +204 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/configuration.md +127 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/gotchas.md +131 -0
- package/dist/template/.opencode/skill/cloudflare/references/stream/patterns.md +152 -0
- package/dist/template/.opencode/skill/cloudflare/references/tail-workers/README.md +640 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/README.md +76 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/api.md +159 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/configuration.md +156 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/gotchas.md +207 -0
- package/dist/template/.opencode/skill/cloudflare/references/terraform/patterns.md +135 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/README.md +82 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/api.md +105 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/configuration.md +113 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/gotchas.md +115 -0
- package/dist/template/.opencode/skill/cloudflare/references/tunnel/patterns.md +157 -0
- package/dist/template/.opencode/skill/cloudflare/references/turn/README.md +699 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/configuration.md +19 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/gotchas.md +27 -0
- package/dist/template/.opencode/skill/cloudflare/references/turnstile/patterns.md +41 -0
- package/dist/template/.opencode/skill/cloudflare/references/vectorize/README.md +682 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/README.md +14 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/api.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/configuration.md +44 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/gotchas.md +24 -0
- package/dist/template/.opencode/skill/cloudflare/references/waf/patterns.md +29 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/README.md +19 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/api.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/configuration.md +31 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/gotchas.md +28 -0
- package/dist/template/.opencode/skill/cloudflare/references/web-analytics/patterns.md +52 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/README.md +47 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/api.md +199 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/configuration.md +185 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/gotchas.md +203 -0
- package/dist/template/.opencode/skill/cloudflare/references/workerd/patterns.md +216 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/README.md +96 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/api.md +137 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/configuration.md +147 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/gotchas.md +99 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers/patterns.md +149 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-ai/README.md +116 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/README.md +48 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/api.md +169 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/configuration.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/gotchas.md +130 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-for-platforms/patterns.md +170 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/README.md +16 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/api.md +20 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/configuration.md +3 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/gotchas.md +35 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-playground/patterns.md +42 -0
- package/dist/template/.opencode/skill/cloudflare/references/workers-vpc/README.md +579 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/README.md +62 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/api.md +125 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/configuration.md +177 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/gotchas.md +136 -0
- package/dist/template/.opencode/skill/cloudflare/references/workflows/patterns.md +132 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/README.md +90 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/api.md +140 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/configuration.md +128 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/gotchas.md +93 -0
- package/dist/template/.opencode/skill/cloudflare/references/wrangler/patterns.md +150 -0
- package/dist/template/.opencode/skill/cloudflare/references/zaraz/README.md +360 -0
- package/dist/template/.opencode/skill/react-best-practices/AGENTS.md +2410 -0
- package/dist/template/.opencode/skill/react-best-practices/README.md +123 -0
- package/dist/template/.opencode/skill/react-best-practices/SKILL.md +125 -0
- package/dist/template/.opencode/skill/react-best-practices/metadata.json +15 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/_sections.md +46 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/_template.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/advanced-event-handler-refs.md +55 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/advanced-use-latest.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-api-routes.md +38 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-defer-await.md +80 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-dependencies.md +36 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-parallel.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/async-suspense-boundaries.md +99 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-barrel-imports.md +59 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-conditional.md +31 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-defer-third-party.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-dynamic-imports.md +35 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/bundle-preload.md +50 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-event-listeners.md +74 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-localstorage-schema.md +71 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-passive-event-listeners.md +48 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/client-swr-dedup.md +56 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-batch-dom-css.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-function-results.md +80 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-property-access.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-cache-storage.md +70 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-combine-iterations.md +32 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-early-exit.md +50 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-hoist-regexp.md +45 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-index-maps.md +37 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-length-check-first.md +49 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-min-max-loop.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-set-map-lookups.md +24 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/js-tosorted-immutable.md +57 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-activity.md +26 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-animate-svg-wrapper.md +47 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-conditional-render.md +40 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-content-visibility.md +38 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-hoist-jsx.md +46 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-hydration-no-flicker.md +82 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rendering-svg-precision.md +28 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-defer-reads.md +39 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-dependencies.md +45 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-derived-state.md +29 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-functional-setstate.md +74 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-lazy-state-init.md +58 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-memo.md +44 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/rerender-transitions.md +40 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-after-nonblocking.md +73 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-cache-lru.md +41 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-cache-react.md +76 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-parallel-fetching.md +83 -0
- package/dist/template/.opencode/skill/react-best-practices/rules/server-serialization.md +38 -0
- package/dist/template/.opencode/skill/supabase/SKILL.md +120 -0
- package/dist/template/.opencode/skill/supabase/mcp.json +27 -0
- package/dist/template/.opencode/skill/vercel-deploy-claimable/SKILL.md +112 -0
- package/dist/template/.opencode/skill/vercel-deploy-claimable/scripts/deploy.sh +249 -0
- package/dist/template/.opencode/skill/web-design-guidelines/SKILL.md +39 -0
- package/package.json +1 -1
|
@@ -0,0 +1,640 @@
|
|
|
1
|
+
# Cloudflare Tail Workers Skill
|
|
2
|
+
|
|
3
|
+
## Purpose
|
|
4
|
+
Expert guidance on Cloudflare Tail Workers—specialized Workers that consume execution events from producer Workers for logging, debugging, analytics, and observability.
|
|
5
|
+
|
|
6
|
+
## When to Use
|
|
7
|
+
- User implements observability/logging for Cloudflare Workers
|
|
8
|
+
- User needs to process Worker execution events, logs, exceptions
|
|
9
|
+
- User builds custom analytics or error tracking
|
|
10
|
+
- User configures real-time event streaming
|
|
11
|
+
- User mentions tail handlers, tail consumers, or producer Workers
|
|
12
|
+
|
|
13
|
+
## Core Concepts
|
|
14
|
+
|
|
15
|
+
### What Are Tail Workers?
|
|
16
|
+
Tail Workers automatically process events from producer Workers (the Workers being monitored). They receive:
|
|
17
|
+
- HTTP request/response info
|
|
18
|
+
- Console logs (console.log/error/warn/debug)
|
|
19
|
+
- Uncaught exceptions
|
|
20
|
+
- Execution outcomes (ok, exception, exceededCpu, etc.)
|
|
21
|
+
- Diagnostic channel events
|
|
22
|
+
|
|
23
|
+
**Key characteristics:**
|
|
24
|
+
- Invoked AFTER producer finishes executing
|
|
25
|
+
- Capture entire request lifecycle including Service Bindings and Dynamic Dispatch sub-requests
|
|
26
|
+
- Billed by CPU time, not request count
|
|
27
|
+
- Available on Workers Paid and Enterprise tiers
|
|
28
|
+
|
|
29
|
+
### Alternative: OpenTelemetry Export
|
|
30
|
+
For batch exports to observability tools (Sentry, Grafana, Honeycomb):
|
|
31
|
+
- Consider OTEL export instead of Tail Workers
|
|
32
|
+
- OTEL sends logs/traces in batches (more efficient)
|
|
33
|
+
- Tail Workers = advanced mode for custom processing
|
|
34
|
+
|
|
35
|
+
## Implementation Patterns
|
|
36
|
+
|
|
37
|
+
### Basic Tail Handler Structure
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
export default {
|
|
41
|
+
async tail(events, env, ctx) {
|
|
42
|
+
// Process events from producer Worker
|
|
43
|
+
}
|
|
44
|
+
};
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Parameters:**
|
|
48
|
+
- `events`: Array of `TailItem` objects (one per producer invocation)
|
|
49
|
+
- `env`: Bindings (KV, D1, R2, env vars, etc.)
|
|
50
|
+
- `ctx`: Context with `waitUntil()` for async work
|
|
51
|
+
|
|
52
|
+
**CRITICAL:** Tail handlers don't return values. Use `ctx.waitUntil()` for async operations.
|
|
53
|
+
|
|
54
|
+
### Event Structure (`TailItem`)
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
interface TailItem {
|
|
58
|
+
scriptName: string; // Producer Worker name
|
|
59
|
+
eventTimestamp: number; // Epoch time
|
|
60
|
+
outcome: 'ok' | 'exception' | 'exceededCpu' | 'exceededMemory'
|
|
61
|
+
| 'canceled' | 'scriptNotFound' | 'responseStreamDisconnected' | 'unknown';
|
|
62
|
+
|
|
63
|
+
event: {
|
|
64
|
+
request?: {
|
|
65
|
+
url: string; // Redacted by default
|
|
66
|
+
method: string;
|
|
67
|
+
headers: Record<string, string>; // Sensitive headers redacted
|
|
68
|
+
cf: IncomingRequestCfProperties;
|
|
69
|
+
getUnredacted(): TailRequest; // Bypass redaction (use carefully)
|
|
70
|
+
};
|
|
71
|
+
response?: {
|
|
72
|
+
status: number;
|
|
73
|
+
};
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
logs: Array<{
|
|
77
|
+
timestamp: number;
|
|
78
|
+
level: 'debug' | 'info' | 'log' | 'warn' | 'error';
|
|
79
|
+
message: any[]; // Args passed to console function
|
|
80
|
+
}>;
|
|
81
|
+
|
|
82
|
+
exceptions: Array<{
|
|
83
|
+
timestamp: number;
|
|
84
|
+
name: string; // Error type (Error, TypeError, etc.)
|
|
85
|
+
message: string; // Error description
|
|
86
|
+
}>;
|
|
87
|
+
|
|
88
|
+
diagnosticsChannelEvents: Array<{
|
|
89
|
+
channel: string;
|
|
90
|
+
message: any;
|
|
91
|
+
timestamp: number;
|
|
92
|
+
}>;
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
### Configuration
|
|
97
|
+
|
|
98
|
+
**Producer Worker wrangler.toml:**
|
|
99
|
+
```toml
|
|
100
|
+
name = "my-producer-worker"
|
|
101
|
+
tail_consumers = [{service = "my-tail-worker"}]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
**Producer Worker wrangler.jsonc:**
|
|
105
|
+
```json
|
|
106
|
+
{
|
|
107
|
+
"name": "my-producer-worker",
|
|
108
|
+
"tail_consumers": [
|
|
109
|
+
{
|
|
110
|
+
"service": "my-tail-worker"
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
}
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
**Tail Worker wrangler.toml:**
|
|
117
|
+
```toml
|
|
118
|
+
name = "my-tail-worker"
|
|
119
|
+
# No special config needed, just must have tail() handler
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Common Use Cases
|
|
123
|
+
|
|
124
|
+
### 1. Send Logs to HTTP Endpoint
|
|
125
|
+
|
|
126
|
+
```typescript
|
|
127
|
+
export default {
|
|
128
|
+
async tail(events, env, ctx) {
|
|
129
|
+
const payload = events.map(event => ({
|
|
130
|
+
script: event.scriptName,
|
|
131
|
+
timestamp: event.eventTimestamp,
|
|
132
|
+
outcome: event.outcome,
|
|
133
|
+
url: event.event?.request?.url,
|
|
134
|
+
status: event.event?.response?.status,
|
|
135
|
+
logs: event.logs,
|
|
136
|
+
exceptions: event.exceptions,
|
|
137
|
+
}));
|
|
138
|
+
|
|
139
|
+
ctx.waitUntil(
|
|
140
|
+
fetch(env.LOG_ENDPOINT, {
|
|
141
|
+
method: "POST",
|
|
142
|
+
headers: { "Content-Type": "application/json" },
|
|
143
|
+
body: JSON.stringify(payload),
|
|
144
|
+
})
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
};
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### 2. Error Tracking to External Service
|
|
151
|
+
|
|
152
|
+
```typescript
|
|
153
|
+
export default {
|
|
154
|
+
async tail(events, env, ctx) {
|
|
155
|
+
for (const event of events) {
|
|
156
|
+
// Only process errors
|
|
157
|
+
if (event.outcome === 'exception' || event.exceptions.length > 0) {
|
|
158
|
+
ctx.waitUntil(
|
|
159
|
+
fetch("https://error-tracker.example.com/errors", {
|
|
160
|
+
method: "POST",
|
|
161
|
+
headers: {
|
|
162
|
+
"Authorization": `Bearer ${env.ERROR_TRACKER_TOKEN}`,
|
|
163
|
+
"Content-Type": "application/json",
|
|
164
|
+
},
|
|
165
|
+
body: JSON.stringify({
|
|
166
|
+
script: event.scriptName,
|
|
167
|
+
timestamp: event.eventTimestamp,
|
|
168
|
+
exceptions: event.exceptions,
|
|
169
|
+
request: event.event?.request?.getUnredacted?.(), // If needed
|
|
170
|
+
logs: event.logs,
|
|
171
|
+
}),
|
|
172
|
+
})
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### 3. Store Logs in KV
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
export default {
|
|
184
|
+
async tail(events, env, ctx) {
|
|
185
|
+
const promises = events.map(event => {
|
|
186
|
+
const key = `log:${event.scriptName}:${event.eventTimestamp}`;
|
|
187
|
+
const value = JSON.stringify({
|
|
188
|
+
outcome: event.outcome,
|
|
189
|
+
logs: event.logs,
|
|
190
|
+
exceptions: event.exceptions,
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
// TTL: 24 hours
|
|
194
|
+
return env.LOGS_KV.put(key, value, { expirationTtl: 86400 });
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
ctx.waitUntil(Promise.all(promises));
|
|
198
|
+
}
|
|
199
|
+
};
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### 4. Analytics Engine for Aggregated Metrics
|
|
203
|
+
|
|
204
|
+
```typescript
|
|
205
|
+
export default {
|
|
206
|
+
async tail(events, env, ctx) {
|
|
207
|
+
const writes = events.map(event =>
|
|
208
|
+
env.ANALYTICS.writeDataPoint({
|
|
209
|
+
// String dimensions
|
|
210
|
+
blobs: [
|
|
211
|
+
event.scriptName,
|
|
212
|
+
event.outcome,
|
|
213
|
+
event.event?.request?.method ?? 'unknown',
|
|
214
|
+
],
|
|
215
|
+
// Numeric metrics
|
|
216
|
+
doubles: [
|
|
217
|
+
1, // Count
|
|
218
|
+
event.event?.response?.status ?? 0,
|
|
219
|
+
],
|
|
220
|
+
// Indexed fields for filtering
|
|
221
|
+
indexes: [
|
|
222
|
+
event.event?.request?.cf?.colo ?? 'unknown',
|
|
223
|
+
],
|
|
224
|
+
})
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
ctx.waitUntil(Promise.all(writes));
|
|
228
|
+
}
|
|
229
|
+
};
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### 5. Filter Specific Routes/Patterns
|
|
233
|
+
|
|
234
|
+
```typescript
|
|
235
|
+
export default {
|
|
236
|
+
async tail(events, env, ctx) {
|
|
237
|
+
// Only process API routes
|
|
238
|
+
const apiEvents = events.filter(event =>
|
|
239
|
+
event.event?.request?.url?.includes('/api/')
|
|
240
|
+
);
|
|
241
|
+
|
|
242
|
+
if (apiEvents.length === 0) return;
|
|
243
|
+
|
|
244
|
+
ctx.waitUntil(
|
|
245
|
+
fetch(env.API_LOGS_ENDPOINT, {
|
|
246
|
+
method: "POST",
|
|
247
|
+
body: JSON.stringify(apiEvents),
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
};
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
### 6. Multi-Destination Logging
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
export default {
|
|
258
|
+
async tail(events, env, ctx) {
|
|
259
|
+
// Send errors to one place, everything else to another
|
|
260
|
+
const errors = events.filter(e => e.outcome === 'exception');
|
|
261
|
+
const success = events.filter(e => e.outcome === 'ok');
|
|
262
|
+
|
|
263
|
+
const tasks = [];
|
|
264
|
+
|
|
265
|
+
if (errors.length > 0) {
|
|
266
|
+
tasks.push(
|
|
267
|
+
fetch(env.ERROR_ENDPOINT, {
|
|
268
|
+
method: "POST",
|
|
269
|
+
body: JSON.stringify(errors),
|
|
270
|
+
})
|
|
271
|
+
);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
if (success.length > 0) {
|
|
275
|
+
tasks.push(
|
|
276
|
+
fetch(env.SUCCESS_ENDPOINT, {
|
|
277
|
+
method: "POST",
|
|
278
|
+
body: JSON.stringify(success),
|
|
279
|
+
})
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
ctx.waitUntil(Promise.all(tasks));
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
### 7. Performance Monitoring
|
|
289
|
+
|
|
290
|
+
```typescript
|
|
291
|
+
export default {
|
|
292
|
+
async tail(events, env, ctx) {
|
|
293
|
+
const metrics = events.map(event => ({
|
|
294
|
+
script: event.scriptName,
|
|
295
|
+
timestamp: event.eventTimestamp,
|
|
296
|
+
duration: calculateDuration(event), // Custom logic
|
|
297
|
+
outcome: event.outcome,
|
|
298
|
+
status: event.event?.response?.status,
|
|
299
|
+
colo: event.event?.request?.cf?.colo,
|
|
300
|
+
}));
|
|
301
|
+
|
|
302
|
+
ctx.waitUntil(
|
|
303
|
+
fetch(env.METRICS_ENDPOINT, {
|
|
304
|
+
method: "POST",
|
|
305
|
+
headers: { "X-API-Key": env.METRICS_API_KEY },
|
|
306
|
+
body: JSON.stringify(metrics),
|
|
307
|
+
})
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
};
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
## Security & Privacy
|
|
314
|
+
|
|
315
|
+
### Automatic Redaction
|
|
316
|
+
By default, sensitive data is redacted from `TailRequest`:
|
|
317
|
+
|
|
318
|
+
**Header redaction:**
|
|
319
|
+
- Headers containing: `auth`, `key`, `secret`, `token`, `jwt` (case-insensitive)
|
|
320
|
+
- `cookie` and `set-cookie` headers
|
|
321
|
+
- Redacted values show as `"REDACTED"`
|
|
322
|
+
|
|
323
|
+
**URL redaction:**
|
|
324
|
+
- Hex IDs: 32+ hex digits → `"REDACTED"`
|
|
325
|
+
- Base-64 IDs: 21+ chars with 2+ upper, 2+ lower, 2+ digits → `"REDACTED"`
|
|
326
|
+
|
|
327
|
+
### Bypassing Redaction
|
|
328
|
+
```typescript
|
|
329
|
+
// Use with extreme caution
|
|
330
|
+
const unredacted = event.event?.request?.getUnredacted();
|
|
331
|
+
// unredacted.url and unredacted.headers contain raw values
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
**Best practices:**
|
|
335
|
+
- Only call `getUnredacted()` when absolutely necessary
|
|
336
|
+
- Never log unredacted sensitive data
|
|
337
|
+
- Implement additional filtering before external transmission
|
|
338
|
+
- Use environment variables for API keys, never hardcode
|
|
339
|
+
|
|
340
|
+
## Wrangler CLI Usage
|
|
341
|
+
|
|
342
|
+
### Deploy Tail Worker
|
|
343
|
+
```bash
|
|
344
|
+
wrangler deploy
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
### View Live Tail Locally (NOT Tail Workers)
|
|
348
|
+
```bash
|
|
349
|
+
# This streams logs to terminal, different from Tail Workers
|
|
350
|
+
wrangler tail <producer-worker-name>
|
|
351
|
+
```
|
|
352
|
+
|
|
353
|
+
### Update Producer Configuration
|
|
354
|
+
```bash
|
|
355
|
+
# Edit wrangler.toml to add tail_consumers
|
|
356
|
+
wrangler deploy
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### Remove Tail Consumer
|
|
360
|
+
```toml
|
|
361
|
+
# Remove from wrangler.toml or set empty array
|
|
362
|
+
tail_consumers = []
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
## TypeScript Types
|
|
366
|
+
|
|
367
|
+
```typescript
|
|
368
|
+
// Add to your Tail Worker
|
|
369
|
+
export default {
|
|
370
|
+
async tail(
|
|
371
|
+
events: TailItem[],
|
|
372
|
+
env: Env,
|
|
373
|
+
ctx: ExecutionContext
|
|
374
|
+
): Promise<void> {
|
|
375
|
+
// Implementation
|
|
376
|
+
}
|
|
377
|
+
} satisfies ExportedHandler<Env>;
|
|
378
|
+
|
|
379
|
+
interface Env {
|
|
380
|
+
// Your bindings
|
|
381
|
+
LOGS_KV: KVNamespace;
|
|
382
|
+
ANALYTICS: AnalyticsEngineDataset;
|
|
383
|
+
LOG_ENDPOINT: string;
|
|
384
|
+
API_TOKEN: string;
|
|
385
|
+
}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
## Testing & Development
|
|
389
|
+
|
|
390
|
+
### Local Testing
|
|
391
|
+
Tail Workers cannot be fully tested locally with `wrangler dev`. Deploy to staging environment for testing.
|
|
392
|
+
|
|
393
|
+
### Testing Strategy
|
|
394
|
+
1. Deploy producer Worker to staging
|
|
395
|
+
2. Deploy Tail Worker to staging
|
|
396
|
+
3. Configure `tail_consumers` in producer
|
|
397
|
+
4. Trigger producer Worker requests
|
|
398
|
+
5. Verify Tail Worker receives events (check destination logs/storage)
|
|
399
|
+
|
|
400
|
+
### Debugging Tips
|
|
401
|
+
```typescript
|
|
402
|
+
export default {
|
|
403
|
+
async tail(events, env, ctx) {
|
|
404
|
+
// Log to console for debugging (won't be captured by self)
|
|
405
|
+
console.log('Received events:', events.length);
|
|
406
|
+
|
|
407
|
+
try {
|
|
408
|
+
// Your logic
|
|
409
|
+
await processEvents(events, env);
|
|
410
|
+
} catch (error) {
|
|
411
|
+
// Log errors
|
|
412
|
+
console.error('Tail Worker error:', error);
|
|
413
|
+
// Consider sending errors to monitoring service
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
};
|
|
417
|
+
```
|
|
418
|
+
|
|
419
|
+
## Advanced Patterns
|
|
420
|
+
|
|
421
|
+
### Batching Events
|
|
422
|
+
```typescript
|
|
423
|
+
// Use KV or Durable Objects to batch events before sending
|
|
424
|
+
export default {
|
|
425
|
+
async tail(events, env, ctx) {
|
|
426
|
+
const batch = await env.BATCH_DO.get(env.BATCH_DO.idFromName("batch"));
|
|
427
|
+
ctx.waitUntil(batch.addEvents(events));
|
|
428
|
+
}
|
|
429
|
+
};
|
|
430
|
+
```
|
|
431
|
+
|
|
432
|
+
### Sampling
|
|
433
|
+
```typescript
|
|
434
|
+
// Only process a percentage of events
|
|
435
|
+
export default {
|
|
436
|
+
async tail(events, env, ctx) {
|
|
437
|
+
const sampleRate = 0.1; // 10%
|
|
438
|
+
const sampledEvents = events.filter(() => Math.random() < sampleRate);
|
|
439
|
+
|
|
440
|
+
if (sampledEvents.length > 0) {
|
|
441
|
+
ctx.waitUntil(sendToEndpoint(sampledEvents, env));
|
|
442
|
+
}
|
|
443
|
+
}
|
|
444
|
+
};
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Workers for Platforms
|
|
448
|
+
For dynamic dispatch Workers, `events` array contains TWO elements:
|
|
449
|
+
1. Dynamic dispatch Worker event
|
|
450
|
+
2. User Worker event
|
|
451
|
+
|
|
452
|
+
```typescript
|
|
453
|
+
export default {
|
|
454
|
+
async tail(events, env, ctx) {
|
|
455
|
+
for (const event of events) {
|
|
456
|
+
// Distinguish between dispatch and user Worker
|
|
457
|
+
if (event.scriptName === 'dispatch-worker') {
|
|
458
|
+
// Handle dispatch Worker event
|
|
459
|
+
} else {
|
|
460
|
+
// Handle user Worker event
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
};
|
|
465
|
+
```
|
|
466
|
+
|
|
467
|
+
## Common Pitfalls
|
|
468
|
+
|
|
469
|
+
1. **Not using `ctx.waitUntil()`:**
|
|
470
|
+
```typescript
|
|
471
|
+
// ❌ WRONG - async work may not complete
|
|
472
|
+
export default {
|
|
473
|
+
async tail(events) {
|
|
474
|
+
fetch(endpoint, { body: JSON.stringify(events) });
|
|
475
|
+
}
|
|
476
|
+
};
|
|
477
|
+
|
|
478
|
+
// ✅ CORRECT
|
|
479
|
+
export default {
|
|
480
|
+
async tail(events, env, ctx) {
|
|
481
|
+
ctx.waitUntil(
|
|
482
|
+
fetch(endpoint, { body: JSON.stringify(events) })
|
|
483
|
+
);
|
|
484
|
+
}
|
|
485
|
+
};
|
|
486
|
+
```
|
|
487
|
+
|
|
488
|
+
2. **Missing tail() handler:**
|
|
489
|
+
Producer Worker deployment will fail if tail_consumers references a Worker without tail() handler.
|
|
490
|
+
|
|
491
|
+
3. **Outcome vs HTTP Status:**
|
|
492
|
+
`outcome` is script execution status, NOT HTTP status. A Worker can return 500 but have outcome='ok' if script completed successfully.
|
|
493
|
+
|
|
494
|
+
4. **Excessive logging:**
|
|
495
|
+
Tail Workers are invoked on EVERY producer invocation. Be mindful of volume and costs.
|
|
496
|
+
|
|
497
|
+
5. **Blocking operations:**
|
|
498
|
+
Don't await in tail handler unless necessary. Use `ctx.waitUntil()` for fire-and-forget operations.
|
|
499
|
+
|
|
500
|
+
## Integration Examples
|
|
501
|
+
|
|
502
|
+
### Sentry
|
|
503
|
+
```typescript
|
|
504
|
+
export default {
|
|
505
|
+
async tail(events, env, ctx) {
|
|
506
|
+
const errors = events.filter(e =>
|
|
507
|
+
e.outcome === 'exception' || e.exceptions.length > 0
|
|
508
|
+
);
|
|
509
|
+
|
|
510
|
+
for (const event of errors) {
|
|
511
|
+
ctx.waitUntil(
|
|
512
|
+
fetch(`https://sentry.io/api/${env.SENTRY_PROJECT}/store/`, {
|
|
513
|
+
method: "POST",
|
|
514
|
+
headers: {
|
|
515
|
+
"X-Sentry-Auth": `Sentry sentry_key=${env.SENTRY_KEY}`,
|
|
516
|
+
"Content-Type": "application/json",
|
|
517
|
+
},
|
|
518
|
+
body: JSON.stringify({
|
|
519
|
+
message: event.exceptions[0]?.message,
|
|
520
|
+
level: "error",
|
|
521
|
+
tags: { worker: event.scriptName },
|
|
522
|
+
extra: { event },
|
|
523
|
+
}),
|
|
524
|
+
})
|
|
525
|
+
);
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### Datadog
|
|
532
|
+
```typescript
|
|
533
|
+
export default {
|
|
534
|
+
async tail(events, env, ctx) {
|
|
535
|
+
const logs = events.flatMap(event =>
|
|
536
|
+
event.logs.map(log => ({
|
|
537
|
+
ddsource: "cloudflare-worker",
|
|
538
|
+
ddtags: `worker:${event.scriptName},outcome:${event.outcome}`,
|
|
539
|
+
hostname: event.event?.request?.cf?.colo,
|
|
540
|
+
message: log.message.join(" "),
|
|
541
|
+
status: log.level,
|
|
542
|
+
timestamp: log.timestamp,
|
|
543
|
+
}))
|
|
544
|
+
);
|
|
545
|
+
|
|
546
|
+
ctx.waitUntil(
|
|
547
|
+
fetch("https://http-intake.logs.datadoghq.com/v1/input", {
|
|
548
|
+
method: "POST",
|
|
549
|
+
headers: {
|
|
550
|
+
"DD-API-KEY": env.DATADOG_API_KEY,
|
|
551
|
+
"Content-Type": "application/json",
|
|
552
|
+
},
|
|
553
|
+
body: JSON.stringify(logs),
|
|
554
|
+
})
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
## Related Resources
|
|
561
|
+
- Tail Workers Docs: https://developers.cloudflare.com/workers/observability/logs/tail-workers/
|
|
562
|
+
- Tail Handler API: https://developers.cloudflare.com/workers/runtime-apis/handlers/tail/
|
|
563
|
+
- Analytics Engine: https://developers.cloudflare.com/analytics/analytics-engine/
|
|
564
|
+
- OpenTelemetry Export: https://developers.cloudflare.com/workers/observability/exporting-opentelemetry-data/
|
|
565
|
+
|
|
566
|
+
## Decision Tree
|
|
567
|
+
|
|
568
|
+
```
|
|
569
|
+
Need observability for Workers?
|
|
570
|
+
├─ Batch export to known tools (Sentry/Grafana/Honeycomb)?
|
|
571
|
+
│ └─ Use OpenTelemetry export (not Tail Workers)
|
|
572
|
+
├─ Custom real-time processing needed?
|
|
573
|
+
│ ├─ Aggregated metrics?
|
|
574
|
+
│ │ └─ Use Tail Worker + Analytics Engine
|
|
575
|
+
│ ├─ Error tracking?
|
|
576
|
+
│ │ └─ Use Tail Worker + external service
|
|
577
|
+
│ ├─ Custom logging/debugging?
|
|
578
|
+
│ │ └─ Use Tail Worker + KV/HTTP endpoint
|
|
579
|
+
│ └─ Complex event processing?
|
|
580
|
+
│ └─ Use Tail Worker + Durable Objects
|
|
581
|
+
└─ Quick debugging?
|
|
582
|
+
└─ Use `wrangler tail` (different from Tail Workers)
|
|
583
|
+
```
|
|
584
|
+
|
|
585
|
+
## Code Quality Guidelines
|
|
586
|
+
|
|
587
|
+
### Type Safety
|
|
588
|
+
```typescript
|
|
589
|
+
// ✅ Use proper types
|
|
590
|
+
interface Env {
|
|
591
|
+
LOG_ENDPOINT: string;
|
|
592
|
+
API_TOKEN: string;
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
export default {
|
|
596
|
+
async tail(
|
|
597
|
+
events: TailItem[],
|
|
598
|
+
env: Env,
|
|
599
|
+
ctx: ExecutionContext
|
|
600
|
+
): Promise<void> {
|
|
601
|
+
// Type-safe implementation
|
|
602
|
+
}
|
|
603
|
+
} satisfies ExportedHandler<Env>;
|
|
604
|
+
|
|
605
|
+
// ❌ Avoid any
|
|
606
|
+
export default {
|
|
607
|
+
async tail(events: any, env: any, ctx: any) {
|
|
608
|
+
// Unsafe
|
|
609
|
+
}
|
|
610
|
+
};
|
|
611
|
+
```
|
|
612
|
+
|
|
613
|
+
### Error Handling
|
|
614
|
+
```typescript
|
|
615
|
+
export default {
|
|
616
|
+
async tail(events, env, ctx) {
|
|
617
|
+
ctx.waitUntil(
|
|
618
|
+
(async () => {
|
|
619
|
+
try {
|
|
620
|
+
await fetch(env.ENDPOINT, {
|
|
621
|
+
method: "POST",
|
|
622
|
+
body: JSON.stringify(events),
|
|
623
|
+
});
|
|
624
|
+
} catch (error) {
|
|
625
|
+
// Log to console or send to fallback
|
|
626
|
+
console.error("Failed to send events:", error);
|
|
627
|
+
}
|
|
628
|
+
})()
|
|
629
|
+
);
|
|
630
|
+
}
|
|
631
|
+
};
|
|
632
|
+
```
|
|
633
|
+
|
|
634
|
+
### Minimal, Surgical Changes
|
|
635
|
+
- Process only necessary events (filter early)
|
|
636
|
+
- Avoid unnecessary data transformations
|
|
637
|
+
- Keep handlers focused and simple
|
|
638
|
+
|
|
639
|
+
## Summary
|
|
640
|
+
Tail Workers provide real-time, custom event processing for Cloudflare Workers. Use them when you need fine-grained control over logging, error tracking, or analytics that goes beyond standard OTEL export. Always use `ctx.waitUntil()` for async work, be mindful of sensitive data redaction, and consider Analytics Engine for aggregated metrics.
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Cloudflare Terraform Provider
|
|
2
|
+
|
|
3
|
+
**Expert guidance for Cloudflare Terraform Provider - infrastructure as code for Cloudflare resources.**
|
|
4
|
+
|
|
5
|
+
## Core Principles
|
|
6
|
+
|
|
7
|
+
- **Provider-first**: Use Terraform provider for ALL infrastructure - never mix with wrangler.toml for the same resources
|
|
8
|
+
- **State management**: Always use remote state (S3, Terraform Cloud, etc.) for team environments
|
|
9
|
+
- **Modular architecture**: Create reusable modules for common patterns (zones, workers, pages)
|
|
10
|
+
- **Version pinning**: Always pin provider version with `~>` for predictable upgrades
|
|
11
|
+
- **Secret management**: Use variables + environment vars for sensitive data - never hardcode API tokens
|
|
12
|
+
|
|
13
|
+
## Provider Setup
|
|
14
|
+
|
|
15
|
+
### Basic Configuration
|
|
16
|
+
|
|
17
|
+
```hcl
|
|
18
|
+
terraform {
|
|
19
|
+
required_version = ">= 1.0"
|
|
20
|
+
|
|
21
|
+
required_providers {
|
|
22
|
+
cloudflare = {
|
|
23
|
+
source = "cloudflare/cloudflare"
|
|
24
|
+
version = "~> 5.15.0"
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
provider "cloudflare" {
|
|
30
|
+
api_token = var.cloudflare_api_token # or CLOUDFLARE_API_TOKEN env var
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Authentication Methods (priority order)
|
|
35
|
+
|
|
36
|
+
1. **API Token** (RECOMMENDED): `api_token` or `CLOUDFLARE_API_TOKEN`
|
|
37
|
+
- Create: Dashboard → My Profile → API Tokens
|
|
38
|
+
- Scope to specific accounts/zones for security
|
|
39
|
+
|
|
40
|
+
2. **Global API Key** (LEGACY): `api_key` + `api_email` or `CLOUDFLARE_API_KEY` + `CLOUDFLARE_EMAIL`
|
|
41
|
+
- Less secure, use tokens instead
|
|
42
|
+
|
|
43
|
+
3. **User Service Key**: `user_service_key` for Origin CA certificates
|
|
44
|
+
|
|
45
|
+
### Backend Configuration
|
|
46
|
+
|
|
47
|
+
```hcl
|
|
48
|
+
terraform {
|
|
49
|
+
backend "s3" {
|
|
50
|
+
bucket = "terraform-state"
|
|
51
|
+
key = "cloudflare/terraform.tfstate"
|
|
52
|
+
region = "us-east-1"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Quick Reference: Common Commands
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
terraform init # Initialize provider
|
|
61
|
+
terraform plan # Plan changes
|
|
62
|
+
terraform apply # Apply changes
|
|
63
|
+
terraform destroy # Destroy resources
|
|
64
|
+
terraform import cloudflare_zone.example <zone-id> # Import existing
|
|
65
|
+
terraform state list # List resources in state
|
|
66
|
+
terraform output # Show outputs
|
|
67
|
+
terraform fmt -recursive # Format code
|
|
68
|
+
terraform validate # Validate configuration
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
## See Also
|
|
72
|
+
|
|
73
|
+
- [Configuration Reference](./configuration.md) - Resources for zones, DNS, workers, KV, R2, D1, Pages, rulesets
|
|
74
|
+
- [API Reference](./api.md) - Data sources for existing resources
|
|
75
|
+
- [Patterns & Use Cases](./patterns.md) - Architecture patterns, multi-env setup, CI/CD integration
|
|
76
|
+
- [Troubleshooting & Best Practices](./gotchas.md) - Common issues, security, best practices
|