@nurix/etna 0.20.0 → 0.20.2

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.
@@ -1,5 +1,5 @@
1
1
  {
2
- "fingerprint": "067206dbe15a",
2
+ "fingerprint": "0407dfb1d18a",
3
3
  "harnesses": {
4
4
  "code": {
5
5
  "plugin": "code",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "code",
3
3
  "name": "code",
4
- "version": "3.10.15",
4
+ "version": "3.11.1",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -15,5 +15,5 @@
15
15
  "docs/memory/main.md",
16
16
  ".mcp.json"
17
17
  ],
18
- "digest": "aa73ece3da8a"
18
+ "digest": "47ab9c67add4"
19
19
  }
@@ -12,7 +12,7 @@ Three tiers, all consuming the canonical `ChartSeries[]` / `ChartPoint` data con
12
12
 
13
13
  ## Spark
14
14
 
15
- Tier-0 inline mark — no axes, no chrome. Import from `@nurix/components/spark`.
15
+ Tier-0 inline mark — no axes, no chrome. Import from `@nurix/components/element/spark`.
16
16
 
17
17
  **Props:** `series` (`ChartSeries[]` or plain `number[]`), `type` [line|bar|pie], `filled`, `fillOpacity`, `strokeWidth` (line), `gap` (bar), `width`, `height`, `useTokens` (default false: self-contained oklch; true: `--chart-N` tokens)
18
18
 
@@ -47,7 +47,7 @@ Define table columns using the `defineColumn()` helper.
47
47
  - `display` - `{ width, sortable }` (width optional — columns are fluid when unset)
48
48
  - `cell` - Custom render function `(row) => ReactNode`
49
49
 
50
- For full control, pass your own `cell()` or import a renderer from `@nurix/components/table` (`StatusPill`, `SelectCell`, etc.) as an escape hatch.
50
+ For full control, pass your own `cell()` or import a renderer from `@nurix/components/block/table` (`StatusPill`, `SelectCell`, etc.) as an escape hatch.
51
51
 
52
52
  ### Metadata options by component
53
53
 
@@ -64,7 +64,7 @@ For full control, pass your own `cell()` or import a renderer from `@nurix/compo
64
64
  ### Example
65
65
 
66
66
  ```tsx
67
- import { defineColumn } from "@nurix/components/table";
67
+ import { defineColumn } from "@nurix/components/block/table";
68
68
 
69
69
  const columns = [
70
70
  defineColumn({
@@ -100,7 +100,7 @@ const columns = [
100
100
 
101
101
  ## PageHeader
102
102
 
103
- Config-driven page masthead with an optional stat ledger — router-agnostic (the consumer owns navigation). Import from `@nurix/components/page-header`.
103
+ Config-driven page masthead with an optional stat ledger — router-agnostic (the consumer owns navigation). Import from `@nurix/components/block/page-header`.
104
104
 
105
105
  **Props:** `title`, `eyebrow` (breadcrumb segments — strings or linked `Crumb`s; last is the current page), `description`, `statusSlot`, `actions`, `stats` (`Stat[]` ledger), `back` (`BackLink`), `onBack`, `onNavigate` (fired with a crumb's/stat's `href`), `statsAlign` [left|right], `tall`
106
106
 
@@ -10,49 +10,49 @@ Columns: `concept` (the composable idea) · `category` (which deep reference cov
10
10
 
11
11
  ```csv
12
12
  concept,category,nurix,shadcn,fallback
13
- button,inputs,Button (button),Button,"native <button>, variants via class, focus-visible ring"
14
- text-input,inputs,"Input (input) — onSave commit, regex validator",Input,"<input type=text>, commit on blur/Enter"
15
- number-input,inputs,"NumberInput (number-input) — min/max/step",—,"<input inputmode=numeric>, clamp on commit, Escape reverts"
16
- textarea,inputs,"Textarea (textarea) — Cmd/Ctrl+Enter commits",Textarea,"<textarea>, blur commits, Escape resets draft"
17
- checkbox,inputs,Checkbox (checkbox),Checkbox,"<input type=checkbox> + label, indeterminate via JS"
18
- switch,inputs,Switch (switch),Switch,"role=switch button, aria-checked, Space toggles"
19
- radio-group,inputs,"RadioGroup + card/segmented variants (radio-group)",RadioGroup,"fieldset of <input type=radio>, arrow-key roving focus"
20
- select,inputs,"Select — searchable, multi, async (select)","Select; Combobox (Popover + Command)","<select> or listbox popover, typeahead, option objects not raw values"
21
- native-select,inputs,"Select* Radix family (native-select)",Select,"plain <select> behind a styled trigger"
22
- date-picker,inputs,DatePicker (date-picker),Date Picker (Calendar + Popover),"<input type=date> or calendar popover, ISO value"
23
- date-range-picker,inputs,"DateRangePicker — presets sidebar (date-range-picker)",—,"two bound date inputs, partial selection reverts on close"
24
- calendar,inputs,"Calendar (calendar) — react-day-picker",Calendar,"month grid <table>, arrow-key day navigation"
25
- slider,inputs,Slider (slider),Slider,"<input type=range> with visible value readout"
26
- rating,inputs,Rating (rating),—,"radio group of icon buttons, half-step optional"
27
- toggle,inputs,"Toggle · ToggleGroup (toggle, toggle-group)","Toggle, Toggle Group","aria-pressed buttons, single or multiple selection"
28
- otp-input,inputs,InputOTP (input-otp),Input OTP,"segmented one-char inputs, paste distributes across slots"
29
- icon-picker,inputs,"IconPicker · Icon (icon-picker)",—,"searchable icon grid in a popover, categorized"
30
- file-upload,inputs,MediaFilePicker (media-file-picker),—,"<input type=file> + drop zone, previews, size and count caps"
31
- form-field,inputs,"Cell — label/content/helper/error slots (cell)",Form + FormField (react-hook-form),"label + control + helper in one block, error slot below control"
13
+ button,inputs,Button (element/button),Button,"native <button>, variants via class, focus-visible ring"
14
+ text-input,inputs,"Input (element/input) — onSave commit, regex validator",Input,"<input type=text>, commit on blur/Enter"
15
+ number-input,inputs,"NumberInput (element/number-input) — min/max/step",—,"<input inputmode=numeric>, clamp on commit, Escape reverts"
16
+ textarea,inputs,"Textarea (element/textarea) — Cmd/Ctrl+Enter commits",Textarea,"<textarea>, blur commits, Escape resets draft"
17
+ checkbox,inputs,Checkbox (element/checkbox),Checkbox,"<input type=checkbox> + label, indeterminate via JS"
18
+ switch,inputs,Switch (element/switch),Switch,"role=switch button, aria-checked, Space toggles"
19
+ radio-group,inputs,"RadioGroup + card/segmented variants (element/radio-group)",RadioGroup,"fieldset of <input type=radio>, arrow-key roving focus"
20
+ select,inputs,"Select — searchable, multi, async (element/select)","Select; Combobox (Popover + Command)","<select> or listbox popover, typeahead, option objects not raw values"
21
+ native-select,inputs,"Select* Radix family (element/native-select)",Select,"plain <select> behind a styled trigger"
22
+ date-picker,inputs,DatePicker (compound/date-picker),Date Picker (Calendar + Popover),"<input type=date> or calendar popover, ISO value"
23
+ date-range-picker,inputs,"DateRangePicker — presets sidebar (compound/date-picker)",—,"two bound date inputs, partial selection reverts on close"
24
+ calendar,inputs,"Calendar (element/calendar) — react-day-picker",Calendar,"month grid <table>, arrow-key day navigation"
25
+ slider,inputs,Slider (element/slider),Slider,"<input type=range> with visible value readout"
26
+ rating,inputs,Rating (element/rating),—,"radio group of icon buttons, half-step optional"
27
+ toggle,inputs,"Toggle · ToggleGroup (element/toggle, element/toggle-group)","Toggle, Toggle Group","aria-pressed buttons, single or multiple selection"
28
+ otp-input,inputs,InputOTP (compound/input-otp),Input OTP,"segmented one-char inputs, paste distributes across slots"
29
+ icon-picker,inputs,"IconPicker · Icon (compound/icon-picker)",—,"searchable icon grid in a popover, categorized"
30
+ file-upload,inputs,MediaFilePicker (compound/media-file-picker),—,"<input type=file> + drop zone, previews, size and count caps"
31
+ form-field,inputs,"Cell — label/content/helper/error slots (compound/cell)",Form + FormField (react-hook-form),"label + control + helper in one block, error slot below control"
32
32
  form-validation,inputs,,Form (react-hook-form),"form element with submit-time validation and inline field errors"
33
33
  rich-text-editor,inputs,,—,"@tiptap/react editor with toolbar and markdown shortcuts"
34
34
  code-editor,inputs,,—,"@monaco-editor/react, mono, optional read-only diff mode"
35
- modal-dialog,overlays,Dialog (dialog),Dialog,"<dialog> or fixed layer, focus trap, ESC closes, header→body→footer"
36
- confirm-dialog,overlays,"Dialog variant=danger — non-dismissible (dialog)",Alert Dialog,"modal with explicit confirm/cancel, no outside-click dismiss"
37
- side-panel,overlays,Sheet (sheet),Sheet,"fixed aside, focus-trapped, ESC closes, interruptible slide"
38
- bottom-drawer,overlays,Sheet side=bottom (sheet),Drawer (vaul),"fixed bottom panel spanning full width"
39
- command-palette,overlays,Command (command),Command (cmdk),"filtered list in a dialog, ⌘K opens, arrow-key + Enter"
40
- dropdown-menu,overlays,DropdownMenu (dropdown-menu),Dropdown Menu,"role=menu under a trigger, arrow-key nav, outside click closes"
41
- context-menu,overlays,ContextMenu (context-menu),Context Menu,"right-click menu at pointer position"
42
- popover,overlays,Popover (popover),Popover,"anchored floating panel, dismiss on outside/ESC"
43
- hover-card,overlays,HoverCard (hover-card),Hover Card,"preview panel on hover intent, delayed open/close"
44
- tooltip,overlays,Tooltip (tooltip),Tooltip,"short hint on hover/focus, never load-bearing content"
45
- data-table,collections,"Table + defineColumn (table)","<Table> + TanStack Table","semantic <table>, sticky header, tabular-nums, real pagination, status chips"
46
- table-primitives,collections,UiTable* family (ui-table),Table,"bare styled <table>/<thead>/<tbody> parts"
47
- list,collections,"List + ListToolbar + ListPagination (list)",—,"<ul> of rows with toolbar and pager"
48
- record-header,collections,"Header — config-driven (header)",—,"page-top block: breadcrumbs, title, status bar, actions"
49
- page-header-stats,collections,"PageHeader — Stat/Crumb/BackLink (page-header)",—,"title row + KPI strip + back link"
35
+ modal-dialog,overlays,Dialog (compound/dialog),Dialog,"<dialog> or fixed layer, focus trap, ESC closes, header→body→footer"
36
+ confirm-dialog,overlays,"Dialog variant=danger — non-dismissible (compound/dialog)",Alert Dialog,"modal with explicit confirm/cancel, no outside-click dismiss"
37
+ side-panel,overlays,Sheet (block/sheet),Sheet,"fixed aside, focus-trapped, ESC closes, interruptible slide"
38
+ bottom-drawer,overlays,Sheet side=bottom (block/sheet),Drawer (vaul),"fixed bottom panel spanning full width"
39
+ command-palette,overlays,Command (compound/command),Command (cmdk),"filtered list in a dialog, ⌘K opens, arrow-key + Enter"
40
+ dropdown-menu,overlays,DropdownMenu (compound/dropdown-menu),Dropdown Menu,"role=menu under a trigger, arrow-key nav, outside click closes"
41
+ context-menu,overlays,ContextMenu (compound/context-menu),Context Menu,"right-click menu at pointer position"
42
+ popover,overlays,Popover (element/popover),Popover,"anchored floating panel, dismiss on outside/ESC"
43
+ hover-card,overlays,HoverCard (element/popover),Hover Card,"preview panel on hover intent, delayed open/close"
44
+ tooltip,overlays,Tooltip (element/tooltip),Tooltip,"short hint on hover/focus, never load-bearing content"
45
+ data-table,collections,"Table + defineColumn (block/table)","<Table> + TanStack Table","semantic <table>, sticky header, tabular-nums, real pagination, status chips"
46
+ table-primitives,collections,UiTable* family (block/ui-table),Table,"bare styled <table>/<thead>/<tbody> parts"
47
+ list,collections,"List + ListToolbar + ListPagination (block/list)",—,"<ul> of rows with toolbar and pager"
48
+ record-header,collections,"Header — config-driven (block/app-header)",—,"page-top block: breadcrumbs, title, status bar, actions"
49
+ page-header-stats,collections,"PageHeader — Stat/Crumb/BackLink (block/page-header)",—,"title row + KPI strip + back link"
50
50
  gantt-timeline,collections,GanttChart (activity-timeline),—,"time-scaled task rows, date axis, horizontal scroll"
51
- changes-feed,collections,ChangesList (changes-list),—,"grouped change-history feed, entity + operation labels"
52
- message-thread,collections,"Message family + MessageScroller (message, message-scroller)",—,"scrolling feed pinned to bottom, jump-to-new button"
53
- chat-bubble,collections,BubbleGroup + Bubble (bubble),—,"aligned bubble rows with reactions row"
54
- attachment,collections,Attachment family (attachment),—,"file card: media, title, actions, error state, dashed idle border"
55
- thread-marker,collections,"Marker — separator/border variants (marker)",—,"inline separator row with icon and label"
51
+ changes-feed,collections,ChangesList (block/changes-list),—,"grouped change-history feed, entity + operation labels"
52
+ message-thread,collections,"Message family + MessageScroller (compound/message, block/message-scroller)",—,"scrolling feed pinned to bottom, jump-to-new button"
53
+ chat-bubble,collections,BubbleGroup + Bubble (element/bubble),—,"aligned bubble rows with reactions row"
54
+ attachment,collections,Attachment family (compound/attachment),—,"file card: media, title, actions, error state, dashed idle border"
55
+ thread-marker,collections,"Marker — separator/border variants (element/marker)",—,"inline separator row with icon and label"
56
56
  json-viewer,collections,,—,"react18-json-view collapsible tree, mono"
57
57
  virtualized-list,collections,,—,"react-window fixed-row virtualization for 1k+ rows"
58
58
  kanban-board,collections,,—,"flex columns of cards, @dnd-kit drag between columns, per-column count"
@@ -60,29 +60,29 @@ event-calendar,collections,,—,"month/week grid of events, today marker, overfl
60
60
  description-list,collections,,—,"<dl> two-column key/value grid, tabular values"
61
61
  filter-toolbar,collections,,—,"row of faceted filter chips + clear-all + result count"
62
62
  vertical-timeline,collections,,—,"ordered event list with time rail and node markers"
63
- sidebar,navigation,"Sidebar family + Brand/Switcher/ItemGroup/UserMenu/Callout (sidebar)",Sidebar,"fixed <nav>: brand + icon sections + badges + user footer, collapsible to icons"
64
- file-tree,navigation,FileTree (sidebar),—,"nested tree with disclosure carets, keyboard nav"
65
- breadcrumb,navigation,Breadcrumb (breadcrumb),Breadcrumb,"<nav aria-label=breadcrumb>, current page unlinked"
66
- tabs,navigation,Tabs (tabs),Tabs,"role=tablist, arrow-key switching, one panel per tab"
67
- pagination,navigation,Pagination (pagination),Pagination,"page buttons + prev/next, aria-current on active page"
68
- navbar,navigation,Navbar (navbar),—,"horizontal top <nav> with links and actions"
69
- navigation-menu,navigation,NavigationMenu (navigation-menu),Navigation Menu,"top-level nav with flyout panels"
70
- menubar,navigation,Menubar (menubar),Menubar,"desktop-app menu strip with full keyboard model"
71
- slide-out-menu,navigation,SlideOutMenu (slide-out-menu),—,"off-canvas nav panel for narrow viewports"
72
- icon-rail,navigation,VerticalIconBar (vertical-icon-bar),—,"narrow vertical icon strip with tooltips"
63
+ sidebar,navigation,"Sidebar family + Brand/Switcher/ItemGroup/UserMenu/Callout (block/sidebar)",Sidebar,"fixed <nav>: brand + icon sections + badges + user footer, collapsible to icons"
64
+ file-tree,navigation,FileTree (block/sidebar),—,"nested tree with disclosure carets, keyboard nav"
65
+ breadcrumb,navigation,Breadcrumb (compound/breadcrumb),Breadcrumb,"<nav aria-label=breadcrumb>, current page unlinked"
66
+ tabs,navigation,Tabs (compound/tabs),Tabs,"role=tablist, arrow-key switching, one panel per tab"
67
+ pagination,navigation,Pagination (compound/pagination),Pagination,"page buttons + prev/next, aria-current on active page"
68
+ navbar,navigation,Navbar (block/app-header),—,"horizontal top <nav> with links and actions"
69
+ navigation-menu,navigation,NavigationMenu (compound/navigation-menu),Navigation Menu,"top-level nav with flyout panels"
70
+ menubar,navigation,Menubar (compound/menubar),Menubar,"desktop-app menu strip with full keyboard model"
71
+ slide-out-menu,navigation,SlideOutMenu (block/slide-out-menu),—,"off-canvas nav panel for narrow viewports"
72
+ icon-rail,navigation,VerticalIconBar (block/vertical-icon-bar),—,"narrow vertical icon strip with tooltips"
73
73
  stepper,navigation,,—,"ordered steps with done/current/todo states, aria-current=step"
74
- alert,feedback,Alert (alert),Alert,"role=alert block, tone via border + icon"
75
- empty-state,feedback,EmptyState (empty-state),Empty,"icon + heading + motivation line + primary action"
76
- error-boundary,feedback,ErrorBoundary (error-boundary),—,"React boundary rendering a retry block"
77
- not-found,feedback,NotFound (not-found),—,"404 block with a way back"
78
- skeleton,feedback,Skeleton (skeleton),Skeleton,"pulsing placeholder matching the final layout"
79
- loader,feedback,Loader (loader),Spinner,"centered spinner with optional label"
80
- text-spinner,feedback,"Braille (braille) · spinner frames (inline-spinner)",—,"animated unicode frames inline with text"
81
- progress,feedback,Progress (progress),Progress,"role=progressbar with aria-valuenow"
82
- toast,feedback,Toaster (sonner),Sonner,"stacked corner notifications, auto-dismiss, action slot"
83
- typing-indicator,feedback,TypingIndicator (typing-indicator),—,"three-dot pulse row"
84
- sparkline,charts,"Spark — line|bar|pie (spark) · Sparkline (sparkline)",—,"inline no-axis SVG mark, token or self-contained color"
85
- inline-bar,charts,BarGraph (bar-graph),—,"compact bar SVG with skeleton, token colors"
74
+ alert,feedback,Alert (element/alert),Alert,"role=alert block, tone via border + icon"
75
+ empty-state,feedback,EmptyState (compound/empty-state),Empty,"icon + heading + motivation line + primary action"
76
+ error-boundary,feedback,ErrorBoundary (lib/error-boundary),—,"React boundary rendering a retry block"
77
+ not-found,feedback,NotFound (compound/empty-state),—,"404 block with a way back"
78
+ skeleton,feedback,Skeleton (element/skeleton),Skeleton,"pulsing placeholder matching the final layout"
79
+ loader,feedback,Loader (element/loader),Spinner,"centered spinner with optional label"
80
+ text-spinner,feedback,"Braille (braille) · spinner frames (element/loader)",—,"animated unicode frames inline with text"
81
+ progress,feedback,Progress (element/progress),Progress,"role=progressbar with aria-valuenow"
82
+ toast,feedback,Toaster (compound/sonner),Sonner,"stacked corner notifications, auto-dismiss, action slot"
83
+ typing-indicator,feedback,TypingIndicator (element/typing-indicator),—,"three-dot pulse row"
84
+ sparkline,charts,"Spark — line|bar|pie (element/spark) · Sparkline (sparkline)",—,"inline no-axis SVG mark, token or self-contained color"
85
+ inline-bar,charts,BarGraph (element/bar-graph),—,"compact bar SVG with skeleton, token colors"
86
86
  inline-line,charts,LineGraph (line-graph),—,"compact line SVG with skeleton"
87
87
  pie-donut,charts,"PieGraph — pie|half-pie|doughnut|half-doughnut (pie-graph)",—,"SVG arcs, max ~6 slices, center slot in doughnut"
88
88
  segmented-progress,charts,ProgressBar (progress-bar),—,"stacked horizontal segments with legend"
@@ -100,44 +100,44 @@ matrix-heatmap,charts,MatrixHeatmap + legend/tooltip (heatmap),—,"x-by-y cell
100
100
  radar,charts,Radar (radar),—,"spider axes with series polygons"
101
101
  ring,charts,Ring (ring),—,"segmented circular progress with center info"
102
102
  chart-chrome,charts,"ChartEmpty · ChartHoverCard · ChartLegend (chart-primitives)",—,"shared empty/tooltip/legend chrome for inline charts"
103
- card,layout,Card family (card),Card,"bordered section: header, content, footer"
103
+ card,layout,Card family (block/card),Card,"bordered section: header, content, footer"
104
104
  stat-card,layout,Statistics family (statistics),—,"number + comparison + trend + state + door, composable regions"
105
- accordion,layout,Accordion (accordion),Accordion,"stacked disclosure sections, single or multiple open"
106
- collapsible,layout,"Collapsible (collapsible) · CollapsiblePanel (collapsible-panel)",Collapsible,"button-controlled region with hidden state"
107
- split-panes,layout,ResizablePanelGroup (resizable),Resizable,"draggable divider panes, keyboard resize"
108
- scroll-area,layout,ScrollArea (scroll-area),Scroll Area,"styled overflow container, visible-on-hover scrollbar"
109
- separator,layout,"Separator (separator) · SeparatorWithText (separator-with-text)",Separator,"<hr>/role=separator, optional centered label"
110
- aspect-ratio,layout,AspectRatio (aspect-ratio),Aspect Ratio,"CSS aspect-ratio box"
111
- carousel,layout,Carousel (carousel),Carousel,"scroll-snap track with prev/next controls"
105
+ accordion,layout,Accordion (compound/accordion),Accordion,"stacked disclosure sections, single or multiple open"
106
+ collapsible,layout,"Collapsible (element/collapsible) · CollapsiblePanel (compound/accordion)",Collapsible,"button-controlled region with hidden state"
107
+ split-panes,layout,ResizablePanelGroup (block/resizable),Resizable,"draggable divider panes, keyboard resize"
108
+ scroll-area,layout,ScrollArea (element/scroll-area),Scroll Area,"styled overflow container, visible-on-hover scrollbar"
109
+ separator,layout,"Separator (element/separator) · SeparatorWithText (element/separator)",Separator,"<hr>/role=separator, optional centered label"
110
+ aspect-ratio,layout,AspectRatio (element/aspect-ratio),Aspect Ratio,"CSS aspect-ratio box"
111
+ carousel,layout,Carousel (compound/carousel),Carousel,"scroll-snap track with prev/next controls"
112
112
  bento-grid,layout,BentoGrid + BentoCard (bento-grid),—,"asymmetric feature grid with spanning cells"
113
- editable-card,layout,EditableCard (editable-card),—,"card with edit-in-place body and commit footer"
114
- drag-reorder,layout,Sortable family (sortable),—,"dnd-kit list reorder, keyboard sortable, drag overlay ghost"
115
- text,typography,Text (text),Typography,"semantic p/span with size and weight scale"
116
- badge,typography,Badge (badge),Badge,"small status pill, tokenized tone"
117
- chip,typography,"Chip (chip) · Option display (select)",—,"removable tag, optional color dot"
118
- code,typography,Code (code),—,"inline <code>, mono"
119
- kbd,typography,Kbd (kbd),Kbd,"<kbd> keycap"
120
- label,typography,Label (label),Label,"<label for> bound to a control"
121
- link,typography,Link (link),—,"<a> with underline discipline"
113
+ editable-card,layout,EditableCard (compound/editable-card),—,"card with edit-in-place body and commit footer"
114
+ drag-reorder,layout,Sortable family (compound/sortable),—,"dnd-kit list reorder, keyboard sortable, drag overlay ghost"
115
+ text,typography,Text (element/text),Typography,"semantic p/span with size and weight scale"
116
+ badge,typography,Badge (element/badge),Badge,"small status pill, tokenized tone"
117
+ chip,typography,"Chip (element/chip) · Option display (element/select)",—,"removable tag, optional color dot"
118
+ code,typography,Code (element/code),—,"inline <code>, mono"
119
+ kbd,typography,Kbd (element/kbd),Kbd,"<kbd> keycap"
120
+ label,typography,Label (element/label),Label,"<label for> bound to a control"
121
+ link,typography,Link (element/link),—,"<a> with underline discipline"
122
122
  secure-text,typography,SecureText (secure-text),—,"masked value with reveal toggle, mono"
123
- markdown,typography,Markdown (markdown),—,"react-markdown rendering with typographic defaults"
124
- avatar,media,Avatar (avatar),Avatar,"image with initials fallback, round"
125
- copy-button,media,CopyButton (copy-button),—,"clipboard write with copied-state swap"
126
- icon,media,"IconRenderer (icon-renderer) + icons-data (icons-data)",—,"lucide icon by name, consistent stroke and size grid"
127
- voice-waveform,media,"LiveWaveform (live-waveform) · MicIcon (mic-icon)",—,"animated level bars from mic input"
128
- brand-logo,media,"Logo — blue-black|white-white|lime-white|blue-white (logo)",—,"inline SVG logo sized by height"
129
- shine-border,media,ShineBorder (shine-border),—,"animated gradient border wrapper, decorative"
130
- theme-toggle,media,ThemeToggler (theme-toggler),—,"light/dark switch writing data-theme"
131
- view-switcher,media,ViewSwitcher (view-switcher),—,"segmented control switching view-type projections"
132
- animated-number,motion,"AnimatedNumber (animated-number) · SlidingNumber (motion-primitives/sliding-number)",—,"tick-up numerals, renders plain text until JS ready"
133
- stagger-entrance,motion,AnimatedGroup (motion-primitives/animated-group),—,"staggered child arrival, identity moments only, never on 100×/day actions"
134
- text-effects,motion,"TextEffect · TextMorph · TextScramble · TextShimmer (motion-primitives/*)",—,"per-character text animation, low-frequency surfaces only"
135
- morphing-overlay,motion,"MorphingDialog · MorphingPopover (motion-primitives/*)",—,"trigger morphs into overlay, interruptible"
136
- panel-transitions,motion,"TransitionPanel · Disclosure · motion Accordion (motion-primitives/*) · animated Tabs (animate-ui)",—,"crossfade/slide between sibling panels, height-animated reveal, interruptible"
137
- decorative-effects,motion,"Spotlight · GlowEffect · AnimatedBackground · InfiniteSlider · Highlight (motion-primitives/*, animate-ui/*)",—,"pointer-tracked washes and loops, decorative only, never on data"
138
- dynamic-toolbar,motion,ToolbarDynamic (motion-primitives/toolbar-dynamic),—,"toolbar expanding to contextual actions"
139
- utility-hooks,hooks,"useClickOutside · useFileUpload · useMediaQuery · useIsMobile (hooks/*)",—,"outside-click, file-upload state, matchMedia boolean, <768px boolean"
140
- class-merge,utils,cn (utils),cn,"clsx + tailwind-merge"
141
- formatting-utils,utils,"formatDate (format) · generateId (id) · getErrorMessage (handle-error)",—,"Intl date formatting, nanoid ids, error-to-message normalization"
142
- composition-utils,utils,"getStrictContext (get-strict-context) · composeRefs (compose-refs)",—,"throwing Provider/hook pair, ref composition"
123
+ markdown,typography,Markdown (element/markdown),—,"react-markdown rendering with typographic defaults"
124
+ avatar,media,Avatar (element/avatar),Avatar,"image with initials fallback, round"
125
+ copy-button,media,CopyButton (compound/copy-button),—,"clipboard write with copied-state swap"
126
+ icon,media,"IconRenderer (element/icon-renderer) + icons-data (lib/icons-data)",—,"lucide icon by name, consistent stroke and size grid"
127
+ voice-waveform,media,"LiveWaveform (element/live-waveform) · MicIcon (element/mic-icon)",—,"animated level bars from mic input"
128
+ brand-logo,media,"Logo — blue-black|white-white|lime-white|blue-white (element/logo)",—,"inline SVG logo sized by height"
129
+ shine-border,media,ShineBorder (effect/shine-border),—,"animated gradient border wrapper, decorative"
130
+ theme-toggle,media,ThemeToggler (element/theme-toggler),—,"light/dark switch writing data-theme"
131
+ view-switcher,media,ViewSwitcher (compound/tabs),—,"segmented control switching view-type projections"
132
+ animated-number,motion,"AnimatedNumber (element/animated-number) · SlidingNumber (element/animated-number)",—,"tick-up numerals, renders plain text until JS ready"
133
+ stagger-entrance,motion,AnimatedGroup (effect/animated-group),—,"staggered child arrival, identity moments only, never on 100×/day actions"
134
+ text-effects,motion,"TextEffect · TextMorph · TextScramble · TextShimmer (effect/*)",—,"per-character text animation, low-frequency surfaces only"
135
+ morphing-overlay,motion,"MorphingDialog · MorphingPopover (effect/*)",—,"trigger morphs into overlay, interruptible"
136
+ panel-transitions,motion,"TransitionPanel · Disclosure · motion Accordion (effect/*) · animated Tabs (animate-ui)",—,"crossfade/slide between sibling panels, height-animated reveal, interruptible"
137
+ decorative-effects,motion,"Spotlight · GlowEffect · AnimatedBackground · InfiniteSlider · Highlight (effect/*, effect/*)",—,"pointer-tracked washes and loops, decorative only, never on data"
138
+ dynamic-toolbar,motion,ToolbarDynamic (effect/toolbar-dynamic),—,"toolbar expanding to contextual actions"
139
+ utility-hooks,hooks,"useClickOutside · useFileUpload · useMediaQuery · useIsMobile (lib/*)",—,"outside-click, file-upload state, matchMedia boolean, <768px boolean"
140
+ class-merge,utils,cn (lib/utils),cn,"clsx + tailwind-merge"
141
+ formatting-utils,utils,"formatDate (lib/format) · generateId (lib/id) · getErrorMessage (lib/handle-error)",—,"Intl date formatting, nanoid ids, error-to-message normalization"
142
+ composition-utils,utils,"getStrictContext (lib/get-strict-context) · composeRefs (lib/compose-refs)",—,"throwing Provider/hook pair, ref composition"
143
143
  ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- Content structure and containers. Import each from its own subpath, e.g. `import { Card, CardContent } from "@nurix/components/card";`.
5
+ Content structure and containers. Import each from its own subpath, e.g. `import { Card, CardContent } from "@nurix/components/block/card";`.
6
6
 
7
7
  ## Statistics
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- Icons, avatars, and media display; import each from its kebab-case subpath, e.g. `import { Avatar } from "@nurix/components/avatar"`.
5
+ Icons, avatars, and media display; import each from its kebab-case subpath, e.g. `import { Avatar } from "@nurix/components/element/avatar"`.
6
6
 
7
7
  ## Avatar
8
8
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- Animation primitives built on the `motion` library (`motion-primitives/*`) plus a small `animate-ui/*` layer. Compose sparingly — decorative and low-frequency surfaces only; never on data or on actions users repeat dozens of times a day. Import each from its own subpath, e.g. `import { AnimatedGroup } from "@nurix/components/motion-primitives/animated-group"`.
5
+ Animation primitives built on the `motion` library (`motion-primitives/*`) plus a small `animate-ui/*` layer. Compose sparingly — decorative and low-frequency surfaces only; never on data or on actions users repeat dozens of times a day. Import each from its own subpath, e.g. `import { AnimatedGroup } from "@nurix/components/effect/animated-group"`.
6
6
 
7
7
  ## Animated numbers
8
8
 
@@ -4,11 +4,11 @@
4
4
 
5
5
  Components: Breadcrumb, Menubar, Navbar, NavigationMenu, Pagination, Sidebar, SlideOutMenu, Tabs, VerticalIconBar
6
6
 
7
- Each imports from its own subpath, with compound members alongside, e.g. `import { Tabs, TabsList, TabsTrigger, TabsContent } from "@nurix/components/tabs"`.
7
+ Each imports from its own subpath, with compound members alongside, e.g. `import { Tabs, TabsList, TabsTrigger, TabsContent } from "@nurix/components/compound/tabs"`.
8
8
 
9
9
  ## Sidebar
10
10
 
11
- App sidebar: full shadcn primitives plus an opinionated layer, all from the single `@nurix/components/sidebar` subpath.
11
+ App sidebar: full shadcn primitives plus an opinionated layer, all from the single `@nurix/components/block/sidebar` subpath.
12
12
 
13
13
  **Sub-components:** `SidebarProvider`, `Sidebar` (`side` [left|right], `variant` [sidebar|floating|inset], `collapsible` [offcanvas|icon|none]), `SidebarTrigger`, `SidebarHeader`, `SidebarContent`, `SidebarFooter`, `SidebarGroup`, `SidebarMenu`, `SidebarMenuItem`, `SidebarMenuButton`, `SidebarRail`, `SidebarInset`, `useSidebar`. **Opinionated layer:** `Brand`, `Switcher` (`render` [simple|rich], `options`, `activeId`, `onSelect`), `ItemGroup` (`render` [list|tree|rich], `collapsible`, `compact`, `collapsedLabel` [hide|divider], `items`, `onItemClick`), `UserMenu`, `Callout`, `FileTree`, `SidebarCommandTrigger`.
14
14
 
@@ -62,7 +62,7 @@ Side panel overlay with header/body/footer layout.
62
62
 
63
63
  ## Other Overlays
64
64
 
65
- Standard compound components following the Trigger/Content pattern; import each from its kebab-case subpath (e.g. `@nurix/components/popover`):
65
+ Standard compound components following the Trigger/Content pattern; import each from its kebab-case subpath (e.g. `@nurix/components/element/popover`):
66
66
 
67
67
  - `Command` (`command`)
68
68
  - `ContextMenu` (`context-menu`)
@@ -34,7 +34,7 @@ The design skill's token artifact (CSS custom properties emitted from the projec
34
34
  Use subpath imports — each published entry maps to one; never import from the root barrel in generated code:
35
35
 
36
36
  ```tsx
37
- import { Button } from "@nurix/components/button";
38
- import { Cell } from "@nurix/components/cell";
39
- import { defineColumn } from "@nurix/components/table";
37
+ import { Button } from "@nurix/components/element/button";
38
+ import { Cell } from "@nurix/components/compound/cell";
39
+ import { defineColumn } from "@nurix/components/block/table";
40
40
  ```
@@ -2,7 +2,7 @@
2
2
 
3
3
  > Generated reference (regen-owned; see [index.md](index.md)). Binds only under `primitives: nurix`.
4
4
 
5
- Import each from its kebab-case subpath, e.g. `import { Badge } from "@nurix/components/badge"`.
5
+ Import each from its kebab-case subpath, e.g. `import { Badge } from "@nurix/components/element/badge"`.
6
6
 
7
7
  ## Text
8
8
 
@@ -43,4 +43,4 @@ Masked display for sensitive values (passwords, API keys, card numbers) with an
43
43
  - `kbd` — `Kbd`: keycap; `variant` [default|outline], `size` [sm|default|lg]
44
44
  - `label` — `Label`: Radix `Label.Root`, tracks a peer/group's `disabled` state automatically
45
45
  - `link` — `Link`: `variant` [default|muted|plain|underline], `size` [sm|default|lg], `asChild`, `external` (forces `target="_blank"` + a trailing icon; also auto-detects `target="_blank"`)
46
- - `markdown` — `Markdown`: GFM `react-markdown` + `remark-gfm` render with a full element map (headings, lists, code, blockquote, tables) styled on the library's own tokens — no `@tailwindcss/typography` plugin needed; safe to re-render incrementally while streaming. **Props:** `children` (markdown string), `className`
46
+ - `markdown` — `Markdown`: GFM `react-markdown` + `remark-gfm` render with a full element map (headings, lists, element/code, blockquote, tables) styled on the library's own tokens — no `@tailwindcss/typography` plugin needed; safe to re-render incrementally while streaming. **Props:** `children` (markdown string), `className`
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "delivery",
3
3
  "name": "delivery",
4
- "version": "0.2.20",
4
+ "version": "0.2.21",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "harness": "etna",
3
3
  "name": "etna",
4
- "version": "1.5.9",
4
+ "version": "1.5.10",
5
5
  "files": [
6
6
  ".prettierignore",
7
7
  ".prettierrc.json",
@@ -0,0 +1,42 @@
1
+ // packages/cli/lib/codex/plugin-manifest.mjs
2
+ // Pure builders for the Codex plugin + marketplace manifests, emitted by the
3
+ // marketplace shipper (.github/scripts/publish.mjs) alongside the Claude ones.
4
+ // A Codex plugin reuses the same skills/ and hooks/ dirs as a Claude plugin — only
5
+ // the manifest differs (.codex-plugin/plugin.json) — plus a Codex marketplace
6
+ // catalog (.agents/plugins/marketplace.json). Codex also reads the legacy
7
+ // .claude-plugin/marketplace.json but for DISCOVERY only, so native ones are still emitted.
8
+
9
+ // The required Codex plugin.json fields + component pointers. `hasHooks` adds the
10
+ // hooks pointer (Codex auto-detects hooks/hooks.json, but naming it is explicit).
11
+ export function buildCodexPluginJson(fm, { hasHooks = false } = {}) {
12
+ const out = {
13
+ name: fm.name,
14
+ version: fm.version,
15
+ description: fm.description,
16
+ skills: './skills/',
17
+ };
18
+ if (hasHooks) out.hooks = './hooks/hooks.json';
19
+ return out;
20
+ }
21
+
22
+ // The repo marketplace catalog Codex reads at .agents/plugins/marketplace.json. Each plugin is a
23
+ // LOCAL source (source.path relative to the catalog root) carrying an explicit install policy:
24
+ // · installation AVAILABLE — offered, not force-installed (INSTALLED_BY_DEFAULT / NOT_AVAILABLE
25
+ // are the other documented tokens; these plugins are opt-in).
26
+ // · authentication NONE — they bundle only skills + hooks, no credentials or external auth.
27
+ // The first keyword (if any) seeds a category. (Enum tokens per codex-support.md → Open Questions;
28
+ // AVAILABLE/NONE are the correct pair for an opt-in, no-auth plugin.)
29
+ export function buildCodexMarketplace(plugins) {
30
+ return {
31
+ name: 'nurixlabs',
32
+ interface: { displayName: 'Nurix Labs' },
33
+ plugins: [...plugins]
34
+ .sort((a, b) => a.name.localeCompare(b.name))
35
+ .map((p) => ({
36
+ name: p.name,
37
+ source: { path: `./plugins/${p.name}` },
38
+ policy: { installation: 'AVAILABLE', authentication: 'NONE' },
39
+ ...(p.frontmatter?.keywords?.length ? { category: p.frontmatter.keywords[0] } : {}),
40
+ })),
41
+ };
42
+ }
@@ -314,6 +314,14 @@ export function materializeHarness({ bundledHarnessDir, targetDir }) {
314
314
  for (const rel of CODEX_REBUILT_DIRS)
315
315
  rmSync(join(targetDir, rel), { recursive: true, force: true });
316
316
 
317
+ // .claude/hooks/ is harness-owned wholesale — nothing else keeps files there. On a refresh it is
318
+ // reset before the write pass, so a script this bundle stopped shipping (a retired check, a
319
+ // renamed lib module) vanishes instead of surviving for ever as a stale copy no enumerated retire
320
+ // list ever names. First contact skips the reset: a colliding file there is the user's, and the
321
+ // backup path below is what stays honest about it.
322
+ if (!firstContact && existsSync(join(bundledHarnessDir, 'hooks')))
323
+ rmSync(join(targetDir, '.claude', 'hooks'), { recursive: true, force: true });
324
+
317
325
  let written = 0;
318
326
  let seeded = 0;
319
327
  const backedUp = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nurix/etna",
3
- "version": "0.20.0",
3
+ "version": "0.20.2",
4
4
  "description": "Bootstrap a project with a Nurix harness — copies the harness's CLAUDE.md, skills, agents, rules, and hooks directly into the project from a bundled payload (no marketplace fetch, no network).",
5
5
  "type": "module",
6
6
  "bin": {
@@ -42,5 +42,5 @@
42
42
  "agent",
43
43
  "plugin"
44
44
  ],
45
- "etnaFingerprint": "067206dbe15a"
45
+ "etnaFingerprint": "0407dfb1d18a"
46
46
  }