mnemos-capture 1.4.1 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  <div align="center">
2
2
  <br>
3
- <a href="https://mnemos-capture.vercel.app">
3
+ <a href="https://xkg.xmu.sh">
4
4
  <picture>
5
5
  <source media="(prefers-color-scheme: dark)" srcset="public/xkg-hero-dark.gif">
6
6
  <img src="public/xkg-hero-light.gif" width="160" height="160" alt="xkg">
@@ -53,7 +53,7 @@ You find useful stuff, you capture through the web app, then xkg connects it int
53
53
  xkg will continuously compound that knowledge over time — keeping AI workers' context up to date as human knowledge evolves.
54
54
 
55
55
  > [!IMPORTANT]
56
- > We are migrating from **mnemos** / **Xmu** to **xkg**. The code now lives at [xmu-labs/xkg](https://github.com/xmu-labs/xkg); the app URL and the npm package still say `mnemos-capture`. Sorry for the inconvenience.
56
+ > We are migrating from **mnemos** / **Xmu** to **xkg**. The app now lives at [xkg.xmu.sh](https://xkg.xmu.sh) and the code at [xmu-labs/xkg](https://github.com/xmu-labs/xkg). Connectors set up with `mnemos-capture.vercel.app` keep working. The npm package still says `mnemos-capture`. Sorry for the inconvenience.
57
57
 
58
58
  ## Start here
59
59
 
@@ -61,7 +61,7 @@ You do not need a terminal to start.
61
61
 
62
62
  ### 1. Create your account
63
63
 
64
- Open **[mnemos-capture.vercel.app](https://mnemos-capture.vercel.app)** and sign in with GitHub.
64
+ Open **[xkg.xmu.sh](https://xkg.xmu.sh)** and sign in with GitHub.
65
65
 
66
66
  xkg will:
67
67
 
@@ -91,20 +91,20 @@ xkg is LLM-agnostic. Any worker that speaks MCP can use the same knowledge.
91
91
  Two primitives:
92
92
 
93
93
  ```text
94
- https://mnemos-capture.vercel.app/api/mcp
94
+ https://xkg.xmu.sh/api/mcp
95
95
  ```
96
96
 
97
97
  ```bash
98
98
  npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY
99
99
  ```
100
100
 
101
- The CLI binary is **`xkg`** (also `xmu` and `mnemos-capture`). `npx` still uses the package name `mnemos-capture`. An MCP server already registered as `xmu` or `mnemos` keeps working.
101
+ The CLI binary is **`xkg`** (also `xmu` and `mnemos-capture`). An MCP server already registered as `xmu` or `mnemos`, or set up with `mnemos-capture@latest`, keeps working.
102
102
 
103
103
  **On the web** — paste the URL (no terminal). **In the terminal** — run the command. Finish xkg onboarding first, then ask: *list my inbox* or *brief me*.
104
104
 
105
105
  ### On the web
106
106
 
107
- Name the connector `xkg`, paste `https://mnemos-capture.vercel.app/api/mcp`, sign in with GitHub when asked.
107
+ Name the connector `xkg`, paste `https://xkg.xmu.sh/api/mcp`, sign in with GitHub when asked.
108
108
 
109
109
  #### Claude
110
110
 
@@ -114,7 +114,7 @@ Name the connector `xkg`, paste `https://mnemos-capture.vercel.app/api/mcp`, sig
114
114
 
115
115
  1. Settings → Plugins → Browse plugins
116
116
  2. Name it xkg
117
- 3. Paste `https://mnemos-capture.vercel.app/api/mcp`
117
+ 3. Paste `https://xkg.xmu.sh/api/mcp`
118
118
  4. Sign in with GitHub when asked
119
119
 
120
120
  #### Grok
@@ -192,7 +192,7 @@ claude mcp add xkg -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY
192
192
  Or the URL, no API key:
193
193
 
194
194
  ```bash
195
- claude mcp add --transport http xkg https://mnemos-capture.vercel.app/api/mcp
195
+ claude mcp add --transport http xkg https://xkg.xmu.sh/api/mcp
196
196
  ```
197
197
 
198
198
  Optional session hooks (MCP works without them):
@@ -233,7 +233,7 @@ If the tool can launch a local process, register the same `npx` command. If it h
233
233
  }
234
234
  ```
235
235
 
236
- No MCP support yet? Capture in the [xkg app](https://mnemos-capture.vercel.app) and connect later.
236
+ No MCP support yet? Capture in the [xkg app](https://xkg.xmu.sh) and connect later.
237
237
 
238
238
  ## Workflow
239
239
 
package/dist/cli/hooks.js CHANGED
@@ -2,15 +2,29 @@ import { homedir, tmpdir } from "os";
2
2
  import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
3
3
  import { join } from "path";
4
4
  import { execSync } from "child_process";
5
- const HOSTED_URL = "https://mnemos-capture.vercel.app/api/mcp";
5
+ const HOSTED_URL = "https://xkg.xmu.sh/api/mcp";
6
6
  const CLAUDE_SETTINGS_PATH = join(homedir(), ".claude", "settings.json");
7
- // Matches both legacy ("mnemos-capture inbox-check") and modern
8
- // ("mnemos-capture@latest inbox-check") hook command forms.
7
+ /** The npm package new hooks run. Releases also publish it as `mnemos-capture`. */
8
+ const PACKAGE = "@xmu-labs/xkg";
9
+ /**
10
+ * Matches hooks this CLI installed under either package name, with or without
11
+ * a version: `npx -y @xmu-labs/xkg@latest inbox-check`,
12
+ * `npx -y mnemos-capture@latest inbox-check`, and the legacy
13
+ * `npx mnemos-capture inbox-check`.
14
+ */
15
+ function isOurHook(cmd, subcommand) {
16
+ // The package must be a whole shell word: `my-xkg` or `@acme/xkg` is someone else's.
17
+ return new RegExp(`(?:^|\\s)(?:${PACKAGE}|mnemos-capture)(?:@[\\w.-]+)?\\s+${subcommand}\\b`).test(cmd);
18
+ }
9
19
  function isXkgHook(cmd) {
10
- return cmd.includes("mnemos-capture") && cmd.includes("inbox-check");
20
+ return isOurHook(cmd, "inbox-check");
11
21
  }
12
22
  function isXkgPreToolHook(cmd) {
13
- return cmd.includes("mnemos-capture") && cmd.includes("vault-check");
23
+ return isOurHook(cmd, "vault-check");
24
+ }
25
+ /** True when a hook already runs the current package at @latest — nothing to migrate. */
26
+ function isCurrentHook(cmd) {
27
+ return cmd.includes(`npx -y ${PACKAGE}@latest `);
14
28
  }
15
29
  function readSettings() {
16
30
  if (!existsSync(CLAUDE_SETTINGS_PATH))
@@ -86,17 +100,16 @@ export function setupHooks(apiKey, opts = {}) {
86
100
  break;
87
101
  }
88
102
  // skipIfExists (serve-mcp auto-install): preserve user-configured hooks but
89
- // silently migrate legacy hooks that don't use @latest so they always stay fresh.
103
+ // silently migrate hooks that pin a version or use the old package name.
90
104
  if (existingCmd && opts.skipIfExists) {
91
- const alreadyLatest = existingCmd.includes("mnemos-capture@latest");
92
- if (alreadyLatest)
105
+ if (isCurrentHook(existingCmd))
93
106
  return;
94
107
  // Migration: preserve the existing --briefing flag when upgrading to @latest
95
108
  opts = { ...opts, briefing: existingCmd.includes("--briefing") };
96
109
  }
97
110
  const command = opts.briefing
98
- ? `npx -y mnemos-capture@latest inbox-check --key ${apiKey} --briefing`
99
- : `npx -y mnemos-capture@latest inbox-check --key ${apiKey}`;
111
+ ? `npx -y ${PACKAGE}@latest inbox-check --key ${apiKey} --briefing`
112
+ : `npx -y ${PACKAGE}@latest inbox-check --key ${apiKey}`;
100
113
  // Remove any existing xkg inbox-check hook (handles key rotation too)
101
114
  const filtered = sessionStart
102
115
  .map((group) => ({
@@ -137,10 +150,10 @@ export function setupPreToolHook(apiKey, opts = {}) {
137
150
  break;
138
151
  }
139
152
  if (existingCmd && opts.skipIfExists) {
140
- if (existingCmd.includes("mnemos-capture@latest"))
153
+ if (isCurrentHook(existingCmd))
141
154
  return;
142
155
  }
143
- const command = `npx -y mnemos-capture@latest vault-check --key ${apiKey}`;
156
+ const command = `npx -y ${PACKAGE}@latest vault-check --key ${apiKey}`;
144
157
  const filtered = preToolCall
145
158
  .map((group) => ({
146
159
  ...group,
package/dist/cli/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const HOSTED_URL = "https://mnemos-capture.vercel.app";
2
+ const HOSTED_URL = "https://xkg.xmu.sh";
3
3
  async function main() {
4
4
  const args = process.argv.slice(2);
5
5
  const command = args[0];
@@ -17,7 +17,7 @@ async function main() {
17
17
  const keyIdx = args.indexOf("--key");
18
18
  const apiKey = keyIdx !== -1 ? args[keyIdx + 1] : undefined;
19
19
  if (!apiKey) {
20
- console.error("Usage: npx mnemos-capture setup-hooks --key YOUR_API_KEY [--briefing] [--vault]");
20
+ console.error("Usage: npx @xmu-labs/xkg setup-hooks --key YOUR_API_KEY [--briefing] [--vault]");
21
21
  process.exit(1);
22
22
  }
23
23
  setupHooks(apiKey, { briefing: args.includes("--briefing"), vault: args.includes("--vault") });
@@ -68,7 +68,7 @@ async function main() {
68
68
  console.log(" First time? Sign in with GitHub — setup takes 30 seconds.");
69
69
  console.log("");
70
70
  console.log(" Connect an AI worker:");
71
- console.log(" claude mcp add xkg -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY");
71
+ console.log(" claude mcp add xkg -- npx -y @xmu-labs/xkg@latest serve-mcp --key YOUR_API_KEY");
72
72
  console.log("");
73
73
  // Try to open the URL in the default browser
74
74
  const { exec } = await import("child_process");
@@ -90,7 +90,7 @@ function printHelp() {
90
90
  xkg kos --key KEY [--plan FILE] Implement a plan in an isolated worktree
91
91
  xkg help Show this help
92
92
 
93
- npx -y mnemos-capture@latest … Same CLI, via the published package
93
+ npx -y @xmu-labs/xkg@latest … Same CLI, via the published package
94
94
 
95
95
  MCP tools (via your AI worker):
96
96
  briefing — Session-start briefing with ranked insights to apply
@@ -108,13 +108,13 @@ function printHelp() {
108
108
  and reports the branch + the plan's Verification Checklist when done.
109
109
 
110
110
  Get started:
111
- 1. Run: npx mnemos-capture
111
+ 1. Run: npx @xmu-labs/xkg
112
112
  2. Sign in with GitHub (creates your knowledge repo automatically)
113
113
  3. Set a PIN for quick mobile access
114
114
  4. Start capturing!
115
115
 
116
116
  Connect to Claude Code:
117
- claude mcp add xkg -- npx -y mnemos-capture@latest serve-mcp --key YOUR_API_KEY
117
+ claude mcp add xkg -- npx -y @xmu-labs/xkg@latest serve-mcp --key YOUR_API_KEY
118
118
 
119
119
  The @latest tag ensures every Claude Code session uses the most recent
120
120
  published version. serve-mcp also self-upgrades on startup as a safety net
@@ -122,10 +122,10 @@ function printHelp() {
122
122
 
123
123
  The hook is installed automatically when you start the MCP server.
124
124
  To upgrade to a full project briefing at session start:
125
- npx mnemos-capture setup-hooks --key YOUR_API_KEY --briefing
125
+ npx @xmu-labs/xkg setup-hooks --key YOUR_API_KEY --briefing
126
126
 
127
127
  To enable the vault (surfaces captures as you edit files — opt-in):
128
- npx mnemos-capture setup-hooks --key YOUR_API_KEY --vault
128
+ npx @xmu-labs/xkg setup-hooks --key YOUR_API_KEY --vault
129
129
  `);
130
130
  }
131
131
  main().catch((err) => {
@@ -1,6 +1,6 @@
1
1
  // MCP server that runs locally via stdio and proxies to the hosted API.
2
- // Used by Claude Code: claude mcp add xkg -- npx mnemos-capture serve-mcp --key <api-key>
3
- const DEFAULT_HOSTED_URL = "https://mnemos-capture.vercel.app/api/mcp";
2
+ // Used by Claude Code: claude mcp add xkg -- npx @xmu-labs/xkg serve-mcp --key <api-key>
3
+ const DEFAULT_HOSTED_URL = "https://xkg.xmu.sh/api/mcp";
4
4
  /** Override for pointing the proxy at a local instance during development. */
5
5
  const HOSTED_URL = process.env.XKG_API_URL ?? process.env.XMU_API_URL ?? process.env.MNEMOS_API_URL ?? DEFAULT_HOSTED_URL;
6
6
  function sendMessage(msg) {
@@ -73,8 +73,8 @@ export async function serveMcp() {
73
73
  const apiKey = keyIdx !== -1 ? args[keyIdx + 1] : undefined;
74
74
  if (!apiKey) {
75
75
  process.stderr.write("\nxkg MCP server requires an API key.\n");
76
- process.stderr.write("Usage: npx -y mnemos-capture@latest serve-mcp --key <your-api-key>\n\n");
77
- process.stderr.write("Get your API key at: https://mnemos-capture.vercel.app/onboard\n\n");
76
+ process.stderr.write("Usage: npx -y @xmu-labs/xkg@latest serve-mcp --key <your-api-key>\n\n");
77
+ process.stderr.write("Get your API key at: https://xkg.xmu.sh/onboard\n\n");
78
78
  process.exit(1);
79
79
  }
80
80
  // Self-upgrade: if a newer version exists on npm, respawn via npx @latest.
@@ -1,26 +1,36 @@
1
1
  // Self-update enforcement: ensures users always run the latest xkg CLI.
2
2
  //
3
3
  // Strategy: on serve-mcp startup, query npm for the latest published version.
4
- // If behind, respawn the process via `npx -y mnemos-capture@latest` and proxy
5
- // stdio. An XKG_UPGRADED=1 env var (MNEMOS_UPGRADED=1 from releases before
4
+ // If behind, respawn the process via `npx -y <name>@<latest>` and proxy stdio.
5
+ // <name> is the package this copy was installed as: every release is published
6
+ // as both `@xmu-labs/xkg` and `mnemos-capture`, so each install updates under its own
7
+ // name. An XKG_UPGRADED=1 env var (MNEMOS_UPGRADED=1 from releases before
6
8
  // 1.4.1) prevents infinite recursion.
7
9
  import { readFileSync } from "fs";
8
10
  import { fileURLToPath } from "url";
9
11
  import { dirname, join } from "path";
10
12
  import { spawn } from "child_process";
11
- const NPM_REGISTRY = "https://registry.npmjs.org/mnemos-capture/latest";
12
13
  const CHECK_TIMEOUT_MS = 2000;
13
- export function getCurrentVersion() {
14
+ /** The names releases are published under; anything else falls back to the first. */
15
+ export const PACKAGE_NAMES = ["@xmu-labs/xkg", "mnemos-capture"];
16
+ function readOwnPackage() {
14
17
  try {
15
18
  const here = dirname(fileURLToPath(import.meta.url));
16
19
  // dist/cli/version-check.js → ../../package.json
17
- const pkg = JSON.parse(readFileSync(join(here, "../../package.json"), "utf-8"));
18
- return pkg.version ?? "0.0.0";
20
+ return JSON.parse(readFileSync(join(here, "../../package.json"), "utf-8"));
19
21
  }
20
22
  catch {
21
- return "0.0.0";
23
+ return {};
22
24
  }
23
25
  }
26
+ export function getCurrentVersion() {
27
+ return readOwnPackage().version ?? "0.0.0";
28
+ }
29
+ /** The npm name this copy was installed as, so updates come from the same name. */
30
+ export function getPackageName() {
31
+ const name = readOwnPackage().name;
32
+ return PACKAGE_NAMES.includes(name ?? "") ? name : PACKAGE_NAMES[0];
33
+ }
24
34
  export function isNewer(latest, current) {
25
35
  const l = latest.split(".").map((n) => parseInt(n, 10) || 0);
26
36
  const c = current.split(".").map((n) => parseInt(n, 10) || 0);
@@ -34,9 +44,11 @@ export function isNewer(latest, current) {
34
44
  }
35
45
  return false;
36
46
  }
37
- async function getLatestVersion() {
47
+ async function getLatestVersion(name) {
38
48
  try {
39
- const res = await fetch(NPM_REGISTRY, { signal: AbortSignal.timeout(CHECK_TIMEOUT_MS) });
49
+ const res = await fetch(`https://registry.npmjs.org/${name}/latest`, {
50
+ signal: AbortSignal.timeout(CHECK_TIMEOUT_MS),
51
+ });
40
52
  if (!res.ok)
41
53
  return null;
42
54
  const data = (await res.json());
@@ -47,8 +59,8 @@ async function getLatestVersion() {
47
59
  }
48
60
  }
49
61
  /**
50
- * If a newer version exists on npm, respawn via `npx -y mnemos-capture@latest`
51
- * with the original argv, piping stdio. Returns true if the caller should stop
62
+ * If a newer version exists on npm, respawn via `npx -y <name>@<latest>` under
63
+ * the name this copy was installed as, with the original argv, piping stdio. Returns true if the caller should stop
52
64
  * (because the child is taking over). Returns false otherwise — caller should
53
65
  * continue with normal startup.
54
66
  */
@@ -57,12 +69,13 @@ export async function maybeSelfUpgrade() {
57
69
  // releases set MNEMOS_UPGRADED, and may be the parent that spawned this one.
58
70
  if (process.env.XKG_UPGRADED === "1" || process.env.MNEMOS_UPGRADED === "1")
59
71
  return false;
72
+ const name = getPackageName();
60
73
  const current = getCurrentVersion();
61
- const latest = await getLatestVersion();
74
+ const latest = await getLatestVersion(name);
62
75
  if (!latest || !isNewer(latest, current))
63
76
  return false;
64
77
  process.stderr.write(`xkg: upgrading to v${latest} (was v${current})...\n`);
65
- const child = spawn("npx", ["-y", `mnemos-capture@${latest}`, ...process.argv.slice(2)], {
78
+ const child = spawn("npx", ["-y", `${name}@${latest}`, ...process.argv.slice(2)], {
66
79
  stdio: "inherit",
67
80
  env: { ...process.env, XKG_UPGRADED: "1" },
68
81
  });
package/package.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "mnemos-capture",
3
- "version": "1.4.1",
3
+ "version": "1.6.0",
4
4
  "description": "xkg — Turn what you discover into context your AI workers can use. Capture once, then brief, plan, and execute with any MCP-compatible tool.",
5
5
  "type": "module",
6
6
  "bin": {
7
- "mnemos-capture": "./dist/cli/index.js",
8
- "xkg": "./dist/cli/index.js",
9
- "xmu": "./dist/cli/index.js"
7
+ "mnemos-capture": "dist/cli/index.js",
8
+ "xkg": "dist/cli/index.js",
9
+ "xmu": "dist/cli/index.js"
10
10
  },
11
11
  "scripts": {
12
12
  "dev": "next dev",
@@ -38,7 +38,7 @@
38
38
  "license": "MIT",
39
39
  "repository": {
40
40
  "type": "git",
41
- "url": "https://github.com/xmu-labs/xkg.git"
41
+ "url": "git+https://github.com/xmu-labs/xkg.git"
42
42
  },
43
43
  "homepage": "https://github.com/xmu-labs/xkg",
44
44
  "files": [
@@ -47,22 +47,22 @@
47
47
  "README.md"
48
48
  ],
49
49
  "dependencies": {
50
- "@anthropic-ai/sdk": "^0.133.0",
51
- "@vercel/postgres": "^0.10.0",
52
- "next": "^16.3.5",
50
+ "@anthropic-ai/sdk": "^0.135.0",
51
+ "@neondatabase/serverless": "^1.2.0",
52
+ "next": "^16.4.2",
53
53
  "react": "^19.3.0",
54
54
  "react-dom": "^19.3.0"
55
55
  },
56
56
  "devDependencies": {
57
57
  "@playwright/test": "^1.62.1",
58
+ "@tailwindcss/postcss": "^4.3.3",
58
59
  "@types/node": "^26",
59
60
  "@types/react": "^19.3.0",
60
61
  "@types/react-dom": "^19.3.0",
61
- "autoprefixer": "^10.6.1",
62
62
  "eslint": "^9.39.5",
63
- "eslint-config-next": "^16.3.5",
63
+ "eslint-config-next": "^16.4.2",
64
64
  "postcss": "^8.5.3",
65
- "tailwindcss": "^3.4.17",
65
+ "tailwindcss": "^4.3.3",
66
66
  "typescript": "^6.0.3",
67
67
  "vitest": "^5.0.1"
68
68
  },