@momentiq/dark-factory-cli 3.0.2 → 3.1.0
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/cli.d.ts.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/mode.d.ts.map +1 -1
- package/dist/commands/mode.js +120 -22
- package/dist/commands/mode.js.map +1 -1
- package/dist/commands/skills.d.ts.map +1 -1
- package/dist/commands/skills.js +11 -1
- package/dist/commands/skills.js.map +1 -1
- package/dist/commands/verify.d.ts.map +1 -1
- package/dist/commands/verify.js +113 -8
- package/dist/commands/verify.js.map +1 -1
- package/dist/mcp/tools/skills-install.d.ts.map +1 -1
- package/dist/mcp/tools/skills-install.js +8 -3
- package/dist/mcp/tools/skills-install.js.map +1 -1
- package/dist/mode/critic-registration.d.ts +30 -10
- package/dist/mode/critic-registration.d.ts.map +1 -1
- package/dist/mode/critic-registration.js +31 -10
- package/dist/mode/critic-registration.js.map +1 -1
- package/dist/mode/guard.d.ts.map +1 -1
- package/dist/mode/guard.js +30 -2
- package/dist/mode/guard.js.map +1 -1
- package/dist/mode/init.d.ts +7 -4
- package/dist/mode/init.d.ts.map +1 -1
- package/dist/mode/init.js +146 -12
- package/dist/mode/init.js.map +1 -1
- package/dist/mode/preview-capture.d.ts +3 -0
- package/dist/mode/preview-capture.d.ts.map +1 -0
- package/dist/mode/preview-capture.js +129 -0
- package/dist/mode/preview-capture.js.map +1 -0
- package/dist/mode/preview.d.ts +160 -0
- package/dist/mode/preview.d.ts.map +1 -0
- package/dist/mode/preview.js +522 -0
- package/dist/mode/preview.js.map +1 -0
- package/dist/onboard/seeders/design-md.d.ts.map +1 -1
- package/dist/onboard/seeders/design-md.js +512 -17
- package/dist/onboard/seeders/design-md.js.map +1 -1
- package/dist/skills/install.d.ts +25 -5
- package/dist/skills/install.d.ts.map +1 -1
- package/dist/skills/install.js +34 -17
- package/dist/skills/install.js.map +1 -1
- package/dist/skills/known-skills.d.ts +2 -0
- package/dist/skills/known-skills.d.ts.map +1 -0
- package/dist/skills/known-skills.js +25 -0
- package/dist/skills/known-skills.js.map +1 -0
- package/package.json +2 -2
- package/skills/designer-build/SKILL.md.tmpl +14 -0
- package/skills/designer-handoff/SKILL.md.tmpl +28 -1
- package/skills/verify/producer/README.md +29 -4
- package/skills/verify/producer/playwright-route.sh +10 -0
- package/skills/verify/producer/surface-declaration.ts +373 -0
- package/skills/verify/producer/ui-route.producer.spec.ts +44 -11
|
@@ -0,0 +1,522 @@
|
|
|
1
|
+
// `df mode preview <component-path>` — component-isolation visual evidence
|
|
2
|
+
// (Closes momentiq-ai/dark-factory#357).
|
|
3
|
+
//
|
|
4
|
+
// THE PAIN. Designer Mode's `evidence.visual: required` mandates a visual loop:
|
|
5
|
+
// boot the app, navigate to the changed surface, screenshot it (the `ui-visual`
|
|
6
|
+
// route). On a container-first / k3d repo the app needs auth + seeded data to
|
|
7
|
+
// boot, and a bare component (a `components/Widget.tsx` with no page that renders
|
|
8
|
+
// it) maps to NO navigable route — so the `ui-visual` route FAILS CLOSED
|
|
9
|
+
// (`planCapture` → `uncovered`) and a NON-ENGINEER cannot produce a screenshot.
|
|
10
|
+
// In the #357 dogfood ~5 avenues to a screenshot all dead-ended here.
|
|
11
|
+
//
|
|
12
|
+
// THE FIX (bounded, first version). Render the ONE component in an isolated
|
|
13
|
+
// harness — no full app, no auth, no data — and capture the SAME evidence shape
|
|
14
|
+
// the `ui-visual` route already emits (`agent-reviews/quality-gates/ui/<sha>/
|
|
15
|
+
// <slug>/{aria.snapshot.txt, after.png, meta.json}`, `evidenceKind:"playwright"`).
|
|
16
|
+
// The existing embed/publish path (`discoverUiEvidence` / `buildScreenshotEmbed`
|
|
17
|
+
// / `readUiArtifacts`) consumes it unchanged. This does NOT by itself create a
|
|
18
|
+
// `QualityGateEvidence` gate result — it produces the artifacts that path renders
|
|
19
|
+
// for a human and uploads.
|
|
20
|
+
//
|
|
21
|
+
// This module is the PURE + orchestration half (no browser, no bundler): harness
|
|
22
|
+
// generation and framework detection are pure and unit-tested; `runPreview` takes
|
|
23
|
+
// an injected `CaptureDeps` so the Vite-server + Playwright wiring
|
|
24
|
+
// (`preview-capture.ts`) is never imported by tests. It degrades gracefully —
|
|
25
|
+
// never crashes — when the component genuinely cannot be rendered (no React / no
|
|
26
|
+
// Vite / a server component) or when the local capture tooling is unavailable.
|
|
27
|
+
//
|
|
28
|
+
// FRAMEWORK BOUNDARY (see the PR body — this is the design edge for PJ + the
|
|
29
|
+
// parallel role-redesign): v1 targets the common case, a React client component
|
|
30
|
+
// rendered through Vite. Vue/Svelte/Angular, Webpack/CRA transform, React Server
|
|
31
|
+
// Components, and a prop-fixture/args model are DEFERRED — each degrades with a
|
|
32
|
+
// clear message rather than a wrong render.
|
|
33
|
+
import { mkdtempSync, readFileSync, existsSync, mkdirSync, writeFileSync, rmSync } from "node:fs";
|
|
34
|
+
import { isAbsolute, join, relative, resolve, sep, basename } from "node:path";
|
|
35
|
+
import { resolveCommit } from "../git.js";
|
|
36
|
+
export const ENTRY_BASENAME = "df-preview-entry.tsx";
|
|
37
|
+
export const INDEX_HTML_BASENAME = "index.html";
|
|
38
|
+
/** POSIX-normalize a relative fs path for use as an ES import specifier. */
|
|
39
|
+
function toImportSpecifier(from, to) {
|
|
40
|
+
let spec = relative(from, to).split(sep).join("/");
|
|
41
|
+
if (!spec.startsWith("."))
|
|
42
|
+
spec = `./${spec}`;
|
|
43
|
+
return spec;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate the minimal isolated-render harness for a React component: an entry
|
|
47
|
+
* that mounts JUST that component (placeholder/default props) inside a `<main>`
|
|
48
|
+
* landmark, plus an `index.html`. The `<main>` wrapper guarantees the same
|
|
49
|
+
* structural render floor the `ui-visual` producer asserts (`getByRole("main")`),
|
|
50
|
+
* regardless of what the component itself renders. PURE — returns file contents;
|
|
51
|
+
* the caller writes them.
|
|
52
|
+
*/
|
|
53
|
+
export function generateHarness(input) {
|
|
54
|
+
const { componentAbsPath, harnessDir, componentName, exportName, reactMajor } = input;
|
|
55
|
+
const importSpec = toImportSpecifier(harnessDir, componentAbsPath);
|
|
56
|
+
const importLine = exportName === undefined
|
|
57
|
+
? `import Target from ${JSON.stringify(importSpec)};`
|
|
58
|
+
: `import { ${exportName} as Target } from ${JSON.stringify(importSpec)};`;
|
|
59
|
+
// React major picks the mount API. `import React` is inert under the automatic
|
|
60
|
+
// JSX runtime (plugin-react's default) and covers a classic-runtime consumer.
|
|
61
|
+
const mount = reactMajor >= 18
|
|
62
|
+
? [
|
|
63
|
+
`import { createRoot } from "react-dom/client";`,
|
|
64
|
+
`const el = document.getElementById("df-preview-root");`,
|
|
65
|
+
`if (el) {`,
|
|
66
|
+
` createRoot(el).render(`,
|
|
67
|
+
` <main aria-label=${JSON.stringify(`df preview: ${componentName}`)}>`,
|
|
68
|
+
` <Target />`,
|
|
69
|
+
` </main>,`,
|
|
70
|
+
` );`,
|
|
71
|
+
`}`,
|
|
72
|
+
]
|
|
73
|
+
: [
|
|
74
|
+
`import { render } from "react-dom";`,
|
|
75
|
+
`const el = document.getElementById("df-preview-root");`,
|
|
76
|
+
`if (el) {`,
|
|
77
|
+
` render(`,
|
|
78
|
+
` <main aria-label=${JSON.stringify(`df preview: ${componentName}`)}>`,
|
|
79
|
+
` <Target />`,
|
|
80
|
+
` </main>,`,
|
|
81
|
+
` el,`,
|
|
82
|
+
` );`,
|
|
83
|
+
`}`,
|
|
84
|
+
];
|
|
85
|
+
const entry = [
|
|
86
|
+
`// AUTO-GENERATED by \`df mode preview\` — isolated render harness for`,
|
|
87
|
+
`// ${componentName}. Ephemeral; the command removes this dir after capture.`,
|
|
88
|
+
`import React from "react";`,
|
|
89
|
+
importLine,
|
|
90
|
+
"",
|
|
91
|
+
...mount,
|
|
92
|
+
"",
|
|
93
|
+
].join("\n");
|
|
94
|
+
const html = [
|
|
95
|
+
`<!doctype html>`,
|
|
96
|
+
`<html lang="en">`,
|
|
97
|
+
` <head>`,
|
|
98
|
+
` <meta charset="utf-8" />`,
|
|
99
|
+
` <meta name="viewport" content="width=device-width, initial-scale=1" />`,
|
|
100
|
+
` <title>df preview: ${escapeHtml(componentName)}</title>`,
|
|
101
|
+
` </head>`,
|
|
102
|
+
` <body>`,
|
|
103
|
+
` <div id="df-preview-root"></div>`,
|
|
104
|
+
` <script type="module" src="/${ENTRY_BASENAME}"></script>`,
|
|
105
|
+
` </body>`,
|
|
106
|
+
`</html>`,
|
|
107
|
+
"",
|
|
108
|
+
].join("\n");
|
|
109
|
+
return [
|
|
110
|
+
{ path: ENTRY_BASENAME, contents: entry },
|
|
111
|
+
{ path: INDEX_HTML_BASENAME, contents: html },
|
|
112
|
+
];
|
|
113
|
+
}
|
|
114
|
+
function escapeHtml(s) {
|
|
115
|
+
return s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">");
|
|
116
|
+
}
|
|
117
|
+
const COMPONENT_EXT_RE = /\.(tsx|jsx)$/;
|
|
118
|
+
function parseReactMajor(deps) {
|
|
119
|
+
const raw = deps?.["react"];
|
|
120
|
+
if (!raw)
|
|
121
|
+
return null;
|
|
122
|
+
const m = raw.match(/(\d+)/);
|
|
123
|
+
return m ? Number(m[1]) : null;
|
|
124
|
+
}
|
|
125
|
+
/** Best-effort PascalCase component name from a filename (`user-card.tsx` →
|
|
126
|
+
* `UserCard`, `Button.tsx` → `Button`). */
|
|
127
|
+
export function componentNameFromPath(componentAbsPath) {
|
|
128
|
+
const base = basename(componentAbsPath).replace(COMPONENT_EXT_RE, "");
|
|
129
|
+
const parts = base.split(/[-_.\s]+/).filter(Boolean);
|
|
130
|
+
if (parts.length === 0)
|
|
131
|
+
return "Component";
|
|
132
|
+
return parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join("");
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Resolve which export the harness should mount. Preference order:
|
|
136
|
+
* 1. `export default` present → default import (undefined exportName).
|
|
137
|
+
* 2. a named export matching the PascalCase filename.
|
|
138
|
+
* 3. the first `export function|const <PascalCaseName>`.
|
|
139
|
+
* Returns `{ kind: "none" }` when no export is found (a blocker).
|
|
140
|
+
*/
|
|
141
|
+
export function resolveExport(source, componentName) {
|
|
142
|
+
if (/\bexport\s+default\b/.test(source))
|
|
143
|
+
return { kind: "default" };
|
|
144
|
+
const named = new Set();
|
|
145
|
+
const re = /\bexport\s+(?:async\s+)?(?:function|const|class)\s+([A-Za-z_$][\w$]*)/g;
|
|
146
|
+
let m;
|
|
147
|
+
while ((m = re.exec(source)) !== null)
|
|
148
|
+
named.add(m[1]);
|
|
149
|
+
// `export { Foo, Bar as Baz }`
|
|
150
|
+
const reBlock = /\bexport\s*\{([^}]*)\}/g;
|
|
151
|
+
while ((m = reBlock.exec(source)) !== null) {
|
|
152
|
+
for (const piece of m[1].split(",")) {
|
|
153
|
+
const asMatch = piece.trim().match(/(?:\bas\s+([A-Za-z_$][\w$]*))$/);
|
|
154
|
+
const name = asMatch ? asMatch[1] : piece.trim().split(/\s+/)[0];
|
|
155
|
+
if (name)
|
|
156
|
+
named.add(name);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (named.has(componentName))
|
|
160
|
+
return { kind: "named", name: componentName };
|
|
161
|
+
// First PascalCase named export (React components are PascalCase by convention).
|
|
162
|
+
for (const n of named) {
|
|
163
|
+
if (/^[A-Z]/.test(n))
|
|
164
|
+
return { kind: "named", name: n };
|
|
165
|
+
}
|
|
166
|
+
return { kind: "none" };
|
|
167
|
+
}
|
|
168
|
+
/** Strong-signal heuristic: is this a React Server Component (unrenderable in a
|
|
169
|
+
* client-only harness)? Conservative — only fires on unambiguous signals so an
|
|
170
|
+
* ordinary client component is never false-blocked. */
|
|
171
|
+
function looksLikeServerComponent(source) {
|
|
172
|
+
const hasUseClient = /^\s*['"]use client['"]\s*;?/m.test(source);
|
|
173
|
+
if (hasUseClient)
|
|
174
|
+
return false;
|
|
175
|
+
// Catches both `import 'server-only'` (side-effect) and `... from 'server-only'`.
|
|
176
|
+
if (/import[^;\n]*['"]server-only['"]/.test(source))
|
|
177
|
+
return true;
|
|
178
|
+
// An `async` default component only makes sense as an RSC.
|
|
179
|
+
if (/\bexport\s+default\s+async\s+function\b/.test(source))
|
|
180
|
+
return true;
|
|
181
|
+
if (/\bexport\s+async\s+function\s+[A-Z]/.test(source))
|
|
182
|
+
return true;
|
|
183
|
+
return false;
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Decide whether the component can be rendered via the generated Vite harness,
|
|
187
|
+
* and gather advisories. PURE — no fs, no network.
|
|
188
|
+
*/
|
|
189
|
+
export function detectStrategy(input) {
|
|
190
|
+
const { componentAbsPath, source, packageDeps } = input;
|
|
191
|
+
const componentName = componentNameFromPath(componentAbsPath);
|
|
192
|
+
const reactMajor = parseReactMajor(packageDeps) ?? 18;
|
|
193
|
+
const storybook = !!packageDeps && Object.keys(packageDeps).some((d) => d.startsWith("@storybook/"));
|
|
194
|
+
const ladle = !!packageDeps && "@ladle/react" in packageDeps;
|
|
195
|
+
const warnings = [];
|
|
196
|
+
if (storybook || ladle) {
|
|
197
|
+
warnings.push(`${storybook ? "Storybook" : "Ladle"} detected — v1 renders via the generated ` +
|
|
198
|
+
`Vite harness; native story capture is deferred (#357 follow-up).`);
|
|
199
|
+
}
|
|
200
|
+
const base = (blocker) => ({
|
|
201
|
+
engine: blocker ? "unsupported" : "vite-harness",
|
|
202
|
+
componentName,
|
|
203
|
+
reactMajor,
|
|
204
|
+
storybook,
|
|
205
|
+
ladle,
|
|
206
|
+
warnings,
|
|
207
|
+
...(blocker ? { blocker } : {}),
|
|
208
|
+
});
|
|
209
|
+
if (!COMPONENT_EXT_RE.test(componentAbsPath)) {
|
|
210
|
+
return base({
|
|
211
|
+
code: "not-a-component-file",
|
|
212
|
+
message: `df mode preview targets a React component file (.tsx/.jsx). "${basename(componentAbsPath)}" ` +
|
|
213
|
+
`is not one. Point at the component's .tsx/.jsx source.`,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
const react = parseReactMajor(packageDeps);
|
|
217
|
+
if (react === null) {
|
|
218
|
+
return base({
|
|
219
|
+
code: "no-react",
|
|
220
|
+
message: "No `react` dependency found in this repo's package.json. v1 previews React " +
|
|
221
|
+
"components only (Vue/Svelte/Angular are deferred — see #357). Install react, or " +
|
|
222
|
+
"use your framework's own component sandbox.",
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
const hasVite = !!packageDeps && ("vite" in packageDeps || "@vitejs/plugin-react" in packageDeps);
|
|
226
|
+
if (!hasVite) {
|
|
227
|
+
return base({
|
|
228
|
+
code: "no-vite",
|
|
229
|
+
message: "No `vite` / `@vitejs/plugin-react` found. v1's generated harness transforms the " +
|
|
230
|
+
"component with Vite (the common React/Vite/Next-client case). Webpack/CRA transform " +
|
|
231
|
+
"is deferred (#357). Add vite + @vitejs/plugin-react as devDependencies, or add a " +
|
|
232
|
+
"Storybook/Ladle setup.",
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
if (looksLikeServerComponent(source)) {
|
|
236
|
+
return base({
|
|
237
|
+
code: "server-component",
|
|
238
|
+
message: "This looks like a React Server Component (no `\"use client\"`, and an async/server-only " +
|
|
239
|
+
"component). It cannot mount in a client-only harness. Add `\"use client\"` if it is " +
|
|
240
|
+
"actually a client component, or preview a client component it renders. RSC capture is " +
|
|
241
|
+
"deferred (#357).",
|
|
242
|
+
});
|
|
243
|
+
}
|
|
244
|
+
const exp = resolveExport(source, componentName);
|
|
245
|
+
if (exp.kind === "none") {
|
|
246
|
+
return base({
|
|
247
|
+
code: "no-export",
|
|
248
|
+
message: `No exported component found in ${basename(componentAbsPath)}. v1 mounts the default export, ` +
|
|
249
|
+
`a named export matching the filename, or the first PascalCase named export.`,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
const result = base();
|
|
253
|
+
if (exp.kind === "named")
|
|
254
|
+
result.exportName = exp.name;
|
|
255
|
+
return result;
|
|
256
|
+
}
|
|
257
|
+
/** Thrown by a `CaptureDeps.capture` when the browser cannot be resolved/launched
|
|
258
|
+
* (Playwright not installed, Chromium binary absent, missing system deps). This
|
|
259
|
+
* is the ONLY capture failure that degrades softly (exit 2, "reached the capture
|
|
260
|
+
* step") — a Vite transform error, a component runtime exception, missing props,
|
|
261
|
+
* or an `fs.allow`-blocked import is a REAL failure and surfaces loudly (exit 1). */
|
|
262
|
+
export class BrowserUnavailableError extends Error {
|
|
263
|
+
constructor(message) {
|
|
264
|
+
super(message);
|
|
265
|
+
this.name = "BrowserUnavailableError";
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
/** Secondary heuristic (belt-and-suspenders alongside `BrowserUnavailableError`):
|
|
269
|
+
* recognize a genuine missing-browser / launch / install failure from its message
|
|
270
|
+
* so a raw Playwright error is still classified as degrade-soft, while a render or
|
|
271
|
+
* transform error is NOT. Kept deliberately narrow. */
|
|
272
|
+
export function isBrowserUnavailable(err) {
|
|
273
|
+
if (err instanceof BrowserUnavailableError)
|
|
274
|
+
return true;
|
|
275
|
+
const msg = (err instanceof Error ? err.message : String(err)).toLowerCase();
|
|
276
|
+
return (/executable doesn'?t exist/.test(msg) ||
|
|
277
|
+
/playwright install/.test(msg) ||
|
|
278
|
+
/host system is missing dependencies/.test(msg) ||
|
|
279
|
+
/missing dependencies to run browser/.test(msg) ||
|
|
280
|
+
/cannot resolve "(playwright|@playwright\/test)"/.test(msg) ||
|
|
281
|
+
/looks like playwright.* was just installed/.test(msg));
|
|
282
|
+
}
|
|
283
|
+
function sanitizeSlug(raw) {
|
|
284
|
+
const s = raw
|
|
285
|
+
.replace(COMPONENT_EXT_RE, "")
|
|
286
|
+
.replace(/[^a-z0-9-]+/gi, "-")
|
|
287
|
+
.replace(/-+/g, "-")
|
|
288
|
+
.replace(/^-|-$/g, "")
|
|
289
|
+
.toLowerCase();
|
|
290
|
+
return s || "component";
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* A safe evidence slug is a SINGLE path segment: filesystem-safe chars only, and
|
|
294
|
+
* never `.` / `..` / anything with a separator. The slug is interpolated into the
|
|
295
|
+
* evidence path (`agent-reviews/quality-gates/ui/<sha>/<slug>/…`), so an operator
|
|
296
|
+
* `--slug ../../..` would otherwise traverse OUT of the evidence tree and clobber
|
|
297
|
+
* arbitrary files. The auto-derived slug is already safe (`sanitizeSlug`); this
|
|
298
|
+
* fail-closes an explicit `--slug`. Exported for the traversal regression test.
|
|
299
|
+
*/
|
|
300
|
+
export function isSafeSlug(slug) {
|
|
301
|
+
if (slug === "" || slug === "." || slug === "..")
|
|
302
|
+
return false;
|
|
303
|
+
if (slug.includes("/") || slug.includes("\\"))
|
|
304
|
+
return false;
|
|
305
|
+
return /^[A-Za-z0-9._-]+$/.test(slug);
|
|
306
|
+
}
|
|
307
|
+
function mergedDeps(pkg) {
|
|
308
|
+
if (!pkg)
|
|
309
|
+
return null;
|
|
310
|
+
const out = {};
|
|
311
|
+
for (const key of ["dependencies", "devDependencies", "peerDependencies"]) {
|
|
312
|
+
const block = pkg[key];
|
|
313
|
+
if (block && typeof block === "object") {
|
|
314
|
+
for (const [k, v] of Object.entries(block)) {
|
|
315
|
+
if (typeof v === "string")
|
|
316
|
+
out[k] = v;
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
return out;
|
|
321
|
+
}
|
|
322
|
+
function readPackageDeps(cwd) {
|
|
323
|
+
const p = join(cwd, "package.json");
|
|
324
|
+
if (!existsSync(p))
|
|
325
|
+
return null;
|
|
326
|
+
try {
|
|
327
|
+
return mergedDeps(JSON.parse(readFileSync(p, "utf8")));
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
return null;
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
/**
|
|
334
|
+
* Render one component in isolation and write `ui-visual`-shaped evidence.
|
|
335
|
+
* Never throws for an expected failure — returns a `degraded`/`error` result
|
|
336
|
+
* with an actionable message and the right exit code.
|
|
337
|
+
*/
|
|
338
|
+
export async function runPreview(opts, deps) {
|
|
339
|
+
const { cwd } = opts;
|
|
340
|
+
const port = opts.port ?? 5199;
|
|
341
|
+
const componentAbsPath = isAbsolute(opts.componentPath)
|
|
342
|
+
? opts.componentPath
|
|
343
|
+
: resolve(cwd, opts.componentPath);
|
|
344
|
+
const relForLog = relative(cwd, componentAbsPath).split(sep).join("/") || opts.componentPath;
|
|
345
|
+
const slug = opts.slug ?? sanitizeSlug(basename(componentAbsPath));
|
|
346
|
+
// Fail closed on an unsafe slug BEFORE it is interpolated into any path — an
|
|
347
|
+
// explicit `--slug ../../..` must not traverse out of the evidence tree.
|
|
348
|
+
if (!isSafeSlug(slug)) {
|
|
349
|
+
return {
|
|
350
|
+
status: "error",
|
|
351
|
+
exitCode: 1,
|
|
352
|
+
slug,
|
|
353
|
+
warnings: [],
|
|
354
|
+
message: `df mode preview: invalid --slug "${slug}". A slug must be a single path ` +
|
|
355
|
+
`segment matching [A-Za-z0-9._-] (no "/", "\\", "." or ".."). No evidence written.`,
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
if (!existsSync(componentAbsPath)) {
|
|
359
|
+
return {
|
|
360
|
+
status: "error",
|
|
361
|
+
exitCode: 1,
|
|
362
|
+
slug,
|
|
363
|
+
warnings: [],
|
|
364
|
+
message: `df mode preview: component not found: ${opts.componentPath}`,
|
|
365
|
+
};
|
|
366
|
+
}
|
|
367
|
+
const source = readFileSync(componentAbsPath, "utf8");
|
|
368
|
+
const detect = detectStrategy({
|
|
369
|
+
cwd,
|
|
370
|
+
componentAbsPath,
|
|
371
|
+
source,
|
|
372
|
+
packageDeps: readPackageDeps(cwd),
|
|
373
|
+
});
|
|
374
|
+
if (detect.blocker) {
|
|
375
|
+
return {
|
|
376
|
+
status: "degraded",
|
|
377
|
+
exitCode: 2,
|
|
378
|
+
slug,
|
|
379
|
+
warnings: detect.warnings,
|
|
380
|
+
message: `df mode preview: cannot render ${relForLog} — ${detect.blocker.message}`,
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const sha = await resolveHeadOrWorktree(cwd);
|
|
384
|
+
const harnessDir = mkdtempSync(join(cwd, ".df-preview-"));
|
|
385
|
+
let server;
|
|
386
|
+
try {
|
|
387
|
+
for (const f of generateHarness({
|
|
388
|
+
componentAbsPath,
|
|
389
|
+
harnessDir,
|
|
390
|
+
componentName: detect.componentName,
|
|
391
|
+
reactMajor: detect.reactMajor,
|
|
392
|
+
...(detect.exportName !== undefined ? { exportName: detect.exportName } : {}),
|
|
393
|
+
})) {
|
|
394
|
+
writeFileSync(join(harnessDir, f.path), f.contents, "utf8");
|
|
395
|
+
}
|
|
396
|
+
try {
|
|
397
|
+
server = await deps.startServer({ cwd, harnessDir, port });
|
|
398
|
+
}
|
|
399
|
+
catch (err) {
|
|
400
|
+
return {
|
|
401
|
+
status: "degraded",
|
|
402
|
+
exitCode: 2,
|
|
403
|
+
slug,
|
|
404
|
+
warnings: detect.warnings,
|
|
405
|
+
message: `df mode preview: reached harness build but could NOT start the isolated Vite dev ` +
|
|
406
|
+
`server for ${relForLog} (${errMsg(err)}). Ensure \`vite\` + \`@vitejs/plugin-react\` ` +
|
|
407
|
+
`are installed in this repo. No evidence written.`,
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
let captured;
|
|
411
|
+
try {
|
|
412
|
+
captured = await deps.capture({ url: server.url, cwd });
|
|
413
|
+
}
|
|
414
|
+
catch (err) {
|
|
415
|
+
// Distinguish a genuinely-unavailable browser (soft-degrade — the render
|
|
416
|
+
// itself was fine, only the screenshot couldn't be taken HERE) from a REAL
|
|
417
|
+
// failure: a Vite transform error, a component runtime exception, missing
|
|
418
|
+
// required props, or a component import blocked by Vite `fs.allow`. The
|
|
419
|
+
// latter must surface LOUDLY (exit 1) — reporting it as "degraded
|
|
420
|
+
// gracefully" would hide a broken component behind a false soft-skip.
|
|
421
|
+
if (isBrowserUnavailable(err)) {
|
|
422
|
+
return {
|
|
423
|
+
status: "degraded",
|
|
424
|
+
exitCode: 2,
|
|
425
|
+
slug,
|
|
426
|
+
warnings: detect.warnings,
|
|
427
|
+
message: `df mode preview: reached the capture step for ${relForLog} but the browser is ` +
|
|
428
|
+
`unavailable (${errMsg(err)}). Install it with \`npx playwright install chromium\` ` +
|
|
429
|
+
`(and \`npm i -D playwright\` if absent). The isolated render succeeded; only the ` +
|
|
430
|
+
`screenshot could not be taken here. No evidence written.`,
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return {
|
|
434
|
+
status: "error",
|
|
435
|
+
exitCode: 1,
|
|
436
|
+
slug,
|
|
437
|
+
warnings: detect.warnings,
|
|
438
|
+
message: `df mode preview: the isolated render of ${relForLog} FAILED (${errMsg(err)}). This is ` +
|
|
439
|
+
`NOT a missing-browser problem — it is typically a Vite transform error, a component ` +
|
|
440
|
+
`runtime exception, missing required props, or an import outside the repo (Vite ` +
|
|
441
|
+
`fs.allow). Fix the component or provide props, then re-run. No evidence written.`,
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
const evidenceDir = writeEvidence({
|
|
445
|
+
cwd,
|
|
446
|
+
sha,
|
|
447
|
+
slug,
|
|
448
|
+
componentRel: relForLog,
|
|
449
|
+
componentName: detect.componentName,
|
|
450
|
+
baseURL: server.url,
|
|
451
|
+
aria: captured.aria,
|
|
452
|
+
png: captured.png,
|
|
453
|
+
warnings: detect.warnings,
|
|
454
|
+
});
|
|
455
|
+
return {
|
|
456
|
+
status: "captured",
|
|
457
|
+
exitCode: 0,
|
|
458
|
+
slug,
|
|
459
|
+
warnings: detect.warnings,
|
|
460
|
+
evidenceDir,
|
|
461
|
+
message: `df mode preview: captured isolated render of ${relForLog} → ${relative(cwd, evidenceDir)}/` +
|
|
462
|
+
` (after.png + aria.snapshot.txt + meta.json, evidenceKind=playwright).`,
|
|
463
|
+
};
|
|
464
|
+
}
|
|
465
|
+
finally {
|
|
466
|
+
if (server) {
|
|
467
|
+
try {
|
|
468
|
+
await server.close();
|
|
469
|
+
}
|
|
470
|
+
catch {
|
|
471
|
+
/* best-effort teardown */
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
rmSync(harnessDir, { recursive: true, force: true });
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
async function resolveHeadOrWorktree(cwd) {
|
|
478
|
+
try {
|
|
479
|
+
return await resolveCommit("HEAD", cwd);
|
|
480
|
+
}
|
|
481
|
+
catch {
|
|
482
|
+
// No commit yet (fresh repo) — evidence is still useful for the designer loop.
|
|
483
|
+
return "working-tree";
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
function errMsg(err) {
|
|
487
|
+
return err instanceof Error ? err.message : String(err);
|
|
488
|
+
}
|
|
489
|
+
/** Write the exact `ui-visual` evidence shape so the existing embed/publish path
|
|
490
|
+
* (`discoverUiEvidence` / `buildScreenshotEmbed` / `readUiArtifacts`) consumes
|
|
491
|
+
* it unchanged. Returns the absolute evidence dir. */
|
|
492
|
+
function writeEvidence(input) {
|
|
493
|
+
const dir = join(input.cwd, "agent-reviews", "quality-gates", "ui", input.sha, input.slug);
|
|
494
|
+
mkdirSync(dir, { recursive: true });
|
|
495
|
+
writeFileSync(join(dir, "after.png"), input.png);
|
|
496
|
+
writeFileSync(join(dir, "aria.snapshot.txt"), `${input.aria.trim()}\n`, "utf8");
|
|
497
|
+
const meta = {
|
|
498
|
+
surface: input.slug,
|
|
499
|
+
// `path` is the embed's human title (buildScreenshotEmbed reads meta.path).
|
|
500
|
+
path: `component:${input.componentRel}`,
|
|
501
|
+
covers: input.componentRel,
|
|
502
|
+
sha: input.sha,
|
|
503
|
+
capturedAt: new Date().toISOString(),
|
|
504
|
+
baseURL: input.baseURL,
|
|
505
|
+
beforeBaseURL: null,
|
|
506
|
+
ariaSnapshotBytes: Buffer.byteLength(input.aria, "utf8"),
|
|
507
|
+
// Keep the same evidenceKind/route as the ui-visual producer so publish.ts
|
|
508
|
+
// uploads the file artifacts and the embed renders them identically.
|
|
509
|
+
evidenceKind: "playwright",
|
|
510
|
+
route: "ui-visual",
|
|
511
|
+
floor: ["aria-snapshot", "after-screenshot"],
|
|
512
|
+
beforeScreenshot: null,
|
|
513
|
+
// HONESTY marker: this is an isolated component render, not a navigated route.
|
|
514
|
+
capture: "component-isolation",
|
|
515
|
+
componentName: input.componentName,
|
|
516
|
+
engine: "vite-harness",
|
|
517
|
+
warnings: input.warnings,
|
|
518
|
+
};
|
|
519
|
+
writeFileSync(join(dir, "meta.json"), `${JSON.stringify(meta, null, 2)}\n`, "utf8");
|
|
520
|
+
return dir;
|
|
521
|
+
}
|
|
522
|
+
//# sourceMappingURL=preview.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preview.js","sourceRoot":"","sources":["../../src/mode/preview.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"design-md.d.ts","sourceRoot":"","sources":["../../../src/onboard/seeders/design-md.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"design-md.d.ts","sourceRoot":"","sources":["../../../src/onboard/seeders/design-md.ts"],"names":[],"mappings":"AAqCA,OAAO,KAAK,EAAE,MAAM,EAAe,MAAM,YAAY,CAAC;AAqoBtD,eAAO,MAAM,cAAc,EAAE,MA+B5B,CAAC"}
|