@smicolon/ai-kit 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (162) hide show
  1. package/.claude-plugin/CLAUDE.md +7 -0
  2. package/.claude-plugin/marketplace.json +373 -0
  3. package/package.json +4 -3
  4. package/packs/architect/CHANGELOG.md +17 -0
  5. package/packs/architect/README.md +58 -0
  6. package/packs/architect/agents/system-architect.md +768 -0
  7. package/packs/architect/commands/diagram-create.md +300 -0
  8. package/packs/better-auth/.claude-plugin/plugin.json +14 -0
  9. package/packs/better-auth/.mcp.json +14 -0
  10. package/packs/better-auth/CHANGELOG.md +26 -0
  11. package/packs/better-auth/README.md +125 -0
  12. package/packs/better-auth/agents/auth-architect.md +278 -0
  13. package/packs/better-auth/commands/auth-provider-add.md +265 -0
  14. package/packs/better-auth/commands/auth-setup.md +298 -0
  15. package/packs/better-auth/skills/auth-security/SKILL.md +425 -0
  16. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +455 -0
  17. package/packs/dev-loop/.claude-plugin/plugin.json +10 -0
  18. package/packs/dev-loop/CHANGELOG.md +69 -0
  19. package/packs/dev-loop/README.md +155 -0
  20. package/packs/dev-loop/commands/cancel-dev.md +21 -0
  21. package/packs/dev-loop/commands/dev-loop.md +72 -0
  22. package/packs/dev-loop/commands/dev-plan.md +351 -0
  23. package/packs/dev-loop/hooks/hooks.json +15 -0
  24. package/packs/dev-loop/hooks/stop-hook.sh +178 -0
  25. package/packs/dev-loop/scripts/setup-dev-loop.sh +194 -0
  26. package/packs/dev-loop/skills/tdd-planner/SKILL.md +249 -0
  27. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +874 -0
  28. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +260 -0
  29. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +275 -0
  30. package/packs/django/CHANGELOG.md +39 -0
  31. package/packs/django/README.md +92 -0
  32. package/packs/django/agents/django-architect.md +182 -0
  33. package/packs/django/agents/django-builder.md +250 -0
  34. package/packs/django/agents/django-feature-based.md +420 -0
  35. package/packs/django/agents/django-reviewer.md +253 -0
  36. package/packs/django/agents/django-tester.md +230 -0
  37. package/packs/django/commands/api-endpoint.md +285 -0
  38. package/packs/django/commands/model-create.md +178 -0
  39. package/packs/django/commands/test-generate.md +325 -0
  40. package/packs/django/rules/migrations.md +138 -0
  41. package/packs/django/rules/models.md +167 -0
  42. package/packs/django/rules/serializers.md +126 -0
  43. package/packs/django/rules/services.md +131 -0
  44. package/packs/django/rules/tests.md +140 -0
  45. package/packs/django/rules/views.md +102 -0
  46. package/packs/django/skills/import-convention-enforcer/SKILL.md +226 -0
  47. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +343 -0
  48. package/packs/django/skills/migration-safety-checker/SKILL.md +375 -0
  49. package/packs/django/skills/model-entity-validator/SKILL.md +298 -0
  50. package/packs/django/skills/performance-optimizer/SKILL.md +447 -0
  51. package/packs/django/skills/red-phase-verifier/SKILL.md +180 -0
  52. package/packs/django/skills/security-first-validator/SKILL.md +435 -0
  53. package/packs/django/skills/test-coverage-advisor/SKILL.md +394 -0
  54. package/packs/django/skills/test-validity-checker/SKILL.md +194 -0
  55. package/packs/failure-log/.claude-plugin/plugin.json +14 -0
  56. package/packs/failure-log/CHANGELOG.md +20 -0
  57. package/packs/failure-log/README.md +168 -0
  58. package/packs/failure-log/commands/failure-add.md +106 -0
  59. package/packs/failure-log/commands/failure-list.md +89 -0
  60. package/packs/failure-log/hooks/hooks.json +16 -0
  61. package/packs/failure-log/hooks/scripts/inject-failures.sh +64 -0
  62. package/packs/failure-log/skills/failure-log-manager/SKILL.md +164 -0
  63. package/packs/flutter/.claude-plugin/plugin.json +10 -0
  64. package/packs/flutter/CHANGELOG.md +19 -0
  65. package/packs/flutter/README.md +170 -0
  66. package/packs/flutter/agents/flutter-architect.md +166 -0
  67. package/packs/flutter/agents/flutter-builder.md +303 -0
  68. package/packs/flutter/agents/release-manager.md +355 -0
  69. package/packs/flutter/commands/fastlane-setup.md +188 -0
  70. package/packs/flutter/commands/flutter-build.md +90 -0
  71. package/packs/flutter/commands/flutter-deploy.md +133 -0
  72. package/packs/flutter/commands/flutter-test.md +117 -0
  73. package/packs/flutter/commands/signing-setup.md +209 -0
  74. package/packs/flutter/hooks/hooks.json +17 -0
  75. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +193 -0
  76. package/packs/flutter/skills/flutter-architecture/SKILL.md +127 -0
  77. package/packs/flutter/skills/store-publishing/SKILL.md +163 -0
  78. package/packs/hono/.claude-plugin/plugin.json +19 -0
  79. package/packs/hono/CHANGELOG.md +19 -0
  80. package/packs/hono/README.md +143 -0
  81. package/packs/hono/agents/hono-architect.md +240 -0
  82. package/packs/hono/agents/hono-builder.md +285 -0
  83. package/packs/hono/agents/hono-reviewer.md +279 -0
  84. package/packs/hono/agents/hono-tester.md +346 -0
  85. package/packs/hono/commands/middleware-create.md +223 -0
  86. package/packs/hono/commands/project-init.md +306 -0
  87. package/packs/hono/commands/route-create.md +153 -0
  88. package/packs/hono/commands/rpc-client.md +263 -0
  89. package/packs/hono/hooks/hooks.json +4 -0
  90. package/packs/hono/skills/cloudflare-bindings/SKILL.md +408 -0
  91. package/packs/hono/skills/hono-patterns/SKILL.md +309 -0
  92. package/packs/hono/skills/rpc-typesafe/SKILL.md +388 -0
  93. package/packs/hono/skills/zod-validation/SKILL.md +332 -0
  94. package/packs/nestjs/CHANGELOG.md +29 -0
  95. package/packs/nestjs/README.md +75 -0
  96. package/packs/nestjs/agents/nestjs-architect.md +402 -0
  97. package/packs/nestjs/agents/nestjs-builder.md +301 -0
  98. package/packs/nestjs/agents/nestjs-tester.md +437 -0
  99. package/packs/nestjs/commands/module-create.md +369 -0
  100. package/packs/nestjs/rules/controllers.md +92 -0
  101. package/packs/nestjs/rules/dto.md +124 -0
  102. package/packs/nestjs/rules/entities.md +102 -0
  103. package/packs/nestjs/rules/services.md +106 -0
  104. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +389 -0
  105. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +365 -0
  106. package/packs/nextjs/CHANGELOG.md +36 -0
  107. package/packs/nextjs/README.md +76 -0
  108. package/packs/nextjs/agents/frontend-tester.md +680 -0
  109. package/packs/nextjs/agents/frontend-visual.md +820 -0
  110. package/packs/nextjs/agents/nextjs-architect.md +331 -0
  111. package/packs/nextjs/agents/nextjs-modular.md +433 -0
  112. package/packs/nextjs/commands/component-create.md +398 -0
  113. package/packs/nextjs/rules/api-routes.md +129 -0
  114. package/packs/nextjs/rules/components.md +106 -0
  115. package/packs/nextjs/rules/hooks.md +132 -0
  116. package/packs/nextjs/skills/accessibility-validator/SKILL.md +445 -0
  117. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +399 -0
  118. package/packs/nextjs/skills/react-form-validator/SKILL.md +569 -0
  119. package/packs/nuxtjs/CHANGELOG.md +30 -0
  120. package/packs/nuxtjs/README.md +56 -0
  121. package/packs/nuxtjs/agents/frontend-tester.md +680 -0
  122. package/packs/nuxtjs/agents/frontend-visual.md +820 -0
  123. package/packs/nuxtjs/agents/nuxtjs-architect.md +537 -0
  124. package/packs/nuxtjs/commands/component-create.md +223 -0
  125. package/packs/nuxtjs/rules/components.md +101 -0
  126. package/packs/nuxtjs/rules/composables.md +118 -0
  127. package/packs/nuxtjs/rules/server-routes.md +127 -0
  128. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +183 -0
  129. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +196 -0
  130. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +190 -0
  131. package/packs/onboard/CHANGELOG.md +22 -0
  132. package/packs/onboard/README.md +103 -0
  133. package/packs/onboard/agents/onboard-guide.md +118 -0
  134. package/packs/onboard/commands/onboard.md +313 -0
  135. package/packs/onboard/skills/onboard-context-provider/SKILL.md +98 -0
  136. package/packs/tanstack-router/.claude-plugin/plugin.json +14 -0
  137. package/packs/tanstack-router/CHANGELOG.md +30 -0
  138. package/packs/tanstack-router/README.md +113 -0
  139. package/packs/tanstack-router/agents/tanstack-architect.md +173 -0
  140. package/packs/tanstack-router/agents/tanstack-builder.md +360 -0
  141. package/packs/tanstack-router/agents/tanstack-tester.md +454 -0
  142. package/packs/tanstack-router/commands/form-create.md +313 -0
  143. package/packs/tanstack-router/commands/query-create.md +263 -0
  144. package/packs/tanstack-router/commands/route-create.md +190 -0
  145. package/packs/tanstack-router/commands/table-create.md +413 -0
  146. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +370 -0
  147. package/packs/tanstack-router/skills/db-patterns/SKILL.md +346 -0
  148. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +415 -0
  149. package/packs/tanstack-router/skills/form-patterns/SKILL.md +425 -0
  150. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +341 -0
  151. package/packs/tanstack-router/skills/query-patterns/SKILL.md +359 -0
  152. package/packs/tanstack-router/skills/router-patterns/SKILL.md +285 -0
  153. package/packs/tanstack-router/skills/store-patterns/SKILL.md +351 -0
  154. package/packs/tanstack-router/skills/table-patterns/SKILL.md +531 -0
  155. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +428 -0
  156. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +490 -0
  157. package/packs/worktree/.claude-plugin/plugin.json +19 -0
  158. package/packs/worktree/CHANGELOG.md +24 -0
  159. package/packs/worktree/README.md +110 -0
  160. package/packs/worktree/commands/wt.md +73 -0
  161. package/packs/worktree/scripts/wt.sh +396 -0
  162. package/packs/worktree/skills/worktree-manager/SKILL.md +68 -0
@@ -0,0 +1,190 @@
1
+ ---
2
+ name: route-create
3
+ description: Create TanStack Router routes with proper file structure and conventions
4
+ args:
5
+ - name: path
6
+ description: Route path (e.g., /posts, /posts/$postId, /users/$userId/settings)
7
+ required: false
8
+ - name: type
9
+ description: Route type (page, layout, pathless, index)
10
+ required: false
11
+ ---
12
+
13
+ # Create TanStack Router Route
14
+
15
+ Create a new route following TanStack Router file-based conventions.
16
+
17
+ ## Instructions
18
+
19
+ 1. **Gather Route Information** (if not provided via args):
20
+ - Ask for the route path (e.g., `/posts/$postId`)
21
+ - Ask for the route type: page, layout, pathless layout, or index
22
+ - Ask if the route needs data loading (loader)
23
+ - Ask if the route needs search params validation
24
+
25
+ 2. **Determine File Name**:
26
+ Convert the path to TanStack Router file naming convention:
27
+ - `/posts` → `posts.tsx` (layout) or `posts.index.tsx` (index)
28
+ - `/posts/$postId` → `posts.$postId.tsx`
29
+ - `/posts/$postId/edit` → `posts_.$postId.edit.tsx`
30
+ - Pathless layout → `_auth.tsx` (prefix with `_`)
31
+
32
+ 3. **Create Route File** in `src/routes/`:
33
+
34
+ For a **page route with loader**:
35
+ ```typescript
36
+ import { createFileRoute } from '@tanstack/react-router'
37
+ import { {Feature}QueryOptions } from '@/features/{feature}/queries'
38
+ import { {Component} } from '@/features/{feature}/components'
39
+
40
+ export const Route = createFileRoute('{path}')({
41
+ loader: ({ context: { queryClient }, params }) =>
42
+ queryClient.ensureQueryData({feature}QueryOptions(params.{param})),
43
+ component: {Component}Page,
44
+ })
45
+
46
+ function {Component}Page() {
47
+ const data = Route.useLoaderData()
48
+ const params = Route.useParams()
49
+
50
+ return <{Component} data={data} />
51
+ }
52
+ ```
53
+
54
+ For a **route with search params**:
55
+ ```typescript
56
+ import { createFileRoute } from '@tanstack/react-router'
57
+ import { z } from 'zod'
58
+
59
+ const searchSchema = z.object({
60
+ page: z.number().default(1),
61
+ sort: z.enum(['newest', 'oldest']).default('newest'),
62
+ search: z.string().optional(),
63
+ })
64
+
65
+ export const Route = createFileRoute('{path}')({
66
+ validateSearch: searchSchema,
67
+ component: {Component}Page,
68
+ })
69
+
70
+ function {Component}Page() {
71
+ const { page, sort, search } = Route.useSearch()
72
+ const navigate = Route.useNavigate()
73
+
74
+ // Update search params
75
+ const setPage = (newPage: number) => {
76
+ navigate({ search: (prev) => ({ ...prev, page: newPage }) })
77
+ }
78
+
79
+ return <{Component} page={page} sort={sort} search={search} onPageChange={setPage} />
80
+ }
81
+ ```
82
+
83
+ For a **layout route**:
84
+ ```typescript
85
+ import { createFileRoute, Outlet } from '@tanstack/react-router'
86
+
87
+ export const Route = createFileRoute('{path}')({
88
+ component: {Feature}Layout,
89
+ })
90
+
91
+ function {Feature}Layout() {
92
+ return (
93
+ <div className="{feature}-layout">
94
+ <nav>{/* Feature navigation */}</nav>
95
+ <main>
96
+ <Outlet />
97
+ </main>
98
+ </div>
99
+ )
100
+ }
101
+ ```
102
+
103
+ For a **pathless layout** (e.g., auth guard):
104
+ ```typescript
105
+ import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'
106
+
107
+ export const Route = createFileRoute('/_auth')({
108
+ beforeLoad: async ({ context }) => {
109
+ if (!context.user) {
110
+ throw redirect({ to: '/login' })
111
+ }
112
+ },
113
+ component: AuthLayout,
114
+ })
115
+
116
+ function AuthLayout() {
117
+ return <Outlet />
118
+ }
119
+ ```
120
+
121
+ 4. **Add Error and Loading States** (if data loading):
122
+ ```typescript
123
+ export const Route = createFileRoute('{path}')({
124
+ loader: ...,
125
+ pendingComponent: () => <{Component}Skeleton />,
126
+ errorComponent: ({ error }) => (
127
+ <div className="error">
128
+ <h2>Error loading {feature}</h2>
129
+ <p>{error.message}</p>
130
+ </div>
131
+ ),
132
+ component: {Component}Page,
133
+ })
134
+ ```
135
+
136
+ 5. **Create Query Options** (if needed) in `src/features/{feature}/queries/`:
137
+ ```typescript
138
+ import { queryOptions } from '@tanstack/react-query'
139
+ import { queryKeys } from '@/lib/query-keys'
140
+ import { {feature}Api } from '@/features/{feature}/api'
141
+
142
+ export const {feature}QueryOptions = (id: string) =>
143
+ queryOptions({
144
+ queryKey: queryKeys.{feature}.detail(id),
145
+ queryFn: () => {feature}Api.get{Feature}(id),
146
+ staleTime: 5 * 60 * 1000,
147
+ })
148
+ ```
149
+
150
+ 6. **Update Query Keys** (if new feature) in `src/lib/query-keys.ts`:
151
+ ```typescript
152
+ export const queryKeys = {
153
+ // existing keys...
154
+ {feature}: {
155
+ all: () => ['{feature}'] as const,
156
+ lists: () => [...queryKeys.{feature}.all(), 'list'] as const,
157
+ list: (filters: {Feature}Filters) => [...queryKeys.{feature}.lists(), filters] as const,
158
+ details: () => [...queryKeys.{feature}.all(), 'detail'] as const,
159
+ detail: (id: string) => [...queryKeys.{feature}.details(), id] as const,
160
+ },
161
+ } as const
162
+ ```
163
+
164
+ 7. **Regenerate Route Tree**:
165
+ ```bash
166
+ bun run routes:generate
167
+ ```
168
+
169
+ ## File Naming Quick Reference
170
+
171
+ | URL Path | File Name |
172
+ |----------|-----------|
173
+ | `/` | `index.tsx` |
174
+ | `/about` | `about.tsx` |
175
+ | `/posts` (layout) | `posts.tsx` |
176
+ | `/posts` (page) | `posts.index.tsx` |
177
+ | `/posts/$postId` | `posts.$postId.tsx` |
178
+ | `/posts/$postId/edit` | `posts_.$postId.edit.tsx` |
179
+ | Auth wrapper | `_auth.tsx` |
180
+ | Catch-all | `$.tsx` |
181
+
182
+ ## Quality Checklist
183
+
184
+ - [ ] File name follows TanStack Router conventions
185
+ - [ ] Route uses `createFileRoute` with correct path
186
+ - [ ] Loader uses `ensureQueryData` (not direct fetch)
187
+ - [ ] Search params validated with Zod schema
188
+ - [ ] Error and pending components provided for data routes
189
+ - [ ] Component uses `Route.useParams()` and `Route.useLoaderData()`
190
+ - [ ] Route tree regenerated after creation
@@ -0,0 +1,413 @@
1
+ ---
2
+ name: table-create
3
+ description: Create TanStack Table components with sorting, filtering, and pagination
4
+ args:
5
+ - name: name
6
+ description: Table name (e.g., PostsTable, UsersTable)
7
+ required: false
8
+ - name: feature
9
+ description: Feature the table belongs to (e.g., posts, users)
10
+ required: false
11
+ ---
12
+
13
+ # Create TanStack Table
14
+
15
+ Create a data table component with TanStack Table, including sorting, filtering, and pagination.
16
+
17
+ ## Instructions
18
+
19
+ 1. **Gather Information** (if not provided via args):
20
+ - Ask for the table name (e.g., `PostsTable`)
21
+ - Ask for the feature it belongs to
22
+ - Ask what columns to include
23
+ - Ask what features to enable: sorting, filtering, pagination, row selection
24
+
25
+ 2. **Create Column Definitions** in `src/features/{feature}/components/{Name}Columns.tsx`:
26
+ ```typescript
27
+ import { createColumnHelper } from '@tanstack/react-table'
28
+ import { Link } from '@tanstack/react-router'
29
+ import type { {Feature} } from '../types'
30
+
31
+ const columnHelper = createColumnHelper<{Feature}>()
32
+
33
+ export const {name}Columns = [
34
+ columnHelper.accessor('title', {
35
+ header: ({ column }) => (
36
+ <button
37
+ onClick={() => column.toggleSorting()}
38
+ className="flex items-center gap-1"
39
+ >
40
+ Title
41
+ {column.getIsSorted() === 'asc' && ' ↑'}
42
+ {column.getIsSorted() === 'desc' && ' ↓'}
43
+ </button>
44
+ ),
45
+ cell: (info) => (
46
+ <Link
47
+ to="/{feature}/$id"
48
+ params={{ id: info.row.original.id }}
49
+ className="hover:underline"
50
+ >
51
+ {info.getValue()}
52
+ </Link>
53
+ ),
54
+ }),
55
+
56
+ columnHelper.accessor('status', {
57
+ header: 'Status',
58
+ cell: (info) => (
59
+ <span className={`badge badge-${info.getValue()}`}>
60
+ {info.getValue()}
61
+ </span>
62
+ ),
63
+ filterFn: 'equals',
64
+ }),
65
+
66
+ columnHelper.accessor('createdAt', {
67
+ header: 'Created',
68
+ cell: (info) => new Date(info.getValue()).toLocaleDateString(),
69
+ sortingFn: 'datetime',
70
+ }),
71
+
72
+ columnHelper.display({
73
+ id: 'actions',
74
+ header: 'Actions',
75
+ cell: ({ row }) => (
76
+ <div className="flex gap-2">
77
+ <Link to="/{feature}/$id/edit" params={{ id: row.original.id }}>
78
+ Edit
79
+ </Link>
80
+ <button onClick={() => handleDelete(row.original.id)}>
81
+ Delete
82
+ </button>
83
+ </div>
84
+ ),
85
+ }),
86
+ ]
87
+ ```
88
+
89
+ 3. **Create Table Component** in `src/features/{feature}/components/{Name}Table.tsx`:
90
+
91
+ For a **basic table**:
92
+ ```typescript
93
+ import {
94
+ useReactTable,
95
+ getCoreRowModel,
96
+ flexRender,
97
+ } from '@tanstack/react-table'
98
+ import { {name}Columns } from './{Name}Columns'
99
+ import type { {Feature} } from '../types'
100
+
101
+ interface {Name}TableProps {
102
+ data: {Feature}[]
103
+ }
104
+
105
+ export function {Name}Table({ data }: {Name}TableProps) {
106
+ const table = useReactTable({
107
+ data,
108
+ columns: {name}Columns,
109
+ getCoreRowModel: getCoreRowModel(),
110
+ })
111
+
112
+ return (
113
+ <table className="w-full">
114
+ <thead>
115
+ {table.getHeaderGroups().map((headerGroup) => (
116
+ <tr key={headerGroup.id}>
117
+ {headerGroup.headers.map((header) => (
118
+ <th key={header.id} className="text-left p-2">
119
+ {header.isPlaceholder
120
+ ? null
121
+ : flexRender(
122
+ header.column.columnDef.header,
123
+ header.getContext()
124
+ )}
125
+ </th>
126
+ ))}
127
+ </tr>
128
+ ))}
129
+ </thead>
130
+ <tbody>
131
+ {table.getRowModel().rows.map((row) => (
132
+ <tr key={row.id} className="border-t">
133
+ {row.getVisibleCells().map((cell) => (
134
+ <td key={cell.id} className="p-2">
135
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
136
+ </td>
137
+ ))}
138
+ </tr>
139
+ ))}
140
+ </tbody>
141
+ </table>
142
+ )
143
+ }
144
+ ```
145
+
146
+ For a **full-featured table** with sorting, filtering, pagination:
147
+ ```typescript
148
+ import { useState } from 'react'
149
+ import {
150
+ useReactTable,
151
+ getCoreRowModel,
152
+ getSortedRowModel,
153
+ getFilteredRowModel,
154
+ getPaginationRowModel,
155
+ flexRender,
156
+ type SortingState,
157
+ type ColumnFiltersState,
158
+ } from '@tanstack/react-table'
159
+ import { {name}Columns } from './{Name}Columns'
160
+ import type { {Feature} } from '../types'
161
+
162
+ interface {Name}TableProps {
163
+ data: {Feature}[]
164
+ }
165
+
166
+ export function {Name}Table({ data }: {Name}TableProps) {
167
+ const [sorting, setSorting] = useState<SortingState>([])
168
+ const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
169
+ const [globalFilter, setGlobalFilter] = useState('')
170
+
171
+ const table = useReactTable({
172
+ data,
173
+ columns: {name}Columns,
174
+ state: {
175
+ sorting,
176
+ columnFilters,
177
+ globalFilter,
178
+ },
179
+ onSortingChange: setSorting,
180
+ onColumnFiltersChange: setColumnFilters,
181
+ onGlobalFilterChange: setGlobalFilter,
182
+ getCoreRowModel: getCoreRowModel(),
183
+ getSortedRowModel: getSortedRowModel(),
184
+ getFilteredRowModel: getFilteredRowModel(),
185
+ getPaginationRowModel: getPaginationRowModel(),
186
+ initialState: {
187
+ pagination: { pageSize: 10 },
188
+ },
189
+ })
190
+
191
+ return (
192
+ <div className="space-y-4">
193
+ {/* Search */}
194
+ <input
195
+ type="search"
196
+ placeholder="Search..."
197
+ value={globalFilter}
198
+ onChange={(e) => setGlobalFilter(e.target.value)}
199
+ className="input"
200
+ />
201
+
202
+ {/* Column Filters */}
203
+ <div className="flex gap-4">
204
+ <select
205
+ value={(table.getColumn('status')?.getFilterValue() as string) ?? ''}
206
+ onChange={(e) =>
207
+ table.getColumn('status')?.setFilterValue(e.target.value || undefined)
208
+ }
209
+ >
210
+ <option value="">All statuses</option>
211
+ <option value="draft">Draft</option>
212
+ <option value="published">Published</option>
213
+ </select>
214
+ </div>
215
+
216
+ {/* Table */}
217
+ <table className="w-full">
218
+ <thead>
219
+ {table.getHeaderGroups().map((headerGroup) => (
220
+ <tr key={headerGroup.id}>
221
+ {headerGroup.headers.map((header) => (
222
+ <th key={header.id} className="text-left p-2">
223
+ {header.isPlaceholder
224
+ ? null
225
+ : flexRender(
226
+ header.column.columnDef.header,
227
+ header.getContext()
228
+ )}
229
+ </th>
230
+ ))}
231
+ </tr>
232
+ ))}
233
+ </thead>
234
+ <tbody>
235
+ {table.getRowModel().rows.length === 0 ? (
236
+ <tr>
237
+ <td colSpan={table.getAllColumns().length} className="text-center p-4">
238
+ No results found
239
+ </td>
240
+ </tr>
241
+ ) : (
242
+ table.getRowModel().rows.map((row) => (
243
+ <tr key={row.id} className="border-t hover:bg-gray-50">
244
+ {row.getVisibleCells().map((cell) => (
245
+ <td key={cell.id} className="p-2">
246
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
247
+ </td>
248
+ ))}
249
+ </tr>
250
+ ))
251
+ )}
252
+ </tbody>
253
+ </table>
254
+
255
+ {/* Pagination */}
256
+ <div className="flex items-center justify-between">
257
+ <span>
258
+ Showing {table.getState().pagination.pageIndex * table.getState().pagination.pageSize + 1} to{' '}
259
+ {Math.min(
260
+ (table.getState().pagination.pageIndex + 1) * table.getState().pagination.pageSize,
261
+ table.getFilteredRowModel().rows.length
262
+ )}{' '}
263
+ of {table.getFilteredRowModel().rows.length}
264
+ </span>
265
+
266
+ <div className="flex gap-2">
267
+ <button
268
+ onClick={() => table.previousPage()}
269
+ disabled={!table.getCanPreviousPage()}
270
+ className="btn"
271
+ >
272
+ Previous
273
+ </button>
274
+ <span className="flex items-center">
275
+ Page {table.getState().pagination.pageIndex + 1} of {table.getPageCount()}
276
+ </span>
277
+ <button
278
+ onClick={() => table.nextPage()}
279
+ disabled={!table.getCanNextPage()}
280
+ className="btn"
281
+ >
282
+ Next
283
+ </button>
284
+ </div>
285
+
286
+ <select
287
+ value={table.getState().pagination.pageSize}
288
+ onChange={(e) => table.setPageSize(Number(e.target.value))}
289
+ >
290
+ {[10, 20, 50].map((size) => (
291
+ <option key={size} value={size}>
292
+ Show {size}
293
+ </option>
294
+ ))}
295
+ </select>
296
+ </div>
297
+ </div>
298
+ )
299
+ }
300
+ ```
301
+
302
+ 4. **Create Server-Side Pagination Table** (for large datasets):
303
+ ```typescript
304
+ import { Route } from '@tanstack/react-router'
305
+
306
+ export function {Name}Table() {
307
+ const { page, pageSize, sort } = Route.useSearch()
308
+ const navigate = Route.useNavigate()
309
+
310
+ const { data, isLoading } = useQuery({
311
+ queryKey: queryKeys.{feature}.list({ page, pageSize, sort }),
312
+ queryFn: () => {feature}Api.get{Feature}s({ page, pageSize, sort }),
313
+ })
314
+
315
+ const table = useReactTable({
316
+ data: data?.items ?? [],
317
+ columns: {name}Columns,
318
+ pageCount: data?.pageCount ?? -1,
319
+ state: {
320
+ pagination: { pageIndex: page - 1, pageSize },
321
+ },
322
+ onPaginationChange: (updater) => {
323
+ const newState =
324
+ typeof updater === 'function'
325
+ ? updater({ pageIndex: page - 1, pageSize })
326
+ : updater
327
+ navigate({
328
+ search: (prev) => ({
329
+ ...prev,
330
+ page: newState.pageIndex + 1,
331
+ pageSize: newState.pageSize,
332
+ }),
333
+ })
334
+ },
335
+ getCoreRowModel: getCoreRowModel(),
336
+ manualPagination: true,
337
+ })
338
+
339
+ if (isLoading) return <TableSkeleton />
340
+
341
+ return (/* Table JSX */)
342
+ }
343
+ ```
344
+
345
+ 5. **Add Row Selection** (if needed):
346
+ ```typescript
347
+ import { useState } from 'react'
348
+ import type { RowSelectionState } from '@tanstack/react-table'
349
+
350
+ export function {Name}Table({ data, onSelectionChange }: Props) {
351
+ const [rowSelection, setRowSelection] = useState<RowSelectionState>({})
352
+
353
+ // Add selection column
354
+ const columnsWithSelection = [
355
+ columnHelper.display({
356
+ id: 'select',
357
+ header: ({ table }) => (
358
+ <input
359
+ type="checkbox"
360
+ checked={table.getIsAllRowsSelected()}
361
+ onChange={table.getToggleAllRowsSelectedHandler()}
362
+ />
363
+ ),
364
+ cell: ({ row }) => (
365
+ <input
366
+ type="checkbox"
367
+ checked={row.getIsSelected()}
368
+ onChange={row.getToggleSelectedHandler()}
369
+ />
370
+ ),
371
+ }),
372
+ ...{name}Columns,
373
+ ]
374
+
375
+ const table = useReactTable({
376
+ data,
377
+ columns: columnsWithSelection,
378
+ state: { rowSelection },
379
+ onRowSelectionChange: setRowSelection,
380
+ getCoreRowModel: getCoreRowModel(),
381
+ enableRowSelection: true,
382
+ })
383
+
384
+ // Get selected rows
385
+ const selectedRows = table.getSelectedRowModel().rows.map((r) => r.original)
386
+
387
+ return (
388
+ <div>
389
+ <span>{selectedRows.length} selected</span>
390
+ {/* Table JSX */}
391
+ </div>
392
+ )
393
+ }
394
+ ```
395
+
396
+ 6. **Update Barrel Exports**:
397
+ ```typescript
398
+ // src/features/{feature}/components/index.ts
399
+ export { {Name}Table } from './{Name}Table'
400
+ export { {name}Columns } from './{Name}Columns'
401
+ ```
402
+
403
+ ## Quality Checklist
404
+
405
+ - [ ] Columns defined outside component or memoized
406
+ - [ ] All cells use `flexRender()`
407
+ - [ ] Sortable columns have toggle handler
408
+ - [ ] Empty state displayed when no data
409
+ - [ ] Pagination shows current range and total
410
+ - [ ] Row selection includes select-all checkbox
411
+ - [ ] Server pagination uses `manualPagination: true`
412
+ - [ ] Loading state shown during data fetch
413
+ - [ ] Actions column has proper key handling