monomind 2.0.3 → 2.1.3
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 +74 -92
- package/package.json +11 -7
- package/packages/@monomind/cli/.claude/helpers/control-start.cjs +13 -20
- package/packages/@monomind/cli/.claude/helpers/event-logger.cjs +109 -6
- package/packages/@monomind/cli/.claude/helpers/graphify-freshen.cjs +19 -17
- package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +60 -28
- package/packages/@monomind/cli/.claude/helpers/handlers/capture-handler.cjs +99 -28
- package/packages/@monomind/cli/.claude/helpers/handlers/edit-handler.cjs +27 -9
- package/packages/@monomind/cli/.claude/helpers/handlers/gates-handler.cjs +18 -9
- package/packages/@monomind/cli/.claude/helpers/handlers/loops-status-handler.cjs +1 -1
- package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +33 -4
- package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +75 -45
- package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +0 -12
- package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +53 -22
- package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +75 -4
- package/packages/@monomind/cli/.claude/helpers/intelligence.cjs +94 -15
- package/packages/@monomind/cli/.claude/helpers/session.cjs +6 -1
- package/packages/@monomind/cli/.claude/helpers/statusline.cjs +10 -10
- package/packages/@monomind/cli/.claude/helpers/token-tracker.cjs +3 -3
- package/packages/@monomind/cli/.claude/helpers/utils/agent-registrations.cjs +41 -0
- package/packages/@monomind/cli/.claude/helpers/utils/fs-helpers.cjs +183 -0
- package/packages/@monomind/cli/.claude/helpers/utils/micro-agents.cjs +10 -6
- package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +73 -2
- package/packages/@monomind/cli/.claude/helpers/utils/telemetry.cjs +35 -19
- package/packages/@monomind/cli/README.md +74 -92
- package/packages/@monomind/cli/bin/cli.js +10 -1
- package/packages/@monomind/cli/dist/src/browser/workflow/store.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +9 -15
- package/packages/@monomind/cli/dist/src/commands/browse.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/cleanup.js +20 -4
- package/packages/@monomind/cli/dist/src/commands/completions.js +66 -261
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +5 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +7 -2
- package/packages/@monomind/cli/dist/src/commands/hooks-workers.js +7 -0
- package/packages/@monomind/cli/dist/src/commands/index.js +3 -0
- package/packages/@monomind/cli/dist/src/commands/mcp.js +11 -6
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +12 -6
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +6 -13
- package/packages/@monomind/cli/dist/src/commands/monograph.js +3 -3
- package/packages/@monomind/cli/dist/src/commands/org.d.ts +3 -1
- package/packages/@monomind/cli/dist/src/commands/org.js +321 -127
- package/packages/@monomind/cli/dist/src/commands/platforms.d.ts +1 -1
- package/packages/@monomind/cli/dist/src/commands/start.js +142 -37
- package/packages/@monomind/cli/dist/src/commands/tokens.js +21 -3
- package/packages/@monomind/cli/dist/src/config-adapter.js +37 -17
- package/packages/@monomind/cli/dist/src/index.js +64 -28
- package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +44 -11
- package/packages/@monomind/cli/dist/src/init/executor.js +93 -55
- package/packages/@monomind/cli/dist/src/mcp-client.d.ts +8 -3
- package/packages/@monomind/cli/dist/src/mcp-client.js +37 -3
- package/packages/@monomind/cli/dist/src/mcp-server.js +8 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +10 -5
- package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.d.ts +8 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +31 -31
- package/packages/@monomind/cli/dist/src/mcp-tools/github-tools.js +30 -8
- package/packages/@monomind/cli/dist/src/mcp-tools/graphify-tools.js +11 -2
- package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +56 -35
- package/packages/@monomind/cli/dist/src/mcp-tools/knowledge-tools.js +9 -1
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +56 -14
- package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +88 -41
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.d.ts +36 -36
- package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +6 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/system-tools.js +4 -4
- package/packages/@monomind/cli/dist/src/mcp-tools/types.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/mcp-tools/types.js +36 -1
- package/packages/@monomind/cli/dist/src/memory/ewc-consolidation.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.d.ts +13 -1
- package/packages/@monomind/cli/dist/src/memory/hnsw-operations.js +66 -14
- package/packages/@monomind/cli/dist/src/memory/intelligence.js +99 -3
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +20 -0
- package/packages/@monomind/cli/dist/src/memory/sona-optimizer.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/orgrt/broker.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/orgrt/broker.js +73 -0
- package/packages/@monomind/cli/dist/src/orgrt/bus.d.ts +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/bus.js +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/daemon.d.ts +46 -0
- package/packages/@monomind/cli/dist/src/orgrt/daemon.js +201 -18
- package/packages/@monomind/cli/dist/src/orgrt/forwarder.d.ts +10 -5
- package/packages/@monomind/cli/dist/src/orgrt/forwarder.js +138 -8
- package/packages/@monomind/cli/dist/src/orgrt/inbox.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/orgrt/inbox.js +56 -0
- package/packages/@monomind/cli/dist/src/orgrt/policy.d.ts +5 -1
- package/packages/@monomind/cli/dist/src/orgrt/policy.js +58 -5
- package/packages/@monomind/cli/dist/src/orgrt/provider.js +1 -0
- package/packages/@monomind/cli/dist/src/orgrt/scheduler.d.ts +13 -0
- package/packages/@monomind/cli/dist/src/orgrt/scheduler.js +48 -0
- package/packages/@monomind/cli/dist/src/orgrt/server.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/orgrt/server.js +39 -0
- package/packages/@monomind/cli/dist/src/orgrt/session.d.ts +10 -1
- package/packages/@monomind/cli/dist/src/orgrt/session.js +24 -1
- package/packages/@monomind/cli/dist/src/orgrt/test-loop.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/orgrt/test-loop.js +108 -0
- package/packages/@monomind/cli/dist/src/orgrt/types.d.ts +52 -52
- package/packages/@monomind/cli/dist/src/output.d.ts +29 -29
- package/packages/@monomind/cli/dist/src/output.js +22 -7
- package/packages/@monomind/cli/dist/src/parser.d.ts +32 -0
- package/packages/@monomind/cli/dist/src/parser.js +130 -5
- package/packages/@monomind/cli/dist/src/routing/embed-worker.js +13 -1
- package/packages/@monomind/cli/dist/src/routing/route-layer-factory.js +31 -0
- package/packages/@monomind/cli/dist/src/services/config-file-manager.d.ts +21 -0
- package/packages/@monomind/cli/dist/src/services/config-file-manager.js +60 -7
- package/packages/@monomind/cli/dist/src/services/crash-reporter.js +2 -1
- package/packages/@monomind/cli/dist/src/types.d.ts +2 -2
- package/packages/@monomind/cli/dist/src/ui/dashboard.html +243 -49
- package/packages/@monomind/cli/dist/src/ui/orgs-files.js +192 -0
- package/packages/@monomind/cli/dist/src/ui/orgs.html +79 -11
- package/packages/@monomind/cli/dist/src/ui/server.mjs +346 -139
- package/packages/@monomind/cli/dist/src/utils/input-guards.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/utils/input-guards.js +39 -5
- package/packages/@monomind/cli/package.json +15 -15
|
@@ -19,23 +19,36 @@ function _isValidDb(p) {
|
|
|
19
19
|
return false;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Resolve the monograph DB path for a given repo root (defaults to project cwd).
|
|
24
|
+
* Falls back to searching up to the git root when the DB isn't directly under
|
|
25
|
+
* `<cwd>/.monomind` — e.g. when called from a subdirectory of the repo. Only
|
|
26
|
+
* the no-arg (project cwd) form is cached; explicit `repoPath` overrides are
|
|
27
|
+
* cheap one-off lookups (staleness checks with a user-supplied path) so caching
|
|
28
|
+
* them isn't worth the invalidation complexity.
|
|
29
|
+
*/
|
|
30
|
+
function getDbPath(repoPathOverride) {
|
|
31
|
+
const cwd = repoPathOverride ?? getProjectCwd();
|
|
32
|
+
const useCache = repoPathOverride === undefined;
|
|
24
33
|
// Invalidate cache when project root changes (e.g. MONOMIND_CWD set after initialize)
|
|
25
|
-
if (_cachedDbPath && _cachedCwd === cwd)
|
|
34
|
+
if (useCache && _cachedDbPath && _cachedCwd === cwd)
|
|
26
35
|
return _cachedDbPath;
|
|
27
|
-
|
|
28
|
-
|
|
36
|
+
if (useCache) {
|
|
37
|
+
_cachedCwd = cwd;
|
|
38
|
+
_cachedDbPath = undefined;
|
|
39
|
+
}
|
|
29
40
|
const direct = join(cwd, '.monomind', 'monograph.db');
|
|
30
41
|
if (_isValidDb(direct)) {
|
|
31
|
-
|
|
42
|
+
if (useCache)
|
|
43
|
+
_cachedDbPath = direct;
|
|
32
44
|
return direct;
|
|
33
45
|
}
|
|
34
46
|
try {
|
|
35
47
|
const root = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf8' }).trim();
|
|
36
48
|
const candidate = join(root, '.monomind', 'monograph.db');
|
|
37
49
|
if (_isValidDb(candidate)) {
|
|
38
|
-
|
|
50
|
+
if (useCache)
|
|
51
|
+
_cachedDbPath = candidate;
|
|
39
52
|
return candidate;
|
|
40
53
|
}
|
|
41
54
|
}
|
|
@@ -46,13 +59,6 @@ function getDbPath() {
|
|
|
46
59
|
function text(t) {
|
|
47
60
|
return { content: [{ type: 'text', text: t }] };
|
|
48
61
|
}
|
|
49
|
-
function ensureDbExists() {
|
|
50
|
-
const p = getDbPath();
|
|
51
|
-
if (!_isValidDb(p)) {
|
|
52
|
-
throw new Error(`Monograph index not built yet. Run monograph_build first (path: ${p}).`);
|
|
53
|
-
}
|
|
54
|
-
return p;
|
|
55
|
-
}
|
|
56
62
|
// ── Active watcher registry ──────────────────────────────────────────────────
|
|
57
63
|
const _activeWatchers = new Map();
|
|
58
64
|
function applyPprRerank(db, seedNodes, damping, maxResults) {
|
|
@@ -577,9 +583,13 @@ function taskRelevance(task, nodeText) {
|
|
|
577
583
|
return taskTerms.filter(t => txt.includes(t)).length / taskTerms.length;
|
|
578
584
|
}
|
|
579
585
|
// ── monograph_visualize ───────────────────────────────────────────────────────
|
|
586
|
+
// Columns needed to render/export the graph — deliberately excludes `embedding`,
|
|
587
|
+
// which can be several KB per node (384D vectors) and would otherwise bloat
|
|
588
|
+
// tool-result payloads and written files by many MB.
|
|
589
|
+
const NODE_RENDER_COLUMNS = 'id, label, name, norm_label, file_path, start_line, end_line, community_id, is_exported, language, properties';
|
|
580
590
|
const monographVisualizeTool = {
|
|
581
591
|
name: 'monograph_visualize',
|
|
582
|
-
description: 'Render the knowledge graph as HTML (default), SVG, or JSON.',
|
|
592
|
+
description: 'Render the knowledge graph as HTML (default), SVG, or JSON. Writes output to a file under .monomind/visualize/ and returns the file path (output can be multi-MB at the max node count, too large to return inline).',
|
|
583
593
|
inputSchema: {
|
|
584
594
|
type: 'object',
|
|
585
595
|
properties: {
|
|
@@ -589,6 +599,7 @@ const monographVisualizeTool = {
|
|
|
589
599
|
},
|
|
590
600
|
handler: async (input) => {
|
|
591
601
|
const { openDb, closeDb, toJson, toHtml, toSvg } = await import('@monoes/monograph');
|
|
602
|
+
const { writeFileSync, mkdirSync } = await import('fs');
|
|
592
603
|
const db = openDb(getDbPath());
|
|
593
604
|
try {
|
|
594
605
|
// Cap maxNodes: passed to SQL LIMIT clause for both nodes (n) and edges
|
|
@@ -598,7 +609,7 @@ const monographVisualizeTool = {
|
|
|
598
609
|
const limit = Number.isFinite(rawMaxNodes) && rawMaxNodes > 0
|
|
599
610
|
? Math.min(Math.floor(rawMaxNodes), MAX_EXPORT_NODES)
|
|
600
611
|
: 500;
|
|
601
|
-
const nodes = db.prepare(
|
|
612
|
+
const nodes = db.prepare(`SELECT ${NODE_RENDER_COLUMNS} FROM nodes LIMIT ?`).all(limit);
|
|
602
613
|
// Only include edges where both endpoints are in the visible node set
|
|
603
614
|
const edges = db.prepare(`
|
|
604
615
|
SELECT e.* FROM edges e
|
|
@@ -607,11 +618,15 @@ const monographVisualizeTool = {
|
|
|
607
618
|
LIMIT ?
|
|
608
619
|
`).all(limit, limit, limit * 3);
|
|
609
620
|
const fmt = input.format ?? 'html';
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
621
|
+
const rendered = fmt === 'json' ? toJson(nodes, edges)
|
|
622
|
+
: fmt === 'svg' ? toSvg(nodes, edges)
|
|
623
|
+
: toHtml(nodes, edges);
|
|
624
|
+
const ext = fmt === 'json' ? 'json' : fmt === 'svg' ? 'svg' : 'html';
|
|
625
|
+
const outDir = resolve(join(getProjectCwd(), '.monomind', 'visualize'));
|
|
626
|
+
mkdirSync(outDir, { recursive: true });
|
|
627
|
+
const outPath = join(outDir, `graph-${Date.now()}.${ext}`);
|
|
628
|
+
writeFileSync(outPath, rendered);
|
|
629
|
+
return text(`Visualization written to ${outPath} (${nodes.length} nodes, ${edges.length} edges)${ext === 'html' ? '\nNote: HTML uses the vis-network CDN script and requires network access to render.' : ''}`);
|
|
615
630
|
}
|
|
616
631
|
finally {
|
|
617
632
|
closeDb(db);
|
|
@@ -700,7 +715,8 @@ const monographReportTool = {
|
|
|
700
715
|
return `${i + 1}. **${n.name}** (${n.label}) — degree ${n.degree}${loc ? ` \`${loc}\`` : ''}`;
|
|
701
716
|
}),
|
|
702
717
|
].join('\n');
|
|
703
|
-
const
|
|
718
|
+
const rawOutPath = input.path ?? join(getProjectCwd(), '.monomind', 'GRAPH_REPORT.md');
|
|
719
|
+
const outPath = resolve(getProjectCwd(), rawOutPath);
|
|
704
720
|
const allowedRoot = resolve(getProjectCwd());
|
|
705
721
|
if (outPath !== allowedRoot && !outPath.startsWith(allowedRoot + sep)) {
|
|
706
722
|
return text(`Error: path must be within the project directory (${allowedRoot})`);
|
|
@@ -725,7 +741,13 @@ let _buildInProgress = false;
|
|
|
725
741
|
async function computeCommitsBehind(repoPath) {
|
|
726
742
|
const { openDb, closeDb } = await import('@monoes/monograph');
|
|
727
743
|
const { execSync } = await import('child_process');
|
|
728
|
-
const
|
|
744
|
+
const dbPath = getDbPath(repoPath);
|
|
745
|
+
if (!_isValidDb(dbPath))
|
|
746
|
+
return null;
|
|
747
|
+
// openDb's fileMustExist option isn't in the currently-published
|
|
748
|
+
// @monoes/monograph release this CLI depends on — _isValidDb above is the
|
|
749
|
+
// real guard against openDb silently creating an empty DB at a missing path.
|
|
750
|
+
const db = openDb(dbPath);
|
|
729
751
|
try {
|
|
730
752
|
const meta = db.prepare("SELECT value FROM index_meta WHERE key = 'last_commit_hash'").get() ?? db.prepare("SELECT value FROM index_meta WHERE key = 'lastCommit'").get();
|
|
731
753
|
const lastCommit = meta?.value ?? null;
|
|
@@ -929,11 +951,13 @@ const monographExportTool = {
|
|
|
929
951
|
const { writeFileSync, mkdirSync } = await import('fs');
|
|
930
952
|
const db = openDb(getDbPath());
|
|
931
953
|
try {
|
|
932
|
-
|
|
954
|
+
// Exclude `embedding` — a several-KB-per-node vector column that would
|
|
955
|
+
// otherwise bloat exported files by many MB for no rendering benefit.
|
|
956
|
+
const nodes = db.prepare(`SELECT ${NODE_RENDER_COLUMNS} FROM nodes`).all();
|
|
933
957
|
const edges = db.prepare('SELECT * FROM edges').all();
|
|
934
958
|
const fmt = input.format;
|
|
935
959
|
const requestedOut = input.outputPath ?? join(getProjectCwd(), '.monomind', 'export');
|
|
936
|
-
const outDir = resolve(requestedOut);
|
|
960
|
+
const outDir = resolve(getProjectCwd(), requestedOut);
|
|
937
961
|
const allowedRoot = resolve(getProjectCwd());
|
|
938
962
|
if (outDir !== allowedRoot && !outDir.startsWith(allowedRoot + sep)) {
|
|
939
963
|
return text(`Error: outputPath must be within the project directory (${allowedRoot})`);
|
|
@@ -1072,8 +1096,10 @@ const monographImpactTool = {
|
|
|
1072
1096
|
const impactPath = typeof rawImpactPath === 'string' && rawImpactPath.length > MAX_IMPACT_PATH_LEN
|
|
1073
1097
|
? rawImpactPath.slice(0, MAX_IMPACT_PATH_LEN) : rawImpactPath;
|
|
1074
1098
|
const rawDepth = input.depth;
|
|
1075
|
-
const depth =
|
|
1076
|
-
?
|
|
1099
|
+
const depth = rawDepth === undefined
|
|
1100
|
+
? undefined
|
|
1101
|
+
: (typeof rawDepth === 'number' && Number.isFinite(rawDepth) && rawDepth > 0
|
|
1102
|
+
? Math.min(Math.floor(rawDepth), 6) : 3);
|
|
1077
1103
|
const result = getMonographImpact(db, {
|
|
1078
1104
|
name: impactName,
|
|
1079
1105
|
filePath: impactPath,
|
|
@@ -1737,7 +1763,13 @@ const monographInstallSkillsTool = {
|
|
|
1737
1763
|
return text(`Invalid platform "${platform}". Must be one of: ${validPlatforms.join(', ')}`);
|
|
1738
1764
|
}
|
|
1739
1765
|
// Load community data from graph
|
|
1740
|
-
const dbPath =
|
|
1766
|
+
const dbPath = getDbPath(repoPath);
|
|
1767
|
+
// openDb's fileMustExist option isn't in the currently-published
|
|
1768
|
+
// @monoes/monograph release this CLI depends on — check validity
|
|
1769
|
+
// ourselves so a missing DB doesn't get silently auto-created empty.
|
|
1770
|
+
if (!_isValidDb(dbPath)) {
|
|
1771
|
+
return text('Graph not built yet. Run monograph_build first.');
|
|
1772
|
+
}
|
|
1741
1773
|
let db;
|
|
1742
1774
|
try {
|
|
1743
1775
|
db = openDb(dbPath);
|
|
@@ -1846,21 +1878,19 @@ const monographListReposTool = {
|
|
|
1846
1878
|
// ── monograph_group_contracts ─────────────────────────────────────────────────
|
|
1847
1879
|
const monographGroupContractsTool = {
|
|
1848
1880
|
name: 'monograph_group_contracts',
|
|
1849
|
-
description: 'List public API contracts (exported symbols, interfaces, and types) for all groups defined in .
|
|
1881
|
+
description: 'List public API contracts (exported symbols, interfaces, and types) for all groups defined in group.yaml.',
|
|
1850
1882
|
inputSchema: {
|
|
1851
1883
|
type: 'object',
|
|
1852
1884
|
properties: {
|
|
1853
|
-
|
|
1885
|
+
configPath: { type: 'string', description: 'Path to group.yaml (defaults to group.yaml in project cwd)' },
|
|
1854
1886
|
},
|
|
1855
1887
|
},
|
|
1856
1888
|
handler: async (input) => {
|
|
1857
1889
|
const { getGroupContracts } = await import('./monograph-compat.js');
|
|
1858
|
-
const
|
|
1859
|
-
const repoPath = input.repoPath ?? getProjectCwd();
|
|
1860
|
-
const configPath = join(repoPath, '.monograph', 'groups.json');
|
|
1890
|
+
const configPath = input.configPath ?? join(getProjectCwd(), 'group.yaml');
|
|
1861
1891
|
const contracts = await getGroupContracts(configPath);
|
|
1862
1892
|
if (contracts.length === 0)
|
|
1863
|
-
return text(
|
|
1893
|
+
return text(`No contracts found. Ensure groups are defined in ${configPath}.`);
|
|
1864
1894
|
const lines = contracts.map(c => `[${c.groupName}] ${c.symbol} — ${c.filePath}:${c.line}`);
|
|
1865
1895
|
return text(lines.join('\n'));
|
|
1866
1896
|
},
|
|
@@ -1872,14 +1902,12 @@ const monographGroupStatusTool = {
|
|
|
1872
1902
|
inputSchema: {
|
|
1873
1903
|
type: 'object',
|
|
1874
1904
|
properties: {
|
|
1875
|
-
|
|
1905
|
+
configPath: { type: 'string', description: 'Path to group.yaml (defaults to group.yaml in project cwd)' },
|
|
1876
1906
|
},
|
|
1877
1907
|
},
|
|
1878
1908
|
handler: async (input) => {
|
|
1879
1909
|
const { getGroupStatus } = await import('./monograph-compat.js');
|
|
1880
|
-
const
|
|
1881
|
-
const repoPath = input.repoPath ?? getProjectCwd();
|
|
1882
|
-
const configPath = join(repoPath, '.monograph', 'groups.json');
|
|
1910
|
+
const configPath = input.configPath ?? join(getProjectCwd(), 'group.yaml');
|
|
1883
1911
|
const status = await getGroupStatus(configPath);
|
|
1884
1912
|
const lines = [`Groups: ${status.totalGroups} (${status.indexedGroups} indexed, ${status.stalledGroups} stalled)`];
|
|
1885
1913
|
for (const g of status.groups) {
|
|
@@ -1954,10 +1982,26 @@ const monographDeadCodeTool = {
|
|
|
1954
1982
|
const repoPath = input.path ?? getProjectCwd();
|
|
1955
1983
|
const cats = input.categories ?? ['dead-functions', 'orphan-files', 'stale-dist'];
|
|
1956
1984
|
const result = {};
|
|
1957
|
-
const dbPath =
|
|
1985
|
+
const dbPath = getDbPath(repoPath);
|
|
1986
|
+
// openDb's fileMustExist option isn't in the currently-published
|
|
1987
|
+
// @monoes/monograph release this CLI depends on — check validity
|
|
1988
|
+
// ourselves so a missing DB doesn't get silently auto-created empty.
|
|
1989
|
+
if (!_isValidDb(dbPath)) {
|
|
1990
|
+
return text(JSON.stringify({ error: 'No monograph index found. Run monograph_build first.' }));
|
|
1991
|
+
}
|
|
1958
1992
|
let db = null;
|
|
1959
1993
|
try {
|
|
1960
1994
|
db = openDb(dbPath);
|
|
1995
|
+
// _isValidDb's size check can't distinguish a real index from an
|
|
1996
|
+
// empty-but-schema-migrated DB (better-sqlite3 auto-creates + migrates
|
|
1997
|
+
// on open, and other unguarded openDb() call sites in this file can
|
|
1998
|
+
// create exactly that as a side effect of an unrelated tool call before
|
|
1999
|
+
// monograph_build ever runs). Verify actual content post-open so this
|
|
2000
|
+
// reports "never built" instead of a misleading "0 dead functions found".
|
|
2001
|
+
const { count } = db.prepare('SELECT COUNT(*) as count FROM nodes').get();
|
|
2002
|
+
if (count === 0) {
|
|
2003
|
+
return text(JSON.stringify({ error: 'No monograph index found. Run monograph_build first.' }));
|
|
2004
|
+
}
|
|
1961
2005
|
}
|
|
1962
2006
|
catch {
|
|
1963
2007
|
return text(JSON.stringify({ error: 'No monograph index found. Run monograph_build first.' }));
|
|
@@ -1997,9 +2041,12 @@ const monographDeadCodeTool = {
|
|
|
1997
2041
|
FROM nodes n
|
|
1998
2042
|
WHERE n.label = 'File'
|
|
1999
2043
|
AND (SELECT COUNT(*) FROM edges e WHERE e.target_id = n.id AND e.relation = 'IMPORTS') = 0
|
|
2000
|
-
AND n.file_path NOT LIKE '
|
|
2044
|
+
AND n.file_path NOT LIKE '%/test/%'
|
|
2045
|
+
AND n.file_path NOT LIKE '%/tests/%'
|
|
2046
|
+
AND n.file_path NOT LIKE '%.test.%'
|
|
2001
2047
|
AND n.file_path NOT LIKE '%__tests__%'
|
|
2002
|
-
AND n.file_path NOT LIKE '
|
|
2048
|
+
AND n.file_path NOT LIKE '%/spec/%'
|
|
2049
|
+
AND n.file_path NOT LIKE '%.spec.%'
|
|
2003
2050
|
AND n.file_path NOT LIKE '%/index.%'
|
|
2004
2051
|
AND n.file_path NOT LIKE 'bin/%'
|
|
2005
2052
|
AND n.file_path NOT LIKE 'scripts/%'
|
package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.d.ts
CHANGED
|
@@ -13,14 +13,14 @@ export declare const PrioritizeGapsInputSchema: z.ZodObject<{
|
|
|
13
13
|
startLine: z.ZodNumber;
|
|
14
14
|
endLine: z.ZodNumber;
|
|
15
15
|
}, "strip", z.ZodTypeAny, {
|
|
16
|
-
type: "function" | "line" | "branch";
|
|
17
16
|
id: string;
|
|
17
|
+
type: "branch" | "function" | "line";
|
|
18
18
|
file: string;
|
|
19
19
|
startLine: number;
|
|
20
20
|
endLine: number;
|
|
21
21
|
}, {
|
|
22
|
-
type: "function" | "line" | "branch";
|
|
23
22
|
id: string;
|
|
23
|
+
type: "branch" | "function" | "line";
|
|
24
24
|
file: string;
|
|
25
25
|
startLine: number;
|
|
26
26
|
endLine: number;
|
|
@@ -52,9 +52,15 @@ export declare const PrioritizeGapsInputSchema: z.ZodObject<{
|
|
|
52
52
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
53
53
|
groupBy: z.ZodDefault<z.ZodEnum<["risk", "file", "type", "none"]>>;
|
|
54
54
|
}, "strip", z.ZodTypeAny, {
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
55
|
+
gaps?: {
|
|
56
|
+
id: string;
|
|
57
|
+
type: "branch" | "function" | "line";
|
|
58
|
+
file: string;
|
|
59
|
+
startLine: number;
|
|
60
|
+
endLine: number;
|
|
61
|
+
}[] | undefined;
|
|
62
|
+
targetPath?: string | undefined;
|
|
63
|
+
factors: ("business-critical" | "change-frequency" | "complexity" | "defect-history" | "dependency-count" | "test-difficulty")[];
|
|
58
64
|
weights?: {
|
|
59
65
|
complexity: number;
|
|
60
66
|
changeFrequency: number;
|
|
@@ -63,16 +69,18 @@ export declare const PrioritizeGapsInputSchema: z.ZodObject<{
|
|
|
63
69
|
dependencyCount: number;
|
|
64
70
|
testDifficulty: number;
|
|
65
71
|
} | undefined;
|
|
72
|
+
limit: number;
|
|
73
|
+
groupBy: "file" | "none" | "risk" | "type";
|
|
74
|
+
}, {
|
|
66
75
|
gaps?: {
|
|
67
|
-
type: "function" | "line" | "branch";
|
|
68
76
|
id: string;
|
|
77
|
+
type: "branch" | "function" | "line";
|
|
69
78
|
file: string;
|
|
70
79
|
startLine: number;
|
|
71
80
|
endLine: number;
|
|
72
81
|
}[] | undefined;
|
|
73
82
|
targetPath?: string | undefined;
|
|
74
|
-
|
|
75
|
-
limit?: number | undefined;
|
|
83
|
+
factors?: ("business-critical" | "change-frequency" | "complexity" | "defect-history" | "dependency-count" | "test-difficulty")[] | undefined;
|
|
76
84
|
weights?: {
|
|
77
85
|
complexity?: number | undefined;
|
|
78
86
|
changeFrequency?: number | undefined;
|
|
@@ -81,16 +89,8 @@ export declare const PrioritizeGapsInputSchema: z.ZodObject<{
|
|
|
81
89
|
dependencyCount?: number | undefined;
|
|
82
90
|
testDifficulty?: number | undefined;
|
|
83
91
|
} | undefined;
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
id: string;
|
|
87
|
-
file: string;
|
|
88
|
-
startLine: number;
|
|
89
|
-
endLine: number;
|
|
90
|
-
}[] | undefined;
|
|
91
|
-
targetPath?: string | undefined;
|
|
92
|
-
factors?: ("complexity" | "change-frequency" | "defect-history" | "business-critical" | "dependency-count" | "test-difficulty")[] | undefined;
|
|
93
|
-
groupBy?: "type" | "none" | "file" | "risk" | undefined;
|
|
92
|
+
limit?: number | undefined;
|
|
93
|
+
groupBy?: "file" | "none" | "risk" | "type" | undefined;
|
|
94
94
|
}>;
|
|
95
95
|
export type PrioritizeGapsInput = z.infer<typeof PrioritizeGapsInputSchema>;
|
|
96
96
|
export interface PrioritizeGapsOutput {
|
|
@@ -176,14 +176,14 @@ export declare const toolDefinition: {
|
|
|
176
176
|
startLine: z.ZodNumber;
|
|
177
177
|
endLine: z.ZodNumber;
|
|
178
178
|
}, "strip", z.ZodTypeAny, {
|
|
179
|
-
type: "function" | "line" | "branch";
|
|
180
179
|
id: string;
|
|
180
|
+
type: "branch" | "function" | "line";
|
|
181
181
|
file: string;
|
|
182
182
|
startLine: number;
|
|
183
183
|
endLine: number;
|
|
184
184
|
}, {
|
|
185
|
-
type: "function" | "line" | "branch";
|
|
186
185
|
id: string;
|
|
186
|
+
type: "branch" | "function" | "line";
|
|
187
187
|
file: string;
|
|
188
188
|
startLine: number;
|
|
189
189
|
endLine: number;
|
|
@@ -215,9 +215,15 @@ export declare const toolDefinition: {
|
|
|
215
215
|
limit: z.ZodDefault<z.ZodNumber>;
|
|
216
216
|
groupBy: z.ZodDefault<z.ZodEnum<["risk", "file", "type", "none"]>>;
|
|
217
217
|
}, "strip", z.ZodTypeAny, {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
218
|
+
gaps?: {
|
|
219
|
+
id: string;
|
|
220
|
+
type: "branch" | "function" | "line";
|
|
221
|
+
file: string;
|
|
222
|
+
startLine: number;
|
|
223
|
+
endLine: number;
|
|
224
|
+
}[] | undefined;
|
|
225
|
+
targetPath?: string | undefined;
|
|
226
|
+
factors: ("business-critical" | "change-frequency" | "complexity" | "defect-history" | "dependency-count" | "test-difficulty")[];
|
|
221
227
|
weights?: {
|
|
222
228
|
complexity: number;
|
|
223
229
|
changeFrequency: number;
|
|
@@ -226,16 +232,18 @@ export declare const toolDefinition: {
|
|
|
226
232
|
dependencyCount: number;
|
|
227
233
|
testDifficulty: number;
|
|
228
234
|
} | undefined;
|
|
235
|
+
limit: number;
|
|
236
|
+
groupBy: "file" | "none" | "risk" | "type";
|
|
237
|
+
}, {
|
|
229
238
|
gaps?: {
|
|
230
|
-
type: "function" | "line" | "branch";
|
|
231
239
|
id: string;
|
|
240
|
+
type: "branch" | "function" | "line";
|
|
232
241
|
file: string;
|
|
233
242
|
startLine: number;
|
|
234
243
|
endLine: number;
|
|
235
244
|
}[] | undefined;
|
|
236
245
|
targetPath?: string | undefined;
|
|
237
|
-
|
|
238
|
-
limit?: number | undefined;
|
|
246
|
+
factors?: ("business-critical" | "change-frequency" | "complexity" | "defect-history" | "dependency-count" | "test-difficulty")[] | undefined;
|
|
239
247
|
weights?: {
|
|
240
248
|
complexity?: number | undefined;
|
|
241
249
|
changeFrequency?: number | undefined;
|
|
@@ -244,16 +252,8 @@ export declare const toolDefinition: {
|
|
|
244
252
|
dependencyCount?: number | undefined;
|
|
245
253
|
testDifficulty?: number | undefined;
|
|
246
254
|
} | undefined;
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
id: string;
|
|
250
|
-
file: string;
|
|
251
|
-
startLine: number;
|
|
252
|
-
endLine: number;
|
|
253
|
-
}[] | undefined;
|
|
254
|
-
targetPath?: string | undefined;
|
|
255
|
-
factors?: ("complexity" | "change-frequency" | "defect-history" | "business-critical" | "dependency-count" | "test-difficulty")[] | undefined;
|
|
256
|
-
groupBy?: "type" | "none" | "file" | "risk" | undefined;
|
|
255
|
+
limit?: number | undefined;
|
|
256
|
+
groupBy?: "file" | "none" | "risk" | "type" | undefined;
|
|
257
257
|
}>;
|
|
258
258
|
handler: typeof handler;
|
|
259
259
|
};
|
package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts
CHANGED
|
@@ -15,16 +15,16 @@ export declare const DetectSecretsInputSchema: z.ZodObject<{
|
|
|
15
15
|
scanHistory: z.ZodDefault<z.ZodBoolean>;
|
|
16
16
|
}, "strip", z.ZodTypeAny, {
|
|
17
17
|
targetPath: string;
|
|
18
|
+
secretTypes: ("api-key" | "aws-key" | "aws-secret" | "azure-key" | "certificate" | "connection-string" | "gcp-key" | "generic" | "password" | "private-key" | "token")[];
|
|
18
19
|
excludePatterns: string[];
|
|
19
|
-
secretTypes: ("password" | "token" | "api-key" | "private-key" | "connection-string" | "certificate" | "aws-key" | "aws-secret" | "gcp-key" | "azure-key" | "generic")[];
|
|
20
20
|
includeEntropy: boolean;
|
|
21
21
|
entropyThreshold: number;
|
|
22
22
|
verifySecrets: boolean;
|
|
23
23
|
scanHistory: boolean;
|
|
24
24
|
}, {
|
|
25
25
|
targetPath: string;
|
|
26
|
+
secretTypes?: ("api-key" | "aws-key" | "aws-secret" | "azure-key" | "certificate" | "connection-string" | "gcp-key" | "generic" | "password" | "private-key" | "token")[] | undefined;
|
|
26
27
|
excludePatterns?: string[] | undefined;
|
|
27
|
-
secretTypes?: ("password" | "token" | "api-key" | "private-key" | "connection-string" | "certificate" | "aws-key" | "aws-secret" | "gcp-key" | "azure-key" | "generic")[] | undefined;
|
|
28
28
|
includeEntropy?: boolean | undefined;
|
|
29
29
|
entropyThreshold?: number | undefined;
|
|
30
30
|
verifySecrets?: boolean | undefined;
|
|
@@ -116,16 +116,16 @@ export declare const toolDefinition: {
|
|
|
116
116
|
scanHistory: z.ZodDefault<z.ZodBoolean>;
|
|
117
117
|
}, "strip", z.ZodTypeAny, {
|
|
118
118
|
targetPath: string;
|
|
119
|
+
secretTypes: ("api-key" | "aws-key" | "aws-secret" | "azure-key" | "certificate" | "connection-string" | "gcp-key" | "generic" | "password" | "private-key" | "token")[];
|
|
119
120
|
excludePatterns: string[];
|
|
120
|
-
secretTypes: ("password" | "token" | "api-key" | "private-key" | "connection-string" | "certificate" | "aws-key" | "aws-secret" | "gcp-key" | "azure-key" | "generic")[];
|
|
121
121
|
includeEntropy: boolean;
|
|
122
122
|
entropyThreshold: number;
|
|
123
123
|
verifySecrets: boolean;
|
|
124
124
|
scanHistory: boolean;
|
|
125
125
|
}, {
|
|
126
126
|
targetPath: string;
|
|
127
|
+
secretTypes?: ("api-key" | "aws-key" | "aws-secret" | "azure-key" | "certificate" | "connection-string" | "gcp-key" | "generic" | "password" | "private-key" | "token")[] | undefined;
|
|
127
128
|
excludePatterns?: string[] | undefined;
|
|
128
|
-
secretTypes?: ("password" | "token" | "api-key" | "private-key" | "connection-string" | "certificate" | "aws-key" | "aws-secret" | "gcp-key" | "azure-key" | "generic")[] | undefined;
|
|
129
129
|
includeEntropy?: boolean | undefined;
|
|
130
130
|
entropyThreshold?: number | undefined;
|
|
131
131
|
verifySecrets?: boolean | undefined;
|
|
@@ -7,13 +7,14 @@
|
|
|
7
7
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync, statSync } from 'node:fs';
|
|
8
8
|
import { join } from 'node:path';
|
|
9
9
|
import { randomBytes } from 'node:crypto';
|
|
10
|
-
import {
|
|
10
|
+
import { getMonomindDataRoot, migrateLegacyStoreFile } from './types.js';
|
|
11
11
|
import { agentTools } from './agent-tools.js';
|
|
12
|
-
// Swarm state persistence
|
|
13
|
-
|
|
12
|
+
// Swarm state persistence — relative to the git-safe data root (see
|
|
13
|
+
// getMonomindDataRoot()), matching agent/task/hive-mind stores.
|
|
14
|
+
const SWARM_DIR = 'swarm';
|
|
14
15
|
const SWARM_STATE_FILE = 'swarm-state.json';
|
|
15
16
|
function getSwarmDir() {
|
|
16
|
-
return join(
|
|
17
|
+
return join(getMonomindDataRoot(), SWARM_DIR);
|
|
17
18
|
}
|
|
18
19
|
function getSwarmStatePath() {
|
|
19
20
|
return join(getSwarmDir(), SWARM_STATE_FILE);
|
|
@@ -28,6 +29,7 @@ const MAX_SWARM_STORE_BYTES = 10 * 1024 * 1024;
|
|
|
28
29
|
function loadSwarmStore() {
|
|
29
30
|
try {
|
|
30
31
|
const path = getSwarmStatePath();
|
|
32
|
+
migrateLegacyStoreFile(path, join(SWARM_DIR, SWARM_STATE_FILE));
|
|
31
33
|
if (existsSync(path)) {
|
|
32
34
|
if (statSync(path).size > MAX_SWARM_STORE_BYTES)
|
|
33
35
|
return { swarms: {}, version: '3.0.0' };
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
* - process.cpuUsage() for real CPU stats
|
|
9
9
|
* - os module for system information
|
|
10
10
|
*/
|
|
11
|
-
import { getProjectCwd } from './types.js';
|
|
11
|
+
import { getProjectCwd, getMonomindDataRoot } from './types.js';
|
|
12
12
|
import { existsSync, readFileSync, statSync, writeFileSync, renameSync, mkdirSync } from 'node:fs';
|
|
13
13
|
import { join, dirname } from 'node:path';
|
|
14
14
|
import { fileURLToPath } from 'node:url';
|
|
@@ -184,7 +184,7 @@ export const systemTools = [
|
|
|
184
184
|
// Fallback: JSON store files (backward compatibility)
|
|
185
185
|
if (_metricsSource === 'none') {
|
|
186
186
|
try {
|
|
187
|
-
const agentStorePath = join(
|
|
187
|
+
const agentStorePath = join(getMonomindDataRoot(), 'agents', 'store.json');
|
|
188
188
|
if (existsSync(agentStorePath) && statSync(agentStorePath).size <= MAX_SYSTEM_STORE_BYTES) {
|
|
189
189
|
const agentStore = JSON.parse(readFileSync(agentStorePath, 'utf-8'));
|
|
190
190
|
const agents = Object.values(agentStore.agents || {});
|
|
@@ -197,7 +197,7 @@ export const systemTools = [
|
|
|
197
197
|
}
|
|
198
198
|
catch { /* agent store not available */ }
|
|
199
199
|
try {
|
|
200
|
-
const taskStorePath = join(
|
|
200
|
+
const taskStorePath = join(getMonomindDataRoot(), 'tasks', 'store.json');
|
|
201
201
|
if (existsSync(taskStorePath) && statSync(taskStorePath).size <= MAX_SYSTEM_STORE_BYTES) {
|
|
202
202
|
const taskStore = JSON.parse(readFileSync(taskStorePath, 'utf-8'));
|
|
203
203
|
const tasks = Object.values(taskStore.tasks || {});
|
|
@@ -534,7 +534,7 @@ export const systemTools = [
|
|
|
534
534
|
},
|
|
535
535
|
handler: async () => {
|
|
536
536
|
// Read from the task store file
|
|
537
|
-
const storePath = join(
|
|
537
|
+
const storePath = join(getMonomindDataRoot(), 'tasks', 'store.json');
|
|
538
538
|
let tasks = [];
|
|
539
539
|
try {
|
|
540
540
|
if (existsSync(storePath) && statSync(storePath).size <= MAX_SYSTEM_STORE_BYTES) {
|
|
@@ -24,6 +24,26 @@ export interface MCPToolResult {
|
|
|
24
24
|
*/
|
|
25
25
|
export declare function getProjectCwd(): string;
|
|
26
26
|
export declare function getMonomindDataRoot(cwd?: string): string;
|
|
27
|
+
/**
|
|
28
|
+
* One-time migration for the agent/task/hive/swarm stores that historically lived
|
|
29
|
+
* under `<projectCwd>/.monomind/<subpath>` (via getProjectCwd()) before being
|
|
30
|
+
* consolidated onto the canonical getMonomindDataRoot() location (typically
|
|
31
|
+
* `<repo>/.git/monomind/<subpath>`). Several MCP tool files (agent-tools.ts,
|
|
32
|
+
* hive-mind-tools.ts, swarm-tools.ts, system-tools.ts) used to read/write the
|
|
33
|
+
* legacy path directly, causing the same logical store to physically split from
|
|
34
|
+
* task-tools.ts/session-tools.ts, which always used getMonomindDataRoot().
|
|
35
|
+
*
|
|
36
|
+
* If the canonical file is missing but the legacy file exists, copy (never move,
|
|
37
|
+
* for safety) the legacy file into place so pre-existing data isn't silently
|
|
38
|
+
* orphaned. Best-effort and idempotent — never throws, and it's a no-op once the
|
|
39
|
+
* canonical file exists or when the two paths already coincide (e.g. no .git).
|
|
40
|
+
*
|
|
41
|
+
* @param canonicalPath Absolute path under getMonomindDataRoot() the tool now reads from.
|
|
42
|
+
* @param legacySubpath Path relative to `.monomind/` that the tool used to read from
|
|
43
|
+
* (e.g. `join('agents', 'store.json')`).
|
|
44
|
+
* @param cwd Optional project cwd override (defaults to getProjectCwd()).
|
|
45
|
+
*/
|
|
46
|
+
export declare function migrateLegacyStoreFile(canonicalPath: string, legacySubpath: string, cwd?: string): void;
|
|
27
47
|
export interface MCPTool {
|
|
28
48
|
name: string;
|
|
29
49
|
description: string;
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Local type definitions to avoid external imports outside package boundary.
|
|
5
5
|
*/
|
|
6
|
-
import { statSync, readFileSync } from 'node:fs';
|
|
6
|
+
import { statSync, readFileSync, existsSync, mkdirSync, copyFileSync } from 'node:fs';
|
|
7
7
|
import { join, dirname, resolve } from 'node:path';
|
|
8
8
|
/**
|
|
9
9
|
* Returns the effective project working directory.
|
|
@@ -60,4 +60,39 @@ export function getMonomindDataRoot(cwd) {
|
|
|
60
60
|
_dataRootCache.set(workDir, result);
|
|
61
61
|
return result;
|
|
62
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* One-time migration for the agent/task/hive/swarm stores that historically lived
|
|
65
|
+
* under `<projectCwd>/.monomind/<subpath>` (via getProjectCwd()) before being
|
|
66
|
+
* consolidated onto the canonical getMonomindDataRoot() location (typically
|
|
67
|
+
* `<repo>/.git/monomind/<subpath>`). Several MCP tool files (agent-tools.ts,
|
|
68
|
+
* hive-mind-tools.ts, swarm-tools.ts, system-tools.ts) used to read/write the
|
|
69
|
+
* legacy path directly, causing the same logical store to physically split from
|
|
70
|
+
* task-tools.ts/session-tools.ts, which always used getMonomindDataRoot().
|
|
71
|
+
*
|
|
72
|
+
* If the canonical file is missing but the legacy file exists, copy (never move,
|
|
73
|
+
* for safety) the legacy file into place so pre-existing data isn't silently
|
|
74
|
+
* orphaned. Best-effort and idempotent — never throws, and it's a no-op once the
|
|
75
|
+
* canonical file exists or when the two paths already coincide (e.g. no .git).
|
|
76
|
+
*
|
|
77
|
+
* @param canonicalPath Absolute path under getMonomindDataRoot() the tool now reads from.
|
|
78
|
+
* @param legacySubpath Path relative to `.monomind/` that the tool used to read from
|
|
79
|
+
* (e.g. `join('agents', 'store.json')`).
|
|
80
|
+
* @param cwd Optional project cwd override (defaults to getProjectCwd()).
|
|
81
|
+
*/
|
|
82
|
+
export function migrateLegacyStoreFile(canonicalPath, legacySubpath, cwd) {
|
|
83
|
+
try {
|
|
84
|
+
if (existsSync(canonicalPath))
|
|
85
|
+
return;
|
|
86
|
+
const legacyPath = join(cwd || getProjectCwd(), '.monomind', legacySubpath);
|
|
87
|
+
if (legacyPath === canonicalPath)
|
|
88
|
+
return;
|
|
89
|
+
if (!existsSync(legacyPath))
|
|
90
|
+
return;
|
|
91
|
+
mkdirSync(dirname(canonicalPath), { recursive: true });
|
|
92
|
+
copyFileSync(legacyPath, canonicalPath);
|
|
93
|
+
}
|
|
94
|
+
catch {
|
|
95
|
+
// Best-effort; leave both stores as-is on any failure.
|
|
96
|
+
}
|
|
97
|
+
}
|
|
63
98
|
//# sourceMappingURL=types.js.map
|
|
@@ -127,6 +127,12 @@ export declare class EWCConsolidator {
|
|
|
127
127
|
private globalFisher;
|
|
128
128
|
private consolidationHistory;
|
|
129
129
|
private initialized;
|
|
130
|
+
/** Dirty flag: true when in-memory state diverges from disk */
|
|
131
|
+
private dirty;
|
|
132
|
+
/** Pending debounced write timer */
|
|
133
|
+
private saveTimer;
|
|
134
|
+
/** Debounce window for disk writes (ms) */
|
|
135
|
+
private static readonly SAVE_DEBOUNCE_MS;
|
|
130
136
|
constructor(config?: Partial<EWCConfig>);
|
|
131
137
|
/**
|
|
132
138
|
* Initialize the consolidator by loading persisted state
|
|
@@ -237,6 +243,12 @@ export declare class EWCConsolidator {
|
|
|
237
243
|
* Prune old, low-importance patterns to stay within limit
|
|
238
244
|
*/
|
|
239
245
|
private pruneOldPatterns;
|
|
246
|
+
/**
|
|
247
|
+
* Schedule a debounced disk flush.
|
|
248
|
+
* Multiple calls within SAVE_DEBOUNCE_MS coalesce into one write,
|
|
249
|
+
* preventing blocking I/O on every consolidation or gradient event.
|
|
250
|
+
*/
|
|
251
|
+
private scheduleSave;
|
|
240
252
|
/**
|
|
241
253
|
* Save state to disk
|
|
242
254
|
*/
|
|
@@ -10,8 +10,20 @@ interface HNSWEntry {
|
|
|
10
10
|
namespace: string;
|
|
11
11
|
content: string;
|
|
12
12
|
}
|
|
13
|
+
/** Minimal shape of the real @monoes/memory HNSWIndex class relied on here. */
|
|
14
|
+
interface RealHNSWIndex {
|
|
15
|
+
addPoint(id: string, vector: Float32Array): Promise<void>;
|
|
16
|
+
search(query: Float32Array, k: number, ef?: number): Promise<Array<{
|
|
17
|
+
id: string;
|
|
18
|
+
distance: number;
|
|
19
|
+
}>>;
|
|
20
|
+
rebuild(entries: Array<{
|
|
21
|
+
id: string;
|
|
22
|
+
vector: Float32Array;
|
|
23
|
+
}>): Promise<void>;
|
|
24
|
+
}
|
|
13
25
|
interface HNSWIndex {
|
|
14
|
-
|
|
26
|
+
instance: RealHNSWIndex;
|
|
15
27
|
entries: Map<string, HNSWEntry>;
|
|
16
28
|
dimensions: number;
|
|
17
29
|
initialized: boolean;
|