@hasna/mementos 0.1.0 → 0.1.1

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.
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>Mementos Dashboard</title>
7
- <script type="module" crossorigin src="/assets/index-Dnhl5e5q.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-C5oRjtKB.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-C8vbNL_5.css">
9
9
  </head>
10
10
  <body>
package/dist/cli/index.js CHANGED
@@ -3640,4 +3640,81 @@ program2.command("bulk <action> <ids...>").description("Batch operations: forget
3640
3640
  handleError(e);
3641
3641
  }
3642
3642
  });
3643
+ program2.command("mcp").description("Install mementos MCP server into Claude Code, Codex, or Gemini").option("--claude", "Install into Claude Code (~/.claude/.mcp.json)").option("--codex", "Install into Codex (~/.codex/config.toml)").option("--gemini", "Install into Gemini (~/.gemini/settings.json)").option("--all", "Install into all supported agents").option("--uninstall", "Remove mementos MCP from config").action((opts) => {
3644
+ const { readFileSync: readFileSync3, writeFileSync, existsSync: fileExists } = __require("fs");
3645
+ const { join: pathJoin } = __require("path");
3646
+ const { homedir: getHome } = __require("os");
3647
+ const home = getHome();
3648
+ const mementosCmd = process.argv[0]?.includes("bun") ? pathJoin(home, ".bun", "bin", "mementos-mcp") : "mementos-mcp";
3649
+ const targets = opts.all ? ["claude", "codex", "gemini"] : [
3650
+ opts.claude ? "claude" : null,
3651
+ opts.codex ? "codex" : null,
3652
+ opts.gemini ? "gemini" : null
3653
+ ].filter(Boolean);
3654
+ if (targets.length === 0) {
3655
+ console.log(chalk.yellow("Specify a target: --claude, --codex, --gemini, or --all"));
3656
+ console.log(chalk.gray("Example: mementos mcp --all"));
3657
+ return;
3658
+ }
3659
+ for (const target of targets) {
3660
+ try {
3661
+ if (target === "claude") {
3662
+ const configPath = pathJoin(home, ".claude", ".mcp.json");
3663
+ let config = {};
3664
+ if (fileExists(configPath)) {
3665
+ config = JSON.parse(readFileSync3(configPath, "utf-8"));
3666
+ }
3667
+ const servers = config["mcpServers"] || {};
3668
+ if (opts.uninstall) {
3669
+ delete servers["mementos"];
3670
+ } else {
3671
+ servers["mementos"] = { command: mementosCmd, args: [] };
3672
+ }
3673
+ config["mcpServers"] = servers;
3674
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + `
3675
+ `, "utf-8");
3676
+ console.log(chalk.green(`${opts.uninstall ? "Removed from" : "Installed into"} Claude Code: ${configPath}`));
3677
+ }
3678
+ if (target === "codex") {
3679
+ const configPath = pathJoin(home, ".codex", "config.toml");
3680
+ if (fileExists(configPath)) {
3681
+ let content = readFileSync3(configPath, "utf-8");
3682
+ if (opts.uninstall) {
3683
+ content = content.replace(/\n\[mcp_servers\.mementos\]\ncommand = "[^"]*"\nargs = \[\]\n?/g, `
3684
+ `);
3685
+ } else if (!content.includes("[mcp_servers.mementos]")) {
3686
+ content += `
3687
+ [mcp_servers.mementos]
3688
+ command = "${mementosCmd}"
3689
+ args = []
3690
+ `;
3691
+ }
3692
+ writeFileSync(configPath, content, "utf-8");
3693
+ console.log(chalk.green(`${opts.uninstall ? "Removed from" : "Installed into"} Codex: ${configPath}`));
3694
+ } else {
3695
+ console.log(chalk.yellow(`Codex config not found: ${configPath}`));
3696
+ }
3697
+ }
3698
+ if (target === "gemini") {
3699
+ const configPath = pathJoin(home, ".gemini", "settings.json");
3700
+ let config = {};
3701
+ if (fileExists(configPath)) {
3702
+ config = JSON.parse(readFileSync3(configPath, "utf-8"));
3703
+ }
3704
+ const servers = config["mcpServers"] || {};
3705
+ if (opts.uninstall) {
3706
+ delete servers["mementos"];
3707
+ } else {
3708
+ servers["mementos"] = { command: mementosCmd, args: [] };
3709
+ }
3710
+ config["mcpServers"] = servers;
3711
+ writeFileSync(configPath, JSON.stringify(config, null, 2) + `
3712
+ `, "utf-8");
3713
+ console.log(chalk.green(`${opts.uninstall ? "Removed from" : "Installed into"} Gemini: ${configPath}`));
3714
+ }
3715
+ } catch (e) {
3716
+ console.error(chalk.red(`Failed for ${target}: ${e instanceof Error ? e.message : String(e)}`));
3717
+ }
3718
+ }
3719
+ });
3643
3720
  program2.parse(process.argv);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAwiBH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAmC9C"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";AACA;;;GAGG;AAslBH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAkD9C"}
@@ -1,6 +1,11 @@
1
1
  #!/usr/bin/env bun
2
2
  // @bun
3
3
 
4
+ // src/server/index.ts
5
+ import { existsSync as existsSync2 } from "fs";
6
+ import { dirname as dirname2, extname, join as join2 } from "path";
7
+ import { fileURLToPath } from "url";
8
+
4
9
  // src/types/index.ts
5
10
  class MemoryNotFoundError extends Error {
6
11
  constructor(id) {
@@ -755,6 +760,44 @@ function parsePort() {
755
760
  }
756
761
  return DEFAULT_PORT;
757
762
  }
763
+ function resolveDashboardDir() {
764
+ const candidates = [];
765
+ try {
766
+ const scriptDir = dirname2(fileURLToPath(import.meta.url));
767
+ candidates.push(join2(scriptDir, "..", "dashboard", "dist"));
768
+ candidates.push(join2(scriptDir, "..", "..", "dashboard", "dist"));
769
+ } catch {}
770
+ if (process.argv[1]) {
771
+ const mainDir = dirname2(process.argv[1]);
772
+ candidates.push(join2(mainDir, "..", "dashboard", "dist"));
773
+ candidates.push(join2(mainDir, "..", "..", "dashboard", "dist"));
774
+ }
775
+ candidates.push(join2(process.cwd(), "dashboard", "dist"));
776
+ for (const c of candidates) {
777
+ if (existsSync2(c))
778
+ return c;
779
+ }
780
+ return join2(process.cwd(), "dashboard", "dist");
781
+ }
782
+ var MIME_TYPES = {
783
+ ".html": "text/html; charset=utf-8",
784
+ ".js": "application/javascript",
785
+ ".css": "text/css",
786
+ ".json": "application/json",
787
+ ".svg": "image/svg+xml",
788
+ ".png": "image/png",
789
+ ".ico": "image/x-icon",
790
+ ".woff": "font/woff",
791
+ ".woff2": "font/woff2"
792
+ };
793
+ function serveStaticFile(filePath) {
794
+ if (!existsSync2(filePath))
795
+ return null;
796
+ const ct = MIME_TYPES[extname(filePath)] || "application/octet-stream";
797
+ return new Response(Bun.file(filePath), {
798
+ headers: { "Content-Type": ct }
799
+ });
800
+ }
758
801
  var CORS_HEADERS = {
759
802
  "Access-Control-Allow-Origin": "*",
760
803
  "Access-Control-Allow-Methods": "GET, POST, PATCH, DELETE, OPTIONS",
@@ -1117,6 +1160,20 @@ function startServer(port) {
1117
1160
  }
1118
1161
  const matched = matchRoute(req.method, pathname);
1119
1162
  if (!matched) {
1163
+ if (pathname.startsWith("/api/")) {
1164
+ return errorResponse("Not found", 404);
1165
+ }
1166
+ const dashDir = resolveDashboardDir();
1167
+ if (existsSync2(dashDir) && (req.method === "GET" || req.method === "HEAD")) {
1168
+ if (pathname !== "/") {
1169
+ const staticRes = serveStaticFile(join2(dashDir, pathname));
1170
+ if (staticRes)
1171
+ return staticRes;
1172
+ }
1173
+ const indexRes = serveStaticFile(join2(dashDir, "index.html"));
1174
+ if (indexRes)
1175
+ return indexRes;
1176
+ }
1120
1177
  return errorResponse("Not found", 404);
1121
1178
  }
1122
1179
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hasna/mementos",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Universal memory system for AI agents - CLI + MCP server + library API",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",