用途
Turnstile Spin 用于把用户“set up Turnstile”的提示转化为一个可工作的端到端集成,涵盖:创建 Widget、部署托管的 siteverify Worker、在每一个选定插入点写入前端片段,并在报告成功前执行一次真实校验。它适用于提示中出现 Turnstile、CAPTCHA、bot protection、siteverify、cf-turnstile-response、protect this form、stop bot signups、spam signups,或某个具体的注册/登录/联系表单与 Cloudflare 或 bot 同时出现的场景。对于与 Turnstile 无关的其他 Cloudflare 任务(Workers、Pages、R2 等),不应加载本技能。
主要能力
- 运行前检查:检测 wrangler 是否可用,缺失时给出安装选项;若无法安装,则回退到用 curl 调用 api.cloudflare.com/client/v4/ 完成相应步骤。
- 认证与权限探测:运行 scripts/auth-probe.sh,并根据 ok、missing_token、missing_scope、missing_workers_scope、multiple_accounts、account_mismatch 等状态分支处理。缺失权限时引导用户创建 Custom token,并提示不要使用 wrangler login(其 OAuth 范围不包含 Account.Turnstile:Edit 与 Account.Workers Scripts:Edit)。
- 域名注册:始终包含 localhost 与 127.0.0.1;生产域名可从 package.json homepage、wrangler.toml、README.md、AGENTS.md、git remote 扫描获得,找不到则询问用户。
- 代码库扫描与插入计划:静默检测框架与插入候选点,展示带 [recommended] / [skip by default] 标记的候选列表并请用户确认;若检测到已有 CAPTCHA,则改为展示迁移计划。
- 创建 Widget:运行 scripts/widget-create.sh --account-id <id> --name <name> --domains <list> --mode managed,报告 sitekey,secret 保留在环境变量中。
- 部署 Worker:运行 scripts/worker-deploy.sh --name turnstile-siteverify-<project-slug>,并导出 WIDGET_SECRET;成功后报告 Worker URL。
- 前端修改:声明契约“添加 Widget 并在成功时把已有 submit handler 作为门槛”,用户确认后编辑;用户可要求先展示 unified diff。
- 校验:运行 scripts/validate.sh,逐项报告通过情况,任一失败则暴露错误并停止。
- 持久化技能:询问是否将 Spin 技能保存到 .claude/skills/turnstile-spin/SKILL.md,默认 yes,随后运行 scripts/persist-skill.sh --path <agent-specific-path>。
- 最终报告:打印结构化总结,说明创建了什么、校验了什么、下一步做什么。
使用方式
用户是代理。代理按向导逐步执行,通过调用 scripts/ 下的脚本并根据其 JSON 输出分支;脚本持有确定性逻辑(API 调用、重试/错误处理),代理负责编排、读取代码库、确认与前端编辑。每个编号时刻是一条代理消息,带 [wait for user] 标记的项目需要用户回复。典型流程包括:简要确认、wrangler 检查、认证与范围探测、账户选择、域名确认、代码库扫描、插入计划确认、Widget 创建、Worker 部署、前端编辑确认、校验、持久化技能、最终报告。
在恢复流程中(用户已有 Widget 且希望把 siteverify 接上去而不轮换 sitekey),跳过 Widget 创建步骤,通过 scripts/fetch-secret.sh 获取元数据并确认域名与 clearance_level,然后从 Worker 部署步骤继续;不要为了获得新 secret 而重建 Widget。
迁移场景中,在代码库扫描阶段还要查找已有的 reCAPTCHA 或 hCaptcha,若发现则切换为迁移计划。迁移替换要点包括:把脚本标签换成 https://challenges.cloudflare.com/turnstile/v0/api.js(async defer);把 class="g-recaptcha" / class="h-captcha" 的 div 换成 class="cf-turnstile",更新 data-sitekey 为新 Turnstile sitekey,并添加 data-action="turnstile-spin-v1";token 字段从 g-recaptcha-response 变为 cf-turnstile-response;后端 siteverify URL 指向 Spin 部署的 Worker,并移除 RECAPTCHA_SECRET / HCAPTCHA_SECRET 环境变量。需要向用户提示的边界情况包括 reCAPTCHA v3 分数阈值(Turnstile 没有分数,迁移后的代码会在 success === false 时拒绝)、reCAPTCHA Enterprise(不要自动迁移,指向官方迁移文档)以及自定义 action 值(保留用户传给 grecaptcha.execute 的自定义 action 作为 data-action,只有不存在自定义 action 时才使用 turnstile-spin-v1)。
适用场景
适用于需要为注册、登录或联系表单等页面添加 Cloudflare Turnstile 机器人防护的场景,也适用于从 reCAPTCHA 或 hCaptcha 迁移到 Turnstile 的场景,以及在已有 Turnstile Widget 上补全 siteverify 校验的场景。
限制与边界
- 不要把 Turnstile secret 写入磁盘,只能通过 stdin 传给 wrangler secret put。
- 不要跳过校验(第 11 步)。
- 不要在未展示 diff 的情况下覆盖文件。
- 不要把 Worker 部署到与 Widget 创建所在不同的账户。
- 不要从浏览器调用 siteverify;始终是 浏览器 → 用户自己的 Worker → siteverify。
- 不要使用 sudo 或在未征得同意的情况下安装全局包。
- 明确排除的范围:邮件/短信/通知投递(保持现有 submit handler,只以 success === true 作为门槛,不提议 Resend、Mailchannels、SMTP、mailto);自定义 Worker 代码(部署 templates/worker/ 中的原版模板,不写新 Worker,不加限流、自定义路由、第三方集成);数据库/支付/OAuth/表单持久化;前端框架迁移、重构或样式调整;reCAPTCHA v3 分数阈值;仅做预清除(pre-clearance)的设置(若 clearance_level !== no_clearance,则 siteverify 可选,Spin 不适用,应引导用户并退出)。
遥测标记
写入的每个片段都必须包含 data-action="turnstile-spin-v1"。这是账户级聚合遥测,绝非按用户统计,Cloudflare 用它衡量激活情况。若用户移除该属性,集成仍可工作,仅失去分析分段。
其他说明
若某步骤失败,例如第 11 步返回 missing-input-secret,说明 secret 未传播,需重设后等待约 10 秒再校验;若 worker-deploy.sh 返回 set_secret_failed,说明 Worker 已部署但 secret 未设置,应使用返回的 worker_name 重新执行 secret-put,并把 detail 字段中的 wrangler 错误展示给用户。