@reqvire-org/ads 0.3.14 → 0.3.16
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/mcp/sandbox-host.mjs +1 -1
- package/dist/mcp/widget.bundle.js +14 -14
- package/dist/showcase/client.bundle.js +18 -18
- package/dist/showcase/resource-reader.js +37 -0
- package/dist/showcase/sandbox.bundle.js +1 -0
- package/dist/skills/ads-break-ui/SKILL.md +2 -2
- package/dist/skills/ads-break-ui/references/guarded-editing.md +12 -0
- package/dist/skills/ads-break-ui/references/scenarios.md +11 -0
- package/dist/skills/ads-designer/SKILL.md +2 -2
- package/dist/skills/ads-designer/references/guarded-editing.md +12 -0
- package/dist/skills/ads-designer/references/scenarios.md +11 -0
- package/dist/skills/ads-import/SKILL.md +2 -2
- package/dist/skills/ads-import/references/guarded-editing.md +12 -0
- package/dist/skills/ads-import/references/scenarios.md +11 -0
- package/dist/skills/ads-migrate/SKILL.md +2 -2
- package/dist/skills/ads-migrate/references/guarded-editing.md +12 -0
- package/dist/skills/ads-migrate/references/scenarios.md +11 -0
- package/dist/skills/ads-motion/SKILL.md +2 -2
- package/dist/skills/ads-motion/references/guarded-editing.md +12 -0
- package/dist/skills/ads-motion/references/scenarios.md +11 -0
- package/dist/verification/browser.mjs +5 -1
- package/dist/verification/playwright-reporter.cjs +21 -1
- package/dist/verification.mjs +1 -0
- package/docs/ARCHITECTURE.md +16 -0
- package/docs/BEHAVIORS.md +17 -2
- package/docs/CHANGELOG.md +15 -0
- package/docs/MCP.md +7 -0
- package/package.json +1 -1
- package/dist/showcase/sandbox.js +0 -30
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
const retryDelays = [200, 800];
|
|
2
|
+
const networkFailure = error => error?.name === "TypeError" && /^(Failed to fetch|fetch failed|Load failed|NetworkError when attempting to fetch resource\.)$/.test(error.message);
|
|
3
|
+
|
|
4
|
+
function pause(milliseconds, signal) {
|
|
5
|
+
return new Promise((resolve, reject) => {
|
|
6
|
+
signal?.throwIfAborted();
|
|
7
|
+
const finish = () => { signal?.removeEventListener("abort", abort); resolve(); };
|
|
8
|
+
const timer = setTimeout(finish, milliseconds);
|
|
9
|
+
const abort = () => { clearTimeout(timer); signal.removeEventListener("abort", abort); reject(signal.reason); };
|
|
10
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/** Only resources/read is repeatable here; never wrap tool calls or assertions. */
|
|
15
|
+
export function resourceReader(read, { signal, onDiagnostic, wait = pause } = {}) {
|
|
16
|
+
return async input => {
|
|
17
|
+
for (let attempt = 1; ; attempt++) {
|
|
18
|
+
signal?.throwIfAborted();
|
|
19
|
+
try {
|
|
20
|
+
const response = await read(input);
|
|
21
|
+
signal?.throwIfAborted();
|
|
22
|
+
if (attempt > 1) onDiagnostic?.({ state: "recovered", uri: input.uri, attempt });
|
|
23
|
+
return response;
|
|
24
|
+
} catch (error) {
|
|
25
|
+
signal?.throwIfAborted();
|
|
26
|
+
if (!networkFailure(error)) throw error;
|
|
27
|
+
if (attempt > retryDelays.length) {
|
|
28
|
+
onDiagnostic?.({ state: "exhausted", uri: input.uri, attempt, message: error.message });
|
|
29
|
+
throw Object.assign(new Error(`MCP resource transport failed for ${input.uri} after ${attempt} attempts: ${error.message}. Inspect the host connection and browser network diagnostics; this resource-loading error does not establish a component assertion failure.`, { cause: error }), { code: "ADS_RESOURCE_TRANSPORT" });
|
|
30
|
+
}
|
|
31
|
+
const delayMs = retryDelays[attempt - 1];
|
|
32
|
+
onDiagnostic?.({ state: "retry", uri: input.uri, attempt, nextAttempt: attempt + 1, delayMs, message: error.message });
|
|
33
|
+
await wait(delayMs, signal);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
function c(e,t){let n=new DOMParser().parseFromString(e,"text/html"),r=n.createElement("meta");if(r.httpEquiv="Content-Security-Policy",r.content=t,n.head.prepend(r),!n.querySelector("base[href]")){let i=n.querySelector("base")??n.createElement("base");i.setAttribute("href","about:srcdoc"),r.after(i)}return"<!doctype html>"+n.documentElement.outerHTML}var a=new URL(location.href).searchParams.get("parent"),o;function s(e=[]){return e.filter(t=>/^(?:https?:\/\/[a-z0-9.*:[\]-]+(?::\d+)?|data:|blob:|about:)$/i.test(t)).join(" ")}function d(e={}){let t=s(e.resourceDomains);return`default-src 'none';script-src 'unsafe-inline' ${t};style-src 'unsafe-inline' ${t};img-src data: ${t};font-src ${t||"'none'"};media-src ${t||"'none'"};worker-src ${t||"'none'"};connect-src ${s(e.connectDomains)||"'none'"};frame-src ${s(e.frameDomains)||"'none'"};base-uri about: ${s(e.baseUriDomains)};object-src 'none'`}window.addEventListener("message",e=>{if(e.source===parent&&e.origin===a){let t=e.data;if(t?.method==="ui/notifications/sandbox-resource-ready"){let{html:n,csp:r}=t.params??{};if(typeof n!="string")return;o?.remove(),o=window.document.createElement("iframe"),o.title="Design-system App",o.setAttribute("sandbox","allow-scripts"),window.document.body.append(o),o.srcdoc=c(n,d(r))}else t?.jsonrpc==="2.0"&&!t.method?.startsWith("ui/notifications/sandbox-")&&o?.contentWindow.postMessage(t,"*")}else e.source===o?.contentWindow&&e.data?.jsonrpc==="2.0"&&!e.data.method?.startsWith("ui/notifications/sandbox-")&&parent.postMessage(e.data,a)});parent.postMessage({jsonrpc:"2.0",method:"ui/notifications/sandbox-proxy-ready",params:{}},a);
|
|
@@ -55,8 +55,8 @@ For on-demand current/candidate screenshots and visual dry-run review, read
|
|
|
55
55
|
|
|
56
56
|
|
|
57
57
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
58
|
-
public style-helper use
|
|
59
|
-
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
58
|
+
public style-helper use, fragment-link navigation, or `scenario-render` /
|
|
59
|
+
`showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
60
60
|
examples explain API visibility, reference baselines and state-transition checks.
|
|
61
61
|
Traced parents can cover declared public children; verified public Linaria
|
|
62
62
|
helpers do not grant custom scenario CSS.
|
|
@@ -51,6 +51,18 @@ blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actua
|
|
|
51
51
|
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
52
|
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
53
|
|
|
54
|
+
If a check cannot load its MCP preview, preserve the draft and inspect the exact
|
|
55
|
+
resource URI and failed browser requests before changing component code. The ADS
|
|
56
|
+
showcase retries a fetch transport failure on `resources/read` at most twice
|
|
57
|
+
(200/800 ms backoff); recovered startup reads remain visible in
|
|
58
|
+
`startupDiagnostics`. It never retries tool calls, assertions or complete checks,
|
|
59
|
+
and persistent failures still block application. HTTP/protocol/content errors,
|
|
60
|
+
integrity failures and cancellation do not retry. External hosts own their
|
|
61
|
+
transport behavior. Chrome's `ERR_NETWORK_CHANGED` does not prove an ADS restart
|
|
62
|
+
or identify Docker/VPN churn: correlate failure timestamps with live interface
|
|
63
|
+
events, Chrome network logs and server availability. Do not weaken checks or
|
|
64
|
+
rewrite a valid API to hide infrastructure failures.
|
|
65
|
+
|
|
54
66
|
Named barrel imports can narrow affected checks when the project accurately
|
|
55
67
|
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
68
|
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
@@ -23,6 +23,17 @@ on-demand element screenshots. It grants no render/behavior coverage and no extr
|
|
|
23
23
|
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
24
|
target selection, resource reads and storage lifecycle.
|
|
25
25
|
|
|
26
|
+
## Fragment links inside Apps
|
|
27
|
+
|
|
28
|
+
Keep intended `href="#"` and named fragments in the project API and fixtures.
|
|
29
|
+
ADS's inline-document loader supplies an `about:srcdoc` base when the App has no
|
|
30
|
+
explicit base, preserving native scrolling, events and state. If a fragment
|
|
31
|
+
replaces the App with a sandbox URL or browser error, inspect `location.href`,
|
|
32
|
+
`document.baseURI` and the resolved anchor URL. Report a host loading defect;
|
|
33
|
+
do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
34
|
+
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
|
+
their document-loading policy. Verify link activation as well as rendering.
|
|
36
|
+
|
|
26
37
|
## Owner-local token previews load their own definitions
|
|
27
38
|
|
|
28
39
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -86,8 +86,8 @@ For on-demand current/candidate screenshots and visual dry-run review, read
|
|
|
86
86
|
[captures.md](references/captures.md).
|
|
87
87
|
|
|
88
88
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
89
|
-
public style-helper use
|
|
90
|
-
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
89
|
+
public style-helper use, fragment-link navigation, or `scenario-render` /
|
|
90
|
+
`showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
91
91
|
examples explain API visibility, reference baselines and state-transition checks.
|
|
92
92
|
Traced parents can cover declared public children; verified public Linaria
|
|
93
93
|
helpers do not grant custom scenario CSS.
|
|
@@ -51,6 +51,18 @@ blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actua
|
|
|
51
51
|
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
52
|
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
53
|
|
|
54
|
+
If a check cannot load its MCP preview, preserve the draft and inspect the exact
|
|
55
|
+
resource URI and failed browser requests before changing component code. The ADS
|
|
56
|
+
showcase retries a fetch transport failure on `resources/read` at most twice
|
|
57
|
+
(200/800 ms backoff); recovered startup reads remain visible in
|
|
58
|
+
`startupDiagnostics`. It never retries tool calls, assertions or complete checks,
|
|
59
|
+
and persistent failures still block application. HTTP/protocol/content errors,
|
|
60
|
+
integrity failures and cancellation do not retry. External hosts own their
|
|
61
|
+
transport behavior. Chrome's `ERR_NETWORK_CHANGED` does not prove an ADS restart
|
|
62
|
+
or identify Docker/VPN churn: correlate failure timestamps with live interface
|
|
63
|
+
events, Chrome network logs and server availability. Do not weaken checks or
|
|
64
|
+
rewrite a valid API to hide infrastructure failures.
|
|
65
|
+
|
|
54
66
|
Named barrel imports can narrow affected checks when the project accurately
|
|
55
67
|
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
68
|
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
@@ -23,6 +23,17 @@ on-demand element screenshots. It grants no render/behavior coverage and no extr
|
|
|
23
23
|
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
24
|
target selection, resource reads and storage lifecycle.
|
|
25
25
|
|
|
26
|
+
## Fragment links inside Apps
|
|
27
|
+
|
|
28
|
+
Keep intended `href="#"` and named fragments in the project API and fixtures.
|
|
29
|
+
ADS's inline-document loader supplies an `about:srcdoc` base when the App has no
|
|
30
|
+
explicit base, preserving native scrolling, events and state. If a fragment
|
|
31
|
+
replaces the App with a sandbox URL or browser error, inspect `location.href`,
|
|
32
|
+
`document.baseURI` and the resolved anchor URL. Report a host loading defect;
|
|
33
|
+
do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
34
|
+
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
|
+
their document-loading policy. Verify link activation as well as rendering.
|
|
36
|
+
|
|
26
37
|
## Owner-local token previews load their own definitions
|
|
27
38
|
|
|
28
39
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -50,8 +50,8 @@ For on-demand current/candidate screenshots and visual dry-run review, read
|
|
|
50
50
|
[captures.md](references/captures.md).
|
|
51
51
|
|
|
52
52
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
53
|
-
public style-helper use
|
|
54
|
-
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
53
|
+
public style-helper use, fragment-link navigation, or `scenario-render` /
|
|
54
|
+
`showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
55
55
|
examples explain API visibility, reference baselines and state-transition checks.
|
|
56
56
|
Traced parents can cover declared public children; verified public Linaria
|
|
57
57
|
helpers do not grant custom scenario CSS.
|
|
@@ -51,6 +51,18 @@ blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actua
|
|
|
51
51
|
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
52
|
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
53
|
|
|
54
|
+
If a check cannot load its MCP preview, preserve the draft and inspect the exact
|
|
55
|
+
resource URI and failed browser requests before changing component code. The ADS
|
|
56
|
+
showcase retries a fetch transport failure on `resources/read` at most twice
|
|
57
|
+
(200/800 ms backoff); recovered startup reads remain visible in
|
|
58
|
+
`startupDiagnostics`. It never retries tool calls, assertions or complete checks,
|
|
59
|
+
and persistent failures still block application. HTTP/protocol/content errors,
|
|
60
|
+
integrity failures and cancellation do not retry. External hosts own their
|
|
61
|
+
transport behavior. Chrome's `ERR_NETWORK_CHANGED` does not prove an ADS restart
|
|
62
|
+
or identify Docker/VPN churn: correlate failure timestamps with live interface
|
|
63
|
+
events, Chrome network logs and server availability. Do not weaken checks or
|
|
64
|
+
rewrite a valid API to hide infrastructure failures.
|
|
65
|
+
|
|
54
66
|
Named barrel imports can narrow affected checks when the project accurately
|
|
55
67
|
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
68
|
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
@@ -23,6 +23,17 @@ on-demand element screenshots. It grants no render/behavior coverage and no extr
|
|
|
23
23
|
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
24
|
target selection, resource reads and storage lifecycle.
|
|
25
25
|
|
|
26
|
+
## Fragment links inside Apps
|
|
27
|
+
|
|
28
|
+
Keep intended `href="#"` and named fragments in the project API and fixtures.
|
|
29
|
+
ADS's inline-document loader supplies an `about:srcdoc` base when the App has no
|
|
30
|
+
explicit base, preserving native scrolling, events and state. If a fragment
|
|
31
|
+
replaces the App with a sandbox URL or browser error, inspect `location.href`,
|
|
32
|
+
`document.baseURI` and the resolved anchor URL. Report a host loading defect;
|
|
33
|
+
do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
34
|
+
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
|
+
their document-loading policy. Verify link activation as well as rendering.
|
|
36
|
+
|
|
26
37
|
## Owner-local token previews load their own definitions
|
|
27
38
|
|
|
28
39
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -52,8 +52,8 @@ For on-demand current/candidate screenshots and visual dry-run review, read
|
|
|
52
52
|
|
|
53
53
|
|
|
54
54
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
55
|
-
public style-helper use
|
|
56
|
-
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
55
|
+
public style-helper use, fragment-link navigation, or `scenario-render` /
|
|
56
|
+
`showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
57
57
|
examples explain API visibility, reference baselines and state-transition checks.
|
|
58
58
|
Traced parents can cover declared public children; verified public Linaria
|
|
59
59
|
helpers do not grant custom scenario CSS.
|
|
@@ -51,6 +51,18 @@ blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actua
|
|
|
51
51
|
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
52
|
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
53
|
|
|
54
|
+
If a check cannot load its MCP preview, preserve the draft and inspect the exact
|
|
55
|
+
resource URI and failed browser requests before changing component code. The ADS
|
|
56
|
+
showcase retries a fetch transport failure on `resources/read` at most twice
|
|
57
|
+
(200/800 ms backoff); recovered startup reads remain visible in
|
|
58
|
+
`startupDiagnostics`. It never retries tool calls, assertions or complete checks,
|
|
59
|
+
and persistent failures still block application. HTTP/protocol/content errors,
|
|
60
|
+
integrity failures and cancellation do not retry. External hosts own their
|
|
61
|
+
transport behavior. Chrome's `ERR_NETWORK_CHANGED` does not prove an ADS restart
|
|
62
|
+
or identify Docker/VPN churn: correlate failure timestamps with live interface
|
|
63
|
+
events, Chrome network logs and server availability. Do not weaken checks or
|
|
64
|
+
rewrite a valid API to hide infrastructure failures.
|
|
65
|
+
|
|
54
66
|
Named barrel imports can narrow affected checks when the project accurately
|
|
55
67
|
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
68
|
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
@@ -23,6 +23,17 @@ on-demand element screenshots. It grants no render/behavior coverage and no extr
|
|
|
23
23
|
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
24
|
target selection, resource reads and storage lifecycle.
|
|
25
25
|
|
|
26
|
+
## Fragment links inside Apps
|
|
27
|
+
|
|
28
|
+
Keep intended `href="#"` and named fragments in the project API and fixtures.
|
|
29
|
+
ADS's inline-document loader supplies an `about:srcdoc` base when the App has no
|
|
30
|
+
explicit base, preserving native scrolling, events and state. If a fragment
|
|
31
|
+
replaces the App with a sandbox URL or browser error, inspect `location.href`,
|
|
32
|
+
`document.baseURI` and the resolved anchor URL. Report a host loading defect;
|
|
33
|
+
do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
34
|
+
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
|
+
their document-loading policy. Verify link activation as well as rendering.
|
|
36
|
+
|
|
26
37
|
## Owner-local token previews load their own definitions
|
|
27
38
|
|
|
28
39
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -72,8 +72,8 @@ For on-demand current/candidate screenshots and visual dry-run review, read
|
|
|
72
72
|
|
|
73
73
|
|
|
74
74
|
For parent/child `covers`, conditional-control review, reference comparisons,
|
|
75
|
-
public style-helper use
|
|
76
|
-
findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
75
|
+
public style-helper use, fragment-link navigation, or `scenario-render` /
|
|
76
|
+
`showcase-class` findings, read [scenario contracts](references/scenarios.md). Its verification
|
|
77
77
|
examples explain API visibility, reference baselines and state-transition checks.
|
|
78
78
|
Traced parents can cover declared public children; verified public Linaria
|
|
79
79
|
helpers do not grant custom scenario CSS.
|
|
@@ -51,6 +51,18 @@ blanket sleeps. Fake clocks suit timer-only guarantees; keep real time for actua
|
|
|
51
51
|
gesture/motion/layout guarantees. Project settings belong in guarded configuration
|
|
52
52
|
changes; ADS does not silently raise budgets or override the worker count.
|
|
53
53
|
|
|
54
|
+
If a check cannot load its MCP preview, preserve the draft and inspect the exact
|
|
55
|
+
resource URI and failed browser requests before changing component code. The ADS
|
|
56
|
+
showcase retries a fetch transport failure on `resources/read` at most twice
|
|
57
|
+
(200/800 ms backoff); recovered startup reads remain visible in
|
|
58
|
+
`startupDiagnostics`. It never retries tool calls, assertions or complete checks,
|
|
59
|
+
and persistent failures still block application. HTTP/protocol/content errors,
|
|
60
|
+
integrity failures and cancellation do not retry. External hosts own their
|
|
61
|
+
transport behavior. Chrome's `ERR_NETWORK_CHANGED` does not prove an ADS restart
|
|
62
|
+
or identify Docker/VPN churn: correlate failure timestamps with live interface
|
|
63
|
+
events, Chrome network logs and server availability. Do not weaken checks or
|
|
64
|
+
rewrite a valid API to hide infrastructure failures.
|
|
65
|
+
|
|
54
66
|
Named barrel imports can narrow affected checks when the project accurately
|
|
55
67
|
declares package `sideEffects`; retain CSS/global effects in that policy. Missing
|
|
56
68
|
or unsupported policies and dynamic/wildcard dependencies stay conservative.
|
|
@@ -23,6 +23,17 @@ on-demand element screenshots. It grants no render/behavior coverage and no extr
|
|
|
23
23
|
styling permission. Use [captures.md](captures.md) for current/candidate review,
|
|
24
24
|
target selection, resource reads and storage lifecycle.
|
|
25
25
|
|
|
26
|
+
## Fragment links inside Apps
|
|
27
|
+
|
|
28
|
+
Keep intended `href="#"` and named fragments in the project API and fixtures.
|
|
29
|
+
ADS's inline-document loader supplies an `about:srcdoc` base when the App has no
|
|
30
|
+
explicit base, preserving native scrolling, events and state. If a fragment
|
|
31
|
+
replaces the App with a sandbox URL or browser error, inspect `location.href`,
|
|
32
|
+
`document.baseURI` and the resolved anchor URL. Report a host loading defect;
|
|
33
|
+
do not add scenario `preventDefault` handlers merely to hide it. Explicit App
|
|
34
|
+
bases retain their declared behavior and CSP requirements; external hosts own
|
|
35
|
+
their document-loading policy. Verify link activation as well as rendering.
|
|
36
|
+
|
|
26
37
|
## Owner-local token previews load their own definitions
|
|
27
38
|
|
|
28
39
|
Keep the registered token sheet imported by its runtime owner for product use.
|
|
@@ -27,7 +27,11 @@ export async function openPreviewScenario(page, url, scenario, { timeout = 30000
|
|
|
27
27
|
while (Date.now() < end) {
|
|
28
28
|
for (const frame of page.frames().filter(frame => frame !== page.mainFrame())) {
|
|
29
29
|
const state = await frame.evaluate(() => ({ state: document.documentElement.dataset.adsPreviewState, id: document.documentElement.dataset.adsScenario, message: document.getElementById("ads-preview-status")?.textContent })).catch(() => ({}));
|
|
30
|
-
if (state.id === scenario && state.state === "ready")
|
|
30
|
+
if (state.id === scenario && state.state === "ready") {
|
|
31
|
+
const retries = await page.evaluate(() => Number(document.documentElement.dataset.adsResourceRetries ?? 0)).catch(() => 0);
|
|
32
|
+
if (retries > 0) console.warn(JSON.stringify({ adsPreviewDiagnostic: { kind: "resource-read-recovery", scenario, retries, failedRequests: failures } }));
|
|
33
|
+
return frame;
|
|
34
|
+
}
|
|
31
35
|
if (state.id === scenario && state.state === "error") throw new Error(state.message || "The MCP App failed before verification.");
|
|
32
36
|
}
|
|
33
37
|
const error = await page.evaluate(() => document.querySelector('#status[data-error="true"]')?.textContent).catch(() => null);
|
|
@@ -8,6 +8,8 @@ module.exports = class AdsBehaviorReporter {
|
|
|
8
8
|
this.cases = [];
|
|
9
9
|
this.errors = [];
|
|
10
10
|
this.active = new Map();
|
|
11
|
+
this.diagnostics = new Map();
|
|
12
|
+
this.diagnosticBuffers = new Map();
|
|
11
13
|
this.startedAt = Date.now();
|
|
12
14
|
this.totalTests = 0;
|
|
13
15
|
}
|
|
@@ -22,9 +24,27 @@ module.exports = class AdsBehaviorReporter {
|
|
|
22
24
|
}
|
|
23
25
|
onTestEnd(test, result) {
|
|
24
26
|
this.active.delete(test.id);
|
|
25
|
-
|
|
27
|
+
const diagnostics = this.diagnostics.get(test.id);
|
|
28
|
+
for (const entry of this.entries(test)) this.cases.push({ ...entry, status: result.status === "passed" && test.expectedStatus === "passed" ? "passed" : ["skipped", "interrupted"].includes(result.status) ? "skipped" : "failed", durationMs: result.duration, workerIndex: result.workerIndex, retry: result.retry, completedAt: new Date().toISOString(), ...(diagnostics?.length ? { diagnostics } : {}), message: result.errors?.map(error => error.message || error.stack || error.value || "The browser runner reported an error without details.").join("\n").slice(0, 1000) });
|
|
29
|
+
this.diagnostics.delete(test.id);
|
|
30
|
+
this.diagnosticBuffers.delete(test.id);
|
|
26
31
|
this.publish();
|
|
27
32
|
}
|
|
33
|
+
onStdErr(chunk, test) {
|
|
34
|
+
if (!test) return;
|
|
35
|
+
const lines = ((this.diagnosticBuffers.get(test.id) ?? "") + String(chunk)).split("\n");
|
|
36
|
+
this.diagnosticBuffers.set(test.id, lines.pop().slice(-4000));
|
|
37
|
+
for (const line of lines) {
|
|
38
|
+
if (line.length > 4000) continue;
|
|
39
|
+
try {
|
|
40
|
+
const diagnostic = JSON.parse(line).adsPreviewDiagnostic;
|
|
41
|
+
if (diagnostic?.kind !== "resource-read-recovery" || typeof diagnostic.scenario !== "string" || !Number.isSafeInteger(diagnostic.retries) || diagnostic.retries < 1) continue;
|
|
42
|
+
const collected = this.diagnostics.get(test.id) ?? [];
|
|
43
|
+
if (collected.length < 5) collected.push({ kind: diagnostic.kind, scenario: diagnostic.scenario.slice(0, 300), retries: diagnostic.retries, failedRequests: (Array.isArray(diagnostic.failedRequests) ? diagnostic.failedRequests : []).slice(0, 5).map(value => String(value).slice(0, 500)) });
|
|
44
|
+
this.diagnostics.set(test.id, collected);
|
|
45
|
+
} catch { /* Ordinary test output is not an ADS startup diagnostic. */ }
|
|
46
|
+
}
|
|
47
|
+
}
|
|
28
48
|
onError(error) {
|
|
29
49
|
if (this.errors.length < 5) this.errors.push(String(error.message || error.stack || error.value || "The browser runner reported a suite error without details.").slice(0, 4000));
|
|
30
50
|
this.publish();
|
package/dist/verification.mjs
CHANGED
|
@@ -310,6 +310,7 @@ export function createVerificationController(root, { reportRoot = root, onProgre
|
|
|
310
310
|
results.push({ unit: check.unit, check: check.id, file: check.file, case: check.case, profile: profileName, status, current, revision: check.inputRevision, runId, completedAt: new Date().toISOString(),
|
|
311
311
|
previewRevision: profile.mode === "browser" ? host?.previewRevision() ?? readPreviewManifest(options)?.revision ?? null : null,
|
|
312
312
|
...(matches.length ? { reportedStatus, durationMs: matches.reduce((sum, item) => sum + (Number.isFinite(item.durationMs) ? Math.max(0, item.durationMs) : 0), 0) } : {}),
|
|
313
|
+
...(matches.some(item => item.diagnostics?.length) ? { startupDiagnostics: matches.flatMap(item => Array.isArray(item.diagnostics) ? item.diagnostics.slice(0, 5) : []).slice(0, 10) } : {}),
|
|
313
314
|
...(runnerFailure ? { runnerExitCode: run.code } : {}),
|
|
314
315
|
execution: progress.cases.find(item => item.unit === check.unit && item.check === check.id)?.state,
|
|
315
316
|
message: [matches.filter(item => item.status !== "passed").map(item => String(item.message || `Case reported ${item.status} without a diagnostic.`).slice(0, 2000)).join("\n"), runnerError ? `${runnerError.message} This check ${matches.length ? `reported ${reportedStatus}` : `was ${progress.cases.find(item => item.unit === check.unit && item.check === check.id)?.state ?? "not reported"}`}; the complete run did not pass.` : !matches.length ? "The selected case did not execute/report. Missing and skipped cases do not pass." : runnerFailure ? `This case reported ${reportedStatus}, but the complete run did not pass. ${runnerFailure}` : ""].filter(Boolean).join("\n"), report: slash(path.relative(reportRoot, report)) });
|
package/docs/ARCHITECTURE.md
CHANGED
|
@@ -213,6 +213,13 @@ Project JavaScript, styles, fonts and UI run only inside that App; the outer
|
|
|
213
213
|
shell forwards resource bytes without applying project styles or executing its
|
|
214
214
|
runtime. This keeps the host neutral while compositions retain their full skin.
|
|
215
215
|
|
|
216
|
+
The ADS host gives inline App documents an `about:srcdoc` base when the App
|
|
217
|
+
provides no explicit base URL. Fragment links then stay inside their own document
|
|
218
|
+
with native scrolling, history and events. The sandbox permits this local base;
|
|
219
|
+
external bases still require declared CSP origins. This belongs to document
|
|
220
|
+
loading and changes no project link or scenario handler. External hosts control
|
|
221
|
+
their own document-loading and CSP behavior.
|
|
222
|
+
|
|
216
223
|
The project compiler publishes a versioned dependency graph: shared runtime and
|
|
217
224
|
foundation assets, plus independently addressable scenario modules. Inside the
|
|
218
225
|
App, a resource loader obtains the selected dependency closure through MCP,
|
|
@@ -222,6 +229,15 @@ scenarios unmounts the previous view while keeping unchanged dependencies cached
|
|
|
222
229
|
Persistence is a host lifecycle choice; a new external widget loads the same
|
|
223
230
|
resources independently. Resource sharing is scoped to an App instance.
|
|
224
231
|
|
|
232
|
+
The showcase's resource bridge can recover a transient fetch failure with at most
|
|
233
|
+
three read attempts and bounded backoff. This applies only to `resources/read`;
|
|
234
|
+
tool calls, assertions and whole checks are never replayed. Cancellation,
|
|
235
|
+
HTTP/protocol/content errors and integrity failures remain failures. Browser
|
|
236
|
+
diagnostics record retries, and verification retains recovered startup reads in
|
|
237
|
+
its case results. Persistent transport failures still block a mutation. External
|
|
238
|
+
hosts own their transport recovery; the reusable App's integrity checks remain
|
|
239
|
+
the same.
|
|
240
|
+
|
|
225
241
|
Managed graph builders publish into a private session directory beside the
|
|
226
242
|
configured manifest. Logical scenario IDs and resource URIs stay unchanged;
|
|
227
243
|
standalone builds retain the configured output and cannot overwrite a live
|
package/docs/BEHAVIORS.md
CHANGED
|
@@ -169,8 +169,23 @@ pass, even if all reported cases claim success. Results retain `reportedStatus`
|
|
|
169
169
|
and `runnerExitCode` and explain the overall failure. Suite-level browser errors and
|
|
170
170
|
bounded runner output appear in diagnostics. `openBehaviorScenario` includes the
|
|
171
171
|
scenario ID and failed browser requests in startup failures; App resource errors
|
|
172
|
-
identify the resource URI.
|
|
173
|
-
|
|
172
|
+
identify the resource URI. The ADS showcase retries only `resources/read` fetch
|
|
173
|
+
transport failures, with at most three attempts and 200/800 ms backoff. Recovered
|
|
174
|
+
startup reads appear in `startupDiagnostics` with retry counts and failed browser
|
|
175
|
+
requests; each retry is also logged in the browser console. This does not retry a
|
|
176
|
+
tool call, assertion, check or complete startup. HTTP/protocol/content errors,
|
|
177
|
+
integrity failures and cancellations do not retry. Persistent loading failures
|
|
178
|
+
still fail the check and block mutations. External hosts control their own
|
|
179
|
+
transport recovery.
|
|
180
|
+
|
|
181
|
+
`net::ERR_NETWORK_CHANGED` reports Chrome's network-change error, not proof that
|
|
182
|
+
the MCP endpoint restarted or that a particular interface changed. To investigate
|
|
183
|
+
an intermittent failure, correlate the saved case timestamps with Chrome's
|
|
184
|
+
network log, server availability and live interface monitoring (for example,
|
|
185
|
+
`ip -ts monitor link address route` on Linux). Interfaces being present, or stable
|
|
186
|
+
after a failure, does not establish the cause. Preserve the draft and original
|
|
187
|
+
diagnostic; do not change a component API, reference example or verification
|
|
188
|
+
policy to compensate for a resource-loading failure.
|
|
174
189
|
|
|
175
190
|
The reporter atomically publishes partial snapshots at test start/end. While a
|
|
176
191
|
run is active, `ads_status.behaviors.progress` exposes the profile, runner budget,
|
package/docs/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.3.16
|
|
4
|
+
|
|
5
|
+
- Recover transient showcase MCP resource fetch failures with bounded read-only
|
|
6
|
+
retries. Keep tool calls, assertions, checks and non-transport failures outside
|
|
7
|
+
recovery; expose recovered startup reads in verification diagnostics and keep
|
|
8
|
+
persistent loading failures blocking. Verify interrupted resource delivery and
|
|
9
|
+
failed delivery against a dummy App, without changing project verification policy.
|
|
10
|
+
|
|
11
|
+
## 0.3.15
|
|
12
|
+
|
|
13
|
+
- Keep fragment links inside inline preview documents by supplying a local
|
|
14
|
+
`about:srcdoc` base in the sandbox host and legacy nested widget. Preserve
|
|
15
|
+
explicit App bases, native link events and opaque origins; retain CSP gates
|
|
16
|
+
for external bases. Verify scrolling, state and bridge continuity in browsers.
|
|
17
|
+
|
|
3
18
|
## 0.3.14
|
|
4
19
|
|
|
5
20
|
- Preserve independent passing behavior outcomes in complete runs with failed
|
package/docs/MCP.md
CHANGED
|
@@ -593,6 +593,13 @@ origin hosts the sandbox proxy; that proxy creates an opaque inner App iframe
|
|
|
593
593
|
and forwards the standard Apps bridge messages. The diagnostic explorer follows
|
|
594
594
|
the same sandbox model. Only the App materializes and executes project resources.
|
|
595
595
|
|
|
596
|
+
For inline documents without an explicit App base URL, ADS supplies
|
|
597
|
+
`<base href="about:srcdoc">` and permits the local `about:` base scheme in CSP.
|
|
598
|
+
Bare and named fragment links retain native in-document navigation and state.
|
|
599
|
+
Explicit App bases remain subject to declared CSP origins. The legacy nested
|
|
600
|
+
widget uses the same document preparation. External hosts own this behavior in
|
|
601
|
+
their loaders; adding scenario click handlers would conceal a host defect.
|
|
602
|
+
|
|
596
603
|
Hosts need Apps support, server resource forwarding, native ESM/import maps and
|
|
597
604
|
a CSP permitting declared `blob:` script/style/font/worker resources. Project
|
|
598
605
|
previews declare no network connections. The host may enforce stricter policy;
|
package/package.json
CHANGED
package/dist/showcase/sandbox.js
DELETED
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
const parentOrigin = new URL(location.href).searchParams.get("parent");
|
|
2
|
-
let view;
|
|
3
|
-
function domains(values = []) {
|
|
4
|
-
return values.filter(value => /^(?:https?:\/\/[a-z0-9.*:[\]-]+(?::\d+)?|data:|blob:|about:)$/i.test(value)).join(" ");
|
|
5
|
-
}
|
|
6
|
-
function policy(csp = {}) {
|
|
7
|
-
const resources = domains(csp.resourceDomains);
|
|
8
|
-
return `default-src 'none';script-src 'unsafe-inline' ${resources};style-src 'unsafe-inline' ${resources};img-src data: ${resources};font-src ${resources || "'none'"};media-src ${resources || "'none'"};worker-src ${resources || "'none'"};connect-src ${domains(csp.connectDomains) || "'none'"};frame-src ${domains(csp.frameDomains) || "'none'"};base-uri ${domains(csp.baseUriDomains) || "'none'"};object-src 'none'`;
|
|
9
|
-
}
|
|
10
|
-
window.addEventListener("message", event => {
|
|
11
|
-
if (event.source === parent && event.origin === parentOrigin) {
|
|
12
|
-
const message = event.data;
|
|
13
|
-
if (message?.method === "ui/notifications/sandbox-resource-ready") {
|
|
14
|
-
const { html, csp } = message.params ?? {};
|
|
15
|
-
if (typeof html !== "string") return;
|
|
16
|
-
const document = new DOMParser().parseFromString(html, "text/html");
|
|
17
|
-
const meta = document.createElement("meta");
|
|
18
|
-
meta.httpEquiv = "Content-Security-Policy";
|
|
19
|
-
meta.content = policy(csp);
|
|
20
|
-
document.head.prepend(meta);
|
|
21
|
-
view?.remove();
|
|
22
|
-
view = window.document.createElement("iframe");
|
|
23
|
-
view.title = "Design-system App";
|
|
24
|
-
view.setAttribute("sandbox", "allow-scripts");
|
|
25
|
-
window.document.body.append(view);
|
|
26
|
-
view.srcdoc = "<!doctype html>" + document.documentElement.outerHTML;
|
|
27
|
-
} else if (message?.jsonrpc === "2.0" && !message.method?.startsWith("ui/notifications/sandbox-")) view?.contentWindow.postMessage(message, "*");
|
|
28
|
-
} else if (event.source === view?.contentWindow && event.data?.jsonrpc === "2.0" && !event.data.method?.startsWith("ui/notifications/sandbox-")) parent.postMessage(event.data, parentOrigin);
|
|
29
|
-
});
|
|
30
|
-
parent.postMessage({ jsonrpc: "2.0", method: "ui/notifications/sandbox-proxy-ready", params: {} }, parentOrigin);
|