ugly-app 0.1.490 → 0.1.492
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/index.js +22 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/inspectUx.d.ts +64 -0
- package/dist/cli/inspectUx.d.ts.map +1 -0
- package/dist/cli/inspectUx.js +245 -0
- package/dist/cli/inspectUx.js.map +1 -0
- package/dist/cli/version.d.ts +1 -1
- package/dist/cli/version.js +1 -1
- package/dist/markdown/client/ProseMirrorEditor/schema.d.ts +4 -4
- package/package.json +1 -1
- package/src/cli/index.ts +39 -0
- package/src/cli/inspectUx.ts +302 -0
- package/src/cli/version.ts +1 -1
- package/templates/.claude/skills/bot-swarm/SKILL.md +67 -12
- package/templates/bots/feedback/run-bot.mjs +217 -57
package/dist/cli/index.js
CHANGED
|
@@ -360,6 +360,28 @@ program
|
|
|
360
360
|
process.exit(1);
|
|
361
361
|
}
|
|
362
362
|
});
|
|
363
|
+
program
|
|
364
|
+
.command('inspect:ux')
|
|
365
|
+
.description('Drive the local dev server through an action script and emit the structured UglyInspectReport (CLS, longTasks, overlaps, safe-area, keyboard, animations, popups). Use --actions to compose navigate/click/focus/hover/scroll/wait/simulate_keyboard probes.')
|
|
366
|
+
.option('--url <url>', 'Base URL (default http://localhost:<localPort>)')
|
|
367
|
+
.option('--path <path>', 'Route path to probe (default /)', '/')
|
|
368
|
+
.option('--device <kind>', 'desktop | ios | android', 'desktop')
|
|
369
|
+
.option('--actions <json>', 'Action array as JSON literal OR path to a JSON file. Each entry is one of: {navigate}, {click}, {focus}, {hover}, {scroll:{to|selector}}, {wait}, {simulate_keyboard}')
|
|
370
|
+
.option('--settle-ms <ms>', 'Settle time after the last action', '800')
|
|
371
|
+
.option('--viewport <wxh>', 'Viewport WxH (e.g. 390x844)')
|
|
372
|
+
.option('--token <token>', 'Bot auth token (cookie). Falls back to $BOT_TOKEN.')
|
|
373
|
+
.option('--timeout-ms <ms>', 'Per-step Playwright timeout', '60000')
|
|
374
|
+
.option('--out <path>', 'Write JSON report to this path instead of stdout')
|
|
375
|
+
.action(async (opts) => {
|
|
376
|
+
try {
|
|
377
|
+
const { runInspectUxCli } = await import('./inspectUx.js');
|
|
378
|
+
await runInspectUxCli(opts);
|
|
379
|
+
}
|
|
380
|
+
catch (e) {
|
|
381
|
+
console.error(e.message);
|
|
382
|
+
process.exit(1);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
363
385
|
program
|
|
364
386
|
.command('dev-logs')
|
|
365
387
|
.description('Show local dev logs from JSONL files')
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import type { UglyInspectReport } from '../client/inspect/types.js';
|
|
2
|
+
export type InspectUxAction = {
|
|
3
|
+
navigate: string;
|
|
4
|
+
} | {
|
|
5
|
+
click: string;
|
|
6
|
+
} | {
|
|
7
|
+
focus: string;
|
|
8
|
+
} | {
|
|
9
|
+
hover: string;
|
|
10
|
+
} | {
|
|
11
|
+
scroll: {
|
|
12
|
+
to: number;
|
|
13
|
+
} | {
|
|
14
|
+
selector: string;
|
|
15
|
+
};
|
|
16
|
+
} | {
|
|
17
|
+
wait: number;
|
|
18
|
+
} | {
|
|
19
|
+
simulate_keyboard: boolean | number;
|
|
20
|
+
};
|
|
21
|
+
export interface InspectUxOptions {
|
|
22
|
+
url?: string;
|
|
23
|
+
urlPath?: string;
|
|
24
|
+
device?: 'desktop' | 'ios' | 'android';
|
|
25
|
+
actions?: InspectUxAction[];
|
|
26
|
+
settleMs?: number;
|
|
27
|
+
viewport?: {
|
|
28
|
+
width: number;
|
|
29
|
+
height: number;
|
|
30
|
+
};
|
|
31
|
+
token?: string;
|
|
32
|
+
outPath?: string;
|
|
33
|
+
json?: boolean;
|
|
34
|
+
timeoutMs?: number;
|
|
35
|
+
}
|
|
36
|
+
export interface InspectUxResult {
|
|
37
|
+
report: UglyInspectReport;
|
|
38
|
+
url: string;
|
|
39
|
+
device: 'desktop' | 'ios' | 'android';
|
|
40
|
+
durationMs: number;
|
|
41
|
+
}
|
|
42
|
+
export declare function inspectUx(opts: InspectUxOptions): Promise<InspectUxResult>;
|
|
43
|
+
/**
|
|
44
|
+
* Parse `--actions <json>`. Accepts either a JSON array literal or a
|
|
45
|
+
* path to a JSON file. Validates each entry against the known action
|
|
46
|
+
* shapes so the caller fails fast instead of inside Playwright.
|
|
47
|
+
*/
|
|
48
|
+
export declare function parseActionsArg(arg: string): InspectUxAction[];
|
|
49
|
+
export declare function parseViewport(arg: string): {
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
};
|
|
53
|
+
export declare function runInspectUxCli(opts: {
|
|
54
|
+
url?: string;
|
|
55
|
+
path?: string;
|
|
56
|
+
device?: string;
|
|
57
|
+
actions?: string;
|
|
58
|
+
settleMs?: string;
|
|
59
|
+
viewport?: string;
|
|
60
|
+
token?: string;
|
|
61
|
+
out?: string;
|
|
62
|
+
timeoutMs?: string;
|
|
63
|
+
}): Promise<void>;
|
|
64
|
+
//# sourceMappingURL=inspectUx.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectUx.d.ts","sourceRoot":"","sources":["../../src/cli/inspectUx.ts"],"names":[],"mappings":"AA+BA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAEpE,MAAM,MAAM,eAAe,GACvB;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,GACpB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,MAAM,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,GACjD;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,GAChB;IAAE,iBAAiB,EAAE,OAAO,GAAG,MAAM,CAAA;CAAE,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;IACvC,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,iBAAiB,CAAC;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,SAAS,GAAG,KAAK,GAAG,SAAS,CAAC;IACtC,UAAU,EAAE,MAAM,CAAC;CACpB;AAID,wBAAsB,SAAS,CAC7B,IAAI,EAAE,gBAAgB,GACrB,OAAO,CAAC,eAAe,CAAC,CA6E1B;AAiED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,eAAe,EAAE,CAe9D;AAgCD,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAI5E;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE;IAC1C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyBhB"}
|
|
@@ -0,0 +1,245 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ugly-app inspect:ux` — drive the local dev server through an action
|
|
3
|
+
* script and emit the structured UglyInspectReport.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the action schema used by ugly-studio's `inspect_ux` coding-
|
|
6
|
+
* agent tool (navigate / click / focus / hover / scroll / wait /
|
|
7
|
+
* simulate_keyboard) so the same probe payload is usable from:
|
|
8
|
+
* - studio coding-agent (tool: inspect_ux)
|
|
9
|
+
* - claude-code CLI, copilot, the bot-swarm driver (this CLI)
|
|
10
|
+
*
|
|
11
|
+
* The probe boots headless Chromium against the project's dev server,
|
|
12
|
+
* calls `window.__uglyInspectMark()`, runs the action list, settles,
|
|
13
|
+
* then reads `window.__uglyInspect({ since: mark })`. The full report
|
|
14
|
+
* is written to stdout as JSON (or `--out <path>`).
|
|
15
|
+
*
|
|
16
|
+
* Requires the project's dev server to be running on
|
|
17
|
+
* `http://localhost:<localPort>` (override with `--url`) and the
|
|
18
|
+
* project to be built on ugly-app ≥ 0.1.489 (the version that ships
|
|
19
|
+
* `window.__uglyInspect`).
|
|
20
|
+
*
|
|
21
|
+
* Why a separate CLI when studio already has the tool: the bot-swarm
|
|
22
|
+
* driver (`bots/feedback/run-bot.mjs`) and any non-studio harness
|
|
23
|
+
* (claude-code, copilot) can't invoke studio's tool. Without this CLI
|
|
24
|
+
* those callers fall back to static screenshots + ad-hoc Playwright,
|
|
25
|
+
* which is exactly the gap that motivated this command — animations
|
|
26
|
+
* and CLS spikes need a measurement window driven by real actions, not
|
|
27
|
+
* a frozen frame.
|
|
28
|
+
*/
|
|
29
|
+
import fs from 'node:fs';
|
|
30
|
+
import path from 'node:path';
|
|
31
|
+
import { getLocalPort } from '../shared/Defaults.js';
|
|
32
|
+
const AUTH_COOKIE = 'auth_token';
|
|
33
|
+
export async function inspectUx(opts) {
|
|
34
|
+
const started = Date.now();
|
|
35
|
+
const baseUrl = (opts.url ?? `http://localhost:${getLocalPort()}`).replace(/\/+$/, '');
|
|
36
|
+
const urlPath = opts.urlPath ?? '/';
|
|
37
|
+
const device = opts.device ?? 'desktop';
|
|
38
|
+
const settleMs = opts.settleMs ?? 800;
|
|
39
|
+
const timeoutMs = opts.timeoutMs ?? 60_000;
|
|
40
|
+
const target = new URL(urlPath.startsWith('/') ? urlPath : `/${urlPath}`, baseUrl);
|
|
41
|
+
if (device !== 'desktop')
|
|
42
|
+
target.searchParams.set('app', device);
|
|
43
|
+
// Dynamic import so missing `playwright` produces a friendly error
|
|
44
|
+
// (the package is not a runtime dependency of ugly-app — consumer
|
|
45
|
+
// projects install it explicitly via `npx playwright install chromium`).
|
|
46
|
+
let chromium;
|
|
47
|
+
try {
|
|
48
|
+
({ chromium } = await import('playwright'));
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw new Error("Playwright is not installed in this project. Run `npm i -D playwright && npx playwright install chromium`, then retry `ugly-app inspect:ux`.");
|
|
52
|
+
}
|
|
53
|
+
const browser = await chromium.launch({ headless: true });
|
|
54
|
+
try {
|
|
55
|
+
const ctx = await browser.newContext(opts.viewport ? { viewport: opts.viewport } : undefined);
|
|
56
|
+
if (opts.token) {
|
|
57
|
+
await ctx.addCookies([
|
|
58
|
+
{
|
|
59
|
+
name: AUTH_COOKIE,
|
|
60
|
+
value: opts.token,
|
|
61
|
+
url: baseUrl,
|
|
62
|
+
},
|
|
63
|
+
]);
|
|
64
|
+
}
|
|
65
|
+
const page = await ctx.newPage();
|
|
66
|
+
page.setDefaultTimeout(timeoutMs);
|
|
67
|
+
await page.goto(target.toString(), {
|
|
68
|
+
waitUntil: 'load',
|
|
69
|
+
timeout: timeoutMs,
|
|
70
|
+
});
|
|
71
|
+
await page.waitForSelector('[data-id]', { timeout: timeoutMs });
|
|
72
|
+
const mark = await page.evaluate(() => {
|
|
73
|
+
return window.__uglyInspectMark?.() ?? Date.now();
|
|
74
|
+
});
|
|
75
|
+
for (const action of opts.actions ?? []) {
|
|
76
|
+
await runAction(page, action);
|
|
77
|
+
}
|
|
78
|
+
await page.waitForTimeout(settleMs);
|
|
79
|
+
const report = await page.evaluate((since) => {
|
|
80
|
+
if (!window.__uglyInspect) {
|
|
81
|
+
throw new Error('window.__uglyInspect not installed — is this an ugly-app project on >= 0.1.489?');
|
|
82
|
+
}
|
|
83
|
+
return window.__uglyInspect({ since });
|
|
84
|
+
}, mark);
|
|
85
|
+
return {
|
|
86
|
+
report,
|
|
87
|
+
url: target.toString(),
|
|
88
|
+
device,
|
|
89
|
+
durationMs: Date.now() - started,
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
finally {
|
|
93
|
+
await browser.close();
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
async function runAction(page, action) {
|
|
97
|
+
if ('navigate' in action) {
|
|
98
|
+
await page.evaluate((to) => {
|
|
99
|
+
window.history.pushState({}, '', to);
|
|
100
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
101
|
+
}, action.navigate);
|
|
102
|
+
}
|
|
103
|
+
else if ('click' in action) {
|
|
104
|
+
await page.evaluate((sel) => {
|
|
105
|
+
const el = document.querySelector(sel);
|
|
106
|
+
if (el && el instanceof HTMLElement)
|
|
107
|
+
el.click();
|
|
108
|
+
}, action.click);
|
|
109
|
+
}
|
|
110
|
+
else if ('focus' in action) {
|
|
111
|
+
await page.evaluate((sel) => {
|
|
112
|
+
const el = document.querySelector(sel);
|
|
113
|
+
if (el && el instanceof HTMLElement)
|
|
114
|
+
el.focus();
|
|
115
|
+
}, action.focus);
|
|
116
|
+
}
|
|
117
|
+
else if ('hover' in action) {
|
|
118
|
+
await page.evaluate((sel) => {
|
|
119
|
+
const el = document.querySelector(sel);
|
|
120
|
+
if (!(el instanceof HTMLElement))
|
|
121
|
+
return;
|
|
122
|
+
const rect = el.getBoundingClientRect();
|
|
123
|
+
const init = {
|
|
124
|
+
bubbles: true,
|
|
125
|
+
cancelable: true,
|
|
126
|
+
clientX: rect.left + rect.width / 2,
|
|
127
|
+
clientY: rect.top + rect.height / 2,
|
|
128
|
+
};
|
|
129
|
+
el.dispatchEvent(new MouseEvent('mouseenter', init));
|
|
130
|
+
el.dispatchEvent(new MouseEvent('mouseover', init));
|
|
131
|
+
}, action.hover);
|
|
132
|
+
}
|
|
133
|
+
else if ('scroll' in action) {
|
|
134
|
+
await page.evaluate((spec) => {
|
|
135
|
+
if ('to' in spec) {
|
|
136
|
+
window.scrollTo({ top: spec.to, behavior: 'smooth' });
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
const el = document.querySelector(spec.selector);
|
|
140
|
+
if (el)
|
|
141
|
+
el.scrollIntoView({
|
|
142
|
+
behavior: 'smooth',
|
|
143
|
+
block: 'center',
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}, action.scroll);
|
|
147
|
+
}
|
|
148
|
+
else if ('wait' in action) {
|
|
149
|
+
await page.waitForTimeout(action.wait);
|
|
150
|
+
}
|
|
151
|
+
else if ('simulate_keyboard' in action) {
|
|
152
|
+
const height = typeof action.simulate_keyboard === 'number'
|
|
153
|
+
? action.simulate_keyboard
|
|
154
|
+
: action.simulate_keyboard
|
|
155
|
+
? 320
|
|
156
|
+
: 0;
|
|
157
|
+
await page.evaluate((h) => {
|
|
158
|
+
window.dispatchEvent(new CustomEvent('keyboard-height', { detail: { height: h } }));
|
|
159
|
+
}, height);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Parse `--actions <json>`. Accepts either a JSON array literal or a
|
|
164
|
+
* path to a JSON file. Validates each entry against the known action
|
|
165
|
+
* shapes so the caller fails fast instead of inside Playwright.
|
|
166
|
+
*/
|
|
167
|
+
export function parseActionsArg(arg) {
|
|
168
|
+
let text = arg;
|
|
169
|
+
if (!arg.trim().startsWith('[') && fs.existsSync(arg)) {
|
|
170
|
+
text = fs.readFileSync(arg, 'utf-8');
|
|
171
|
+
}
|
|
172
|
+
let parsed;
|
|
173
|
+
try {
|
|
174
|
+
parsed = JSON.parse(text);
|
|
175
|
+
}
|
|
176
|
+
catch (err) {
|
|
177
|
+
throw new Error(`--actions: failed to parse JSON (${err.message})`);
|
|
178
|
+
}
|
|
179
|
+
if (!Array.isArray(parsed)) {
|
|
180
|
+
throw new Error('--actions: expected a JSON array');
|
|
181
|
+
}
|
|
182
|
+
return parsed.map((a, i) => validateAction(a, i));
|
|
183
|
+
}
|
|
184
|
+
function validateAction(a, i) {
|
|
185
|
+
if (!a || typeof a !== 'object') {
|
|
186
|
+
throw new Error(`--actions[${i}]: not an object`);
|
|
187
|
+
}
|
|
188
|
+
const obj = a;
|
|
189
|
+
if (typeof obj.navigate === 'string')
|
|
190
|
+
return { navigate: obj.navigate };
|
|
191
|
+
if (typeof obj.click === 'string')
|
|
192
|
+
return { click: obj.click };
|
|
193
|
+
if (typeof obj.focus === 'string')
|
|
194
|
+
return { focus: obj.focus };
|
|
195
|
+
if (typeof obj.hover === 'string')
|
|
196
|
+
return { hover: obj.hover };
|
|
197
|
+
if (typeof obj.wait === 'number')
|
|
198
|
+
return { wait: obj.wait };
|
|
199
|
+
if ('simulate_keyboard' in obj &&
|
|
200
|
+
(typeof obj.simulate_keyboard === 'number' ||
|
|
201
|
+
typeof obj.simulate_keyboard === 'boolean')) {
|
|
202
|
+
return { simulate_keyboard: obj.simulate_keyboard };
|
|
203
|
+
}
|
|
204
|
+
if (obj.scroll && typeof obj.scroll === 'object') {
|
|
205
|
+
const s = obj.scroll;
|
|
206
|
+
if (typeof s.to === 'number')
|
|
207
|
+
return { scroll: { to: s.to } };
|
|
208
|
+
if (typeof s.selector === 'string')
|
|
209
|
+
return { scroll: { selector: s.selector } };
|
|
210
|
+
}
|
|
211
|
+
throw new Error(`--actions[${i}]: unknown shape — expected one of navigate/click/focus/hover/scroll/wait/simulate_keyboard`);
|
|
212
|
+
}
|
|
213
|
+
const VIEWPORT_RE = /^(\d+)x(\d+)$/i;
|
|
214
|
+
export function parseViewport(arg) {
|
|
215
|
+
const m = VIEWPORT_RE.exec(arg);
|
|
216
|
+
if (!m)
|
|
217
|
+
throw new Error(`--viewport: expected WxH (e.g. 390x844), got "${arg}"`);
|
|
218
|
+
return { width: parseInt(m[1], 10), height: parseInt(m[2], 10) };
|
|
219
|
+
}
|
|
220
|
+
export async function runInspectUxCli(opts) {
|
|
221
|
+
const device = (opts.device ?? 'desktop');
|
|
222
|
+
if (!['desktop', 'ios', 'android'].includes(device)) {
|
|
223
|
+
throw new Error(`--device: expected desktop|ios|android, got "${opts.device}"`);
|
|
224
|
+
}
|
|
225
|
+
const result = await inspectUx({
|
|
226
|
+
url: opts.url,
|
|
227
|
+
urlPath: opts.path,
|
|
228
|
+
device,
|
|
229
|
+
actions: opts.actions ? parseActionsArg(opts.actions) : undefined,
|
|
230
|
+
settleMs: opts.settleMs ? parseInt(opts.settleMs, 10) : undefined,
|
|
231
|
+
viewport: opts.viewport ? parseViewport(opts.viewport) : undefined,
|
|
232
|
+
token: opts.token ?? process.env['BOT_TOKEN'],
|
|
233
|
+
timeoutMs: opts.timeoutMs ? parseInt(opts.timeoutMs, 10) : undefined,
|
|
234
|
+
});
|
|
235
|
+
const json = JSON.stringify(result.report, null, 2);
|
|
236
|
+
if (opts.out) {
|
|
237
|
+
fs.mkdirSync(path.dirname(opts.out), { recursive: true });
|
|
238
|
+
fs.writeFileSync(opts.out, json);
|
|
239
|
+
process.stdout.write(`inspect:ux → ${opts.out} (${result.durationMs}ms, ${result.report.animations.length} animations, ${result.report.overlaps.length} overlaps, cls=${result.report.cls.total.toFixed(3)})\n`);
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
process.stdout.write(json + '\n');
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
//# sourceMappingURL=inspectUx.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspectUx.js","sourceRoot":"","sources":["../../src/cli/inspectUx.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/version.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const CLI_VERSION = "0.1.
|
|
1
|
+
export declare const CLI_VERSION = "0.1.492";
|
|
2
2
|
//# sourceMappingURL=version.d.ts.map
|
package/dist/cli/version.js
CHANGED
|
@@ -5,14 +5,14 @@
|
|
|
5
5
|
* Supports GFM (tables, task lists, strikethrough) and custom nodes (mentions, bot tags).
|
|
6
6
|
*/
|
|
7
7
|
import { Schema } from 'prosemirror-model';
|
|
8
|
-
export declare const schema: Schema<"
|
|
8
|
+
export declare const schema: Schema<"blockquote" | "table" | "image" | "svg" | "text" | "heading" | "paragraph" | "latex" | "mermaid" | "mention" | "table_row" | "table_cell" | "table_header" | "doc" | "code_block" | "horizontal_rule" | "bullet_list" | "ordered_list" | "list_item" | "hard_break" | "bot_tag" | "vegalite" | "markmap", "link" | "code" | "em" | "strong" | "strikethrough" | "highlight" | "comment_anchor">;
|
|
9
9
|
export declare const nodeTypes: {
|
|
10
|
-
readonly text: import("prosemirror-model").NodeType;
|
|
11
|
-
readonly table: import("prosemirror-model").NodeType;
|
|
12
10
|
readonly blockquote: import("prosemirror-model").NodeType;
|
|
13
|
-
readonly
|
|
11
|
+
readonly table: import("prosemirror-model").NodeType;
|
|
14
12
|
readonly image: import("prosemirror-model").NodeType;
|
|
15
13
|
readonly svg: import("prosemirror-model").NodeType;
|
|
14
|
+
readonly text: import("prosemirror-model").NodeType;
|
|
15
|
+
readonly heading: import("prosemirror-model").NodeType;
|
|
16
16
|
readonly paragraph: import("prosemirror-model").NodeType;
|
|
17
17
|
readonly latex: import("prosemirror-model").NodeType;
|
|
18
18
|
readonly mermaid: import("prosemirror-model").NodeType;
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -419,6 +419,45 @@ program
|
|
|
419
419
|
},
|
|
420
420
|
);
|
|
421
421
|
|
|
422
|
+
program
|
|
423
|
+
.command('inspect:ux')
|
|
424
|
+
.description(
|
|
425
|
+
'Drive the local dev server through an action script and emit the structured UglyInspectReport (CLS, longTasks, overlaps, safe-area, keyboard, animations, popups). Use --actions to compose navigate/click/focus/hover/scroll/wait/simulate_keyboard probes.',
|
|
426
|
+
)
|
|
427
|
+
.option('--url <url>', 'Base URL (default http://localhost:<localPort>)')
|
|
428
|
+
.option('--path <path>', 'Route path to probe (default /)', '/')
|
|
429
|
+
.option('--device <kind>', 'desktop | ios | android', 'desktop')
|
|
430
|
+
.option(
|
|
431
|
+
'--actions <json>',
|
|
432
|
+
'Action array as JSON literal OR path to a JSON file. Each entry is one of: {navigate}, {click}, {focus}, {hover}, {scroll:{to|selector}}, {wait}, {simulate_keyboard}',
|
|
433
|
+
)
|
|
434
|
+
.option('--settle-ms <ms>', 'Settle time after the last action', '800')
|
|
435
|
+
.option('--viewport <wxh>', 'Viewport WxH (e.g. 390x844)')
|
|
436
|
+
.option('--token <token>', 'Bot auth token (cookie). Falls back to $BOT_TOKEN.')
|
|
437
|
+
.option('--timeout-ms <ms>', 'Per-step Playwright timeout', '60000')
|
|
438
|
+
.option('--out <path>', 'Write JSON report to this path instead of stdout')
|
|
439
|
+
.action(
|
|
440
|
+
async (opts: {
|
|
441
|
+
url?: string;
|
|
442
|
+
path?: string;
|
|
443
|
+
device?: string;
|
|
444
|
+
actions?: string;
|
|
445
|
+
settleMs?: string;
|
|
446
|
+
viewport?: string;
|
|
447
|
+
token?: string;
|
|
448
|
+
timeoutMs?: string;
|
|
449
|
+
out?: string;
|
|
450
|
+
}) => {
|
|
451
|
+
try {
|
|
452
|
+
const { runInspectUxCli } = await import('./inspectUx.js');
|
|
453
|
+
await runInspectUxCli(opts);
|
|
454
|
+
} catch (e) {
|
|
455
|
+
console.error((e as Error).message);
|
|
456
|
+
process.exit(1);
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
);
|
|
460
|
+
|
|
422
461
|
program
|
|
423
462
|
.command('dev-logs')
|
|
424
463
|
.description('Show local dev logs from JSONL files')
|
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ugly-app inspect:ux` — drive the local dev server through an action
|
|
3
|
+
* script and emit the structured UglyInspectReport.
|
|
4
|
+
*
|
|
5
|
+
* Mirrors the action schema used by ugly-studio's `inspect_ux` coding-
|
|
6
|
+
* agent tool (navigate / click / focus / hover / scroll / wait /
|
|
7
|
+
* simulate_keyboard) so the same probe payload is usable from:
|
|
8
|
+
* - studio coding-agent (tool: inspect_ux)
|
|
9
|
+
* - claude-code CLI, copilot, the bot-swarm driver (this CLI)
|
|
10
|
+
*
|
|
11
|
+
* The probe boots headless Chromium against the project's dev server,
|
|
12
|
+
* calls `window.__uglyInspectMark()`, runs the action list, settles,
|
|
13
|
+
* then reads `window.__uglyInspect({ since: mark })`. The full report
|
|
14
|
+
* is written to stdout as JSON (or `--out <path>`).
|
|
15
|
+
*
|
|
16
|
+
* Requires the project's dev server to be running on
|
|
17
|
+
* `http://localhost:<localPort>` (override with `--url`) and the
|
|
18
|
+
* project to be built on ugly-app ≥ 0.1.489 (the version that ships
|
|
19
|
+
* `window.__uglyInspect`).
|
|
20
|
+
*
|
|
21
|
+
* Why a separate CLI when studio already has the tool: the bot-swarm
|
|
22
|
+
* driver (`bots/feedback/run-bot.mjs`) and any non-studio harness
|
|
23
|
+
* (claude-code, copilot) can't invoke studio's tool. Without this CLI
|
|
24
|
+
* those callers fall back to static screenshots + ad-hoc Playwright,
|
|
25
|
+
* which is exactly the gap that motivated this command — animations
|
|
26
|
+
* and CLS spikes need a measurement window driven by real actions, not
|
|
27
|
+
* a frozen frame.
|
|
28
|
+
*/
|
|
29
|
+
import fs from 'node:fs';
|
|
30
|
+
import path from 'node:path';
|
|
31
|
+
import { getLocalPort } from '../shared/Defaults.js';
|
|
32
|
+
import type { UglyInspectReport } from '../client/inspect/types.js';
|
|
33
|
+
|
|
34
|
+
export type InspectUxAction =
|
|
35
|
+
| { navigate: string }
|
|
36
|
+
| { click: string }
|
|
37
|
+
| { focus: string }
|
|
38
|
+
| { hover: string }
|
|
39
|
+
| { scroll: { to: number } | { selector: string } }
|
|
40
|
+
| { wait: number }
|
|
41
|
+
| { simulate_keyboard: boolean | number };
|
|
42
|
+
|
|
43
|
+
export interface InspectUxOptions {
|
|
44
|
+
url?: string;
|
|
45
|
+
urlPath?: string;
|
|
46
|
+
device?: 'desktop' | 'ios' | 'android';
|
|
47
|
+
actions?: InspectUxAction[];
|
|
48
|
+
settleMs?: number;
|
|
49
|
+
viewport?: { width: number; height: number };
|
|
50
|
+
token?: string;
|
|
51
|
+
outPath?: string;
|
|
52
|
+
json?: boolean;
|
|
53
|
+
timeoutMs?: number;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export interface InspectUxResult {
|
|
57
|
+
report: UglyInspectReport;
|
|
58
|
+
url: string;
|
|
59
|
+
device: 'desktop' | 'ios' | 'android';
|
|
60
|
+
durationMs: number;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
const AUTH_COOKIE = 'auth_token';
|
|
64
|
+
|
|
65
|
+
export async function inspectUx(
|
|
66
|
+
opts: InspectUxOptions,
|
|
67
|
+
): Promise<InspectUxResult> {
|
|
68
|
+
const started = Date.now();
|
|
69
|
+
const baseUrl = (opts.url ?? `http://localhost:${getLocalPort()}`).replace(
|
|
70
|
+
/\/+$/,
|
|
71
|
+
'',
|
|
72
|
+
);
|
|
73
|
+
const urlPath = opts.urlPath ?? '/';
|
|
74
|
+
const device = opts.device ?? 'desktop';
|
|
75
|
+
const settleMs = opts.settleMs ?? 800;
|
|
76
|
+
const timeoutMs = opts.timeoutMs ?? 60_000;
|
|
77
|
+
const target = new URL(
|
|
78
|
+
urlPath.startsWith('/') ? urlPath : `/${urlPath}`,
|
|
79
|
+
baseUrl,
|
|
80
|
+
);
|
|
81
|
+
if (device !== 'desktop') target.searchParams.set('app', device);
|
|
82
|
+
|
|
83
|
+
// Dynamic import so missing `playwright` produces a friendly error
|
|
84
|
+
// (the package is not a runtime dependency of ugly-app — consumer
|
|
85
|
+
// projects install it explicitly via `npx playwright install chromium`).
|
|
86
|
+
let chromium: typeof import('playwright').chromium;
|
|
87
|
+
try {
|
|
88
|
+
({ chromium } = await import('playwright'));
|
|
89
|
+
} catch {
|
|
90
|
+
throw new Error(
|
|
91
|
+
"Playwright is not installed in this project. Run `npm i -D playwright && npx playwright install chromium`, then retry `ugly-app inspect:ux`.",
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const browser = await chromium.launch({ headless: true });
|
|
96
|
+
try {
|
|
97
|
+
const ctx = await browser.newContext(
|
|
98
|
+
opts.viewport ? { viewport: opts.viewport } : undefined,
|
|
99
|
+
);
|
|
100
|
+
if (opts.token) {
|
|
101
|
+
await ctx.addCookies([
|
|
102
|
+
{
|
|
103
|
+
name: AUTH_COOKIE,
|
|
104
|
+
value: opts.token,
|
|
105
|
+
url: baseUrl,
|
|
106
|
+
},
|
|
107
|
+
]);
|
|
108
|
+
}
|
|
109
|
+
const page = await ctx.newPage();
|
|
110
|
+
page.setDefaultTimeout(timeoutMs);
|
|
111
|
+
await page.goto(target.toString(), {
|
|
112
|
+
waitUntil: 'load',
|
|
113
|
+
timeout: timeoutMs,
|
|
114
|
+
});
|
|
115
|
+
await page.waitForSelector('[data-id]', { timeout: timeoutMs });
|
|
116
|
+
|
|
117
|
+
const mark: number = await page.evaluate(() => {
|
|
118
|
+
return window.__uglyInspectMark?.() ?? Date.now();
|
|
119
|
+
});
|
|
120
|
+
|
|
121
|
+
for (const action of opts.actions ?? []) {
|
|
122
|
+
await runAction(page, action);
|
|
123
|
+
}
|
|
124
|
+
await page.waitForTimeout(settleMs);
|
|
125
|
+
|
|
126
|
+
const report = await page.evaluate((since: number) => {
|
|
127
|
+
if (!window.__uglyInspect) {
|
|
128
|
+
throw new Error(
|
|
129
|
+
'window.__uglyInspect not installed — is this an ugly-app project on >= 0.1.489?',
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
return window.__uglyInspect({ since });
|
|
133
|
+
}, mark);
|
|
134
|
+
|
|
135
|
+
return {
|
|
136
|
+
report,
|
|
137
|
+
url: target.toString(),
|
|
138
|
+
device,
|
|
139
|
+
durationMs: Date.now() - started,
|
|
140
|
+
};
|
|
141
|
+
} finally {
|
|
142
|
+
await browser.close();
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function runAction(
|
|
147
|
+
page: import('playwright').Page,
|
|
148
|
+
action: InspectUxAction,
|
|
149
|
+
): Promise<void> {
|
|
150
|
+
if ('navigate' in action) {
|
|
151
|
+
await page.evaluate((to: string) => {
|
|
152
|
+
window.history.pushState({}, '', to);
|
|
153
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
154
|
+
}, action.navigate);
|
|
155
|
+
} else if ('click' in action) {
|
|
156
|
+
await page.evaluate((sel: string) => {
|
|
157
|
+
const el = document.querySelector(sel);
|
|
158
|
+
if (el && el instanceof HTMLElement) el.click();
|
|
159
|
+
}, action.click);
|
|
160
|
+
} else if ('focus' in action) {
|
|
161
|
+
await page.evaluate((sel: string) => {
|
|
162
|
+
const el = document.querySelector(sel);
|
|
163
|
+
if (el && el instanceof HTMLElement) el.focus();
|
|
164
|
+
}, action.focus);
|
|
165
|
+
} else if ('hover' in action) {
|
|
166
|
+
await page.evaluate((sel: string) => {
|
|
167
|
+
const el = document.querySelector(sel);
|
|
168
|
+
if (!(el instanceof HTMLElement)) return;
|
|
169
|
+
const rect = el.getBoundingClientRect();
|
|
170
|
+
const init = {
|
|
171
|
+
bubbles: true,
|
|
172
|
+
cancelable: true,
|
|
173
|
+
clientX: rect.left + rect.width / 2,
|
|
174
|
+
clientY: rect.top + rect.height / 2,
|
|
175
|
+
};
|
|
176
|
+
el.dispatchEvent(new MouseEvent('mouseenter', init));
|
|
177
|
+
el.dispatchEvent(new MouseEvent('mouseover', init));
|
|
178
|
+
}, action.hover);
|
|
179
|
+
} else if ('scroll' in action) {
|
|
180
|
+
await page.evaluate((spec: { to: number } | { selector: string }) => {
|
|
181
|
+
if ('to' in spec) {
|
|
182
|
+
window.scrollTo({ top: spec.to, behavior: 'smooth' });
|
|
183
|
+
} else {
|
|
184
|
+
const el = document.querySelector(spec.selector);
|
|
185
|
+
if (el)
|
|
186
|
+
(el as HTMLElement).scrollIntoView({
|
|
187
|
+
behavior: 'smooth',
|
|
188
|
+
block: 'center',
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}, action.scroll);
|
|
192
|
+
} else if ('wait' in action) {
|
|
193
|
+
await page.waitForTimeout(action.wait);
|
|
194
|
+
} else if ('simulate_keyboard' in action) {
|
|
195
|
+
const height =
|
|
196
|
+
typeof action.simulate_keyboard === 'number'
|
|
197
|
+
? action.simulate_keyboard
|
|
198
|
+
: action.simulate_keyboard
|
|
199
|
+
? 320
|
|
200
|
+
: 0;
|
|
201
|
+
await page.evaluate((h: number) => {
|
|
202
|
+
window.dispatchEvent(
|
|
203
|
+
new CustomEvent('keyboard-height', { detail: { height: h } }),
|
|
204
|
+
);
|
|
205
|
+
}, height);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* Parse `--actions <json>`. Accepts either a JSON array literal or a
|
|
211
|
+
* path to a JSON file. Validates each entry against the known action
|
|
212
|
+
* shapes so the caller fails fast instead of inside Playwright.
|
|
213
|
+
*/
|
|
214
|
+
export function parseActionsArg(arg: string): InspectUxAction[] {
|
|
215
|
+
let text = arg;
|
|
216
|
+
if (!arg.trim().startsWith('[') && fs.existsSync(arg)) {
|
|
217
|
+
text = fs.readFileSync(arg, 'utf-8');
|
|
218
|
+
}
|
|
219
|
+
let parsed: unknown;
|
|
220
|
+
try {
|
|
221
|
+
parsed = JSON.parse(text);
|
|
222
|
+
} catch (err) {
|
|
223
|
+
throw new Error(`--actions: failed to parse JSON (${(err as Error).message})`);
|
|
224
|
+
}
|
|
225
|
+
if (!Array.isArray(parsed)) {
|
|
226
|
+
throw new Error('--actions: expected a JSON array');
|
|
227
|
+
}
|
|
228
|
+
return parsed.map((a, i) => validateAction(a, i));
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function validateAction(a: unknown, i: number): InspectUxAction {
|
|
232
|
+
if (!a || typeof a !== 'object') {
|
|
233
|
+
throw new Error(`--actions[${i}]: not an object`);
|
|
234
|
+
}
|
|
235
|
+
const obj = a as Record<string, unknown>;
|
|
236
|
+
if (typeof obj.navigate === 'string') return { navigate: obj.navigate };
|
|
237
|
+
if (typeof obj.click === 'string') return { click: obj.click };
|
|
238
|
+
if (typeof obj.focus === 'string') return { focus: obj.focus };
|
|
239
|
+
if (typeof obj.hover === 'string') return { hover: obj.hover };
|
|
240
|
+
if (typeof obj.wait === 'number') return { wait: obj.wait };
|
|
241
|
+
if (
|
|
242
|
+
'simulate_keyboard' in obj &&
|
|
243
|
+
(typeof obj.simulate_keyboard === 'number' ||
|
|
244
|
+
typeof obj.simulate_keyboard === 'boolean')
|
|
245
|
+
) {
|
|
246
|
+
return { simulate_keyboard: obj.simulate_keyboard };
|
|
247
|
+
}
|
|
248
|
+
if (obj.scroll && typeof obj.scroll === 'object') {
|
|
249
|
+
const s = obj.scroll as Record<string, unknown>;
|
|
250
|
+
if (typeof s.to === 'number') return { scroll: { to: s.to } };
|
|
251
|
+
if (typeof s.selector === 'string')
|
|
252
|
+
return { scroll: { selector: s.selector } };
|
|
253
|
+
}
|
|
254
|
+
throw new Error(
|
|
255
|
+
`--actions[${i}]: unknown shape — expected one of navigate/click/focus/hover/scroll/wait/simulate_keyboard`,
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
const VIEWPORT_RE = /^(\d+)x(\d+)$/i;
|
|
260
|
+
|
|
261
|
+
export function parseViewport(arg: string): { width: number; height: number } {
|
|
262
|
+
const m = VIEWPORT_RE.exec(arg);
|
|
263
|
+
if (!m) throw new Error(`--viewport: expected WxH (e.g. 390x844), got "${arg}"`);
|
|
264
|
+
return { width: parseInt(m[1], 10), height: parseInt(m[2], 10) };
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
export async function runInspectUxCli(opts: {
|
|
268
|
+
url?: string;
|
|
269
|
+
path?: string;
|
|
270
|
+
device?: string;
|
|
271
|
+
actions?: string;
|
|
272
|
+
settleMs?: string;
|
|
273
|
+
viewport?: string;
|
|
274
|
+
token?: string;
|
|
275
|
+
out?: string;
|
|
276
|
+
timeoutMs?: string;
|
|
277
|
+
}): Promise<void> {
|
|
278
|
+
const device = (opts.device ?? 'desktop') as 'desktop' | 'ios' | 'android';
|
|
279
|
+
if (!['desktop', 'ios', 'android'].includes(device)) {
|
|
280
|
+
throw new Error(`--device: expected desktop|ios|android, got "${opts.device}"`);
|
|
281
|
+
}
|
|
282
|
+
const result = await inspectUx({
|
|
283
|
+
url: opts.url,
|
|
284
|
+
urlPath: opts.path,
|
|
285
|
+
device,
|
|
286
|
+
actions: opts.actions ? parseActionsArg(opts.actions) : undefined,
|
|
287
|
+
settleMs: opts.settleMs ? parseInt(opts.settleMs, 10) : undefined,
|
|
288
|
+
viewport: opts.viewport ? parseViewport(opts.viewport) : undefined,
|
|
289
|
+
token: opts.token ?? process.env['BOT_TOKEN'],
|
|
290
|
+
timeoutMs: opts.timeoutMs ? parseInt(opts.timeoutMs, 10) : undefined,
|
|
291
|
+
});
|
|
292
|
+
const json = JSON.stringify(result.report, null, 2);
|
|
293
|
+
if (opts.out) {
|
|
294
|
+
fs.mkdirSync(path.dirname(opts.out), { recursive: true });
|
|
295
|
+
fs.writeFileSync(opts.out, json);
|
|
296
|
+
process.stdout.write(
|
|
297
|
+
`inspect:ux → ${opts.out} (${result.durationMs}ms, ${result.report.animations.length} animations, ${result.report.overlaps.length} overlaps, cls=${result.report.cls.total.toFixed(3)})\n`,
|
|
298
|
+
);
|
|
299
|
+
} else {
|
|
300
|
+
process.stdout.write(json + '\n');
|
|
301
|
+
}
|
|
302
|
+
}
|
package/src/cli/version.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Auto-generated by prebuild — do not edit manually
|
|
2
|
-
export const CLI_VERSION = "0.1.
|
|
2
|
+
export const CLI_VERSION = "0.1.492";
|
|
@@ -231,9 +231,9 @@ Dispatch ALL active personas as **parallel subagents** (`delegate_parallel`). If
|
|
|
231
231
|
node bots/feedback/run-bot.mjs {slug} --capture
|
|
232
232
|
```
|
|
233
233
|
|
|
234
|
-
This writes fresh PNGs + element maps to `bots/journal/cycles/screenshots/{slug}/<page>.png` and `<page>.element-map.json` reflecting the CURRENT site. **
|
|
234
|
+
This writes fresh PNGs + element maps to `bots/journal/cycles/screenshots/{slug}/<page>.png` and `<page>.element-map.json` reflecting the CURRENT site. **The driver also writes one `UglyInspectReport` per interaction** — `<page>.mount.ux-report.json`, `<page>.hover-first.ux-report.json`, `<page>.scroll-deep.ux-report.json`, `<page>.focus-input.ux-report.json` — each capturing layout shift, animation jank, overlapping interactive controls, safe-area violations, and mobile keyboard coverage during a measurement window driven by the named action script. The legacy `<page>.ux-report.json` is kept as an alias for the `mount` window. A persona that cares about a different interaction set can write `bots/feedback/active/{slug}/interactions.json` (same action schema as `inspect_ux` and `ugly-app inspect:ux`); see [run-bot.mjs](bots/feedback/run-bot.mjs) for the default list. No feedback is submitted yet.
|
|
235
235
|
|
|
236
|
-
3. **LOOK at each page AND READ
|
|
236
|
+
3. **LOOK at each page AND READ every UX report.** For each PNG under `bots/journal/cycles/screenshots/{slug}/`, inspect it using vision — the persona **must actually see** the page before writing findings — AND read **every** sibling `<page>.<interaction>.ux-report.json` (mount + hover-first + scroll-deep + focus-input by default) to ground the visual critique in measured defects across each interaction window:
|
|
237
237
|
|
|
238
238
|
- If `analyze_image` is available (ugly-studio coding-agent):
|
|
239
239
|
|
|
@@ -251,16 +251,20 @@ Dispatch ALL active personas as **parallel subagents** (`delegate_parallel`). If
|
|
|
251
251
|
|
|
252
252
|
- Cross-reference with the matching `<page>.element-map.json` to resolve specific `dataId` / source-file references when you find something worth reporting.
|
|
253
253
|
|
|
254
|
-
- **Mine `<page>.ux-report.json`** for objective defects the screenshot alone cannot show. Treat each of these as a finding worth a feedback row — quote the offending selector in the message:
|
|
255
|
-
- `safeAreaViolations[]` → `{ "type": "bug", "message": "<selector> spills outside iOS safe area on <side> edge" }`
|
|
256
|
-
- `overlaps[]` → `{ "type": "design", "message": "<a.selector> and <b.selector> overlap by Npx — likely a z-index or layout bug" }`
|
|
257
|
-
- `keyboard.coveredInputs[]` → `{ "type": "bug", "message": "<selector> is covered by the on-screen keyboard when focused" }`
|
|
258
|
-
- `cls.total > 0.1` → `{ "type": "design", "message": "page shifts significantly during
|
|
259
|
-
- `animations[].droppedFrames > 2` → `{ "type": "bug", "message": "<element> animation drops M frames over Tms" }`
|
|
254
|
+
- **Mine every `<page>.<interaction>.ux-report.json`** for objective defects the screenshot alone cannot show. Treat each of these as a finding worth a feedback row — quote the offending selector AND the interaction window in the message so the maintain bot can reproduce:
|
|
255
|
+
- `safeAreaViolations[]` → `{ "type": "bug", "message": "<selector> spills outside iOS safe area on <side> edge (mount)" }`
|
|
256
|
+
- `overlaps[]` → `{ "type": "design", "message": "<a.selector> and <b.selector> overlap by Npx during <interaction> — likely a z-index or layout bug" }`
|
|
257
|
+
- `keyboard.coveredInputs[]` → `{ "type": "bug", "message": "<selector> is covered by the on-screen keyboard when focused (focus-input)" }`
|
|
258
|
+
- `cls.total > 0.1` → `{ "type": "design", "message": "page shifts significantly during <interaction>: <cls.total> across N spikes" }`
|
|
259
|
+
- `animations[].droppedFrames > 2` → `{ "type": "bug", "message": "<element> animation drops M frames over Tms during <interaction>" }`
|
|
260
|
+
- `popups[].droppedFrames > 0` or `popups[].mountMs > 200` → `{ "type": "bug", "message": "<selector> popup entry drops M frames / takes Tms to mount during <interaction>" }`
|
|
261
|
+
- `longTasks[]` with `duration > 100` → `{ "type": "bug", "message": "<duration>ms long task during <during> blocks main thread" }`
|
|
260
262
|
|
|
261
|
-
Visual critique still flows from the screenshot — the structured signals add the movement-and-mobile dimension a single frame can't show.
|
|
263
|
+
Visual critique still flows from the screenshot — the structured signals add the movement-and-mobile dimension a single frame can't show. **Animations specifically are invisible in a static PNG; the per-interaction ux-report is the only signal you have on them.**
|
|
262
264
|
|
|
263
|
-
**Hard rule — no exceptions, including cycle 001:** every active persona must perform ≥1 vision call (`analyze_image` or Read on a PNG) against its **own** captured screenshots before its findings.json is written. Writing findings.json for a persona without a logged vision call for that same persona is a **cycle failure** — stop the cycle and surface it. "All bots see the same blank canvas, I'll just author findings in a batch" is the exact shortcut this rule exists to prevent: feedback authored from imagination instead of
|
|
265
|
+
**Hard rule #1 — vision (no exceptions, including cycle 001):** every active persona must perform ≥1 vision call (`analyze_image` or Read on a PNG) against its **own** captured screenshots before its findings.json is written. Writing findings.json for a persona without a logged vision call for that same persona is a **cycle failure** — stop the cycle and surface it. "All bots see the same blank canvas, I'll just author findings in a batch" is the exact shortcut this rule exists to prevent: feedback authored from imagination instead of what the persona actually saw is dead weight that pollutes the swarm's signal.
|
|
266
|
+
|
|
267
|
+
**Hard rule #2 — ux-report (no exceptions):** every active persona must perform ≥1 Read on each `<page>.<interaction>.ux-report.json` under its own screenshot directory before its findings.json is written. The default config produces four reports per route (`mount`, `hover-first`, `scroll-deep`, `focus-input`); skipping any of them is a **cycle failure**. Vague hand-wave findings like "the page feels janky" without a quoted selector + interaction from a report are the failure mode this rule prevents — measured input was the whole point of writing the reports. Telemetry from `ws_6zyk6bv3mpvtimky:sess_9dnxh2b8mpvtimky` (2026-06-01) caught the previous version of this skill in the exact failure: 37 vision calls, **one** ux-report read across 10 personas, **zero** animation findings — even though the reports captured real overlap defects.
|
|
264
268
|
|
|
265
269
|
4. **AUTHOR findings.json.** Write 1–5 findings to `bots/feedback/active/{slug}/findings.json`:
|
|
266
270
|
|
|
@@ -302,6 +306,55 @@ Record which bots succeeded and which failed/timed out.
|
|
|
302
306
|
|
|
303
307
|
---
|
|
304
308
|
|
|
309
|
+
## Step 2b — Motion Probe
|
|
310
|
+
|
|
311
|
+
**Once per cycle, not once per persona.** The persona pass measures the default interaction set baked into [run-bot.mjs](bots/feedback/run-bot.mjs); the motion probe targets specific, code-aware interactions that the maintain bot built or modified this cycle. It exists because animation and entry jank are invisible in a static screenshot and almost always invisible in the default `mount` window too — they only show up when a user actually triggers the transition.
|
|
312
|
+
|
|
313
|
+
1. **Pick 3–5 motion-bearing interactions** worth measuring this cycle. The rule of thumb: anything that animates, slides, fades, scroll-links, mounts a popup, or reveals a keyboard. Concrete candidates:
|
|
314
|
+
- Popup/modal entry (`{ click: "[data-id=open-modal]" }, { wait: 600 }`)
|
|
315
|
+
- Drawer / accordion expand
|
|
316
|
+
- Hover-state primary CTA (`{ hover: "[data-id=primary-cta]" }, { wait: 400 }`)
|
|
317
|
+
- Mobile keyboard reveal on the main input (`{ focus: "[data-id=composer]" }, { simulate_keyboard: true }, { wait: 400 }`) on `device: ios`
|
|
318
|
+
- Scroll-linked hero animation (`{ scroll: { to: 2000 } }, { wait: 1200 }`)
|
|
319
|
+
- SPA route transition (`{ navigate: "/settings" }, { wait: 800 }`)
|
|
320
|
+
|
|
321
|
+
If the maintain bot built nothing motion-bearing this cycle, skip the probe and note it in the journal — do not synthesize fake motion findings.
|
|
322
|
+
|
|
323
|
+
2. **Run the probe.** Two equivalent surfaces — pick whichever your harness exposes:
|
|
324
|
+
|
|
325
|
+
- **Studio coding-agent** (this skill running inside `ugly-studio`): call the `inspect_ux` tool directly with the actions list.
|
|
326
|
+
|
|
327
|
+
```
|
|
328
|
+
inspect_ux({ url_path: "/", device: "ios",
|
|
329
|
+
actions: [{ click: "[data-id=open-modal]" }, { wait: 600 }] })
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
- **claude-code CLI, copilot, or anywhere else**: shell out to `npx ugly-app inspect:ux`. The action schema is identical.
|
|
333
|
+
|
|
334
|
+
```bash
|
|
335
|
+
npx ugly-app inspect:ux \
|
|
336
|
+
--path / --device ios \
|
|
337
|
+
--actions '[{"click":"[data-id=open-modal]"},{"wait":600}]' \
|
|
338
|
+
--out bots/journal/cycles/screenshots/_motion/open-modal-ios.ux-report.json
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
Both surfaces return the same `UglyInspectReport` and call the same `window.__uglyInspect()` probe — the only difference is whether the report lands in your tool result or on disk.
|
|
342
|
+
|
|
343
|
+
3. **Convert real defects into feedback rows.** Submit findings via `npx ugly-app feedback:submit --type bug --token <BOT_TOKEN> ...` (use the manager's `BOT_TOKEN`, not a persona's — the motion probe is the manager's voice, not a critic's). Concrete thresholds:
|
|
344
|
+
- any `animations[].droppedFrames > 2` → `bug`
|
|
345
|
+
- any `popups[].droppedFrames > 0` or `popups[].mountMs > 200` → `bug`
|
|
346
|
+
- any `cls.spikes[]` triggered by this interaction (`cls.total > 0` AND happened after the action) → `design`
|
|
347
|
+
- any `longTasks[]` with `duration > 100` → `bug`
|
|
348
|
+
- any `keyboard.coveredInputs[]` on the mobile profiles → `bug`
|
|
349
|
+
|
|
350
|
+
Quote the action, the selector, and the measured value in the feedback message so the maintain bot can reproduce.
|
|
351
|
+
|
|
352
|
+
4. **Verify in Step 5.** After the restart loop reports healthy, re-run the same interactions list with `inspect_ux` / `inspect:ux` and compare `droppedFrames` / `popups[].mountMs` / `cls.total` before vs after. The maintain bot's claim that the fix worked must be backed by a measured improvement, not a fresh screenshot.
|
|
353
|
+
|
|
354
|
+
**Why this is its own step, not per-persona work**: personas describe what they *feel*; the motion probe produces what is *measured*. Putting the probe under the manager makes it a single decisive pass per cycle instead of N redundant probes, and it lets the manager target the maintain bot's actual diff (popups added today, scroll-linked animation built today) instead of the generic-static set baked into run-bot.mjs.
|
|
355
|
+
|
|
356
|
+
---
|
|
357
|
+
|
|
305
358
|
## Step 3 — Maintain Bot
|
|
306
359
|
|
|
307
360
|
Run sequentially in one session. No questions. Make autonomous decisions.
|
|
@@ -510,9 +563,11 @@ If that grep prints any filenames, the cycle has NOT satisfied the rule — keep
|
|
|
510
563
|
|
|
511
564
|
**Never declare restart success against a blank verification screenshot.** A passing API curl is not a substitute — the user-visible page must render.
|
|
512
565
|
|
|
513
|
-
9.
|
|
566
|
+
9. **Re-run the Step 2b motion probe interactions** against the now-restarted server and diff against the pre-fix run. If `cls.total`, `animations[].droppedFrames`, or `popups[].mountMs` regressed for any interaction the maintain bot touched this cycle, restart is **not** complete — surface the regression as a bug feedback row and let the next cycle pick it up (do not silently move on). If all measured interactions are within tolerance or improved, note the before/after numbers in the journal under the Restart section.
|
|
567
|
+
|
|
568
|
+
10. Once healthy, visually verified, and motion-verified: update the journal cycle file's Restart outcome to `success` or note any fixes made
|
|
514
569
|
|
|
515
|
-
|
|
570
|
+
11. Commit any remaining changes: `[bot] fix: restart issues`
|
|
516
571
|
|
|
517
572
|
**The restart loop has no retry limit.** It runs until clean or until externally killed. If a human has to intervene, the bots have failed.
|
|
518
573
|
|
|
@@ -25,11 +25,34 @@
|
|
|
25
25
|
* and the feedback-submit args. A known-good template short-circuits
|
|
26
26
|
* that loop. Don't rewrite the I/O scaffolding.
|
|
27
27
|
*
|
|
28
|
-
* Output:
|
|
28
|
+
* Output per route:
|
|
29
29
|
* - bots/journal/cycles/screenshots/<slug>/<page>.png
|
|
30
30
|
* - bots/journal/cycles/screenshots/<slug>/<page>.element-map.json
|
|
31
|
+
* - bots/journal/cycles/screenshots/<slug>/<page>.<interaction>.ux-report.json
|
|
32
|
+
* — one report per interaction (mount, hover-first, scroll-deep,
|
|
33
|
+
* focus-input by default). Each is a measurement WINDOW driven
|
|
34
|
+
* by the named action script, so animation jank and CLS that
|
|
35
|
+
* only appear during a specific gesture get isolated instead of
|
|
36
|
+
* conflated with page mount.
|
|
37
|
+
* - bots/journal/cycles/screenshots/<slug>/<page>.ux-report.json
|
|
38
|
+
* — kept as an alias for the `mount` report so callers that
|
|
39
|
+
* look for the legacy single-report path don't break.
|
|
31
40
|
* - feedback rows posted via `submitFeedbackBot` (data-proxy
|
|
32
41
|
* `db.captureFeedback` under the hood).
|
|
42
|
+
*
|
|
43
|
+
* Personas can override the default interaction set by writing
|
|
44
|
+
* `bots/feedback/active/<slug>/interactions.json`:
|
|
45
|
+
*
|
|
46
|
+
* [
|
|
47
|
+
* { "name": "mount", "actions": [] },
|
|
48
|
+
* { "name": "open-feedback",
|
|
49
|
+
* "actions": [{ "click": "[data-id=feedback-button]" },
|
|
50
|
+
* { "wait": 600 }] }
|
|
51
|
+
* ]
|
|
52
|
+
*
|
|
53
|
+
* Action shapes mirror `ugly-app inspect:ux` and the studio coding-
|
|
54
|
+
* agent `inspect_ux` tool: navigate / click / focus / hover /
|
|
55
|
+
* scroll:{to|selector} / wait / simulate_keyboard.
|
|
33
56
|
*/
|
|
34
57
|
import { chromium } from 'playwright';
|
|
35
58
|
import { execFile } from 'node:child_process';
|
|
@@ -181,6 +204,135 @@ async function submitFeedback({ type, message, url, screenshot, elementMap }) {
|
|
|
181
204
|
}
|
|
182
205
|
}
|
|
183
206
|
|
|
207
|
+
// --- Interaction scripts --------------------------------------------
|
|
208
|
+
// Each interaction defines a measurement window. The driver navigates
|
|
209
|
+
// fresh to the route, marks, runs the actions, settles, and reads
|
|
210
|
+
// `window.__uglyInspect()`. Personas override by writing
|
|
211
|
+
// `bots/feedback/active/<slug>/interactions.json` (same shape).
|
|
212
|
+
const DEFAULT_INTERACTIONS = [
|
|
213
|
+
// Pure mount: no interaction. Catches initial CLS, hydration shifts,
|
|
214
|
+
// safe-area violations, mount-time animations. Also produces the
|
|
215
|
+
// screenshot + element-map for vision callers.
|
|
216
|
+
{ name: 'mount', actions: [] },
|
|
217
|
+
// Hover-first: trigger hover transitions on the first non-feedback
|
|
218
|
+
// interactive element. Cheap, surfaces hover-state animation jank.
|
|
219
|
+
{
|
|
220
|
+
name: 'hover-first',
|
|
221
|
+
actions: [
|
|
222
|
+
{ hover: '[data-id]:not([data-id=feedback-button]):not(input):not(textarea)' },
|
|
223
|
+
{ wait: 600 },
|
|
224
|
+
],
|
|
225
|
+
},
|
|
226
|
+
// Scroll-deep: drives scroll-linked animations and any IntersectionObserver
|
|
227
|
+
// entry animations. Two-stage scroll catches enter + exit jank.
|
|
228
|
+
{
|
|
229
|
+
name: 'scroll-deep',
|
|
230
|
+
actions: [
|
|
231
|
+
{ scroll: { to: 1200 } },
|
|
232
|
+
{ wait: 800 },
|
|
233
|
+
{ scroll: { to: 0 } },
|
|
234
|
+
{ wait: 600 },
|
|
235
|
+
],
|
|
236
|
+
},
|
|
237
|
+
// Focus-input: opens the mobile keyboard simulation against the
|
|
238
|
+
// first input. Surfaces keyboard-covers-input on mobile profiles and
|
|
239
|
+
// focus-ring animation jank.
|
|
240
|
+
{
|
|
241
|
+
name: 'focus-input',
|
|
242
|
+
actions: [
|
|
243
|
+
{ focus: 'input, textarea' },
|
|
244
|
+
{ simulate_keyboard: true },
|
|
245
|
+
{ wait: 400 },
|
|
246
|
+
],
|
|
247
|
+
},
|
|
248
|
+
];
|
|
249
|
+
|
|
250
|
+
function loadInteractions() {
|
|
251
|
+
const overridePath = path.join(BOT_DIR, 'interactions.json');
|
|
252
|
+
if (!fs.existsSync(overridePath)) return DEFAULT_INTERACTIONS;
|
|
253
|
+
try {
|
|
254
|
+
const parsed = JSON.parse(fs.readFileSync(overridePath, 'utf-8'));
|
|
255
|
+
if (
|
|
256
|
+
Array.isArray(parsed) &&
|
|
257
|
+
parsed.every(
|
|
258
|
+
(e) =>
|
|
259
|
+
e &&
|
|
260
|
+
typeof e.name === 'string' &&
|
|
261
|
+
Array.isArray(e.actions),
|
|
262
|
+
)
|
|
263
|
+
) {
|
|
264
|
+
return parsed;
|
|
265
|
+
}
|
|
266
|
+
console.error(
|
|
267
|
+
`[${SLUG}] interactions.json malformed — falling back to defaults`,
|
|
268
|
+
);
|
|
269
|
+
} catch (err) {
|
|
270
|
+
console.error(
|
|
271
|
+
`[${SLUG}] interactions.json parse error: ${err.message} — falling back to defaults`,
|
|
272
|
+
);
|
|
273
|
+
}
|
|
274
|
+
return DEFAULT_INTERACTIONS;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Run a single action against a page. Mirrors the action schema used
|
|
278
|
+
// by `ugly-app inspect:ux` and the studio coding-agent `inspect_ux`
|
|
279
|
+
// tool so a persona's interactions.json is portable across harnesses.
|
|
280
|
+
async function runAction(page, action) {
|
|
281
|
+
if ('navigate' in action) {
|
|
282
|
+
await page.evaluate((to) => {
|
|
283
|
+
window.history.pushState({}, '', to);
|
|
284
|
+
window.dispatchEvent(new PopStateEvent('popstate'));
|
|
285
|
+
}, action.navigate);
|
|
286
|
+
} else if ('click' in action) {
|
|
287
|
+
await page.evaluate((sel) => {
|
|
288
|
+
const el = document.querySelector(sel);
|
|
289
|
+
if (el) el.click?.();
|
|
290
|
+
}, action.click);
|
|
291
|
+
} else if ('focus' in action) {
|
|
292
|
+
await page.evaluate((sel) => {
|
|
293
|
+
const el = document.querySelector(sel);
|
|
294
|
+
if (el && typeof el.focus === 'function') el.focus();
|
|
295
|
+
}, action.focus);
|
|
296
|
+
} else if ('hover' in action) {
|
|
297
|
+
await page.evaluate((sel) => {
|
|
298
|
+
const el = document.querySelector(sel);
|
|
299
|
+
if (!el) return;
|
|
300
|
+
const rect = el.getBoundingClientRect();
|
|
301
|
+
const init = {
|
|
302
|
+
bubbles: true,
|
|
303
|
+
cancelable: true,
|
|
304
|
+
clientX: rect.left + rect.width / 2,
|
|
305
|
+
clientY: rect.top + rect.height / 2,
|
|
306
|
+
};
|
|
307
|
+
el.dispatchEvent(new MouseEvent('mouseenter', init));
|
|
308
|
+
el.dispatchEvent(new MouseEvent('mouseover', init));
|
|
309
|
+
}, action.hover);
|
|
310
|
+
} else if ('scroll' in action) {
|
|
311
|
+
await page.evaluate((spec) => {
|
|
312
|
+
if ('to' in spec) {
|
|
313
|
+
window.scrollTo({ top: spec.to, behavior: 'smooth' });
|
|
314
|
+
} else {
|
|
315
|
+
const el = document.querySelector(spec.selector);
|
|
316
|
+
if (el) el.scrollIntoView({ behavior: 'smooth', block: 'center' });
|
|
317
|
+
}
|
|
318
|
+
}, action.scroll);
|
|
319
|
+
} else if ('wait' in action) {
|
|
320
|
+
await page.waitForTimeout(action.wait);
|
|
321
|
+
} else if ('simulate_keyboard' in action) {
|
|
322
|
+
const h =
|
|
323
|
+
typeof action.simulate_keyboard === 'number'
|
|
324
|
+
? action.simulate_keyboard
|
|
325
|
+
: action.simulate_keyboard
|
|
326
|
+
? 320
|
|
327
|
+
: 0;
|
|
328
|
+
await page.evaluate((height) => {
|
|
329
|
+
window.dispatchEvent(
|
|
330
|
+
new CustomEvent('keyboard-height', { detail: { height } }),
|
|
331
|
+
);
|
|
332
|
+
}, h);
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
184
336
|
// --- Per-route helpers ----------------------------------------------
|
|
185
337
|
function routeFilenames(route) {
|
|
186
338
|
const slugForFile = route === '/' ? 'home' : route.replace(/[^a-z0-9]+/gi, '-');
|
|
@@ -188,64 +340,69 @@ function routeFilenames(route) {
|
|
|
188
340
|
slugForFile,
|
|
189
341
|
screenshotPath: path.join(SCREENSHOTS_DIR, `${slugForFile}.png`),
|
|
190
342
|
elementMapPath: path.join(SCREENSHOTS_DIR, `${slugForFile}.element-map.json`),
|
|
191
|
-
|
|
343
|
+
legacyUxReportPath: path.join(SCREENSHOTS_DIR, `${slugForFile}.ux-report.json`),
|
|
344
|
+
perInteractionUxReportPath: (name) =>
|
|
345
|
+
path.join(SCREENSHOTS_DIR, `${slugForFile}.${name}.ux-report.json`),
|
|
192
346
|
url: `${BASE_URL}${route}`,
|
|
193
347
|
};
|
|
194
348
|
}
|
|
195
349
|
|
|
196
|
-
async function captureRoute(page, route) {
|
|
197
|
-
const {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
) {
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
350
|
+
async function captureRoute(page, route, interactions) {
|
|
351
|
+
const {
|
|
352
|
+
screenshotPath,
|
|
353
|
+
elementMapPath,
|
|
354
|
+
legacyUxReportPath,
|
|
355
|
+
perInteractionUxReportPath,
|
|
356
|
+
url,
|
|
357
|
+
} = routeFilenames(route);
|
|
358
|
+
for (const interaction of interactions) {
|
|
359
|
+
try {
|
|
360
|
+
await page.goto(url, { waitUntil: 'networkidle', timeout: 15_000 });
|
|
361
|
+
} catch (err) {
|
|
362
|
+
console.error(
|
|
363
|
+
`[${SLUG}] ${interaction.name}: failed to load ${url}: ${err.message}`,
|
|
364
|
+
);
|
|
365
|
+
return false;
|
|
366
|
+
}
|
|
367
|
+
let uxReport = null;
|
|
368
|
+
try {
|
|
369
|
+
const mark = await page.evaluate(
|
|
370
|
+
() => window.__uglyInspectMark?.() ?? Date.now(),
|
|
371
|
+
);
|
|
372
|
+
for (const action of interaction.actions) {
|
|
373
|
+
await runAction(page, action);
|
|
374
|
+
}
|
|
375
|
+
// Settle long enough for the smooth-scroll / hover transition to
|
|
376
|
+
// finish before reading. 800ms matches the studio inspect_ux
|
|
377
|
+
// default so reports are comparable across harnesses.
|
|
378
|
+
await page.waitForTimeout(800);
|
|
379
|
+
uxReport = await page.evaluate(
|
|
380
|
+
(s) => window.__uglyInspect?.({ since: s }) ?? null,
|
|
381
|
+
mark,
|
|
382
|
+
);
|
|
383
|
+
} catch {
|
|
384
|
+
// window.__uglyInspect not installed (pre-0.1.489 ugly-app) — leave
|
|
385
|
+
// uxReport null so downstream skills can detect the absence.
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// The mount interaction owns the canonical screenshot + element-map
|
|
389
|
+
// (clean DOM, no hover/focus state baked in) and the legacy
|
|
390
|
+
// single-report path. Subsequent interactions only emit their own
|
|
391
|
+
// ux-report file.
|
|
392
|
+
if (interaction.name === 'mount') {
|
|
393
|
+
await page.screenshot({ path: screenshotPath, fullPage: true });
|
|
394
|
+
const elementMap = await captureElementMap(page);
|
|
395
|
+
fs.writeFileSync(elementMapPath, JSON.stringify(elementMap, null, 2));
|
|
396
|
+
if (uxReport) {
|
|
397
|
+
fs.writeFileSync(legacyUxReportPath, JSON.stringify(uxReport, null, 2));
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
if (uxReport) {
|
|
401
|
+
fs.writeFileSync(
|
|
402
|
+
perInteractionUxReportPath(interaction.name),
|
|
403
|
+
JSON.stringify(uxReport, null, 2),
|
|
404
|
+
);
|
|
405
|
+
}
|
|
249
406
|
}
|
|
250
407
|
return true;
|
|
251
408
|
}
|
|
@@ -311,14 +468,17 @@ if (MODE === 'capture' || MODE === 'both') {
|
|
|
311
468
|
},
|
|
312
469
|
]);
|
|
313
470
|
const page = await ctx.newPage();
|
|
471
|
+
const interactions = loadInteractions();
|
|
314
472
|
for (const route of pages) {
|
|
315
|
-
const ok = await captureRoute(page, route);
|
|
473
|
+
const ok = await captureRoute(page, route, interactions);
|
|
316
474
|
if (ok && MODE === 'both') {
|
|
317
475
|
await submitForRoute(route);
|
|
318
476
|
}
|
|
319
477
|
}
|
|
320
478
|
await browser.close();
|
|
321
|
-
console.log(
|
|
479
|
+
console.log(
|
|
480
|
+
`[${SLUG}] ${MODE === 'both' ? 'done' : 'captured'} — ${pages.length} pages × ${interactions.length} interactions.`,
|
|
481
|
+
);
|
|
322
482
|
} else {
|
|
323
483
|
// MODE === 'submit' — no Playwright needed, just post the findings.
|
|
324
484
|
for (const route of pages) {
|