@archetypeai/ds-cli 0.3.7

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 (37) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +123 -0
  3. package/bin.js +77 -0
  4. package/commands/add.js +42 -0
  5. package/commands/create.js +238 -0
  6. package/commands/init.js +199 -0
  7. package/files/AGENTS.md +63 -0
  8. package/files/CLAUDE.md +63 -0
  9. package/files/LICENSE +21 -0
  10. package/files/rules/accessibility.md +219 -0
  11. package/files/rules/charts.md +352 -0
  12. package/files/rules/components.md +267 -0
  13. package/files/rules/design-principles.md +56 -0
  14. package/files/rules/linting.md +31 -0
  15. package/files/rules/state.md +405 -0
  16. package/files/rules/styling.md +245 -0
  17. package/files/skills/apply-ds/SKILL.md +117 -0
  18. package/files/skills/apply-ds/scripts/setup.sh +271 -0
  19. package/files/skills/build-pattern/SKILL.md +202 -0
  20. package/files/skills/create-dashboard/SKILL.md +189 -0
  21. package/files/skills/deploy-worker/SKILL.md +231 -0
  22. package/files/skills/deploy-worker/references/wrangler-commands.md +327 -0
  23. package/files/skills/fix-accessibility/SKILL.md +184 -0
  24. package/files/skills/fix-metadata/SKILL.md +118 -0
  25. package/files/skills/fix-metadata/assets/favicon.ico +0 -0
  26. package/files/skills/setup-chart/SKILL.md +225 -0
  27. package/files/skills/setup-chart/data/embedding.csv +42 -0
  28. package/files/skills/setup-chart/data/timeseries.csv +173 -0
  29. package/files/skills/setup-chart/references/scatter-chart.md +229 -0
  30. package/files/skills/setup-chart/references/sensor-chart.md +156 -0
  31. package/lib/add-ds-config-codeagent.js +154 -0
  32. package/lib/add-ds-ui-svelte.js +93 -0
  33. package/lib/scaffold-ds-svelte-project.js +272 -0
  34. package/lib/use-package-manager.js +65 -0
  35. package/lib/use-shadcn-svelte-registry.js +26 -0
  36. package/lib/validate-url.js +31 -0
  37. package/package.json +34 -0
@@ -0,0 +1,267 @@
1
+ ---
2
+ paths:
3
+ - '**/components/**/*.svelte'
4
+ - '$lib/**/*.svelte'
5
+ - '**/primitives/**/*.svelte'
6
+ - '**/patterns/**/*.svelte'
7
+ ---
8
+
9
+ # Component Authoring Rules
10
+
11
+ ## Props Pattern
12
+
13
+ Every component should destructure props using `$props()` with this standard pattern:
14
+
15
+ ```svelte
16
+ <script>
17
+ import { cn } from '$lib/utils.js';
18
+
19
+ let { ref = $bindable(null), class: className, children, ...restProps } = $props();
20
+ </script>
21
+ ```
22
+
23
+ Key points:
24
+
25
+ - `ref = $bindable(null)` - enables parent to bind to DOM element
26
+ - `class: className` - rename to avoid reserved word conflict
27
+ - `children` - snippet for slot content
28
+ - `...restProps` - capture remaining props for spreading
29
+
30
+ ## data-slot Attributes
31
+
32
+ Add `data-slot` to root elements for identification and styling hooks:
33
+
34
+ ```svelte
35
+ <div bind:this={ref} data-slot="card" class={cn('bg-card ...', className)} {...restProps}>
36
+ {@render children?.()}
37
+ </div>
38
+ ```
39
+
40
+ This enables parent styling like `*:data-[slot=card]:p-4`.
41
+
42
+ ## Class Merging with cn()
43
+
44
+ Always use `cn()` for class composition - never raw string concatenation:
45
+
46
+ ```svelte
47
+ <!-- Correct -->
48
+ <div class={cn('bg-card text-card-foreground', className)}>
49
+
50
+ <!-- Wrong -->
51
+ <div class={`bg-card text-card-foreground ${className}`}>
52
+ ```
53
+
54
+ `cn()` uses clsx + tailwind-merge to properly handle class conflicts.
55
+
56
+ ## bits-ui Wrapper Pattern
57
+
58
+ When wrapping bits-ui primitives, import the primitive and wrap it:
59
+
60
+ ```svelte
61
+ <script>
62
+ import { Select as SelectPrimitive } from 'bits-ui';
63
+ import { cn } from '$lib/utils.js';
64
+
65
+ let { ref = $bindable(null), class: className, children, ...restProps } = $props();
66
+ </script>
67
+
68
+ <SelectPrimitive.Trigger
69
+ bind:ref
70
+ data-slot="select-trigger"
71
+ class={cn('border-input bg-transparent ...', className)}
72
+ {...restProps}
73
+ >
74
+ {@render children?.()}
75
+ </SelectPrimitive.Trigger>
76
+ ```
77
+
78
+ Common bits-ui primitives:
79
+
80
+ - `Dialog` - Dialog.Root, Dialog.Portal, Dialog.Content, Dialog.Trigger, Dialog.Close
81
+ - `AlertDialog` - AlertDialog.Root, AlertDialog.Trigger, AlertDialog.Content, AlertDialog.Action, AlertDialog.Cancel
82
+ - `Select` - Select.Root, Select.Trigger, Select.Content, Select.Item
83
+ - `Popover` - Popover.Root, Popover.Portal, Popover.Content, Popover.Trigger
84
+ - `HoverCard` - HoverCard.Root, HoverCard.Trigger, HoverCard.Content
85
+ - `Tooltip` - Tooltip.Root, Tooltip.Trigger, Tooltip.Content
86
+ - `DropdownMenu` - DropdownMenu.Root, DropdownMenu.Trigger, DropdownMenu.Content, DropdownMenu.Item
87
+ - `ContextMenu` - ContextMenu.Root, ContextMenu.Trigger, ContextMenu.Content, ContextMenu.Item
88
+ - `Accordion` - Accordion.Root, Accordion.Item, Accordion.Trigger, Accordion.Content
89
+ - `Tabs` - Tabs.Root, Tabs.List, Tabs.Trigger, Tabs.Content
90
+ - `Collapsible` - Collapsible.Root, Collapsible.Trigger, Collapsible.Content
91
+ - `Command` - Command.Root, Command.Input, Command.List, Command.Item
92
+
93
+ Additional bits-ui primitives: Calendar, RangeCalendar, Checkbox, Switch, Slider, Toggle, ToggleGroup, RadioGroup, Menubar, NavigationMenu, Pagination, InputOTP, Sidebar, Progress, Label, Separator, AspectRatio, Avatar, ScrollArea, Sheet. Check the source files for their wrapper patterns.
94
+
95
+ ## tailwind-variants (tv)
96
+
97
+ Define variants in `<script module>` for reuse and export:
98
+
99
+ ```svelte
100
+ <script module>
101
+ import { cn } from '$lib/utils.js';
102
+ import { tv } from 'tailwind-variants';
103
+
104
+ export const buttonVariants = tv({
105
+ base: 'inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors',
106
+ variants: {
107
+ variant: {
108
+ default: 'bg-primary text-primary-foreground hover:bg-primary/90',
109
+ destructive: 'bg-destructive text-white hover:bg-destructive/90',
110
+ outline: 'border bg-background hover:bg-accent',
111
+ secondary: 'bg-secondary text-secondary-foreground hover:bg-secondary/80',
112
+ ghost: 'hover:bg-accent hover:text-accent-foreground',
113
+ link: 'text-primary underline-offset-4 hover:underline'
114
+ },
115
+ size: {
116
+ default: 'h-9 px-4 py-2',
117
+ sm: 'h-8 px-3 rounded-md',
118
+ lg: 'h-10 px-6 rounded-md',
119
+ icon: 'size-9'
120
+ }
121
+ },
122
+ defaultVariants: {
123
+ variant: 'default',
124
+ size: 'default'
125
+ }
126
+ });
127
+ </script>
128
+
129
+ <script>
130
+ let { variant = 'default', size = 'default', class: className, ...restProps } = $props();
131
+ </script>
132
+
133
+ <button class={cn(buttonVariants({ variant, size }), className)} {...restProps}>
134
+ {@render children?.()}
135
+ </button>
136
+ ```
137
+
138
+ ## Snippet Slots
139
+
140
+ Use `{@render}` for slot content:
141
+
142
+ ```svelte
143
+ <!-- Default slot -->
144
+ {@render children?.()}
145
+
146
+ <!-- Named snippets (passed as props) -->
147
+ {#snippet icon()}
148
+ <ChevronDown />
149
+ {/snippet}
150
+
151
+ <Button {icon}>Click me</Button>
152
+
153
+ <!-- In component, render the snippet prop -->
154
+ {@render icon?.()}
155
+ ```
156
+
157
+ ## restProps Spreading
158
+
159
+ Always spread `...restProps` on the root element to pass through attributes:
160
+
161
+ ```svelte
162
+ <button
163
+ bind:this={ref}
164
+ data-slot="button"
165
+ class={cn(buttonVariants({ variant, size }), className)}
166
+ {type}
167
+ {disabled}
168
+ {...restProps}
169
+ >
170
+ {@render children?.()}
171
+ </button>
172
+ ```
173
+
174
+ ## Conditional Rendering
175
+
176
+ Use standard Svelte `{#if}` blocks for conditional content:
177
+
178
+ ```svelte
179
+ {#if href}
180
+ <a bind:this={ref} data-slot="button" {href} {...restProps}>
181
+ {@render children?.()}
182
+ </a>
183
+ {:else}
184
+ <button bind:this={ref} data-slot="button" {...restProps}>
185
+ {@render children?.()}
186
+ </button>
187
+ {/if}
188
+ ```
189
+
190
+ ## Icon Handling
191
+
192
+ Icons from Lucide use consistent sizing classes:
193
+
194
+ ```svelte
195
+ <script>
196
+ import ChevronDownIcon from '@lucide/svelte/icons/chevron-down';
197
+ </script>
198
+
199
+ <ChevronDownIcon class="size-4 opacity-50" />
200
+ ```
201
+
202
+ Default icon sizing in buttons: `[&_svg:not([class*='size-'])]:size-4`
203
+
204
+ ## Example: Complete Card Component
205
+
206
+ ```svelte
207
+ <script>
208
+ import { cn } from '$lib/utils.js';
209
+
210
+ let { ref = $bindable(null), class: className, children, ...restProps } = $props();
211
+ </script>
212
+
213
+ <div
214
+ bind:this={ref}
215
+ data-slot="card"
216
+ class={cn(
217
+ 'bg-card text-card-foreground flex flex-col gap-6 rounded-md border py-6 shadow-sm',
218
+ className
219
+ )}
220
+ {...restProps}
221
+ >
222
+ {@render children?.()}
223
+ </div>
224
+ ```
225
+
226
+ ## Example: Dialog Content with bits-ui
227
+
228
+ ```svelte
229
+ <script>
230
+ import { Dialog as DialogPrimitive } from 'bits-ui';
231
+ import DialogPortal from './dialog-portal.svelte';
232
+ import XIcon from '@lucide/svelte/icons/x';
233
+ import * as Dialog from './index.js';
234
+ import { cn } from '$lib/utils.js';
235
+
236
+ let {
237
+ ref = $bindable(null),
238
+ class: className,
239
+ portalProps,
240
+ children,
241
+ showCloseButton = true,
242
+ ...restProps
243
+ } = $props();
244
+ </script>
245
+
246
+ <DialogPortal {...portalProps}>
247
+ <Dialog.Overlay />
248
+ <DialogPrimitive.Content
249
+ bind:ref
250
+ data-slot="dialog-content"
251
+ class={cn(
252
+ 'bg-background fixed top-[50%] left-[50%] z-50 w-full max-w-lg translate-x-[-50%] translate-y-[-50%] rounded-lg border p-6 shadow-lg',
253
+ 'data-[state=open]:animate-in data-[state=closed]:animate-out',
254
+ className
255
+ )}
256
+ {...restProps}
257
+ >
258
+ {@render children?.()}
259
+ {#if showCloseButton}
260
+ <DialogPrimitive.Close class="absolute end-4 top-4 rounded-xs opacity-70 hover:opacity-100">
261
+ <XIcon />
262
+ <span class="sr-only">Close</span>
263
+ </DialogPrimitive.Close>
264
+ {/if}
265
+ </DialogPrimitive.Content>
266
+ </DialogPortal>
267
+ ```
@@ -0,0 +1,56 @@
1
+ # Physical AI Design Principles
2
+
3
+ ## Scope
4
+
5
+ This design system targets the **Measure** and **Reason** layers of the Physical AI stack. Interfaces built with it should support **augmentation** (helping humans perceive the physical world) and **dialogue** (helping humans reason about it). Operation and cooperation — where AI takes action in the world — are out of scope currently but will become relevant in the future.
6
+
7
+ ## The Physical AI Stack
8
+
9
+ Physical AI capabilities form a dependency stack where each layer builds on the one below:
10
+
11
+ 1. **Interpret** — Make the physical world legible by surfacing signals, anomalies, and structures from sensor data
12
+ 2. **Reason** — Enable shared reasoning between humans and AI: explore hypotheses, compare alternatives, support decisions
13
+ 3. **Operate** — Delegated action: human sets intent, system executes within defined boundaries (future scope)
14
+ 4. **Co-operate** — Joint action: shared agency through mutual adjustment between humans and AI (future scope)
15
+
16
+ ## Agency
17
+
18
+ ### Human Agency Comes First
19
+
20
+ At the Measure layer, the AI augments human perception — it surfaces what would otherwise remain invisible. The human retains full responsibility to interpret and act. Interfaces should present information without prescribing conclusions.
21
+
22
+ At the Reason layer, interaction is dialogic. The AI contributes explanations and comparisons, but the human drives inquiry and judgment. Interfaces should enable exploration, not deliver verdicts.
23
+
24
+ At the Operate layer, humans shift from direct control to goal-setting and supervision. The AI executes within defined boundaries, and responsibility becomes distributed. Interfaces should make intent, constraints, and system behavior transparent.
25
+
26
+ At the Co-operate layer, humans and AI act as coordinated participants. Action is jointly negotiated, and intent, context, and responsibility are shared and continuously adjusted. Interfaces should support mutual awareness and fluid handoffs.
27
+
28
+ ### Interaction Is Situated
29
+
30
+ Interaction unfolds within a three-way relationship: **person, system, and physical world**. Meaning arises from how sensor data, context, and human intent come together in a specific place and moment. Interfaces must maintain this connection to the physical context being observed — sensor sources, locations, time ranges, environmental conditions. Do not abstract away the situational grounding.
31
+
32
+ ## Design Implications
33
+
34
+ ### Make the World Legible
35
+
36
+ - Prioritize data clarity: visualizations should reveal structure in sensor data — trends, anomalies, distributions, correlations
37
+ - Use semantic tokens (e.g. `text-atai-good`, `text-atai-warning`, `text-atai-critical`) to communicate meaningful states, not for decorative emphasis
38
+ - Design for continuous monitoring: prefer dashboards and live views over static reports
39
+
40
+ ### Support Dialogue, Not Monologue
41
+
42
+ - Provide entry points for inquiry: interfaces should invite questions, comparisons, and hypothesis exploration
43
+ - Frame AI output as contribution, not conclusion — use language and layout that position AI reasoning as input to human judgment
44
+ - Enable iterative refinement: conversational flows, follow-up exploration, adjustable parameters
45
+
46
+ ### Preserve Physical Context
47
+
48
+ - Show provenance: which sensors, what time range, what conditions produced the data being displayed
49
+ - Ground abstract representations in physical reality — link charts to sensor locations, timestamps to real events
50
+ - Consider operational environments: interfaces may be used in the field, not only at a desk
51
+
52
+ ### Respect the Stack Boundary
53
+
54
+ - Default to interfaces that support perception and reasoning rather than autonomous AI action
55
+ - Where possible, distinguish between "the system shows" (Measure) and "the system suggests" (Reason)
56
+ - Prefer framing AI output as observations or suggestions rather than commands or decisions
@@ -0,0 +1,31 @@
1
+ # Linting & Formatting
2
+
3
+ ## Commands
4
+
5
+ | Command | Description |
6
+ | ---------------------- | -------------------------------- |
7
+ | `npm run lint` | Check for linting errors |
8
+ | `npm run lint:fix` | Auto-fix linting errors |
9
+ | `npm run format` | Format all files with Prettier |
10
+ | `npm run format:check` | Check formatting without changes |
11
+
12
+ ## Stack
13
+
14
+ - **ESLint** - Flat config (v9+) with `eslint-plugin-svelte`
15
+ - **Prettier** - Code formatting
16
+ - **prettier-plugin-svelte** - Svelte file formatting
17
+ - **prettier-plugin-tailwindcss** - Auto-sorts Tailwind classes
18
+
19
+ ## Workflow
20
+
21
+ Run linting and formatting before committing:
22
+
23
+ ```bash
24
+ npm run lint:fix && npm run format
25
+ ```
26
+
27
+ Or check without auto-fixing:
28
+
29
+ ```bash
30
+ npm run lint && npm run format:check
31
+ ```