@liorium/youtube-omni-mcp 0.2.3 → 0.2.5

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/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.2.5 - 2026-05-14
4
+
5
+ - Add deeper read-only synthesis for transcript structure, claim-like moments, hook pattern classification, comment themes, and research briefs.
6
+ - Replace mock comment summarization with actual comment-text analysis for questions, requests, themes, and sentiment signals.
7
+ - Feed transcript hooks and comment signals into planning briefs with recommended angles and content opportunities.
8
+
9
+ ## 0.2.4 - 2026-05-14
10
+
11
+ - Replace the transcript placeholder provider with a read-only YouTube timedtext provider.
12
+ - Add resilient `yt-dlp` caption metadata fallback when watch-page caption URLs are missing or stale.
13
+ - Keep transcript calls non-destructive and unavailable-safe when captions cannot be fetched.
14
+
3
15
  ## 0.2.3 - 2026-05-14
4
16
 
5
17
  - Ensure the published `youtube-omni-mcp` CLI bin is executable after build so `npx -y @liorium/youtube-omni-mcp` can launch the MCP stdio server.
@@ -0,0 +1,50 @@
1
+ export type HookAnalysis = {
2
+ pattern: string;
3
+ reasons: string[];
4
+ };
5
+ export type CommentTheme = {
6
+ theme: string;
7
+ intent: string;
8
+ opportunity: string;
9
+ };
10
+ export declare function splitSentences(text: string): string[];
11
+ export declare function analyzeHookPattern(hook: string): HookAnalysis;
12
+ export declare function extractTranscriptStructure(text: string, includeClaims?: boolean): {
13
+ hook: string;
14
+ cta: string;
15
+ outline: {
16
+ section: string;
17
+ text: string;
18
+ purpose: string;
19
+ }[];
20
+ claims: {
21
+ text: string;
22
+ type: string;
23
+ evidenceStrength: string;
24
+ }[];
25
+ scriptPatterns: string[];
26
+ hookAnalysis: HookAnalysis;
27
+ };
28
+ export declare function classifyComment(text: string): CommentTheme;
29
+ export declare function summarizeCommentSet(comments: Array<{
30
+ text?: string;
31
+ likeCount?: number;
32
+ }>, includeQuestions?: boolean, includeRequests?: boolean): {
33
+ summary: string;
34
+ questions: string[];
35
+ contentRequests: string[];
36
+ themes: {
37
+ theme: string;
38
+ intent: string;
39
+ opportunity: string;
40
+ count: number;
41
+ examples: string[];
42
+ totalLikes: number;
43
+ }[];
44
+ sentimentSignal: {
45
+ positiveCount: number;
46
+ concernCount: number;
47
+ mixed: boolean;
48
+ dominant: string;
49
+ };
50
+ };
@@ -0,0 +1,143 @@
1
+ export function splitSentences(text) {
2
+ return text
3
+ .replace(/\s+/g, ' ')
4
+ .split(/(?<=[.!?])\s+/)
5
+ .map((sentence) => sentence.trim())
6
+ .filter(Boolean);
7
+ }
8
+ export function analyzeHookPattern(hook) {
9
+ const lower = hook.toLowerCase();
10
+ const reasons = [];
11
+ if (/^\s*(what|why|how|can|could|would|is|are|do|does|did)\b/i.test(hook) || hook.includes('?')) {
12
+ reasons.push('opens with a question');
13
+ }
14
+ if (lower.includes('secret') || lower.includes('hidden') || lower.includes('nobody') || lower.includes('what if')) {
15
+ reasons.push('creates a curiosity gap');
16
+ }
17
+ if (/\b(\d+|days?|steps?|experiments?|case study|rebuilt|result)\b/i.test(hook)) {
18
+ reasons.push('promises a concrete result');
19
+ }
20
+ if (lower.includes('but') || lower.includes('cost') || lower.includes('danger') || lower.includes('problem') || lower.includes('failure')) {
21
+ reasons.push('frames conflict or stakes');
22
+ }
23
+ let pattern = 'statement-hook';
24
+ if (reasons.includes('opens with a question') && reasons.includes('creates a curiosity gap'))
25
+ pattern = 'question-hook';
26
+ else if (reasons.includes('promises a concrete result'))
27
+ pattern = 'challenge-result';
28
+ else if (reasons.includes('creates a curiosity gap'))
29
+ pattern = 'curiosity-gap';
30
+ else if (reasons.includes('frames conflict or stakes'))
31
+ pattern = 'conflict-stakes';
32
+ else if (reasons.includes('opens with a question'))
33
+ pattern = 'question-hook';
34
+ return { pattern, reasons: reasons.length ? reasons : ['states the topic directly'] };
35
+ }
36
+ export function extractTranscriptStructure(text, includeClaims = true) {
37
+ const sentences = splitSentences(text);
38
+ const hookText = sentences[0] ?? '';
39
+ const ctaSentence = [...sentences].reverse().find((sentence) => /\b(subscribe|comment|download|share|follow|watch next|checklist|worksheet)\b/i.test(sentence)) ?? '';
40
+ const hookAnalysis = analyzeHookPattern(hookText);
41
+ const midpoint = Math.max(1, Math.floor(sentences.length / 2));
42
+ const outline = [
43
+ { section: 'hook', text: hookText, purpose: 'capture attention and frame the promise' },
44
+ { section: 'development', text: sentences.slice(1, midpoint).join(' '), purpose: 'build context and evidence' },
45
+ { section: 'payoff', text: sentences.slice(midpoint, Math.max(midpoint, sentences.length - 1)).join(' '), purpose: 'deliver insight or framework' },
46
+ { section: 'cta', text: ctaSentence, purpose: 'ask for the next audience action' }
47
+ ].filter((section) => section.text.length > 0);
48
+ const claimPatterns = /\b(claim|found|shows|proves|because|therefore|this matters|the first|the second|researchers|study|data)\b/i;
49
+ const claims = includeClaims
50
+ ? sentences
51
+ .filter((sentence) => claimPatterns.test(sentence))
52
+ .slice(0, 8)
53
+ .map((sentence) => ({ text: sentence, type: 'claim', evidenceStrength: /\b(found|researchers|study|data|experiments?)\b/i.test(sentence) ? 'medium' : 'low' }))
54
+ : [];
55
+ const scriptPatterns = [...new Set([
56
+ hookAnalysis.pattern,
57
+ ctaSentence ? 'explicit-cta' : 'soft-cta',
58
+ claims.length > 0 ? 'evidence-led' : 'narrative-led'
59
+ ])];
60
+ return {
61
+ hook: hookText,
62
+ cta: ctaSentence,
63
+ outline,
64
+ claims,
65
+ scriptPatterns,
66
+ hookAnalysis
67
+ };
68
+ }
69
+ export function classifyComment(text) {
70
+ const lower = text.toLowerCase();
71
+ if (/\b(can you|could you|please|make|share|template|examples?|follow-up|more)\b/i.test(text)) {
72
+ return {
73
+ theme: 'content requests',
74
+ intent: 'request',
75
+ opportunity: 'Create a follow-up asset, checklist, or example-driven episode.'
76
+ };
77
+ }
78
+ if (text.includes('?') || /\b(how|why|what|which|confused|setup|trust|cost|problem)\b/i.test(text)) {
79
+ return {
80
+ theme: 'audience confusion',
81
+ intent: 'confusion',
82
+ opportunity: 'Add a clearer explainer segment that answers setup, cost, and trust questions.'
83
+ };
84
+ }
85
+ if (/\b(great|excellent|helpful|love|amazing|thanks|good)\b/i.test(text)) {
86
+ return {
87
+ theme: 'positive feedback',
88
+ intent: 'praise',
89
+ opportunity: 'Reuse the praised framing and turn it into a repeatable series format.'
90
+ };
91
+ }
92
+ if (/\b(wrong|bad|hate|danger|concern|scary|risk)\b/i.test(lower)) {
93
+ return {
94
+ theme: 'concerns and objections',
95
+ intent: 'concern',
96
+ opportunity: 'Address objections directly with evidence and counterexamples.'
97
+ };
98
+ }
99
+ return {
100
+ theme: 'general reaction',
101
+ intent: 'reaction',
102
+ opportunity: 'Mine representative reactions for framing language.'
103
+ };
104
+ }
105
+ export function summarizeCommentSet(comments, includeQuestions = true, includeRequests = true) {
106
+ const texts = comments.map((comment) => String(comment.text ?? '').trim()).filter(Boolean);
107
+ const grouped = new Map();
108
+ let positiveCount = 0;
109
+ let concernCount = 0;
110
+ for (const comment of comments) {
111
+ const text = String(comment.text ?? '').trim();
112
+ if (!text)
113
+ continue;
114
+ const classification = classifyComment(text);
115
+ if (classification.intent === 'praise')
116
+ positiveCount += 1;
117
+ if (classification.intent === 'concern' || classification.intent === 'confusion')
118
+ concernCount += 1;
119
+ const existing = grouped.get(classification.theme) ?? { ...classification, count: 0, examples: [], totalLikes: 0 };
120
+ existing.count += 1;
121
+ existing.totalLikes += Number(comment.likeCount ?? 0);
122
+ if (existing.examples.length < 3)
123
+ existing.examples.push(text);
124
+ grouped.set(classification.theme, existing);
125
+ }
126
+ const themes = [...grouped.values()].sort((a, b) => b.count - a.count || b.totalLikes - a.totalLikes);
127
+ const questions = includeQuestions ? texts.filter((text) => text.includes('?') || /\b(how|why|what|which)\b/i.test(text)).slice(0, 10) : [];
128
+ const contentRequests = includeRequests ? texts.filter((text) => /\b(can you|could you|please|make|share|template|examples?|follow-up|more)\b/i.test(text)).slice(0, 10) : [];
129
+ const topTheme = themes[0]?.theme ?? 'no clear theme';
130
+ return {
131
+ summary: `${texts.length} comments analyzed. Top signal: ${topTheme}. ${questions.length} questions and ${contentRequests.length} requests detected.`,
132
+ questions,
133
+ contentRequests,
134
+ themes,
135
+ sentimentSignal: {
136
+ positiveCount,
137
+ concernCount,
138
+ mixed: positiveCount > 0 && concernCount > 0,
139
+ dominant: concernCount > positiveCount ? 'concern' : positiveCount > 0 ? 'positive' : 'neutral'
140
+ }
141
+ };
142
+ }
143
+ //# sourceMappingURL=synthesis.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"synthesis.js","sourceRoot":"","sources":["../../../src/core/synthesis.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,18 @@
1
1
  import type { ProviderHealth, YoutubeOmniProvider } from './types.js';
2
+ type FetchLike = typeof fetch;
3
+ type YtDlpMetadataLoader = (videoId: string, lang: string) => Promise<any | undefined>;
2
4
  export declare class TranscriptProvider implements YoutubeOmniProvider {
3
5
  id: string;
4
6
  name: string;
5
7
  authTier: "none";
6
8
  capabilities: string[];
9
+ private readonly fetchImpl;
10
+ private readonly loadYtDlpMetadata;
11
+ constructor(fetchImpl?: FetchLike, loadYtDlpMetadata?: YtDlpMetadataLoader);
7
12
  isConfigured(): boolean;
8
13
  healthCheck(): Promise<ProviderHealth>;
14
+ private fetchTrackText;
15
+ private fetchTranscript;
9
16
  getTranscriptSegments(input: {
10
17
  videoIds: string[];
11
18
  lang: string;
@@ -17,7 +24,7 @@ export declare class TranscriptProvider implements YoutubeOmniProvider {
17
24
  format: "key_segments";
18
25
  intro: string;
19
26
  outro: string;
20
- availability: string;
27
+ availability: "available" | "unavailable";
21
28
  }[];
22
29
  }>;
23
30
  getTranscriptFullText(input: {
@@ -31,3 +38,4 @@ export declare class TranscriptProvider implements YoutubeOmniProvider {
31
38
  truncated: boolean;
32
39
  }>;
33
40
  }
41
+ export {};
@@ -1,17 +1,206 @@
1
+ import { execFile } from 'node:child_process';
2
+ function normalizeTranscriptText(text) {
3
+ return text
4
+ .replace(/\s+/g, ' ')
5
+ .replace(/\s+([,.!?;:])/g, '$1')
6
+ .trim();
7
+ }
8
+ function stripJsonAssignment(script, marker) {
9
+ const start = script.indexOf(marker);
10
+ if (start < 0)
11
+ return undefined;
12
+ const jsonStart = script.indexOf('{', start + marker.length);
13
+ if (jsonStart < 0)
14
+ return undefined;
15
+ let depth = 0;
16
+ let inString = false;
17
+ let escaped = false;
18
+ for (let i = jsonStart; i < script.length; i += 1) {
19
+ const char = script[i];
20
+ if (inString) {
21
+ if (escaped) {
22
+ escaped = false;
23
+ }
24
+ else if (char === '\\') {
25
+ escaped = true;
26
+ }
27
+ else if (char === '"') {
28
+ inString = false;
29
+ }
30
+ continue;
31
+ }
32
+ if (char === '"') {
33
+ inString = true;
34
+ }
35
+ else if (char === '{') {
36
+ depth += 1;
37
+ }
38
+ else if (char === '}') {
39
+ depth -= 1;
40
+ if (depth === 0)
41
+ return script.slice(jsonStart, i + 1);
42
+ }
43
+ }
44
+ return undefined;
45
+ }
46
+ function parsePlayerResponse(html) {
47
+ const raw = stripJsonAssignment(html, 'ytInitialPlayerResponse');
48
+ if (!raw)
49
+ return undefined;
50
+ try {
51
+ return JSON.parse(raw);
52
+ }
53
+ catch {
54
+ return undefined;
55
+ }
56
+ }
57
+ function trackLanguageMatches(track, lang) {
58
+ if (track.languageCode === lang)
59
+ return true;
60
+ const base = lang.split('-')[0];
61
+ return track.languageCode === base || track.vssId === `.${lang}` || track.vssId === `a.${lang}` || track.vssId === `.${base}` || track.vssId === `a.${base}`;
62
+ }
63
+ function chooseCaptionTrack(tracks, lang) {
64
+ return tracks.find((track) => trackLanguageMatches(track, lang))
65
+ ?? tracks.find((track) => trackLanguageMatches(track, 'en'))
66
+ ?? tracks[0];
67
+ }
68
+ function timedTextUrl(baseUrl) {
69
+ const url = new URL(baseUrl);
70
+ url.searchParams.set('fmt', 'json3');
71
+ return url.toString();
72
+ }
73
+ function chooseYtDlpCaption(metadata, lang) {
74
+ const subtitles = metadata?.subtitles ?? {};
75
+ const automaticCaptions = metadata?.automatic_captions ?? {};
76
+ const base = lang.split('-')[0];
77
+ const tracks = subtitles[lang] ?? subtitles[base] ?? automaticCaptions[lang] ?? automaticCaptions[base];
78
+ if (!Array.isArray(tracks))
79
+ return undefined;
80
+ return tracks.find((track) => track?.ext === 'json3') ?? tracks.find((track) => typeof track?.url === 'string');
81
+ }
82
+ async function defaultYtDlpMetadata(videoId, lang) {
83
+ return new Promise((resolve) => {
84
+ const child = execFile('yt-dlp', [
85
+ '--skip-download',
86
+ '--write-auto-subs',
87
+ '--write-subs',
88
+ '--sub-lang', lang,
89
+ '--sub-format', 'json3/vtt/srv3/best',
90
+ '--dump-json',
91
+ `https://www.youtube.com/watch?v=${videoId}`
92
+ ], { timeout: 30000, maxBuffer: 8 * 1024 * 1024 }, (error, stdout) => {
93
+ if (error || !stdout.trim()) {
94
+ resolve(undefined);
95
+ return;
96
+ }
97
+ try {
98
+ resolve(JSON.parse(stdout));
99
+ }
100
+ catch {
101
+ resolve(undefined);
102
+ }
103
+ });
104
+ child.stdin?.end();
105
+ });
106
+ }
107
+ function textFromJson3(data) {
108
+ const chunks = [];
109
+ for (const event of data?.events ?? []) {
110
+ for (const segment of event?.segs ?? []) {
111
+ if (typeof segment?.utf8 === 'string')
112
+ chunks.push(segment.utf8);
113
+ }
114
+ }
115
+ return normalizeTranscriptText(chunks.join(''));
116
+ }
117
+ function truncate(text, maxChars) {
118
+ if (text.length <= maxChars)
119
+ return { text, truncated: false };
120
+ return { text: text.slice(0, maxChars), truncated: true };
121
+ }
122
+ function keySegments(text) {
123
+ if (!text)
124
+ return { intro: '', outro: '' };
125
+ const intro = text.slice(0, 700).trim();
126
+ const outro = text.slice(Math.max(0, text.length - 700)).trim();
127
+ return { intro, outro };
128
+ }
1
129
  export class TranscriptProvider {
2
- id = 'transcript_placeholder';
3
- name = 'Transcript Placeholder Provider';
130
+ id = 'youtube_timedtext';
131
+ name = 'YouTube Timed Text Transcript Provider';
4
132
  authTier = 'none';
5
133
  capabilities = ['transcript'];
134
+ fetchImpl;
135
+ loadYtDlpMetadata;
136
+ constructor(fetchImpl = fetch, loadYtDlpMetadata = defaultYtDlpMetadata) {
137
+ this.fetchImpl = fetchImpl;
138
+ this.loadYtDlpMetadata = loadYtDlpMetadata;
139
+ }
6
140
  isConfigured() { return true; }
7
141
  async healthCheck() {
8
- return { provider: this.id, configured: true, authTier: this.authTier, capabilities: this.capabilities, warnings: ['Transcript provider returns unavailable placeholders until a real transcript adapter is configured'] };
142
+ return { provider: this.id, configured: true, authTier: this.authTier, capabilities: this.capabilities, warnings: [] };
143
+ }
144
+ async fetchTrackText(trackUrl) {
145
+ const transcriptResponse = await this.fetchImpl(trackUrl);
146
+ if (!transcriptResponse.ok)
147
+ return '';
148
+ const data = await transcriptResponse.json();
149
+ return textFromJson3(data);
150
+ }
151
+ async fetchTranscript(videoId, lang) {
152
+ try {
153
+ const watchUrl = `https://www.youtube.com/watch?v=${encodeURIComponent(videoId)}&hl=${encodeURIComponent(lang)}`;
154
+ const watchResponse = await this.fetchImpl(watchUrl);
155
+ let trackUrl;
156
+ if (watchResponse.ok) {
157
+ const html = await watchResponse.text();
158
+ const playerResponse = parsePlayerResponse(html);
159
+ const tracks = playerResponse?.captions?.playerCaptionsTracklistRenderer?.captionTracks ?? [];
160
+ const track = chooseCaptionTrack(tracks, lang);
161
+ if (track?.baseUrl)
162
+ trackUrl = timedTextUrl(track.baseUrl);
163
+ }
164
+ if (!trackUrl) {
165
+ const metadata = await this.loadYtDlpMetadata(videoId, lang);
166
+ const ytDlpTrack = chooseYtDlpCaption(metadata, lang);
167
+ if (ytDlpTrack?.url)
168
+ trackUrl = timedTextUrl(ytDlpTrack.url);
169
+ }
170
+ if (!trackUrl)
171
+ return { text: '', availability: 'unavailable' };
172
+ let text = await this.fetchTrackText(trackUrl);
173
+ if (!text) {
174
+ const metadata = await this.loadYtDlpMetadata(videoId, lang);
175
+ const ytDlpTrack = chooseYtDlpCaption(metadata, lang);
176
+ if (ytDlpTrack?.url)
177
+ text = await this.fetchTrackText(timedTextUrl(ytDlpTrack.url));
178
+ }
179
+ return { text, availability: text ? 'available' : 'unavailable' };
180
+ }
181
+ catch {
182
+ return { text: '', availability: 'unavailable' };
183
+ }
9
184
  }
10
185
  async getTranscriptSegments(input) {
11
- return { transcripts: input.videoIds.map((videoId) => ({ videoId, language: input.lang, format: input.format, intro: '', outro: '', availability: 'unavailable' })) };
186
+ const transcripts = await Promise.all(input.videoIds.map(async (videoId) => {
187
+ const result = await this.fetchTranscript(videoId, input.lang);
188
+ const segments = keySegments(result.text);
189
+ return {
190
+ videoId,
191
+ language: input.lang,
192
+ format: input.format,
193
+ intro: segments.intro,
194
+ outro: segments.outro,
195
+ availability: result.availability
196
+ };
197
+ }));
198
+ return { transcripts };
12
199
  }
13
200
  async getTranscriptFullText(input) {
14
- return { videoId: input.videoId, language: input.lang, text: '', truncated: false };
201
+ const result = await this.fetchTranscript(input.videoId, input.lang);
202
+ const capped = truncate(result.text, input.maxChars);
203
+ return { videoId: input.videoId, language: input.lang, text: capped.text, truncated: capped.truncated };
15
204
  }
16
205
  }
17
206
  //# sourceMappingURL=transcript-provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transcript-provider.js","sourceRoot":"","sources":["../../../src/providers/transcript-provider.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,kBAAkB;IAC7B,EAAE,GAAG,wBAAwB,CAAC;IAC9B,IAAI,GAAG,iCAAiC,CAAC;IACzC,QAAQ,GAAG,MAAe,CAAC;IAC3B,YAAY,GAAG,CAAC,YAAY,CAAC,CAAC;IAE9B,YAAY,KAAc,OAAO,IAAI,CAAC,CAAC,CAAC;IAExC,KAAK,CAAC,WAAW;QACf,OAAO,EAAE,QAAQ,EAAE,IAAI,CAAC,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,QAAQ,EAAE,YAAY,EAAE,IAAI,CAAC,YAAY,EAAE,QAAQ,EAAE,CAAC,oGAAoG,CAAC,EAAE,CAAC;IAC7N,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,KAAmE;QAC7F,OAAO,EAAE,WAAW,EAAE,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,YAAY,EAAE,aAAa,EAAE,CAAC,CAAC,EAAE,CAAC;IACxK,CAAC;IAED,KAAK,CAAC,qBAAqB,CAAC,KAA0D;QACpF,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,CAAC;IACtF,CAAC;CACF"}
1
+ {"version":3,"file":"transcript-provider.js","sourceRoot":"","sources":["../../../src/providers/transcript-provider.ts"],"names":[],"mappings":"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"}
@@ -7,9 +7,18 @@ export declare function summarizeComments(input: unknown, registry: ProviderRegi
7
7
  summary: string;
8
8
  questions: string[];
9
9
  contentRequests: string[];
10
+ themes: {
11
+ theme: string;
12
+ intent: string;
13
+ opportunity: string;
14
+ count: number;
15
+ examples: string[];
16
+ totalLikes: number;
17
+ }[];
10
18
  sentimentSignal: {
11
- positive: string;
12
- negative: string;
19
+ positiveCount: number;
20
+ concernCount: number;
13
21
  mixed: boolean;
22
+ dominant: string;
14
23
  };
15
24
  }>>;
@@ -1,4 +1,5 @@
1
1
  import { makeEnvelope } from '../core/envelope.js';
2
+ import { summarizeCommentSet } from '../core/synthesis.js';
2
3
  import { getCommentsSchema, summarizeCommentsSchema } from '../schemas/comments.js';
3
4
  export async function getVideoComments(input, registry) {
4
5
  const parsed = getCommentsSchema.parse(input);
@@ -10,6 +11,7 @@ export async function summarizeComments(input, registry) {
10
11
  const parsed = summarizeCommentsSchema.parse(input);
11
12
  const provider = registry.requireCapability('comments');
12
13
  const comments = await provider.getVideoComments({ videoId: parsed.videoId, maxResults: parsed.maxComments, maxReplies: 0 });
13
- return makeEnvelope({ tool: 'youtube.comments.summarize', provider: provider.id, authTier: provider.authTier, data: { summary: 'Mock audience response is positive with requests for follow-up content.', questions: parsed.includeQuestions ? ['Can you make a follow-up?'] : [], contentRequests: parsed.includeRequests ? ['More examples'] : [], sentimentSignal: { positive: 'high', negative: 'low', mixed: false } }, warnings: ['Sentiment is an estimate, not a fact.'] });
14
+ const data = summarizeCommentSet(comments.comments, parsed.includeQuestions, parsed.includeRequests);
15
+ return makeEnvelope({ tool: 'youtube.comments.summarize', provider: provider.id, authTier: provider.authTier, data, warnings: ['Sentiment and themes are heuristic estimates, not facts.'] });
14
16
  }
15
17
  //# sourceMappingURL=comments.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../../src/tools/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAc,EAAE,QAA0B;IAC/E,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,gBAAiB,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,6DAA6D,CAAC,EAAE,CAAC,CAAC;AAC7L,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAc,EAAE,QAA0B;IAChF,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,gBAAiB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9H,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,4BAA4B,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,yEAAyE,EAAE,SAAS,EAAE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,eAAe,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,eAAe,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,uCAAuC,CAAC,EAAE,CAAC,CAAC;AACtd,CAAC"}
1
+ {"version":3,"file":"comments.js","sourceRoot":"","sources":["../../../src/tools/comments.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEpF,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,KAAc,EAAE,QAA0B;IAC/E,MAAM,MAAM,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,gBAAiB,CAAC,MAAM,CAAC,CAAC;IACtD,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,sBAAsB,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,6DAA6D,CAAC,EAAE,CAAC,CAAC;AAC7L,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,KAAc,EAAE,QAA0B;IAChF,MAAM,MAAM,GAAG,uBAAuB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACpD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAG,MAAM,QAAQ,CAAC,gBAAiB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9H,MAAM,IAAI,GAAG,mBAAmB,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,gBAAgB,EAAE,MAAM,CAAC,eAAe,CAAC,CAAC;IACrG,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,4BAA4B,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,0DAA0D,CAAC,EAAE,CAAC,CAAC;AAChM,CAAC"}
@@ -3,11 +3,24 @@ export declare function generateResearchBrief(input: unknown, registry: Provider
3
3
  brief: {
4
4
  topic: string;
5
5
  benchmarkVideos: any[];
6
- benchmarkChannels: never[];
6
+ benchmarkChannels: {
7
+ channelId: any;
8
+ }[];
7
9
  titlePatterns: string[];
8
- hookPatterns: string[];
9
- audienceQuestions: never[];
10
- contentOpportunities: never[];
10
+ hookPatterns: {
11
+ pattern: string;
12
+ example: string;
13
+ videoId: string;
14
+ reasons: string[];
15
+ }[];
16
+ audienceQuestions: string[];
17
+ contentOpportunities: any[];
18
+ recommendedAngles: {
19
+ angle: string;
20
+ evidence: any[];
21
+ rationale: string;
22
+ }[];
23
+ commentThemes: any[];
11
24
  risks: string[];
12
25
  };
13
26
  }>>;
@@ -1,9 +1,81 @@
1
1
  import { makeEnvelope } from '../core/envelope.js';
2
+ import { analyzeHookPattern, summarizeCommentSet } from '../core/synthesis.js';
2
3
  import { researchBriefSchema } from '../schemas/planning.js';
4
+ function unique(items) {
5
+ return [...new Set(items)];
6
+ }
7
+ function angleFromTitle(title, topic, index) {
8
+ return title?.trim() || `${topic} angle ${index + 1}`;
9
+ }
3
10
  export async function generateResearchBrief(input, registry) {
4
11
  const parsed = researchBriefSchema.parse(input);
5
- const provider = registry.requireCapability('search');
6
- const videos = await provider.searchVideos({ query: parsed.topic, maxResults: parsed.sampleSize });
7
- return makeEnvelope({ tool: 'youtube.planning.generate_research_brief', provider: provider.id, authTier: provider.authTier, data: { brief: { topic: parsed.topic, benchmarkVideos: videos.videos, benchmarkChannels: [], titlePatterns: ['clear promise + concrete payoff'], hookPatterns: ['open with conflict or curiosity gap'], audienceQuestions: [], contentOpportunities: [], risks: ['Do not copy competitor content verbatim.'] } }, warnings: ['Draft only; no upload or publishing action is performed.'] });
12
+ const searchProvider = registry.requireCapability('search');
13
+ const videos = await searchProvider.searchVideos({ query: parsed.topic, maxResults: parsed.sampleSize });
14
+ const benchmarkVideos = videos.videos;
15
+ const videoIds = benchmarkVideos.map((video) => video.videoId).filter(Boolean).slice(0, 5);
16
+ let hookPatterns = [];
17
+ if (parsed.includeTranscripts && videoIds.length > 0) {
18
+ try {
19
+ const transcriptProvider = registry.requireCapability('transcript');
20
+ const segments = await transcriptProvider.getTranscriptSegments({ videoIds, lang: 'en', format: 'key_segments' });
21
+ hookPatterns = segments.transcripts
22
+ .filter((transcript) => transcript.intro)
23
+ .map((transcript) => {
24
+ const analysis = analyzeHookPattern(transcript.intro);
25
+ return { pattern: analysis.pattern, example: transcript.intro, videoId: transcript.videoId, reasons: analysis.reasons };
26
+ });
27
+ }
28
+ catch {
29
+ hookPatterns = [];
30
+ }
31
+ }
32
+ let audienceQuestions = [];
33
+ let contentRequests = [];
34
+ let commentThemes = [];
35
+ if (parsed.includeComments && videoIds[0]) {
36
+ try {
37
+ const commentsProvider = registry.requireCapability('comments');
38
+ const comments = await commentsProvider.getVideoComments({ videoId: videoIds[0], maxResults: 50, maxReplies: 0 });
39
+ const summary = summarizeCommentSet(comments.comments, true, true);
40
+ audienceQuestions = summary.questions;
41
+ contentRequests = summary.contentRequests;
42
+ commentThemes = summary.themes;
43
+ }
44
+ catch {
45
+ audienceQuestions = [];
46
+ contentRequests = [];
47
+ commentThemes = [];
48
+ }
49
+ }
50
+ const recommendedAngles = benchmarkVideos.slice(0, 5).map((video, index) => ({
51
+ angle: angleFromTitle(video.title, parsed.topic, index),
52
+ evidence: [video.videoId].filter(Boolean),
53
+ rationale: index === 0 ? 'Lead with the strongest benchmark title pattern and validate with hooks/comments.' : 'Use as a secondary format test backed by benchmark discovery.'
54
+ }));
55
+ const contentOpportunities = unique([
56
+ ...contentRequests.map((request) => `Turn audience request into follow-up: ${request}`),
57
+ ...commentThemes.slice(0, 3).map((theme) => theme.opportunity),
58
+ ...(hookPatterns[0] ? [`Adapt ${hookPatterns[0].pattern} opening: ${hookPatterns[0].example.slice(0, 120)}`] : [])
59
+ ].filter(Boolean));
60
+ return makeEnvelope({
61
+ tool: 'youtube.planning.generate_research_brief',
62
+ provider: searchProvider.id,
63
+ authTier: searchProvider.authTier,
64
+ data: {
65
+ brief: {
66
+ topic: parsed.topic,
67
+ benchmarkVideos,
68
+ benchmarkChannels: unique(benchmarkVideos.map((video) => video.channelId).filter(Boolean)).map((channelId) => ({ channelId })),
69
+ titlePatterns: ['clear promise + concrete payoff', 'specific topic + stakes', 'case-study framing'],
70
+ hookPatterns,
71
+ audienceQuestions,
72
+ contentOpportunities,
73
+ recommendedAngles,
74
+ commentThemes,
75
+ risks: ['Do not copy competitor content verbatim.', 'Verify claims independently before scripting.', 'Treat transcript/comment signals as public audience signals, not private analytics.']
76
+ }
77
+ },
78
+ warnings: ['Draft only; no upload or publishing action is performed. Transcript/comment synthesis is heuristic.']
79
+ });
8
80
  }
9
81
  //# sourceMappingURL=planning.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"planning.js","sourceRoot":"","sources":["../../../src/tools/planning.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAE7D,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAc,EAAE,QAA0B;IACpF,MAAM,MAAM,GAAG,mBAAmB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,YAAa,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IACpG,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,0CAA0C,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,EAAE,EAAE,EAAE,aAAa,EAAE,CAAC,iCAAiC,CAAC,EAAE,YAAY,EAAE,CAAC,qCAAqC,CAAC,EAAE,iBAAiB,EAAE,EAAE,EAAE,oBAAoB,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,0CAA0C,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,CAAC,0DAA0D,CAAC,EAAE,CAAC,CAAC;AAC1f,CAAC"}
1
+ {"version":3,"file":"planning.js","sourceRoot":"","sources":["../../../src/tools/planning.ts"],"names":[],"mappings":"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"}
@@ -16,6 +16,7 @@ export declare function compareHooks(input: unknown, registry: ProviderRegistry)
16
16
  videoId: any;
17
17
  hook: any;
18
18
  pattern: string;
19
+ reasons: string[];
19
20
  availability: any;
20
21
  }[];
21
22
  }>>;
@@ -32,8 +33,11 @@ export declare function summarizeCommentPainPoints(input: unknown, registry: Pro
32
33
  videoId: string;
33
34
  painPoints: {
34
35
  theme: string;
36
+ intent: string;
37
+ opportunity: string;
35
38
  count: number;
36
39
  examples: string[];
40
+ totalLikes: number;
37
41
  }[];
38
42
  }>>;
39
43
  export declare function generateVideoAngleMatrix(input: unknown, registry: ProviderRegistry): Promise<import("../core/envelope.js").ToolEnvelope<{
@@ -1,33 +1,16 @@
1
1
  import { makeEnvelope } from '../core/envelope.js';
2
+ import { analyzeHookPattern, classifyComment } from '../core/synthesis.js';
2
3
  import { commentPainPointsSchema, compareHooksSchema, outlierVideosSchema, topicAnglesSchema, videoAngleMatrixSchema } from '../schemas/research.js';
3
4
  function numberFrom(value, fallback = 0) {
4
5
  const parsed = Number(value);
5
6
  return Number.isFinite(parsed) ? parsed : fallback;
6
7
  }
7
- function patternForHook(hook) {
8
- const lower = hook.toLowerCase();
9
- if (lower.includes('?'))
10
- return 'question';
11
- if (lower.includes('secret') || lower.includes('hidden'))
12
- return 'curiosity_gap';
13
- if (lower.includes('mock') || lower.includes('this is'))
14
- return 'direct_promise';
15
- return 'statement';
16
- }
17
8
  function titleAngle(title, topic, index) {
18
9
  const cleaned = title.replace(/\s+/g, ' ').trim();
19
10
  if (cleaned.length > 0)
20
11
  return cleaned;
21
12
  return `${topic} angle ${index + 1}`;
22
13
  }
23
- function themeForComment(text) {
24
- const lower = text.toLowerCase();
25
- if (lower.includes('follow-up') || lower.includes('make'))
26
- return 'follow-up requests';
27
- if (lower.includes('?') || lower.includes('how') || lower.includes('why'))
28
- return 'audience questions';
29
- return 'positive feedback';
30
- }
31
14
  export async function findOutlierVideos(input, registry) {
32
15
  const parsed = outlierVideosSchema.parse(input);
33
16
  const searchProvider = registry.requireCapability('search');
@@ -68,7 +51,8 @@ export async function compareHooks(input, registry) {
68
51
  const data = await provider.getTranscriptSegments({ videoIds: parsed.videoIds, lang: parsed.lang, format: 'key_segments' });
69
52
  const hooks = data.transcripts.map((transcript) => {
70
53
  const hook = transcript.intro || '';
71
- return { videoId: transcript.videoId, hook, pattern: patternForHook(hook), availability: transcript.availability ?? 'unknown' };
54
+ const analysis = analyzeHookPattern(hook);
55
+ return { videoId: transcript.videoId, hook, pattern: analysis.pattern, reasons: analysis.reasons, availability: transcript.availability ?? 'unknown' };
72
56
  });
73
57
  return makeEnvelope({
74
58
  tool: 'youtube.research.compare_hooks',
@@ -103,14 +87,15 @@ export async function summarizeCommentPainPoints(input, registry) {
103
87
  const grouped = new Map();
104
88
  for (const comment of data.comments) {
105
89
  const text = String(comment.text ?? '');
106
- const theme = themeForComment(text);
107
- const existing = grouped.get(theme) ?? { theme, count: 0, examples: [] };
90
+ const classification = classifyComment(text);
91
+ const existing = grouped.get(classification.theme) ?? { ...classification, count: 0, examples: [], totalLikes: 0 };
108
92
  existing.count += 1;
93
+ existing.totalLikes += numberFrom(comment.likeCount);
109
94
  if (existing.examples.length < 3)
110
95
  existing.examples.push(text);
111
- grouped.set(theme, existing);
96
+ grouped.set(classification.theme, existing);
112
97
  }
113
- const painPoints = [...grouped.values()].sort((a, b) => b.count - a.count);
98
+ const painPoints = [...grouped.values()].sort((a, b) => b.count - a.count || b.totalLikes - a.totalLikes);
114
99
  return makeEnvelope({
115
100
  tool: 'youtube.research.summarize_comment_pain_points',
116
101
  provider: provider.id,
@@ -1 +1 @@
1
- {"version":3,"file":"research.js","sourceRoot":"","sources":["../../../src/tools/research.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"research.js","sourceRoot":"","sources":["../../../src/tools/research.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,6 @@ export async function classifyActionRiskTool(input) {
5
5
  return makeEnvelope({ tool: 'youtube.safety.classify_action_risk', provider: 'core', authTier: 'none', data: risk, warnings: risk.allowedInV0 ? [] : ['This action is part of the full scope but locked in v0.'] });
6
6
  }
7
7
  export async function listCapabilities(_input) {
8
- return makeEnvelope({ tool: 'youtube.safety.list_capabilities', provider: 'core', authTier: 'none', data: { version: '0.2.3', phase: 'v0.2.3-executable-bin', enabledNamespaces: ['discovery', 'video', 'channel', 'transcript', 'comments', 'planning', 'research', 'safety'], lockedNamespaces: ['operations', 'community-write', 'analytics-oauth', 'reporting', 'media-download', 'shorts-render', 'music-private'] }, warnings: [] });
8
+ return makeEnvelope({ tool: 'youtube.safety.list_capabilities', provider: 'core', authTier: 'none', data: { version: '0.2.5', phase: 'v0.2.5-deeper-readonly-synthesis', enabledNamespaces: ['discovery', 'video', 'channel', 'transcript', 'comments', 'planning', 'research', 'safety'], lockedNamespaces: ['operations', 'community-write', 'analytics-oauth', 'reporting', 'media-download', 'shorts-render', 'music-private'] }, warnings: [] });
9
9
  }
10
10
  //# sourceMappingURL=safety.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../../src/tools/safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAA2D;IACtG,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,qCAAqC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,yDAAyD,CAAC,EAAE,CAAC,CAAC;AACtN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAA6B;IAClE,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,uBAAuB,EAAE,iBAAiB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AAC7a,CAAC"}
1
+ {"version":3,"file":"safety.js","sourceRoot":"","sources":["../../../src/tools/safety.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAC;AAErD,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,KAA2D;IACtG,MAAM,IAAI,GAAG,kBAAkB,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9C,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,qCAAqC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,yDAAyD,CAAC,EAAE,CAAC,CAAC;AACtN,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CAAC,MAA6B;IAClE,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,kCAAkC,EAAE,iBAAiB,EAAE,CAAC,WAAW,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,QAAQ,CAAC,EAAE,gBAAgB,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,WAAW,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;AACxb,CAAC"}
@@ -11,7 +11,16 @@ export declare function getTranscriptFullText(input: unknown, registry: Provider
11
11
  export declare function analyzeTranscriptStructure(input: unknown, registry: ProviderRegistry): Promise<import("../core/envelope.js").ToolEnvelope<{
12
12
  hook: string;
13
13
  cta: string;
14
- outline: string[];
15
- claims: never[];
14
+ outline: {
15
+ section: string;
16
+ text: string;
17
+ purpose: string;
18
+ }[];
19
+ claims: {
20
+ text: string;
21
+ type: string;
22
+ evidenceStrength: string;
23
+ }[];
16
24
  scriptPatterns: string[];
25
+ hookAnalysis: import("../core/synthesis.js").HookAnalysis;
17
26
  }>>;
@@ -1,4 +1,5 @@
1
1
  import { makeEnvelope } from '../core/envelope.js';
2
+ import { extractTranscriptStructure } from '../core/synthesis.js';
2
3
  import { transcriptFullTextSchema, transcriptSegmentsSchema, transcriptStructureSchema } from '../schemas/transcript.js';
3
4
  export async function getTranscriptSegments(input, registry) {
4
5
  const parsed = transcriptSegmentsSchema.parse(input);
@@ -16,6 +17,7 @@ export async function analyzeTranscriptStructure(input, registry) {
16
17
  const parsed = transcriptStructureSchema.parse(input);
17
18
  const provider = registry.requireCapability('transcript');
18
19
  const full = await provider.getTranscriptFullText({ videoId: parsed.videoId, lang: parsed.lang, maxChars: 20000 });
19
- return makeEnvelope({ tool: 'youtube.transcript.analyze_structure', provider: provider.id, authTier: provider.authTier, data: { hook: full.text.includes('Mock hook') ? 'Mock hook intro' : full.text.slice(0, 80), cta: full.text.includes('CTA') ? 'Mock CTA outro' : '', outline: ['intro', 'body', 'cta'], claims: parsed.includeClaims ? [] : [], scriptPatterns: ['hook-body-cta'] }, warnings: ['Structure analysis is heuristic.'] });
20
+ const structure = extractTranscriptStructure(full.text, parsed.includeClaims);
21
+ return makeEnvelope({ tool: 'youtube.transcript.analyze_structure', provider: provider.id, authTier: provider.authTier, data: structure, warnings: ['Structure analysis is heuristic and derived from available transcript text.'] });
20
22
  }
21
23
  //# sourceMappingURL=transcript.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/tools/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAEzH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAc,EAAE,QAA0B;IACpF,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,kEAAkE,CAAC,EAAE,CAAC,CAAC;AAC7M,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAc,EAAE,QAA0B;IACpF,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,mFAAmF,CAAC,EAAE,CAAC,CAAC;AAC/N,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAc,EAAE,QAA0B;IACzF,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACpH,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,sCAAsC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,cAAc,EAAE,CAAC,eAAe,CAAC,EAAE,EAAE,QAAQ,EAAE,CAAC,kCAAkC,CAAC,EAAE,CAAC,CAAC;AAChb,CAAC"}
1
+ {"version":3,"file":"transcript.js","sourceRoot":"","sources":["../../../src/tools/transcript.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,sBAAsB,CAAC;AAElE,OAAO,EAAE,wBAAwB,EAAE,wBAAwB,EAAE,yBAAyB,EAAE,MAAM,0BAA0B,CAAC;AAEzH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAc,EAAE,QAA0B;IACpF,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,kEAAkE,CAAC,EAAE,CAAC,CAAC;AAC7M,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,KAAc,EAAE,QAA0B;IACpF,MAAM,MAAM,GAAG,wBAAwB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACrD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,MAAM,CAAC,CAAC;IAC3D,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,kCAAkC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,mFAAmF,CAAC,EAAE,CAAC,CAAC;AAC/N,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAAC,KAAc,EAAE,QAA0B;IACzF,MAAM,MAAM,GAAG,yBAAyB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IACtD,MAAM,QAAQ,GAAG,QAAQ,CAAC,iBAAiB,CAAC,YAAY,CAAC,CAAC;IAC1D,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,qBAAsB,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC,CAAC;IACpH,MAAM,SAAS,GAAG,0BAA0B,CAAC,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,aAAa,CAAC,CAAC;IAC9E,OAAO,YAAY,CAAC,EAAE,IAAI,EAAE,sCAAsC,EAAE,QAAQ,EAAE,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,6EAA6E,CAAC,EAAE,CAAC,CAAC;AACxO,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@liorium/youtube-omni-mcp",
3
- "version": "0.2.3",
3
+ "version": "0.2.5",
4
4
  "description": "YouTube Creator Intelligence, Analytics, Operations, and Production MCP server.",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",