@reqvire-org/ads 0.3.12 → 0.3.14
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 +20 -1
- package/dist/bootstrap-ds/ADS.md +4 -1
- package/dist/capture/worker.mjs +38 -0
- package/dist/capture-store.mjs +123 -0
- package/dist/capture.mjs +117 -0
- package/dist/check.mjs +8 -2
- package/dist/config.mjs +6 -1
- package/dist/mcp/context.mjs +1 -1
- package/dist/mcp/mutations.mjs +25 -5
- package/dist/mcp/server.mjs +62 -15
- package/dist/scenario-slots.mjs +124 -0
- package/dist/scenarios.mjs +9 -3
- package/dist/showcase/client.bundle.js +18 -18
- package/dist/showcase/style.css +2 -0
- package/dist/skills/ads-break-ui/SKILL.md +6 -1
- package/dist/skills/ads-break-ui/references/captures.md +147 -0
- package/dist/skills/ads-break-ui/references/guarded-editing.md +72 -3
- package/dist/skills/ads-break-ui/references/scenarios.md +40 -1
- package/dist/skills/ads-designer/SKILL.md +6 -1
- package/dist/skills/ads-designer/assets/bootstrap-ds/ADS.md +4 -1
- package/dist/skills/ads-designer/references/captures.md +147 -0
- package/dist/skills/ads-designer/references/guarded-editing.md +72 -3
- package/dist/skills/ads-designer/references/scenarios.md +40 -1
- package/dist/skills/ads-import/SKILL.md +6 -1
- package/dist/skills/ads-import/references/captures.md +147 -0
- package/dist/skills/ads-import/references/guarded-editing.md +72 -3
- package/dist/skills/ads-import/references/scenarios.md +40 -1
- package/dist/skills/ads-migrate/SKILL.md +6 -1
- package/dist/skills/ads-migrate/references/captures.md +147 -0
- package/dist/skills/ads-migrate/references/guarded-editing.md +72 -3
- package/dist/skills/ads-migrate/references/scenarios.md +40 -1
- package/dist/skills/ads-motion/SKILL.md +6 -1
- package/dist/skills/ads-motion/references/captures.md +147 -0
- package/dist/skills/ads-motion/references/guarded-editing.md +72 -3
- package/dist/skills/ads-motion/references/scenarios.md +40 -1
- package/dist/source-values.mjs +2 -1
- package/dist/verification/browser.mjs +8 -3
- package/dist/verification/playwright-reporter.cjs +23 -8
- package/dist/verification.mjs +142 -33
- package/docs/ADS.md +10 -2
- package/docs/ARCHITECTURE.md +43 -2
- package/docs/BEHAVIORS.md +66 -7
- package/docs/CHANGELOG.md +27 -0
- package/docs/GUIDE.md +48 -1
- package/docs/MCP.md +54 -1
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Scenario rendering, token previews and public class helpers
|
|
2
2
|
|
|
3
|
-
Use this reference for `scenario-render`, `scenario-coverage` or `showcase-class`
|
|
3
|
+
Use this reference for `scenario-render`, `scenario-coverage`, `showcase-control` or `showcase-class`
|
|
4
4
|
diagnostics. MCP serves the same guide as `ads://guides/scenarios`.
|
|
5
5
|
|
|
6
6
|
All preview kinds open at `?scenario=<discovered-id>`. Use the returned showcase
|
|
@@ -18,6 +18,11 @@ recovers missed atomic replacements. Do not touch source to force freshness;
|
|
|
18
18
|
inspect build diagnostics. Upgrade the project's compiler dependency together
|
|
19
19
|
with MCP when an older reporter lacks source evidence.
|
|
20
20
|
|
|
21
|
+
Optional static `captureTargets` names CSS selectors within the scenario's App for
|
|
22
|
+
on-demand element screenshots. It grants no render/behavior coverage and no extra
|
|
23
|
+
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
|
+
target selection, resource reads and storage lifecycle.
|
|
25
|
+
|
|
21
26
|
## Owner-local token previews load their own definitions
|
|
22
27
|
|
|
23
28
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -85,6 +90,40 @@ do not export the helper solely for a test. Public/private ownership is a produc
|
|
|
85
90
|
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
91
|
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
92
|
|
|
93
|
+
## Native semantics through a public runtime slot
|
|
94
|
+
|
|
95
|
+
A native element can be the direct child of a public runtime component that
|
|
96
|
+
actually clones that child with its own props:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<Action asChild>
|
|
100
|
+
<a href={fixture.destination}>Documentation</a>
|
|
101
|
+
</Action>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`Action` and the fixture are illustrative; use the project's intended public API.
|
|
105
|
+
The runtime owner supplies presentation and interaction; the anchor supplies link
|
|
106
|
+
semantics. Keep this composition when it is the product contract. Do not replace
|
|
107
|
+
the anchor with an unrelated styled link, add a demo-only prop, disable the guard
|
|
108
|
+
or write outside MCP merely to silence a diagnostic.
|
|
109
|
+
|
|
110
|
+
ADS follows the selected runtime render path, the exact child and real imported
|
|
111
|
+
React/Preact `cloneElement` operations, including local slot/prop-merging helpers.
|
|
112
|
+
The prop need not be named `asChild`; the spelling alone grants no permission.
|
|
113
|
+
JSX and recognized framework factories follow the same rule. The native element
|
|
114
|
+
must be the single direct child: another native control nested inside it remains
|
|
115
|
+
subject to the ordinary ownership rule. Passing children through a container,
|
|
116
|
+
a scenario-local wrapper or an opaque component does not establish a slot.
|
|
117
|
+
|
|
118
|
+
This grants no scenario styling permission. Inline styles and arbitrary class
|
|
119
|
+
names remain rejected, including on the slotted child. Public style helpers retain
|
|
120
|
+
their own provenance checks. Unknown branches that could render the native child
|
|
121
|
+
directly, multiple children and untraceable replacement props remain blocked.
|
|
122
|
+
If a valid slot contract cannot be traced, keep the intended API and report a
|
|
123
|
+
small reproduction rather than inventing a product workaround. Static proof
|
|
124
|
+
establishes ownership, not correct prop merging, focus, keyboard or navigation
|
|
125
|
+
behavior; verify those in the built App and registered checks.
|
|
126
|
+
|
|
88
127
|
## Scenarios may consume verified public style helpers
|
|
89
128
|
|
|
90
129
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -31,7 +31,10 @@ also list a `ds.config.json` companion: change only that owner's `inlineStyleFil
|
|
|
31
31
|
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
32
32
|
fail the core checks; do not pre-register a boundary without its implementation.
|
|
33
33
|
Use `dryRun: true` to
|
|
34
|
-
inspect validation
|
|
34
|
+
inspect validation, including affected registered behavior checks on the isolated
|
|
35
|
+
candidate. For a prepared draft, request its diff and dry-run the returned
|
|
36
|
+
`patchFile`; `ads_verify` checks current source and accepts no draft argument.
|
|
37
|
+
Applying re-runs the gates. Fix rejected patches in their
|
|
35
38
|
owner. Use `ads_apply_transaction` for genuinely coupled owner patches;
|
|
36
39
|
never bypass a rejection with direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
37
40
|
`documentation`, and branding/fonts use their discovered `assets/*` unit.
|
|
@@ -43,6 +46,8 @@ stay out of model context. Binary changes require Git. When editing is disabled,
|
|
|
43
46
|
use the client's normal source-editing tools.
|
|
44
47
|
For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
45
48
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
49
|
+
For on-demand current/candidate screenshots and visual dry-run review, read
|
|
50
|
+
[captures.md](references/captures.md).
|
|
46
51
|
|
|
47
52
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
48
53
|
public style-helper use in scenarios, or `scenario-render` / `showcase-class`
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# On-demand visual captures
|
|
2
|
+
|
|
3
|
+
Use captures when reviewing appearance or a proposed visual change. Discover exact
|
|
4
|
+
scenario IDs with `ads_scenarios`; these are project-owned independently mountable
|
|
5
|
+
token, component, pattern and composition views. A component export alone is not
|
|
6
|
+
a renderable fixture. Controllers/hooks need a scenario demonstrating their visible
|
|
7
|
+
effects. ADS never supplies library-specific renderers, fixtures or capture targets.
|
|
8
|
+
|
|
9
|
+
## Capture current source
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
ads_capture({
|
|
13
|
+
scenario: "components/Example",
|
|
14
|
+
theme: "dark",
|
|
15
|
+
viewport: { width: 1280, height: 800 }
|
|
16
|
+
})
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The ID above is illustrative; use one returned by discovery. The default is light
|
|
20
|
+
theme at 1280 × 800 CSS pixels. Capture uses the real sandboxed MCP App with the
|
|
21
|
+
requested viewport and excludes showcase navigation. The default image records
|
|
22
|
+
the complete widget viewport, including its current scroll/state; it does not
|
|
23
|
+
automatically stitch every scroll position into one image.
|
|
24
|
+
|
|
25
|
+
ADS starts an isolated showcase/compiler and an owned browser process, using the
|
|
26
|
+
connected project's installed `@playwright/test` or `playwright`. It installs no
|
|
27
|
+
dependency/browser. Chromium is the default; optional project configuration is:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcp": {
|
|
32
|
+
"capture": {
|
|
33
|
+
"browser": "chromium",
|
|
34
|
+
"channel": "chrome",
|
|
35
|
+
"timeoutMs": 60000
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Omit `channel` to use Playwright's installed Chromium. Firefox and WebKit are also
|
|
42
|
+
accepted browser choices; channel is Chromium-only. The registered browser must
|
|
43
|
+
be installed locally. This budget bounds the capture runner, including preview
|
|
44
|
+
readiness. Capture does not run the project's entire Playwright suite or require a
|
|
45
|
+
behavior manifest. Readiness uses the App bridge, fonts and settled image loads,
|
|
46
|
+
not `networkidle` (MCP maintains live connections).
|
|
47
|
+
|
|
48
|
+
## Capture a named element
|
|
49
|
+
|
|
50
|
+
Declare selectors in the scenario's static metadata:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
export const scenario = {
|
|
54
|
+
title: "Example",
|
|
55
|
+
covers: ["Example"],
|
|
56
|
+
captureTargets: {
|
|
57
|
+
control: '[data-testid="example-control"]'
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Use attributes/selectors already owned by the real UI or its public review pattern.
|
|
63
|
+
Scenarios keep their existing styling/control rules. A target is not permission
|
|
64
|
+
to add demo-only product props, custom CSS or synthetic native controls. Each
|
|
65
|
+
selector is scoped to the App iframe and must match exactly one visible element.
|
|
66
|
+
Select it with `ads_capture({scenario:"<discovered ID>",target:"control"})`.
|
|
67
|
+
`captureTargets` allows up to 20 named CSS selectors. Unknown, hidden, ambiguous
|
|
68
|
+
or unrenderable targets fail explicitly; ADS does not guess a substitute element.
|
|
69
|
+
Arrange a specific interaction state through the scenario's real fixture/adapter;
|
|
70
|
+
capture itself accepts no arbitrary browser script or click sequence.
|
|
71
|
+
|
|
72
|
+
Screenshots hide the text caret and disable animations by default. Set
|
|
73
|
+
`animations:"allow"` when motion must remain active, and account for nondeterminism.
|
|
74
|
+
The same capture settings are used for both sides of a candidate comparison.
|
|
75
|
+
|
|
76
|
+
## Review a patch without applying it
|
|
77
|
+
|
|
78
|
+
Prepare/diff an owner draft normally, then request screenshots during its guarded
|
|
79
|
+
dry run:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
ads_apply_patch({
|
|
83
|
+
unit: "components/Example",
|
|
84
|
+
patchFile: ".ds/patches/<returned-name>.patch",
|
|
85
|
+
dryRun: true,
|
|
86
|
+
screenshot: true,
|
|
87
|
+
captures: [{ scenario: "components/Example", target: "control", theme: "light" }]
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The placeholder owner/ID/path must come from discovery/preparation. Transactions
|
|
92
|
+
accept the same `screenshot`/`captures` fields. Select 1–8 distinct scenario/target
|
|
93
|
+
pairs explicitly; do not capture every affected scenario by default. Ordinary dry
|
|
94
|
+
runs and patches create no screenshots. `screenshot:true` requires `dryRun:true`.
|
|
95
|
+
|
|
96
|
+
Core, registered lint/project and affected behavior gates pass first. ADS then
|
|
97
|
+
captures current source and the isolated candidate under matching theme, viewport,
|
|
98
|
+
animation and browser settings. Candidate screenshots survive candidate-directory
|
|
99
|
+
cleanup. Final source/conflict checks still run before the pair is published. A
|
|
100
|
+
failed/cancelled capture does not replace existing image slots or apply source.
|
|
101
|
+
If a scenario/target is newly introduced, `current` is null with an explicit
|
|
102
|
+
`currentAbsent` explanation; only the real candidate image exists.
|
|
103
|
+
|
|
104
|
+
Review the returned images and diagnostics, fix the draft if necessary, then apply
|
|
105
|
+
with `dryRun:false`. Apply reruns all gates. An image is promoted only when the
|
|
106
|
+
accepted source revision matches the captured candidate; other proposals remain
|
|
107
|
+
stale. Images do not approve a patch or certify interaction/accessibility/parity.
|
|
108
|
+
|
|
109
|
+
## Two slots, no automatic history
|
|
110
|
+
|
|
111
|
+
The stable capture key identifies the scenario and optional named target. Theme,
|
|
112
|
+
viewport and revision are metadata, not additional resource identities.
|
|
113
|
+
|
|
114
|
+
| Successful operation | Result for that target |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| Standalone `ads_capture` | Fresh current; any earlier candidate removed |
|
|
117
|
+
| Screenshot-enabled dry run | Fresh current + candidate; replaces the old pair |
|
|
118
|
+
| Apply matching proposed source | Candidate becomes current; candidate slot cleared |
|
|
119
|
+
| `ads_capture_clear({scenario,target?,candidateOnly:true})` | Discard candidate, retain current when present |
|
|
120
|
+
| `ads_capture_clear({scenario,target?})` | Remove both slots |
|
|
121
|
+
| Remove scenario/target | Orphan images collected on resource refresh/discovery |
|
|
122
|
+
|
|
123
|
+
No previous slot, revision history or TTL is kept. Later source changes mark
|
|
124
|
+
images stale rather than silently recapturing them. New proposals replace the
|
|
125
|
+
candidate. Three limits keep storage bounded: at most 4 MiB per PNG, 8 megapixels
|
|
126
|
+
per image and 256 MiB total capture storage. Clear unneeded targets if the store
|
|
127
|
+
reaches its limit. Viewport dimensions range from 100 to 4096 pixels per axis,
|
|
128
|
+
subject to the pixel limit.
|
|
129
|
+
|
|
130
|
+
## Read resources and freshness
|
|
131
|
+
|
|
132
|
+
`ads://project/captures` lists existing slots and metadata. Each returned image URI
|
|
133
|
+
uses the template `ads://captures/{key}/{slot}`, with `slot` current or candidate.
|
|
134
|
+
Read the exact returned URI through MCP `resources/read` (or the host's resource
|
|
135
|
+
tool). The result is `image/png` with binary `blob`, not a filesystem or browser
|
|
136
|
+
URL. Use the client's image/resource viewer; do not paste base64 into model text.
|
|
137
|
+
|
|
138
|
+
Capture metadata records source/build revision, fixture owner file, settings,
|
|
139
|
+
capture time, PNG dimensions/digest and candidate proposal identity. Current is
|
|
140
|
+
stale when its source revision differs; a candidate becomes stale when its base
|
|
141
|
+
source changes. Static freshness does not prove external/live fixture data stayed
|
|
142
|
+
identical. Subscribe to the index and image URIs for `resources/updated`, including
|
|
143
|
+
candidate removal; explicitly reread when the host does not deliver notifications.
|
|
144
|
+
Absent/cleared slots return a resource-not-found diagnostic, not an old image.
|
|
145
|
+
The resource catalogue exposes one index and an image URI template, avoiding a
|
|
146
|
+
resource-list entry for every new revision. Images stay as generated development
|
|
147
|
+
data under `.ds/captures/`; none belongs in product bundles or source patches.
|
|
@@ -6,6 +6,64 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
To verify a draft before applying it, diff it and dry-run the returned patch:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
ads_prepare_patch({"unit":"components/Example","action":"diff","draft":"<returned draft ID>"})
|
|
13
|
+
ads_apply_patch({"unit":"components/Example","patchFile":"<returned patchFile>","dryRun":true})
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The dry run validates the full candidate, including affected registered behavior
|
|
17
|
+
checks in an isolated project copy. Configured browser checks use that candidate's
|
|
18
|
+
managed preview, not the live showcase. Inspect the returned `behavior` failures
|
|
19
|
+
or the registered behavior-check results in `checks`, fix the draft and diff again.
|
|
20
|
+
Keep behavior.json/specs with their owner and use registered checks; a scratchpad
|
|
21
|
+
run against live source cannot verify unapplied changes. After validation, apply
|
|
22
|
+
with `dryRun:false`; ADS revalidates before writing. Dry-run evidence is not saved
|
|
23
|
+
as passing evidence for the live project.
|
|
24
|
+
|
|
25
|
+
`ads_verify({unit,checks?})` selects checks for current project source; it has no
|
|
26
|
+
draft argument. There is no dedicated selected-check runner for drafts yet.
|
|
27
|
+
Use a dry-run transaction for genuinely coupled draft patches.
|
|
28
|
+
|
|
29
|
+
Behavior-run performance belongs to both orchestration and project checks. ADS
|
|
30
|
+
selects affected owners, filters registered Playwright case tags and shares one
|
|
31
|
+
candidate host per run. The project owns assertions, browser setup, worker count,
|
|
32
|
+
per-test timeouts and its profile's whole-run `timeoutMs`. The latter covers the
|
|
33
|
+
entire runner process, not each test. Do not rewrite APIs, drop guarantees or
|
|
34
|
+
disable checks to fit the budget. Inspect measured durations before tuning it.
|
|
35
|
+
|
|
36
|
+
During verification, inspect `ads_status.behaviors.progress`; during candidate
|
|
37
|
+
validation, inspect `ads_status.mutations.progress`. These show completed/active/
|
|
38
|
+
pending checks and timings. MCP clients requesting progress also receive updates.
|
|
39
|
+
A timeout retains reported case outcomes and identifies active/unstarted checks;
|
|
40
|
+
it still blocks the mutation. `reportedStatus:"passed"` within an incomplete run
|
|
41
|
+
is diagnostic information, not a passing guarantee. Reports/artifacts under the
|
|
42
|
+
live project's `.ds/verification/` survive candidate cleanup. Uninstrumented custom
|
|
43
|
+
runners may report an unknown execution state instead of claiming a case started.
|
|
44
|
+
|
|
45
|
+
For independent browser specs, consider a small parallel worker count and measure
|
|
46
|
+
on the target machine. Use separate contexts/pages, independent state and the
|
|
47
|
+
candidate URLs provided by `openBehaviorScenario`; avoid fixed live-server URLs,
|
|
48
|
+
shared mutable fixtures and test-order assumptions. Files can run in parallel;
|
|
49
|
+
tests in one file remain sequential by default. Prefer readiness assertions over
|
|
50
|
+
blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actual
|
|
51
|
+
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
|
+
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
|
+
|
|
54
|
+
Named barrel imports can narrow affected checks when the project accurately
|
|
55
|
+
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
|
+
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
57
|
+
Do not change the policy merely to suppress verification of real side effects.
|
|
58
|
+
|
|
59
|
+
For registered measured-geometry style writes, use direct `element.style.transform =
|
|
60
|
+
value` or `element.style.setProperty("--ds-measured-value", value)` with the exact
|
|
61
|
+
file/property boundary. The current guard rejects a style-object alias such as
|
|
62
|
+
`const style = element.style` as an escape; it does not trace the alias to later
|
|
63
|
+
writes. Keep writes explicit when adapting local controller code. This syntax
|
|
64
|
+
constraint is separate from deciding which measured properties belong to the
|
|
65
|
+
controller; it does not authorize unregistered visual writes.
|
|
66
|
+
|
|
9
67
|
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
68
|
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
69
|
README links together. Conventional root credits/license/notice names support
|
|
@@ -49,6 +107,17 @@ Keep contextual public parts public when they are intended consumer API. Demonst
|
|
|
49
107
|
them through their actual public composition/customization path and list their real
|
|
50
108
|
render references in covers. Do not count internal production renders as public API
|
|
51
109
|
coverage. Behavioral APIs use exercises and registered guarantees instead.
|
|
52
|
-
Scenario controls still use public UI
|
|
53
|
-
|
|
54
|
-
|
|
110
|
+
Scenario controls still use public UI. A native link/button can supply semantics
|
|
111
|
+
as the single direct child of a public runtime slot when source tracing proves
|
|
112
|
+
that owner clones the child with its props. An `asChild` flag alone is insufficient;
|
|
113
|
+
standalone native controls and custom scenario styling remain rejected. See
|
|
114
|
+
[scenarios.md](scenarios.md) for evidence and limits. Preserve the intended
|
|
115
|
+
composition instead of substituting an unrelated styled control or adding a
|
|
116
|
+
demo-only component prop. Review framing belongs in public layout patterns.
|
|
117
|
+
|
|
118
|
+
A complete runner report containing an ordinary failed assertion preserves each
|
|
119
|
+
passing check as `passed`; the failed check remains `failed`, and overall
|
|
120
|
+
verification still rejects the mutation. Fix the actual failing checks instead of
|
|
121
|
+
assuming every affected owner failed. Suite errors, unexplained runner exits,
|
|
122
|
+
missing results and interrupted runs cannot certify passing guarantees. Use the
|
|
123
|
+
case's `reportedStatus`, message and report to distinguish these conditions.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Scenario rendering, token previews and public class helpers
|
|
2
2
|
|
|
3
|
-
Use this reference for `scenario-render`, `scenario-coverage` or `showcase-class`
|
|
3
|
+
Use this reference for `scenario-render`, `scenario-coverage`, `showcase-control` or `showcase-class`
|
|
4
4
|
diagnostics. MCP serves the same guide as `ads://guides/scenarios`.
|
|
5
5
|
|
|
6
6
|
All preview kinds open at `?scenario=<discovered-id>`. Use the returned showcase
|
|
@@ -18,6 +18,11 @@ recovers missed atomic replacements. Do not touch source to force freshness;
|
|
|
18
18
|
inspect build diagnostics. Upgrade the project's compiler dependency together
|
|
19
19
|
with MCP when an older reporter lacks source evidence.
|
|
20
20
|
|
|
21
|
+
Optional static `captureTargets` names CSS selectors within the scenario's App for
|
|
22
|
+
on-demand element screenshots. It grants no render/behavior coverage and no extra
|
|
23
|
+
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
|
+
target selection, resource reads and storage lifecycle.
|
|
25
|
+
|
|
21
26
|
## Owner-local token previews load their own definitions
|
|
22
27
|
|
|
23
28
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -85,6 +90,40 @@ do not export the helper solely for a test. Public/private ownership is a produc
|
|
|
85
90
|
decision, not a coverage workaround. Browser checks verify transitions but do not
|
|
86
91
|
replace the current static `covers` requirement; `exercises` does not waive it.
|
|
87
92
|
|
|
93
|
+
## Native semantics through a public runtime slot
|
|
94
|
+
|
|
95
|
+
A native element can be the direct child of a public runtime component that
|
|
96
|
+
actually clones that child with its own props:
|
|
97
|
+
|
|
98
|
+
```tsx
|
|
99
|
+
<Action asChild>
|
|
100
|
+
<a href={fixture.destination}>Documentation</a>
|
|
101
|
+
</Action>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`Action` and the fixture are illustrative; use the project's intended public API.
|
|
105
|
+
The runtime owner supplies presentation and interaction; the anchor supplies link
|
|
106
|
+
semantics. Keep this composition when it is the product contract. Do not replace
|
|
107
|
+
the anchor with an unrelated styled link, add a demo-only prop, disable the guard
|
|
108
|
+
or write outside MCP merely to silence a diagnostic.
|
|
109
|
+
|
|
110
|
+
ADS follows the selected runtime render path, the exact child and real imported
|
|
111
|
+
React/Preact `cloneElement` operations, including local slot/prop-merging helpers.
|
|
112
|
+
The prop need not be named `asChild`; the spelling alone grants no permission.
|
|
113
|
+
JSX and recognized framework factories follow the same rule. The native element
|
|
114
|
+
must be the single direct child: another native control nested inside it remains
|
|
115
|
+
subject to the ordinary ownership rule. Passing children through a container,
|
|
116
|
+
a scenario-local wrapper or an opaque component does not establish a slot.
|
|
117
|
+
|
|
118
|
+
This grants no scenario styling permission. Inline styles and arbitrary class
|
|
119
|
+
names remain rejected, including on the slotted child. Public style helpers retain
|
|
120
|
+
their own provenance checks. Unknown branches that could render the native child
|
|
121
|
+
directly, multiple children and untraceable replacement props remain blocked.
|
|
122
|
+
If a valid slot contract cannot be traced, keep the intended API and report a
|
|
123
|
+
small reproduction rather than inventing a product workaround. Static proof
|
|
124
|
+
establishes ownership, not correct prop merging, focus, keyboard or navigation
|
|
125
|
+
behavior; verify those in the built App and registered checks.
|
|
126
|
+
|
|
88
127
|
## Scenarios may consume verified public style helpers
|
|
89
128
|
|
|
90
129
|
A deliberately public helper can expose its owner's Linaria treatment:
|
|
@@ -32,7 +32,10 @@ also list a `ds.config.json` companion: change only that owner's `inlineStyleFil
|
|
|
32
32
|
and `boundaries.styleWrites` entries together with its source. Unused permissions
|
|
33
33
|
fail the core checks; do not pre-register a boundary without its implementation.
|
|
34
34
|
Use `dryRun: true` to
|
|
35
|
-
inspect validation
|
|
35
|
+
inspect validation, including affected registered behavior checks on the isolated
|
|
36
|
+
candidate. For a prepared draft, request its diff and dry-run the returned
|
|
37
|
+
`patchFile`; `ads_verify` checks current source and accepts no draft argument.
|
|
38
|
+
Applying re-runs the gates. Fix rejected patches in their
|
|
36
39
|
owner. Use `ads_apply_transaction` for genuinely coupled owner patches;
|
|
37
40
|
never bypass a rejection with direct source writes. Shared styles/helpers use `foundation`, root guides use
|
|
38
41
|
`documentation`, and branding/fonts use their discovered `assets/*` unit.
|
|
@@ -44,6 +47,8 @@ stay out of model context. Binary changes require Git. When editing is disabled,
|
|
|
44
47
|
use the client's normal source-editing tools.
|
|
45
48
|
For owner drafts, token-sample reconciliation, coupled transactions and local
|
|
46
49
|
constant namespaces, read [guarded-editing.md](references/guarded-editing.md).
|
|
50
|
+
For on-demand current/candidate screenshots and visual dry-run review, read
|
|
51
|
+
[captures.md](references/captures.md).
|
|
47
52
|
|
|
48
53
|
|
|
49
54
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
# On-demand visual captures
|
|
2
|
+
|
|
3
|
+
Use captures when reviewing appearance or a proposed visual change. Discover exact
|
|
4
|
+
scenario IDs with `ads_scenarios`; these are project-owned independently mountable
|
|
5
|
+
token, component, pattern and composition views. A component export alone is not
|
|
6
|
+
a renderable fixture. Controllers/hooks need a scenario demonstrating their visible
|
|
7
|
+
effects. ADS never supplies library-specific renderers, fixtures or capture targets.
|
|
8
|
+
|
|
9
|
+
## Capture current source
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
ads_capture({
|
|
13
|
+
scenario: "components/Example",
|
|
14
|
+
theme: "dark",
|
|
15
|
+
viewport: { width: 1280, height: 800 }
|
|
16
|
+
})
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The ID above is illustrative; use one returned by discovery. The default is light
|
|
20
|
+
theme at 1280 × 800 CSS pixels. Capture uses the real sandboxed MCP App with the
|
|
21
|
+
requested viewport and excludes showcase navigation. The default image records
|
|
22
|
+
the complete widget viewport, including its current scroll/state; it does not
|
|
23
|
+
automatically stitch every scroll position into one image.
|
|
24
|
+
|
|
25
|
+
ADS starts an isolated showcase/compiler and an owned browser process, using the
|
|
26
|
+
connected project's installed `@playwright/test` or `playwright`. It installs no
|
|
27
|
+
dependency/browser. Chromium is the default; optional project configuration is:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"mcp": {
|
|
32
|
+
"capture": {
|
|
33
|
+
"browser": "chromium",
|
|
34
|
+
"channel": "chrome",
|
|
35
|
+
"timeoutMs": 60000
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Omit `channel` to use Playwright's installed Chromium. Firefox and WebKit are also
|
|
42
|
+
accepted browser choices; channel is Chromium-only. The registered browser must
|
|
43
|
+
be installed locally. This budget bounds the capture runner, including preview
|
|
44
|
+
readiness. Capture does not run the project's entire Playwright suite or require a
|
|
45
|
+
behavior manifest. Readiness uses the App bridge, fonts and settled image loads,
|
|
46
|
+
not `networkidle` (MCP maintains live connections).
|
|
47
|
+
|
|
48
|
+
## Capture a named element
|
|
49
|
+
|
|
50
|
+
Declare selectors in the scenario's static metadata:
|
|
51
|
+
|
|
52
|
+
```tsx
|
|
53
|
+
export const scenario = {
|
|
54
|
+
title: "Example",
|
|
55
|
+
covers: ["Example"],
|
|
56
|
+
captureTargets: {
|
|
57
|
+
control: '[data-testid="example-control"]'
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Use attributes/selectors already owned by the real UI or its public review pattern.
|
|
63
|
+
Scenarios keep their existing styling/control rules. A target is not permission
|
|
64
|
+
to add demo-only product props, custom CSS or synthetic native controls. Each
|
|
65
|
+
selector is scoped to the App iframe and must match exactly one visible element.
|
|
66
|
+
Select it with `ads_capture({scenario:"<discovered ID>",target:"control"})`.
|
|
67
|
+
`captureTargets` allows up to 20 named CSS selectors. Unknown, hidden, ambiguous
|
|
68
|
+
or unrenderable targets fail explicitly; ADS does not guess a substitute element.
|
|
69
|
+
Arrange a specific interaction state through the scenario's real fixture/adapter;
|
|
70
|
+
capture itself accepts no arbitrary browser script or click sequence.
|
|
71
|
+
|
|
72
|
+
Screenshots hide the text caret and disable animations by default. Set
|
|
73
|
+
`animations:"allow"` when motion must remain active, and account for nondeterminism.
|
|
74
|
+
The same capture settings are used for both sides of a candidate comparison.
|
|
75
|
+
|
|
76
|
+
## Review a patch without applying it
|
|
77
|
+
|
|
78
|
+
Prepare/diff an owner draft normally, then request screenshots during its guarded
|
|
79
|
+
dry run:
|
|
80
|
+
|
|
81
|
+
```js
|
|
82
|
+
ads_apply_patch({
|
|
83
|
+
unit: "components/Example",
|
|
84
|
+
patchFile: ".ds/patches/<returned-name>.patch",
|
|
85
|
+
dryRun: true,
|
|
86
|
+
screenshot: true,
|
|
87
|
+
captures: [{ scenario: "components/Example", target: "control", theme: "light" }]
|
|
88
|
+
})
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
The placeholder owner/ID/path must come from discovery/preparation. Transactions
|
|
92
|
+
accept the same `screenshot`/`captures` fields. Select 1–8 distinct scenario/target
|
|
93
|
+
pairs explicitly; do not capture every affected scenario by default. Ordinary dry
|
|
94
|
+
runs and patches create no screenshots. `screenshot:true` requires `dryRun:true`.
|
|
95
|
+
|
|
96
|
+
Core, registered lint/project and affected behavior gates pass first. ADS then
|
|
97
|
+
captures current source and the isolated candidate under matching theme, viewport,
|
|
98
|
+
animation and browser settings. Candidate screenshots survive candidate-directory
|
|
99
|
+
cleanup. Final source/conflict checks still run before the pair is published. A
|
|
100
|
+
failed/cancelled capture does not replace existing image slots or apply source.
|
|
101
|
+
If a scenario/target is newly introduced, `current` is null with an explicit
|
|
102
|
+
`currentAbsent` explanation; only the real candidate image exists.
|
|
103
|
+
|
|
104
|
+
Review the returned images and diagnostics, fix the draft if necessary, then apply
|
|
105
|
+
with `dryRun:false`. Apply reruns all gates. An image is promoted only when the
|
|
106
|
+
accepted source revision matches the captured candidate; other proposals remain
|
|
107
|
+
stale. Images do not approve a patch or certify interaction/accessibility/parity.
|
|
108
|
+
|
|
109
|
+
## Two slots, no automatic history
|
|
110
|
+
|
|
111
|
+
The stable capture key identifies the scenario and optional named target. Theme,
|
|
112
|
+
viewport and revision are metadata, not additional resource identities.
|
|
113
|
+
|
|
114
|
+
| Successful operation | Result for that target |
|
|
115
|
+
| --- | --- |
|
|
116
|
+
| Standalone `ads_capture` | Fresh current; any earlier candidate removed |
|
|
117
|
+
| Screenshot-enabled dry run | Fresh current + candidate; replaces the old pair |
|
|
118
|
+
| Apply matching proposed source | Candidate becomes current; candidate slot cleared |
|
|
119
|
+
| `ads_capture_clear({scenario,target?,candidateOnly:true})` | Discard candidate, retain current when present |
|
|
120
|
+
| `ads_capture_clear({scenario,target?})` | Remove both slots |
|
|
121
|
+
| Remove scenario/target | Orphan images collected on resource refresh/discovery |
|
|
122
|
+
|
|
123
|
+
No previous slot, revision history or TTL is kept. Later source changes mark
|
|
124
|
+
images stale rather than silently recapturing them. New proposals replace the
|
|
125
|
+
candidate. Three limits keep storage bounded: at most 4 MiB per PNG, 8 megapixels
|
|
126
|
+
per image and 256 MiB total capture storage. Clear unneeded targets if the store
|
|
127
|
+
reaches its limit. Viewport dimensions range from 100 to 4096 pixels per axis,
|
|
128
|
+
subject to the pixel limit.
|
|
129
|
+
|
|
130
|
+
## Read resources and freshness
|
|
131
|
+
|
|
132
|
+
`ads://project/captures` lists existing slots and metadata. Each returned image URI
|
|
133
|
+
uses the template `ads://captures/{key}/{slot}`, with `slot` current or candidate.
|
|
134
|
+
Read the exact returned URI through MCP `resources/read` (or the host's resource
|
|
135
|
+
tool). The result is `image/png` with binary `blob`, not a filesystem or browser
|
|
136
|
+
URL. Use the client's image/resource viewer; do not paste base64 into model text.
|
|
137
|
+
|
|
138
|
+
Capture metadata records source/build revision, fixture owner file, settings,
|
|
139
|
+
capture time, PNG dimensions/digest and candidate proposal identity. Current is
|
|
140
|
+
stale when its source revision differs; a candidate becomes stale when its base
|
|
141
|
+
source changes. Static freshness does not prove external/live fixture data stayed
|
|
142
|
+
identical. Subscribe to the index and image URIs for `resources/updated`, including
|
|
143
|
+
candidate removal; explicitly reread when the host does not deliver notifications.
|
|
144
|
+
Absent/cleared slots return a resource-not-found diagnostic, not an old image.
|
|
145
|
+
The resource catalogue exposes one index and an image URI template, avoiding a
|
|
146
|
+
resource-list entry for every new revision. Images stay as generated development
|
|
147
|
+
data under `.ds/captures/`; none belongs in product bundles or source patches.
|
|
@@ -6,6 +6,64 @@ tools, request `action:"diff"`, then apply the returned patchFile. Discard the
|
|
|
6
6
|
draft afterward. Remote clients can keep sending inline Git diffs. Neither draft
|
|
7
7
|
preparation nor diff generation validates or changes live source.
|
|
8
8
|
|
|
9
|
+
To verify a draft before applying it, diff it and dry-run the returned patch:
|
|
10
|
+
|
|
11
|
+
```js
|
|
12
|
+
ads_prepare_patch({"unit":"components/Example","action":"diff","draft":"<returned draft ID>"})
|
|
13
|
+
ads_apply_patch({"unit":"components/Example","patchFile":"<returned patchFile>","dryRun":true})
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The dry run validates the full candidate, including affected registered behavior
|
|
17
|
+
checks in an isolated project copy. Configured browser checks use that candidate's
|
|
18
|
+
managed preview, not the live showcase. Inspect the returned `behavior` failures
|
|
19
|
+
or the registered behavior-check results in `checks`, fix the draft and diff again.
|
|
20
|
+
Keep behavior.json/specs with their owner and use registered checks; a scratchpad
|
|
21
|
+
run against live source cannot verify unapplied changes. After validation, apply
|
|
22
|
+
with `dryRun:false`; ADS revalidates before writing. Dry-run evidence is not saved
|
|
23
|
+
as passing evidence for the live project.
|
|
24
|
+
|
|
25
|
+
`ads_verify({unit,checks?})` selects checks for current project source; it has no
|
|
26
|
+
draft argument. There is no dedicated selected-check runner for drafts yet.
|
|
27
|
+
Use a dry-run transaction for genuinely coupled draft patches.
|
|
28
|
+
|
|
29
|
+
Behavior-run performance belongs to both orchestration and project checks. ADS
|
|
30
|
+
selects affected owners, filters registered Playwright case tags and shares one
|
|
31
|
+
candidate host per run. The project owns assertions, browser setup, worker count,
|
|
32
|
+
per-test timeouts and its profile's whole-run `timeoutMs`. The latter covers the
|
|
33
|
+
entire runner process, not each test. Do not rewrite APIs, drop guarantees or
|
|
34
|
+
disable checks to fit the budget. Inspect measured durations before tuning it.
|
|
35
|
+
|
|
36
|
+
During verification, inspect `ads_status.behaviors.progress`; during candidate
|
|
37
|
+
validation, inspect `ads_status.mutations.progress`. These show completed/active/
|
|
38
|
+
pending checks and timings. MCP clients requesting progress also receive updates.
|
|
39
|
+
A timeout retains reported case outcomes and identifies active/unstarted checks;
|
|
40
|
+
it still blocks the mutation. `reportedStatus:"passed"` within an incomplete run
|
|
41
|
+
is diagnostic information, not a passing guarantee. Reports/artifacts under the
|
|
42
|
+
live project's `.ds/verification/` survive candidate cleanup. Uninstrumented custom
|
|
43
|
+
runners may report an unknown execution state instead of claiming a case started.
|
|
44
|
+
|
|
45
|
+
For independent browser specs, consider a small parallel worker count and measure
|
|
46
|
+
on the target machine. Use separate contexts/pages, independent state and the
|
|
47
|
+
candidate URLs provided by `openBehaviorScenario`; avoid fixed live-server URLs,
|
|
48
|
+
shared mutable fixtures and test-order assumptions. Files can run in parallel;
|
|
49
|
+
tests in one file remain sequential by default. Prefer readiness assertions over
|
|
50
|
+
blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actual
|
|
51
|
+
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
|
+
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
|
+
|
|
54
|
+
Named barrel imports can narrow affected checks when the project accurately
|
|
55
|
+
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
|
+
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
57
|
+
Do not change the policy merely to suppress verification of real side effects.
|
|
58
|
+
|
|
59
|
+
For registered measured-geometry style writes, use direct `element.style.transform =
|
|
60
|
+
value` or `element.style.setProperty("--ds-measured-value", value)` with the exact
|
|
61
|
+
file/property boundary. The current guard rejects a style-object alias such as
|
|
62
|
+
`const style = element.style` as an escape; it does not trace the alias to later
|
|
63
|
+
writes. Keep writes explicit when adapting local controller code. This syntax
|
|
64
|
+
constraint is separate from deciding which measured properties belong to the
|
|
65
|
+
controller; it does not authorize unregistered visual writes.
|
|
66
|
+
|
|
9
67
|
Shared provenance uses the existing `documentation` unit. Read its `filePolicy`
|
|
10
68
|
from `ads_units`: one patch can create `CREDITS.md`, shared `licenses/*.txt` and
|
|
11
69
|
README links together. Conventional root credits/license/notice names support
|
|
@@ -49,6 +107,17 @@ Keep contextual public parts public when they are intended consumer API. Demonst
|
|
|
49
107
|
them through their actual public composition/customization path and list their real
|
|
50
108
|
render references in covers. Do not count internal production renders as public API
|
|
51
109
|
coverage. Behavioral APIs use exercises and registered guarantees instead.
|
|
52
|
-
Scenario controls still use public UI
|
|
53
|
-
|
|
54
|
-
|
|
110
|
+
Scenario controls still use public UI. A native link/button can supply semantics
|
|
111
|
+
as the single direct child of a public runtime slot when source tracing proves
|
|
112
|
+
that owner clones the child with its props. An `asChild` flag alone is insufficient;
|
|
113
|
+
standalone native controls and custom scenario styling remain rejected. See
|
|
114
|
+
[scenarios.md](scenarios.md) for evidence and limits. Preserve the intended
|
|
115
|
+
composition instead of substituting an unrelated styled control or adding a
|
|
116
|
+
demo-only component prop. Review framing belongs in public layout patterns.
|
|
117
|
+
|
|
118
|
+
A complete runner report containing an ordinary failed assertion preserves each
|
|
119
|
+
passing check as `passed`; the failed check remains `failed`, and overall
|
|
120
|
+
verification still rejects the mutation. Fix the actual failing checks instead of
|
|
121
|
+
assuming every affected owner failed. Suite errors, unexplained runner exits,
|
|
122
|
+
missing results and interrupted runs cannot certify passing guarantees. Use the
|
|
123
|
+
case's `reportedStatus`, message and report to distinguish these conditions.
|