@vyuhlabs/dxkit 1.5.1 → 1.6.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.
- package/CHANGELOG.md +264 -0
- package/README.md +265 -352
- package/THIRD_PARTY_NOTICES.md +40 -0
- package/dist/analyzers/developer/detailed.d.ts +26 -0
- package/dist/analyzers/developer/detailed.d.ts.map +1 -0
- package/dist/analyzers/developer/detailed.js +193 -0
- package/dist/analyzers/developer/detailed.js.map +1 -0
- package/dist/analyzers/developer/gather.d.ts +11 -0
- package/dist/analyzers/developer/gather.d.ts.map +1 -0
- package/dist/analyzers/developer/gather.js +167 -0
- package/dist/analyzers/developer/gather.js.map +1 -0
- package/dist/analyzers/developer/index.d.ts +8 -0
- package/dist/analyzers/developer/index.d.ts.map +1 -0
- package/dist/analyzers/developer/index.js +168 -0
- package/dist/analyzers/developer/index.js.map +1 -0
- package/dist/analyzers/developer/types.d.ts +49 -0
- package/dist/analyzers/developer/types.d.ts.map +1 -0
- package/dist/analyzers/developer/types.js +6 -0
- package/dist/analyzers/developer/types.js.map +1 -0
- package/dist/analyzers/docs/shallow.d.ts +9 -0
- package/dist/analyzers/docs/shallow.d.ts.map +1 -0
- package/dist/analyzers/docs/shallow.js +8 -0
- package/dist/analyzers/docs/shallow.js.map +1 -0
- package/dist/analyzers/dx/shallow.d.ts +9 -0
- package/dist/analyzers/dx/shallow.d.ts.map +1 -0
- package/dist/analyzers/dx/shallow.js +8 -0
- package/dist/analyzers/dx/shallow.js.map +1 -0
- package/dist/analyzers/evidence.d.ts +36 -0
- package/dist/analyzers/evidence.d.ts.map +1 -0
- package/dist/analyzers/evidence.js +3 -0
- package/dist/analyzers/evidence.js.map +1 -0
- package/dist/analyzers/health/actions.d.ts +10 -0
- package/dist/analyzers/health/actions.d.ts.map +1 -0
- package/dist/analyzers/health/actions.js +284 -0
- package/dist/analyzers/health/actions.js.map +1 -0
- package/dist/analyzers/health/detailed.d.ts +26 -0
- package/dist/analyzers/health/detailed.d.ts.map +1 -0
- package/dist/analyzers/health/detailed.js +147 -0
- package/dist/analyzers/health/detailed.js.map +1 -0
- package/dist/analyzers/health.d.ts +22 -0
- package/dist/analyzers/health.d.ts.map +1 -0
- package/dist/analyzers/health.js +270 -0
- package/dist/analyzers/health.js.map +1 -0
- package/dist/analyzers/index.d.ts +3 -0
- package/dist/analyzers/index.d.ts.map +1 -0
- package/dist/analyzers/index.js +6 -0
- package/dist/analyzers/index.js.map +1 -0
- package/dist/analyzers/maintainability/shallow.d.ts +9 -0
- package/dist/analyzers/maintainability/shallow.d.ts.map +1 -0
- package/dist/analyzers/maintainability/shallow.js +8 -0
- package/dist/analyzers/maintainability/shallow.js.map +1 -0
- package/dist/analyzers/quality/actions.d.ts +5 -0
- package/dist/analyzers/quality/actions.d.ts.map +1 -0
- package/dist/analyzers/quality/actions.js +158 -0
- package/dist/analyzers/quality/actions.js.map +1 -0
- package/dist/analyzers/quality/detailed.d.ts +17 -0
- package/dist/analyzers/quality/detailed.d.ts.map +1 -0
- package/dist/analyzers/quality/detailed.js +122 -0
- package/dist/analyzers/quality/detailed.js.map +1 -0
- package/dist/analyzers/quality/gather.d.ts +38 -0
- package/dist/analyzers/quality/gather.d.ts.map +1 -0
- package/dist/analyzers/quality/gather.js +279 -0
- package/dist/analyzers/quality/gather.js.map +1 -0
- package/dist/analyzers/quality/index.d.ts +12 -0
- package/dist/analyzers/quality/index.d.ts.map +1 -0
- package/dist/analyzers/quality/index.js +281 -0
- package/dist/analyzers/quality/index.js.map +1 -0
- package/dist/analyzers/quality/shallow.d.ts +9 -0
- package/dist/analyzers/quality/shallow.d.ts.map +1 -0
- package/dist/analyzers/quality/shallow.js +8 -0
- package/dist/analyzers/quality/shallow.js.map +1 -0
- package/dist/analyzers/quality/types.d.ts +66 -0
- package/dist/analyzers/quality/types.d.ts.map +1 -0
- package/dist/analyzers/quality/types.js +3 -0
- package/dist/analyzers/quality/types.js.map +1 -0
- package/dist/analyzers/remediation.d.ts +42 -0
- package/dist/analyzers/remediation.d.ts.map +1 -0
- package/dist/analyzers/remediation.js +28 -0
- package/dist/analyzers/remediation.js.map +1 -0
- package/dist/analyzers/scoring.d.ts +32 -0
- package/dist/analyzers/scoring.d.ts.map +1 -0
- package/dist/analyzers/scoring.js +410 -0
- package/dist/analyzers/scoring.js.map +1 -0
- package/dist/analyzers/security/actions.d.ts +7 -0
- package/dist/analyzers/security/actions.d.ts.map +1 -0
- package/dist/analyzers/security/actions.js +104 -0
- package/dist/analyzers/security/actions.js.map +1 -0
- package/dist/analyzers/security/detailed.d.ts +14 -0
- package/dist/analyzers/security/detailed.d.ts.map +1 -0
- package/dist/analyzers/security/detailed.js +124 -0
- package/dist/analyzers/security/detailed.js.map +1 -0
- package/dist/analyzers/security/gather.d.ts +12 -0
- package/dist/analyzers/security/gather.d.ts.map +1 -0
- package/dist/analyzers/security/gather.js +195 -0
- package/dist/analyzers/security/gather.js.map +1 -0
- package/dist/analyzers/security/index.d.ts +8 -0
- package/dist/analyzers/security/index.d.ts.map +1 -0
- package/dist/analyzers/security/index.js +173 -0
- package/dist/analyzers/security/index.js.map +1 -0
- package/dist/analyzers/security/scoring.d.ts +29 -0
- package/dist/analyzers/security/scoring.d.ts.map +1 -0
- package/dist/analyzers/security/scoring.js +40 -0
- package/dist/analyzers/security/scoring.js.map +1 -0
- package/dist/analyzers/security/shallow.d.ts +10 -0
- package/dist/analyzers/security/shallow.d.ts.map +1 -0
- package/dist/analyzers/security/shallow.js +8 -0
- package/dist/analyzers/security/shallow.js.map +1 -0
- package/dist/analyzers/security/types.d.ts +43 -0
- package/dist/analyzers/security/types.d.ts.map +1 -0
- package/dist/analyzers/security/types.js +6 -0
- package/dist/analyzers/security/types.js.map +1 -0
- package/dist/analyzers/tests/actions.d.ts +6 -0
- package/dist/analyzers/tests/actions.d.ts.map +1 -0
- package/dist/analyzers/tests/actions.js +80 -0
- package/dist/analyzers/tests/actions.js.map +1 -0
- package/dist/analyzers/tests/detailed.d.ts +14 -0
- package/dist/analyzers/tests/detailed.d.ts.map +1 -0
- package/dist/analyzers/tests/detailed.js +121 -0
- package/dist/analyzers/tests/detailed.js.map +1 -0
- package/dist/analyzers/tests/gather.d.ts +5 -0
- package/dist/analyzers/tests/gather.d.ts.map +1 -0
- package/dist/analyzers/tests/gather.js +270 -0
- package/dist/analyzers/tests/gather.js.map +1 -0
- package/dist/analyzers/tests/import-graph.d.ts +48 -0
- package/dist/analyzers/tests/import-graph.d.ts.map +1 -0
- package/dist/analyzers/tests/import-graph.js +231 -0
- package/dist/analyzers/tests/import-graph.js.map +1 -0
- package/dist/analyzers/tests/index.d.ts +8 -0
- package/dist/analyzers/tests/index.d.ts.map +1 -0
- package/dist/analyzers/tests/index.js +247 -0
- package/dist/analyzers/tests/index.js.map +1 -0
- package/dist/analyzers/tests/scoring.d.ts +27 -0
- package/dist/analyzers/tests/scoring.d.ts.map +1 -0
- package/dist/analyzers/tests/scoring.js +38 -0
- package/dist/analyzers/tests/scoring.js.map +1 -0
- package/dist/analyzers/tests/shallow.d.ts +9 -0
- package/dist/analyzers/tests/shallow.d.ts.map +1 -0
- package/dist/analyzers/tests/shallow.js +8 -0
- package/dist/analyzers/tests/shallow.js.map +1 -0
- package/dist/analyzers/tests/types.d.ts +49 -0
- package/dist/analyzers/tests/types.d.ts.map +1 -0
- package/dist/analyzers/tests/types.js +6 -0
- package/dist/analyzers/tests/types.js.map +1 -0
- package/dist/analyzers/tools/cloc.d.ts +8 -0
- package/dist/analyzers/tools/cloc.d.ts.map +1 -0
- package/dist/analyzers/tools/cloc.js +49 -0
- package/dist/analyzers/tools/cloc.js.map +1 -0
- package/dist/analyzers/tools/coverage.d.ts +59 -0
- package/dist/analyzers/tools/coverage.d.ts.map +1 -0
- package/dist/analyzers/tools/coverage.js +280 -0
- package/dist/analyzers/tools/coverage.js.map +1 -0
- package/dist/analyzers/tools/cvss-v4-lookup.d.ts +10 -0
- package/dist/analyzers/tools/cvss-v4-lookup.d.ts.map +1 -0
- package/dist/analyzers/tools/cvss-v4-lookup.js +284 -0
- package/dist/analyzers/tools/cvss-v4-lookup.js.map +1 -0
- package/dist/analyzers/tools/cvss-v4.d.ts +24 -0
- package/dist/analyzers/tools/cvss-v4.d.ts.map +1 -0
- package/dist/analyzers/tools/cvss-v4.js +362 -0
- package/dist/analyzers/tools/cvss-v4.js.map +1 -0
- package/dist/analyzers/tools/default-exclusions.gitignore +56 -0
- package/dist/analyzers/tools/exclusions.d.ts +70 -0
- package/dist/analyzers/tools/exclusions.d.ts.map +1 -0
- package/dist/analyzers/tools/exclusions.js +250 -0
- package/dist/analyzers/tools/exclusions.js.map +1 -0
- package/dist/analyzers/tools/generic.d.ts +4 -0
- package/dist/analyzers/tools/generic.d.ts.map +1 -0
- package/dist/analyzers/tools/generic.js +198 -0
- package/dist/analyzers/tools/generic.js.map +1 -0
- package/dist/analyzers/tools/gitleaks.d.ts +8 -0
- package/dist/analyzers/tools/gitleaks.d.ts.map +1 -0
- package/dist/analyzers/tools/gitleaks.js +58 -0
- package/dist/analyzers/tools/gitleaks.js.map +1 -0
- package/dist/analyzers/tools/graphify.d.ts +4 -0
- package/dist/analyzers/tools/graphify.d.ts.map +1 -0
- package/dist/analyzers/tools/graphify.js +222 -0
- package/dist/analyzers/tools/graphify.js.map +1 -0
- package/dist/analyzers/tools/osv.d.ts +51 -0
- package/dist/analyzers/tools/osv.d.ts.map +1 -0
- package/dist/analyzers/tools/osv.js +188 -0
- package/dist/analyzers/tools/osv.js.map +1 -0
- package/dist/analyzers/tools/parallel.d.ts +8 -0
- package/dist/analyzers/tools/parallel.d.ts.map +1 -0
- package/dist/analyzers/tools/parallel.js +195 -0
- package/dist/analyzers/tools/parallel.js.map +1 -0
- package/dist/analyzers/tools/runner.d.ts +13 -0
- package/dist/analyzers/tools/runner.d.ts.map +1 -0
- package/dist/analyzers/tools/runner.js +109 -0
- package/dist/analyzers/tools/runner.js.map +1 -0
- package/dist/analyzers/tools/suppressions.d.ts +55 -0
- package/dist/analyzers/tools/suppressions.d.ts.map +1 -0
- package/dist/analyzers/tools/suppressions.js +203 -0
- package/dist/analyzers/tools/suppressions.js.map +1 -0
- package/dist/analyzers/tools/timing.d.ts +9 -0
- package/dist/analyzers/tools/timing.d.ts.map +1 -0
- package/dist/analyzers/tools/timing.js +29 -0
- package/dist/analyzers/tools/timing.js.map +1 -0
- package/dist/analyzers/tools/tool-registry.d.ts +86 -0
- package/dist/analyzers/tools/tool-registry.d.ts.map +1 -0
- package/dist/analyzers/tools/tool-registry.js +705 -0
- package/dist/analyzers/tools/tool-registry.js.map +1 -0
- package/dist/analyzers/types.d.ts +125 -0
- package/dist/analyzers/types.d.ts.map +1 -0
- package/dist/analyzers/types.js +11 -0
- package/dist/analyzers/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +405 -0
- package/dist/cli.js.map +1 -1
- package/dist/detect.d.ts.map +1 -1
- package/dist/detect.js +24 -15
- package/dist/detect.js.map +1 -1
- package/dist/languages/csharp.d.ts +5 -0
- package/dist/languages/csharp.d.ts.map +1 -0
- package/dist/languages/csharp.js +265 -0
- package/dist/languages/csharp.js.map +1 -0
- package/dist/languages/go.d.ts +11 -0
- package/dist/languages/go.d.ts.map +1 -0
- package/dist/languages/go.js +321 -0
- package/dist/languages/go.js.map +1 -0
- package/dist/languages/index.d.ts +6 -0
- package/dist/languages/index.d.ts.map +1 -0
- package/dist/languages/index.js +18 -0
- package/dist/languages/index.js.map +1 -0
- package/dist/languages/python.d.ts +3 -0
- package/dist/languages/python.d.ts.map +1 -0
- package/dist/languages/python.js +284 -0
- package/dist/languages/python.js.map +1 -0
- package/dist/languages/rust.d.ts +17 -0
- package/dist/languages/rust.d.ts.map +1 -0
- package/dist/languages/rust.js +333 -0
- package/dist/languages/rust.js.map +1 -0
- package/dist/languages/types.d.ts +38 -0
- package/dist/languages/types.d.ts.map +1 -0
- package/dist/languages/types.js +3 -0
- package/dist/languages/types.js.map +1 -0
- package/dist/languages/typescript.d.ts +15 -0
- package/dist/languages/typescript.d.ts.map +1 -0
- package/dist/languages/typescript.js +353 -0
- package/dist/languages/typescript.js.map +1 -0
- package/dist/logger.d.ts +1 -0
- package/dist/logger.d.ts.map +1 -1
- package/dist/logger.js +25 -12
- package/dist/logger.js.map +1 -1
- package/dist/project-yaml.d.ts.map +1 -1
- package/dist/project-yaml.js +1 -0
- package/dist/project-yaml.js.map +1 -1
- package/dist/tools-cli.d.ts +2 -0
- package/dist/tools-cli.d.ts.map +1 -0
- package/dist/tools-cli.js +231 -0
- package/dist/tools-cli.js.map +1 -0
- package/dist/types.d.ts +10 -0
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -2
- package/templates/.claude/commands/dev-report.md +34 -4
- package/templates/.claude/commands/health.md +45 -2
- package/templates/.claude/commands/quality.md.template +38 -15
- package/templates/.claude/commands/test-gaps.md +36 -2
- package/templates/.claude/commands/vulnerabilities.md +36 -2
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.runToolsCommand = runToolsCommand;
|
|
37
|
+
/**
|
|
38
|
+
* CLI handler for `vyuh-dxkit tools` subcommand.
|
|
39
|
+
*
|
|
40
|
+
* Modes:
|
|
41
|
+
* - `vyuh-dxkit tools` → list status for required tools
|
|
42
|
+
* - `vyuh-dxkit tools install` → interactive install of missing tools
|
|
43
|
+
* - `vyuh-dxkit tools install --yes` → install all missing, no prompts
|
|
44
|
+
*/
|
|
45
|
+
const readline = __importStar(require("readline/promises"));
|
|
46
|
+
const process_1 = require("process");
|
|
47
|
+
const child_process_1 = require("child_process");
|
|
48
|
+
const detect_1 = require("./detect");
|
|
49
|
+
const logger = __importStar(require("./logger"));
|
|
50
|
+
const tool_registry_1 = require("./analyzers/tools/tool-registry");
|
|
51
|
+
const LAYER_ORDER = {
|
|
52
|
+
universal: 1,
|
|
53
|
+
language: 2,
|
|
54
|
+
optional: 3,
|
|
55
|
+
};
|
|
56
|
+
const LAYER_LABEL = {
|
|
57
|
+
universal: 'universal',
|
|
58
|
+
language: 'language ',
|
|
59
|
+
optional: 'optional ',
|
|
60
|
+
};
|
|
61
|
+
function sortByLayer(statuses) {
|
|
62
|
+
return [...statuses].sort((a, b) => {
|
|
63
|
+
const la = LAYER_ORDER[a.requirement.layer] || 99;
|
|
64
|
+
const lb = LAYER_ORDER[b.requirement.layer] || 99;
|
|
65
|
+
if (la !== lb)
|
|
66
|
+
return la - lb;
|
|
67
|
+
return a.name.localeCompare(b.name);
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
function formatStatusLine(s) {
|
|
71
|
+
const icon = s.available ? '\x1b[32m✓\x1b[0m' : '\x1b[31m✗\x1b[0m';
|
|
72
|
+
const name = s.name.padEnd(16);
|
|
73
|
+
const layer = LAYER_LABEL[s.requirement.layer] || s.requirement.layer;
|
|
74
|
+
const forStack = s.requirement.for.padEnd(7);
|
|
75
|
+
if (s.available) {
|
|
76
|
+
const src = s.source === 'path' ? '' : ` (${s.source})`;
|
|
77
|
+
return ` ${icon} ${name} ${layer} ${forStack} ${logger.bold('found')}${src}`;
|
|
78
|
+
}
|
|
79
|
+
return ` ${icon} ${name} ${layer} ${forStack} \x1b[2mmissing\x1b[0m`;
|
|
80
|
+
}
|
|
81
|
+
/** Show tool status for the repo's detected stack. */
|
|
82
|
+
function showStatus(targetPath) {
|
|
83
|
+
const stack = (0, detect_1.detect)(targetPath);
|
|
84
|
+
const langs = Object.entries(stack.languages)
|
|
85
|
+
.filter(([, v]) => v)
|
|
86
|
+
.map(([k]) => k);
|
|
87
|
+
logger.header('vyuh-dxkit tools');
|
|
88
|
+
logger.info(`Stack: ${langs.join(', ') || 'unknown'}`);
|
|
89
|
+
console.log('');
|
|
90
|
+
const statuses = sortByLayer((0, tool_registry_1.checkAllTools)(stack.languages, targetPath));
|
|
91
|
+
console.log(` ${logger.bold('Tool'.padEnd(16))} ${logger.bold('layer'.padEnd(10))} ${logger.bold('for'.padEnd(7))} ${logger.bold('status')}`);
|
|
92
|
+
console.log(` ${'─'.repeat(16)} ${'─'.repeat(10)} ${'─'.repeat(7)} ${'─'.repeat(20)}`);
|
|
93
|
+
for (const s of statuses) {
|
|
94
|
+
console.log(formatStatusLine(s));
|
|
95
|
+
if (s.available && s.version) {
|
|
96
|
+
logger.dim(` version: ${s.version}`);
|
|
97
|
+
}
|
|
98
|
+
if (s.available && s.path && s.source !== 'path') {
|
|
99
|
+
logger.dim(` path: ${s.path}`);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
const missing = statuses.filter((s) => !s.available);
|
|
103
|
+
const total = statuses.length;
|
|
104
|
+
console.log('');
|
|
105
|
+
if (missing.length === 0) {
|
|
106
|
+
logger.success(`All ${total} required tools available.`);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
logger.warn(`${missing.length}/${total} tools missing.`);
|
|
110
|
+
console.log('');
|
|
111
|
+
logger.dim(`Run \`vyuh-dxkit tools install\` to install missing tools interactively.`);
|
|
112
|
+
}
|
|
113
|
+
return statuses;
|
|
114
|
+
}
|
|
115
|
+
async function confirm(rl, question) {
|
|
116
|
+
const answer = await rl.question(` ${question} [Y/n]: `);
|
|
117
|
+
if (!answer.trim())
|
|
118
|
+
return true;
|
|
119
|
+
return answer.trim().toLowerCase().startsWith('y');
|
|
120
|
+
}
|
|
121
|
+
function runInstallCmd(cmd) {
|
|
122
|
+
try {
|
|
123
|
+
// Use bash -c so multi-command scripts (with &&, ||, ;) work
|
|
124
|
+
(0, child_process_1.execSync)(cmd, {
|
|
125
|
+
shell: '/bin/bash',
|
|
126
|
+
stdio: ['inherit', 'inherit', 'inherit'],
|
|
127
|
+
timeout: 600000, // 10 min for downloads
|
|
128
|
+
});
|
|
129
|
+
return { success: true, message: 'installed' };
|
|
130
|
+
}
|
|
131
|
+
catch (err) {
|
|
132
|
+
const e = err;
|
|
133
|
+
return { success: false, message: e.message || 'unknown error' };
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
/** Interactive install of missing tools. */
|
|
137
|
+
async function runInstall(targetPath, autoYes) {
|
|
138
|
+
const statuses = showStatus(targetPath);
|
|
139
|
+
const missing = statuses.filter((s) => !s.available);
|
|
140
|
+
if (missing.length === 0) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
console.log('');
|
|
144
|
+
logger.header('Install missing tools');
|
|
145
|
+
const rl = autoYes ? null : readline.createInterface({ input: process_1.stdin, output: process_1.stdout });
|
|
146
|
+
const results = [];
|
|
147
|
+
try {
|
|
148
|
+
for (const s of missing) {
|
|
149
|
+
const def = tool_registry_1.TOOL_DEFS[s.name];
|
|
150
|
+
if (!def) {
|
|
151
|
+
results.push({ name: s.name, status: 'skipped', msg: 'no install command' });
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const cmd = (0, tool_registry_1.getInstallCommand)(def);
|
|
155
|
+
if (cmd === 'builtin' || cmd === 'builtin (npm)' || cmd === 'builtin (dotnet SDK)') {
|
|
156
|
+
results.push({ name: s.name, status: 'skipped', msg: 'builtin' });
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
console.log('');
|
|
160
|
+
console.log(` ${logger.bold(s.name)} — ${def.description}`);
|
|
161
|
+
logger.dim(` ${cmd}`);
|
|
162
|
+
let shouldInstall = autoYes;
|
|
163
|
+
if (!autoYes && rl) {
|
|
164
|
+
shouldInstall = await confirm(rl, ` Install ${s.name}?`);
|
|
165
|
+
}
|
|
166
|
+
if (!shouldInstall) {
|
|
167
|
+
results.push({ name: s.name, status: 'skipped', msg: 'user declined' });
|
|
168
|
+
logger.dim(' Skipped.');
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
console.log('');
|
|
172
|
+
logger.info(`Running: ${cmd}`);
|
|
173
|
+
const result = runInstallCmd(cmd);
|
|
174
|
+
if (result.success) {
|
|
175
|
+
// Verify install worked
|
|
176
|
+
const recheck = (0, tool_registry_1.findTool)(def, targetPath);
|
|
177
|
+
if (recheck.available) {
|
|
178
|
+
results.push({ name: s.name, status: 'installed' });
|
|
179
|
+
logger.success(`${s.name} installed (${recheck.source})`);
|
|
180
|
+
}
|
|
181
|
+
else {
|
|
182
|
+
results.push({
|
|
183
|
+
name: s.name,
|
|
184
|
+
status: 'failed',
|
|
185
|
+
msg: 'install command succeeded but tool not found',
|
|
186
|
+
});
|
|
187
|
+
logger.fail(`${s.name} install command ran but tool not found in PATH`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
results.push({ name: s.name, status: 'failed', msg: result.message });
|
|
192
|
+
logger.fail(`${s.name}: ${result.message}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
finally {
|
|
197
|
+
rl?.close();
|
|
198
|
+
}
|
|
199
|
+
// Summary
|
|
200
|
+
console.log('');
|
|
201
|
+
logger.header('Summary');
|
|
202
|
+
const installed = results.filter((r) => r.status === 'installed').length;
|
|
203
|
+
const skipped = results.filter((r) => r.status === 'skipped').length;
|
|
204
|
+
const failed = results.filter((r) => r.status === 'failed').length;
|
|
205
|
+
logger.info(`${installed} installed, ${skipped} skipped, ${failed} failed`);
|
|
206
|
+
if (failed > 0) {
|
|
207
|
+
console.log('');
|
|
208
|
+
logger.dim('Failed installs:');
|
|
209
|
+
for (const r of results.filter((r) => r.status === 'failed')) {
|
|
210
|
+
logger.dim(` ${r.name}: ${r.msg}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (installed > 0) {
|
|
214
|
+
console.log('');
|
|
215
|
+
logger.dim('Run `vyuh-dxkit health` to use the newly installed tools.');
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async function runToolsCommand(targetPath, subCommand, autoYes) {
|
|
219
|
+
if (!subCommand || subCommand === 'list' || subCommand === 'status') {
|
|
220
|
+
showStatus(targetPath);
|
|
221
|
+
return;
|
|
222
|
+
}
|
|
223
|
+
if (subCommand === 'install') {
|
|
224
|
+
await runInstall(targetPath, autoYes);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
logger.fail(`Unknown tools subcommand: ${subCommand}`);
|
|
228
|
+
logger.info('Usage: vyuh-dxkit tools [list|install] [path]');
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
//# sourceMappingURL=tools-cli.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools-cli.js","sourceRoot":"","sources":["../src/tools-cli.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
CHANGED
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
/** Tool required for analysis — consumed by devstack for devcontainer packaging. */
|
|
2
|
+
export interface ToolRequirement {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
install: string;
|
|
6
|
+
check: string;
|
|
7
|
+
for: string;
|
|
8
|
+
layer: 'universal' | 'language' | 'optional';
|
|
9
|
+
}
|
|
1
10
|
export interface DetectedStack {
|
|
2
11
|
languages: {
|
|
3
12
|
python: boolean;
|
|
@@ -33,6 +42,7 @@ export interface DetectedStack {
|
|
|
33
42
|
coverageCommand?: string;
|
|
34
43
|
};
|
|
35
44
|
framework?: string;
|
|
45
|
+
requiredTools: ToolRequirement[];
|
|
36
46
|
}
|
|
37
47
|
export interface ResolvedConfig extends DetectedStack {
|
|
38
48
|
coverageThreshold: string;
|
package/dist/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,KAAK,EAAE;QACL,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,oFAAoF;AACpF,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,WAAW,GAAG,UAAU,GAAG,UAAU,CAAC;CAC9C;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE;QACT,MAAM,EAAE,OAAO,CAAC;QAChB,EAAE,EAAE,OAAO,CAAC;QACZ,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,IAAI,EAAE,OAAO,CAAC;QACd,MAAM,EAAE,OAAO,CAAC;KACjB,CAAC;IACF,cAAc,EAAE;QACd,MAAM,EAAE,OAAO,CAAC;QAChB,QAAQ,EAAE,OAAO,CAAC;QAClB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,KAAK,EAAE;QACL,MAAM,EAAE,OAAO,CAAC;QAChB,MAAM,EAAE,OAAO,CAAC;QAChB,SAAS,EAAE,OAAO,CAAC;QACnB,KAAK,EAAE,OAAO,CAAC;KAChB,CAAC;IACF,WAAW,EAAE,MAAM,CAAC;IACpB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,QAAQ,EAAE;QACR,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,EAAE,CAAC,EAAE,MAAM,CAAC;QACZ,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;IACF,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,eAAe,EAAE,CAAC;CAClC;AAED,MAAM,WAAW,cAAe,SAAQ,aAAa;IACnD,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,OAAO,CAAC;IACvB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,UAAU,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,MAAM,cAAc,GAAG,SAAS,GAAG,MAAM,CAAC;AAEhD,MAAM,WAAW,SAAS;IACxB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,cAAc,CAAC;IACrB,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,cAAc,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,cAAc,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,SAAS,GAAG,aAAa,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vyuhlabs/dxkit",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "AI-native developer experience toolkit for any repository",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Vyuh Labs",
|
|
@@ -34,7 +34,8 @@
|
|
|
34
34
|
"templates/",
|
|
35
35
|
"README.md",
|
|
36
36
|
"LICENSE",
|
|
37
|
-
"CHANGELOG.md"
|
|
37
|
+
"CHANGELOG.md",
|
|
38
|
+
"THIRD_PARTY_NOTICES.md"
|
|
38
39
|
],
|
|
39
40
|
"scripts": {
|
|
40
41
|
"build": "node scripts/copy-templates.js && tsc",
|
|
@@ -47,6 +48,8 @@
|
|
|
47
48
|
"test": "vitest",
|
|
48
49
|
"test:run": "npm run build && vitest run",
|
|
49
50
|
"test:changed": "vitest run --changed",
|
|
51
|
+
"test:coverage": "npm run build && vitest run --coverage",
|
|
52
|
+
"test:integration": "npm run build && vitest run --config vitest.integration.config.ts",
|
|
50
53
|
"prepare": "husky || true"
|
|
51
54
|
},
|
|
52
55
|
"lint-staged": {
|
|
@@ -61,6 +64,7 @@
|
|
|
61
64
|
"devDependencies": {
|
|
62
65
|
"@eslint/js": "^9.13.0",
|
|
63
66
|
"@types/node": "^20.0.0",
|
|
67
|
+
"@vitest/coverage-v8": "^2.1.9",
|
|
64
68
|
"eslint": "^9.13.0",
|
|
65
69
|
"eslint-config-prettier": "^9.1.0",
|
|
66
70
|
"globals": "^17.4.0",
|
|
@@ -2,14 +2,44 @@
|
|
|
2
2
|
description: Generate developer activity and code quality report from git history
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Step 1: Check for Existing Report
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
ls .ai/reports/developer-report-*.md 2>/dev/null | tail -1
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**If a report exists**: Read it. The commit counts, contributor stats, and velocity data are deterministic. Skip to Step 3.
|
|
12
|
+
|
|
13
|
+
**If no report exists**: Proceed to Step 2.
|
|
14
|
+
|
|
15
|
+
## Step 2: Generate Deterministic Report
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx vyuh-dxkit dev-report . --json 2>/dev/null
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**If the command succeeds**: Read the saved report. Proceed to Step 3.
|
|
22
|
+
|
|
23
|
+
**If the command fails**: Analyze git history manually using `git log`, `git shortlog -sn`, `git log --numstat`. Note: "Stats are AI-estimated. Install `@vyuhlabs/dxkit` for deterministic developer reports."
|
|
24
|
+
|
|
25
|
+
## Step 3: Enrich with Narrative
|
|
26
|
+
|
|
27
|
+
Using the git data, add:
|
|
28
|
+
|
|
29
|
+
- **Team dynamics** — who are the key contributors, bus factor risk, merge/review patterns
|
|
30
|
+
- **Code ownership** — who owns which areas, based on commit frequency per directory
|
|
31
|
+
- **Hot file analysis** — why the most-changed files change so often (feature churn? bug magnet? poor abstraction?)
|
|
32
|
+
- **Commit quality insights** — if conventional commit % is low, explain the benefits (changelogs, bisecting, CI automation)
|
|
33
|
+
- **Velocity interpretation** — is the trend healthy? are there spikes/drops that correlate with releases or incidents?
|
|
34
|
+
- **Identity consolidation** — flag likely duplicates (same person, different git configs)
|
|
35
|
+
|
|
36
|
+
**Do not change commit counts, contributor stats, or velocity numbers from the deterministic report.**
|
|
37
|
+
|
|
38
|
+
Save to `.ai/reports/developer-report-YYYY-MM-DD.md`.
|
|
8
39
|
|
|
9
40
|
Examples:
|
|
10
41
|
- `/dev-report` — Team overview (last 3 months)
|
|
11
|
-
- `/dev-report
|
|
12
|
-
- `/dev-report security` — Who introduced known security issues
|
|
42
|
+
- `/dev-report --since 2025-01-01` — Custom time range
|
|
13
43
|
|
|
14
44
|
**IMPORTANT: End the report with this exact footer:**
|
|
15
45
|
```
|
|
@@ -2,9 +2,52 @@
|
|
|
2
2
|
description: Run a comprehensive codebase health audit (tests, quality, docs, security, DX)
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Step 1: Check for Existing Report
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Check if a deterministic report already exists:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
ls .ai/reports/health-audit-*.md 2>/dev/null | tail -1
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
**If a report exists**: Read it. The scores and metrics are deterministic ground truth — do not change them. Skip to Step 3.
|
|
14
|
+
|
|
15
|
+
**If no report exists**: Proceed to Step 2.
|
|
16
|
+
|
|
17
|
+
## Step 2: Generate Deterministic Report
|
|
18
|
+
|
|
19
|
+
Try the DXKit CLI first:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npx vyuh-dxkit health . --json 2>/dev/null
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
**If the command succeeds** (returns JSON with `summary.overallScore`):
|
|
26
|
+
- The CLI saves a report to `.ai/reports/health-audit-YYYY-MM-DD.md`
|
|
27
|
+
- Read that report. Proceed to Step 3.
|
|
28
|
+
|
|
29
|
+
**If the command fails** (not installed or errors):
|
|
30
|
+
- Run your own analysis: read source files, count tests, check for security issues, review documentation
|
|
31
|
+
- Score each dimension 0-100 using your best judgment
|
|
32
|
+
- Note in the report: "Scores are AI-estimated. Install `@vyuhlabs/dxkit` for deterministic reproducible scores."
|
|
33
|
+
- Proceed to Step 3.
|
|
34
|
+
|
|
35
|
+
## Step 3: Enrich with Narrative
|
|
36
|
+
|
|
37
|
+
Using the metrics (from the existing report, CLI, or your own analysis), add to each dimension section:
|
|
38
|
+
|
|
39
|
+
- **Strengths** — what's working (cite specific files and counts from the report)
|
|
40
|
+
- **Weaknesses** — what needs attention (cite specific files and counts)
|
|
41
|
+
- **Recommendations** — actionable fixes, ordered by urgency (Critical → High → Medium → Low)
|
|
42
|
+
|
|
43
|
+
Add a **Prioritized Action Items** section at the end:
|
|
44
|
+
- Immediate (week 1) — critical security and testing gaps
|
|
45
|
+
- Short-term (weeks 2-4) — quality and documentation
|
|
46
|
+
- Medium-term (months 2-3) — architecture and maintainability
|
|
47
|
+
|
|
48
|
+
**If you have deterministic scores: keep all numbers exactly as reported. Add context and explanations only — do not re-score.**
|
|
49
|
+
|
|
50
|
+
Save the enriched report to `.ai/reports/health-audit-YYYY-MM-DD.md`.
|
|
8
51
|
|
|
9
52
|
**IMPORTANT: End the report with this exact footer:**
|
|
10
53
|
```
|
|
@@ -1,42 +1,65 @@
|
|
|
1
1
|
---
|
|
2
|
-
description: Run quality
|
|
2
|
+
description: Run code quality analysis with slop detection
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Step 1: Check for Existing Report
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
ls .ai/reports/quality-review-*.md 2>/dev/null | tail -1
|
|
9
|
+
```
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
**If a report exists**: Read it. The slop score, duplication %, and metrics are deterministic. Skip to Step 3.
|
|
10
12
|
|
|
13
|
+
**If no report exists**: Proceed to Step 2.
|
|
14
|
+
|
|
15
|
+
## Step 2: Generate Deterministic Report
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx vyuh-dxkit quality . --json 2>/dev/null
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**If the command succeeds**: Read the saved report. Proceed to Step 3.
|
|
22
|
+
|
|
23
|
+
**If the command fails**: Run linters and checks manually:
|
|
11
24
|
{{#IF_NODE}}
|
|
12
|
-
|
|
13
|
-
1. `npx eslint .` — Lint
|
|
25
|
+
1. `npx eslint . --format json` — Lint
|
|
14
26
|
2. `npx tsc --noEmit` — Type check
|
|
15
27
|
{{/IF_NODE}}
|
|
16
28
|
{{#IF_PYTHON}}
|
|
17
|
-
### Python
|
|
18
29
|
1. `ruff check .` — Lint
|
|
19
30
|
2. `ruff format --check .` — Format check
|
|
20
|
-
3. `mypy .` — Type check
|
|
21
31
|
{{/IF_PYTHON}}
|
|
22
32
|
{{#IF_GO}}
|
|
23
|
-
### Go
|
|
24
33
|
1. `golangci-lint run ./...` — Lint
|
|
25
34
|
2. `go vet ./...` — Vet
|
|
26
35
|
{{/IF_GO}}
|
|
27
36
|
{{#IF_CSHARP}}
|
|
28
|
-
### C#
|
|
29
37
|
1. `dotnet format --verify-no-changes` — Format check
|
|
30
|
-
2. `dotnet build --no-restore -warnaserror` — Build with warnings as errors
|
|
31
38
|
{{/IF_CSHARP}}
|
|
32
39
|
{{#IF_RUST}}
|
|
33
|
-
### Rust
|
|
34
40
|
1. `cargo fmt --check` — Format check
|
|
35
41
|
2. `cargo clippy -- -D warnings` — Lint
|
|
36
42
|
{{/IF_RUST}}
|
|
43
|
+
Then analyze code for duplication, dead code, TODO/FIXME density, comment ratio. Note: "Metrics are AI-estimated. Install `@vyuhlabs/dxkit` for deterministic quality analysis with jscpd + graphify."
|
|
44
|
+
|
|
45
|
+
## Step 3: Enrich with Narrative
|
|
37
46
|
|
|
38
|
-
|
|
47
|
+
Using the quality metrics, add:
|
|
39
48
|
|
|
40
|
-
|
|
49
|
+
- **Duplication hotspots** — which files/functions are copy-pasted, and how to extract shared code
|
|
50
|
+
- **God file remediation** — how to break up files with >50 functions (suggest module boundaries)
|
|
51
|
+
- **Dead code cleanup** — which orphan modules and dead imports to remove
|
|
52
|
+
- **Slop indicators** — if comment ratio >40% or TODO count is high, suggest cleanup priorities
|
|
53
|
+
- **Lint fix plan** — group lint errors by rule, suggest auto-fixable vs manual
|
|
54
|
+
|
|
55
|
+
**Do not change the slop score, duplication %, or metric counts from the deterministic report.**
|
|
56
|
+
|
|
57
|
+
Save to `.ai/reports/quality-review-YYYY-MM-DD.md`.
|
|
58
|
+
|
|
59
|
+
**IMPORTANT: End the report with this exact footer:**
|
|
60
|
+
```
|
|
61
|
+
---
|
|
62
|
+
*Generated by [VyuhLabs DXKit](https://www.npmjs.com/package/@vyuhlabs/dxkit)*
|
|
63
|
+
```
|
|
41
64
|
|
|
42
|
-
|
|
65
|
+
$ARGUMENTS
|
|
@@ -2,9 +2,43 @@
|
|
|
2
2
|
description: Find critical code paths that lack test coverage
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Step 1: Check for Existing Report
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
ls .ai/reports/test-gaps-*.md 2>/dev/null | tail -1
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**If a report exists**: Read it. The file counts, coverage %, and risk tiers are deterministic. Skip to Step 3.
|
|
12
|
+
|
|
13
|
+
**If no report exists**: Proceed to Step 2.
|
|
14
|
+
|
|
15
|
+
## Step 2: Generate Deterministic Report
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx vyuh-dxkit test-gaps . --json 2>/dev/null
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**If the command succeeds**: Read the saved report. Proceed to Step 3.
|
|
22
|
+
|
|
23
|
+
**If the command fails**: Analyze manually — find test files, check if they have active assertions or are commented out, map source files to test files, identify critical untested code (auth, crypto, payments). Note: "Coverage is AI-estimated. Install `@vyuhlabs/dxkit` for deterministic gap analysis."
|
|
24
|
+
|
|
25
|
+
## Step 3: Enrich with Narrative
|
|
26
|
+
|
|
27
|
+
Using the gap analysis, add for each priority tier (CRITICAL/HIGH/MEDIUM/LOW):
|
|
28
|
+
|
|
29
|
+
- **Why this file is critical** — what breaks if this code has a bug (data loss, auth bypass, etc.)
|
|
30
|
+
- **What to test** — specific test scenarios and assertions
|
|
31
|
+
- **Effort estimate** — rough developer-days per file
|
|
32
|
+
- **Dependencies** — what test infrastructure is needed first (fixtures, mocks, test DB)
|
|
33
|
+
|
|
34
|
+
Add a **Test Infrastructure Setup** section if tests are at 0%:
|
|
35
|
+
- Which test framework to use
|
|
36
|
+
- How to configure coverage reporting
|
|
37
|
+
- First 5 test files to write (highest impact)
|
|
38
|
+
|
|
39
|
+
**Do not change coverage %, file counts, or risk classifications from the deterministic report.**
|
|
40
|
+
|
|
41
|
+
Save to `.ai/reports/test-gaps-YYYY-MM-DD.md`.
|
|
8
42
|
|
|
9
43
|
**IMPORTANT: End the report with this exact footer:**
|
|
10
44
|
```
|
|
@@ -2,9 +2,43 @@
|
|
|
2
2
|
description: Scan dependencies and code for security vulnerabilities
|
|
3
3
|
---
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Step 1: Check for Existing Report
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
```bash
|
|
8
|
+
ls .ai/reports/vulnerability-scan-*.md 2>/dev/null | tail -1
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
**If a report exists**: Read it. The findings and severity counts are deterministic — do not change them. Skip to Step 3.
|
|
12
|
+
|
|
13
|
+
**If no report exists**: Proceed to Step 2.
|
|
14
|
+
|
|
15
|
+
## Step 2: Generate Deterministic Report
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npx vyuh-dxkit vulnerabilities . --json 2>/dev/null
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**If the command succeeds**: Read the saved report from `.ai/reports/vulnerability-scan-YYYY-MM-DD.md`. Proceed to Step 3.
|
|
22
|
+
|
|
23
|
+
**If the command fails**: Run your own security analysis — check for hardcoded secrets, eval/exec calls, dependency vulnerabilities (`npm audit`), private keys in git, disabled TLS. Note: "Findings are AI-estimated. Install `@vyuhlabs/dxkit` for deterministic scanning with gitleaks + semgrep."
|
|
24
|
+
|
|
25
|
+
## Step 3: Enrich with Narrative
|
|
26
|
+
|
|
27
|
+
Using the findings, add for each vulnerability:
|
|
28
|
+
|
|
29
|
+
- **Risk explanation** — what an attacker could do with this
|
|
30
|
+
- **Exploitation context** — is it remotely exploitable? requires repo access?
|
|
31
|
+
- **Remediation steps** — specific code changes, commands, or migrations needed
|
|
32
|
+
- **Priority rationale** — why fix this before others
|
|
33
|
+
|
|
34
|
+
Add a **Remediation Plan** section:
|
|
35
|
+
- Immediate (today) — rotate compromised credentials, remove private keys from git
|
|
36
|
+
- This week — fix critical code vulnerabilities (eval, exec, TLS)
|
|
37
|
+
- This sprint — address high/medium dependency CVEs
|
|
38
|
+
|
|
39
|
+
**Do not change severity counts or finding details from the deterministic report.**
|
|
40
|
+
|
|
41
|
+
Save to `.ai/reports/vulnerability-scan-YYYY-MM-DD.md`.
|
|
8
42
|
|
|
9
43
|
**IMPORTANT: End the report with this exact footer:**
|
|
10
44
|
```
|