monomind 2.5.4 → 2.5.6
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 +10 -3
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/topology.md +121 -0
- package/packages/@monomind/cli/.claude/commands/mastermind.md +121 -102
- package/packages/@monomind/cli/.claude/helpers/control-start.cjs +22 -2
- package/packages/@monomind/cli/.claude/helpers/control-stop.cjs +95 -0
- package/packages/@monomind/cli/.claude/helpers/graphify-freshen.cjs +6 -0
- package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +13 -5
- package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +33 -10
- package/packages/@monomind/cli/.claude/helpers/utils/system-pressure.cjs +46 -0
- package/packages/@monomind/cli/.claude/settings.json +448 -0
- package/packages/@monomind/cli/README.md +10 -3
- package/packages/@monomind/cli/bin/cli.js +16 -6
- package/packages/@monomind/cli/bin/mcp-server.js +17 -8
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/cleanup.js +53 -1
- package/packages/@monomind/cli/dist/src/commands/config.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/index.js +4 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +3 -3
- package/packages/@monomind/cli/dist/src/commands/init.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/mcp.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +8 -7
- package/packages/@monomind/cli/dist/src/commands/memory-list.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/memory.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/memory.js +4 -4
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/performance.js +8 -9
- package/packages/@monomind/cli/dist/src/commands/status.js +2 -2
- package/packages/@monomind/cli/dist/src/commands/swarm.js +1 -1
- package/packages/@monomind/cli/dist/src/index.js +1 -1
- package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +2 -2
- package/packages/@monomind/cli/dist/src/init/executor.js +13 -6
- package/packages/@monomind/cli/dist/src/init/helpers-generator.js +66 -3
- package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/init/shared-instructions-generator.js +1 -1
- package/packages/@monomind/cli/dist/src/init/statusline-generator.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +2 -2
- package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/knowledge/document-pipeline.js +3 -3
- package/packages/@monomind/cli/dist/src/mcp-client.d.ts +13 -51
- package/packages/@monomind/cli/dist/src/mcp-client.js +79 -134
- package/packages/@monomind/cli/dist/src/mcp-server.js +4 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +45 -19
- package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +1 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/hooks-intelligence.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/knowledge-tools.js +1 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +2 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +22 -9
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +3 -3
- package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +1 -1
- package/packages/@monomind/cli/dist/src/memory/embedding-operations.js +2 -2
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +53 -26
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +2 -2
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +7 -3
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +24 -10
- package/packages/@monomind/cli/dist/src/memory/memory-crud.js +2 -2
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +6 -6
- package/packages/@monomind/cli/dist/src/memory/memory-read.js +4 -4
- package/packages/@monomind/cli/dist/src/orgrt/daemon.js +12 -6
- package/packages/@monomind/cli/dist/src/orgrt/mailbox.d.ts +1 -0
- package/packages/@monomind/cli/dist/src/orgrt/mailbox.js +4 -0
- package/packages/@monomind/cli/dist/src/orgrt/policy.js +1 -1
- package/packages/@monomind/cli/dist/src/orgrt/server.js +25 -0
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +327 -611
- package/packages/@monomind/cli/dist/src/ui/server.mjs +165 -22
- package/packages/@monomind/cli/package.json +1 -1
- package/scripts/growth-content-calendar.mjs +140 -0
|
@@ -41,22 +41,31 @@ process.stdin.on('data', async (chunk) => {
|
|
|
41
41
|
|
|
42
42
|
for (const line of lines) {
|
|
43
43
|
if (line.trim()) {
|
|
44
|
+
let parsed;
|
|
44
45
|
try {
|
|
45
|
-
|
|
46
|
-
|
|
46
|
+
parsed = JSON.parse(line);
|
|
47
|
+
} catch {
|
|
48
|
+
console.log(JSON.stringify({
|
|
49
|
+
jsonrpc: '2.0',
|
|
50
|
+
id: null,
|
|
51
|
+
error: { code: -32700, message: 'Parse error' },
|
|
52
|
+
}));
|
|
53
|
+
continue;
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const response = await handleMessage(parsed);
|
|
47
57
|
if (response) {
|
|
48
58
|
console.log(JSON.stringify(response));
|
|
49
59
|
}
|
|
50
60
|
} catch (error) {
|
|
51
61
|
console.error(
|
|
52
|
-
`[${new Date().toISOString()}] ERROR [monomind-mcp]
|
|
62
|
+
`[${new Date().toISOString()}] ERROR [monomind-mcp] handler error:`,
|
|
53
63
|
error instanceof Error ? error.message : String(error)
|
|
54
64
|
);
|
|
55
|
-
// Send parse error response
|
|
56
65
|
console.log(JSON.stringify({
|
|
57
66
|
jsonrpc: '2.0',
|
|
58
|
-
id: null,
|
|
59
|
-
error: { code: -
|
|
67
|
+
id: parsed.id ?? null,
|
|
68
|
+
error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error' },
|
|
60
69
|
}));
|
|
61
70
|
}
|
|
62
71
|
}
|
|
@@ -122,7 +131,7 @@ async function handleMessage(message) {
|
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
case 'tools/list': {
|
|
125
|
-
const tools = listMCPTools();
|
|
134
|
+
const tools = await listMCPTools();
|
|
126
135
|
return {
|
|
127
136
|
jsonrpc: '2.0',
|
|
128
137
|
id: message.id,
|
|
@@ -140,7 +149,7 @@ async function handleMessage(message) {
|
|
|
140
149
|
const toolName = params.name;
|
|
141
150
|
const toolParams = params.arguments || {};
|
|
142
151
|
|
|
143
|
-
if (!hasTool(toolName)) {
|
|
152
|
+
if (!await hasTool(toolName)) {
|
|
144
153
|
return {
|
|
145
154
|
jsonrpc: '2.0',
|
|
146
155
|
id: message.id,
|
|
@@ -44,7 +44,7 @@ export const AGENT_TYPES = [
|
|
|
44
44
|
{ value: 'optimizer', label: 'Optimizer', hint: 'Performance optimization and bottleneck analysis' },
|
|
45
45
|
{ value: 'security-architect', label: 'Security Architect', hint: 'Security architecture and threat modeling' },
|
|
46
46
|
{ value: 'security-auditor', label: 'Security Auditor', hint: 'CVE remediation and security testing' },
|
|
47
|
-
{ value: 'memory-specialist', label: 'Memory Specialist', hint: '
|
|
47
|
+
{ value: 'memory-specialist', label: 'Memory Specialist', hint: 'SQLite-backed ANN search (150x-12,500x faster)' },
|
|
48
48
|
{ value: 'swarm-specialist', label: 'Swarm Specialist', hint: 'Unified coordination engine' },
|
|
49
49
|
{ value: 'performance-engineer', label: 'Performance Engineer', hint: '2.49x-7.47x optimization targets' },
|
|
50
50
|
{ value: 'core-architect', label: 'Core Architect', hint: 'Domain-driven design restructure' },
|
|
@@ -58,7 +58,7 @@ export const metricsCommand = {
|
|
|
58
58
|
note: totalAgents === 0 ? 'No agents spawned yet. Use: agent spawn -t coder' : undefined,
|
|
59
59
|
},
|
|
60
60
|
byType,
|
|
61
|
-
performance: { memoryEntries: `${vectorCount} entries`, searchBackend: vectorCount > 0 ? '
|
|
61
|
+
performance: { memoryEntries: `${vectorCount} entries`, searchBackend: vectorCount > 0 ? 'SQLite' : 'none' },
|
|
62
62
|
};
|
|
63
63
|
if (ctx.flags.format === 'json') {
|
|
64
64
|
output.printJson(metrics);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* github.com/monoes/monomind
|
|
6
6
|
*/
|
|
7
7
|
import { output } from '../output.js';
|
|
8
|
-
import { existsSync, lstatSync, rmSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'fs';
|
|
8
|
+
import { existsSync, lstatSync, rmSync, readdirSync, readFileSync, writeFileSync, mkdirSync, unlinkSync, statSync } from 'fs';
|
|
9
9
|
import { join, dirname } from 'path';
|
|
10
10
|
/**
|
|
11
11
|
* Artifact directories and files that monomind/monomind may create
|
|
@@ -374,6 +374,58 @@ export const cleanupCommand = {
|
|
|
374
374
|
output.writeln();
|
|
375
375
|
return { success: true, message: `Removed ${removed} stale scratch file(s)`, data: { found: stale, removedCount: removed, removedSize, dryRun } };
|
|
376
376
|
}
|
|
377
|
+
// Kill background processes before removing their state files
|
|
378
|
+
if (force) {
|
|
379
|
+
// Guard against a stale PID file outliving its process and the OS
|
|
380
|
+
// recycling that PID for an unrelated process — verify the live
|
|
381
|
+
// process actually looks like ours before signaling it.
|
|
382
|
+
const looksLikeOurProcess = (pid) => {
|
|
383
|
+
try {
|
|
384
|
+
const { execSync } = require('child_process');
|
|
385
|
+
const cmd = execSync(`ps -p ${pid} -o command=`, { timeout: 2000, encoding: 'utf-8' }).trim();
|
|
386
|
+
// Covers direct `node ...` spawns as well as the npx fallback in
|
|
387
|
+
// control-start.cjs's findCliPath(), which shows up in `ps` as
|
|
388
|
+
// "npm exec ..." / "npx ..." with no literal "node".
|
|
389
|
+
const looksLikeNode = cmd.includes('node') || cmd.includes('npx') || cmd.includes('npm exec');
|
|
390
|
+
return looksLikeNode && (cmd.includes('monomind') || cmd.includes(cwd));
|
|
391
|
+
}
|
|
392
|
+
catch {
|
|
393
|
+
return false;
|
|
394
|
+
}
|
|
395
|
+
};
|
|
396
|
+
const controlPath = join(cwd, '.monomind', 'control.json');
|
|
397
|
+
try {
|
|
398
|
+
if (existsSync(controlPath) && statSync(controlPath).size <= 4096) {
|
|
399
|
+
const status = JSON.parse(readFileSync(controlPath, 'utf-8'));
|
|
400
|
+
if (status?.pid && Number.isInteger(status.pid) && status.pid > 0 && looksLikeOurProcess(status.pid)) {
|
|
401
|
+
process.kill(status.pid, 'SIGTERM');
|
|
402
|
+
output.writeln(output.info(` Stopped dashboard server (pid ${status.pid})`));
|
|
403
|
+
}
|
|
404
|
+
try {
|
|
405
|
+
unlinkSync(controlPath);
|
|
406
|
+
}
|
|
407
|
+
catch { }
|
|
408
|
+
}
|
|
409
|
+
}
|
|
410
|
+
catch { /* already gone */ }
|
|
411
|
+
for (const pidName of ['monograph.watch.pid', 'monograph-watch.pid']) {
|
|
412
|
+
try {
|
|
413
|
+
const pp = join(cwd, '.monomind', pidName);
|
|
414
|
+
if (!existsSync(pp) || statSync(pp).size > 32)
|
|
415
|
+
continue;
|
|
416
|
+
const pid = parseInt(readFileSync(pp, 'utf-8').trim(), 10);
|
|
417
|
+
if (Number.isInteger(pid) && pid > 0 && looksLikeOurProcess(pid)) {
|
|
418
|
+
process.kill(pid, 'SIGTERM');
|
|
419
|
+
output.writeln(output.info(` Stopped monograph watcher (pid ${pid})`));
|
|
420
|
+
}
|
|
421
|
+
try {
|
|
422
|
+
unlinkSync(pp);
|
|
423
|
+
}
|
|
424
|
+
catch { }
|
|
425
|
+
}
|
|
426
|
+
catch { /* already gone */ }
|
|
427
|
+
}
|
|
428
|
+
}
|
|
377
429
|
output.writeln();
|
|
378
430
|
output.writeln(output.bold(dryRun
|
|
379
431
|
? 'Monomind Cleanup (dry run)'
|
|
@@ -140,7 +140,7 @@ const setCommand = {
|
|
|
140
140
|
],
|
|
141
141
|
examples: [
|
|
142
142
|
{ command: 'monomind config set swarm.maxAgents 20', description: 'Set max agents' },
|
|
143
|
-
{ command: 'monomind config set -k memory.backend -v
|
|
143
|
+
{ command: 'monomind config set -k memory.backend -v sqlite', description: 'Set memory backend' }
|
|
144
144
|
],
|
|
145
145
|
action: async (ctx) => {
|
|
146
146
|
const key = (ctx.flags.key || ctx.args[0] || '').slice(0, 256);
|
|
@@ -400,7 +400,7 @@ export const statuslineCommand = {
|
|
|
400
400
|
const mcpColor = mcpStats.enabled > 0 ? c.brightGreen : c.dim;
|
|
401
401
|
const sizeDisplay = memoryStats.dbSizeKB >= 1024 ? `${(memoryStats.dbSizeKB / 1024).toFixed(1)}MB` : `${memoryStats.dbSizeKB}KB`;
|
|
402
402
|
const hnswIndicator = memoryStats.hasHnsw ? `${c.brightGreen}⚡${c.reset}` : '';
|
|
403
|
-
const line4 = `${c.brightCyan}📊
|
|
403
|
+
const line4 = `${c.brightCyan}📊 SQLite${c.reset} ` +
|
|
404
404
|
`${c.cyan}Vectors${c.reset} ${vectorColor}●~${memoryStats.vectorCount}${hnswIndicator}${c.reset} ${c.dim}│${c.reset} ` +
|
|
405
405
|
`${c.cyan}Size${c.reset} ${c.brightWhite}${sizeDisplay}${c.reset} ${c.dim}│${c.reset} ` +
|
|
406
406
|
`${c.cyan}Tests${c.reset} ${testColor}●${testStats.testFiles}${c.reset} ${c.dim}(~${testStats.testCases} est.)${c.reset} ${c.dim}│${c.reset} ` +
|
|
@@ -486,7 +486,7 @@ export const hooksCommand = {
|
|
|
486
486
|
output.printList([
|
|
487
487
|
'🧠 Trajectory + outcome logging',
|
|
488
488
|
'🎯 Keyword routing + route-outcome measurement',
|
|
489
|
-
'🔍
|
|
489
|
+
'🔍 SQLite-backed vector search (ANN)',
|
|
490
490
|
'🎯 32.3% token reduction',
|
|
491
491
|
'👥 Agent Teams integration (auto task assignment)'
|
|
492
492
|
]);
|
|
@@ -144,6 +144,7 @@ export const commandsByCategory = {
|
|
|
144
144
|
statusCommand,
|
|
145
145
|
agentCommand,
|
|
146
146
|
swarmCommand,
|
|
147
|
+
orgCommand,
|
|
147
148
|
memoryCommand,
|
|
148
149
|
docCommand,
|
|
149
150
|
taskCommand,
|
|
@@ -156,11 +157,14 @@ export const commandsByCategory = {
|
|
|
156
157
|
performanceCommand,
|
|
157
158
|
guidanceCommand,
|
|
158
159
|
autopilotCommand,
|
|
160
|
+
designCommand,
|
|
159
161
|
],
|
|
160
162
|
utility: [
|
|
161
163
|
configCommand,
|
|
162
164
|
doctorCommand,
|
|
163
165
|
completionsCommand,
|
|
166
|
+
reportCrashCommand,
|
|
167
|
+
crashReportingCommand,
|
|
164
168
|
],
|
|
165
169
|
analysis: [
|
|
166
170
|
analyzeCommand,
|
|
@@ -60,7 +60,7 @@ export const wizardCommand = {
|
|
|
60
60
|
message: 'Select skill sets:',
|
|
61
61
|
options: [
|
|
62
62
|
{ value: 'core', label: 'Core', hint: 'Swarm, memory skills', selected: true },
|
|
63
|
-
{ value: 'memory', label: 'Memory (
|
|
63
|
+
{ value: 'memory', label: 'Memory (SQLite)', hint: 'Vector database skills', selected: true },
|
|
64
64
|
{ value: 'github', label: 'GitHub', hint: 'GitHub integration skills', selected: true },
|
|
65
65
|
],
|
|
66
66
|
});
|
|
@@ -111,8 +111,8 @@ export const wizardCommand = {
|
|
|
111
111
|
const memoryBackend = await select({
|
|
112
112
|
message: 'Select memory backend:',
|
|
113
113
|
options: [
|
|
114
|
-
{ value: 'hybrid', label: 'Hybrid', hint: 'SQLite
|
|
115
|
-
{ value: 'lancedb', label: 'LanceDB', hint: '
|
|
114
|
+
{ value: 'hybrid', label: 'Hybrid', hint: 'SQLite with vector search (recommended)' },
|
|
115
|
+
{ value: 'lancedb', label: 'LanceDB (legacy alias)', hint: 'Historical name — now backed by SQLite' },
|
|
116
116
|
{ value: 'sqlite', label: 'SQLite', hint: 'Standard SQL storage' },
|
|
117
117
|
{ value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' },
|
|
118
118
|
],
|
|
@@ -94,7 +94,7 @@ const initAction = async (ctx) => {
|
|
|
94
94
|
if (!noWatch) {
|
|
95
95
|
try {
|
|
96
96
|
const { spawn } = await import('child_process');
|
|
97
|
-
const pidFile = path.join(ctx.cwd, '.monomind', 'monograph
|
|
97
|
+
const pidFile = path.join(ctx.cwd, '.monomind', 'monograph.watch.pid');
|
|
98
98
|
let alreadyRunning = false;
|
|
99
99
|
if (fs.existsSync(pidFile) && fs.statSync(pidFile).size <= 32) {
|
|
100
100
|
const existingPid = parseInt(fs.readFileSync(pidFile, 'utf8').trim(), 10);
|
|
@@ -107,7 +107,7 @@ const initAction = async (ctx) => {
|
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
109
|
if (!alreadyRunning) {
|
|
110
|
-
const logPath = path.join(ctx.cwd, '.monomind', 'monograph
|
|
110
|
+
const logPath = path.join(ctx.cwd, '.monomind', 'monograph.watch.log');
|
|
111
111
|
const { openSync } = fs;
|
|
112
112
|
const logFd = openSync(logPath, 'a');
|
|
113
113
|
const proc = spawn(process.execPath, [process.argv[1], 'monograph', 'watch'], {
|
|
@@ -364,7 +364,7 @@ const toolsCommand = {
|
|
|
364
364
|
// Use local tool registry
|
|
365
365
|
let tools;
|
|
366
366
|
// Get tools from local registry
|
|
367
|
-
const registeredTools = listMCPTools(category);
|
|
367
|
+
const registeredTools = await listMCPTools(category);
|
|
368
368
|
if (registeredTools.length > 0) {
|
|
369
369
|
tools = registeredTools.map(tool => ({
|
|
370
370
|
name: tool.name,
|
|
@@ -542,7 +542,7 @@ const execCommand = {
|
|
|
542
542
|
}
|
|
543
543
|
try {
|
|
544
544
|
// Execute through local MCP tool registry
|
|
545
|
-
if (!hasTool(tool)) {
|
|
545
|
+
if (!await hasTool(tool)) {
|
|
546
546
|
output.printError(`Tool not found: ${tool}`);
|
|
547
547
|
return { success: false, exitCode: 1 };
|
|
548
548
|
}
|
|
@@ -7,16 +7,16 @@ import { select, confirm } from '../prompt.js';
|
|
|
7
7
|
import { configManager } from '../services/config-file-manager.js';
|
|
8
8
|
// Memory backends (needed for configureCommand)
|
|
9
9
|
const BACKENDS = [
|
|
10
|
-
{ value: 'lancedb', label: 'LanceDB', hint: '
|
|
10
|
+
{ value: 'lancedb', label: 'LanceDB (legacy alias)', hint: 'Historical name — now backed by SQLite' },
|
|
11
11
|
{ value: 'sqlite', label: 'SQLite', hint: 'Lightweight local storage' },
|
|
12
|
-
{ value: 'hybrid', label: 'Hybrid', hint: 'SQLite
|
|
12
|
+
{ value: 'hybrid', label: 'Hybrid', hint: 'SQLite with vector search (recommended)' },
|
|
13
13
|
{ value: 'memory', label: 'In-Memory', hint: 'Fast but non-persistent' }
|
|
14
14
|
];
|
|
15
15
|
// Delete command
|
|
16
16
|
export const deleteCommand = {
|
|
17
17
|
name: 'delete',
|
|
18
18
|
aliases: ['rm'],
|
|
19
|
-
description: 'Delete a memory entry (
|
|
19
|
+
description: 'Delete a memory entry (SQLite-backed, Memory Palace, or knowledge chunk)',
|
|
20
20
|
options: [
|
|
21
21
|
{
|
|
22
22
|
name: 'key',
|
|
@@ -189,16 +189,17 @@ export const statsCommand = {
|
|
|
189
189
|
const memoryConfig = configManager.get(ctx.cwd, 'memory');
|
|
190
190
|
const configuredBackend = memoryConfig?.backend || 'hybrid';
|
|
191
191
|
// The actual storage engine currently in use for reads/writes is always
|
|
192
|
-
//
|
|
193
|
-
// configured (but not-yet-wired)
|
|
192
|
+
// SQLite (better-sqlite3, sql.js WASM fallback — see memory-bridge.ts) —
|
|
193
|
+
// report the real on-disk path, not the configured (but not-yet-wired)
|
|
194
|
+
// backend's path.
|
|
194
195
|
const backendStats = await bridgeGetBackendStats();
|
|
195
196
|
const realLocation = bridgeGetDbPath();
|
|
196
197
|
const statsResult = {
|
|
197
198
|
totalEntries: entries.length,
|
|
198
199
|
totalSize: totalBytes >= 1048576 ? `${(totalBytes / 1048576).toFixed(1)} MB`
|
|
199
200
|
: totalBytes >= 1024 ? `${(totalBytes / 1024).toFixed(1)} KB` : `${totalBytes} B`,
|
|
200
|
-
version: '
|
|
201
|
-
backend: `
|
|
201
|
+
version: 'sqlite',
|
|
202
|
+
backend: `SQLite (configured: ${configuredBackend})`,
|
|
202
203
|
location: realLocation,
|
|
203
204
|
oldestEntry: times[0] ? new Date(times[0]).toISOString() : null,
|
|
204
205
|
newestEntry: times.length ? new Date(times[times.length - 1]).toISOString() : null,
|
|
@@ -103,7 +103,7 @@ export const listCommand = {
|
|
|
103
103
|
// Edit command
|
|
104
104
|
export const editCommand = {
|
|
105
105
|
name: 'edit',
|
|
106
|
-
description: 'Edit a memory entry (
|
|
106
|
+
description: 'Edit a memory entry (SQLite-backed, Memory Palace, or knowledge chunk)',
|
|
107
107
|
options: [
|
|
108
108
|
{ name: 'key', short: 'k', description: 'Storage key', type: 'string' },
|
|
109
109
|
{ name: 'namespace', short: 'n', description: 'Memory namespace', type: 'string', default: 'default' },
|
|
@@ -112,7 +112,7 @@ export const editCommand = {
|
|
|
112
112
|
{ name: 'id', description: 'Entry ID (palace/knowledge)', type: 'string' }
|
|
113
113
|
],
|
|
114
114
|
examples: [
|
|
115
|
-
{ command: 'monomind memory edit -k "pattern/auth" --value "updated content"', description: 'Edit
|
|
115
|
+
{ command: 'monomind memory edit -k "pattern/auth" --value "updated content"', description: 'Edit SQLite-backed entry' },
|
|
116
116
|
{ command: 'monomind memory edit --source palace --id "abc123" --value "new content"', description: 'Edit Memory Palace drawer' },
|
|
117
117
|
{ command: 'monomind memory edit --source knowledge --id "chunk-42" --value "updated"', description: 'Edit knowledge chunk' }
|
|
118
118
|
],
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* CLI Memory Command
|
|
3
|
-
* Memory operations
|
|
3
|
+
* Memory operations — SQLite-backed (better-sqlite3, sql.js WASM fallback)
|
|
4
4
|
*
|
|
5
5
|
* Split into sub-modules:
|
|
6
6
|
* memory-crud.ts — store, retrieve, search
|
|
@@ -59,7 +59,7 @@ const initMemoryCommand = {
|
|
|
59
59
|
],
|
|
60
60
|
examples: [
|
|
61
61
|
{ command: 'monomind memory init', description: 'Initialize hybrid backend with all features' },
|
|
62
|
-
{ command: 'monomind memory init -b lancedb', description: 'Initialize
|
|
62
|
+
{ command: 'monomind memory init -b lancedb', description: 'Initialize memory backend (legacy "lancedb" alias, now SQLite-backed)' },
|
|
63
63
|
{ command: 'monomind memory init -p ./data/memory.db --force', description: 'Reinitialize at custom path' },
|
|
64
64
|
{ command: 'monomind memory init --verbose --verify', description: 'Initialize with full verification' }
|
|
65
65
|
],
|
|
@@ -264,11 +264,11 @@ export const memoryCommand = {
|
|
|
264
264
|
output.printList([
|
|
265
265
|
`${output.highlight('init')} - Initialize memory database (sql.js)`,
|
|
266
266
|
`${output.highlight('store')} - Store data in memory`,
|
|
267
|
-
`${output.highlight('edit')} - Edit an entry (
|
|
267
|
+
`${output.highlight('edit')} - Edit an entry (SQLite-backed, palace, knowledge)`,
|
|
268
268
|
`${output.highlight('retrieve')} - Retrieve data from memory`,
|
|
269
269
|
`${output.highlight('search')} - Semantic/vector search`,
|
|
270
270
|
`${output.highlight('list')} - List memory entries`,
|
|
271
|
-
`${output.highlight('delete')} - Delete an entry (
|
|
271
|
+
`${output.highlight('delete')} - Delete an entry (SQLite-backed, palace, knowledge)`,
|
|
272
272
|
`${output.highlight('templates')} - Show best-practice entry templates`,
|
|
273
273
|
`${output.highlight('stats')} - Show statistics`,
|
|
274
274
|
`${output.highlight('configure')} - Configure backend`,
|
|
@@ -52,7 +52,7 @@ export const statusCommand = {
|
|
|
52
52
|
component: 'Pattern Index',
|
|
53
53
|
status: hnswStatus.available ? output.success('Ready') : output.dim('Empty'),
|
|
54
54
|
details: hnswStatus.available
|
|
55
|
-
? `${hnswStatus.entryCount} vectors, ${hnswStatus.dimensions}-dim (ANN via
|
|
55
|
+
? `${hnswStatus.entryCount} vectors, ${hnswStatus.dimensions}-dim (ANN via SQLite)`
|
|
56
56
|
: 'No vectors indexed yet',
|
|
57
57
|
},
|
|
58
58
|
{
|
|
@@ -554,17 +554,16 @@ const bottleneckCommand = {
|
|
|
554
554
|
}
|
|
555
555
|
catch { /* ok */ }
|
|
556
556
|
}
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
}
|
|
557
|
+
try {
|
|
558
|
+
const { bridgeGetDbPath } = await import('../memory/memory-bridge.js');
|
|
559
|
+
const dbFile = path.join(bridgeGetDbPath(), 'memory.db');
|
|
560
|
+
const stat = fs.statSync(dbFile).size ?? 0;
|
|
561
|
+
const sizeMB = stat / 1024 / 1024;
|
|
562
|
+
if (sizeMB > 100) {
|
|
563
|
+
findings.push({ component: 'Memory DB', bottleneck: `SQLite ${sizeMB.toFixed(0)}MB`, severity: output.warning('Medium'), solution: 'Run: monomind memory compact' });
|
|
565
564
|
}
|
|
566
|
-
catch { /* no lance.db */ }
|
|
567
565
|
}
|
|
566
|
+
catch { /* no memory.db yet */ }
|
|
568
567
|
const network = (perf.network ?? {});
|
|
569
568
|
if (!network.batching) {
|
|
570
569
|
findings.push({ component: 'Network', bottleneck: 'No request batching', severity: output.info('Low'), solution: 'Run: monomind performance optimize --apply -t latency' });
|
|
@@ -83,7 +83,7 @@ async function getSystemStatus() {
|
|
|
83
83
|
const memoryStatus = {
|
|
84
84
|
entries: 0,
|
|
85
85
|
size: 0,
|
|
86
|
-
backend: '
|
|
86
|
+
backend: 'sqlite',
|
|
87
87
|
performance: { avgSearchTime: 0, cacheHitRate: 0 },
|
|
88
88
|
};
|
|
89
89
|
// Get task status
|
|
@@ -507,7 +507,7 @@ const memoryCommand = {
|
|
|
507
507
|
const entries = listed?.success ? listed.entries : [];
|
|
508
508
|
const totalBytes = entries.reduce((s, e) => s + (e.content || '').length, 0);
|
|
509
509
|
const result = {
|
|
510
|
-
backend: '
|
|
510
|
+
backend: 'SQLite',
|
|
511
511
|
entries: entries.length,
|
|
512
512
|
size: totalBytes,
|
|
513
513
|
};
|
|
@@ -289,7 +289,7 @@ const initCommand = {
|
|
|
289
289
|
output.writeln(output.dim(' Initializing memory namespace...'));
|
|
290
290
|
output.writeln(output.dim(' Setting up communication channels...'));
|
|
291
291
|
if (v1Mode) {
|
|
292
|
-
output.writeln(output.dim(' Configuring
|
|
292
|
+
output.writeln(output.dim(' Configuring SQLite-backed vector search (ANN)....'));
|
|
293
293
|
output.writeln(output.dim(' Initializing keyword routing + outcome measurement...'));
|
|
294
294
|
}
|
|
295
295
|
output.writeln();
|
|
@@ -310,7 +310,7 @@ export class CLI {
|
|
|
310
310
|
this.output.writeln(this.output.bold('V1 FEATURES:'));
|
|
311
311
|
this.output.printList([
|
|
312
312
|
'15-agent hierarchical mesh coordination',
|
|
313
|
-
'
|
|
313
|
+
'SQLite-backed ANN vector indexing',
|
|
314
314
|
'Keyword routing + route-outcome measurement',
|
|
315
315
|
'Unified SwarmCoordinator engine',
|
|
316
316
|
'Event-sourced state management',
|
|
@@ -192,7 +192,7 @@ function cliCommandsTable() {
|
|
|
192
192
|
| \`init\` | 5 | Project initialization |
|
|
193
193
|
| \`agent\` | 7 | Agent lifecycle management |
|
|
194
194
|
| \`swarm\` | 6 | Multi-agent swarm coordination |
|
|
195
|
-
| \`memory\` | 12 |
|
|
195
|
+
| \`memory\` | 12 | SQLite memory with ANN search |
|
|
196
196
|
| \`task\` | 5 | Task creation and lifecycle |
|
|
197
197
|
| \`session\` | 6 | Session state management |
|
|
198
198
|
| \`hooks\` | 29 | Self-learning hooks + 15 background workers${unavailNote(avail.hooks)} |
|
|
@@ -371,7 +371,7 @@ function intelligenceSystem() {
|
|
|
371
371
|
|
|
372
372
|
- **Keyword routing**: Deterministic task→agent routing via \`createKeywordRouter\`
|
|
373
373
|
- **Outcome measurement**: Route and command outcomes are recorded and scored to surface routing accuracy over time
|
|
374
|
-
- **Pattern search**:
|
|
374
|
+
- **Pattern search**: SQLite-backed ANN vector search for finding similar past patterns
|
|
375
375
|
|
|
376
376
|
Routing and learning are JS-only — no native engine is required. Outcomes
|
|
377
377
|
feed back into the recorded metrics so routing quality is measured, not assumed.`;
|
|
@@ -1617,7 +1617,7 @@ async function writeCapabilitiesDoc(targetDir, options, result) {
|
|
|
1617
1617
|
Monomind is a domain-driven design architecture for multi-agent AI coordination with:
|
|
1618
1618
|
|
|
1619
1619
|
- **15-Agent Swarm Coordination** with hierarchical and mesh topologies
|
|
1620
|
-
- **ANN Vector Search** - indexed pattern retrieval via
|
|
1620
|
+
- **ANN Vector Search** - indexed pattern retrieval via SQLite (better-sqlite3, sql.js WASM fallback)
|
|
1621
1621
|
- **Keyword Routing** - deterministic task→agent routing with outcome measurement
|
|
1622
1622
|
- **Byzantine Fault Tolerance** - Queen-led consensus mechanisms
|
|
1623
1623
|
- **MCP Server Integration** - Model Context Protocol support
|
|
@@ -1712,7 +1712,7 @@ npx monomind@latest swarm monitor
|
|
|
1712
1712
|
| \`init\` | 5 | Project initialization |
|
|
1713
1713
|
| \`agent\` | 7 | Agent lifecycle management |
|
|
1714
1714
|
| \`swarm\` | 6 | Multi-agent coordination |
|
|
1715
|
-
| \`memory\` | 12 |
|
|
1715
|
+
| \`memory\` | 12 | SQLite with ANN vector search |
|
|
1716
1716
|
| \`mcp\` | 9 | MCP server management |
|
|
1717
1717
|
| \`task\` | 5 | Task assignment |
|
|
1718
1718
|
| \`session\` | 6 | Session persistence |
|
|
@@ -1819,7 +1819,7 @@ session start when their output is >6h old; run on demand with
|
|
|
1819
1819
|
|
|
1820
1820
|
### Intelligence System
|
|
1821
1821
|
- **Keyword routing**: Deterministic task→agent routing with outcome measurement
|
|
1822
|
-
- **ANN pattern search**: Indexed vector search via
|
|
1822
|
+
- **ANN pattern search**: Indexed vector search via SQLite
|
|
1823
1823
|
- **ReasoningBank**: Stores learned patterns and trajectories for retrieval
|
|
1824
1824
|
- **Int8 Quantization**: ~4x memory reduction for stored embeddings
|
|
1825
1825
|
|
|
@@ -1891,7 +1891,7 @@ npx monomind@latest memory init --force
|
|
|
1891
1891
|
|
|
1892
1892
|
| Metric | Target | Status |
|
|
1893
1893
|
|--------|--------|--------|
|
|
1894
|
-
| ANN Search | Indexed vector search | ✅ Implemented (
|
|
1894
|
+
| ANN Search | Indexed vector search | ✅ Implemented (SQLite) |
|
|
1895
1895
|
| Memory Reduction | 50-75% | ✅ Implemented (~4x via Int8 quantization) |
|
|
1896
1896
|
| Pattern Learning | Recorded + retrievable | ✅ Implemented (ReasoningBank) |
|
|
1897
1897
|
| MCP Response | <100ms | ✅ Achieved |
|
|
@@ -1909,7 +1909,7 @@ npx monomind@latest memory init --force
|
|
|
1909
1909
|
### Integrated Packages
|
|
1910
1910
|
| Package | Version | Purpose |
|
|
1911
1911
|
|---------|---------|---------|
|
|
1912
|
-
|
|
|
1912
|
+
| better-sqlite3 (sql.js WASM fallback) | latest | SQLite vector database (ANN search) |
|
|
1913
1913
|
|
|
1914
1914
|
### Optional Integrations
|
|
1915
1915
|
| Package | Command |
|
|
@@ -1994,7 +1994,8 @@ async function writeClaudeMd(targetDir, options, result) {
|
|
|
1994
1994
|
'# Monomind Integration (auto-generated by monomind init)',
|
|
1995
1995
|
'When working on multi-file tasks or complex features, use ToolSearch to find and invoke monomind MCP tools.',
|
|
1996
1996
|
'Key tools: memory_store, memory_search, hooks_route, swarm_init, agent_spawn.',
|
|
1997
|
-
'
|
|
1997
|
+
'**Code navigation**: ALWAYS call `mcp__monomind__monograph_query` BEFORE grep/rg/find for code exploration — it returns file path + line number from a pre-built knowledge graph. Call `mcp__monomind__monograph_suggest` with a task description for multi-file tasks. Only fall back to grep if monograph returns 0 results or the DB is not built.',
|
|
1998
|
+
'Check system-reminder tags for [INTELLIGENCE] pattern suggestions and [MONOGRAPH] context before starting work.',
|
|
1998
1999
|
'',
|
|
1999
2000
|
].join('\n');
|
|
2000
2001
|
try {
|
|
@@ -2007,6 +2008,12 @@ async function writeClaudeMd(targetDir, options, result) {
|
|
|
2007
2008
|
fs.appendFileSync(globalClaudeMd, monomindBlock);
|
|
2008
2009
|
result.created.files.push('~/.claude/CLAUDE.md (appended monomind block)');
|
|
2009
2010
|
}
|
|
2011
|
+
else if (!existing.includes('monograph_query')) {
|
|
2012
|
+
// Upgrade existing block to include monograph instructions
|
|
2013
|
+
const updated = existing.replace(/# Monomind Integration[^\n]*\n(?:(?!^#).+\n)*/m, monomindBlock.trimStart() + '\n');
|
|
2014
|
+
atomicWriteFile(globalClaudeMd, updated);
|
|
2015
|
+
result.created.files.push('~/.claude/CLAUDE.md (upgraded monomind block)');
|
|
2016
|
+
}
|
|
2010
2017
|
}
|
|
2011
2018
|
else {
|
|
2012
2019
|
atomicWriteFile(globalClaudeMd, monomindBlock.trimStart());
|
|
@@ -487,12 +487,33 @@ export function generateHookHandler() {
|
|
|
487
487
|
' },',
|
|
488
488
|
'',
|
|
489
489
|
" 'pre-bash': () => {",
|
|
490
|
-
' // Graph-assisted grep: resolve patterns via monograph DB before grep runs',
|
|
491
490
|
' var cmd = (hookInput.toolInput || hookInput.tool_input || {}).command || hookInput.command || "";',
|
|
492
491
|
' if (typeof cmd !== "string") cmd = "";',
|
|
493
|
-
'
|
|
492
|
+
' var isGrep = /\\b(?:grep|rg|ag|find|fd)\\b/.test(cmd);',
|
|
493
|
+
' if (!isGrep) return;',
|
|
494
|
+
' // Graph gate: remind to use monograph before grep',
|
|
495
|
+
' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
|
|
496
|
+
' if (fs.existsSync(dbPath)) {',
|
|
497
|
+
' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
|
|
498
|
+
' var gateState = {};',
|
|
499
|
+
' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
|
|
500
|
+
' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
|
|
501
|
+
' var sessId = hookInput.sessionId || hookInput.session_id || "";',
|
|
502
|
+
' if (sessId) {',
|
|
503
|
+
' var s = sessions[sessId] || { queried: false, blockedOnce: false };',
|
|
504
|
+
' if (!s.queried && !s.blockedOnce) {',
|
|
505
|
+
' s.blockedOnce = true; s.ts = Date.now(); sessions[sessId] = s;',
|
|
506
|
+
' try { fs.mkdirSync(path.join(process.cwd(), ".monomind"), { recursive: true }); fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions })); } catch(e) {}',
|
|
507
|
+
' process.stderr.write(JSON.stringify({ decision: "block", reason: "[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before grep/find. This blocks once per session." }) + "\\n");',
|
|
508
|
+
' process.exitCode = 2; return;',
|
|
509
|
+
' }',
|
|
510
|
+
' if (!s.queried) {',
|
|
511
|
+
' console.log("[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session — try monograph first for faster results.");',
|
|
512
|
+
' }',
|
|
513
|
+
' }',
|
|
514
|
+
' }',
|
|
515
|
+
' // Graph-assisted grep: resolve patterns via monograph DB',
|
|
494
516
|
' try {',
|
|
495
|
-
' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
|
|
496
517
|
' if (!fs.existsSync(dbPath)) return;',
|
|
497
518
|
' var Database;',
|
|
498
519
|
' try { Database = require("better-sqlite3"); } catch(e) {',
|
|
@@ -518,6 +539,33 @@ export function generateHookHandler() {
|
|
|
518
539
|
' } catch (e) { /* non-fatal */ }',
|
|
519
540
|
' },',
|
|
520
541
|
'',
|
|
542
|
+
" 'pre-search': () => {",
|
|
543
|
+
' // Graph gate for Grep/Glob tools (same logic as pre-bash)',
|
|
544
|
+
' var dbPath = path.join(process.cwd(), ".monomind", "monograph.db");',
|
|
545
|
+
' if (!fs.existsSync(dbPath)) return;',
|
|
546
|
+
' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
|
|
547
|
+
' var gateState = {};',
|
|
548
|
+
' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
|
|
549
|
+
' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
|
|
550
|
+
' var sessId = hookInput.sessionId || hookInput.session_id || "";',
|
|
551
|
+
' if (sessId) {',
|
|
552
|
+
' var s = sessions[sessId] || { queried: false, blockedOnce: false };',
|
|
553
|
+
' if (!s.queried && !s.blockedOnce) {',
|
|
554
|
+
' s.blockedOnce = true; s.ts = Date.now(); sessions[sessId] = s;',
|
|
555
|
+
' try { fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions })); } catch(e) {}',
|
|
556
|
+
' process.stderr.write(JSON.stringify({ decision: "block", reason: "[graph-gate] Call mcp__monomind__monograph_query or monograph_suggest before Grep/Glob. This blocks once per session." }) + "\\n");',
|
|
557
|
+
' process.exitCode = 2; return;',
|
|
558
|
+
' }',
|
|
559
|
+
' if (!s.queried) {',
|
|
560
|
+
' console.log("[MONOGRAPH_REMINDER] monograph_query/suggest not yet called this session.");',
|
|
561
|
+
' }',
|
|
562
|
+
' }',
|
|
563
|
+
' },',
|
|
564
|
+
'',
|
|
565
|
+
" 'pre-write': () => {",
|
|
566
|
+
' // Stub — real implementation in the full hook-handler.cjs',
|
|
567
|
+
' },',
|
|
568
|
+
'',
|
|
521
569
|
" 'post-edit': () => {",
|
|
522
570
|
' if (session && session.metric) {',
|
|
523
571
|
" try { session.metric('edits'); } catch (e) { /* no active session */ }",
|
|
@@ -563,6 +611,21 @@ export function generateHookHandler() {
|
|
|
563
611
|
' }',
|
|
564
612
|
' },',
|
|
565
613
|
'',
|
|
614
|
+
" 'post-graph-tool': () => {",
|
|
615
|
+
' // Clear the graph gate when a real monograph tool is called',
|
|
616
|
+
' var sessId = hookInput.sessionId || hookInput.session_id || "";',
|
|
617
|
+
' if (!sessId) return;',
|
|
618
|
+
' var stateFile = path.join(process.cwd(), ".monomind", "graph-gate-state.json");',
|
|
619
|
+
' try {',
|
|
620
|
+
' var gateState = {};',
|
|
621
|
+
' try { gateState = JSON.parse(fs.readFileSync(stateFile, "utf-8")); } catch(e) {}',
|
|
622
|
+
' var sessions = (gateState && typeof gateState.sessions === "object") ? gateState.sessions : {};',
|
|
623
|
+
' var s = sessions[sessId] || { blockedOnce: false };',
|
|
624
|
+
' s.queried = true; s.ts = Date.now(); sessions[sessId] = s;',
|
|
625
|
+
' fs.writeFileSync(stateFile, JSON.stringify({ sessions: sessions }));',
|
|
626
|
+
' } catch(e) {}',
|
|
627
|
+
' },',
|
|
628
|
+
'',
|
|
566
629
|
" 'session-end': () => {",
|
|
567
630
|
' if (intelligence && intelligence.consolidate) {',
|
|
568
631
|
' try {',
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Auto-detects project profile and generates:
|
|
5
5
|
* 1. .agents/shared_instructions.md — prepended to every agent prompt
|
|
6
|
-
* 2. Memory seeds — pre-loaded into
|
|
6
|
+
* 2. Memory seeds — pre-loaded into SQLite so agents start with project best practices
|
|
7
7
|
*/
|
|
8
8
|
import type { InitResult } from './types.js';
|
|
9
9
|
export interface ProjectProfile {
|