@redaksjon/protokoll 1.0.11 → 1.0.12-dev.20260208061348.8654d07

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.
@@ -1,71 +1,5 @@
1
1
  import matter from 'gray-matter';
2
2
 
3
- const formatMetadataMarkdown = (metadata) => {
4
- const lines = [];
5
- if (metadata.title) {
6
- lines.push(`# ${metadata.title}`);
7
- lines.push("");
8
- }
9
- lines.push("## Metadata");
10
- lines.push("");
11
- if (metadata.date) {
12
- const dateStr = metadata.date.toLocaleDateString("en-US", {
13
- year: "numeric",
14
- month: "long",
15
- day: "numeric"
16
- });
17
- lines.push(`**Date**: ${dateStr}`);
18
- if (metadata.recordingTime) {
19
- lines.push(`**Time**: ${metadata.recordingTime}`);
20
- } else {
21
- const timeStr = metadata.date.toLocaleTimeString("en-US", {
22
- hour: "2-digit",
23
- minute: "2-digit",
24
- hour12: true
25
- });
26
- lines.push(`**Time**: ${timeStr}`);
27
- }
28
- }
29
- lines.push("");
30
- if (metadata.project) {
31
- lines.push(`**Project**: ${metadata.project}`);
32
- if (metadata.projectId) {
33
- lines.push(`**Project ID**: \`${metadata.projectId}\``);
34
- }
35
- lines.push("");
36
- }
37
- if (metadata.routing) {
38
- lines.push("### Routing");
39
- lines.push("");
40
- lines.push(`**Destination**: ${metadata.routing.destination}`);
41
- lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);
42
- lines.push("");
43
- if (metadata.routing.signals.length > 0) {
44
- lines.push("**Classification Signals**:");
45
- for (const signal of metadata.routing.signals) {
46
- const signalType = signal.type.replace(/_/g, " ");
47
- const weight = (signal.weight * 100).toFixed(0);
48
- lines.push(`- ${signalType}: "${signal.value}" (${weight}% weight)`);
49
- }
50
- lines.push("");
51
- }
52
- if (metadata.routing.reasoning) {
53
- lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);
54
- lines.push("");
55
- }
56
- }
57
- if (metadata.tags && metadata.tags.length > 0) {
58
- lines.push("**Tags**: " + metadata.tags.map((tag) => `\`${tag}\``).join(", "));
59
- lines.push("");
60
- }
61
- if (metadata.duration) {
62
- lines.push(`**Duration**: ${metadata.duration}`);
63
- lines.push("");
64
- }
65
- lines.push("---");
66
- lines.push("");
67
- return lines.join("\n");
68
- };
69
3
  const formatEntityMetadataMarkdown = (metadata) => {
70
4
  if (!metadata.entities) {
71
5
  return "";
@@ -491,5 +425,5 @@ const frontmatter = /*#__PURE__*/Object.freeze(/*#__PURE__*/Object.definePropert
491
425
  updateTranscript
492
426
  }, Symbol.toStringTag, { value: 'Module' }));
493
427
 
494
- export { VALID_STATUSES as V, addTask as a, formatMetadataMarkdown as b, completeTask as c, deleteTask as d, extractTagsFromSignals as e, formatEntityMetadataMarkdown as f, createRoutingMetadata as g, frontmatter as h, isValidStatus as i, parseTranscriptContent as p, stringifyTranscript as s, updateStatus as u };
428
+ export { VALID_STATUSES as V, addTask as a, createRoutingMetadata as b, completeTask as c, deleteTask as d, extractTagsFromSignals as e, formatEntityMetadataMarkdown as f, frontmatter as g, isValidStatus as i, parseTranscriptContent as p, stringifyTranscript as s, updateStatus as u };
495
429
  //# sourceMappingURL=frontmatter.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter.js","sources":["../src/util/metadata.ts","../src/util/frontmatter.ts"],"sourcesContent":["import * as Routing from '@/routing';\n\n// ============================================================================\n// Lifecycle Types\n// ============================================================================\n\n/**\n * Transcript lifecycle status\n * - initial: Whisper transcription complete\n * - enhanced: Context-aware enhancement complete\n * - reviewed: User has reviewed the transcript\n * - in_progress: Has outstanding tasks to complete\n * - closed: All work complete, no pending tasks\n * - archived: Archived for long-term storage\n */\nexport type TranscriptStatus = 'initial' | 'enhanced' | 'reviewed' | 'in_progress' | 'closed' | 'archived';\n\n/**\n * Record of a status transition with timestamp\n */\nexport interface StatusTransition {\n from: TranscriptStatus;\n to: TranscriptStatus;\n at: string; // ISO 8601 timestamp\n}\n\n/**\n * A follow-up task associated with a transcript\n */\nexport interface Task {\n id: string; // generated unique ID (e.g., task-1234567890-abc123)\n description: string;\n status: 'open' | 'done';\n created: string; // ISO 8601 timestamp\n changed?: string; // ISO 8601 timestamp - when last modified\n completed?: string; // ISO 8601 timestamp - when marked done\n}\n\n// ============================================================================\n// Entity Types\n// ============================================================================\n\nexport interface EntityReference {\n id: string;\n name: string;\n type: 'person' | 'project' | 'term' | 'company';\n}\n\nexport interface TranscriptMetadata {\n // Core fields\n title?: string;\n project?: string;\n projectId?: string;\n routing?: RoutingMetadata;\n tags?: string[];\n date?: Date;\n recordingTime?: string;\n confidence?: number;\n duration?: string;\n \n // Lifecycle fields\n status?: TranscriptStatus;\n history?: StatusTransition[];\n tasks?: Task[];\n \n // Entity references - entities mentioned/used in this transcript\n entities?: {\n people?: EntityReference[];\n projects?: EntityReference[];\n terms?: EntityReference[];\n companies?: EntityReference[];\n };\n}\n\nexport interface RoutingMetadata {\n destination: string;\n confidence: number;\n signals: Routing.ClassificationSignal[];\n reasoning: string;\n}\n\n/**\n * Format metadata as Markdown heading section\n */\nexport const formatMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n const lines: string[] = [];\n \n // Title section\n if (metadata.title) {\n lines.push(`# ${metadata.title}`);\n lines.push('');\n }\n \n // Metadata frontmatter as readable markdown\n lines.push('## Metadata');\n lines.push('');\n \n // Date and Time\n if (metadata.date) {\n const dateStr = metadata.date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n lines.push(`**Date**: ${dateStr}`);\n \n if (metadata.recordingTime) {\n lines.push(`**Time**: ${metadata.recordingTime}`);\n } else {\n const timeStr = metadata.date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n lines.push(`**Time**: ${timeStr}`);\n }\n }\n \n lines.push('');\n \n // Project\n if (metadata.project) {\n lines.push(`**Project**: ${metadata.project}`);\n if (metadata.projectId) {\n lines.push(`**Project ID**: \\`${metadata.projectId}\\``);\n }\n lines.push('');\n }\n \n // Routing Information\n if (metadata.routing) {\n lines.push('### Routing');\n lines.push('');\n lines.push(`**Destination**: ${metadata.routing.destination}`);\n lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);\n lines.push('');\n \n if (metadata.routing.signals.length > 0) {\n lines.push('**Classification Signals**:');\n for (const signal of metadata.routing.signals) {\n const signalType = signal.type.replace(/_/g, ' ');\n const weight = (signal.weight * 100).toFixed(0);\n lines.push(`- ${signalType}: \"${signal.value}\" (${weight}% weight)`);\n }\n lines.push('');\n }\n \n if (metadata.routing.reasoning) {\n lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);\n lines.push('');\n }\n }\n \n // Tags\n if (metadata.tags && metadata.tags.length > 0) {\n lines.push('**Tags**: ' + metadata.tags.map(tag => `\\`${tag}\\``).join(', '));\n lines.push('');\n }\n \n // Duration\n if (metadata.duration) {\n lines.push(`**Duration**: ${metadata.duration}`);\n lines.push('');\n }\n \n // Separator\n lines.push('---');\n lines.push('');\n \n return lines.join('\\n');\n};\n\n/**\n * Format entity metadata as Markdown footer section\n * This goes at the END of the transcript for machine readability\n */\nexport const formatEntityMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n if (!metadata.entities) {\n return '';\n }\n \n const lines: string[] = [];\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('## Entity References');\n lines.push('');\n lines.push('<!-- Machine-readable entity metadata for indexing and querying -->');\n lines.push('');\n \n // People\n if (metadata.entities.people && metadata.entities.people.length > 0) {\n lines.push('### People');\n lines.push('');\n for (const person of metadata.entities.people) {\n lines.push(`- \\`${person.id}\\`: ${person.name}`);\n }\n lines.push('');\n }\n \n // Projects\n if (metadata.entities.projects && metadata.entities.projects.length > 0) {\n lines.push('### Projects');\n lines.push('');\n for (const project of metadata.entities.projects) {\n lines.push(`- \\`${project.id}\\`: ${project.name}`);\n }\n lines.push('');\n }\n \n // Terms\n if (metadata.entities.terms && metadata.entities.terms.length > 0) {\n lines.push('### Terms');\n lines.push('');\n for (const term of metadata.entities.terms) {\n lines.push(`- \\`${term.id}\\`: ${term.name}`);\n }\n lines.push('');\n }\n \n // Companies\n if (metadata.entities.companies && metadata.entities.companies.length > 0) {\n lines.push('### Companies');\n lines.push('');\n for (const company of metadata.entities.companies) {\n lines.push(`- \\`${company.id}\\`: ${company.name}`);\n }\n lines.push('');\n }\n \n return lines.join('\\n');\n};\n\n/**\n * Parse entity metadata from a transcript\n * Reads the Entity References section if present\n */\nexport const parseEntityMetadata = (content: string): TranscriptMetadata['entities'] | undefined => {\n // Find the Entity References section\n // Look for \"## Entity References\" and capture everything after it until the next \"##\" header or end of content\n const headerIndex = content.indexOf('## Entity References');\n if (headerIndex === -1) {\n return undefined;\n }\n \n // Find the start of the content (after the header and any whitespace/newlines)\n let contentStart = headerIndex + '## Entity References'.length;\n // Skip whitespace and newlines\n while (contentStart < content.length && (content[contentStart] === '\\n' || content[contentStart] === '\\r' || content[contentStart] === ' ' || content[contentStart] === '\\t')) {\n contentStart++;\n }\n \n // Find the end - look for next \"##\" at start of line or end of content\n const remainingContent = content.substring(contentStart);\n const nextHeaderMatch = remainingContent.match(/\\n## /);\n const sectionContent = nextHeaderMatch \n ? remainingContent.substring(0, nextHeaderMatch.index)\n : remainingContent;\n const entities: NonNullable<TranscriptMetadata['entities']> = {\n people: [],\n projects: [],\n terms: [],\n companies: [],\n };\n \n // Parse each entity type\n const parseEntities = (type: 'People' | 'Projects' | 'Terms' | 'Companies'): EntityReference[] => {\n // Map plural type names to singular entity types\n const typeMap: Record<string, 'person' | 'project' | 'term' | 'company'> = {\n 'People': 'person',\n 'Projects': 'project',\n 'Terms': 'term',\n 'Companies': 'company',\n };\n \n const entityType = typeMap[type];\n \n // Find the section for this type\n const sectionHeader = `### ${type}`;\n const sectionStart = sectionContent.indexOf(sectionHeader);\n if (sectionStart === -1) return [];\n \n // Find the end (next ### or end of content)\n // Skip past the header line (including newline)\n const headerEnd = sectionStart + sectionHeader.length;\n let sectionTextStart = headerEnd;\n // Skip whitespace and newlines after the header\n while (sectionTextStart < sectionContent.length && \n (sectionContent[sectionTextStart] === '\\n' || sectionContent[sectionTextStart] === '\\r' || sectionContent[sectionTextStart] === ' ')) {\n sectionTextStart++;\n }\n \n const afterSection = sectionContent.substring(sectionTextStart);\n const nextSection = afterSection.search(/\\n###/);\n const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);\n \n // Extract items - match format: \"- `id`: name\"\n // Match bullet point with backticked ID and name\n const items: EntityReference[] = [];\n // Use multiline regex to match across lines, look for \"- `id`: name\" pattern\n const lines = sectionText.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Match: \"- `id`: name\" or \"- `id`:name\" (with or without space after colon)\n const match = trimmed.match(/^- `([^`]+)`:\\s*(.+)$/);\n if (match) {\n items.push({\n id: match[1],\n name: match[2].trim(),\n type: entityType,\n });\n }\n }\n \n return items;\n };\n \n entities.people = parseEntities('People');\n entities.projects = parseEntities('Projects');\n entities.terms = parseEntities('Terms');\n entities.companies = parseEntities('Companies');\n \n // Only return if we found any entities\n const hasEntities = \n entities.people.length > 0 ||\n entities.projects.length > 0 ||\n entities.terms.length > 0 ||\n entities.companies.length > 0;\n \n return hasEntities ? entities : undefined;\n};\n\n/**\n * Extract routing metadata from a RouteDecision\n */\nexport const createRoutingMetadata = (decision: Routing.RouteDecision): RoutingMetadata => {\n return {\n destination: decision.destination.path,\n confidence: decision.confidence,\n signals: decision.signals,\n reasoning: decision.reasoning,\n };\n};\n\n/**\n * Format duration in seconds to readable format (e.g., \"2m 30s\")\n */\nexport const formatDuration = (seconds: number): string => {\n const minutes = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n \n if (minutes === 0) {\n return `${secs}s`;\n }\n \n if (secs === 0) {\n return `${minutes}m`;\n }\n \n return `${minutes}m ${secs}s`;\n};\n\n/**\n * Format time as HH:MM AM/PM\n */\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\n/**\n * Extract topic from routing signals\n */\nexport const extractTopicFromSignals = (signals: Routing.ClassificationSignal[]): string | undefined => {\n const topicSignal = signals.find(s => s.type === 'topic' || s.type === 'context_type');\n return topicSignal?.value;\n};\n\n/**\n * Extract all tags from routing signals\n * Tags are deduplicated to avoid duplicates from multiple signal sources\n */\nexport const extractTagsFromSignals = (signals: Routing.ClassificationSignal[]): string[] => {\n const tags = signals\n .filter(s => s.type !== 'context_type') // Skip generic context type\n .map(s => s.value)\n .filter((v): v is string => typeof v === 'string');\n \n // Deduplicate tags using Set\n return Array.from(new Set(tags));\n};\n\n// ============================================================================\n// Lifecycle Utilities\n// ============================================================================\n\n/**\n * Valid transcript statuses for validation\n */\nexport const VALID_STATUSES: TranscriptStatus[] = [\n 'initial', 'enhanced', 'reviewed', 'in_progress', 'closed', 'archived'\n];\n\n/**\n * Check if a string is a valid TranscriptStatus\n */\nexport const isValidStatus = (status: string): status is TranscriptStatus => {\n return VALID_STATUSES.includes(status as TranscriptStatus);\n};\n\n/**\n * Generate a unique task ID\n */\nexport const generateTaskId = (): string => {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `task-${timestamp}-${random}`;\n};\n\n/**\n * Create a new task\n */\nexport const createTask = (description: string): Task => {\n return {\n id: generateTaskId(),\n description,\n status: 'open',\n created: new Date().toISOString(),\n };\n};\n\n/**\n * Update transcript status and record the transition in history\n * Returns unchanged metadata if status is the same (no duplicate history)\n */\nexport const updateStatus = (\n metadata: TranscriptMetadata,\n newStatus: TranscriptStatus\n): TranscriptMetadata => {\n const oldStatus = metadata.status;\n \n // Don't add duplicate history if status unchanged\n if (oldStatus === newStatus) {\n return metadata;\n }\n \n const transition: StatusTransition = {\n from: oldStatus || 'reviewed',\n to: newStatus,\n at: new Date().toISOString(),\n };\n \n return {\n ...metadata,\n status: newStatus,\n history: [...(metadata.history || []), transition],\n };\n};\n\n/**\n * Apply default lifecycle fields to metadata\n * Used during lazy migration of old-format transcripts\n */\nexport const applyLifecycleDefaults = (metadata: TranscriptMetadata): TranscriptMetadata => {\n return {\n ...metadata,\n status: metadata.status ?? 'reviewed',\n history: metadata.history ?? [],\n tasks: metadata.tasks ?? [],\n };\n};\n\n/**\n * Complete a task by ID\n */\nexport const completeTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n const now = new Date().toISOString();\n const updatedTasks = [...tasks];\n updatedTasks[taskIndex] = {\n ...updatedTasks[taskIndex],\n status: 'done',\n changed: now,\n completed: now,\n };\n \n return {\n ...metadata,\n tasks: updatedTasks,\n };\n};\n\n/**\n * Delete a task by ID\n */\nexport const deleteTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n return {\n ...metadata,\n tasks: tasks.filter(t => t.id !== taskId),\n };\n};\n\n/**\n * Add a task to metadata\n */\nexport const addTask = (metadata: TranscriptMetadata, description: string): { metadata: TranscriptMetadata; task: Task } => {\n const task = createTask(description);\n \n return {\n metadata: {\n ...metadata,\n tasks: [...(metadata.tasks || []), task],\n },\n task,\n };\n};\n\n\n","/**\n * Frontmatter parsing utilities using gray-matter\n * \n * This module provides reliable YAML frontmatter parsing for transcript files,\n * consolidating all machine-readable data in frontmatter.\n */\n\nimport matter from 'gray-matter';\nimport { TranscriptMetadata, parseEntityMetadata, applyLifecycleDefaults, TranscriptStatus, StatusTransition, Task } from './metadata';\n\nexport interface ParsedFrontmatter {\n /** Parsed metadata from frontmatter (with lifecycle defaults applied) */\n metadata: TranscriptMetadata;\n /** Clean body content (no entity section, no legacy metadata sections) */\n body: string;\n /** Whether this file needs migration (old format detected) */\n needsMigration: boolean;\n}\n\n// Re-export types for convenience\nexport type { TranscriptMetadata, TranscriptStatus, StatusTransition, Task };\n\n/**\n * Parse old-style ## Metadata section from body content\n */\nfunction parseOldMetadataSection(content: string): Partial<TranscriptMetadata> {\n const metadata: Partial<TranscriptMetadata> = {};\n \n // Find the ## Metadata section\n // Look for ## Metadata followed by content until we hit --- or another ## or end of string\n const metadataMatch = content.match(/## Metadata\\s*\\n([\\s\\S]*?)(?:\\n---|\\n##|$)/);\n if (!metadataMatch) {\n return metadata;\n }\n \n const metadataSection = metadataMatch[1];\n \n // Extract project\n const projectMatch = metadataSection.match(/\\*\\*Project\\*\\*:\\s*(.+)/);\n if (projectMatch) {\n metadata.project = projectMatch[1].trim();\n }\n \n // Extract project ID\n const projectIdMatch = metadataSection.match(/\\*\\*Project ID\\*\\*:\\s*`([^`]+)`/);\n if (projectIdMatch) {\n metadata.projectId = projectIdMatch[1].trim();\n }\n \n // Extract tags\n const tagsMatch = metadataSection.match(/\\*\\*Tags\\*\\*:\\s*(.+)/);\n if (tagsMatch) {\n const tagsStr = tagsMatch[1];\n // Tags are formatted as `tag1`, `tag2`, `tag3`\n const tags = tagsStr.match(/`([^`]+)`/g);\n if (tags) {\n metadata.tags = tags.map(t => t.replace(/`/g, '').trim());\n }\n }\n \n // Extract date\n const dateMatch = metadataSection.match(/\\*\\*Date\\*\\*:\\s*(.+)/);\n if (dateMatch) {\n const dateStr = dateMatch[1].trim();\n // Try to parse the date (format: \"December 22, 2025\")\n const parsed = new Date(dateStr);\n if (!isNaN(parsed.getTime())) {\n metadata.date = parsed;\n }\n }\n \n // Extract time\n const timeMatch = metadataSection.match(/\\*\\*Time\\*\\*:\\s*(.+)/);\n if (timeMatch) {\n metadata.recordingTime = timeMatch[1].trim();\n }\n \n // Extract routing information\n const routingMatch = metadataSection.match(/### Routing\\s+([\\s\\S]*?)(?:\\n###|\\n##|$)/);\n if (routingMatch) {\n const routingSection = routingMatch[1];\n \n const destMatch = routingSection.match(/\\*\\*Destination\\*\\*:\\s*(.+)/);\n const confMatch = routingSection.match(/\\*\\*Confidence\\*\\*:\\s*([\\d.]+)%/);\n const reasoningMatch = routingSection.match(/\\*\\*Reasoning\\*\\*:\\s*(.+)/);\n \n if (destMatch || confMatch) {\n metadata.routing = {\n destination: destMatch ? destMatch[1].trim() : '',\n confidence: confMatch ? parseFloat(confMatch[1]) / 100 : 0,\n signals: [],\n reasoning: reasoningMatch ? reasoningMatch[1].trim() : '',\n };\n \n // Extract classification signals\n const signalsMatch = routingSection.match(/\\*\\*Classification Signals\\*\\*:\\s+([\\s\\S]*?)(?:\\n\\*\\*|$)/);\n if (signalsMatch) {\n const signalsText = signalsMatch[1];\n const signalLines = signalsText.split('\\n').filter(l => l.trim().startsWith('-'));\n \n for (const line of signalLines) {\n // Format: - topic: \"Node.js\" (30% weight)\n const signalMatch = line.match(/- ([^:]+):\\s*\"([^\"]+)\"\\s*\\((\\d+)% weight\\)/);\n if (signalMatch) {\n const typeStr = signalMatch[1].trim().replace(/ /g, '_');\n // Map to valid signal types\n const validTypes = ['explicit_phrase', 'associated_person', 'associated_company', 'topic', 'context_type'];\n const type = validTypes.includes(typeStr) ? typeStr : 'topic';\n \n metadata.routing.signals.push({\n type: type as 'explicit_phrase' | 'associated_person' | 'associated_company' | 'topic' | 'context_type',\n value: signalMatch[2].trim(),\n weight: parseFloat(signalMatch[3]) / 100,\n });\n }\n }\n }\n }\n }\n \n return metadata;\n}\n\n/**\n * Parse a transcript file using gray-matter\n * Handles both new format (all metadata in frontmatter) and old format (entities in body)\n */\nexport function parseTranscriptContent(content: string): ParsedFrontmatter {\n // Parse frontmatter using gray-matter\n const { data: frontmatter, content: rawBody } = matter(content);\n \n // Detect if this is old format\n const needsMigration = isOldFormat(content, frontmatter);\n \n // Build metadata from frontmatter\n let metadata: TranscriptMetadata = {\n title: frontmatter.title,\n date: frontmatter.date ? new Date(frontmatter.date) : undefined,\n recordingTime: frontmatter.recordingTime,\n duration: frontmatter.duration,\n project: frontmatter.project,\n projectId: frontmatter.projectId,\n tags: frontmatter.tags,\n confidence: frontmatter.confidence,\n routing: frontmatter.routing,\n status: frontmatter.status,\n history: frontmatter.history,\n tasks: frontmatter.tasks,\n entities: frontmatter.entities,\n };\n \n // If old format, parse the ## Metadata section from the original content\n // (not rawBody, because gray-matter might have consumed it)\n if (needsMigration) {\n const oldMetadata = parseOldMetadataSection(content);\n // Merge: start with old metadata, then overlay frontmatter values (if present)\n // Only overlay non-undefined values from frontmatter\n metadata = {\n ...oldMetadata,\n ...(metadata.title !== undefined && { title: metadata.title }),\n ...(metadata.date !== undefined && { date: metadata.date }),\n ...(metadata.recordingTime !== undefined && { recordingTime: metadata.recordingTime }),\n ...(metadata.duration !== undefined && { duration: metadata.duration }),\n ...(metadata.project !== undefined && { project: metadata.project }),\n ...(metadata.projectId !== undefined && { projectId: metadata.projectId }),\n ...(metadata.tags !== undefined && { tags: metadata.tags }),\n ...(metadata.confidence !== undefined && { confidence: metadata.confidence }),\n ...(metadata.routing !== undefined && { routing: metadata.routing }),\n ...(metadata.status !== undefined && { status: metadata.status }),\n ...(metadata.history !== undefined && { history: metadata.history }),\n ...(metadata.tasks !== undefined && { tasks: metadata.tasks }),\n ...(metadata.entities !== undefined && { entities: metadata.entities }),\n };\n }\n \n // If entities not in frontmatter, try to extract from body (old format)\n if (!metadata.entities) {\n const extractedEntities = parseEntityMetadata(rawBody);\n if (extractedEntities) {\n metadata.entities = extractedEntities;\n }\n }\n \n // Extract title from body if not in frontmatter (old format)\n let cleanBody = rawBody;\n const titleMatch = rawBody.match(/^#\\s+(.+)$/m);\n \n if (!metadata.title && titleMatch) {\n // No title in frontmatter, extract from H1\n metadata.title = titleMatch[1].trim();\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n } else if (metadata.title && titleMatch) {\n // Title in frontmatter, remove H1 from body\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Apply lifecycle defaults\n metadata = applyLifecycleDefaults(metadata);\n \n // Clean the body (remove entity section if present)\n cleanBody = stripLegacySections(cleanBody);\n \n return {\n metadata,\n body: cleanBody,\n needsMigration,\n };\n}\n\n/**\n * Detect if a file is in old format\n */\nfunction isOldFormat(content: string, frontmatter: Record<string, unknown>): boolean {\n // No frontmatter at all\n if (!content.startsWith('---')) {\n return true;\n }\n \n // Has frontmatter but entities are in body, not frontmatter\n if (!frontmatter.entities && content.includes('## Entity References')) {\n return true;\n }\n \n // Has legacy ## Metadata section in body\n if (content.includes('\\n## Metadata\\n')) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Strip legacy sections from body content\n * Removes: ## Entity References, ## Metadata\n * Note: This must be careful not to remove these patterns if they appear in code blocks\n */\nexport function stripLegacySections(body: string): string {\n let clean = body;\n \n // Remove ## Metadata section (at start, before content)\n // This is trickier - it's between title and content\n // Pattern: ## Metadata ... --- (the --- is the separator before content)\n // Only match if it's at the start of the content (after optional whitespace)\n clean = clean.replace(/^(\\s*)## Metadata[\\s\\S]*?\\n---\\n/, '');\n \n // Remove ## Entity References section (at end of file)\n // Pattern: optional separator (---), then ## Entity References, then everything after\n // We need to be more careful here to avoid matching inside code blocks\n // Look for the pattern at the end of the file, after a separator\n const entityRefPattern = /\\n---\\s*\\n+## Entity References[\\s\\S]*$/;\n if (entityRefPattern.test(clean)) {\n clean = clean.replace(entityRefPattern, '');\n } else {\n // Try without the separator (some files might not have it)\n // But only if it's truly at the end (no other ## headers after it)\n const endPattern = /\\n## Entity References\\s*\\n[\\s\\S]*$/;\n if (endPattern.test(clean)) {\n // Check if there are any other ## headers after this point\n const match = clean.match(endPattern);\n if (match) {\n const entitySection = match[0];\n // If there are no other ## headers in this section (except Entity References sub-headers like ### Projects)\n // then it's safe to remove\n const otherHeaders = entitySection.match(/\\n## (?!Entity References)/g);\n if (!otherHeaders || otherHeaders.length === 0) {\n clean = clean.replace(endPattern, '');\n }\n }\n }\n }\n \n return clean.trim();\n}\n\n/**\n * Check if metadata has any entities\n */\nexport function hasEntities(entities: TranscriptMetadata['entities']): boolean {\n if (!entities) return false;\n return !!(\n entities.people?.length || \n entities.projects?.length || \n entities.terms?.length || \n entities.companies?.length\n );\n}\n\n// ============================================================================\n// Writing Functions\n// ============================================================================\n\n/**\n * Build a frontmatter object from TranscriptMetadata\n * Only includes non-empty values to keep YAML clean\n */\nexport function buildFrontmatter(metadata: TranscriptMetadata): Record<string, unknown> {\n const fm: Record<string, unknown> = {};\n \n // Core fields\n if (metadata.title) fm.title = metadata.title;\n if (metadata.date) fm.date = metadata.date.toISOString();\n if (metadata.recordingTime) fm.recordingTime = metadata.recordingTime;\n if (metadata.duration) fm.duration = metadata.duration;\n if (metadata.project) fm.project = metadata.project;\n if (metadata.projectId) fm.projectId = metadata.projectId;\n if (metadata.tags && metadata.tags.length > 0) fm.tags = metadata.tags;\n if (metadata.confidence !== undefined) fm.confidence = metadata.confidence;\n \n // Routing\n if (metadata.routing) fm.routing = metadata.routing;\n \n // Lifecycle\n if (metadata.status) fm.status = metadata.status;\n if (metadata.history && metadata.history.length > 0) fm.history = metadata.history;\n if (metadata.tasks && metadata.tasks.length > 0) fm.tasks = metadata.tasks;\n \n // Entities (now in frontmatter, not in body)\n if (hasEntities(metadata.entities)) {\n fm.entities = metadata.entities;\n }\n \n return fm;\n}\n\n/**\n * Stringify a transcript with YAML frontmatter\n * Uses gray-matter for consistent output\n * Ensures title is ONLY in frontmatter, never in body\n */\nexport function stringifyTranscript(metadata: TranscriptMetadata, body: string): string {\n const frontmatter = buildFrontmatter(metadata);\n \n // Clean the body (remove any legacy sections)\n let cleanBody = stripLegacySections(body);\n \n // Remove any leading frontmatter delimiters from the body\n // This can happen if the body was extracted incorrectly or has leftover delimiters\n cleanBody = cleanBody.replace(/^---\\s*\\n/, '').trim();\n \n // Remove H1 title from body if it matches the frontmatter title\n // Title should ONLY be in frontmatter\n if (metadata.title) {\n // Remove exact H1 match\n const h1Pattern = new RegExp(`^#\\\\s+${escapeRegex(metadata.title)}\\\\s*$`, 'm');\n cleanBody = cleanBody.replace(h1Pattern, '').trim();\n \n // Also remove any H1 at the start of the body (common pattern)\n cleanBody = cleanBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Use gray-matter to create the output\n // It handles YAML serialization, escaping, etc.\n return matter.stringify(cleanBody + '\\n', frontmatter);\n}\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Update a transcript's content while preserving/updating metadata\n * This is the main function for saving transcripts in the new format\n */\nexport function updateTranscript(\n originalContent: string,\n updates: {\n body?: string;\n metadata?: Partial<TranscriptMetadata>;\n }\n): string {\n // Parse the original\n const parsed = parseTranscriptContent(originalContent);\n \n // Merge metadata updates\n const newMetadata: TranscriptMetadata = {\n ...parsed.metadata,\n ...updates.metadata,\n };\n \n // Use updated body or original\n const newBody = updates.body ?? parsed.body;\n \n // Stringify with new format\n return stringifyTranscript(newMetadata, newBody);\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"frontmatter.js","sources":["../src/util/metadata.ts","../src/util/frontmatter.ts"],"sourcesContent":["import * as Routing from '@/routing';\n\n// ============================================================================\n// Lifecycle Types\n// ============================================================================\n\n/**\n * Transcript lifecycle status\n * - initial: Whisper transcription complete\n * - enhanced: Context-aware enhancement complete\n * - reviewed: User has reviewed the transcript\n * - in_progress: Has outstanding tasks to complete\n * - closed: All work complete, no pending tasks\n * - archived: Archived for long-term storage\n */\nexport type TranscriptStatus = 'initial' | 'enhanced' | 'reviewed' | 'in_progress' | 'closed' | 'archived';\n\n/**\n * Record of a status transition with timestamp\n */\nexport interface StatusTransition {\n from: TranscriptStatus;\n to: TranscriptStatus;\n at: string; // ISO 8601 timestamp\n}\n\n/**\n * A follow-up task associated with a transcript\n */\nexport interface Task {\n id: string; // generated unique ID (e.g., task-1234567890-abc123)\n description: string;\n status: 'open' | 'done';\n created: string; // ISO 8601 timestamp\n changed?: string; // ISO 8601 timestamp - when last modified\n completed?: string; // ISO 8601 timestamp - when marked done\n}\n\n// ============================================================================\n// Entity Types\n// ============================================================================\n\nexport interface EntityReference {\n id: string;\n name: string;\n type: 'person' | 'project' | 'term' | 'company';\n}\n\nexport interface TranscriptMetadata {\n // Core fields\n title?: string;\n project?: string;\n projectId?: string;\n routing?: RoutingMetadata;\n tags?: string[];\n date?: Date;\n recordingTime?: string;\n confidence?: number;\n duration?: string;\n \n // Lifecycle fields\n status?: TranscriptStatus;\n history?: StatusTransition[];\n tasks?: Task[];\n \n // Entity references - entities mentioned/used in this transcript\n entities?: {\n people?: EntityReference[];\n projects?: EntityReference[];\n terms?: EntityReference[];\n companies?: EntityReference[];\n };\n}\n\nexport interface RoutingMetadata {\n destination: string;\n confidence: number;\n signals: Routing.ClassificationSignal[];\n reasoning: string;\n}\n\n/**\n * Format metadata as Markdown heading section\n */\nexport const formatMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n const lines: string[] = [];\n \n // Title section\n if (metadata.title) {\n lines.push(`# ${metadata.title}`);\n lines.push('');\n }\n \n // Metadata frontmatter as readable markdown\n lines.push('## Metadata');\n lines.push('');\n \n // Date and Time\n if (metadata.date) {\n const dateStr = metadata.date.toLocaleDateString('en-US', {\n year: 'numeric',\n month: 'long',\n day: 'numeric'\n });\n lines.push(`**Date**: ${dateStr}`);\n \n if (metadata.recordingTime) {\n lines.push(`**Time**: ${metadata.recordingTime}`);\n } else {\n const timeStr = metadata.date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n lines.push(`**Time**: ${timeStr}`);\n }\n }\n \n lines.push('');\n \n // Project\n if (metadata.project) {\n lines.push(`**Project**: ${metadata.project}`);\n if (metadata.projectId) {\n lines.push(`**Project ID**: \\`${metadata.projectId}\\``);\n }\n lines.push('');\n }\n \n // Routing Information\n if (metadata.routing) {\n lines.push('### Routing');\n lines.push('');\n lines.push(`**Destination**: ${metadata.routing.destination}`);\n lines.push(`**Confidence**: ${(metadata.routing.confidence * 100).toFixed(1)}%`);\n lines.push('');\n \n if (metadata.routing.signals.length > 0) {\n lines.push('**Classification Signals**:');\n for (const signal of metadata.routing.signals) {\n const signalType = signal.type.replace(/_/g, ' ');\n const weight = (signal.weight * 100).toFixed(0);\n lines.push(`- ${signalType}: \"${signal.value}\" (${weight}% weight)`);\n }\n lines.push('');\n }\n \n if (metadata.routing.reasoning) {\n lines.push(`**Reasoning**: ${metadata.routing.reasoning}`);\n lines.push('');\n }\n }\n \n // Tags\n if (metadata.tags && metadata.tags.length > 0) {\n lines.push('**Tags**: ' + metadata.tags.map(tag => `\\`${tag}\\``).join(', '));\n lines.push('');\n }\n \n // Duration\n if (metadata.duration) {\n lines.push(`**Duration**: ${metadata.duration}`);\n lines.push('');\n }\n \n // Separator\n lines.push('---');\n lines.push('');\n \n return lines.join('\\n');\n};\n\n/**\n * Format entity metadata as Markdown footer section\n * This goes at the END of the transcript for machine readability\n */\nexport const formatEntityMetadataMarkdown = (metadata: TranscriptMetadata): string => {\n if (!metadata.entities) {\n return '';\n }\n \n const lines: string[] = [];\n lines.push('');\n lines.push('---');\n lines.push('');\n lines.push('## Entity References');\n lines.push('');\n lines.push('<!-- Machine-readable entity metadata for indexing and querying -->');\n lines.push('');\n \n // People\n if (metadata.entities.people && metadata.entities.people.length > 0) {\n lines.push('### People');\n lines.push('');\n for (const person of metadata.entities.people) {\n lines.push(`- \\`${person.id}\\`: ${person.name}`);\n }\n lines.push('');\n }\n \n // Projects\n if (metadata.entities.projects && metadata.entities.projects.length > 0) {\n lines.push('### Projects');\n lines.push('');\n for (const project of metadata.entities.projects) {\n lines.push(`- \\`${project.id}\\`: ${project.name}`);\n }\n lines.push('');\n }\n \n // Terms\n if (metadata.entities.terms && metadata.entities.terms.length > 0) {\n lines.push('### Terms');\n lines.push('');\n for (const term of metadata.entities.terms) {\n lines.push(`- \\`${term.id}\\`: ${term.name}`);\n }\n lines.push('');\n }\n \n // Companies\n if (metadata.entities.companies && metadata.entities.companies.length > 0) {\n lines.push('### Companies');\n lines.push('');\n for (const company of metadata.entities.companies) {\n lines.push(`- \\`${company.id}\\`: ${company.name}`);\n }\n lines.push('');\n }\n \n return lines.join('\\n');\n};\n\n/**\n * Parse entity metadata from a transcript\n * Reads the Entity References section if present\n */\nexport const parseEntityMetadata = (content: string): TranscriptMetadata['entities'] | undefined => {\n // Find the Entity References section\n // Look for \"## Entity References\" and capture everything after it until the next \"##\" header or end of content\n const headerIndex = content.indexOf('## Entity References');\n if (headerIndex === -1) {\n return undefined;\n }\n \n // Find the start of the content (after the header and any whitespace/newlines)\n let contentStart = headerIndex + '## Entity References'.length;\n // Skip whitespace and newlines\n while (contentStart < content.length && (content[contentStart] === '\\n' || content[contentStart] === '\\r' || content[contentStart] === ' ' || content[contentStart] === '\\t')) {\n contentStart++;\n }\n \n // Find the end - look for next \"##\" at start of line or end of content\n const remainingContent = content.substring(contentStart);\n const nextHeaderMatch = remainingContent.match(/\\n## /);\n const sectionContent = nextHeaderMatch \n ? remainingContent.substring(0, nextHeaderMatch.index)\n : remainingContent;\n const entities: NonNullable<TranscriptMetadata['entities']> = {\n people: [],\n projects: [],\n terms: [],\n companies: [],\n };\n \n // Parse each entity type\n const parseEntities = (type: 'People' | 'Projects' | 'Terms' | 'Companies'): EntityReference[] => {\n // Map plural type names to singular entity types\n const typeMap: Record<string, 'person' | 'project' | 'term' | 'company'> = {\n 'People': 'person',\n 'Projects': 'project',\n 'Terms': 'term',\n 'Companies': 'company',\n };\n \n const entityType = typeMap[type];\n \n // Find the section for this type\n const sectionHeader = `### ${type}`;\n const sectionStart = sectionContent.indexOf(sectionHeader);\n if (sectionStart === -1) return [];\n \n // Find the end (next ### or end of content)\n // Skip past the header line (including newline)\n const headerEnd = sectionStart + sectionHeader.length;\n let sectionTextStart = headerEnd;\n // Skip whitespace and newlines after the header\n while (sectionTextStart < sectionContent.length && \n (sectionContent[sectionTextStart] === '\\n' || sectionContent[sectionTextStart] === '\\r' || sectionContent[sectionTextStart] === ' ')) {\n sectionTextStart++;\n }\n \n const afterSection = sectionContent.substring(sectionTextStart);\n const nextSection = afterSection.search(/\\n###/);\n const sectionText = nextSection === -1 ? afterSection : afterSection.substring(0, nextSection);\n \n // Extract items - match format: \"- `id`: name\"\n // Match bullet point with backticked ID and name\n const items: EntityReference[] = [];\n // Use multiline regex to match across lines, look for \"- `id`: name\" pattern\n const lines = sectionText.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n // Match: \"- `id`: name\" or \"- `id`:name\" (with or without space after colon)\n const match = trimmed.match(/^- `([^`]+)`:\\s*(.+)$/);\n if (match) {\n items.push({\n id: match[1],\n name: match[2].trim(),\n type: entityType,\n });\n }\n }\n \n return items;\n };\n \n entities.people = parseEntities('People');\n entities.projects = parseEntities('Projects');\n entities.terms = parseEntities('Terms');\n entities.companies = parseEntities('Companies');\n \n // Only return if we found any entities\n const hasEntities = \n entities.people.length > 0 ||\n entities.projects.length > 0 ||\n entities.terms.length > 0 ||\n entities.companies.length > 0;\n \n return hasEntities ? entities : undefined;\n};\n\n/**\n * Extract routing metadata from a RouteDecision\n */\nexport const createRoutingMetadata = (decision: Routing.RouteDecision): RoutingMetadata => {\n return {\n destination: decision.destination.path,\n confidence: decision.confidence,\n signals: decision.signals,\n reasoning: decision.reasoning,\n };\n};\n\n/**\n * Format duration in seconds to readable format (e.g., \"2m 30s\")\n */\nexport const formatDuration = (seconds: number): string => {\n const minutes = Math.floor(seconds / 60);\n const secs = Math.round(seconds % 60);\n \n if (minutes === 0) {\n return `${secs}s`;\n }\n \n if (secs === 0) {\n return `${minutes}m`;\n }\n \n return `${minutes}m ${secs}s`;\n};\n\n/**\n * Format time as HH:MM AM/PM\n */\nexport const formatTime = (date: Date): string => {\n return date.toLocaleTimeString('en-US', {\n hour: '2-digit',\n minute: '2-digit',\n hour12: true\n });\n};\n\n/**\n * Extract topic from routing signals\n */\nexport const extractTopicFromSignals = (signals: Routing.ClassificationSignal[]): string | undefined => {\n const topicSignal = signals.find(s => s.type === 'topic' || s.type === 'context_type');\n return topicSignal?.value;\n};\n\n/**\n * Extract all tags from routing signals\n * Tags are deduplicated to avoid duplicates from multiple signal sources\n */\nexport const extractTagsFromSignals = (signals: Routing.ClassificationSignal[]): string[] => {\n const tags = signals\n .filter(s => s.type !== 'context_type') // Skip generic context type\n .map(s => s.value)\n .filter((v): v is string => typeof v === 'string');\n \n // Deduplicate tags using Set\n return Array.from(new Set(tags));\n};\n\n// ============================================================================\n// Lifecycle Utilities\n// ============================================================================\n\n/**\n * Valid transcript statuses for validation\n */\nexport const VALID_STATUSES: TranscriptStatus[] = [\n 'initial', 'enhanced', 'reviewed', 'in_progress', 'closed', 'archived'\n];\n\n/**\n * Check if a string is a valid TranscriptStatus\n */\nexport const isValidStatus = (status: string): status is TranscriptStatus => {\n return VALID_STATUSES.includes(status as TranscriptStatus);\n};\n\n/**\n * Generate a unique task ID\n */\nexport const generateTaskId = (): string => {\n const timestamp = Date.now();\n const random = Math.random().toString(36).substring(2, 8);\n return `task-${timestamp}-${random}`;\n};\n\n/**\n * Create a new task\n */\nexport const createTask = (description: string): Task => {\n return {\n id: generateTaskId(),\n description,\n status: 'open',\n created: new Date().toISOString(),\n };\n};\n\n/**\n * Update transcript status and record the transition in history\n * Returns unchanged metadata if status is the same (no duplicate history)\n */\nexport const updateStatus = (\n metadata: TranscriptMetadata,\n newStatus: TranscriptStatus\n): TranscriptMetadata => {\n const oldStatus = metadata.status;\n \n // Don't add duplicate history if status unchanged\n if (oldStatus === newStatus) {\n return metadata;\n }\n \n const transition: StatusTransition = {\n from: oldStatus || 'reviewed',\n to: newStatus,\n at: new Date().toISOString(),\n };\n \n return {\n ...metadata,\n status: newStatus,\n history: [...(metadata.history || []), transition],\n };\n};\n\n/**\n * Apply default lifecycle fields to metadata\n * Used during lazy migration of old-format transcripts\n */\nexport const applyLifecycleDefaults = (metadata: TranscriptMetadata): TranscriptMetadata => {\n return {\n ...metadata,\n status: metadata.status ?? 'reviewed',\n history: metadata.history ?? [],\n tasks: metadata.tasks ?? [],\n };\n};\n\n/**\n * Complete a task by ID\n */\nexport const completeTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n const now = new Date().toISOString();\n const updatedTasks = [...tasks];\n updatedTasks[taskIndex] = {\n ...updatedTasks[taskIndex],\n status: 'done',\n changed: now,\n completed: now,\n };\n \n return {\n ...metadata,\n tasks: updatedTasks,\n };\n};\n\n/**\n * Delete a task by ID\n */\nexport const deleteTask = (metadata: TranscriptMetadata, taskId: string): TranscriptMetadata => {\n const tasks = metadata.tasks || [];\n const taskIndex = tasks.findIndex(t => t.id === taskId);\n \n if (taskIndex === -1) {\n throw new Error(`Task not found: ${taskId}`);\n }\n \n return {\n ...metadata,\n tasks: tasks.filter(t => t.id !== taskId),\n };\n};\n\n/**\n * Add a task to metadata\n */\nexport const addTask = (metadata: TranscriptMetadata, description: string): { metadata: TranscriptMetadata; task: Task } => {\n const task = createTask(description);\n \n return {\n metadata: {\n ...metadata,\n tasks: [...(metadata.tasks || []), task],\n },\n task,\n };\n};\n\n\n","/**\n * Frontmatter parsing utilities using gray-matter\n * \n * This module provides reliable YAML frontmatter parsing for transcript files,\n * consolidating all machine-readable data in frontmatter.\n */\n\nimport matter from 'gray-matter';\nimport { TranscriptMetadata, parseEntityMetadata, applyLifecycleDefaults, TranscriptStatus, StatusTransition, Task } from './metadata';\n\nexport interface ParsedFrontmatter {\n /** Parsed metadata from frontmatter (with lifecycle defaults applied) */\n metadata: TranscriptMetadata;\n /** Clean body content (no entity section, no legacy metadata sections) */\n body: string;\n /** Whether this file needs migration (old format detected) */\n needsMigration: boolean;\n}\n\n// Re-export types for convenience\nexport type { TranscriptMetadata, TranscriptStatus, StatusTransition, Task };\n\n/**\n * Parse old-style ## Metadata section from body content\n */\nfunction parseOldMetadataSection(content: string): Partial<TranscriptMetadata> {\n const metadata: Partial<TranscriptMetadata> = {};\n \n // Find the ## Metadata section\n // Look for ## Metadata followed by content until we hit --- or another ## or end of string\n const metadataMatch = content.match(/## Metadata\\s*\\n([\\s\\S]*?)(?:\\n---|\\n##|$)/);\n if (!metadataMatch) {\n return metadata;\n }\n \n const metadataSection = metadataMatch[1];\n \n // Extract project\n const projectMatch = metadataSection.match(/\\*\\*Project\\*\\*:\\s*(.+)/);\n if (projectMatch) {\n metadata.project = projectMatch[1].trim();\n }\n \n // Extract project ID\n const projectIdMatch = metadataSection.match(/\\*\\*Project ID\\*\\*:\\s*`([^`]+)`/);\n if (projectIdMatch) {\n metadata.projectId = projectIdMatch[1].trim();\n }\n \n // Extract tags\n const tagsMatch = metadataSection.match(/\\*\\*Tags\\*\\*:\\s*(.+)/);\n if (tagsMatch) {\n const tagsStr = tagsMatch[1];\n // Tags are formatted as `tag1`, `tag2`, `tag3`\n const tags = tagsStr.match(/`([^`]+)`/g);\n if (tags) {\n metadata.tags = tags.map(t => t.replace(/`/g, '').trim());\n }\n }\n \n // Extract date\n const dateMatch = metadataSection.match(/\\*\\*Date\\*\\*:\\s*(.+)/);\n if (dateMatch) {\n const dateStr = dateMatch[1].trim();\n // Try to parse the date (format: \"December 22, 2025\")\n const parsed = new Date(dateStr);\n if (!isNaN(parsed.getTime())) {\n metadata.date = parsed;\n }\n }\n \n // Extract time\n const timeMatch = metadataSection.match(/\\*\\*Time\\*\\*:\\s*(.+)/);\n if (timeMatch) {\n metadata.recordingTime = timeMatch[1].trim();\n }\n \n // Extract routing information\n const routingMatch = metadataSection.match(/### Routing\\s+([\\s\\S]*?)(?:\\n###|\\n##|$)/);\n if (routingMatch) {\n const routingSection = routingMatch[1];\n \n const destMatch = routingSection.match(/\\*\\*Destination\\*\\*:\\s*(.+)/);\n const confMatch = routingSection.match(/\\*\\*Confidence\\*\\*:\\s*([\\d.]+)%/);\n const reasoningMatch = routingSection.match(/\\*\\*Reasoning\\*\\*:\\s*(.+)/);\n \n if (destMatch || confMatch) {\n metadata.routing = {\n destination: destMatch ? destMatch[1].trim() : '',\n confidence: confMatch ? parseFloat(confMatch[1]) / 100 : 0,\n signals: [],\n reasoning: reasoningMatch ? reasoningMatch[1].trim() : '',\n };\n \n // Extract classification signals\n const signalsMatch = routingSection.match(/\\*\\*Classification Signals\\*\\*:\\s+([\\s\\S]*?)(?:\\n\\*\\*|$)/);\n if (signalsMatch) {\n const signalsText = signalsMatch[1];\n const signalLines = signalsText.split('\\n').filter(l => l.trim().startsWith('-'));\n \n for (const line of signalLines) {\n // Format: - topic: \"Node.js\" (30% weight)\n const signalMatch = line.match(/- ([^:]+):\\s*\"([^\"]+)\"\\s*\\((\\d+)% weight\\)/);\n if (signalMatch) {\n const typeStr = signalMatch[1].trim().replace(/ /g, '_');\n // Map to valid signal types\n const validTypes = ['explicit_phrase', 'associated_person', 'associated_company', 'topic', 'context_type'];\n const type = validTypes.includes(typeStr) ? typeStr : 'topic';\n \n metadata.routing.signals.push({\n type: type as 'explicit_phrase' | 'associated_person' | 'associated_company' | 'topic' | 'context_type',\n value: signalMatch[2].trim(),\n weight: parseFloat(signalMatch[3]) / 100,\n });\n }\n }\n }\n }\n }\n \n return metadata;\n}\n\n/**\n * Parse a transcript file using gray-matter\n * Handles both new format (all metadata in frontmatter) and old format (entities in body)\n */\nexport function parseTranscriptContent(content: string): ParsedFrontmatter {\n // Parse frontmatter using gray-matter\n const { data: frontmatter, content: rawBody } = matter(content);\n \n // Detect if this is old format\n const needsMigration = isOldFormat(content, frontmatter);\n \n // Build metadata from frontmatter\n let metadata: TranscriptMetadata = {\n title: frontmatter.title,\n date: frontmatter.date ? new Date(frontmatter.date) : undefined,\n recordingTime: frontmatter.recordingTime,\n duration: frontmatter.duration,\n project: frontmatter.project,\n projectId: frontmatter.projectId,\n tags: frontmatter.tags,\n confidence: frontmatter.confidence,\n routing: frontmatter.routing,\n status: frontmatter.status,\n history: frontmatter.history,\n tasks: frontmatter.tasks,\n entities: frontmatter.entities,\n };\n \n // If old format, parse the ## Metadata section from the original content\n // (not rawBody, because gray-matter might have consumed it)\n if (needsMigration) {\n const oldMetadata = parseOldMetadataSection(content);\n // Merge: start with old metadata, then overlay frontmatter values (if present)\n // Only overlay non-undefined values from frontmatter\n metadata = {\n ...oldMetadata,\n ...(metadata.title !== undefined && { title: metadata.title }),\n ...(metadata.date !== undefined && { date: metadata.date }),\n ...(metadata.recordingTime !== undefined && { recordingTime: metadata.recordingTime }),\n ...(metadata.duration !== undefined && { duration: metadata.duration }),\n ...(metadata.project !== undefined && { project: metadata.project }),\n ...(metadata.projectId !== undefined && { projectId: metadata.projectId }),\n ...(metadata.tags !== undefined && { tags: metadata.tags }),\n ...(metadata.confidence !== undefined && { confidence: metadata.confidence }),\n ...(metadata.routing !== undefined && { routing: metadata.routing }),\n ...(metadata.status !== undefined && { status: metadata.status }),\n ...(metadata.history !== undefined && { history: metadata.history }),\n ...(metadata.tasks !== undefined && { tasks: metadata.tasks }),\n ...(metadata.entities !== undefined && { entities: metadata.entities }),\n };\n }\n \n // If entities not in frontmatter, try to extract from body (old format)\n if (!metadata.entities) {\n const extractedEntities = parseEntityMetadata(rawBody);\n if (extractedEntities) {\n metadata.entities = extractedEntities;\n }\n }\n \n // Extract title from body if not in frontmatter (old format)\n let cleanBody = rawBody;\n const titleMatch = rawBody.match(/^#\\s+(.+)$/m);\n \n if (!metadata.title && titleMatch) {\n // No title in frontmatter, extract from H1\n metadata.title = titleMatch[1].trim();\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n } else if (metadata.title && titleMatch) {\n // Title in frontmatter, remove H1 from body\n cleanBody = rawBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Apply lifecycle defaults\n metadata = applyLifecycleDefaults(metadata);\n \n // Clean the body (remove entity section if present)\n cleanBody = stripLegacySections(cleanBody);\n \n return {\n metadata,\n body: cleanBody,\n needsMigration,\n };\n}\n\n/**\n * Detect if a file is in old format\n */\nfunction isOldFormat(content: string, frontmatter: Record<string, unknown>): boolean {\n // No frontmatter at all\n if (!content.startsWith('---')) {\n return true;\n }\n \n // Has frontmatter but entities are in body, not frontmatter\n if (!frontmatter.entities && content.includes('## Entity References')) {\n return true;\n }\n \n // Has legacy ## Metadata section in body\n if (content.includes('\\n## Metadata\\n')) {\n return true;\n }\n \n return false;\n}\n\n/**\n * Strip legacy sections from body content\n * Removes: ## Entity References, ## Metadata\n * Note: This must be careful not to remove these patterns if they appear in code blocks\n */\nexport function stripLegacySections(body: string): string {\n let clean = body;\n \n // Remove ## Metadata section (at start, before content)\n // This is trickier - it's between title and content\n // Pattern: ## Metadata ... --- (the --- is the separator before content)\n // Only match if it's at the start of the content (after optional whitespace)\n clean = clean.replace(/^(\\s*)## Metadata[\\s\\S]*?\\n---\\n/, '');\n \n // Remove ## Entity References section (at end of file)\n // Pattern: optional separator (---), then ## Entity References, then everything after\n // We need to be more careful here to avoid matching inside code blocks\n // Look for the pattern at the end of the file, after a separator\n const entityRefPattern = /\\n---\\s*\\n+## Entity References[\\s\\S]*$/;\n if (entityRefPattern.test(clean)) {\n clean = clean.replace(entityRefPattern, '');\n } else {\n // Try without the separator (some files might not have it)\n // But only if it's truly at the end (no other ## headers after it)\n const endPattern = /\\n## Entity References\\s*\\n[\\s\\S]*$/;\n if (endPattern.test(clean)) {\n // Check if there are any other ## headers after this point\n const match = clean.match(endPattern);\n if (match) {\n const entitySection = match[0];\n // If there are no other ## headers in this section (except Entity References sub-headers like ### Projects)\n // then it's safe to remove\n const otherHeaders = entitySection.match(/\\n## (?!Entity References)/g);\n if (!otherHeaders || otherHeaders.length === 0) {\n clean = clean.replace(endPattern, '');\n }\n }\n }\n }\n \n return clean.trim();\n}\n\n/**\n * Check if metadata has any entities\n */\nexport function hasEntities(entities: TranscriptMetadata['entities']): boolean {\n if (!entities) return false;\n return !!(\n entities.people?.length || \n entities.projects?.length || \n entities.terms?.length || \n entities.companies?.length\n );\n}\n\n// ============================================================================\n// Writing Functions\n// ============================================================================\n\n/**\n * Build a frontmatter object from TranscriptMetadata\n * Only includes non-empty values to keep YAML clean\n */\nexport function buildFrontmatter(metadata: TranscriptMetadata): Record<string, unknown> {\n const fm: Record<string, unknown> = {};\n \n // Core fields\n if (metadata.title) fm.title = metadata.title;\n if (metadata.date) fm.date = metadata.date.toISOString();\n if (metadata.recordingTime) fm.recordingTime = metadata.recordingTime;\n if (metadata.duration) fm.duration = metadata.duration;\n if (metadata.project) fm.project = metadata.project;\n if (metadata.projectId) fm.projectId = metadata.projectId;\n if (metadata.tags && metadata.tags.length > 0) fm.tags = metadata.tags;\n if (metadata.confidence !== undefined) fm.confidence = metadata.confidence;\n \n // Routing\n if (metadata.routing) fm.routing = metadata.routing;\n \n // Lifecycle\n if (metadata.status) fm.status = metadata.status;\n if (metadata.history && metadata.history.length > 0) fm.history = metadata.history;\n if (metadata.tasks && metadata.tasks.length > 0) fm.tasks = metadata.tasks;\n \n // Entities (now in frontmatter, not in body)\n if (hasEntities(metadata.entities)) {\n fm.entities = metadata.entities;\n }\n \n return fm;\n}\n\n/**\n * Stringify a transcript with YAML frontmatter\n * Uses gray-matter for consistent output\n * Ensures title is ONLY in frontmatter, never in body\n */\nexport function stringifyTranscript(metadata: TranscriptMetadata, body: string): string {\n const frontmatter = buildFrontmatter(metadata);\n \n // Clean the body (remove any legacy sections)\n let cleanBody = stripLegacySections(body);\n \n // Remove any leading frontmatter delimiters from the body\n // This can happen if the body was extracted incorrectly or has leftover delimiters\n cleanBody = cleanBody.replace(/^---\\s*\\n/, '').trim();\n \n // Remove H1 title from body if it matches the frontmatter title\n // Title should ONLY be in frontmatter\n if (metadata.title) {\n // Remove exact H1 match\n const h1Pattern = new RegExp(`^#\\\\s+${escapeRegex(metadata.title)}\\\\s*$`, 'm');\n cleanBody = cleanBody.replace(h1Pattern, '').trim();\n \n // Also remove any H1 at the start of the body (common pattern)\n cleanBody = cleanBody.replace(/^#\\s+.+$/m, '').trim();\n }\n \n // Use gray-matter to create the output\n // It handles YAML serialization, escaping, etc.\n return matter.stringify(cleanBody + '\\n', frontmatter);\n}\n\n/**\n * Escape special regex characters in a string\n */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\$&');\n}\n\n/**\n * Update a transcript's content while preserving/updating metadata\n * This is the main function for saving transcripts in the new format\n */\nexport function updateTranscript(\n originalContent: string,\n updates: {\n body?: string;\n metadata?: Partial<TranscriptMetadata>;\n }\n): string {\n // Parse the original\n const parsed = parseTranscriptContent(originalContent);\n \n // Merge metadata updates\n const newMetadata: TranscriptMetadata = {\n ...parsed.metadata,\n ...updates.metadata,\n };\n \n // Use updated body or original\n const newBody = updates.body ?? parsed.body;\n \n // Stringify with new format\n return stringifyTranscript(newMetadata, newBody);\n}\n"],"names":[],"mappings":";;AAgLO,MAAM,4BAAA,GAA+B,CAAC,QAAA,KAAyC;AAClF,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACpB,IAAA,OAAO,EAAA;AAAA,EACX;AAEA,EAAA,MAAM,QAAkB,EAAC;AACzB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,KAAK,CAAA;AAChB,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,sBAAsB,CAAA;AACjC,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,EAAA,KAAA,CAAM,KAAK,qEAAqE,CAAA;AAChF,EAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAGb,EAAA,IAAI,SAAS,QAAA,CAAS,MAAA,IAAU,SAAS,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG;AACjE,IAAA,KAAA,CAAM,KAAK,YAAY,CAAA;AACvB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,MAAA,IAAU,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ;AAC3C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,MAAA,CAAO,EAAE,CAAA,IAAA,EAAO,MAAA,CAAO,IAAI,CAAA,CAAE,CAAA;AAAA,IACnD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,QAAA,IAAY,SAAS,QAAA,CAAS,QAAA,CAAS,SAAS,CAAA,EAAG;AACrE,IAAA,KAAA,CAAM,KAAK,cAAc,CAAA;AACzB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,QAAA,CAAS,QAAA,CAAS,QAAA,EAAU;AAC9C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,OAAA,CAAQ,EAAE,CAAA,IAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,IACrD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,KAAA,IAAS,SAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,EAAG;AAC/D,IAAA,KAAA,CAAM,KAAK,WAAW,CAAA;AACtB,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,IAAA,IAAQ,QAAA,CAAS,QAAA,CAAS,KAAA,EAAO;AACxC,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,IAAA,CAAK,EAAE,CAAA,IAAA,EAAO,IAAA,CAAK,IAAI,CAAA,CAAE,CAAA;AAAA,IAC/C;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAGA,EAAA,IAAI,SAAS,QAAA,CAAS,SAAA,IAAa,SAAS,QAAA,CAAS,SAAA,CAAU,SAAS,CAAA,EAAG;AACvE,IAAA,KAAA,CAAM,KAAK,eAAe,CAAA;AAC1B,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AACb,IAAA,KAAA,MAAW,OAAA,IAAW,QAAA,CAAS,QAAA,CAAS,SAAA,EAAW;AAC/C,MAAA,KAAA,CAAM,KAAK,CAAA,IAAA,EAAO,OAAA,CAAQ,EAAE,CAAA,IAAA,EAAO,OAAA,CAAQ,IAAI,CAAA,CAAE,CAAA;AAAA,IACrD;AACA,IAAA,KAAA,CAAM,KAAK,EAAE,CAAA;AAAA,EACjB;AAEA,EAAA,OAAO,KAAA,CAAM,KAAK,IAAI,CAAA;AAC1B;AAMO,MAAM,mBAAA,GAAsB,CAAC,OAAA,KAAgE;AAGhG,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,OAAA,CAAQ,sBAAsB,CAAA;AAC1D,EAAA,IAAI,gBAAgB,EAAA,EAAI;AACpB,IAAA,OAAO,MAAA;AAAA,EACX;AAGA,EAAA,IAAI,YAAA,GAAe,cAAc,sBAAA,CAAuB,MAAA;AAExD,EAAA,OAAO,eAAe,OAAA,CAAQ,MAAA,KAAW,QAAQ,YAAY,CAAA,KAAM,QAAQ,OAAA,CAAQ,YAAY,CAAA,KAAM,IAAA,IAAQ,QAAQ,YAAY,CAAA,KAAM,OAAO,OAAA,CAAQ,YAAY,MAAM,GAAA,CAAA,EAAO;AAC3K,IAAA,YAAA,EAAA;AAAA,EACJ;AAGA,EAAA,MAAM,gBAAA,GAAmB,OAAA,CAAQ,SAAA,CAAU,YAAY,CAAA;AACvD,EAAA,MAAM,eAAA,GAAkB,gBAAA,CAAiB,KAAA,CAAM,OAAO,CAAA;AACtD,EAAA,MAAM,iBAAiB,eAAA,GACjB,gBAAA,CAAiB,UAAU,CAAA,EAAG,eAAA,CAAgB,KAAK,CAAA,GACnD,gBAAA;AACN,EAAA,MAAM,QAAA,GAAwD;AAAA,IAC1D,QAAQ,EAAC;AAAA,IACT,UAAU,EAAC;AAAA,IACX,OAAO,EAAC;AAAA,IACR,WAAW;AAAC,GAChB;AAGA,EAAA,MAAM,aAAA,GAAgB,CAAC,IAAA,KAA2E;AAE9F,IAAA,MAAM,OAAA,GAAqE;AAAA,MACvE,QAAA,EAAU,QAAA;AAAA,MACV,UAAA,EAAY,SAAA;AAAA,MACZ,OAAA,EAAS,MAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACjB;AAEA,IAAA,MAAM,UAAA,GAAa,QAAQ,IAAI,CAAA;AAG/B,IAAA,MAAM,aAAA,GAAgB,OAAO,IAAI,CAAA,CAAA;AACjC,IAAA,MAAM,YAAA,GAAe,cAAA,CAAe,OAAA,CAAQ,aAAa,CAAA;AACzD,IAAA,IAAI,YAAA,KAAiB,EAAA,EAAI,OAAO,EAAC;AAIjC,IAAA,MAAM,SAAA,GAAY,eAAe,aAAA,CAAc,MAAA;AAC/C,IAAA,IAAI,gBAAA,GAAmB,SAAA;AAEvB,IAAA,OAAO,gBAAA,GAAmB,cAAA,CAAe,MAAA,KACjC,cAAA,CAAe,gBAAgB,CAAA,KAAM,IAAA,IAAQ,cAAA,CAAe,gBAAgB,CAAA,KAAM,IAAA,IAAQ,cAAA,CAAe,gBAAgB,MAAM,GAAA,CAAA,EAAM;AACzI,MAAA,gBAAA,EAAA;AAAA,IACJ;AAEA,IAAA,MAAM,YAAA,GAAe,cAAA,CAAe,SAAA,CAAU,gBAAgB,CAAA;AAC9D,IAAA,MAAM,WAAA,GAAc,YAAA,CAAa,MAAA,CAAO,OAAO,CAAA;AAC/C,IAAA,MAAM,cAAc,WAAA,KAAgB,EAAA,GAAK,eAAe,YAAA,CAAa,SAAA,CAAU,GAAG,WAAW,CAAA;AAI7F,IAAA,MAAM,QAA2B,EAAC;AAElC,IAAA,MAAM,KAAA,GAAQ,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA;AACpC,IAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACtB,MAAA,MAAM,OAAA,GAAU,KAAK,IAAA,EAAK;AAE1B,MAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,CAAM,uBAAuB,CAAA;AACnD,MAAA,IAAI,KAAA,EAAO;AACP,QAAA,KAAA,CAAM,IAAA,CAAK;AAAA,UACP,EAAA,EAAI,MAAM,CAAC,CAAA;AAAA,UACX,IAAA,EAAM,KAAA,CAAM,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,UACpB,IAAA,EAAM;AAAA,SACT,CAAA;AAAA,MACL;AAAA,IACJ;AAEA,IAAA,OAAO,KAAA;AAAA,EACX,CAAA;AAEA,EAAA,QAAA,CAAS,MAAA,GAAS,cAAc,QAAQ,CAAA;AACxC,EAAA,QAAA,CAAS,QAAA,GAAW,cAAc,UAAU,CAAA;AAC5C,EAAA,QAAA,CAAS,KAAA,GAAQ,cAAc,OAAO,CAAA;AACtC,EAAA,QAAA,CAAS,SAAA,GAAY,cAAc,WAAW,CAAA;AAG9C,EAAA,MAAM,WAAA,GACF,QAAA,CAAS,MAAA,CAAO,MAAA,GAAS,KACzB,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAA,IAC3B,SAAS,KAAA,CAAM,MAAA,GAAS,CAAA,IACxB,QAAA,CAAS,UAAU,MAAA,GAAS,CAAA;AAEhC,EAAA,OAAO,cAAc,QAAA,GAAW,MAAA;AACpC,CAAA;AAKO,MAAM,qBAAA,GAAwB,CAAC,QAAA,KAAqD;AACvF,EAAA,OAAO;AAAA,IACH,WAAA,EAAa,SAAS,WAAA,CAAY,IAAA;AAAA,IAClC,YAAY,QAAA,CAAS,UAAA;AAAA,IACrB,SAAS,QAAA,CAAS,OAAA;AAAA,IAClB,WAAW,QAAA,CAAS;AAAA,GACxB;AACJ;AA2CO,MAAM,sBAAA,GAAyB,CAAC,OAAA,KAAsD;AACzF,EAAA,MAAM,OAAO,OAAA,CACR,MAAA,CAAO,OAAK,CAAA,CAAE,IAAA,KAAS,cAAc,CAAA,CACrC,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,KAAK,CAAA,CAChB,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,MAAM,QAAQ,CAAA;AAGrD,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,IAAI,GAAA,CAAI,IAAI,CAAC,CAAA;AACnC;AASO,MAAM,cAAA,GAAqC;AAAA,EAC9C,SAAA;AAAA,EAAW,UAAA;AAAA,EAAY,UAAA;AAAA,EAAY,aAAA;AAAA,EAAe,QAAA;AAAA,EAAU;AAChE;AAKO,MAAM,aAAA,GAAgB,CAAC,MAAA,KAA+C;AACzE,EAAA,OAAO,cAAA,CAAe,SAAS,MAA0B,CAAA;AAC7D;AAKO,MAAM,iBAAiB,MAAc;AACxC,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAC3B,EAAA,MAAM,MAAA,GAAS,KAAK,MAAA,EAAO,CAAE,SAAS,EAAE,CAAA,CAAE,SAAA,CAAU,CAAA,EAAG,CAAC,CAAA;AACxD,EAAA,OAAO,CAAA,KAAA,EAAQ,SAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA;AACtC,CAAA;AAKO,MAAM,UAAA,GAAa,CAAC,WAAA,KAA8B;AACrD,EAAA,OAAO;AAAA,IACH,IAAI,cAAA,EAAe;AAAA,IACnB,WAAA;AAAA,IACA,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAA,iBAAS,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GACpC;AACJ,CAAA;AAMO,MAAM,YAAA,GAAe,CACxB,QAAA,EACA,SAAA,KACqB;AACrB,EAAA,MAAM,YAAY,QAAA,CAAS,MAAA;AAG3B,EAAA,IAAI,cAAc,SAAA,EAAW;AACzB,IAAA,OAAO,QAAA;AAAA,EACX;AAEA,EAAA,MAAM,UAAA,GAA+B;AAAA,IACjC,MAAM,SAAA,IAAa,UAAA;AAAA,IACnB,EAAA,EAAI,SAAA;AAAA,IACJ,EAAA,EAAA,iBAAI,IAAI,IAAA,EAAK,EAAE,WAAA;AAAY,GAC/B;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,SAAA;AAAA,IACR,SAAS,CAAC,GAAI,SAAS,OAAA,IAAW,IAAK,UAAU;AAAA,GACrD;AACJ;AAMO,MAAM,sBAAA,GAAyB,CAAC,QAAA,KAAqD;AACxF,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,MAAA,EAAQ,SAAS,MAAA,IAAU,UAAA;AAAA,IAC3B,OAAA,EAAS,QAAA,CAAS,OAAA,IAAW,EAAC;AAAA,IAC9B,KAAA,EAAO,QAAA,CAAS,KAAA,IAAS;AAAC,GAC9B;AACJ,CAAA;AAKO,MAAM,YAAA,GAAe,CAAC,QAAA,EAA8B,MAAA,KAAuC;AAC9F,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,IAAS,EAAC;AACjC,EAAA,MAAM,YAAY,KAAA,CAAM,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM,CAAA;AAEtD,EAAA,IAAI,cAAc,EAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/C;AAEA,EAAA,MAAM,GAAA,GAAA,iBAAM,IAAI,IAAA,EAAK,EAAE,WAAA,EAAY;AACnC,EAAA,MAAM,YAAA,GAAe,CAAC,GAAG,KAAK,CAAA;AAC9B,EAAA,YAAA,CAAa,SAAS,CAAA,GAAI;AAAA,IACtB,GAAG,aAAa,SAAS,CAAA;AAAA,IACzB,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,GAAA;AAAA,IACT,SAAA,EAAW;AAAA,GACf;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,KAAA,EAAO;AAAA,GACX;AACJ;AAKO,MAAM,UAAA,GAAa,CAAC,QAAA,EAA8B,MAAA,KAAuC;AAC5F,EAAA,MAAM,KAAA,GAAQ,QAAA,CAAS,KAAA,IAAS,EAAC;AACjC,EAAA,MAAM,YAAY,KAAA,CAAM,SAAA,CAAU,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM,CAAA;AAEtD,EAAA,IAAI,cAAc,EAAA,EAAI;AAClB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gBAAA,EAAmB,MAAM,CAAA,CAAE,CAAA;AAAA,EAC/C;AAEA,EAAA,OAAO;AAAA,IACH,GAAG,QAAA;AAAA,IACH,OAAO,KAAA,CAAM,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,OAAO,MAAM;AAAA,GAC5C;AACJ;AAKO,MAAM,OAAA,GAAU,CAAC,QAAA,EAA8B,WAAA,KAAsE;AACxH,EAAA,MAAM,IAAA,GAAO,WAAW,WAAW,CAAA;AAEnC,EAAA,OAAO;AAAA,IACH,QAAA,EAAU;AAAA,MACN,GAAG,QAAA;AAAA,MACH,OAAO,CAAC,GAAI,SAAS,KAAA,IAAS,IAAK,IAAI;AAAA,KAC3C;AAAA,IACA;AAAA,GACJ;AACJ;;AC1fA,SAAS,wBAAwB,OAAA,EAA8C;AAC3E,EAAA,MAAM,WAAwC,EAAC;AAI/C,EAAA,MAAM,aAAA,GAAgB,OAAA,CAAQ,KAAA,CAAM,4CAA4C,CAAA;AAChF,EAAA,IAAI,CAAC,aAAA,EAAe;AAChB,IAAA,OAAO,QAAA;AAAA,EACX;AAEA,EAAA,MAAM,eAAA,GAAkB,cAAc,CAAC,CAAA;AAGvC,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,yBAAyB,CAAA;AACpE,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,QAAA,CAAS,OAAA,GAAU,YAAA,CAAa,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAC5C;AAGA,EAAA,MAAM,cAAA,GAAiB,eAAA,CAAgB,KAAA,CAAM,iCAAiC,CAAA;AAC9E,EAAA,IAAI,cAAA,EAAgB;AAChB,IAAA,QAAA,CAAS,SAAA,GAAY,cAAA,CAAe,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAChD;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,MAAM,OAAA,GAAU,UAAU,CAAC,CAAA;AAE3B,IAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,KAAA,CAAM,YAAY,CAAA;AACvC,IAAA,IAAI,IAAA,EAAM;AACN,MAAA,QAAA,CAAS,IAAA,GAAO,IAAA,CAAK,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,QAAQ,IAAA,EAAM,EAAE,CAAA,CAAE,IAAA,EAAM,CAAA;AAAA,IAC5D;AAAA,EACJ;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,MAAM,OAAA,GAAU,SAAA,CAAU,CAAC,CAAA,CAAE,IAAA,EAAK;AAElC,IAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,OAAO,CAAA;AAC/B,IAAA,IAAI,CAAC,KAAA,CAAM,MAAA,CAAO,OAAA,EAAS,CAAA,EAAG;AAC1B,MAAA,QAAA,CAAS,IAAA,GAAO,MAAA;AAAA,IACpB;AAAA,EACJ;AAGA,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,KAAA,CAAM,sBAAsB,CAAA;AAC9D,EAAA,IAAI,SAAA,EAAW;AACX,IAAA,QAAA,CAAS,aAAA,GAAgB,SAAA,CAAU,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,EAC/C;AAGA,EAAA,MAAM,YAAA,GAAe,eAAA,CAAgB,KAAA,CAAM,0CAA0C,CAAA;AACrF,EAAA,IAAI,YAAA,EAAc;AACd,IAAA,MAAM,cAAA,GAAiB,aAAa,CAAC,CAAA;AAErC,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,KAAA,CAAM,6BAA6B,CAAA;AACpE,IAAA,MAAM,SAAA,GAAY,cAAA,CAAe,KAAA,CAAM,iCAAiC,CAAA;AACxE,IAAA,MAAM,cAAA,GAAiB,cAAA,CAAe,KAAA,CAAM,2BAA2B,CAAA;AAEvE,IAAA,IAAI,aAAa,SAAA,EAAW;AACxB,MAAA,QAAA,CAAS,OAAA,GAAU;AAAA,QACf,aAAa,SAAA,GAAY,SAAA,CAAU,CAAC,CAAA,CAAE,MAAK,GAAI,EAAA;AAAA,QAC/C,YAAY,SAAA,GAAY,UAAA,CAAW,UAAU,CAAC,CAAC,IAAI,GAAA,GAAM,CAAA;AAAA,QACzD,SAAS,EAAC;AAAA,QACV,WAAW,cAAA,GAAiB,cAAA,CAAe,CAAC,CAAA,CAAE,MAAK,GAAI;AAAA,OAC3D;AAGA,MAAA,MAAM,YAAA,GAAe,cAAA,CAAe,KAAA,CAAM,0DAA0D,CAAA;AACpG,MAAA,IAAI,YAAA,EAAc;AACd,QAAA,MAAM,WAAA,GAAc,aAAa,CAAC,CAAA;AAClC,QAAA,MAAM,WAAA,GAAc,WAAA,CAAY,KAAA,CAAM,IAAI,CAAA,CAAE,MAAA,CAAO,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAK,CAAE,UAAA,CAAW,GAAG,CAAC,CAAA;AAEhF,QAAA,KAAA,MAAW,QAAQ,WAAA,EAAa;AAE5B,UAAA,MAAM,WAAA,GAAc,IAAA,CAAK,KAAA,CAAM,4CAA4C,CAAA;AAC3E,UAAA,IAAI,WAAA,EAAa;AACb,YAAA,MAAM,OAAA,GAAU,YAAY,CAAC,CAAA,CAAE,MAAK,CAAE,OAAA,CAAQ,MAAM,GAAG,CAAA;AAEvD,YAAA,MAAM,aAAa,CAAC,iBAAA,EAAmB,mBAAA,EAAqB,oBAAA,EAAsB,SAAS,cAAc,CAAA;AACzG,YAAA,MAAM,IAAA,GAAO,UAAA,CAAW,QAAA,CAAS,OAAO,IAAI,OAAA,GAAU,OAAA;AAEtD,YAAA,QAAA,CAAS,OAAA,CAAQ,QAAQ,IAAA,CAAK;AAAA,cAC1B,IAAA;AAAA,cACA,KAAA,EAAO,WAAA,CAAY,CAAC,CAAA,CAAE,IAAA,EAAK;AAAA,cAC3B,MAAA,EAAQ,UAAA,CAAW,WAAA,CAAY,CAAC,CAAC,CAAA,GAAI;AAAA,aACxC,CAAA;AAAA,UACL;AAAA,QACJ;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,EAAA,OAAO,QAAA;AACX;AAMO,SAAS,uBAAuB,OAAA,EAAoC;AAEvE,EAAA,MAAM,EAAE,IAAA,EAAM,WAAA,EAAa,SAAS,OAAA,EAAQ,GAAI,OAAO,OAAO,CAAA;AAG9D,EAAA,MAAM,cAAA,GAAiB,WAAA,CAAY,OAAA,EAAS,WAAW,CAAA;AAGvD,EAAA,IAAI,QAAA,GAA+B;AAAA,IAC/B,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,MAAM,WAAA,CAAY,IAAA,GAAO,IAAI,IAAA,CAAK,WAAA,CAAY,IAAI,CAAA,GAAI,MAAA;AAAA,IACtD,eAAe,WAAA,CAAY,aAAA;AAAA,IAC3B,UAAU,WAAA,CAAY,QAAA;AAAA,IACtB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,WAAW,WAAA,CAAY,SAAA;AAAA,IACvB,MAAM,WAAA,CAAY,IAAA;AAAA,IAClB,YAAY,WAAA,CAAY,UAAA;AAAA,IACxB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,QAAQ,WAAA,CAAY,MAAA;AAAA,IACpB,SAAS,WAAA,CAAY,OAAA;AAAA,IACrB,OAAO,WAAA,CAAY,KAAA;AAAA,IACnB,UAAU,WAAA,CAAY;AAAA,GAC1B;AAIA,EAAA,IAAI,cAAA,EAAgB;AAChB,IAAA,MAAM,WAAA,GAAc,wBAAwB,OAAO,CAAA;AAGnD,IAAA,QAAA,GAAW;AAAA,MACP,GAAG,WAAA;AAAA,MACH,GAAI,QAAA,CAAS,KAAA,KAAU,UAAa,EAAE,KAAA,EAAO,SAAS,KAAA,EAAM;AAAA,MAC5D,GAAI,QAAA,CAAS,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACzD,GAAI,QAAA,CAAS,aAAA,KAAkB,UAAa,EAAE,aAAA,EAAe,SAAS,aAAA,EAAc;AAAA,MACpF,GAAI,QAAA,CAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,SAAS,QAAA,EAAS;AAAA,MACrE,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,SAAA,KAAc,UAAa,EAAE,SAAA,EAAW,SAAS,SAAA,EAAU;AAAA,MACxE,GAAI,QAAA,CAAS,IAAA,KAAS,UAAa,EAAE,IAAA,EAAM,SAAS,IAAA,EAAK;AAAA,MACzD,GAAI,QAAA,CAAS,UAAA,KAAe,UAAa,EAAE,UAAA,EAAY,SAAS,UAAA,EAAW;AAAA,MAC3E,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,MAAA,KAAW,UAAa,EAAE,MAAA,EAAQ,SAAS,MAAA,EAAO;AAAA,MAC/D,GAAI,QAAA,CAAS,OAAA,KAAY,UAAa,EAAE,OAAA,EAAS,SAAS,OAAA,EAAQ;AAAA,MAClE,GAAI,QAAA,CAAS,KAAA,KAAU,UAAa,EAAE,KAAA,EAAO,SAAS,KAAA,EAAM;AAAA,MAC5D,GAAI,QAAA,CAAS,QAAA,KAAa,UAAa,EAAE,QAAA,EAAU,SAAS,QAAA;AAAS,KACzE;AAAA,EACJ;AAGA,EAAA,IAAI,CAAC,SAAS,QAAA,EAAU;AACpB,IAAA,MAAM,iBAAA,GAAoB,oBAAoB,OAAO,CAAA;AACrD,IAAA,IAAI,iBAAA,EAAmB;AACnB,MAAA,QAAA,CAAS,QAAA,GAAW,iBAAA;AAAA,IACxB;AAAA,EACJ;AAGA,EAAA,IAAI,SAAA,GAAY,OAAA;AAChB,EAAA,MAAM,UAAA,GAAa,OAAA,CAAQ,KAAA,CAAM,aAAa,CAAA;AAE9C,EAAA,IAAI,CAAC,QAAA,CAAS,KAAA,IAAS,UAAA,EAAY;AAE/B,IAAA,QAAA,CAAS,KAAA,GAAQ,UAAA,CAAW,CAAC,CAAA,CAAE,IAAA,EAAK;AACpC,IAAA,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACtD,CAAA,MAAA,IAAW,QAAA,CAAS,KAAA,IAAS,UAAA,EAAY;AAErC,IAAA,SAAA,GAAY,OAAA,CAAQ,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACtD;AAGA,EAAA,QAAA,GAAW,uBAAuB,QAAQ,CAAA;AAG1C,EAAA,SAAA,GAAY,oBAAoB,SAAS,CAAA;AAEzC,EAAA,OAAO;AAAA,IACH,QAAA;AAAA,IACA,IAAA,EAAM,SAAA;AAAA,IACN;AAAA,GACJ;AACJ;AAKA,SAAS,WAAA,CAAY,SAAiB,WAAA,EAA+C;AAEjF,EAAA,IAAI,CAAC,OAAA,CAAQ,UAAA,CAAW,KAAK,CAAA,EAAG;AAC5B,IAAA,OAAO,IAAA;AAAA,EACX;AAGA,EAAA,IAAI,CAAC,WAAA,CAAY,QAAA,IAAY,OAAA,CAAQ,QAAA,CAAS,sBAAsB,CAAA,EAAG;AACnE,IAAA,OAAO,IAAA;AAAA,EACX;AAGA,EAAA,IAAI,OAAA,CAAQ,QAAA,CAAS,iBAAiB,CAAA,EAAG;AACrC,IAAA,OAAO,IAAA;AAAA,EACX;AAEA,EAAA,OAAO,KAAA;AACX;AAOO,SAAS,oBAAoB,IAAA,EAAsB;AACtD,EAAA,IAAI,KAAA,GAAQ,IAAA;AAMZ,EAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,kCAAA,EAAoC,EAAE,CAAA;AAM5D,EAAA,MAAM,gBAAA,GAAmB,yCAAA;AACzB,EAAA,IAAI,gBAAA,CAAiB,IAAA,CAAK,KAAK,CAAA,EAAG;AAC9B,IAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,gBAAA,EAAkB,EAAE,CAAA;AAAA,EAC9C,CAAA,MAAO;AAGH,IAAA,MAAM,UAAA,GAAa,qCAAA;AACnB,IAAA,IAAI,UAAA,CAAW,IAAA,CAAK,KAAK,CAAA,EAAG;AAExB,MAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,UAAU,CAAA;AACpC,MAAA,IAAI,KAAA,EAAO;AACP,QAAA,MAAM,aAAA,GAAgB,MAAM,CAAC,CAAA;AAG7B,QAAA,MAAM,YAAA,GAAe,aAAA,CAAc,KAAA,CAAM,6BAA6B,CAAA;AACtE,QAAA,IAAI,CAAC,YAAA,IAAgB,YAAA,CAAa,MAAA,KAAW,CAAA,EAAG;AAC5C,UAAA,KAAA,GAAQ,KAAA,CAAM,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAAA,QACxC;AAAA,MACJ;AAAA,IACJ;AAAA,EACJ;AAEA,EAAA,OAAO,MAAM,IAAA,EAAK;AACtB;AAKO,SAAS,YAAY,QAAA,EAAmD;AAC3E,EAAA,IAAI,CAAC,UAAU,OAAO,KAAA;AACtB,EAAA,OAAO,CAAC,EACJ,QAAA,CAAS,MAAA,EAAQ,MAAA,IACjB,QAAA,CAAS,QAAA,EAAU,MAAA,IACnB,QAAA,CAAS,KAAA,EAAO,MAAA,IAChB,QAAA,CAAS,SAAA,EAAW,MAAA,CAAA;AAE5B;AAUO,SAAS,iBAAiB,QAAA,EAAuD;AACpF,EAAA,MAAM,KAA8B,EAAC;AAGrC,EAAA,IAAI,QAAA,CAAS,KAAA,EAAO,EAAA,CAAG,KAAA,GAAQ,QAAA,CAAS,KAAA;AACxC,EAAA,IAAI,SAAS,IAAA,EAAM,EAAA,CAAG,IAAA,GAAO,QAAA,CAAS,KAAK,WAAA,EAAY;AACvD,EAAA,IAAI,QAAA,CAAS,aAAA,EAAe,EAAA,CAAG,aAAA,GAAgB,QAAA,CAAS,aAAA;AACxD,EAAA,IAAI,QAAA,CAAS,QAAA,EAAU,EAAA,CAAG,QAAA,GAAW,QAAA,CAAS,QAAA;AAC9C,EAAA,IAAI,QAAA,CAAS,OAAA,EAAS,EAAA,CAAG,OAAA,GAAU,QAAA,CAAS,OAAA;AAC5C,EAAA,IAAI,QAAA,CAAS,SAAA,EAAW,EAAA,CAAG,SAAA,GAAY,QAAA,CAAS,SAAA;AAChD,EAAA,IAAI,QAAA,CAAS,QAAQ,QAAA,CAAS,IAAA,CAAK,SAAS,CAAA,EAAG,EAAA,CAAG,OAAO,QAAA,CAAS,IAAA;AAClE,EAAA,IAAI,QAAA,CAAS,UAAA,KAAe,MAAA,EAAW,EAAA,CAAG,aAAa,QAAA,CAAS,UAAA;AAGhE,EAAA,IAAI,QAAA,CAAS,OAAA,EAAS,EAAA,CAAG,OAAA,GAAU,QAAA,CAAS,OAAA;AAG5C,EAAA,IAAI,QAAA,CAAS,MAAA,EAAQ,EAAA,CAAG,MAAA,GAAS,QAAA,CAAS,MAAA;AAC1C,EAAA,IAAI,QAAA,CAAS,WAAW,QAAA,CAAS,OAAA,CAAQ,SAAS,CAAA,EAAG,EAAA,CAAG,UAAU,QAAA,CAAS,OAAA;AAC3E,EAAA,IAAI,QAAA,CAAS,SAAS,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA,EAAG,EAAA,CAAG,QAAQ,QAAA,CAAS,KAAA;AAGrE,EAAA,IAAI,WAAA,CAAY,QAAA,CAAS,QAAQ,CAAA,EAAG;AAChC,IAAA,EAAA,CAAG,WAAW,QAAA,CAAS,QAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,EAAA;AACX;AAOO,SAAS,mBAAA,CAAoB,UAA8B,IAAA,EAAsB;AACpF,EAAA,MAAM,WAAA,GAAc,iBAAiB,QAAQ,CAAA;AAG7C,EAAA,IAAI,SAAA,GAAY,oBAAoB,IAAI,CAAA;AAIxC,EAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAIpD,EAAA,IAAI,SAAS,KAAA,EAAO;AAEhB,IAAA,MAAM,SAAA,GAAY,IAAI,MAAA,CAAO,CAAA,MAAA,EAAS,YAAY,QAAA,CAAS,KAAK,CAAC,CAAA,KAAA,CAAA,EAAS,GAAG,CAAA;AAC7E,IAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,SAAA,EAAW,EAAE,EAAE,IAAA,EAAK;AAGlD,IAAA,SAAA,GAAY,SAAA,CAAU,OAAA,CAAQ,WAAA,EAAa,EAAE,EAAE,IAAA,EAAK;AAAA,EACxD;AAIA,EAAA,OAAO,MAAA,CAAO,SAAA,CAAU,SAAA,GAAY,IAAA,EAAM,WAAW,CAAA;AACzD;AAKA,SAAS,YAAY,GAAA,EAAqB;AACtC,EAAA,OAAO,GAAA,CAAI,OAAA,CAAQ,qBAAA,EAAuB,MAAM,CAAA;AACpD;AAMO,SAAS,gBAAA,CACZ,iBACA,OAAA,EAIM;AAEN,EAAA,MAAM,MAAA,GAAS,uBAAuB,eAAe,CAAA;AAGrD,EAAA,MAAM,WAAA,GAAkC;AAAA,IACpC,GAAG,MAAA,CAAO,QAAA;AAAA,IACV,GAAG,OAAA,CAAQ;AAAA,GACf;AAGA,EAAA,MAAM,OAAA,GAAU,OAAA,CAAQ,IAAA,IAAQ,MAAA,CAAO,IAAA;AAGvC,EAAA,OAAO,mBAAA,CAAoB,aAAa,OAAO,CAAA;AACnD;;;;;;;;;;;;;;"}
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { c as create, p as create$1, o as create$2, n as getLogger, C as listTranscripts, x as DEFAULT_AUDIO_EXTENSIONS, w as DEFAULT_OUTPUT_STRUCTURE, v as DEFAULT_OUTPUT_FILENAME_OPTIONS, B as create$3, g as DEFAULT_TRANSCRIPTION_MODEL, e as DEFAULT_MODEL, E as DEFAULT_TEMP_DIRECTORY, m as DEFAULT_MAX_AUDIO_SIZE, q as DEFAULT_INTERMEDIATE_DIRECTORY, l as DEFAULT_REASONING_LEVEL, F as findIgnoredResilient, G as findCompanyResilient, f as findTermResilient, H as findPersonResilient, I as findProjectResilient, a as create$4, J as create$6, K as create$8, L as processFeedback, M as applyChanges, N as combineTranscripts, O as editTranscript, Q as parseTranscript, h as PROGRAM_NAME, V as VERSION } from './transcript.js';
1
+ import { c as create, p as create$1, o as create$2, n as getLogger, C as listTranscripts, x as DEFAULT_AUDIO_EXTENSIONS, w as DEFAULT_OUTPUT_STRUCTURE, v as DEFAULT_OUTPUT_FILENAME_OPTIONS, B as create$3, g as DEFAULT_TRANSCRIPTION_MODEL, e as DEFAULT_MODEL, E as DEFAULT_TEMP_DIRECTORY, m as DEFAULT_MAX_AUDIO_SIZE, q as DEFAULT_INTERMEDIATE_DIRECTORY, l as DEFAULT_REASONING_LEVEL, F as findIgnoredResilient, G as findCompanyResilient, f as findTermResilient, H as findPersonResilient, I as findProjectResilient, a as create$4, J as create$6, K as create$8, L as processFeedback, M as applyChanges, N as combineTranscripts, O as editTranscript, Q as validateOrThrow, R as parseTranscript, h as PROGRAM_NAME, V as VERSION } from './transcript.js';
2
2
  import { stat, readFile, readdir, mkdir, writeFile, unlink } from 'node:fs/promises';
3
3
  import { resolve, relative, extname, join, dirname, basename, isAbsolute } from 'node:path';
4
4
  import * as yaml from 'js-yaml';
@@ -3112,7 +3112,7 @@ async function handleUpdateTerm(args) {
3112
3112
  if (!smartConfig.enabled || smartConfig.termsEnabled === false) {
3113
3113
  throw new Error("Term smart assistance is disabled in configuration.");
3114
3114
  }
3115
- const ContentFetcher = await import('./transcript.js').then(n => n.S);
3115
+ const ContentFetcher = await import('./transcript.js').then(n => n.T);
3116
3116
  const contentFetcher = ContentFetcher.create();
3117
3117
  const fetchResult = await contentFetcher.fetch(args.source);
3118
3118
  if (!fetchResult.success) {
@@ -3832,19 +3832,7 @@ async function handleEditTranscript(args) {
3832
3832
  });
3833
3833
  validatePathWithinDirectory(result.outputPath, outputDirectory);
3834
3834
  try {
3835
- const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.h);
3836
- const validation = parseTranscriptContent(result.content);
3837
- if (!validation.metadata) {
3838
- throw new Error("Generated content has no parseable metadata");
3839
- }
3840
- if (!result.content.trim().startsWith("---")) {
3841
- throw new Error("Generated content does not start with YAML frontmatter (---). Title may be placed before frontmatter.");
3842
- }
3843
- const lines = result.content.split("\n");
3844
- const closingDelimiterIndex = lines.findIndex((line, idx) => idx > 0 && line.trim() === "---");
3845
- if (closingDelimiterIndex === -1) {
3846
- throw new Error("Generated content is missing closing YAML frontmatter delimiter (---)");
3847
- }
3835
+ validateOrThrow(result.content);
3848
3836
  console.log("✅ Transcript content validated successfully");
3849
3837
  } catch (validationError) {
3850
3838
  console.error("❌ Transcript validation failed:", validationError);
@@ -3865,7 +3853,7 @@ async function handleEditTranscript(args) {
3865
3853
  let previousStatus;
3866
3854
  if (args.status) {
3867
3855
  const content = await readFile(finalOutputPath, "utf-8");
3868
- const { parseTranscriptContent, stringifyTranscript } = await import('./frontmatter.js').then(n => n.h);
3856
+ const { parseTranscriptContent, stringifyTranscript } = await import('./frontmatter.js').then(n => n.g);
3869
3857
  const parsed = parseTranscriptContent(content);
3870
3858
  previousStatus = parsed.metadata.status || "reviewed";
3871
3859
  if (previousStatus !== args.status) {
@@ -3920,7 +3908,7 @@ async function handleChangeTranscriptDate(args) {
3920
3908
  throw new Error(`Invalid date format: ${args.newDate}. Use ISO 8601 format (e.g., "2026-01-15" or "2026-01-15T10:30:00Z")`);
3921
3909
  }
3922
3910
  const content = await readFile2(absolutePath, "utf-8");
3923
- const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.h);
3911
+ const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.g);
3924
3912
  const parsed = parseTranscriptContent(content);
3925
3913
  if (!parsed.metadata) {
3926
3914
  throw new Error("Could not parse transcript metadata");
@@ -3951,7 +3939,7 @@ async function handleChangeTranscriptDate(args) {
3951
3939
  throw error;
3952
3940
  }
3953
3941
  }
3954
- const { updateTranscript } = await import('./frontmatter.js').then(n => n.h);
3942
+ const { updateTranscript } = await import('./frontmatter.js').then(n => n.g);
3955
3943
  const updatedContent = updateTranscript(content, {
3956
3944
  metadata: {
3957
3945
  date: newDate
@@ -3985,7 +3973,7 @@ async function handleCombineTranscripts(args) {
3985
3973
  });
3986
3974
  await validatePathWithinOutputDirectory(result.outputPath, args.contextDirectory);
3987
3975
  try {
3988
- const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.h);
3976
+ const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.g);
3989
3977
  const validation = parseTranscriptContent(result.content);
3990
3978
  if (!validation.metadata) {
3991
3979
  throw new Error("Combined content has no parseable metadata");
@@ -4032,7 +4020,7 @@ async function handleUpdateTranscriptContent(args) {
4032
4020
  const originalContent = await readFile(absolutePath, "utf-8");
4033
4021
  const updatedContent = replaceTranscriptContent(originalContent, args.content);
4034
4022
  try {
4035
- const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.h);
4023
+ const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.g);
4036
4024
  const validation = parseTranscriptContent(updatedContent);
4037
4025
  if (!validation.metadata) {
4038
4026
  throw new Error("Updated content has no parseable metadata");
@@ -4116,7 +4104,7 @@ async function handleUpdateTranscriptEntityReferences(args) {
4116
4104
  };
4117
4105
  const updatedContent = replaceEntityReferences(originalContent, metadataForFormatting);
4118
4106
  try {
4119
- const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.h);
4107
+ const { parseTranscriptContent } = await import('./frontmatter.js').then(n => n.g);
4120
4108
  const validation = parseTranscriptContent(updatedContent);
4121
4109
  if (!validation.metadata) {
4122
4110
  throw new Error("Updated content has no parseable metadata");
@@ -4349,7 +4337,7 @@ async function handleCreateNote(args) {
4349
4337
  status: "reviewed"
4350
4338
  // Default status for new notes
4351
4339
  };
4352
- const transcriptContent = await import('./frontmatter.js').then(n => n.h).then(
4340
+ const transcriptContent = await import('./frontmatter.js').then(n => n.g).then(
4353
4341
  (fm) => fm.stringifyTranscript(fullMetadata, args.content || "")
4354
4342
  );
4355
4343
  await mkdir(dirname(absolutePath), { recursive: true });