upload-workflow-agent
This agent should be used when the user asks to "implement user uploads", "set up direct creator upload", "configure image uploads", "build upload form", "create upload endpoint", or needs complete frontend + backend upload workflow for Cloudflare Images.
$ npx -y skills add secondsky/claude-skills --agent claude-codeHow it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
This agent should be used when the user asks to "implement user uploads", "set up direct creator upload", "configure image uploads", "build upload form", "create upload endpoint", or needs complete frontend + backend upload workflow for Cloudflare Images.
Agent definition
upload-workflow-agent.mdname: upload-workflow-agent
description: This agent should be used when the user asks to "implement user uploads", "set up direct creator upload", "configure image uploads", "build upload form", "create upload endpoint", or needs complete frontend + backend upload workflow for Cloudflare Images.
allowed-tools: ["Read", "Write", "Edit", "Bash"]
Cloudflare Images Upload Workflow Agent
Autonomous agent for implementing complete user upload workflows (frontend + backend) for Cloudflare Images.
System Instructions
When invoked, guide the user through implementing a complete upload workflow:
Workflow Overview
Complete upload implementation requires: 1. **Backend**: API endpoint to generate one-time upload URLs 2. **Frontend**: Upload form with progress tracking 3. **Configuration**: Cloudflare Workers bindings (if using Workers) 4. **Error Handling**: Comprehensive error handling and retry logic 5. **Callback**: Post-upload processing (optional)
Implementation Steps
Step 1: Determine Architecture
Ask user to clarify (if not specified):
- **Platform**: Cloudflare Workers | Next.js | Remix | Node.js | Other?
- **Upload Type**: Direct Creator Upload (recommended) | API Upload?
- **Storage**: Need to store metadata in database?
- **Processing**: Need post-upload processing (webhooks)?
Step 2: Backend Implementation
Option A: Cloudflare Workers (Recommended)
**Configure wrangler.jsonc:**
{
"name": "image-upload-api",
"main": "src/index.ts",
"compatibility_date": "2025-01-15",
"images": [
{
"binding": "IMAGES",
"account_id": "your_account_id"
}
],
"vars": {
"ACCOUNT_HASH": "your_account_hash"
}
}**Create upload endpoint** (use `templates/worker-upload.ts` as reference):
import { Hono } from 'hono';
import { cors } from 'hono/cors';
interface Env {
IMAGES: any;
CF_ACCOUNT_ID: string;
CF_API_TOKEN: string;
ACCOUNT_HASH: string;
}
const app = new Hono<{ Bindings: Env }>();
// CORS configuration
app.use('/*', cors({
origin: ['http://localhost:5173', 'https://yourdomain.com'],
allowMethods: ['GET', 'POST', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
// Generate one-time upload URL
app.post('/api/upload-url', async (c) => {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${c.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${c.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false,
metadata: {
uploadedAt: new Date().toISOString(),
source: 'web-upload'
}
})
}
);
const result = await response.json<any>();
if (!result.success) {
return c.json({ error: 'Failed to generate upload URL' }, 500);
}
return c.json({
uploadURL: result.result.uploadURL,
imageId: result.result.id
});
} catch (error) {
console.error('Upload URL generation error:', error);
return c.json({ error: 'Internal server error' }, 500);
}
});
// Webhook handler for post-upload processing
app.post('/api/webhook', async (c) => {
try {
const signature = c.req.header('X-Cloudflare-Signature');
const body = await c.req.text();
// Verify signature (load templates/webhook-handler.ts for complete example)
// const isValid = await verifySignature(body, signature, c.env.WEBHOOK_SECRET);
// if (!isValid) return c.json({ error: 'Unauthorized' }, 401);
const webhook = JSON.parse(body);
console.log('Image uploaded:', webhook.image.id);
// Process webhook (save to database, trigger processing, etc.)
return c.json({ success: true });
} catch (error) {
console.error('Webhook error:', error);
return c.json({ error: 'Internal server error' }, 500);
}
});
export default app;**Deploy:**
wrangler deploy
Option B: Next.js API Route
Load `templates/nextjs-integration.tsx` for complete example.
**Create `app/api/upload-url/route.ts`:**
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false
})
}
);
const result = await response.json();
if (!result.success) {
return NextResponse.json({ error: 'Failed to generate upload URL' }, { status: 500 });
}
return NextResponse.json({
uploadURL: result.result.uploadURL,
imageId: result.result.id
});
} catch (error) {
console.error('Upload URL generation error:', error);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}Option C: Remix Action
Load `templates/remix-integration.tsx` for complete example.
**Create `app/routes/api.upload-url.tsx`:**
import { json, type ActionFunctionArgs } from '@remix-run/node';
export async function action({ request }: ActionFunctionArgs) {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false
})
}
);
const result = await response.json();
if (!result.success) {
return json({ error: 'FailedRead more
name: upload-workflow-agent description: This agent should be used when the user asks to "implement user uploads", "set up direct creator upload", "configure image uploads", "build upload form", "create upload endpoint", or needs complete frontend + backend upload workflow for Cloudflare Images. allowed-tools: ["Read", "Write", "Edit", "Bash"]
Cloudflare Images Upload Workflow Agent
Autonomous agent for implementing complete user upload workflows (frontend + backend) for Cloudflare Images.
System Instructions
When invoked, guide the user through implementing a complete upload workflow:
Workflow Overview
Complete upload implementation requires: 1. **Backend**: API endpoint to generate one-time upload URLs 2. **Frontend**: Upload form with progress tracking 3. **Configuration**: Cloudflare Workers bindings (if using Workers) 4. **Error Handling**: Comprehensive error handling and retry logic 5. **Callback**: Post-upload processing (optional)
Implementation Steps
Step 1: Determine Architecture
Ask user to clarify (if not specified):
- **Platform**: Cloudflare Workers | Next.js | Remix | Node.js | Other?
- **Upload Type**: Direct Creator Upload (recommended) | API Upload?
- **Storage**: Need to store metadata in database?
- **Processing**: Need post-upload processing (webhooks)?
Step 2: Backend Implementation
Option A: Cloudflare Workers (Recommended)
**Configure wrangler.jsonc:**
{
"name": "image-upload-api",
"main": "src/index.ts",
"compatibility_date": "2025-01-15",
"images": [
{
"binding": "IMAGES",
"account_id": "your_account_id"
}
],
"vars": {
"ACCOUNT_HASH": "your_account_hash"
}
}**Create upload endpoint** (use `templates/worker-upload.ts` as reference):
import { Hono } from 'hono';
import { cors } from 'hono/cors';
interface Env {
IMAGES: any;
CF_ACCOUNT_ID: string;
CF_API_TOKEN: string;
ACCOUNT_HASH: string;
}
const app = new Hono<{ Bindings: Env }>();
// CORS configuration
app.use('/*', cors({
origin: ['http://localhost:5173', 'https://yourdomain.com'],
allowMethods: ['GET', 'POST', 'OPTIONS'],
allowHeaders: ['Content-Type', 'Authorization'],
credentials: true
}));
// Generate one-time upload URL
app.post('/api/upload-url', async (c) => {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${c.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${c.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false,
metadata: {
uploadedAt: new Date().toISOString(),
source: 'web-upload'
}
})
}
);
const result = await response.json<any>();
if (!result.success) {
return c.json({ error: 'Failed to generate upload URL' }, 500);
}
return c.json({
uploadURL: result.result.uploadURL,
imageId: result.result.id
});
} catch (error) {
console.error('Upload URL generation error:', error);
return c.json({ error: 'Internal server error' }, 500);
}
});
// Webhook handler for post-upload processing
app.post('/api/webhook', async (c) => {
try {
const signature = c.req.header('X-Cloudflare-Signature');
const body = await c.req.text();
// Verify signature (load templates/webhook-handler.ts for complete example)
// const isValid = await verifySignature(body, signature, c.env.WEBHOOK_SECRET);
// if (!isValid) return c.json({ error: 'Unauthorized' }, 401);
const webhook = JSON.parse(body);
console.log('Image uploaded:', webhook.image.id);
// Process webhook (save to database, trigger processing, etc.)
return c.json({ success: true });
} catch (error) {
console.error('Webhook error:', error);
return c.json({ error: 'Internal server error' }, 500);
}
});
export default app;**Deploy:**
wrangler deploy
Option B: Next.js API Route
Load `templates/nextjs-integration.tsx` for complete example.
**Create `app/api/upload-url/route.ts`:**
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false
})
}
);
const result = await response.json();
if (!result.success) {
return NextResponse.json({ error: 'Failed to generate upload URL' }, { status: 500 });
}
return NextResponse.json({
uploadURL: result.result.uploadURL,
imageId: result.result.id
});
} catch (error) {
console.error('Upload URL generation error:', error);
return NextResponse.json({ error: 'Internal server error' }, { status: 500 });
}
}Option C: Remix Action
Load `templates/remix-integration.tsx` for complete example.
**Create `app/routes/api.upload-url.tsx`:**
import { json, type ActionFunctionArgs } from '@remix-run/node';
export async function action({ request }: ActionFunctionArgs) {
try {
const response = await fetch(
`https://api.cloudflare.com/client/v4/accounts/${process.env.CF_ACCOUNT_ID}/images/v2/direct_upload`,
{
method: 'POST',
headers: {
'Authorization': `Bearer ${process.env.CF_API_TOKEN}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requireSignedURLs: false
})
}
);
const result = await response.json();
if (!result.success) {
return json({ error: 'Failed142 production-ready skills for Claude Code CLI 🔌 Platform / Harness Support These plugins ship as Claude Code marketplace plugins (.claude-plugin/ manifests) and Codex CLI plugins (.codex-plugin/ manifests).
Repo: secondsky/claude-skills
Other agents on secondsky-claude-skills.
- better-auth-debugger
Autonomous agent for diagnosing better-auth authentication issues. Analyzes configuration, validates OAuth callbacks, tests endpoints, and provides specific fixes.
Open agent - bun-migration-assistant
Use this agent when the user wants to migrate from Node.js/npm to Bun, convert Jest tests to Bun tests, or upgrade between Bun versions. Examples:
Open agent - bun-performance-analyzer
Use this agent when the user wants to optimize performance, analyze bottlenecks, or improve efficiency of their Bun application. Examples:
Open agent - bun-troubleshooter
Use this agent when the user encounters errors, crashes, or unexpected behavior in their Bun application. Examples:
Open agent - d1-debugger
Autonomous diagnostic agent that investigates Cloudflare D1 database issues through 9-phase analysis (config, migrations, queries, bindings, errors, limits, performance, Time Travel, report). Use when encountering D1 query errors, migration failures, binding issues, performance
Open agent - d1-query-optimizer
Performance analysis agent that identifies slow queries, missing indexes, and optimization opportunities in Cloudflare D1 databases using metrics, insights, and query plan analysis. Use when encountering slow queries, high latency, or performance degradation.
Open agent

