Skip to content

feat: add @tanstack/intent AI agent skills for Router and Start#6866

Open
tannerlinsley wants to merge 3 commits intomainfrom
feat/tanstack-intent-skills
Open

feat: add @tanstack/intent AI agent skills for Router and Start#6866
tannerlinsley wants to merge 3 commits intomainfrom
feat/tanstack-intent-skills

Conversation

@tannerlinsley
Copy link
Member

@tannerlinsley tannerlinsley commented Mar 8, 2026

Summary

Adds @tanstack/intent SKILL.md files across 11 packages to help AI coding agents (Claude, Cursor, Copilot, etc.) generate correct TanStack Router and Start code. Each skill covers patterns, API usage, and common failure modes that agents frequently get wrong.

What's included

28 SKILL.md files across 11 packages:

Package Skills Coverage
router-core 10 Core concepts, search/path params, navigation, data loading, auth/guards, code splitting, not-found/errors, type safety, SSR
react-router 3 React bindings, Router+Query composition, migration from React Router
start-client-core 6 Start setup, server functions, middleware, execution model, server routes, deployment
react-start 2 React Start bindings, migration from Next.js
virtual-file-routes 1 Programmatic route tree building
router-plugin 1 Bundler plugin configuration
start-server-core 1 Server-side runtime
solid-router 1 Solid bindings
vue-router 1 Vue bindings
solid-start 1 Solid Start bindings
vue-start 1 Vue Start bindings

Per-package scaffolding:

  • bin/intent.js shim for npx intent discovery
  • skills/_artifacts/ metadata (domain_map.yaml, skill_spec.md, skill_tree.yaml)
  • @tanstack/intent devDependency
  • Package.json wired with files and bin entries

Root-level artifacts:

  • _artifacts/skill_tree.yaml — consolidated Router skill tree (13 skills)
  • _artifacts/start_skill_tree.yaml — consolidated Start skill tree (8 skills)
  • _artifacts/domain_map.yaml and _artifacts/start_domain_map.yaml — domain maps

Key design decisions:

  • Core/framework-agnostic skills live in core packages (router-core, start-client-core)
  • Framework-specific skills live in framework packages (react-router, solid-router, vue-router, etc.)
  • Every skill reinforces TanStack's own API patterns — agents confuse Router/Start with Next.js or React Router due to training data
  • All skills emphasize full type inference (never cast, never annotate inferred values)
  • All 28 skills pass @tanstack/intent validate (under 500 lines, correct frontmatter)

GitHub labels created: 28 skill:* labels for issue/PR categorization

Summary by CodeRabbit

  • New Features

    • Added comprehensive skill documentation and guides across TanStack Router and TanStack Start libraries, covering routing, navigation, data loading, authentication, deployment, and server functions.
    • Introduced the intent CLI tool for skill validation and management across packages.
  • Documentation

    • New migration guides from React Router and Next.js.
    • Added extensive reference documentation with code examples and best practices.
  • Chores

    • Updated package configurations for skill distribution and CLI integration.
    • Added automated skill validation workflows.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 8, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This pull request introduces comprehensive skill documentation and metadata infrastructure for the TanStack Router ecosystem. It adds documentation files (SKILL.md), domain maps, skill specs, and skill trees across multiple packages, along with CLI bin scripts for the @tanstack/intent library, GitHub Actions workflows for skill validation and notifications, and package configuration updates to support the new skill distribution system.

Changes

Cohort / File(s) Summary
Skill Documentation for Router Core
packages/router-core/skills/router-core/*, packages/router-core/skills/router-core/*/SKILL.md, packages/router-core/skills/router-core/search-params/references/*
Added comprehensive SKILL.md documentation files covering auth-and-guards, code-splitting, data-loading, navigation, not-found-and-errors, path-params, search-params, ssr, and type-safety sub-skills, plus validation patterns reference guide for search params.
Skill Artifacts for Router Core
packages/router-core/skills/_artifacts/domain_map.yaml, packages/router-core/skills/_artifacts/skill_spec.md, packages/router-core/skills/_artifacts/skill_tree.yaml
Added domain map, skill specification, and skill tree YAML/Markdown artifacts documenting domains, skills, failure modes, and cross-references for TanStack Router Core.
Skill Documentation for React Router
packages/react-router/skills/react-router/SKILL.md, packages/react-router/skills/compositions/router-query/SKILL.md, packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
Added documentation for React bindings, Router-Query integration patterns, and step-by-step migration guide from React Router v7 to TanStack Router.
Skill Artifacts for React Router
_artifacts/domain_map.yaml, _artifacts/skill_spec.md, _artifacts/skill_tree.yaml
Added domain, skill, and skill tree artifacts for TanStack Router project-level documentation and guidance.
Skill Documentation for TanStack Start (Core & Client)
packages/start-client-core/skills/start-core/*, packages/react-start/skills/react-start/SKILL.md, packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md, packages/start-server-core/skills/start-server-core/SKILL.md
Added comprehensive documentation for Start Core skills (server functions, middleware, execution model, server routes, deployment), React Start bindings, and Next.js migration guide, plus server-core runtime documentation.
Skill Artifacts for TanStack Start
packages/react-start/skills/_artifacts/*, packages/start-client-core/skills/_artifacts/*, packages/start-server-core/skills/_artifacts/*, _artifacts/start_domain_map.yaml, _artifacts/start_skill_tree.yaml
Added domain maps, skill specs, and skill trees for Start framework across React Start, Start Client Core, and Start Server Core packages.
Framework Bindings Documentation
packages/solid-router/skills/solid-router/SKILL.md, packages/solid-start/skills/solid-start/SKILL.md, packages/vue-router/skills/vue-router/SKILL.md, packages/vue-start/skills/vue-start/SKILL.md, packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md
Added Solid Router, Solid Start, Vue Router, Vue Start, and Virtual File Routes skill documentation with framework-specific setup and usage patterns.
Framework Bindings Artifacts
packages/solid-router/skills/_artifacts/*, packages/solid-start/skills/_artifacts/*, packages/vue-router/skills/_artifacts/*, packages/vue-start/skills/_artifacts/*, packages/virtual-file-routes/skills/_artifacts/*, packages/router-plugin/skills/_artifacts/*
Added domain maps, skill specs, and skill trees for all framework bindings and router plugin.
CLI & Intent Bin Scripts
packages/*/bin/intent.js
Added 10 similar bin/intent.js scripts across react-router, react-start, router-core, router-plugin, solid-router, solid-start, start-client-core, start-server-core, virtual-file-routes, and vue-start packages, each exposing the @tanstack/intent CLI with fallback installation guidance.
Package Configuration Updates
packages/*/package.json (11 files)
Updated files arrays to include "skills", "bin", and exclude "!skills/_artifacts"; added "@tanstack/intent" devDependency; added bin entry mapping "intent" to "./bin/intent.js" in react-router, react-start, router-core, router-plugin, solid-router, solid-start, start-client-core, start-server-core, virtual-file-routes, vue-router, and vue-start.
GitHub Actions Workflows
.github/workflows/check-skills.yml, .github/workflows/notify-playbooks.yml, .github/workflows/validate-skills.yml
Added three new workflows: check-skills for detecting and reporting stale skills via PR, notify-playbooks for dispatching skill-check events to intent repository, and validate-skills for validating skill directory structure on pull requests.
ESLint Configuration Updates
packages/react-router/eslint.config.ts, packages/solid-router/eslint.config.ts, packages/vue-router/eslint.config.ts, packages/vue-start/eslint.config.ts
Added ignores pattern for bin/** directory across four packages to exclude auto-generated bin scripts from linting.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 Whiskers twitching with delight,
Skills documented, shining bright!
From Router Core to Vue's sweet dance,
Intent CLI gives each package a chance!
Domain maps and trees take flight,
TanStack wisdom, bundled just right!

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat: add @tanstack/intent AI agent skills for Router and Start' directly and accurately describes the primary change: adding AI agent skills documentation across multiple packages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/tanstack-intent-skills
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

@nx-cloud
Copy link

nx-cloud bot commented Mar 8, 2026

View your CI Pipeline Execution ↗ for commit 5a08dfd

Command Status Duration Result
nx affected --targets=test:eslint,test:unit,tes... ✅ Succeeded 10m 16s View ↗
nx run-many --target=build --exclude=examples/*... ✅ Succeeded 2m 10s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-13 06:31:50 UTC

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 17

Note

Due to the large number of review comments, Critical, Major severity comments were prioritized as inline comments.

🟡 Minor comments (28)
packages/router-core/skills/router-core/search-params/SKILL.md-26-28 (1)

26-28: ⚠️ Potential issue | 🟡 Minor

Fix the split blockquote.

The blank line between these two quoted warnings trips markdownlint MD028 and can make the docs check fail. Keep them in one contiguous blockquote or turn them into separate paragraphs.

📝 Proposed fix
 > **CRITICAL**: Use `fallback()` from `@tanstack/zod-adapter`, NOT zod's `.catch()`. Using `.catch()` makes the output type `unknown`, destroying type safety.
-
 > **CRITICAL**: Types are fully inferred. Never annotate the return of `useSearch()`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/search-params/SKILL.md` around lines
26 - 28, Remove the blank line splitting the two quoted warnings so they form a
single contiguous blockquote (or alternatively render each as its own
paragraph); specifically, merge the lines containing "**CRITICAL**: Use
`fallback()` from `@tanstack/zod-adapter`, NOT zod's `.catch()`." and
"**CRITICAL**: Types are fully inferred. Never annotate the return of
`useSearch()`." into one blockquote section to fix the MD028 markdownlint error.
packages/router-core/skills/router-core/not-found-and-errors/SKILL.md-23-23 (1)

23-23: ⚠️ Potential issue | 🟡 Minor

Remove blank line between blockquotes.

The blank line between the two blockquote sections violates markdownlint rule MD028. Either merge the blockquotes or remove the blank line for consistency.

📝 Proposed fix
 > **CRITICAL**: Do NOT use the deprecated `NotFoundRoute`. When present, `notFound()` and `notFoundComponent` will NOT work. Remove it and use `notFoundComponent` instead.
-
 > **CRITICAL**: `useLoaderData` may be undefined inside `notFoundComponent`. Use `useParams`, `useSearch`, or `useRouteContext` instead.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/not-found-and-errors/SKILL.md` at
line 23, Remove the blank line between the two blockquote sections in SKILL.md
to satisfy markdownlint MD028; locate the two consecutive blockquote blocks (the
lines starting with ">") and either merge them into a single continuous
blockquote or delete the empty line between them so they appear as one
contiguous block.
packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md-23-25 (1)

23-25: ⚠️ Potential issue | 🟡 Minor

Fix the markdownlint warnings in this new skill doc.

Line 24 triggers MD028 because the blockquote is split by a raw blank line, and Line 462 triggers MD040 because the fence has no language. Small issues, but they keep the doc lint output noisy.

Suggested doc tweak
 > **CRITICAL**: If your UI is blank after migration, open the console. Errors like "cannot use useNavigate outside of context" mean React Router imports remain alongside TanStack Router imports. Uninstall `react-router` to surface them as TypeScript errors.
-
+>
 > **CRITICAL**: TanStack Router uses `to` + `params` for navigation, NOT template literal paths. Never interpolate params into the `to` string.
-```
+```text
 React Router: /posts/:postId
 TanStack Router: /posts/$postId
</details>


Also applies to: 462-465

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
around lines 23 - 25, The markdown has two lint issues: a blockquote split by a
raw blank line (MD028) and a fenced code block with no language (MD040) in the
SKILL.md content; fix by removing the stray blank line inside the blockquote so
the two CRITICAL lines remain contiguous, and add a language identifier (e.g.,
text) to the triple-backtick fence shown in the suggested example (also
update the same fence at the other occurrence referenced) so the linter stops
flagging MD028 and MD040.


</details>

</blockquote></details>
<details>
<summary>packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md-388-395 (1)</summary><blockquote>

`388-395`: _⚠️ Potential issue_ | _🟡 Minor_

**Include `react-router-dom` in the cleanup search.**

Line 391 and Line 392 only catch `from 'react-router'`, so stale `react-router-dom` imports slip past this checklist step. `npx tsc --noEmit` later helps, but the search itself is incomplete.

<details>
<summary>Suggested doc tweak</summary>

```diff
- grep -r "from 'react-router" src/
- grep -r 'from "react-router' src/
+ grep -rE "from ['\"]react-router(-dom)?['\"]" src/
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md`
around lines 388 - 395, Update the cleanup checklist in SKILL.md so the search
for remaining imports also catches react-router-dom; modify the two grep
commands that currently search for "from 'react-router" / 'from "react-router'
(the lines containing those grep commands) to either add equivalent grep lines
for "react-router-dom" or broaden the pattern to match both packages, so stale
react-router-dom imports are flagged before running npx tsc --noEmit.
packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md-199-201 (1)

199-201: ⚠️ Potential issue | 🟡 Minor

Fix the active-state styling example to match TanStack Router's activeProps API.

The description mentions "automatic active data attribute," but TanStack Router's Link component uses the activeProps prop to apply styles when a link is active—not automatic data attributes. The example className="[&.active]:font-bold" doesn't align with this API; it should be activeProps={{ className: 'font-bold' }} to properly demonstrate how to style active links in TanStack Router.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md`
around lines 199 - 201, The active-state styling example is incorrect: replace
the suggestion to use an automatic `active` data attribute and the
`className="[&.active]:font-bold"` example with TanStack Router's `activeProps`
API on the `Link` component (e.g., use `activeProps={{ className: 'font-bold'
}}`) and update the text to explain `activeProps` applies props when a link is
active; keep the existing notes that `to` is a route path pattern and `params`
are separate typed props but remove the mention of an automatic `active` data
attribute.
packages/react-router/skills/compositions/router-query/SKILL.md-87-112 (1)

87-112: ⚠️ Potential issue | 🟡 Minor

Add missing import for QueryClientProvider.

Line 102 uses QueryClientProvider but it's not included in the imports (lines 89-91). For consistency with other examples in this document (lines 37 and 160 show the import), and to prevent readers from copying incomplete code, add the import.

📦 Proposed fix
 // src/router.tsx
-import { QueryClient } from '@tanstack/react-query'
+import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
 import { createRouter } from '@tanstack/react-router'
 import { routeTree } from './routeTree.gen'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
87 - 112, The file is missing the QueryClientProvider import used in
createAppRouter's Wrap component; add QueryClientProvider to the existing import
from '@tanstack/react-query' (alongside QueryClient) at the top of the file so
createAppRouter and its Wrap JSX can reference QueryClientProvider correctly.
packages/router-core/skills/router-core/search-params/references/validation-patterns.md-241-247 (1)

241-247: ⚠️ Potential issue | 🟡 Minor

Same issue: installation includes unused adapter.

Line 243 states "No adapter needed" but line 246 includes @tanstack/arktype-adapter in the installation. Unlike the Valibot section, there's no alternative example showing adapter usage here. Either remove the adapter from the installation command or add a section explaining when it's needed.

📝 Suggested fix
 ## ArkType (Standard Schema)
 
 ArkType 2.0-rc+ implements Standard Schema. No adapter needed — pass the type directly to `validateSearch`.
 
 ```bash
-npm install arktype `@tanstack/arktype-adapter`
+npm install arktype
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In
@packages/router-core/skills/router-core/search-params/references/validation-patterns.md
around lines 241 - 247, The install command incorrectly includes
@tanstack/arktype-adapter despite the preceding text saying "No adapter needed"
for ArkType 2.0-rc+; update the documentation in the ArkType (Standard Schema)
block by removing the adapter from the npm install line so it reads just "npm
install arktype", or alternatively keep the adapter but add a brief clarifying
sentence and example that explains when and why @tanstack/arktype-adapter is
required (mirroring the Valibot section) and show the adapter usage; update the
surrounding text to remain consistent with the chosen approach.


</details>

</blockquote></details>
<details>
<summary>packages/router-core/skills/router-core/search-params/references/validation-patterns.md-174-179 (1)</summary><blockquote>

`174-179`: _⚠️ Potential issue_ | _🟡 Minor_

**Clarify installation command vs. "no adapter needed" statement.**

Line 176 states "No adapter wrapper needed" but line 179 includes `@tanstack/valibot-adapter` in the installation command. Since the adapter is shown as an "Alternative" approach later (line 222), consider either:
- Moving the adapter installation to line 224 (near the alternative section), or  
- Adding a note explaining the adapter is optional for advanced use cases

This will reduce confusion about which packages users actually need.


<details>
<summary>📝 Suggested clarification</summary>

```diff
 ## Valibot (Standard Schema)
 
 Valibot 1.0+ implements Standard Schema. No adapter wrapper needed — pass the schema directly to `validateSearch`.
 
 ```bash
-npm install valibot `@tanstack/valibot-adapter`
+npm install valibot

Then in the alternative section:

```diff
 ### Valibot with Adapter (Alternative)
 
 If you need explicit input/output type control:
 
+```bash
+npm install `@tanstack/valibot-adapter`
+```
+
 ```tsx
 import { valibotValidator } from '@tanstack/valibot-adapter'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`
around lines 174 - 179, The docs currently say "No adapter wrapper needed" but
the install line includes `@tanstack/valibot-adapter` which contradicts that;
update the Valibot section so the primary install command installs only valibot
(for use with validateSearch) and either move the `@tanstack/valibot-adapter`
install into the "Alternative" section near the valibotValidator example or add
a one-line note that the adapter is optional for advanced use cases; ensure
references to validateSearch and valibotValidator remain unchanged so readers
can locate the usage examples.
packages/router-core/skills/router-core/navigation/SKILL.md-402-417 (1)

402-417: ⚠️ Potential issue | 🟡 Minor

Change the comment from "no accessibility" to "no link semantics."

Native <button> elements are accessible by default—they're focusable, keyboard-activable, and expose proper semantics to assistive technologies. The real issue here is that the button lacks link semantics and router affordances like href, Cmd/Ctrl+Click behavior, and active/inactive states. Calling it "no accessibility" teaches the wrong model and obscures why <Link> is the better choice.

Suggested wording
-// WRONG — no href, no cmd+click, no preloading, no accessibility
+// WRONG — no href, no cmd+click, no preloading, and no link semantics
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/navigation/SKILL.md` around lines 402
- 417, Update the explanatory comment in the MEDIUM example to replace "no
accessibility" with "no link semantics" and explain that using useNavigate in
the BadNav example (function BadNav) results in a button element that lacks link
semantics and router affordances (no href, no Cmd/Ctrl-click, no preloading, no
active state), while the GoodNav example (function GoodNav using Link) preserves
those link semantics; edit the text around useNavigate/BadNav/GoodNav to reflect
this corrected phrasing and rationale.
packages/router-core/skills/router-core/navigation/SKILL.md-171-171 (1)

171-171: ⚠️ Potential issue | 🟡 Minor

Clarify freshness vs eviction here.

This sentence currently teaches the wrong knob: TanStack Router uses defaultPreloadStaleTime for how long preloaded data is considered fresh, while unused preloaded data is evicted based on defaultPreloadMaxAge. As written, an agent trying to change retention will likely edit the stale-time setting instead.

Suggested wording
-Preloaded data is cached for 30 seconds by default (`defaultPreloadStaleTime`). When using an external cache like TanStack Query, set `defaultPreloadStaleTime: 0` to let the external library control freshness.
+Preloaded data is considered fresh for 30 seconds by default (`defaultPreloadStaleTime`). Unused preloaded data is evicted after 30 seconds by default (`defaultPreloadMaxAge`). When using an external cache like TanStack Query, set `defaultPreloadStaleTime: 0` to let the external library control freshness.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/navigation/SKILL.md` at line 171, The
docs confuse freshness vs eviction: update the sentence to state that
defaultPreloadStaleTime controls how long preloaded data is considered fresh,
while defaultPreloadMaxAge controls how long unused preloaded data is kept
(evicted after this age); mention that when delegating retention to an external
cache like TanStack Query you should set defaultPreloadMaxAge appropriately
(e.g., 0) if you want the external cache to control eviction, and set
defaultPreloadStaleTime to 0 only if you want the external library to control
freshness. Reference the symbols defaultPreloadStaleTime and
defaultPreloadMaxAge when making this change.
packages/router-core/skills/router-core/path-params/SKILL.md-277-287 (1)

277-287: ⚠️ Potential issue | 🟡 Minor

Add missing imports to code snippets using redirect and notFound.

Both examples read like full route files, but redirect and notFound are standalone exports from @tanstack/react-router that must be explicitly imported. Other skill files in the codebase consistently include these imports in similar examples. Omitting them makes it easy for developers to copy-paste non-compiling code.

✏️ Suggested doc fix
+import { createFileRoute, redirect } from '@tanstack/react-router'
+
 export const Route = createFileRoute('/posts/$postId')({
   beforeLoad: async ({ params }) => {
     // params.postId available here
     const canView = await checkPermission(params.postId)
     if (!canView) throw redirect({ to: '/unauthorized' })
   },
   loader: async ({ params }) => {
     return fetchPost(params.postId)
   },
 })
+import { createFileRoute, notFound } from '@tanstack/react-router'
+
 export const Route = createFileRoute('/posts/$postId')({
   loader: async ({ params }) => {
     const id = parseInt(params.postId, 10)
     if (isNaN(id)) throw notFound()
     return fetchPost(id)
   },
 })

Also applies to: 359-381

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/path-params/SKILL.md` around lines
277 - 287, The example route snippets use the standalone exports redirect and
notFound but don't import them; update the Route examples using createFileRoute
(and related examples at the other location) to add an explicit import for
redirect and/or notFound from "@tanstack/react-router" so the beforeLoad, loader
and notFound usage compiles when copy-pasted—locate the examples referencing
redirect, notFound, Route, createFileRoute, beforeLoad and loader and add the
appropriate import statements.
packages/router-core/skills/router-core/path-params/SKILL.md-317-335 (1)

317-335: ⚠️ Potential issue | 🟡 Minor

Clarify route syntax vs. param key for splat routes.

The current section conflates $ (route syntax) with _splat (param access). While technically correct that $ is used for routes and _splat for params, the wording "The captured value is under _splat, not *" is misleading—* is a v1 backwards-compatibility alias, not an error. For AI skill documentation, explicitly separate the two concepts:

✏️ Suggested wording
-TanStack Router uses `$` for splat routes. The captured value is under `_splat`, not `*`.
+TanStack Router uses `$` in the route path for splat routes. The captured value is available under the `_splat` param key.
...
-> Note: `*` works in v1 for backwards compatibility but will be removed in v2. Always use `_splat`.
+> Note: Prefer `$` for route syntax and `_splat` for param access. The `*` key is a v1-only backwards-compatibility alias and will be removed in v2.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/path-params/SKILL.md` around lines
317 - 335, Reword the paragraph in SKILL.md to separate route syntax from param
access: state that routes use `$` in path syntax (e.g., File:
src/routes/files.$.tsx) while the captured value is available as the `_splat`
param via Route.useParams(); clarify that `*` is only a v1
backwards-compatibility alias (not the param name) and will be removed in v2,
and update the example and wording to reflect that distinction (reference
symbols: createFileRoute, Route.useParams(), `_splat`, `$`, and `*`).
packages/virtual-file-routes/skills/_artifacts/skill_spec.md-9-15 (1)

9-15: ⚠️ Potential issue | 🟡 Minor

Domain name inconsistency between tables.

Line 9 uses "Virtual Route Configuration" (title case) while Line 15 uses "virtual-route-config" (hyphenated lowercase). Consider using a consistent format across both tables to avoid potential tooling mismatches.

Proposed fix
 | Skill               | Type | Domain               | What it covers                                             | Failure modes |
 | ------------------- | ---- | -------------------- | ---------------------------------------------------------- | ------------- |
-| virtual-file-routes | core | virtual-route-config | rootRoute, index, route, layout, physical, subtree configs | 2             |
+| virtual-file-routes | core | Virtual Route Configuration | rootRoute, index, route, layout, physical, subtree configs | 2             |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/virtual-file-routes/skills/_artifacts/skill_spec.md` around lines 9
- 15, The "Virtual Route Configuration" title in the first table and the
"virtual-route-config" domain cell in the Skill Inventory table are
inconsistent; update one so both use the same normalized format (pick either
Title Case or hyphenated-lowercase) — e.g., change "Virtual Route Configuration"
to "virtual-route-config" OR change the domain cell "virtual-route-config" to
"Virtual Route Configuration" — and ensure both occurrences (the table header
and the Domain column entry) match exactly.
packages/router-plugin/skills/_artifacts/skill_spec.md-9-15 (1)

9-15: ⚠️ Potential issue | 🟡 Minor

Domain name inconsistency between tables.

Line 9 uses "Bundler Integration" (title case) while Line 15 uses "bundler-integration" (hyphenated lowercase). This pattern appears across multiple skill_spec.md files in this PR—consider normalizing all domain references to a single format.

Proposed fix
 | Skill         | Type | Domain              | What it covers                                                 | Failure modes |
 | ------------- | ---- | ------------------- | -------------------------------------------------------------- | ------------- |
-| router-plugin | core | bundler-integration | Vite/Webpack/Rspack/esbuild plugins, route gen, code splitting | 2             |
+| router-plugin | core | Bundler Integration | Vite/Webpack/Rspack/esbuild plugins, route gen, code splitting | 2             |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-plugin/skills/_artifacts/skill_spec.md` around lines 9 - 15,
The domain string is inconsistent: change the header cell "Bundler Integration"
in the first table to match the inventory format "bundler-integration" so both
table entries use the same lowercase hyphenated form; update the header in the
top table (the cell under the first table's second column) to
"bundler-integration" and scan other skill_spec.md files to normalize any other
occurrences to this same format (e.g., ensure the "router-plugin" row's Domain
value remains "bundler-integration").
packages/vue-router/skills/_artifacts/skill_spec.md-9-15 (1)

9-15: ⚠️ Potential issue | 🟡 Minor

Domain name inconsistency between tables.

Line 9 uses "Vue Router Bindings" (title case with spaces) while Line 15 uses "vue-router-bindings" (hyphenated lowercase). If the intent tooling performs case-sensitive domain matching, this mismatch could cause lookup failures.

Proposed fix
 | Skill      | Type      | Domain              | What it covers                                                  | Failure modes |
 | ---------- | --------- | ------------------- | --------------------------------------------------------------- | ------------- |
-| vue-router | framework | vue-router-bindings | Ref<T> returns, defineComponent, h(), provide/inject, Html/Body | 2             |
+| vue-router | framework | Vue Router Bindings | Ref<T> returns, defineComponent, h(), provide/inject, Html/Body | 2             |

Or normalize to the hyphenated form in both tables, depending on the convention used by @tanstack/intent.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-router/skills/_artifacts/skill_spec.md` around lines 9 - 15, The
domain string is inconsistent between the top table title "Vue Router Bindings"
and the Skill Inventory domain value "vue-router-bindings"; normalize them to
the same form (prefer the hyphenated lowercase convention used by
`@tanstack/intent`) by changing the title or the domain value so both read
"vue-router-bindings" and ensure the domain column for the "vue-router" skill
and the table header use that exact string.
packages/router-plugin/bin/intent.js-8-19 (1)

8-19: ⚠️ Potential issue | 🟡 Minor

Disambiguate transitive dependency failures from missing @tanstack/intent.

The catch block at lines 8–19 treats any ERR_MODULE_NOT_FOUND or MODULE_NOT_FOUND as "@tanstack/intent is not installed," but Node.js throws these errors for any unresolved module during import—including missing transitive dependencies or broken internal modules within @tanstack/intent. This masks the actual problem: a broken install or incompatible version.

Check the error message for @tanstack/intent to distinguish the two cases. Only show the friendly install hint when the missing package is @tanstack/intent itself; rethrow other resolution failures unchanged.

Proposed fix
 try {
   await import('@tanstack/intent/intent-library')
 } catch (e) {
-  if (e?.code === 'ERR_MODULE_NOT_FOUND' || e?.code === 'MODULE_NOT_FOUND') {
+  const code = e && typeof e === 'object' ? e.code : undefined
+  const message = e instanceof Error ? e.message : String(e)
+  const isMissingIntent =
+    (code === 'ERR_MODULE_NOT_FOUND' || code === 'MODULE_NOT_FOUND') &&
+    /@tanstack\/intent(\/intent-library)?/.test(message)
+
+  if (isMissingIntent) {
     console.error('@tanstack/intent is not installed.')
     console.error('')
     console.error('Install it as a dev dependency:')
     console.error('  npm add -D `@tanstack/intent`')
     console.error('')

Note: This pattern appears in 12 files across the repository and should be updated consistently.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-plugin/bin/intent.js` around lines 8 - 19, The catch block in
packages/router-plugin/bin/intent.js currently treats any
ERR_MODULE_NOT_FOUND/MODULE_NOT_FOUND as “@tanstack/intent is not installed”;
change it to inspect the error text to ensure the missing module is actually
'@tanstack/intent' before showing the friendly install hint: check e.message (or
e?.stack) for the exact string "Cannot find module" or the module name
"'@tanstack/intent'" (or "@tanstack/intent") and only print the install/help
output in that case; for all other ERR_MODULE_NOT_FOUND/MODULE_NOT_FOUND errors
rethrow e unchanged so transitive dependency or internal module failures are not
masked. Apply the same check pattern to other similar catch blocks found across
the repo.
packages/start-client-core/bin/intent.js-8-19 (1)

8-19: ⚠️ Potential issue | 🟡 Minor

Don't treat every MODULE_NOT_FOUND as "intent is missing".

This catch block only checks e.code. If @tanstack/intent/intent-library is present but one of its imports is missing, the shim will print the install hint and exit with a misleading error message. Narrow the guard to errors that specifically mention @tanstack/intent/intent-library in the error message before applying the fallback message.

♻️ Suggested guard
 } catch (e) {
-  if (e?.code === 'ERR_MODULE_NOT_FOUND' || e?.code === 'MODULE_NOT_FOUND') {
+  const isMissingIntentLibrary =
+    (e?.code === 'ERR_MODULE_NOT_FOUND' || e?.code === 'MODULE_NOT_FOUND') &&
+    String(e?.message ?? '').includes('@tanstack/intent/intent-library')
+
+  if (isMissingIntentLibrary) {
     console.error('@tanstack/intent is not installed.')
     console.error('')
     console.error('Install it as a dev dependency:')
@@
     process.exit(1)
   }
   throw e
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/bin/intent.js` around lines 8 - 19, The catch
block currently treats any ERR_MODULE_NOT_FOUND/MODULE_NOT_FOUND as if
`@tanstack/intent` is missing; update the guard in the catch to also verify the
error message references the specific module path (e.g.
'@tanstack/intent/intent-library') before printing the install hint and
exiting—keep the existing e.code checks (e?.code === 'ERR_MODULE_NOT_FOUND' ||
e?.code === 'MODULE_NOT_FOUND') but require e.message (or e.toString()) to
include the module identifier string before running the console.error/install
instructions in the same catch block.
packages/start-server-core/package.json-89-98 (1)

89-98: ⚠️ Potential issue | 🟡 Minor

Consider making the npx fallback automatic or moving @tanstack/intent to dependencies.

When ./bin/intent.js is called by a consumer without @tanstack/intent installed, it fails gracefully with error messaging that suggests running npx @tanstack/intent@latest. However, this requires user intervention. If the binary should work seamlessly for consumers of this package, either:

  • Move @tanstack/intent from devDependencies to dependencies, or
  • Automatically invoke the npx fallback instead of just suggesting it.

The current error handling is present but reactive rather than proactive.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/package.json` around lines 89 - 98, The package
currently lists "@tanstack/intent" under devDependencies but exposes a bin
"intent" that requires it; update package.json to move "@tanstack/intent" from
devDependencies into dependencies so consumers get it installed, or
alternatively modify the runtime in ./bin/intent.js (the "intent" entry point)
to programmatically attempt to require("@tanstack/intent") and, on failure,
spawn an automatic "npx `@tanstack/intent`@latest" fallback instead of only
printing instructions; pick one approach, ensure the change references the
"@tanstack/intent" dependency and the "./bin/intent.js" bin entry, and update
package.json accordingly.
packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md-214-219 (1)

214-219: ⚠️ Potential issue | 🟡 Minor

The documentation comment is contradictory and should be clarified.

Lines 215 and 218 contradict each other: line 215 says "does NOT create a /dashboard URL" while line 218 says "The URL is /dashboard". The intended point—that layout() contributes no path segment—gets lost. Update to clarify that layout() itself is pathless while the child route provides the segment:

Suggested fix
-// This does NOT create a /dashboard URL
+// `layout()` itself does not add a URL segment
 layout('dashboardLayout.tsx', [route('/dashboard', 'dashboard.tsx')])

-// The URL is /dashboard, and dashboardLayout.tsx wraps it
+// `/dashboard` comes from the child route; the layout only wraps it
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md` around
lines 214 - 219, The comment is contradictory about whether
layout('dashboardLayout.tsx', [route('/dashboard', 'dashboard.tsx')]) creates
the /dashboard path; update the doc to state clearly that layout() is pathless
and does not add a URL segment, while the child route(route('/dashboard',
'dashboard.tsx')) supplies the /dashboard path and is wrapped by
dashboardLayout.tsx. Mention the symbols layout(), route(), dashboardLayout.tsx
and dashboard.tsx so readers can find the example.
packages/start-client-core/skills/start-core/middleware/SKILL.md-23-25 (1)

23-25: ⚠️ Potential issue | 🟡 Minor

Remove the blank line inside the CRITICAL blockquote.

The empty line here trips markdownlint MD028.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/middleware/SKILL.md` around
lines 23 - 25, Remove the empty line inside the CRITICAL blockquote in SKILL.md
so the two CRITICAL sentences about method order (`middleware()` →
`inputValidator()` → `client()` → `server()`) and `sendContext` validation
appear as a single continuous blockquote paragraph; edit the blockquote to join
the sentences without a blank line to satisfy markdownlint MD028.
packages/react-router/skills/react-router/SKILL.md-29-33 (1)

29-33: ⚠️ Potential issue | 🟡 Minor

Keep the CRITICAL callouts in one blockquote.

The blank lines on Line 30 and Line 32 trigger markdownlint MD028.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/react-router/SKILL.md` around lines 29 - 33,
Combine the three separate CRITICAL blockquotes into a single blockquote by
merging the three lines starting with "**CRITICAL**: TanStack Router types...",
"**CRITICAL**: TanStack Router is CLIENT-FIRST...", and "**CRITICAL**: Do not
confuse `@tanstack/react-router`..." into one contiguous blockquote with no
blank lines between them to satisfy markdownlint MD028 (remove the blank lines
that currently exist between those CRITICAL callouts).
packages/start-client-core/skills/start-core/execution-model/SKILL.md-23-27 (1)

23-27: ⚠️ Potential issue | 🟡 Minor

Remove the blank lines inside the CRITICAL blockquote.

The empty lines between these three callouts trip markdownlint MD028.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/execution-model/SKILL.md` around
lines 23 - 27, Remove the empty lines inside the CRITICAL blockquote in SKILL.md
so the three bullet sentences are contiguous (no blank lines between the three
lines beginning with "**CRITICAL**: ALL code...", "**CRITICAL**: Module-level
`process.env`...", and "**CRITICAL**: `VITE_` prefixed..."). Edit the blockquote
so it reads as three consecutive lines with no blank lines to satisfy
markdownlint MD028.
packages/react-start/skills/_artifacts/skill_tree.yaml-11-12 (1)

11-12: ⚠️ Potential issue | 🟡 Minor

Path resolution for generated_from reference needs clarification.

The generated_from references _artifacts/start_domain_map.yaml. The actual file exists at the repository root (_artifacts/start_domain_map.yaml), but the YAML file is located in packages/react-start/skills/_artifacts/. If the consuming tool resolves paths relative to the YAML file's location, the reference will fail. Confirm whether paths are resolved from the repository root or relative to the file's directory, and adjust the path accordingly if needed.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-start/skills/_artifacts/skill_tree.yaml` around lines 11 - 12,
The generated_from reference in skill_tree.yaml points to start_domain_map.yaml
but may be resolved relative to the YAML file instead of the repository root;
check how the consuming tool resolves paths, and then update the generated_from
value in skill_tree.yaml so it correctly points to start_domain_map.yaml (either
by changing it to a repo-root absolute reference or by rewriting it as the
correct relative path from the skill_tree.yaml location) so the resolver finds
the start_domain_map.yaml file.
packages/solid-router/skills/solid-router/SKILL.md-27-33 (1)

27-33: ⚠️ Potential issue | 🟡 Minor

Remove the blank lines inside this blockquote.

markdownlint already flags MD028 here, so this doc will ship with avoidable warnings.

🧹 Proposed fix
 > **CRITICAL**: TanStack Router types are FULLY INFERRED. Never cast, never annotate inferred values.
-
 > **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, not on the server.
-
 > **CRITICAL**: Most hooks return `Accessor<T>` — you MUST call the accessor (`value()`) to read the reactive value. This is the `#1` difference from the React version.
-
 > **CRITICAL**: Do not confuse `@tanstack/solid-router` with `@solidjs/router`. They are completely different libraries with different APIs.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/solid-router/skills/solid-router/SKILL.md` around lines 27 - 33, The
blockquote containing the four "**CRITICAL**" lines currently has empty blank
lines inside it which triggers markdownlint MD028; remove the extra blank lines
so the blockquote is a contiguous set of lines (ensure each line begins with ">"
and there are no empty ">" lines between them), preserving the exact text of the
"**CRITICAL**" entries (e.g., the lines starting with "> **CRITICAL**: TanStack
Router types...", "> **CRITICAL**: TanStack Router is CLIENT-FIRST...", ">
**CRITICAL**: Most hooks return `Accessor<T>`...", "> **CRITICAL**: Do not
confuse `@tanstack/solid-router`...") to resolve the lint warning.
packages/router-core/skills/router-core/auth-and-guards/SKILL.md-23-23 (1)

23-23: ⚠️ Potential issue | 🟡 Minor

Fix the relative link to the parent skill.

From packages/router-core/skills/router-core/auth-and-guards/, this target walks up one directory too many and resolves to a non-existent path. ../SKILL.md points at the sibling parent skill.

🔗 Proposed fix
-This skill builds on router-core. Read [router-core](../../../router-core/skills/router-core/SKILL.md) first for foundational concepts.
+This skill builds on router-core. Read [router-core](../SKILL.md) first for foundational concepts.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/auth-and-guards/SKILL.md` at line 23,
Update the broken relative link in
packages/router-core/skills/router-core/auth-and-guards/SKILL.md so it points to
the parent skill one directory up; replace the incorrect ../../SKILL.md (which
climbs too many levels) with ../SKILL.md to reference the sibling parent skill
correctly.
packages/start-client-core/skills/start-core/server-routes/SKILL.md-254-263 (1)

254-263: ⚠️ Potential issue | 🟡 Minor

Add a language tag to the route-conflict example fence.

The fence opened at Line 256 is unlabeled, so it trips MD040 and loses syntax highlighting. text would be enough here.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/server-routes/SKILL.md` around
lines 254 - 263, The code block in the "1. MEDIUM: Duplicate route paths"
example is an unlabeled fenced code block (the triple-backtick fence containing
"# WRONG — both resolve to /users, causes error" and the following lines), which
triggers MD040; add a language tag (e.g., change ``` to ```text) on that fence
so the example is labelled and gains correct syntax highlighting and linter
compliance.
packages/start-client-core/skills/start-core/server-functions/SKILL.md-22-24 (1)

22-24: ⚠️ Potential issue | 🟡 Minor

Fix the markdownlint warnings in this skill doc.

Line 23 still trips MD028 because the adjacent blockquotes are separated by a raw blank line, and the fence opened at Line 228 should be tagged as text/plaintext to satisfy MD040.

Also applies to: 228-233

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/server-functions/SKILL.md`
around lines 22 - 24, Fix the markdownlint issues by removing the raw blank line
between the two adjacent blockquotes (the pair starting with "**CRITICAL**:
Loaders are ISOMORPHIC..." and the subsequent "**CRITICAL**: Do not use..."
block) so they are consecutive blockquote lines (resolves MD028), and update the
fenced code block near the bottom of SKILL.md (the fence opened as an untyped
triple-backtick block around the example text) to include an explicit language
tag of either "text" or "plaintext" (resolves MD040); ensure no other blank
lines separate those blockquotes and that the fence uses ```text or
```plaintext.
packages/start-client-core/skills/start-core/SKILL.md-21-25 (1)

21-25: ⚠️ Potential issue | 🟡 Minor

Fix the markdownlint warnings in the overview skill.

Lines 21-25 still have raw blank lines between adjacent blockquotes (MD028), and the decision tree opened at Line 39 should declare a language such as text so MD040 stays clean.

Also applies to: 39-54

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/SKILL.md` around lines 21 - 25,
Fix the markdownlint issues: remove the raw blank lines between adjacent
blockquotes in the overview so the multiple consecutive > lines are contiguous
(address MD028) and add a language identifier (e.g., "text") to the fenced
decision-tree code block opened around the decision tree (the fenced block
starting near Line 39) to satisfy MD040; update the SKILL.md blockquote group
and the code fence declaration accordingly.
🧹 Nitpick comments (5)
packages/router-core/skills/router-core/type-safety/SKILL.md (1)

24-26: Optional: Address markdownlint warning for stricter compliance.

The blank line between blockquotes improves readability by separating two distinct critical warnings, but markdownlint flags this as MD028. If strict linter compliance is required, you can remove the blank line or merge the blockquotes.

🔧 Optional fix to merge blockquotes
 > **CRITICAL**: NEVER use `as Type`, explicit generic params, `satisfies` on hook returns, or type annotations on inferred values. Every cast masks real type errors and breaks the inference chain.
-
+>
 > **CRITICAL**: Do NOT confuse TanStack Router with Next.js or React Router. There is no `getServerSideProps`, no `useSearchParams()`, no `useLoaderData()` from `react-router-dom`.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/type-safety/SKILL.md` around lines 24
- 26, The markdown contains two adjacent blockquotes that are separated by a
blank line which triggers markdownlint MD028; edit SKILL.md to either remove the
blank line between the two CRITICAL blockquotes or merge them into a single
blockquote so the warnings remain intact but the file passes the linter (target
the two lines containing the "**CRITICAL**:" messages and adjust spacing
accordingly).
packages/router-core/skills/router-core/data-loading/SKILL.md (1)

483-484: Consider using markdown links for cross-references.

The cross-references are formatted as bold text. If these SKILL.md files are meant to be navigable or if the skill system supports linking, consider using standard markdown link syntax for consistency:

-- See also: **router-core/search-params/SKILL.md** — `loaderDeps` consumes validated search params as cache keys
-- See also: **compositions/router-query/SKILL.md** — for external cache coordination with TanStack Query
+- See also: [router-core/search-params](../search-params/SKILL.md) — `loaderDeps` consumes validated search params as cache keys
+- See also: [compositions/router-query](../../../compositions/router-query/SKILL.md) — for external cache coordination with TanStack Query

Alternatively, if the bold text format is the standard convention for the @tanstack/intent skill system, this is fine as-is.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/data-loading/SKILL.md` around lines
483 - 484, Replace the bold cross-reference lines that currently read
"**router-core/search-params/SKILL.md** — `loaderDeps` consumes validated search
params as cache keys" and "**compositions/router-query/SKILL.md** — for external
cache coordination with TanStack Query" with standard markdown links so the
references are navigable (e.g. use
[router-core/search-params/SKILL.md](router-core/search-params/SKILL.md) and
[compositions/router-query/SKILL.md](compositions/router-query/SKILL.md)),
keeping the trailing explanatory text and the code span `loaderDeps` intact.
packages/router-plugin/package.json (1)

103-103: Consider linting or syntax-checking the new bin.

These lines make bin/intent.js part of the shipped surface, but this package’s current CI only lint-checks ./src. A tiny node --check ./bin/intent.js or adding ./bin to the ESLint target would keep publish-time regressions from slipping through.

Also applies to: 154-155

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-plugin/package.json` at line 103, The package.json now
exposes "bin" (making bin/intent.js part of the shipped surface) but CI only
lints ./src, so add a publish-time syntax check for the new bin or include ./bin
in linting: update CI to run `node --check ./bin/intent.js` (or equivalent
syntax check) and/or add ./bin to the ESLint target so bin/intent.js (and the
other bin entry at lines 154-155) are checked before publishing.
packages/react-start/skills/_artifacts/skill_tree.yaml (1)

1-1: Header comment doesn't match actual file path.

The comment indicates skills/_artifacts/start_skill_tree.yaml but the file is located at packages/react-start/skills/_artifacts/skill_tree.yaml.

📝 Suggested fix
-# skills/_artifacts/start_skill_tree.yaml
+# packages/react-start/skills/_artifacts/skill_tree.yaml
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-start/skills/_artifacts/skill_tree.yaml` at line 1, The header
comment at the top of the YAML incorrectly references "start_skill_tree.yaml";
update that comment to match the actual file name "skill_tree.yaml" by replacing
the text "skills/_artifacts/start_skill_tree.yaml" in the top-of-file comment
(the line that currently starts with "# ") with
"skills/_artifacts/skill_tree.yaml" so the header accurately reflects this
file's name and prevents confusion.
packages/start-server-core/skills/_artifacts/domain_map.yaml (1)

48-63: Keep the failure-mode records schema-consistent with the other artifacts.

These entries omit source, while the paired packages/start-server-core/skills/_artifacts/skill_spec.md already records one and the reviewed client-core domain map does the same in YAML. Adding it here would keep the machine-readable shape uniform.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/skills/_artifacts/domain_map.yaml` around lines 48
- 63, The two failure_mode entries under failure_modes (the ones with mistake
values "Missing AsyncLocalStorage setup" and "Incorrect handler export for
deployment target") are missing the required source field; update each entry to
include a source key with an appropriate identifier string (matching the schema
used in skill_spec.md and the client-core domain map) so the records are
schema-consistent while preserving existing keys mistake, mechanism, priority,
and status.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: d232371a-f31e-496c-b398-32a3e2447e98

📥 Commits

Reviewing files that changed from the base of the PR and between 88fcbec and 142682c.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (83)
  • _artifacts/domain_map.yaml
  • _artifacts/skill_spec.md
  • _artifacts/skill_tree.yaml
  • _artifacts/start_domain_map.yaml
  • _artifacts/start_skill_tree.yaml
  • packages/react-router/bin/intent.js
  • packages/react-router/package.json
  • packages/react-router/skills/compositions/router-query/SKILL.md
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/react-router/skills/react-router/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/react-start/package.json
  • packages/react-start/skills/_artifacts/domain_map.yaml
  • packages/react-start/skills/_artifacts/skill_spec.md
  • packages/react-start/skills/_artifacts/skill_tree.yaml
  • packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md
  • packages/react-start/skills/react-start/SKILL.md
  • packages/router-core/bin/intent.js
  • packages/router-core/package.json
  • packages/router-core/skills/router-core/SKILL.md
  • packages/router-core/skills/router-core/auth-and-guards/SKILL.md
  • packages/router-core/skills/router-core/code-splitting/SKILL.md
  • packages/router-core/skills/router-core/data-loading/SKILL.md
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/path-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/references/validation-patterns.md
  • packages/router-core/skills/router-core/ssr/SKILL.md
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/router-plugin/package.json
  • packages/router-plugin/skills/_artifacts/domain_map.yaml
  • packages/router-plugin/skills/_artifacts/skill_spec.md
  • packages/router-plugin/skills/_artifacts/skill_tree.yaml
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/solid-router/package.json
  • packages/solid-router/skills/_artifacts/domain_map.yaml
  • packages/solid-router/skills/_artifacts/skill_spec.md
  • packages/solid-router/skills/_artifacts/skill_tree.yaml
  • packages/solid-router/skills/solid-router/SKILL.md
  • packages/solid-start/bin/intent.js
  • packages/solid-start/package.json
  • packages/solid-start/skills/_artifacts/domain_map.yaml
  • packages/solid-start/skills/_artifacts/skill_spec.md
  • packages/solid-start/skills/_artifacts/skill_tree.yaml
  • packages/solid-start/skills/solid-start/SKILL.md
  • packages/start-client-core/bin/intent.js
  • packages/start-client-core/package.json
  • packages/start-client-core/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/_artifacts/skill_spec.md
  • packages/start-client-core/skills/_artifacts/skill_tree.yaml
  • packages/start-client-core/skills/start-core/SKILL.md
  • packages/start-client-core/skills/start-core/deployment/SKILL.md
  • packages/start-client-core/skills/start-core/execution-model/SKILL.md
  • packages/start-client-core/skills/start-core/middleware/SKILL.md
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/start-server-core/bin/intent.js
  • packages/start-server-core/package.json
  • packages/start-server-core/skills/_artifacts/domain_map.yaml
  • packages/start-server-core/skills/_artifacts/skill_spec.md
  • packages/start-server-core/skills/_artifacts/skill_tree.yaml
  • packages/start-server-core/skills/start-server-core/SKILL.md
  • packages/virtual-file-routes/bin/intent.js
  • packages/virtual-file-routes/package.json
  • packages/virtual-file-routes/skills/_artifacts/domain_map.yaml
  • packages/virtual-file-routes/skills/_artifacts/skill_spec.md
  • packages/virtual-file-routes/skills/_artifacts/skill_tree.yaml
  • packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md
  • packages/vue-router/bin/intent.js
  • packages/vue-router/package.json
  • packages/vue-router/skills/_artifacts/domain_map.yaml
  • packages/vue-router/skills/_artifacts/skill_spec.md
  • packages/vue-router/skills/_artifacts/skill_tree.yaml
  • packages/vue-router/skills/vue-router/SKILL.md
  • packages/vue-start/bin/intent.js
  • packages/vue-start/package.json
  • packages/vue-start/skills/_artifacts/domain_map.yaml
  • packages/vue-start/skills/_artifacts/skill_spec.md
  • packages/vue-start/skills/_artifacts/skill_tree.yaml
  • packages/vue-start/skills/vue-start/SKILL.md

@github-actions
Copy link
Contributor

github-actions bot commented Mar 9, 2026

Bundle Size Benchmarks

  • Commit: 32497be9c8fc
  • Measured at: 2026-03-13T06:22:23.090Z
  • Baseline source: history:32497be9c8fc
  • Dashboard: bundle-size history
Scenario Current (gzip) Delta vs baseline Raw Brotli Trend
react-router.minimal 87.09 KiB 0 B (0.00%) 274.11 KiB 75.68 KiB ▅▅▅▅▅▅▅▅▅▅▅
react-router.full 90.08 KiB 0 B (0.00%) 284.36 KiB 78.32 KiB ▅▅▅▅▅▅▅▅▅▅▅
solid-router.minimal 36.42 KiB 0 B (0.00%) 109.29 KiB 32.74 KiB ▅▅▅▅▅▅▅▅▅▅▅
solid-router.full 40.75 KiB 0 B (0.00%) 122.27 KiB 36.58 KiB ▅▅▅▅▅▅▅▅▅▅▅
vue-router.minimal 52.29 KiB 0 B (0.00%) 149.34 KiB 47.01 KiB ▅▅▅▅▅▅▅▅▅▅▅
vue-router.full 57.08 KiB 0 B (0.00%) 164.85 KiB 51.27 KiB ▅▅▅▅▅▅▅▅▅▅▅
react-start.minimal 99.66 KiB 0 B (0.00%) 313.26 KiB 86.22 KiB ▅▅▅▅▅▅▅▅▅▅▅
react-start.full 102.97 KiB 0 B (0.00%) 322.99 KiB 89.07 KiB ▅▅▅▅▅▅▅▅▅▅▅
solid-start.minimal 48.75 KiB 0 B (0.00%) 146.89 KiB 43.14 KiB ▅▅▅▅▅▅▅▅▅▅▅
solid-start.full 54.21 KiB 0 B (0.00%) 162.75 KiB 47.88 KiB ▅▅▅▅▅▅▅▅▅▅▅

Trend sparkline is historical gzip bytes ending with this PR measurement; lower is better.

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 9, 2026

More templates

@tanstack/arktype-adapter

npm i https://pkg.pr.new/@tanstack/arktype-adapter@6866

@tanstack/eslint-plugin-router

npm i https://pkg.pr.new/@tanstack/eslint-plugin-router@6866

@tanstack/history

npm i https://pkg.pr.new/@tanstack/history@6866

@tanstack/nitro-v2-vite-plugin

npm i https://pkg.pr.new/@tanstack/nitro-v2-vite-plugin@6866

@tanstack/react-router

npm i https://pkg.pr.new/@tanstack/react-router@6866

@tanstack/react-router-devtools

npm i https://pkg.pr.new/@tanstack/react-router-devtools@6866

@tanstack/react-router-ssr-query

npm i https://pkg.pr.new/@tanstack/react-router-ssr-query@6866

@tanstack/react-start

npm i https://pkg.pr.new/@tanstack/react-start@6866

@tanstack/react-start-client

npm i https://pkg.pr.new/@tanstack/react-start-client@6866

@tanstack/react-start-server

npm i https://pkg.pr.new/@tanstack/react-start-server@6866

@tanstack/router-cli

npm i https://pkg.pr.new/@tanstack/router-cli@6866

@tanstack/router-core

npm i https://pkg.pr.new/@tanstack/router-core@6866

@tanstack/router-devtools

npm i https://pkg.pr.new/@tanstack/router-devtools@6866

@tanstack/router-devtools-core

npm i https://pkg.pr.new/@tanstack/router-devtools-core@6866

@tanstack/router-generator

npm i https://pkg.pr.new/@tanstack/router-generator@6866

@tanstack/router-plugin

npm i https://pkg.pr.new/@tanstack/router-plugin@6866

@tanstack/router-ssr-query-core

npm i https://pkg.pr.new/@tanstack/router-ssr-query-core@6866

@tanstack/router-utils

npm i https://pkg.pr.new/@tanstack/router-utils@6866

@tanstack/router-vite-plugin

npm i https://pkg.pr.new/@tanstack/router-vite-plugin@6866

@tanstack/solid-router

npm i https://pkg.pr.new/@tanstack/solid-router@6866

@tanstack/solid-router-devtools

npm i https://pkg.pr.new/@tanstack/solid-router-devtools@6866

@tanstack/solid-router-ssr-query

npm i https://pkg.pr.new/@tanstack/solid-router-ssr-query@6866

@tanstack/solid-start

npm i https://pkg.pr.new/@tanstack/solid-start@6866

@tanstack/solid-start-client

npm i https://pkg.pr.new/@tanstack/solid-start-client@6866

@tanstack/solid-start-server

npm i https://pkg.pr.new/@tanstack/solid-start-server@6866

@tanstack/start-client-core

npm i https://pkg.pr.new/@tanstack/start-client-core@6866

@tanstack/start-fn-stubs

npm i https://pkg.pr.new/@tanstack/start-fn-stubs@6866

@tanstack/start-plugin-core

npm i https://pkg.pr.new/@tanstack/start-plugin-core@6866

@tanstack/start-server-core

npm i https://pkg.pr.new/@tanstack/start-server-core@6866

@tanstack/start-static-server-functions

npm i https://pkg.pr.new/@tanstack/start-static-server-functions@6866

@tanstack/start-storage-context

npm i https://pkg.pr.new/@tanstack/start-storage-context@6866

@tanstack/valibot-adapter

npm i https://pkg.pr.new/@tanstack/valibot-adapter@6866

@tanstack/virtual-file-routes

npm i https://pkg.pr.new/@tanstack/virtual-file-routes@6866

@tanstack/vue-router

npm i https://pkg.pr.new/@tanstack/vue-router@6866

@tanstack/vue-router-devtools

npm i https://pkg.pr.new/@tanstack/vue-router-devtools@6866

@tanstack/vue-router-ssr-query

npm i https://pkg.pr.new/@tanstack/vue-router-ssr-query@6866

@tanstack/vue-start

npm i https://pkg.pr.new/@tanstack/vue-start@6866

@tanstack/vue-start-client

npm i https://pkg.pr.new/@tanstack/vue-start-client@6866

@tanstack/vue-start-server

npm i https://pkg.pr.new/@tanstack/vue-start-server@6866

@tanstack/zod-adapter

npm i https://pkg.pr.new/@tanstack/zod-adapter@6866

commit: 5995e7e

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 10

♻️ Duplicate comments (4)
packages/start-client-core/skills/_artifacts/domain_map.yaml (1)

8-17: ⚠️ Potential issue | 🟠 Major

Make the package-local domain map describe the package it ships with.

This file lives under packages/start-client-core, but Lines 9-17 still identify it as @tanstack/react-start with primary_framework: 'React'. That conflicts with the sibling package-local skill_tree.yaml, and it makes the published metadata look React-specific even though this package is the framework-agnostic core. Either align the library block with @tanstack/start-client-core, or move this consolidated React Start descriptor to the repo-level artifact instead.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/_artifacts/domain_map.yaml` around lines 8
- 17, The library metadata in the domain_map.yaml is incorrect for this package:
update the library block that currently sets name: '@tanstack/react-start' and
primary_framework: 'React' so it accurately describes this package (e.g., name
'@tanstack/start-client-core' and a framework-agnostic primary_framework) or
remove/move this consolidated React-specific descriptor to the repo-level
artifact; edit the library block in domain_map.yaml (the fields name, version if
needed, description, and primary_framework) to align with the package-local
skill_tree.yaml and the actual package purpose.
packages/start-client-core/skills/start-core/server-routes/SKILL.md (1)

24-77: ⚠️ Potential issue | 🟠 Major

Keep this core skill framework-agnostic.

Lines 26-27, 45-46, 112-113, and 129-130 hard-code @tanstack/react-router, and Lines 46-77 add a React-only useState UI example. Because this file ships from packages/start-client-core, agents following it for Solid/Vue Start will learn the wrong bindings. Please rewrite these snippets with framework-neutral placeholders or move the binding-specific examples into the framework package skills.

Also applies to: 110-154, 198-249

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/server-routes/SKILL.md` around
lines 24 - 77, The file hard-codes React and `@tanstack/react-router` usage
(imports of "@tanstack/react-router", createFileRoute usage tied to React, and
the HelloComponent using useState) which makes the core skill
framework-specific; replace those snippets with framework-neutral placeholders
or abstract examples: remove the direct import of "@tanstack/react-router" and
instead reference a generic "createFileRoute" or "router-lib" placeholder,
replace the React-only HelloComponent and useState example with a neutral
client-side example (e.g., describe a fetch POST workflow or show pseudocode for
a UI handler) or move the React-specific example into the React framework skill
package, and update all occurrences of Route, createFileRoute, HelloComponent,
and any React hooks so the core package remains framework-agnostic.
packages/start-client-core/skills/start-core/execution-model/SKILL.md (1)

44-154: ⚠️ Potential issue | 🟠 Major

This still teaches React bindings in a framework-neutral skill.

Lines 46, 63, 77, 88, 103, 121, and 147 still hard-code @tanstack/react-start, @tanstack/react-router, and React.ReactNode. Agents using the core skill from Solid/Vue Start will copy the React packages/types from here. Keep this skill binding-agnostic and move concrete React snippets into react-start.

Based on learnings, Separate framework-agnostic core logic from React/Solid bindings.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/execution-model/SKILL.md` around
lines 44 - 154, The SKILL.md contains framework-specific React bindings (imports
and types) that make the core skill non-agnostic; replace hard-coded usages of
`@tanstack/react-start`, `@tanstack/react-router`, and React.ReactNode in the
examples and prose with framework-neutral placeholders (e.g.,
`@tanstack/`<framework>-start or “your framework’s start package”) and generic
types (e.g., “Component children” or “framework-specific node”), and relocate
the concrete React examples for createServerFn, createServerOnlyFn,
createClientOnlyFn, ClientOnly, useHydrated, and createIsomorphicFn into the
react-start/react-router package docs so the core SKILL.md only shows
framework-agnostic snippets and references where framework-specific
implementations live.
packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md (1)

143-149: ⚠️ Potential issue | 🟡 Minor

Keep the file-path example framework-agnostic too.

Line 147 still hardcodes target: 'react'. Since this skill is framework-agnostic, that alternate snippet can still steer Solid/Vue agents toward an invalid plugin target.

✏️ Suggested adjustment
 tanstackRouter({
-  target: 'react',
+  target: '<framework>', // 'react' | 'solid' | 'vue'
   virtualRouteConfig: './routes.ts',
 })

Verify by comparing the two snippets in this file and scanning other virtualRouteConfig examples:

#!/bin/bash
set -euo pipefail

echo "Generic integration example in this skill:"
sed -n '126,140p' packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md

echo
echo "File-path variant under review:"
sed -n '143,149p' packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md

echo
echo "Other tanstackRouter + virtualRouteConfig examples in docs/skills:"
rg -n -C2 "virtualRouteConfig|target:\s*'(react|solid|vue)'|target:\s*'<framework>'" \
  packages/virtual-file-routes \
  packages/router-plugin \
  docs/router \
  -g '*.md'

Expected result: the file-path variant should follow the same framework-agnostic pattern as the main example instead of leaving a React-only default.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md` around
lines 143 - 149, The example snippet hardcodes target: 'react' which breaks the
skill's framework-agnostic intent; update the file-path variant that uses
tanstackRouter and virtualRouteConfig ('./routes.ts') to either remove the
hardcoded target or replace it with a neutral placeholder like target:
'<framework>' so it matches the generic example elsewhere in SKILL.md and avoids
steering Solid/Vue users to an invalid plugin target.
🧹 Nitpick comments (1)
packages/vue-router/skills/vue-router/SKILL.md (1)

66-90: Consider clarifying JSX setup or using SFC examples.

The route component examples use JSX syntax (fragments <>, function components returning JSX), but the Vite config only shows @vitejs/plugin-vue. Vue JSX requires @vitejs/plugin-vue-jsx. Most Vue developers use SFC templates, so this could cause confusion.

Consider either:

  1. Adding a note that JSX requires @vitejs/plugin-vue-jsx
  2. Using Vue SFC (.vue files) for these examples to match typical Vue patterns
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-router/skills/vue-router/SKILL.md` around lines 66 - 90, The
example uses JSX (RootLayout with fragments and Link/Outlet JSX) but the
docs/config only mention `@vitejs/plugin-vue`; update the example or note: either
add a clarifying comment that using JSX/TSX requires installing and enabling
`@vitejs/plugin-vue-jsx` in Vite, or replace the snippet with an equivalent Single
File Component (.vue) example (e.g., export default component using <template>
with <router-link> and <router-view>), and reference the createRootRoute, Route,
and RootLayout symbols so readers can find and update the code consistently.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-router/skills/compositions/router-query/SKILL.md`:
- Around line 340-358: Rename the example functions to avoid shadowing the
imported createRouter: change both example function declarations from
createRouter() to createAppRouter() (and update any internal references) so they
call the imported createRouter from `@tanstack/react-router` instead of recursing;
ensure both the "WRONG" and "CORRECT" snippets use createAppRouter and keep the
context/queryClient logic identical to the shown examples.

In `@packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md`:
- Around line 34-39: The installation instructions wrongly mark
`@tanstack/react-router-devtools` as a devDependency even though the guide
imports/uses TanStackRouterDevtools at runtime; update the commands so
`@tanstack/react-router-devtools` is installed as a regular dependency (move it
from the -D line into the main npm install command) and keep only
`@tanstack/router-plugin` as a devDependency, ensuring the runtime import
(TanStackRouterDevtools) is available in production builds.
- Around line 23-24: Update the CRITICAL migration note and the cleanup/search
instructions to include react-router-dom alongside react-router: modify the
warning sentence that currently references only `react-router` (the CRITICAL
note) to mention both `react-router` and `react-router-dom`, and add
corresponding grep/search commands for `react-router-dom` where the current grep
commands for `react-router` appear (the grep lines referenced near the end of
the document) so stale `react-router-dom` imports are detected and removed
during the uninstall/cleanup step.

In `@packages/react-router/skills/react-router/SKILL.md`:
- Around line 451-472: The example incorrectly recreates the router with
changing auth (useMemo) instead of creating the router once with a placeholder
context and injecting the live auth via RouterProvider; update the code so
createRouter({ routeTree, context: { auth: undefined! } }) is called once (e.g.,
at module scope or top-level of App), remove the useMemo recreation in App,
create an InnerApp that calls useAuth(), and render <RouterProvider
router={router} context={{ auth }} /> inside that InnerApp, wrapping InnerApp
with your AuthProvider in App.

In `@packages/router-core/skills/router-core/type-safety/SKILL.md`:
- Around line 252-266: The code fence redeclares `const props` and places an
`import` after statements, producing invalid TypeScript; split into separate,
self-contained snippets so each example compiles independently: (1) show the
wrong example with `import type { LinkProps }` at the top and `const props:
LinkProps = { to: '/posts' }`, (2) show the correct `as const satisfies
LinkProps` variant with its own import if needed, and (3) show the narrowed
generic example with `import type { RegisteredRouter }` (and `LinkProps`) at the
top and `const props = { to: '/posts' } as const satisfies
LinkProps<RegisteredRouter, string, '/posts'>`; ensure no duplicate `const
props` in the same snippet and place imports before usage so each snippet is
independently valid.
- Around line 107-115: The route example throws redirect(...) in beforeLoad but
never imports redirect, making the snippet invalid; update the top import to
include redirect alongside createFileRoute (e.g., import { createFileRoute,
redirect } from '@tanstack/react-router') so Route's beforeLoad can call
redirect; ensure the symbol names referenced are createFileRoute, redirect, and
beforeLoad in the Route definition.

In `@packages/start-server-core/bin/intent.js`:
- Around line 8-18: The catch block that currently treats any
ERR_MODULE_NOT_FOUND / MODULE_NOT_FOUND as "@tanstack/intent is not installed"
is too broad; update the handler to verify the missing-module message actually
references "@tanstack/intent" (e.g., inspect e.message or e.requireStack for
"Cannot find module '@tanstack/intent'" or the module name string) before
printing the install prompt, otherwise rethrow or print the original error and
exit; modify the catch around the dynamic import (the try/catch handling e) to
check e?.code and e?.message.includes('@tanstack/intent') (or similar) and only
show the installation/helpful console.error lines and process.exit(1) when the
missing module is indeed `@tanstack/intent`, otherwise surface the real error.

In `@packages/start-server-core/skills/start-server-core/SKILL.md`:
- Around line 20-22: The two consecutive blockquote paragraphs in SKILL.md (the
lines starting with "**CRITICAL**: These utilities are SERVER-ONLY..." and
"**CRITICAL**: Types are FULLY INFERRED...") currently have an extra blank line
that trips markdownlint MD028; remove the empty line between those blockquote
lines (or merge them into a single contiguous blockquote) so there is no blank
line inside the blockquote, preserving the existing wording and punctuation.
- Around line 53-64: Several markdown code blocks in SKILL.md call
createServerFn but omit its import; update every snippet that invokes
createServerFn (the blocks showing serverFn =
createServerFn({...}).handler(...)) to include the missing import statement: add
import { createServerFn } from '@tanstack/react-start' at the top of each of
those code fences so each example is self-contained and copy-pasteable.

In `@packages/vue-router/skills/vue-router/SKILL.md`:
- Around line 304-315: The Vue SFC example includes JavaScript-style comments
outside a <script> block (the "// SFC template... MyRoute.component.vue" line)
which will break if copied into an .vue file; replace that leading // comment
with an HTML comment (e.g., <!-- MyRoute.component.vue - SFC template -->) or
move the explanatory text above the code block in markdown, leaving the
<template> and <script setup> (and the useLoaderData/data usage) intact.

---

Duplicate comments:
In `@packages/start-client-core/skills/_artifacts/domain_map.yaml`:
- Around line 8-17: The library metadata in the domain_map.yaml is incorrect for
this package: update the library block that currently sets name:
'@tanstack/react-start' and primary_framework: 'React' so it accurately
describes this package (e.g., name '@tanstack/start-client-core' and a
framework-agnostic primary_framework) or remove/move this consolidated
React-specific descriptor to the repo-level artifact; edit the library block in
domain_map.yaml (the fields name, version if needed, description, and
primary_framework) to align with the package-local skill_tree.yaml and the
actual package purpose.

In `@packages/start-client-core/skills/start-core/execution-model/SKILL.md`:
- Around line 44-154: The SKILL.md contains framework-specific React bindings
(imports and types) that make the core skill non-agnostic; replace hard-coded
usages of `@tanstack/react-start`, `@tanstack/react-router`, and React.ReactNode in
the examples and prose with framework-neutral placeholders (e.g.,
`@tanstack/`<framework>-start or “your framework’s start package”) and generic
types (e.g., “Component children” or “framework-specific node”), and relocate
the concrete React examples for createServerFn, createServerOnlyFn,
createClientOnlyFn, ClientOnly, useHydrated, and createIsomorphicFn into the
react-start/react-router package docs so the core SKILL.md only shows
framework-agnostic snippets and references where framework-specific
implementations live.

In `@packages/start-client-core/skills/start-core/server-routes/SKILL.md`:
- Around line 24-77: The file hard-codes React and `@tanstack/react-router` usage
(imports of "@tanstack/react-router", createFileRoute usage tied to React, and
the HelloComponent using useState) which makes the core skill
framework-specific; replace those snippets with framework-neutral placeholders
or abstract examples: remove the direct import of "@tanstack/react-router" and
instead reference a generic "createFileRoute" or "router-lib" placeholder,
replace the React-only HelloComponent and useState example with a neutral
client-side example (e.g., describe a fetch POST workflow or show pseudocode for
a UI handler) or move the React-specific example into the React framework skill
package, and update all occurrences of Route, createFileRoute, HelloComponent,
and any React hooks so the core package remains framework-agnostic.

In `@packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md`:
- Around line 143-149: The example snippet hardcodes target: 'react' which
breaks the skill's framework-agnostic intent; update the file-path variant that
uses tanstackRouter and virtualRouteConfig ('./routes.ts') to either remove the
hardcoded target or replace it with a neutral placeholder like target:
'<framework>' so it matches the generic example elsewhere in SKILL.md and avoids
steering Solid/Vue users to an invalid plugin target.

---

Nitpick comments:
In `@packages/vue-router/skills/vue-router/SKILL.md`:
- Around line 66-90: The example uses JSX (RootLayout with fragments and
Link/Outlet JSX) but the docs/config only mention `@vitejs/plugin-vue`; update the
example or note: either add a clarifying comment that using JSX/TSX requires
installing and enabling `@vitejs/plugin-vue-jsx` in Vite, or replace the snippet
with an equivalent Single File Component (.vue) example (e.g., export default
component using <template> with <router-link> and <router-view>), and reference
the createRootRoute, Route, and RootLayout symbols so readers can find and
update the code consistently.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4b8d9909-3c64-4d2e-86ed-62f9fe37b901

📥 Commits

Reviewing files that changed from the base of the PR and between 142682c and ec661f4.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (33)
  • packages/react-router/bin/intent.js
  • packages/react-router/skills/compositions/router-query/SKILL.md
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/react-router/skills/react-router/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/router-core/skills/router-core/auth-and-guards/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/ssr/SKILL.md
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/solid-router/bin/intent.js
  • packages/solid-router/skills/_artifacts/domain_map.yaml
  • packages/solid-router/skills/solid-router/SKILL.md
  • packages/solid-start/bin/intent.js
  • packages/start-client-core/bin/intent.js
  • packages/start-client-core/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/_artifacts/skill_spec.md
  • packages/start-client-core/skills/_artifacts/skill_tree.yaml
  • packages/start-client-core/skills/start-core/SKILL.md
  • packages/start-client-core/skills/start-core/execution-model/SKILL.md
  • packages/start-client-core/skills/start-core/middleware/SKILL.md
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/start-server-core/bin/intent.js
  • packages/start-server-core/skills/start-server-core/SKILL.md
  • packages/virtual-file-routes/bin/intent.js
  • packages/virtual-file-routes/skills/_artifacts/domain_map.yaml
  • packages/virtual-file-routes/skills/virtual-file-routes/SKILL.md
  • packages/vue-router/bin/intent.js
  • packages/vue-router/skills/_artifacts/domain_map.yaml
  • packages/vue-router/skills/vue-router/SKILL.md
  • packages/vue-start/bin/intent.js
✅ Files skipped from review due to trivial changes (2)
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (13)
  • packages/start-client-core/skills/_artifacts/skill_spec.md
  • packages/react-router/bin/intent.js
  • packages/start-client-core/bin/intent.js
  • packages/vue-start/bin/intent.js
  • packages/start-client-core/skills/start-core/SKILL.md
  • packages/router-core/skills/router-core/ssr/SKILL.md
  • packages/vue-router/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/start-client-core/skills/start-core/middleware/SKILL.md
  • packages/virtual-file-routes/bin/intent.js
  • packages/solid-start/bin/intent.js
  • packages/solid-router/bin/intent.js

@codspeed-hq
Copy link

codspeed-hq bot commented Mar 9, 2026

Merging this PR will not alter performance

✅ 6 untouched benchmarks


Comparing feat/tanstack-intent-skills (5a08dfd) with main (32497be)

Open in CodSpeed

Copy link
Contributor

@Sheraff Sheraff left a comment

Choose a reason for hiding this comment

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

I reviewed react-router, router-core, solid-router, vue-router. I'm not very knowledgeable in the other areas (server-side stuff).

Add SKILL.md files across 11 packages to help AI coding agents generate
correct TanStack Router and Start code. Skills cover common patterns,
API usage, and failure modes that agents frequently get wrong.

Packages with skills:
- router-core (10 skills): core concepts, search/path params, navigation,
  data loading, auth/guards, code splitting, not-found/errors, type safety, SSR
- react-router (3): React bindings, Router+Query composition, migration from React Router
- start-client-core (6): Start setup, server functions, middleware,
  execution model, server routes, deployment
- react-start (2): React Start bindings, migration from Next.js
- virtual-file-routes (1): programmatic route tree building
- router-plugin (1): bundler plugin configuration
- start-server-core (1): server-side runtime
- solid-router (1): Solid bindings
- vue-router (1): Vue bindings
- solid-start (1): Solid Start bindings
- vue-start (1): Vue Start bindings

Each package includes bin/intent.js shim, _artifacts/ metadata, and
@tanstack/intent devDependency.
- Fix incorrect createTanstackRouter → createRouter in router-query examples
- Fix missing React type imports (ComponentPropsWithoutRef, FormEvent)
- Fix hardcoded localhost:3000 in SSR example, use req headers instead
- Fix session.update/clear to use await with data payload
- Fix start-setup → start-core slug mismatch in domain_map + skill_spec
- Make start-client-core skill_tree self-contained (remove react-start refs)
- Add framework-agnostic comments to execution-model and middleware skills
- Make virtual-file-routes vite example framework-agnostic
- Fix solid-router domain_map: Link is primary, createLink for wrappers
- Fix vue-router domain_map: scope Ref unwrapping to script, not templates
- Fix vue-router SKILL.md: tsx → vue fence language for template snippets
- Fix virtual-file-routes domain_map failure mode wording
- Fix MD028 blockquote blank lines across 11 files
- Fix MD040 missing fence languages across 4 files
- Update pnpm-lock.yaml
@tannerlinsley tannerlinsley force-pushed the feat/tanstack-intent-skills branch from ec661f4 to 9341075 Compare March 13, 2026 05:56
@changeset-bot
Copy link

changeset-bot bot commented Mar 13, 2026

⚠️ No Changeset found

Latest commit: 5a08dfd

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@tannerlinsley tannerlinsley force-pushed the feat/tanstack-intent-skills branch from 9341075 to 9f862cc Compare March 13, 2026 05:59
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 13

🧹 Nitpick comments (5)
.github/workflows/validate-skills.yml (1)

31-52: Consider simplifying the validation logic for clarity.

The current logic has a subtle precedence: if a top-level skills/ directory exists, it's validated exclusively; otherwise, monorepo packages/*/skills directories are validated. If both exist, only the top-level one is validated.

This may be intentional, but the comment on line 38 ("Monorepo — find skills/ under packages") doesn't clarify this mutual exclusivity. Consider either:

  1. Validating both if both exist, or
  2. Adding a comment explaining the precedence
♻️ Optional: validate both layouts if both exist
       - name: Find and validate skills
         run: |
           # Find all directories containing SKILL.md files
-          SKILLS_DIR=""
-          if [ -d "skills" ]; then
-            SKILLS_DIR="skills"
-          elif [ -d "packages" ]; then
+          FOUND=0
+          
+          # Check top-level skills directory
+          if [ -d "skills" ]; then
+            echo "Validating skills/..."
+            intent validate "skills"
+            FOUND=1
+          fi
+          
+          # Check monorepo packages/*/skills
+          if [ -d "packages" ]; then
             # Monorepo — find skills/ under packages
             for dir in packages/*/skills; do
               if [ -d "$dir" ]; then
                 echo "Validating $dir..."
                 intent validate "$dir"
+                FOUND=1
               fi
             done
-            exit 0
           fi
 
-          if [ -n "$SKILLS_DIR" ]; then
-            intent validate "$SKILLS_DIR"
-          else
+          if [ "$FOUND" -eq 0 ]; then
             echo "No skills/ directory found — skipping validation."
           fi
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/validate-skills.yml around lines 31 - 52, The validation
logic currently treats a top-level SKILLS_DIR as exclusive; update the script so
it validates both a top-level "skills" directory and any "packages/*/skills"
directories when both exist: keep the SKILLS_DIR check and call intent validate
"$SKILLS_DIR" if present, remove the early exit in the packages branch, then
always iterate packages/*/skills and run intent validate "$dir" for each
existing dir (preserving the existing echo and intent validate usage) so both
layouts are validated; alternatively, if you prefer keeping exclusivity, change
the comment near the for loop to state the precedence clearly referencing
SKILLS_DIR and the packages/*/skills loop.
_artifacts/start_domain_map.yaml (1)

8-17: Consider clarifying the scope of this domain map.

The library.name is @tanstack/react-start and primary_framework is React, but this file is named start_domain_map.yaml which suggests it covers TanStack Start broadly. Since the PR includes Solid and Vue Start bindings with their own domain maps, consider whether this should be renamed to react_start_domain_map.yaml for clarity, or if the description should note this is the canonical/reference domain map with React as the primary example.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@_artifacts/start_domain_map.yaml` around lines 8 - 17, The domain map's scope
is ambiguous because library.name ('@tanstack/react-start') and
primary_framework ('React') imply a React-specific map while the file name
suggests a general "start" domain map; either rename the file to reflect React
explicitly (e.g., react_start_domain_map.yaml) or update the YAML description to
state this is the canonical/reference domain map and that Solid/Vue have
separate domain maps; update the file name or the description field accordingly
and ensure consistency with other Start binding domain map filenames.
packages/router-core/skills/router-core/SKILL.md (1)

37-67: Add language identifier to fenced code block.

The decision tree code block lacks a language identifier, triggering MD040 lint warning. Since this is plain text/pseudocode, specify text as the language.

🧹 Proposed fix
-```
+```text
 Need to add/read/write URL query parameters?
   → router-core/search-params
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/SKILL.md` around lines 37 - 67, The
fenced decision-tree block in SKILL.md is missing a language identifier and
triggers MD040; update the opening fence to include a language (use "text") so
the block becomes ```text ... ```, ensuring the entire decision-tree content
between the triple backticks remains unchanged; target the decision-tree fenced
block in SKILL.md to add the language identifier.
packages/router-core/skills/router-core/auth-and-guards/SKILL.md (1)

108-127: Pattern differs from react-router SKILL.md.

A past review noted this InnerApp pattern differs from the approach in packages/react-router/skills/react-router/SKILL.md. While both are valid, consistency across skill files reduces confusion. Consider aligning the patterns or adding a note explaining when to use each approach.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/auth-and-guards/SKILL.md` around
lines 108 - 127, The SKILL.md example uses an InnerApp pattern (functions
InnerApp, App) that differs from the pattern in
packages/react-router/skills/react-router/SKILL.md; update the skill file to be
consistent by either switching this example to the same pattern used in the
react-router SKILL.md or add a short explanatory note in SKILL.md clarifying
when to use the InnerApp approach (showing useAuth + RouterProvider with
context) versus the alternative (wrapping RouterProvider inside AuthProvider or
passing auth differently). Reference the example symbols InnerApp, App,
AuthProvider, useAuth, RouterProvider and router so readers can map the guidance
to the existing code samples.
.github/workflows/check-skills.yml (1)

40-46: Consider using pnpm for consistency.

The workflow uses npm install -g and npm install while the repository uses pnpm. For consistency and to avoid potential resolution differences, consider using pnpm:

🧹 Proposed change
       - name: Install intent CLI
-        run: npm install -g `@tanstack/intent`
+        run: pnpm add -g `@tanstack/intent`

       - name: Install dependencies
-        run: npm install --ignore-scripts
-        env:
-          npm_config_legacy_peer_deps: 'true'
+        run: pnpm install --ignore-scripts

Note: This would also require adding pnpm setup via actions like pnpm/action-setup before the Node setup step.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/check-skills.yml around lines 40 - 46, Replace the npm
steps with pnpm equivalents to match the repo: add a pnpm setup action (e.g.,
uses: pnpm/action-setup@v2) before Node setup, then change the "Install intent
CLI" step to use pnpm (pnpm add -g `@tanstack/intent` or pnpm dlx as appropriate)
and change the "Install dependencies" step to run pnpm install (preferably pnpm
install --frozen-lockfile to ensure deterministic installs); ensure any
npm-specific env vars are removed or converted and that the workflow retains
necessary flags (e.g., --ignore-scripts only if required).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.github/workflows/notify-playbooks.yml:
- Line 40: The workflow uses git diff --name-only HEAD~1 HEAD to populate FILES
which misses changes when multiple commits are pushed; replace that range with
the push-range SHAs provided by the GitHub event (use the event before/after
SHAs) so FILES reflects the full push. Update the command that sets FILES (the
FILES=... assignment) to call git diff --name-only using the push-range
variables (event.before / event.after or the GitHub-provided env vars like
GITHUB_EVENT_BEFORE / GITHUB_SHA) instead of HEAD~1 and HEAD so downstream
checks operate on the complete set of changed files.

In `@packages/react-router/package.json`:
- Around line 102-103: The lockfile is out of sync with package.json because the
devDependency removal (the "@tanstack/intent" change and specifically the
removed "vibe-rules" entry in devDependencies) wasn't reflected in
pnpm-lock.yaml; run pnpm install at repo root to regenerate pnpm-lock.yaml,
verify that "vibe-rules" no longer appears in the lockfile and that
devDependencies match package.json, then commit and push the updated
pnpm-lock.yaml so CI can proceed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md`:
- Around line 27-29: The blockquote in SKILL.md contains an empty blank line
between two quoted lines (the two "**CRITICAL**" sentences), triggering
markdownlint MD028; remove the blank line so the two lines are part of the same
continuous blockquote (i.e., ensure the second "**CRITICAL**: For SSR..." line
is directly after the first quoted line with no intervening blank line) to fix
the MD028 formatting error.
- Around line 416-418: Update the guidance to avoid implying fire-and-forget for
critical data: clarify that loaders should await/return ensureQueryData when
data is critical to block navigation and prevent loading flashes, while
fire-and-forget (calling ensureQueryData without awaiting/returning) is only
appropriate for non-critical/streaming cases; mention defaultPreloadStaleTime:
0, useSuspenseQuery, router.invalidate, and loader explicitly so readers know
when to await ensureQueryData versus when side-effect-only calls are acceptable.

In `@packages/react-router/skills/react-router/SKILL.md`:
- Line 346: The JSX example contains a stray leading semicolon before the
CatchBoundary component; remove the semicolon so the tag starts with
"<CatchBoundary" (locate the JSX snippet containing ";<CatchBoundary" in the
SKILL.md example and change it to start with "CatchBoundary" to avoid a
copy/paste/syntax hazard).

In `@packages/react-start/skills/react-start/SKILL.md`:
- Around line 178-204: The example is missing the React useState import used in
EditPostForm; add an import for useState from 'react' at the top of the snippet
so the EditPostForm component can call useState without error—keep the existing
imports for createServerFn and useServerFn from '@tanstack/react-start' and
ensure useState is imported alongside them (referencing the useState symbol and
the EditPostForm component in the snippet).
- Around line 25-29: Remove the empty lines separating the consecutive
blockquotes (the lines starting "**CRITICAL**: All code is ISOMORPHIC...",
"**CRITICAL**: Do not confuse `@tanstack/react-start`...", and "**CRITICAL**:
Types are FULLY INFERRED...") so they form adjacent blockquote lines with no
blank lines between them to satisfy MD028; simply delete the blank lines between
those quoted lines or combine them into a single multi-line blockquote.

In `@packages/router-core/skills/router-core/code-splitting/SKILL.md`:
- Around line 22-25: Remove the blank line separating the two blockquote lines
so they remain part of a single contiguous blockquote; edit the SKILL.md block
containing "**CRITICAL**: Never `export` component functions from route files —
exported functions are included in the main bundle and bypass code splitting
entirely." and "**CRITICAL**: Use `getRouteApi('/path')` in code-split files,
NOT `import { Route } from './route'`. Importing Route defeats code splitting."
to eliminate the empty line between them (fixing markdownlint MD028 /
no-blanks-blockquote).

In `@packages/router-core/skills/router-core/path-params/SKILL.md`:
- Around line 23-26: There is an extra blank line between consecutive
blockquotes causing markdownlint MD028; open the SKILL.md section containing the
two "**CRITICAL**" blockquotes and remove the blank line so the blockquotes are
adjacent (i.e., ensure the two lines starting "**CRITICAL**: Never interpolate
params..." and "**CRITICAL**: Types are fully inferred..." are consecutive
blockquote lines with no intervening blank line), then run the linter to confirm
MD028 is resolved.

In `@packages/router-core/skills/router-core/ssr/SKILL.md`:
- Line 350: Guard the bodyless response before calling pipeline: in the code
path that calls pipeline(response.body as any, res) check whether response.body
is present (e.g., if (!response.body) { return res.end() } or send the
appropriate status/headers) and only call pipeline when body is defined; update
the call site that currently uses pipeline(response.body as any, res) to handle
bodyless responses safely to avoid passing undefined into pipeline.
- Around line 24-28: The blockquote sequence containing the three
warning/critical paragraphs (the lines starting with "**WARNING**: SSR APIs...",
"**CRITICAL**: TanStack Router is CLIENT-FIRST...", and "**CRITICAL**: Do not
generate Next.js patterns...") has blank lines between items which triggers
MD028; remove the empty lines so each blockquote line is contiguous (each line
begins with "> " and there are no blank lines inside the blockquote), or merge
the paragraphs into a single continuous blockquote to satisfy markdownlint.

In `@packages/solid-start/skills/solid-start/SKILL.md`:
- Around line 25-29: The three consecutive blockquotes starting with
"**CRITICAL**: All code is ISOMORPHIC...", "**CRITICAL**: Do not confuse...",
and "**CRITICAL**: Types are FULLY INFERRED..." violate MD028 due to blank lines
between them; remove the blank lines and either merge them into a single
continuous blockquote or separate them with a different delimiter (e.g., a
heading or horizontal rule). Edit SKILL.md to eliminate the empty lines between
these blockquote lines so they become one combined blockquote or replace the
intermediate blank lines with a non-blockquote separator.

In `@packages/start-client-core/skills/start-core/deployment/SKILL.md`:
- Around line 154-160: The ssr callback for Route (created via
createFileRoute('/docs/$docType/$docId')) references non-existent params
(params.status and params.value.docType); update the ssr function to use the
actual path params (e.g., params.docType and params.docId) and any required
request body/query checks instead of params.status or params.value;
specifically, modify the ssr callback on the Route export to inspect
params.docType (and params.docId if needed) and return false when docType ===
'sheet' (or adjust logic per intended behavior).

---

Nitpick comments:
In `@_artifacts/start_domain_map.yaml`:
- Around line 8-17: The domain map's scope is ambiguous because library.name
('@tanstack/react-start') and primary_framework ('React') imply a React-specific
map while the file name suggests a general "start" domain map; either rename the
file to reflect React explicitly (e.g., react_start_domain_map.yaml) or update
the YAML description to state this is the canonical/reference domain map and
that Solid/Vue have separate domain maps; update the file name or the
description field accordingly and ensure consistency with other Start binding
domain map filenames.

In @.github/workflows/check-skills.yml:
- Around line 40-46: Replace the npm steps with pnpm equivalents to match the
repo: add a pnpm setup action (e.g., uses: pnpm/action-setup@v2) before Node
setup, then change the "Install intent CLI" step to use pnpm (pnpm add -g
`@tanstack/intent` or pnpm dlx as appropriate) and change the "Install
dependencies" step to run pnpm install (preferably pnpm install
--frozen-lockfile to ensure deterministic installs); ensure any npm-specific env
vars are removed or converted and that the workflow retains necessary flags
(e.g., --ignore-scripts only if required).

In @.github/workflows/validate-skills.yml:
- Around line 31-52: The validation logic currently treats a top-level
SKILLS_DIR as exclusive; update the script so it validates both a top-level
"skills" directory and any "packages/*/skills" directories when both exist: keep
the SKILLS_DIR check and call intent validate "$SKILLS_DIR" if present, remove
the early exit in the packages branch, then always iterate packages/*/skills and
run intent validate "$dir" for each existing dir (preserving the existing echo
and intent validate usage) so both layouts are validated; alternatively, if you
prefer keeping exclusivity, change the comment near the for loop to state the
precedence clearly referencing SKILLS_DIR and the packages/*/skills loop.

In `@packages/router-core/skills/router-core/auth-and-guards/SKILL.md`:
- Around line 108-127: The SKILL.md example uses an InnerApp pattern (functions
InnerApp, App) that differs from the pattern in
packages/react-router/skills/react-router/SKILL.md; update the skill file to be
consistent by either switching this example to the same pattern used in the
react-router SKILL.md or add a short explanatory note in SKILL.md clarifying
when to use the InnerApp approach (showing useAuth + RouterProvider with
context) versus the alternative (wrapping RouterProvider inside AuthProvider or
passing auth differently). Reference the example symbols InnerApp, App,
AuthProvider, useAuth, RouterProvider and router so readers can map the guidance
to the existing code samples.

In `@packages/router-core/skills/router-core/SKILL.md`:
- Around line 37-67: The fenced decision-tree block in SKILL.md is missing a
language identifier and triggers MD040; update the opening fence to include a
language (use "text") so the block becomes ```text ... ```, ensuring the entire
decision-tree content between the triple backticks remains unchanged; target the
decision-tree fenced block in SKILL.md to add the language identifier.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74a979b4-8390-4ade-92af-a577daf3a975

📥 Commits

Reviewing files that changed from the base of the PR and between ec661f4 and 9341075.

📒 Files selected for processing (58)
  • .github/workflows/check-skills.yml
  • .github/workflows/notify-playbooks.yml
  • .github/workflows/validate-skills.yml
  • _artifacts/domain_map.yaml
  • _artifacts/skill_spec.md
  • _artifacts/skill_tree.yaml
  • _artifacts/start_domain_map.yaml
  • _artifacts/start_skill_tree.yaml
  • packages/react-router/bin/intent.js
  • packages/react-router/package.json
  • packages/react-router/skills/compositions/router-query/SKILL.md
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/react-router/skills/react-router/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/react-start/package.json
  • packages/react-start/skills/_artifacts/domain_map.yaml
  • packages/react-start/skills/_artifacts/skill_spec.md
  • packages/react-start/skills/_artifacts/skill_tree.yaml
  • packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md
  • packages/react-start/skills/react-start/SKILL.md
  • packages/router-core/bin/intent.js
  • packages/router-core/package.json
  • packages/router-core/skills/router-core/SKILL.md
  • packages/router-core/skills/router-core/auth-and-guards/SKILL.md
  • packages/router-core/skills/router-core/code-splitting/SKILL.md
  • packages/router-core/skills/router-core/data-loading/SKILL.md
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/path-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/references/validation-patterns.md
  • packages/router-core/skills/router-core/ssr/SKILL.md
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/router-plugin/package.json
  • packages/router-plugin/skills/_artifacts/domain_map.yaml
  • packages/router-plugin/skills/_artifacts/skill_spec.md
  • packages/router-plugin/skills/_artifacts/skill_tree.yaml
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/solid-router/package.json
  • packages/solid-router/skills/_artifacts/domain_map.yaml
  • packages/solid-router/skills/_artifacts/skill_spec.md
  • packages/solid-router/skills/_artifacts/skill_tree.yaml
  • packages/solid-router/skills/solid-router/SKILL.md
  • packages/solid-start/bin/intent.js
  • packages/solid-start/package.json
  • packages/solid-start/skills/_artifacts/domain_map.yaml
  • packages/solid-start/skills/_artifacts/skill_spec.md
  • packages/solid-start/skills/_artifacts/skill_tree.yaml
  • packages/solid-start/skills/solid-start/SKILL.md
  • packages/start-client-core/bin/intent.js
  • packages/start-client-core/package.json
  • packages/start-client-core/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/_artifacts/skill_spec.md
  • packages/start-client-core/skills/_artifacts/skill_tree.yaml
  • packages/start-client-core/skills/start-core/SKILL.md
  • packages/start-client-core/skills/start-core/deployment/SKILL.md
✅ Files skipped from review due to trivial changes (3)
  • packages/solid-start/skills/_artifacts/skill_tree.yaml
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-core/skills/router-core/search-params/references/validation-patterns.md
🚧 Files skipped from review as they are similar to previous changes (21)
  • _artifacts/domain_map.yaml
  • packages/solid-start/package.json
  • packages/react-router/bin/intent.js
  • packages/start-client-core/package.json
  • packages/solid-router/skills/_artifacts/skill_tree.yaml
  • packages/react-start/skills/_artifacts/domain_map.yaml
  • packages/solid-router/package.json
  • packages/solid-router/skills/_artifacts/skill_spec.md
  • packages/react-start/bin/intent.js
  • packages/solid-router/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/_artifacts/skill_spec.md
  • packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md
  • packages/react-start/skills/_artifacts/skill_tree.yaml
  • packages/react-start/skills/_artifacts/skill_spec.md
  • packages/start-client-core/bin/intent.js
  • packages/router-plugin/skills/_artifacts/domain_map.yaml
  • packages/start-client-core/skills/start-core/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/start-client-core/skills/_artifacts/skill_tree.yaml
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/react-start/package.json

- name: Collect changed files
id: changes
run: |
FILES=$(git diff --name-only HEAD~1 HEAD | jq -R -s -c 'split("\n") | map(select(length > 0))')
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Use push range SHAs instead of HEAD~1..HEAD for changed files.

Line 40 misses files when a push contains multiple commits, so downstream skill checks can run on incomplete change sets.

Proposed fix
-          FILES=$(git diff --name-only HEAD~1 HEAD | jq -R -s -c 'split("\n") | map(select(length > 0))')
+          BASE_SHA="${{ github.event.before }}"
+          if [ "$BASE_SHA" = "0000000000000000000000000000000000000000" ]; then
+            BASE_SHA="$(git rev-list --max-parents=0 HEAD)"
+          fi
+          FILES=$(git diff --name-only "$BASE_SHA" "${{ github.sha }}" | jq -R -s -c 'split("\n") | map(select(length > 0))')
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.github/workflows/notify-playbooks.yml at line 40, The workflow uses git
diff --name-only HEAD~1 HEAD to populate FILES which misses changes when
multiple commits are pushed; replace that range with the push-range SHAs
provided by the GitHub event (use the event before/after SHAs) so FILES reflects
the full push. Update the command that sets FILES (the FILES=... assignment) to
call git diff --name-only using the push-range variables (event.before /
event.after or the GitHub-provided env vars like GITHUB_EVENT_BEFORE /
GITHUB_SHA) instead of HEAD~1 and HEAD so downstream checks operate on the
complete set of changed files.

Comment on lines +27 to +29
> **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.

> **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix MD028 blockquote formatting at Line 28.

There is a blank line inside a blockquote between two quoted lines, which triggers markdownlint MD028.

🛠️ Proposed fix
 > **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.
-
 > **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.
> **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
> **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.
> **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 28-28: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
27 - 29, The blockquote in SKILL.md contains an empty blank line between two
quoted lines (the two "**CRITICAL**" sentences), triggering markdownlint MD028;
remove the blank line so the two lines are part of the same continuous
blockquote (i.e., ensure the second "**CRITICAL**: For SSR..." line is directly
after the first quoted line with no intervening blank line) to fix the MD028
formatting error.


```tsx
import { CatchBoundary } from '@tanstack/react-router'
;<CatchBoundary
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the stray leading semicolon in the JSX example.

;<CatchBoundary is a copy/paste hazard in a teaching snippet and should be <CatchBoundary.

Suggested fix
-;<CatchBoundary
+<CatchBoundary
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
;<CatchBoundary
<CatchBoundary
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/react-router/SKILL.md` at line 346, The JSX
example contains a stray leading semicolon before the CatchBoundary component;
remove the semicolon so the tag starts with "<CatchBoundary" (locate the JSX
snippet containing ";<CatchBoundary" in the SKILL.md example and change it to
start with "CatchBoundary" to avoid a copy/paste/syntax hazard).

Comment on lines +23 to +26
> **CRITICAL**: Never interpolate params into the `to` string. Always use the `params` prop. This is the most common agent mistake for path params.
> **CRITICAL**: Types are fully inferred. Never annotate the return of `useParams()`.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Clean up blockquote spacing for MD028 compliance.

Line 24 includes a blank-line break inside consecutive blockquotes, which will keep markdownlint noisy.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 24-24: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/path-params/SKILL.md` around lines 23
- 26, There is an extra blank line between consecutive blockquotes causing
markdownlint MD028; open the SKILL.md section containing the two "**CRITICAL**"
blockquotes and remove the blank line so the blockquotes are adjacent (i.e.,
ensure the two lines starting "**CRITICAL**: Never interpolate params..." and
"**CRITICAL**: Types are fully inferred..." are consecutive blockquote lines
with no intervening blank line), then run the linter to confirm MD028 is
resolved.

Comment on lines +24 to +28
> **WARNING**: SSR APIs are experimental. They share internal implementations with TanStack Start and may change. **TanStack Start is the recommended way to do SSR in production** — use manual SSR setup only when integrating with an existing server.

> **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default. With SSR enabled, loaders run on BOTH client AND server. They are NOT server-only like Remix/Next.js loaders. See [router-core/data-loading](../data-loading/SKILL.md).

> **CRITICAL**: Do not generate Next.js patterns (`getServerSideProps`, App Router, server components) or Remix patterns (server-only loader exports). TanStack Router has its own SSR API.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix blockquote spacing to satisfy MD028.

Lines 24–28 include blank lines inside a blockquote sequence, which triggers markdownlint warnings.

🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 25-25: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 27-27: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/ssr/SKILL.md` around lines 24 - 28,
The blockquote sequence containing the three warning/critical paragraphs (the
lines starting with "**WARNING**: SSR APIs...", "**CRITICAL**: TanStack Router
is CLIENT-FIRST...", and "**CRITICAL**: Do not generate Next.js patterns...")
has blank lines between items which triggers MD028; remove the empty lines so
each blockquote line is contiguous (each line begins with "> " and there are no
blank lines inside the blockquote), or merge the paragraphs into a single
continuous blockquote to satisfy markdownlint.

res.setHeader(name, value)
})

return pipeline(response.body as any, res)
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Guard bodyless responses before piping to Express response.

Line 350 assumes response.body is always present; bodyless responses can throw at runtime when passed to pipeline.

Proposed fix
-  return pipeline(response.body as any, res)
+  if (!response.body) {
+    res.end()
+    return
+  }
+  return pipeline(response.body as any, res)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return pipeline(response.body as any, res)
if (!response.body) {
res.end()
return
}
return pipeline(response.body as any, res)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/ssr/SKILL.md` at line 350, Guard the
bodyless response before calling pipeline: in the code path that calls
pipeline(response.body as any, res) check whether response.body is present
(e.g., if (!response.body) { return res.end() } or send the appropriate
status/headers) and only call pipeline when body is defined; update the call
site that currently uses pipeline(response.body as any, res) to handle bodyless
responses safely to avoid passing undefined into pipeline.

Comment on lines +25 to +29
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.

> **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.

> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix blank lines between consecutive blockquotes.

Static analysis flags MD028: blank lines inside blockquote. Consecutive blockquotes separated by blank lines should be combined or use a different separator.

📝 Proposed fix to combine blockquotes
 > **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
-
-> **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.
-
-> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
+>
+> **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.
+>
+> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
> **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.
> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
>
> **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.
>
> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
🧰 Tools
🪛 LanguageTool

[style] ~27-~27: Consider using a different adverb to strengthen your wording.
Context: ...SolidStart (@solidjs/start). They are completely different frameworks with different API...

(COMPLETELY_ENTIRELY)

🪛 markdownlint-cli2 (0.21.0)

[warning] 26-26: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 28-28: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/solid-start/skills/solid-start/SKILL.md` around lines 25 - 29, The
three consecutive blockquotes starting with "**CRITICAL**: All code is
ISOMORPHIC...", "**CRITICAL**: Do not confuse...", and "**CRITICAL**: Types are
FULLY INFERRED..." violate MD028 due to blank lines between them; remove the
blank lines and either merge them into a single continuous blockquote or
separate them with a different delimiter (e.g., a heading or horizontal rule).
Edit SKILL.md to eliminate the empty lines between these blockquote lines so
they become one combined blockquote or replace the intermediate blank lines with
a non-blockquote separator.

Comment on lines +154 to +160
export const Route = createFileRoute('/docs/$docType/$docId')({
ssr: ({ params }) => {
if (params.status === 'success' && params.value.docType === 'sheet') {
return false
}
},
})
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

# First, locate the file
fd "SKILL.md" packages/start-client-core

Repository: TanStack/router

Length of output: 451


🏁 Script executed:

# Search for the route pattern in the repository to understand context
rg "/docs/\$docType/\$docId" --type md

Repository: TanStack/router

Length of output: 41


🏁 Script executed:

# Read the specific file to verify lines 154-160
cat -n packages/start-client-core/skills/start-core/deployment/SKILL.md | sed -n '150,165p'

Repository: TanStack/router

Length of output: 519


Fix invalid ssr callback params example.

The example in lines 154-160 references params.status and params.value.docType, which do not exist as path parameters for the route /docs/$docType/$docId. Path parameters for this route are only docType and docId. The code should be corrected:

Proposed fix
 export const Route = createFileRoute('/docs/$docType/$docId')({
-  ssr: ({ params }) => {
-    if (params.status === 'success' && params.value.docType === 'sheet') {
-      return false
-    }
-  },
+  ssr: ({ params }) => params.docType !== 'sheet',
 })
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export const Route = createFileRoute('/docs/$docType/$docId')({
ssr: ({ params }) => {
if (params.status === 'success' && params.value.docType === 'sheet') {
return false
}
},
})
export const Route = createFileRoute('/docs/$docType/$docId')({
ssr: ({ params }) => params.docType !== 'sheet',
})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-client-core/skills/start-core/deployment/SKILL.md` around
lines 154 - 160, The ssr callback for Route (created via
createFileRoute('/docs/$docType/$docId')) references non-existent params
(params.status and params.value.docType); update the ssr function to use the
actual path params (e.g., params.docType and params.docId) and any required
request body/query checks instead of params.status or params.value;
specifically, modify the ssr callback on the Route export to inspect
params.docType (and params.docId if needed) and return false when docType ===
'sheet' (or adjust logic per intended behavior).

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 7

♻️ Duplicate comments (7)
packages/solid-start/skills/solid-start/SKILL.md (1)

25-29: ⚠️ Potential issue | 🟡 Minor

Fix consecutive blockquote formatting (MD028).

Line 26 and Line 28 contain blank lines inside a continuous blockquote block, which violates markdownlint MD028.

🛠️ Suggested fix
 > **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
-
 > **CRITICAL**: Do not confuse `@tanstack/solid-start` with SolidStart (`@solidjs/start`). They are completely different frameworks with different APIs.
-
 > **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/solid-start/skills/solid-start/SKILL.md` around lines 25 - 29, The
blockquote has blank lines breaking a continuous '>' block (MD028); update the
three consecutive blockquote lines containing "All code is ISOMORPHIC...", "Do
not confuse `@tanstack/solid-start`...", and "Types are FULLY INFERRED..." so
they form one contiguous blockquote without empty lines between them—either
remove the blank lines or ensure each line begins with '>' and there are no
empty '>'-prefixed lines; this will fix the MD028 violation.
packages/react-router/skills/compositions/router-query/SKILL.md (2)

27-29: ⚠️ Potential issue | 🟡 Minor

Remove the blank line inside the blockquote (MD028).

At Line 28, the empty line breaks the blockquote and triggers markdownlint MD028.

🛠️ Proposed fix
 > **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.
-
 > **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
27 - 29, The blockquote in SKILL.md that contains the two CRITICAL notes ("Set
`defaultPreloadStaleTime: 0`..." and "For SSR, create `QueryClient`...") has an
extra blank line breaking the blockquote (MD028); remove the empty line between
these two quoted lines so both CRITICAL lines remain part of the same blockquote
(no blank line between the quoted paragraphs).

416-418: ⚠️ Potential issue | 🟠 Major

Clarify loader guidance: don’t recommend side-effect-only ensureQueryData for critical data.

Line 417 currently implies fire-and-forget ensureQueryData. That contradicts the blocking-loader pattern described earlier and can reintroduce loading flashes for critical content. Keep return/await ensureQueryData(...) for critical data; reserve non-awaited calls for non-critical streaming cases.

🛠️ Proposed wording update
 - Router's `staleTime`/`gcTime` still apply to the loader return value. For pure Query patterns, return nothing from the loader (just `ensureQueryData` for the side effect) and read data exclusively from `useSuspenseQuery`
+- Router's `staleTime`/`gcTime` still apply to loader-managed data. For critical data, return/await `ensureQueryData(...)` in the loader and read via `useSuspenseQuery`. For non-critical/streaming data, use fire-and-forget `prefetchQuery(...)`.
In current TanStack Router + TanStack Query docs, should route loaders return/await `queryClient.ensureQueryData(...)` for critical data to block navigation and avoid loading flashes, and is non-awaited prefetch only recommended for non-critical streaming data?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
416 - 418, Update the guidance to clarify that for critical data loaders should
return or await queryClient.ensureQueryData(...) (blocking-loader pattern) so
navigation is blocked and loading flashes avoided, while non-awaited
ensureQueryData should only be recommended for non-critical
streaming/prefetching; keep the notes about defaultPreloadStaleTime: 0,
router.invalidate(), and that Query's own staleTime/gcTime govern refetching,
but explicitly state that ensureQueryData must be awaited/returned for critical
route data to enforce blocking behavior.
packages/start-server-core/skills/start-server-core/SKILL.md (2)

20-22: ⚠️ Potential issue | 🟡 Minor

Fix the blank line inside the blockquote.

Line 21 still contains only >, which creates a blank line inside the blockquote and triggers markdownlint MD028. Remove the blank line between the two blockquote paragraphs.

🧹 Suggested fix
 > **CRITICAL**: These utilities are SERVER-ONLY. Import them from `@tanstack/<framework>-start/server`, not from the main entry point. They throw if called outside a server request context.
->
+>
 > **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/skills/start-server-core/SKILL.md` around lines 20
- 22, Remove the empty blockquote line between the two CRITICAL paragraphs in
SKILL.md so the two quoted lines become consecutive blockquote paragraphs;
specifically, delete the solitary ">" line that sits between the "**CRITICAL**:
These utilities are SERVER-ONLY..." paragraph and the "**CRITICAL**: Types are
FULLY INFERRED..." paragraph to satisfy markdownlint MD028.

197-212: ⚠️ Potential issue | 🟡 Minor

Add the missing createServerFn import.

This code block uses createServerFn on line 202 but doesn't import it. All other code examples in this file include the necessary imports. Add import { createServerFn } from '@tanstack/react-start' to make this example self-contained and copy-pasteable.

📦 Suggested fix
 ```ts
 // Use `@tanstack/`<framework>-start for your framework (react, solid, vue)
+import { createServerFn } from '@tanstack/react-start'
 import { getValidatedQuery } from '@tanstack/react-start/server'
 import { z } from 'zod'
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/start-server-core/skills/start-server-core/SKILL.md` around lines
197 - 212, The example uses createServerFn but doesn't import it; add an import
for createServerFn from '@tanstack/react-start' at the top of the snippet so the
code is self-contained and copy-pasteable (alongside the existing
getValidatedQuery and z imports) — locate the example that declares serverFn via
createServerFn(...).handler and add the missing import statement for
createServerFn.
packages/router-core/bin/intent.js (1)

9-15: ⚠️ Potential issue | 🟠 Major

Match only the top-level missing module.

ERR_MODULE_NOT_FOUND / MODULE_NOT_FOUND are generic import-resolution errors, so the current includes('@tanstack/intent') guard is still broad enough to misreport some failures inside @tanstack/intent as “not installed”. Match the missing specifier itself before printing the install hint. The same generated shim pattern appears in the sibling bin/intent.js files in this PR. (nodejs.org)

Suggested tightening
-  const missingIntentLibrary =
-    typeof e?.message === 'string' && e.message.includes('@tanstack/intent')
+  const missingIntentLibrary =
+    typeof e?.message === 'string' &&
+    /Cannot find (?:package|module) ['"]@tanstack\/intent(?:\/intent-library)?['"]/.test(
+      e.message,
+    )
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/bin/intent.js` around lines 9 - 15, The check currently
treats any Module Not Found error whose message includes '@tanstack/intent' as
"not installed"; tighten it by extracting the missing specifier from the error
message and matching it exactly to '@tanstack/intent' before printing the
install hint. Update the logic in the intent bootstrap logic that defines
isModuleNotFound and missingIntentLibrary (look for variables named
isModuleNotFound, missingIntentLibrary and use e?.message) to parse e.message
with a regex that captures the missing module specifier (the quoted string in
Node's "Cannot find module 'X'" / "Cannot find package 'X'" messages) and only
set missingIntentLibrary true when that captured specifier ===
'@tanstack/intent'; apply the same change to the sibling bin/intent.js generated
shims.
packages/react-router/skills/react-router/SKILL.md (1)

346-346: ⚠️ Potential issue | 🟡 Minor

Remove the stray leading semicolon.

;<CatchBoundary is still a copy/paste syntax hazard in this example.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/react-router/SKILL.md` at line 346, Example
contains a stray leading semicolon before the JSX tag — remove the semicolon
preceding "<CatchBoundary" so the tag begins with "<CatchBoundary" (search for
the token sequence ";<CatchBoundary" in SKILL.md and delete the semicolon), and
scan the file for any other inadvertent leading semicolons before JSX tags like
CatchBoundary to clean similar copy/paste artifacts.
🧹 Nitpick comments (1)
packages/vue-router/skills/vue-router/SKILL.md (1)

23-23: Align internal markdown links with repo link convention.

These links use deep filesystem traversal (../../../...). Please switch to the docs-relative internal link format required for markdown docs in this repository.

As per coding guidelines "**/*.md: Use internal docs links relative to docs/ folder (e.g., ./guide/data-loading)".

Also applies to: 389-389

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-router/skills/vue-router/SKILL.md` at line 23, Replace the deep
filesystem traversal link "../../../router-core/skills/router-core/SKILL.md"
with the docs-relative internal link format used in this repo (for example
"./router-core/skills/router-core/SKILL.md") so the reference to "router-core"
uses the docs-relative path convention; update any other occurrences (e.g., the
link on line 389) to the same "./..." docs-relative style to match the "*.md"
guideline.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/react-router/skills/react-router/SKILL.md`:
- Around line 482-493: Update the guidance that currently mandates wrapping
Await in an external <Suspense>; instead explain that Await (see Await component
in packages/react-router/src/awaited.tsx) will implicitly handle Suspense when a
fallback prop is provided. Remove the "always wrap in Suspense" wording and
replace the example with the recommended pattern using Await with a fallback
prop (i.e., <Await promise={...} fallback={...}>...</Await>), and add a brief
cross-reference to the deferred-data-loading guide and
packages/router-core/skills/router-core/data-loading/SKILL.md for the canonical
pattern.

In `@packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md`:
- Around line 24-29: The blockquote has extra blank lines between consecutive
quoted lines causing markdownlint MD028; remove the blank lines so the three
consecutive blockquote paragraphs starting with "**CRITICAL**: TanStack Start is
isomorphic by default...", "**CRITICAL**: TanStack Start uses `createServerFn`,
NOT \"use server\" directives...", and "**CRITICAL**: Types are FULLY
INFERRED..." are contiguous blockquote lines (i.e., no empty lines between them)
to satisfy the no-blanks-blockquote rule.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`:
- Line 376: The snippet contains a stray leading semicolon before the Link
component; remove the leading ";" so the line reads starting with "<Link
search={(prev) => ({ ...prev, startDate: new Date().toISOString() })}>" (i.e.,
update the snippet containing the Link component and its search prop/arrow
function to drop the semicolon).

In `@packages/solid-router/skills/solid-router/SKILL.md`:
- Around line 326-356: Update the documentation so `ScrollRestoration` is not
shown as the current recommended approach: either remove the `<ScrollRestoration
/>` example or clearly mark it as deprecated/legacy-only and add a short note
pointing readers to use createRouter({ scrollRestoration: true }) instead;
specifically edit the section that contains the `ScrollRestoration` component
example to replace it with a legacy deprecation callout or delete the example
and include a one-line snippet referencing `createRouter` as the primary
approach.

In `@packages/vue-router/skills/vue-router/SKILL.md`:
- Around line 216-220: The fenced example for RouterProvider mixes TSX label
with Vue template syntax; update the code block for the RouterProvider example
to either use a Vue fence and Vue template syntax (so the <RouterProvider
:router="router" /> line is valid) or convert the markup to valid TSX/JSX props
(e.g., <RouterProvider router={router} />) and keep the fence label consistent;
locate the example around the RouterProvider import and the <RouterProvider ...
/> usage to make the fix.
- Around line 27-33: Collapse the three consecutive blockquote callouts into a
single contiguous blockquote by removing the blank lines between the
"**CRITICAL**" lines so they form one continuous quoted section; specifically,
edit the block containing the three lines starting with "**CRITICAL**: TanStack
Router types...", "**CRITICAL**: TanStack Router is CLIENT-FIRST...", and
"**CRITICAL**: Most composables return `Ref<T>`..." in SKILL.md and delete the
empty lines separating them (or alternatively separate them into non-adjacent
blocks) to resolve MD028.

In `@packages/vue-start/skills/vue-start/SKILL.md`:
- Around line 24-28: Remove the blank lines between the consecutive blockquote
lines that start with "**CRITICAL**:" so they become a single continuous
blockquote (or merge them into one blockquote paragraph) to satisfy markdownlint
MD028; specifically edit the three lines containing "**CRITICAL**: All code is
ISOMORPHIC by default...", "**CRITICAL**: Do not confuse `@tanstack/vue-start`
with Nuxt...", and "**CRITICAL**: Types are FULLY INFERRED..." so there are no
empty lines between these blockquote items.

---

Duplicate comments:
In `@packages/react-router/skills/compositions/router-query/SKILL.md`:
- Around line 27-29: The blockquote in SKILL.md that contains the two CRITICAL
notes ("Set `defaultPreloadStaleTime: 0`..." and "For SSR, create
`QueryClient`...") has an extra blank line breaking the blockquote (MD028);
remove the empty line between these two quoted lines so both CRITICAL lines
remain part of the same blockquote (no blank line between the quoted
paragraphs).
- Around line 416-418: Update the guidance to clarify that for critical data
loaders should return or await queryClient.ensureQueryData(...) (blocking-loader
pattern) so navigation is blocked and loading flashes avoided, while non-awaited
ensureQueryData should only be recommended for non-critical
streaming/prefetching; keep the notes about defaultPreloadStaleTime: 0,
router.invalidate(), and that Query's own staleTime/gcTime govern refetching,
but explicitly state that ensureQueryData must be awaited/returned for critical
route data to enforce blocking behavior.

In `@packages/react-router/skills/react-router/SKILL.md`:
- Line 346: Example contains a stray leading semicolon before the JSX tag —
remove the semicolon preceding "<CatchBoundary" so the tag begins with
"<CatchBoundary" (search for the token sequence ";<CatchBoundary" in SKILL.md
and delete the semicolon), and scan the file for any other inadvertent leading
semicolons before JSX tags like CatchBoundary to clean similar copy/paste
artifacts.

In `@packages/router-core/bin/intent.js`:
- Around line 9-15: The check currently treats any Module Not Found error whose
message includes '@tanstack/intent' as "not installed"; tighten it by extracting
the missing specifier from the error message and matching it exactly to
'@tanstack/intent' before printing the install hint. Update the logic in the
intent bootstrap logic that defines isModuleNotFound and missingIntentLibrary
(look for variables named isModuleNotFound, missingIntentLibrary and use
e?.message) to parse e.message with a regex that captures the missing module
specifier (the quoted string in Node's "Cannot find module 'X'" / "Cannot find
package 'X'" messages) and only set missingIntentLibrary true when that captured
specifier === '@tanstack/intent'; apply the same change to the sibling
bin/intent.js generated shims.

In `@packages/solid-start/skills/solid-start/SKILL.md`:
- Around line 25-29: The blockquote has blank lines breaking a continuous '>'
block (MD028); update the three consecutive blockquote lines containing "All
code is ISOMORPHIC...", "Do not confuse `@tanstack/solid-start`...", and "Types
are FULLY INFERRED..." so they form one contiguous blockquote without empty
lines between them—either remove the blank lines or ensure each line begins with
'>' and there are no empty '>'-prefixed lines; this will fix the MD028
violation.

In `@packages/start-server-core/skills/start-server-core/SKILL.md`:
- Around line 20-22: Remove the empty blockquote line between the two CRITICAL
paragraphs in SKILL.md so the two quoted lines become consecutive blockquote
paragraphs; specifically, delete the solitary ">" line that sits between the
"**CRITICAL**: These utilities are SERVER-ONLY..." paragraph and the
"**CRITICAL**: Types are FULLY INFERRED..." paragraph to satisfy markdownlint
MD028.
- Around line 197-212: The example uses createServerFn but doesn't import it;
add an import for createServerFn from '@tanstack/react-start' at the top of the
snippet so the code is self-contained and copy-pasteable (alongside the existing
getValidatedQuery and z imports) — locate the example that declares serverFn via
createServerFn(...).handler and add the missing import statement for
createServerFn.

---

Nitpick comments:
In `@packages/vue-router/skills/vue-router/SKILL.md`:
- Line 23: Replace the deep filesystem traversal link
"../../../router-core/skills/router-core/SKILL.md" with the docs-relative
internal link format used in this repo (for example
"./router-core/skills/router-core/SKILL.md") so the reference to "router-core"
uses the docs-relative path convention; update any other occurrences (e.g., the
link on line 389) to the same "./..." docs-relative style to match the "*.md"
guideline.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 4e8779a6-ad1b-4d49-ba43-b97f78e0d368

📥 Commits

Reviewing files that changed from the base of the PR and between 9341075 and 9f862cc.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (31)
  • packages/react-router/bin/intent.js
  • packages/react-router/package.json
  • packages/react-router/skills/compositions/router-query/SKILL.md
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/react-router/skills/react-router/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md
  • packages/router-core/bin/intent.js
  • packages/router-core/skills/router-core/auth-and-guards/SKILL.md
  • packages/router-core/skills/router-core/data-loading/SKILL.md
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/references/validation-patterns.md
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/solid-router/skills/solid-router/SKILL.md
  • packages/solid-start/bin/intent.js
  • packages/solid-start/skills/solid-start/SKILL.md
  • packages/start-client-core/bin/intent.js
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/start-server-core/bin/intent.js
  • packages/start-server-core/skills/start-server-core/SKILL.md
  • packages/virtual-file-routes/bin/intent.js
  • packages/vue-router/bin/intent.js
  • packages/vue-router/skills/vue-router/SKILL.md
  • packages/vue-start/bin/intent.js
  • packages/vue-start/skills/vue-start/SKILL.md
✅ Files skipped from review due to trivial changes (1)
  • packages/router-core/skills/router-core/type-safety/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/solid-router/bin/intent.js
  • packages/virtual-file-routes/bin/intent.js
  • packages/react-router/bin/intent.js
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/vue-router/bin/intent.js
  • packages/solid-start/bin/intent.js
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/vue-start/bin/intent.js
  • packages/react-start/bin/intent.js
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/router-core/skills/router-core/navigation/SKILL.md

Comment on lines +482 to +493
### 3. MEDIUM: Missing Suspense boundary for `Await`/deferred data

`Await` requires a `<Suspense>` ancestor. Without it, the deferred promise has no fallback UI and throws.

```tsx
// WRONG — no Suspense boundary
<Await promise={deferredData}>{(data) => <div>{data}</div>}</Await>

// CORRECT — wrap in Suspense
<Suspense fallback={<div>Loading...</div>}>
<Await promise={deferredData}>{(data) => <div>{data}</div>}</Await>
</Suspense>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, locate the SKILL.md file mentioned
find . -name "SKILL.md" -type f | head -20

Repository: TanStack/router

Length of output: 1283


🏁 Script executed:

# Check the specific lines in the React Router skill file
if [ -f "packages/react-router/skills/react-router/SKILL.md" ]; then
  wc -l "packages/react-router/skills/react-router/SKILL.md"
fi

Repository: TanStack/router

Length of output: 113


🏁 Script executed:

# Search for deferred-data guide in docs
find . -name "*deferred*" -o -name "*defer*" | grep -E "\.(md|tsx?)$" | head -20

Repository: TanStack/router

Length of output: 1177


🏁 Script executed:

# Read the specific section mentioned (482-493)
sed -n '475,500p' "packages/react-router/skills/react-router/SKILL.md"

Repository: TanStack/router

Length of output: 774


🏁 Script executed:

# Read the deferred-data-loading guide
cat "docs/router/guide/deferred-data-loading.md"

Repository: TanStack/router

Length of output: 7968


🏁 Script executed:

# Read the router-core data-loading SKILL.md
cat "packages/router-core/skills/router-core/data-loading/SKILL.md"

Repository: TanStack/router

Length of output: 13727


🏁 Script executed:

# Search for Await component implementation
find . -name "*.ts" -o -name "*.tsx" | xargs grep -l "export.*Await" | grep -v node_modules | grep -v dist | head -10

Repository: TanStack/router

Length of output: 378


🏁 Script executed:

# Look for Await component in the react-router package
find . -path "*/react-router/*" -name "*.ts" -o -name "*.tsx" | xargs grep -l "function Await\|const Await" | grep -v test | grep -v e2e | head -10

Repository: TanStack/router

Length of output: 176


🏁 Script executed:

# Read the Await component implementation for React
cat "packages/react-router/src/awaited.tsx"

Repository: TanStack/router

Length of output: 1453


🏁 Script executed:

# Also check the deferred-data-loading guide more carefully for any Suspense mentions
grep -n "Suspense" "docs/router/guide/deferred-data-loading.md" | head -20

Repository: TanStack/router

Length of output: 552


🏁 Script executed:

# Check if there are any API docs for the Await component
find . -name "*.md" -path "*/docs/*" | xargs grep -l "Await" | grep -E "(api|reference)" | head -10

Repository: TanStack/router

Length of output: 214


🏁 Script executed:

# Check the Await API documentation
cat "docs/router/api/router/awaitComponent.md"

Repository: TanStack/router

Length of output: 1136


Remove the "always wrap in Suspense" instruction; Await handles Suspense internally when fallback is provided.

The Await component automatically wraps itself in <Suspense> when you provide the fallback prop (see the component implementation in packages/react-router/src/awaited.tsx). This contradicts the section's teaching that you must manually wrap with <Suspense>. The actual pattern, documented in the deferred-data-loading guide and the sibling packages/router-core/skills/router-core/data-loading/SKILL.md, is:

<Await promise={deferredData} fallback={<div>Loading...</div>}>
  {(data) => <div>{data}</div>}
</Await>

Update the section to show the fallback prop pattern as the default approach, without requiring an outer <Suspense> wrapper.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/react-router/SKILL.md` around lines 482 - 493,
Update the guidance that currently mandates wrapping Await in an external
<Suspense>; instead explain that Await (see Await component in
packages/react-router/src/awaited.tsx) will implicitly handle Suspense when a
fallback prop is provided. Remove the "always wrap in Suspense" wording and
replace the example with the recommended pattern using Await with a fallback
prop (i.e., <Await promise={...} fallback={...}>...</Await>), and add a brief
cross-reference to the deferred-data-loading guide and
packages/router-core/skills/router-core/data-loading/SKILL.md for the canonical
pattern.

Comment on lines +24 to +29
> **CRITICAL**: TanStack Start is isomorphic by default. ALL code runs in both environments unless you use `createServerFn`. This is the opposite of Next.js Server Components, where code is server-only by default.

> **CRITICAL**: TanStack Start uses `createServerFn`, NOT `"use server"` directives. Do not carry over any `"use server"` or `"use client"` directives.

> **CRITICAL**: Types are FULLY INFERRED in TanStack Router/Start. Never cast, never annotate inferred values.

Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix blockquote spacing to satisfy markdownlint MD028.

Line 25 and Line 27 include blank lines between consecutive blockquote lines, which triggers no-blanks-blockquote.

Proposed fix
 > **CRITICAL**: TanStack Start is isomorphic by default. ALL code runs in both environments unless you use `createServerFn`. This is the opposite of Next.js Server Components, where code is server-only by default.
-
 > **CRITICAL**: TanStack Start uses `createServerFn`, NOT `"use server"` directives. Do not carry over any `"use server"` or `"use client"` directives.
-
 > **CRITICAL**: Types are FULLY INFERRED in TanStack Router/Start. Never cast, never annotate inferred values.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **CRITICAL**: TanStack Start is isomorphic by default. ALL code runs in both environments unless you use `createServerFn`. This is the opposite of Next.js Server Components, where code is server-only by default.
> **CRITICAL**: TanStack Start uses `createServerFn`, NOT `"use server"` directives. Do not carry over any `"use server"` or `"use client"` directives.
> **CRITICAL**: Types are FULLY INFERRED in TanStack Router/Start. Never cast, never annotate inferred values.
> **CRITICAL**: TanStack Start is isomorphic by default. ALL code runs in both environments unless you use `createServerFn`. This is the opposite of Next.js Server Components, where code is server-only by default.
> **CRITICAL**: TanStack Start uses `createServerFn`, NOT `"use server"` directives. Do not carry over any `"use server"` or `"use client"` directives.
> **CRITICAL**: Types are FULLY INFERRED in TanStack Router/Start. Never cast, never annotate inferred values.
🧰 Tools
🪛 markdownlint-cli2 (0.21.0)

[warning] 25-25: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 27-27: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md` around
lines 24 - 29, The blockquote has extra blank lines between consecutive quoted
lines causing markdownlint MD028; remove the blank lines so the three
consecutive blockquote paragraphs starting with "**CRITICAL**: TanStack Start is
isomorphic by default...", "**CRITICAL**: TanStack Start uses `createServerFn`,
NOT \"use server\" directives...", and "**CRITICAL**: Types are FULLY
INFERRED..." are contiguous blockquote lines (i.e., no empty lines between them)
to satisfy the no-blanks-blockquote rule.

}

// When navigating:
;<Link search={(prev) => ({ ...prev, startDate: new Date().toISOString() })}>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove the stray leading semicolon.

;<Link ...> is a copy/paste syntax hazard in a reference snippet.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`
at line 376, The snippet contains a stray leading semicolon before the Link
component; remove the leading ";" so the line reads starting with "<Link
search={(prev) => ({ ...prev, startDate: new Date().toISOString() })}>" (i.e.,
update the snippet containing the Link component and its search prop/arrow
function to drop the semicolon).

Comment on lines +27 to +33
> **CRITICAL**: TanStack Router types are FULLY INFERRED. Never cast, never annotate inferred values.

> **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, not on the server.

> **CRITICAL**: Most composables return `Ref<T>` — access via `.value` in script, auto-unwrapped in templates. This is the #1 difference from the React version.

> **CRITICAL**: Do not confuse `@tanstack/vue-router` with `vue-router` (the official Vue router). They are completely different libraries with different APIs.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Remove blank lines between consecutive blockquote callouts.

The blockquote warnings at Line 28, Line 30, and Line 32 trigger MD028 and should be collapsed into one continuous blockquote section (or split into separate non-adjacent blocks without blank lines).

Proposed fix
 > **CRITICAL**: TanStack Router types are FULLY INFERRED. Never cast, never annotate inferred values.
-
 > **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, not on the server.
-
 > **CRITICAL**: Most composables return `Ref<T>` — access via `.value` in script, auto-unwrapped in templates. This is the `#1` difference from the React version.
-
 > **CRITICAL**: Do not confuse `@tanstack/vue-router` with `vue-router` (the official Vue router). They are completely different libraries with different APIs.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **CRITICAL**: TanStack Router types are FULLY INFERRED. Never cast, never annotate inferred values.
> **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, not on the server.
> **CRITICAL**: Most composables return `Ref<T>` — access via `.value` in script, auto-unwrapped in templates. This is the #1 difference from the React version.
> **CRITICAL**: Do not confuse `@tanstack/vue-router` with `vue-router` (the official Vue router). They are completely different libraries with different APIs.
> **CRITICAL**: TanStack Router types are FULLY INFERRED. Never cast, never annotate inferred values.
> **CRITICAL**: TanStack Router is CLIENT-FIRST. Loaders run on the client by default, not on the server.
> **CRITICAL**: Most composables return `Ref<T>` — access via `.value` in script, auto-unwrapped in templates. This is the `#1` difference from the React version.
> **CRITICAL**: Do not confuse `@tanstack/vue-router` with `vue-router` (the official Vue router). They are completely different libraries with different APIs.
🧰 Tools
🪛 LanguageTool

[style] ~33-~33: Consider using a different adverb to strengthen your wording.
Context: ...er` (the official Vue router). They are completely different libraries with different APIs...

(COMPLETELY_ENTIRELY)

🪛 markdownlint-cli2 (0.21.0)

[warning] 28-28: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 30-30: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 32-32: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-router/skills/vue-router/SKILL.md` around lines 27 - 33,
Collapse the three consecutive blockquote callouts into a single contiguous
blockquote by removing the blank lines between the "**CRITICAL**" lines so they
form one continuous quoted section; specifically, edit the block containing the
three lines starting with "**CRITICAL**: TanStack Router types...",
"**CRITICAL**: TanStack Router is CLIENT-FIRST...", and "**CRITICAL**: Most
composables return `Ref<T>`..." in SKILL.md and delete the empty lines
separating them (or alternatively separate them into non-adjacent blocks) to
resolve MD028.

Comment on lines +216 to +220
```tsx
import { RouterProvider } from '@tanstack/vue-router'
// In createApp or template
<RouterProvider :router="router" />
```
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Fix mixed syntax in RouterProvider example fence.

This block is labeled tsx but uses Vue template binding syntax (:router), which is invalid TSX when copied. Use a vue fence or convert to valid TSX/JSX props.

Proposed fix
-```tsx
+```vue
 import { RouterProvider } from '@tanstack/vue-router'
 // In createApp or template
 <RouterProvider :router="router" />

</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/vue-router/skills/vue-router/SKILL.md around lines 216 - 220, The
fenced example for RouterProvider mixes TSX label with Vue template syntax;
update the code block for the RouterProvider example to either use a Vue fence
and Vue template syntax (so the line is
valid) or convert the markup to valid TSX/JSX props (e.g., ) and keep the fence label consistent; locate the example
around the RouterProvider import and the <RouterProvider ... /> usage to make
the fix.


</details>

<!-- fingerprinting:phantom:triton:hawk -->

<!-- This is an auto-generated comment by CodeRabbit -->

Comment on lines +24 to +28
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.

> **CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt. They are completely different frameworks with different APIs.

> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix blockquote spacing to satisfy markdownlint (MD028).

Line [25] and Line [27] introduce blank lines inside consecutive blockquotes, which trips MD028. Remove the blank lines (or convert to a single blockquote block).

Suggested fix
 > **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
-
 > **CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt. They are completely different frameworks with different APIs.
-
 > **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
> **CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt. They are completely different frameworks with different APIs.
> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
> **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
> **CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt. They are completely different frameworks with different APIs.
> **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
🧰 Tools
🪛 LanguageTool

[style] ~26-~26: Consider using a different adverb to strengthen your wording.
Context: ...tanstack/vue-start` with Nuxt. They are completely different frameworks with different API...

(COMPLETELY_ENTIRELY)

🪛 markdownlint-cli2 (0.21.0)

[warning] 25-25: Blank line inside blockquote

(MD028, no-blanks-blockquote)


[warning] 27-27: Blank line inside blockquote

(MD028, no-blanks-blockquote)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-start/skills/vue-start/SKILL.md` around lines 24 - 28, Remove
the blank lines between the consecutive blockquote lines that start with
"**CRITICAL**:" so they become a single continuous blockquote (or merge them
into one blockquote paragraph) to satisfy markdownlint MD028; specifically edit
the three lines containing "**CRITICAL**: All code is ISOMORPHIC by default...",
"**CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt...", and
"**CRITICAL**: Types are FULLY INFERRED..." so there are no empty lines between
these blockquote items.

@tannerlinsley tannerlinsley force-pushed the feat/tanstack-intent-skills branch from 9f862cc to 7f52034 Compare March 13, 2026 06:18
- Address all 9 Sheraff review comments (ensureQueryData, auth patterns,
  open redirect, useLocation migration, reusable components, zodValidator)
- Address all 11 actionable CodeRabbit comments (naming collisions,
  framework-agnostic comments, missing imports, bin/intent.js error handling)
- Full source-verified audit of all 28 skills across 7 re-audited packages
- Fix solid-start: add HydrationScript, move HeadContent to body, use
  shellComponent pattern
- Fix solid-router: useLoaderDeps returns Accessor<T>, ScrollRestoration
  deprecated, add missing hooks/components
- Fix vue-router: useLinkProps returns LinkHTMLAttributes, useLoaderDeps
  returns Ref<T>, fix split-file convention
- Fix start-server-core: correct file path, server fn prefix, getValidatedQuery
  API, add createServerFn imports to all examples
- Fix router-core skills: preloadStaleTime wording, loader route param,
  error retry pattern, search-params adapter scoping
- All 28 skills pass @tanstack/intent validate
@tannerlinsley tannerlinsley force-pushed the feat/tanstack-intent-skills branch from 7f52034 to 5a08dfd Compare March 13, 2026 06:20
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (8)
packages/vue-start/skills/vue-start/SKILL.md (1)

24-28: ⚠️ Potential issue | 🟡 Minor

Remove blank lines between consecutive blockquotes (MD028).

Line [25] and Line [27] still split consecutive > blockquotes with empty lines, which keeps markdownlint MD028 failing.

Suggested fix
 > **CRITICAL**: All code is ISOMORPHIC by default. Loaders run on BOTH server and client. Use `createServerFn` for server-only logic.
-
 > **CRITICAL**: Do not confuse `@tanstack/vue-start` with Nuxt. They are completely different frameworks with different APIs.
-
 > **CRITICAL**: Types are FULLY INFERRED. Never cast, never annotate inferred values.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/vue-start/skills/vue-start/SKILL.md` around lines 24 - 28, The three
consecutive blockquote lines in SKILL.md (the lines starting with "**CRITICAL**:
All code is ISOMORPHIC...", "**CRITICAL**: Do not confuse
`@tanstack/vue-start`...", and "**CRITICAL**: Types are FULLY INFERRED...")
currently have blank lines between them causing markdownlint MD028; remove the
empty lines so the three `>` blockquotes are adjacent (no blank lines) to make
them a consecutive blockquote and resolve MD028.
packages/react-router/skills/react-router/SKILL.md (2)

346-346: ⚠️ Potential issue | 🟡 Minor

Remove the stray leading semicolon before CatchBoundary.

Line 346 starts with ;<CatchBoundary, which is a copy/paste footgun in a teaching snippet and should be plain JSX.

Suggested fix
-;<CatchBoundary
+<CatchBoundary
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/react-router/SKILL.md` at line 346, Remove the
stray leading semicolon before the CatchBoundary JSX example in SKILL.md so the
snippet reads plain JSX; locate the fragment that begins with a semicolon
followed by CatchBoundary (the `CatchBoundary` component example) and delete the
semicolon so the element starts with `<CatchBoundary` to avoid the copy/paste
footgun.

482-493: ⚠️ Potential issue | 🟠 Major

The Await guidance is too strict; prefer the fallback prop pattern.

The section currently teaches that Await must always be wrapped in <Suspense>. In TanStack React Router, Await can handle suspense when fallback is provided, so this should not be framed as a hard requirement in all cases.

Suggested fix
-### 3. MEDIUM: Missing Suspense boundary for `Await`/deferred data
-
-`Await` requires a `<Suspense>` ancestor. Without it, the deferred promise has no fallback UI and throws.
+### 3. MEDIUM: Missing fallback handling for deferred data
+
+Use `Await` with a `fallback` prop (or provide a Suspense ancestor). Prefer the `fallback` prop pattern in examples.

 ```tsx
-// WRONG — no Suspense boundary
+// WRONG — no fallback UI for deferred promise
 <Await promise={deferredData}>{(data) => <div>{data}</div>}</Await>
 
-// CORRECT — wrap in Suspense
-<Suspense fallback={<div>Loading...</div>}>
-  <Await promise={deferredData}>{(data) => <div>{data}</div>}</Await>
-</Suspense>
+// CORRECT — provide fallback directly
+<Await promise={deferredData} fallback={<div>Loading...</div>}>
+  {(data) => <div>{data}</div>}
+</Await>
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/react-router/skills/react-router/SKILL.md around lines 482 - 493,
Update the guidance that currently states Await must always be wrapped in a
Suspense boundary: change the wording to explain that Await can accept a
fallback prop so it does not strictly require an external Suspense, and update
the examples around Await/deferredData to replace the "no Suspense boundary" vs
"wrap in Suspense" examples with "no fallback UI for deferred promise" and
"provide fallback directly" variants that demonstrate using Await with its
fallback prop; reference the Await component, its fallback prop, Suspense only
where applicable, and the deferredData example to locate and replace the
content.


</details>

</blockquote></details>
<details>
<summary>packages/solid-router/skills/solid-router/SKILL.md (1)</summary><blockquote>

`348-356`: _⚠️ Potential issue_ | _🟡 Minor_

**Mark `ScrollRestoration` example as legacy or remove it.**

Line 326 says this component is deprecated, but this section still presents it as standard usage. That creates mixed guidance.

<details>
<summary>Suggested doc fix</summary>

```diff
-### `ScrollRestoration`
-
-Restores scroll position on navigation:
+### `ScrollRestoration` (legacy/deprecated)
+
+Legacy usage only. Prefer `createRouter({ scrollRestoration: true })`.

 ```tsx
 import { ScrollRestoration } from '@tanstack/solid-router'
 // In root route component
 ;<ScrollRestoration />
</details>

  

```web
For `@tanstack/solid-router` version 1.166.2, is <ScrollRestoration /> deprecated, and is createRouter({ scrollRestoration: true }) the recommended approach?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/solid-router/skills/solid-router/SKILL.md` around lines 348 - 356,
Update the docs so the ScrollRestoration example is either removed or explicitly
marked as deprecated/legacy: locate the example showing <ScrollRestoration />
(symbol: ScrollRestoration) in SKILL.md and change the text to indicate it's
deprecated for v1.166.2 and advise using createRouter({ scrollRestoration: true
}) (symbol: createRouter) as the recommended approach; ensure the doc text
clarifies which versions this applies to and optionally link to the router
config example instead of the component usage.
packages/react-router/skills/compositions/router-query/SKILL.md (2)

27-29: ⚠️ Potential issue | 🟡 Minor

Remove the blank line inside the blockquote (MD028).

There’s an empty line between two quoted lines, which breaks markdownlint no-blanks-blockquote.

Suggested fix
 > **CRITICAL**: Set `defaultPreloadStaleTime: 0` when using TanStack Query. Without this, Router's built-in preload cache (30s default) prevents Query from controlling data freshness.
-
 > **CRITICAL**: For SSR, create `QueryClient` inside the `createRouter` factory function. A module-level singleton leaks data between server requests.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
27 - 29, Remove the stray blank line inside the blockquote in SKILL.md that
triggers markdownlint MD028; merge the two quoted lines so the blockquote
contains no empty lines (ensure the two lines starting with "**CRITICAL**: Set
`defaultPreloadStaleTime: 0`..." and "**CRITICAL**: For SSR, create
`QueryClient`..." are adjacent with no blank line between them).

416-418: ⚠️ Potential issue | 🟠 Major

Clarify Line 417: don’t imply fire-and-forget ensureQueryData for critical loader data.

Line 417 currently suggests “return nothing” while calling ensureQueryData for side effects. That conflicts with the earlier “ensure before render/no flash” pattern. For critical route data, the loader should return/await ensureQueryData; fire-and-forget is better limited to non-critical streaming cases (e.g., prefetchQuery).

Suggested wording update
 - Router's `staleTime`/`gcTime` still apply to the loader return value. For pure Query patterns, return nothing from the loader (just `ensureQueryData` for the side effect) and read data exclusively from `useSuspenseQuery`
 + Router's `staleTime`/`gcTime` still apply to loader-managed data. For critical data, return/await `ensureQueryData(...)` in the loader so navigation can wait for cache readiness. Use fire-and-forget only for non-critical/streaming fetches (typically via `prefetchQuery`), and read UI data via `useSuspenseQuery`.
In official TanStack Router + TanStack Query docs, should route loaders return/await queryClient.ensureQueryData(...) for critical-above-the-fold data to avoid loading flashes, and is fire-and-forget intended only for non-critical streaming data (typically prefetchQuery)?
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/react-router/skills/compositions/router-query/SKILL.md` around lines
416 - 418, Update the guidance around ensureQueryData to make clear that for
critical, above-the-fold loader data you should await/return the Promise from
queryClient.ensureQueryData (or return the loader result) so the router waits
and avoids loading flashes, and reserve fire-and-forget (e.g., using
prefetchQuery or not awaiting ensureQueryData) only for non-critical
streaming/prefetch scenarios; reference Router options like
defaultPreloadStaleTime and behaviors of staleTime/gcTime and router.invalidate
in the same paragraph so readers know Query still controls refetching while the
loader must await ensureQueryData for guaranteed data before render.
packages/vue-router/skills/vue-router/SKILL.md (1)

216-220: ⚠️ Potential issue | 🟡 Minor

Mixed syntax in RouterProvider example.

This code block is labeled tsx but line 219 uses Vue template binding syntax (:router), which is invalid TSX. The past review flagged this issue, but it appears unaddressed.

Proposed fix: Use Vue fence or JSX syntax

Option 1: Change to Vue fence

-```tsx
+```vue
+<script setup>
 import { RouterProvider } from '@tanstack/vue-router'
-// In createApp or template
+</script>
+<template>
 <RouterProvider :router="router" />
+</template>

**Option 2: Show createApp usage with JSX**
```diff
 ```tsx
 import { RouterProvider } from '@tanstack/vue-router'
-// In createApp or template
-<RouterProvider :router="router" />
+import { createApp } from 'vue'
+
+const app = createApp(RouterProvider, { router })
+app.mount('#root')
</details>

<details>
<summary>🤖 Prompt for AI Agents</summary>

Verify each finding against the current code and only fix it if needed.

In @packages/vue-router/skills/vue-router/SKILL.md around lines 216 - 220, The
example shows mixed TSX and Vue template syntax for RouterProvider
(RouterProvider, :router, createApp/router) — fix by making the snippet
consistent: either change the code fence to a Vue block and use <script setup>
plus a with (reference
RouterProvider and router), or convert to valid JSX/TSX by importing createApp
and passing router as props to RouterProvider (e.g., createApp(RouterProvider, {
router })). Update the snippet to use one of these two options so RouterProvider
usage is valid.


</details>

</blockquote></details>
<details>
<summary>packages/router-core/skills/router-core/search-params/references/validation-patterns.md (1)</summary><blockquote>

`376-376`: _⚠️ Potential issue_ | _🟡 Minor_

**Remove the stray leading semicolon.**

The semicolon before `<Link` is a syntax error in the navigation example.



<details>
<summary>🔧 Proposed fix</summary>

```diff
-;<Link search={(prev) => ({ ...prev, startDate: new Date().toISOString() })}>
+<Link search={(prev) => ({ ...prev, startDate: new Date().toISOString() })}>
   Set Start Date
 </Link>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`
at line 376, Remove the stray leading semicolon before the JSX example starting
with <Link search={(prev) => ({ ...prev, startDate: new Date().toISOString()
})}> so the line begins with the <Link ...> element (no leading semicolon) to
fix the syntax error in the navigation example.
🧹 Nitpick comments (1)
packages/router-core/skills/router-core/type-safety/SKILL.md (1)

497-497: Consider turning “See also” into clickable relative links.

This improves discoverability for humans and agents consuming the markdown.

As per coding guidelines, "**/*.md: Use internal docs links relative to docs/ folder (e.g., ./guide/data-loading)".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/type-safety/SKILL.md` at line 497,
Update the "See also" line in SKILL.md to use clickable relative markdown links
instead of plain text; replace the plain references ("router-core (Register
setup), router-core/navigation (from narrowing), router-core/code-splitting
(getRouteApi)") with relative doc links following the repo guideline (e.g.,
./router-core, ./router-core/navigation, ./router-core/code-splitting) so
readers and agents can navigate directly from the docs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/router-core/skills/router-core/auth-and-guards/SKILL.md`:
- Line 458: Replace the plain-text cross-reference "See also:
**router-core/data-loading/SKILL.md** — `beforeLoad` runs before `loader`; auth
context flows into loader via route context" with the internal docs-link style
used elsewhere (relative to the docs/ folder), e.g. convert to a relative docs
link (like ./router-core/data-loading) while preserving the explanatory text and
inline code references (`beforeLoad`, `loader`, "route context"); update the
SKILL.md line that contains that sentence to use the docs link syntax instead of
the literal .md filename.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`:
- Around line 5-7: The doc incorrectly states "Zod v3 does not implement
Standard Schema"; update the text in validation-patterns.md to note that Zod
v3.24.0+ does implement Standard Schema, and clarify that `@tanstack/zod-adapter`
is recommended (for conveniences like fallback()) but not strictly required for
Zod >= 3.24.0; also state which minimum Zod versions require the adapter if you
intend to target older Zod releases, and keep the guidance to prefer adapter's
fallback() over zod's .catch() and to wrap validators with zodValidator() for
consistency.

---

Duplicate comments:
In `@packages/react-router/skills/compositions/router-query/SKILL.md`:
- Around line 27-29: Remove the stray blank line inside the blockquote in
SKILL.md that triggers markdownlint MD028; merge the two quoted lines so the
blockquote contains no empty lines (ensure the two lines starting with
"**CRITICAL**: Set `defaultPreloadStaleTime: 0`..." and "**CRITICAL**: For SSR,
create `QueryClient`..." are adjacent with no blank line between them).
- Around line 416-418: Update the guidance around ensureQueryData to make clear
that for critical, above-the-fold loader data you should await/return the
Promise from queryClient.ensureQueryData (or return the loader result) so the
router waits and avoids loading flashes, and reserve fire-and-forget (e.g.,
using prefetchQuery or not awaiting ensureQueryData) only for non-critical
streaming/prefetch scenarios; reference Router options like
defaultPreloadStaleTime and behaviors of staleTime/gcTime and router.invalidate
in the same paragraph so readers know Query still controls refetching while the
loader must await ensureQueryData for guaranteed data before render.

In `@packages/react-router/skills/react-router/SKILL.md`:
- Line 346: Remove the stray leading semicolon before the CatchBoundary JSX
example in SKILL.md so the snippet reads plain JSX; locate the fragment that
begins with a semicolon followed by CatchBoundary (the `CatchBoundary` component
example) and delete the semicolon so the element starts with `<CatchBoundary` to
avoid the copy/paste footgun.
- Around line 482-493: Update the guidance that currently states Await must
always be wrapped in a Suspense boundary: change the wording to explain that
Await can accept a fallback prop so it does not strictly require an external
Suspense, and update the examples around Await/deferredData to replace the "no
Suspense boundary" vs "wrap in Suspense" examples with "no fallback UI for
deferred promise" and "provide fallback directly" variants that demonstrate
using Await with its fallback prop; reference the Await component, its fallback
prop, Suspense only where applicable, and the deferredData example to locate and
replace the content.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`:
- Line 376: Remove the stray leading semicolon before the JSX example starting
with <Link search={(prev) => ({ ...prev, startDate: new Date().toISOString()
})}> so the line begins with the <Link ...> element (no leading semicolon) to
fix the syntax error in the navigation example.

In `@packages/solid-router/skills/solid-router/SKILL.md`:
- Around line 348-356: Update the docs so the ScrollRestoration example is
either removed or explicitly marked as deprecated/legacy: locate the example
showing <ScrollRestoration /> (symbol: ScrollRestoration) in SKILL.md and change
the text to indicate it's deprecated for v1.166.2 and advise using
createRouter({ scrollRestoration: true }) (symbol: createRouter) as the
recommended approach; ensure the doc text clarifies which versions this applies
to and optionally link to the router config example instead of the component
usage.

In `@packages/vue-router/skills/vue-router/SKILL.md`:
- Around line 216-220: The example shows mixed TSX and Vue template syntax for
RouterProvider (RouterProvider, :router, createApp/router) — fix by making the
snippet consistent: either change the code fence to a Vue block and use <script
setup> plus a <template> with <RouterProvider :router="router" /> (reference
RouterProvider and router), or convert to valid JSX/TSX by importing createApp
and passing router as props to RouterProvider (e.g., createApp(RouterProvider, {
router })). Update the snippet to use one of these two options so RouterProvider
usage is valid.

In `@packages/vue-start/skills/vue-start/SKILL.md`:
- Around line 24-28: The three consecutive blockquote lines in SKILL.md (the
lines starting with "**CRITICAL**: All code is ISOMORPHIC...", "**CRITICAL**: Do
not confuse `@tanstack/vue-start`...", and "**CRITICAL**: Types are FULLY
INFERRED...") currently have blank lines between them causing markdownlint
MD028; remove the empty lines so the three `>` blockquotes are adjacent (no
blank lines) to make them a consecutive blockquote and resolve MD028.

---

Nitpick comments:
In `@packages/router-core/skills/router-core/type-safety/SKILL.md`:
- Line 497: Update the "See also" line in SKILL.md to use clickable relative
markdown links instead of plain text; replace the plain references ("router-core
(Register setup), router-core/navigation (from narrowing),
router-core/code-splitting (getRouteApi)") with relative doc links following the
repo guideline (e.g., ./router-core, ./router-core/navigation,
./router-core/code-splitting) so readers and agents can navigate directly from
the docs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 77796193-6f92-4133-88f9-c56e4e09bcd3

📥 Commits

Reviewing files that changed from the base of the PR and between 9f862cc and 5a08dfd.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (34)
  • packages/react-router/bin/intent.js
  • packages/react-router/eslint.config.ts
  • packages/react-router/skills/compositions/router-query/SKILL.md
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md
  • packages/react-router/skills/react-router/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/react-start/skills/lifecycle/migrate-from-nextjs/SKILL.md
  • packages/router-core/bin/intent.js
  • packages/router-core/skills/router-core/auth-and-guards/SKILL.md
  • packages/router-core/skills/router-core/data-loading/SKILL.md
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/search-params/references/validation-patterns.md
  • packages/router-core/skills/router-core/type-safety/SKILL.md
  • packages/router-plugin/bin/intent.js
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/solid-router/eslint.config.ts
  • packages/solid-router/skills/solid-router/SKILL.md
  • packages/solid-start/bin/intent.js
  • packages/solid-start/skills/solid-start/SKILL.md
  • packages/start-client-core/bin/intent.js
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/start-server-core/bin/intent.js
  • packages/start-server-core/skills/start-server-core/SKILL.md
  • packages/virtual-file-routes/bin/intent.js
  • packages/vue-router/bin/intent.js
  • packages/vue-router/eslint.config.ts
  • packages/vue-router/skills/vue-router/SKILL.md
  • packages/vue-start/bin/intent.js
  • packages/vue-start/eslint.config.ts
  • packages/vue-start/skills/vue-start/SKILL.md
✅ Files skipped from review due to trivial changes (2)
  • packages/router-core/skills/router-core/search-params/SKILL.md
  • packages/router-core/skills/router-core/not-found-and-errors/SKILL.md
🚧 Files skipped from review as they are similar to previous changes (14)
  • packages/vue-start/bin/intent.js
  • packages/solid-start/bin/intent.js
  • packages/router-core/bin/intent.js
  • packages/start-client-core/skills/start-core/server-functions/SKILL.md
  • packages/solid-router/bin/intent.js
  • packages/router-core/skills/router-core/navigation/SKILL.md
  • packages/router-plugin/skills/router-plugin/SKILL.md
  • packages/start-client-core/skills/start-core/server-routes/SKILL.md
  • packages/react-router/bin/intent.js
  • packages/start-server-core/bin/intent.js
  • packages/start-server-core/skills/start-server-core/SKILL.md
  • packages/react-start/bin/intent.js
  • packages/virtual-file-routes/bin/intent.js
  • packages/react-router/skills/lifecycle/migrate-from-react-router/SKILL.md


## Cross-References

- See also: **router-core/data-loading/SKILL.md** — `beforeLoad` runs before `loader`; auth context flows into loader via route context
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Use a proper internal docs link format for the cross-reference.

Line 458 is plain text and not using the internal docs-link style. Convert it to a relative docs link format.

Suggested doc link fix
-- See also: **router-core/data-loading/SKILL.md** — `beforeLoad` runs before `loader`; auth context flows into loader via route context
+- See also: [./guide/data-loading](./guide/data-loading) — `beforeLoad` runs before `loader`; auth context flows into loader via route context

As per coding guidelines, **/*.md: Use internal docs links relative to docs/ folder (e.g., ./guide/data-loading).

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/router-core/skills/router-core/auth-and-guards/SKILL.md` at line
458, Replace the plain-text cross-reference "See also:
**router-core/data-loading/SKILL.md** — `beforeLoad` runs before `loader`; auth
context flows into loader via route context" with the internal docs-link style
used elsewhere (relative to the docs/ folder), e.g. convert to a relative docs
link (like ./router-core/data-loading) while preserving the explanatory text and
inline code references (`beforeLoad`, `loader`, "route context"); update the
SKILL.md line that contains that sentence to use the docs link syntax instead of
the literal .md filename.

Comment on lines +5 to +7
## Zod with `@tanstack/zod-adapter`

Zod v3 does not implement Standard Schema, so the `@tanstack/zod-adapter` wrapper is required. Always use `fallback()` from the adapter instead of zod's `.catch()`. Always wrap with `zodValidator()`.
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

Does Zod v3 support Standard Schema, or is the @tanstack/zod-adapter required for TanStack Router?

💡 Result:

Zod v3 does support Standard Schema, but only starting in Zod v3.24.0+ (earlier v3 releases do not). [1]

TanStack Router’s validateSearch can accept Standard Schema-compatible schemas directly, so with Zod >= 3.24.0 you can typically pass your Zod schema without an adapter. [2]

That said, TanStack Router’s docs still recommend @tanstack/zod-adapter (e.g. zodValidator, fallback) because it provides Zod-specific conveniences beyond the bare Standard Schema interface. [3]

Sources: [1] [2] [3]


Update documentation to reflect accurate Zod v3 Standard Schema support.

The statement "Zod v3 does not implement Standard Schema" is inaccurate. Zod v3.24.0 and later do support Standard Schema. While the @tanstack/zod-adapter remains recommended for Zod-specific conveniences like fallback(), it is not strictly required for Zod >= 3.24.0. The documentation should clarify this distinction and, if targeting a minimum version, explicitly state which Zod v3 versions require the adapter.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@packages/router-core/skills/router-core/search-params/references/validation-patterns.md`
around lines 5 - 7, The doc incorrectly states "Zod v3 does not implement
Standard Schema"; update the text in validation-patterns.md to note that Zod
v3.24.0+ does implement Standard Schema, and clarify that `@tanstack/zod-adapter`
is recommended (for conveniences like fallback()) but not strictly required for
Zod >= 3.24.0; also state which minimum Zod versions require the adapter if you
intend to target older Zod releases, and keep the guidance to prefer adapter's
fallback() over zod's .catch() and to wrap validators with zodValidator() for
consistency.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants