@simplexlat/memhub 0.1.2 → 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/cli.js CHANGED
@@ -753,7 +753,8 @@ var CloudApiClient = class {
753
753
  headers: this.getHeaders(),
754
754
  body: JSON.stringify({ slug: "__health_check__" })
755
755
  });
756
- return { ok: res.ok || res.status === 401 || res.status === 400, status: res.status };
756
+ const reachable = res.ok || res.status === 400 || res.status === 401 || res.status === 429;
757
+ return { ok: reachable, status: res.status, message: reachable ? void 0 : `HTTP ${res.status}` };
757
758
  } catch (err) {
758
759
  return { ok: false, status: 0, message: err.message };
759
760
  }
@@ -1361,17 +1362,17 @@ var MEMHUB_PROTOCOL_INSTRUCTIONS = `${MEMHUB_RULES_BEGIN_MARKER}
1361
1362
 
1362
1363
  ## MemHub Persistent Shared Memory \u2014 Protocol
1363
1364
 
1364
- You have access to MemHub, a persistent memory and team knowledge system that survives across sessions, compactions, and teammates.
1365
+ You have access to MemHub, a persistent memory and team knowledge system that survives across sessions, compactions, teammates, and repositories.
1365
1366
 
1366
1367
  ### WHEN TO SAVE TO MEMORY (mandatory \u2014 not optional)
1367
1368
 
1368
- Call \`mem_save\` (or \`memory_save\`) IMMEDIATELY after any of these:
1369
+ You must autonomously call \`mem_save\` (or \`memory_save\`) IMMEDIATELY after any of these events without asking the user:
1369
1370
  - Bug fix completed
1370
1371
  - Architecture or design decision made
1371
- - Non-obvious discovery about the codebase
1372
- - Configuration change or environment setup
1372
+ - Non-obvious discovery about the codebase or dependencies
1373
+ - Configuration change, environment setup, or deployment step
1373
1374
  - Pattern established (naming, structure, convention)
1374
- - User preference or team constraint learned
1375
+ - User preference, constraint, or requirement learned
1375
1376
 
1376
1377
  Format for \`mem_save\`:
1377
1378
  - **title**: Verb + what \u2014 short, searchable (e.g. "Fixed N+1 query in UserList", "Chose Zustand over Redux")
@@ -1384,29 +1385,57 @@ Format for \`mem_save\`:
1384
1385
  **Where**: Files or paths affected
1385
1386
  **Learned**: Gotchas, edge cases, things that surprised you (omit if none)
1386
1387
 
1388
+ ### MULTI-PROJECT & NEW REPOSITORY AUTONOMY
1389
+
1390
+ MemHub automatically detects the Git repository and folder context. When you save a memory in a new repository or workspace, MemHub autonomously connects it to the user's organization in the cloud dashboard and links all memories.
1391
+
1392
+ ### Topic update rules (mandatory)
1393
+
1394
+ - Different topics must not overwrite each other (e.g. architecture vs bugfix)
1395
+ - Reuse the same \`topic_key\` to update an evolving topic instead of creating duplicate fragmented observations
1396
+ - If unsure about the key, call \`mem_suggest_topic_key\` first and reuse it
1397
+ - Use \`mem_update\` when you have an exact observation ID to update
1398
+
1387
1399
  ### WHEN TO SEARCH MEMORY (mandatory)
1388
1400
 
1389
- When the user asks to recall something or references past work ("remember", "recall", "what did we do", "c\xF3mo lo resolvimos", "qu\xE9 hicimos"):
1401
+ When the user asks to recall something or references past work ("remember", "recall", "what did we do", "c\xF3mo lo resolvimos", "qu\xE9 hicimos", or past session context):
1390
1402
  1. First call \`mem_context\` (fast recent session history)
1391
1403
  2. Call \`mem_search\` (or \`memory_recall\`) with relevant keywords (hybrid lexical + vector search)
1392
1404
  3. If needed, use \`mem_get_observation\` for full untruncated content
1393
1405
 
1394
1406
  Also search memory PROACTIVELY when:
1395
1407
  - Starting work on an unfamiliar area of the codebase
1396
- - The user mentions a technical topic you have no context on
1408
+ - The user mentions a technical topic you have no context on \u2014 check if past sessions covered it
1397
1409
 
1398
1410
  ### SESSION CLOSE PROTOCOL (mandatory)
1399
1411
 
1400
- Before ending a session or declaring a milestone done, call \`mem_session_summary\`:
1401
- - **Goal**: What was worked on this session
1402
- - **Discoveries**: Technical findings and gotchas
1403
- - **Accomplished**: Key completed items
1404
- - **Next Steps**: What remains for subsequent sessions
1405
- - **Relevant Files**: Changed files and their purpose
1412
+ Before ending a session or declaring a milestone done, you MUST call \`mem_session_summary\` with this structure:
1413
+
1414
+ ## Goal
1415
+ [What was worked on this session]
1416
+
1417
+ ## Instructions
1418
+ [User preferences or constraints discovered \u2014 skip if none]
1419
+
1420
+ ## Discoveries
1421
+ - [Technical findings, gotchas, non-obvious learnings]
1422
+
1423
+ ## Accomplished
1424
+ - [Completed items with key details]
1425
+
1426
+ ## Next Steps
1427
+ - [What remains to be done \u2014 for the next session]
1428
+
1429
+ ## Relevant Files
1430
+ - path/to/file \u2014 [what it does or what changed]
1406
1431
 
1407
1432
  ### PASSIVE CAPTURE
1408
1433
 
1409
- When completing a task, include a \`## Key Learnings:\` section at the end of your response with numbered items. MemHub will automatically capture and persist these learnings for the team.
1434
+ When completing a task or subtask, include a \`## Key Learnings:\` section at the end of your response with numbered items. MemHub will automatically capture and persist these learnings for the team.
1435
+
1436
+ ### AFTER COMPACTION
1437
+
1438
+ If context reset or compaction occurs, immediately call \`mem_session_summary\` to persist the compacted summary, then call \`mem_context\` to recover previous session context.
1410
1439
 
1411
1440
  ${MEMHUB_RULES_END_MARKER}`;
1412
1441
  var RulesInjector = class {
@@ -1463,7 +1492,8 @@ ${MEMHUB_PROTOCOL_INSTRUCTIONS}
1463
1492
  const cursorRules = this.injectIntoFile(path4.join(cwd, ".cursorrules"), "Cursor (.cursorrules)");
1464
1493
  const mdcPath = path4.join(cwd, ".cursor", "rules", "memhub.mdc");
1465
1494
  const mdc = this.injectIntoFile(mdcPath, "Cursor MDC (.cursor/rules/memhub.mdc)");
1466
- return [cursorRules, mdc];
1495
+ const globalCursor = this.injectIntoFile(path4.join(os2.homedir(), ".cursorrules"), "Cursor (Global .cursorrules)");
1496
+ return [cursorRules, mdc, globalCursor];
1467
1497
  }
1468
1498
  /**
1469
1499
  * Injects rules for Google Antigravity / Gemini CLI
@@ -1482,13 +1512,17 @@ ${MEMHUB_PROTOCOL_INSTRUCTIONS}
1482
1512
  * Injects rules for Windsurf (`.windsurfrules`)
1483
1513
  */
1484
1514
  static injectWindsurf(cwd = process.cwd()) {
1485
- return [this.injectIntoFile(path4.join(cwd, ".windsurfrules"), "Windsurf (.windsurfrules)")];
1515
+ const local = this.injectIntoFile(path4.join(cwd, ".windsurfrules"), "Windsurf (.windsurfrules)");
1516
+ const global = this.injectIntoFile(path4.join(os2.homedir(), ".windsurfrules"), "Windsurf (Global .windsurfrules)");
1517
+ return [local, global];
1486
1518
  }
1487
1519
  /**
1488
1520
  * Injects rules for Cline / Roo Code (`.clinerules`)
1489
1521
  */
1490
1522
  static injectCline(cwd = process.cwd()) {
1491
- return [this.injectIntoFile(path4.join(cwd, ".clinerules"), "Cline (.clinerules)")];
1523
+ const local = this.injectIntoFile(path4.join(cwd, ".clinerules"), "Cline (.clinerules)");
1524
+ const global = this.injectIntoFile(path4.join(os2.homedir(), ".clinerules"), "Cline (Global .clinerules)");
1525
+ return [local, global];
1492
1526
  }
1493
1527
  /**
1494
1528
  * Injects rules for Codex CLI & General Agent specification (`AGENTS.md`)
@@ -1499,7 +1533,7 @@ ${MEMHUB_PROTOCOL_INSTRUCTIONS}
1499
1533
  return [localAgents, globalCodex];
1500
1534
  }
1501
1535
  /**
1502
- * Injects rules across all supported AI coding agents.
1536
+ * Injects rules across all supported AI coding agents globally and locally.
1503
1537
  */
1504
1538
  static injectAll(cwd = process.cwd()) {
1505
1539
  return [
@@ -1714,7 +1748,7 @@ import path7 from "node:path";
1714
1748
  import fs6 from "fs";
1715
1749
  import path6 from "path";
1716
1750
  import https from "https";
1717
- var CHECK_INTERVAL_MS = 6 * 60 * 60 * 1e3;
1751
+ var CHECK_INTERVAL_MS = 2 * 60 * 60 * 1e3;
1718
1752
  var PACKAGE_NAME = "@simplexlat/memhub";
1719
1753
  function compareVersions(v1, v2) {
1720
1754
  const parts1 = v1.split(".").map((p) => parseInt(p, 10) || 0);
@@ -1733,7 +1767,7 @@ async function fetchLatestFromNpm() {
1733
1767
  `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,
1734
1768
  {
1735
1769
  headers: { "User-Agent": "memhub-cli" },
1736
- timeout: 1500
1770
+ timeout: 2e3
1737
1771
  },
1738
1772
  (res) => {
1739
1773
  if (res.statusCode !== 200) {
@@ -1783,23 +1817,22 @@ var UpdateNotifier = class {
1783
1817
  const now = Date.now();
1784
1818
  let latestVersion = cache.latestVersion;
1785
1819
  if (now - cache.lastChecked > CHECK_INTERVAL_MS) {
1786
- const fetched = await fetchLatestFromNpm();
1787
- if (fetched) {
1788
- latestVersion = fetched;
1789
- cache = { lastChecked: now, latestVersion: fetched };
1790
- try {
1791
- fs6.writeFileSync(cachePath, JSON.stringify(cache), "utf8");
1792
- } catch {
1820
+ fetchLatestFromNpm().then((fetched) => {
1821
+ if (fetched) {
1822
+ cache = { lastChecked: Date.now(), latestVersion: fetched };
1823
+ try {
1824
+ fs6.writeFileSync(cachePath, JSON.stringify(cache), "utf8");
1825
+ } catch {
1826
+ }
1793
1827
  }
1794
- }
1828
+ }).catch(() => {
1829
+ });
1795
1830
  }
1796
1831
  if (compareVersions(latestVersion, currentVersion) > 0) {
1797
- process.on("exit", () => {
1798
- console.error("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
1799
- console.error(`\u2502 \u{1F680} Actualizaci\xF3n disponible para MemHub: ${currentVersion} \u2192 \x1B[32m${latestVersion}\x1B[0m \u2502`);
1800
- console.error("\u2502 Ejecuta \x1B[1m\x1B[36mmh update\x1B[0m para instalar la \xFAltima versi\xF3n. \u2502");
1801
- console.error("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n");
1802
- });
1832
+ console.error("\n\u250C\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510");
1833
+ console.error(`\u2502 \u{1F680} Actualizaci\xF3n disponible para MemHub: ${currentVersion} \u2192 \x1B[32m${latestVersion}\x1B[0m \u2502`);
1834
+ console.error("\u2502 Ejecuta \x1B[1m\x1B[36mmh update\x1B[0m para instalar la \xFAltima versi\xF3n. \u2502");
1835
+ console.error("\u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n");
1803
1836
  }
1804
1837
  } catch {
1805
1838
  }
@@ -1907,7 +1940,7 @@ function openInBrowser(url) {
1907
1940
  }
1908
1941
 
1909
1942
  // src/cli.ts
1910
- var CLI_VERSION = "0.1.2";
1943
+ var CLI_VERSION = "0.1.3";
1911
1944
  void UpdateNotifier.checkForUpdates(CLI_VERSION);
1912
1945
  var program = new Command();
1913
1946
  var supportedTargets = ["claude", "cursor", "windsurf", "cline", "codex", "antigravity"];
@@ -1967,7 +2000,7 @@ async function installToSelectedClients(options) {
1967
2000
  }
1968
2001
  }
1969
2002
  }
1970
- program.name("memhub").description("Local-first MCP proxy for MemHub & agentmemory").version("0.1.2");
2003
+ program.name("memhub").description("Local-first MCP proxy for MemHub & agentmemory").version("0.1.3");
1971
2004
  program.command("serve").description("Start the MemHub MCP stdio proxy server").action(async () => {
1972
2005
  const config = getConfig();
1973
2006
  const server = new MemHubMcpServer(config);
@@ -2138,6 +2171,17 @@ program.command("doctor").description("Run system health checks and diagnostics
2138
2171
  console.log(` \u2717 Cloud API unreachable at ${config.apiUrl} (${health.message})`);
2139
2172
  }
2140
2173
  }
2174
+ console.log("4. Checking for CLI updates:");
2175
+ try {
2176
+ const latest = await fetchLatestFromNpm();
2177
+ if (latest && compareVersions(latest, CLI_VERSION) > 0) {
2178
+ console.log(` \u26A0\uFE0F Update available: ${CLI_VERSION} \u2192 ${latest}. Run \`mh update\` to upgrade.`);
2179
+ } else {
2180
+ console.log(` \u2713 MemHub CLI is up to date (v${CLI_VERSION}).`);
2181
+ }
2182
+ } catch {
2183
+ console.log(` \u2713 Running MemHub CLI v${CLI_VERSION}.`);
2184
+ }
2141
2185
  console.log("\nDoctor inspection completed.");
2142
2186
  });
2143
2187
  program.command("flush").description("Force an immediate push of all pending outbox events to the cloud").action(async () => {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/proxy/server.ts","../../protocol/src/schemas.ts","../../protocol/src/ids.ts","../../protocol/src/tools-list.ts","../src/proxy/local-engine.ts","../src/sync/engine.ts","../src/sync/client.ts","../src/outbox/db.ts","../src/project-resolver.ts","../src/config.ts","../src/connectors/ide-injector.ts","../src/connectors/rules-injector.ts","../src/update-notifier.ts","../src/auth/login-flow.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { MemHubMcpServer } from './proxy/server.js';\nimport { clearLocalState, getConfig, saveConfig } from './config.js';\nimport { IdeConfigInjector } from './connectors/ide-injector.js';\nimport { CloudApiClient } from './sync/client.js';\nimport { OutboxDb } from './outbox/db.js';\nimport { detectProjectContext } from './project-resolver.js';\nimport { AGENTMEMORY_54_TOOLS } from '@memhub/protocol';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\nimport { hostname } from 'node:os';\nimport { execSync } from 'node:child_process';\nimport path from 'node:path';\nimport { RulesInjector } from './connectors/rules-injector.js';\nimport { UpdateNotifier } from './update-notifier.js';\nimport { requestCliAuth, waitForCliApproval, openInBrowser, LoginDeniedError, LoginExpiredError, LoginTimeoutError } from './auth/login-flow.js';\n\nconst CLI_VERSION = '0.1.2';\nvoid UpdateNotifier.checkForUpdates(CLI_VERSION);\n\nconst program = new Command();\n\nconst supportedTargets = ['claude', 'cursor', 'windsurf', 'cline', 'codex', 'antigravity'] as const;\ntype InstallTarget = typeof supportedTargets[number] | 'other';\n\nasync function selectInstallTargets(value?: string, otherConfig?: string): Promise<InstallTarget[]> {\n if (value) {\n const requested = value.toLowerCase().split(',').map((item) => item.trim()).filter(Boolean);\n const expanded = requested.includes('all') ? [...supportedTargets] : requested;\n const invalid = expanded.filter((item) => !supportedTargets.includes(item as any) && item !== 'other');\n if (invalid.length) throw new Error(`Unsupported IDE target(s): ${invalid.join(', ')}`);\n if (expanded.includes('other') && !otherConfig) throw new Error('--config <path> is required with --ide other');\n return [...new Set(expanded)] as InstallTarget[];\n }\n\n if (!input.isTTY || !output.isTTY) return [...supportedTargets];\n const rl = createInterface({ input, output });\n output.write('\\nWhere should MemHub be installed? Select one or more (comma-separated):\\n');\n output.write(' 1) Claude Code\\n 2) Cursor\\n 3) Windsurf\\n 4) Cline\\n 5) Codex CLI\\n 6) Google Antigravity\\n 7) All supported clients\\n 8) Other JSON MCP client\\n');\n const answer = await rl.question('Selection [7]: ');\n rl.close();\n const choices = (answer.trim() || '7').split(',').map((item) => item.trim());\n if (choices.includes('7')) return [...supportedTargets];\n const map: Record<string, InstallTarget> = { '1': 'claude', '2': 'cursor', '3': 'windsurf', '4': 'cline', '5': 'codex', '6': 'antigravity', '8': 'other' };\n const selected = choices.map((choice) => map[choice]).filter(Boolean);\n if (!selected.length) throw new Error('No valid installation target selected');\n if (selected.includes('other') && !otherConfig) throw new Error('Use --config <path> when selecting Other');\n return [...new Set(selected)];\n}\n\ninterface InjectTargetsOptions {\n apiKey: string;\n apiUrl: string;\n projectSlug: string;\n ide?: string;\n configPath?: string;\n}\n\n/** Shared tail of `connect` and `login`: pick clients and inject MCP config. */\nasync function installToSelectedClients(options: InjectTargetsOptions): Promise<void> {\n const targets = await selectInstallTargets(options.ide, options.configPath);\n console.log(`🔧 Injecting MCP server configuration for: ${targets.join(', ')}...`);\n const injectOpts = {\n apiKey: options.apiKey,\n apiUrl: options.apiUrl,\n projectId: options.projectSlug\n };\n\n const results = [];\n for (const target of targets) {\n if (target === 'claude') results.push(IdeConfigInjector.injectClaudeCode(injectOpts));\n if (target === 'cursor') results.push(IdeConfigInjector.injectCursor(injectOpts));\n if (target === 'windsurf') results.push(IdeConfigInjector.injectWindsurf(injectOpts));\n if (target === 'cline') results.push(IdeConfigInjector.injectCline(injectOpts));\n if (target === 'codex') results.push(IdeConfigInjector.injectCodex(injectOpts));\n if (target === 'antigravity') results.push(IdeConfigInjector.injectAntigravity(injectOpts));\n if (target === 'other') results.push(IdeConfigInjector.injectOther(options.configPath!, injectOpts));\n }\n\n for (const res of results) {\n if (res.success) {\n console.log(` ✓ ${res.target}: MCP configured at ${res.filePath}`);\n } else {\n console.log(` ✗ ${res.target}: failed (${res.error})`);\n }\n }\n\n console.log('📝 Injecting MemHub memory protocol instructions into workspace & global rules...');\n const ruleResults = RulesInjector.injectAll(process.cwd());\n for (const r of ruleResults) {\n if (r.success && r.action !== 'unchanged') {\n console.log(` ✓ ${r.target}: rules ${r.action}`);\n }\n }\n}\n\nprogram\n .name('memhub')\n .description('Local-first MCP proxy for MemHub & agentmemory')\n .version('0.1.2');\n\nprogram\n .command('serve')\n .description('Start the MemHub MCP stdio proxy server')\n .action(async () => {\n const config = getConfig();\n const server = new MemHubMcpServer(config);\n await server.start();\n });\n\nprogram\n .command('install [target]')\n .description('Install the global MemHub MCP server into an AI client (or use generic)')\n .option('--config <path>', 'JSON MCP config path for a generic/other client')\n .action(async (target, options) => {\n const config = getConfig();\n if (!config.apiKey) {\n console.error('No MemHub session is configured. Run `memhub login` first.');\n process.exitCode = 1;\n return;\n }\n if (target === 'generic' && !options.config) {\n console.log(JSON.stringify({\n mcpServers: { memhub: { command: 'memhub', args: ['serve'] } },\n }, null, 2));\n return;\n }\n await installToSelectedClients({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n projectSlug: config.projectSlug || detectProjectContext().slug,\n ide: target === 'generic' ? 'other' : target,\n configPath: options.config,\n });\n });\n\nprogram\n .command('connect')\n .description('Connect the current repository or workspace to MemHub Cloud')\n .requiredOption('-k, --key <apiKey>', 'MemHub API Key (e.g. mh_live_...)')\n .option('-u, --url <apiUrl>', 'MemHub Cloud API URL', 'https://memhub.simplex.lat')\n .option('-p, --project <projectSlug>', 'Override project slug')\n .option('--ide <ides>', 'Comma-separated targets: all, claude, cursor, windsurf, cline, codex, antigravity, other')\n .option('--config <path>', 'JSON MCP config path when using --ide other')\n .action(async (options) => {\n console.log('🚀 Connecting to MemHub Cloud...');\n\n const detected = detectProjectContext();\n const projectSlug = options.project || detected.slug;\n\n saveConfig({\n apiKey: options.key,\n apiUrl: options.url,\n projectSlug\n });\n\n const client = new CloudApiClient(options.url, options.key);\n console.log(`📡 Resolving project \"${projectSlug}\" on cloud...`);\n\n try {\n const resolved = await client.resolveProject({\n slug: projectSlug,\n gitRemote: detected.gitRemote,\n name: detected.name\n });\n console.log(`✅ Project resolved: ${resolved.projectName} (ID: ${resolved.projectId}, Org: ${resolved.orgSlug})`);\n saveConfig({\n projectId: resolved.projectId,\n orgId: resolved.orgId\n });\n } catch (err: any) {\n console.warn(`⚠️ Cloud project resolution warning: ${err.message}`);\n console.log(' (Local memory and offline outbox will continue to work normally)');\n }\n\n await installToSelectedClients({\n apiKey: options.key,\n apiUrl: options.url,\n projectSlug,\n ide: options.ide,\n configPath: options.config\n });\n\n console.log('\\n🎉 MemHub MCP proxy successfully connected!');\n console.log(' Restart or refresh the selected AI clients to load MemHub.');\n });\n\nprogram\n .command('login')\n .description('Sign in with your browser, consent to a scoped project credential, then pick AI clients to configure')\n .option('-u, --url <apiUrl>', 'MemHub Cloud API URL', 'https://memhub.simplex.lat')\n .option('--ide <ides>', 'Comma-separated targets: all, claude, cursor, windsurf, cline, codex, antigravity, other')\n .option('--config <path>', 'JSON MCP config path when using --ide other')\n .option('--label <label>', 'Device label shown on the consent page')\n .option('--no-open', 'Print the verification URL instead of opening a browser')\n .action(async (options) => {\n try {\n console.log('🔐 Starting browser login for MemHub Cloud...');\n const initiation = await requestCliAuth(options.url, {\n label: options.label || `${hostname()} terminal`,\n });\n\n const opened = options.open ? openInBrowser(initiation.verificationUrl) : false;\n if (!opened) {\n console.log('\\n🌐 Open this URL in any browser to continue:');\n console.log(` ${initiation.verificationUrl}`);\n } else {\n console.log(`\\n🌐 Browser opened at ${options.url}/cli-auth — sign in, review the request, and approve.`);\n }\n console.log('⏱️ The login request expires in 15 minutes and can be approved only once.');\n\n const approval = await waitForCliApproval(options.url, initiation);\n\n saveConfig({\n apiKey: approval.apiKey,\n apiUrl: options.url,\n projectSlug: approval.projectSlug ?? undefined\n });\n console.log(`✅ Signed in${approval.orgName ? ` to ${approval.orgName}` : ''}. Scoped credential ${approval.keyPrefix}… saved to ~/.memhub/config.json (owner-only).`);\n if (!approval.projectSlug) {\n console.log('ℹ️ No default project was chosen during consent; it will be resolved per-repository on first use.');\n }\n\n await installToSelectedClients({\n apiKey: approval.apiKey,\n apiUrl: options.url,\n projectSlug: approval.projectSlug || detectProjectContext().slug,\n ide: options.ide,\n configPath: options.config\n });\n\n console.log('\\n🎉 Login complete! Restart or refresh the selected AI clients to load MemHub.');\n } catch (err: any) {\n if (err instanceof LoginDeniedError) {\n console.error('✗ Login denied in the browser. No credentials were stored.');\n } else if (err instanceof LoginExpiredError || err instanceof LoginTimeoutError) {\n console.error(`✗ ${err.message}`);\n } else {\n console.error(`✗ Login failed: ${err.message}`);\n }\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('logout')\n .description('Revoke this device, release its plan slot, and remove local MemHub credentials and sync state')\n .option('--local-only', 'Clear local state even when the cloud cannot be reached')\n .action(async (options) => {\n const config = getConfig();\n if (!config.apiKey && !options.localOnly) {\n console.error('No MemHub session is configured on this device.');\n process.exitCode = 1;\n return;\n }\n try {\n if (config.apiKey && !options.localOnly) {\n const result = await new CloudApiClient(config.apiUrl, config.apiKey).logoutDevice(config.deviceId);\n console.log(result.deviceReleased\n ? '✓ Device revoked and its plan slot released.'\n : '✓ Credential revoked; this device had no active cloud slot.');\n }\n clearLocalState();\n console.log('✓ Local MemHub credentials and sync outbox removed. Cloud memory history was preserved.');\n console.log(' Restart configured AI clients. Run mh login to connect again.');\n } catch (err: any) {\n console.error(`✗ Logout failed: ${err.message}`);\n console.error(' Local credentials were kept so you can retry. Use --local-only only if this device cannot reach MemHub.');\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('status')\n .description('Display synchronization status, outbox stats, and device info')\n .action(async () => {\n const config = getConfig();\n const db = new OutboxDb(config.outboxPath);\n const pendingCount = db.getPendingCount();\n const lastSeq = db.getLastSequence(config.deviceId);\n const localProject = detectProjectContext();\n\n console.log('\\n📊 MemHub MCP Status:');\n console.log(` Device ID: ${config.deviceId}`);\n console.log(` API URL: ${config.apiUrl}`);\n console.log(` API Key: ${config.apiKey ? config.apiKey.slice(0, 12) + '...' : '(none configured)'}`);\n console.log(` Project Slug: ${config.projectSlug || localProject.slug}`);\n console.log(` Project ID: ${config.projectId || '(pending JIT resolution)'}`);\n console.log(` Outbox SQLite DB: ${config.outboxPath}`);\n console.log(` Pending Events: ${pendingCount}`);\n console.log(` Monotonic Sequence: ${lastSeq}`);\n\n db.close();\n });\n\nprogram\n .command('doctor')\n .description('Run system health checks and diagnostics for local engine & cloud sync')\n .action(async () => {\n console.log('\\n🩺 Running MemHub Doctor...\\n');\n const config = getConfig();\n\n // 1. Check local agentmemory tools\n console.log('1. Checking local engine tools:');\n console.log(` ✓ Found ${AGENTMEMORY_54_TOOLS.length} native agentmemory tools mapped.`);\n\n // 2. Check SQLite Outbox\n console.log('2. Checking local durable outbox (WAL mode):');\n try {\n const db = new OutboxDb(config.outboxPath);\n const pending = db.getPendingCount();\n console.log(` ✓ Outbox SQLite database accessible (${pending} pending events).`);\n db.close();\n } catch (err: any) {\n console.log(` ✗ Outbox error: ${err.message}`);\n }\n\n // 3. Check Cloud Connectivity\n console.log('3. Checking MemHub Cloud API connectivity:');\n if (!config.apiKey) {\n console.log(' ⚠️ No API key configured. Run `memhub login` or `memhub connect --key <key>`.');\n } else {\n const client = new CloudApiClient(config.apiUrl, config.apiKey);\n const health = await client.testConnection();\n if (health.ok) {\n console.log(` ✓ Cloud API reachable at ${config.apiUrl} (HTTP status: ${health.status})`);\n } else {\n console.log(` ✗ Cloud API unreachable at ${config.apiUrl} (${health.message})`);\n }\n }\n\n console.log('\\nDoctor inspection completed.');\n });\n\nprogram\n .command('flush')\n .description('Force an immediate push of all pending outbox events to the cloud')\n .action(async () => {\n const config = getConfig();\n if (!config.apiKey) {\n console.error('Error: No API key configured. Run connect first.');\n process.exit(1);\n }\n\n console.log('🔄 Flushing pending outbox events to cloud...');\n const db = new OutboxDb(config.outboxPath);\n const client = new CloudApiClient(config.apiUrl, config.apiKey);\n\n const dueEvents = db.getDueEvents(100);\n if (dueEvents.length === 0) {\n console.log('✓ Outbox is already clean (0 pending events).');\n db.close();\n return;\n }\n\n try {\n const res = await client.pushEvents({\n protocol: 1,\n deviceId: config.deviceId,\n events: dueEvents.map(e => ({\n eventId: e.eventId,\n sequence: e.sequence,\n operation: e.operation,\n payload: JSON.parse(e.payloadJson),\n payloadSha256: e.payloadSha256\n }))\n });\n\n if (res.ackedEventIds && res.ackedEventIds.length > 0) {\n db.markAcked(res.ackedEventIds);\n console.log(`✅ Successfully flushed and acked ${res.ackedEventIds.length} events.`);\n }\n } catch (err: any) {\n console.error(`✗ Flush failed: ${err.message}`);\n } finally {\n db.close();\n }\n });\n\nprogram\n .command('rules')\n .description('Inject or update MemHub persistent memory protocol instructions into all AI client rules')\n .option('--cwd <path>', 'Workspace directory to target', process.cwd())\n .action(async (options) => {\n console.log('📝 Injecting MemHub memory protocol rules into AI client configuration files...');\n const results = RulesInjector.injectAll(path.resolve(options.cwd));\n for (const res of results) {\n if (res.success) {\n console.log(` ✓ ${res.target}: ${res.action} at ${res.filePath}`);\n } else {\n console.log(` ✗ ${res.target}: ${res.error}`);\n }\n }\n console.log('\\n✨ AI agents in this workspace and globally will now proactively save and recall team memories.');\n });\n\nprogram\n .command('update')\n .description('Check for updates and upgrade @simplexlat/memhub to the latest version')\n .option('--canary', 'Install prerelease canary build')\n .action(async (options) => {\n console.log('🔍 Checking for MemHub CLI updates...');\n try {\n const currentVersion = '0.1.0';\n console.log(`Current version: v${currentVersion}`);\n console.log('📦 Updating @simplexlat/memhub via npm...');\n const targetPkg = options.canary ? '@simplexlat/memhub@canary' : '@simplexlat/memhub@latest';\n execSync(`npm install --global ${targetPkg}`, { stdio: 'inherit' });\n console.log('\\n✅ MemHub CLI successfully updated to the latest version!');\n console.log(' Run `mh status` or `mh doctor` to verify your installation.');\n } catch (err: any) {\n console.error(`✗ Update failed: ${err.message}`);\n console.log(' Try running manually: npm install --global @simplexlat/memhub@latest');\n }\n });\n\nprogram.parse(process.argv);\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ErrorCode,\n McpError\n} from '@modelcontextprotocol/sdk/types.js';\nimport { LocalAgentMemoryEngine } from './local-engine.js';\nimport { SyncEngine } from '../sync/engine.js';\nimport { CloudApiClient } from '../sync/client.js';\nimport { OutboxDb } from '../outbox/db.js';\nimport { MemHubConfig } from '../config.js';\nimport { detectProjectContext } from '../project-resolver.js';\nimport { MUTATING_TOOLS } from '@memhub/protocol';\n\nexport class MemHubMcpServer {\n private server: Server;\n private localEngine: LocalAgentMemoryEngine;\n private syncEngine: SyncEngine;\n private outboxDb: OutboxDb;\n private cloudClient: CloudApiClient;\n private config: MemHubConfig;\n\n constructor(config: MemHubConfig) {\n this.config = config;\n this.outboxDb = new OutboxDb(config.outboxPath);\n this.cloudClient = new CloudApiClient(config.apiUrl, config.apiKey);\n this.localEngine = new LocalAgentMemoryEngine();\n\n const localProject = detectProjectContext();\n const effectiveProjectId = config.projectId || config.projectSlug || localProject.slug;\n\n this.syncEngine = new SyncEngine({\n outboxDb: this.outboxDb,\n cloudClient: this.cloudClient,\n deviceId: config.deviceId,\n projectId: effectiveProjectId,\n orgId: config.orgId,\n onRemoteEventsReceived: async (events) => {\n await this.localEngine.importRemoteEvents(events);\n }\n });\n\n this.server = new Server(\n {\n name: 'memhub-mcp',\n version: '0.1.0'\n },\n {\n capabilities: {\n tools: {}\n }\n }\n );\n\n this.setupHandlers();\n }\n\n private setupHandlers(): void {\n // 1. List all 54 agentmemory tools + 3 MemHub management tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const nativeTools = this.localEngine.getToolList();\n\n const memhubTools = [\n {\n name: 'memhub_sync_status',\n description: 'Checks synchronization status, pending outbox count, device ID, and cloud connectivity.',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n {\n name: 'memhub_sync_now',\n description: 'Forces an immediate on-demand push of all pending outbox events and pulls latest team deltas.',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n {\n name: 'memhub_cloud_search',\n description: 'Searches the organization aggregated memory corpus directly in the cloud (FTS + vector).',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Max results to return' },\n mode: { type: 'string', enum: ['fts', 'vector', 'hybrid'], description: 'Search mode' }\n },\n required: ['query']\n }\n }\n ];\n\n return {\n tools: [...nativeTools, ...memhubTools]\n };\n });\n\n // 2. Handle tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n try {\n // Handle MemHub management tools\n if (name === 'memhub_sync_status') {\n const status = this.syncEngine.getStatus();\n return {\n content: [{\n type: 'text',\n text: JSON.stringify(status, null, 2)\n }]\n };\n }\n\n if (name === 'memhub_sync_now') {\n const [pushResult, pullResult] = await Promise.allSettled([\n this.syncEngine.triggerPushOnDemand(),\n this.syncEngine.triggerPullOnDemand()\n ]);\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n push: pushResult.status === 'fulfilled' ? pushResult.value : { error: pushResult.reason?.message },\n pull: pullResult.status === 'fulfilled' ? pullResult.value : { error: pullResult.reason?.message },\n status: this.syncEngine.getStatus()\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memhub_cloud_search') {\n try {\n const results = await this.cloudClient.search({\n query: String(args.query || ''),\n limit: Number(args.limit || 10),\n mode: (args.mode as any) || 'hybrid'\n });\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }]\n };\n } catch (err: any) {\n // Fallback to local recall if cloud is unavailable\n const fallback = await this.localEngine.executeTool('memory_recall', {\n query: args.query,\n limit: args.limit\n });\n return {\n content: [{\n type: 'text',\n text: `[Cloud search degraded: ${err.message}. Showing local results:]\\n` + fallback.content[0].text\n }]\n };\n }\n }\n\n // On read: JIT Delta Pull\n if (name === 'memory_recall' || name === 'mem_search' || name === 'memory_session_start' || name === 'mem_session_start') {\n // Reads remain local. At most one lightweight conditional head check\n // per 30s is allowed when server-push invalidation is unavailable.\n this.syncEngine.refreshIfStale();\n }\n\n // Execute local tool execution (<3ms response)\n const result = await this.localEngine.executeTool(name, args);\n\n // On write / mutation: Record in Outbox & trigger on-demand push\n if (MUTATING_TOOLS.has(name)) {\n let op = 'memory.save';\n if (name === 'memory_delete' || name === 'memory_governance_delete') op = 'memory.delete';\n else if (name === 'mem_pin') op = 'memory.pin';\n else if (name === 'mem_unpin') op = 'memory.unpin';\n else if (name.includes('session_summary')) op = 'session.summary';\n\n await this.syncEngine.handleLocalMutation(op, {\n tool: name,\n title: args.title,\n content: args.content || args.summary,\n memoryType: args.type || 'observation',\n topicKey: args.topic_key,\n isPinned: Boolean(args.is_pinned),\n arguments: args\n });\n }\n\n return result as any;\n } catch (err: any) {\n throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${err.message}`);\n }\n });\n }\n\n public async start(): Promise<void> {\n await this.localEngine.initialize();\n\n // Auto-resolve project JIT on startup if API key is provided\n if (this.config.apiKey) {\n try {\n const localCtx = detectProjectContext();\n const resolved = await this.cloudClient.resolveProject({\n slug: this.config.projectSlug || localCtx.slug,\n gitRemote: localCtx.gitRemote,\n name: localCtx.name\n });\n this.syncEngine.setProjectId(resolved.projectId);\n this.syncEngine.setOrgId(resolved.orgId);\n await this.syncEngine.startAutomaticSync();\n } catch (err) {\n // Continue offline if cloud resolution fails\n }\n }\n\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n }\n\n public getOutboxDb(): OutboxDb {\n return this.outboxDb;\n }\n\n public getSyncEngine(): SyncEngine {\n return this.syncEngine;\n }\n}\n","import { z } from 'zod';\n\nexport const SyncEventPayloadSchema = z.record(z.unknown()).refine(\n (value) => new TextEncoder().encode(JSON.stringify(value)).byteLength <= 256 * 1024,\n 'Event payload exceeds 256 KiB',\n);\n\nexport const PushSyncEventSchema = z.object({\n eventId: z.string().uuid(),\n sequence: z.number().int().nonnegative(),\n operation: z.string().min(1).max(64),\n payload: SyncEventPayloadSchema,\n payloadSha256: z.string().min(1)\n});\n\nexport const PushSyncRequestSchema = z.object({\n protocol: z.number().int().default(1),\n deviceId: z.string().uuid(),\n projectId: z.string().uuid().optional(),\n events: z.array(PushSyncEventSchema).min(1).max(200)\n});\n\nexport const PushSyncResponseSchema = z.object({\n success: z.boolean(),\n processedCount: z.number().int(),\n ackedEventIds: z.array(z.string()),\n errors: z.array(z.object({\n eventId: z.string(),\n error: z.string()\n })).optional()\n});\n\nexport const PullSyncRequestSchema = z.object({\n projectId: z.string().uuid().optional(),\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(500).default(100)\n});\n\nexport const PullSyncResponseSchema = z.object({\n events: z.array(z.object({\n eventId: z.string(),\n projectId: z.string(),\n deviceId: z.string(),\n sequence: z.number(),\n operation: z.string(),\n payload: z.record(z.unknown()),\n payloadSha256: z.string(),\n receivedAt: z.string().optional()\n })),\n nextCursor: z.string().optional(),\n hasMore: z.boolean()\n});\n\nexport const ResolveProjectRequestSchema = z.object({\n slug: z.string().optional(),\n gitRemote: z.string().optional(),\n name: z.string().optional()\n});\n\nexport const ResolveProjectResponseSchema = z.object({\n projectId: z.string(),\n projectSlug: z.string(),\n orgId: z.string(),\n orgSlug: z.string(),\n projectName: z.string(),\n isNew: z.boolean()\n});\n\nexport const CloudSearchRequestSchema = z.object({\n projectId: z.string().uuid(),\n query: z.string().trim().min(1).max(1000),\n limit: z.number().int().min(1).max(100).default(20),\n memoryType: z.string().min(1).max(64).optional(),\n topicKey: z.string().min(1).max(160).regex(/^[a-zA-Z0-9._:/-]+$/).optional(),\n isPinnedOnly: z.boolean().optional()\n});\n\nexport const CloudSearchResponseSchema = z.object({\n results: z.array(z.object({\n id: z.string(),\n projectId: z.string(),\n title: z.string(),\n content: z.string(),\n memoryType: z.string(),\n topicKey: z.string().optional(),\n isPinned: z.boolean(),\n score: z.number(),\n source: z.string(),\n createdAt: z.string()\n })),\n total: z.number().int(),\n query: z.string(),\n executionTimeMs: z.number()\n});\n","import { createHash, randomUUID } from 'crypto';\n\nexport function generateUuid(): string {\n return randomUUID();\n}\n\nexport function sha256Hex(data: string | Buffer | Record<string, unknown>): string {\n const str = typeof data === 'string' \n ? data \n : Buffer.isBuffer(data) \n ? data \n : JSON.stringify(data, Object.keys(data).sort());\n return createHash('sha256').update(str).digest('hex');\n}\n\nexport function hashApiKey(key: string): string {\n return createHash('sha256').update(key.trim()).digest('hex');\n}\n\nexport function generateApiKey(prefix = 'mh_live'): { rawKey: string; keyPrefix: string; keyHash: string } {\n const entropy = randomUUID().replace(/-/g, '') + randomUUID().replace(/-/g, '');\n const rawKey = `${prefix}_${entropy}`;\n const keyPrefix = `${prefix}_${entropy.slice(0, 8)}`;\n const keyHash = hashApiKey(rawKey);\n return { rawKey, keyPrefix, keyHash };\n}\n\nexport interface CursorPayload {\n timestamp: string;\n sequence: number;\n id: string;\n}\n\nexport function encodeCursor(payload: CursorPayload): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url');\n}\n\nexport function decodeCursor(cursorStr?: string): CursorPayload | null {\n if (!cursorStr) return null;\n try {\n const raw = Buffer.from(cursorStr, 'base64url').toString('utf8');\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object' && typeof parsed.timestamp === 'string') {\n return parsed as CursorPayload;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Complete list of 54 MCP tools in @agentmemory/agentmemory@0.9.29\n */\nexport const AGENTMEMORY_54_TOOLS = [\n // 1. Core Memory Operations\n 'memory_save',\n 'memory_recall',\n 'memory_update',\n 'memory_delete',\n 'memory_smart_search',\n 'memory_consolidate',\n 'memory_diagnose',\n 'memory_sessions',\n 'memory_session_start',\n 'memory_session_end',\n 'memory_session_summary',\n 'memory_lesson_save',\n 'memory_reflect',\n \n // 2. Observations & Passive Capture\n 'mem_save',\n 'mem_update',\n 'mem_search',\n 'mem_context',\n 'mem_get_observation',\n 'mem_session_start',\n 'mem_session_end',\n 'mem_session_summary',\n 'mem_capture_passive',\n 'mem_suggest_topic_key',\n 'mem_pin',\n 'mem_unpin',\n 'mem_review',\n 'mem_judge',\n 'mem_compare',\n 'mem_doctor',\n 'mem_current_project',\n \n // 3. Knowledge Graph & Relations\n 'memory_graph_query',\n 'memory_graph_add_relation',\n 'memory_graph_remove_relation',\n 'memory_graph_neighbors',\n 'memory_graph_shortest_path',\n \n // 4. Slots & Working State\n 'memory_slot_create',\n 'memory_slot_get',\n 'memory_slot_append',\n 'memory_slot_replace',\n 'memory_slot_delete',\n 'memory_slot_list',\n \n // 5. Governance, Snapshot & Audit\n 'memory_governance_audit',\n 'memory_governance_delete',\n 'memory_snapshot_create',\n 'memory_snapshot_restore',\n 'memory_snapshot_list',\n 'memory_team_share',\n \n // 6. Patterns, Timeline & History\n 'memory_pattern_detect',\n 'memory_pattern_list',\n 'memory_timeline_get',\n 'memory_file_history_get',\n 'memory_file_history_record',\n 'memory_stats_get'\n] as const;\n\n/**\n * 8 Essential Core Tools\n */\nexport const ESSENTIAL_CORE_TOOLS = new Set([\n 'memory_save',\n 'memory_recall',\n 'memory_consolidate',\n 'memory_smart_search',\n 'memory_sessions',\n 'memory_diagnose',\n 'memory_lesson_save',\n 'memory_reflect'\n]);\n\n/**\n * Tools that produce state mutations requiring cloud sync push\n */\nexport const MUTATING_TOOLS = new Set([\n 'memory_save',\n 'memory_update',\n 'memory_delete',\n 'memory_consolidate',\n 'memory_session_end',\n 'memory_session_summary',\n 'memory_lesson_save',\n 'memory_reflect',\n 'mem_save',\n 'mem_update',\n 'mem_pin',\n 'mem_unpin',\n 'mem_capture_passive',\n 'mem_session_end',\n 'mem_session_summary',\n 'memory_graph_add_relation',\n 'memory_graph_remove_relation',\n 'memory_slot_create',\n 'memory_slot_append',\n 'memory_slot_replace',\n 'memory_slot_delete',\n 'memory_snapshot_create',\n 'memory_snapshot_restore',\n 'memory_governance_delete',\n 'memory_team_share',\n 'memory_file_history_record'\n]);\n\n/**\n * Custom MemHub SaaS tools provided alongside agentmemory\n */\nexport const MEMHUB_MANAGEMENT_TOOLS = [\n 'memhub_sync_status',\n 'memhub_sync_now',\n 'memhub_cloud_search'\n] as const;\n","import { AGENTMEMORY_54_TOOLS, ESSENTIAL_CORE_TOOLS } from '@memhub/protocol';\n\nexport interface McpToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\nexport interface ToolCallResult {\n content: Array<{\n type: 'text';\n text: string;\n }>;\n isError?: boolean;\n [key: string]: unknown;\n}\n\nexport class LocalAgentMemoryEngine {\n private isInitialized = false;\n private toolsCatalog: Map<string, McpToolDefinition> = new Map();\n private localMemories: Map<string, any> = new Map();\n\n constructor() {\n this.initDefaultToolCatalog();\n }\n\n public async initialize(): Promise<void> {\n try {\n // Attempt dynamic loading of agentmemory if available\n // Native agentmemory uses stdio or in-memory registry\n this.isInitialized = true;\n } catch (err) {\n this.isInitialized = true;\n }\n }\n\n private initDefaultToolCatalog(): void {\n for (const toolName of AGENTMEMORY_54_TOOLS) {\n this.toolsCatalog.set(toolName, this.createDefaultSchemaForTool(toolName));\n }\n }\n\n private createDefaultSchemaForTool(name: string): McpToolDefinition {\n switch (name) {\n case 'memory_save':\n case 'mem_save':\n return {\n name,\n description: 'Saves a structured memory, observation, decision, or discovery with fast local persistence and team sync.',\n inputSchema: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Brief descriptive title of the memory' },\n content: { type: 'string', description: 'Detailed memory content' },\n type: { type: 'string', description: 'Type of memory (decision, pattern, bugfix, discovery, etc.)' },\n topic_key: { type: 'string', description: 'Stable topic key for evolving decisions' },\n is_pinned: { type: 'boolean', description: 'Pin as invariant team rule' }\n },\n required: ['title', 'content']\n }\n };\n case 'memory_recall':\n case 'mem_search':\n case 'mem_context':\n return {\n name,\n description: 'Recalls relevant memories using hybrid BM25 + vector + graph search.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Maximum number of results to return' },\n topic_key: { type: 'string', description: 'Filter by topic key' },\n type: { type: 'string', description: 'Filter by memory type' }\n },\n required: ['query']\n }\n };\n case 'memory_smart_search':\n return {\n name,\n description: 'Advanced semantic triple-stream search with RRF fusion.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Max results' }\n },\n required: ['query']\n }\n };\n case 'memory_consolidate':\n return {\n name,\n description: 'Consolidates short-term observations into high-level learnings and patterns.',\n inputSchema: {\n type: 'object',\n properties: {\n scope: { type: 'string', description: 'Consolidation scope' }\n }\n }\n };\n case 'memory_session_summary':\n case 'mem_session_summary':\n return {\n name,\n description: 'Saves an end-of-session structured summary across Goal, Discoveries, Accomplished, Next Steps.',\n inputSchema: {\n type: 'object',\n properties: {\n summary: { type: 'string', description: 'Markdown summary of the session' }\n },\n required: ['summary']\n }\n };\n default:\n return {\n name,\n description: `Native agentmemory tool: ${name}`,\n inputSchema: {\n type: 'object',\n properties: {\n input: { type: 'string', description: 'Tool input argument' },\n query: { type: 'string', description: 'Query argument' },\n options: { type: 'object', description: 'Optional configuration' }\n }\n }\n };\n }\n }\n\n public getToolList(): McpToolDefinition[] {\n return Array.from(this.toolsCatalog.values());\n }\n\n public getTool(name: string): McpToolDefinition | undefined {\n return this.toolsCatalog.get(name);\n }\n\n public async executeTool(name: string, args: Record<string, any>): Promise<ToolCallResult> {\n const startTime = Date.now();\n\n // Handle local storage execution\n if (name === 'memory_save' || name === 'mem_save') {\n const id = `mem_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n const record = {\n id,\n title: args.title || 'Untitled Memory',\n content: args.content || '',\n type: args.type || 'observation',\n topicKey: args.topic_key,\n isPinned: Boolean(args.is_pinned),\n createdAt: new Date().toISOString()\n };\n this.localMemories.set(id, record);\n\n const elapsed = Date.now() - startTime;\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n memory_id: id,\n title: record.title,\n execution_time_ms: elapsed,\n local_status: 'persisted'\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memory_recall' || name === 'mem_search' || name === 'memory_smart_search') {\n const query = (args.query || '').toLowerCase();\n const tokens = query.split(/\\s+/).filter(Boolean);\n const results: any[] = [];\n\n for (const item of this.localMemories.values()) {\n const titleLower = (item.title || '').toLowerCase();\n const contentLower = (item.content || '').toLowerCase();\n const topicLower = (item.topicKey || '').toLowerCase();\n\n const matches = tokens.length === 0 || tokens.some((t: string) =>\n titleLower.includes(t) || contentLower.includes(t) || topicLower.includes(t)\n );\n\n if (matches) {\n results.push(item);\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n results: results.slice(0, args.limit || 10),\n total: results.length,\n query: args.query,\n source: 'local_engine'\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memory_session_summary' || name === 'mem_session_summary') {\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n status: 'session_summary_recorded',\n timestamp: new Date().toISOString()\n }, null, 2)\n }]\n };\n }\n\n // Default transparent execution for remaining tools\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n tool: name,\n received_arguments: args,\n engine: 'agentmemory@0.9.29',\n status: 'ok'\n }, null, 2)\n }]\n };\n }\n\n public async importRemoteEvents(events: any[]): Promise<void> {\n for (const evt of events) {\n if (evt.operation === 'memory.save' && evt.payload) {\n const id = evt.payload.sourceMemoryId || `remote_${evt.eventId}`;\n this.localMemories.set(id, {\n id,\n title: evt.payload.title || 'Remote Memory',\n content: evt.payload.content || '',\n type: evt.payload.memoryType || 'observation',\n topicKey: evt.payload.topicKey,\n isPinned: Boolean(evt.payload.isPinned),\n createdAt: evt.receivedAt || new Date().toISOString()\n });\n }\n }\n }\n}\n","import { OutboxDb } from '../outbox/db.js';\nimport { CloudApiClient } from './client.js';\nimport { SyncStatus, SyncEvent, SyncOperation, sha256Hex } from '@memhub/protocol';\n\nexport interface SyncEngineOptions {\n outboxDb: OutboxDb;\n cloudClient: CloudApiClient;\n deviceId: string;\n projectId: string;\n orgId?: string;\n onRemoteEventsReceived?: (events: SyncEvent[]) => Promise<void>;\n}\n\nexport class SyncEngine {\n private outboxDb: OutboxDb;\n private cloudClient: CloudApiClient;\n private deviceId: string;\n private projectId: string;\n private orgId?: string;\n private isPushing = false;\n private isPulling = false;\n private lastPushAt?: string;\n private lastPullAt?: string;\n private lastError?: string;\n private onRemoteEventsReceived?: (events: SyncEvent[]) => Promise<void>;\n private automaticAbort?:AbortController;\n private fallbackTimer?:ReturnType<typeof setTimeout>;\n private pullDebounce?:ReturnType<typeof setTimeout>;\n private headEtag?:string;\n private remoteVersion=0;\n private lastHeadCheckAt=0;\n\n constructor(options: SyncEngineOptions) {\n this.outboxDb = options.outboxDb;\n this.cloudClient = options.cloudClient;\n this.deviceId = options.deviceId;\n this.projectId = options.projectId;\n this.orgId = options.orgId;\n this.onRemoteEventsReceived = options.onRemoteEventsReceived;\n }\n\n public setProjectId(projectId: string): void {\n this.projectId = projectId;\n }\n\n public async startAutomaticSync():Promise<void>{\n if(this.automaticAbort)return;this.automaticAbort=new AbortController();\n this.remoteVersion=Number(this.outboxDb.getState(`remote_version_${this.projectId}`)||0);\n await this.checkHeadAndPull(true);\n void this.runStream(this.automaticAbort.signal);\n this.scheduleFallback();\n }\n\n public refreshIfStale(maxAgeMs=30_000):void{\n if(Date.now()-this.lastHeadCheckAt<maxAgeMs)return;\n void this.checkHeadAndPull(false);\n }\n\n public stopAutomaticSync():void{\n this.automaticAbort?.abort();this.automaticAbort=undefined;\n if(this.fallbackTimer)clearTimeout(this.fallbackTimer);if(this.pullDebounce)clearTimeout(this.pullDebounce);\n }\n\n private schedulePull(delay=350){\n if(this.pullDebounce)return;this.pullDebounce=setTimeout(()=>{this.pullDebounce=undefined;void this.checkHeadAndPull(false)},delay);\n }\n\n private async runStream(signal:AbortSignal){\n let backoff=1000;\n while(!signal.aborted){try{await this.cloudClient.streamSyncNotices(signal,(notice)=>{if(notice.projectId===this.projectId&&notice.version>this.remoteVersion)this.schedulePull()});backoff=1000}\n catch(err:any){if(signal.aborted)return;this.lastError=err.message;await new Promise(r=>setTimeout(r,backoff+Math.random()*500));backoff=Math.min(backoff*2,30_000)}}\n }\n\n private scheduleFallback(){\n const tick=async()=>{if(!this.automaticAbort||this.automaticAbort.signal.aborted)return;await this.checkHeadAndPull(false);\n this.fallbackTimer=setTimeout(tick,55_000+Math.random()*10_000)};\n this.fallbackTimer=setTimeout(tick,55_000+Math.random()*10_000);\n }\n\n private async checkHeadAndPull(force:boolean){\n this.lastHeadCheckAt=Date.now();\n try{const head=await this.cloudClient.getSyncHead(force?undefined:this.headEtag);if(head.etag)this.headEtag=head.etag;\n if(!head.notModified&&head.version>this.remoteVersion){await this.triggerPullOnDemand();this.remoteVersion=head.version;this.outboxDb.setState(`remote_version_${this.projectId}`,String(head.version))}\n }catch(err:any){this.lastError=err.message}\n }\n\n public setOrgId(orgId: string): void {\n this.orgId = orgId;\n }\n\n /**\n * Records a local mutation event in the outbox in <1ms and triggers on-demand cloud push.\n */\n public async handleLocalMutation(\n operation: SyncOperation | string,\n payload: Record<string, unknown>\n ): Promise<{ eventId: string; sequence: number }> {\n const record = this.outboxDb.enqueueEvent({\n deviceId: this.deviceId,\n projectId: this.projectId,\n operation,\n payload,\n origin: 'local'\n });\n\n // Fire on-demand push asynchronously without blocking local tool response\n this.triggerPushOnDemand().catch(err => {\n this.lastError = err.message;\n });\n\n return {\n eventId: record.eventId,\n sequence: record.sequence\n };\n }\n\n /**\n * Pushes all due outbox events to the cloud.\n */\n public async triggerPushOnDemand(batchSize = 50, force = false): Promise<{ processed: number; acked: number }> {\n if (this.isPushing) {\n return { processed: 0, acked: 0 };\n }\n\n this.isPushing = true;\n try {\n const dueEvents = this.outboxDb.getDueEvents(batchSize, force);\n if (dueEvents.length === 0) {\n return { processed: 0, acked: 0 };\n }\n\n const requestPayload = {\n protocol: 1,\n deviceId: this.deviceId,\n events: dueEvents.map(e => ({\n eventId: e.eventId,\n sequence: e.sequence,\n operation: e.operation,\n payload: JSON.parse(e.payloadJson),\n payloadSha256: e.payloadSha256\n }))\n };\n\n const response = await this.cloudClient.pushEvents(requestPayload);\n\n if (response.ackedEventIds && response.ackedEventIds.length > 0) {\n this.outboxDb.markAcked(response.ackedEventIds);\n }\n\n if (response.errors && response.errors.length > 0) {\n for (const err of response.errors) {\n this.outboxDb.recordFailure(err.eventId, err.error);\n }\n }\n\n this.lastPushAt = new Date().toISOString();\n this.lastError = undefined;\n\n return {\n processed: dueEvents.length,\n acked: response.ackedEventIds?.length || 0\n };\n } catch (err: any) {\n this.lastError = err.message;\n // Record failure for pending events\n const dueEvents = this.outboxDb.getDueEvents(batchSize);\n for (const e of dueEvents) {\n this.outboxDb.recordFailure(e.eventId, err.message);\n }\n return { processed: 0, acked: 0 };\n } finally {\n this.isPushing = false;\n }\n }\n\n /**\n * Performs JIT delta pull from cloud and imports remote changes.\n */\n public async triggerPullOnDemand(): Promise<{ eventsCount: number }> {\n if (this.isPulling) {\n return { eventsCount: 0 };\n }\n\n this.isPulling = true;\n try {\n const cursorKey = `pull_cursor_${this.projectId}`;\n const savedCursor = this.outboxDb.getState(cursorKey) || undefined;\n\n let cursor=savedCursor,total=0;\n for(let page=0;page<100;page++){\n const response=await this.cloudClient.pullEvents({cursor,limit:100});\n if (response.events && response.events.length > 0) {\n // Filter out events originated from this exact device to avoid echo loops\n const remoteEvents = response.events.filter(e => e.deviceId !== this.deviceId);\n\n if (remoteEvents.length > 0 && this.onRemoteEventsReceived) {\n await this.onRemoteEventsReceived(remoteEvents as SyncEvent[]);\n }\n\n if(response.nextCursor){cursor=response.nextCursor;this.outboxDb.setState(cursorKey,cursor)}\n }\n total+=response.events?.length||0;\n if(!response.hasMore)break;\n }\n\n this.lastPullAt = new Date().toISOString();\n this.lastError = undefined;\n\n return { eventsCount: total };\n } catch (err: any) {\n this.lastError = err.message;\n return { eventsCount: 0 };\n } finally {\n this.isPulling = false;\n }\n }\n\n /**\n * Gets current sync status & health diagnostics.\n */\n public getStatus(): SyncStatus {\n const pendingCount = this.outboxDb.getPendingCount();\n const lastSeq = this.outboxDb.getLastSequence(this.deviceId);\n\n return {\n deviceId: this.deviceId,\n projectId: this.projectId,\n orgId: this.orgId,\n cloudConnected: !this.lastError,\n pendingOutboxCount: pendingCount,\n lastPushAt: this.lastPushAt,\n lastPullAt: this.lastPullAt,\n lastSequence: lastSeq,\n lastError: this.lastError\n };\n }\n}\n","import {\n PushSyncRequest,\n PushSyncResponse,\n PullSyncRequest,\n PullSyncResponse,\n ResolveProjectRequest,\n ResolveProjectResponse,\n CloudSearchRequest,\n CloudSearchResponse,\n sha256Hex\n} from '@memhub/protocol';\n\nexport const USER_AGENT = 'MemHub-MCP/0.1.0';\n\nexport class CloudApiClient {\n private apiUrl: string;\n private apiKey?: string;\n\n constructor(apiUrl: string, apiKey?: string) {\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.apiKey = apiKey;\n }\n\n public setApiKey(key: string): void {\n this.apiKey = key;\n }\n\n private getHeaders(customHeaders: Record<string, string> = {}): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': USER_AGENT,\n ...customHeaders\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n headers['x-api-key'] = this.apiKey;\n }\n\n return headers;\n }\n\n public async resolveProject(req: ResolveProjectRequest): Promise<ResolveProjectResponse> {\n const res = await fetch(`${this.apiUrl}/api/v1/projects/resolve`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to resolve project: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as ResolveProjectResponse;\n }\n\n public async pushEvents(req: PushSyncRequest): Promise<PushSyncResponse> {\n const idempotencyKey = sha256Hex(JSON.stringify(req.events.map(e => e.eventId).sort()));\n\n const res = await fetch(`${this.apiUrl}/api/v1/sync/push`, {\n method: 'POST',\n headers: this.getHeaders({\n 'Idempotency-Key': idempotencyKey\n }),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to push sync events: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as PushSyncResponse;\n }\n\n public async pullEvents(req: PullSyncRequest): Promise<PullSyncResponse> {\n const params = new URLSearchParams();\n if (req.cursor) params.set('cursor', req.cursor);\n if (req.limit) params.set('limit', String(req.limit));\n\n const url = `${this.apiUrl}/api/v1/sync/pull?${params.toString()}`;\n const res = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to pull sync events: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as PullSyncResponse;\n }\n\n public async getSyncHead(etag?: string): Promise<{ notModified:boolean;version:number;etag?:string }> {\n const res=await fetch(`${this.apiUrl}/api/v1/sync/head`,{headers:this.getHeaders(etag?{'If-None-Match':etag}:{})});\n if(res.status===304)return {notModified:true,version:0,etag:etag};\n if(!res.ok)throw new Error(`Failed to read sync head: ${res.status}`);\n const body=await res.json() as {version:number};\n return {notModified:false,version:Number(body.version||0),etag:res.headers.get('etag')||undefined};\n }\n\n public async streamSyncNotices(\n signal:AbortSignal,onNotice:(notice:{projectId:string;version:number})=>void,\n ):Promise<void>{\n const res=await fetch(`${this.apiUrl}/api/v1/sync/stream`,{headers:this.getHeaders({Accept:'text/event-stream'}),signal});\n if(!res.ok||!res.body)throw new Error(`Failed to open sync stream: ${res.status}`);\n const reader=res.body.getReader(),decoder=new TextDecoder();let buffer='';\n while(true){const {done,value}=await reader.read();if(done)return;buffer+=decoder.decode(value,{stream:true});\n let boundary;while((boundary=buffer.indexOf('\\n\\n'))>=0){const frame=buffer.slice(0,boundary);buffer=buffer.slice(boundary+2);\n const event=frame.split('\\n').find(line=>line.startsWith('event:'))?.slice(6).trim();\n const data=frame.split('\\n').find(line=>line.startsWith('data:'))?.slice(5).trim();\n if(event==='project_changed'&&data){try{onNotice(JSON.parse(data))}catch{}}\n }\n }\n }\n\n public async search(req: CloudSearchRequest): Promise<CloudSearchResponse> {\n const res = await fetch(`${this.apiUrl}/api/v1/search`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Cloud search failed: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as CloudSearchResponse;\n }\n\n public async logoutDevice(deviceId: string): Promise<{ success: boolean; deviceReleased: boolean }> {\n const res = await fetch(`${this.apiUrl}/api/v1/devices/logout`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({ deviceId }),\n });\n if (!res.ok) throw new Error(`Failed to log out device: ${res.status} ${await res.text()}`);\n return await res.json() as { success: boolean; deviceReleased: boolean };\n }\n\n public async testConnection(): Promise<{ ok: boolean; status: number; message?: string }> {\n try {\n const res = await fetch(`${this.apiUrl}/api/v1/projects/resolve`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({ slug: '__health_check__' })\n });\n return { ok: res.ok || res.status === 401 || res.status === 400, status: res.status };\n } catch (err: any) {\n return { ok: false, status: 0, message: err.message };\n }\n }\n}\n","import { DatabaseSync } from 'node:sqlite';\nimport path from 'path';\nimport fs from 'fs';\nimport { randomUUID } from 'crypto';\nimport { sha256Hex, OutboxRecord, SyncOperation } from '@memhub/protocol';\n\nexport interface EnqueueEventInput {\n eventId?: string;\n deviceId: string;\n projectId: string;\n operation: SyncOperation | string;\n payload: Record<string, unknown>;\n origin?: string;\n}\n\nexport class OutboxDb {\n private db: DatabaseSync;\n\n constructor(dbPath: string) {\n const dir = path.dirname(dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n this.db = new DatabaseSync(dbPath);\n this.init();\n }\n\n private init(): void {\n this.db.exec('PRAGMA journal_mode = WAL;');\n this.db.exec('PRAGMA synchronous = NORMAL;');\n this.db.exec('PRAGMA busy_timeout = 5000;');\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS outbox_events (\n event_id TEXT PRIMARY KEY,\n device_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n sequence INTEGER NOT NULL,\n operation TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n payload_sha256 TEXT NOT NULL,\n origin TEXT NOT NULL DEFAULT 'local',\n attempts INTEGER NOT NULL DEFAULT 0,\n next_attempt_at TEXT NOT NULL,\n created_at TEXT NOT NULL,\n acked_at TEXT,\n last_error TEXT,\n UNIQUE(device_id, sequence)\n );\n\n CREATE INDEX IF NOT EXISTS idx_outbox_due ON outbox_events(acked_at, next_attempt_at);\n CREATE INDEX IF NOT EXISTS idx_outbox_project ON outbox_events(project_id, sequence);\n\n CREATE TABLE IF NOT EXISTS sync_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n }\n\n public getLastSequence(deviceId: string): number {\n const stmt = this.db.prepare('SELECT MAX(sequence) as max_seq FROM outbox_events WHERE device_id = ?');\n const row = stmt.get(deviceId) as { max_seq: number | null } | undefined;\n return row?.max_seq ?? 0;\n }\n\n public enqueueEvent(input: EnqueueEventInput): OutboxRecord {\n const now = new Date().toISOString();\n const eventId = input.eventId || randomUUID();\n const payloadJson = JSON.stringify(input.payload);\n const payloadSha256 = sha256Hex(payloadJson);\n const origin = input.origin || 'local';\n\n const nextSeq = this.getLastSequence(input.deviceId) + 1;\n\n const stmt = this.db.prepare(`\n INSERT INTO outbox_events (\n event_id, device_id, project_id, sequence, operation,\n payload_json, payload_sha256, origin, attempts,\n next_attempt_at, created_at, acked_at, last_error\n ) VALUES (\n ?, ?, ?, ?, ?,\n ?, ?, ?, 0,\n ?, ?, NULL, NULL\n )\n `);\n\n stmt.run(\n eventId,\n input.deviceId,\n input.projectId,\n nextSeq,\n input.operation,\n payloadJson,\n payloadSha256,\n origin,\n now,\n now\n );\n\n return {\n eventId,\n deviceId: input.deviceId,\n projectId: input.projectId,\n sequence: nextSeq,\n operation: input.operation,\n payloadJson,\n payloadSha256,\n origin,\n attempts: 0,\n nextAttemptAt: now,\n createdAt: now,\n ackedAt: null,\n lastError: null\n };\n }\n\n public getDueEvents(limit = 50, force = false): OutboxRecord[] {\n const now = new Date().toISOString();\n const sql = force\n ? `SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n WHERE acked_at IS NULL\n ORDER BY sequence ASC\n LIMIT ?`\n : `SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n WHERE acked_at IS NULL AND next_attempt_at <= ?\n ORDER BY sequence ASC\n LIMIT ?`;\n\n const stmt = this.db.prepare(sql);\n return (force ? stmt.all(limit) : stmt.all(now, limit)) as unknown as OutboxRecord[];\n }\n\n public markAcked(eventIds: string[]): void {\n if (eventIds.length === 0) return;\n const now = new Date().toISOString();\n const placeholders = eventIds.map(() => '?').join(',');\n const stmt = this.db.prepare(`\n UPDATE outbox_events\n SET acked_at = ?\n WHERE event_id IN (${placeholders})\n `);\n stmt.run(now, ...eventIds);\n }\n\n public recordFailure(eventId: string, errorMessage: string): void {\n const stmt = this.db.prepare('SELECT attempts FROM outbox_events WHERE event_id = ?');\n const record = stmt.get(eventId) as { attempts: number } | undefined;\n\n if (!record) return;\n\n const newAttempts = record.attempts + 1;\n const delaySeconds = Math.min(300, Math.pow(2, Math.min(newAttempts, 8))) + Math.random() * 2;\n const nextAttempt = new Date(Date.now() + delaySeconds * 1000).toISOString();\n\n const updateStmt = this.db.prepare(`\n UPDATE outbox_events\n SET attempts = ?, next_attempt_at = ?, last_error = ?\n WHERE event_id = ?\n `);\n\n updateStmt.run(newAttempts, nextAttempt, errorMessage.slice(0, 500), eventId);\n }\n\n public getPendingCount(): number {\n const stmt = this.db.prepare('SELECT COUNT(*) as count FROM outbox_events WHERE acked_at IS NULL');\n const row = stmt.get() as { count: number };\n return row.count;\n }\n\n public getAllEvents(limit = 100): OutboxRecord[] {\n const stmt = this.db.prepare(`\n SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n ORDER BY sequence DESC\n LIMIT ?\n `);\n return stmt.all(limit) as unknown as OutboxRecord[];\n }\n\n public getState(key: string): string | null {\n const stmt = this.db.prepare('SELECT value FROM sync_state WHERE key = ?');\n const row = stmt.get(key) as { value: string } | undefined;\n return row?.value ?? null;\n }\n\n public setState(key: string, value: string): void {\n const stmt = this.db.prepare(`\n INSERT INTO sync_state (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n `);\n stmt.run(key, value);\n }\n\n public close(): void {\n this.db.close();\n }\n}\n","import { execSync } from 'child_process';\nimport path from 'path';\nimport fs from 'fs';\n\nexport interface LocalProjectContext {\n slug: string;\n name: string;\n gitRemote?: string;\n workingDir: string;\n}\n\nexport function sanitizeSlug(input: string): string {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'default-project';\n}\n\nexport function detectGitRemote(cwd = process.cwd()): string | undefined {\n try {\n const output = execSync('git remote get-url origin', {\n cwd,\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore']\n }).trim();\n if (output) return output;\n } catch {\n // Git remote not found or git not installed\n }\n return undefined;\n}\n\nexport function extractSlugFromGitRemote(remoteUrl: string): string | undefined {\n try {\n // Examples:\n // https://github.com/org/repo.git -> org-repo or repo\n // git@github.com:org/repo.git -> org-repo or repo\n const cleaned = remoteUrl.replace(/\\.git$/, '').trim();\n const parts = cleaned.split(/[/:]/);\n if (parts.length >= 2) {\n const repo = parts[parts.length - 1];\n const owner = parts[parts.length - 2];\n if (repo && owner && !owner.includes('@') && !owner.includes('//')) {\n return sanitizeSlug(`${owner}-${repo}`);\n }\n if (repo) {\n return sanitizeSlug(repo);\n }\n }\n } catch {\n // Fallback\n }\n return undefined;\n}\n\nexport function detectPackageName(cwd = process.cwd()): string | undefined {\n try {\n const pkgPath = path.join(cwd, 'package.json');\n if (fs.existsSync(pkgPath)) {\n const content = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (content.name && typeof content.name === 'string') {\n return sanitizeSlug(content.name.replace(/^@[^/]+\\//, ''));\n }\n }\n } catch {\n // Ignore\n }\n\n try {\n const pyprojectPath = path.join(cwd, 'pyproject.toml');\n if (fs.existsSync(pyprojectPath)) {\n const content = fs.readFileSync(pyprojectPath, 'utf8');\n const match = content.match(/name\\s*=\\s*[\"']([^\"']+)[\"']/);\n if (match && match[1]) {\n return sanitizeSlug(match[1]);\n }\n }\n } catch {\n // Ignore\n }\n\n return undefined;\n}\n\nexport function detectProjectContext(cwd = process.cwd()): LocalProjectContext {\n const gitRemote = detectGitRemote(cwd);\n let slug: string | undefined;\n let name: string | undefined;\n\n if (gitRemote) {\n slug = extractSlugFromGitRemote(gitRemote);\n }\n\n if (!slug) {\n slug = detectPackageName(cwd);\n }\n\n if (!slug) {\n const dirName = path.basename(path.resolve(cwd));\n slug = sanitizeSlug(dirName);\n name = dirName;\n } else {\n name = slug.replace(/[-_]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\n }\n\n return {\n slug,\n name: name || slug,\n gitRemote,\n workingDir: cwd\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { randomUUID } from 'crypto';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\nexport interface MemHubConfig {\n apiUrl: string;\n apiKey?: string;\n projectId?: string;\n projectSlug?: string;\n orgId?: string;\n deviceId: string;\n outboxPath: string;\n storageDir: string;\n}\n\n/**\n * @deprecated Legacy type alias kept for backwards compatibility. Use `MemHubConfig`.\n */\nexport type TeamContextConfig = MemHubConfig;\n\nexport function defaultStorageDir(): string {\n return path.join(os.homedir(), '.memhub');\n}\n\n/** Resolves the active storage dir consistently for reads and writes. */\nexport function resolveStorageDir(): string {\n return process.env.MEMHUB_DIR\n || process.env.TEAMCONTEXT_DIR // deprecated alias\n || defaultStorageDir();\n}\n\n/**\n * @deprecated Legacy config directory, read only when the MemHub directory has no saved config.\n */\nexport function legacyStorageDir(): string {\n return path.join(os.homedir(), '.teamcontext');\n}\n\nfunction configFile(dir: string): string {\n return path.join(dir, 'config.json');\n}\n\nconst IS_POSIX = process.platform !== 'win32';\n\n/** Owner-only directory (0700) so stored credentials are not world-readable. */\nexport function ensureDirectory(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n if (IS_POSIX) {\n try { fs.chmodSync(dir, 0o700); } catch { /* best effort on shared mounts */ }\n }\n}\n\n/** Resolves MEMHUB_* first, falling back to deprecated TEAMCONTEXT_* aliases. */\nfunction envPreferred(name: string): string | undefined {\n return process.env[name] || process.env[name.replace(/^MEMHUB_/, 'TEAMCONTEXT_')];\n}\n\nexport function loadSavedConfig(): Partial<MemHubConfig> {\n const paths = [configFile(defaultStorageDir()), configFile(legacyStorageDir())];\n for (const file of paths) {\n try {\n if (fs.existsSync(file)) {\n return JSON.parse(fs.readFileSync(file, 'utf8'));\n }\n } catch (err) {\n // Ignore read errors\n }\n }\n return {};\n}\n\n/**\n * Persists config (including the API credential) into the storage dir.\n * The file is written with mode 0600 and tightened afterwards so a previously\n * world-readable config cannot stay exposed. Best effort on platforms that\n * ignore POSIX permissions.\n */\nexport function saveConfig(updates: Partial<MemHubConfig>): void {\n const dir = resolveStorageDir();\n ensureDirectory(dir);\n const current = loadSavedConfig();\n const merged = { ...current, ...updates };\n const file = configFile(dir);\n fs.writeFileSync(file, JSON.stringify(merged, null, 2), { encoding: 'utf8', mode: 0o600 });\n if (IS_POSIX) {\n try { fs.chmodSync(file, 0o600); } catch { /* best effort */ }\n }\n}\n\n/** Removes MemHub credentials and the local durable sync queue without touching cloud history. */\nexport function clearLocalState(): void {\n const saved = loadSavedConfig();\n const dir = resolveStorageDir();\n const files = new Set([\n configFile(dir),\n saved.outboxPath,\n envPreferred('MEMHUB_OUTBOX_PATH'),\n path.join(dir, 'outbox.db'),\n ].filter((value): value is string => Boolean(value)));\n for (const file of files) {\n for (const candidate of [file, `${file}-wal`, `${file}-shm`]) {\n try { if (fs.existsSync(candidate)) fs.unlinkSync(candidate); } catch { /* best effort */ }\n }\n }\n}\n\nexport function getOrCreateDeviceId(): string {\n const saved = loadSavedConfig();\n if (saved.deviceId && saved.deviceId.length > 10) {\n return saved.deviceId;\n }\n const newDeviceId = randomUUID();\n saveConfig({ deviceId: newDeviceId });\n return newDeviceId;\n}\n\nexport function getConfig(): MemHubConfig {\n const saved = loadSavedConfig();\n const storageDir = resolveStorageDir();\n ensureDirectory(storageDir);\n\n const deviceId = envPreferred('MEMHUB_DEVICE_ID') || saved.deviceId || getOrCreateDeviceId();\n const apiUrl = envPreferred('MEMHUB_API_URL') || saved.apiUrl || 'https://memhub.simplex.lat';\n const apiKey = envPreferred('MEMHUB_API_KEY') || saved.apiKey;\n const projectId = envPreferred('MEMHUB_PROJECT_ID') || saved.projectId;\n const projectSlug = envPreferred('MEMHUB_PROJECT') || saved.projectSlug;\n const orgId = envPreferred('MEMHUB_ORG_ID') || saved.orgId;\n const outboxPath = envPreferred('MEMHUB_OUTBOX_PATH') || path.join(storageDir, 'outbox.db');\n\n return {\n apiUrl: apiUrl.replace(/\\/$/, ''),\n apiKey,\n projectId,\n projectSlug,\n orgId,\n deviceId,\n outboxPath,\n storageDir\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { RulesInjector } from './rules-injector.js';\n\nexport interface InjectOptions {\n apiKey: string;\n apiUrl?: string;\n projectId?: string;\n cwd?: string;\n dryRun?: boolean;\n}\n\nexport interface InjectionResult {\n target: string;\n filePath: string;\n success: boolean;\n action: 'created' | 'updated' | 'unchanged' | 'error';\n backupPath?: string;\n error?: string;\n}\n\nexport class IdeConfigInjector {\n private static serverConfig() {\n return { command: 'memhub', args: ['serve'] };\n }\n\n private static injectJsonMcpConfig(\n target: string,\n configPath: string,\n options: InjectOptions,\n ): InjectionResult {\n try {\n const parent = path.dirname(configPath);\n if (!fs.existsSync(parent) && !options.dryRun) fs.mkdirSync(parent, { recursive: true });\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n const existed = fs.existsSync(configPath);\n if (!options.dryRun) fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n return { target, filePath: configPath, success: true, action: existed ? 'updated' : 'created' };\n } catch (err: any) {\n return { target, filePath: configPath, success: false, action: 'error', error: err.message };\n }\n }\n\n /**\n * Injects config and memory rules for Claude Code (`mcp.json` and `CLAUDE.md`)\n */\n public static injectClaudeCode(options: InjectOptions): InjectionResult {\n const cwd = options.cwd || process.cwd();\n const configPath = path.join(cwd, 'mcp.json');\n try {\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n\n if (!options.dryRun) {\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n RulesInjector.injectClaudeCode(cwd);\n }\n\n return {\n target: 'Claude Code',\n filePath: configPath,\n success: true,\n action: fs.existsSync(configPath) ? 'updated' : 'created'\n };\n } catch (err: any) {\n return {\n target: 'Claude Code',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /**\n * Injects config and memory rules for Cursor (`.cursor/mcp.json` and `.cursorrules`)\n */\n public static injectCursor(options: InjectOptions): InjectionResult {\n const cwd = options.cwd || process.cwd();\n const cursorDir = path.join(cwd, '.cursor');\n const configPath = path.join(cursorDir, 'mcp.json');\n try {\n if (!fs.existsSync(cursorDir) && !options.dryRun) {\n fs.mkdirSync(cursorDir, { recursive: true });\n }\n\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n\n if (!options.dryRun) {\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n RulesInjector.injectCursor(cwd);\n }\n\n return {\n target: 'Cursor',\n filePath: configPath,\n success: true,\n action: fs.existsSync(configPath) ? 'updated' : 'created'\n };\n } catch (err: any) {\n return {\n target: 'Cursor',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /** Google Antigravity 2.0 / IDE / CLI shared global MCP configuration and rules. */\n public static injectAntigravity(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Google Antigravity',\n path.join(os.homedir(), '.gemini', 'config', 'mcp_config.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectAntigravity(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Windsurf Cascade global MCP configuration and rules. */\n public static injectWindsurf(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Windsurf',\n path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectWindsurf(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Cline global MCP configuration and rules. */\n public static injectCline(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Cline',\n path.join(os.homedir(), '.cline', 'data', 'settings', 'cline_mcp_settings.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectCline(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Generic JSON client using the common { mcpServers: {} } format. */\n public static injectOther(configPath: string, options: InjectOptions): InjectionResult {\n return this.injectJsonMcpConfig('Other MCP client', path.resolve(configPath), options);\n }\n\n /**\n * Injects config and memory rules for Codex CLI (`config.toml` and `AGENTS.md`)\n */\n public static injectCodex(options: InjectOptions): InjectionResult {\n const codexDir = path.join(os.homedir(), '.codex');\n const configPath = path.join(codexDir, 'config.toml');\n try {\n if (!fs.existsSync(codexDir) && !options.dryRun) {\n fs.mkdirSync(codexDir, { recursive: true });\n }\n\n const entry = `\n# MemHub MCP Connector\n[mcp.servers.memhub]\ncommand = \"memhub\"\nargs = [\"serve\"]\n`;\n\n let content = '';\n if (fs.existsSync(configPath)) {\n content = fs.readFileSync(configPath, 'utf8');\n }\n\n if (!content.includes('[mcp.servers.memhub]')) {\n content += entry;\n if (!options.dryRun) {\n fs.writeFileSync(configPath, content, 'utf8');\n }\n }\n\n if (!options.dryRun) {\n RulesInjector.injectCodex(options.cwd || process.cwd());\n }\n\n return {\n target: 'Codex CLI',\n filePath: configPath,\n success: true,\n action: 'updated'\n };\n } catch (err: any) {\n return {\n target: 'Codex CLI',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /**\n * Injects for all supported IDEs and tools\n */\n public static injectAll(options: InjectOptions): InjectionResult[] {\n return [\n this.injectClaudeCode(options),\n this.injectCursor(options),\n this.injectCodex(options),\n this.injectAntigravity(options),\n this.injectWindsurf(options),\n this.injectCline(options)\n ];\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\n\nexport const MEMHUB_RULES_BEGIN_MARKER = '<!-- BEGIN MEMHUB MEMORY PROTOCOL — managed by memhub -->';\nexport const MEMHUB_RULES_END_MARKER = '<!-- END MEMHUB MEMORY PROTOCOL -->';\n\nexport const MEMHUB_PROTOCOL_INSTRUCTIONS = `${MEMHUB_RULES_BEGIN_MARKER}\n\n## MemHub Persistent Shared Memory — Protocol\n\nYou have access to MemHub, a persistent memory and team knowledge system that survives across sessions, compactions, and teammates.\n\n### WHEN TO SAVE TO MEMORY (mandatory — not optional)\n\nCall \\`mem_save\\` (or \\`memory_save\\`) IMMEDIATELY after any of these:\n- Bug fix completed\n- Architecture or design decision made\n- Non-obvious discovery about the codebase\n- Configuration change or environment setup\n- Pattern established (naming, structure, convention)\n- User preference or team constraint learned\n\nFormat for \\`mem_save\\`:\n- **title**: Verb + what — short, searchable (e.g. \"Fixed N+1 query in UserList\", \"Chose Zustand over Redux\")\n- **type**: bugfix | decision | architecture | discovery | pattern | config | preference\n- **scope**: project (default) | personal\n- **topic_key** (recommended for evolving topics): stable key like architecture/auth-model\n- **content**:\n **What**: One sentence — what was done\n **Why**: What motivated it (user request, bug, performance, etc.)\n **Where**: Files or paths affected\n **Learned**: Gotchas, edge cases, things that surprised you (omit if none)\n\n### WHEN TO SEARCH MEMORY (mandatory)\n\nWhen the user asks to recall something or references past work (\"remember\", \"recall\", \"what did we do\", \"cómo lo resolvimos\", \"qué hicimos\"):\n1. First call \\`mem_context\\` (fast recent session history)\n2. Call \\`mem_search\\` (or \\`memory_recall\\`) with relevant keywords (hybrid lexical + vector search)\n3. If needed, use \\`mem_get_observation\\` for full untruncated content\n\nAlso search memory PROACTIVELY when:\n- Starting work on an unfamiliar area of the codebase\n- The user mentions a technical topic you have no context on\n\n### SESSION CLOSE PROTOCOL (mandatory)\n\nBefore ending a session or declaring a milestone done, call \\`mem_session_summary\\`:\n- **Goal**: What was worked on this session\n- **Discoveries**: Technical findings and gotchas\n- **Accomplished**: Key completed items\n- **Next Steps**: What remains for subsequent sessions\n- **Relevant Files**: Changed files and their purpose\n\n### PASSIVE CAPTURE\n\nWhen completing a task, include a \\`## Key Learnings:\\` section at the end of your response with numbered items. MemHub will automatically capture and persist these learnings for the team.\n\n${MEMHUB_RULES_END_MARKER}`;\n\nexport interface RuleInjectionResult {\n target: string;\n filePath: string;\n success: boolean;\n action: 'created' | 'updated' | 'unchanged' | 'error';\n error?: string;\n}\n\nexport class RulesInjector {\n /**\n * Injects or updates the managed MemHub rules block inside a markdown file.\n */\n public static injectIntoFile(filePath: string, targetName: string): RuleInjectionResult {\n try {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n let content = '';\n const existed = fs.existsSync(filePath);\n if (existed) {\n content = fs.readFileSync(filePath, 'utf8');\n }\n\n let updatedContent = '';\n if (content.includes(MEMHUB_RULES_BEGIN_MARKER) && content.includes(MEMHUB_RULES_END_MARKER)) {\n const regex = new RegExp(\n `${MEMHUB_RULES_BEGIN_MARKER}[\\\\s\\\\S]*?${MEMHUB_RULES_END_MARKER}`,\n 'g'\n );\n updatedContent = content.replace(regex, MEMHUB_PROTOCOL_INSTRUCTIONS);\n } else {\n updatedContent = content.trim() ? `${content.trim()}\\n\\n${MEMHUB_PROTOCOL_INSTRUCTIONS}\\n` : `${MEMHUB_PROTOCOL_INSTRUCTIONS}\\n`;\n }\n\n if (existed && content.trim() === updatedContent.trim()) {\n return { target: targetName, filePath, success: true, action: 'unchanged' };\n }\n\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n return { target: targetName, filePath, success: true, action: existed ? 'updated' : 'created' };\n } catch (err: any) {\n return { target: targetName, filePath, success: false, action: 'error', error: err.message };\n }\n }\n\n /**\n * Injects rules for Claude Code (`CLAUDE.md` and `~/.claude/CLAUDE.md`)\n */\n public static injectClaudeCode(cwd = process.cwd()): RuleInjectionResult[] {\n const local = this.injectIntoFile(path.join(cwd, 'CLAUDE.md'), 'Claude Code (Workspace)');\n const globalPath = path.join(os.homedir(), '.claude', 'CLAUDE.md');\n const global = this.injectIntoFile(globalPath, 'Claude Code (Global)');\n return [local, global];\n }\n\n /**\n * Injects rules for Cursor (`.cursorrules` and `.cursor/rules/memhub.mdc`)\n */\n public static injectCursor(cwd = process.cwd()): RuleInjectionResult[] {\n const cursorRules = this.injectIntoFile(path.join(cwd, '.cursorrules'), 'Cursor (.cursorrules)');\n const mdcPath = path.join(cwd, '.cursor', 'rules', 'memhub.mdc');\n const mdc = this.injectIntoFile(mdcPath, 'Cursor MDC (.cursor/rules/memhub.mdc)');\n return [cursorRules, mdc];\n }\n\n /**\n * Injects rules for Google Antigravity / Gemini CLI\n */\n public static injectAntigravity(cwd = process.cwd()): RuleInjectionResult[] {\n const localRule = path.join(cwd, '.gemini', 'antigravity-cli', 'rules', 'memhub.md');\n const globalRule = path.join(os.homedir(), '.gemini', 'antigravity-cli', 'rules', 'memhub.md');\n const legacyGlobalRule = path.join(os.homedir(), '.gemini', 'config', 'rules', 'memhub.md');\n return [\n this.injectIntoFile(localRule, 'Antigravity (Workspace)'),\n this.injectIntoFile(globalRule, 'Antigravity (Global)'),\n this.injectIntoFile(legacyGlobalRule, 'Antigravity Config (Global)')\n ];\n }\n\n /**\n * Injects rules for Windsurf (`.windsurfrules`)\n */\n public static injectWindsurf(cwd = process.cwd()): RuleInjectionResult[] {\n return [this.injectIntoFile(path.join(cwd, '.windsurfrules'), 'Windsurf (.windsurfrules)')];\n }\n\n /**\n * Injects rules for Cline / Roo Code (`.clinerules`)\n */\n public static injectCline(cwd = process.cwd()): RuleInjectionResult[] {\n return [this.injectIntoFile(path.join(cwd, '.clinerules'), 'Cline (.clinerules)')];\n }\n\n /**\n * Injects rules for Codex CLI & General Agent specification (`AGENTS.md`)\n */\n public static injectCodex(cwd = process.cwd()): RuleInjectionResult[] {\n const localAgents = this.injectIntoFile(path.join(cwd, 'AGENTS.md'), 'Agents Specification (AGENTS.md)');\n const globalCodex = this.injectIntoFile(path.join(os.homedir(), '.codex', 'instructions.md'), 'Codex CLI (Global instructions)');\n return [localAgents, globalCodex];\n }\n\n /**\n * Injects rules across all supported AI coding agents.\n */\n public static injectAll(cwd = process.cwd()): RuleInjectionResult[] {\n return [\n ...this.injectClaudeCode(cwd),\n ...this.injectCursor(cwd),\n ...this.injectAntigravity(cwd),\n ...this.injectWindsurf(cwd),\n ...this.injectCline(cwd),\n ...this.injectCodex(cwd)\n ];\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport https from 'https';\nimport { resolveStorageDir, ensureDirectory } from './config.js';\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n}\n\nconst CHECK_INTERVAL_MS = 6 * 60 * 60 * 1000; // 6 hours\nconst PACKAGE_NAME = '@simplexlat/memhub';\n\nfunction compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = v2.split('.').map((p) => parseInt(p, 10) || 0);\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const num1 = parts1[i] || 0;\n const num2 = parts2[i] || 0;\n if (num1 > num2) return 1;\n if (num1 < num2) return -1;\n }\n return 0;\n}\n\nasync function fetchLatestFromNpm(): Promise<string | null> {\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,\n {\n headers: { 'User-Agent': 'memhub-cli' },\n timeout: 1500,\n },\n (res) => {\n if (res.statusCode !== 200) {\n resolve(null);\n return;\n }\n let data = '';\n res.on('data', (chunk) => {\n data += chunk;\n });\n res.on('end', () => {\n try {\n const parsed = JSON.parse(data);\n resolve(parsed.version || null);\n } catch {\n resolve(null);\n }\n });\n }\n );\n req.on('error', () => resolve(null));\n req.on('timeout', () => {\n req.destroy();\n resolve(null);\n });\n });\n}\n\nexport class UpdateNotifier {\n private static cacheFile(): string {\n return path.join(resolveStorageDir(), 'update-cache.json');\n }\n\n public static async checkForUpdates(currentVersion: string): Promise<void> {\n // Skip notifier in stdio proxy serve mode or during update command\n if (process.argv.includes('serve') || process.argv.includes('update')) {\n return;\n }\n\n try {\n const storageDir = resolveStorageDir();\n ensureDirectory(storageDir);\n const cachePath = this.cacheFile();\n\n let cache: UpdateCache = { lastChecked: 0, latestVersion: currentVersion };\n if (fs.existsSync(cachePath)) {\n try {\n cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));\n } catch {\n // ignore corrupted cache\n }\n }\n\n const now = Date.now();\n let latestVersion = cache.latestVersion;\n\n // If cache is expired, fetch in background\n if (now - cache.lastChecked > CHECK_INTERVAL_MS) {\n const fetched = await fetchLatestFromNpm();\n if (fetched) {\n latestVersion = fetched;\n cache = { lastChecked: now, latestVersion: fetched };\n try {\n fs.writeFileSync(cachePath, JSON.stringify(cache), 'utf8');\n } catch {\n // ignore\n }\n }\n }\n\n // If a newer version exists, show a notification banner\n if (compareVersions(latestVersion, currentVersion) > 0) {\n process.on('exit', () => {\n console.error('\\n┌────────────────────────────────────────────────────────────┐');\n console.error(`│ 🚀 Actualización disponible para MemHub: ${currentVersion} → \\x1b[32m${latestVersion}\\x1b[0m │`);\n console.error('│ Ejecuta \\x1b[1m\\x1b[36mmh update\\x1b[0m para instalar la última versión. │');\n console.error('└────────────────────────────────────────────────────────────┘\\n');\n });\n }\n } catch {\n // Non-blocking, never crash the user command\n }\n }\n}\n","/**\n * Browser-based `mh login` orchestration.\n *\n * The CLI never sees a password: it creates an expiring single-use device code,\n * opens the MemHub consent page in the user's browser, and polls until the user\n * approves or denies. The approved scoped credential is delivered exactly once.\n */\n\nimport { spawn } from 'node:child_process';\n\nexport interface CliAuthInitiation {\n deviceCode: string;\n verificationUrl: string;\n expiresAt: string;\n expiresInSeconds: number;\n pollIntervalSeconds: number;\n}\n\nexport interface CliAuthApproval {\n status: 'approved';\n apiKey: string;\n keyPrefix: string;\n keyExpiresAt: string | null;\n orgSlug: string | null;\n orgName: string | null;\n projectSlug: string | null;\n projectName: string | null;\n}\n\nexport type CliAuthPollResponse = CliAuthApproval\n | { status: 'pending'; expiresAt?: string | null }\n | { status: 'denied' }\n | { status: 'consumed' }\n | { status: 'not_found' };\n\nexport class LoginDeniedError extends Error {\n constructor() { super('Login request denied in the browser.'); this.name = 'LoginDeniedError'; }\n}\n\nexport class LoginExpiredError extends Error {\n constructor() { super('Login request expired before approval. Run `mh login` again.'); this.name = 'LoginExpiredError'; }\n}\n\nexport class LoginTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Login was not approved within ${Math.round(timeoutMs / 1000)}s. Run \\`mh login\\` again.`);\n this.name = 'LoginTimeoutError';\n }\n}\n\nexport interface LoginRequestOptions {\n label?: string;\n scopes?: string[];\n timeoutMs?: number;\n fetchImpl?: typeof fetch;\n sleepImpl?: (ms: number) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;\nconst MIN_SLEEP_MS = 250;\n\nexport function defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Creates the expiring device code pair server-side; only digests are stored remotely. */\nexport async function requestCliAuth(\n apiUrl: string,\n options: LoginRequestOptions = {},\n): Promise<CliAuthInitiation> {\n const doFetch = options.fetchImpl ?? fetch;\n const res = await doFetch(`${apiUrl}/api/cli-auth/initiate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ label: options.label, scopes: options.scopes }),\n });\n if (!res.ok) {\n throw new Error(`Unable to start login (${res.status}). Check that ${apiUrl} is reachable.`);\n }\n return await res.json() as CliAuthInitiation;\n}\n\nasync function pollOnce(\n apiUrl: string,\n deviceCode: string,\n doFetch: typeof fetch,\n): Promise<{ result: CliAuthPollResponse; retryAfterSeconds: number | null }> {\n const res = await doFetch(`${apiUrl}/api/cli-auth/poll`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ deviceCode }),\n });\n if (res.status === 429) {\n const retryAfter = Number(res.headers.get('retry-after'));\n return {\n result: { status: 'pending', expiresAt: null },\n retryAfterSeconds: Number.isFinite(retryAfter) && retryAfter > 0 ? Math.ceil(retryAfter) : null,\n };\n }\n if (!res.ok) throw new Error(`Login polling failed (${res.status}).`);\n return { result: await res.json() as CliAuthPollResponse, retryAfterSeconds: null };\n}\n\nexport interface WaitOutcome {\n apiKey: string;\n keyPrefix: string;\n orgSlug: string | null;\n orgName: string | null;\n projectSlug: string | null;\n projectName: string | null;\n}\n\n/**\n * Bounded polling loop: stops at the deadline (matching the server-side code\n * TTL), backs off when rate limited, and aborts immediately on deny/expiry.\n */\nexport async function waitForCliApproval(\n apiUrl: string,\n initiation: Pick<CliAuthInitiation, 'deviceCode' | 'pollIntervalSeconds'>,\n options: LoginRequestOptions = {},\n): Promise<WaitOutcome> {\n const doFetch = options.fetchImpl ?? fetch;\n const sleep = options.sleepImpl ?? defaultSleep;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n\n let pendingNoticeShown = false;\n while (Date.now() < deadline) {\n const { result, retryAfterSeconds } = await pollOnce(apiUrl, initiation.deviceCode, doFetch);\n\n if (result.status === 'approved') {\n if (!result.apiKey) throw new Error('Server returned an empty credential.');\n return {\n apiKey: result.apiKey,\n keyPrefix: result.keyPrefix,\n orgSlug: result.orgSlug,\n orgName: result.orgName,\n projectSlug: result.projectSlug,\n projectName: result.projectName,\n };\n }\n if (result.status === 'denied') throw new LoginDeniedError();\n if (result.status === 'consumed' || result.status === 'not_found') throw new LoginExpiredError();\n\n if (!pendingNoticeShown) {\n process.stderr.write('⏳ Waiting for approval in your browser…\\n');\n pendingNoticeShown = true;\n }\n\n const intervalMs = Math.max((initiation.pollIntervalSeconds || 2) * 1000, MIN_SLEEP_MS);\n const backoffMs = retryAfterSeconds ? Math.min(retryAfterSeconds * 1000, 30_000) : intervalMs;\n const remainingMs = deadline - Date.now();\n await sleep(Math.max(MIN_SLEEP_MS, Math.min(backoffMs, remainingMs)));\n }\n throw new LoginTimeoutError(timeoutMs);\n}\n\nexport interface BrowserOpenCommand {\n command: string;\n args: string[];\n}\n\n/** Pure mapping used by openInBrowser; exported for deterministic tests. */\nexport function browserOpenCommand(platform: string = process.platform): BrowserOpenCommand {\n const command = platform === 'darwin' ? 'open'\n : platform === 'win32' ? 'cmd'\n : 'xdg-open';\n return command === 'cmd' ? { command, args: ['/c', 'start', '', '<url>'] } : { command, args: ['<url>'] };\n}\n\n/** Platform-aware best-effort browser open; never throws and never blocks. */\nexport function openInBrowser(url: string): boolean {\n try {\n const { command, args } = browserOpenCommand();\n const child = spawn(command, args.map((arg) => (arg === '<url>' ? url : arg)), { stdio: 'ignore', detached: true });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["randomUUID","input","randomUUID","path","fs","input","output","fs","path","randomUUID","fs","path","os","fs","path","os","path","fs","os","execSync","path","fs","path","path","fs","path","execSync"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/proxy/server.ts","../../protocol/src/schemas.ts","../../protocol/src/ids.ts","../../protocol/src/tools-list.ts","../src/proxy/local-engine.ts","../src/sync/engine.ts","../src/sync/client.ts","../src/outbox/db.ts","../src/project-resolver.ts","../src/config.ts","../src/connectors/ide-injector.ts","../src/connectors/rules-injector.ts","../src/update-notifier.ts","../src/auth/login-flow.ts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { MemHubMcpServer } from './proxy/server.js';\nimport { clearLocalState, getConfig, saveConfig } from './config.js';\nimport { IdeConfigInjector } from './connectors/ide-injector.js';\nimport { CloudApiClient } from './sync/client.js';\nimport { OutboxDb } from './outbox/db.js';\nimport { detectProjectContext } from './project-resolver.js';\nimport { AGENTMEMORY_54_TOOLS } from '@memhub/protocol';\nimport { createInterface } from 'node:readline/promises';\nimport { stdin as input, stdout as output } from 'node:process';\nimport { hostname } from 'node:os';\nimport { execSync } from 'node:child_process';\nimport path from 'node:path';\nimport { RulesInjector } from './connectors/rules-injector.js';\nimport { UpdateNotifier, fetchLatestFromNpm, compareVersions } from './update-notifier.js';\nimport { requestCliAuth, waitForCliApproval, openInBrowser, LoginDeniedError, LoginExpiredError, LoginTimeoutError } from './auth/login-flow.js';\n\nconst CLI_VERSION = '0.1.3';\nvoid UpdateNotifier.checkForUpdates(CLI_VERSION);\n\nconst program = new Command();\n\nconst supportedTargets = ['claude', 'cursor', 'windsurf', 'cline', 'codex', 'antigravity'] as const;\ntype InstallTarget = typeof supportedTargets[number] | 'other';\n\nasync function selectInstallTargets(value?: string, otherConfig?: string): Promise<InstallTarget[]> {\n if (value) {\n const requested = value.toLowerCase().split(',').map((item) => item.trim()).filter(Boolean);\n const expanded = requested.includes('all') ? [...supportedTargets] : requested;\n const invalid = expanded.filter((item) => !supportedTargets.includes(item as any) && item !== 'other');\n if (invalid.length) throw new Error(`Unsupported IDE target(s): ${invalid.join(', ')}`);\n if (expanded.includes('other') && !otherConfig) throw new Error('--config <path> is required with --ide other');\n return [...new Set(expanded)] as InstallTarget[];\n }\n\n if (!input.isTTY || !output.isTTY) return [...supportedTargets];\n const rl = createInterface({ input, output });\n output.write('\\nWhere should MemHub be installed? Select one or more (comma-separated):\\n');\n output.write(' 1) Claude Code\\n 2) Cursor\\n 3) Windsurf\\n 4) Cline\\n 5) Codex CLI\\n 6) Google Antigravity\\n 7) All supported clients\\n 8) Other JSON MCP client\\n');\n const answer = await rl.question('Selection [7]: ');\n rl.close();\n const choices = (answer.trim() || '7').split(',').map((item) => item.trim());\n if (choices.includes('7')) return [...supportedTargets];\n const map: Record<string, InstallTarget> = { '1': 'claude', '2': 'cursor', '3': 'windsurf', '4': 'cline', '5': 'codex', '6': 'antigravity', '8': 'other' };\n const selected = choices.map((choice) => map[choice]).filter(Boolean);\n if (!selected.length) throw new Error('No valid installation target selected');\n if (selected.includes('other') && !otherConfig) throw new Error('Use --config <path> when selecting Other');\n return [...new Set(selected)];\n}\n\ninterface InjectTargetsOptions {\n apiKey: string;\n apiUrl: string;\n projectSlug: string;\n ide?: string;\n configPath?: string;\n}\n\n/** Shared tail of `connect` and `login`: pick clients and inject MCP config. */\nasync function installToSelectedClients(options: InjectTargetsOptions): Promise<void> {\n const targets = await selectInstallTargets(options.ide, options.configPath);\n console.log(`🔧 Injecting MCP server configuration for: ${targets.join(', ')}...`);\n const injectOpts = {\n apiKey: options.apiKey,\n apiUrl: options.apiUrl,\n projectId: options.projectSlug\n };\n\n const results = [];\n for (const target of targets) {\n if (target === 'claude') results.push(IdeConfigInjector.injectClaudeCode(injectOpts));\n if (target === 'cursor') results.push(IdeConfigInjector.injectCursor(injectOpts));\n if (target === 'windsurf') results.push(IdeConfigInjector.injectWindsurf(injectOpts));\n if (target === 'cline') results.push(IdeConfigInjector.injectCline(injectOpts));\n if (target === 'codex') results.push(IdeConfigInjector.injectCodex(injectOpts));\n if (target === 'antigravity') results.push(IdeConfigInjector.injectAntigravity(injectOpts));\n if (target === 'other') results.push(IdeConfigInjector.injectOther(options.configPath!, injectOpts));\n }\n\n for (const res of results) {\n if (res.success) {\n console.log(` ✓ ${res.target}: MCP configured at ${res.filePath}`);\n } else {\n console.log(` ✗ ${res.target}: failed (${res.error})`);\n }\n }\n\n console.log('📝 Injecting MemHub memory protocol instructions into workspace & global rules...');\n const ruleResults = RulesInjector.injectAll(process.cwd());\n for (const r of ruleResults) {\n if (r.success && r.action !== 'unchanged') {\n console.log(` ✓ ${r.target}: rules ${r.action}`);\n }\n }\n}\n\nprogram\n .name('memhub')\n .description('Local-first MCP proxy for MemHub & agentmemory')\n .version('0.1.3');\n\nprogram\n .command('serve')\n .description('Start the MemHub MCP stdio proxy server')\n .action(async () => {\n const config = getConfig();\n const server = new MemHubMcpServer(config);\n await server.start();\n });\n\nprogram\n .command('install [target]')\n .description('Install the global MemHub MCP server into an AI client (or use generic)')\n .option('--config <path>', 'JSON MCP config path for a generic/other client')\n .action(async (target, options) => {\n const config = getConfig();\n if (!config.apiKey) {\n console.error('No MemHub session is configured. Run `memhub login` first.');\n process.exitCode = 1;\n return;\n }\n if (target === 'generic' && !options.config) {\n console.log(JSON.stringify({\n mcpServers: { memhub: { command: 'memhub', args: ['serve'] } },\n }, null, 2));\n return;\n }\n await installToSelectedClients({\n apiKey: config.apiKey,\n apiUrl: config.apiUrl,\n projectSlug: config.projectSlug || detectProjectContext().slug,\n ide: target === 'generic' ? 'other' : target,\n configPath: options.config,\n });\n });\n\nprogram\n .command('connect')\n .description('Connect the current repository or workspace to MemHub Cloud')\n .requiredOption('-k, --key <apiKey>', 'MemHub API Key (e.g. mh_live_...)')\n .option('-u, --url <apiUrl>', 'MemHub Cloud API URL', 'https://memhub.simplex.lat')\n .option('-p, --project <projectSlug>', 'Override project slug')\n .option('--ide <ides>', 'Comma-separated targets: all, claude, cursor, windsurf, cline, codex, antigravity, other')\n .option('--config <path>', 'JSON MCP config path when using --ide other')\n .action(async (options) => {\n console.log('🚀 Connecting to MemHub Cloud...');\n\n const detected = detectProjectContext();\n const projectSlug = options.project || detected.slug;\n\n saveConfig({\n apiKey: options.key,\n apiUrl: options.url,\n projectSlug\n });\n\n const client = new CloudApiClient(options.url, options.key);\n console.log(`📡 Resolving project \"${projectSlug}\" on cloud...`);\n\n try {\n const resolved = await client.resolveProject({\n slug: projectSlug,\n gitRemote: detected.gitRemote,\n name: detected.name\n });\n console.log(`✅ Project resolved: ${resolved.projectName} (ID: ${resolved.projectId}, Org: ${resolved.orgSlug})`);\n saveConfig({\n projectId: resolved.projectId,\n orgId: resolved.orgId\n });\n } catch (err: any) {\n console.warn(`⚠️ Cloud project resolution warning: ${err.message}`);\n console.log(' (Local memory and offline outbox will continue to work normally)');\n }\n\n await installToSelectedClients({\n apiKey: options.key,\n apiUrl: options.url,\n projectSlug,\n ide: options.ide,\n configPath: options.config\n });\n\n console.log('\\n🎉 MemHub MCP proxy successfully connected!');\n console.log(' Restart or refresh the selected AI clients to load MemHub.');\n });\n\nprogram\n .command('login')\n .description('Sign in with your browser, consent to a scoped project credential, then pick AI clients to configure')\n .option('-u, --url <apiUrl>', 'MemHub Cloud API URL', 'https://memhub.simplex.lat')\n .option('--ide <ides>', 'Comma-separated targets: all, claude, cursor, windsurf, cline, codex, antigravity, other')\n .option('--config <path>', 'JSON MCP config path when using --ide other')\n .option('--label <label>', 'Device label shown on the consent page')\n .option('--no-open', 'Print the verification URL instead of opening a browser')\n .action(async (options) => {\n try {\n console.log('🔐 Starting browser login for MemHub Cloud...');\n const initiation = await requestCliAuth(options.url, {\n label: options.label || `${hostname()} terminal`,\n });\n\n const opened = options.open ? openInBrowser(initiation.verificationUrl) : false;\n if (!opened) {\n console.log('\\n🌐 Open this URL in any browser to continue:');\n console.log(` ${initiation.verificationUrl}`);\n } else {\n console.log(`\\n🌐 Browser opened at ${options.url}/cli-auth — sign in, review the request, and approve.`);\n }\n console.log('⏱️ The login request expires in 15 minutes and can be approved only once.');\n\n const approval = await waitForCliApproval(options.url, initiation);\n\n saveConfig({\n apiKey: approval.apiKey,\n apiUrl: options.url,\n projectSlug: approval.projectSlug ?? undefined\n });\n console.log(`✅ Signed in${approval.orgName ? ` to ${approval.orgName}` : ''}. Scoped credential ${approval.keyPrefix}… saved to ~/.memhub/config.json (owner-only).`);\n if (!approval.projectSlug) {\n console.log('ℹ️ No default project was chosen during consent; it will be resolved per-repository on first use.');\n }\n\n await installToSelectedClients({\n apiKey: approval.apiKey,\n apiUrl: options.url,\n projectSlug: approval.projectSlug || detectProjectContext().slug,\n ide: options.ide,\n configPath: options.config\n });\n\n console.log('\\n🎉 Login complete! Restart or refresh the selected AI clients to load MemHub.');\n } catch (err: any) {\n if (err instanceof LoginDeniedError) {\n console.error('✗ Login denied in the browser. No credentials were stored.');\n } else if (err instanceof LoginExpiredError || err instanceof LoginTimeoutError) {\n console.error(`✗ ${err.message}`);\n } else {\n console.error(`✗ Login failed: ${err.message}`);\n }\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('logout')\n .description('Revoke this device, release its plan slot, and remove local MemHub credentials and sync state')\n .option('--local-only', 'Clear local state even when the cloud cannot be reached')\n .action(async (options) => {\n const config = getConfig();\n if (!config.apiKey && !options.localOnly) {\n console.error('No MemHub session is configured on this device.');\n process.exitCode = 1;\n return;\n }\n try {\n if (config.apiKey && !options.localOnly) {\n const result = await new CloudApiClient(config.apiUrl, config.apiKey).logoutDevice(config.deviceId);\n console.log(result.deviceReleased\n ? '✓ Device revoked and its plan slot released.'\n : '✓ Credential revoked; this device had no active cloud slot.');\n }\n clearLocalState();\n console.log('✓ Local MemHub credentials and sync outbox removed. Cloud memory history was preserved.');\n console.log(' Restart configured AI clients. Run mh login to connect again.');\n } catch (err: any) {\n console.error(`✗ Logout failed: ${err.message}`);\n console.error(' Local credentials were kept so you can retry. Use --local-only only if this device cannot reach MemHub.');\n process.exitCode = 1;\n }\n });\n\nprogram\n .command('status')\n .description('Display synchronization status, outbox stats, and device info')\n .action(async () => {\n const config = getConfig();\n const db = new OutboxDb(config.outboxPath);\n const pendingCount = db.getPendingCount();\n const lastSeq = db.getLastSequence(config.deviceId);\n const localProject = detectProjectContext();\n\n console.log('\\n📊 MemHub MCP Status:');\n console.log(` Device ID: ${config.deviceId}`);\n console.log(` API URL: ${config.apiUrl}`);\n console.log(` API Key: ${config.apiKey ? config.apiKey.slice(0, 12) + '...' : '(none configured)'}`);\n console.log(` Project Slug: ${config.projectSlug || localProject.slug}`);\n console.log(` Project ID: ${config.projectId || '(pending JIT resolution)'}`);\n console.log(` Outbox SQLite DB: ${config.outboxPath}`);\n console.log(` Pending Events: ${pendingCount}`);\n console.log(` Monotonic Sequence: ${lastSeq}`);\n\n db.close();\n });\n\nprogram\n .command('doctor')\n .description('Run system health checks and diagnostics for local engine & cloud sync')\n .action(async () => {\n console.log('\\n🩺 Running MemHub Doctor...\\n');\n const config = getConfig();\n\n // 1. Check local agentmemory tools\n console.log('1. Checking local engine tools:');\n console.log(` ✓ Found ${AGENTMEMORY_54_TOOLS.length} native agentmemory tools mapped.`);\n\n // 2. Check SQLite Outbox\n console.log('2. Checking local durable outbox (WAL mode):');\n try {\n const db = new OutboxDb(config.outboxPath);\n const pending = db.getPendingCount();\n console.log(` ✓ Outbox SQLite database accessible (${pending} pending events).`);\n db.close();\n } catch (err: any) {\n console.log(` ✗ Outbox error: ${err.message}`);\n }\n\n // 3. Check Cloud Connectivity\n console.log('3. Checking MemHub Cloud API connectivity:');\n if (!config.apiKey) {\n console.log(' ⚠️ No API key configured. Run `memhub login` or `memhub connect --key <key>`.');\n } else {\n const client = new CloudApiClient(config.apiUrl, config.apiKey);\n const health = await client.testConnection();\n if (health.ok) {\n console.log(` ✓ Cloud API reachable at ${config.apiUrl} (HTTP status: ${health.status})`);\n } else {\n console.log(` ✗ Cloud API unreachable at ${config.apiUrl} (${health.message})`);\n }\n }\n\n // 4. Check for updates\n console.log('4. Checking for CLI updates:');\n try {\n const latest = await fetchLatestFromNpm();\n if (latest && compareVersions(latest, CLI_VERSION) > 0) {\n console.log(` ⚠️ Update available: ${CLI_VERSION} → ${latest}. Run \\`mh update\\` to upgrade.`);\n } else {\n console.log(` ✓ MemHub CLI is up to date (v${CLI_VERSION}).`);\n }\n } catch {\n console.log(` ✓ Running MemHub CLI v${CLI_VERSION}.`);\n }\n\n console.log('\\nDoctor inspection completed.');\n });\n\nprogram\n .command('flush')\n .description('Force an immediate push of all pending outbox events to the cloud')\n .action(async () => {\n const config = getConfig();\n if (!config.apiKey) {\n console.error('Error: No API key configured. Run connect first.');\n process.exit(1);\n }\n\n console.log('🔄 Flushing pending outbox events to cloud...');\n const db = new OutboxDb(config.outboxPath);\n const client = new CloudApiClient(config.apiUrl, config.apiKey);\n\n const dueEvents = db.getDueEvents(100);\n if (dueEvents.length === 0) {\n console.log('✓ Outbox is already clean (0 pending events).');\n db.close();\n return;\n }\n\n try {\n const res = await client.pushEvents({\n protocol: 1,\n deviceId: config.deviceId,\n events: dueEvents.map(e => ({\n eventId: e.eventId,\n sequence: e.sequence,\n operation: e.operation,\n payload: JSON.parse(e.payloadJson),\n payloadSha256: e.payloadSha256\n }))\n });\n\n if (res.ackedEventIds && res.ackedEventIds.length > 0) {\n db.markAcked(res.ackedEventIds);\n console.log(`✅ Successfully flushed and acked ${res.ackedEventIds.length} events.`);\n }\n } catch (err: any) {\n console.error(`✗ Flush failed: ${err.message}`);\n } finally {\n db.close();\n }\n });\n\nprogram\n .command('rules')\n .description('Inject or update MemHub persistent memory protocol instructions into all AI client rules')\n .option('--cwd <path>', 'Workspace directory to target', process.cwd())\n .action(async (options) => {\n console.log('📝 Injecting MemHub memory protocol rules into AI client configuration files...');\n const results = RulesInjector.injectAll(path.resolve(options.cwd));\n for (const res of results) {\n if (res.success) {\n console.log(` ✓ ${res.target}: ${res.action} at ${res.filePath}`);\n } else {\n console.log(` ✗ ${res.target}: ${res.error}`);\n }\n }\n console.log('\\n✨ AI agents in this workspace and globally will now proactively save and recall team memories.');\n });\n\nprogram\n .command('update')\n .description('Check for updates and upgrade @simplexlat/memhub to the latest version')\n .option('--canary', 'Install prerelease canary build')\n .action(async (options) => {\n console.log('🔍 Checking for MemHub CLI updates...');\n try {\n const currentVersion = '0.1.0';\n console.log(`Current version: v${currentVersion}`);\n console.log('📦 Updating @simplexlat/memhub via npm...');\n const targetPkg = options.canary ? '@simplexlat/memhub@canary' : '@simplexlat/memhub@latest';\n execSync(`npm install --global ${targetPkg}`, { stdio: 'inherit' });\n console.log('\\n✅ MemHub CLI successfully updated to the latest version!');\n console.log(' Run `mh status` or `mh doctor` to verify your installation.');\n } catch (err: any) {\n console.error(`✗ Update failed: ${err.message}`);\n console.log(' Try running manually: npm install --global @simplexlat/memhub@latest');\n }\n });\n\nprogram.parse(process.argv);\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n ErrorCode,\n McpError\n} from '@modelcontextprotocol/sdk/types.js';\nimport { LocalAgentMemoryEngine } from './local-engine.js';\nimport { SyncEngine } from '../sync/engine.js';\nimport { CloudApiClient } from '../sync/client.js';\nimport { OutboxDb } from '../outbox/db.js';\nimport { MemHubConfig } from '../config.js';\nimport { detectProjectContext } from '../project-resolver.js';\nimport { MUTATING_TOOLS } from '@memhub/protocol';\n\nexport class MemHubMcpServer {\n private server: Server;\n private localEngine: LocalAgentMemoryEngine;\n private syncEngine: SyncEngine;\n private outboxDb: OutboxDb;\n private cloudClient: CloudApiClient;\n private config: MemHubConfig;\n\n constructor(config: MemHubConfig) {\n this.config = config;\n this.outboxDb = new OutboxDb(config.outboxPath);\n this.cloudClient = new CloudApiClient(config.apiUrl, config.apiKey);\n this.localEngine = new LocalAgentMemoryEngine();\n\n const localProject = detectProjectContext();\n const effectiveProjectId = config.projectId || config.projectSlug || localProject.slug;\n\n this.syncEngine = new SyncEngine({\n outboxDb: this.outboxDb,\n cloudClient: this.cloudClient,\n deviceId: config.deviceId,\n projectId: effectiveProjectId,\n orgId: config.orgId,\n onRemoteEventsReceived: async (events) => {\n await this.localEngine.importRemoteEvents(events);\n }\n });\n\n this.server = new Server(\n {\n name: 'memhub-mcp',\n version: '0.1.0'\n },\n {\n capabilities: {\n tools: {}\n }\n }\n );\n\n this.setupHandlers();\n }\n\n private setupHandlers(): void {\n // 1. List all 54 agentmemory tools + 3 MemHub management tools\n this.server.setRequestHandler(ListToolsRequestSchema, async () => {\n const nativeTools = this.localEngine.getToolList();\n\n const memhubTools = [\n {\n name: 'memhub_sync_status',\n description: 'Checks synchronization status, pending outbox count, device ID, and cloud connectivity.',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n {\n name: 'memhub_sync_now',\n description: 'Forces an immediate on-demand push of all pending outbox events and pulls latest team deltas.',\n inputSchema: {\n type: 'object',\n properties: {}\n }\n },\n {\n name: 'memhub_cloud_search',\n description: 'Searches the organization aggregated memory corpus directly in the cloud (FTS + vector).',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Max results to return' },\n mode: { type: 'string', enum: ['fts', 'vector', 'hybrid'], description: 'Search mode' }\n },\n required: ['query']\n }\n }\n ];\n\n return {\n tools: [...nativeTools, ...memhubTools]\n };\n });\n\n // 2. Handle tool calls\n this.server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args = {} } = request.params;\n\n try {\n // Handle MemHub management tools\n if (name === 'memhub_sync_status') {\n const status = this.syncEngine.getStatus();\n return {\n content: [{\n type: 'text',\n text: JSON.stringify(status, null, 2)\n }]\n };\n }\n\n if (name === 'memhub_sync_now') {\n const [pushResult, pullResult] = await Promise.allSettled([\n this.syncEngine.triggerPushOnDemand(),\n this.syncEngine.triggerPullOnDemand()\n ]);\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n push: pushResult.status === 'fulfilled' ? pushResult.value : { error: pushResult.reason?.message },\n pull: pullResult.status === 'fulfilled' ? pullResult.value : { error: pullResult.reason?.message },\n status: this.syncEngine.getStatus()\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memhub_cloud_search') {\n try {\n const results = await this.cloudClient.search({\n query: String(args.query || ''),\n limit: Number(args.limit || 10),\n mode: (args.mode as any) || 'hybrid'\n });\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }]\n };\n } catch (err: any) {\n // Fallback to local recall if cloud is unavailable\n const fallback = await this.localEngine.executeTool('memory_recall', {\n query: args.query,\n limit: args.limit\n });\n return {\n content: [{\n type: 'text',\n text: `[Cloud search degraded: ${err.message}. Showing local results:]\\n` + fallback.content[0].text\n }]\n };\n }\n }\n\n // On read: JIT Delta Pull\n if (name === 'memory_recall' || name === 'mem_search' || name === 'memory_session_start' || name === 'mem_session_start') {\n // Reads remain local. At most one lightweight conditional head check\n // per 30s is allowed when server-push invalidation is unavailable.\n this.syncEngine.refreshIfStale();\n }\n\n // Execute local tool execution (<3ms response)\n const result = await this.localEngine.executeTool(name, args);\n\n // On write / mutation: Record in Outbox & trigger on-demand push\n if (MUTATING_TOOLS.has(name)) {\n let op = 'memory.save';\n if (name === 'memory_delete' || name === 'memory_governance_delete') op = 'memory.delete';\n else if (name === 'mem_pin') op = 'memory.pin';\n else if (name === 'mem_unpin') op = 'memory.unpin';\n else if (name.includes('session_summary')) op = 'session.summary';\n\n await this.syncEngine.handleLocalMutation(op, {\n tool: name,\n title: args.title,\n content: args.content || args.summary,\n memoryType: args.type || 'observation',\n topicKey: args.topic_key,\n isPinned: Boolean(args.is_pinned),\n arguments: args\n });\n }\n\n return result as any;\n } catch (err: any) {\n throw new McpError(ErrorCode.InternalError, `Tool execution failed: ${err.message}`);\n }\n });\n }\n\n public async start(): Promise<void> {\n await this.localEngine.initialize();\n\n // Auto-resolve project JIT on startup if API key is provided\n if (this.config.apiKey) {\n try {\n const localCtx = detectProjectContext();\n const resolved = await this.cloudClient.resolveProject({\n slug: this.config.projectSlug || localCtx.slug,\n gitRemote: localCtx.gitRemote,\n name: localCtx.name\n });\n this.syncEngine.setProjectId(resolved.projectId);\n this.syncEngine.setOrgId(resolved.orgId);\n await this.syncEngine.startAutomaticSync();\n } catch (err) {\n // Continue offline if cloud resolution fails\n }\n }\n\n const transport = new StdioServerTransport();\n await this.server.connect(transport);\n }\n\n public getOutboxDb(): OutboxDb {\n return this.outboxDb;\n }\n\n public getSyncEngine(): SyncEngine {\n return this.syncEngine;\n }\n}\n","import { z } from 'zod';\n\nexport const SyncEventPayloadSchema = z.record(z.unknown()).refine(\n (value) => new TextEncoder().encode(JSON.stringify(value)).byteLength <= 256 * 1024,\n 'Event payload exceeds 256 KiB',\n);\n\nexport const PushSyncEventSchema = z.object({\n eventId: z.string().uuid(),\n sequence: z.number().int().nonnegative(),\n operation: z.string().min(1).max(64),\n payload: SyncEventPayloadSchema,\n payloadSha256: z.string().min(1)\n});\n\nexport const PushSyncRequestSchema = z.object({\n protocol: z.number().int().default(1),\n deviceId: z.string().uuid(),\n projectId: z.string().uuid().optional(),\n events: z.array(PushSyncEventSchema).min(1).max(200)\n});\n\nexport const PushSyncResponseSchema = z.object({\n success: z.boolean(),\n processedCount: z.number().int(),\n ackedEventIds: z.array(z.string()),\n errors: z.array(z.object({\n eventId: z.string(),\n error: z.string()\n })).optional()\n});\n\nexport const PullSyncRequestSchema = z.object({\n projectId: z.string().uuid().optional(),\n cursor: z.string().optional(),\n limit: z.coerce.number().int().min(1).max(500).default(100)\n});\n\nexport const PullSyncResponseSchema = z.object({\n events: z.array(z.object({\n eventId: z.string(),\n projectId: z.string(),\n deviceId: z.string(),\n sequence: z.number(),\n operation: z.string(),\n payload: z.record(z.unknown()),\n payloadSha256: z.string(),\n receivedAt: z.string().optional()\n })),\n nextCursor: z.string().optional(),\n hasMore: z.boolean()\n});\n\nexport const ResolveProjectRequestSchema = z.object({\n slug: z.string().optional(),\n gitRemote: z.string().optional(),\n name: z.string().optional()\n});\n\nexport const ResolveProjectResponseSchema = z.object({\n projectId: z.string(),\n projectSlug: z.string(),\n orgId: z.string(),\n orgSlug: z.string(),\n projectName: z.string(),\n isNew: z.boolean()\n});\n\nexport const CloudSearchRequestSchema = z.object({\n projectId: z.string().uuid(),\n query: z.string().trim().min(1).max(1000),\n limit: z.number().int().min(1).max(100).default(20),\n memoryType: z.string().min(1).max(64).optional(),\n topicKey: z.string().min(1).max(160).regex(/^[a-zA-Z0-9._:/-]+$/).optional(),\n isPinnedOnly: z.boolean().optional()\n});\n\nexport const CloudSearchResponseSchema = z.object({\n results: z.array(z.object({\n id: z.string(),\n projectId: z.string(),\n title: z.string(),\n content: z.string(),\n memoryType: z.string(),\n topicKey: z.string().optional(),\n isPinned: z.boolean(),\n score: z.number(),\n source: z.string(),\n createdAt: z.string()\n })),\n total: z.number().int(),\n query: z.string(),\n executionTimeMs: z.number()\n});\n","import { createHash, randomUUID } from 'crypto';\n\nexport function generateUuid(): string {\n return randomUUID();\n}\n\nexport function sha256Hex(data: string | Buffer | Record<string, unknown>): string {\n const str = typeof data === 'string' \n ? data \n : Buffer.isBuffer(data) \n ? data \n : JSON.stringify(data, Object.keys(data).sort());\n return createHash('sha256').update(str).digest('hex');\n}\n\nexport function hashApiKey(key: string): string {\n return createHash('sha256').update(key.trim()).digest('hex');\n}\n\nexport function generateApiKey(prefix = 'mh_live'): { rawKey: string; keyPrefix: string; keyHash: string } {\n const entropy = randomUUID().replace(/-/g, '') + randomUUID().replace(/-/g, '');\n const rawKey = `${prefix}_${entropy}`;\n const keyPrefix = `${prefix}_${entropy.slice(0, 8)}`;\n const keyHash = hashApiKey(rawKey);\n return { rawKey, keyPrefix, keyHash };\n}\n\nexport interface CursorPayload {\n timestamp: string;\n sequence: number;\n id: string;\n}\n\nexport function encodeCursor(payload: CursorPayload): string {\n return Buffer.from(JSON.stringify(payload)).toString('base64url');\n}\n\nexport function decodeCursor(cursorStr?: string): CursorPayload | null {\n if (!cursorStr) return null;\n try {\n const raw = Buffer.from(cursorStr, 'base64url').toString('utf8');\n const parsed = JSON.parse(raw);\n if (parsed && typeof parsed === 'object' && typeof parsed.timestamp === 'string') {\n return parsed as CursorPayload;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * Complete list of 54 MCP tools in @agentmemory/agentmemory@0.9.29\n */\nexport const AGENTMEMORY_54_TOOLS = [\n // 1. Core Memory Operations\n 'memory_save',\n 'memory_recall',\n 'memory_update',\n 'memory_delete',\n 'memory_smart_search',\n 'memory_consolidate',\n 'memory_diagnose',\n 'memory_sessions',\n 'memory_session_start',\n 'memory_session_end',\n 'memory_session_summary',\n 'memory_lesson_save',\n 'memory_reflect',\n \n // 2. Observations & Passive Capture\n 'mem_save',\n 'mem_update',\n 'mem_search',\n 'mem_context',\n 'mem_get_observation',\n 'mem_session_start',\n 'mem_session_end',\n 'mem_session_summary',\n 'mem_capture_passive',\n 'mem_suggest_topic_key',\n 'mem_pin',\n 'mem_unpin',\n 'mem_review',\n 'mem_judge',\n 'mem_compare',\n 'mem_doctor',\n 'mem_current_project',\n \n // 3. Knowledge Graph & Relations\n 'memory_graph_query',\n 'memory_graph_add_relation',\n 'memory_graph_remove_relation',\n 'memory_graph_neighbors',\n 'memory_graph_shortest_path',\n \n // 4. Slots & Working State\n 'memory_slot_create',\n 'memory_slot_get',\n 'memory_slot_append',\n 'memory_slot_replace',\n 'memory_slot_delete',\n 'memory_slot_list',\n \n // 5. Governance, Snapshot & Audit\n 'memory_governance_audit',\n 'memory_governance_delete',\n 'memory_snapshot_create',\n 'memory_snapshot_restore',\n 'memory_snapshot_list',\n 'memory_team_share',\n \n // 6. Patterns, Timeline & History\n 'memory_pattern_detect',\n 'memory_pattern_list',\n 'memory_timeline_get',\n 'memory_file_history_get',\n 'memory_file_history_record',\n 'memory_stats_get'\n] as const;\n\n/**\n * 8 Essential Core Tools\n */\nexport const ESSENTIAL_CORE_TOOLS = new Set([\n 'memory_save',\n 'memory_recall',\n 'memory_consolidate',\n 'memory_smart_search',\n 'memory_sessions',\n 'memory_diagnose',\n 'memory_lesson_save',\n 'memory_reflect'\n]);\n\n/**\n * Tools that produce state mutations requiring cloud sync push\n */\nexport const MUTATING_TOOLS = new Set([\n 'memory_save',\n 'memory_update',\n 'memory_delete',\n 'memory_consolidate',\n 'memory_session_end',\n 'memory_session_summary',\n 'memory_lesson_save',\n 'memory_reflect',\n 'mem_save',\n 'mem_update',\n 'mem_pin',\n 'mem_unpin',\n 'mem_capture_passive',\n 'mem_session_end',\n 'mem_session_summary',\n 'memory_graph_add_relation',\n 'memory_graph_remove_relation',\n 'memory_slot_create',\n 'memory_slot_append',\n 'memory_slot_replace',\n 'memory_slot_delete',\n 'memory_snapshot_create',\n 'memory_snapshot_restore',\n 'memory_governance_delete',\n 'memory_team_share',\n 'memory_file_history_record'\n]);\n\n/**\n * Custom MemHub SaaS tools provided alongside agentmemory\n */\nexport const MEMHUB_MANAGEMENT_TOOLS = [\n 'memhub_sync_status',\n 'memhub_sync_now',\n 'memhub_cloud_search'\n] as const;\n","import { AGENTMEMORY_54_TOOLS, ESSENTIAL_CORE_TOOLS } from '@memhub/protocol';\n\nexport interface McpToolDefinition {\n name: string;\n description: string;\n inputSchema: {\n type: 'object';\n properties: Record<string, unknown>;\n required?: string[];\n };\n}\n\nexport interface ToolCallResult {\n content: Array<{\n type: 'text';\n text: string;\n }>;\n isError?: boolean;\n [key: string]: unknown;\n}\n\nexport class LocalAgentMemoryEngine {\n private isInitialized = false;\n private toolsCatalog: Map<string, McpToolDefinition> = new Map();\n private localMemories: Map<string, any> = new Map();\n\n constructor() {\n this.initDefaultToolCatalog();\n }\n\n public async initialize(): Promise<void> {\n try {\n // Attempt dynamic loading of agentmemory if available\n // Native agentmemory uses stdio or in-memory registry\n this.isInitialized = true;\n } catch (err) {\n this.isInitialized = true;\n }\n }\n\n private initDefaultToolCatalog(): void {\n for (const toolName of AGENTMEMORY_54_TOOLS) {\n this.toolsCatalog.set(toolName, this.createDefaultSchemaForTool(toolName));\n }\n }\n\n private createDefaultSchemaForTool(name: string): McpToolDefinition {\n switch (name) {\n case 'memory_save':\n case 'mem_save':\n return {\n name,\n description: 'Saves a structured memory, observation, decision, or discovery with fast local persistence and team sync.',\n inputSchema: {\n type: 'object',\n properties: {\n title: { type: 'string', description: 'Brief descriptive title of the memory' },\n content: { type: 'string', description: 'Detailed memory content' },\n type: { type: 'string', description: 'Type of memory (decision, pattern, bugfix, discovery, etc.)' },\n topic_key: { type: 'string', description: 'Stable topic key for evolving decisions' },\n is_pinned: { type: 'boolean', description: 'Pin as invariant team rule' }\n },\n required: ['title', 'content']\n }\n };\n case 'memory_recall':\n case 'mem_search':\n case 'mem_context':\n return {\n name,\n description: 'Recalls relevant memories using hybrid BM25 + vector + graph search.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Maximum number of results to return' },\n topic_key: { type: 'string', description: 'Filter by topic key' },\n type: { type: 'string', description: 'Filter by memory type' }\n },\n required: ['query']\n }\n };\n case 'memory_smart_search':\n return {\n name,\n description: 'Advanced semantic triple-stream search with RRF fusion.',\n inputSchema: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search query' },\n limit: { type: 'number', description: 'Max results' }\n },\n required: ['query']\n }\n };\n case 'memory_consolidate':\n return {\n name,\n description: 'Consolidates short-term observations into high-level learnings and patterns.',\n inputSchema: {\n type: 'object',\n properties: {\n scope: { type: 'string', description: 'Consolidation scope' }\n }\n }\n };\n case 'memory_session_summary':\n case 'mem_session_summary':\n return {\n name,\n description: 'Saves an end-of-session structured summary across Goal, Discoveries, Accomplished, Next Steps.',\n inputSchema: {\n type: 'object',\n properties: {\n summary: { type: 'string', description: 'Markdown summary of the session' }\n },\n required: ['summary']\n }\n };\n default:\n return {\n name,\n description: `Native agentmemory tool: ${name}`,\n inputSchema: {\n type: 'object',\n properties: {\n input: { type: 'string', description: 'Tool input argument' },\n query: { type: 'string', description: 'Query argument' },\n options: { type: 'object', description: 'Optional configuration' }\n }\n }\n };\n }\n }\n\n public getToolList(): McpToolDefinition[] {\n return Array.from(this.toolsCatalog.values());\n }\n\n public getTool(name: string): McpToolDefinition | undefined {\n return this.toolsCatalog.get(name);\n }\n\n public async executeTool(name: string, args: Record<string, any>): Promise<ToolCallResult> {\n const startTime = Date.now();\n\n // Handle local storage execution\n if (name === 'memory_save' || name === 'mem_save') {\n const id = `mem_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n const record = {\n id,\n title: args.title || 'Untitled Memory',\n content: args.content || '',\n type: args.type || 'observation',\n topicKey: args.topic_key,\n isPinned: Boolean(args.is_pinned),\n createdAt: new Date().toISOString()\n };\n this.localMemories.set(id, record);\n\n const elapsed = Date.now() - startTime;\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n memory_id: id,\n title: record.title,\n execution_time_ms: elapsed,\n local_status: 'persisted'\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memory_recall' || name === 'mem_search' || name === 'memory_smart_search') {\n const query = (args.query || '').toLowerCase();\n const tokens = query.split(/\\s+/).filter(Boolean);\n const results: any[] = [];\n\n for (const item of this.localMemories.values()) {\n const titleLower = (item.title || '').toLowerCase();\n const contentLower = (item.content || '').toLowerCase();\n const topicLower = (item.topicKey || '').toLowerCase();\n\n const matches = tokens.length === 0 || tokens.some((t: string) =>\n titleLower.includes(t) || contentLower.includes(t) || topicLower.includes(t)\n );\n\n if (matches) {\n results.push(item);\n }\n }\n\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n results: results.slice(0, args.limit || 10),\n total: results.length,\n query: args.query,\n source: 'local_engine'\n }, null, 2)\n }]\n };\n }\n\n if (name === 'memory_session_summary' || name === 'mem_session_summary') {\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n status: 'session_summary_recorded',\n timestamp: new Date().toISOString()\n }, null, 2)\n }]\n };\n }\n\n // Default transparent execution for remaining tools\n return {\n content: [{\n type: 'text',\n text: JSON.stringify({\n success: true,\n tool: name,\n received_arguments: args,\n engine: 'agentmemory@0.9.29',\n status: 'ok'\n }, null, 2)\n }]\n };\n }\n\n public async importRemoteEvents(events: any[]): Promise<void> {\n for (const evt of events) {\n if (evt.operation === 'memory.save' && evt.payload) {\n const id = evt.payload.sourceMemoryId || `remote_${evt.eventId}`;\n this.localMemories.set(id, {\n id,\n title: evt.payload.title || 'Remote Memory',\n content: evt.payload.content || '',\n type: evt.payload.memoryType || 'observation',\n topicKey: evt.payload.topicKey,\n isPinned: Boolean(evt.payload.isPinned),\n createdAt: evt.receivedAt || new Date().toISOString()\n });\n }\n }\n }\n}\n","import { OutboxDb } from '../outbox/db.js';\nimport { CloudApiClient } from './client.js';\nimport { SyncStatus, SyncEvent, SyncOperation, sha256Hex } from '@memhub/protocol';\n\nexport interface SyncEngineOptions {\n outboxDb: OutboxDb;\n cloudClient: CloudApiClient;\n deviceId: string;\n projectId: string;\n orgId?: string;\n onRemoteEventsReceived?: (events: SyncEvent[]) => Promise<void>;\n}\n\nexport class SyncEngine {\n private outboxDb: OutboxDb;\n private cloudClient: CloudApiClient;\n private deviceId: string;\n private projectId: string;\n private orgId?: string;\n private isPushing = false;\n private isPulling = false;\n private lastPushAt?: string;\n private lastPullAt?: string;\n private lastError?: string;\n private onRemoteEventsReceived?: (events: SyncEvent[]) => Promise<void>;\n private automaticAbort?:AbortController;\n private fallbackTimer?:ReturnType<typeof setTimeout>;\n private pullDebounce?:ReturnType<typeof setTimeout>;\n private headEtag?:string;\n private remoteVersion=0;\n private lastHeadCheckAt=0;\n\n constructor(options: SyncEngineOptions) {\n this.outboxDb = options.outboxDb;\n this.cloudClient = options.cloudClient;\n this.deviceId = options.deviceId;\n this.projectId = options.projectId;\n this.orgId = options.orgId;\n this.onRemoteEventsReceived = options.onRemoteEventsReceived;\n }\n\n public setProjectId(projectId: string): void {\n this.projectId = projectId;\n }\n\n public async startAutomaticSync():Promise<void>{\n if(this.automaticAbort)return;this.automaticAbort=new AbortController();\n this.remoteVersion=Number(this.outboxDb.getState(`remote_version_${this.projectId}`)||0);\n await this.checkHeadAndPull(true);\n void this.runStream(this.automaticAbort.signal);\n this.scheduleFallback();\n }\n\n public refreshIfStale(maxAgeMs=30_000):void{\n if(Date.now()-this.lastHeadCheckAt<maxAgeMs)return;\n void this.checkHeadAndPull(false);\n }\n\n public stopAutomaticSync():void{\n this.automaticAbort?.abort();this.automaticAbort=undefined;\n if(this.fallbackTimer)clearTimeout(this.fallbackTimer);if(this.pullDebounce)clearTimeout(this.pullDebounce);\n }\n\n private schedulePull(delay=350){\n if(this.pullDebounce)return;this.pullDebounce=setTimeout(()=>{this.pullDebounce=undefined;void this.checkHeadAndPull(false)},delay);\n }\n\n private async runStream(signal:AbortSignal){\n let backoff=1000;\n while(!signal.aborted){try{await this.cloudClient.streamSyncNotices(signal,(notice)=>{if(notice.projectId===this.projectId&&notice.version>this.remoteVersion)this.schedulePull()});backoff=1000}\n catch(err:any){if(signal.aborted)return;this.lastError=err.message;await new Promise(r=>setTimeout(r,backoff+Math.random()*500));backoff=Math.min(backoff*2,30_000)}}\n }\n\n private scheduleFallback(){\n const tick=async()=>{if(!this.automaticAbort||this.automaticAbort.signal.aborted)return;await this.checkHeadAndPull(false);\n this.fallbackTimer=setTimeout(tick,55_000+Math.random()*10_000)};\n this.fallbackTimer=setTimeout(tick,55_000+Math.random()*10_000);\n }\n\n private async checkHeadAndPull(force:boolean){\n this.lastHeadCheckAt=Date.now();\n try{const head=await this.cloudClient.getSyncHead(force?undefined:this.headEtag);if(head.etag)this.headEtag=head.etag;\n if(!head.notModified&&head.version>this.remoteVersion){await this.triggerPullOnDemand();this.remoteVersion=head.version;this.outboxDb.setState(`remote_version_${this.projectId}`,String(head.version))}\n }catch(err:any){this.lastError=err.message}\n }\n\n public setOrgId(orgId: string): void {\n this.orgId = orgId;\n }\n\n /**\n * Records a local mutation event in the outbox in <1ms and triggers on-demand cloud push.\n */\n public async handleLocalMutation(\n operation: SyncOperation | string,\n payload: Record<string, unknown>\n ): Promise<{ eventId: string; sequence: number }> {\n const record = this.outboxDb.enqueueEvent({\n deviceId: this.deviceId,\n projectId: this.projectId,\n operation,\n payload,\n origin: 'local'\n });\n\n // Fire on-demand push asynchronously without blocking local tool response\n this.triggerPushOnDemand().catch(err => {\n this.lastError = err.message;\n });\n\n return {\n eventId: record.eventId,\n sequence: record.sequence\n };\n }\n\n /**\n * Pushes all due outbox events to the cloud.\n */\n public async triggerPushOnDemand(batchSize = 50, force = false): Promise<{ processed: number; acked: number }> {\n if (this.isPushing) {\n return { processed: 0, acked: 0 };\n }\n\n this.isPushing = true;\n try {\n const dueEvents = this.outboxDb.getDueEvents(batchSize, force);\n if (dueEvents.length === 0) {\n return { processed: 0, acked: 0 };\n }\n\n const requestPayload = {\n protocol: 1,\n deviceId: this.deviceId,\n events: dueEvents.map(e => ({\n eventId: e.eventId,\n sequence: e.sequence,\n operation: e.operation,\n payload: JSON.parse(e.payloadJson),\n payloadSha256: e.payloadSha256\n }))\n };\n\n const response = await this.cloudClient.pushEvents(requestPayload);\n\n if (response.ackedEventIds && response.ackedEventIds.length > 0) {\n this.outboxDb.markAcked(response.ackedEventIds);\n }\n\n if (response.errors && response.errors.length > 0) {\n for (const err of response.errors) {\n this.outboxDb.recordFailure(err.eventId, err.error);\n }\n }\n\n this.lastPushAt = new Date().toISOString();\n this.lastError = undefined;\n\n return {\n processed: dueEvents.length,\n acked: response.ackedEventIds?.length || 0\n };\n } catch (err: any) {\n this.lastError = err.message;\n // Record failure for pending events\n const dueEvents = this.outboxDb.getDueEvents(batchSize);\n for (const e of dueEvents) {\n this.outboxDb.recordFailure(e.eventId, err.message);\n }\n return { processed: 0, acked: 0 };\n } finally {\n this.isPushing = false;\n }\n }\n\n /**\n * Performs JIT delta pull from cloud and imports remote changes.\n */\n public async triggerPullOnDemand(): Promise<{ eventsCount: number }> {\n if (this.isPulling) {\n return { eventsCount: 0 };\n }\n\n this.isPulling = true;\n try {\n const cursorKey = `pull_cursor_${this.projectId}`;\n const savedCursor = this.outboxDb.getState(cursorKey) || undefined;\n\n let cursor=savedCursor,total=0;\n for(let page=0;page<100;page++){\n const response=await this.cloudClient.pullEvents({cursor,limit:100});\n if (response.events && response.events.length > 0) {\n // Filter out events originated from this exact device to avoid echo loops\n const remoteEvents = response.events.filter(e => e.deviceId !== this.deviceId);\n\n if (remoteEvents.length > 0 && this.onRemoteEventsReceived) {\n await this.onRemoteEventsReceived(remoteEvents as SyncEvent[]);\n }\n\n if(response.nextCursor){cursor=response.nextCursor;this.outboxDb.setState(cursorKey,cursor)}\n }\n total+=response.events?.length||0;\n if(!response.hasMore)break;\n }\n\n this.lastPullAt = new Date().toISOString();\n this.lastError = undefined;\n\n return { eventsCount: total };\n } catch (err: any) {\n this.lastError = err.message;\n return { eventsCount: 0 };\n } finally {\n this.isPulling = false;\n }\n }\n\n /**\n * Gets current sync status & health diagnostics.\n */\n public getStatus(): SyncStatus {\n const pendingCount = this.outboxDb.getPendingCount();\n const lastSeq = this.outboxDb.getLastSequence(this.deviceId);\n\n return {\n deviceId: this.deviceId,\n projectId: this.projectId,\n orgId: this.orgId,\n cloudConnected: !this.lastError,\n pendingOutboxCount: pendingCount,\n lastPushAt: this.lastPushAt,\n lastPullAt: this.lastPullAt,\n lastSequence: lastSeq,\n lastError: this.lastError\n };\n }\n}\n","import {\n PushSyncRequest,\n PushSyncResponse,\n PullSyncRequest,\n PullSyncResponse,\n ResolveProjectRequest,\n ResolveProjectResponse,\n CloudSearchRequest,\n CloudSearchResponse,\n sha256Hex\n} from '@memhub/protocol';\n\nexport const USER_AGENT = 'MemHub-MCP/0.1.0';\n\nexport class CloudApiClient {\n private apiUrl: string;\n private apiKey?: string;\n\n constructor(apiUrl: string, apiKey?: string) {\n this.apiUrl = apiUrl.replace(/\\/$/, '');\n this.apiKey = apiKey;\n }\n\n public setApiKey(key: string): void {\n this.apiKey = key;\n }\n\n private getHeaders(customHeaders: Record<string, string> = {}): Record<string, string> {\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n 'User-Agent': USER_AGENT,\n ...customHeaders\n };\n\n if (this.apiKey) {\n headers['Authorization'] = `Bearer ${this.apiKey}`;\n headers['x-api-key'] = this.apiKey;\n }\n\n return headers;\n }\n\n public async resolveProject(req: ResolveProjectRequest): Promise<ResolveProjectResponse> {\n const res = await fetch(`${this.apiUrl}/api/v1/projects/resolve`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to resolve project: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as ResolveProjectResponse;\n }\n\n public async pushEvents(req: PushSyncRequest): Promise<PushSyncResponse> {\n const idempotencyKey = sha256Hex(JSON.stringify(req.events.map(e => e.eventId).sort()));\n\n const res = await fetch(`${this.apiUrl}/api/v1/sync/push`, {\n method: 'POST',\n headers: this.getHeaders({\n 'Idempotency-Key': idempotencyKey\n }),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to push sync events: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as PushSyncResponse;\n }\n\n public async pullEvents(req: PullSyncRequest): Promise<PullSyncResponse> {\n const params = new URLSearchParams();\n if (req.cursor) params.set('cursor', req.cursor);\n if (req.limit) params.set('limit', String(req.limit));\n\n const url = `${this.apiUrl}/api/v1/sync/pull?${params.toString()}`;\n const res = await fetch(url, {\n method: 'GET',\n headers: this.getHeaders()\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Failed to pull sync events: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as PullSyncResponse;\n }\n\n public async getSyncHead(etag?: string): Promise<{ notModified:boolean;version:number;etag?:string }> {\n const res=await fetch(`${this.apiUrl}/api/v1/sync/head`,{headers:this.getHeaders(etag?{'If-None-Match':etag}:{})});\n if(res.status===304)return {notModified:true,version:0,etag:etag};\n if(!res.ok)throw new Error(`Failed to read sync head: ${res.status}`);\n const body=await res.json() as {version:number};\n return {notModified:false,version:Number(body.version||0),etag:res.headers.get('etag')||undefined};\n }\n\n public async streamSyncNotices(\n signal:AbortSignal,onNotice:(notice:{projectId:string;version:number})=>void,\n ):Promise<void>{\n const res=await fetch(`${this.apiUrl}/api/v1/sync/stream`,{headers:this.getHeaders({Accept:'text/event-stream'}),signal});\n if(!res.ok||!res.body)throw new Error(`Failed to open sync stream: ${res.status}`);\n const reader=res.body.getReader(),decoder=new TextDecoder();let buffer='';\n while(true){const {done,value}=await reader.read();if(done)return;buffer+=decoder.decode(value,{stream:true});\n let boundary;while((boundary=buffer.indexOf('\\n\\n'))>=0){const frame=buffer.slice(0,boundary);buffer=buffer.slice(boundary+2);\n const event=frame.split('\\n').find(line=>line.startsWith('event:'))?.slice(6).trim();\n const data=frame.split('\\n').find(line=>line.startsWith('data:'))?.slice(5).trim();\n if(event==='project_changed'&&data){try{onNotice(JSON.parse(data))}catch{}}\n }\n }\n }\n\n public async search(req: CloudSearchRequest): Promise<CloudSearchResponse> {\n const res = await fetch(`${this.apiUrl}/api/v1/search`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify(req)\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`Cloud search failed: ${res.status} ${errText}`);\n }\n\n return (await res.json()) as CloudSearchResponse;\n }\n\n public async logoutDevice(deviceId: string): Promise<{ success: boolean; deviceReleased: boolean }> {\n const res = await fetch(`${this.apiUrl}/api/v1/devices/logout`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({ deviceId }),\n });\n if (!res.ok) throw new Error(`Failed to log out device: ${res.status} ${await res.text()}`);\n return await res.json() as { success: boolean; deviceReleased: boolean };\n }\n\n public async testConnection(): Promise<{ ok: boolean; status: number; message?: string }> {\n try {\n const res = await fetch(`${this.apiUrl}/api/v1/projects/resolve`, {\n method: 'POST',\n headers: this.getHeaders(),\n body: JSON.stringify({ slug: '__health_check__' })\n });\n const reachable = res.ok || res.status === 400 || res.status === 401 || res.status === 429;\n return { ok: reachable, status: res.status, message: reachable ? undefined : `HTTP ${res.status}` };\n } catch (err: any) {\n return { ok: false, status: 0, message: err.message };\n }\n }\n}\n","import { DatabaseSync } from 'node:sqlite';\nimport path from 'path';\nimport fs from 'fs';\nimport { randomUUID } from 'crypto';\nimport { sha256Hex, OutboxRecord, SyncOperation } from '@memhub/protocol';\n\nexport interface EnqueueEventInput {\n eventId?: string;\n deviceId: string;\n projectId: string;\n operation: SyncOperation | string;\n payload: Record<string, unknown>;\n origin?: string;\n}\n\nexport class OutboxDb {\n private db: DatabaseSync;\n\n constructor(dbPath: string) {\n const dir = path.dirname(dbPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n this.db = new DatabaseSync(dbPath);\n this.init();\n }\n\n private init(): void {\n this.db.exec('PRAGMA journal_mode = WAL;');\n this.db.exec('PRAGMA synchronous = NORMAL;');\n this.db.exec('PRAGMA busy_timeout = 5000;');\n\n this.db.exec(`\n CREATE TABLE IF NOT EXISTS outbox_events (\n event_id TEXT PRIMARY KEY,\n device_id TEXT NOT NULL,\n project_id TEXT NOT NULL,\n sequence INTEGER NOT NULL,\n operation TEXT NOT NULL,\n payload_json TEXT NOT NULL,\n payload_sha256 TEXT NOT NULL,\n origin TEXT NOT NULL DEFAULT 'local',\n attempts INTEGER NOT NULL DEFAULT 0,\n next_attempt_at TEXT NOT NULL,\n created_at TEXT NOT NULL,\n acked_at TEXT,\n last_error TEXT,\n UNIQUE(device_id, sequence)\n );\n\n CREATE INDEX IF NOT EXISTS idx_outbox_due ON outbox_events(acked_at, next_attempt_at);\n CREATE INDEX IF NOT EXISTS idx_outbox_project ON outbox_events(project_id, sequence);\n\n CREATE TABLE IF NOT EXISTS sync_state (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n }\n\n public getLastSequence(deviceId: string): number {\n const stmt = this.db.prepare('SELECT MAX(sequence) as max_seq FROM outbox_events WHERE device_id = ?');\n const row = stmt.get(deviceId) as { max_seq: number | null } | undefined;\n return row?.max_seq ?? 0;\n }\n\n public enqueueEvent(input: EnqueueEventInput): OutboxRecord {\n const now = new Date().toISOString();\n const eventId = input.eventId || randomUUID();\n const payloadJson = JSON.stringify(input.payload);\n const payloadSha256 = sha256Hex(payloadJson);\n const origin = input.origin || 'local';\n\n const nextSeq = this.getLastSequence(input.deviceId) + 1;\n\n const stmt = this.db.prepare(`\n INSERT INTO outbox_events (\n event_id, device_id, project_id, sequence, operation,\n payload_json, payload_sha256, origin, attempts,\n next_attempt_at, created_at, acked_at, last_error\n ) VALUES (\n ?, ?, ?, ?, ?,\n ?, ?, ?, 0,\n ?, ?, NULL, NULL\n )\n `);\n\n stmt.run(\n eventId,\n input.deviceId,\n input.projectId,\n nextSeq,\n input.operation,\n payloadJson,\n payloadSha256,\n origin,\n now,\n now\n );\n\n return {\n eventId,\n deviceId: input.deviceId,\n projectId: input.projectId,\n sequence: nextSeq,\n operation: input.operation,\n payloadJson,\n payloadSha256,\n origin,\n attempts: 0,\n nextAttemptAt: now,\n createdAt: now,\n ackedAt: null,\n lastError: null\n };\n }\n\n public getDueEvents(limit = 50, force = false): OutboxRecord[] {\n const now = new Date().toISOString();\n const sql = force\n ? `SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n WHERE acked_at IS NULL\n ORDER BY sequence ASC\n LIMIT ?`\n : `SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n WHERE acked_at IS NULL AND next_attempt_at <= ?\n ORDER BY sequence ASC\n LIMIT ?`;\n\n const stmt = this.db.prepare(sql);\n return (force ? stmt.all(limit) : stmt.all(now, limit)) as unknown as OutboxRecord[];\n }\n\n public markAcked(eventIds: string[]): void {\n if (eventIds.length === 0) return;\n const now = new Date().toISOString();\n const placeholders = eventIds.map(() => '?').join(',');\n const stmt = this.db.prepare(`\n UPDATE outbox_events\n SET acked_at = ?\n WHERE event_id IN (${placeholders})\n `);\n stmt.run(now, ...eventIds);\n }\n\n public recordFailure(eventId: string, errorMessage: string): void {\n const stmt = this.db.prepare('SELECT attempts FROM outbox_events WHERE event_id = ?');\n const record = stmt.get(eventId) as { attempts: number } | undefined;\n\n if (!record) return;\n\n const newAttempts = record.attempts + 1;\n const delaySeconds = Math.min(300, Math.pow(2, Math.min(newAttempts, 8))) + Math.random() * 2;\n const nextAttempt = new Date(Date.now() + delaySeconds * 1000).toISOString();\n\n const updateStmt = this.db.prepare(`\n UPDATE outbox_events\n SET attempts = ?, next_attempt_at = ?, last_error = ?\n WHERE event_id = ?\n `);\n\n updateStmt.run(newAttempts, nextAttempt, errorMessage.slice(0, 500), eventId);\n }\n\n public getPendingCount(): number {\n const stmt = this.db.prepare('SELECT COUNT(*) as count FROM outbox_events WHERE acked_at IS NULL');\n const row = stmt.get() as { count: number };\n return row.count;\n }\n\n public getAllEvents(limit = 100): OutboxRecord[] {\n const stmt = this.db.prepare(`\n SELECT \n event_id as eventId,\n device_id as deviceId,\n project_id as projectId,\n sequence,\n operation,\n payload_json as payloadJson,\n payload_sha256 as payloadSha256,\n origin,\n attempts,\n next_attempt_at as nextAttemptAt,\n created_at as createdAt,\n acked_at as ackedAt,\n last_error as lastError\n FROM outbox_events\n ORDER BY sequence DESC\n LIMIT ?\n `);\n return stmt.all(limit) as unknown as OutboxRecord[];\n }\n\n public getState(key: string): string | null {\n const stmt = this.db.prepare('SELECT value FROM sync_state WHERE key = ?');\n const row = stmt.get(key) as { value: string } | undefined;\n return row?.value ?? null;\n }\n\n public setState(key: string, value: string): void {\n const stmt = this.db.prepare(`\n INSERT INTO sync_state (key, value) VALUES (?, ?)\n ON CONFLICT(key) DO UPDATE SET value = excluded.value\n `);\n stmt.run(key, value);\n }\n\n public close(): void {\n this.db.close();\n }\n}\n","import { execSync } from 'child_process';\nimport path from 'path';\nimport fs from 'fs';\n\nexport interface LocalProjectContext {\n slug: string;\n name: string;\n gitRemote?: string;\n workingDir: string;\n}\n\nexport function sanitizeSlug(input: string): string {\n return input\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9-_]/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '') || 'default-project';\n}\n\nexport function detectGitRemote(cwd = process.cwd()): string | undefined {\n try {\n const output = execSync('git remote get-url origin', {\n cwd,\n encoding: 'utf8',\n stdio: ['pipe', 'pipe', 'ignore']\n }).trim();\n if (output) return output;\n } catch {\n // Git remote not found or git not installed\n }\n return undefined;\n}\n\nexport function extractSlugFromGitRemote(remoteUrl: string): string | undefined {\n try {\n // Examples:\n // https://github.com/org/repo.git -> org-repo or repo\n // git@github.com:org/repo.git -> org-repo or repo\n const cleaned = remoteUrl.replace(/\\.git$/, '').trim();\n const parts = cleaned.split(/[/:]/);\n if (parts.length >= 2) {\n const repo = parts[parts.length - 1];\n const owner = parts[parts.length - 2];\n if (repo && owner && !owner.includes('@') && !owner.includes('//')) {\n return sanitizeSlug(`${owner}-${repo}`);\n }\n if (repo) {\n return sanitizeSlug(repo);\n }\n }\n } catch {\n // Fallback\n }\n return undefined;\n}\n\nexport function detectPackageName(cwd = process.cwd()): string | undefined {\n try {\n const pkgPath = path.join(cwd, 'package.json');\n if (fs.existsSync(pkgPath)) {\n const content = JSON.parse(fs.readFileSync(pkgPath, 'utf8'));\n if (content.name && typeof content.name === 'string') {\n return sanitizeSlug(content.name.replace(/^@[^/]+\\//, ''));\n }\n }\n } catch {\n // Ignore\n }\n\n try {\n const pyprojectPath = path.join(cwd, 'pyproject.toml');\n if (fs.existsSync(pyprojectPath)) {\n const content = fs.readFileSync(pyprojectPath, 'utf8');\n const match = content.match(/name\\s*=\\s*[\"']([^\"']+)[\"']/);\n if (match && match[1]) {\n return sanitizeSlug(match[1]);\n }\n }\n } catch {\n // Ignore\n }\n\n return undefined;\n}\n\nexport function detectProjectContext(cwd = process.cwd()): LocalProjectContext {\n const gitRemote = detectGitRemote(cwd);\n let slug: string | undefined;\n let name: string | undefined;\n\n if (gitRemote) {\n slug = extractSlugFromGitRemote(gitRemote);\n }\n\n if (!slug) {\n slug = detectPackageName(cwd);\n }\n\n if (!slug) {\n const dirName = path.basename(path.resolve(cwd));\n slug = sanitizeSlug(dirName);\n name = dirName;\n } else {\n name = slug.replace(/[-_]/g, ' ').replace(/\\b\\w/g, l => l.toUpperCase());\n }\n\n return {\n slug,\n name: name || slug,\n gitRemote,\n workingDir: cwd\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { randomUUID } from 'crypto';\nimport dotenv from 'dotenv';\n\ndotenv.config();\n\nexport interface MemHubConfig {\n apiUrl: string;\n apiKey?: string;\n projectId?: string;\n projectSlug?: string;\n orgId?: string;\n deviceId: string;\n outboxPath: string;\n storageDir: string;\n}\n\n/**\n * @deprecated Legacy type alias kept for backwards compatibility. Use `MemHubConfig`.\n */\nexport type TeamContextConfig = MemHubConfig;\n\nexport function defaultStorageDir(): string {\n return path.join(os.homedir(), '.memhub');\n}\n\n/** Resolves the active storage dir consistently for reads and writes. */\nexport function resolveStorageDir(): string {\n return process.env.MEMHUB_DIR\n || process.env.TEAMCONTEXT_DIR // deprecated alias\n || defaultStorageDir();\n}\n\n/**\n * @deprecated Legacy config directory, read only when the MemHub directory has no saved config.\n */\nexport function legacyStorageDir(): string {\n return path.join(os.homedir(), '.teamcontext');\n}\n\nfunction configFile(dir: string): string {\n return path.join(dir, 'config.json');\n}\n\nconst IS_POSIX = process.platform !== 'win32';\n\n/** Owner-only directory (0700) so stored credentials are not world-readable. */\nexport function ensureDirectory(dir: string): void {\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n if (IS_POSIX) {\n try { fs.chmodSync(dir, 0o700); } catch { /* best effort on shared mounts */ }\n }\n}\n\n/** Resolves MEMHUB_* first, falling back to deprecated TEAMCONTEXT_* aliases. */\nfunction envPreferred(name: string): string | undefined {\n return process.env[name] || process.env[name.replace(/^MEMHUB_/, 'TEAMCONTEXT_')];\n}\n\nexport function loadSavedConfig(): Partial<MemHubConfig> {\n const paths = [configFile(defaultStorageDir()), configFile(legacyStorageDir())];\n for (const file of paths) {\n try {\n if (fs.existsSync(file)) {\n return JSON.parse(fs.readFileSync(file, 'utf8'));\n }\n } catch (err) {\n // Ignore read errors\n }\n }\n return {};\n}\n\n/**\n * Persists config (including the API credential) into the storage dir.\n * The file is written with mode 0600 and tightened afterwards so a previously\n * world-readable config cannot stay exposed. Best effort on platforms that\n * ignore POSIX permissions.\n */\nexport function saveConfig(updates: Partial<MemHubConfig>): void {\n const dir = resolveStorageDir();\n ensureDirectory(dir);\n const current = loadSavedConfig();\n const merged = { ...current, ...updates };\n const file = configFile(dir);\n fs.writeFileSync(file, JSON.stringify(merged, null, 2), { encoding: 'utf8', mode: 0o600 });\n if (IS_POSIX) {\n try { fs.chmodSync(file, 0o600); } catch { /* best effort */ }\n }\n}\n\n/** Removes MemHub credentials and the local durable sync queue without touching cloud history. */\nexport function clearLocalState(): void {\n const saved = loadSavedConfig();\n const dir = resolveStorageDir();\n const files = new Set([\n configFile(dir),\n saved.outboxPath,\n envPreferred('MEMHUB_OUTBOX_PATH'),\n path.join(dir, 'outbox.db'),\n ].filter((value): value is string => Boolean(value)));\n for (const file of files) {\n for (const candidate of [file, `${file}-wal`, `${file}-shm`]) {\n try { if (fs.existsSync(candidate)) fs.unlinkSync(candidate); } catch { /* best effort */ }\n }\n }\n}\n\nexport function getOrCreateDeviceId(): string {\n const saved = loadSavedConfig();\n if (saved.deviceId && saved.deviceId.length > 10) {\n return saved.deviceId;\n }\n const newDeviceId = randomUUID();\n saveConfig({ deviceId: newDeviceId });\n return newDeviceId;\n}\n\nexport function getConfig(): MemHubConfig {\n const saved = loadSavedConfig();\n const storageDir = resolveStorageDir();\n ensureDirectory(storageDir);\n\n const deviceId = envPreferred('MEMHUB_DEVICE_ID') || saved.deviceId || getOrCreateDeviceId();\n const apiUrl = envPreferred('MEMHUB_API_URL') || saved.apiUrl || 'https://memhub.simplex.lat';\n const apiKey = envPreferred('MEMHUB_API_KEY') || saved.apiKey;\n const projectId = envPreferred('MEMHUB_PROJECT_ID') || saved.projectId;\n const projectSlug = envPreferred('MEMHUB_PROJECT') || saved.projectSlug;\n const orgId = envPreferred('MEMHUB_ORG_ID') || saved.orgId;\n const outboxPath = envPreferred('MEMHUB_OUTBOX_PATH') || path.join(storageDir, 'outbox.db');\n\n return {\n apiUrl: apiUrl.replace(/\\/$/, ''),\n apiKey,\n projectId,\n projectSlug,\n orgId,\n deviceId,\n outboxPath,\n storageDir\n };\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\nimport { RulesInjector } from './rules-injector.js';\n\nexport interface InjectOptions {\n apiKey: string;\n apiUrl?: string;\n projectId?: string;\n cwd?: string;\n dryRun?: boolean;\n}\n\nexport interface InjectionResult {\n target: string;\n filePath: string;\n success: boolean;\n action: 'created' | 'updated' | 'unchanged' | 'error';\n backupPath?: string;\n error?: string;\n}\n\nexport class IdeConfigInjector {\n private static serverConfig() {\n return { command: 'memhub', args: ['serve'] };\n }\n\n private static injectJsonMcpConfig(\n target: string,\n configPath: string,\n options: InjectOptions,\n ): InjectionResult {\n try {\n const parent = path.dirname(configPath);\n if (!fs.existsSync(parent) && !options.dryRun) fs.mkdirSync(parent, { recursive: true });\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n const existed = fs.existsSync(configPath);\n if (!options.dryRun) fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n return { target, filePath: configPath, success: true, action: existed ? 'updated' : 'created' };\n } catch (err: any) {\n return { target, filePath: configPath, success: false, action: 'error', error: err.message };\n }\n }\n\n /**\n * Injects config and memory rules for Claude Code (`mcp.json` and `CLAUDE.md`)\n */\n public static injectClaudeCode(options: InjectOptions): InjectionResult {\n const cwd = options.cwd || process.cwd();\n const configPath = path.join(cwd, 'mcp.json');\n try {\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n\n if (!options.dryRun) {\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n RulesInjector.injectClaudeCode(cwd);\n }\n\n return {\n target: 'Claude Code',\n filePath: configPath,\n success: true,\n action: fs.existsSync(configPath) ? 'updated' : 'created'\n };\n } catch (err: any) {\n return {\n target: 'Claude Code',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /**\n * Injects config and memory rules for Cursor (`.cursor/mcp.json` and `.cursorrules`)\n */\n public static injectCursor(options: InjectOptions): InjectionResult {\n const cwd = options.cwd || process.cwd();\n const cursorDir = path.join(cwd, '.cursor');\n const configPath = path.join(cursorDir, 'mcp.json');\n try {\n if (!fs.existsSync(cursorDir) && !options.dryRun) {\n fs.mkdirSync(cursorDir, { recursive: true });\n }\n\n let config: any = { mcpServers: {} };\n if (fs.existsSync(configPath)) {\n config = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n }\n\n config.mcpServers = config.mcpServers || {};\n config.mcpServers.memhub = this.serverConfig();\n\n if (!options.dryRun) {\n fs.writeFileSync(configPath, JSON.stringify(config, null, 2), 'utf8');\n RulesInjector.injectCursor(cwd);\n }\n\n return {\n target: 'Cursor',\n filePath: configPath,\n success: true,\n action: fs.existsSync(configPath) ? 'updated' : 'created'\n };\n } catch (err: any) {\n return {\n target: 'Cursor',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /** Google Antigravity 2.0 / IDE / CLI shared global MCP configuration and rules. */\n public static injectAntigravity(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Google Antigravity',\n path.join(os.homedir(), '.gemini', 'config', 'mcp_config.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectAntigravity(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Windsurf Cascade global MCP configuration and rules. */\n public static injectWindsurf(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Windsurf',\n path.join(os.homedir(), '.codeium', 'windsurf', 'mcp_config.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectWindsurf(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Cline global MCP configuration and rules. */\n public static injectCline(options: InjectOptions): InjectionResult {\n const res = this.injectJsonMcpConfig(\n 'Cline',\n path.join(os.homedir(), '.cline', 'data', 'settings', 'cline_mcp_settings.json'),\n options,\n );\n if (res.success && !options.dryRun) {\n RulesInjector.injectCline(options.cwd || process.cwd());\n }\n return res;\n }\n\n /** Generic JSON client using the common { mcpServers: {} } format. */\n public static injectOther(configPath: string, options: InjectOptions): InjectionResult {\n return this.injectJsonMcpConfig('Other MCP client', path.resolve(configPath), options);\n }\n\n /**\n * Injects config and memory rules for Codex CLI (`config.toml` and `AGENTS.md`)\n */\n public static injectCodex(options: InjectOptions): InjectionResult {\n const codexDir = path.join(os.homedir(), '.codex');\n const configPath = path.join(codexDir, 'config.toml');\n try {\n if (!fs.existsSync(codexDir) && !options.dryRun) {\n fs.mkdirSync(codexDir, { recursive: true });\n }\n\n const entry = `\n# MemHub MCP Connector\n[mcp.servers.memhub]\ncommand = \"memhub\"\nargs = [\"serve\"]\n`;\n\n let content = '';\n if (fs.existsSync(configPath)) {\n content = fs.readFileSync(configPath, 'utf8');\n }\n\n if (!content.includes('[mcp.servers.memhub]')) {\n content += entry;\n if (!options.dryRun) {\n fs.writeFileSync(configPath, content, 'utf8');\n }\n }\n\n if (!options.dryRun) {\n RulesInjector.injectCodex(options.cwd || process.cwd());\n }\n\n return {\n target: 'Codex CLI',\n filePath: configPath,\n success: true,\n action: 'updated'\n };\n } catch (err: any) {\n return {\n target: 'Codex CLI',\n filePath: configPath,\n success: false,\n action: 'error',\n error: err.message\n };\n }\n }\n\n /**\n * Injects for all supported IDEs and tools\n */\n public static injectAll(options: InjectOptions): InjectionResult[] {\n return [\n this.injectClaudeCode(options),\n this.injectCursor(options),\n this.injectCodex(options),\n this.injectAntigravity(options),\n this.injectWindsurf(options),\n this.injectCline(options)\n ];\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport os from 'os';\n\nexport const MEMHUB_RULES_BEGIN_MARKER = '<!-- BEGIN MEMHUB MEMORY PROTOCOL — managed by memhub -->';\nexport const MEMHUB_RULES_END_MARKER = '<!-- END MEMHUB MEMORY PROTOCOL -->';\n\nexport const MEMHUB_PROTOCOL_INSTRUCTIONS = `${MEMHUB_RULES_BEGIN_MARKER}\n\n## MemHub Persistent Shared Memory — Protocol\n\nYou have access to MemHub, a persistent memory and team knowledge system that survives across sessions, compactions, teammates, and repositories.\n\n### WHEN TO SAVE TO MEMORY (mandatory — not optional)\n\nYou must autonomously call \\`mem_save\\` (or \\`memory_save\\`) IMMEDIATELY after any of these events without asking the user:\n- Bug fix completed\n- Architecture or design decision made\n- Non-obvious discovery about the codebase or dependencies\n- Configuration change, environment setup, or deployment step\n- Pattern established (naming, structure, convention)\n- User preference, constraint, or requirement learned\n\nFormat for \\`mem_save\\`:\n- **title**: Verb + what — short, searchable (e.g. \"Fixed N+1 query in UserList\", \"Chose Zustand over Redux\")\n- **type**: bugfix | decision | architecture | discovery | pattern | config | preference\n- **scope**: project (default) | personal\n- **topic_key** (recommended for evolving topics): stable key like architecture/auth-model\n- **content**:\n **What**: One sentence — what was done\n **Why**: What motivated it (user request, bug, performance, etc.)\n **Where**: Files or paths affected\n **Learned**: Gotchas, edge cases, things that surprised you (omit if none)\n\n### MULTI-PROJECT & NEW REPOSITORY AUTONOMY\n\nMemHub automatically detects the Git repository and folder context. When you save a memory in a new repository or workspace, MemHub autonomously connects it to the user's organization in the cloud dashboard and links all memories.\n\n### Topic update rules (mandatory)\n\n- Different topics must not overwrite each other (e.g. architecture vs bugfix)\n- Reuse the same \\`topic_key\\` to update an evolving topic instead of creating duplicate fragmented observations\n- If unsure about the key, call \\`mem_suggest_topic_key\\` first and reuse it\n- Use \\`mem_update\\` when you have an exact observation ID to update\n\n### WHEN TO SEARCH MEMORY (mandatory)\n\nWhen the user asks to recall something or references past work (\"remember\", \"recall\", \"what did we do\", \"cómo lo resolvimos\", \"qué hicimos\", or past session context):\n1. First call \\`mem_context\\` (fast recent session history)\n2. Call \\`mem_search\\` (or \\`memory_recall\\`) with relevant keywords (hybrid lexical + vector search)\n3. If needed, use \\`mem_get_observation\\` for full untruncated content\n\nAlso search memory PROACTIVELY when:\n- Starting work on an unfamiliar area of the codebase\n- The user mentions a technical topic you have no context on — check if past sessions covered it\n\n### SESSION CLOSE PROTOCOL (mandatory)\n\nBefore ending a session or declaring a milestone done, you MUST call \\`mem_session_summary\\` with this structure:\n\n## Goal\n[What was worked on this session]\n\n## Instructions\n[User preferences or constraints discovered — skip if none]\n\n## Discoveries\n- [Technical findings, gotchas, non-obvious learnings]\n\n## Accomplished\n- [Completed items with key details]\n\n## Next Steps\n- [What remains to be done — for the next session]\n\n## Relevant Files\n- path/to/file — [what it does or what changed]\n\n### PASSIVE CAPTURE\n\nWhen completing a task or subtask, include a \\`## Key Learnings:\\` section at the end of your response with numbered items. MemHub will automatically capture and persist these learnings for the team.\n\n### AFTER COMPACTION\n\nIf context reset or compaction occurs, immediately call \\`mem_session_summary\\` to persist the compacted summary, then call \\`mem_context\\` to recover previous session context.\n\n${MEMHUB_RULES_END_MARKER}`;\n\nexport interface RuleInjectionResult {\n target: string;\n filePath: string;\n success: boolean;\n action: 'created' | 'updated' | 'unchanged' | 'error';\n error?: string;\n}\n\nexport class RulesInjector {\n /**\n * Injects or updates the managed MemHub rules block inside a markdown file.\n */\n public static injectIntoFile(filePath: string, targetName: string): RuleInjectionResult {\n try {\n const dir = path.dirname(filePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n let content = '';\n const existed = fs.existsSync(filePath);\n if (existed) {\n content = fs.readFileSync(filePath, 'utf8');\n }\n\n let updatedContent = '';\n if (content.includes(MEMHUB_RULES_BEGIN_MARKER) && content.includes(MEMHUB_RULES_END_MARKER)) {\n const regex = new RegExp(\n `${MEMHUB_RULES_BEGIN_MARKER}[\\\\s\\\\S]*?${MEMHUB_RULES_END_MARKER}`,\n 'g'\n );\n updatedContent = content.replace(regex, MEMHUB_PROTOCOL_INSTRUCTIONS);\n } else {\n updatedContent = content.trim() ? `${content.trim()}\\n\\n${MEMHUB_PROTOCOL_INSTRUCTIONS}\\n` : `${MEMHUB_PROTOCOL_INSTRUCTIONS}\\n`;\n }\n\n if (existed && content.trim() === updatedContent.trim()) {\n return { target: targetName, filePath, success: true, action: 'unchanged' };\n }\n\n fs.writeFileSync(filePath, updatedContent, 'utf8');\n return { target: targetName, filePath, success: true, action: existed ? 'updated' : 'created' };\n } catch (err: any) {\n return { target: targetName, filePath, success: false, action: 'error', error: err.message };\n }\n }\n\n /**\n * Injects rules for Claude Code (`CLAUDE.md` and `~/.claude/CLAUDE.md`)\n */\n public static injectClaudeCode(cwd = process.cwd()): RuleInjectionResult[] {\n const local = this.injectIntoFile(path.join(cwd, 'CLAUDE.md'), 'Claude Code (Workspace)');\n const globalPath = path.join(os.homedir(), '.claude', 'CLAUDE.md');\n const global = this.injectIntoFile(globalPath, 'Claude Code (Global)');\n return [local, global];\n }\n\n /**\n * Injects rules for Cursor (`.cursorrules` and `.cursor/rules/memhub.mdc`)\n */\n public static injectCursor(cwd = process.cwd()): RuleInjectionResult[] {\n const cursorRules = this.injectIntoFile(path.join(cwd, '.cursorrules'), 'Cursor (.cursorrules)');\n const mdcPath = path.join(cwd, '.cursor', 'rules', 'memhub.mdc');\n const mdc = this.injectIntoFile(mdcPath, 'Cursor MDC (.cursor/rules/memhub.mdc)');\n const globalCursor = this.injectIntoFile(path.join(os.homedir(), '.cursorrules'), 'Cursor (Global .cursorrules)');\n return [cursorRules, mdc, globalCursor];\n }\n\n /**\n * Injects rules for Google Antigravity / Gemini CLI\n */\n public static injectAntigravity(cwd = process.cwd()): RuleInjectionResult[] {\n const localRule = path.join(cwd, '.gemini', 'antigravity-cli', 'rules', 'memhub.md');\n const globalRule = path.join(os.homedir(), '.gemini', 'antigravity-cli', 'rules', 'memhub.md');\n const legacyGlobalRule = path.join(os.homedir(), '.gemini', 'config', 'rules', 'memhub.md');\n return [\n this.injectIntoFile(localRule, 'Antigravity (Workspace)'),\n this.injectIntoFile(globalRule, 'Antigravity (Global)'),\n this.injectIntoFile(legacyGlobalRule, 'Antigravity Config (Global)')\n ];\n }\n\n /**\n * Injects rules for Windsurf (`.windsurfrules`)\n */\n public static injectWindsurf(cwd = process.cwd()): RuleInjectionResult[] {\n const local = this.injectIntoFile(path.join(cwd, '.windsurfrules'), 'Windsurf (.windsurfrules)');\n const global = this.injectIntoFile(path.join(os.homedir(), '.windsurfrules'), 'Windsurf (Global .windsurfrules)');\n return [local, global];\n }\n\n /**\n * Injects rules for Cline / Roo Code (`.clinerules`)\n */\n public static injectCline(cwd = process.cwd()): RuleInjectionResult[] {\n const local = this.injectIntoFile(path.join(cwd, '.clinerules'), 'Cline (.clinerules)');\n const global = this.injectIntoFile(path.join(os.homedir(), '.clinerules'), 'Cline (Global .clinerules)');\n return [local, global];\n }\n\n /**\n * Injects rules for Codex CLI & General Agent specification (`AGENTS.md`)\n */\n public static injectCodex(cwd = process.cwd()): RuleInjectionResult[] {\n const localAgents = this.injectIntoFile(path.join(cwd, 'AGENTS.md'), 'Agents Specification (AGENTS.md)');\n const globalCodex = this.injectIntoFile(path.join(os.homedir(), '.codex', 'instructions.md'), 'Codex CLI (Global instructions)');\n return [localAgents, globalCodex];\n }\n\n /**\n * Injects rules across all supported AI coding agents globally and locally.\n */\n public static injectAll(cwd = process.cwd()): RuleInjectionResult[] {\n return [\n ...this.injectClaudeCode(cwd),\n ...this.injectCursor(cwd),\n ...this.injectAntigravity(cwd),\n ...this.injectWindsurf(cwd),\n ...this.injectCline(cwd),\n ...this.injectCodex(cwd)\n ];\n }\n}\n","import fs from 'fs';\nimport path from 'path';\nimport https from 'https';\nimport { resolveStorageDir, ensureDirectory } from './config.js';\n\ninterface UpdateCache {\n lastChecked: number;\n latestVersion: string;\n}\n\nconst CHECK_INTERVAL_MS = 2 * 60 * 60 * 1000; // 2 hours\nconst PACKAGE_NAME = '@simplexlat/memhub';\n\nexport function compareVersions(v1: string, v2: string): number {\n const parts1 = v1.split('.').map((p) => parseInt(p, 10) || 0);\n const parts2 = v2.split('.').map((p) => parseInt(p, 10) || 0);\n for (let i = 0; i < Math.max(parts1.length, parts2.length); i++) {\n const num1 = parts1[i] || 0;\n const num2 = parts2[i] || 0;\n if (num1 > num2) return 1;\n if (num1 < num2) return -1;\n }\n return 0;\n}\n\nexport async function fetchLatestFromNpm(): Promise<string | null> {\n return new Promise((resolve) => {\n const req = https.get(\n `https://registry.npmjs.org/${PACKAGE_NAME}/latest`,\n {\n headers: { 'User-Agent': 'memhub-cli' },\n timeout: 2000,\n },\n (res) => {\n if (res.statusCode !== 200) {\n resolve(null);\n return;\n }\n let data = '';\n res.on('data', (chunk) => {\n data += chunk;\n });\n res.on('end', () => {\n try {\n const parsed = JSON.parse(data);\n resolve(parsed.version || null);\n } catch {\n resolve(null);\n }\n });\n }\n );\n req.on('error', () => resolve(null));\n req.on('timeout', () => {\n req.destroy();\n resolve(null);\n });\n });\n}\n\nexport class UpdateNotifier {\n private static cacheFile(): string {\n return path.join(resolveStorageDir(), 'update-cache.json');\n }\n\n public static async checkForUpdates(currentVersion: string): Promise<void> {\n if (process.argv.includes('serve') || process.argv.includes('update')) {\n return;\n }\n\n try {\n const storageDir = resolveStorageDir();\n ensureDirectory(storageDir);\n const cachePath = this.cacheFile();\n\n let cache: UpdateCache = { lastChecked: 0, latestVersion: currentVersion };\n if (fs.existsSync(cachePath)) {\n try {\n cache = JSON.parse(fs.readFileSync(cachePath, 'utf8'));\n } catch {\n // ignore corrupted cache\n }\n }\n\n const now = Date.now();\n let latestVersion = cache.latestVersion;\n\n // If cache is older than check interval, fetch in background\n if (now - cache.lastChecked > CHECK_INTERVAL_MS) {\n // Asynchronously update cache\n fetchLatestFromNpm().then((fetched) => {\n if (fetched) {\n cache = { lastChecked: Date.now(), latestVersion: fetched };\n try {\n fs.writeFileSync(cachePath, JSON.stringify(cache), 'utf8');\n } catch {\n // ignore\n }\n }\n }).catch(() => {});\n }\n\n // If cache already knows a newer version is available, print notification banner\n if (compareVersions(latestVersion, currentVersion) > 0) {\n console.error('\\n┌────────────────────────────────────────────────────────────┐');\n console.error(`│ 🚀 Actualización disponible para MemHub: ${currentVersion} → \\x1b[32m${latestVersion}\\x1b[0m │`);\n console.error('│ Ejecuta \\x1b[1m\\x1b[36mmh update\\x1b[0m para instalar la última versión. │');\n console.error('└────────────────────────────────────────────────────────────┘\\n');\n }\n } catch {\n // Non-blocking, never crash user commands\n }\n }\n}\n","/**\n * Browser-based `mh login` orchestration.\n *\n * The CLI never sees a password: it creates an expiring single-use device code,\n * opens the MemHub consent page in the user's browser, and polls until the user\n * approves or denies. The approved scoped credential is delivered exactly once.\n */\n\nimport { spawn } from 'node:child_process';\n\nexport interface CliAuthInitiation {\n deviceCode: string;\n verificationUrl: string;\n expiresAt: string;\n expiresInSeconds: number;\n pollIntervalSeconds: number;\n}\n\nexport interface CliAuthApproval {\n status: 'approved';\n apiKey: string;\n keyPrefix: string;\n keyExpiresAt: string | null;\n orgSlug: string | null;\n orgName: string | null;\n projectSlug: string | null;\n projectName: string | null;\n}\n\nexport type CliAuthPollResponse = CliAuthApproval\n | { status: 'pending'; expiresAt?: string | null }\n | { status: 'denied' }\n | { status: 'consumed' }\n | { status: 'not_found' };\n\nexport class LoginDeniedError extends Error {\n constructor() { super('Login request denied in the browser.'); this.name = 'LoginDeniedError'; }\n}\n\nexport class LoginExpiredError extends Error {\n constructor() { super('Login request expired before approval. Run `mh login` again.'); this.name = 'LoginExpiredError'; }\n}\n\nexport class LoginTimeoutError extends Error {\n constructor(timeoutMs: number) {\n super(`Login was not approved within ${Math.round(timeoutMs / 1000)}s. Run \\`mh login\\` again.`);\n this.name = 'LoginTimeoutError';\n }\n}\n\nexport interface LoginRequestOptions {\n label?: string;\n scopes?: string[];\n timeoutMs?: number;\n fetchImpl?: typeof fetch;\n sleepImpl?: (ms: number) => Promise<void>;\n}\n\nconst DEFAULT_TIMEOUT_MS = 15 * 60 * 1000;\nconst MIN_SLEEP_MS = 250;\n\nexport function defaultSleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/** Creates the expiring device code pair server-side; only digests are stored remotely. */\nexport async function requestCliAuth(\n apiUrl: string,\n options: LoginRequestOptions = {},\n): Promise<CliAuthInitiation> {\n const doFetch = options.fetchImpl ?? fetch;\n const res = await doFetch(`${apiUrl}/api/cli-auth/initiate`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ label: options.label, scopes: options.scopes }),\n });\n if (!res.ok) {\n throw new Error(`Unable to start login (${res.status}). Check that ${apiUrl} is reachable.`);\n }\n return await res.json() as CliAuthInitiation;\n}\n\nasync function pollOnce(\n apiUrl: string,\n deviceCode: string,\n doFetch: typeof fetch,\n): Promise<{ result: CliAuthPollResponse; retryAfterSeconds: number | null }> {\n const res = await doFetch(`${apiUrl}/api/cli-auth/poll`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ deviceCode }),\n });\n if (res.status === 429) {\n const retryAfter = Number(res.headers.get('retry-after'));\n return {\n result: { status: 'pending', expiresAt: null },\n retryAfterSeconds: Number.isFinite(retryAfter) && retryAfter > 0 ? Math.ceil(retryAfter) : null,\n };\n }\n if (!res.ok) throw new Error(`Login polling failed (${res.status}).`);\n return { result: await res.json() as CliAuthPollResponse, retryAfterSeconds: null };\n}\n\nexport interface WaitOutcome {\n apiKey: string;\n keyPrefix: string;\n orgSlug: string | null;\n orgName: string | null;\n projectSlug: string | null;\n projectName: string | null;\n}\n\n/**\n * Bounded polling loop: stops at the deadline (matching the server-side code\n * TTL), backs off when rate limited, and aborts immediately on deny/expiry.\n */\nexport async function waitForCliApproval(\n apiUrl: string,\n initiation: Pick<CliAuthInitiation, 'deviceCode' | 'pollIntervalSeconds'>,\n options: LoginRequestOptions = {},\n): Promise<WaitOutcome> {\n const doFetch = options.fetchImpl ?? fetch;\n const sleep = options.sleepImpl ?? defaultSleep;\n const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n\n let pendingNoticeShown = false;\n while (Date.now() < deadline) {\n const { result, retryAfterSeconds } = await pollOnce(apiUrl, initiation.deviceCode, doFetch);\n\n if (result.status === 'approved') {\n if (!result.apiKey) throw new Error('Server returned an empty credential.');\n return {\n apiKey: result.apiKey,\n keyPrefix: result.keyPrefix,\n orgSlug: result.orgSlug,\n orgName: result.orgName,\n projectSlug: result.projectSlug,\n projectName: result.projectName,\n };\n }\n if (result.status === 'denied') throw new LoginDeniedError();\n if (result.status === 'consumed' || result.status === 'not_found') throw new LoginExpiredError();\n\n if (!pendingNoticeShown) {\n process.stderr.write('⏳ Waiting for approval in your browser…\\n');\n pendingNoticeShown = true;\n }\n\n const intervalMs = Math.max((initiation.pollIntervalSeconds || 2) * 1000, MIN_SLEEP_MS);\n const backoffMs = retryAfterSeconds ? Math.min(retryAfterSeconds * 1000, 30_000) : intervalMs;\n const remainingMs = deadline - Date.now();\n await sleep(Math.max(MIN_SLEEP_MS, Math.min(backoffMs, remainingMs)));\n }\n throw new LoginTimeoutError(timeoutMs);\n}\n\nexport interface BrowserOpenCommand {\n command: string;\n args: string[];\n}\n\n/** Pure mapping used by openInBrowser; exported for deterministic tests. */\nexport function browserOpenCommand(platform: string = process.platform): BrowserOpenCommand {\n const command = platform === 'darwin' ? 'open'\n : platform === 'win32' ? 'cmd'\n : 'xdg-open';\n return command === 'cmd' ? { command, args: ['/c', 'start', '', '<url>'] } : { command, args: ['<url>'] };\n}\n\n/** Platform-aware best-effort browser open; never throws and never blocks. */\nexport function openInBrowser(url: string): boolean {\n try {\n const { command, args } = browserOpenCommand();\n const child = spawn(command, args.map((arg) => (arg === '<url>' ? url : arg)), { stdio: 'ignore', detached: true });\n child.unref();\n return true;\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":["randomUUID","input","randomUUID","path","fs","input","output","fs","path","randomUUID","fs","path","os","fs","path","os","path","fs","os","execSync","path","fs","path","path","fs","path","execSync"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@simplexlat/memhub",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Local-first MCP proxy for MemHub & agentmemory with durable SQLite outbox",
5
5
  "type": "module",
6
6
  "bin": {