@dealdeploy/skl 0.1.7 → 0.1.8

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/.agents/skills/opentui/SKILL.md +198 -0
  2. package/.agents/skills/opentui/references/animation/REFERENCE.md +431 -0
  3. package/.agents/skills/opentui/references/components/REFERENCE.md +143 -0
  4. package/.agents/skills/opentui/references/components/code-diff.md +496 -0
  5. package/.agents/skills/opentui/references/components/containers.md +412 -0
  6. package/.agents/skills/opentui/references/components/inputs.md +531 -0
  7. package/.agents/skills/opentui/references/components/text-display.md +384 -0
  8. package/.agents/skills/opentui/references/core/REFERENCE.md +145 -0
  9. package/.agents/skills/opentui/references/core/api.md +506 -0
  10. package/.agents/skills/opentui/references/core/configuration.md +166 -0
  11. package/.agents/skills/opentui/references/core/gotchas.md +393 -0
  12. package/.agents/skills/opentui/references/core/patterns.md +448 -0
  13. package/.agents/skills/opentui/references/keyboard/REFERENCE.md +511 -0
  14. package/.agents/skills/opentui/references/layout/REFERENCE.md +337 -0
  15. package/.agents/skills/opentui/references/layout/patterns.md +444 -0
  16. package/.agents/skills/opentui/references/react/REFERENCE.md +174 -0
  17. package/.agents/skills/opentui/references/react/api.md +435 -0
  18. package/.agents/skills/opentui/references/react/configuration.md +301 -0
  19. package/.agents/skills/opentui/references/react/gotchas.md +443 -0
  20. package/.agents/skills/opentui/references/react/patterns.md +501 -0
  21. package/.agents/skills/opentui/references/solid/REFERENCE.md +201 -0
  22. package/.agents/skills/opentui/references/solid/api.md +543 -0
  23. package/.agents/skills/opentui/references/solid/configuration.md +315 -0
  24. package/.agents/skills/opentui/references/solid/gotchas.md +415 -0
  25. package/.agents/skills/opentui/references/solid/patterns.md +558 -0
  26. package/.agents/skills/opentui/references/testing/REFERENCE.md +614 -0
  27. package/.claude/settings.local.json +11 -0
  28. package/.claude/skills/opentui/SKILL.md +198 -0
  29. package/.claude/skills/opentui/references/animation/REFERENCE.md +431 -0
  30. package/.claude/skills/opentui/references/components/REFERENCE.md +143 -0
  31. package/.claude/skills/opentui/references/components/code-diff.md +496 -0
  32. package/.claude/skills/opentui/references/components/containers.md +412 -0
  33. package/.claude/skills/opentui/references/components/inputs.md +531 -0
  34. package/.claude/skills/opentui/references/components/text-display.md +384 -0
  35. package/.claude/skills/opentui/references/core/REFERENCE.md +145 -0
  36. package/.claude/skills/opentui/references/core/api.md +506 -0
  37. package/.claude/skills/opentui/references/core/configuration.md +166 -0
  38. package/.claude/skills/opentui/references/core/gotchas.md +393 -0
  39. package/.claude/skills/opentui/references/core/patterns.md +448 -0
  40. package/.claude/skills/opentui/references/keyboard/REFERENCE.md +511 -0
  41. package/.claude/skills/opentui/references/layout/REFERENCE.md +337 -0
  42. package/.claude/skills/opentui/references/layout/patterns.md +444 -0
  43. package/.claude/skills/opentui/references/react/REFERENCE.md +174 -0
  44. package/.claude/skills/opentui/references/react/api.md +435 -0
  45. package/.claude/skills/opentui/references/react/configuration.md +301 -0
  46. package/.claude/skills/opentui/references/react/gotchas.md +443 -0
  47. package/.claude/skills/opentui/references/react/patterns.md +501 -0
  48. package/.claude/skills/opentui/references/solid/REFERENCE.md +201 -0
  49. package/.claude/skills/opentui/references/solid/api.md +543 -0
  50. package/.claude/skills/opentui/references/solid/configuration.md +315 -0
  51. package/.claude/skills/opentui/references/solid/gotchas.md +415 -0
  52. package/.claude/skills/opentui/references/solid/patterns.md +558 -0
  53. package/.claude/skills/opentui/references/testing/REFERENCE.md +614 -0
  54. package/bun.lock +0 -1
  55. package/index.ts +163 -38
  56. package/package.json +1 -1
  57. package/update.ts +87 -0
@@ -0,0 +1,558 @@
1
+ # Solid Patterns
2
+
3
+ ## Reactive State
4
+
5
+ ### Signals
6
+
7
+ Basic reactive state with signals:
8
+
9
+ ```tsx
10
+ import { createSignal } from "solid-js"
11
+
12
+ function Counter() {
13
+ const [count, setCount] = createSignal(0)
14
+
15
+ return (
16
+ <box flexDirection="row" gap={2}>
17
+ <text>Count: {count()}</text>
18
+ <box border onMouseDown={() => setCount(c => c - 1)}>
19
+ <text>-</text>
20
+ </box>
21
+ <box border onMouseDown={() => setCount(c => c + 1)}>
22
+ <text>+</text>
23
+ </box>
24
+ </box>
25
+ )
26
+ }
27
+ ```
28
+
29
+ ### Derived State
30
+
31
+ Compute values from signals:
32
+
33
+ ```tsx
34
+ import { createSignal, createMemo } from "solid-js"
35
+
36
+ function PriceCalculator() {
37
+ const [quantity, setQuantity] = createSignal(1)
38
+ const [price, setPrice] = createSignal(9.99)
39
+
40
+ // Derived value - only recalculates when dependencies change
41
+ const total = createMemo(() => quantity() * price())
42
+ const formatted = createMemo(() => `$${total().toFixed(2)}`)
43
+
44
+ return (
45
+ <box flexDirection="column">
46
+ <text>Quantity: {quantity()}</text>
47
+ <text>Price: ${price()}</text>
48
+ <text>Total: {formatted()}</text>
49
+ </box>
50
+ )
51
+ }
52
+ ```
53
+
54
+ ### Effects
55
+
56
+ React to state changes:
57
+
58
+ ```tsx
59
+ import { createSignal, createEffect, onCleanup } from "solid-js"
60
+
61
+ function AutoSave() {
62
+ const [content, setContent] = createSignal("")
63
+
64
+ createEffect(() => {
65
+ const text = content()
66
+
67
+ // Debounced save
68
+ const timeout = setTimeout(() => {
69
+ saveToFile(text)
70
+ }, 1000)
71
+
72
+ // Cleanup on next run or disposal
73
+ onCleanup(() => clearTimeout(timeout))
74
+ })
75
+
76
+ return (
77
+ <textarea
78
+ value={content()}
79
+ onInput={setContent}
80
+ placeholder="Auto-saves after 1 second..."
81
+ />
82
+ )
83
+ }
84
+ ```
85
+
86
+ ## Stores
87
+
88
+ ### createStore for Complex State
89
+
90
+ ```tsx
91
+ import { createStore } from "solid-js/store"
92
+
93
+ interface AppState {
94
+ user: { name: string; email: string } | null
95
+ items: Array<{ id: number; name: string; done: boolean }>
96
+ settings: { theme: "dark" | "light" }
97
+ }
98
+
99
+ function App() {
100
+ const [state, setState] = createStore<AppState>({
101
+ user: null,
102
+ items: [],
103
+ settings: { theme: "dark" },
104
+ })
105
+
106
+ const addItem = (name: string) => {
107
+ setState("items", items => [
108
+ ...items,
109
+ { id: Date.now(), name, done: false }
110
+ ])
111
+ }
112
+
113
+ const toggleItem = (id: number) => {
114
+ setState("items", item => item.id === id, "done", done => !done)
115
+ }
116
+
117
+ const setTheme = (theme: "dark" | "light") => {
118
+ setState("settings", "theme", theme)
119
+ }
120
+
121
+ return (
122
+ <box backgroundColor={state.settings.theme === "dark" ? "#1a1a2e" : "#f0f0f0"}>
123
+ <For each={state.items}>
124
+ {(item) => (
125
+ <text
126
+ fg={item.done ? "#888" : "#fff"}
127
+ onMouseDown={() => toggleItem(item.id)}
128
+ >
129
+ {item.done ? "[x]" : "[ ]"} {item.name}
130
+ </text>
131
+ )}
132
+ </For>
133
+ </box>
134
+ )
135
+ }
136
+ ```
137
+
138
+ ### Store with Context
139
+
140
+ Share state across components:
141
+
142
+ ```tsx
143
+ import { createStore } from "solid-js/store"
144
+ import { createContext, useContext, ParentComponent } from "solid-js"
145
+
146
+ interface Store {
147
+ count: number
148
+ items: string[]
149
+ }
150
+
151
+ type StoreContextValue = [
152
+ Store,
153
+ {
154
+ increment: () => void
155
+ addItem: (item: string) => void
156
+ }
157
+ ]
158
+
159
+ const StoreContext = createContext<StoreContextValue>()
160
+
161
+ const StoreProvider: ParentComponent = (props) => {
162
+ const [state, setState] = createStore<Store>({
163
+ count: 0,
164
+ items: [],
165
+ })
166
+
167
+ const actions = {
168
+ increment: () => setState("count", c => c + 1),
169
+ addItem: (item: string) => setState("items", i => [...i, item]),
170
+ }
171
+
172
+ return (
173
+ <StoreContext.Provider value={[state, actions]}>
174
+ {props.children}
175
+ </StoreContext.Provider>
176
+ )
177
+ }
178
+
179
+ function useStore() {
180
+ const context = useContext(StoreContext)
181
+ if (!context) throw new Error("useStore must be used within StoreProvider")
182
+ return context
183
+ }
184
+
185
+ // Usage
186
+ function Counter() {
187
+ const [state, { increment }] = useStore()
188
+ return (
189
+ <box onMouseDown={increment}>
190
+ <text>Count: {state.count}</text>
191
+ </box>
192
+ )
193
+ }
194
+ ```
195
+
196
+ ## Control Flow
197
+
198
+ ### Conditional Rendering with Show
199
+
200
+ ```tsx
201
+ import { Show, createSignal } from "solid-js"
202
+
203
+ function ToggleableContent() {
204
+ const [visible, setVisible] = createSignal(false)
205
+
206
+ return (
207
+ <box flexDirection="column">
208
+ <box border onMouseDown={() => setVisible(v => !v)}>
209
+ <text>Toggle</text>
210
+ </box>
211
+
212
+ <Show
213
+ when={visible()}
214
+ fallback={<text fg="#888">Content is hidden</text>}
215
+ >
216
+ <text fg="#0f0">Content is visible!</text>
217
+ </Show>
218
+ </box>
219
+ )
220
+ }
221
+ ```
222
+
223
+ ### Lists with For
224
+
225
+ ```tsx
226
+ import { For, createSignal } from "solid-js"
227
+
228
+ function TodoList() {
229
+ const [todos, setTodos] = createSignal([
230
+ { id: 1, text: "Learn Solid", done: false },
231
+ { id: 2, text: "Build TUI", done: false },
232
+ ])
233
+
234
+ const toggle = (id: number) => {
235
+ setTodos(todos =>
236
+ todos.map(t =>
237
+ t.id === id ? { ...t, done: !t.done } : t
238
+ )
239
+ )
240
+ }
241
+
242
+ return (
243
+ <box flexDirection="column">
244
+ <For each={todos()}>
245
+ {(todo) => (
246
+ <box onMouseDown={() => toggle(todo.id)}>
247
+ <text fg={todo.done ? "#888" : "#fff"}>
248
+ {todo.done ? "[x]" : "[ ]"} {todo.text}
249
+ </text>
250
+ </box>
251
+ )}
252
+ </For>
253
+ </box>
254
+ )
255
+ }
256
+ ```
257
+
258
+ ### Index for Primitive Arrays
259
+
260
+ Use `Index` when array items are primitives:
261
+
262
+ ```tsx
263
+ import { Index, createSignal } from "solid-js"
264
+
265
+ function StringList() {
266
+ const [items, setItems] = createSignal(["apple", "banana", "cherry"])
267
+
268
+ return (
269
+ <box flexDirection="column">
270
+ <Index each={items()}>
271
+ {(item, index) => (
272
+ <text>{index}: {item()}</text>
273
+ )}
274
+ </Index>
275
+ </box>
276
+ )
277
+ }
278
+ ```
279
+
280
+ ### Switch/Match for Multiple Conditions
281
+
282
+ ```tsx
283
+ import { Switch, Match, createSignal } from "solid-js"
284
+
285
+ type Status = "idle" | "loading" | "success" | "error"
286
+
287
+ function StatusDisplay() {
288
+ const [status, setStatus] = createSignal<Status>("idle")
289
+
290
+ return (
291
+ <Switch>
292
+ <Match when={status() === "idle"}>
293
+ <text>Ready</text>
294
+ </Match>
295
+ <Match when={status() === "loading"}>
296
+ <text fg="#ff0">Loading...</text>
297
+ </Match>
298
+ <Match when={status() === "success"}>
299
+ <text fg="#0f0">Success!</text>
300
+ </Match>
301
+ <Match when={status() === "error"}>
302
+ <text fg="#f00">Error occurred</text>
303
+ </Match>
304
+ </Switch>
305
+ )
306
+ }
307
+ ```
308
+
309
+ ## Focus Management
310
+
311
+ ### Focus State
312
+
313
+ ```tsx
314
+ import { createSignal } from "solid-js"
315
+ import { useKeyboard } from "@opentui/solid"
316
+
317
+ function FocusableForm() {
318
+ const [focusIndex, setFocusIndex] = createSignal(0)
319
+ const fields = ["name", "email", "message"]
320
+
321
+ useKeyboard((key) => {
322
+ if (key.name === "tab") {
323
+ setFocusIndex(i => (i + 1) % fields.length)
324
+ }
325
+ if (key.shift && key.name === "tab") {
326
+ setFocusIndex(i => (i - 1 + fields.length) % fields.length)
327
+ }
328
+ })
329
+
330
+ return (
331
+ <box flexDirection="column" gap={1}>
332
+ <Index each={fields}>
333
+ {(field, i) => (
334
+ <input
335
+ placeholder={`Enter ${field()}...`}
336
+ focused={i === focusIndex()}
337
+ />
338
+ )}
339
+ </Index>
340
+ </box>
341
+ )
342
+ }
343
+ ```
344
+
345
+ ## Keyboard Navigation
346
+
347
+ ### Global Shortcuts
348
+
349
+ ```tsx
350
+ import { useKeyboard } from "@opentui/solid"
351
+
352
+ function App() {
353
+ useKeyboard((key) => {
354
+ if (key.name === "escape") {
355
+ process.exit(0)
356
+ }
357
+
358
+ if (key.ctrl && key.name === "s") {
359
+ save()
360
+ }
361
+
362
+ // Vim-style
363
+ if (key.name === "j") moveDown()
364
+ if (key.name === "k") moveUp()
365
+ })
366
+
367
+ return <box>{/* ... */}</box>
368
+ }
369
+ ```
370
+
371
+ ## Responsive Design
372
+
373
+ ### Terminal-size Responsive
374
+
375
+ ```tsx
376
+ import { useTerminalDimensions } from "@opentui/solid"
377
+
378
+ function ResponsiveLayout() {
379
+ const dims = useTerminalDimensions()
380
+
381
+ return (
382
+ <box flexDirection={dims().width > 80 ? "row" : "column"}>
383
+ <box flexGrow={1}>
384
+ <text>Panel 1</text>
385
+ </box>
386
+ <box flexGrow={1}>
387
+ <text>Panel 2</text>
388
+ </box>
389
+ </box>
390
+ )
391
+ }
392
+ ```
393
+
394
+ ## Async Data
395
+
396
+ ### Resources
397
+
398
+ ```tsx
399
+ import { createResource, Suspense } from "solid-js"
400
+
401
+ async function fetchData() {
402
+ const response = await fetch("https://api.example.com/data")
403
+ return response.json()
404
+ }
405
+
406
+ function DataDisplay() {
407
+ const [data] = createResource(fetchData)
408
+
409
+ return (
410
+ <Suspense fallback={<text>Loading...</text>}>
411
+ <Show when={data()}>
412
+ {(items) => (
413
+ <For each={items()}>
414
+ {(item) => <text>{item.name}</text>}
415
+ </For>
416
+ )}
417
+ </Show>
418
+ </Suspense>
419
+ )
420
+ }
421
+ ```
422
+
423
+ ### Error Handling
424
+
425
+ ```tsx
426
+ import { createResource, Show, ErrorBoundary } from "solid-js"
427
+
428
+ function SafeDataDisplay() {
429
+ const [data] = createResource(fetchData)
430
+
431
+ return (
432
+ <ErrorBoundary fallback={(err) => <text fg="red">Error: {err.message}</text>}>
433
+ <Show
434
+ when={!data.loading}
435
+ fallback={<text>Loading...</text>}
436
+ >
437
+ <Show
438
+ when={!data.error}
439
+ fallback={<text fg="red">Failed to load</text>}
440
+ >
441
+ <For each={data()}>
442
+ {(item) => <text>{item.name}</text>}
443
+ </For>
444
+ </Show>
445
+ </Show>
446
+ </ErrorBoundary>
447
+ )
448
+ }
449
+ ```
450
+
451
+ ## Component Composition
452
+
453
+ ### Props and Children
454
+
455
+ ```tsx
456
+ import { ParentComponent, JSX } from "solid-js"
457
+
458
+ interface PanelProps {
459
+ title: string
460
+ children: JSX.Element
461
+ }
462
+
463
+ const Panel: ParentComponent<{ title: string }> = (props) => {
464
+ return (
465
+ <box border padding={1} flexDirection="column">
466
+ <text fg="#0ff">{props.title}</text>
467
+ <box marginTop={1}>
468
+ {props.children}
469
+ </box>
470
+ </box>
471
+ )
472
+ }
473
+
474
+ // Usage
475
+ <Panel title="Settings">
476
+ <text>Panel content here</text>
477
+ </Panel>
478
+ ```
479
+
480
+ ### Spread Props
481
+
482
+ ```tsx
483
+ import { splitProps } from "solid-js"
484
+
485
+ interface ButtonProps {
486
+ label: string
487
+ onClick: () => void
488
+ // ...rest goes to box
489
+ }
490
+
491
+ function Button(props: ButtonProps) {
492
+ const [local, rest] = splitProps(props, ["label", "onClick"])
493
+
494
+ return (
495
+ <box border onMouseDown={local.onClick} {...rest}>
496
+ <text>{local.label}</text>
497
+ </box>
498
+ )
499
+ }
500
+ ```
501
+
502
+ ## Animation
503
+
504
+ ### With Timeline
505
+
506
+ ```tsx
507
+ import { createSignal, onMount } from "solid-js"
508
+ import { useTimeline } from "@opentui/solid"
509
+
510
+ function AnimatedProgress() {
511
+ const [width, setWidth] = createSignal(0)
512
+
513
+ const timeline = useTimeline({
514
+ duration: 2000,
515
+ })
516
+
517
+ onMount(() => {
518
+ timeline.add(
519
+ { value: 0 },
520
+ {
521
+ value: 50,
522
+ duration: 2000,
523
+ ease: "easeOutQuad",
524
+ onUpdate: (anim) => {
525
+ setWidth(Math.round(anim.targets[0].value))
526
+ },
527
+ }
528
+ )
529
+ })
530
+
531
+ return (
532
+ <box flexDirection="column" gap={1}>
533
+ <text>Progress: {width()}%</text>
534
+ <box width={50} height={1} backgroundColor="#333">
535
+ <box width={width()} height={1} backgroundColor="#0f0" />
536
+ </box>
537
+ </box>
538
+ )
539
+ }
540
+ ```
541
+
542
+ ### Interval-based
543
+
544
+ ```tsx
545
+ import { createSignal, onCleanup } from "solid-js"
546
+
547
+ function Clock() {
548
+ const [time, setTime] = createSignal(new Date())
549
+
550
+ const interval = setInterval(() => {
551
+ setTime(new Date())
552
+ }, 1000)
553
+
554
+ onCleanup(() => clearInterval(interval))
555
+
556
+ return <text>{time().toLocaleTimeString()}</text>
557
+ }
558
+ ```