@bennys001/claude-code-memory 0.10.0 → 0.11.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.
Files changed (2) hide show
  1. package/dist/index.js +126 -24
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@
4
4
  var package_default = {
5
5
  name: "@bennys001/claude-code-memory",
6
6
  publishConfig: { access: "public" },
7
- version: "0.10.0",
7
+ version: "0.11.1",
8
8
  description: "MCP server that gives Claude Code persistent memory via an Obsidian knowledge vault",
9
9
  module: "dist/index.js",
10
10
  main: "dist/index.js",
@@ -866,12 +866,47 @@ function registerResearchTool(server, entries, vaultPath) {
866
866
  });
867
867
  }
868
868
 
869
- // src/index.ts
870
- import { spawn as spawn2 } from "child_process";
871
-
872
869
  // src/cli/claude-code.ts
873
870
  import { spawn } from "child_process";
874
- var SERVER_CMD = ["bunx", "@bennys001/claude-code-memory", "--stdio"];
871
+ var SERVER_CMD = ["ccm", "--stdio"];
872
+ function installGlobal() {
873
+ return new Promise((resolve4) => {
874
+ let stderr = "";
875
+ const proc = spawn("bun", ["install", "-g", "@bennys001/claude-code-memory"], { stdio: ["ignore", "ignore", "pipe"] });
876
+ proc.stderr.on("data", (data) => {
877
+ stderr += data.toString();
878
+ });
879
+ proc.on("error", (err) => {
880
+ resolve4({ success: false, error: err.message });
881
+ });
882
+ proc.on("close", (code) => {
883
+ if (code === 0) {
884
+ resolve4({ success: true });
885
+ } else {
886
+ resolve4({ success: false, error: stderr.trim() || `bun install exited with code ${code}` });
887
+ }
888
+ });
889
+ });
890
+ }
891
+ function uninstallGlobal() {
892
+ return new Promise((resolve4) => {
893
+ let stderr = "";
894
+ const proc = spawn("bun", ["remove", "-g", "@bennys001/claude-code-memory"], { stdio: ["ignore", "ignore", "pipe"] });
895
+ proc.stderr.on("data", (data) => {
896
+ stderr += data.toString();
897
+ });
898
+ proc.on("error", (err) => {
899
+ resolve4({ success: false, error: err.message });
900
+ });
901
+ proc.on("close", (code) => {
902
+ if (code === 0) {
903
+ resolve4({ success: true });
904
+ } else {
905
+ resolve4({ success: false, error: stderr.trim() || `bun remove exited with code ${code}` });
906
+ }
907
+ });
908
+ });
909
+ }
875
910
  var REGISTER_ARGS = [
876
911
  "mcp",
877
912
  "add",
@@ -884,7 +919,15 @@ var REGISTER_ARGS = [
884
919
  ...SERVER_CMD
885
920
  ];
886
921
  var MANUAL_COMMAND = `claude mcp add --transport stdio --scope user ccm -- ${SERVER_CMD.join(" ")}`;
887
- function registerMcpServer() {
922
+ function removeMcpServer() {
923
+ return new Promise((resolve4) => {
924
+ const proc = spawn("claude", ["mcp", "remove", "ccm"], { stdio: "ignore" });
925
+ proc.on("error", () => resolve4());
926
+ proc.on("close", () => resolve4());
927
+ });
928
+ }
929
+ async function registerMcpServer() {
930
+ await removeMcpServer();
888
931
  return new Promise((resolve4) => {
889
932
  let stdout = "";
890
933
  let stderr = "";
@@ -1085,6 +1128,18 @@ async function registerVaultWithObsidian(vaultPath, configPath = DEFAULT_CONFIG_
1085
1128
  await writeFile2(configPath, JSON.stringify(config, null, 2));
1086
1129
  return { registered: true, vaultId };
1087
1130
  }
1131
+ async function unregisterVaultFromObsidian(vaultPath, configPath = DEFAULT_CONFIG_PATH) {
1132
+ const config = await loadObsidianConfig(configPath);
1133
+ if (!config)
1134
+ return false;
1135
+ const vaultId = findVaultByPath(config, vaultPath);
1136
+ if (!vaultId)
1137
+ return false;
1138
+ await copyFile(configPath, `${configPath}.backup`);
1139
+ delete config.vaults[vaultId];
1140
+ await writeFile2(configPath, JSON.stringify(config, null, 2));
1141
+ return true;
1142
+ }
1088
1143
 
1089
1144
  // src/cli/init.ts
1090
1145
  var VAULT_PATH = join6(homedir3(), ".ccm", "knowledge-base");
@@ -1126,6 +1181,12 @@ async function executeInit() {
1126
1181
  detail: obsidianResult.reason
1127
1182
  });
1128
1183
  }
1184
+ const installResult = await installGlobal();
1185
+ if (installResult.success) {
1186
+ steps.push({ name: "global install", status: "created", detail: "ccm binary installed" });
1187
+ } else {
1188
+ steps.push({ name: "global install", status: "failed", detail: installResult.error });
1189
+ }
1129
1190
  const mcpResult = await registerMcpServer();
1130
1191
  if (mcpResult.success) {
1131
1192
  steps.push({ name: "Claude Code MCP", status: "created", detail: mcpResult.output });
@@ -1169,6 +1230,8 @@ function formatInitSummary(result) {
1169
1230
  }
1170
1231
 
1171
1232
  // src/index.ts
1233
+ import { rm } from "fs/promises";
1234
+ import { createInterface } from "readline";
1172
1235
  var VAULT_PATH2 = join7(homedir4(), ".ccm", "knowledge-base");
1173
1236
  function parseCliArgs() {
1174
1237
  const args = process.argv.slice(2);
@@ -1176,19 +1239,27 @@ function parseCliArgs() {
1176
1239
  return "version";
1177
1240
  if (args.includes("--update"))
1178
1241
  return "update";
1242
+ if (args.includes("--uninstall"))
1243
+ return "uninstall";
1179
1244
  if (args.includes("--init"))
1180
1245
  return "init";
1181
1246
  if (args.includes("--stdio"))
1182
1247
  return "serve";
1248
+ if (!process.stdin.isTTY)
1249
+ return "serve";
1183
1250
  return "help";
1184
1251
  }
1185
1252
  function printHelp() {
1186
1253
  console.log(`${C.bold}claude-code-memory${C.reset} ${C.dim}(ccm)${C.reset} \u2014 Persistent memory for Claude Code
1187
1254
 
1188
1255
  ${C.bold}Usage:${C.reset}
1189
- ${C.cyan}bunx @bennys001/claude-code-memory --init${C.reset} Set up vault and register MCP server
1190
- ${C.cyan}ccm --update${C.reset} Update to the latest version
1191
- ${C.cyan}ccm --version${C.reset} Show installed version
1256
+ ${C.cyan}ccm --init${C.reset} Set up vault and register MCP server
1257
+ ${C.cyan}ccm --update${C.reset} Update to the latest version
1258
+ ${C.cyan}ccm --uninstall${C.reset} Remove ccm, MCP server, and optionally the vault
1259
+ ${C.cyan}ccm --version${C.reset} Show installed version
1260
+
1261
+ ${C.bold}First-time install:${C.reset}
1262
+ ${C.cyan}bun install -g @bennys001/claude-code-memory && ccm --init${C.reset}
1192
1263
 
1193
1264
  ${C.dim}Vault:${C.reset} ~/.ccm/knowledge-base/
1194
1265
  ${C.dim}Docs:${C.reset} https://github.com/bennys001/claude-code-memory`);
@@ -1200,18 +1271,6 @@ async function fetchLatestVersion() {
1200
1271
  const data = await res.json();
1201
1272
  return data.version;
1202
1273
  }
1203
- function runCommand(cmd, args) {
1204
- return new Promise((resolve4, reject) => {
1205
- const proc = spawn2(cmd, args, { stdio: "inherit" });
1206
- proc.on("error", reject);
1207
- proc.on("close", (code) => {
1208
- if (code === 0)
1209
- resolve4();
1210
- else
1211
- reject(new Error(`${cmd} ${args.join(" ")} exited with code ${code}`));
1212
- });
1213
- });
1214
- }
1215
1274
  async function runUpdate() {
1216
1275
  console.log(`${C.dim}Checking for updates...${C.reset}`);
1217
1276
  const latest = await fetchLatestVersion();
@@ -1221,12 +1280,50 @@ async function runUpdate() {
1221
1280
  }
1222
1281
  console.log(`${C.dim}v${package_default.version}${C.reset} \u2192 ${C.green}v${latest}${C.reset}
1223
1282
  `);
1224
- await runCommand("bun", ["pm", "cache", "rm"]);
1225
- await runCommand("claude", ["mcp", "remove", "ccm"]);
1226
- await runCommand("claude", ["mcp", "add", "--transport", "stdio", "--scope", "user", "ccm", "--", ...SERVER_CMD]);
1283
+ const installResult = await installGlobal();
1284
+ if (!installResult.success) {
1285
+ throw new Error(`Global install failed: ${installResult.error}`);
1286
+ }
1287
+ const mcpResult = await registerMcpServer();
1288
+ if (!mcpResult.success) {
1289
+ throw new Error(`MCP registration failed: ${mcpResult.error}`);
1290
+ }
1227
1291
  console.log(`
1228
1292
  ${C.green}Updated to v${latest}${C.reset}`);
1229
1293
  }
1294
+ function promptConfirm(question) {
1295
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
1296
+ return new Promise((resolve4) => {
1297
+ rl.question(question, (answer) => {
1298
+ rl.close();
1299
+ resolve4(answer.toLowerCase() === "y");
1300
+ });
1301
+ });
1302
+ }
1303
+ async function runUninstall() {
1304
+ console.log(`${C.bold}ccm uninstall${C.reset}
1305
+ `);
1306
+ await removeMcpServer();
1307
+ console.log(` ${C.green}+${C.reset} Removed MCP server`);
1308
+ await unregisterVaultFromObsidian(VAULT_PATH);
1309
+ console.log(` ${C.green}+${C.reset} Unregistered Obsidian vault`);
1310
+ const ccmDir = join7(homedir4(), ".ccm");
1311
+ const deleteVault = await promptConfirm(` Delete vault at ${C.dim}${VAULT_PATH}${C.reset}? ${C.dim}(y/N)${C.reset} `);
1312
+ if (deleteVault) {
1313
+ await rm(ccmDir, { recursive: true, force: true });
1314
+ console.log(` ${C.green}+${C.reset} Deleted vault`);
1315
+ } else {
1316
+ console.log(` ${C.yellow}-${C.reset} Kept vault`);
1317
+ }
1318
+ const uninstallResult = await uninstallGlobal();
1319
+ if (uninstallResult.success) {
1320
+ console.log(` ${C.green}+${C.reset} Uninstalled ccm binary`);
1321
+ } else {
1322
+ console.log(` ${C.red}!${C.reset} Failed to uninstall: ${uninstallResult.error}`);
1323
+ }
1324
+ console.log(`
1325
+ ${C.green}Done${C.reset}`);
1326
+ }
1230
1327
  async function runInit() {
1231
1328
  const result = await executeInit();
1232
1329
  console.log(formatInitSummary(result));
@@ -1268,6 +1365,11 @@ if (cli === "version") {
1268
1365
  console.error("Fatal:", err);
1269
1366
  process.exit(1);
1270
1367
  });
1368
+ } else if (cli === "uninstall") {
1369
+ runUninstall().catch((err) => {
1370
+ console.error("Fatal:", err);
1371
+ process.exit(1);
1372
+ });
1271
1373
  } else if (cli === "init") {
1272
1374
  runInit().catch((err) => {
1273
1375
  console.error("Fatal:", err);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@bennys001/claude-code-memory",
3
3
  "publishConfig": { "access": "public" },
4
- "version": "0.10.0",
4
+ "version": "0.11.1",
5
5
  "description": "MCP server that gives Claude Code persistent memory via an Obsidian knowledge vault",
6
6
  "module": "dist/index.js",
7
7
  "main": "dist/index.js",