@dealdeploy/skl 0.1.6 → 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 (56) 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/index.ts +429 -86
  55. package/package.json +2 -1
  56. package/update.ts +87 -0
@@ -0,0 +1,198 @@
1
+ ---
2
+ name: opentui
3
+ description: Comprehensive OpenTUI skill for building terminal user interfaces. Covers the core imperative API, React reconciler, and Solid reconciler. Use for any TUI development task including components, layout, keyboard handling, animations, and testing.
4
+ metadata:
5
+ references: core, react, solid
6
+ ---
7
+
8
+ # OpenTUI Platform Skill
9
+
10
+ Consolidated skill for building terminal user interfaces with OpenTUI. Use decision trees below to find the right framework and components, then load detailed references.
11
+
12
+ ## Critical Rules
13
+
14
+ **Follow these rules in all OpenTUI code:**
15
+
16
+ 1. **Use `create-tui` for new projects.** See framework `REFERENCE.md` quick starts.
17
+ 2. **`create-tui` options must come before arguments.** `bunx create-tui -t react my-app` works, `bunx create-tui my-app -t react` does NOT.
18
+ 3. **Never call `process.exit()` directly.** Use `renderer.destroy()` (see `core/gotchas.md`).
19
+ 4. **Text styling requires nested tags in React/Solid.** Use modifier elements, not props (see `components/text-display.md`).
20
+
21
+ ## How to Use This Skill
22
+
23
+ ### Reference File Structure
24
+
25
+ Framework references follow a 5-file pattern. Cross-cutting concepts are single-file guides.
26
+
27
+ Each framework in `./references/<framework>/` contains:
28
+
29
+ | File | Purpose | When to Read |
30
+ |------|---------|--------------|
31
+ | `REFERENCE.md` | Overview, when to use, quick start | **Always read first** |
32
+ | `api.md` | Runtime API, components, hooks | Writing code |
33
+ | `configuration.md` | Setup, tsconfig, bundling | Configuring a project |
34
+ | `patterns.md` | Common patterns, best practices | Implementation guidance |
35
+ | `gotchas.md` | Pitfalls, limitations, debugging | Troubleshooting |
36
+
37
+ Cross-cutting concepts in `./references/<concept>/` have `REFERENCE.md` as the entry point.
38
+
39
+ ### Reading Order
40
+
41
+ 1. Start with `REFERENCE.md` for your chosen framework
42
+ 2. Then read additional files relevant to your task:
43
+ - Building components -> `api.md` + `components/<category>.md`
44
+ - Setting up project -> `configuration.md`
45
+ - Layout/positioning -> `layout/REFERENCE.md`
46
+ - Keyboard/input handling -> `keyboard/REFERENCE.md`
47
+ - Animations -> `animation/REFERENCE.md`
48
+ - Troubleshooting -> `gotchas.md` + `testing/REFERENCE.md`
49
+
50
+ ### Example Paths
51
+
52
+ ```
53
+ ./references/react/REFERENCE.md # Start here for React
54
+ ./references/react/api.md # React components and hooks
55
+ ./references/solid/configuration.md # Solid project setup
56
+ ./references/components/inputs.md # Input, Textarea, Select docs
57
+ ./references/core/gotchas.md # Core debugging tips
58
+ ```
59
+
60
+ ### Runtime Notes
61
+
62
+ OpenTUI runs on Bun and uses Zig for native builds. Read `./references/core/gotchas.md` for runtime requirements and build guidance.
63
+
64
+ ## Quick Decision Trees
65
+
66
+ ### "Which framework should I use?"
67
+
68
+ ```
69
+ Which framework?
70
+ ├─ I want full control, maximum performance, no framework overhead
71
+ │ └─ core/ (imperative API)
72
+ ├─ I know React, want familiar component patterns
73
+ │ └─ react/ (React reconciler)
74
+ ├─ I want fine-grained reactivity, optimal re-renders
75
+ │ └─ solid/ (Solid reconciler)
76
+ └─ I'm building a library/framework on top of OpenTUI
77
+ └─ core/ (imperative API)
78
+ ```
79
+
80
+ ### "I need to display content"
81
+
82
+ ```
83
+ Display content?
84
+ ├─ Plain or styled text -> components/text-display.md
85
+ ├─ Container with borders/background -> components/containers.md
86
+ ├─ Scrollable content area -> components/containers.md (scrollbox)
87
+ ├─ ASCII art banner/title -> components/text-display.md (ascii-font)
88
+ ├─ Code with syntax highlighting -> components/code-diff.md
89
+ ├─ Diff viewer (unified/split) -> components/code-diff.md
90
+ ├─ Line numbers with diagnostics -> components/code-diff.md
91
+ └─ Markdown content (streaming) -> components/code-diff.md (markdown)
92
+ ```
93
+
94
+ ### "I need user input"
95
+
96
+ ```
97
+ User input?
98
+ ├─ Single-line text field -> components/inputs.md (input)
99
+ ├─ Multi-line text editor -> components/inputs.md (textarea)
100
+ ├─ Select from a list (vertical) -> components/inputs.md (select)
101
+ ├─ Tab-based selection (horizontal) -> components/inputs.md (tab-select)
102
+ └─ Custom keyboard shortcuts -> keyboard/REFERENCE.md
103
+ ```
104
+
105
+ ### "I need layout/positioning"
106
+
107
+ ```
108
+ Layout?
109
+ ├─ Flexbox-style layouts (row, column, wrap) -> layout/REFERENCE.md
110
+ ├─ Absolute positioning -> layout/patterns.md
111
+ ├─ Responsive to terminal size -> layout/patterns.md
112
+ ├─ Centering content -> layout/patterns.md
113
+ └─ Complex nested layouts -> layout/patterns.md
114
+ ```
115
+
116
+ ### "I need animations"
117
+
118
+ ```
119
+ Animations?
120
+ ├─ Timeline-based animations -> animation/REFERENCE.md
121
+ ├─ Easing functions -> animation/REFERENCE.md
122
+ ├─ Property transitions -> animation/REFERENCE.md
123
+ └─ Looping animations -> animation/REFERENCE.md
124
+ ```
125
+
126
+ ### "I need to handle input"
127
+
128
+ ```
129
+ Input handling?
130
+ ├─ Keyboard events (keypress, release) -> keyboard/REFERENCE.md
131
+ ├─ Focus management -> keyboard/REFERENCE.md
132
+ ├─ Paste events -> keyboard/REFERENCE.md
133
+ ├─ Mouse events -> components/containers.md
134
+ └─ Text selection -> components/text-display.md
135
+ ```
136
+
137
+ ### "I need to test my TUI"
138
+
139
+ ```
140
+ Testing?
141
+ ├─ Snapshot testing -> testing/REFERENCE.md
142
+ ├─ Interaction testing -> testing/REFERENCE.md
143
+ ├─ Test renderer setup -> testing/REFERENCE.md
144
+ └─ Debugging tests -> testing/REFERENCE.md
145
+ ```
146
+
147
+ ### "I need to debug/troubleshoot"
148
+
149
+ ```
150
+ Troubleshooting?
151
+ ├─ Runtime errors, crashes -> <framework>/gotchas.md
152
+ ├─ Layout issues -> layout/REFERENCE.md + layout/patterns.md
153
+ ├─ Input/focus issues -> keyboard/REFERENCE.md
154
+ └─ Repro + regression tests -> testing/REFERENCE.md
155
+ ```
156
+
157
+ ### Troubleshooting Index
158
+
159
+ - Terminal cleanup, crashes -> `core/gotchas.md`
160
+ - Text styling not applying -> `components/text-display.md`
161
+ - Input focus/shortcuts -> `keyboard/REFERENCE.md`
162
+ - Layout misalignment -> `layout/REFERENCE.md`
163
+ - Flaky snapshots -> `testing/REFERENCE.md`
164
+
165
+ For component naming differences and text modifiers, see `components/REFERENCE.md`.
166
+
167
+ ## Product Index
168
+
169
+ ### Frameworks
170
+ | Framework | Entry File | Description |
171
+ |-----------|------------|-------------|
172
+ | Core | `./references/core/REFERENCE.md` | Imperative API, all primitives |
173
+ | React | `./references/react/REFERENCE.md` | React reconciler for declarative TUI |
174
+ | Solid | `./references/solid/REFERENCE.md` | SolidJS reconciler for declarative TUI |
175
+
176
+ ### Cross-Cutting Concepts
177
+ | Concept | Entry File | Description |
178
+ |---------|------------|-------------|
179
+ | Layout | `./references/layout/REFERENCE.md` | Yoga/Flexbox layout system |
180
+ | Components | `./references/components/REFERENCE.md` | Component reference by category |
181
+ | Keyboard | `./references/keyboard/REFERENCE.md` | Keyboard input handling |
182
+ | Animation | `./references/animation/REFERENCE.md` | Timeline-based animations |
183
+ | Testing | `./references/testing/REFERENCE.md` | Test renderer and snapshots |
184
+
185
+ ### Component Categories
186
+ | Category | Entry File | Components |
187
+ |----------|------------|------------|
188
+ | Text & Display | `./references/components/text-display.md` | text, ascii-font, styled text |
189
+ | Containers | `./references/components/containers.md` | box, scrollbox, borders |
190
+ | Inputs | `./references/components/inputs.md` | input, textarea, select, tab-select |
191
+ | Code & Diff | `./references/components/code-diff.md` | code, line-number, diff, markdown |
192
+
193
+ ## Resources
194
+
195
+ **Repository**: https://github.com/anomalyco/opentui
196
+ **Core Docs**: https://github.com/anomalyco/opentui/tree/main/packages/core/docs
197
+ **Examples**: https://github.com/anomalyco/opentui/tree/main/packages/core/src/examples
198
+ **Awesome List**: https://github.com/msmps/awesome-opentui
@@ -0,0 +1,431 @@
1
+ # Animation System
2
+
3
+ OpenTUI provides a timeline-based animation system for smooth property transitions.
4
+
5
+ ## Overview
6
+
7
+ Animations in OpenTUI use:
8
+ - **Timeline**: Orchestrates multiple animations
9
+ - **Animation Engine**: Manages timelines and rendering
10
+ - **Easing Functions**: Control animation curves
11
+
12
+ ## When to Use
13
+
14
+ Use this reference when you need timeline-driven animations, easing curves, or progressive transitions.
15
+
16
+ ## Basic Usage
17
+
18
+ ### React
19
+
20
+ ```tsx
21
+ import { useTimeline } from "@opentui/react"
22
+ import { useEffect, useState } from "react"
23
+
24
+ function AnimatedBox() {
25
+ const [width, setWidth] = useState(0)
26
+
27
+ const timeline = useTimeline({
28
+ duration: 2000,
29
+ })
30
+
31
+ useEffect(() => {
32
+ timeline.add(
33
+ { width: 0 },
34
+ {
35
+ width: 50,
36
+ duration: 2000,
37
+ ease: "easeOutQuad",
38
+ onUpdate: (anim) => {
39
+ setWidth(Math.round(anim.targets[0].width))
40
+ },
41
+ }
42
+ )
43
+ }, [])
44
+
45
+ return (
46
+ <box
47
+ width={width}
48
+ height={3}
49
+ backgroundColor="#6a5acd"
50
+ />
51
+ )
52
+ }
53
+ ```
54
+
55
+ ### Solid
56
+
57
+ ```tsx
58
+ import { useTimeline } from "@opentui/solid"
59
+ import { createSignal, onMount } from "solid-js"
60
+
61
+ function AnimatedBox() {
62
+ const [width, setWidth] = createSignal(0)
63
+
64
+ const timeline = useTimeline({
65
+ duration: 2000,
66
+ })
67
+
68
+ onMount(() => {
69
+ timeline.add(
70
+ { width: 0 },
71
+ {
72
+ width: 50,
73
+ duration: 2000,
74
+ ease: "easeOutQuad",
75
+ onUpdate: (anim) => {
76
+ setWidth(Math.round(anim.targets[0].width))
77
+ },
78
+ }
79
+ )
80
+ })
81
+
82
+ return (
83
+ <box
84
+ width={width()}
85
+ height={3}
86
+ backgroundColor="#6a5acd"
87
+ />
88
+ )
89
+ }
90
+ ```
91
+
92
+ ### Core
93
+
94
+ ```typescript
95
+ import { createCliRenderer, Timeline, engine } from "@opentui/core"
96
+
97
+ const renderer = await createCliRenderer()
98
+ engine.attach(renderer)
99
+
100
+ const timeline = new Timeline({
101
+ duration: 2000,
102
+ autoplay: true,
103
+ })
104
+
105
+ timeline.add(
106
+ { x: 0 },
107
+ {
108
+ x: 50,
109
+ duration: 2000,
110
+ ease: "easeOutQuad",
111
+ onUpdate: (anim) => {
112
+ box.setLeft(Math.round(anim.targets[0].x))
113
+ },
114
+ }
115
+ )
116
+
117
+ engine.addTimeline(timeline)
118
+ ```
119
+
120
+ ## Timeline Options
121
+
122
+ ```typescript
123
+ const timeline = useTimeline({
124
+ duration: 2000, // Total duration in ms
125
+ loop: false, // Loop the timeline
126
+ autoplay: true, // Start automatically
127
+ onComplete: () => {}, // Called when timeline completes
128
+ onPause: () => {}, // Called when timeline pauses
129
+ })
130
+ ```
131
+
132
+ ## Timeline Methods
133
+
134
+ ```typescript
135
+ // Add animation
136
+ timeline.add(target, properties, startTime?)
137
+
138
+ // Control playback
139
+ timeline.play() // Start/resume
140
+ timeline.pause() // Pause
141
+ timeline.restart() // Restart from beginning
142
+
143
+ // State
144
+ timeline.progress // Current progress (0-1)
145
+ timeline.duration // Total duration
146
+ ```
147
+
148
+ ## Animation Properties
149
+
150
+ ```typescript
151
+ timeline.add(
152
+ { value: 0 }, // Target object with initial values
153
+ {
154
+ value: 100, // Final value
155
+ duration: 1000, // Animation duration in ms
156
+ ease: "linear", // Easing function
157
+ delay: 0, // Delay before starting
158
+ onUpdate: (anim) => {
159
+ // Called each frame
160
+ const current = anim.targets[0].value
161
+ },
162
+ onComplete: () => {
163
+ // Called when this animation completes
164
+ },
165
+ },
166
+ 0 // Start time in timeline (optional)
167
+ )
168
+ ```
169
+
170
+ ## Easing Functions
171
+
172
+ Available easing functions:
173
+
174
+ ### Linear
175
+
176
+ | Name | Description |
177
+ |------|-------------|
178
+ | `linear` | Constant speed |
179
+
180
+ ### Quad (Power of 2)
181
+
182
+ | Name | Description |
183
+ |------|-------------|
184
+ | `easeInQuad` | Slow start |
185
+ | `easeOutQuad` | Slow end |
186
+ | `easeInOutQuad` | Slow start and end |
187
+
188
+ ### Cubic (Power of 3)
189
+
190
+ | Name | Description |
191
+ |------|-------------|
192
+ | `easeInCubic` | Slower start |
193
+ | `easeOutCubic` | Slower end |
194
+ | `easeInOutCubic` | Slower start and end |
195
+
196
+ ### Quart (Power of 4)
197
+
198
+ | Name | Description |
199
+ |------|-------------|
200
+ | `easeInQuart` | Even slower start |
201
+ | `easeOutQuart` | Even slower end |
202
+ | `easeInOutQuart` | Even slower start and end |
203
+
204
+ ### Expo (Exponential)
205
+
206
+ | Name | Description |
207
+ |------|-------------|
208
+ | `easeInExpo` | Exponential start |
209
+ | `easeOutExpo` | Exponential end |
210
+ | `easeInOutExpo` | Exponential start and end |
211
+
212
+ ### Back (Overshoot)
213
+
214
+ | Name | Description |
215
+ |------|-------------|
216
+ | `easeInBack` | Pull back, then forward |
217
+ | `easeOutBack` | Overshoot, then settle |
218
+ | `easeInOutBack` | Both |
219
+
220
+ ### Elastic
221
+
222
+ | Name | Description |
223
+ |------|-------------|
224
+ | `easeInElastic` | Elastic start |
225
+ | `easeOutElastic` | Elastic end (bouncy) |
226
+ | `easeInOutElastic` | Both |
227
+
228
+ ### Bounce
229
+
230
+ | Name | Description |
231
+ |------|-------------|
232
+ | `easeInBounce` | Bounce at start |
233
+ | `easeOutBounce` | Bounce at end |
234
+ | `easeInOutBounce` | Both |
235
+
236
+ ## Patterns
237
+
238
+ ### Progress Bar
239
+
240
+ ```tsx
241
+ function ProgressBar({ progress }: { progress: number }) {
242
+ const [width, setWidth] = useState(0)
243
+ const maxWidth = 50
244
+
245
+ const timeline = useTimeline()
246
+
247
+ useEffect(() => {
248
+ timeline.add(
249
+ { value: width },
250
+ {
251
+ value: (progress / 100) * maxWidth,
252
+ duration: 300,
253
+ ease: "easeOutQuad",
254
+ onUpdate: (anim) => {
255
+ setWidth(Math.round(anim.targets[0].value))
256
+ },
257
+ }
258
+ )
259
+ }, [progress])
260
+
261
+ return (
262
+ <box flexDirection="column" gap={1}>
263
+ <text>Progress: {progress}%</text>
264
+ <box width={maxWidth} height={1} backgroundColor="#333">
265
+ <box width={width} height={1} backgroundColor="#00FF00" />
266
+ </box>
267
+ </box>
268
+ )
269
+ }
270
+ ```
271
+
272
+ ### Fade In
273
+
274
+ ```tsx
275
+ function FadeIn({ children }) {
276
+ const [opacity, setOpacity] = useState(0)
277
+
278
+ const timeline = useTimeline()
279
+
280
+ useEffect(() => {
281
+ timeline.add(
282
+ { opacity: 0 },
283
+ {
284
+ opacity: 1,
285
+ duration: 500,
286
+ ease: "easeOutQuad",
287
+ onUpdate: (anim) => {
288
+ setOpacity(anim.targets[0].opacity)
289
+ },
290
+ }
291
+ )
292
+ }, [])
293
+
294
+ return (
295
+ <box style={{ opacity }}>
296
+ {children}
297
+ </box>
298
+ )
299
+ }
300
+ ```
301
+
302
+ ### Looping Animation
303
+
304
+ ```tsx
305
+ function Spinner() {
306
+ const [frame, setFrame] = useState(0)
307
+ const frames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
308
+
309
+ useEffect(() => {
310
+ const interval = setInterval(() => {
311
+ setFrame(f => (f + 1) % frames.length)
312
+ }, 80)
313
+
314
+ return () => clearInterval(interval)
315
+ }, [])
316
+
317
+ return <text>{frames[frame]} Loading...</text>
318
+ }
319
+ ```
320
+
321
+ ### Staggered Animation
322
+
323
+ ```tsx
324
+ function StaggeredList({ items }) {
325
+ const [visibleCount, setVisibleCount] = useState(0)
326
+
327
+ useEffect(() => {
328
+ let count = 0
329
+ const interval = setInterval(() => {
330
+ count++
331
+ setVisibleCount(count)
332
+ if (count >= items.length) {
333
+ clearInterval(interval)
334
+ }
335
+ }, 100)
336
+
337
+ return () => clearInterval(interval)
338
+ }, [items.length])
339
+
340
+ return (
341
+ <box flexDirection="column">
342
+ {items.slice(0, visibleCount).map((item, i) => (
343
+ <text key={i}>{item}</text>
344
+ ))}
345
+ </box>
346
+ )
347
+ }
348
+ ```
349
+
350
+ ### Slide In
351
+
352
+ ```tsx
353
+ function SlideIn({ children, from = "left" }) {
354
+ const [offset, setOffset] = useState(from === "left" ? -20 : 20)
355
+
356
+ const timeline = useTimeline()
357
+
358
+ useEffect(() => {
359
+ timeline.add(
360
+ { offset: from === "left" ? -20 : 20 },
361
+ {
362
+ offset: 0,
363
+ duration: 300,
364
+ ease: "easeOutCubic",
365
+ onUpdate: (anim) => {
366
+ setOffset(Math.round(anim.targets[0].offset))
367
+ },
368
+ }
369
+ )
370
+ }, [])
371
+
372
+ return (
373
+ <box position="relative" left={offset}>
374
+ {children}
375
+ </box>
376
+ )
377
+ }
378
+ ```
379
+
380
+ ## Performance Tips
381
+
382
+ ### Batch Updates
383
+
384
+ Timeline automatically batches updates within the render loop.
385
+
386
+ ### Use Integer Values
387
+
388
+ Round animated values for character-based positioning:
389
+
390
+ ```typescript
391
+ onUpdate: (anim) => {
392
+ setX(Math.round(anim.targets[0].x))
393
+ }
394
+ ```
395
+
396
+ ### Clean Up Timelines
397
+
398
+ Hooks automatically clean up, but for core:
399
+
400
+ ```typescript
401
+ // When done with timeline
402
+ engine.removeTimeline(timeline)
403
+ ```
404
+
405
+ ## Gotchas
406
+
407
+ ### Terminal Refresh Rate
408
+
409
+ Terminal UIs typically refresh at 60 FPS max. Very fast animations may appear choppy.
410
+
411
+ ### Character Grid
412
+
413
+ Animations are constrained to character cells. Sub-pixel positioning isn't possible.
414
+
415
+ ### Cleanup in Effects
416
+
417
+ Always clean up intervals and timelines:
418
+
419
+ ```tsx
420
+ useEffect(() => {
421
+ const interval = setInterval(...)
422
+ return () => clearInterval(interval)
423
+ }, [])
424
+ ```
425
+
426
+ ## See Also
427
+
428
+ - [React API](../react/api.md) - `useTimeline` hook reference
429
+ - [Solid API](../solid/api.md) - `useTimeline` hook reference
430
+ - [Core API](../core/api.md) - `AnimationEngine` and `Timeline` classes
431
+ - [Layout Patterns](../layout/patterns.md) - Animated positioning and transitions