coverme-scanner 1.3.0 → 1.3.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/README.md +1 -1
- package/assets/coverme-cli.png +0 -0
- package/dist/cli/index.js +32 -2
- package/dist/cli/index.js.map +1 -1
- package/package.json +6 -1
- package/.claude/commands/coverme.md +0 -577
- package/commands/scan.md +0 -317
- package/src/cli/index.ts +0 -251
- package/src/cli/init.ts +0 -678
- package/src/cli/scan.ts +0 -86
- package/src/prompts/architecture-reviewer.md +0 -173
- package/src/prompts/consensus-builder.md +0 -249
- package/src/prompts/context-discovery.md +0 -176
- package/src/prompts/cross-validator.md +0 -270
- package/src/prompts/deep-dive-expert.md +0 -226
- package/src/prompts/dependency-auditor.md +0 -192
- package/src/prompts/mitigation-validator.md +0 -301
- package/src/prompts/orchestration.md +0 -1716
- package/src/prompts/performance-hunter.md +0 -202
- package/src/prompts/quality-analyzer.md +0 -348
- package/src/prompts/report-generator.md +0 -285
- package/src/prompts/runtime-verify.md +0 -353
- package/src/prompts/security-scanner.md +0 -243
- package/src/report/generator.ts +0 -799
- package/src/report/index.ts +0 -92
- package/src/templates/agents.example.json +0 -16
- package/src/templates/agents.schema.json +0 -75
- package/src/templates/report.html +0 -1767
- package/src/templates/scan-result.json +0 -37
- package/src/types.ts +0 -184
- package/tsconfig.json +0 -20
package/commands/scan.md
DELETED
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
# Vibecode Tracker - Multi-Agent Code Scanner
|
|
2
|
-
|
|
3
|
-
Run a comprehensive code analysis using 11 AI agents with cross-validation.
|
|
4
|
-
|
|
5
|
-
$ARGUMENTS
|
|
6
|
-
|
|
7
|
-
## Execution Flow
|
|
8
|
-
|
|
9
|
-
You will orchestrate a multi-phase code scan. Follow each phase exactly.
|
|
10
|
-
|
|
11
|
-
---
|
|
12
|
-
|
|
13
|
-
## PHASE 0: Context Discovery (REQUIRED FIRST)
|
|
14
|
-
|
|
15
|
-
Before ANY scanning, understand the project:
|
|
16
|
-
|
|
17
|
-
**Launch ONE agent with Task tool (subagent_type="Explore"):**
|
|
18
|
-
|
|
19
|
-
```
|
|
20
|
-
Understand this codebase thoroughly.
|
|
21
|
-
|
|
22
|
-
1. Find and read ALL documentation:
|
|
23
|
-
- README.md, CLAUDE.md, .claude/CLAUDE.md
|
|
24
|
-
- docs/*.md, ARCHITECTURE.md, SECURITY.md
|
|
25
|
-
|
|
26
|
-
2. Identify tech stack from:
|
|
27
|
-
- package.json (Node.js)
|
|
28
|
-
- requirements.txt (Python)
|
|
29
|
-
- go.mod, Cargo.toml, etc.
|
|
30
|
-
|
|
31
|
-
3. Map the architecture:
|
|
32
|
-
- Entry points (routes, controllers)
|
|
33
|
-
- Middleware and auth
|
|
34
|
-
- Database access patterns
|
|
35
|
-
- External service integrations
|
|
36
|
-
|
|
37
|
-
4. Note security-relevant components:
|
|
38
|
-
- Auth system used
|
|
39
|
-
- Encryption implementations
|
|
40
|
-
- File handling
|
|
41
|
-
- User input processing
|
|
42
|
-
|
|
43
|
-
Output a structured JSON summary of the project context.
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
**Wait for this agent to complete before proceeding.**
|
|
47
|
-
|
|
48
|
-
---
|
|
49
|
-
|
|
50
|
-
## PHASE 1: Discovery Scan (5 Agents in Parallel)
|
|
51
|
-
|
|
52
|
-
Launch ALL 5 agents simultaneously using parallel Task tool calls:
|
|
53
|
-
|
|
54
|
-
### Agent 1: Security Scanner
|
|
55
|
-
```
|
|
56
|
-
You are a security researcher. Scan this codebase for vulnerabilities.
|
|
57
|
-
|
|
58
|
-
PROJECT CONTEXT: {paste context from Phase 0}
|
|
59
|
-
|
|
60
|
-
Check for:
|
|
61
|
-
- SQL/NoSQL injection, XSS, Command injection
|
|
62
|
-
- Authentication/Authorization flaws
|
|
63
|
-
- Cryptography issues, hardcoded secrets
|
|
64
|
-
- SSRF, Path traversal, File upload issues
|
|
65
|
-
- Rate limiting, Session management
|
|
66
|
-
|
|
67
|
-
For EACH finding output JSON:
|
|
68
|
-
{
|
|
69
|
-
"id": "SEC-001",
|
|
70
|
-
"title": "...",
|
|
71
|
-
"severity": "critical|high|medium|low",
|
|
72
|
-
"file": "path/to/file.js",
|
|
73
|
-
"line": 123,
|
|
74
|
-
"code": "vulnerable code snippet",
|
|
75
|
-
"description": "What's wrong",
|
|
76
|
-
"exploit": "How to exploit",
|
|
77
|
-
"recommendation": "How to fix",
|
|
78
|
-
"evidence": ["data flow proof"]
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
Be thorough. Check EVERY file.
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
### Agent 2: Quality Analyzer
|
|
85
|
-
```
|
|
86
|
-
You are a code quality expert. Scan for quality issues.
|
|
87
|
-
|
|
88
|
-
PROJECT CONTEXT: {paste context from Phase 0}
|
|
89
|
-
|
|
90
|
-
Check for:
|
|
91
|
-
- DRY violations (duplicated code)
|
|
92
|
-
- High complexity functions
|
|
93
|
-
- Dead code, unused imports
|
|
94
|
-
- Error handling issues
|
|
95
|
-
- Type safety problems
|
|
96
|
-
- Anti-patterns
|
|
97
|
-
|
|
98
|
-
Output findings as JSON with "QUAL-XXX" IDs.
|
|
99
|
-
```
|
|
100
|
-
|
|
101
|
-
### Agent 3: Architecture Reviewer
|
|
102
|
-
```
|
|
103
|
-
You are a software architect. Review the codebase structure.
|
|
104
|
-
|
|
105
|
-
PROJECT CONTEXT: {paste context from Phase 0}
|
|
106
|
-
|
|
107
|
-
Check for:
|
|
108
|
-
- Layer violations
|
|
109
|
-
- Circular dependencies
|
|
110
|
-
- Missing abstractions
|
|
111
|
-
- Component coupling
|
|
112
|
-
- API design issues
|
|
113
|
-
- Configuration problems
|
|
114
|
-
|
|
115
|
-
Output findings as JSON with "ARCH-XXX" IDs.
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
### Agent 4: Dependency Auditor
|
|
119
|
-
```
|
|
120
|
-
You are a dependency security expert. Audit all dependencies.
|
|
121
|
-
|
|
122
|
-
PROJECT CONTEXT: {paste context from Phase 0}
|
|
123
|
-
|
|
124
|
-
Check for:
|
|
125
|
-
- CVEs in dependencies
|
|
126
|
-
- Outdated packages
|
|
127
|
-
- License compliance
|
|
128
|
-
- Unused dependencies
|
|
129
|
-
- Supply chain risks
|
|
130
|
-
|
|
131
|
-
Output findings as JSON with "DEPS-XXX" IDs.
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
### Agent 5: Performance Hunter
|
|
135
|
-
```
|
|
136
|
-
You are a performance engineer. Find performance issues.
|
|
137
|
-
|
|
138
|
-
PROJECT CONTEXT: {paste context from Phase 0}
|
|
139
|
-
|
|
140
|
-
Check for:
|
|
141
|
-
- N+1 query patterns
|
|
142
|
-
- Memory leaks
|
|
143
|
-
- Blocking operations
|
|
144
|
-
- Missing caching
|
|
145
|
-
- Inefficient algorithms
|
|
146
|
-
|
|
147
|
-
Output findings as JSON with "PERF-XXX" IDs.
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
**Wait for ALL 5 agents to complete before proceeding.**
|
|
151
|
-
|
|
152
|
-
---
|
|
153
|
-
|
|
154
|
-
## PHASE 2: Cross-Validation (3 Agents in Parallel)
|
|
155
|
-
|
|
156
|
-
Collect ALL findings from Phase 1, then launch 3 validators:
|
|
157
|
-
|
|
158
|
-
### Validator A: False Positive Hunter
|
|
159
|
-
```
|
|
160
|
-
Review all findings from Phase 1 for FALSE POSITIVES.
|
|
161
|
-
|
|
162
|
-
FINDINGS TO VALIDATE:
|
|
163
|
-
{paste all findings from Phase 1}
|
|
164
|
-
|
|
165
|
-
For each finding:
|
|
166
|
-
1. Read the actual code
|
|
167
|
-
2. Check for mitigating controls
|
|
168
|
-
3. Verify the issue is real
|
|
169
|
-
|
|
170
|
-
Output:
|
|
171
|
-
{
|
|
172
|
-
"confirmed": ["SEC-001", "QUAL-003", ...],
|
|
173
|
-
"falsePositives": [
|
|
174
|
-
{"id": "SEC-002", "reason": "Input is sanitized at line X"}
|
|
175
|
-
]
|
|
176
|
-
}
|
|
177
|
-
```
|
|
178
|
-
|
|
179
|
-
### Validator B: Evidence Challenger
|
|
180
|
-
```
|
|
181
|
-
Challenge every HIGH and CRITICAL finding.
|
|
182
|
-
|
|
183
|
-
FINDINGS TO VALIDATE:
|
|
184
|
-
{paste HIGH/CRITICAL findings only}
|
|
185
|
-
|
|
186
|
-
For each finding:
|
|
187
|
-
1. Read the full code context
|
|
188
|
-
2. Trace the data flow
|
|
189
|
-
3. Attempt to construct an exploit
|
|
190
|
-
4. Determine if truly exploitable
|
|
191
|
-
|
|
192
|
-
Output same format as Validator A.
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
### Validator C: Missing Issues Hunter
|
|
196
|
-
```
|
|
197
|
-
Look for issues that Phase 1 agents MISSED.
|
|
198
|
-
|
|
199
|
-
EXISTING FINDINGS:
|
|
200
|
-
{paste all findings}
|
|
201
|
-
|
|
202
|
-
Search for:
|
|
203
|
-
- Business logic flaws
|
|
204
|
-
- Race conditions
|
|
205
|
-
- Edge cases
|
|
206
|
-
- Integration vulnerabilities
|
|
207
|
-
- Combination attacks
|
|
208
|
-
|
|
209
|
-
Output:
|
|
210
|
-
{
|
|
211
|
-
"missedIssues": [
|
|
212
|
-
{full finding object with new ID}
|
|
213
|
-
]
|
|
214
|
-
}
|
|
215
|
-
```
|
|
216
|
-
|
|
217
|
-
**Wait for ALL 3 validators to complete.**
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
## PHASE 3: Deep Dive (If Needed)
|
|
222
|
-
|
|
223
|
-
For any finding where Validator A and B disagree, launch a Deep Dive agent:
|
|
224
|
-
|
|
225
|
-
```
|
|
226
|
-
DISPUTED FINDING:
|
|
227
|
-
{finding details}
|
|
228
|
-
|
|
229
|
-
VALIDATOR A SAYS: {verdict}
|
|
230
|
-
VALIDATOR B SAYS: {verdict}
|
|
231
|
-
|
|
232
|
-
Perform exhaustive analysis:
|
|
233
|
-
1. Read ALL relevant code
|
|
234
|
-
2. Trace complete data flow
|
|
235
|
-
3. Check all mitigating controls
|
|
236
|
-
4. Determine the TRUE status
|
|
237
|
-
|
|
238
|
-
Output your final verdict with detailed evidence.
|
|
239
|
-
```
|
|
240
|
-
|
|
241
|
-
---
|
|
242
|
-
|
|
243
|
-
## PHASE 4: Build Consensus
|
|
244
|
-
|
|
245
|
-
Now aggregate all results:
|
|
246
|
-
|
|
247
|
-
1. **Merge duplicates** - Same issue from multiple agents
|
|
248
|
-
2. **Calculate confidence**:
|
|
249
|
-
- Each validator confirmation: +15%
|
|
250
|
-
- Each false_positive vote: -20%
|
|
251
|
-
- Deep dive confirmation: +25%
|
|
252
|
-
3. **Filter**: Remove findings with <50% confidence
|
|
253
|
-
4. **Sort**: By severity, then confidence
|
|
254
|
-
|
|
255
|
-
---
|
|
256
|
-
|
|
257
|
-
## PHASE 5: Generate Report
|
|
258
|
-
|
|
259
|
-
Create a professional PDF report:
|
|
260
|
-
|
|
261
|
-
### Structure:
|
|
262
|
-
1. **Cover Page** - Project name, date, finding counts
|
|
263
|
-
2. **Executive Summary** - One page for leadership
|
|
264
|
-
3. **Scan Overview** - Files scanned, duration, methodology
|
|
265
|
-
4. **Critical Issues** - Full detail with code and fixes
|
|
266
|
-
5. **High Issues** - Full detail
|
|
267
|
-
6. **Medium Issues** - Summarized table
|
|
268
|
-
7. **Low Issues** - List only
|
|
269
|
-
8. **Positive Observations** - Good patterns found
|
|
270
|
-
9. **Recommendations** - Prioritized action items
|
|
271
|
-
|
|
272
|
-
### Generate Report:
|
|
273
|
-
|
|
274
|
-
Use the report generator prompt to create the Markdown content, then convert to PDF:
|
|
275
|
-
|
|
276
|
-
```bash
|
|
277
|
-
npx md-to-pdf vibecode-report.md
|
|
278
|
-
```
|
|
279
|
-
|
|
280
|
-
Or use the Read tool to save directly as PDF if available.
|
|
281
|
-
|
|
282
|
-
---
|
|
283
|
-
|
|
284
|
-
## Output
|
|
285
|
-
|
|
286
|
-
Save the final report as:
|
|
287
|
-
```
|
|
288
|
-
vibecode-report-{YYYY-MM-DD}.pdf
|
|
289
|
-
```
|
|
290
|
-
|
|
291
|
-
Also save the raw findings as:
|
|
292
|
-
```
|
|
293
|
-
vibecode-findings-{YYYY-MM-DD}.json
|
|
294
|
-
```
|
|
295
|
-
|
|
296
|
-
---
|
|
297
|
-
|
|
298
|
-
## Quick Options
|
|
299
|
-
|
|
300
|
-
If the user specifies options:
|
|
301
|
-
|
|
302
|
-
- `/scan security` - Only run Security Scanner + validators
|
|
303
|
-
- `/scan quality` - Only run Quality Analyzer + validators
|
|
304
|
-
- `/scan --quick` - Skip validation phase (faster, less accurate)
|
|
305
|
-
- `/scan --json` - Output JSON only, no PDF
|
|
306
|
-
|
|
307
|
-
---
|
|
308
|
-
|
|
309
|
-
## Important Notes
|
|
310
|
-
|
|
311
|
-
1. **Always run Phase 0 first** - Context is critical
|
|
312
|
-
2. **Use parallel Task calls** - Faster execution
|
|
313
|
-
3. **Wait between phases** - Each phase needs previous results
|
|
314
|
-
4. **Be thorough** - Better to find more and filter than miss issues
|
|
315
|
-
5. **Include positives** - Good patterns are important too
|
|
316
|
-
|
|
317
|
-
BEGIN SCAN NOW.
|
package/src/cli/index.ts
DELETED
|
@@ -1,251 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
import { Command } from 'commander';
|
|
4
|
-
import { init } from './init.js';
|
|
5
|
-
import { scan } from './scan.js';
|
|
6
|
-
import { generateReport } from '../report/index.js';
|
|
7
|
-
import { readFileSync, writeFileSync, existsSync, mkdirSync, copyFileSync } from 'fs';
|
|
8
|
-
import { join } from 'path';
|
|
9
|
-
|
|
10
|
-
const pkg = JSON.parse(readFileSync(join(__dirname, '..', '..', 'package.json'), 'utf-8'));
|
|
11
|
-
|
|
12
|
-
const program = new Command();
|
|
13
|
-
|
|
14
|
-
program
|
|
15
|
-
.name('coverme')
|
|
16
|
-
.description('AI-powered code scanner with multi-agent verification for Claude Code')
|
|
17
|
-
.version(pkg.version);
|
|
18
|
-
|
|
19
|
-
program
|
|
20
|
-
.command('init')
|
|
21
|
-
.description('Install vibecode slash commands into .claude/commands/')
|
|
22
|
-
.option('-g, --global', 'Install globally to ~/.claude/commands/')
|
|
23
|
-
.action(init);
|
|
24
|
-
|
|
25
|
-
program
|
|
26
|
-
.command('scan')
|
|
27
|
-
.description('Scan codebase with multi-agent AI verification')
|
|
28
|
-
.argument('[path]', 'Path to scan', '.')
|
|
29
|
-
.option('-o, --output <format>', 'Output format: json, pdf, md, html', 'pdf')
|
|
30
|
-
.option('-O, --output-path <path>', 'Output file path')
|
|
31
|
-
.option('-c, --categories <cats>', 'Categories to scan: security,quality,arch,deps,perf', 'all')
|
|
32
|
-
.option('-s, --severity <level>', 'Minimum severity: critical,high,medium,low,info', 'low')
|
|
33
|
-
.option('-v, --verbose', 'Verbose output')
|
|
34
|
-
.option('-p, --parallel <num>', 'Number of parallel agents', '5')
|
|
35
|
-
.action(scan);
|
|
36
|
-
|
|
37
|
-
program
|
|
38
|
-
.command('report')
|
|
39
|
-
.description('Generate PDF/HTML report from scan JSON')
|
|
40
|
-
.argument('<json-file>', 'Path to scan results JSON file')
|
|
41
|
-
.option('-o, --output <path>', 'Output file path')
|
|
42
|
-
.option('-f, --format <format>', 'Output format: pdf, html', 'pdf')
|
|
43
|
-
.action(async (jsonFile: string, options: { output?: string; format?: 'pdf' | 'html' }) => {
|
|
44
|
-
await generateReport(jsonFile, options.output, options.format || 'pdf');
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
// Agent management commands
|
|
48
|
-
const agentCmd = program
|
|
49
|
-
.command('agent')
|
|
50
|
-
.description('Manage custom agents');
|
|
51
|
-
|
|
52
|
-
agentCmd
|
|
53
|
-
.command('add')
|
|
54
|
-
.description('Add a new custom agent')
|
|
55
|
-
.argument('<name>', 'Agent name (e.g., "John")')
|
|
56
|
-
.argument('<task>', 'What the agent should do')
|
|
57
|
-
.action((name: string, task: string) => {
|
|
58
|
-
const covermeDir = join(process.cwd(), '.coverme');
|
|
59
|
-
const agentsPath = join(covermeDir, 'agents.json');
|
|
60
|
-
|
|
61
|
-
if (!existsSync(covermeDir)) {
|
|
62
|
-
mkdirSync(covermeDir, { recursive: true });
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let agents: any = { agents: [] };
|
|
66
|
-
if (existsSync(agentsPath)) {
|
|
67
|
-
agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
68
|
-
if (!agents.agents) agents.agents = [];
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
agents.agents.push({ name, task });
|
|
72
|
-
writeFileSync(agentsPath, JSON.stringify(agents, null, 2));
|
|
73
|
-
console.log(`Added agent "${name}"`);
|
|
74
|
-
console.log(`Task: ${task}`);
|
|
75
|
-
});
|
|
76
|
-
|
|
77
|
-
agentCmd
|
|
78
|
-
.command('list')
|
|
79
|
-
.description('List all custom agents')
|
|
80
|
-
.action(() => {
|
|
81
|
-
const agentsPath = join(process.cwd(), '.coverme', 'agents.json');
|
|
82
|
-
if (!existsSync(agentsPath)) {
|
|
83
|
-
console.log('No custom agents. Add one with: coverme agent add "John" "Check .env files for secrets"');
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
const agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
88
|
-
if (!agents.agents || agents.agents.length === 0) {
|
|
89
|
-
console.log('No custom agents. Add one with: coverme agent add "John" "Check .env files for secrets"');
|
|
90
|
-
return;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
console.log('\nCustom Agents:\n');
|
|
94
|
-
agents.agents.forEach((agent: any, i: number) => {
|
|
95
|
-
console.log(` ${i + 1}. ${agent.name}`);
|
|
96
|
-
console.log(` Task: ${agent.task}`);
|
|
97
|
-
console.log('');
|
|
98
|
-
});
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
agentCmd
|
|
102
|
-
.command('remove')
|
|
103
|
-
.description('Remove a custom agent')
|
|
104
|
-
.argument('<name>', 'Agent name to remove')
|
|
105
|
-
.action((name: string) => {
|
|
106
|
-
const agentsPath = join(process.cwd(), '.coverme', 'agents.json');
|
|
107
|
-
if (!existsSync(agentsPath)) {
|
|
108
|
-
console.error('No agents.json found');
|
|
109
|
-
return;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
113
|
-
const idx = agents.agents.findIndex((a: any) => a.name.toLowerCase() === name.toLowerCase());
|
|
114
|
-
if (idx === -1) {
|
|
115
|
-
console.error(`Agent "${name}" not found`);
|
|
116
|
-
return;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
const removed = agents.agents.splice(idx, 1)[0];
|
|
120
|
-
writeFileSync(agentsPath, JSON.stringify(agents, null, 2));
|
|
121
|
-
console.log(`Removed agent "${removed.name}"`);
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
// Runtime verification commands
|
|
125
|
-
const verifyCmd = program
|
|
126
|
-
.command('verify')
|
|
127
|
-
.description('Verify runtime environment matches code expectations');
|
|
128
|
-
|
|
129
|
-
verifyCmd
|
|
130
|
-
.command('setup')
|
|
131
|
-
.description('Configure SSH access for runtime verification')
|
|
132
|
-
.option('-h, --host <host>', 'SSH host (e.g., user@server.com)')
|
|
133
|
-
.option('-p, --port <port>', 'SSH port', '22')
|
|
134
|
-
.option('-k, --key <path>', 'Path to SSH private key')
|
|
135
|
-
.option('-n, --name <name>', 'Environment name (e.g., production, staging)')
|
|
136
|
-
.action((options: { host?: string; port?: string; key?: string; name?: string }) => {
|
|
137
|
-
const covermeDir = join(process.cwd(), '.coverme');
|
|
138
|
-
const configPath = join(covermeDir, 'runtime.json');
|
|
139
|
-
|
|
140
|
-
if (!existsSync(covermeDir)) {
|
|
141
|
-
mkdirSync(covermeDir, { recursive: true });
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
let config: any = { environments: [] };
|
|
145
|
-
if (existsSync(configPath)) {
|
|
146
|
-
config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
147
|
-
if (!config.environments) config.environments = [];
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
if (!options.host) {
|
|
151
|
-
console.log('\nRuntime Verification Setup');
|
|
152
|
-
console.log('==========================\n');
|
|
153
|
-
console.log('This feature allows CoverMe to SSH into your servers and compare');
|
|
154
|
-
console.log('the actual runtime environment against your code configuration.\n');
|
|
155
|
-
console.log('Usage:');
|
|
156
|
-
console.log(' coverme verify setup --host user@server.com --name production');
|
|
157
|
-
console.log(' coverme verify setup --host deploy@staging.example.com --key ~/.ssh/id_rsa --name staging\n');
|
|
158
|
-
console.log('Options:');
|
|
159
|
-
console.log(' -h, --host <host> SSH host (required)');
|
|
160
|
-
console.log(' -n, --name <name> Environment name (default: from host)');
|
|
161
|
-
console.log(' -p, --port <port> SSH port (default: 22)');
|
|
162
|
-
console.log(' -k, --key <path> Path to SSH private key\n');
|
|
163
|
-
|
|
164
|
-
if (config.environments.length > 0) {
|
|
165
|
-
console.log('Configured environments:');
|
|
166
|
-
config.environments.forEach((env: any, i: number) => {
|
|
167
|
-
console.log(` ${i + 1}. ${env.name}: ${env.host}:${env.port}`);
|
|
168
|
-
});
|
|
169
|
-
}
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const envName = options.name || options.host.split('@')[1]?.split('.')[0] || 'default';
|
|
174
|
-
|
|
175
|
-
// Remove existing with same name
|
|
176
|
-
config.environments = config.environments.filter((e: any) => e.name !== envName);
|
|
177
|
-
|
|
178
|
-
config.environments.push({
|
|
179
|
-
name: envName,
|
|
180
|
-
host: options.host,
|
|
181
|
-
port: parseInt(options.port || '22'),
|
|
182
|
-
keyPath: options.key || null,
|
|
183
|
-
addedAt: new Date().toISOString()
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
187
|
-
console.log(`\nAdded environment "${envName}"`);
|
|
188
|
-
console.log(` Host: ${options.host}`);
|
|
189
|
-
console.log(` Port: ${options.port || '22'}`);
|
|
190
|
-
if (options.key) console.log(` Key: ${options.key}`);
|
|
191
|
-
console.log('\nRun verification with:');
|
|
192
|
-
console.log(` /coverme-verify ${envName}`);
|
|
193
|
-
console.log('\nOr in Claude Code:');
|
|
194
|
-
console.log(` /coverme --verify ${envName}`);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
verifyCmd
|
|
198
|
-
.command('list')
|
|
199
|
-
.description('List configured environments')
|
|
200
|
-
.action(() => {
|
|
201
|
-
const configPath = join(process.cwd(), '.coverme', 'runtime.json');
|
|
202
|
-
|
|
203
|
-
if (!existsSync(configPath)) {
|
|
204
|
-
console.log('No environments configured.');
|
|
205
|
-
console.log('Run: coverme verify setup --host user@server.com --name production');
|
|
206
|
-
return;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
210
|
-
|
|
211
|
-
if (!config.environments || config.environments.length === 0) {
|
|
212
|
-
console.log('No environments configured.');
|
|
213
|
-
return;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
console.log('\nConfigured Environments:\n');
|
|
217
|
-
config.environments.forEach((env: any, i: number) => {
|
|
218
|
-
console.log(` ${i + 1}. ${env.name}`);
|
|
219
|
-
console.log(` Host: ${env.host}:${env.port}`);
|
|
220
|
-
if (env.keyPath) console.log(` Key: ${env.keyPath}`);
|
|
221
|
-
console.log(` Added: ${new Date(env.addedAt).toLocaleDateString()}`);
|
|
222
|
-
console.log('');
|
|
223
|
-
});
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
verifyCmd
|
|
227
|
-
.command('remove')
|
|
228
|
-
.description('Remove an environment')
|
|
229
|
-
.argument('<name>', 'Environment name')
|
|
230
|
-
.action((name: string) => {
|
|
231
|
-
const configPath = join(process.cwd(), '.coverme', 'runtime.json');
|
|
232
|
-
|
|
233
|
-
if (!existsSync(configPath)) {
|
|
234
|
-
console.error('No environments configured.');
|
|
235
|
-
return;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
const config = JSON.parse(readFileSync(configPath, 'utf-8'));
|
|
239
|
-
const idx = config.environments.findIndex((e: any) => e.name.toLowerCase() === name.toLowerCase());
|
|
240
|
-
|
|
241
|
-
if (idx === -1) {
|
|
242
|
-
console.error(`Environment "${name}" not found`);
|
|
243
|
-
return;
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
const removed = config.environments.splice(idx, 1)[0];
|
|
247
|
-
writeFileSync(configPath, JSON.stringify(config, null, 2));
|
|
248
|
-
console.log(`Removed environment "${removed.name}"`);
|
|
249
|
-
});
|
|
250
|
-
|
|
251
|
-
program.parse();
|