# enable Kit Potential: Why Custom Agent Skills Beat Blank Prompts

> Discover how pre-packaged agent skills transform AI from a code stranger into an integrated toolkit extension
> By Dave · 2026-07-08
> Source: https://otf-kit.dev/blog/skills-that-ship-with-kit

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:

1. 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.
2. 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.
3. 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.

```md
---
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.

## Three skills that ship with the kit

A kit's skill index lives in `ai/prompts/` and looks like this:

```bash
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 total
```

Each 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 indices
- `db/migrations/0003_orders.sql` — generated, not hand-edited
- `src/server/orders.ts` — typed `list`, `get`, `create`, `update`, `remove` helpers
- `src/types/order.ts` — inferred `Order` and `NewOrder` types

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:

1. **Slash command** — in Cursor or Claude Code, `/add-entity` renders the prompt in the input box with its argument schema.
2. **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.
3. **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.ts` lives, 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.



![blank prompt vs skill invocation — the same "add a settings page" request, asked 5 times a](https://cdn.otf-kit.dev/blog/skills-that-ship-with-kit/inline-1.png)



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 Order` and 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.