@debuffjp/cli 0.0.0-stage → 0.2.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.
Files changed (90) hide show
  1. package/README.md +86 -2
  2. package/aseprite/new-font.lua +31 -0
  3. package/bin/debuff.js +3 -0
  4. package/client.d.ts +3 -0
  5. package/dist/agent-link.d.ts +28 -0
  6. package/dist/agent-link.d.ts.map +1 -0
  7. package/dist/agent-link.js +122 -0
  8. package/dist/agent-link.js.map +1 -0
  9. package/dist/assets/aseprite.d.ts +29 -0
  10. package/dist/assets/aseprite.d.ts.map +1 -0
  11. package/dist/assets/aseprite.js +107 -0
  12. package/dist/assets/aseprite.js.map +1 -0
  13. package/dist/assets/atlas.d.ts +58 -0
  14. package/dist/assets/atlas.d.ts.map +1 -0
  15. package/dist/assets/atlas.js +164 -0
  16. package/dist/assets/atlas.js.map +1 -0
  17. package/dist/assets/builtin.d.ts +5 -0
  18. package/dist/assets/builtin.d.ts.map +1 -0
  19. package/dist/assets/builtin.js +47 -0
  20. package/dist/assets/builtin.js.map +1 -0
  21. package/dist/assets/command.d.ts +4 -0
  22. package/dist/assets/command.d.ts.map +1 -0
  23. package/dist/assets/command.js +35 -0
  24. package/dist/assets/command.js.map +1 -0
  25. package/dist/assets/compile.d.ts +29 -0
  26. package/dist/assets/compile.d.ts.map +1 -0
  27. package/dist/assets/compile.js +209 -0
  28. package/dist/assets/compile.js.map +1 -0
  29. package/dist/assets/index.d.ts +6 -0
  30. package/dist/assets/index.d.ts.map +1 -0
  31. package/dist/assets/index.js +6 -0
  32. package/dist/assets/index.js.map +1 -0
  33. package/dist/cli.d.ts +3 -0
  34. package/dist/cli.d.ts.map +1 -0
  35. package/dist/cli.js +257 -0
  36. package/dist/cli.js.map +1 -0
  37. package/dist/config.d.ts +24 -0
  38. package/dist/config.d.ts.map +1 -0
  39. package/dist/config.js +53 -0
  40. package/dist/config.js.map +1 -0
  41. package/dist/fuzz.d.ts +43 -0
  42. package/dist/fuzz.d.ts.map +1 -0
  43. package/dist/fuzz.js +229 -0
  44. package/dist/fuzz.js.map +1 -0
  45. package/dist/index.d.ts +12 -0
  46. package/dist/index.d.ts.map +1 -0
  47. package/dist/index.js +11 -0
  48. package/dist/index.js.map +1 -0
  49. package/dist/inspect.d.ts +35 -0
  50. package/dist/inspect.d.ts.map +1 -0
  51. package/dist/inspect.js +37 -0
  52. package/dist/inspect.js.map +1 -0
  53. package/dist/plugin.d.ts +146 -0
  54. package/dist/plugin.d.ts.map +1 -0
  55. package/dist/plugin.js +2 -0
  56. package/dist/plugin.js.map +1 -0
  57. package/dist/report.d.ts +26 -0
  58. package/dist/report.d.ts.map +1 -0
  59. package/dist/report.js +80 -0
  60. package/dist/report.js.map +1 -0
  61. package/dist/scenario/browser.d.ts +12 -0
  62. package/dist/scenario/browser.d.ts.map +1 -0
  63. package/dist/scenario/browser.js +59 -0
  64. package/dist/scenario/browser.js.map +1 -0
  65. package/dist/scenario/index.d.ts +5 -0
  66. package/dist/scenario/index.d.ts.map +1 -0
  67. package/dist/scenario/index.js +4 -0
  68. package/dist/scenario/index.js.map +1 -0
  69. package/dist/scenario/run.d.ts +14 -0
  70. package/dist/scenario/run.d.ts.map +1 -0
  71. package/dist/scenario/run.js +255 -0
  72. package/dist/scenario/run.js.map +1 -0
  73. package/dist/scenario/schema.d.ts +8 -0
  74. package/dist/scenario/schema.d.ts.map +1 -0
  75. package/dist/scenario/schema.js +23 -0
  76. package/dist/scenario/schema.js.map +1 -0
  77. package/dist/scenario/types.d.ts +103 -0
  78. package/dist/scenario/types.d.ts.map +1 -0
  79. package/dist/scenario/types.js +2 -0
  80. package/dist/scenario/types.js.map +1 -0
  81. package/dist/vite-plugin.d.ts +18 -0
  82. package/dist/vite-plugin.d.ts.map +1 -0
  83. package/dist/vite-plugin.js +122 -0
  84. package/dist/vite-plugin.js.map +1 -0
  85. package/dist/vite.d.ts +13 -0
  86. package/dist/vite.d.ts.map +1 -0
  87. package/dist/vite.js +25 -0
  88. package/dist/vite.js.map +1 -0
  89. package/package.json +71 -4
  90. package/schema/scenario.schema.json +120 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ /** Call `window.__DEBUFF_DEV__[method](...args)`. */
2
+ export declare function callHook([method, args]: [string, unknown[]]): unknown;
3
+ export declare function hooksReady(): boolean;
4
+ /**
5
+ * Fraction of pixels whose RGB differs by more than `threshold` (sum of channel deltas), 1 if sizes differ,
6
+ * plus a PNG data URL highlighting the differing pixels in red over a faded copy of `a`.
7
+ */
8
+ export declare function diffImages([a, b, threshold]: [string, string, number]): Promise<{
9
+ ratio: number;
10
+ image?: string;
11
+ }>;
12
+ //# sourceMappingURL=browser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.d.ts","sourceRoot":"","sources":["../../src/scenario/browser.ts"],"names":[],"mappings":"AAKA,qDAAqD;AACrD,wBAAgB,QAAQ,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAMrE;AAED,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;;GAGG;AACH,wBAAsB,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAqCxH"}
@@ -0,0 +1,59 @@
1
+ // Functions in this file are serialised by Playwright and run inside the page.
2
+ // They must be self-contained: no imports, no closures over module scope.
3
+ /** Call `window.__DEBUFF_DEV__[method](...args)`. */
4
+ export function callHook([method, args]) {
5
+ const hooks = window.__DEBUFF_DEV__;
6
+ if (!hooks)
7
+ throw new Error("window.__DEBUFF_DEV__ is missing. Call exposeDevHooks(game, { input }) in dev builds.");
8
+ const fn = hooks[method];
9
+ if (typeof fn !== "function")
10
+ throw new Error(`__DEBUFF_DEV__.${method} is not a function`);
11
+ return fn(...args);
12
+ }
13
+ export function hooksReady() {
14
+ return window.__DEBUFF_DEV__?.controlled === true;
15
+ }
16
+ /**
17
+ * Fraction of pixels whose RGB differs by more than `threshold` (sum of channel deltas), 1 if sizes differ,
18
+ * plus a PNG data URL highlighting the differing pixels in red over a faded copy of `a`.
19
+ */
20
+ export async function diffImages([a, b, threshold]) {
21
+ const load = (src) => new Promise((resolve, reject) => {
22
+ const img = new Image();
23
+ img.onload = () => resolve(img);
24
+ img.onerror = reject;
25
+ img.src = src;
26
+ });
27
+ const [ia, ib] = await Promise.all([load(a), load(b)]);
28
+ if (ia.width !== ib.width || ia.height !== ib.height)
29
+ return { ratio: 1 };
30
+ const read = (img) => {
31
+ const canvas = document.createElement("canvas");
32
+ canvas.width = img.width;
33
+ canvas.height = img.height;
34
+ const ctx = canvas.getContext("2d");
35
+ if (!ctx)
36
+ throw new Error("2D context unavailable");
37
+ ctx.drawImage(img, 0, 0);
38
+ return { canvas, ctx, image: ctx.getImageData(0, 0, canvas.width, canvas.height) };
39
+ };
40
+ const out = read(ia);
41
+ const da = out.image.data;
42
+ const db = read(ib).image.data;
43
+ let different = 0;
44
+ for (let i = 0; i < da.length; i += 4) {
45
+ const delta = Math.abs((da[i] ?? 0) - (db[i] ?? 0)) + Math.abs((da[i + 1] ?? 0) - (db[i + 1] ?? 0)) + Math.abs((da[i + 2] ?? 0) - (db[i + 2] ?? 0));
46
+ if (delta > threshold) {
47
+ different++;
48
+ da[i] = 255;
49
+ da[i + 1] = 0;
50
+ da[i + 2] = 0;
51
+ }
52
+ else {
53
+ da[i + 3] = 64;
54
+ }
55
+ }
56
+ out.ctx.putImageData(out.image, 0, 0);
57
+ return { ratio: different / (da.length / 4), image: out.canvas.toDataURL("image/png") };
58
+ }
59
+ //# sourceMappingURL=browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"browser.js","sourceRoot":"","sources":["../../src/scenario/browser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { callHook, diffImages, hooksReady } from "./browser.js";
2
+ export { captureDiffMessage, compare, findScenarios, formatScenario, launchBrowser, pick, runScenarios } from "./run.js";
3
+ export { baseScenarioSchema, scenarioSchema } from "./schema.js";
4
+ export type { CaptureResult, Comparison, RunOptions, Scenario, ScenarioReport, Step, StepResult } from "./types.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/scenario/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACzH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AACjE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,EAAE,cAAc,EAAE,IAAI,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { callHook, diffImages, hooksReady } from "./browser.js";
2
+ export { captureDiffMessage, compare, findScenarios, formatScenario, launchBrowser, pick, runScenarios } from "./run.js";
3
+ export { baseScenarioSchema, scenarioSchema } from "./schema.js";
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/scenario/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAChE,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACzH,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { Browser } from "playwright-core";
2
+ import type { CaptureResult, Comparison, RunOptions, ScenarioReport } from "./types.js";
3
+ export declare function findScenarios(root: string, files: string[]): string[];
4
+ /** Read a dotted path, e.g. "state.player.x". */
5
+ export declare function pick(obj: unknown, path: string): unknown;
6
+ /** Returns a failure message, or undefined if every condition holds. */
7
+ export declare function compare(actual: unknown, c: Comparison): string | undefined;
8
+ /** Launch the system Chrome/Edge (or DEBUFF_BROWSER) through playwright-core. */
9
+ export declare function launchBrowser(): Promise<Browser>;
10
+ export declare function runScenarios(options: RunOptions): Promise<ScenarioReport[]>;
11
+ export declare const UPDATE_HINT = "If this change is intended, run `npx debuff scenario --update`.";
12
+ export declare function captureDiffMessage(capture: string, result: CaptureResult, tolerance: number, root: string): string;
13
+ export declare function formatScenario(r: ScenarioReport): string;
14
+ //# sourceMappingURL=run.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/scenario/run.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,OAAO,EAAQ,MAAM,iBAAiB,CAAC;AAIrD,OAAO,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,UAAU,EAAY,cAAc,EAAoB,MAAM,YAAY,CAAC;AAOpH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAQrE;AAED,iDAAiD;AACjD,wBAAgB,IAAI,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD;AAED,wEAAwE;AACxE,wBAAgB,OAAO,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,CAY1E;AAED,iFAAiF;AACjF,wBAAsB,aAAa,IAAI,OAAO,CAAC,OAAO,CAAC,CAYtD;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,UAAU,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC,CA2BjF;AAqID,eAAO,MAAM,WAAW,oEAAoE,CAAC;AAE7F,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CASlH;AAID,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CASxD"}
@@ -0,0 +1,255 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { basename, join, relative } from "node:path";
3
+ import { amber, lime, paint } from "create-debuff";
4
+ import pc from "picocolors";
5
+ import { createDevServer } from "../vite.js";
6
+ import { callHook, diffImages, hooksReady } from "./browser.js";
7
+ /** Pixels whose summed RGB delta exceeds this count as different (absorbs anti-aliasing noise). */
8
+ const PIXEL_THRESHOLD = 48;
9
+ const DEFAULT_TOLERANCE = 0.002;
10
+ const VIEWPORT = { width: 960, height: 540 };
11
+ export function findScenarios(root, files) {
12
+ if (files.length)
13
+ return files.map((f) => join(root, f));
14
+ const dir = join(root, "scenarios");
15
+ if (!existsSync(dir))
16
+ return [];
17
+ return readdirSync(dir)
18
+ .filter((f) => f.endsWith(".json"))
19
+ .sort()
20
+ .map((f) => join(dir, f));
21
+ }
22
+ /** Read a dotted path, e.g. "state.player.x". */
23
+ export function pick(obj, path) {
24
+ return path.split(".").reduce((o, k) => (o && typeof o === "object" ? o[k] : undefined), obj);
25
+ }
26
+ /** Returns a failure message, or undefined if every condition holds. */
27
+ export function compare(actual, c) {
28
+ const show = (v) => JSON.stringify(v) ?? String(v);
29
+ if ("eq" in c && show(actual) !== show(c.eq))
30
+ return `expected ${show(c.eq)}, got ${show(actual)}`;
31
+ const numeric = c.gt !== undefined || c.gte !== undefined || c.lt !== undefined || c.lte !== undefined || c.approx;
32
+ if (!numeric)
33
+ return undefined;
34
+ if (typeof actual !== "number")
35
+ return `expected a number, got ${show(actual)}`;
36
+ if (c.gt !== undefined && !(actual > c.gt))
37
+ return `expected > ${c.gt}, got ${actual}`;
38
+ if (c.gte !== undefined && !(actual >= c.gte))
39
+ return `expected >= ${c.gte}, got ${actual}`;
40
+ if (c.lt !== undefined && !(actual < c.lt))
41
+ return `expected < ${c.lt}, got ${actual}`;
42
+ if (c.lte !== undefined && !(actual <= c.lte))
43
+ return `expected <= ${c.lte}, got ${actual}`;
44
+ if (c.approx && !(Math.abs(actual - c.approx[0]) <= c.approx[1]))
45
+ return `expected ${c.approx[0]} ± ${c.approx[1]}, got ${actual}`;
46
+ return undefined;
47
+ }
48
+ /** Launch the system Chrome/Edge (or DEBUFF_BROWSER) through playwright-core. */
49
+ export async function launchBrowser() {
50
+ const { chromium } = await import("playwright-core");
51
+ const executablePath = process.env.DEBUFF_BROWSER;
52
+ if (executablePath)
53
+ return chromium.launch({ executablePath });
54
+ for (const channel of ["chrome", "msedge", "chromium"]) {
55
+ try {
56
+ return await chromium.launch({ channel });
57
+ }
58
+ catch {
59
+ // Not installed; try the next channel.
60
+ }
61
+ }
62
+ throw new Error("No Chromium-based browser found. Install Chrome or Edge, or set DEBUFF_BROWSER to a browser executable.");
63
+ }
64
+ export async function runScenarios(options) {
65
+ const files = findScenarios(options.root, options.files);
66
+ if (!files.length)
67
+ throw new Error(`No scenarios found. Add JSON files to ${join(options.root, "scenarios")}.`);
68
+ const server = await createDevServer(options.root, { port: 0, logLevel: "error" });
69
+ await server.listen();
70
+ const base = server.resolvedUrls?.local[0];
71
+ if (!base)
72
+ throw new Error("Dev server did not report a URL");
73
+ const browser = await launchBrowser();
74
+ const reports = [];
75
+ try {
76
+ for (const file of files) {
77
+ const scenario = JSON.parse(readFileSync(file, "utf8"));
78
+ const page = await browser.newPage({ viewport: VIEWPORT, deviceScaleFactor: 1 });
79
+ try {
80
+ reports.push(await runOne(page, base, scenario.name ?? basename(file, ".json"), scenario, options));
81
+ }
82
+ finally {
83
+ await page.close();
84
+ }
85
+ }
86
+ }
87
+ finally {
88
+ await browser.close();
89
+ await server.close();
90
+ }
91
+ const outDir = join(options.root, ".debuff", "reports");
92
+ mkdirSync(outDir, { recursive: true });
93
+ for (const r of reports)
94
+ writeFileSync(join(outDir, `scenario-${r.name}.json`), `${JSON.stringify(r, null, 2)}\n`);
95
+ return reports;
96
+ }
97
+ async function runOne(page, base, name, scenario, options) {
98
+ const started = Date.now();
99
+ const url = new URL(scenario.page ?? "/", base);
100
+ url.searchParams.set("debuff-scenario", "1");
101
+ await page.goto(url.toString());
102
+ await page.waitForFunction(hooksReady, undefined, { timeout: 15_000 });
103
+ const call = (method, ...args) => page.evaluate(callHook, [method, args]);
104
+ const pluginSteps = new Map();
105
+ for (const plugin of options.plugins ?? [])
106
+ for (const def of plugin.scenarioSteps ?? [])
107
+ pluginSteps.set(`${plugin.name}:${def.name}`, def);
108
+ const stepContext = {
109
+ call,
110
+ // Playwright serialises fn into the page; the cast bridges its overloads to our simpler signature.
111
+ evaluate: (fn, arg) => page.evaluate(fn, arg),
112
+ };
113
+ const steps = [];
114
+ const captures = [];
115
+ for (const [index, step] of scenario.steps.entries()) {
116
+ let message;
117
+ try {
118
+ // Plugin steps are namespaced ("plugin:step"); everything else is a built-in step.
119
+ const key = Object.keys(step)[0] ?? "";
120
+ if (key.includes(":")) {
121
+ const plugin = pluginSteps.get(key);
122
+ message = plugin
123
+ ? await plugin.run(step[key], stepContext)
124
+ : `Unknown plugin step "${key}". Is its plugin listed in debuff.config.ts?`;
125
+ }
126
+ else {
127
+ message = await runStep(step, call, async (capture, tolerance) => {
128
+ const result = await compareCapture(page, options, name, capture, tolerance, await call("capture"));
129
+ captures.push(result);
130
+ if (result.status === "diff") {
131
+ return captureDiffMessage(capture, result, tolerance, options.root);
132
+ }
133
+ if (result.status === "missing")
134
+ return `capture "${capture}" has no baseline for ${process.platform} (run with --update)`;
135
+ return undefined;
136
+ });
137
+ }
138
+ }
139
+ catch (err) {
140
+ message = err instanceof Error ? (err.message.split("\n")[0] ?? err.message) : String(err);
141
+ }
142
+ steps.push({ index, step, ok: !message, ...(message ? { message } : {}) });
143
+ }
144
+ const errors = await call("errors");
145
+ return {
146
+ name,
147
+ ok: steps.every((s) => s.ok) && errors.length === 0,
148
+ steps,
149
+ errors,
150
+ captures,
151
+ finalState: await call("state"),
152
+ durationMs: Date.now() - started,
153
+ };
154
+ }
155
+ async function runStep(step, call, capture) {
156
+ if ("wait" in step)
157
+ await call("step", step.wait);
158
+ else if ("press" in step)
159
+ await call("press", step.press);
160
+ else if ("release" in step)
161
+ await call("release", step.release);
162
+ else if ("tap" in step)
163
+ await call("tap", ...step.tap);
164
+ else if ("pointerDown" in step)
165
+ await call("pointerDown", ...step.pointerDown);
166
+ else if ("pointerMove" in step)
167
+ await call("pointerMove", ...step.pointerMove);
168
+ else if ("pointerUp" in step)
169
+ await call("pointerUp");
170
+ else if ("command" in step)
171
+ await call("command", step.command, ...(step.args ?? []));
172
+ else if ("set" in step) {
173
+ for (const [path, value] of Object.entries(step.set)) {
174
+ const dot = path.indexOf(".");
175
+ if (dot < 1)
176
+ return `set: "${path}" must be "group.key"`;
177
+ await call("setParam", path.slice(0, dot), path.slice(dot + 1), value);
178
+ }
179
+ }
180
+ else if ("expect" in step) {
181
+ const state = await call("state");
182
+ const failures = Object.entries(step.expect).flatMap(([path, c]) => {
183
+ const m = compare(pick(state, path), c);
184
+ return m ? [`${path}: ${m}`] : [];
185
+ });
186
+ if (failures.length)
187
+ return failures.join("; ");
188
+ }
189
+ else if ("capture" in step) {
190
+ return capture(step.capture, step.tolerance ?? DEFAULT_TOLERANCE);
191
+ }
192
+ else {
193
+ return `Unknown step: ${JSON.stringify(step)}`;
194
+ }
195
+ return undefined;
196
+ }
197
+ /** Baselines are per platform because font rasterisation differs between operating systems. */
198
+ async function compareCapture(page, options, scenario, name, tolerance, dataUrl) {
199
+ const png = Buffer.from(dataUrl.slice(dataUrl.indexOf(",") + 1), "base64");
200
+ const outDir = join(options.root, ".debuff", "captures", scenario);
201
+ const baselineDir = join(options.root, "scenarios", "__baselines__", scenario);
202
+ mkdirSync(outDir, { recursive: true });
203
+ const path = join(outDir, `${name}.png`);
204
+ const baseline = join(baselineDir, `${name}.${process.platform}.png`);
205
+ writeFileSync(path, png);
206
+ const existed = existsSync(baseline);
207
+ if (!existed && options.strict && !options.update)
208
+ return { name, path, baseline, status: "missing" };
209
+ if (!existed) {
210
+ mkdirSync(baselineDir, { recursive: true });
211
+ writeFileSync(baseline, png);
212
+ return { name, path, baseline, status: "new" };
213
+ }
214
+ const expected = `data:image/png;base64,${readFileSync(baseline).toString("base64")}`;
215
+ const result = await page.evaluate(diffImages, [dataUrl, expected, PIXEL_THRESHOLD]);
216
+ if (result.ratio <= tolerance)
217
+ return { name, path, baseline, status: "match", diffRatio: result.ratio };
218
+ // Only rewrite baselines that actually changed, so `--update` leaves a reviewable diff.
219
+ if (options.update) {
220
+ writeFileSync(baseline, png);
221
+ return { name, path, baseline, status: "updated", diffRatio: result.ratio };
222
+ }
223
+ let diff;
224
+ if (result.image) {
225
+ diff = join(outDir, `${name}.diff.png`);
226
+ writeFileSync(diff, Buffer.from(result.image.slice(result.image.indexOf(",") + 1), "base64"));
227
+ }
228
+ return { name, path, baseline, status: "diff", diffRatio: result.ratio, ...(diff ? { diff } : {}) };
229
+ }
230
+ export const UPDATE_HINT = "If this change is intended, run `npx debuff scenario --update`.";
231
+ export function captureDiffMessage(capture, result, tolerance, root) {
232
+ const rel = (p) => relative(root, p).split("\\").join("/");
233
+ return [
234
+ `capture "${capture}" differs: ${pct(result.diffRatio ?? 1)} of pixels (tolerance ${pct(tolerance)})`,
235
+ ` actual: ${rel(result.path)}`,
236
+ ` baseline: ${rel(result.baseline)}`,
237
+ ...(result.diff ? [` diff: ${rel(result.diff)}`] : []),
238
+ ` ${UPDATE_HINT}`,
239
+ ].join("\n");
240
+ }
241
+ const pct = (n) => `${(n * 100).toFixed(2)}%`;
242
+ export function formatScenario(r) {
243
+ const lines = [`${r.ok ? lime("PASS") : paint("red", "FAIL")} ${pc.bold(r.name)} ${pc.dim(`${r.durationMs} ms`)}`];
244
+ for (const s of r.steps)
245
+ if (!s.ok)
246
+ lines.push(` ${pc.red("✖")} step ${s.index} ${pc.dim(JSON.stringify(s.step))}\n ${s.message}`);
247
+ for (const e of r.errors)
248
+ lines.push(` ${pc.red("✖")} runtime error: ${e.split("\n")[0]}`);
249
+ for (const c of r.captures) {
250
+ const color = c.status === "match" ? lime : c.status === "diff" || c.status === "missing" ? (s) => paint("red", s) : amber;
251
+ lines.push(` ${pc.dim("capture")} ${c.name}: ${color(c.status)}${c.diffRatio !== undefined ? pc.dim(` (${pct(c.diffRatio)})`) : ""}`);
252
+ }
253
+ return lines.join("\n");
254
+ }
255
+ //# sourceMappingURL=run.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/scenario/run.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { ToolingPlugin } from "../plugin.js";
2
+ type JsonObject = Record<string, unknown>;
3
+ /** The built-in scenario schema shipped as `@debuffjp/cli/schema/scenario.schema.json`. */
4
+ export declare function baseScenarioSchema(): JsonObject;
5
+ /** The scenario schema extended with every plugin's step types, for editors and agents. */
6
+ export declare function scenarioSchema(plugins?: readonly ToolingPlugin[]): JsonObject;
7
+ export {};
8
+ //# sourceMappingURL=schema.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/scenario/schema.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1C,2FAA2F;AAC3F,wBAAgB,kBAAkB,IAAI,UAAU,CAE/C;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,OAAO,GAAE,SAAS,aAAa,EAAO,GAAG,UAAU,CAejF"}
@@ -0,0 +1,23 @@
1
+ import { readFileSync } from "node:fs";
2
+ /** The built-in scenario schema shipped as `@debuffjp/cli/schema/scenario.schema.json`. */
3
+ export function baseScenarioSchema() {
4
+ return JSON.parse(readFileSync(new URL("../../schema/scenario.schema.json", import.meta.url), "utf8"));
5
+ }
6
+ /** The scenario schema extended with every plugin's step types, for editors and agents. */
7
+ export function scenarioSchema(plugins = []) {
8
+ const schema = baseScenarioSchema();
9
+ const defs = schema.$defs;
10
+ for (const plugin of plugins) {
11
+ for (const step of plugin.scenarioSteps ?? []) {
12
+ const key = `${plugin.name}:${step.name}`;
13
+ defs.step.oneOf.push({
14
+ type: "object",
15
+ required: [key],
16
+ additionalProperties: false,
17
+ properties: { [key]: { description: step.description, ...step.schema } },
18
+ });
19
+ }
20
+ }
21
+ return schema;
22
+ }
23
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/scenario/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKvC,2FAA2F;AAC3F,MAAM,UAAU,kBAAkB;IAChC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,GAAG,CAAC,mCAAmC,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,CAAe,CAAC;AACvH,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,cAAc,CAAC,OAAO,GAA6B,EAAE;IACnE,MAAM,MAAM,GAAG,kBAAkB,EAAE,CAAC;IACpC,MAAM,IAAI,GAAG,MAAM,CAAC,KAA0C,CAAC;IAC/D,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,aAAa,IAAI,EAAE,EAAE,CAAC;YAC9C,MAAM,GAAG,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;gBACnB,IAAI,EAAE,QAAQ;gBACd,QAAQ,EAAE,CAAC,GAAG,CAAC;gBACf,oBAAoB,EAAE,KAAK;gBAC3B,UAAU,EAAE,EAAE,CAAC,GAAG,CAAC,EAAE,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE;aACzE,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,103 @@
1
+ import type { ToolingPlugin } from "../plugin.js";
2
+ /**
3
+ * A scenario is a JSON file of steps. Time only advances through `wait`, so runs are
4
+ * deterministic. Validate with the JSON Schema in `@debuffjp/cli/schema/scenario.schema.json`.
5
+ */
6
+ export interface Scenario {
7
+ $schema?: string;
8
+ /** Defaults to the file name. */
9
+ name?: string;
10
+ /** Path to open on the dev server. Default "/". */
11
+ page?: string;
12
+ steps: Step[];
13
+ }
14
+ /** All given conditions must hold. */
15
+ export interface Comparison {
16
+ eq?: unknown;
17
+ gt?: number;
18
+ gte?: number;
19
+ lt?: number;
20
+ lte?: number;
21
+ /** `[target, tolerance]` */
22
+ approx?: [number, number];
23
+ }
24
+ export type Step =
25
+ /** Advance N fixed simulation steps. */
26
+ {
27
+ wait: number;
28
+ }
29
+ /** Hold a key (`KeyboardEvent.code`). */
30
+ | {
31
+ press: string;
32
+ } | {
33
+ release: string;
34
+ }
35
+ /** Press and release the pointer at logical coordinates over one step. */
36
+ | {
37
+ tap: [number, number];
38
+ } | {
39
+ pointerDown: [number, number];
40
+ } | {
41
+ pointerMove: [number, number];
42
+ } | {
43
+ pointerUp: true;
44
+ }
45
+ /** Set params: `{ "player.speed": 300 }` sets group "player", key "speed". */
46
+ | {
47
+ set: Record<string, number | boolean>;
48
+ }
49
+ /** Run a command the game registered with `devTools({ commands })`. */
50
+ | {
51
+ command: string;
52
+ args?: unknown[];
53
+ }
54
+ /** Assert on dev state paths: "scene", "tick", "state.score", "stats.fps". */
55
+ | {
56
+ expect: Record<string, Comparison>;
57
+ }
58
+ /** Screenshot compared against the per-platform baseline. */
59
+ | {
60
+ capture: string;
61
+ tolerance?: number;
62
+ }
63
+ /** Plugin step: `{ "<plugin>:<step>": value }`. */
64
+ | {
65
+ [pluginStep: `${string}:${string}`]: unknown;
66
+ };
67
+ export interface StepResult {
68
+ index: number;
69
+ step: Step;
70
+ ok: boolean;
71
+ message?: string;
72
+ }
73
+ export interface CaptureResult {
74
+ name: string;
75
+ path: string;
76
+ baseline: string;
77
+ /** `new`: no baseline existed and one was written. `missing`: no baseline and `--strict`. */
78
+ status: "new" | "match" | "diff" | "updated" | "missing";
79
+ diffRatio?: number;
80
+ /** Image highlighting the differing pixels, written when `status` is `diff` and sizes match. */
81
+ diff?: string;
82
+ }
83
+ export interface ScenarioReport {
84
+ name: string;
85
+ ok: boolean;
86
+ steps: StepResult[];
87
+ errors: string[];
88
+ captures: CaptureResult[];
89
+ finalState: unknown;
90
+ durationMs: number;
91
+ }
92
+ export interface RunOptions {
93
+ /** Tooling plugins whose `scenarioSteps` should be available. */
94
+ plugins?: ToolingPlugin[];
95
+ root: string;
96
+ /** Scenario files relative to root. Default: every `scenarios/*.json`. */
97
+ files: string[];
98
+ /** Overwrite baselines with new captures. */
99
+ update: boolean;
100
+ /** Fail when a baseline is missing instead of recording it. */
101
+ strict: boolean;
102
+ }
103
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scenario/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/scenario/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ import type { PluginOption } from "vite";
2
+ import type { AtlasOptions } from "./assets/atlas.js";
3
+ import type { ToolingPlugin } from "./plugin.js";
4
+ export declare const ASSETS_DIR = "assets";
5
+ export interface DebuffViteOptions {
6
+ plugins?: ToolingPlugin[];
7
+ /** Atlas packing options; `false` disables. Default on. */
8
+ atlas?: AtlasOptions | false;
9
+ /** Relay agent commands to the game open in the browser (`debuff dev` turns this on). Default false. */
10
+ agentLink?: boolean;
11
+ }
12
+ /**
13
+ * Serves `<root>/assets/` through the asset pipeline: `/assets/manifest.json` and every file the
14
+ * manifest references, in dev from memory and in builds as emitted files. Files the manifest doesn't
15
+ * reference are not served or shipped.
16
+ */
17
+ export declare function debuff(options?: DebuffViteOptions): PluginOption[];
18
+ //# sourceMappingURL=vite-plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.d.ts","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAU,YAAY,EAAE,MAAM,MAAM,CAAC;AAEjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEtD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,UAAU,WAAW,CAAC;AAmBnC,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,2DAA2D;IAC3D,KAAK,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC;IAC7B,wGAAwG;IACxG,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,iBAAsB,GAAG,YAAY,EAAE,CAsFtE"}