conare 0.5.13 → 0.5.15
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/dist/index.js +108 -53
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1825,20 +1825,27 @@ function showDetectedApps(targets) {
|
|
|
1825
1825
|
`), "Detected apps");
|
|
1826
1826
|
}
|
|
1827
1827
|
function showCountingLocalChats() {
|
|
1828
|
-
|
|
1828
|
+
countingSpinner = Y2();
|
|
1829
|
+
countingSpinner.start("Scanning local chats");
|
|
1829
1830
|
}
|
|
1830
1831
|
function showCountingToolChats(tool) {
|
|
1831
|
-
|
|
1832
|
+
countingSpinner?.message(`Scanning ${tool} chats`);
|
|
1832
1833
|
}
|
|
1833
1834
|
function showCountingToolProgress(tool, checked, found, total) {
|
|
1834
|
-
const checkedText = total ? `${checked.toLocaleString()}/${total.toLocaleString()}
|
|
1835
|
-
|
|
1835
|
+
const checkedText = total ? `${checked.toLocaleString()}/${total.toLocaleString()}` : checked.toLocaleString();
|
|
1836
|
+
countingSpinner?.message(`Scanning ${tool}: ${checkedText} files, ${found.toLocaleString()} importable`);
|
|
1836
1837
|
}
|
|
1837
1838
|
function showCountingToolDone(tool, count) {
|
|
1838
|
-
|
|
1839
|
+
toolTotals[tool] = count;
|
|
1840
|
+
countingSpinner?.message(`${tool}: ${count.toLocaleString()} chats`);
|
|
1839
1841
|
}
|
|
1840
1842
|
function showLocalChatsCounted() {
|
|
1841
|
-
|
|
1843
|
+
if (!countingSpinner)
|
|
1844
|
+
return;
|
|
1845
|
+
const entries = Object.entries(toolTotals).filter(([, n]) => n > 0);
|
|
1846
|
+
const summary = entries.length ? entries.map(([tool, n]) => `${tool} ${n.toLocaleString()}`).join(", ") : "no chats found";
|
|
1847
|
+
countingSpinner.stop(`Found ${summary}`);
|
|
1848
|
+
countingSpinner = null;
|
|
1842
1849
|
}
|
|
1843
1850
|
async function promptApiKey(options) {
|
|
1844
1851
|
if (options.providedApiKey) {
|
|
@@ -1929,8 +1936,10 @@ async function confirmBackgroundSync() {
|
|
|
1929
1936
|
}));
|
|
1930
1937
|
return value === "yes";
|
|
1931
1938
|
}
|
|
1939
|
+
var countingSpinner = null, toolTotals;
|
|
1932
1940
|
var init_interactive = __esm(() => {
|
|
1933
1941
|
init_dist2();
|
|
1942
|
+
toolTotals = {};
|
|
1934
1943
|
});
|
|
1935
1944
|
|
|
1936
1945
|
// src/index.ts
|
|
@@ -2046,6 +2055,42 @@ function parseSession(lines) {
|
|
|
2046
2055
|
})).filter((t) => t.assistant.length >= MIN_TURN_LEN);
|
|
2047
2056
|
return { turns, date, sourceTimestamp, startedAt, updatedAt };
|
|
2048
2057
|
}
|
|
2058
|
+
function hasAnyImportableTurn(lines) {
|
|
2059
|
+
let currentUser = null;
|
|
2060
|
+
let currentAssistant = [];
|
|
2061
|
+
const closeRound = () => {
|
|
2062
|
+
if (currentUser === null || currentAssistant.length === 0)
|
|
2063
|
+
return false;
|
|
2064
|
+
const assistant = currentAssistant.filter((p) => !isNarration(p)).join(`
|
|
2065
|
+
|
|
2066
|
+
`);
|
|
2067
|
+
return assistant.length >= MIN_TURN_LEN;
|
|
2068
|
+
};
|
|
2069
|
+
for (const line of lines) {
|
|
2070
|
+
if (!line.trim())
|
|
2071
|
+
continue;
|
|
2072
|
+
let obj;
|
|
2073
|
+
try {
|
|
2074
|
+
obj = JSON.parse(line);
|
|
2075
|
+
} catch {
|
|
2076
|
+
continue;
|
|
2077
|
+
}
|
|
2078
|
+
if (obj.type === "user") {
|
|
2079
|
+
const text = cleanText(extractText(obj.message?.content));
|
|
2080
|
+
if (text.length >= MIN_TURN_LEN) {
|
|
2081
|
+
if (closeRound())
|
|
2082
|
+
return true;
|
|
2083
|
+
currentUser = text;
|
|
2084
|
+
currentAssistant = [];
|
|
2085
|
+
}
|
|
2086
|
+
} else if (obj.type === "assistant") {
|
|
2087
|
+
const text = cleanText(extractText(obj.message?.content));
|
|
2088
|
+
if (text.length >= MIN_TURN_LEN)
|
|
2089
|
+
currentAssistant.push(text);
|
|
2090
|
+
}
|
|
2091
|
+
}
|
|
2092
|
+
return closeRound();
|
|
2093
|
+
}
|
|
2049
2094
|
function getParentUuid(lines) {
|
|
2050
2095
|
for (const line of lines) {
|
|
2051
2096
|
if (!line.trim())
|
|
@@ -2062,54 +2107,50 @@ function getParentUuid(lines) {
|
|
|
2062
2107
|
}
|
|
2063
2108
|
return;
|
|
2064
2109
|
}
|
|
2065
|
-
function countImportableClaudeSessions(onProgress) {
|
|
2110
|
+
async function countImportableClaudeSessions(onProgress) {
|
|
2111
|
+
const { readFile } = await import("node:fs/promises");
|
|
2066
2112
|
const projectsDir = join2(homedir2(), ".claude", "projects");
|
|
2067
|
-
let count = 0;
|
|
2068
|
-
let checked = 0;
|
|
2069
|
-
let total = 0;
|
|
2070
2113
|
let projectDirs;
|
|
2071
2114
|
try {
|
|
2072
2115
|
projectDirs = readdirSync(projectsDir);
|
|
2073
2116
|
} catch {
|
|
2074
2117
|
return 0;
|
|
2075
2118
|
}
|
|
2076
|
-
const
|
|
2119
|
+
const allFiles = [];
|
|
2120
|
+
for (const projDir of projectDirs) {
|
|
2077
2121
|
const projPath = join2(projectsDir, projDir);
|
|
2078
2122
|
try {
|
|
2079
|
-
const
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
|
|
2088
|
-
|
|
2089
|
-
|
|
2123
|
+
for (const f of readdirSync(projPath)) {
|
|
2124
|
+
if (f.endsWith(".jsonl"))
|
|
2125
|
+
allFiles.push(join2(projPath, f));
|
|
2126
|
+
}
|
|
2127
|
+
} catch {}
|
|
2128
|
+
}
|
|
2129
|
+
const total = allFiles.length;
|
|
2130
|
+
let count = 0;
|
|
2131
|
+
let checked = 0;
|
|
2132
|
+
const CONCURRENCY = 16;
|
|
2133
|
+
let nextIdx = 0;
|
|
2134
|
+
const worker = async () => {
|
|
2135
|
+
while (true) {
|
|
2136
|
+
const i = nextIdx++;
|
|
2137
|
+
if (i >= allFiles.length)
|
|
2138
|
+
return;
|
|
2090
2139
|
try {
|
|
2091
|
-
const raw =
|
|
2140
|
+
const raw = await readFile(allFiles[i], "utf-8");
|
|
2092
2141
|
const lines = raw.split(`
|
|
2093
2142
|
`);
|
|
2094
2143
|
const parentUuid = getParentUuid(lines);
|
|
2095
|
-
if (parentUuid
|
|
2096
|
-
if (checked % 100 === 0)
|
|
2097
|
-
report();
|
|
2098
|
-
continue;
|
|
2099
|
-
}
|
|
2100
|
-
const { turns } = parseSession(lines);
|
|
2101
|
-
if (turns.length > 0)
|
|
2144
|
+
if (parentUuid == null && hasAnyImportableTurn(lines))
|
|
2102
2145
|
count++;
|
|
2103
|
-
} catch {
|
|
2104
|
-
|
|
2105
|
-
report();
|
|
2106
|
-
continue;
|
|
2107
|
-
}
|
|
2146
|
+
} catch {}
|
|
2147
|
+
checked++;
|
|
2108
2148
|
if (checked % 100 === 0)
|
|
2109
|
-
|
|
2149
|
+
onProgress?.({ checked, found: count, total });
|
|
2110
2150
|
}
|
|
2111
|
-
}
|
|
2112
|
-
|
|
2151
|
+
};
|
|
2152
|
+
await Promise.all(Array.from({ length: CONCURRENCY }, () => worker()));
|
|
2153
|
+
onProgress?.({ checked, found: count, total });
|
|
2113
2154
|
return count;
|
|
2114
2155
|
}
|
|
2115
2156
|
function ingestClaude() {
|
|
@@ -2302,25 +2343,39 @@ function walkCodexSessionFiles(dir, visit) {
|
|
|
2302
2343
|
}
|
|
2303
2344
|
} catch {}
|
|
2304
2345
|
}
|
|
2305
|
-
function countImportableCodexSessions(onProgress) {
|
|
2346
|
+
async function countImportableCodexSessions(onProgress) {
|
|
2306
2347
|
const sessionsDir = join3(homedir3(), ".codex", "sessions");
|
|
2307
2348
|
if (!existsSync3(sessionsDir))
|
|
2308
2349
|
return 0;
|
|
2350
|
+
const { readFile } = await import("node:fs/promises");
|
|
2351
|
+
const files = [];
|
|
2352
|
+
walkCodexSessionFiles(sessionsDir, (filePath) => {
|
|
2353
|
+
files.push(filePath);
|
|
2354
|
+
});
|
|
2355
|
+
const total = files.length;
|
|
2309
2356
|
let count = 0;
|
|
2310
2357
|
let checked = 0;
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2358
|
+
const CONCURRENCY = 16;
|
|
2359
|
+
let nextIdx = 0;
|
|
2360
|
+
const worker = async () => {
|
|
2361
|
+
while (true) {
|
|
2362
|
+
const i = nextIdx++;
|
|
2363
|
+
if (i >= files.length)
|
|
2364
|
+
return;
|
|
2365
|
+
try {
|
|
2366
|
+
const lines = (await readFile(files[i], "utf-8")).split(`
|
|
2315
2367
|
`).filter(Boolean);
|
|
2316
|
-
|
|
2317
|
-
|
|
2318
|
-
|
|
2319
|
-
|
|
2320
|
-
|
|
2321
|
-
|
|
2322
|
-
|
|
2323
|
-
|
|
2368
|
+
const { rounds } = parseCodexSession(lines);
|
|
2369
|
+
if (rounds.length > 0)
|
|
2370
|
+
count++;
|
|
2371
|
+
} catch {}
|
|
2372
|
+
checked++;
|
|
2373
|
+
if (checked % 100 === 0)
|
|
2374
|
+
onProgress?.({ checked, found: count, total });
|
|
2375
|
+
}
|
|
2376
|
+
};
|
|
2377
|
+
await Promise.all(Array.from({ length: CONCURRENCY }, () => worker()));
|
|
2378
|
+
onProgress?.({ checked, found: count, total });
|
|
2324
2379
|
return count;
|
|
2325
2380
|
}
|
|
2326
2381
|
function walkCodexSessions(dir, memories, sessionIds, stats) {
|
|
@@ -2797,7 +2852,7 @@ async function detect(options = {}) {
|
|
|
2797
2852
|
const claudeDir = join5(home, ".claude", "projects");
|
|
2798
2853
|
if (existsSync5(claudeDir)) {
|
|
2799
2854
|
onProgress?.({ tool: "Claude Code", status: "start" });
|
|
2800
|
-
const sessionCount = countImportableClaudeSessions((progress) => {
|
|
2855
|
+
const sessionCount = await countImportableClaudeSessions((progress) => {
|
|
2801
2856
|
onProgress?.({ tool: "Claude Code", status: "progress", ...progress });
|
|
2802
2857
|
});
|
|
2803
2858
|
onProgress?.({ tool: "Claude Code", status: "done", count: sessionCount });
|
|
@@ -2810,7 +2865,7 @@ async function detect(options = {}) {
|
|
|
2810
2865
|
const codexSessions = join5(home, ".codex", "sessions");
|
|
2811
2866
|
if (existsSync5(codexConfig) || existsSync5(codexSessions)) {
|
|
2812
2867
|
onProgress?.({ tool: "Codex", status: "start" });
|
|
2813
|
-
const sessionCount = countImportableCodexSessions((progress) => {
|
|
2868
|
+
const sessionCount = await countImportableCodexSessions((progress) => {
|
|
2814
2869
|
onProgress?.({ tool: "Codex", status: "progress", ...progress });
|
|
2815
2870
|
});
|
|
2816
2871
|
onProgress?.({ tool: "Codex", status: "done", count: sessionCount });
|