Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/frank-experts-build.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/intent': patch
---

Make `SKILL.md` frontmatter spec-compliant. `name` must now be a spec-legal leaf segment matching its parent directory (lowercase letters, numbers, and hyphens; 64 characters max; no slashes), and the Intent-specific scalars `type`, `library`, `library_version`, and `framework` live under the `metadata` map. `intent validate` now errors on a slash/non-leaf `name`, a `name` with non-spec characters or over 64 characters, non-spec top-level scalar keys, and a non-string `metadata` map. Skill identity is derived from the directory path rather than the frontmatter `name`, and the `generate-skill` and `tree-generator` templates emit the new shape.
6 changes: 5 additions & 1 deletion docs/cli/intent-validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ For each discovered `SKILL.md`:
- Frontmatter delimiter and structure are valid
- YAML frontmatter parses successfully
- Required fields exist: `name`, `description`
- `name` matches skill directory path under the target root
- `name` is a single leaf segment matching the skill's parent directory (no slashes); the namespace is carried by the directory path
- `name` uses only lowercase letters, numbers, and hyphens
- `name` is at most 64 characters
- Only spec top-level keys are allowed (`name`, `description`, `license`, `compatibility`, `metadata`, `allowed-tools`); Intent-specific scalars (`type`, `library`, `library_version`, `framework`) must live under `metadata`
- `metadata`, when present, is a mapping of string values
- `description` length is at most 1024 characters
- `type: framework` requires `requires` to be an array
- Total file length is at most 500 lines
Expand Down
3 changes: 2 additions & 1 deletion docs/getting-started/quick-start-maintainers.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,8 @@ npx @tanstack/intent@latest validate
This checks:
- Valid YAML frontmatter in every SKILL.md
- Required fields (`name`, `description`) are present
- Skill names match their directory paths
- Skill `name` is a leaf segment matching its parent directory
- Intent-specific scalars (`type`, `library`, `library_version`, `framework`) live under `metadata`, not at the top level
- Description length <= 1024 characters
- Line count limits (500 lines max per skill)
- Framework skills have a `requires` array
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@
"sherif": "^1.11.1",
"tinyglobby": "^0.2.17",
"typescript": "6.0.3",
"vitest": "4.1.8",
"yaml": "2.9.0"
"vitest": "4.1.8"
}
}
54 changes: 34 additions & 20 deletions packages/intent/meta/generate-skill/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,9 @@ SKILL.md into that package's skills directory (e.g.
`packages/client/skills/core/SKILL.md`), not a shared root.

1. **Skill name** — format `library-group/skill-name` (e.g. `tanstack-query/core`,
`tanstack-router/loaders`, `db/core/live-queries`)
`tanstack-router/loaders`, `db/core/live-queries`). This is the skill's
directory path: its **last segment** becomes the frontmatter `name` (a
spec-legal leaf), and the full path is where the `SKILL.md` lives.
2. **Skill description** — what the skill covers and when an agent should load it
3. **Source documentation** — the docs, guides, API references, and/or source
files to distill from
Expand Down Expand Up @@ -170,62 +172,74 @@ domain-discovery — use those directly.

```yaml
---
name: [library]/[skill-name]
name: '[skill-name]'
description: >
[1–3 sentences. What this skill covers and exactly when an agent should
load it. Written for the agent — include the keywords an agent would
encounter when it needs this skill. Dense routing key.]
type: core
library: [library]
library_version: "[version this targets]"
metadata:
type: core
library: '[library]'
library_version: '[version this targets]'
sources:
- "[Owner/repo]:docs/[path].md"
- "[Owner/repo]:src/[path].ts"
- '[Owner/repo]:docs/[path].md'
- '[Owner/repo]:src/[path].ts'
---
```

### Sub-skill frontmatter

```yaml
---
name: [library]/[parent]/[skill-name]
name: '[skill-name]'
description: >
[1–3 sentences. What this sub-topic covers and when to load it.]
type: sub-skill
library: [library]
library_version: "[version]"
metadata:
type: sub-skill
library: '[library]'
library_version: '[version]'
sources:
- "[Owner/repo]:docs/[path].md"
- '[Owner/repo]:docs/[path].md'
---
```

### Framework skill frontmatter

```yaml
---
name: [library]/[framework]
name: '[framework]'
description: >
[1–3 sentences. Framework-specific bindings. Name the hooks, components,
providers.]
type: framework
library: [library]
framework: [react | vue | solid | svelte | angular]
library_version: "[version]"
metadata:
type: framework
library: '[library]'
framework: '[react | vue | solid | svelte | angular]'
library_version: '[version]'
requires:
- [library]/core
- '[library]/core'
sources:
- "[Owner/repo]:docs/framework/[framework]/[path].md"
- '[Owner/repo]:docs/framework/[framework]/[path].md'
---
```

### Frontmatter rules

- `name` is the spec-legal leaf segment — lowercase letters, numbers, and
hyphens only — and matches the skill's parent directory. It carries no
slashes; the namespace lives in the skill's directory path instead.
- Intent-specific scalars (`type`, `library`, `library_version`, `framework`)
live under the `metadata` map. The Agent Skills spec permits only `name`,
`description`, `license`, `compatibility`, `metadata`, and `allowed-tools`
at the top level, so emitting these scalars at the top level fails
validation.
- `description` must be written so the agent loads this skill at the right
time — not too broad (triggers on everything) and not too narrow (never
triggers). Pack with function names, option names, concept keywords.
- `sources` uses the format `Owner/repo:relative-path`. Glob patterns are
supported (e.g. `TanStack/query:docs/framework/react/guides/*.md`).
- `library_version` is the version of the source library this skill targets.
- `metadata.library_version` is the version of the source library this skill
targets.
- `requires` lists skills that must be loaded before this one.

---
Expand Down
80 changes: 42 additions & 38 deletions packages/intent/meta/tree-generator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,14 +287,15 @@ framework-agnostic concepts and contains the sub-skill registry.

```yaml
---
name: [lib]-core
name: '[lib]-core'
description: >
[1–3 sentences. What this library does and the framework-agnostic
concepts it provides. Pack with keywords: function names, config
options, concepts. This is a routing key, not a human summary.]
type: core
library: [lib]
library_version: "[version this targets]"
metadata:
type: core
library: '[lib]'
library_version: '[version this targets]'
---
```

Expand Down Expand Up @@ -332,16 +333,17 @@ One SKILL.md per domain. Follow this structure exactly.

```yaml
---
name: [lib]-core/[domain-slug]
name: '[domain-slug]'
description: >
[1–3 sentences. What this domain covers AND when to load it. Name
specific functions, options, or APIs. Dense routing key.]
type: sub-skill
library: [lib]
library_version: "[version]"
metadata:
type: sub-skill
library: '[lib]'
library_version: '[version]'
sources:
- "[repo]:docs/[path].md"
- "[repo]:src/[path].ts"
- '[repo]:docs/[path].md'
- '[repo]:src/[path].ts'
---
```

Expand Down Expand Up @@ -452,17 +454,18 @@ framework-specific patterns and mistakes.

```yaml
---
name: react-[lib]
name: 'react-[lib]'
description: >
[1–3 sentences. React-specific bindings for [library]. Name the hooks,
components, and providers. Mention React-specific patterns like SSR
hydration if applicable.]
type: framework
library: [lib]
framework: react
library_version: "[version]"
metadata:
type: framework
library: '[lib]'
framework: react
library_version: '[version]'
requires:
- [lib]-core
- '[lib]-core'
---
```

Expand Down Expand Up @@ -499,18 +502,18 @@ with the framework frontmatter:

```yaml
---
name: react-[lib]/[domain-slug]
name: '[domain-slug]'
description: >
[React-specific description for this domain.]
type: sub-skill
library: [lib]
framework: react
library_version: "[version]"
metadata:
type: sub-skill
library: '[lib]'
framework: react
library_version: '[version]'
requires:
- [lib]-core
- [lib]-core/[domain-slug]
- '[lib]-core'
- '[lib]-core/[domain-slug]'
---

This skill builds on [lib]-core/[domain-slug]. Read the core skill first.
```

Expand Down Expand Up @@ -556,19 +559,19 @@ framework hooks and providers).

```yaml
---
name: compositions/[lib-a]-[lib-b]
name: '[lib-a]-[lib-b]'
description: >
[How lib-a and lib-b wire together. Name the specific integration
points: functions, hooks, patterns.]
type: composition
library_version: "[version of primary lib]"
metadata:
type: composition
library_version: '[version of primary lib]'
requires:
- [lib-a]-core
- react-[lib-a]
- [lib-b]-core
- react-[lib-b]
- '[lib-a]-core'
- 'react-[lib-a]'
- '[lib-b]-core'
- 'react-[lib-b]'
---

This skill requires familiarity with both [lib-a] and [lib-b].
Read their core and framework skills first.
```
Expand Down Expand Up @@ -601,15 +604,16 @@ for these skill types.

```yaml
---
name: react-[lib]/security
name: security
description: >
Go-live security validation for [library]. Checks [specific concerns].
type: security
library: [lib]
framework: react
library_version: '[version]'
metadata:
type: security
library: '[lib]'
framework: react
library_version: '[version]'
requires:
- react-[lib]
- 'react-[lib]'
---
```

Expand Down
Loading
Loading