monomind 1.18.13 → 1.19.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (218) hide show
  1. package/.claude/agents/core/researcher.md +29 -24
  2. package/.claude/agents/github/code-review-swarm.md +1 -1
  3. package/.claude/agents/github/github-modes.md +1 -1
  4. package/.claude/agents/github/issue-tracker.md +1 -1
  5. package/.claude/agents/github/multi-repo-swarm.md +1 -1
  6. package/.claude/agents/github/pr-manager.md +1 -1
  7. package/.claude/agents/github/project-board-sync.md +1 -1
  8. package/.claude/agents/github/release-manager.md +1 -1
  9. package/.claude/agents/github/repo-architect.md +1 -1
  10. package/.claude/agents/github/swarm-issue.md +1 -1
  11. package/.claude/agents/github/swarm-pr.md +1 -1
  12. package/.claude/agents/github/sync-coordinator.md +1 -1
  13. package/.claude/agents/github/workflow-automation.md +1 -1
  14. package/.claude/agents/goal/goal-planner.md +1 -1
  15. package/.claude/agents/specialized/specialized-workflow-architect.md +11 -14
  16. package/.claude/agents/testing/production-validator.md +8 -7
  17. package/.claude/agents/testing/testing-evidence-collector.md +3 -1
  18. package/.claude/commands/mastermind/_repeat.md +22 -3
  19. package/.claude/commands/mastermind/architect.md +1 -1
  20. package/.claude/commands/mastermind/autodev.md +1 -1
  21. package/.claude/commands/mastermind/build.md +1 -1
  22. package/.claude/commands/mastermind/code-review.md +5 -5
  23. package/.claude/commands/mastermind/debug.md +1 -1
  24. package/.claude/commands/mastermind/help.md +2 -2
  25. package/.claude/commands/mastermind/idea.md +1 -1
  26. package/.claude/commands/mastermind/improve.md +1 -1
  27. package/.claude/commands/mastermind/okf-export.md +14 -0
  28. package/.claude/commands/mastermind/okf-import.md +15 -0
  29. package/.claude/commands/mastermind/plan.md +1 -1
  30. package/.claude/commands/mastermind/research.md +1 -1
  31. package/.claude/commands/mastermind/review.md +12 -1
  32. package/.claude/commands/mastermind/runorg.md +1 -1
  33. package/.claude/commands/mastermind/taskdev.md +1 -1
  34. package/.claude/commands/mastermind/tdd.md +1 -1
  35. package/.claude/commands/mastermind/verify.md +1 -1
  36. package/.claude/helpers/graphify-freshen.cjs +16 -20
  37. package/.claude/helpers/handlers/agent-start-handler.cjs +11 -36
  38. package/.claude/helpers/handlers/capture-handler.cjs +110 -0
  39. package/.claude/helpers/handlers/route-handler.cjs +180 -256
  40. package/.claude/helpers/handlers/session-handler.cjs +139 -142
  41. package/.claude/helpers/handlers/session-restore-handler.cjs +15 -10
  42. package/.claude/helpers/handlers/task-handler.cjs +8 -155
  43. package/.claude/helpers/hook-handler.cjs +89 -5
  44. package/.claude/helpers/intelligence.cjs +164 -15
  45. package/.claude/helpers/learning-service.mjs +1 -0
  46. package/.claude/helpers/mastermind-activate.cjs +33 -51
  47. package/.claude/helpers/monolean-activate.cjs +13 -3
  48. package/.claude/helpers/monolean-propagate.cjs +7 -3
  49. package/.claude/helpers/router.cjs +47 -9
  50. package/.claude/helpers/utils/monograph.cjs +37 -20
  51. package/.claude/settings.json +0 -20
  52. package/.claude/skills/mastermind-skills/_repeat.md +29 -4
  53. package/.claude/skills/mastermind-skills/architect.md +5 -6
  54. package/.claude/skills/mastermind-skills/autodev.md +8 -5
  55. package/.claude/skills/mastermind-skills/review.md +25 -11
  56. package/.claude/skills/mastermind-skills/techport.md +37 -3
  57. package/.claude/skills/monodesign/document.md +9 -6
  58. package/.claude/skills/monodesign/extract.md +1 -1
  59. package/.claude/skills/monodesign/reference/document.md +1 -1
  60. package/.claude/skills/monodesign/reference/live.md +1 -1
  61. package/.claude/skills/monolean/SKILL.md +1 -1
  62. package/package.json +1 -1
  63. package/packages/@monomind/cli/.claude/agents/core/researcher.md +29 -24
  64. package/packages/@monomind/cli/.claude/agents/github/code-review-swarm.md +1 -1
  65. package/packages/@monomind/cli/.claude/agents/github/github-modes.md +1 -1
  66. package/packages/@monomind/cli/.claude/agents/github/issue-tracker.md +1 -1
  67. package/packages/@monomind/cli/.claude/agents/github/multi-repo-swarm.md +1 -1
  68. package/packages/@monomind/cli/.claude/agents/github/pr-manager.md +1 -1
  69. package/packages/@monomind/cli/.claude/agents/github/project-board-sync.md +1 -1
  70. package/packages/@monomind/cli/.claude/agents/github/release-manager.md +1 -1
  71. package/packages/@monomind/cli/.claude/agents/github/repo-architect.md +1 -1
  72. package/packages/@monomind/cli/.claude/agents/github/swarm-issue.md +1 -1
  73. package/packages/@monomind/cli/.claude/agents/github/swarm-pr.md +1 -1
  74. package/packages/@monomind/cli/.claude/agents/github/sync-coordinator.md +1 -1
  75. package/packages/@monomind/cli/.claude/agents/github/workflow-automation.md +1 -1
  76. package/packages/@monomind/cli/.claude/agents/goal/goal-planner.md +1 -1
  77. package/packages/@monomind/cli/.claude/agents/specialized/specialized-workflow-architect.md +11 -14
  78. package/packages/@monomind/cli/.claude/agents/testing/production-validator.md +8 -7
  79. package/packages/@monomind/cli/.claude/agents/testing/testing-evidence-collector.md +3 -1
  80. package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +22 -3
  81. package/packages/@monomind/cli/.claude/commands/mastermind/architect.md +1 -1
  82. package/packages/@monomind/cli/.claude/commands/mastermind/autodev.md +1 -1
  83. package/packages/@monomind/cli/.claude/commands/mastermind/build.md +1 -1
  84. package/packages/@monomind/cli/.claude/commands/mastermind/code-review.md +5 -5
  85. package/packages/@monomind/cli/.claude/commands/mastermind/debug.md +1 -1
  86. package/packages/@monomind/cli/.claude/commands/mastermind/help.md +2 -2
  87. package/packages/@monomind/cli/.claude/commands/mastermind/idea.md +1 -1
  88. package/packages/@monomind/cli/.claude/commands/mastermind/improve.md +1 -1
  89. package/packages/@monomind/cli/.claude/commands/mastermind/okf-export.md +14 -0
  90. package/packages/@monomind/cli/.claude/commands/mastermind/okf-import.md +15 -0
  91. package/packages/@monomind/cli/.claude/commands/mastermind/plan.md +1 -1
  92. package/packages/@monomind/cli/.claude/commands/mastermind/research.md +1 -1
  93. package/packages/@monomind/cli/.claude/commands/mastermind/review.md +12 -1
  94. package/packages/@monomind/cli/.claude/commands/mastermind/runorg.md +1 -1
  95. package/packages/@monomind/cli/.claude/commands/mastermind/taskdev.md +1 -1
  96. package/packages/@monomind/cli/.claude/commands/mastermind/tdd.md +1 -1
  97. package/packages/@monomind/cli/.claude/commands/mastermind/verify.md +1 -1
  98. package/packages/@monomind/cli/.claude/helpers/graphify-freshen.cjs +16 -20
  99. package/packages/@monomind/cli/.claude/helpers/handlers/agent-start-handler.cjs +11 -36
  100. package/packages/@monomind/cli/.claude/helpers/handlers/capture-handler.cjs +110 -0
  101. package/packages/@monomind/cli/.claude/helpers/handlers/route-handler.cjs +180 -256
  102. package/packages/@monomind/cli/.claude/helpers/handlers/session-handler.cjs +139 -142
  103. package/packages/@monomind/cli/.claude/helpers/handlers/session-restore-handler.cjs +15 -10
  104. package/packages/@monomind/cli/.claude/helpers/handlers/task-handler.cjs +8 -155
  105. package/packages/@monomind/cli/.claude/helpers/hook-handler.cjs +89 -5
  106. package/packages/@monomind/cli/.claude/helpers/intelligence.cjs +164 -15
  107. package/packages/@monomind/cli/.claude/helpers/learning-service.mjs +1 -0
  108. package/packages/@monomind/cli/.claude/helpers/mastermind-activate.cjs +33 -51
  109. package/packages/@monomind/cli/.claude/helpers/monolean-activate.cjs +13 -3
  110. package/packages/@monomind/cli/.claude/helpers/monolean-propagate.cjs +7 -3
  111. package/packages/@monomind/cli/.claude/helpers/router.cjs +47 -9
  112. package/packages/@monomind/cli/.claude/helpers/utils/monograph.cjs +37 -20
  113. package/packages/@monomind/cli/.claude/skills/mastermind-skills/_repeat.md +29 -4
  114. package/packages/@monomind/cli/.claude/skills/mastermind-skills/architect.md +5 -6
  115. package/packages/@monomind/cli/.claude/skills/mastermind-skills/autodev.md +8 -5
  116. package/packages/@monomind/cli/.claude/skills/mastermind-skills/review.md +25 -11
  117. package/packages/@monomind/cli/.claude/skills/mastermind-skills/techport.md +37 -3
  118. package/packages/@monomind/cli/.claude/skills/monodesign/document.md +9 -6
  119. package/packages/@monomind/cli/.claude/skills/monodesign/extract.md +1 -1
  120. package/packages/@monomind/cli/.claude/skills/monodesign/reference/document.md +1 -1
  121. package/packages/@monomind/cli/.claude/skills/monodesign/reference/live.md +1 -1
  122. package/packages/@monomind/cli/.claude/skills/monolean/SKILL.md +1 -1
  123. package/packages/@monomind/cli/bin/mcp-server.js +11 -1
  124. package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +1 -2
  125. package/packages/@monomind/cli/dist/src/commands/agent-ops.js +1 -59
  126. package/packages/@monomind/cli/dist/src/commands/agent.js +2 -3
  127. package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +1 -1
  128. package/packages/@monomind/cli/dist/src/commands/browse-action.js +94 -2
  129. package/packages/@monomind/cli/dist/src/commands/completions.js +11 -56
  130. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +1 -1
  131. package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +1 -1
  132. package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +2 -2
  133. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +1 -3
  134. package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +2 -116
  135. package/packages/@monomind/cli/dist/src/commands/hive-mind.js +2 -5
  136. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +8 -7
  137. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +1 -1
  138. package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +2 -2
  139. package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.d.ts +0 -3
  140. package/packages/@monomind/cli/dist/src/commands/hooks-extended-commands.js +0 -307
  141. package/packages/@monomind/cli/dist/src/commands/hooks.js +1 -12
  142. package/packages/@monomind/cli/dist/src/commands/index.d.ts +3 -51
  143. package/packages/@monomind/cli/dist/src/commands/index.js +36 -184
  144. package/packages/@monomind/cli/dist/src/commands/init-wizard.js +2 -4
  145. package/packages/@monomind/cli/dist/src/commands/mcp.js +32 -4
  146. package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +1 -2
  147. package/packages/@monomind/cli/dist/src/commands/memory-admin.js +1 -118
  148. package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +1 -2
  149. package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +5 -171
  150. package/packages/@monomind/cli/dist/src/commands/memory.js +3 -6
  151. package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +3 -1
  152. package/packages/@monomind/cli/dist/src/commands/neural-core.js +145 -6
  153. package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +4 -4
  154. package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +1 -1
  155. package/packages/@monomind/cli/dist/src/commands/neural-registry.js +4 -4
  156. package/packages/@monomind/cli/dist/src/commands/neural.d.ts +1 -1
  157. package/packages/@monomind/cli/dist/src/commands/neural.js +6 -6
  158. package/packages/@monomind/cli/dist/src/commands/performance.js +68 -58
  159. package/packages/@monomind/cli/dist/src/commands/providers.js +2 -131
  160. package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +0 -1
  161. package/packages/@monomind/cli/dist/src/commands/security-misc.js +69 -45
  162. package/packages/@monomind/cli/dist/src/commands/security.js +2 -4
  163. package/packages/@monomind/cli/dist/src/commands/session.js +1 -285
  164. package/packages/@monomind/cli/dist/src/commands/start.js +2 -41
  165. package/packages/@monomind/cli/dist/src/commands/status.js +18 -29
  166. package/packages/@monomind/cli/dist/src/commands/swarm.js +1 -1
  167. package/packages/@monomind/cli/dist/src/commands/task.js +2 -49
  168. package/packages/@monomind/cli/dist/src/commands/workflow.js +2 -104
  169. package/packages/@monomind/cli/dist/src/index.js +7 -0
  170. package/packages/@monomind/cli/dist/src/init/executor.js +3 -14
  171. package/packages/@monomind/cli/dist/src/init/helpers-generator.js +2 -22
  172. package/packages/@monomind/cli/dist/src/init/settings-generator.js +0 -1
  173. package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -3
  174. package/packages/@monomind/cli/dist/src/init/types.js +0 -2
  175. package/packages/@monomind/cli/dist/src/mcp-client.js +0 -6
  176. package/packages/@monomind/cli/dist/src/mcp-server.js +16 -0
  177. package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +0 -17
  178. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/causal-infer.d.ts +5 -5
  179. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/causal-infer.js +32 -46
  180. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/consensus-verify.d.ts +2 -3
  181. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/consensus-verify.js +22 -20
  182. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/memory-gate.d.ts +3 -2
  183. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/memory-gate.js +32 -19
  184. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/quantum-topology.d.ts +4 -4
  185. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/quantum-topology.js +11 -17
  186. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/spectral-analyze.d.ts +2 -3
  187. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/spectral-analyze.js +51 -32
  188. package/packages/@monomind/cli/dist/src/mcp-tools/coherence/types.d.ts +5 -9
  189. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +2 -2
  190. package/packages/@monomind/cli/dist/src/mcp-tools/hive-mind-tools.js +25 -3
  191. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.d.ts +0 -3
  192. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-routing.js +45 -159
  193. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +1 -4
  194. package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -2
  195. package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -3
  196. package/packages/@monomind/cli/dist/src/mcp-tools/memory-tools.js +24 -0
  197. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +452 -7
  198. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +4 -10
  199. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +28 -54
  200. package/packages/@monomind/cli/dist/src/mcp-tools/performance-tools.js +5 -17
  201. package/packages/@monomind/cli/dist/src/mcp-tools/quality/coverage-analysis/prioritize-gaps.js +2 -2
  202. package/packages/@monomind/cli/dist/src/mcp-tools/quality/security-compliance/detect-secrets.d.ts +4 -4
  203. package/packages/@monomind/cli/dist/src/mcp-tools/quality-tools.d.ts +7 -2
  204. package/packages/@monomind/cli/dist/src/mcp-tools/quality-tools.js +7 -257
  205. package/packages/@monomind/cli/dist/src/memory/intelligence.d.ts +7 -8
  206. package/packages/@monomind/cli/dist/src/memory/intelligence.js +15 -16
  207. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +1 -0
  208. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +37 -0
  209. package/packages/@monomind/cli/dist/src/services/worker-daemon.d.ts +3 -21
  210. package/packages/@monomind/cli/dist/src/services/worker-daemon.js +13 -80
  211. package/packages/@monomind/cli/dist/src/suggest.js +0 -5
  212. package/packages/@monomind/cli/package.json +1 -1
  213. package/packages/@monomind/guidance/README.md +49 -1153
  214. package/packages/@monomind/guidance/package.json +1 -74
  215. package/.claude/helpers/auto-memory-hook.mjs +0 -503
  216. package/packages/@monomind/cli/.claude/helpers/auto-memory-hook.mjs +0 -503
  217. package/packages/@monomind/cli/dist/src/commands/deployment.d.ts +0 -10
  218. package/packages/@monomind/cli/dist/src/commands/deployment.js +0 -706
@@ -5,13 +5,88 @@
5
5
  * All monograph_* tools are backed by @monoes/monograph package.
6
6
  */
7
7
  import { join, resolve, sep } from 'path';
8
+ import { execSync } from 'child_process';
9
+ import { statSync } from 'fs';
10
+ import { randomUUID } from 'crypto';
8
11
  import { getProjectCwd } from './types.js';
12
+ let _cachedDbPath;
13
+ let _cachedCwd;
14
+ function _isValidDb(p) {
15
+ try {
16
+ return statSync(p).size >= 100;
17
+ }
18
+ catch {
19
+ return false;
20
+ }
21
+ }
9
22
  function getDbPath() {
10
- return join(getProjectCwd(), '.monomind', 'monograph.db');
23
+ const cwd = getProjectCwd();
24
+ // Invalidate cache when project root changes (e.g. MONOMIND_CWD set after initialize)
25
+ if (_cachedDbPath && _cachedCwd === cwd)
26
+ return _cachedDbPath;
27
+ _cachedCwd = cwd;
28
+ _cachedDbPath = undefined;
29
+ const direct = join(cwd, '.monomind', 'monograph.db');
30
+ if (_isValidDb(direct)) {
31
+ _cachedDbPath = direct;
32
+ return direct;
33
+ }
34
+ try {
35
+ const root = execSync('git rev-parse --show-toplevel', { cwd, encoding: 'utf8' }).trim();
36
+ const candidate = join(root, '.monomind', 'monograph.db');
37
+ if (_isValidDb(candidate)) {
38
+ _cachedDbPath = candidate;
39
+ return candidate;
40
+ }
41
+ }
42
+ catch { /* not in a git repo */ }
43
+ // Don't cache failures — the DB may be created by a subsequent build
44
+ return direct;
11
45
  }
12
46
  function text(t) {
13
47
  return { content: [{ type: 'text', text: t }] };
14
48
  }
49
+ // ── Active watcher registry ──────────────────────────────────────────────────
50
+ const _activeWatchers = new Map();
51
+ function applyPprRerank(db, seedNodes, damping, maxResults) {
52
+ const propagated = new Map();
53
+ for (const r of seedNodes) {
54
+ propagated.set(r.id, r.score);
55
+ }
56
+ const neighborStmt = db.prepare('SELECT target_id FROM edges WHERE source_id = @id');
57
+ for (const r of seedNodes) {
58
+ const neighbors = neighborStmt.all({ id: r.id });
59
+ for (const n of neighbors) {
60
+ const boost = r.score * damping;
61
+ const current = propagated.get(n.target_id) ?? 0;
62
+ propagated.set(n.target_id, Math.max(current, boost));
63
+ }
64
+ }
65
+ const seedIds = new Set(seedNodes.map(r => r.id));
66
+ const ranked = seedNodes.map(r => ({
67
+ ...r,
68
+ combinedScore: Math.max(r.score, propagated.get(r.id) ?? 0),
69
+ boostedByNeighbors: false,
70
+ }));
71
+ for (const [id, score] of propagated) {
72
+ if (!seedIds.has(id)) {
73
+ const node = db.prepare('SELECT id, name, label, file_path, start_line FROM nodes WHERE id = @id').get({ id });
74
+ if (node) {
75
+ ranked.push({
76
+ id: node.id, name: node.name, label: node.label,
77
+ filePath: node.file_path, startLine: node.start_line,
78
+ score: 0, combinedScore: score, boostedByNeighbors: true,
79
+ });
80
+ }
81
+ }
82
+ }
83
+ ranked.sort((a, b) => b.combinedScore - a.combinedScore);
84
+ return ranked.slice(0, maxResults).map(r => ({
85
+ id: r.id, name: r.name, label: r.label,
86
+ filePath: r.filePath, startLine: r.startLine,
87
+ score: r.combinedScore, boostedByNeighbors: r.boostedByNeighbors,
88
+ }));
89
+ }
15
90
  // ── monograph_build ───────────────────────────────────────────────────────────
16
91
  const monographBuildTool = {
17
92
  name: 'monograph_build',
@@ -50,6 +125,8 @@ const monographQueryTool = {
50
125
  query: { type: 'string', description: 'Search terms' },
51
126
  limit: { type: 'number', description: 'Max results (default 20)' },
52
127
  label: { type: 'string', description: 'Filter by node type: Class, Function, Method, etc.' },
128
+ rerank: { type: 'boolean', description: 'Apply HippoRAG-style PPR graph reranking to boost neighbors of top hits (default: true)' },
129
+ damping: { type: 'number', description: 'PPR damping factor when rerank=true (0-1, default 0.5)' },
53
130
  },
54
131
  required: ['query'],
55
132
  },
@@ -73,19 +150,49 @@ const monographQueryTool = {
73
150
  ? rawQuery.slice(0, MAX_MONOGRAPH_QUERY_LEN)
74
151
  : rawQuery;
75
152
  const label = input.label;
153
+ const rerank = input.rerank ?? true;
154
+ const damping = input.damping ?? 0.5;
76
155
  if (process.env['MONOGRAPH_EMBEDDINGS'] === 'true') {
77
- const results = await hybridQuery(db, query, { limit, label });
156
+ const results = await hybridQuery(db, query, { limit: rerank ? limit * 2 : limit, label });
78
157
  if (results.length === 0)
79
158
  return text('No results found.');
159
+ if (rerank) {
160
+ const seeds = results.map(r => ({
161
+ id: r.id, name: r.name ?? r.id, label: r.label ?? '?',
162
+ filePath: r.filePath ?? '', startLine: r.startLine ?? null,
163
+ score: r.score,
164
+ }));
165
+ const reranked = applyPprRerank(db, seeds, damping, limit);
166
+ const lines = reranked.map(r => {
167
+ const loc = r.filePath ? (r.startLine != null ? `${r.filePath}:${r.startLine}` : r.filePath) : '';
168
+ const tag = r.boostedByNeighbors ? ' [PPR-boosted]' : '';
169
+ return `[${r.label}] ${r.name} ${loc} (score: ${r.score.toFixed(4)})${tag}`;
170
+ });
171
+ return text(lines.join('\n'));
172
+ }
80
173
  const lines = results.map(r => {
81
174
  const loc = r.filePath ? (r.startLine != null ? `${r.filePath}:${r.startLine}` : r.filePath) : '';
82
175
  return `[${r.label ?? '?'}] ${r.name ?? r.id} ${loc} (score: ${r.score.toFixed(4)})`;
83
176
  });
84
177
  return text(lines.join('\n'));
85
178
  }
86
- const results = ftsSearch(db, query, limit, label);
179
+ const results = ftsSearch(db, query, rerank ? limit * 2 : limit, label);
87
180
  if (results.length === 0)
88
181
  return text('No results found.');
182
+ if (rerank) {
183
+ const seeds = results.map(r => ({
184
+ id: r.id, name: r.name, label: r.label,
185
+ filePath: r.filePath ?? '', startLine: r.startLine ?? null,
186
+ score: Math.abs(r.rank),
187
+ }));
188
+ const reranked = applyPprRerank(db, seeds, damping, limit);
189
+ const lines = reranked.map(r => {
190
+ const loc = r.filePath ? (r.startLine != null ? `${r.filePath}:${r.startLine}` : r.filePath) : '';
191
+ const tag = r.boostedByNeighbors ? ' [PPR-boosted]' : '';
192
+ return `[${r.label}] ${r.name} ${loc} (score: ${r.score.toFixed(3)})${tag}`;
193
+ });
194
+ return text(lines.join('\n'));
195
+ }
89
196
  const lines = results.map(r => {
90
197
  const loc = r.filePath ? (r.startLine != null ? `${r.filePath}:${r.startLine}` : r.filePath) : '';
91
198
  return `[${r.label}] ${r.name} ${loc} (score: ${r.rank.toFixed(3)})`;
@@ -493,11 +600,15 @@ const monographWatchTool = {
493
600
  handler: async (input) => {
494
601
  const { MonographWatcher } = await import('@monoes/monograph');
495
602
  const repoPath = input.path ?? getProjectCwd();
603
+ if (_activeWatchers.has(repoPath)) {
604
+ return text(`Monograph watcher already running for ${repoPath}.`);
605
+ }
496
606
  const watcher = new MonographWatcher(repoPath);
497
607
  watcher.on('monograph:updated', (_paths) => {
498
608
  import('@monoes/monograph').then(({ buildAsync }) => buildAsync(repoPath)).catch(() => { });
499
609
  });
500
610
  await watcher.start();
611
+ _activeWatchers.set(repoPath, watcher);
501
612
  return text(`Monograph watcher started for ${repoPath}. Watching for file changes...`);
502
613
  },
503
614
  };
@@ -505,9 +616,21 @@ const monographWatchTool = {
505
616
  const monographWatchStopTool = {
506
617
  name: 'monograph_watch_stop',
507
618
  description: 'Stop the Monograph file watcher.',
508
- inputSchema: { type: 'object', properties: {} },
509
- handler: async () => {
510
- return text('Watcher stop requested. (Restart MCP server to fully clear watchers.)');
619
+ inputSchema: {
620
+ type: 'object',
621
+ properties: {
622
+ path: { type: 'string', description: 'Repo path whose watcher to stop (defaults to project cwd)' },
623
+ },
624
+ },
625
+ handler: async (input) => {
626
+ const repoPath = input.path ?? getProjectCwd();
627
+ const watcher = _activeWatchers.get(repoPath);
628
+ if (!watcher) {
629
+ return text(`No active watcher found for ${repoPath}.`);
630
+ }
631
+ await watcher.stop();
632
+ _activeWatchers.delete(repoPath);
633
+ return text(`Monograph watcher stopped for ${repoPath}.`);
511
634
  },
512
635
  };
513
636
  // ── monograph_report ──────────────────────────────────────────────────────────
@@ -771,7 +894,7 @@ const monographExportTool = {
771
894
  required: ['format'],
772
895
  },
773
896
  handler: async (input) => {
774
- const { openDb, closeDb, toJson, toSvg, toGraphml, toCypher } = await import('@monoes/monograph');
897
+ const { openDb, closeDb, toJson, toSvg, toGraphml, toCypher, toObsidian, toCanvas } = await import('@monoes/monograph');
775
898
  const { writeFileSync, mkdirSync } = await import('fs');
776
899
  const db = openDb(getDbPath());
777
900
  try {
@@ -805,6 +928,15 @@ const monographExportTool = {
805
928
  writeFileSync(p, toCypher(nodes, edges));
806
929
  return text(`Exported Cypher to ${p}`);
807
930
  }
931
+ if (fmt === 'obsidian') {
932
+ toObsidian(nodes, edges, outDir);
933
+ return text(`Exported Obsidian vault to ${outDir}`);
934
+ }
935
+ if (fmt === 'canvas') {
936
+ const p = join(outDir, 'graph.canvas');
937
+ writeFileSync(p, toCanvas(nodes, edges));
938
+ return text(`Exported Canvas to ${p}`);
939
+ }
808
940
  return text(`Format ${fmt} export written to ${outDir}`);
809
941
  }
810
942
  finally {
@@ -2020,6 +2152,313 @@ function findStaleDist(repoPath) {
2020
2152
  findings,
2021
2153
  };
2022
2154
  }
2155
+ // ── monograph_agent_history ───────────────────────────────────────────────────
2156
+ const monographAgentHistoryTool = {
2157
+ name: 'monograph_agent_history',
2158
+ description: 'Query past agent interactions by org, type, session, or time range. Returns rows ordered by timestamp descending.',
2159
+ inputSchema: {
2160
+ type: 'object',
2161
+ properties: {
2162
+ org_name: { type: 'string', description: 'Filter by org name' },
2163
+ agent_type: { type: 'string', description: 'Filter by agent type' },
2164
+ session_id: { type: 'string', description: 'Filter by session id' },
2165
+ since: { type: 'number', description: 'Unix timestamp (ms) — only interactions after this time' },
2166
+ limit: { type: 'number', description: 'Max rows to return (default 50)' },
2167
+ },
2168
+ },
2169
+ handler: async (input) => {
2170
+ const { openDb, closeDb } = await import('@monoes/monograph');
2171
+ const db = openDb(getDbPath());
2172
+ try {
2173
+ const conditions = [];
2174
+ const params = {};
2175
+ if (typeof input.org_name === 'string') {
2176
+ conditions.push('org_name = @org_name');
2177
+ params.org_name = input.org_name;
2178
+ }
2179
+ if (typeof input.agent_type === 'string') {
2180
+ conditions.push('agent_type = @agent_type');
2181
+ params.agent_type = input.agent_type;
2182
+ }
2183
+ if (typeof input.session_id === 'string') {
2184
+ conditions.push('session_id = @session_id');
2185
+ params.session_id = input.session_id;
2186
+ }
2187
+ if (typeof input.since === 'number') {
2188
+ conditions.push('timestamp >= @since');
2189
+ params.since = input.since;
2190
+ }
2191
+ const MAX_LIMIT = 1_000;
2192
+ const rawLimit = input.limit ?? 50;
2193
+ const limit = Number.isFinite(rawLimit) && rawLimit > 0
2194
+ ? Math.min(Math.floor(rawLimit), MAX_LIMIT)
2195
+ : 50;
2196
+ params.limit = limit;
2197
+ const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
2198
+ const sql = `SELECT * FROM agent_interactions ${where} ORDER BY timestamp DESC LIMIT @limit`;
2199
+ const rows = db.prepare(sql).all(params);
2200
+ if (rows.length === 0)
2201
+ return text('No agent interactions found.');
2202
+ return text(JSON.stringify(rows, null, 2));
2203
+ }
2204
+ finally {
2205
+ closeDb(db);
2206
+ }
2207
+ },
2208
+ };
2209
+ // ── monograph_agent_patterns ──────────────────────────────────────────────────
2210
+ const monographAgentPatternsTool = {
2211
+ name: 'monograph_agent_patterns',
2212
+ description: 'Aggregate agent interaction patterns: success rates, costs, and token usage grouped by agent type, org, or session.',
2213
+ inputSchema: {
2214
+ type: 'object',
2215
+ properties: {
2216
+ group_by: {
2217
+ type: 'string',
2218
+ description: "Column to group by: 'agent_type' | 'org_name' | 'session_id'",
2219
+ },
2220
+ since: { type: 'number', description: 'Unix timestamp (ms) — only interactions after this time' },
2221
+ min_count: { type: 'number', description: 'Minimum interaction count to include in results (default 2)' },
2222
+ },
2223
+ required: ['group_by'],
2224
+ },
2225
+ handler: async (input) => {
2226
+ const groupBy = input.group_by;
2227
+ const ALLOWED_GROUP_COLUMNS = new Set(['agent_type', 'org_name', 'session_id']);
2228
+ if (!ALLOWED_GROUP_COLUMNS.has(groupBy)) {
2229
+ return text(`Invalid group_by: ${groupBy}. Must be one of: agent_type, org_name, session_id`);
2230
+ }
2231
+ const { openDb, closeDb } = await import('@monoes/monograph');
2232
+ const db = openDb(getDbPath());
2233
+ try {
2234
+ const params = {};
2235
+ const conditions = [];
2236
+ if (typeof input.since === 'number') {
2237
+ conditions.push('timestamp >= @since');
2238
+ params.since = input.since;
2239
+ }
2240
+ const minCount = typeof input.min_count === 'number' && input.min_count > 0
2241
+ ? Math.floor(input.min_count)
2242
+ : 2;
2243
+ params.min_count = minCount;
2244
+ const where = conditions.length ? `WHERE ${conditions.join(' AND ')}` : '';
2245
+ const sql = `
2246
+ SELECT
2247
+ ${groupBy} AS group_key,
2248
+ COUNT(*) AS interaction_count,
2249
+ AVG(success) AS success_rate,
2250
+ SUM(tokens_in) AS total_tokens_in,
2251
+ SUM(tokens_out) AS total_tokens_out,
2252
+ SUM(cost_usd) AS total_cost_usd,
2253
+ AVG(duration_ms) AS avg_duration_ms
2254
+ FROM agent_interactions
2255
+ ${where}
2256
+ GROUP BY ${groupBy}
2257
+ HAVING COUNT(*) >= @min_count
2258
+ ORDER BY interaction_count DESC
2259
+ `;
2260
+ const rows = db.prepare(sql).all(params);
2261
+ if (rows.length === 0)
2262
+ return text('No agent interaction patterns found.');
2263
+ return text(JSON.stringify(rows, null, 2));
2264
+ }
2265
+ finally {
2266
+ closeDb(db);
2267
+ }
2268
+ },
2269
+ };
2270
+ // ── monograph_agent_record ────────────────────────────────────────────────────
2271
+ const monographAgentRecordTool = {
2272
+ name: 'monograph_agent_record',
2273
+ description: 'Record an agent interaction (called by capture hooks).',
2274
+ inputSchema: {
2275
+ type: 'object',
2276
+ properties: {
2277
+ session_id: { type: 'string', description: 'Session id' },
2278
+ agent_type: { type: 'string', description: 'Agent type' },
2279
+ org_name: { type: 'string', description: 'Org name' },
2280
+ parent_agent: { type: 'string', description: 'Parent agent name/type, if spawned by another agent' },
2281
+ prompt_summary: { type: 'string', description: 'Short summary of the prompt given to the agent' },
2282
+ result_summary: { type: 'string', description: 'Short summary of the agent result' },
2283
+ tokens_in: { type: 'number', description: 'Input tokens consumed (default 0)' },
2284
+ tokens_out: { type: 'number', description: 'Output tokens produced (default 0)' },
2285
+ cost_usd: { type: 'number', description: 'Cost in USD (default 0)' },
2286
+ success: { type: 'boolean', description: 'Whether the interaction succeeded (default true)' },
2287
+ duration_ms: { type: 'number', description: 'Duration in milliseconds (default 0)' },
2288
+ },
2289
+ required: ['session_id', 'agent_type'],
2290
+ },
2291
+ handler: async (input) => {
2292
+ const { openDb, closeDb } = await import('@monoes/monograph');
2293
+ const db = openDb(getDbPath());
2294
+ try {
2295
+ const id = randomUUID();
2296
+ const timestamp = Date.now();
2297
+ db.prepare(`
2298
+ INSERT INTO agent_interactions (
2299
+ id, session_id, org_name, agent_type, parent_agent,
2300
+ prompt_summary, result_summary, tokens_in, tokens_out,
2301
+ cost_usd, success, duration_ms, timestamp
2302
+ ) VALUES (
2303
+ @id, @session_id, @org_name, @agent_type, @parent_agent,
2304
+ @prompt_summary, @result_summary, @tokens_in, @tokens_out,
2305
+ @cost_usd, @success, @duration_ms, @timestamp
2306
+ )
2307
+ `).run({
2308
+ id,
2309
+ session_id: input.session_id,
2310
+ org_name: input.org_name ?? null,
2311
+ agent_type: input.agent_type,
2312
+ parent_agent: input.parent_agent ?? null,
2313
+ prompt_summary: input.prompt_summary ?? null,
2314
+ result_summary: input.result_summary ?? null,
2315
+ tokens_in: input.tokens_in ?? 0,
2316
+ tokens_out: input.tokens_out ?? 0,
2317
+ cost_usd: input.cost_usd ?? 0,
2318
+ success: input.success === false ? 0 : 1,
2319
+ duration_ms: input.duration_ms ?? 0,
2320
+ timestamp,
2321
+ });
2322
+ return text(`Recorded agent interaction ${id} for ${input.agent_type} at ${timestamp}`);
2323
+ }
2324
+ finally {
2325
+ closeDb(db);
2326
+ }
2327
+ },
2328
+ };
2329
+ // ── monograph_rank_with_graph (ported from MemoryGraph) ──────────────────────
2330
+ const monographRankWithGraphTool = {
2331
+ name: 'monograph_rank_with_graph',
2332
+ description: 'Blend BM25/vector search scores with PageRank for graph-aware ranking. Ported from MemoryGraph.rankWithGraph (HippoRAG-inspired).',
2333
+ inputSchema: {
2334
+ type: 'object',
2335
+ properties: {
2336
+ query: { type: 'string', description: 'Search query to run through monograph_query first' },
2337
+ alpha: { type: 'number', description: 'Weight for search score vs PageRank (0-1, default 0.7 = 70% search, 30% PageRank)' },
2338
+ limit: { type: 'number', description: 'Max results (default 20)' },
2339
+ },
2340
+ required: ['query'],
2341
+ },
2342
+ handler: async (input) => {
2343
+ const { openDb, closeDb, pageRank } = await import('@monoes/monograph');
2344
+ const db = openDb(getDbPath());
2345
+ try {
2346
+ const alpha = input.alpha ?? 0.7;
2347
+ const limit = input.limit ?? 20;
2348
+ const query = input.query;
2349
+ const searchResults = db.prepare(`
2350
+ SELECT n.id, n.name, n.label, n.file_path, n.start_line, n.community_id,
2351
+ bm25(nodes_fts) AS score
2352
+ FROM nodes_fts
2353
+ JOIN nodes n ON n.id = nodes_fts.rowid
2354
+ WHERE nodes_fts MATCH @query
2355
+ ORDER BY bm25(nodes_fts)
2356
+ LIMIT @limit
2357
+ `).all({ query, limit: limit * 2 });
2358
+ if (searchResults.length === 0)
2359
+ return text('No results found.');
2360
+ const ranks = pageRank(db);
2361
+ const N = ranks.size || 1;
2362
+ const ranked = searchResults.map(r => {
2363
+ const pr = ranks.get(r.id) ?? 0;
2364
+ return {
2365
+ ...r,
2366
+ pageRank: pr,
2367
+ combinedScore: alpha * Math.abs(r.score) + (1 - alpha) * (pr * N),
2368
+ };
2369
+ }).sort((a, b) => b.combinedScore - a.combinedScore).slice(0, limit);
2370
+ return text(JSON.stringify(ranked, null, 2));
2371
+ }
2372
+ finally {
2373
+ closeDb(db);
2374
+ }
2375
+ },
2376
+ };
2377
+ // ── monograph_community_summaries (ported from MemoryGraph) ──────────────────
2378
+ const monographCommunitySummariesTool = {
2379
+ name: 'monograph_community_summaries',
2380
+ description: 'GraphRAG-style community summaries: top-K communities by average PageRank with member counts and top nodes. Ported from MemoryGraph.getCommunitySummaries.',
2381
+ inputSchema: {
2382
+ type: 'object',
2383
+ properties: {
2384
+ top_k: { type: 'number', description: 'Number of top communities to return (default 5)' },
2385
+ },
2386
+ },
2387
+ handler: async (input) => {
2388
+ const { openDb, closeDb, pageRank } = await import('@monoes/monograph');
2389
+ const db = openDb(getDbPath());
2390
+ try {
2391
+ const topK = input.top_k ?? 5;
2392
+ const ranks = pageRank(db);
2393
+ const rows = db.prepare(`SELECT id, community_id FROM nodes WHERE community_id IS NOT NULL`).all();
2394
+ const communityMap = new Map();
2395
+ for (const row of rows) {
2396
+ const rank = ranks.get(row.id) ?? 0;
2397
+ const entry = communityMap.get(row.community_id) ?? { nodeIds: [], rankSum: 0 };
2398
+ entry.nodeIds.push(row.id);
2399
+ entry.rankSum += rank;
2400
+ communityMap.set(row.community_id, entry);
2401
+ }
2402
+ const summaries = [...communityMap.entries()]
2403
+ .map(([communityId, { nodeIds, rankSum }]) => ({
2404
+ communityId,
2405
+ nodeCount: nodeIds.length,
2406
+ topNodeIds: nodeIds.slice(0, 3),
2407
+ avgPageRank: nodeIds.length > 0 ? rankSum / nodeIds.length : 0,
2408
+ }))
2409
+ .sort((a, b) => b.avgPageRank - a.avgPageRank)
2410
+ .slice(0, topK);
2411
+ return text(JSON.stringify(summaries, null, 2));
2412
+ }
2413
+ finally {
2414
+ closeDb(db);
2415
+ }
2416
+ },
2417
+ };
2418
+ // ── monograph_ppr_rerank (ported from MemoryGraph) ───────────────────────────
2419
+ const monographPprRerankTool = {
2420
+ name: 'monograph_ppr_rerank',
2421
+ description: 'HippoRAG-style PPR re-ranking: search, then expand one hop through edges and boost neighbor scores. Ported from MemoryGraph.pprRerank (arXiv:2405.14831).',
2422
+ inputSchema: {
2423
+ type: 'object',
2424
+ properties: {
2425
+ query: { type: 'string', description: 'Search query' },
2426
+ damping: { type: 'number', description: 'Score propagation damping factor (default 0.5)' },
2427
+ limit: { type: 'number', description: 'Max results (default 20)' },
2428
+ },
2429
+ required: ['query'],
2430
+ },
2431
+ handler: async (input) => {
2432
+ const { openDb, closeDb } = await import('@monoes/monograph');
2433
+ const db = openDb(getDbPath());
2434
+ try {
2435
+ const damping = input.damping ?? 0.5;
2436
+ const limit = input.limit ?? 20;
2437
+ const query = input.query;
2438
+ const searchResults = db.prepare(`
2439
+ SELECT n.id, n.name, n.label, n.file_path, n.start_line,
2440
+ bm25(nodes_fts) AS score
2441
+ FROM nodes_fts
2442
+ JOIN nodes n ON n.id = nodes_fts.rowid
2443
+ WHERE nodes_fts MATCH @query
2444
+ ORDER BY bm25(nodes_fts)
2445
+ LIMIT @limit
2446
+ `).all({ query, limit: limit * 2 });
2447
+ if (searchResults.length === 0)
2448
+ return text('No results found.');
2449
+ const seeds = searchResults.map(r => ({
2450
+ id: r.id, name: r.name, label: r.label,
2451
+ filePath: r.file_path, startLine: r.start_line ?? null,
2452
+ score: Math.abs(r.score),
2453
+ }));
2454
+ const reranked = applyPprRerank(db, seeds, damping, limit);
2455
+ return text(JSON.stringify(reranked, null, 2));
2456
+ }
2457
+ finally {
2458
+ closeDb(db);
2459
+ }
2460
+ },
2461
+ };
2023
2462
  export const monographTools = [
2024
2463
  monographBuildTool,
2025
2464
  monographQueryTool,
@@ -2066,5 +2505,11 @@ export const monographTools = [
2066
2505
  monographGroupContractsTool,
2067
2506
  monographGroupStatusTool,
2068
2507
  monographDeadCodeTool,
2508
+ monographAgentHistoryTool,
2509
+ monographAgentPatternsTool,
2510
+ monographAgentRecordTool,
2511
+ monographRankWithGraphTool,
2512
+ monographCommunitySummariesTool,
2513
+ monographPprRerankTool,
2069
2514
  ];
2070
2515
  //# sourceMappingURL=monograph-tools.js.map
@@ -1,15 +1,9 @@
1
1
  /**
2
- * Neural MCP Tools for CLI
2
+ * Pattern Store MCP Tools
3
3
  *
4
- * V2 Compatibility - Neural network and ML tools
5
- *
6
- * HYBRID Implementation:
7
- * - Uses monovector ONNX embeddings when available
8
- * - Falls back to deterministic hash-based embeddings otherwise
9
- * - Pattern storage and search with cosine similarity (real math in all tiers)
10
- * - Training stores patterns as searchable embeddings (not simulated)
11
- *
12
- * Note: The lean build has no neural training. The full loop lives on monoes-full-loop.
4
+ * Embed text as vectors, store patterns, search by cosine similarity.
5
+ * Uses monovector ONNX embeddings when available, deterministic hash fallback otherwise.
6
+ * Tools are registered under the "neural" namespace for backwards compatibility.
13
7
  */
14
8
  import { type MCPTool } from './types.js';
15
9
  export declare const neuralTools: MCPTool[];