mnueron 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,359 @@
1
+ /**
2
+ * v0.2.6 — Claude Cowork local import.
3
+ *
4
+ * Cowork ("local agent mode") is the desktop variant of Claude that the
5
+ * non-developer "Cowork" mode runs on. Under the hood it's the Claude Code
6
+ * runtime, which writes one JSONL transcript per session into a folder
7
+ * whose name encodes the session's cwd.
8
+ *
9
+ * On disk these transcripts live under one of several roots depending on
10
+ * how the Claude desktop app was installed and the OS:
11
+ *
12
+ * - ~/.claude/projects/<encoded-cwd>/<sessionUuid>.jsonl
13
+ * (regular Claude Code or non-Store Claude Desktop installs)
14
+ *
15
+ * - %LOCALAPPDATA%\Packages\Claude_<sfx>\LocalCache\Roaming\Claude\
16
+ * local-agent-mode-sessions\**\.claude\projects\
17
+ * <encoded-cwd>\<sessionUuid>.jsonl
18
+ * OR more directly
19
+ * %LOCALAPPDATA%\Packages\Claude_<sfx>\LocalCache\Roaming\Claude\
20
+ * local-agent-mode-sessions\**\<sessionUuid>.jsonl
21
+ * (Microsoft Store install — Store sandboxes %APPDATA% writes into
22
+ * the package folder)
23
+ *
24
+ * To stay robust to wherever Cowork actually writes, we recursively walk
25
+ * a list of candidate roots looking for *.jsonl files. Each file is then
26
+ * sniffed: it counts as a Cowork transcript when the cwd recorded in the
27
+ * file contains `local-agent-mode-sessions`.
28
+ *
29
+ * Each session becomes ONE memory containing the flattened transcript.
30
+ * The mnueron chunker (LocalProvider.save/bulkSave) automatically splits
31
+ * long transcripts per-turn for granular recall.
32
+ *
33
+ * Triggered from the CLI: `mnueron import --claude-cowork`
34
+ */
35
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
36
+ import { homedir, platform } from 'node:os';
37
+ import { join } from 'node:path';
38
+ const MAX_TRANSCRIPT_CHARS = 10_000_000; // chunker splits per-turn; cap just prevents runaway
39
+ const MAX_WALK_DEPTH = 10; // safety cap on recursion
40
+ const COWORK_MARKER = 'local-agent-mode-sessions';
41
+ /**
42
+ * Roots to walk on this platform.
43
+ *
44
+ * Order matters only for the `projectsDir` "primary" hint. We still walk
45
+ * every existing root and merge the sessions found.
46
+ */
47
+ function candidateRoots() {
48
+ const home = homedir();
49
+ const roots = [];
50
+ // Universal: ~/.claude/projects/
51
+ roots.push(join(home, '.claude', 'projects'));
52
+ switch (platform()) {
53
+ case 'win32': {
54
+ const appdata = process.env.APPDATA ?? join(home, 'AppData', 'Roaming');
55
+ const localApp = process.env.LOCALAPPDATA ?? join(home, 'AppData', 'Local');
56
+ // Non-Store install location for the cowork agent root.
57
+ roots.push(join(appdata, 'Claude', 'local-agent-mode-sessions'));
58
+ roots.push(join(appdata, 'AnthropicClaude', 'local-agent-mode-sessions'));
59
+ // Microsoft Store sandboxed location. The package suffix isn't stable,
60
+ // so we glob the Packages directory for any Claude*\LocalCache\Roaming
61
+ // \Claude\local-agent-mode-sessions folder.
62
+ const packagesDir = join(localApp, 'Packages');
63
+ if (existsSync(packagesDir)) {
64
+ try {
65
+ for (const name of readdirSync(packagesDir)) {
66
+ if (!name.toLowerCase().startsWith('claude') &&
67
+ !name.toLowerCase().startsWith('anthropic')) {
68
+ continue;
69
+ }
70
+ roots.push(join(packagesDir, name, 'LocalCache', 'Roaming', 'Claude', 'local-agent-mode-sessions'));
71
+ }
72
+ }
73
+ catch {
74
+ /* ignore unreadable Packages dir */
75
+ }
76
+ }
77
+ break;
78
+ }
79
+ case 'darwin':
80
+ // ~/Library/Application Support/Claude/local-agent-mode-sessions/
81
+ roots.push(join(home, 'Library', 'Application Support', 'Claude', 'local-agent-mode-sessions'), join(home, 'Library', 'Application Support', 'AnthropicClaude', 'local-agent-mode-sessions'));
82
+ break;
83
+ case 'linux':
84
+ roots.push(join(home, '.config', 'Claude', 'local-agent-mode-sessions'), join(home, '.config', 'AnthropicClaude', 'local-agent-mode-sessions'));
85
+ break;
86
+ }
87
+ return roots;
88
+ }
89
+ /**
90
+ * Locate every Cowork session transcript reachable from this machine.
91
+ * Read-only — does not import anything.
92
+ */
93
+ export function probeClaudeCowork() {
94
+ const attempted = candidateRoots();
95
+ const scanned = [];
96
+ const sessions = [];
97
+ for (const root of attempted) {
98
+ if (!existsSync(root))
99
+ continue;
100
+ scanned.push(root);
101
+ walkForJsonl(root, 0, (filePath) => {
102
+ try {
103
+ const fileStat = statSync(filePath);
104
+ if (!fileStat.isFile() || fileStat.size < 50)
105
+ return;
106
+ const info = quickScan(filePath);
107
+ // Only keep files that look like cowork transcripts (cwd marker).
108
+ if (info.messageCount === 0)
109
+ return;
110
+ if (!info.cwd.includes(COWORK_MARKER))
111
+ return;
112
+ const base = filePath.split(/[\\/]/).pop() ?? '';
113
+ sessions.push({
114
+ sessionId: base.replace(/\.jsonl$/, ''),
115
+ filePath,
116
+ cwd: info.cwd,
117
+ title: info.title,
118
+ messageCount: info.messageCount,
119
+ mtimeMs: fileStat.mtimeMs,
120
+ sizeBytes: fileStat.size,
121
+ });
122
+ }
123
+ catch {
124
+ /* unreadable — skip */
125
+ }
126
+ });
127
+ }
128
+ // Dedup by sessionId — the same transcript can show up under multiple roots
129
+ // (e.g., a symlinked or sandboxed copy).
130
+ const dedup = new Map();
131
+ for (const s of sessions) {
132
+ const prev = dedup.get(s.sessionId);
133
+ if (!prev || s.mtimeMs > prev.mtimeMs)
134
+ dedup.set(s.sessionId, s);
135
+ }
136
+ const final = [...dedup.values()].sort((a, b) => b.mtimeMs - a.mtimeMs);
137
+ const out = {
138
+ found: final.length > 0,
139
+ projectsDir: scanned[0] ?? null,
140
+ scannedRoots: scanned,
141
+ pathsAttempted: attempted,
142
+ sessions: final,
143
+ hints: [],
144
+ };
145
+ if (final.length > 0) {
146
+ out.hints.push(`Found ${final.length} Cowork session(s) across ${scanned.length} root(s).`);
147
+ }
148
+ else if (scanned.length === 0) {
149
+ out.hints.push('None of the candidate Cowork roots existed on this machine.', 'On Windows the Microsoft Store install lives under', '%LOCALAPPDATA%\\Packages\\Claude_<sfx>\\LocalCache\\Roaming\\Claude\\local-agent-mode-sessions\\.', 'If you have a non-default install location, point us at it:', ' mnueron import --claude-cowork --dir <path>');
150
+ }
151
+ else {
152
+ out.hints.push(`Walked ${scanned.length} root(s) but found no Cowork session transcripts.`, 'A .jsonl file qualifies as Cowork when the cwd it records contains', `"${COWORK_MARKER}". Run a Cowork chat once and re-try.`);
153
+ }
154
+ return out;
155
+ }
156
+ /**
157
+ * Recursively walk `dir` up to MAX_WALK_DEPTH levels and call `onFile` for
158
+ * each `.jsonl` we find. Doesn't follow symlinks, swallows perm errors.
159
+ */
160
+ function walkForJsonl(dir, depth, onFile) {
161
+ if (depth > MAX_WALK_DEPTH)
162
+ return;
163
+ let entries;
164
+ try {
165
+ entries = readdirSync(dir);
166
+ }
167
+ catch {
168
+ return;
169
+ }
170
+ for (const name of entries) {
171
+ const p = join(dir, name);
172
+ let st;
173
+ try {
174
+ st = statSync(p);
175
+ }
176
+ catch {
177
+ continue;
178
+ }
179
+ if (st.isDirectory()) {
180
+ walkForJsonl(p, depth + 1, onFile);
181
+ }
182
+ else if (st.isFile() && name.endsWith('.jsonl')) {
183
+ onFile(p);
184
+ }
185
+ }
186
+ }
187
+ /**
188
+ * Pass over a transcript counting human-readable turns and grabbing the
189
+ * latest ai-title + cwd. Skips internal-state records.
190
+ */
191
+ function quickScan(filePath) {
192
+ const raw = readFileSync(filePath, 'utf8');
193
+ let title;
194
+ let cwd = '';
195
+ let messageCount = 0;
196
+ for (const line of raw.split('\n')) {
197
+ if (!line.trim())
198
+ continue;
199
+ let obj;
200
+ try {
201
+ obj = JSON.parse(line);
202
+ }
203
+ catch {
204
+ continue;
205
+ }
206
+ if (obj.type === 'user' || obj.type === 'assistant') {
207
+ messageCount++;
208
+ if (!cwd && typeof obj.cwd === 'string')
209
+ cwd = obj.cwd;
210
+ }
211
+ else if (obj.type === 'ai-title' && typeof obj.aiTitle === 'string') {
212
+ title = obj.aiTitle;
213
+ }
214
+ }
215
+ return { title, cwd, messageCount };
216
+ }
217
+ /**
218
+ * Convert one Cowork transcript file into a SaveMemoryInput. Returns an
219
+ * empty array if there are no human-readable turns.
220
+ */
221
+ export function importFromCoworkSession(filePath, namespace, sessionMeta) {
222
+ const raw = readFileSync(filePath, 'utf8');
223
+ const turns = [];
224
+ for (const line of raw.split('\n')) {
225
+ if (!line.trim())
226
+ continue;
227
+ let obj;
228
+ try {
229
+ obj = JSON.parse(line);
230
+ }
231
+ catch {
232
+ continue;
233
+ }
234
+ if (obj.type === 'user') {
235
+ const text = extractUserText(obj.message);
236
+ if (text)
237
+ turns.push({ role: 'user', text, ts: obj.timestamp });
238
+ }
239
+ else if (obj.type === 'assistant') {
240
+ const text = extractAssistantText(obj.message);
241
+ if (text)
242
+ turns.push({ role: 'assistant', text, ts: obj.timestamp });
243
+ }
244
+ }
245
+ if (turns.length === 0)
246
+ return [];
247
+ const parts = [];
248
+ const titleLine = sessionMeta.title
249
+ ? `# ${sessionMeta.title}`
250
+ : `# Cowork session ${sessionMeta.sessionId}`;
251
+ parts.push(titleLine);
252
+ if (turns[0]?.ts)
253
+ parts.push(`(${turns[0].ts})`);
254
+ parts.push('');
255
+ for (const t of turns) {
256
+ parts.push(`**${t.role === 'assistant' ? 'Claude' : 'User'}:** ${t.text}`);
257
+ parts.push('');
258
+ }
259
+ let content = parts.join('\n').trim();
260
+ if (content.length > MAX_TRANSCRIPT_CHARS) {
261
+ content = content.slice(0, MAX_TRANSCRIPT_CHARS) +
262
+ `\n\n[truncated — original ${content.length} chars]`;
263
+ }
264
+ return [{
265
+ content,
266
+ namespace,
267
+ source: 'claude-cowork',
268
+ source_ref: `cowork:${sessionMeta.sessionId}`,
269
+ tags: ['imported', 'claude-cowork'],
270
+ metadata: {
271
+ title: sessionMeta.title ?? null,
272
+ session_id: sessionMeta.sessionId,
273
+ cwd: sessionMeta.cwd,
274
+ message_count: turns.length,
275
+ first_timestamp: turns[0]?.ts ?? null,
276
+ last_timestamp: turns[turns.length - 1]?.ts ?? null,
277
+ },
278
+ }];
279
+ }
280
+ function extractUserText(message) {
281
+ if (!message)
282
+ return '';
283
+ if (typeof message.content === 'string')
284
+ return message.content.trim();
285
+ if (Array.isArray(message.content)) {
286
+ return message.content
287
+ .filter((b) => b?.type === 'text' && typeof b.text === 'string')
288
+ .map((b) => b.text)
289
+ .join('\n')
290
+ .trim();
291
+ }
292
+ return '';
293
+ }
294
+ function extractAssistantText(message) {
295
+ if (!message || !Array.isArray(message.content))
296
+ return '';
297
+ // Skip thinking blocks (internal reasoning) and tool_use blocks (mostly noise
298
+ // in memory). Keep only `text` blocks — these are what the human actually saw.
299
+ return message.content
300
+ .filter((b) => b?.type === 'text' && typeof b.text === 'string')
301
+ .map((b) => b.text)
302
+ .join('\n')
303
+ .trim();
304
+ }
305
+ /**
306
+ * Probe + import every Cowork session into mnueron. Idempotent via
307
+ * `source_ref` dedup — re-running just re-upserts.
308
+ */
309
+ export async function autoImport(provider, namespace, opts = {}) {
310
+ const probe = probeClaudeCowork();
311
+ if (!probe.found || probe.sessions.length === 0) {
312
+ throw new Error('No Cowork sessions found. ' +
313
+ 'Run Cowork at least once first, then try again.');
314
+ }
315
+ const sessions = opts.limit && opts.limit > 0
316
+ ? probe.sessions.slice(0, opts.limit)
317
+ : probe.sessions;
318
+ let parsed = 0;
319
+ let empty = 0;
320
+ let errors = 0;
321
+ let saved = 0;
322
+ const items = [];
323
+ for (const s of sessions) {
324
+ try {
325
+ const sessionItems = importFromCoworkSession(s.filePath, namespace, {
326
+ sessionId: s.sessionId,
327
+ title: s.title,
328
+ cwd: s.cwd,
329
+ });
330
+ if (sessionItems.length === 0) {
331
+ empty++;
332
+ continue;
333
+ }
334
+ items.push(...sessionItems);
335
+ parsed++;
336
+ }
337
+ catch {
338
+ errors++;
339
+ }
340
+ }
341
+ if (!opts.dryRun && items.length > 0) {
342
+ const result = await provider.bulkSave(items);
343
+ saved = result.saved;
344
+ errors += result.errors;
345
+ }
346
+ return {
347
+ totalSessions: probe.sessions.length,
348
+ parsed,
349
+ empty,
350
+ saved,
351
+ errors,
352
+ sessions: sessions.map((s) => ({
353
+ sessionId: s.sessionId,
354
+ title: s.title,
355
+ messageCount: s.messageCount,
356
+ })),
357
+ };
358
+ }
359
+ //# sourceMappingURL=claude_cowork.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude_cowork.js","sourceRoot":"","sources":["../../src/import/claude_cowork.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC1E,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAIjC,MAAM,oBAAoB,GAAG,UAAU,CAAC,CAAC,qDAAqD;AAC9F,MAAM,cAAc,GAAG,EAAE,CAAC,CAAY,0BAA0B;AAChE,MAAM,aAAa,GAAG,2BAA2B,CAAC;AAwBlD;;;;;GAKG;AACH,SAAS,cAAc;IACrB,MAAM,IAAI,GAAG,OAAO,EAAE,CAAC;IACvB,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,iCAAiC;IACjC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC,CAAC;IAE9C,QAAQ,QAAQ,EAAE,EAAE,CAAC;QACnB,KAAK,OAAO,CAAC,CAAC,CAAC;YACb,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;YACxE,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,YAAY,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;YAE5E,wDAAwD;YACxD,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,2BAA2B,CAAC,CAAC,CAAC;YACjE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAAC,CAAC;YAE1E,uEAAuE;YACvE,uEAAuE;YACvE,4CAA4C;YAC5C,MAAM,WAAW,GAAG,IAAI,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;YAC/C,IAAI,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC5B,IAAI,CAAC;oBACH,KAAK,MAAM,IAAI,IAAI,WAAW,CAAC,WAAW,CAAC,EAAE,CAAC;wBAC5C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;4BACxC,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;4BAChD,SAAS;wBACX,CAAC;wBACD,KAAK,CAAC,IAAI,CACR,IAAI,CACF,WAAW,EACX,IAAI,EACJ,YAAY,EACZ,SAAS,EACT,QAAQ,EACR,2BAA2B,CAC5B,CACF,CAAC;oBACJ,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC;oBACP,oCAAoC;gBACtC,CAAC;YACH,CAAC;YACD,MAAM;QACR,CAAC;QACD,KAAK,QAAQ;YACX,kEAAkE;YAClE,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,QAAQ,EAAE,2BAA2B,CAAC,EACnF,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,qBAAqB,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CAC7F,CAAC;YACF,MAAM;QACR,KAAK,OAAO;YACV,KAAK,CAAC,IAAI,CACR,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,2BAA2B,CAAC,EAC5D,IAAI,CAAC,IAAI,EAAE,SAAS,EAAE,iBAAiB,EAAE,2BAA2B,CAAC,CACtE,CAAC;YACF,MAAM;IACV,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,iBAAiB;IAC/B,MAAM,SAAS,GAAG,cAAc,EAAE,CAAC;IACnC,MAAM,OAAO,GAAa,EAAE,CAAC;IAC7B,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;QAC7B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,SAAS;QAChC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnB,YAAY,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE;YACjC,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBACpC,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,QAAQ,CAAC,IAAI,GAAG,EAAE;oBAAE,OAAO;gBACrD,MAAM,IAAI,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;gBACjC,kEAAkE;gBAClE,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC;oBAAE,OAAO;gBACpC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,aAAa,CAAC;oBAAE,OAAO;gBAC9C,MAAM,IAAI,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBACjD,QAAQ,CAAC,IAAI,CAAC;oBACZ,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;oBACvC,QAAQ;oBACR,GAAG,EAAE,IAAI,CAAC,GAAG;oBACb,KAAK,EAAE,IAAI,CAAC,KAAK;oBACjB,YAAY,EAAE,IAAI,CAAC,YAAY;oBAC/B,OAAO,EAAE,QAAQ,CAAC,OAAO;oBACzB,SAAS,EAAE,QAAQ,CAAC,IAAI;iBACzB,CAAC,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACP,uBAAuB;YACzB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,4EAA4E;IAC5E,yCAAyC;IACzC,MAAM,KAAK,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC/C,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO;YAAE,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IACnE,CAAC;IACD,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC;IAExE,MAAM,GAAG,GAAsB;QAC7B,KAAK,EAAE,KAAK,CAAC,MAAM,GAAG,CAAC;QACvB,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,IAAI;QAC/B,YAAY,EAAE,OAAO;QACrB,cAAc,EAAE,SAAS;QACzB,QAAQ,EAAE,KAAK;QACf,KAAK,EAAE,EAAE;KACV,CAAC;IAEF,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,KAAK,CAAC,MAAM,6BAA6B,OAAO,CAAC,MAAM,WAAW,CAAC,CAAC;IAC9F,CAAC;SAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,KAAK,CAAC,IAAI,CACZ,6DAA6D,EAC7D,oDAAoD,EACpD,mGAAmG,EACnG,6DAA6D,EAC7D,+CAA+C,CAChD,CAAC;IACJ,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,KAAK,CAAC,IAAI,CACZ,UAAU,OAAO,CAAC,MAAM,mDAAmD,EAC3E,oEAAoE,EACpE,IAAI,aAAa,uCAAuC,CACzD,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;;;GAGG;AACH,SAAS,YAAY,CACnB,GAAW,EACX,KAAa,EACb,MAAkC;IAElC,IAAI,KAAK,GAAG,cAAc;QAAE,OAAO;IACnC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO;IACT,CAAC;IACD,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC1B,IAAI,EAAE,CAAC;QACP,IAAI,CAAC;YACH,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;QACnB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC;YACrB,YAAY,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;QACrC,CAAC;aAAM,IAAI,EAAE,CAAC,MAAM,EAAE,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YAClD,MAAM,CAAC,CAAC,CAAC,CAAC;QACZ,CAAC;IACH,CAAC;AACH,CAAC;AAQD;;;GAGG;AACH,SAAS,SAAS,CAAC,QAAgB;IACjC,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,IAAI,KAAyB,CAAC;IAC9B,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,IAAI,YAAY,GAAG,CAAC,CAAC;IACrB,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACpD,YAAY,EAAE,CAAC;YACf,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ;gBAAE,GAAG,GAAG,GAAG,CAAC,GAAG,CAAC;QACzD,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,UAAU,IAAI,OAAO,GAAG,CAAC,OAAO,KAAK,QAAQ,EAAE,CAAC;YACtE,KAAK,GAAG,GAAG,CAAC,OAAO,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,CAAC;AACtC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,uBAAuB,CACrC,QAAgB,EAChB,SAAiB,EACjB,WAA+D;IAE/D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAqE,EAAE,CAAC;IAEnF,KAAK,MAAM,IAAI,IAAI,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;YAAE,SAAS;QAC3B,IAAI,GAAQ,CAAC;QACb,IAAI,CAAC;YACH,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC1C,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QAClE,CAAC;aAAM,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACpC,MAAM,IAAI,GAAG,oBAAoB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAC/C,IAAI,IAAI;gBAAE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,SAAS,EAAE,CAAC,CAAC;QACvE,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAElC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,SAAS,GAAG,WAAW,CAAC,KAAK;QACjC,CAAC,CAAC,KAAK,WAAW,CAAC,KAAK,EAAE;QAC1B,CAAC,CAAC,oBAAoB,WAAW,CAAC,SAAS,EAAE,CAAC;IAChD,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;IACtB,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,KAAK,WAAW,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;QAC3E,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IACD,IAAI,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;IACtC,IAAI,OAAO,CAAC,MAAM,GAAG,oBAAoB,EAAE,CAAC;QAC1C,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,oBAAoB,CAAC;YAC9C,6BAA6B,OAAO,CAAC,MAAM,SAAS,CAAC;IACzD,CAAC;IAED,OAAO,CAAC;YACN,OAAO;YACP,SAAS;YACT,MAAM,EAAE,eAAe;YACvB,UAAU,EAAE,UAAU,WAAW,CAAC,SAAS,EAAE;YAC7C,IAAI,EAAE,CAAC,UAAU,EAAE,eAAe,CAAC;YACnC,QAAQ,EAAE;gBACR,KAAK,EAAE,WAAW,CAAC,KAAK,IAAI,IAAI;gBAChC,UAAU,EAAE,WAAW,CAAC,SAAS;gBACjC,GAAG,EAAE,WAAW,CAAC,GAAG;gBACpB,aAAa,EAAE,KAAK,CAAC,MAAM;gBAC3B,eAAe,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI;gBACrC,cAAc,EAAE,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,EAAE,IAAI,IAAI;aACpD;SACF,CAAC,CAAC;AACL,CAAC;AAED,SAAS,eAAe,CAAC,OAAY;IACnC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,IAAI,OAAO,OAAO,CAAC,OAAO,KAAK,QAAQ;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;IACvE,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QACnC,OAAO,OAAO,CAAC,OAAO;aACnB,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;aACpE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAc,CAAC;aACjC,IAAI,CAAC,IAAI,CAAC;aACV,IAAI,EAAE,CAAC;IACZ,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,oBAAoB,CAAC,OAAY;IACxC,IAAI,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC;QAAE,OAAO,EAAE,CAAC;IAC3D,8EAA8E;IAC9E,+EAA+E;IAC/E,OAAO,OAAO,CAAC,OAAO;SACnB,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,CAAC,IAAI,KAAK,QAAQ,CAAC;SACpE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAc,CAAC;SACjC,IAAI,CAAC,IAAI,CAAC;SACV,IAAI,EAAE,CAAC;AACZ,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAC9B,QAAkB,EAClB,SAAiB,EACjB,OAA6C,EAAE;IAS/C,MAAM,KAAK,GAAG,iBAAiB,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,KAAK,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CACb,4BAA4B;YAC5B,iDAAiD,CAClD,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,GAAG,CAAC;QAC3C,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC;QACrC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;IAEnB,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,KAAK,GAAsB,EAAE,CAAC;IAEpC,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,YAAY,GAAG,uBAAuB,CAAC,CAAC,CAAC,QAAQ,EAAE,SAAS,EAAE;gBAClE,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,GAAG,EAAE,CAAC,CAAC,GAAG;aACX,CAAC,CAAC;YACH,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9B,KAAK,EAAE,CAAC;gBACR,SAAS;YACX,CAAC;YACD,KAAK,CAAC,IAAI,CAAC,GAAG,YAAY,CAAC,CAAC;YAC5B,MAAM,EAAE,CAAC;QACX,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,EAAE,CAAC;QACX,CAAC;IACH,CAAC;IAED,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;QAC9C,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC;QACrB,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;IAC1B,CAAC;IAED,OAAO;QACL,aAAa,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;QACpC,MAAM;QACN,KAAK;QACL,KAAK;QACL,MAAM;QACN,QAAQ,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC7B,SAAS,EAAE,CAAC,CAAC,SAAS;YACtB,KAAK,EAAE,CAAC,CAAC,KAAK;YACd,YAAY,EAAE,CAAC,CAAC,YAAY;SAC7B,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC"}
@@ -0,0 +1,196 @@
1
+ /**
2
+ * v0.2.5 — Claude Desktop local import.
3
+ *
4
+ * Claude Desktop is an Electron app. Its on-disk format is undocumented
5
+ * and has changed across versions (Local Storage / IndexedDB / SQLite
6
+ * variants depending on Electron + Anthropic's app shape). Cracking the
7
+ * live cache is fragile.
8
+ *
9
+ * Stable path that works on every version: Claude's built-in
10
+ * Settings → Privacy → Export data feature outputs a JSON file with all
11
+ * conversations. This module:
12
+ *
13
+ * 1. PROBE mode: locate the Claude Desktop folder and list what's
14
+ * there. Useful for the user to discover where their data lives
15
+ * and for us to add format-specific parsers as we see real data.
16
+ *
17
+ * 2. IMPORT mode: ingest a JSON export file (the one from
18
+ * Settings → Privacy → Export). Same `importClaudeExport()` path
19
+ * as the regular CLI's `mnueron import --claude`.
20
+ *
21
+ * 3. AUTO mode: try to find a recently-downloaded Claude export under
22
+ * ~/Downloads, ~/Desktop, or the Claude config folder itself. If
23
+ * one is found, import it. Otherwise, fall through to PROBE and
24
+ * print instructions for getting one.
25
+ *
26
+ * Why not crack the cache: Electron's leveldb data is unstable across
27
+ * minor versions, varies by platform, and Anthropic changes shape
28
+ * without notice. The JSON export is a documented API surface and
29
+ * survives version bumps.
30
+ */
31
+ import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
32
+ import { homedir, platform } from 'node:os';
33
+ import { join } from 'node:path';
34
+ import { importClaudeExport } from './claude.js';
35
+ /**
36
+ * Walk all the standard Claude Desktop folder locations and return what's
37
+ * there + heuristic hints. Doesn't read or modify anything — read-only
38
+ * inspection.
39
+ */
40
+ export function probeClaudeDesktop() {
41
+ const attempted = standardPaths();
42
+ const found = attempted.find((p) => existsSync(p)) ?? null;
43
+ const out = {
44
+ found: !!found,
45
+ path: found,
46
+ pathsAttempted: attempted,
47
+ contents: [],
48
+ hints: [],
49
+ exportCandidates: [],
50
+ };
51
+ if (!found) {
52
+ out.hints.push('Claude Desktop folder not found at any standard location.', 'Install Claude Desktop from https://claude.ai/download first.', 'If you have it installed under a non-default path, point us at it:', ' mnueron import --claude-desktop --dir <path>');
53
+ return out;
54
+ }
55
+ // Top-level listing
56
+ for (const name of readdirSync(found)) {
57
+ try {
58
+ const p = join(found, name);
59
+ const stat = statSync(p);
60
+ out.contents.push({
61
+ name,
62
+ type: stat.isDirectory() ? 'dir' : 'file',
63
+ size: stat.isFile() ? stat.size : undefined,
64
+ });
65
+ }
66
+ catch {
67
+ /* permission denied or symlink loop — skip */
68
+ }
69
+ }
70
+ // Heuristic hints based on what's there
71
+ const has = (n) => out.contents.some((c) => c.name === n);
72
+ if (has('Local Storage'))
73
+ out.hints.push('• Local Storage/ — Electron localStorage (leveldb)');
74
+ if (has('IndexedDB'))
75
+ out.hints.push('• IndexedDB/ — conversations likely stored here in newer builds');
76
+ if (has('Preferences'))
77
+ out.hints.push('• Preferences — app config JSON (settings only, no chats)');
78
+ if (has('Session Storage'))
79
+ out.hints.push('• Session Storage/ — short-lived per-session data');
80
+ if (has('Cache') || has('Code Cache')) {
81
+ out.hints.push('• Cache/ Code Cache/ — HTTP + V8 caches (skip; no chat data)');
82
+ }
83
+ // Probe for an export JSON file in the Claude folder itself
84
+ out.exportCandidates.push(...findExportCandidates(found));
85
+ // Also check Downloads + Desktop, since that's where the export
86
+ // dialog usually drops the file.
87
+ const home = homedir();
88
+ for (const folder of [join(home, 'Downloads'), join(home, 'Desktop')]) {
89
+ if (existsSync(folder)) {
90
+ out.exportCandidates.push(...findExportCandidates(folder));
91
+ }
92
+ }
93
+ if (out.exportCandidates.length > 0) {
94
+ out.hints.push(`Found ${out.exportCandidates.length} candidate export file(s) — see exportCandidates below.`);
95
+ }
96
+ else {
97
+ out.hints.push('No Claude export JSON found yet. To create one:', ' 1. Open Claude Desktop', ' 2. Settings → Privacy → Export data', ' 3. Save the resulting JSON to your Downloads folder', ' 4. Re-run: mnueron import --claude-desktop');
98
+ }
99
+ return out;
100
+ }
101
+ /**
102
+ * Heuristic: a Claude export file is a `.json` that contains either
103
+ * `"chat_messages"` or `"conversations"` near the top + was modified in
104
+ * the last 90 days. We don't fully parse here — just enough to flag.
105
+ */
106
+ function findExportCandidates(dir) {
107
+ const hits = [];
108
+ try {
109
+ const ninetyDaysAgo = Date.now() - 90 * 24 * 3600 * 1000;
110
+ for (const name of readdirSync(dir)) {
111
+ if (!name.toLowerCase().endsWith('.json'))
112
+ continue;
113
+ const p = join(dir, name);
114
+ try {
115
+ const stat = statSync(p);
116
+ if (!stat.isFile() || stat.size < 200 || stat.mtimeMs < ninetyDaysAgo)
117
+ continue;
118
+ // Sniff: read the first 8 KB and look for tell-tale keys. Avoids
119
+ // parsing massive files just to reject them.
120
+ const fd = readFileSync(p, { encoding: 'utf8', flag: 'r' }).slice(0, 8192);
121
+ if (fd.includes('"chat_messages"') ||
122
+ fd.includes('"conversations"') ||
123
+ (fd.includes('"sender"') && fd.includes('"human"'))) {
124
+ hits.push(p);
125
+ }
126
+ }
127
+ catch { /* unreadable — skip */ }
128
+ }
129
+ }
130
+ catch { /* dir not readable */ }
131
+ return hits;
132
+ }
133
+ /**
134
+ * Import a Claude Desktop export JSON file. Delegates to the existing
135
+ * importClaudeExport() — same format as `mnueron import --claude` for
136
+ * web exports.
137
+ */
138
+ export async function importFromExportFile(filePath, namespace) {
139
+ if (!existsSync(filePath)) {
140
+ throw new Error(`export file not found: ${filePath}`);
141
+ }
142
+ return importClaudeExport(filePath, namespace);
143
+ }
144
+ /**
145
+ * Auto-find a recent export JSON and import it. Returns the import
146
+ * result + the resolved path. If nothing's found, throws so the caller
147
+ * can fall back to probe + manual guidance.
148
+ */
149
+ export async function autoImport(provider, namespace) {
150
+ const probe = probeClaudeDesktop();
151
+ if (probe.exportCandidates.length === 0) {
152
+ throw new Error('No Claude Desktop export JSON found. ' +
153
+ 'Open Claude Desktop → Settings → Privacy → Export data, ' +
154
+ 'save the JSON, then re-run this command.');
155
+ }
156
+ // Pick the newest by mtime
157
+ const newest = probe.exportCandidates
158
+ .map((p) => ({ p, m: statSync(p).mtimeMs }))
159
+ .sort((a, b) => b.m - a.m)[0].p;
160
+ const items = await importFromExportFile(newest, namespace);
161
+ const result = await provider.bulkSave(items);
162
+ return { path: newest, ...result };
163
+ }
164
+ /**
165
+ * Default-location paths for Claude Desktop's user data folder per OS.
166
+ * The first one that exists wins. If your install is non-standard,
167
+ * pass `--dir <path>` to the CLI subcommand.
168
+ */
169
+ function standardPaths() {
170
+ const home = homedir();
171
+ switch (platform()) {
172
+ case 'darwin':
173
+ return [
174
+ join(home, 'Library', 'Application Support', 'Claude'),
175
+ join(home, 'Library', 'Application Support', 'AnthropicClaude'),
176
+ ];
177
+ case 'win32': {
178
+ const appdata = process.env.APPDATA ?? join(home, 'AppData', 'Roaming');
179
+ const localApp = process.env.LOCALAPPDATA ?? join(home, 'AppData', 'Local');
180
+ return [
181
+ join(appdata, 'Claude'),
182
+ join(appdata, 'AnthropicClaude'),
183
+ join(localApp, 'Claude'),
184
+ join(localApp, 'AnthropicClaude'),
185
+ ];
186
+ }
187
+ case 'linux':
188
+ return [
189
+ join(home, '.config', 'Claude'),
190
+ join(home, '.config', 'AnthropicClaude'),
191
+ ];
192
+ default:
193
+ return [];
194
+ }
195
+ }
196
+ //# sourceMappingURL=claude_desktop.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude_desktop.js","sourceRoot":"","sources":["../../src/import/claude_desktop.ts"],"names":[],"mappings":"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"}