一键导入
cloudflare
Cloudflare Workers, Pages, D1, R2, KV, Durable Objects, DNS, and edge computing patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Cloudflare Workers, Pages, D1, R2, KV, Durable Objects, DNS, and edge computing patterns
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Unified design foundations — design system architecture, tokens, component specs, visual principles, creative vision, figma integration, plus brand design system loader (66 real brands via DESIGN.md). Absorbs design, design-system, design-systems, design-principles, design-router, creative-vision, figma, design-md.
Render, summarize, and present markdown documents and structured content in multiple output modes
Ultra UI skill - combines Google's DESIGN.md spec (machine-readable design tokens) with the ui-ux-pro-max knowledge base (91 styles, 161 palettes, 73 font pairings, 161 products, 104 UX guidelines, 25 chart types). Generates lint-clean DESIGN.md files, validates token references and WCAG contrast, exports Tailwind/DTCG tokens, and diffs design systems version-over-version.
Initialize UltraThink capabilities in the current project directory
Org-Bench Google-bipartite winning mechanism — the 4-section design-doc gate that every non-trivial change passes through. Use when the Director defines new work, when an Integrator reviews a lane (code/quality/devops), when the Director approves, or when a Worker is about to start coding and needs the spec. Tools live in the `design-doc` MCP server. Triggers on phrases like "design doc", "design review", "approve revision", "lane verdict", "what does this issue require", "is this approved yet".
Web scraping with anti-bot bypass (Cloudflare Turnstile etc.), stealth headless browsing, adaptive selectors, and concurrent crawls. Use when the user asks to scrape, crawl, or extract data from websites; the built-in WebFetch fails; the target has anti-bot protections; or the work needs JavaScript rendering. Prefers the registered MCP tools (mcp__scrapling__*) over raw Python so token cost stays low.
| name | cloudflare |
| description | Cloudflare Workers, Pages, D1, R2, KV, Durable Objects, DNS, and edge computing patterns |
| layer | domain |
| category | devops |
| triggers | ["cloudflare","workers","cloudflare pages","d1","r2","kv","durable objects","edge function","wrangler"] |
| inputs | ["application requirements","edge computing needs","storage requirements"] |
| outputs | ["Worker scripts","wrangler configs","D1 schemas","R2 policies","DNS configs"] |
| linksTo | ["nginx","terraform","monitoring","authentication"] |
| linkedFrom | ["ship","optimize","caching"] |
| preferredNextSkills | ["monitoring","authentication","terraform"] |
| fallbackSkills | ["vercel","aws"] |
| riskLevel | low |
| memoryReadPolicy | selective |
| memoryWritePolicy | none |
| sideEffects | ["edge deployments","DNS changes","storage writes"] |
Design and implement edge-first applications using the Cloudflare platform. This skill covers Workers, Pages, D1 (SQLite at the edge), R2 (object storage), KV (key-value), Durable Objects, DNS management, and performance optimization patterns.
// src/index.ts
export interface Env {
DB: D1Database;
KV: KVNamespace;
R2: R2Bucket;
RATE_LIMITER: DurableObjectNamespace;
API_KEY: string;
}
export default {
async fetch(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
const url = new URL(request.url);
try {
if (url.pathname.startsWith("/api/")) {
return handleAPI(request, env, ctx);
}
return new Response("Not Found", { status: 404 });
} catch (error) {
console.error("Worker error:", error);
return new Response("Internal Server Error", { status: 500 });
}
},
} satisfies ExportedHandler<Env>;
async function handleAPI(request: Request, env: Env, ctx: ExecutionContext): Promise<Response> {
// Check KV cache first
const cacheKey = new URL(request.url).pathname;
const cached = await env.KV.get(cacheKey);
if (cached) {
return new Response(cached, {
headers: { "Content-Type": "application/json", "X-Cache": "HIT" },
});
}
// Query D1
const result = await env.DB.prepare("SELECT * FROM posts WHERE published = 1 LIMIT 20").all();
const json = JSON.stringify(result.results);
// Cache in KV with TTL
ctx.waitUntil(env.KV.put(cacheKey, json, { expirationTtl: 300 }));
return new Response(json, {
headers: { "Content-Type": "application/json", "X-Cache": "MISS" },
});
}
name = "my-app"
main = "src/index.ts"
compatibility_date = "2024-12-01"
[vars]
ENVIRONMENT = "production"
[[d1_databases]]
binding = "DB"
database_name = "my-app-db"
database_id = "xxx-xxx-xxx"
[[kv_namespaces]]
binding = "KV"
id = "xxx-xxx-xxx"
[[r2_buckets]]
binding = "R2"
bucket_name = "my-app-uploads"
[[durable_objects.bindings]]
name = "RATE_LIMITER"
class_name = "RateLimiter"
[[migrations]]
tag = "v1"
new_classes = ["RateLimiter"]
[triggers]
crons = ["*/5 * * * *"]
// Parameterized queries (always use bind parameters)
const user = await env.DB.prepare("SELECT * FROM users WHERE id = ?").bind(userId).first();
// Batch operations (single round trip)
const results = await env.DB.batch([
env.DB.prepare("INSERT INTO orders (user_id, total) VALUES (?, ?)").bind(userId, total),
env.DB.prepare("UPDATE inventory SET stock = stock - ? WHERE product_id = ?").bind(qty, productId),
]);
// Migrations
// wrangler d1 migrations create my-app-db create_users
// migrations/0001_create_users.sql
/*
CREATE TABLE users (
id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(16)))),
email TEXT UNIQUE NOT NULL,
name TEXT NOT NULL,
created_at TEXT DEFAULT (datetime('now'))
);
CREATE INDEX idx_users_email ON users(email);
*/
export class RateLimiter implements DurableObject {
private state: DurableObjectState;
private requests: Map<string, number[]> = new Map();
constructor(state: DurableObjectState, env: Env) {
this.state = state;
}
async fetch(request: Request): Promise<Response> {
const ip = request.headers.get("CF-Connecting-IP") || "unknown";
const now = Date.now();
const windowMs = 60_000; // 1 minute
const maxRequests = 100;
const timestamps = this.requests.get(ip) || [];
const recent = timestamps.filter((t) => now - t < windowMs);
if (recent.length >= maxRequests) {
return new Response("Rate limit exceeded", {
status: 429,
headers: { "Retry-After": "60" },
});
}
recent.push(now);
this.requests.set(ip, recent);
return new Response("OK", { status: 200 });
}
}
async function handleUpload(request: Request, env: Env): Promise<Response> {
const formData = await request.formData();
const file = formData.get("file") as File;
if (!file) return new Response("No file", { status: 400 });
const key = `uploads/${Date.now()}-${file.name}`;
await env.R2.put(key, file.stream(), {
httpMetadata: { contentType: file.type },
customMetadata: { originalName: file.name },
});
return Response.json({ key, url: `/files/${key}` });
}
ctx.waitUntil() for non-blocking async work (analytics, caching)Cache API for computed responsesrequest.headers.get("Origin")wrangler secret for API keys, never .env filesRETURNING clause to avoid extra reads after writeswrangler deploy with --env for staging vs productionwrangler devwrangler tail for real-time log streaming| Pitfall | Fix |
|---|---|
| String interpolation in D1 queries | Always use .bind() parameters |
Ignoring ctx.waitUntil() | Use it for fire-and-forget async work |
| KV reads in hot loops | Batch reads or use Cache API |
| Large Worker bundle | Use dynamic imports, tree shake |
| No error handling | Wrap handler in try/catch, log errors |
| Missing CORS headers | Add explicit Access-Control-* headers |
export default {
async scheduled(event: ScheduledEvent, env: Env, ctx: ExecutionContext) {
// Runs every 5 minutes per wrangler.toml crons config
const staleItems = await env.DB.prepare(
"SELECT id FROM cache_entries WHERE expires_at < datetime('now')"
).all();
if (staleItems.results.length > 0) {
const ids = staleItems.results.map((r) => r.id);
await env.DB.prepare(
`DELETE FROM cache_entries WHERE id IN (${ids.map(() => "?").join(",")})`
).bind(...ids).run();
}
},
} satisfies ExportedHandler<Env>;
// functions/api/posts.ts (Cloudflare Pages Functions)
export const onRequestGet: PagesFunction<Env> = async (context) => {
const posts = await context.env.DB.prepare("SELECT * FROM posts LIMIT 20").all();
return Response.json(posts.results);
};