Install
$ agentstack add skill-hec-ovi-agentickit-write-a-consumer-skill ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
Write a Consumer Skill
Contract
By the end of this skill the consumer has:
- A
.pilot/folder at the root of their app (sibling topackage.json
and app/ or src/), readable by the server at startup.
- A valid
RESOLVER.mdwith at least one trigger row. - One or more
skills//SKILL.mdfiles with frontmatter that parses
under packages/agentickit/src/protocol/skill.ts.
createPilotHandlerin their API route (nosystemoption needed —
the handler auto-loads .pilot/).
- A matching
usePilotActionfor every capability the model should be
able to invoke. A SKILL.md without a matching action still feeds the model instructions, but the model has nothing to call — lead with the action registration if you can.
Iron Law: lead with the CLI
The CLI emits canonical markdown. Every hand-written shape is a chance for a subtle format mistake the parser silently drops. Use:
npx agentickit init # first time only, creates the folder
npx agentickit add-skill # per new capability, appends resolver row
Only hand-edit when the CLI can't express what you want (e.g. adding prose between sections). Even then, open the CLI-generated file and imitate its shape rather than inventing your own.
Phases
Phase 1: scaffold
cd your-app
npx agentickit init
Resulting layout:
your-app/
.pilot/
RESOLVER.md
skills/
example/
SKILL.md
The folder lives at the app root because the server handler looks for ./.pilot/ relative to process.cwd() at startup. Don't put it under public/ — the browser doesn't need to see it.
Phase 2: add one skill
npx agentickit add-skill refund-order
Emits .pilot/skills/refund-order/SKILL.md with frontmatter pre-filled (name: refund-order) and TODO markers in the body. Appends a row to .pilot/RESOLVER.md under ## Skills.
Edit both files. The SKILL.md body is plain prose the model reads verbatim; the resolver row is one-line trigger text the agent uses to route natural-language requests. Neither file is executed — it's context.
Phase 3: register the matching action
usePilotAction({
name: "refund_order", // must EXACTLY match a tool name in SKILL.md
description: "Refund a past order. Always confirms amounts over $100.",
parameters: z.object({
orderId: z.string(),
amount: z.number(),
}),
handler: async ({ orderId, amount }) => {
return await api.refundOrder({ orderId, amount });
},
mutating: true,
});
The name on the action must match a tool name listed in the SKILL.md frontmatter tools: list. The action's description is what reaches the model at tool-selection time; the SKILL.md body is context for when to pick the tool.
Phase 4: verify
pnpm dev
In the server terminal you should see:
[agentickit] auto-loaded .pilot/ (~N chars)
Send a user message matching one of the resolver triggers; the sidebar shows the assistant calling your action. Turn on debug: true in createPilotHandler to see per-step transcripts in the terminal and appended to ./debug/agentickit-YYYY-MM-DD.log.
Canonical shapes (for hand-editors)
SKILL.md
---
name: refund-order
description: Refund a past order. Always confirms amounts over $100.
tools:
- get_order
- issue_refund
mutating: true
---
# When to use
Triggered by phrases like "refund", "cancel order", "return". Use for
any transaction the user wants to reverse.
# How to use
1. Call `get_order({ id })` to resolve the order.
2. If `order.total > 100`, summarize and ask the user to confirm.
3. Call `issue_refund({ orderId, amount })`.
# Anti-patterns
- Do not refund partial line-items without checking `order.lineItems[]`.
- Do not batch refunds across orders.
Frontmatter rules enforced by parseSkill:
- Block fenced by
---top and bottom. nameanddescriptionare required strings.tools/allowed-tools/triggersare string lists (leading-).mutatingistrue/false.- Nested maps, anchors, and flow-style lists are NOT supported. Stick to
the shape above.
RESOLVER.md
# Agent Resolver
You are a concise assistant for this checkout flow. Reply in short
markdown. Prefer calling tools over describing steps.
## Skills
| Trigger | Skill |
| ---------------------------------- | ------------------------------ |
| "refund", "cancel order", "return" | `skills/refund-order/SKILL.md` |
| "fill checkout", "apply invoice" | `skills/fill-checkout/SKILL.md`|
parseResolver only reads:
- H2 (
##) headings for section labels. - Rows starting with
|, excluding the|---|---|separator and the
| Trigger | Skill | header (case-insensitive).
- Skill cells must wrap the path in backticks:
` skills//SKILL.md `.
- Lines prefixed
GStack:,Check, orReadare preserved as
external pointers (the runtime includes them in the prompt as reference text).
Anything else on a row is silently dropped today. The resolver validator (v0.2) will warn instead.
Anti-Patterns
- Hand-writing a new skill when the CLI exists. The CLI emits the
canonical shape; hand-writing invites silent parse failures.
- Putting JS imports in SKILL.md. The protocol is runtime-agnostic
markdown. Code bindings live in usePilotAction.
- Skill
namethat doesn't match any tool or action. The markdown
still reaches the model (the body is prose), but the model has nothing to invoke. Match names byte-for-byte.
- Natural-language triggers that no user would type. The LLM matches
triggers loosely, but a trigger like "initiate the recursive refundability evaluation" will never fire because no human speaks that way.
- Putting
.pilot/underpublic/or any bundler-served path. It
doesn't need HTTP access — the server reads it from the filesystem at startup.
Output Format
After authoring, report:
- The skill
name(s) created. - The resolver triggers that route to each.
- The matching
usePilotActionregistrations (name + file path). - Confirmation of a clean
[agentickit] auto-loaded .pilot/line on
dev-server startup.
Tools Used
npx agentickit init/npx agentickit add-skillfor
scaffolding.
- Edit files under
.pilot/for content. - Edit the component that registers the matching
usePilotAction. - Read
packages/agentickit/src/protocol/*.tsto verify what shapes the
parser accepts when hand-editing.
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: hec-ovi
- Source: hec-ovi/agentickit
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.