enable Kit Potential: Why Custom Agent Skills Beat Blank Prompts
The difference between an AI agent that ships your next feature and one that hallucinates an entire new app is usually about 200 lines of markdown.
Not a better model. Not a longer context window. A skill file.
That's the bet a kit makes when it ships with prompt files: the agent isn't a stranger to your code; it's an extension of it. The skill is the contract. The model is the engine.
The blank-prompt tax
Give an agent a blank prompt against an existing codebase and three things happen:
- It invents a convention that doesn't match yours. Pluralised table names where you use singular. Snake_case where you use camelCase. A new
utils/directory when you don't have one. - It picks the closest-looking file and copies its shape — even when that file is the wrong model. A component from an old admin tool becomes the template for a public landing page.
- It succeeds by accident and fails on the next request because nothing was committed to a shared contract.
Every one of these is a stranger-to-the-codebase failure. The agent doesn't know where the schema lives. It doesn't know the routing convention. It doesn't know which column is reserved. It guesses.
Most "the model isn't smart enough" complaints are actually "the model wasn't told."
What a skill is, and what it isn't
A skill is not a prompt. A prompt is "build me a settings page." A skill is:
When the user says they want a new persistent resource, do A, then B, then C, against these files, with these names, then stop.
Concretely, it's a markdown file the agent reads only when invoked, plus the context it needs to do the job deterministically.
---
name: add-entity
description: Add a new persistent resource (Order, Post, Workout) to the kit.
Use when the user wants a new database table with types, server functions,
and a migration.
---
# add-entity
## Inputs
- `name` — PascalCase, singular (e.g. `Order`)
- `fields[]` — { name, type, nullable, default }
## Steps
1. Append to `db/schema.ts` using the kit's schema helper. Use snake_case
column names. Always add `id`, `createdAt`, `updatedAt`.
2. Run `pnpm db:generate`. Do not hand-edit migrations.
3. Add a typed query module to `src/server/<name_plural>.ts` exporting
`list`, `get`, `create`, `update`, `remove`.
4. Export the inferred type from `src/types/<name>.ts`.
5. Stop. Do not create routes, screens, or seed data unless asked.The shape matters. The skill is invocable by name, typed, has steps, and ends with stop. The agent doesn't have to guess when the job is done.
11 production screens. Login, database, payments — all wired.
The SaaS Dashboard Kit ships everything already connected. Nothing to set up. Live demo at saas.otf-kit.dev.
Three skills that ship with the kit
A kit's skill index lives in ai/prompts/ and looks like this:
ls ai/prompts/
# add-entity.md
# add-screen.md
# add-api-route.md
# wire-auth.md
# seed-data.md
# add-settings-section.md
# add-billing-webhook.md
# add-tenant.md
# ... # 20 tested prompts totalEach file is a single repeatable operation on the kit. The directory is the manifest.
/add-entity name=Order fields="customerId:uuid,totalCents:int,status:enum"
Produces:
db/schema.ts— new table with the right columns and indicesdb/migrations/0003_orders.sql— generated, not hand-editedsrc/server/orders.ts— typedlist,get,create,update,removehelperssrc/types/order.ts— inferredOrderandNewOrdertypes
The skill knew the file layout. The agent didn't have to discover it.
/add-screen name=OrderList parent=/dashboard adds a screen at the right route, composed from the kit's UI primitives, with list + detail + edit views wired to the server functions the previous skill produced. The two skills compose because they were written against each other.
/wire-auth screen=/dashboard/orders wraps the screen in the kit's requireAuth() helper, redirects to the kit's sign-in route, and adds the right role check. No manual session lookup. No drift between this screen and the next one an engineer adds six months later.
Three skills, three real operations, three deterministic contracts. The agent isn't freelancing — it's invoking.
Discoverability beats discoverability-once
If you put the same contract in a single CLAUDE.md at the repo root, the agent reads all 200 lines on every turn. That's permanent context tax. And worse — the agent doesn't know when to apply each rule, so it over-applies. It generates migrations on every feature add. It inserts requireAuth() calls on screens that don't need them. It writes the createdAt/updatedAt columns on a join table that doesn't need them.
A skill file is loaded on demand. The agent sees the manifest, picks the matching one, reads only that file. Context stays cheap. Determinism stays high.
The directory IS the menu. The agent has a list of capabilities, not a fog of rules.
How an agent actually invokes one
Same skill file, three surfaces:
- Slash command — in Cursor or Claude Code,
/add-entityrenders the prompt in the input box with its argument schema. - Tool call — in Claude Code or any MCP-compatible client, the skill is exposed as a tool with a typed JSON schema. The router picks it by name.
- Headless agent — a router reads the manifest, matches the user's intent to a skill by description, loads the file, runs the steps.
The skill is the source of truth. The agent is the consumer. The kit ships both.
This is also why the same ai/prompts/ directory works across surfaces. Cursor reads it as .cursorrules-style slash commands. Claude Code reads it as tool definitions. Cline reads it as prompt files. One source, three consumers, zero translation layer.
What the skill knows that you don't have to
The real win: a skill that ships inside the kit was written against the kit. It knows:
- Where
db/schema.tslives, and that you must not put migrations there by hand - That server functions use the kit's typed RPC helper, not raw
fetch - That screens compose from the kit's UI primitives — the same component name on web and native
- That auth checks go through
requireAuth(), not a manual session lookup - That design tokens flip one theme across web and mobile, so you never repeat a hex code
A skill bolted onto a codebase after the fact can't know any of this. It would have to rediscover it every time, which means it would sometimes get it wrong. The first run would pass review; the fifth would quietly introduce a bug.

A skill that ships inside the kit is the kit. The agent isn't a stranger — it's an extension that already speaks the dialect.
What this gets you
Three concrete scenarios:
- A new hire on day one. They don't read 200 pages of docs. They run
/add-entity Orderand watch the right files appear in the right places — same files a senior engineer would have written. Onboarding drops from a week to an afternoon. - A product manager wants to test "what if we had a Reviews resource?" They ask Claude Code. The agent picks
add-entity, fills the arguments from the request, the migration runs, the types export, the server functions land. First-try success. - You come back in six months. The agent still works. The skills still match the code. Nothing has rotted because the skill file and the kit's source live in the same repo and evolve together.
The quality compounds. Every refinement to the skill file is a refinement every future run inherits. Every new component added to the kit is a new primitive every skill can compose.
The kit is the index
The thing to internalise: a kit's value is not just the code it ships. It's the skills that know the code.
The free SDK ships ~200 components across web and native, plus the skill files that match them — add-screen, add-entity, wire-auth, and a dozen more, all in ai/prompts/. A paid full-stack kit — SaaS Dashboard, Fitness, Booking — ships auth already wired, the DB schema already migrated, and the skills that know which file to touch when you say "add a tenant" or "add a billing webhook." The kit ships the conventions; the agent invokes them.
Same outcome on every invocation. Same shape of file. Same naming convention. That's the bet.
The agent isn't replacing the kit. The kit isn't replacing the agent. They're the same surface viewed from two sides: the kit is the grammar, the agent is the speaker. Pick the boring, repeatable grammar and let the model be the voice.
Closing
A skill is a contract. The prompt is the verb; the skill is the grammar.
Ship the grammar with the code. The agent will figure out the verb — and it will figure it out the same way every time.
Ship the product, not the setup.
- 11 production screens — auth, billing, team, analytics, settings
- Real database, payments, and login — all wired on day 1
- AI configs pre-tuned so your agent extends instead of regenerates