@bennys001/claude-code-memory 0.9.10 → 0.10.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 +6 -6
- package/dist/index.js +121 -82
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -49,7 +49,7 @@ Creates a new note with structured frontmatter. Create-only — rejects existing
|
|
|
49
49
|
| Param | Type | Required | Description |
|
|
50
50
|
|------------|----------|----------|-------------------------------------------------|
|
|
51
51
|
| `path` | string | Yes | Relative path for new note |
|
|
52
|
-
| `type` | string | Yes | `
|
|
52
|
+
| `type` | string | Yes | `gotchas`, `decisions`, `patterns`, or `references` |
|
|
53
53
|
| `title` | string | Yes | Note title (becomes H1) |
|
|
54
54
|
| `body` | string | Yes | Markdown body |
|
|
55
55
|
| `tags` | string[] | No | Searchable tags |
|
|
@@ -95,10 +95,10 @@ Add { cache: 'no-store' } or use revalidate to avoid stale data...
|
|
|
95
95
|
|
|
96
96
|
| Type | Icon | Purpose |
|
|
97
97
|
|-------------|------|------------------------------------|
|
|
98
|
-
| `
|
|
99
|
-
| `
|
|
100
|
-
| `
|
|
101
|
-
| `
|
|
98
|
+
| `gotchas` | 🔴 | Pitfalls and common mistakes |
|
|
99
|
+
| `decisions` | 🟤 | Architecture and tooling decisions |
|
|
100
|
+
| `patterns` | 🔵 | Reusable code patterns |
|
|
101
|
+
| `references` | 🟢 | Cheatsheets and quick-reference |
|
|
102
102
|
|
|
103
103
|
### Frontmatter Fields
|
|
104
104
|
|
|
@@ -139,7 +139,7 @@ name = "my-next-app"
|
|
|
139
139
|
|
|
140
140
|
[filter]
|
|
141
141
|
tags = ["typescript", "react", "nextjs"]
|
|
142
|
-
types = ["
|
|
142
|
+
types = ["gotchas", "patterns"]
|
|
143
143
|
exclude = ["drafts/*"]
|
|
144
144
|
```
|
|
145
145
|
|
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.
|
|
7
|
+
version: "0.10.0",
|
|
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",
|
|
@@ -68,18 +68,18 @@ import { get_encoding } from "tiktoken";
|
|
|
68
68
|
|
|
69
69
|
// src/vault/types.ts
|
|
70
70
|
import { z } from "zod";
|
|
71
|
-
var NoteType = z.enum(["
|
|
71
|
+
var NoteType = z.enum(["gotchas", "decisions", "patterns", "references"]);
|
|
72
72
|
var NOTE_TYPE_ICONS = {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
73
|
+
gotchas: "\uD83D\uDD34",
|
|
74
|
+
decisions: "\uD83D\uDFE4",
|
|
75
|
+
patterns: "\uD83D\uDD35",
|
|
76
|
+
references: "\uD83D\uDFE2"
|
|
77
77
|
};
|
|
78
78
|
var NOTE_TYPE_PRIORITY = {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
79
|
+
gotchas: 0,
|
|
80
|
+
decisions: 1,
|
|
81
|
+
patterns: 2,
|
|
82
|
+
references: 3
|
|
83
83
|
};
|
|
84
84
|
var NoteFrontmatter = z.object({
|
|
85
85
|
type: NoteType,
|
|
@@ -202,7 +202,7 @@ function formatKnowledgeSection(entries) {
|
|
|
202
202
|
return [
|
|
203
203
|
"## Knowledge Index",
|
|
204
204
|
"Use MCP tool `read` with the note path to fetch full details on demand.",
|
|
205
|
-
"\uD83D\uDD34 =
|
|
205
|
+
"\uD83D\uDD34 = gotchas \uD83D\uDFE4 = decisions \uD83D\uDD35 = patterns \uD83D\uDFE2 = references",
|
|
206
206
|
"",
|
|
207
207
|
table
|
|
208
208
|
].join(`
|
|
@@ -866,6 +866,64 @@ 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
|
+
// src/cli/claude-code.ts
|
|
873
|
+
import { spawn } from "child_process";
|
|
874
|
+
var SERVER_CMD = ["bunx", "@bennys001/claude-code-memory", "--stdio"];
|
|
875
|
+
var REGISTER_ARGS = [
|
|
876
|
+
"mcp",
|
|
877
|
+
"add",
|
|
878
|
+
"--transport",
|
|
879
|
+
"stdio",
|
|
880
|
+
"--scope",
|
|
881
|
+
"user",
|
|
882
|
+
"ccm",
|
|
883
|
+
"--",
|
|
884
|
+
...SERVER_CMD
|
|
885
|
+
];
|
|
886
|
+
var MANUAL_COMMAND = `claude mcp add --transport stdio --scope user ccm -- ${SERVER_CMD.join(" ")}`;
|
|
887
|
+
function registerMcpServer() {
|
|
888
|
+
return new Promise((resolve4) => {
|
|
889
|
+
let stdout = "";
|
|
890
|
+
let stderr = "";
|
|
891
|
+
const proc = spawn("claude", REGISTER_ARGS, { stdio: "pipe" });
|
|
892
|
+
proc.stdout.on("data", (data) => {
|
|
893
|
+
stdout += data.toString();
|
|
894
|
+
});
|
|
895
|
+
proc.stderr.on("data", (data) => {
|
|
896
|
+
stderr += data.toString();
|
|
897
|
+
});
|
|
898
|
+
proc.on("error", (err) => {
|
|
899
|
+
if (err.code === "ENOENT") {
|
|
900
|
+
resolve4({
|
|
901
|
+
success: false,
|
|
902
|
+
error: "Claude CLI not found in PATH",
|
|
903
|
+
manualCommand: MANUAL_COMMAND
|
|
904
|
+
});
|
|
905
|
+
} else {
|
|
906
|
+
resolve4({
|
|
907
|
+
success: false,
|
|
908
|
+
error: err.message,
|
|
909
|
+
manualCommand: MANUAL_COMMAND
|
|
910
|
+
});
|
|
911
|
+
}
|
|
912
|
+
});
|
|
913
|
+
proc.on("close", (code) => {
|
|
914
|
+
if (code === 0) {
|
|
915
|
+
resolve4({ success: true, output: (stdout || stderr).trim() });
|
|
916
|
+
} else {
|
|
917
|
+
resolve4({
|
|
918
|
+
success: false,
|
|
919
|
+
error: (stderr || stdout).trim() || `Process exited with code ${code}`,
|
|
920
|
+
manualCommand: MANUAL_COMMAND
|
|
921
|
+
});
|
|
922
|
+
}
|
|
923
|
+
});
|
|
924
|
+
});
|
|
925
|
+
}
|
|
926
|
+
|
|
869
927
|
// src/cli/init.ts
|
|
870
928
|
import { mkdir as mkdir2 } from "fs/promises";
|
|
871
929
|
import { join as join6 } from "path";
|
|
@@ -873,7 +931,7 @@ import { homedir as homedir3 } from "os";
|
|
|
873
931
|
|
|
874
932
|
// src/cli/seed.ts
|
|
875
933
|
var OFM_NOTE = (date) => `---
|
|
876
|
-
type:
|
|
934
|
+
type: patterns
|
|
877
935
|
tags:
|
|
878
936
|
- obsidian
|
|
879
937
|
- markdown
|
|
@@ -1028,73 +1086,6 @@ async function registerVaultWithObsidian(vaultPath, configPath = DEFAULT_CONFIG_
|
|
|
1028
1086
|
return { registered: true, vaultId };
|
|
1029
1087
|
}
|
|
1030
1088
|
|
|
1031
|
-
// src/cli/claude-code.ts
|
|
1032
|
-
import { spawn } from "child_process";
|
|
1033
|
-
import { resolve as resolvePath } from "path";
|
|
1034
|
-
function buildServerCommand() {
|
|
1035
|
-
const runtime = resolvePath(process.argv[0]);
|
|
1036
|
-
const script = resolvePath(process.argv[1]);
|
|
1037
|
-
return [runtime, script, "--stdio"];
|
|
1038
|
-
}
|
|
1039
|
-
function buildRegisterArgs(serverCmd) {
|
|
1040
|
-
return [
|
|
1041
|
-
"mcp",
|
|
1042
|
-
"add",
|
|
1043
|
-
"--transport",
|
|
1044
|
-
"stdio",
|
|
1045
|
-
"--scope",
|
|
1046
|
-
"user",
|
|
1047
|
-
"ccm",
|
|
1048
|
-
"--",
|
|
1049
|
-
...serverCmd
|
|
1050
|
-
];
|
|
1051
|
-
}
|
|
1052
|
-
function formatManualCommand(serverCmd) {
|
|
1053
|
-
return `claude mcp add --transport stdio --scope user ccm -- ${serverCmd.join(" ")}`;
|
|
1054
|
-
}
|
|
1055
|
-
function registerMcpServer() {
|
|
1056
|
-
const serverCmd = buildServerCommand();
|
|
1057
|
-
const registerArgs = buildRegisterArgs(serverCmd);
|
|
1058
|
-
const manualCommand = formatManualCommand(serverCmd);
|
|
1059
|
-
return new Promise((resolve4) => {
|
|
1060
|
-
let stdout = "";
|
|
1061
|
-
let stderr = "";
|
|
1062
|
-
const proc = spawn("claude", registerArgs, { stdio: "pipe" });
|
|
1063
|
-
proc.stdout.on("data", (data) => {
|
|
1064
|
-
stdout += data.toString();
|
|
1065
|
-
});
|
|
1066
|
-
proc.stderr.on("data", (data) => {
|
|
1067
|
-
stderr += data.toString();
|
|
1068
|
-
});
|
|
1069
|
-
proc.on("error", (err) => {
|
|
1070
|
-
if (err.code === "ENOENT") {
|
|
1071
|
-
resolve4({
|
|
1072
|
-
success: false,
|
|
1073
|
-
error: "Claude CLI not found in PATH",
|
|
1074
|
-
manualCommand
|
|
1075
|
-
});
|
|
1076
|
-
} else {
|
|
1077
|
-
resolve4({
|
|
1078
|
-
success: false,
|
|
1079
|
-
error: err.message,
|
|
1080
|
-
manualCommand
|
|
1081
|
-
});
|
|
1082
|
-
}
|
|
1083
|
-
});
|
|
1084
|
-
proc.on("close", (code) => {
|
|
1085
|
-
if (code === 0) {
|
|
1086
|
-
resolve4({ success: true, output: (stdout || stderr).trim() });
|
|
1087
|
-
} else {
|
|
1088
|
-
resolve4({
|
|
1089
|
-
success: false,
|
|
1090
|
-
error: (stderr || stdout).trim() || `Process exited with code ${code}`,
|
|
1091
|
-
manualCommand
|
|
1092
|
-
});
|
|
1093
|
-
}
|
|
1094
|
-
});
|
|
1095
|
-
});
|
|
1096
|
-
}
|
|
1097
|
-
|
|
1098
1089
|
// src/cli/init.ts
|
|
1099
1090
|
var VAULT_PATH = join6(homedir3(), ".ccm", "knowledge-base");
|
|
1100
1091
|
var SUBDIRS = ["gotchas", "decisions", "patterns", "references", "_templates"];
|
|
@@ -1181,6 +1172,10 @@ function formatInitSummary(result) {
|
|
|
1181
1172
|
var VAULT_PATH2 = join7(homedir4(), ".ccm", "knowledge-base");
|
|
1182
1173
|
function parseCliArgs() {
|
|
1183
1174
|
const args = process.argv.slice(2);
|
|
1175
|
+
if (args.includes("--version") || args.includes("-v"))
|
|
1176
|
+
return "version";
|
|
1177
|
+
if (args.includes("--update"))
|
|
1178
|
+
return "update";
|
|
1184
1179
|
if (args.includes("--init"))
|
|
1185
1180
|
return "init";
|
|
1186
1181
|
if (args.includes("--stdio"))
|
|
@@ -1188,14 +1183,50 @@ function parseCliArgs() {
|
|
|
1188
1183
|
return "help";
|
|
1189
1184
|
}
|
|
1190
1185
|
function printHelp() {
|
|
1191
|
-
console.log(`${C.bold}
|
|
1186
|
+
console.log(`${C.bold}claude-code-memory${C.reset} ${C.dim}(ccm)${C.reset} \u2014 Persistent memory for Claude Code
|
|
1192
1187
|
|
|
1193
1188
|
${C.bold}Usage:${C.reset}
|
|
1194
|
-
${C.cyan}
|
|
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
|
|
1195
1192
|
|
|
1196
1193
|
${C.dim}Vault:${C.reset} ~/.ccm/knowledge-base/
|
|
1197
1194
|
${C.dim}Docs:${C.reset} https://github.com/bennys001/claude-code-memory`);
|
|
1198
1195
|
}
|
|
1196
|
+
async function fetchLatestVersion() {
|
|
1197
|
+
const res = await fetch("https://registry.npmjs.org/@bennys001/claude-code-memory/latest");
|
|
1198
|
+
if (!res.ok)
|
|
1199
|
+
throw new Error(`npm registry returned ${res.status}`);
|
|
1200
|
+
const data = await res.json();
|
|
1201
|
+
return data.version;
|
|
1202
|
+
}
|
|
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
|
+
async function runUpdate() {
|
|
1216
|
+
console.log(`${C.dim}Checking for updates...${C.reset}`);
|
|
1217
|
+
const latest = await fetchLatestVersion();
|
|
1218
|
+
if (latest === package_default.version) {
|
|
1219
|
+
console.log(`Already on the latest version: ${C.green}v${package_default.version}${C.reset}`);
|
|
1220
|
+
return;
|
|
1221
|
+
}
|
|
1222
|
+
console.log(`${C.dim}v${package_default.version}${C.reset} \u2192 ${C.green}v${latest}${C.reset}
|
|
1223
|
+
`);
|
|
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]);
|
|
1227
|
+
console.log(`
|
|
1228
|
+
${C.green}Updated to v${latest}${C.reset}`);
|
|
1229
|
+
}
|
|
1199
1230
|
async function runInit() {
|
|
1200
1231
|
const result = await executeInit();
|
|
1201
1232
|
console.log(formatInitSummary(result));
|
|
@@ -1226,9 +1257,17 @@ async function runServer() {
|
|
|
1226
1257
|
process.on("SIGTERM", shutdown);
|
|
1227
1258
|
}
|
|
1228
1259
|
var cli = parseCliArgs();
|
|
1229
|
-
if (cli === "
|
|
1260
|
+
if (cli === "version") {
|
|
1261
|
+
console.log(package_default.version);
|
|
1262
|
+
process.exit(0);
|
|
1263
|
+
} else if (cli === "help") {
|
|
1230
1264
|
printHelp();
|
|
1231
1265
|
process.exit(0);
|
|
1266
|
+
} else if (cli === "update") {
|
|
1267
|
+
runUpdate().catch((err) => {
|
|
1268
|
+
console.error("Fatal:", err);
|
|
1269
|
+
process.exit(1);
|
|
1270
|
+
});
|
|
1232
1271
|
} else if (cli === "init") {
|
|
1233
1272
|
runInit().catch((err) => {
|
|
1234
1273
|
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.
|
|
4
|
+
"version": "0.10.0",
|
|
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",
|