@dealdeploy/skl 0.1.7 → 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 (55) 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/skills/opentui/SKILL.md +198 -0
  28. package/.claude/skills/opentui/references/animation/REFERENCE.md +431 -0
  29. package/.claude/skills/opentui/references/components/REFERENCE.md +143 -0
  30. package/.claude/skills/opentui/references/components/code-diff.md +496 -0
  31. package/.claude/skills/opentui/references/components/containers.md +412 -0
  32. package/.claude/skills/opentui/references/components/inputs.md +531 -0
  33. package/.claude/skills/opentui/references/components/text-display.md +384 -0
  34. package/.claude/skills/opentui/references/core/REFERENCE.md +145 -0
  35. package/.claude/skills/opentui/references/core/api.md +506 -0
  36. package/.claude/skills/opentui/references/core/configuration.md +166 -0
  37. package/.claude/skills/opentui/references/core/gotchas.md +393 -0
  38. package/.claude/skills/opentui/references/core/patterns.md +448 -0
  39. package/.claude/skills/opentui/references/keyboard/REFERENCE.md +511 -0
  40. package/.claude/skills/opentui/references/layout/REFERENCE.md +337 -0
  41. package/.claude/skills/opentui/references/layout/patterns.md +444 -0
  42. package/.claude/skills/opentui/references/react/REFERENCE.md +174 -0
  43. package/.claude/skills/opentui/references/react/api.md +435 -0
  44. package/.claude/skills/opentui/references/react/configuration.md +301 -0
  45. package/.claude/skills/opentui/references/react/gotchas.md +443 -0
  46. package/.claude/skills/opentui/references/react/patterns.md +501 -0
  47. package/.claude/skills/opentui/references/solid/REFERENCE.md +201 -0
  48. package/.claude/skills/opentui/references/solid/api.md +543 -0
  49. package/.claude/skills/opentui/references/solid/configuration.md +315 -0
  50. package/.claude/skills/opentui/references/solid/gotchas.md +415 -0
  51. package/.claude/skills/opentui/references/solid/patterns.md +558 -0
  52. package/.claude/skills/opentui/references/testing/REFERENCE.md +614 -0
  53. package/index.ts +169 -38
  54. package/package.json +1 -1
  55. package/update.ts +87 -0
@@ -0,0 +1,443 @@
1
+ # React Gotchas
2
+
3
+ ## Critical
4
+
5
+ ### Never use `process.exit()` directly
6
+
7
+ **This is the most common mistake.** Using `process.exit()` leaves the terminal in a broken state (cursor hidden, raw mode, alternate screen).
8
+
9
+ ```tsx
10
+ // WRONG - Terminal left in broken state
11
+ process.exit(0)
12
+
13
+ // CORRECT - Use renderer.destroy()
14
+ import { useRenderer } from "@opentui/react"
15
+
16
+ function App() {
17
+ const renderer = useRenderer()
18
+
19
+ const handleExit = () => {
20
+ renderer.destroy() // Cleans up and exits properly
21
+ }
22
+ }
23
+ ```
24
+
25
+ `renderer.destroy()` restores the terminal (exits alternate screen, restores cursor, etc.) before exiting.
26
+
27
+ ### Signal Handling
28
+
29
+ OpenTUI automatically handles cleanup for these signals:
30
+ - `SIGINT` (Ctrl+C), `SIGTERM`, `SIGQUIT` - Standard termination
31
+ - `SIGHUP` - Terminal closed/hangup
32
+ - `SIGBREAK` - Ctrl+Break (Windows)
33
+ - `SIGPIPE` - Broken pipe (output closed)
34
+ - `SIGBUS`, `SIGFPE` - Hardware errors
35
+
36
+ This ensures terminal state is restored even on unexpected termination. If you need custom signal handling, use `exitOnCtrlC: false` and handle signals yourself while still calling `renderer.destroy()`.
37
+
38
+ ## JSX Configuration
39
+
40
+ ### Missing jsxImportSource
41
+
42
+ **Symptom**: JSX elements have wrong types, components don't render
43
+
44
+ ```
45
+ // Error: Property 'text' does not exist on type 'JSX.IntrinsicElements'
46
+ ```
47
+
48
+ **Fix**: Configure tsconfig.json:
49
+
50
+ ```json
51
+ {
52
+ "compilerOptions": {
53
+ "jsx": "react-jsx",
54
+ "jsxImportSource": "@opentui/react"
55
+ }
56
+ }
57
+ ```
58
+
59
+ ### HTML Elements vs TUI Elements
60
+
61
+ OpenTUI's JSX elements are **not** HTML elements:
62
+
63
+ ```tsx
64
+ // WRONG - These are HTML concepts
65
+ <div>Not supported</div>
66
+ <button>Not supported</button>
67
+ <span>Only works inside <text></span>
68
+
69
+ // CORRECT - OpenTUI elements
70
+ <box>Container</box>
71
+ <text>Display text</text>
72
+ <text><span>Inline styled</span></text>
73
+ ```
74
+
75
+ ## Component Issues
76
+
77
+ ### Text Modifiers Outside Text
78
+
79
+ Text modifiers only work inside `<text>`:
80
+
81
+ ```tsx
82
+ // WRONG
83
+ <box>
84
+ <strong>This won't work</strong>
85
+ </box>
86
+
87
+ // CORRECT
88
+ <box>
89
+ <text>
90
+ <strong>This works</strong>
91
+ </text>
92
+ </box>
93
+ ```
94
+
95
+ ### Focus Not Working
96
+
97
+ Components must be explicitly focused:
98
+
99
+ ```tsx
100
+ // WRONG - Won't receive keyboard input
101
+ <input placeholder="Type here..." />
102
+
103
+ // CORRECT
104
+ <input placeholder="Type here..." focused />
105
+
106
+ // Or manage focus state
107
+ const [isFocused, setIsFocused] = useState(true)
108
+ <input placeholder="Type here..." focused={isFocused} />
109
+ ```
110
+
111
+ ### Select Not Responding
112
+
113
+ Select requires focus and proper options format:
114
+
115
+ ```tsx
116
+ // WRONG - Missing required properties
117
+ <select options={["a", "b", "c"]} />
118
+
119
+ // CORRECT
120
+ <select
121
+ options={[
122
+ { name: "Option A", description: "First option", value: "a" },
123
+ { name: "Option B", description: "Second option", value: "b" },
124
+ ]}
125
+ onSelect={(index, option) => {
126
+ // Called when Enter is pressed
127
+ console.log("Selected:", option.name)
128
+ }}
129
+ focused
130
+ />
131
+ ```
132
+
133
+ ### Select Events Confusion
134
+
135
+ Remember: `onSelect` fires on Enter (selection confirmed), `onChange` fires on navigation:
136
+
137
+ ```tsx
138
+ // WRONG - expecting onChange to fire on Enter
139
+ <select
140
+ options={options}
141
+ onChange={(i, opt) => submitForm(opt)} // This fires on arrow keys!
142
+ />
143
+
144
+ // CORRECT
145
+ <select
146
+ options={options}
147
+ onSelect={(i, opt) => submitForm(opt)} // Enter pressed - submit
148
+ onChange={(i, opt) => showPreview(opt)} // Arrow keys - preview
149
+ />
150
+ ```
151
+
152
+ ## Hook Issues
153
+
154
+ ### useKeyboard Not Firing
155
+
156
+ Multiple `useKeyboard` hooks can conflict:
157
+
158
+ ```tsx
159
+ // Both handlers fire - may cause issues
160
+ function App() {
161
+ useKeyboard((key) => { /* parent handler */ })
162
+ return <ChildWithKeyboard />
163
+ }
164
+
165
+ function ChildWithKeyboard() {
166
+ useKeyboard((key) => { /* child handler */ })
167
+ return <text>Child</text>
168
+ }
169
+ ```
170
+
171
+ **Solution**: Use a single keyboard handler or implement event stopping:
172
+
173
+ ```tsx
174
+ function App() {
175
+ const [handled, setHandled] = useState(false)
176
+
177
+ useKeyboard((key) => {
178
+ if (handled) {
179
+ setHandled(false)
180
+ return
181
+ }
182
+ // Handle at app level
183
+ })
184
+
185
+ return <Child onKeyHandled={() => setHandled(true)} />
186
+ }
187
+ ```
188
+
189
+ ### useEffect Cleanup
190
+
191
+ Always clean up intervals and listeners:
192
+
193
+ ```tsx
194
+ // WRONG - Memory leak
195
+ useEffect(() => {
196
+ setInterval(() => updateData(), 1000)
197
+ }, [])
198
+
199
+ // CORRECT
200
+ useEffect(() => {
201
+ const interval = setInterval(() => updateData(), 1000)
202
+ return () => clearInterval(interval) // Cleanup!
203
+ }, [])
204
+ ```
205
+
206
+ ## Styling Issues
207
+
208
+ ### Colors Not Applying
209
+
210
+ Check color format:
211
+
212
+ ```tsx
213
+ // CORRECT formats
214
+ <text fg="#FF0000">Red</text>
215
+ <text fg="red">Red</text>
216
+ <box backgroundColor="#1a1a2e">Box</box>
217
+
218
+ // WRONG
219
+ <text fg="FF0000">Missing #</text>
220
+ <text color="#FF0000">Wrong prop name (use fg)</text>
221
+ ```
222
+
223
+ ### Layout Not Working
224
+
225
+ Ensure parent has dimensions:
226
+
227
+ ```tsx
228
+ // WRONG - Parent has no height
229
+ <box flexDirection="column">
230
+ <box flexGrow={1}>Won't grow</box>
231
+ </box>
232
+
233
+ // CORRECT
234
+ <box flexDirection="column" height="100%">
235
+ <box flexGrow={1}>Will grow</box>
236
+ </box>
237
+ ```
238
+
239
+ ### Percentage Widths Not Working
240
+
241
+ Parent must have explicit dimensions:
242
+
243
+ ```tsx
244
+ // WRONG
245
+ <box>
246
+ <box width="50%">Won't work</box>
247
+ </box>
248
+
249
+ // CORRECT
250
+ <box width="100%">
251
+ <box width="50%">Works</box>
252
+ </box>
253
+ ```
254
+
255
+ ## Performance Issues
256
+
257
+ ### Too Many Re-renders
258
+
259
+ Avoid inline objects/functions in props:
260
+
261
+ ```tsx
262
+ // WRONG - New object every render
263
+ <box style={{ padding: 2 }}>Content</box>
264
+
265
+ // BETTER - Use direct props
266
+ <box padding={2}>Content</box>
267
+
268
+ // OR memoize style objects
269
+ const style = useMemo(() => ({ padding: 2 }), [])
270
+ <box style={style}>Content</box>
271
+ ```
272
+
273
+ ### Heavy Components
274
+
275
+ Use React.memo for expensive components:
276
+
277
+ ```tsx
278
+ const ExpensiveList = React.memo(function ExpensiveList({
279
+ items
280
+ }: {
281
+ items: Item[]
282
+ }) {
283
+ return (
284
+ <box flexDirection="column">
285
+ {items.map(item => (
286
+ <text key={item.id}>{item.name}</text>
287
+ ))}
288
+ </box>
289
+ )
290
+ })
291
+ ```
292
+
293
+ ### State Updates During Render
294
+
295
+ Don't update state during render:
296
+
297
+ ```tsx
298
+ // WRONG
299
+ function Component({ value }: { value: number }) {
300
+ const [count, setCount] = useState(0)
301
+
302
+ // This causes infinite loop!
303
+ if (value > 10) {
304
+ setCount(value)
305
+ }
306
+
307
+ return <text>{count}</text>
308
+ }
309
+
310
+ // CORRECT
311
+ function Component({ value }: { value: number }) {
312
+ const [count, setCount] = useState(0)
313
+
314
+ useEffect(() => {
315
+ if (value > 10) {
316
+ setCount(value)
317
+ }
318
+ }, [value])
319
+
320
+ return <text>{count}</text>
321
+ }
322
+ ```
323
+
324
+ ## Debugging
325
+
326
+ ### Console Not Visible
327
+
328
+ OpenTUI captures console output. Show the overlay:
329
+
330
+ ```tsx
331
+ import { useRenderer } from "@opentui/react"
332
+ import { useEffect } from "react"
333
+
334
+ function App() {
335
+ const renderer = useRenderer()
336
+
337
+ useEffect(() => {
338
+ renderer.console.show()
339
+ console.log("Now you can see this!")
340
+ }, [renderer])
341
+
342
+ return <box>{/* ... */}</box>
343
+ }
344
+ ```
345
+
346
+ ### Component Not Rendering
347
+
348
+ Check if component is in the tree:
349
+
350
+ ```tsx
351
+ // WRONG - Conditional returns nothing
352
+ function MaybeComponent({ show }: { show: boolean }) {
353
+ if (!show) return // Returns undefined!
354
+ return <text>Visible</text>
355
+ }
356
+
357
+ // CORRECT
358
+ function MaybeComponent({ show }: { show: boolean }) {
359
+ if (!show) return null // Explicit null
360
+ return <text>Visible</text>
361
+ }
362
+ ```
363
+
364
+ ### Events Not Firing
365
+
366
+ Check event handler names:
367
+
368
+ ```tsx
369
+ // WRONG
370
+ <box onClick={() => {}}>Click</box> // No onClick in TUI
371
+
372
+ // CORRECT
373
+ <box onMouseDown={() => {}}>Click</box>
374
+ <box onMouseUp={() => {}}>Click</box>
375
+ ```
376
+
377
+ ## Runtime Issues
378
+
379
+ ### Use Bun, Not Node
380
+
381
+ ```bash
382
+ # WRONG
383
+ node src/index.tsx
384
+ npm run start
385
+
386
+ # CORRECT
387
+ bun run src/index.tsx
388
+ bun run start
389
+ ```
390
+
391
+ ### Async Top-level
392
+
393
+ Bun supports top-level await, but be careful:
394
+
395
+ ```tsx
396
+ // index.tsx - This works in Bun
397
+ const renderer = await createCliRenderer()
398
+ createRoot(renderer).render(<App />)
399
+
400
+ // If you need to handle errors
401
+ try {
402
+ const renderer = await createCliRenderer()
403
+ createRoot(renderer).render(<App />)
404
+ } catch (error) {
405
+ console.error("Failed to initialize:", error)
406
+ process.exit(1)
407
+ }
408
+ ```
409
+
410
+ ## Common Error Messages
411
+
412
+ ### "Cannot read properties of undefined (reading 'root')"
413
+
414
+ Renderer not initialized:
415
+
416
+ ```tsx
417
+ // WRONG
418
+ const renderer = createCliRenderer() // Missing await!
419
+ createRoot(renderer).render(<App />)
420
+
421
+ // CORRECT
422
+ const renderer = await createCliRenderer()
423
+ createRoot(renderer).render(<App />)
424
+ ```
425
+
426
+ ### "Invalid hook call"
427
+
428
+ Hooks called outside component:
429
+
430
+ ```tsx
431
+ // WRONG
432
+ const dimensions = useTerminalDimensions() // Outside component!
433
+
434
+ function App() {
435
+ return <text>{dimensions.width}</text>
436
+ }
437
+
438
+ // CORRECT
439
+ function App() {
440
+ const dimensions = useTerminalDimensions()
441
+ return <text>{dimensions.width}</text>
442
+ }
443
+ ```