monomind 1.17.0 → 1.17.2
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.
- package/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/.claude/commands/mastermind/_repeat.md +4 -0
- package/.claude/commands/mastermind/master.md +52 -1
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/mastermind/_repeat.md +2 -0
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
- package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
- package/packages/@monomind/cli/dist/src/agents/registry-builder.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/agents/registry-builder.js +22 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
- package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +20 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +432 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +54 -943
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
- package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
- package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
- package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
- package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
- package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
- package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
- package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
- package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
- package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
- package/packages/@monomind/cli/dist/src/index.js +8 -37
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
- package/packages/@monomind/cli/dist/src/parser.js +11 -6
- package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
- package/packages/@monomind/cli/package.json +2 -3
- package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage gaps and progress hook commands
|
|
3
|
+
*/
|
|
4
|
+
import { output } from '../output.js';
|
|
5
|
+
import { callMCPTool, MCPClientError } from '../mcp-client.js';
|
|
6
|
+
import { readCoverageFromDisk, classifyCoverageGap, suggestAgentsForFile, } from './hooks-coverage-utils.js';
|
|
7
|
+
export const coverageGapsCommand = {
|
|
8
|
+
name: 'coverage-gaps',
|
|
9
|
+
description: 'List all coverage gaps with priority scoring and agent assignments',
|
|
10
|
+
options: [
|
|
11
|
+
{
|
|
12
|
+
name: 'threshold',
|
|
13
|
+
description: 'Coverage threshold percentage (default: 80)',
|
|
14
|
+
type: 'number',
|
|
15
|
+
default: 80
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'group-by-agent',
|
|
19
|
+
description: 'Group gaps by suggested agent (default: true)',
|
|
20
|
+
type: 'boolean',
|
|
21
|
+
default: true
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'critical-only',
|
|
25
|
+
description: 'Show only critical gaps',
|
|
26
|
+
type: 'boolean',
|
|
27
|
+
default: false
|
|
28
|
+
}
|
|
29
|
+
],
|
|
30
|
+
examples: [
|
|
31
|
+
{ command: 'monomind hooks coverage-gaps', description: 'List all coverage gaps' },
|
|
32
|
+
{ command: 'monomind hooks coverage-gaps --critical-only', description: 'Only critical gaps' },
|
|
33
|
+
{ command: 'monomind hooks coverage-gaps --threshold 90', description: 'Stricter threshold' }
|
|
34
|
+
],
|
|
35
|
+
action: async (ctx) => {
|
|
36
|
+
const threshold = ctx.flags.threshold || 80;
|
|
37
|
+
const groupByAgent = ctx.flags['group-by-agent'] !== false;
|
|
38
|
+
const criticalOnly = ctx.flags['critical-only'] || false;
|
|
39
|
+
const spinner = output.createSpinner({ text: 'Analyzing project coverage gaps...' });
|
|
40
|
+
spinner.start();
|
|
41
|
+
const diskCoverage = readCoverageFromDisk();
|
|
42
|
+
if (diskCoverage.found) {
|
|
43
|
+
spinner.succeed(`Coverage data loaded from ${diskCoverage.source}`);
|
|
44
|
+
const allGaps = diskCoverage.entries
|
|
45
|
+
.filter(e => e.lines < threshold)
|
|
46
|
+
.map(e => {
|
|
47
|
+
const { gapType, priority } = classifyCoverageGap(e.lines, threshold);
|
|
48
|
+
return {
|
|
49
|
+
filePath: e.filePath,
|
|
50
|
+
coveragePercent: e.lines,
|
|
51
|
+
gapType,
|
|
52
|
+
complexity: Math.round((100 - e.lines) / 10),
|
|
53
|
+
priority,
|
|
54
|
+
suggestedAgents: suggestAgentsForFile(e.filePath),
|
|
55
|
+
reason: `Line coverage ${e.lines.toFixed(1)}% below ${threshold}% threshold`,
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
const gaps = criticalOnly
|
|
59
|
+
? allGaps.filter(g => g.gapType === 'critical')
|
|
60
|
+
: allGaps;
|
|
61
|
+
const agentAssignments = {};
|
|
62
|
+
if (groupByAgent) {
|
|
63
|
+
for (const gap of gaps) {
|
|
64
|
+
const agent = gap.suggestedAgents[0] || 'tester';
|
|
65
|
+
if (!agentAssignments[agent])
|
|
66
|
+
agentAssignments[agent] = [];
|
|
67
|
+
agentAssignments[agent].push(gap.filePath);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const result = {
|
|
71
|
+
success: true,
|
|
72
|
+
gaps,
|
|
73
|
+
summary: {
|
|
74
|
+
totalFiles: diskCoverage.summary.totalFiles,
|
|
75
|
+
overallLineCoverage: diskCoverage.summary.overallLineCoverage,
|
|
76
|
+
overallBranchCoverage: diskCoverage.summary.overallBranchCoverage,
|
|
77
|
+
filesBelowThreshold: gaps.length,
|
|
78
|
+
coverageThreshold: threshold,
|
|
79
|
+
},
|
|
80
|
+
agentAssignments,
|
|
81
|
+
monovectorAvailable: false,
|
|
82
|
+
source: diskCoverage.source,
|
|
83
|
+
};
|
|
84
|
+
if (ctx.flags.format === 'json') {
|
|
85
|
+
output.printJson(result);
|
|
86
|
+
return { success: true, data: result };
|
|
87
|
+
}
|
|
88
|
+
output.writeln();
|
|
89
|
+
output.printBox([
|
|
90
|
+
`Total Files: ${result.summary.totalFiles}`,
|
|
91
|
+
`Line Coverage: ${result.summary.overallLineCoverage.toFixed(1)}%`,
|
|
92
|
+
`Branch Coverage: ${result.summary.overallBranchCoverage.toFixed(1)}%`,
|
|
93
|
+
`Below ${threshold}%: ${result.summary.filesBelowThreshold} files`,
|
|
94
|
+
`Source: ${output.highlight(diskCoverage.source)}`
|
|
95
|
+
].join('\n'), 'Coverage Gap Analysis');
|
|
96
|
+
if (gaps.length > 0) {
|
|
97
|
+
output.writeln();
|
|
98
|
+
output.writeln(output.bold(`Coverage Gaps (${gaps.length} files)`));
|
|
99
|
+
output.printTable({
|
|
100
|
+
columns: [
|
|
101
|
+
{ key: 'filePath', header: 'File', width: 35, format: (v) => {
|
|
102
|
+
const s = String(v);
|
|
103
|
+
return s.length > 32 ? '...' + s.slice(-32) : s;
|
|
104
|
+
} },
|
|
105
|
+
{ key: 'coveragePercent', header: 'Coverage', width: 10, align: 'right', format: (v) => `${Number(v).toFixed(1)}%` },
|
|
106
|
+
{ key: 'gapType', header: 'Type', width: 10, format: (v) => {
|
|
107
|
+
const t = String(v);
|
|
108
|
+
if (t === 'critical')
|
|
109
|
+
return output.error(t);
|
|
110
|
+
if (t === 'high')
|
|
111
|
+
return output.warning(t);
|
|
112
|
+
return t;
|
|
113
|
+
} },
|
|
114
|
+
{ key: 'priority', header: 'Priority', width: 8, align: 'right' },
|
|
115
|
+
{ key: 'suggestedAgents', header: 'Agent', width: 12, format: (v) => Array.isArray(v) ? v[0] || '' : String(v) }
|
|
116
|
+
],
|
|
117
|
+
data: gaps.slice(0, 20)
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
else {
|
|
121
|
+
output.writeln();
|
|
122
|
+
output.printSuccess('No coverage gaps found! All files meet threshold.');
|
|
123
|
+
}
|
|
124
|
+
if (groupByAgent && Object.keys(agentAssignments).length > 0) {
|
|
125
|
+
output.writeln();
|
|
126
|
+
output.writeln(output.bold('Agent Assignments'));
|
|
127
|
+
for (const [agent, files] of Object.entries(agentAssignments)) {
|
|
128
|
+
output.writeln();
|
|
129
|
+
output.writeln(` ${output.highlight(agent)} (${files.length} files)`);
|
|
130
|
+
files.slice(0, 3).forEach(f => {
|
|
131
|
+
output.writeln(` - ${output.dim(f)}`);
|
|
132
|
+
});
|
|
133
|
+
if (files.length > 3) {
|
|
134
|
+
output.writeln(` ... and ${files.length - 3} more`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
return { success: true, data: result };
|
|
139
|
+
}
|
|
140
|
+
try {
|
|
141
|
+
const result = await callMCPTool('hooks_coverage-gaps', { threshold, groupByAgent });
|
|
142
|
+
spinner.stop();
|
|
143
|
+
const gaps = criticalOnly
|
|
144
|
+
? result.gaps.filter(g => g.gapType === 'critical')
|
|
145
|
+
: result.gaps;
|
|
146
|
+
if (ctx.flags.format === 'json') {
|
|
147
|
+
output.printJson({ ...result, gaps });
|
|
148
|
+
return { success: true, data: result };
|
|
149
|
+
}
|
|
150
|
+
output.writeln();
|
|
151
|
+
output.printBox([
|
|
152
|
+
`Total Files: ${result.summary.totalFiles}`,
|
|
153
|
+
`Line Coverage: ${result.summary.overallLineCoverage.toFixed(1)}%`,
|
|
154
|
+
`Branch Coverage: ${result.summary.overallBranchCoverage.toFixed(1)}%`,
|
|
155
|
+
`Below ${result.summary.coverageThreshold}%: ${result.summary.filesBelowThreshold} files`,
|
|
156
|
+
`Keyword routing: ${result.monovectorAvailable ? output.success('Available') : output.dim('Unavailable')}`
|
|
157
|
+
].join('\n'), 'Coverage Gap Analysis');
|
|
158
|
+
if (gaps.length > 0) {
|
|
159
|
+
output.writeln();
|
|
160
|
+
output.writeln(output.bold(`Coverage Gaps (${gaps.length} files)`));
|
|
161
|
+
output.printTable({
|
|
162
|
+
columns: [
|
|
163
|
+
{ key: 'filePath', header: 'File', width: 35, format: (v) => {
|
|
164
|
+
const s = String(v);
|
|
165
|
+
return s.length > 32 ? '...' + s.slice(-32) : s;
|
|
166
|
+
} },
|
|
167
|
+
{ key: 'coveragePercent', header: 'Coverage', width: 10, align: 'right', format: (v) => `${Number(v).toFixed(1)}%` },
|
|
168
|
+
{ key: 'gapType', header: 'Type', width: 10, format: (v) => {
|
|
169
|
+
const t = String(v);
|
|
170
|
+
if (t === 'critical')
|
|
171
|
+
return output.error(t);
|
|
172
|
+
if (t === 'high')
|
|
173
|
+
return output.warning(t);
|
|
174
|
+
return t;
|
|
175
|
+
} },
|
|
176
|
+
{ key: 'priority', header: 'Priority', width: 8, align: 'right' },
|
|
177
|
+
{ key: 'suggestedAgents', header: 'Agent', width: 12, format: (v) => Array.isArray(v) ? v[0] || '' : String(v) }
|
|
178
|
+
],
|
|
179
|
+
data: gaps.slice(0, 20)
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
else {
|
|
183
|
+
output.writeln();
|
|
184
|
+
output.printSuccess('No coverage gaps found! All files meet threshold.');
|
|
185
|
+
}
|
|
186
|
+
if (groupByAgent && Object.keys(result.agentAssignments).length > 0) {
|
|
187
|
+
output.writeln();
|
|
188
|
+
output.writeln(output.bold('Agent Assignments'));
|
|
189
|
+
for (const [agent, files] of Object.entries(result.agentAssignments)) {
|
|
190
|
+
output.writeln();
|
|
191
|
+
output.writeln(` ${output.highlight(agent)} (${files.length} files)`);
|
|
192
|
+
files.slice(0, 3).forEach(f => {
|
|
193
|
+
output.writeln(` - ${output.dim(f)}`);
|
|
194
|
+
});
|
|
195
|
+
if (files.length > 3) {
|
|
196
|
+
output.writeln(` ... and ${files.length - 3} more`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
return { success: true, data: result };
|
|
201
|
+
}
|
|
202
|
+
catch {
|
|
203
|
+
spinner.fail('No coverage data found');
|
|
204
|
+
output.writeln();
|
|
205
|
+
output.printWarning('No coverage data found. Run your test suite with coverage first.');
|
|
206
|
+
output.writeln();
|
|
207
|
+
output.printList([
|
|
208
|
+
'Jest: npx jest --coverage',
|
|
209
|
+
'Vitest: npx vitest --coverage',
|
|
210
|
+
'nyc: npx nyc npm test',
|
|
211
|
+
'c8: npx c8 npm test',
|
|
212
|
+
]);
|
|
213
|
+
output.writeln();
|
|
214
|
+
output.writeln(output.dim('Expected files: coverage/coverage-summary.json, coverage/lcov.info, or .nyc_output/out.json'));
|
|
215
|
+
return { success: false, exitCode: 1 };
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
};
|
|
219
|
+
export const progressHookCommand = {
|
|
220
|
+
name: 'progress',
|
|
221
|
+
description: 'Check implementation progress via hooks',
|
|
222
|
+
options: [
|
|
223
|
+
{
|
|
224
|
+
name: 'detailed',
|
|
225
|
+
short: 'd',
|
|
226
|
+
description: 'Show detailed breakdown by category',
|
|
227
|
+
type: 'boolean',
|
|
228
|
+
default: false
|
|
229
|
+
},
|
|
230
|
+
{
|
|
231
|
+
name: 'sync',
|
|
232
|
+
short: 's',
|
|
233
|
+
description: 'Sync and persist progress to file',
|
|
234
|
+
type: 'boolean',
|
|
235
|
+
default: false
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
name: 'summary',
|
|
239
|
+
description: 'Show human-readable summary',
|
|
240
|
+
type: 'boolean',
|
|
241
|
+
default: false
|
|
242
|
+
}
|
|
243
|
+
],
|
|
244
|
+
examples: [
|
|
245
|
+
{ command: 'monomind hooks progress', description: 'Check current progress' },
|
|
246
|
+
{ command: 'monomind hooks progress -d', description: 'Detailed breakdown' },
|
|
247
|
+
{ command: 'monomind hooks progress --sync', description: 'Sync progress to file' },
|
|
248
|
+
{ command: 'monomind hooks progress --summary', description: 'Human-readable summary' }
|
|
249
|
+
],
|
|
250
|
+
action: async (ctx) => {
|
|
251
|
+
const detailed = ctx.flags.detailed;
|
|
252
|
+
const sync = ctx.flags.sync;
|
|
253
|
+
const summary = ctx.flags.summary;
|
|
254
|
+
try {
|
|
255
|
+
if (summary) {
|
|
256
|
+
const spinner = output.createSpinner({ text: 'Getting progress summary...' });
|
|
257
|
+
spinner.start();
|
|
258
|
+
const result = await callMCPTool('progress_summary', {});
|
|
259
|
+
spinner.stop();
|
|
260
|
+
if (ctx.flags.format === 'json') {
|
|
261
|
+
output.printJson(result);
|
|
262
|
+
return { success: true, data: result };
|
|
263
|
+
}
|
|
264
|
+
output.writeln();
|
|
265
|
+
output.writeln(result.summary);
|
|
266
|
+
return { success: true, data: result };
|
|
267
|
+
}
|
|
268
|
+
if (sync) {
|
|
269
|
+
const spinner = output.createSpinner({ text: 'Syncing progress...' });
|
|
270
|
+
spinner.start();
|
|
271
|
+
const result = await callMCPTool('progress_sync', {});
|
|
272
|
+
spinner.stop();
|
|
273
|
+
if (ctx.flags.format === 'json') {
|
|
274
|
+
output.printJson(result);
|
|
275
|
+
return { success: true, data: result };
|
|
276
|
+
}
|
|
277
|
+
output.writeln();
|
|
278
|
+
output.printSuccess(`Progress synced: ${result.progress}%`);
|
|
279
|
+
output.writeln(output.dim(` Persisted to .monomind/metrics/v1-progress.json`));
|
|
280
|
+
output.writeln(output.dim(` Last updated: ${result.lastUpdated}`));
|
|
281
|
+
return { success: true, data: result };
|
|
282
|
+
}
|
|
283
|
+
const spinner = output.createSpinner({ text: 'Checking v1 progress...' });
|
|
284
|
+
spinner.start();
|
|
285
|
+
const result = await callMCPTool('progress_check', { detailed });
|
|
286
|
+
spinner.stop();
|
|
287
|
+
if (ctx.flags.format === 'json') {
|
|
288
|
+
output.printJson(result);
|
|
289
|
+
return { success: true, data: result };
|
|
290
|
+
}
|
|
291
|
+
output.writeln();
|
|
292
|
+
const progressValue = result.overall ?? result.progress ?? 0;
|
|
293
|
+
const barWidth = 30;
|
|
294
|
+
const filled = Math.round((progressValue / 100) * barWidth);
|
|
295
|
+
const empty = barWidth - filled;
|
|
296
|
+
const bar = output.success('█'.repeat(filled)) + output.dim('░'.repeat(empty));
|
|
297
|
+
output.writeln(output.bold('v1 Implementation Progress'));
|
|
298
|
+
output.writeln();
|
|
299
|
+
output.writeln(`[${bar}] ${progressValue}%`);
|
|
300
|
+
output.writeln();
|
|
301
|
+
if (detailed && result.cli) {
|
|
302
|
+
output.writeln(output.highlight('CLI Commands:') + ` ${result.cli.progress}% (${result.cli.commands}/${result.cli.target})`);
|
|
303
|
+
output.writeln(output.highlight('MCP Tools:') + ` ${result.mcp?.progress ?? 0}% (${result.mcp?.tools ?? 0}/${result.mcp?.target ?? 0})`);
|
|
304
|
+
output.writeln(output.highlight('Hooks:') + ` ${result.hooks?.progress ?? 0}% (${result.hooks?.subcommands ?? 0}/${result.hooks?.target ?? 0})`);
|
|
305
|
+
output.writeln(output.highlight('Packages:') + ` ${result.packages?.progress ?? 0}% (${result.packages?.total ?? 0}/${result.packages?.target ?? 0})`);
|
|
306
|
+
output.writeln(output.highlight('DDD Structure:') + ` ${result.ddd?.progress ?? 0}% (${result.packages?.withDDD ?? 0}/${result.packages?.total ?? 0})`);
|
|
307
|
+
output.writeln();
|
|
308
|
+
if (result.codebase) {
|
|
309
|
+
output.writeln(output.dim(`Codebase: ${result.codebase.totalFiles} files, ${result.codebase.totalLines.toLocaleString()} lines`));
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
else if (result.breakdown) {
|
|
313
|
+
output.writeln('Breakdown:');
|
|
314
|
+
for (const [category, value] of Object.entries(result.breakdown)) {
|
|
315
|
+
output.writeln(` ${output.highlight(category)}: ${value}`);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (result.lastUpdated) {
|
|
319
|
+
output.writeln(output.dim(`Last updated: ${result.lastUpdated}`));
|
|
320
|
+
}
|
|
321
|
+
return { success: true, data: result };
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
if (error instanceof MCPClientError) {
|
|
325
|
+
output.printError(`Progress check failed: ${error.message}`);
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
output.printError(`Progress check failed: ${String(error)}`);
|
|
329
|
+
}
|
|
330
|
+
return { success: false, exitCode: 1 };
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
};
|
|
334
|
+
//# sourceMappingURL=hooks-coverage-gaps.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Coverage-aware routing commands: coverage-route, coverage-suggest
|
|
3
|
+
*/
|
|
4
|
+
import type { Command } from '../types.js';
|
|
5
|
+
export declare const coverageRouteCommand: Command;
|
|
6
|
+
export declare const coverageSuggestCommand: Command;
|
|
7
|
+
//# sourceMappingURL=hooks-coverage-routing.d.ts.map
|