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

Remove internal milestone wording from unsupported `git:` source errors.
24 changes: 20 additions & 4 deletions docs/cli/intent-hooks.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ title: intent hooks
id: intent-hooks
---

`intent hooks install` installs lifecycle hooks that surface available Intent skills and enforce loading matching guidance before edits in supported agents.
`intent hooks install` installs lifecycle hooks that surface available Intent skills and gate supported edit tools until they observe an Intent load command.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟡 Minor | ⚡ Quick win

Use the formal lifecycle terminology for the hook catalog.

The trust model defines Available as discovered and Permitted as allowed by intent.skills and intent.exclude. The hook catalog is policy-filtered, so calling it “available” can imply that unlisted skills are surfaced.

  • docs/cli/intent-hooks.md#L6-L6: replace “available Intent skills” with “permitted” or “surfaced” skills.
  • docs/cli/intent-hooks.md#L20-L21: describe the session catalog as containing permitted or surfaced entries.
  • docs/getting-started/quick-start-consumers.md#L59-L59: use the same terminology for the session catalog.
📍 Affects 2 files
  • docs/cli/intent-hooks.md#L6-L6 (this comment)
  • docs/cli/intent-hooks.md#L20-L21
  • docs/getting-started/quick-start-consumers.md#L59-L59
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@docs/cli/intent-hooks.md` at line 6, The hook documentation uses “available”
for policy-filtered skills; update the session-catalog terminology to
“permitted” or “surfaced” consistently. In docs/cli/intent-hooks.md lines 6 and
20-21, revise both descriptions; in
docs/getting-started/quick-start-consumers.md line 59, apply the same
terminology. Preserve the existing lifecycle distinction between Available and
Permitted.


```bash
npx @tanstack/intent@latest hooks install [--scope project|user] [--agents copilot,claude,codex|all]
Expand All @@ -16,14 +16,30 @@ npx @tanstack/intent@latest hooks install [--scope project|user] [--agents copil

## Behavior

### Session behavior

- Installs hook behavior without writing an `intent-skills` guidance block.
- Adds a session-start skill catalog for supported agents so the agent sees available `skill-id: description` entries before it starts work.
- Keeps edit enforcement in place: supported edit tools are blocked until the agent runs `intent load <skill-id>` for matching guidance.
- Returns a session-start skill catalog as agent context with available `skill-id: description` entries.
- Blocks supported edit tools until the hook observes a recognized `intent load <skill-id>` command.
- Uses `package.json#intent.skills` and `package.json#intent.exclude` to control which skills appear in the session catalog.

### Installation behavior

- `--scope project` writes project-local hook config for agents that support it.
- `--scope user` writes user-level agent config and stores runner scripts under `~/.tanstack/intent/hooks`.
- `--agents all` is the default. In project scope, Copilot is skipped because the supported Copilot CLI hook location is user-scoped.
- Run `intent install` separately when you also want to write project guidance.
- Use `package.json#intent.skills` and `package.json#intent.exclude` to control which skills are surfaced in the session catalog.

The hook records a recognized load command before that command completes.

Hooks do not verify that:

- The command succeeded.
- The selected skill matched the task.
- The agent received the returned content.
- The model applied the guidance.

Hook output is an edit gate and observation signal, not proof of activation or correct agent behavior. See [Lifecycle boundaries](../concepts/trust-model#lifecycle-boundaries).

## Hook support

Expand Down
23 changes: 15 additions & 8 deletions docs/cli/intent-install.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,20 @@ npx @tanstack/intent@latest install [--map] [--dry-run] [--print-prompt] [--glob

## Behavior

### Default guidance

- 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.
- Verifies the managed block before reporting success.

### Mapping mode

- Scans packages and writes compact `id`, `run`, and `for` mappings only when `--map` is passed.
- Surfaces packages permitted by `package.json#intent.skills` in `--map` mode. See [Configuration](../concepts/configuration).
- Skips reference, meta, maintainer, and maintainer-only skills in `--map` mode.
- Writes compact skill identities and runnable guidance commands instead of local file 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`.
Expand Down Expand Up @@ -76,13 +81,15 @@ tanstackIntent:

## 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.`
| Result | Message |
| --- | --- |
| Mapping created | `Created AGENTS.md with 1 mapping.` |
| Mappings updated | `Updated AGENTS.md with 2 mappings.` |
| 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.` |

To suppress trust and migration notices in automation, pass `--no-notices`.

Expand Down
31 changes: 19 additions & 12 deletions docs/cli/intent-list.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,38 @@ npx @tanstack/intent@latest list [--json] [--debug] [--global] [--global-only] [

## Options

### Output

- `--json`: print JSON instead of text output
- `--debug`: print discovery debug details to stderr
- `--no-notices`: suppress non-critical notices on stderr; the acknowledged-risk notice for `intent.skills: ["*"]` remains visible

### Scan scope

- `--global`: include global packages after project packages
- `--global-only`: list global packages only
- `--show-hidden`: show unlisted hidden skill sources when run outside an agent session
- `--no-notices`: suppress non-critical notices on stderr

## What you get

### Selection

- Scans project and workspace dependencies for intent-enabled packages and skills
- Surfaces packages permitted by `package.json#intent.skills` (see [Allowlist](#allowlist))
- Includes global packages only when `--global` or `--global-only` is passed
- Includes warnings from discovery
- Excludes packages and skills matched by package.json `intent.exclude`
- Prints debug details to stderr when `--debug` is passed
- If no packages are discovered, prints `No intent-enabled packages found.`

When both local and global packages are scanned, local packages take precedence. `SOURCE` shows whether the selected package came from local discovery or explicit global scanning.

### Text output

- Summary line with package count and skill count
- Package table columns: `PACKAGE`, `SOURCE`, `VERSION`, `SKILLS`
- Skill tree grouped by package
- Optional warnings section (`⚠ ...` per warning)
- Optional notices section on stderr (`ℹ ...` per notice), suppressed by `--no-notices`
- Discovery warnings (`⚠ ...`) on stdout
- `No intent-enabled packages found.` when no packages are discovered

`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.
Policy notices (`ℹ ...`) are written to stderr.

## JSON output

Expand Down Expand Up @@ -118,7 +126,7 @@ The list as a whole has three special forms:
- **Empty** (`"skills": []`): no package is surfaced, with an info notice printed to stderr.
- **Wildcard** (`"skills": ["*"]`): every discovered package is surfaced, with an acknowledged-risk notice printed to stderr. This exact trust-all entry is distinct from a scoped package pattern such as `@tanstack/*`.

A package that ships skills but is not listed or matched by a pattern is dropped. When packages are dropped this way, Intent prints one summary line naming them so you can opt in. In agent sessions, hidden sources are reported by count only; run `intent list --show-hidden` outside the agent session to review candidates. An exact entry or pattern that matches no discovered package is reported as well. Package patterns support `*` wildcards. Matching is currently by package name. See [Configuration](../concepts/configuration) and [Trust model](../concepts/trust-model).
A package that ships skills but is not listed or matched by a pattern is dropped. When packages are dropped this way, Intent prints one policy notice naming them so you can opt in. In agent sessions, hidden sources are reported by count only; run `intent list --show-hidden` outside the agent session to review candidates. An exact entry or pattern that matches no discovered package is reported as well. Package patterns support `*` wildcards. Matching uses both package name and source kind. See [Configuration](../concepts/configuration) and [Trust model](../concepts/trust-model).

## Excludes

Expand All @@ -136,10 +144,9 @@ Manage persistent excludes with `intent exclude add|remove|list`.

A pattern without `#` excludes a whole package. A pattern with `#` excludes a single skill (`@scope/pkg#search-params`), and the skill segment may itself be a glob (`@scope/pkg#experimental-*`). A pattern may cross package boundaries at skill granularity (`*#experimental-*`). The `#*` shortcut (`@scope/pkg#*`) excludes the whole package. Only exact names and `*` wildcards are supported on each segment. Bare package-name patterns keep working unchanged.

An excluded package never triggers the unlisted-source warning, because an exclude is an explicit decision rather than an oversight.
An excluded package never triggers the unlisted-source notice, because an exclude is an explicit decision rather than an oversight.

## Common errors

- Scanner failures are printed as errors
- Unsupported environments:
- Deno projects without `node_modules`
- Deno projects without `node_modules` are unsupported
20 changes: 19 additions & 1 deletion docs/cli/intent-load.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,27 @@ npx @tanstack/intent@latest load <package>#<skill> [--path] [--json] [--debug] [

## What you get

### Resolution

- Validates `<package>#<skill>` before scanning
- Scans project-local packages by default
- Includes global packages only when `--global` or `--global-only` is passed
- Refuses before scanning when the target package is not permitted by `package.json#intent.skills`
- Checks the target package name against `package.json#intent.skills` before resolution, then enforces its source kind after resolution
- Refuses before scanning when the target package or skill matches `intent.exclude`
Comment thread
coderabbitai[bot] marked this conversation as resolved.

### Selection

- Prefers local packages when `--global` is used and the same package exists locally and globally
- Accepts an unambiguous short skill name when a package-prefixed skill exists

### Output

- Prints raw `SKILL.md` content by default
- Prints the scanner-reported path when `--path` is passed
- Prints debug details to stderr when `--debug` is passed

A successful load proves that Intent resolved the selected skill under current policy and returned its content. It does not prove that the skill was relevant to the task, reached an agent's active context, or was followed correctly. See [Lifecycle boundaries](../concepts/trust-model#lifecycle-boundaries).

The package can be scoped or unscoped. The skill can include slash-separated sub-skill names.

Examples:
Expand Down Expand Up @@ -60,12 +70,20 @@ npx @tanstack/intent@latest load some-lib#core --path

## Common errors

### Invalid skill identity

- 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.`

### Resolution failures

- Missing package: `Cannot resolve skill use "...": package "..." was not found.`
- Missing skill: `Cannot resolve skill use "...": skill "..." was not found in package "...".`
- Skill suggestion: `Did you mean @tanstack/router-core#router-core/auth-and-guards?`

### Policy refusals

- Unlisted package: `Cannot load skill use "...": package "..." is not listed in intent.skills.`
- Excluded package: `Cannot load skill use "...": package "..." is excluded by Intent configuration.`
- Excluded skill: `Cannot load skill use "...": skill "..." is excluded by Intent configuration.`
Expand Down
59 changes: 31 additions & 28 deletions docs/cli/intent-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,34 @@ title: setup commands
id: intent-setup
---

Intent exposes publishing setup as two commands.

```bash
npx @tanstack/intent@latest edit-package-json
npx @tanstack/intent@latest setup
```
Intent exposes publishing setup as two commands.
```bash
npx @tanstack/intent@latest edit-package-json
npx @tanstack/intent@latest setup
```

## Commands

- `edit-package-json`: add or normalize `package.json` entries needed to publish skills
- `setup`: copy workflow templates to `.github/workflows`
- `setup-github-actions`: legacy alias for `setup`
- `edit-package-json`: add or normalize `package.json` entries needed to publish skills
- `setup`: copy workflow templates to `.github/workflows`
- `setup-github-actions`: legacy alias for `setup`

## What each command changes

- `edit-package-json`
- Requires a valid `package.json` in current directory
- Ensures `keywords` includes `tanstack-intent`
- Ensures `files` includes required publish entries
- Preserves existing indentation
- `setup`
- Copies the `check-skills.yml` workflow template from `@tanstack/intent/meta/templates/workflows` to `.github/workflows`
- Applies variable substitution (`PACKAGE_NAME`, `PACKAGE_LABEL`, `PAYLOAD_PACKAGE`, `REPO`, `DOCS_PATH`, `SRC_PATH`, `WATCH_PATHS`)
- Detects the workspace root in monorepos and writes repo-level workflows there
- Skips files that already exist at destination
### `edit-package-json`

- Requires a valid `package.json` in the current directory
- Ensures `keywords` includes `tanstack-intent`
- Ensures `files` includes required publish entries
- Preserves existing indentation

### `setup`

- Copies the `check-skills.yml` workflow template from `@tanstack/intent/meta/templates/workflows` to `.github/workflows`
- Applies variable substitution (`PACKAGE_NAME`, `PACKAGE_LABEL`, `PAYLOAD_PACKAGE`, `REPO`, `DOCS_PATH`, `SRC_PATH`, `WATCH_PATHS`)
- Detects the workspace root in monorepos and writes repo-level workflows there
- Skips files that already exist at the destination

## Required `files` entries

Expand All @@ -39,15 +42,15 @@ npx @tanstack/intent@latest setup
## Common errors

- Missing or invalid `package.json` when running `edit-package-json`
- Missing template source when running `setup`

## Notes

- `setup` skips existing files
- `check-skills.yml` validates skills on PRs and opens review PRs from release/manual runs
- To adopt updated workflow templates, delete or move the old generated workflow files first, then rerun `setup`
- If your repo has an older generated `validate-skills.yml`, remove it after adopting the current `check-skills.yml`; PR validation now lives in `check-skills.yml`
- In monorepos, run `setup` from either the repo root or a package directory; Intent writes workflows to the workspace root
- Missing template source when running `setup`

## Notes
- `setup` skips existing files
- `check-skills.yml` validates skills on PRs and opens review PRs from release/manual runs
- To adopt updated workflow templates, delete or move the old generated workflow files first, then rerun `setup`
- If your repo has an older generated `validate-skills.yml`, remove it after adopting the current `check-skills.yml`; PR validation now lives in `check-skills.yml`
- In monorepos, run `setup` from either the repo root or a package directory; Intent writes workflows to the workspace root

## Related

Expand Down
22 changes: 16 additions & 6 deletions docs/cli/intent-stale.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,22 @@ npx @tanstack/intent@latest stale [--json]

## Behavior

### Scope

- Checks the current package by default
- From a monorepo root, checks workspace packages that ship skills and also reports public workspace packages with no skill or artifact coverage
- Applies the `package.json#intent.skills` allowlist when falling back to installed dependencies; workspace packages are first-party and checked regardless. See [Configuration](../concepts/configuration).
- When `dir` is provided, scopes the check to the targeted package or skills directory
- Computes one staleness report per package

### Coverage

- Reads repo-root `_artifacts/*domain_map.yaml` and `_artifacts/*skill_tree.yaml` when present
- Flags public workspace packages that are not represented by generated skills or artifact coverage
- Skips workspace packages with `"private": true`

### Output and workflow state

- Prints text output by default or JSON with `--json`
- Prints a non-failing workflow update reminder when `.github/workflows/check-skills.yml` is missing the current `intent-workflow-version` stamp
- If no packages are found, prints `No intent-enabled packages found.`
Expand Down Expand Up @@ -74,12 +82,14 @@ Ignored packages are excluded from missing coverage signals. Private workspace p

Report fields:

- `library`: package name
- `currentVersion`: latest version from npm registry (or `null` if unavailable)
- `skillVersion`: `library_version` from skills (or `null`)
- `versionDrift`: `major | minor | patch | null`
- `skills`: array of per-skill checks
- `signals`: array of artifact and workspace coverage checks
| Field | Meaning |
| --- | --- |
| `library` | Package name |
| `currentVersion` | Latest version from npm registry, or `null` if unavailable |
| `skillVersion` | `library_version` from skills, or `null` |
| `versionDrift` | `major`, `minor`, `patch`, or `null` |
| `skills` | Per-skill checks |
| `signals` | Artifact and workspace coverage checks |

Skill fields:

Expand Down
12 changes: 8 additions & 4 deletions docs/cli/intent-validate.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,21 +49,25 @@ npx @tanstack/intent@latest validate --fix

## Validation checks

For each discovered `SKILL.md`:
### File structure

- Frontmatter delimiter and structure are valid
- YAML frontmatter parses successfully
- Required fields exist: `name`, `description`
- `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
- `name` uses only lowercase letters, numbers, and hyphens and is at most 64 characters

### Field rules

- 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

If `<dir>/_artifacts` exists, it also validates artifacts:
### Artifacts

When `<dir>/_artifacts` exists, Intent also checks:

- Required files: `domain_map.yaml`, `skill_spec.md`, `skill_tree.yaml`
- Required files must be non-empty
Expand Down
Loading
Loading