@nathanvale/chatline 0.0.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 (216) hide show
  1. package/CHANGELOG.md +1 -0
  2. package/LICENSE +21 -0
  3. package/README.md +1535 -0
  4. package/dist/bin/index.js +5121 -0
  5. package/dist/cli/commands/clean.d.ts +17 -0
  6. package/dist/cli/commands/clean.d.ts.map +1 -0
  7. package/dist/cli/commands/clean.js +142 -0
  8. package/dist/cli/commands/clean.js.map +1 -0
  9. package/dist/cli/commands/doctor.d.ts +17 -0
  10. package/dist/cli/commands/doctor.d.ts.map +1 -0
  11. package/dist/cli/commands/doctor.js +202 -0
  12. package/dist/cli/commands/doctor.js.map +1 -0
  13. package/dist/cli/commands/enrich-ai.d.ts +17 -0
  14. package/dist/cli/commands/enrich-ai.d.ts.map +1 -0
  15. package/dist/cli/commands/enrich-ai.js +371 -0
  16. package/dist/cli/commands/enrich-ai.js.map +1 -0
  17. package/dist/cli/commands/index.d.ts +16 -0
  18. package/dist/cli/commands/index.d.ts.map +1 -0
  19. package/dist/cli/commands/index.js +16 -0
  20. package/dist/cli/commands/index.js.map +1 -0
  21. package/dist/cli/commands/ingest-csv.d.ts +17 -0
  22. package/dist/cli/commands/ingest-csv.d.ts.map +1 -0
  23. package/dist/cli/commands/ingest-csv.js +138 -0
  24. package/dist/cli/commands/ingest-csv.js.map +1 -0
  25. package/dist/cli/commands/ingest-db.d.ts +17 -0
  26. package/dist/cli/commands/ingest-db.d.ts.map +1 -0
  27. package/dist/cli/commands/ingest-db.js +159 -0
  28. package/dist/cli/commands/ingest-db.js.map +1 -0
  29. package/dist/cli/commands/init.d.ts +17 -0
  30. package/dist/cli/commands/init.d.ts.map +1 -0
  31. package/dist/cli/commands/init.js +110 -0
  32. package/dist/cli/commands/init.js.map +1 -0
  33. package/dist/cli/commands/normalize-link.d.ts +16 -0
  34. package/dist/cli/commands/normalize-link.d.ts.map +1 -0
  35. package/dist/cli/commands/normalize-link.js +144 -0
  36. package/dist/cli/commands/normalize-link.js.map +1 -0
  37. package/dist/cli/commands/render-markdown.d.ts +17 -0
  38. package/dist/cli/commands/render-markdown.d.ts.map +1 -0
  39. package/dist/cli/commands/render-markdown.js +218 -0
  40. package/dist/cli/commands/render-markdown.js.map +1 -0
  41. package/dist/cli/commands/stats.d.ts +17 -0
  42. package/dist/cli/commands/stats.d.ts.map +1 -0
  43. package/dist/cli/commands/stats.js +175 -0
  44. package/dist/cli/commands/stats.js.map +1 -0
  45. package/dist/cli/commands/validate.d.ts +17 -0
  46. package/dist/cli/commands/validate.d.ts.map +1 -0
  47. package/dist/cli/commands/validate.js +152 -0
  48. package/dist/cli/commands/validate.js.map +1 -0
  49. package/dist/cli/index.d.ts +13 -0
  50. package/dist/cli/index.d.ts.map +1 -0
  51. package/dist/cli/index.js +121 -0
  52. package/dist/cli/index.js.map +1 -0
  53. package/dist/cli/types.d.ts +93 -0
  54. package/dist/cli/types.d.ts.map +1 -0
  55. package/dist/cli/types.js +7 -0
  56. package/dist/cli/types.js.map +1 -0
  57. package/dist/cli/utils.d.ts +29 -0
  58. package/dist/cli/utils.d.ts.map +1 -0
  59. package/dist/cli/utils.js +53 -0
  60. package/dist/cli/utils.js.map +1 -0
  61. package/dist/cli.d.ts +9 -0
  62. package/dist/cli.d.ts.map +1 -0
  63. package/dist/cli.js +1805 -0
  64. package/dist/config/generator.d.ts +90 -0
  65. package/dist/config/generator.d.ts.map +1 -0
  66. package/dist/config/generator.js +320 -0
  67. package/dist/config/generator.js.map +1 -0
  68. package/dist/config/loader.d.ts +107 -0
  69. package/dist/config/loader.d.ts.map +1 -0
  70. package/dist/config/loader.js +251 -0
  71. package/dist/config/loader.js.map +1 -0
  72. package/dist/config/schema.d.ts +107 -0
  73. package/dist/config/schema.d.ts.map +1 -0
  74. package/dist/config/schema.js +169 -0
  75. package/dist/config/schema.js.map +1 -0
  76. package/dist/enrich/audio-transcription.d.ts +77 -0
  77. package/dist/enrich/audio-transcription.d.ts.map +1 -0
  78. package/dist/enrich/audio-transcription.js +370 -0
  79. package/dist/enrich/audio-transcription.js.map +1 -0
  80. package/dist/enrich/checkpoint.d.ts +137 -0
  81. package/dist/enrich/checkpoint.d.ts.map +1 -0
  82. package/dist/enrich/checkpoint.js +205 -0
  83. package/dist/enrich/checkpoint.js.map +1 -0
  84. package/dist/enrich/idempotency.d.ts +90 -0
  85. package/dist/enrich/idempotency.d.ts.map +1 -0
  86. package/dist/enrich/idempotency.js +188 -0
  87. package/dist/enrich/idempotency.js.map +1 -0
  88. package/dist/enrich/image-analysis.d.ts +62 -0
  89. package/dist/enrich/image-analysis.d.ts.map +1 -0
  90. package/dist/enrich/image-analysis.js +264 -0
  91. package/dist/enrich/image-analysis.js.map +1 -0
  92. package/dist/enrich/index.d.ts +60 -0
  93. package/dist/enrich/index.d.ts.map +1 -0
  94. package/dist/enrich/index.js +74 -0
  95. package/dist/enrich/index.js.map +1 -0
  96. package/dist/enrich/link-enrichment.d.ts +37 -0
  97. package/dist/enrich/link-enrichment.d.ts.map +1 -0
  98. package/dist/enrich/link-enrichment.js +202 -0
  99. package/dist/enrich/link-enrichment.js.map +1 -0
  100. package/dist/enrich/pdf-video-handling.d.ts +49 -0
  101. package/dist/enrich/pdf-video-handling.d.ts.map +1 -0
  102. package/dist/enrich/pdf-video-handling.js +325 -0
  103. package/dist/enrich/pdf-video-handling.js.map +1 -0
  104. package/dist/enrich/progress-tracker.d.ts +120 -0
  105. package/dist/enrich/progress-tracker.d.ts.map +1 -0
  106. package/dist/enrich/progress-tracker.js +220 -0
  107. package/dist/enrich/progress-tracker.js.map +1 -0
  108. package/dist/enrich/providers/firecrawl.d.ts +18 -0
  109. package/dist/enrich/providers/firecrawl.d.ts.map +1 -0
  110. package/dist/enrich/providers/firecrawl.js +48 -0
  111. package/dist/enrich/providers/firecrawl.js.map +1 -0
  112. package/dist/enrich/providers/generic.d.ts +16 -0
  113. package/dist/enrich/providers/generic.d.ts.map +1 -0
  114. package/dist/enrich/providers/generic.js +36 -0
  115. package/dist/enrich/providers/generic.js.map +1 -0
  116. package/dist/enrich/providers/index.d.ts +14 -0
  117. package/dist/enrich/providers/index.d.ts.map +1 -0
  118. package/dist/enrich/providers/index.js +13 -0
  119. package/dist/enrich/providers/index.js.map +1 -0
  120. package/dist/enrich/providers/instagram.d.ts +16 -0
  121. package/dist/enrich/providers/instagram.d.ts.map +1 -0
  122. package/dist/enrich/providers/instagram.js +43 -0
  123. package/dist/enrich/providers/instagram.js.map +1 -0
  124. package/dist/enrich/providers/spotify.d.ts +16 -0
  125. package/dist/enrich/providers/spotify.d.ts.map +1 -0
  126. package/dist/enrich/providers/spotify.js +45 -0
  127. package/dist/enrich/providers/spotify.js.map +1 -0
  128. package/dist/enrich/providers/twitter.d.ts +16 -0
  129. package/dist/enrich/providers/twitter.d.ts.map +1 -0
  130. package/dist/enrich/providers/twitter.js +43 -0
  131. package/dist/enrich/providers/twitter.js.map +1 -0
  132. package/dist/enrich/providers/types.d.ts +47 -0
  133. package/dist/enrich/providers/types.d.ts.map +1 -0
  134. package/dist/enrich/providers/types.js +15 -0
  135. package/dist/enrich/providers/types.js.map +1 -0
  136. package/dist/enrich/providers/youtube.d.ts +16 -0
  137. package/dist/enrich/providers/youtube.d.ts.map +1 -0
  138. package/dist/enrich/providers/youtube.js +43 -0
  139. package/dist/enrich/providers/youtube.js.map +1 -0
  140. package/dist/enrich/rate-limiting.d.ts +118 -0
  141. package/dist/enrich/rate-limiting.d.ts.map +1 -0
  142. package/dist/enrich/rate-limiting.js +258 -0
  143. package/dist/enrich/rate-limiting.js.map +1 -0
  144. package/dist/index.d.ts +688 -0
  145. package/dist/index.d.ts.map +1 -0
  146. package/dist/index.js +1729 -0
  147. package/dist/index.js.map +1 -0
  148. package/dist/ingest/dedup-merge.d.ts +82 -0
  149. package/dist/ingest/dedup-merge.d.ts.map +1 -0
  150. package/dist/ingest/dedup-merge.js +262 -0
  151. package/dist/ingest/dedup-merge.js.map +1 -0
  152. package/dist/ingest/ingest-csv.d.ts +62 -0
  153. package/dist/ingest/ingest-csv.d.ts.map +1 -0
  154. package/dist/ingest/ingest-csv.js +300 -0
  155. package/dist/ingest/ingest-csv.js.map +1 -0
  156. package/dist/ingest/ingest-db.d.ts +64 -0
  157. package/dist/ingest/ingest-db.d.ts.map +1 -0
  158. package/dist/ingest/ingest-db.js +172 -0
  159. package/dist/ingest/ingest-db.js.map +1 -0
  160. package/dist/ingest/link-replies-and-tapbacks.d.ts +53 -0
  161. package/dist/ingest/link-replies-and-tapbacks.d.ts.map +1 -0
  162. package/dist/ingest/link-replies-and-tapbacks.js +381 -0
  163. package/dist/ingest/link-replies-and-tapbacks.js.map +1 -0
  164. package/dist/normalize/date-converters.d.ts +45 -0
  165. package/dist/normalize/date-converters.d.ts.map +1 -0
  166. package/dist/normalize/date-converters.js +166 -0
  167. package/dist/normalize/date-converters.js.map +1 -0
  168. package/dist/normalize/path-validator.d.ts +65 -0
  169. package/dist/normalize/path-validator.d.ts.map +1 -0
  170. package/dist/normalize/path-validator.js +221 -0
  171. package/dist/normalize/path-validator.js.map +1 -0
  172. package/dist/normalize/validate-normalized.d.ts +45 -0
  173. package/dist/normalize/validate-normalized.d.ts.map +1 -0
  174. package/dist/normalize/validate-normalized.js +144 -0
  175. package/dist/normalize/validate-normalized.js.map +1 -0
  176. package/dist/render/embeds-blockquotes.d.ts +84 -0
  177. package/dist/render/embeds-blockquotes.d.ts.map +1 -0
  178. package/dist/render/embeds-blockquotes.js +204 -0
  179. package/dist/render/embeds-blockquotes.js.map +1 -0
  180. package/dist/render/grouping.d.ts +78 -0
  181. package/dist/render/grouping.d.ts.map +1 -0
  182. package/dist/render/grouping.js +134 -0
  183. package/dist/render/grouping.js.map +1 -0
  184. package/dist/render/index.d.ts +47 -0
  185. package/dist/render/index.d.ts.map +1 -0
  186. package/dist/render/index.js +245 -0
  187. package/dist/render/index.js.map +1 -0
  188. package/dist/render/reply-rendering.d.ts +88 -0
  189. package/dist/render/reply-rendering.d.ts.map +1 -0
  190. package/dist/render/reply-rendering.js +196 -0
  191. package/dist/render/reply-rendering.js.map +1 -0
  192. package/dist/schema/message.d.ts +125 -0
  193. package/dist/schema/message.d.ts.map +1 -0
  194. package/dist/schema/message.js +331 -0
  195. package/dist/schema/message.js.map +1 -0
  196. package/dist/utils/delta-detection.d.ts +107 -0
  197. package/dist/utils/delta-detection.d.ts.map +1 -0
  198. package/dist/utils/delta-detection.js +199 -0
  199. package/dist/utils/delta-detection.js.map +1 -0
  200. package/dist/utils/enrichment-merge.d.ts +135 -0
  201. package/dist/utils/enrichment-merge.d.ts.map +1 -0
  202. package/dist/utils/enrichment-merge.js +280 -0
  203. package/dist/utils/enrichment-merge.js.map +1 -0
  204. package/dist/utils/human.d.ts +15 -0
  205. package/dist/utils/human.d.ts.map +1 -0
  206. package/dist/utils/human.js +27 -0
  207. package/dist/utils/human.js.map +1 -0
  208. package/dist/utils/incremental-state.d.ts +133 -0
  209. package/dist/utils/incremental-state.d.ts.map +1 -0
  210. package/dist/utils/incremental-state.js +237 -0
  211. package/dist/utils/incremental-state.js.map +1 -0
  212. package/dist/utils/logger.d.ts +40 -0
  213. package/dist/utils/logger.d.ts.map +1 -0
  214. package/dist/utils/logger.js +176 -0
  215. package/dist/utils/logger.js.map +1 -0
  216. package/package.json +165 -0
@@ -0,0 +1,218 @@
1
+ /**
2
+ * Render Markdown Command
3
+ *
4
+ * Generate Obsidian-compatible markdown timeline files.
5
+ * CLI-T04: Implement Render Command
6
+ */
7
+ import { humanError, humanInfo, humanWarn } from '#utils/human';
8
+ import { applyLogLevel, cliLogger, logEvent } from '../utils.js';
9
+ /**
10
+ * Execute the render-markdown command logic
11
+ */
12
+ export async function executeRenderMarkdown(options, globalOptions) {
13
+ const { input, output, startDate, endDate, groupByTime, nestedReplies, maxNestingDepth, } = options;
14
+ const { verbose, quiet } = globalOptions;
15
+ applyLogLevel(verbose, quiet);
16
+ logEvent('render-start', {
17
+ command: 'render-markdown',
18
+ phase: 'start',
19
+ options: {
20
+ input,
21
+ output,
22
+ startDate,
23
+ endDate,
24
+ groupByTime,
25
+ nestedReplies,
26
+ maxNestingDepth,
27
+ },
28
+ });
29
+ // CLI-T04-AC01: Date filtering validation
30
+ const fs = await import('node:fs');
31
+ if (!fs.existsSync(input)) {
32
+ humanError(`❌ Input file not found: ${input}`);
33
+ process.exit(1);
34
+ }
35
+ let startDateObj = null;
36
+ let endDateObj = null;
37
+ if (startDate) {
38
+ const start = new Date(startDate);
39
+ if (Number.isNaN(start.getTime())) {
40
+ humanError(`❌ Invalid start date: ${startDate} (use YYYY-MM-DD format)`);
41
+ process.exit(1);
42
+ }
43
+ startDateObj = start;
44
+ }
45
+ if (endDate) {
46
+ const end = new Date(endDate);
47
+ if (Number.isNaN(end.getTime())) {
48
+ humanError(`❌ Invalid end date: ${endDate} (use YYYY-MM-DD format)`);
49
+ process.exit(1);
50
+ }
51
+ // Set to end of day
52
+ end.setHours(23, 59, 59, 999);
53
+ endDateObj = end;
54
+ }
55
+ // CLI-T04-AC03: Validate max nesting depth
56
+ const maxNestingDepthNum = Number.parseInt(maxNestingDepth, 10);
57
+ if (Number.isNaN(maxNestingDepthNum) || maxNestingDepthNum < 1) {
58
+ humanError('❌ --max-nesting-depth must be a positive number');
59
+ process.exit(1);
60
+ }
61
+ if (verbose) {
62
+ humanInfo(`📄 Input: ${input}`);
63
+ humanInfo(`📁 Output directory: ${output}`);
64
+ if (startDateObj) {
65
+ humanInfo(`📅 Start date: ${startDate}`);
66
+ }
67
+ if (endDateObj) {
68
+ humanInfo(`📅 End date: ${endDate}`);
69
+ }
70
+ humanInfo(`⏱️ Group by time: ${groupByTime}`);
71
+ humanInfo(`⬅️ Nested replies: ${nestedReplies}`);
72
+ humanInfo(`📊 Max nesting depth: ${maxNestingDepthNum}`);
73
+ }
74
+ // Load input messages
75
+ const content = fs.readFileSync(input, 'utf-8');
76
+ const data = JSON.parse(content);
77
+ let messages = Array.isArray(data) ? data : data.messages || [];
78
+ if (verbose) {
79
+ humanInfo(`✓ Loaded ${messages.length.toLocaleString()} messages`);
80
+ }
81
+ // Filter by date range if specified
82
+ if (startDateObj || endDateObj) {
83
+ const filtered = messages.filter((msg) => {
84
+ const msgDate = new Date(msg.date);
85
+ if (startDateObj && msgDate < startDateObj)
86
+ return false;
87
+ if (endDateObj && msgDate > endDateObj)
88
+ return false;
89
+ return true;
90
+ });
91
+ humanInfo(`📊 Filtered to ${filtered.length.toLocaleString()} messages in date range`);
92
+ logEvent('render-filtered', {
93
+ command: 'render-markdown',
94
+ phase: 'progress',
95
+ metrics: { filtered: filtered.length, original: messages.length },
96
+ options: {
97
+ startDate: startDateObj ? startDateObj.toISOString() : undefined,
98
+ endDate: endDateObj ? endDateObj.toISOString() : undefined,
99
+ },
100
+ });
101
+ messages = filtered;
102
+ }
103
+ // Import render functions
104
+ const { renderMessages } = await import('../../render/index.js');
105
+ // Render messages to markdown
106
+ const rendered = renderMessages(messages);
107
+ if (rendered.size === 0) {
108
+ humanWarn('⚠️ No messages to render');
109
+ process.exit(0);
110
+ }
111
+ // CLI-T04-AC04: Create output directory if doesn't exist
112
+ const path = await import('node:path');
113
+ const outputDir = path.resolve(output || './timeline');
114
+ if (!fs.existsSync(outputDir)) {
115
+ fs.mkdirSync(outputDir, { recursive: true });
116
+ if (verbose) {
117
+ cliLogger.info('Created output directory', { outputDir });
118
+ }
119
+ }
120
+ // Write markdown files
121
+ let filesWritten = 0;
122
+ const dates = Array.from(rendered.keys()).sort();
123
+ for (const date of dates) {
124
+ const markdown = rendered.get(date);
125
+ if (!markdown)
126
+ continue;
127
+ const filename = `${date}.md`;
128
+ const filepath = path.join(outputDir, filename);
129
+ fs.writeFileSync(filepath, markdown, 'utf-8');
130
+ filesWritten++;
131
+ if (verbose) {
132
+ humanInfo(`✓ Wrote ${filename}`);
133
+ logEvent('render-file-written', {
134
+ command: 'render-markdown',
135
+ phase: 'progress',
136
+ metrics: { filesWritten },
137
+ context: { filename, filepath },
138
+ });
139
+ }
140
+ }
141
+ // CLI-T04-AC05: Summary output
142
+ humanInfo(`\n✅ Rendered ${filesWritten} markdown file(s)`);
143
+ humanInfo(`✓ Wrote ${filesWritten.toLocaleString()} markdown file${filesWritten === 1 ? '' : 's'} to ${outputDir}`);
144
+ // Message summary
145
+ const textMessages = messages.filter((m) => m.messageKind === 'text').length;
146
+ const mediaMessages = messages.filter((m) => m.messageKind === 'media').length;
147
+ const tapbacks = messages.filter((m) => m.messageKind === 'tapback').length;
148
+ humanInfo('\n📊 Message Summary:');
149
+ humanInfo(` Total: ${messages.length.toLocaleString()}`);
150
+ humanInfo(` Text: ${textMessages.toLocaleString()}`);
151
+ humanInfo(` Media: ${mediaMessages.toLocaleString()}`);
152
+ humanInfo(` Tapbacks: ${tapbacks.toLocaleString()}`);
153
+ logEvent('render-summary', {
154
+ command: 'render-markdown',
155
+ phase: 'summary',
156
+ metrics: {
157
+ filesWritten,
158
+ totalMessages: messages.length,
159
+ textMessages,
160
+ mediaMessages,
161
+ tapbacks,
162
+ },
163
+ options: {
164
+ outputDir,
165
+ groupByTime,
166
+ nestedReplies,
167
+ maxNestingDepth: maxNestingDepthNum,
168
+ },
169
+ exitCode: 0,
170
+ });
171
+ }
172
+ /**
173
+ * Register the render-markdown command with Commander
174
+ */
175
+ export function registerRenderMarkdownCommand(program, getGlobalOptions) {
176
+ program
177
+ .command('render-markdown')
178
+ .description('Generate Obsidian-compatible markdown timeline files')
179
+ .requiredOption('-i, --input <path>', 'input enriched JSON file')
180
+ .option('-o, --output <dir>', 'output directory for markdown files', './timeline')
181
+ .option('--start-date <date>', 'render messages from this date (YYYY-MM-DD)')
182
+ .option('--end-date <date>', 'render messages until this date (YYYY-MM-DD)')
183
+ .option('--group-by-time', 'group messages by time-of-day (Morning/Afternoon/Evening)', true)
184
+ .option('--nested-replies', 'render replies as nested blockquotes', true)
185
+ .option('--max-nesting-depth <n>', 'maximum nesting depth for replies (default 10)', '10')
186
+ .action(async (options) => {
187
+ try {
188
+ await executeRenderMarkdown(options, getGlobalOptions());
189
+ process.exit(0);
190
+ }
191
+ catch (error) {
192
+ humanError('❌ Failed to render markdown:', error instanceof Error ? error.message : String(error));
193
+ if (getGlobalOptions().verbose && error instanceof Error) {
194
+ humanError(error.stack);
195
+ }
196
+ logEvent('render-error', {
197
+ command: 'render-markdown',
198
+ phase: 'error',
199
+ error: {
200
+ type: error instanceof Error ? error.name : 'Unknown',
201
+ message: error instanceof Error ? error.message : String(error),
202
+ ...(error instanceof Error && error.stack
203
+ ? { stack: error.stack }
204
+ : {}),
205
+ },
206
+ options: {
207
+ output: options.output,
208
+ groupByTime: options.groupByTime,
209
+ nestedReplies: options.nestedReplies,
210
+ maxNestingDepth: options.maxNestingDepth,
211
+ },
212
+ exitCode: 2,
213
+ });
214
+ process.exit(2);
215
+ }
216
+ });
217
+ }
218
+ //# sourceMappingURL=render-markdown.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render-markdown.js","sourceRoot":"","sources":["../../../src/cli/commands/render-markdown.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Stats Command
3
+ *
4
+ * Show statistics for message file.
5
+ * CLI-T05-AC02: stats command to show message counts by type
6
+ */
7
+ import type { Command } from 'commander';
8
+ import type { GlobalOptions, StatsOptions } from '../types.js';
9
+ /**
10
+ * Execute the stats command logic
11
+ */
12
+ export declare function executeStats(options: StatsOptions, globalOptions: GlobalOptions): Promise<void>;
13
+ /**
14
+ * Register the stats command with Commander
15
+ */
16
+ export declare function registerStatsCommand(program: Command, getGlobalOptions: () => GlobalOptions): void;
17
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/stats.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAG9D;;GAEG;AACH,wBAAsB,YAAY,CACjC,OAAO,EAAE,YAAY,EACrB,aAAa,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CA8If;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,MAAM,aAAa,GACnC,IAAI,CAkCN"}
@@ -0,0 +1,175 @@
1
+ /**
2
+ * Stats Command
3
+ *
4
+ * Show statistics for message file.
5
+ * CLI-T05-AC02: stats command to show message counts by type
6
+ */
7
+ import { humanError, humanInfo } from '#utils/human';
8
+ import { applyLogLevel, logEvent } from '../utils.js';
9
+ /**
10
+ * Execute the stats command logic
11
+ */
12
+ export async function executeStats(options, globalOptions) {
13
+ const { input } = options;
14
+ const verbose = globalOptions.verbose || options.verbose || false;
15
+ applyLogLevel(verbose, globalOptions.quiet);
16
+ logEvent('stats-start', {
17
+ command: 'stats',
18
+ phase: 'start',
19
+ options: { input },
20
+ });
21
+ const fs = await import('node:fs');
22
+ // Validate input file exists
23
+ if (!fs.existsSync(input)) {
24
+ humanError(`❌ Input file not found: ${input}`);
25
+ process.exit(1);
26
+ }
27
+ // Load and parse JSON
28
+ const content = fs.readFileSync(input, 'utf-8');
29
+ let data;
30
+ try {
31
+ data = JSON.parse(content);
32
+ }
33
+ catch {
34
+ humanError(`❌ Invalid JSON: ${input}`);
35
+ process.exit(1);
36
+ }
37
+ // Extract messages
38
+ const messages = Array.isArray(data)
39
+ ? data
40
+ : data.messages || [];
41
+ // Count by messageKind
42
+ const stats = {
43
+ total: messages.length,
44
+ text: 0,
45
+ media: 0,
46
+ tapback: 0,
47
+ notification: 0,
48
+ withMedia: 0,
49
+ withEnrichment: 0,
50
+ dateRange: { min: null, max: null },
51
+ };
52
+ const senders = new Set();
53
+ let totalEnrichments = 0;
54
+ messages.forEach((msg) => {
55
+ if (msg.messageKind === 'text')
56
+ stats.text++;
57
+ if (msg.messageKind === 'media')
58
+ stats.media++;
59
+ if (msg.messageKind === 'tapback')
60
+ stats.tapback++;
61
+ if (msg.messageKind === 'notification')
62
+ stats.notification++;
63
+ if (msg.media) {
64
+ stats.withMedia++;
65
+ if (msg.media.enrichment && Array.isArray(msg.media.enrichment)) {
66
+ stats.withEnrichment++;
67
+ totalEnrichments += msg.media.enrichment.length;
68
+ }
69
+ }
70
+ const sender = msg.handle ?? (msg.isFromMe ? 'Me' : 'Unknown');
71
+ senders.add(sender);
72
+ if (msg.date) {
73
+ if (!stats.dateRange.min || msg.date < stats.dateRange.min) {
74
+ stats.dateRange.min = msg.date;
75
+ }
76
+ if (!stats.dateRange.max || msg.date > stats.dateRange.max) {
77
+ stats.dateRange.max = msg.date;
78
+ }
79
+ }
80
+ });
81
+ // Output summary
82
+ humanInfo('📊 Message Statistics');
83
+ humanInfo(`\n Total messages: ${stats.total.toLocaleString()}`);
84
+ humanInfo('\n Message Types:');
85
+ humanInfo(` Text: ${stats.text}`);
86
+ humanInfo(` Media: ${stats.media}`);
87
+ humanInfo(` Tapbacks: ${stats.tapback}`);
88
+ humanInfo(` Notifications: ${stats.notification}`);
89
+ humanInfo('\n Enrichment:');
90
+ humanInfo(` Messages with media: ${stats.withMedia}`);
91
+ humanInfo(` Messages with enrichment: ${stats.withEnrichment}`);
92
+ if (stats.withEnrichment > 0) {
93
+ humanInfo(` Total enrichments: ${totalEnrichments}`);
94
+ humanInfo(` Avg enrichments per message: ${(totalEnrichments / stats.withEnrichment).toFixed(2)}`);
95
+ }
96
+ humanInfo('\n Date Range:');
97
+ if (stats.dateRange.min && stats.dateRange.max) {
98
+ humanInfo(` From: ${stats.dateRange.min}`);
99
+ humanInfo(` To: ${stats.dateRange.max}`);
100
+ const minDate = new Date(stats.dateRange.min);
101
+ const maxDate = new Date(stats.dateRange.max);
102
+ const days = Math.floor((maxDate.getTime() - minDate.getTime()) / (1000 * 60 * 60 * 24));
103
+ humanInfo(` Duration: ${days + 1} days`);
104
+ }
105
+ else {
106
+ humanInfo(' None');
107
+ }
108
+ if (verbose) {
109
+ humanInfo(`\n Participants: ${senders.size}`);
110
+ if (senders.size > 0 && senders.size <= 20) {
111
+ Array.from(senders)
112
+ .sort()
113
+ .forEach((sender) => {
114
+ const count = messages.filter((m) => {
115
+ const msgSender = m.handle ?? (m.isFromMe ? 'Me' : 'Unknown');
116
+ return msgSender === sender;
117
+ }).length;
118
+ humanInfo(` ${sender}: ${count}`);
119
+ });
120
+ }
121
+ }
122
+ logEvent('stats-summary', {
123
+ command: 'stats',
124
+ phase: 'summary',
125
+ metrics: {
126
+ total: stats.total,
127
+ text: stats.text,
128
+ media: stats.media,
129
+ tapback: stats.tapback,
130
+ notification: stats.notification,
131
+ withMedia: stats.withMedia,
132
+ withEnrichment: stats.withEnrichment,
133
+ participants: senders.size,
134
+ },
135
+ options: { input, verbose },
136
+ exitCode: 0,
137
+ });
138
+ }
139
+ /**
140
+ * Register the stats command with Commander
141
+ */
142
+ export function registerStatsCommand(program, getGlobalOptions) {
143
+ program
144
+ .command('stats')
145
+ .description('Show statistics for message file')
146
+ .requiredOption('-i, --input <path>', 'path to message JSON file')
147
+ .option('-v, --verbose', 'show detailed statistics', false)
148
+ .action(async (options) => {
149
+ try {
150
+ await executeStats(options, getGlobalOptions());
151
+ process.exit(0);
152
+ }
153
+ catch (error) {
154
+ humanError('❌ Stats failed:', error instanceof Error ? error.message : String(error));
155
+ if (getGlobalOptions().verbose && error instanceof Error) {
156
+ humanError(error.stack);
157
+ }
158
+ logEvent('stats-error', {
159
+ command: 'stats',
160
+ phase: 'error',
161
+ error: {
162
+ type: error instanceof Error ? error.name : 'Unknown',
163
+ message: error instanceof Error ? error.message : String(error),
164
+ ...(error instanceof Error && error.stack
165
+ ? { stack: error.stack }
166
+ : {}),
167
+ },
168
+ options: { input: options.input, verbose: options.verbose },
169
+ exitCode: 2,
170
+ });
171
+ process.exit(2);
172
+ }
173
+ });
174
+ }
175
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../../../src/cli/commands/stats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Validate Command
3
+ *
4
+ * Validate JSON file against message schema.
5
+ * CLI-T05-AC01: validate command to check JSON against schema
6
+ */
7
+ import type { Command } from 'commander';
8
+ import type { GlobalOptions, ValidateOptions } from '../types.js';
9
+ /**
10
+ * Execute the validate command logic
11
+ */
12
+ export declare function executeValidate(options: ValidateOptions, globalOptions: GlobalOptions): Promise<void>;
13
+ /**
14
+ * Register the validate command with Commander
15
+ */
16
+ export declare function registerValidateCommand(program: Command, getGlobalOptions: () => GlobalOptions): void;
17
+ //# sourceMappingURL=validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,aAAa,CAAA;AAGjE;;GAEG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,eAAe,EACxB,aAAa,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CAsHf;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACtC,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,MAAM,aAAa,GACnC,IAAI,CAgCN"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Validate Command
3
+ *
4
+ * Validate JSON file against message schema.
5
+ * CLI-T05-AC01: validate command to check JSON against schema
6
+ */
7
+ import { humanError, humanInfo } from '#utils/human';
8
+ import { applyLogLevel, logEvent } from '../utils.js';
9
+ /**
10
+ * Execute the validate command logic
11
+ */
12
+ export async function executeValidate(options, globalOptions) {
13
+ const { input, quiet } = options;
14
+ const { verbose } = globalOptions;
15
+ applyLogLevel(verbose, globalOptions.quiet);
16
+ const fs = await import('node:fs');
17
+ // Validate input file exists
18
+ if (!fs.existsSync(input)) {
19
+ humanError(`❌ Input file not found: ${input}`);
20
+ process.exit(1);
21
+ }
22
+ // Load and parse JSON
23
+ const content = fs.readFileSync(input, 'utf-8');
24
+ let data;
25
+ try {
26
+ data = JSON.parse(content);
27
+ }
28
+ catch (e) {
29
+ humanError(`❌ Invalid JSON: ${input}`);
30
+ humanError(` ${e instanceof Error ? e.message : String(e)}`);
31
+ process.exit(1);
32
+ }
33
+ // Validate schema
34
+ const { MessageSchema } = await import('../../schema/message.js');
35
+ const messages = Array.isArray(data)
36
+ ? data
37
+ : data.messages || [];
38
+ let validCount = 0;
39
+ const errors = [];
40
+ for (let i = 0; i < messages.length; i++) {
41
+ const result = MessageSchema.safeParse(messages[i]);
42
+ if (result.success) {
43
+ validCount++;
44
+ }
45
+ else {
46
+ result.error.errors.forEach((err) => {
47
+ errors.push({
48
+ index: i,
49
+ path: err.path.join('.'),
50
+ message: err.message,
51
+ });
52
+ });
53
+ }
54
+ }
55
+ // Output results
56
+ if (!quiet) {
57
+ humanInfo('📊 Validation Results:');
58
+ humanInfo(` Valid: ${validCount}/${messages.length}`);
59
+ }
60
+ logEvent('validate-results', {
61
+ command: 'validate',
62
+ phase: 'progress',
63
+ metrics: {
64
+ valid: validCount,
65
+ total: messages.length,
66
+ errors: errors.length,
67
+ },
68
+ options: { quiet },
69
+ });
70
+ if (errors.length === 0) {
71
+ humanInfo(`✅ All ${messages.length} messages are valid`);
72
+ logEvent('validate-summary', {
73
+ command: 'validate',
74
+ phase: 'summary',
75
+ metrics: { valid: validCount, total: messages.length },
76
+ exitCode: 0,
77
+ });
78
+ process.exit(0);
79
+ }
80
+ else {
81
+ humanError(`❌ ${errors.length} validation error(s) found`);
82
+ logEvent('validate-error-summary', {
83
+ command: 'validate',
84
+ phase: 'error',
85
+ metrics: {
86
+ valid: validCount,
87
+ total: messages.length,
88
+ errors: errors.length,
89
+ },
90
+ exitCode: 1,
91
+ });
92
+ if (!quiet) {
93
+ const grouped = new Map();
94
+ errors.forEach((err) => {
95
+ if (!grouped.has(err.index))
96
+ grouped.set(err.index, []);
97
+ grouped.get(err.index).push({ path: err.path, message: err.message });
98
+ });
99
+ let shown = 0;
100
+ grouped.forEach((errs, index) => {
101
+ if (shown < 10) {
102
+ humanError(`\n Message ${index}:`);
103
+ errs.forEach((err) => {
104
+ humanError(` ${err.path || 'root'}: ${err.message}`);
105
+ shown++;
106
+ if (shown >= 10)
107
+ return;
108
+ });
109
+ }
110
+ });
111
+ if (shown < errors.length) {
112
+ humanError(`\n ... and ${errors.length - shown} more errors`);
113
+ }
114
+ }
115
+ process.exit(1);
116
+ }
117
+ }
118
+ /**
119
+ * Register the validate command with Commander
120
+ */
121
+ export function registerValidateCommand(program, getGlobalOptions) {
122
+ program
123
+ .command('validate')
124
+ .description('Validate JSON file against message schema')
125
+ .requiredOption('-i, --input <path>', 'path to JSON file to validate')
126
+ .option('-q, --quiet', 'suppress detailed error messages', false)
127
+ .action(async (options) => {
128
+ try {
129
+ await executeValidate(options, getGlobalOptions());
130
+ }
131
+ catch (error) {
132
+ humanError('❌ Validation failed:', error instanceof Error ? error.message : String(error));
133
+ if (getGlobalOptions().verbose && error instanceof Error) {
134
+ humanError(error.stack);
135
+ }
136
+ logEvent('validate-runtime-error', {
137
+ command: 'validate',
138
+ phase: 'error',
139
+ error: {
140
+ type: error instanceof Error ? error.name : 'Unknown',
141
+ message: error instanceof Error ? error.message : String(error),
142
+ ...(error instanceof Error && error.stack
143
+ ? { stack: error.stack }
144
+ : {}),
145
+ },
146
+ exitCode: 2,
147
+ });
148
+ process.exit(2);
149
+ }
150
+ });
151
+ }
152
+ //# sourceMappingURL=validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validate.js","sourceRoot":"","sources":["../../../src/cli/commands/validate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * iMessage Timeline CLI
4
+ *
5
+ * Main CLI entry point that registers all commands and handles execution.
6
+ * This is the modular replacement for the monolithic cli.ts file.
7
+ */
8
+ import { Command } from 'commander';
9
+ /**
10
+ * Creates and configures the main CLI program with all commands.
11
+ */
12
+ export declare function createProgram(): Command;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAMH,OAAO,EAAE,OAAO,EAAuB,MAAM,WAAW,CAAA;AA2BxD;;GAEG;AACH,wBAAgB,aAAa,IAAI,OAAO,CA8FvC"}