miriad-viz 0.8.0 → 0.9.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/dist-cli/{chunk-4CGFDD2G.js → chunk-WP7ZSXBZ.js} +2 -10
- package/dist-cli/{curate-SMBYTH7I.js → curate-OPFP3APX.js} +1 -1
- package/dist-cli/index.js +80 -20
- package/dist-cli/{transform-N4UK7EOP.js → transform-SCT5EYPV.js} +1 -1
- package/dist-lib/index.cjs +2 -10
- package/dist-lib/index.cjs.map +1 -1
- package/dist-lib/index.js +2 -10
- package/dist-lib/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -28,7 +28,7 @@ function transformToRawData(sources) {
|
|
|
28
28
|
),
|
|
29
29
|
commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),
|
|
30
30
|
prs: transformPRs(sources.prs, sources.prAgentMap),
|
|
31
|
-
messages: transformMessages(sources.timelineEvents
|
|
31
|
+
messages: transformMessages(sources.timelineEvents),
|
|
32
32
|
artifacts: sources.artifactData ? transformArtifacts(
|
|
33
33
|
sources.artifactData,
|
|
34
34
|
sources.retroPageData,
|
|
@@ -280,15 +280,7 @@ function transformArtifacts(artifactData, retroData, prs, prAgentMap) {
|
|
|
280
280
|
artifacts.sort((a, b) => a.createdAt - b.createdAt);
|
|
281
281
|
return artifacts;
|
|
282
282
|
}
|
|
283
|
-
function transformMessages(timelineEvents
|
|
284
|
-
if (messages && messages.length > 0) {
|
|
285
|
-
return messages.map((msg) => ({
|
|
286
|
-
id: msg.id,
|
|
287
|
-
timestamp: new Date(msg.timestamp).getTime(),
|
|
288
|
-
sender: msg.sender,
|
|
289
|
-
mentions: msg.mentions
|
|
290
|
-
}));
|
|
291
|
-
}
|
|
283
|
+
function transformMessages(timelineEvents) {
|
|
292
284
|
const messageEvents = timelineEvents.events.filter(
|
|
293
285
|
(e) => e.type === "message" || e.type === "beam"
|
|
294
286
|
);
|
package/dist-cli/index.js
CHANGED
|
@@ -326,13 +326,20 @@ function formatDensityReport(reports, projectStart, projectEnd, timingLines) {
|
|
|
326
326
|
lines.push(" \u{1F4CA} Pacing guidance:");
|
|
327
327
|
lines.push(" - High pill count \u2192 lower vizSpeed so pills appear one-by-one like dialog");
|
|
328
328
|
lines.push(" - Zero activity \u2192 raise vizSpeed to skip dead time");
|
|
329
|
-
lines.push(
|
|
330
|
-
" - Messages \u2260 pills: messages = raw activity density, pills = curated selections that actually render"
|
|
331
|
-
);
|
|
332
329
|
lines.push(
|
|
333
330
|
" - Commits/PRs/Files are visual events too \u2014 a section can be busy even if chat is quiet"
|
|
334
331
|
);
|
|
335
332
|
lines.push(" - Goal: narration should match what the viewer shows on screen");
|
|
333
|
+
lines.push("");
|
|
334
|
+
lines.push(" \u{1F4D6} Glossary (these are DIFFERENT visual elements):");
|
|
335
|
+
lines.push(
|
|
336
|
+
" - Pills = curated chat pills from timeline-events.json \u2014 labeled bubbles on screen"
|
|
337
|
+
);
|
|
338
|
+
lines.push(
|
|
339
|
+
" - Msgs = raw message count from messages-full.json \u2014 activity density signal only"
|
|
340
|
+
);
|
|
341
|
+
lines.push(" - Pills are what the viewer SHOWS. Msgs tell you how BUSY the period was.");
|
|
342
|
+
lines.push(" - To add more pills: edit timeline-events.json in the curate step.");
|
|
336
343
|
return lines;
|
|
337
344
|
}
|
|
338
345
|
|
|
@@ -678,8 +685,15 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
678
685
|
output.push("", " Missing:");
|
|
679
686
|
for (const f of missing) output.push(` \u25CB ${f}`);
|
|
680
687
|
}
|
|
681
|
-
output.push("", " Run `npx miriad-viz curate` to generate scaffolds
|
|
682
|
-
output.push("
|
|
688
|
+
output.push("", " Run `npx miriad-viz curate` to generate scaffolds.");
|
|
689
|
+
output.push("");
|
|
690
|
+
output.push(" Remember: the scaffold gives you RAW events (activity density).");
|
|
691
|
+
output.push(" You must ADD milestone events with labels at narration-aligned timestamps.");
|
|
692
|
+
output.push(" Each narration line needs at least one labeled event in its time range.");
|
|
693
|
+
output.push(
|
|
694
|
+
" Raw messages (messages-full.json) are your SOURCE \u2014 read them to find content."
|
|
695
|
+
);
|
|
696
|
+
output.push(" timeline-events.json is your OUTPUT \u2014 the chat pills that appear on screen.");
|
|
683
697
|
output.push("", " When done: npx miriad-viz next");
|
|
684
698
|
return { action: "waiting_for_edit", step, progress, output };
|
|
685
699
|
}
|
|
@@ -688,21 +702,48 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
688
702
|
output.push(" This step generates scaffold files for editorial content:");
|
|
689
703
|
output.push(" \u2022 retro-page-data.json \u2014 phases, milestones, featured quotes, narration");
|
|
690
704
|
output.push(" \u2022 retro-page-quotes.json \u2014 additional standout quotes");
|
|
691
|
-
output.push(" \u2022 timeline-events.json \u2014
|
|
705
|
+
output.push(" \u2022 timeline-events.json \u2014 scaffolded from extracted data (YOU MUST EDIT THIS)");
|
|
706
|
+
output.push("");
|
|
707
|
+
output.push(" \u26A0\uFE0F Three concepts \u2014 understand these before editing:");
|
|
708
|
+
output.push(" \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500");
|
|
709
|
+
output.push(" 1. RAW MESSAGES (messages-full.json)");
|
|
710
|
+
output.push(" Your SOURCE material. Read these to find interesting content.");
|
|
711
|
+
output.push(" Never rendered as chat pills. Used only for density counting.");
|
|
712
|
+
output.push("");
|
|
713
|
+
output.push(" 2. CURATED CHAT PILLS (timeline-events.json)");
|
|
714
|
+
output.push(" Your OUTPUT. These render as labeled bubbles on screen.");
|
|
715
|
+
output.push(" The scaffold gives you raw activity events (unlabeled density).");
|
|
716
|
+
output.push(" You MUST add milestone events with labels at narration timestamps.");
|
|
717
|
+
output.push("");
|
|
718
|
+
output.push(" 3. MESSAGE ACTIVITY (background visualization)");
|
|
719
|
+
output.push(" Raw messages rendered as density patterns. Different from chat pills.");
|
|
720
|
+
output.push(" You do NOT control this \u2014 it comes from the extract data automatically.");
|
|
692
721
|
output.push("");
|
|
693
722
|
output.push(" YOUR TASK:");
|
|
694
723
|
output.push(" 1. Run: npx miriad-viz curate");
|
|
695
724
|
output.push(" This generates scaffolds pre-filled from your extracted data.");
|
|
696
|
-
output.push(" 2.
|
|
725
|
+
output.push(" 2. Edit timeline-events.json (this is your MAIN job):");
|
|
726
|
+
output.push(" - The scaffold has raw message events (activity density) \u2014 keep them");
|
|
727
|
+
output.push(" - ADD 15-20 milestone events with labels at narration-aligned timestamps");
|
|
728
|
+
output.push(' - Each milestone: { type: "message", timestamp: "...", agent: "...",');
|
|
729
|
+
output.push(' content: "Short label that makes sense as a chat pill" }');
|
|
730
|
+
output.push(" - Goal: every narration line should have at least one labeled event");
|
|
731
|
+
output.push(" during its time range");
|
|
732
|
+
output.push(" 3. Fill in retro-page-data.json:");
|
|
697
733
|
output.push(" - Define phases (story arcs with start/end dates)");
|
|
698
734
|
output.push(" - Add milestones (key moments)");
|
|
699
735
|
output.push(" - Select featured quotes from the data");
|
|
700
736
|
output.push(" - Write narration-editorial entries (fractional 0-1 positions)");
|
|
701
|
-
output.push("
|
|
737
|
+
output.push(" 4. Fill in retro-page-quotes.json:");
|
|
702
738
|
output.push(" - Add standout quotes with speaker, text, and timestamp");
|
|
703
|
-
output.push(" 4. timeline-events.json is auto-generated \u2014 review but don't edit");
|
|
704
739
|
output.push(" 5. Present to human and iterate");
|
|
705
740
|
output.push("");
|
|
741
|
+
output.push(" \u2705 Curation checklist:");
|
|
742
|
+
output.push(" \u25A1 Every narration line has at least one labeled event in its time range");
|
|
743
|
+
output.push(" \u25A1 Milestone labels are short (< 60 chars) and make sense as chat pills");
|
|
744
|
+
output.push(" \u25A1 Milestone timestamps fall within the project time window");
|
|
745
|
+
output.push(" \u25A1 Raw events kept for density \u2014 milestones added for content");
|
|
746
|
+
output.push("");
|
|
706
747
|
output.push(" \u26A0\uFE0F narration-editorial uses FRACTIONAL 0-1 for start/end (e.g. 0.23, 0.68).");
|
|
707
748
|
output.push(" Everything else in curation uses ISO timestamps. Do NOT mix them up.");
|
|
708
749
|
output.push("");
|
|
@@ -1411,15 +1452,27 @@ function gatherDataSummary(projectDir, dataDir) {
|
|
|
1411
1452
|
data.chatActivity = tryRead("chat-activity.json");
|
|
1412
1453
|
return buildDataSummary(data);
|
|
1413
1454
|
}
|
|
1414
|
-
function gatherDensityData(projectDir, dataDir) {
|
|
1455
|
+
function gatherDensityData(projectDir, dataDir, outputDir) {
|
|
1415
1456
|
const tryRead = (filename) => {
|
|
1416
|
-
const
|
|
1417
|
-
if (
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1457
|
+
const dataPath = resolve3(projectDir, dataDir, filename);
|
|
1458
|
+
if (existsSync3(dataPath)) {
|
|
1459
|
+
try {
|
|
1460
|
+
return JSON.parse(readFileSync2(dataPath, "utf-8"));
|
|
1461
|
+
} catch {
|
|
1462
|
+
return null;
|
|
1463
|
+
}
|
|
1422
1464
|
}
|
|
1465
|
+
if (outputDir) {
|
|
1466
|
+
const outputPath = resolve3(projectDir, outputDir, filename);
|
|
1467
|
+
if (existsSync3(outputPath)) {
|
|
1468
|
+
try {
|
|
1469
|
+
return JSON.parse(readFileSync2(outputPath, "utf-8"));
|
|
1470
|
+
} catch {
|
|
1471
|
+
return null;
|
|
1472
|
+
}
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
return null;
|
|
1423
1476
|
};
|
|
1424
1477
|
const script = tryRead("script.json");
|
|
1425
1478
|
if (!script?.lines || script.lines.length === 0) return null;
|
|
@@ -1539,7 +1592,11 @@ async function runNext(flags) {
|
|
|
1539
1592
|
const existingFiles = [...gatherExistingFiles(projectDir), ...gatherAudioFiles(projectDir)];
|
|
1540
1593
|
const logTails = gatherLogTails(projectDir);
|
|
1541
1594
|
const dataSummary = gatherDataSummary(projectDir, progress.project.dataDir);
|
|
1542
|
-
const densityData = gatherDensityData(
|
|
1595
|
+
const densityData = gatherDensityData(
|
|
1596
|
+
projectDir,
|
|
1597
|
+
progress.project.dataDir,
|
|
1598
|
+
progress.project.outputDir
|
|
1599
|
+
);
|
|
1543
1600
|
const result = computeNext(
|
|
1544
1601
|
progress,
|
|
1545
1602
|
existingFiles,
|
|
@@ -1618,14 +1675,14 @@ async function main() {
|
|
|
1618
1675
|
}
|
|
1619
1676
|
case "curate": {
|
|
1620
1677
|
const { projectDir, progress } = requireProject();
|
|
1621
|
-
const { runCurate } = await import("./curate-
|
|
1678
|
+
const { runCurate } = await import("./curate-OPFP3APX.js");
|
|
1622
1679
|
await runCurate({ projectDir, progress });
|
|
1623
1680
|
break;
|
|
1624
1681
|
}
|
|
1625
1682
|
case "transform": {
|
|
1626
1683
|
const { projectDir, progress } = requireProject();
|
|
1627
1684
|
const { parseDuration } = await import("./parse-duration-NVLCEFAF.js");
|
|
1628
|
-
const { runTransform } = await import("./transform-
|
|
1685
|
+
const { runTransform } = await import("./transform-SCT5EYPV.js");
|
|
1629
1686
|
const padding = {};
|
|
1630
1687
|
if (typeof flags["pad-start"] === "string") {
|
|
1631
1688
|
padding.padStartMs = parseDuration(flags["pad-start"]);
|
|
@@ -1653,7 +1710,7 @@ async function main() {
|
|
|
1653
1710
|
console.log("");
|
|
1654
1711
|
console.log(chainResult.previewTable);
|
|
1655
1712
|
}
|
|
1656
|
-
const { runTransform } = await import("./transform-
|
|
1713
|
+
const { runTransform } = await import("./transform-SCT5EYPV.js");
|
|
1657
1714
|
await runTransform({ projectDir, progress });
|
|
1658
1715
|
const { runPreview: runPreview2 } = await import("./preview-UUWVOX5Y.js");
|
|
1659
1716
|
await runPreview2({ projectDir, progress, port, noOpen: flags["no-open"] === true });
|
|
@@ -1816,3 +1873,6 @@ main().catch((err) => {
|
|
|
1816
1873
|
console.error(err);
|
|
1817
1874
|
process.exit(1);
|
|
1818
1875
|
});
|
|
1876
|
+
export {
|
|
1877
|
+
gatherDensityData
|
|
1878
|
+
};
|
package/dist-lib/index.cjs
CHANGED
|
@@ -35,7 +35,7 @@ function transformToRawData(sources) {
|
|
|
35
35
|
),
|
|
36
36
|
commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),
|
|
37
37
|
prs: transformPRs(sources.prs, sources.prAgentMap),
|
|
38
|
-
messages: transformMessages(sources.timelineEvents
|
|
38
|
+
messages: transformMessages(sources.timelineEvents),
|
|
39
39
|
artifacts: sources.artifactData ? transformArtifacts(
|
|
40
40
|
sources.artifactData,
|
|
41
41
|
sources.retroPageData,
|
|
@@ -284,15 +284,7 @@ function transformArtifacts(artifactData, retroData, prs, prAgentMap) {
|
|
|
284
284
|
artifacts.sort((a, b) => a.createdAt - b.createdAt);
|
|
285
285
|
return artifacts;
|
|
286
286
|
}
|
|
287
|
-
function transformMessages(timelineEvents
|
|
288
|
-
if (messages && messages.length > 0) {
|
|
289
|
-
return messages.map((msg) => ({
|
|
290
|
-
id: msg.id,
|
|
291
|
-
timestamp: new Date(msg.timestamp).getTime(),
|
|
292
|
-
sender: msg.sender,
|
|
293
|
-
mentions: msg.mentions
|
|
294
|
-
}));
|
|
295
|
-
}
|
|
287
|
+
function transformMessages(timelineEvents) {
|
|
296
288
|
const messageEvents = timelineEvents.events.filter(
|
|
297
289
|
(e) => e.type === "message" || e.type === "beam"
|
|
298
290
|
);
|
package/dist-lib/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transform/transform-raw.ts","../src/transform/transform-curation.ts","../src/types/script.ts","../src/types/pacing.ts","../src/types/timing.ts","../src/audio/manifest.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Transform source data → RawData (Contract A).\n *\n * Pure function. Deterministic. No side effects.\n * Maps existing JSON files to the generic RawData contract.\n */\n\nimport type {\n RawAgent,\n RawArtifact,\n RawCommit,\n RawData,\n RawMessage,\n RawPR,\n} from '../types/raw-data.js';\nimport type {\n SourceArtifactData,\n SourceBeamEvent,\n SourceCommit,\n SourceMessage,\n SourceMessageEvent,\n SourcePR,\n SourcePRAgentMap,\n SourceRetroPageData,\n SourceTimelineEvents,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Infer a RawAgent role from a freeform role string (e.g. from teamAssembly).\n *\n * Checks for known keywords in the string (case-insensitive).\n * Order matters — more specific matches first (e.g. \"eng-lead\" matches \"lead\").\n * Falls back to 'builder' as the safest default (most common role).\n */\nexport function inferRole(roleString: string): RawAgent['role'] {\n const s = roleString.toLowerCase();\n if (s.includes('human') || s === 'user') return 'human';\n if (s.includes('lead')) return 'lead';\n if (s.includes('pm')) return 'pm';\n if (s.includes('tester') || s.includes('qa')) return 'tester';\n if (s.includes('reviewer') || s.includes('review')) return 'reviewer';\n if (s.includes('auditor') || s.includes('audit')) return 'auditor';\n if (s.includes('challenger') || s.includes('challenge')) return 'challenger';\n if (s.includes('scout')) return 'scout';\n if (s.includes('ideation')) return 'ideation';\n if (s.includes('research')) return 'researcher';\n if (s.includes('builder') || s.includes('build')) return 'builder';\n return 'builder'; // safe default — most common role\n}\n\n/**\n * Transform all source data into RawData.\n * This is the main entry point for the extraction layer.\n */\nexport function transformToRawData(sources: TransformSources): RawData {\n // First agent from teamAssembly is the default for unattributed items\n const defaultAgent = sources.retroPageData.teamAssembly[0]?.agent.replace('@', '') ?? 'unknown';\n\n return {\n project: {\n name: sources.retroPageData.meta.title,\n description: sources.retroPageData.meta.subtitle,\n },\n agents: transformAgents(\n sources.retroPageData,\n sources.chatActivity.agentTotals,\n sources.timelineEvents,\n ),\n commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),\n prs: transformPRs(sources.prs, sources.prAgentMap),\n messages: transformMessages(sources.timelineEvents, sources.messages),\n artifacts: sources.artifactData\n ? transformArtifacts(\n sources.artifactData,\n sources.retroPageData,\n sources.prs,\n sources.prAgentMap,\n )\n : [],\n };\n}\n\n/**\n * Build a map of agent → earliest message timestamp from timeline events.\n * Only counts messages where the agent is the sender (not just mentioned).\n */\nfunction buildFirstMessageTimeMap(timelineEvents?: SourceTimelineEvents): Map<string, number> {\n const map = new Map<string, number>();\n if (!timelineEvents) return map;\n\n for (const evt of timelineEvents.events) {\n if (evt.type !== 'message' && evt.type !== 'beam') continue;\n const sender = (evt as SourceMessageEvent | SourceBeamEvent).from;\n const ts = new Date(evt.t).getTime();\n const existing = map.get(sender);\n if (existing === undefined || ts < existing) {\n map.set(sender, ts);\n }\n }\n\n return map;\n}\n\n/**\n * Build RawAgent[] from team assembly data + chat activity.\n *\n * joinedAt resolution priority:\n * 1. First message timestamp from timeline events (most accurate)\n * 2. teamAssembly join time (curated/scaffold fallback)\n * 3. Project start date (last resort)\n *\n * Role resolution priority:\n * 1. Explicit `agentRoles` override (if provided)\n * 2. Inferred from teamAssembly `role` field (e.g. \"eng-lead\" → \"lead\")\n * 3. Default: 'builder' (most common role, safe fallback)\n *\n * Never throws on unknown agents — always infers or defaults.\n */\nexport function transformAgents(\n retroData: SourceRetroPageData,\n agentTotals: Record<string, number>,\n timelineEvents?: SourceTimelineEvents,\n agentRoles?: Record<string, string>,\n): RawAgent[] {\n const agents: RawAgent[] = [];\n const seen = new Set<string>();\n\n // Build first-message-time lookup from timeline events\n const firstMessageTime = buildFirstMessageTimeMap(timelineEvents);\n\n // Build a lookup from teamAssembly role fields for agents not in override\n const assemblyRoles = new Map<string, string>();\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n assemblyRoles.set(id, entry.role);\n }\n\n /** Resolve role for an agent: override → teamAssembly inference → default */\n function resolveRole(id: string): RawAgent['role'] {\n // 1. Explicit override\n if (agentRoles?.[id]) {\n return inferRole(agentRoles[id]);\n }\n // 2. Infer from teamAssembly role field\n const assemblyRole = assemblyRoles.get(id);\n if (assemblyRole) {\n return inferRole(assemblyRole);\n }\n // 3. Default\n return 'builder';\n }\n\n /** Resolve joinedAt: earliest of (first message, teamAssembly time), or startDate */\n function resolveJoinedAt(id: string, assemblyTime?: number): number {\n const msgTime = firstMessageTime.get(id);\n // Use earliest available timestamp — agent was present from whichever came first\n if (msgTime !== undefined && assemblyTime !== undefined) {\n return Math.min(msgTime, assemblyTime);\n }\n if (msgTime !== undefined) return msgTime;\n if (assemblyTime !== undefined) return assemblyTime;\n // Last resort: project start date\n return new Date(retroData.meta.startDate).getTime();\n }\n\n // Primary source: team assembly (has join times)\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n if (seen.has(id)) continue;\n seen.add(id);\n\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id, new Date(entry.time).getTime()),\n });\n }\n\n // Catch any agents in chat activity not in team assembly\n for (const id of Object.keys(agentTotals)) {\n if (seen.has(id)) continue;\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id),\n });\n seen.add(id);\n }\n\n return agents;\n}\n\n/**\n * Transform git commits → RawCommit[].\n * Cross-references pr-agent-map for attribution.\n *\n * @param defaultAgent - Fallback agent for commits with no PR reference\n * (typically the first agent from teamAssembly/roster)\n */\nexport function transformCommits(\n commits: SourceCommit[],\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): RawCommit[] {\n return commits.map((c) => {\n const agent = resolveCommitAgent(c, prAgentMap, defaultAgent);\n\n return {\n sha: c.hash,\n timestamp: new Date(c.date).getTime(),\n agent,\n message: c.subject,\n filesChanged: c.files.length,\n insertions: c.totalInsertions,\n deletions: c.totalDeletions,\n prNumber: c.prNumber ?? undefined,\n };\n });\n}\n\n/**\n * Resolve which agent authored a commit.\n * Strategy chain:\n * 1. prNumber field → pr-agent-map lookup\n * 2. \"Merge pull request #N\" in subject → pr-agent-map lookup\n * 3. \"(#N)\" suffix in subject → pr-agent-map lookup\n * 4. Fallback to defaultAgent (first agent from roster/teamAssembly)\n */\nexport function resolveCommitAgent(\n commit: SourceCommit,\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): string {\n // Strategy 1: direct prNumber field\n if (commit.prNumber != null) {\n const agent = prAgentMap[String(commit.prNumber)];\n if (agent) return agent;\n }\n\n // Strategy 2: \"Merge pull request #N\" pattern\n const mergeMatch = commit.subject.match(/^Merge pull request #(\\d+)/);\n if (mergeMatch) {\n const agent = prAgentMap[mergeMatch[1]];\n if (agent) return agent;\n }\n\n // Strategy 3: \"(#N)\" suffix pattern\n const suffixMatch = commit.subject.match(/\\(#(\\d+)\\)\\s*$/);\n if (suffixMatch) {\n const agent = prAgentMap[suffixMatch[1]];\n if (agent) return agent;\n }\n\n // Fallback: first agent from roster (caller provides)\n return defaultAgent;\n}\n\n/**\n * Transform PR details → RawPR[].\n * Cross-references pr-agent-map for attribution.\n */\nexport function transformPRs(prs: SourcePR[], prAgentMap: SourcePRAgentMap): RawPR[] {\n return prs.map((pr) => {\n const agent = prAgentMap[String(pr.number)] ?? 'unknown';\n\n return {\n number: pr.number,\n title: pr.title,\n agent,\n createdAt: new Date(pr.createdAt).getTime(),\n mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : null,\n additions: pr.additions,\n deletions: pr.deletions,\n branch: pr.headRefName,\n };\n });\n}\n\n/**\n * Infer artifact type from slug or file path.\n *\n * Handles both platforms:\n * - Redux: file paths with extensions (\"/specs/auth.md\", \"plan/task-X1Y2\")\n * - Cast: artifact slugs (\"spec-auth\", \"screenshot-login\", \"qa-review\")\n *\n * Redux patterns are checked first (more specific), cast patterns as fallback.\n */\nexport function inferArtifactType(slug: string): RawArtifact['type'] {\n // --- Redux: plan item prefixes ---\n if (slug.startsWith('plan/task-')) return 'task';\n if (slug.startsWith('plan/spec-')) return 'doc';\n\n // --- Extension-based (works for both platforms, but primarily redux file paths) ---\n const ext = slug.split('.').pop()?.toLowerCase();\n if (ext && ['ts', 'tsx', 'js', 'jsx', 'py', 'rs', 'go', 'sh'].includes(ext)) return 'code';\n if (ext && ['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'ico'].includes(ext)) return 'asset';\n if (ext && ['md', 'txt', 'json', 'yaml', 'yml', 'toml'].includes(ext)) return 'doc';\n\n // --- Redux: path-based patterns ---\n if (slug.includes('/specs/') || slug.includes('/spec/')) return 'doc';\n if (slug.includes('/assets/') || slug.includes('/images/')) return 'asset';\n\n // --- Cast: existing slug patterns (backward compat) ---\n if (slug.includes('.app.')) return 'code';\n if (slug.includes('screenshot') || slug.includes('qa-')) return 'asset';\n if (slug.includes('decision')) return 'decision';\n if (slug.includes('task') || slug.includes('phase-')) return 'task';\n if (slug.startsWith('spec-') || slug.startsWith('spec')) return 'doc';\n if (slug.includes('concept')) return 'doc';\n\n return 'doc';\n}\n\n/**\n * Resolve artifact agent from source data.\n *\n * Priority:\n * 1. Explicit `createdBy` from the artifact record (Miriad API provides this)\n * 2. PR number in slug → pr-agent-map lookup\n * 3. Configurable default (first agent from roster, typically the lead)\n */\nexport function resolveArtifactAgent(\n slug: string,\n prAgentMap: SourcePRAgentMap,\n createdBy: string | undefined,\n defaultAgent: string,\n): string {\n // 1. Explicit creator from source data\n if (createdBy) return createdBy;\n\n // 2. PR reference in slug → agent map\n const prMatch = slug.match(/#?(\\d+)/);\n if (prMatch) {\n const agent = prAgentMap[prMatch[1]];\n if (agent) return agent;\n }\n\n // 3. Default (first agent from roster)\n return defaultAgent;\n}\n\n/** Category name → artifact type */\nconst CATEGORY_TYPE_MAP: Record<string, RawArtifact['type']> = {\n qaScreenshots: 'asset',\n transitionSpecs: 'doc',\n transitionConcepts: 'doc',\n scenes: 'doc',\n vizConcepts: 'code',\n teamPrinciples: 'doc',\n retroData: 'doc',\n decisions: 'decision',\n};\n\n/**\n * Distribute N artifacts within time boundaries, clustered around\n * PR timestamps when available for realistic density.\n */\nexport function distributeTimestamps(\n count: number,\n bounds: { start: number; end: number },\n prTimestamps: number[],\n): number[] {\n const phasePRTimes = prTimestamps.filter((t) => t >= bounds.start && t <= bounds.end);\n const timestamps: number[] = [];\n\n for (let i = 0; i < count; i++) {\n let timestamp: number;\n if (phasePRTimes.length > 0) {\n const prIdx = i % phasePRTimes.length;\n timestamp = phasePRTimes[prIdx] + i * 60000;\n } else {\n const fraction = count > 1 ? i / (count - 1) : 0.5;\n timestamp = bounds.start + fraction * (bounds.end - bounds.start);\n }\n timestamps.push(Math.round(Math.max(bounds.start, Math.min(bounds.end, timestamp))));\n }\n\n return timestamps;\n}\n\n/**\n * Build a type distribution from category data.\n *\n * Each category maps to a type. We build a weighted list so bulk\n * artifacts can be assigned types proportional to category counts.\n * Returns entries sorted by count descending for deterministic assignment.\n *\n * Agent assignment is NOT done here — it's handled by the caller using\n * round-robin over the known agent list (from teamAssembly).\n */\nexport function buildCategoryDistribution(\n categories: SourceArtifactData['categories'],\n): Array<{ type: RawArtifact['type']; weight: number }> {\n const entries: Array<{ type: RawArtifact['type']; count: number }> = [];\n let total = 0;\n\n for (const [categoryName, categoryData] of Object.entries(categories)) {\n if (categoryData.count === 0) continue;\n entries.push({\n type: CATEGORY_TYPE_MAP[categoryName] ?? 'doc',\n count: categoryData.count,\n });\n total += categoryData.count;\n }\n\n if (total === 0) return [{ type: 'doc', weight: 1 }];\n\n return entries\n .sort((a, b) => b.count - a.count)\n .map((e) => ({ type: e.type, weight: e.count / total }));\n}\n\n/**\n * Build a slug → createdBy lookup from SourceArtifactData category items.\n * Items can be plain strings (no creator info) or objects with optional createdBy.\n */\nfunction buildCreatedByLookup(categories: SourceArtifactData['categories']): Map<string, string> {\n const lookup = new Map<string, string>();\n for (const categoryData of Object.values(categories)) {\n for (const item of categoryData.items ?? []) {\n if (typeof item === 'object' && item.createdBy) {\n lookup.set(item.slug, item.createdBy);\n }\n }\n }\n return lookup;\n}\n\n/**\n * Transform artifact-data.json → RawArtifact[].\n *\n * Uses phase `count` fields for correct per-phase density. Each phase\n * specifies how many artifacts were created during that time window:\n * Phase 1: 5, Phase 2: 45, Phase 3: 80, Phase 4: 120, Phase 5: 60 = 310\n *\n * Within each phase:\n * 1. Curated slugs get their own entries with createdBy from source data\n * 2. Remaining count filled with generated artifacts using category\n * type proportions and round-robin agent assignment\n * 3. All timestamps distributed within phase boundaries, clustered\n * around PR activity\n */\nexport function transformArtifacts(\n artifactData: SourceArtifactData,\n retroData: SourceRetroPageData,\n prs: SourcePR[],\n prAgentMap: SourcePRAgentMap,\n): RawArtifact[] {\n const artifacts: RawArtifact[] = [];\n\n // Build agent list from teamAssembly for round-robin and default\n const agentIds = retroData.teamAssembly.map((e) => e.agent.replace('@', ''));\n const defaultAgent = agentIds[0] ?? 'unknown';\n\n const phaseBoundaries = retroData.phases.map((p) => ({\n start: new Date(p.start).getTime(),\n end: new Date(p.end).getTime(),\n }));\n\n const prTimestamps = prs.map((pr) => new Date(pr.createdAt).getTime()).sort((a, b) => a - b);\n const distribution = buildCategoryDistribution(artifactData.categories);\n const createdByLookup = buildCreatedByLookup(artifactData.categories);\n\n let phaseIndex = 0;\n let globalBulkIndex = 0;\n\n for (const [_phaseName, phaseData] of Object.entries(artifactData.phases)) {\n if (phaseIndex >= phaseBoundaries.length) break;\n const bounds = phaseBoundaries[phaseIndex];\n phaseIndex++;\n\n const totalCount = phaseData.count;\n const slugs = phaseData.artifacts;\n const bulkCount = Math.max(0, totalCount - slugs.length);\n\n // All artifacts in this phase share one timestamp distribution\n const timestamps = distributeTimestamps(totalCount, bounds, prTimestamps);\n\n // ── Curated slugs first ──────────────────────────────────────────────\n let tsIdx = 0;\n for (const slug of slugs) {\n artifacts.push({\n slug,\n type: inferArtifactType(slug),\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent: resolveArtifactAgent(slug, prAgentMap, createdByLookup.get(slug), defaultAgent),\n });\n tsIdx++;\n }\n\n // ── Bulk artifacts fill remaining count ───────────────────────────────\n // Assign type by walking through the weighted distribution.\n // Assign agent by round-robin over the known agent list.\n let distIdx = 0;\n let distBudget = Math.round(distribution[0].weight * bulkCount);\n\n for (let i = 0; i < bulkCount; i++) {\n // Advance to next distribution bucket when current is exhausted\n while (distBudget <= 0 && distIdx < distribution.length - 1) {\n distIdx++;\n distBudget = Math.round(distribution[distIdx].weight * bulkCount);\n }\n distBudget--;\n\n const entry = distribution[distIdx];\n // Round-robin agent assignment across the roster\n const agent =\n agentIds.length > 0 ? agentIds[globalBulkIndex % agentIds.length] : defaultAgent;\n artifacts.push({\n slug: `phase${phaseIndex}-${entry.type}-${String(globalBulkIndex + 1).padStart(3, '0')}`,\n type: entry.type,\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent,\n });\n tsIdx++;\n globalBulkIndex++;\n }\n }\n\n artifacts.sort((a, b) => a.createdAt - b.createdAt);\n\n return artifacts;\n}\n\n/**\n * Build RawMessage[] from extracted messages (data/messages.json).\n * Falls back to timeline events for backwards compatibility.\n *\n * Messages are DATA — they flow through extract → transform directly,\n * bypassing the curate step. The curate step handles editorial content\n * (quotes, narration, phases) only.\n */\nexport function transformMessages(\n timelineEvents: SourceTimelineEvents,\n messages?: SourceMessage[],\n): RawMessage[] {\n // Prefer extracted messages (direct data pipeline)\n if (messages && messages.length > 0) {\n return messages.map((msg) => ({\n id: msg.id,\n timestamp: new Date(msg.timestamp).getTime(),\n sender: msg.sender,\n mentions: msg.mentions,\n }));\n }\n\n // Fallback: legacy path via timeline events (beam/message events from curate)\n const messageEvents = timelineEvents.events.filter(\n (e): e is SourceMessageEvent | SourceBeamEvent => e.type === 'message' || e.type === 'beam',\n );\n\n return messageEvents.map((evt, i) => ({\n id: `msg-${String(i).padStart(4, '0')}`,\n timestamp: new Date(evt.t).getTime(),\n sender: evt.from,\n mentions: [evt.to],\n }));\n}\n","/**\n * Transform source data → CurationData (editorial content).\n *\n * Pure function. Deterministic. No side effects.\n * Maps curated board artifacts to the CurationData contract.\n */\n\nimport type {\n CurationData,\n CurationMilestone,\n CurationNarrationEntry,\n CurationPhase,\n CurationQuote,\n CurationTrustKeyframe,\n} from '../types/raw-data.js';\nimport type {\n SourceRetroPageData,\n SourceRetroPageQuotes,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Transform curated source data into CurationData.\n * This is the main entry point for the curation layer.\n */\nexport function transformToCurationData(sources: TransformSources): CurationData {\n const narration = transformNarration(sources.retroPageData);\n const meta = sources.retroPageData.meta;\n\n // Thread curated timeline bounds from meta.startDate/endDate\n const curatedStartMs = meta?.startDate ? new Date(meta.startDate).getTime() : undefined;\n const curatedEndMs = meta?.endDate ? new Date(meta.endDate).getTime() : undefined;\n\n return {\n phases: transformPhases(sources.retroPageData),\n quotes: transformQuotes(sources.retroPageData, sources.retroPageQuotes),\n milestones: transformMilestones(sources.retroPageData),\n trustKeyframes: transformTrustKeyframes(sources.retroPageData),\n ...(narration.length > 0 ? { editorialNarration: narration } : {}),\n ...(curatedStartMs && !Number.isNaN(curatedStartMs) ? { curatedStartMs } : {}),\n ...(curatedEndMs && !Number.isNaN(curatedEndMs) ? { curatedEndMs } : {}),\n };\n}\n\n/**\n * Transform phase definitions from retro-page-data.\n * Phases have hand-curated boundaries, names, and descriptions.\n */\nexport function transformPhases(retroData: SourceRetroPageData): CurationPhase[] {\n return retroData.phases.map((p) => ({\n id: p.id,\n name: p.name,\n startTime: new Date(p.start).getTime(),\n endTime: new Date(p.end).getTime(),\n }));\n}\n\n/**\n * Transform milestones from retro-page-data.\n * Each milestone is cross-referenced to its containing phase.\n */\nexport function transformMilestones(retroData: SourceRetroPageData): CurationMilestone[] {\n const phases = retroData.phases;\n\n return retroData.milestones.map((m) => {\n const milestoneTime = new Date(m.time).getTime();\n const phase = findPhaseForTimestamp(milestoneTime, phases);\n\n return {\n label: m.label,\n timestamp: milestoneTime,\n phase: phase?.id ?? 'unknown',\n };\n });\n}\n\n/**\n * Map mood category to mood string for quotes from retroPageData.\n */\nconst CATEGORY_MOOD: Record<string, string> = {\n theGood: 'good',\n theBad: 'bad',\n theUgly: 'angry',\n theFunny: 'good',\n};\n\n/**\n * Map mood category to mood string for quotes from retroPageQuotes.\n */\nconst ADDITION_MOOD: Record<string, string> = {\n good: 'good',\n bad: 'bad',\n ugly: 'angry',\n};\n\n/**\n * Transform quotes from both curated sources.\n * Merges retro-page-data quotes (theGood/theBad/theUgly/theFunny) with\n * retro-page-quotes additions (good/bad/ugly). Parses informal timestamps,\n * strips @ prefix from speakers, and cross-references to phases.\n * Sorted by timestamp.\n */\nexport function transformQuotes(\n retroData: SourceRetroPageData,\n retroQuotes: SourceRetroPageQuotes,\n): CurationQuote[] {\n const phases = retroData.phases;\n const quotes: CurationQuote[] = [];\n\n // Derive reference year from first phase start date (for informal timestamp parsing)\n const firstPhaseStart = phases[0]?.start;\n const referenceYear = firstPhaseStart\n ? new Date(firstPhaseStart).getUTCFullYear()\n : new Date().getUTCFullYear();\n\n // Source 1: retroPageData.quotes (theGood, theBad, theUgly, theFunny)\n for (const [category, entries] of Object.entries(retroData.quotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = CATEGORY_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.time, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Source 2: retroPageQuotes (good, bad, ugly)\n for (const [category, entries] of Object.entries(retroQuotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = ADDITION_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.timestamp, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Sort chronologically\n quotes.sort((a, b) => a.timestamp - b.timestamp);\n return quotes;\n}\n\n/**\n * Transform trust arc keyframes from retro-page-data.\n * Source levels are 0-100 integers; we normalize to 0-1.\n * Sorted by timestamp for interpolation.\n */\nexport function transformTrustKeyframes(retroData: SourceRetroPageData): CurationTrustKeyframe[] {\n if (!retroData.trustArc || retroData.trustArc.length === 0) return [];\n\n return retroData.trustArc\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n level: entry.level / 100, // normalize 0-100 → 0-1\n label: entry.label,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/** Month abbreviation → 0-based index */\nconst MONTH_ABBREVS: Record<string, number> = {\n jan: 0,\n feb: 1,\n mar: 2,\n apr: 3,\n may: 4,\n jun: 5,\n jul: 6,\n aug: 7,\n sep: 8,\n oct: 9,\n nov: 10,\n dec: 11,\n};\n\n/**\n * Transform editorial narration entries from retro-page-data.\n * Each entry has an ISO timestamp, phase title, color, text, and type.\n * Returns empty array if no narration is present in the source data.\n */\nexport function transformNarration(retroData: SourceRetroPageData): CurationNarrationEntry[] {\n if (!retroData.editorialNarration || retroData.editorialNarration.length === 0) return [];\n\n return retroData.editorialNarration\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n phaseTitle: entry.phaseTitle,\n phaseColor: entry.phaseColor,\n text: entry.text,\n type: entry.type,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/**\n * Parse informal timestamp strings like \"Feb 10 21:18\", \"Dec 31 (early)\", \"Jan 2 ~23:00\".\n * Accepts any 3-letter month abbreviation.\n *\n * @param timeStr - Informal timestamp (e.g., \"Feb 10 21:18\", \"Dec 31\")\n * @param referenceYear - Year to use (e.g., 2025). Required — no hardcoded default.\n * For projects spanning Dec→Jan, callers should handle year rollover.\n * @returns Unix ms or null if unparseable.\n */\nexport function parseInformalTimestamp(\n timeStr: string | undefined | null,\n referenceYear: number,\n): number | null {\n if (!timeStr) return null;\n\n // Try ISO 8601 first (scaffold generates ISO timestamps)\n const isoDate = new Date(timeStr);\n if (!Number.isNaN(isoDate.getTime()) && timeStr.includes('-')) {\n return isoDate.getTime();\n }\n\n // Strip tildes and parenthetical notes\n const cleaned = timeStr\n .replace(/~/g, '')\n .replace(/\\(.*?\\)/g, '')\n .trim();\n\n // Match \"Mon DD HH:MM\" or \"Mon DD\" (3-letter month abbreviation)\n const match = cleaned.match(/([A-Za-z]{3})\\s+(\\d{1,2})(?:\\s+(\\d{1,2}):(\\d{2}))?/);\n if (!match) return null;\n\n const monthIdx = MONTH_ABBREVS[match[1].toLowerCase()];\n if (monthIdx === undefined) return null;\n\n const day = Number.parseInt(match[2], 10);\n const hour = match[3] ? Number.parseInt(match[3], 10) : 12; // default to noon if no time\n const minute = match[4] ? Number.parseInt(match[4], 10) : 0;\n\n const date = new Date(Date.UTC(referenceYear, monthIdx, day, hour, minute, 0));\n return date.getTime();\n}\n\n/**\n * Find which phase a timestamp falls within.\n * Returns the phase or undefined if outside all phases.\n */\nfunction findPhaseForTimestamp(\n timestamp: number,\n phases: SourceRetroPageData['phases'],\n): SourceRetroPageData['phases'][number] | undefined {\n return phases.find((p) => {\n const start = new Date(p.start).getTime();\n const end = new Date(p.end).getTime();\n return timestamp >= start && timestamp <= end;\n });\n}\n","/**\n * ScriptFile — the authoring contract for Step 2 (Script Writing).\n *\n * WHY: The script is the creative foundation. An agent writes this file\n * to define the narrative structure: who speaks, what they say, and in\n * what style. Every downstream file (pacing, timing) derives from this.\n *\n * The agent creates this from scratch in Step 2, guided by extracted data\n * (event density, agent activity, phases). The human reviews and approves.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const ScriptLineSchema = z.object({\n /** Unique identifier for this line (e.g., 'narrator-01', 'lead-03') */\n id: z.string().min(1),\n /** Who speaks this line (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Optional phase this line belongs to (for grouping in the viz) */\n phaseId: z.string().optional(),\n});\n\nexport const ScriptFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Ordered list of script lines */\n lines: z.array(ScriptLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type ScriptLine = z.infer<typeof ScriptLineSchema>;\nexport type ScriptFile = z.infer<typeof ScriptFileSchema>;\n","/**\n * PacingFile — the agent-facing timing contract for Step 4 (Viz Timing).\n *\n * WHY: The pacing file is what the agent edits to control how fast the viz\n * moves during each narration line. scaffold-pacing generates it from\n * script.json + audio clip durations. The agent then annotates 4 optional\n * fields per line: pauseAfter, vizSpeed, gapVizSpeed, note.\n *\n * Design: Approach A (Annotated Script) — mirrors the script with timing\n * annotations. Text + clip durations inline. Defaults handle 80% of lines.\n * No cascading edits (unlike start-time approaches).\n *\n * vizSpeed definition: multiplier on project-time-per-second.\n * 2.0 = viz moves 2x faster = LESS screen time for that period.\n * 0.5 = viz moves 2x slower = MORE screen time for that period.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const PacingLineSchema = z.object({\n /** Line ID — must match script.json line ID */\n id: z.string().min(1),\n /** Text from script (read-only, for context while editing pacing) */\n text: z.string().min(1),\n /** Audio clip duration in seconds (measured from file, read-only) */\n clipDuration: z.number().positive(),\n /** Silence after this line in seconds (overrides defaultPauseSec) */\n pauseAfter: z.number().nonnegative().optional(),\n /** Viz speed multiplier DURING this clip's audio. >1 = faster, <1 = slower */\n vizSpeed: z.number().positive().optional(),\n /** Viz speed multiplier DURING the pause after this clip (defaults to defaultVizSpeed) */\n gapVizSpeed: z.number().positive().optional(),\n /** Agent's reasoning for pacing choices (human reads during review) */\n note: z.string().optional(),\n});\n\nexport const PacingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Seconds of viz playback before first narration line */\n leadInSec: z.number().nonnegative().optional(),\n /** Seconds of viz playback after last narration line */\n tailOutSec: z.number().nonnegative().optional(),\n /** Default pause between lines in seconds (used when pauseAfter not set) */\n defaultPauseSec: z.number().nonnegative(),\n /** Default viz speed multiplier (used when vizSpeed/gapVizSpeed not set) */\n defaultVizSpeed: z.number().positive(),\n /** Ordered list of pacing lines — must match script.json order */\n lines: z.array(PacingLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type PacingLine = z.infer<typeof PacingLineSchema>;\nexport type PacingFile = z.infer<typeof PacingFileSchema>;\n","/**\n * TimingFile — the engine-facing contract produced by generateTiming().\n *\n * WHY: This is the fully-resolved timing data that the transform layer reads\n * to produce narration entries with precise progress mapping. All fields are\n * required — no defaults, no optionals (except phase). generateTiming()\n * resolves all defaults from PacingFile and computes progress values.\n *\n * The transform layer validates this on read (belt-and-suspenders with\n * generateTiming's validation on write). If this file is corrupt, the\n * pipeline fails fast with a clear error.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const TimedLineSchema = z\n .object({\n /** Line ID — matches script.json and pacing.json */\n id: z.string().min(1),\n /** Speaker identifier (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Wall-clock start time in seconds from video start */\n startSec: z.number().nonnegative(),\n /** Audio clip duration in seconds */\n durationSec: z.number().positive(),\n /** Pause after this line in seconds (resolved from defaults) */\n pauseAfterSec: z.number().nonnegative(),\n /** Audio file path relative to audio directory (e.g., 'narrator-01.mp3') */\n audioFile: z.string().min(1),\n /** Viz progress at clip start [0, 1] */\n progressStart: z.number().min(0).max(1),\n /** Viz progress at clip end [0, 1] */\n progressEnd: z.number().min(0).max(1),\n /** Viz speed multiplier during this clip */\n vizSpeed: z.number().positive(),\n /** Viz speed multiplier during the pause after this clip */\n gapVizSpeed: z.number().positive(),\n /** Phase this line belongs to (optional) */\n phase: z.string().optional(),\n })\n .refine((line) => line.progressStart <= line.progressEnd, {\n message: 'progressStart must be <= progressEnd',\n path: ['progressStart'],\n });\n\nexport const TimingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Total video duration in seconds */\n totalDurationSec: z.number().positive(),\n /** Ordered list of timed lines — fully resolved, all fields required */\n lines: z.array(TimedLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type TimedLine = z.infer<typeof TimedLineSchema>;\nexport type TimingFile = z.infer<typeof TimingFileSchema>;\n","/**\n * Audio manifest schema — the contract between audio generation and Remotion consumption.\n * Lives at: remotion/public/audio/audio-manifest.json\n *\n * @module audio/manifest\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AudioManifest {\n version: 1;\n fps: number;\n totalDurationSec: number;\n\n /** Per-beat voice clips */\n dialog: DialogBeat[];\n /** Background music tracks */\n music: MusicTrack[];\n /** One-shot sound effects */\n sfx: SfxPlacement[];\n /** Text overlays (title cards, labels, data accents) */\n overlays: TextOverlay[];\n}\n\nexport interface DialogBeat {\n id: string;\n file: string;\n speaker: string;\n text: string;\n startSec: number;\n durationSec: number;\n volume?: number;\n style?: 'quote' | 'narrator' | 'text-card';\n}\n\nexport interface MusicTrack {\n id: string;\n file: string;\n startSec: number;\n durationSec: number;\n volume: number;\n fadeInSec?: number;\n fadeOutSec?: number;\n duckTo?: number;\n}\n\nexport interface SfxPlacement {\n id: string;\n file: string;\n startSec: number;\n volume?: number;\n note?: string;\n}\n\nexport interface TextOverlay {\n id: string;\n type: 'title-card' | 'speaker-label' | 'data-accent' | 'chapter';\n text: string;\n startSec: number;\n durationSec: number;\n style?: {\n fontSize?: number;\n color?: string;\n position?: 'center' | 'bottom-left' | 'bottom-right' | 'top';\n typingSpeed?: number | null;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate an AudioManifest for structural correctness.\n *\n * Checks:\n * - Required top-level fields (version, fps, totalDurationSec)\n * - Dialog beats within totalDurationSec, no same-speaker overlap\n * - Music tracks within totalDurationSec, volume 0-1\n * - SFX placements within totalDurationSec\n * - Overlay timing within totalDurationSec\n * - File paths are relative strings (no absolute paths)\n * - Volume values in 0-1 range\n */\nexport function validateAudioManifest(manifest: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (manifest == null || typeof manifest !== 'object') {\n return { valid: false, errors: ['Manifest must be a non-null object'] };\n }\n\n const m = manifest as Record<string, unknown>;\n\n // --- Required top-level fields ---\n if (m.version !== 1) {\n errors.push(`version must be 1, got ${JSON.stringify(m.version)}`);\n }\n if (typeof m.fps !== 'number' || m.fps <= 0) {\n errors.push(`fps must be a positive number, got ${JSON.stringify(m.fps)}`);\n }\n if (typeof m.totalDurationSec !== 'number' || m.totalDurationSec <= 0) {\n errors.push(\n `totalDurationSec must be a positive number, got ${JSON.stringify(m.totalDurationSec)}`,\n );\n }\n\n const totalDur = typeof m.totalDurationSec === 'number' ? m.totalDurationSec : 0;\n\n // --- Arrays must exist ---\n if (!Array.isArray(m.dialog)) {\n errors.push('dialog must be an array');\n }\n if (!Array.isArray(m.music)) {\n errors.push('music must be an array');\n }\n if (!Array.isArray(m.sfx)) {\n errors.push('sfx must be an array');\n }\n if (!Array.isArray(m.overlays)) {\n errors.push('overlays must be an array');\n }\n\n // Bail early if arrays are missing — can't validate contents\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n const dialog = m.dialog as DialogBeat[];\n const music = m.music as MusicTrack[];\n const sfx = m.sfx as SfxPlacement[];\n const overlays = m.overlays as TextOverlay[];\n\n // --- Shared helpers ---\n function checkFilePath(file: unknown, context: string): void {\n if (typeof file !== 'string' || file.length === 0) {\n errors.push(`${context}: file must be a non-empty string`);\n } else if (file.startsWith('/') || file.startsWith('\\\\')) {\n errors.push(`${context}: file must be a relative path, got \"${file}\"`);\n }\n }\n\n function checkVolume(vol: unknown, context: string, required: boolean): void {\n if (vol == null) {\n if (required) errors.push(`${context}: volume is required`);\n return;\n }\n if (typeof vol !== 'number' || vol < 0 || vol > 1) {\n errors.push(`${context}: volume must be 0-1, got ${JSON.stringify(vol)}`);\n }\n }\n\n function checkTimingWithin(startSec: unknown, durationSec: unknown, context: string): void {\n if (typeof startSec !== 'number' || startSec < 0) {\n errors.push(\n `${context}: startSec must be a non-negative number, got ${JSON.stringify(startSec)}`,\n );\n return;\n }\n if (typeof durationSec === 'number') {\n if (durationSec < 0) {\n errors.push(`${context}: durationSec must be non-negative, got ${durationSec}`);\n }\n if (startSec + durationSec > totalDur) {\n errors.push(\n `${context}: startSec (${startSec}) + durationSec (${durationSec}) = ${startSec + durationSec} exceeds totalDurationSec (${totalDur})`,\n );\n }\n }\n }\n\n // --- Dialog beats ---\n const ids = new Set<string>();\n for (let i = 0; i < dialog.length; i++) {\n const b = dialog[i];\n const ctx = `dialog[${i}] (${b.id ?? 'no id'})`;\n\n if (typeof b.id !== 'string' || b.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n } else if (ids.has(b.id)) {\n errors.push(`${ctx}: duplicate id \"${b.id}\"`);\n } else {\n ids.add(b.id);\n }\n\n checkFilePath(b.file, ctx);\n\n if (typeof b.speaker !== 'string' || b.speaker.length === 0) {\n errors.push(`${ctx}: speaker must be a non-empty string`);\n }\n if (typeof b.text !== 'string') {\n errors.push(`${ctx}: text must be a string`);\n }\n if (typeof b.durationSec !== 'number' || b.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(b.durationSec)}`,\n );\n }\n\n checkTimingWithin(b.startSec, b.durationSec, ctx);\n checkVolume(b.volume, ctx, false);\n\n if (\n b.style !== undefined &&\n b.style !== 'quote' &&\n b.style !== 'narrator' &&\n b.style !== 'text-card'\n ) {\n errors.push(`${ctx}: style must be 'quote', 'narrator', or 'text-card', got \"${b.style}\"`);\n }\n }\n\n // --- Same-speaker overlap check ---\n const bySpeaker = new Map<string, DialogBeat[]>();\n for (const b of dialog) {\n if (typeof b.speaker !== 'string') continue;\n const list = bySpeaker.get(b.speaker) ?? [];\n list.push(b);\n bySpeaker.set(b.speaker, list);\n }\n for (const [speaker, beats] of bySpeaker) {\n const sorted = [...beats].sort((a, b) => a.startSec - b.startSec);\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1];\n const curr = sorted[i];\n const prevEnd = prev.startSec + prev.durationSec;\n if (prevEnd > curr.startSec) {\n errors.push(\n `dialog overlap for speaker \"${speaker}\": \"${prev.id}\" ends at ${prevEnd}s but \"${curr.id}\" starts at ${curr.startSec}s`,\n );\n }\n }\n }\n\n // --- Music tracks ---\n for (let i = 0; i < music.length; i++) {\n const t = music[i];\n const ctx = `music[${i}] (${t.id ?? 'no id'})`;\n\n if (typeof t.id !== 'string' || t.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(t.file, ctx);\n checkTimingWithin(t.startSec, t.durationSec, ctx);\n checkVolume(t.volume, ctx, true);\n\n if (t.fadeInSec != null && (typeof t.fadeInSec !== 'number' || t.fadeInSec < 0)) {\n errors.push(`${ctx}: fadeInSec must be a non-negative number`);\n }\n if (t.fadeOutSec != null && (typeof t.fadeOutSec !== 'number' || t.fadeOutSec < 0)) {\n errors.push(`${ctx}: fadeOutSec must be a non-negative number`);\n }\n if (t.duckTo != null) {\n if (typeof t.duckTo !== 'number' || t.duckTo < 0 || t.duckTo > 1) {\n errors.push(`${ctx}: duckTo must be 0-1, got ${JSON.stringify(t.duckTo)}`);\n }\n }\n }\n\n // --- SFX placements ---\n for (let i = 0; i < sfx.length; i++) {\n const s = sfx[i];\n const ctx = `sfx[${i}] (${s.id ?? 'no id'})`;\n\n if (typeof s.id !== 'string' || s.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(s.file, ctx);\n if (typeof s.startSec !== 'number' || s.startSec < 0) {\n errors.push(\n `${ctx}: startSec must be a non-negative number, got ${JSON.stringify(s.startSec)}`,\n );\n }\n if (s.startSec > totalDur) {\n errors.push(`${ctx}: startSec (${s.startSec}) exceeds totalDurationSec (${totalDur})`);\n }\n checkVolume(s.volume, ctx, false);\n }\n\n // --- Text overlays ---\n const validOverlayTypes = new Set(['title-card', 'speaker-label', 'data-accent', 'chapter']);\n const validPositions = new Set(['center', 'bottom-left', 'bottom-right', 'top']);\n for (let i = 0; i < overlays.length; i++) {\n const o = overlays[i];\n const ctx = `overlays[${i}] (${o.id ?? 'no id'})`;\n\n if (typeof o.id !== 'string' || o.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n if (!validOverlayTypes.has(o.type)) {\n errors.push(\n `${ctx}: type must be one of ${[...validOverlayTypes].join(', ')}, got \"${o.type}\"`,\n );\n }\n if (typeof o.text !== 'string' || o.text.length === 0) {\n errors.push(`${ctx}: text must be a non-empty string`);\n }\n if (typeof o.durationSec !== 'number' || o.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(o.durationSec)}`,\n );\n }\n checkTimingWithin(o.startSec, o.durationSec, ctx);\n\n if (o.style != null) {\n if (typeof o.style !== 'object') {\n errors.push(`${ctx}: style must be an object`);\n } else {\n if (\n o.style.fontSize != null &&\n (typeof o.style.fontSize !== 'number' || o.style.fontSize <= 0)\n ) {\n errors.push(`${ctx}: style.fontSize must be a positive number`);\n }\n if (o.style.color != null && typeof o.style.color !== 'string') {\n errors.push(`${ctx}: style.color must be a string`);\n }\n if (o.style.position != null && !validPositions.has(o.style.position)) {\n errors.push(\n `${ctx}: style.position must be one of ${[...validPositions].join(', ')}, got \"${o.style.position}\"`,\n );\n }\n if (\n o.style.typingSpeed !== undefined &&\n o.style.typingSpeed !== null &&\n (typeof o.style.typingSpeed !== 'number' || o.style.typingSpeed <= 0)\n ) {\n errors.push(`${ctx}: style.typingSpeed must be a positive number or null`);\n }\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute total duration from manifest content.\n * Returns max(endTime) across all tracks + 2s padding.\n * Useful for agents building the manifest before totalDurationSec is known.\n */\nexport function computeTotalDuration(\n manifest: Pick<AudioManifest, 'dialog' | 'music' | 'sfx' | 'overlays'>,\n): number {\n let maxEnd = 0;\n\n for (const b of manifest.dialog) {\n maxEnd = Math.max(maxEnd, b.startSec + b.durationSec);\n }\n for (const t of manifest.music) {\n maxEnd = Math.max(maxEnd, t.startSec + t.durationSec);\n }\n for (const s of manifest.sfx) {\n // SFX don't have durationSec — use startSec only\n maxEnd = Math.max(maxEnd, s.startSec);\n }\n for (const o of manifest.overlays) {\n maxEnd = Math.max(maxEnd, o.startSec + o.durationSec);\n }\n\n return maxEnd + 2;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/transform/transform-raw.ts","../src/transform/transform-curation.ts","../src/types/script.ts","../src/types/pacing.ts","../src/types/timing.ts","../src/audio/manifest.ts"],"names":["z"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\n * Transform source data → RawData (Contract A).\n *\n * Pure function. Deterministic. No side effects.\n * Maps existing JSON files to the generic RawData contract.\n */\n\nimport type {\n RawAgent,\n RawArtifact,\n RawCommit,\n RawData,\n RawMessage,\n RawPR,\n} from '../types/raw-data.js';\nimport type {\n SourceArtifactData,\n SourceBeamEvent,\n SourceCommit,\n SourceMessageEvent,\n SourcePR,\n SourcePRAgentMap,\n SourceRetroPageData,\n SourceTimelineEvents,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Infer a RawAgent role from a freeform role string (e.g. from teamAssembly).\n *\n * Checks for known keywords in the string (case-insensitive).\n * Order matters — more specific matches first (e.g. \"eng-lead\" matches \"lead\").\n * Falls back to 'builder' as the safest default (most common role).\n */\nexport function inferRole(roleString: string): RawAgent['role'] {\n const s = roleString.toLowerCase();\n if (s.includes('human') || s === 'user') return 'human';\n if (s.includes('lead')) return 'lead';\n if (s.includes('pm')) return 'pm';\n if (s.includes('tester') || s.includes('qa')) return 'tester';\n if (s.includes('reviewer') || s.includes('review')) return 'reviewer';\n if (s.includes('auditor') || s.includes('audit')) return 'auditor';\n if (s.includes('challenger') || s.includes('challenge')) return 'challenger';\n if (s.includes('scout')) return 'scout';\n if (s.includes('ideation')) return 'ideation';\n if (s.includes('research')) return 'researcher';\n if (s.includes('builder') || s.includes('build')) return 'builder';\n return 'builder'; // safe default — most common role\n}\n\n/**\n * Transform all source data into RawData.\n * This is the main entry point for the extraction layer.\n */\nexport function transformToRawData(sources: TransformSources): RawData {\n // First agent from teamAssembly is the default for unattributed items\n const defaultAgent = sources.retroPageData.teamAssembly[0]?.agent.replace('@', '') ?? 'unknown';\n\n return {\n project: {\n name: sources.retroPageData.meta.title,\n description: sources.retroPageData.meta.subtitle,\n },\n agents: transformAgents(\n sources.retroPageData,\n sources.chatActivity.agentTotals,\n sources.timelineEvents,\n ),\n commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),\n prs: transformPRs(sources.prs, sources.prAgentMap),\n messages: transformMessages(sources.timelineEvents),\n artifacts: sources.artifactData\n ? transformArtifacts(\n sources.artifactData,\n sources.retroPageData,\n sources.prs,\n sources.prAgentMap,\n )\n : [],\n };\n}\n\n/**\n * Build a map of agent → earliest message timestamp from timeline events.\n * Only counts messages where the agent is the sender (not just mentioned).\n */\nfunction buildFirstMessageTimeMap(timelineEvents?: SourceTimelineEvents): Map<string, number> {\n const map = new Map<string, number>();\n if (!timelineEvents) return map;\n\n for (const evt of timelineEvents.events) {\n if (evt.type !== 'message' && evt.type !== 'beam') continue;\n const sender = (evt as SourceMessageEvent | SourceBeamEvent).from;\n const ts = new Date(evt.t).getTime();\n const existing = map.get(sender);\n if (existing === undefined || ts < existing) {\n map.set(sender, ts);\n }\n }\n\n return map;\n}\n\n/**\n * Build RawAgent[] from team assembly data + chat activity.\n *\n * joinedAt resolution priority:\n * 1. First message timestamp from timeline events (most accurate)\n * 2. teamAssembly join time (curated/scaffold fallback)\n * 3. Project start date (last resort)\n *\n * Role resolution priority:\n * 1. Explicit `agentRoles` override (if provided)\n * 2. Inferred from teamAssembly `role` field (e.g. \"eng-lead\" → \"lead\")\n * 3. Default: 'builder' (most common role, safe fallback)\n *\n * Never throws on unknown agents — always infers or defaults.\n */\nexport function transformAgents(\n retroData: SourceRetroPageData,\n agentTotals: Record<string, number>,\n timelineEvents?: SourceTimelineEvents,\n agentRoles?: Record<string, string>,\n): RawAgent[] {\n const agents: RawAgent[] = [];\n const seen = new Set<string>();\n\n // Build first-message-time lookup from timeline events\n const firstMessageTime = buildFirstMessageTimeMap(timelineEvents);\n\n // Build a lookup from teamAssembly role fields for agents not in override\n const assemblyRoles = new Map<string, string>();\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n assemblyRoles.set(id, entry.role);\n }\n\n /** Resolve role for an agent: override → teamAssembly inference → default */\n function resolveRole(id: string): RawAgent['role'] {\n // 1. Explicit override\n if (agentRoles?.[id]) {\n return inferRole(agentRoles[id]);\n }\n // 2. Infer from teamAssembly role field\n const assemblyRole = assemblyRoles.get(id);\n if (assemblyRole) {\n return inferRole(assemblyRole);\n }\n // 3. Default\n return 'builder';\n }\n\n /** Resolve joinedAt: earliest of (first message, teamAssembly time), or startDate */\n function resolveJoinedAt(id: string, assemblyTime?: number): number {\n const msgTime = firstMessageTime.get(id);\n // Use earliest available timestamp — agent was present from whichever came first\n if (msgTime !== undefined && assemblyTime !== undefined) {\n return Math.min(msgTime, assemblyTime);\n }\n if (msgTime !== undefined) return msgTime;\n if (assemblyTime !== undefined) return assemblyTime;\n // Last resort: project start date\n return new Date(retroData.meta.startDate).getTime();\n }\n\n // Primary source: team assembly (has join times)\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n if (seen.has(id)) continue;\n seen.add(id);\n\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id, new Date(entry.time).getTime()),\n });\n }\n\n // Catch any agents in chat activity not in team assembly\n for (const id of Object.keys(agentTotals)) {\n if (seen.has(id)) continue;\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id),\n });\n seen.add(id);\n }\n\n return agents;\n}\n\n/**\n * Transform git commits → RawCommit[].\n * Cross-references pr-agent-map for attribution.\n *\n * @param defaultAgent - Fallback agent for commits with no PR reference\n * (typically the first agent from teamAssembly/roster)\n */\nexport function transformCommits(\n commits: SourceCommit[],\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): RawCommit[] {\n return commits.map((c) => {\n const agent = resolveCommitAgent(c, prAgentMap, defaultAgent);\n\n return {\n sha: c.hash,\n timestamp: new Date(c.date).getTime(),\n agent,\n message: c.subject,\n filesChanged: c.files.length,\n insertions: c.totalInsertions,\n deletions: c.totalDeletions,\n prNumber: c.prNumber ?? undefined,\n };\n });\n}\n\n/**\n * Resolve which agent authored a commit.\n * Strategy chain:\n * 1. prNumber field → pr-agent-map lookup\n * 2. \"Merge pull request #N\" in subject → pr-agent-map lookup\n * 3. \"(#N)\" suffix in subject → pr-agent-map lookup\n * 4. Fallback to defaultAgent (first agent from roster/teamAssembly)\n */\nexport function resolveCommitAgent(\n commit: SourceCommit,\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): string {\n // Strategy 1: direct prNumber field\n if (commit.prNumber != null) {\n const agent = prAgentMap[String(commit.prNumber)];\n if (agent) return agent;\n }\n\n // Strategy 2: \"Merge pull request #N\" pattern\n const mergeMatch = commit.subject.match(/^Merge pull request #(\\d+)/);\n if (mergeMatch) {\n const agent = prAgentMap[mergeMatch[1]];\n if (agent) return agent;\n }\n\n // Strategy 3: \"(#N)\" suffix pattern\n const suffixMatch = commit.subject.match(/\\(#(\\d+)\\)\\s*$/);\n if (suffixMatch) {\n const agent = prAgentMap[suffixMatch[1]];\n if (agent) return agent;\n }\n\n // Fallback: first agent from roster (caller provides)\n return defaultAgent;\n}\n\n/**\n * Transform PR details → RawPR[].\n * Cross-references pr-agent-map for attribution.\n */\nexport function transformPRs(prs: SourcePR[], prAgentMap: SourcePRAgentMap): RawPR[] {\n return prs.map((pr) => {\n const agent = prAgentMap[String(pr.number)] ?? 'unknown';\n\n return {\n number: pr.number,\n title: pr.title,\n agent,\n createdAt: new Date(pr.createdAt).getTime(),\n mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : null,\n additions: pr.additions,\n deletions: pr.deletions,\n branch: pr.headRefName,\n };\n });\n}\n\n/**\n * Infer artifact type from slug or file path.\n *\n * Handles both platforms:\n * - Redux: file paths with extensions (\"/specs/auth.md\", \"plan/task-X1Y2\")\n * - Cast: artifact slugs (\"spec-auth\", \"screenshot-login\", \"qa-review\")\n *\n * Redux patterns are checked first (more specific), cast patterns as fallback.\n */\nexport function inferArtifactType(slug: string): RawArtifact['type'] {\n // --- Redux: plan item prefixes ---\n if (slug.startsWith('plan/task-')) return 'task';\n if (slug.startsWith('plan/spec-')) return 'doc';\n\n // --- Extension-based (works for both platforms, but primarily redux file paths) ---\n const ext = slug.split('.').pop()?.toLowerCase();\n if (ext && ['ts', 'tsx', 'js', 'jsx', 'py', 'rs', 'go', 'sh'].includes(ext)) return 'code';\n if (ext && ['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'ico'].includes(ext)) return 'asset';\n if (ext && ['md', 'txt', 'json', 'yaml', 'yml', 'toml'].includes(ext)) return 'doc';\n\n // --- Redux: path-based patterns ---\n if (slug.includes('/specs/') || slug.includes('/spec/')) return 'doc';\n if (slug.includes('/assets/') || slug.includes('/images/')) return 'asset';\n\n // --- Cast: existing slug patterns (backward compat) ---\n if (slug.includes('.app.')) return 'code';\n if (slug.includes('screenshot') || slug.includes('qa-')) return 'asset';\n if (slug.includes('decision')) return 'decision';\n if (slug.includes('task') || slug.includes('phase-')) return 'task';\n if (slug.startsWith('spec-') || slug.startsWith('spec')) return 'doc';\n if (slug.includes('concept')) return 'doc';\n\n return 'doc';\n}\n\n/**\n * Resolve artifact agent from source data.\n *\n * Priority:\n * 1. Explicit `createdBy` from the artifact record (Miriad API provides this)\n * 2. PR number in slug → pr-agent-map lookup\n * 3. Configurable default (first agent from roster, typically the lead)\n */\nexport function resolveArtifactAgent(\n slug: string,\n prAgentMap: SourcePRAgentMap,\n createdBy: string | undefined,\n defaultAgent: string,\n): string {\n // 1. Explicit creator from source data\n if (createdBy) return createdBy;\n\n // 2. PR reference in slug → agent map\n const prMatch = slug.match(/#?(\\d+)/);\n if (prMatch) {\n const agent = prAgentMap[prMatch[1]];\n if (agent) return agent;\n }\n\n // 3. Default (first agent from roster)\n return defaultAgent;\n}\n\n/** Category name → artifact type */\nconst CATEGORY_TYPE_MAP: Record<string, RawArtifact['type']> = {\n qaScreenshots: 'asset',\n transitionSpecs: 'doc',\n transitionConcepts: 'doc',\n scenes: 'doc',\n vizConcepts: 'code',\n teamPrinciples: 'doc',\n retroData: 'doc',\n decisions: 'decision',\n};\n\n/**\n * Distribute N artifacts within time boundaries, clustered around\n * PR timestamps when available for realistic density.\n */\nexport function distributeTimestamps(\n count: number,\n bounds: { start: number; end: number },\n prTimestamps: number[],\n): number[] {\n const phasePRTimes = prTimestamps.filter((t) => t >= bounds.start && t <= bounds.end);\n const timestamps: number[] = [];\n\n for (let i = 0; i < count; i++) {\n let timestamp: number;\n if (phasePRTimes.length > 0) {\n const prIdx = i % phasePRTimes.length;\n timestamp = phasePRTimes[prIdx] + i * 60000;\n } else {\n const fraction = count > 1 ? i / (count - 1) : 0.5;\n timestamp = bounds.start + fraction * (bounds.end - bounds.start);\n }\n timestamps.push(Math.round(Math.max(bounds.start, Math.min(bounds.end, timestamp))));\n }\n\n return timestamps;\n}\n\n/**\n * Build a type distribution from category data.\n *\n * Each category maps to a type. We build a weighted list so bulk\n * artifacts can be assigned types proportional to category counts.\n * Returns entries sorted by count descending for deterministic assignment.\n *\n * Agent assignment is NOT done here — it's handled by the caller using\n * round-robin over the known agent list (from teamAssembly).\n */\nexport function buildCategoryDistribution(\n categories: SourceArtifactData['categories'],\n): Array<{ type: RawArtifact['type']; weight: number }> {\n const entries: Array<{ type: RawArtifact['type']; count: number }> = [];\n let total = 0;\n\n for (const [categoryName, categoryData] of Object.entries(categories)) {\n if (categoryData.count === 0) continue;\n entries.push({\n type: CATEGORY_TYPE_MAP[categoryName] ?? 'doc',\n count: categoryData.count,\n });\n total += categoryData.count;\n }\n\n if (total === 0) return [{ type: 'doc', weight: 1 }];\n\n return entries\n .sort((a, b) => b.count - a.count)\n .map((e) => ({ type: e.type, weight: e.count / total }));\n}\n\n/**\n * Build a slug → createdBy lookup from SourceArtifactData category items.\n * Items can be plain strings (no creator info) or objects with optional createdBy.\n */\nfunction buildCreatedByLookup(categories: SourceArtifactData['categories']): Map<string, string> {\n const lookup = new Map<string, string>();\n for (const categoryData of Object.values(categories)) {\n for (const item of categoryData.items ?? []) {\n if (typeof item === 'object' && item.createdBy) {\n lookup.set(item.slug, item.createdBy);\n }\n }\n }\n return lookup;\n}\n\n/**\n * Transform artifact-data.json → RawArtifact[].\n *\n * Uses phase `count` fields for correct per-phase density. Each phase\n * specifies how many artifacts were created during that time window:\n * Phase 1: 5, Phase 2: 45, Phase 3: 80, Phase 4: 120, Phase 5: 60 = 310\n *\n * Within each phase:\n * 1. Curated slugs get their own entries with createdBy from source data\n * 2. Remaining count filled with generated artifacts using category\n * type proportions and round-robin agent assignment\n * 3. All timestamps distributed within phase boundaries, clustered\n * around PR activity\n */\nexport function transformArtifacts(\n artifactData: SourceArtifactData,\n retroData: SourceRetroPageData,\n prs: SourcePR[],\n prAgentMap: SourcePRAgentMap,\n): RawArtifact[] {\n const artifacts: RawArtifact[] = [];\n\n // Build agent list from teamAssembly for round-robin and default\n const agentIds = retroData.teamAssembly.map((e) => e.agent.replace('@', ''));\n const defaultAgent = agentIds[0] ?? 'unknown';\n\n const phaseBoundaries = retroData.phases.map((p) => ({\n start: new Date(p.start).getTime(),\n end: new Date(p.end).getTime(),\n }));\n\n const prTimestamps = prs.map((pr) => new Date(pr.createdAt).getTime()).sort((a, b) => a - b);\n const distribution = buildCategoryDistribution(artifactData.categories);\n const createdByLookup = buildCreatedByLookup(artifactData.categories);\n\n let phaseIndex = 0;\n let globalBulkIndex = 0;\n\n for (const [_phaseName, phaseData] of Object.entries(artifactData.phases)) {\n if (phaseIndex >= phaseBoundaries.length) break;\n const bounds = phaseBoundaries[phaseIndex];\n phaseIndex++;\n\n const totalCount = phaseData.count;\n const slugs = phaseData.artifacts;\n const bulkCount = Math.max(0, totalCount - slugs.length);\n\n // All artifacts in this phase share one timestamp distribution\n const timestamps = distributeTimestamps(totalCount, bounds, prTimestamps);\n\n // ── Curated slugs first ──────────────────────────────────────────────\n let tsIdx = 0;\n for (const slug of slugs) {\n artifacts.push({\n slug,\n type: inferArtifactType(slug),\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent: resolveArtifactAgent(slug, prAgentMap, createdByLookup.get(slug), defaultAgent),\n });\n tsIdx++;\n }\n\n // ── Bulk artifacts fill remaining count ───────────────────────────────\n // Assign type by walking through the weighted distribution.\n // Assign agent by round-robin over the known agent list.\n let distIdx = 0;\n let distBudget = Math.round(distribution[0].weight * bulkCount);\n\n for (let i = 0; i < bulkCount; i++) {\n // Advance to next distribution bucket when current is exhausted\n while (distBudget <= 0 && distIdx < distribution.length - 1) {\n distIdx++;\n distBudget = Math.round(distribution[distIdx].weight * bulkCount);\n }\n distBudget--;\n\n const entry = distribution[distIdx];\n // Round-robin agent assignment across the roster\n const agent =\n agentIds.length > 0 ? agentIds[globalBulkIndex % agentIds.length] : defaultAgent;\n artifacts.push({\n slug: `phase${phaseIndex}-${entry.type}-${String(globalBulkIndex + 1).padStart(3, '0')}`,\n type: entry.type,\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent,\n });\n tsIdx++;\n globalBulkIndex++;\n }\n }\n\n artifacts.sort((a, b) => a.createdAt - b.createdAt);\n\n return artifacts;\n}\n\n/**\n * Transform curated timeline events into chat pills for the viewer.\n *\n * Chat pills come ONLY from timeline-events.json (curated).\n * Raw messages (messages-viz.json) are NEVER a source for chat pills —\n * they exist only for the agent to read during curation and for the\n * density table's \"Msgs\" column.\n *\n * Single source of truth: the curated file.\n */\nexport function transformMessages(timelineEvents: SourceTimelineEvents): RawMessage[] {\n const messageEvents = timelineEvents.events.filter(\n (e): e is SourceMessageEvent | SourceBeamEvent => e.type === 'message' || e.type === 'beam',\n );\n\n return messageEvents.map((evt, i) => ({\n id: `msg-${String(i).padStart(4, '0')}`,\n timestamp: new Date(evt.t).getTime(),\n sender: evt.from,\n mentions: [evt.to],\n }));\n}\n","/**\n * Transform source data → CurationData (editorial content).\n *\n * Pure function. Deterministic. No side effects.\n * Maps curated board artifacts to the CurationData contract.\n */\n\nimport type {\n CurationData,\n CurationMilestone,\n CurationNarrationEntry,\n CurationPhase,\n CurationQuote,\n CurationTrustKeyframe,\n} from '../types/raw-data.js';\nimport type {\n SourceRetroPageData,\n SourceRetroPageQuotes,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Transform curated source data into CurationData.\n * This is the main entry point for the curation layer.\n */\nexport function transformToCurationData(sources: TransformSources): CurationData {\n const narration = transformNarration(sources.retroPageData);\n const meta = sources.retroPageData.meta;\n\n // Thread curated timeline bounds from meta.startDate/endDate\n const curatedStartMs = meta?.startDate ? new Date(meta.startDate).getTime() : undefined;\n const curatedEndMs = meta?.endDate ? new Date(meta.endDate).getTime() : undefined;\n\n return {\n phases: transformPhases(sources.retroPageData),\n quotes: transformQuotes(sources.retroPageData, sources.retroPageQuotes),\n milestones: transformMilestones(sources.retroPageData),\n trustKeyframes: transformTrustKeyframes(sources.retroPageData),\n ...(narration.length > 0 ? { editorialNarration: narration } : {}),\n ...(curatedStartMs && !Number.isNaN(curatedStartMs) ? { curatedStartMs } : {}),\n ...(curatedEndMs && !Number.isNaN(curatedEndMs) ? { curatedEndMs } : {}),\n };\n}\n\n/**\n * Transform phase definitions from retro-page-data.\n * Phases have hand-curated boundaries, names, and descriptions.\n */\nexport function transformPhases(retroData: SourceRetroPageData): CurationPhase[] {\n return retroData.phases.map((p) => ({\n id: p.id,\n name: p.name,\n startTime: new Date(p.start).getTime(),\n endTime: new Date(p.end).getTime(),\n }));\n}\n\n/**\n * Transform milestones from retro-page-data.\n * Each milestone is cross-referenced to its containing phase.\n */\nexport function transformMilestones(retroData: SourceRetroPageData): CurationMilestone[] {\n const phases = retroData.phases;\n\n return retroData.milestones.map((m) => {\n const milestoneTime = new Date(m.time).getTime();\n const phase = findPhaseForTimestamp(milestoneTime, phases);\n\n return {\n label: m.label,\n timestamp: milestoneTime,\n phase: phase?.id ?? 'unknown',\n };\n });\n}\n\n/**\n * Map mood category to mood string for quotes from retroPageData.\n */\nconst CATEGORY_MOOD: Record<string, string> = {\n theGood: 'good',\n theBad: 'bad',\n theUgly: 'angry',\n theFunny: 'good',\n};\n\n/**\n * Map mood category to mood string for quotes from retroPageQuotes.\n */\nconst ADDITION_MOOD: Record<string, string> = {\n good: 'good',\n bad: 'bad',\n ugly: 'angry',\n};\n\n/**\n * Transform quotes from both curated sources.\n * Merges retro-page-data quotes (theGood/theBad/theUgly/theFunny) with\n * retro-page-quotes additions (good/bad/ugly). Parses informal timestamps,\n * strips @ prefix from speakers, and cross-references to phases.\n * Sorted by timestamp.\n */\nexport function transformQuotes(\n retroData: SourceRetroPageData,\n retroQuotes: SourceRetroPageQuotes,\n): CurationQuote[] {\n const phases = retroData.phases;\n const quotes: CurationQuote[] = [];\n\n // Derive reference year from first phase start date (for informal timestamp parsing)\n const firstPhaseStart = phases[0]?.start;\n const referenceYear = firstPhaseStart\n ? new Date(firstPhaseStart).getUTCFullYear()\n : new Date().getUTCFullYear();\n\n // Source 1: retroPageData.quotes (theGood, theBad, theUgly, theFunny)\n for (const [category, entries] of Object.entries(retroData.quotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = CATEGORY_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.time, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Source 2: retroPageQuotes (good, bad, ugly)\n for (const [category, entries] of Object.entries(retroQuotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = ADDITION_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.timestamp, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Sort chronologically\n quotes.sort((a, b) => a.timestamp - b.timestamp);\n return quotes;\n}\n\n/**\n * Transform trust arc keyframes from retro-page-data.\n * Source levels are 0-100 integers; we normalize to 0-1.\n * Sorted by timestamp for interpolation.\n */\nexport function transformTrustKeyframes(retroData: SourceRetroPageData): CurationTrustKeyframe[] {\n if (!retroData.trustArc || retroData.trustArc.length === 0) return [];\n\n return retroData.trustArc\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n level: entry.level / 100, // normalize 0-100 → 0-1\n label: entry.label,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/** Month abbreviation → 0-based index */\nconst MONTH_ABBREVS: Record<string, number> = {\n jan: 0,\n feb: 1,\n mar: 2,\n apr: 3,\n may: 4,\n jun: 5,\n jul: 6,\n aug: 7,\n sep: 8,\n oct: 9,\n nov: 10,\n dec: 11,\n};\n\n/**\n * Transform editorial narration entries from retro-page-data.\n * Each entry has an ISO timestamp, phase title, color, text, and type.\n * Returns empty array if no narration is present in the source data.\n */\nexport function transformNarration(retroData: SourceRetroPageData): CurationNarrationEntry[] {\n if (!retroData.editorialNarration || retroData.editorialNarration.length === 0) return [];\n\n return retroData.editorialNarration\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n phaseTitle: entry.phaseTitle,\n phaseColor: entry.phaseColor,\n text: entry.text,\n type: entry.type,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/**\n * Parse informal timestamp strings like \"Feb 10 21:18\", \"Dec 31 (early)\", \"Jan 2 ~23:00\".\n * Accepts any 3-letter month abbreviation.\n *\n * @param timeStr - Informal timestamp (e.g., \"Feb 10 21:18\", \"Dec 31\")\n * @param referenceYear - Year to use (e.g., 2025). Required — no hardcoded default.\n * For projects spanning Dec→Jan, callers should handle year rollover.\n * @returns Unix ms or null if unparseable.\n */\nexport function parseInformalTimestamp(\n timeStr: string | undefined | null,\n referenceYear: number,\n): number | null {\n if (!timeStr) return null;\n\n // Try ISO 8601 first (scaffold generates ISO timestamps)\n const isoDate = new Date(timeStr);\n if (!Number.isNaN(isoDate.getTime()) && timeStr.includes('-')) {\n return isoDate.getTime();\n }\n\n // Strip tildes and parenthetical notes\n const cleaned = timeStr\n .replace(/~/g, '')\n .replace(/\\(.*?\\)/g, '')\n .trim();\n\n // Match \"Mon DD HH:MM\" or \"Mon DD\" (3-letter month abbreviation)\n const match = cleaned.match(/([A-Za-z]{3})\\s+(\\d{1,2})(?:\\s+(\\d{1,2}):(\\d{2}))?/);\n if (!match) return null;\n\n const monthIdx = MONTH_ABBREVS[match[1].toLowerCase()];\n if (monthIdx === undefined) return null;\n\n const day = Number.parseInt(match[2], 10);\n const hour = match[3] ? Number.parseInt(match[3], 10) : 12; // default to noon if no time\n const minute = match[4] ? Number.parseInt(match[4], 10) : 0;\n\n const date = new Date(Date.UTC(referenceYear, monthIdx, day, hour, minute, 0));\n return date.getTime();\n}\n\n/**\n * Find which phase a timestamp falls within.\n * Returns the phase or undefined if outside all phases.\n */\nfunction findPhaseForTimestamp(\n timestamp: number,\n phases: SourceRetroPageData['phases'],\n): SourceRetroPageData['phases'][number] | undefined {\n return phases.find((p) => {\n const start = new Date(p.start).getTime();\n const end = new Date(p.end).getTime();\n return timestamp >= start && timestamp <= end;\n });\n}\n","/**\n * ScriptFile — the authoring contract for Step 2 (Script Writing).\n *\n * WHY: The script is the creative foundation. An agent writes this file\n * to define the narrative structure: who speaks, what they say, and in\n * what style. Every downstream file (pacing, timing) derives from this.\n *\n * The agent creates this from scratch in Step 2, guided by extracted data\n * (event density, agent activity, phases). The human reviews and approves.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const ScriptLineSchema = z.object({\n /** Unique identifier for this line (e.g., 'narrator-01', 'lead-03') */\n id: z.string().min(1),\n /** Who speaks this line (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Optional phase this line belongs to (for grouping in the viz) */\n phaseId: z.string().optional(),\n});\n\nexport const ScriptFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Ordered list of script lines */\n lines: z.array(ScriptLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type ScriptLine = z.infer<typeof ScriptLineSchema>;\nexport type ScriptFile = z.infer<typeof ScriptFileSchema>;\n","/**\n * PacingFile — the agent-facing timing contract for Step 4 (Viz Timing).\n *\n * WHY: The pacing file is what the agent edits to control how fast the viz\n * moves during each narration line. scaffold-pacing generates it from\n * script.json + audio clip durations. The agent then annotates 4 optional\n * fields per line: pauseAfter, vizSpeed, gapVizSpeed, note.\n *\n * Design: Approach A (Annotated Script) — mirrors the script with timing\n * annotations. Text + clip durations inline. Defaults handle 80% of lines.\n * No cascading edits (unlike start-time approaches).\n *\n * vizSpeed definition: multiplier on project-time-per-second.\n * 2.0 = viz moves 2x faster = LESS screen time for that period.\n * 0.5 = viz moves 2x slower = MORE screen time for that period.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const PacingLineSchema = z.object({\n /** Line ID — must match script.json line ID */\n id: z.string().min(1),\n /** Text from script (read-only, for context while editing pacing) */\n text: z.string().min(1),\n /** Audio clip duration in seconds (measured from file, read-only) */\n clipDuration: z.number().positive(),\n /** Silence after this line in seconds (overrides defaultPauseSec) */\n pauseAfter: z.number().nonnegative().optional(),\n /** Viz speed multiplier DURING this clip's audio. >1 = faster, <1 = slower */\n vizSpeed: z.number().positive().optional(),\n /** Viz speed multiplier DURING the pause after this clip (defaults to defaultVizSpeed) */\n gapVizSpeed: z.number().positive().optional(),\n /** Agent's reasoning for pacing choices (human reads during review) */\n note: z.string().optional(),\n});\n\nexport const PacingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Seconds of viz playback before first narration line */\n leadInSec: z.number().nonnegative().optional(),\n /** Seconds of viz playback after last narration line */\n tailOutSec: z.number().nonnegative().optional(),\n /** Default pause between lines in seconds (used when pauseAfter not set) */\n defaultPauseSec: z.number().nonnegative(),\n /** Default viz speed multiplier (used when vizSpeed/gapVizSpeed not set) */\n defaultVizSpeed: z.number().positive(),\n /** Ordered list of pacing lines — must match script.json order */\n lines: z.array(PacingLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type PacingLine = z.infer<typeof PacingLineSchema>;\nexport type PacingFile = z.infer<typeof PacingFileSchema>;\n","/**\n * TimingFile — the engine-facing contract produced by generateTiming().\n *\n * WHY: This is the fully-resolved timing data that the transform layer reads\n * to produce narration entries with precise progress mapping. All fields are\n * required — no defaults, no optionals (except phase). generateTiming()\n * resolves all defaults from PacingFile and computes progress values.\n *\n * The transform layer validates this on read (belt-and-suspenders with\n * generateTiming's validation on write). If this file is corrupt, the\n * pipeline fails fast with a clear error.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const TimedLineSchema = z\n .object({\n /** Line ID — matches script.json and pacing.json */\n id: z.string().min(1),\n /** Speaker identifier (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Wall-clock start time in seconds from video start */\n startSec: z.number().nonnegative(),\n /** Audio clip duration in seconds */\n durationSec: z.number().positive(),\n /** Pause after this line in seconds (resolved from defaults) */\n pauseAfterSec: z.number().nonnegative(),\n /** Audio file path relative to audio directory (e.g., 'narrator-01.mp3') */\n audioFile: z.string().min(1),\n /** Viz progress at clip start [0, 1] */\n progressStart: z.number().min(0).max(1),\n /** Viz progress at clip end [0, 1] */\n progressEnd: z.number().min(0).max(1),\n /** Viz speed multiplier during this clip */\n vizSpeed: z.number().positive(),\n /** Viz speed multiplier during the pause after this clip */\n gapVizSpeed: z.number().positive(),\n /** Phase this line belongs to (optional) */\n phase: z.string().optional(),\n })\n .refine((line) => line.progressStart <= line.progressEnd, {\n message: 'progressStart must be <= progressEnd',\n path: ['progressStart'],\n });\n\nexport const TimingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Total video duration in seconds */\n totalDurationSec: z.number().positive(),\n /** Ordered list of timed lines — fully resolved, all fields required */\n lines: z.array(TimedLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type TimedLine = z.infer<typeof TimedLineSchema>;\nexport type TimingFile = z.infer<typeof TimingFileSchema>;\n","/**\n * Audio manifest schema — the contract between audio generation and Remotion consumption.\n * Lives at: remotion/public/audio/audio-manifest.json\n *\n * @module audio/manifest\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AudioManifest {\n version: 1;\n fps: number;\n totalDurationSec: number;\n\n /** Per-beat voice clips */\n dialog: DialogBeat[];\n /** Background music tracks */\n music: MusicTrack[];\n /** One-shot sound effects */\n sfx: SfxPlacement[];\n /** Text overlays (title cards, labels, data accents) */\n overlays: TextOverlay[];\n}\n\nexport interface DialogBeat {\n id: string;\n file: string;\n speaker: string;\n text: string;\n startSec: number;\n durationSec: number;\n volume?: number;\n style?: 'quote' | 'narrator' | 'text-card';\n}\n\nexport interface MusicTrack {\n id: string;\n file: string;\n startSec: number;\n durationSec: number;\n volume: number;\n fadeInSec?: number;\n fadeOutSec?: number;\n duckTo?: number;\n}\n\nexport interface SfxPlacement {\n id: string;\n file: string;\n startSec: number;\n volume?: number;\n note?: string;\n}\n\nexport interface TextOverlay {\n id: string;\n type: 'title-card' | 'speaker-label' | 'data-accent' | 'chapter';\n text: string;\n startSec: number;\n durationSec: number;\n style?: {\n fontSize?: number;\n color?: string;\n position?: 'center' | 'bottom-left' | 'bottom-right' | 'top';\n typingSpeed?: number | null;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate an AudioManifest for structural correctness.\n *\n * Checks:\n * - Required top-level fields (version, fps, totalDurationSec)\n * - Dialog beats within totalDurationSec, no same-speaker overlap\n * - Music tracks within totalDurationSec, volume 0-1\n * - SFX placements within totalDurationSec\n * - Overlay timing within totalDurationSec\n * - File paths are relative strings (no absolute paths)\n * - Volume values in 0-1 range\n */\nexport function validateAudioManifest(manifest: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (manifest == null || typeof manifest !== 'object') {\n return { valid: false, errors: ['Manifest must be a non-null object'] };\n }\n\n const m = manifest as Record<string, unknown>;\n\n // --- Required top-level fields ---\n if (m.version !== 1) {\n errors.push(`version must be 1, got ${JSON.stringify(m.version)}`);\n }\n if (typeof m.fps !== 'number' || m.fps <= 0) {\n errors.push(`fps must be a positive number, got ${JSON.stringify(m.fps)}`);\n }\n if (typeof m.totalDurationSec !== 'number' || m.totalDurationSec <= 0) {\n errors.push(\n `totalDurationSec must be a positive number, got ${JSON.stringify(m.totalDurationSec)}`,\n );\n }\n\n const totalDur = typeof m.totalDurationSec === 'number' ? m.totalDurationSec : 0;\n\n // --- Arrays must exist ---\n if (!Array.isArray(m.dialog)) {\n errors.push('dialog must be an array');\n }\n if (!Array.isArray(m.music)) {\n errors.push('music must be an array');\n }\n if (!Array.isArray(m.sfx)) {\n errors.push('sfx must be an array');\n }\n if (!Array.isArray(m.overlays)) {\n errors.push('overlays must be an array');\n }\n\n // Bail early if arrays are missing — can't validate contents\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n const dialog = m.dialog as DialogBeat[];\n const music = m.music as MusicTrack[];\n const sfx = m.sfx as SfxPlacement[];\n const overlays = m.overlays as TextOverlay[];\n\n // --- Shared helpers ---\n function checkFilePath(file: unknown, context: string): void {\n if (typeof file !== 'string' || file.length === 0) {\n errors.push(`${context}: file must be a non-empty string`);\n } else if (file.startsWith('/') || file.startsWith('\\\\')) {\n errors.push(`${context}: file must be a relative path, got \"${file}\"`);\n }\n }\n\n function checkVolume(vol: unknown, context: string, required: boolean): void {\n if (vol == null) {\n if (required) errors.push(`${context}: volume is required`);\n return;\n }\n if (typeof vol !== 'number' || vol < 0 || vol > 1) {\n errors.push(`${context}: volume must be 0-1, got ${JSON.stringify(vol)}`);\n }\n }\n\n function checkTimingWithin(startSec: unknown, durationSec: unknown, context: string): void {\n if (typeof startSec !== 'number' || startSec < 0) {\n errors.push(\n `${context}: startSec must be a non-negative number, got ${JSON.stringify(startSec)}`,\n );\n return;\n }\n if (typeof durationSec === 'number') {\n if (durationSec < 0) {\n errors.push(`${context}: durationSec must be non-negative, got ${durationSec}`);\n }\n if (startSec + durationSec > totalDur) {\n errors.push(\n `${context}: startSec (${startSec}) + durationSec (${durationSec}) = ${startSec + durationSec} exceeds totalDurationSec (${totalDur})`,\n );\n }\n }\n }\n\n // --- Dialog beats ---\n const ids = new Set<string>();\n for (let i = 0; i < dialog.length; i++) {\n const b = dialog[i];\n const ctx = `dialog[${i}] (${b.id ?? 'no id'})`;\n\n if (typeof b.id !== 'string' || b.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n } else if (ids.has(b.id)) {\n errors.push(`${ctx}: duplicate id \"${b.id}\"`);\n } else {\n ids.add(b.id);\n }\n\n checkFilePath(b.file, ctx);\n\n if (typeof b.speaker !== 'string' || b.speaker.length === 0) {\n errors.push(`${ctx}: speaker must be a non-empty string`);\n }\n if (typeof b.text !== 'string') {\n errors.push(`${ctx}: text must be a string`);\n }\n if (typeof b.durationSec !== 'number' || b.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(b.durationSec)}`,\n );\n }\n\n checkTimingWithin(b.startSec, b.durationSec, ctx);\n checkVolume(b.volume, ctx, false);\n\n if (\n b.style !== undefined &&\n b.style !== 'quote' &&\n b.style !== 'narrator' &&\n b.style !== 'text-card'\n ) {\n errors.push(`${ctx}: style must be 'quote', 'narrator', or 'text-card', got \"${b.style}\"`);\n }\n }\n\n // --- Same-speaker overlap check ---\n const bySpeaker = new Map<string, DialogBeat[]>();\n for (const b of dialog) {\n if (typeof b.speaker !== 'string') continue;\n const list = bySpeaker.get(b.speaker) ?? [];\n list.push(b);\n bySpeaker.set(b.speaker, list);\n }\n for (const [speaker, beats] of bySpeaker) {\n const sorted = [...beats].sort((a, b) => a.startSec - b.startSec);\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1];\n const curr = sorted[i];\n const prevEnd = prev.startSec + prev.durationSec;\n if (prevEnd > curr.startSec) {\n errors.push(\n `dialog overlap for speaker \"${speaker}\": \"${prev.id}\" ends at ${prevEnd}s but \"${curr.id}\" starts at ${curr.startSec}s`,\n );\n }\n }\n }\n\n // --- Music tracks ---\n for (let i = 0; i < music.length; i++) {\n const t = music[i];\n const ctx = `music[${i}] (${t.id ?? 'no id'})`;\n\n if (typeof t.id !== 'string' || t.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(t.file, ctx);\n checkTimingWithin(t.startSec, t.durationSec, ctx);\n checkVolume(t.volume, ctx, true);\n\n if (t.fadeInSec != null && (typeof t.fadeInSec !== 'number' || t.fadeInSec < 0)) {\n errors.push(`${ctx}: fadeInSec must be a non-negative number`);\n }\n if (t.fadeOutSec != null && (typeof t.fadeOutSec !== 'number' || t.fadeOutSec < 0)) {\n errors.push(`${ctx}: fadeOutSec must be a non-negative number`);\n }\n if (t.duckTo != null) {\n if (typeof t.duckTo !== 'number' || t.duckTo < 0 || t.duckTo > 1) {\n errors.push(`${ctx}: duckTo must be 0-1, got ${JSON.stringify(t.duckTo)}`);\n }\n }\n }\n\n // --- SFX placements ---\n for (let i = 0; i < sfx.length; i++) {\n const s = sfx[i];\n const ctx = `sfx[${i}] (${s.id ?? 'no id'})`;\n\n if (typeof s.id !== 'string' || s.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(s.file, ctx);\n if (typeof s.startSec !== 'number' || s.startSec < 0) {\n errors.push(\n `${ctx}: startSec must be a non-negative number, got ${JSON.stringify(s.startSec)}`,\n );\n }\n if (s.startSec > totalDur) {\n errors.push(`${ctx}: startSec (${s.startSec}) exceeds totalDurationSec (${totalDur})`);\n }\n checkVolume(s.volume, ctx, false);\n }\n\n // --- Text overlays ---\n const validOverlayTypes = new Set(['title-card', 'speaker-label', 'data-accent', 'chapter']);\n const validPositions = new Set(['center', 'bottom-left', 'bottom-right', 'top']);\n for (let i = 0; i < overlays.length; i++) {\n const o = overlays[i];\n const ctx = `overlays[${i}] (${o.id ?? 'no id'})`;\n\n if (typeof o.id !== 'string' || o.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n if (!validOverlayTypes.has(o.type)) {\n errors.push(\n `${ctx}: type must be one of ${[...validOverlayTypes].join(', ')}, got \"${o.type}\"`,\n );\n }\n if (typeof o.text !== 'string' || o.text.length === 0) {\n errors.push(`${ctx}: text must be a non-empty string`);\n }\n if (typeof o.durationSec !== 'number' || o.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(o.durationSec)}`,\n );\n }\n checkTimingWithin(o.startSec, o.durationSec, ctx);\n\n if (o.style != null) {\n if (typeof o.style !== 'object') {\n errors.push(`${ctx}: style must be an object`);\n } else {\n if (\n o.style.fontSize != null &&\n (typeof o.style.fontSize !== 'number' || o.style.fontSize <= 0)\n ) {\n errors.push(`${ctx}: style.fontSize must be a positive number`);\n }\n if (o.style.color != null && typeof o.style.color !== 'string') {\n errors.push(`${ctx}: style.color must be a string`);\n }\n if (o.style.position != null && !validPositions.has(o.style.position)) {\n errors.push(\n `${ctx}: style.position must be one of ${[...validPositions].join(', ')}, got \"${o.style.position}\"`,\n );\n }\n if (\n o.style.typingSpeed !== undefined &&\n o.style.typingSpeed !== null &&\n (typeof o.style.typingSpeed !== 'number' || o.style.typingSpeed <= 0)\n ) {\n errors.push(`${ctx}: style.typingSpeed must be a positive number or null`);\n }\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute total duration from manifest content.\n * Returns max(endTime) across all tracks + 2s padding.\n * Useful for agents building the manifest before totalDurationSec is known.\n */\nexport function computeTotalDuration(\n manifest: Pick<AudioManifest, 'dialog' | 'music' | 'sfx' | 'overlays'>,\n): number {\n let maxEnd = 0;\n\n for (const b of manifest.dialog) {\n maxEnd = Math.max(maxEnd, b.startSec + b.durationSec);\n }\n for (const t of manifest.music) {\n maxEnd = Math.max(maxEnd, t.startSec + t.durationSec);\n }\n for (const s of manifest.sfx) {\n // SFX don't have durationSec — use startSec only\n maxEnd = Math.max(maxEnd, s.startSec);\n }\n for (const o of manifest.overlays) {\n maxEnd = Math.max(maxEnd, o.startSec + o.durationSec);\n }\n\n return maxEnd + 2;\n}\n"]}
|
package/dist-lib/index.js
CHANGED
|
@@ -33,7 +33,7 @@ function transformToRawData(sources) {
|
|
|
33
33
|
),
|
|
34
34
|
commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),
|
|
35
35
|
prs: transformPRs(sources.prs, sources.prAgentMap),
|
|
36
|
-
messages: transformMessages(sources.timelineEvents
|
|
36
|
+
messages: transformMessages(sources.timelineEvents),
|
|
37
37
|
artifacts: sources.artifactData ? transformArtifacts(
|
|
38
38
|
sources.artifactData,
|
|
39
39
|
sources.retroPageData,
|
|
@@ -282,15 +282,7 @@ function transformArtifacts(artifactData, retroData, prs, prAgentMap) {
|
|
|
282
282
|
artifacts.sort((a, b) => a.createdAt - b.createdAt);
|
|
283
283
|
return artifacts;
|
|
284
284
|
}
|
|
285
|
-
function transformMessages(timelineEvents
|
|
286
|
-
if (messages && messages.length > 0) {
|
|
287
|
-
return messages.map((msg) => ({
|
|
288
|
-
id: msg.id,
|
|
289
|
-
timestamp: new Date(msg.timestamp).getTime(),
|
|
290
|
-
sender: msg.sender,
|
|
291
|
-
mentions: msg.mentions
|
|
292
|
-
}));
|
|
293
|
-
}
|
|
285
|
+
function transformMessages(timelineEvents) {
|
|
294
286
|
const messageEvents = timelineEvents.events.filter(
|
|
295
287
|
(e) => e.type === "message" || e.type === "beam"
|
|
296
288
|
);
|
package/dist-lib/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transform/transform-raw.ts","../src/transform/transform-curation.ts","../src/types/script.ts","../src/types/pacing.ts","../src/types/timing.ts","../src/audio/manifest.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Transform source data → RawData (Contract A).\n *\n * Pure function. Deterministic. No side effects.\n * Maps existing JSON files to the generic RawData contract.\n */\n\nimport type {\n RawAgent,\n RawArtifact,\n RawCommit,\n RawData,\n RawMessage,\n RawPR,\n} from '../types/raw-data.js';\nimport type {\n SourceArtifactData,\n SourceBeamEvent,\n SourceCommit,\n SourceMessage,\n SourceMessageEvent,\n SourcePR,\n SourcePRAgentMap,\n SourceRetroPageData,\n SourceTimelineEvents,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Infer a RawAgent role from a freeform role string (e.g. from teamAssembly).\n *\n * Checks for known keywords in the string (case-insensitive).\n * Order matters — more specific matches first (e.g. \"eng-lead\" matches \"lead\").\n * Falls back to 'builder' as the safest default (most common role).\n */\nexport function inferRole(roleString: string): RawAgent['role'] {\n const s = roleString.toLowerCase();\n if (s.includes('human') || s === 'user') return 'human';\n if (s.includes('lead')) return 'lead';\n if (s.includes('pm')) return 'pm';\n if (s.includes('tester') || s.includes('qa')) return 'tester';\n if (s.includes('reviewer') || s.includes('review')) return 'reviewer';\n if (s.includes('auditor') || s.includes('audit')) return 'auditor';\n if (s.includes('challenger') || s.includes('challenge')) return 'challenger';\n if (s.includes('scout')) return 'scout';\n if (s.includes('ideation')) return 'ideation';\n if (s.includes('research')) return 'researcher';\n if (s.includes('builder') || s.includes('build')) return 'builder';\n return 'builder'; // safe default — most common role\n}\n\n/**\n * Transform all source data into RawData.\n * This is the main entry point for the extraction layer.\n */\nexport function transformToRawData(sources: TransformSources): RawData {\n // First agent from teamAssembly is the default for unattributed items\n const defaultAgent = sources.retroPageData.teamAssembly[0]?.agent.replace('@', '') ?? 'unknown';\n\n return {\n project: {\n name: sources.retroPageData.meta.title,\n description: sources.retroPageData.meta.subtitle,\n },\n agents: transformAgents(\n sources.retroPageData,\n sources.chatActivity.agentTotals,\n sources.timelineEvents,\n ),\n commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),\n prs: transformPRs(sources.prs, sources.prAgentMap),\n messages: transformMessages(sources.timelineEvents, sources.messages),\n artifacts: sources.artifactData\n ? transformArtifacts(\n sources.artifactData,\n sources.retroPageData,\n sources.prs,\n sources.prAgentMap,\n )\n : [],\n };\n}\n\n/**\n * Build a map of agent → earliest message timestamp from timeline events.\n * Only counts messages where the agent is the sender (not just mentioned).\n */\nfunction buildFirstMessageTimeMap(timelineEvents?: SourceTimelineEvents): Map<string, number> {\n const map = new Map<string, number>();\n if (!timelineEvents) return map;\n\n for (const evt of timelineEvents.events) {\n if (evt.type !== 'message' && evt.type !== 'beam') continue;\n const sender = (evt as SourceMessageEvent | SourceBeamEvent).from;\n const ts = new Date(evt.t).getTime();\n const existing = map.get(sender);\n if (existing === undefined || ts < existing) {\n map.set(sender, ts);\n }\n }\n\n return map;\n}\n\n/**\n * Build RawAgent[] from team assembly data + chat activity.\n *\n * joinedAt resolution priority:\n * 1. First message timestamp from timeline events (most accurate)\n * 2. teamAssembly join time (curated/scaffold fallback)\n * 3. Project start date (last resort)\n *\n * Role resolution priority:\n * 1. Explicit `agentRoles` override (if provided)\n * 2. Inferred from teamAssembly `role` field (e.g. \"eng-lead\" → \"lead\")\n * 3. Default: 'builder' (most common role, safe fallback)\n *\n * Never throws on unknown agents — always infers or defaults.\n */\nexport function transformAgents(\n retroData: SourceRetroPageData,\n agentTotals: Record<string, number>,\n timelineEvents?: SourceTimelineEvents,\n agentRoles?: Record<string, string>,\n): RawAgent[] {\n const agents: RawAgent[] = [];\n const seen = new Set<string>();\n\n // Build first-message-time lookup from timeline events\n const firstMessageTime = buildFirstMessageTimeMap(timelineEvents);\n\n // Build a lookup from teamAssembly role fields for agents not in override\n const assemblyRoles = new Map<string, string>();\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n assemblyRoles.set(id, entry.role);\n }\n\n /** Resolve role for an agent: override → teamAssembly inference → default */\n function resolveRole(id: string): RawAgent['role'] {\n // 1. Explicit override\n if (agentRoles?.[id]) {\n return inferRole(agentRoles[id]);\n }\n // 2. Infer from teamAssembly role field\n const assemblyRole = assemblyRoles.get(id);\n if (assemblyRole) {\n return inferRole(assemblyRole);\n }\n // 3. Default\n return 'builder';\n }\n\n /** Resolve joinedAt: earliest of (first message, teamAssembly time), or startDate */\n function resolveJoinedAt(id: string, assemblyTime?: number): number {\n const msgTime = firstMessageTime.get(id);\n // Use earliest available timestamp — agent was present from whichever came first\n if (msgTime !== undefined && assemblyTime !== undefined) {\n return Math.min(msgTime, assemblyTime);\n }\n if (msgTime !== undefined) return msgTime;\n if (assemblyTime !== undefined) return assemblyTime;\n // Last resort: project start date\n return new Date(retroData.meta.startDate).getTime();\n }\n\n // Primary source: team assembly (has join times)\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n if (seen.has(id)) continue;\n seen.add(id);\n\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id, new Date(entry.time).getTime()),\n });\n }\n\n // Catch any agents in chat activity not in team assembly\n for (const id of Object.keys(agentTotals)) {\n if (seen.has(id)) continue;\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id),\n });\n seen.add(id);\n }\n\n return agents;\n}\n\n/**\n * Transform git commits → RawCommit[].\n * Cross-references pr-agent-map for attribution.\n *\n * @param defaultAgent - Fallback agent for commits with no PR reference\n * (typically the first agent from teamAssembly/roster)\n */\nexport function transformCommits(\n commits: SourceCommit[],\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): RawCommit[] {\n return commits.map((c) => {\n const agent = resolveCommitAgent(c, prAgentMap, defaultAgent);\n\n return {\n sha: c.hash,\n timestamp: new Date(c.date).getTime(),\n agent,\n message: c.subject,\n filesChanged: c.files.length,\n insertions: c.totalInsertions,\n deletions: c.totalDeletions,\n prNumber: c.prNumber ?? undefined,\n };\n });\n}\n\n/**\n * Resolve which agent authored a commit.\n * Strategy chain:\n * 1. prNumber field → pr-agent-map lookup\n * 2. \"Merge pull request #N\" in subject → pr-agent-map lookup\n * 3. \"(#N)\" suffix in subject → pr-agent-map lookup\n * 4. Fallback to defaultAgent (first agent from roster/teamAssembly)\n */\nexport function resolveCommitAgent(\n commit: SourceCommit,\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): string {\n // Strategy 1: direct prNumber field\n if (commit.prNumber != null) {\n const agent = prAgentMap[String(commit.prNumber)];\n if (agent) return agent;\n }\n\n // Strategy 2: \"Merge pull request #N\" pattern\n const mergeMatch = commit.subject.match(/^Merge pull request #(\\d+)/);\n if (mergeMatch) {\n const agent = prAgentMap[mergeMatch[1]];\n if (agent) return agent;\n }\n\n // Strategy 3: \"(#N)\" suffix pattern\n const suffixMatch = commit.subject.match(/\\(#(\\d+)\\)\\s*$/);\n if (suffixMatch) {\n const agent = prAgentMap[suffixMatch[1]];\n if (agent) return agent;\n }\n\n // Fallback: first agent from roster (caller provides)\n return defaultAgent;\n}\n\n/**\n * Transform PR details → RawPR[].\n * Cross-references pr-agent-map for attribution.\n */\nexport function transformPRs(prs: SourcePR[], prAgentMap: SourcePRAgentMap): RawPR[] {\n return prs.map((pr) => {\n const agent = prAgentMap[String(pr.number)] ?? 'unknown';\n\n return {\n number: pr.number,\n title: pr.title,\n agent,\n createdAt: new Date(pr.createdAt).getTime(),\n mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : null,\n additions: pr.additions,\n deletions: pr.deletions,\n branch: pr.headRefName,\n };\n });\n}\n\n/**\n * Infer artifact type from slug or file path.\n *\n * Handles both platforms:\n * - Redux: file paths with extensions (\"/specs/auth.md\", \"plan/task-X1Y2\")\n * - Cast: artifact slugs (\"spec-auth\", \"screenshot-login\", \"qa-review\")\n *\n * Redux patterns are checked first (more specific), cast patterns as fallback.\n */\nexport function inferArtifactType(slug: string): RawArtifact['type'] {\n // --- Redux: plan item prefixes ---\n if (slug.startsWith('plan/task-')) return 'task';\n if (slug.startsWith('plan/spec-')) return 'doc';\n\n // --- Extension-based (works for both platforms, but primarily redux file paths) ---\n const ext = slug.split('.').pop()?.toLowerCase();\n if (ext && ['ts', 'tsx', 'js', 'jsx', 'py', 'rs', 'go', 'sh'].includes(ext)) return 'code';\n if (ext && ['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'ico'].includes(ext)) return 'asset';\n if (ext && ['md', 'txt', 'json', 'yaml', 'yml', 'toml'].includes(ext)) return 'doc';\n\n // --- Redux: path-based patterns ---\n if (slug.includes('/specs/') || slug.includes('/spec/')) return 'doc';\n if (slug.includes('/assets/') || slug.includes('/images/')) return 'asset';\n\n // --- Cast: existing slug patterns (backward compat) ---\n if (slug.includes('.app.')) return 'code';\n if (slug.includes('screenshot') || slug.includes('qa-')) return 'asset';\n if (slug.includes('decision')) return 'decision';\n if (slug.includes('task') || slug.includes('phase-')) return 'task';\n if (slug.startsWith('spec-') || slug.startsWith('spec')) return 'doc';\n if (slug.includes('concept')) return 'doc';\n\n return 'doc';\n}\n\n/**\n * Resolve artifact agent from source data.\n *\n * Priority:\n * 1. Explicit `createdBy` from the artifact record (Miriad API provides this)\n * 2. PR number in slug → pr-agent-map lookup\n * 3. Configurable default (first agent from roster, typically the lead)\n */\nexport function resolveArtifactAgent(\n slug: string,\n prAgentMap: SourcePRAgentMap,\n createdBy: string | undefined,\n defaultAgent: string,\n): string {\n // 1. Explicit creator from source data\n if (createdBy) return createdBy;\n\n // 2. PR reference in slug → agent map\n const prMatch = slug.match(/#?(\\d+)/);\n if (prMatch) {\n const agent = prAgentMap[prMatch[1]];\n if (agent) return agent;\n }\n\n // 3. Default (first agent from roster)\n return defaultAgent;\n}\n\n/** Category name → artifact type */\nconst CATEGORY_TYPE_MAP: Record<string, RawArtifact['type']> = {\n qaScreenshots: 'asset',\n transitionSpecs: 'doc',\n transitionConcepts: 'doc',\n scenes: 'doc',\n vizConcepts: 'code',\n teamPrinciples: 'doc',\n retroData: 'doc',\n decisions: 'decision',\n};\n\n/**\n * Distribute N artifacts within time boundaries, clustered around\n * PR timestamps when available for realistic density.\n */\nexport function distributeTimestamps(\n count: number,\n bounds: { start: number; end: number },\n prTimestamps: number[],\n): number[] {\n const phasePRTimes = prTimestamps.filter((t) => t >= bounds.start && t <= bounds.end);\n const timestamps: number[] = [];\n\n for (let i = 0; i < count; i++) {\n let timestamp: number;\n if (phasePRTimes.length > 0) {\n const prIdx = i % phasePRTimes.length;\n timestamp = phasePRTimes[prIdx] + i * 60000;\n } else {\n const fraction = count > 1 ? i / (count - 1) : 0.5;\n timestamp = bounds.start + fraction * (bounds.end - bounds.start);\n }\n timestamps.push(Math.round(Math.max(bounds.start, Math.min(bounds.end, timestamp))));\n }\n\n return timestamps;\n}\n\n/**\n * Build a type distribution from category data.\n *\n * Each category maps to a type. We build a weighted list so bulk\n * artifacts can be assigned types proportional to category counts.\n * Returns entries sorted by count descending for deterministic assignment.\n *\n * Agent assignment is NOT done here — it's handled by the caller using\n * round-robin over the known agent list (from teamAssembly).\n */\nexport function buildCategoryDistribution(\n categories: SourceArtifactData['categories'],\n): Array<{ type: RawArtifact['type']; weight: number }> {\n const entries: Array<{ type: RawArtifact['type']; count: number }> = [];\n let total = 0;\n\n for (const [categoryName, categoryData] of Object.entries(categories)) {\n if (categoryData.count === 0) continue;\n entries.push({\n type: CATEGORY_TYPE_MAP[categoryName] ?? 'doc',\n count: categoryData.count,\n });\n total += categoryData.count;\n }\n\n if (total === 0) return [{ type: 'doc', weight: 1 }];\n\n return entries\n .sort((a, b) => b.count - a.count)\n .map((e) => ({ type: e.type, weight: e.count / total }));\n}\n\n/**\n * Build a slug → createdBy lookup from SourceArtifactData category items.\n * Items can be plain strings (no creator info) or objects with optional createdBy.\n */\nfunction buildCreatedByLookup(categories: SourceArtifactData['categories']): Map<string, string> {\n const lookup = new Map<string, string>();\n for (const categoryData of Object.values(categories)) {\n for (const item of categoryData.items ?? []) {\n if (typeof item === 'object' && item.createdBy) {\n lookup.set(item.slug, item.createdBy);\n }\n }\n }\n return lookup;\n}\n\n/**\n * Transform artifact-data.json → RawArtifact[].\n *\n * Uses phase `count` fields for correct per-phase density. Each phase\n * specifies how many artifacts were created during that time window:\n * Phase 1: 5, Phase 2: 45, Phase 3: 80, Phase 4: 120, Phase 5: 60 = 310\n *\n * Within each phase:\n * 1. Curated slugs get their own entries with createdBy from source data\n * 2. Remaining count filled with generated artifacts using category\n * type proportions and round-robin agent assignment\n * 3. All timestamps distributed within phase boundaries, clustered\n * around PR activity\n */\nexport function transformArtifacts(\n artifactData: SourceArtifactData,\n retroData: SourceRetroPageData,\n prs: SourcePR[],\n prAgentMap: SourcePRAgentMap,\n): RawArtifact[] {\n const artifacts: RawArtifact[] = [];\n\n // Build agent list from teamAssembly for round-robin and default\n const agentIds = retroData.teamAssembly.map((e) => e.agent.replace('@', ''));\n const defaultAgent = agentIds[0] ?? 'unknown';\n\n const phaseBoundaries = retroData.phases.map((p) => ({\n start: new Date(p.start).getTime(),\n end: new Date(p.end).getTime(),\n }));\n\n const prTimestamps = prs.map((pr) => new Date(pr.createdAt).getTime()).sort((a, b) => a - b);\n const distribution = buildCategoryDistribution(artifactData.categories);\n const createdByLookup = buildCreatedByLookup(artifactData.categories);\n\n let phaseIndex = 0;\n let globalBulkIndex = 0;\n\n for (const [_phaseName, phaseData] of Object.entries(artifactData.phases)) {\n if (phaseIndex >= phaseBoundaries.length) break;\n const bounds = phaseBoundaries[phaseIndex];\n phaseIndex++;\n\n const totalCount = phaseData.count;\n const slugs = phaseData.artifacts;\n const bulkCount = Math.max(0, totalCount - slugs.length);\n\n // All artifacts in this phase share one timestamp distribution\n const timestamps = distributeTimestamps(totalCount, bounds, prTimestamps);\n\n // ── Curated slugs first ──────────────────────────────────────────────\n let tsIdx = 0;\n for (const slug of slugs) {\n artifacts.push({\n slug,\n type: inferArtifactType(slug),\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent: resolveArtifactAgent(slug, prAgentMap, createdByLookup.get(slug), defaultAgent),\n });\n tsIdx++;\n }\n\n // ── Bulk artifacts fill remaining count ───────────────────────────────\n // Assign type by walking through the weighted distribution.\n // Assign agent by round-robin over the known agent list.\n let distIdx = 0;\n let distBudget = Math.round(distribution[0].weight * bulkCount);\n\n for (let i = 0; i < bulkCount; i++) {\n // Advance to next distribution bucket when current is exhausted\n while (distBudget <= 0 && distIdx < distribution.length - 1) {\n distIdx++;\n distBudget = Math.round(distribution[distIdx].weight * bulkCount);\n }\n distBudget--;\n\n const entry = distribution[distIdx];\n // Round-robin agent assignment across the roster\n const agent =\n agentIds.length > 0 ? agentIds[globalBulkIndex % agentIds.length] : defaultAgent;\n artifacts.push({\n slug: `phase${phaseIndex}-${entry.type}-${String(globalBulkIndex + 1).padStart(3, '0')}`,\n type: entry.type,\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent,\n });\n tsIdx++;\n globalBulkIndex++;\n }\n }\n\n artifacts.sort((a, b) => a.createdAt - b.createdAt);\n\n return artifacts;\n}\n\n/**\n * Build RawMessage[] from extracted messages (data/messages.json).\n * Falls back to timeline events for backwards compatibility.\n *\n * Messages are DATA — they flow through extract → transform directly,\n * bypassing the curate step. The curate step handles editorial content\n * (quotes, narration, phases) only.\n */\nexport function transformMessages(\n timelineEvents: SourceTimelineEvents,\n messages?: SourceMessage[],\n): RawMessage[] {\n // Prefer extracted messages (direct data pipeline)\n if (messages && messages.length > 0) {\n return messages.map((msg) => ({\n id: msg.id,\n timestamp: new Date(msg.timestamp).getTime(),\n sender: msg.sender,\n mentions: msg.mentions,\n }));\n }\n\n // Fallback: legacy path via timeline events (beam/message events from curate)\n const messageEvents = timelineEvents.events.filter(\n (e): e is SourceMessageEvent | SourceBeamEvent => e.type === 'message' || e.type === 'beam',\n );\n\n return messageEvents.map((evt, i) => ({\n id: `msg-${String(i).padStart(4, '0')}`,\n timestamp: new Date(evt.t).getTime(),\n sender: evt.from,\n mentions: [evt.to],\n }));\n}\n","/**\n * Transform source data → CurationData (editorial content).\n *\n * Pure function. Deterministic. No side effects.\n * Maps curated board artifacts to the CurationData contract.\n */\n\nimport type {\n CurationData,\n CurationMilestone,\n CurationNarrationEntry,\n CurationPhase,\n CurationQuote,\n CurationTrustKeyframe,\n} from '../types/raw-data.js';\nimport type {\n SourceRetroPageData,\n SourceRetroPageQuotes,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Transform curated source data into CurationData.\n * This is the main entry point for the curation layer.\n */\nexport function transformToCurationData(sources: TransformSources): CurationData {\n const narration = transformNarration(sources.retroPageData);\n const meta = sources.retroPageData.meta;\n\n // Thread curated timeline bounds from meta.startDate/endDate\n const curatedStartMs = meta?.startDate ? new Date(meta.startDate).getTime() : undefined;\n const curatedEndMs = meta?.endDate ? new Date(meta.endDate).getTime() : undefined;\n\n return {\n phases: transformPhases(sources.retroPageData),\n quotes: transformQuotes(sources.retroPageData, sources.retroPageQuotes),\n milestones: transformMilestones(sources.retroPageData),\n trustKeyframes: transformTrustKeyframes(sources.retroPageData),\n ...(narration.length > 0 ? { editorialNarration: narration } : {}),\n ...(curatedStartMs && !Number.isNaN(curatedStartMs) ? { curatedStartMs } : {}),\n ...(curatedEndMs && !Number.isNaN(curatedEndMs) ? { curatedEndMs } : {}),\n };\n}\n\n/**\n * Transform phase definitions from retro-page-data.\n * Phases have hand-curated boundaries, names, and descriptions.\n */\nexport function transformPhases(retroData: SourceRetroPageData): CurationPhase[] {\n return retroData.phases.map((p) => ({\n id: p.id,\n name: p.name,\n startTime: new Date(p.start).getTime(),\n endTime: new Date(p.end).getTime(),\n }));\n}\n\n/**\n * Transform milestones from retro-page-data.\n * Each milestone is cross-referenced to its containing phase.\n */\nexport function transformMilestones(retroData: SourceRetroPageData): CurationMilestone[] {\n const phases = retroData.phases;\n\n return retroData.milestones.map((m) => {\n const milestoneTime = new Date(m.time).getTime();\n const phase = findPhaseForTimestamp(milestoneTime, phases);\n\n return {\n label: m.label,\n timestamp: milestoneTime,\n phase: phase?.id ?? 'unknown',\n };\n });\n}\n\n/**\n * Map mood category to mood string for quotes from retroPageData.\n */\nconst CATEGORY_MOOD: Record<string, string> = {\n theGood: 'good',\n theBad: 'bad',\n theUgly: 'angry',\n theFunny: 'good',\n};\n\n/**\n * Map mood category to mood string for quotes from retroPageQuotes.\n */\nconst ADDITION_MOOD: Record<string, string> = {\n good: 'good',\n bad: 'bad',\n ugly: 'angry',\n};\n\n/**\n * Transform quotes from both curated sources.\n * Merges retro-page-data quotes (theGood/theBad/theUgly/theFunny) with\n * retro-page-quotes additions (good/bad/ugly). Parses informal timestamps,\n * strips @ prefix from speakers, and cross-references to phases.\n * Sorted by timestamp.\n */\nexport function transformQuotes(\n retroData: SourceRetroPageData,\n retroQuotes: SourceRetroPageQuotes,\n): CurationQuote[] {\n const phases = retroData.phases;\n const quotes: CurationQuote[] = [];\n\n // Derive reference year from first phase start date (for informal timestamp parsing)\n const firstPhaseStart = phases[0]?.start;\n const referenceYear = firstPhaseStart\n ? new Date(firstPhaseStart).getUTCFullYear()\n : new Date().getUTCFullYear();\n\n // Source 1: retroPageData.quotes (theGood, theBad, theUgly, theFunny)\n for (const [category, entries] of Object.entries(retroData.quotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = CATEGORY_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.time, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Source 2: retroPageQuotes (good, bad, ugly)\n for (const [category, entries] of Object.entries(retroQuotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = ADDITION_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.timestamp, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Sort chronologically\n quotes.sort((a, b) => a.timestamp - b.timestamp);\n return quotes;\n}\n\n/**\n * Transform trust arc keyframes from retro-page-data.\n * Source levels are 0-100 integers; we normalize to 0-1.\n * Sorted by timestamp for interpolation.\n */\nexport function transformTrustKeyframes(retroData: SourceRetroPageData): CurationTrustKeyframe[] {\n if (!retroData.trustArc || retroData.trustArc.length === 0) return [];\n\n return retroData.trustArc\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n level: entry.level / 100, // normalize 0-100 → 0-1\n label: entry.label,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/** Month abbreviation → 0-based index */\nconst MONTH_ABBREVS: Record<string, number> = {\n jan: 0,\n feb: 1,\n mar: 2,\n apr: 3,\n may: 4,\n jun: 5,\n jul: 6,\n aug: 7,\n sep: 8,\n oct: 9,\n nov: 10,\n dec: 11,\n};\n\n/**\n * Transform editorial narration entries from retro-page-data.\n * Each entry has an ISO timestamp, phase title, color, text, and type.\n * Returns empty array if no narration is present in the source data.\n */\nexport function transformNarration(retroData: SourceRetroPageData): CurationNarrationEntry[] {\n if (!retroData.editorialNarration || retroData.editorialNarration.length === 0) return [];\n\n return retroData.editorialNarration\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n phaseTitle: entry.phaseTitle,\n phaseColor: entry.phaseColor,\n text: entry.text,\n type: entry.type,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/**\n * Parse informal timestamp strings like \"Feb 10 21:18\", \"Dec 31 (early)\", \"Jan 2 ~23:00\".\n * Accepts any 3-letter month abbreviation.\n *\n * @param timeStr - Informal timestamp (e.g., \"Feb 10 21:18\", \"Dec 31\")\n * @param referenceYear - Year to use (e.g., 2025). Required — no hardcoded default.\n * For projects spanning Dec→Jan, callers should handle year rollover.\n * @returns Unix ms or null if unparseable.\n */\nexport function parseInformalTimestamp(\n timeStr: string | undefined | null,\n referenceYear: number,\n): number | null {\n if (!timeStr) return null;\n\n // Try ISO 8601 first (scaffold generates ISO timestamps)\n const isoDate = new Date(timeStr);\n if (!Number.isNaN(isoDate.getTime()) && timeStr.includes('-')) {\n return isoDate.getTime();\n }\n\n // Strip tildes and parenthetical notes\n const cleaned = timeStr\n .replace(/~/g, '')\n .replace(/\\(.*?\\)/g, '')\n .trim();\n\n // Match \"Mon DD HH:MM\" or \"Mon DD\" (3-letter month abbreviation)\n const match = cleaned.match(/([A-Za-z]{3})\\s+(\\d{1,2})(?:\\s+(\\d{1,2}):(\\d{2}))?/);\n if (!match) return null;\n\n const monthIdx = MONTH_ABBREVS[match[1].toLowerCase()];\n if (monthIdx === undefined) return null;\n\n const day = Number.parseInt(match[2], 10);\n const hour = match[3] ? Number.parseInt(match[3], 10) : 12; // default to noon if no time\n const minute = match[4] ? Number.parseInt(match[4], 10) : 0;\n\n const date = new Date(Date.UTC(referenceYear, monthIdx, day, hour, minute, 0));\n return date.getTime();\n}\n\n/**\n * Find which phase a timestamp falls within.\n * Returns the phase or undefined if outside all phases.\n */\nfunction findPhaseForTimestamp(\n timestamp: number,\n phases: SourceRetroPageData['phases'],\n): SourceRetroPageData['phases'][number] | undefined {\n return phases.find((p) => {\n const start = new Date(p.start).getTime();\n const end = new Date(p.end).getTime();\n return timestamp >= start && timestamp <= end;\n });\n}\n","/**\n * ScriptFile — the authoring contract for Step 2 (Script Writing).\n *\n * WHY: The script is the creative foundation. An agent writes this file\n * to define the narrative structure: who speaks, what they say, and in\n * what style. Every downstream file (pacing, timing) derives from this.\n *\n * The agent creates this from scratch in Step 2, guided by extracted data\n * (event density, agent activity, phases). The human reviews and approves.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const ScriptLineSchema = z.object({\n /** Unique identifier for this line (e.g., 'narrator-01', 'lead-03') */\n id: z.string().min(1),\n /** Who speaks this line (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Optional phase this line belongs to (for grouping in the viz) */\n phaseId: z.string().optional(),\n});\n\nexport const ScriptFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Ordered list of script lines */\n lines: z.array(ScriptLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type ScriptLine = z.infer<typeof ScriptLineSchema>;\nexport type ScriptFile = z.infer<typeof ScriptFileSchema>;\n","/**\n * PacingFile — the agent-facing timing contract for Step 4 (Viz Timing).\n *\n * WHY: The pacing file is what the agent edits to control how fast the viz\n * moves during each narration line. scaffold-pacing generates it from\n * script.json + audio clip durations. The agent then annotates 4 optional\n * fields per line: pauseAfter, vizSpeed, gapVizSpeed, note.\n *\n * Design: Approach A (Annotated Script) — mirrors the script with timing\n * annotations. Text + clip durations inline. Defaults handle 80% of lines.\n * No cascading edits (unlike start-time approaches).\n *\n * vizSpeed definition: multiplier on project-time-per-second.\n * 2.0 = viz moves 2x faster = LESS screen time for that period.\n * 0.5 = viz moves 2x slower = MORE screen time for that period.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const PacingLineSchema = z.object({\n /** Line ID — must match script.json line ID */\n id: z.string().min(1),\n /** Text from script (read-only, for context while editing pacing) */\n text: z.string().min(1),\n /** Audio clip duration in seconds (measured from file, read-only) */\n clipDuration: z.number().positive(),\n /** Silence after this line in seconds (overrides defaultPauseSec) */\n pauseAfter: z.number().nonnegative().optional(),\n /** Viz speed multiplier DURING this clip's audio. >1 = faster, <1 = slower */\n vizSpeed: z.number().positive().optional(),\n /** Viz speed multiplier DURING the pause after this clip (defaults to defaultVizSpeed) */\n gapVizSpeed: z.number().positive().optional(),\n /** Agent's reasoning for pacing choices (human reads during review) */\n note: z.string().optional(),\n});\n\nexport const PacingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Seconds of viz playback before first narration line */\n leadInSec: z.number().nonnegative().optional(),\n /** Seconds of viz playback after last narration line */\n tailOutSec: z.number().nonnegative().optional(),\n /** Default pause between lines in seconds (used when pauseAfter not set) */\n defaultPauseSec: z.number().nonnegative(),\n /** Default viz speed multiplier (used when vizSpeed/gapVizSpeed not set) */\n defaultVizSpeed: z.number().positive(),\n /** Ordered list of pacing lines — must match script.json order */\n lines: z.array(PacingLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type PacingLine = z.infer<typeof PacingLineSchema>;\nexport type PacingFile = z.infer<typeof PacingFileSchema>;\n","/**\n * TimingFile — the engine-facing contract produced by generateTiming().\n *\n * WHY: This is the fully-resolved timing data that the transform layer reads\n * to produce narration entries with precise progress mapping. All fields are\n * required — no defaults, no optionals (except phase). generateTiming()\n * resolves all defaults from PacingFile and computes progress values.\n *\n * The transform layer validates this on read (belt-and-suspenders with\n * generateTiming's validation on write). If this file is corrupt, the\n * pipeline fails fast with a clear error.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const TimedLineSchema = z\n .object({\n /** Line ID — matches script.json and pacing.json */\n id: z.string().min(1),\n /** Speaker identifier (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Wall-clock start time in seconds from video start */\n startSec: z.number().nonnegative(),\n /** Audio clip duration in seconds */\n durationSec: z.number().positive(),\n /** Pause after this line in seconds (resolved from defaults) */\n pauseAfterSec: z.number().nonnegative(),\n /** Audio file path relative to audio directory (e.g., 'narrator-01.mp3') */\n audioFile: z.string().min(1),\n /** Viz progress at clip start [0, 1] */\n progressStart: z.number().min(0).max(1),\n /** Viz progress at clip end [0, 1] */\n progressEnd: z.number().min(0).max(1),\n /** Viz speed multiplier during this clip */\n vizSpeed: z.number().positive(),\n /** Viz speed multiplier during the pause after this clip */\n gapVizSpeed: z.number().positive(),\n /** Phase this line belongs to (optional) */\n phase: z.string().optional(),\n })\n .refine((line) => line.progressStart <= line.progressEnd, {\n message: 'progressStart must be <= progressEnd',\n path: ['progressStart'],\n });\n\nexport const TimingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Total video duration in seconds */\n totalDurationSec: z.number().positive(),\n /** Ordered list of timed lines — fully resolved, all fields required */\n lines: z.array(TimedLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type TimedLine = z.infer<typeof TimedLineSchema>;\nexport type TimingFile = z.infer<typeof TimingFileSchema>;\n","/**\n * Audio manifest schema — the contract between audio generation and Remotion consumption.\n * Lives at: remotion/public/audio/audio-manifest.json\n *\n * @module audio/manifest\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AudioManifest {\n version: 1;\n fps: number;\n totalDurationSec: number;\n\n /** Per-beat voice clips */\n dialog: DialogBeat[];\n /** Background music tracks */\n music: MusicTrack[];\n /** One-shot sound effects */\n sfx: SfxPlacement[];\n /** Text overlays (title cards, labels, data accents) */\n overlays: TextOverlay[];\n}\n\nexport interface DialogBeat {\n id: string;\n file: string;\n speaker: string;\n text: string;\n startSec: number;\n durationSec: number;\n volume?: number;\n style?: 'quote' | 'narrator' | 'text-card';\n}\n\nexport interface MusicTrack {\n id: string;\n file: string;\n startSec: number;\n durationSec: number;\n volume: number;\n fadeInSec?: number;\n fadeOutSec?: number;\n duckTo?: number;\n}\n\nexport interface SfxPlacement {\n id: string;\n file: string;\n startSec: number;\n volume?: number;\n note?: string;\n}\n\nexport interface TextOverlay {\n id: string;\n type: 'title-card' | 'speaker-label' | 'data-accent' | 'chapter';\n text: string;\n startSec: number;\n durationSec: number;\n style?: {\n fontSize?: number;\n color?: string;\n position?: 'center' | 'bottom-left' | 'bottom-right' | 'top';\n typingSpeed?: number | null;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate an AudioManifest for structural correctness.\n *\n * Checks:\n * - Required top-level fields (version, fps, totalDurationSec)\n * - Dialog beats within totalDurationSec, no same-speaker overlap\n * - Music tracks within totalDurationSec, volume 0-1\n * - SFX placements within totalDurationSec\n * - Overlay timing within totalDurationSec\n * - File paths are relative strings (no absolute paths)\n * - Volume values in 0-1 range\n */\nexport function validateAudioManifest(manifest: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (manifest == null || typeof manifest !== 'object') {\n return { valid: false, errors: ['Manifest must be a non-null object'] };\n }\n\n const m = manifest as Record<string, unknown>;\n\n // --- Required top-level fields ---\n if (m.version !== 1) {\n errors.push(`version must be 1, got ${JSON.stringify(m.version)}`);\n }\n if (typeof m.fps !== 'number' || m.fps <= 0) {\n errors.push(`fps must be a positive number, got ${JSON.stringify(m.fps)}`);\n }\n if (typeof m.totalDurationSec !== 'number' || m.totalDurationSec <= 0) {\n errors.push(\n `totalDurationSec must be a positive number, got ${JSON.stringify(m.totalDurationSec)}`,\n );\n }\n\n const totalDur = typeof m.totalDurationSec === 'number' ? m.totalDurationSec : 0;\n\n // --- Arrays must exist ---\n if (!Array.isArray(m.dialog)) {\n errors.push('dialog must be an array');\n }\n if (!Array.isArray(m.music)) {\n errors.push('music must be an array');\n }\n if (!Array.isArray(m.sfx)) {\n errors.push('sfx must be an array');\n }\n if (!Array.isArray(m.overlays)) {\n errors.push('overlays must be an array');\n }\n\n // Bail early if arrays are missing — can't validate contents\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n const dialog = m.dialog as DialogBeat[];\n const music = m.music as MusicTrack[];\n const sfx = m.sfx as SfxPlacement[];\n const overlays = m.overlays as TextOverlay[];\n\n // --- Shared helpers ---\n function checkFilePath(file: unknown, context: string): void {\n if (typeof file !== 'string' || file.length === 0) {\n errors.push(`${context}: file must be a non-empty string`);\n } else if (file.startsWith('/') || file.startsWith('\\\\')) {\n errors.push(`${context}: file must be a relative path, got \"${file}\"`);\n }\n }\n\n function checkVolume(vol: unknown, context: string, required: boolean): void {\n if (vol == null) {\n if (required) errors.push(`${context}: volume is required`);\n return;\n }\n if (typeof vol !== 'number' || vol < 0 || vol > 1) {\n errors.push(`${context}: volume must be 0-1, got ${JSON.stringify(vol)}`);\n }\n }\n\n function checkTimingWithin(startSec: unknown, durationSec: unknown, context: string): void {\n if (typeof startSec !== 'number' || startSec < 0) {\n errors.push(\n `${context}: startSec must be a non-negative number, got ${JSON.stringify(startSec)}`,\n );\n return;\n }\n if (typeof durationSec === 'number') {\n if (durationSec < 0) {\n errors.push(`${context}: durationSec must be non-negative, got ${durationSec}`);\n }\n if (startSec + durationSec > totalDur) {\n errors.push(\n `${context}: startSec (${startSec}) + durationSec (${durationSec}) = ${startSec + durationSec} exceeds totalDurationSec (${totalDur})`,\n );\n }\n }\n }\n\n // --- Dialog beats ---\n const ids = new Set<string>();\n for (let i = 0; i < dialog.length; i++) {\n const b = dialog[i];\n const ctx = `dialog[${i}] (${b.id ?? 'no id'})`;\n\n if (typeof b.id !== 'string' || b.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n } else if (ids.has(b.id)) {\n errors.push(`${ctx}: duplicate id \"${b.id}\"`);\n } else {\n ids.add(b.id);\n }\n\n checkFilePath(b.file, ctx);\n\n if (typeof b.speaker !== 'string' || b.speaker.length === 0) {\n errors.push(`${ctx}: speaker must be a non-empty string`);\n }\n if (typeof b.text !== 'string') {\n errors.push(`${ctx}: text must be a string`);\n }\n if (typeof b.durationSec !== 'number' || b.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(b.durationSec)}`,\n );\n }\n\n checkTimingWithin(b.startSec, b.durationSec, ctx);\n checkVolume(b.volume, ctx, false);\n\n if (\n b.style !== undefined &&\n b.style !== 'quote' &&\n b.style !== 'narrator' &&\n b.style !== 'text-card'\n ) {\n errors.push(`${ctx}: style must be 'quote', 'narrator', or 'text-card', got \"${b.style}\"`);\n }\n }\n\n // --- Same-speaker overlap check ---\n const bySpeaker = new Map<string, DialogBeat[]>();\n for (const b of dialog) {\n if (typeof b.speaker !== 'string') continue;\n const list = bySpeaker.get(b.speaker) ?? [];\n list.push(b);\n bySpeaker.set(b.speaker, list);\n }\n for (const [speaker, beats] of bySpeaker) {\n const sorted = [...beats].sort((a, b) => a.startSec - b.startSec);\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1];\n const curr = sorted[i];\n const prevEnd = prev.startSec + prev.durationSec;\n if (prevEnd > curr.startSec) {\n errors.push(\n `dialog overlap for speaker \"${speaker}\": \"${prev.id}\" ends at ${prevEnd}s but \"${curr.id}\" starts at ${curr.startSec}s`,\n );\n }\n }\n }\n\n // --- Music tracks ---\n for (let i = 0; i < music.length; i++) {\n const t = music[i];\n const ctx = `music[${i}] (${t.id ?? 'no id'})`;\n\n if (typeof t.id !== 'string' || t.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(t.file, ctx);\n checkTimingWithin(t.startSec, t.durationSec, ctx);\n checkVolume(t.volume, ctx, true);\n\n if (t.fadeInSec != null && (typeof t.fadeInSec !== 'number' || t.fadeInSec < 0)) {\n errors.push(`${ctx}: fadeInSec must be a non-negative number`);\n }\n if (t.fadeOutSec != null && (typeof t.fadeOutSec !== 'number' || t.fadeOutSec < 0)) {\n errors.push(`${ctx}: fadeOutSec must be a non-negative number`);\n }\n if (t.duckTo != null) {\n if (typeof t.duckTo !== 'number' || t.duckTo < 0 || t.duckTo > 1) {\n errors.push(`${ctx}: duckTo must be 0-1, got ${JSON.stringify(t.duckTo)}`);\n }\n }\n }\n\n // --- SFX placements ---\n for (let i = 0; i < sfx.length; i++) {\n const s = sfx[i];\n const ctx = `sfx[${i}] (${s.id ?? 'no id'})`;\n\n if (typeof s.id !== 'string' || s.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(s.file, ctx);\n if (typeof s.startSec !== 'number' || s.startSec < 0) {\n errors.push(\n `${ctx}: startSec must be a non-negative number, got ${JSON.stringify(s.startSec)}`,\n );\n }\n if (s.startSec > totalDur) {\n errors.push(`${ctx}: startSec (${s.startSec}) exceeds totalDurationSec (${totalDur})`);\n }\n checkVolume(s.volume, ctx, false);\n }\n\n // --- Text overlays ---\n const validOverlayTypes = new Set(['title-card', 'speaker-label', 'data-accent', 'chapter']);\n const validPositions = new Set(['center', 'bottom-left', 'bottom-right', 'top']);\n for (let i = 0; i < overlays.length; i++) {\n const o = overlays[i];\n const ctx = `overlays[${i}] (${o.id ?? 'no id'})`;\n\n if (typeof o.id !== 'string' || o.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n if (!validOverlayTypes.has(o.type)) {\n errors.push(\n `${ctx}: type must be one of ${[...validOverlayTypes].join(', ')}, got \"${o.type}\"`,\n );\n }\n if (typeof o.text !== 'string' || o.text.length === 0) {\n errors.push(`${ctx}: text must be a non-empty string`);\n }\n if (typeof o.durationSec !== 'number' || o.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(o.durationSec)}`,\n );\n }\n checkTimingWithin(o.startSec, o.durationSec, ctx);\n\n if (o.style != null) {\n if (typeof o.style !== 'object') {\n errors.push(`${ctx}: style must be an object`);\n } else {\n if (\n o.style.fontSize != null &&\n (typeof o.style.fontSize !== 'number' || o.style.fontSize <= 0)\n ) {\n errors.push(`${ctx}: style.fontSize must be a positive number`);\n }\n if (o.style.color != null && typeof o.style.color !== 'string') {\n errors.push(`${ctx}: style.color must be a string`);\n }\n if (o.style.position != null && !validPositions.has(o.style.position)) {\n errors.push(\n `${ctx}: style.position must be one of ${[...validPositions].join(', ')}, got \"${o.style.position}\"`,\n );\n }\n if (\n o.style.typingSpeed !== undefined &&\n o.style.typingSpeed !== null &&\n (typeof o.style.typingSpeed !== 'number' || o.style.typingSpeed <= 0)\n ) {\n errors.push(`${ctx}: style.typingSpeed must be a positive number or null`);\n }\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute total duration from manifest content.\n * Returns max(endTime) across all tracks + 2s padding.\n * Useful for agents building the manifest before totalDurationSec is known.\n */\nexport function computeTotalDuration(\n manifest: Pick<AudioManifest, 'dialog' | 'music' | 'sfx' | 'overlays'>,\n): number {\n let maxEnd = 0;\n\n for (const b of manifest.dialog) {\n maxEnd = Math.max(maxEnd, b.startSec + b.durationSec);\n }\n for (const t of manifest.music) {\n maxEnd = Math.max(maxEnd, t.startSec + t.durationSec);\n }\n for (const s of manifest.sfx) {\n // SFX don't have durationSec — use startSec only\n maxEnd = Math.max(maxEnd, s.startSec);\n }\n for (const o of manifest.overlays) {\n maxEnd = Math.max(maxEnd, o.startSec + o.durationSec);\n }\n\n return maxEnd + 2;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/transform/transform-raw.ts","../src/transform/transform-curation.ts","../src/types/script.ts","../src/types/pacing.ts","../src/types/timing.ts","../src/audio/manifest.ts"],"names":["z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Transform source data → RawData (Contract A).\n *\n * Pure function. Deterministic. No side effects.\n * Maps existing JSON files to the generic RawData contract.\n */\n\nimport type {\n RawAgent,\n RawArtifact,\n RawCommit,\n RawData,\n RawMessage,\n RawPR,\n} from '../types/raw-data.js';\nimport type {\n SourceArtifactData,\n SourceBeamEvent,\n SourceCommit,\n SourceMessageEvent,\n SourcePR,\n SourcePRAgentMap,\n SourceRetroPageData,\n SourceTimelineEvents,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Infer a RawAgent role from a freeform role string (e.g. from teamAssembly).\n *\n * Checks for known keywords in the string (case-insensitive).\n * Order matters — more specific matches first (e.g. \"eng-lead\" matches \"lead\").\n * Falls back to 'builder' as the safest default (most common role).\n */\nexport function inferRole(roleString: string): RawAgent['role'] {\n const s = roleString.toLowerCase();\n if (s.includes('human') || s === 'user') return 'human';\n if (s.includes('lead')) return 'lead';\n if (s.includes('pm')) return 'pm';\n if (s.includes('tester') || s.includes('qa')) return 'tester';\n if (s.includes('reviewer') || s.includes('review')) return 'reviewer';\n if (s.includes('auditor') || s.includes('audit')) return 'auditor';\n if (s.includes('challenger') || s.includes('challenge')) return 'challenger';\n if (s.includes('scout')) return 'scout';\n if (s.includes('ideation')) return 'ideation';\n if (s.includes('research')) return 'researcher';\n if (s.includes('builder') || s.includes('build')) return 'builder';\n return 'builder'; // safe default — most common role\n}\n\n/**\n * Transform all source data into RawData.\n * This is the main entry point for the extraction layer.\n */\nexport function transformToRawData(sources: TransformSources): RawData {\n // First agent from teamAssembly is the default for unattributed items\n const defaultAgent = sources.retroPageData.teamAssembly[0]?.agent.replace('@', '') ?? 'unknown';\n\n return {\n project: {\n name: sources.retroPageData.meta.title,\n description: sources.retroPageData.meta.subtitle,\n },\n agents: transformAgents(\n sources.retroPageData,\n sources.chatActivity.agentTotals,\n sources.timelineEvents,\n ),\n commits: transformCommits(sources.commits, sources.prAgentMap, defaultAgent),\n prs: transformPRs(sources.prs, sources.prAgentMap),\n messages: transformMessages(sources.timelineEvents),\n artifacts: sources.artifactData\n ? transformArtifacts(\n sources.artifactData,\n sources.retroPageData,\n sources.prs,\n sources.prAgentMap,\n )\n : [],\n };\n}\n\n/**\n * Build a map of agent → earliest message timestamp from timeline events.\n * Only counts messages where the agent is the sender (not just mentioned).\n */\nfunction buildFirstMessageTimeMap(timelineEvents?: SourceTimelineEvents): Map<string, number> {\n const map = new Map<string, number>();\n if (!timelineEvents) return map;\n\n for (const evt of timelineEvents.events) {\n if (evt.type !== 'message' && evt.type !== 'beam') continue;\n const sender = (evt as SourceMessageEvent | SourceBeamEvent).from;\n const ts = new Date(evt.t).getTime();\n const existing = map.get(sender);\n if (existing === undefined || ts < existing) {\n map.set(sender, ts);\n }\n }\n\n return map;\n}\n\n/**\n * Build RawAgent[] from team assembly data + chat activity.\n *\n * joinedAt resolution priority:\n * 1. First message timestamp from timeline events (most accurate)\n * 2. teamAssembly join time (curated/scaffold fallback)\n * 3. Project start date (last resort)\n *\n * Role resolution priority:\n * 1. Explicit `agentRoles` override (if provided)\n * 2. Inferred from teamAssembly `role` field (e.g. \"eng-lead\" → \"lead\")\n * 3. Default: 'builder' (most common role, safe fallback)\n *\n * Never throws on unknown agents — always infers or defaults.\n */\nexport function transformAgents(\n retroData: SourceRetroPageData,\n agentTotals: Record<string, number>,\n timelineEvents?: SourceTimelineEvents,\n agentRoles?: Record<string, string>,\n): RawAgent[] {\n const agents: RawAgent[] = [];\n const seen = new Set<string>();\n\n // Build first-message-time lookup from timeline events\n const firstMessageTime = buildFirstMessageTimeMap(timelineEvents);\n\n // Build a lookup from teamAssembly role fields for agents not in override\n const assemblyRoles = new Map<string, string>();\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n assemblyRoles.set(id, entry.role);\n }\n\n /** Resolve role for an agent: override → teamAssembly inference → default */\n function resolveRole(id: string): RawAgent['role'] {\n // 1. Explicit override\n if (agentRoles?.[id]) {\n return inferRole(agentRoles[id]);\n }\n // 2. Infer from teamAssembly role field\n const assemblyRole = assemblyRoles.get(id);\n if (assemblyRole) {\n return inferRole(assemblyRole);\n }\n // 3. Default\n return 'builder';\n }\n\n /** Resolve joinedAt: earliest of (first message, teamAssembly time), or startDate */\n function resolveJoinedAt(id: string, assemblyTime?: number): number {\n const msgTime = firstMessageTime.get(id);\n // Use earliest available timestamp — agent was present from whichever came first\n if (msgTime !== undefined && assemblyTime !== undefined) {\n return Math.min(msgTime, assemblyTime);\n }\n if (msgTime !== undefined) return msgTime;\n if (assemblyTime !== undefined) return assemblyTime;\n // Last resort: project start date\n return new Date(retroData.meta.startDate).getTime();\n }\n\n // Primary source: team assembly (has join times)\n for (const entry of retroData.teamAssembly) {\n const id = entry.agent.replace('@', '');\n if (seen.has(id)) continue;\n seen.add(id);\n\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id, new Date(entry.time).getTime()),\n });\n }\n\n // Catch any agents in chat activity not in team assembly\n for (const id of Object.keys(agentTotals)) {\n if (seen.has(id)) continue;\n agents.push({\n id,\n role: resolveRole(id),\n joinedAt: resolveJoinedAt(id),\n });\n seen.add(id);\n }\n\n return agents;\n}\n\n/**\n * Transform git commits → RawCommit[].\n * Cross-references pr-agent-map for attribution.\n *\n * @param defaultAgent - Fallback agent for commits with no PR reference\n * (typically the first agent from teamAssembly/roster)\n */\nexport function transformCommits(\n commits: SourceCommit[],\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): RawCommit[] {\n return commits.map((c) => {\n const agent = resolveCommitAgent(c, prAgentMap, defaultAgent);\n\n return {\n sha: c.hash,\n timestamp: new Date(c.date).getTime(),\n agent,\n message: c.subject,\n filesChanged: c.files.length,\n insertions: c.totalInsertions,\n deletions: c.totalDeletions,\n prNumber: c.prNumber ?? undefined,\n };\n });\n}\n\n/**\n * Resolve which agent authored a commit.\n * Strategy chain:\n * 1. prNumber field → pr-agent-map lookup\n * 2. \"Merge pull request #N\" in subject → pr-agent-map lookup\n * 3. \"(#N)\" suffix in subject → pr-agent-map lookup\n * 4. Fallback to defaultAgent (first agent from roster/teamAssembly)\n */\nexport function resolveCommitAgent(\n commit: SourceCommit,\n prAgentMap: SourcePRAgentMap,\n defaultAgent = 'unknown',\n): string {\n // Strategy 1: direct prNumber field\n if (commit.prNumber != null) {\n const agent = prAgentMap[String(commit.prNumber)];\n if (agent) return agent;\n }\n\n // Strategy 2: \"Merge pull request #N\" pattern\n const mergeMatch = commit.subject.match(/^Merge pull request #(\\d+)/);\n if (mergeMatch) {\n const agent = prAgentMap[mergeMatch[1]];\n if (agent) return agent;\n }\n\n // Strategy 3: \"(#N)\" suffix pattern\n const suffixMatch = commit.subject.match(/\\(#(\\d+)\\)\\s*$/);\n if (suffixMatch) {\n const agent = prAgentMap[suffixMatch[1]];\n if (agent) return agent;\n }\n\n // Fallback: first agent from roster (caller provides)\n return defaultAgent;\n}\n\n/**\n * Transform PR details → RawPR[].\n * Cross-references pr-agent-map for attribution.\n */\nexport function transformPRs(prs: SourcePR[], prAgentMap: SourcePRAgentMap): RawPR[] {\n return prs.map((pr) => {\n const agent = prAgentMap[String(pr.number)] ?? 'unknown';\n\n return {\n number: pr.number,\n title: pr.title,\n agent,\n createdAt: new Date(pr.createdAt).getTime(),\n mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : null,\n additions: pr.additions,\n deletions: pr.deletions,\n branch: pr.headRefName,\n };\n });\n}\n\n/**\n * Infer artifact type from slug or file path.\n *\n * Handles both platforms:\n * - Redux: file paths with extensions (\"/specs/auth.md\", \"plan/task-X1Y2\")\n * - Cast: artifact slugs (\"spec-auth\", \"screenshot-login\", \"qa-review\")\n *\n * Redux patterns are checked first (more specific), cast patterns as fallback.\n */\nexport function inferArtifactType(slug: string): RawArtifact['type'] {\n // --- Redux: plan item prefixes ---\n if (slug.startsWith('plan/task-')) return 'task';\n if (slug.startsWith('plan/spec-')) return 'doc';\n\n // --- Extension-based (works for both platforms, but primarily redux file paths) ---\n const ext = slug.split('.').pop()?.toLowerCase();\n if (ext && ['ts', 'tsx', 'js', 'jsx', 'py', 'rs', 'go', 'sh'].includes(ext)) return 'code';\n if (ext && ['png', 'jpg', 'jpeg', 'svg', 'gif', 'webp', 'ico'].includes(ext)) return 'asset';\n if (ext && ['md', 'txt', 'json', 'yaml', 'yml', 'toml'].includes(ext)) return 'doc';\n\n // --- Redux: path-based patterns ---\n if (slug.includes('/specs/') || slug.includes('/spec/')) return 'doc';\n if (slug.includes('/assets/') || slug.includes('/images/')) return 'asset';\n\n // --- Cast: existing slug patterns (backward compat) ---\n if (slug.includes('.app.')) return 'code';\n if (slug.includes('screenshot') || slug.includes('qa-')) return 'asset';\n if (slug.includes('decision')) return 'decision';\n if (slug.includes('task') || slug.includes('phase-')) return 'task';\n if (slug.startsWith('spec-') || slug.startsWith('spec')) return 'doc';\n if (slug.includes('concept')) return 'doc';\n\n return 'doc';\n}\n\n/**\n * Resolve artifact agent from source data.\n *\n * Priority:\n * 1. Explicit `createdBy` from the artifact record (Miriad API provides this)\n * 2. PR number in slug → pr-agent-map lookup\n * 3. Configurable default (first agent from roster, typically the lead)\n */\nexport function resolveArtifactAgent(\n slug: string,\n prAgentMap: SourcePRAgentMap,\n createdBy: string | undefined,\n defaultAgent: string,\n): string {\n // 1. Explicit creator from source data\n if (createdBy) return createdBy;\n\n // 2. PR reference in slug → agent map\n const prMatch = slug.match(/#?(\\d+)/);\n if (prMatch) {\n const agent = prAgentMap[prMatch[1]];\n if (agent) return agent;\n }\n\n // 3. Default (first agent from roster)\n return defaultAgent;\n}\n\n/** Category name → artifact type */\nconst CATEGORY_TYPE_MAP: Record<string, RawArtifact['type']> = {\n qaScreenshots: 'asset',\n transitionSpecs: 'doc',\n transitionConcepts: 'doc',\n scenes: 'doc',\n vizConcepts: 'code',\n teamPrinciples: 'doc',\n retroData: 'doc',\n decisions: 'decision',\n};\n\n/**\n * Distribute N artifacts within time boundaries, clustered around\n * PR timestamps when available for realistic density.\n */\nexport function distributeTimestamps(\n count: number,\n bounds: { start: number; end: number },\n prTimestamps: number[],\n): number[] {\n const phasePRTimes = prTimestamps.filter((t) => t >= bounds.start && t <= bounds.end);\n const timestamps: number[] = [];\n\n for (let i = 0; i < count; i++) {\n let timestamp: number;\n if (phasePRTimes.length > 0) {\n const prIdx = i % phasePRTimes.length;\n timestamp = phasePRTimes[prIdx] + i * 60000;\n } else {\n const fraction = count > 1 ? i / (count - 1) : 0.5;\n timestamp = bounds.start + fraction * (bounds.end - bounds.start);\n }\n timestamps.push(Math.round(Math.max(bounds.start, Math.min(bounds.end, timestamp))));\n }\n\n return timestamps;\n}\n\n/**\n * Build a type distribution from category data.\n *\n * Each category maps to a type. We build a weighted list so bulk\n * artifacts can be assigned types proportional to category counts.\n * Returns entries sorted by count descending for deterministic assignment.\n *\n * Agent assignment is NOT done here — it's handled by the caller using\n * round-robin over the known agent list (from teamAssembly).\n */\nexport function buildCategoryDistribution(\n categories: SourceArtifactData['categories'],\n): Array<{ type: RawArtifact['type']; weight: number }> {\n const entries: Array<{ type: RawArtifact['type']; count: number }> = [];\n let total = 0;\n\n for (const [categoryName, categoryData] of Object.entries(categories)) {\n if (categoryData.count === 0) continue;\n entries.push({\n type: CATEGORY_TYPE_MAP[categoryName] ?? 'doc',\n count: categoryData.count,\n });\n total += categoryData.count;\n }\n\n if (total === 0) return [{ type: 'doc', weight: 1 }];\n\n return entries\n .sort((a, b) => b.count - a.count)\n .map((e) => ({ type: e.type, weight: e.count / total }));\n}\n\n/**\n * Build a slug → createdBy lookup from SourceArtifactData category items.\n * Items can be plain strings (no creator info) or objects with optional createdBy.\n */\nfunction buildCreatedByLookup(categories: SourceArtifactData['categories']): Map<string, string> {\n const lookup = new Map<string, string>();\n for (const categoryData of Object.values(categories)) {\n for (const item of categoryData.items ?? []) {\n if (typeof item === 'object' && item.createdBy) {\n lookup.set(item.slug, item.createdBy);\n }\n }\n }\n return lookup;\n}\n\n/**\n * Transform artifact-data.json → RawArtifact[].\n *\n * Uses phase `count` fields for correct per-phase density. Each phase\n * specifies how many artifacts were created during that time window:\n * Phase 1: 5, Phase 2: 45, Phase 3: 80, Phase 4: 120, Phase 5: 60 = 310\n *\n * Within each phase:\n * 1. Curated slugs get their own entries with createdBy from source data\n * 2. Remaining count filled with generated artifacts using category\n * type proportions and round-robin agent assignment\n * 3. All timestamps distributed within phase boundaries, clustered\n * around PR activity\n */\nexport function transformArtifacts(\n artifactData: SourceArtifactData,\n retroData: SourceRetroPageData,\n prs: SourcePR[],\n prAgentMap: SourcePRAgentMap,\n): RawArtifact[] {\n const artifacts: RawArtifact[] = [];\n\n // Build agent list from teamAssembly for round-robin and default\n const agentIds = retroData.teamAssembly.map((e) => e.agent.replace('@', ''));\n const defaultAgent = agentIds[0] ?? 'unknown';\n\n const phaseBoundaries = retroData.phases.map((p) => ({\n start: new Date(p.start).getTime(),\n end: new Date(p.end).getTime(),\n }));\n\n const prTimestamps = prs.map((pr) => new Date(pr.createdAt).getTime()).sort((a, b) => a - b);\n const distribution = buildCategoryDistribution(artifactData.categories);\n const createdByLookup = buildCreatedByLookup(artifactData.categories);\n\n let phaseIndex = 0;\n let globalBulkIndex = 0;\n\n for (const [_phaseName, phaseData] of Object.entries(artifactData.phases)) {\n if (phaseIndex >= phaseBoundaries.length) break;\n const bounds = phaseBoundaries[phaseIndex];\n phaseIndex++;\n\n const totalCount = phaseData.count;\n const slugs = phaseData.artifacts;\n const bulkCount = Math.max(0, totalCount - slugs.length);\n\n // All artifacts in this phase share one timestamp distribution\n const timestamps = distributeTimestamps(totalCount, bounds, prTimestamps);\n\n // ── Curated slugs first ──────────────────────────────────────────────\n let tsIdx = 0;\n for (const slug of slugs) {\n artifacts.push({\n slug,\n type: inferArtifactType(slug),\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent: resolveArtifactAgent(slug, prAgentMap, createdByLookup.get(slug), defaultAgent),\n });\n tsIdx++;\n }\n\n // ── Bulk artifacts fill remaining count ───────────────────────────────\n // Assign type by walking through the weighted distribution.\n // Assign agent by round-robin over the known agent list.\n let distIdx = 0;\n let distBudget = Math.round(distribution[0].weight * bulkCount);\n\n for (let i = 0; i < bulkCount; i++) {\n // Advance to next distribution bucket when current is exhausted\n while (distBudget <= 0 && distIdx < distribution.length - 1) {\n distIdx++;\n distBudget = Math.round(distribution[distIdx].weight * bulkCount);\n }\n distBudget--;\n\n const entry = distribution[distIdx];\n // Round-robin agent assignment across the roster\n const agent =\n agentIds.length > 0 ? agentIds[globalBulkIndex % agentIds.length] : defaultAgent;\n artifacts.push({\n slug: `phase${phaseIndex}-${entry.type}-${String(globalBulkIndex + 1).padStart(3, '0')}`,\n type: entry.type,\n createdAt: timestamps[tsIdx],\n updatedAt: timestamps[tsIdx],\n agent,\n });\n tsIdx++;\n globalBulkIndex++;\n }\n }\n\n artifacts.sort((a, b) => a.createdAt - b.createdAt);\n\n return artifacts;\n}\n\n/**\n * Transform curated timeline events into chat pills for the viewer.\n *\n * Chat pills come ONLY from timeline-events.json (curated).\n * Raw messages (messages-viz.json) are NEVER a source for chat pills —\n * they exist only for the agent to read during curation and for the\n * density table's \"Msgs\" column.\n *\n * Single source of truth: the curated file.\n */\nexport function transformMessages(timelineEvents: SourceTimelineEvents): RawMessage[] {\n const messageEvents = timelineEvents.events.filter(\n (e): e is SourceMessageEvent | SourceBeamEvent => e.type === 'message' || e.type === 'beam',\n );\n\n return messageEvents.map((evt, i) => ({\n id: `msg-${String(i).padStart(4, '0')}`,\n timestamp: new Date(evt.t).getTime(),\n sender: evt.from,\n mentions: [evt.to],\n }));\n}\n","/**\n * Transform source data → CurationData (editorial content).\n *\n * Pure function. Deterministic. No side effects.\n * Maps curated board artifacts to the CurationData contract.\n */\n\nimport type {\n CurationData,\n CurationMilestone,\n CurationNarrationEntry,\n CurationPhase,\n CurationQuote,\n CurationTrustKeyframe,\n} from '../types/raw-data.js';\nimport type {\n SourceRetroPageData,\n SourceRetroPageQuotes,\n TransformSources,\n} from './source-types.js';\n\n/**\n * Transform curated source data into CurationData.\n * This is the main entry point for the curation layer.\n */\nexport function transformToCurationData(sources: TransformSources): CurationData {\n const narration = transformNarration(sources.retroPageData);\n const meta = sources.retroPageData.meta;\n\n // Thread curated timeline bounds from meta.startDate/endDate\n const curatedStartMs = meta?.startDate ? new Date(meta.startDate).getTime() : undefined;\n const curatedEndMs = meta?.endDate ? new Date(meta.endDate).getTime() : undefined;\n\n return {\n phases: transformPhases(sources.retroPageData),\n quotes: transformQuotes(sources.retroPageData, sources.retroPageQuotes),\n milestones: transformMilestones(sources.retroPageData),\n trustKeyframes: transformTrustKeyframes(sources.retroPageData),\n ...(narration.length > 0 ? { editorialNarration: narration } : {}),\n ...(curatedStartMs && !Number.isNaN(curatedStartMs) ? { curatedStartMs } : {}),\n ...(curatedEndMs && !Number.isNaN(curatedEndMs) ? { curatedEndMs } : {}),\n };\n}\n\n/**\n * Transform phase definitions from retro-page-data.\n * Phases have hand-curated boundaries, names, and descriptions.\n */\nexport function transformPhases(retroData: SourceRetroPageData): CurationPhase[] {\n return retroData.phases.map((p) => ({\n id: p.id,\n name: p.name,\n startTime: new Date(p.start).getTime(),\n endTime: new Date(p.end).getTime(),\n }));\n}\n\n/**\n * Transform milestones from retro-page-data.\n * Each milestone is cross-referenced to its containing phase.\n */\nexport function transformMilestones(retroData: SourceRetroPageData): CurationMilestone[] {\n const phases = retroData.phases;\n\n return retroData.milestones.map((m) => {\n const milestoneTime = new Date(m.time).getTime();\n const phase = findPhaseForTimestamp(milestoneTime, phases);\n\n return {\n label: m.label,\n timestamp: milestoneTime,\n phase: phase?.id ?? 'unknown',\n };\n });\n}\n\n/**\n * Map mood category to mood string for quotes from retroPageData.\n */\nconst CATEGORY_MOOD: Record<string, string> = {\n theGood: 'good',\n theBad: 'bad',\n theUgly: 'angry',\n theFunny: 'good',\n};\n\n/**\n * Map mood category to mood string for quotes from retroPageQuotes.\n */\nconst ADDITION_MOOD: Record<string, string> = {\n good: 'good',\n bad: 'bad',\n ugly: 'angry',\n};\n\n/**\n * Transform quotes from both curated sources.\n * Merges retro-page-data quotes (theGood/theBad/theUgly/theFunny) with\n * retro-page-quotes additions (good/bad/ugly). Parses informal timestamps,\n * strips @ prefix from speakers, and cross-references to phases.\n * Sorted by timestamp.\n */\nexport function transformQuotes(\n retroData: SourceRetroPageData,\n retroQuotes: SourceRetroPageQuotes,\n): CurationQuote[] {\n const phases = retroData.phases;\n const quotes: CurationQuote[] = [];\n\n // Derive reference year from first phase start date (for informal timestamp parsing)\n const firstPhaseStart = phases[0]?.start;\n const referenceYear = firstPhaseStart\n ? new Date(firstPhaseStart).getUTCFullYear()\n : new Date().getUTCFullYear();\n\n // Source 1: retroPageData.quotes (theGood, theBad, theUgly, theFunny)\n for (const [category, entries] of Object.entries(retroData.quotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = CATEGORY_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.time, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Source 2: retroPageQuotes (good, bad, ugly)\n for (const [category, entries] of Object.entries(retroQuotes)) {\n if (!Array.isArray(entries)) continue; // skip _comment and other non-quote fields\n const mood = ADDITION_MOOD[category] ?? 'good';\n for (const entry of entries) {\n const timestamp = parseInformalTimestamp(entry.timestamp, referenceYear);\n if (timestamp == null) continue;\n const phase = findPhaseForTimestamp(timestamp, phases);\n quotes.push({\n text: entry.text,\n speaker: entry.author.replace(/^@/, ''),\n timestamp,\n phase: phase?.id ?? 'unknown',\n mood,\n });\n }\n }\n\n // Sort chronologically\n quotes.sort((a, b) => a.timestamp - b.timestamp);\n return quotes;\n}\n\n/**\n * Transform trust arc keyframes from retro-page-data.\n * Source levels are 0-100 integers; we normalize to 0-1.\n * Sorted by timestamp for interpolation.\n */\nexport function transformTrustKeyframes(retroData: SourceRetroPageData): CurationTrustKeyframe[] {\n if (!retroData.trustArc || retroData.trustArc.length === 0) return [];\n\n return retroData.trustArc\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n level: entry.level / 100, // normalize 0-100 → 0-1\n label: entry.label,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/** Month abbreviation → 0-based index */\nconst MONTH_ABBREVS: Record<string, number> = {\n jan: 0,\n feb: 1,\n mar: 2,\n apr: 3,\n may: 4,\n jun: 5,\n jul: 6,\n aug: 7,\n sep: 8,\n oct: 9,\n nov: 10,\n dec: 11,\n};\n\n/**\n * Transform editorial narration entries from retro-page-data.\n * Each entry has an ISO timestamp, phase title, color, text, and type.\n * Returns empty array if no narration is present in the source data.\n */\nexport function transformNarration(retroData: SourceRetroPageData): CurationNarrationEntry[] {\n if (!retroData.editorialNarration || retroData.editorialNarration.length === 0) return [];\n\n return retroData.editorialNarration\n .map((entry) => ({\n timestamp: new Date(entry.time).getTime(),\n phaseTitle: entry.phaseTitle,\n phaseColor: entry.phaseColor,\n text: entry.text,\n type: entry.type,\n }))\n .sort((a, b) => a.timestamp - b.timestamp);\n}\n\n/**\n * Parse informal timestamp strings like \"Feb 10 21:18\", \"Dec 31 (early)\", \"Jan 2 ~23:00\".\n * Accepts any 3-letter month abbreviation.\n *\n * @param timeStr - Informal timestamp (e.g., \"Feb 10 21:18\", \"Dec 31\")\n * @param referenceYear - Year to use (e.g., 2025). Required — no hardcoded default.\n * For projects spanning Dec→Jan, callers should handle year rollover.\n * @returns Unix ms or null if unparseable.\n */\nexport function parseInformalTimestamp(\n timeStr: string | undefined | null,\n referenceYear: number,\n): number | null {\n if (!timeStr) return null;\n\n // Try ISO 8601 first (scaffold generates ISO timestamps)\n const isoDate = new Date(timeStr);\n if (!Number.isNaN(isoDate.getTime()) && timeStr.includes('-')) {\n return isoDate.getTime();\n }\n\n // Strip tildes and parenthetical notes\n const cleaned = timeStr\n .replace(/~/g, '')\n .replace(/\\(.*?\\)/g, '')\n .trim();\n\n // Match \"Mon DD HH:MM\" or \"Mon DD\" (3-letter month abbreviation)\n const match = cleaned.match(/([A-Za-z]{3})\\s+(\\d{1,2})(?:\\s+(\\d{1,2}):(\\d{2}))?/);\n if (!match) return null;\n\n const monthIdx = MONTH_ABBREVS[match[1].toLowerCase()];\n if (monthIdx === undefined) return null;\n\n const day = Number.parseInt(match[2], 10);\n const hour = match[3] ? Number.parseInt(match[3], 10) : 12; // default to noon if no time\n const minute = match[4] ? Number.parseInt(match[4], 10) : 0;\n\n const date = new Date(Date.UTC(referenceYear, monthIdx, day, hour, minute, 0));\n return date.getTime();\n}\n\n/**\n * Find which phase a timestamp falls within.\n * Returns the phase or undefined if outside all phases.\n */\nfunction findPhaseForTimestamp(\n timestamp: number,\n phases: SourceRetroPageData['phases'],\n): SourceRetroPageData['phases'][number] | undefined {\n return phases.find((p) => {\n const start = new Date(p.start).getTime();\n const end = new Date(p.end).getTime();\n return timestamp >= start && timestamp <= end;\n });\n}\n","/**\n * ScriptFile — the authoring contract for Step 2 (Script Writing).\n *\n * WHY: The script is the creative foundation. An agent writes this file\n * to define the narrative structure: who speaks, what they say, and in\n * what style. Every downstream file (pacing, timing) derives from this.\n *\n * The agent creates this from scratch in Step 2, guided by extracted data\n * (event density, agent activity, phases). The human reviews and approves.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const ScriptLineSchema = z.object({\n /** Unique identifier for this line (e.g., 'narrator-01', 'lead-03') */\n id: z.string().min(1),\n /** Who speaks this line (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Optional phase this line belongs to (for grouping in the viz) */\n phaseId: z.string().optional(),\n});\n\nexport const ScriptFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Ordered list of script lines */\n lines: z.array(ScriptLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type ScriptLine = z.infer<typeof ScriptLineSchema>;\nexport type ScriptFile = z.infer<typeof ScriptFileSchema>;\n","/**\n * PacingFile — the agent-facing timing contract for Step 4 (Viz Timing).\n *\n * WHY: The pacing file is what the agent edits to control how fast the viz\n * moves during each narration line. scaffold-pacing generates it from\n * script.json + audio clip durations. The agent then annotates 4 optional\n * fields per line: pauseAfter, vizSpeed, gapVizSpeed, note.\n *\n * Design: Approach A (Annotated Script) — mirrors the script with timing\n * annotations. Text + clip durations inline. Defaults handle 80% of lines.\n * No cascading edits (unlike start-time approaches).\n *\n * vizSpeed definition: multiplier on project-time-per-second.\n * 2.0 = viz moves 2x faster = LESS screen time for that period.\n * 0.5 = viz moves 2x slower = MORE screen time for that period.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const PacingLineSchema = z.object({\n /** Line ID — must match script.json line ID */\n id: z.string().min(1),\n /** Text from script (read-only, for context while editing pacing) */\n text: z.string().min(1),\n /** Audio clip duration in seconds (measured from file, read-only) */\n clipDuration: z.number().positive(),\n /** Silence after this line in seconds (overrides defaultPauseSec) */\n pauseAfter: z.number().nonnegative().optional(),\n /** Viz speed multiplier DURING this clip's audio. >1 = faster, <1 = slower */\n vizSpeed: z.number().positive().optional(),\n /** Viz speed multiplier DURING the pause after this clip (defaults to defaultVizSpeed) */\n gapVizSpeed: z.number().positive().optional(),\n /** Agent's reasoning for pacing choices (human reads during review) */\n note: z.string().optional(),\n});\n\nexport const PacingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Seconds of viz playback before first narration line */\n leadInSec: z.number().nonnegative().optional(),\n /** Seconds of viz playback after last narration line */\n tailOutSec: z.number().nonnegative().optional(),\n /** Default pause between lines in seconds (used when pauseAfter not set) */\n defaultPauseSec: z.number().nonnegative(),\n /** Default viz speed multiplier (used when vizSpeed/gapVizSpeed not set) */\n defaultVizSpeed: z.number().positive(),\n /** Ordered list of pacing lines — must match script.json order */\n lines: z.array(PacingLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type PacingLine = z.infer<typeof PacingLineSchema>;\nexport type PacingFile = z.infer<typeof PacingFileSchema>;\n","/**\n * TimingFile — the engine-facing contract produced by generateTiming().\n *\n * WHY: This is the fully-resolved timing data that the transform layer reads\n * to produce narration entries with precise progress mapping. All fields are\n * required — no defaults, no optionals (except phase). generateTiming()\n * resolves all defaults from PacingFile and computes progress values.\n *\n * The transform layer validates this on read (belt-and-suspenders with\n * generateTiming's validation on write). If this file is corrupt, the\n * pipeline fails fast with a clear error.\n */\n\nimport { z } from 'zod';\n\n// --- Zod schemas (source of truth) ---\n\nexport const TimedLineSchema = z\n .object({\n /** Line ID — matches script.json and pacing.json */\n id: z.string().min(1),\n /** Speaker identifier (e.g., 'narrator', 'lead', 'snorre') */\n speaker: z.string().min(1),\n /** The spoken text */\n text: z.string().min(1),\n /** Rendering style: narrator voice (cursive) or agent quote (normal) */\n style: z.enum(['narrator', 'quote']),\n /** Wall-clock start time in seconds from video start */\n startSec: z.number().nonnegative(),\n /** Audio clip duration in seconds */\n durationSec: z.number().positive(),\n /** Pause after this line in seconds (resolved from defaults) */\n pauseAfterSec: z.number().nonnegative(),\n /** Audio file path relative to audio directory (e.g., 'narrator-01.mp3') */\n audioFile: z.string().min(1),\n /** Viz progress at clip start [0, 1] */\n progressStart: z.number().min(0).max(1),\n /** Viz progress at clip end [0, 1] */\n progressEnd: z.number().min(0).max(1),\n /** Viz speed multiplier during this clip */\n vizSpeed: z.number().positive(),\n /** Viz speed multiplier during the pause after this clip */\n gapVizSpeed: z.number().positive(),\n /** Phase this line belongs to (optional) */\n phase: z.string().optional(),\n })\n .refine((line) => line.progressStart <= line.progressEnd, {\n message: 'progressStart must be <= progressEnd',\n path: ['progressStart'],\n });\n\nexport const TimingFileSchema = z\n .object({\n /** Schema version — always 1 for now */\n version: z.literal(1),\n /** Total video duration in seconds */\n totalDurationSec: z.number().positive(),\n /** Ordered list of timed lines — fully resolved, all fields required */\n lines: z.array(TimedLineSchema).min(1),\n })\n .superRefine((data, ctx) => {\n // Enforce unique line IDs\n const ids = new Set<string>();\n for (let i = 0; i < data.lines.length; i++) {\n const id = data.lines[i].id;\n if (ids.has(id)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Duplicate line ID: \"${id}\" (line index ${i})`,\n path: ['lines', i, 'id'],\n });\n }\n ids.add(id);\n }\n });\n\n// --- TypeScript types (inferred from schemas) ---\n\nexport type TimedLine = z.infer<typeof TimedLineSchema>;\nexport type TimingFile = z.infer<typeof TimingFileSchema>;\n","/**\n * Audio manifest schema — the contract between audio generation and Remotion consumption.\n * Lives at: remotion/public/audio/audio-manifest.json\n *\n * @module audio/manifest\n */\n\n// ---------------------------------------------------------------------------\n// Types\n// ---------------------------------------------------------------------------\n\nexport interface AudioManifest {\n version: 1;\n fps: number;\n totalDurationSec: number;\n\n /** Per-beat voice clips */\n dialog: DialogBeat[];\n /** Background music tracks */\n music: MusicTrack[];\n /** One-shot sound effects */\n sfx: SfxPlacement[];\n /** Text overlays (title cards, labels, data accents) */\n overlays: TextOverlay[];\n}\n\nexport interface DialogBeat {\n id: string;\n file: string;\n speaker: string;\n text: string;\n startSec: number;\n durationSec: number;\n volume?: number;\n style?: 'quote' | 'narrator' | 'text-card';\n}\n\nexport interface MusicTrack {\n id: string;\n file: string;\n startSec: number;\n durationSec: number;\n volume: number;\n fadeInSec?: number;\n fadeOutSec?: number;\n duckTo?: number;\n}\n\nexport interface SfxPlacement {\n id: string;\n file: string;\n startSec: number;\n volume?: number;\n note?: string;\n}\n\nexport interface TextOverlay {\n id: string;\n type: 'title-card' | 'speaker-label' | 'data-accent' | 'chapter';\n text: string;\n startSec: number;\n durationSec: number;\n style?: {\n fontSize?: number;\n color?: string;\n position?: 'center' | 'bottom-left' | 'bottom-right' | 'top';\n typingSpeed?: number | null;\n };\n}\n\n// ---------------------------------------------------------------------------\n// Validation\n// ---------------------------------------------------------------------------\n\nexport interface ValidationResult {\n valid: boolean;\n errors: string[];\n}\n\n/**\n * Validate an AudioManifest for structural correctness.\n *\n * Checks:\n * - Required top-level fields (version, fps, totalDurationSec)\n * - Dialog beats within totalDurationSec, no same-speaker overlap\n * - Music tracks within totalDurationSec, volume 0-1\n * - SFX placements within totalDurationSec\n * - Overlay timing within totalDurationSec\n * - File paths are relative strings (no absolute paths)\n * - Volume values in 0-1 range\n */\nexport function validateAudioManifest(manifest: unknown): ValidationResult {\n const errors: string[] = [];\n\n if (manifest == null || typeof manifest !== 'object') {\n return { valid: false, errors: ['Manifest must be a non-null object'] };\n }\n\n const m = manifest as Record<string, unknown>;\n\n // --- Required top-level fields ---\n if (m.version !== 1) {\n errors.push(`version must be 1, got ${JSON.stringify(m.version)}`);\n }\n if (typeof m.fps !== 'number' || m.fps <= 0) {\n errors.push(`fps must be a positive number, got ${JSON.stringify(m.fps)}`);\n }\n if (typeof m.totalDurationSec !== 'number' || m.totalDurationSec <= 0) {\n errors.push(\n `totalDurationSec must be a positive number, got ${JSON.stringify(m.totalDurationSec)}`,\n );\n }\n\n const totalDur = typeof m.totalDurationSec === 'number' ? m.totalDurationSec : 0;\n\n // --- Arrays must exist ---\n if (!Array.isArray(m.dialog)) {\n errors.push('dialog must be an array');\n }\n if (!Array.isArray(m.music)) {\n errors.push('music must be an array');\n }\n if (!Array.isArray(m.sfx)) {\n errors.push('sfx must be an array');\n }\n if (!Array.isArray(m.overlays)) {\n errors.push('overlays must be an array');\n }\n\n // Bail early if arrays are missing — can't validate contents\n if (errors.length > 0) {\n return { valid: false, errors };\n }\n\n const dialog = m.dialog as DialogBeat[];\n const music = m.music as MusicTrack[];\n const sfx = m.sfx as SfxPlacement[];\n const overlays = m.overlays as TextOverlay[];\n\n // --- Shared helpers ---\n function checkFilePath(file: unknown, context: string): void {\n if (typeof file !== 'string' || file.length === 0) {\n errors.push(`${context}: file must be a non-empty string`);\n } else if (file.startsWith('/') || file.startsWith('\\\\')) {\n errors.push(`${context}: file must be a relative path, got \"${file}\"`);\n }\n }\n\n function checkVolume(vol: unknown, context: string, required: boolean): void {\n if (vol == null) {\n if (required) errors.push(`${context}: volume is required`);\n return;\n }\n if (typeof vol !== 'number' || vol < 0 || vol > 1) {\n errors.push(`${context}: volume must be 0-1, got ${JSON.stringify(vol)}`);\n }\n }\n\n function checkTimingWithin(startSec: unknown, durationSec: unknown, context: string): void {\n if (typeof startSec !== 'number' || startSec < 0) {\n errors.push(\n `${context}: startSec must be a non-negative number, got ${JSON.stringify(startSec)}`,\n );\n return;\n }\n if (typeof durationSec === 'number') {\n if (durationSec < 0) {\n errors.push(`${context}: durationSec must be non-negative, got ${durationSec}`);\n }\n if (startSec + durationSec > totalDur) {\n errors.push(\n `${context}: startSec (${startSec}) + durationSec (${durationSec}) = ${startSec + durationSec} exceeds totalDurationSec (${totalDur})`,\n );\n }\n }\n }\n\n // --- Dialog beats ---\n const ids = new Set<string>();\n for (let i = 0; i < dialog.length; i++) {\n const b = dialog[i];\n const ctx = `dialog[${i}] (${b.id ?? 'no id'})`;\n\n if (typeof b.id !== 'string' || b.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n } else if (ids.has(b.id)) {\n errors.push(`${ctx}: duplicate id \"${b.id}\"`);\n } else {\n ids.add(b.id);\n }\n\n checkFilePath(b.file, ctx);\n\n if (typeof b.speaker !== 'string' || b.speaker.length === 0) {\n errors.push(`${ctx}: speaker must be a non-empty string`);\n }\n if (typeof b.text !== 'string') {\n errors.push(`${ctx}: text must be a string`);\n }\n if (typeof b.durationSec !== 'number' || b.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(b.durationSec)}`,\n );\n }\n\n checkTimingWithin(b.startSec, b.durationSec, ctx);\n checkVolume(b.volume, ctx, false);\n\n if (\n b.style !== undefined &&\n b.style !== 'quote' &&\n b.style !== 'narrator' &&\n b.style !== 'text-card'\n ) {\n errors.push(`${ctx}: style must be 'quote', 'narrator', or 'text-card', got \"${b.style}\"`);\n }\n }\n\n // --- Same-speaker overlap check ---\n const bySpeaker = new Map<string, DialogBeat[]>();\n for (const b of dialog) {\n if (typeof b.speaker !== 'string') continue;\n const list = bySpeaker.get(b.speaker) ?? [];\n list.push(b);\n bySpeaker.set(b.speaker, list);\n }\n for (const [speaker, beats] of bySpeaker) {\n const sorted = [...beats].sort((a, b) => a.startSec - b.startSec);\n for (let i = 1; i < sorted.length; i++) {\n const prev = sorted[i - 1];\n const curr = sorted[i];\n const prevEnd = prev.startSec + prev.durationSec;\n if (prevEnd > curr.startSec) {\n errors.push(\n `dialog overlap for speaker \"${speaker}\": \"${prev.id}\" ends at ${prevEnd}s but \"${curr.id}\" starts at ${curr.startSec}s`,\n );\n }\n }\n }\n\n // --- Music tracks ---\n for (let i = 0; i < music.length; i++) {\n const t = music[i];\n const ctx = `music[${i}] (${t.id ?? 'no id'})`;\n\n if (typeof t.id !== 'string' || t.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(t.file, ctx);\n checkTimingWithin(t.startSec, t.durationSec, ctx);\n checkVolume(t.volume, ctx, true);\n\n if (t.fadeInSec != null && (typeof t.fadeInSec !== 'number' || t.fadeInSec < 0)) {\n errors.push(`${ctx}: fadeInSec must be a non-negative number`);\n }\n if (t.fadeOutSec != null && (typeof t.fadeOutSec !== 'number' || t.fadeOutSec < 0)) {\n errors.push(`${ctx}: fadeOutSec must be a non-negative number`);\n }\n if (t.duckTo != null) {\n if (typeof t.duckTo !== 'number' || t.duckTo < 0 || t.duckTo > 1) {\n errors.push(`${ctx}: duckTo must be 0-1, got ${JSON.stringify(t.duckTo)}`);\n }\n }\n }\n\n // --- SFX placements ---\n for (let i = 0; i < sfx.length; i++) {\n const s = sfx[i];\n const ctx = `sfx[${i}] (${s.id ?? 'no id'})`;\n\n if (typeof s.id !== 'string' || s.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n checkFilePath(s.file, ctx);\n if (typeof s.startSec !== 'number' || s.startSec < 0) {\n errors.push(\n `${ctx}: startSec must be a non-negative number, got ${JSON.stringify(s.startSec)}`,\n );\n }\n if (s.startSec > totalDur) {\n errors.push(`${ctx}: startSec (${s.startSec}) exceeds totalDurationSec (${totalDur})`);\n }\n checkVolume(s.volume, ctx, false);\n }\n\n // --- Text overlays ---\n const validOverlayTypes = new Set(['title-card', 'speaker-label', 'data-accent', 'chapter']);\n const validPositions = new Set(['center', 'bottom-left', 'bottom-right', 'top']);\n for (let i = 0; i < overlays.length; i++) {\n const o = overlays[i];\n const ctx = `overlays[${i}] (${o.id ?? 'no id'})`;\n\n if (typeof o.id !== 'string' || o.id.length === 0) {\n errors.push(`${ctx}: id must be a non-empty string`);\n }\n if (!validOverlayTypes.has(o.type)) {\n errors.push(\n `${ctx}: type must be one of ${[...validOverlayTypes].join(', ')}, got \"${o.type}\"`,\n );\n }\n if (typeof o.text !== 'string' || o.text.length === 0) {\n errors.push(`${ctx}: text must be a non-empty string`);\n }\n if (typeof o.durationSec !== 'number' || o.durationSec <= 0) {\n errors.push(\n `${ctx}: durationSec must be a positive number, got ${JSON.stringify(o.durationSec)}`,\n );\n }\n checkTimingWithin(o.startSec, o.durationSec, ctx);\n\n if (o.style != null) {\n if (typeof o.style !== 'object') {\n errors.push(`${ctx}: style must be an object`);\n } else {\n if (\n o.style.fontSize != null &&\n (typeof o.style.fontSize !== 'number' || o.style.fontSize <= 0)\n ) {\n errors.push(`${ctx}: style.fontSize must be a positive number`);\n }\n if (o.style.color != null && typeof o.style.color !== 'string') {\n errors.push(`${ctx}: style.color must be a string`);\n }\n if (o.style.position != null && !validPositions.has(o.style.position)) {\n errors.push(\n `${ctx}: style.position must be one of ${[...validPositions].join(', ')}, got \"${o.style.position}\"`,\n );\n }\n if (\n o.style.typingSpeed !== undefined &&\n o.style.typingSpeed !== null &&\n (typeof o.style.typingSpeed !== 'number' || o.style.typingSpeed <= 0)\n ) {\n errors.push(`${ctx}: style.typingSpeed must be a positive number or null`);\n }\n }\n }\n }\n\n return { valid: errors.length === 0, errors };\n}\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Compute total duration from manifest content.\n * Returns max(endTime) across all tracks + 2s padding.\n * Useful for agents building the manifest before totalDurationSec is known.\n */\nexport function computeTotalDuration(\n manifest: Pick<AudioManifest, 'dialog' | 'music' | 'sfx' | 'overlays'>,\n): number {\n let maxEnd = 0;\n\n for (const b of manifest.dialog) {\n maxEnd = Math.max(maxEnd, b.startSec + b.durationSec);\n }\n for (const t of manifest.music) {\n maxEnd = Math.max(maxEnd, t.startSec + t.durationSec);\n }\n for (const s of manifest.sfx) {\n // SFX don't have durationSec — use startSec only\n maxEnd = Math.max(maxEnd, s.startSec);\n }\n for (const o of manifest.overlays) {\n maxEnd = Math.max(maxEnd, o.startSec + o.durationSec);\n }\n\n return maxEnd + 2;\n}\n"]}
|