demofly 0.2.7 → 0.2.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/README.md +154 -0
  2. package/dist/commands/analyze.d.ts +3 -0
  3. package/dist/commands/analyze.d.ts.map +1 -0
  4. package/dist/commands/analyze.js +163 -0
  5. package/dist/commands/analyze.js.map +1 -0
  6. package/dist/commands/demos/get.d.ts.map +1 -1
  7. package/dist/commands/demos/get.js +3 -1
  8. package/dist/commands/demos/get.js.map +1 -1
  9. package/dist/commands/demos/open.d.ts.map +1 -1
  10. package/dist/commands/demos/open.js +3 -1
  11. package/dist/commands/demos/open.js.map +1 -1
  12. package/dist/commands/generate.d.ts.map +1 -1
  13. package/dist/commands/generate.js +575 -49
  14. package/dist/commands/generate.js.map +1 -1
  15. package/dist/commands/init.d.ts.map +1 -1
  16. package/dist/commands/init.js +50 -6
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/push.d.ts.map +1 -1
  19. package/dist/commands/push.js +23 -3
  20. package/dist/commands/push.js.map +1 -1
  21. package/dist/commands/render.d.ts.map +1 -1
  22. package/dist/commands/render.js +5 -2
  23. package/dist/commands/render.js.map +1 -1
  24. package/dist/commands/tts.d.ts.map +1 -1
  25. package/dist/commands/tts.js +127 -12
  26. package/dist/commands/tts.js.map +1 -1
  27. package/dist/commands/update.d.ts.map +1 -1
  28. package/dist/commands/update.js +19 -0
  29. package/dist/commands/update.js.map +1 -1
  30. package/dist/commands/voices/select.d.ts.map +1 -1
  31. package/dist/commands/voices/select.js +66 -11
  32. package/dist/commands/voices/select.js.map +1 -1
  33. package/dist/lib/audio-probe.d.ts +23 -0
  34. package/dist/lib/audio-probe.d.ts.map +1 -0
  35. package/dist/lib/audio-probe.js +59 -0
  36. package/dist/lib/audio-probe.js.map +1 -0
  37. package/dist/lib/demo-config.d.ts +7 -0
  38. package/dist/lib/demo-config.d.ts.map +1 -1
  39. package/dist/lib/demo-config.js +9 -0
  40. package/dist/lib/demo-config.js.map +1 -1
  41. package/dist/lib/edit-proposals.d.ts +48 -1
  42. package/dist/lib/edit-proposals.d.ts.map +1 -1
  43. package/dist/lib/edit-proposals.js +49 -0
  44. package/dist/lib/edit-proposals.js.map +1 -1
  45. package/dist/lib/push-project.d.ts +37 -0
  46. package/dist/lib/push-project.d.ts.map +1 -0
  47. package/dist/lib/push-project.js +194 -0
  48. package/dist/lib/push-project.js.map +1 -0
  49. package/dist/lib/resolve-demo.d.ts +9 -0
  50. package/dist/lib/resolve-demo.d.ts.map +1 -0
  51. package/dist/lib/resolve-demo.js +10 -0
  52. package/dist/lib/resolve-demo.js.map +1 -0
  53. package/dist/lib/retiming.js +47 -0
  54. package/dist/lib/retiming.js.map +1 -1
  55. package/dist/lib/scene-assembler.d.ts +29 -0
  56. package/dist/lib/scene-assembler.d.ts.map +1 -0
  57. package/dist/lib/scene-assembler.js +202 -0
  58. package/dist/lib/scene-assembler.js.map +1 -0
  59. package/dist/lib/voice-resolver.d.ts +4 -0
  60. package/dist/lib/voice-resolver.d.ts.map +1 -1
  61. package/dist/lib/voice-resolver.js +5 -2
  62. package/dist/lib/voice-resolver.js.map +1 -1
  63. package/package.json +1 -1
@@ -1,37 +1,53 @@
1
1
  import {} from "commander";
2
- import { existsSync } from "node:fs";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { resolve } from "node:path";
4
- import { generateAllAudio } from "../lib/tts.js";
4
+ import { generateAllAudio, parseTranscript } from "../lib/tts.js";
5
+ import { getToken } from "../lib/credentials.js";
6
+ import { createApiClient, getAppUrl } from "../lib/api-client.js";
7
+ import { getDefaultVoice } from "../lib/voice-config.js";
8
+ import { resolveVoice, buildAvailableVoices, isCloudVoice, KOKORO_VOICES, } from "../lib/voice-resolver.js";
9
+ import { generateCloudAudio, getSubscriptionStatus } from "../lib/cloud-tts.js";
5
10
  export function registerTtsCommand(program) {
6
11
  program
7
12
  .command("tts <project>")
8
13
  .description("Generate TTS audio from a project's transcript.md")
9
- .option("--voice <name>", "TTS voice name", "af_heart")
14
+ .option("--voice <name>", "TTS voice name")
15
+ .option("--provider <provider>", "TTS provider (e.g., elevenlabs, openai)")
10
16
  .option("--speed <multiplier>", "TTS speed multiplier", "1.0")
11
- .action((project, opts) => {
17
+ .action(async (project, opts) => {
12
18
  const projectDir = resolve(process.cwd(), "demofly", project);
13
19
  const transcriptPath = resolve(projectDir, "transcript.md");
14
20
  if (!existsSync(transcriptPath)) {
15
21
  console.error(`No transcript.md found in demofly/${project}/. Generate one with /demofly:create ${project} in Claude Code.`);
16
22
  process.exit(1);
17
23
  }
18
- const ttsOpts = {
19
- voice: opts.voice,
20
- speed: parseFloat(opts.speed),
21
- };
22
- console.log(`Generating TTS audio for project "${project}"...\n`);
24
+ const speed = parseFloat(opts.speed);
25
+ // Resolve the voice to use
26
+ const voice = await resolveVoiceForTts(opts.voice, opts.provider);
27
+ console.log(`Generating TTS audio for project "${project}"...`);
28
+ console.log(` Voice: ${voice.name} (${voice.provider})\n`);
23
29
  try {
24
- const results = generateAllAudio(transcriptPath, projectDir, ttsOpts);
30
+ let results;
31
+ if (isCloudVoice(voice)) {
32
+ results = await generateCloudTtsForProject(transcriptPath, projectDir, voice, speed);
33
+ }
34
+ else {
35
+ // Local Kokoro generation
36
+ const ttsOpts = {
37
+ voice: voice.providerId,
38
+ speed,
39
+ };
40
+ results = generateAllAudio(transcriptPath, projectDir, ttsOpts);
41
+ }
25
42
  if (results.length === 0) {
26
43
  console.log("No scenes found in transcript. Nothing to generate.");
27
44
  return;
28
45
  }
29
46
  const totalDuration = results.reduce((sum, r) => sum + r.durationS, 0);
30
- const peakMemory = Math.max(...results.map((r) => r.peakMemoryMb));
31
47
  console.log("\n--- demofly tts summary ---\n");
48
+ console.log(` Voice: ${voice.name} (${voice.provider})`);
32
49
  console.log(` Scenes: ${results.length}`);
33
50
  console.log(` Duration: ${totalDuration.toFixed(1)}s`);
34
- console.log(` Peak memory: ${peakMemory.toFixed(0)}MB`);
35
51
  console.log();
36
52
  }
37
53
  catch (error) {
@@ -41,4 +57,103 @@ export function registerTtsCommand(program) {
41
57
  }
42
58
  });
43
59
  }
60
+ /**
61
+ * Resolve the voice for TTS, fetching API voices if authenticated.
62
+ * Falls back to Kokoro if API is unreachable.
63
+ */
64
+ async function resolveVoiceForTts(voiceName, providerName) {
65
+ const defaultVoice = getDefaultVoice();
66
+ const name = voiceName ?? defaultVoice.name;
67
+ const provider = providerName ?? (voiceName ? undefined : defaultVoice.provider);
68
+ // Try to get API voices for resolution if authenticated
69
+ const token = await getToken();
70
+ let apiVoices;
71
+ if (token) {
72
+ try {
73
+ const api = createApiClient(token);
74
+ apiVoices = await api.get("/voices");
75
+ }
76
+ catch {
77
+ // API unreachable — proceed with local voices only
78
+ }
79
+ }
80
+ const available = buildAvailableVoices(apiVoices);
81
+ const resolved = resolveVoice(name, provider, available);
82
+ if (!resolved) {
83
+ // Voice not found — fall back to Kokoro default
84
+ console.warn(`Voice "${name}" not found. Using default Kokoro voice.\n`);
85
+ return {
86
+ name: "heart",
87
+ provider: "kokoro",
88
+ providerId: "af_heart",
89
+ tier: "free",
90
+ };
91
+ }
92
+ return resolved;
93
+ }
94
+ /**
95
+ * Generate cloud TTS for all scenes in a project.
96
+ * Falls back to Kokoro if the API is unavailable or user isn't subscribed.
97
+ */
98
+ async function generateCloudTtsForProject(transcriptPath, projectDir, voice, speed) {
99
+ const token = await getToken();
100
+ if (!token) {
101
+ return fallbackToKokoro(transcriptPath, projectDir, speed, "Not authenticated.");
102
+ }
103
+ const api = createApiClient(token);
104
+ // Check subscription
105
+ try {
106
+ const sub = await getSubscriptionStatus(api);
107
+ if (sub.plan !== "pro") {
108
+ return fallbackToKokoro(transcriptPath, projectDir, speed, `Premium voices require a Pro subscription. Upgrade at ${getAppUrl()}/upgrade`);
109
+ }
110
+ }
111
+ catch {
112
+ return fallbackToKokoro(transcriptPath, projectDir, speed, "Cloud TTS unavailable.");
113
+ }
114
+ const content = readFileSync(transcriptPath, "utf-8");
115
+ const scenes = parseTranscript(content);
116
+ if (scenes.length === 0)
117
+ return [];
118
+ const audioDir = resolve(projectDir, "audio");
119
+ if (!existsSync(audioDir)) {
120
+ mkdirSync(audioDir, { recursive: true });
121
+ }
122
+ const results = [];
123
+ for (const scene of scenes) {
124
+ console.log(` TTS: ${scene.sceneId} (${scene.text.length} chars)`);
125
+ try {
126
+ const start = performance.now();
127
+ const { audio, durationS } = await generateCloudAudio(scene.text, voice.providerId, voice.provider, api, { speed });
128
+ const elapsedS = (performance.now() - start) / 1000;
129
+ const outputPath = resolve(audioDir, `${scene.sceneId}.mp3`);
130
+ writeFileSync(outputPath, Buffer.from(audio));
131
+ results.push({
132
+ sceneId: scene.sceneId,
133
+ filePath: outputPath,
134
+ durationS,
135
+ peakMemoryMb: 0,
136
+ elapsedS,
137
+ });
138
+ console.log(` -> ${durationS.toFixed(1)}s audio, ${elapsedS.toFixed(1)}s elapsed`);
139
+ }
140
+ catch (err) {
141
+ if (err.status === 403) {
142
+ return fallbackToKokoro(transcriptPath, projectDir, speed, `Premium voices require a Pro subscription. Using local voice instead. Upgrade at ${getAppUrl()}/upgrade`);
143
+ }
144
+ // Network/server error on individual scene — warn and fall back entirely
145
+ console.warn(` Cloud TTS failed for ${scene.sceneId}: ${err.message}`);
146
+ return fallbackToKokoro(transcriptPath, projectDir, speed, "Cloud TTS unavailable, falling back to local voice.");
147
+ }
148
+ }
149
+ return results;
150
+ }
151
+ function fallbackToKokoro(transcriptPath, projectDir, speed, reason) {
152
+ console.warn(`${reason} Falling back to Kokoro.\n`);
153
+ const defaultKokoro = KOKORO_VOICES[0];
154
+ return generateAllAudio(transcriptPath, projectDir, {
155
+ voice: defaultKokoro.kokoroId,
156
+ speed,
157
+ });
158
+ }
44
159
  //# sourceMappingURL=tts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tts.js","sourceRoot":"","sources":["../../src/commands/tts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGjD,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO;SACJ,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,mDAAmD,CAAC;SAChE,MAAM,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,UAAU,CAAC;SACtD,MAAM,CAAC,sBAAsB,EAAE,sBAAsB,EAAE,KAAK,CAAC;SAC7D,MAAM,CAAC,CAAC,OAAe,EAAE,IAAsC,EAAE,EAAE;QAClE,MAAM,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC9D,MAAM,cAAc,GAAG,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC;QAE5D,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CACX,qCAAqC,OAAO,wCAAwC,OAAO,kBAAkB,CAC9G,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAe;YAC1B,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC;SAC9B,CAAC;QAEF,OAAO,CAAC,GAAG,CAAC,qCAAqC,OAAO,QAAQ,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,gBAAgB,CAAC,cAAc,EAAE,UAAU,EAAE,OAAO,CAAC,CAAC;YAEtE,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;gBACnE,OAAO;YACT,CAAC;YAED,MAAM,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;YACvE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC;YAEnE,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;YAC/C,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;YAChD,OAAO,CAAC,GAAG,CAAC,kBAAkB,aAAa,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAC3D,OAAO,CAAC,GAAG,CAAC,kBAAkB,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YACzD,OAAO,CAAC,GAAG,EAAE,CAAC;QAChB,CAAC;QAAC,OAAO,KAAc,EAAE,CAAC;YACxB,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,0BAA0B,OAAO,EAAE,CAAC,CAAC;YACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"tts.js","sourceRoot":"","sources":["../../src/commands/tts.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAczC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAqD5D"}
1
+ {"version":3,"file":"update.d.ts","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAezC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA8E5D"}
@@ -2,6 +2,7 @@ import {} from "commander";
2
2
  import { execSync } from "node:child_process";
3
3
  import chalk from "chalk";
4
4
  import { VERSION } from "../lib/version.js";
5
+ import { commandExists } from "../lib/checks.js";
5
6
  async function fetchLatestVersion() {
6
7
  const response = await fetch("https://registry.npmjs.org/demofly/latest");
7
8
  if (!response.ok) {
@@ -49,6 +50,24 @@ export function registerUpdateCommand(program) {
49
50
  console.error(chalk.dim(" sudo npm install -g demofly@latest"));
50
51
  process.exit(1);
51
52
  }
53
+ // Update the Demofly Claude Code plugin
54
+ if (!commandExists("claude")) {
55
+ console.log(chalk.yellow("\nCould not update Demofly plugin: claude CLI not found."));
56
+ console.log(chalk.dim(" Run manually: claude plugin update demofly@demofly-marketplace"));
57
+ }
58
+ else {
59
+ try {
60
+ console.log("\nUpdating Demofly plugin...");
61
+ execSync("claude plugin update demofly@demofly-marketplace", {
62
+ stdio: "inherit",
63
+ });
64
+ console.log(chalk.green("Demofly plugin updated."));
65
+ }
66
+ catch {
67
+ console.log(chalk.yellow("\nDemofly plugin update failed."));
68
+ console.log(chalk.dim(" Run manually: claude plugin update demofly@demofly-marketplace"));
69
+ }
70
+ }
52
71
  });
53
72
  }
54
73
  //# sourceMappingURL=update.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAE5C,KAAK,UAAU,kBAAkB;IAC/B,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC1E,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IAC9D,CAAC;IACD,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;IAC5D,OAAO,IAAI,CAAC,OAAO,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,qBAAqB,CAAC,OAAgB;IACpD,OAAO;SACJ,OAAO,CAAC,QAAQ,CAAC;SACjB,WAAW,CAAC,0CAA0C,CAAC;SACvD,MAAM,CAAC,SAAS,EAAE,sCAAsC,CAAC;SACzD,MAAM,CAAC,KAAK,EAAE,IAAyB,EAAE,EAAE;QAC1C,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,MAAM,kBAAkB,EAAE,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,6DAA6D,CAAC,CACzE,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QAED,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,OAAO,GAAG,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAC9C,OAAO,CAAC,GAAG,CAAC,YAAY,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC/C,OAAO,CAAC,GAAG,CACT,SAAS,KAAK,CAAC,IAAI,CAAC,gBAAgB,CAAC,cAAc,CACpD,CAAC;YACJ,CAAC;YACD,OAAO;QACT,CAAC;QAED,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,wBAAwB,OAAO,GAAG,CAAC,CAAC,CAAC;YAC7D,OAAO;QACT,CAAC;QAED,OAAO,CAAC,GAAG,CACT,oBAAoB,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CACrE,CAAC;QAEF,IAAI,CAAC;YACH,QAAQ,CAAC,+BAA+B,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC;YAChE,OAAO,CAAC,GAAG,CACT,KAAK,CAAC,KAAK,CAAC,8BAA8B,MAAM,EAAE,CAAC,CACpD,CAAC;QACJ,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CACrE,CAAC;YACF,OAAO,CAAC,KAAK,CACX,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAClD,CAAC;YACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"update.js","sourceRoot":"","sources":["../../src/commands/update.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/commands/voices/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AAyBzC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CA+E3D"}
1
+ {"version":3,"file":"select.d.ts","sourceRoot":"","sources":["../../../src/commands/voices/select.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,WAAW,CAAC;AA4BzC,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,OAAO,GAAG,IAAI,CAyI3D"}
@@ -1,9 +1,12 @@
1
1
  import {} from "commander";
2
2
  import { createInterface } from "node:readline";
3
+ import { existsSync } from "node:fs";
4
+ import { resolve } from "node:path";
3
5
  import { getToken } from "../../lib/credentials.js";
4
6
  import { createApiClient, getAppUrl } from "../../lib/api-client.js";
5
7
  import { setDefaultVoice, getDefaultVoice } from "../../lib/voice-config.js";
6
- import { KOKORO_VOICES } from "../../lib/voice-resolver.js";
8
+ import { getDemoVoicePreference, setDemoVoicePreference } from "../../lib/demo-config.js";
9
+ import { KOKORO_VOICES, resolveVoice, buildAvailableVoices } from "../../lib/voice-resolver.js";
7
10
  function prompt(question) {
8
11
  const rl = createInterface({ input: process.stdin, output: process.stdout });
9
12
  return new Promise((resolve) => {
@@ -15,11 +18,22 @@ function prompt(question) {
15
18
  }
16
19
  export function registerSelectCommand(voices) {
17
20
  voices
18
- .command("select")
19
- .description("Choose default voice interactively")
20
- .action(async () => {
21
+ .command("select [demo]")
22
+ .description("Choose default voice interactively (or set voice for a specific demo)")
23
+ .option("--voice <id>", "Set voice directly without interactive picker")
24
+ .action(async (demo, opts) => {
25
+ // Validate demo directory if provided
26
+ let demoDir = null;
27
+ if (demo) {
28
+ demoDir = resolve(process.cwd(), "demofly", demo);
29
+ const configPath = resolve(demoDir, "demofly.json");
30
+ if (!existsSync(demoDir) || !existsSync(configPath)) {
31
+ console.error(`Demo '${demo}' not found. Check the demo name and try again.`);
32
+ process.exit(1);
33
+ }
34
+ }
21
35
  const token = await getToken();
22
- const currentDefault = getDefaultVoice();
36
+ // Build voice choices
23
37
  const choices = KOKORO_VOICES.map((v) => ({
24
38
  name: v.name,
25
39
  provider: "kokoro",
@@ -27,6 +41,7 @@ export function registerSelectCommand(voices) {
27
41
  label: `${v.name} (kokoro)`,
28
42
  }));
29
43
  let isPro = false;
44
+ let apiVoices = null;
30
45
  if (token) {
31
46
  const api = createApiClient(token);
32
47
  const [subRes, voicesRes] = await Promise.all([
@@ -34,6 +49,7 @@ export function registerSelectCommand(voices) {
34
49
  api.get("/voices").catch(() => null),
35
50
  ]);
36
51
  isPro = subRes?.plan === "pro";
52
+ apiVoices = voicesRes;
37
53
  if (voicesRes) {
38
54
  for (const v of voicesRes) {
39
55
  if (v.provider === "kokoro" || v.provider === "orpheus")
@@ -51,12 +67,45 @@ export function registerSelectCommand(voices) {
51
67
  console.log("Could not reach Demofly API. Showing local voices only.\n");
52
68
  }
53
69
  }
70
+ // Direct voice selection via --voice flag
71
+ if (opts.voice) {
72
+ const available = buildAvailableVoices(apiVoices?.map((v) => ({
73
+ voiceName: v.voiceName,
74
+ provider: v.provider,
75
+ voiceId: v.voiceId,
76
+ providerId: v.providerId,
77
+ tier: v.tier,
78
+ })) ?? undefined);
79
+ const resolved = resolveVoice(opts.voice, undefined, available);
80
+ if (!resolved) {
81
+ console.error(`Voice "${opts.voice}" not found. Run \`demofly voices list\` to see available voices.`);
82
+ process.exit(1);
83
+ }
84
+ if (resolved.tier === "premium" && !isPro) {
85
+ console.log(`This is a premium voice. Upgrade to Pro to use it: ${getAppUrl()}/upgrade`);
86
+ return;
87
+ }
88
+ if (demoDir) {
89
+ setDemoVoicePreference(demoDir, { name: resolved.name, provider: resolved.provider });
90
+ console.log(`Voice for ${demo} set to ${resolved.name} (${resolved.provider})`);
91
+ }
92
+ else {
93
+ setDefaultVoice(resolved.name, resolved.provider);
94
+ console.log(`Default voice set to: ${resolved.name} (${resolved.provider})`);
95
+ }
96
+ return;
97
+ }
98
+ // Determine current voice for highlighting
99
+ const currentVoice = demoDir
100
+ ? getDemoVoicePreference(demoDir) ?? getDefaultVoice()
101
+ : getDefaultVoice();
54
102
  // Display numbered list
55
- console.log("Available voices:\n");
103
+ const target = demoDir ? `voice for ${demo}` : "default voice";
104
+ console.log(`Select ${target}:\n`);
56
105
  for (let i = 0; i < choices.length; i++) {
57
- const isDefault = choices[i].name === currentDefault.name &&
58
- choices[i].provider === currentDefault.provider;
59
- const marker = isDefault ? " (current)" : "";
106
+ const isCurrent = choices[i].name === currentVoice.name &&
107
+ choices[i].provider === currentVoice.provider;
108
+ const marker = isCurrent ? " (current)" : "";
60
109
  console.log(` ${(i + 1).toString().padStart(2)}. ${choices[i].label}${marker}`);
61
110
  }
62
111
  console.log();
@@ -72,8 +121,14 @@ export function registerSelectCommand(voices) {
72
121
  console.log(`This is a premium voice. Upgrade to Pro to use it: ${getAppUrl()}/upgrade`);
73
122
  return;
74
123
  }
75
- setDefaultVoice(selected.name, selected.provider);
76
- console.log(`Default voice set to: ${selected.name} (${selected.provider})`);
124
+ if (demoDir) {
125
+ setDemoVoicePreference(demoDir, { name: selected.name, provider: selected.provider });
126
+ console.log(`Voice for ${demo} set to ${selected.name} (${selected.provider})`);
127
+ }
128
+ else {
129
+ setDefaultVoice(selected.name, selected.provider);
130
+ console.log(`Default voice set to: ${selected.name} (${selected.provider})`);
131
+ }
77
132
  });
78
133
  }
79
134
  //# sourceMappingURL=select.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../src/commands/voices/select.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"select.js","sourceRoot":"","sources":["../../../src/commands/voices/select.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,23 @@
1
+ export declare function hasFfprobe(): boolean;
2
+ /**
3
+ * Probe audio file duration using ffprobe.
4
+ * Returns duration in milliseconds.
5
+ */
6
+ export declare function probeAudioDuration(filePath: string): number;
7
+ export type OverflowSeverity = "ok" | "warning" | "critical";
8
+ export interface OverflowResult {
9
+ overflowMs: number;
10
+ severity: OverflowSeverity;
11
+ }
12
+ /**
13
+ * Compute overflow of audio duration relative to scene window.
14
+ * Positive overflowMs = audio is too long.
15
+ * Negative overflowMs = audio fits with room to spare.
16
+ *
17
+ * Severity thresholds:
18
+ * - ok: overflow <= 0
19
+ * - warning: overflow > 0 but <= 2000ms OR <= 30% of window (whichever is larger)
20
+ * - critical: overflow > 2000ms AND > 30% of window
21
+ */
22
+ export declare function computeOverflow(audioDurationMs: number, sceneWindowMs: number): OverflowResult;
23
+ //# sourceMappingURL=audio-probe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-probe.d.ts","sourceRoot":"","sources":["../../src/lib/audio-probe.ts"],"names":[],"mappings":"AAGA,wBAAgB,UAAU,IAAI,OAAO,CAOpC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuB3D;AAED,MAAM,MAAM,gBAAgB,GAAG,IAAI,GAAG,SAAS,GAAG,UAAU,CAAC;AAE7D,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B;AAED;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,eAAe,EAAE,MAAM,EACvB,aAAa,EAAE,MAAM,GACpB,cAAc,CAehB"}
@@ -0,0 +1,59 @@
1
+ import { execSync } from "node:child_process";
2
+ import { existsSync } from "node:fs";
3
+ export function hasFfprobe() {
4
+ try {
5
+ execSync("ffprobe -version", { stdio: "pipe" });
6
+ return true;
7
+ }
8
+ catch {
9
+ return false;
10
+ }
11
+ }
12
+ /**
13
+ * Probe audio file duration using ffprobe.
14
+ * Returns duration in milliseconds.
15
+ */
16
+ export function probeAudioDuration(filePath) {
17
+ if (!existsSync(filePath)) {
18
+ throw new Error(`Audio file not found: ${filePath}`);
19
+ }
20
+ try {
21
+ const output = execSync(`ffprobe -v error -show_entries format=duration -of csv=p=0 "${filePath}"`, { encoding: "utf-8", timeout: 30_000, stdio: ["pipe", "pipe", "pipe"] });
22
+ const seconds = parseFloat(output.trim());
23
+ if (Number.isNaN(seconds)) {
24
+ throw new Error(`ffprobe returned non-numeric duration: ${output.trim()}`);
25
+ }
26
+ return Math.round(seconds * 1000);
27
+ }
28
+ catch (error) {
29
+ if (error instanceof Error && error.message.startsWith("Audio file not found")) {
30
+ throw error;
31
+ }
32
+ const execError = error;
33
+ const detail = execError.stderr || execError.message || "unknown error";
34
+ throw new Error(`ffprobe failed for ${filePath}: ${detail}`);
35
+ }
36
+ }
37
+ /**
38
+ * Compute overflow of audio duration relative to scene window.
39
+ * Positive overflowMs = audio is too long.
40
+ * Negative overflowMs = audio fits with room to spare.
41
+ *
42
+ * Severity thresholds:
43
+ * - ok: overflow <= 0
44
+ * - warning: overflow > 0 but <= 2000ms OR <= 30% of window (whichever is larger)
45
+ * - critical: overflow > 2000ms AND > 30% of window
46
+ */
47
+ export function computeOverflow(audioDurationMs, sceneWindowMs) {
48
+ const overflowMs = audioDurationMs - sceneWindowMs;
49
+ if (overflowMs <= 0) {
50
+ return { overflowMs, severity: "ok" };
51
+ }
52
+ const exceedsAbsolute = overflowMs > 2000;
53
+ const exceedsPercent = overflowMs > sceneWindowMs * 0.3;
54
+ if (exceedsAbsolute && exceedsPercent) {
55
+ return { overflowMs, severity: "critical" };
56
+ }
57
+ return { overflowMs, severity: "warning" };
58
+ }
59
+ //# sourceMappingURL=audio-probe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audio-probe.js","sourceRoot":"","sources":["../../src/lib/audio-probe.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAErC,MAAM,UAAU,UAAU;IACxB,IAAI,CAAC;QACH,QAAQ,CAAC,kBAAkB,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAChD,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,QAAgB;IACjD,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAC;IACvD,CAAC;IAED,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,QAAQ,CACrB,+DAA+D,QAAQ,GAAG,EAC1E,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,CACxE,CAAC;QACF,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,0CAA0C,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC7E,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,IAAI,CAAC,CAAC;IACpC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC/E,MAAM,KAAK,CAAC;QACd,CAAC;QACD,MAAM,SAAS,GAAG,KAA8C,CAAC;QACjE,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,IAAI,SAAS,CAAC,OAAO,IAAI,eAAe,CAAC;QACxE,MAAM,IAAI,KAAK,CAAC,sBAAsB,QAAQ,KAAK,MAAM,EAAE,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AASD;;;;;;;;;GASG;AACH,MAAM,UAAU,eAAe,CAC7B,eAAuB,EACvB,aAAqB;IAErB,MAAM,UAAU,GAAG,eAAe,GAAG,aAAa,CAAC;IAEnD,IAAI,UAAU,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;IACxC,CAAC;IAED,MAAM,eAAe,GAAG,UAAU,GAAG,IAAI,CAAC;IAC1C,MAAM,cAAc,GAAG,UAAU,GAAG,aAAa,GAAG,GAAG,CAAC;IAExD,IAAI,eAAe,IAAI,cAAc,EAAE,CAAC;QACtC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAC9C,CAAC;IAED,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AAC7C,CAAC"}
@@ -1,8 +1,15 @@
1
+ export interface VoicePreference {
2
+ name: string;
3
+ provider: string;
4
+ }
1
5
  export interface DemoConfig {
2
6
  projectSlug: string;
3
7
  cloudDemoId?: string;
8
+ voicePreference?: VoicePreference;
4
9
  }
5
10
  export declare function readDemoConfig(projectDir: string): DemoConfig | null;
6
11
  export declare function writeDemoConfig(projectDir: string, config: DemoConfig): void;
12
+ export declare function getDemoVoicePreference(projectDir: string): VoicePreference | null;
13
+ export declare function setDemoVoicePreference(projectDir: string, voice: VoicePreference): void;
7
14
  export declare function ensureProjectSlug(projectDir: string): string;
8
15
  //# sourceMappingURL=demo-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"demo-config.d.ts","sourceRoot":"","sources":["../../src/lib/demo-config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAID,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQpE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAG5E;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAU5D"}
1
+ {"version":3,"file":"demo-config.d.ts","sourceRoot":"","sources":["../../src/lib/demo-config.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,eAAe,CAAC;CACnC;AAID,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI,CAQpE;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,IAAI,CAG5E;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAGjF;AAED,wBAAgB,sBAAsB,CAAC,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,GAAG,IAAI,CAIvF;AAED,wBAAgB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAU5D"}
@@ -16,6 +16,15 @@ export function writeDemoConfig(projectDir, config) {
16
16
  const configPath = resolve(projectDir, CONFIG_FILE);
17
17
  writeFileSync(configPath, JSON.stringify(config, null, 2) + "\n");
18
18
  }
19
+ export function getDemoVoicePreference(projectDir) {
20
+ const config = readDemoConfig(projectDir);
21
+ return config?.voicePreference ?? null;
22
+ }
23
+ export function setDemoVoicePreference(projectDir, voice) {
24
+ const existing = readDemoConfig(projectDir);
25
+ const config = { projectSlug: basename(projectDir), ...existing, voicePreference: voice };
26
+ writeDemoConfig(projectDir, config);
27
+ }
19
28
  export function ensureProjectSlug(projectDir) {
20
29
  const existing = readDemoConfig(projectDir);
21
30
  if (existing?.projectSlug) {
@@ -1 +1 @@
1
- {"version":3,"file":"demo-config.js","sourceRoot":"","sources":["../../src/lib/demo-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAO9C,MAAM,WAAW,GAAG,cAAc,CAAC;AAEnC,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,MAAkB;IACpE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,WAAW,CAAC;IAC9B,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAe,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;IACpE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC;AACpB,CAAC"}
1
+ {"version":3,"file":"demo-config.js","sourceRoot":"","sources":["../../src/lib/demo-config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAa9C,MAAM,WAAW,GAAG,cAAc,CAAC;AAEnC,MAAM,UAAU,cAAc,CAAC,UAAkB;IAC/C,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,MAAkB;IACpE,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC;IACpD,aAAa,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACvD,MAAM,MAAM,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC1C,OAAO,MAAM,EAAE,eAAe,IAAI,IAAI,CAAC;AACzC,CAAC;AAED,MAAM,UAAU,sBAAsB,CAAC,UAAkB,EAAE,KAAsB;IAC/E,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,MAAM,MAAM,GAAe,EAAE,WAAW,EAAE,QAAQ,CAAC,UAAU,CAAC,EAAE,GAAG,QAAQ,EAAE,eAAe,EAAE,KAAK,EAAE,CAAC;IACtG,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;AACtC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,UAAkB;IAClD,MAAM,QAAQ,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC;IAC5C,IAAI,QAAQ,EAAE,WAAW,EAAE,CAAC;QAC1B,OAAO,QAAQ,CAAC,WAAW,CAAC;IAC9B,CAAC;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,CAAC;IACxC,MAAM,MAAM,GAAe,EAAE,WAAW,EAAE,UAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;IACpE,eAAe,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IACpC,OAAO,UAAU,CAAC;AACpB,CAAC"}
@@ -8,16 +8,39 @@
8
8
  * data, hero moment awareness, and assembly best practices.
9
9
  */
10
10
  import type { AlignmentData } from "./alignment.js";
11
- export type EditType = "speed_video" | "slow_video" | "freeze_frame" | "trim_silence" | "insert_crossfade" | "pad_silence" | "no_change";
11
+ export type EditType = "speed_video" | "slow_video" | "freeze_frame" | "trim_silence" | "insert_crossfade" | "pad_silence" | "no_change" | "cut_segment" | "speed_segment";
12
12
  export interface EditDecision {
13
13
  beatId: string;
14
+ sceneId?: string;
14
15
  editType: EditType;
15
16
  segmentStartMs: number;
16
17
  segmentEndMs: number;
17
18
  targetDurationMs: number;
19
+ speedFactor?: number;
18
20
  rationale: string;
19
21
  confidence: number;
20
22
  }
23
+ export interface DeadTimeCandidate {
24
+ sceneId: string;
25
+ startMs: number;
26
+ endMs: number;
27
+ gapMs: number;
28
+ hasNarration: boolean;
29
+ }
30
+ export interface DeterministicSignals {
31
+ deadTimeCandidates: DeadTimeCandidate[];
32
+ silenceSegments: {
33
+ sceneId: string;
34
+ startMs: number;
35
+ endMs: number;
36
+ }[];
37
+ durationDrift: {
38
+ sceneId: string;
39
+ audioDurationMs: number;
40
+ videoDurationMs: number;
41
+ driftMs: number;
42
+ }[];
43
+ }
21
44
  export interface EditDecisionsData {
22
45
  decisions: EditDecision[];
23
46
  skipped: EditDecision[];
@@ -39,6 +62,30 @@ export interface EditDecisionsData {
39
62
  * based on visual content).
40
63
  */
41
64
  export declare function generateEditProposals(alignment: AlignmentData, heroSceneIds?: string[]): EditDecisionsData;
65
+ /**
66
+ * Detect dead time segments within scenes: gaps between timing markers
67
+ * that exceed a threshold with no corresponding narration coverage.
68
+ */
69
+ export declare function detectDeadTime(timingData: import("./timing.js").TimingData, narrationBeats?: {
70
+ sceneId: string;
71
+ startMs: number;
72
+ endMs: number;
73
+ }[], thresholdMs?: number): DeadTimeCandidate[];
74
+ /**
75
+ * Build deterministic signals for the LLM edit decision engine.
76
+ */
77
+ export declare function buildDeterministicSignals(timingData: import("./timing.js").TimingData, audioDurations?: {
78
+ sceneId: string;
79
+ durationMs: number;
80
+ }[], narrationBeats?: {
81
+ sceneId: string;
82
+ startMs: number;
83
+ endMs: number;
84
+ }[], silenceSegments?: {
85
+ sceneId: string;
86
+ startMs: number;
87
+ endMs: number;
88
+ }[]): DeterministicSignals;
42
89
  /**
43
90
  * Generate edit proposals and write to recordings/edit-decisions.json.
44
91
  */
@@ -1 +1 @@
1
- {"version":3,"file":"edit-proposals.d.ts","sourceRoot":"","sources":["../../src/lib/edit-proposals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAGnE,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,YAAY,GACZ,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,aAAa,GACb,WAAW,CAAC;AAEhB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,aAAa,EACxB,YAAY,GAAE,MAAM,EAAO,GAC1B,iBAAiB,CA2BnB;AAwGD;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAAM,EAAO,GAC1B,iBAAiB,GAAG,IAAI,CAqB1B"}
1
+ {"version":3,"file":"edit-proposals.d.ts","sourceRoot":"","sources":["../../src/lib/edit-proposals.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,OAAO,KAAK,EAAE,aAAa,EAAiB,MAAM,gBAAgB,CAAC;AAGnE,MAAM,MAAM,QAAQ,GAChB,aAAa,GACb,YAAY,GACZ,cAAc,GACd,cAAc,GACd,kBAAkB,GAClB,aAAa,GACb,WAAW,GACX,aAAa,GACb,eAAe,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,CAAC;IACnB,cAAc,EAAE,MAAM,CAAC;IACvB,YAAY,EAAE,MAAM,CAAC;IACrB,gBAAgB,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,oBAAoB;IACnC,kBAAkB,EAAE,iBAAiB,EAAE,CAAC;IACxC,eAAe,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvE,aAAa,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,eAAe,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACzG;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAUD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,aAAa,EACxB,YAAY,GAAE,MAAM,EAAO,GAC1B,iBAAiB,CA2BnB;AAwGD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,UAAU,EAAE,OAAO,aAAa,EAAE,UAAU,EAC5C,cAAc,GAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAO,EAC1E,WAAW,SAAO,GACjB,iBAAiB,EAAE,CAiCrB;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,UAAU,EAAE,OAAO,aAAa,EAAE,UAAU,EAC5C,cAAc,GAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,EAAO,EAC9D,cAAc,GAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAO,EAC1E,eAAe,GAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,EAAO,GAC1E,oBAAoB,CAgBtB;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC3C,UAAU,EAAE,MAAM,EAClB,YAAY,GAAE,MAAM,EAAO,GAC1B,iBAAiB,GAAG,IAAI,CAqB1B"}