Skip to content

Commit ff87349

Browse files
feat: add compact skill resolution for install mappings (#115)
1 parent 6069ffc commit ff87349

37 files changed

Lines changed: 3593 additions & 334 deletions

.changeset/yummy-balloons-bow.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
'@tanstack/intent': patch
3+
---
4+
5+
Add compact skill mappings and runtime resolution for agent config setup.
6+
7+
`intent install` now writes verified `intent-skills` blocks with compact `when`/`use` entries instead of embedding `load` paths. This keeps generated config portable across npm, pnpm, Bun, and Deno node_modules layouts, including transitive/package-manager-internal installs.
8+
9+
Add `intent resolve <package>#<skill>` to resolve compact mappings to the installed skill path at runtime, with `--json`, `--global`, and `--global-only` support. `intent list`, `intent install`, and `intent resolve` now scan local project packages by default and require explicit global flags for global package scanning.

docs/cli/intent-install.md

Lines changed: 81 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,81 @@
1-
---
2-
title: intent install
3-
id: intent-install
4-
---
5-
6-
`intent install` prints instructions for setting up an `intent-skills` mapping block in your project guidance file.
7-
8-
```bash
9-
npx @tanstack/intent@latest install
10-
```
11-
12-
The command prints text only. It does not edit files.
13-
14-
## Output
15-
16-
The printed instructions include this tagged block template:
17-
18-
```yaml
19-
<!-- intent-skills:start -->
20-
# Skill mappings — when working in these areas, load the linked skill file into context.
21-
skills:
22-
- task: "describe the task or code area here"
23-
load: "node_modules/package-name/skills/skill-name/SKILL.md"
24-
<!-- intent-skills:end -->
25-
```
26-
27-
They also ask you to:
28-
29-
1. Check for an existing block first
30-
2. Run `intent list` to discover installed skills, including any packages surfaced by the command's explicit global scan
31-
3. Ask whether you want a config target other than `AGENTS.md`
32-
4. Update an existing block in place when one already exists
33-
5. Add task-to-skill mappings
34-
6. Preserve all content outside the tagged block
35-
36-
If no existing block is found, `AGENTS.md` is the default target.
37-
38-
## Related
39-
40-
- [intent list](./intent-list)
41-
- [Quick Start for Consumers](../getting-started/quick-start-consumers)
1+
---
2+
title: intent install
3+
id: intent-install
4+
---
5+
6+
`intent install` creates or updates an `intent-skills` guidance block in a project guidance file.
7+
8+
```bash
9+
npx @tanstack/intent@latest install [--map] [--dry-run] [--print-prompt] [--global] [--global-only]
10+
```
11+
12+
## Options
13+
14+
- `--map`: write explicit task-to-skill mappings instead of lightweight loading guidance
15+
- `--dry-run`: print the generated block without writing files
16+
- `--print-prompt`: print the agent setup prompt instead of writing files
17+
- `--global`: include global packages after project packages when `--map` is passed
18+
- `--global-only`: install mappings from global packages only when `--map` is passed
19+
20+
## Behavior
21+
22+
- Writes lightweight skill loading guidance by default.
23+
- Creates `AGENTS.md` when no managed block exists.
24+
- Updates an existing managed block in a supported config file.
25+
- Preserves all content outside the managed block.
26+
- Scans packages and writes compact `when` and `use` mappings only when `--map` is passed.
27+
- Skips reference, meta, maintainer, and maintainer-only skills in `--map` mode.
28+
- Writes compact `when` and `use` entries instead of load paths in `--map` mode.
29+
- Verifies the managed block before reporting success.
30+
- Prints `No intent-enabled skills found.` and does not create a config file when `--map` finds no actionable skills.
31+
32+
Supported config files: `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`.
33+
34+
## Default output
35+
36+
The default block tells agents to discover skills and load matching guidance on demand:
37+
38+
```markdown
39+
<!-- intent-skills:start -->
40+
## Skill Loading
41+
42+
Before substantial work:
43+
- Skill check: run `npx @tanstack/intent@latest list`, or use skills already listed in context.
44+
- Skill guidance: if one local skill clearly matches the task, run `npx @tanstack/intent@latest load <package>#<skill>` and follow the returned `SKILL.md`.
45+
- Monorepos: when working across packages, run the skill check from the workspace root and prefer the local skill for the package being changed.
46+
- Multiple matches: prefer the most specific local skill for the package or concern you are changing; load additional skills only when the task spans multiple packages or concerns.
47+
<!-- intent-skills:end -->
48+
```
49+
50+
## Mapping output
51+
52+
`--map` writes compact skill identities:
53+
54+
```yaml
55+
<!-- intent-skills:start -->
56+
# Skill mappings - load `use` with `npx @tanstack/intent@latest load <use>`.
57+
skills:
58+
- when: "Query data fetching patterns"
59+
use: "@tanstack/query#fetching"
60+
<!-- intent-skills:end -->
61+
```
62+
63+
- `when`: task-routing phrase for agents
64+
- `use`: portable skill identity in `<package>#<skill>` format
65+
- The block does not store `load` paths, absolute paths, or package-manager-internal paths
66+
67+
## Status messages
68+
69+
- Created: `Created AGENTS.md with 1 mapping.`
70+
- Updated: `Updated AGENTS.md with 2 mappings.`
71+
- Unchanged: `No changes to AGENTS.md; 2 mappings already current.`
72+
- Guidance created: `Created AGENTS.md with skill loading guidance.`
73+
- Guidance unchanged: `No changes to AGENTS.md; skill loading guidance already current.`
74+
- Placement tip: `Tip: Keep the intent-skills block near the top of AGENTS.md so agents read it before task-specific instructions.`
75+
- No actionable skills in `--map` mode: `No intent-enabled skills found.`
76+
77+
## Related
78+
79+
- [intent list](./intent-list)
80+
- [intent load](./intent-load)
81+
- [Quick Start for Consumers](../getting-started/quick-start-consumers)

docs/cli/intent-list.md

Lines changed: 105 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,70 +1,105 @@
1-
---
2-
title: intent list
3-
id: intent-list
4-
---
5-
6-
`intent list` discovers skill-enabled packages and prints available skills.
7-
8-
```bash
9-
npx @tanstack/intent@latest list [--json]
10-
```
11-
12-
## Options
13-
14-
- `--json`: print JSON instead of text output
15-
16-
## What you get
17-
18-
- Scans project and workspace dependencies for intent-enabled packages and skills
19-
- Intentionally includes accessible global packages when listing installed skills
20-
- Includes warnings from discovery
21-
- If no packages are discovered, prints `No intent-enabled packages found.`
22-
- Summary line with package count, skill count, and detected package manager
23-
- Package table columns: `PACKAGE`, `SOURCE`, `VERSION`, `SKILLS`, `REQUIRES`
24-
- Skill tree grouped by package
25-
- Optional warnings section (`⚠ ...` per warning)
26-
27-
`REQUIRES` uses `intent.requires` values joined by `, `; empty values render as ``.
28-
`SOURCE` is a lightweight indicator showing whether the selected package came from local discovery or explicit global scanning.
29-
30-
## JSON output
31-
32-
`--json` prints the `ScanResult` object:
33-
34-
```json
35-
{
36-
"packageManager": "npm | pnpm | yarn | bun | unknown",
37-
"packages": [
38-
{
39-
"name": "string",
40-
"version": "string",
41-
"source": "local | global",
42-
"intent": {
43-
"version": 1,
44-
"repo": "string",
45-
"docs": "string",
46-
"requires": ["string"]
47-
},
48-
"skills": [
49-
{
50-
"name": "string",
51-
"path": "string",
52-
"description": "string",
53-
"type": "string (optional)",
54-
"framework": "string (optional)"
55-
}
56-
]
57-
}
58-
],
59-
"warnings": ["string"]
60-
}
61-
```
62-
63-
`packages` are ordered using `intent.requires` when possible. When the same package exists both locally and globally, `intent list` prefers the local package.
64-
65-
## Common errors
66-
67-
- Scanner failures are printed as errors
68-
- Unsupported environments:
69-
- Yarn PnP without `node_modules`
70-
- Deno projects without `node_modules`
1+
---
2+
title: intent list
3+
id: intent-list
4+
---
5+
6+
`intent list` discovers skill-enabled packages and prints available skills.
7+
8+
```bash
9+
npx @tanstack/intent@latest list [--json] [--global] [--global-only]
10+
```
11+
12+
## Options
13+
14+
- `--json`: print JSON instead of text output
15+
- `--global`: include global packages after project packages
16+
- `--global-only`: list global packages only
17+
18+
## What you get
19+
20+
- Scans project and workspace dependencies for intent-enabled packages and skills
21+
- Includes global packages only when `--global` or `--global-only` is passed
22+
- Includes warnings from discovery
23+
- If no packages are discovered, prints `No intent-enabled packages found.`
24+
- Summary line with package count, skill count, and detected package manager
25+
- Package table columns: `PACKAGE`, `SOURCE`, `VERSION`, `SKILLS`, `REQUIRES`
26+
- Skill tree grouped by package
27+
- Optional warnings section (`⚠ ...` per warning)
28+
29+
`REQUIRES` uses `intent.requires` values joined by a comma and space; empty values render as ``.
30+
`SOURCE` is a lightweight indicator showing whether the selected package came from local discovery or explicit global scanning.
31+
When both local and global packages are scanned, local packages take precedence.
32+
33+
## JSON output
34+
35+
`--json` prints the `ScanResult` object:
36+
37+
```json
38+
{
39+
"packageManager": "npm | pnpm | yarn | bun | unknown",
40+
"packages": [
41+
{
42+
"name": "string",
43+
"version": "string",
44+
"source": "local | global",
45+
"packageRoot": "string",
46+
"intent": {
47+
"version": 1,
48+
"repo": "string",
49+
"docs": "string",
50+
"requires": ["string"]
51+
},
52+
"skills": [
53+
{
54+
"name": "string",
55+
"path": "string",
56+
"description": "string",
57+
"type": "string (optional)",
58+
"framework": "string (optional)"
59+
}
60+
]
61+
}
62+
],
63+
"warnings": ["string"],
64+
"conflicts": [
65+
{
66+
"packageName": "string",
67+
"chosen": {
68+
"version": "string",
69+
"packageRoot": "string"
70+
},
71+
"variants": [
72+
{
73+
"version": "string",
74+
"packageRoot": "string"
75+
}
76+
]
77+
}
78+
],
79+
"nodeModules": {
80+
"local": {
81+
"path": "string | null",
82+
"detected": true,
83+
"exists": true,
84+
"scanned": true
85+
},
86+
"global": {
87+
"path": "string | null",
88+
"detected": true,
89+
"exists": true,
90+
"scanned": false,
91+
"source": "string (optional)"
92+
}
93+
}
94+
}
95+
```
96+
97+
`packages` are ordered using `intent.requires` when possible.
98+
When the same package exists both locally and globally and global scanning is enabled, `intent list` prefers the local package.
99+
100+
## Common errors
101+
102+
- Scanner failures are printed as errors
103+
- Unsupported environments:
104+
- Yarn PnP without `node_modules`
105+
- Deno projects without `node_modules`

docs/cli/intent-load.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
---
2+
title: intent load
3+
id: intent-load
4+
---
5+
6+
`intent load` loads a compact skill identity from the current install and prints the matching `SKILL.md` content.
7+
8+
```bash
9+
npx @tanstack/intent@latest load <package>#<skill> [--path] [--json] [--global] [--global-only]
10+
```
11+
12+
## Options
13+
14+
- `--path`: print the resolved skill path instead of the file content
15+
- `--json`: print structured JSON with metadata and content
16+
- `--global`: load from project packages first, then global packages
17+
- `--global-only`: load from global packages only
18+
19+
## What you get
20+
21+
- Validates `<package>#<skill>` before scanning
22+
- Scans project-local packages by default
23+
- Includes global packages only when `--global` or `--global-only` is passed
24+
- Prefers local packages when `--global` is used and the same package exists locally and globally
25+
- Prints raw `SKILL.md` content by default
26+
- Prints the scanner-reported path when `--path` is passed
27+
28+
The package can be scoped or unscoped. The skill can include slash-separated sub-skill names.
29+
30+
Examples:
31+
32+
```bash
33+
npx @tanstack/intent@latest load @tanstack/query#fetching
34+
npx @tanstack/intent@latest load @tanstack/query#core/fetching
35+
npx @tanstack/intent@latest load some-lib#core --path
36+
```
37+
38+
## JSON output
39+
40+
`--json` prints:
41+
42+
```json
43+
{
44+
"package": "@tanstack/query",
45+
"skill": "fetching",
46+
"path": "node_modules/@tanstack/query/skills/fetching/SKILL.md",
47+
"packageRoot": "node_modules/@tanstack/query",
48+
"source": "local",
49+
"version": "5.0.0",
50+
"content": "---\nname: fetching\n---\n\n...",
51+
"warnings": []
52+
}
53+
```
54+
55+
## Common errors
56+
57+
- Missing separator: `Invalid skill use "@tanstack/query": expected <package>#<skill>.`
58+
- Empty package: `Invalid skill use "#core": package is required.`
59+
- Empty skill: `Invalid skill use "@tanstack/query#": skill is required.`
60+
- Missing package: `Cannot resolve skill use "...": package "..." was not found.`
61+
- Missing skill: `Cannot resolve skill use "...": skill "..." was not found in package "...".`
62+
63+
## Related
64+
65+
- [intent list](./intent-list)
66+
- [intent install](./intent-install)

docs/config.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
"label": "intent list",
3939
"to": "cli/intent-list"
4040
},
41+
{
42+
"label": "intent load",
43+
"to": "cli/intent-load"
44+
},
4145
{
4246
"label": "intent meta",
4347
"to": "cli/intent-meta"

0 commit comments

Comments
 (0)