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.
Files changed (2) hide show
  1. package/dist/index.js +126 -6
  2. 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") {} else if (args[i] === "--config-only") {} else if (args[i] === "--help" || args[i] === "-h") {
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://mcp.conare.ai
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://mcp.conare.ai");
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
- return { key, dryRun, force, source, wasmDir, indexPath };
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://mcp.conare.ai");
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
- console.log("Done! MCP will be configured by the install script.");
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);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conare",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "description": "Conare CLI for ingesting AI chat history and configuring memory at conare.ai",
5
5
  "type": "module",
6
6
  "bin": {