memory-journal-mcp 7.7.1 → 8.0.1
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/README.md +126 -56
- package/dist/chunk-6OHRCNYW.js +3231 -0
- package/dist/chunk-JFMITANR.js +5168 -0
- package/dist/{chunk-ARLYSFSI.js → chunk-UHSO65A4.js} +4242 -6092
- package/dist/{chunk-6LPTBIB6.js → chunk-V3UTFQQK.js} +318 -4330
- package/dist/cli.js +21 -3
- package/dist/index.d.ts +16 -13
- package/dist/index.js +4 -2
- package/dist/resources-IJVKDFGS.js +2 -0
- package/dist/tools-44DGXE3V.js +2 -0
- package/dist/worker-script.js +201 -20
- package/package.json +6 -4
- package/skills/README.md +62 -25
- package/skills/adversarial-performance/SKILL.md +139 -0
- package/skills/adversarial-performance/references/audit-categories.md +462 -0
- package/skills/adversarial-performance/references/copilot-performance-prompts.md +44 -0
- package/skills/adversarial-performance/references/copilot-usage.md +16 -0
- package/skills/adversarial-performance/references/feedback-loop.md +177 -0
- package/skills/adversarial-performance/references/multi-pass-performance-protocol.md +398 -0
- package/skills/adversarial-planner/SKILL.md +23 -54
- package/skills/adversarial-planner/references/copilot-integration.md +25 -40
- package/skills/adversarial-planner/references/copilot-usage.md +16 -0
- package/skills/adversarial-planner/references/multi-pass-protocol.md +4 -0
- package/skills/adversarial-security/SKILL.md +149 -0
- package/skills/adversarial-security/references/adversarial-base-protocol.md +44 -0
- package/skills/adversarial-security/references/audit-categories.md +723 -0
- package/skills/adversarial-security/references/copilot-security-prompts.md +142 -0
- package/skills/adversarial-security/references/copilot-usage.md +16 -0
- package/skills/adversarial-security/references/feedback-loop.md +206 -0
- package/skills/adversarial-security/references/journal-opt-out.md +7 -0
- package/skills/adversarial-security/references/multi-pass-security-protocol.md +403 -0
- package/skills/adversarial-skill-audit/SKILL.md +118 -0
- package/skills/adversarial-skill-audit/references/audit-categories.md +308 -0
- package/skills/adversarial-skill-audit/references/copilot-skill-prompts.md +68 -0
- package/skills/adversarial-skill-audit/references/copilot-usage.md +16 -0
- package/skills/adversarial-skill-audit/references/feedback-loop.md +155 -0
- package/skills/adversarial-skill-audit/references/multi-pass-skill-protocol.md +367 -0
- package/skills/adversarial-skill-audit/scripts/check-skills.ps1 +48 -0
- package/skills/adversarial-skill-audit/scripts/run-copilot.ps1 +52 -0
- package/skills/adversarial-workflow-audit/SKILL.md +82 -0
- package/skills/adversarial-workflow-audit/references/audit-categories.md +28 -0
- package/skills/adversarial-workflow-audit/references/copilot-usage.md +16 -0
- package/skills/adversarial-workflow-audit/scripts/check-workflows.ps1 +24 -0
- package/skills/agents-sdk/SKILL.md +220 -0
- package/skills/agents-sdk/references/callable.md +92 -0
- package/skills/agents-sdk/references/codemode.md +209 -0
- package/skills/agents-sdk/references/email.md +144 -0
- package/skills/agents-sdk/references/mcp/SKILL.md +65 -0
- package/skills/agents-sdk/references/mcp/code-mode-reference.md +245 -0
- package/skills/agents-sdk/references/mcp/oauth-reference.md +359 -0
- package/skills/agents-sdk/references/mcp/references/architecture-reference.md +208 -0
- package/skills/agents-sdk/references/mcp/references/cloudflare-quickstart.md +156 -0
- package/skills/agents-sdk/references/mcp/references/error-handling.md +343 -0
- package/skills/agents-sdk/references/mcp/references/http-security.md +164 -0
- package/skills/agents-sdk/references/mcp/references/implementation-guide.md +507 -0
- package/skills/agents-sdk/references/mcp/references/testing-reference.md +171 -0
- package/skills/agents-sdk/references/mcp.md +157 -0
- package/skills/agents-sdk/references/state-scheduling.md +164 -0
- package/skills/agents-sdk/references/streaming-chat.md +168 -0
- package/skills/agents-sdk/references/workflows.md +136 -0
- package/skills/auth-identity/SKILL.md +48 -0
- package/skills/autonomous-dev/SKILL.md +46 -23
- package/skills/autonomous-dev/references/workflow_orchestration.md +22 -0
- package/skills/aws/SKILL.md +39 -0
- package/skills/azure/SKILL.md +38 -0
- package/skills/bin/sync.js +7 -1
- package/skills/biome/SKILL.md +59 -0
- package/skills/bun/SKILL.md +8 -2
- package/skills/cloudflare/SKILL.md +37 -0
- package/skills/cloudflare/references/agents-sdk/README.md +95 -0
- package/skills/cloudflare/references/agents-sdk/api.md +195 -0
- package/skills/cloudflare/references/agents-sdk/configuration.md +178 -0
- package/skills/cloudflare/references/agents-sdk/gotchas.md +173 -0
- package/skills/cloudflare/references/agents-sdk/patterns.md +215 -0
- package/skills/cloudflare/references/ai-gateway/README.md +176 -0
- package/skills/cloudflare/references/ai-gateway/configuration.md +117 -0
- package/skills/cloudflare/references/ai-gateway/dynamic-routing.md +88 -0
- package/skills/cloudflare/references/ai-gateway/features.md +96 -0
- package/skills/cloudflare/references/ai-gateway/sdk-integration.md +110 -0
- package/skills/cloudflare/references/ai-gateway/troubleshooting.md +90 -0
- package/skills/cloudflare/references/ai-search/README.md +145 -0
- package/skills/cloudflare/references/ai-search/api.md +87 -0
- package/skills/cloudflare/references/ai-search/configuration.md +91 -0
- package/skills/cloudflare/references/ai-search/gotchas.md +92 -0
- package/skills/cloudflare/references/ai-search/patterns.md +87 -0
- package/skills/cloudflare/references/analytics-engine/README.md +96 -0
- package/skills/cloudflare/references/analytics-engine/api.md +112 -0
- package/skills/cloudflare/references/analytics-engine/configuration.md +107 -0
- package/skills/cloudflare/references/analytics-engine/gotchas.md +87 -0
- package/skills/cloudflare/references/analytics-engine/patterns.md +83 -0
- package/skills/cloudflare/references/api/README.md +66 -0
- package/skills/cloudflare/references/api/api.md +205 -0
- package/skills/cloudflare/references/api/configuration.md +158 -0
- package/skills/cloudflare/references/api/gotchas.md +231 -0
- package/skills/cloudflare/references/api/patterns.md +208 -0
- package/skills/cloudflare/references/api-shield/README.md +44 -0
- package/skills/cloudflare/references/api-shield/api.md +153 -0
- package/skills/cloudflare/references/api-shield/configuration.md +210 -0
- package/skills/cloudflare/references/api-shield/gotchas.md +132 -0
- package/skills/cloudflare/references/api-shield/patterns.md +185 -0
- package/skills/cloudflare/references/argo-smart-routing/README.md +96 -0
- package/skills/cloudflare/references/argo-smart-routing/api.md +253 -0
- package/skills/cloudflare/references/argo-smart-routing/configuration.md +205 -0
- package/skills/cloudflare/references/argo-smart-routing/gotchas.md +115 -0
- package/skills/cloudflare/references/argo-smart-routing/patterns.md +107 -0
- package/skills/cloudflare/references/bindings/README.md +127 -0
- package/skills/cloudflare/references/bindings/api.md +214 -0
- package/skills/cloudflare/references/bindings/configuration.md +200 -0
- package/skills/cloudflare/references/bindings/gotchas.md +210 -0
- package/skills/cloudflare/references/bindings/patterns.md +205 -0
- package/skills/cloudflare/references/bot-management/README.md +95 -0
- package/skills/cloudflare/references/bot-management/api.md +175 -0
- package/skills/cloudflare/references/bot-management/configuration.md +175 -0
- package/skills/cloudflare/references/bot-management/gotchas.md +116 -0
- package/skills/cloudflare/references/bot-management/patterns.md +181 -0
- package/skills/cloudflare/references/browser-rendering/README.md +84 -0
- package/skills/cloudflare/references/browser-rendering/api.md +108 -0
- package/skills/cloudflare/references/browser-rendering/configuration.md +78 -0
- package/skills/cloudflare/references/browser-rendering/gotchas.md +91 -0
- package/skills/cloudflare/references/browser-rendering/patterns.md +93 -0
- package/skills/cloudflare/references/c3/README.md +111 -0
- package/skills/cloudflare/references/c3/api.md +71 -0
- package/skills/cloudflare/references/c3/configuration.md +85 -0
- package/skills/cloudflare/references/c3/gotchas.md +97 -0
- package/skills/cloudflare/references/c3/patterns.md +84 -0
- package/skills/cloudflare/references/cache-reserve/README.md +150 -0
- package/skills/cloudflare/references/cache-reserve/api.md +184 -0
- package/skills/cloudflare/references/cache-reserve/configuration.md +170 -0
- package/skills/cloudflare/references/cache-reserve/gotchas.md +136 -0
- package/skills/cloudflare/references/cache-reserve/patterns.md +197 -0
- package/skills/cloudflare/references/containers/README.md +87 -0
- package/skills/cloudflare/references/containers/api.md +197 -0
- package/skills/cloudflare/references/containers/configuration.md +191 -0
- package/skills/cloudflare/references/containers/gotchas.md +182 -0
- package/skills/cloudflare/references/containers/patterns.md +204 -0
- package/skills/cloudflare/references/cron-triggers/README.md +101 -0
- package/skills/cloudflare/references/cron-triggers/api.md +224 -0
- package/skills/cloudflare/references/cron-triggers/configuration.md +190 -0
- package/skills/cloudflare/references/cron-triggers/gotchas.md +207 -0
- package/skills/cloudflare/references/cron-triggers/patterns.md +274 -0
- package/skills/cloudflare/references/d1/README.md +137 -0
- package/skills/cloudflare/references/d1/api.md +213 -0
- package/skills/cloudflare/references/d1/configuration.md +198 -0
- package/skills/cloudflare/references/d1/gotchas.md +98 -0
- package/skills/cloudflare/references/d1/patterns.md +240 -0
- package/skills/cloudflare/references/ddos/README.md +42 -0
- package/skills/cloudflare/references/ddos/api.md +158 -0
- package/skills/cloudflare/references/ddos/configuration.md +94 -0
- package/skills/cloudflare/references/ddos/gotchas.md +114 -0
- package/skills/cloudflare/references/ddos/patterns.md +220 -0
- package/skills/cloudflare/references/decision-trees.md +95 -0
- package/skills/cloudflare/references/do-storage/README.md +79 -0
- package/skills/cloudflare/references/do-storage/api.md +107 -0
- package/skills/cloudflare/references/do-storage/configuration.md +114 -0
- package/skills/cloudflare/references/do-storage/gotchas.md +153 -0
- package/skills/cloudflare/references/do-storage/patterns.md +210 -0
- package/skills/cloudflare/references/do-storage/testing.md +186 -0
- package/skills/cloudflare/references/durable-objects/README.md +194 -0
- package/skills/cloudflare/references/durable-objects/api.md +205 -0
- package/skills/cloudflare/references/durable-objects/configuration.md +160 -0
- package/skills/cloudflare/references/durable-objects/gotchas.md +200 -0
- package/skills/cloudflare/references/durable-objects/patterns.md +205 -0
- package/skills/cloudflare/references/email-routing/README.md +89 -0
- package/skills/cloudflare/references/email-routing/api.md +192 -0
- package/skills/cloudflare/references/email-routing/configuration.md +187 -0
- package/skills/cloudflare/references/email-routing/gotchas.md +203 -0
- package/skills/cloudflare/references/email-routing/patterns.md +241 -0
- package/skills/cloudflare/references/email-workers/README.md +153 -0
- package/skills/cloudflare/references/email-workers/api.md +227 -0
- package/skills/cloudflare/references/email-workers/configuration.md +115 -0
- package/skills/cloudflare/references/email-workers/gotchas.md +133 -0
- package/skills/cloudflare/references/email-workers/patterns.md +108 -0
- package/skills/cloudflare/references/graphql-api/README.md +147 -0
- package/skills/cloudflare/references/graphql-api/api.md +175 -0
- package/skills/cloudflare/references/graphql-api/configuration.md +151 -0
- package/skills/cloudflare/references/graphql-api/gotchas.md +111 -0
- package/skills/cloudflare/references/graphql-api/patterns.md +276 -0
- package/skills/cloudflare/references/hyperdrive/README.md +84 -0
- package/skills/cloudflare/references/hyperdrive/api.md +149 -0
- package/skills/cloudflare/references/hyperdrive/configuration.md +166 -0
- package/skills/cloudflare/references/hyperdrive/gotchas.md +77 -0
- package/skills/cloudflare/references/hyperdrive/patterns.md +203 -0
- package/skills/cloudflare/references/images/README.md +65 -0
- package/skills/cloudflare/references/images/api.md +101 -0
- package/skills/cloudflare/references/images/configuration.md +206 -0
- package/skills/cloudflare/references/images/gotchas.md +106 -0
- package/skills/cloudflare/references/images/patterns.md +126 -0
- package/skills/cloudflare/references/kv/README.md +90 -0
- package/skills/cloudflare/references/kv/api.md +163 -0
- package/skills/cloudflare/references/kv/configuration.md +148 -0
- package/skills/cloudflare/references/kv/gotchas.md +133 -0
- package/skills/cloudflare/references/kv/patterns.md +195 -0
- package/skills/cloudflare/references/miniflare/README.md +113 -0
- package/skills/cloudflare/references/miniflare/api.md +204 -0
- package/skills/cloudflare/references/miniflare/configuration.md +174 -0
- package/skills/cloudflare/references/miniflare/gotchas.md +179 -0
- package/skills/cloudflare/references/miniflare/patterns.md +187 -0
- package/skills/cloudflare/references/network-interconnect/README.md +104 -0
- package/skills/cloudflare/references/network-interconnect/api.md +220 -0
- package/skills/cloudflare/references/network-interconnect/configuration.md +123 -0
- package/skills/cloudflare/references/network-interconnect/gotchas.md +175 -0
- package/skills/cloudflare/references/network-interconnect/patterns.md +174 -0
- package/skills/cloudflare/references/observability/README.md +93 -0
- package/skills/cloudflare/references/observability/api.md +168 -0
- package/skills/cloudflare/references/observability/configuration.md +178 -0
- package/skills/cloudflare/references/observability/gotchas.md +125 -0
- package/skills/cloudflare/references/observability/patterns.md +105 -0
- package/skills/cloudflare/references/pages/README.md +92 -0
- package/skills/cloudflare/references/pages/api.md +205 -0
- package/skills/cloudflare/references/pages/configuration.md +216 -0
- package/skills/cloudflare/references/pages/gotchas.md +218 -0
- package/skills/cloudflare/references/pages/patterns.md +215 -0
- package/skills/cloudflare/references/pages-functions/README.md +104 -0
- package/skills/cloudflare/references/pages-functions/api.md +159 -0
- package/skills/cloudflare/references/pages-functions/configuration.md +130 -0
- package/skills/cloudflare/references/pages-functions/gotchas.md +102 -0
- package/skills/cloudflare/references/pages-functions/patterns.md +148 -0
- package/skills/cloudflare/references/pipelines/README.md +109 -0
- package/skills/cloudflare/references/pipelines/api.md +214 -0
- package/skills/cloudflare/references/pipelines/configuration.md +98 -0
- package/skills/cloudflare/references/pipelines/gotchas.md +84 -0
- package/skills/cloudflare/references/pipelines/patterns.md +87 -0
- package/skills/cloudflare/references/product-index.md +112 -0
- package/skills/cloudflare/references/pulumi/README.md +113 -0
- package/skills/cloudflare/references/pulumi/api.md +230 -0
- package/skills/cloudflare/references/pulumi/configuration.md +213 -0
- package/skills/cloudflare/references/pulumi/gotchas.md +205 -0
- package/skills/cloudflare/references/pulumi/patterns.md +260 -0
- package/skills/cloudflare/references/queues/README.md +99 -0
- package/skills/cloudflare/references/queues/api.md +211 -0
- package/skills/cloudflare/references/queues/configuration.md +151 -0
- package/skills/cloudflare/references/queues/gotchas.md +210 -0
- package/skills/cloudflare/references/queues/patterns.md +220 -0
- package/skills/cloudflare/references/r2/README.md +97 -0
- package/skills/cloudflare/references/r2/api.md +235 -0
- package/skills/cloudflare/references/r2/configuration.md +176 -0
- package/skills/cloudflare/references/r2/gotchas.md +190 -0
- package/skills/cloudflare/references/r2/patterns.md +203 -0
- package/skills/cloudflare/references/r2-data-catalog/README.md +157 -0
- package/skills/cloudflare/references/r2-data-catalog/api.md +199 -0
- package/skills/cloudflare/references/r2-data-catalog/configuration.md +205 -0
- package/skills/cloudflare/references/r2-data-catalog/gotchas.md +170 -0
- package/skills/cloudflare/references/r2-data-catalog/patterns.md +191 -0
- package/skills/cloudflare/references/r2-sql/README.md +138 -0
- package/skills/cloudflare/references/r2-sql/SKILL.md.backup +512 -0
- package/skills/cloudflare/references/r2-sql/api.md +159 -0
- package/skills/cloudflare/references/r2-sql/configuration.md +152 -0
- package/skills/cloudflare/references/r2-sql/gotchas.md +228 -0
- package/skills/cloudflare/references/r2-sql/patterns.md +230 -0
- package/skills/cloudflare/references/realtime-sfu/README.md +66 -0
- package/skills/cloudflare/references/realtime-sfu/api.md +164 -0
- package/skills/cloudflare/references/realtime-sfu/configuration.md +141 -0
- package/skills/cloudflare/references/realtime-sfu/gotchas.md +138 -0
- package/skills/cloudflare/references/realtime-sfu/patterns.md +187 -0
- package/skills/cloudflare/references/realtimekit/README.md +118 -0
- package/skills/cloudflare/references/realtimekit/api.md +234 -0
- package/skills/cloudflare/references/realtimekit/configuration.md +226 -0
- package/skills/cloudflare/references/realtimekit/gotchas.md +206 -0
- package/skills/cloudflare/references/realtimekit/patterns.md +240 -0
- package/skills/cloudflare/references/sandbox/README.md +104 -0
- package/skills/cloudflare/references/sandbox/api.md +200 -0
- package/skills/cloudflare/references/sandbox/configuration.md +154 -0
- package/skills/cloudflare/references/sandbox/gotchas.md +201 -0
- package/skills/cloudflare/references/sandbox/patterns.md +195 -0
- package/skills/cloudflare/references/secrets-store/README.md +77 -0
- package/skills/cloudflare/references/secrets-store/api.md +199 -0
- package/skills/cloudflare/references/secrets-store/configuration.md +187 -0
- package/skills/cloudflare/references/secrets-store/gotchas.md +97 -0
- package/skills/cloudflare/references/secrets-store/patterns.md +218 -0
- package/skills/cloudflare/references/smart-placement/README.md +143 -0
- package/skills/cloudflare/references/smart-placement/api.md +192 -0
- package/skills/cloudflare/references/smart-placement/configuration.md +202 -0
- package/skills/cloudflare/references/smart-placement/gotchas.md +180 -0
- package/skills/cloudflare/references/smart-placement/patterns.md +190 -0
- package/skills/cloudflare/references/snippets/README.md +74 -0
- package/skills/cloudflare/references/snippets/api.md +214 -0
- package/skills/cloudflare/references/snippets/configuration.md +239 -0
- package/skills/cloudflare/references/snippets/gotchas.md +104 -0
- package/skills/cloudflare/references/snippets/patterns.md +135 -0
- package/skills/cloudflare/references/spectrum/README.md +52 -0
- package/skills/cloudflare/references/spectrum/api.md +184 -0
- package/skills/cloudflare/references/spectrum/configuration.md +203 -0
- package/skills/cloudflare/references/spectrum/gotchas.md +155 -0
- package/skills/cloudflare/references/spectrum/patterns.md +206 -0
- package/skills/cloudflare/references/static-assets/README.md +65 -0
- package/skills/cloudflare/references/static-assets/api.md +201 -0
- package/skills/cloudflare/references/static-assets/configuration.md +186 -0
- package/skills/cloudflare/references/static-assets/gotchas.md +164 -0
- package/skills/cloudflare/references/static-assets/patterns.md +189 -0
- package/skills/cloudflare/references/stream/README.md +123 -0
- package/skills/cloudflare/references/stream/api-live.md +202 -0
- package/skills/cloudflare/references/stream/api.md +206 -0
- package/skills/cloudflare/references/stream/configuration.md +151 -0
- package/skills/cloudflare/references/stream/gotchas.md +139 -0
- package/skills/cloudflare/references/stream/patterns.md +217 -0
- package/skills/cloudflare/references/tail-workers/README.md +92 -0
- package/skills/cloudflare/references/tail-workers/api.md +203 -0
- package/skills/cloudflare/references/tail-workers/configuration.md +178 -0
- package/skills/cloudflare/references/tail-workers/gotchas.md +206 -0
- package/skills/cloudflare/references/tail-workers/patterns.md +190 -0
- package/skills/cloudflare/references/terraform/README.md +100 -0
- package/skills/cloudflare/references/terraform/api.md +178 -0
- package/skills/cloudflare/references/terraform/configuration.md +197 -0
- package/skills/cloudflare/references/terraform/gotchas.md +150 -0
- package/skills/cloudflare/references/terraform/patterns.md +174 -0
- package/skills/cloudflare/references/tunnel/README.md +137 -0
- package/skills/cloudflare/references/tunnel/api.md +205 -0
- package/skills/cloudflare/references/tunnel/configuration.md +163 -0
- package/skills/cloudflare/references/tunnel/gotchas.md +159 -0
- package/skills/cloudflare/references/tunnel/networking.md +174 -0
- package/skills/cloudflare/references/tunnel/patterns.md +199 -0
- package/skills/cloudflare/references/turn/README.md +86 -0
- package/skills/cloudflare/references/turn/api.md +236 -0
- package/skills/cloudflare/references/turn/configuration.md +181 -0
- package/skills/cloudflare/references/turn/gotchas.md +236 -0
- package/skills/cloudflare/references/turn/patterns.md +228 -0
- package/skills/cloudflare/references/turnstile/README.md +102 -0
- package/skills/cloudflare/references/turnstile/api.md +253 -0
- package/skills/cloudflare/references/turnstile/configuration.md +242 -0
- package/skills/cloudflare/references/turnstile/gotchas.md +253 -0
- package/skills/cloudflare/references/turnstile/patterns.md +195 -0
- package/skills/cloudflare/references/vectorize/README.md +133 -0
- package/skills/cloudflare/references/vectorize/api.md +89 -0
- package/skills/cloudflare/references/vectorize/configuration.md +91 -0
- package/skills/cloudflare/references/vectorize/gotchas.md +83 -0
- package/skills/cloudflare/references/vectorize/patterns.md +92 -0
- package/skills/cloudflare/references/waf/README.md +125 -0
- package/skills/cloudflare/references/waf/api.md +203 -0
- package/skills/cloudflare/references/waf/configuration.md +215 -0
- package/skills/cloudflare/references/waf/gotchas.md +208 -0
- package/skills/cloudflare/references/waf/patterns.md +236 -0
- package/skills/cloudflare/references/web-analytics/README.md +149 -0
- package/skills/cloudflare/references/web-analytics/configuration.md +81 -0
- package/skills/cloudflare/references/web-analytics/gotchas.md +86 -0
- package/skills/cloudflare/references/web-analytics/integration.md +63 -0
- package/skills/cloudflare/references/web-analytics/patterns.md +98 -0
- package/skills/cloudflare/references/workerd/README.md +85 -0
- package/skills/cloudflare/references/workerd/api.md +219 -0
- package/skills/cloudflare/references/workerd/configuration.md +200 -0
- package/skills/cloudflare/references/workerd/gotchas.md +151 -0
- package/skills/cloudflare/references/workerd/patterns.md +205 -0
- package/skills/cloudflare/references/workers/README.md +110 -0
- package/skills/cloudflare/references/workers/api.md +197 -0
- package/skills/cloudflare/references/workers/configuration.md +184 -0
- package/skills/cloudflare/references/workers/frameworks.md +200 -0
- package/skills/cloudflare/references/workers/gotchas.md +145 -0
- package/skills/cloudflare/references/workers/patterns.md +220 -0
- package/skills/cloudflare/references/workers-ai/README.md +206 -0
- package/skills/cloudflare/references/workers-ai/api.md +115 -0
- package/skills/cloudflare/references/workers-ai/configuration.md +98 -0
- package/skills/cloudflare/references/workers-ai/gotchas.md +130 -0
- package/skills/cloudflare/references/workers-ai/patterns.md +122 -0
- package/skills/cloudflare/references/workers-for-platforms/README.md +95 -0
- package/skills/cloudflare/references/workers-for-platforms/api.md +212 -0
- package/skills/cloudflare/references/workers-for-platforms/configuration.md +178 -0
- package/skills/cloudflare/references/workers-for-platforms/gotchas.md +134 -0
- package/skills/cloudflare/references/workers-for-platforms/patterns.md +210 -0
- package/skills/cloudflare/references/workers-playground/README.md +131 -0
- package/skills/cloudflare/references/workers-playground/api.md +101 -0
- package/skills/cloudflare/references/workers-playground/configuration.md +169 -0
- package/skills/cloudflare/references/workers-playground/gotchas.md +88 -0
- package/skills/cloudflare/references/workers-playground/patterns.md +134 -0
- package/skills/cloudflare/references/workers-vpc/README.md +130 -0
- package/skills/cloudflare/references/workers-vpc/api.md +196 -0
- package/skills/cloudflare/references/workers-vpc/configuration.md +151 -0
- package/skills/cloudflare/references/workers-vpc/gotchas.md +171 -0
- package/skills/cloudflare/references/workers-vpc/patterns.md +235 -0
- package/skills/cloudflare/references/workflows/README.md +72 -0
- package/skills/cloudflare/references/workflows/api.md +237 -0
- package/skills/cloudflare/references/workflows/configuration.md +158 -0
- package/skills/cloudflare/references/workflows/gotchas.md +97 -0
- package/skills/cloudflare/references/workflows/patterns.md +245 -0
- package/skills/cloudflare/references/wrangler/README.md +143 -0
- package/skills/cloudflare/references/wrangler/api.md +188 -0
- package/skills/cloudflare/references/wrangler/configuration.md +198 -0
- package/skills/cloudflare/references/wrangler/gotchas.md +212 -0
- package/skills/cloudflare/references/wrangler/patterns.md +211 -0
- package/skills/cloudflare/references/zaraz/IMPLEMENTATION_SUMMARY.md +131 -0
- package/skills/cloudflare/references/zaraz/README.md +114 -0
- package/skills/cloudflare/references/zaraz/api.md +118 -0
- package/skills/cloudflare/references/zaraz/configuration.md +94 -0
- package/skills/cloudflare/references/zaraz/gotchas.md +88 -0
- package/skills/cloudflare/references/zaraz/patterns.md +77 -0
- package/skills/docker/SKILL.md +7 -101
- package/skills/docker/references/advanced-examples.md +71 -0
- package/skills/docker/references/templates.md +34 -0
- package/skills/docs-marketer/SKILL.md +178 -0
- package/skills/docs-marketer/references/audit-categories.md +328 -0
- package/skills/docs-marketer/references/copilot-docs-prompts.md +88 -0
- package/skills/docs-marketer/references/copilot-usage.md +16 -0
- package/skills/docs-marketer/references/feedback-loop.md +155 -0
- package/skills/docs-marketer/references/multi-pass-docs-protocol.md +410 -0
- package/skills/drizzle-orm/SKILL.md +82 -0
- package/skills/durable-objects/SKILL.md +167 -0
- package/skills/durable-objects/references/advanced_features.md +29 -0
- package/skills/durable-objects/references/rules.md +300 -0
- package/skills/durable-objects/references/testing.md +261 -0
- package/skills/durable-objects/references/workers.md +336 -0
- package/skills/gcp/SKILL.md +37 -0
- package/skills/github-actions/SKILL.md +5 -58
- package/skills/github-actions/references/templates.md +65 -0
- package/skills/github-commander/SKILL.md +13 -21
- package/skills/github-commander/workflows/copilot-audit.md +12 -12
- package/skills/github-copilot-cli/SKILL.md +21 -26
- package/skills/github-repo-setup/SKILL.md +136 -0
- package/skills/github-repo-setup/references/community-standards.md +136 -0
- package/skills/github-repo-setup/references/github-automation.md +490 -0
- package/skills/github-repo-setup/references/inline-templates.md +205 -0
- package/skills/github-repo-setup/references/project-config.md +320 -0
- package/skills/gitlab/SKILL.md +7 -2
- package/skills/gitlab/package-lock.json +389 -389
- package/skills/golang/SKILL.md +8 -1
- package/skills/graphql/SKILL.md +30 -0
- package/skills/hono/SKILL.md +82 -0
- package/skills/journal-optimizer/SKILL.md +206 -0
- package/skills/journal-optimizer/references/optimizer-scripts.md +169 -0
- package/skills/llm-app-engineering/SKILL.md +18 -0
- package/skills/monorepo/SKILL.md +56 -0
- package/skills/multi-agent-orchestration/SKILL.md +14 -0
- package/skills/mysql/SKILL.md +6 -2
- package/skills/next-best-practices/SKILL.md +86 -0
- package/skills/next-best-practices/references/cache-components-examples.md +234 -0
- package/skills/next-best-practices/references/cache-components.md +210 -0
- package/skills/next-best-practices/references/upgrade-decision-tree.md +33 -0
- package/skills/next-best-practices/references/upgrade.md +43 -0
- package/skills/next-cache-components/SKILL.md +441 -0
- package/skills/next-upgrade/SKILL.md +43 -0
- package/skills/next-upgrade/references/decision-tree.md +33 -0
- package/skills/nodejs/SKILL.md +46 -0
- package/skills/opentelemetry/SKILL.md +62 -0
- package/skills/package.json +39 -4
- package/skills/playwright-standard/SKILL.md +6 -11
- package/skills/playwright-standard/references/locators.md +7 -0
- package/skills/postgres/SKILL.md +6 -1
- package/skills/python/SKILL.md +8 -70
- package/skills/python/references/advanced-patterns.md +37 -0
- package/skills/python/references/config-templates.md +48 -0
- package/skills/rag-pipelines/SKILL.md +14 -0
- package/skills/redis/SKILL.md +31 -0
- package/skills/render/SKILL.md +35 -0
- package/skills/rust/SKILL.md +15 -25
- package/skills/rust/references/borrow-checker.md +13 -0
- package/skills/rust/references/ecosystem.md +11 -0
- package/skills/sandbox-sdk/SKILL.md +186 -0
- package/skills/sandbox-sdk/references/api-quick-ref.md +113 -0
- package/skills/sandbox-sdk/references/examples.md +52 -0
- package/skills/shadcn-ui/SKILL.md +22 -57
- package/skills/skill-builder/SKILL.md +23 -424
- package/skills/skill-builder/references/tutorial.md +457 -0
- package/skills/sqlite/SKILL.md +16 -5
- package/skills/table.md +59 -0
- package/skills/tailwind-css/SKILL.md +11 -60
- package/skills/tailwind-css/references/component-patterns.md +52 -0
- package/skills/trpc/SKILL.md +56 -0
- package/skills/typescript/SKILL.md +30 -433
- package/skills/typescript/references/tutorial.md +453 -0
- package/skills/vercel-ai-sdk/SKILL.md +48 -0
- package/skills/vitest-standard/SKILL.md +5 -11
- package/skills/vitest-standard/references/assertions.md +11 -0
- package/skills/web-perf/SKILL.md +207 -0
- package/skills/workers-best-practices/SKILL.md +120 -0
- package/skills/workers-best-practices/references/anti-patterns.md +18 -0
- package/skills/workers-best-practices/references/review.md +174 -0
- package/skills/workers-best-practices/references/rules.md +485 -0
- package/skills/wrangler/SKILL.md +43 -0
- package/skills/wrangler/references/cli-commands.md +861 -0
- package/skills/zod/SKILL.md +48 -0
- package/dist/tools-P4VGG4FH.js +0 -1
- package/skills/react-best-practices/AGENTS.md +0 -2883
- package/skills/react-best-practices/SKILL.md +0 -138
- /package/skills/{react-best-practices → next-best-practices}/README.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/metadata.json +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/_sections.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/_template.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-event-handler-refs.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-init-once.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/advanced-use-latest.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-api-routes.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-defer-await.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-dependencies.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-parallel.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/async-suspense-boundaries.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-barrel-imports.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-conditional.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-defer-third-party.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-dynamic-imports.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/bundle-preload.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-event-listeners.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-localstorage-schema.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-passive-event-listeners.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/client-swr-dedup.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-batch-dom-css.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-function-results.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-property-access.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-cache-storage.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-combine-iterations.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-early-exit.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-hoist-regexp.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-index-maps.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-length-check-first.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-min-max-loop.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-set-map-lookups.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/js-tosorted-immutable.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-activity.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-animate-svg-wrapper.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-conditional-render.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-content-visibility.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hoist-jsx.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hydration-no-flicker.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-hydration-suppress-warning.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-svg-precision.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rendering-usetransition-loading.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-defer-reads.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-dependencies.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-derived-state-no-effect.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-derived-state.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-functional-setstate.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-lazy-state-init.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-memo-with-default-value.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-memo.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-move-effect-to-event.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-simple-expression-in-memo.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-transitions.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/rerender-use-ref-transient-values.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-after-nonblocking.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-auth-actions.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-cache-lru.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-cache-react.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-dedup-props.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-parallel-fetching.md +0 -0
- /package/skills/{react-best-practices → next-best-practices}/rules/server-serialization.md +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
# Gotchas and Troubleshooting
|
|
2
|
+
|
|
3
|
+
Common pitfalls, limitations, and solutions for TCP Sockets in Cloudflare Workers.
|
|
4
|
+
|
|
5
|
+
## Platform Limits
|
|
6
|
+
|
|
7
|
+
### Connection Limits
|
|
8
|
+
|
|
9
|
+
| Limit | Value |
|
|
10
|
+
| ---------------------------------- | ------------------------------ |
|
|
11
|
+
| Max concurrent sockets per request | 6 (hard limit) |
|
|
12
|
+
| Socket lifetime | Request duration |
|
|
13
|
+
| Connection timeout | Platform-dependent, no setting |
|
|
14
|
+
|
|
15
|
+
**Problem:** Exceeding 6 connections throws error
|
|
16
|
+
|
|
17
|
+
**Solution:** Process in batches of 6
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
for (let i = 0; i < hosts.length; i += 6) {
|
|
21
|
+
const batch = hosts.slice(i, i + 6).map((h) => connect({ hostname: h, port: 443 }))
|
|
22
|
+
await Promise.all(
|
|
23
|
+
batch.map(async (s) => {
|
|
24
|
+
/* use */ await s.close()
|
|
25
|
+
})
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Blocked Destinations
|
|
31
|
+
|
|
32
|
+
Cloudflare IPs (1.1.1.1), localhost (127.0.0.1), port 25 (SMTP), Worker's own URL blocked for security.
|
|
33
|
+
|
|
34
|
+
**Solution:** Use public IPs or Tunnel hostnames: `connect({ hostname: "db.internal.company.net", port: 5432 })`
|
|
35
|
+
|
|
36
|
+
### Scope Requirements
|
|
37
|
+
|
|
38
|
+
**Problem:** Sockets created in global scope fail
|
|
39
|
+
|
|
40
|
+
**Cause:** Sockets tied to request lifecycle
|
|
41
|
+
|
|
42
|
+
**Solution:** Create inside handler: `export default { async fetch() { const socket = connect(...); } }`
|
|
43
|
+
|
|
44
|
+
## Common Errors
|
|
45
|
+
|
|
46
|
+
### Error: "proxy request failed"
|
|
47
|
+
|
|
48
|
+
**Causes:** Blocked destination (Cloudflare IP, localhost, port 25), DNS failure, network unreachable
|
|
49
|
+
|
|
50
|
+
**Solution:** Validate destinations, use Tunnel hostnames, catch errors with try/catch
|
|
51
|
+
|
|
52
|
+
### Error: "TCP Loop detected"
|
|
53
|
+
|
|
54
|
+
**Cause:** Worker connecting to itself
|
|
55
|
+
|
|
56
|
+
**Solution:** Connect to external service, not Worker's own hostname
|
|
57
|
+
|
|
58
|
+
### Error: "Port 25 prohibited"
|
|
59
|
+
|
|
60
|
+
**Cause:** SMTP port blocked
|
|
61
|
+
|
|
62
|
+
**Solution:** Use Email Workers API for email
|
|
63
|
+
|
|
64
|
+
### Error: "socket is not open"
|
|
65
|
+
|
|
66
|
+
**Cause:** Read/write after close
|
|
67
|
+
|
|
68
|
+
**Solution:** Always use try/finally to ensure proper closure order
|
|
69
|
+
|
|
70
|
+
### Error: Connection timeout
|
|
71
|
+
|
|
72
|
+
**Cause:** No built-in timeout
|
|
73
|
+
|
|
74
|
+
**Solution:** Use `Promise.race()`:
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
const socket = connect(addr, opts)
|
|
78
|
+
const timeout = new Promise((_, reject) => setTimeout(() => reject(new Error('Timeout')), 5000))
|
|
79
|
+
await Promise.race([socket.opened, timeout])
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## TLS/SSL Issues
|
|
83
|
+
|
|
84
|
+
### StartTLS Timing
|
|
85
|
+
|
|
86
|
+
**Problem:** Calling `startTls()` too early
|
|
87
|
+
|
|
88
|
+
**Solution:** Send protocol-specific STARTTLS command, wait for server OK, then call `socket.startTls()`
|
|
89
|
+
|
|
90
|
+
### Certificate Validation
|
|
91
|
+
|
|
92
|
+
**Problem:** Self-signed certs fail
|
|
93
|
+
|
|
94
|
+
**Solution:** Use proper certs or Tunnel (handles TLS termination)
|
|
95
|
+
|
|
96
|
+
## Performance Issues
|
|
97
|
+
|
|
98
|
+
### Not Using Connection Pooling
|
|
99
|
+
|
|
100
|
+
**Problem:** New connection overhead per request
|
|
101
|
+
|
|
102
|
+
**Solution:** Use [Hyperdrive](../hyperdrive/) for databases (built-in pooling)
|
|
103
|
+
|
|
104
|
+
### Not Using Smart Placement
|
|
105
|
+
|
|
106
|
+
**Problem:** High latency to backend
|
|
107
|
+
|
|
108
|
+
**Solution:** Enable: `{ "placement": { "mode": "smart" } }` in wrangler.jsonc
|
|
109
|
+
|
|
110
|
+
### Forgetting to Close Sockets
|
|
111
|
+
|
|
112
|
+
**Problem:** Resource leaks
|
|
113
|
+
|
|
114
|
+
**Solution:** Always use try/finally:
|
|
115
|
+
|
|
116
|
+
```typescript
|
|
117
|
+
const socket = connect({ hostname: 'api.internal', port: 443 })
|
|
118
|
+
try {
|
|
119
|
+
// Use socket
|
|
120
|
+
} finally {
|
|
121
|
+
await socket.close()
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Data Handling Issues
|
|
126
|
+
|
|
127
|
+
### Assuming Single Read Gets All Data
|
|
128
|
+
|
|
129
|
+
**Problem:** Only reading once may miss chunked data
|
|
130
|
+
|
|
131
|
+
**Solution:** Loop `reader.read()` until `done === true` (see patterns.md)
|
|
132
|
+
|
|
133
|
+
### Text Encoding Issues
|
|
134
|
+
|
|
135
|
+
**Problem:** Using wrong encoding
|
|
136
|
+
|
|
137
|
+
**Solution:** Specify encoding: `new TextDecoder('iso-8859-1').decode(data)`
|
|
138
|
+
|
|
139
|
+
## Security Issues
|
|
140
|
+
|
|
141
|
+
### SSRF Vulnerability
|
|
142
|
+
|
|
143
|
+
**Problem:** User-controlled destinations allow access to internal services
|
|
144
|
+
|
|
145
|
+
**Solution:** Validate against strict allowlist:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
const ALLOWED = ['api1.internal.net', 'api2.internal.net']
|
|
149
|
+
const host = new URL(req.url).searchParams.get('host')
|
|
150
|
+
if (!host || !ALLOWED.includes(host)) return new Response('Forbidden', { status: 403 })
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
## When to Use Alternatives
|
|
154
|
+
|
|
155
|
+
| Use Case | Alternative | Reason |
|
|
156
|
+
| ------------------------- | ---------------------------- | --------------------------- |
|
|
157
|
+
| PostgreSQL/MySQL | [Hyperdrive](../hyperdrive/) | Connection pooling, caching |
|
|
158
|
+
| HTTP/HTTPS | `fetch()` | Simpler, built-in |
|
|
159
|
+
| HTTP with SSRF protection | VPC Services (beta 2025+) | Declarative bindings |
|
|
160
|
+
|
|
161
|
+
## Debugging Tips
|
|
162
|
+
|
|
163
|
+
1. **Log connection details:** `const info = await socket.opened; console.log(info.remoteAddress);`
|
|
164
|
+
2. **Test with public services first:** Use tcpbin.com:4242 echo server
|
|
165
|
+
3. **Verify Tunnel:** `cloudflared tunnel info <name>` and `cloudflared tunnel route ip list`
|
|
166
|
+
|
|
167
|
+
## Related
|
|
168
|
+
|
|
169
|
+
- [Hyperdrive](../hyperdrive/) - Database connections
|
|
170
|
+
- [Smart Placement](../smart-placement/) - Latency optimization
|
|
171
|
+
- [Tunnel Troubleshooting](../tunnel/gotchas.md)
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
# Common Patterns
|
|
2
|
+
|
|
3
|
+
Real-world patterns and examples for TCP Sockets in Cloudflare Workers.
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
import { connect } from 'cloudflare:sockets'
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
## Basic Patterns
|
|
10
|
+
|
|
11
|
+
### Simple Request-Response
|
|
12
|
+
|
|
13
|
+
```typescript
|
|
14
|
+
const socket = connect({ hostname: 'echo.example.com', port: 7 }, { secureTransport: 'on' })
|
|
15
|
+
try {
|
|
16
|
+
await socket.opened
|
|
17
|
+
const writer = socket.writable.getWriter()
|
|
18
|
+
await writer.write(new TextEncoder().encode('Hello\n'))
|
|
19
|
+
await writer.close()
|
|
20
|
+
|
|
21
|
+
const reader = socket.readable.getReader()
|
|
22
|
+
const { value } = await reader.read()
|
|
23
|
+
return new Response(value)
|
|
24
|
+
} finally {
|
|
25
|
+
await socket.close()
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Reading All Data
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
async function readAll(socket: Socket): Promise<Uint8Array> {
|
|
33
|
+
const reader = socket.readable.getReader()
|
|
34
|
+
const chunks: Uint8Array[] = []
|
|
35
|
+
while (true) {
|
|
36
|
+
const { done, value } = await reader.read()
|
|
37
|
+
if (done) break
|
|
38
|
+
chunks.push(value)
|
|
39
|
+
}
|
|
40
|
+
const total = chunks.reduce((sum, c) => sum + c.length, 0)
|
|
41
|
+
const result = new Uint8Array(total)
|
|
42
|
+
let offset = 0
|
|
43
|
+
for (const chunk of chunks) {
|
|
44
|
+
result.set(chunk, offset)
|
|
45
|
+
offset += chunk.length
|
|
46
|
+
}
|
|
47
|
+
return result
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### Streaming Response
|
|
52
|
+
|
|
53
|
+
```typescript
|
|
54
|
+
// Stream socket data directly to HTTP response
|
|
55
|
+
const socket = connect({ hostname: 'stream.internal', port: 9000 }, { secureTransport: 'on' })
|
|
56
|
+
const writer = socket.writable.getWriter()
|
|
57
|
+
await writer.write(new TextEncoder().encode('STREAM\n'))
|
|
58
|
+
await writer.close()
|
|
59
|
+
return new Response(socket.readable)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Protocol Examples
|
|
63
|
+
|
|
64
|
+
### Redis RESP
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// Send: *2\r\n$3\r\nGET\r\n$<keylen>\r\n<key>\r\n
|
|
68
|
+
// Recv: $<len>\r\n<data>\r\n or $-1\r\n for null
|
|
69
|
+
const socket = connect({ hostname: 'redis.internal', port: 6379 })
|
|
70
|
+
const writer = socket.writable.getWriter()
|
|
71
|
+
await writer.write(new TextEncoder().encode(`*2\r\n$3\r\nGET\r\n$3\r\nkey\r\n`))
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### PostgreSQL
|
|
75
|
+
|
|
76
|
+
**Use [Hyperdrive](../hyperdrive/) for production.** Raw Postgres protocol is complex (startup, auth, query messages).
|
|
77
|
+
|
|
78
|
+
### MQTT
|
|
79
|
+
|
|
80
|
+
```typescript
|
|
81
|
+
const socket = connect({ hostname: 'mqtt.broker', port: 1883 })
|
|
82
|
+
const writer = socket.writable.getWriter()
|
|
83
|
+
// CONNECT: 0x10 <len> 0x00 0x04 "MQTT" 0x04 <flags> ...
|
|
84
|
+
// PUBLISH: 0x30 <len> <topic_len> <topic> <message>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Error Handling Patterns
|
|
88
|
+
|
|
89
|
+
### Retry with Backoff
|
|
90
|
+
|
|
91
|
+
```typescript
|
|
92
|
+
async function connectWithRetry(
|
|
93
|
+
addr: SocketAddress,
|
|
94
|
+
opts: SocketOptions,
|
|
95
|
+
maxRetries = 3
|
|
96
|
+
): Promise<Socket> {
|
|
97
|
+
for (let i = 1; i <= maxRetries; i++) {
|
|
98
|
+
try {
|
|
99
|
+
const socket = connect(addr, opts)
|
|
100
|
+
await socket.opened
|
|
101
|
+
return socket
|
|
102
|
+
} catch (error) {
|
|
103
|
+
if (i === maxRetries) throw error
|
|
104
|
+
await new Promise((r) => setTimeout(r, 1000 * Math.pow(2, i - 1))) // Exponential backoff
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
throw new Error('Unreachable')
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Timeout
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
async function connectWithTimeout(
|
|
115
|
+
addr: SocketAddress,
|
|
116
|
+
opts: SocketOptions,
|
|
117
|
+
ms = 5000
|
|
118
|
+
): Promise<Socket> {
|
|
119
|
+
const socket = connect(addr, opts)
|
|
120
|
+
const timeout = new Promise<never>((_, reject) =>
|
|
121
|
+
setTimeout(() => reject(new Error('Timeout')), ms)
|
|
122
|
+
)
|
|
123
|
+
await Promise.race([socket.opened, timeout])
|
|
124
|
+
return socket
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Fallback
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
async function connectWithFallback(
|
|
132
|
+
primary: string,
|
|
133
|
+
fallback: string,
|
|
134
|
+
port: number
|
|
135
|
+
): Promise<Socket> {
|
|
136
|
+
try {
|
|
137
|
+
const socket = connect({ hostname: primary, port }, { secureTransport: 'on' })
|
|
138
|
+
await socket.opened
|
|
139
|
+
return socket
|
|
140
|
+
} catch {
|
|
141
|
+
return connect({ hostname: fallback, port }, { secureTransport: 'on' })
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## Security Patterns
|
|
147
|
+
|
|
148
|
+
### Destination Allowlist (Prevent SSRF)
|
|
149
|
+
|
|
150
|
+
```typescript
|
|
151
|
+
const ALLOWED_HOSTS = ['db.internal.company.net', 'api.internal.company.net', /^10\.0\.1\.\d+$/]
|
|
152
|
+
|
|
153
|
+
function isAllowed(hostname: string): boolean {
|
|
154
|
+
return ALLOWED_HOSTS.some((p) => (p instanceof RegExp ? p.test(hostname) : p === hostname))
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export default {
|
|
158
|
+
async fetch(req: Request): Promise<Response> {
|
|
159
|
+
const target = new URL(req.url).searchParams.get('host')
|
|
160
|
+
if (!target || !isAllowed(target)) return new Response('Forbidden', { status: 403 })
|
|
161
|
+
const socket = connect({ hostname: target, port: 443 })
|
|
162
|
+
// Use socket...
|
|
163
|
+
},
|
|
164
|
+
}
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Connection Pooling
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
class SocketPool {
|
|
171
|
+
private pool = new Map<string, Socket[]>()
|
|
172
|
+
|
|
173
|
+
async acquire(hostname: string, port: number): Promise<Socket> {
|
|
174
|
+
const key = `${hostname}:${port}`
|
|
175
|
+
const sockets = this.pool.get(key) || []
|
|
176
|
+
if (sockets.length > 0) return sockets.pop()!
|
|
177
|
+
const socket = connect({ hostname, port }, { secureTransport: 'on' })
|
|
178
|
+
await socket.opened
|
|
179
|
+
return socket
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
release(hostname: string, port: number, socket: Socket): void {
|
|
183
|
+
const key = `${hostname}:${port}`
|
|
184
|
+
const sockets = this.pool.get(key) || []
|
|
185
|
+
if (sockets.length < 3) {
|
|
186
|
+
sockets.push(socket)
|
|
187
|
+
this.pool.set(key, sockets)
|
|
188
|
+
} else socket.close()
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Multi-Protocol Gateway
|
|
194
|
+
|
|
195
|
+
```typescript
|
|
196
|
+
interface Protocol {
|
|
197
|
+
name: string
|
|
198
|
+
defaultPort: number
|
|
199
|
+
test(host: string, port: number): Promise<string>
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
const PROTOCOLS: Record<string, Protocol> = {
|
|
203
|
+
redis: {
|
|
204
|
+
name: 'redis',
|
|
205
|
+
defaultPort: 6379,
|
|
206
|
+
async test(host, port) {
|
|
207
|
+
const socket = connect({ hostname: host, port })
|
|
208
|
+
try {
|
|
209
|
+
const writer = socket.writable.getWriter()
|
|
210
|
+
await writer.write(new TextEncoder().encode('*1\r\n$4\r\nPING\r\n'))
|
|
211
|
+
writer.releaseLock()
|
|
212
|
+
const reader = socket.readable.getReader()
|
|
213
|
+
const { value } = await reader.read()
|
|
214
|
+
return new TextDecoder().decode(value || new Uint8Array())
|
|
215
|
+
} finally {
|
|
216
|
+
await socket.close()
|
|
217
|
+
}
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
export default {
|
|
223
|
+
async fetch(req: Request): Promise<Response> {
|
|
224
|
+
const url = new URL(req.url)
|
|
225
|
+
const proto = url.pathname.slice(1) // /redis
|
|
226
|
+
const host = url.searchParams.get('host')
|
|
227
|
+
if (!host || !PROTOCOLS[proto]) return new Response('Invalid', { status: 400 })
|
|
228
|
+
const result = await PROTOCOLS[proto].test(
|
|
229
|
+
host,
|
|
230
|
+
parseInt(url.searchParams.get('port') || '') || PROTOCOLS[proto].defaultPort
|
|
231
|
+
)
|
|
232
|
+
return new Response(result)
|
|
233
|
+
},
|
|
234
|
+
}
|
|
235
|
+
```
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Cloudflare Workflows
|
|
2
|
+
|
|
3
|
+
Durable multi-step applications with automatic retries, state persistence, and long-running execution.
|
|
4
|
+
|
|
5
|
+
## What It Does
|
|
6
|
+
|
|
7
|
+
- Chain steps with automatic retry logic
|
|
8
|
+
- Persist state between steps (minutes → weeks)
|
|
9
|
+
- Handle failures without losing progress
|
|
10
|
+
- Wait for external events/approvals
|
|
11
|
+
- Sleep without consuming resources
|
|
12
|
+
|
|
13
|
+
**Available:** Free & Paid Workers plans
|
|
14
|
+
|
|
15
|
+
## Core Concepts
|
|
16
|
+
|
|
17
|
+
**Workflow**: Class extending `WorkflowEntrypoint` with `run` method
|
|
18
|
+
**Instance**: Single execution with unique ID & independent state
|
|
19
|
+
**Steps**: Independently retriable units via `step.do()` - API calls, DB queries, AI invocations
|
|
20
|
+
**State**: Persisted from step returns; step name = cache key
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
import { WorkflowEntrypoint, WorkflowStep, WorkflowEvent } from 'cloudflare:workers'
|
|
26
|
+
|
|
27
|
+
type Env = { MY_WORKFLOW: Workflow; DB: D1Database }
|
|
28
|
+
type Params = { userId: string }
|
|
29
|
+
|
|
30
|
+
export class MyWorkflow extends WorkflowEntrypoint<Env, Params> {
|
|
31
|
+
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
|
|
32
|
+
const user = await step.do('fetch user', async () => {
|
|
33
|
+
return await this.env.DB.prepare('SELECT * FROM users WHERE id = ?')
|
|
34
|
+
.bind(event.payload.userId)
|
|
35
|
+
.first()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
await step.sleep('wait 7 days', '7 days')
|
|
39
|
+
|
|
40
|
+
await step.do('send reminder', async () => {
|
|
41
|
+
await sendEmail(user.email, 'Reminder!')
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Key Features
|
|
48
|
+
|
|
49
|
+
- **Durability**: Failed steps don't re-run successful ones
|
|
50
|
+
- **Retries**: Configurable backoff (constant/linear/exponential)
|
|
51
|
+
- **Events**: `waitForEvent()` for webhooks/approvals (timeout: 1h → 365d)
|
|
52
|
+
- **Sleep**: `sleep()` / `sleepUntil()` for scheduling (max 365d)
|
|
53
|
+
- **Parallel**: `Promise.all()` for concurrent steps
|
|
54
|
+
- **Idempotency**: Check-then-execute patterns
|
|
55
|
+
|
|
56
|
+
## Reading Order
|
|
57
|
+
|
|
58
|
+
**Getting Started:** configuration.md → api.md → patterns.md
|
|
59
|
+
**Troubleshooting:** gotchas.md
|
|
60
|
+
|
|
61
|
+
## In This Reference
|
|
62
|
+
|
|
63
|
+
- [configuration.md](./configuration.md) - wrangler.jsonc setup, step config, bindings
|
|
64
|
+
- [api.md](./api.md) - Step APIs, instance management, sleep/parameters
|
|
65
|
+
- [patterns.md](./patterns.md) - Common workflows, testing, orchestration
|
|
66
|
+
- [gotchas.md](./gotchas.md) - Timeouts, limits, debugging strategies
|
|
67
|
+
|
|
68
|
+
## See Also
|
|
69
|
+
|
|
70
|
+
- [durable-objects](../durable-objects/) - Alternative stateful approach
|
|
71
|
+
- [queues](../queues/) - Message-driven workflows
|
|
72
|
+
- [workers](../workers/) - Entry point for workflow instances
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
# Workflow APIs
|
|
2
|
+
|
|
3
|
+
## Step APIs
|
|
4
|
+
|
|
5
|
+
```typescript
|
|
6
|
+
// step.do()
|
|
7
|
+
const result = await step.do('step name', async () => {
|
|
8
|
+
/* logic */
|
|
9
|
+
})
|
|
10
|
+
const result = await step.do('step name', { retries, timeout }, async () => {})
|
|
11
|
+
|
|
12
|
+
// step.sleep()
|
|
13
|
+
await step.sleep('description', '1 hour')
|
|
14
|
+
await step.sleep('description', 5000) // ms
|
|
15
|
+
|
|
16
|
+
// step.sleepUntil()
|
|
17
|
+
await step.sleepUntil('description', Date.parse('2024-12-31'))
|
|
18
|
+
|
|
19
|
+
// step.waitForEvent()
|
|
20
|
+
const data = await step.waitForEvent<PayloadType>('wait', { event: 'webhook-type', timeout: '24h' }) // Default 24h, max 365d
|
|
21
|
+
try {
|
|
22
|
+
const event = await step.waitForEvent('wait', { event: 'approval', timeout: '1h' })
|
|
23
|
+
} catch (e) {
|
|
24
|
+
/* Timeout */
|
|
25
|
+
}
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Instance Management
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// Create single
|
|
32
|
+
const instance = await env.MY_WORKFLOW.create({
|
|
33
|
+
id: crypto.randomUUID(),
|
|
34
|
+
params: { userId: 'user123' },
|
|
35
|
+
}) // id optional, auto-generated if omitted
|
|
36
|
+
|
|
37
|
+
// Create with custom retention (default: 3 days free, 30 days paid)
|
|
38
|
+
const instance = await env.MY_WORKFLOW.create({
|
|
39
|
+
id: crypto.randomUUID(),
|
|
40
|
+
params: { userId: 'user123' },
|
|
41
|
+
retention: '30 days', // Override default retention period
|
|
42
|
+
})
|
|
43
|
+
|
|
44
|
+
// Batch (max 100, idempotent: skips existing IDs)
|
|
45
|
+
const instances = await env.MY_WORKFLOW.createBatch([
|
|
46
|
+
{ id: 'user1', params: { name: 'John' } },
|
|
47
|
+
{ id: 'user2', params: { name: 'Jane' } },
|
|
48
|
+
])
|
|
49
|
+
|
|
50
|
+
// Get & Status
|
|
51
|
+
const instance = await env.MY_WORKFLOW.get('instance-id')
|
|
52
|
+
const status = await instance.status() // {status: 'queued' | 'running' | 'paused' | 'errored' | 'terminated' | 'complete' | 'waiting' | 'waitingForPause' | 'unknown', error?, output?}
|
|
53
|
+
|
|
54
|
+
// Control
|
|
55
|
+
await instance.pause()
|
|
56
|
+
await instance.resume()
|
|
57
|
+
await instance.terminate()
|
|
58
|
+
await instance.restart()
|
|
59
|
+
|
|
60
|
+
// Send Events
|
|
61
|
+
await instance.sendEvent({ type: 'approval', payload: { approved: true } }) // Must match waitForEvent type
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Triggering Workflows
|
|
65
|
+
|
|
66
|
+
```typescript
|
|
67
|
+
// From Worker
|
|
68
|
+
export default {
|
|
69
|
+
async fetch(req, env) {
|
|
70
|
+
const instance = await env.MY_WORKFLOW.create({
|
|
71
|
+
id: crypto.randomUUID(),
|
|
72
|
+
params: { userId: 'user123' },
|
|
73
|
+
})
|
|
74
|
+
return Response.json({ id: instance.id })
|
|
75
|
+
},
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// From Queue
|
|
79
|
+
export default {
|
|
80
|
+
async queue(batch, env) {
|
|
81
|
+
for (const msg of batch.messages) {
|
|
82
|
+
await env.MY_WORKFLOW.create({ id: `job-${msg.id}`, params: msg.body })
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// From Cron
|
|
88
|
+
export default {
|
|
89
|
+
async scheduled(event, env) {
|
|
90
|
+
await env.CLEANUP_WORKFLOW.create({
|
|
91
|
+
id: `cleanup-${Date.now()}`,
|
|
92
|
+
params: { timestamp: event.scheduledTime },
|
|
93
|
+
})
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// From Another Workflow (non-blocking)
|
|
98
|
+
export class ParentWorkflow extends WorkflowEntrypoint<Env, Params> {
|
|
99
|
+
async run(event, step) {
|
|
100
|
+
const child = await step.do(
|
|
101
|
+
'start child',
|
|
102
|
+
async () =>
|
|
103
|
+
await this.env.CHILD_WORKFLOW.create({ id: `child-${event.instanceId}`, params: {} })
|
|
104
|
+
)
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Error Handling
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { NonRetryableError } from 'cloudflare:workers'
|
|
113
|
+
|
|
114
|
+
// NonRetryableError
|
|
115
|
+
await step.do('validate', async () => {
|
|
116
|
+
if (!event.payload.paymentMethod) throw new NonRetryableError('Payment method required')
|
|
117
|
+
const res = await fetch('https://api.example.com/charge', { method: 'POST' })
|
|
118
|
+
if (res.status === 401) throw new NonRetryableError('Invalid credentials') // Don't retry
|
|
119
|
+
if (!res.ok) throw new Error('Retryable failure') // Will retry
|
|
120
|
+
return res.json()
|
|
121
|
+
})
|
|
122
|
+
|
|
123
|
+
// Catching Errors
|
|
124
|
+
try {
|
|
125
|
+
await step.do('risky op', async () => {
|
|
126
|
+
throw new NonRetryableError('Failed')
|
|
127
|
+
})
|
|
128
|
+
} catch (e) {
|
|
129
|
+
await step.do('cleanup', async () => {})
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Idempotency
|
|
133
|
+
await step.do('charge', async () => {
|
|
134
|
+
const sub = await fetch(`https://api/subscriptions/${id}`).then((r) => r.json())
|
|
135
|
+
if (sub.charged) return sub // Already done
|
|
136
|
+
return await fetch(`https://api/subscriptions/${id}`, {
|
|
137
|
+
method: 'POST',
|
|
138
|
+
body: JSON.stringify({ amount: 10.0 }),
|
|
139
|
+
}).then((r) => r.json())
|
|
140
|
+
})
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
## Type Constraints
|
|
144
|
+
|
|
145
|
+
Params and step returns must be `Rpc.Serializable<T>`:
|
|
146
|
+
|
|
147
|
+
```typescript
|
|
148
|
+
// ✅ Valid types
|
|
149
|
+
type ValidParams = {
|
|
150
|
+
userId: string
|
|
151
|
+
count: number
|
|
152
|
+
tags: string[]
|
|
153
|
+
metadata: Record<string, unknown>
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// ❌ Invalid types
|
|
157
|
+
type InvalidParams = {
|
|
158
|
+
callback: () => void // Functions not serializable
|
|
159
|
+
symbol: symbol // Symbols not serializable
|
|
160
|
+
circular: any // Circular references not allowed
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
// Step returns follow same rules
|
|
164
|
+
const result = await step.do('fetch', async () => {
|
|
165
|
+
return { userId: '123', data: [1, 2, 3] } // ✅ Plain object
|
|
166
|
+
})
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Sleep & Scheduling
|
|
170
|
+
|
|
171
|
+
```typescript
|
|
172
|
+
// Relative
|
|
173
|
+
await step.sleep('wait 1 hour', '1 hour')
|
|
174
|
+
await step.sleep('wait 30 days', '30 days')
|
|
175
|
+
await step.sleep('wait 5s', 5000) // ms
|
|
176
|
+
|
|
177
|
+
// Absolute
|
|
178
|
+
await step.sleepUntil('launch date', Date.parse('24 Oct 2024 13:00:00 UTC'))
|
|
179
|
+
await step.sleepUntil('deadline', new Date('2024-12-31T23:59:59Z'))
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Units: second, minute, hour, day, week, month, year. Max: 365 days.
|
|
183
|
+
Sleeping instances don't count toward concurrency.
|
|
184
|
+
|
|
185
|
+
## Parameters
|
|
186
|
+
|
|
187
|
+
**Pass from Worker:**
|
|
188
|
+
|
|
189
|
+
```typescript
|
|
190
|
+
const instance = await env.MY_WORKFLOW.create({
|
|
191
|
+
id: crypto.randomUUID(),
|
|
192
|
+
params: { userId: 'user123', email: 'user@example.com' },
|
|
193
|
+
})
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Access in Workflow:**
|
|
197
|
+
|
|
198
|
+
```typescript
|
|
199
|
+
async run(event: WorkflowEvent<Params>, step: WorkflowStep) {
|
|
200
|
+
const userId = event.payload.userId;
|
|
201
|
+
const instanceId = event.instanceId;
|
|
202
|
+
const createdAt = event.timestamp;
|
|
203
|
+
}
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
**CLI Trigger:**
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npx wrangler workflows trigger my-workflow '{"userId":"user123"}'
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
## Wrangler CLI
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
npm create cloudflare@latest my-workflow -- --template "cloudflare/workflows-starter"
|
|
216
|
+
npx wrangler deploy
|
|
217
|
+
npx wrangler workflows list
|
|
218
|
+
npx wrangler workflows trigger my-workflow '{"userId":"user123"}'
|
|
219
|
+
npx wrangler workflows instances list my-workflow
|
|
220
|
+
npx wrangler workflows instances describe my-workflow instance-id
|
|
221
|
+
npx wrangler workflows instances pause/resume/terminate my-workflow instance-id
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## REST API
|
|
225
|
+
|
|
226
|
+
```bash
|
|
227
|
+
# Create
|
|
228
|
+
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances" -H "Authorization: Bearer {token}" -d '{"id":"custom-id","params":{"userId":"user123"}}'
|
|
229
|
+
|
|
230
|
+
# Status
|
|
231
|
+
curl "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/status" -H "Authorization: Bearer {token}"
|
|
232
|
+
|
|
233
|
+
# Send Event
|
|
234
|
+
curl -X POST "https://api.cloudflare.com/client/v4/accounts/{account_id}/workflows/{workflow_name}/instances/{instance_id}/events" -H "Authorization: Bearer {token}" -d '{"type":"approval","payload":{"approved":true}}'
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
See: [configuration.md](./configuration.md), [patterns.md](./patterns.md)
|