File format

A skill file and an agent-profile file are both plain markdown with a --- block at the top: the block holds the settings, everything below it is the instructions.

---
id: brand-audit
name: Brand audit
---
 
Everything down here is what the agent reads.

The block is optional. A file with no --- at all is all instructions, and everything takes its default — which is a perfectly good skill.

The settings block

It looks like YAML and is deliberately a much smaller thing: one key: value per line, starting in the first column. Values can be

  • plain text — name: Brand audit

  • true or false — readOnly: true

  • a number — maxRounds: 6

  • a list, written either way:

    tools: [find_nodes, get_node]
    tools:
      - find_nodes
      - get_node

Quotes around a value are optional and are stripped. Blank lines and # comments are ignored. Anything else — a line that isn't key: value, an indented key, a tab, a key set twice, a block that is never closed — is reported as an error with the line number, rather than being half-understood.

Unknown fields are an error. If you write whenUse: instead of whenToUse:, the file will refuse to load and tell you so. That is on purpose: a setting that is quietly ignored is much harder to notice than a file that says what's wrong with it.

A skill

A skill is a sheet of instructions the agent pulls in when a job matches it. The agent only ever sees the name, description and whenToUse up front — that is how it decides — and reads the body only once it has decided to follow the skill. So write whenToUse as the sentence you'd use to recognise the job, and put the actual steps in the body.

Put the file in skills/.

---
id: brand-audit
name: Brand audit
description: Check a page against the brand palette and type scale.
whenToUse: The user asks whether a design is on-brand, or to fix off-brand colors.
tools:
  - get_document_outline
  - find_nodes
  - get_node
  - get_styles
  - set_fills
---
 
Audit the current page against the brand, then report before changing anything.
 
1. Read `get_document_outline` to see what's on the page.
2. Collect every fill and stroke color with `find_nodes` and `get_node`.
3. Compare each one against the brand palette:
   - ink `#12131A`
   - paper `#FFFDF7`
   - signal `#FF4A1C`
   - muted `#8A8F98`
4. Anything within ~4% of a brand color is a near-miss and should be snapped to it with `set_fills`.
   Anything further away is a deliberate choice — list it, don't change it.
5. Finish with a short list: what you snapped, and what you left alone and why.

Skill fields

FieldRequiredDefaultWhat it does
idthe file nameHow the skill is referred to. Lower-case letters, digits and -; anything else is folded to -. Matching a built-in's id replaces it.
namethe idWhat the panel and the agent's skill list show.
descriptionemptyOne sentence on what the skill is for. The agent sees this before it opens the skill.
whenToUseemptyOne sentence on when it applies. This is the line the agent matches a request against — it's the most important field in the file.
toolsall toolsNarrows the tools the agent may call while following this skill. See tool names.
the body✓The instructions. Up to 20,000 characters.

A skill with an empty body is an error: there is nothing to follow.

An agent profile

A profile is a persona the main agent hands a self-contained job to. The child starts with a clean slate — it never sees your conversation — does its job, and hands back one summary. So the body should describe a job, not a personality, and should say what the summary must contain.

Put the file in agents/.

---
id: spacing-critic
name: Spacing critic
description: Measures the gaps in a layout and reports the ones that break the rhythm.
whenToUse: A layout feels off and you want the spacing checked before anything is moved.
model: inherit
readOnly: true
tools: [get_document_outline, find_nodes, get_node, measure]
maxRounds: 10
---
 
You measure spacing. You never change anything.
 
1. Use `get_document_outline`, then `find_nodes` to get every visible layer in the frame you were given.
2. With `measure` and `get_node`, collect the vertical gap between each pair of stacked siblings and the
   padding inside each container.
3. Work out the dominant step (usually the most common gap, often 4 or 8).
4. Report only what breaks it. For each one give the node id, the gap you measured, and the nearest value on
   the step.
 
Your summary is the only thing that comes back, so make it a list of `nodeId — 13px, should be 12px` lines and
nothing else. No preamble, no offer to fix them.

Profile fields

FieldRequiredDefaultWhat it does
idthe file nameHow the agent refers to the profile when it delegates. Matching a built-in's id replaces it.
namethe idWhat the panel shows.
descriptionemptyOne sentence on what the persona does.
whenToUseemptyOne sentence on when to delegate to it. The agent matches against this.
modelinheritinherit uses whatever model your chat is on. Otherwise a model id, to pin a cheap model to a cheap job.
readOnlyfalsetrue means it can look but never change the document. It can only tighten — see what a file can't do.
toolsall toolsNarrows the tools the child may call. See tool names.
maxRounds8How many model turns the child gets before it has to report back. 1–24.
the body✓The child's instructions. Up to 20,000 characters.

Read-only profiles with no model set are run on a fast model automatically, because a survey is tool calls and a paragraph rather than hard thinking. Pin a model when that isn't the trade you want.

Field spellings

whenToUse, readOnly and maxRounds also accept when-to-use / when_to_use, readonly / read-only / read_only, and max-rounds / max_rounds. tools also accepts a comma-separated string (tools: find_nodes, get_node), so a definition copied from another tool usually works unchanged.