vidpipe 1.0.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.
Files changed (213) hide show
  1. package/README.md +243 -0
  2. package/assets/fonts/Montserrat-Bold.ttf +0 -0
  3. package/assets/fonts/Montserrat-Regular.ttf +0 -0
  4. package/assets/fonts/OFL.txt +93 -0
  5. package/dist/__tests__/agents.test.d.ts +2 -0
  6. package/dist/__tests__/agents.test.d.ts.map +1 -0
  7. package/dist/__tests__/agents.test.js +434 -0
  8. package/dist/__tests__/agents.test.js.map +1 -0
  9. package/dist/__tests__/aspectRatio.test.d.ts +2 -0
  10. package/dist/__tests__/aspectRatio.test.d.ts.map +1 -0
  11. package/dist/__tests__/aspectRatio.test.js +406 -0
  12. package/dist/__tests__/aspectRatio.test.js.map +1 -0
  13. package/dist/__tests__/captionGenerator.test.d.ts +2 -0
  14. package/dist/__tests__/captionGenerator.test.d.ts.map +1 -0
  15. package/dist/__tests__/captionGenerator.test.js +435 -0
  16. package/dist/__tests__/captionGenerator.test.js.map +1 -0
  17. package/dist/__tests__/config.test.d.ts +2 -0
  18. package/dist/__tests__/config.test.d.ts.map +1 -0
  19. package/dist/__tests__/config.test.js +81 -0
  20. package/dist/__tests__/config.test.js.map +1 -0
  21. package/dist/__tests__/faceDetection.test.d.ts +2 -0
  22. package/dist/__tests__/faceDetection.test.d.ts.map +1 -0
  23. package/dist/__tests__/faceDetection.test.js +372 -0
  24. package/dist/__tests__/faceDetection.test.js.map +1 -0
  25. package/dist/__tests__/ffmpegTools.test.d.ts +2 -0
  26. package/dist/__tests__/ffmpegTools.test.d.ts.map +1 -0
  27. package/dist/__tests__/ffmpegTools.test.js +464 -0
  28. package/dist/__tests__/ffmpegTools.test.js.map +1 -0
  29. package/dist/__tests__/integration/captionBurn.test.d.ts +2 -0
  30. package/dist/__tests__/integration/captionBurn.test.d.ts.map +1 -0
  31. package/dist/__tests__/integration/captionBurn.test.js +103 -0
  32. package/dist/__tests__/integration/captionBurn.test.js.map +1 -0
  33. package/dist/__tests__/integration/clipComposite.test.d.ts +2 -0
  34. package/dist/__tests__/integration/clipComposite.test.d.ts.map +1 -0
  35. package/dist/__tests__/integration/clipComposite.test.js +56 -0
  36. package/dist/__tests__/integration/clipComposite.test.js.map +1 -0
  37. package/dist/__tests__/integration/faceDetection.test.d.ts +2 -0
  38. package/dist/__tests__/integration/faceDetection.test.d.ts.map +1 -0
  39. package/dist/__tests__/integration/faceDetection.test.js +85 -0
  40. package/dist/__tests__/integration/faceDetection.test.js.map +1 -0
  41. package/dist/__tests__/integration/ffmpegPipeline.test.d.ts +2 -0
  42. package/dist/__tests__/integration/ffmpegPipeline.test.d.ts.map +1 -0
  43. package/dist/__tests__/integration/ffmpegPipeline.test.js +88 -0
  44. package/dist/__tests__/integration/ffmpegPipeline.test.js.map +1 -0
  45. package/dist/__tests__/integration/fixture.d.ts +19 -0
  46. package/dist/__tests__/integration/fixture.d.ts.map +1 -0
  47. package/dist/__tests__/integration/fixture.js +112 -0
  48. package/dist/__tests__/integration/fixture.js.map +1 -0
  49. package/dist/__tests__/integration/fixture.test.d.ts +2 -0
  50. package/dist/__tests__/integration/fixture.test.d.ts.map +1 -0
  51. package/dist/__tests__/integration/fixture.test.js +27 -0
  52. package/dist/__tests__/integration/fixture.test.js.map +1 -0
  53. package/dist/__tests__/integration/realCaptions.test.d.ts +2 -0
  54. package/dist/__tests__/integration/realCaptions.test.d.ts.map +1 -0
  55. package/dist/__tests__/integration/realCaptions.test.js +226 -0
  56. package/dist/__tests__/integration/realCaptions.test.js.map +1 -0
  57. package/dist/__tests__/integration/realPipeline.test.d.ts +2 -0
  58. package/dist/__tests__/integration/realPipeline.test.d.ts.map +1 -0
  59. package/dist/__tests__/integration/realPipeline.test.js +210 -0
  60. package/dist/__tests__/integration/realPipeline.test.js.map +1 -0
  61. package/dist/__tests__/integration/silenceRemoval.test.d.ts +2 -0
  62. package/dist/__tests__/integration/silenceRemoval.test.d.ts.map +1 -0
  63. package/dist/__tests__/integration/silenceRemoval.test.js +93 -0
  64. package/dist/__tests__/integration/silenceRemoval.test.js.map +1 -0
  65. package/dist/__tests__/pipeline.test.d.ts +2 -0
  66. package/dist/__tests__/pipeline.test.d.ts.map +1 -0
  67. package/dist/__tests__/pipeline.test.js +434 -0
  68. package/dist/__tests__/pipeline.test.js.map +1 -0
  69. package/dist/__tests__/services.test.d.ts +2 -0
  70. package/dist/__tests__/services.test.d.ts.map +1 -0
  71. package/dist/__tests__/services.test.js +655 -0
  72. package/dist/__tests__/services.test.js.map +1 -0
  73. package/dist/__tests__/silenceRemoval.test.d.ts +2 -0
  74. package/dist/__tests__/silenceRemoval.test.d.ts.map +1 -0
  75. package/dist/__tests__/silenceRemoval.test.js +266 -0
  76. package/dist/__tests__/silenceRemoval.test.js.map +1 -0
  77. package/dist/__tests__/singlePassEdit.test.d.ts +2 -0
  78. package/dist/__tests__/singlePassEdit.test.d.ts.map +1 -0
  79. package/dist/__tests__/singlePassEdit.test.js +321 -0
  80. package/dist/__tests__/singlePassEdit.test.js.map +1 -0
  81. package/dist/__tests__/smoke.test.d.ts +2 -0
  82. package/dist/__tests__/smoke.test.d.ts.map +1 -0
  83. package/dist/__tests__/smoke.test.js +8 -0
  84. package/dist/__tests__/smoke.test.js.map +1 -0
  85. package/dist/__tests__/utilities.test.d.ts +2 -0
  86. package/dist/__tests__/utilities.test.d.ts.map +1 -0
  87. package/dist/__tests__/utilities.test.js +268 -0
  88. package/dist/__tests__/utilities.test.js.map +1 -0
  89. package/dist/agents/BaseAgent.d.ts +52 -0
  90. package/dist/agents/BaseAgent.d.ts.map +1 -0
  91. package/dist/agents/BaseAgent.js +108 -0
  92. package/dist/agents/BaseAgent.js.map +1 -0
  93. package/dist/agents/BlogAgent.d.ts +3 -0
  94. package/dist/agents/BlogAgent.d.ts.map +1 -0
  95. package/dist/agents/BlogAgent.js +163 -0
  96. package/dist/agents/BlogAgent.js.map +1 -0
  97. package/dist/agents/ChapterAgent.d.ts +11 -0
  98. package/dist/agents/ChapterAgent.d.ts.map +1 -0
  99. package/dist/agents/ChapterAgent.js +191 -0
  100. package/dist/agents/ChapterAgent.js.map +1 -0
  101. package/dist/agents/MediumVideoAgent.d.ts +3 -0
  102. package/dist/agents/MediumVideoAgent.d.ts.map +1 -0
  103. package/dist/agents/MediumVideoAgent.js +219 -0
  104. package/dist/agents/MediumVideoAgent.js.map +1 -0
  105. package/dist/agents/ShortsAgent.d.ts +3 -0
  106. package/dist/agents/ShortsAgent.d.ts.map +1 -0
  107. package/dist/agents/ShortsAgent.js +243 -0
  108. package/dist/agents/ShortsAgent.js.map +1 -0
  109. package/dist/agents/SilenceRemovalAgent.d.ts +9 -0
  110. package/dist/agents/SilenceRemovalAgent.d.ts.map +1 -0
  111. package/dist/agents/SilenceRemovalAgent.js +208 -0
  112. package/dist/agents/SilenceRemovalAgent.js.map +1 -0
  113. package/dist/agents/SocialMediaAgent.d.ts +4 -0
  114. package/dist/agents/SocialMediaAgent.d.ts.map +1 -0
  115. package/dist/agents/SocialMediaAgent.js +248 -0
  116. package/dist/agents/SocialMediaAgent.js.map +1 -0
  117. package/dist/agents/SummaryAgent.d.ts +11 -0
  118. package/dist/agents/SummaryAgent.d.ts.map +1 -0
  119. package/dist/agents/SummaryAgent.js +333 -0
  120. package/dist/agents/SummaryAgent.js.map +1 -0
  121. package/dist/config/brand.d.ts +29 -0
  122. package/dist/config/brand.d.ts.map +1 -0
  123. package/dist/config/brand.js +83 -0
  124. package/dist/config/brand.js.map +1 -0
  125. package/dist/config/environment.d.ts +36 -0
  126. package/dist/config/environment.d.ts.map +1 -0
  127. package/dist/config/environment.js +44 -0
  128. package/dist/config/environment.js.map +1 -0
  129. package/dist/config/logger.d.ts +5 -0
  130. package/dist/config/logger.d.ts.map +1 -0
  131. package/dist/config/logger.js +13 -0
  132. package/dist/config/logger.js.map +1 -0
  133. package/dist/index.d.ts +2 -0
  134. package/dist/index.d.ts.map +1 -0
  135. package/dist/index.js +135 -0
  136. package/dist/index.js.map +1 -0
  137. package/dist/pipeline.d.ts +57 -0
  138. package/dist/pipeline.d.ts.map +1 -0
  139. package/dist/pipeline.js +287 -0
  140. package/dist/pipeline.js.map +1 -0
  141. package/dist/services/captionGeneration.d.ts +7 -0
  142. package/dist/services/captionGeneration.d.ts.map +1 -0
  143. package/dist/services/captionGeneration.js +29 -0
  144. package/dist/services/captionGeneration.js.map +1 -0
  145. package/dist/services/fileWatcher.d.ts +19 -0
  146. package/dist/services/fileWatcher.d.ts.map +1 -0
  147. package/dist/services/fileWatcher.js +120 -0
  148. package/dist/services/fileWatcher.js.map +1 -0
  149. package/dist/services/gitOperations.d.ts +3 -0
  150. package/dist/services/gitOperations.d.ts.map +1 -0
  151. package/dist/services/gitOperations.js +43 -0
  152. package/dist/services/gitOperations.js.map +1 -0
  153. package/dist/services/socialPosting.d.ts +38 -0
  154. package/dist/services/socialPosting.d.ts.map +1 -0
  155. package/dist/services/socialPosting.js +102 -0
  156. package/dist/services/socialPosting.js.map +1 -0
  157. package/dist/services/transcription.d.ts +3 -0
  158. package/dist/services/transcription.d.ts.map +1 -0
  159. package/dist/services/transcription.js +100 -0
  160. package/dist/services/transcription.js.map +1 -0
  161. package/dist/services/videoIngestion.d.ts +3 -0
  162. package/dist/services/videoIngestion.d.ts.map +1 -0
  163. package/dist/services/videoIngestion.js +103 -0
  164. package/dist/services/videoIngestion.js.map +1 -0
  165. package/dist/tools/captions/captionGenerator.d.ts +84 -0
  166. package/dist/tools/captions/captionGenerator.d.ts.map +1 -0
  167. package/dist/tools/captions/captionGenerator.js +390 -0
  168. package/dist/tools/captions/captionGenerator.js.map +1 -0
  169. package/dist/tools/ffmpeg/aspectRatio.d.ts +101 -0
  170. package/dist/tools/ffmpeg/aspectRatio.d.ts.map +1 -0
  171. package/dist/tools/ffmpeg/aspectRatio.js +338 -0
  172. package/dist/tools/ffmpeg/aspectRatio.js.map +1 -0
  173. package/dist/tools/ffmpeg/audioExtraction.d.ts +16 -0
  174. package/dist/tools/ffmpeg/audioExtraction.d.ts.map +1 -0
  175. package/dist/tools/ffmpeg/audioExtraction.js +86 -0
  176. package/dist/tools/ffmpeg/audioExtraction.js.map +1 -0
  177. package/dist/tools/ffmpeg/captionBurning.d.ts +8 -0
  178. package/dist/tools/ffmpeg/captionBurning.d.ts.map +1 -0
  179. package/dist/tools/ffmpeg/captionBurning.js +71 -0
  180. package/dist/tools/ffmpeg/captionBurning.js.map +1 -0
  181. package/dist/tools/ffmpeg/clipExtraction.d.ts +23 -0
  182. package/dist/tools/ffmpeg/clipExtraction.d.ts.map +1 -0
  183. package/dist/tools/ffmpeg/clipExtraction.js +178 -0
  184. package/dist/tools/ffmpeg/clipExtraction.js.map +1 -0
  185. package/dist/tools/ffmpeg/faceDetection.d.ts +127 -0
  186. package/dist/tools/ffmpeg/faceDetection.d.ts.map +1 -0
  187. package/dist/tools/ffmpeg/faceDetection.js +500 -0
  188. package/dist/tools/ffmpeg/faceDetection.js.map +1 -0
  189. package/dist/tools/ffmpeg/frameCapture.d.ts +10 -0
  190. package/dist/tools/ffmpeg/frameCapture.d.ts.map +1 -0
  191. package/dist/tools/ffmpeg/frameCapture.js +48 -0
  192. package/dist/tools/ffmpeg/frameCapture.js.map +1 -0
  193. package/dist/tools/ffmpeg/silenceDetection.d.ts +10 -0
  194. package/dist/tools/ffmpeg/silenceDetection.d.ts.map +1 -0
  195. package/dist/tools/ffmpeg/silenceDetection.js +55 -0
  196. package/dist/tools/ffmpeg/silenceDetection.js.map +1 -0
  197. package/dist/tools/ffmpeg/singlePassEdit.d.ts +25 -0
  198. package/dist/tools/ffmpeg/singlePassEdit.d.ts.map +1 -0
  199. package/dist/tools/ffmpeg/singlePassEdit.js +123 -0
  200. package/dist/tools/ffmpeg/singlePassEdit.js.map +1 -0
  201. package/dist/tools/search/exaClient.d.ts +8 -0
  202. package/dist/tools/search/exaClient.d.ts.map +1 -0
  203. package/dist/tools/search/exaClient.js +38 -0
  204. package/dist/tools/search/exaClient.js.map +1 -0
  205. package/dist/tools/whisper/whisperClient.d.ts +3 -0
  206. package/dist/tools/whisper/whisperClient.d.ts.map +1 -0
  207. package/dist/tools/whisper/whisperClient.js +77 -0
  208. package/dist/tools/whisper/whisperClient.js.map +1 -0
  209. package/dist/types/index.d.ts +305 -0
  210. package/dist/types/index.d.ts.map +1 -0
  211. package/dist/types/index.js +44 -0
  212. package/dist/types/index.js.map +1 -0
  213. package/package.json +63 -0
@@ -0,0 +1,333 @@
1
+ import { promises as fs } from 'fs';
2
+ import path from 'path';
3
+ import { BaseAgent } from './BaseAgent';
4
+ import { captureFrame } from '../tools/ffmpeg/frameCapture';
5
+ import logger from '../config/logger';
6
+ import { getBrandConfig } from '../config/brand';
7
+ import { getConfig } from '../config/environment';
8
+ // ── Helpers ──────────────────────────────────────────────────────────────────
9
+ /** Format seconds → "MM:SS" */
10
+ function fmtTime(seconds) {
11
+ const m = Math.floor(seconds / 60);
12
+ const s = Math.floor(seconds % 60);
13
+ return `${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`;
14
+ }
15
+ /** Build a compact transcript block with timestamps for the LLM prompt. */
16
+ function buildTranscriptBlock(transcript) {
17
+ return transcript.segments
18
+ .map((seg) => `[${fmtTime(seg.start)} → ${fmtTime(seg.end)}] ${seg.text.trim()}`)
19
+ .join('\n');
20
+ }
21
+ // ── System prompt ────────────────────────────────────────────────────────────
22
+ function buildSystemPrompt(shortsInfo, socialPostsInfo, captionsInfo, chaptersInfo) {
23
+ const brand = getBrandConfig();
24
+ return `You are a Video Summary Agent writing from the perspective of ${brand.name} (${brand.handle}).
25
+ Brand voice: ${brand.voice.tone}. ${brand.voice.personality} ${brand.voice.style}
26
+
27
+ Your job is to analyse a video transcript and produce a beautiful, narrative-style Markdown README.
28
+
29
+ **Workflow**
30
+ 1. Read the transcript carefully.
31
+ 2. Identify 3-8 key topics, decisions, highlights, or memorable moments.
32
+ 3. For each highlight, decide on a representative timestamp and call the "capture_frame" tool to grab a screenshot.
33
+ 4. Once all frames are captured, call the "write_summary" tool with the final Markdown.
34
+
35
+ **Markdown structure — follow this layout exactly:**
36
+
37
+ \`\`\`
38
+ # [Video Title]
39
+
40
+ > [Compelling one-line hook/tagline that captures the video's value]
41
+
42
+ [2-3 paragraph natural summary that reads like a blog post, NOT a timeline.
43
+ Weave in key insights naturally. Write in the brand voice: ${brand.voice.tone}.
44
+ ${brand.contentGuidelines.blogFocus}]
45
+
46
+ ---
47
+
48
+ ## Key Moments
49
+
50
+ [For each key topic: write a narrative paragraph (not bullet points).
51
+ Embed the timestamp as an inline badge like \`[0:12]\` within the text, NOT as a section header.
52
+ Embed the screenshot naturally within or after the paragraph.
53
+ Use blockquotes (>) for standout quotes or insights.]
54
+
55
+ ![Description](thumbnails/snapshot-001.png)
56
+
57
+ [Continue with next topic paragraph...]
58
+
59
+ ---
60
+
61
+ ## 📊 Quick Reference
62
+
63
+ | Topic | Timestamp |
64
+ |-------|-----------|
65
+ | Topic name | \`M:SS\` |
66
+ | ... | ... |
67
+
68
+ ---
69
+ ${chaptersInfo}
70
+ ${shortsInfo}
71
+ ${socialPostsInfo}
72
+ ${captionsInfo}
73
+
74
+ ---
75
+
76
+ *Generated on [DATE] • Duration: [DURATION] • Tags: [relevant tags]*
77
+ \`\`\`
78
+
79
+ **Writing style rules**
80
+ - Write in a narrative, blog-post style — NOT a timestamp-driven timeline.
81
+ - Timestamps appear as subtle inline badges like \`[0:12]\` or \`[1:30]\` within sentences, never as section headers.
82
+ - The summary paragraphs should flow naturally and be enjoyable to read.
83
+ - Use the brand perspective: ${brand.voice.personality}
84
+ - Topics to emphasize: ${brand.advocacy.interests.join(', ')}
85
+ - Avoid: ${brand.advocacy.avoids.join(', ')}
86
+
87
+ **Screenshot distribution rules — CRITICAL**
88
+ - You MUST spread screenshots across the ENTIRE video duration, from beginning to end.
89
+ - Divide the video into equal segments based on the number of screenshots you plan to capture, and pick one timestamp from each segment.
90
+ - NO MORE than 2 screenshots should fall within the same 60-second window.
91
+ - If the video is longer than 2 minutes, your first screenshot must NOT be in the first 10% and your last screenshot must be in the final 30% of the video.
92
+ - Use the suggested timestamp ranges provided in the user message as guidance, but pick the exact moment within each range that best matches a key topic in the transcript.
93
+
94
+ **Tool rules**
95
+ - Always call "capture_frame" BEFORE "write_summary".
96
+ - The snapshot index must be a 1-based integer; the filename will be snapshot-001.png, etc.
97
+ - In the Markdown, reference screenshots as \`thumbnails/snapshot-001.png\` (relative path).
98
+ - Call "write_summary" exactly once with the complete Markdown string.`;
99
+ }
100
+ // ── SummaryAgent ─────────────────────────────────────────────────────────────
101
+ class SummaryAgent extends BaseAgent {
102
+ videoPath;
103
+ outputDir;
104
+ snapshots = [];
105
+ constructor(videoPath, outputDir, systemPrompt) {
106
+ super('SummaryAgent', systemPrompt);
107
+ this.videoPath = videoPath;
108
+ this.outputDir = outputDir;
109
+ }
110
+ // Resolved paths
111
+ get thumbnailDir() {
112
+ return path.join(this.outputDir, 'thumbnails');
113
+ }
114
+ get markdownPath() {
115
+ return path.join(this.outputDir, 'README.md');
116
+ }
117
+ /* ── Tools exposed to the LLM ─────────────────────────────────────────── */
118
+ getTools() {
119
+ return [
120
+ {
121
+ name: 'capture_frame',
122
+ description: 'Capture a screenshot from the video at a specific timestamp. ' +
123
+ 'Provide: timestamp (seconds), description (what is shown), index (1-based integer for filename).',
124
+ parameters: {
125
+ type: 'object',
126
+ properties: {
127
+ timestamp: { type: 'number', description: 'Timestamp in seconds to capture' },
128
+ description: { type: 'string', description: 'Brief description of the visual moment' },
129
+ index: { type: 'integer', description: '1-based snapshot index (used for filename)' },
130
+ },
131
+ required: ['timestamp', 'description', 'index'],
132
+ },
133
+ handler: async (rawArgs) => {
134
+ const args = rawArgs;
135
+ return this.handleCaptureFrame(args);
136
+ },
137
+ },
138
+ {
139
+ name: 'write_summary',
140
+ description: 'Write the final Markdown summary to disk. ' +
141
+ 'Provide: markdown (full README content), title, overview, and keyTopics array.',
142
+ parameters: {
143
+ type: 'object',
144
+ properties: {
145
+ markdown: { type: 'string', description: 'Complete Markdown content for README.md' },
146
+ title: { type: 'string', description: 'Video title' },
147
+ overview: { type: 'string', description: 'Short overview paragraph' },
148
+ keyTopics: {
149
+ type: 'array',
150
+ items: { type: 'string' },
151
+ description: 'List of key topic names',
152
+ },
153
+ },
154
+ required: ['markdown', 'title', 'overview', 'keyTopics'],
155
+ },
156
+ handler: async (rawArgs) => {
157
+ const args = rawArgs;
158
+ return this.handleWriteSummary(args);
159
+ },
160
+ },
161
+ ];
162
+ }
163
+ /* ── Tool dispatch (required by BaseAgent) ─────────────────────────────── */
164
+ async handleToolCall(toolName, args) {
165
+ switch (toolName) {
166
+ case 'capture_frame':
167
+ return this.handleCaptureFrame(args);
168
+ case 'write_summary':
169
+ return this.handleWriteSummary(args);
170
+ default:
171
+ throw new Error(`Unknown tool: ${toolName}`);
172
+ }
173
+ }
174
+ /* ── Tool implementations ──────────────────────────────────────────────── */
175
+ async handleCaptureFrame(args) {
176
+ const idx = String(args.index).padStart(3, '0');
177
+ const filename = `snapshot-${idx}.png`;
178
+ const outputPath = path.join(this.thumbnailDir, filename);
179
+ await captureFrame(this.videoPath, args.timestamp, outputPath);
180
+ const snapshot = {
181
+ timestamp: args.timestamp,
182
+ description: args.description,
183
+ outputPath,
184
+ };
185
+ this.snapshots.push(snapshot);
186
+ logger.info(`[SummaryAgent] Captured snapshot ${idx} at ${fmtTime(args.timestamp)}`);
187
+ return `Frame captured: thumbnails/${filename}`;
188
+ }
189
+ async handleWriteSummary(args) {
190
+ await fs.mkdir(this.outputDir, { recursive: true });
191
+ await fs.writeFile(this.markdownPath, args.markdown, 'utf-8');
192
+ logger.info(`[SummaryAgent] Wrote summary → ${this.markdownPath}`);
193
+ return `Summary written to ${this.markdownPath}`;
194
+ }
195
+ /** Expose collected data after the run. */
196
+ getResult(args) {
197
+ return {
198
+ title: args.title,
199
+ overview: args.overview,
200
+ keyTopics: args.keyTopics,
201
+ snapshots: this.snapshots,
202
+ markdownPath: this.markdownPath,
203
+ };
204
+ }
205
+ }
206
+ // ── Public API ───────────────────────────────────────────────────────────────
207
+ /** Build the Shorts section for the README template. */
208
+ function buildShortsSection(shorts) {
209
+ if (!shorts || shorts.length === 0) {
210
+ return `
211
+ ## ✂️ Shorts
212
+
213
+ | Short | Duration | Description |
214
+ |-------|----------|-------------|
215
+ | *Shorts will appear here once generated* | | |`;
216
+ }
217
+ const rows = shorts
218
+ .map((s) => `| [${s.title}](shorts/${s.slug}.mp4) | ${Math.round(s.totalDuration)}s | ${s.description} |`)
219
+ .join('\n');
220
+ return `
221
+ ## ✂️ Shorts
222
+
223
+ | Short | Duration | Description |
224
+ |-------|----------|-------------|
225
+ ${rows}`;
226
+ }
227
+ /** Build the Social Media Posts section for the README template. */
228
+ function buildSocialPostsSection() {
229
+ return `
230
+ ## 📱 Social Media Posts
231
+
232
+ - [TikTok](social-posts/tiktok.md)
233
+ - [YouTube](social-posts/youtube.md)
234
+ - [Instagram](social-posts/instagram.md)
235
+ - [LinkedIn](social-posts/linkedin.md)
236
+ - [X / Twitter](social-posts/x.md)
237
+ - [Dev.to Blog](social-posts/devto.md)`;
238
+ }
239
+ /** Build the Captions section for the README template. */
240
+ function buildCaptionsSection() {
241
+ return `
242
+ ## 🎬 Captions
243
+
244
+ - [SRT](captions/captions.srt) | [VTT](captions/captions.vtt) | [ASS (Styled)](captions/captions.ass)`;
245
+ }
246
+ /** Format seconds → YouTube-style timestamp for chapters display */
247
+ function toYouTubeTimestamp(seconds) {
248
+ const h = Math.floor(seconds / 3600);
249
+ const m = Math.floor((seconds % 3600) / 60);
250
+ const s = Math.floor(seconds % 60);
251
+ return h > 0
252
+ ? `${h}:${String(m).padStart(2, '0')}:${String(s).padStart(2, '0')}`
253
+ : `${m}:${String(s).padStart(2, '0')}`;
254
+ }
255
+ /** Build the Chapters section for the README template. */
256
+ function buildChaptersSection(chapters) {
257
+ if (!chapters || chapters.length === 0) {
258
+ return '';
259
+ }
260
+ const rows = chapters
261
+ .map((ch) => `| \`${toYouTubeTimestamp(ch.timestamp)}\` | ${ch.title} | ${ch.description} |`)
262
+ .join('\n');
263
+ return `
264
+ ## 📑 Chapters
265
+
266
+ | Time | Chapter | Description |
267
+ |------|---------|-------------|
268
+ ${rows}
269
+
270
+ > 📋 [YouTube Timestamps](chapters/chapters-youtube.txt) • [Markdown](chapters/chapters.md) • [JSON](chapters/chapters.json)`;
271
+ }
272
+ /**
273
+ * Generate a beautiful Markdown summary for a video recording.
274
+ *
275
+ * 1. Creates a SummaryAgent with `capture_frame` and `write_summary` tools
276
+ * 2. Builds a prompt containing the full transcript with timestamps
277
+ * 3. Lets the agent analyse the transcript, capture key frames, and write Markdown
278
+ * 4. Returns a {@link VideoSummary} with metadata and snapshot paths
279
+ */
280
+ export async function generateSummary(video, transcript, shorts, chapters) {
281
+ const config = getConfig();
282
+ const outputDir = path.join(config.OUTPUT_DIR, video.slug);
283
+ // Build content-section snippets for the system prompt
284
+ const shortsInfo = buildShortsSection(shorts);
285
+ const socialPostsInfo = buildSocialPostsSection();
286
+ const captionsInfo = buildCaptionsSection();
287
+ const chaptersInfo = buildChaptersSection(chapters);
288
+ const systemPrompt = buildSystemPrompt(shortsInfo, socialPostsInfo, captionsInfo, chaptersInfo);
289
+ const agent = new SummaryAgent(video.repoPath, outputDir, systemPrompt);
290
+ const transcriptBlock = buildTranscriptBlock(transcript);
291
+ // Pre-calculate suggested screenshot time ranges spread across the full video
292
+ const screenshotCount = Math.min(8, Math.max(3, Math.round(video.duration / 120)));
293
+ const interval = video.duration / screenshotCount;
294
+ const suggestedRanges = Array.from({ length: screenshotCount }, (_, i) => {
295
+ const center = Math.round(interval * (i + 0.5));
296
+ const lo = Math.max(0, Math.round(center - interval / 2));
297
+ const hi = Math.min(Math.round(video.duration), Math.round(center + interval / 2));
298
+ return `${fmtTime(lo)}–${fmtTime(hi)} (${lo}s–${hi}s)`;
299
+ }).join(', ');
300
+ const userPrompt = [
301
+ `**Video:** ${video.filename}`,
302
+ `**Duration:** ${fmtTime(video.duration)} (${Math.round(video.duration)} seconds)`,
303
+ `**Date:** ${video.createdAt.toISOString().slice(0, 10)}`,
304
+ '',
305
+ `**Suggested screenshot time ranges (one screenshot per range):**`,
306
+ suggestedRanges,
307
+ '',
308
+ '---',
309
+ '',
310
+ '**Transcript:**',
311
+ '',
312
+ transcriptBlock,
313
+ ].join('\n');
314
+ let lastWriteArgs;
315
+ // Intercept write_summary args so we can build the return value
316
+ // Uses `as any` to access private method — required by the intercept-and-capture pattern
317
+ const origHandleWrite = agent.handleWriteSummary.bind(agent);
318
+ agent.handleWriteSummary = async (args) => {
319
+ lastWriteArgs = args;
320
+ return origHandleWrite(args);
321
+ };
322
+ try {
323
+ await agent.run(userPrompt);
324
+ if (!lastWriteArgs) {
325
+ throw new Error('SummaryAgent did not call write_summary');
326
+ }
327
+ return agent.getResult(lastWriteArgs);
328
+ }
329
+ finally {
330
+ await agent.destroy();
331
+ }
332
+ }
333
+ //# sourceMappingURL=SummaryAgent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SummaryAgent.js","sourceRoot":"","sources":["../../src/agents/SummaryAgent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface BrandConfig {
2
+ name: string;
3
+ handle: string;
4
+ tagline: string;
5
+ voice: {
6
+ tone: string;
7
+ personality: string;
8
+ style: string;
9
+ };
10
+ advocacy: {
11
+ primary: string[];
12
+ interests: string[];
13
+ avoids: string[];
14
+ };
15
+ customVocabulary: string[];
16
+ hashtags: {
17
+ always: string[];
18
+ preferred: string[];
19
+ platforms: Record<string, string[]>;
20
+ };
21
+ contentGuidelines: {
22
+ shortsFocus: string;
23
+ blogFocus: string;
24
+ socialFocus: string;
25
+ };
26
+ }
27
+ export declare function getBrandConfig(): BrandConfig;
28
+ export declare function getWhisperPrompt(): string;
29
+ //# sourceMappingURL=brand.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand.d.ts","sourceRoot":"","sources":["../../src/config/brand.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE,MAAM,CAAA;IACf,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAA;QACZ,WAAW,EAAE,MAAM,CAAA;QACnB,KAAK,EAAE,MAAM,CAAA;KACd,CAAA;IACD,QAAQ,EAAE;QACR,OAAO,EAAE,MAAM,EAAE,CAAA;QACjB,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,MAAM,EAAE,MAAM,EAAE,CAAA;KACjB,CAAA;IACD,gBAAgB,EAAE,MAAM,EAAE,CAAA;IAC1B,QAAQ,EAAE;QACR,MAAM,EAAE,MAAM,EAAE,CAAA;QAChB,SAAS,EAAE,MAAM,EAAE,CAAA;QACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAA;KACpC,CAAA;IACD,iBAAiB,EAAE;QACjB,WAAW,EAAE,MAAM,CAAA;QACnB,SAAS,EAAE,MAAM,CAAA;QACjB,WAAW,EAAE,MAAM,CAAA;KACpB,CAAA;CACF;AAiED,wBAAgB,cAAc,IAAI,WAAW,CAiB5C;AAGD,wBAAgB,gBAAgB,IAAI,MAAM,CAGzC"}
@@ -0,0 +1,83 @@
1
+ import fs from 'fs';
2
+ import { getConfig } from './environment';
3
+ import logger from './logger';
4
+ const defaultBrand = {
5
+ name: 'Creator',
6
+ handle: '@creator',
7
+ tagline: '',
8
+ voice: {
9
+ tone: 'professional, friendly',
10
+ personality: 'A knowledgeable content creator.',
11
+ style: 'Clear and concise.',
12
+ },
13
+ advocacy: {
14
+ primary: [],
15
+ interests: [],
16
+ avoids: [],
17
+ },
18
+ customVocabulary: [],
19
+ hashtags: {
20
+ always: [],
21
+ preferred: [],
22
+ platforms: {},
23
+ },
24
+ contentGuidelines: {
25
+ shortsFocus: 'Highlight key moments and insights.',
26
+ blogFocus: 'Educational and informative content.',
27
+ socialFocus: 'Engaging and authentic posts.',
28
+ },
29
+ };
30
+ let cachedBrand = null;
31
+ /** Validate brand config and log warnings for missing or empty fields. */
32
+ function validateBrandConfig(brand) {
33
+ const requiredStrings = ['name', 'handle', 'tagline'];
34
+ for (const field of requiredStrings) {
35
+ if (!brand[field]) {
36
+ logger.warn(`brand.json: missing or empty field "${field}"`);
37
+ }
38
+ }
39
+ const requiredObjects = [
40
+ { key: 'voice', subKeys: ['tone', 'personality', 'style'] },
41
+ { key: 'advocacy', subKeys: ['primary', 'interests'] },
42
+ { key: 'hashtags', subKeys: ['always', 'preferred'] },
43
+ { key: 'contentGuidelines', subKeys: ['shortsFocus', 'blogFocus', 'socialFocus'] },
44
+ ];
45
+ for (const { key, subKeys } of requiredObjects) {
46
+ if (!brand[key]) {
47
+ logger.warn(`brand.json: missing section "${key}"`);
48
+ }
49
+ else {
50
+ const section = brand[key];
51
+ for (const sub of subKeys) {
52
+ if (!section[sub] || (Array.isArray(section[sub]) && section[sub].length === 0)) {
53
+ logger.warn(`brand.json: missing or empty field "${key}.${sub}"`);
54
+ }
55
+ }
56
+ }
57
+ }
58
+ if (!brand.customVocabulary || brand.customVocabulary.length === 0) {
59
+ logger.warn('brand.json: "customVocabulary" is empty — Whisper prompt will be blank');
60
+ }
61
+ }
62
+ export function getBrandConfig() {
63
+ if (cachedBrand)
64
+ return cachedBrand;
65
+ const config = getConfig();
66
+ const brandPath = config.BRAND_PATH;
67
+ if (!fs.existsSync(brandPath)) {
68
+ logger.warn('brand.json not found — using defaults');
69
+ cachedBrand = { ...defaultBrand };
70
+ return cachedBrand;
71
+ }
72
+ const raw = fs.readFileSync(brandPath, 'utf-8');
73
+ cachedBrand = JSON.parse(raw);
74
+ validateBrandConfig(cachedBrand);
75
+ logger.info(`Brand config loaded: ${cachedBrand.name}`);
76
+ return cachedBrand;
77
+ }
78
+ // Helper to get Whisper prompt from brand vocabulary
79
+ export function getWhisperPrompt() {
80
+ const brand = getBrandConfig();
81
+ return brand.customVocabulary.join(', ');
82
+ }
83
+ //# sourceMappingURL=brand.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"brand.js","sourceRoot":"","sources":["../../src/config/brand.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ export interface AppEnvironment {
2
+ OPENAI_API_KEY: string;
3
+ WATCH_FOLDER: string;
4
+ REPO_ROOT: string;
5
+ FFMPEG_PATH: string;
6
+ FFPROBE_PATH: string;
7
+ EXA_API_KEY: string;
8
+ OUTPUT_DIR: string;
9
+ BRAND_PATH: string;
10
+ VERBOSE: boolean;
11
+ SKIP_GIT: boolean;
12
+ SKIP_SILENCE_REMOVAL: boolean;
13
+ SKIP_SHORTS: boolean;
14
+ SKIP_MEDIUM_CLIPS: boolean;
15
+ SKIP_SOCIAL: boolean;
16
+ SKIP_CAPTIONS: boolean;
17
+ }
18
+ export interface CLIOptions {
19
+ watchDir?: string;
20
+ outputDir?: string;
21
+ openaiKey?: string;
22
+ exaKey?: string;
23
+ brand?: string;
24
+ verbose?: boolean;
25
+ git?: boolean;
26
+ silenceRemoval?: boolean;
27
+ shorts?: boolean;
28
+ mediumClips?: boolean;
29
+ social?: boolean;
30
+ captions?: boolean;
31
+ }
32
+ export declare function validateRequiredKeys(): void;
33
+ /** Merge CLI options → env vars → defaults. Call before getConfig(). */
34
+ export declare function initConfig(cli?: CLIOptions): AppEnvironment;
35
+ export declare function getConfig(): AppEnvironment;
36
+ //# sourceMappingURL=environment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.d.ts","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"AAUA,MAAM,WAAW,cAAc;IAC7B,cAAc,EAAE,MAAM,CAAA;IACtB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,CAAA;IACnB,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,OAAO,EAAE,OAAO,CAAA;IAChB,QAAQ,EAAE,OAAO,CAAA;IACjB,oBAAoB,EAAE,OAAO,CAAA;IAC7B,WAAW,EAAE,OAAO,CAAA;IACpB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,WAAW,EAAE,OAAO,CAAA;IACpB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,OAAO,CAAC,EAAE,OAAO,CAAA;IACjB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,cAAc,CAAC,EAAE,OAAO,CAAA;IACxB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAA;CACnB;AAID,wBAAgB,oBAAoB,IAAI,IAAI,CAI3C;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,GAAG,GAAE,UAAe,GAAG,cAAc,CAsB/D;AAED,wBAAgB,SAAS,IAAI,cAAc,CAO1C"}
@@ -0,0 +1,44 @@
1
+ import path from 'path';
2
+ import fs from 'fs';
3
+ import dotenv from 'dotenv';
4
+ // Load .env file from repo root
5
+ const envPath = path.join(process.cwd(), '.env');
6
+ if (fs.existsSync(envPath)) {
7
+ dotenv.config({ path: envPath });
8
+ }
9
+ let config = null;
10
+ export function validateRequiredKeys() {
11
+ if (!config?.OPENAI_API_KEY && !process.env.OPENAI_API_KEY) {
12
+ throw new Error('Missing required: OPENAI_API_KEY (set via --openai-key or env var)');
13
+ }
14
+ }
15
+ /** Merge CLI options → env vars → defaults. Call before getConfig(). */
16
+ export function initConfig(cli = {}) {
17
+ const repoRoot = process.env.REPO_ROOT || process.cwd();
18
+ config = {
19
+ OPENAI_API_KEY: cli.openaiKey || process.env.OPENAI_API_KEY || '',
20
+ WATCH_FOLDER: cli.watchDir || process.env.WATCH_FOLDER || path.join(repoRoot, 'watch'),
21
+ REPO_ROOT: repoRoot,
22
+ FFMPEG_PATH: process.env.FFMPEG_PATH || 'ffmpeg',
23
+ FFPROBE_PATH: process.env.FFPROBE_PATH || 'ffprobe',
24
+ EXA_API_KEY: cli.exaKey || process.env.EXA_API_KEY || '',
25
+ OUTPUT_DIR: cli.outputDir || process.env.OUTPUT_DIR || path.join(repoRoot, 'recordings'),
26
+ BRAND_PATH: cli.brand || process.env.BRAND_PATH || path.join(repoRoot, 'brand.json'),
27
+ VERBOSE: cli.verbose ?? false,
28
+ SKIP_GIT: cli.git === false,
29
+ SKIP_SILENCE_REMOVAL: cli.silenceRemoval === false,
30
+ SKIP_SHORTS: cli.shorts === false,
31
+ SKIP_MEDIUM_CLIPS: cli.mediumClips === false,
32
+ SKIP_SOCIAL: cli.social === false,
33
+ SKIP_CAPTIONS: cli.captions === false,
34
+ };
35
+ return config;
36
+ }
37
+ export function getConfig() {
38
+ if (config) {
39
+ return config;
40
+ }
41
+ // Fallback: init with no CLI options (pure env-var mode)
42
+ return initConfig();
43
+ }
44
+ //# sourceMappingURL=environment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"environment.js","sourceRoot":"","sources":["../../src/config/environment.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAA;AACvB,OAAO,EAAE,MAAM,IAAI,CAAA;AACnB,OAAO,MAAM,MAAM,QAAQ,CAAA;AAE3B,gCAAgC;AAChC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAA;AAChD,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3B,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAA;AAClC,CAAC;AAmCD,IAAI,MAAM,GAA0B,IAAI,CAAA;AAExC,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC,MAAM,EAAE,cAAc,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,CAAC;QAC3D,MAAM,IAAI,KAAK,CAAC,oEAAoE,CAAC,CAAA;IACvF,CAAC;AACH,CAAC;AAED,wEAAwE;AACxE,MAAM,UAAU,UAAU,CAAC,MAAkB,EAAE;IAC7C,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,EAAE,CAAA;IAEvD,MAAM,GAAG;QACP,cAAc,EAAE,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,EAAE;QACjE,YAAY,EAAE,GAAG,CAAC,QAAQ,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC;QACtF,SAAS,EAAE,QAAQ;QACnB,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,QAAQ;QAChD,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,SAAS;QACnD,WAAW,EAAE,GAAG,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE;QACxD,UAAU,EAAE,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;QACxF,UAAU,EAAE,GAAG,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,YAAY,CAAC;QACpF,OAAO,EAAE,GAAG,CAAC,OAAO,IAAI,KAAK;QAC7B,QAAQ,EAAE,GAAG,CAAC,GAAG,KAAK,KAAK;QAC3B,oBAAoB,EAAE,GAAG,CAAC,cAAc,KAAK,KAAK;QAClD,WAAW,EAAE,GAAG,CAAC,MAAM,KAAK,KAAK;QACjC,iBAAiB,EAAE,GAAG,CAAC,WAAW,KAAK,KAAK;QAC5C,WAAW,EAAE,GAAG,CAAC,MAAM,KAAK,KAAK;QACjC,aAAa,EAAE,GAAG,CAAC,QAAQ,KAAK,KAAK;KACtC,CAAA;IAED,OAAO,MAAM,CAAA;AACf,CAAC;AAED,MAAM,UAAU,SAAS;IACvB,IAAI,MAAM,EAAE,CAAC;QACX,OAAO,MAAM,CAAA;IACf,CAAC;IAED,yDAAyD;IACzD,OAAO,UAAU,EAAE,CAAA;AACrB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import winston from 'winston';
2
+ declare const logger: winston.Logger;
3
+ export declare function setVerbose(): void;
4
+ export default logger;
5
+ //# sourceMappingURL=logger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/config/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,QAAA,MAAM,MAAM,gBASV,CAAA;AAEF,wBAAgB,UAAU,IAAI,IAAI,CAEjC;AAED,eAAe,MAAM,CAAA"}
@@ -0,0 +1,13 @@
1
+ import winston from 'winston';
2
+ const logger = winston.createLogger({
3
+ level: 'info',
4
+ format: winston.format.combine(winston.format.timestamp(), winston.format.printf(({ timestamp, level, message }) => {
5
+ return `${timestamp} [${level.toUpperCase()}]: ${message}`;
6
+ })),
7
+ transports: [new winston.transports.Console()],
8
+ });
9
+ export function setVerbose() {
10
+ logger.level = 'debug';
11
+ }
12
+ export default logger;
13
+ //# sourceMappingURL=logger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/config/logger.ts"],"names":[],"mappings":"AAAA,OAAO,OAAO,MAAM,SAAS,CAAA;AAE7B,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAClC,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,CAC5B,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAC1B,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE;QACtD,OAAO,GAAG,SAAS,KAAK,KAAK,CAAC,WAAW,EAAE,MAAM,OAAO,EAAE,CAAA;IAC5D,CAAC,CAAC,CACH;IACD,UAAU,EAAE,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;CAC/C,CAAC,CAAA;AAEF,MAAM,UAAU,UAAU;IACxB,MAAM,CAAC,KAAK,GAAG,OAAO,CAAA;AACxB,CAAC;AAED,eAAe,MAAM,CAAA"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}