@tacone/prosey 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/bin/prosey CHANGED
@@ -103291,7 +103291,7 @@ function openInBrowser(htmlPath) {
103291
103291
  // package.json
103292
103292
  var package_default = {
103293
103293
  name: "@tacone/prosey",
103294
- version: "0.5.0",
103294
+ version: "0.6.0",
103295
103295
  description: "Download YouTube video transcripts from the CLI",
103296
103296
  module: "src/index.ts",
103297
103297
  type: "module",
@@ -122284,10 +122284,12 @@ try {
122284
122284
  const dir2 = cacheDir(videoId, cacheOpts2);
122285
122285
  let segments2 = null;
122286
122286
  let summary = null;
122287
+ let cachedInfo = null;
122287
122288
  startTimer();
122288
122289
  if (!noCache) {
122289
122290
  const cachedSegments = await readCache(dir2, "transcript.json");
122290
122291
  const cachedSummary = await readCache(dir2, "summary.md");
122292
+ cachedInfo = await readCache(dir2, "info.json");
122291
122293
  if (cachedSegments && cachedSummary) {
122292
122294
  info("Transcript cached");
122293
122295
  debug("Cache hit:", dir2);
@@ -122299,23 +122301,83 @@ try {
122299
122301
  } else {
122300
122302
  debug("Cache skipped (--no-cache)");
122301
122303
  }
122302
- if (!segments2) {
122303
- info("Fetching transcript...");
122304
- segments2 = lang ? await fetchTranscript(videoId, { lang }) : await fetchTranscript(videoId);
122305
- info(`Transcript: ${segments2.length} segments`);
122306
- await writeCache(dir2, "transcript.json", JSON.stringify(segments2));
122307
- debug("Cache written: transcript.json");
122308
- }
122309
122304
  const prompt2 = resolveSummarizePrompt(config) ?? "";
122310
122305
  if (!prompt2) {
122311
122306
  console.error("Error: no prompt configured. Set a prompt in the [summarize] section of your config.");
122312
122307
  exitProcess(1);
122313
122308
  }
122314
- const transcriptText = toText(segments2, !noDecode);
122309
+ let structuredContent;
122310
+ if (!segments2) {
122311
+ info("Fetching transcript...");
122312
+ const opts = lang ? { lang, videoDetails: true } : { videoDetails: true };
122313
+ const result = await fetchTranscript(videoId, opts);
122314
+ segments2 = result.segments;
122315
+ const infoJson = JSON.stringify({
122316
+ title: result.videoDetails.title,
122317
+ channel: result.videoDetails.author,
122318
+ description: result.videoDetails.description
122319
+ });
122320
+ cachedInfo = infoJson;
122321
+ const chapterValue = formatChaptersAsJson(extractChapters(result.videoDetails.description));
122322
+ const truncatedInfo = JSON.stringify({
122323
+ title: result.videoDetails.title,
122324
+ channel: result.videoDetails.author,
122325
+ description: result.videoDetails.description.slice(0, 1000)
122326
+ });
122327
+ const transcriptText = toText(segments2, !noDecode);
122328
+ structuredContent = `INFO:
122329
+ ${truncatedInfo}
122330
+
122331
+ TEXT:
122332
+ ${transcriptText}`;
122333
+ if (dryRun) {
122334
+ await outputText(`${prompt2}
122335
+
122336
+ ${structuredContent}
122337
+ `);
122338
+ exitProcess(0);
122339
+ }
122340
+ info(`Transcript: ${segments2.length} segments`);
122341
+ await writeCache(dir2, "transcript.json", JSON.stringify(segments2));
122342
+ await writeCache(dir2, "info.json", infoJson);
122343
+ await writeCache(dir2, "chapters.json", chapterValue);
122344
+ debug("Cache written: transcript.json, info.json, chapters.json");
122345
+ } else {
122346
+ let chapterValue;
122347
+ if (!cachedInfo) {
122348
+ debug("Cache missing info.json, re-fetching video details");
122349
+ const fallbackOpts = lang ? { lang, videoDetails: true } : { videoDetails: true };
122350
+ const fallbackResult = await fetchTranscript(videoId, fallbackOpts);
122351
+ cachedInfo = JSON.stringify({
122352
+ title: fallbackResult.videoDetails.title,
122353
+ channel: fallbackResult.videoDetails.author,
122354
+ description: fallbackResult.videoDetails.description
122355
+ });
122356
+ await writeCache(dir2, "info.json", cachedInfo);
122357
+ chapterValue = formatChaptersAsJson(extractChapters(fallbackResult.videoDetails.description));
122358
+ await writeCache(dir2, "chapters.json", chapterValue);
122359
+ debug("Cache written: info.json, chapters.json");
122360
+ } else {
122361
+ const cachedChapters = await readCache(dir2, "chapters.json");
122362
+ chapterValue = cachedChapters ?? "not available";
122363
+ }
122364
+ const transcriptText = toText(segments2, !noDecode);
122365
+ const cachedInfoObj = JSON.parse(cachedInfo);
122366
+ const truncatedInfo = JSON.stringify({
122367
+ title: cachedInfoObj.title,
122368
+ channel: cachedInfoObj.channel,
122369
+ description: cachedInfoObj.description.slice(0, 1000)
122370
+ });
122371
+ structuredContent = `INFO:
122372
+ ${truncatedInfo}
122373
+
122374
+ TEXT:
122375
+ ${transcriptText}`;
122376
+ }
122315
122377
  if (dryRun) {
122316
122378
  await outputText(`${prompt2}
122317
122379
 
122318
- ${transcriptText}
122380
+ ${structuredContent}
122319
122381
  `);
122320
122382
  exitProcess(0);
122321
122383
  }
@@ -122324,7 +122386,7 @@ ${transcriptText}
122324
122386
  summary = await summarize({
122325
122387
  prompt: prompt2,
122326
122388
  command: sumCmd,
122327
- transcript: transcriptText,
122389
+ transcript: structuredContent,
122328
122390
  cwd: dir2
122329
122391
  });
122330
122392
  info("Summary ready");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tacone/prosey",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "Download YouTube video transcripts from the CLI",
5
5
  "module": "src/index.ts",
6
6
  "type": "module",
@@ -29,7 +29,23 @@ command = "OPENCODE_PERMISSION='{\"read\":\"allow\",\"write\":\"deny\",\"edit\":
29
29
  # Customize this to change how transcripts are summarized.
30
30
 
31
31
  prompt = """
32
- Write a comprehensive summary of the following transcription.
32
+ Write a comprehensive summary of the following video transcription:
33
+
34
+ Guidelines:
35
+ - use the INFO section data to correct spellings in the text (e.g. Pi vs Pie)
36
+ - use the INFO title value as the main title (h1 header)
37
+ - use the TIMESTAMPS only to understand the structure, don't output time markers
38
+ - content length: aim to be the same range as the original text or more.
39
+ - section titles should be h2 headers
40
+
41
+ Content considerations:
42
+
43
+ - findings should be presented in lists or table
44
+ - flows should be presented in ordered lists
45
+ - elaborations are better in prose
46
+ - when content mixes types within a section, lead with prose and break out lists only for discrete items
47
+
48
+ Only output the summary text without adding anything.
33
49
  """
34
50
 
35
51
  # Command override for summarize. Uncomment to use a different command
package/src/index.ts CHANGED
@@ -443,12 +443,14 @@ try {
443
443
  const dir = cacheDir(videoId, cacheOpts);
444
444
  let segments: TranscriptSegment[] | null = null;
445
445
  let summary: string | null = null;
446
+ let cachedInfo: string | null = null;
446
447
 
447
448
  startTimer();
448
449
 
449
450
  if (!noCache) {
450
451
  const cachedSegments = await readCache(dir, "transcript.json");
451
452
  const cachedSummary = await readCache(dir, "summary.md");
453
+ cachedInfo = await readCache(dir, "info.json");
452
454
  if (cachedSegments && cachedSummary) {
453
455
  info("Transcript cached");
454
456
  debug("Cache hit:", dir);
@@ -461,14 +463,6 @@ try {
461
463
  debug("Cache skipped (--no-cache)");
462
464
  }
463
465
 
464
- if (!segments) {
465
- info("Fetching transcript...");
466
- segments = lang ? await fetchTranscript(videoId, { lang }) : await fetchTranscript(videoId);
467
- info(`Transcript: ${segments.length} segments`);
468
- await writeCache(dir, "transcript.json", JSON.stringify(segments));
469
- debug("Cache written: transcript.json");
470
- }
471
-
472
466
  const prompt = resolveSummarizePrompt(config) ?? "";
473
467
  if (!prompt) {
474
468
  console.error(
@@ -476,10 +470,80 @@ try {
476
470
  );
477
471
  exitProcess(1);
478
472
  }
479
- const transcriptText = toText(segments, !noDecode);
473
+
474
+ let structuredContent: string;
475
+
476
+ if (!segments) {
477
+ info("Fetching transcript...");
478
+ const opts = lang ? { lang, videoDetails: true as const } : { videoDetails: true as const };
479
+ const result = (await fetchTranscript(videoId, opts)) as {
480
+ videoDetails: VideoDetails;
481
+ segments: TranscriptSegment[];
482
+ };
483
+ segments = result.segments;
484
+ const infoJson = JSON.stringify({
485
+ title: result.videoDetails.title,
486
+ channel: result.videoDetails.author,
487
+ description: result.videoDetails.description,
488
+ });
489
+ cachedInfo = infoJson;
490
+ const chapterValue = formatChaptersAsJson(extractChapters(result.videoDetails.description));
491
+ const truncatedInfo = JSON.stringify({
492
+ title: result.videoDetails.title,
493
+ channel: result.videoDetails.author,
494
+ description: result.videoDetails.description.slice(0, 1000),
495
+ });
496
+ const transcriptText = toText(segments, !noDecode);
497
+ structuredContent = `INFO:\n${truncatedInfo}\n\nTEXT:\n${transcriptText}`;
498
+
499
+ if (dryRun) {
500
+ await outputText(`${prompt}\n\n${structuredContent}\n`);
501
+ exitProcess(0);
502
+ }
503
+
504
+ info(`Transcript: ${segments.length} segments`);
505
+ await writeCache(dir, "transcript.json", JSON.stringify(segments));
506
+ await writeCache(dir, "info.json", infoJson);
507
+ await writeCache(dir, "chapters.json", chapterValue);
508
+ debug("Cache written: transcript.json, info.json, chapters.json");
509
+ } else {
510
+ let chapterValue: string;
511
+ if (!cachedInfo) {
512
+ debug("Cache missing info.json, re-fetching video details");
513
+ const fallbackOpts = lang
514
+ ? { lang, videoDetails: true as const }
515
+ : { videoDetails: true as const };
516
+ const fallbackResult = (await fetchTranscript(videoId, fallbackOpts)) as {
517
+ videoDetails: VideoDetails;
518
+ segments: TranscriptSegment[];
519
+ };
520
+ cachedInfo = JSON.stringify({
521
+ title: fallbackResult.videoDetails.title,
522
+ channel: fallbackResult.videoDetails.author,
523
+ description: fallbackResult.videoDetails.description,
524
+ });
525
+ await writeCache(dir, "info.json", cachedInfo);
526
+ chapterValue = formatChaptersAsJson(
527
+ extractChapters(fallbackResult.videoDetails.description),
528
+ );
529
+ await writeCache(dir, "chapters.json", chapterValue);
530
+ debug("Cache written: info.json, chapters.json");
531
+ } else {
532
+ const cachedChapters = await readCache(dir, "chapters.json");
533
+ chapterValue = cachedChapters ?? "not available";
534
+ }
535
+ const transcriptText = toText(segments, !noDecode);
536
+ const cachedInfoObj = JSON.parse(cachedInfo);
537
+ const truncatedInfo = JSON.stringify({
538
+ title: cachedInfoObj.title,
539
+ channel: cachedInfoObj.channel,
540
+ description: cachedInfoObj.description.slice(0, 1000),
541
+ });
542
+ structuredContent = `INFO:\n${truncatedInfo}\n\nTEXT:\n${transcriptText}`;
543
+ }
480
544
 
481
545
  if (dryRun) {
482
- await outputText(`${prompt}\n\n${transcriptText}\n`);
546
+ await outputText(`${prompt}\n\n${structuredContent}\n`);
483
547
  exitProcess(0);
484
548
  }
485
549
 
@@ -488,7 +552,7 @@ try {
488
552
  summary = await summarize({
489
553
  prompt,
490
554
  command: sumCmd,
491
- transcript: transcriptText,
555
+ transcript: structuredContent,
492
556
  cwd: dir,
493
557
  });
494
558
  info("Summary ready");