@debuffjp/cli 0.0.0-stage → 0.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.
Files changed (81) hide show
  1. package/README.md +63 -2
  2. package/bin/debuff.js +3 -0
  3. package/client.d.ts +3 -0
  4. package/dist/agent-link.d.ts +28 -0
  5. package/dist/agent-link.d.ts.map +1 -0
  6. package/dist/agent-link.js +122 -0
  7. package/dist/agent-link.js.map +1 -0
  8. package/dist/assets/atlas.d.ts +58 -0
  9. package/dist/assets/atlas.d.ts.map +1 -0
  10. package/dist/assets/atlas.js +164 -0
  11. package/dist/assets/atlas.js.map +1 -0
  12. package/dist/assets/builtin.d.ts +5 -0
  13. package/dist/assets/builtin.d.ts.map +1 -0
  14. package/dist/assets/builtin.js +47 -0
  15. package/dist/assets/builtin.js.map +1 -0
  16. package/dist/assets/command.d.ts +4 -0
  17. package/dist/assets/command.d.ts.map +1 -0
  18. package/dist/assets/command.js +35 -0
  19. package/dist/assets/command.js.map +1 -0
  20. package/dist/assets/compile.d.ts +29 -0
  21. package/dist/assets/compile.d.ts.map +1 -0
  22. package/dist/assets/compile.js +209 -0
  23. package/dist/assets/compile.js.map +1 -0
  24. package/dist/assets/index.d.ts +5 -0
  25. package/dist/assets/index.d.ts.map +1 -0
  26. package/dist/assets/index.js +5 -0
  27. package/dist/assets/index.js.map +1 -0
  28. package/dist/cli.d.ts +3 -0
  29. package/dist/cli.d.ts.map +1 -0
  30. package/dist/cli.js +212 -0
  31. package/dist/cli.js.map +1 -0
  32. package/dist/config.d.ts +24 -0
  33. package/dist/config.d.ts.map +1 -0
  34. package/dist/config.js +53 -0
  35. package/dist/config.js.map +1 -0
  36. package/dist/index.d.ts +11 -0
  37. package/dist/index.d.ts.map +1 -0
  38. package/dist/index.js +10 -0
  39. package/dist/index.js.map +1 -0
  40. package/dist/inspect.d.ts +35 -0
  41. package/dist/inspect.d.ts.map +1 -0
  42. package/dist/inspect.js +37 -0
  43. package/dist/inspect.js.map +1 -0
  44. package/dist/plugin.d.ts +146 -0
  45. package/dist/plugin.d.ts.map +1 -0
  46. package/dist/plugin.js +2 -0
  47. package/dist/plugin.js.map +1 -0
  48. package/dist/report.d.ts +26 -0
  49. package/dist/report.d.ts.map +1 -0
  50. package/dist/report.js +80 -0
  51. package/dist/report.js.map +1 -0
  52. package/dist/scenario/browser.d.ts +6 -0
  53. package/dist/scenario/browser.d.ts.map +1 -0
  54. package/dist/scenario/browser.js +47 -0
  55. package/dist/scenario/browser.js.map +1 -0
  56. package/dist/scenario/index.d.ts +5 -0
  57. package/dist/scenario/index.d.ts.map +1 -0
  58. package/dist/scenario/index.js +4 -0
  59. package/dist/scenario/index.js.map +1 -0
  60. package/dist/scenario/run.d.ts +12 -0
  61. package/dist/scenario/run.d.ts.map +1 -0
  62. package/dist/scenario/run.js +230 -0
  63. package/dist/scenario/run.js.map +1 -0
  64. package/dist/scenario/schema.d.ts +8 -0
  65. package/dist/scenario/schema.d.ts.map +1 -0
  66. package/dist/scenario/schema.js +23 -0
  67. package/dist/scenario/schema.js.map +1 -0
  68. package/dist/scenario/types.d.ts +96 -0
  69. package/dist/scenario/types.d.ts.map +1 -0
  70. package/dist/scenario/types.js +2 -0
  71. package/dist/scenario/types.js.map +1 -0
  72. package/dist/vite-plugin.d.ts +18 -0
  73. package/dist/vite-plugin.d.ts.map +1 -0
  74. package/dist/vite-plugin.js +122 -0
  75. package/dist/vite-plugin.js.map +1 -0
  76. package/dist/vite.d.ts +13 -0
  77. package/dist/vite.d.ts.map +1 -0
  78. package/dist/vite.js +24 -0
  79. package/dist/vite.js.map +1 -0
  80. package/package.json +63 -4
  81. package/schema/scenario.schema.json +111 -0
@@ -0,0 +1,230 @@
1
+ import { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from "node:fs";
2
+ import { basename, join } 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 `capture "${capture}" differs: ${pct(result.diffRatio ?? 1)} of pixels (tolerance ${pct(tolerance)})`;
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 ("set" in step) {
171
+ for (const [path, value] of Object.entries(step.set)) {
172
+ const dot = path.indexOf(".");
173
+ if (dot < 1)
174
+ return `set: "${path}" must be "group.key"`;
175
+ await call("setParam", path.slice(0, dot), path.slice(dot + 1), value);
176
+ }
177
+ }
178
+ else if ("expect" in step) {
179
+ const state = await call("state");
180
+ const failures = Object.entries(step.expect).flatMap(([path, c]) => {
181
+ const m = compare(pick(state, path), c);
182
+ return m ? [`${path}: ${m}`] : [];
183
+ });
184
+ if (failures.length)
185
+ return failures.join("; ");
186
+ }
187
+ else if ("capture" in step) {
188
+ return capture(step.capture, step.tolerance ?? DEFAULT_TOLERANCE);
189
+ }
190
+ else {
191
+ return `Unknown step: ${JSON.stringify(step)}`;
192
+ }
193
+ return undefined;
194
+ }
195
+ /** Baselines are per platform because font rasterisation differs between operating systems. */
196
+ async function compareCapture(page, options, scenario, name, tolerance, dataUrl) {
197
+ const png = Buffer.from(dataUrl.slice(dataUrl.indexOf(",") + 1), "base64");
198
+ const outDir = join(options.root, ".debuff", "captures", scenario);
199
+ const baselineDir = join(options.root, "scenarios", "__baselines__", scenario);
200
+ mkdirSync(outDir, { recursive: true });
201
+ const path = join(outDir, `${name}.png`);
202
+ const baseline = join(baselineDir, `${name}.${process.platform}.png`);
203
+ writeFileSync(path, png);
204
+ const existed = existsSync(baseline);
205
+ if (!existed && options.strict && !options.update)
206
+ return { name, path, baseline, status: "missing" };
207
+ if (!existed || options.update) {
208
+ mkdirSync(baselineDir, { recursive: true });
209
+ writeFileSync(baseline, png);
210
+ return { name, path, baseline, status: existed ? "updated" : "new" };
211
+ }
212
+ const expected = `data:image/png;base64,${readFileSync(baseline).toString("base64")}`;
213
+ const diffRatio = await page.evaluate(diffImages, [dataUrl, expected, PIXEL_THRESHOLD]);
214
+ return { name, path, baseline, status: diffRatio <= tolerance ? "match" : "diff", diffRatio };
215
+ }
216
+ const pct = (n) => `${(n * 100).toFixed(2)}%`;
217
+ export function formatScenario(r) {
218
+ const lines = [`${r.ok ? lime("PASS") : paint("red", "FAIL")} ${pc.bold(r.name)} ${pc.dim(`${r.durationMs} ms`)}`];
219
+ for (const s of r.steps)
220
+ if (!s.ok)
221
+ lines.push(` ${pc.red("✖")} step ${s.index} ${pc.dim(JSON.stringify(s.step))}\n ${s.message}`);
222
+ for (const e of r.errors)
223
+ lines.push(` ${pc.red("✖")} runtime error: ${e.split("\n")[0]}`);
224
+ for (const c of r.captures) {
225
+ const color = c.status === "match" ? lime : c.status === "diff" || c.status === "missing" ? (s) => paint("red", s) : amber;
226
+ lines.push(` ${pc.dim("capture")} ${c.name}: ${color(c.status)}${c.diffRatio !== undefined ? pc.dim(` (${pct(c.diffRatio)})`) : ""}`);
227
+ }
228
+ return lines.join("\n");
229
+ }
230
+ //# 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,96 @@
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
+ /** Assert on dev state paths: "scene", "tick", "state.score", "stats.fps". */
50
+ | {
51
+ expect: Record<string, Comparison>;
52
+ }
53
+ /** Screenshot compared against the per-platform baseline. */
54
+ | {
55
+ capture: string;
56
+ tolerance?: number;
57
+ }
58
+ /** Plugin step: `{ "<plugin>:<step>": value }`. */
59
+ | {
60
+ [pluginStep: `${string}:${string}`]: unknown;
61
+ };
62
+ export interface StepResult {
63
+ index: number;
64
+ step: Step;
65
+ ok: boolean;
66
+ message?: string;
67
+ }
68
+ export interface CaptureResult {
69
+ name: string;
70
+ path: string;
71
+ baseline: string;
72
+ /** `new`: no baseline existed and one was written. `missing`: no baseline and `--strict`. */
73
+ status: "new" | "match" | "diff" | "updated" | "missing";
74
+ diffRatio?: number;
75
+ }
76
+ export interface ScenarioReport {
77
+ name: string;
78
+ ok: boolean;
79
+ steps: StepResult[];
80
+ errors: string[];
81
+ captures: CaptureResult[];
82
+ finalState: unknown;
83
+ durationMs: number;
84
+ }
85
+ export interface RunOptions {
86
+ /** Tooling plugins whose `scenarioSteps` should be available. */
87
+ plugins?: ToolingPlugin[];
88
+ root: string;
89
+ /** Scenario files relative to root. Default: every `scenarios/*.json`. */
90
+ files: string[];
91
+ /** Overwrite baselines with new captures. */
92
+ update: boolean;
93
+ /** Fail when a baseline is missing instead of recording it. */
94
+ strict: boolean;
95
+ }
96
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/scenario/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAElD;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,mDAAmD;IACnD,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,IAAI,EAAE,CAAC;CACf;AAED,sCAAsC;AACtC,MAAM,WAAW,UAAU;IACzB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC3B;AAED,MAAM,MAAM,IAAI;AACd,wCAAwC;AACtC;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE;AAClB,yCAAyC;GACvC;IAAE,KAAK,EAAE,MAAM,CAAA;CAAE,GACjB;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE;AACrB,0EAA0E;GACxE;IAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACzB;IAAE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACjC;IAAE,WAAW,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GACjC;IAAE,SAAS,EAAE,IAAI,CAAA;CAAE;AACrB,8EAA8E;GAC5E;IAAE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,CAAA;CAAE;AAC3C,8EAA8E;GAC5E;IAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;CAAE;AACxC,6DAA6D;GAC3D;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE;AACzC,mDAAmD;GACjD;IAAE,CAAC,UAAU,EAAE,GAAG,MAAM,IAAI,MAAM,EAAE,GAAG,OAAO,CAAA;CAAE,CAAC;AAErD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,IAAI,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,6FAA6F;IAC7F,MAAM,EAAE,KAAK,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,CAAC;IACzD,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,UAAU;IACzB,iEAAiE;IACjE,OAAO,CAAC,EAAE,aAAa,EAAE,CAAC;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0EAA0E;IAC1E,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,6CAA6C;IAC7C,MAAM,EAAE,OAAO,CAAC;IAChB,+DAA+D;IAC/D,MAAM,EAAE,OAAO,CAAC;CACjB"}
@@ -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"}
@@ -0,0 +1,122 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { extname, join, resolve, sep } from "node:path";
3
+ import { attachAgentLink } from "./agent-link.js";
4
+ import { compileAssets } from "./assets/compile.js";
5
+ export const ASSETS_DIR = "assets";
6
+ const URL_PREFIX = `/${ASSETS_DIR}/`;
7
+ const MIME = {
8
+ ".png": "image/png",
9
+ ".jpg": "image/jpeg",
10
+ ".jpeg": "image/jpeg",
11
+ ".webp": "image/webp",
12
+ ".avif": "image/avif",
13
+ ".gif": "image/gif",
14
+ ".json": "application/json",
15
+ ".ogg": "audio/ogg",
16
+ ".opus": "audio/ogg",
17
+ ".mp3": "audio/mpeg",
18
+ ".wav": "audio/wav",
19
+ ".m4a": "audio/mp4",
20
+ ".txt": "text/plain; charset=utf-8",
21
+ };
22
+ /**
23
+ * Serves `<root>/assets/` through the asset pipeline: `/assets/manifest.json` and every file the
24
+ * manifest references, in dev from memory and in builds as emitted files. Files the manifest doesn't
25
+ * reference are not served or shipped.
26
+ */
27
+ export function debuff(options = {}) {
28
+ let root = process.cwd();
29
+ let current;
30
+ const compile = () => {
31
+ current = compileAssets(root, {
32
+ plugins: options.plugins ?? [],
33
+ ...(options.atlas === undefined ? {} : { atlas: options.atlas }),
34
+ }).then((r) => {
35
+ for (const w of r.warnings)
36
+ console.warn(`[debuff] ${w}`);
37
+ return r;
38
+ });
39
+ return current;
40
+ };
41
+ const latest = () => current ?? compile();
42
+ /** Bytes for a URL path under /assets/, or undefined if the manifest doesn't reference it. */
43
+ const read = (r, rel) => {
44
+ if (rel === "manifest.json")
45
+ return Buffer.from(`${JSON.stringify(r.manifest, null, 2)}\n`);
46
+ const generated = r.outputs.get(rel);
47
+ if (generated)
48
+ return generated;
49
+ const referenced = Object.values(r.manifest.assets).some((a) => a.src === `${ASSETS_DIR}/${rel}`);
50
+ const file = resolve(root, ASSETS_DIR, rel);
51
+ const inside = file.startsWith(resolve(root, ASSETS_DIR) + sep);
52
+ return referenced && inside && existsSync(file) ? readFileSync(file) : undefined;
53
+ };
54
+ const core = {
55
+ name: "debuff",
56
+ configResolved(config) {
57
+ root = config.root;
58
+ },
59
+ buildStart() {
60
+ compile();
61
+ },
62
+ configureServer(server) {
63
+ const dir = join(root, ASSETS_DIR);
64
+ server.watcher.add(dir);
65
+ const onChange = (file) => {
66
+ if (!file.startsWith(dir))
67
+ return;
68
+ compile().then(() => server.ws.send({ type: "full-reload" }));
69
+ };
70
+ server.watcher.on("add", onChange);
71
+ server.watcher.on("unlink", onChange);
72
+ server.watcher.on("change", onChange);
73
+ if (options.agentLink)
74
+ attachAgentLink(server, root);
75
+ server.middlewares.use(async (req, res, next) => {
76
+ const url = req.url?.split("?")[0];
77
+ if (!url?.startsWith(URL_PREFIX))
78
+ return next();
79
+ const rel = decodeURIComponent(url.slice(URL_PREFIX.length));
80
+ const body = read(await latest(), rel);
81
+ if (!body) {
82
+ res.statusCode = 404;
83
+ res.end(`[debuff] ${rel} is not in the asset manifest. Run \`debuff assets\` to see what was imported.`);
84
+ return;
85
+ }
86
+ res.setHeader("Content-Type", MIME[extname(rel).toLowerCase()] ?? "application/octet-stream");
87
+ res.setHeader("Cache-Control", "no-cache");
88
+ res.end(body);
89
+ });
90
+ },
91
+ // Preload the manifest and the default group's images so they download alongside the code,
92
+ // instead of only after the game script has run and asked for them.
93
+ async transformIndexHtml() {
94
+ const r = await latest();
95
+ const images = new Set();
96
+ for (const a of Object.values(r.manifest.assets))
97
+ if (a.type === "image" && !a.group)
98
+ images.add(a.src);
99
+ return [
100
+ {
101
+ tag: "link",
102
+ attrs: { rel: "preload", href: `${ASSETS_DIR}/manifest.json`, as: "fetch", crossorigin: "anonymous" },
103
+ injectTo: "head",
104
+ },
105
+ ...[...images].map((href) => ({ tag: "link", attrs: { rel: "preload", href, as: "image" }, injectTo: "head" })),
106
+ ];
107
+ },
108
+ async generateBundle() {
109
+ const r = await latest();
110
+ const files = new Set(["manifest.json", ...r.outputs.keys()]);
111
+ for (const a of Object.values(r.manifest.assets))
112
+ files.add(a.src.slice(ASSETS_DIR.length + 1));
113
+ for (const rel of files) {
114
+ const source = read(r, rel);
115
+ if (source)
116
+ this.emitFile({ type: "asset", fileName: `${ASSETS_DIR}/${rel}`, source });
117
+ }
118
+ },
119
+ };
120
+ return [core, ...(options.plugins ?? []).map((p) => p.vite ?? null)];
121
+ }
122
+ //# sourceMappingURL=vite-plugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite-plugin.js","sourceRoot":"","sources":["../src/vite-plugin.ts"],"names":[],"mappings":"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"}
package/dist/vite.d.ts ADDED
@@ -0,0 +1,13 @@
1
+ import type { InlineConfig, ViteDevServer } from "vite";
2
+ import { type ResolvedConfig } from "./config.js";
3
+ /** Vite config for a debuff project: loads `debuff.config.ts` and respects a project's own vite.config. */
4
+ export declare function viteConfig(root: string, extra?: InlineConfig, config?: ResolvedConfig, link?: {
5
+ agentLink?: boolean;
6
+ }): Promise<InlineConfig>;
7
+ export declare function createDevServer(root: string, options?: {
8
+ port?: number;
9
+ host?: boolean;
10
+ logLevel?: InlineConfig["logLevel"];
11
+ agentLink?: boolean;
12
+ }): Promise<ViteDevServer>;
13
+ //# sourceMappingURL=vite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.d.ts","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AACxD,OAAO,EAAc,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAK9D,2GAA2G;AAC3G,wBAAsB,UAAU,CAC9B,IAAI,EAAE,MAAM,EACZ,KAAK,GAAE,YAAiB,EACxB,MAAM,CAAC,EAAE,cAAc,EACvB,IAAI,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACjC,OAAO,CAAC,YAAY,CAAC,CASvB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,YAAY,CAAC,UAAU,CAAC,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACxG,OAAO,CAAC,aAAa,CAAC,CAaxB"}
package/dist/vite.js ADDED
@@ -0,0 +1,24 @@
1
+ import { existsSync } from "node:fs";
2
+ import { join } from "node:path";
3
+ import { loadConfig } from "./config.js";
4
+ import { debuff } from "./vite-plugin.js";
5
+ const VITE_CONFIG_FILES = ["vite.config.ts", "vite.config.mts", "vite.config.js", "vite.config.mjs"];
6
+ /** Vite config for a debuff project: loads `debuff.config.ts` and respects a project's own vite.config. */
7
+ export async function viteConfig(root, extra = {}, config, link = {}) {
8
+ const resolved = config ?? (await loadConfig(root));
9
+ const hasViteConfig = VITE_CONFIG_FILES.some((f) => existsSync(join(root, f)));
10
+ return {
11
+ root,
12
+ ...(hasViteConfig ? {} : { configFile: false }),
13
+ plugins: debuff({ plugins: resolved.plugins, atlas: resolved.atlas, agentLink: link.agentLink ?? false }),
14
+ ...extra,
15
+ };
16
+ }
17
+ export async function createDevServer(root, options = {}) {
18
+ const { createServer } = await import("vite");
19
+ return createServer(await viteConfig(root, {
20
+ ...(options.logLevel ? { logLevel: options.logLevel } : {}),
21
+ server: { port: options.port ?? 5173, strictPort: false, host: options.host ?? false },
22
+ }, undefined, { agentLink: options.agentLink ?? false }));
23
+ }
24
+ //# sourceMappingURL=vite.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vite.js","sourceRoot":"","sources":["../src/vite.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAuB,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAE1C,MAAM,iBAAiB,GAAG,CAAC,gBAAgB,EAAE,iBAAiB,EAAE,gBAAgB,EAAE,iBAAiB,CAAC,CAAC;AAErG,2GAA2G;AAC3G,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,IAAY,EACZ,KAAK,GAAiB,EAAE,EACxB,MAAuB,EACvB,IAAI,GAA4B,EAAE;IAElC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACpD,MAAM,aAAa,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IAC/E,OAAO;QACL,IAAI;QACJ,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC;QAC/C,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE,QAAQ,CAAC,KAAK,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,IAAI,KAAK,EAAE,CAAC;QACzG,GAAG,KAAK;KACT,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,IAAY,EACZ,OAAO,GAAgG,EAAE;IAEzG,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,YAAY,CACjB,MAAM,UAAU,CACd,IAAI,EACJ;QACE,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3D,MAAM,EAAE,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,IAAI,KAAK,EAAE;KACvF,EACD,SAAS,EACT,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,KAAK,EAAE,CAC1C,CACF,CAAC;AACJ,CAAC"}