UNPKG

summarizely-cli

Version:

YouTube summarizer that respects your existing subscriptions. No API keys required.

70 lines 3.33 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.buildPrompt = buildPrompt; function buildPrompt(cap, _videoId, opts) { // Free‑flow, narrative‑first summary prompt const metaLines = []; metaLines.push(`# ${cap.title}`); metaLines.push(''); metaLines.push(`**URL:** ${cap.url} `); if (cap.channel) metaLines.push(`**Channel:** ${cap.channel} `); if (cap.published) metaLines.push(`**Published:** ${cap.published} `); if (typeof cap.durationSec === 'number') metaLines.push(`**Duration:** ${formatDuration(cap.durationSec)} `); if (typeof cap.viewCount === 'number') metaLines.push(`**Views:** ${formatCompactNumber(cap.viewCount)} `); if (typeof cap.likeCount === 'number') metaLines.push(`**Likes:** ${formatCompactNumber(cap.likeCount)} `); metaLines.push('**Summary Type:** Full '); metaLines.push(`**Generated:** ${new Date().toISOString()}`); metaLines.push('\n---\n'); const guide = [ 'Write a vivid, free‑flowing Markdown summary that follows the video\'s natural narrative arc from start to finish.', 'Base everything on the transcript; let the speaker\'s flow lead the structure.', '', 'Guiding style:', '- Strong rhythm, succinct sentences, zero filler.', '- Chronological by default; compress repeats and tighten rambly bits.', '- Creative formatting as needed: micro‑headings, short bullets, callouts, side‑notes, pull quotes, tasteful emojis if they fit.', '- Weave in concrete specifics (names, numbers, terms, examples) where they naturally land.', '- Bold key phrases to anchor the eye. Do not add timestamps.', '- Finish with a brief “Highlights” ribbon and (optional) a tiny “Takeaways” list — keep both punchy.', '', 'Start your answer with this exact metadata block:', ...metaLines, 'Now write the summary.', ].join('\n'); // Collapse whitespace to keep input compact let transcript = (cap.transcript || '').replace(/\s+/g, ' ').trim(); const max = opts?.maxChars ?? Infinity; let truncNote = ''; if (transcript.length > max) { transcript = transcript.slice(0, max); truncNote = `\n\n(Note: transcript truncated to ${max.toLocaleString()} characters for processing.)`; } return `Title: ${cap.title}\nURL: ${cap.url}\n\n${guide}${truncNote}\n\nTranscript:\n${transcript}`; } // Helper for Claude CLI print mode: returns query (instructions) and body (transcript only) function formatDuration(totalSec) { const s = Math.max(0, Math.floor(totalSec)); const h = Math.floor(s / 3600); const m = Math.floor((s % 3600) / 60); const sec = s % 60; const mm = String(m).padStart(2, '0'); const ss = String(sec).padStart(2, '0'); return h > 0 ? `${h}:${mm}:${ss}` : `${m}:${ss}`; } function formatCompactNumber(n) { const abs = Math.abs(n); const trim = (x) => x.toFixed(1).replace(/\.0$/, ''); if (abs >= 1000000000) return `${trim(n / 1000000000)}B`; if (abs >= 1000000) return `${trim(n / 1000000)}M`; if (abs >= 1000) return `${trim(n / 1000)}K`; return Math.round(n).toLocaleString(); } //# sourceMappingURL=prompt.js.map