@qazuor/claude-code-config 0.4.0 → 0.6.0

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 (64) hide show
  1. package/README.md +395 -50
  2. package/dist/bin.cjs +3207 -165
  3. package/dist/bin.cjs.map +1 -1
  4. package/dist/bin.js +3207 -165
  5. package/dist/bin.js.map +1 -1
  6. package/dist/index.cjs +75 -58
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +284 -1
  9. package/dist/index.d.ts +284 -1
  10. package/dist/index.js +75 -58
  11. package/dist/index.js.map +1 -1
  12. package/package.json +24 -24
  13. package/templates/CLAUDE.md.template +60 -5
  14. package/templates/agents/README.md +58 -39
  15. package/templates/agents/_registry.json +43 -202
  16. package/templates/agents/engineering/{hono-engineer.md → api-engineer.md} +61 -70
  17. package/templates/agents/engineering/database-engineer.md +253 -0
  18. package/templates/agents/engineering/frontend-engineer.md +302 -0
  19. package/templates/docs/_registry.json +54 -0
  20. package/templates/docs/standards/code-standards.md +20 -0
  21. package/templates/docs/standards/design-standards.md +13 -0
  22. package/templates/docs/standards/documentation-standards.md +13 -0
  23. package/templates/docs/standards/performance-standards.md +524 -0
  24. package/templates/docs/standards/security-standards.md +496 -0
  25. package/templates/docs/standards/testing-standards.md +15 -0
  26. package/templates/hooks/on-notification.sh +0 -0
  27. package/templates/scripts/add-changelogs.sh +0 -0
  28. package/templates/scripts/generate-code-registry.ts +0 -0
  29. package/templates/scripts/health-check.sh +0 -0
  30. package/templates/scripts/sync-registry.sh +0 -0
  31. package/templates/scripts/telemetry-report.ts +0 -0
  32. package/templates/scripts/validate-docs.sh +0 -0
  33. package/templates/scripts/validate-registry.sh +0 -0
  34. package/templates/scripts/validate-structure.sh +0 -0
  35. package/templates/scripts/worktree-cleanup.sh +0 -0
  36. package/templates/scripts/worktree-create.sh +0 -0
  37. package/templates/skills/README.md +99 -90
  38. package/templates/skills/_registry.json +323 -16
  39. package/templates/skills/api-frameworks/express-patterns.md +411 -0
  40. package/templates/skills/api-frameworks/fastify-patterns.md +419 -0
  41. package/templates/skills/api-frameworks/hono-patterns.md +388 -0
  42. package/templates/skills/api-frameworks/nestjs-patterns.md +497 -0
  43. package/templates/skills/database/drizzle-patterns.md +449 -0
  44. package/templates/skills/database/mongoose-patterns.md +503 -0
  45. package/templates/skills/database/prisma-patterns.md +487 -0
  46. package/templates/skills/frontend-frameworks/astro-patterns.md +415 -0
  47. package/templates/skills/frontend-frameworks/nextjs-patterns.md +470 -0
  48. package/templates/skills/frontend-frameworks/react-patterns.md +516 -0
  49. package/templates/skills/frontend-frameworks/tanstack-start-patterns.md +469 -0
  50. package/templates/skills/patterns/atdd-methodology.md +364 -0
  51. package/templates/skills/patterns/bdd-methodology.md +281 -0
  52. package/templates/skills/patterns/clean-architecture.md +444 -0
  53. package/templates/skills/patterns/hexagonal-architecture.md +567 -0
  54. package/templates/skills/patterns/vertical-slice-architecture.md +502 -0
  55. package/templates/agents/engineering/astro-engineer.md +0 -293
  56. package/templates/agents/engineering/db-drizzle-engineer.md +0 -360
  57. package/templates/agents/engineering/express-engineer.md +0 -316
  58. package/templates/agents/engineering/fastify-engineer.md +0 -399
  59. package/templates/agents/engineering/mongoose-engineer.md +0 -473
  60. package/templates/agents/engineering/nestjs-engineer.md +0 -429
  61. package/templates/agents/engineering/nextjs-engineer.md +0 -451
  62. package/templates/agents/engineering/prisma-engineer.md +0 -432
  63. package/templates/agents/engineering/react-senior-dev.md +0 -394
  64. package/templates/agents/engineering/tanstack-start-engineer.md +0 -447
@@ -0,0 +1,469 @@
1
+ # TanStack Start Patterns
2
+
3
+ ## Overview
4
+
5
+ TanStack Start is a full-stack React framework with file-based routing and server functions. This skill provides patterns for building TanStack Start applications.
6
+
7
+ ---
8
+
9
+ ## Route Definition
10
+
11
+ ### Basic Route
12
+
13
+ ```typescript
14
+ // app/routes/index.tsx
15
+ import { createFileRoute } from '@tanstack/react-router';
16
+
17
+ export const Route = createFileRoute('/')({
18
+ component: HomePage,
19
+ });
20
+
21
+ function HomePage() {
22
+ return (
23
+ <main className="container py-8">
24
+ <h1>Welcome</h1>
25
+ <p>This is the home page.</p>
26
+ </main>
27
+ );
28
+ }
29
+ ```
30
+
31
+ ### Route with Loader
32
+
33
+ ```typescript
34
+ // app/routes/items/index.tsx
35
+ import { createFileRoute } from '@tanstack/react-router';
36
+ import { getItems } from '@/lib/api';
37
+
38
+ export const Route = createFileRoute('/items/')({
39
+ loader: async () => {
40
+ const items = await getItems();
41
+ return { items };
42
+ },
43
+ component: ItemsPage,
44
+ });
45
+
46
+ function ItemsPage() {
47
+ const { items } = Route.useLoaderData();
48
+
49
+ return (
50
+ <main>
51
+ <h1>Items</h1>
52
+ <ul>
53
+ {items.map((item) => (
54
+ <li key={item.id}>{item.title}</li>
55
+ ))}
56
+ </ul>
57
+ </main>
58
+ );
59
+ }
60
+ ```
61
+
62
+ ### Dynamic Route
63
+
64
+ ```typescript
65
+ // app/routes/items/$itemId.tsx
66
+ import { createFileRoute, notFound } from '@tanstack/react-router';
67
+ import { getItem } from '@/lib/api';
68
+
69
+ export const Route = createFileRoute('/items/$itemId')({
70
+ loader: async ({ params }) => {
71
+ const item = await getItem(params.itemId);
72
+
73
+ if (!item) {
74
+ throw notFound();
75
+ }
76
+
77
+ return { item };
78
+ },
79
+ component: ItemPage,
80
+ });
81
+
82
+ function ItemPage() {
83
+ const { item } = Route.useLoaderData();
84
+
85
+ return (
86
+ <article>
87
+ <h1>{item.title}</h1>
88
+ <p>{item.description}</p>
89
+ <p>Price: ${item.price}</p>
90
+ </article>
91
+ );
92
+ }
93
+ ```
94
+
95
+ ---
96
+
97
+ ## Server Functions
98
+
99
+ ### Basic Server Function
100
+
101
+ ```typescript
102
+ // app/lib/server-fns.ts
103
+ import { createServerFn } from '@tanstack/start';
104
+ import { db } from './db';
105
+
106
+ export const getItems = createServerFn('GET', async () => {
107
+ const items = await db.item.findMany({
108
+ where: { status: 'active' },
109
+ orderBy: { createdAt: 'desc' },
110
+ });
111
+
112
+ return items;
113
+ });
114
+
115
+ export const getItem = createServerFn('GET', async (id: string) => {
116
+ const item = await db.item.findUnique({
117
+ where: { id },
118
+ });
119
+
120
+ return item;
121
+ });
122
+ ```
123
+
124
+ ### Mutation Server Function
125
+
126
+ ```typescript
127
+ // app/lib/server-fns.ts
128
+ import { createServerFn } from '@tanstack/start';
129
+ import { z } from 'zod';
130
+ import { db } from './db';
131
+ import { getSession } from './auth';
132
+
133
+ const createItemSchema = z.object({
134
+ title: z.string().min(1),
135
+ description: z.string().optional(),
136
+ price: z.number().positive(),
137
+ });
138
+
139
+ export const createItem = createServerFn('POST', async (input: unknown) => {
140
+ const session = await getSession();
141
+ if (!session?.user) {
142
+ throw new Error('Unauthorized');
143
+ }
144
+
145
+ const data = createItemSchema.parse(input);
146
+
147
+ const item = await db.item.create({
148
+ data: {
149
+ ...data,
150
+ authorId: session.user.id,
151
+ },
152
+ });
153
+
154
+ return item;
155
+ });
156
+
157
+ export const updateItem = createServerFn(
158
+ 'POST',
159
+ async ({ id, data }: { id: string; data: unknown }) => {
160
+ const session = await getSession();
161
+ if (!session?.user) {
162
+ throw new Error('Unauthorized');
163
+ }
164
+
165
+ const parsed = createItemSchema.partial().parse(data);
166
+
167
+ const item = await db.item.update({
168
+ where: { id, authorId: session.user.id },
169
+ data: parsed,
170
+ });
171
+
172
+ return item;
173
+ }
174
+ );
175
+
176
+ export const deleteItem = createServerFn('POST', async (id: string) => {
177
+ const session = await getSession();
178
+ if (!session?.user) {
179
+ throw new Error('Unauthorized');
180
+ }
181
+
182
+ await db.item.delete({
183
+ where: { id, authorId: session.user.id },
184
+ });
185
+
186
+ return { success: true };
187
+ });
188
+ ```
189
+
190
+ ---
191
+
192
+ ## Using Server Functions in Components
193
+
194
+ ### With TanStack Query
195
+
196
+ ```typescript
197
+ // app/routes/items/index.tsx
198
+ import { createFileRoute } from '@tanstack/react-router';
199
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
200
+ import { getItems, createItem, deleteItem } from '@/lib/server-fns';
201
+
202
+ export const Route = createFileRoute('/items/')({
203
+ loader: () => getItems(),
204
+ component: ItemsPage,
205
+ });
206
+
207
+ function ItemsPage() {
208
+ const items = Route.useLoaderData();
209
+ const queryClient = useQueryClient();
210
+
211
+ const createMutation = useMutation({
212
+ mutationFn: createItem,
213
+ onSuccess: () => {
214
+ queryClient.invalidateQueries({ queryKey: ['items'] });
215
+ },
216
+ });
217
+
218
+ const deleteMutation = useMutation({
219
+ mutationFn: deleteItem,
220
+ onSuccess: () => {
221
+ queryClient.invalidateQueries({ queryKey: ['items'] });
222
+ },
223
+ });
224
+
225
+ return (
226
+ <main>
227
+ <h1>Items</h1>
228
+
229
+ <form
230
+ onSubmit={(e) => {
231
+ e.preventDefault();
232
+ const formData = new FormData(e.currentTarget);
233
+ createMutation.mutate({
234
+ title: formData.get('title') as string,
235
+ price: Number(formData.get('price')),
236
+ });
237
+ }}
238
+ >
239
+ <input name="title" placeholder="Title" required />
240
+ <input name="price" type="number" placeholder="Price" required />
241
+ <button type="submit" disabled={createMutation.isPending}>
242
+ Create
243
+ </button>
244
+ </form>
245
+
246
+ <ul>
247
+ {items.map((item) => (
248
+ <li key={item.id}>
249
+ {item.title} - ${item.price}
250
+ <button
251
+ onClick={() => deleteMutation.mutate(item.id)}
252
+ disabled={deleteMutation.isPending}
253
+ >
254
+ Delete
255
+ </button>
256
+ </li>
257
+ ))}
258
+ </ul>
259
+ </main>
260
+ );
261
+ }
262
+ ```
263
+
264
+ ---
265
+
266
+ ## Layouts
267
+
268
+ ### Root Layout
269
+
270
+ ```typescript
271
+ // app/routes/__root.tsx
272
+ import { createRootRoute, Outlet } from '@tanstack/react-router';
273
+ import { Header } from '@/components/Header';
274
+ import { Footer } from '@/components/Footer';
275
+
276
+ export const Route = createRootRoute({
277
+ component: RootLayout,
278
+ });
279
+
280
+ function RootLayout() {
281
+ return (
282
+ <>
283
+ <Header />
284
+ <Outlet />
285
+ <Footer />
286
+ </>
287
+ );
288
+ }
289
+ ```
290
+
291
+ ### Nested Layout
292
+
293
+ ```typescript
294
+ // app/routes/dashboard/_layout.tsx
295
+ import { createFileRoute, Outlet } from '@tanstack/react-router';
296
+ import { Sidebar } from '@/components/Sidebar';
297
+
298
+ export const Route = createFileRoute('/dashboard/_layout')({
299
+ component: DashboardLayout,
300
+ });
301
+
302
+ function DashboardLayout() {
303
+ return (
304
+ <div className="flex">
305
+ <Sidebar />
306
+ <main className="flex-1">
307
+ <Outlet />
308
+ </main>
309
+ </div>
310
+ );
311
+ }
312
+ ```
313
+
314
+ ---
315
+
316
+ ## Error Handling
317
+
318
+ ### Route Error Boundary
319
+
320
+ ```typescript
321
+ // app/routes/items/$itemId.tsx
322
+ import { createFileRoute, notFound, ErrorComponent } from '@tanstack/react-router';
323
+
324
+ export const Route = createFileRoute('/items/$itemId')({
325
+ loader: async ({ params }) => {
326
+ const item = await getItem(params.itemId);
327
+
328
+ if (!item) {
329
+ throw notFound();
330
+ }
331
+
332
+ return { item };
333
+ },
334
+ errorComponent: ItemErrorBoundary,
335
+ notFoundComponent: ItemNotFound,
336
+ component: ItemPage,
337
+ });
338
+
339
+ function ItemErrorBoundary({ error }: { error: Error }) {
340
+ return (
341
+ <div className="p-4 border border-red-500 rounded">
342
+ <h2>Error loading item</h2>
343
+ <p>{error.message}</p>
344
+ </div>
345
+ );
346
+ }
347
+
348
+ function ItemNotFound() {
349
+ return (
350
+ <div className="p-4">
351
+ <h2>Item not found</h2>
352
+ <p>The item you're looking for doesn't exist.</p>
353
+ </div>
354
+ );
355
+ }
356
+ ```
357
+
358
+ ---
359
+
360
+ ## Search Params
361
+
362
+ ### Route with Search Params
363
+
364
+ ```typescript
365
+ // app/routes/items/index.tsx
366
+ import { createFileRoute } from '@tanstack/react-router';
367
+ import { z } from 'zod';
368
+
369
+ const itemsSearchSchema = z.object({
370
+ q: z.string().optional(),
371
+ page: z.number().default(1),
372
+ status: z.enum(['active', 'archived']).optional(),
373
+ });
374
+
375
+ export const Route = createFileRoute('/items/')({
376
+ validateSearch: itemsSearchSchema,
377
+ loaderDeps: ({ search }) => ({ search }),
378
+ loader: async ({ deps }) => {
379
+ const items = await getItems(deps.search);
380
+ return { items };
381
+ },
382
+ component: ItemsPage,
383
+ });
384
+
385
+ function ItemsPage() {
386
+ const { items } = Route.useLoaderData();
387
+ const search = Route.useSearch();
388
+ const navigate = Route.useNavigate();
389
+
390
+ return (
391
+ <main>
392
+ <input
393
+ value={search.q || ''}
394
+ onChange={(e) =>
395
+ navigate({ search: { ...search, q: e.target.value } })
396
+ }
397
+ placeholder="Search..."
398
+ />
399
+
400
+ <select
401
+ value={search.status || ''}
402
+ onChange={(e) =>
403
+ navigate({
404
+ search: { ...search, status: e.target.value || undefined },
405
+ })
406
+ }
407
+ >
408
+ <option value="">All</option>
409
+ <option value="active">Active</option>
410
+ <option value="archived">Archived</option>
411
+ </select>
412
+
413
+ <ul>
414
+ {items.map((item) => (
415
+ <li key={item.id}>{item.title}</li>
416
+ ))}
417
+ </ul>
418
+ </main>
419
+ );
420
+ }
421
+ ```
422
+
423
+ ---
424
+
425
+ ## Project Structure
426
+
427
+ ```
428
+ app/
429
+ ├── routes/
430
+ │ ├── __root.tsx # Root layout
431
+ │ ├── index.tsx # Home page
432
+ │ ├── about.tsx
433
+ │ ├── items/
434
+ │ │ ├── index.tsx # /items
435
+ │ │ └── $itemId.tsx # /items/:itemId
436
+ │ └── dashboard/
437
+ │ ├── _layout.tsx # Dashboard layout
438
+ │ └── index.tsx # /dashboard
439
+ ├── components/
440
+ │ ├── Header.tsx
441
+ │ ├── Footer.tsx
442
+ │ └── Sidebar.tsx
443
+ ├── lib/
444
+ │ ├── server-fns.ts # Server functions
445
+ │ ├── db.ts # Database client
446
+ │ └── auth.ts # Authentication
447
+ └── styles/
448
+ └── global.css
449
+ ```
450
+
451
+ ---
452
+
453
+ ## Best Practices
454
+
455
+ ### Good
456
+
457
+ - Use loaders for data fetching
458
+ - Use server functions for mutations
459
+ - Use search params validation with Zod
460
+ - Use TanStack Query for client-side caching
461
+ - Use error and notFound components
462
+
463
+ ### Bad
464
+
465
+ - Client-side fetching when loader works
466
+ - Not validating search params
467
+ - Ignoring error boundaries
468
+ - Not using server functions for sensitive operations
469
+ - Putting business logic in components