@claude-flow/cli 3.0.0-alpha.14 → 3.0.0-alpha.16

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 (66) hide show
  1. package/dist/src/commands/analyze.d.ts +19 -0
  2. package/dist/src/commands/analyze.d.ts.map +1 -0
  3. package/dist/src/commands/analyze.js +1819 -0
  4. package/dist/src/commands/analyze.js.map +1 -0
  5. package/dist/src/commands/doctor.d.ts.map +1 -1
  6. package/dist/src/commands/doctor.js +75 -2
  7. package/dist/src/commands/doctor.js.map +1 -1
  8. package/dist/src/commands/hooks.d.ts.map +1 -1
  9. package/dist/src/commands/hooks.js +325 -1
  10. package/dist/src/commands/hooks.js.map +1 -1
  11. package/dist/src/commands/index.d.ts +2 -0
  12. package/dist/src/commands/index.d.ts.map +1 -1
  13. package/dist/src/commands/index.js +12 -0
  14. package/dist/src/commands/index.js.map +1 -1
  15. package/dist/src/commands/route.d.ts +16 -0
  16. package/dist/src/commands/route.d.ts.map +1 -0
  17. package/dist/src/commands/route.js +597 -0
  18. package/dist/src/commands/route.js.map +1 -0
  19. package/dist/src/init/claudemd-generator.d.ts.map +1 -1
  20. package/dist/src/init/claudemd-generator.js +218 -362
  21. package/dist/src/init/claudemd-generator.js.map +1 -1
  22. package/dist/src/mcp-client.d.ts.map +1 -1
  23. package/dist/src/mcp-client.js +2 -0
  24. package/dist/src/mcp-client.js.map +1 -1
  25. package/dist/src/mcp-tools/analyze-tools.d.ts +38 -0
  26. package/dist/src/mcp-tools/analyze-tools.d.ts.map +1 -0
  27. package/dist/src/mcp-tools/analyze-tools.js +317 -0
  28. package/dist/src/mcp-tools/analyze-tools.js.map +1 -0
  29. package/dist/src/mcp-tools/index.d.ts +2 -0
  30. package/dist/src/mcp-tools/index.d.ts.map +1 -1
  31. package/dist/src/mcp-tools/index.js +2 -0
  32. package/dist/src/mcp-tools/index.js.map +1 -1
  33. package/dist/src/ruvector/ast-analyzer.d.ts +67 -0
  34. package/dist/src/ruvector/ast-analyzer.d.ts.map +1 -0
  35. package/dist/src/ruvector/ast-analyzer.js +277 -0
  36. package/dist/src/ruvector/ast-analyzer.js.map +1 -0
  37. package/dist/src/ruvector/coverage-router.d.ts +145 -0
  38. package/dist/src/ruvector/coverage-router.d.ts.map +1 -0
  39. package/dist/src/ruvector/coverage-router.js +451 -0
  40. package/dist/src/ruvector/coverage-router.js.map +1 -0
  41. package/dist/src/ruvector/coverage-tools.d.ts +33 -0
  42. package/dist/src/ruvector/coverage-tools.d.ts.map +1 -0
  43. package/dist/src/ruvector/coverage-tools.js +157 -0
  44. package/dist/src/ruvector/coverage-tools.js.map +1 -0
  45. package/dist/src/ruvector/diff-classifier.d.ts +154 -0
  46. package/dist/src/ruvector/diff-classifier.d.ts.map +1 -0
  47. package/dist/src/ruvector/diff-classifier.js +508 -0
  48. package/dist/src/ruvector/diff-classifier.js.map +1 -0
  49. package/dist/src/ruvector/graph-analyzer.d.ts +174 -0
  50. package/dist/src/ruvector/graph-analyzer.d.ts.map +1 -0
  51. package/dist/src/ruvector/graph-analyzer.js +878 -0
  52. package/dist/src/ruvector/graph-analyzer.js.map +1 -0
  53. package/dist/src/ruvector/index.d.ts +27 -0
  54. package/dist/src/ruvector/index.d.ts.map +1 -0
  55. package/dist/src/ruvector/index.js +47 -0
  56. package/dist/src/ruvector/index.js.map +1 -0
  57. package/dist/src/ruvector/q-learning-router.d.ts +211 -0
  58. package/dist/src/ruvector/q-learning-router.d.ts.map +1 -0
  59. package/dist/src/ruvector/q-learning-router.js +681 -0
  60. package/dist/src/ruvector/q-learning-router.js.map +1 -0
  61. package/dist/src/ruvector/vector-db.d.ts +69 -0
  62. package/dist/src/ruvector/vector-db.d.ts.map +1 -0
  63. package/dist/src/ruvector/vector-db.js +243 -0
  64. package/dist/src/ruvector/vector-db.js.map +1 -0
  65. package/dist/tsconfig.tsbuildinfo +1 -1
  66. package/package.json +13 -1
@@ -1970,6 +1970,323 @@ function formatWorkerStatus(status) {
1970
1970
  return status;
1971
1971
  }
1972
1972
  }
1973
+ // ============================================================================
1974
+ // Coverage-Aware Routing Commands
1975
+ // ============================================================================
1976
+ // Coverage route subcommand
1977
+ const coverageRouteCommand = {
1978
+ name: 'coverage-route',
1979
+ description: 'Route task to agents based on test coverage gaps (ruvector integration)',
1980
+ options: [
1981
+ {
1982
+ name: 'task',
1983
+ short: 't',
1984
+ description: 'Task description to route',
1985
+ type: 'string',
1986
+ required: true
1987
+ },
1988
+ {
1989
+ name: 'threshold',
1990
+ description: 'Coverage threshold percentage (default: 80)',
1991
+ type: 'number',
1992
+ default: 80
1993
+ },
1994
+ {
1995
+ name: 'no-ruvector',
1996
+ description: 'Disable ruvector integration',
1997
+ type: 'boolean',
1998
+ default: false
1999
+ }
2000
+ ],
2001
+ examples: [
2002
+ { command: 'claude-flow hooks coverage-route -t "fix bug in auth"', description: 'Route with coverage awareness' },
2003
+ { command: 'claude-flow hooks coverage-route -t "add tests" --threshold 90', description: 'Route with custom threshold' }
2004
+ ],
2005
+ action: async (ctx) => {
2006
+ const task = ctx.args[0] || ctx.flags.task;
2007
+ const threshold = ctx.flags.threshold || 80;
2008
+ const useRuvector = !ctx.flags['no-ruvector'];
2009
+ if (!task) {
2010
+ output.printError('Task description is required. Use --task or -t flag.');
2011
+ return { success: false, exitCode: 1 };
2012
+ }
2013
+ const spinner = output.createSpinner({ text: 'Analyzing coverage and routing task...' });
2014
+ spinner.start();
2015
+ try {
2016
+ const result = await callMCPTool('hooks/coverage-route', {
2017
+ task,
2018
+ threshold,
2019
+ useRuvector,
2020
+ });
2021
+ spinner.stop();
2022
+ if (ctx.flags.format === 'json') {
2023
+ output.printJson(result);
2024
+ return { success: true, data: result };
2025
+ }
2026
+ output.writeln();
2027
+ output.printBox([
2028
+ `Agent: ${output.highlight(result.routing.primaryAgent)}`,
2029
+ `Confidence: ${(result.routing.confidence * 100).toFixed(1)}%`,
2030
+ `Coverage-Aware: ${result.coverageAware ? output.success('Yes') : output.dim('No coverage data')}`,
2031
+ `Reason: ${result.routing.reason}`
2032
+ ].join('\n'), 'Coverage-Aware Routing');
2033
+ if (result.gaps.length > 0) {
2034
+ output.writeln();
2035
+ output.writeln(output.bold('Priority Coverage Gaps'));
2036
+ output.printTable({
2037
+ columns: [
2038
+ { key: 'filePath', header: 'File', width: 35, format: (v) => {
2039
+ const s = String(v);
2040
+ return s.length > 32 ? '...' + s.slice(-32) : s;
2041
+ } },
2042
+ { key: 'coveragePercent', header: 'Coverage', width: 10, align: 'right', format: (v) => `${Number(v).toFixed(1)}%` },
2043
+ { key: 'gapType', header: 'Type', width: 10 },
2044
+ { key: 'suggestedAgents', header: 'Agent', width: 15, format: (v) => Array.isArray(v) ? v[0] || '' : String(v) }
2045
+ ],
2046
+ data: result.gaps.slice(0, 8)
2047
+ });
2048
+ }
2049
+ if (result.metrics.filesAnalyzed > 0) {
2050
+ output.writeln();
2051
+ output.writeln(output.bold('Coverage Metrics'));
2052
+ output.printList([
2053
+ `Files Analyzed: ${result.metrics.filesAnalyzed}`,
2054
+ `Total Gaps: ${result.metrics.totalGaps}`,
2055
+ `Critical Gaps: ${result.metrics.criticalGaps}`,
2056
+ `Average Coverage: ${result.metrics.avgCoverage.toFixed(1)}%`
2057
+ ]);
2058
+ }
2059
+ if (result.suggestions.length > 0) {
2060
+ output.writeln();
2061
+ output.writeln(output.bold('Suggestions'));
2062
+ output.printList(result.suggestions.map(s => output.dim(s)));
2063
+ }
2064
+ return { success: true, data: result };
2065
+ }
2066
+ catch (error) {
2067
+ spinner.fail('Coverage routing failed');
2068
+ if (error instanceof MCPClientError) {
2069
+ output.printError(`Error: ${error.message}`);
2070
+ }
2071
+ else {
2072
+ output.printError(`Unexpected error: ${String(error)}`);
2073
+ }
2074
+ return { success: false, exitCode: 1 };
2075
+ }
2076
+ }
2077
+ };
2078
+ // Coverage suggest subcommand
2079
+ const coverageSuggestCommand = {
2080
+ name: 'coverage-suggest',
2081
+ description: 'Suggest coverage improvements for a path (ruvector integration)',
2082
+ options: [
2083
+ {
2084
+ name: 'path',
2085
+ short: 'p',
2086
+ description: 'Path to analyze for coverage suggestions',
2087
+ type: 'string',
2088
+ required: true
2089
+ },
2090
+ {
2091
+ name: 'threshold',
2092
+ description: 'Coverage threshold percentage (default: 80)',
2093
+ type: 'number',
2094
+ default: 80
2095
+ },
2096
+ {
2097
+ name: 'limit',
2098
+ short: 'l',
2099
+ description: 'Maximum number of suggestions (default: 20)',
2100
+ type: 'number',
2101
+ default: 20
2102
+ }
2103
+ ],
2104
+ examples: [
2105
+ { command: 'claude-flow hooks coverage-suggest -p src/', description: 'Suggest improvements for src/' },
2106
+ { command: 'claude-flow hooks coverage-suggest -p src/services --threshold 90', description: 'Stricter threshold' }
2107
+ ],
2108
+ action: async (ctx) => {
2109
+ const path = ctx.args[0] || ctx.flags.path;
2110
+ const threshold = ctx.flags.threshold || 80;
2111
+ const limit = ctx.flags.limit || 20;
2112
+ if (!path) {
2113
+ output.printError('Path is required. Use --path or -p flag.');
2114
+ return { success: false, exitCode: 1 };
2115
+ }
2116
+ const spinner = output.createSpinner({ text: `Analyzing coverage for ${path}...` });
2117
+ spinner.start();
2118
+ try {
2119
+ const result = await callMCPTool('hooks/coverage-suggest', {
2120
+ path,
2121
+ threshold,
2122
+ limit,
2123
+ });
2124
+ spinner.stop();
2125
+ if (ctx.flags.format === 'json') {
2126
+ output.printJson(result);
2127
+ return { success: true, data: result };
2128
+ }
2129
+ output.writeln();
2130
+ output.printBox([
2131
+ `Path: ${output.highlight(result.path)}`,
2132
+ `Files Analyzed: ${result.summary.totalFiles}`,
2133
+ `Line Coverage: ${result.summary.overallLineCoverage.toFixed(1)}%`,
2134
+ `Branch Coverage: ${result.summary.overallBranchCoverage.toFixed(1)}%`,
2135
+ `Below Threshold: ${result.summary.filesBelowThreshold} files`,
2136
+ `RuVector: ${result.ruvectorAvailable ? output.success('Available') : output.dim('Not installed')}`
2137
+ ].join('\n'), 'Coverage Summary');
2138
+ if (result.suggestions.length > 0) {
2139
+ output.writeln();
2140
+ output.writeln(output.bold('Coverage Improvement Suggestions'));
2141
+ output.printTable({
2142
+ columns: [
2143
+ { key: 'filePath', header: 'File', width: 40, format: (v) => {
2144
+ const s = String(v);
2145
+ return s.length > 37 ? '...' + s.slice(-37) : s;
2146
+ } },
2147
+ { key: 'coveragePercent', header: 'Coverage', width: 10, align: 'right', format: (v) => `${Number(v).toFixed(1)}%` },
2148
+ { key: 'gapType', header: 'Priority', width: 10 },
2149
+ { key: 'reason', header: 'Reason', width: 25 }
2150
+ ],
2151
+ data: result.suggestions.slice(0, 15)
2152
+ });
2153
+ }
2154
+ else {
2155
+ output.writeln();
2156
+ output.printSuccess('All files meet coverage threshold!');
2157
+ }
2158
+ if (result.prioritizedFiles.length > 0) {
2159
+ output.writeln();
2160
+ output.writeln(output.bold('Priority Files (Top 5)'));
2161
+ output.printList(result.prioritizedFiles.slice(0, 5).map(f => output.highlight(f)));
2162
+ }
2163
+ return { success: true, data: result };
2164
+ }
2165
+ catch (error) {
2166
+ spinner.fail('Coverage analysis failed');
2167
+ if (error instanceof MCPClientError) {
2168
+ output.printError(`Error: ${error.message}`);
2169
+ }
2170
+ else {
2171
+ output.printError(`Unexpected error: ${String(error)}`);
2172
+ }
2173
+ return { success: false, exitCode: 1 };
2174
+ }
2175
+ }
2176
+ };
2177
+ // Coverage gaps subcommand
2178
+ const coverageGapsCommand = {
2179
+ name: 'coverage-gaps',
2180
+ description: 'List all coverage gaps with priority scoring and agent assignments',
2181
+ options: [
2182
+ {
2183
+ name: 'threshold',
2184
+ description: 'Coverage threshold percentage (default: 80)',
2185
+ type: 'number',
2186
+ default: 80
2187
+ },
2188
+ {
2189
+ name: 'group-by-agent',
2190
+ description: 'Group gaps by suggested agent (default: true)',
2191
+ type: 'boolean',
2192
+ default: true
2193
+ },
2194
+ {
2195
+ name: 'critical-only',
2196
+ description: 'Show only critical gaps',
2197
+ type: 'boolean',
2198
+ default: false
2199
+ }
2200
+ ],
2201
+ examples: [
2202
+ { command: 'claude-flow hooks coverage-gaps', description: 'List all coverage gaps' },
2203
+ { command: 'claude-flow hooks coverage-gaps --critical-only', description: 'Only critical gaps' },
2204
+ { command: 'claude-flow hooks coverage-gaps --threshold 90', description: 'Stricter threshold' }
2205
+ ],
2206
+ action: async (ctx) => {
2207
+ const threshold = ctx.flags.threshold || 80;
2208
+ const groupByAgent = ctx.flags['group-by-agent'] !== false;
2209
+ const criticalOnly = ctx.flags['critical-only'] || false;
2210
+ const spinner = output.createSpinner({ text: 'Analyzing project coverage gaps...' });
2211
+ spinner.start();
2212
+ try {
2213
+ const result = await callMCPTool('hooks/coverage-gaps', {
2214
+ threshold,
2215
+ groupByAgent,
2216
+ });
2217
+ spinner.stop();
2218
+ // Filter if critical-only
2219
+ const gaps = criticalOnly
2220
+ ? result.gaps.filter(g => g.gapType === 'critical')
2221
+ : result.gaps;
2222
+ if (ctx.flags.format === 'json') {
2223
+ output.printJson({ ...result, gaps });
2224
+ return { success: true, data: result };
2225
+ }
2226
+ output.writeln();
2227
+ output.printBox([
2228
+ `Total Files: ${result.summary.totalFiles}`,
2229
+ `Line Coverage: ${result.summary.overallLineCoverage.toFixed(1)}%`,
2230
+ `Branch Coverage: ${result.summary.overallBranchCoverage.toFixed(1)}%`,
2231
+ `Below ${result.summary.coverageThreshold}%: ${result.summary.filesBelowThreshold} files`,
2232
+ `RuVector: ${result.ruvectorAvailable ? output.success('Available') : output.dim('Not installed')}`
2233
+ ].join('\n'), 'Coverage Gap Analysis');
2234
+ if (gaps.length > 0) {
2235
+ output.writeln();
2236
+ output.writeln(output.bold(`Coverage Gaps (${gaps.length} files)`));
2237
+ output.printTable({
2238
+ columns: [
2239
+ { key: 'filePath', header: 'File', width: 35, format: (v) => {
2240
+ const s = String(v);
2241
+ return s.length > 32 ? '...' + s.slice(-32) : s;
2242
+ } },
2243
+ { key: 'coveragePercent', header: 'Coverage', width: 10, align: 'right', format: (v) => `${Number(v).toFixed(1)}%` },
2244
+ { key: 'gapType', header: 'Type', width: 10, format: (v) => {
2245
+ const t = String(v);
2246
+ if (t === 'critical')
2247
+ return output.error(t);
2248
+ if (t === 'high')
2249
+ return output.warning(t);
2250
+ return t;
2251
+ } },
2252
+ { key: 'priority', header: 'Priority', width: 8, align: 'right' },
2253
+ { key: 'suggestedAgents', header: 'Agent', width: 12, format: (v) => Array.isArray(v) ? v[0] || '' : String(v) }
2254
+ ],
2255
+ data: gaps.slice(0, 20)
2256
+ });
2257
+ }
2258
+ else {
2259
+ output.writeln();
2260
+ output.printSuccess('No coverage gaps found! All files meet threshold.');
2261
+ }
2262
+ if (groupByAgent && Object.keys(result.agentAssignments).length > 0) {
2263
+ output.writeln();
2264
+ output.writeln(output.bold('Agent Assignments'));
2265
+ for (const [agent, files] of Object.entries(result.agentAssignments)) {
2266
+ output.writeln();
2267
+ output.writeln(` ${output.highlight(agent)} (${files.length} files)`);
2268
+ files.slice(0, 3).forEach(f => {
2269
+ output.writeln(` - ${output.dim(f)}`);
2270
+ });
2271
+ if (files.length > 3) {
2272
+ output.writeln(` ... and ${files.length - 3} more`);
2273
+ }
2274
+ }
2275
+ }
2276
+ return { success: true, data: result };
2277
+ }
2278
+ catch (error) {
2279
+ spinner.fail('Coverage gap analysis failed');
2280
+ if (error instanceof MCPClientError) {
2281
+ output.printError(`Error: ${error.message}`);
2282
+ }
2283
+ else {
2284
+ output.printError(`Unexpected error: ${String(error)}`);
2285
+ }
2286
+ return { success: false, exitCode: 1 };
2287
+ }
2288
+ }
2289
+ };
1973
2290
  // Worker parent command
1974
2291
  const workerCommand = {
1975
2292
  name: 'worker',
@@ -2044,6 +2361,10 @@ export const hooksCommand = {
2044
2361
  listCommand,
2045
2362
  intelligenceCommand,
2046
2363
  workerCommand,
2364
+ // Coverage-aware routing commands
2365
+ coverageRouteCommand,
2366
+ coverageSuggestCommand,
2367
+ coverageGapsCommand,
2047
2368
  ],
2048
2369
  options: [],
2049
2370
  examples: [
@@ -2077,7 +2398,10 @@ export const hooksCommand = {
2077
2398
  `${output.highlight('metrics')} - View learning metrics dashboard`,
2078
2399
  `${output.highlight('transfer')} - Transfer patterns from another project`,
2079
2400
  `${output.highlight('list')} - List all registered hooks`,
2080
- `${output.highlight('worker')} - Background worker management (12 workers)`
2401
+ `${output.highlight('worker')} - Background worker management (12 workers)`,
2402
+ `${output.highlight('coverage-route')} - Route tasks based on coverage gaps (ruvector)`,
2403
+ `${output.highlight('coverage-suggest')}- Suggest coverage improvements`,
2404
+ `${output.highlight('coverage-gaps')} - List all coverage gaps with agents`
2081
2405
  ]);
2082
2406
  output.writeln();
2083
2407
  output.writeln('Run "claude-flow hooks <subcommand> --help" for subcommand help');