@archetypeai/ds-cli 0.3.7 → 0.3.10

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 (28) hide show
  1. package/README.md +25 -67
  2. package/commands/create.js +5 -27
  3. package/commands/init.js +5 -27
  4. package/files/AGENTS.md +19 -3
  5. package/files/CLAUDE.md +21 -3
  6. package/files/rules/accessibility.md +49 -0
  7. package/files/rules/frontend-architecture.md +77 -0
  8. package/files/skills/apply-ds/SKILL.md +92 -80
  9. package/files/skills/apply-ds/scripts/audit.sh +169 -0
  10. package/files/skills/apply-ds/scripts/setup.sh +48 -166
  11. package/files/skills/create-dashboard/SKILL.md +12 -0
  12. package/files/skills/embedding-from-file/SKILL.md +415 -0
  13. package/files/skills/embedding-from-sensor/SKILL.md +406 -0
  14. package/files/skills/embedding-upload/SKILL.md +414 -0
  15. package/files/skills/fix-accessibility/SKILL.md +57 -9
  16. package/files/skills/newton-activity-monitor-lens-on-video/SKILL.md +817 -0
  17. package/files/skills/newton-camera-frame-analysis/SKILL.md +611 -0
  18. package/files/skills/newton-camera-frame-analysis/scripts/activity-monitor-frame.py +165 -0
  19. package/files/skills/newton-camera-frame-analysis/scripts/captures/logs/api_responses_20260206_105610.json +62 -0
  20. package/files/skills/newton-camera-frame-analysis/scripts/continuous_monitor.py +119 -0
  21. package/files/skills/newton-direct-query/SKILL.md +212 -0
  22. package/files/skills/newton-direct-query/scripts/direct_query.py +129 -0
  23. package/files/skills/newton-machine-state-from-file/SKILL.md +545 -0
  24. package/files/skills/newton-machine-state-from-sensor/SKILL.md +707 -0
  25. package/files/skills/newton-machine-state-upload/SKILL.md +986 -0
  26. package/lib/add-ds-ui-svelte.js +5 -2
  27. package/lib/scaffold-ds-svelte-project.js +25 -18
  28. package/package.json +13 -2
package/README.md CHANGED
@@ -1,123 +1,81 @@
1
1
  ## @archetypeai/ds-cli
2
2
 
3
- `@archetypeai/ds-cli` is the CLI for the **Archetype AI Design System**. It provides commands for creating, configuring, and managing projects that use the design system.
3
+ CLI for the **Archetype AI Design System**. Scaffold new projects, add the design system to existing ones, and manage components and agent configurations.
4
4
 
5
5
  ---
6
6
 
7
- ## Commands
8
-
9
- ### `create` — Scaffold a new project
7
+ Run directly with `npx`:
10
8
 
11
9
  ```bash
12
10
  npx @archetypeai/ds-cli create my-app
13
11
  ```
14
12
 
15
- Scaffolds a full SvelteKit + Tailwind v4 + shadcn-svelte project:
13
+ ---
14
+
15
+ ## Commands
16
+
17
+ ### `create` → Scaffold a new project
16
18
 
17
- 1. Creates a SvelteKit project via `sv create`
18
- 2. Installs design tokens (`@archetypeai/ds-lib-tokens`)
19
- 3. Optionally installs internal fonts (`@archetypeai/ds-lib-fonts-internal`)
20
- 4. Initializes shadcn-svelte (`components.json`, `utils.js`, dependencies)
21
- 5. Configures CSS (`layout.css` with design tokens and optional fonts import)
22
- 6. Installs all components from the design system registry
23
- 7. Optionally installs AI agent configuration (Cursor or Claude Code)
24
- 8. Creates a demo page with Button examples
19
+ ```bash
20
+ npx @archetypeai/ds-cli create my-app
21
+ ```
25
22
 
26
- #### Create flags
23
+ Sets up a SvelteKit + Tailwind v4 + shadcn-svelte project with design tokens, components, and an optional demo page.
27
24
 
28
25
  | Flag | Values | Default |
29
26
  |------|--------|---------|
30
27
  | `--framework` | `svelte` | prompt |
31
28
  | `--pm` | `npm`, `pnpm`, `bun`, `yarn` | prompt |
32
- | `--fonts` / `--no-fonts` | boolean | prompt (default: yes) |
33
- | `--no-components` | skip component installation | install all |
29
+ | `--no-components` | skip component install | install all |
34
30
  | `--codeagent` | `cursor`, `claude`, `none` | prompt |
35
31
 
36
32
  ```bash
37
- npx @archetypeai/ds-cli create my-app --framework svelte --pm pnpm --no-fonts --codeagent none
33
+ npx @archetypeai/ds-cli create my-app --framework svelte --pm pnpm --codeagent none
38
34
  ```
39
35
 
40
36
  ---
41
37
 
42
- ### `init` Add DS to an existing project
38
+ ### `init` Add DS to an existing project
43
39
 
44
40
  ```bash
45
41
  cd my-existing-app
46
42
  npx @archetypeai/ds-cli init
47
43
  ```
48
44
 
49
- Run from an existing SvelteKit project root. Detects your package manager from the lockfile and installs the design system without creating a new project:
50
-
51
- 1. Detects project (verifies `package.json` and `svelte.config.js`)
52
- 2. Auto-detects package manager from lockfile
53
- 3. Installs Tailwind CSS v4 if not already present
54
- 4. Installs design tokens
55
- 5. Optionally installs internal fonts
56
- 6. Initializes shadcn-svelte
57
- 7. Prepends DS imports to existing `layout.css` (preserves your styles)
58
- 8. Installs all components from the registry
59
- 9. Optionally installs AI agent configuration
60
-
61
- #### Init flags
45
+ Run from a SvelteKit project root. Auto-detects your package manager, installs tokens, shadcn-svelte, and components, and prepends DS imports to your `layout.css` (preserving existing styles).
62
46
 
63
47
  | Flag | Values | Default |
64
48
  |------|--------|---------|
65
- | `--pm` | `npm`, `pnpm`, `bun`, `yarn` | auto-detect from lockfile |
66
- | `--fonts` / `--no-fonts` | boolean | prompt (default: yes) |
67
- | `--no-components` | skip component installation | install all |
49
+ | `--pm` | `npm`, `pnpm`, `bun`, `yarn` | auto-detect |
50
+ | `--no-components` | skip component install | install all |
68
51
  | `--codeagent` | `cursor`, `claude`, `none` | prompt |
69
52
 
70
53
  ```bash
71
- npx @archetypeai/ds-cli init --pm npm --no-fonts --codeagent none
54
+ npx @archetypeai/ds-cli init --pm npm --codeagent none
72
55
  ```
73
56
 
74
57
  ---
75
58
 
76
- ### `add` Add components or agent configurations
59
+ ### `add` Add components or agent config
77
60
 
78
- #### `add ds-ui-svelte` — Install all design system components
61
+ #### `add ds-ui-svelte`
79
62
 
80
63
  ```bash
81
64
  npx @archetypeai/ds-cli add ds-ui-svelte
82
65
  ```
83
66
 
84
- Installs all components from the design system registry into your project. Requires shadcn-svelte to be initialized (`components.json` must exist).
67
+ Installs all components from the registry. Requires shadcn-svelte (`components.json` must exist).
85
68
 
86
- #### `add ds-config-codeagent` — Install agent configuration
69
+ #### `add ds-config-codeagent`
87
70
 
88
71
  ```bash
89
72
  npx @archetypeai/ds-cli add ds-config-codeagent --cursor
90
73
  npx @archetypeai/ds-cli add ds-config-codeagent --claude
91
74
  ```
92
75
 
93
- Installs agent configuration files (AGENTS.md/CLAUDE.md, skills, and rules) for the specified IDE. If no flag is provided, an interactive prompt will ask which IDE to configure.
94
-
95
76
  | Flag | Effect |
96
77
  |------|--------|
97
- | `--cursor` | Copies AGENTS.md, skills, and rules to `.cursor/` |
98
- | `--claude` | Copies CLAUDE.md, skills, and rules to `.claude/` |
99
-
100
- ---
101
-
102
- ## Environment Variables
103
-
104
- | Variable | Default | Description |
105
- |----------|---------|-------------|
106
- | `REGISTRY_URL` | `https://design-system.archetypeai.workers.dev` | Override the component registry URL for testing or private registries |
107
-
108
- ---
109
-
110
- ## Security
111
-
112
- The CLI validates all data from external sources before use:
113
-
114
- - **Registry URLs** are validated against an HTTPS + `/r/<name>.json` pattern before being passed to any shell command
115
- - **Shell commands** use `execFileSync` (no shell interpolation) to prevent injection even if validation is bypassed
116
- - **Package manager** and **framework** flag values are validated against known allowlists
117
- - **Fetch requests** have a 15-second timeout to prevent hanging on unresponsive registries
118
-
119
- ---
120
-
121
- ## Fonts
78
+ | `--cursor` | Installs AGENTS.md, skills, and rules to `.cursor/` |
79
+ | `--claude` | Installs CLAUDE.md, skills, and rules to `.claude/` |
122
80
 
123
- The internal fonts package (`@archetypeai/ds-lib-fonts-internal`) is not yet published. When available, it will be on npmjs.org. If omitted, the theme falls back to system fonts.
81
+ Without a flag, an interactive prompt asks which IDE to configure.
@@ -6,7 +6,6 @@ import { fetchComponents } from '../lib/use-shadcn-svelte-registry.js';
6
6
  import {
7
7
  runSvCreate,
8
8
  installTokens,
9
- installFonts,
10
9
  initShadcn,
11
10
  configureCss,
12
11
  installComponents,
@@ -20,7 +19,6 @@ export function parseFlags(args) {
20
19
  name: null,
21
20
  framework: null,
22
21
  pm: null,
23
- fonts: null,
24
22
  components: true,
25
23
  agent: null
26
24
  };
@@ -31,10 +29,6 @@ export function parseFlags(args) {
31
29
  flags.framework = args[++i];
32
30
  } else if (arg === '--pm' && args[i + 1]) {
33
31
  flags.pm = args[++i];
34
- } else if (arg === '--fonts') {
35
- flags.fonts = true;
36
- } else if (arg === '--no-fonts') {
37
- flags.fonts = false;
38
32
  } else if (arg === '--no-components') {
39
33
  flags.components = false;
40
34
  } else if (arg === '--codeagent' && args[i + 1]) {
@@ -139,38 +133,22 @@ export async function create(args) {
139
133
  }
140
134
 
141
135
  // create SvelteKit project
142
- const created = runSvCreate(pm, name, targetDir);
136
+ const created = await runSvCreate(pm, name, targetDir);
143
137
  if (!created) {
144
138
  process.exit(1);
145
139
  }
146
140
 
147
- // specify fonts
148
- let includeFonts = flags.fonts;
149
- if (includeFonts === null) {
150
- includeFonts = await p.confirm({
151
- message: 'Install internal fonts package?',
152
- initialValue: true
153
- });
154
- if (p.isCancel(includeFonts)) {
155
- p.cancel('Setup cancelled.');
156
- process.exit(0);
157
- }
158
- }
159
-
160
141
  // install packages
161
- const tokensOk = installTokens(pm, projectPath);
142
+ const tokensOk = await installTokens(pm, projectPath);
162
143
  if (!tokensOk) {
163
144
  process.exit(1);
164
145
  }
165
146
 
166
- if (includeFonts) {
167
- installFonts(pm, projectPath);
168
- }
169
-
170
147
  // init shadcn-svelte
171
- initShadcn(pm, projectPath);
148
+ await initShadcn(pm, projectPath);
172
149
 
173
150
  // configure CSS
151
+ const includeFonts = false;
174
152
  configureCss(projectPath, includeFonts);
175
153
 
176
154
  // install components
@@ -180,7 +158,7 @@ export async function create(args) {
180
158
  s.start('Fetching component list');
181
159
  const components = await fetchComponents();
182
160
  s.stop(`Found ${components.length} components`);
183
- installComponents(pm, projectPath, components);
161
+ await installComponents(pm, projectPath, components);
184
162
  } catch (error) {
185
163
  p.log.warn(`Component installation skipped: ${error.message}`);
186
164
  }
package/commands/init.js CHANGED
@@ -6,7 +6,6 @@ import { fetchComponents } from '../lib/use-shadcn-svelte-registry.js';
6
6
  import {
7
7
  installTailwind,
8
8
  installTokens,
9
- installFonts,
10
9
  initShadcn,
11
10
  prependCss,
12
11
  installComponents,
@@ -17,7 +16,6 @@ import {
17
16
  export function parseFlags(args) {
18
17
  const flags = {
19
18
  pm: null,
20
- fonts: null,
21
19
  components: true,
22
20
  agent: null
23
21
  };
@@ -26,10 +24,6 @@ export function parseFlags(args) {
26
24
  const arg = args[i];
27
25
  if (arg === '--pm' && args[i + 1]) {
28
26
  flags.pm = args[++i];
29
- } else if (arg === '--fonts') {
30
- flags.fonts = true;
31
- } else if (arg === '--no-fonts') {
32
- flags.fonts = false;
33
27
  } else if (arg === '--no-components') {
34
28
  flags.components = false;
35
29
  } else if (arg === '--codeagent' && args[i + 1]) {
@@ -107,39 +101,23 @@ export async function init(args) {
107
101
  // detect and install Tailwind if missing
108
102
  if (!hasTailwind(projectPath)) {
109
103
  p.log.info('Tailwind CSS not found in dependencies.');
110
- const tailwindOk = installTailwind(pm, projectPath);
104
+ const tailwindOk = await installTailwind(pm, projectPath);
111
105
  if (!tailwindOk) {
112
106
  process.exit(1);
113
107
  }
114
108
  }
115
109
 
116
- // specify fonts
117
- let includeFonts = flags.fonts;
118
- if (includeFonts === null) {
119
- includeFonts = await p.confirm({
120
- message: 'Install internal fonts package?',
121
- initialValue: true
122
- });
123
- if (p.isCancel(includeFonts)) {
124
- p.cancel('Setup cancelled.');
125
- process.exit(0);
126
- }
127
- }
128
-
129
110
  // install packages
130
- const tokensOk = installTokens(pm, projectPath);
111
+ const tokensOk = await installTokens(pm, projectPath);
131
112
  if (!tokensOk) {
132
113
  process.exit(1);
133
114
  }
134
115
 
135
- if (includeFonts) {
136
- installFonts(pm, projectPath);
137
- }
138
-
139
116
  // init shadcn-svelte
140
- initShadcn(pm, projectPath);
117
+ await initShadcn(pm, projectPath);
141
118
 
142
119
  // configure CSS (prepend to existing)
120
+ const includeFonts = false;
143
121
  prependCss(projectPath, includeFonts);
144
122
 
145
123
  // install components
@@ -149,7 +127,7 @@ export async function init(args) {
149
127
  s.start('Fetching component list');
150
128
  const components = await fetchComponents();
151
129
  s.stop(`Found ${components.length} components`);
152
- installComponents(pm, projectPath, components);
130
+ await installComponents(pm, projectPath, components);
153
131
  } catch (error) {
154
132
  p.log.warn(`Component installation skipped: ${error.message}`);
155
133
  }
package/files/AGENTS.md CHANGED
@@ -28,7 +28,6 @@ Standard Tailwind is fine for:
28
28
 
29
29
  - Spacing/sizing: `p-4`, `w-full`, `gap-2`, `h-screen`
30
30
  - Layout: `flex`, `grid`, `absolute`, `relative`
31
- - One-off colors: gradients, illustrations, custom accents
32
31
 
33
32
  ## CSS Import Order
34
33
 
@@ -49,15 +48,32 @@ Standard Tailwind is fine for:
49
48
 
50
49
  Read these when relevant to your task:
51
50
 
52
- - `@skills/apply-ds` - setup tokens in new project
51
+ - `@skills/apply-ds` - apply DS tokens, components, and patterns to an existing demo
53
52
  - `@skills/build-pattern` - create composite patterns from primitives
54
53
  - `@skills/setup-chart` - set up charts with layerchart
55
54
  - `@skills/create-dashboard` - scaffold a full-viewport dashboard with menubar and panels
56
55
  - `@skills/fix-accessibility` - audit and fix a11y issues
57
56
  - `@skills/fix-metadata` - update page titles, favicons, and OG tags
58
57
  - `@skills/deploy-worker` - deploy SvelteKit projects to Cloudflare Workers
59
- - `@skills/explain-code` - explain code with structure and traced execution
58
+ - `@skills/embedding-from-file` - run an Embedding Lens by streaming sensor data from a CSV file
59
+ - `@skills/embedding-from-sensor` - run an Embedding Lens by streaming real-time data from a physical sensor
60
+ - `@skills/embedding-upload` - run an Embedding Lens by uploading a CSV file for server-side processing
61
+ - `@skills/newton-activity-monitor-lens-on-video` - analyze uploaded video files using Newton's activity monitor lens
62
+ - `@skills/newton-camera-frame-analysis` - live webcam frame analysis using Newton's vision model
63
+ - `@skills/newton-direct-query` - simple direct query to Newton model using the /query API endpoint
64
+ - `@skills/newton-machine-state-from-file` - run a Machine State Lens by streaming sensor data from a CSV file
65
+ - `@skills/newton-machine-state-from-sensor` - run a Machine State Lens by streaming real-time data from a physical sensor
66
+ - `@skills/newton-machine-state-upload` - run a Machine State Lens by uploading a CSV file for server-side processing
60
67
 
61
68
  ## Rules
62
69
 
63
70
  See `@rules/` for comprehensive guidance on design principles, components, styling, charts, and linting.
71
+
72
+ - `@rules/accessibility` — a11y guidelines and ARIA patterns
73
+ - `@rules/charts` — chart setup, layerchart conventions, data visualization
74
+ - `@rules/components` — component API patterns, props, variants, slots
75
+ - `@rules/design-principles` — visual design language, spacing, typography
76
+ - `@rules/frontend-architecture` — component decomposition, page composition, API logic extraction
77
+ - `@rules/linting` — linting and formatting rules
78
+ - `@rules/state` — state management with Svelte 5 runes
79
+ - `@rules/styling` — Tailwind v4, semantic tokens, theming
package/files/CLAUDE.md CHANGED
@@ -28,7 +28,6 @@ Standard Tailwind is fine for:
28
28
 
29
29
  - Spacing/sizing: `p-4`, `w-full`, `gap-2`, `h-screen`
30
30
  - Layout: `flex`, `grid`, `absolute`, `relative`
31
- - One-off colors: gradients, illustrations, custom accents
32
31
 
33
32
  ## CSS Import Order
34
33
 
@@ -47,17 +46,36 @@ Standard Tailwind is fine for:
47
46
 
48
47
  ## Skills
49
48
 
49
+ **Skill composition:** When building a demo that uses a Newton or Embedding API skill, also consult `@skills/create-dashboard` for dashboard layouts and `@skills/build-pattern` for extracting components. Only include chart components (SensorChart, ScatterChart) if the user's request involves time-series or explicitly mentions charts.
50
+
50
51
  Read these when relevant to your task:
51
52
 
52
- - `@skills/apply-ds` - setup tokens in new project
53
+ - `@skills/apply-ds` - apply DS tokens, components, and patterns to an existing demo
53
54
  - `@skills/build-pattern` - create composite patterns from primitives
54
55
  - `@skills/setup-chart` - set up charts with layerchart
55
56
  - `@skills/create-dashboard` - scaffold a full-viewport dashboard with menubar and panels
56
57
  - `@skills/fix-accessibility` - audit and fix a11y issues
57
58
  - `@skills/fix-metadata` - update page titles, favicons, and OG tags
58
59
  - `@skills/deploy-worker` - deploy SvelteKit projects to Cloudflare Workers
59
- - `@skills/explain-code` - explain code with structure and traced execution
60
+ - `@skills/embedding-from-file` - run an Embedding Lens by streaming sensor data from a CSV file
61
+ - `@skills/embedding-from-sensor` - run an Embedding Lens by streaming real-time data from a physical sensor
62
+ - `@skills/embedding-upload` - run an Embedding Lens by uploading a CSV file for server-side processing
63
+ - `@skills/newton-activity-monitor-lens-on-video` - analyze uploaded video files using Newton's activity monitor lens
64
+ - `@skills/newton-camera-frame-analysis` - live webcam frame analysis using Newton's vision model
65
+ - `@skills/newton-direct-query` - simple direct query to Newton model using the /query API endpoint
66
+ - `@skills/newton-machine-state-from-file` - run a Machine State Lens by streaming sensor data from a CSV file
67
+ - `@skills/newton-machine-state-from-sensor` - run a Machine State Lens by streaming real-time data from a physical sensor
68
+ - `@skills/newton-machine-state-upload` - run a Machine State Lens by uploading a CSV file for server-side processing
60
69
 
61
70
  ## Rules
62
71
 
63
72
  See `@rules/` for comprehensive guidance on design principles, components, styling, charts, and linting.
73
+
74
+ - `@rules/accessibility` — a11y guidelines and ARIA patterns
75
+ - `@rules/charts` — chart setup, layerchart conventions, data visualization
76
+ - `@rules/components` — component API patterns, props, variants, slots
77
+ - `@rules/design-principles` — visual design language, spacing, typography
78
+ - `@rules/frontend-architecture` — component decomposition, page composition, API logic extraction
79
+ - `@rules/linting` — linting and formatting rules
80
+ - `@rules/state` — state management with Svelte 5 runes
81
+ - `@rules/styling` — Tailwind v4, semantic tokens, theming
@@ -205,10 +205,59 @@ For custom interactive elements, ensure:
205
205
  >
206
206
  ```
207
207
 
208
+ ## Page Structure
209
+
210
+ ### Skip Link
211
+
212
+ Every page should have a skip link as the first focusable element:
213
+
214
+ ```svelte
215
+ <a
216
+ href="#main-content"
217
+ class="sr-only focus:not-sr-only focus:fixed focus:top-4 focus:left-4 focus:z-50 focus:rounded-md focus:bg-background focus:px-4 focus:py-2 focus:text-foreground focus:ring-2 focus:ring-ring"
218
+ >
219
+ Skip to content
220
+ </a>
221
+
222
+ <main id="main-content">
223
+ <!-- page content -->
224
+ </main>
225
+ ```
226
+
227
+ ### Semantic Landmarks
228
+
229
+ Use semantic HTML elements instead of generic `<div>` wrappers:
230
+
231
+ ```svelte
232
+ <!-- Before -->
233
+ <div class="header">...</div>
234
+ <div class="nav">...</div>
235
+ <div class="content">...</div>
236
+
237
+ <!-- After -->
238
+ <header>...</header>
239
+ <nav>...</nav>
240
+ <main id="main-content">...</main>
241
+ ```
242
+
243
+ ### Heading Hierarchy
244
+
245
+ Every page needs an `<h1>`. If the visual design doesn't include one, add it as screen-reader-only:
246
+
247
+ ```svelte
248
+ <h1 class="sr-only">Dashboard</h1>
249
+ ```
250
+
251
+ Never skip heading levels (e.g. `<h1>` → `<h3>`). Use the correct level for the document outline.
252
+
208
253
  ## Checklist
209
254
 
210
255
  When building components, verify:
211
256
 
257
+ - [ ] Page has a skip-to-content link as the first focusable element
258
+ - [ ] Page uses semantic landmarks (`<main>`, `<header>`, `<nav>`)
259
+ - [ ] Page has an `<h1>` (visible or `sr-only`)
260
+ - [ ] Heading hierarchy doesn't skip levels
212
261
  - [ ] Icon-only buttons have `aria-label`
213
262
  - [ ] Decorative icons have `aria-hidden="true"`
214
263
  - [ ] Interactive groups have `aria-label`
@@ -0,0 +1,77 @@
1
+ ---
2
+ paths:
3
+ - '**/routes/**/*.svelte'
4
+ - '**/+page.svelte'
5
+ - '**/+layout.svelte'
6
+ ---
7
+
8
+ # Frontend Architecture
9
+
10
+ When building a page that involves more than a simple static layout, decompose it into components rather than writing a monolithic `+page.svelte`.
11
+
12
+ ## When to extract a component
13
+
14
+ Extract a component when a section of UI has:
15
+
16
+ - 3+ primitives composed together (Card + Badge + Button = a status card)
17
+ - Its own reactive state (`$state`, `$derived`)
18
+ - Potential for reuse across pages or skills
19
+
20
+ Common extraction candidates: media inputs, status displays, result/summary views, streaming logs, file upload flows.
21
+
22
+ ## Gold-standard references
23
+
24
+ The project includes pattern components that demonstrate these conventions. Study them before building new ones:
25
+
26
+ - `$lib/components/ui/VideoPlayer.svelte` — media playback with controls, composes Card + AspectRatio + Button + Slider
27
+ - `$lib/components/ui/ExpandableLog.svelte` — streaming log display, composes Collapsible + Item + Badge
28
+ - `$lib/components/ui/StatusBadge.svelte` — health indicator with derived state, composes Badge + Avatar
29
+ - `$lib/components/ui/HealthscoreCard.svelte` — score card with derived state, composes Card sub-components
30
+ - `$lib/components/ui/Menubar.svelte` — branded header with snippet slots
31
+
32
+ Check if an existing pattern fits before building a new one. Use `@skills/build-pattern` to create new patterns that follow these same conventions.
33
+
34
+ ## Component conventions
35
+
36
+ Follow `@rules/components` for the full conventions. The essentials:
37
+
38
+ - `let { class: className, ...restProps } = $props();`
39
+ - `cn()` for all class merging — never raw string concatenation
40
+ - `$derived` for computed state
41
+ - Spread `...restProps` on the root element
42
+ - Compose from DS primitives (Card, Badge, Button, etc.) — not raw HTML
43
+
44
+ ## Page-level orchestration
45
+
46
+ `+page.svelte` is the orchestrator. It should:
47
+
48
+ - Own flow state (status, session IDs, error messages)
49
+ - Import and compose child components
50
+ - Pass data down via props
51
+ - Handle top-level layout (using `@skills/create-dashboard` for dashboard layouts)
52
+
53
+ Components should be presentational where possible — receive data via props, emit events up.
54
+
55
+ ## API and streaming logic extraction
56
+
57
+ SSE consumers, fetch wrappers, polling loops, and data transforms belong in a utility file, not inline in components or pages:
58
+
59
+ ```
60
+ src/lib/api/activity-monitor.js — SSE + session management
61
+ src/lib/api/machine-state.js — streaming + windowing
62
+ src/lib/api/embeddings.js — upload + embedding extraction
63
+ ```
64
+
65
+ This keeps components focused on rendering and makes API logic testable and reusable.
66
+
67
+ ## Streaming UI
68
+
69
+ For skills that stream results (SSE, polling), prefer:
70
+
71
+ - Progressive rendering — show results as they arrive, don't wait for completion
72
+ - Live counters or progress indicators
73
+ - Auto-scrolling log views (reference ExpandableLog pattern)
74
+
75
+ ## Override clause
76
+
77
+ If the user explicitly requests a single-file prototype, a minimal example, or specifies a different structure, follow their instruction. These guidelines apply to production-quality demos, not quick experiments.