@pcircle/memesh 2.11.0 → 3.0.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 +153 -52
- package/dist/cli/assets/d3.v7.min.js +2 -0
- package/dist/cli/view.d.ts +1 -0
- package/dist/cli/view.d.ts.map +1 -1
- package/dist/cli/view.js +2198 -10
- package/dist/cli/view.js.map +1 -1
- package/dist/core/config.d.ts +33 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +70 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/extractor.d.ts +26 -0
- package/dist/core/extractor.d.ts.map +1 -0
- package/dist/core/extractor.js +106 -0
- package/dist/core/extractor.js.map +1 -0
- package/dist/core/lifecycle.d.ts +9 -0
- package/dist/core/lifecycle.d.ts.map +1 -0
- package/dist/core/lifecycle.js +51 -0
- package/dist/core/lifecycle.js.map +1 -0
- package/dist/core/operations.d.ts +9 -0
- package/dist/core/operations.d.ts.map +1 -0
- package/dist/core/operations.js +342 -0
- package/dist/core/operations.js.map +1 -0
- package/dist/core/query-expander.d.ts +4 -0
- package/dist/core/query-expander.d.ts.map +1 -0
- package/dist/core/query-expander.js +114 -0
- package/dist/core/query-expander.js.map +1 -0
- package/dist/core/schema-export.d.ts +2 -0
- package/dist/core/schema-export.d.ts.map +1 -0
- package/dist/core/schema-export.js +67 -0
- package/dist/core/schema-export.js.map +1 -0
- package/dist/core/scoring.d.ts +25 -0
- package/dist/core/scoring.d.ts.map +1 -0
- package/dist/core/scoring.js +40 -0
- package/dist/core/scoring.js.map +1 -0
- package/dist/core/types.d.ts +124 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +2 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/version-check.d.ts +10 -0
- package/dist/core/version-check.d.ts.map +1 -0
- package/dist/core/version-check.js +44 -0
- package/dist/core/version-check.js.map +1 -0
- package/dist/db.d.ts.map +1 -1
- package/dist/db.js +33 -0
- package/dist/db.js.map +1 -1
- package/dist/knowledge-graph.d.ts +16 -30
- package/dist/knowledge-graph.d.ts.map +1 -1
- package/dist/knowledge-graph.js +205 -24
- package/dist/knowledge-graph.js.map +1 -1
- package/dist/mcp/server.js +8 -1
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +1 -92
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +1 -182
- package/dist/mcp/tools.js.map +1 -1
- package/dist/transports/cli/cli.d.ts +3 -0
- package/dist/transports/cli/cli.d.ts.map +1 -0
- package/dist/transports/cli/cli.js +378 -0
- package/dist/transports/cli/cli.js.map +1 -0
- package/dist/transports/http/server.d.ts +5 -0
- package/dist/transports/http/server.d.ts.map +1 -0
- package/dist/transports/http/server.js +314 -0
- package/dist/transports/http/server.js.map +1 -0
- package/dist/transports/mcp/handlers.d.ts +184 -0
- package/dist/transports/mcp/handlers.d.ts.map +1 -0
- package/dist/transports/mcp/handlers.js +271 -0
- package/dist/transports/mcp/handlers.js.map +1 -0
- package/hooks/hooks.json +24 -0
- package/package.json +27 -9
- package/plugin.json +4 -4
- package/scripts/hooks/post-commit.js +35 -6
- package/scripts/hooks/pre-compact.js +198 -0
- package/scripts/hooks/session-start.js +73 -25
- package/scripts/hooks/session-summary.js +255 -0
|
@@ -0,0 +1,271 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { remember, recallEnhanced, forget, consolidate, exportMemories, importMemories } from '../../core/operations.js';
|
|
3
|
+
import { KnowledgeGraph } from '../../knowledge-graph.js';
|
|
4
|
+
import { getDatabase } from '../../db.js';
|
|
5
|
+
const RememberSchema = z.object({
|
|
6
|
+
name: z.string().min(1),
|
|
7
|
+
type: z.string().min(1),
|
|
8
|
+
observations: z.array(z.string()).optional(),
|
|
9
|
+
tags: z.array(z.string()).optional(),
|
|
10
|
+
relations: z
|
|
11
|
+
.array(z.object({ to: z.string().min(1), type: z.string().min(1) }))
|
|
12
|
+
.optional(),
|
|
13
|
+
namespace: z.enum(['personal', 'team', 'global']).optional(),
|
|
14
|
+
});
|
|
15
|
+
const RecallSchema = z.object({
|
|
16
|
+
query: z.string().optional(),
|
|
17
|
+
tag: z.string().optional(),
|
|
18
|
+
limit: z.number().int().min(1).max(100).optional(),
|
|
19
|
+
include_archived: z.boolean().optional(),
|
|
20
|
+
namespace: z.enum(['personal', 'team', 'global']).optional(),
|
|
21
|
+
cross_project: z.boolean().optional(),
|
|
22
|
+
});
|
|
23
|
+
const ForgetSchema = z.object({
|
|
24
|
+
name: z.string().min(1),
|
|
25
|
+
observation: z.string().optional(),
|
|
26
|
+
});
|
|
27
|
+
const ConsolidateSchema = z.object({
|
|
28
|
+
name: z.string().optional(),
|
|
29
|
+
tag: z.string().optional(),
|
|
30
|
+
min_observations: z.number().int().min(1).optional(),
|
|
31
|
+
});
|
|
32
|
+
const ExportSchema = z.object({
|
|
33
|
+
tag: z.string().optional(),
|
|
34
|
+
namespace: z.string().optional(),
|
|
35
|
+
limit: z.number().int().min(1).max(10000).optional(),
|
|
36
|
+
});
|
|
37
|
+
const ExportResultSchema = z.object({
|
|
38
|
+
version: z.string(),
|
|
39
|
+
exported_at: z.string(),
|
|
40
|
+
entity_count: z.number(),
|
|
41
|
+
entities: z.array(z.object({
|
|
42
|
+
name: z.string().min(1).max(255),
|
|
43
|
+
type: z.string().min(1).max(100),
|
|
44
|
+
namespace: z.string(),
|
|
45
|
+
observations: z.array(z.string().max(10000)),
|
|
46
|
+
tags: z.array(z.string().max(255)),
|
|
47
|
+
relations: z.array(z.object({ to: z.string().min(1).max(255), type: z.string().min(1).max(100) })),
|
|
48
|
+
})),
|
|
49
|
+
});
|
|
50
|
+
const ImportSchema = z.object({
|
|
51
|
+
data: ExportResultSchema,
|
|
52
|
+
namespace: z.string().optional(),
|
|
53
|
+
merge_strategy: z.enum(['skip', 'overwrite', 'append']),
|
|
54
|
+
});
|
|
55
|
+
export const TOOL_DEFINITIONS = [
|
|
56
|
+
{
|
|
57
|
+
name: 'remember',
|
|
58
|
+
description: 'Store knowledge as an entity with observations, tags, and relations. Use this to remember decisions, patterns, lessons learned, and important context.',
|
|
59
|
+
inputSchema: {
|
|
60
|
+
type: 'object',
|
|
61
|
+
properties: {
|
|
62
|
+
name: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
description: 'Unique entity name (e.g., "auth-decision", "jwt-pattern"). Reusing a name appends observations and dedupes tags instead of replacing the entity.',
|
|
65
|
+
},
|
|
66
|
+
type: {
|
|
67
|
+
type: 'string',
|
|
68
|
+
description: 'Entity type (e.g., "decision", "pattern", "lesson", "commit")',
|
|
69
|
+
},
|
|
70
|
+
observations: {
|
|
71
|
+
type: 'array',
|
|
72
|
+
items: { type: 'string' },
|
|
73
|
+
description: 'Key facts or observations about this entity',
|
|
74
|
+
},
|
|
75
|
+
tags: {
|
|
76
|
+
type: 'array',
|
|
77
|
+
items: { type: 'string' },
|
|
78
|
+
description: 'Tags for filtering (e.g., "project:myapp", "type:decision")',
|
|
79
|
+
},
|
|
80
|
+
relations: {
|
|
81
|
+
type: 'array',
|
|
82
|
+
items: {
|
|
83
|
+
type: 'object',
|
|
84
|
+
properties: {
|
|
85
|
+
to: { type: 'string', description: 'Target entity name' },
|
|
86
|
+
type: {
|
|
87
|
+
type: 'string',
|
|
88
|
+
description: 'Relation type (e.g., "implements", "related-to")',
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
required: ['to', 'type'],
|
|
92
|
+
additionalProperties: false,
|
|
93
|
+
},
|
|
94
|
+
description: 'Relations to other entities',
|
|
95
|
+
},
|
|
96
|
+
namespace: {
|
|
97
|
+
type: 'string',
|
|
98
|
+
enum: ['personal', 'team', 'global'],
|
|
99
|
+
description: 'Namespace for organizing the entity (default: "personal")',
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
required: ['name', 'type'],
|
|
103
|
+
additionalProperties: false,
|
|
104
|
+
},
|
|
105
|
+
},
|
|
106
|
+
{
|
|
107
|
+
name: 'recall',
|
|
108
|
+
description: 'Search and retrieve stored knowledge. Uses full-text search with optional project tag filtering. Call with no query to list recent memories.',
|
|
109
|
+
inputSchema: {
|
|
110
|
+
type: 'object',
|
|
111
|
+
properties: {
|
|
112
|
+
query: {
|
|
113
|
+
type: 'string',
|
|
114
|
+
description: 'Search query (uses FTS5 full-text search). Leave empty to list recent.',
|
|
115
|
+
},
|
|
116
|
+
tag: {
|
|
117
|
+
type: 'string',
|
|
118
|
+
description: 'Filter by tag (e.g., "project:myapp")',
|
|
119
|
+
},
|
|
120
|
+
limit: {
|
|
121
|
+
type: 'number',
|
|
122
|
+
description: 'Max results (default: 20, max: 100)',
|
|
123
|
+
},
|
|
124
|
+
include_archived: {
|
|
125
|
+
type: 'boolean',
|
|
126
|
+
description: 'Include archived (forgotten) entities in results. Default: false.',
|
|
127
|
+
},
|
|
128
|
+
namespace: {
|
|
129
|
+
type: 'string',
|
|
130
|
+
enum: ['personal', 'team', 'global'],
|
|
131
|
+
description: 'Filter results by namespace. Omit to search all namespaces.',
|
|
132
|
+
},
|
|
133
|
+
cross_project: {
|
|
134
|
+
type: 'boolean',
|
|
135
|
+
description: 'Search across all project tags (ignores tag filter). Default: false.',
|
|
136
|
+
},
|
|
137
|
+
},
|
|
138
|
+
additionalProperties: false,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
{
|
|
142
|
+
name: 'forget',
|
|
143
|
+
description: 'Archive an entity (soft-delete) or remove a specific observation. Archived entities are hidden from recall but preserved in the database. To remove just one observation, pass the observation parameter.',
|
|
144
|
+
inputSchema: {
|
|
145
|
+
type: 'object',
|
|
146
|
+
properties: {
|
|
147
|
+
name: { type: 'string', description: 'Entity name to archive or modify' },
|
|
148
|
+
observation: {
|
|
149
|
+
type: 'string',
|
|
150
|
+
description: 'If provided, only this specific observation is removed (entity stays active). If omitted, the entire entity is archived.',
|
|
151
|
+
},
|
|
152
|
+
},
|
|
153
|
+
required: ['name'],
|
|
154
|
+
additionalProperties: false,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
{
|
|
158
|
+
name: 'consolidate',
|
|
159
|
+
description: 'Compress verbose entity observations using an LLM into 2–3 dense sentences that preserve all key facts. Requires Smart Mode (run: memesh setup). Original observations are replaced by the LLM summary.',
|
|
160
|
+
inputSchema: {
|
|
161
|
+
type: 'object',
|
|
162
|
+
properties: {
|
|
163
|
+
name: { type: 'string', description: 'Specific entity name to consolidate' },
|
|
164
|
+
tag: { type: 'string', description: 'Consolidate all entities with this tag' },
|
|
165
|
+
min_observations: {
|
|
166
|
+
type: 'number',
|
|
167
|
+
description: 'Minimum observations required to trigger consolidation (default: 5)',
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
additionalProperties: false,
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
{
|
|
174
|
+
name: 'export',
|
|
175
|
+
description: 'Export memories as JSON for sharing or backup. Returns a portable snapshot of entities and their observations, tags, and relations.',
|
|
176
|
+
inputSchema: {
|
|
177
|
+
type: 'object',
|
|
178
|
+
properties: {
|
|
179
|
+
tag: { type: 'string', description: 'Export only entities with this tag' },
|
|
180
|
+
namespace: { type: 'string', description: 'Export only from this namespace (personal, team, global)' },
|
|
181
|
+
limit: { type: 'number', description: 'Max entities to export (default: 1000)' },
|
|
182
|
+
},
|
|
183
|
+
additionalProperties: false,
|
|
184
|
+
},
|
|
185
|
+
},
|
|
186
|
+
{
|
|
187
|
+
name: 'import',
|
|
188
|
+
description: 'Import memories from a JSON export snapshot. Supports skip, append, or overwrite strategies for handling existing entities.',
|
|
189
|
+
inputSchema: {
|
|
190
|
+
type: 'object',
|
|
191
|
+
properties: {
|
|
192
|
+
data: { type: 'object', description: 'Export JSON data (from the export tool)' },
|
|
193
|
+
namespace: { type: 'string', description: 'Override namespace for all imported entities' },
|
|
194
|
+
merge_strategy: {
|
|
195
|
+
type: 'string',
|
|
196
|
+
enum: ['skip', 'overwrite', 'append'],
|
|
197
|
+
description: 'How to handle existing entities: skip (default) = leave untouched, append = add observations, overwrite = archive existing and recreate',
|
|
198
|
+
},
|
|
199
|
+
},
|
|
200
|
+
required: ['data', 'merge_strategy'],
|
|
201
|
+
additionalProperties: false,
|
|
202
|
+
},
|
|
203
|
+
},
|
|
204
|
+
];
|
|
205
|
+
function ok(data) {
|
|
206
|
+
return { content: [{ type: 'text', text: JSON.stringify(data) }] };
|
|
207
|
+
}
|
|
208
|
+
function fail(message) {
|
|
209
|
+
return { content: [{ type: 'text', text: message }], isError: true };
|
|
210
|
+
}
|
|
211
|
+
function parseOrFail(schema, args) {
|
|
212
|
+
const parsed = schema.safeParse(args ?? {});
|
|
213
|
+
if (!parsed.success) {
|
|
214
|
+
const message = parsed.error instanceof z.ZodError
|
|
215
|
+
? parsed.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join('; ')
|
|
216
|
+
: String(parsed.error);
|
|
217
|
+
return { ok: false, result: fail(message) };
|
|
218
|
+
}
|
|
219
|
+
return { ok: true, data: parsed.data };
|
|
220
|
+
}
|
|
221
|
+
export async function handleTool(name, args) {
|
|
222
|
+
try {
|
|
223
|
+
if (name === 'remember') {
|
|
224
|
+
const r = parseOrFail(RememberSchema, args);
|
|
225
|
+
if (!r.ok)
|
|
226
|
+
return r.result;
|
|
227
|
+
return ok(remember(r.data));
|
|
228
|
+
}
|
|
229
|
+
if (name === 'recall') {
|
|
230
|
+
const r = parseOrFail(RecallSchema, args);
|
|
231
|
+
if (!r.ok)
|
|
232
|
+
return r.result;
|
|
233
|
+
const entities = await recallEnhanced(r.data);
|
|
234
|
+
const kg = new KnowledgeGraph(getDatabase());
|
|
235
|
+
const conflicts = kg.findConflicts(entities.map(e => e.name));
|
|
236
|
+
if (conflicts.length > 0) {
|
|
237
|
+
return ok({ entities, conflicts });
|
|
238
|
+
}
|
|
239
|
+
return ok(entities);
|
|
240
|
+
}
|
|
241
|
+
if (name === 'forget') {
|
|
242
|
+
const r = parseOrFail(ForgetSchema, args);
|
|
243
|
+
if (!r.ok)
|
|
244
|
+
return r.result;
|
|
245
|
+
return ok(forget(r.data));
|
|
246
|
+
}
|
|
247
|
+
if (name === 'consolidate') {
|
|
248
|
+
const r = parseOrFail(ConsolidateSchema, args);
|
|
249
|
+
if (!r.ok)
|
|
250
|
+
return r.result;
|
|
251
|
+
return ok(await consolidate(r.data));
|
|
252
|
+
}
|
|
253
|
+
if (name === 'export') {
|
|
254
|
+
const r = parseOrFail(ExportSchema, args);
|
|
255
|
+
if (!r.ok)
|
|
256
|
+
return r.result;
|
|
257
|
+
return ok(exportMemories(r.data));
|
|
258
|
+
}
|
|
259
|
+
if (name === 'import') {
|
|
260
|
+
const r = parseOrFail(ImportSchema, args);
|
|
261
|
+
if (!r.ok)
|
|
262
|
+
return r.result;
|
|
263
|
+
return ok(importMemories(r.data));
|
|
264
|
+
}
|
|
265
|
+
return fail(`Unknown tool: ${name}`);
|
|
266
|
+
}
|
|
267
|
+
catch (err) {
|
|
268
|
+
return fail(`Tool "${name}" failed: ${err.message}`);
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
//# sourceMappingURL=handlers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handlers.js","sourceRoot":"","sources":["../../../src/transports/mcp/handlers.ts"],"names":[],"mappings":"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"}
|
package/hooks/hooks.json
CHANGED
|
@@ -21,6 +21,30 @@
|
|
|
21
21
|
}
|
|
22
22
|
]
|
|
23
23
|
}
|
|
24
|
+
],
|
|
25
|
+
"Stop": [
|
|
26
|
+
{
|
|
27
|
+
"matcher": "*",
|
|
28
|
+
"hooks": [
|
|
29
|
+
{
|
|
30
|
+
"type": "command",
|
|
31
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/session-summary.js",
|
|
32
|
+
"timeout": 10
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
],
|
|
37
|
+
"PreCompact": [
|
|
38
|
+
{
|
|
39
|
+
"matcher": "*",
|
|
40
|
+
"hooks": [
|
|
41
|
+
{
|
|
42
|
+
"type": "command",
|
|
43
|
+
"command": "${CLAUDE_PLUGIN_ROOT}/scripts/hooks/pre-compact.js",
|
|
44
|
+
"timeout": 10
|
|
45
|
+
}
|
|
46
|
+
]
|
|
47
|
+
}
|
|
24
48
|
]
|
|
25
49
|
}
|
|
26
50
|
}
|
package/package.json
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pcircle/memesh",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "MeMesh —
|
|
3
|
+
"version": "3.0.0",
|
|
4
|
+
"description": "MeMesh — The lightest universal AI memory layer. One SQLite file, any LLM, zero cloud.",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
8
|
-
"memesh": "dist/
|
|
8
|
+
"memesh": "dist/transports/cli/cli.js",
|
|
9
|
+
"memesh-mcp": "dist/mcp/server.js",
|
|
10
|
+
"memesh-http": "dist/transports/http/server.js",
|
|
9
11
|
"memesh-view": "dist/cli/view.js"
|
|
10
12
|
},
|
|
11
13
|
"files": [
|
|
@@ -18,25 +20,41 @@
|
|
|
18
20
|
"LICENSE"
|
|
19
21
|
],
|
|
20
22
|
"scripts": {
|
|
21
|
-
"build": "tsc &&
|
|
23
|
+
"build": "tsc && node scripts/copy-cli-assets.mjs && node scripts/set-executable-bits.mjs",
|
|
22
24
|
"test": "vitest",
|
|
25
|
+
"test:packaged": "node scripts/smoke-packed-artifact.mjs",
|
|
23
26
|
"typecheck": "tsc --noEmit",
|
|
24
27
|
"start": "node dist/mcp/server.js"
|
|
25
28
|
},
|
|
26
29
|
"author": "PCIRCLE-AI",
|
|
27
30
|
"license": "MIT",
|
|
28
|
-
"homepage": "https://github.com/PCIRCLE-AI/
|
|
31
|
+
"homepage": "https://github.com/PCIRCLE-AI/memesh-llm-memory",
|
|
32
|
+
"bugs": {
|
|
33
|
+
"url": "https://github.com/PCIRCLE-AI/memesh-llm-memory/issues"
|
|
34
|
+
},
|
|
35
|
+
"keywords": [
|
|
36
|
+
"claude-code",
|
|
37
|
+
"mcp",
|
|
38
|
+
"model-context-protocol",
|
|
39
|
+
"memory",
|
|
40
|
+
"sqlite",
|
|
41
|
+
"knowledge-graph"
|
|
42
|
+
],
|
|
29
43
|
"repository": {
|
|
30
44
|
"type": "git",
|
|
31
|
-
"url": "git+https://github.com/PCIRCLE-AI/
|
|
45
|
+
"url": "git+https://github.com/PCIRCLE-AI/memesh-llm-memory.git"
|
|
32
46
|
},
|
|
33
47
|
"dependencies": {
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
48
|
+
"@modelcontextprotocol/sdk": "^1.29.0",
|
|
49
|
+
"better-sqlite3": "^12.9.0",
|
|
50
|
+
"commander": "^14.0.3",
|
|
51
|
+
"express": "^5.2.1",
|
|
52
|
+
"sqlite-vec": "^0.1.9",
|
|
53
|
+
"zod": "^4.3.6"
|
|
37
54
|
},
|
|
38
55
|
"devDependencies": {
|
|
39
56
|
"@types/better-sqlite3": "^7.6.13",
|
|
57
|
+
"@types/express": "^5.0.6",
|
|
40
58
|
"@types/node": "^25.0.9",
|
|
41
59
|
"typescript": "^5.9.3",
|
|
42
60
|
"vitest": "^4.0.17"
|
package/plugin.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "memesh",
|
|
3
|
-
"description": "MeMesh —
|
|
3
|
+
"description": "MeMesh — The lightest universal AI memory layer. One SQLite file, any LLM, zero cloud.",
|
|
4
4
|
"author": { "name": "PCIRCLE AI" },
|
|
5
|
-
"version": "
|
|
6
|
-
"homepage": "https://github.com/PCIRCLE-AI/
|
|
7
|
-
"repository": "https://github.com/PCIRCLE-AI/
|
|
5
|
+
"version": "3.0.0",
|
|
6
|
+
"homepage": "https://github.com/PCIRCLE-AI/memesh-llm-memory",
|
|
7
|
+
"repository": "https://github.com/PCIRCLE-AI/memesh-llm-memory",
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"keywords": ["claude-code", "mcp", "knowledge-graph", "ai-memory"],
|
|
10
10
|
"mcpServers": "./.mcp.json",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
import { createRequire } from 'module';
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
4
5
|
import { homedir } from 'os';
|
|
5
6
|
import { join, basename } from 'path';
|
|
6
7
|
import { existsSync, mkdirSync } from 'fs';
|
|
@@ -45,6 +46,13 @@ CREATE TABLE IF NOT EXISTS tags (
|
|
|
45
46
|
|
|
46
47
|
CREATE INDEX IF NOT EXISTS idx_tags_entity ON tags(entity_id);
|
|
47
48
|
CREATE INDEX IF NOT EXISTS idx_tags_tag ON tags(tag);
|
|
49
|
+
DELETE FROM tags
|
|
50
|
+
WHERE id NOT IN (
|
|
51
|
+
SELECT MIN(id)
|
|
52
|
+
FROM tags
|
|
53
|
+
GROUP BY entity_id, tag
|
|
54
|
+
);
|
|
55
|
+
CREATE UNIQUE INDEX IF NOT EXISTS idx_tags_entity_tag_unique ON tags(entity_id, tag);
|
|
48
56
|
CREATE INDEX IF NOT EXISTS idx_observations_entity ON observations(entity_id);
|
|
49
57
|
CREATE INDEX IF NOT EXISTS idx_relations_from ON relations(from_entity_id);
|
|
50
58
|
CREATE INDEX IF NOT EXISTS idx_relations_to ON relations(to_entity_id);
|
|
@@ -73,6 +81,9 @@ process.stdin.on('end', () => {
|
|
|
73
81
|
const commitMatch = toolOutput.match(/\[[\w/.-]+ ([a-f0-9]{7,})\] (.+)/);
|
|
74
82
|
if (!commitMatch) return exit0();
|
|
75
83
|
|
|
84
|
+
const branchMatch = commitMatch[0].match(/^\[([^\s]+)\s/);
|
|
85
|
+
const branch = branchMatch ? branchMatch[1] : 'unknown';
|
|
86
|
+
|
|
76
87
|
const commitHash = commitMatch[1];
|
|
77
88
|
const commitMsg = commitMatch[2];
|
|
78
89
|
const projectName = basename(data.cwd || process.cwd());
|
|
@@ -106,15 +117,32 @@ process.stdin.on('end', () => {
|
|
|
106
117
|
: db.prepare('SELECT content FROM observations WHERE entity_id = ?').all(entity.id);
|
|
107
118
|
const prevObsText = isNew ? undefined : prevObs.map(o => o.content).join(' ');
|
|
108
119
|
|
|
109
|
-
// Add
|
|
120
|
+
// Add observations
|
|
110
121
|
db.prepare('INSERT INTO observations (entity_id, content) VALUES (?, ?)').run(entity.id, commitMsg);
|
|
122
|
+
db.prepare('INSERT INTO observations (entity_id, content) VALUES (?, ?)').run(entity.id, `Branch: ${branch}`);
|
|
123
|
+
|
|
124
|
+
// Add richer diff stats as an observation (backward compatible — failures are silently ignored)
|
|
125
|
+
try {
|
|
126
|
+
const stat = execFileSync('git', ['show', '--stat', '--format=', commitHash], {
|
|
127
|
+
cwd: data.cwd || process.cwd(),
|
|
128
|
+
encoding: 'utf8',
|
|
129
|
+
timeout: 5000,
|
|
130
|
+
}).trim();
|
|
131
|
+
if (stat) {
|
|
132
|
+
// Last non-empty line is the summary, e.g. "3 files changed, 45 insertions(+), 12 deletions(-)"
|
|
133
|
+
const statLines = stat.split('\n').filter(l => l.trim());
|
|
134
|
+
const summary = statLines[statLines.length - 1]?.trim() || '';
|
|
135
|
+
if (summary) {
|
|
136
|
+
db.prepare('INSERT INTO observations (entity_id, content) VALUES (?, ?)').run(entity.id, `Diff stats: ${summary}`);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
} catch {
|
|
140
|
+
// git show failed — no diff stats recorded, existing behavior unchanged
|
|
141
|
+
}
|
|
111
142
|
|
|
112
|
-
// Add project tag
|
|
143
|
+
// Add project tag
|
|
113
144
|
const projectTag = `project:${projectName}`;
|
|
114
|
-
|
|
115
|
-
if (!existingTag) {
|
|
116
|
-
db.prepare('INSERT INTO tags (entity_id, tag) VALUES (?, ?)').run(entity.id, projectTag);
|
|
117
|
-
}
|
|
145
|
+
db.prepare('INSERT OR IGNORE INTO tags (entity_id, tag) VALUES (?, ?)').run(entity.id, projectTag);
|
|
118
146
|
|
|
119
147
|
// Update FTS index — delete old entry first if entity existed
|
|
120
148
|
if (prevObsText !== undefined) {
|
|
@@ -132,6 +160,7 @@ process.stdin.on('end', () => {
|
|
|
132
160
|
// Never crash Claude Code — but leave a trace for debugging
|
|
133
161
|
try { process.stderr.write(`[memesh post-commit] ${err?.message || err}\n`); } catch {}
|
|
134
162
|
}
|
|
163
|
+
console.log(JSON.stringify({ suppressOutput: true }));
|
|
135
164
|
exit0();
|
|
136
165
|
});
|
|
137
166
|
|