@conscia-labs/design-system 1.0.2 → 1.1.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.
package/AGENT_GUIDE.md ADDED
@@ -0,0 +1,213 @@
1
+ # Conscia Design System: Agent Guide
2
+
3
+ This file is the compact, version-matched contract for coding agents working in
4
+ an application that has `@conscia-labs/design-system` installed. Read the
5
+ installed copy before changing application UI. The installed package version is
6
+ authoritative when this guide differs from documentation on `main`.
7
+
8
+ ## Start here
9
+
10
+ 1. Inspect the application's existing shell, global stylesheet, routing, and
11
+ nearby design-system usage before editing.
12
+ 2. Reuse a public Conscia pattern when one matches the workflow. Use primitives
13
+ when the application genuinely needs a composition the package does not own.
14
+ 3. Import only public exports. Do not reach into `dist` or package internals.
15
+ 4. Preserve the application's routing, authentication, permissions, data,
16
+ mutations, validation, and business behavior.
17
+ 5. Verify the affected UI at desktop and mobile sizes, including keyboard and
18
+ visible focus behavior for interactive changes.
19
+
20
+ Live examples and component guidance:
21
+ <https://conscia-labs.github.io/design-system/>
22
+
23
+ Machine-readable component inventory:
24
+ <https://conscia-labs.github.io/design-system/agent-manifest.json>
25
+
26
+ ## Installation contract
27
+
28
+ Tailwind CSS v4 applications import these styles once from their global CSS:
29
+
30
+ ```css
31
+ @import "tailwindcss";
32
+ @import "@conscia-labs/design-system/tailwind.css";
33
+ ```
34
+
35
+ Do not add another `@source` for the package. The published stylesheet already
36
+ contains the package-relative source declaration.
37
+
38
+ Applications that do not run Tailwind use the complete precompiled bundle:
39
+
40
+ ```css
41
+ @import "@conscia-labs/design-system/standalone.css";
42
+ ```
43
+
44
+ Never import `standalone.css` in a Tailwind application. Its preflight and
45
+ utilities would compete with the application's generated CSS.
46
+
47
+ Set shared preferences on the document root:
48
+
49
+ ```tsx
50
+ <html
51
+ lang="en"
52
+ data-appearance="system"
53
+ data-density="comfortable"
54
+ suppressHydrationWarning
55
+ >
56
+ ```
57
+
58
+ Supported appearance values are `light`, `dark`, and `system`. Supported
59
+ density values are `comfortable`, `compact`, and `operational`.
60
+
61
+ ## Non-negotiable boundaries
62
+
63
+ - Do not copy design-system components into the application.
64
+ - Do not install `@base-ui/react`, `@radix-ui/*`, or copied shadcn components
65
+ when the design system already provides the behavior.
66
+ - Do not use the removed `asChild` API. Use the documented `render` prop for
67
+ custom-host composition.
68
+ - Do not use legacy utilities such as `bg-primary`, `bg-muted`, `border-input`,
69
+ or their associated legacy variables. Use Conscia semantic roles.
70
+ - Do not reach into package implementation files or depend on Base UI details.
71
+ - Do not add application z-index workarounds for supported overlays before
72
+ checking the documented `modal` behavior.
73
+ - Do not encode status using color alone. Retain meaningful text, labels, or
74
+ icons.
75
+
76
+ ## Choose the highest useful level
77
+
78
+ ### Patterns
79
+
80
+ Prefer patterns for recurring product workflows:
81
+
82
+ - Application chrome: `AppShell`, `AppHeader`, `AppSidebar`, `MainRegion`,
83
+ `PageFrame`, and `SidebarNavigation`.
84
+ - Page composition: `PageHeader`, `PageToolbar`, `ResourceSummary`, and
85
+ `DetailSection`.
86
+ - Data-heavy collections: `DataTable`, `EntityTable`, `InventorySurface`, and
87
+ `PaginationControls`.
88
+ - Operational dashboards: `MetricCard`, `MetricBand`, `DataPanel`,
89
+ `AttentionList`, and `ActivityList`.
90
+ - States and feedback: `StateView`, `ErrorState`, `LoadingRows`,
91
+ `ConfirmationDialog`, `CommandPalette`, and `FilterBar`.
92
+ - Multi-rail workspaces: the `Workbench*` family.
93
+
94
+ ### Primitives
95
+
96
+ Use primitives for application-specific compositions: `Button`, `Card`,
97
+ `Field`, `Input`, `Select`, `SearchableSelect`, `Dialog`, `Sheet`, `Popover`,
98
+ `Tabs`, `Table`, `Badge`, `Alert`, `Toast`, and related anatomy exports.
99
+
100
+ Consult `agent-manifest.json` for the complete public runtime inventory and the
101
+ playground route for each family.
102
+
103
+ ## Frequent decisions
104
+
105
+ - Use `Table` for semantic table anatomy. Use `DataTable` for sorting,
106
+ selection, column definitions, responsive rows, or pagination.
107
+ - Use `Tabs` for layered content or mode switching. Use `NavigationTabs` for
108
+ route-backed destinations.
109
+ - Use `Select` for a short, familiar list. Use `SearchableSelect` for longer
110
+ lists that users need to filter.
111
+ - Use `LoadingButton` for asynchronous actions so layout, disabled state, and
112
+ `aria-busy` remain consistent.
113
+ - Use `ConfirmationDialog` or `AlertDialog` only for consequential decisions.
114
+ - Use `operational` density for information-heavy administration, inventory,
115
+ and workspace surfaces. Keep `comfortable` for general-purpose product UI.
116
+
117
+ ## Composition examples
118
+
119
+ Use fields as the unit of form layout and accessible help/error content:
120
+
121
+ ```tsx
122
+ import {
123
+ Button,
124
+ Field,
125
+ FieldDescription,
126
+ FieldLabel,
127
+ Input,
128
+ } from "@conscia-labs/design-system";
129
+
130
+ <form className="grid gap-5">
131
+ <Field>
132
+ <FieldLabel htmlFor="connection-name">Name</FieldLabel>
133
+ <Input id="connection-name" name="name" />
134
+ <FieldDescription>Use a name operators will recognize.</FieldDescription>
135
+ </Field>
136
+ <Button type="submit">Create connection</Button>
137
+ </form>;
138
+ ```
139
+
140
+ Keep popup controls non-modal when nested inside a modal surface:
141
+
142
+ ```tsx
143
+ <Dialog open={open} onOpenChange={setOpen}>
144
+ <DialogContent>
145
+ <DialogBody>
146
+ <FormSelect modal={false} name="vendor" options={vendorOptions} />
147
+ <SearchableSelect
148
+ modal={false}
149
+ name="model"
150
+ options={modelOptions}
151
+ onValueChange={setModel}
152
+ />
153
+ </DialogBody>
154
+ </DialogContent>
155
+ </Dialog>
156
+ ```
157
+
158
+ Prefer the integrated global header for new application shells:
159
+
160
+ ```tsx
161
+ <AppShell headerLayout="integrated">
162
+ <AppHeader>
163
+ <AppHeaderStart>
164
+ <SidebarTrigger />
165
+ {productIdentity}
166
+ </AppHeaderStart>
167
+ <AppHeaderSearch>{globalSearch}</AppHeaderSearch>
168
+ <AppHeaderActions>{accountActions}</AppHeaderActions>
169
+ </AppHeader>
170
+ <AppSidebar variant="auto">
171
+ <AppSidebarContent>{navigation}</AppSidebarContent>
172
+ </AppSidebar>
173
+ <MainRegion>{children}</MainRegion>
174
+ </AppShell>
175
+ ```
176
+
177
+ ## Styling
178
+
179
+ Use semantic tokens and utilities rather than palette colors:
180
+
181
+ - Surfaces: `canvas`, `surface`, `surface-raised`, `surface-muted`, and
182
+ `surface-floating`.
183
+ - Text: `text-primary`, `text-secondary`, `text-supporting`, and `text-muted`.
184
+ - Actions and selection: `action-*` and `selection-*`.
185
+ - Status: `information-*`, `success-*`, `warning-*`, and `danger-*`.
186
+ - Neutral structure: `border-subtle`, `control-border`, and shared radius,
187
+ spacing, type, elevation, and focus tokens.
188
+
189
+ Use `className` for layout and local composition. Override semantic variables
190
+ only when the product intentionally changes a system-level decision. Avoid
191
+ component descendant selectors.
192
+
193
+ ## Accessibility ownership
194
+
195
+ The package provides component-level keyboard behavior, focus management, and
196
+ semantic structure. The application remains responsible for:
197
+
198
+ - Meaningful labels and accessible names.
199
+ - Heading order and page landmarks.
200
+ - Form validation messages and their relationships.
201
+ - Alternative text.
202
+ - Route state such as `aria-current`.
203
+ - Complete keyboard-accessible business workflows.
204
+
205
+ ## Verification
206
+
207
+ Use the consuming application's own commands. At minimum, run its typecheck and
208
+ tests for behavior changes, then inspect the affected route in light and dark
209
+ appearance at desktop and mobile sizes. For interactive changes, exercise the
210
+ keyboard path, focus return, disabled or pending state, and any nested overlay.
211
+
212
+ For migration work, use the versioned migration guide linked from the package
213
+ README. Do not infer compatibility from old shadcn or Radix usage.
package/README.md CHANGED
@@ -6,7 +6,7 @@ The shared React component library for building clear, consistent, and accessibl
6
6
 
7
7
  > **Package:** available publicly as [`@conscia-labs/design-system`](https://www.npmjs.com/package/@conscia-labs/design-system).
8
8
  >
9
- > **v1.0.0:** this README documents the clean-break v1 contract. `1.0.0` is published as the stable v1 release.
9
+ > **Current release:** `1.1.2` is the latest stable v1 release.
10
10
  >
11
11
  > **Migration:** upgrading an application to v1? Follow the [Design System v1 Migration Guide](https://github.com/conscia-labs/design-system/blob/main/docs/design-system-v1-migration.md).
12
12
 
@@ -353,17 +353,19 @@ The shared shell owns presentation and responsive behavior. The host application
353
353
 
354
354
  ```tsx
355
355
  import {
356
+ AppHeader,
357
+ AppHeaderActions,
358
+ AppHeaderSearch,
359
+ AppHeaderStart,
356
360
  AppShell,
357
361
  AppSidebar,
358
362
  AppSidebarContent,
359
- AppSidebarHeader,
360
363
  MainRegion,
361
364
  PageContent,
362
365
  PageFrame,
363
366
  PageHeader,
364
- ProductIdentity,
367
+ SidebarNavigation,
365
368
  SidebarTrigger,
366
- TopBar,
367
369
  } from "@conscia-labs/design-system";
368
370
 
369
371
  export function ProductShell({
@@ -374,23 +376,23 @@ export function ProductShell({
374
376
  children: React.ReactNode;
375
377
  }) {
376
378
  return (
377
- <AppShell>
379
+ <AppShell headerLayout="integrated">
380
+ <AppHeader>
381
+ <AppHeaderStart>
382
+ <SidebarTrigger />
383
+ {/* Brand and product/workspace context */}
384
+ </AppHeaderStart>
385
+ <AppHeaderSearch mobileTrigger={mobileSearchTrigger}>
386
+ {globalSearch}
387
+ </AppHeaderSearch>
388
+ <AppHeaderActions>{accountActions}</AppHeaderActions>
389
+ </AppHeader>
390
+
378
391
  <AppSidebar>
379
- <AppSidebarHeader>
380
- <ProductIdentity
381
- label="Conscia"
382
- description="Administration"
383
- />
384
- </AppSidebarHeader>
385
392
  <AppSidebarContent>{navigation}</AppSidebarContent>
386
393
  </AppSidebar>
387
394
 
388
395
  <MainRegion>
389
- <TopBar>
390
- {/* Keep the toggle in the topbar; it must remain visible when the sidebar collapses. */}
391
- <SidebarTrigger />
392
- </TopBar>
393
-
394
396
  <PageFrame width="wide">
395
397
  <PageContent>
396
398
  <PageHeader
@@ -406,6 +408,66 @@ export function ProductShell({
406
408
  }
407
409
  ```
408
410
 
411
+ `AppHeader` is the preferred global chrome: it spans the viewport while the
412
+ sidebar begins below it. The historical `TopBar` plus `AppSidebarHeader`
413
+ composition remains supported through the default `headerLayout="split"` for
414
+ existing v1 consumers.
415
+
416
+ Use static groups for normal application navigation:
417
+
418
+ ```tsx
419
+ const entries = [
420
+ {
421
+ type: "group",
422
+ id: "delivery",
423
+ label: "Delivery metrics",
424
+ items: [
425
+ { id: "/dashboard", label: "Dashboard", icon: <LayoutDashboard /> },
426
+ { id: "/reporting", label: "Reporting", icon: <FileText /> },
427
+ ],
428
+ },
429
+ ] satisfies SidebarNavigationEntry[];
430
+
431
+ <SidebarNavigation entries={entries} renderLink={renderLink} />;
432
+ ```
433
+
434
+ Static labels organize the information architecture without becoming controls.
435
+ Only use `type: "submenu"` when destinations form a genuine nested hierarchy
436
+ or the section is unusually long. Untyped sections retain their historical
437
+ collapsible behavior for compatibility, but new code should always choose an
438
+ explicit type.
439
+
440
+ ## Building an operational dashboard
441
+
442
+ Use `MetricCard` for a metric with direction, sentiment, benchmark, and optional
443
+ visualization. Direction and sentiment are deliberately independent: lower
444
+ lead time is a downward but positive change.
445
+
446
+ ```tsx
447
+ <MetricCard
448
+ label="Lead time for changes"
449
+ description="First commit to production"
450
+ value="18.6"
451
+ unit="hours"
452
+ trend={
453
+ <MetricTrend
454
+ direction="down"
455
+ sentiment="positive"
456
+ value="22%"
457
+ accessibleLabel="Down 22 percent, a positive change"
458
+ />
459
+ }
460
+ visualization={<ProductChart />}
461
+ visualizationSummary="Lead time is lower at the end of the period."
462
+ />
463
+ ```
464
+
465
+ `DataPanel` provides flush panel anatomy for charts and divided rows;
466
+ `AttentionList` represents persistent operational findings without announcing
467
+ them as live alerts. `ActivityItem` accepts `leading` and `trailing` slots for
468
+ status markers and structured metadata. The package supplies chart and trend
469
+ tokens but intentionally does not bundle a charting library or dashboard grid.
470
+
409
471
  ## Building a workbench surface
410
472
 
411
473
  Workbench patterns provide a reusable composition for applications that need
@@ -543,17 +605,14 @@ accessible naming content, and use `className` to control its width.
543
605
 
544
606
  ### Sidebar variants and semantic surfaces
545
607
 
546
- `AppSidebar` keeps the historical dark treatment by default. Consumers that
547
- want the sidebar to follow the application appearance can opt into the
548
- refreshed hierarchy with `variant="auto"`; `variant="light"` is available for
549
- an explicitly light sidebar.
608
+ `AppSidebar` follows application appearance by default through `variant="auto"`.
609
+ `variant="dark"` and `variant="light"` remain available when a product needs an
610
+ explicitly fixed treatment.
550
611
 
551
612
  ```tsx
552
- <AppShell>
613
+ <AppShell headerLayout="integrated">
614
+ <AppHeader>{/* global identity, search, and actions */}</AppHeader>
553
615
  <AppSidebar variant="auto">
554
- <AppSidebarHeader>
555
- <ProductIdentity label="Conscia" description="Administration" />
556
- </AppSidebarHeader>
557
616
  <AppSidebarContent>{navigation}</AppSidebarContent>
558
617
  <AppSidebarFooter>{accountMenu}</AppSidebarFooter>
559
618
  </AppSidebar>
@@ -607,15 +666,10 @@ can still be supplied as arbitrary React nodes. Routing, conversation rows,
607
666
  row actions, account menus, permissions, and appearance controls remain
608
667
  application-owned.
609
668
 
610
- The shell uses `--ds-topbar-height` as the shared chrome-height contract. The
611
- sidebar header aliases the historical `--ds-sidebar-header-height` token to the
612
- same value, so the two rails stay aligned. `TopBar` also owns shared horizontal
613
- padding through its responsive `--ds-topbar-padding-x` tokens; applications
614
- should not add a normal-use hardcoded height or padding override. Keep leading
615
- and trailing actions inside the topbar so icons and labels share the same
616
- vertical rhythm and visible focus treatment. `SidebarTrigger` should be
617
- rendered as a child of `TopBar`, never inside `AppSidebar`; the topbar remains
618
- mounted when the sidebar enters collapsed or mobile states.
669
+ The shell uses `--ds-topbar-height` as the shared chrome-height contract.
670
+ `AppHeader` and the compatibility `TopBar` both use the responsive
671
+ `--ds-topbar-padding-x` tokens. Keep `SidebarTrigger` in either header—not
672
+ inside `AppSidebar`—so it remains available in collapsed and mobile states.
619
673
 
620
674
  Sidebar section labels use the field-label size with a restrained medium weight
621
675
  and tracking. Navigation rows retain the shared comfortable/touch heights,
@@ -636,7 +690,7 @@ The ownership boundary is:
636
690
  | Shared design system | Application-owned |
637
691
  | --- | --- |
638
692
  | Sidebar variant tokens, surface hierarchy, geometry, responsive drawer, focus states, active/hover/disabled styling, tooltips, and search affordance behavior | Routes, permissions, navigation data, query/filter state, conversation or inventory data, row actions, account/profile menus, sign-out, and product-specific persistence keys |
639
- | `NavigationGroup` keyboard expansion and `SidebarNavigation` collapsed flyouts | Group labels/content, link destinations, active-route calculation, and business-specific empty states |
693
+ | Static group structure, explicit submenu expansion, collapsed flyouts, and active/hover/focus styling | Group labels/content, link destinations, active-route calculation, and business-specific empty states |
640
694
 
641
695
  ## Choosing the right component
642
696
 
@@ -694,6 +748,40 @@ Use `SearchableSelect` when users need to find an item in a longer list by label
694
748
  Both `FormSelect` and `SearchableSelect` contribute a named value to a native
695
749
  HTML form when their `name` prop is provided.
696
750
 
751
+ ### Nested overlays
752
+
753
+ Portaled controls can be used inside `Dialog` and `Sheet` without clipping
754
+ their popup. The popup Positioner is mounted in a Base UI portal and uses the
755
+ shared overlay layer hierarchy:
756
+
757
+ | Layer | Components | z-index |
758
+ | --- | --- | ---: |
759
+ | Modal | `Dialog`, `Sheet`, `AlertDialog` | 40 |
760
+ | Popup | `Select`, `Popover`, `SearchableSelect`, `DropdownMenu` | 50 |
761
+ | Transient | `Toast`, `Tooltip` | 100 |
762
+
763
+ Base UI `Select` is modal by default, so `FormSelect` preserves that default
764
+ for backwards compatibility. Set `modal={false}` when a `Select` or
765
+ `FormSelect` is nested in a modal surface so it does not add a second backdrop,
766
+ focus boundary, or inert page state. `SearchableSelect` also exposes `modal`
767
+ and preserves Combobox's current non-modal default:
768
+
769
+ ```tsx
770
+ <Dialog open={open} onOpenChange={setOpen}>
771
+ <DialogContent>
772
+ <DialogBody className="overflow-y-auto">
773
+ <FormSelect modal={false} name="vendor" options={vendorOptions} />
774
+ <SearchableSelect modal={false} name="model" options={modelOptions} onValueChange={setModel} />
775
+ </DialogBody>
776
+ </DialogContent>
777
+ </Dialog>
778
+ ```
779
+
780
+ `Select`, `Popover`, and `DropdownMenu` already forward their Base UI root
781
+ props, including `modal`. Use the same `modal={false}` setting for those
782
+ controls when they are nested. No consuming-app z-index override or portal
783
+ adapter is required.
784
+
697
785
  ## Semantic color
698
786
 
699
787
  Color communicates meaning rather than palette choice:
@@ -779,6 +867,35 @@ import { cn } from "@conscia-labs/design-system/utils";
779
867
 
780
868
  All public entry points are ESM-only.
781
869
 
870
+ ## Agent integration
871
+
872
+ The package ships a concise [`AGENT_GUIDE.md`](./AGENT_GUIDE.md) and generated
873
+ [`agent-manifest.json`](./agent-manifest.json) alongside its runtime files. The
874
+ guide records the integration contract, component-selection rules, important
875
+ boundaries, and verification expectations for the exact installed version. The
876
+ manifest maps every public component family to its exports and live playground
877
+ route.
878
+
879
+ Add or update a managed Conscia section in a consuming repository's
880
+ `AGENTS.md` after installing the package:
881
+
882
+ ```bash
883
+ pnpm exec conscia-design-system init-agents
884
+ ```
885
+
886
+ Preview the instructions without writing a file:
887
+
888
+ ```bash
889
+ pnpm exec conscia-design-system init-agents --dry-run
890
+ ```
891
+
892
+ The initializer preserves all instructions outside its marker-delimited block,
893
+ so applications can safely rerun it when upgrading. The block tells coding
894
+ agents to read the package-local guide before UI work. Agents and developers can
895
+ also use the [live playground](https://conscia-labs.github.io/design-system/),
896
+ [`llms.txt`](https://conscia-labs.github.io/design-system/llms.txt), and the
897
+ [public machine-readable inventory](https://conscia-labs.github.io/design-system/agent-manifest.json).
898
+
782
899
  ## Local development
783
900
 
784
901
  Install dependencies:
@@ -805,6 +922,7 @@ pnpm typecheck:playground
805
922
  pnpm test
806
923
  pnpm test:package
807
924
  pnpm build:playground
925
+ pnpm build:playground:static
808
926
  ```
809
927
 
810
928
  `pnpm test:package` creates the production artifacts, validates the package
@@ -815,11 +933,18 @@ Reusable foundation, primitive, and pattern code belongs in `src`. Fixtures and
815
933
 
816
934
  ## Releasing
817
935
 
818
- The `1.0.0` release is the first public v1 package. Releases are published from
819
- GitHub Actions through npm trusted publishing, with the release tag required to
820
- match the version in `package.json` exactly. npm’s trusted-publishing flow
821
- provides short-lived CI authentication and provenance for the published
822
- package.
936
+ Development is integrated through `dev`; `main` contains released source only.
937
+ Feature and fix branches target `dev`, and a release pull request is opened from
938
+ `dev` to `main`. The CI workflow rejects pull requests to `main` from any other
939
+ branch. See [CONTRIBUTING.md](./CONTRIBUTING.md) for the complete branch model
940
+ and recommended GitHub branch rules.
941
+
942
+ Merging the release pull request runs CI but does not publish. Run `pnpm release`
943
+ from the reviewed `main` commit to create and push the version tag. That single
944
+ tag workflow validates the release, deploys the playground to GitHub Pages, and
945
+ publishes the npm package. The tag must match the version in `package.json`
946
+ exactly and point to a commit on `main`. npm’s trusted-publishing flow provides
947
+ short-lived CI authentication and provenance for the published package.
823
948
 
824
949
  Before creating a release tag, complete the release checklist in the
825
950
  [migration ledger](./docs/base-ui-migration.md), finalize the
@@ -834,27 +959,39 @@ pnpm typecheck:playground
834
959
  pnpm test
835
960
  pnpm test:package
836
961
  pnpm test:consumer
837
- pnpm build:playground
962
+ pnpm build:playground:static
838
963
  pnpm test:visual
839
964
  ```
840
965
 
841
- Then prepare and tag a release. Replace `VERSION` with the package version you
842
- are releasing:
966
+ Prepare the version change on a branch from `dev`, merge it into `dev`, then
967
+ open and merge the release pull request from `dev` to `main`. Replace `VERSION`
968
+ with the package version you are releasing:
843
969
 
844
970
  ```bash
971
+ git switch dev
972
+ git pull --ff-only origin dev
973
+ git switch -c release/vVERSION
845
974
  pnpm version VERSION --no-git-tag-version
846
- git add package.json README.md docs/base-ui-migration.md docs/design-system-v1-migration.md
975
+ # Update CHANGELOG.md and any release notes for VERSION.
976
+ # Review the generated metadata, then stage the complete release change.
977
+ git add -A
847
978
  git commit -m "Release vVERSION"
848
- git tag -a vVERSION -m "Release vVERSION"
849
- git push origin main
850
- git push origin vVERSION
979
+ git push -u origin release/vVERSION
980
+ # Open release/vVERSION -> dev, then dev -> main pull requests.
981
+
982
+ git switch main
983
+ git pull --ff-only origin main
984
+ pnpm release
851
985
  ```
852
986
 
853
- Pushing the tag starts the `npm-production` release workflow. The workflow
854
- verifies that the tag matches `package.json`, runs the release validation, and
855
- publishes the package to npm without a long-lived npm token. Because this is a
856
- scoped public package, the release configuration must retain public access;
857
- see npm’s [scoped-package publishing guidance](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
987
+ The merge to `main` runs CI. `pnpm release` pushes the version tag and starts
988
+ the release workflow, which verifies the version and branch ancestry, runs the
989
+ release validation, deploys Pages, and publishes the package to npm without a
990
+ long-lived npm token. Because this is a scoped public package, the release
991
+ configuration must retain public access; see npm’s [scoped-package publishing guidance](https://docs.npmjs.com/creating-and-publishing-scoped-public-packages/).
992
+
993
+ The `pnpm version` lifecycle hook refreshes the README release marker and
994
+ generated agent metadata, including `agent-manifest.json` and `playground/public/llms.txt`.
858
995
 
859
996
  ## Design-system boundaries
860
997