persyst-mcp 2.1.3 → 2.2.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.
- package/bin/init.js +7 -0
- package/index.js +41 -0
- package/package.json +2 -2
- package/src/attestation.js +7 -1
- package/src/database.js +973 -877
- package/src/extractor-heuristic.js +324 -250
- package/src/git.js +7 -1
- package/src/search.js +597 -456
- package/src/server.js +72 -67
- package/src/tools.js +157 -20
- package/src/watcher.js +306 -0
package/bin/init.js
CHANGED
|
@@ -45,6 +45,13 @@ You are integrated with Persyst, a local-first MCP memory server that stores use
|
|
|
45
45
|
- Agentic Swarms & Namespaces: If you are part of a multi-agent swarm or need private partition, pass your agent name as \`agent_id\` and set \`shared: false\` to store private memories. For general project guidelines and files, leave \`shared: true\` (default) so other agents can access them.
|
|
46
46
|
- Handle Contradictions: Persyst handles contradiction detection automatically. If a new fact contradicts an old memory, Persyst will flag it.
|
|
47
47
|
- Quality Over Quantity: Do NOT store trivial facts, temporary conversation noise, or duplicate data. "Bad data is worse than no data". Only store long-term architecture decisions, project details, and explicit user preferences.
|
|
48
|
+
|
|
49
|
+
## Mandatory Completion Checklist (HARD CONSTRAINT)
|
|
50
|
+
Before writing your final response declaring a task, feature, or bug fix complete:
|
|
51
|
+
1. Ask yourself: "Did I implement a feature, fix a bug, configure a tool, or discover a project rule?"
|
|
52
|
+
2. If YES: Call the \`add_memory\` tool to store the milestone as your final tool call *before* writing your final message to the user.
|
|
53
|
+
3. If NO: You may proceed to conclude without saving.
|
|
54
|
+
Never rely on the user to remind you to save milestones.
|
|
48
55
|
`;
|
|
49
56
|
|
|
50
57
|
const GENERAL_GUIDE = `# Persyst General Agent Integration Guide
|
package/index.js
CHANGED
|
@@ -15,6 +15,47 @@
|
|
|
15
15
|
* persyst-mcp (if installed globally)
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
// If running inside Bun (like Qwen's internal runtime), spawn Node.js instead
|
|
19
|
+
if (process.versions.bun && !process.env.PERSYST_RUN_BY_NODE) {
|
|
20
|
+
const { spawn } = await import('child_process');
|
|
21
|
+
const child = spawn('C:\\Program Files\\nodejs\\node.exe', [
|
|
22
|
+
process.argv[1],
|
|
23
|
+
...process.argv.slice(2)
|
|
24
|
+
], {
|
|
25
|
+
stdio: 'inherit',
|
|
26
|
+
env: {
|
|
27
|
+
...process.env,
|
|
28
|
+
PERSYST_RUN_BY_NODE: 'true'
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
child.on('exit', (code) => {
|
|
32
|
+
process.exit(code ?? 0);
|
|
33
|
+
});
|
|
34
|
+
// Prevent further execution in Bun
|
|
35
|
+
await new Promise(() => {});
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Fix PATH on Windows if running in environments like Qwen Desktop that override PATH
|
|
39
|
+
if (process.platform === 'win32') {
|
|
40
|
+
const nodeBin = 'C:\\Program Files\\nodejs';
|
|
41
|
+
const gitBin = 'C:\\Program Files\\Git\\cmd';
|
|
42
|
+
const systemBin = 'C:\\WINDOWS\\system32;C:\\WINDOWS';
|
|
43
|
+
|
|
44
|
+
const currentPath = process.env.PATH || '';
|
|
45
|
+
const paths = currentPath.split(';');
|
|
46
|
+
|
|
47
|
+
if (!paths.includes(nodeBin)) paths.push(nodeBin);
|
|
48
|
+
if (!paths.includes(gitBin)) paths.push(gitBin);
|
|
49
|
+
|
|
50
|
+
// Make sure system folders are there
|
|
51
|
+
const sysPaths = systemBin.split(';');
|
|
52
|
+
sysPaths.forEach(p => {
|
|
53
|
+
if (!paths.includes(p)) paths.push(p);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
process.env.PATH = paths.join(';');
|
|
57
|
+
}
|
|
58
|
+
|
|
18
59
|
// Handle subcommands before starting the server
|
|
19
60
|
const subcommand = process.argv[2];
|
|
20
61
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "persyst-mcp",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Local-first MCP memory server with hybrid keyword + semantic search for coding agents",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "index.js",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
],
|
|
27
27
|
"scripts": {
|
|
28
28
|
"start": "node index.js",
|
|
29
|
-
"test": "node test/smoke.js",
|
|
29
|
+
"test": "cross-env NODE_ENV=test node test/smoke.js",
|
|
30
30
|
"test:heavy": "cross-env NODE_ENV=test node --test test/test_*.js",
|
|
31
31
|
"worker": "node bin/extract-worker.js",
|
|
32
32
|
"extract": "node bin/extract.js"
|
package/src/attestation.js
CHANGED
|
@@ -60,10 +60,16 @@ export function createAttestation(query, memories, agentId = null, sessionId = n
|
|
|
60
60
|
// Map memories to {id, content_hash, score}
|
|
61
61
|
const memoriesRetrieved = memories.map(m => {
|
|
62
62
|
const contentHash = crypto.createHash('sha256').update(m.content).digest('hex');
|
|
63
|
+
let scoreVal = 0;
|
|
64
|
+
if (m.hybrid_score !== undefined && m.hybrid_score !== null) {
|
|
65
|
+
scoreVal = m.hybrid_score;
|
|
66
|
+
} else if (m.score !== undefined && m.score !== null) {
|
|
67
|
+
scoreVal = m.score;
|
|
68
|
+
}
|
|
63
69
|
return {
|
|
64
70
|
id: m.id,
|
|
65
71
|
content_hash: contentHash,
|
|
66
|
-
score: parseFloat(
|
|
72
|
+
score: parseFloat(scoreVal)
|
|
67
73
|
};
|
|
68
74
|
});
|
|
69
75
|
|