nativeapptemplate-agent 0.1.2 → 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.
- package/CLAUDE.md +9 -7
- package/README.md +65 -21
- package/dist/agents/judge.d.ts +8 -0
- package/dist/agents/judge.d.ts.map +1 -1
- package/dist/agents/judge.js +100 -14
- package/dist/agents/judge.js.map +1 -1
- package/dist/agents/repair.d.ts +14 -0
- package/dist/agents/repair.d.ts.map +1 -0
- package/dist/agents/repair.js +103 -0
- package/dist/agents/repair.js.map +1 -0
- package/dist/agents/types.d.ts +34 -1
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/dispatch.d.ts +21 -2
- package/dist/dispatch.d.ts.map +1 -1
- package/dist/dispatch.js +250 -14
- package/dist/dispatch.js.map +1 -1
- package/dist/env-bridge.d.ts +17 -0
- package/dist/env-bridge.d.ts.map +1 -0
- package/dist/env-bridge.js +211 -0
- package/dist/env-bridge.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +88 -3
- package/dist/index.js.map +1 -1
- package/dist/mcp.d.ts +5 -0
- package/dist/mcp.d.ts.map +1 -0
- package/dist/mcp.js +83 -0
- package/dist/mcp.js.map +1 -0
- package/dist/mobile.d.ts +30 -0
- package/dist/mobile.d.ts.map +1 -0
- package/dist/mobile.js +173 -0
- package/dist/mobile.js.map +1 -0
- package/dist/rails-lifecycle.d.ts +16 -0
- package/dist/rails-lifecycle.d.ts.map +1 -0
- package/dist/rails-lifecycle.js +184 -0
- package/dist/rails-lifecycle.js.map +1 -0
- package/dist/rename-overrides.d.ts +23 -0
- package/dist/rename-overrides.d.ts.map +1 -0
- package/dist/rename-overrides.js +58 -0
- package/dist/rename-overrides.js.map +1 -0
- package/dist/repair-loop.d.ts +25 -0
- package/dist/repair-loop.d.ts.map +1 -0
- package/dist/repair-loop.js +67 -0
- package/dist/repair-loop.js.map +1 -0
- package/dist/report/collect.d.ts +28 -0
- package/dist/report/collect.d.ts.map +1 -0
- package/dist/report/collect.js +117 -0
- package/dist/report/collect.js.map +1 -0
- package/dist/report/model.d.ts +49 -0
- package/dist/report/model.d.ts.map +1 -0
- package/dist/report/model.js +2 -0
- package/dist/report/model.js.map +1 -0
- package/dist/report/render.d.ts +3 -0
- package/dist/report/render.d.ts.map +1 -0
- package/dist/report/render.js +242 -0
- package/dist/report/render.js.map +1 -0
- package/dist/report/theme.d.ts +2 -0
- package/dist/report/theme.d.ts.map +1 -0
- package/dist/report/theme.js +115 -0
- package/dist/report/theme.js.map +1 -0
- package/dist/slug.d.ts +3 -0
- package/dist/slug.d.ts.map +1 -1
- package/dist/slug.js +30 -0
- package/dist/slug.js.map +1 -1
- package/dist/validation/capture.d.ts.map +1 -1
- package/dist/validation/capture.js +19 -2
- package/dist/validation/capture.js.map +1 -1
- package/dist/validation/index.d.ts +6 -0
- package/dist/validation/index.d.ts.map +1 -1
- package/dist/validation/index.js +3 -0
- package/dist/validation/index.js.map +1 -1
- package/dist/validation/launch.d.ts +10 -0
- package/dist/validation/launch.d.ts.map +1 -1
- package/dist/validation/launch.js +103 -5
- package/dist/validation/launch.js.map +1 -1
- package/dist/validation/layer1.d.ts.map +1 -1
- package/dist/validation/layer1.js +12 -4
- package/dist/validation/layer1.js.map +1 -1
- package/dist/validation/scenarios/queue.d.ts +12 -0
- package/dist/validation/scenarios/queue.d.ts.map +1 -0
- package/dist/validation/scenarios/queue.js +204 -0
- package/dist/validation/scenarios/queue.js.map +1 -0
- package/dist/validation/stage2-judge.d.ts +21 -0
- package/dist/validation/stage2-judge.d.ts.map +1 -0
- package/dist/validation/stage2-judge.js +204 -0
- package/dist/validation/stage2-judge.js.map +1 -0
- package/dist/validation/stage2.d.ts +73 -0
- package/dist/validation/stage2.d.ts.map +1 -0
- package/dist/validation/stage2.js +313 -0
- package/dist/validation/stage2.js.map +1 -0
- package/dist/version.d.ts +2 -0
- package/dist/version.d.ts.map +1 -0
- package/dist/version.js +17 -0
- package/dist/version.js.map +1 -0
- package/package.json +6 -3
- package/scripts/ruby/rename.rb +7 -3
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { setTimeout as sleep } from "node:timers/promises";
|
|
3
|
+
import { readFile } from "node:fs/promises";
|
|
4
|
+
import { join } from "node:path";
|
|
5
|
+
import { scrubbedEnv } from "./env.js";
|
|
6
|
+
import { trace } from "./trace.js";
|
|
7
|
+
const DEFAULT_READY_TIMEOUT_MS = 60_000;
|
|
8
|
+
const DEFAULT_SHUTDOWN_GRACE_MS = 5_000;
|
|
9
|
+
export async function startRails(input) {
|
|
10
|
+
const { host, port } = await resolveHostPort(input);
|
|
11
|
+
const url = `http://${host}:${port}`;
|
|
12
|
+
// Two prep steps before bin/dev:
|
|
13
|
+
// 1. bundle install — Layer 2 ran it but gems land in a path
|
|
14
|
+
// bin/rails sees for one-shot CLI; bin/dev needs them again
|
|
15
|
+
// in the same shell context. Idempotent + fast (~1s warm).
|
|
16
|
+
// 2. bin/rails db:prepare — creates+migrates the primary db AND
|
|
17
|
+
// the cable/queue/cache databases the substrate uses
|
|
18
|
+
// (config/database.yml multi-db). Without it, Solid Queue
|
|
19
|
+
// (loaded as a Puma plugin via SOLID_QUEUE_IN_PUMA=true in
|
|
20
|
+
// .env) can't open its queue connection and crashes Puma:
|
|
21
|
+
// "Detected Solid Queue has gone away, stopping Puma".
|
|
22
|
+
trace("dispatch", `rails-lifecycle: bundle install in ${input.outDir}`);
|
|
23
|
+
await runMiseStep(input.outDir, ["bundle", "install"], 180_000, "bundle install");
|
|
24
|
+
trace("dispatch", `rails-lifecycle: bin/rails db:prepare in ${input.outDir}`);
|
|
25
|
+
await runMiseStep(input.outDir, ["bin/rails", "db:prepare"], 60_000, "db:prepare");
|
|
26
|
+
// db:seed_fu — substrate uses the seed-fu gem (NOT standard
|
|
27
|
+
// db:seed). Required because db:prepare only runs seeds on
|
|
28
|
+
// fresh-create; for an already-existing DB it just migrates,
|
|
29
|
+
// leaving PrivacyVersion / TermsVersion empty — which causes
|
|
30
|
+
// signup to 500 in render_create_success when it looks up the
|
|
31
|
+
// current version. seed-fu is idempotent.
|
|
32
|
+
trace("dispatch", `rails-lifecycle: bin/rails db:seed_fu in ${input.outDir}`);
|
|
33
|
+
await runMiseStep(input.outDir, ["bin/rails", "db:seed_fu"], 60_000, "db:seed_fu");
|
|
34
|
+
// Wrap with `mise exec --` so the substrate's pinned Ruby /
|
|
35
|
+
// bundler version activates (substrate's .mise.toml or .tool-versions
|
|
36
|
+
// pins a specific version that may not match system Ruby). Layer 2
|
|
37
|
+
// uses the same wrapper for `bin/rails runner` — match it here so
|
|
38
|
+
// Stage 2's server uses the same toolchain that Layer 2 validated.
|
|
39
|
+
trace("dispatch", `rails-lifecycle: spawning mise exec -- bin/dev in ${input.outDir} (target ${url})`);
|
|
40
|
+
const child = spawn("mise", ["exec", "--", "bin/dev"], {
|
|
41
|
+
cwd: input.outDir,
|
|
42
|
+
env: scrubbedEnv(),
|
|
43
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
44
|
+
detached: false,
|
|
45
|
+
});
|
|
46
|
+
// Drain stdio so the child doesn't block on backed-up pipes; route
|
|
47
|
+
// a tail to the dispatch trace so silent failures (port already in
|
|
48
|
+
// use, missing gem, etc.) surface in tmp/trace/dispatch.log.
|
|
49
|
+
const tail = [];
|
|
50
|
+
const onData = (c) => {
|
|
51
|
+
const text = c.toString("utf8");
|
|
52
|
+
tail.push(text);
|
|
53
|
+
if (tail.length > 50)
|
|
54
|
+
tail.shift();
|
|
55
|
+
};
|
|
56
|
+
child.stdout?.on("data", onData);
|
|
57
|
+
child.stderr?.on("data", onData);
|
|
58
|
+
// Surface child crash before we time out waiting for ready.
|
|
59
|
+
let exitedEarly = false;
|
|
60
|
+
child.on("exit", (code) => {
|
|
61
|
+
exitedEarly = true;
|
|
62
|
+
trace("dispatch", `rails-lifecycle: child exited early (code=${code}); recent output: ${tail.join("").slice(-500)}`);
|
|
63
|
+
});
|
|
64
|
+
const readyTimeoutMs = input.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS;
|
|
65
|
+
const ready = await waitForReady(host, port, readyTimeoutMs, () => exitedEarly);
|
|
66
|
+
if (!ready) {
|
|
67
|
+
child.kill("SIGTERM");
|
|
68
|
+
const lastOutput = tail.join("").slice(-500);
|
|
69
|
+
throw new Error(`Rails server at ${url} did not become ready within ${readyTimeoutMs}ms` +
|
|
70
|
+
(exitedEarly ? ` (child exited early)` : "") +
|
|
71
|
+
`; recent output: ${lastOutput}`);
|
|
72
|
+
}
|
|
73
|
+
trace("dispatch", `rails-lifecycle: server reachable at ${url}`);
|
|
74
|
+
const shutdownGraceMs = input.shutdownGraceMs ?? DEFAULT_SHUTDOWN_GRACE_MS;
|
|
75
|
+
return {
|
|
76
|
+
child,
|
|
77
|
+
url,
|
|
78
|
+
async stop() {
|
|
79
|
+
if (exitedEarly)
|
|
80
|
+
return;
|
|
81
|
+
trace("dispatch", `rails-lifecycle: stopping ${url}`);
|
|
82
|
+
child.kill("SIGTERM");
|
|
83
|
+
const exit = new Promise((resolve) => {
|
|
84
|
+
if (child.exitCode !== null) {
|
|
85
|
+
resolve();
|
|
86
|
+
}
|
|
87
|
+
else {
|
|
88
|
+
child.on("exit", () => resolve());
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
const timeout = sleep(shutdownGraceMs).then(() => {
|
|
92
|
+
if (child.exitCode === null) {
|
|
93
|
+
trace("dispatch", `rails-lifecycle: SIGTERM did not exit in ${shutdownGraceMs}ms; SIGKILL`);
|
|
94
|
+
child.kill("SIGKILL");
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
await Promise.race([exit, timeout]);
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
export async function waitForReady(host, port, timeoutMs, childExitedEarly) {
|
|
102
|
+
const url = `http://${host}:${port}/`;
|
|
103
|
+
const deadline = Date.now() + timeoutMs;
|
|
104
|
+
while (Date.now() < deadline) {
|
|
105
|
+
if (childExitedEarly?.())
|
|
106
|
+
return false;
|
|
107
|
+
try {
|
|
108
|
+
const res = await fetch(url, { signal: AbortSignal.timeout(2_000) });
|
|
109
|
+
// Any HTTP response (even 404) means Rails is up. Network/connection
|
|
110
|
+
// errors throw; we keep polling.
|
|
111
|
+
if (res.status < 500)
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// ECONNREFUSED, EHOSTUNREACH, AbortError — not ready, keep polling.
|
|
116
|
+
}
|
|
117
|
+
await sleep(1_000);
|
|
118
|
+
}
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
async function resolveHostPort(input) {
|
|
122
|
+
if (input.host !== undefined && input.port !== undefined) {
|
|
123
|
+
return { host: input.host, port: input.port };
|
|
124
|
+
}
|
|
125
|
+
// Read from the generated rails dir's .env (which mirrors substrate's
|
|
126
|
+
// .env via the rails worker's verbatim copy).
|
|
127
|
+
const envPath = join(input.outDir, ".env");
|
|
128
|
+
const env = await readDotenv(envPath);
|
|
129
|
+
const host = input.host ?? env["HOST"] ?? "0.0.0.0";
|
|
130
|
+
const portStr = env["PORT"];
|
|
131
|
+
const port = input.port ?? (portStr ? Number.parseInt(portStr, 10) : 3000);
|
|
132
|
+
if (Number.isNaN(port))
|
|
133
|
+
throw new Error(`rails-lifecycle: PORT in ${envPath} is not a number: ${portStr}`);
|
|
134
|
+
return { host, port };
|
|
135
|
+
}
|
|
136
|
+
async function runMiseStep(cwd, args, timeoutMs, label) {
|
|
137
|
+
await new Promise((resolveStep, rejectStep) => {
|
|
138
|
+
const child = spawn("mise", ["exec", "--", ...args], {
|
|
139
|
+
cwd,
|
|
140
|
+
env: scrubbedEnv(),
|
|
141
|
+
stdio: ["ignore", "pipe", "pipe"],
|
|
142
|
+
});
|
|
143
|
+
const out = [];
|
|
144
|
+
child.stdout?.on("data", (c) => out.push(c.toString("utf8")));
|
|
145
|
+
child.stderr?.on("data", (c) => out.push(c.toString("utf8")));
|
|
146
|
+
const timer = setTimeout(() => child.kill("SIGTERM"), timeoutMs);
|
|
147
|
+
child.on("exit", (code) => {
|
|
148
|
+
clearTimeout(timer);
|
|
149
|
+
if (code === 0)
|
|
150
|
+
resolveStep();
|
|
151
|
+
else
|
|
152
|
+
rejectStep(new Error(`${label} exited ${code}: ${out.join("").slice(-800)}`));
|
|
153
|
+
});
|
|
154
|
+
child.on("error", (err) => {
|
|
155
|
+
clearTimeout(timer);
|
|
156
|
+
rejectStep(err);
|
|
157
|
+
});
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
async function readDotenv(path) {
|
|
161
|
+
let raw;
|
|
162
|
+
try {
|
|
163
|
+
raw = await readFile(path, "utf8");
|
|
164
|
+
}
|
|
165
|
+
catch {
|
|
166
|
+
return {};
|
|
167
|
+
}
|
|
168
|
+
const out = {};
|
|
169
|
+
for (const line of raw.split("\n")) {
|
|
170
|
+
const trimmed = line.trim();
|
|
171
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
172
|
+
continue;
|
|
173
|
+
const eq = trimmed.indexOf("=");
|
|
174
|
+
if (eq < 1)
|
|
175
|
+
continue;
|
|
176
|
+
const key = trimmed.slice(0, eq).trim();
|
|
177
|
+
const valueRaw = trimmed.slice(eq + 1).trim();
|
|
178
|
+
const value = valueRaw.replace(/^"(.*)"$/, "$1").replace(/^'(.*)'$/, "$1");
|
|
179
|
+
if (key && value)
|
|
180
|
+
out[key] = value;
|
|
181
|
+
}
|
|
182
|
+
return out;
|
|
183
|
+
}
|
|
184
|
+
//# sourceMappingURL=rails-lifecycle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rails-lifecycle.js","sourceRoot":"","sources":["../src/rails-lifecycle.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Entity, RenamePair } from "./agents/types.js";
|
|
2
|
+
export type OverrideOutcome = {
|
|
3
|
+
kind: "changed";
|
|
4
|
+
from: string;
|
|
5
|
+
was: string;
|
|
6
|
+
to: string;
|
|
7
|
+
} | {
|
|
8
|
+
kind: "noop";
|
|
9
|
+
from: string;
|
|
10
|
+
to: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "unmatched";
|
|
13
|
+
from: string;
|
|
14
|
+
to: string;
|
|
15
|
+
};
|
|
16
|
+
export type ApplyOverridesResult = {
|
|
17
|
+
plan: RenamePair[];
|
|
18
|
+
outcomes: OverrideOutcome[];
|
|
19
|
+
};
|
|
20
|
+
export declare function parseRenamePair(raw: string | undefined): RenamePair | null;
|
|
21
|
+
export declare function applyRenameOverrides(plan: readonly RenamePair[], overrides: readonly RenamePair[]): ApplyOverridesResult;
|
|
22
|
+
export declare function syncEntityNames(entities: readonly Entity[], outcomes: readonly OverrideOutcome[]): readonly Entity[];
|
|
23
|
+
//# sourceMappingURL=rename-overrides.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-overrides.d.ts","sourceRoot":"","sources":["../src/rename-overrides.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAO5D,MAAM,MAAM,eAAe,GACvB;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,GAC1C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAC;AAEpD,MAAM,MAAM,oBAAoB,GAAG;IACjC,IAAI,EAAE,UAAU,EAAE,CAAC;IACnB,QAAQ,EAAE,eAAe,EAAE,CAAC;CAC7B,CAAC;AAKF,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,UAAU,GAAG,IAAI,CAQ1E;AAOD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,SAAS,UAAU,EAAE,EAC3B,SAAS,EAAE,SAAS,UAAU,EAAE,GAC/B,oBAAoB,CAiBtB;AAQD,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,SAAS,MAAM,EAAE,EAC3B,QAAQ,EAAE,SAAS,eAAe,EAAE,GACnC,SAAS,MAAM,EAAE,CAUnB"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
// Parse a single `--rename From=To` value. Splits on the first `=` only;
|
|
2
|
+
// returns null for malformed input (missing flag value, empty side) so the
|
|
3
|
+
// caller can warn and skip rather than push a junk pair into the plan.
|
|
4
|
+
export function parseRenamePair(raw) {
|
|
5
|
+
if (raw === undefined)
|
|
6
|
+
return null;
|
|
7
|
+
const eq = raw.indexOf("=");
|
|
8
|
+
if (eq <= 0)
|
|
9
|
+
return null;
|
|
10
|
+
const from = raw.slice(0, eq).trim();
|
|
11
|
+
const to = raw.slice(eq + 1).trim();
|
|
12
|
+
if (!from || !to)
|
|
13
|
+
return null;
|
|
14
|
+
return { from, to };
|
|
15
|
+
}
|
|
16
|
+
// Merge manual overrides onto the planner's rename plan. Semantics are
|
|
17
|
+
// "change a planned target": an override keys on the substrate token (`from`)
|
|
18
|
+
// and replaces the planner's chosen target (`to`). Overrides whose `from`
|
|
19
|
+
// matches no planned rename are reported as `unmatched` and dropped — we don't
|
|
20
|
+
// silently invent new renames. Later overrides for the same `from` win.
|
|
21
|
+
export function applyRenameOverrides(plan, overrides) {
|
|
22
|
+
const merged = plan.map((p) => ({ ...p }));
|
|
23
|
+
const outcomes = [];
|
|
24
|
+
for (const override of overrides) {
|
|
25
|
+
const target = merged.find((p) => p.from === override.from);
|
|
26
|
+
if (!target) {
|
|
27
|
+
outcomes.push({ kind: "unmatched", from: override.from, to: override.to });
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
if (target.to === override.to) {
|
|
31
|
+
outcomes.push({ kind: "noop", from: override.from, to: override.to });
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
outcomes.push({ kind: "changed", from: override.from, was: target.to, to: override.to });
|
|
35
|
+
target.to = override.to;
|
|
36
|
+
}
|
|
37
|
+
return { plan: merged, outcomes };
|
|
38
|
+
}
|
|
39
|
+
// Keep entity names in step with rename-plan overrides. The planner names each
|
|
40
|
+
// entity after its rename target (e.g. it emits both `Shopkeeper -> Monitor`
|
|
41
|
+
// and an entity `Monitor` that `replaces` Shopkeeper), so a `--rename` that
|
|
42
|
+
// changes the target must also rename the entity or the report contradicts its
|
|
43
|
+
// own rename plan. Only entities whose name still matches the planner's old
|
|
44
|
+
// target are touched — an entity deliberately named differently is left alone.
|
|
45
|
+
export function syncEntityNames(entities, outcomes) {
|
|
46
|
+
const changes = new Map();
|
|
47
|
+
for (const o of outcomes) {
|
|
48
|
+
if (o.kind === "changed")
|
|
49
|
+
changes.set(o.from, { was: o.was, to: o.to });
|
|
50
|
+
}
|
|
51
|
+
if (changes.size === 0)
|
|
52
|
+
return entities;
|
|
53
|
+
return entities.map((e) => {
|
|
54
|
+
const change = changes.get(e.replaces);
|
|
55
|
+
return change && e.name === change.was ? { ...e, name: change.to } : e;
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=rename-overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rename-overrides.js","sourceRoot":"","sources":["../src/rename-overrides.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { Platform, PlatformDetail } from "./agents/types.js";
|
|
2
|
+
import type { RepairAttempt } from "./report/model.js";
|
|
3
|
+
import type { RepairLayer } from "./agents/repair.js";
|
|
4
|
+
export type RevalidateResult = Pick<PlatformDetail, "layer1" | "layer2">;
|
|
5
|
+
export type RepairLoopDeps = {
|
|
6
|
+
repair: (platform: Platform, layer: RepairLayer, detail: PlatformDetail) => Promise<{
|
|
7
|
+
action: string;
|
|
8
|
+
}>;
|
|
9
|
+
revalidate: (platform: Platform) => Promise<RevalidateResult>;
|
|
10
|
+
};
|
|
11
|
+
export type RepairLoopInput = {
|
|
12
|
+
platforms: readonly PlatformDetail[];
|
|
13
|
+
reviewerPass: boolean;
|
|
14
|
+
maxIterations: number;
|
|
15
|
+
deps: RepairLoopDeps;
|
|
16
|
+
};
|
|
17
|
+
export type RepairLoopResult = {
|
|
18
|
+
platforms: PlatformDetail[];
|
|
19
|
+
attempts: RepairAttempt[];
|
|
20
|
+
overallPass: boolean;
|
|
21
|
+
summary: string;
|
|
22
|
+
};
|
|
23
|
+
export declare const REPAIR_ITERATION_CAP = 5;
|
|
24
|
+
export declare function runRepairLoop(input: RepairLoopInput): Promise<RepairLoopResult>;
|
|
25
|
+
//# sourceMappingURL=repair-loop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-loop.d.ts","sourceRoot":"","sources":["../src/repair-loop.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKtD,MAAM,MAAM,gBAAgB,GAAG,IAAI,CAAC,cAAc,EAAE,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAEzE,MAAM,MAAM,cAAc,GAAG;IAG3B,MAAM,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,EAAE,cAAc,KAAK,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAExG,UAAU,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC;CAC/D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,YAAY,EAAE,OAAO,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,cAAc,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B,QAAQ,EAAE,aAAa,EAAE,CAAC;IAC1B,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB,CAAC;AAMF,eAAO,MAAM,oBAAoB,IAAI,CAAC;AAYtC,wBAAsB,aAAa,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA4BrF"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// The CLAUDE.md hard cap: never iterate more than this regardless of the
|
|
2
|
+
// requested maxIterations.
|
|
3
|
+
export const REPAIR_ITERATION_CAP = 5;
|
|
4
|
+
// Bounded self-repair: while a code-repairable layer is failing, repair the
|
|
5
|
+
// highest-priority failure, re-validate that platform, and record the
|
|
6
|
+
// attempt — until everything passes or the iteration cap is hit. Pure
|
|
7
|
+
// control flow: all I/O (the repair agent, the validators) is injected via
|
|
8
|
+
// deps, so this is unit-testable without the LLM or a device.
|
|
9
|
+
//
|
|
10
|
+
// Scope: Layer 1 (leftover tokens) then Layer 2 (build) are the
|
|
11
|
+
// code-repairable, cheaply re-checkable layers. Layer 3 (vision) and the
|
|
12
|
+
// contract reviewer are surfaced but not auto-repaired — a Layer 3 miss is
|
|
13
|
+
// often environmental (e.g. a first-launch system dialog), not a source bug.
|
|
14
|
+
export async function runRepairLoop(input) {
|
|
15
|
+
const cap = Math.min(input.maxIterations, REPAIR_ITERATION_CAP);
|
|
16
|
+
const platforms = input.platforms.map((p) => ({ ...p }));
|
|
17
|
+
const attempts = [];
|
|
18
|
+
for (let iteration = 1; iteration <= cap; iteration++) {
|
|
19
|
+
const target = nextTarget(platforms);
|
|
20
|
+
if (!target)
|
|
21
|
+
break; // no code-repairable failure remains
|
|
22
|
+
const detail = platforms.find((p) => p.platform === target.platform);
|
|
23
|
+
const { action } = await input.deps.repair(target.platform, target.layer, detail);
|
|
24
|
+
const revalidated = await input.deps.revalidate(target.platform);
|
|
25
|
+
const idx = platforms.findIndex((p) => p.platform === target.platform);
|
|
26
|
+
platforms[idx] = { ...platforms[idx], layer1: revalidated.layer1, layer2: revalidated.layer2 };
|
|
27
|
+
const resolved = target.layer === "layer1" ? revalidated.layer1.pass : revalidated.layer2.pass;
|
|
28
|
+
attempts.push({ iteration, failingLayer: target.layer, platform: target.platform, action, resolved });
|
|
29
|
+
if (computeOverall(platforms, input.reviewerPass))
|
|
30
|
+
break;
|
|
31
|
+
}
|
|
32
|
+
return {
|
|
33
|
+
platforms,
|
|
34
|
+
attempts,
|
|
35
|
+
overallPass: computeOverall(platforms, input.reviewerPass),
|
|
36
|
+
summary: summarize(platforms, input.reviewerPass),
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
// Highest-priority code-repairable failure: all Layer 1 misses before any
|
|
40
|
+
// Layer 2 miss (leftover tokens routinely cause the build error, so fixing
|
|
41
|
+
// structure first avoids chasing a downstream symptom).
|
|
42
|
+
function nextTarget(platforms) {
|
|
43
|
+
for (const p of platforms)
|
|
44
|
+
if (!p.layer1.pass)
|
|
45
|
+
return { platform: p.platform, layer: "layer1" };
|
|
46
|
+
for (const p of platforms)
|
|
47
|
+
if (!p.layer2.pass)
|
|
48
|
+
return { platform: p.platform, layer: "layer2" };
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
function computeOverall(platforms, reviewerPass) {
|
|
52
|
+
const layer1And2 = platforms.every((p) => p.layer1.pass && p.layer2.pass);
|
|
53
|
+
const layer3 = platforms.every((p) => p.layer3 === undefined || p.layer3.pass);
|
|
54
|
+
return layer1And2 && layer3 && reviewerPass;
|
|
55
|
+
}
|
|
56
|
+
// Mirrors the judge's one-line summary so the post-repair report reads
|
|
57
|
+
// identically to a first-pass report.
|
|
58
|
+
function summarize(platforms, reviewerPass) {
|
|
59
|
+
const total = platforms.length;
|
|
60
|
+
const l1 = platforms.filter((p) => p.layer1.pass).length;
|
|
61
|
+
const l2 = platforms.filter((p) => p.layer2.pass).length;
|
|
62
|
+
const l3Plats = platforms.filter((p) => p.layer3 !== undefined);
|
|
63
|
+
const l3 = l3Plats.filter((p) => p.layer3.pass).length;
|
|
64
|
+
const l3Summary = l3Plats.length > 0 ? `Layer 3 ${l3}/${l3Plats.length} pass` : "Layer 3 skipped";
|
|
65
|
+
return `Layer 1 ${l1}/${total} pass · Layer 2 ${l2}/${total} pass · ${l3Summary} · reviewer ${reviewerPass ? "PASS" : "FAIL"}`;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=repair-loop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"repair-loop.js","sourceRoot":"","sources":["../src/repair-loop.ts"],"names":[],"mappings":"AAiCA,yEAAyE;AACzE,2BAA2B;AAC3B,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,CAAC;AAEtC,4EAA4E;AAC5E,sEAAsE;AACtE,sEAAsE;AACtE,2EAA2E;AAC3E,8DAA8D;AAC9D,EAAE;AACF,gEAAgE;AAChE,yEAAyE;AACzE,2EAA2E;AAC3E,6EAA6E;AAC7E,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAsB;IACxD,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAAC;IAChE,MAAM,SAAS,GAAqB,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3E,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,IAAI,SAAS,GAAG,CAAC,EAAE,SAAS,IAAI,GAAG,EAAE,SAAS,EAAE,EAAE,CAAC;QACtD,MAAM,MAAM,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM;YAAE,MAAM,CAAC,qCAAqC;QAEzD,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAE,CAAC;QACtE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAElF,MAAM,WAAW,GAAG,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjE,MAAM,GAAG,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,MAAM,CAAC,QAAQ,CAAC,CAAC;QACvE,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC,GAAG,CAAE,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;QAEhG,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,IAAI,CAAC;QAC/F,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC,CAAC;QAEtG,IAAI,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;YAAE,MAAM;IAC3D,CAAC;IAED,OAAO;QACL,SAAS;QACT,QAAQ;QACR,WAAW,EAAE,cAAc,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;QAC1D,OAAO,EAAE,SAAS,CAAC,SAAS,EAAE,KAAK,CAAC,YAAY,CAAC;KAClD,CAAC;AACJ,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,wDAAwD;AACxD,SAAS,UAAU,CAAC,SAAoC;IACtD,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;YAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAChG,KAAK,MAAM,CAAC,IAAI,SAAS;QAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI;YAAE,OAAO,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC;IAChG,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,cAAc,CAAC,SAAoC,EAAE,YAAqB;IACjF,MAAM,UAAU,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1E,MAAM,MAAM,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAC/E,OAAO,UAAU,IAAI,MAAM,IAAI,YAAY,CAAC;AAC9C,CAAC;AAED,uEAAuE;AACvE,sCAAsC;AACtC,SAAS,SAAS,CAAC,SAAoC,EAAE,YAAqB;IAC5E,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;IAC/B,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACzD,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;IAChE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAO,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC;IACxD,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,IAAI,OAAO,CAAC,MAAM,OAAO,CAAC,CAAC,CAAC,iBAAiB,CAAC;IAClG,OAAO,WAAW,EAAE,IAAI,KAAK,mBAAmB,EAAE,IAAI,KAAK,WAAW,SAAS,eAAe,YAAY,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;AACjI,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { DomainSpec, JudgeResult, ReviewerResult } from "../agents/types.js";
|
|
2
|
+
import type { RepairAttempt, RunReport } from "./model.js";
|
|
3
|
+
export type ReportFormat = "html" | "json" | "both";
|
|
4
|
+
export type BuildRunReportInput = {
|
|
5
|
+
spec: string;
|
|
6
|
+
domain: DomainSpec;
|
|
7
|
+
judge: JudgeResult;
|
|
8
|
+
reviewer: ReviewerResult;
|
|
9
|
+
agentVersion: string;
|
|
10
|
+
judgeModel: string;
|
|
11
|
+
visualLevel: 0 | 1 | 2;
|
|
12
|
+
startedAt: number;
|
|
13
|
+
finishedAt: number;
|
|
14
|
+
repairAttempts?: readonly RepairAttempt[];
|
|
15
|
+
};
|
|
16
|
+
export declare function buildRunReport(input: BuildRunReportInput): RunReport;
|
|
17
|
+
export type WriteReportOptions = {
|
|
18
|
+
dir: string;
|
|
19
|
+
format?: ReportFormat;
|
|
20
|
+
embed?: boolean;
|
|
21
|
+
};
|
|
22
|
+
export type ReportPaths = {
|
|
23
|
+
jsonPath?: string;
|
|
24
|
+
htmlPath?: string;
|
|
25
|
+
};
|
|
26
|
+
export declare function writeReport(report: RunReport, options: WriteReportOptions): Promise<ReportPaths>;
|
|
27
|
+
export declare function collectScreenshotPaths(report: RunReport): string[];
|
|
28
|
+
//# sourceMappingURL=collect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.d.ts","sourceRoot":"","sources":["../../src/report/collect.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAElF,OAAO,KAAK,EAAY,aAAa,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAErE,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AAEpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,WAAW,CAAC;IACnB,QAAQ,EAAE,cAAc,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,CAAC;AAIF,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,SAAS,CAqCpE;AAED,MAAM,MAAM,kBAAkB,GAAG;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,wBAAsB,WAAW,CAAC,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,WAAW,CAAC,CAqBtG;AAID,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,EAAE,CAgBlE"}
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
import { copyFile, mkdir, readFile, writeFile } from "node:fs/promises";
|
|
2
|
+
import { basename, isAbsolute, join, resolve } from "node:path";
|
|
3
|
+
import { renderReport } from "./render.js";
|
|
4
|
+
// Pure assembly: fold the run's pieces into the single RunReport
|
|
5
|
+
// aggregate. No I/O — writeReport handles disk.
|
|
6
|
+
export function buildRunReport(input) {
|
|
7
|
+
return {
|
|
8
|
+
meta: {
|
|
9
|
+
spec: input.spec,
|
|
10
|
+
slug: input.domain.slug,
|
|
11
|
+
displayName: input.domain.displayName,
|
|
12
|
+
agentVersion: input.agentVersion,
|
|
13
|
+
judgeModel: input.judgeModel,
|
|
14
|
+
visualLevel: input.visualLevel,
|
|
15
|
+
startedAt: new Date(input.startedAt).toISOString(),
|
|
16
|
+
finishedAt: new Date(input.finishedAt).toISOString(),
|
|
17
|
+
durationMs: input.finishedAt - input.startedAt,
|
|
18
|
+
},
|
|
19
|
+
overallPass: input.judge.overallPass,
|
|
20
|
+
summary: input.judge.summary,
|
|
21
|
+
platforms: input.judge.platforms ?? [],
|
|
22
|
+
reviewer: {
|
|
23
|
+
contractParity: input.reviewer.contractParity,
|
|
24
|
+
diffs: input.reviewer.diffs,
|
|
25
|
+
},
|
|
26
|
+
domain: {
|
|
27
|
+
renamePlan: input.domain.renamePlan.map((r) => ({ from: r.from, to: r.to })),
|
|
28
|
+
entities: input.domain.entities.map((e) => ({
|
|
29
|
+
name: e.name,
|
|
30
|
+
replaces: e.replaces,
|
|
31
|
+
fields: e.fields.map((f) => ({
|
|
32
|
+
name: f.name,
|
|
33
|
+
type: f.type,
|
|
34
|
+
...(f.references !== undefined ? { references: f.references } : {}),
|
|
35
|
+
})),
|
|
36
|
+
...(e.states !== undefined ? { states: e.states } : {}),
|
|
37
|
+
})),
|
|
38
|
+
},
|
|
39
|
+
...(input.repairAttempts && input.repairAttempts.length > 0
|
|
40
|
+
? { repairAttempts: input.repairAttempts }
|
|
41
|
+
: {}),
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
export async function writeReport(report, options) {
|
|
45
|
+
const format = options.format ?? "both";
|
|
46
|
+
const embed = options.embed ?? true;
|
|
47
|
+
await mkdir(options.dir, { recursive: true });
|
|
48
|
+
const paths = {};
|
|
49
|
+
if (format === "json" || format === "both") {
|
|
50
|
+
const jsonPath = join(options.dir, "report.json");
|
|
51
|
+
await writeFile(jsonPath, `${JSON.stringify(report, null, 2)}\n`, "utf8");
|
|
52
|
+
paths.jsonPath = jsonPath;
|
|
53
|
+
}
|
|
54
|
+
if (format === "html" || format === "both") {
|
|
55
|
+
const assets = await resolveAssets(report, options.dir, embed);
|
|
56
|
+
const htmlPath = join(options.dir, "validation-report.html");
|
|
57
|
+
await writeFile(htmlPath, renderReport(report, assets), "utf8");
|
|
58
|
+
paths.htmlPath = htmlPath;
|
|
59
|
+
}
|
|
60
|
+
return paths;
|
|
61
|
+
}
|
|
62
|
+
// Every screenshot file path referenced anywhere in the report,
|
|
63
|
+
// de-duplicated and in stable order.
|
|
64
|
+
export function collectScreenshotPaths(report) {
|
|
65
|
+
const seen = new Set();
|
|
66
|
+
const add = (p) => {
|
|
67
|
+
if (p && !seen.has(p))
|
|
68
|
+
seen.add(p);
|
|
69
|
+
};
|
|
70
|
+
for (const platform of report.platforms) {
|
|
71
|
+
const l3 = platform.layer3;
|
|
72
|
+
if (!l3)
|
|
73
|
+
continue;
|
|
74
|
+
add(l3.screenshotPath);
|
|
75
|
+
const s2 = l3.stage2;
|
|
76
|
+
if (s2) {
|
|
77
|
+
add(s2.representativeScreenshot);
|
|
78
|
+
for (const s of s2.screenshots)
|
|
79
|
+
add(s);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return [...seen];
|
|
83
|
+
}
|
|
84
|
+
// Turn screenshot file paths into render-ready <img src> values. With
|
|
85
|
+
// embed=true each PNG becomes a base64 data: URI (single self-contained
|
|
86
|
+
// file). With embed=false PNGs are copied to <dir>/report-assets/ and
|
|
87
|
+
// referenced by relative path. Unreadable paths are skipped — the
|
|
88
|
+
// renderer shows a placeholder for any path missing from the map.
|
|
89
|
+
async function resolveAssets(report, dir, embed) {
|
|
90
|
+
const paths = collectScreenshotPaths(report);
|
|
91
|
+
if (paths.length === 0)
|
|
92
|
+
return {};
|
|
93
|
+
const map = {};
|
|
94
|
+
const assetsDir = join(dir, "report-assets");
|
|
95
|
+
if (!embed)
|
|
96
|
+
await mkdir(assetsDir, { recursive: true });
|
|
97
|
+
await Promise.all(paths.map(async (p) => {
|
|
98
|
+
const abs = isAbsolute(p) ? p : resolve(process.cwd(), p);
|
|
99
|
+
try {
|
|
100
|
+
if (embed) {
|
|
101
|
+
const buf = await readFile(abs);
|
|
102
|
+
map[p] = `data:image/png;base64,${buf.toString("base64")}`;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
const name = basename(abs);
|
|
106
|
+
await copyFile(abs, join(assetsDir, name));
|
|
107
|
+
map[p] = `report-assets/${name}`;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
// Leave unmapped — renderer renders a "screenshot unavailable"
|
|
112
|
+
// placeholder rather than a broken image.
|
|
113
|
+
}
|
|
114
|
+
}));
|
|
115
|
+
return map;
|
|
116
|
+
}
|
|
117
|
+
//# sourceMappingURL=collect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collect.js","sourceRoot":"","sources":["../../src/report/collect.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import type { PlatformDetail } from "../agents/types.js";
|
|
2
|
+
export type RunReport = {
|
|
3
|
+
meta: RunMeta;
|
|
4
|
+
overallPass: boolean;
|
|
5
|
+
summary: string;
|
|
6
|
+
platforms: readonly PlatformDetail[];
|
|
7
|
+
reviewer: {
|
|
8
|
+
contractParity: "pass" | "fail";
|
|
9
|
+
diffs: readonly string[];
|
|
10
|
+
};
|
|
11
|
+
domain: {
|
|
12
|
+
renamePlan: readonly {
|
|
13
|
+
from: string;
|
|
14
|
+
to: string;
|
|
15
|
+
}[];
|
|
16
|
+
entities: readonly RunReportEntity[];
|
|
17
|
+
};
|
|
18
|
+
repairAttempts?: readonly RepairAttempt[];
|
|
19
|
+
};
|
|
20
|
+
export type RunMeta = {
|
|
21
|
+
spec: string;
|
|
22
|
+
slug: string;
|
|
23
|
+
displayName: string;
|
|
24
|
+
agentVersion: string;
|
|
25
|
+
judgeModel: string;
|
|
26
|
+
visualLevel: 0 | 1 | 2;
|
|
27
|
+
startedAt: string;
|
|
28
|
+
finishedAt: string;
|
|
29
|
+
durationMs: number;
|
|
30
|
+
};
|
|
31
|
+
export type RunReportEntity = {
|
|
32
|
+
name: string;
|
|
33
|
+
replaces: string;
|
|
34
|
+
fields: readonly {
|
|
35
|
+
name: string;
|
|
36
|
+
type: string;
|
|
37
|
+
references?: string;
|
|
38
|
+
}[];
|
|
39
|
+
states?: readonly string[];
|
|
40
|
+
};
|
|
41
|
+
export type RepairAttempt = {
|
|
42
|
+
iteration: number;
|
|
43
|
+
failingLayer: "layer1" | "layer2" | "layer3" | "reviewer";
|
|
44
|
+
platform?: "rails" | "ios" | "android";
|
|
45
|
+
action: string;
|
|
46
|
+
resolved: boolean;
|
|
47
|
+
};
|
|
48
|
+
export type AssetMap = Record<string, string>;
|
|
49
|
+
//# sourceMappingURL=model.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../../src/report/model.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAMzD,MAAM,MAAM,SAAS,GAAG;IACtB,IAAI,EAAE,OAAO,CAAC;IACd,WAAW,EAAE,OAAO,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,SAAS,cAAc,EAAE,CAAC;IACrC,QAAQ,EAAE;QACR,cAAc,EAAE,MAAM,GAAG,MAAM,CAAC;QAChC,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;KAC1B,CAAC;IACF,MAAM,EAAE;QACN,UAAU,EAAE,SAAS;YAAE,IAAI,EAAE,MAAM,CAAC;YAAC,EAAE,EAAE,MAAM,CAAA;SAAE,EAAE,CAAC;QACpD,QAAQ,EAAE,SAAS,eAAe,EAAE,CAAC;KACtC,CAAC;IAGF,cAAc,CAAC,EAAE,SAAS,aAAa,EAAE,CAAC;CAC3C,CAAC;AAEF,MAAM,MAAM,OAAO,GAAG;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvE,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5B,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAAC;IAC1D,QAAQ,CAAC,EAAE,OAAO,GAAG,KAAK,GAAG,SAAS,CAAC;IACvC,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAMF,MAAM,MAAM,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/report/model.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/report/render.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAOtD,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,GAAE,QAAa,GAAG,MAAM,CA4B7E"}
|