pi-cloudflare 0.1.0

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.
Files changed (410) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +67 -0
  3. package/bin/setup.mjs +103 -0
  4. package/dist/auth-flow.d.ts +15 -0
  5. package/dist/auth-flow.d.ts.map +1 -0
  6. package/dist/auth-flow.js +90 -0
  7. package/dist/auth-flow.js.map +1 -0
  8. package/dist/client.d.ts +18 -0
  9. package/dist/client.d.ts.map +1 -0
  10. package/dist/client.js +47 -0
  11. package/dist/client.js.map +1 -0
  12. package/dist/config.d.ts +13 -0
  13. package/dist/config.d.ts.map +1 -0
  14. package/dist/config.js +10 -0
  15. package/dist/config.js.map +1 -0
  16. package/dist/index.d.ts +24 -0
  17. package/dist/index.d.ts.map +1 -0
  18. package/dist/index.js +109 -0
  19. package/dist/index.js.map +1 -0
  20. package/dist/oauth.d.ts +44 -0
  21. package/dist/oauth.d.ts.map +1 -0
  22. package/dist/oauth.js +135 -0
  23. package/dist/oauth.js.map +1 -0
  24. package/dist/proxy.d.ts +29 -0
  25. package/dist/proxy.d.ts.map +1 -0
  26. package/dist/proxy.js +39 -0
  27. package/dist/proxy.js.map +1 -0
  28. package/dist/servers.d.ts +19 -0
  29. package/dist/servers.d.ts.map +1 -0
  30. package/dist/servers.js +40 -0
  31. package/dist/servers.js.map +1 -0
  32. package/dist/token-store.d.ts +23 -0
  33. package/dist/token-store.d.ts.map +1 -0
  34. package/dist/token-store.js +47 -0
  35. package/dist/token-store.js.map +1 -0
  36. package/package.json +67 -0
  37. package/skills/agents-sdk/SKILL.md +221 -0
  38. package/skills/agents-sdk/references/browse-the-web.md +63 -0
  39. package/skills/agents-sdk/references/callable.md +92 -0
  40. package/skills/agents-sdk/references/client-sdk.md +110 -0
  41. package/skills/agents-sdk/references/codemode.md +110 -0
  42. package/skills/agents-sdk/references/configuration.md +72 -0
  43. package/skills/agents-sdk/references/durable-execution.md +51 -0
  44. package/skills/agents-sdk/references/email.md +146 -0
  45. package/skills/agents-sdk/references/human-in-the-loop.md +67 -0
  46. package/skills/agents-sdk/references/mcp.md +188 -0
  47. package/skills/agents-sdk/references/observability.md +44 -0
  48. package/skills/agents-sdk/references/queue-retries.md +79 -0
  49. package/skills/agents-sdk/references/routing.md +75 -0
  50. package/skills/agents-sdk/references/server-driven-messages.md +63 -0
  51. package/skills/agents-sdk/references/state-scheduling.md +171 -0
  52. package/skills/agents-sdk/references/streaming-chat.md +198 -0
  53. package/skills/agents-sdk/references/think.md +112 -0
  54. package/skills/agents-sdk/references/voice.md +68 -0
  55. package/skills/agents-sdk/references/webhooks-push.md +86 -0
  56. package/skills/agents-sdk/references/workflows.md +132 -0
  57. package/skills/cloudflare/SKILL.md +248 -0
  58. package/skills/cloudflare/references/agents-sdk/README.md +89 -0
  59. package/skills/cloudflare/references/agents-sdk/api.md +190 -0
  60. package/skills/cloudflare/references/agents-sdk/configuration.md +182 -0
  61. package/skills/cloudflare/references/agents-sdk/gotchas.md +158 -0
  62. package/skills/cloudflare/references/agents-sdk/patterns.md +192 -0
  63. package/skills/cloudflare/references/ai-gateway/README.md +175 -0
  64. package/skills/cloudflare/references/ai-gateway/configuration.md +111 -0
  65. package/skills/cloudflare/references/ai-gateway/dynamic-routing.md +82 -0
  66. package/skills/cloudflare/references/ai-gateway/features.md +96 -0
  67. package/skills/cloudflare/references/ai-gateway/sdk-integration.md +114 -0
  68. package/skills/cloudflare/references/ai-gateway/troubleshooting.md +88 -0
  69. package/skills/cloudflare/references/ai-search/README.md +138 -0
  70. package/skills/cloudflare/references/ai-search/api.md +87 -0
  71. package/skills/cloudflare/references/ai-search/configuration.md +88 -0
  72. package/skills/cloudflare/references/ai-search/gotchas.md +81 -0
  73. package/skills/cloudflare/references/ai-search/patterns.md +85 -0
  74. package/skills/cloudflare/references/analytics-engine/README.md +94 -0
  75. package/skills/cloudflare/references/analytics-engine/api.md +112 -0
  76. package/skills/cloudflare/references/analytics-engine/configuration.md +112 -0
  77. package/skills/cloudflare/references/analytics-engine/gotchas.md +85 -0
  78. package/skills/cloudflare/references/analytics-engine/patterns.md +83 -0
  79. package/skills/cloudflare/references/api/README.md +66 -0
  80. package/skills/cloudflare/references/api/api.md +204 -0
  81. package/skills/cloudflare/references/api/configuration.md +160 -0
  82. package/skills/cloudflare/references/api/gotchas.md +225 -0
  83. package/skills/cloudflare/references/api/patterns.md +204 -0
  84. package/skills/cloudflare/references/api-shield/README.md +44 -0
  85. package/skills/cloudflare/references/api-shield/api.md +141 -0
  86. package/skills/cloudflare/references/api-shield/configuration.md +192 -0
  87. package/skills/cloudflare/references/api-shield/gotchas.md +125 -0
  88. package/skills/cloudflare/references/api-shield/patterns.md +180 -0
  89. package/skills/cloudflare/references/argo-smart-routing/README.md +90 -0
  90. package/skills/cloudflare/references/argo-smart-routing/api.md +240 -0
  91. package/skills/cloudflare/references/argo-smart-routing/configuration.md +197 -0
  92. package/skills/cloudflare/references/argo-smart-routing/gotchas.md +111 -0
  93. package/skills/cloudflare/references/argo-smart-routing/patterns.md +104 -0
  94. package/skills/cloudflare/references/artifacts/README.md +79 -0
  95. package/skills/cloudflare/references/artifacts/api.md +128 -0
  96. package/skills/cloudflare/references/artifacts/configuration.md +92 -0
  97. package/skills/cloudflare/references/bindings/README.md +122 -0
  98. package/skills/cloudflare/references/bindings/api.md +203 -0
  99. package/skills/cloudflare/references/bindings/configuration.md +188 -0
  100. package/skills/cloudflare/references/bindings/gotchas.md +208 -0
  101. package/skills/cloudflare/references/bindings/patterns.md +200 -0
  102. package/skills/cloudflare/references/bot-management/README.md +94 -0
  103. package/skills/cloudflare/references/bot-management/api.md +169 -0
  104. package/skills/cloudflare/references/bot-management/configuration.md +163 -0
  105. package/skills/cloudflare/references/bot-management/gotchas.md +114 -0
  106. package/skills/cloudflare/references/bot-management/patterns.md +182 -0
  107. package/skills/cloudflare/references/browser-rendering/README.md +78 -0
  108. package/skills/cloudflare/references/browser-rendering/api.md +108 -0
  109. package/skills/cloudflare/references/browser-rendering/configuration.md +78 -0
  110. package/skills/cloudflare/references/browser-rendering/gotchas.md +88 -0
  111. package/skills/cloudflare/references/browser-rendering/patterns.md +91 -0
  112. package/skills/cloudflare/references/c3/README.md +111 -0
  113. package/skills/cloudflare/references/c3/api.md +71 -0
  114. package/skills/cloudflare/references/c3/configuration.md +81 -0
  115. package/skills/cloudflare/references/c3/gotchas.md +92 -0
  116. package/skills/cloudflare/references/c3/patterns.md +82 -0
  117. package/skills/cloudflare/references/cache-reserve/README.md +147 -0
  118. package/skills/cloudflare/references/cache-reserve/api.md +194 -0
  119. package/skills/cloudflare/references/cache-reserve/configuration.md +169 -0
  120. package/skills/cloudflare/references/cache-reserve/gotchas.md +132 -0
  121. package/skills/cloudflare/references/cache-reserve/patterns.md +197 -0
  122. package/skills/cloudflare/references/containers/README.md +85 -0
  123. package/skills/cloudflare/references/containers/api.md +187 -0
  124. package/skills/cloudflare/references/containers/configuration.md +188 -0
  125. package/skills/cloudflare/references/containers/gotchas.md +178 -0
  126. package/skills/cloudflare/references/containers/patterns.md +202 -0
  127. package/skills/cloudflare/references/cron-triggers/README.md +99 -0
  128. package/skills/cloudflare/references/cron-triggers/api.md +196 -0
  129. package/skills/cloudflare/references/cron-triggers/configuration.md +180 -0
  130. package/skills/cloudflare/references/cron-triggers/gotchas.md +199 -0
  131. package/skills/cloudflare/references/cron-triggers/patterns.md +190 -0
  132. package/skills/cloudflare/references/d1/README.md +133 -0
  133. package/skills/cloudflare/references/d1/api.md +196 -0
  134. package/skills/cloudflare/references/d1/configuration.md +191 -0
  135. package/skills/cloudflare/references/d1/gotchas.md +98 -0
  136. package/skills/cloudflare/references/d1/patterns.md +189 -0
  137. package/skills/cloudflare/references/ddos/README.md +41 -0
  138. package/skills/cloudflare/references/ddos/api.md +164 -0
  139. package/skills/cloudflare/references/ddos/configuration.md +93 -0
  140. package/skills/cloudflare/references/ddos/gotchas.md +107 -0
  141. package/skills/cloudflare/references/ddos/patterns.md +174 -0
  142. package/skills/cloudflare/references/do-storage/README.md +75 -0
  143. package/skills/cloudflare/references/do-storage/api.md +102 -0
  144. package/skills/cloudflare/references/do-storage/configuration.md +112 -0
  145. package/skills/cloudflare/references/do-storage/gotchas.md +150 -0
  146. package/skills/cloudflare/references/do-storage/patterns.md +194 -0
  147. package/skills/cloudflare/references/do-storage/testing.md +183 -0
  148. package/skills/cloudflare/references/durable-objects/README.md +185 -0
  149. package/skills/cloudflare/references/durable-objects/api.md +187 -0
  150. package/skills/cloudflare/references/durable-objects/configuration.md +160 -0
  151. package/skills/cloudflare/references/durable-objects/gotchas.md +197 -0
  152. package/skills/cloudflare/references/durable-objects/patterns.md +201 -0
  153. package/skills/cloudflare/references/email-routing/README.md +89 -0
  154. package/skills/cloudflare/references/email-routing/api.md +195 -0
  155. package/skills/cloudflare/references/email-routing/configuration.md +186 -0
  156. package/skills/cloudflare/references/email-routing/gotchas.md +196 -0
  157. package/skills/cloudflare/references/email-routing/patterns.md +229 -0
  158. package/skills/cloudflare/references/email-workers/README.md +151 -0
  159. package/skills/cloudflare/references/email-workers/api.md +237 -0
  160. package/skills/cloudflare/references/email-workers/configuration.md +112 -0
  161. package/skills/cloudflare/references/email-workers/gotchas.md +125 -0
  162. package/skills/cloudflare/references/email-workers/patterns.md +102 -0
  163. package/skills/cloudflare/references/flagship/README.md +59 -0
  164. package/skills/cloudflare/references/flagship/api.md +390 -0
  165. package/skills/cloudflare/references/flagship/configuration.md +202 -0
  166. package/skills/cloudflare/references/flagship/gotchas.md +178 -0
  167. package/skills/cloudflare/references/flagship/patterns.md +469 -0
  168. package/skills/cloudflare/references/graphql-api/README.md +147 -0
  169. package/skills/cloudflare/references/graphql-api/api.md +175 -0
  170. package/skills/cloudflare/references/graphql-api/configuration.md +118 -0
  171. package/skills/cloudflare/references/graphql-api/gotchas.md +110 -0
  172. package/skills/cloudflare/references/graphql-api/patterns.md +225 -0
  173. package/skills/cloudflare/references/hyperdrive/README.md +82 -0
  174. package/skills/cloudflare/references/hyperdrive/api.md +143 -0
  175. package/skills/cloudflare/references/hyperdrive/configuration.md +159 -0
  176. package/skills/cloudflare/references/hyperdrive/gotchas.md +77 -0
  177. package/skills/cloudflare/references/hyperdrive/patterns.md +190 -0
  178. package/skills/cloudflare/references/images/README.md +61 -0
  179. package/skills/cloudflare/references/images/api.md +96 -0
  180. package/skills/cloudflare/references/images/configuration.md +211 -0
  181. package/skills/cloudflare/references/images/gotchas.md +99 -0
  182. package/skills/cloudflare/references/images/patterns.md +115 -0
  183. package/skills/cloudflare/references/kv/README.md +89 -0
  184. package/skills/cloudflare/references/kv/api.md +160 -0
  185. package/skills/cloudflare/references/kv/configuration.md +144 -0
  186. package/skills/cloudflare/references/kv/gotchas.md +131 -0
  187. package/skills/cloudflare/references/kv/patterns.md +196 -0
  188. package/skills/cloudflare/references/miniflare/README.md +105 -0
  189. package/skills/cloudflare/references/miniflare/api.md +187 -0
  190. package/skills/cloudflare/references/miniflare/configuration.md +173 -0
  191. package/skills/cloudflare/references/miniflare/gotchas.md +160 -0
  192. package/skills/cloudflare/references/miniflare/patterns.md +181 -0
  193. package/skills/cloudflare/references/network-interconnect/README.md +99 -0
  194. package/skills/cloudflare/references/network-interconnect/api.md +199 -0
  195. package/skills/cloudflare/references/network-interconnect/configuration.md +114 -0
  196. package/skills/cloudflare/references/network-interconnect/gotchas.md +165 -0
  197. package/skills/cloudflare/references/network-interconnect/patterns.md +166 -0
  198. package/skills/cloudflare/references/observability/README.md +88 -0
  199. package/skills/cloudflare/references/observability/api.md +164 -0
  200. package/skills/cloudflare/references/observability/configuration.md +169 -0
  201. package/skills/cloudflare/references/observability/gotchas.md +115 -0
  202. package/skills/cloudflare/references/observability/patterns.md +105 -0
  203. package/skills/cloudflare/references/pages/README.md +88 -0
  204. package/skills/cloudflare/references/pages/api.md +204 -0
  205. package/skills/cloudflare/references/pages/configuration.md +201 -0
  206. package/skills/cloudflare/references/pages/gotchas.md +203 -0
  207. package/skills/cloudflare/references/pages/patterns.md +204 -0
  208. package/skills/cloudflare/references/pages-functions/README.md +98 -0
  209. package/skills/cloudflare/references/pages-functions/api.md +143 -0
  210. package/skills/cloudflare/references/pages-functions/configuration.md +122 -0
  211. package/skills/cloudflare/references/pages-functions/gotchas.md +94 -0
  212. package/skills/cloudflare/references/pages-functions/patterns.md +137 -0
  213. package/skills/cloudflare/references/pipelines/README.md +90 -0
  214. package/skills/cloudflare/references/pipelines/api.md +124 -0
  215. package/skills/cloudflare/references/pipelines/configuration.md +155 -0
  216. package/skills/cloudflare/references/pipelines/gotchas.md +58 -0
  217. package/skills/cloudflare/references/pipelines/patterns.md +130 -0
  218. package/skills/cloudflare/references/pulumi/README.md +100 -0
  219. package/skills/cloudflare/references/pulumi/api.md +200 -0
  220. package/skills/cloudflare/references/pulumi/configuration.md +198 -0
  221. package/skills/cloudflare/references/pulumi/gotchas.md +181 -0
  222. package/skills/cloudflare/references/pulumi/patterns.md +191 -0
  223. package/skills/cloudflare/references/queues/README.md +96 -0
  224. package/skills/cloudflare/references/queues/api.md +206 -0
  225. package/skills/cloudflare/references/queues/configuration.md +144 -0
  226. package/skills/cloudflare/references/queues/gotchas.md +206 -0
  227. package/skills/cloudflare/references/queues/patterns.md +220 -0
  228. package/skills/cloudflare/references/r2/README.md +95 -0
  229. package/skills/cloudflare/references/r2/api.md +200 -0
  230. package/skills/cloudflare/references/r2/configuration.md +165 -0
  231. package/skills/cloudflare/references/r2/gotchas.md +190 -0
  232. package/skills/cloudflare/references/r2/patterns.md +193 -0
  233. package/skills/cloudflare/references/r2-data-catalog/README.md +75 -0
  234. package/skills/cloudflare/references/r2-data-catalog/api.md +122 -0
  235. package/skills/cloudflare/references/r2-data-catalog/configuration.md +98 -0
  236. package/skills/cloudflare/references/r2-data-catalog/gotchas.md +55 -0
  237. package/skills/cloudflare/references/r2-data-catalog/patterns.md +122 -0
  238. package/skills/cloudflare/references/r2-sql/README.md +64 -0
  239. package/skills/cloudflare/references/r2-sql/api.md +121 -0
  240. package/skills/cloudflare/references/r2-sql/configuration.md +50 -0
  241. package/skills/cloudflare/references/r2-sql/gotchas.md +39 -0
  242. package/skills/cloudflare/references/r2-sql/patterns.md +118 -0
  243. package/skills/cloudflare/references/realtime-sfu/README.md +65 -0
  244. package/skills/cloudflare/references/realtime-sfu/api.md +158 -0
  245. package/skills/cloudflare/references/realtime-sfu/configuration.md +137 -0
  246. package/skills/cloudflare/references/realtime-sfu/gotchas.md +133 -0
  247. package/skills/cloudflare/references/realtime-sfu/patterns.md +174 -0
  248. package/skills/cloudflare/references/realtimekit/README.md +113 -0
  249. package/skills/cloudflare/references/realtimekit/api.md +212 -0
  250. package/skills/cloudflare/references/realtimekit/configuration.md +203 -0
  251. package/skills/cloudflare/references/realtimekit/gotchas.md +169 -0
  252. package/skills/cloudflare/references/realtimekit/patterns.md +223 -0
  253. package/skills/cloudflare/references/sandbox/README.md +96 -0
  254. package/skills/cloudflare/references/sandbox/api.md +198 -0
  255. package/skills/cloudflare/references/sandbox/configuration.md +143 -0
  256. package/skills/cloudflare/references/sandbox/gotchas.md +194 -0
  257. package/skills/cloudflare/references/sandbox/patterns.md +201 -0
  258. package/skills/cloudflare/references/secrets-store/README.md +74 -0
  259. package/skills/cloudflare/references/secrets-store/api.md +200 -0
  260. package/skills/cloudflare/references/secrets-store/configuration.md +185 -0
  261. package/skills/cloudflare/references/secrets-store/gotchas.md +97 -0
  262. package/skills/cloudflare/references/secrets-store/patterns.md +207 -0
  263. package/skills/cloudflare/references/smart-placement/README.md +138 -0
  264. package/skills/cloudflare/references/smart-placement/api.md +183 -0
  265. package/skills/cloudflare/references/smart-placement/configuration.md +196 -0
  266. package/skills/cloudflare/references/smart-placement/gotchas.md +174 -0
  267. package/skills/cloudflare/references/smart-placement/patterns.md +183 -0
  268. package/skills/cloudflare/references/snippets/README.md +68 -0
  269. package/skills/cloudflare/references/snippets/api.md +198 -0
  270. package/skills/cloudflare/references/snippets/configuration.md +227 -0
  271. package/skills/cloudflare/references/snippets/gotchas.md +86 -0
  272. package/skills/cloudflare/references/snippets/patterns.md +135 -0
  273. package/skills/cloudflare/references/spectrum/README.md +52 -0
  274. package/skills/cloudflare/references/spectrum/api.md +181 -0
  275. package/skills/cloudflare/references/spectrum/configuration.md +194 -0
  276. package/skills/cloudflare/references/spectrum/gotchas.md +145 -0
  277. package/skills/cloudflare/references/spectrum/patterns.md +196 -0
  278. package/skills/cloudflare/references/static-assets/README.md +65 -0
  279. package/skills/cloudflare/references/static-assets/api.md +199 -0
  280. package/skills/cloudflare/references/static-assets/configuration.md +186 -0
  281. package/skills/cloudflare/references/static-assets/gotchas.md +162 -0
  282. package/skills/cloudflare/references/static-assets/patterns.md +189 -0
  283. package/skills/cloudflare/references/stream/README.md +114 -0
  284. package/skills/cloudflare/references/stream/api-live.md +195 -0
  285. package/skills/cloudflare/references/stream/api.md +199 -0
  286. package/skills/cloudflare/references/stream/configuration.md +141 -0
  287. package/skills/cloudflare/references/stream/gotchas.md +130 -0
  288. package/skills/cloudflare/references/stream/patterns.md +184 -0
  289. package/skills/cloudflare/references/tail-workers/README.md +89 -0
  290. package/skills/cloudflare/references/tail-workers/api.md +200 -0
  291. package/skills/cloudflare/references/tail-workers/configuration.md +176 -0
  292. package/skills/cloudflare/references/tail-workers/gotchas.md +192 -0
  293. package/skills/cloudflare/references/tail-workers/patterns.md +180 -0
  294. package/skills/cloudflare/references/terraform/README.md +102 -0
  295. package/skills/cloudflare/references/terraform/api.md +178 -0
  296. package/skills/cloudflare/references/terraform/configuration.md +197 -0
  297. package/skills/cloudflare/references/terraform/gotchas.md +150 -0
  298. package/skills/cloudflare/references/terraform/patterns.md +174 -0
  299. package/skills/cloudflare/references/tunnel/README.md +129 -0
  300. package/skills/cloudflare/references/tunnel/api.md +193 -0
  301. package/skills/cloudflare/references/tunnel/configuration.md +157 -0
  302. package/skills/cloudflare/references/tunnel/gotchas.md +147 -0
  303. package/skills/cloudflare/references/tunnel/networking.md +168 -0
  304. package/skills/cloudflare/references/tunnel/patterns.md +192 -0
  305. package/skills/cloudflare/references/turn/README.md +82 -0
  306. package/skills/cloudflare/references/turn/api.md +239 -0
  307. package/skills/cloudflare/references/turn/configuration.md +179 -0
  308. package/skills/cloudflare/references/turn/gotchas.md +231 -0
  309. package/skills/cloudflare/references/turn/patterns.md +213 -0
  310. package/skills/cloudflare/references/turnstile/README.md +99 -0
  311. package/skills/cloudflare/references/turnstile/api.md +240 -0
  312. package/skills/cloudflare/references/turnstile/configuration.md +222 -0
  313. package/skills/cloudflare/references/turnstile/gotchas.md +218 -0
  314. package/skills/cloudflare/references/turnstile/patterns.md +193 -0
  315. package/skills/cloudflare/references/vectorize/README.md +133 -0
  316. package/skills/cloudflare/references/vectorize/api.md +88 -0
  317. package/skills/cloudflare/references/vectorize/configuration.md +88 -0
  318. package/skills/cloudflare/references/vectorize/gotchas.md +76 -0
  319. package/skills/cloudflare/references/vectorize/patterns.md +90 -0
  320. package/skills/cloudflare/references/waf/README.md +113 -0
  321. package/skills/cloudflare/references/waf/api.md +202 -0
  322. package/skills/cloudflare/references/waf/configuration.md +203 -0
  323. package/skills/cloudflare/references/waf/gotchas.md +204 -0
  324. package/skills/cloudflare/references/waf/patterns.md +197 -0
  325. package/skills/cloudflare/references/web-analytics/README.md +141 -0
  326. package/skills/cloudflare/references/web-analytics/configuration.md +76 -0
  327. package/skills/cloudflare/references/web-analytics/gotchas.md +82 -0
  328. package/skills/cloudflare/references/web-analytics/integration.md +60 -0
  329. package/skills/cloudflare/references/web-analytics/patterns.md +91 -0
  330. package/skills/cloudflare/references/workerd/README.md +78 -0
  331. package/skills/cloudflare/references/workerd/api.md +185 -0
  332. package/skills/cloudflare/references/workerd/configuration.md +183 -0
  333. package/skills/cloudflare/references/workerd/gotchas.md +139 -0
  334. package/skills/cloudflare/references/workerd/patterns.md +192 -0
  335. package/skills/cloudflare/references/workers/README.md +108 -0
  336. package/skills/cloudflare/references/workers/api.md +195 -0
  337. package/skills/cloudflare/references/workers/configuration.md +185 -0
  338. package/skills/cloudflare/references/workers/frameworks.md +197 -0
  339. package/skills/cloudflare/references/workers/gotchas.md +137 -0
  340. package/skills/cloudflare/references/workers/patterns.md +198 -0
  341. package/skills/cloudflare/references/workers-ai/README.md +197 -0
  342. package/skills/cloudflare/references/workers-ai/api.md +112 -0
  343. package/skills/cloudflare/references/workers-ai/configuration.md +97 -0
  344. package/skills/cloudflare/references/workers-ai/gotchas.md +114 -0
  345. package/skills/cloudflare/references/workers-ai/patterns.md +120 -0
  346. package/skills/cloudflare/references/workers-for-platforms/README.md +89 -0
  347. package/skills/cloudflare/references/workers-for-platforms/api.md +196 -0
  348. package/skills/cloudflare/references/workers-for-platforms/configuration.md +167 -0
  349. package/skills/cloudflare/references/workers-for-platforms/gotchas.md +134 -0
  350. package/skills/cloudflare/references/workers-for-platforms/patterns.md +188 -0
  351. package/skills/cloudflare/references/workers-playground/README.md +127 -0
  352. package/skills/cloudflare/references/workers-playground/api.md +101 -0
  353. package/skills/cloudflare/references/workers-playground/configuration.md +163 -0
  354. package/skills/cloudflare/references/workers-playground/gotchas.md +88 -0
  355. package/skills/cloudflare/references/workers-playground/patterns.md +132 -0
  356. package/skills/cloudflare/references/workers-vpc/README.md +127 -0
  357. package/skills/cloudflare/references/workers-vpc/api.md +202 -0
  358. package/skills/cloudflare/references/workers-vpc/configuration.md +147 -0
  359. package/skills/cloudflare/references/workers-vpc/gotchas.md +167 -0
  360. package/skills/cloudflare/references/workers-vpc/patterns.md +209 -0
  361. package/skills/cloudflare/references/workflows/README.md +77 -0
  362. package/skills/cloudflare/references/workflows/api.md +218 -0
  363. package/skills/cloudflare/references/workflows/configuration.md +152 -0
  364. package/skills/cloudflare/references/workflows/gotchas.md +90 -0
  365. package/skills/cloudflare/references/workflows/patterns.md +175 -0
  366. package/skills/cloudflare/references/wrangler/README.md +135 -0
  367. package/skills/cloudflare/references/wrangler/api.md +188 -0
  368. package/skills/cloudflare/references/wrangler/configuration.md +197 -0
  369. package/skills/cloudflare/references/wrangler/gotchas.md +197 -0
  370. package/skills/cloudflare/references/wrangler/patterns.md +209 -0
  371. package/skills/cloudflare/references/zaraz/IMPLEMENTATION_SUMMARY.md +121 -0
  372. package/skills/cloudflare/references/zaraz/README.md +111 -0
  373. package/skills/cloudflare/references/zaraz/api.md +112 -0
  374. package/skills/cloudflare/references/zaraz/configuration.md +90 -0
  375. package/skills/cloudflare/references/zaraz/gotchas.md +81 -0
  376. package/skills/cloudflare/references/zaraz/patterns.md +74 -0
  377. package/skills/cloudflare-email-service/SKILL.md +103 -0
  378. package/skills/cloudflare-email-service/references/cli-and-mcp.md +125 -0
  379. package/skills/cloudflare-email-service/references/deliverability.md +285 -0
  380. package/skills/cloudflare-email-service/references/rest-api.md +184 -0
  381. package/skills/cloudflare-email-service/references/routing.md +199 -0
  382. package/skills/cloudflare-email-service/references/sending.md +252 -0
  383. package/skills/cloudflare-one/SKILL.md +176 -0
  384. package/skills/cloudflare-one-migrations/SKILL.md +110 -0
  385. package/skills/durable-objects/SKILL.md +186 -0
  386. package/skills/durable-objects/references/rules.md +295 -0
  387. package/skills/durable-objects/references/testing.md +264 -0
  388. package/skills/durable-objects/references/workers.md +346 -0
  389. package/skills/sandbox-migrate-to-next/SKILL.md +185 -0
  390. package/skills/sandbox-next/SKILL.md +91 -0
  391. package/skills/sandbox-next/references/api-quick-ref.md +94 -0
  392. package/skills/sandbox-next/references/examples.md +15 -0
  393. package/skills/sandbox-stable/SKILL.md +110 -0
  394. package/skills/turnstile-spin/README.md +51 -0
  395. package/skills/turnstile-spin/SKILL.md +330 -0
  396. package/skills/turnstile-spin/references/astro.md +199 -0
  397. package/skills/turnstile-spin/references/hugo.md +114 -0
  398. package/skills/turnstile-spin/references/nextjs-app.md +261 -0
  399. package/skills/turnstile-spin/references/nextjs-pages.md +82 -0
  400. package/skills/turnstile-spin/references/sveltekit.md +191 -0
  401. package/skills/turnstile-spin/references/vanilla-html.md +157 -0
  402. package/skills/turnstile-spin/scripts/auth-probe.sh +285 -0
  403. package/skills/turnstile-spin/scripts/persist-skill.sh +114 -0
  404. package/skills/turnstile-spin/scripts/validate.sh +137 -0
  405. package/skills/turnstile-spin/scripts/widget-create.sh +121 -0
  406. package/skills/turnstile-spin/tests/validation.md +62 -0
  407. package/skills/workers-best-practices/SKILL.md +127 -0
  408. package/skills/workers-best-practices/references/review.md +174 -0
  409. package/skills/workers-best-practices/references/rules.md +467 -0
  410. package/skills/wrangler/SKILL.md +922 -0
@@ -0,0 +1,114 @@
1
+ #!/usr/bin/env bash
2
+ # Persists the canonical Spin skill bundle into the current project.
3
+
4
+ set +x
5
+ set -uo pipefail
6
+
7
+ unset CLOUDFLARE_API_TOKEN CF_API_TOKEN CLOUDFLARE_API_KEY CF_API_KEY
8
+ unset CLOUDFLARE_EMAIL CF_API_EMAIL WIDGET_SECRET TURNSTILE_SECRET
9
+ unset WRANGLER_BIN WRANGLER_VERSION
10
+ unset GITHUB_TOKEN GH_TOKEN GITLAB_TOKEN NPM_TOKEN
11
+
12
+ need_arg() {
13
+ if [[ -z "${2-}" || "$2" == --* ]]; then
14
+ echo "persist-skill: missing value for $1" >&2
15
+ exit 2
16
+ fi
17
+ }
18
+
19
+ PATH_ARG=""
20
+ while [[ $# -gt 0 ]]; do
21
+ case "$1" in
22
+ --path) need_arg "$1" "${2-}"; PATH_ARG="$2"; shift 2 ;;
23
+ *) echo "persist-skill: unknown arg $1" >&2; exit 2 ;;
24
+ esac
25
+ done
26
+
27
+ [[ -n "$PATH_ARG" ]] || { echo "persist-skill: --path required" >&2; exit 2; }
28
+ if [[ "$(basename "$PATH_ARG")" != "SKILL.md" ]]; then
29
+ echo "persist-skill: --path must end in SKILL.md for a directory-based skill bundle" >&2
30
+ echo '{"status":"error","reason":"file_target_not_supported"}'
31
+ exit 2
32
+ fi
33
+
34
+ for command_name in git python3; do
35
+ command -v "$command_name" >/dev/null 2>&1 || {
36
+ echo "persist-skill: $command_name is required" >&2
37
+ echo "{\"status\":\"error\",\"reason\":\"${command_name}_not_available\"}"
38
+ exit 1
39
+ }
40
+ done
41
+
42
+ PROJECT_ROOT="$(pwd -P)"
43
+ TARGET_DIR="$(python3 -I -c 'import os,sys; print(os.path.realpath(os.path.abspath(sys.argv[1])))' "$(dirname "$PATH_ARG")")"
44
+ if [[ "$TARGET_DIR" != "$PROJECT_ROOT" && "$TARGET_DIR" != "$PROJECT_ROOT/"* ]]; then
45
+ echo "persist-skill: target must be inside the current project" >&2
46
+ echo '{"status":"error","reason":"target_outside_project"}'
47
+ exit 1
48
+ fi
49
+ if [[ -e "$TARGET_DIR" ]] && ! python3 -I -c 'import os,sys; raise SystemExit(0 if not os.listdir(sys.argv[1]) else 1)' "$TARGET_DIR"; then
50
+ echo "persist-skill: target directory is not empty" >&2
51
+ echo '{"status":"error","reason":"target_not_empty"}'
52
+ exit 1
53
+ fi
54
+
55
+ if ! TEMP_DIR="$(mktemp -d "${TMPDIR:-/tmp}/turnstile-spin-persist.XXXXXX")"; then
56
+ echo "persist-skill: could not create a temporary directory" >&2
57
+ echo '{"status":"error","reason":"temporary_directory_failed"}'
58
+ exit 1
59
+ fi
60
+ trap 'rm -rf "$TEMP_DIR"' EXIT
61
+
62
+ if ! git -c core.hooksPath=/dev/null clone \
63
+ --quiet \
64
+ --depth 1 \
65
+ --filter=blob:none \
66
+ --sparse \
67
+ "https://github.com/cloudflare/skills.git" \
68
+ "$TEMP_DIR/repo"; then
69
+ echo "persist-skill: clone failed" >&2
70
+ echo '{"status":"error","reason":"clone_failed"}'
71
+ exit 1
72
+ fi
73
+ if ! git -C "$TEMP_DIR/repo" -c core.hooksPath=/dev/null sparse-checkout set skills/turnstile-spin; then
74
+ echo "persist-skill: sparse checkout failed" >&2
75
+ echo '{"status":"error","reason":"sparse_checkout_failed"}'
76
+ exit 1
77
+ fi
78
+
79
+ SOURCE_DIR="$TEMP_DIR/repo/skills/turnstile-spin"
80
+ if [[ ! -f "$SOURCE_DIR/SKILL.md" ]]; then
81
+ echo "persist-skill: canonical bundle is missing SKILL.md" >&2
82
+ echo '{"status":"error","reason":"skill_missing"}'
83
+ exit 1
84
+ fi
85
+
86
+ python3 -I - "$SOURCE_DIR" "$TARGET_DIR" <<'PY'
87
+ import pathlib
88
+ import shutil
89
+ import sys
90
+
91
+ source = pathlib.Path(sys.argv[1])
92
+ target = pathlib.Path(sys.argv[2])
93
+ if target.exists():
94
+ target.rmdir()
95
+ target.parent.mkdir(parents=True, exist_ok=True)
96
+ shutil.copytree(source, target, dirs_exist_ok=False)
97
+ for script in (target / "scripts").glob("*.sh"):
98
+ script.chmod(0o755)
99
+ PY
100
+
101
+ python3 -I - "$PATH_ARG" "$TARGET_DIR" <<'PY'
102
+ import json
103
+ import pathlib
104
+ import sys
105
+
106
+ path_arg, bundle_root = sys.argv[1], pathlib.Path(sys.argv[2])
107
+ scripts = sorted(path.name for path in (bundle_root / "scripts").glob("*.sh"))
108
+ print(json.dumps({
109
+ "status": "ok",
110
+ "path": path_arg,
111
+ "bundle_root": str(bundle_root),
112
+ "scripts": scripts,
113
+ }))
114
+ PY
@@ -0,0 +1,137 @@
1
+ #!/usr/bin/env bash
2
+ # Validates a Turnstile widget without placing its secret in arguments,
3
+ # exported environment variables, logs, or temporary files.
4
+
5
+ set +x
6
+ set -euo pipefail
7
+
8
+ usage() {
9
+ echo "Usage: printf '%s' \"\$TURNSTILE_SECRET\" | $0 --sitekey <sitekey> --account-id <account-id> --expected-domains '<json-array>'" >&2
10
+ exit 2
11
+ }
12
+
13
+ need_arg() {
14
+ if [[ -z "${2-}" || "$2" == --* ]]; then
15
+ usage
16
+ fi
17
+ }
18
+
19
+ SITEKEY=""
20
+ ACCOUNT_ID=""
21
+ EXPECTED_DOMAINS_JSON=""
22
+
23
+ while [[ $# -gt 0 ]]; do
24
+ case "$1" in
25
+ --sitekey)
26
+ need_arg "$1" "${2-}"
27
+ SITEKEY="$2"
28
+ shift 2
29
+ ;;
30
+ --account-id)
31
+ need_arg "$1" "${2-}"
32
+ ACCOUNT_ID="$2"
33
+ shift 2
34
+ ;;
35
+ --expected-domains)
36
+ need_arg "$1" "${2-}"
37
+ EXPECTED_DOMAINS_JSON="$2"
38
+ shift 2
39
+ ;;
40
+ *) usage ;;
41
+ esac
42
+ done
43
+
44
+ [[ -n "$SITEKEY" && -n "$ACCOUNT_ID" && -n "$EXPECTED_DOMAINS_JSON" ]] || usage
45
+ : "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN must be set}"
46
+ API_TOKEN="$CLOUDFLARE_API_TOKEN"
47
+ unset CLOUDFLARE_API_TOKEN
48
+ [[ "$API_TOKEN" =~ ^[A-Za-z0-9_-]+$ ]] || {
49
+ echo "validate: CLOUDFLARE_API_TOKEN has an invalid format" >&2
50
+ exit 1
51
+ }
52
+
53
+ for command_name in curl jq python3; do
54
+ command -v "$command_name" >/dev/null 2>&1 || {
55
+ echo "validate: $command_name is required" >&2
56
+ exit 1
57
+ }
58
+ done
59
+
60
+ if ! jq -e '
61
+ type == "array" and
62
+ length > 0 and
63
+ all(.[]; type == "string" and length > 0)
64
+ ' <<<"$EXPECTED_DOMAINS_JSON" >/dev/null; then
65
+ echo "validate: --expected-domains must be a non-empty JSON array of domains" >&2
66
+ exit 2
67
+ fi
68
+
69
+ WIDGET_SECRET=""
70
+ IFS= read -r -d '' WIDGET_SECRET || true
71
+ trap 'unset API_TOKEN WIDGET_SECRET WIDGET_API_SECRET WIDGET_RESPONSE SITEVERIFY_RESPONSE' EXIT
72
+
73
+ if [[ -z "$WIDGET_SECRET" || "$WIDGET_SECRET" =~ [[:space:]] ]]; then
74
+ echo "validate: standard input must contain one non-empty secret without whitespace" >&2
75
+ exit 1
76
+ fi
77
+
78
+ ACCOUNT_ENCODED="$(python3 -I -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$ACCOUNT_ID")"
79
+ SITEKEY_ENCODED="$(python3 -I -c 'import sys, urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$SITEKEY")"
80
+
81
+ if ! WIDGET_RESPONSE="$(
82
+ printf 'header = "Authorization: Bearer %s"\n' "$API_TOKEN" |
83
+ curl --disable --config - --fail --silent --show-error \
84
+ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ENCODED/challenges/widgets/$SITEKEY_ENCODED"
85
+ )"; then
86
+ echo "validate: widget metadata lookup failed" >&2
87
+ exit 1
88
+ fi
89
+
90
+ if ! printf '%s' "$WIDGET_RESPONSE" | jq -e --arg sitekey "$SITEKEY" --argjson expected "$EXPECTED_DOMAINS_JSON" '
91
+ . as $widget
92
+ | (.success == true) and
93
+ (.result.sitekey == $sitekey) and
94
+ ((.result.clearance_level | type) == "string") and
95
+ (.result.clearance_level as $clearance | ["no_clearance", "interactive", "managed", "jschallenge"] | index($clearance) != null) and
96
+ ((.result.domains | type) == "array") and
97
+ (all($expected[]; . as $domain | $widget.result.domains | index($domain) != null))
98
+ ' >/dev/null; then
99
+ echo "validate: widget sitekey, domains, or clearance level was invalid" >&2
100
+ exit 1
101
+ fi
102
+
103
+ if ! WIDGET_API_SECRET="$(printf '%s' "$WIDGET_RESPONSE" | jq -er '.result.secret | select(type == "string" and test("^\\S+$"))')"; then
104
+ echo "validate: widget metadata did not include a valid secret" >&2
105
+ exit 1
106
+ fi
107
+ if [[ "$WIDGET_API_SECRET" != "$WIDGET_SECRET" ]]; then
108
+ echo "validate: secret does not belong to the requested sitekey" >&2
109
+ exit 1
110
+ fi
111
+ unset WIDGET_API_SECRET
112
+ unset WIDGET_RESPONSE
113
+
114
+ if ! SITEVERIFY_RESPONSE="$(
115
+ printf '%s' "$WIDGET_SECRET" |
116
+ python3 -I -c 'import sys,urllib.parse; print(urllib.parse.urlencode({"secret":sys.stdin.read(),"response":"XXXX.DUMMY.TOKEN.XXXX"}),end="")' |
117
+ curl --disable --fail --silent --show-error \
118
+ "https://challenges.cloudflare.com/turnstile/v0/siteverify" \
119
+ -H "Content-Type: application/x-www-form-urlencoded" \
120
+ --data-binary @-
121
+ )"; then
122
+ echo "validate: dummy-token siteverify request failed" >&2
123
+ exit 1
124
+ fi
125
+
126
+ if ! jq -e '
127
+ (.success == false) and
128
+ ((.["error-codes"] | type) == "array") and
129
+ ((.["error-codes"] | index("invalid-input-response")) != null) and
130
+ ((.["error-codes"] | index("invalid-input-secret")) == null)
131
+ ' <<<"$SITEVERIFY_RESPONSE" >/dev/null; then
132
+ echo "validate: siteverify did not confirm the widget secret" >&2
133
+ exit 1
134
+ fi
135
+
136
+ unset WIDGET_SECRET SITEVERIFY_RESPONSE
137
+ echo '{"status":"ok","metadata_check":"ran","dummy_siteverify":"ran"}'
@@ -0,0 +1,121 @@
1
+ #!/usr/bin/env bash
2
+ # Creates a Turnstile widget without writing credentials or the response to disk.
3
+
4
+ set +x
5
+ set -uo pipefail
6
+
7
+ need_arg() {
8
+ if [[ -z "${2-}" || "$2" == --* ]]; then
9
+ echo "widget-create: missing value for $1" >&2
10
+ exit 2
11
+ fi
12
+ }
13
+
14
+ MODE="managed"
15
+ ACCOUNT_ID=""
16
+ NAME=""
17
+ DOMAINS=""
18
+
19
+ while [[ $# -gt 0 ]]; do
20
+ case "$1" in
21
+ --account-id) need_arg "$1" "${2-}"; ACCOUNT_ID="$2"; shift 2 ;;
22
+ --name) need_arg "$1" "${2-}"; NAME="$2"; shift 2 ;;
23
+ --domains) need_arg "$1" "${2-}"; DOMAINS="$2"; shift 2 ;;
24
+ --mode) need_arg "$1" "${2-}"; MODE="$2"; shift 2 ;;
25
+ *) echo "widget-create: unknown arg $1" >&2; exit 2 ;;
26
+ esac
27
+ done
28
+
29
+ : "${CLOUDFLARE_API_TOKEN:?CLOUDFLARE_API_TOKEN must be set}"
30
+ API_TOKEN="$CLOUDFLARE_API_TOKEN"
31
+ unset CLOUDFLARE_API_TOKEN
32
+ [[ -n "$ACCOUNT_ID" ]] || { echo "widget-create: --account-id required" >&2; exit 2; }
33
+ [[ -n "$NAME" ]] || { echo "widget-create: --name required" >&2; exit 2; }
34
+ [[ -n "$DOMAINS" ]] || { echo "widget-create: --domains required" >&2; exit 2; }
35
+ [[ "$API_TOKEN" =~ ^[A-Za-z0-9_-]+$ ]] || {
36
+ echo "widget-create: CLOUDFLARE_API_TOKEN has an invalid format" >&2
37
+ exit 1
38
+ }
39
+ case "$MODE" in
40
+ managed|invisible|non-interactive) ;;
41
+ *) echo "widget-create: unsupported mode" >&2; exit 2 ;;
42
+ esac
43
+
44
+ for command_name in curl python3; do
45
+ command -v "$command_name" >/dev/null 2>&1 || {
46
+ echo "widget-create: $command_name is required" >&2
47
+ exit 1
48
+ }
49
+ done
50
+
51
+ BODY_JSON="$(python3 -I -c '
52
+ import json, sys
53
+ name, domains_csv, mode = sys.argv[1], sys.argv[2], sys.argv[3]
54
+ domains = [domain.strip() for domain in domains_csv.split(",") if domain.strip()]
55
+ if not domains:
56
+ raise SystemExit(2)
57
+ print(json.dumps({"name": name, "domains": domains, "mode": mode}))
58
+ ' "$NAME" "$DOMAINS" "$MODE")" || {
59
+ echo "widget-create: --domains must include at least one domain" >&2
60
+ exit 2
61
+ }
62
+ ACCOUNT_ENCODED="$(python3 -I -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1], safe=""))' "$ACCOUNT_ID")"
63
+
64
+ if ! API_RESPONSE="$(
65
+ printf 'header = "Authorization: Bearer %s"\n' "$API_TOKEN" |
66
+ curl --disable --config - --silent --show-error --write-out $'\n%{http_code}' -X POST \
67
+ "https://api.cloudflare.com/client/v4/accounts/$ACCOUNT_ENCODED/challenges/widgets" \
68
+ -H "Content-Type: application/json" \
69
+ --data "$BODY_JSON"
70
+ )"; then
71
+ echo "widget-create: Cloudflare API request failed" >&2
72
+ echo '{"status":"error","code":0,"message":"Cloudflare API request failed"}'
73
+ exit 1
74
+ fi
75
+ unset BODY_JSON
76
+ unset API_TOKEN
77
+
78
+ HTTP_CODE="${API_RESPONSE##*$'\n'}"
79
+ RESPONSE_BODY="${API_RESPONSE%$'\n'*}"
80
+ unset API_RESPONSE
81
+
82
+ if ! printf '%s' "$RESPONSE_BODY" | python3 -I -c '
83
+ import json
84
+ import re
85
+ import sys
86
+
87
+ http_code = sys.argv[1]
88
+ try:
89
+ data = json.load(sys.stdin)
90
+ except Exception:
91
+ print(f"widget-create: non-JSON response (HTTP {http_code})", file=sys.stderr)
92
+ print(json.dumps({"status":"error","code":0,"message":"Cloudflare API returned an invalid response"}))
93
+ raise SystemExit(1)
94
+
95
+ errors = data.get("errors") if isinstance(data, dict) else []
96
+ first = errors[0] if isinstance(errors, list) and errors and isinstance(errors[0], dict) else {}
97
+ code = first.get("code", 0)
98
+ if not isinstance(data, dict) or data.get("success") is not True:
99
+ print(f"widget-create: request failed (HTTP {http_code}, code={code})", file=sys.stderr)
100
+ print(json.dumps({"status":"error","code":code,"message":"Cloudflare API request failed"}))
101
+ raise SystemExit(1)
102
+
103
+ result = data.get("result")
104
+ sitekey = result.get("sitekey") if isinstance(result, dict) else None
105
+ secret = result.get("secret") if isinstance(result, dict) else None
106
+ if not (
107
+ isinstance(sitekey, str)
108
+ and re.fullmatch(r"\S{1,256}", sitekey)
109
+ and isinstance(secret, str)
110
+ and re.fullmatch(r"\S{1,1024}", secret)
111
+ ):
112
+ print("widget-create: API returned invalid widget credentials", file=sys.stderr)
113
+ print(json.dumps({"status":"error","code":0,"message":"Cloudflare API returned invalid widget credentials"}))
114
+ raise SystemExit(1)
115
+
116
+ print(json.dumps({"status":"ok","sitekey":sitekey,"secret":secret}))
117
+ ' "$HTTP_CODE"; then
118
+ unset RESPONSE_BODY
119
+ exit 1
120
+ fi
121
+ unset RESPONSE_BODY
@@ -0,0 +1,62 @@
1
+ # Skill validation cases
2
+
3
+ These cases match the assertions in the Turnstile Spin PRD. Run them after editing this skill to confirm an agent loading it can still execute the wizard end-to-end.
4
+
5
+ ## Test 1: Dummy Siteverify returns a structured error
6
+
7
+ Step 10's `validate.sh` sends a deliberately-invalid token directly to `challenges.cloudflare.com/turnstile/v0/siteverify` using the captured secret. The expected response is `success: false` with `error-codes: ["invalid-input-response"]`. Anything else means the secret is wrong or the widget is misconfigured.
8
+
9
+ ```sh
10
+ printf '%s' "$WIDGET_SECRET" |
11
+ python3 -I -c 'import sys,urllib.parse; print(urllib.parse.urlencode({"secret":sys.stdin.read(),"response":"XXXX.DUMMY.TOKEN.XXXX"}),end="")' |
12
+ curl --disable --fail --silent --show-error \
13
+ "https://challenges.cloudflare.com/turnstile/v0/siteverify" \
14
+ -H "Content-Type: application/x-www-form-urlencoded" \
15
+ --data-binary @- |
16
+ jq -e '.success == false and (.["error-codes"] | index("invalid-input-response"))'
17
+ ```
18
+
19
+ Expected exit code: 0.
20
+
21
+ ## Test 2: Metadata matches the sitekey and secret
22
+
23
+ ```sh
24
+ printf '%s' "$WIDGET_SECRET" |
25
+ scripts/validate.sh \
26
+ --sitekey "$SITEKEY" \
27
+ --account-id "$ACCOUNT_ID" \
28
+ --expected-domains '["example.com","localhost","127.0.0.1"]'
29
+ ```
30
+
31
+ Expected exit code: 0 for all valid clearance levels: `no_clearance`, `interactive`, `managed`, and `jschallenge`. A secret from another sitekey must fail.
32
+
33
+ ## Test 3: Runtime checks match the protected surface
34
+
35
+ Inspect every generated frontend and backend pair:
36
+
37
+ - The widget has a meaningful action such as `signup`, `login`, or `contact`.
38
+ - The backend requires the same `result.action` value.
39
+ - The backend requires `result.hostname` to match its deployment-specific frontend hostname allowlist.
40
+ - A production hostname allowlist does not contain `localhost` or `127.0.0.1`.
41
+
42
+ ## Test 4: Same-page retries reset the correct widget
43
+
44
+ Native forms that navigate do not need reset logic. For each same-page flow, verify that the code retains the widget ID returned by `turnstile.render()` and calls `turnstile.reset(widgetId)` after the request completes. Multiple protected surfaces must not share a widget ID or reset without an ID.
45
+
46
+ ## Test 5: Skill persists to a bundle location
47
+
48
+ After Step 11:
49
+
50
+ ```sh
51
+ test -f .claude/skills/turnstile-spin/SKILL.md \
52
+ || test -f .codex/skills/turnstile-spin/SKILL.md \
53
+ || test -f .opencode/skills/turnstile-spin/SKILL.md
54
+ ```
55
+
56
+ Expected exit code: 0. File-oriented rules targets install the hosted `prompt.md` directly instead of using `persist-skill.sh`.
57
+
58
+ ## Running all cases
59
+
60
+ The consuming test harness must pass the widget secret through standard input. It must not export it or place it in a command argument.
61
+
62
+ (`run-all.sh` is not bundled with this skill; the cases above are intended to be wired into the consuming agent's own test harness, or run by hand after a deploy.)
@@ -0,0 +1,127 @@
1
+ ---
2
+ name: workers-best-practices
3
+ description: Reviews and authors Cloudflare Workers code against production best practices. Load when writing new Workers, reviewing Worker code, configuring wrangler.jsonc, or checking for common Workers anti-patterns (streaming, floating promises, global state, secrets, bindings, observability). Biases towards retrieval from Cloudflare docs over pre-trained knowledge.
4
+ ---
5
+
6
+ Your knowledge of Cloudflare Workers APIs, types, and configuration may be outdated. **Prefer retrieval over pre-training** for any Workers code task — writing or reviewing.
7
+
8
+ ## Retrieval Sources
9
+
10
+ Fetch the **latest** versions before writing or reviewing Workers code. Do not rely on baked-in knowledge for API signatures, config fields, or binding shapes.
11
+
12
+ | Source | How to retrieve | Use for |
13
+ |--------|----------------|---------|
14
+ | Workers best practices | Fetch `https://developers.cloudflare.com/workers/best-practices/workers-best-practices/` | Canonical rules, patterns, anti-patterns |
15
+ | Workers types | See `references/review.md` for retrieval steps | API signatures, handler types, binding types |
16
+ | Wrangler config schema | `node_modules/wrangler/config-schema.json` | Config fields, binding shapes, allowed values |
17
+ | Cloudflare docs | Search tool or `https://developers.cloudflare.com/workers/` | API reference, compatibility dates/flags |
18
+
19
+ ## FIRST: Fetch Latest References
20
+
21
+ Before reviewing or writing Workers code, retrieve the current best practices page and relevant type definitions. If the project's `node_modules` has an older version, **prefer the latest published version**.
22
+
23
+ ```bash
24
+ # Fetch latest workers types
25
+ mkdir -p /tmp/workers-types-latest && \
26
+ npm pack @cloudflare/workers-types --pack-destination /tmp/workers-types-latest && \
27
+ tar -xzf /tmp/workers-types-latest/cloudflare-workers-types-*.tgz -C /tmp/workers-types-latest
28
+ # Types at /tmp/workers-types-latest/package/index.d.ts
29
+ ```
30
+
31
+ ## Reference Documentation
32
+
33
+ - `references/rules.md` — all best practice rules with code examples and anti-patterns
34
+ - `references/review.md` — type validation, config validation, binding access patterns, review process
35
+
36
+ ## Rules Quick Reference
37
+
38
+ ### Configuration
39
+
40
+ | Rule | Summary |
41
+ |------|---------|
42
+ | Compatibility date | Set `compatibility_date` to today on new projects; update periodically on existing ones |
43
+ | nodejs_compat | Enable the `nodejs_compat` flag — many libraries depend on Node.js built-ins |
44
+ | wrangler types | Run `wrangler types` to generate `Env` — never hand-write binding interfaces |
45
+ | Secrets | Use `wrangler secret put`, never hardcode secrets in config or source |
46
+ | wrangler.jsonc | Use JSONC config for non-secret settings — newer features are JSON-only |
47
+
48
+ ### Request & Response Handling
49
+
50
+ | Rule | Summary |
51
+ |------|---------|
52
+ | Streaming | Stream large/unknown payloads — never `await response.text()` on unbounded data |
53
+ | waitUntil | Use `ctx.waitUntil()` for post-response work; do not destructure `ctx` |
54
+
55
+ ### Architecture
56
+
57
+ | Rule | Summary |
58
+ |------|---------|
59
+ | Bindings over REST | Use in-process bindings (KV, R2, D1, Queues) — not the Cloudflare REST API |
60
+ | Queues & Workflows | Move async/background work off the critical path |
61
+ | Service bindings | Use service bindings for Worker-to-Worker calls — not public HTTP |
62
+ | Hyperdrive | Always use Hyperdrive for external PostgreSQL/MySQL connections |
63
+
64
+ ### Observability
65
+
66
+ | Rule | Summary |
67
+ |------|---------|
68
+ | Logs & Traces | Enable `observability` in config with `head_sampling_rate`; use structured JSON logging |
69
+
70
+ ### Code Patterns
71
+
72
+ | Rule | Summary |
73
+ |------|---------|
74
+ | No global request state | Never store request-scoped data in module-level variables |
75
+ | Floating promises | Every Promise must be `await`ed, `return`ed, `void`ed, or passed to `ctx.waitUntil()` |
76
+
77
+ ### Security
78
+
79
+ | Rule | Summary |
80
+ |------|---------|
81
+ | Web Crypto | Use `crypto.randomUUID()` / `crypto.getRandomValues()` — never `Math.random()` for security |
82
+ | No passThroughOnException | Use explicit try/catch with structured error responses |
83
+
84
+ ## Anti-Patterns to Flag
85
+
86
+ | Anti-pattern | Why it matters |
87
+ |-------------|----------------|
88
+ | `await response.text()` on unbounded data | Memory exhaustion — 128 MB limit |
89
+ | Hardcoded secrets in source or config | Credential leak via version control |
90
+ | `Math.random()` for tokens/IDs | Predictable, not cryptographically secure |
91
+ | Bare `fetch()` without `await` or `waitUntil` | Floating promise — dropped result, swallowed error |
92
+ | Module-level mutable variables for request state | Cross-request data leaks, stale state, I/O errors |
93
+ | Cloudflare REST API from inside a Worker | Unnecessary network hop, auth overhead, added latency |
94
+ | `ctx.passThroughOnException()` as error handling | Hides bugs, makes debugging impossible |
95
+ | Hand-written `Env` interface | Drifts from actual wrangler config bindings |
96
+ | Direct string comparison for secret values | Timing side-channel — use `crypto.subtle.timingSafeEqual` |
97
+ | Destructuring `ctx` (`const { waitUntil } = ctx`) | Loses `this` binding — throws "Illegal invocation" at runtime |
98
+ | `any` on `Env` or handler params | Defeats type safety for all binding access |
99
+ | `as unknown as T` double-cast | Hides real type incompatibilities — fix the design |
100
+ | `implements` on platform base classes (instead of `extends`) | Legacy — loses `this.ctx`, `this.env`. Applies to DurableObject, WorkerEntrypoint, Workflow |
101
+ | `env.X` inside platform base class | Should be `this.env.X` in classes extending DurableObject, WorkerEntrypoint, etc. |
102
+
103
+ ## Review Workflow
104
+
105
+ 1. **Retrieve** — fetch latest best practices page, workers types, and wrangler schema
106
+ 2. **Read full files** — not just diffs; context matters for binding access patterns
107
+ 3. **Check types** — binding access, handler signatures, no `any`, no unsafe casts (see `references/review.md`)
108
+ 4. **Check config** — compatibility_date, nodejs_compat, observability, secrets, binding-code consistency
109
+ 5. **Check patterns** — streaming, floating promises, global state, serialization boundaries
110
+ 6. **Check security** — crypto usage, secret handling, timing-safe comparisons, error handling
111
+ 7. **Validate with tools** — `npx tsc --noEmit`, lint for `no-floating-promises`
112
+ 8. **Reference rules** — see `references/rules.md` for each rule's correct pattern
113
+
114
+ ## Scope
115
+
116
+ This skill covers Workers-specific best practices and code review. For related topics:
117
+
118
+ - **Durable Objects**: load the `durable-objects` skill
119
+ - **Workflows**: see [Rules of Workflows](https://developers.cloudflare.com/workflows/build/rules-of-workflows/)
120
+ - **Wrangler CLI commands**: load the `wrangler` skill
121
+
122
+ ## Principles
123
+
124
+ - **Be certain.** Retrieve before flagging. If unsure about an API, config field, or pattern, fetch the docs first.
125
+ - **Provide evidence.** Reference line numbers, tool output, or docs links.
126
+ - **Focus on what developers will copy.** Workers code in examples and docs gets pasted into production.
127
+ - **Correctness over completeness.** A concise example that works beats a comprehensive one with errors.