@archetypeai/ds-cli 0.13.0 → 0.14.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/files/AGENTS.md CHANGED
@@ -70,6 +70,10 @@ Use semantic tokens for anything themed; standard Tailwind for layout.
70
70
  - Spacing scale: `xs sm md lg xl` work as `p-lg`, `gap-md`, `space-y-xl`, `mb-sm`
71
71
  - Chart series colors: `var(--chart-1)` … `var(--chart-5)`
72
72
  - Radius on interactive elements: `rounded-interactive`
73
+ - Scrollbars are owned by the theme (`--scrollbar`, `--scrollbar-track`,
74
+ `--scrollbar-width`). Every `overflow-*` container is already on-brand in both
75
+ themes — write no scrollbar CSS at all. `bg-scrollbar` exists for a
76
+ custom-rendered thumb
73
77
 
74
78
  Standard Tailwind is fine for spacing/sizing (`p-4`, `w-full`, `gap-2`) and
75
79
  layout (`flex`, `grid`, `absolute`). Status colors communicate state — never
@@ -169,4 +173,8 @@ Compose project-specific components from package primitives in
169
173
  `sideBarSelection`, `lensTray*`, `backToDashboard`) exist in the package
170
174
  types but are internal to the Archetype AI console product — never use them
171
175
  - Keep the `@source` directives and the CSS import order exactly as above
176
+ - Never style scrollbars in app code — no `::-webkit-scrollbar` rules, no
177
+ `scrollbar-color`/`scrollbar-width`. The theme sets both, and setting
178
+ `scrollbar-*` locally also silently disables the webkit pseudo-elements on
179
+ that element
172
180
  - `layerchart` stays pinned exactly
package/files/CLAUDE.md CHANGED
@@ -70,6 +70,10 @@ Use semantic tokens for anything themed; standard Tailwind for layout.
70
70
  - Spacing scale: `xs sm md lg xl` work as `p-lg`, `gap-md`, `space-y-xl`, `mb-sm`
71
71
  - Chart series colors: `var(--chart-1)` … `var(--chart-5)`
72
72
  - Radius on interactive elements: `rounded-interactive`
73
+ - Scrollbars are owned by the theme (`--scrollbar`, `--scrollbar-track`,
74
+ `--scrollbar-width`). Every `overflow-*` container is already on-brand in both
75
+ themes — write no scrollbar CSS at all. `bg-scrollbar` exists for a
76
+ custom-rendered thumb
73
77
 
74
78
  Standard Tailwind is fine for spacing/sizing (`p-4`, `w-full`, `gap-2`) and
75
79
  layout (`flex`, `grid`, `absolute`). Status colors communicate state — never
@@ -169,4 +173,8 @@ Compose project-specific components from package primitives in
169
173
  `sideBarSelection`, `lensTray*`, `backToDashboard`) exist in the package
170
174
  types but are internal to the Archetype AI console product — never use them
171
175
  - Keep the `@source` directives and the CSS import order exactly as above
176
+ - Never style scrollbars in app code — no `::-webkit-scrollbar` rules, no
177
+ `scrollbar-color`/`scrollbar-width`. The theme sets both, and setting
178
+ `scrollbar-*` locally also silently disables the webkit pseudo-elements on
179
+ that element
172
180
  - `layerchart` stays pinned exactly
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "archetypeai-design-system",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "components": [
5
5
  {
6
6
  "name": "alert",
@@ -38,6 +38,39 @@
38
38
  "`<AspectRatio ratio={16 / 9}>` wrapping an image, video, or bg-muted placeholder."
39
39
  ]
40
40
  },
41
+ {
42
+ "name": "avatar",
43
+ "import": "@archetypeai/ds-ui-svelte-console/primitives/avatar",
44
+ "source": "https://design-system-console.archetypeai.workers.dev/r/avatar.json",
45
+ "description": "User or entity avatar with an image and an initials fallback.",
46
+ "usage": [
47
+ "Always compose Root + Fallback: `Avatar.Root` on its own renders an empty circle. The fallback is what shows while the image loads, when there is no `src`, and when the image 404s — so initials (`{user.name.split(' ').map((p) => p[0]).join('')}`) belong there even when you expect a photo.",
48
+ "Image: `Avatar.Image src={user.avatarUrl} alt={user.name}` — it is a real `<img>`, so `alt` is yours to pass and a missing one is an accessibility violation. Use the person's name, not \"avatar\".",
49
+ "Size: `sm` (28px) for dense chrome like the side-nav profile row, `default` (36px) for lists and headers, `lg` (48px) for a profile or detail header. The size lands on `data-size` and the fallback's type scales off it through `group-data-[size=…]/avatar`, so overriding the root's `size-*` by hand desynchronises the two — add a size variant instead.",
50
+ "Shape: `circle` for people, `squircle` (12px radius at every size) for non-human entities (an org, a workspace, a model) so the two read apart at a glance. The radius is deliberately generous — at `sm` the squircle sits close to a circle, which is the intended look.",
51
+ "Skipping the loading flash: pass `loadingStatus=\"loaded\"` when the image is already cached or inlined, which shows it immediately instead of flashing the fallback. It is bindable, so `bind:loadingStatus` also reads the outcome (`loading` | `loaded` | `error`) if the caller needs to react to a broken image.",
52
+ "Stacking (“who is on this session”): a `flex -space-x-2` row plus `*:data-[slot=avatar]:ring-2 *:data-[slot=avatar]:ring-background *:data-[slot=avatar]:border-0` on the container. The ring is what cuts each avatar out of the one behind it, and it hangs off `data-slot`, so separation stays a container concern rather than a prop. Drop the border in a stack: the root's `border-border` sits just inside the ring, so leaving it on renders a grey rim against a white gap against the next rim, and the overlap reads muddy. Stack images, not initials — the overlap covers each avatar's trailing edge, which a face survives and two letters do not."
53
+ ],
54
+ "variants": {
55
+ "avatarVariants": {
56
+ "axes": {
57
+ "size": [
58
+ "sm",
59
+ "default",
60
+ "lg"
61
+ ],
62
+ "shape": [
63
+ "circle",
64
+ "squircle"
65
+ ]
66
+ },
67
+ "defaults": {
68
+ "size": "default",
69
+ "shape": "circle"
70
+ }
71
+ }
72
+ }
73
+ },
41
74
  {
42
75
  "name": "badge",
43
76
  "import": "@archetypeai/ds-ui-svelte-console/primitives/badge",
@@ -250,6 +283,19 @@
250
283
  "source": "https://design-system-console.archetypeai.workers.dev/r/console-utils.json",
251
284
  "description": "className merge helper cn() (clsx + tailwind-merge with the rounded-interactive extension). Re-exported as $lib/utils in scaffolded apps."
252
285
  },
286
+ {
287
+ "name": "copy-button",
288
+ "import": "@archetypeai/ds-ui-svelte-console/primitives/copy-button",
289
+ "source": "https://design-system-console.archetypeai.workers.dev/r/copy-button.json",
290
+ "description": "Copy-to-clipboard control that owns its own copied state.",
291
+ "usage": [
292
+ "Icon beside a value: `CopyButton value={job.id} label=\"Copy job ID\" title={job.id}` — `label` is the accessible name, so say what is being copied rather than \"Copy\", and pass the full value as `title` whenever the visible text is truncated.",
293
+ "Value inside the control: pass the value as children (`<CopyButton value={id} label=\"Copy blueprint ID\">{id}</CopyButton>`) and the whole thing becomes one copy target with one hover, instead of a 16px icon beside plain text. The hit area follows automatically — children give the `inline` size, icon-only gives the 36px `icon` size.",
294
+ "Feedback: a check mark replaces the glyph for 1500ms (`feedbackDuration`) and a toast fires on both success and failure, so a mounted `<Toaster />` is a prerequisite. Pass `toast={false}` where the inline check is feedback enough — a table of IDs, where a toast per copy is noise — and the component announces the copy to screen readers itself instead. `successMessage` / `errorMessage` override the wording; `onCopy(copied)` hooks anything else.",
295
+ "Inside a row that navigates: `stopPropagation` keeps the click off the row's own handler (and off an enclosing anchor). Reveal-on-hover is the Button axis, `visibility=\"hover\"`, which needs `group` on the row — but not when the value is inside the control, since it would fade the value too.",
296
+ "Copying without a button: `copyText(text)` is exported from the same subpath for a labelled action that happens to copy (a \"Copy CSV\" button in a dialog footer). It resolves to whether the write landed."
297
+ ]
298
+ },
253
299
  {
254
300
  "name": "counter",
255
301
  "import": "@archetypeai/ds-ui-svelte-console/primitives/counter",
@@ -258,6 +304,7 @@
258
304
  "usage": [
259
305
  "Count: `Counter value={412}` rolls only the digit places that changed; past 999 it abbreviates (`1.2K`, `123K`, `1.2M`) so it never grows a fifth column, and the exact number stays in its title + accessible label.",
260
306
  "Absent vs zero vs loading: omit the component entirely when there is no count, pass `value={0}` for an empty one, and `value={null}` while it is still loading (reserves the same width so nothing reflows when it arrives).",
307
+ "At least, for a list you cannot size: `Counter value={103} atLeast` renders `103+` when the caller has loaded 103 rows and knows only that more exist (keyset pagination, a capped query). The number is the caller's own, not a rounded threshold, and the accessible label reads \"at least 103\". Past 999 the abbreviation truncates instead of rounding, so `1250` shows `1.2K+` and never claims rows nobody loaded. `atLeast` is ignored on `value={0}`, where it would state nothing.",
261
308
  "Tone & size: `tone=\"muted\"` for a quieter pill against busy chrome; `size=\"sm\"` for dense rows (tables, list items). Inside a tab strip use `Tabs.Count`, which re-colors it for the active/inactive trigger."
262
309
  ],
263
310
  "variants": {
@@ -967,7 +1014,8 @@
967
1014
  "Icon view toggle (list/grid): `Tabs.List variant=\"toggle\"` + `Tabs.Trigger variant=\"icon\"` with an icon + title.",
968
1015
  "Segmented source switch (Library | File IDs | Upload): `variant=\"toggle\"` list + triggers `size=\"pill\" typography=\"mono\"`.",
969
1016
  "Page-section tabs (Progress | Logs | Artifacts): `Tabs.List variant=\"line\"` with plain text triggers; always `Tabs.Root bind:value`.",
970
- "Count on a trigger: `<Tabs.Trigger value=\"logs\">Logs <Tabs.Count value={logCount} /></Tabs.Trigger>` — an odometer pill that abbreviates past 999 (`1.2K`) so the strip never reflows. Pass `value={null}` while the count is still loading (it reserves the width), `value={0}` for an empty tab, and omit `Tabs.Count` entirely for a tab that has no count at all."
1017
+ "Count on a trigger: `<Tabs.Trigger value=\"logs\">Logs <Tabs.Count value={logCount} /></Tabs.Trigger>` — an odometer pill that abbreviates past 999 (`1.2K`) so the strip never reflows. Pass `value={null}` while the count is still loading (it reserves the width), `value={0}` for an empty tab, and omit `Tabs.Count` entirely for a tab that has no count at all.",
1018
+ "Count on a tab that cannot be sized: `<Tabs.Count value={loaded} atLeast />` renders `103+` for a keyset-paginated tab that knows only how many rows it has so far. Prefer it over dropping the count entirely, which reads as \"none\"."
971
1019
  ],
972
1020
  "variants": {
973
1021
  "tabsListVariants": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@archetypeai/ds-cli",
3
- "version": "0.13.0",
3
+ "version": "0.14.0",
4
4
  "description": "Archetype AI Design System CLI Tool",
5
5
  "type": "module",
6
6
  "bin": {