miriad-viz 0.4.1 → 0.4.3

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.
@@ -189,6 +189,7 @@ function findProjectDir(startDir) {
189
189
  }
190
190
 
191
191
  export {
192
+ STEPS,
192
193
  createProgressFile,
193
194
  getNextStep,
194
195
  STEP_CONFIG,
@@ -9,7 +9,7 @@ import {
9
9
  markComplete,
10
10
  markInProgress,
11
11
  writeProgress
12
- } from "./chunk-X2MHAVAE.js";
12
+ } from "./chunk-GPVKAGZT.js";
13
13
 
14
14
  // src/cli/guided/steps/curate.ts
15
15
  import { existsSync, readFileSync, writeFileSync } from "fs";
@@ -11,7 +11,7 @@ import {
11
11
  markError,
12
12
  markInProgress,
13
13
  writeProgress
14
- } from "./chunk-X2MHAVAE.js";
14
+ } from "./chunk-GPVKAGZT.js";
15
15
 
16
16
  // src/cli/guided/steps/extract.ts
17
17
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "fs";
package/dist-cli/index.js CHANGED
@@ -1,12 +1,13 @@
1
1
  import {
2
2
  PROGRESS_FILENAME,
3
+ STEPS,
3
4
  STEP_CONFIG,
4
5
  createProgressFile,
5
6
  findProjectDir,
6
7
  getNextStep,
7
8
  readProgress,
8
9
  writeProgress
9
- } from "./chunk-X2MHAVAE.js";
10
+ } from "./chunk-GPVKAGZT.js";
10
11
 
11
12
  // src/cli/guided/index.ts
12
13
  import { existsSync as existsSync3, readFileSync as readFileSync2, readdirSync } from "fs";
@@ -504,7 +505,9 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
504
505
  output.push(" search around turning points, find the best quotes");
505
506
  output.push(" 3. Write script.json with ordered narration lines");
506
507
  output.push(" 4. ALSO propose: phases, milestones, featured quotes (curation)");
507
- output.push(" 5. Present to human and iterate");
508
+ output.push(" 5. Curate chat pills: pick 10-20 standout messages, suggest placement");
509
+ output.push(" aligned with narration beats (think in %, not timestamps)");
510
+ output.push(" 6. Present to human and iterate");
508
511
  output.push("");
509
512
  output.push(" Script format:");
510
513
  output.push(' { "version": 1, "lines": [');
@@ -517,7 +520,7 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
517
520
  output.push(" Save as: data/script.json");
518
521
  output.push("");
519
522
  output.push(" When human approves: npx miriad-viz next --script-approved");
520
- const scriptDoc = readBundledDoc("script-writing");
523
+ const scriptDoc = readBundledDoc("miriad-viz-script-writing");
521
524
  if (scriptDoc) {
522
525
  output.push("");
523
526
  output.push("\u2501\u2501\u2501 SCRIPT WRITING GUIDE \u2501\u2501\u2501");
@@ -627,24 +630,27 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
627
630
  output.push(" Each line has an id, speaker, text, and style.");
628
631
  output.push("");
629
632
  output.push(" WORKFLOW:");
630
- output.push(" 1. Ask human about voice preferences per speaker");
631
- output.push(" 2. Generate one audio file per script line");
632
- output.push(" 3. Save as: audio/{lineId}.mp3");
633
+ output.push(
634
+ " 1. List available voices: GET /v1/voices (header: xi-api-key: $ELEVENLABS_API_KEY)"
635
+ );
636
+ output.push(" 2. Read data/script.json \u2014 get speakers and line counts");
637
+ output.push(' 3. Suggest a voice for each speaker (be proactive, not "what do you want?")');
638
+ output.push(" 4. Generate one test clip per speaker for human approval");
639
+ output.push(" 5. Generate all clips: audio/{lineId}.mp3");
633
640
  output.push(" \u26A0\uFE0F Filename MUST match script line ID exactly");
634
641
  output.push(" narrator-01 \u2192 audio/narrator-01.mp3");
635
- output.push(" 4. Human listens and gives feedback");
636
- output.push(" 5. Regenerate specific lines as needed");
642
+ output.push(" 6. Human listens and gives feedback");
643
+ output.push(" 7. Regenerate specific lines as needed");
637
644
  output.push("");
638
- output.push(" CAPABILITIES:");
639
- output.push(" \u{1F5E3}\uFE0F Text-to-Speech \u2014 multi-speaker with distinct voices");
640
- output.push(" API: POST /v1/text-to-speech/{voice_id}");
641
- output.push(" Voices: https://elevenlabs.io/voice-library");
645
+ output.push(" API:");
646
+ output.push(" \u{1F50D} List voices: GET /v1/voices");
647
+ output.push(" \u{1F5E3}\uFE0F Generate clip: POST /v1/text-to-speech/{voice_id}");
642
648
  output.push("");
643
649
  output.push(" When approved: npx miriad-viz next --voices-approved");
644
650
  output.push("");
645
651
  output.push(" To skip voices and render a silent video:");
646
652
  output.push(" npx miriad-viz next --skip-audio");
647
- const voicesDoc = readBundledDoc("voice-generation");
653
+ const voicesDoc = readBundledDoc("miriad-viz-voice-generation");
648
654
  if (voicesDoc) {
649
655
  output.push("");
650
656
  output.push("\u2501\u2501\u2501 VOICE GENERATION GUIDE \u2501\u2501\u2501");
@@ -908,6 +914,35 @@ function computeNext(progress, existingFiles, logTails, flags = {}, dataSummary,
908
914
  return { action: "printed_command", step, command, progress, output };
909
915
  }
910
916
 
917
+ // src/cli/guided/show.ts
918
+ var VALID_SHOW_STEPS = STEPS.filter((s) => s !== "init");
919
+ function buildShowProgress(progress, stepName) {
920
+ if (!VALID_SHOW_STEPS.includes(stepName)) {
921
+ return {
922
+ error: `Unknown step: '${stepName}'. Valid steps: ${VALID_SHOW_STEPS.join(", ")}`
923
+ };
924
+ }
925
+ const targetStep = stepName;
926
+ const now = (/* @__PURE__ */ new Date()).toISOString();
927
+ const synthetic = {
928
+ ...progress,
929
+ steps: { ...progress.steps },
930
+ lastUpdated: now
931
+ };
932
+ let reachedTarget = false;
933
+ for (const step of STEPS) {
934
+ if (step === targetStep) {
935
+ synthetic.steps[step] = { status: "pending" };
936
+ reachedTarget = true;
937
+ } else if (!reachedTarget) {
938
+ synthetic.steps[step] = { status: "complete", completedAt: now };
939
+ } else {
940
+ synthetic.steps[step] = { status: "pending" };
941
+ }
942
+ }
943
+ return { progress: synthetic };
944
+ }
945
+
911
946
  // src/cli/guided/steps/init.ts
912
947
  import { existsSync as existsSync2, mkdirSync } from "fs";
913
948
  import { resolve as resolve2 } from "path";
@@ -1040,6 +1075,7 @@ Usage: npx miriad-viz <command> [options]
1040
1075
  Commands:
1041
1076
  init Initialize a new project
1042
1077
  next Advance to the next step
1078
+ show <step> Replay guidance for any step
1043
1079
  status Show current progress
1044
1080
  extract Run data extraction
1045
1081
  curate Generate curation scaffolds
@@ -1211,7 +1247,7 @@ async function main() {
1211
1247
  }
1212
1248
  case "extract": {
1213
1249
  const { projectDir, progress } = requireProject();
1214
- const { runExtract } = await import("./extract-7SPUMODE.js");
1250
+ const { runExtract } = await import("./extract-S5XKRYPG.js");
1215
1251
  await runExtract({
1216
1252
  projectDir,
1217
1253
  progress,
@@ -1225,14 +1261,14 @@ async function main() {
1225
1261
  }
1226
1262
  case "curate": {
1227
1263
  const { projectDir, progress } = requireProject();
1228
- const { runCurate } = await import("./curate-7VM5QLE2.js");
1264
+ const { runCurate } = await import("./curate-LBMQRKKG.js");
1229
1265
  await runCurate({ projectDir, progress });
1230
1266
  break;
1231
1267
  }
1232
1268
  case "transform": {
1233
1269
  const { projectDir, progress } = requireProject();
1234
1270
  const { parseDuration } = await import("./parse-duration-NVLCEFAF.js");
1235
- const { runTransform } = await import("./transform-BO6MECNO.js");
1271
+ const { runTransform } = await import("./transform-TEJWDQWZ.js");
1236
1272
  const padding = {};
1237
1273
  if (typeof flags["pad-start"] === "string") {
1238
1274
  padding.padStartMs = parseDuration(flags["pad-start"]);
@@ -1260,19 +1296,19 @@ async function main() {
1260
1296
  console.log("");
1261
1297
  console.log(chainResult.previewTable);
1262
1298
  }
1263
- const { runTransform } = await import("./transform-BO6MECNO.js");
1299
+ const { runTransform } = await import("./transform-TEJWDQWZ.js");
1264
1300
  await runTransform({ projectDir, progress });
1265
- const { runPreview: runPreview2 } = await import("./preview-QFLKQHQA.js");
1301
+ const { runPreview: runPreview2 } = await import("./preview-F7ILLPMG.js");
1266
1302
  await runPreview2({ projectDir, progress, port, noOpen: flags["no-open"] === true });
1267
1303
  break;
1268
1304
  }
1269
- const { runPreview } = await import("./preview-QFLKQHQA.js");
1305
+ const { runPreview } = await import("./preview-F7ILLPMG.js");
1270
1306
  await runPreview({ projectDir, progress, port, noOpen: flags["no-open"] === true });
1271
1307
  break;
1272
1308
  }
1273
1309
  case "render": {
1274
1310
  const { projectDir, progress } = requireProject();
1275
- const { runRender } = await import("./render-F5W4QY3Q.js");
1311
+ const { runRender } = await import("./render-TC223YOE.js");
1276
1312
  await runRender({ projectDir, progress, draft: flags.draft === true });
1277
1313
  break;
1278
1314
  }
@@ -1372,6 +1408,42 @@ async function main() {
1372
1408
  }
1373
1409
  break;
1374
1410
  }
1411
+ case "show": {
1412
+ const stepName = positional[0];
1413
+ if (!stepName) {
1414
+ console.error(
1415
+ `
1416
+ \u2717 Missing step name. Usage: npx miriad-viz show <step>
1417
+ Valid steps: ${VALID_SHOW_STEPS.join(", ")}`
1418
+ );
1419
+ process.exit(1);
1420
+ }
1421
+ const { projectDir, progress } = requireProject();
1422
+ const showResult = buildShowProgress(progress, stepName);
1423
+ if (showResult.error) {
1424
+ console.error(`
1425
+ \u2717 ${showResult.error}`);
1426
+ process.exit(1);
1427
+ }
1428
+ const showFiles = [...gatherExistingFiles(projectDir), ...gatherAudioFiles(projectDir)];
1429
+ const showLogTails = gatherLogTails(projectDir);
1430
+ const showDataSummary = gatherDataSummary(projectDir, progress.project.dataDir);
1431
+ const showEnv = {
1432
+ hasElevenLabsKey: !!process.env.ELEVENLABS_API_KEY
1433
+ };
1434
+ const result = computeNext(
1435
+ showResult.progress,
1436
+ showFiles,
1437
+ showLogTails,
1438
+ {},
1439
+ showDataSummary,
1440
+ showEnv
1441
+ );
1442
+ for (const line of result.output) {
1443
+ console.log(line);
1444
+ }
1445
+ break;
1446
+ }
1375
1447
  case "help":
1376
1448
  case "--help":
1377
1449
  case "-h":
@@ -5,7 +5,7 @@ import {
5
5
  import {
6
6
  markComplete,
7
7
  writeProgress
8
- } from "./chunk-X2MHAVAE.js";
8
+ } from "./chunk-GPVKAGZT.js";
9
9
 
10
10
  // src/cli/guided/steps/preview.ts
11
11
  import { execSync } from "child_process";
@@ -3,7 +3,7 @@ import {
3
3
  markError,
4
4
  markInProgress,
5
5
  writeProgress
6
- } from "./chunk-X2MHAVAE.js";
6
+ } from "./chunk-GPVKAGZT.js";
7
7
 
8
8
  // src/cli/guided/steps/render.ts
9
9
  import { execSync } from "child_process";
@@ -9,7 +9,7 @@ import {
9
9
  markError,
10
10
  markInProgress,
11
11
  writeProgress
12
- } from "./chunk-X2MHAVAE.js";
12
+ } from "./chunk-GPVKAGZT.js";
13
13
  import {
14
14
  TimingFileSchema
15
15
  } from "./chunk-SKRQW7PY.js";
@@ -1768,7 +1768,13 @@ function GearIcon({ size = 14 }) {
1768
1768
  }
1769
1769
  );
1770
1770
  }
1771
- function Footer({ playback, frame, devMode, onToggleDev }) {
1771
+ function Footer({
1772
+ playback,
1773
+ frame,
1774
+ devMode,
1775
+ onToggleDev,
1776
+ hasTimingFile = false
1777
+ }) {
1772
1778
  const { progress, playing, speed, toggle, setSpeed, scrub } = playback;
1773
1779
  const handleKeyDown = react.useCallback(
1774
1780
  (e) => {
@@ -1780,12 +1786,14 @@ function Footer({ playback, frame, devMode, onToggleDev }) {
1780
1786
  break;
1781
1787
  }
1782
1788
  case "ArrowRight": {
1789
+ if (hasTimingFile) break;
1783
1790
  e.preventDefault();
1784
1791
  const idx = SPEEDS.indexOf(speed);
1785
1792
  if (idx < SPEEDS.length - 1) setSpeed(SPEEDS[idx + 1]);
1786
1793
  break;
1787
1794
  }
1788
1795
  case "ArrowLeft": {
1796
+ if (hasTimingFile) break;
1789
1797
  e.preventDefault();
1790
1798
  const idx = SPEEDS.indexOf(speed);
1791
1799
  if (idx > 0) setSpeed(SPEEDS[idx - 1]);
@@ -1808,7 +1816,7 @@ function Footer({ playback, frame, devMode, onToggleDev }) {
1808
1816
  }
1809
1817
  }
1810
1818
  },
1811
- [toggle, speed, setSpeed, scrub, onToggleDev]
1819
+ [toggle, speed, setSpeed, scrub, onToggleDev, hasTimingFile]
1812
1820
  );
1813
1821
  react.useEffect(() => {
1814
1822
  window.addEventListener("keydown", handleKeyDown);
@@ -1843,7 +1851,7 @@ function Footer({ playback, frame, devMode, onToggleDev }) {
1843
1851
  style: scrubberStyle
1844
1852
  }
1845
1853
  ),
1846
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: speedGroupStyle, children: SPEEDS.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
1854
+ !hasTimingFile && /* @__PURE__ */ jsxRuntime.jsx("div", { style: speedGroupStyle, children: SPEEDS.map((s) => /* @__PURE__ */ jsxRuntime.jsxs(
1847
1855
  "button",
1848
1856
  {
1849
1857
  type: "button",
@@ -2566,7 +2574,8 @@ function App() {
2566
2574
  playback,
2567
2575
  frame,
2568
2576
  devMode,
2569
- onToggleDev: toggleDevMode
2577
+ onToggleDev: toggleDevMode,
2578
+ hasTimingFile: timingFile !== null
2570
2579
  }
2571
2580
  )
2572
2581
  ] })