conare 0.4.4 → 0.4.6

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 +142 -144
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -34,6 +34,27 @@ import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync
34
34
  import { createHash } from "node:crypto";
35
35
  import { join as join2 } from "node:path";
36
36
  import { homedir as homedir2 } from "node:os";
37
+ function fitContent(header, rounds) {
38
+ const buildContent = (maxUser) => {
39
+ const body = rounds.map((r) => {
40
+ const user = maxUser > 0 && r.user.length > maxUser ? r.user.slice(0, maxUser) + "..." : r.user;
41
+ return `## Q: ${user}
42
+
43
+ ${r.assistant}`;
44
+ }).join(`
45
+
46
+ ---
47
+
48
+ `);
49
+ return `${header}
50
+
51
+ ${body}`;
52
+ };
53
+ const full = buildContent(0);
54
+ if (full.length <= MAX_MEMORY_CONTENT)
55
+ return full;
56
+ return buildContent(TRUNCATED_USER_MSG);
57
+ }
37
58
  function isNarration(text) {
38
59
  const stripped = text.trim();
39
60
  if (stripped.length < MIN_SUBSTANTIVE)
@@ -97,7 +118,7 @@ function clearIngested(source) {
97
118
  mkdirSync(dir, { recursive: true });
98
119
  writeFileSync(MANIFEST_PATH, JSON.stringify(manifest, null, 2));
99
120
  }
100
- var MANIFEST_PATH, MIN_SUBSTANTIVE = 200, NARRATION_RE;
121
+ var MANIFEST_PATH, MAX_MEMORY_CONTENT = 200000, TRUNCATED_USER_MSG = 3000, MIN_SUBSTANTIVE = 200, NARRATION_RE;
101
122
  var init_shared = __esm(() => {
102
123
  MANIFEST_PATH = join2(homedir2(), ".conare", "ingested.json");
103
124
  NARRATION_RE = /^[\s\n]*(Let me |Now let me |Now I['\u2019]|Now add |Now fix |Now replace |Now integrate |Now update |Now pass |Now clean |Now build|Update the |Builds clean|Deployed\.|Wait, I |Let['\u2019]s test |Good —|Great\.|Perfect\.|Alright|OK,? let me|I[''\u2019]ll |Starting |I need to |Need |I found |I read |I[''\u2019]ve (loaded|confirmed|verified)|Context loaded|Next (I[''\u2019]|step)|Deps confirm|Diff check|Still missing|I[''\u2019]ll (do|check|inspect|trace|run|grab|pull|read|verify))/;
@@ -525,13 +546,13 @@ async function getRemoteMemoryCount(apiKey) {
525
546
  return null;
526
547
  }
527
548
  }
528
- async function uploadItems(apiKey, items, asyncEmbed = false) {
549
+ async function uploadItems(apiKey, items) {
529
550
  let retries = 4;
530
551
  while (retries > 0) {
531
552
  try {
532
553
  const data = await apiRequest("/api/memories/bulk", apiKey, {
533
554
  method: "POST",
534
- body: JSON.stringify(asyncEmbed ? { items, async: true } : items)
555
+ body: JSON.stringify({ items })
535
556
  });
536
557
  if (!Array.isArray(data.results) || data.results.length !== items.length) {
537
558
  throw new Error("Unexpected bulk upload response");
@@ -562,7 +583,7 @@ async function uploadBulk(apiKey, memories, onProgress) {
562
583
  const results = [];
563
584
  const batches = createUploadBatches(memories);
564
585
  for (const batch of batches) {
565
- let batchResults = await uploadItems(apiKey, batch.items, true);
586
+ let batchResults = await uploadItems(apiKey, batch.items);
566
587
  if (batch.items.length > 1 && batchResults.some((result) => !result.success)) {
567
588
  const retriedResults = [];
568
589
  for (let i = 0;i < batch.items.length; i++) {
@@ -571,7 +592,7 @@ async function uploadBulk(apiKey, memories, onProgress) {
571
592
  retriedResults.push(result);
572
593
  continue;
573
594
  }
574
- const [singleResult] = await uploadItems(apiKey, [batch.items[i]], true);
595
+ const [singleResult] = await uploadItems(apiKey, [batch.items[i]]);
575
596
  retriedResults.push(singleResult);
576
597
  }
577
598
  batchResults = retriedResults;
@@ -593,7 +614,7 @@ async function uploadBulk(apiKey, memories, onProgress) {
593
614
  }
594
615
  return { success, failed, results };
595
616
  }
596
- var API_URL2 = "https://mcp.conare.ai", ApiError, PAGE_SIZE = 200, DELETE_CONCURRENCY = 5;
617
+ var API_URL2 = "https://conare.ai", ApiError, PAGE_SIZE = 200, DELETE_CONCURRENCY = 5;
597
618
  var init_api = __esm(() => {
598
619
  ApiError = class ApiError extends Error {
599
620
  statusCode;
@@ -1743,7 +1764,7 @@ async function promptApiKey(options) {
1743
1764
  validate(value) {
1744
1765
  const resolved = value.trim() || options.savedApiKey || "";
1745
1766
  if (!resolved)
1746
- return "Enter an API key from https://mcp.conare.ai";
1767
+ return "Enter an API key from https://conare.ai";
1747
1768
  if (!resolved.startsWith("cmem_"))
1748
1769
  return "API keys start with cmem_";
1749
1770
  return;
@@ -1775,7 +1796,7 @@ async function promptAuth(options) {
1775
1796
  validate(value) {
1776
1797
  const resolved = value.trim();
1777
1798
  if (!resolved)
1778
- return "Enter an API key from https://mcp.conare.ai";
1799
+ return "Enter an API key from https://conare.ai";
1779
1800
  if (!resolved.startsWith("cmem_"))
1780
1801
  return "API keys start with cmem_";
1781
1802
  return;
@@ -2007,7 +2028,7 @@ async function detect() {
2007
2028
  // src/auth.ts
2008
2029
  import { execSync } from "node:child_process";
2009
2030
  import { platform as platform2 } from "node:os";
2010
- var API_URL = "https://mcp.conare.ai";
2031
+ var API_URL = "https://conare.ai";
2011
2032
  async function browserAuth() {
2012
2033
  const stateBytes = new Uint8Array(16);
2013
2034
  crypto.getRandomValues(stateBytes);
@@ -2088,7 +2109,6 @@ init_shared();
2088
2109
  import { readdirSync as readdirSync2, readFileSync as readFileSync3, existsSync as existsSync3 } from "node:fs";
2089
2110
  import { join as join3, basename } from "node:path";
2090
2111
  import { homedir as homedir3, platform as platform3 } from "node:os";
2091
- var MAX_CONTENT = 48000;
2092
2112
  var MIN_TURN_LEN = 50;
2093
2113
  function resolveProjectName(dirName) {
2094
2114
  const segments = dirName.replace(/^-/, "").split("-");
@@ -2231,22 +2251,7 @@ function ingestClaude() {
2231
2251
  continue;
2232
2252
  }
2233
2253
  const header = `# Chat: ${project}${date ? ` | ${date}` : ""}`;
2234
- const body = turns.map((t) => {
2235
- return `## Q: ${t.user}
2236
-
2237
- ${t.assistant}`;
2238
- }).join(`
2239
-
2240
- ---
2241
-
2242
- `);
2243
- let content = `${header}
2244
-
2245
- ${body}`;
2246
- if (content.length > MAX_CONTENT)
2247
- content = content.slice(0, MAX_CONTENT) + `
2248
-
2249
- [truncated]`;
2254
+ const content = fitContent(header, turns);
2250
2255
  const contentHash = createContentHash(content);
2251
2256
  const dedupKey = `claude:${sessionId}`;
2252
2257
  const fingerprint = `${dedupKey}:${contentHash}`;
@@ -2277,7 +2282,6 @@ init_shared();
2277
2282
  import { existsSync as existsSync4, readFileSync as readFileSync4, readdirSync as readdirSync3 } from "node:fs";
2278
2283
  import { join as join4, basename as basename2 } from "node:path";
2279
2284
  import { homedir as homedir4 } from "node:os";
2280
- var MAX_CONTENT2 = 48000;
2281
2285
  function isCodexBoilerplate(text) {
2282
2286
  return text.startsWith("# AGENTS.md instructions for") || text.startsWith("<INSTRUCTIONS>") || text.startsWith("<user_instructions>") || text.startsWith("<user_action>");
2283
2287
  }
@@ -2385,25 +2389,14 @@ function walkCodexSessions(dir, memories, sessionIds, stats) {
2385
2389
  stats.filtered++;
2386
2390
  continue;
2387
2391
  }
2388
- const body = rounds.map((r) => {
2389
- const assistant = r.assistantParts.join(`
2390
-
2391
- `);
2392
- return `## Q: ${r.user}
2393
-
2394
- ${assistant}`;
2395
- }).join(`
2392
+ const header = `# Codex Session${project ? `: ${project}` : ""} | ${date || "unknown"}`;
2393
+ const turns = rounds.map((r) => ({
2394
+ user: r.user,
2395
+ assistant: r.assistantParts.join(`
2396
2396
 
2397
- ---
2398
-
2399
- `);
2400
- let content = `# Codex Session${project ? `: ${project}` : ""} | ${date || "unknown"}
2401
-
2402
- ${body}`;
2403
- if (content.length > MAX_CONTENT2)
2404
- content = content.slice(0, MAX_CONTENT2) + `
2405
-
2406
- [truncated]`;
2397
+ `)
2398
+ }));
2399
+ const content = fitContent(header, turns);
2407
2400
  const contentHash = createContentHash(content);
2408
2401
  const dedupKey = `codex:${sessionId}`;
2409
2402
  const fingerprint = `${dedupKey}:${contentHash}`;
@@ -2435,7 +2428,6 @@ init_shared();
2435
2428
  import { readFileSync as readFileSync5, statSync } from "node:fs";
2436
2429
  import { join as join5 } from "node:path";
2437
2430
  import { createRequire as createRequire3 } from "node:module";
2438
- var MAX_CONTENT3 = 48000;
2439
2431
  var MAX_DB_SIZE = 2 * 1024 * 1024 * 1024;
2440
2432
  var WARN_DB_SIZE = 500 * 1024 * 1024;
2441
2433
  var MIN_TURN_LEN2 = 50;
@@ -2551,22 +2543,7 @@ async function ingestCursor(dbPath, wasmDir) {
2551
2543
  const sessionName = parsed.name || "Cursor Chat";
2552
2544
  const date = parsed.createdAt ? new Date(parsed.createdAt).toISOString().slice(0, 10) : "unknown";
2553
2545
  const header = `# ${sessionName} | ${date}`;
2554
- const body = turns.map((t) => {
2555
- return `## Q: ${t.user}
2556
-
2557
- ${t.assistant}`;
2558
- }).join(`
2559
-
2560
- ---
2561
-
2562
- `);
2563
- let content = `${header}
2564
-
2565
- ${body}`;
2566
- if (content.length > MAX_CONTENT3)
2567
- content = content.slice(0, MAX_CONTENT3) + `
2568
-
2569
- [truncated]`;
2546
+ const content = fitContent(header, turns);
2570
2547
  const contentHash = createContentHash(content);
2571
2548
  const dedupKey = `cursor:${composerId}`;
2572
2549
  const fingerprint = `${dedupKey}:${contentHash}`;
@@ -2606,7 +2583,7 @@ import { existsSync as existsSync6, mkdirSync as mkdirSync2, readFileSync as rea
2606
2583
  import { dirname, join as join7 } from "node:path";
2607
2584
  import { homedir as homedir5, platform as platform5 } from "node:os";
2608
2585
  import { spawnSync } from "node:child_process";
2609
- var CONARE_URL = "https://mcp.conare.ai";
2586
+ var CONARE_URL = "https://conare.ai";
2610
2587
  var SERVER_NAME = "conare";
2611
2588
  var MCP_TARGETS = [
2612
2589
  { id: "claude", label: "Claude Code", defaultSelected: true },
@@ -2919,7 +2896,7 @@ Expected outcome: future \`recall\` calls surface the information automatically
2919
2896
 
2920
2897
  - Use \`after\`/\`before\` (Unix ms) for time-scoped searches: "what did we work on this week?"
2921
2898
  - Use \`containerTag\` to filter by source: \`claude-chats\`, \`codex-chats\`, \`cursor-chats\`, \`codebase\`, \`preferences\`
2922
- - Use \`project\` for cross-project filtering (partial names work: "conare" matches "fun/conare-memory-engine")
2899
+ - Use \`project\` for cross-project filtering (partial names work: "conare" matches "fun/conare")
2923
2900
  - Keep \`limit\` low (3-5) for focused results, higher (10-15) for broad exploration
2924
2901
  - When user asks to "remember" something, save it with \`save\` — it goes to the \`preferences\` container and gets surfaced by \`recall\` in future sessions
2925
2902
 
@@ -3115,31 +3092,6 @@ echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) START sync" >> "$LOG"
3115
3092
  2>> "$LOG"
3116
3093
  echo "$(date -u +%Y-%m-%dT%H:%M:%SZ) DONE sync (exit $?)" >> "$LOG"
3117
3094
  `;
3118
- function makePlist(intervalMinutes) {
3119
- const home = homedir7();
3120
- return `<?xml version="1.0" encoding="UTF-8"?>
3121
- <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
3122
- "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3123
- <plist version="1.0">
3124
- <dict>
3125
- <key>Label</key>
3126
- <string>${PLIST_LABEL}</string>
3127
- <key>ProgramArguments</key>
3128
- <array>
3129
- <string>/bin/bash</string>
3130
- <string>${home}/.conare/bin/run.sh</string>
3131
- </array>
3132
- <key>StartInterval</key>
3133
- <integer>${intervalMinutes * 60}</integer>
3134
- <key>StandardOutPath</key>
3135
- <string>${home}/.conare/ingest.log</string>
3136
- <key>StandardErrorPath</key>
3137
- <string>${home}/.conare/ingest.log</string>
3138
- <key>RunAtLoad</key>
3139
- <true/>
3140
- </dict>
3141
- </plist>`;
3142
- }
3143
3095
  var SYSTEMD_SERVICE_CONTENT = `[Unit]
3144
3096
  Description=Conare Memory — background sync
3145
3097
 
@@ -3241,22 +3193,12 @@ function findSqlJs() {
3241
3193
  }
3242
3194
  return null;
3243
3195
  }
3244
- function setupMacOS(intervalMinutes) {
3245
- const plistDir = dirname2(PLIST_PATH);
3246
- mkdirSync4(plistDir, { recursive: true });
3247
- writeFileSync4(PLIST_PATH, makePlist(intervalMinutes));
3248
- const id = uid();
3196
+ function cleanupOldLaunchAgent() {
3249
3197
  try {
3250
- execSync3(`launchctl bootout gui/${id} "${PLIST_PATH}" 2>/dev/null`, { stdio: "ignore" });
3198
+ execSync3(`launchctl bootout gui/${uid()} "${PLIST_PATH}" 2>/dev/null`, { stdio: "ignore" });
3251
3199
  } catch {}
3252
- try {
3253
- execSync3(`launchctl bootstrap gui/${id} "${PLIST_PATH}"`, { stdio: "ignore" });
3254
- } catch {
3255
- try {
3256
- execSync3(`launchctl load "${PLIST_PATH}"`, { stdio: "ignore" });
3257
- } catch {
3258
- throw new Error("Failed to load launchd agent. Try manually: launchctl load " + PLIST_PATH);
3259
- }
3200
+ if (existsSync8(PLIST_PATH)) {
3201
+ unlinkSync(PLIST_PATH);
3260
3202
  }
3261
3203
  }
3262
3204
  function setupLinuxSystemd(intervalMinutes) {
@@ -3266,13 +3208,30 @@ function setupLinuxSystemd(intervalMinutes) {
3266
3208
  execSync3("systemctl --user daemon-reload", { stdio: "ignore" });
3267
3209
  execSync3("systemctl --user enable --now conare-sync.timer", { stdio: "ignore" });
3268
3210
  }
3269
- function setupLinuxCron(intervalMinutes) {
3270
- const cronCmd = `${homedir7()}/.conare/bin/run.sh`;
3271
- const cronLine = `*/${intervalMinutes} * * * * ${cronCmd}`;
3211
+ var CRON_SAFE_INTERVALS = [1, 2, 3, 4, 5, 6, 10, 12, 15, 20, 30];
3212
+ function clampCronInterval(intervalMinutes) {
3213
+ const n = Number.isFinite(intervalMinutes) ? Math.round(intervalMinutes) : 10;
3214
+ if (n <= 0)
3215
+ return 10;
3216
+ let best = 10;
3217
+ let bestDist = Infinity;
3218
+ for (const safe of CRON_SAFE_INTERVALS) {
3219
+ const dist = Math.abs(n - safe);
3220
+ if (dist < bestDist) {
3221
+ bestDist = dist;
3222
+ best = safe;
3223
+ }
3224
+ }
3225
+ return best;
3226
+ }
3227
+ function setupCron(intervalMinutes) {
3228
+ const clamped = clampCronInterval(intervalMinutes);
3229
+ const cronCmd = `"${homedir7()}/.conare/bin/run.sh"`;
3230
+ const cronLine = `*/${clamped} * * * * ${cronCmd} # conare-sync`;
3272
3231
  try {
3273
3232
  const existing = execSync3("crontab -l 2>/dev/null", { encoding: "utf-8" });
3274
3233
  const filtered = existing.split(`
3275
- `).filter((l) => !l.includes("conare")).join(`
3234
+ `).filter((l) => !l.endsWith("# conare-sync") && !l.includes(".conare/bin/run.sh")).join(`
3276
3235
  `);
3277
3236
  const newCrontab = (filtered.trim() ? filtered.trim() + `
3278
3237
  ` : "") + cronLine + `
@@ -3283,6 +3242,47 @@ function setupLinuxCron(intervalMinutes) {
3283
3242
  `, stdio: ["pipe", "ignore", "ignore"] });
3284
3243
  }
3285
3244
  }
3245
+ function removeCronEntry() {
3246
+ try {
3247
+ const existing = execSync3("crontab -l 2>/dev/null", { encoding: "utf-8" });
3248
+ const lines = existing.split(`
3249
+ `);
3250
+ const filtered = lines.filter((l) => !l.endsWith("# conare-sync") && !l.includes(".conare/bin/run.sh"));
3251
+ if (filtered.length === lines.length)
3252
+ return false;
3253
+ const newCrontab = filtered.join(`
3254
+ `).trim();
3255
+ if (newCrontab) {
3256
+ execSync3("crontab -", { input: newCrontab + `
3257
+ `, stdio: ["pipe", "ignore", "ignore"] });
3258
+ } else {
3259
+ execSync3("crontab -", { input: `
3260
+ `, stdio: ["pipe", "ignore", "ignore"] });
3261
+ }
3262
+ return true;
3263
+ } catch {
3264
+ return false;
3265
+ }
3266
+ }
3267
+ function runSyncNow() {
3268
+ const os = platform6();
3269
+ try {
3270
+ if (os === "win32") {
3271
+ const runCmd = join9(BIN_DIR, "run.cmd");
3272
+ if (existsSync8(runCmd)) {
3273
+ execSync3(`"${runCmd}"`, { stdio: "ignore", timeout: 60000 });
3274
+ return true;
3275
+ }
3276
+ } else {
3277
+ const runSh = join9(BIN_DIR, "run.sh");
3278
+ if (existsSync8(runSh)) {
3279
+ execSync3(`/bin/bash "${runSh}"`, { stdio: "ignore", timeout: 60000 });
3280
+ return true;
3281
+ }
3282
+ }
3283
+ } catch {}
3284
+ return false;
3285
+ }
3286
3286
  function installGlobalCommand() {
3287
3287
  const isWindows = platform6() === "win32";
3288
3288
  if (isWindows) {
@@ -3398,13 +3398,20 @@ function persistAndInstallGlobal(apiKey) {
3398
3398
  messages.push(globalMsg);
3399
3399
  return messages;
3400
3400
  }
3401
+ function sanitizeInterval(n) {
3402
+ if (!Number.isFinite(n) || n <= 0)
3403
+ return 10;
3404
+ return Math.max(1, Math.round(n));
3405
+ }
3401
3406
  function installSync(apiKey, intervalMinutes = 10) {
3402
3407
  const messages = persistAndInstallGlobal(apiKey);
3403
3408
  const os = platform6();
3409
+ intervalMinutes = sanitizeInterval(intervalMinutes);
3404
3410
  if (os === "darwin") {
3405
- setupMacOS(intervalMinutes);
3406
- messages.push(`Installed launchd agent (every ${intervalMinutes} min)`);
3407
- messages.push(`Plist: ${PLIST_PATH}`);
3411
+ cleanupOldLaunchAgent();
3412
+ const actual = clampCronInterval(intervalMinutes);
3413
+ setupCron(intervalMinutes);
3414
+ messages.push(`Installed cron job (every ${actual} min)`);
3408
3415
  } else if (os === "win32") {
3409
3416
  setupWindows(intervalMinutes);
3410
3417
  messages.push(`Installed Windows Task Scheduler (every ${intervalMinutes} min)`);
@@ -3413,25 +3420,23 @@ function installSync(apiKey, intervalMinutes = 10) {
3413
3420
  setupLinuxSystemd(intervalMinutes);
3414
3421
  messages.push(`Installed systemd timer (every ${intervalMinutes} min)`);
3415
3422
  } else {
3416
- setupLinuxCron(intervalMinutes);
3417
- messages.push(`Installed cron job (every ${intervalMinutes} min)`);
3423
+ const actual = clampCronInterval(intervalMinutes);
3424
+ setupCron(intervalMinutes);
3425
+ messages.push(`Installed cron job (every ${actual} min)`);
3418
3426
  }
3419
3427
  } else {
3420
3428
  messages.push(`Unsupported platform: ${os}. Run manually: ~/.conare/bin/run.sh`);
3421
3429
  }
3430
+ const syncOk = runSyncNow();
3431
+ messages.push(syncOk ? "First sync completed" : "First sync deferred to next timer tick");
3422
3432
  return messages;
3423
3433
  }
3424
3434
  function uninstallSync() {
3425
3435
  const messages = [];
3426
3436
  const os = platform6();
3427
3437
  if (os === "darwin") {
3428
- try {
3429
- execSync3(`launchctl bootout gui/${uid()} "${PLIST_PATH}" 2>/dev/null`, { stdio: "ignore" });
3430
- } catch {}
3431
- if (existsSync8(PLIST_PATH)) {
3432
- unlinkSync(PLIST_PATH);
3433
- messages.push("Removed launchd agent");
3434
- }
3438
+ removeCronEntry() && messages.push("Removed cron job");
3439
+ cleanupOldLaunchAgent();
3435
3440
  } else if (os === "win32") {
3436
3441
  try {
3437
3442
  execSync3(`schtasks /Delete /TN "${TASK_NAME}" /F`, { stdio: "ignore" });
@@ -3451,25 +3456,18 @@ function uninstallSync() {
3451
3456
  } catch {}
3452
3457
  messages.push("Removed systemd timer");
3453
3458
  } else {
3454
- try {
3455
- const existing = execSync3("crontab -l 2>/dev/null", { encoding: "utf-8" });
3456
- const filtered = existing.split(`
3457
- `).filter((l) => !l.includes("conare")).join(`
3458
- `);
3459
- execSync3("crontab -", { input: filtered.trim() + `
3460
- `, stdio: ["pipe", "ignore", "ignore"] });
3461
- messages.push("Removed cron job");
3462
- } catch {}
3459
+ removeCronEntry() && messages.push("Removed cron job");
3463
3460
  }
3464
3461
  }
3465
- const filesToRemove = [
3466
- join9(CONARE_DIR, "config.json"),
3467
- join9(CONARE_DIR, "sync.lock")
3468
- ];
3469
- for (const f of filesToRemove) {
3470
- if (existsSync8(f))
3471
- unlinkSync(f);
3472
- }
3462
+ const configPath = join9(CONARE_DIR, "config.json");
3463
+ if (existsSync8(configPath))
3464
+ unlinkSync(configPath);
3465
+ const lockDir = join9(CONARE_DIR, "sync.lock.d");
3466
+ if (existsSync8(lockDir))
3467
+ rmSync2(lockDir, { recursive: true, force: true });
3468
+ const lockFile = join9(CONARE_DIR, "sync.lock");
3469
+ if (existsSync8(lockFile))
3470
+ unlinkSync(lockFile);
3473
3471
  if (existsSync8(BIN_DIR)) {
3474
3472
  rmSync2(BIN_DIR, { recursive: true, force: true });
3475
3473
  messages.push("Removed ~/.conare/bin/");
@@ -3493,14 +3491,14 @@ function printMissingKeyError() {
3493
3491
  console.error("Error: no API key configured.");
3494
3492
  console.error("");
3495
3493
  console.error("Run one of these:");
3496
- console.error(" bunx conare@latest --key YOUR_API_KEY");
3497
- console.error(" npx conare@latest --key YOUR_API_KEY");
3494
+ console.error(" npx conare@latest");
3495
+ console.error(" bunx conare@latest");
3498
3496
  console.error("");
3499
3497
  console.error("For a built-in command, install globally:");
3500
3498
  console.error(" bun add -g conare");
3501
3499
  console.error(" npm i -g conare");
3502
3500
  console.error("");
3503
- console.error("Get your API key at https://mcp.conare.ai");
3501
+ console.error("Get your API key at https://conare.ai");
3504
3502
  }
3505
3503
  function printFailureSummary(results, memories) {
3506
3504
  const failures = results.map((result, index) => ({ ...result, memory: memories[index] })).filter((result) => !result.success);
@@ -3619,7 +3617,7 @@ Options:
3619
3617
  --source <name> Only ingest from: claude, codex, cursor
3620
3618
  --wasm-dir <path> Path to sql.js module (for Cursor ingestion)
3621
3619
 
3622
- Get your API key at https://mcp.conare.ai
3620
+ Get your API key at https://conare.ai
3623
3621
  `);
3624
3622
  process.exit(0);
3625
3623
  }
@@ -3671,7 +3669,7 @@ async function runInstall() {
3671
3669
  }
3672
3670
  const auth = await validateKey(apiKey);
3673
3671
  if (!auth.valid) {
3674
- console.error("Invalid API key. Check your key at https://mcp.conare.ai");
3672
+ console.error("Invalid API key. Check your key at https://conare.ai");
3675
3673
  process.exit(1);
3676
3674
  }
3677
3675
  saveApiKey(apiKey);
@@ -3788,7 +3786,7 @@ async function main() {
3788
3786
  if (opts.installSync) {
3789
3787
  const auth2 = await validateKey(apiKey);
3790
3788
  if (!auth2.valid) {
3791
- console.error("Invalid API key. Check your key at https://mcp.conare.ai");
3789
+ console.error("Invalid API key. Check your key at https://conare.ai");
3792
3790
  process.exit(1);
3793
3791
  }
3794
3792
  const syncSpinner = Y2();
@@ -3801,7 +3799,7 @@ async function main() {
3801
3799
  log("");
3802
3800
  const auth = await validateKey(apiKey);
3803
3801
  if (!auth.valid) {
3804
- console.error("Invalid API key. Check your key at https://mcp.conare.ai");
3802
+ console.error("Invalid API key. Check your key at https://conare.ai");
3805
3803
  process.exit(1);
3806
3804
  }
3807
3805
  saveApiKey(apiKey);
@@ -3838,7 +3836,7 @@ async function main() {
3838
3836
  if (opts.force) {
3839
3837
  clearIngested("codebase");
3840
3838
  try {
3841
- await fetch("https://mcp.conare.ai/api/containers/codebase", {
3839
+ await fetch("https://conare.ai/api/containers/codebase", {
3842
3840
  method: "DELETE",
3843
3841
  headers: { Authorization: `Bearer ${apiKey}` }
3844
3842
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conare",
3
- "version": "0.4.4",
3
+ "version": "0.4.6",
4
4
  "description": "Conare CLI for ingesting AI chat history and configuring memory at conare.ai",
5
5
  "type": "module",
6
6
  "bin": {