conare 0.1.1 → 0.1.3
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 +48 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -376,12 +376,13 @@ function ingestClaude() {
|
|
|
376
376
|
const projectsDir = join3(homedir3(), ".claude", "projects");
|
|
377
377
|
const memories = [];
|
|
378
378
|
const sessionIds = [];
|
|
379
|
-
let
|
|
379
|
+
let filtered = 0;
|
|
380
|
+
let deduped = 0;
|
|
380
381
|
let projectDirs;
|
|
381
382
|
try {
|
|
382
383
|
projectDirs = readdirSync2(projectsDir);
|
|
383
384
|
} catch {
|
|
384
|
-
return { memories, sessionIds, skipped };
|
|
385
|
+
return { memories, sessionIds, skipped: 0, filtered, deduped };
|
|
385
386
|
}
|
|
386
387
|
for (const projDir of projectDirs) {
|
|
387
388
|
const projPath = join3(projectsDir, projDir);
|
|
@@ -398,7 +399,7 @@ function ingestClaude() {
|
|
|
398
399
|
const { turns, date } = parseSession(raw.split(`
|
|
399
400
|
`));
|
|
400
401
|
if (turns.length === 0) {
|
|
401
|
-
|
|
402
|
+
filtered++;
|
|
402
403
|
continue;
|
|
403
404
|
}
|
|
404
405
|
const header = `# Chat: ${project}${date ? ` | ${date}` : ""}`;
|
|
@@ -423,7 +424,7 @@ ${body}`;
|
|
|
423
424
|
const dedupKey = `claude:${sessionId}`;
|
|
424
425
|
const fingerprint = `${dedupKey}:${contentHash}`;
|
|
425
426
|
if (isIngested("claude", fingerprint)) {
|
|
426
|
-
|
|
427
|
+
deduped++;
|
|
427
428
|
continue;
|
|
428
429
|
}
|
|
429
430
|
memories.push({
|
|
@@ -441,7 +442,7 @@ ${body}`;
|
|
|
441
442
|
sessionIds.push(sessionId);
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
|
-
return { memories, sessionIds, skipped };
|
|
445
|
+
return { memories, sessionIds, skipped: filtered + deduped, filtered, deduped };
|
|
445
446
|
}
|
|
446
447
|
|
|
447
448
|
// src/ingest/codex.ts
|
|
@@ -452,7 +453,8 @@ var MAX_CONTENT2 = 48000;
|
|
|
452
453
|
function ingestCodex() {
|
|
453
454
|
const memories = [];
|
|
454
455
|
const sessionIds = [];
|
|
455
|
-
let
|
|
456
|
+
let filtered = 0;
|
|
457
|
+
let deduped = 0;
|
|
456
458
|
const historyPath = join4(homedir4(), ".codex", "history.jsonl");
|
|
457
459
|
if (existsSync3(historyPath)) {
|
|
458
460
|
try {
|
|
@@ -490,14 +492,14 @@ ${body}`;
|
|
|
490
492
|
|
|
491
493
|
[truncated]`;
|
|
492
494
|
if (content.length < 100) {
|
|
493
|
-
|
|
495
|
+
filtered++;
|
|
494
496
|
continue;
|
|
495
497
|
}
|
|
496
498
|
const contentHash = createContentHash(content);
|
|
497
499
|
const dedupKey = `codex:${sessionId}`;
|
|
498
500
|
const fingerprint = `${dedupKey}:${contentHash}`;
|
|
499
501
|
if (isIngested("codex", fingerprint)) {
|
|
500
|
-
|
|
502
|
+
deduped++;
|
|
501
503
|
continue;
|
|
502
504
|
}
|
|
503
505
|
memories.push({
|
|
@@ -512,16 +514,19 @@ ${body}`;
|
|
|
512
514
|
const sessionsDir = join4(homedir4(), ".codex", "sessions");
|
|
513
515
|
if (existsSync3(sessionsDir)) {
|
|
514
516
|
try {
|
|
515
|
-
|
|
517
|
+
const stats = { filtered: 0, deduped: 0 };
|
|
518
|
+
walkCodexSessions(sessionsDir, memories, sessionIds, stats);
|
|
519
|
+
filtered += stats.filtered;
|
|
520
|
+
deduped += stats.deduped;
|
|
516
521
|
} catch {}
|
|
517
522
|
}
|
|
518
|
-
return { memories, sessionIds, skipped };
|
|
523
|
+
return { memories, sessionIds, skipped: filtered + deduped, filtered, deduped };
|
|
519
524
|
}
|
|
520
|
-
function walkCodexSessions(dir, memories, sessionIds,
|
|
525
|
+
function walkCodexSessions(dir, memories, sessionIds, stats) {
|
|
521
526
|
try {
|
|
522
527
|
for (const entry of readdirSync3(dir, { withFileTypes: true })) {
|
|
523
528
|
if (entry.isDirectory()) {
|
|
524
|
-
walkCodexSessions(join4(dir, entry.name), memories, sessionIds,
|
|
529
|
+
walkCodexSessions(join4(dir, entry.name), memories, sessionIds, stats);
|
|
525
530
|
} else if (entry.name.endsWith(".jsonl")) {
|
|
526
531
|
const sessionId = basename2(entry.name, ".jsonl");
|
|
527
532
|
if (sessionIds.includes(sessionId))
|
|
@@ -552,8 +557,10 @@ function walkCodexSessions(dir, memories, sessionIds, skipped) {
|
|
|
552
557
|
continue;
|
|
553
558
|
}
|
|
554
559
|
}
|
|
555
|
-
if (turns.length === 0)
|
|
560
|
+
if (turns.length === 0) {
|
|
561
|
+
stats.filtered++;
|
|
556
562
|
continue;
|
|
563
|
+
}
|
|
557
564
|
const body = turns.map((t) => t.length > 500 ? t.slice(0, 500) + "..." : t).join(`
|
|
558
565
|
|
|
559
566
|
---
|
|
@@ -570,6 +577,7 @@ ${body}`;
|
|
|
570
577
|
const dedupKey = `codex:${sessionId}`;
|
|
571
578
|
const fingerprint = `${dedupKey}:${contentHash}`;
|
|
572
579
|
if (isIngested("codex", fingerprint)) {
|
|
580
|
+
stats.deduped++;
|
|
573
581
|
continue;
|
|
574
582
|
}
|
|
575
583
|
memories.push({
|
|
@@ -649,17 +657,18 @@ function extractTurns(db, composerId, bubbleHeaders) {
|
|
|
649
657
|
async function ingestCursor(dbPath, wasmDir) {
|
|
650
658
|
const memories = [];
|
|
651
659
|
const sessionIds = [];
|
|
652
|
-
let
|
|
660
|
+
let filtered = 0;
|
|
661
|
+
let deduped = 0;
|
|
653
662
|
let fileSize;
|
|
654
663
|
try {
|
|
655
664
|
fileSize = statSync(dbPath).size;
|
|
656
665
|
} catch {
|
|
657
666
|
console.log(" Skipping Cursor: database not accessible");
|
|
658
|
-
return { memories, sessionIds, skipped };
|
|
667
|
+
return { memories, sessionIds, skipped: 0, filtered, deduped };
|
|
659
668
|
}
|
|
660
669
|
if (fileSize > MAX_DB_SIZE) {
|
|
661
670
|
console.log(` Skipping Cursor: database too large (${(fileSize / 1024 / 1024 / 1024).toFixed(1)}GB)`);
|
|
662
|
-
return { memories, sessionIds, skipped };
|
|
671
|
+
return { memories, sessionIds, skipped: 0, filtered, deduped };
|
|
663
672
|
}
|
|
664
673
|
if (fileSize > WARN_DB_SIZE) {
|
|
665
674
|
console.log(` Warning: large database (${(fileSize / 1024 / 1024).toFixed(0)}MB), loading into memory...`);
|
|
@@ -667,14 +676,14 @@ async function ingestCursor(dbPath, wasmDir) {
|
|
|
667
676
|
const initSqlJs = loadSqlJs(wasmDir);
|
|
668
677
|
if (!initSqlJs) {
|
|
669
678
|
console.log(" Skipping Cursor: sql.js not available");
|
|
670
|
-
return { memories, sessionIds, skipped };
|
|
679
|
+
return { memories, sessionIds, skipped: 0, filtered, deduped };
|
|
671
680
|
}
|
|
672
681
|
let db;
|
|
673
682
|
try {
|
|
674
683
|
db = await openDb(initSqlJs, dbPath, wasmDir);
|
|
675
684
|
} catch (e) {
|
|
676
685
|
console.log(` Skipping Cursor: cannot open database (${e.message})`);
|
|
677
|
-
return { memories, sessionIds, skipped };
|
|
686
|
+
return { memories, sessionIds, skipped: 0, filtered, deduped };
|
|
678
687
|
}
|
|
679
688
|
try {
|
|
680
689
|
let rows = [];
|
|
@@ -689,21 +698,21 @@ async function ingestCursor(dbPath, wasmDir) {
|
|
|
689
698
|
try {
|
|
690
699
|
parsed = JSON.parse(value);
|
|
691
700
|
if (!parsed || typeof parsed !== "object") {
|
|
692
|
-
|
|
701
|
+
filtered++;
|
|
693
702
|
continue;
|
|
694
703
|
}
|
|
695
704
|
} catch {
|
|
696
|
-
|
|
705
|
+
filtered++;
|
|
697
706
|
continue;
|
|
698
707
|
}
|
|
699
708
|
const bubbleHeaders = parsed.fullConversationHeadersOnly;
|
|
700
709
|
if (!Array.isArray(bubbleHeaders) || bubbleHeaders.length === 0) {
|
|
701
|
-
|
|
710
|
+
filtered++;
|
|
702
711
|
continue;
|
|
703
712
|
}
|
|
704
713
|
const turns = extractTurns(db, composerId, bubbleHeaders);
|
|
705
714
|
if (turns.length === 0) {
|
|
706
|
-
|
|
715
|
+
filtered++;
|
|
707
716
|
continue;
|
|
708
717
|
}
|
|
709
718
|
const sessionName = parsed.name || "Cursor Chat";
|
|
@@ -730,7 +739,7 @@ ${body}`;
|
|
|
730
739
|
const dedupKey = `cursor:${composerId}`;
|
|
731
740
|
const fingerprint = `${dedupKey}:${contentHash}`;
|
|
732
741
|
if (isIngested("cursor", fingerprint)) {
|
|
733
|
-
|
|
742
|
+
deduped++;
|
|
734
743
|
continue;
|
|
735
744
|
}
|
|
736
745
|
memories.push({
|
|
@@ -752,7 +761,7 @@ ${body}`;
|
|
|
752
761
|
} finally {
|
|
753
762
|
db.close();
|
|
754
763
|
}
|
|
755
|
-
return { memories, sessionIds, skipped };
|
|
764
|
+
return { memories, sessionIds, skipped: filtered + deduped, filtered, deduped };
|
|
756
765
|
}
|
|
757
766
|
|
|
758
767
|
// src/ingest/codebase.ts
|
|
@@ -1000,7 +1009,7 @@ function indexCodebase(rootPath) {
|
|
|
1000
1009
|
|
|
1001
1010
|
// src/api.ts
|
|
1002
1011
|
var API_URL = "https://mcp.conare.ai";
|
|
1003
|
-
function createUploadBatches(memories, maxItems =
|
|
1012
|
+
function createUploadBatches(memories, maxItems = 64, maxChars = 1e6) {
|
|
1004
1013
|
const batches = [];
|
|
1005
1014
|
let current = [];
|
|
1006
1015
|
let currentChars = 0;
|
|
@@ -1926,6 +1935,14 @@ function renderProgressSummary(success, failed, noun) {
|
|
|
1926
1935
|
return `\r \x1B[32m✓\x1B[0m [\x1B[36m${bar}\x1B[0m] ${success} ${noun}, ${failed} failed (${pct}%)${" ".repeat(12)}
|
|
1927
1936
|
`;
|
|
1928
1937
|
}
|
|
1938
|
+
function renderDiscoverySummary(discovered, filtered, deduped) {
|
|
1939
|
+
const parts = [`${discovered} ingestible`];
|
|
1940
|
+
if (filtered > 0)
|
|
1941
|
+
parts.push(`${filtered} filtered`);
|
|
1942
|
+
if (deduped > 0)
|
|
1943
|
+
parts.push(`${deduped} already imported`);
|
|
1944
|
+
return parts.join(", ");
|
|
1945
|
+
}
|
|
1929
1946
|
function parseArgs() {
|
|
1930
1947
|
const args = process.argv.slice(2);
|
|
1931
1948
|
let key = "";
|
|
@@ -2160,22 +2177,22 @@ Nothing new to index.`);
|
|
|
2160
2177
|
const shouldIngest = (name) => selectedSources.includes(name);
|
|
2161
2178
|
if (shouldIngest("claude") && tools.find((t) => t.name === "Claude Code")?.available) {
|
|
2162
2179
|
process.stdout.write("Ingesting Claude Code... ");
|
|
2163
|
-
const { memories,
|
|
2180
|
+
const { memories, filtered, deduped } = ingestClaude();
|
|
2164
2181
|
allMemories.push(...memories);
|
|
2165
|
-
console.log(
|
|
2182
|
+
console.log(renderDiscoverySummary(memories.length, filtered, deduped));
|
|
2166
2183
|
}
|
|
2167
2184
|
if (shouldIngest("codex") && tools.find((t) => t.name === "Codex")?.available) {
|
|
2168
2185
|
process.stdout.write("Ingesting Codex... ");
|
|
2169
|
-
const { memories,
|
|
2186
|
+
const { memories, filtered, deduped } = ingestCodex();
|
|
2170
2187
|
allMemories.push(...memories);
|
|
2171
|
-
console.log(
|
|
2188
|
+
console.log(renderDiscoverySummary(memories.length, filtered, deduped));
|
|
2172
2189
|
}
|
|
2173
2190
|
if (shouldIngest("cursor") && tools.find((t) => t.name === "Cursor")?.available) {
|
|
2174
2191
|
process.stdout.write("Ingesting Cursor... ");
|
|
2175
2192
|
const cursorTool = tools.find((t) => t.name === "Cursor");
|
|
2176
|
-
const { memories,
|
|
2193
|
+
const { memories, filtered, deduped } = await ingestCursor(cursorTool.path, opts.wasmDir);
|
|
2177
2194
|
allMemories.push(...memories);
|
|
2178
|
-
console.log(
|
|
2195
|
+
console.log(renderDiscoverySummary(memories.length, filtered, deduped));
|
|
2179
2196
|
}
|
|
2180
2197
|
console.log();
|
|
2181
2198
|
if (allMemories.length === 0) {
|