Add Turnstile Spin skill#58
Merged
Merged
Conversation
Adds an agent skill at skills/turnstile-spin/ that scaffolds Cloudflare Turnstile end-to-end: scan the codebase, create the widget via the Cloudflare API, deploy the managed siteverify Worker (template bundled at skills/turnstile-spin/templates/worker/), write the frontend snippets, and validate the integration. Every emitted widget carries action='turnstile-spin-v1' for analytics segmentation. Mirrors developers.cloudflare.com/turnstile/spin/.
dmmulroy
reviewed
Jun 3, 2026
dmmulroy
left a comment
Collaborator
There was a problem hiding this comment.
some quick general feedback:
- We should try to keep the
SKILL.mdfile itself as close to or under 200 LoC if possible - Attempting to use skills and markdown for control flow, generally speaking, doesn't work well and it'd be better to offload to a deterministic shell/python script(s) if possible.
That being said - I'm happy to approve/merge if there are evals supporting this as a good design because it's all kinda hand wavey vibes for best practices anyways
Per maintainer feedback (cf cloudflare#58), SKILL.md is now a thin orchestration layer (~160 LoC, down from ~500) and the deterministic API calls + retry logic live in 6 helper scripts: - scripts/auth-probe.sh: token + scope + account-mismatch detection - scripts/widget-create.sh: Cloudflare API widget creation - scripts/worker-deploy.sh: degit + wrangler deploy + secret put + retry on name conflict - scripts/validate.sh: health + dummy-siteverify + hostname-domains end-to-end checks - scripts/persist-skill.sh: fetch canonical SKILL.md with HTTP 200 + frontmatter validation - scripts/fetch-secret.sh: recovery-flow secret retrieval via API Each script outputs structured JSON; the agent branches on the status field instead of parsing prose. The conversational flow, hard scope boundaries, recovery decision tree, and CAPTCHA-migration logic remain in SKILL.md since those are agent-behavior policy, not API mechanics.
juleslemee
pushed a commit
to juleslemee/cloudflare-docs
that referenced
this pull request
Jun 3, 2026
Sync to the refactored skill bundle. The MDX page's inlined paste-into-agent prompt now consists of the (much shorter) SKILL.md orchestration + a bootstrap section that writes the 6 helper scripts under /tmp/turnstile-spin-scripts/. Total prompt length is comparable to before; the architecture is cleaner because the agent now branches on structured JSON output from deterministic scripts instead of inline bash interpretation. Companion to cloudflare/skills#58.
added 4 commits
June 3, 2026 16:39
…et_secret failure handling - auth-probe.sh now handles multi-account tokens: emits multiple_accounts when >1 accounts and CLOUDFLARE_ACCOUNT_ID is unset, checks membership (not [0] equality) when the env var is set - auth-probe.sh probes GET /workers/scripts after GET /challenges/widgets so a token missing Account.Workers Scripts:Edit fails before the agent creates a widget (irreversible) and then tries to deploy - worker-deploy.sh makes set_secret failure fatal: previously the script could emit status:ok with the Worker deployed but TURNSTILE_SECRET_KEY unset - SKILL.md Step 3 documents the new statuses (multiple_accounts, missing_workers_scope) and the re-run loop after the user picks an account - SKILL.md Step 9 documents the set_secret_failed recovery path
Wrangler emits the deployed Worker URL on stdout (progress indicators on stderr). The script captured only stderr and then grepped that file for the URL, so successful deploys could still emit url_parse_failed. Capture both streams.
Addresses 14 issues found in an internal adversarial review: Scripts: - auth-probe.sh: reword Workers scope comment (best-effort proxy, not a guarantee that Read implies Edit). - worker-deploy.sh: URL parser falls back from workers.dev regex to a broader match for custom domains and Workers for Platforms. set_secret failure now captures wrangler stderr into a temp file and includes a detail field in the error JSON instead of swallowing the diagnostic. - fetch-secret.sh: emit clearance_level and domains so the recovery flow's pre-clearance check is implementable. Without these the contract was documentation theatre. - validate.sh: hit /health (not /); the diagnostic was lying about the path. Also assert _worker metadata is present in the dummy siteverify response (Step 7b promised this; the script never checked). - persist-skill.sh: install canonical bundle (SKILL.md + scripts/ + references/ + templates/) via degit from cloudflare/skills instead of writing the inlined bootstrap index.md. Persisted skills now re-run without the /tmp/ bootstrap path. SKILL.md: - Recovery flow uses fetch-secret.sh's new clearance_level and domains fields. Drops the ?widget=<id> URL trigger (nothing parsed it; it was documentation theatre). Recovery is now invoked verbally. - Edge case table replaces $WORKER_NAME env var references with the worker_name field returned by worker-deploy.sh. - Adds explicit set_secret_failed recovery row. Worker template: - parseBody accepts the reCAPTCHA-style `response` field name alongside `token` and `cf-turnstile-response`, so backends migrated from reCAPTCHA/hCaptcha work without backend code changes (drop the secret field, keep the rest).
…rk hint - worker-deploy.sh now uses openssl rand -hex 3 for the name-conflict retry suffix, falling back to the previous date tail if openssl is absent. The docs prose already called this a hash; the script body now matches. - SKILL.md Step 3's parallel-work hint is conditional on option 3 (paste in chat). Options 1 and 2 restart the session and lose any pre-fetched scan state, so the agent no longer pre-fetches in those cases.
dmmulroy
approved these changes
Jun 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds an agent skill at
skills/turnstile-spin/that scaffolds Cloudflare Turnstile end-to-end in one prompt: detect the project's stack, create the widget via the Cloudflare API, deploy a managed siteverify Worker into the customer's account (from the bundled template atskills/turnstile-spin/templates/worker/), write the frontend snippets, and validate the integration before reporting success.Every emitted widget carries
data-action="turnstile-spin-v1"for analytics segmentation. Mirrors the canonical docs at developers.cloudflare.com/turnstile/spin (also being PR'd againstcloudflare/cloudflare-docs).What's in the bundle
SKILL.md— full agent script: when to load, hard scope boundaries, recovery flow, 9-step wizard (auth + scope probe, codebase scan, user confirmation, widget create, Worker deploy, frontend edits, validation, persist), edge cases.templates/worker/— Worker source the agent deploys (5 TS files +wrangler.toml+package.json+public/post-deploy.html).references/— per-framework snippets (vanilla HTML, Next.js App + Pages, Astro, SvelteKit, Hugo).tests/— validation runbook.README.md— project context.Why this skill
Turnstile activation has an 8.4% completion rate today. Most accounts render the widget but never wire
siteverifyon the backend, so requests bypass verification while the widget gives a false sense of protection. Spin closes that gap with a single agent prompt.Internal context
Tier 3 launch tracked in NC-8209. PRD: https://jira.cfdata.org/browse/NC-8209