@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.
- package/README.md +63 -2
- package/bin/debuff.js +3 -0
- package/client.d.ts +3 -0
- package/dist/agent-link.d.ts +28 -0
- package/dist/agent-link.d.ts.map +1 -0
- package/dist/agent-link.js +122 -0
- package/dist/agent-link.js.map +1 -0
- package/dist/assets/atlas.d.ts +58 -0
- package/dist/assets/atlas.d.ts.map +1 -0
- package/dist/assets/atlas.js +164 -0
- package/dist/assets/atlas.js.map +1 -0
- package/dist/assets/builtin.d.ts +5 -0
- package/dist/assets/builtin.d.ts.map +1 -0
- package/dist/assets/builtin.js +47 -0
- package/dist/assets/builtin.js.map +1 -0
- package/dist/assets/command.d.ts +4 -0
- package/dist/assets/command.d.ts.map +1 -0
- package/dist/assets/command.js +35 -0
- package/dist/assets/command.js.map +1 -0
- package/dist/assets/compile.d.ts +29 -0
- package/dist/assets/compile.d.ts.map +1 -0
- package/dist/assets/compile.js +209 -0
- package/dist/assets/compile.js.map +1 -0
- package/dist/assets/index.d.ts +5 -0
- package/dist/assets/index.d.ts.map +1 -0
- package/dist/assets/index.js +5 -0
- package/dist/assets/index.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +212 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +24 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +53 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/inspect.d.ts +35 -0
- package/dist/inspect.d.ts.map +1 -0
- package/dist/inspect.js +37 -0
- package/dist/inspect.js.map +1 -0
- package/dist/plugin.d.ts +146 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +2 -0
- package/dist/plugin.js.map +1 -0
- package/dist/report.d.ts +26 -0
- package/dist/report.d.ts.map +1 -0
- package/dist/report.js +80 -0
- package/dist/report.js.map +1 -0
- package/dist/scenario/browser.d.ts +6 -0
- package/dist/scenario/browser.d.ts.map +1 -0
- package/dist/scenario/browser.js +47 -0
- package/dist/scenario/browser.js.map +1 -0
- package/dist/scenario/index.d.ts +5 -0
- package/dist/scenario/index.d.ts.map +1 -0
- package/dist/scenario/index.js +4 -0
- package/dist/scenario/index.js.map +1 -0
- package/dist/scenario/run.d.ts +12 -0
- package/dist/scenario/run.d.ts.map +1 -0
- package/dist/scenario/run.js +230 -0
- package/dist/scenario/run.js.map +1 -0
- package/dist/scenario/schema.d.ts +8 -0
- package/dist/scenario/schema.d.ts.map +1 -0
- package/dist/scenario/schema.js +23 -0
- package/dist/scenario/schema.js.map +1 -0
- package/dist/scenario/types.d.ts +96 -0
- package/dist/scenario/types.d.ts.map +1 -0
- package/dist/scenario/types.js +2 -0
- package/dist/scenario/types.js.map +1 -0
- package/dist/vite-plugin.d.ts +18 -0
- package/dist/vite-plugin.d.ts.map +1 -0
- package/dist/vite-plugin.js +122 -0
- package/dist/vite-plugin.js.map +1 -0
- package/dist/vite.d.ts +13 -0
- package/dist/vite.d.ts.map +1 -0
- package/dist/vite.js +24 -0
- package/dist/vite.js.map +1 -0
- package/package.json +63 -4
- package/schema/scenario.schema.json +111 -0
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** JSON summary of a debuff project for agents and tools (`debuff inspect`, MCP `inspect_project`). */
|
|
2
|
+
export declare function inspectProject(root: string): Promise<{
|
|
3
|
+
name: unknown;
|
|
4
|
+
debuff: string;
|
|
5
|
+
dependencies: {};
|
|
6
|
+
config: string | null;
|
|
7
|
+
plugins: {
|
|
8
|
+
name: string;
|
|
9
|
+
apiVersion: 1;
|
|
10
|
+
importers: {
|
|
11
|
+
name: string;
|
|
12
|
+
extensions: string[];
|
|
13
|
+
kind: string;
|
|
14
|
+
}[];
|
|
15
|
+
commands: string[];
|
|
16
|
+
scenarioSteps: string[];
|
|
17
|
+
vite: boolean;
|
|
18
|
+
}[];
|
|
19
|
+
assets: {
|
|
20
|
+
count: number;
|
|
21
|
+
bytes: number;
|
|
22
|
+
byId: Record<string, import("./plugin.js").CompiledEntry>;
|
|
23
|
+
unused: string[];
|
|
24
|
+
warnings: string[];
|
|
25
|
+
};
|
|
26
|
+
build: {
|
|
27
|
+
totals: Record<"asset" | "code" | "html" | "map" | "other", {
|
|
28
|
+
bytes: number;
|
|
29
|
+
gzip: number;
|
|
30
|
+
brotli: number;
|
|
31
|
+
}>;
|
|
32
|
+
} | null;
|
|
33
|
+
runtime: string;
|
|
34
|
+
}>;
|
|
35
|
+
//# sourceMappingURL=inspect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.d.ts","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"AAQA,uGAAuG;AACvG,wBAAsB,cAAc,CAAC,IAAI,EAAE,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BhD"}
|
package/dist/inspect.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { compileAssets, findUnused } from "./assets/index.js";
|
|
4
|
+
import { loadConfig } from "./config.js";
|
|
5
|
+
import { buildReport } from "./report.js";
|
|
6
|
+
const version = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8")).version;
|
|
7
|
+
/** JSON summary of a debuff project for agents and tools (`debuff inspect`, MCP `inspect_project`). */
|
|
8
|
+
export async function inspectProject(root) {
|
|
9
|
+
const pkg = JSON.parse(readFileSync(join(root, "package.json"), "utf8"));
|
|
10
|
+
const config = await loadConfig(root);
|
|
11
|
+
const { manifest, warnings } = await compileAssets(root, { plugins: config.plugins, atlas: config.atlas });
|
|
12
|
+
const dist = join(root, "dist");
|
|
13
|
+
return {
|
|
14
|
+
name: pkg.name,
|
|
15
|
+
debuff: version,
|
|
16
|
+
dependencies: pkg.dependencies ?? {},
|
|
17
|
+
config: config.file ?? null,
|
|
18
|
+
plugins: config.plugins.map((pl) => ({
|
|
19
|
+
name: pl.name,
|
|
20
|
+
apiVersion: pl.apiVersion,
|
|
21
|
+
importers: (pl.assets ?? []).map((i) => ({ name: i.name, extensions: i.extensions, kind: "command" in i ? "command" : "function" })),
|
|
22
|
+
commands: (pl.commands ?? []).map((c) => `${pl.name}:${c.name}`),
|
|
23
|
+
scenarioSteps: (pl.scenarioSteps ?? []).map((s) => `${pl.name}:${s.name}`),
|
|
24
|
+
vite: Boolean(pl.vite),
|
|
25
|
+
})),
|
|
26
|
+
assets: {
|
|
27
|
+
count: Object.keys(manifest.assets).length,
|
|
28
|
+
bytes: Object.values(manifest.assets).reduce((n, a) => n + a.bytes, 0),
|
|
29
|
+
byId: manifest.assets,
|
|
30
|
+
unused: findUnused(root, manifest),
|
|
31
|
+
warnings,
|
|
32
|
+
},
|
|
33
|
+
build: existsSync(dist) ? { totals: buildReport(dist).totals } : null,
|
|
34
|
+
runtime: "Live params and scene state: window.__DEBUFF_DEV__ in the dev server, `debuff scenario`, or the debuff MCP game_* tools.",
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=inspect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../src/inspect.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import type { PluginOption } from "vite";
|
|
2
|
+
/** Manifest entry types the runtime loader understands. */
|
|
3
|
+
export type AssetType = "image" | "json" | "audio" | "text" | "sheet";
|
|
4
|
+
/** One frame of a sprite sheet, in source-image pixels. `duration` is in seconds. */
|
|
5
|
+
export interface SheetFrame {
|
|
6
|
+
x: number;
|
|
7
|
+
y: number;
|
|
8
|
+
w: number;
|
|
9
|
+
h: number;
|
|
10
|
+
duration?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface SheetAnimation {
|
|
13
|
+
/** Indices into `frames`. */
|
|
14
|
+
frames: number[];
|
|
15
|
+
loop?: boolean;
|
|
16
|
+
}
|
|
17
|
+
/** A manifest entry as produced by an importer; the compiler adds `bytes` and `hash`. */
|
|
18
|
+
export interface AssetEntry {
|
|
19
|
+
type: AssetType;
|
|
20
|
+
/** URL relative to the site root, e.g. "assets/hero.png". */
|
|
21
|
+
src: string;
|
|
22
|
+
group?: string;
|
|
23
|
+
/** Uniform sprite grid (from the `name@WxH.png` convention). */
|
|
24
|
+
grid?: {
|
|
25
|
+
frameWidth: number;
|
|
26
|
+
frameHeight: number;
|
|
27
|
+
};
|
|
28
|
+
/** Region of `src` holding this image, when it was packed into an atlas. */
|
|
29
|
+
rect?: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
w: number;
|
|
33
|
+
h: number;
|
|
34
|
+
};
|
|
35
|
+
/** Explicit frames, for `sheet` entries. */
|
|
36
|
+
frames?: SheetFrame[];
|
|
37
|
+
animations?: Record<string, SheetAnimation>;
|
|
38
|
+
}
|
|
39
|
+
export interface CompiledEntry extends AssetEntry {
|
|
40
|
+
bytes: number;
|
|
41
|
+
hash: string;
|
|
42
|
+
}
|
|
43
|
+
/** What an importer is given. Serialised as JSON on stdin for command importers. */
|
|
44
|
+
export interface SourceFile {
|
|
45
|
+
/** Absolute path on disk. */
|
|
46
|
+
path: string;
|
|
47
|
+
/** Path relative to `assets/`, forward slashes. */
|
|
48
|
+
rel: string;
|
|
49
|
+
/** Default asset id derived from the path (group prefix, no extension). */
|
|
50
|
+
id: string;
|
|
51
|
+
/** Preload group (first folder), if any. */
|
|
52
|
+
group?: string;
|
|
53
|
+
/** Lower-case extension including the dot, e.g. ".json". For multi-part matches, the matched suffix. */
|
|
54
|
+
ext: string;
|
|
55
|
+
}
|
|
56
|
+
/** A generated file, served in dev and emitted into the build under `assets/`. */
|
|
57
|
+
export interface GeneratedFile {
|
|
58
|
+
/** Path relative to `assets/`, e.g. "hero.png". */
|
|
59
|
+
path: string;
|
|
60
|
+
contents: string;
|
|
61
|
+
encoding?: "utf8" | "base64";
|
|
62
|
+
}
|
|
63
|
+
/** What an importer returns. Command importers print this as JSON on stdout. */
|
|
64
|
+
export interface ImportResult {
|
|
65
|
+
/** Manifest entries keyed by asset id. Entries without `src` bytes on disk must reference a generated file. */
|
|
66
|
+
assets: Record<string, AssetEntry>;
|
|
67
|
+
/** Files to serve and emit (atlases, transcoded audio…). Sources are never modified. */
|
|
68
|
+
outputs?: GeneratedFile[];
|
|
69
|
+
/** Other source files (relative to `assets/`) this importer handled, so built-ins skip them. */
|
|
70
|
+
consumes?: string[];
|
|
71
|
+
warnings?: string[];
|
|
72
|
+
}
|
|
73
|
+
interface ImporterBase {
|
|
74
|
+
/** Used in errors, cache keys and `debuff inspect`. */
|
|
75
|
+
name: string;
|
|
76
|
+
/** File suffixes this importer claims, matched case-insensitively against the end of the path, e.g. [".aseprite.json"]. */
|
|
77
|
+
extensions: string[];
|
|
78
|
+
}
|
|
79
|
+
/** Runs inside the CLI process. Must be a pure function of the file contents and options. */
|
|
80
|
+
export interface FunctionImporter extends ImporterBase {
|
|
81
|
+
import(file: SourceFile): ImportResult | Promise<ImportResult>;
|
|
82
|
+
}
|
|
83
|
+
/** Runs an external program (any language): `SourceFile` JSON on stdin, `ImportResult` JSON on stdout. */
|
|
84
|
+
export interface CommandImporter extends ImporterBase {
|
|
85
|
+
command: [string, ...string[]];
|
|
86
|
+
}
|
|
87
|
+
export type AssetImporter = FunctionImporter | CommandImporter;
|
|
88
|
+
export interface CommandOption {
|
|
89
|
+
/** cac-style flags, e.g. "--out <dir>" or "-w, --watch". */
|
|
90
|
+
flags: string;
|
|
91
|
+
description: string;
|
|
92
|
+
default?: unknown;
|
|
93
|
+
}
|
|
94
|
+
export interface CommandContext {
|
|
95
|
+
/** Project root. */
|
|
96
|
+
root: string;
|
|
97
|
+
/** Positional arguments after the command name. */
|
|
98
|
+
args: string[];
|
|
99
|
+
/** Parsed options (camelCased). */
|
|
100
|
+
options: Record<string, unknown>;
|
|
101
|
+
/** Emit machine-readable output when true (`--json`). */
|
|
102
|
+
json: boolean;
|
|
103
|
+
}
|
|
104
|
+
/** A CLI command, exposed as `debuff <plugin>:<name>`. */
|
|
105
|
+
export interface CommandDef {
|
|
106
|
+
/** kebab-case; the full command is `<plugin name>:<name>`. */
|
|
107
|
+
name: string;
|
|
108
|
+
description: string;
|
|
109
|
+
options?: CommandOption[];
|
|
110
|
+
/** Return an exit code (0 = success). */
|
|
111
|
+
run(ctx: CommandContext): number | Promise<number>;
|
|
112
|
+
}
|
|
113
|
+
/** What a scenario step handler can do in the running game. */
|
|
114
|
+
export interface StepContext {
|
|
115
|
+
/** Call a `window.__DEBUFF_DEV__` method, e.g. `call("press", "Space")`. */
|
|
116
|
+
call<R = unknown>(method: string, ...args: unknown[]): Promise<R>;
|
|
117
|
+
/** Evaluate a function in the page (Playwright semantics). */
|
|
118
|
+
evaluate<R, A>(fn: (arg: A) => R | Promise<R>, arg: A): Promise<R>;
|
|
119
|
+
}
|
|
120
|
+
/** A scenario step type, used in JSON as `{ "<plugin>:<name>": value }`. */
|
|
121
|
+
export interface StepDef<V = unknown> {
|
|
122
|
+
/** kebab-case; the step key is `<plugin name>:<name>`. */
|
|
123
|
+
name: string;
|
|
124
|
+
description: string;
|
|
125
|
+
/** JSON Schema for the step's value; merged into the scenario schema for editors and agents. */
|
|
126
|
+
schema: Record<string, unknown>;
|
|
127
|
+
/** Return a failure message, or undefined if the step passed. */
|
|
128
|
+
run(value: V, ctx: StepContext): string | undefined | Promise<string | undefined>;
|
|
129
|
+
}
|
|
130
|
+
/** Tooling plugin contract (ADR 0004). */
|
|
131
|
+
export interface ToolingPlugin {
|
|
132
|
+
/** Unique kebab-case id. */
|
|
133
|
+
name: string;
|
|
134
|
+
/** Contract version this plugin targets. */
|
|
135
|
+
apiVersion: 1;
|
|
136
|
+
assets?: AssetImporter[];
|
|
137
|
+
/** CLI commands, namespaced as `debuff <name>:<command>`. */
|
|
138
|
+
commands?: CommandDef[];
|
|
139
|
+
/** Scenario step types, namespaced as `"<name>:<step>"`. */
|
|
140
|
+
scenarioSteps?: StepDef[];
|
|
141
|
+
/** Extra Vite plugins (escape hatch). */
|
|
142
|
+
vite?: PluginOption;
|
|
143
|
+
}
|
|
144
|
+
export declare const TOOLING_API_VERSION = 1;
|
|
145
|
+
export {};
|
|
146
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AA0JA,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC"}
|
package/dist/report.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
export interface FileReport {
|
|
2
|
+
path: string;
|
|
3
|
+
kind: "code" | "html" | "asset" | "map" | "other";
|
|
4
|
+
bytes: number;
|
|
5
|
+
gzip: number;
|
|
6
|
+
brotli: number;
|
|
7
|
+
}
|
|
8
|
+
export interface BuildReport {
|
|
9
|
+
dir: string;
|
|
10
|
+
files: FileReport[];
|
|
11
|
+
totals: Record<FileReport["kind"], {
|
|
12
|
+
bytes: number;
|
|
13
|
+
gzip: number;
|
|
14
|
+
brotli: number;
|
|
15
|
+
}>;
|
|
16
|
+
largestAsset: FileReport | undefined;
|
|
17
|
+
leaks: {
|
|
18
|
+
path: string;
|
|
19
|
+
token: string;
|
|
20
|
+
}[];
|
|
21
|
+
}
|
|
22
|
+
/** Tokens that only exist in dev builds. Kept short so false positives are unlikely. */
|
|
23
|
+
export declare const DEV_TOKENS: string[];
|
|
24
|
+
export declare function buildReport(dir: string): BuildReport;
|
|
25
|
+
export declare function formatReport(r: BuildReport): string;
|
|
26
|
+
//# sourceMappingURL=report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpF,YAAY,EAAE,UAAU,GAAG,SAAS,CAAC;IACrC,KAAK,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAC1C;AAED,wFAAwF;AACxF,eAAO,MAAM,UAAU,UAAqB,CAAC;AAkB7C,wBAAgB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAyBpD;AAID,wBAAgB,YAAY,CAAC,CAAC,EAAE,WAAW,GAAG,MAAM,CA2BnD"}
|
package/dist/report.js
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
2
|
+
import { basename, extname, join, relative, sep } from "node:path";
|
|
3
|
+
import { brotliCompressSync, gzipSync } from "node:zlib";
|
|
4
|
+
import { lime, paint, pink, sky } from "create-debuff";
|
|
5
|
+
import pc from "picocolors";
|
|
6
|
+
/** Tokens that only exist in dev builds. Kept short so false positives are unlikely. */
|
|
7
|
+
export const DEV_TOKENS = ["__DEBUFF_DEV__"];
|
|
8
|
+
function walk(dir) {
|
|
9
|
+
return readdirSync(dir).flatMap((name) => {
|
|
10
|
+
const path = join(dir, name);
|
|
11
|
+
return statSync(path).isDirectory() ? walk(path) : [path];
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
function kindOf(path) {
|
|
15
|
+
const ext = extname(path);
|
|
16
|
+
if (ext === ".map")
|
|
17
|
+
return "map";
|
|
18
|
+
if (ext === ".js" || ext === ".mjs" || ext === ".css")
|
|
19
|
+
return "code";
|
|
20
|
+
if (ext === ".html")
|
|
21
|
+
return "html";
|
|
22
|
+
if (/\.(png|jpe?g|webp|gif|ogg|mp3|wav|m4a|json|txt|woff2?)$/.test(path))
|
|
23
|
+
return "asset";
|
|
24
|
+
return "other";
|
|
25
|
+
}
|
|
26
|
+
export function buildReport(dir) {
|
|
27
|
+
if (!existsSync(dir))
|
|
28
|
+
throw new Error(`No build output at ${dir}. Run \`debuff build\` first.`);
|
|
29
|
+
const files = [];
|
|
30
|
+
const leaks = [];
|
|
31
|
+
for (const file of walk(dir).sort()) {
|
|
32
|
+
if (basename(file).startsWith(".") || basename(file) === "debuff-report.json")
|
|
33
|
+
continue;
|
|
34
|
+
const data = readFileSync(file);
|
|
35
|
+
const path = relative(dir, file).split(sep).join("/");
|
|
36
|
+
const kind = kindOf(path);
|
|
37
|
+
files.push({ path, kind, bytes: data.length, gzip: gzipSync(data).length, brotli: brotliCompressSync(data).length });
|
|
38
|
+
if (kind === "code" || kind === "html") {
|
|
39
|
+
const text = data.toString("utf8");
|
|
40
|
+
for (const token of DEV_TOKENS)
|
|
41
|
+
if (text.includes(token))
|
|
42
|
+
leaks.push({ path, token });
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const zero = () => ({ bytes: 0, gzip: 0, brotli: 0 });
|
|
46
|
+
const totals = { code: zero(), html: zero(), asset: zero(), map: zero(), other: zero() };
|
|
47
|
+
for (const f of files) {
|
|
48
|
+
const t = totals[f.kind];
|
|
49
|
+
t.bytes += f.bytes;
|
|
50
|
+
t.gzip += f.gzip;
|
|
51
|
+
t.brotli += f.brotli;
|
|
52
|
+
}
|
|
53
|
+
const largestAsset = files.filter((f) => f.kind === "asset").sort((a, b) => b.bytes - a.bytes)[0];
|
|
54
|
+
return { dir, files, totals, largestAsset, leaks };
|
|
55
|
+
}
|
|
56
|
+
const kb = (n) => `${(n / 1024).toFixed(1)} kB`;
|
|
57
|
+
export function formatReport(r) {
|
|
58
|
+
const w = Math.max(...r.files.map((f) => f.path.length), 4);
|
|
59
|
+
const kindColor = {
|
|
60
|
+
code: sky,
|
|
61
|
+
html: (s) => paint("violet", s),
|
|
62
|
+
asset: pink,
|
|
63
|
+
map: pc.dim,
|
|
64
|
+
other: pc.dim,
|
|
65
|
+
};
|
|
66
|
+
const lines = [pc.dim(`${"file".padEnd(w)} ${"raw".padStart(9)} ${"gzip".padStart(9)} ${"brotli".padStart(9)}`)];
|
|
67
|
+
for (const f of r.files) {
|
|
68
|
+
lines.push(`${kindColor[f.kind](f.path.padEnd(w))} ${pc.dim(kb(f.bytes).padStart(9))} ${kb(f.gzip).padStart(9)} ${pc.bold(kb(f.brotli).padStart(9))}`);
|
|
69
|
+
}
|
|
70
|
+
lines.push("");
|
|
71
|
+
for (const [kind, t] of Object.entries(r.totals)) {
|
|
72
|
+
if (t.bytes)
|
|
73
|
+
lines.push(`${kindColor[kind](kind.padEnd(6))} ${pc.bold(kb(t.brotli))} brotli ${pc.dim(`${kb(t.gzip)} gzip · ${kb(t.bytes)} raw`)}`);
|
|
74
|
+
}
|
|
75
|
+
if (r.largestAsset)
|
|
76
|
+
lines.push(pc.dim(`largest asset: ${r.largestAsset.path} (${kb(r.largestAsset.bytes)})`));
|
|
77
|
+
lines.push(r.leaks.length ? pc.red(`✖ dev leaks: ${r.leaks.map((l) => `${l.token} in ${l.path}`).join(", ")}`) : lime("✔ dev boundary clean"));
|
|
78
|
+
return lines.join("\n");
|
|
79
|
+
}
|
|
80
|
+
//# sourceMappingURL=report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Call `window.__DEBUFF_DEV__[method](...args)`. */
|
|
2
|
+
export declare function callHook([method, args]: [string, unknown[]]): unknown;
|
|
3
|
+
export declare function hooksReady(): boolean;
|
|
4
|
+
/** Fraction of pixels whose RGB differs by more than `threshold` (sum of channel deltas). 1 if sizes differ. */
|
|
5
|
+
export declare function diffImages([a, b, threshold]: [string, string, number]): Promise<number>;
|
|
6
|
+
//# 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,gHAAgH;AAChH,wBAAsB,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CA4B7F"}
|
|
@@ -0,0 +1,47 @@
|
|
|
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
|
+
/** Fraction of pixels whose RGB differs by more than `threshold` (sum of channel deltas). 1 if sizes differ. */
|
|
17
|
+
export async function diffImages([a, b, threshold]) {
|
|
18
|
+
const load = (src) => new Promise((resolve, reject) => {
|
|
19
|
+
const img = new Image();
|
|
20
|
+
img.onload = () => resolve(img);
|
|
21
|
+
img.onerror = reject;
|
|
22
|
+
img.src = src;
|
|
23
|
+
});
|
|
24
|
+
const [ia, ib] = await Promise.all([load(a), load(b)]);
|
|
25
|
+
if (ia.width !== ib.width || ia.height !== ib.height)
|
|
26
|
+
return 1;
|
|
27
|
+
const read = (img) => {
|
|
28
|
+
const canvas = document.createElement("canvas");
|
|
29
|
+
canvas.width = img.width;
|
|
30
|
+
canvas.height = img.height;
|
|
31
|
+
const ctx = canvas.getContext("2d");
|
|
32
|
+
if (!ctx)
|
|
33
|
+
throw new Error("2D context unavailable");
|
|
34
|
+
ctx.drawImage(img, 0, 0);
|
|
35
|
+
return ctx.getImageData(0, 0, canvas.width, canvas.height).data;
|
|
36
|
+
};
|
|
37
|
+
const da = read(ia);
|
|
38
|
+
const db = read(ib);
|
|
39
|
+
let different = 0;
|
|
40
|
+
for (let i = 0; i < da.length; i += 4) {
|
|
41
|
+
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));
|
|
42
|
+
if (delta > threshold)
|
|
43
|
+
different++;
|
|
44
|
+
}
|
|
45
|
+
return different / (da.length / 4);
|
|
46
|
+
}
|
|
47
|
+
//# 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 { 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,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrG,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 @@
|
|
|
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,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,aAAa,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AACrG,OAAO,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Browser } from "playwright-core";
|
|
2
|
+
import type { 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 function formatScenario(r: ScenarioReport): string;
|
|
12
|
+
//# 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,EAAiB,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;AA2HD,wBAAgB,cAAc,CAAC,CAAC,EAAE,cAAc,GAAG,MAAM,CASxD"}
|