@smicolon/ai-kit 0.1.0 → 0.2.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 (164) hide show
  1. package/.claude-plugin/CLAUDE.md +7 -0
  2. package/.claude-plugin/marketplace.json +373 -0
  3. package/README.md +26 -16
  4. package/dist/index.js +146 -38
  5. package/package.json +4 -3
  6. package/packs/architect/CHANGELOG.md +17 -0
  7. package/packs/architect/README.md +58 -0
  8. package/packs/architect/agents/system-architect.md +768 -0
  9. package/packs/architect/commands/diagram-create.md +300 -0
  10. package/packs/better-auth/.claude-plugin/plugin.json +14 -0
  11. package/packs/better-auth/.mcp.json +14 -0
  12. package/packs/better-auth/CHANGELOG.md +26 -0
  13. package/packs/better-auth/README.md +125 -0
  14. package/packs/better-auth/agents/auth-architect.md +278 -0
  15. package/packs/better-auth/commands/auth-provider-add.md +265 -0
  16. package/packs/better-auth/commands/auth-setup.md +298 -0
  17. package/packs/better-auth/skills/auth-security/SKILL.md +425 -0
  18. package/packs/better-auth/skills/better-auth-patterns/SKILL.md +455 -0
  19. package/packs/dev-loop/.claude-plugin/plugin.json +10 -0
  20. package/packs/dev-loop/CHANGELOG.md +69 -0
  21. package/packs/dev-loop/README.md +155 -0
  22. package/packs/dev-loop/commands/cancel-dev.md +21 -0
  23. package/packs/dev-loop/commands/dev-loop.md +72 -0
  24. package/packs/dev-loop/commands/dev-plan.md +351 -0
  25. package/packs/dev-loop/hooks/hooks.json +15 -0
  26. package/packs/dev-loop/hooks/stop-hook.sh +178 -0
  27. package/packs/dev-loop/scripts/setup-dev-loop.sh +194 -0
  28. package/packs/dev-loop/skills/tdd-planner/SKILL.md +249 -0
  29. package/packs/dev-loop/skills/tdd-planner/references/framework-patterns.md +874 -0
  30. package/packs/dev-loop/skills/tdd-planner/references/good-example.md +260 -0
  31. package/packs/dev-loop/skills/tdd-planner/references/plan-template.md +275 -0
  32. package/packs/django/CHANGELOG.md +39 -0
  33. package/packs/django/README.md +92 -0
  34. package/packs/django/agents/django-architect.md +182 -0
  35. package/packs/django/agents/django-builder.md +250 -0
  36. package/packs/django/agents/django-feature-based.md +420 -0
  37. package/packs/django/agents/django-reviewer.md +253 -0
  38. package/packs/django/agents/django-tester.md +230 -0
  39. package/packs/django/commands/api-endpoint.md +285 -0
  40. package/packs/django/commands/model-create.md +178 -0
  41. package/packs/django/commands/test-generate.md +325 -0
  42. package/packs/django/rules/migrations.md +138 -0
  43. package/packs/django/rules/models.md +167 -0
  44. package/packs/django/rules/serializers.md +126 -0
  45. package/packs/django/rules/services.md +131 -0
  46. package/packs/django/rules/tests.md +140 -0
  47. package/packs/django/rules/views.md +102 -0
  48. package/packs/django/skills/import-convention-enforcer/SKILL.md +226 -0
  49. package/packs/django/skills/import-convention-enforcer/patterns/django-imports.md +343 -0
  50. package/packs/django/skills/migration-safety-checker/SKILL.md +375 -0
  51. package/packs/django/skills/model-entity-validator/SKILL.md +298 -0
  52. package/packs/django/skills/performance-optimizer/SKILL.md +447 -0
  53. package/packs/django/skills/red-phase-verifier/SKILL.md +180 -0
  54. package/packs/django/skills/security-first-validator/SKILL.md +435 -0
  55. package/packs/django/skills/test-coverage-advisor/SKILL.md +394 -0
  56. package/packs/django/skills/test-validity-checker/SKILL.md +194 -0
  57. package/packs/failure-log/.claude-plugin/plugin.json +14 -0
  58. package/packs/failure-log/CHANGELOG.md +20 -0
  59. package/packs/failure-log/README.md +168 -0
  60. package/packs/failure-log/commands/failure-add.md +106 -0
  61. package/packs/failure-log/commands/failure-list.md +89 -0
  62. package/packs/failure-log/hooks/hooks.json +16 -0
  63. package/packs/failure-log/hooks/scripts/inject-failures.sh +64 -0
  64. package/packs/failure-log/skills/failure-log-manager/SKILL.md +164 -0
  65. package/packs/flutter/.claude-plugin/plugin.json +10 -0
  66. package/packs/flutter/CHANGELOG.md +19 -0
  67. package/packs/flutter/README.md +170 -0
  68. package/packs/flutter/agents/flutter-architect.md +166 -0
  69. package/packs/flutter/agents/flutter-builder.md +303 -0
  70. package/packs/flutter/agents/release-manager.md +355 -0
  71. package/packs/flutter/commands/fastlane-setup.md +188 -0
  72. package/packs/flutter/commands/flutter-build.md +90 -0
  73. package/packs/flutter/commands/flutter-deploy.md +133 -0
  74. package/packs/flutter/commands/flutter-test.md +117 -0
  75. package/packs/flutter/commands/signing-setup.md +209 -0
  76. package/packs/flutter/hooks/hooks.json +17 -0
  77. package/packs/flutter/skills/fastlane-knowledge/SKILL.md +193 -0
  78. package/packs/flutter/skills/flutter-architecture/SKILL.md +127 -0
  79. package/packs/flutter/skills/store-publishing/SKILL.md +163 -0
  80. package/packs/hono/.claude-plugin/plugin.json +19 -0
  81. package/packs/hono/CHANGELOG.md +19 -0
  82. package/packs/hono/README.md +143 -0
  83. package/packs/hono/agents/hono-architect.md +240 -0
  84. package/packs/hono/agents/hono-builder.md +285 -0
  85. package/packs/hono/agents/hono-reviewer.md +279 -0
  86. package/packs/hono/agents/hono-tester.md +346 -0
  87. package/packs/hono/commands/middleware-create.md +223 -0
  88. package/packs/hono/commands/project-init.md +306 -0
  89. package/packs/hono/commands/route-create.md +153 -0
  90. package/packs/hono/commands/rpc-client.md +263 -0
  91. package/packs/hono/hooks/hooks.json +4 -0
  92. package/packs/hono/skills/cloudflare-bindings/SKILL.md +408 -0
  93. package/packs/hono/skills/hono-patterns/SKILL.md +309 -0
  94. package/packs/hono/skills/rpc-typesafe/SKILL.md +388 -0
  95. package/packs/hono/skills/zod-validation/SKILL.md +332 -0
  96. package/packs/nestjs/CHANGELOG.md +29 -0
  97. package/packs/nestjs/README.md +75 -0
  98. package/packs/nestjs/agents/nestjs-architect.md +402 -0
  99. package/packs/nestjs/agents/nestjs-builder.md +301 -0
  100. package/packs/nestjs/agents/nestjs-tester.md +437 -0
  101. package/packs/nestjs/commands/module-create.md +369 -0
  102. package/packs/nestjs/rules/controllers.md +92 -0
  103. package/packs/nestjs/rules/dto.md +124 -0
  104. package/packs/nestjs/rules/entities.md +102 -0
  105. package/packs/nestjs/rules/services.md +106 -0
  106. package/packs/nestjs/skills/barrel-export-manager/SKILL.md +389 -0
  107. package/packs/nestjs/skills/import-convention-enforcer/SKILL.md +365 -0
  108. package/packs/nextjs/CHANGELOG.md +36 -0
  109. package/packs/nextjs/README.md +76 -0
  110. package/packs/nextjs/agents/frontend-tester.md +680 -0
  111. package/packs/nextjs/agents/frontend-visual.md +820 -0
  112. package/packs/nextjs/agents/nextjs-architect.md +331 -0
  113. package/packs/nextjs/agents/nextjs-modular.md +433 -0
  114. package/packs/nextjs/commands/component-create.md +398 -0
  115. package/packs/nextjs/rules/api-routes.md +129 -0
  116. package/packs/nextjs/rules/components.md +106 -0
  117. package/packs/nextjs/rules/hooks.md +132 -0
  118. package/packs/nextjs/skills/accessibility-validator/SKILL.md +445 -0
  119. package/packs/nextjs/skills/import-convention-enforcer/SKILL.md +399 -0
  120. package/packs/nextjs/skills/react-form-validator/SKILL.md +569 -0
  121. package/packs/nuxtjs/CHANGELOG.md +30 -0
  122. package/packs/nuxtjs/README.md +56 -0
  123. package/packs/nuxtjs/agents/frontend-tester.md +680 -0
  124. package/packs/nuxtjs/agents/frontend-visual.md +820 -0
  125. package/packs/nuxtjs/agents/nuxtjs-architect.md +537 -0
  126. package/packs/nuxtjs/commands/component-create.md +223 -0
  127. package/packs/nuxtjs/rules/components.md +101 -0
  128. package/packs/nuxtjs/rules/composables.md +118 -0
  129. package/packs/nuxtjs/rules/server-routes.md +127 -0
  130. package/packs/nuxtjs/skills/accessibility-validator/SKILL.md +183 -0
  131. package/packs/nuxtjs/skills/import-convention-enforcer/SKILL.md +196 -0
  132. package/packs/nuxtjs/skills/veevalidate-form-validator/SKILL.md +190 -0
  133. package/packs/onboard/CHANGELOG.md +22 -0
  134. package/packs/onboard/README.md +103 -0
  135. package/packs/onboard/agents/onboard-guide.md +118 -0
  136. package/packs/onboard/commands/onboard.md +313 -0
  137. package/packs/onboard/skills/onboard-context-provider/SKILL.md +98 -0
  138. package/packs/tanstack-router/.claude-plugin/plugin.json +14 -0
  139. package/packs/tanstack-router/CHANGELOG.md +30 -0
  140. package/packs/tanstack-router/README.md +113 -0
  141. package/packs/tanstack-router/agents/tanstack-architect.md +173 -0
  142. package/packs/tanstack-router/agents/tanstack-builder.md +360 -0
  143. package/packs/tanstack-router/agents/tanstack-tester.md +454 -0
  144. package/packs/tanstack-router/commands/form-create.md +313 -0
  145. package/packs/tanstack-router/commands/query-create.md +263 -0
  146. package/packs/tanstack-router/commands/route-create.md +190 -0
  147. package/packs/tanstack-router/commands/table-create.md +413 -0
  148. package/packs/tanstack-router/skills/ai-patterns/SKILL.md +370 -0
  149. package/packs/tanstack-router/skills/db-patterns/SKILL.md +346 -0
  150. package/packs/tanstack-router/skills/devtools-patterns/SKILL.md +415 -0
  151. package/packs/tanstack-router/skills/form-patterns/SKILL.md +425 -0
  152. package/packs/tanstack-router/skills/pacer-patterns/SKILL.md +341 -0
  153. package/packs/tanstack-router/skills/query-patterns/SKILL.md +359 -0
  154. package/packs/tanstack-router/skills/router-patterns/SKILL.md +285 -0
  155. package/packs/tanstack-router/skills/store-patterns/SKILL.md +351 -0
  156. package/packs/tanstack-router/skills/table-patterns/SKILL.md +531 -0
  157. package/packs/tanstack-router/skills/tanstack-conventions/SKILL.md +428 -0
  158. package/packs/tanstack-router/skills/virtual-patterns/SKILL.md +490 -0
  159. package/packs/worktree/.claude-plugin/plugin.json +19 -0
  160. package/packs/worktree/CHANGELOG.md +24 -0
  161. package/packs/worktree/README.md +110 -0
  162. package/packs/worktree/commands/wt.md +73 -0
  163. package/packs/worktree/scripts/wt.sh +396 -0
  164. package/packs/worktree/skills/worktree-manager/SKILL.md +68 -0
@@ -0,0 +1,490 @@
1
+ ---
2
+ name: TanStack Virtual Patterns
3
+ description: >-
4
+ Auto-enforce TanStack Virtual best practices for list virtualization. Activates
5
+ when implementing large lists, infinite scroll, virtualized grids, or performance
6
+ optimization for long lists in React applications.
7
+ version: 1.0.0
8
+ ---
9
+
10
+ # TanStack Virtual Patterns
11
+
12
+ This skill enforces TanStack Virtual best practices for efficient rendering of large lists.
13
+
14
+ ## Basic Virtual List
15
+
16
+ ```typescript
17
+ import { useVirtualizer } from '@tanstack/react-virtual'
18
+ import { useRef } from 'react'
19
+
20
+ interface VirtualListProps<T> {
21
+ items: T[]
22
+ renderItem: (item: T, index: number) => React.ReactNode
23
+ estimateSize?: number
24
+ }
25
+
26
+ export function VirtualList<T>({
27
+ items,
28
+ renderItem,
29
+ estimateSize = 50,
30
+ }: VirtualListProps<T>) {
31
+ const parentRef = useRef<HTMLDivElement>(null)
32
+
33
+ const virtualizer = useVirtualizer({
34
+ count: items.length,
35
+ getScrollElement: () => parentRef.current,
36
+ estimateSize: () => estimateSize,
37
+ overscan: 5,
38
+ })
39
+
40
+ return (
41
+ <div
42
+ ref={parentRef}
43
+ className="h-[400px] overflow-auto"
44
+ >
45
+ <div
46
+ style={{
47
+ height: `${virtualizer.getTotalSize()}px`,
48
+ width: '100%',
49
+ position: 'relative',
50
+ }}
51
+ >
52
+ {virtualizer.getVirtualItems().map((virtualItem) => (
53
+ <div
54
+ key={virtualItem.key}
55
+ style={{
56
+ position: 'absolute',
57
+ top: 0,
58
+ left: 0,
59
+ width: '100%',
60
+ height: `${virtualItem.size}px`,
61
+ transform: `translateY(${virtualItem.start}px)`,
62
+ }}
63
+ >
64
+ {renderItem(items[virtualItem.index], virtualItem.index)}
65
+ </div>
66
+ ))}
67
+ </div>
68
+ </div>
69
+ )
70
+ }
71
+ ```
72
+
73
+ ## Dynamic Size Virtual List
74
+
75
+ ```typescript
76
+ import { useVirtualizer } from '@tanstack/react-virtual'
77
+ import { useRef, useCallback } from 'react'
78
+
79
+ export function DynamicVirtualList({ items }: { items: Post[] }) {
80
+ const parentRef = useRef<HTMLDivElement>(null)
81
+
82
+ const virtualizer = useVirtualizer({
83
+ count: items.length,
84
+ getScrollElement: () => parentRef.current,
85
+ estimateSize: () => 100, // Estimated height
86
+ measureElement: (element) => element.getBoundingClientRect().height,
87
+ })
88
+
89
+ return (
90
+ <div ref={parentRef} className="h-[600px] overflow-auto">
91
+ <div
92
+ style={{
93
+ height: `${virtualizer.getTotalSize()}px`,
94
+ position: 'relative',
95
+ }}
96
+ >
97
+ {virtualizer.getVirtualItems().map((virtualItem) => (
98
+ <div
99
+ key={virtualItem.key}
100
+ data-index={virtualItem.index}
101
+ ref={virtualizer.measureElement}
102
+ style={{
103
+ position: 'absolute',
104
+ top: 0,
105
+ left: 0,
106
+ width: '100%',
107
+ transform: `translateY(${virtualItem.start}px)`,
108
+ }}
109
+ >
110
+ <PostCard post={items[virtualItem.index]} />
111
+ </div>
112
+ ))}
113
+ </div>
114
+ </div>
115
+ )
116
+ }
117
+ ```
118
+
119
+ ## Virtual Grid
120
+
121
+ ```typescript
122
+ import { useVirtualizer } from '@tanstack/react-virtual'
123
+ import { useRef } from 'react'
124
+
125
+ interface VirtualGridProps<T> {
126
+ items: T[]
127
+ columns: number
128
+ renderItem: (item: T, index: number) => React.ReactNode
129
+ rowHeight?: number
130
+ }
131
+
132
+ export function VirtualGrid<T>({
133
+ items,
134
+ columns,
135
+ renderItem,
136
+ rowHeight = 200,
137
+ }: VirtualGridProps<T>) {
138
+ const parentRef = useRef<HTMLDivElement>(null)
139
+ const rowCount = Math.ceil(items.length / columns)
140
+
141
+ const rowVirtualizer = useVirtualizer({
142
+ count: rowCount,
143
+ getScrollElement: () => parentRef.current,
144
+ estimateSize: () => rowHeight,
145
+ overscan: 2,
146
+ })
147
+
148
+ return (
149
+ <div ref={parentRef} className="h-[600px] overflow-auto">
150
+ <div
151
+ style={{
152
+ height: `${rowVirtualizer.getTotalSize()}px`,
153
+ position: 'relative',
154
+ }}
155
+ >
156
+ {rowVirtualizer.getVirtualItems().map((virtualRow) => {
157
+ const startIndex = virtualRow.index * columns
158
+ const rowItems = items.slice(startIndex, startIndex + columns)
159
+
160
+ return (
161
+ <div
162
+ key={virtualRow.key}
163
+ style={{
164
+ position: 'absolute',
165
+ top: 0,
166
+ left: 0,
167
+ width: '100%',
168
+ height: `${virtualRow.size}px`,
169
+ transform: `translateY(${virtualRow.start}px)`,
170
+ display: 'grid',
171
+ gridTemplateColumns: `repeat(${columns}, 1fr)`,
172
+ gap: '1rem',
173
+ }}
174
+ >
175
+ {rowItems.map((item, i) => (
176
+ <div key={startIndex + i}>
177
+ {renderItem(item, startIndex + i)}
178
+ </div>
179
+ ))}
180
+ </div>
181
+ )
182
+ })}
183
+ </div>
184
+ </div>
185
+ )
186
+ }
187
+ ```
188
+
189
+ ## Infinite Scroll with Virtual List
190
+
191
+ ```typescript
192
+ import { useVirtualizer } from '@tanstack/react-virtual'
193
+ import { useInfiniteQuery } from '@tanstack/react-query'
194
+ import { useRef, useEffect } from 'react'
195
+ import { queryKeys } from '@/lib/query-keys'
196
+
197
+ export function InfiniteVirtualList() {
198
+ const parentRef = useRef<HTMLDivElement>(null)
199
+
200
+ const {
201
+ data,
202
+ fetchNextPage,
203
+ hasNextPage,
204
+ isFetchingNextPage,
205
+ } = useInfiniteQuery({
206
+ queryKey: queryKeys.posts.list({ infinite: true }),
207
+ queryFn: ({ pageParam = 1 }) => postApi.getPosts({ page: pageParam }),
208
+ getNextPageParam: (lastPage) =>
209
+ lastPage.hasMore ? lastPage.nextPage : undefined,
210
+ initialPageParam: 1,
211
+ })
212
+
213
+ const allItems = data?.pages.flatMap((page) => page.items) ?? []
214
+
215
+ const virtualizer = useVirtualizer({
216
+ count: hasNextPage ? allItems.length + 1 : allItems.length,
217
+ getScrollElement: () => parentRef.current,
218
+ estimateSize: () => 80,
219
+ overscan: 5,
220
+ })
221
+
222
+ const virtualItems = virtualizer.getVirtualItems()
223
+
224
+ // Load more when reaching the end
225
+ useEffect(() => {
226
+ const lastItem = virtualItems[virtualItems.length - 1]
227
+ if (!lastItem) return
228
+
229
+ if (
230
+ lastItem.index >= allItems.length - 1 &&
231
+ hasNextPage &&
232
+ !isFetchingNextPage
233
+ ) {
234
+ fetchNextPage()
235
+ }
236
+ }, [virtualItems, hasNextPage, isFetchingNextPage, allItems.length, fetchNextPage])
237
+
238
+ return (
239
+ <div ref={parentRef} className="h-[600px] overflow-auto">
240
+ <div
241
+ style={{
242
+ height: `${virtualizer.getTotalSize()}px`,
243
+ position: 'relative',
244
+ }}
245
+ >
246
+ {virtualItems.map((virtualItem) => {
247
+ const isLoader = virtualItem.index >= allItems.length
248
+
249
+ return (
250
+ <div
251
+ key={virtualItem.key}
252
+ style={{
253
+ position: 'absolute',
254
+ top: 0,
255
+ left: 0,
256
+ width: '100%',
257
+ height: `${virtualItem.size}px`,
258
+ transform: `translateY(${virtualItem.start}px)`,
259
+ }}
260
+ >
261
+ {isLoader ? (
262
+ <div className="flex items-center justify-center h-full">
263
+ Loading more...
264
+ </div>
265
+ ) : (
266
+ <PostCard post={allItems[virtualItem.index]} />
267
+ )}
268
+ </div>
269
+ )
270
+ })}
271
+ </div>
272
+ </div>
273
+ )
274
+ }
275
+ ```
276
+
277
+ ## Horizontal Virtual List
278
+
279
+ ```typescript
280
+ import { useVirtualizer } from '@tanstack/react-virtual'
281
+ import { useRef } from 'react'
282
+
283
+ export function HorizontalVirtualList({ items }: { items: Image[] }) {
284
+ const parentRef = useRef<HTMLDivElement>(null)
285
+
286
+ const virtualizer = useVirtualizer({
287
+ horizontal: true,
288
+ count: items.length,
289
+ getScrollElement: () => parentRef.current,
290
+ estimateSize: () => 200,
291
+ overscan: 3,
292
+ })
293
+
294
+ return (
295
+ <div ref={parentRef} className="w-full overflow-x-auto">
296
+ <div
297
+ style={{
298
+ width: `${virtualizer.getTotalSize()}px`,
299
+ height: '200px',
300
+ position: 'relative',
301
+ }}
302
+ >
303
+ {virtualizer.getVirtualItems().map((virtualItem) => (
304
+ <div
305
+ key={virtualItem.key}
306
+ style={{
307
+ position: 'absolute',
308
+ top: 0,
309
+ left: 0,
310
+ height: '100%',
311
+ width: `${virtualItem.size}px`,
312
+ transform: `translateX(${virtualItem.start}px)`,
313
+ }}
314
+ >
315
+ <img
316
+ src={items[virtualItem.index].url}
317
+ alt={items[virtualItem.index].alt}
318
+ className="h-full w-full object-cover"
319
+ />
320
+ </div>
321
+ ))}
322
+ </div>
323
+ </div>
324
+ )
325
+ }
326
+ ```
327
+
328
+ ## Virtual Table (with TanStack Table)
329
+
330
+ ```typescript
331
+ import { useVirtualizer } from '@tanstack/react-virtual'
332
+ import { useReactTable, getCoreRowModel, flexRender } from '@tanstack/react-table'
333
+ import { useRef } from 'react'
334
+
335
+ export function VirtualTable<T>({
336
+ data,
337
+ columns,
338
+ }: {
339
+ data: T[]
340
+ columns: ColumnDef<T>[]
341
+ }) {
342
+ const parentRef = useRef<HTMLDivElement>(null)
343
+
344
+ const table = useReactTable({
345
+ data,
346
+ columns,
347
+ getCoreRowModel: getCoreRowModel(),
348
+ })
349
+
350
+ const { rows } = table.getRowModel()
351
+
352
+ const virtualizer = useVirtualizer({
353
+ count: rows.length,
354
+ getScrollElement: () => parentRef.current,
355
+ estimateSize: () => 50,
356
+ overscan: 10,
357
+ })
358
+
359
+ return (
360
+ <div ref={parentRef} className="h-[600px] overflow-auto">
361
+ <table className="w-full">
362
+ <thead className="sticky top-0 bg-white z-10">
363
+ {table.getHeaderGroups().map((headerGroup) => (
364
+ <tr key={headerGroup.id}>
365
+ {headerGroup.headers.map((header) => (
366
+ <th key={header.id}>
367
+ {flexRender(header.column.columnDef.header, header.getContext())}
368
+ </th>
369
+ ))}
370
+ </tr>
371
+ ))}
372
+ </thead>
373
+ <tbody>
374
+ <tr style={{ height: `${virtualizer.getTotalSize()}px` }}>
375
+ <td colSpan={columns.length} style={{ padding: 0 }}>
376
+ <div style={{ position: 'relative' }}>
377
+ {virtualizer.getVirtualItems().map((virtualRow) => {
378
+ const row = rows[virtualRow.index]
379
+ return (
380
+ <div
381
+ key={row.id}
382
+ style={{
383
+ position: 'absolute',
384
+ top: 0,
385
+ left: 0,
386
+ width: '100%',
387
+ height: `${virtualRow.size}px`,
388
+ transform: `translateY(${virtualRow.start}px)`,
389
+ display: 'flex',
390
+ }}
391
+ >
392
+ {row.getVisibleCells().map((cell) => (
393
+ <div key={cell.id} className="flex-1 px-4 py-2">
394
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
395
+ </div>
396
+ ))}
397
+ </div>
398
+ )
399
+ })}
400
+ </div>
401
+ </td>
402
+ </tr>
403
+ </tbody>
404
+ </table>
405
+ </div>
406
+ )
407
+ }
408
+ ```
409
+
410
+ ## Scroll to Index
411
+
412
+ ```typescript
413
+ export function ScrollableVirtualList({ items }: { items: Post[] }) {
414
+ const parentRef = useRef<HTMLDivElement>(null)
415
+
416
+ const virtualizer = useVirtualizer({
417
+ count: items.length,
418
+ getScrollElement: () => parentRef.current,
419
+ estimateSize: () => 50,
420
+ })
421
+
422
+ const scrollToItem = (index: number) => {
423
+ virtualizer.scrollToIndex(index, { align: 'center', behavior: 'smooth' })
424
+ }
425
+
426
+ return (
427
+ <div>
428
+ <div className="flex gap-2 mb-4">
429
+ <button onClick={() => scrollToItem(0)}>First</button>
430
+ <button onClick={() => scrollToItem(Math.floor(items.length / 2))}>
431
+ Middle
432
+ </button>
433
+ <button onClick={() => scrollToItem(items.length - 1)}>Last</button>
434
+ </div>
435
+ <div ref={parentRef} className="h-[400px] overflow-auto">
436
+ {/* Virtual list content */}
437
+ </div>
438
+ </div>
439
+ )
440
+ }
441
+ ```
442
+
443
+ ## Conventions to Enforce
444
+
445
+ 1. **Ref for scroll element** - Always use `useRef` for parent container
446
+ 2. **Fixed height container** - Parent must have defined height/overflow
447
+ 3. **Overscan** - Include 3-5 items for smooth scrolling
448
+ 4. **Absolute positioning** - Use transform for item placement
449
+ 5. **Stable keys** - Use virtualItem.key, not index
450
+ 6. **Dynamic sizing** - Use `measureElement` for variable heights
451
+ 7. **Combine with Query** - Use infinite queries for data loading
452
+
453
+ ## Anti-Patterns to Block
454
+
455
+ ```typescript
456
+ // ❌ WRONG: No fixed height container
457
+ <div ref={parentRef}>
458
+ {virtualItems.map(...)}
459
+ </div>
460
+
461
+ // ✅ CORRECT: Fixed height with overflow
462
+ <div ref={parentRef} className="h-[400px] overflow-auto">
463
+ {virtualItems.map(...)}
464
+ </div>
465
+
466
+ // ❌ WRONG: Using index as key
467
+ {virtualItems.map((item, index) => (
468
+ <div key={index}>...</div>
469
+ ))}
470
+
471
+ // ✅ CORRECT: Using virtualItem.key
472
+ {virtualItems.map((virtualItem) => (
473
+ <div key={virtualItem.key}>...</div>
474
+ ))}
475
+
476
+ // ❌ WRONG: No overscan
477
+ const virtualizer = useVirtualizer({
478
+ count: items.length,
479
+ getScrollElement: () => parentRef.current,
480
+ estimateSize: () => 50,
481
+ })
482
+
483
+ // ✅ CORRECT: Include overscan
484
+ const virtualizer = useVirtualizer({
485
+ count: items.length,
486
+ getScrollElement: () => parentRef.current,
487
+ estimateSize: () => 50,
488
+ overscan: 5,
489
+ })
490
+ ```
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "worktree",
3
+ "version": "0.1.0",
4
+ "description": "Git worktree manager for parallel development with automatic env copying and dependency installation",
5
+ "author": {
6
+ "name": "Smicolon",
7
+ "email": "dev@smicolon.com",
8
+ "url": "https://github.com/smicolon"
9
+ },
10
+ "license": "MIT",
11
+ "repository": "https://github.com/smicolon/ai-kit",
12
+ "keywords": [
13
+ "git",
14
+ "worktree",
15
+ "parallel-development",
16
+ "branch-management",
17
+ "monorepo"
18
+ ]
19
+ }
@@ -0,0 +1,24 @@
1
+ # Changelog
2
+
3
+ All notable changes to smi-worktree will be documented in this file.
4
+
5
+ ## [Unreleased]
6
+
7
+ ### Changed
8
+ - Renamed from `smi-worktree` to `worktree` as part of ai-kit migration
9
+ - Moved from `plugins/smi-worktree/` to `packs/worktree/`
10
+
11
+ ## [0.1.0] - 2026-01-17
12
+
13
+ ### Added
14
+
15
+ - Initial release
16
+ - `/wt create` command with auto-setup (env copying, dep install)
17
+ - `/wt list` command to show all worktrees
18
+ - `/wt remove` command with optional branch deletion
19
+ - `/wt open` command for Cursor/VS Code integration
20
+ - Short aliases: `c`, `ls`, `rm`, `o`
21
+ - Package manager detection (bun, pnpm, yarn, npm)
22
+ - Monorepo detection (workspaces, turbo, nx, lerna)
23
+ - Nested `.env*` file copying for monorepos
24
+ - worktree-manager skill for auto-triggering
@@ -0,0 +1,110 @@
1
+ # worktree
2
+
3
+ Git worktree manager for parallel development with automatic environment setup.
4
+
5
+ ## Features
6
+
7
+ - **Sibling naming**: `project--branch-name/` convention
8
+ - **Auto env copy**: Copies `.env*` from root and nested directories
9
+ - **Package manager detection**: bun → pnpm → yarn → npm
10
+ - **Monorepo aware**: Detects workspaces, turbo, nx, lerna
11
+ - **Editor integration**: Open in Cursor, Antigravity, or VS Code
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ /plugin install worktree
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ ### Create Worktree
22
+
23
+ ```bash
24
+ /wt create feature/authentication
25
+ /wt c feat-payments # short form
26
+ ```
27
+
28
+ Creates worktree at `~/code/project--feature-authentication/` with:
29
+ - All `.env*` files copied
30
+ - Dependencies installed
31
+
32
+ ### List Worktrees
33
+
34
+ ```bash
35
+ /wt list
36
+ /wt ls # short form
37
+ ```
38
+
39
+ ### Remove Worktree
40
+
41
+ ```bash
42
+ /wt remove feature/authentication
43
+ /wt rm feat-payments -d # also delete branch
44
+ ```
45
+
46
+ ### Open in Editor
47
+
48
+ ```bash
49
+ /wt open feat-payments # auto-detect
50
+ /wt o feat-payments # short form
51
+ /wt o feat-payments --cursor # or -c
52
+ /wt o feat-payments --agy # or -a
53
+ /wt o feat-payments --code # or -v
54
+ ```
55
+
56
+ ### Set Default Editor
57
+
58
+ Add to your shell profile (`~/.zshrc` or `~/.bashrc`):
59
+
60
+ ```bash
61
+ export WT_EDITOR=agy # cursor, agy, or code
62
+ ```
63
+
64
+ Priority: flag > `WT_EDITOR` > auto-detect (Cursor → Antigravity → VS Code)
65
+
66
+ ## Naming Convention
67
+
68
+ ```
69
+ ~/code/retail-plus/ # main repo
70
+ ~/code/retail-plus--feat-auth/ # worktree (sibling with --)
71
+ ~/code/retail-plus--fix-bug-123/ # another worktree
72
+ ```
73
+
74
+ ## Auto-Setup Details
75
+
76
+ ### Environment Files
77
+
78
+ Copies from:
79
+ - Root: `.env`, `.env.local`, `.env.development`, etc.
80
+ - Nested: `apps/*/.env*`, `packages/*/.env*`, `services/*/.env*`
81
+
82
+ ### Package Manager Detection
83
+
84
+ Checks in order:
85
+ 1. `bun.lockb` or `bun.lock` → `bun install`
86
+ 2. `pnpm-lock.yaml` → `pnpm install`
87
+ 3. `yarn.lock` → `yarn install`
88
+ 4. `package-lock.json` or `package.json` → `npm install`
89
+
90
+ ### Monorepo Detection
91
+
92
+ Detects via:
93
+ - `pnpm-workspace.yaml`
94
+ - `turbo.json`
95
+ - `nx.json`
96
+ - `lerna.json`
97
+ - `"workspaces"` in `package.json`
98
+
99
+ ## Skill Triggers
100
+
101
+ The worktree-manager skill auto-activates when you mention:
102
+ - "worktree" or "git worktree"
103
+ - "parallel development"
104
+ - "feature branch setup"
105
+ - "work on multiple branches"
106
+ - "separate workspace for branch"
107
+
108
+ ## License
109
+
110
+ MIT
@@ -0,0 +1,73 @@
1
+ ---
2
+ name: wt
3
+ description: Git worktree manager - create, list, remove, and open worktrees with automatic env copying and dependency installation
4
+ argument-hint: '<command> [branch] [options]'
5
+ allowed-tools: ["Bash(${CLAUDE_PLUGIN_ROOT}/scripts/wt.sh:*)"]
6
+ ---
7
+
8
+ # Git Worktree Manager
9
+
10
+ Manage git worktrees with automatic setup for parallel development.
11
+
12
+ ## Usage
13
+
14
+ ```bash
15
+ /wt <command> [args]
16
+ ```
17
+
18
+ ## Commands
19
+
20
+ | Command | Alias | Description |
21
+ |---------|-------|-------------|
22
+ | `create <branch>` | `c` | Create worktree, copy .env files, install deps |
23
+ | `list` | `ls` | List all worktrees for current repo |
24
+ | `remove <branch>` | `rm` | Remove worktree (add `-d` to delete branch) |
25
+ | `open <branch> [--editor]` | `o` | Open worktree (--cursor\|-c, --agy\|-a, --code\|-v) |
26
+
27
+ ## Instructions
28
+
29
+ Run the worktree manager script:
30
+
31
+ ```!
32
+ "${CLAUDE_PLUGIN_ROOT}/scripts/wt.sh" $ARGUMENTS
33
+ ```
34
+
35
+ ## Examples
36
+
37
+ ```bash
38
+ # Create worktree for new feature
39
+ /wt create feature/authentication
40
+
41
+ # Short form
42
+ /wt c feat-payments
43
+
44
+ # List all worktrees
45
+ /wt ls
46
+
47
+ # Remove worktree
48
+ /wt rm feature/authentication
49
+
50
+ # Remove worktree AND delete branch
51
+ /wt rm feat-payments -d
52
+
53
+ # Open in editor (auto-detect)
54
+ /wt o feat-payments
55
+
56
+ # Open in specific editor
57
+ /wt o feat-payments --agy
58
+ /wt o feat-payments -c
59
+ ```
60
+
61
+ ## Naming Convention
62
+
63
+ ```
64
+ ~/code/retail-plus/ → main repo
65
+ ~/code/retail-plus--feat-auth/ → worktree (sibling with --)
66
+ ```
67
+
68
+ ## Auto-Setup on Create
69
+
70
+ 1. Copies all `.env*` files from root
71
+ 2. Copies nested `.env*` from `apps/*/`, `packages/*/`, `services/*/`
72
+ 3. Detects package manager (bun → pnpm → yarn → npm)
73
+ 4. Runs install at root (monorepo-aware)