monomind 1.10.57 → 1.11.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 (232) hide show
  1. package/.claude/agents/core/coordinator.md +71 -0
  2. package/.claude/agents/generated/case-analyst.md +50 -0
  3. package/.claude/agents/generated/copy-editor.md +45 -0
  4. package/.claude/agents/generated/court-reporter.md +50 -0
  5. package/.claude/agents/generated/defender.md +51 -0
  6. package/.claude/agents/generated/editor-in-chief.md +45 -0
  7. package/.claude/agents/generated/fact-checker.md +45 -0
  8. package/.claude/agents/generated/judge.md +51 -0
  9. package/.claude/agents/generated/prosecutor.md +51 -0
  10. package/.claude/agents/generated/reporter.md +45 -0
  11. package/.claude/commands/hooks/README.md +1 -1
  12. package/.claude/commands/hooks/overview.md +1 -1
  13. package/.claude/commands/mastermind/_repeat.md +1 -1
  14. package/.claude/commands/mastermind/do.md +3 -1
  15. package/.claude/commands/mastermind/help.md +2 -2
  16. package/.claude/commands/mastermind/master.md +39 -6
  17. package/.claude/commands/mastermind/memory.md +1 -1
  18. package/.claude/commands/memory/memory-search.md +2 -2
  19. package/.claude/commands/monitoring/status.md +1 -1
  20. package/.claude/commands/{browse.md → monobrowse.md} +2 -2
  21. package/.claude/commands/sparc.md +1 -1
  22. package/.claude/helpers/handlers/graph-status-handler.cjs +1 -1
  23. package/.claude/helpers/loop-tracker.cjs +1 -1
  24. package/.claude/scheduled_tasks.lock +1 -1
  25. package/.claude/skills/agent-browser-testing/SKILL.md +1 -1
  26. package/.claude/skills/hooks-automation/SKILL.md +0 -3
  27. package/.claude/skills/mastermind/build.md +1 -1
  28. package/.claude/skills/mastermind/code-quality-reviewer-prompt.md +60 -0
  29. package/.claude/skills/mastermind/content.md +1 -1
  30. package/.claude/skills/mastermind/createorg.md +79 -2
  31. package/.claude/skills/mastermind/design.md +3 -1
  32. package/.claude/skills/mastermind/finance.md +1 -1
  33. package/.claude/skills/mastermind/implementer-prompt.md +109 -0
  34. package/.claude/skills/mastermind/marketing.md +1 -1
  35. package/.claude/skills/mastermind/ops.md +1 -1
  36. package/.claude/skills/mastermind/plan.md +20 -2
  37. package/.claude/skills/mastermind/release.md +1 -1
  38. package/.claude/skills/mastermind/research.md +1 -1
  39. package/.claude/skills/mastermind/review.md +1 -1
  40. package/.claude/skills/mastermind/sales.md +1 -1
  41. package/.claude/skills/mastermind/spec-reviewer-prompt.md +63 -0
  42. package/.claude/skills/sparc-methodology/SKILL.md +3 -3
  43. package/.claude/skills/swarm-advanced/SKILL.md +1 -4
  44. package/.claude-plugin/README.md +1 -2
  45. package/.claude-plugin/docs/PLUGIN_SUMMARY.md +0 -1
  46. package/README.md +18 -32
  47. package/package.json +1 -1
  48. package/packages/@monomind/cli/README.md +18 -32
  49. package/packages/@monomind/cli/dist/src/agents/registry-builder.d.ts +1 -7
  50. package/packages/@monomind/cli/dist/src/agents/registry-builder.js +10 -6
  51. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.d.ts +59 -12
  52. package/packages/@monomind/cli/dist/src/benchmarks/benchmark-runner.js +67 -13
  53. package/packages/@monomind/cli/dist/src/benchmarks/pretrain/index.d.ts +0 -13
  54. package/packages/@monomind/cli/dist/src/commands/agent-wasm.d.ts +2 -2
  55. package/packages/@monomind/cli/dist/src/commands/agent-wasm.js +5 -5
  56. package/packages/@monomind/cli/dist/src/commands/agent.js +1 -6
  57. package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +1 -1
  58. package/packages/@monomind/cli/dist/src/commands/analyze.js +8 -18
  59. package/packages/@monomind/cli/dist/src/commands/doctor.js +53 -3
  60. package/packages/@monomind/cli/dist/src/commands/embeddings.js +9 -33
  61. package/packages/@monomind/cli/dist/src/commands/hooks.js +24 -76
  62. package/packages/@monomind/cli/dist/src/commands/index.d.ts +4 -6
  63. package/packages/@monomind/cli/dist/src/commands/index.js +8 -15
  64. package/packages/@monomind/cli/dist/src/commands/init.js +2 -2
  65. package/packages/@monomind/cli/dist/src/commands/issues.js +16 -11
  66. package/packages/@monomind/cli/dist/src/commands/memory.js +6 -6
  67. package/packages/@monomind/cli/dist/src/commands/migrate.js +1 -2
  68. package/packages/@monomind/cli/dist/src/commands/monograph.js +18 -11
  69. package/packages/@monomind/cli/dist/src/commands/monovector/backup.d.ts +11 -0
  70. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/backup.js +25 -25
  71. package/packages/@monomind/cli/dist/src/commands/monovector/benchmark.d.ts +11 -0
  72. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/benchmark.js +14 -14
  73. package/packages/@monomind/cli/dist/src/commands/monovector/import.d.ts +18 -0
  74. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/import.js +21 -21
  75. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/index.d.ts +6 -6
  76. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/index.js +22 -22
  77. package/packages/@monomind/cli/dist/src/commands/monovector/init.d.ts +11 -0
  78. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/init.js +36 -36
  79. package/packages/@monomind/cli/dist/src/commands/monovector/migrate.d.ts +11 -0
  80. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/migrate.js +16 -16
  81. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/optimize.d.ts +2 -2
  82. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/optimize.js +10 -10
  83. package/packages/@monomind/cli/dist/src/commands/monovector/setup.d.ts +18 -0
  84. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/setup.js +77 -77
  85. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/status.d.ts +2 -2
  86. package/packages/@monomind/cli/dist/src/commands/{ruvector → monovector}/status.js +34 -34
  87. package/packages/@monomind/cli/dist/src/commands/neural.d.ts +1 -1
  88. package/packages/@monomind/cli/dist/src/commands/neural.js +31 -608
  89. package/packages/@monomind/cli/dist/src/commands/performance.js +7 -10
  90. package/packages/@monomind/cli/dist/src/commands/plugins.js +3 -4
  91. package/packages/@monomind/cli/dist/src/commands/process.js +5 -12
  92. package/packages/@monomind/cli/dist/src/commands/progress.js +16 -16
  93. package/packages/@monomind/cli/dist/src/commands/route.d.ts +2 -2
  94. package/packages/@monomind/cli/dist/src/commands/route.js +23 -23
  95. package/packages/@monomind/cli/dist/src/commands/status.js +0 -3
  96. package/packages/@monomind/cli/dist/src/commands/swarm.js +2 -3
  97. package/packages/@monomind/cli/dist/src/config-adapter.js +27 -0
  98. package/packages/@monomind/cli/dist/src/consensus/audit-writer.d.ts +44 -17
  99. package/packages/@monomind/cli/dist/src/dlq/dlq-replayer.d.ts +1 -1
  100. package/packages/@monomind/cli/dist/src/index.js +5 -5
  101. package/packages/@monomind/cli/dist/src/init/claudemd-generator.js +10 -14
  102. package/packages/@monomind/cli/dist/src/init/executor.js +17 -27
  103. package/packages/@monomind/cli/dist/src/init/helpers-generator.js +2 -2
  104. package/packages/@monomind/cli/dist/src/init/types.d.ts +1 -1
  105. package/packages/@monomind/cli/dist/src/mcp-client.js +1 -7
  106. package/packages/@monomind/cli/dist/src/mcp-server.js +9 -1
  107. package/packages/@monomind/cli/dist/src/mcp-tools/agent-tools.js +1 -52
  108. package/packages/@monomind/cli/dist/src/mcp-tools/analyze-tools.js +5 -5
  109. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.d.ts +1 -1
  110. package/packages/@monomind/cli/dist/src/mcp-tools/browser-tools.js +6 -5
  111. package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.d.ts +1 -1
  112. package/packages/@monomind/cli/dist/src/mcp-tools/coordination-tools.js +51 -54
  113. package/packages/@monomind/cli/dist/src/mcp-tools/daa-tools.d.ts +1 -1
  114. package/packages/@monomind/cli/dist/src/mcp-tools/embeddings-tools.js +10 -10
  115. package/packages/@monomind/cli/dist/src/mcp-tools/guidance-tools.js +0 -24
  116. package/packages/@monomind/cli/dist/src/mcp-tools/hooks-tools.js +189 -480
  117. package/packages/@monomind/cli/dist/src/mcp-tools/index.d.ts +0 -2
  118. package/packages/@monomind/cli/dist/src/mcp-tools/index.js +0 -2
  119. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.d.ts +334 -0
  120. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-compat.js +1108 -0
  121. package/packages/@monomind/cli/dist/src/mcp-tools/monograph-tools.js +76 -34
  122. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.d.ts +1 -1
  123. package/packages/@monomind/cli/dist/src/mcp-tools/neural-tools.js +2 -2
  124. package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.d.ts +2 -2
  125. package/packages/@monomind/cli/dist/src/mcp-tools/ruvllm-tools.js +3 -3
  126. package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.d.ts +1 -1
  127. package/packages/@monomind/cli/dist/src/mcp-tools/terminal-tools.js +29 -19
  128. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.d.ts +1 -1
  129. package/packages/@monomind/cli/dist/src/mcp-tools/wasm-agent-tools.js +2 -2
  130. package/packages/@monomind/cli/dist/src/memory/intelligence.js +14 -8
  131. package/packages/@monomind/cli/dist/src/memory/memory-bridge.d.ts +17 -2
  132. package/packages/@monomind/cli/dist/src/memory/memory-bridge.js +76 -23
  133. package/packages/@monomind/cli/dist/src/memory/memory-initializer.d.ts +2 -2
  134. package/packages/@monomind/cli/dist/src/memory/memory-initializer.js +37 -39
  135. package/packages/@monomind/cli/dist/src/monovector/capabilities.d.ts +34 -0
  136. package/packages/@monomind/cli/dist/src/monovector/capabilities.js +37 -0
  137. package/packages/@monomind/cli/dist/src/monovector/command-outcomes.d.ts +37 -0
  138. package/packages/@monomind/cli/dist/src/monovector/command-outcomes.js +87 -0
  139. package/packages/@monomind/cli/dist/src/monovector/coverage-router.d.ts +103 -0
  140. package/packages/@monomind/cli/dist/src/monovector/coverage-router.js +337 -0
  141. package/packages/@monomind/cli/dist/src/monovector/coverage-tools.d.ts +14 -0
  142. package/packages/@monomind/cli/dist/src/monovector/coverage-tools.js +112 -0
  143. package/packages/@monomind/cli/dist/src/{ruvector → monovector}/diff-classifier.d.ts +2 -2
  144. package/packages/@monomind/cli/dist/src/monovector/index.d.ts +61 -0
  145. package/packages/@monomind/cli/dist/src/monovector/index.js +67 -0
  146. package/packages/@monomind/cli/dist/src/monovector/init-state.d.ts +35 -0
  147. package/packages/@monomind/cli/dist/src/monovector/init-state.js +36 -0
  148. package/packages/@monomind/cli/dist/src/monovector/route-outcomes.d.ts +55 -0
  149. package/packages/@monomind/cli/dist/src/monovector/route-outcomes.js +137 -0
  150. package/packages/@monomind/cli/dist/src/parser.js +3 -3
  151. package/packages/@monomind/cli/dist/src/plugins/store/discovery.js +0 -31
  152. package/packages/@monomind/cli/dist/src/production/circuit-breaker.d.ts +26 -6
  153. package/packages/@monomind/cli/dist/src/production/error-handler.d.ts +55 -30
  154. package/packages/@monomind/cli/dist/src/production/index.d.ts +3 -20
  155. package/packages/@monomind/cli/dist/src/production/index.js +3 -15
  156. package/packages/@monomind/cli/dist/src/production/monitoring.d.ts +54 -34
  157. package/packages/@monomind/cli/dist/src/production/monitoring.js +12 -14
  158. package/packages/@monomind/cli/dist/src/production/rate-limiter.d.ts +64 -19
  159. package/packages/@monomind/cli/dist/src/production/rate-limiter.js +5 -5
  160. package/packages/@monomind/cli/dist/src/production/retry.js +4 -2
  161. package/packages/@monomind/cli/dist/src/services/claim-service.d.ts +50 -59
  162. package/packages/@monomind/cli/dist/src/services/claim-service.js +83 -50
  163. package/packages/@monomind/cli/dist/src/services/config-file-manager.js +8 -1
  164. package/packages/@monomind/cli/dist/src/services/worker-daemon.js +4 -0
  165. package/packages/@monomind/cli/dist/src/types.d.ts +13 -0
  166. package/packages/@monomind/cli/package.json +13 -13
  167. package/packages/@monomind/guidance/dist/index.d.ts +1 -1
  168. package/packages/@monomind/guidance/dist/index.js +1 -1
  169. package/packages/@monomind/guidance/package.json +1 -2
  170. package/scripts/build-monovector.sh +10 -0
  171. package/scripts/publish-monovector.sh +20 -0
  172. package/.claude/commands/monomind/adr.md +0 -11
  173. package/.claude/commands/monomind/budget.md +0 -7
  174. package/.claude/commands/monomind/createtask.md +0 -277
  175. package/.claude/commands/monomind/do.md +0 -498
  176. package/.claude/commands/monomind/graph-status.md +0 -7
  177. package/.claude/commands/monomind/help.md +0 -118
  178. package/.claude/commands/monomind/idea.md +0 -273
  179. package/.claude/commands/monomind/improve.md +0 -352
  180. package/.claude/commands/monomind/loops.md +0 -7
  181. package/.claude/commands/monomind/memory.md +0 -230
  182. package/.claude/commands/monomind/repeat.md +0 -257
  183. package/.claude/commands/monomind/review.md +0 -317
  184. package/.claude/commands/monomind/specialagents.md +0 -125
  185. package/.claude/commands/monomind/swarm.md +0 -161
  186. package/.claude/commands/monomind/understand.md +0 -139
  187. package/.claude/commands/training/README.md +0 -39
  188. package/.claude/commands/training/neural-patterns.md +0 -73
  189. package/.claude/commands/training/neural-train.md +0 -79
  190. package/packages/@monomind/cli/dist/src/commands/appliance-advanced.d.ts +0 -9
  191. package/packages/@monomind/cli/dist/src/commands/appliance-advanced.js +0 -238
  192. package/packages/@monomind/cli/dist/src/commands/appliance.d.ts +0 -8
  193. package/packages/@monomind/cli/dist/src/commands/appliance.js +0 -406
  194. package/packages/@monomind/cli/dist/src/commands/ruvector/backup.d.ts +0 -11
  195. package/packages/@monomind/cli/dist/src/commands/ruvector/benchmark.d.ts +0 -11
  196. package/packages/@monomind/cli/dist/src/commands/ruvector/import.d.ts +0 -18
  197. package/packages/@monomind/cli/dist/src/commands/ruvector/init.d.ts +0 -11
  198. package/packages/@monomind/cli/dist/src/commands/ruvector/migrate.d.ts +0 -11
  199. package/packages/@monomind/cli/dist/src/commands/ruvector/setup.d.ts +0 -18
  200. package/packages/@monomind/cli/dist/src/ruvector/agent-wasm.d.ts +0 -182
  201. package/packages/@monomind/cli/dist/src/ruvector/agent-wasm.js +0 -316
  202. package/packages/@monomind/cli/dist/src/ruvector/ast-analyzer.d.ts +0 -67
  203. package/packages/@monomind/cli/dist/src/ruvector/ast-analyzer.js +0 -277
  204. package/packages/@monomind/cli/dist/src/ruvector/coverage-router.d.ts +0 -160
  205. package/packages/@monomind/cli/dist/src/ruvector/coverage-router.js +0 -539
  206. package/packages/@monomind/cli/dist/src/ruvector/coverage-tools.d.ts +0 -33
  207. package/packages/@monomind/cli/dist/src/ruvector/coverage-tools.js +0 -157
  208. package/packages/@monomind/cli/dist/src/ruvector/enhanced-model-router.d.ts +0 -146
  209. package/packages/@monomind/cli/dist/src/ruvector/enhanced-model-router.js +0 -551
  210. package/packages/@monomind/cli/dist/src/ruvector/flash-attention.d.ts +0 -195
  211. package/packages/@monomind/cli/dist/src/ruvector/flash-attention.js +0 -643
  212. package/packages/@monomind/cli/dist/src/ruvector/graph-analyzer.d.ts +0 -187
  213. package/packages/@monomind/cli/dist/src/ruvector/graph-analyzer.js +0 -929
  214. package/packages/@monomind/cli/dist/src/ruvector/index.d.ts +0 -67
  215. package/packages/@monomind/cli/dist/src/ruvector/index.js +0 -88
  216. package/packages/@monomind/cli/dist/src/ruvector/lora-adapter.d.ts +0 -218
  217. package/packages/@monomind/cli/dist/src/ruvector/lora-adapter.js +0 -455
  218. package/packages/@monomind/cli/dist/src/ruvector/model-router.d.ts +0 -222
  219. package/packages/@monomind/cli/dist/src/ruvector/model-router.js +0 -512
  220. package/packages/@monomind/cli/dist/src/ruvector/moe-router.d.ts +0 -213
  221. package/packages/@monomind/cli/dist/src/ruvector/moe-router.js +0 -649
  222. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.d.ts +0 -217
  223. package/packages/@monomind/cli/dist/src/ruvector/q-learning-router.js +0 -712
  224. package/packages/@monomind/cli/dist/src/ruvector/ruvllm-wasm.d.ts +0 -179
  225. package/packages/@monomind/cli/dist/src/ruvector/ruvllm-wasm.js +0 -363
  226. package/packages/@monomind/cli/dist/src/ruvector/semantic-router.d.ts +0 -77
  227. package/packages/@monomind/cli/dist/src/ruvector/semantic-router.js +0 -178
  228. package/packages/@monomind/cli/dist/src/ruvector/vector-db.d.ts +0 -69
  229. package/packages/@monomind/cli/dist/src/ruvector/vector-db.js +0 -243
  230. package/packages/@monomind/cli/dist/src/services/ruvector-training.d.ts +0 -222
  231. package/packages/@monomind/cli/dist/src/services/ruvector-training.js +0 -696
  232. /package/packages/@monomind/cli/dist/src/{ruvector → monovector}/diff-classifier.js +0 -0
@@ -1,160 +0,0 @@
1
- /**
2
- * Coverage Router for Test Routing
3
- *
4
- * Optimizations:
5
- * - Async file I/O for non-blocking coverage loading
6
- * - TTL-based caching of coverage data
7
- * - Singleton router instance
8
- */
9
- /**
10
- * Clear coverage cache
11
- */
12
- export declare function clearCoverageCache(): void;
13
- /**
14
- * Get coverage cache stats
15
- */
16
- export declare function getCoverageCacheStats(): {
17
- size: number;
18
- };
19
- export interface CoverageRouterConfig {
20
- minCoverage: number;
21
- targetCoverage: number;
22
- incremental: boolean;
23
- coverageTypes: ('line' | 'branch' | 'function' | 'statement')[];
24
- }
25
- export interface FileCoverage {
26
- path: string;
27
- lineCoverage: number;
28
- branchCoverage: number;
29
- functionCoverage: number;
30
- statementCoverage: number;
31
- uncoveredLines: number[];
32
- totalLines: number;
33
- coveredLines: number;
34
- }
35
- export interface CoverageReport {
36
- overall: number;
37
- byType: {
38
- line: number;
39
- branch: number;
40
- function: number;
41
- statement: number;
42
- };
43
- byFile: FileCoverage[];
44
- lowestCoverage: FileCoverage[];
45
- highestCoverage: FileCoverage[];
46
- uncoveredCritical: string[];
47
- timestamp: number;
48
- }
49
- export interface CoverageRouteResult {
50
- action: 'add-tests' | 'review-coverage' | 'skip' | 'prioritize';
51
- priority: number;
52
- targetFiles: string[];
53
- testTypes: ('unit' | 'integration' | 'e2e')[];
54
- gaps: Array<{
55
- file: string;
56
- currentCoverage: number;
57
- targetCoverage: number;
58
- gap: number;
59
- suggestedTests: string[];
60
- }>;
61
- estimatedEffort: number;
62
- impactScore: number;
63
- }
64
- export declare class CoverageRouter {
65
- private config;
66
- private ruvectorEngine;
67
- private useNative;
68
- private coverageHistory;
69
- constructor(config?: Partial<CoverageRouterConfig>);
70
- initialize(): Promise<void>;
71
- parseCoverage(data: unknown, format?: 'lcov' | 'istanbul' | 'cobertura' | 'json'): CoverageReport;
72
- route(coverage: CoverageReport, changedFiles?: string[]): CoverageRouteResult;
73
- getTrend(): {
74
- direction: 'up' | 'down' | 'stable';
75
- change: number;
76
- };
77
- addToHistory(report: CoverageReport): void;
78
- getStats(): Record<string, number | boolean>;
79
- private parseLcov;
80
- private parseIstanbul;
81
- private parseCobertura;
82
- private parseJson;
83
- private finalizeFileCoverage;
84
- private buildReport;
85
- private findCriticalUncovered;
86
- private calculateGaps;
87
- private suggestTests;
88
- private prioritizeFiles;
89
- private determineAction;
90
- private calculatePriority;
91
- private recommendTestTypes;
92
- private estimateEffort;
93
- private calculateImpact;
94
- }
95
- export declare function createCoverageRouter(config?: Partial<CoverageRouterConfig>): CoverageRouter;
96
- /**
97
- * Coverage suggestion result
98
- */
99
- export interface CoverageSuggestResult {
100
- path: string;
101
- suggestions: Array<{
102
- file: string;
103
- currentCoverage: number;
104
- targetCoverage: number;
105
- gap: number;
106
- priority: number;
107
- suggestedTests: string[];
108
- }>;
109
- totalGap: number;
110
- estimatedEffort: number;
111
- }
112
- /**
113
- * Coverage gaps result
114
- */
115
- export interface CoverageGapsResult {
116
- totalGaps: number;
117
- gaps: Array<{
118
- file: string;
119
- currentCoverage: number;
120
- targetCoverage: number;
121
- gap: number;
122
- priority: number;
123
- suggestedAgent: string;
124
- }>;
125
- byAgent: Record<string, string[]>;
126
- summary: string;
127
- }
128
- /**
129
- * Coverage route options
130
- */
131
- export interface CoverageRouteOptions {
132
- projectRoot?: string;
133
- threshold?: number;
134
- useRuvector?: boolean;
135
- }
136
- /**
137
- * Coverage suggest options
138
- */
139
- export interface CoverageSuggestOptions extends CoverageRouteOptions {
140
- limit?: number;
141
- }
142
- /**
143
- * Coverage gaps options
144
- */
145
- export interface CoverageGapsOptions extends CoverageRouteOptions {
146
- groupByAgent?: boolean;
147
- }
148
- /**
149
- * Route a task based on coverage analysis
150
- */
151
- export declare function coverageRoute(task: string, options?: CoverageRouteOptions): Promise<CoverageRouteResult>;
152
- /**
153
- * Suggest coverage improvements for a path
154
- */
155
- export declare function coverageSuggest(path: string, options?: CoverageSuggestOptions): Promise<CoverageSuggestResult>;
156
- /**
157
- * List all coverage gaps with agent assignments
158
- */
159
- export declare function coverageGaps(options?: CoverageGapsOptions): Promise<CoverageGapsResult>;
160
- //# sourceMappingURL=coverage-router.d.ts.map
@@ -1,539 +0,0 @@
1
- /**
2
- * Coverage Router for Test Routing
3
- *
4
- * Optimizations:
5
- * - Async file I/O for non-blocking coverage loading
6
- * - TTL-based caching of coverage data
7
- * - Singleton router instance
8
- */
9
- // ============================================================================
10
- // Caching for Performance
11
- // ============================================================================
12
- import { existsSync } from 'node:fs';
13
- import { readFile } from 'node:fs/promises';
14
- import { resolve, normalize, isAbsolute, join } from 'node:path';
15
- /**
16
- * Cache for coverage data (1 minute TTL)
17
- */
18
- const coverageDataCache = new Map();
19
- const COVERAGE_CACHE_TTL_MS = 60 * 1000; // 1 minute
20
- const COVERAGE_CACHE_MAX = 50;
21
- /**
22
- * Clear coverage cache
23
- */
24
- export function clearCoverageCache() {
25
- coverageDataCache.clear();
26
- }
27
- /**
28
- * Get coverage cache stats
29
- */
30
- export function getCoverageCacheStats() {
31
- return { size: coverageDataCache.size };
32
- }
33
- const DEFAULT_CONFIG = {
34
- minCoverage: 70,
35
- targetCoverage: 85,
36
- incremental: true,
37
- coverageTypes: ['line', 'branch', 'function', 'statement'],
38
- };
39
- export class CoverageRouter {
40
- config;
41
- ruvectorEngine = null;
42
- useNative = false;
43
- coverageHistory = [];
44
- constructor(config = {}) {
45
- this.config = { ...DEFAULT_CONFIG, ...config };
46
- }
47
- async initialize() {
48
- try {
49
- // @ruvector/coverage is optional - gracefully fallback if not installed
50
- const ruvector = await import('@ruvector/coverage').catch(() => null);
51
- if (ruvector) {
52
- this.ruvectorEngine = ruvector.createCoverageRouter?.(this.config);
53
- this.useNative = !!this.ruvectorEngine;
54
- }
55
- }
56
- catch {
57
- this.useNative = false;
58
- }
59
- }
60
- parseCoverage(data, format = 'json') {
61
- switch (format) {
62
- case 'lcov': return this.parseLcov(data);
63
- case 'istanbul': return this.parseIstanbul(data);
64
- case 'cobertura': return this.parseCobertura(data);
65
- default: return this.parseJson(data);
66
- }
67
- }
68
- route(coverage, changedFiles) {
69
- const gaps = this.calculateGaps(coverage);
70
- const targetFiles = this.prioritizeFiles(coverage, changedFiles);
71
- const action = this.determineAction(coverage, gaps);
72
- const priority = this.calculatePriority(coverage, changedFiles);
73
- const testTypes = this.recommendTestTypes(gaps);
74
- const estimatedEffort = this.estimateEffort(gaps);
75
- const impactScore = this.calculateImpact(coverage, targetFiles);
76
- return { action, priority, targetFiles, testTypes, gaps, estimatedEffort, impactScore };
77
- }
78
- getTrend() {
79
- if (this.coverageHistory.length < 2)
80
- return { direction: 'stable', change: 0 };
81
- const recent = this.coverageHistory[this.coverageHistory.length - 1];
82
- const previous = this.coverageHistory[this.coverageHistory.length - 2];
83
- const change = recent.overall - previous.overall;
84
- return { direction: change > 0.5 ? 'up' : change < -0.5 ? 'down' : 'stable', change };
85
- }
86
- addToHistory(report) {
87
- this.coverageHistory.push(report);
88
- if (this.coverageHistory.length > 10)
89
- this.coverageHistory.shift();
90
- }
91
- getStats() {
92
- return { useNative: this.useNative, historySize: this.coverageHistory.length, minCoverage: this.config.minCoverage, targetCoverage: this.config.targetCoverage };
93
- }
94
- parseLcov(data) {
95
- const files = [];
96
- let currentFile = null;
97
- const lines = data.split('\n');
98
- for (const line of lines) {
99
- if (line.startsWith('SF:')) {
100
- if (currentFile?.path)
101
- files.push(this.finalizeFileCoverage(currentFile));
102
- currentFile = { path: line.substring(3), uncoveredLines: [], totalLines: 0, coveredLines: 0 };
103
- }
104
- else if (line.startsWith('LF:')) {
105
- if (currentFile)
106
- currentFile.totalLines = parseInt(line.substring(3), 10);
107
- }
108
- else if (line.startsWith('LH:')) {
109
- if (currentFile)
110
- currentFile.coveredLines = parseInt(line.substring(3), 10);
111
- }
112
- else if (line.startsWith('DA:')) {
113
- const [lineNum, hits] = line.substring(3).split(',').map(Number);
114
- if (currentFile && hits === 0)
115
- currentFile.uncoveredLines?.push(lineNum);
116
- }
117
- else if (line === 'end_of_record') {
118
- if (currentFile?.path)
119
- files.push(this.finalizeFileCoverage(currentFile));
120
- currentFile = null;
121
- }
122
- }
123
- return this.buildReport(files);
124
- }
125
- parseIstanbul(data) {
126
- const files = [];
127
- for (const [path, coverage] of Object.entries(data)) {
128
- const cov = coverage;
129
- const statements = cov.s;
130
- const functions = cov.f;
131
- const branches = cov.b;
132
- const statementCovered = Object.values(statements).filter(v => v > 0).length;
133
- const statementTotal = Object.values(statements).length;
134
- const functionCovered = Object.values(functions).filter(v => v > 0).length;
135
- const functionTotal = Object.values(functions).length;
136
- const branchCovered = Object.values(branches).flat().filter(v => v > 0).length;
137
- const branchTotal = Object.values(branches).flat().length;
138
- files.push({
139
- path, lineCoverage: statementTotal > 0 ? (statementCovered / statementTotal) * 100 : 100,
140
- branchCoverage: branchTotal > 0 ? (branchCovered / branchTotal) * 100 : 100,
141
- functionCoverage: functionTotal > 0 ? (functionCovered / functionTotal) * 100 : 100,
142
- statementCoverage: statementTotal > 0 ? (statementCovered / statementTotal) * 100 : 100,
143
- uncoveredLines: [], totalLines: statementTotal, coveredLines: statementCovered,
144
- });
145
- }
146
- return this.buildReport(files);
147
- }
148
- parseCobertura(data) {
149
- const files = [];
150
- const classMatches = data.matchAll(/<class[^>]*filename="([^"]+)"[^>]*line-rate="([^"]+)"[^>]*branch-rate="([^"]+)"[^>]*>/g);
151
- for (const match of classMatches) {
152
- files.push({
153
- path: match[1], lineCoverage: parseFloat(match[2]) * 100, branchCoverage: parseFloat(match[3]) * 100,
154
- functionCoverage: parseFloat(match[2]) * 100, statementCoverage: parseFloat(match[2]) * 100,
155
- uncoveredLines: [], totalLines: 0, coveredLines: 0,
156
- });
157
- }
158
- return this.buildReport(files);
159
- }
160
- parseJson(data) {
161
- if (Array.isArray(data))
162
- return this.buildReport(data);
163
- const files = [];
164
- for (const [path, coverage] of Object.entries(data)) {
165
- const cov = coverage;
166
- files.push({
167
- path, lineCoverage: cov.lineCoverage || 0, branchCoverage: cov.branchCoverage || 0,
168
- functionCoverage: cov.functionCoverage || 0, statementCoverage: cov.statementCoverage || 0,
169
- uncoveredLines: cov.uncoveredLines || [], totalLines: cov.totalLines || 0, coveredLines: cov.coveredLines || 0,
170
- });
171
- }
172
- return this.buildReport(files);
173
- }
174
- finalizeFileCoverage(partial) {
175
- const lineCoverage = partial.totalLines && partial.totalLines > 0 ? (partial.coveredLines || 0) / partial.totalLines * 100 : 100;
176
- return { path: partial.path || 'unknown', lineCoverage, branchCoverage: lineCoverage, functionCoverage: lineCoverage, statementCoverage: lineCoverage, uncoveredLines: partial.uncoveredLines || [], totalLines: partial.totalLines || 0, coveredLines: partial.coveredLines || 0 };
177
- }
178
- buildReport(files) {
179
- const totalLines = files.reduce((sum, f) => sum + f.totalLines, 0);
180
- const coveredLines = files.reduce((sum, f) => sum + f.coveredLines, 0);
181
- const overall = totalLines > 0 ? (coveredLines / totalLines) * 100 : 100;
182
- const avgLine = files.length > 0 ? files.reduce((sum, f) => sum + f.lineCoverage, 0) / files.length : 100;
183
- const avgBranch = files.length > 0 ? files.reduce((sum, f) => sum + f.branchCoverage, 0) / files.length : 100;
184
- const avgFunction = files.length > 0 ? files.reduce((sum, f) => sum + f.functionCoverage, 0) / files.length : 100;
185
- const avgStatement = files.length > 0 ? files.reduce((sum, f) => sum + f.statementCoverage, 0) / files.length : 100;
186
- const sortedByLine = [...files].sort((a, b) => a.lineCoverage - b.lineCoverage);
187
- return { overall, byType: { line: avgLine, branch: avgBranch, function: avgFunction, statement: avgStatement }, byFile: files, lowestCoverage: sortedByLine.slice(0, 5), highestCoverage: sortedByLine.slice(-5).reverse(), uncoveredCritical: this.findCriticalUncovered(files), timestamp: Date.now() };
188
- }
189
- findCriticalUncovered(files) {
190
- const critical = [];
191
- const criticalPatterns = [/auth/, /security/, /payment/, /core/, /main/, /index/];
192
- for (const file of files) {
193
- if (file.lineCoverage < this.config.minCoverage) {
194
- for (const pattern of criticalPatterns) {
195
- if (pattern.test(file.path)) {
196
- critical.push(file.path);
197
- break;
198
- }
199
- }
200
- }
201
- }
202
- return critical.slice(0, 10);
203
- }
204
- calculateGaps(coverage) {
205
- const gaps = [];
206
- for (const file of coverage.byFile) {
207
- if (file.lineCoverage < this.config.targetCoverage) {
208
- const gap = this.config.targetCoverage - file.lineCoverage;
209
- gaps.push({ file: file.path, currentCoverage: file.lineCoverage, targetCoverage: this.config.targetCoverage, gap, suggestedTests: this.suggestTests(file) });
210
- }
211
- }
212
- return gaps.sort((a, b) => b.gap - a.gap).slice(0, 10);
213
- }
214
- suggestTests(file) {
215
- const suggestions = [];
216
- if (file.uncoveredLines.length > 10)
217
- suggestions.push('Add unit tests for uncovered code paths');
218
- if (file.branchCoverage < 50)
219
- suggestions.push('Add branch coverage tests (if/else paths)');
220
- if (file.functionCoverage < 80)
221
- suggestions.push('Add tests for untested functions');
222
- if (/api|endpoint|route|handler/.test(file.path))
223
- suggestions.push('Add integration tests for API endpoints');
224
- return suggestions.slice(0, 3);
225
- }
226
- prioritizeFiles(coverage, changedFiles) {
227
- let targetFiles = coverage.lowestCoverage.map(f => f.path);
228
- if (changedFiles && changedFiles.length > 0) {
229
- const changedWithLowCoverage = coverage.byFile.filter(f => changedFiles.some(cf => f.path.includes(cf))).filter(f => f.lineCoverage < this.config.targetCoverage).map(f => f.path);
230
- targetFiles = [...new Set([...changedWithLowCoverage, ...targetFiles])];
231
- }
232
- return targetFiles.slice(0, 10);
233
- }
234
- determineAction(coverage, gaps) {
235
- if (coverage.overall < this.config.minCoverage)
236
- return 'prioritize';
237
- if (gaps.length > 5)
238
- return 'add-tests';
239
- if (coverage.overall < this.config.targetCoverage)
240
- return 'review-coverage';
241
- return 'skip';
242
- }
243
- calculatePriority(coverage, changedFiles) {
244
- let priority = 5;
245
- if (coverage.overall < 50)
246
- priority += 4;
247
- else if (coverage.overall < 70)
248
- priority += 2;
249
- else if (coverage.overall < 85)
250
- priority += 1;
251
- priority += Math.min(3, coverage.uncoveredCritical.length);
252
- if (changedFiles && changedFiles.length > 0) {
253
- const changedLowCoverage = coverage.byFile.filter(f => changedFiles.some(cf => f.path.includes(cf))).filter(f => f.lineCoverage < this.config.minCoverage);
254
- priority += Math.min(2, changedLowCoverage.length);
255
- }
256
- return Math.min(10, priority);
257
- }
258
- recommendTestTypes(gaps) {
259
- const types = new Set(['unit']);
260
- for (const gap of gaps) {
261
- if (/api|endpoint|route|handler|service/.test(gap.file))
262
- types.add('integration');
263
- if (/page|component|view|ui/.test(gap.file))
264
- types.add('e2e');
265
- }
266
- return Array.from(types);
267
- }
268
- estimateEffort(gaps) {
269
- let effort = 0;
270
- for (const gap of gaps)
271
- effort += (gap.gap / 10) * 0.5;
272
- return Math.round(effort * 10) / 10;
273
- }
274
- calculateImpact(coverage, targetFiles) {
275
- const potentialGain = targetFiles.reduce((sum, file) => {
276
- const fileCov = coverage.byFile.find(f => f.path === file);
277
- return fileCov ? sum + (this.config.targetCoverage - fileCov.lineCoverage) : sum;
278
- }, 0);
279
- return Math.min(100, Math.round(potentialGain / targetFiles.length || 0));
280
- }
281
- }
282
- export function createCoverageRouter(config) {
283
- return new CoverageRouter(config);
284
- }
285
- /**
286
- * Route a task based on coverage analysis
287
- */
288
- export async function coverageRoute(task, options = {}) {
289
- const router = new CoverageRouter({
290
- targetCoverage: options.threshold || 80,
291
- });
292
- // Try to load coverage data
293
- const coverage = await loadProjectCoverage(options.projectRoot);
294
- if (!coverage) {
295
- return {
296
- action: 'skip',
297
- priority: 1,
298
- targetFiles: [],
299
- testTypes: ['unit'],
300
- gaps: [],
301
- estimatedEffort: 0,
302
- impactScore: 0,
303
- };
304
- }
305
- return router.route(coverage);
306
- }
307
- /**
308
- * Suggest coverage improvements for a path
309
- */
310
- export async function coverageSuggest(path, options = {}) {
311
- const limit = options.limit || 20;
312
- const threshold = options.threshold || 80;
313
- const coverage = await loadProjectCoverage(options.projectRoot);
314
- if (!coverage) {
315
- return {
316
- path,
317
- suggestions: [],
318
- totalGap: 0,
319
- estimatedEffort: 0,
320
- };
321
- }
322
- // Filter files matching the path
323
- const matchingFiles = coverage.byFile.filter(f => f.path.includes(path));
324
- const belowThreshold = matchingFiles.filter(f => f.lineCoverage < threshold);
325
- const suggestions = belowThreshold
326
- .map(f => ({
327
- file: f.path,
328
- currentCoverage: f.lineCoverage,
329
- targetCoverage: threshold,
330
- gap: threshold - f.lineCoverage,
331
- priority: calculateFilePriority(f.path, f.lineCoverage, threshold),
332
- suggestedTests: suggestTestsForFile(f),
333
- }))
334
- .sort((a, b) => b.priority - a.priority)
335
- .slice(0, limit);
336
- const totalGap = suggestions.reduce((sum, s) => sum + s.gap, 0);
337
- const estimatedEffort = totalGap * 0.1; // Rough estimate: 0.1 hours per % gap
338
- return { path, suggestions, totalGap, estimatedEffort };
339
- }
340
- /**
341
- * List all coverage gaps with agent assignments
342
- */
343
- export async function coverageGaps(options = {}) {
344
- const threshold = options.threshold || 80;
345
- const groupByAgent = options.groupByAgent !== false;
346
- const coverage = await loadProjectCoverage(options.projectRoot);
347
- if (!coverage) {
348
- return {
349
- totalGaps: 0,
350
- gaps: [],
351
- byAgent: {},
352
- summary: 'No coverage data found',
353
- };
354
- }
355
- const belowThreshold = coverage.byFile.filter(f => f.lineCoverage < threshold);
356
- const gaps = belowThreshold.map(f => ({
357
- file: f.path,
358
- currentCoverage: f.lineCoverage,
359
- targetCoverage: threshold,
360
- gap: threshold - f.lineCoverage,
361
- priority: calculateFilePriority(f.path, f.lineCoverage, threshold),
362
- suggestedAgent: suggestAgentForFile(f.path),
363
- }));
364
- const byAgent = {};
365
- if (groupByAgent) {
366
- for (const gap of gaps) {
367
- if (!byAgent[gap.suggestedAgent]) {
368
- byAgent[gap.suggestedAgent] = [];
369
- }
370
- byAgent[gap.suggestedAgent].push(gap.file);
371
- }
372
- }
373
- return {
374
- totalGaps: gaps.length,
375
- gaps,
376
- byAgent,
377
- summary: `${gaps.length} files below ${threshold}% coverage threshold`,
378
- };
379
- }
380
- /**
381
- * Validate and normalize path to prevent directory traversal
382
- * Returns null if path is invalid or attempts traversal
383
- */
384
- function validateProjectPath(inputPath) {
385
- // resolve, normalize, isAbsolute imported at top of module
386
- // Default to cwd if not provided
387
- const basePath = inputPath || process.cwd();
388
- // Normalize and resolve the path
389
- const normalizedPath = normalize(basePath);
390
- const resolvedPath = isAbsolute(normalizedPath) ? normalizedPath : resolve(process.cwd(), normalizedPath);
391
- // Enforce containment: resolved path must stay within cwd regardless of how it was expressed
392
- if (!resolvedPath.startsWith(process.cwd())) {
393
- return null;
394
- }
395
- // Additional validation: no null bytes or control characters
396
- if (/[\x00-\x1f]/.test(resolvedPath)) {
397
- return null;
398
- }
399
- // Limit path length to prevent DoS
400
- if (resolvedPath.length > 4096) {
401
- return null;
402
- }
403
- return resolvedPath;
404
- }
405
- /**
406
- * Load project coverage data (async with caching)
407
- */
408
- async function loadProjectCoverage(projectRoot, skipCache) {
409
- // Validate and normalize the project root path
410
- const root = validateProjectPath(projectRoot);
411
- if (!root) {
412
- // Invalid path detected, return null safely
413
- return null;
414
- }
415
- // Check cache first
416
- if (!skipCache) {
417
- const cached = coverageDataCache.get(root);
418
- if (cached && Date.now() - cached.timestamp < COVERAGE_CACHE_TTL_MS) {
419
- return cached.report;
420
- }
421
- }
422
- // existsSync, readFile, join, normalize imported at top of module
423
- // Try common coverage locations (all relative to validated root)
424
- const coverageLocations = [
425
- ['coverage', 'coverage-final.json'],
426
- ['coverage', 'lcov.info'],
427
- ['.nyc_output', 'coverage.json'],
428
- ['coverage.json'],
429
- ];
430
- for (const pathParts of coverageLocations) {
431
- // Join and normalize to prevent traversal in coverage paths
432
- const coveragePath = normalize(join(root, ...pathParts));
433
- // Ensure the coverage path is still within or under root
434
- if (!coveragePath.startsWith(root)) {
435
- continue;
436
- }
437
- if (existsSync(coveragePath)) {
438
- try {
439
- const { stat } = await import('node:fs/promises');
440
- const MAX_COVERAGE_SIZE = 50 * 1024 * 1024; // 50 MB
441
- const fileStats = await stat(coveragePath);
442
- if (fileStats.size > MAX_COVERAGE_SIZE)
443
- continue;
444
- // Use async file read for non-blocking I/O
445
- const content = await readFile(coveragePath, 'utf-8');
446
- const router = new CoverageRouter();
447
- let report = null;
448
- if (coveragePath.endsWith('.json')) {
449
- report = router.parseCoverage(JSON.parse(content), 'istanbul');
450
- }
451
- else if (coveragePath.endsWith('.info')) {
452
- report = router.parseCoverage(content, 'lcov');
453
- }
454
- // Cache the result (evict oldest entry if at capacity)
455
- if (report) {
456
- if (coverageDataCache.size >= COVERAGE_CACHE_MAX) {
457
- const firstKey = coverageDataCache.keys().next().value;
458
- if (firstKey !== undefined)
459
- coverageDataCache.delete(firstKey);
460
- }
461
- coverageDataCache.set(root, { report, timestamp: Date.now() });
462
- return report;
463
- }
464
- }
465
- catch {
466
- // Continue to next path
467
- }
468
- }
469
- }
470
- return null;
471
- }
472
- /**
473
- * Calculate priority for a file based on path and coverage
474
- */
475
- function calculateFilePriority(path, coverage, threshold) {
476
- let priority = 5;
477
- // Gap-based priority
478
- const gap = threshold - coverage;
479
- if (gap > 50)
480
- priority += 3;
481
- else if (gap > 30)
482
- priority += 2;
483
- else if (gap > 15)
484
- priority += 1;
485
- // Path-based priority
486
- const lowerPath = path.toLowerCase();
487
- if (/core|main|index/.test(lowerPath))
488
- priority += 2;
489
- if (/auth|security|payment/.test(lowerPath))
490
- priority += 3;
491
- if (/api|service|controller/.test(lowerPath))
492
- priority += 1;
493
- if (/util|helper/.test(lowerPath))
494
- priority -= 1;
495
- if (/test|spec|mock/.test(lowerPath))
496
- priority -= 2;
497
- return Math.max(1, Math.min(10, priority));
498
- }
499
- /**
500
- * Suggest tests for a file based on its coverage
501
- */
502
- function suggestTestsForFile(file) {
503
- const suggestions = [];
504
- if (file.uncoveredLines.length > 10) {
505
- suggestions.push('Add unit tests for uncovered code paths');
506
- }
507
- if (file.branchCoverage < 50) {
508
- suggestions.push('Add branch coverage tests (if/else paths)');
509
- }
510
- if (file.functionCoverage < 80) {
511
- suggestions.push('Add tests for untested functions');
512
- }
513
- const lowerPath = file.path.toLowerCase();
514
- if (/api|endpoint|route|handler/.test(lowerPath)) {
515
- suggestions.push('Add integration tests for API endpoints');
516
- }
517
- if (/component|view|ui/.test(lowerPath)) {
518
- suggestions.push('Add component tests with user interactions');
519
- }
520
- return suggestions.slice(0, 3);
521
- }
522
- /**
523
- * Suggest an agent type for a file
524
- */
525
- function suggestAgentForFile(path) {
526
- const lowerPath = path.toLowerCase();
527
- if (/api|endpoint|route|controller/.test(lowerPath))
528
- return 'api-tester';
529
- if (/component|view|ui|page/.test(lowerPath))
530
- return 'ui-tester';
531
- if (/service|repository|model/.test(lowerPath))
532
- return 'unit-tester';
533
- if (/integration|e2e/.test(lowerPath))
534
- return 'e2e-tester';
535
- if (/util|helper|lib/.test(lowerPath))
536
- return 'unit-tester';
537
- return 'tester';
538
- }
539
- //# sourceMappingURL=coverage-router.js.map