cloudflare-pages-ops
Skill2 starsChanged 3 months agoMITView on GitHub
Use when driving Cloudflare Pages web-hosting directly — creating a Pages project, deploying a build, adding a custom domain, reading deployment status, and listing/inspecting projects/deployments/domains. CLI-first on the Wrangler CLI (which reads CLOUDFLARE_API_TOKEN + CLOUDFLARE_ACCOUNT_ID and runs headlessly — never `wrangler login`) with a REST fallback on Cloudflare's official API at https://api.cloudflare.com/client/v4 (auth Authorization: Bearer <scoped token>; every path account-scoped under /accounts/{account_id}/pages/...). Resolves the Pages REST operations from a bundled OpenAPI slice via an endpoint index + a $ref-resolver, with the response envelope, deploy stage machine, and multipart-deploy + Direct-Upload-vs-Git caveats handled explicitly. Consumes caller-injected credentials (account_id from context + a token by variable name) — it does not provision them; the token is read only by the Wrangler/curl subprocess, never printed. Static/JAMstack + serverless, not full-stack container apps.
- Reads credentials
- Installs packages
- Commits and pushes
In this repository77 other files it gives its agents.
- alembicSkill
- atlassian-rest-opsSkill
- authoring-api-referenceSkill
- authoring-api-specSkill
- authoring-architecture-docSkill
- authoring-data-modelSkill
- authoring-design-systemSkill
- authoring-developer-guideSkill
- authoring-feature-specSkill
- authoring-hi-fiSkill
- authoring-prdSkill
- authoring-release-runbookSkill
- authoring-technical-designSkill
- authoring-test-planSkill
- authoring-user-flowsSkill
- authoring-user-guideSkill
- authoring-wireframesSkill
- biomeSkill
- code-prior-art-surveySkill
- content-template-gatewaySkill
- design-reviewSkill
- external-content-sanitizerSkill
- github-cli-opsSkill
- integrations-prior-art-surveySkill
- jenkins-rest-opsSkill
- market-competitive-prior-art-surveySkill
- ml-prior-art-surveySkill
- motion-reactSkill
- netlify-opsSkill
- openapi-ts-clientSkill
- platform-ecosystem-prior-art-surveySkill
- polyglot-git-hooksSkill
- project-document-discoverySkill
- pydantic-v2Skill
- python-monorepo-architectureSkill
- react-component-testingSkill
- regulatory-prior-art-surveySkill
- rest-api-designSkill
- reviewing-api-referenceSkill
- reviewing-api-specSkill
- reviewing-architecture-docSkill
- reviewing-code-prior-art-surveySkill
- reviewing-data-modelSkill
- reviewing-design-systemSkill
- reviewing-developer-guideSkill
- reviewing-document-discoverySkill
- reviewing-document-setSkill
- reviewing-feature-specSkill
- reviewing-hi-fiSkill
- reviewing-integrations-prior-art-surveySkill
- reviewing-market-competitive-prior-art-surveySkill
- reviewing-ml-prior-art-surveySkill
- reviewing-platform-ecosystem-prior-art-surveySkill
- reviewing-prdSkill
- reviewing-regulatory-prior-art-surveySkill
- reviewing-release-runbookSkill
- reviewing-scale-prior-art-surveySkill
- reviewing-security-prior-art-surveySkill
- reviewing-technical-designSkill
- reviewing-test-planSkill
- The first 60 shown.
The file
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 1 is distinctive, and 3 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈1
Distinctive · estimate
This author's own choices. Worth a look.
3
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 90
Check the envelope, not just HTTP: Every REST response is {success, errors, messages, result} — a 200 can carry success: false.
- Distinctive: line 109
Use REST for custom domains + per-deployment status (Wrangler has no command for those).
- Very specific: line 125
Echoing the token: Never echo $CLOUDFLARE_API_TOKEN, never paste it into a printed command, never write its value to a file.
- Very specific: line 129
Loading the whole spec: Don't cat the bundled slice — scan the index, resolve one op.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
cloudflare-pages-ops
Overview
This skill lets an agent perform Cloudflare Pages operations CLI-first (the Wrangler CLI) with a REST fallback on Cloudflare's official API — no SDK. Wrangler is the ergonomic common path (create a project, deploy a build directory); the REST API is the comprehensive long tail (custom domains, deployment status, project/deployment/domain management), grounded on a bundled Pages OpenAPI slice via an endpoint index + a $ref-resolver so coverage never loads the spec into context. The agent consumes the caller-injected account_id + token, picks the Wrangler command or REST operation, runs it, and parses the result. It drives Cloudflare Pages' static/JAMstack + serverless surface — not full-stack container hosting.
When to activate
- ✅ Creating a Pages project, or deploying a build directory to one (Direct Upload).
- ✅ Adding/listing a custom domain, or reading deployment status (the stage machine).
- ✅ Listing/inspecting/deleting projects, deployments (retry/rollback), or domains.
Do NOT activate when:
- You need full-stack container/app hosting (Render, Fly.io, Railway, Vercel SSR-as-PaaS) — Cloudflare Pages here is a static/JAMstack + serverless host only.
- You only need credential setup — credentials are provided by the caller; this skill does not provision or resolve them, and never runs
wrangler login(seereferences/credentials.md).
Workflow
Step 1 — Receive the injected credentials
The caller has already resolved the account and injected what this operation needs — consume it; do not look for a record or log in. You receive from context:
account_id(a non-secret plain context value — exported asCLOUDFLARE_ACCOUNT_IDand interpolated into the REST path) and the capability (web-hosting).- The token, by an ordered load rule the context carries the variable NAME for: the project-level
.envvalue if that file exists and defines the var, else the environment variable of that name (project.envfirst). The token value is never in context prose — only its variable name. Perform no scope resolution or directory walk; it is project.env, not.envrc.
Bridge into CLOUDFLARE_API_TOKEN (Bearer) + CLOUDFLARE_ACCOUNT_ID. Never wrangler login. Full contract: references/credentials.md.
Step 2 — Pick the common path (Wrangler) or the long tail (REST)
- Wrangler (common path): scan
assets/cli-index.mdforpages project create,pages deploy,pages project list,pages deployment list/tail. Detail:references/wrangler.md. - REST (long tail): scan
assets/endpoint-index.md, thenpython3 scripts/endpoint.py <operationId>to resolve params + body + a curl skeleton. Detail:references/rest-api.md. Never load the bundled slice into context.
Step 3 — Run it
The four bundled scripts cover the priority ops:
create-project.sh <name> [branch]—wrangler pages project create … --production-branch …(Direct-Upload project).deploy.sh <project> <dir> [branch]—wrangler pages deploy … --commit-dirty true(uploads the built dir).add-custom-domain.sh <project> <domain>— RESTPOST …/domains(Wrangler has no domain command).deployment-status.sh <project> <deployment-id>— RESTget-deployment-info(the stage machine).
For anything else: Wrangler command from cli-index.md, or a curl against the resolved REST op.
Step 4 — Handle the response
- Get the deployment id first.
deploy.sh(Wrangler) prints only text, not the iddeployment-status.shneeds — capture it withwrangler pages deployment list --project-name <name> --json | jq -r '.[0].Id'(deployment list --jsonreturns capitalized table keys, so.Id, not.id). - Deploys are async + staged. A deployment moves through
latest_stage.name∈ queued/initialize/clone_repo/build/deploy withstatus∈ success/idle/active/failure/canceled. Polldeployment-status.shuntil thedeploystage reachesstatus: success(done) or any stage hitsfailure. - Check the envelope, not just HTTP. Every REST response is
{success, errors, messages, result}— a200can carrysuccess: false; readerrors[].code/message. - Custom domain ≠ DNS. Adding a domain needs it on a Cloudflare zone with DNS pointed at the project.
- Limits: 1,200 requests / 5 min per user → HTTP 429.
Rules
Hard rules (never violate):
- Never
wrangler login. Auth is the injectedCLOUDFLARE_API_TOKEN+CLOUDFLARE_ACCOUNT_ID; Wrangler runs headlessly. A missing token/account_id is a hard caller error, not a cue to log in. - Never read or print the token value. Reference it only as
$CLOUDFLARE_API_TOKEN(env /Bearer); the subprocess reads it from the environment. The token lives only in.env(gitignored) or the environment.account_idis non-secret context, not a secret. - Deploy a directory with Wrangler, not curl. The REST
create-deploymentbody ismultipart/form-data; never hand-roll a directory deploy overcurl. - Resolve before constructing a REST call. Build a body/params from the
$ref-resolved schema (endpoint.py) — never from a guessed field set. - Check
success, not just HTTP. A200withsuccess:falseis a failure — readerrors[]. - This skill never writes credentials. Credentials are provided by the caller.
Preferences (override-able):
- Pass
--jsontowrangler pages project list/deployment listfor machine output. --commit-dirty trueon a deploy from an uncommitted tree.- Use REST for custom domains + per-deployment status (Wrangler has no command for those).
Gotchas
- Don't log in. Reaching for
wrangler loginwhen the token "isn't working" violates the contract — a bad token/account_id is an error to surface, not a login to perform. CLOUDFLARE_ACCOUNT_IDis required headlessly. Wrangler needs it alongside the token; a missing account id is the most common CI failure.- Deploy is multipart. The REST deploy endpoint is
multipart/form-data(binary parts) — usewrangler pages deploy <dir>; don't JSON-POST a deploy. - Direct Upload vs Git-connected.
wrangler pages deployworks on Direct-Upload projects; a Git-connected project deploys ongit pushand Wrangler won't deploy it. (A Direct-Upload project can't later switch to Git.) - The envelope hides failures.
{success:false}can ride a200; always check it. - Custom domain needs DNS — the API won't create it.
add-custom-domain.shonly registers the domain (status: initializing); the RESTPOST /domainsdoes NOT create the DNS record, even on a same-account zone (only the dashboard auto-creates it). Validation stays pending ("CNAME record not set") until aCNAME <domain> -> <project>.pages.devexists on the zone — and a Pages-scoped token can't create that record (needs Zone DNS:Edit), so the caller adds it out-of-band. pages deploy <dir>uploads, doesn't build. Pass the already-built output dir (dist/build/…); Wrangler doesn't run your framework build.- Rate limit. 1,200 req/5 min per user, cumulative — back off on 429.
Anti-patterns
- Running
wrangler login. Forbidden — the contract injects the token; never resolve your own auth or prompt the user to log in. - Echoing the token. Never
echo $CLOUDFLARE_API_TOKEN, never paste it into a printed command, never write its value to a file. Reference the env var only. (account_idis non-secret and may appear in paths.) - Hand-rolling a directory deploy over REST. The deploy is multipart — use Wrangler.
- Guessing a REST body. Resolve
create-project/add-domainwithendpoint.py— don't hand-write a body from memory. - Trusting the HTTP status alone. A
200withsuccess:falseis a failure — readerrors[]. - Loading the whole spec. Don't
catthe bundled slice — scan the index, resolve one op. (And never fetch the 10 MB full Cloudflare OpenAPI.)
Output
This skill produces CLI/API side effects (the requested Cloudflare Pages operation) and returns the parsed result to the calling agent. It writes no files of its own (it only consumes the caller-injected credentials). For a deploy it reports the deployment id + URL + terminal stage status; for a project it reports the project name/id + URL; for reads it returns the requested result. The abstract consumer is the calling agent (or a sub-agent) that needs the web-hosting operation performed; secrets never enter that output.
Related
references/credentials.md— the credential contract (account_idfrom context + token-by-name →CLOUDFLARE_API_TOKEN, the ordered load rule, no-login).references/wrangler.md— the Wrangler Pages surface + what it doesn't cover.references/rest-api.md— the REST long tail, the envelope, the deploy stage machine, limits.- This is the CLI-first sibling of
github-cli-opsand the OpenAPI-grounded sibling ofatlassian-rest-ops/netlify-ops, under the per-provider service-skill pattern.
Progressive disclosure
Heavy content lives in subfolders, loaded only on demand:
references/credentials.md— caller-injectedaccount_id+ token, the ordered load rule, the Bearer bridge, no-login. Load in Step 1.references/wrangler.md— the Wrangler commands + the Direct-Upload-vs-Git rule + CLI gotchas. Load in Steps 2–3.references/rest-api.md— the REST pattern, the priority-op table, the envelope, the deploy stage machine, limits. Load for the REST tail.references/sources.md— provenance (the bundled Pages slice + official docs) + the "confirm live" items.assets/cli-index.md— the Wrangler quick command list (Step 2).assets/endpoint-index.md— one line per REST operation (Step 2).assets/cloudflare-pages-openapi.json— the bundled Pages OpenAPI slice (queried via the resolver, never loaded wholesale).scripts/endpoint.py+.validation.md— thepython3$ref-resolver (Step 2).scripts/{create-project,deploy,add-custom-domain,deployment-status}.sh+.validation.md— four validated priority-op scripts.
Standalone usage (optional, not required)
This is a convenience for a human running the skill by hand outside an agent-flow — it is not a dependency of the skill. The skill's normative contract is caller-injection (Step 1); this appendix is only the manual-operator bridge.
To run by hand, create a scoped token (My Profile → API Tokens → Create Token, Cloudflare Pages: Edit), store its value in a gitignored .env, install Wrangler (npm i -g wrangler), then populate the vars yourself:
set -a; source .env; set +a # loads $CLOUDFLARE_PAGES_TOKEN, never prints it
export CLOUDFLARE_ACCOUNT_ID="<account-id>"
export CLOUDFLARE_API_TOKEN="$CLOUDFLARE_PAGES_TOKEN"
bash scripts/create-project.sh my-site main
bash scripts/deploy.sh my-site ./distThe token value is referenced by name only, never printed. Prefer a revocable, short-lived scoped token.
Body budget
description≤ 1,024 chars (agentskills.io cap).- Body ≤ ~500 lines / 5,000 tokens — kept in context every turn; Wrangler/REST detail lives in
references/. assets/cloudflare-pages-openapi.jsonis the Pages slice (queried on disk, never loaded into context).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

