cloudflare-workers-publish
Deploy static HTML files to Cloudflare Workers with 1Password credential management.
What this skill does
# Cloudflare Workers Publish
Deploy static HTML files (Bokeh charts, dashboards, reports) to Cloudflare Workers with Static Assets, using 1Password for credential management.
**Scope**: Static-only deployments on workers.dev. No dynamic Workers, no R2 object storage.
**Prerequisite**: 1Password CLI (`brew install 1password-cli`) + Node.js (`npx wrangler`)
---
> **Self-Evolving Skill**: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
## When to Use This Skill
- Publishing HTML files to a public URL (too large for GitHub)
- Setting up a new Cloudflare Workers static site
- Troubleshooting a failed Cloudflare deploy
- Rotating Cloudflare API tokens in 1Password
**Do NOT use for**: Dynamic Workers (JavaScript/TypeScript logic), Cloudflare Pages (deprecated April 2025 - CFW-01), R2 object storage, or custom domains (advanced setup not covered).
---
## Architecture
```
Local project/
├── results/published/ # Deploy root (contains wrangler.toml)
│ ├── wrangler.toml # Workers config (name + assets)
│ ├── index.html # Auto-generated directory listing
│ └── gen800/ # Subdirectories with HTML files
│ └── XRPUSDT_750/
│ └── equity_plot.html # 13MB Bokeh chart
└── scripts/
└── publish_findings.sh # Deploy script (3 phases)
Credential flow:
1Password (Claude Automation vault)
├── account_id (TEXT) → CLOUDFLARE_ACCOUNT_ID env var
└── credential (CONCEALED) → CLOUDFLARE_API_TOKEN env var
↓
npx wrangler deploy
↓
https://{name}.{slug}.workers.dev/
```
---
## TodoWrite Task Templates
### Template A - New Static Site (First-Time Setup)
```
1. [Preflight] Verify Node.js and 1Password CLI installed
2. [Preflight] Create Cloudflare API token (Workers Scripts Edit permission)
3. [Execute] Pre-provision 1Password item in Claude Automation vault (biometric)
4. [Execute] Store token + account ID in 1Password item fields
5. [Execute] Create publish directory with wrangler.toml (3 fields only)
6. [Execute] Create deploy script from skill template (parameterize 4 vars)
7. [Execute] Create mise task wrapper in .mise/tasks/publish.toml
8. [Execute] Add .wrangler/ to .gitignore
9. [Execute] Add LFS tracking for large HTML files in .gitattributes
10. [Verify] Enable workers.dev subdomain in Cloudflare dashboard
11. [Verify] Run first deploy and verify URL in browser (NOT curl)
12. [Verify] Document the workers.dev URL in project docs
```
### Template B - Add Files to Existing Published Site
```
1. [Preflight] Verify files are real content, not LFS pointers (head -1)
2. [Execute] Copy HTML files to published/{generation}/{symbol_threshold}/
3. [Execute] Run deploy script (index.html auto-regenerates)
4. [Verify] Verify new files appear at workers.dev URL in browser
```
### Template C - New Worker (New Subdomain/Project)
```
1. [Preflight] Choose worker name ({name}.{slug}.workers.dev)
2. [Execute] Create 1Password item OR reuse existing Cloudflare credentials
3. [Execute] Create wrangler.toml with chosen name and today's date
4. [Execute] Create parameterized deploy script from skill template
5. [Execute] Create mise task wrapper
6. [Verify] Deploy and discover actual workers.dev URL via wrangler output
```
### Template D - Rotate Cloudflare API Token
```
1. [Execute] Create new API token in Cloudflare dashboard (Workers Scripts Edit)
2. [Execute] Update 1Password item credential field (biometric required)
3. [Verify] Run deploy script to verify new token works
4. [Execute] Revoke old token in Cloudflare dashboard
```
### Template E - Troubleshoot Failed Deploy
```
1. Is wrangler.toml in current directory? (CFW-10)
2. Are credentials populated? Print first 8 chars of account ID
3. Is --reveal present for CONCEALED fields? (CFW-03)
4. Is workers.dev subdomain registered in CF dashboard? (CFW-07)
5. Does token have Workers Scripts Edit permission? (CFW-11)
6. Are HTML files real content or LFS pointers? head -1 file (CFW-12)
7. SSL handshake error? Verify in browser, not curl (CFW-08)
8. Is npx wrangler installed? npx wrangler --version
```
---
## Workflow: First-Time Setup
### Phase 1: Create Cloudflare API Token
1. Go to <https://dash.cloudflare.com/profile/api-tokens>
2. Click **Create Token** > **Custom token**
3. Set permissions: **Account** > **Workers Scripts** > **Edit** (CFW-11)
4. Account Resources: **Include** > your account
5. Copy the token (shown only once)
### Phase 2: Provision 1Password Credentials
**CRITICAL (CFW-02)**: 1Password service accounts can only READ items. They CANNOT CREATE new items. Create the item manually first.
See [1Password setup guide](./references/onep-credential-setup.md) for step-by-step instructions.
After provisioning, the item should have:
| Field | Type | `--reveal` | Content |
| ------------ | --------- | ---------- | ------------------ |
| `account_id` | TEXT | No | Cloudflare acct ID |
| `credential` | CONCEALED | **YES** | API token |
### Phase 3: Create wrangler.toml
See [wrangler setup guide](./references/wrangler-setup.md).
```toml
# Minimal Workers Static Assets config (CFW-09)
name = "my-project-name"
compatibility_date = "2026-02-18"
[assets]
directory = "."
```
### Phase 4: Create Deploy Script
Copy the bundled template and edit the 4 config variables:
```bash
cp "$(skill-path)/scripts/publish_static.sh" scripts/publish_myproject.sh
# Edit: PUBLISH_DIR, OP_ITEM_ID, SITE_TITLE, PROJECT_URL
```
Or reference the working implementation: `rangebar-patterns/scripts/publish_findings.sh`
### Phase 5: Create mise Task
```toml
# .mise/tasks/publish.toml (CFW-13: bash in .sh file, not inline TOML)
["publish:site"]
description = "Deploy published files to Cloudflare Workers (static)"
run = "bash scripts/publish_myproject.sh"
```
Add to `.mise.toml` `[task_config] includes`:
```toml
[task_config]
includes = [
".mise/tasks/publish.toml",
]
```
### Phase 6: Git Hygiene
**.gitignore**:
```
# Wrangler temp files (Cloudflare Workers deploy)
.wrangler/
results/published/.wrangler/
```
**.gitattributes** (for large HTML files):
```
results/published/**/*.html filter=lfs diff=lfs merge=lfs -text
```
### Phase 7: Enable workers.dev Subdomain (CFW-07)
First-time Cloudflare accounts must enable the workers.dev route:
1. Go to <https://dash.cloudflare.com> > **Workers & Pages**
2. Enable workers.dev subdomain
**The subdomain is NOT predictable** (CFW-06). Discover yours after deploy:
```bash
npx wrangler whoami
```
### Phase 8: Deploy and Verify
```bash
mise run publish:site
```
**Verify in BROWSER, not curl** (CFW-08). macOS LibreSSL can fail TLS handshake with Cloudflare but browsers handle it fine.
---
## Anti-Patterns Summary
Full details with code examples: [references/anti-patterns.md](./references/anti-patterns.md)
| ID | Severity | Gotcha | Fix |
| ------ | -------- | ---------------------------------------- | --------------------------------------------- |
| CFW-01 | HIGH | Cloudflare Pages deprecated (April 2025) | Use Workers with Static Assets |
| CFW-02 | HIGH | 1P service account creating items | Pre-provision via biometric/web UI |
| CFW-03 | HIGH | Missing `--reveal` for CONCEALED fields | Always pass `--reveal` for API tokens |
| CFW-04 | MEDIUM | SC2155 `export VAR=$(cmd)` | Split: `VAR=$(cmd)` then `export VAR` |
| CFW-05 | LOW | Bash 4+ `${var^^}` on macOS | Use `tr '[:lower:]' '[:upper:]'` |
| CFW-06 | MEDIUM | Assuming workers.dev URL foRelated in Web Dev
generating-lwc-components
IncludedLightning Web Components with PICKLES methodology and 165-point scoring. Use this skill when the user creates or edits LWC components, builds wire service patterns, or writes Jest tests for LWC. TRIGGER when: user creates/edits LWC components, touches lwc/**/*.js, .html, .css, .js-meta.xml files, or asks about wire service, SLDS, or Jest LWC tests. DO NOT TRIGGER when: Apex classes (use generating-apex), Aura components, or Visualforce.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Set up queries with useQuery, mutations with useMutation, configure QueryClient caching strategies, implement optimistic updates, and handle infinite scroll with useInfiniteQuery. Use when: setting up data fetching in React projects, migrating from v4 to v5, or fixing object syntax required errors, query callbacks removed issues, cacheTime renamed to gcTime, isPending vs isLoading confusion, keepPreviousData removed problems.
document-processor-api
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
nutrient-document-processing
IncludedProcess documents with Nutrient DWS. Use when the user wants to generate PDFs from HTML or URLs, convert Office/images/PDFs, assemble or split packets, OCR scans, extract text/tables/key-value pairs, redact PII, watermark, sign, fill forms, optimize PDFs, or produce compliance outputs like PDF/A or PDF/UA. Triggers include convert to PDF, merge these PDFs, OCR this scan, extract tables, redact PII, sign this PDF, make this PDF/A, or linearize for web delivery.
tanstack-query
IncludedManage server state in React with TanStack Query v5. Covers useMutationState, simplified optimistic updates, throwOnError, network mode (offline/PWA), and infiniteQueryOptions. Use when setting up data fetching, fixing v4→v5 migration errors (object syntax, gcTime, isPending, keepPreviousData), or debugging SSR/hydration issues with streaming server components.
accelint-nextjs-best-practices
IncludedNext.js performance optimization and best practices. Use when writing Next.js code (App Router or Pages Router); implementing Server Components, Server Actions, or API routes; optimizing RSC serialization, data fetching, or server-side rendering; reviewing Next.js code for performance issues; fixing authentication in Server Actions; or implementing Suspense boundaries, parallel data fetching, or request deduplication.