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/young-bats-shop.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@tanstack/intent': patch
---

Improves the intent CLI with better setup validation, clearer feedback, version conflict detection, and improved monorepo support.
61 changes: 49 additions & 12 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ name: Release

on:
push:
# branches: [main, alpha, beta, rc]
branches: [main, '*-pre', '*-maint']

concurrency:
group: ${{ github.workflow }}-${{ github.event.number || github.ref }}
cancel-in-progress: true
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false

env:
NX_CLOUD_ACCESS_TOKEN: ${{ secrets.NX_CLOUD_ACCESS_TOKEN }}
Expand All @@ -19,7 +19,7 @@ permissions:
jobs:
release:
name: Release
if: github.repository_owner == 'TanStack'
if: "github.repository_owner == 'TanStack' && !contains(github.event.head_commit.message, 'ci: changeset release')"
runs-on: ubuntu-latest
steps:
- name: Checkout
Expand All @@ -29,13 +29,50 @@ jobs:
- name: Setup Tools
uses: tanstack/config/.github/setup@main
- name: Run Tests
run: pnpm run test:ci
- name: Run Changesets (version or publish)
uses: changesets/action@v1.5.3
with:
version: pnpm run changeset:version
publish: pnpm run changeset:publish
commit: 'ci: Version Packages'
title: 'ci: Version Packages'
run: pnpm run test:ci --parallel=3
- name: Version Packages
run: pnpm run changeset:version
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Commit Release
id: commit
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
git add .
if git commit -m "ci: changeset release"; then
git push
echo "committed=true" >> "$GITHUB_OUTPUT"
fi
- name: Set Dist Tag
id: dist-tag
if: steps.commit.outputs.committed == 'true'
run: |
branch="${GITHUB_REF_NAME}"
if [[ "$branch" == *-pre ]]; then
echo "tag=next" >> "$GITHUB_OUTPUT"
elif [[ "$branch" == *-maint ]]; then
echo "tag=maint" >> "$GITHUB_OUTPUT"
fi
- name: Publish Packages
if: steps.commit.outputs.committed == 'true'
run: |
if [[ -n "${{ steps.dist-tag.outputs.tag }}" ]]; then
pnpm run changeset:publish --tag "${{ steps.dist-tag.outputs.tag }}"
else
pnpm run changeset:publish
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
- name: Create GitHub Release
if: steps.commit.outputs.committed == 'true'
run: |
if [[ "${{ steps.dist-tag.outputs.tag }}" == 'next' ]]; then
node scripts/create-github-release.mjs --prerelease
else
node scripts/create-github-release.mjs
fi
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
10 changes: 7 additions & 3 deletions docs/cli/intent-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,14 @@ They also ask you to:

1. Check for an existing block first
2. Run `intent list` to discover installed skills
3. Add task-to-skill mappings
4. Preserve all content outside the tagged block
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)
- [Setting Up Agent Config](../guides/consumers/agent-config-setup)
- [Quick Start for Consumers](../getting-started/quick-start-consumers)
11 changes: 7 additions & 4 deletions docs/getting-started/quick-start-consumers.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,14 @@ npx @tanstack/intent@latest install
```

This prints a skill that instructs your AI agent to:
1. Check for existing `intent-skills` mappings in your config files (CLAUDE.md, .cursorrules, etc.)
2. Run `intent list` to discover available skills from installed packages
1. Check for existing `intent-skills` mappings in your config files (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, etc.)
2. Run `npx @tanstack/intent@latest list` to discover available skills from installed packages
3. Scan your repository structure to understand your project
4. Propose relevant skill-to-task mappings based on your codebase patterns
5. Write or update an `intent-skills` block in your agent config
5. Ask if you want a target other than `AGENTS.md`
6. Write or update an `intent-skills` block in your agent config

If an `intent-skills` block already exists, the agent updates that file in place. If no block exists, `AGENTS.md` is the default target.

Your agent will create mappings like:

Expand All @@ -45,7 +48,7 @@ Skills version with library releases. When you update a library:
npm update @tanstack/react-query
```

The new version brings updated skills automatically — you don't need to do anything. The skills are shipped with the library, so you always get the version that matches your installed code.
The new version brings updated skills automatically — you don't need to do anything. The skills are shipped with the library, so you always get the version that matches your installed code. If a package is installed both locally and globally, Intent prefers the local version.

If you need to see what skills have changed, run:

Expand Down
6 changes: 3 additions & 3 deletions docs/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ id: overview

`@tanstack/intent` is a CLI for shipping and consuming Agent Skills as package artifacts.

Skills are markdown documents that teach AI coding agents how to use your library correctly. Intent versions them with your releases, ships them inside npm packages, discovers them from `node_modules`, and helps agents load them automatically when working on matching tasks.
Skills are markdown documents that teach AI coding agents how to use your library correctly. Intent versions them with your releases, ships them inside npm packages, discovers them from local and accessible global `node_modules`, and helps agents load them automatically when working on matching tasks.

## What Intent does

Expand All @@ -30,13 +30,13 @@ Intent provides tooling for two workflows:
npx @tanstack/intent@latest list
```

Scans `node_modules` for intent-enabled packages and shows available skills with paths and descriptions.
Scans local `node_modules` and any accessible global `node_modules` for intent-enabled packages, preferring local packages when both exist.

```bash
npx @tanstack/intent@latest install
```

Prints instructions for your agent to create `intent-skills` mappings in your config files (CLAUDE.md, .cursorrules, etc.).
Prints instructions for your agent to create `intent-skills` mappings in your config files (`AGENTS.md`, `CLAUDE.md`, `.cursorrules`, etc.). Existing mappings are updated in place; otherwise `AGENTS.md` is the default target.

### Scaffolding and validation

Expand Down
47 changes: 42 additions & 5 deletions packages/intent/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,28 @@ Docs target humans who browse. Types check individual API calls but can't encode

The ecosystem already moves toward agent-readable knowledge — Cursor rules, CLAUDE.md files, skills directories. But delivery is stuck in copy-paste: hunt for a community-maintained rules file, paste it into your config, repeat for every tool. No versioning, no update path, no staleness signal.

## Skills: versioned knowledge in npm
## Skills: versioned knowledge in your package manager

A skill is a short, versioned document that tells agents how to use a specific capability of your library — correct patterns, common mistakes, and when to apply them. Skills ship inside your npm package and travel with the tool via `npm update` — not the model's training cutoff, not community-maintained rules files, not prompt snippets in READMEs. Versioned knowledge the maintainer owns, updated when the package updates.
A skill is a short, versioned document that tells agents how to use a specific capability of your library — correct patterns, common mistakes, and when to apply them. Skills ship inside your package and travel with the tool via your normal package manager update flow — not the model's training cutoff, not community-maintained rules files, not prompt snippets in READMEs. Versioned knowledge the maintainer owns, updated when the package updates.

Each skill declares its source docs. When those docs change, the CLI flags the skill for review. One source of truth, one derived artifact that stays in sync.

The [Agent Skills spec](https://agentskills.io) is an open standard already adopted by VS Code, GitHub Copilot, OpenAI Codex, Cursor, Claude Code, Goose, Amp, and others.

## Quick Start

### Command runners

Use whichever command runner matches your environment:

| Tool | Pattern |
| ---- | -------------------------------------------- |
| npm | `npx @tanstack/intent@latest <command>` |
| pnpm | `pnpm dlx @tanstack/intent@latest <command>` |
| bun | `bunx @tanstack/intent@latest <command>` |

If you use Deno, support is best-effort today via `npm:` interop with `node_modules` enabled. First-class Deno runtime support is not implemented yet.

### For library consumers

Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .cursorrules, etc.):
Expand All @@ -28,7 +40,7 @@ Set up skill-to-task mappings in your project's agent config files (CLAUDE.md, .
npx @tanstack/intent@latest install
```

No per-library setup. No hunting for rules files. Install the package, run `npx @tanstack/intent@latest install`, and the agent understands the tool. Update the package, and skills update too.
No per-library setup. No hunting for rules files. Install the package, run `npx @tanstack/intent@latest install` through your preferred command runner, and the agent understands the tool. Update the package, and skills update too.

List available skills from installed packages:

Expand All @@ -52,23 +64,48 @@ Validate your skill files:
npx @tanstack/intent@latest validate
```

In a monorepo, you can validate a package from the repo root:

```bash
npx @tanstack/intent@latest validate packages/router/skills
```

Check for skills that have fallen behind their sources:

```bash
npx @tanstack/intent@latest stale
```

From a monorepo root, `intent stale` checks every workspace package that ships skills. To scope it to one package, pass a directory like `intent stale packages/router`.

Copy CI workflow templates into your repo so validation and staleness checks run on every push:

```bash
npx @tanstack/intent@latest setup-github-actions
```

## Compatibility

| Environment | Status | Notes |
| -------------- | ----------- | -------------------------------------------------- |
| Node.js + npm | Supported | Use `npx @tanstack/intent@latest <command>` |
| Node.js + pnpm | Supported | Use `pnpm dlx @tanstack/intent@latest <command>` |
| Node.js + Bun | Supported | Use `bunx @tanstack/intent@latest <command>` |
| Deno | Best-effort | Requires `npm:` interop and `node_modules` support |
| Yarn PnP | Unsupported | `@tanstack/intent` scans `node_modules` |

## Monorepos

- Run `npx @tanstack/intent@latest setup-github-actions` from either the repo root or a package directory. Intent detects the workspace root and writes workflows to the repo-level `.github/workflows/` directory.
- Generated workflows are monorepo-aware: validation loops over workspace packages with skills, staleness checks run from the workspace root, and notify workflows watch package `src/` and docs paths.
- Run `npx @tanstack/intent@latest validate packages/<pkg>/skills` from the repo root to validate one package without root-level packaging warnings.
- Run `npx @tanstack/intent@latest stale` from the repo root to check all workspace packages with skills, or `intent stale packages/<pkg>` to check one package.

## Keeping skills current

The real risk with any derived artifact is staleness. `npx @tanstack/intent@latest stale` flags skills whose source docs have changed, and CI templates catch drift before it ships.

The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next `npm update`. Every support interaction produces an artifact that prevents the same class of problem for all future users — not just the one who reported it.
The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` lets users submit structured reports when a skill produces wrong output — which skill, which version, what broke. That context flows back to the maintainer, and the fix ships to everyone on the next package update. Every support interaction produces an artifact that prevents the same class of problem for all future users — not just the one who reported it.

## CLI Commands

Expand All @@ -80,7 +117,7 @@ The feedback loop runs both directions. `npx @tanstack/intent@latest feedback` l
| `npx @tanstack/intent@latest scaffold` | Print the guided skill generation prompt |
| `npx @tanstack/intent@latest validate [dir]` | Validate SKILL.md files |
| `npx @tanstack/intent@latest setup-github-actions` | Copy CI templates into your repo |
| `npx @tanstack/intent@latest stale [--json]` | Check skills for version drift |
| `npx @tanstack/intent@latest stale [dir] [--json]` | Check skills for version drift |
| `npx @tanstack/intent@latest feedback` | Submit skill feedback |

## License
Expand Down
2 changes: 1 addition & 1 deletion packages/intent/meta/feedback-collection/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ during the session:

- **Loaded and used:** Skills you read and actively followed.
- **Available but not loaded:** Skills that were installed (discoverable via
`intent list`) but you never read. This is important — many issues stem from
`npx @tanstack/intent@latest list`) but you never read. This is important — many issues stem from
the agent not loading the right skill, not from the skill itself being wrong.

### 1b: Gap detection
Expand Down
8 changes: 4 additions & 4 deletions packages/intent/meta/templates/workflows/check-skills.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
# Triggers: new release published, or manual workflow_dispatch.
#
# Template variables (replaced by `intent setup`):
# {{PACKAGE_NAME}} — e.g. @tanstack/query
# {{PACKAGE_LABEL}} — e.g. @tanstack/query or my-workspace workspace

name: Check Skills

Expand Down Expand Up @@ -36,12 +36,12 @@ jobs:
node-version: 20

- name: Install intent
run: npm install {{PACKAGE_NAME}}
run: npm install -g @tanstack/intent

- name: Check staleness
id: stale
run: |
OUTPUT=$(npx @tanstack/intent stale --json 2>&1) || true
OUTPUT=$(intent stale --json 2>&1) || true
echo "$OUTPUT"

# Check if any skills need review
Expand Down Expand Up @@ -81,7 +81,7 @@ jobs:
const summary = lines.join('\n');

const prompt = [
'Review and update the following stale intent skills for {{PACKAGE_NAME}}:',
'Review and update the following stale intent skills for {{PACKAGE_LABEL}}:',
'',
...stale.map(s => '- ' + s.skill + ': ' + s.reasons.join(', ')),
'',
Expand Down
8 changes: 4 additions & 4 deletions packages/intent/meta/templates/workflows/notify-intent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
# as the INTENT_NOTIFY_TOKEN repository secret.
#
# Template variables (replaced by `intent setup`):
# {{PACKAGE_NAME}} — e.g. @tanstack/query
# {{DOCS_PATH}} — e.g. docs/**
# {{SRC_PATH}} — e.g. packages/query-core/src/**
# {{PAYLOAD_PACKAGE}} — e.g. @tanstack/query or my-workspace workspace
# {{DOCS_PATH}} — e.g. docs/**
# {{SRC_PATH}} — e.g. packages/query-core/src/**

name: Notify Intent

Expand Down Expand Up @@ -46,7 +46,7 @@ jobs:
event-type: skill-check
client-payload: |
{
"package": "{{PACKAGE_NAME}}",
"package": "{{PAYLOAD_PACKAGE}}",
"sha": "${{ github.sha }}",
"changed_files": ${{ steps.changes.outputs.files }}
}
4 changes: 2 additions & 2 deletions packages/intent/meta/tree-generator/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ Every skill has a `type` field in its frontmatter. Valid types:
| `composition` | Integration between two or more libraries | `electric-drizzle` |
| `security` | Audit checklist or security validation | `electric-security-check` |

Agents discover skills via `tanstack intent list` and read them directly
Agents discover skills via `npx @tanstack/intent list` and read them directly
from `node_modules`. Framework skills declare a `requires` dependency on
their core skill so agents load them in the right order.

Expand Down Expand Up @@ -274,7 +274,7 @@ packages/
│ └── package.json # Add "skills" to files array
```

Run `intent edit-package-json` to wire each package's `package.json`
Run `npx @tanstack/intent@latest edit-package-json` to wire each package's `package.json`
automatically (adds `"skills"`, `"bin"`, and `"!skills/_artifacts"` to the
`files` array, and adds the `bin` entry if missing).

Expand Down
5 changes: 3 additions & 2 deletions packages/intent/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"types": "./dist/index.d.mts"
},
"./intent-library": {
"import": "./dist/intent-library.mjs"
"import": "./dist/intent-library.mjs",
"types": "./dist/intent-library.d.mts"
}
},
"bin": {
Expand All @@ -32,7 +33,7 @@
"tsdown": "^0.19.0"
},
"scripts": {
"prepack": "pnpm run build",
"prepack": "npm run build",
"build": "tsdown src/index.ts src/cli.ts src/setup.ts src/intent-library.ts src/library-scanner.ts --format esm --dts",
"test:lib": "vitest run",
"test:types": "tsc --noEmit"
Expand Down
Loading
Loading