@archetypeai/ds-cli 0.9.1 → 0.10.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.
- package/README.md +3 -3
- package/commands/create.js +2 -2
- package/commands/init.js +2 -2
- package/files/AGENTS.md +128 -70
- package/files/CLAUDE.md +128 -70
- package/files/ds-manifest.json +998 -1024
- package/lib/add-ds-config-codeagent.js +3 -57
- package/package.json +2 -2
- package/files/LICENSE +0 -21
- package/files/rules/accessibility.md +0 -268
- package/files/rules/charts.md +0 -256
- package/files/rules/components.md +0 -251
- package/files/rules/design-principles.md +0 -71
- package/files/rules/frontend-architecture.md +0 -86
- package/files/rules/linting.md +0 -31
- package/files/rules/state.md +0 -373
- package/files/rules/styling.md +0 -142
- package/files/skills/apply-ds/SKILL.md +0 -121
- package/files/skills/apply-ds/scripts/audit.sh +0 -169
- package/files/skills/apply-ds/scripts/setup.sh +0 -153
- package/files/skills/build-component/SKILL.md +0 -153
- package/files/skills/create-dashboard/SKILL.md +0 -220
- package/files/skills/deploy-worker/SKILL.md +0 -231
- package/files/skills/deploy-worker/references/wrangler-commands.md +0 -327
- package/files/skills/fix-accessibility/SKILL.md +0 -232
- package/files/skills/fix-metadata/SKILL.md +0 -118
- package/files/skills/fix-metadata/assets/favicon.ico +0 -0
- package/files/skills/setup-chart/SKILL.md +0 -223
- package/files/skills/setup-chart/data/embedding.csv +0 -42
- package/files/skills/setup-chart/data/timeseries.csv +0 -173
- package/files/skills/setup-chart/references/scatter-chart.md +0 -229
- package/files/skills/setup-chart/references/sensor-chart.md +0 -156
package/files/rules/state.md
DELETED
|
@@ -1,373 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- '**/*.svelte'
|
|
4
|
-
- '**/*.svelte.js'
|
|
5
|
-
- '**/*.svelte.ts'
|
|
6
|
-
---
|
|
7
|
-
|
|
8
|
-
# Svelte 5 State Management
|
|
9
|
-
|
|
10
|
-
Svelte 5 uses runes - special `$` prefixed primitives that control reactivity.
|
|
11
|
-
|
|
12
|
-
## $state - Reactive State
|
|
13
|
-
|
|
14
|
-
Declare reactive state that triggers UI updates when changed:
|
|
15
|
-
|
|
16
|
-
```svelte
|
|
17
|
-
<script>
|
|
18
|
-
let count = $state(0);
|
|
19
|
-
let user = $state({ name: 'Alice', age: 30 });
|
|
20
|
-
</script>
|
|
21
|
-
|
|
22
|
-
<button onclick={() => count++}>
|
|
23
|
-
Clicked {count} times
|
|
24
|
-
</button>
|
|
25
|
-
```
|
|
26
|
-
|
|
27
|
-
### Deep Reactivity
|
|
28
|
-
|
|
29
|
-
Objects and arrays become deeply reactive proxies:
|
|
30
|
-
|
|
31
|
-
```svelte
|
|
32
|
-
<script>
|
|
33
|
-
let todos = $state([{ done: false, text: 'Learn Svelte 5' }]);
|
|
34
|
-
|
|
35
|
-
// This triggers updates - the array is a proxy
|
|
36
|
-
todos.push({ done: false, text: 'Build app' });
|
|
37
|
-
|
|
38
|
-
// This also triggers updates
|
|
39
|
-
todos[0].done = true;
|
|
40
|
-
</script>
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
### $state.raw - Non-Proxied State
|
|
44
|
-
|
|
45
|
-
For large objects you don't plan to mutate, use `$state.raw` for better performance:
|
|
46
|
-
|
|
47
|
-
```svelte
|
|
48
|
-
<script>
|
|
49
|
-
// Must reassign entirely, can't mutate
|
|
50
|
-
let data = $state.raw({ items: largeArray });
|
|
51
|
-
|
|
52
|
-
// This won't trigger updates
|
|
53
|
-
data.items.push(newItem);
|
|
54
|
-
|
|
55
|
-
// This will - full reassignment
|
|
56
|
-
data = { items: [...data.items, newItem] };
|
|
57
|
-
</script>
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### $state.snapshot - Get Plain Object
|
|
61
|
-
|
|
62
|
-
Get a non-reactive copy of a state proxy (useful for APIs that don't expect proxies):
|
|
63
|
-
|
|
64
|
-
```svelte
|
|
65
|
-
<script>
|
|
66
|
-
let state = $state({ count: 0 });
|
|
67
|
-
|
|
68
|
-
function save() {
|
|
69
|
-
// Pass plain object to external API
|
|
70
|
-
const snapshot = $state.snapshot(state);
|
|
71
|
-
localStorage.setItem('state', JSON.stringify(snapshot));
|
|
72
|
-
}
|
|
73
|
-
</script>
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
### Class Fields
|
|
77
|
-
|
|
78
|
-
Use $state in class fields:
|
|
79
|
-
|
|
80
|
-
```svelte
|
|
81
|
-
<script>
|
|
82
|
-
class Counter {
|
|
83
|
-
count = $state(0);
|
|
84
|
-
|
|
85
|
-
increment() {
|
|
86
|
-
this.count++;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
let counter = new Counter();
|
|
91
|
-
</script>
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## $derived - Computed Values
|
|
95
|
-
|
|
96
|
-
Declare values that automatically update when dependencies change:
|
|
97
|
-
|
|
98
|
-
```svelte
|
|
99
|
-
<script>
|
|
100
|
-
let count = $state(0);
|
|
101
|
-
let doubled = $derived(count * 2);
|
|
102
|
-
let quadrupled = $derived(doubled * 2);
|
|
103
|
-
</script>
|
|
104
|
-
|
|
105
|
-
<p>{count} × 2 = {doubled}</p><p>{count} × 4 = {quadrupled}</p>
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
### $derived.by - Complex Derivations
|
|
109
|
-
|
|
110
|
-
For multi-line logic, use `$derived.by`:
|
|
111
|
-
|
|
112
|
-
```svelte
|
|
113
|
-
<script>
|
|
114
|
-
let items = $state([1, 2, 3, 4, 5]);
|
|
115
|
-
|
|
116
|
-
let stats = $derived.by(() => {
|
|
117
|
-
const sum = items.reduce((a, b) => a + b, 0);
|
|
118
|
-
const avg = sum / items.length;
|
|
119
|
-
const max = Math.max(...items);
|
|
120
|
-
return { sum, avg, max };
|
|
121
|
-
});
|
|
122
|
-
</script>
|
|
123
|
-
|
|
124
|
-
<p>Sum: {stats.sum}, Avg: {stats.avg}, Max: {stats.max}</p>
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
### Overriding Derived Values (Optimistic UI)
|
|
128
|
-
|
|
129
|
-
Derived values can be temporarily overridden:
|
|
130
|
-
|
|
131
|
-
```svelte
|
|
132
|
-
<script>
|
|
133
|
-
let { post } = $props();
|
|
134
|
-
let likes = $derived(post.likes);
|
|
135
|
-
|
|
136
|
-
async function like() {
|
|
137
|
-
likes++; // Optimistic update
|
|
138
|
-
try {
|
|
139
|
-
await api.likePost(post.id);
|
|
140
|
-
} catch {
|
|
141
|
-
likes--; // Rollback on failure
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
</script>
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## $effect - Side Effects
|
|
148
|
-
|
|
149
|
-
Run code when reactive dependencies change:
|
|
150
|
-
|
|
151
|
-
```svelte
|
|
152
|
-
<script>
|
|
153
|
-
let count = $state(0);
|
|
154
|
-
|
|
155
|
-
$effect(() => {
|
|
156
|
-
console.log('Count changed to', count);
|
|
157
|
-
document.title = `Count: ${count}`;
|
|
158
|
-
});
|
|
159
|
-
</script>
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
### Teardown / Cleanup
|
|
163
|
-
|
|
164
|
-
Return a function to clean up before re-running or on destroy:
|
|
165
|
-
|
|
166
|
-
```svelte
|
|
167
|
-
<script>
|
|
168
|
-
let interval = $state(1000);
|
|
169
|
-
|
|
170
|
-
$effect(() => {
|
|
171
|
-
const id = setInterval(() => {
|
|
172
|
-
console.log('tick');
|
|
173
|
-
}, interval);
|
|
174
|
-
|
|
175
|
-
// Cleanup: runs before re-run and on component destroy
|
|
176
|
-
return () => clearInterval(id);
|
|
177
|
-
});
|
|
178
|
-
</script>
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
### $effect.pre - Run Before DOM Updates
|
|
182
|
-
|
|
183
|
-
Rarely needed - runs before DOM updates:
|
|
184
|
-
|
|
185
|
-
```svelte
|
|
186
|
-
<script>
|
|
187
|
-
let messages = $state([]);
|
|
188
|
-
let container;
|
|
189
|
-
|
|
190
|
-
$effect.pre(() => {
|
|
191
|
-
// Check scroll position before DOM updates
|
|
192
|
-
messages.length; // Track this dependency
|
|
193
|
-
|
|
194
|
-
if (container && shouldAutoScroll(container)) {
|
|
195
|
-
// Will scroll after DOM updates
|
|
196
|
-
tick().then(() => container.scrollTo(0, container.scrollHeight));
|
|
197
|
-
}
|
|
198
|
-
});
|
|
199
|
-
</script>
|
|
200
|
-
```
|
|
201
|
-
|
|
202
|
-
### When NOT to Use $effect
|
|
203
|
-
|
|
204
|
-
**Don't sync state - use $derived instead:**
|
|
205
|
-
|
|
206
|
-
```svelte
|
|
207
|
-
<script>
|
|
208
|
-
let count = $state(0);
|
|
209
|
-
|
|
210
|
-
// BAD - don't do this
|
|
211
|
-
let doubled = $state(0);
|
|
212
|
-
$effect(() => {
|
|
213
|
-
doubled = count * 2;
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
// GOOD - use $derived
|
|
217
|
-
let doubled = $derived(count * 2);
|
|
218
|
-
</script>
|
|
219
|
-
```
|
|
220
|
-
|
|
221
|
-
**Don't create infinite loops:**
|
|
222
|
-
|
|
223
|
-
```svelte
|
|
224
|
-
<script>
|
|
225
|
-
let count = $state(0);
|
|
226
|
-
|
|
227
|
-
// BAD - infinite loop! reads and writes count
|
|
228
|
-
$effect(() => {
|
|
229
|
-
count = count + 1;
|
|
230
|
-
});
|
|
231
|
-
</script>
|
|
232
|
-
```
|
|
233
|
-
|
|
234
|
-
**Use callbacks for linked values instead of effects:**
|
|
235
|
-
|
|
236
|
-
```svelte
|
|
237
|
-
<script>
|
|
238
|
-
let spent = $state(0);
|
|
239
|
-
let left = $derived(100 - spent);
|
|
240
|
-
|
|
241
|
-
// Update spent via callback, not effect
|
|
242
|
-
function updateLeft(newLeft) {
|
|
243
|
-
spent = 100 - newLeft;
|
|
244
|
-
}
|
|
245
|
-
</script>
|
|
246
|
-
|
|
247
|
-
<input type="range" bind:value={spent} max={100} />
|
|
248
|
-
<input type="range" value={left} oninput={(e) => updateLeft(+e.target.value)} max={100} />
|
|
249
|
-
```
|
|
250
|
-
|
|
251
|
-
## $bindable - Two-Way Binding
|
|
252
|
-
|
|
253
|
-
Enable parent components to bind to a prop:
|
|
254
|
-
|
|
255
|
-
```svelte
|
|
256
|
-
<!-- FancyInput.svelte -->
|
|
257
|
-
<script>
|
|
258
|
-
let { value = $bindable(''), ...props } = $props();
|
|
259
|
-
</script>
|
|
260
|
-
|
|
261
|
-
<input bind:value {value} {...props} />
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
```svelte
|
|
265
|
-
<!-- Parent.svelte -->
|
|
266
|
-
<script>
|
|
267
|
-
import FancyInput from './FancyInput.svelte';
|
|
268
|
-
let name = $state('');
|
|
269
|
-
</script>
|
|
270
|
-
|
|
271
|
-
<FancyInput bind:value={name} /><p>Hello, {name}!</p>
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
See [components.md](./components.md) for more on `$props()` and `$bindable()`.
|
|
275
|
-
|
|
276
|
-
## $inspect - Debugging (Dev Only)
|
|
277
|
-
|
|
278
|
-
Log when values change (removed in production builds):
|
|
279
|
-
|
|
280
|
-
```svelte
|
|
281
|
-
<script>
|
|
282
|
-
let count = $state(0);
|
|
283
|
-
let user = $state({ name: 'Alice' });
|
|
284
|
-
|
|
285
|
-
// Logs whenever count or user changes
|
|
286
|
-
$inspect(count, user);
|
|
287
|
-
</script>
|
|
288
|
-
```
|
|
289
|
-
|
|
290
|
-
### Custom Inspection
|
|
291
|
-
|
|
292
|
-
```svelte
|
|
293
|
-
<script>
|
|
294
|
-
let count = $state(0);
|
|
295
|
-
|
|
296
|
-
$inspect(count).with((type, value) => {
|
|
297
|
-
if (type === 'update') {
|
|
298
|
-
debugger; // Break on changes
|
|
299
|
-
}
|
|
300
|
-
});
|
|
301
|
-
</script>
|
|
302
|
-
```
|
|
303
|
-
|
|
304
|
-
### Trace Effect Dependencies
|
|
305
|
-
|
|
306
|
-
```svelte
|
|
307
|
-
<script>
|
|
308
|
-
$effect(() => {
|
|
309
|
-
$inspect.trace(); // Must be first statement
|
|
310
|
-
doSomethingComplex();
|
|
311
|
-
});
|
|
312
|
-
</script>
|
|
313
|
-
```
|
|
314
|
-
|
|
315
|
-
## Common Gotchas
|
|
316
|
-
|
|
317
|
-
### Destructuring Breaks Reactivity
|
|
318
|
-
|
|
319
|
-
```svelte
|
|
320
|
-
<script>
|
|
321
|
-
let user = $state({ name: 'Alice', age: 30 });
|
|
322
|
-
|
|
323
|
-
// BAD - name and age are not reactive
|
|
324
|
-
let { name, age } = user;
|
|
325
|
-
|
|
326
|
-
// GOOD - access via object
|
|
327
|
-
// In template: {user.name}, {user.age}
|
|
328
|
-
</script>
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
### Async Code Doesn't Track Dependencies
|
|
332
|
-
|
|
333
|
-
Only synchronously-read state inside `$effect` is tracked. State read inside `setTimeout`, `await`, or callbacks is not tracked.
|
|
334
|
-
|
|
335
|
-
### Exporting Reassigned State
|
|
336
|
-
|
|
337
|
-
Can't directly export state that gets reassigned. Wrap in an object instead:
|
|
338
|
-
|
|
339
|
-
```javascript
|
|
340
|
-
// state.svelte.js
|
|
341
|
-
export const counter = $state({ count: 0 });
|
|
342
|
-
export function increment() {
|
|
343
|
-
counter.count++;
|
|
344
|
-
}
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
### Effects Only Run in Browser
|
|
348
|
-
|
|
349
|
-
`$effect` doesn't run during SSR:
|
|
350
|
-
|
|
351
|
-
```svelte
|
|
352
|
-
<script>
|
|
353
|
-
$effect(() => {
|
|
354
|
-
// Safe to use browser APIs here
|
|
355
|
-
window.addEventListener('resize', handleResize);
|
|
356
|
-
return () => window.removeEventListener('resize', handleResize);
|
|
357
|
-
});
|
|
358
|
-
</script>
|
|
359
|
-
```
|
|
360
|
-
|
|
361
|
-
## Quick Reference
|
|
362
|
-
|
|
363
|
-
| Rune | Purpose | Example |
|
|
364
|
-
| ------------------- | ----------------- | ---------------------------------------- |
|
|
365
|
-
| `$state(value)` | Reactive state | `let count = $state(0)` |
|
|
366
|
-
| `$state.raw(value)` | Non-proxied state | `let data = $state.raw(bigObject)` |
|
|
367
|
-
| `$derived(expr)` | Computed value | `let doubled = $derived(count * 2)` |
|
|
368
|
-
| `$derived.by(fn)` | Complex computed | `$derived.by(() => { ... })` |
|
|
369
|
-
| `$effect(fn)` | Side effect | `$effect(() => { ... })` |
|
|
370
|
-
| `$effect.pre(fn)` | Pre-DOM effect | `$effect.pre(() => { ... })` |
|
|
371
|
-
| `$props()` | Component props | `let { foo } = $props()` |
|
|
372
|
-
| `$bindable()` | Two-way prop | `let { value = $bindable() } = $props()` |
|
|
373
|
-
| `$inspect(...)` | Debug logging | `$inspect(count)` |
|
package/files/rules/styling.md
DELETED
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
paths:
|
|
3
|
-
- '**/*.css'
|
|
4
|
-
- '**/*.svelte'
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Styling Rules
|
|
8
|
-
|
|
9
|
-
## Semantic Tokens
|
|
10
|
-
|
|
11
|
-
For the complete token reference including dark mode overrides, type scale (h1–h6, p, small), and spacing definitions, read `node_modules/@archetypeai/ds-lib-tokens/theme.css`.
|
|
12
|
-
|
|
13
|
-
Token naming pattern: `bg-{token}`, `text-{token}-foreground`, `border-{token}`.
|
|
14
|
-
|
|
15
|
-
Core tokens: `background`, `foreground`, `primary`, `secondary`, `muted`, `card`, `accent`, `destructive`, `border`, `input`, `ring`.
|
|
16
|
-
|
|
17
|
-
ATAI brand tokens: `atai-neutral`, `atai-good`, `atai-warning`, `atai-critical`.
|
|
18
|
-
|
|
19
|
-
Chart series: `--chart-1` through `--chart-5` (see `@rules/charts`).
|
|
20
|
-
|
|
21
|
-
## When to Use Semantic vs Standard Tailwind
|
|
22
|
-
|
|
23
|
-
### Use Semantic Tokens For:
|
|
24
|
-
|
|
25
|
-
```svelte
|
|
26
|
-
<!-- Themed colors that should change with light/dark mode -->
|
|
27
|
-
<div class="bg-background text-foreground">
|
|
28
|
-
<div class="bg-card border-border">
|
|
29
|
-
<button class="bg-primary text-primary-foreground">
|
|
30
|
-
<span class="text-muted-foreground">
|
|
31
|
-
```
|
|
32
|
-
|
|
33
|
-
### Use Standard Tailwind For:
|
|
34
|
-
|
|
35
|
-
```svelte
|
|
36
|
-
<!-- Spacing and sizing -->
|
|
37
|
-
<div class="p-4 gap-2 w-full h-screen">
|
|
38
|
-
|
|
39
|
-
<!-- Layout utilities -->
|
|
40
|
-
<div class="flex items-center justify-between">
|
|
41
|
-
<div class="grid grid-cols-2 gap-4">
|
|
42
|
-
<div class="absolute top-0 left-0">
|
|
43
|
-
|
|
44
|
-
<!-- One-off custom colors -->
|
|
45
|
-
<div class="bg-linear-to-r from-purple-500 to-pink-500">
|
|
46
|
-
<div class="text-amber-500"> <!-- specific non-themed color -->
|
|
47
|
-
|
|
48
|
-
<!-- Responsive breakpoints -->
|
|
49
|
-
<div class="sm:flex md:grid lg:hidden">
|
|
50
|
-
|
|
51
|
-
<!-- Animations and transitions -->
|
|
52
|
-
<div class="transition-all duration-200 ease-in-out">
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
## Dark Mode
|
|
56
|
-
|
|
57
|
-
Dark mode activates via `.dark` class on the root element:
|
|
58
|
-
|
|
59
|
-
```html
|
|
60
|
-
<html class="dark">
|
|
61
|
-
...
|
|
62
|
-
</html>
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Semantic tokens automatically switch values in dark mode. No manual dark: prefixes needed for themed colors:
|
|
66
|
-
|
|
67
|
-
```svelte
|
|
68
|
-
<!-- This works in both light and dark mode automatically -->
|
|
69
|
-
<div class="bg-background text-foreground border-border">
|
|
70
|
-
```
|
|
71
|
-
|
|
72
|
-
For custom dark mode overrides, use the `dark:` prefix:
|
|
73
|
-
|
|
74
|
-
```svelte
|
|
75
|
-
<div class="bg-white dark:bg-slate-900"> <!-- custom dark override -->
|
|
76
|
-
```
|
|
77
|
-
|
|
78
|
-
For class merging with `cn()`, see `@rules/components`.
|
|
79
|
-
|
|
80
|
-
## CSS Import Order
|
|
81
|
-
|
|
82
|
-
In your global CSS file:
|
|
83
|
-
|
|
84
|
-
```css
|
|
85
|
-
@import 'tailwindcss';
|
|
86
|
-
@import 'tw-animate-css';
|
|
87
|
-
@import '@archetypeai/ds-lib-tokens/fonts.css';
|
|
88
|
-
@import '@archetypeai/ds-lib-tokens/theme.css';
|
|
89
|
-
@source '../../node_modules/@archetypeai/ds-ui-svelte-console/dist';
|
|
90
|
-
@source '../../node_modules/@archetypeai/ds-ui-svelte-labs/dist';
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Order matters — `tailwindcss` first, then the tokens theme, then the package `@source` directives (they make Tailwind emit classes used inside the package dists).
|
|
94
|
-
|
|
95
|
-
## Tailwind v4 Specifics
|
|
96
|
-
|
|
97
|
-
### @theme Directive
|
|
98
|
-
|
|
99
|
-
Custom theme values are defined with `@theme`:
|
|
100
|
-
|
|
101
|
-
```css
|
|
102
|
-
@theme {
|
|
103
|
-
--font-sans: 'PP Neue Montreal', system-ui, sans-serif;
|
|
104
|
-
--radius-md: var(--radius);
|
|
105
|
-
--spacing-md: 0.75rem;
|
|
106
|
-
--color-primary: var(--primary);
|
|
107
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### CSS Variables in Classes
|
|
111
|
-
|
|
112
|
-
You can use CSS variables directly:
|
|
113
|
-
|
|
114
|
-
```svelte
|
|
115
|
-
<div style:--legend-color={seriesColor}>
|
|
116
|
-
<span class="bg-(--legend-color)"> </span>
|
|
117
|
-
</div>
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
### No @apply in Components
|
|
121
|
-
|
|
122
|
-
Prefer Tailwind classes directly in markup. Use @apply only in base layer CSS:
|
|
123
|
-
|
|
124
|
-
```css
|
|
125
|
-
/* In theme.css - OK */
|
|
126
|
-
@layer base {
|
|
127
|
-
body {
|
|
128
|
-
@apply bg-background text-foreground;
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
```svelte
|
|
134
|
-
<!-- In components - use classes directly -->
|
|
135
|
-
<div class="bg-background text-foreground">
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
## Common Patterns
|
|
139
|
-
|
|
140
|
-
For focus ring, disabled state, and data-state animation CSS patterns, see `@rules/accessibility`.
|
|
141
|
-
|
|
142
|
-
For icon sizing conventions, see `@rules/components`.
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: apply-ds
|
|
3
|
-
description: Apply DS tokens and components to an existing demo initialized with ds-cli init.
|
|
4
|
-
allowed-tools: Read, Edit, Grep, Bash
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
# Applying the Design System to a Demo
|
|
8
|
-
|
|
9
|
-
This skill assumes `npx @archetypeai/ds-cli init` has already been run. The project has tokens, Tailwind v4, and both design system packages (`@archetypeai/ds-ui-svelte-console`, `@archetypeai/ds-ui-svelte-labs`) installed. The goal is to migrate the demo's existing UI to use DS components and semantic tokens. Read `ds-manifest.json` at the project root for the full component catalog.
|
|
10
|
-
|
|
11
|
-
## Steps
|
|
12
|
-
|
|
13
|
-
1. Audit for non-DS patterns
|
|
14
|
-
2. Replace raw colors with semantic tokens
|
|
15
|
-
3. Replace native elements with DS components
|
|
16
|
-
4. Apply layout patterns
|
|
17
|
-
5. Set up linting and formatting
|
|
18
|
-
6. Verify
|
|
19
|
-
|
|
20
|
-
## Step 1: Audit for Non-DS Patterns
|
|
21
|
-
|
|
22
|
-
Run the `scripts/audit.sh` script located in this skill's directory from the project root. The script scans all `.svelte` files and reports:
|
|
23
|
-
|
|
24
|
-
- **Raw Tailwind colors** — utilities like `bg-gray-100`, `text-blue-500`, `border-red-300` that should be semantic tokens
|
|
25
|
-
- **Native HTML elements** — `<button>`, `<input>`, `<table>`, `<select>`, `<textarea>`, `<dialog>`, `<hr>` that have DS component equivalents
|
|
26
|
-
- **Hardcoded colors** — inline `color:`, `background:`, `background-color:`, `border-color:` style values
|
|
27
|
-
- **Class concatenation** — string templates or `+` concatenation on class attributes instead of `cn()`
|
|
28
|
-
|
|
29
|
-
Review the output to prioritize what to migrate.
|
|
30
|
-
|
|
31
|
-
## Step 2: Replace Raw Colors with Semantic Tokens
|
|
32
|
-
|
|
33
|
-
Replace raw Tailwind color utilities with semantic equivalents throughout `.svelte` files:
|
|
34
|
-
|
|
35
|
-
| Raw Tailwind | Semantic Token |
|
|
36
|
-
| --- | --- |
|
|
37
|
-
| `bg-white` | `bg-background` |
|
|
38
|
-
| `bg-black` | `bg-foreground` |
|
|
39
|
-
| `text-black` | `text-foreground` |
|
|
40
|
-
| `text-white` | `text-background` |
|
|
41
|
-
| `bg-gray-50`, `bg-gray-100` | `bg-muted` |
|
|
42
|
-
| `text-gray-500`, `text-gray-600` | `text-muted-foreground` |
|
|
43
|
-
| `bg-gray-200`, `bg-gray-300` | `bg-accent` |
|
|
44
|
-
| `border-gray-200`, `border-gray-300` | `border-border` |
|
|
45
|
-
| `bg-slate-900`, `bg-gray-900` | `bg-primary` |
|
|
46
|
-
| `text-slate-900`, `text-gray-900` | `text-primary` |
|
|
47
|
-
| `bg-red-*` | `bg-destructive` |
|
|
48
|
-
| `text-red-*` | `text-destructive` |
|
|
49
|
-
| `bg-green-*` | `bg-atai-good` |
|
|
50
|
-
| `text-green-*` | `text-atai-good` |
|
|
51
|
-
| `bg-yellow-*` | `bg-atai-warning` |
|
|
52
|
-
| `text-yellow-*` | `text-atai-warning` |
|
|
53
|
-
| `bg-blue-*` | `bg-atai-neutral` |
|
|
54
|
-
| `text-blue-*` | `text-atai-neutral` |
|
|
55
|
-
|
|
56
|
-
Use judgement — not every raw color maps 1:1. Context matters:
|
|
57
|
-
|
|
58
|
-
- A `bg-gray-100` card background → `bg-card` or `bg-muted`
|
|
59
|
-
- A `bg-gray-100` hover state → `bg-accent`
|
|
60
|
-
- A `text-gray-400` placeholder → `text-muted-foreground`
|
|
61
|
-
- A `border-gray-200` divider → `border-border`
|
|
62
|
-
|
|
63
|
-
Leave non-color utilities (`p-4`, `flex`, `rounded-lg`, etc.) unchanged.
|
|
64
|
-
|
|
65
|
-
## Step 3: Replace Native Elements with DS Components
|
|
66
|
-
|
|
67
|
-
Swap native HTML elements for their DS component equivalents. Add imports as needed.
|
|
68
|
-
|
|
69
|
-
| Native Element | DS Component | Import From |
|
|
70
|
-
| --- | --- | --- |
|
|
71
|
-
| `<button>` | `<Button>` | `@archetypeai/ds-ui-svelte-console/primitives/button` |
|
|
72
|
-
| `<input>` | `<Input>` | `@archetypeai/ds-ui-svelte-console/primitives/input` |
|
|
73
|
-
| `<textarea>` | `<Textarea>` | `@archetypeai/ds-ui-svelte-console/primitives/textarea` |
|
|
74
|
-
| `<select>` | `<Select.Root>` + `<Select.Trigger>` + `<Select.Content>` + `<Select.Item>` | `@archetypeai/ds-ui-svelte-console/primitives/select` |
|
|
75
|
-
| `<table>` | `<Table.Root>` + `<Table.Header>` + `<Table.Row>` + `<Table.Head>` + `<Table.Body>` + `<Table.Cell>` | `@archetypeai/ds-ui-svelte-console/primitives/table` |
|
|
76
|
-
| `<dialog>` | `<Dialog.Root>` + `<Dialog.Content>` + `<Dialog.Header>` + `<Dialog.Title>` | `@archetypeai/ds-ui-svelte-console/primitives/dialog` |
|
|
77
|
-
| `<hr>` | `<Separator>` | `@archetypeai/ds-ui-svelte-console/primitives/separator` |
|
|
78
|
-
| `<label>` | `<Label>` | `@archetypeai/ds-ui-svelte-console/primitives/label` |
|
|
79
|
-
| `<a>` (styled as button) | `<Button variant="link">` or `<Button>` with `href` | `@archetypeai/ds-ui-svelte-console/primitives/button` |
|
|
80
|
-
|
|
81
|
-
For each replacement:
|
|
82
|
-
|
|
83
|
-
1. Add the import to the `<script>` block
|
|
84
|
-
2. Replace the element and map attributes (`class` → `class`, `onclick` → `onclick`, etc.)
|
|
85
|
-
3. Use `cn()` from `$lib/utils.js` for merging classes — never raw concatenation
|
|
86
|
-
4. Map native variants: e.g. a small styled button → `<Button size="sm">`, a ghost-styled button → `<Button variant="ghost">`
|
|
87
|
-
|
|
88
|
-
## Step 4: Apply Layout Patterns
|
|
89
|
-
|
|
90
|
-
Identify structural opportunities to use DS composition patterns:
|
|
91
|
-
|
|
92
|
-
- **Cards** — wrap content sections in `<Card.Root>` / `<Card.Header>` / `<Card.Content>` instead of raw `<div>` with border/shadow classes
|
|
93
|
-
- **Separators** — replace `<hr>` or border-bottom hacks with `<Separator>`
|
|
94
|
-
- **Badges** — replace styled `<span>` status indicators with `<Badge>`
|
|
95
|
-
- **Spinners** — replace loading placeholders with `<Spinner>`
|
|
96
|
-
- **Empty states** — replace ad-hoc "no data" markup with `<EmptyState>`
|
|
97
|
-
- **Tooltips** — replace `title` attributes with `<Tooltip.Root>` / `<Tooltip.Trigger>` / `<Tooltip.Content>`
|
|
98
|
-
|
|
99
|
-
Import console components from `@archetypeai/ds-ui-svelte-console/primitives/<name>` and labs components (menubar, charts, slider, switch, ...) from `@archetypeai/ds-ui-svelte-labs/primitives/<name>` — see `ds-manifest.json` for the catalog.
|
|
100
|
-
|
|
101
|
-
## Step 5: Lint and Format
|
|
102
|
-
|
|
103
|
-
Run linting and formatting to clean up the migrated code:
|
|
104
|
-
|
|
105
|
-
```bash
|
|
106
|
-
npm run lint:fix && npm run format
|
|
107
|
-
```
|
|
108
|
-
|
|
109
|
-
See `@rules/linting.md` for details.
|
|
110
|
-
|
|
111
|
-
## Step 6: Verify
|
|
112
|
-
|
|
113
|
-
Confirm the design system is properly applied:
|
|
114
|
-
|
|
115
|
-
- [ ] No raw Tailwind color utilities in `.svelte` files (re-run the audit script)
|
|
116
|
-
- [ ] Native elements replaced with DS components where appropriate
|
|
117
|
-
- [ ] Component imports resolve to the design system packages (`@archetypeai/ds-ui-svelte-console`, `@archetypeai/ds-ui-svelte-labs`) — or `$lib/components/ui/` only for deliberately modified registry source
|
|
118
|
-
- [ ] `cn()` used for class merging — no string concatenation
|
|
119
|
-
- [ ] Linting passes: `npm run lint && npm run format:check`
|
|
120
|
-
- [ ] App builds without errors: `npm run build`
|
|
121
|
-
- [ ] App runs correctly: `npm run dev`
|