noecosystem-design 0.1.2 → 0.2.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.
Files changed (136) hide show
  1. package/README.md +73 -35
  2. package/apps/showcase/src/catalog/catalog-index.tsx +8 -8
  3. package/apps/showcase/src/catalog/catalog-shell.tsx +7 -2
  4. package/apps/storybook/stories/catalog/calendar.stories.tsx +3 -1
  5. package/apps/storybook/stories/catalog/date-picker.stories.tsx +5 -1
  6. package/apps/storybook/stories/catalog/icon-system.stories.tsx +3 -2
  7. package/docs/adr/0006-icons8-icon-policy.md +4 -4
  8. package/docs/design-system/architecture.md +1 -1
  9. package/docs/design-system/ci-cd.md +22 -7
  10. package/docs/design-system/inventory.md +0 -1
  11. package/docs/design-system/rtl.md +1 -1
  12. package/package.json +2 -2
  13. package/packages/ai-ui/src/activity-feed.tsx +1 -2
  14. package/packages/ai-ui/src/agent-composer.tsx +1 -1
  15. package/packages/ai-ui/src/agent-message.tsx +1 -1
  16. package/packages/ai-ui/src/agent-plan.tsx +1 -1
  17. package/packages/ai-ui/src/agent-workspace.tsx +1 -2
  18. package/packages/ai-ui/src/approval-request.tsx +1 -1
  19. package/packages/ai-ui/src/run-inspector.tsx +1 -1
  20. package/packages/ai-ui/src/tool-call.tsx +1 -1
  21. package/packages/data-ui/src/activity-gauge.tsx +1 -1
  22. package/packages/data-ui/src/chart-frame.tsx +1 -1
  23. package/packages/data-ui/src/chart.tsx +1 -2
  24. package/packages/data-ui/src/dashboard-shell.tsx +1 -2
  25. package/packages/data-ui/src/data-table.tsx +1 -1
  26. package/packages/data-ui/src/filter-bar.tsx +1 -2
  27. package/packages/data-ui/src/metric-card.tsx +1 -1
  28. package/packages/data-ui/src/pagination.tsx +1 -3
  29. package/packages/data-ui/src/pie-chart.tsx +1 -1
  30. package/packages/data-ui/src/radar-chart.tsx +1 -1
  31. package/packages/design-tokens/src/base.css +1 -1
  32. package/packages/design-tokens/src/palette.ts +4 -4
  33. package/packages/design-tokens/src/tokens.css +6 -12
  34. package/packages/design-tokens/src/tokens.json +4 -4
  35. package/packages/design-tokens/src/tokens.mjs +4 -4
  36. package/packages/icons/package.json +3 -0
  37. package/packages/icons/src/adapters.tsx +4 -4
  38. package/packages/icons/src/iconsax.tsx +233 -0
  39. package/packages/icons/src/index.tsx +1 -103
  40. package/packages/registry/catalog-index.json +1 -1
  41. package/packages/registry/component-audit.json +1 -1
  42. package/packages/registry/docs-index.json +135 -403
  43. package/packages/registry/manifest.json +1642 -6110
  44. package/packages/registry/r/activity-feed.json +9 -32
  45. package/packages/registry/r/agent-composer.json +9 -34
  46. package/packages/registry/r/agent-message.json +9 -32
  47. package/packages/registry/r/agent-plan.json +9 -32
  48. package/packages/registry/r/agent-workspace.json +9 -32
  49. package/packages/registry/r/alert.json +9 -33
  50. package/packages/registry/r/app-frame.json +9 -32
  51. package/packages/registry/r/approval-request.json +9 -34
  52. package/packages/registry/r/badge.json +9 -33
  53. package/packages/registry/r/bidi-text.json +7 -25
  54. package/packages/registry/r/bottom-navigation.json +9 -32
  55. package/packages/registry/r/button.json +7 -29
  56. package/packages/registry/r/calendar.json +15 -31
  57. package/packages/registry/r/card.json +9 -32
  58. package/packages/registry/r/chart-frame.json +9 -32
  59. package/packages/registry/r/chart.json +8 -30
  60. package/packages/registry/r/code-block.json +9 -32
  61. package/packages/registry/r/context-menu.json +8 -36
  62. package/packages/registry/r/dashboard-01.json +7 -23
  63. package/packages/registry/r/dashboard-02.json +6 -20
  64. package/packages/registry/r/dashboard-shell.json +9 -32
  65. package/packages/registry/r/data-list.json +9 -32
  66. package/packages/registry/r/data-table.json +9 -32
  67. package/packages/registry/r/date-picker.json +15 -31
  68. package/packages/registry/r/dialog.json +11 -45
  69. package/packages/registry/r/direction-provider.json +6 -21
  70. package/packages/registry/r/drawer.json +10 -36
  71. package/packages/registry/r/dropdown.json +9 -37
  72. package/packages/registry/r/empty-state.json +9 -32
  73. package/packages/registry/r/error-state.json +9 -32
  74. package/packages/registry/r/fab.json +9 -34
  75. package/packages/registry/r/featured-icon.json +7 -29
  76. package/packages/registry/r/filter-bar.json +10 -35
  77. package/packages/registry/r/gradient-picker.json +7 -24
  78. package/packages/registry/r/header-navigation.json +9 -32
  79. package/packages/registry/r/hero-header.json +7 -25
  80. package/packages/registry/r/icon-system.json +14 -29
  81. package/packages/registry/r/image-picker.json +7 -24
  82. package/packages/registry/r/inline-cta.json +14 -32
  83. package/packages/registry/r/input.json +9 -33
  84. package/packages/registry/r/landing-page.json +6 -21
  85. package/packages/registry/r/login-page.json +9 -35
  86. package/packages/registry/r/marketing-header.json +8 -26
  87. package/packages/registry/r/menu.json +9 -34
  88. package/packages/registry/r/messaging.json +9 -33
  89. package/packages/registry/r/metric-card.json +9 -32
  90. package/packages/registry/r/mobile-screen.json +9 -32
  91. package/packages/registry/r/not-found.json +7 -25
  92. package/packages/registry/r/page-header.json +9 -32
  93. package/packages/registry/r/pagination.json +15 -31
  94. package/packages/registry/r/progress-steps.json +9 -33
  95. package/packages/registry/r/run-inspector.json +9 -32
  96. package/packages/registry/r/section-header.json +9 -32
  97. package/packages/registry/r/settings-01.json +5 -19
  98. package/packages/registry/r/settings-02.json +5 -19
  99. package/packages/registry/r/settings-page.json +9 -32
  100. package/packages/registry/r/sidebar-navigation.json +9 -32
  101. package/packages/registry/r/sign-in-form.json +9 -34
  102. package/packages/registry/r/skeleton.json +9 -32
  103. package/packages/registry/r/spinner.json +9 -32
  104. package/packages/registry/r/tabs.json +9 -34
  105. package/packages/registry/r/textarea.json +9 -33
  106. package/packages/registry/r/tool-call.json +9 -32
  107. package/packages/registry/r/tooltip.json +9 -33
  108. package/packages/registry/r/utility-button.json +9 -37
  109. package/packages/registry/r/workflow-canvas.json +9 -32
  110. package/packages/registry/r/workflow-node.json +9 -32
  111. package/packages/registry/registry.json +232 -937
  112. package/packages/registry/search-index.json +579 -2194
  113. package/packages/ui/package.json +4 -1
  114. package/packages/ui/src/date-picker.browser.test.tsx +1 -1
  115. package/packages/ui/src/date-picker.tsx +1 -2
  116. package/packages/ui/src/gradient-picker.tsx +6 -2
  117. package/packages/ui/src/theme-provider.browser.test.tsx +15 -6
  118. package/packages/ui/src/theme-provider.tsx +19 -5
  119. package/packages/workflow-ui/src/workflow-canvas.tsx +1 -1
  120. package/packages/workflow-ui/src/workflow-node.tsx +1 -1
  121. package/scripts/enrich-registry-payloads.mjs +9 -3
  122. package/scripts/fix-registry-closure.mjs +2 -1
  123. package/scripts/generate-manifest.mjs +61 -39
  124. package/scripts/validate-manifest.mjs +24 -33
  125. package/scripts/verify-registry-consumer.mjs +33 -7
  126. package/tests/e2e/catalog-typography.spec.ts +6 -4
  127. package/tests/icons.test.mjs +5 -5
  128. package/tsconfig.base.json +17 -51
  129. package/apps/showcase/src/catalog/__screenshots__/catalog-shell.browser.test.tsx/filters-the-component-inventory-and-exposes-the-selected-audit-state-1.png +0 -0
  130. package/apps/showcase/src/catalog/__screenshots__/catalog-shell.browser.test.tsx/opens-a-component-detail-view-and-returns-to-the-grid-1.png +0 -0
  131. package/apps/showcase/src/catalog/__screenshots__/catalog-shell.browser.test.tsx/switching-locale-to-Persian-updates-document-direction-to-rtl-1.png +0 -0
  132. package/packages/ui/src/__screenshots__/button.browser.test.tsx/Button-preserves-native--busy--disabled--and-ref-contracts-1.png +0 -0
  133. package/packages/ui/src/__screenshots__/button.browser.test.tsx/a-disabled-polymorphic-Button-cannot-navigate-or-receive-focus-1.png +0 -0
  134. package/packages/ui/src/__screenshots__/date-picker.browser.test.tsx/DatePicker-Escape-closes-popover-and-returns-focus-to-input-1.png +0 -0
  135. package/packages/ui/src/__screenshots__/date-picker.browser.test.tsx/DatePicker-click-outside-closes-popover-1.png +0 -0
  136. package/packages/ui/src/__screenshots__/dialog.browser.test.tsx/Dialog-propagates-RTL-into-the-portal-and-traps-then-restores-focus-1.png +0 -0
package/README.md CHANGED
@@ -1,21 +1,36 @@
1
1
  # NOE Design System
2
2
 
3
- NOE is a multilingual, bidirectional, theme-aware React design system. This package
4
- publishes an agent-readable source snapshot: semantic tokens, component source,
5
- registry metadata, reference apps, documentation, and verification contracts.
3
+ NOE is a multilingual, bidirectional, theme-aware React design system. The public
4
+ `noecosystem-design` package is an agent-readable source snapshot: semantic tokens,
5
+ component source, registry metadata, reference apps, documentation, and verification
6
+ contracts.
6
7
 
7
- ## Start here
8
+ ## Quick start
9
+
10
+ ### Give a coding agent NOE context
8
11
 
9
12
  ```bash
10
- # Give a coding agent the NOE source context.
11
13
  npm install noecosystem-design
14
+ ```
15
+
16
+ The package is read-only source context, not a compiled runtime dependency. Start an
17
+ agent with these files, in this order:
12
18
 
13
- # The agent starts with these files after installation:
19
+ ```bash
14
20
  cat node_modules/noecosystem-design/AGENTS.md
15
21
  cat node_modules/noecosystem-design/llms.txt
16
22
  cat node_modules/noecosystem-design/docs/design-system/gpt-agent-prompt.md
23
+ ```
17
24
 
18
- # For a writable, verifiable workspace, use a repository checkout.
25
+ For GPT, copy
26
+ [`docs/design-system/gpt-agent-prompt.md`](docs/design-system/gpt-agent-prompt.md),
27
+ replace `<TARGET_REPOSITORY>` and `<DESCRIBE THE REQUESTED OUTCOME...>`, and send it
28
+ as one task. Keep the task section outcome-focused; the template already supplies
29
+ the stable NOE operating context.
30
+
31
+ ### Work on NOE itself
32
+
33
+ ```bash
19
34
  git clone https://github.com/NOrchestration/noe-design-system.git
20
35
  cd noe-design-system
21
36
  corepack enable
@@ -24,38 +39,34 @@ pnpm check
24
39
  ```
25
40
 
26
41
  Read [`AGENTS.md`](AGENTS.md) before changing code. Use [`llms.txt`](llms.txt) as the
27
- retrieval map, then read the affected package and component records. The canonical
28
- catalog is [`packages/registry/manifest.json`](packages/registry/manifest.json).
42
+ retrieval map, then inspect the affected package and component records. The canonical
43
+ component catalog is [`packages/registry/manifest.json`](packages/registry/manifest.json).
29
44
 
30
- For a GPT coding agent, copy
31
- [`docs/design-system/gpt-agent-prompt.md`](docs/design-system/gpt-agent-prompt.md),
32
- replace `<TARGET_REPOSITORY>` and `<DESCRIBE THE REQUESTED OUTCOME...>`, and send it
33
- as one task prompt. The template carries static NOE context once; put only the
34
- requested outcome, scope, and non-negotiable constraints in its `Task` section.
45
+ ## Package contract
35
46
 
36
- ## What `noecosystem-design` is and is not
47
+ | Use `noecosystem-design` for | Do not use it for |
48
+ | --- | --- |
49
+ | Giving an agent NOE source, rules, registry metadata, and examples | `import { Button } from "noecosystem-design"` |
50
+ | Reviewing or adapting NOE patterns in another repository | Replacing a published runtime component library |
51
+ | Finding reusable components before designing a new one | Assuming a public registry endpoint is deployed |
37
52
 
38
- - It is a source and metadata distribution for people and coding agents.
39
- - It is not a compiled runtime library: do not write `import { Button } from
40
- "noecosystem-design"`.
41
- - Internal source packages use the `@noe/*` names. They are workspace boundaries,
42
- not published npm packages at this time.
43
- - The shadcn-compatible `@noe` registry is locally generated and tested, but its
44
- external site endpoint is not yet evidenced as deployed. Do not claim or assume
45
- that `shadcn add @noe/<item>` works against the public domain.
53
+ Internal source packages use the `@noe/*` names. They are workspace boundaries, not
54
+ published npm packages. The shadcn-compatible `@noe` registry is locally generated
55
+ and tested, but its external endpoint is not deployment-proven; do not assume that
56
+ `shadcn add @noe/<item>` works against a public domain.
46
57
 
47
- ## Agent operating route
58
+ ## Agent workflow
48
59
 
49
60
  1. Read `AGENTS.md`, then `llms.txt`.
50
- 2. Find the requested capability in `packages/registry/manifest.json`; read its
51
- `useWhen`, `doNotUseWhen`, accessibility, i18n, and dependency contracts.
61
+ 2. Locate the capability in `packages/registry/manifest.json`; read its `useWhen`,
62
+ `doNotUseWhen`, accessibility, i18n, and dependency contracts.
52
63
  3. Reuse an existing `@noe` component before considering a foundation or new code.
53
- 4. Preserve semantic tokens, i18n, RTL/bidi, and portal direction contracts.
64
+ 4. Preserve semantic tokens, i18n, RTL/bidi, and portal-direction contracts.
54
65
  5. Update source, stories, tests, registry metadata, and documentation together.
55
- 6. Report only executed verification; planned or locally generated registry output
56
- is not deployment evidence.
66
+ 6. Report only checks actually executed; local registry output is not evidence of a
67
+ deployed external installation path.
57
68
 
58
- ## Workspace commands
69
+ ## Workspace checks
59
70
 
60
71
  | Command | Purpose |
61
72
  | --- | --- |
@@ -70,6 +81,28 @@ requested outcome, scope, and non-negotiable constraints in its `Task` section.
70
81
  | `pnpm verify` | Registry, i18n, RTL, governance, and secret audits |
71
82
  | `pnpm check` | Full local release gate |
72
83
 
84
+ ## Automated npm publishing
85
+
86
+ The repository uses npm Trusted Publishing with GitHub Actions OIDC. After a change
87
+ is merged into `main`, the `ci` workflow must complete successfully before
88
+ [`publish.yml`](.github/workflows/publish.yml) publishes the package.
89
+
90
+ - Publishing uses short-lived OIDC credentials; no npm token is stored in GitHub.
91
+ - npm provenance attestations are unavailable while this GitHub repository is private.
92
+ - A version already present on npm is skipped, so a re-run cannot overwrite it.
93
+ - Bump the root `package.json` version before merging a release-worthy change.
94
+ - `workflow_dispatch` supports an intentional manual re-run from `main`.
95
+
96
+ The optional dependency-review job is disabled unless the repository variable
97
+ `ENABLE_DEPENDENCY_REVIEW` is set to `true` after Dependency Graph and GitHub
98
+ Advanced Security are enabled in repository settings.
99
+
100
+ CodeQL is similarly opt-in through `ENABLE_CODEQL=true`: first enable **Code
101
+ Security** for this private repository in GitHub’s security settings, then set the
102
+ variable. This avoids a misleading failed workflow when GitHub cannot accept SARIF
103
+ uploads. The workflows use Node 24; the runner’s Node 20 deprecation notice does not
104
+ require a compatibility override.
105
+
73
106
  ## Architecture
74
107
 
75
108
  ```text
@@ -84,8 +117,13 @@ packages/icons Icon policy and directional mirroring
84
117
  packages/registry Canonical component catalog and install metadata
85
118
  ```
86
119
 
87
- See [`docs/design-system/README.md`](docs/design-system/README.md) for the focused
88
- documentation index and [`docs/design-system/agent-guide.md`](docs/design-system/agent-guide.md)
89
- for the coding-agent workflow. The ready-to-paste
90
- [`docs/design-system/gpt-agent-prompt.md`](docs/design-system/gpt-agent-prompt.md)
91
- is the recommended task wrapper for GPT.
120
+ ## Documentation
121
+
122
+ - [`docs/design-system/README.md`](docs/design-system/README.md): focused
123
+ documentation index
124
+ - [`docs/design-system/agent-guide.md`](docs/design-system/agent-guide.md): agent
125
+ workflow and verification expectations
126
+ - [`docs/design-system/gpt-agent-prompt.md`](docs/design-system/gpt-agent-prompt.md):
127
+ ready-to-paste GPT task wrapper
128
+ - [`packages/registry/manifest.json`](packages/registry/manifest.json): canonical
129
+ registry catalog and component contracts
@@ -23,7 +23,7 @@ import {
23
23
  PieChart,
24
24
  RadarChart,
25
25
  } from '@noe/data-ui';
26
- import { ChevronIcon, icons8Source, NoeMark } from '@noe/icons';
26
+ import { ChevronIcon, iconsaxFreeSource, NoeMark } from '@noe/icons';
27
27
  import {
28
28
  AboutPage,
29
29
  Alert,
@@ -261,9 +261,7 @@ export const catalogEntries: readonly CatalogEntry[] = [
261
261
  preview: ({ t }) => (
262
262
  <div style={{ display: 'grid', gap: '0.5rem', fontSize: '0.875rem' }}>
263
263
  <AutoDirectionText>{t('catalog.preview.bidi.autoText')}</AutoDirectionText>
264
- <BidiText>
265
- PR #482 {t('catalog.preview.bidi.related')}
266
- </BidiText>
264
+ <BidiText>PR #482 {t('catalog.preview.bidi.related')}</BidiText>
267
265
  <TechnicalValue>a1b2c3d4 · mcp://fs/read</TechnicalValue>
268
266
  <span dir="ltr" style={{ fontFamily: 'var(--font-sf-pro, var(--noe-font-family-sans))' }}>
269
267
  <LocalizedNumber value={128942.5} locale="en" /> ·{' '}
@@ -316,7 +314,7 @@ export const catalogEntries: readonly CatalogEntry[] = [
316
314
  status: statusOf('icon-system'),
317
315
  name: 'Icon System',
318
316
  description:
319
- 'Icons8-sourced interface icons with an explicit directional-mirroring policy for RTL layouts.',
317
+ 'Iconsax Free interface icons delivered through the NOE wrapper with an explicit directional-mirroring policy for RTL layouts.',
320
318
  package: '@noe/icons',
321
319
  registryItem: null,
322
320
  preview: () => (
@@ -338,7 +336,7 @@ export const catalogEntries: readonly CatalogEntry[] = [
338
336
  </div>
339
337
  </div>
340
338
  <span className="font-mono text-[0.6875rem] text-muted-foreground">
341
- {icons8Source.provider} / {icons8Source.asset}
339
+ {iconsaxFreeSource.provider} / {iconsaxFreeSource.package}
342
340
  </span>
343
341
  </div>
344
342
  ),
@@ -491,7 +489,9 @@ export const catalogEntries: readonly CatalogEntry[] = [
491
489
  package: '@noe/ui',
492
490
  registryItem: null,
493
491
  preview: () => (
494
- <div style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', alignItems: 'center' }}>
492
+ <div
493
+ style={{ display: 'flex', flexDirection: 'column', gap: '0.75rem', alignItems: 'center' }}
494
+ >
495
495
  <Card style={{ maxWidth: '20rem', width: '100%' }}>
496
496
  <CardHeader>
497
497
  <CardTitle>Syncing</CardTitle>
@@ -1646,7 +1646,7 @@ export const catalogEntries: readonly CatalogEntry[] = [
1646
1646
  description: 'Marketing header navigation with brand, links and actions.',
1647
1647
  package: '@noe/ui',
1648
1648
  registryItem: 'marketing-header',
1649
- preview: () => (
1649
+ preview: () => (
1650
1650
  <MarketingHeader
1651
1651
  brand={<span>NOE</span>}
1652
1652
  links={
@@ -96,7 +96,9 @@ export function CatalogShell({ initialEntries = catalogEntries }: CatalogShellPr
96
96
  try {
97
97
  return (
98
98
  typeof document !== 'undefined' &&
99
- (document as unknown as { fonts?: { check: (s: string) => boolean } }).fonts?.check(fontSpec) === true
99
+ (document as unknown as { fonts?: { check: (s: string) => boolean } }).fonts?.check(
100
+ fontSpec,
101
+ ) === true
100
102
  );
101
103
  } catch {
102
104
  return false;
@@ -109,7 +111,10 @@ export function CatalogShell({ initialEntries = catalogEntries }: CatalogShellPr
109
111
  markReady();
110
112
  return;
111
113
  }
112
- const hasLoad = typeof document !== 'undefined' && typeof (document as unknown as { fonts?: { load: (s: string) => Promise<unknown> } }).fonts?.load === 'function';
114
+ const hasLoad =
115
+ typeof document !== 'undefined' &&
116
+ typeof (document as unknown as { fonts?: { load: (s: string) => Promise<unknown> } }).fonts
117
+ ?.load === 'function';
113
118
  if (hasLoad) {
114
119
  let timedOut = false;
115
120
  const timeoutId = setTimeout(() => {
@@ -22,7 +22,9 @@ export const Jalali: Story = {
22
22
  };
23
23
  export const JalaliLeapDay: Story = {
24
24
  args: { calendar: 'persian', locale: 'fa-IR', value: new Date('2025-03-20T00:00:00Z') },
25
- render: () => <Calendar calendar="persian" locale="fa-IR" value={new Date('2025-03-20T00:00:00Z')} />,
25
+ render: () => (
26
+ <Calendar calendar="persian" locale="fa-IR" value={new Date('2025-03-20T00:00:00Z')} />
27
+ ),
26
28
  };
27
29
  export const WithMinMax: Story = {
28
30
  args: {
@@ -17,7 +17,11 @@ export const RTL: Story = {
17
17
  ),
18
18
  };
19
19
  export const WithMinMax: Story = {
20
- args: { min: new Date('2025-03-10T00:00:00Z'), max: new Date('2025-03-20T00:00:00Z'), value: new Date('2025-03-15T00:00:00Z') },
20
+ args: {
21
+ min: new Date('2025-03-10T00:00:00Z'),
22
+ max: new Date('2025-03-20T00:00:00Z'),
23
+ value: new Date('2025-03-15T00:00:00Z'),
24
+ },
21
25
  };
22
26
  export const Jalali: Story = {
23
27
  args: { calendar: 'persian', locale: 'fa-IR', value: new Date('2025-03-20T00:00:00Z') },
@@ -3,7 +3,7 @@ import type { Meta, StoryObj } from '@storybook/react-vite';
3
3
  import {
4
4
  ChevronIcon,
5
5
  iconDirectionPolicy,
6
- icons8Source,
6
+ iconsaxFreeSource,
7
7
  NoeMark,
8
8
  } from '../../../../packages/icons/src/index';
9
9
 
@@ -31,7 +31,8 @@ function IconGallery() {
31
31
  <strong>Never mirror:</strong> {iconDirectionPolicy.neverMirror.join(', ')}
32
32
  </div>
33
33
  <div>
34
- <strong>Interface source:</strong> {icons8Source.provider} / {icons8Source.asset}
34
+ <strong>Interface source:</strong> {iconsaxFreeSource.provider} /{' '}
35
+ {iconsaxFreeSource.package}
35
36
  </div>
36
37
  </div>
37
38
  );
@@ -1,9 +1,9 @@
1
- # ADR 0006: Icons8 icon policy
1
+ # ADR 0006: Iconsax Free icon policy
2
2
 
3
3
  Status: Accepted
4
4
 
5
- Earlier proposals locked Lucide as the product icon family. The repository has since adopted Icons8 as the icon source (`packages/icons/src/index.tsx`, `icons8Source`, commit "feat: adopt Icons8 logical chevrons"), with `NoeMark` registered as a separate NOE brand asset.
5
+ Earlier proposals locked Lucide as the product icon family. The repository now adopts Iconsax Free through the audited `@noe/icons` wrapper (`packages/icons/src/iconsax.tsx`, `iconsaxFreeSource`), with `NoeMark` registered as a separate NOE brand asset.
6
6
 
7
- Decision: the product uses exactly one icon family, Icons8, plus NOE brand marks. Directional icons use logical directions (`forward`/`backward`) and mirror only through the scoped `.noe-logical-icon` class under `iconDirectionPolicy`; brand marks never mirror. Lucide is not adopted and icon families must not be mixed.
7
+ Decision: the product uses exactly one provider icon family, Iconsax Free, plus NOE brand marks. Applications import from `@noe/icons`, never from `iconsax-react`. Directional icons use logical directions (`forward`/`backward`) and mirror only through the scoped `.noe-logical-icon` class under `iconDirectionPolicy`; brand marks never mirror. Lucide is not adopted and icon families must not be mixed.
8
8
 
9
- Consequences: every added third-party icon records provider and source metadata in the style of `icons8Source`; `NoeMark` is a NOE brand asset, not an Icons8 icon, and carries no such source record; Icons8 licensing terms are part of adoption review; icon-related documentation and stories must reflect the mirroring policy rather than physical left/right semantics.
9
+ Consequences: every added third-party icon records provider and source metadata in the style of `iconsaxFreeSource`; `NoeMark` is a NOE brand asset and carries no provider metadata; Iconsax Free's MIT license is part of adoption review; icon-related documentation and stories must reflect the mirroring policy rather than physical left/right semantics.
@@ -42,5 +42,5 @@ deployment gate in ADR 0007.
42
42
  - No custom MCP server while the official shadcn MCP satisfies registry discovery.
43
43
  - Registry publication and package release are separate operational gates (ADR 0007).
44
44
  - `@noe/*` is the single package namespace for packages, registry items, diagrams and agent instructions (ADR 0005).
45
- - Icons8 is the only third-party icon family; NOE brand marks never mirror (ADR 0006).
45
+ - Iconsax Free is the only third-party icon family, exposed through `@noe/icons`; NOE brand marks never mirror (ADR 0006).
46
46
  - Capability libraries stay behind adapters; NOE tokens and `@noe/*` own product markup, style, RTL behavior and approval states (ADR 0008).
@@ -14,24 +14,37 @@ entry and push to the default branch:
14
14
  | `ci / build-and-verify` | Workspace build + registry/i18n/RTL/governance audits |
15
15
  | `ci / e2e-critical` | Playwright matrix: chromium en/fa/pseudo + firefox/webkit smoke |
16
16
 
17
- The `security` workflow adds CodeQL analysis, scheduled CodeQL runs and
18
- dependency review on pull requests.
17
+ The `security` workflow contains opt-in CodeQL analysis and dependency review.
18
+ For this private repository, GitHub must first have Code Security and Dependency
19
+ Graph/GitHub Advanced Security enabled. Set `ENABLE_CODEQL=true` and
20
+ `ENABLE_DEPENDENCY_REVIEW=true` repository variables only after the corresponding
21
+ GitHub features are available.
19
22
 
20
23
  ## Security controls
21
24
 
22
- - Minimal `GITHUB_TOKEN` permissions (`contents: read`; `security-events: write`
23
- only where CodeQL needs it).
25
+ - Minimal `GITHUB_TOKEN` permissions. CodeQL receives `actions: read`,
26
+ `contents: read`, and `security-events: write`; dependency review receives only
27
+ `contents: read`.
24
28
  - All third-party actions pinned to immutable full commit SHAs with the
25
29
  upstream version documented beside them; Dependabot keeps SHAs updated.
26
30
  - No secrets in logs; no privileged secrets available to untrusted PR code.
27
- - Concurrency groups cancel superseded PR runs; deployments are never cancelled
28
- mid-run because none run from CI yet.
31
+ - Concurrency groups cancel superseded PR runs. The npm publishing workflow is
32
+ serialized and is never cancelled mid-publish.
29
33
 
30
34
  ## Artifacts
31
35
 
32
36
  Storybook static build, dist outputs, Playwright reports/traces/screenshots are
33
37
  uploaded with 14-day retention on relevant outcomes.
34
38
 
39
+ ## Publishing
40
+
41
+ `publish.yml` runs after a successful `ci` workflow on a push to `main`. It checks
42
+ out the verified commit, builds it, verifies the npm tarball, and publishes only if
43
+ the root `package.json` version is not already on npm. npm Trusted Publishing uses
44
+ GitHub Actions OIDC, so the workflow stores no npm token.
45
+
46
+ Manual `workflow_dispatch` publishing is restricted to `main`.
47
+
35
48
  ## Deployment
36
49
 
37
50
  No deployment provider is invented. Storybook artifacts are produced on every
@@ -43,4 +56,6 @@ long-lived credentials.
43
56
 
44
57
  Recommended required status checks once branch protection is active:
45
58
  `ci / quality`, `ci / unit`, `ci / component`, `ci / storybook`,
46
- `ci / build-and-verify`, `ci / e2e-critical`, `security / codeql`.
59
+ `ci / build-and-verify`, `ci / e2e-critical`. Add `security / codeql` only after
60
+ Code Security is enabled and `ENABLE_CODEQL=true`; otherwise it is intentionally
61
+ skipped rather than reported as a false failure.
@@ -386,4 +386,3 @@ Total catalog entries: **129** · registry items: **67**
386
386
  - `fab`: Mobile-only floating action button anchored to the logical end edge above the bottom navigation, with safe-area padding and required accessible label.
387
387
  - `mobile-screen`: Single-column mobile page scaffold composing an app bar, scrollable content region, optional floating action button and bottom navigation.
388
388
  - `bottom-navigation`: Mobile-only bottom tab bar with current-page state, badges, icon slots and safe-area padding; hidden from the medium breakpoint upward.
389
-
@@ -16,7 +16,7 @@ Use logical margin, padding, inset, border and text alignment. Maintain semantic
16
16
 
17
17
  Forward/backward, next/previous, chevron, indent/outdent and panel-opening icons may mirror. Brand, play, pause, upload, download, search, settings, check, close, charts, code and service logos do not mirror automatically.
18
18
 
19
- The shared `ChevronIcon` uses `icons8Source` and opts into this policy through the scoped `.noe-logical-icon` class. `NoeMark` remains a NOE brand asset and never mirrors.
19
+ The shared `ChevronIcon` uses the `iconsaxFreeSource` wrapper and opts into this policy through the scoped `.noe-logical-icon` class. `NoeMark` remains a NOE brand asset and never mirrors.
20
20
 
21
21
  ## Mixed content
22
22
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noecosystem-design",
3
- "version": "0.1.2",
3
+ "version": "0.2.0",
4
4
  "private": false,
5
5
  "description": "Agent-readable NOE design-system source, registry metadata, and verification contracts.",
6
6
  "keywords": [
@@ -94,7 +94,7 @@
94
94
  "format": "biome format --write .",
95
95
  "format:check": "biome format .",
96
96
  "gen:inventory": "node scripts/generate-inventory.mjs",
97
- "gen:manifest": "node scripts/generate-manifest.mjs",
97
+ "gen:manifest": "node scripts/generate-manifest.mjs && biome format --write packages/registry/manifest.json packages/registry/component-audit.json packages/registry/search-index.json packages/registry/registry.json packages/registry/catalog-index.json packages/registry/docs-index.json",
98
98
  "validate:manifest": "node scripts/validate-manifest.mjs",
99
99
  "lint": "biome lint .",
100
100
  "typecheck": "tsc -p tsconfig.json --pretty false",
@@ -1,4 +1,3 @@
1
-
2
1
  import type * as React from 'react';
3
2
  import { cn } from '@noe/ui/lib/cn';
4
3
 
@@ -57,4 +56,4 @@ export function ActivityFeed({ label, items, className, ...props }: ActivityFeed
57
56
  ))}
58
57
  </ol>
59
58
  );
60
- }
59
+ }
@@ -51,4 +51,4 @@ export function AgentComposer({
51
51
  </div>
52
52
  </form>
53
53
  );
54
- }
54
+ }
@@ -47,4 +47,4 @@ export function AgentMessage({
47
47
  </AutoDirectionText>
48
48
  </article>
49
49
  );
50
- }
50
+ }
@@ -66,4 +66,4 @@ export function AgentPlan({
66
66
  </ol>
67
67
  </section>
68
68
  );
69
- }
69
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import type * as React from 'react';
3
2
  import { cn } from '@noe/ui/lib/cn';
4
3
 
@@ -60,4 +59,4 @@ export function AgentWorkspace({
60
59
  ) : null}
61
60
  </section>
62
61
  );
63
- }
62
+ }
@@ -90,4 +90,4 @@ export function ApprovalRequest({
90
90
  </footer>
91
91
  </section>
92
92
  );
93
- }
93
+ }
@@ -51,4 +51,4 @@ export function RunInspector({
51
51
  {children}
52
52
  </aside>
53
53
  );
54
- }
54
+ }
@@ -68,4 +68,4 @@ export function ToolCall({
68
68
  </div>
69
69
  </details>
70
70
  );
71
- }
71
+ }
@@ -35,4 +35,4 @@ export function ActivityGauge({ className, ...props }: React.ComponentProps<'div
35
35
  </table>
36
36
  </div>
37
37
  );
38
- }
38
+ }
@@ -38,4 +38,4 @@ export function ChartFrame({
38
38
  </div>
39
39
  </figure>
40
40
  );
41
- }
41
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import type * as React from 'react';
3
2
  import { cn } from '@noe/ui/lib/cn';
4
3
 
@@ -128,4 +127,4 @@ export function Chart({
128
127
  </div>
129
128
  </div>
130
129
  );
131
- }
130
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import type * as React from 'react';
3
2
  import { cn } from '@noe/ui/lib/cn';
4
3
 
@@ -53,4 +52,4 @@ export function DashboardShell({
53
52
  {pagination ? <div data-slot="dashboard-shell-pagination">{pagination}</div> : null}
54
53
  </section>
55
54
  );
56
- }
55
+ }
@@ -96,4 +96,4 @@ export function DataTable<Row extends { id: string }>({
96
96
  </table>
97
97
  </section>
98
98
  );
99
- }
99
+ }
@@ -1,4 +1,3 @@
1
-
2
1
  import type * as React from 'react';
3
2
  import { cn } from '@noe/ui/lib/cn';
4
3
 
@@ -25,4 +24,4 @@ export function FilterBar({ label, search, filters, action, className, ...props
25
24
  {action ? <div className="ms-auto flex items-center gap-2">{action}</div> : null}
26
25
  </search>
27
26
  );
28
- }
27
+ }
@@ -40,4 +40,4 @@ export function MetricCard({
40
40
  ) : null}
41
41
  </article>
42
42
  );
43
- }
43
+ }
@@ -1,5 +1,3 @@
1
-
2
-
3
1
  import type * as React from 'react';
4
2
  import { ChevronIcon } from '@noe/icons';
5
3
  import { Button } from '@noe/ui/button';
@@ -64,4 +62,4 @@ export function Pagination({
64
62
  </Button>
65
63
  </nav>
66
64
  );
67
- }
65
+ }
@@ -35,4 +35,4 @@ export function PieChart({ className, ...props }: React.ComponentProps<'div'>) {
35
35
  </table>
36
36
  </div>
37
37
  );
38
- }
38
+ }
@@ -35,4 +35,4 @@ export function RadarChart({ className, ...props }: React.ComponentProps<'div'>)
35
35
  </table>
36
36
  </div>
37
37
  );
38
- }
38
+ }
@@ -173,7 +173,7 @@
173
173
  }
174
174
  }
175
175
 
176
- /* Logical Icons8 chevrons opt into direction-aware motion. Brand and
176
+ /* Logical Iconsax chevrons opt into direction-aware motion. Brand and
177
177
  * semantic glyphs do not receive a global transform. */
178
178
  .noe-logical-icon[data-logical-direction="backward"],
179
179
  [dir="rtl"] .noe-logical-icon[data-logical-direction="forward"] {
@@ -5,14 +5,14 @@
5
5
  * from this registry to avoid hard-coded duplication.
6
6
  */
7
7
 
8
- export const PALETTES = ["graphite"] as const;
8
+ export const PALETTES = ['graphite'] as const;
9
9
 
10
10
  export type Palette = (typeof PALETTES)[number];
11
11
 
12
- export const DEFAULT_PALETTE: Palette = "graphite";
12
+ export const DEFAULT_PALETTE: Palette = 'graphite';
13
13
 
14
- export const PALETTE_STORAGE_KEY = "noecosystem-palette";
15
- export const PALETTE_COOKIE_KEY = "noecosystem-palette";
14
+ export const PALETTE_STORAGE_KEY = 'noecosystem-palette';
15
+ export const PALETTE_COOKIE_KEY = 'noecosystem-palette';
16
16
 
17
17
  export function isPalette(value: unknown): value is Palette {
18
18
  return (PALETTES as readonly string[]).includes(value as string);
@@ -145,8 +145,8 @@
145
145
  --noe-color-muted-foreground: var(--noe-primitive-color-ink-500);
146
146
  --noe-color-border: rgba(23, 25, 24, 0.16);
147
147
  --noe-color-border-strong: var(--noe-primitive-color-ink-300);
148
- --noe-color-accent: var(--noe-primitive-color-mint-500);
149
- --noe-color-accent-hover: var(--noe-primitive-color-mint-400);
148
+ --noe-color-accent: var(--noe-primitive-color-cyan-500);
149
+ --noe-color-accent-hover: var(--noe-primitive-color-cyan-500);
150
150
  --noe-color-accent-foreground: var(--noe-primitive-color-paper-0);
151
151
  --noe-color-signal: var(--noe-primitive-color-coral-500);
152
152
  --noe-color-success: var(--noe-primitive-color-green-600);
@@ -175,8 +175,8 @@
175
175
  --noe-color-muted-foreground: var(--noe-primitive-color-ink-400);
176
176
  --noe-color-border: rgba(246, 244, 242, 0.14);
177
177
  --noe-color-border-strong: var(--noe-primitive-color-ink-600);
178
- --noe-color-accent: var(--noe-primitive-color-mint-100);
179
- --noe-color-accent-hover: var(--noe-primitive-color-mint-200);
178
+ --noe-color-accent: var(--noe-primitive-color-cyan-400);
179
+ --noe-color-accent-hover: var(--noe-primitive-color-cyan-400);
180
180
  --noe-color-accent-foreground: var(--noe-primitive-color-ink-950);
181
181
  --noe-color-signal: var(--noe-primitive-color-coral-400);
182
182
  --noe-color-success: var(--noe-primitive-color-green-500);
@@ -206,8 +206,8 @@
206
206
  --noe-color-muted-foreground: var(--noe-primitive-color-ink-400);
207
207
  --noe-color-border: rgba(246, 244, 242, 0.14);
208
208
  --noe-color-border-strong: var(--noe-primitive-color-ink-600);
209
- --noe-color-accent: var(--noe-primitive-color-mint-100);
210
- --noe-color-accent-hover: var(--noe-primitive-color-mint-200);
209
+ --noe-color-accent: var(--noe-primitive-color-cyan-400);
210
+ --noe-color-accent-hover: var(--noe-primitive-color-cyan-400);
211
211
  --noe-color-accent-foreground: var(--noe-primitive-color-ink-950);
212
212
  --noe-color-signal: var(--noe-primitive-color-coral-400);
213
213
  --noe-color-success: var(--noe-primitive-color-green-500);
@@ -225,12 +225,6 @@
225
225
  }
226
226
  }
227
227
 
228
- /* Palette: Graphite is the only approved palette. Extendable via [data-noe-palette="..."] overrides. */
229
- :root,
230
- [data-noe-palette="graphite"] {
231
- /* No overrides — graphite uses the default semantic tokens above. */
232
- }
233
-
234
228
  /* Component tokens: stable customization seams. */
235
229
  :root {
236
230
  --noe-component-button-height: var(--noe-control-height-md);