@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.
- package/CHANGELOG.md +1 -0
- package/LICENSE +21 -0
- package/README.md +1535 -0
- package/dist/bin/index.js +5121 -0
- package/dist/cli/commands/clean.d.ts +17 -0
- package/dist/cli/commands/clean.d.ts.map +1 -0
- package/dist/cli/commands/clean.js +142 -0
- package/dist/cli/commands/clean.js.map +1 -0
- package/dist/cli/commands/doctor.d.ts +17 -0
- package/dist/cli/commands/doctor.d.ts.map +1 -0
- package/dist/cli/commands/doctor.js +202 -0
- package/dist/cli/commands/doctor.js.map +1 -0
- package/dist/cli/commands/enrich-ai.d.ts +17 -0
- package/dist/cli/commands/enrich-ai.d.ts.map +1 -0
- package/dist/cli/commands/enrich-ai.js +371 -0
- package/dist/cli/commands/enrich-ai.js.map +1 -0
- package/dist/cli/commands/index.d.ts +16 -0
- package/dist/cli/commands/index.d.ts.map +1 -0
- package/dist/cli/commands/index.js +16 -0
- package/dist/cli/commands/index.js.map +1 -0
- package/dist/cli/commands/ingest-csv.d.ts +17 -0
- package/dist/cli/commands/ingest-csv.d.ts.map +1 -0
- package/dist/cli/commands/ingest-csv.js +138 -0
- package/dist/cli/commands/ingest-csv.js.map +1 -0
- package/dist/cli/commands/ingest-db.d.ts +17 -0
- package/dist/cli/commands/ingest-db.d.ts.map +1 -0
- package/dist/cli/commands/ingest-db.js +159 -0
- package/dist/cli/commands/ingest-db.js.map +1 -0
- package/dist/cli/commands/init.d.ts +17 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +110 -0
- package/dist/cli/commands/init.js.map +1 -0
- package/dist/cli/commands/normalize-link.d.ts +16 -0
- package/dist/cli/commands/normalize-link.d.ts.map +1 -0
- package/dist/cli/commands/normalize-link.js +144 -0
- package/dist/cli/commands/normalize-link.js.map +1 -0
- package/dist/cli/commands/render-markdown.d.ts +17 -0
- package/dist/cli/commands/render-markdown.d.ts.map +1 -0
- package/dist/cli/commands/render-markdown.js +218 -0
- package/dist/cli/commands/render-markdown.js.map +1 -0
- package/dist/cli/commands/stats.d.ts +17 -0
- package/dist/cli/commands/stats.d.ts.map +1 -0
- package/dist/cli/commands/stats.js +175 -0
- package/dist/cli/commands/stats.js.map +1 -0
- package/dist/cli/commands/validate.d.ts +17 -0
- package/dist/cli/commands/validate.d.ts.map +1 -0
- package/dist/cli/commands/validate.js +152 -0
- package/dist/cli/commands/validate.js.map +1 -0
- package/dist/cli/index.d.ts +13 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +121 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/types.d.ts +93 -0
- package/dist/cli/types.d.ts.map +1 -0
- package/dist/cli/types.js +7 -0
- package/dist/cli/types.js.map +1 -0
- package/dist/cli/utils.d.ts +29 -0
- package/dist/cli/utils.d.ts.map +1 -0
- package/dist/cli/utils.js +53 -0
- package/dist/cli/utils.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1805 -0
- package/dist/config/generator.d.ts +90 -0
- package/dist/config/generator.d.ts.map +1 -0
- package/dist/config/generator.js +320 -0
- package/dist/config/generator.js.map +1 -0
- package/dist/config/loader.d.ts +107 -0
- package/dist/config/loader.d.ts.map +1 -0
- package/dist/config/loader.js +251 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/schema.d.ts +107 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +169 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/enrich/audio-transcription.d.ts +77 -0
- package/dist/enrich/audio-transcription.d.ts.map +1 -0
- package/dist/enrich/audio-transcription.js +370 -0
- package/dist/enrich/audio-transcription.js.map +1 -0
- package/dist/enrich/checkpoint.d.ts +137 -0
- package/dist/enrich/checkpoint.d.ts.map +1 -0
- package/dist/enrich/checkpoint.js +205 -0
- package/dist/enrich/checkpoint.js.map +1 -0
- package/dist/enrich/idempotency.d.ts +90 -0
- package/dist/enrich/idempotency.d.ts.map +1 -0
- package/dist/enrich/idempotency.js +188 -0
- package/dist/enrich/idempotency.js.map +1 -0
- package/dist/enrich/image-analysis.d.ts +62 -0
- package/dist/enrich/image-analysis.d.ts.map +1 -0
- package/dist/enrich/image-analysis.js +264 -0
- package/dist/enrich/image-analysis.js.map +1 -0
- package/dist/enrich/index.d.ts +60 -0
- package/dist/enrich/index.d.ts.map +1 -0
- package/dist/enrich/index.js +74 -0
- package/dist/enrich/index.js.map +1 -0
- package/dist/enrich/link-enrichment.d.ts +37 -0
- package/dist/enrich/link-enrichment.d.ts.map +1 -0
- package/dist/enrich/link-enrichment.js +202 -0
- package/dist/enrich/link-enrichment.js.map +1 -0
- package/dist/enrich/pdf-video-handling.d.ts +49 -0
- package/dist/enrich/pdf-video-handling.d.ts.map +1 -0
- package/dist/enrich/pdf-video-handling.js +325 -0
- package/dist/enrich/pdf-video-handling.js.map +1 -0
- package/dist/enrich/progress-tracker.d.ts +120 -0
- package/dist/enrich/progress-tracker.d.ts.map +1 -0
- package/dist/enrich/progress-tracker.js +220 -0
- package/dist/enrich/progress-tracker.js.map +1 -0
- package/dist/enrich/providers/firecrawl.d.ts +18 -0
- package/dist/enrich/providers/firecrawl.d.ts.map +1 -0
- package/dist/enrich/providers/firecrawl.js +48 -0
- package/dist/enrich/providers/firecrawl.js.map +1 -0
- package/dist/enrich/providers/generic.d.ts +16 -0
- package/dist/enrich/providers/generic.d.ts.map +1 -0
- package/dist/enrich/providers/generic.js +36 -0
- package/dist/enrich/providers/generic.js.map +1 -0
- package/dist/enrich/providers/index.d.ts +14 -0
- package/dist/enrich/providers/index.d.ts.map +1 -0
- package/dist/enrich/providers/index.js +13 -0
- package/dist/enrich/providers/index.js.map +1 -0
- package/dist/enrich/providers/instagram.d.ts +16 -0
- package/dist/enrich/providers/instagram.d.ts.map +1 -0
- package/dist/enrich/providers/instagram.js +43 -0
- package/dist/enrich/providers/instagram.js.map +1 -0
- package/dist/enrich/providers/spotify.d.ts +16 -0
- package/dist/enrich/providers/spotify.d.ts.map +1 -0
- package/dist/enrich/providers/spotify.js +45 -0
- package/dist/enrich/providers/spotify.js.map +1 -0
- package/dist/enrich/providers/twitter.d.ts +16 -0
- package/dist/enrich/providers/twitter.d.ts.map +1 -0
- package/dist/enrich/providers/twitter.js +43 -0
- package/dist/enrich/providers/twitter.js.map +1 -0
- package/dist/enrich/providers/types.d.ts +47 -0
- package/dist/enrich/providers/types.d.ts.map +1 -0
- package/dist/enrich/providers/types.js +15 -0
- package/dist/enrich/providers/types.js.map +1 -0
- package/dist/enrich/providers/youtube.d.ts +16 -0
- package/dist/enrich/providers/youtube.d.ts.map +1 -0
- package/dist/enrich/providers/youtube.js +43 -0
- package/dist/enrich/providers/youtube.js.map +1 -0
- package/dist/enrich/rate-limiting.d.ts +118 -0
- package/dist/enrich/rate-limiting.d.ts.map +1 -0
- package/dist/enrich/rate-limiting.js +258 -0
- package/dist/enrich/rate-limiting.js.map +1 -0
- package/dist/index.d.ts +688 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1729 -0
- package/dist/index.js.map +1 -0
- package/dist/ingest/dedup-merge.d.ts +82 -0
- package/dist/ingest/dedup-merge.d.ts.map +1 -0
- package/dist/ingest/dedup-merge.js +262 -0
- package/dist/ingest/dedup-merge.js.map +1 -0
- package/dist/ingest/ingest-csv.d.ts +62 -0
- package/dist/ingest/ingest-csv.d.ts.map +1 -0
- package/dist/ingest/ingest-csv.js +300 -0
- package/dist/ingest/ingest-csv.js.map +1 -0
- package/dist/ingest/ingest-db.d.ts +64 -0
- package/dist/ingest/ingest-db.d.ts.map +1 -0
- package/dist/ingest/ingest-db.js +172 -0
- package/dist/ingest/ingest-db.js.map +1 -0
- package/dist/ingest/link-replies-and-tapbacks.d.ts +53 -0
- package/dist/ingest/link-replies-and-tapbacks.d.ts.map +1 -0
- package/dist/ingest/link-replies-and-tapbacks.js +381 -0
- package/dist/ingest/link-replies-and-tapbacks.js.map +1 -0
- package/dist/normalize/date-converters.d.ts +45 -0
- package/dist/normalize/date-converters.d.ts.map +1 -0
- package/dist/normalize/date-converters.js +166 -0
- package/dist/normalize/date-converters.js.map +1 -0
- package/dist/normalize/path-validator.d.ts +65 -0
- package/dist/normalize/path-validator.d.ts.map +1 -0
- package/dist/normalize/path-validator.js +221 -0
- package/dist/normalize/path-validator.js.map +1 -0
- package/dist/normalize/validate-normalized.d.ts +45 -0
- package/dist/normalize/validate-normalized.d.ts.map +1 -0
- package/dist/normalize/validate-normalized.js +144 -0
- package/dist/normalize/validate-normalized.js.map +1 -0
- package/dist/render/embeds-blockquotes.d.ts +84 -0
- package/dist/render/embeds-blockquotes.d.ts.map +1 -0
- package/dist/render/embeds-blockquotes.js +204 -0
- package/dist/render/embeds-blockquotes.js.map +1 -0
- package/dist/render/grouping.d.ts +78 -0
- package/dist/render/grouping.d.ts.map +1 -0
- package/dist/render/grouping.js +134 -0
- package/dist/render/grouping.js.map +1 -0
- package/dist/render/index.d.ts +47 -0
- package/dist/render/index.d.ts.map +1 -0
- package/dist/render/index.js +245 -0
- package/dist/render/index.js.map +1 -0
- package/dist/render/reply-rendering.d.ts +88 -0
- package/dist/render/reply-rendering.d.ts.map +1 -0
- package/dist/render/reply-rendering.js +196 -0
- package/dist/render/reply-rendering.js.map +1 -0
- package/dist/schema/message.d.ts +125 -0
- package/dist/schema/message.d.ts.map +1 -0
- package/dist/schema/message.js +331 -0
- package/dist/schema/message.js.map +1 -0
- package/dist/utils/delta-detection.d.ts +107 -0
- package/dist/utils/delta-detection.d.ts.map +1 -0
- package/dist/utils/delta-detection.js +199 -0
- package/dist/utils/delta-detection.js.map +1 -0
- package/dist/utils/enrichment-merge.d.ts +135 -0
- package/dist/utils/enrichment-merge.d.ts.map +1 -0
- package/dist/utils/enrichment-merge.js +280 -0
- package/dist/utils/enrichment-merge.js.map +1 -0
- package/dist/utils/human.d.ts +15 -0
- package/dist/utils/human.d.ts.map +1 -0
- package/dist/utils/human.js +27 -0
- package/dist/utils/human.js.map +1 -0
- package/dist/utils/incremental-state.d.ts +133 -0
- package/dist/utils/incremental-state.d.ts.map +1 -0
- package/dist/utils/incremental-state.js +237 -0
- package/dist/utils/incremental-state.js.map +1 -0
- package/dist/utils/logger.d.ts +40 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js +176 -0
- package/dist/utils/logger.js.map +1 -0
- package/package.json +165 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ingest DB Command
|
|
3
|
+
*
|
|
4
|
+
* Import messages from macOS Messages.app database export (JSON).
|
|
5
|
+
* CLI-T02-AC02: ingest-db command with database path and contact filtering
|
|
6
|
+
*/
|
|
7
|
+
import { humanError, humanInfo } from '#utils/human';
|
|
8
|
+
import { applyLogLevel, cliLogger, logEvent } from '../utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute the ingest-db command logic
|
|
11
|
+
*/
|
|
12
|
+
export async function executeIngestDB(options, globalOptions) {
|
|
13
|
+
const { input, output, attachments, contact } = options;
|
|
14
|
+
const { verbose, quiet } = globalOptions;
|
|
15
|
+
applyLogLevel(verbose, quiet);
|
|
16
|
+
logEvent('ingest-start', {
|
|
17
|
+
command: 'ingest-db',
|
|
18
|
+
phase: 'start',
|
|
19
|
+
options: {
|
|
20
|
+
input,
|
|
21
|
+
output,
|
|
22
|
+
attachmentsCount: attachments?.length,
|
|
23
|
+
contact,
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
// CLI-T02-AC04: Input file validation with clear error messages
|
|
27
|
+
const fs = await import('node:fs');
|
|
28
|
+
if (!fs.existsSync(input)) {
|
|
29
|
+
humanError(`ā Input JSON file not found: ${input}`);
|
|
30
|
+
humanError('\nPlease check:');
|
|
31
|
+
humanError(' ⢠File path is correct');
|
|
32
|
+
humanError(' ⢠File exists and is readable');
|
|
33
|
+
process.exit(1);
|
|
34
|
+
}
|
|
35
|
+
// CLI-T02-AC03: Attachment root validation (check directories exist)
|
|
36
|
+
const attachmentRoots = [];
|
|
37
|
+
if (attachments && attachments.length > 0) {
|
|
38
|
+
for (const dir of attachments) {
|
|
39
|
+
if (!fs.existsSync(dir)) {
|
|
40
|
+
humanError(`ā Attachment directory not found: ${dir}`);
|
|
41
|
+
process.exit(1);
|
|
42
|
+
}
|
|
43
|
+
if (!fs.statSync(dir).isDirectory()) {
|
|
44
|
+
humanError(`ā Not a directory: ${dir}`);
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
attachmentRoots.push(dir);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
// Default: ~/Library/Messages/Attachments
|
|
52
|
+
const os = await import('node:os');
|
|
53
|
+
const path = await import('node:path');
|
|
54
|
+
const defaultRoot = path.join(os.homedir(), 'Library', 'Messages', 'Attachments');
|
|
55
|
+
if (fs.existsSync(defaultRoot)) {
|
|
56
|
+
attachmentRoots.push(defaultRoot);
|
|
57
|
+
if (verbose) {
|
|
58
|
+
humanInfo(`Using default attachment root: ${defaultRoot}`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// CLI-T02-AC02: ingest-db command with database path and contact filtering
|
|
63
|
+
const { splitDBMessage } = await import('../../ingest/ingest-db.js');
|
|
64
|
+
const { createExportEnvelope, validateMessages } = await import('../../ingest/ingest-csv.js');
|
|
65
|
+
if (verbose) {
|
|
66
|
+
cliLogger.info('Reading DB export', {
|
|
67
|
+
input,
|
|
68
|
+
attachmentRoots,
|
|
69
|
+
contact,
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
// Read and parse DB export JSON
|
|
73
|
+
const content = fs.readFileSync(input, 'utf-8');
|
|
74
|
+
const dbMessages = JSON.parse(content);
|
|
75
|
+
if (!Array.isArray(dbMessages)) {
|
|
76
|
+
humanError(`ā Expected JSON array of DB messages, got: ${typeof dbMessages}`);
|
|
77
|
+
process.exit(1);
|
|
78
|
+
}
|
|
79
|
+
// Filter by contact if specified
|
|
80
|
+
let filteredMessages = dbMessages;
|
|
81
|
+
if (contact) {
|
|
82
|
+
filteredMessages = dbMessages.filter((m) => m.handle === contact);
|
|
83
|
+
humanInfo(`ā Filtered to ${filteredMessages.length} messages from ${contact}`);
|
|
84
|
+
}
|
|
85
|
+
// Split DB messages into Message objects
|
|
86
|
+
const messages = [];
|
|
87
|
+
filteredMessages.forEach((dbMsg, index) => {
|
|
88
|
+
const split = splitDBMessage(dbMsg, index + 1, { attachmentRoots });
|
|
89
|
+
messages.push(...split);
|
|
90
|
+
});
|
|
91
|
+
// CLI-T02-AC05: Progress output
|
|
92
|
+
humanInfo(`ā Parsed ${messages.length.toLocaleString()} messages from DB export`);
|
|
93
|
+
// Validate messages before writing
|
|
94
|
+
const validation = validateMessages(messages);
|
|
95
|
+
if (!validation.valid) {
|
|
96
|
+
humanError(`ā ${validation.errors.length} messages failed validation`);
|
|
97
|
+
if (verbose) {
|
|
98
|
+
validation.errors.slice(0, 5).forEach((err) => {
|
|
99
|
+
humanError(` Message ${err.index}:`, err.issues);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
process.exit(1);
|
|
103
|
+
}
|
|
104
|
+
// Write export envelope
|
|
105
|
+
const envelope = createExportEnvelope(messages);
|
|
106
|
+
fs.writeFileSync(output, JSON.stringify(envelope, null, 2), 'utf-8');
|
|
107
|
+
humanInfo(`ā Wrote ${messages.length.toLocaleString()} messages to ${output}`);
|
|
108
|
+
humanInfo('\nš Summary:');
|
|
109
|
+
const dbText = messages.filter((m) => m.messageKind === 'text').length;
|
|
110
|
+
const dbMedia = messages.filter((m) => m.messageKind === 'media').length;
|
|
111
|
+
humanInfo(` Text: ${dbText}`);
|
|
112
|
+
humanInfo(` Media: ${dbMedia}`);
|
|
113
|
+
logEvent('ingest-summary', {
|
|
114
|
+
command: 'ingest-db',
|
|
115
|
+
phase: 'summary',
|
|
116
|
+
metrics: { total: messages.length, text: dbText, media: dbMedia },
|
|
117
|
+
options: { output, contact },
|
|
118
|
+
exitCode: 0,
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Register the ingest-db command with Commander
|
|
123
|
+
*/
|
|
124
|
+
export function registerIngestDBCommand(program, getGlobalOptions) {
|
|
125
|
+
program
|
|
126
|
+
.command('ingest-db')
|
|
127
|
+
.description('Import messages from macOS Messages.app database export (JSON)')
|
|
128
|
+
.requiredOption('-i, --input <path>', 'path to JSON file with DB messages')
|
|
129
|
+
.option('-o, --output <path>', 'output JSON file path', './messages.db.ingested.json')
|
|
130
|
+
.option('-a, --attachments <dir...>', 'attachment root directories')
|
|
131
|
+
.option('--contact <handle>', 'filter to specific contact handle')
|
|
132
|
+
.action(async (options) => {
|
|
133
|
+
try {
|
|
134
|
+
await executeIngestDB(options, getGlobalOptions());
|
|
135
|
+
process.exit(0);
|
|
136
|
+
}
|
|
137
|
+
catch (error) {
|
|
138
|
+
humanError('ā Failed to ingest DB export:', error instanceof Error ? error.message : String(error));
|
|
139
|
+
if (getGlobalOptions().verbose && error instanceof Error) {
|
|
140
|
+
humanError(error.stack);
|
|
141
|
+
}
|
|
142
|
+
logEvent('ingest-error', {
|
|
143
|
+
command: 'ingest-db',
|
|
144
|
+
phase: 'error',
|
|
145
|
+
error: {
|
|
146
|
+
type: error instanceof Error ? error.name : 'Unknown',
|
|
147
|
+
message: error instanceof Error ? error.message : String(error),
|
|
148
|
+
...(error instanceof Error && error.stack
|
|
149
|
+
? { stack: error.stack }
|
|
150
|
+
: {}),
|
|
151
|
+
},
|
|
152
|
+
options: { output: options.output, contact: options.contact },
|
|
153
|
+
exitCode: 2,
|
|
154
|
+
});
|
|
155
|
+
process.exit(2);
|
|
156
|
+
}
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=ingest-db.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ingest-db.js","sourceRoot":"","sources":["../../../src/cli/commands/ingest-db.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Command
|
|
3
|
+
*
|
|
4
|
+
* Generate starter configuration file.
|
|
5
|
+
* CONFIG-T03: Implement config generator
|
|
6
|
+
*/
|
|
7
|
+
import type { Command } from 'commander';
|
|
8
|
+
import type { GlobalOptions, InitOptions } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute the init command logic
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeInit(options: InitOptions, globalOptions: GlobalOptions): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Register the init command with Commander
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerInitCommand(program: Command, getGlobalOptions: () => GlobalOptions): void;
|
|
17
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,KAAK,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAG7D;;GAEG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,WAAW,EACpB,aAAa,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CAkEf;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAClC,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,MAAM,aAAa,GACnC,IAAI,CA6CN"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Init Command
|
|
3
|
+
*
|
|
4
|
+
* Generate starter configuration file.
|
|
5
|
+
* CONFIG-T03: Implement config generator
|
|
6
|
+
*/
|
|
7
|
+
import { humanError, humanInfo } from '#utils/human';
|
|
8
|
+
import { applyLogLevel, logEvent } from '../utils.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute the init command logic
|
|
11
|
+
*/
|
|
12
|
+
export async function executeInit(options, globalOptions) {
|
|
13
|
+
const { format, force, output } = options;
|
|
14
|
+
const { verbose, quiet } = globalOptions;
|
|
15
|
+
applyLogLevel(verbose, quiet);
|
|
16
|
+
// Validate format
|
|
17
|
+
if (format !== 'json' && format !== 'yaml') {
|
|
18
|
+
humanError(`ā Invalid format: ${format}`);
|
|
19
|
+
humanError('Supported formats: json, yaml');
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
// Lazy import to avoid circular dependencies
|
|
23
|
+
const { generateConfigFile, getDefaultConfigPath, configFileExists } = await import('../../config/generator.js');
|
|
24
|
+
// Determine output path
|
|
25
|
+
const filePath = output || getDefaultConfigPath(format);
|
|
26
|
+
// CONFIG-T03-AC04: Check for existing file and prompt if needed
|
|
27
|
+
const exists = await configFileExists(filePath);
|
|
28
|
+
if (exists && !force) {
|
|
29
|
+
humanError(`ā Config file already exists: ${filePath}`);
|
|
30
|
+
humanError('\nOptions:');
|
|
31
|
+
humanError(' ⢠Use --force to overwrite');
|
|
32
|
+
humanError(' ⢠Use --output to specify different path');
|
|
33
|
+
humanError(' ⢠Manually remove the existing file');
|
|
34
|
+
process.exit(1);
|
|
35
|
+
}
|
|
36
|
+
// CONFIG-T03-AC01, AC02, AC03: Generate config file
|
|
37
|
+
const result = await generateConfigFile({
|
|
38
|
+
filePath,
|
|
39
|
+
format,
|
|
40
|
+
force,
|
|
41
|
+
});
|
|
42
|
+
if (result.success) {
|
|
43
|
+
humanInfo(result.message);
|
|
44
|
+
humanInfo('\nš Next steps:');
|
|
45
|
+
humanInfo(` 1. Edit ${filePath} to add your API keys`);
|
|
46
|
+
humanInfo(' 2. Set GEMINI_API_KEY environment variable');
|
|
47
|
+
humanInfo(' 3. (Optional) Set FIRECRAWL_API_KEY for enhanced link scraping');
|
|
48
|
+
humanInfo('\nš” See inline comments in the config file for details');
|
|
49
|
+
logEvent('init-summary', {
|
|
50
|
+
command: 'init',
|
|
51
|
+
phase: 'summary',
|
|
52
|
+
options: { format, filePath, force },
|
|
53
|
+
message: result.message,
|
|
54
|
+
exitCode: 0,
|
|
55
|
+
});
|
|
56
|
+
process.exit(0);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
humanError(`ā ${result.message}`);
|
|
60
|
+
logEvent('init-error', {
|
|
61
|
+
command: 'init',
|
|
62
|
+
phase: 'error',
|
|
63
|
+
options: { format, filePath, force },
|
|
64
|
+
message: result.message,
|
|
65
|
+
exitCode: 1,
|
|
66
|
+
});
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Register the init command with Commander
|
|
72
|
+
*/
|
|
73
|
+
export function registerInitCommand(program, getGlobalOptions) {
|
|
74
|
+
program
|
|
75
|
+
.command('init')
|
|
76
|
+
.description('Generate starter configuration file')
|
|
77
|
+
.option('-f, --format <type>', 'config file format (json|yaml)', 'yaml')
|
|
78
|
+
.option('--force', 'overwrite existing config file without prompting', false)
|
|
79
|
+
.option('-o, --output <path>', 'output file path (default: auto-detected from format)')
|
|
80
|
+
.action(async (options) => {
|
|
81
|
+
try {
|
|
82
|
+
await executeInit(options, getGlobalOptions());
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
humanError('ā Failed to generate config:', error instanceof Error ? error.message : String(error));
|
|
86
|
+
if (getGlobalOptions().verbose && error instanceof Error) {
|
|
87
|
+
humanError(error.stack);
|
|
88
|
+
}
|
|
89
|
+
logEvent('init-runtime-error', {
|
|
90
|
+
command: 'init',
|
|
91
|
+
phase: 'error',
|
|
92
|
+
error: {
|
|
93
|
+
type: error instanceof Error ? error.name : 'Unknown',
|
|
94
|
+
message: error instanceof Error ? error.message : String(error),
|
|
95
|
+
...(error instanceof Error && error.stack
|
|
96
|
+
? { stack: error.stack }
|
|
97
|
+
: {}),
|
|
98
|
+
},
|
|
99
|
+
options: {
|
|
100
|
+
format: options.format,
|
|
101
|
+
output: options.output,
|
|
102
|
+
force: options.force,
|
|
103
|
+
},
|
|
104
|
+
exitCode: 2,
|
|
105
|
+
});
|
|
106
|
+
process.exit(2);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=init.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize Link Command
|
|
3
|
+
*
|
|
4
|
+
* Deduplicate and link messages from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import type { Command } from 'commander';
|
|
7
|
+
import type { GlobalOptions, NormalizeLinkOptions } from '../types.js';
|
|
8
|
+
/**
|
|
9
|
+
* Execute the normalize-link command logic
|
|
10
|
+
*/
|
|
11
|
+
export declare function executeNormalizeLink(options: NormalizeLinkOptions, globalOptions: GlobalOptions): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Register the normalize-link command with Commander
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerNormalizeLinkCommand(program: Command, getGlobalOptions: () => GlobalOptions): void;
|
|
16
|
+
//# sourceMappingURL=normalize-link.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-link.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/normalize-link.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAGtE;;GAEG;AACH,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,oBAAoB,EAC7B,aAAa,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CAoIf;AAED;;GAEG;AACH,wBAAgB,4BAA4B,CAC3C,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,MAAM,aAAa,GACnC,IAAI,CAwCN"}
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize Link Command
|
|
3
|
+
*
|
|
4
|
+
* Deduplicate and link messages from multiple sources.
|
|
5
|
+
*/
|
|
6
|
+
import { humanError, humanInfo } from '#utils/human';
|
|
7
|
+
import { applyLogLevel, cliLogger, logEvent } from '../utils.js';
|
|
8
|
+
/**
|
|
9
|
+
* Execute the normalize-link command logic
|
|
10
|
+
*/
|
|
11
|
+
export async function executeNormalizeLink(options, globalOptions) {
|
|
12
|
+
const { input, output } = options;
|
|
13
|
+
const { verbose, quiet } = globalOptions;
|
|
14
|
+
applyLogLevel(verbose, quiet);
|
|
15
|
+
// Validate inputs
|
|
16
|
+
const fs = await import('node:fs');
|
|
17
|
+
const inputFiles = Array.isArray(input) ? input : [input];
|
|
18
|
+
for (const file of inputFiles) {
|
|
19
|
+
if (!fs.existsSync(file)) {
|
|
20
|
+
humanError(`ā Input file not found: ${file}`);
|
|
21
|
+
process.exit(1);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
if (verbose) {
|
|
25
|
+
cliLogger.info('Start normalize-link', {
|
|
26
|
+
files: inputFiles.length,
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
// Load input files
|
|
30
|
+
const allMessages = [];
|
|
31
|
+
for (const file of inputFiles) {
|
|
32
|
+
const content = fs.readFileSync(file, 'utf-8');
|
|
33
|
+
const data = JSON.parse(content);
|
|
34
|
+
const messages = Array.isArray(data) ? data : data.messages || [];
|
|
35
|
+
allMessages.push(...messages);
|
|
36
|
+
humanInfo(`ā Loaded ${messages.length} messages from ${file}`);
|
|
37
|
+
}
|
|
38
|
+
// Import normalize pipeline
|
|
39
|
+
const { linkRepliesToParents } = await import('../../ingest/link-replies-and-tapbacks.js');
|
|
40
|
+
const { dedupAndMerge } = await import('../../ingest/dedup-merge.js');
|
|
41
|
+
const { validateNormalizedMessages } = await import('../../normalize/validate-normalized.js');
|
|
42
|
+
if (verbose) {
|
|
43
|
+
cliLogger.info('Total messages before linking', {
|
|
44
|
+
count: allMessages.length,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
// Step 1: Link replies and tapbacks
|
|
48
|
+
const linkedResult = linkRepliesToParents(allMessages, {
|
|
49
|
+
trackAmbiguous: true,
|
|
50
|
+
});
|
|
51
|
+
const linkedMessages = Array.isArray(linkedResult)
|
|
52
|
+
? linkedResult
|
|
53
|
+
: linkedResult.messages;
|
|
54
|
+
if (verbose && !Array.isArray(linkedResult) && linkedResult.ambiguousLinks) {
|
|
55
|
+
cliLogger.warn('Ambiguous reply/tapback links detected', {
|
|
56
|
+
count: linkedResult.ambiguousLinks.length,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
// Step 2: Deduplicate and merge (if multiple sources)
|
|
60
|
+
let normalizedMessages = linkedMessages;
|
|
61
|
+
if (inputFiles.length > 1) {
|
|
62
|
+
// Split messages by source for dedup-merge
|
|
63
|
+
const csvMessages = linkedMessages.filter((m) => m.exportVersion?.includes('csv') || !m.rowid);
|
|
64
|
+
const dbMessages = linkedMessages.filter((m) => m.rowid !== undefined);
|
|
65
|
+
const mergeResult = dedupAndMerge(csvMessages, dbMessages);
|
|
66
|
+
normalizedMessages = mergeResult.messages;
|
|
67
|
+
if (verbose) {
|
|
68
|
+
cliLogger.info('Merge statistics', {
|
|
69
|
+
input: mergeResult.stats.csvCount + mergeResult.stats.dbCount,
|
|
70
|
+
output: mergeResult.stats.outputCount,
|
|
71
|
+
exactMatches: mergeResult.stats.exactMatches,
|
|
72
|
+
contentMatches: mergeResult.stats.contentMatches,
|
|
73
|
+
noMatches: mergeResult.stats.noMatches,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
// Step 3: Validate normalized messages
|
|
78
|
+
const validatedMessages = validateNormalizedMessages(normalizedMessages);
|
|
79
|
+
// Write output envelope
|
|
80
|
+
const { createExportEnvelope } = await import('../../ingest/ingest-csv.js');
|
|
81
|
+
const envelope = createExportEnvelope(validatedMessages);
|
|
82
|
+
envelope.source = 'merged';
|
|
83
|
+
fs.writeFileSync(output, JSON.stringify(envelope, null, 2), 'utf-8');
|
|
84
|
+
humanInfo(`\nā
Normalized ${validatedMessages.length.toLocaleString()} messages`);
|
|
85
|
+
humanInfo(`ā Wrote to ${output}`);
|
|
86
|
+
humanInfo('\nš Final Summary:');
|
|
87
|
+
const nText = validatedMessages.filter((m) => m.messageKind === 'text').length;
|
|
88
|
+
const nMedia = validatedMessages.filter((m) => m.messageKind === 'media').length;
|
|
89
|
+
const nTapbacks = validatedMessages.filter((m) => m.messageKind === 'tapback').length;
|
|
90
|
+
const nNotifs = validatedMessages.filter((m) => m.messageKind === 'notification').length;
|
|
91
|
+
humanInfo(` Text: ${nText}`);
|
|
92
|
+
humanInfo(` Media: ${nMedia}`);
|
|
93
|
+
humanInfo(` Tapbacks: ${nTapbacks}`);
|
|
94
|
+
humanInfo(` Notifications: ${nNotifs}`);
|
|
95
|
+
logEvent('normalize-summary', {
|
|
96
|
+
command: 'normalize-link',
|
|
97
|
+
phase: 'summary',
|
|
98
|
+
metrics: {
|
|
99
|
+
total: validatedMessages.length,
|
|
100
|
+
text: nText,
|
|
101
|
+
media: nMedia,
|
|
102
|
+
tapbacks: nTapbacks,
|
|
103
|
+
notifications: nNotifs,
|
|
104
|
+
},
|
|
105
|
+
options: { output },
|
|
106
|
+
exitCode: 0,
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Register the normalize-link command with Commander
|
|
111
|
+
*/
|
|
112
|
+
export function registerNormalizeLinkCommand(program, getGlobalOptions) {
|
|
113
|
+
program
|
|
114
|
+
.command('normalize-link')
|
|
115
|
+
.description('Deduplicate and link messages from multiple sources')
|
|
116
|
+
.requiredOption('-i, --input <files...>', 'input JSON files (CSV, DB, or both)')
|
|
117
|
+
.option('-o, --output <path>', 'output JSON file path', './messages.normalized.json')
|
|
118
|
+
.action(async (options) => {
|
|
119
|
+
try {
|
|
120
|
+
await executeNormalizeLink(options, getGlobalOptions());
|
|
121
|
+
process.exit(0);
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
humanError('ā Failed to normalize-link:', error instanceof Error ? error.message : String(error));
|
|
125
|
+
if (getGlobalOptions().verbose && error instanceof Error) {
|
|
126
|
+
humanError(error.stack);
|
|
127
|
+
}
|
|
128
|
+
logEvent('normalize-error', {
|
|
129
|
+
command: 'normalize-link',
|
|
130
|
+
phase: 'error',
|
|
131
|
+
error: {
|
|
132
|
+
type: error instanceof Error ? error.name : 'Unknown',
|
|
133
|
+
message: error instanceof Error ? error.message : String(error),
|
|
134
|
+
...(error instanceof Error && error.stack
|
|
135
|
+
? { stack: error.stack }
|
|
136
|
+
: {}),
|
|
137
|
+
},
|
|
138
|
+
exitCode: 2,
|
|
139
|
+
});
|
|
140
|
+
process.exit(2);
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=normalize-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"normalize-link.js","sourceRoot":"","sources":["../../../src/cli/commands/normalize-link.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Render Markdown Command
|
|
3
|
+
*
|
|
4
|
+
* Generate Obsidian-compatible markdown timeline files.
|
|
5
|
+
* CLI-T04: Implement Render Command
|
|
6
|
+
*/
|
|
7
|
+
import type { Command } from 'commander';
|
|
8
|
+
import type { GlobalOptions, RenderMarkdownOptions } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Execute the render-markdown command logic
|
|
11
|
+
*/
|
|
12
|
+
export declare function executeRenderMarkdown(options: RenderMarkdownOptions, globalOptions: GlobalOptions): Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Register the render-markdown command with Commander
|
|
15
|
+
*/
|
|
16
|
+
export declare function registerRenderMarkdownCommand(program: Command, getGlobalOptions: () => GlobalOptions): void;
|
|
17
|
+
//# sourceMappingURL=render-markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"render-markdown.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/render-markdown.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AAGxC,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAA;AAGvE;;GAEG;AACH,wBAAsB,qBAAqB,CAC1C,OAAO,EAAE,qBAAqB,EAC9B,aAAa,EAAE,aAAa,GAC1B,OAAO,CAAC,IAAI,CAAC,CAiMf;AAED;;GAEG;AACH,wBAAgB,6BAA6B,CAC5C,OAAO,EAAE,OAAO,EAChB,gBAAgB,EAAE,MAAM,aAAa,GACnC,IAAI,CA2DN"}
|