unity-open-mcp 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. package/dist/capabilities/cost-hints.js +73 -0
  2. package/dist/capabilities/cost-hints.js.map +1 -1
  3. package/dist/capabilities/intent-groups.js +76 -4
  4. package/dist/capabilities/intent-groups.js.map +1 -1
  5. package/dist/capabilities/lifecycle.js +9 -0
  6. package/dist/capabilities/lifecycle.js.map +1 -1
  7. package/dist/capabilities/tool-groups.js +75 -17
  8. package/dist/capabilities/tool-groups.js.map +1 -1
  9. package/dist/constants.d.ts +2 -2
  10. package/dist/constants.js +2 -2
  11. package/dist/event-stream.d.ts +10 -0
  12. package/dist/event-stream.js +29 -0
  13. package/dist/event-stream.js.map +1 -1
  14. package/dist/game-view-settle.d.ts +18 -0
  15. package/dist/game-view-settle.js +81 -0
  16. package/dist/game-view-settle.js.map +1 -0
  17. package/dist/jobs/adapters.d.ts +59 -0
  18. package/dist/jobs/adapters.js +226 -0
  19. package/dist/jobs/adapters.js.map +1 -1
  20. package/dist/live-client.d.ts +10 -0
  21. package/dist/live-client.js +26 -3
  22. package/dist/live-client.js.map +1 -1
  23. package/dist/local-tools.js +3 -0
  24. package/dist/local-tools.js.map +1 -1
  25. package/dist/playmode-routes.d.ts +17 -0
  26. package/dist/playmode-routes.js +50 -0
  27. package/dist/playmode-routes.js.map +1 -0
  28. package/dist/playtest/png.d.ts +27 -0
  29. package/dist/playtest/png.js +248 -0
  30. package/dist/playtest/png.js.map +1 -0
  31. package/dist/playtest/recorder.d.ts +203 -0
  32. package/dist/playtest/recorder.js +945 -0
  33. package/dist/playtest/recorder.js.map +1 -0
  34. package/dist/playtest/redact.d.ts +16 -0
  35. package/dist/playtest/redact.js +124 -0
  36. package/dist/playtest/redact.js.map +1 -0
  37. package/dist/playtest/report.d.ts +73 -0
  38. package/dist/playtest/report.js +477 -0
  39. package/dist/playtest/report.js.map +1 -0
  40. package/dist/playtest/session-store.d.ts +78 -0
  41. package/dist/playtest/session-store.js +224 -0
  42. package/dist/playtest/session-store.js.map +1 -0
  43. package/dist/skill/SKILL.md +20 -3
  44. package/dist/skill/references/senses-and-tests.md +3 -0
  45. package/dist/tool-router.d.ts +44 -0
  46. package/dist/tool-router.js +235 -2
  47. package/dist/tool-router.js.map +1 -1
  48. package/dist/tools/batch-execute.js +5 -1
  49. package/dist/tools/batch-execute.js.map +1 -1
  50. package/dist/tools/capture-inline.js +30 -12
  51. package/dist/tools/capture-inline.js.map +1 -1
  52. package/dist/tools/capture-series.d.ts +46 -0
  53. package/dist/tools/capture-series.js +116 -0
  54. package/dist/tools/capture-series.js.map +1 -0
  55. package/dist/tools/game-view.d.ts +44 -0
  56. package/dist/tools/game-view.js +103 -0
  57. package/dist/tools/game-view.js.map +1 -0
  58. package/dist/tools/index.d.ts +1 -0
  59. package/dist/tools/index.js +34 -7
  60. package/dist/tools/index.js.map +1 -1
  61. package/dist/tools/inputsim-gesture.d.ts +46 -0
  62. package/dist/tools/inputsim-gesture.js +123 -0
  63. package/dist/tools/inputsim-gesture.js.map +1 -0
  64. package/dist/tools/inputsim-pointer.js +35 -2
  65. package/dist/tools/inputsim-pointer.js.map +1 -1
  66. package/dist/tools/inputsim-touch.js +42 -22
  67. package/dist/tools/inputsim-touch.js.map +1 -1
  68. package/dist/tools/jobs.js +1 -1
  69. package/dist/tools/jobs.js.map +1 -1
  70. package/dist/tools/player-state.d.ts +42 -0
  71. package/dist/tools/player-state.js +142 -0
  72. package/dist/tools/player-state.js.map +1 -0
  73. package/dist/tools/playtest-conditions.d.ts +334 -0
  74. package/dist/tools/playtest-conditions.js +99 -0
  75. package/dist/tools/playtest-conditions.js.map +1 -0
  76. package/dist/tools/playtest-session.d.ts +45 -0
  77. package/dist/tools/playtest-session.js +105 -0
  78. package/dist/tools/playtest-session.js.map +1 -0
  79. package/dist/tools/playtest-wait.d.ts +46 -0
  80. package/dist/tools/playtest-wait.js +86 -0
  81. package/dist/tools/playtest-wait.js.map +1 -0
  82. package/dist/tools/screenshot.js +31 -8
  83. package/dist/tools/screenshot.js.map +1 -1
  84. package/dist/tools/text-target.d.ts +22 -0
  85. package/dist/tools/text-target.js +39 -0
  86. package/dist/tools/text-target.js.map +1 -0
  87. package/dist/tools/ui-snapshot.d.ts +41 -0
  88. package/dist/tools/ui-snapshot.js +87 -0
  89. package/dist/tools/ui-snapshot.js.map +1 -0
  90. package/package.json +1 -1
@@ -0,0 +1,477 @@
1
+ // Playtest session report — `end` turns the session log into a self-contained
2
+ // folder a human can open: report.md + the full frames (already linked into
3
+ // report/frames/ during the session) + downscaled thumbnails in report/thumbs/.
4
+ // Steps are the calls between two `mark`s, each with its verdict and note;
5
+ // every console error / exception is listed once with its first occurrence
6
+ // (step, call, during / after it) and stack; the player-state diff from the
7
+ // session's snapshot and the editor events (play mode, domain reloads) close
8
+ // it. Calls that were in flight when an earlier MCP server process stopped are
9
+ // reported as lost; calls of the ending process that had not returned yet, as
10
+ // still running at end.
11
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
12
+ import { join } from "node:path";
13
+ import { thumbnail } from "./png.js";
14
+ import { REPORT_DIR, REPORT_FILE, THUMBS_DIR } from "./session-store.js";
15
+ const cell = (value) => value.replace(/\|/g, "\\|").replace(/\r?\n/g, " ");
16
+ const code = (value) => "`" + value.replace(/`/g, "'") + "`";
17
+ // A code span inside a table cell: a `|` splits the row even there, so it is escaped too.
18
+ const cellCode = (value) => cell(code(value));
19
+ const clip = (value, max) => (value.length > max ? `${value.slice(0, max)}…` : value);
20
+ const firstLine = (value) => value.split("\n")[0].trim();
21
+ const shortTool = (tool) => tool.replace(/^unity_open_mcp_/, "").replace(/^unity_senses_/, "senses_");
22
+ const time = (isoText) => (isoText ? isoText.replace(/^.*T/, "").replace("Z", "") : "");
23
+ // One row per message: the event stream says Exception / Assert where a response's logs[] says error.
24
+ const errorKey = (e) => firstLine(String(e.message ?? "")).slice(0, 200);
25
+ const SPECIFIC_TYPES = new Set(["exception", "assert"]);
26
+ const sameMessage = (a, b) => firstLine(String(a.message ?? "")).slice(0, 200) === firstLine(String(b.message ?? "")).slice(0, 200);
27
+ function duration(ms) {
28
+ if (ms < 1000)
29
+ return `${Math.round(ms)} ms`;
30
+ if (ms < 60_000)
31
+ return `${(ms / 1000).toFixed(1)} s`;
32
+ const m = Math.floor(ms / 60_000), s = Math.round((ms % 60_000) / 1000);
33
+ return `${m} min ${s} s`;
34
+ }
35
+ /** Merge an attributed stream error into a call, replacing a stack-less response copy of the same message. */
36
+ function mergeError(list, item) {
37
+ const index = list.findIndex(e => sameMessage(e, item));
38
+ if (index < 0) {
39
+ list.push(item);
40
+ return;
41
+ }
42
+ if (!list[index].stack && item.stack)
43
+ list[index] = { ...list[index], ...item };
44
+ }
45
+ export function writeReport(input) {
46
+ const { dir, meta, entries, redactor } = input;
47
+ const reportDir = join(dir, REPORT_DIR);
48
+ mkdirSync(join(reportDir, THUMBS_DIR), { recursive: true });
49
+ // ---- model -------------------------------------------------------------
50
+ const calls = new Map();
51
+ const started = new Map();
52
+ const orderedEvents = [];
53
+ const editorEvents = [];
54
+ const notes = [];
55
+ const looseErrors = [];
56
+ let endNote;
57
+ let running = new Set();
58
+ let errorRepeats = [];
59
+ let errorsOverLimit = 0, streamGaps = 0, firstGap;
60
+ for (const entry of entries) {
61
+ switch (entry.k) {
62
+ case "call_started":
63
+ started.set(entry.seq, entry);
64
+ orderedEvents.push({ kind: "start", entry });
65
+ break;
66
+ case "call":
67
+ calls.set(entry.seq, {
68
+ seq: entry.seq, tool: entry.tool, kind: entry.kind, at: entry.at, duration_ms: entry.duration_ms ?? 0,
69
+ status: entry.status, args: entry.args ?? started.get(entry.seq)?.args, error: entry.error, summary: entry.summary,
70
+ captures: Array.isArray(entry.captures) ? entry.captures : [], errors: Array.isArray(entry.errors) ? [...entry.errors] : [],
71
+ errorsAfter: [], job_id: entry.job_id, of: entry.of, streamDown: entry.stream === false,
72
+ });
73
+ if (!started.has(entry.seq))
74
+ orderedEvents.push({ kind: "call", entry });
75
+ break;
76
+ case "mark":
77
+ orderedEvents.push({ kind: "mark", entry });
78
+ break;
79
+ case "errors":
80
+ for (const item of Array.isArray(entry.items) ? entry.items : []) {
81
+ const target = typeof item.seq === "number" ? calls.get(item.seq) : undefined;
82
+ if (target && item.relation === "during")
83
+ mergeError(target.errors, item);
84
+ else if (target)
85
+ target.errorsAfter.push(item);
86
+ else
87
+ looseErrors.push(item);
88
+ }
89
+ break;
90
+ case "editor":
91
+ editorEvents.push(entry);
92
+ break;
93
+ case "stream_gap":
94
+ if (streamGaps++ === 0)
95
+ firstGap = `${entry.at} (${entry.detail})`;
96
+ break;
97
+ case "limit":
98
+ notes.push(String(entry.message));
99
+ break;
100
+ case "adopted":
101
+ notes.push(`At ${entry.at} a new MCP server process took the session over from pid ${entry.from_pid}.`);
102
+ break;
103
+ case "end_note":
104
+ endNote = entry.note;
105
+ break;
106
+ case "session_ended":
107
+ if (entry.dropped_calls)
108
+ notes.push(`${entry.dropped_calls} call(s) over the recording limit were not logged.`);
109
+ if (entry.frames_skipped)
110
+ notes.push(`${entry.frames_skipped} frame(s) over the frame limit were referenced, not copied.`);
111
+ running = new Set(Array.isArray(entry.running) ? entry.running : []);
112
+ errorRepeats = Array.isArray(entry.error_repeats) ? entry.error_repeats : [];
113
+ errorsOverLimit = typeof entry.errors_over_limit === "number" ? entry.errors_over_limit : 0;
114
+ if (entry.errors_dropped)
115
+ notes.push(`${entry.errors_dropped} console error(s) arrived while the backlog of one call was full and were dropped (not counted).`);
116
+ break;
117
+ }
118
+ }
119
+ if (streamGaps)
120
+ notes.push(`The bridge event stream reported missed events ${streamGaps} time(s), first at ${firstGap}; errors from those moments may be missing.`);
121
+ // Steps: the calls before each mark belong to it; a call still "started" without
122
+ // a result was lost (an earlier process stopped) or still running at end.
123
+ const steps = [];
124
+ let current = [];
125
+ const lost = [];
126
+ const runningAtEnd = [];
127
+ for (const { kind, entry } of orderedEvents) {
128
+ if (kind === "mark") {
129
+ steps.push({ number: entry.step, label: entry.label, verdict: entry.verdict, note: entry.note, at: entry.at, calls: current });
130
+ current = [];
131
+ continue;
132
+ }
133
+ const row = calls.get(entry.seq);
134
+ if (row) {
135
+ current.push(row);
136
+ continue;
137
+ }
138
+ if (kind === "start") {
139
+ const still = running.has(entry.seq);
140
+ (still ? runningAtEnd : lost).push({ seq: entry.seq, tool: entry.tool, at: entry.at });
141
+ current.push({ seq: entry.seq, tool: entry.tool, kind: entry.kind, at: entry.at, duration_ms: 0, status: still ? "running" : "lost", args: entry.args,
142
+ captures: [], errors: [], errorsAfter: [], ...(still ? { running: true } : { lost: true }) });
143
+ }
144
+ }
145
+ if (current.length)
146
+ steps.push({ number: null, label: "After the last mark", verdict: null, calls: current });
147
+ const catalog = new Map();
148
+ let totalErrors = 0;
149
+ const record = (e, step, call, relation) => {
150
+ totalErrors++;
151
+ const key = errorKey(e);
152
+ const row = catalog.get(key);
153
+ if (row) {
154
+ row.count++;
155
+ if (!row.stack && e.stack)
156
+ row.stack = e.stack;
157
+ if (SPECIFIC_TYPES.has(String(e.type).toLowerCase()) && !SPECIFIC_TYPES.has(row.type.toLowerCase()))
158
+ row.type = String(e.type);
159
+ return;
160
+ }
161
+ catalog.set(key, {
162
+ id: catalog.size + 1, type: String(e.type ?? "error"), message: String(e.message ?? ""), stack: e.stack,
163
+ first_step: step?.number ?? null, first_call: call?.seq ?? null, first_tool: call?.tool, relation, at: e.at, count: 1,
164
+ });
165
+ };
166
+ const stepOfCall = new Map();
167
+ for (const step of steps)
168
+ for (const call of step.calls)
169
+ stepOfCall.set(call.seq, step);
170
+ for (const e of looseErrors)
171
+ record(e, null, null, "before the first call");
172
+ // Walk in time order so "first occurrence" is chronological.
173
+ const timeline = [];
174
+ for (const step of steps)
175
+ for (const call of step.calls) {
176
+ // The same message from the response and the stream inside one call is one occurrence.
177
+ call.errors = call.errors.filter((e, i) => call.errors.findIndex(other => sameMessage(other, e)) === i);
178
+ for (const e of call.errors)
179
+ timeline.push({ e, step, call, relation: "during", at: Date.parse(e.at ?? call.at) || 0 });
180
+ for (const e of call.errorsAfter)
181
+ timeline.push({ e, step, call, relation: "after", at: Date.parse(e.at ?? call.at) || 0 });
182
+ }
183
+ timeline.sort((a, b) => a.at - b.at);
184
+ for (const t of timeline)
185
+ record(t.e, t.step, t.call, t.relation);
186
+ // Occurrences the recorder counted but did not log (a message past its repeat cap, errors past the session cap).
187
+ let suppressed = 0;
188
+ for (const repeat of errorRepeats) {
189
+ const count = typeof repeat.count === "number" ? repeat.count : 0;
190
+ const row = catalog.get(errorKey(repeat));
191
+ if (row)
192
+ row.count += count;
193
+ suppressed += count;
194
+ }
195
+ totalErrors += suppressed + errorsOverLimit;
196
+ if (suppressed)
197
+ notes.push(`${suppressed} repeat(s) of ${errorRepeats.length} message(s) over the per-message log cap were counted, not logged (they are in the ×counts).`);
198
+ if (errorsOverLimit)
199
+ notes.push(`${errorsOverLimit} console error(s) over the per-call / per-session error limit were counted, not logged.`);
200
+ const errorRows = [...catalog.values()].sort((a, b) => a.id - b.id);
201
+ // ---- thumbnails --------------------------------------------------------
202
+ const budgetEnd = input.now() + (input.thumbnailBudgetMs ?? 20_000);
203
+ let thumbs = 0, captureCount = 0, thumbSkipped = 0;
204
+ const thumbFor = (capture) => {
205
+ if (!capture.file)
206
+ return null;
207
+ if (thumbs >= input.maxThumbnails || input.now() > budgetEnd) {
208
+ thumbSkipped++;
209
+ return null;
210
+ }
211
+ const source = join(reportDir, capture.file);
212
+ const name = capture.file.replace(/^frames\//, "").replace(/\.png$/i, "") + ".thumb.png";
213
+ const target = join(reportDir, THUMBS_DIR, name);
214
+ try {
215
+ if (!existsSync(target)) {
216
+ const contact = capture.label === "contact sheet";
217
+ const thumb = thumbnail(readFileSync(source), contact ? 960 : 320, contact ? 480 : 320);
218
+ if (!thumb)
219
+ return null;
220
+ writeFileSync(target, thumb.png);
221
+ }
222
+ thumbs++;
223
+ return `${THUMBS_DIR}/${name}`;
224
+ }
225
+ catch {
226
+ return null;
227
+ }
228
+ };
229
+ // ---- markdown ----------------------------------------------------------
230
+ const verdicts = { ok: 0, bug: 0, suspicious: 0 };
231
+ for (const step of steps)
232
+ if (step.verdict && step.verdict in verdicts)
233
+ verdicts[step.verdict]++;
234
+ const allCalls = [...calls.values()];
235
+ const failedCalls = allCalls.filter(c => c.status === "error").length;
236
+ for (const c of allCalls)
237
+ captureCount += c.captures.filter(x => x.file).length;
238
+ const startedMs = Date.parse(meta.started_at), endedMs = Date.parse(meta.ended_at ?? new Date(input.now()).toISOString());
239
+ const device = meta.device ?? {};
240
+ const view = (device.view ?? {});
241
+ const deviceText = [
242
+ device.summary ? String(device.summary) : null,
243
+ view.mode ? `${view.mode === "simulator" ? `Device Simulator ${view.device ?? ""}`.trim() : `Game view ${view.size ?? ""}`.trim()}` : null,
244
+ Array.isArray(view.screen) ? `${view.screen[0]}×${view.screen[1]}${view.orientation ? ` ${view.orientation}` : ""}` : null,
245
+ ].filter(Boolean).join(" · ") || "not recorded";
246
+ // A hook ran: an invoke that succeeded, or a job (`jobs start` row) whose observed result did not fail.
247
+ const hooks = {};
248
+ const failedJobs = new Set(allCalls.filter(c => c.of !== undefined && c.status === "error").map(c => c.of));
249
+ for (const c of allCalls) {
250
+ const args = c.args;
251
+ const id = typeof args?.command_id === "string" ? args.command_id
252
+ : typeof args?.tool_or_command === "string" ? args.tool_or_command : "";
253
+ const ran = c.status === "ok" || (c.status === "job_started" && !failedJobs.has(c.seq));
254
+ if (/(^|\.)playtest\.begin$/.test(id) && ran)
255
+ hooks.begin = id;
256
+ if (/(^|\.)playtest\.end$/.test(id) && ran)
257
+ hooks.end = id;
258
+ }
259
+ const md = [];
260
+ md.push(`# Playtest report: ${cell(meta.name)}`, "");
261
+ md.push("| | |", "|---|---|");
262
+ md.push(`| Session | ${cellCode(meta.id)} |`);
263
+ md.push(`| Project | ${cell(meta.company)} / ${cell(meta.product)} (${cellCode(meta.project)}) |`);
264
+ md.push(`| Started | ${meta.started_at} |`);
265
+ md.push(`| Ended | ${meta.ended_at ?? "—"} (${Number.isFinite(endedMs - startedMs) ? duration(endedMs - startedMs) : "?"}) |`);
266
+ md.push(`| Device | ${cell(deviceText)} |`);
267
+ md.push(`| Player-state snapshot | ${meta.snapshot ? `${cellCode(meta.snapshot.name)} (${meta.snapshot.taken ? "taken at start" : "existing"})` : "none"} |`);
268
+ if (hooks.begin || hooks.end)
269
+ md.push(`| Project isolation hook | ${[hooks.begin, hooks.end].filter(Boolean).map(h => cellCode(h)).join(" → ")}${hooks.begin && !hooks.end ? " (end hook not recorded)" : ""} |`);
270
+ md.push(`| Recorded | ${allCalls.length} call(s) in ${steps.length} step(s), ${failedCalls} failed, ${captureCount} frame(s), ${errorRows.length} distinct error(s) (${totalErrors} total) |`);
271
+ md.push(`| Verdicts | ok ${verdicts.ok} · bug ${verdicts.bug} · suspicious ${verdicts.suspicious} |`);
272
+ md.push("");
273
+ md.push("## Findings", "");
274
+ const findings = steps.filter(s => s.verdict === "bug" || s.verdict === "suspicious");
275
+ if (!findings.length && !errorRows.length && !lost.length && !runningAtEnd.length && !failedCalls)
276
+ md.push("No bug or suspicious verdicts, no console errors, no failed calls.");
277
+ for (const step of findings)
278
+ md.push(`- **${step.verdict}** — step ${step.number}: ${cell(step.label)}${step.note ? ` — ${cell(step.note)}` : ""}`);
279
+ for (const row of errorRows)
280
+ md.push(`- **${row.type}** ${code(clip(firstLine(row.message), 160))} — first in ${row.first_step !== null ? `step ${row.first_step}` : row.first_call !== null ? "the unmarked calls" : "the session before any call"}${row.first_call !== null ? `, call #${row.first_call} ${code(shortTool(row.first_tool ?? ""))} (${row.relation} it)` : ""}${row.count > 1 ? `, ×${row.count}` : ""} → [E${row.id}](#e${row.id})`);
281
+ if (failedCalls)
282
+ md.push(`- ${failedCalls} recorded call(s) failed (status \`error\` in the steps below).`);
283
+ for (const l of lost)
284
+ md.push(`- **Lost in flight:** call #${l.seq} ${code(shortTool(l.tool))} started at ${l.at} and never finished — the MCP server process stopped during it.`);
285
+ for (const l of runningAtEnd)
286
+ md.push(`- **Still running at end:** call #${l.seq} ${code(shortTool(l.tool))} started at ${l.at} and had not returned when the session ended.`);
287
+ if (endNote)
288
+ md.push("", `> ${cell(endNote)}`);
289
+ md.push("");
290
+ md.push("## Steps", "");
291
+ if (!steps.length)
292
+ md.push("No calls were recorded.", "");
293
+ for (const step of steps) {
294
+ md.push(step.number !== null ? `### Step ${step.number}: ${cell(step.label)} — ${step.verdict}` : `### ${step.label}`, "");
295
+ if (step.note)
296
+ md.push(`> ${cell(step.note)}`, "");
297
+ if (!step.calls.length) {
298
+ md.push("_No recorded calls in this step._", "");
299
+ continue;
300
+ }
301
+ md.push("| # | Time | Tool | Arguments | Result | Duration |", "|---|---|---|---|---|---|");
302
+ for (const call of step.calls) {
303
+ const result = call.lost ? "**lost** (server stopped)"
304
+ : call.running ? "**still running at end**"
305
+ : call.status === "error" ? `**error** ${cellCode(call.error?.code ?? "")}${call.error?.message ? ` ${cell(clip(call.error.message, 120))}` : ""}`
306
+ : call.status === "job_started" ? `job ${cellCode(call.job_id ?? "")}`
307
+ : resultText(call);
308
+ md.push(`| ${call.seq}${call.of ? ` (of #${call.of})` : ""} | ${time(call.at)} | ${cellCode(shortTool(call.tool))} | ${call.args !== undefined ? cellCode(clip(JSON.stringify(call.args), 160)) : ""} | ${result} | ${call.lost || call.running ? "—" : duration(call.duration_ms)} |`);
309
+ }
310
+ md.push("");
311
+ const stepErrors = step.calls.flatMap(c => [
312
+ ...c.errors.map(e => ({ e, c, relation: "during" })), ...c.errorsAfter.map(e => ({ e, c, relation: "after" })),
313
+ ]);
314
+ if (stepErrors.length) {
315
+ md.push("Console errors in this step:", "");
316
+ for (const { e, c, relation } of stepErrors.slice(0, 20)) {
317
+ const row = catalog.get(errorKey(e));
318
+ md.push(`- ${e.type} ${code(clip(firstLine(String(e.message ?? "")), 200))} — ${relation} call #${c.seq}${row ? ` → [E${row.id}](#e${row.id})` : ""}`);
319
+ }
320
+ if (stepErrors.length > 20)
321
+ md.push(`- … ${stepErrors.length - 20} more`);
322
+ md.push("");
323
+ }
324
+ const shots = [];
325
+ for (const call of step.calls) {
326
+ const files = call.captures.filter(c => c.file);
327
+ // A series: its contact sheet, else the first and the last frame.
328
+ const sheet = files.find(c => c.label === "contact sheet");
329
+ const chosen = sheet ? [sheet] : files.length > 3 ? [files[0], files[Math.floor(files.length / 2)], files[files.length - 1]] : files;
330
+ for (const capture of chosen) {
331
+ const thumb = thumbFor(capture);
332
+ const caption = `#${call.seq}${capture.label ? ` ${capture.label}` : ""}${capture.frame !== undefined ? ` F${capture.frame}` : ""}`;
333
+ shots.push(thumb ? `[![${caption}](${thumb})](${capture.file})` : `[${caption}](${capture.file})`);
334
+ }
335
+ const rest = files.filter(f => !chosen.includes(f));
336
+ if (rest.length)
337
+ shots.push(`#${call.seq}: ${rest.length} more frame(s): ${rest.slice(0, 12).map((f, i) => `[${f.frame !== undefined ? `F${f.frame}` : i + 1}](${f.file})`).join(" ")}${rest.length > 12 ? " …" : ""}`);
338
+ const skipped = call.captures.filter(c => !c.file && c.source);
339
+ if (skipped.length)
340
+ shots.push(`#${call.seq}: ${skipped.length} frame(s) not copied (${skipped[0].skipped ?? skipped[0].missing ?? "unavailable"}): ${code(skipped[0].source)}${skipped.length > 1 ? " …" : ""}`);
341
+ }
342
+ if (shots.length)
343
+ md.push("Frames:", "", shots.join(" "), "");
344
+ }
345
+ md.push("## Errors", "");
346
+ if (!errorRows.length)
347
+ md.push("No console errors or exceptions were logged while recording.", "");
348
+ for (const row of errorRows) {
349
+ md.push(`### E${row.id}`, "");
350
+ md.push(`**${row.type}** ${code(clip(firstLine(row.message), 300))}`, "");
351
+ md.push(`First occurrence: ${row.first_step !== null ? `step ${row.first_step}` : "outside a marked step"}${row.first_call !== null ? `, ${row.relation} call #${row.first_call} ${code(shortTool(row.first_tool ?? ""))}` : ` (${row.relation})`}${row.at ? ` at ${row.at}` : ""}; seen ${row.count} time(s).`, "");
352
+ const body = [row.message.includes("\n") ? row.message : null, row.stack ? row.stack.trim() : null].filter(Boolean).join("\n");
353
+ if (body)
354
+ md.push("```text", clip(body, 4_000).replace(/```/g, "'''"), "```", "");
355
+ else
356
+ md.push("_No stack trace (reported by the tool response; the event stream was not connected)._", "");
357
+ }
358
+ md.push("## State diff", "");
359
+ let stateDiff = null;
360
+ if (!meta.snapshot)
361
+ md.push("No player-state snapshot was taken for this session.", "");
362
+ else if (!input.stateDiff)
363
+ md.push(`Not computed (\`diff: false\`). Snapshot: ${code(meta.snapshot.name)}.`, "");
364
+ else if (!input.stateDiff.ok) {
365
+ stateDiff = { error: input.stateDiff.error };
366
+ md.push(`The diff against ${code(meta.snapshot.name)} failed: ${code(JSON.stringify(input.stateDiff.error).slice(0, 300))}.`, "");
367
+ }
368
+ else {
369
+ const diff = input.stateDiff.output;
370
+ writeFileSync(join(reportDir, "state-diff.json"), JSON.stringify(diff, null, 2));
371
+ stateDiff = { identical: diff.identical, prefs: diff.prefs?.counts, files: diff.files?.counts, editor_prefs: diff.editor_prefs?.counts ?? null };
372
+ md.push(`Snapshot ${code(meta.snapshot.name)} → the state at the end of the session${diff.to?.mode ? ` (${diff.to.mode} mode)` : ""}. Full diff: [state-diff.json](state-diff.json).`, "");
373
+ if (diff.identical)
374
+ md.push("No PlayerPrefs, EditorPrefs or persistentDataPath change.", "");
375
+ for (const [title, part] of [["PlayerPrefs", diff.prefs], ["EditorPrefs", diff.editor_prefs]]) {
376
+ if (!part)
377
+ continue;
378
+ const rows = [
379
+ ...(part.added ?? []).map((e) => ["added", e.key, "", show(e.to ?? e)]),
380
+ ...(part.removed ?? []).map((e) => ["removed", e.key, show(e.from ?? e), ""]),
381
+ ...(part.changed ?? []).map((e) => ["changed", e.key, show(e.from), show(e.to)]),
382
+ ];
383
+ if (!rows.length)
384
+ continue;
385
+ md.push(`${title}: ${JSON.stringify(part.counts ?? {})}`, "", "| Change | Key | From | To |", "|---|---|---|---|");
386
+ for (const [change, key, from, to] of rows)
387
+ md.push(`| ${change} | ${cellCode(String(key))} | ${cell(from)} | ${cell(to)} |`);
388
+ if (part.truncated)
389
+ md.push(`| … | ${part.truncated} more | | |`);
390
+ md.push("");
391
+ }
392
+ const files = diff.files;
393
+ if (files && ((files.added?.length ?? 0) + (files.removed?.length ?? 0) + (files.changed?.length ?? 0)) > 0) {
394
+ md.push(`persistentDataPath files: ${JSON.stringify(files.counts ?? {})}`, "", "| Change | Path | Size |", "|---|---|---|");
395
+ for (const e of files.added ?? [])
396
+ md.push(`| added | ${cellCode(String(e.path))} | ${e.size ?? ""} |`);
397
+ for (const e of files.removed ?? [])
398
+ md.push(`| removed | ${cellCode(String(e.path))} | ${e.size ?? ""} |`);
399
+ for (const e of files.changed ?? [])
400
+ md.push(`| changed | ${cellCode(String(e.path))} | ${e.from?.size ?? ""} → ${e.to?.size ?? ""} |`);
401
+ md.push("");
402
+ }
403
+ }
404
+ if (editorEvents.length) {
405
+ md.push("## Editor events", "", "| Time | State |", "|---|---|");
406
+ for (const e of editorEvents)
407
+ md.push(`| ${time(e.at)} | ${cellCode(String(e.state))}${EDITOR_STATE_NOTES[String(e.state)] ?? ""} |`);
408
+ md.push("");
409
+ }
410
+ const streamDown = allCalls.filter(c => c.streamDown).length;
411
+ if (streamDown)
412
+ notes.push(`${streamDown} call(s) ran while the bridge event stream was disconnected (a domain reload or restart in progress): their errors come from the tool responses only, without stacks.`);
413
+ if (thumbSkipped)
414
+ notes.push(`${thumbSkipped} frame(s) are linked without a thumbnail (thumbnail limit ${input.maxThumbnails} or time budget).`);
415
+ md.push("## Notes", "");
416
+ md.push("- Frames are full-size PNGs in [frames/](frames/); thumbnails in [thumbs/](thumbs/). The raw log is `../log.jsonl` (one JSON line per event).");
417
+ md.push("- Errors are matched to calls by time: \"during\" = logged while the call ran, \"after\" = logged between this call and the next recorded one.");
418
+ md.push("- Secrets in arguments, notes, console text and the state diff are replaced with `[redacted]`.");
419
+ for (const note of notes)
420
+ md.push(`- ${cell(note)}`);
421
+ md.push("");
422
+ const reportPath = join(reportDir, REPORT_FILE);
423
+ writeFileSync(reportPath, redactor.text(md.join("\n")));
424
+ return {
425
+ report: reportPath, steps: steps.length, calls: allCalls.length, failed_calls: failedCalls, captures: captureCount, thumbnails: thumbs,
426
+ duration_ms: Number.isFinite(endedMs - startedMs) ? endedMs - startedMs : 0, verdicts,
427
+ errors: { unique: errorRows.length, total: totalErrors },
428
+ findings: findings.slice(0, 10).map(s => ({ step: s.number ?? 0, label: s.label, verdict: s.verdict, ...(s.note ? { note: clip(s.note, 300) } : {}) })),
429
+ top_errors: errorRows.slice(0, 5).map(r => ({ type: r.type, message: clip(firstLine(r.message), 200), first_step: r.first_step, first_call: r.first_call, relation: r.relation, count: r.count })),
430
+ lost_in_flight: lost, running_at_end: runningAtEnd, state_diff: stateDiff, hooks, notes,
431
+ };
432
+ }
433
+ const EDITOR_STATE_NOTES = {
434
+ reloading: " (domain reload)",
435
+ stream_reconnected: " (the bridge was away and came back: a domain reload or an Editor restart)",
436
+ entering_playmode: " (entering play mode)",
437
+ exiting_playmode: " (leaving play mode)",
438
+ };
439
+ function show(value) {
440
+ if (value === undefined || value === null)
441
+ return "";
442
+ if (typeof value === "object") {
443
+ if ("value" in value)
444
+ return `${value.type ? `${value.type} ` : ""}${clip(JSON.stringify(value.value), 80)}`;
445
+ if ("length" in value)
446
+ return `${value.type ?? "string"} (${value.length} chars)`;
447
+ return clip(JSON.stringify(value), 80);
448
+ }
449
+ return clip(String(value), 80);
450
+ }
451
+ function resultText(call) {
452
+ const s = call.summary ?? {};
453
+ const parts = [];
454
+ if (typeof s.outcome === "string")
455
+ parts.push(s.outcome);
456
+ const fired = s.fired;
457
+ if (fired && typeof fired === "object" && fired.type)
458
+ parts.push(`fired ${fired.type}${fired.frame !== undefined ? ` @F${fired.frame}` : ""}`);
459
+ const captured = s.capturedAt;
460
+ if (captured && typeof captured === "object")
461
+ parts.push([captured.mode, captured.device ?? captured.size, Array.isArray(captured.screen) ? captured.screen.join("×") : null].filter(Boolean).join(" "));
462
+ const series = s.series;
463
+ if (series && typeof series === "object" && series.captured !== undefined)
464
+ parts.push(`${series.captured} frame(s)`);
465
+ if (Array.isArray(s.backend))
466
+ parts.push(s.backend.join("+"));
467
+ if (s.result !== undefined)
468
+ parts.push(code(clip(JSON.stringify(s.result), 100)));
469
+ if (typeof s.action === "string" && call.kind === "control")
470
+ parts.push(`${s.action} requested`);
471
+ else if (typeof s.isPlaying === "boolean")
472
+ parts.push(s.isPlaying ? "playing" : "edit mode");
473
+ if (call.captures.length && !series)
474
+ parts.push(`${call.captures.length} frame(s)`);
475
+ return ["ok", ...parts].map(p => cell(p)).join(" · ");
476
+ }
477
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/playtest/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ export declare const SESSION_FORMAT = 1;
2
+ export declare const SESSION_FILE = "session.json";
3
+ export declare const LOG_FILE = "log.jsonl";
4
+ export declare const REPORT_DIR = "report";
5
+ export declare const FRAMES_DIR = "frames";
6
+ export declare const THUMBS_DIR = "thumbs";
7
+ export declare const REPORT_FILE = "report.md";
8
+ export interface SessionOwner {
9
+ project: string;
10
+ agent: string;
11
+ port?: number;
12
+ }
13
+ export interface SessionMeta {
14
+ format: number;
15
+ id: string;
16
+ name: string;
17
+ project: string;
18
+ company: string;
19
+ product: string;
20
+ owner: SessionOwner;
21
+ /** MCP server process that owns the session; a dead pid makes it adoptable. */
22
+ server_pid: number;
23
+ started_at: string;
24
+ state: "open" | "ended";
25
+ ended_at?: string;
26
+ device: Record<string, unknown> | null;
27
+ snapshot: {
28
+ name: string;
29
+ taken: boolean;
30
+ } | null;
31
+ report?: string;
32
+ adoptions?: Array<{
33
+ at: string;
34
+ from: SessionOwner;
35
+ from_pid: number;
36
+ }>;
37
+ limits: Record<string, number>;
38
+ }
39
+ /** The platform app-data folder (same rule as the bridge's player-state store). */
40
+ export declare function appDataRoot(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv, home?: string): string;
41
+ export declare function sessionsRoot(platform?: NodeJS.Platform, env?: NodeJS.ProcessEnv, home?: string): string;
42
+ /** A company / product name as one path segment (the bridge's SafeSegment rule). */
43
+ export declare function safeSegment(value: string | null | undefined): string;
44
+ /** A session id: UTC stamp + a slug of the name + 4 hex, safe as a folder name. */
45
+ export declare function sessionId(name: string, now: Date, random: string): string;
46
+ export declare const SESSION_ID_PATTERN: RegExp;
47
+ /**
48
+ * Company / product from ProjectSettings/ProjectSettings.asset — the fallback
49
+ * when the Editor cannot be asked (a restart with the Editor closed). Plain
50
+ * and quoted YAML scalars only; anything else falls back to Unity's defaults.
51
+ */
52
+ export declare function readProjectIdentity(projectPath: string): {
53
+ company: string;
54
+ product: string;
55
+ } | null;
56
+ export declare class SessionStore {
57
+ readonly root: string;
58
+ constructor(root: string);
59
+ productDir(company: string, product: string): string;
60
+ dir(meta: Pick<SessionMeta, "company" | "product" | "id">): string;
61
+ create(meta: SessionMeta): string;
62
+ writeMeta(meta: SessionMeta): void;
63
+ readMeta(dir: string): SessionMeta | null;
64
+ append(meta: Pick<SessionMeta, "company" | "product" | "id">, entry: Record<string, unknown>): void;
65
+ /**
66
+ * Every parseable line of a session log; a torn line (a crash mid-write) is
67
+ * skipped. Read in chunks, so a log larger than the longest JS string still
68
+ * yields its entries.
69
+ */
70
+ readLog(dir: string): Array<Record<string, any>>;
71
+ /** End a torn last line, so the next appended entry starts a line of its own. */
72
+ terminateLog(dir: string): void;
73
+ /** Sessions of one product, newest first. */
74
+ list(company: string, product: string): Array<{
75
+ dir: string;
76
+ meta: SessionMeta;
77
+ }>;
78
+ }