conare 0.3.9 → 0.4.0

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 +277 -139
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -1575,27 +1575,23 @@ async function countCursorSessions(dbPath) {
1575
1575
  }
1576
1576
  async function detect() {
1577
1577
  const home = homedir();
1578
+ const os = platform();
1578
1579
  const tools = [];
1579
1580
  const claudeDir = join(home, ".claude", "projects");
1580
1581
  if (existsSync(claudeDir)) {
1581
1582
  const sessionCount = countJsonlFiles(claudeDir);
1582
- tools.push({
1583
- name: "Claude Code",
1584
- available: sessionCount > 0,
1585
- path: claudeDir,
1586
- sessionCount
1587
- });
1583
+ tools.push({ name: "Claude Code", id: "claude", available: sessionCount > 0, path: claudeDir, sessionCount });
1588
1584
  } else {
1589
- tools.push({ name: "Claude Code", available: false, path: claudeDir, sessionCount: 0 });
1585
+ tools.push({ name: "Claude Code", id: "claude", available: false, path: claudeDir, sessionCount: 0 });
1590
1586
  }
1587
+ const codexConfig = join(home, ".codex", "config.toml");
1591
1588
  const codexHistory = join(home, ".codex", "history.jsonl");
1592
1589
  const codexSessions = join(home, ".codex", "sessions");
1593
- if (existsSync(codexHistory) || existsSync(codexSessions)) {
1590
+ if (existsSync(codexConfig) || existsSync(codexHistory) || existsSync(codexSessions)) {
1594
1591
  let sessionCount = 0;
1595
1592
  if (existsSync(codexHistory)) {
1596
1593
  try {
1597
- const { readFileSync: readFileSync2 } = __require("node:fs");
1598
- const lines = readFileSync2(codexHistory, "utf-8").split(`
1594
+ const lines = readFileSync(codexHistory, "utf-8").split(`
1599
1595
  `).filter(Boolean);
1600
1596
  const sessions = new Set(lines.map((l) => {
1601
1597
  try {
@@ -1608,16 +1604,10 @@ async function detect() {
1608
1604
  sessionCount = sessions.size;
1609
1605
  } catch {}
1610
1606
  }
1611
- tools.push({
1612
- name: "Codex",
1613
- available: true,
1614
- path: existsSync(codexHistory) ? codexHistory : codexSessions,
1615
- sessionCount
1616
- });
1607
+ tools.push({ name: "Codex", id: "codex", available: true, path: codexConfig, sessionCount });
1617
1608
  } else {
1618
- tools.push({ name: "Codex", available: false, path: codexHistory, sessionCount: 0 });
1609
+ tools.push({ name: "Codex", id: "codex", available: false, path: codexConfig, sessionCount: 0 });
1619
1610
  }
1620
- const os = platform();
1621
1611
  let cursorDbPath;
1622
1612
  if (os === "darwin") {
1623
1613
  cursorDbPath = join(home, "Library", "Application Support", "Cursor", "User", "globalStorage", "state.vscdb");
@@ -1628,10 +1618,65 @@ async function detect() {
1628
1618
  }
1629
1619
  tools.push({
1630
1620
  name: "Cursor",
1621
+ id: "cursor",
1631
1622
  available: existsSync(cursorDbPath),
1632
1623
  path: cursorDbPath,
1633
1624
  sessionCount: existsSync(cursorDbPath) ? await countCursorSessions(cursorDbPath) : 0
1634
1625
  });
1626
+ const windsurfDir = join(home, ".codeium", "windsurf");
1627
+ tools.push({
1628
+ name: "Windsurf",
1629
+ id: "windsurf",
1630
+ available: existsSync(windsurfDir),
1631
+ path: join(windsurfDir, "mcp_config.json"),
1632
+ sessionCount: 0
1633
+ });
1634
+ let vscodePath;
1635
+ if (os === "darwin") {
1636
+ vscodePath = join(home, "Library", "Application Support", "Code");
1637
+ } else if (os === "win32") {
1638
+ vscodePath = join(process.env.APPDATA || join(home, "AppData", "Roaming"), "Code");
1639
+ } else {
1640
+ vscodePath = join(home, ".config", "Code");
1641
+ }
1642
+ tools.push({
1643
+ name: "VS Code Copilot",
1644
+ id: "vscode",
1645
+ available: existsSync(vscodePath),
1646
+ path: join(vscodePath, "User", "mcp.json"),
1647
+ sessionCount: 0
1648
+ });
1649
+ let clinePath;
1650
+ if (os === "darwin") {
1651
+ clinePath = join(home, "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev");
1652
+ } else if (os === "win32") {
1653
+ clinePath = join(process.env.APPDATA || join(home, "AppData", "Roaming"), "Code", "User", "globalStorage", "saoudrizwan.claude-dev");
1654
+ } else {
1655
+ clinePath = join(home, ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev");
1656
+ }
1657
+ tools.push({
1658
+ name: "Cline",
1659
+ id: "cline",
1660
+ available: existsSync(clinePath),
1661
+ path: join(clinePath, "settings", "cline_mcp_settings.json"),
1662
+ sessionCount: 0
1663
+ });
1664
+ const zedPath = os === "darwin" ? join(home, ".zed") : join(home, ".config", "zed");
1665
+ tools.push({
1666
+ name: "Zed",
1667
+ id: "zed",
1668
+ available: existsSync(zedPath),
1669
+ path: join(zedPath, "settings.json"),
1670
+ sessionCount: 0
1671
+ });
1672
+ const openclawDir = join(home, ".openclaw");
1673
+ tools.push({
1674
+ name: "OpenClaw",
1675
+ id: "openclaw",
1676
+ available: existsSync(openclawDir),
1677
+ path: join(openclawDir, "openclaw.json"),
1678
+ sessionCount: 0
1679
+ });
1635
1680
  return tools;
1636
1681
  }
1637
1682
 
@@ -2240,9 +2285,14 @@ import { spawnSync } from "node:child_process";
2240
2285
  var CONARE_URL = "https://mcp.conare.ai";
2241
2286
  var SERVER_NAME = "conare";
2242
2287
  var MCP_TARGETS = [
2243
- { id: "claude", label: "Claude Code" },
2244
- { id: "cursor", label: "Cursor" },
2245
- { id: "codex", label: "Codex" }
2288
+ { id: "claude", label: "Claude Code", defaultSelected: true },
2289
+ { id: "codex", label: "Codex", defaultSelected: true },
2290
+ { id: "cursor", label: "Cursor", defaultSelected: false },
2291
+ { id: "windsurf", label: "Windsurf", defaultSelected: false },
2292
+ { id: "vscode", label: "VS Code Copilot", defaultSelected: false },
2293
+ { id: "cline", label: "Cline", defaultSelected: false },
2294
+ { id: "zed", label: "Zed", defaultSelected: false },
2295
+ { id: "openclaw", label: "OpenClaw", defaultSelected: false }
2246
2296
  ];
2247
2297
  function readJsonFile(path) {
2248
2298
  try {
@@ -2265,14 +2315,6 @@ function getServerConfig(apiKey) {
2265
2315
  }
2266
2316
  };
2267
2317
  }
2268
- function upsertMcpServer(path, apiKey) {
2269
- const config = readJsonFile(path);
2270
- if (!config.mcpServers || typeof config.mcpServers !== "object") {
2271
- config.mcpServers = {};
2272
- }
2273
- config.mcpServers[SERVER_NAME] = getServerConfig(apiKey);
2274
- writeJsonFile(path, config);
2275
- }
2276
2318
  function configureClaude(apiKey) {
2277
2319
  const claudeConfigPath = join7(homedir5(), ".claude.json");
2278
2320
  const claudeMcpPath = join7(homedir5(), ".claude", "mcp.json");
@@ -2282,16 +2324,193 @@ function configureClaude(apiKey) {
2282
2324
  }).status === 0) {
2283
2325
  return "Claude Code configured via `claude mcp add-json`";
2284
2326
  }
2285
- upsertMcpServer(claudeConfigPath, apiKey);
2327
+ const config = readJsonFile(claudeConfigPath);
2328
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2329
+ config.mcpServers = {};
2330
+ }
2331
+ config.mcpServers[SERVER_NAME] = getServerConfig(apiKey);
2332
+ writeJsonFile(claudeConfigPath, config);
2286
2333
  if (existsSync6(join7(homedir5(), ".claude"))) {
2287
- upsertMcpServer(claudeMcpPath, apiKey);
2334
+ const mcpConfig = readJsonFile(claudeMcpPath);
2335
+ if (!mcpConfig.mcpServers || typeof mcpConfig.mcpServers !== "object") {
2336
+ mcpConfig.mcpServers = {};
2337
+ }
2338
+ mcpConfig.mcpServers[SERVER_NAME] = getServerConfig(apiKey);
2339
+ writeJsonFile(claudeMcpPath, mcpConfig);
2288
2340
  }
2289
2341
  return `Claude Code configured at ${claudeConfigPath}`;
2290
2342
  }
2291
- function configureJsonClient(path, apiKey, label) {
2292
- upsertMcpServer(path, apiKey);
2293
- return `${label} configured at ${path}`;
2343
+ function configureCodex(apiKey) {
2344
+ const configPath = join7(homedir5(), ".codex", "config.toml");
2345
+ if (spawnSync("codex", ["mcp", "add", SERVER_NAME, "--url", `${CONARE_URL}/mcp`, "--header", `Authorization: Bearer ${apiKey}`], {
2346
+ stdio: "ignore",
2347
+ shell: platform5() === "win32"
2348
+ }).status === 0) {
2349
+ return "Codex configured via `codex mcp add`";
2350
+ }
2351
+ let toml = "";
2352
+ try {
2353
+ toml = readFileSync7(configPath, "utf-8");
2354
+ } catch {}
2355
+ const sectionHeader = `[mcp_servers.${SERVER_NAME}]`;
2356
+ const newSection = [
2357
+ sectionHeader,
2358
+ `url = "${CONARE_URL}/mcp"`,
2359
+ `enabled = true`,
2360
+ "",
2361
+ `[mcp_servers.${SERVER_NAME}.http_headers]`,
2362
+ `"Authorization" = "Bearer ${apiKey}"`
2363
+ ].join(`
2364
+ `);
2365
+ const sectionRegex = new RegExp(`\\[mcp_servers\\.${SERVER_NAME}(?:\\.[^\\]]*)?\\][^\\[]*`, "g");
2366
+ const cleaned = toml.replace(sectionRegex, "").replace(/\n{3,}/g, `
2367
+
2368
+ `).trim();
2369
+ const result = cleaned ? `${cleaned}
2370
+
2371
+ ${newSection}
2372
+ ` : `${newSection}
2373
+ `;
2374
+ mkdirSync2(dirname(configPath), { recursive: true });
2375
+ writeFileSync2(configPath, result);
2376
+ const oldMcpJson = join7(homedir5(), ".codex", "mcp.json");
2377
+ try {
2378
+ if (existsSync6(oldMcpJson)) {
2379
+ const old = readJsonFile(oldMcpJson);
2380
+ const servers = old.mcpServers;
2381
+ if (servers && (("conare" in servers) || ("conare-memory" in servers))) {
2382
+ delete servers["conare"];
2383
+ delete servers["conare-memory"];
2384
+ if (Object.keys(servers).length === 0) {
2385
+ rmSync(oldMcpJson);
2386
+ } else {
2387
+ writeJsonFile(oldMcpJson, old);
2388
+ }
2389
+ }
2390
+ }
2391
+ } catch {}
2392
+ return `Codex configured at ${configPath}`;
2393
+ }
2394
+ function configureCursor(apiKey) {
2395
+ const configPath = join7(homedir5(), ".cursor", "mcp.json");
2396
+ const config = readJsonFile(configPath);
2397
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2398
+ config.mcpServers = {};
2399
+ }
2400
+ config.mcpServers[SERVER_NAME] = {
2401
+ url: `${CONARE_URL}/mcp`,
2402
+ headers: { Authorization: `Bearer ${apiKey}` }
2403
+ };
2404
+ writeJsonFile(configPath, config);
2405
+ return `Cursor configured at ${configPath}`;
2406
+ }
2407
+ function configureWindsurf(apiKey) {
2408
+ const configPath = join7(homedir5(), ".codeium", "windsurf", "mcp_config.json");
2409
+ const config = readJsonFile(configPath);
2410
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2411
+ config.mcpServers = {};
2412
+ }
2413
+ config.mcpServers[SERVER_NAME] = {
2414
+ serverUrl: `${CONARE_URL}/mcp`,
2415
+ headers: { Authorization: `Bearer ${apiKey}` }
2416
+ };
2417
+ writeJsonFile(configPath, config);
2418
+ return `Windsurf configured at ${configPath}`;
2419
+ }
2420
+ function configureVscode(apiKey) {
2421
+ const os = platform5();
2422
+ let configPath;
2423
+ if (os === "darwin") {
2424
+ configPath = join7(homedir5(), "Library", "Application Support", "Code", "User", "mcp.json");
2425
+ } else if (os === "win32") {
2426
+ configPath = join7(process.env.APPDATA || join7(homedir5(), "AppData", "Roaming"), "Code", "User", "mcp.json");
2427
+ } else {
2428
+ configPath = join7(homedir5(), ".config", "Code", "User", "mcp.json");
2429
+ }
2430
+ const config = readJsonFile(configPath);
2431
+ if (!config.servers || typeof config.servers !== "object") {
2432
+ config.servers = {};
2433
+ }
2434
+ config.servers[SERVER_NAME] = {
2435
+ type: "http",
2436
+ url: `${CONARE_URL}/mcp`,
2437
+ headers: { Authorization: `Bearer ${apiKey}` }
2438
+ };
2439
+ writeJsonFile(configPath, config);
2440
+ return `VS Code Copilot configured at ${configPath}`;
2441
+ }
2442
+ function configureCline(apiKey) {
2443
+ const os = platform5();
2444
+ let configPath;
2445
+ if (os === "darwin") {
2446
+ configPath = join7(homedir5(), "Library", "Application Support", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
2447
+ } else if (os === "win32") {
2448
+ configPath = join7(process.env.APPDATA || join7(homedir5(), "AppData", "Roaming"), "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
2449
+ } else {
2450
+ configPath = join7(homedir5(), ".config", "Code", "User", "globalStorage", "saoudrizwan.claude-dev", "settings", "cline_mcp_settings.json");
2451
+ }
2452
+ const config = readJsonFile(configPath);
2453
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2454
+ config.mcpServers = {};
2455
+ }
2456
+ config.mcpServers[SERVER_NAME] = {
2457
+ url: `${CONARE_URL}/mcp`,
2458
+ headers: { Authorization: `Bearer ${apiKey}` },
2459
+ disabled: false
2460
+ };
2461
+ writeJsonFile(configPath, config);
2462
+ return `Cline configured at ${configPath}`;
2463
+ }
2464
+ function configureZed(apiKey) {
2465
+ const os = platform5();
2466
+ let configPath;
2467
+ if (os === "darwin") {
2468
+ configPath = join7(homedir5(), ".zed", "settings.json");
2469
+ } else {
2470
+ configPath = join7(homedir5(), ".config", "zed", "settings.json");
2471
+ }
2472
+ const config = readJsonFile(configPath);
2473
+ if (!config.context_servers || typeof config.context_servers !== "object") {
2474
+ config.context_servers = {};
2475
+ }
2476
+ config.context_servers[SERVER_NAME] = {
2477
+ command: "npx",
2478
+ args: [
2479
+ "-y",
2480
+ "mcp-remote",
2481
+ `${CONARE_URL}/mcp`,
2482
+ "--header",
2483
+ `Authorization:Bearer ${apiKey}`
2484
+ ],
2485
+ env: {}
2486
+ };
2487
+ writeJsonFile(configPath, config);
2488
+ return `Zed configured at ${configPath}`;
2294
2489
  }
2490
+ function configureOpenclaw(apiKey) {
2491
+ const configPath = join7(homedir5(), ".openclaw", "openclaw.json");
2492
+ const config = readJsonFile(configPath);
2493
+ if (!config.mcpServers || typeof config.mcpServers !== "object") {
2494
+ config.mcpServers = {};
2495
+ }
2496
+ config.mcpServers[SERVER_NAME] = {
2497
+ type: "streamable-http",
2498
+ url: `${CONARE_URL}/mcp`,
2499
+ headers: { Authorization: `Bearer ${apiKey}` }
2500
+ };
2501
+ writeJsonFile(configPath, config);
2502
+ return `OpenClaw configured at ${configPath}`;
2503
+ }
2504
+ var CLIENT_CONFIGURATORS = {
2505
+ claude: configureClaude,
2506
+ codex: configureCodex,
2507
+ cursor: configureCursor,
2508
+ windsurf: configureWindsurf,
2509
+ vscode: configureVscode,
2510
+ cline: configureCline,
2511
+ zed: configureZed,
2512
+ openclaw: configureOpenclaw
2513
+ };
2295
2514
  var SKILL_MD = `---
2296
2515
  name: conare
2297
2516
  description: Complements the Conare MCP server by teaching the agent when and how to load prior project context, search past sessions, save durable preferences, list stored memories, and forget saved items. Use when the user asks what they worked on before, wants prior context loaded at the start of a task, asks to remember or forget something, or needs past conversations, decisions, or code recalled from memory.
@@ -2365,95 +2584,6 @@ Expected outcome: future \`recall\` calls surface the information automatically
2365
2584
  - Keep \`limit\` low (3-5) for focused results, higher (10-15) for broad exploration
2366
2585
  - When user asks to "remember" something, save it with \`save\` — it goes to the \`preferences\` container and gets surfaced by \`recall\` in future sessions
2367
2586
 
2368
- ## Examples
2369
-
2370
- ### Example 1: Start with context
2371
-
2372
- User says: "Help me continue the OAuth migration in this repo."
2373
-
2374
- Actions:
2375
- 1. Call \`recall\` with context like "continue OAuth migration in the current repository".
2376
- 2. Review returned memories for prior migration decisions, unresolved blockers, and saved preferences.
2377
- 3. Proceed with implementation using that context.
2378
-
2379
- Result: the agent starts with the relevant project history instead of asking the user to restate it.
2380
-
2381
- ### Example 2: Find prior work
2382
-
2383
- User says: "What did we decide last week about billing webhooks?"
2384
-
2385
- Actions:
2386
- 1. Call \`search\` with a descriptive query such as "billing webhook decision refunds retries last week".
2387
- 2. If results are weak, retry with alternatives like "refund webhook handling" or "billing retry policy".
2388
- 3. Summarize the decision and note uncertainty if memories conflict.
2389
-
2390
- Result: the agent retrieves prior decisions from memory rather than guessing.
2391
-
2392
- ### Example 3: Save a durable preference
2393
-
2394
- User says: "Remember that I prefer ripgrep over grep."
2395
-
2396
- Actions:
2397
- 1. Call \`save\` with the preference in durable wording.
2398
- 2. Confirm the preference was saved.
2399
-
2400
- Result: future \`recall\` results can surface that preference automatically.
2401
-
2402
- ## Troubleshooting
2403
-
2404
- ### Weak or irrelevant search results
2405
-
2406
- Cause:
2407
- - Query is too short or too generic.
2408
- - Search needs a different phrasing or time scope.
2409
-
2410
- Response:
2411
- 1. Rewrite the query with concrete nouns, entities, and actions.
2412
- 2. Add \`after\`/\`before\` when the user implies a time window.
2413
- 3. Add \`project\` or \`containerTag\` when the scope is known.
2414
-
2415
- ### \`recall\` returns little useful context
2416
-
2417
- Cause:
2418
- - Conversation context passed to \`recall\` was too vague.
2419
- - The project parameter was omitted when it should have been included.
2420
-
2421
- Response:
2422
- 1. Retry \`recall\` with a more specific task description.
2423
- 2. Include \`project\` if the workspace or repository is known.
2424
- 3. Fall back to \`search\` for the exact topic the user cares about.
2425
-
2426
- ### Unsure whether to save something
2427
-
2428
- Cause:
2429
- - The information may be temporary rather than durable.
2430
-
2431
- Response:
2432
- 1. Save it when it is likely to help in future sessions, especially if it reflects a preference, rule, decision, or durable project fact.
2433
- 2. Skip only clearly transient implementation notes unless the user explicitly asks to retain them.
2434
-
2435
- ## Triggering Tests
2436
-
2437
- Use these tests to validate whether the skill description is tuned correctly.
2438
-
2439
- Should trigger:
2440
- - "What did we work on in this repo last week?"
2441
- - "Load context for the auth refactor before we continue."
2442
- - "Remember that I prefer pnpm in JavaScript projects."
2443
- - "Forget the note about using staging Stripe keys."
2444
- - "Search my past sessions for the DO migration fix."
2445
-
2446
- Should not trigger:
2447
- - "Write a sorting function in TypeScript."
2448
- - "What is the weather in San Francisco?"
2449
- - "Explain how PostgreSQL indexes work."
2450
- - "Create a landing page from this mockup."
2451
-
2452
- Success criteria:
2453
- - Triggers on memory-oriented requests and start-of-task context loading.
2454
- - Does not trigger on generic coding or research tasks with no memory component.
2455
- - Uses \`recall\` first for new task continuation, and uses \`search\` only when the user asks about specific past work.
2456
-
2457
2587
  ## Setup
2458
2588
 
2459
2589
  Install with a single command:
@@ -2486,16 +2616,17 @@ function installSkill() {
2486
2616
  } catch {}
2487
2617
  return "Agent Skill installed";
2488
2618
  }
2489
- function configureMcp(apiKey, targets = ["claude", "cursor", "codex"]) {
2619
+ function configureMcp(apiKey, targets = ["claude", "codex"]) {
2490
2620
  const results = [];
2491
- if (targets.includes("claude")) {
2492
- results.push(configureClaude(apiKey));
2493
- }
2494
- if (targets.includes("cursor")) {
2495
- results.push(configureJsonClient(join7(homedir5(), ".cursor", "mcp.json"), apiKey, "Cursor"));
2496
- }
2497
- if (targets.includes("codex")) {
2498
- results.push(configureJsonClient(join7(homedir5(), ".codex", "mcp.json"), apiKey, "Codex"));
2621
+ for (const target of targets) {
2622
+ const configurator = CLIENT_CONFIGURATORS[target];
2623
+ if (configurator) {
2624
+ try {
2625
+ results.push(configurator(apiKey));
2626
+ } catch (e) {
2627
+ results.push(`${target}: failed — ${e.message}`);
2628
+ }
2629
+ }
2499
2630
  }
2500
2631
  try {
2501
2632
  results.push(installSkill());
@@ -3132,10 +3263,13 @@ conare — AI memory for your coding tools
3132
3263
 
3133
3264
  Usage:
3134
3265
  conare Interactive setup with browser auth
3135
- conare install Just install the MCP
3266
+ conare install Just install the MCP (all detected clients)
3136
3267
  conare --key <api_key> Ingest chat history (key optional with browser auth)
3137
3268
  conare --key <api_key> --index [path] Index codebase
3138
3269
 
3270
+ Supported clients:
3271
+ Claude Code, Codex, Cursor, Windsurf, VS Code Copilot, Cline, Zed, OpenClaw
3272
+
3139
3273
  Options:
3140
3274
  --key <key> Your Conare API key (optional if using browser auth, starts with cmem_)
3141
3275
  --config-file <path> Read API key from JSON config file (e.g. ~/.conare/config.json)
@@ -3210,8 +3344,12 @@ async function runInstall() {
3210
3344
  process.exit(1);
3211
3345
  }
3212
3346
  saveApiKey(apiKey);
3213
- const allTargets = MCP_TARGETS.map((t) => t.id);
3214
- const lines = configureMcp(apiKey, allTargets);
3347
+ const detectedTools = await detect();
3348
+ const targets = MCP_TARGETS.filter((t) => {
3349
+ const detected = detectedTools.find((d3) => d3.id === t.id);
3350
+ return detected?.available || t.defaultSelected;
3351
+ }).map((t) => t.id);
3352
+ const lines = configureMcp(apiKey, targets);
3215
3353
  for (const line of lines)
3216
3354
  console.log(` ${line}`);
3217
3355
  console.log("");
@@ -3243,7 +3381,7 @@ async function main() {
3243
3381
  const savedApiKey = getSavedApiKey();
3244
3382
  const hasTty = !!process.stdin.isTTY && !!process.stdout.isTTY;
3245
3383
  const shouldRunInteractive = hasTty && !opts.dryRun && !opts.quiet && (opts.interactive || !opts.force && !opts.source && !opts.indexPath && !opts.configOnly && !opts.ingestOnly && !opts.wasmDir);
3246
- let selectedTargets = MCP_TARGETS.map((target) => target.id);
3384
+ let selectedTargets = MCP_TARGETS.filter((t) => t.defaultSelected).map((t) => t.id);
3247
3385
  let effectiveConfigOnly = opts.configOnly;
3248
3386
  let effectiveIngestOnly = opts.ingestOnly;
3249
3387
  let effectiveIndexPath = opts.indexPath;
@@ -3254,19 +3392,19 @@ async function main() {
3254
3392
  id: target.id,
3255
3393
  label: target.label,
3256
3394
  available: true,
3257
- recommended: true,
3395
+ recommended: target.defaultSelected,
3258
3396
  detectedCount: undefined
3259
3397
  }));
3260
3398
  let interactiveMode = false;
3261
3399
  if (shouldRunInteractive) {
3262
3400
  const detectedTools = await detect();
3263
3401
  interactiveTargets = MCP_TARGETS.map((target) => {
3264
- const detected = detectedTools.find((tool) => target.id === "claude" && tool.name === "Claude Code" || target.id === "cursor" && tool.name === "Cursor" || target.id === "codex" && tool.name === "Codex");
3402
+ const detected = detectedTools.find((tool) => tool.id === target.id);
3265
3403
  return {
3266
3404
  id: target.id,
3267
3405
  label: target.label,
3268
3406
  available: detected?.available,
3269
- recommended: detected?.available !== false,
3407
+ recommended: target.defaultSelected && detected?.available !== false,
3270
3408
  detectedCount: detected?.sessionCount
3271
3409
  };
3272
3410
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "conare",
3
- "version": "0.3.9",
3
+ "version": "0.4.0",
4
4
  "description": "Conare CLI for ingesting AI chat history and configuring memory at conare.ai",
5
5
  "type": "module",
6
6
  "bin": {