@reqvire-org/ads 0.3.0 → 0.3.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.
Files changed (56) hide show
  1. package/README.md +1 -1
  2. package/dist/bootstrap-ds/ADS.md +47 -7
  3. package/dist/bootstrap-ds/README.md +12 -10
  4. package/dist/bootstrap-ds/design-system/index.ts +1 -1
  5. package/dist/bootstrap-ds/design-system/patterns/token-preview/Scenario.tsx +4 -0
  6. package/dist/bootstrap-ds/design-system/patterns/token-preview/TokenPreview.tsx +31 -0
  7. package/dist/bootstrap-ds/design-system/patterns/token-preview/fixture.ts +8 -0
  8. package/dist/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +44 -43
  9. package/dist/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +3 -13
  10. package/dist/bootstrap-ds/design-system/tokens/base.css +4 -1
  11. package/dist/bootstrap-ds/design-system/tokens/colors.css +2 -2
  12. package/dist/bootstrap-ds/ds.config.json +10 -0
  13. package/dist/check.mjs +29 -13
  14. package/dist/contracts/foundation.json +211 -0
  15. package/dist/foundation.mjs +114 -0
  16. package/dist/init.mjs +22 -5
  17. package/dist/mcp/apps.mjs +2 -2
  18. package/dist/mcp/build-status.mjs +22 -9
  19. package/dist/mcp/context.mjs +1 -1
  20. package/dist/mcp/preview-watch.mjs +35 -12
  21. package/dist/mcp/preview-widget.bundle.js +40 -38
  22. package/dist/mcp/project-widget.bundle.js +42 -38
  23. package/dist/mcp/prompts.mjs +1 -1
  24. package/dist/mcp/server.mjs +5 -5
  25. package/dist/preview-resources.mjs +1 -1
  26. package/dist/scenarios-compiler.mjs +86 -43
  27. package/dist/scenarios.mjs +16 -5
  28. package/dist/skills/ads-assimilate/SKILL.md +47 -12
  29. package/dist/skills/ads-assimilate/references/cli.md +3 -2
  30. package/dist/skills/ads-break-ui/SKILL.md +47 -12
  31. package/dist/skills/ads-break-ui/references/verification.md +4 -0
  32. package/dist/skills/ads-designer/SKILL.md +49 -14
  33. package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +47 -7
  34. package/dist/skills/ads-designer/assets/bootstrap-ds/README.md +12 -10
  35. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/index.ts +1 -1
  36. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/token-preview/Scenario.tsx +4 -0
  37. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/token-preview/TokenPreview.tsx +31 -0
  38. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/token-preview/fixture.ts +8 -0
  39. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.fixture.ts +44 -43
  40. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/Foundation.scenario.tsx +3 -13
  41. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/base.css +4 -1
  42. package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/colors.css +2 -2
  43. package/dist/skills/ads-designer/assets/bootstrap-ds/ds.config.json +10 -0
  44. package/dist/skills/ads-designer/references/cli.md +3 -2
  45. package/dist/skills/ads-import/SKILL.md +47 -12
  46. package/dist/skills/ads-import/references/cli.md +3 -2
  47. package/dist/skills/ads-motion/SKILL.md +47 -12
  48. package/dist/token-policy.mjs +12 -0
  49. package/dist/token-samples.mjs +8 -0
  50. package/dist/units.mjs +34 -10
  51. package/docs/ADS.md +52 -9
  52. package/docs/ARCHITECTURE.md +44 -3
  53. package/docs/CHANGELOG.md +32 -1
  54. package/docs/GUIDE.md +17 -6
  55. package/docs/MCP.md +62 -9
  56. package/package.json +3 -2
@@ -57,9 +57,15 @@ relevant ranges with `ads_read_file` and send only a Git unified diff through
57
57
  `ads_apply_patch({ unit, patch, dryRun })`. A unit includes its own implementation,
58
58
  scenarios and fixtures; imported peers remain separate. `tokens` is the token
59
59
  foundation unit. Unit discovery and file ownership are distinct from preview IDs.
60
- Include only that owner's required re-exports in the public entry. Use
61
- `dryRun: true` to inspect validation; applying re-runs the gates. Fix rejected
62
- patches in their owner. Shared styles/helpers use `foundation`, root guides use
60
+ Include only that owner's required re-exports in the public entry; preserve
61
+ unrelated statements. Its real re-export may accompany removal of a redundant
62
+ `export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
63
+ entry in `companionFiles`: when creating/deleting a canonical token file such as
64
+ `fonts.css`, include only its required import change there in the same patch.
65
+ Preserve other imports/comments and the canonical order. Use `dryRun: true` to
66
+ inspect validation; applying re-runs the gates. Fix rejected patches in their
67
+ owner. Report unsupported coupled changes instead of bypassing a rejection with
68
+ direct source writes. Shared styles/helpers use `foundation`, root guides use
63
69
  `documentation`, and branding/fonts use their discovered `assets/*` unit.
64
70
  Intentional configuration, rule exceptions, registered guard code and compiler
65
71
  changes use `configuration`; validate the proposed settings and keep mandatory
@@ -92,8 +98,8 @@ checks; do not fetch the unpublished package.
92
98
 
93
99
  Read [assets/bootstrap-ds/README.md](assets/bootstrap-ds/README.md) and its
94
100
  [contract](assets/bootstrap-ds/ADS.md). The scaffold contains semantic token
95
- defaults, React/TypeScript/Linaria configuration, general lint, an empty public
96
- barrel, empty component/pattern directories, and a project preview compiler adapter. The browser shell is supplied by ADS tooling.
101
+ defaults, React/TypeScript/Linaria configuration, general lint, a public
102
+ barrel, empty product component directories, a project-owned token review pattern, and a project preview compiler adapter. The browser shell is supplied by ADS tooling.
97
103
  It contains no components, shell patterns, vendored fonts, or example screens.
98
104
 
99
105
  Resolve assets relative to this skill's `SKILL.md`, including after installation
@@ -299,15 +305,25 @@ entry independently and verify real behavior at narrow/wide sizes in both themes
299
305
  The older `showcase-coverage` policy separately checks application references.
300
306
 
301
307
  Token previews use that same scenario pipeline. Colocate a token scenario and
302
- fixture under the configured token directory. Use static metadata
303
- `{ title: "Typography", covers: ["TokenSamples"], tokens: fixture.tokens }` with
304
- literal const fixture fields; names/sample text are fixture data, values come
305
- from the real foundation CSS. Reuse a public project review pattern for styled
306
- samples. The minimal starter's foundation value scenario can have `covers: []`.
307
- Every declared token needs reachable scenario coverage; adding/removing a token
308
- requires fixture updates. Fix `token-scenario-reference`, `token-scenario-render`
309
- and `token-scenario-coverage` findings. Metadata and unused fixture fields do not
310
- count. Discover exact token IDs with `ads_scenarios({kind:"tokens"})`; mount them
308
+ fixture under the configured token directory. Declare metadata
309
+ `{ title: fixture.title, covers: ["TokenSamples"], samples: fixture.samples }`.
310
+ The renderer name is project-owned; use its real public API. Each literal fixture
311
+ sample declares `{ token, property, probe }`: a real token, the CSS property its
312
+ sample demonstrates, and a valid test value different from that token's current
313
+ value. Pass `samples` into the rendered public review pattern. Names, sample text,
314
+ bindings and probes are fixture data; displayed values come from foundation CSS.
315
+ There is no property catalogue, token-name mapping or probe palette in ADS.
316
+ Every token needs sample coverage; fabricated tokens, missing bindings/probes,
317
+ unused fixtures and value-only lists fail the static gates. `covers: []` is invalid.
318
+ During App rendering, the browser checks sample markers `data-ads-token` and
319
+ `data-ads-property`, validates CSS with its own `CSS.supports`, and temporarily
320
+ probes each token to verify that the declared sample property responds. It restores
321
+ values immediately. Missing, hidden, invalid or hardcoded samples produce a preview
322
+ error instead of a successful review. These browser checks apply to the mounted
323
+ scenario/theme, not every application state or pixel-level design quality.
324
+ Keep styles in the project renderer; do not add inline-style exemptions to scenarios.
325
+ Fix `token-scenario-reference`, `token-scenario-render` and `token-scenario-coverage`
326
+ findings. Metadata and unused fixture fields do not count. Discover exact token IDs with `ads_scenarios({kind:"tokens"})`; mount them
311
327
  with `ads_show_scenario({id})` or `ads_show_tokens({category:id})`. With the shared
312
328
  resource compiler, omitting category opens the first project token scenario.
313
329
  Legacy compilers retain the generic definition inspector. Use `ads_tokens` for
@@ -325,6 +341,25 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
325
341
  foundation CSS rather than assigning shared token values in JavaScript. Keep
326
342
  full-app integration harnesses and workflow coverage in application test support.
327
343
 
344
+ Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
345
+ on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
346
+ three closed roles: root/body typography, canvas and theme defaults; limited native
347
+ normalization; and global focus indicators/reduced-motion rules. Every selector
348
+ branch, property and value must fit its role. Token-backed control skins, layout,
349
+ interactive state rules and owner hooks are rejected even through `:where()`.
350
+ Do not copy an unchecked upstream preflight or turn a component repair into a reset.
351
+ Put skin/state/animation in the Linaria owner, and scenario layout variations in
352
+ the public review pattern's typed API. Browser review still verifies the effects.
353
+
354
+ Invalid metadata and source failures keep the managed compiler alive for repairs.
355
+ Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
356
+ successful output. If the builder exited, fix its command and invoke the preview
357
+ again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
358
+ also reload on the next preview invocation. Reconnect the client when upgrading
359
+ the ADS server package itself. Persistent SSE/notification streams make
360
+ `networkidle` unsuitable: wait for the App's current ready/error state instead.
361
+
362
+
328
363
 
329
364
 
330
365
  Register component/project Oxlint plugins and rules in `ds.config.json`. Use
@@ -40,6 +40,35 @@ Token names and prefixes are fixed by ADS architecture; foreign brand prefixes
40
40
  are rejected. Shared assignments belong in token files. Components own
41
41
  `--ds-*`, patterns `--ux-*`, and the showcase `--showcase-*`; token files cannot
42
42
  assign those local variables or override component state.
43
+
44
+ Foundation roles are enforced by `foundation-role`, `foundation-selector` and
45
+ `foundation-import`, alongside the regular token checks. Shared definitions
46
+ belong on the document root or explicit root themes; ordinary declarations belong
47
+ in `base.css`, and font-face descriptors in optional `fonts.css`. The entry imports
48
+ canonical sheets; those sheets cannot import another styling layer. Component
49
+ classes, IDs, data/ARIA hooks, contextual selectors, keyframes and scoped UI rules
50
+ are rejected in the foundation, including nested functional selectors. Raw visual
51
+ values and undefined token references are checked in native defaults too; literal
52
+ font-face metadata keeps its separate asset role.
53
+
54
+ `base.css` has three closed roles:
55
+
56
+ - Document defaults: root/body typography, canvas colors and theme behavior,
57
+ global text selection and document scrollbars.
58
+ - Native resets: permitted normalization properties and values, such as zero
59
+ spacing, inherited control typography, list resets and responsive replaced media.
60
+ - Global accessibility: universal `:focus-visible` outline rules, and reduced-motion
61
+ overrides inside `@media (prefers-reduced-motion: reduce)`.
62
+
63
+ The `foundation-role` check validates every selector branch, property and value.
64
+ Native selectors are not a bypass: token-backed button backgrounds, flex/grid
65
+ layout, component-specific focus rules and hover/disabled skins are rejected.
66
+ Shared token definitions belong in value sheets, not `base.css`. No project token
67
+ names are embedded in this policy. A zero-specificity `:where()` wrapper does not
68
+ change ownership. Put component design and animation in Linaria owners, and
69
+ scenario layout variations in typed public review-pattern props. Browser review
70
+ still checks the effects and accessibility of permitted defaults.
71
+
43
72
  Own primitive markup, focus, hover, selected, disabled, loading, and motion in
44
73
  the primitive. Use typed props for variations. Keep reusable structure and skin
45
74
  in colocated Linaria blocks using `css` and `cx` from `@linaria/atomic`.
@@ -114,13 +143,24 @@ design-system/
114
143
  Flat owners may use `Button.scenario.tsx` and `Button.fixture.ts` instead.
115
144
  `Scenario.tsx` exports a default independently mountable view and literal metadata
116
145
  `export const scenario = { title: "Button states", covers: ["Button"] };`.
117
- Token entries under the configured token directory also declare `tokens`:
118
- `export const scenario = { title: "Typography", covers: ["TokenSamples"], tokens: fixture.tokens };`.
119
- Metadata may read literal const fixture fields; it cannot run expressions,
120
- functions, wildcard lists or token discovery. The same fixture list must be
121
- consumed by the default entry. `covers: []` is valid for a minimal token value
122
- inspection entry without public UI; styled samples use a real public review
123
- pattern. Names and sample text belong to the fixture, values to foundation CSS.
146
+ Token entries under the configured token directory declare
147
+ `export const scenario = { title: fixture.title, covers: ["TokenSamples"], samples: fixture.samples };`.
148
+ `TokenSamples` is any project-owned public review pattern, not a required name.
149
+ Its colocated fixture declares literal `samples: [{ token, property, probe }]`.
150
+ Each token must exist and have sample coverage; duplicate bindings, missing probes,
151
+ empty covers and value-only inspectors fail. The default entry passes the declared
152
+ samples to a rendered public pattern's `samples` prop. No token-name/property mapping
153
+ or sample values are embedded in the tool. Display values come from foundation CSS;
154
+ probes are isolated verification inputs owned by the fixture.
155
+
156
+ The renderer marks the actual styled element with `data-ads-token` and
157
+ `data-ads-property`. In a browser, the App validates the declared property/value and
158
+ probe using `CSS.supports`, checks the sample is rendered, then temporarily changes
159
+ that token to its fixture probe. Its computed sample property must respond. Values
160
+ are restored before yielding to painting; hardcoded lookalikes fail. Source gates
161
+ prove the contract structure, not successful rendering. The browser check covers
162
+ the mounted scenario and theme; visual quality and other states still need review.
163
+
124
164
  It imports real public UI through `@ds` and its local fixture. The adapter supplies
125
165
  initial state, callbacks and simulated services. The default entry needs no
126
166
  mandatory caller inputs or prior page initialization. Related parts may share a
@@ -1,8 +1,8 @@
1
1
  # Empty native design system
2
2
 
3
- This private React/TypeScript workspace contains semantic CSS tokens, an empty
4
- public barrel, Linaria extraction and a project preview compiler adapter. It has
5
- no components, patterns, icons, fonts or example screens. The minimal showcase
3
+ This private React/TypeScript workspace contains semantic CSS tokens, a project-owned
4
+ token review pattern, a public barrel, Linaria extraction and a preview compiler
5
+ adapter. It has no product components, icons, fonts or example screens. The minimal showcase
6
6
  shell and MCP client come from ADS tooling.
7
7
 
8
8
  Read the local [contract](ADS.md) and the
@@ -13,7 +13,7 @@ Read the local [contract](ADS.md) and the
13
13
  Copy the contents of `bootstrap-ds/`, including dotfiles, into a new project.
14
14
  The installed `ads-designer` skill contains the same files in
15
15
  `assets/bootstrap-ds/`. Set the project name in `package.json`. Use Node 22.12 or
16
- newer and ADS 0.3 or later for the shared-resource preview compiler.
16
+ newer and ADS 0.3.1 or later for the shared-resource preview compiler.
17
17
 
18
18
  ```sh
19
19
  npx @reqvire-org/ads init --framework react
@@ -25,7 +25,7 @@ npm run dev:showcase
25
25
  For unreleased tooling, run init using the real local package:
26
26
 
27
27
  ```sh
28
- ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.0.tgz"
28
+ ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.1.tgz"
29
29
  npx --yes --package "$ads_tool_package" ads init --framework react --tool-package "$ads_tool_package"
30
30
  npm install
31
31
  npm run build
@@ -44,7 +44,7 @@ native Preact app without a saved ADS framework, use `ads init --framework preac
44
44
  Init records that choice and generates native hook imports without migrating the
45
45
  app or rewriting its compiler. Subsequent init runs reuse the saved choice.
46
46
  Init adds missing foundation files and connects architectural checks; it does
47
- not configure Linaria or generate component source. Generated `.ds/` files are
47
+ not configure Linaria or generate product component source. Generated `.ds/` files are
48
48
  ignored; original artwork and provenance belong in `assets/brand/`.
49
49
 
50
50
  ## Inspect and add UI
@@ -56,10 +56,12 @@ Its MCP client discovers entries, invokes preview tools and follows notification
56
56
  There are no required TokensPage/ComponentsPage/PatternsPage/CompositionPage
57
57
  files, and no separate project browser app to implement or rebuild.
58
58
 
59
- The existing `tokens/Foundation.scenario.tsx` and colocated fixture inspect all
60
- starter token values. Add/remove fixture names alongside token definitions;
61
- `ads check` rejects missing coverage and invented names. Styled token samples
62
- belong to your public review patterns and mount through the same scenario pipeline.
59
+ The existing `tokens/Foundation.scenario.tsx` and colocated fixture visually demonstrate all
60
+ starter token values. The fixture owns `{ token, property, probe }` bindings;
61
+ the public `TokenPreview` pattern owns their presentation and applies the real CSS
62
+ variables. Add/remove samples alongside token definitions. `ads check` rejects
63
+ missing coverage and invented names; the App verifies the declared CSS bindings
64
+ in the browser. Extend or replace the project-owned pattern as your tokens evolve.
63
65
 
64
66
  Create a component under `design-system/components/`, export it through `@ds`,
65
67
  and colocate `Scenario.tsx` plus `fixture.ts` (or `<Owner>.scenario.tsx` and
@@ -2,4 +2,4 @@
2
2
  import "./styles.css";
3
3
 
4
4
  // Add public component and pattern exports here as they are implemented.
5
- export {};
5
+ export { TokenPreview } from "./patterns/token-preview/TokenPreview";
@@ -0,0 +1,4 @@
1
+ import { TokenPreview } from "@ds";
2
+ import { fixture } from "./fixture";
3
+ export const scenario = { title: fixture.title, covers: ["TokenPreview"] };
4
+ export default function Scenario() { return <TokenPreview {...fixture} />; }
@@ -0,0 +1,31 @@
1
+ import { useLayoutEffect, useRef } from "react";
2
+ import { css, cx } from "@linaria/atomic";
3
+
4
+ export interface TokenSample { token: `--${string}`; property: string; }
5
+ export interface TokenPreviewProps { title: string; samples: readonly TokenSample[]; text: string; }
6
+ const sampleStyle = css`
7
+ display: inline-block;
8
+ position: relative;
9
+ white-space: pre-line;
10
+ &[data-ads-property="animation-duration"] { animation-duration: var(--ux-token-preview-value); }
11
+ &[data-ads-property="animation-timing-function"] { animation-timing-function: var(--ux-token-preview-value); }
12
+ &[data-ads-property="background-color"] { background-color: var(--ux-token-preview-value); }
13
+ &[data-ads-property="border-radius"] { border-radius: var(--ux-token-preview-value); }
14
+ &[data-ads-property="box-shadow"] { box-shadow: var(--ux-token-preview-value); }
15
+ &[data-ads-property="color"] { color: var(--ux-token-preview-value); }
16
+ &[data-ads-property="font-family"] { font-family: var(--ux-token-preview-value); }
17
+ &[data-ads-property="font-size"] { font-size: var(--ux-token-preview-value); }
18
+ &[data-ads-property="font-weight"] { font-weight: var(--ux-token-preview-value); }
19
+ &[data-ads-property="line-height"] { line-height: var(--ux-token-preview-value); }
20
+ &[data-ads-property="width"] { width: var(--ux-token-preview-value); }
21
+ &[data-ads-property="z-index"] { z-index: var(--ux-token-preview-value); }
22
+ `;
23
+ function Sample({ sample, text }: { sample: TokenSample; text: string }) {
24
+ const ref = useRef<HTMLSpanElement>(null);
25
+ useLayoutEffect(() => { ref.current?.style.setProperty("--ux-token-preview-value", `var(${sample.token})`); }, [sample.token]);
26
+ return <span ref={ref} className={cx("ux-token-preview__sample", sampleStyle)} data-ads-token={sample.token} data-ads-property={sample.property}>{text}</span>;
27
+ }
28
+ /** Project-owned review UI. Values always come from the real foundation CSS. */
29
+ export function TokenPreview({ title, samples, text }: TokenPreviewProps) {
30
+ return <section className="ux-token-preview"><h1>{title}</h1>{samples.map(sample => <div key={`${sample.token}:${sample.property}`} className="ux-token-preview__item"><code className="ux-token-preview__name">{sample.token}</code><Sample sample={sample} text={text}/></div>)}</section>;
31
+ }
@@ -0,0 +1,8 @@
1
+ export const fixture = {
2
+ "title": "Token preview",
3
+ "text": "Aa",
4
+ samples: [
5
+ {"token": "--accent", "property": "background-color", "probe": "rgb(31, 97, 163)"},
6
+ {"token": "--space-4", "property": "width", "probe": "13.375px"},
7
+ ]
8
+ } as const;
@@ -1,47 +1,48 @@
1
1
  export const fixture = {
2
2
  "title": "Foundation",
3
- "tokens": [
4
- "--accent",
5
- "--accent-fg",
6
- "--accent-hover",
7
- "--bg-canvas",
8
- "--bg-hover",
9
- "--bg-surface",
10
- "--border-default",
11
- "--border-focus",
12
- "--border-w",
13
- "--dur-fast",
14
- "--dur-normal",
15
- "--ease-standard",
16
- "--focus-offset",
17
- "--focus-w",
18
- "--font-mono",
19
- "--font-sans",
20
- "--leading-normal",
21
- "--leading-tight",
22
- "--radius-lg",
23
- "--radius-md",
24
- "--radius-sm",
25
- "--shadow-raised",
26
- "--shadow-xs",
27
- "--space-0",
28
- "--space-12",
29
- "--space-16",
30
- "--space-2",
31
- "--space-4",
32
- "--space-6",
33
- "--space-8",
34
- "--text-base",
35
- "--text-body",
36
- "--text-inverse",
37
- "--text-lg",
38
- "--text-muted",
39
- "--text-sm",
40
- "--text-strong",
41
- "--text-xl",
42
- "--weight-medium",
43
- "--weight-normal",
44
- "--weight-semibold",
45
- "--z-overlay"
3
+ "text": "Aa",
4
+ samples: [
5
+ {"token": "--accent", "property": "background-color", "probe": "rgb(31, 97, 163)"},
6
+ {"token": "--accent-fg", "property": "background-color", "probe": "rgb(31, 97, 163)"},
7
+ {"token": "--accent-hover", "property": "background-color", "probe": "rgb(31, 97, 163)"},
8
+ {"token": "--bg-canvas", "property": "background-color", "probe": "rgb(31, 97, 163)"},
9
+ {"token": "--bg-hover", "property": "background-color", "probe": "rgb(31, 97, 163)"},
10
+ {"token": "--bg-surface", "property": "background-color", "probe": "rgb(31, 97, 163)"},
11
+ {"token": "--border-default", "property": "background-color", "probe": "rgb(31, 97, 163)"},
12
+ {"token": "--border-focus", "property": "background-color", "probe": "rgb(31, 97, 163)"},
13
+ {"token": "--border-w", "property": "width", "probe": "13.375px"},
14
+ {"token": "--dur-fast", "property": "animation-duration", "probe": "0.375s"},
15
+ {"token": "--dur-normal", "property": "animation-duration", "probe": "0.375s"},
16
+ {"token": "--ease-standard", "property": "animation-timing-function", "probe": "cubic-bezier(.13,.27,.61,.83)"},
17
+ {"token": "--focus-offset", "property": "width", "probe": "13.375px"},
18
+ {"token": "--focus-w", "property": "width", "probe": "13.375px"},
19
+ {"token": "--font-mono", "property": "font-family", "probe": "monospace, serif"},
20
+ {"token": "--font-sans", "property": "font-family", "probe": "monospace, serif"},
21
+ {"token": "--leading-normal", "property": "line-height", "probe": "2.375"},
22
+ {"token": "--leading-tight", "property": "line-height", "probe": "2.375"},
23
+ {"token": "--radius-lg", "property": "border-radius", "probe": "13.375px"},
24
+ {"token": "--radius-md", "property": "border-radius", "probe": "13.375px"},
25
+ {"token": "--radius-sm", "property": "border-radius", "probe": "13.375px"},
26
+ {"token": "--shadow-raised", "property": "box-shadow", "probe": "1px 3px 5px rgb(31, 97, 163)"},
27
+ {"token": "--shadow-xs", "property": "box-shadow", "probe": "1px 3px 5px rgb(31, 97, 163)"},
28
+ {"token": "--space-0", "property": "width", "probe": "13.375px"},
29
+ {"token": "--space-12", "property": "width", "probe": "13.375px"},
30
+ {"token": "--space-16", "property": "width", "probe": "13.375px"},
31
+ {"token": "--space-2", "property": "width", "probe": "13.375px"},
32
+ {"token": "--space-4", "property": "width", "probe": "13.375px"},
33
+ {"token": "--space-6", "property": "width", "probe": "13.375px"},
34
+ {"token": "--space-8", "property": "width", "probe": "13.375px"},
35
+ {"token": "--text-base", "property": "font-size", "probe": "41.375px"},
36
+ {"token": "--text-body", "property": "color", "probe": "rgb(31, 97, 163)"},
37
+ {"token": "--text-inverse", "property": "color", "probe": "rgb(31, 97, 163)"},
38
+ {"token": "--text-lg", "property": "font-size", "probe": "41.375px"},
39
+ {"token": "--text-muted", "property": "color", "probe": "rgb(31, 97, 163)"},
40
+ {"token": "--text-sm", "property": "font-size", "probe": "41.375px"},
41
+ {"token": "--text-strong", "property": "color", "probe": "rgb(31, 97, 163)"},
42
+ {"token": "--text-xl", "property": "font-size", "probe": "41.375px"},
43
+ {"token": "--weight-medium", "property": "font-weight", "probe": "327"},
44
+ {"token": "--weight-normal", "property": "font-weight", "probe": "327"},
45
+ {"token": "--weight-semibold", "property": "font-weight", "probe": "327"},
46
+ {"token": "--z-overlay", "property": "z-index", "probe": "367"},
46
47
  ]
47
48
  } as const;
@@ -1,14 +1,4 @@
1
- import { useEffect, useState } from "react";
1
+ import { TokenPreview } from "@ds";
2
2
  import { fixture } from "./Foundation.fixture";
3
- export const scenario = { title: fixture.title, covers: [], tokens: fixture.tokens };
4
- export default function Scenario() {
5
- const [values, setValues] = useState<Record<string, string>>({});
6
- useEffect(() => {
7
- const read = () => { const style = getComputedStyle(document.documentElement); setValues(Object.fromEntries(fixture.tokens.map(name => [name, style.getPropertyValue(name).trim()]))); };
8
- read();
9
- const observer = new MutationObserver(read);
10
- observer.observe(document.documentElement, {attributes: true, attributeFilter: ["data-theme"]});
11
- return () => observer.disconnect();
12
- }, []);
13
- return <section><h1>{fixture.title}</h1><dl>{fixture.tokens.map(name => <div key={name}><dt><code>{name}</code></dt><dd>{values[name]}</dd></div>)}</dl></section>;
14
- }
3
+ export const scenario = { title: fixture.title, covers: ["TokenPreview"], samples: fixture.samples };
4
+ export default function Scenario() { return <TokenPreview {...fixture} />; }
@@ -1,3 +1,6 @@
1
+ :root { color-scheme: light; }
2
+ :root[data-theme="dark"] { color-scheme: dark; }
3
+
1
4
  *,
2
5
  *::before,
3
6
  *::after {
@@ -5,7 +8,7 @@
5
8
  }
6
9
 
7
10
  body {
8
- margin: var(--space-0);
11
+ margin: 0;
9
12
  background: var(--bg-canvas);
10
13
  color: var(--text-body);
11
14
  font-family: var(--font-sans);
@@ -1,5 +1,5 @@
1
1
  :root {
2
- color-scheme: light;
2
+
3
3
  --bg-canvas: #faf9f6;
4
4
  --bg-surface: #fff;
5
5
  --bg-hover: #f1efea;
@@ -15,7 +15,7 @@
15
15
  }
16
16
 
17
17
  :root[data-theme="dark"] {
18
- color-scheme: dark;
18
+
19
19
  --bg-canvas: #17191e;
20
20
  --bg-surface: #20232a;
21
21
  --bg-hover: #2c3039;
@@ -9,5 +9,15 @@
9
9
  "--watch"
10
10
  ]
11
11
  }
12
+ },
13
+ "boundaries": {
14
+ "styleWrites": [
15
+ {
16
+ "file": "design-system/patterns/token-preview/TokenPreview.tsx",
17
+ "properties": [
18
+ "--ux-token-preview-value"
19
+ ]
20
+ }
21
+ ]
12
22
  }
13
23
  }
@@ -55,7 +55,7 @@ If no published distribution exists, build and pack the tooling checkout with
55
55
  From inside an existing test project:
56
56
 
57
57
  ```sh
58
- ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.0.tgz"
58
+ ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.2.tgz"
59
59
  npx --yes --package "$ads_tool_package" ads --help
60
60
  npx --yes --package "$ads_tool_package" ads init --framework react --tool-package "$ads_tool_package"
61
61
  npm install
@@ -93,7 +93,8 @@ component rules through the project's plugin adapter and `ds.config.json`, then
93
93
  run its actual build. Use `lint-config` directly for custom pipeline integration
94
94
  or debugging, not as a separate routine setup step.
95
95
 
96
- Use ADS 0.3 or later for the shared-resource preview compiler. `mcp` starts stdio
96
+ Use ADS 0.3.2 or later for the closed foundation contract and recoverable
97
+ shared-resource preview compiler. `mcp` starts stdio
97
98
  plus its local website; `showcase` starts the browser-only MCP runtime. Open the existing runtime URL from `ads_status` when
98
99
  connected; otherwise use `npm run dev:showcase` or the installed `ads showcase`.
99
100
  The tool client discovers entries and renders MCP Apps. Init adds the launch
@@ -21,9 +21,15 @@ relevant ranges with `ads_read_file` and send only a Git unified diff through
21
21
  `ads_apply_patch({ unit, patch, dryRun })`. A unit includes its own implementation,
22
22
  scenarios and fixtures; imported peers remain separate. `tokens` is the token
23
23
  foundation unit. Unit discovery and file ownership are distinct from preview IDs.
24
- Include only that owner's required re-exports in the public entry. Use
25
- `dryRun: true` to inspect validation; applying re-runs the gates. Fix rejected
26
- patches in their owner. Shared styles/helpers use `foundation`, root guides use
24
+ Include only that owner's required re-exports in the public entry; preserve
25
+ unrelated statements. Its real re-export may accompany removal of a redundant
26
+ `export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
27
+ entry in `companionFiles`: when creating/deleting a canonical token file such as
28
+ `fonts.css`, include only its required import change there in the same patch.
29
+ Preserve other imports/comments and the canonical order. Use `dryRun: true` to
30
+ inspect validation; applying re-runs the gates. Fix rejected patches in their
31
+ owner. Report unsupported coupled changes instead of bypassing a rejection with
32
+ direct source writes. Shared styles/helpers use `foundation`, root guides use
27
33
  `documentation`, and branding/fonts use their discovered `assets/*` unit.
28
34
  Intentional configuration, rule exceptions, registered guard code and compiler
29
35
  changes use `configuration`; validate the proposed settings and keep mandatory
@@ -266,15 +272,25 @@ entry independently and verify real behavior at narrow/wide sizes in both themes
266
272
  The older `showcase-coverage` policy separately checks application references.
267
273
 
268
274
  Token previews use that same scenario pipeline. Colocate a token scenario and
269
- fixture under the configured token directory. Use static metadata
270
- `{ title: "Typography", covers: ["TokenSamples"], tokens: fixture.tokens }` with
271
- literal const fixture fields; names/sample text are fixture data, values come
272
- from the real foundation CSS. Reuse a public project review pattern for styled
273
- samples. The minimal starter's foundation value scenario can have `covers: []`.
274
- Every declared token needs reachable scenario coverage; adding/removing a token
275
- requires fixture updates. Fix `token-scenario-reference`, `token-scenario-render`
276
- and `token-scenario-coverage` findings. Metadata and unused fixture fields do not
277
- count. Discover exact token IDs with `ads_scenarios({kind:"tokens"})`; mount them
275
+ fixture under the configured token directory. Declare metadata
276
+ `{ title: fixture.title, covers: ["TokenSamples"], samples: fixture.samples }`.
277
+ The renderer name is project-owned; use its real public API. Each literal fixture
278
+ sample declares `{ token, property, probe }`: a real token, the CSS property its
279
+ sample demonstrates, and a valid test value different from that token's current
280
+ value. Pass `samples` into the rendered public review pattern. Names, sample text,
281
+ bindings and probes are fixture data; displayed values come from foundation CSS.
282
+ There is no property catalogue, token-name mapping or probe palette in ADS.
283
+ Every token needs sample coverage; fabricated tokens, missing bindings/probes,
284
+ unused fixtures and value-only lists fail the static gates. `covers: []` is invalid.
285
+ During App rendering, the browser checks sample markers `data-ads-token` and
286
+ `data-ads-property`, validates CSS with its own `CSS.supports`, and temporarily
287
+ probes each token to verify that the declared sample property responds. It restores
288
+ values immediately. Missing, hidden, invalid or hardcoded samples produce a preview
289
+ error instead of a successful review. These browser checks apply to the mounted
290
+ scenario/theme, not every application state or pixel-level design quality.
291
+ Keep styles in the project renderer; do not add inline-style exemptions to scenarios.
292
+ Fix `token-scenario-reference`, `token-scenario-render` and `token-scenario-coverage`
293
+ findings. Metadata and unused fixture fields do not count. Discover exact token IDs with `ads_scenarios({kind:"tokens"})`; mount them
278
294
  with `ads_show_scenario({id})` or `ads_show_tokens({category:id})`. With the shared
279
295
  resource compiler, omitting category opens the first project token scenario.
280
296
  Legacy compilers retain the generic definition inspector. Use `ads_tokens` for
@@ -292,6 +308,25 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
292
308
  foundation CSS rather than assigning shared token values in JavaScript. Keep
293
309
  full-app integration harnesses and workflow coverage in application test support.
294
310
 
311
+ Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
312
+ on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
313
+ three closed roles: root/body typography, canvas and theme defaults; limited native
314
+ normalization; and global focus indicators/reduced-motion rules. Every selector
315
+ branch, property and value must fit its role. Token-backed control skins, layout,
316
+ interactive state rules and owner hooks are rejected even through `:where()`.
317
+ Do not copy an unchecked upstream preflight or turn a component repair into a reset.
318
+ Put skin/state/animation in the Linaria owner, and scenario layout variations in
319
+ the public review pattern's typed API. Browser review still verifies the effects.
320
+
321
+ Invalid metadata and source failures keep the managed compiler alive for repairs.
322
+ Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
323
+ successful output. If the builder exited, fix its command and invoke the preview
324
+ again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
325
+ also reload on the next preview invocation. Reconnect the client when upgrading
326
+ the ADS server package itself. Persistent SSE/notification streams make
327
+ `networkidle` unsuitable: wait for the App's current ready/error state instead.
328
+
329
+
295
330
 
296
331
 
297
332
  Register component/project Oxlint plugins and rules in `ds.config.json`. Use
@@ -55,7 +55,7 @@ If no published distribution exists, build and pack the tooling checkout with
55
55
  From inside an existing test project:
56
56
 
57
57
  ```sh
58
- ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.0.tgz"
58
+ ads_tool_package="/absolute/path/to/reqvire-org-ads-0.3.2.tgz"
59
59
  npx --yes --package "$ads_tool_package" ads --help
60
60
  npx --yes --package "$ads_tool_package" ads init --framework react --tool-package "$ads_tool_package"
61
61
  npm install
@@ -93,7 +93,8 @@ component rules through the project's plugin adapter and `ds.config.json`, then
93
93
  run its actual build. Use `lint-config` directly for custom pipeline integration
94
94
  or debugging, not as a separate routine setup step.
95
95
 
96
- Use ADS 0.3 or later for the shared-resource preview compiler. `mcp` starts stdio
96
+ Use ADS 0.3.2 or later for the closed foundation contract and recoverable
97
+ shared-resource preview compiler. `mcp` starts stdio
97
98
  plus its local website; `showcase` starts the browser-only MCP runtime. Open the existing runtime URL from `ads_status` when
98
99
  connected; otherwise use `npm run dev:showcase` or the installed `ads showcase`.
99
100
  The tool client discovers entries and renders MCP Apps. Init adds the launch