@reqvire-org/ads 0.3.18 → 0.3.21
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/README.md +2 -0
- package/dist/behaviors.mjs +19 -9
- package/dist/bootstrap-ds/ADS.md +2 -2
- package/dist/bootstrap-ds/README.md +2 -2
- package/dist/bootstrap-ds/design-system/index.ts +0 -1
- package/dist/bootstrap-ds/design-system/review/index.ts +1 -0
- package/dist/bootstrap-ds/design-system/tokens/{Foundation.scenario.tsx → Foundation.ads.scenario.tsx} +2 -2
- package/dist/bootstrap-ds/ds.config.json +1 -1
- package/dist/bootstrap-ds/tsconfig.build.json +9 -2
- package/dist/bootstrap-ds/tsconfig.json +18 -3
- package/dist/bootstrap-ds/vite.config.ts +1 -1
- package/dist/boundaries.mjs +6 -2
- package/dist/check.mjs +44 -17
- package/dist/config.mjs +33 -5
- package/dist/contract-migration.mjs +110 -0
- package/dist/contracts.d.mts +22 -0
- package/dist/evidence.mjs +1 -1
- package/dist/index.mjs +1 -0
- package/dist/init.mjs +18 -15
- package/dist/layers.mjs +288 -0
- package/dist/lint-config.mjs +1 -1
- package/dist/mcp/catalog.mjs +9 -2
- package/dist/mcp/context.mjs +2 -1
- package/dist/mcp/edit-preparation.mjs +9 -6
- package/dist/mcp/mutations.mjs +1 -1
- package/dist/mcp/preview-widget.bundle.js +41 -39
- package/dist/mcp/prompts.mjs +1 -1
- package/dist/mcp/server.mjs +9 -3
- package/dist/mcp/widget.bundle.js +1 -1
- package/dist/oxlint.mjs +3 -1
- package/dist/paint-contracts.mjs +124 -0
- package/dist/preview-resources.mjs +12 -2
- package/dist/public-api.mjs +13 -6
- package/dist/public-props.mjs +2 -2
- package/dist/runtime-contracts.mjs +225 -0
- package/dist/scenario-trace.mjs +37 -9
- package/dist/scenarios-vite.mjs +3 -2
- package/dist/scenarios.mjs +89 -30
- package/dist/scoped-tokens.mjs +9 -4
- package/dist/showcase/client.bundle.js +1 -1
- package/dist/showcase/sandbox.bundle.js +1 -1
- package/dist/skills/ads-break-ui/SKILL.md +25 -6
- package/dist/skills/ads-break-ui/references/contracts.md +250 -0
- package/dist/skills/ads-break-ui/references/guarded-editing.md +1 -1
- package/dist/skills/ads-break-ui/references/layers.md +123 -0
- package/dist/skills/ads-break-ui/references/review.md +96 -0
- package/dist/skills/ads-break-ui/references/scenarios.md +24 -3
- package/dist/skills/ads-designer/SKILL.md +26 -7
- package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +2 -2
- package/dist/skills/ads-designer/assets/bootstrap-ds/README.md +2 -2
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/index.ts +0 -1
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/review/index.ts +1 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/{Foundation.scenario.tsx → Foundation.ads.scenario.tsx} +2 -2
- package/dist/skills/ads-designer/assets/bootstrap-ds/ds.config.json +1 -1
- package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.build.json +9 -2
- package/dist/skills/ads-designer/assets/bootstrap-ds/tsconfig.json +18 -3
- package/dist/skills/ads-designer/assets/bootstrap-ds/vite.config.ts +1 -1
- package/dist/skills/ads-designer/references/contracts.md +250 -0
- package/dist/skills/ads-designer/references/guarded-editing.md +1 -1
- package/dist/skills/ads-designer/references/layers.md +123 -0
- package/dist/skills/ads-designer/references/review.md +96 -0
- package/dist/skills/ads-designer/references/scenarios.md +24 -3
- package/dist/skills/ads-import/SKILL.md +25 -6
- package/dist/skills/ads-import/references/contracts.md +250 -0
- package/dist/skills/ads-import/references/guarded-editing.md +1 -1
- package/dist/skills/ads-import/references/layers.md +123 -0
- package/dist/skills/ads-import/references/review.md +96 -0
- package/dist/skills/ads-import/references/scenarios.md +24 -3
- package/dist/skills/ads-migrate/SKILL.md +25 -6
- package/dist/skills/ads-migrate/references/contracts.md +250 -0
- package/dist/skills/ads-migrate/references/guarded-editing.md +1 -1
- package/dist/skills/ads-migrate/references/layers.md +123 -0
- package/dist/skills/ads-migrate/references/review.md +96 -0
- package/dist/skills/ads-migrate/references/scenarios.md +24 -3
- package/dist/skills/ads-motion/SKILL.md +26 -7
- package/dist/skills/ads-motion/references/audit.md +1 -1
- package/dist/skills/ads-motion/references/contracts.md +250 -0
- package/dist/skills/ads-motion/references/guarded-editing.md +1 -1
- package/dist/skills/ads-motion/references/layers.md +123 -0
- package/dist/skills/ads-motion/references/motion-review.md +35 -0
- package/dist/skills/ads-motion/references/review.md +96 -35
- package/dist/skills/ads-motion/references/scenarios.md +24 -3
- package/dist/token-origins.mjs +24 -0
- package/dist/tokens.mjs +4 -3
- package/dist/unit-contracts.mjs +203 -0
- package/dist/units.mjs +26 -17
- package/dist/verification/browser.mjs +156 -26
- package/dist/verification/playwright-reporter.cjs +13 -3
- package/docs/ADS.md +40 -6
- package/docs/ARCHITECTURE.md +73 -4
- package/docs/BEHAVIORS.md +15 -0
- package/docs/CHANGELOG.md +42 -0
- package/docs/CONTRACTS.md +250 -0
- package/docs/GUIDE.md +29 -3
- package/docs/MCP.md +42 -6
- package/package.json +4 -1
- package/dist/bootstrap-ds/design-system/patterns/token-preview/Scenario.tsx +0 -4
- package/dist/bootstrap-ds/design-system/patterns/token-preview/fixture.ts +0 -8
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/token-preview/Scenario.tsx +0 -4
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/patterns/token-preview/fixture.ts +0 -8
- /package/dist/bootstrap-ds/design-system/{patterns → review}/token-preview/TokenPreview.tsx +0 -0
- /package/dist/bootstrap-ds/design-system/tokens/{Foundation.fixture.ts → Foundation.ads.fixture.ts} +0 -0
- /package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/{patterns → review}/token-preview/TokenPreview.tsx +0 -0
- /package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/{Foundation.fixture.ts → Foundation.ads.fixture.ts} +0 -0
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# Development-only review UI
|
|
2
|
+
|
|
3
|
+
Read this when creating or migrating demo frames, preview sizing helpers, token
|
|
4
|
+
renderers or demonstration controls. MCP serves it as `ads://guides/review`.
|
|
5
|
+
|
|
6
|
+
## Responsibilities and boundaries
|
|
7
|
+
|
|
8
|
+
Components provide cohesive production capabilities. Patterns provide reusable
|
|
9
|
+
application structures/workflows. Both receive variable application data and
|
|
10
|
+
callbacks through their APIs. Their scenarios import the same implementation
|
|
11
|
+
used by the application and supply fixtures; do not create a second implementation
|
|
12
|
+
that only looks correct in the showcase.
|
|
13
|
+
|
|
14
|
+
`design-system/review/` owns development-only presentation: example frames,
|
|
15
|
+
arrangement, demonstration controls, token sample renderers and their styles.
|
|
16
|
+
It remains project-owned. The MCP host shell stays generic; review code executes
|
|
17
|
+
inside the preview App with the project's framework, foundation, fonts and styles.
|
|
18
|
+
Nothing depends on particular helper names or an imported component library.
|
|
19
|
+
|
|
20
|
+
The development entry defaults to `review/index.ts` relative to `dsDir`; configure
|
|
21
|
+
`reviewEntry` for another script inside `review/`. Its import alias is the
|
|
22
|
+
configured `publicAlias` plus `/review`, normally `@ds/review`. Discover the actual
|
|
23
|
+
entry/alias through `ads_status.project.review`. Export helpers there, never from
|
|
24
|
+
the production public barrel. Review implementations, types and styles must not
|
|
25
|
+
enter application, component, pattern or controller dependencies. Tests, fixtures,
|
|
26
|
+
scenarios and preview mounts can consume review code.
|
|
27
|
+
|
|
28
|
+
Review helpers can own Linaria presentation, local state and demo controls. Normal
|
|
29
|
+
style-token, variable ownership, measured-style-write and application separation
|
|
30
|
+
gates still apply. They consume deliberate public component/pattern/controller
|
|
31
|
+
contracts and may reuse local foundation helpers. They cannot target private
|
|
32
|
+
component styles or replace real product behavior. Keep one-off fixture data in
|
|
33
|
+
the scenario; a helper need not become a product API to frame an example.
|
|
34
|
+
|
|
35
|
+
## Scenario and token contracts
|
|
36
|
+
|
|
37
|
+
```tsx
|
|
38
|
+
import { Panel } from "@ds";
|
|
39
|
+
import { ReviewFrame } from "@ds/review";
|
|
40
|
+
import { fixture } from "./Panel.fixture";
|
|
41
|
+
|
|
42
|
+
export const scenario = { title: "Panel", covers: ["Panel"] };
|
|
43
|
+
export default function Scenario() {
|
|
44
|
+
return <ReviewFrame><Panel {...fixture} /></ReviewFrame>;
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The names above are illustrative. `covers` names the production subjects actually
|
|
49
|
+
demonstrated, not every review wrapper. A review export has no product catalogue
|
|
50
|
+
entry and needs no standalone catalogue scenario. Keep review unit tests/specs
|
|
51
|
+
beside their owner; optional behavior contracts can verify review guarantees
|
|
52
|
+
through an existing real scenario. They establish no production coverage.
|
|
53
|
+
|
|
54
|
+
A token scenario may name its real review renderer in `covers`, import it from
|
|
55
|
+
the development entry, declare `samples: fixture.samples`, and pass those samples
|
|
56
|
+
into the renderer. Existing real product patterns may also serve as token UI.
|
|
57
|
+
Empty covers, unused samples, fabricated tokens and plain value lists remain
|
|
58
|
+
invalid. The rendered App must still pass token-binding checks. See
|
|
59
|
+
[scenarios.md](scenarios.md) for the full token/render contract.
|
|
60
|
+
|
|
61
|
+
Review class helpers can supply source-proven Linaria classes to a scenario.
|
|
62
|
+
Arbitrary scenario classes/styles remain forbidden. A review wrapper's own native
|
|
63
|
+
controls do not authorize arbitrary native controls in its consuming scenario;
|
|
64
|
+
slot/selector exceptions still need actual production-owner evidence. Keep
|
|
65
|
+
production and review export names distinct where `covers` would be ambiguous.
|
|
66
|
+
|
|
67
|
+
## Build and guarded edits
|
|
68
|
+
|
|
69
|
+
The normal preview plugin registers the exact review alias before broader product
|
|
70
|
+
aliases. Configure the same alias in project TypeScript and any independent
|
|
71
|
+
preview/dev harness. In an ordered bundler alias map, put `@ds/review` before
|
|
72
|
+
`@ds`; the broad `@ds` mapping must not resolve it as `index.ts/review`.
|
|
73
|
+
Production entrypoints never import the development entry. Inspect the product
|
|
74
|
+
bundle for review modules/CSS; passing static checks does not prove bundle parity.
|
|
75
|
+
|
|
76
|
+
Use `ads_units` for `review/<Owner>` units. Scenarios, local specs and helper files
|
|
77
|
+
follow ordinary flat/directory ownership. A review patch may update only its own
|
|
78
|
+
re-exports in the development entry and its own documented style boundaries.
|
|
79
|
+
Product owners retain the separate production entry companion. Use prepared
|
|
80
|
+
patches/dry runs and coupled transactions as described in
|
|
81
|
+
[guarded-editing.md](guarded-editing.md); do not bypass a rejected mutation.
|
|
82
|
+
|
|
83
|
+
For an existing project, identify helpers by responsibility and actual consumers,
|
|
84
|
+
not names or the number of imported components. Preserve real application patterns.
|
|
85
|
+
Move only demo helpers, their styles and relevant guides to `review/`; update
|
|
86
|
+
scenario/preview imports, style-boundary paths, TypeScript/bundler aliases and
|
|
87
|
+
links. Remove their production exports and obsolete standalone product scenarios.
|
|
88
|
+
Do not copy old example fixtures or export demonstration controls as product UI.
|
|
89
|
+
|
|
90
|
+
Upgrade ADS before migrating a consuming project: older versions do not know the
|
|
91
|
+
separate review entry. For staged guarded edits, first add distinctly named review
|
|
92
|
+
exports, migrate consumers in passing owner patches, then remove the old pattern
|
|
93
|
+
exports/owners once unused. Required coupled changes use a transaction. Check
|
|
94
|
+
source gates, typecheck, preview and production builds, real browser rendering,
|
|
95
|
+
registered behaviors and token bindings. A source move alone establishes none
|
|
96
|
+
of those rendered guarantees.
|
|
@@ -34,10 +34,31 @@ do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
|
34
34
|
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
35
|
their document-loading policy. Verify link activation as well as rendering.
|
|
36
36
|
|
|
37
|
+
## Forms inside Apps
|
|
38
|
+
|
|
39
|
+
Use real form semantics and the runtime owner's intended submit handler. ADS's
|
|
40
|
+
showcase and diagnostic explorer permit `allow-forms` at every iframe layer,
|
|
41
|
+
including legacy widgets. Browser constraint validation, Submit clicks, Enter and
|
|
42
|
+
`requestSubmit()` can reach the normal submit path. Client-side forms call
|
|
43
|
+
`preventDefault()` in their submit handlers; the host does not synthesize clicks
|
|
44
|
+
or submit events. Native action requests are blocked by CSP `form-action 'none'`.
|
|
45
|
+
Submit effects that use tools or resources still follow the MCP bridge.
|
|
46
|
+
|
|
47
|
+
If a click fires but the `submit` handler never runs, inspect the browser's sandbox
|
|
48
|
+
diagnostic and every ancestor iframe's permissions. Distinguish that host problem
|
|
49
|
+
from native constraint validation legitimately preventing submission. Do not add
|
|
50
|
+
scenario click interception to disguise a missing sandbox permission. External
|
|
51
|
+
MCP hosts control their own sandbox/CSP policy.
|
|
52
|
+
|
|
53
|
+
Verify an invalid submit, a valid submit, implicit Enter submission and the promised
|
|
54
|
+
state effects. A working Next button is not evidence that form submission works.
|
|
55
|
+
Keep native action navigation separate from client-side submission behavior;
|
|
56
|
+
`allow-forms` does not grant host DOM access or top-level navigation.
|
|
57
|
+
|
|
37
58
|
## Owner-local token previews load their own definitions
|
|
38
59
|
|
|
39
60
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
40
|
-
A colocated `kind: "tokens"` scenario may render only the
|
|
61
|
+
A colocated `kind: "tokens"` scenario may render only the development-only review renderer
|
|
41
62
|
with its fixture samples. Discovery adds the registered owner sheet to the
|
|
42
63
|
generated record's `stylesheets`; `previewEntriesPlugin` imports those paths
|
|
43
64
|
into the token preview independently of the runtime component. Custom builders
|
|
@@ -91,7 +112,7 @@ These examples describe verification mistakes, not component-specific rules:
|
|
|
91
112
|
|
|
92
113
|
| Situation | Do not | Do instead |
|
|
93
114
|
|-----------|--------|------------|
|
|
94
|
-
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's
|
|
115
|
+
| A reference example sets `width: 15rem`, while the native popup uses its default width. | Remove the reference width and claim the original example now matches. | Keep the baseline intact. Reproduce demo sizing through the project's development-only review helper or supported style helper. If a different native size is intentional, document it. Label any additional normalized comparison separately. |
|
|
95
116
|
| Static tracing cannot prove that a public clear control renders when a value is selected. | Remove its export, drop its required coverage, or change runtime behavior merely to pass the gate. | Preserve the intended public API. Try a meaningful selected-state fixture or another real scenario. If valid rendering remains untraceable, report the tooling limitation with a small reproduction. |
|
|
96
117
|
| A screenshot shows the clear control in a selected state. | Treat its presence as evidence that clearing works. | Add a browser check: start selected, activate Clear, assert the value and selection are empty, verify the control's resulting visibility and documented focus behavior, then select again. |
|
|
97
118
|
|
|
@@ -207,6 +228,6 @@ An `exercises` entry records behavioral use; it never grants styling permission.
|
|
|
207
228
|
Keep helper signatures compatible with the product API. Fix ownership/provenance
|
|
208
229
|
in the runtime owner when genuinely wrong; retain intentional public APIs when
|
|
209
230
|
reporting an unsupported trace. Demo-only sizing, framing and arrangement still
|
|
210
|
-
belong in
|
|
231
|
+
belong in development-only review helpers. A style helper is not permission to
|
|
211
232
|
author a second design in the scenario. For cascade risks and extraction issues,
|
|
212
233
|
read [atomic-styles.md](atomic-styles.md).
|
|
@@ -90,6 +90,19 @@ then page needed `ads_results` sections using the returned result ID. Inspect
|
|
|
90
90
|
one `ads_investigate({unit,check,runId})` summary before changing APIs or policy;
|
|
91
91
|
load request/error/artifact details only when relevant.
|
|
92
92
|
|
|
93
|
+
Review/demo layout belongs in development-only `review/`, exported through the
|
|
94
|
+
separate `${publicAlias}/review` entry (normally `@ds/review`), never the production
|
|
95
|
+
barrel. Product patterns are application UI. For ownership, migration, token
|
|
96
|
+
renderers, build aliases or `review-import` / `review-contract` diagnostics, read
|
|
97
|
+
[development review UI](references/review.md), also served as `ads://guides/review`.
|
|
98
|
+
|
|
99
|
+
A component provides one cohesive UI capability; a pattern arranges capabilities
|
|
100
|
+
into reusable structures or workflows. Components may compose components/controllers;
|
|
101
|
+
layout patterns may arrange slots. Do not classify by component count. For owner
|
|
102
|
+
selection or `component-dependency`, `component-contract` or `component-style`, read
|
|
103
|
+
[layer responsibilities and contracts](references/layers.md), also served as
|
|
104
|
+
`ads://guides/layers`. Preserve public APIs and documented non-state styling hooks.
|
|
105
|
+
|
|
93
106
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
94
107
|
public style-helper use, native slot/selector composition, fragment navigation,
|
|
95
108
|
or `scenario-render` / `showcase-control` / `showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
@@ -148,7 +161,7 @@ checks; do not fetch the unpublished package.
|
|
|
148
161
|
Read [assets/bootstrap-ds/README.md](assets/bootstrap-ds/README.md) and its
|
|
149
162
|
[contract](assets/bootstrap-ds/ADS.md). The scaffold contains semantic token
|
|
150
163
|
defaults, React/TypeScript/Linaria configuration, general lint, a public
|
|
151
|
-
barrel, empty product component directories, a project-owned token review
|
|
164
|
+
barrel, empty product component directories, a project-owned token review renderer, and a project preview compiler adapter. The browser shell is supplied by ADS tooling.
|
|
152
165
|
It contains no components, shell patterns, vendored fonts, or example screens.
|
|
153
166
|
|
|
154
167
|
Resolve assets relative to this skill's `SKILL.md`, including after installation
|
|
@@ -361,7 +374,7 @@ fixture under the configured token directory. Declare metadata
|
|
|
361
374
|
The renderer name is project-owned; use its real public API. Each literal fixture
|
|
362
375
|
sample declares `{ token, property, probe }`: a real token, the CSS property its
|
|
363
376
|
sample demonstrates, and a valid test value different from that token's current
|
|
364
|
-
value. Pass `samples` into the rendered
|
|
377
|
+
value. Pass `samples` into the rendered development-only review renderer. Names, sample text,
|
|
365
378
|
bindings and probes are fixture data; displayed values come from foundation CSS.
|
|
366
379
|
There is no property catalogue, token-name mapping or probe palette in ADS.
|
|
367
380
|
Every token needs sample coverage; fabricated tokens, missing bindings/probes,
|
|
@@ -382,10 +395,12 @@ source definitions and values; inspecting definitions does not prove UI parity.
|
|
|
382
395
|
The tool keeps the shared naming contract; sample templates and their token
|
|
383
396
|
lists belong to the project.
|
|
384
397
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
398
|
+
Development review helpers need no product catalogue scenario. A token scenario
|
|
399
|
+
may name its review renderer in `covers`; ordinary component/pattern scenarios
|
|
400
|
+
cover their production subjects. Keep review exports in the separate review entry.
|
|
401
|
+
Remove redundant helper catalogue scenarios during migration. Product UI retains
|
|
402
|
+
its real render-coverage requirement. Keep directory ownership anchored by its
|
|
403
|
+
implementation entry (`index` or a file matching the directory name) or colocated fixture.
|
|
389
404
|
Import colocated image/font fixtures so MCP serves them through asset resources.
|
|
390
405
|
For a broken-image case, use a local failing fixture, rather than an external
|
|
391
406
|
network failure or a domain-specific CSP exception. Production asset APIs remain
|
|
@@ -409,7 +424,7 @@ branch, property and value must fit its role. Token-backed control skins, layout
|
|
|
409
424
|
interactive state rules and owner hooks are rejected even through `:where()`.
|
|
410
425
|
Do not copy an unchecked upstream preflight or turn a component repair into a reset.
|
|
411
426
|
Keep behavior and skin in their runtime owner. Put demo-only sizing and framing
|
|
412
|
-
in a
|
|
427
|
+
in a development-only review helper; add component props for a deliberate runtime
|
|
413
428
|
API need. Preserve required capabilities while following ownership rules.
|
|
414
429
|
Use tokens for absolute/font-relative lengths, including `ch`, `ex`, `cap`, `ic`
|
|
415
430
|
and `lh`; calculations and fallback values follow the same rule. Structural
|
|
@@ -507,3 +522,7 @@ For visual work, inspect the real project showcase, including keyboard/focus,
|
|
|
507
522
|
relevant pointer/touch behavior, dark theme, and reduced motion as needed.
|
|
508
523
|
A screenshot alone does not prove behavior or animation. Validate public imports,
|
|
509
524
|
CSS/asset resolution, required setup, and local documentation links.
|
|
525
|
+
|
|
526
|
+
For static owner contracts, `.ads.` development roles, typed paint/binding APIs,
|
|
527
|
+
declarative evidence, token privacy and guarded migration, read
|
|
528
|
+
[contracts.md](references/contracts.md) when the task touches those contracts.
|
|
@@ -72,7 +72,7 @@ layout, component-specific focus rules and hover/disabled skins are rejected.
|
|
|
72
72
|
Shared token definitions belong in value sheets, not `base.css`. No project token
|
|
73
73
|
names are embedded in this policy. A zero-specificity `:where()` wrapper does not
|
|
74
74
|
change ownership. Put component design and animation in Linaria owners, and
|
|
75
|
-
scenario layout variations in typed
|
|
75
|
+
scenario layout variations in typed review-helper props. Browser review
|
|
76
76
|
still checks the effects and accessibility of permitted defaults.
|
|
77
77
|
|
|
78
78
|
Own primitive markup, focus, hover, selected, disabled, loading, and motion in
|
|
@@ -151,7 +151,7 @@ Flat owners may use `Button.scenario.tsx` and `Button.fixture.ts` instead.
|
|
|
151
151
|
`export const scenario = { title: "Button states", covers: ["Button"] };`.
|
|
152
152
|
Token entries under the configured token directory declare
|
|
153
153
|
`export const scenario = { title: fixture.title, covers: ["TokenSamples"], samples: fixture.samples };`.
|
|
154
|
-
`TokenSamples` is any project-owned
|
|
154
|
+
`TokenSamples` is any project-owned development-only review renderer, not a required name.
|
|
155
155
|
Its colocated fixture declares literal `samples: [{ token, property, probe }]`.
|
|
156
156
|
Each token must exist and have sample coverage; duplicate bindings, missing probes,
|
|
157
157
|
empty covers and value-only inspectors fail. The default entry passes the declared
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Empty native design system
|
|
2
2
|
|
|
3
3
|
This private React/TypeScript workspace contains semantic CSS tokens, a project-owned
|
|
4
|
-
token review
|
|
4
|
+
token review renderer, a public barrel, Linaria extraction and a preview compiler
|
|
5
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
|
|
|
@@ -56,7 +56,7 @@ 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 visually demonstrate all
|
|
59
|
+
The existing `tokens/Foundation.ads.scenario.tsx` and colocated fixture visually demonstrate all
|
|
60
60
|
starter token values. The fixture owns `{ token, property, probe }` bindings;
|
|
61
61
|
the public `TokenPreview` pattern owns their presentation and applies the real CSS
|
|
62
62
|
variables. Add/remove samples alongside token definitions. `ads check` rejects
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { TokenPreview } from "./token-preview/TokenPreview";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { TokenPreview } from "@ds";
|
|
2
|
-
import { fixture } from "./Foundation.fixture";
|
|
1
|
+
import { TokenPreview } from "@ds/review";
|
|
2
|
+
import { fixture } from "./Foundation.ads.fixture";
|
|
3
3
|
export const scenario = { title: fixture.title, covers: ["TokenPreview"], samples: fixture.samples };
|
|
4
4
|
export default function Scenario() { return <TokenPreview {...fixture} />; }
|
|
@@ -7,6 +7,13 @@
|
|
|
7
7
|
"rootDir": "design-system",
|
|
8
8
|
"outDir": "dist"
|
|
9
9
|
},
|
|
10
|
-
"include": [
|
|
11
|
-
|
|
10
|
+
"include": [
|
|
11
|
+
"design-system/index.ts"
|
|
12
|
+
],
|
|
13
|
+
"exclude": [
|
|
14
|
+
"design-system/showcase",
|
|
15
|
+
"design-system/review",
|
|
16
|
+
"design-system/composition",
|
|
17
|
+
"**/*.ads.*"
|
|
18
|
+
]
|
|
12
19
|
}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"compilerOptions": {
|
|
3
3
|
"target": "ES2022",
|
|
4
|
-
"lib": [
|
|
4
|
+
"lib": [
|
|
5
|
+
"ES2022",
|
|
6
|
+
"DOM",
|
|
7
|
+
"DOM.Iterable"
|
|
8
|
+
],
|
|
5
9
|
"module": "ESNext",
|
|
6
10
|
"moduleResolution": "bundler",
|
|
7
11
|
"skipLibCheck": true,
|
|
@@ -14,7 +18,18 @@
|
|
|
14
18
|
"noUnusedParameters": true,
|
|
15
19
|
"noFallthroughCasesInSwitch": true,
|
|
16
20
|
"baseUrl": ".",
|
|
17
|
-
"paths": {
|
|
21
|
+
"paths": {
|
|
22
|
+
"@ds/review": [
|
|
23
|
+
"design-system/review/index.ts"
|
|
24
|
+
],
|
|
25
|
+
"@ds": [
|
|
26
|
+
"design-system/index.ts"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
18
29
|
},
|
|
19
|
-
"include": [
|
|
30
|
+
"include": [
|
|
31
|
+
"src",
|
|
32
|
+
"design-system",
|
|
33
|
+
"vite.config.ts"
|
|
34
|
+
]
|
|
20
35
|
}
|
|
@@ -7,7 +7,7 @@ import { linariaTagResolver } from "@reqvire-org/ads/linaria";
|
|
|
7
7
|
export default defineConfig({
|
|
8
8
|
plugins: [wyw({ tagResolver: linariaTagResolver }), react()],
|
|
9
9
|
resolve: {
|
|
10
|
-
alias: { "@ds": path.resolve(import.meta.dirname, "design-system/index.ts") },
|
|
10
|
+
alias: { "@ds/review": path.resolve(import.meta.dirname, "design-system/review/index.ts"), "@ds": path.resolve(import.meta.dirname, "design-system/index.ts") },
|
|
11
11
|
},
|
|
12
12
|
build: {
|
|
13
13
|
outDir: "dist",
|
|
@@ -0,0 +1,250 @@
|
|
|
1
|
+
# Static owner contracts and development files
|
|
2
|
+
|
|
3
|
+
Use one optional `<Owner>.ads.contract.ts` for owner-local tokens, constrained
|
|
4
|
+
paint inputs, scoped runtime bindings, declarative parts and behavioral checks.
|
|
5
|
+
The import `import type { UnitContract } from "@reqvire-org/ads/contracts"` supplies
|
|
6
|
+
development typing. ADS reads its AST and resolves real symbols without importing
|
|
7
|
+
or executing project modules. It adds no production runtime.
|
|
8
|
+
|
|
9
|
+
## Files and ownership
|
|
10
|
+
|
|
11
|
+
```text
|
|
12
|
+
components/Plot/
|
|
13
|
+
Plot.tsx production API/root
|
|
14
|
+
Series.tsx production declarative API
|
|
15
|
+
renderer.tsx production consumer
|
|
16
|
+
paints.ts production binding producer
|
|
17
|
+
types.ts production prop types
|
|
18
|
+
tokens.css optional production token definitions
|
|
19
|
+
Plot.ads.contract.ts static tool declaration
|
|
20
|
+
Plot.ads.scenario.tsx demonstration
|
|
21
|
+
Plot.ads.fixture.ts demonstration data
|
|
22
|
+
Tokens.ads.scenario.tsx real owner-token samples
|
|
23
|
+
Tokens.ads.fixture.ts sample bindings/probes
|
|
24
|
+
Plot.ads.behavior.spec.ts registered browser checks
|
|
25
|
+
Plot.ads.test.tsx optional unit tests
|
|
26
|
+
Plot.ads.helpers.ts development-only adapters
|
|
27
|
+
README.md API/provenance
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
This is an example, not a required inventory. Use the same roles for patterns,
|
|
31
|
+
controllers and relevant development owners. `review/` remains a separate
|
|
32
|
+
shared development layer; its implementation filenames need no extra marker.
|
|
33
|
+
Runtime components, types and styles cannot import `.ads.` files, tests, fixtures
|
|
34
|
+
or review code through aliases, barrels or helpers. Unknown `.ads.` roles are
|
|
35
|
+
still development-only and are diagnosed. Fixtures/helpers cannot define styles;
|
|
36
|
+
put demo framing in review. Ordinary README/license files retain their names.
|
|
37
|
+
|
|
38
|
+
Scenarios/fixtures/review enter only the selected preview closure. Contracts are
|
|
39
|
+
never executable preview modules; derived audit descriptors are data. Specs run
|
|
40
|
+
only in the configured test runner. Production declaration emission must also
|
|
41
|
+
start from the public runtime entry, rather than include every file under the
|
|
42
|
+
design-system folder. The starter’s `tsconfig.build.json` does this; its normal
|
|
43
|
+
no-emit typecheck still checks development sources. Core import guards protect
|
|
44
|
+
the runtime dependency closure. Review custom emitter configurations through
|
|
45
|
+
the configuration owner before migrating a consuming project. Guards remain tooling. Production prop types
|
|
46
|
+
belong in runtime files, never inferred from a development contract.
|
|
47
|
+
|
|
48
|
+
## A contract uses actual implementation references
|
|
49
|
+
|
|
50
|
+
```ts
|
|
51
|
+
import type { UnitContract } from "@reqvire-org/ads/contracts";
|
|
52
|
+
import { Plot } from "./Plot";
|
|
53
|
+
import { Series } from "./Series";
|
|
54
|
+
import { Renderer } from "./renderer";
|
|
55
|
+
import { paints } from "./paints";
|
|
56
|
+
|
|
57
|
+
export default {
|
|
58
|
+
schemaVersion: 1,
|
|
59
|
+
tokens: { namespace: "--plot-", stylesheet: "./tokens.css" },
|
|
60
|
+
paintInputs: [
|
|
61
|
+
{ api: Plot, property: "config.*.paint", kind: "paint-reference" },
|
|
62
|
+
{ api: Series, property: "fill", kind: "paint-reference", bindings: ["items"] },
|
|
63
|
+
],
|
|
64
|
+
bindings: {
|
|
65
|
+
items: {
|
|
66
|
+
input: { api: Plot, property: "config" },
|
|
67
|
+
producer: paints,
|
|
68
|
+
valueFrom: "paint",
|
|
69
|
+
variable: "--plot-runtime-${key}",
|
|
70
|
+
scope: { api: Plot, selector: '[data-plot-root=""]' },
|
|
71
|
+
checks: ["isolation"],
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
declarativeParts: [
|
|
75
|
+
{ api: Series, parent: Plot, consumer: Renderer, checks: ["isolation"] },
|
|
76
|
+
],
|
|
77
|
+
behavior: {
|
|
78
|
+
subjects: { plot: { api: Plot }, renderer: { implementation: Renderer } },
|
|
79
|
+
guarantees: [{
|
|
80
|
+
id: "scoped-output",
|
|
81
|
+
description: "Changing either instance updates only its own output.",
|
|
82
|
+
subjects: ["plot", "renderer"], checks: ["isolation"],
|
|
83
|
+
}],
|
|
84
|
+
checks: {
|
|
85
|
+
isolation: {
|
|
86
|
+
file: "./Plot.ads.behavior.spec.ts", case: "isolation",
|
|
87
|
+
scenario: "components/Plot", profile: "widget",
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
} satisfies UnitContract;
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Keep contracts small; most owners need none or one section. Supported data are
|
|
95
|
+
literal objects/arrays, static constants/spreads, `as const` and `satisfies`.
|
|
96
|
+
Symbol references resolve through normal imports, aliases and re-exports.
|
|
97
|
+
Calls, getters, methods, computed metadata and environment-dependent expressions
|
|
98
|
+
are rejected. Function references are opaque identities, never executed.
|
|
99
|
+
Private implementation subjects may be internal module exports without becoming
|
|
100
|
+
public barrel exports. Producers/consumers must belong to the same owner. Required
|
|
101
|
+
checks must exist, back named guarantees and use a browser profile with the
|
|
102
|
+
corresponding scenario. A relationship is registration, not a passing guarantee.
|
|
103
|
+
|
|
104
|
+
## Typed paints and runtime bindings
|
|
105
|
+
|
|
106
|
+
Production-facing types can use:
|
|
107
|
+
|
|
108
|
+
```ts
|
|
109
|
+
export type Paint = `var(--${string})` | `url(#${string})` | "none" | "currentColor";
|
|
110
|
+
export interface SeriesProps { fill?: Paint }
|
|
111
|
+
export type Config = Readonly<Record<string, { paint: Paint }>>;
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
ADS follows the actual property path/type, including nested maps. A name such as
|
|
115
|
+
`Paint`, an arbitrary `string`, `any` or a forged metadata role grants no waiver.
|
|
116
|
+
Supported references are a single accessible token/binding `var(--name)`, a local
|
|
117
|
+
SVG paint `url(#id)`, `none` or `currentColor`. Fallbacks, raw colours, external
|
|
118
|
+
URLs and arbitrary CSS are outside this role. Raw domain colours need a separately
|
|
119
|
+
reviewed validated input boundary; they are not implicitly supported here.
|
|
120
|
+
|
|
121
|
+
A runtime family is instance data, not an infinite design-token inventory. Its
|
|
122
|
+
source proof requires the declared config map, exact key/value mapping and actual
|
|
123
|
+
root attachment. Supported producers use `Object.entries(config)` with a loop,
|
|
124
|
+
or `Object.fromEntries(...map(...))`; same-owner helper returns are traceable.
|
|
125
|
+
Guard each key before the write/return using
|
|
126
|
+
`if (!/^[A-Za-z0-9_-]+$/.test(key)) throw new Error("Invalid key")` (a loop may
|
|
127
|
+
`continue`). Return only the computed map. For example:
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
export function paints(config: Config) {
|
|
131
|
+
const result: Record<string, string> = {};
|
|
132
|
+
for (const [key, entry] of Object.entries(config)) {
|
|
133
|
+
if (!/^[A-Za-z0-9_-]+$/.test(key)) throw new Error("Invalid key");
|
|
134
|
+
result[`--plot-runtime-${key}`] = entry.paint;
|
|
135
|
+
}
|
|
136
|
+
return result;
|
|
137
|
+
}
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
The runtime root attaches that returned map using `style={paints(config)}` or a
|
|
141
|
+
traceable local/useMemo result and the declared class/exact data attribute.
|
|
142
|
+
Place spreading props before the explicit scope/style so an unknown spread
|
|
143
|
+
cannot replace them. This grants permission to that binding attachment only;
|
|
144
|
+
it does not authorize arbitrary inline styling, CSSProperties APIs or bulk writes.
|
|
145
|
+
Unsupported dynamic producers/attachment paths fail with an analysis diagnostic.
|
|
146
|
+
Keep the implementation project-owned; there is no required ADS binding helper.
|
|
147
|
+
|
|
148
|
+
Families cannot overlap shared tokens, owner-token namespaces, private runtime
|
|
149
|
+
prefixes or other bindings. A broad family such as `--color-${key}` grants no
|
|
150
|
+
shared-token exception. Use a distinct private family where collision freedom
|
|
151
|
+
cannot be established. Registered paint consumers list their allowed binding IDs;
|
|
152
|
+
borrowing a peer's family or private token remains invalid. Bindings are scoped
|
|
153
|
+
to their actual root; portals outside it need deliberate project integration.
|
|
154
|
+
|
|
155
|
+
The App audit checks current mounted instances, accessible values, local SVG
|
|
156
|
+
resources and computed paint-property responses. Visibility and complete rendered
|
|
157
|
+
output still need assertions in the registered browser checks. It rejects missing/duplicate IDs and reports unobserved written values separately. It is bounded to 100 families, 20 instances per family, 100 keys
|
|
158
|
+
and 1000 elements per instance. Exceeding a budget reports limits and complete: false; it does not invalidate a
|
|
159
|
+
working component. An unobserved paint effect also remains unverified until its
|
|
160
|
+
relevant consumer/state is checked. It does
|
|
161
|
+
not prove every future input, visibility state or interaction. In registered
|
|
162
|
+
Playwright checks, use `auditBehaviorPaints(frame)` from
|
|
163
|
+
`@reqvire-org/ads/verification` after updates. Assert `result.ok` and, when claiming complete current-map
|
|
164
|
+
evidence, `result.complete` and the expected `verified` entries.
|
|
165
|
+
Exercise two instances with identical keys/different paints, key updates/removal,
|
|
166
|
+
themes, local SVG IDs and invalid/inaccessible references. Keep normal runner
|
|
167
|
+
profiles; React StrictMode still needs a project development harness.
|
|
168
|
+
|
|
169
|
+
## Rendered and declarative evidence
|
|
170
|
+
|
|
171
|
+
`covers` names rendered public UI. A null-returning declarative part belongs in
|
|
172
|
+
`exercises`, alongside behavioral APIs:
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
export const scenario = {
|
|
176
|
+
title: "Plot", covers: ["Plot"], exercises: ["Series"],
|
|
177
|
+
};
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
The real part must reach its registered consumer through a rendered parent.
|
|
181
|
+
ADS resolves source identity comparisons (`child.type === Series`, including a
|
|
182
|
+
traceable comparison helper) and reads of that same child’s props traced from the consumer’s children input.
|
|
183
|
+
A comparison against a decoy object gives no evidence. An import, unrelated parent, unused
|
|
184
|
+
child or metadata claim gives no consumption credit. Unknown render branches are
|
|
185
|
+
conservative. Browser checks must verify that adding/removing/changing the part
|
|
186
|
+
changes output. Source relationships and current browser evidence are separate.
|
|
187
|
+
Do not add fake DOM, hide public parts or rewrite a valid API to appease tracing.
|
|
188
|
+
|
|
189
|
+
Scenario metadata is validated by field/entry with positions and reasons.
|
|
190
|
+
A bad entry still blocks acceptance while valid independent render evidence is
|
|
191
|
+
retained. Unreadable prerequisites report coverage as not established. Inspect
|
|
192
|
+
the exact source diagnostic and bounded results; do not assume every subsequent
|
|
193
|
+
missing preview means its runtime API is invalid.
|
|
194
|
+
|
|
195
|
+
## Local tokens and project consistency
|
|
196
|
+
|
|
197
|
+
`tokens.css` remains optional production design data for component/pattern owners,
|
|
198
|
+
imported by the runtime owner. Controllers stay headless; review uses the shared
|
|
199
|
+
vocabulary and its own development presentation state. Only root/theme definitions belong there. Tokens require real sample
|
|
200
|
+
coverage, including independently built owner token scenarios. One namespace
|
|
201
|
+
cannot be shared by peer components. Private references remain private through
|
|
202
|
+
TS constants, re-exports, helper returns, SVG/paint props and property reads/writes.
|
|
203
|
+
Normal composition of a public component using its own tokens remains valid.
|
|
204
|
+
Source analysis covers supported value flows; arbitrary dynamic code is not
|
|
205
|
+
proof of ownership. CSS variables remain browser-visible; namespacing is an
|
|
206
|
+
architecture boundary, not browser encapsulation.
|
|
207
|
+
|
|
208
|
+
Ownership does not establish a project's visual scale:
|
|
209
|
+
|
|
210
|
+
- A component redefining shared `--space-4` fails.
|
|
211
|
+
- Its private `--plot-gap: 7px` can be valid component geometry.
|
|
212
|
+
- `--plot-gap: var(--space-4)` preserves a shared scale with local meaning.
|
|
213
|
+
|
|
214
|
+
Choose project policy explicitly. A registered project check can use tooling-only
|
|
215
|
+
`inspectTokens(root)` and `inspectTokenOrigins(inventory, name, { stopAt: names })`
|
|
216
|
+
from `@reqvire-org/ads`. `aliasOnly` verifies every theme definition follows only
|
|
217
|
+
aliases to the explicitly selected origins; `literals` and `diagnostics` explain
|
|
218
|
+
violations/limits. Select the exact targets and permitted shared origins. Keep
|
|
219
|
+
intentional geometry exceptions exact with documented reasons. ADS neither
|
|
220
|
+
infers spacing meaning from names nor prescribes a global spacing palette.
|
|
221
|
+
|
|
222
|
+
## Migration and MCP editing
|
|
223
|
+
|
|
224
|
+
Legacy `tokens.json`/`<Owner>.tokens.json` and `behavior.json` remain readable.
|
|
225
|
+
Use either authoring form per section; competing declarations fail. New contracts
|
|
226
|
+
normalize into the same discovery, ownership, source revisions, affected-check
|
|
227
|
+
selection and candidate gates. `ads_units` exposes `contractFile`; `ads_catalog`
|
|
228
|
+
reports constrained paint paths and declarative parent/consumer/check references.
|
|
229
|
+
Use bounded file reads and paged detailed results, not repeated whole-project dumps.
|
|
230
|
+
|
|
231
|
+
Install supporting ADS tooling before migrating a consuming project and reconnect
|
|
232
|
+
MCP before replacing a package used by a running server. Then:
|
|
233
|
+
|
|
234
|
+
1. Discover one owner with `ads_units`.
|
|
235
|
+
2. `ads_prepare_patch({ unit, action: "migrate" })` creates a normal local draft.
|
|
236
|
+
3. Review the converted contract, renamed files/imports and migration notes.
|
|
237
|
+
4. `ads_prepare_patch({ unit, action: "diff", draft })` emits its Git patchFile.
|
|
238
|
+
5. Dry-run/apply with `ads_apply_patch`, or a genuinely coupled transaction.
|
|
239
|
+
|
|
240
|
+
Migration never edits live source or bypasses gates. It retains stable scenario
|
|
241
|
+
IDs and check case IDs. An optional static `scenario.id` preserves a legacy
|
|
242
|
+
identity when a renamed filename would otherwise be ambiguous; it must stay
|
|
243
|
+
inside the owning unit and be unique. Whole-file or unimportable private behavior subjects stay
|
|
244
|
+
in legacy registration with a note until deliberately resolved. Unknown runner
|
|
245
|
+
globs, custom adapters and documentation references require review. Ambiguous
|
|
246
|
+
flat-to-directory renames stay in the legacy form with a migration note so file
|
|
247
|
+
ownership cannot silently change. Preserve
|
|
248
|
+
licenses, pending drafts and unrelated work; keep transactions within their limits.
|
|
249
|
+
There is no alternate JSON contract editor. Do not loosen a guard or make a valid
|
|
250
|
+
API private merely to complete a migration.
|
|
@@ -103,7 +103,7 @@ and a definition-only `tokens.css`, imported by its runtime source. Flat owners
|
|
|
103
103
|
shared or --ds-/--ux-/--showcase- variables. Only that owner consumes/defines its
|
|
104
104
|
local tokens; aliases can use shared or own tokens. UI styles stay in Linaria.
|
|
105
105
|
Add a colocated token scenario with `kind:"tokens"`, real fixture `samples` and a
|
|
106
|
-
|
|
106
|
+
development-only review renderer. These inputs belong to the same owner and need real sample
|
|
107
107
|
coverage. Manifests and fixtures stay out of the product bundle.
|
|
108
108
|
|
|
109
109
|
`ads_prepare_token_samples({id, bindings?})` preserves existing project samples,
|