conare 0.0.1 → 0.0.2
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 +126 -6
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -2,6 +2,10 @@
|
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
4
4
|
|
|
5
|
+
// src/index.ts
|
|
6
|
+
import { existsSync as existsSync6 } from "node:fs";
|
|
7
|
+
import { join as join8 } from "node:path";
|
|
8
|
+
|
|
5
9
|
// src/detect.ts
|
|
6
10
|
import { existsSync, readdirSync } from "node:fs";
|
|
7
11
|
import { join } from "node:path";
|
|
@@ -876,6 +880,68 @@ async function uploadBulk(apiKey, memories, onProgress) {
|
|
|
876
880
|
return { success, failed, results };
|
|
877
881
|
}
|
|
878
882
|
|
|
883
|
+
// src/configure.ts
|
|
884
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync2, readFileSync as readFileSync6, writeFileSync as writeFileSync2 } from "node:fs";
|
|
885
|
+
import { dirname, join as join7 } from "node:path";
|
|
886
|
+
import { homedir as homedir5 } from "node:os";
|
|
887
|
+
import { spawnSync } from "node:child_process";
|
|
888
|
+
var CONARE_URL = "https://mcp.conare.ai";
|
|
889
|
+
var SERVER_NAME = "conare-memory";
|
|
890
|
+
function readJsonFile(path) {
|
|
891
|
+
try {
|
|
892
|
+
return JSON.parse(readFileSync6(path, "utf-8"));
|
|
893
|
+
} catch {
|
|
894
|
+
return {};
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
function writeJsonFile(path, data) {
|
|
898
|
+
mkdirSync2(dirname(path), { recursive: true });
|
|
899
|
+
writeFileSync2(path, JSON.stringify(data, null, 2) + `
|
|
900
|
+
`);
|
|
901
|
+
}
|
|
902
|
+
function getServerConfig(apiKey) {
|
|
903
|
+
return {
|
|
904
|
+
type: "http",
|
|
905
|
+
url: `${CONARE_URL}/mcp`,
|
|
906
|
+
headers: {
|
|
907
|
+
Authorization: `Bearer ${apiKey}`
|
|
908
|
+
}
|
|
909
|
+
};
|
|
910
|
+
}
|
|
911
|
+
function upsertMcpServer(path, apiKey) {
|
|
912
|
+
const config = readJsonFile(path);
|
|
913
|
+
if (!config.mcpServers || typeof config.mcpServers !== "object") {
|
|
914
|
+
config.mcpServers = {};
|
|
915
|
+
}
|
|
916
|
+
config.mcpServers[SERVER_NAME] = getServerConfig(apiKey);
|
|
917
|
+
writeJsonFile(path, config);
|
|
918
|
+
}
|
|
919
|
+
function configureClaude(apiKey) {
|
|
920
|
+
const claudeConfigPath = join7(homedir5(), ".claude.json");
|
|
921
|
+
const claudeMcpPath = join7(homedir5(), ".claude", "mcp.json");
|
|
922
|
+
if (spawnSync("claude", ["mcp", "add-json", SERVER_NAME, "--scope", "user", JSON.stringify(getServerConfig(apiKey))], {
|
|
923
|
+
stdio: "ignore"
|
|
924
|
+
}).status === 0) {
|
|
925
|
+
return "Claude Code configured via `claude mcp add-json`";
|
|
926
|
+
}
|
|
927
|
+
upsertMcpServer(claudeConfigPath, apiKey);
|
|
928
|
+
if (existsSync5(join7(homedir5(), ".claude"))) {
|
|
929
|
+
upsertMcpServer(claudeMcpPath, apiKey);
|
|
930
|
+
}
|
|
931
|
+
return `Claude Code configured at ${claudeConfigPath}`;
|
|
932
|
+
}
|
|
933
|
+
function configureJsonClient(path, apiKey, label) {
|
|
934
|
+
upsertMcpServer(path, apiKey);
|
|
935
|
+
return `${label} configured at ${path}`;
|
|
936
|
+
}
|
|
937
|
+
function configureMcp(apiKey) {
|
|
938
|
+
const results = [];
|
|
939
|
+
results.push(configureClaude(apiKey));
|
|
940
|
+
results.push(configureJsonClient(join7(homedir5(), ".cursor", "mcp.json"), apiKey, "Cursor"));
|
|
941
|
+
results.push(configureJsonClient(join7(homedir5(), ".codex", "mcp.json"), apiKey, "Codex"));
|
|
942
|
+
return results;
|
|
943
|
+
}
|
|
944
|
+
|
|
879
945
|
// src/index.ts
|
|
880
946
|
function getDedupKey(memory) {
|
|
881
947
|
const metadata = memory.metadata;
|
|
@@ -886,6 +952,8 @@ function parseArgs() {
|
|
|
886
952
|
let key = "";
|
|
887
953
|
let dryRun = false;
|
|
888
954
|
let force = false;
|
|
955
|
+
let ingestOnly = false;
|
|
956
|
+
let configOnly = false;
|
|
889
957
|
let source;
|
|
890
958
|
let wasmDir;
|
|
891
959
|
let indexPath;
|
|
@@ -902,7 +970,11 @@ function parseArgs() {
|
|
|
902
970
|
wasmDir = args[++i];
|
|
903
971
|
} else if (args[i] === "--index") {
|
|
904
972
|
indexPath = args[i + 1] && !args[i + 1].startsWith("--") ? args[++i] : ".";
|
|
905
|
-
} else if (args[i] === "--ingest-only") {
|
|
973
|
+
} else if (args[i] === "--ingest-only") {
|
|
974
|
+
ingestOnly = true;
|
|
975
|
+
} else if (args[i] === "--config-only") {
|
|
976
|
+
configOnly = true;
|
|
977
|
+
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
906
978
|
console.log(`
|
|
907
979
|
conare — Ingest AI chat history into Conare
|
|
908
980
|
|
|
@@ -915,34 +987,63 @@ Options:
|
|
|
915
987
|
--index [path] Index codebase at path (default: current directory)
|
|
916
988
|
--dry-run Preview what would be uploaded
|
|
917
989
|
--force Re-ingest all / re-index all (bypass dedup)
|
|
990
|
+
--ingest-only Ingest memories without MCP configuration
|
|
991
|
+
--config-only Configure MCP only, skip ingestion
|
|
918
992
|
--source <name> Only ingest from: claude, codex, cursor
|
|
919
993
|
--wasm-dir <path> Path to sql.js module (for Cursor ingestion)
|
|
920
994
|
|
|
921
|
-
Get your API key at https://
|
|
995
|
+
Get your API key at https://conare.ai
|
|
922
996
|
`);
|
|
923
997
|
process.exit(0);
|
|
924
998
|
}
|
|
925
999
|
}
|
|
926
1000
|
if (!key) {
|
|
927
|
-
console.error("Error: --key is required. Get your API key at https://
|
|
1001
|
+
console.error("Error: --key is required. Get your API key at https://conare.ai");
|
|
928
1002
|
process.exit(1);
|
|
929
1003
|
}
|
|
930
1004
|
if (!key.startsWith("cmem_")) {
|
|
931
1005
|
console.error("Error: API key must start with cmem_");
|
|
932
1006
|
process.exit(1);
|
|
933
1007
|
}
|
|
934
|
-
|
|
1008
|
+
if (ingestOnly && configOnly) {
|
|
1009
|
+
console.error("Error: --ingest-only and --config-only cannot be used together");
|
|
1010
|
+
process.exit(1);
|
|
1011
|
+
}
|
|
1012
|
+
return { key, dryRun, force, ingestOnly, configOnly, source, wasmDir, indexPath };
|
|
935
1013
|
}
|
|
936
1014
|
async function main() {
|
|
937
1015
|
const opts = parseArgs();
|
|
1016
|
+
console.log("");
|
|
1017
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1018
|
+
console.log(" Conare Installer");
|
|
1019
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1020
|
+
console.log("");
|
|
938
1021
|
process.stdout.write("Validating API key... ");
|
|
939
1022
|
const auth = await validateKey(opts.key);
|
|
940
1023
|
if (!auth.valid) {
|
|
941
|
-
console.error("INVALID. Check your key at https://
|
|
1024
|
+
console.error("INVALID. Check your key at https://conare.ai");
|
|
942
1025
|
process.exit(1);
|
|
943
1026
|
}
|
|
944
1027
|
console.log(`OK (${auth.email})`);
|
|
945
1028
|
console.log();
|
|
1029
|
+
if (!opts.wasmDir && existsSync6(join8(process.cwd(), "node_modules", "sql.js"))) {
|
|
1030
|
+
opts.wasmDir = join8(process.cwd(), "node_modules");
|
|
1031
|
+
}
|
|
1032
|
+
if (opts.configOnly) {
|
|
1033
|
+
if (!opts.dryRun) {
|
|
1034
|
+
console.log("─── Configuring MCP ───");
|
|
1035
|
+
console.log("");
|
|
1036
|
+
for (const line of configureMcp(opts.key)) {
|
|
1037
|
+
console.log(` ✓ ${line}`);
|
|
1038
|
+
}
|
|
1039
|
+
console.log("");
|
|
1040
|
+
}
|
|
1041
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1042
|
+
console.log(" ✓ Done! Conare MCP is configured.");
|
|
1043
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1044
|
+
console.log("");
|
|
1045
|
+
return;
|
|
1046
|
+
}
|
|
946
1047
|
if (opts.indexPath !== undefined) {
|
|
947
1048
|
const { resolve: resolve2 } = await import("node:path");
|
|
948
1049
|
const absPath = resolve2(opts.indexPath);
|
|
@@ -989,6 +1090,14 @@ Nothing new to index.`);
|
|
|
989
1090
|
markIngested("codebase", fileHashes);
|
|
990
1091
|
}
|
|
991
1092
|
console.log();
|
|
1093
|
+
if (!opts.dryRun && !opts.ingestOnly) {
|
|
1094
|
+
console.log("─── Configuring MCP ───");
|
|
1095
|
+
console.log("");
|
|
1096
|
+
for (const line of configureMcp(opts.key)) {
|
|
1097
|
+
console.log(` ✓ ${line}`);
|
|
1098
|
+
}
|
|
1099
|
+
console.log("");
|
|
1100
|
+
}
|
|
992
1101
|
console.log("Done! Your codebase is now searchable via recall.");
|
|
993
1102
|
return;
|
|
994
1103
|
}
|
|
@@ -1086,7 +1195,18 @@ Nothing new to index.`);
|
|
|
1086
1195
|
}
|
|
1087
1196
|
}
|
|
1088
1197
|
console.log();
|
|
1089
|
-
|
|
1198
|
+
if (!opts.dryRun && !opts.ingestOnly) {
|
|
1199
|
+
console.log("─── Configuring MCP ───");
|
|
1200
|
+
console.log("");
|
|
1201
|
+
for (const line of configureMcp(opts.key)) {
|
|
1202
|
+
console.log(` ✓ ${line}`);
|
|
1203
|
+
}
|
|
1204
|
+
console.log("");
|
|
1205
|
+
}
|
|
1206
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1207
|
+
console.log(" ✓ Done! Every new conversation now starts with context.");
|
|
1208
|
+
console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
|
|
1209
|
+
console.log("");
|
|
1090
1210
|
}
|
|
1091
1211
|
main().catch((e) => {
|
|
1092
1212
|
console.error("Error:", e.message || e);
|