-
-
Notifications
You must be signed in to change notification settings - Fork 9
feat: add compact skill resolution for install mappings #115
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
0409018
update install prompt
LadyBluenotes 8983f1c
update install prompt
LadyBluenotes 44091b5
avoid absolute skill paths in install guidance
LadyBluenotes 951c646
centralize safe skill path handling
LadyBluenotes e90daaa
add deterministic install block builder
LadyBluenotes 1269f41
add idempotent install file writer
LadyBluenotes b745316
Update install command to write agent skill mappings
LadyBluenotes c125e36
Verify installed agent skill mappings before reporting success
LadyBluenotes 799bca2
fix: harden install skill mapping verification
LadyBluenotes 7c7882c
fix: share safe skill load path rewriting
LadyBluenotes 1467d59
add compact skill identity helpers
LadyBluenotes 802428d
add resolver core API
LadyBluenotes c8b395f
add resolver cli command
LadyBluenotes b6c9007
make global intent scanning opt-in
LadyBluenotes 85ad196
generate compact intent skill mappings
LadyBluenotes 360fd33
cover pnpm paths in skill resolver
LadyBluenotes ee99caf
cover resolve CLI failure paths
LadyBluenotes c580912
improve integration install diagnostics
LadyBluenotes d193922
Tighten resolve validation and install prompt
LadyBluenotes 7e20e07
update docs
LadyBluenotes 47a21a4
ci: apply automated fixes
autofix-ci[bot] 08a181d
changeset
LadyBluenotes c053ec8
simplify
LadyBluenotes 88761d2
update version
LadyBluenotes 400c316
fix release?
LadyBluenotes 9a5224a
Merge branch 'main' into install-prompt
LadyBluenotes 3b0ae0c
ci: apply automated fixes
autofix-ci[bot] 30d74f2
fix: review fixes — warning prefix match, doc accuracy, stale references
KyleAMathews d1e0452
ci: apply automated fixes
autofix-ci[bot] 6f7aeb3
remove resolve and introduce load and --map
LadyBluenotes 4e42356
ci: apply automated fixes
autofix-ci[bot] f8523d2
ci: apply automated fixes (attempt 2/3)
autofix-ci[bot] File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| --- | ||
| '@tanstack/intent': patch | ||
| --- | ||
|
|
||
| Add compact skill mappings and runtime resolution for agent config setup. | ||
|
|
||
| `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. | ||
|
|
||
| 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. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,41 +1,81 @@ | ||
| --- | ||
| title: intent install | ||
| id: intent-install | ||
| --- | ||
|
|
||
| `intent install` prints instructions for setting up an `intent-skills` mapping block in your project guidance file. | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest install | ||
| ``` | ||
|
|
||
| The command prints text only. It does not edit files. | ||
|
|
||
| ## Output | ||
|
|
||
| The printed instructions include this tagged block template: | ||
|
|
||
| ```yaml | ||
| <!-- intent-skills:start --> | ||
| # Skill mappings — when working in these areas, load the linked skill file into context. | ||
| skills: | ||
| - task: "describe the task or code area here" | ||
| load: "node_modules/package-name/skills/skill-name/SKILL.md" | ||
| <!-- intent-skills:end --> | ||
| ``` | ||
|
|
||
| They also ask you to: | ||
|
|
||
| 1. Check for an existing block first | ||
| 2. Run `intent list` to discover installed skills, including any packages surfaced by the command's explicit global scan | ||
| 3. Ask whether you want a config target other than `AGENTS.md` | ||
| 4. Update an existing block in place when one already exists | ||
| 5. Add task-to-skill mappings | ||
| 6. Preserve all content outside the tagged block | ||
|
|
||
| If no existing block is found, `AGENTS.md` is the default target. | ||
|
|
||
| ## Related | ||
|
|
||
| - [intent list](./intent-list) | ||
| - [Quick Start for Consumers](../getting-started/quick-start-consumers) | ||
| --- | ||
| title: intent install | ||
| id: intent-install | ||
| --- | ||
|
|
||
| `intent install` creates or updates an `intent-skills` guidance block in a project guidance file. | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest install [--map] [--dry-run] [--print-prompt] [--global] [--global-only] | ||
| ``` | ||
|
|
||
| ## Options | ||
|
|
||
| - `--map`: write explicit task-to-skill mappings instead of lightweight loading guidance | ||
| - `--dry-run`: print the generated block without writing files | ||
| - `--print-prompt`: print the agent setup prompt instead of writing files | ||
| - `--global`: include global packages after project packages when `--map` is passed | ||
| - `--global-only`: install mappings from global packages only when `--map` is passed | ||
|
|
||
| ## Behavior | ||
|
|
||
| - Writes lightweight skill loading guidance by default. | ||
| - Creates `AGENTS.md` when no managed block exists. | ||
| - Updates an existing managed block in a supported config file. | ||
| - Preserves all content outside the managed block. | ||
| - Scans packages and writes compact `when` and `use` mappings only when `--map` is passed. | ||
| - Skips reference, meta, maintainer, and maintainer-only skills in `--map` mode. | ||
| - Writes compact `when` and `use` entries instead of load paths in `--map` mode. | ||
| - Verifies the managed block before reporting success. | ||
| - Prints `No intent-enabled skills found.` and does not create a config file when `--map` finds no actionable skills. | ||
|
|
||
| Supported config files: `AGENTS.md`, `CLAUDE.md`, `.cursorrules`, `.github/copilot-instructions.md`. | ||
|
|
||
| ## Default output | ||
|
|
||
| The default block tells agents to discover skills and load matching guidance on demand: | ||
|
|
||
| ```markdown | ||
| <!-- intent-skills:start --> | ||
| ## Skill Loading | ||
|
|
||
| Before substantial work: | ||
| - Skill check: run `npx @tanstack/intent@latest list`, or use skills already listed in context. | ||
| - Skill guidance: if one local skill clearly matches the task, run `npx @tanstack/intent@latest load <package>#<skill>` and follow the returned `SKILL.md`. | ||
| - Monorepos: when working across packages, run the skill check from the workspace root and prefer the local skill for the package being changed. | ||
| - 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. | ||
| <!-- intent-skills:end --> | ||
| ``` | ||
|
|
||
| ## Mapping output | ||
|
|
||
| `--map` writes compact skill identities: | ||
|
|
||
| ```yaml | ||
| <!-- intent-skills:start --> | ||
| # Skill mappings - load `use` with `npx @tanstack/intent@latest load <use>`. | ||
| skills: | ||
| - when: "Query data fetching patterns" | ||
| use: "@tanstack/query#fetching" | ||
| <!-- intent-skills:end --> | ||
| ``` | ||
|
|
||
| - `when`: task-routing phrase for agents | ||
| - `use`: portable skill identity in `<package>#<skill>` format | ||
| - The block does not store `load` paths, absolute paths, or package-manager-internal paths | ||
|
|
||
| ## Status messages | ||
|
|
||
| - Created: `Created AGENTS.md with 1 mapping.` | ||
| - Updated: `Updated AGENTS.md with 2 mappings.` | ||
| - Unchanged: `No changes to AGENTS.md; 2 mappings already current.` | ||
| - Guidance created: `Created AGENTS.md with skill loading guidance.` | ||
| - Guidance unchanged: `No changes to AGENTS.md; skill loading guidance already current.` | ||
| - Placement tip: `Tip: Keep the intent-skills block near the top of AGENTS.md so agents read it before task-specific instructions.` | ||
| - No actionable skills in `--map` mode: `No intent-enabled skills found.` | ||
|
|
||
| ## Related | ||
|
|
||
| - [intent list](./intent-list) | ||
| - [intent load](./intent-load) | ||
| - [Quick Start for Consumers](../getting-started/quick-start-consumers) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,70 +1,105 @@ | ||
| --- | ||
| title: intent list | ||
| id: intent-list | ||
| --- | ||
|
|
||
| `intent list` discovers skill-enabled packages and prints available skills. | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest list [--json] | ||
| ``` | ||
|
|
||
| ## Options | ||
|
|
||
| - `--json`: print JSON instead of text output | ||
|
|
||
| ## What you get | ||
|
|
||
| - Scans project and workspace dependencies for intent-enabled packages and skills | ||
| - Intentionally includes accessible global packages when listing installed skills | ||
| - Includes warnings from discovery | ||
| - If no packages are discovered, prints `No intent-enabled packages found.` | ||
| - Summary line with package count, skill count, and detected package manager | ||
| - Package table columns: `PACKAGE`, `SOURCE`, `VERSION`, `SKILLS`, `REQUIRES` | ||
| - Skill tree grouped by package | ||
| - Optional warnings section (`⚠ ...` per warning) | ||
|
|
||
| `REQUIRES` uses `intent.requires` values joined by `, `; empty values render as `–`. | ||
| `SOURCE` is a lightweight indicator showing whether the selected package came from local discovery or explicit global scanning. | ||
|
|
||
| ## JSON output | ||
|
|
||
| `--json` prints the `ScanResult` object: | ||
|
|
||
| ```json | ||
| { | ||
| "packageManager": "npm | pnpm | yarn | bun | unknown", | ||
| "packages": [ | ||
| { | ||
| "name": "string", | ||
| "version": "string", | ||
| "source": "local | global", | ||
| "intent": { | ||
| "version": 1, | ||
| "repo": "string", | ||
| "docs": "string", | ||
| "requires": ["string"] | ||
| }, | ||
| "skills": [ | ||
| { | ||
| "name": "string", | ||
| "path": "string", | ||
| "description": "string", | ||
| "type": "string (optional)", | ||
| "framework": "string (optional)" | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| "warnings": ["string"] | ||
| } | ||
| ``` | ||
|
|
||
| `packages` are ordered using `intent.requires` when possible. When the same package exists both locally and globally, `intent list` prefers the local package. | ||
|
|
||
| ## Common errors | ||
|
|
||
| - Scanner failures are printed as errors | ||
| - Unsupported environments: | ||
| - Yarn PnP without `node_modules` | ||
| - Deno projects without `node_modules` | ||
| --- | ||
| title: intent list | ||
| id: intent-list | ||
| --- | ||
|
|
||
| `intent list` discovers skill-enabled packages and prints available skills. | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest list [--json] [--global] [--global-only] | ||
| ``` | ||
|
|
||
| ## Options | ||
|
|
||
| - `--json`: print JSON instead of text output | ||
| - `--global`: include global packages after project packages | ||
| - `--global-only`: list global packages only | ||
|
|
||
| ## What you get | ||
|
|
||
| - Scans project and workspace dependencies for intent-enabled packages and skills | ||
| - Includes global packages only when `--global` or `--global-only` is passed | ||
| - Includes warnings from discovery | ||
| - If no packages are discovered, prints `No intent-enabled packages found.` | ||
| - Summary line with package count, skill count, and detected package manager | ||
| - Package table columns: `PACKAGE`, `SOURCE`, `VERSION`, `SKILLS`, `REQUIRES` | ||
| - Skill tree grouped by package | ||
| - Optional warnings section (`⚠ ...` per warning) | ||
|
|
||
| `REQUIRES` uses `intent.requires` values joined by a comma and space; empty values render as `–`. | ||
| `SOURCE` is a lightweight indicator showing whether the selected package came from local discovery or explicit global scanning. | ||
| When both local and global packages are scanned, local packages take precedence. | ||
|
|
||
| ## JSON output | ||
|
|
||
| `--json` prints the `ScanResult` object: | ||
|
|
||
| ```json | ||
| { | ||
| "packageManager": "npm | pnpm | yarn | bun | unknown", | ||
| "packages": [ | ||
| { | ||
| "name": "string", | ||
| "version": "string", | ||
| "source": "local | global", | ||
| "packageRoot": "string", | ||
| "intent": { | ||
| "version": 1, | ||
| "repo": "string", | ||
| "docs": "string", | ||
| "requires": ["string"] | ||
| }, | ||
| "skills": [ | ||
| { | ||
| "name": "string", | ||
| "path": "string", | ||
| "description": "string", | ||
| "type": "string (optional)", | ||
| "framework": "string (optional)" | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| "warnings": ["string"], | ||
| "conflicts": [ | ||
| { | ||
| "packageName": "string", | ||
| "chosen": { | ||
| "version": "string", | ||
| "packageRoot": "string" | ||
| }, | ||
| "variants": [ | ||
| { | ||
| "version": "string", | ||
| "packageRoot": "string" | ||
| } | ||
| ] | ||
| } | ||
| ], | ||
| "nodeModules": { | ||
| "local": { | ||
| "path": "string | null", | ||
| "detected": true, | ||
| "exists": true, | ||
| "scanned": true | ||
| }, | ||
| "global": { | ||
| "path": "string | null", | ||
| "detected": true, | ||
| "exists": true, | ||
| "scanned": false, | ||
| "source": "string (optional)" | ||
| } | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| `packages` are ordered using `intent.requires` when possible. | ||
| When the same package exists both locally and globally and global scanning is enabled, `intent list` prefers the local package. | ||
|
|
||
| ## Common errors | ||
|
|
||
| - Scanner failures are printed as errors | ||
| - Unsupported environments: | ||
| - Yarn PnP without `node_modules` | ||
| - Deno projects without `node_modules` | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,66 @@ | ||
| --- | ||
| title: intent load | ||
| id: intent-load | ||
| --- | ||
|
|
||
| `intent load` loads a compact skill identity from the current install and prints the matching `SKILL.md` content. | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest load <package>#<skill> [--path] [--json] [--global] [--global-only] | ||
| ``` | ||
|
|
||
| ## Options | ||
|
|
||
| - `--path`: print the resolved skill path instead of the file content | ||
| - `--json`: print structured JSON with metadata and content | ||
| - `--global`: load from project packages first, then global packages | ||
| - `--global-only`: load from global packages only | ||
|
|
||
| ## What you get | ||
|
|
||
| - Validates `<package>#<skill>` before scanning | ||
| - Scans project-local packages by default | ||
| - Includes global packages only when `--global` or `--global-only` is passed | ||
| - Prefers local packages when `--global` is used and the same package exists locally and globally | ||
| - Prints raw `SKILL.md` content by default | ||
| - Prints the scanner-reported path when `--path` is passed | ||
|
|
||
| The package can be scoped or unscoped. The skill can include slash-separated sub-skill names. | ||
|
|
||
| Examples: | ||
|
|
||
| ```bash | ||
| npx @tanstack/intent@latest load @tanstack/query#fetching | ||
| npx @tanstack/intent@latest load @tanstack/query#core/fetching | ||
| npx @tanstack/intent@latest load some-lib#core --path | ||
| ``` | ||
|
|
||
| ## JSON output | ||
|
|
||
| `--json` prints: | ||
|
|
||
| ```json | ||
| { | ||
| "package": "@tanstack/query", | ||
| "skill": "fetching", | ||
| "path": "node_modules/@tanstack/query/skills/fetching/SKILL.md", | ||
| "packageRoot": "node_modules/@tanstack/query", | ||
| "source": "local", | ||
| "version": "5.0.0", | ||
| "content": "---\nname: fetching\n---\n\n...", | ||
| "warnings": [] | ||
| } | ||
| ``` | ||
|
|
||
| ## Common errors | ||
|
|
||
| - Missing separator: `Invalid skill use "@tanstack/query": expected <package>#<skill>.` | ||
| - Empty package: `Invalid skill use "#core": package is required.` | ||
| - Empty skill: `Invalid skill use "@tanstack/query#": skill is required.` | ||
| - Missing package: `Cannot resolve skill use "...": package "..." was not found.` | ||
| - Missing skill: `Cannot resolve skill use "...": skill "..." was not found in package "...".` | ||
|
|
||
| ## Related | ||
|
|
||
| - [intent list](./intent-list) | ||
| - [intent install](./intent-install) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Document
nodeModules.local.pathas nullable.NodeModulesScanTarget.pathisstring | nullfor both local and global scan targets, so the JSON schema example should not imply local always has a path.📝 Proposed fix
"local": { - "path": "string", + "path": "string | null", "detected": true, "exists": true, "scanned": true📝 Committable suggestion
🤖 Prompt for AI Agents