miriad-viz 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist-cli/{chunk-IMD2MNLI.js → chunk-GLABTDMO.js} +13 -0
- package/dist-cli/{chunk-PHPII3CV.js → chunk-UTFBENVA.js} +47 -3
- package/dist-cli/{curate-QUIYJ7VJ.js → curate-SMBYTH7I.js} +1 -1
- package/dist-cli/{extract-NDJN7REW.js → extract-5JGICL3V.js} +11 -3
- package/dist-cli/index.js +171 -14
- package/dist-cli/{preview-PXC6HTMF.js → preview-UUWVOX5Y.js} +1 -1
- package/dist-cli/{render-JV57PXIE.js → render-T2UXDN25.js} +3 -3
- package/dist-cli/{transform-POVVUALD.js → transform-N4UK7EOP.js} +3 -3
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ var STEPS_V2 = [
|
|
|
3
3
|
"init",
|
|
4
4
|
"extract",
|
|
5
5
|
"script",
|
|
6
|
+
"curate",
|
|
6
7
|
"voices",
|
|
7
8
|
"viz-timing",
|
|
8
9
|
"sound-design",
|
|
@@ -18,6 +19,7 @@ function createProgressFile(project) {
|
|
|
18
19
|
init: { status: "complete", completedAt: now },
|
|
19
20
|
extract: { status: "pending" },
|
|
20
21
|
script: { status: "pending" },
|
|
22
|
+
curate: { status: "pending" },
|
|
21
23
|
voices: { status: "pending" },
|
|
22
24
|
"viz-timing": { status: "pending" },
|
|
23
25
|
"sound-design": { status: "pending" },
|
|
@@ -54,6 +56,7 @@ function migrateV1toV2(v1) {
|
|
|
54
56
|
init,
|
|
55
57
|
extract,
|
|
56
58
|
script,
|
|
59
|
+
curate: v1.steps.curate ?? { status: "pending" },
|
|
57
60
|
voices,
|
|
58
61
|
"viz-timing": vizTiming,
|
|
59
62
|
"sound-design": soundDesign,
|
|
@@ -80,6 +83,16 @@ var STEP_CONFIG = {
|
|
|
80
83
|
creative: true,
|
|
81
84
|
outputFiles: ["data/script.json"]
|
|
82
85
|
},
|
|
86
|
+
curate: {
|
|
87
|
+
mode: "inline",
|
|
88
|
+
label: "Curate editorial content",
|
|
89
|
+
creative: true,
|
|
90
|
+
outputFiles: [
|
|
91
|
+
"data/retro-page-data.json",
|
|
92
|
+
"data/retro-page-quotes.json",
|
|
93
|
+
"data/timeline-events.json"
|
|
94
|
+
]
|
|
95
|
+
},
|
|
83
96
|
voices: {
|
|
84
97
|
mode: "inline",
|
|
85
98
|
label: "Generate voices (TTS)",
|
|
@@ -5,11 +5,12 @@ import { resolve } from "path";
|
|
|
5
5
|
function canSync() {
|
|
6
6
|
return !!(process.env.MIRIAD_SPACE_TOKEN && process.env.MIRIAD_API_URL && process.env.MIRIAD_CHANNEL_ID);
|
|
7
7
|
}
|
|
8
|
-
function getBoardSyncConfig(
|
|
8
|
+
function getBoardSyncConfig(dataDir) {
|
|
9
9
|
const apiUrl = process.env.MIRIAD_API_URL;
|
|
10
10
|
const channelId = process.env.MIRIAD_CHANNEL_ID;
|
|
11
11
|
const spaceToken = process.env.MIRIAD_SPACE_TOKEN;
|
|
12
12
|
if (!apiUrl || !channelId || !spaceToken) return null;
|
|
13
|
+
const boardDir = dataDir ? `/${dataDir.replace(/^\.\//, "").replace(/\/$/, "").split("/").pop()}` : "/data";
|
|
13
14
|
return { apiUrl, channelId, spaceToken, boardDir };
|
|
14
15
|
}
|
|
15
16
|
var TIMEOUT_MS = 1e4;
|
|
@@ -17,6 +18,25 @@ async function syncTextFile(config, localPath, boardPath) {
|
|
|
17
18
|
const content = readFileSync(localPath, "utf-8");
|
|
18
19
|
const fullBoardPath = `${config.boardDir}/${boardPath}`;
|
|
19
20
|
const url = `${config.apiUrl}/channels/${config.channelId}/files${fullBoardPath}`;
|
|
21
|
+
let version;
|
|
22
|
+
try {
|
|
23
|
+
const getController = new AbortController();
|
|
24
|
+
const getTimeout = setTimeout(() => getController.abort(), TIMEOUT_MS);
|
|
25
|
+
try {
|
|
26
|
+
const getRes = await fetch(url, {
|
|
27
|
+
method: "GET",
|
|
28
|
+
headers: { Authorization: `Bearer ${config.spaceToken}` },
|
|
29
|
+
signal: getController.signal
|
|
30
|
+
});
|
|
31
|
+
if (getRes.ok) {
|
|
32
|
+
const data = await getRes.json();
|
|
33
|
+
version = data.version;
|
|
34
|
+
}
|
|
35
|
+
} finally {
|
|
36
|
+
clearTimeout(getTimeout);
|
|
37
|
+
}
|
|
38
|
+
} catch {
|
|
39
|
+
}
|
|
20
40
|
const controller = new AbortController();
|
|
21
41
|
const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
22
42
|
try {
|
|
@@ -26,7 +46,7 @@ async function syncTextFile(config, localPath, boardPath) {
|
|
|
26
46
|
Authorization: `Bearer ${config.spaceToken}`,
|
|
27
47
|
"Content-Type": "application/json"
|
|
28
48
|
},
|
|
29
|
-
body: JSON.stringify({ content }),
|
|
49
|
+
body: JSON.stringify({ content, ...version !== void 0 ? { version } : {} }),
|
|
30
50
|
signal: controller.signal
|
|
31
51
|
});
|
|
32
52
|
if (!res.ok) {
|
|
@@ -43,6 +63,26 @@ async function syncTextFile(config, localPath, boardPath) {
|
|
|
43
63
|
async function syncBinaryFile(config, localPath, boardPath, mimeType = "application/octet-stream") {
|
|
44
64
|
const fullBoardPath = `${config.boardDir}/${boardPath}`;
|
|
45
65
|
const uploadUrl = `${config.apiUrl}/channels/${config.channelId}/files/upload`;
|
|
66
|
+
let version;
|
|
67
|
+
try {
|
|
68
|
+
const fileUrl = `${config.apiUrl}/channels/${config.channelId}/files${fullBoardPath}`;
|
|
69
|
+
const getController = new AbortController();
|
|
70
|
+
const getTimeout = setTimeout(() => getController.abort(), TIMEOUT_MS);
|
|
71
|
+
try {
|
|
72
|
+
const getRes = await fetch(fileUrl, {
|
|
73
|
+
method: "GET",
|
|
74
|
+
headers: { Authorization: `Bearer ${config.spaceToken}` },
|
|
75
|
+
signal: getController.signal
|
|
76
|
+
});
|
|
77
|
+
if (getRes.ok) {
|
|
78
|
+
const data = await getRes.json();
|
|
79
|
+
version = data.version;
|
|
80
|
+
}
|
|
81
|
+
} finally {
|
|
82
|
+
clearTimeout(getTimeout);
|
|
83
|
+
}
|
|
84
|
+
} catch {
|
|
85
|
+
}
|
|
46
86
|
const controller = new AbortController();
|
|
47
87
|
const timeout = setTimeout(() => controller.abort(), TIMEOUT_MS);
|
|
48
88
|
try {
|
|
@@ -52,7 +92,11 @@ async function syncBinaryFile(config, localPath, boardPath, mimeType = "applicat
|
|
|
52
92
|
Authorization: `Bearer ${config.spaceToken}`,
|
|
53
93
|
"Content-Type": "application/json"
|
|
54
94
|
},
|
|
55
|
-
body: JSON.stringify({
|
|
95
|
+
body: JSON.stringify({
|
|
96
|
+
path: fullBoardPath,
|
|
97
|
+
mimeType,
|
|
98
|
+
...version !== void 0 ? { version } : {}
|
|
99
|
+
}),
|
|
56
100
|
signal: controller.signal
|
|
57
101
|
});
|
|
58
102
|
if (!res.ok) {
|
|
@@ -12,13 +12,13 @@ import {
|
|
|
12
12
|
canSync,
|
|
13
13
|
getBoardSyncConfig,
|
|
14
14
|
syncStepOutputs
|
|
15
|
-
} from "./chunk-
|
|
15
|
+
} from "./chunk-UTFBENVA.js";
|
|
16
16
|
import {
|
|
17
17
|
markComplete,
|
|
18
18
|
markError,
|
|
19
19
|
markInProgress,
|
|
20
20
|
writeProgress
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-GLABTDMO.js";
|
|
22
22
|
|
|
23
23
|
// src/cli/guided/steps/extract.ts
|
|
24
24
|
import { existsSync as existsSync2, mkdirSync, writeFileSync } from "fs";
|
|
@@ -652,6 +652,14 @@ Processing ${extractedMessages.length} messages...`);
|
|
|
652
652
|
}));
|
|
653
653
|
writeJSON(dataDir, "messages-viz.json", lightMessages);
|
|
654
654
|
outputs.push("messages-viz.json");
|
|
655
|
+
const fullMessages = extractedMessages.map((msg) => ({
|
|
656
|
+
id: msg.id,
|
|
657
|
+
timestamp: msg.timestamp,
|
|
658
|
+
sender: msg.sender,
|
|
659
|
+
content: msg.content
|
|
660
|
+
}));
|
|
661
|
+
writeJSON(dataDir, "messages-full.json", fullMessages);
|
|
662
|
+
outputs.push("messages-full.json");
|
|
655
663
|
}
|
|
656
664
|
let extractedArtifacts = extractResult.artifacts;
|
|
657
665
|
if (extractedArtifacts.length > 0) {
|
|
@@ -679,7 +687,7 @@ Processing ${extractedArtifacts.length} artifacts...`);
|
|
|
679
687
|
markComplete(progress, "extract", outputs);
|
|
680
688
|
writeProgress(projectDir, progress);
|
|
681
689
|
if (canSync()) {
|
|
682
|
-
const syncConfig = getBoardSyncConfig();
|
|
690
|
+
const syncConfig = getBoardSyncConfig(project.dataDir);
|
|
683
691
|
if (syncConfig) {
|
|
684
692
|
await syncStepOutputs(syncConfig, "extract", dataDir);
|
|
685
693
|
}
|
package/dist-cli/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
pullFromBoard,
|
|
5
5
|
syncStepOutputs,
|
|
6
6
|
syncTextFile
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-UTFBENVA.js";
|
|
8
8
|
import {
|
|
9
9
|
PROGRESS_FILENAME,
|
|
10
10
|
STEPS,
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
getNextStep,
|
|
15
15
|
readProgress,
|
|
16
16
|
writeProgress
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GLABTDMO.js";
|
|
18
18
|
|
|
19
19
|
// src/cli/guided/index.ts
|
|
20
20
|
import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync } from "fs";
|
|
@@ -398,6 +398,41 @@ function buildVizTimingApprovalError() {
|
|
|
398
398
|
|
|
399
399
|
// src/cli/guided/next.ts
|
|
400
400
|
var AUDIO_DIR_PREFIX = "remotion/public/audio/";
|
|
401
|
+
var STEP_OUTPUT_FILES = {
|
|
402
|
+
extract: [".miriad-viz.json"],
|
|
403
|
+
script: ["script.json", "pacing.json"],
|
|
404
|
+
curate: ["retro-page-data.json", "retro-page-quotes.json", "timeline-events.json"],
|
|
405
|
+
voices: [],
|
|
406
|
+
// dynamic — audio/*.mp3 files
|
|
407
|
+
"viz-timing": ["timing.json"],
|
|
408
|
+
"sound-design": ["audio-manifest.json"],
|
|
409
|
+
render: []
|
|
410
|
+
// video too large for board
|
|
411
|
+
};
|
|
412
|
+
function buildSyncInstructions(step, progress, audioFiles) {
|
|
413
|
+
if (progress.project.platform !== "redux") return [];
|
|
414
|
+
const dataDir = progress.project.dataDir || "data";
|
|
415
|
+
const boardDir = `/${dataDir.replace(/^\.\//, "").replace(/\/$/, "").split("/").pop()}`;
|
|
416
|
+
const lines = [];
|
|
417
|
+
const files = STEP_OUTPUT_FILES[step] ?? [];
|
|
418
|
+
const filesToSync = step === "voices" && audioFiles && audioFiles.length > 0 ? audioFiles : files;
|
|
419
|
+
if (filesToSync.length === 0) return [];
|
|
420
|
+
lines.push("");
|
|
421
|
+
lines.push(" \u2601 Sync to board:");
|
|
422
|
+
for (const file of filesToSync) {
|
|
423
|
+
const boardPath = `${boardDir}/${file}`;
|
|
424
|
+
const isBinary = file.endsWith(".mp3") || file.endsWith(".wav") || file.endsWith(".mp4");
|
|
425
|
+
if (isBinary) {
|
|
426
|
+
lines.push(` ${file} \u2192 upload to board at ${boardPath}`);
|
|
427
|
+
} else {
|
|
428
|
+
lines.push(` ${file} \u2192 write to board at ${boardPath}`);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
lines.push("");
|
|
432
|
+
lines.push(" Text: read file from sandbox \u2192 write to board");
|
|
433
|
+
lines.push(" Binary: upload (presigned URL) \u2192 curl PUT from sandbox");
|
|
434
|
+
return lines;
|
|
435
|
+
}
|
|
401
436
|
function buildCommand(step, progress, flags) {
|
|
402
437
|
const base = `npx miriad-viz ${step}`;
|
|
403
438
|
const parts = [base];
|
|
@@ -454,6 +489,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
454
489
|
outputs: ["data/script.json"]
|
|
455
490
|
};
|
|
456
491
|
output.push("", "\u2713 Script approved.");
|
|
492
|
+
output.push(...buildSyncInstructions("script", progress));
|
|
457
493
|
const chainResult = computeNext(progress, existingFiles, logTails, flags, dataSummary, env);
|
|
458
494
|
return {
|
|
459
495
|
...chainResult,
|
|
@@ -470,6 +506,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
470
506
|
outputs: ["data/script.json"]
|
|
471
507
|
};
|
|
472
508
|
output.push("", "\u2713 Script found.");
|
|
509
|
+
output.push(...buildSyncInstructions("script", progress));
|
|
473
510
|
output.push("");
|
|
474
511
|
output.push(" \u256D\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\u2500\u2500\u2500\u2500\u256E");
|
|
475
512
|
output.push(" \u2502 \u26D4 CREATIVE STOP \u2014 DO NOT PROCEED AUTOMATICALLY \u2502");
|
|
@@ -513,8 +550,19 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
513
550
|
output.push(` - "What's the arc? What tone?"`);
|
|
514
551
|
output.push(' - "Which moments matter most?"');
|
|
515
552
|
output.push(' - "Any specific quotes to include?"');
|
|
516
|
-
output.push(" 2. Mine the data
|
|
517
|
-
|
|
553
|
+
output.push(" 2. Mine the data for quotes and key moments:");
|
|
554
|
+
if (progress.project.platform === "redux") {
|
|
555
|
+
output.push(" data/messages-full.json has full message content.");
|
|
556
|
+
output.push(" \u26A0\uFE0F Do NOT load the whole file into context \u2014 it can be huge.");
|
|
557
|
+
output.push(" Use grep/jq to search:");
|
|
558
|
+
output.push(' grep -i "keyword" data/messages-full.json | head -20');
|
|
559
|
+
output.push(
|
|
560
|
+
` jq '.[] | select(.content | test("keyword"; "i")) | {sender, content}' data/messages-full.json`
|
|
561
|
+
);
|
|
562
|
+
} else {
|
|
563
|
+
output.push(" grep messages.json for emotional keywords,");
|
|
564
|
+
output.push(" search around turning points, find the best quotes");
|
|
565
|
+
}
|
|
518
566
|
output.push(" 3. Write script.json with ordered narration lines");
|
|
519
567
|
output.push(" 4. ALSO propose: phases, milestones, featured quotes (curation)");
|
|
520
568
|
output.push(" 5. Curate chat pills: pick 10-20 standout messages, suggest placement");
|
|
@@ -542,6 +590,109 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
542
590
|
progress.steps.script = { status: "in_progress" };
|
|
543
591
|
return { action: "run_inline", step, progress, output };
|
|
544
592
|
}
|
|
593
|
+
if (step === "curate") {
|
|
594
|
+
const CURATE_OUTPUT_FILES = [
|
|
595
|
+
"data/retro-page-data.json",
|
|
596
|
+
"data/retro-page-quotes.json",
|
|
597
|
+
"data/timeline-events.json"
|
|
598
|
+
];
|
|
599
|
+
if (flags["curate-approved"]) {
|
|
600
|
+
const missing = CURATE_OUTPUT_FILES.filter((f) => !fileSet.has(f));
|
|
601
|
+
if (missing.length > 0) {
|
|
602
|
+
output.push("", "\u2717 Missing curate outputs:");
|
|
603
|
+
for (const f of missing) {
|
|
604
|
+
output.push(` ${f}`);
|
|
605
|
+
}
|
|
606
|
+
output.push("", " Run `npx miriad-viz curate` first, then fill in the scaffolds.");
|
|
607
|
+
return { action: "error_shown", step, progress, output };
|
|
608
|
+
}
|
|
609
|
+
progress.steps.curate = {
|
|
610
|
+
status: "complete",
|
|
611
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
612
|
+
outputs: CURATE_OUTPUT_FILES
|
|
613
|
+
};
|
|
614
|
+
output.push("", "\u2713 Curation approved.");
|
|
615
|
+
output.push(...buildSyncInstructions("curate", progress));
|
|
616
|
+
const chainResult = computeNext(progress, existingFiles, logTails, flags, dataSummary, env);
|
|
617
|
+
return {
|
|
618
|
+
...chainResult,
|
|
619
|
+
action: "completed_and_chained",
|
|
620
|
+
output: [...output, ...chainResult.output]
|
|
621
|
+
};
|
|
622
|
+
}
|
|
623
|
+
if (state.status === "in_progress") {
|
|
624
|
+
const hasAll = CURATE_OUTPUT_FILES.every((f) => fileSet.has(f));
|
|
625
|
+
if (hasAll) {
|
|
626
|
+
progress.steps.curate = {
|
|
627
|
+
status: "complete",
|
|
628
|
+
completedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
629
|
+
outputs: CURATE_OUTPUT_FILES
|
|
630
|
+
};
|
|
631
|
+
output.push("", "\u2713 Curate outputs found.");
|
|
632
|
+
output.push(...buildSyncInstructions("curate", progress));
|
|
633
|
+
output.push("");
|
|
634
|
+
output.push(" \u256D\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\u2500\u2500\u2500\u2500\u256E");
|
|
635
|
+
output.push(" \u2502 \u26D4 CREATIVE STOP \u2014 DO NOT PROCEED AUTOMATICALLY \u2502");
|
|
636
|
+
output.push(" \u2502 \u2502");
|
|
637
|
+
output.push(" \u2502 Present the curation to the human: \u2502");
|
|
638
|
+
output.push(" \u2502 1. Summarize the phases and milestones \u2502");
|
|
639
|
+
output.push(" \u2502 2. List the featured quotes \u2502");
|
|
640
|
+
output.push(" \u2502 3. Show the timeline event count \u2502");
|
|
641
|
+
output.push(" \u2502 4. Ask for feedback and iterate if needed \u2502");
|
|
642
|
+
output.push(" \u2502 \u2502");
|
|
643
|
+
output.push(" \u2502 When approved: npx miriad-viz next --curate-approved \u2502");
|
|
644
|
+
output.push(" \u2570\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\u2500\u2500\u2500\u2500\u256F");
|
|
645
|
+
return { action: "creative_stop", step, progress, output };
|
|
646
|
+
}
|
|
647
|
+
const existing = CURATE_OUTPUT_FILES.filter((f) => fileSet.has(f));
|
|
648
|
+
const missing = CURATE_OUTPUT_FILES.filter((f) => !fileSet.has(f));
|
|
649
|
+
if (existing.length > 0) {
|
|
650
|
+
output.push("", " Found:");
|
|
651
|
+
for (const f of existing) output.push(` \u2713 ${f}`);
|
|
652
|
+
}
|
|
653
|
+
if (missing.length > 0) {
|
|
654
|
+
output.push("", " Missing:");
|
|
655
|
+
for (const f of missing) output.push(` \u25CB ${f}`);
|
|
656
|
+
}
|
|
657
|
+
output.push("", " Run `npx miriad-viz curate` to generate scaffolds,");
|
|
658
|
+
output.push(" then fill in retro-page-data.json and retro-page-quotes.json.");
|
|
659
|
+
output.push("", " When done: npx miriad-viz next");
|
|
660
|
+
return { action: "waiting_for_edit", step, progress, output };
|
|
661
|
+
}
|
|
662
|
+
output.push("", "\u{1F4CB} Curate Editorial Content");
|
|
663
|
+
output.push("");
|
|
664
|
+
output.push(" This step generates scaffold files for editorial content:");
|
|
665
|
+
output.push(" \u2022 retro-page-data.json \u2014 phases, milestones, featured quotes, narration");
|
|
666
|
+
output.push(" \u2022 retro-page-quotes.json \u2014 additional standout quotes");
|
|
667
|
+
output.push(" \u2022 timeline-events.json \u2014 auto-generated from extracted data");
|
|
668
|
+
output.push("");
|
|
669
|
+
output.push(" YOUR TASK:");
|
|
670
|
+
output.push(" 1. Run: npx miriad-viz curate");
|
|
671
|
+
output.push(" This generates scaffolds pre-filled from your extracted data.");
|
|
672
|
+
output.push(" 2. Fill in retro-page-data.json:");
|
|
673
|
+
output.push(" - Define phases (story arcs with start/end dates)");
|
|
674
|
+
output.push(" - Add milestones (key moments)");
|
|
675
|
+
output.push(" - Select featured quotes from the data");
|
|
676
|
+
output.push(" - Write narration-editorial entries (fractional 0-1 positions)");
|
|
677
|
+
output.push(" 3. Fill in retro-page-quotes.json:");
|
|
678
|
+
output.push(" - Add standout quotes with speaker, text, and timestamp");
|
|
679
|
+
output.push(" 4. timeline-events.json is auto-generated \u2014 review but don't edit");
|
|
680
|
+
output.push(" 5. Present to human and iterate");
|
|
681
|
+
output.push("");
|
|
682
|
+
output.push(" \u26A0\uFE0F narration-editorial uses FRACTIONAL 0-1 for start/end (e.g. 0.23, 0.68).");
|
|
683
|
+
output.push(" Everything else in curation uses ISO timestamps. Do NOT mix them up.");
|
|
684
|
+
output.push("");
|
|
685
|
+
output.push(" When human approves: npx miriad-viz next --curate-approved");
|
|
686
|
+
const curateDoc = readBundledDoc("miriad-viz-curation");
|
|
687
|
+
if (curateDoc) {
|
|
688
|
+
output.push("");
|
|
689
|
+
output.push("\u2501\u2501\u2501 CURATION GUIDE \u2501\u2501\u2501");
|
|
690
|
+
output.push(curateDoc);
|
|
691
|
+
output.push("\u2501\u2501\u2501 END CURATION GUIDE \u2501\u2501\u2501");
|
|
692
|
+
}
|
|
693
|
+
progress.steps.curate = { status: "in_progress" };
|
|
694
|
+
return { action: "run_inline", step, progress, output };
|
|
695
|
+
}
|
|
545
696
|
if (step === "voices") {
|
|
546
697
|
const VOICE_AUDIO_PREFIX = "audio/";
|
|
547
698
|
if (flags["skip-audio"]) {
|
|
@@ -578,6 +729,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
578
729
|
"",
|
|
579
730
|
`\u2713 Voices approved (${audioFiles.length} clip${audioFiles.length > 1 ? "s" : ""}).`
|
|
580
731
|
);
|
|
732
|
+
output.push(...buildSyncInstructions("voices", progress, audioFiles));
|
|
581
733
|
const chainResult = computeNext(progress, existingFiles, logTails, flags, dataSummary, env);
|
|
582
734
|
return {
|
|
583
735
|
...chainResult,
|
|
@@ -684,6 +836,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
684
836
|
outputs: ["data/timing.json"]
|
|
685
837
|
};
|
|
686
838
|
output.push("", "\u2713 Timing approved.");
|
|
839
|
+
output.push(...buildSyncInstructions("viz-timing", progress));
|
|
687
840
|
const chainResult = computeNext(progress, existingFiles, logTails, flags, dataSummary, env);
|
|
688
841
|
return {
|
|
689
842
|
...chainResult,
|
|
@@ -706,6 +859,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
706
859
|
completedAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
707
860
|
};
|
|
708
861
|
output.push("", "\u2713 Sound design approved.");
|
|
862
|
+
output.push(...buildSyncInstructions("sound-design", progress));
|
|
709
863
|
const chainResult = computeNext(progress, existingFiles, logTails, flags, dataSummary, env);
|
|
710
864
|
return {
|
|
711
865
|
...chainResult,
|
|
@@ -734,6 +888,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
|
|
|
734
888
|
outputs: config.outputFiles.filter((f) => fileSet.has(f))
|
|
735
889
|
};
|
|
736
890
|
output.push("", `\u2713 ${config.label} complete!`);
|
|
891
|
+
output.push(...buildSyncInstructions(step, progress));
|
|
737
892
|
if (step === "extract" && dataSummary && dataSummary.length > 0) {
|
|
738
893
|
output.push(...dataSummary);
|
|
739
894
|
}
|
|
@@ -1003,7 +1158,7 @@ Project already initialized: ${existing.project.name}`);
|
|
|
1003
1158
|
const repo = options.repo;
|
|
1004
1159
|
const channel = options.channel;
|
|
1005
1160
|
const agents = parseAgentList(options.agents);
|
|
1006
|
-
const dataDir = "./data";
|
|
1161
|
+
const dataDir = options.dataDir || "./data";
|
|
1007
1162
|
const outputDir = options.outdir || "./output";
|
|
1008
1163
|
const config = {
|
|
1009
1164
|
name,
|
|
@@ -1077,6 +1232,7 @@ function showStatus(progress) {
|
|
|
1077
1232
|
init: "Initialize project",
|
|
1078
1233
|
extract: "Extract source data",
|
|
1079
1234
|
script: "Write narrative script",
|
|
1235
|
+
curate: "Curate editorial content",
|
|
1080
1236
|
voices: "Generate voices (TTS)",
|
|
1081
1237
|
"viz-timing": "Set visualization timing",
|
|
1082
1238
|
"sound-design": "Sound design (SFX + music)",
|
|
@@ -1230,7 +1386,7 @@ async function runNext(flags) {
|
|
|
1230
1386
|
const dataFiles = existsSync3(dataDir) ? readdirSync(dataDir) : [];
|
|
1231
1387
|
const hasLocalData = dataFiles.length > 0;
|
|
1232
1388
|
if (!hasLocalData) {
|
|
1233
|
-
const syncConfig = getBoardSyncConfig();
|
|
1389
|
+
const syncConfig = getBoardSyncConfig(progress.project.dataDir);
|
|
1234
1390
|
if (syncConfig) {
|
|
1235
1391
|
console.log("\n\u2601 Checking board for existing pipeline state...");
|
|
1236
1392
|
const { pulled, warnings } = await pullFromBoard(syncConfig, dataDir);
|
|
@@ -1287,7 +1443,7 @@ async function runNext(flags) {
|
|
|
1287
1443
|
}
|
|
1288
1444
|
writeProgress(projectDir, result.progress);
|
|
1289
1445
|
if (canSync()) {
|
|
1290
|
-
const syncConfig = getBoardSyncConfig();
|
|
1446
|
+
const syncConfig = getBoardSyncConfig(result.progress.project.dataDir);
|
|
1291
1447
|
if (syncConfig) {
|
|
1292
1448
|
const dataDir2 = resolve3(projectDir, result.progress.project.dataDir);
|
|
1293
1449
|
if (result.step && (result.action === "completed_and_chained" || result.action === "creative_stop")) {
|
|
@@ -1323,6 +1479,7 @@ async function main() {
|
|
|
1323
1479
|
channel: typeof flags.channel === "string" ? flags.channel : void 0,
|
|
1324
1480
|
agents: typeof flags.agents === "string" ? flags.agents : void 0,
|
|
1325
1481
|
outdir: typeof flags.outdir === "string" ? flags.outdir : void 0,
|
|
1482
|
+
dataDir: typeof flags["data-dir"] === "string" ? flags["data-dir"] : void 0,
|
|
1326
1483
|
platform: typeof flags.platform === "string" && (flags.platform === "cast" || flags.platform === "redux") ? flags.platform : void 0
|
|
1327
1484
|
});
|
|
1328
1485
|
break;
|
|
@@ -1336,7 +1493,7 @@ async function main() {
|
|
|
1336
1493
|
}
|
|
1337
1494
|
case "extract": {
|
|
1338
1495
|
const { projectDir, progress } = requireProject();
|
|
1339
|
-
const { runExtract } = await import("./extract-
|
|
1496
|
+
const { runExtract } = await import("./extract-5JGICL3V.js");
|
|
1340
1497
|
await runExtract({
|
|
1341
1498
|
projectDir,
|
|
1342
1499
|
progress,
|
|
@@ -1350,14 +1507,14 @@ async function main() {
|
|
|
1350
1507
|
}
|
|
1351
1508
|
case "curate": {
|
|
1352
1509
|
const { projectDir, progress } = requireProject();
|
|
1353
|
-
const { runCurate } = await import("./curate-
|
|
1510
|
+
const { runCurate } = await import("./curate-SMBYTH7I.js");
|
|
1354
1511
|
await runCurate({ projectDir, progress });
|
|
1355
1512
|
break;
|
|
1356
1513
|
}
|
|
1357
1514
|
case "transform": {
|
|
1358
1515
|
const { projectDir, progress } = requireProject();
|
|
1359
1516
|
const { parseDuration } = await import("./parse-duration-NVLCEFAF.js");
|
|
1360
|
-
const { runTransform } = await import("./transform-
|
|
1517
|
+
const { runTransform } = await import("./transform-N4UK7EOP.js");
|
|
1361
1518
|
const padding = {};
|
|
1362
1519
|
if (typeof flags["pad-start"] === "string") {
|
|
1363
1520
|
padding.padStartMs = parseDuration(flags["pad-start"]);
|
|
@@ -1385,19 +1542,19 @@ async function main() {
|
|
|
1385
1542
|
console.log("");
|
|
1386
1543
|
console.log(chainResult.previewTable);
|
|
1387
1544
|
}
|
|
1388
|
-
const { runTransform } = await import("./transform-
|
|
1545
|
+
const { runTransform } = await import("./transform-N4UK7EOP.js");
|
|
1389
1546
|
await runTransform({ projectDir, progress });
|
|
1390
|
-
const { runPreview: runPreview2 } = await import("./preview-
|
|
1547
|
+
const { runPreview: runPreview2 } = await import("./preview-UUWVOX5Y.js");
|
|
1391
1548
|
await runPreview2({ projectDir, progress, port, noOpen: flags["no-open"] === true });
|
|
1392
1549
|
break;
|
|
1393
1550
|
}
|
|
1394
|
-
const { runPreview } = await import("./preview-
|
|
1551
|
+
const { runPreview } = await import("./preview-UUWVOX5Y.js");
|
|
1395
1552
|
await runPreview({ projectDir, progress, port, noOpen: flags["no-open"] === true });
|
|
1396
1553
|
break;
|
|
1397
1554
|
}
|
|
1398
1555
|
case "render": {
|
|
1399
1556
|
const { projectDir, progress } = requireProject();
|
|
1400
|
-
const { runRender } = await import("./render-
|
|
1557
|
+
const { runRender } = await import("./render-T2UXDN25.js");
|
|
1401
1558
|
await runRender({ projectDir, progress, draft: flags.draft === true });
|
|
1402
1559
|
break;
|
|
1403
1560
|
}
|
|
@@ -2,13 +2,13 @@ import {
|
|
|
2
2
|
canSync,
|
|
3
3
|
getBoardSyncConfig,
|
|
4
4
|
syncStepOutputs
|
|
5
|
-
} from "./chunk-
|
|
5
|
+
} from "./chunk-UTFBENVA.js";
|
|
6
6
|
import {
|
|
7
7
|
markComplete,
|
|
8
8
|
markError,
|
|
9
9
|
markInProgress,
|
|
10
10
|
writeProgress
|
|
11
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-GLABTDMO.js";
|
|
12
12
|
|
|
13
13
|
// src/cli/guided/steps/render.ts
|
|
14
14
|
import { execSync } from "child_process";
|
|
@@ -365,7 +365,7 @@ async function runRender(options) {
|
|
|
365
365
|
markComplete(progress, "render", outputExists ? [`remotion/out/${outputName}`] : void 0);
|
|
366
366
|
writeProgress(projectDir, progress);
|
|
367
367
|
if (canSync()) {
|
|
368
|
-
const syncConfig = getBoardSyncConfig();
|
|
368
|
+
const syncConfig = getBoardSyncConfig(progress.project.dataDir);
|
|
369
369
|
if (syncConfig) {
|
|
370
370
|
await syncStepOutputs(syncConfig, "render", resolve(projectDir, progress.project.dataDir));
|
|
371
371
|
}
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
canSync,
|
|
6
6
|
getBoardSyncConfig,
|
|
7
7
|
syncStepOutputs
|
|
8
|
-
} from "./chunk-
|
|
8
|
+
} from "./chunk-UTFBENVA.js";
|
|
9
9
|
import {
|
|
10
10
|
transformToRawData
|
|
11
11
|
} from "./chunk-4CGFDD2G.js";
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
markError,
|
|
15
15
|
markInProgress,
|
|
16
16
|
writeProgress
|
|
17
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-GLABTDMO.js";
|
|
18
18
|
import {
|
|
19
19
|
TimingFileSchema
|
|
20
20
|
} from "./chunk-SKRQW7PY.js";
|
|
@@ -745,7 +745,7 @@ Output written to ${progress.project.outputDir}/:`);
|
|
|
745
745
|
]);
|
|
746
746
|
writeProgress(projectDir, progress);
|
|
747
747
|
if (canSync()) {
|
|
748
|
-
const syncConfig = getBoardSyncConfig();
|
|
748
|
+
const syncConfig = getBoardSyncConfig(progress.project.dataDir);
|
|
749
749
|
if (syncConfig) {
|
|
750
750
|
await syncStepOutputs(syncConfig, "transform", outDir);
|
|
751
751
|
}
|