ruvector 0.2.23 → 0.2.25

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 (111) hide show
  1. package/bin/cli.js +211 -63
  2. package/dist/analysis/complexity.d.ts +52 -0
  3. package/dist/analysis/complexity.d.ts.map +1 -0
  4. package/dist/analysis/complexity.js +146 -0
  5. package/dist/analysis/index.d.ts +15 -0
  6. package/dist/analysis/index.d.ts.map +1 -0
  7. package/dist/analysis/index.js +38 -0
  8. package/dist/analysis/patterns.d.ts +71 -0
  9. package/dist/analysis/patterns.d.ts.map +1 -0
  10. package/dist/analysis/patterns.js +243 -0
  11. package/dist/analysis/security.d.ts +51 -0
  12. package/dist/analysis/security.d.ts.map +1 -0
  13. package/dist/analysis/security.js +139 -0
  14. package/dist/core/adaptive-embedder.d.ts +156 -0
  15. package/dist/core/adaptive-embedder.d.ts.map +1 -0
  16. package/dist/core/adaptive-embedder.js +838 -0
  17. package/dist/core/agentdb-fast.d.ts +149 -0
  18. package/dist/core/agentdb-fast.d.ts.map +1 -0
  19. package/dist/core/agentdb-fast.js +301 -0
  20. package/dist/core/ast-parser.d.ts +108 -0
  21. package/dist/core/ast-parser.d.ts.map +1 -0
  22. package/dist/core/ast-parser.js +602 -0
  23. package/dist/core/attention-fallbacks.d.ts +321 -0
  24. package/dist/core/attention-fallbacks.d.ts.map +1 -0
  25. package/dist/core/attention-fallbacks.js +552 -0
  26. package/dist/core/cluster-wrapper.d.ts +148 -0
  27. package/dist/core/cluster-wrapper.d.ts.map +1 -0
  28. package/dist/core/cluster-wrapper.js +271 -0
  29. package/dist/core/coverage-router.d.ts +88 -0
  30. package/dist/core/coverage-router.d.ts.map +1 -0
  31. package/dist/core/coverage-router.js +315 -0
  32. package/dist/core/diff-embeddings.d.ts +93 -0
  33. package/dist/core/diff-embeddings.d.ts.map +1 -0
  34. package/dist/core/diff-embeddings.js +334 -0
  35. package/dist/core/diskann-wrapper.d.ts +53 -0
  36. package/dist/core/diskann-wrapper.d.ts.map +1 -0
  37. package/dist/core/diskann-wrapper.js +105 -0
  38. package/dist/core/gnn-wrapper.d.ts +143 -0
  39. package/dist/core/gnn-wrapper.d.ts.map +1 -0
  40. package/dist/core/gnn-wrapper.js +213 -0
  41. package/dist/core/graph-algorithms.d.ts +83 -0
  42. package/dist/core/graph-algorithms.d.ts.map +1 -0
  43. package/dist/core/graph-algorithms.js +514 -0
  44. package/dist/core/graph-wrapper.d.ts +147 -0
  45. package/dist/core/graph-wrapper.d.ts.map +1 -0
  46. package/dist/core/graph-wrapper.js +299 -0
  47. package/dist/core/index.d.ts +50 -0
  48. package/dist/core/index.d.ts.map +1 -0
  49. package/dist/core/index.js +92 -0
  50. package/dist/core/intelligence-engine.d.ts +258 -0
  51. package/dist/core/intelligence-engine.d.ts.map +1 -0
  52. package/dist/core/intelligence-engine.js +1030 -0
  53. package/dist/core/learning-engine.d.ts +160 -0
  54. package/dist/core/learning-engine.d.ts.map +1 -0
  55. package/dist/core/learning-engine.js +589 -0
  56. package/dist/core/neural-embeddings.d.ts +393 -0
  57. package/dist/core/neural-embeddings.d.ts.map +1 -0
  58. package/dist/core/neural-embeddings.js +1091 -0
  59. package/dist/core/neural-perf.d.ts +331 -0
  60. package/dist/core/neural-perf.d.ts.map +1 -0
  61. package/dist/core/neural-perf.js +704 -0
  62. package/dist/core/onnx/pkg/package.json +3 -0
  63. package/dist/core/onnx-embedder.d.ts +105 -0
  64. package/dist/core/onnx-embedder.d.ts.map +1 -0
  65. package/dist/core/onnx-embedder.js +410 -0
  66. package/dist/core/onnx-optimized.d.ts +109 -0
  67. package/dist/core/onnx-optimized.d.ts.map +1 -0
  68. package/dist/core/onnx-optimized.js +419 -0
  69. package/dist/core/parallel-intelligence.d.ts +109 -0
  70. package/dist/core/parallel-intelligence.d.ts.map +1 -0
  71. package/dist/core/parallel-intelligence.js +340 -0
  72. package/dist/core/parallel-workers.d.ts +177 -0
  73. package/dist/core/parallel-workers.d.ts.map +1 -0
  74. package/dist/core/parallel-workers.js +783 -0
  75. package/dist/core/router-wrapper.d.ts +75 -0
  76. package/dist/core/router-wrapper.d.ts.map +1 -0
  77. package/dist/core/router-wrapper.js +243 -0
  78. package/dist/core/rvf-wrapper.d.ts +86 -0
  79. package/dist/core/rvf-wrapper.d.ts.map +1 -0
  80. package/dist/core/rvf-wrapper.js +102 -0
  81. package/dist/core/sona-wrapper.d.ts +226 -0
  82. package/dist/core/sona-wrapper.d.ts.map +1 -0
  83. package/dist/core/sona-wrapper.js +282 -0
  84. package/dist/core/tensor-compress.d.ts +134 -0
  85. package/dist/core/tensor-compress.d.ts.map +1 -0
  86. package/dist/core/tensor-compress.js +432 -0
  87. package/dist/index.d.ts +106 -0
  88. package/dist/index.d.ts.map +1 -0
  89. package/dist/index.js +258 -0
  90. package/dist/services/embedding-service.d.ts +136 -0
  91. package/dist/services/embedding-service.d.ts.map +1 -0
  92. package/dist/services/embedding-service.js +294 -0
  93. package/dist/services/index.d.ts +6 -0
  94. package/dist/services/index.d.ts.map +1 -0
  95. package/dist/services/index.js +26 -0
  96. package/dist/types.d.ts +145 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +2 -0
  99. package/dist/workers/benchmark.d.ts +44 -0
  100. package/dist/workers/benchmark.d.ts.map +1 -0
  101. package/dist/workers/benchmark.js +230 -0
  102. package/dist/workers/index.d.ts +10 -0
  103. package/dist/workers/index.d.ts.map +1 -0
  104. package/dist/workers/index.js +25 -0
  105. package/dist/workers/native-worker.d.ts +76 -0
  106. package/dist/workers/native-worker.d.ts.map +1 -0
  107. package/dist/workers/native-worker.js +490 -0
  108. package/dist/workers/types.d.ts +69 -0
  109. package/dist/workers/types.d.ts.map +1 -0
  110. package/dist/workers/types.js +7 -0
  111. package/package.json +8 -7
@@ -0,0 +1,271 @@
1
+ "use strict";
2
+ /**
3
+ * Cluster Wrapper - Distributed coordination for multi-agent systems
4
+ *
5
+ * Wraps @ruvector/cluster for Raft consensus, auto-sharding,
6
+ * and distributed memory across agents.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.RuvectorCluster = void 0;
10
+ exports.isClusterAvailable = isClusterAvailable;
11
+ exports.createCluster = createCluster;
12
+ let clusterModule = null;
13
+ let loadError = null;
14
+ function getClusterModule() {
15
+ if (clusterModule)
16
+ return clusterModule;
17
+ if (loadError)
18
+ throw loadError;
19
+ try {
20
+ clusterModule = require('@ruvector/cluster');
21
+ return clusterModule;
22
+ }
23
+ catch (e) {
24
+ loadError = new Error(`@ruvector/cluster not installed: ${e.message}\n` +
25
+ `Install with: npm install @ruvector/cluster`);
26
+ throw loadError;
27
+ }
28
+ }
29
+ function isClusterAvailable() {
30
+ try {
31
+ getClusterModule();
32
+ return true;
33
+ }
34
+ catch {
35
+ return false;
36
+ }
37
+ }
38
+ /**
39
+ * Distributed cluster for multi-agent coordination
40
+ */
41
+ class RuvectorCluster {
42
+ constructor(config) {
43
+ this.isLeader = false;
44
+ const cluster = getClusterModule();
45
+ this.nodeId = config.nodeId;
46
+ this.inner = new cluster.Cluster({
47
+ nodeId: config.nodeId,
48
+ address: config.address,
49
+ peers: config.peers ?? [],
50
+ shards: config.shards ?? 16,
51
+ replicationFactor: config.replicationFactor ?? 2,
52
+ });
53
+ }
54
+ // ===========================================================================
55
+ // Cluster Lifecycle
56
+ // ===========================================================================
57
+ /**
58
+ * Start the cluster node
59
+ */
60
+ async start() {
61
+ await this.inner.start();
62
+ }
63
+ /**
64
+ * Stop the cluster node gracefully
65
+ */
66
+ async stop() {
67
+ await this.inner.stop();
68
+ }
69
+ /**
70
+ * Join an existing cluster
71
+ */
72
+ async join(peerAddress) {
73
+ return this.inner.join(peerAddress);
74
+ }
75
+ /**
76
+ * Leave the cluster
77
+ */
78
+ async leave() {
79
+ await this.inner.leave();
80
+ }
81
+ // ===========================================================================
82
+ // Node Management
83
+ // ===========================================================================
84
+ /**
85
+ * Get current node info
86
+ */
87
+ getNodeInfo() {
88
+ return this.inner.getNodeInfo();
89
+ }
90
+ /**
91
+ * Get all cluster nodes
92
+ */
93
+ getNodes() {
94
+ return this.inner.getNodes();
95
+ }
96
+ /**
97
+ * Check if this node is the leader
98
+ */
99
+ isClusterLeader() {
100
+ this.isLeader = this.inner.isLeader();
101
+ return this.isLeader;
102
+ }
103
+ /**
104
+ * Get the current leader
105
+ */
106
+ getLeader() {
107
+ return this.inner.getLeader();
108
+ }
109
+ // ===========================================================================
110
+ // Distributed Operations
111
+ // ===========================================================================
112
+ /**
113
+ * Put a value in distributed storage
114
+ */
115
+ async put(key, value) {
116
+ return this.inner.put(key, JSON.stringify(value));
117
+ }
118
+ /**
119
+ * Get a value from distributed storage
120
+ */
121
+ async get(key) {
122
+ const result = await this.inner.get(key);
123
+ return result ? JSON.parse(result) : null;
124
+ }
125
+ /**
126
+ * Delete a value from distributed storage
127
+ */
128
+ async delete(key) {
129
+ return this.inner.delete(key);
130
+ }
131
+ /**
132
+ * Atomic compare-and-swap
133
+ */
134
+ async compareAndSwap(key, expected, newValue) {
135
+ return this.inner.compareAndSwap(key, JSON.stringify(expected), JSON.stringify(newValue));
136
+ }
137
+ // ===========================================================================
138
+ // Sharding
139
+ // ===========================================================================
140
+ /**
141
+ * Get shard information
142
+ */
143
+ getShards() {
144
+ return this.inner.getShards();
145
+ }
146
+ /**
147
+ * Get the shard for a key
148
+ */
149
+ getShardForKey(key) {
150
+ return this.inner.getShardForKey(key);
151
+ }
152
+ /**
153
+ * Trigger shard rebalancing
154
+ */
155
+ async rebalance() {
156
+ await this.inner.rebalance();
157
+ }
158
+ // ===========================================================================
159
+ // Distributed Locks
160
+ // ===========================================================================
161
+ /**
162
+ * Acquire a distributed lock
163
+ */
164
+ async lock(name, timeout = 30000) {
165
+ return this.inner.lock(name, timeout);
166
+ }
167
+ /**
168
+ * Release a distributed lock
169
+ */
170
+ async unlock(name, token) {
171
+ return this.inner.unlock(name, token);
172
+ }
173
+ /**
174
+ * Extend a lock's TTL
175
+ */
176
+ async extendLock(name, token, extension = 30000) {
177
+ return this.inner.extendLock(name, token, extension);
178
+ }
179
+ // ===========================================================================
180
+ // Pub/Sub
181
+ // ===========================================================================
182
+ /**
183
+ * Subscribe to a channel
184
+ */
185
+ subscribe(channel, callback) {
186
+ return this.inner.subscribe(channel, (msg) => {
187
+ callback(JSON.parse(msg));
188
+ });
189
+ }
190
+ /**
191
+ * Publish to a channel
192
+ */
193
+ async publish(channel, message) {
194
+ return this.inner.publish(channel, JSON.stringify(message));
195
+ }
196
+ // ===========================================================================
197
+ // Agent Coordination
198
+ // ===========================================================================
199
+ /**
200
+ * Register an agent with the cluster
201
+ */
202
+ async registerAgent(agentId, capabilities) {
203
+ return this.put(`agent:${agentId}`, {
204
+ id: agentId,
205
+ capabilities,
206
+ node: this.nodeId,
207
+ registeredAt: Date.now(),
208
+ });
209
+ }
210
+ /**
211
+ * Find agents with a capability
212
+ */
213
+ async findAgents(capability) {
214
+ const agents = await this.inner.scan('agent:*');
215
+ const matching = [];
216
+ for (const key of agents) {
217
+ const agent = await this.get(key);
218
+ if (agent?.capabilities?.includes(capability)) {
219
+ matching.push(agent.id);
220
+ }
221
+ }
222
+ return matching;
223
+ }
224
+ /**
225
+ * Assign a task to an agent
226
+ */
227
+ async assignTask(taskId, agentId, task) {
228
+ const assigned = await this.put(`task:${taskId}`, {
229
+ id: taskId,
230
+ agent: agentId,
231
+ task,
232
+ status: 'assigned',
233
+ assignedAt: Date.now(),
234
+ });
235
+ if (assigned) {
236
+ await this.publish(`agent:${agentId}:tasks`, { type: 'new_task', taskId });
237
+ }
238
+ return assigned;
239
+ }
240
+ /**
241
+ * Complete a task
242
+ */
243
+ async completeTask(taskId, result) {
244
+ const task = await this.get(`task:${taskId}`);
245
+ if (!task)
246
+ return false;
247
+ return this.put(`task:${taskId}`, {
248
+ ...task,
249
+ status: 'completed',
250
+ result,
251
+ completedAt: Date.now(),
252
+ });
253
+ }
254
+ // ===========================================================================
255
+ // Stats
256
+ // ===========================================================================
257
+ /**
258
+ * Get cluster statistics
259
+ */
260
+ stats() {
261
+ return this.inner.stats();
262
+ }
263
+ }
264
+ exports.RuvectorCluster = RuvectorCluster;
265
+ /**
266
+ * Create a cluster node for agent coordination
267
+ */
268
+ function createCluster(config) {
269
+ return new RuvectorCluster(config);
270
+ }
271
+ exports.default = RuvectorCluster;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Coverage Router - Test coverage-aware agent routing
3
+ *
4
+ * Uses test coverage data to make smarter routing decisions:
5
+ * - Prioritize testing for uncovered code
6
+ * - Route to tester agent for low-coverage files
7
+ * - Suggest test files for modified code
8
+ */
9
+ export interface CoverageData {
10
+ file: string;
11
+ lines: {
12
+ total: number;
13
+ covered: number;
14
+ percentage: number;
15
+ };
16
+ functions: {
17
+ total: number;
18
+ covered: number;
19
+ percentage: number;
20
+ };
21
+ branches: {
22
+ total: number;
23
+ covered: number;
24
+ percentage: number;
25
+ };
26
+ uncoveredLines: number[];
27
+ uncoveredFunctions: string[];
28
+ }
29
+ export interface CoverageSummary {
30
+ files: Map<string, CoverageData>;
31
+ overall: {
32
+ lines: number;
33
+ functions: number;
34
+ branches: number;
35
+ };
36
+ lowCoverageFiles: string[];
37
+ uncoveredFiles: string[];
38
+ }
39
+ export interface TestSuggestion {
40
+ file: string;
41
+ testFile: string;
42
+ reason: string;
43
+ priority: 'high' | 'medium' | 'low';
44
+ coverage: number;
45
+ uncoveredFunctions: string[];
46
+ }
47
+ /**
48
+ * Parse Istanbul/NYC JSON coverage report
49
+ */
50
+ export declare function parseIstanbulCoverage(coveragePath: string): CoverageSummary;
51
+ /**
52
+ * Find coverage report in project
53
+ */
54
+ export declare function findCoverageReport(projectRoot?: string): string | null;
55
+ /**
56
+ * Get coverage data for a specific file
57
+ */
58
+ export declare function getFileCoverage(file: string, summary?: CoverageSummary): CoverageData | null;
59
+ /**
60
+ * Suggest tests for files based on coverage
61
+ */
62
+ export declare function suggestTests(files: string[], summary?: CoverageSummary): TestSuggestion[];
63
+ /**
64
+ * Determine if a file needs the tester agent based on coverage
65
+ */
66
+ export declare function shouldRouteToTester(file: string, summary?: CoverageSummary): {
67
+ route: boolean;
68
+ reason: string;
69
+ coverage: number;
70
+ };
71
+ /**
72
+ * Get coverage-aware routing weight for agent selection
73
+ */
74
+ export declare function getCoverageRoutingWeight(file: string, summary?: CoverageSummary): {
75
+ coder: number;
76
+ tester: number;
77
+ reviewer: number;
78
+ };
79
+ declare const _default: {
80
+ parseIstanbulCoverage: typeof parseIstanbulCoverage;
81
+ findCoverageReport: typeof findCoverageReport;
82
+ getFileCoverage: typeof getFileCoverage;
83
+ suggestTests: typeof suggestTests;
84
+ shouldRouteToTester: typeof shouldRouteToTester;
85
+ getCoverageRoutingWeight: typeof getCoverageRoutingWeight;
86
+ };
87
+ export default _default;
88
+ //# sourceMappingURL=coverage-router.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coverage-router.d.ts","sourceRoot":"","sources":["../../src/core/coverage-router.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE;QACL,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,SAAS,EAAE;QACT,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,QAAQ,EAAE;QACR,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,UAAU,EAAE,MAAM,CAAC;KACpB,CAAC;IACF,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IACjC,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;IACF,gBAAgB,EAAE,MAAM,EAAE,CAAC;IAC3B,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;IACpC,QAAQ,EAAE,MAAM,CAAC;IACjB,kBAAkB,EAAE,MAAM,EAAE,CAAC;CAC9B;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,YAAY,EAAE,MAAM,GAAG,eAAe,CA0F3E;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,GAAE,MAAsB,GAAG,MAAM,GAAG,IAAI,CAiBrF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,YAAY,GAAG,IAAI,CAqB5F;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG,cAAc,EAAE,CAwEzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IAC5E,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAgCA;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,eAAe,GAAG;IACjF,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAuBA;;;;;;;;;AAED,wBAOE"}
@@ -0,0 +1,315 @@
1
+ "use strict";
2
+ /**
3
+ * Coverage Router - Test coverage-aware agent routing
4
+ *
5
+ * Uses test coverage data to make smarter routing decisions:
6
+ * - Prioritize testing for uncovered code
7
+ * - Route to tester agent for low-coverage files
8
+ * - Suggest test files for modified code
9
+ */
10
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
11
+ if (k2 === undefined) k2 = k;
12
+ var desc = Object.getOwnPropertyDescriptor(m, k);
13
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
14
+ desc = { enumerable: true, get: function() { return m[k]; } };
15
+ }
16
+ Object.defineProperty(o, k2, desc);
17
+ }) : (function(o, m, k, k2) {
18
+ if (k2 === undefined) k2 = k;
19
+ o[k2] = m[k];
20
+ }));
21
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
22
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
23
+ }) : function(o, v) {
24
+ o["default"] = v;
25
+ });
26
+ var __importStar = (this && this.__importStar) || (function () {
27
+ var ownKeys = function(o) {
28
+ ownKeys = Object.getOwnPropertyNames || function (o) {
29
+ var ar = [];
30
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
31
+ return ar;
32
+ };
33
+ return ownKeys(o);
34
+ };
35
+ return function (mod) {
36
+ if (mod && mod.__esModule) return mod;
37
+ var result = {};
38
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
39
+ __setModuleDefault(result, mod);
40
+ return result;
41
+ };
42
+ })();
43
+ Object.defineProperty(exports, "__esModule", { value: true });
44
+ exports.parseIstanbulCoverage = parseIstanbulCoverage;
45
+ exports.findCoverageReport = findCoverageReport;
46
+ exports.getFileCoverage = getFileCoverage;
47
+ exports.suggestTests = suggestTests;
48
+ exports.shouldRouteToTester = shouldRouteToTester;
49
+ exports.getCoverageRoutingWeight = getCoverageRoutingWeight;
50
+ const fs = __importStar(require("fs"));
51
+ const path = __importStar(require("path"));
52
+ /**
53
+ * Parse Istanbul/NYC JSON coverage report
54
+ */
55
+ function parseIstanbulCoverage(coveragePath) {
56
+ const files = new Map();
57
+ const lowCoverageFiles = [];
58
+ const uncoveredFiles = [];
59
+ let totalLines = 0, coveredLines = 0;
60
+ let totalFunctions = 0, coveredFunctions = 0;
61
+ let totalBranches = 0, coveredBranches = 0;
62
+ try {
63
+ const coverage = JSON.parse(fs.readFileSync(coveragePath, 'utf8'));
64
+ for (const [file, data] of Object.entries(coverage)) {
65
+ // Skip test files
66
+ if (file.includes('.test.') || file.includes('.spec.') || file.includes('__tests__')) {
67
+ continue;
68
+ }
69
+ // Parse statement coverage
70
+ const statements = Object.values(data.s || {});
71
+ const linesCovered = statements.filter(n => n > 0).length;
72
+ const linesTotal = statements.length;
73
+ // Parse function coverage
74
+ const functions = Object.values(data.f || {});
75
+ const fnCovered = functions.filter(n => n > 0).length;
76
+ const fnTotal = functions.length;
77
+ // Parse branch coverage
78
+ const branches = Object.values(data.b || {}).flat();
79
+ const brCovered = branches.filter(n => n > 0).length;
80
+ const brTotal = branches.length;
81
+ // Find uncovered lines
82
+ const uncoveredLines = [];
83
+ for (const [line, count] of Object.entries(data.s || {})) {
84
+ if (count === 0) {
85
+ uncoveredLines.push(parseInt(line));
86
+ }
87
+ }
88
+ // Find uncovered functions
89
+ const uncoveredFunctions = [];
90
+ const fnMap = data.fnMap || {};
91
+ for (const [fnId, count] of Object.entries(data.f || {})) {
92
+ if (count === 0 && fnMap[fnId]) {
93
+ uncoveredFunctions.push(fnMap[fnId].name || `function_${fnId}`);
94
+ }
95
+ }
96
+ const linePercentage = linesTotal > 0 ? (linesCovered / linesTotal) * 100 : 100;
97
+ const fnPercentage = fnTotal > 0 ? (fnCovered / fnTotal) * 100 : 100;
98
+ const brPercentage = brTotal > 0 ? (brCovered / brTotal) * 100 : 100;
99
+ files.set(file, {
100
+ file,
101
+ lines: { total: linesTotal, covered: linesCovered, percentage: linePercentage },
102
+ functions: { total: fnTotal, covered: fnCovered, percentage: fnPercentage },
103
+ branches: { total: brTotal, covered: brCovered, percentage: brPercentage },
104
+ uncoveredLines,
105
+ uncoveredFunctions,
106
+ });
107
+ totalLines += linesTotal;
108
+ coveredLines += linesCovered;
109
+ totalFunctions += fnTotal;
110
+ coveredFunctions += fnCovered;
111
+ totalBranches += brTotal;
112
+ coveredBranches += brCovered;
113
+ if (linePercentage < 50) {
114
+ lowCoverageFiles.push(file);
115
+ }
116
+ if (linePercentage === 0 && linesTotal > 0) {
117
+ uncoveredFiles.push(file);
118
+ }
119
+ }
120
+ }
121
+ catch (e) {
122
+ // Return empty summary on error
123
+ }
124
+ return {
125
+ files,
126
+ overall: {
127
+ lines: totalLines > 0 ? (coveredLines / totalLines) * 100 : 0,
128
+ functions: totalFunctions > 0 ? (coveredFunctions / totalFunctions) * 100 : 0,
129
+ branches: totalBranches > 0 ? (coveredBranches / totalBranches) * 100 : 0,
130
+ },
131
+ lowCoverageFiles,
132
+ uncoveredFiles,
133
+ };
134
+ }
135
+ /**
136
+ * Find coverage report in project
137
+ */
138
+ function findCoverageReport(projectRoot = process.cwd()) {
139
+ const possiblePaths = [
140
+ 'coverage/coverage-final.json',
141
+ 'coverage/coverage-summary.json',
142
+ '.nyc_output/coverage.json',
143
+ 'coverage.json',
144
+ 'coverage/lcov.info',
145
+ ];
146
+ for (const p of possiblePaths) {
147
+ const fullPath = path.join(projectRoot, p);
148
+ if (fs.existsSync(fullPath)) {
149
+ return fullPath;
150
+ }
151
+ }
152
+ return null;
153
+ }
154
+ /**
155
+ * Get coverage data for a specific file
156
+ */
157
+ function getFileCoverage(file, summary) {
158
+ if (!summary) {
159
+ const reportPath = findCoverageReport();
160
+ if (!reportPath)
161
+ return null;
162
+ summary = parseIstanbulCoverage(reportPath);
163
+ }
164
+ // Try exact match first
165
+ if (summary.files.has(file)) {
166
+ return summary.files.get(file);
167
+ }
168
+ // Try matching by basename
169
+ const basename = path.basename(file);
170
+ for (const [key, data] of summary.files) {
171
+ if (key.endsWith(file) || key.endsWith(basename)) {
172
+ return data;
173
+ }
174
+ }
175
+ return null;
176
+ }
177
+ /**
178
+ * Suggest tests for files based on coverage
179
+ */
180
+ function suggestTests(files, summary) {
181
+ if (!summary) {
182
+ const reportPath = findCoverageReport();
183
+ if (reportPath) {
184
+ summary = parseIstanbulCoverage(reportPath);
185
+ }
186
+ }
187
+ const suggestions = [];
188
+ for (const file of files) {
189
+ const coverage = summary ? getFileCoverage(file, summary) : null;
190
+ // Determine test file path
191
+ const ext = path.extname(file);
192
+ const base = path.basename(file, ext);
193
+ const dir = path.dirname(file);
194
+ const possibleTestFiles = [
195
+ path.join(dir, `${base}.test${ext}`),
196
+ path.join(dir, `${base}.spec${ext}`),
197
+ path.join(dir, '__tests__', `${base}.test${ext}`),
198
+ path.join('test', `${base}.test${ext}`),
199
+ path.join('tests', `${base}.test${ext}`),
200
+ ];
201
+ const existingTestFile = possibleTestFiles.find(t => fs.existsSync(t));
202
+ const testFile = existingTestFile || possibleTestFiles[0];
203
+ if (!coverage) {
204
+ suggestions.push({
205
+ file,
206
+ testFile,
207
+ reason: 'No coverage data - needs test file',
208
+ priority: 'high',
209
+ coverage: 0,
210
+ uncoveredFunctions: [],
211
+ });
212
+ }
213
+ else if (coverage.lines.percentage < 30) {
214
+ suggestions.push({
215
+ file,
216
+ testFile,
217
+ reason: `Very low coverage (${coverage.lines.percentage.toFixed(1)}%)`,
218
+ priority: 'high',
219
+ coverage: coverage.lines.percentage,
220
+ uncoveredFunctions: coverage.uncoveredFunctions,
221
+ });
222
+ }
223
+ else if (coverage.lines.percentage < 70) {
224
+ suggestions.push({
225
+ file,
226
+ testFile,
227
+ reason: `Low coverage (${coverage.lines.percentage.toFixed(1)}%)`,
228
+ priority: 'medium',
229
+ coverage: coverage.lines.percentage,
230
+ uncoveredFunctions: coverage.uncoveredFunctions,
231
+ });
232
+ }
233
+ else if (coverage.uncoveredFunctions.length > 0) {
234
+ suggestions.push({
235
+ file,
236
+ testFile,
237
+ reason: `${coverage.uncoveredFunctions.length} untested functions`,
238
+ priority: 'low',
239
+ coverage: coverage.lines.percentage,
240
+ uncoveredFunctions: coverage.uncoveredFunctions,
241
+ });
242
+ }
243
+ }
244
+ return suggestions.sort((a, b) => {
245
+ const priorityOrder = { high: 0, medium: 1, low: 2 };
246
+ return priorityOrder[a.priority] - priorityOrder[b.priority];
247
+ });
248
+ }
249
+ /**
250
+ * Determine if a file needs the tester agent based on coverage
251
+ */
252
+ function shouldRouteToTester(file, summary) {
253
+ const coverage = getFileCoverage(file, summary);
254
+ if (!coverage) {
255
+ return {
256
+ route: true,
257
+ reason: 'No test coverage data available',
258
+ coverage: 0,
259
+ };
260
+ }
261
+ if (coverage.lines.percentage < 50) {
262
+ return {
263
+ route: true,
264
+ reason: `Low coverage: ${coverage.lines.percentage.toFixed(1)}%`,
265
+ coverage: coverage.lines.percentage,
266
+ };
267
+ }
268
+ if (coverage.uncoveredFunctions.length > 3) {
269
+ return {
270
+ route: true,
271
+ reason: `${coverage.uncoveredFunctions.length} untested functions`,
272
+ coverage: coverage.lines.percentage,
273
+ };
274
+ }
275
+ return {
276
+ route: false,
277
+ reason: `Adequate coverage: ${coverage.lines.percentage.toFixed(1)}%`,
278
+ coverage: coverage.lines.percentage,
279
+ };
280
+ }
281
+ /**
282
+ * Get coverage-aware routing weight for agent selection
283
+ */
284
+ function getCoverageRoutingWeight(file, summary) {
285
+ const coverage = getFileCoverage(file, summary);
286
+ if (!coverage) {
287
+ // No coverage = prioritize testing
288
+ return { coder: 0.3, tester: 0.5, reviewer: 0.2 };
289
+ }
290
+ const pct = coverage.lines.percentage;
291
+ if (pct < 30) {
292
+ // Very low - strongly prioritize testing
293
+ return { coder: 0.2, tester: 0.6, reviewer: 0.2 };
294
+ }
295
+ else if (pct < 60) {
296
+ // Low - moderate testing priority
297
+ return { coder: 0.4, tester: 0.4, reviewer: 0.2 };
298
+ }
299
+ else if (pct < 80) {
300
+ // Okay - balanced
301
+ return { coder: 0.5, tester: 0.3, reviewer: 0.2 };
302
+ }
303
+ else {
304
+ // Good - focus on code quality
305
+ return { coder: 0.5, tester: 0.2, reviewer: 0.3 };
306
+ }
307
+ }
308
+ exports.default = {
309
+ parseIstanbulCoverage,
310
+ findCoverageReport,
311
+ getFileCoverage,
312
+ suggestTests,
313
+ shouldRouteToTester,
314
+ getCoverageRoutingWeight,
315
+ };