@nathanvale/chatline 0.0.1 → 0.0.2-next.1

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/CHANGELOG.md +12 -0
  2. package/dist/bin/index.js +1 -1
  3. package/dist/index.js +1 -1
  4. package/package.json +1 -1
  5. package/dist/cli/commands/clean.d.ts +0 -17
  6. package/dist/cli/commands/clean.d.ts.map +0 -1
  7. package/dist/cli/commands/clean.js +0 -142
  8. package/dist/cli/commands/clean.js.map +0 -1
  9. package/dist/cli/commands/doctor.d.ts +0 -17
  10. package/dist/cli/commands/doctor.d.ts.map +0 -1
  11. package/dist/cli/commands/doctor.js +0 -202
  12. package/dist/cli/commands/doctor.js.map +0 -1
  13. package/dist/cli/commands/enrich-ai.d.ts +0 -17
  14. package/dist/cli/commands/enrich-ai.d.ts.map +0 -1
  15. package/dist/cli/commands/enrich-ai.js +0 -371
  16. package/dist/cli/commands/enrich-ai.js.map +0 -1
  17. package/dist/cli/commands/index.d.ts +0 -16
  18. package/dist/cli/commands/index.d.ts.map +0 -1
  19. package/dist/cli/commands/index.js +0 -16
  20. package/dist/cli/commands/index.js.map +0 -1
  21. package/dist/cli/commands/ingest-csv.d.ts +0 -17
  22. package/dist/cli/commands/ingest-csv.d.ts.map +0 -1
  23. package/dist/cli/commands/ingest-csv.js +0 -138
  24. package/dist/cli/commands/ingest-csv.js.map +0 -1
  25. package/dist/cli/commands/ingest-db.d.ts +0 -17
  26. package/dist/cli/commands/ingest-db.d.ts.map +0 -1
  27. package/dist/cli/commands/ingest-db.js +0 -159
  28. package/dist/cli/commands/ingest-db.js.map +0 -1
  29. package/dist/cli/commands/init.d.ts +0 -17
  30. package/dist/cli/commands/init.d.ts.map +0 -1
  31. package/dist/cli/commands/init.js +0 -110
  32. package/dist/cli/commands/init.js.map +0 -1
  33. package/dist/cli/commands/normalize-link.d.ts +0 -16
  34. package/dist/cli/commands/normalize-link.d.ts.map +0 -1
  35. package/dist/cli/commands/normalize-link.js +0 -144
  36. package/dist/cli/commands/normalize-link.js.map +0 -1
  37. package/dist/cli/commands/render-markdown.d.ts +0 -17
  38. package/dist/cli/commands/render-markdown.d.ts.map +0 -1
  39. package/dist/cli/commands/render-markdown.js +0 -218
  40. package/dist/cli/commands/render-markdown.js.map +0 -1
  41. package/dist/cli/commands/stats.d.ts +0 -17
  42. package/dist/cli/commands/stats.d.ts.map +0 -1
  43. package/dist/cli/commands/stats.js +0 -175
  44. package/dist/cli/commands/stats.js.map +0 -1
  45. package/dist/cli/commands/validate.d.ts +0 -17
  46. package/dist/cli/commands/validate.d.ts.map +0 -1
  47. package/dist/cli/commands/validate.js +0 -152
  48. package/dist/cli/commands/validate.js.map +0 -1
  49. package/dist/cli/index.d.ts +0 -13
  50. package/dist/cli/index.d.ts.map +0 -1
  51. package/dist/cli/index.js +0 -121
  52. package/dist/cli/index.js.map +0 -1
  53. package/dist/cli/types.d.ts +0 -93
  54. package/dist/cli/types.d.ts.map +0 -1
  55. package/dist/cli/types.js +0 -7
  56. package/dist/cli/types.js.map +0 -1
  57. package/dist/cli/utils.d.ts +0 -29
  58. package/dist/cli/utils.d.ts.map +0 -1
  59. package/dist/cli/utils.js +0 -53
  60. package/dist/cli/utils.js.map +0 -1
  61. package/dist/cli.d.ts +0 -9
  62. package/dist/cli.d.ts.map +0 -1
  63. package/dist/cli.js +0 -1805
  64. package/dist/config/generator.d.ts +0 -90
  65. package/dist/config/generator.d.ts.map +0 -1
  66. package/dist/config/generator.js +0 -320
  67. package/dist/config/generator.js.map +0 -1
  68. package/dist/config/loader.d.ts +0 -107
  69. package/dist/config/loader.d.ts.map +0 -1
  70. package/dist/config/loader.js +0 -251
  71. package/dist/config/loader.js.map +0 -1
  72. package/dist/config/schema.d.ts +0 -107
  73. package/dist/config/schema.d.ts.map +0 -1
  74. package/dist/config/schema.js +0 -169
  75. package/dist/config/schema.js.map +0 -1
  76. package/dist/enrich/audio-transcription.d.ts +0 -77
  77. package/dist/enrich/audio-transcription.d.ts.map +0 -1
  78. package/dist/enrich/audio-transcription.js +0 -370
  79. package/dist/enrich/audio-transcription.js.map +0 -1
  80. package/dist/enrich/checkpoint.d.ts +0 -137
  81. package/dist/enrich/checkpoint.d.ts.map +0 -1
  82. package/dist/enrich/checkpoint.js +0 -205
  83. package/dist/enrich/checkpoint.js.map +0 -1
  84. package/dist/enrich/idempotency.d.ts +0 -90
  85. package/dist/enrich/idempotency.d.ts.map +0 -1
  86. package/dist/enrich/idempotency.js +0 -188
  87. package/dist/enrich/idempotency.js.map +0 -1
  88. package/dist/enrich/image-analysis.d.ts +0 -62
  89. package/dist/enrich/image-analysis.d.ts.map +0 -1
  90. package/dist/enrich/image-analysis.js +0 -264
  91. package/dist/enrich/image-analysis.js.map +0 -1
  92. package/dist/enrich/index.d.ts +0 -60
  93. package/dist/enrich/index.d.ts.map +0 -1
  94. package/dist/enrich/index.js +0 -74
  95. package/dist/enrich/index.js.map +0 -1
  96. package/dist/enrich/link-enrichment.d.ts +0 -37
  97. package/dist/enrich/link-enrichment.d.ts.map +0 -1
  98. package/dist/enrich/link-enrichment.js +0 -202
  99. package/dist/enrich/link-enrichment.js.map +0 -1
  100. package/dist/enrich/pdf-video-handling.d.ts +0 -49
  101. package/dist/enrich/pdf-video-handling.d.ts.map +0 -1
  102. package/dist/enrich/pdf-video-handling.js +0 -325
  103. package/dist/enrich/pdf-video-handling.js.map +0 -1
  104. package/dist/enrich/progress-tracker.d.ts +0 -120
  105. package/dist/enrich/progress-tracker.d.ts.map +0 -1
  106. package/dist/enrich/progress-tracker.js +0 -220
  107. package/dist/enrich/progress-tracker.js.map +0 -1
  108. package/dist/enrich/providers/firecrawl.d.ts +0 -18
  109. package/dist/enrich/providers/firecrawl.d.ts.map +0 -1
  110. package/dist/enrich/providers/firecrawl.js +0 -48
  111. package/dist/enrich/providers/firecrawl.js.map +0 -1
  112. package/dist/enrich/providers/generic.d.ts +0 -16
  113. package/dist/enrich/providers/generic.d.ts.map +0 -1
  114. package/dist/enrich/providers/generic.js +0 -36
  115. package/dist/enrich/providers/generic.js.map +0 -1
  116. package/dist/enrich/providers/index.d.ts +0 -14
  117. package/dist/enrich/providers/index.d.ts.map +0 -1
  118. package/dist/enrich/providers/index.js +0 -13
  119. package/dist/enrich/providers/index.js.map +0 -1
  120. package/dist/enrich/providers/instagram.d.ts +0 -16
  121. package/dist/enrich/providers/instagram.d.ts.map +0 -1
  122. package/dist/enrich/providers/instagram.js +0 -43
  123. package/dist/enrich/providers/instagram.js.map +0 -1
  124. package/dist/enrich/providers/spotify.d.ts +0 -16
  125. package/dist/enrich/providers/spotify.d.ts.map +0 -1
  126. package/dist/enrich/providers/spotify.js +0 -45
  127. package/dist/enrich/providers/spotify.js.map +0 -1
  128. package/dist/enrich/providers/twitter.d.ts +0 -16
  129. package/dist/enrich/providers/twitter.d.ts.map +0 -1
  130. package/dist/enrich/providers/twitter.js +0 -43
  131. package/dist/enrich/providers/twitter.js.map +0 -1
  132. package/dist/enrich/providers/types.d.ts +0 -47
  133. package/dist/enrich/providers/types.d.ts.map +0 -1
  134. package/dist/enrich/providers/types.js +0 -15
  135. package/dist/enrich/providers/types.js.map +0 -1
  136. package/dist/enrich/providers/youtube.d.ts +0 -16
  137. package/dist/enrich/providers/youtube.d.ts.map +0 -1
  138. package/dist/enrich/providers/youtube.js +0 -43
  139. package/dist/enrich/providers/youtube.js.map +0 -1
  140. package/dist/enrich/rate-limiting.d.ts +0 -118
  141. package/dist/enrich/rate-limiting.d.ts.map +0 -1
  142. package/dist/enrich/rate-limiting.js +0 -258
  143. package/dist/enrich/rate-limiting.js.map +0 -1
  144. package/dist/index.d.ts.map +0 -1
  145. package/dist/index.js.map +0 -1
  146. package/dist/ingest/dedup-merge.d.ts +0 -82
  147. package/dist/ingest/dedup-merge.d.ts.map +0 -1
  148. package/dist/ingest/dedup-merge.js +0 -262
  149. package/dist/ingest/dedup-merge.js.map +0 -1
  150. package/dist/ingest/ingest-csv.d.ts +0 -62
  151. package/dist/ingest/ingest-csv.d.ts.map +0 -1
  152. package/dist/ingest/ingest-csv.js +0 -300
  153. package/dist/ingest/ingest-csv.js.map +0 -1
  154. package/dist/ingest/ingest-db.d.ts +0 -64
  155. package/dist/ingest/ingest-db.d.ts.map +0 -1
  156. package/dist/ingest/ingest-db.js +0 -172
  157. package/dist/ingest/ingest-db.js.map +0 -1
  158. package/dist/ingest/link-replies-and-tapbacks.d.ts +0 -53
  159. package/dist/ingest/link-replies-and-tapbacks.d.ts.map +0 -1
  160. package/dist/ingest/link-replies-and-tapbacks.js +0 -381
  161. package/dist/ingest/link-replies-and-tapbacks.js.map +0 -1
  162. package/dist/normalize/date-converters.d.ts +0 -45
  163. package/dist/normalize/date-converters.d.ts.map +0 -1
  164. package/dist/normalize/date-converters.js +0 -166
  165. package/dist/normalize/date-converters.js.map +0 -1
  166. package/dist/normalize/path-validator.d.ts +0 -65
  167. package/dist/normalize/path-validator.d.ts.map +0 -1
  168. package/dist/normalize/path-validator.js +0 -221
  169. package/dist/normalize/path-validator.js.map +0 -1
  170. package/dist/normalize/validate-normalized.d.ts +0 -45
  171. package/dist/normalize/validate-normalized.d.ts.map +0 -1
  172. package/dist/normalize/validate-normalized.js +0 -144
  173. package/dist/normalize/validate-normalized.js.map +0 -1
  174. package/dist/render/embeds-blockquotes.d.ts +0 -84
  175. package/dist/render/embeds-blockquotes.d.ts.map +0 -1
  176. package/dist/render/embeds-blockquotes.js +0 -204
  177. package/dist/render/embeds-blockquotes.js.map +0 -1
  178. package/dist/render/grouping.d.ts +0 -78
  179. package/dist/render/grouping.d.ts.map +0 -1
  180. package/dist/render/grouping.js +0 -134
  181. package/dist/render/grouping.js.map +0 -1
  182. package/dist/render/index.d.ts +0 -47
  183. package/dist/render/index.d.ts.map +0 -1
  184. package/dist/render/index.js +0 -245
  185. package/dist/render/index.js.map +0 -1
  186. package/dist/render/reply-rendering.d.ts +0 -88
  187. package/dist/render/reply-rendering.d.ts.map +0 -1
  188. package/dist/render/reply-rendering.js +0 -196
  189. package/dist/render/reply-rendering.js.map +0 -1
  190. package/dist/schema/message.d.ts +0 -125
  191. package/dist/schema/message.d.ts.map +0 -1
  192. package/dist/schema/message.js +0 -331
  193. package/dist/schema/message.js.map +0 -1
  194. package/dist/utils/delta-detection.d.ts +0 -107
  195. package/dist/utils/delta-detection.d.ts.map +0 -1
  196. package/dist/utils/delta-detection.js +0 -199
  197. package/dist/utils/delta-detection.js.map +0 -1
  198. package/dist/utils/enrichment-merge.d.ts +0 -135
  199. package/dist/utils/enrichment-merge.d.ts.map +0 -1
  200. package/dist/utils/enrichment-merge.js +0 -280
  201. package/dist/utils/enrichment-merge.js.map +0 -1
  202. package/dist/utils/human.d.ts +0 -15
  203. package/dist/utils/human.d.ts.map +0 -1
  204. package/dist/utils/human.js +0 -27
  205. package/dist/utils/human.js.map +0 -1
  206. package/dist/utils/incremental-state.d.ts +0 -133
  207. package/dist/utils/incremental-state.d.ts.map +0 -1
  208. package/dist/utils/incremental-state.js +0 -237
  209. package/dist/utils/incremental-state.js.map +0 -1
  210. package/dist/utils/logger.d.ts +0 -40
  211. package/dist/utils/logger.d.ts.map +0 -1
  212. package/dist/utils/logger.js +0 -176
  213. package/dist/utils/logger.js.map +0 -1
@@ -1,144 +0,0 @@
1
- // src/normalize/validate-normalized.ts
2
- // Zod validation layer for normalized messages
3
- // Spec §4.3, §9: Schema validation with comprehensive error reporting
4
- import { MessageSchema } from '../schema/message';
5
- /**
6
- * AC01: Validate all normalized messages against MessageSchema
7
- * AC02: Include field paths in error messages
8
- * AC03: Batch validation - collect all errors before throwing
9
- * @param messages - Array of messages to validate
10
- * @returns Array of validated messages if all pass
11
- * @throws Error with formatted error messages if any validation fails
12
- */
13
- export function validateNormalizedMessages(messages) {
14
- if (!Array.isArray(messages)) {
15
- throw new Error('Messages must be an array');
16
- }
17
- const validatedMessages = [];
18
- const errors = [];
19
- // Process each message and collect errors (AC03: no fail-fast)
20
- for (let i = 0; i < messages.length; i++) {
21
- const message = messages[i];
22
- // AC04: Check for snake_case fields before schema validation
23
- if (typeof message === 'object' &&
24
- message !== null &&
25
- hasSnakeCaseFields(message)) {
26
- const snakeCaseFields = getSnakeCaseFields(message);
27
- const fieldList = snakeCaseFields.join(', ');
28
- errors.push({
29
- index: i,
30
- fieldPath: 'root',
31
- message: `Message contains snake_case fields: ${fieldList}. Use camelCase instead.`,
32
- });
33
- continue;
34
- }
35
- // Validate against schema
36
- const result = MessageSchema.safeParse(message);
37
- if (!result.success) {
38
- // AC02: Format Zod errors with field paths
39
- const formattedErrors = formatValidationErrors(i, result.error.errors);
40
- errors.push({
41
- index: i,
42
- fieldPath: 'multiple',
43
- message: formattedErrors,
44
- });
45
- }
46
- else {
47
- validatedMessages.push(result.data);
48
- }
49
- }
50
- // If any errors occurred, throw with all collected errors (AC03)
51
- if (errors.length > 0) {
52
- const errorSummary = errors
53
- .map((e) => `messages.${e.index}: ${e.message}`)
54
- .join('\n');
55
- const error = new Error(`Validation failed:\n${errorSummary}`);
56
- error.name = 'ValidationError';
57
- throw error;
58
- }
59
- return validatedMessages;
60
- }
61
- /**
62
- * AC02: Format Zod validation errors with field paths
63
- * Converts Zod error array into readable messages with paths
64
- * @param messageIndex - Index of the message in the array
65
- * @param zodErrors - Zod validation errors
66
- * @returns Formatted error message string
67
- */
68
- export function formatValidationErrors(_messageIndex, zodErrors) {
69
- if (!Array.isArray(zodErrors) || zodErrors.length === 0) {
70
- return 'Unknown validation error';
71
- }
72
- const formatted = zodErrors
73
- .map((error) => {
74
- // Build path: ["media", "enrichment", 0, "createdAt"] -> "media.enrichment.0.createdAt"
75
- const path = (error.path || []).join('.');
76
- const pathPrefix = path ? `${path}: ` : '';
77
- return `${pathPrefix}${error.message}`;
78
- })
79
- .join('; ');
80
- return formatted;
81
- }
82
- /**
83
- * AC04: Detect if message has snake_case fields
84
- * Recursively checks for snake_case field names
85
- * @param obj - Object to check
86
- * @returns true if any snake_case fields found
87
- */
88
- export function hasSnakeCaseFields(obj, depth = 0) {
89
- if (depth > 10)
90
- return false; // Prevent infinite recursion
91
- if (typeof obj !== 'object' || obj === null)
92
- return false;
93
- const record = obj;
94
- for (const key of Object.keys(record)) {
95
- // Check if key contains underscore (snake_case indicator)
96
- if (key.includes('_') && !key.startsWith('__')) {
97
- return true;
98
- }
99
- // Recursively check nested objects
100
- const value = record[key];
101
- if (typeof value === 'object' && value !== null) {
102
- if (hasSnakeCaseFields(value, depth + 1)) {
103
- return true;
104
- }
105
- }
106
- }
107
- return false;
108
- }
109
- /**
110
- * Get all snake_case fields in an object (for error reporting)
111
- * @param obj - Object to check
112
- * @returns Array of field names that use snake_case
113
- */
114
- export function getSnakeCaseFields(obj, prefix = '', depth = 0) {
115
- if (depth > 10)
116
- return []; // Prevent infinite recursion
117
- if (typeof obj !== 'object' || obj === null)
118
- return [];
119
- const snakeCaseFields = [];
120
- const record = obj;
121
- for (const key of Object.keys(record)) {
122
- const fullPath = prefix ? `${prefix}.${key}` : key;
123
- // Check if key contains underscore (snake_case indicator)
124
- if (key.includes('_') && !key.startsWith('__')) {
125
- snakeCaseFields.push(fullPath);
126
- }
127
- // Recursively check nested objects
128
- const value = record[key];
129
- if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
130
- snakeCaseFields.push(...getSnakeCaseFields(value, fullPath, depth + 1));
131
- }
132
- }
133
- return snakeCaseFields;
134
- }
135
- /**
136
- * AC03: Collect validation errors from multiple messages
137
- * Helper to aggregate errors with message index
138
- * @param errorList - List of validation errors
139
- * @returns Formatted error messages with indices
140
- */
141
- export function collectValidationErrors(errorList) {
142
- return errorList.map((e) => `messages.${e.index}.${e.fieldPath}: ${e.message}`);
143
- }
144
- //# sourceMappingURL=validate-normalized.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"validate-normalized.js","sourceRoot":"","sources":["../../src/normalize/validate-normalized.ts"],"names":[],"mappings":"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"}
@@ -1,84 +0,0 @@
1
- /**
2
- * Embeds and Blockquotes Rendering Module (RENDER--T03)
3
- *
4
- * Implements Obsidian-friendly embeds and blockquote rendering:
5
- * - AC01: Image embeds with ![[path]] syntax
6
- * - AC02: Preview images with links to originals (HEIC/TIFF)
7
- * - AC03: Transcription blockquotes with speaker labels
8
- * - AC04: Link context blockquotes with metadata
9
- * - AC05: PDF summary blockquotes with formatting
10
- */
11
- import type { MediaEnrichment, Message } from '#schema/message';
12
- /**
13
- * AC01: Render image embed with Obsidian wikilink syntax
14
- * Format: ![[path]]
15
- */
16
- export declare function renderImageEmbed(path: string): string;
17
- /**
18
- * AC02: Render preview image with link to original
19
- * For HEIC/TIFF files, shows preview with link to original
20
- */
21
- export declare function renderPreviewImageWithLink(previewPath: string, originalPath: string): string;
22
- /**
23
- * AC03: Render transcription as blockquote
24
- * Handles multiline transcriptions with speaker labels and timestamps
25
- */
26
- export declare function renderTranscriptionBlockquote(enrichment: MediaEnrichment): string;
27
- /**
28
- * AC04: Render link context as blockquote
29
- * Shows title as markdown link and summary as blockquote
30
- */
31
- export declare function renderLinkContextBlockquote(enrichment: MediaEnrichment): string;
32
- /**
33
- * AC05: Render PDF summary as blockquote
34
- * Preserves paragraph structure with blockquote formatting
35
- */
36
- export declare function renderPdfSummaryBlockquote(enrichment: MediaEnrichment): string;
37
- /**
38
- * Determine if a message should render an embed
39
- * Only renders embeds for image media
40
- */
41
- export declare function shouldRenderEmbed(message: Message): boolean;
42
- /**
43
- * Get the path to embed for a media message
44
- * Returns undefined if message cannot be embedded
45
- */
46
- export declare function getEmbedPath(message: Message): string | undefined;
47
- /**
48
- * Get preview path for an image file
49
- * For HEIC/TIFF, returns the .jpg preview path
50
- * For JPG/PNG, returns the original path
51
- */
52
- export declare function getPreviewPath(originalPath: string): string;
53
- /**
54
- * Get the original path from a preview path
55
- * Handles HEIC.jpg -> HEIC and TIFF.jpg -> TIFF conversions
56
- */
57
- export declare function getOriginalPath(previewPath: string): string;
58
- /**
59
- * Extract enrichments of a specific kind from a media message
60
- */
61
- export declare function getEnrichmentsByKind(message: Message, kind: MediaEnrichment['kind']): MediaEnrichment[];
62
- /**
63
- * Get all transcription enrichments from a message
64
- */
65
- export declare function getTranscriptions(message: Message): MediaEnrichment[];
66
- /**
67
- * Get all link context enrichments from a message
68
- */
69
- export declare function getLinkContexts(message: Message): MediaEnrichment[];
70
- /**
71
- * Get all PDF summary enrichments from a message
72
- */
73
- export declare function getPdfSummaries(message: Message): MediaEnrichment[];
74
- /**
75
- * Render all blockquotes for a message's enrichments
76
- */
77
- export type RenderedEnrichments = {
78
- embeds: string[];
79
- transcriptions: string[];
80
- linkContexts: string[];
81
- pdfSummaries: string[];
82
- };
83
- export declare function renderAllEnrichments(message: Message): RenderedEnrichments;
84
- //# sourceMappingURL=embeds-blockquotes.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embeds-blockquotes.d.ts","sourceRoot":"","sources":["../../src/render/embeds-blockquotes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAE/D;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,WAAW,EAAE,MAAM,EACnB,YAAY,EAAE,MAAM,GAClB,MAAM,CAGR;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAC5C,UAAU,EAAE,eAAe,GACzB,MAAM,CAOR;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAC1C,UAAU,EAAE,eAAe,GACzB,MAAM,CA2BR;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CACzC,UAAU,EAAE,eAAe,GACzB,MAAM,CAOR;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAMjE;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAa3D;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAkB3D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,OAAO,EAChB,IAAI,EAAE,eAAe,CAAC,MAAM,CAAC,GAC3B,eAAe,EAAE,CAMnB;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,EAAE,CAErE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,EAAE,CAEnE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,eAAe,EAAE,CAEnE;AAED;;GAEG;AACH,MAAM,MAAM,mBAAmB,GAAG;IACjC,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,cAAc,EAAE,MAAM,EAAE,CAAA;IACxB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,MAAM,EAAE,CAAA;CACtB,CAAA;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,mBAAmB,CAwC1E"}
@@ -1,204 +0,0 @@
1
- /**
2
- * Embeds and Blockquotes Rendering Module (RENDER--T03)
3
- *
4
- * Implements Obsidian-friendly embeds and blockquote rendering:
5
- * - AC01: Image embeds with ![[path]] syntax
6
- * - AC02: Preview images with links to originals (HEIC/TIFF)
7
- * - AC03: Transcription blockquotes with speaker labels
8
- * - AC04: Link context blockquotes with metadata
9
- * - AC05: PDF summary blockquotes with formatting
10
- */
11
- /**
12
- * AC01: Render image embed with Obsidian wikilink syntax
13
- * Format: ![[path]]
14
- */
15
- export function renderImageEmbed(path) {
16
- return `![[${path}]]`;
17
- }
18
- /**
19
- * AC02: Render preview image with link to original
20
- * For HEIC/TIFF files, shows preview with link to original
21
- */
22
- export function renderPreviewImageWithLink(previewPath, originalPath) {
23
- const filename = originalPath.split('/').pop() || 'original';
24
- return `![[${previewPath}]]\n[Original: ${filename}](${originalPath})`;
25
- }
26
- /**
27
- * AC03: Render transcription as blockquote
28
- * Handles multiline transcriptions with speaker labels and timestamps
29
- */
30
- export function renderTranscriptionBlockquote(enrichment) {
31
- if (enrichment.kind !== 'transcription' || !enrichment.transcription) {
32
- return '';
33
- }
34
- const lines = enrichment.transcription.split('\n');
35
- return lines.map((line) => `> ${line}`).join('\n');
36
- }
37
- /**
38
- * AC04: Render link context as blockquote
39
- * Shows title as markdown link and summary as blockquote
40
- */
41
- export function renderLinkContextBlockquote(enrichment) {
42
- if (enrichment.kind !== 'link_context') {
43
- return '';
44
- }
45
- const parts = [];
46
- // Format title as markdown link if available
47
- if (enrichment.title && enrichment.url) {
48
- parts.push(`> [${enrichment.title}](${enrichment.url})`);
49
- }
50
- else if (enrichment.url) {
51
- parts.push(`> [${enrichment.url}](${enrichment.url})`);
52
- }
53
- // Add summary as blockquote lines
54
- if (enrichment.summary) {
55
- const summaryLines = enrichment.summary.split('\n');
56
- for (const line of summaryLines) {
57
- if (line.trim()) {
58
- parts.push(`> ${line}`);
59
- }
60
- else {
61
- parts.push('> ');
62
- }
63
- }
64
- }
65
- return parts.join('\n');
66
- }
67
- /**
68
- * AC05: Render PDF summary as blockquote
69
- * Preserves paragraph structure with blockquote formatting
70
- */
71
- export function renderPdfSummaryBlockquote(enrichment) {
72
- if (enrichment.kind !== 'pdf_summary' || !enrichment.pdfSummary) {
73
- return '';
74
- }
75
- const lines = enrichment.pdfSummary.split('\n');
76
- return lines.map((line) => `> ${line}`).join('\n');
77
- }
78
- /**
79
- * Determine if a message should render an embed
80
- * Only renders embeds for image media
81
- */
82
- export function shouldRenderEmbed(message) {
83
- if (message.messageKind !== 'media' || !message.media) {
84
- return false;
85
- }
86
- // Only embed images
87
- return message.media.mediaKind === 'image';
88
- }
89
- /**
90
- * Get the path to embed for a media message
91
- * Returns undefined if message cannot be embedded
92
- */
93
- export function getEmbedPath(message) {
94
- if (!shouldRenderEmbed(message)) {
95
- return undefined;
96
- }
97
- return message.media?.path;
98
- }
99
- /**
100
- * Get preview path for an image file
101
- * For HEIC/TIFF, returns the .jpg preview path
102
- * For JPG/PNG, returns the original path
103
- */
104
- export function getPreviewPath(originalPath) {
105
- const lowerPath = originalPath.toLowerCase();
106
- if (lowerPath.endsWith('.heic')) {
107
- return `${originalPath}.jpg`;
108
- }
109
- if (lowerPath.endsWith('.tiff') || lowerPath.endsWith('.tif')) {
110
- return `${originalPath}.jpg`;
111
- }
112
- // JPG, PNG, and other formats return as-is
113
- return originalPath;
114
- }
115
- /**
116
- * Get the original path from a preview path
117
- * Handles HEIC.jpg -> HEIC and TIFF.jpg -> TIFF conversions
118
- */
119
- export function getOriginalPath(previewPath) {
120
- // If it ends with .jpg, check if it's a preview
121
- if (previewPath.endsWith('.jpg')) {
122
- const withoutJpg = previewPath.slice(0, -4);
123
- if (withoutJpg.toLowerCase().endsWith('.heic')) {
124
- return withoutJpg;
125
- }
126
- if (withoutJpg.toLowerCase().endsWith('.tiff') ||
127
- withoutJpg.toLowerCase().endsWith('.tif')) {
128
- return withoutJpg;
129
- }
130
- }
131
- return previewPath;
132
- }
133
- /**
134
- * Extract enrichments of a specific kind from a media message
135
- */
136
- export function getEnrichmentsByKind(message, kind) {
137
- if (message.messageKind !== 'media' || !message.media?.enrichment) {
138
- return [];
139
- }
140
- return message.media.enrichment.filter((e) => e.kind === kind);
141
- }
142
- /**
143
- * Get all transcription enrichments from a message
144
- */
145
- export function getTranscriptions(message) {
146
- return getEnrichmentsByKind(message, 'transcription');
147
- }
148
- /**
149
- * Get all link context enrichments from a message
150
- */
151
- export function getLinkContexts(message) {
152
- return getEnrichmentsByKind(message, 'link_context');
153
- }
154
- /**
155
- * Get all PDF summary enrichments from a message
156
- */
157
- export function getPdfSummaries(message) {
158
- return getEnrichmentsByKind(message, 'pdf_summary');
159
- }
160
- export function renderAllEnrichments(message) {
161
- const result = {
162
- embeds: [],
163
- transcriptions: [],
164
- linkContexts: [],
165
- pdfSummaries: [],
166
- };
167
- // Handle image embeds
168
- if (shouldRenderEmbed(message)) {
169
- const embedPath = getEmbedPath(message);
170
- if (embedPath) {
171
- const previewPath = getPreviewPath(embedPath);
172
- if (previewPath === embedPath) {
173
- // No preview needed, just embed
174
- result.embeds.push(renderImageEmbed(embedPath));
175
- }
176
- else {
177
- // Preview available, show with link to original
178
- result.embeds.push(renderPreviewImageWithLink(previewPath, embedPath));
179
- }
180
- }
181
- }
182
- // Handle enrichments if media
183
- if (message.media?.enrichment) {
184
- for (const enrichment of message.media.enrichment) {
185
- if (enrichment.kind === 'transcription') {
186
- const rendered = renderTranscriptionBlockquote(enrichment);
187
- if (rendered)
188
- result.transcriptions.push(rendered);
189
- }
190
- else if (enrichment.kind === 'link_context') {
191
- const rendered = renderLinkContextBlockquote(enrichment);
192
- if (rendered)
193
- result.linkContexts.push(rendered);
194
- }
195
- else if (enrichment.kind === 'pdf_summary') {
196
- const rendered = renderPdfSummaryBlockquote(enrichment);
197
- if (rendered)
198
- result.pdfSummaries.push(rendered);
199
- }
200
- }
201
- }
202
- return result;
203
- }
204
- //# sourceMappingURL=embeds-blockquotes.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"embeds-blockquotes.js","sourceRoot":"","sources":["../../src/render/embeds-blockquotes.ts"],"names":[],"mappings":"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"}
@@ -1,78 +0,0 @@
1
- /**
2
- * Grouping and Anchor Generation Module (RENDER--T01)
3
- *
4
- * Implements message grouping and Obsidian-friendly anchor generation:
5
- * - AC01: Group messages by date (YYYY-MM-DD)
6
- * - AC02: Sub-group by time-of-day (Morning/Afternoon/Evening)
7
- * - AC03: Generate unique anchor IDs (#msg-{guid})
8
- * - AC04: Obsidian-compatible deep-link anchors
9
- * - AC05: Maintain chronological ordering within time-of-day groups
10
- */
11
- import type { Message } from '#schema/message';
12
- /**
13
- * Time-of-day classification
14
- */
15
- export type TimeOfDay = 'morning' | 'afternoon' | 'evening';
16
- /**
17
- * Group structure for a single time-of-day period
18
- */
19
- export type TimeOfDayGroup = {
20
- morning: Message[];
21
- afternoon: Message[];
22
- evening: Message[];
23
- };
24
- /**
25
- * Grouped messages by date and time-of-day
26
- * Key: YYYY-MM-DD
27
- */
28
- export type GroupedMessages = {
29
- [date: string]: TimeOfDayGroup;
30
- };
31
- /**
32
- * AC02: Classify a timestamp into time-of-day category
33
- * Morning: 00:00-11:59
34
- * Afternoon: 12:00-17:59
35
- * Evening: 18:00-23:59
36
- */
37
- export declare function classifyTimeOfDay(isoTimestamp: string): TimeOfDay;
38
- /**
39
- * AC03: Generate unique anchor ID for a message
40
- * Format: #msg-{guid}
41
- */
42
- export declare function generateAnchorId(guid: string): string;
43
- /**
44
- * AC01: Extract date from ISO timestamp in YYYY-MM-DD format
45
- */
46
- export declare function extractDate(isoTimestamp: string): string;
47
- /**
48
- * AC05: Sort messages chronologically by timestamp
49
- * Does not mutate original array
50
- */
51
- export declare function sortByTimestamp(messages: Message[]): Message[];
52
- /**
53
- * AC01-AC05: Group messages by date and time-of-day
54
- * Returns nested structure with chronological ordering maintained
55
- */
56
- export declare function groupMessagesByDateAndTimeOfDay(messages: Message[]): GroupedMessages;
57
- /**
58
- * Get all unique dates from grouped messages
59
- * Returns dates in chronological order
60
- */
61
- export declare function getDatesSorted(grouped: GroupedMessages): string[];
62
- /**
63
- * Get all messages from a date group in chronological order
64
- * Combines all time-of-day groups in order
65
- */
66
- export declare function getAllMessagesForDate(dateGroup: TimeOfDayGroup): Message[];
67
- /**
68
- * Type guards and utilities
69
- */
70
- /**
71
- * Check if date group has any messages
72
- */
73
- export declare function hasMessages(dateGroup: TimeOfDayGroup): boolean;
74
- /**
75
- * Get count of messages in time-of-day
76
- */
77
- export declare function getMessageCount(dateGroup: TimeOfDayGroup): number;
78
- //# sourceMappingURL=grouping.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"grouping.d.ts","sourceRoot":"","sources":["../../src/render/grouping.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,iBAAiB,CAAA;AAc9C;;GAEG;AACH,MAAM,MAAM,SAAS,GAAG,SAAS,GAAG,WAAW,GAAG,SAAS,CAAA;AAE3D;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC5B,OAAO,EAAE,OAAO,EAAE,CAAA;IAClB,SAAS,EAAE,OAAO,EAAE,CAAA;IACpB,OAAO,EAAE,OAAO,EAAE,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,MAAM,MAAM,eAAe,GAAG;IAC7B,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAAA;CAC9B,CAAA;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,YAAY,EAAE,MAAM,GAAG,SAAS,CAWjE;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAErD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAMxD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAM9D;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAC9C,QAAQ,EAAE,OAAO,EAAE,GACjB,eAAe,CAgCjB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,MAAM,EAAE,CAIjE;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,EAAE,CAE1E;AAED;;GAEG;AAEH;;GAEG;AACH,wBAAgB,WAAW,CAAC,SAAS,EAAE,cAAc,GAAG,OAAO,CAM9D;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,cAAc,GAAG,MAAM,CAMjE"}
@@ -1,134 +0,0 @@
1
- /**
2
- * Grouping and Anchor Generation Module (RENDER--T01)
3
- *
4
- * Implements message grouping and Obsidian-friendly anchor generation:
5
- * - AC01: Group messages by date (YYYY-MM-DD)
6
- * - AC02: Sub-group by time-of-day (Morning/Afternoon/Evening)
7
- * - AC03: Generate unique anchor IDs (#msg-{guid})
8
- * - AC04: Obsidian-compatible deep-link anchors
9
- * - AC05: Maintain chronological ordering within time-of-day groups
10
- */
11
- /**
12
- * Normalize any ISO-like timestamp to canonical UTC ISO format.
13
- * - If no timezone designator (no 'Z' and no +/- offset), treat as UTC by appending 'Z'.
14
- * - Then return Date.toISOString() to canonicalize milliseconds and Z suffix.
15
- */
16
- function normalizeIsoUtc(input) {
17
- const hasZ = /Z$/.test(input);
18
- const hasOffset = /[+-]\d{2}:?\d{2}$/.test(input);
19
- const coerced = hasZ || hasOffset ? input : `${input.replace(/\s+$/, '')}Z`;
20
- return new Date(coerced).toISOString();
21
- }
22
- /**
23
- * AC02: Classify a timestamp into time-of-day category
24
- * Morning: 00:00-11:59
25
- * Afternoon: 12:00-17:59
26
- * Evening: 18:00-23:59
27
- */
28
- export function classifyTimeOfDay(isoTimestamp) {
29
- const date = new Date(normalizeIsoUtc(isoTimestamp));
30
- const hours = date.getUTCHours();
31
- if (hours < 12) {
32
- return 'morning';
33
- }
34
- if (hours < 18) {
35
- return 'afternoon';
36
- }
37
- return 'evening';
38
- }
39
- /**
40
- * AC03: Generate unique anchor ID for a message
41
- * Format: #msg-{guid}
42
- */
43
- export function generateAnchorId(guid) {
44
- return `#msg-${guid}`;
45
- }
46
- /**
47
- * AC01: Extract date from ISO timestamp in YYYY-MM-DD format
48
- */
49
- export function extractDate(isoTimestamp) {
50
- const date = new Date(normalizeIsoUtc(isoTimestamp));
51
- const year = date.getUTCFullYear();
52
- const month = String(date.getUTCMonth() + 1).padStart(2, '0');
53
- const day = String(date.getUTCDate()).padStart(2, '0');
54
- return `${year}-${month}-${day}`;
55
- }
56
- /**
57
- * AC05: Sort messages chronologically by timestamp
58
- * Does not mutate original array
59
- */
60
- export function sortByTimestamp(messages) {
61
- return [...messages].sort((a, b) => {
62
- const timeA = new Date(normalizeIsoUtc(a.date)).getTime();
63
- const timeB = new Date(normalizeIsoUtc(b.date)).getTime();
64
- return timeA - timeB;
65
- });
66
- }
67
- /**
68
- * AC01-AC05: Group messages by date and time-of-day
69
- * Returns nested structure with chronological ordering maintained
70
- */
71
- export function groupMessagesByDateAndTimeOfDay(messages) {
72
- const grouped = {};
73
- // First pass: create date groups and classify by time-of-day
74
- for (const message of messages) {
75
- const date = extractDate(message.date);
76
- const timeOfDay = classifyTimeOfDay(message.date);
77
- // Initialize date group if not exists
78
- if (!grouped[date]) {
79
- grouped[date] = {
80
- morning: [],
81
- afternoon: [],
82
- evening: [],
83
- };
84
- }
85
- // Add message to appropriate time-of-day group
86
- grouped[date][timeOfDay].push(message);
87
- }
88
- // Second pass: sort each time-of-day group chronologically
89
- for (const date in grouped) {
90
- const dayGroup = grouped[date];
91
- if (dayGroup) {
92
- dayGroup.morning = sortByTimestamp(dayGroup.morning);
93
- dayGroup.afternoon = sortByTimestamp(dayGroup.afternoon);
94
- dayGroup.evening = sortByTimestamp(dayGroup.evening);
95
- }
96
- }
97
- return grouped;
98
- }
99
- /**
100
- * Get all unique dates from grouped messages
101
- * Returns dates in chronological order
102
- */
103
- export function getDatesSorted(grouped) {
104
- // Keys are YYYY-MM-DD; lexicographic sort is equivalent to chronological
105
- // Avoid Date parsing entirely to prevent any environment-specific quirks.
106
- return Object.keys(grouped).sort();
107
- }
108
- /**
109
- * Get all messages from a date group in chronological order
110
- * Combines all time-of-day groups in order
111
- */
112
- export function getAllMessagesForDate(dateGroup) {
113
- return [...dateGroup.morning, ...dateGroup.afternoon, ...dateGroup.evening];
114
- }
115
- /**
116
- * Type guards and utilities
117
- */
118
- /**
119
- * Check if date group has any messages
120
- */
121
- export function hasMessages(dateGroup) {
122
- return (dateGroup.morning.length > 0 ||
123
- dateGroup.afternoon.length > 0 ||
124
- dateGroup.evening.length > 0);
125
- }
126
- /**
127
- * Get count of messages in time-of-day
128
- */
129
- export function getMessageCount(dateGroup) {
130
- return (dateGroup.morning.length +
131
- dateGroup.afternoon.length +
132
- dateGroup.evening.length);
133
- }
134
- //# sourceMappingURL=grouping.js.map