@qazuor/claude-code-config 0.5.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 (57) hide show
  1. package/README.md +106 -41
  2. package/dist/bin.cjs +963 -84
  3. package/dist/bin.cjs.map +1 -1
  4. package/dist/bin.js +963 -84
  5. package/dist/bin.js.map +1 -1
  6. package/dist/index.cjs +73 -56
  7. package/dist/index.cjs.map +1 -1
  8. package/dist/index.d.cts +2 -0
  9. package/dist/index.d.ts +2 -0
  10. package/dist/index.js +73 -56
  11. package/dist/index.js.map +1 -1
  12. package/package.json +23 -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/hooks/on-notification.sh +0 -0
  20. package/templates/scripts/add-changelogs.sh +0 -0
  21. package/templates/scripts/generate-code-registry.ts +0 -0
  22. package/templates/scripts/health-check.sh +0 -0
  23. package/templates/scripts/sync-registry.sh +0 -0
  24. package/templates/scripts/telemetry-report.ts +0 -0
  25. package/templates/scripts/validate-docs.sh +0 -0
  26. package/templates/scripts/validate-registry.sh +0 -0
  27. package/templates/scripts/validate-structure.sh +0 -0
  28. package/templates/scripts/worktree-cleanup.sh +0 -0
  29. package/templates/scripts/worktree-create.sh +0 -0
  30. package/templates/skills/README.md +99 -90
  31. package/templates/skills/_registry.json +323 -16
  32. package/templates/skills/api-frameworks/express-patterns.md +411 -0
  33. package/templates/skills/api-frameworks/fastify-patterns.md +419 -0
  34. package/templates/skills/api-frameworks/hono-patterns.md +388 -0
  35. package/templates/skills/api-frameworks/nestjs-patterns.md +497 -0
  36. package/templates/skills/database/drizzle-patterns.md +449 -0
  37. package/templates/skills/database/mongoose-patterns.md +503 -0
  38. package/templates/skills/database/prisma-patterns.md +487 -0
  39. package/templates/skills/frontend-frameworks/astro-patterns.md +415 -0
  40. package/templates/skills/frontend-frameworks/nextjs-patterns.md +470 -0
  41. package/templates/skills/frontend-frameworks/react-patterns.md +516 -0
  42. package/templates/skills/frontend-frameworks/tanstack-start-patterns.md +469 -0
  43. package/templates/skills/patterns/atdd-methodology.md +364 -0
  44. package/templates/skills/patterns/bdd-methodology.md +281 -0
  45. package/templates/skills/patterns/clean-architecture.md +444 -0
  46. package/templates/skills/patterns/hexagonal-architecture.md +567 -0
  47. package/templates/skills/patterns/vertical-slice-architecture.md +502 -0
  48. package/templates/agents/engineering/astro-engineer.md +0 -293
  49. package/templates/agents/engineering/db-drizzle-engineer.md +0 -360
  50. package/templates/agents/engineering/express-engineer.md +0 -316
  51. package/templates/agents/engineering/fastify-engineer.md +0 -399
  52. package/templates/agents/engineering/mongoose-engineer.md +0 -473
  53. package/templates/agents/engineering/nestjs-engineer.md +0 -429
  54. package/templates/agents/engineering/nextjs-engineer.md +0 -451
  55. package/templates/agents/engineering/prisma-engineer.md +0 -432
  56. package/templates/agents/engineering/react-senior-dev.md +0 -394
  57. package/templates/agents/engineering/tanstack-start-engineer.md +0 -447
@@ -0,0 +1,415 @@
1
+ # Astro Patterns
2
+
3
+ ## Overview
4
+
5
+ Astro is a web framework for content-focused websites with islands architecture. This skill provides patterns for building Astro applications.
6
+
7
+ ---
8
+
9
+ ## Page Components
10
+
11
+ ### Basic Page
12
+
13
+ ```astro
14
+ ---
15
+ // src/pages/index.astro
16
+ import BaseLayout from '@/layouts/BaseLayout.astro';
17
+ import { getItems } from '@/lib/api';
18
+
19
+ const items = await getItems();
20
+ ---
21
+
22
+ <BaseLayout title="Home">
23
+ <main>
24
+ <h1>Welcome</h1>
25
+ <ul>
26
+ {items.map((item) => (
27
+ <li>
28
+ <a href={`/items/${item.id}`}>{item.title}</a>
29
+ </li>
30
+ ))}
31
+ </ul>
32
+ </main>
33
+ </BaseLayout>
34
+ ```
35
+
36
+ ### Dynamic Route
37
+
38
+ ```astro
39
+ ---
40
+ // src/pages/items/[id].astro
41
+ import BaseLayout from '@/layouts/BaseLayout.astro';
42
+ import { getItem, getItems } from '@/lib/api';
43
+
44
+ export async function getStaticPaths() {
45
+ const items = await getItems();
46
+
47
+ return items.map((item) => ({
48
+ params: { id: item.id },
49
+ props: { item },
50
+ }));
51
+ }
52
+
53
+ interface Props {
54
+ item: Item;
55
+ }
56
+
57
+ const { item } = Astro.props;
58
+ ---
59
+
60
+ <BaseLayout title={item.title}>
61
+ <article>
62
+ <h1>{item.title}</h1>
63
+ <p>{item.description}</p>
64
+ <p>Price: ${item.price}</p>
65
+ </article>
66
+ </BaseLayout>
67
+ ```
68
+
69
+ ---
70
+
71
+ ## Layouts
72
+
73
+ ### Base Layout
74
+
75
+ ```astro
76
+ ---
77
+ // src/layouts/BaseLayout.astro
78
+ import Header from '@/components/Header.astro';
79
+ import Footer from '@/components/Footer.astro';
80
+ import '@/styles/global.css';
81
+
82
+ interface Props {
83
+ title: string;
84
+ description?: string;
85
+ }
86
+
87
+ const { title, description = 'Default description' } = Astro.props;
88
+ ---
89
+
90
+ <!doctype html>
91
+ <html lang="en">
92
+ <head>
93
+ <meta charset="UTF-8" />
94
+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
95
+ <meta name="description" content={description} />
96
+ <title>{title}</title>
97
+ </head>
98
+ <body>
99
+ <Header />
100
+ <slot />
101
+ <Footer />
102
+ </body>
103
+ </html>
104
+ ```
105
+
106
+ ### Nested Layouts
107
+
108
+ ```astro
109
+ ---
110
+ // src/layouts/DocsLayout.astro
111
+ import BaseLayout from './BaseLayout.astro';
112
+ import Sidebar from '@/components/Sidebar.astro';
113
+
114
+ interface Props {
115
+ title: string;
116
+ }
117
+
118
+ const { title } = Astro.props;
119
+ ---
120
+
121
+ <BaseLayout title={title}>
122
+ <div class="flex">
123
+ <Sidebar />
124
+ <main class="flex-1">
125
+ <slot />
126
+ </main>
127
+ </div>
128
+ </BaseLayout>
129
+ ```
130
+
131
+ ---
132
+
133
+ ## Islands Architecture
134
+
135
+ ### React Island
136
+
137
+ ```astro
138
+ ---
139
+ // src/pages/interactive.astro
140
+ import BaseLayout from '@/layouts/BaseLayout.astro';
141
+ import Counter from '@/components/Counter'; // React component
142
+ import ItemForm from '@/components/ItemForm'; // React component
143
+ ---
144
+
145
+ <BaseLayout title="Interactive Page">
146
+ <h1>Static Content</h1>
147
+
148
+ <!-- Hydrates on page load -->
149
+ <Counter client:load initialCount={0} />
150
+
151
+ <!-- Hydrates when visible -->
152
+ <ItemForm client:visible />
153
+
154
+ <!-- Hydrates on idle -->
155
+ <HeavyComponent client:idle />
156
+
157
+ <!-- Only client-side (no SSR) -->
158
+ <ClientOnlyWidget client:only="react" />
159
+ </BaseLayout>
160
+ ```
161
+
162
+ ### Interactive React Component
163
+
164
+ ```tsx
165
+ // src/components/Counter.tsx
166
+ import { useState } from 'react';
167
+
168
+ interface CounterProps {
169
+ initialCount: number;
170
+ }
171
+
172
+ export default function Counter({ initialCount }: CounterProps) {
173
+ const [count, setCount] = useState(initialCount);
174
+
175
+ return (
176
+ <div className="p-4 border rounded">
177
+ <p>Count: {count}</p>
178
+ <button onClick={() => setCount(count + 1)}>Increment</button>
179
+ <button onClick={() => setCount(count - 1)}>Decrement</button>
180
+ </div>
181
+ );
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## Content Collections
188
+
189
+ ### Collection Schema
190
+
191
+ ```typescript
192
+ // src/content/config.ts
193
+ import { defineCollection, z } from 'astro:content';
194
+
195
+ const blog = defineCollection({
196
+ type: 'content',
197
+ schema: z.object({
198
+ title: z.string(),
199
+ description: z.string(),
200
+ pubDate: z.coerce.date(),
201
+ updatedDate: z.coerce.date().optional(),
202
+ heroImage: z.string().optional(),
203
+ tags: z.array(z.string()).default([]),
204
+ draft: z.boolean().default(false),
205
+ }),
206
+ });
207
+
208
+ const authors = defineCollection({
209
+ type: 'data',
210
+ schema: z.object({
211
+ name: z.string(),
212
+ bio: z.string(),
213
+ avatar: z.string(),
214
+ }),
215
+ });
216
+
217
+ export const collections = { blog, authors };
218
+ ```
219
+
220
+ ### Using Collections
221
+
222
+ ```astro
223
+ ---
224
+ // src/pages/blog/index.astro
225
+ import { getCollection } from 'astro:content';
226
+ import BaseLayout from '@/layouts/BaseLayout.astro';
227
+ import BlogCard from '@/components/BlogCard.astro';
228
+
229
+ const posts = await getCollection('blog', ({ data }) => {
230
+ return !data.draft;
231
+ });
232
+
233
+ const sortedPosts = posts.sort(
234
+ (a, b) => b.data.pubDate.valueOf() - a.data.pubDate.valueOf()
235
+ );
236
+ ---
237
+
238
+ <BaseLayout title="Blog">
239
+ <h1>Blog Posts</h1>
240
+ <div class="grid gap-4">
241
+ {sortedPosts.map((post) => (
242
+ <BlogCard post={post} />
243
+ ))}
244
+ </div>
245
+ </BaseLayout>
246
+ ```
247
+
248
+ ### Blog Post Page
249
+
250
+ ```astro
251
+ ---
252
+ // src/pages/blog/[...slug].astro
253
+ import { getCollection } from 'astro:content';
254
+ import BlogLayout from '@/layouts/BlogLayout.astro';
255
+
256
+ export async function getStaticPaths() {
257
+ const posts = await getCollection('blog');
258
+
259
+ return posts.map((post) => ({
260
+ params: { slug: post.slug },
261
+ props: { post },
262
+ }));
263
+ }
264
+
265
+ const { post } = Astro.props;
266
+ const { Content } = await post.render();
267
+ ---
268
+
269
+ <BlogLayout title={post.data.title}>
270
+ <article>
271
+ <h1>{post.data.title}</h1>
272
+ <time datetime={post.data.pubDate.toISOString()}>
273
+ {post.data.pubDate.toLocaleDateString()}
274
+ </time>
275
+ <Content />
276
+ </article>
277
+ </BlogLayout>
278
+ ```
279
+
280
+ ---
281
+
282
+ ## API Routes
283
+
284
+ ### Basic Endpoint
285
+
286
+ ```typescript
287
+ // src/pages/api/items.ts
288
+ import type { APIRoute } from 'astro';
289
+ import { getItems } from '@/lib/api';
290
+
291
+ export const GET: APIRoute = async () => {
292
+ const items = await getItems();
293
+
294
+ return new Response(JSON.stringify({ data: items }), {
295
+ status: 200,
296
+ headers: {
297
+ 'Content-Type': 'application/json',
298
+ },
299
+ });
300
+ };
301
+
302
+ export const POST: APIRoute = async ({ request }) => {
303
+ const body = await request.json();
304
+
305
+ // Create item...
306
+
307
+ return new Response(JSON.stringify({ data: newItem }), {
308
+ status: 201,
309
+ headers: {
310
+ 'Content-Type': 'application/json',
311
+ },
312
+ });
313
+ };
314
+ ```
315
+
316
+ ### Dynamic Endpoint
317
+
318
+ ```typescript
319
+ // src/pages/api/items/[id].ts
320
+ import type { APIRoute } from 'astro';
321
+
322
+ export const GET: APIRoute = async ({ params }) => {
323
+ const { id } = params;
324
+ const item = await getItem(id);
325
+
326
+ if (!item) {
327
+ return new Response(JSON.stringify({ error: 'Not found' }), {
328
+ status: 404,
329
+ });
330
+ }
331
+
332
+ return new Response(JSON.stringify({ data: item }), {
333
+ status: 200,
334
+ });
335
+ };
336
+ ```
337
+
338
+ ---
339
+
340
+ ## Integrations
341
+
342
+ ### Config with Integrations
343
+
344
+ ```typescript
345
+ // astro.config.mjs
346
+ import { defineConfig } from 'astro/config';
347
+ import react from '@astrojs/react';
348
+ import tailwind from '@astrojs/tailwind';
349
+ import sitemap from '@astrojs/sitemap';
350
+ import vercel from '@astrojs/vercel/serverless';
351
+
352
+ export default defineConfig({
353
+ site: 'https://example.com',
354
+ integrations: [
355
+ react(),
356
+ tailwind(),
357
+ sitemap(),
358
+ ],
359
+ output: 'hybrid', // Static by default, opt-in to server rendering
360
+ adapter: vercel(),
361
+ });
362
+ ```
363
+
364
+ ---
365
+
366
+ ## Project Structure
367
+
368
+ ```
369
+ src/
370
+ ├── pages/
371
+ │ ├── index.astro
372
+ │ ├── about.astro
373
+ │ ├── blog/
374
+ │ │ ├── index.astro
375
+ │ │ └── [...slug].astro
376
+ │ └── api/
377
+ │ └── items.ts
378
+ ├── layouts/
379
+ │ ├── BaseLayout.astro
380
+ │ └── BlogLayout.astro
381
+ ├── components/
382
+ │ ├── Header.astro # Static component
383
+ │ ├── Footer.astro
384
+ │ ├── BlogCard.astro
385
+ │ └── Counter.tsx # React island
386
+ ├── content/
387
+ │ ├── config.ts
388
+ │ └── blog/
389
+ │ ├── post-1.md
390
+ │ └── post-2.md
391
+ ├── lib/
392
+ │ └── api.ts
393
+ └── styles/
394
+ └── global.css
395
+ ```
396
+
397
+ ---
398
+
399
+ ## Best Practices
400
+
401
+ ### Good
402
+
403
+ - Use Astro components for static content
404
+ - Use islands (`client:*`) only for interactive parts
405
+ - Use content collections for structured content
406
+ - Use `client:visible` for below-the-fold interactivity
407
+ - Generate static pages when possible
408
+
409
+ ### Bad
410
+
411
+ - Adding `client:load` to everything (defeats the purpose)
412
+ - Using React/Vue for static content
413
+ - Not using content collections for blog/docs
414
+ - Ignoring image optimization
415
+ - Server rendering when static works