@telemetryos/cli 1.9.0 → 1.11.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 (41) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/dist/commands/auth.js +8 -15
  3. package/dist/commands/init.js +131 -68
  4. package/dist/commands/publish.d.ts +22 -0
  5. package/dist/commands/publish.js +238 -0
  6. package/dist/index.js +2 -0
  7. package/dist/plugins/math-tools.d.ts +2 -0
  8. package/dist/plugins/math-tools.js +18 -0
  9. package/dist/services/api-client.d.ts +18 -0
  10. package/dist/services/api-client.js +70 -0
  11. package/dist/services/archiver.d.ts +4 -0
  12. package/dist/services/archiver.js +65 -0
  13. package/dist/services/build-poller.d.ts +10 -0
  14. package/dist/services/build-poller.js +63 -0
  15. package/dist/services/cli-config.d.ts +10 -0
  16. package/dist/services/cli-config.js +45 -0
  17. package/dist/services/generate-application.d.ts +2 -1
  18. package/dist/services/generate-application.js +31 -32
  19. package/dist/services/project-config.d.ts +24 -0
  20. package/dist/services/project-config.js +51 -0
  21. package/dist/services/run-server.js +29 -73
  22. package/dist/types/api.d.ts +44 -0
  23. package/dist/types/api.js +1 -0
  24. package/dist/types/applications.d.ts +44 -0
  25. package/dist/types/applications.js +1 -0
  26. package/dist/utils/ansi.d.ts +10 -0
  27. package/dist/utils/ansi.js +10 -0
  28. package/dist/utils/path-utils.d.ts +55 -0
  29. package/dist/utils/path-utils.js +99 -0
  30. package/package.json +4 -2
  31. package/templates/vite-react-typescript/CLAUDE.md +14 -6
  32. package/templates/vite-react-typescript/_claude/skills/tos-architecture/SKILL.md +4 -28
  33. package/templates/vite-react-typescript/_claude/skills/tos-multi-mode/SKILL.md +359 -0
  34. package/templates/vite-react-typescript/_claude/skills/tos-render-design/SKILL.md +304 -12
  35. package/templates/vite-react-typescript/_claude/skills/tos-render-kiosk-design/SKILL.md +384 -0
  36. package/templates/vite-react-typescript/_claude/skills/tos-render-signage-design/SKILL.md +515 -0
  37. package/templates/vite-react-typescript/_claude/skills/tos-render-ui-design/SKILL.md +325 -0
  38. package/templates/vite-react-typescript/_claude/skills/tos-requirements/SKILL.md +405 -125
  39. package/templates/vite-react-typescript/_claude/skills/tos-store-sync/SKILL.md +96 -5
  40. package/templates/vite-react-typescript/_claude/skills/tos-weather-api/SKILL.md +443 -269
  41. package/templates/vite-react-typescript/index.html +1 -1
@@ -0,0 +1,325 @@
1
+ ---
2
+ name: tos-render-ui-design
3
+ description: Foundation for TelemetryOS Render views. MUST use FIRST before tos-render-signage-design or tos-render-kiosk-design. Covers UI scaling, rem usage, responsive layouts, and best practices for all display types.
4
+ ---
5
+
6
+ # Render View UI Design (Foundation)
7
+
8
+ This skill covers the foundational UI design patterns for ALL TelemetryOS Render views, whether building digital signage (display-only) or interactive kiosks (touch-enabled).
9
+
10
+ > **Note:** Always read this skill FIRST, then read either `tos-render-signage-design` (display-only) or `tos-render-kiosk-design` (interactive) depending on your use case.
11
+
12
+ > **Base styles:** The init project already provides base infrastructural styles in `index.css` (viewport scaling, box-sizing) and `Render.css` (`.render` class with padding, overflow, flexbox). Build on these—don't override them. But feel free to build a new visual theme.
13
+
14
+
15
+ ## Design Thinking
16
+
17
+ Before coding, understand the context and commit to a BOLD aesthetic direction:
18
+ - **Purpose**: What problem does this interface solve? Who uses it?
19
+ - **Tone**: Pick an extreme: brutally minimal, maximalist chaos, retro-futuristic, organic/natural, luxury/refined, playful/toy-like, editorial/magazine, brutalist/raw, art deco/geometric, soft/pastel, industrial/utilitarian, etc. There are so many flavors to choose from. Use these for inspiration but design one that is true to the aesthetic direction.
20
+ - **Constraints**: Technical requirements (framework, performance, accessibility).
21
+ - **Differentiation**: What makes this UNFORGETTABLE? What's the one thing someone will remember?
22
+
23
+ **CRITICAL**: Choose a clear conceptual direction and execute it with precision. Bold maximalism and refined minimalism both work - the key is intentionality, not intensity.
24
+
25
+ Then implement working code (HTML/CSS/JS, React, Vue, etc.) that is:
26
+ - Production-grade and functional
27
+ - Visually striking and memorable
28
+ - Cohesive with a clear aesthetic point-of-view
29
+ - Meticulously refined in every detail
30
+
31
+ ## Frontend Aesthetics Guidelines
32
+
33
+ Focus on:
34
+ - **Typography**: Choose fonts that are beautiful, unique, and interesting. Avoid generic fonts like Arial and Inter; opt instead for distinctive choices that elevate the frontend's aesthetics; unexpected, characterful font choices. Pair a distinctive display font with a refined body font.
35
+ - **Color & Theme**: Commit to a cohesive aesthetic. Use CSS variables for consistency. Dominant colors with sharp accents outperform timid, evenly-distributed palettes.
36
+ - **Motion**: Use animations for effects and micro-interactions. Prioritize CSS-only solutions for HTML. Use Motion library for React when available. Focus on high-impact moments: one well-orchestrated page load with staggered reveals (animation-delay) creates more delight than scattered micro-interactions. Use scroll-triggering and hover states that surprise.
37
+ - **Spatial Composition**: Unexpected layouts. Asymmetry. Overlap. Diagonal flow. Grid-breaking elements. Generous negative space OR controlled density.
38
+ - **Backgrounds & Visual Details**: Create atmosphere and depth rather than defaulting to solid colors. Add contextual effects and textures that match the overall aesthetic. Apply creative forms like gradient meshes, noise textures, geometric patterns, layered transparencies, dramatic shadows, decorative borders, custom cursors, and grain overlays.
39
+
40
+ NEVER use generic AI-generated aesthetics like overused font families (Inter, Roboto, Arial, system fonts), cliched color schemes (particularly purple gradients on white backgrounds), predictable layouts and component patterns, and cookie-cutter design that lacks context-specific character.
41
+
42
+ Interpret creatively and make unexpected choices that feel genuinely designed for the context. No design should be the same. Vary between light and dark themes, different fonts, different aesthetics. NEVER converge on common choices (Space Grotesk, for example) across generations.
43
+
44
+ **IMPORTANT**: Match implementation complexity to the aesthetic vision. Maximalist designs need elaborate code with extensive animations and effects. Minimalist or refined designs need restraint, precision, and careful attention to spacing, typography, and subtle details. Elegance comes from executing the vision well.
45
+
46
+ Remember: Claude is capable of extraordinary creative work. Don't hold back, show what can truly be created when thinking outside the box and committing fully to a distinctive vision.
47
+
48
+ ---
49
+
50
+ ## Quick Reference
51
+
52
+ | Concept | Key Points | Where Used |
53
+ |---------|-----------|------------|
54
+ | UI Scaling | Call `useUiScaleToSetRem(uiScale)` once in Render | All render views |
55
+ | rem Units | All sizing in rem (not px) | All styles |
56
+ | Title Safe Zone | Keep ~3rem padding from edges | All layouts |
57
+ | Text Size | Minimum 2rem for body, 4rem for headlines | All text |
58
+ | Flex Layouts | Use `min-height: 0` on flex children | All containers |
59
+ | Text Overflow | Truncate with ellipsis or line-clamp | All text that might overflow |
60
+ | Responsive | Use `useUiAspectRatio()` for portrait/landscape | Adaptive layouts |
61
+ | Outside-In Layout | Divide viewport space first, components fill allocations (see signage skill) | Signage layouts |
62
+
63
+ **Next steps after reading:**
64
+ - Display-only content? → Read `tos-render-signage-design`
65
+ - Interactive kiosk? → Read `tos-render-kiosk-design`
66
+
67
+ ---
68
+
69
+ ## UI Scale System
70
+
71
+ Displays range from tablets to 8K video walls. Standard CSS pixels create inconsistent sizing. The SDK provides hooks that redefine `rem` as viewport-relative:
72
+
73
+ ### useUiScaleToSetRem(uiScale)
74
+
75
+ Sets the document's root font-size based on viewport. **Call once in your Render view:**
76
+
77
+ ```typescript
78
+ import { useUiScaleToSetRem } from '@telemetryos/sdk/react'
79
+ import { useUiScaleStoreState } from '../hooks/store'
80
+
81
+ export function Render() {
82
+ const [_isLoading, uiScale] = useUiScaleStoreState()
83
+ useUiScaleToSetRem(uiScale)
84
+
85
+ return <div className="content">...</div>
86
+ }
87
+ ```
88
+
89
+ **How it works:**
90
+ - At scale 1: `1rem` = 1% of viewport's longest dimension
91
+ - At scale 2: `1rem` = 2% of viewport's longest dimension
92
+ - A 2rem font occupies identical screen percentage on Full HD and 4K
93
+
94
+ ### useUiAspectRatio()
95
+
96
+ Returns current aspect ratio, updating on resize:
97
+
98
+ ```typescript
99
+ import { useUiAspectRatio } from '@telemetryos/sdk/react'
100
+
101
+ export function Render() {
102
+ const aspectRatio = useUiAspectRatio()
103
+
104
+ // > 1 = landscape, < 1 = portrait, = 1 = square
105
+ const isPortrait = aspectRatio < 1
106
+
107
+ return (
108
+ <div className={isPortrait ? 'portrait-layout' : 'landscape-layout'}>
109
+ ...
110
+ </div>
111
+ )
112
+ }
113
+ ```
114
+
115
+ ---
116
+
117
+ ## Layout Fundamentals
118
+
119
+ ### Use rem for Everything
120
+
121
+ All sizing should use `rem` to scale with the UI scale setting:
122
+
123
+ ```css
124
+ /* CORRECT - Scales with viewport */
125
+ .title {
126
+ font-size: 4rem;
127
+ margin-bottom: 1rem;
128
+ }
129
+
130
+ .card {
131
+ padding: 2rem;
132
+ border-radius: 0.5rem;
133
+ }
134
+ ```
135
+
136
+ ```css
137
+ /* WRONG - Fixed pixels don't scale */
138
+ .title {
139
+ font-size: 48px;
140
+ margin-bottom: 12px;
141
+ }
142
+ ```
143
+
144
+ ### Title Safe Zone
145
+
146
+ The init project's `.render` class already applies ~3rem padding from screen edges (SMPTE ST 2046-1 standard for avoiding bezel cutoff). Keep this padding when building your layout.
147
+
148
+ ### Constrain Layouts
149
+
150
+ The init project's `index.css` and `.render` class already set up the base layout with `overflow: hidden` and flexbox. When adding child elements, use `min-height: 0` or `min-width: 0` on flex children to allow them to shrink:
151
+
152
+ ```css
153
+ .my-content {
154
+ flex: 1;
155
+ min-height: 0; /* Allows flex children to shrink below content size */
156
+ }
157
+ ```
158
+
159
+ ### Text Truncation
160
+
161
+ When text might overflow, truncate gracefully:
162
+
163
+ ```css
164
+ /* Single line truncation */
165
+ .title {
166
+ white-space: nowrap;
167
+ overflow: hidden;
168
+ text-overflow: ellipsis;
169
+ }
170
+
171
+ /* Multi-line truncation */
172
+ .description {
173
+ display: -webkit-box;
174
+ -webkit-line-clamp: 3;
175
+ -webkit-box-orient: vertical;
176
+ overflow: hidden;
177
+ }
178
+ ```
179
+
180
+ ---
181
+
182
+ ## Typography
183
+
184
+ ### Minimum Text Size
185
+
186
+ Text should be no smaller than ~2rem for comfortable viewing at typical distances (approximately 4% of screen height):
187
+
188
+ ```css
189
+ .body-text {
190
+ font-size: 2rem; /* Minimum readable size */
191
+ }
192
+
193
+ .headline {
194
+ font-size: 4rem;
195
+ }
196
+
197
+ .small-label {
198
+ font-size: 1.5rem; /* Use sparingly */
199
+ }
200
+ ```
201
+
202
+ **Why 2rem minimum?**
203
+ - Content is viewed from a distance (not handheld)
204
+ - Smaller text becomes unreadable
205
+ - 2rem ≈ 4% of screen height at scale 1
206
+
207
+ ---
208
+
209
+ ## Responsive Design
210
+
211
+ ### Adaptive Content for Orientation
212
+
213
+ Use `useUiAspectRatio()` to adapt layouts for portrait vs landscape:
214
+
215
+ ```typescript
216
+ function Dashboard() {
217
+ const aspectRatio = useUiAspectRatio()
218
+ const isPortrait = aspectRatio < 1
219
+
220
+ return (
221
+ <div className={`dashboard ${isPortrait ? 'dashboard--portrait' : ''}`}>
222
+ <PrimaryContent />
223
+ {/* Hide sidebar in portrait mode */}
224
+ {!isPortrait && <Sidebar />}
225
+ </div>
226
+ )
227
+ }
228
+ ```
229
+
230
+ ```css
231
+ .dashboard {
232
+ display: flex;
233
+ gap: 2rem;
234
+ }
235
+
236
+ .dashboard--portrait {
237
+ flex-direction: column;
238
+ }
239
+ ```
240
+
241
+ ---
242
+
243
+ ## Store Hook for UI Scale
244
+
245
+ Create a store hook to let admins adjust the UI scale in Settings:
246
+
247
+ ```typescript
248
+ // hooks/store.ts
249
+ import { createUseInstanceStoreState } from '@telemetryos/sdk/react'
250
+
251
+ export const useUiScaleStoreState = createUseInstanceStoreState<number>('ui-scale', 1)
252
+ ```
253
+
254
+ ```typescript
255
+ // Settings.tsx - Add slider control
256
+ import { SettingsSliderFrame, SettingsField, SettingsLabel } from '@telemetryos/sdk/react'
257
+ import { useUiScaleStoreState } from '../hooks/store'
258
+
259
+ export function Settings() {
260
+ // Pass 0 debounce for instant slider updates
261
+ const [isLoading, uiScale, setUiScale] = useUiScaleStoreState(0)
262
+
263
+ return (
264
+ <SettingsField>
265
+ <SettingsLabel>UI Scale</SettingsLabel>
266
+ <SettingsSliderFrame>
267
+ <input
268
+ type="range"
269
+ min={1}
270
+ max={3}
271
+ step={0.01}
272
+ disabled={isLoading}
273
+ value={uiScale}
274
+ onChange={(e) => setUiScale(parseFloat(e.target.value))}
275
+ />
276
+ <span>{uiScale}x</span>
277
+ </SettingsSliderFrame>
278
+ </SettingsField>
279
+ )
280
+ }
281
+ ```
282
+
283
+ ---
284
+
285
+ ## Best Practices Summary
286
+
287
+ ✅ **Use rem everywhere** - All sizing should use rem units, not px
288
+ ✅ **Call useUiScaleToSetRem() once** - In Render view with uiScale from store
289
+ ✅ **Respect title safe zone** - Keep the ~3rem padding from init project
290
+ ✅ **Keep text readable** - Minimum 2rem for body, 4rem for headlines
291
+ ✅ **Constrain flex layouts** - Use `min-height: 0` on flex children
292
+ ✅ **Truncate overflow** - Use ellipsis or line-clamp for text that might overflow
293
+ ✅ **Adapt to orientation** - Use `useUiAspectRatio()` for portrait/landscape layouts
294
+ ✅ **Don't override base styles** - Build on index.css, don't replace it
295
+
296
+ ---
297
+
298
+ ## Common Mistakes
299
+
300
+ | Mistake | Problem | Fix |
301
+ |---------|---------|-----|
302
+ | Using `px` units | Won't scale across resolutions | Use `rem` everywhere |
303
+ | Fixed heights in `px` | Breaks on different aspect ratios | Use `vh`, `%`, or flex |
304
+ | Forgetting `useUiScaleToSetRem()` | `rem` units won't scale properly | Call it once in Render view with uiScale |
305
+ | Text below 2rem | Unreadable from viewing distance | Minimum 2rem for body text |
306
+ | Removing `.render` padding | Content cut off by bezels | Keep the ~3rem padding from init project |
307
+ | Overriding `index.css` base styles | Breaks viewport scaling | Add new styles, don't modify base setup |
308
+
309
+ ---
310
+
311
+ ## Next Steps
312
+
313
+ After mastering these foundational concepts, read the appropriate specialized skill:
314
+
315
+ ### Building Display-Only Content (Digital Signage)?
316
+ → Read `tos-render-signage-design`
317
+ - No user interaction patterns
318
+ - No scrolling constraints
319
+ - Auto-rotation considerations
320
+
321
+ ### Building Interactive Content (Kiosk)?
322
+ → Read `tos-render-kiosk-design`
323
+ - Touch interaction patterns
324
+ - Idle timeout behavior
325
+ - Navigation state management