Skip to content

Add Turnstile Spin skill#58

Merged
dmmulroy merged 6 commits into
cloudflare:mainfrom
juleslemee:add-turnstile-spin-skill
Jun 4, 2026
Merged

Add Turnstile Spin skill#58
dmmulroy merged 6 commits into
cloudflare:mainfrom
juleslemee:add-turnstile-spin-skill

Conversation

@juleslemee

Copy link
Copy Markdown
Contributor

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 at skills/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 against cloudflare/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 siteverify on 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

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 dmmulroy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some quick general feedback:

  • We should try to keep the SKILL.md file 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.
jules lemee 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 dmmulroy merged commit 7548066 into cloudflare:main Jun 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants