AI Skills
Agent skills for AI coding assistants to build Ploy applications
AI Skills
Ploy provides agent skills that give AI coding assistants the knowledge to scaffold and build applications on Ploy. These skills work with Claude Code, Cursor, Windsurf, Codex, Aider, Cline, and other AI coding tools.
Available Skills
| Skill | Description | Use When |
|---|---|---|
worker-basic | Basic Cloudflare Worker | Building APIs, webhooks, serverless functions |
nextjs-app | Next.js application | Full-stack web apps with SSR |
db-drizzle | D1 database with Drizzle | Adding persistence to workers |
nextjs-db | Next.js with database | Full-stack apps with data |
queue-handler | Message queues | Background jobs, async processing |
workflow | Durable workflows | Multi-step processes, sagas |
start-framework | Ploy Start framework | Type-safe REST APIs |
Quick Install
The easiest way to install skills is using add-skill, which works with any AI coding tool:
npx add-skill polarlightsllc/ployThis will prompt you to:
- Select which skills to install
- Choose your AI tool (Claude Code, Cursor, Windsurf, etc.)
- Automatically install to the correct location
Install specific skills
# Install only the skills you need
npx add-skill polarlightsllc/ploy/worker-basic
npx add-skill polarlightsllc/ploy/start-framework
npx add-skill polarlightsllc/ploy/db-drizzleManual Installation
Usage Examples
Once skills are installed, ask your AI assistant:
Create a Worker
"Create a new Ploy worker with health check and JSON API endpoints"
The AI will use the worker-basic skill to scaffold:
import type { Ploy } from "@meetploy/types";
export default {
async fetch(request: Request, env: Env): Promise<Response> {
const url = new URL(request.url);
if (url.pathname === "/health") {
return Response.json({ status: "ok" });
}
if (url.pathname === "/api/data") {
return Response.json({ message: "Hello!" });
}
return new Response("Not Found", { status: 404 });
},
} satisfies Ploy<Env>;Add Database
"Add a users table with CRUD operations"
The AI will use the db-drizzle skill to add:
# ploy.yaml
db:
DB: default// schema.ts
export const users = sqliteTable("users", {
id: integer("id").primaryKey({ autoIncrement: true }),
name: text("name").notNull(),
email: text("email").notNull().unique(),
});Build a REST API
"Create a REST API for managing products with Ploy Start"
The AI will use the start-framework skill:
import { ploy, withDrizzle, z } from "@meetploy/start";
const worker = ploy<Env>()
.state(withDrizzle("DB", schema))
.openapi({ path: "/docs", info: { title: "Products API", version: "1.0.0" } })
.get(
"/products",
{
response: z.object({ products: z.array(productSchema) }),
},
async (ctx) => {
const products = await ctx.state.db.select().from(schema.products);
return { products };
},
)
.post(
"/products",
{
body: z.object({ name: z.string(), price: z.number() }),
response: z.object({ product: productSchema }),
},
async (ctx) => {
const [product] = await ctx.state.db
.insert(schema.products)
.values(ctx.body)
.returning();
return { product };
},
)
.build();Add Background Processing
"Add a queue for processing image uploads"
The AI will use the queue-handler skill:
# ploy.yaml
queue:
UPLOADS: image-uploadsexport default {
async fetch(request, env) {
const { messageId } = await env.UPLOADS.send({
type: "process-image",
imageUrl: "...",
});
return Response.json({ queued: true, messageId });
},
async message(event) {
await processImage(event.payload);
},
} satisfies Ploy<Env>;Create a Workflow
"Build an order processing workflow with payment and shipping"
The AI will use the workflow skill:
workflows: {
async order_processing({ input, step, log }) {
log("Processing order", { orderId: input.orderId });
const payment = await step.run("charge", async () => {
return await chargeCustomer(input.amount);
});
const shipment = await step.run("ship", async () => {
return await createShipment(input.address);
});
await step.sleep(24 * 60 * 60 * 1000); // 24 hours
await step.run("followup", async () => {
await sendFollowupEmail(input.email);
});
return { paymentId: payment.id, trackingNumber: shipment.tracking };
},
}Skill Architecture
Each skill is a markdown file with:
---
name: skill-name
description: Brief description for selection
---
# Skill Name
Instructions for the AI on how to implement this pattern...Skills include:
- Project structure
- Configuration files (ploy.yaml, package.json, tsconfig.json)
- Code examples with TypeScript
- Best practices and patterns
- Common use cases
Creating Custom Skills
Add your own skills by creating markdown files in skills/your-skill/SKILL.md:
---
name: my-custom-skill
description: Custom pattern for my project
---
# My Custom Skill
When asked to implement [pattern], follow these steps...Repository
Skills are maintained in the Ploy repository: github.com/polarlightsllc/ploy
ploy/
└── skills/
├── README.md
├── worker-basic/
│ └── SKILL.md
├── nextjs-app/
│ └── SKILL.md
├── db-drizzle/
│ └── SKILL.md
├── nextjs-db/
│ └── SKILL.md
├── queue-handler/
│ └── SKILL.md
├── workflow/
│ └── SKILL.md
└── start-framework/
└── SKILL.mdTroubleshooting
Skill Not Recognized
Ensure the skill files are in the correct location for your tool:
- Claude Code:
~/.claude/skills/or.claude/skills/in project - Cursor:
~/.cursor/skills/or referenced in.cursorrules
AI Not Following Instructions
Try being more specific in your request:
- "Use the worker-basic skill to create a new API"
- "Following the db-drizzle skill, add a users table"
Missing Dependencies
After scaffolding, run:
pnpm install
pnpm types # Generate env.d.tsHow is this guide?
Last updated on