codecruise 0.1.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 (129) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +111 -0
  3. package/bin/codecruise.js +68 -0
  4. package/config/CLAUDE.md +107 -0
  5. package/config/agents/analyst.md +48 -0
  6. package/config/agents/architect-reviewer.md +161 -0
  7. package/config/agents/architect.md +119 -0
  8. package/config/agents/critic.md +63 -0
  9. package/config/agents/developer.md +96 -0
  10. package/config/agents/devops.md +81 -0
  11. package/config/agents/orchestrator.md +91 -0
  12. package/config/agents/planner.md +139 -0
  13. package/config/agents/retro.md +52 -0
  14. package/config/agents/reviewer.md +101 -0
  15. package/config/agents/security-reviewer.md +57 -0
  16. package/config/agents/stack/expo/AGENT.md +473 -0
  17. package/config/agents/stack/expo/rules/critical.md +427 -0
  18. package/config/agents/stack/expo/rules/native.md +455 -0
  19. package/config/agents/stack/expo/rules/navigation.md +445 -0
  20. package/config/agents/stack/expo/rules/performance.md +415 -0
  21. package/config/agents/stack/fastify/AGENT.md +397 -0
  22. package/config/agents/stack/fastify/rules/api-design.md +283 -0
  23. package/config/agents/stack/fastify/rules/critical.md +232 -0
  24. package/config/agents/stack/fastify/rules/queues.md +303 -0
  25. package/config/agents/stack/fastify/rules/security.md +384 -0
  26. package/config/agents/stack/index.yaml +48 -0
  27. package/config/agents/stack/nextjs/AGENT.md +421 -0
  28. package/config/agents/stack/nextjs/rules/components.md +413 -0
  29. package/config/agents/stack/nextjs/rules/critical.md +391 -0
  30. package/config/agents/stack/nextjs/rules/performance.md +403 -0
  31. package/config/agents/stack/nextjs/rules/styling.md +334 -0
  32. package/config/agents/stack/shared-ts/AGENT.md +384 -0
  33. package/config/agents/stack/shared-ts/rules/critical.md +315 -0
  34. package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
  35. package/config/agents/stack/shared-ts/rules/zod.md +427 -0
  36. package/config/agents/tester.md +79 -0
  37. package/config/commands/architect-discuss.md +366 -0
  38. package/config/commands/architect-list.md +160 -0
  39. package/config/commands/architect-review.md +111 -0
  40. package/config/commands/architect.md +118 -0
  41. package/config/commands/compact.md +118 -0
  42. package/config/commands/companion.md +279 -0
  43. package/config/commands/dashboard.md +152 -0
  44. package/config/commands/doctor.md +227 -0
  45. package/config/commands/dogfood-report.md +101 -0
  46. package/config/commands/flags/run-autonomous.md +110 -0
  47. package/config/commands/flags/run-pause.md +80 -0
  48. package/config/commands/ingest.md +173 -0
  49. package/config/commands/init.md +128 -0
  50. package/config/commands/metrics.md +87 -0
  51. package/config/commands/parallel.md +320 -0
  52. package/config/commands/pause.md +55 -0
  53. package/config/commands/plan-review.md +130 -0
  54. package/config/commands/plan.md +216 -0
  55. package/config/commands/production-check.md +308 -0
  56. package/config/commands/refine.md +323 -0
  57. package/config/commands/resume.md +72 -0
  58. package/config/commands/retro.md +121 -0
  59. package/config/commands/retry.md +75 -0
  60. package/config/commands/role.md +310 -0
  61. package/config/commands/run.md +417 -0
  62. package/config/commands/scope.md +85 -0
  63. package/config/commands/setup-permissions.md +104 -0
  64. package/config/commands/skip.md +75 -0
  65. package/config/commands/spec-forge.md +213 -0
  66. package/config/commands/spec-help.md +194 -0
  67. package/config/commands/spec-patch.md +342 -0
  68. package/config/commands/spec-resolve.md +110 -0
  69. package/config/commands/spec-review.md +153 -0
  70. package/config/commands/status.md +114 -0
  71. package/config/commands/sync.md +131 -0
  72. package/config/commands/task.md +138 -0
  73. package/config/commands/verify.md +124 -0
  74. package/config/hooks/README.md +632 -0
  75. package/config/hooks/activity-log.sh +187 -0
  76. package/config/hooks/anti-rationalize.sh +52 -0
  77. package/config/hooks/capture-verification.sh +112 -0
  78. package/config/hooks/collect-metrics.sh +135 -0
  79. package/config/hooks/enforce-file-scope.sh +75 -0
  80. package/config/hooks/enforce-state-machine.sh +161 -0
  81. package/config/hooks/enforce-tdd.sh +180 -0
  82. package/config/hooks/format.sh +40 -0
  83. package/config/hooks/lib/activity-helpers.sh +162 -0
  84. package/config/hooks/lib/read-settings.sh +71 -0
  85. package/config/hooks/load-context-skills.sh +95 -0
  86. package/config/hooks/notify.sh +81 -0
  87. package/config/hooks/pre-commit.sample +35 -0
  88. package/config/hooks/protect-files.sh +63 -0
  89. package/config/hooks/track-agents.sh +41 -0
  90. package/config/hooks/track-commands.sh +37 -0
  91. package/config/hooks/track-enforcement.sh +44 -0
  92. package/config/hooks/track-ooda.sh +77 -0
  93. package/config/hooks/validate-commit-msg.sh +35 -0
  94. package/config/hooks/validate-plan.sh +213 -0
  95. package/config/hooks/verify-criteria.sh +46 -0
  96. package/config/hooks/verify-todo-completion.sh +140 -0
  97. package/config/rules/comments.md +25 -0
  98. package/config/rules/decision-rules.md +308 -0
  99. package/config/rules/hygiene.md +247 -0
  100. package/config/rules/pattern-detection.md +372 -0
  101. package/config/rules/profiles.md +193 -0
  102. package/config/rules/recovery.md +83 -0
  103. package/config/rules/scope-detection.md +213 -0
  104. package/config/rules/standards.md +127 -0
  105. package/config/rules/workflow.md +121 -0
  106. package/config/schemas.md +767 -0
  107. package/config/settings.json +195 -0
  108. package/config/skills/backend/SKILL.md +734 -0
  109. package/config/skills/database/SKILL.md +426 -0
  110. package/config/skills/frontend/SKILL.md +434 -0
  111. package/config/skills/git/SKILL.md +396 -0
  112. package/config/skills/index.yaml +36 -0
  113. package/config/skills/observability/SKILL.md +430 -0
  114. package/config/skills/package-dev/SKILL.md +498 -0
  115. package/config/skills/performance/SKILL.md +378 -0
  116. package/config/skills/resilience/SKILL.md +573 -0
  117. package/config/skills/testing/SKILL.md +398 -0
  118. package/config/skills/testing-patterns/SKILL.md +276 -0
  119. package/config/skills/typescript/SKILL.md +152 -0
  120. package/config/templates/CLAUDE.md +70 -0
  121. package/config/templates/README.md +117 -0
  122. package/config/templates/steering/adr-template.md +102 -0
  123. package/config/templates/steering/product.md +60 -0
  124. package/config/templates/steering/rfc-template.md +159 -0
  125. package/config/templates/steering/structure.md +146 -0
  126. package/config/templates/steering/tech.md +85 -0
  127. package/package.json +40 -0
  128. package/src/install.js +163 -0
  129. package/src/report.js +310 -0
@@ -0,0 +1,413 @@
1
+ # Component Rules - React & shadcn/ui
2
+
3
+ Patterns for building maintainable React components.
4
+
5
+ ---
6
+
7
+ ## Component Structure
8
+
9
+ ### COMP-001: Use function components
10
+
11
+ ```typescript
12
+ // GOOD
13
+ function UserCard({ user }: { user: User }) {
14
+ return <div>...</div>;
15
+ }
16
+
17
+ // Also good - arrow function for small components
18
+ const Badge = ({ label }: { label: string }) => (
19
+ <span className="badge">{label}</span>
20
+ );
21
+
22
+ // Export named, not default (better refactoring)
23
+ export function UserCard({ user }: { user: User }) { ... }
24
+ ```
25
+
26
+ ### COMP-002: Prop types with interface
27
+
28
+ ```typescript
29
+ interface UserCardProps {
30
+ user: User;
31
+ onEdit?: (user: User) => void;
32
+ className?: string;
33
+ children?: React.ReactNode;
34
+ }
35
+
36
+ function UserCard({ user, onEdit, className, children }: UserCardProps) {
37
+ return (
38
+ <Card className={cn('p-4', className)}>
39
+ <h3>{user.name}</h3>
40
+ {children}
41
+ {onEdit && <Button onClick={() => onEdit(user)}>Edit</Button>}
42
+ </Card>
43
+ );
44
+ }
45
+ ```
46
+
47
+ ### COMP-003: Composition over configuration
48
+
49
+ ```typescript
50
+ // BAD - Too many props
51
+ <Card
52
+ title="Settings"
53
+ subtitle="Manage your account"
54
+ icon={<Settings />}
55
+ actions={[{ label: 'Save', onClick: save }]}
56
+ footer={<HelpLink />}
57
+ />
58
+
59
+ // GOOD - Composable
60
+ <Card>
61
+ <CardHeader>
62
+ <CardIcon><Settings /></CardIcon>
63
+ <CardTitle>Settings</CardTitle>
64
+ <CardDescription>Manage your account</CardDescription>
65
+ </CardHeader>
66
+ <CardContent>...</CardContent>
67
+ <CardFooter>
68
+ <HelpLink />
69
+ <Button onClick={save}>Save</Button>
70
+ </CardFooter>
71
+ </Card>
72
+ ```
73
+
74
+ ---
75
+
76
+ ## shadcn/ui Patterns
77
+
78
+ ### COMP-004: Use shadcn components correctly
79
+
80
+ ```typescript
81
+ // Button variants
82
+ <Button>Default</Button>
83
+ <Button variant="secondary">Secondary</Button>
84
+ <Button variant="destructive">Delete</Button>
85
+ <Button variant="outline">Outline</Button>
86
+ <Button variant="ghost">Ghost</Button>
87
+ <Button size="sm">Small</Button>
88
+ <Button size="icon"><Plus /></Button>
89
+
90
+ // With loading state
91
+ <Button disabled={isLoading}>
92
+ {isLoading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
93
+ {isLoading ? 'Saving...' : 'Save'}
94
+ </Button>
95
+
96
+ // As link
97
+ <Button asChild>
98
+ <Link href="/dashboard">Go to Dashboard</Link>
99
+ </Button>
100
+ ```
101
+
102
+ ### COMP-005: Form components with React Hook Form
103
+
104
+ ```typescript
105
+ import { useForm } from 'react-hook-form';
106
+ import { zodResolver } from '@hookform/resolvers/zod';
107
+ import {
108
+ Form,
109
+ FormControl,
110
+ FormDescription,
111
+ FormField,
112
+ FormItem,
113
+ FormLabel,
114
+ FormMessage,
115
+ } from '@/components/ui/form';
116
+
117
+ function ProfileForm() {
118
+ const form = useForm<FormData>({
119
+ resolver: zodResolver(schema),
120
+ });
121
+
122
+ return (
123
+ <Form {...form}>
124
+ <form onSubmit={form.handleSubmit(onSubmit)}>
125
+ <FormField
126
+ control={form.control}
127
+ name="username"
128
+ render={({ field }) => (
129
+ <FormItem>
130
+ <FormLabel>Username</FormLabel>
131
+ <FormControl>
132
+ <Input placeholder="johndoe" {...field} />
133
+ </FormControl>
134
+ <FormDescription>
135
+ This is your public display name.
136
+ </FormDescription>
137
+ <FormMessage />
138
+ </FormItem>
139
+ )}
140
+ />
141
+ </form>
142
+ </Form>
143
+ );
144
+ }
145
+ ```
146
+
147
+ ### COMP-006: Dialog and Sheet patterns
148
+
149
+ ```typescript
150
+ // Controlled dialog
151
+ function EditUserDialog({ user, open, onOpenChange }) {
152
+ return (
153
+ <Dialog open={open} onOpenChange={onOpenChange}>
154
+ <DialogContent>
155
+ <DialogHeader>
156
+ <DialogTitle>Edit User</DialogTitle>
157
+ <DialogDescription>
158
+ Make changes to the user profile.
159
+ </DialogDescription>
160
+ </DialogHeader>
161
+ <UserForm user={user} onSuccess={() => onOpenChange(false)} />
162
+ </DialogContent>
163
+ </Dialog>
164
+ );
165
+ }
166
+
167
+ // With trigger
168
+ function CreateUserButton() {
169
+ return (
170
+ <Dialog>
171
+ <DialogTrigger asChild>
172
+ <Button>Create User</Button>
173
+ </DialogTrigger>
174
+ <DialogContent>
175
+ <DialogHeader>
176
+ <DialogTitle>Create User</DialogTitle>
177
+ </DialogHeader>
178
+ <UserForm />
179
+ </DialogContent>
180
+ </Dialog>
181
+ );
182
+ }
183
+ ```
184
+
185
+ ---
186
+
187
+ ## State Patterns
188
+
189
+ ### COMP-007: Lift state appropriately
190
+
191
+ ```typescript
192
+ // State lives in lowest common ancestor
193
+
194
+ // Parent manages shared state
195
+ function UserList() {
196
+ const [selectedId, setSelectedId] = useState<string | null>(null);
197
+
198
+ return (
199
+ <div className="flex">
200
+ <UserSidebar
201
+ selectedId={selectedId}
202
+ onSelect={setSelectedId}
203
+ />
204
+ <UserDetail userId={selectedId} />
205
+ </div>
206
+ );
207
+ }
208
+
209
+ // Children receive props, no local state needed
210
+ function UserSidebar({ selectedId, onSelect }) {
211
+ const { data: users } = useUsers();
212
+
213
+ return (
214
+ <ul>
215
+ {users.map(user => (
216
+ <li
217
+ key={user.id}
218
+ className={cn(user.id === selectedId && 'bg-accent')}
219
+ onClick={() => onSelect(user.id)}
220
+ >
221
+ {user.name}
222
+ </li>
223
+ ))}
224
+ </ul>
225
+ );
226
+ }
227
+ ```
228
+
229
+ ### COMP-008: Use compound components for complex UI
230
+
231
+ ```typescript
232
+ // Compound component pattern
233
+ const TabsContext = createContext<{...} | null>(null);
234
+
235
+ function Tabs({ children, defaultValue }) {
236
+ const [value, setValue] = useState(defaultValue);
237
+
238
+ return (
239
+ <TabsContext.Provider value={{ value, setValue }}>
240
+ <div className="tabs">{children}</div>
241
+ </TabsContext.Provider>
242
+ );
243
+ }
244
+
245
+ function TabsList({ children }) {
246
+ return <div className="tabs-list">{children}</div>;
247
+ }
248
+
249
+ function TabsTrigger({ value, children }) {
250
+ const { value: selected, setValue } = useContext(TabsContext);
251
+
252
+ return (
253
+ <button
254
+ className={cn('tab', value === selected && 'active')}
255
+ onClick={() => setValue(value)}
256
+ >
257
+ {children}
258
+ </button>
259
+ );
260
+ }
261
+
262
+ function TabsContent({ value, children }) {
263
+ const { value: selected } = useContext(TabsContext);
264
+ if (value !== selected) return null;
265
+ return <div className="tab-content">{children}</div>;
266
+ }
267
+
268
+ // Usage
269
+ <Tabs defaultValue="account">
270
+ <TabsList>
271
+ <TabsTrigger value="account">Account</TabsTrigger>
272
+ <TabsTrigger value="security">Security</TabsTrigger>
273
+ </TabsList>
274
+ <TabsContent value="account">...</TabsContent>
275
+ <TabsContent value="security">...</TabsContent>
276
+ </Tabs>
277
+ ```
278
+
279
+ ---
280
+
281
+ ## Event Handling
282
+
283
+ ### COMP-009: Memoize callbacks appropriately
284
+
285
+ ```typescript
286
+ // Only memoize when passing to memoized children
287
+ // or when callback identity matters
288
+
289
+ // Usually NOT needed
290
+ function UserList() {
291
+ const handleClick = (id: string) => {
292
+ // This is fine, UserItem likely re-renders anyway
293
+ };
294
+
295
+ return users.map(u => <UserItem key={u.id} onClick={() => handleClick(u.id)} />);
296
+ }
297
+
298
+ // Memoize when passing to virtualized lists or heavy components
299
+ const handleClick = useCallback((id: string) => {
300
+ setSelected(id);
301
+ }, []);
302
+
303
+ // Or when used in effects
304
+ const fetchUser = useCallback(async () => {
305
+ const user = await getUser(userId);
306
+ setUser(user);
307
+ }, [userId]);
308
+
309
+ useEffect(() => {
310
+ fetchUser();
311
+ }, [fetchUser]);
312
+ ```
313
+
314
+ ### COMP-010: Handle async actions in forms
315
+
316
+ ```typescript
317
+ function SubmitButton() {
318
+ const { pending } = useFormStatus();
319
+
320
+ return (
321
+ <Button type="submit" disabled={pending}>
322
+ {pending ? (
323
+ <>
324
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
325
+ Saving...
326
+ </>
327
+ ) : (
328
+ 'Save'
329
+ )}
330
+ </Button>
331
+ );
332
+ }
333
+
334
+ function UserForm() {
335
+ const [state, formAction] = useFormState(createUser, initialState);
336
+
337
+ return (
338
+ <form action={formAction}>
339
+ {state?.error && <Alert variant="destructive">{state.error}</Alert>}
340
+ <Input name="email" />
341
+ <SubmitButton />
342
+ </form>
343
+ );
344
+ }
345
+ ```
346
+
347
+ ---
348
+
349
+ ## Accessibility
350
+
351
+ ### COMP-011: Use semantic HTML
352
+
353
+ ```typescript
354
+ // GOOD
355
+ <nav aria-label="Main navigation">
356
+ <ul>
357
+ <li><Link href="/">Home</Link></li>
358
+ </ul>
359
+ </nav>
360
+
361
+ <main>
362
+ <article>
363
+ <h1>Title</h1>
364
+ <p>Content</p>
365
+ </article>
366
+ </main>
367
+
368
+ <button onClick={handleClick}>Click me</button>
369
+
370
+ // BAD
371
+ <div onClick={handleClick}>Click me</div>
372
+ ```
373
+
374
+ ### COMP-012: Accessible forms
375
+
376
+ ```typescript
377
+ // Labels
378
+ <label htmlFor="email">Email</label>
379
+ <input id="email" type="email" aria-describedby="email-hint" />
380
+ <p id="email-hint">We'll never share your email.</p>
381
+
382
+ // Required fields
383
+ <label htmlFor="name">
384
+ Name <span aria-hidden="true">*</span>
385
+ <span className="sr-only">(required)</span>
386
+ </label>
387
+ <input id="name" required aria-required="true" />
388
+
389
+ // Error states
390
+ <input
391
+ id="email"
392
+ aria-invalid={hasError}
393
+ aria-describedby={hasError ? 'email-error' : undefined}
394
+ />
395
+ {hasError && <p id="email-error" role="alert">Invalid email</p>}
396
+ ```
397
+
398
+ ### COMP-013: Screen reader utilities
399
+
400
+ ```typescript
401
+ // Visually hidden but accessible
402
+ <span className="sr-only">Open menu</span>
403
+
404
+ // Skip link
405
+ <a href="#main-content" className="sr-only focus:not-sr-only">
406
+ Skip to main content
407
+ </a>
408
+
409
+ // Live regions
410
+ <div aria-live="polite" aria-atomic="true">
411
+ {notification}
412
+ </div>
413
+ ```