@reqvire-org/ads 0.3.1 → 0.3.3
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/dist/bootstrap-ds/ADS.md +29 -0
- package/dist/bootstrap-ds/design-system/tokens/base.css +4 -1
- package/dist/bootstrap-ds/design-system/tokens/colors.css +2 -2
- package/dist/boundaries.mjs +21 -23
- package/dist/check.mjs +45 -15
- package/dist/cli.mjs +1 -0
- package/dist/contracts/foundation.json +211 -0
- package/dist/foundation.mjs +114 -0
- package/dist/mcp/build-status.mjs +22 -9
- package/dist/mcp/mutations.mjs +1 -1
- package/dist/mcp/preview-watch.mjs +35 -12
- package/dist/mcp/prompts.mjs +1 -1
- package/dist/mcp/server.mjs +6 -6
- package/dist/oxlint.mjs +1 -1
- package/dist/scenarios-compiler.mjs +86 -43
- package/dist/skills/ads-assimilate/SKILL.md +43 -2
- package/dist/skills/ads-assimilate/references/cli.md +3 -2
- package/dist/skills/ads-assimilate/references/native-implementation.md +16 -0
- package/dist/skills/ads-break-ui/SKILL.md +43 -2
- package/dist/skills/ads-designer/SKILL.md +43 -2
- package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +29 -0
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/base.css +4 -1
- package/dist/skills/ads-designer/assets/bootstrap-ds/design-system/tokens/colors.css +2 -2
- package/dist/skills/ads-designer/references/cli.md +3 -2
- package/dist/skills/ads-import/SKILL.md +43 -2
- package/dist/skills/ads-import/references/cli.md +3 -2
- package/dist/skills/ads-motion/SKILL.md +43 -2
- package/dist/style-boundaries.mjs +59 -0
- package/dist/units.mjs +37 -1
- package/docs/ADS.md +34 -1
- package/docs/ARCHITECTURE.md +38 -6
- package/docs/CHANGELOG.md +28 -0
- package/docs/GUIDE.md +18 -1
- package/docs/MCP.md +48 -7
- package/package.json +2 -1
|
@@ -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.
|
|
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.
|
|
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
|
|
@@ -55,6 +55,22 @@ target framework. With the default root ADS layout:
|
|
|
55
55
|
dimensions, positions, or transforms. Document and constrain the exception in
|
|
56
56
|
the shared architecture guard; never broaden it to arbitrary visual styles.
|
|
57
57
|
|
|
58
|
+
Preserve the reference's required capabilities while assigning each concern to
|
|
59
|
+
its owner. Demo utilities for container size, border or framing become a public
|
|
60
|
+
review/layout pattern around the real component. Add component props for a
|
|
61
|
+
deliberate runtime API requirement; missing demo layout alone is not justification.
|
|
62
|
+
For imperative geometry, register exact `styleWrites` properties. After migrating
|
|
63
|
+
from JSX inline geometry, change source and its own config companion together:
|
|
64
|
+
remove the obsolete `inlineStyleFiles` exception and register only properties the
|
|
65
|
+
implementation actually writes. Verify the final component with that boundary.
|
|
66
|
+
|
|
67
|
+
Keep presentational building blocks independent of an unnecessary form controller
|
|
68
|
+
or other state engine. Scenario adapters may own demo state and validation. When
|
|
69
|
+
a reusable controller is part of the intended product API, define and test its
|
|
70
|
+
actual contract; a similar method shape alone does not establish compatibility
|
|
71
|
+
with the reference library. Keep state updaters pure and verify submit, focus,
|
|
72
|
+
validation, reset and asynchronous behavior that the API promises.
|
|
73
|
+
|
|
58
74
|
Use current repository conventions in another target rather than assuming the
|
|
59
75
|
same framework, directory structure, or lint tooling.
|
|
60
76
|
|
|
@@ -30,7 +30,11 @@ unrelated statements. Its real re-export may accompany removal of a redundant
|
|
|
30
30
|
`export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
|
|
31
31
|
entry in `companionFiles`: when creating/deleting a canonical token file such as
|
|
32
32
|
`fonts.css`, include only its required import change there in the same patch.
|
|
33
|
-
Preserve other imports/comments and the canonical order.
|
|
33
|
+
Preserve other imports/comments and the canonical order. Runtime owner manifests
|
|
34
|
+
also list a `ds.config.json` companion: change only that owner's `inlineStyleFiles`
|
|
35
|
+
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
36
|
+
fail the core checks; do not pre-register a boundary without its implementation.
|
|
37
|
+
Use `dryRun: true` to
|
|
34
38
|
inspect validation; applying re-runs the gates. Fix rejected patches in their
|
|
35
39
|
owner. Report unsupported coupled changes instead of bypassing a rejection with
|
|
36
40
|
direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
@@ -193,6 +197,15 @@ source definitions and values; inspecting definitions does not prove UI parity.
|
|
|
193
197
|
The tool keeps the shared naming contract; sample templates and their token
|
|
194
198
|
lists belong to the project.
|
|
195
199
|
|
|
200
|
+
A public review pattern may be covered by real token or composition scenarios;
|
|
201
|
+
it needs no redundant standalone entry. Remove an optional scenario only while
|
|
202
|
+
retaining reachable render coverage. Keep directory ownership anchored by its
|
|
203
|
+
runtime entry (`index` or a file matching the directory name) or colocated fixture.
|
|
204
|
+
Import colocated image/font fixtures so MCP serves them through asset resources.
|
|
205
|
+
For a broken-image case, use a local failing fixture, rather than an external
|
|
206
|
+
network failure or a domain-specific CSP exception. Production asset APIs remain
|
|
207
|
+
unrestricted by this fixture guidance.
|
|
208
|
+
|
|
196
209
|
Scenarios, colocated fixtures and helpers are development-only. Never export them
|
|
197
210
|
from the runtime barrel or import them in production, including through aliases,
|
|
198
211
|
re-exports or dynamic imports. They may not import application stores, routers,
|
|
@@ -203,6 +216,27 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
|
|
|
203
216
|
foundation CSS rather than assigning shared token values in JavaScript. Keep
|
|
204
217
|
full-app integration harnesses and workflow coverage in application test support.
|
|
205
218
|
|
|
219
|
+
Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
|
|
220
|
+
on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
|
|
221
|
+
three closed roles: root/body typography, canvas and theme defaults; limited native
|
|
222
|
+
normalization; and global focus indicators/reduced-motion rules. Every selector
|
|
223
|
+
branch, property and value must fit its role. Token-backed control skins, layout,
|
|
224
|
+
interactive state rules and owner hooks are rejected even through `:where()`.
|
|
225
|
+
Do not copy an unchecked upstream preflight or turn a component repair into a reset.
|
|
226
|
+
Keep behavior and skin in their runtime owner. Put demo-only sizing and framing
|
|
227
|
+
in a public review/layout pattern; add component props for a deliberate runtime
|
|
228
|
+
API need. Preserve required capabilities while following ownership rules.
|
|
229
|
+
Browser review still verifies the effects.
|
|
230
|
+
|
|
231
|
+
Invalid metadata and source failures keep the managed compiler alive for repairs.
|
|
232
|
+
Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
|
|
233
|
+
successful output. If the builder exited, fix its command and invoke the preview
|
|
234
|
+
again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
|
|
235
|
+
also reload on the next preview invocation. Reconnect the client when upgrading
|
|
236
|
+
the ADS server package itself. Persistent SSE/notification streams make
|
|
237
|
+
`networkidle` unsuitable: wait for the App's current ready/error state instead.
|
|
238
|
+
|
|
239
|
+
|
|
206
240
|
|
|
207
241
|
|
|
208
242
|
Register component/project Oxlint plugins and rules in `ds.config.json`. Use
|
|
@@ -210,7 +244,14 @@ scoped `oxlint.overrides` for justified file-specific settings; never edit
|
|
|
210
244
|
`.ds/oxlintrc.json`. These overrides configure Oxlint, not the independent
|
|
211
245
|
architecture checks in `ads check`. Measured renderer properties and documented
|
|
212
246
|
non-state hooks use explicit `boundaries`; shared token writes and primitive
|
|
213
|
-
state overrides cannot be allowlisted.
|
|
247
|
+
state overrides cannot be allowlisted. When migrating JSX inline geometry to
|
|
248
|
+
imperative writes, port the source and replace its own boundary entries together
|
|
249
|
+
in the owner's patch. Remove obsolete `inlineStyleFiles` entries and unused
|
|
250
|
+
`styleWrites` properties; do not broaden permissions to keep a migration passing.
|
|
251
|
+
Pointer-capture advisories call for review of cancellation, capture loss and
|
|
252
|
+
teardown, including cleanup delegated to hooks. Verify actual cleanup in a browser;
|
|
253
|
+
a locally present handler alone does not prove correctness.
|
|
254
|
+
Add generic architectural protections to
|
|
214
255
|
ADS core and keep domain/component-specific rules registered in project setup.
|
|
215
256
|
|
|
216
257
|
Read [references/verification.md](references/verification.md) for viewport,
|
|
@@ -62,7 +62,11 @@ unrelated statements. Its real re-export may accompany removal of a redundant
|
|
|
62
62
|
`export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
|
|
63
63
|
entry in `companionFiles`: when creating/deleting a canonical token file such as
|
|
64
64
|
`fonts.css`, include only its required import change there in the same patch.
|
|
65
|
-
Preserve other imports/comments and the canonical order.
|
|
65
|
+
Preserve other imports/comments and the canonical order. Runtime owner manifests
|
|
66
|
+
also list a `ds.config.json` companion: change only that owner's `inlineStyleFiles`
|
|
67
|
+
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
68
|
+
fail the core checks; do not pre-register a boundary without its implementation.
|
|
69
|
+
Use `dryRun: true` to
|
|
66
70
|
inspect validation; applying re-runs the gates. Fix rejected patches in their
|
|
67
71
|
owner. Report unsupported coupled changes instead of bypassing a rejection with
|
|
68
72
|
direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
@@ -331,6 +335,15 @@ source definitions and values; inspecting definitions does not prove UI parity.
|
|
|
331
335
|
The tool keeps the shared naming contract; sample templates and their token
|
|
332
336
|
lists belong to the project.
|
|
333
337
|
|
|
338
|
+
A public review pattern may be covered by real token or composition scenarios;
|
|
339
|
+
it needs no redundant standalone entry. Remove an optional scenario only while
|
|
340
|
+
retaining reachable render coverage. Keep directory ownership anchored by its
|
|
341
|
+
runtime entry (`index` or a file matching the directory name) or colocated fixture.
|
|
342
|
+
Import colocated image/font fixtures so MCP serves them through asset resources.
|
|
343
|
+
For a broken-image case, use a local failing fixture, rather than an external
|
|
344
|
+
network failure or a domain-specific CSP exception. Production asset APIs remain
|
|
345
|
+
unrestricted by this fixture guidance.
|
|
346
|
+
|
|
334
347
|
Scenarios, colocated fixtures and helpers are development-only. Never export them
|
|
335
348
|
from the runtime barrel or import them in production, including through aliases,
|
|
336
349
|
re-exports or dynamic imports. They may not import application stores, routers,
|
|
@@ -341,6 +354,27 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
|
|
|
341
354
|
foundation CSS rather than assigning shared token values in JavaScript. Keep
|
|
342
355
|
full-app integration harnesses and workflow coverage in application test support.
|
|
343
356
|
|
|
357
|
+
Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
|
|
358
|
+
on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
|
|
359
|
+
three closed roles: root/body typography, canvas and theme defaults; limited native
|
|
360
|
+
normalization; and global focus indicators/reduced-motion rules. Every selector
|
|
361
|
+
branch, property and value must fit its role. Token-backed control skins, layout,
|
|
362
|
+
interactive state rules and owner hooks are rejected even through `:where()`.
|
|
363
|
+
Do not copy an unchecked upstream preflight or turn a component repair into a reset.
|
|
364
|
+
Keep behavior and skin in their runtime owner. Put demo-only sizing and framing
|
|
365
|
+
in a public review/layout pattern; add component props for a deliberate runtime
|
|
366
|
+
API need. Preserve required capabilities while following ownership rules.
|
|
367
|
+
Browser review still verifies the effects.
|
|
368
|
+
|
|
369
|
+
Invalid metadata and source failures keep the managed compiler alive for repairs.
|
|
370
|
+
Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
|
|
371
|
+
successful output. If the builder exited, fix its command and invoke the preview
|
|
372
|
+
again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
|
|
373
|
+
also reload on the next preview invocation. Reconnect the client when upgrading
|
|
374
|
+
the ADS server package itself. Persistent SSE/notification streams make
|
|
375
|
+
`networkidle` unsuitable: wait for the App's current ready/error state instead.
|
|
376
|
+
|
|
377
|
+
|
|
344
378
|
|
|
345
379
|
|
|
346
380
|
Register component/project Oxlint plugins and rules in `ds.config.json`. Use
|
|
@@ -348,7 +382,14 @@ scoped `oxlint.overrides` for justified file-specific settings; never edit
|
|
|
348
382
|
`.ds/oxlintrc.json`. These overrides configure Oxlint, not the independent
|
|
349
383
|
architecture checks in `ads check`. Measured renderer properties and documented
|
|
350
384
|
non-state hooks use explicit `boundaries`; shared token writes and primitive
|
|
351
|
-
state overrides cannot be allowlisted.
|
|
385
|
+
state overrides cannot be allowlisted. When migrating JSX inline geometry to
|
|
386
|
+
imperative writes, port the source and replace its own boundary entries together
|
|
387
|
+
in the owner's patch. Remove obsolete `inlineStyleFiles` entries and unused
|
|
388
|
+
`styleWrites` properties; do not broaden permissions to keep a migration passing.
|
|
389
|
+
Pointer-capture advisories call for review of cancellation, capture loss and
|
|
390
|
+
teardown, including cleanup delegated to hooks. Verify actual cleanup in a browser;
|
|
391
|
+
a locally present handler alone does not prove correctness.
|
|
392
|
+
Add generic architectural protections to
|
|
352
393
|
ADS core and keep domain/component-specific rules registered in project setup.
|
|
353
394
|
|
|
354
395
|
Examples and composition scenarios must consume the same public components, patterns,
|
|
@@ -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`.
|
|
@@ -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:
|
|
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
|
-
|
|
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
|
-
|
|
18
|
+
|
|
19
19
|
--bg-canvas: #17191e;
|
|
20
20
|
--bg-surface: #20232a;
|
|
21
21
|
--bg-hover: #2c3039;
|
|
@@ -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.
|
|
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.
|
|
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
|
|
@@ -26,7 +26,11 @@ unrelated statements. Its real re-export may accompany removal of a redundant
|
|
|
26
26
|
`export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
|
|
27
27
|
entry in `companionFiles`: when creating/deleting a canonical token file such as
|
|
28
28
|
`fonts.css`, include only its required import change there in the same patch.
|
|
29
|
-
Preserve other imports/comments and the canonical order.
|
|
29
|
+
Preserve other imports/comments and the canonical order. Runtime owner manifests
|
|
30
|
+
also list a `ds.config.json` companion: change only that owner's `inlineStyleFiles`
|
|
31
|
+
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
32
|
+
fail the core checks; do not pre-register a boundary without its implementation.
|
|
33
|
+
Use `dryRun: true` to
|
|
30
34
|
inspect validation; applying re-runs the gates. Fix rejected patches in their
|
|
31
35
|
owner. Report unsupported coupled changes instead of bypassing a rejection with
|
|
32
36
|
direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
@@ -298,6 +302,15 @@ source definitions and values; inspecting definitions does not prove UI parity.
|
|
|
298
302
|
The tool keeps the shared naming contract; sample templates and their token
|
|
299
303
|
lists belong to the project.
|
|
300
304
|
|
|
305
|
+
A public review pattern may be covered by real token or composition scenarios;
|
|
306
|
+
it needs no redundant standalone entry. Remove an optional scenario only while
|
|
307
|
+
retaining reachable render coverage. Keep directory ownership anchored by its
|
|
308
|
+
runtime entry (`index` or a file matching the directory name) or colocated fixture.
|
|
309
|
+
Import colocated image/font fixtures so MCP serves them through asset resources.
|
|
310
|
+
For a broken-image case, use a local failing fixture, rather than an external
|
|
311
|
+
network failure or a domain-specific CSP exception. Production asset APIs remain
|
|
312
|
+
unrestricted by this fixture guidance.
|
|
313
|
+
|
|
301
314
|
Scenarios, colocated fixtures and helpers are development-only. Never export them
|
|
302
315
|
from the runtime barrel or import them in production, including through aliases,
|
|
303
316
|
re-exports or dynamic imports. They may not import application stores, routers,
|
|
@@ -308,6 +321,27 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
|
|
|
308
321
|
foundation CSS rather than assigning shared token values in JavaScript. Keep
|
|
309
322
|
full-app integration harnesses and workflow coverage in application test support.
|
|
310
323
|
|
|
324
|
+
Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
|
|
325
|
+
on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
|
|
326
|
+
three closed roles: root/body typography, canvas and theme defaults; limited native
|
|
327
|
+
normalization; and global focus indicators/reduced-motion rules. Every selector
|
|
328
|
+
branch, property and value must fit its role. Token-backed control skins, layout,
|
|
329
|
+
interactive state rules and owner hooks are rejected even through `:where()`.
|
|
330
|
+
Do not copy an unchecked upstream preflight or turn a component repair into a reset.
|
|
331
|
+
Keep behavior and skin in their runtime owner. Put demo-only sizing and framing
|
|
332
|
+
in a public review/layout pattern; add component props for a deliberate runtime
|
|
333
|
+
API need. Preserve required capabilities while following ownership rules.
|
|
334
|
+
Browser review still verifies the effects.
|
|
335
|
+
|
|
336
|
+
Invalid metadata and source failures keep the managed compiler alive for repairs.
|
|
337
|
+
Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
|
|
338
|
+
successful output. If the builder exited, fix its command and invoke the preview
|
|
339
|
+
again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
|
|
340
|
+
also reload on the next preview invocation. Reconnect the client when upgrading
|
|
341
|
+
the ADS server package itself. Persistent SSE/notification streams make
|
|
342
|
+
`networkidle` unsuitable: wait for the App's current ready/error state instead.
|
|
343
|
+
|
|
344
|
+
|
|
311
345
|
|
|
312
346
|
|
|
313
347
|
Register component/project Oxlint plugins and rules in `ds.config.json`. Use
|
|
@@ -315,7 +349,14 @@ scoped `oxlint.overrides` for justified file-specific settings; never edit
|
|
|
315
349
|
`.ds/oxlintrc.json`. These overrides configure Oxlint, not the independent
|
|
316
350
|
architecture checks in `ads check`. Measured renderer properties and documented
|
|
317
351
|
non-state hooks use explicit `boundaries`; shared token writes and primitive
|
|
318
|
-
state overrides cannot be allowlisted.
|
|
352
|
+
state overrides cannot be allowlisted. When migrating JSX inline geometry to
|
|
353
|
+
imperative writes, port the source and replace its own boundary entries together
|
|
354
|
+
in the owner's patch. Remove obsolete `inlineStyleFiles` entries and unused
|
|
355
|
+
`styleWrites` properties; do not broaden permissions to keep a migration passing.
|
|
356
|
+
Pointer-capture advisories call for review of cancellation, capture loss and
|
|
357
|
+
teardown, including cleanup delegated to hooks. Verify actual cleanup in a browser;
|
|
358
|
+
a locally present handler alone does not prove correctness.
|
|
359
|
+
Add generic architectural protections to
|
|
319
360
|
ADS core and keep domain/component-specific rules registered in project setup.
|
|
320
361
|
|
|
321
362
|
Write or update the imported item's local README with public usage, required
|
|
@@ -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.
|
|
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.
|
|
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
|
|
@@ -47,7 +47,11 @@ unrelated statements. Its real re-export may accompany removal of a redundant
|
|
|
47
47
|
`export {};` placeholder; do not add empty exports. A `tokens` manifest lists the foundation
|
|
48
48
|
entry in `companionFiles`: when creating/deleting a canonical token file such as
|
|
49
49
|
`fonts.css`, include only its required import change there in the same patch.
|
|
50
|
-
Preserve other imports/comments and the canonical order.
|
|
50
|
+
Preserve other imports/comments and the canonical order. Runtime owner manifests
|
|
51
|
+
also list a `ds.config.json` companion: change only that owner's `inlineStyleFiles`
|
|
52
|
+
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
53
|
+
fail the core checks; do not pre-register a boundary without its implementation.
|
|
54
|
+
Use `dryRun: true` to
|
|
51
55
|
inspect validation; applying re-runs the gates. Fix rejected patches in their
|
|
52
56
|
owner. Report unsupported coupled changes instead of bypassing a rejection with
|
|
53
57
|
direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
@@ -188,6 +192,15 @@ source definitions and values; inspecting definitions does not prove UI parity.
|
|
|
188
192
|
The tool keeps the shared naming contract; sample templates and their token
|
|
189
193
|
lists belong to the project.
|
|
190
194
|
|
|
195
|
+
A public review pattern may be covered by real token or composition scenarios;
|
|
196
|
+
it needs no redundant standalone entry. Remove an optional scenario only while
|
|
197
|
+
retaining reachable render coverage. Keep directory ownership anchored by its
|
|
198
|
+
runtime entry (`index` or a file matching the directory name) or colocated fixture.
|
|
199
|
+
Import colocated image/font fixtures so MCP serves them through asset resources.
|
|
200
|
+
For a broken-image case, use a local failing fixture, rather than an external
|
|
201
|
+
network failure or a domain-specific CSP exception. Production asset APIs remain
|
|
202
|
+
unrestricted by this fixture guidance.
|
|
203
|
+
|
|
191
204
|
Scenarios, colocated fixtures and helpers are development-only. Never export them
|
|
192
205
|
from the runtime barrel or import them in production, including through aliases,
|
|
193
206
|
re-exports or dynamic imports. They may not import application stores, routers,
|
|
@@ -198,6 +211,27 @@ Use local simulated services in fixtures. Tests may import fixtures; load real
|
|
|
198
211
|
foundation CSS rather than assigning shared token values in JavaScript. Keep
|
|
199
212
|
full-app integration harnesses and workflow coverage in application test support.
|
|
200
213
|
|
|
214
|
+
Foundation CSS is checked, not an escape hatch. Value sheets define shared tokens
|
|
215
|
+
on the document root/themes; `fonts.css` holds font-face metadata. `base.css` has
|
|
216
|
+
three closed roles: root/body typography, canvas and theme defaults; limited native
|
|
217
|
+
normalization; and global focus indicators/reduced-motion rules. Every selector
|
|
218
|
+
branch, property and value must fit its role. Token-backed control skins, layout,
|
|
219
|
+
interactive state rules and owner hooks are rejected even through `:where()`.
|
|
220
|
+
Do not copy an unchecked upstream preflight or turn a component repair into a reset.
|
|
221
|
+
Keep behavior and skin in their runtime owner. Put demo-only sizing and framing
|
|
222
|
+
in a public review/layout pattern; add component props for a deliberate runtime
|
|
223
|
+
API need. Preserve required capabilities while following ownership rules.
|
|
224
|
+
Browser review still verifies the effects.
|
|
225
|
+
|
|
226
|
+
Invalid metadata and source failures keep the managed compiler alive for repairs.
|
|
227
|
+
Read `ads_status.build` or `ads://project/build`, fix the owner, then wait for current
|
|
228
|
+
successful output. If the builder exited, fix its command and invoke the preview
|
|
229
|
+
again; ADS starts one fresh child without an MCP reconnect. Compiler-code changes
|
|
230
|
+
also reload on the next preview invocation. Reconnect the client when upgrading
|
|
231
|
+
the ADS server package itself. Persistent SSE/notification streams make
|
|
232
|
+
`networkidle` unsuitable: wait for the App's current ready/error state instead.
|
|
233
|
+
|
|
234
|
+
|
|
201
235
|
|
|
202
236
|
|
|
203
237
|
Register component/project Oxlint plugins and rules in `ds.config.json`. Use
|
|
@@ -205,7 +239,14 @@ scoped `oxlint.overrides` for justified file-specific settings; never edit
|
|
|
205
239
|
`.ds/oxlintrc.json`. These overrides configure Oxlint, not the independent
|
|
206
240
|
architecture checks in `ads check`. Measured renderer properties and documented
|
|
207
241
|
non-state hooks use explicit `boundaries`; shared token writes and primitive
|
|
208
|
-
state overrides cannot be allowlisted.
|
|
242
|
+
state overrides cannot be allowlisted. When migrating JSX inline geometry to
|
|
243
|
+
imperative writes, port the source and replace its own boundary entries together
|
|
244
|
+
in the owner's patch. Remove obsolete `inlineStyleFiles` entries and unused
|
|
245
|
+
`styleWrites` properties; do not broaden permissions to keep a migration passing.
|
|
246
|
+
Pointer-capture advisories call for review of cancellation, capture loss and
|
|
247
|
+
teardown, including cleanup delegated to hooks. Verify actual cleanup in a browser;
|
|
248
|
+
a locally present handler alone does not prove correctness.
|
|
249
|
+
Add generic architectural protections to
|
|
209
250
|
ADS core and keep domain/component-specific rules registered in project setup.
|
|
210
251
|
|
|
211
252
|
- Motion constants belong in the project's token layer. Shared token meanings
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import ts from "typescript";
|
|
3
|
+
import { isUiCssProperties, styleAccessProperty } from "./boundaries.mjs";
|
|
4
|
+
import { uiOperation } from "./ui-framework.mjs";
|
|
5
|
+
|
|
6
|
+
const nameOf = node => node && (ts.isIdentifier(node) || ts.isStringLiteralLike(node)) ? node.text : null;
|
|
7
|
+
|
|
8
|
+
/** Audit explicit permissions without inferring project-specific style APIs. */
|
|
9
|
+
export function inspectStyleBoundaries({ root, config }, program, report) {
|
|
10
|
+
const checker = program.getTypeChecker(), usage = new Map();
|
|
11
|
+
function inspect(file) {
|
|
12
|
+
if (usage.has(file)) return usage.get(file);
|
|
13
|
+
const result = { inline: false, writes: new Set() }, source = program.getSourceFile(file);
|
|
14
|
+
function visit(node) {
|
|
15
|
+
if ((ts.isJsxAttribute(node) && nameOf(node.name) === "style") || isUiCssProperties(node, checker)) result.inline = true;
|
|
16
|
+
if (ts.isCallExpression(node) && uiOperation(node.expression, checker) === "createElement") {
|
|
17
|
+
const props = node.arguments[1];
|
|
18
|
+
if (props && ts.isObjectLiteralExpression(props) && props.properties.some(property => nameOf(property.name) === "style")) result.inline = true;
|
|
19
|
+
}
|
|
20
|
+
const property = styleAccessProperty(node);
|
|
21
|
+
if (typeof property === "string") result.writes.add(property);
|
|
22
|
+
ts.forEachChild(node, visit);
|
|
23
|
+
}
|
|
24
|
+
if (source) visit(source);
|
|
25
|
+
usage.set(file, result);
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
const configFile = path.join(root, "ds.config.json");
|
|
29
|
+
for (const file of config.inlineStyleFiles) {
|
|
30
|
+
if (!inspect(path.resolve(root, file)).inline) report(configFile, "stale-style-boundary", `inlineStyleFiles entry ${file} has no JSX/factory style or UI CSSProperties use. Remove the unused permission; migrate source and its own boundary entries together in the owner's patch.`);
|
|
31
|
+
}
|
|
32
|
+
for (const { file, properties } of config.boundaries.styleWrites) {
|
|
33
|
+
const used = inspect(path.resolve(root, file)).writes;
|
|
34
|
+
for (const property of properties) if (!used.has(property)) report(configFile, "stale-style-boundary", `styleWrites entry ${file} never writes ${property}. Remove the unused property in the owner's source/boundary patch.`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** A local review signal, never proof that delegated cleanup is absent/correct. */
|
|
39
|
+
export function pointerCaptureAdvisories(source) {
|
|
40
|
+
const captures = [], cleanup = [];
|
|
41
|
+
function hasHandler(node) {
|
|
42
|
+
while (node && (ts.isJsxExpression(node) || ts.isParenthesizedExpression(node) || ts.isAsExpression(node) || ts.isNonNullExpression(node))) node = node.expression;
|
|
43
|
+
return !!node && ![ts.SyntaxKind.NullKeyword, ts.SyntaxKind.FalseKeyword].includes(node.kind) && !(ts.isIdentifier(node) && node.text === "undefined");
|
|
44
|
+
}
|
|
45
|
+
function visit(node) {
|
|
46
|
+
if (ts.isCallExpression(node) && ts.isPropertyAccessExpression(node.expression)) {
|
|
47
|
+
if (node.expression.name.text === "setPointerCapture") captures.push(node);
|
|
48
|
+
if (node.expression.name.text === "addEventListener" && node.arguments[0] && ts.isStringLiteralLike(node.arguments[0]) && node.arguments[0].text === "lostpointercapture" && hasHandler(node.arguments[1])) cleanup.push(node);
|
|
49
|
+
}
|
|
50
|
+
if ((ts.isJsxAttribute(node) || ts.isPropertyAssignment(node) || ts.isMethodDeclaration(node)) && /^(?:onLostPointerCapture(?:Capture)?|onlostpointercapture)$/.test(nameOf(node.name) ?? "") && (ts.isMethodDeclaration(node) || hasHandler(node.initializer))) cleanup.push(node);
|
|
51
|
+
if (ts.isBinaryExpression(node) && node.operatorToken.kind === ts.SyntaxKind.EqualsToken && ts.isPropertyAccessExpression(node.left) && node.left.name.text === "onlostpointercapture" && hasHandler(node.right)) cleanup.push(node);
|
|
52
|
+
ts.forEachChild(node, visit);
|
|
53
|
+
}
|
|
54
|
+
visit(source);
|
|
55
|
+
return cleanup.length ? [] : captures.map(node => {
|
|
56
|
+
const position = source.getLineAndCharacterOfPosition(node.getStart(source));
|
|
57
|
+
return { rule: "pointer-capture-review", line: position.line + 1, column: position.character + 1, message: "Pointer capture has no locally visible lostpointercapture cleanup handler. Verify cancellation and capture-loss cleanup, including any delegated hook/helper. This advisory does not prove cleanup is missing or correct." };
|
|
58
|
+
});
|
|
59
|
+
}
|
package/dist/units.mjs
CHANGED
|
@@ -84,7 +84,19 @@ export function inspectUnits(options) {
|
|
|
84
84
|
}
|
|
85
85
|
walk(dsRoot);
|
|
86
86
|
files.sort();
|
|
87
|
-
|
|
87
|
+
// Runtime entry conventions keep directory ownership stable when an optional
|
|
88
|
+
// preview is removed. A flat scenario family still denotes separate owners.
|
|
89
|
+
const sameName = name => name.replace(/[-_]/g, "").toLowerCase();
|
|
90
|
+
const flatFamilies = new Set(files.filter(file => /\.scenario\.[cm]?[jt]sx?$/.test(file)).map(file => path.posix.dirname(file)));
|
|
91
|
+
const directories = new Set(files.filter(file => /(?:^|\/)Scenario\.[cm]?[jt]sx?$/.test(file)).map(file => slash(path.dirname(file))));
|
|
92
|
+
for (const file of files) {
|
|
93
|
+
if (!/^(?:components|patterns|composition)\//.test(file) || !source.test(file)) continue;
|
|
94
|
+
const directory = slash(path.dirname(file)), name = path.basename(file).replace(source, "");
|
|
95
|
+
if (!directory.includes("/") || /\.(?:scenario|fixture|scenario-adapter)$/.test(name)) continue;
|
|
96
|
+
if (flatFamilies.has(directory)) continue;
|
|
97
|
+
if (name === "index" || sameName(name) === sameName(path.posix.basename(directory)) || name === "fixture") directories.add(directory);
|
|
98
|
+
}
|
|
99
|
+
const directoryUnits = [...directories].sort((a, b) => b.length - a.length);
|
|
88
100
|
const flatUnits = [...new Set(files.filter(file => /^(?:components|patterns|composition)\//.test(file) && source.test(file) && !directoryUnits.some(directory => file.startsWith(directory + "/"))).map(file => {
|
|
89
101
|
const base = path.basename(file).split(".")[0];
|
|
90
102
|
return slash(path.join(path.dirname(file), base));
|
|
@@ -120,10 +132,15 @@ export function inspectUnits(options) {
|
|
|
120
132
|
const file = slash(path.relative(root, path.join(dsRoot, relative)));
|
|
121
133
|
if (!units.get(id).files.includes(file)) units.get(id).files.push(file);
|
|
122
134
|
}
|
|
135
|
+
for (const unit of units.values()) if (boundaryCompanion(unit.id)) {
|
|
136
|
+
(unit.companionFiles ??= []).push({ path: "ds.config.json", allowedChanges: "Only this owner's inlineStyleFiles and boundaries.styleWrites entries, together with its source change; preserve all other configuration and peer permissions." });
|
|
137
|
+
}
|
|
123
138
|
return { units: [...units.values()].sort((a, b) => a.id.localeCompare(b.id)), owner, publicEntry, stylesEntry, tokenDir,
|
|
124
139
|
relative: file => slash(path.relative(dsRoot, path.resolve(root, file))) };
|
|
125
140
|
}
|
|
126
141
|
|
|
142
|
+
function boundaryCompanion(unit) { return !["configuration", "documentation", "assets"].includes(unit.split("/")[0]); }
|
|
143
|
+
|
|
127
144
|
export function validateUnitId(unit) {
|
|
128
145
|
if (typeof unit !== "string" || unit.length > 256 || !/^[A-Za-z0-9_-]+(?:\/[A-Za-z0-9_-]+)*$/.test(unit) || ["components", "patterns", "composition"].includes(unit)) throw fail("Select one ADS unit ID from ads_units or an unoccupied owner path following its colocation convention.");
|
|
129
146
|
}
|
|
@@ -134,6 +151,7 @@ export function checkUnitFiles(options, unit, changes, inventory = inspectUnits(
|
|
|
134
151
|
for (const change of changes) {
|
|
135
152
|
const relative = inventory.relative(change.path);
|
|
136
153
|
if (allowNew && unit === "configuration") continue; // The candidate must register every setup/extension file.
|
|
154
|
+
if (change.path === "ds.config.json" && boundaryCompanion(unit)) continue; // Validated against only this owner below.
|
|
137
155
|
if (relative === inventory.publicEntry) continue;
|
|
138
156
|
if (unit === "tokens" && relative === inventory.stylesEntry) continue; // Controlled foundation import bookkeeping.
|
|
139
157
|
if (allowNew && change.originalContent === null && (relative.startsWith(unit + "/") || relative.startsWith(unit + "."))) continue;
|
|
@@ -153,6 +171,24 @@ export function checkUnitCandidate(afterOptions, unit, changes, before) {
|
|
|
153
171
|
if (unit === "configuration" && (entry.id === "configuration" || after.owner(relative) === "configuration")) continue;
|
|
154
172
|
if (after.owner(relative) !== entry.id) throw fail("A patch cannot change ownership of existing peer units. Choose an unoccupied owner path.", file);
|
|
155
173
|
}
|
|
174
|
+
const boundaryChange = changes.find(change => change.path === "ds.config.json");
|
|
175
|
+
if (boundaryChange && unit !== "configuration") {
|
|
176
|
+
if (!boundaryCompanion(unit) || typeof boundaryChange.originalContent !== "string" || typeof boundaryChange.content !== "string") throw fail("This unit cannot create/delete configuration.", boundaryChange.path);
|
|
177
|
+
if (!changes.some(change => change.path !== boundaryChange.path && (before.owner(before.relative(change.path)) === unit || after.owner(after.relative(change.path)) === unit))) throw fail("Boundary companions require a source change in the selected owner.", boundaryChange.path);
|
|
178
|
+
function peerPolicy(content, inventory) {
|
|
179
|
+
const config = JSON.parse(content);
|
|
180
|
+
const owns = file => typeof file === "string" && inventory.owner(inventory.relative(file)) === unit;
|
|
181
|
+
config.inlineStyleFiles = (config.inlineStyleFiles ?? []).filter(file => !owns(file));
|
|
182
|
+
config.boundaries = { ...config.boundaries, styleWrites: (config.boundaries?.styleWrites ?? []).filter(entry => !owns(entry.file)) };
|
|
183
|
+
return config;
|
|
184
|
+
}
|
|
185
|
+
function canonical(value) {
|
|
186
|
+
if (Array.isArray(value)) return value.map(canonical);
|
|
187
|
+
if (value && typeof value === "object") return Object.fromEntries(Object.keys(value).sort().map(key => [key, canonical(value[key])]));
|
|
188
|
+
return value;
|
|
189
|
+
}
|
|
190
|
+
if (JSON.stringify(canonical(peerPolicy(boundaryChange.originalContent, before))) !== JSON.stringify(canonical(peerPolicy(boundaryChange.content, after)))) throw fail("Boundary companion patches may change only inlineStyleFiles and styleWrites entries owned by the selected unit; preserve all other configuration and peer permissions.", boundaryChange.path);
|
|
191
|
+
}
|
|
156
192
|
const foundationChange = changes.find(change => before.relative(change.path) === before.stylesEntry);
|
|
157
193
|
if (unit === "tokens" && foundationChange) {
|
|
158
194
|
const { originalContent: current, content: proposed } = foundationChange;
|
package/docs/ADS.md
CHANGED
|
@@ -169,6 +169,35 @@ custom styling in fixture files. The ADS frame pattern uses `--ux-*`. Foreign br
|
|
|
169
169
|
CSS imports the approved token files in order; shared assignments belong in
|
|
170
170
|
those token files, never in consumer styles or component state overrides.
|
|
171
171
|
|
|
172
|
+
Foundation roles are enforced by `foundation-role`, `foundation-selector` and
|
|
173
|
+
`foundation-import`, alongside the regular token checks. Shared definitions
|
|
174
|
+
belong on the document root or explicit root themes; ordinary declarations belong
|
|
175
|
+
in `base.css`, and font-face descriptors in optional `fonts.css`. The entry imports
|
|
176
|
+
canonical sheets; those sheets cannot import another styling layer. Component
|
|
177
|
+
classes, IDs, data/ARIA hooks, contextual selectors, keyframes and scoped UI rules
|
|
178
|
+
are rejected in the foundation, including nested functional selectors. Raw visual
|
|
179
|
+
values and undefined token references are checked in native defaults too; literal
|
|
180
|
+
font-face metadata keeps its separate asset role.
|
|
181
|
+
|
|
182
|
+
`base.css` has three closed roles:
|
|
183
|
+
|
|
184
|
+
- Document defaults: root/body typography, canvas colors and theme behavior,
|
|
185
|
+
global text selection and document scrollbars.
|
|
186
|
+
- Native resets: permitted normalization properties and values, such as zero
|
|
187
|
+
spacing, inherited control typography, list resets and responsive replaced media.
|
|
188
|
+
- Global accessibility: universal `:focus-visible` outline rules, and reduced-motion
|
|
189
|
+
overrides inside `@media (prefers-reduced-motion: reduce)`.
|
|
190
|
+
|
|
191
|
+
The `foundation-role` check validates every selector branch, property and value.
|
|
192
|
+
Native selectors are not a bypass: token-backed button backgrounds, flex/grid
|
|
193
|
+
layout, component-specific focus rules and hover/disabled skins are rejected.
|
|
194
|
+
Shared token definitions belong in value sheets, not `base.css`. No project token
|
|
195
|
+
names are embedded in this policy. A zero-specificity `:where()` wrapper does not
|
|
196
|
+
change ownership. Put component design and animation in Linaria owners, and
|
|
197
|
+
scenario layout variations in typed public review-pattern props. Browser review
|
|
198
|
+
still checks the effects and accessibility of permitted defaults.
|
|
199
|
+
|
|
200
|
+
|
|
172
201
|
Store original branding and its usage, credits, and licenses in
|
|
173
202
|
`assets/brand/`, and fonts in `assets/fonts/`. Configure generated icons and
|
|
174
203
|
asset mounts as described in the [branding guide](GUIDE.md#branding).
|
|
@@ -262,10 +291,14 @@ The checks enforce the architecture's ownership boundaries:
|
|
|
262
291
|
| Tokens and styles | Fixed token vocabulary, required definitions, declared value types and references, raw visual values, shared-token assignments, foundation import order, and component/pattern namespaces |
|
|
263
292
|
| Public API and dependencies | Consumers use public ADS imports; ADS implementations and showcase do not import application source; runtime code does not import showcase fixtures |
|
|
264
293
|
| Interaction policy | Primitive state variables stay inside components; non-state customization hooks require explicit registration |
|
|
265
|
-
| Renderer exceptions | Inline
|
|
294
|
+
| Renderer exceptions | Inline styles and imperative writes require used, narrow configured boundaries; stale entries fail; public props omit inherited style and reject open-ended visual strings |
|
|
266
295
|
| Preview ownership | Scenarios define no CSS, custom classes, or native controls; all declared tokens and public renderable UI have reachable registered scenarios; token references must exist; legacy catalogue pages are checked when present |
|
|
267
296
|
| Assets | Source/public collisions and configured generated artifacts in source are rejected |
|
|
268
297
|
|
|
298
|
+
Pointer capture without locally visible capture-loss cleanup produces a
|
|
299
|
+
nonblocking advisory. Review delegated cleanup and browser behavior; neither a
|
|
300
|
+
warning nor a handler's presence establishes lifecycle correctness.
|
|
301
|
+
|
|
269
302
|
Document a new ownership exception with its guard/configuration change and
|
|
270
303
|
tests. Passing static checks establishes only the policies and source formats
|
|
271
304
|
they cover. Browser review and behavior tests still verify accessibility,
|