@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,444 @@
1
+ # Layout Patterns
2
+
3
+ Common layout recipes for terminal user interfaces.
4
+
5
+ ## Full-Screen App
6
+
7
+ Fill the entire terminal:
8
+
9
+ ```tsx
10
+ function App() {
11
+ return (
12
+ <box width="100%" height="100%">
13
+ {/* Content fills terminal */}
14
+ </box>
15
+ )
16
+ }
17
+ ```
18
+
19
+ ## Header/Content/Footer
20
+
21
+ Classic app layout:
22
+
23
+ ```tsx
24
+ function AppLayout() {
25
+ return (
26
+ <box flexDirection="column" width="100%" height="100%">
27
+ {/* Header - fixed height */}
28
+ <box height={3} borderStyle="single" borderBottom>
29
+ <text>Header</text>
30
+ </box>
31
+
32
+ {/* Content - fills remaining space */}
33
+ <box flexGrow={1}>
34
+ <text>Main Content</text>
35
+ </box>
36
+
37
+ {/* Footer - fixed height */}
38
+ <box height={1}>
39
+ <text>Status: Ready</text>
40
+ </box>
41
+ </box>
42
+ )
43
+ }
44
+ ```
45
+
46
+ ## Sidebar Layout
47
+
48
+ ```tsx
49
+ function SidebarLayout() {
50
+ return (
51
+ <box flexDirection="row" width="100%" height="100%">
52
+ {/* Sidebar - fixed width */}
53
+ <box width={25} borderStyle="single" borderRight>
54
+ <text>Sidebar</text>
55
+ </box>
56
+
57
+ {/* Main - fills remaining space */}
58
+ <box flexGrow={1}>
59
+ <text>Main Content</text>
60
+ </box>
61
+ </box>
62
+ )
63
+ }
64
+ ```
65
+
66
+ ## Resizable Sidebar
67
+
68
+ Responsive based on terminal width:
69
+
70
+ ```tsx
71
+ function ResponsiveSidebar() {
72
+ const dims = useTerminalDimensions() // React: useTerminalDimensions()
73
+ const showSidebar = dims.width > 60
74
+ const sidebarWidth = Math.min(30, Math.floor(dims.width * 0.3))
75
+
76
+ return (
77
+ <box flexDirection="row" width="100%" height="100%">
78
+ {showSidebar && (
79
+ <box width={sidebarWidth} border>
80
+ <text>Sidebar</text>
81
+ </box>
82
+ )}
83
+ <box flexGrow={1}>
84
+ <text>Main</text>
85
+ </box>
86
+ </box>
87
+ )
88
+ }
89
+ ```
90
+
91
+ ## Centered Content
92
+
93
+ ### Horizontally Centered
94
+
95
+ ```tsx
96
+ <box width="100%" justifyContent="center">
97
+ <box width={40}>
98
+ <text>Centered horizontally</text>
99
+ </box>
100
+ </box>
101
+ ```
102
+
103
+ ### Vertically Centered
104
+
105
+ ```tsx
106
+ <box height="100%" alignItems="center">
107
+ <text>Centered vertically</text>
108
+ </box>
109
+ ```
110
+
111
+ ### Both Axes
112
+
113
+ ```tsx
114
+ <box
115
+ width="100%"
116
+ height="100%"
117
+ justifyContent="center"
118
+ alignItems="center"
119
+ >
120
+ <box width={40} height={10} border>
121
+ <text>Centered both ways</text>
122
+ </box>
123
+ </box>
124
+ ```
125
+
126
+ ## Modal/Dialog
127
+
128
+ Centered overlay:
129
+
130
+ ```tsx
131
+ function Modal({ children, visible }) {
132
+ if (!visible) return null
133
+
134
+ return (
135
+ <box
136
+ position="absolute"
137
+ left={0}
138
+ top={0}
139
+ width="100%"
140
+ height="100%"
141
+ justifyContent="center"
142
+ alignItems="center"
143
+ backgroundColor="rgba(0,0,0,0.5)"
144
+ >
145
+ <box
146
+ width={50}
147
+ height={15}
148
+ border
149
+ borderStyle="double"
150
+ backgroundColor="#1a1a2e"
151
+ padding={2}
152
+ >
153
+ {children}
154
+ </box>
155
+ </box>
156
+ )
157
+ }
158
+ ```
159
+
160
+ ## Grid Layout
161
+
162
+ Using flexWrap:
163
+
164
+ ```tsx
165
+ function Grid({ items, columns = 3 }) {
166
+ const itemWidth = `${Math.floor(100 / columns)}%`
167
+
168
+ return (
169
+ <box flexDirection="row" flexWrap="wrap" width="100%">
170
+ {items.map((item, i) => (
171
+ <box key={i} width={itemWidth} padding={1}>
172
+ <text>{item}</text>
173
+ </box>
174
+ ))}
175
+ </box>
176
+ )
177
+ }
178
+ ```
179
+
180
+ ## Split Panels
181
+
182
+ ### Horizontal Split
183
+
184
+ ```tsx
185
+ function HorizontalSplit({ ratio = 0.5 }) {
186
+ return (
187
+ <box flexDirection="row" width="100%" height="100%">
188
+ <box width={`${ratio * 100}%`} border>
189
+ <text>Left Panel</text>
190
+ </box>
191
+ <box flexGrow={1} border>
192
+ <text>Right Panel</text>
193
+ </box>
194
+ </box>
195
+ )
196
+ }
197
+ ```
198
+
199
+ ### Vertical Split
200
+
201
+ ```tsx
202
+ function VerticalSplit({ ratio = 0.5 }) {
203
+ return (
204
+ <box flexDirection="column" width="100%" height="100%">
205
+ <box height={`${ratio * 100}%`} border>
206
+ <text>Top Panel</text>
207
+ </box>
208
+ <box flexGrow={1} border>
209
+ <text>Bottom Panel</text>
210
+ </box>
211
+ </box>
212
+ )
213
+ }
214
+ ```
215
+
216
+ ## Form Layout
217
+
218
+ Label + Input pairs:
219
+
220
+ ```tsx
221
+ function FormField({ label, children }) {
222
+ return (
223
+ <box flexDirection="row" marginBottom={1}>
224
+ <box width={15}>
225
+ <text>{label}:</text>
226
+ </box>
227
+ <box flexGrow={1}>
228
+ {children}
229
+ </box>
230
+ </box>
231
+ )
232
+ }
233
+
234
+ function LoginForm() {
235
+ return (
236
+ <box flexDirection="column" padding={2} border width={50}>
237
+ <FormField label="Username">
238
+ <input placeholder="Enter username" />
239
+ </FormField>
240
+ <FormField label="Password">
241
+ <input placeholder="Enter password" />
242
+ </FormField>
243
+ <box marginTop={2} justifyContent="flex-end">
244
+ <box border padding={1}>
245
+ <text>Login</text>
246
+ </box>
247
+ </box>
248
+ </box>
249
+ )
250
+ }
251
+ ```
252
+
253
+ ## Navigation Tabs
254
+
255
+ ```tsx
256
+ function TabBar({ tabs, activeIndex, onSelect }) {
257
+ return (
258
+ <box flexDirection="row" borderBottom>
259
+ {tabs.map((tab, i) => (
260
+ <box
261
+ key={i}
262
+ padding={1}
263
+ backgroundColor={i === activeIndex ? "#333" : "transparent"}
264
+ onMouseDown={() => onSelect(i)}
265
+ >
266
+ <text fg={i === activeIndex ? "#fff" : "#888"}>
267
+ {tab}
268
+ </text>
269
+ </box>
270
+ ))}
271
+ </box>
272
+ )
273
+ }
274
+ ```
275
+
276
+ ## Sticky Footer
277
+
278
+ Footer always at bottom:
279
+
280
+ ```tsx
281
+ function StickyFooterLayout() {
282
+ return (
283
+ <box flexDirection="column" width="100%" height="100%">
284
+ {/* Content area */}
285
+ <box flexGrow={1} flexDirection="column">
286
+ {/* Your content here */}
287
+ <text>Content that might be short</text>
288
+ </box>
289
+
290
+ {/* Footer pushed to bottom */}
291
+ <box height={1}>
292
+ <text fg="#888">Press ? for help | q to quit</text>
293
+ </box>
294
+ </box>
295
+ )
296
+ }
297
+ ```
298
+
299
+ ## Absolute Positioning Overlay
300
+
301
+ Tooltip or popup:
302
+
303
+ ```tsx
304
+ function Tooltip({ x, y, children }) {
305
+ return (
306
+ <box
307
+ position="absolute"
308
+ left={x}
309
+ top={y}
310
+ border
311
+ backgroundColor="#333"
312
+ padding={1}
313
+ zIndex={100}
314
+ >
315
+ {children}
316
+ </box>
317
+ )
318
+ }
319
+ ```
320
+
321
+ ## Responsive Breakpoints
322
+
323
+ Different layouts based on terminal size:
324
+
325
+ ```tsx
326
+ function ResponsiveApp() {
327
+ const { width, height } = useTerminalDimensions()
328
+
329
+ // Define breakpoints
330
+ const isSmall = width < 60
331
+ const isMedium = width >= 60 && width < 100
332
+ const isLarge = width >= 100
333
+
334
+ if (isSmall) {
335
+ // Mobile-like: stacked layout
336
+ return (
337
+ <box flexDirection="column">
338
+ <Navigation />
339
+ <Content />
340
+ </box>
341
+ )
342
+ }
343
+
344
+ if (isMedium) {
345
+ // Tablet-like: sidebar + content
346
+ return (
347
+ <box flexDirection="row">
348
+ <box width={20}><Navigation /></box>
349
+ <box flexGrow={1}><Content /></box>
350
+ </box>
351
+ )
352
+ }
353
+
354
+ // Large: full layout
355
+ return (
356
+ <box flexDirection="row">
357
+ <box width={25}><Navigation /></box>
358
+ <box flexGrow={1}><Content /></box>
359
+ <box width={30}><Sidebar /></box>
360
+ </box>
361
+ )
362
+ }
363
+ ```
364
+
365
+ ## Equal Height Columns
366
+
367
+ ```tsx
368
+ function EqualColumns() {
369
+ return (
370
+ <box flexDirection="row" alignItems="stretch" height={20}>
371
+ <box flexGrow={1} border>
372
+ <text>Short content</text>
373
+ </box>
374
+ <box flexGrow={1} border>
375
+ <text>
376
+ Longer content that
377
+ spans multiple lines
378
+ and takes up space
379
+ </text>
380
+ </box>
381
+ <box flexGrow={1} border>
382
+ <text>Medium content</text>
383
+ </box>
384
+ </box>
385
+ )
386
+ }
387
+ ```
388
+
389
+ ## Spacing Utilities
390
+
391
+ Consistent spacing patterns:
392
+
393
+ ```tsx
394
+ // Spacer component
395
+ function Spacer({ size = 1 }) {
396
+ return <box height={size} width={size} />
397
+ }
398
+
399
+ // Divider component
400
+ function Divider() {
401
+ return <box height={1} width="100%" backgroundColor="#333" />
402
+ }
403
+
404
+ // Usage
405
+ <box flexDirection="column">
406
+ <text>Section 1</text>
407
+ <Spacer size={2} />
408
+ <Divider />
409
+ <Spacer size={2} />
410
+ <text>Section 2</text>
411
+ </box>
412
+ ```
413
+
414
+ ### Axis Shorthand Props
415
+
416
+ Use `paddingX`/`paddingY` and `marginX`/`marginY` for horizontal/vertical spacing:
417
+
418
+ ```tsx
419
+ // Horizontal padding (left + right)
420
+ <box paddingX={4}>
421
+ <text>4 chars padding left and right</text>
422
+ </box>
423
+
424
+ // Vertical padding (top + bottom)
425
+ <box paddingY={2}>
426
+ <text>2 lines padding top and bottom</text>
427
+ </box>
428
+
429
+ // Horizontal margin for centering-like effect
430
+ <box marginX={10}>
431
+ <text>Indented content</text>
432
+ </box>
433
+
434
+ // Combined for card-like spacing
435
+ <box paddingX={3} paddingY={1} marginY={1} border>
436
+ <text>Nicely spaced card</text>
437
+ </box>
438
+ ```
439
+
440
+ These are shorthand for:
441
+ - `paddingX={n}` = `paddingLeft={n}` + `paddingRight={n}`
442
+ - `paddingY={n}` = `paddingTop={n}` + `paddingBottom={n}`
443
+ - `marginX={n}` = `marginLeft={n}` + `marginRight={n}`
444
+ - `marginY={n}` = `marginTop={n}` + `marginBottom={n}`
@@ -0,0 +1,174 @@
1
+ # OpenTUI React (@opentui/react)
2
+
3
+ A React reconciler for building terminal user interfaces with familiar React patterns. Write TUIs using JSX, hooks, and component composition.
4
+
5
+ ## Overview
6
+
7
+ OpenTUI React provides:
8
+ - **Custom reconciler**: React components render to OpenTUI renderables
9
+ - **JSX intrinsics**: `<text>`, `<box>`, `<input>`, etc.
10
+ - **Hooks**: `useKeyboard`, `useRenderer`, `useTimeline`, etc.
11
+ - **Full React compatibility**: useState, useEffect, context, and more
12
+
13
+ ## When to Use React
14
+
15
+ Use the React reconciler when:
16
+ - You're familiar with React patterns
17
+ - You want declarative UI composition
18
+ - You need React's ecosystem (context, state management libraries)
19
+ - Building applications with complex state
20
+ - Team knows React already
21
+
22
+ ## When NOT to Use React
23
+
24
+ | Scenario | Use Instead |
25
+ |----------|-------------|
26
+ | Maximum performance critical | `@opentui/core` (imperative) |
27
+ | Fine-grained reactivity | `@opentui/solid` |
28
+ | Smallest bundle size | `@opentui/core` |
29
+ | Building a framework/library | `@opentui/core` |
30
+
31
+ ## Quick Start
32
+
33
+ ```bash
34
+ bunx create-tui@latest -t react my-app
35
+ cd my-app
36
+ bun run src/index.tsx
37
+ ```
38
+
39
+ The CLI creates the `my-app` directory for you - it must **not already exist**.
40
+
41
+ **Agent guidance**: Always use autonomous mode with `-t <template>` flag. Never use interactive mode (`bunx create-tui@latest my-app` without `-t`) as it requires user prompts that agents cannot respond to.
42
+
43
+ Or manual setup:
44
+
45
+ ```bash
46
+ mkdir my-tui && cd my-tui
47
+ bun init
48
+ bun install @opentui/react @opentui/core react
49
+ ```
50
+
51
+ ```tsx
52
+ import { createCliRenderer } from "@opentui/core"
53
+ import { createRoot } from "@opentui/react"
54
+ import { useState } from "react"
55
+
56
+ function App() {
57
+ const [count, setCount] = useState(0)
58
+
59
+ return (
60
+ <box border padding={2}>
61
+ <text>Count: {count}</text>
62
+ <box
63
+ border
64
+ onMouseDown={() => setCount(c => c + 1)}
65
+ >
66
+ <text>Click me!</text>
67
+ </box>
68
+ </box>
69
+ )
70
+ }
71
+
72
+ const renderer = await createCliRenderer()
73
+ createRoot(renderer).render(<App />)
74
+ ```
75
+
76
+ ## Core Concepts
77
+
78
+ ### JSX Elements
79
+
80
+ React maps JSX intrinsic elements to OpenTUI renderables:
81
+
82
+ ```tsx
83
+ // These are not HTML elements!
84
+ <text>Hello</text> // TextRenderable
85
+ <box border>Content</box> // BoxRenderable
86
+ <input placeholder="..." /> // InputRenderable
87
+ <select options={[...]} /> // SelectRenderable
88
+ ```
89
+
90
+ ### Text Modifiers
91
+
92
+ Inside `<text>`, use modifier elements:
93
+
94
+ ```tsx
95
+ <text>
96
+ <strong>Bold</strong>, <em>italic</em>, and <u>underlined</u>
97
+ <span fg="red">Colored text</span>
98
+ <br />
99
+ New line with <a href="https://example.com">link</a>
100
+ </text>
101
+ ```
102
+
103
+ ### Styling
104
+
105
+ Two approaches to styling:
106
+
107
+ ```tsx
108
+ // Direct props
109
+ <box backgroundColor="blue" padding={2} border>
110
+ <text fg="#00FF00">Green text</text>
111
+ </box>
112
+
113
+ // Style prop
114
+ <box style={{ backgroundColor: "blue", padding: 2, border: true }}>
115
+ <text style={{ fg: "#00FF00" }}>Green text</text>
116
+ </box>
117
+ ```
118
+
119
+ ## Available Components
120
+
121
+ ### Layout & Display
122
+ - `<text>` - Styled text content
123
+ - `<box>` - Container with borders and layout
124
+ - `<scrollbox>` - Scrollable container
125
+ - `<ascii-font>` - ASCII art text
126
+
127
+ ### Input
128
+ - `<input>` - Single-line text input
129
+ - `<textarea>` - Multi-line text input
130
+ - `<select>` - List selection
131
+ - `<tab-select>` - Tab-based selection
132
+
133
+ ### Code & Diff
134
+ - `<code>` - Syntax-highlighted code
135
+ - `<line-number>` - Code with line numbers
136
+ - `<diff>` - Unified or split diff viewer
137
+
138
+ ### Text Modifiers (inside `<text>`)
139
+ - `<span>` - Inline styled text
140
+ - `<strong>`, `<b>` - Bold
141
+ - `<em>`, `<i>` - Italic
142
+ - `<u>` - Underline
143
+ - `<br>` - Line break
144
+ - `<a>` - Link
145
+
146
+ ## Essential Hooks
147
+
148
+ ```tsx
149
+ import {
150
+ useRenderer,
151
+ useKeyboard,
152
+ useOnResize,
153
+ useTerminalDimensions,
154
+ useTimeline,
155
+ } from "@opentui/react"
156
+ ```
157
+
158
+ See [API Reference](./api.md) for detailed hook documentation.
159
+
160
+ ## In This Reference
161
+
162
+ - [Configuration](./configuration.md) - Project setup, tsconfig, bundling
163
+ - [API](./api.md) - Components, hooks, createRoot
164
+ - [Patterns](./patterns.md) - State management, keyboard handling, forms
165
+ - [Gotchas](./gotchas.md) - Common issues, debugging, limitations
166
+
167
+ ## See Also
168
+
169
+ - [Core](../core/REFERENCE.md) - Underlying imperative API
170
+ - [Solid](../solid/REFERENCE.md) - Alternative declarative approach
171
+ - [Components](../components/REFERENCE.md) - Component reference by category
172
+ - [Layout](../layout/REFERENCE.md) - Flexbox layout system
173
+ - [Keyboard](../keyboard/REFERENCE.md) - Input handling and shortcuts
174
+ - [Testing](../testing/REFERENCE.md) - Test renderer and snapshots