monomind 1.11.5 → 1.11.7

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.
Files changed (37) hide show
  1. package/README.md +0 -1
  2. package/package.json +11 -4
  3. package/packages/@monomind/cli/README.md +0 -1
  4. package/packages/@monomind/cli/dist/src/commands/agent.js +8 -1
  5. package/packages/@monomind/cli/dist/src/commands/benchmark.js +17 -45
  6. package/packages/@monomind/cli/dist/src/commands/index.d.ts +0 -2
  7. package/packages/@monomind/cli/dist/src/commands/index.js +0 -7
  8. package/packages/@monomind/cli/dist/src/commands/monograph.js +1 -1
  9. package/packages/@monomind/cli/dist/src/commands/plugins.js +1 -2
  10. package/packages/@monomind/cli/dist/src/commands/route.js +27 -36
  11. package/packages/@monomind/cli/dist/src/index.js +6 -26
  12. package/packages/@monomind/cli/dist/src/mcp-server.js +1 -1
  13. package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.d.ts +0 -8
  14. package/packages/@monomind/cli/dist/src/mcp-tools/auto-install.js +0 -4
  15. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +2 -7
  16. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.d.ts +4 -313
  17. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +11 -1051
  18. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +25 -25
  19. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +1 -1
  20. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +4 -30
  21. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -2
  22. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +1 -2
  23. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +7 -115
  24. package/packages/@monomind/cli/dist/src/monovector/index.d.ts +1 -8
  25. package/packages/@monomind/cli/dist/src/monovector/index.js +1 -13
  26. package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +0 -33
  27. package/packages/@monomind/cli/dist/src/routing/llm-caller.d.ts +24 -0
  28. package/packages/@monomind/cli/dist/src/routing/llm-caller.js +109 -0
  29. package/packages/@monomind/cli/dist/src/update/checker.js +0 -1
  30. package/packages/@monomind/cli/dist/src/update/validator.js +0 -10
  31. package/packages/@monomind/cli/package.json +4 -11
  32. package/packages/@monomind/guidance/package.json +1 -2
  33. package/packages/@monomind/cli/bundled-graph/dist/src/build.js +0 -73
  34. package/packages/@monomind/cli/bundled-graph/dist/src/cluster.js +0 -120
  35. package/packages/@monomind/cli/bundled-graph/package.json +0 -57
  36. package/packages/@monomind/cli/dist/src/commands/embeddings.d.ts +0 -18
  37. package/packages/@monomind/cli/dist/src/commands/embeddings.js +0 -1628
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Claude Code (headless) LLM caller for semantic-routing fallback.
3
+ *
4
+ * Monomind always runs on top of Claude Code, so low-confidence route
5
+ * classification is delegated to the local `claude` CLI in headless print
6
+ * mode — NOT to the Anthropic API with a managed key. There is no
7
+ * `@anthropic-ai/sdk` dependency and no `ANTHROPIC_API_KEY` requirement: the
8
+ * host's existing Claude Code auth is reused.
9
+ *
10
+ * The returned function matches `LLMFallbackConfig.llmCaller` from
11
+ * `@monomind/routing` — `(prompt: string) => Promise<string>`. When the
12
+ * `claude` CLI is unavailable it throws, which the routing layer already
13
+ * catches and degrades to the best semantic match.
14
+ */
15
+ import { spawn, execSync } from 'child_process';
16
+ import { tmpdir } from 'os';
17
+ /** Default model for routing fallback — Haiku is fast and cheap for slug classification. */
18
+ const DEFAULT_ROUTING_MODEL = 'haiku';
19
+ /**
20
+ * Max time to wait for a single classification before giving up.
21
+ * `claude --print` is a full headless session (cold start ~10s, can spike),
22
+ * so this is generous; the routing layer degrades to the best semantic match
23
+ * on timeout rather than blocking the caller.
24
+ */
25
+ const DEFAULT_TIMEOUT_MS = 45_000;
26
+ let claudeAvailable = null;
27
+ /** Cheap, cached check that the `claude` CLI is installed and on PATH. */
28
+ export function isClaudeCodeAvailable() {
29
+ if (claudeAvailable !== null)
30
+ return claudeAvailable;
31
+ try {
32
+ execSync('claude --version', { encoding: 'utf-8', stdio: 'pipe', timeout: 5000, windowsHide: true });
33
+ claudeAvailable = true;
34
+ }
35
+ catch {
36
+ claudeAvailable = false;
37
+ }
38
+ return claudeAvailable;
39
+ }
40
+ /**
41
+ * Build an `llmCaller` that delegates a classification prompt to a headless
42
+ * Claude Code agent (`claude --print --model <model> -- <prompt>`).
43
+ *
44
+ * Returns `null` when the `claude` CLI is not available, so callers can omit
45
+ * `llmFallback` entirely and let routing run keyword + semantic only.
46
+ */
47
+ export function createClaudeLLMCaller(options = {}) {
48
+ if (!isClaudeCodeAvailable())
49
+ return null;
50
+ const model = options.model ?? DEFAULT_ROUTING_MODEL;
51
+ const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
52
+ const cwd = options.cwd ?? tmpdir();
53
+ return (prompt) => new Promise((resolve, reject) => {
54
+ const env = { ...process.env };
55
+ // Don't let the child detect a "nested" session.
56
+ delete env.CLAUDE_SESSION_ID;
57
+ delete env.CLAUDE_PARENT_SESSION_ID;
58
+ // Constrain to a pure one-shot classifier:
59
+ // --strict-mcp-config (with no --mcp-config) loads ZERO MCP servers, so
60
+ // the child never loads monomind's own MCP server — avoids latency and
61
+ // a potential routing→MCP→routing recursion.
62
+ // --no-session-persistence keeps throwaway classification calls out of
63
+ // the user's session history.
64
+ // `--` terminates option parsing so a prompt can't smuggle flags.
65
+ const child = spawn('claude', ['--print', '--model', model, '--strict-mcp-config', '--no-session-persistence', '--', prompt], {
66
+ cwd,
67
+ env,
68
+ // 'ignore' closes stdin at spawn so `claude --print` doesn't block on EOF.
69
+ stdio: ['ignore', 'pipe', 'pipe'],
70
+ windowsHide: true,
71
+ });
72
+ let stdout = '';
73
+ let stderr = '';
74
+ let settled = false;
75
+ const timer = setTimeout(() => {
76
+ if (settled)
77
+ return;
78
+ try {
79
+ child.kill('SIGTERM');
80
+ }
81
+ catch { /* may already be dead */ }
82
+ settled = true;
83
+ reject(new Error(`claude routing fallback timed out after ${timeoutMs}ms`));
84
+ }, timeoutMs);
85
+ timer.unref?.();
86
+ child.stdout?.on('data', (d) => { stdout += d.toString(); });
87
+ child.stderr?.on('data', (d) => { stderr += d.toString(); });
88
+ child.on('error', (err) => {
89
+ if (settled)
90
+ return;
91
+ settled = true;
92
+ clearTimeout(timer);
93
+ reject(err);
94
+ });
95
+ child.on('close', (code) => {
96
+ if (settled)
97
+ return;
98
+ settled = true;
99
+ clearTimeout(timer);
100
+ if (code === 0) {
101
+ resolve(stdout.trim());
102
+ }
103
+ else {
104
+ reject(new Error(stderr.trim() || `claude exited with code ${code}`));
105
+ }
106
+ });
107
+ });
108
+ }
109
+ //# sourceMappingURL=llm-caller.js.map
@@ -17,7 +17,6 @@ const DEFAULT_CONFIG = {
17
17
  priority: {
18
18
  '@monomind/security': 'critical',
19
19
  '@monomind/cli': 'high',
20
- '@monomind/embeddings': 'normal',
21
20
  },
22
21
  exclude: [],
23
22
  };
@@ -6,12 +6,8 @@ import * as semver from 'semver';
6
6
  // Known compatibility matrix between @monomind packages
7
7
  const COMPATIBILITY_MATRIX = {
8
8
  '@monomind/cli': {
9
- '@monomind/embeddings': { minVersion: '3.0.0-alpha.1' },
10
9
  '@monomind/security': { minVersion: '3.0.0-alpha.1' },
11
10
  },
12
- '@monomind/embeddings': {
13
- '@monomind/cli': { minVersion: '3.0.0-alpha.50' },
14
- },
15
11
  };
16
12
  // Known breaking changes by version
17
13
  const BREAKING_CHANGES = {
@@ -22,12 +18,6 @@ const BREAKING_CHANGES = {
22
18
  'Agent spawning now requires type parameter',
23
19
  ],
24
20
  },
25
- '@monomind/embeddings': {
26
- '3.0.0': [
27
- 'Switched from better-sqlite3 to sql.js',
28
- 'New initialization required with initEmbeddings()',
29
- ],
30
- },
31
21
  };
32
22
  export function validateUpdate(packageName, fromVersion, toVersion, installedPackages) {
33
23
  const result = {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monoes/monomindcli",
3
- "version": "1.11.5",
3
+ "version": "1.11.7",
4
4
  "type": "module",
5
5
  "description": "Monomind CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
6
6
  "main": "dist/src/index.js",
@@ -68,7 +68,6 @@
68
68
  "dist",
69
69
  "bin",
70
70
  ".claude",
71
- "bundled-graph",
72
71
  "scripts",
73
72
  "README.md"
74
73
  ],
@@ -88,26 +87,20 @@
88
87
  "dependencies": {
89
88
  "ws": "^8.18.0",
90
89
  "@noble/ed25519": "^2.1.0",
91
- "@monoes/monograph": "^1.1.0",
90
+ "@monoes/monograph": "^1.2.0",
92
91
  "@monomind/aidefence": "workspace:*",
93
- "@monomind/embeddings": "workspace:*",
94
92
  "@monomind/guidance": "workspace:*",
95
93
  "@monomind/mcp": "workspace:*",
94
+ "@monomind/routing": "workspace:*",
96
95
  "graphology": "^0.25.4",
97
- "graphology-communities-louvain": "^2.0.1",
98
96
  "graphology-metrics": "^2.4.0",
99
- "graphology-shortest-path": "^2.0.2",
100
- "graphology-traversal": "^0.3.1",
101
- "graphology-types": "^0.24.7",
102
- "chokidar": "^3.6.0",
103
97
  "semver": "^7.6.0"
104
98
  },
105
99
  "optionalDependencies": {
106
100
  "sql.js": "^1.14.1",
107
101
  "@monoes/memory": "workspace:*",
108
102
  "@monomind/plugin-gastown-bridge": "^0.1.3",
109
- "agentic-flow": "^3.0.0-alpha.1",
110
- "@anthropic-ai/sdk": "*"
103
+ "agentic-flow": "^3.0.0-alpha.1"
111
104
  },
112
105
  "publishConfig": {
113
106
  "access": "public",
@@ -140,8 +140,7 @@
140
140
  "typecheck": "tsc --noEmit"
141
141
  },
142
142
  "dependencies": {
143
- "@monomind/hooks": "workspace:*",
144
- "@monoes/memory": "workspace:*"
143
+ "@monomind/hooks": "workspace:*"
145
144
  },
146
145
  "devDependencies": {
147
146
  "@types/node": "^20.10.0",
@@ -1,73 +0,0 @@
1
- import Graph from 'graphology';
2
- // Mirrors upstream graphify's _normalize_id: lowercase + collapse non-alphanumeric to underscores.
3
- function normalizeId(s) {
4
- return s.replace(/[^a-zA-Z0-9]+/g, '_').replace(/^_+|_+$/g, '').toLowerCase();
5
- }
6
- /**
7
- * Build a graphology Graph from extracted nodes and edges.
8
- * Deduplicates nodes by id, merges parallel edges with higher weight.
9
- */
10
- export function buildGraph(extraction) {
11
- const graph = new Graph({ type: 'directed', multi: false });
12
- // Add all nodes — merge attributes if already present (dedup by id)
13
- for (const node of extraction.nodes) {
14
- if (!graph.hasNode(node.id)) {
15
- graph.addNode(node.id, { ...node });
16
- }
17
- else {
18
- graph.mergeNodeAttributes(node.id, { ...node });
19
- }
20
- }
21
- // Build normalized ID lookup to remap mismatched edge endpoints before stubbing.
22
- const normToId = new Map();
23
- graph.forEachNode((id) => {
24
- normToId.set(normalizeId(id), id);
25
- });
26
- // Add edges — skip self-loops, remap via normalization, stub only true externals
27
- for (const edge of extraction.edges) {
28
- let src = edge.source;
29
- let tgt = edge.target;
30
- if (!graph.hasNode(src)) {
31
- const remapped = normToId.get(normalizeId(src));
32
- if (remapped) {
33
- src = remapped;
34
- }
35
- else {
36
- graph.addNode(src, { id: src, label: src, fileType: 'unknown', sourceFile: '' });
37
- normToId.set(normalizeId(src), src);
38
- }
39
- }
40
- if (!graph.hasNode(tgt)) {
41
- const remapped = normToId.get(normalizeId(tgt));
42
- if (remapped) {
43
- tgt = remapped;
44
- }
45
- else {
46
- graph.addNode(tgt, { id: tgt, label: tgt, fileType: 'unknown', sourceFile: '' });
47
- normToId.set(normalizeId(tgt), tgt);
48
- }
49
- }
50
- if (src === tgt)
51
- continue;
52
- try {
53
- graph.addEdge(src, tgt, {
54
- relation: edge.relation,
55
- confidence: edge.confidence,
56
- confidenceScore: edge.confidenceScore,
57
- weight: edge.weight ?? 1,
58
- sourceFile: edge.sourceFile,
59
- sourceLocation: edge.sourceLocation,
60
- });
61
- }
62
- catch {
63
- // Edge already exists — bump its weight
64
- const existing = graph.edge(src, tgt);
65
- if (existing) {
66
- const prev = graph.getEdgeAttribute(existing, 'weight') ?? 1;
67
- graph.setEdgeAttribute(existing, 'weight', prev + 1);
68
- }
69
- }
70
- }
71
- return graph;
72
- }
73
- //# sourceMappingURL=build.js.map
@@ -1,120 +0,0 @@
1
- import Graph from 'graphology';
2
- export async function detectCommunities(graph) {
3
- let louvainFn = null;
4
- try {
5
- const mod = await import('graphology-communities-louvain');
6
- louvainFn = mod.default;
7
- }
8
- catch { /* louvain not available */ }
9
- if (louvainFn) {
10
- try {
11
- const assignment = louvainFn(graph);
12
- for (const [nodeId, communityId] of Object.entries(assignment)) {
13
- graph.setNodeAttribute(nodeId, 'community', communityId);
14
- }
15
- const communities = {};
16
- for (const [nodeId, communityId] of Object.entries(assignment)) {
17
- if (!communities[communityId])
18
- communities[communityId] = [];
19
- communities[communityId].push(nodeId);
20
- }
21
- return splitOversizedCommunities(graph, communities, 0.25, louvainFn);
22
- }
23
- catch { /* fall through */ }
24
- }
25
- return splitOversizedCommunities(graph, fallbackCluster(graph), 0.25, louvainFn);
26
- }
27
- function fallbackCluster(graph) {
28
- const dirMap = new Map();
29
- let nextId = 0;
30
- const communities = {};
31
- graph.forEachNode((id, attrs) => {
32
- const file = attrs.sourceFile || '';
33
- const parts = file.split('/');
34
- const dir = parts.length > 1 ? parts.slice(0, -1).join('/') : 'root';
35
- if (!dirMap.has(dir))
36
- dirMap.set(dir, nextId++);
37
- const cid = dirMap.get(dir);
38
- graph.setNodeAttribute(id, 'community', cid);
39
- if (!communities[cid])
40
- communities[cid] = [];
41
- communities[cid].push(id);
42
- });
43
- return communities;
44
- }
45
- export function cohesionScore(graph, communityNodes) {
46
- const memberSet = new Set(communityNodes);
47
- let totalEdges = 0;
48
- let internalEdges = 0;
49
- graph.forEachEdge((_edge, _attrs, source, target) => {
50
- const srcIn = memberSet.has(source);
51
- const tgtIn = memberSet.has(target);
52
- if (srcIn || tgtIn) {
53
- totalEdges++;
54
- if (srcIn && tgtIn)
55
- internalEdges++;
56
- }
57
- });
58
- return totalEdges === 0 ? 1.0 : internalEdges / totalEdges;
59
- }
60
- export function splitOversizedCommunities(graph, communities, threshold = 0.25, louvainFn = null) {
61
- const maxSize = threshold * graph.order;
62
- const allIds = Object.keys(communities).map(Number);
63
- let nextId = allIds.length > 0 ? Math.max(...allIds) + 1 : 0;
64
- for (const [cidStr, members] of Object.entries(communities)) {
65
- if (members.length <= maxSize)
66
- continue;
67
- const cid = Number(cidStr);
68
- // Attempt topology-based second pass via Louvain on the community subgraph
69
- if (louvainFn && members.length >= 10) {
70
- try {
71
- const memberSet = new Set(members);
72
- const subG = new Graph({ type: 'undirected', multi: false });
73
- for (const nodeId of members)
74
- subG.addNode(nodeId);
75
- graph.forEachEdge((_e, _a, source, target) => {
76
- if (memberSet.has(source) && memberSet.has(target) && source !== target && !subG.hasEdge(source, target))
77
- subG.addEdge(source, target);
78
- });
79
- const subAssignment = louvainFn(subG);
80
- const subCommunityCount = new Set(Object.values(subAssignment)).size;
81
- if (subCommunityCount > 1 && subCommunityCount <= Math.ceil(members.length / 2)) {
82
- const subIdMap = new Map();
83
- const newSubIds = {};
84
- for (const [nodeId, localId] of Object.entries(subAssignment)) {
85
- if (!subIdMap.has(localId))
86
- subIdMap.set(localId, nextId++);
87
- const globalId = subIdMap.get(localId);
88
- graph.setNodeAttribute(nodeId, 'community', globalId);
89
- if (!newSubIds[globalId])
90
- newSubIds[globalId] = [];
91
- newSubIds[globalId].push(nodeId);
92
- }
93
- delete communities[cid];
94
- Object.assign(communities, newSubIds);
95
- continue;
96
- }
97
- }
98
- catch { /* fall through to directory heuristic */ }
99
- }
100
- // Directory heuristic fallback
101
- const subMap = new Map();
102
- const newSubIds = {};
103
- for (const nodeId of members) {
104
- const file = graph.getNodeAttribute(nodeId, 'sourceFile') || '';
105
- const parts = file.split('/');
106
- const parentDir = parts.length > 1 ? parts[parts.length - 2] : 'root';
107
- if (!subMap.has(parentDir))
108
- subMap.set(parentDir, nextId++);
109
- const subId = subMap.get(parentDir);
110
- graph.setNodeAttribute(nodeId, 'community', subId);
111
- if (!newSubIds[subId])
112
- newSubIds[subId] = [];
113
- newSubIds[subId].push(nodeId);
114
- }
115
- delete communities[cid];
116
- Object.assign(communities, newSubIds);
117
- }
118
- return communities;
119
- }
120
- //# sourceMappingURL=cluster.js.map
@@ -1,57 +0,0 @@
1
- {
2
- "name": "@monomind/graph",
3
- "version": "1.4.0",
4
- "type": "module",
5
- "description": "Knowledge graph engine for monomind — AST extraction, graph construction, community detection, and persistent codebase understanding",
6
- "main": "./dist/src/index.js",
7
- "types": "./dist/src/index.d.ts",
8
- "exports": {
9
- ".": {
10
- "types": "./dist/src/index.d.ts",
11
- "import": "./dist/src/index.js"
12
- }
13
- },
14
- "files": [
15
- "dist",
16
- "src"
17
- ],
18
- "scripts": {
19
- "build": "tsc",
20
- "test": "vitest run",
21
- "clean": "rm -rf dist"
22
- },
23
- "dependencies": {
24
- "graphology": "^0.25.4",
25
- "graphology-types": "^0.24.7",
26
- "graphology-communities-louvain": "^2.0.1",
27
- "graphology-shortest-path": "^2.0.2",
28
- "graphology-traversal": "^0.3.1",
29
- "graphology-metrics": "^2.4.0",
30
- "chokidar": "^3.6.0"
31
- },
32
- "devDependencies": {
33
- "@types/node": "^20.0.0",
34
- "typescript": "^5.3.0",
35
- "vitest": "^4.1.4"
36
- },
37
- "optionalDependencies": {
38
- "node-tree-sitter": "^0.22.4",
39
- "tree-sitter-typescript": "^0.23.2",
40
- "tree-sitter-javascript": "^0.23.1",
41
- "tree-sitter-python": "^0.23.6",
42
- "tree-sitter-go": "^0.23.4",
43
- "tree-sitter-rust": "^0.23.2",
44
- "tree-sitter-java": "^0.23.5",
45
- "tree-sitter-c": "^0.23.4",
46
- "tree-sitter-cpp": "^0.23.4",
47
- "tree-sitter-ruby": "^0.23.1",
48
- "tree-sitter-c-sharp": "^0.23.1",
49
- "tree-sitter-kotlin": "^0.3.9",
50
- "tree-sitter-swift": "^0.6.1",
51
- "tree-sitter-scala": "^0.23.4",
52
- "tree-sitter-php": "^0.23.11"
53
- },
54
- "publishConfig": {
55
- "access": "public"
56
- }
57
- }
@@ -1,18 +0,0 @@
1
- /**
2
- * CLI Embeddings Command
3
- * Vector embeddings, semantic search, similarity operations
4
- *
5
- * Features:
6
- * - Multiple providers: OpenAI, Transformers.js, Agentic-Flow, Mock
7
- * - Document chunking with overlap
8
- * - L2/L1/minmax/zscore normalization
9
- * - Hyperbolic embeddings (Poincaré ball)
10
- * - Neural substrate integration
11
- * - Persistent SQLite cache
12
- *
13
- * github.com/nokhodian/monomind
14
- */
15
- import type { Command } from '../types.js';
16
- export declare const embeddingsCommand: Command;
17
- export default embeddingsCommand;
18
- //# sourceMappingURL=embeddings.d.ts.map