From 45bbfa44090c6a7bd67b8a2a1440e369720edd21 Mon Sep 17 00:00:00 2001 From: Carlos Martin Sanchez Date: Sun, 3 May 2026 00:29:15 +0200 Subject: [PATCH 1/3] Please provide the file changes or a description of the code modifications so I can generate the commit message for you. --- ...k-promptable-fullstack-app-template.skill.yaml} | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) rename skills/src/{tanstack-fullstack-pattern.skill.yaml => tanstack-promptable-fullstack-app-template.skill.yaml} (95%) diff --git a/skills/src/tanstack-fullstack-pattern.skill.yaml b/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml similarity index 95% rename from skills/src/tanstack-fullstack-pattern.skill.yaml rename to skills/src/tanstack-promptable-fullstack-app-template.skill.yaml index 99709a4..4a8d203 100644 --- a/skills/src/tanstack-fullstack-pattern.skill.yaml +++ b/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml @@ -1,5 +1,5 @@ -id: tanstack-fullstack-pattern -title: TanStack Fullstack Pattern +id: tanstack-promptable-fullstack-app-template +title: TanStack Promptable Fullstack App Template summary: >- Use when scaffolding a new TanStack Start project, adding domain entities to the fullstack template, or implementing the interface-first repository pattern @@ -65,6 +65,7 @@ capabilities: recommended-prompt list - Parent layout routes that centralize beforeLoad guards and shared loader data for nested child routes + - Dynamic route schema extraction for AI tool-calling and context awareness triggers: - fullstack template - TanStack Start project @@ -106,7 +107,8 @@ constraints: - Shared route gates and expensive reads are implemented on the parent layout route (beforeLoad + loader); child routes avoid duplicating the same work - TanStack Router, Start, Query, Table, and AI guidance follows the official - docs surfaced via npx @tanstack/cli, not memorized APIs + docs. Always leverage the CLI via `npx @tanstack/cli --help` to check the current docs, rather than relying on memorized APIs. + - Actively ask the skill user for clarifications when needed, especially when making choices about movable pieces or architectural decisions. - Every enum-ish field exposes a distinct-values AI tool so the assistant grounds filter arguments in real data - Router configures defaultStaleTime, defaultPreload, defaultPreloadStaleTime, @@ -166,7 +168,7 @@ content: | 8. URL-as-state: filters, tabs, selections live in URL search params via `validateSearch` (Zod/ArkType). Use `loaderDeps` to feed validated search into loaders. 9. Middleware chain: auth is global middleware, invalidation runs on mutation server functions. 10. Mutation pattern: POST server functions chain `.middleware([requireAuthMiddleware, invalidateMiddleware])`, return domain data or throw `HttpError`. Callers normalize errors: UI via `processResponse()`, AI tools via `safeToolHandler()` / `createSafeServerTool()`. - 11. Query pattern: GET server functions throw on failure for centralized error handling. + 11. Query pattern: GET server functions throw on failure for centralized error handling. When possible, use static server functions for performance improvements. 12. Maximize AI tool coverage: expose **every** repository method (reads and writes) via `createSafeServerTool()` so failures return `{ error, code }`. If a server function exists, it gets a tool. 13. Router capabilities as AI client tools: expose `router.navigate()` and `router.invalidate()` as client tools via `toolDefinition()`. 14. AI system prompt context: `buildSystemPrompt()` injects three context blocks into every AI chat request. (a) **Current User** — name, email, role from the auth middleware context (server-side; no client round-trip needed). (b) **Browser Context** — timezone, locale, and current date/time from `browserContext` sent by `ChatDrawer` (client-side). (c) **Current Location** — pathname, search params, and full URL from `browserContext`; route patterns (e.g. `/tasks/$taskId`) are matched to resolve dynamic segments. The navigation manifest mirrors `routeTree.gen.ts` and lists each route's search params. When adding routes, update `navigationManifest.ts` and add pattern-matching in `buildSystemPrompt()` for new dynamic segments. @@ -299,6 +301,10 @@ content: | `buildSystemPrompt()` composes `BASE_SYSTEM_PROMPT` (rule 25) + navigation manifest + dynamic context (rule 14). When modifying: add tools to the array, update `BASE_SYSTEM_PROMPT` when the data model changes, add pattern-matching for new dynamic route segments. See AGENTS.md section 8 "System Prompt Generation" for the six-section prompt template. + ## Dynamic Route Schema Extraction for AI + + To help the AI navigate accurately using client tools, dynamically extract your TanStack Router configuration from `router.flatRoutes`. Map this array to extract `fullPath`, `staticData.description` (for page context), path params (from segments starting with `$`), and search params (by inspecting `validateSearch` keys). Passing this structured map in the system prompt allows the AI to discover available routes and required parameters without hallucinating URLs. + ## Verification Testing setup (Vitest, Playwright, auth fixtures) and the full validation checklist are in [AGENTS.md](https://github.com/carlosvin/tanstack-fullstack-ai-template/blob/main/AGENTS.md) sections 10 and 12. Quick smoke test: `pnpm format && pnpm lint && pnpm test && pnpm build`. From de6825097469ada240dd8f5e8e97dd6e57692ed6 Mon Sep 17 00:00:00 2001 From: Carlos Martin Sanchez Date: Sun, 3 May 2026 00:33:33 +0200 Subject: [PATCH 2/3] docs: prioritize React Server Components by default and update Link wrapper documentation to include styling requirements --- AGENTS.md | 1 + .../tanstack-promptable-fullstack-app-template.skill.yaml | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index d37c799..a516802 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -90,6 +90,7 @@ If your team prefers [`@tabler/icons-react`](https://tabler.io/icons) (the Manti ## 4. TypeScript and React +- **Server Components by Default**: TanStack Start supports React Server Components. Rely on Server Components by default. Reduce the usage of `"use client"` directives. Only use `"use client"` at the top of files when React hooks (`useState`, `useEffect`) or browser APIs are strictly necessary. Keep client components as small and leaf-level as possible. - **Functional Components**: Prefer functional components and hooks over class components. - **Type Safety**: Use TypeScript features like interfaces, types, and generics effectively. - **Zod-First Types**: All domain types are defined as Zod schemas and TypeScript types are inferred via `z.infer<>`. Tools-layer schemas live in `src/services/schemas/schemas.ts` (with `.describe()` on every field for AI JSON Schema); repository-layer schemas live in `repository.ts`. See the [skill](.agents/skills/tanstack-fullstack-pattern/SKILL.md) for the three schema layers, `loaderDeps`, and cross-layer `Schema.parse()` mapping. diff --git a/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml b/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml index 4a8d203..492eb6e 100644 --- a/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml +++ b/skills/src/tanstack-promptable-fullstack-app-template.skill.yaml @@ -103,7 +103,7 @@ constraints: - Non-secret runtime config is exposed via a GET server function and inlined into the document as window.__ENV__ before client JS runs - Internal navigation uses a project-local Link wrapper that preserves search - params by default + params by default and renders using the chosen component library's elements - Shared route gates and expensive reads are implemented on the parent layout route (beforeLoad + loader); child routes avoid duplicating the same work - TanStack Router, Start, Query, Table, and AI guidance follows the official @@ -113,6 +113,7 @@ constraints: grounds filter arguments in real data - Router configures defaultStaleTime, defaultPreload, defaultPreloadStaleTime, scrollRestoration, and a root notFoundComponent + - Reduce the usage of "use client". Rely on Server Components by default. Only use "use client" when state, effects, or browser APIs are strictly necessary. steps: - Define schemas as source of truth and infer types - "Split schemas by layer: repository input/output schemas and tool-facing @@ -188,11 +189,12 @@ content: | 29. Explicit agent loop depth: configure `agentLoopStrategy: maxIterations(N)` explicitly on the `chat()` call (default N=10). This caps the number of consecutive tool-calling iterations the AI can run before returning a final answer, which bounds latency, cost, and infinite-loop risk. Tune N only after measuring; do not rely on the framework default. 30. Public runtime config bridge: expose non-secret runtime config (Sentry DSN, environment name, feature flags) via a GET server function `getPublicEnv()` and inline the result as `window.__ENV__` in the root `RootDocument` using a small `