@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.
- package/README.md +25 -67
- package/commands/create.js +5 -27
- package/commands/init.js +5 -27
- package/files/AGENTS.md +19 -3
- package/files/CLAUDE.md +21 -3
- package/files/rules/accessibility.md +49 -0
- package/files/rules/frontend-architecture.md +77 -0
- package/files/skills/apply-ds/SKILL.md +92 -80
- package/files/skills/apply-ds/scripts/audit.sh +169 -0
- package/files/skills/apply-ds/scripts/setup.sh +48 -166
- package/files/skills/create-dashboard/SKILL.md +12 -0
- package/files/skills/embedding-from-file/SKILL.md +415 -0
- package/files/skills/embedding-from-sensor/SKILL.md +406 -0
- package/files/skills/embedding-upload/SKILL.md +414 -0
- package/files/skills/fix-accessibility/SKILL.md +57 -9
- package/files/skills/newton-activity-monitor-lens-on-video/SKILL.md +817 -0
- package/files/skills/newton-camera-frame-analysis/SKILL.md +611 -0
- package/files/skills/newton-camera-frame-analysis/scripts/activity-monitor-frame.py +165 -0
- package/files/skills/newton-camera-frame-analysis/scripts/captures/logs/api_responses_20260206_105610.json +62 -0
- package/files/skills/newton-camera-frame-analysis/scripts/continuous_monitor.py +119 -0
- package/files/skills/newton-direct-query/SKILL.md +212 -0
- package/files/skills/newton-direct-query/scripts/direct_query.py +129 -0
- package/files/skills/newton-machine-state-from-file/SKILL.md +545 -0
- package/files/skills/newton-machine-state-from-sensor/SKILL.md +707 -0
- package/files/skills/newton-machine-state-upload/SKILL.md +986 -0
- package/lib/add-ds-ui-svelte.js +5 -2
- package/lib/scaffold-ds-svelte-project.js +25 -18
- package/package.json +13 -2
package/README.md
CHANGED
|
@@ -1,123 +1,81 @@
|
|
|
1
1
|
## @archetypeai/ds-cli
|
|
2
2
|
|
|
3
|
-
|
|
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
|
-
|
|
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
|
-
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## Commands
|
|
16
|
+
|
|
17
|
+
### `create` → Scaffold a new project
|
|
16
18
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
-
| `--
|
|
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 --
|
|
33
|
+
npx @archetypeai/ds-cli create my-app --framework svelte --pm pnpm --codeagent none
|
|
38
34
|
```
|
|
39
35
|
|
|
40
36
|
---
|
|
41
37
|
|
|
42
|
-
### `init`
|
|
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
|
|
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
|
|
66
|
-
| `--
|
|
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 --
|
|
54
|
+
npx @archetypeai/ds-cli init --pm npm --codeagent none
|
|
72
55
|
```
|
|
73
56
|
|
|
74
57
|
---
|
|
75
58
|
|
|
76
|
-
### `add`
|
|
59
|
+
### `add` → Add components or agent config
|
|
77
60
|
|
|
78
|
-
#### `add ds-ui-svelte`
|
|
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
|
|
67
|
+
Installs all components from the registry. Requires shadcn-svelte (`components.json` must exist).
|
|
85
68
|
|
|
86
|
-
#### `add ds-config-codeagent`
|
|
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` |
|
|
98
|
-
| `--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
|
-
|
|
81
|
+
Without a flag, an interactive prompt asks which IDE to configure.
|
package/commands/create.js
CHANGED
|
@@ -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` -
|
|
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/
|
|
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` -
|
|
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/
|
|
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.
|