coverme-scanner 1.0.24 → 1.0.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/commands/coverme.md +18 -6
- package/dist/cli/index.js +22 -118
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +5 -8
- package/dist/cli/init.js.map +1 -1
- package/dist/templates/agents.example.json +8 -25
- package/package.json +1 -1
- package/src/cli/index.ts +21 -125
- package/src/cli/init.ts +5 -8
- package/src/templates/agents.example.json +8 -25
|
@@ -25,12 +25,19 @@ Execute ALL phases automatically. Do NOT stop until the HTML report is open.
|
|
|
25
25
|
cat .coverme/agents.json 2>/dev/null || echo "NO_CUSTOM_AGENTS"
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
If the file exists,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
If the file exists, it will look like this:
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"agents": [
|
|
32
|
+
{ "name": "John", "task": "Check .env files for secrets" },
|
|
33
|
+
{ "name": "Sarah", "task": "Find regex patterns vulnerable to ReDoS" }
|
|
34
|
+
]
|
|
35
|
+
}
|
|
36
|
+
```
|
|
32
37
|
|
|
33
|
-
For
|
|
38
|
+
For EACH custom agent, launch it in Phase 1 alongside the built-in agents. The agent should:
|
|
39
|
+
1. Do what the `task` says
|
|
40
|
+
2. Output findings with ID prefix based on the agent name (e.g., JOHN-001, SARAH-001)
|
|
34
41
|
|
|
35
42
|
---
|
|
36
43
|
|
|
@@ -41,7 +48,12 @@ Launch ALL built-in agents + custom discovery agents IN PARALLEL using the Task
|
|
|
41
48
|
**IMPORTANT**: Set `run_in_background: true` on ALL Task tool calls to run agents in parallel without blocking.
|
|
42
49
|
|
|
43
50
|
### Custom Agents (from .coverme/agents.json)
|
|
44
|
-
If custom agents
|
|
51
|
+
If custom agents were loaded in Phase 0, launch each one as a Task with their specific task.
|
|
52
|
+
|
|
53
|
+
Example: If agents.json has `{"name": "John", "task": "Check .env files"}`, launch:
|
|
54
|
+
```
|
|
55
|
+
Task: "John: Check .env files for secrets and sensitive configuration. Output findings as JSON with id prefix JOHN-XXX"
|
|
56
|
+
```
|
|
45
57
|
|
|
46
58
|
### Agent 1: Security Scanner (Core)
|
|
47
59
|
```
|
package/dist/cli/index.js
CHANGED
|
@@ -42,87 +42,27 @@ program
|
|
|
42
42
|
const agentCmd = program
|
|
43
43
|
.command('agent')
|
|
44
44
|
.description('Manage custom agents');
|
|
45
|
-
agentCmd
|
|
46
|
-
.command('init')
|
|
47
|
-
.description('Create .coverme/agents.json with example custom agents')
|
|
48
|
-
.action(() => {
|
|
49
|
-
const covermeDir = (0, path_1.join)(process.cwd(), '.coverme');
|
|
50
|
-
if (!(0, fs_1.existsSync)(covermeDir)) {
|
|
51
|
-
(0, fs_1.mkdirSync)(covermeDir, { recursive: true });
|
|
52
|
-
}
|
|
53
|
-
const agentsPath = (0, path_1.join)(covermeDir, 'agents.json');
|
|
54
|
-
if ((0, fs_1.existsSync)(agentsPath)) {
|
|
55
|
-
console.log(`agents.json already exists at ${agentsPath}`);
|
|
56
|
-
console.log('Use "coverme agent add" to add a new agent');
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
const exampleAgents = {
|
|
60
|
-
customAgents: [],
|
|
61
|
-
settings: {
|
|
62
|
-
runCustomAgentsInParallel: true,
|
|
63
|
-
customAgentTimeout: 120000
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
(0, fs_1.writeFileSync)(agentsPath, JSON.stringify(exampleAgents, null, 2));
|
|
67
|
-
console.log(`Created ${agentsPath}`);
|
|
68
|
-
console.log('Use "coverme agent add" to add custom agents');
|
|
69
|
-
});
|
|
70
45
|
agentCmd
|
|
71
46
|
.command('add')
|
|
72
|
-
.description('Add a new custom agent
|
|
73
|
-
.
|
|
74
|
-
.
|
|
75
|
-
.
|
|
76
|
-
.option('--prefix <prefix>', 'Finding ID prefix (2-6 uppercase letters)')
|
|
77
|
-
.option('--prompt <prompt>', 'Agent prompt/instructions')
|
|
78
|
-
.action((options) => {
|
|
47
|
+
.description('Add a new custom agent')
|
|
48
|
+
.argument('<name>', 'Agent name (e.g., "John")')
|
|
49
|
+
.argument('<task>', 'What the agent should do')
|
|
50
|
+
.action((name, task) => {
|
|
79
51
|
const covermeDir = (0, path_1.join)(process.cwd(), '.coverme');
|
|
80
52
|
const agentsPath = (0, path_1.join)(covermeDir, 'agents.json');
|
|
81
53
|
if (!(0, fs_1.existsSync)(covermeDir)) {
|
|
82
54
|
(0, fs_1.mkdirSync)(covermeDir, { recursive: true });
|
|
83
55
|
}
|
|
84
|
-
let agents = {
|
|
56
|
+
let agents = { agents: [] };
|
|
85
57
|
if ((0, fs_1.existsSync)(agentsPath)) {
|
|
86
58
|
agents = JSON.parse((0, fs_1.readFileSync)(agentsPath, 'utf-8'));
|
|
59
|
+
if (!agents.agents)
|
|
60
|
+
agents.agents = [];
|
|
87
61
|
}
|
|
88
|
-
|
|
89
|
-
console.log(`
|
|
90
|
-
Usage: coverme agent add --id <id> --name <name> --phase <phase> --prefix <prefix> --prompt <prompt>
|
|
91
|
-
|
|
92
|
-
Example:
|
|
93
|
-
coverme agent add \\
|
|
94
|
-
--id "dror" \\
|
|
95
|
-
--name "Dror - Security Expert" \\
|
|
96
|
-
--phase "discovery" \\
|
|
97
|
-
--prefix "DROR" \\
|
|
98
|
-
--prompt "You are Dror, a security expert. Find advanced vulnerabilities..."
|
|
99
|
-
|
|
100
|
-
Phases:
|
|
101
|
-
discovery - Runs in Phase 1 with security scanners
|
|
102
|
-
validation - Runs in Phase 2 with validators
|
|
103
|
-
consensus - Runs in Phase 3 during consensus building
|
|
104
|
-
`);
|
|
105
|
-
return;
|
|
106
|
-
}
|
|
107
|
-
const newAgent = {
|
|
108
|
-
id: options.id,
|
|
109
|
-
name: options.name,
|
|
110
|
-
phase: options.phase,
|
|
111
|
-
priority: 5,
|
|
112
|
-
idPrefix: options.prefix || options.id.toUpperCase().slice(0, 4),
|
|
113
|
-
prompt: options.prompt,
|
|
114
|
-
enabled: true,
|
|
115
|
-
runInBackground: true
|
|
116
|
-
};
|
|
117
|
-
// Check for duplicate ID
|
|
118
|
-
if (agents.customAgents.some((a) => a.id === newAgent.id)) {
|
|
119
|
-
console.error(`Agent with id "${newAgent.id}" already exists`);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
agents.customAgents.push(newAgent);
|
|
62
|
+
agents.agents.push({ name, task });
|
|
123
63
|
(0, fs_1.writeFileSync)(agentsPath, JSON.stringify(agents, null, 2));
|
|
124
|
-
console.log(`Added agent "${
|
|
125
|
-
console.log(`
|
|
64
|
+
console.log(`Added agent "${name}"`);
|
|
65
|
+
console.log(`Task: ${task}`);
|
|
126
66
|
});
|
|
127
67
|
agentCmd
|
|
128
68
|
.command('list')
|
|
@@ -130,76 +70,40 @@ agentCmd
|
|
|
130
70
|
.action(() => {
|
|
131
71
|
const agentsPath = (0, path_1.join)(process.cwd(), '.coverme', 'agents.json');
|
|
132
72
|
if (!(0, fs_1.existsSync)(agentsPath)) {
|
|
133
|
-
console.log('No custom agents
|
|
73
|
+
console.log('No custom agents. Add one with: coverme agent add "John" "Check .env files for secrets"');
|
|
134
74
|
return;
|
|
135
75
|
}
|
|
136
76
|
const agents = JSON.parse((0, fs_1.readFileSync)(agentsPath, 'utf-8'));
|
|
137
|
-
if (!agents.
|
|
138
|
-
console.log('No custom agents
|
|
77
|
+
if (!agents.agents || agents.agents.length === 0) {
|
|
78
|
+
console.log('No custom agents. Add one with: coverme agent add "John" "Check .env files for secrets"');
|
|
139
79
|
return;
|
|
140
80
|
}
|
|
141
81
|
console.log('\nCustom Agents:\n');
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
console.log(`
|
|
145
|
-
console.log(` ID: ${agent.id} | Phase: ${agent.phase} | Prefix: ${agent.idPrefix}`);
|
|
146
|
-
console.log(` Prompt: ${agent.prompt.slice(0, 60)}...`);
|
|
82
|
+
agents.agents.forEach((agent, i) => {
|
|
83
|
+
console.log(` ${i + 1}. ${agent.name}`);
|
|
84
|
+
console.log(` Task: ${agent.task}`);
|
|
147
85
|
console.log('');
|
|
148
|
-
}
|
|
86
|
+
});
|
|
149
87
|
});
|
|
150
88
|
agentCmd
|
|
151
89
|
.command('remove')
|
|
152
90
|
.description('Remove a custom agent')
|
|
153
|
-
.argument('<
|
|
154
|
-
.action((
|
|
91
|
+
.argument('<name>', 'Agent name to remove')
|
|
92
|
+
.action((name) => {
|
|
155
93
|
const agentsPath = (0, path_1.join)(process.cwd(), '.coverme', 'agents.json');
|
|
156
94
|
if (!(0, fs_1.existsSync)(agentsPath)) {
|
|
157
95
|
console.error('No agents.json found');
|
|
158
96
|
return;
|
|
159
97
|
}
|
|
160
98
|
const agents = JSON.parse((0, fs_1.readFileSync)(agentsPath, 'utf-8'));
|
|
161
|
-
const idx = agents.
|
|
99
|
+
const idx = agents.agents.findIndex((a) => a.name.toLowerCase() === name.toLowerCase());
|
|
162
100
|
if (idx === -1) {
|
|
163
|
-
console.error(`Agent "${
|
|
101
|
+
console.error(`Agent "${name}" not found`);
|
|
164
102
|
return;
|
|
165
103
|
}
|
|
166
|
-
const removed = agents.
|
|
104
|
+
const removed = agents.agents.splice(idx, 1)[0];
|
|
167
105
|
(0, fs_1.writeFileSync)(agentsPath, JSON.stringify(agents, null, 2));
|
|
168
106
|
console.log(`Removed agent "${removed.name}"`);
|
|
169
107
|
});
|
|
170
|
-
agentCmd
|
|
171
|
-
.command('example')
|
|
172
|
-
.description('Show example agent configurations')
|
|
173
|
-
.action(() => {
|
|
174
|
-
const examplePath = (0, path_1.join)(__dirname, '..', 'templates', 'agents.example.json');
|
|
175
|
-
if ((0, fs_1.existsSync)(examplePath)) {
|
|
176
|
-
console.log((0, fs_1.readFileSync)(examplePath, 'utf-8'));
|
|
177
|
-
}
|
|
178
|
-
else {
|
|
179
|
-
console.log(`
|
|
180
|
-
Example agents.json:
|
|
181
|
-
|
|
182
|
-
{
|
|
183
|
-
"customAgents": [
|
|
184
|
-
{
|
|
185
|
-
"id": "dror",
|
|
186
|
-
"name": "Dror - Senior Security Expert",
|
|
187
|
-
"phase": "discovery",
|
|
188
|
-
"priority": 1,
|
|
189
|
-
"idPrefix": "DROR",
|
|
190
|
-
"prompt": "You are Dror, a senior security expert with 15 years of experience..."
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
"id": "compliance",
|
|
194
|
-
"name": "Compliance Checker",
|
|
195
|
-
"phase": "discovery",
|
|
196
|
-
"idPrefix": "COMP",
|
|
197
|
-
"prompt": "Check for GDPR, PCI-DSS, HIPAA, SOC2 compliance issues..."
|
|
198
|
-
}
|
|
199
|
-
]
|
|
200
|
-
}
|
|
201
|
-
`);
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
108
|
program.parse();
|
|
205
109
|
//# sourceMappingURL=index.js.map
|
package/dist/cli/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,uCAAiC;AACjC,uCAAiC;AACjC,iDAAoD;AACpD,2BAAsF;AACtF,+BAA4B;AAE5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3F,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,uEAAuE,CAAC;KACpF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,cAAc,EAAE,yCAAyC,CAAC;KACjE,MAAM,CAAC,cAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gDAAgD,CAAC;KAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC;KACvC,MAAM,CAAC,uBAAuB,EAAE,oCAAoC,EAAE,KAAK,CAAC;KAC5E,MAAM,CAAC,0BAA0B,EAAE,kBAAkB,CAAC;KACtD,MAAM,CAAC,yBAAyB,EAAE,qDAAqD,EAAE,KAAK,CAAC;KAC/F,MAAM,CAAC,wBAAwB,EAAE,iDAAiD,EAAE,KAAK,CAAC;KAC1F,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,EAAE,GAAG,CAAC;KAChE,MAAM,CAAC,cAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,QAAQ,CAAC,aAAa,EAAE,gCAAgC,CAAC;KACzD,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,EAAE,KAAK,CAAC;KAClE,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,OAAqD,EAAE,EAAE;IACxF,MAAM,IAAA,yBAAc,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEL,4BAA4B;AAC5B,MAAM,QAAQ,GAAG,OAAO;KACrB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sBAAsB,CAAC,CAAC;AAEvC,QAAQ;KACL,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/cli/index.ts"],"names":[],"mappings":";;;AAEA,yCAAoC;AACpC,uCAAiC;AACjC,uCAAiC;AACjC,iDAAoD;AACpD,2BAAsF;AACtF,+BAA4B;AAE5B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,IAAA,WAAI,EAAC,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC;AAE3F,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,uEAAuE,CAAC;KACpF,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAExB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wDAAwD,CAAC;KACrE,MAAM,CAAC,cAAc,EAAE,yCAAyC,CAAC;KACjE,MAAM,CAAC,cAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gDAAgD,CAAC;KAC7D,QAAQ,CAAC,QAAQ,EAAE,cAAc,EAAE,GAAG,CAAC;KACvC,MAAM,CAAC,uBAAuB,EAAE,oCAAoC,EAAE,KAAK,CAAC;KAC5E,MAAM,CAAC,0BAA0B,EAAE,kBAAkB,CAAC;KACtD,MAAM,CAAC,yBAAyB,EAAE,qDAAqD,EAAE,KAAK,CAAC;KAC/F,MAAM,CAAC,wBAAwB,EAAE,iDAAiD,EAAE,KAAK,CAAC;KAC1F,MAAM,CAAC,eAAe,EAAE,gBAAgB,CAAC;KACzC,MAAM,CAAC,sBAAsB,EAAE,2BAA2B,EAAE,GAAG,CAAC;KAChE,MAAM,CAAC,cAAI,CAAC,CAAC;AAEhB,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,yCAAyC,CAAC;KACtD,QAAQ,CAAC,aAAa,EAAE,gCAAgC,CAAC;KACzD,MAAM,CAAC,qBAAqB,EAAE,kBAAkB,CAAC;KACjD,MAAM,CAAC,uBAAuB,EAAE,0BAA0B,EAAE,KAAK,CAAC;KAClE,MAAM,CAAC,KAAK,EAAE,QAAgB,EAAE,OAAqD,EAAE,EAAE;IACxF,MAAM,IAAA,yBAAc,EAAC,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAC1E,CAAC,CAAC,CAAC;AAEL,4BAA4B;AAC5B,MAAM,QAAQ,GAAG,OAAO;KACrB,OAAO,CAAC,OAAO,CAAC;KAChB,WAAW,CAAC,sBAAsB,CAAC,CAAC;AAEvC,QAAQ;KACL,OAAO,CAAC,KAAK,CAAC;KACd,WAAW,CAAC,wBAAwB,CAAC;KACrC,QAAQ,CAAC,QAAQ,EAAE,2BAA2B,CAAC;KAC/C,QAAQ,CAAC,QAAQ,EAAE,0BAA0B,CAAC;KAC9C,MAAM,CAAC,CAAC,IAAY,EAAE,IAAY,EAAE,EAAE;IACrC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,CAAC,CAAC;IACnD,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,aAAa,CAAC,CAAC;IAEnD,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,IAAI,MAAM,GAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;IACjC,IAAI,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC3B,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;IACzC,CAAC;IAED,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IACnC,IAAA,kBAAa,EAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,GAAG,CAAC,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;AAC/B,CAAC,CAAC,CAAC;AAEL,QAAQ;KACL,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,wBAAwB,CAAC;KACrC,MAAM,CAAC,GAAG,EAAE;IACX,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAClE,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,yFAAyF,CAAC,CAAC;QACvG,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,yFAAyF,CAAC,CAAC;QACvG,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,CAAC;IAClC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAU,EAAE,CAAS,EAAE,EAAE;QAC9C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACzC,OAAO,CAAC,GAAG,CAAC,cAAc,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEL,QAAQ;KACL,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,uBAAuB,CAAC;KACpC,QAAQ,CAAC,QAAQ,EAAE,sBAAsB,CAAC;KAC1C,MAAM,CAAC,CAAC,IAAY,EAAE,EAAE;IACvB,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,OAAO,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,aAAa,CAAC,CAAC;IAClE,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;QACtC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC7F,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,aAAa,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,IAAA,kBAAa,EAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,CAAC,IAAI,GAAG,CAAC,CAAC;AACjD,CAAC,CAAC,CAAC;AAEL,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
package/dist/cli/init.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAihBD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"AAIA,UAAU,WAAW;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAihBD,wBAAsB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAwI9D"}
|
package/dist/cli/init.js
CHANGED
|
@@ -676,16 +676,13 @@ Reports saved to: .coverme/
|
|
|
676
676
|
- scan_YYYY-MM-DD_HH-MM-SS.json
|
|
677
677
|
|
|
678
678
|
Custom Agents:
|
|
679
|
-
Add your own
|
|
679
|
+
Add your own experts to the scan:
|
|
680
680
|
|
|
681
|
-
coverme agent add
|
|
682
|
-
|
|
683
|
-
--name "John - Security Expert" \\
|
|
684
|
-
--phase "discovery" \\
|
|
685
|
-
--prefix "JOHN" \\
|
|
686
|
-
--prompt "You are John, a senior security expert..."
|
|
681
|
+
coverme agent add "John" "Check all .env files for exposed secrets"
|
|
682
|
+
coverme agent add "Sarah" "Find regex patterns vulnerable to ReDoS"
|
|
687
683
|
|
|
688
|
-
|
|
684
|
+
List agents: coverme agent list
|
|
685
|
+
Remove agent: coverme agent remove "John"
|
|
689
686
|
|
|
690
687
|
The .coverme/ folder is automatically added to .gitignore
|
|
691
688
|
|
package/dist/cli/init.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuhBA,
|
|
1
|
+
{"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/cli/init.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,33 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"customAgents": [
|
|
2
|
+
"agents": [
|
|
4
3
|
{
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"phase": "discovery",
|
|
8
|
-
"priority": 1,
|
|
9
|
-
"idPrefix": "JOHN",
|
|
10
|
-
"prompt": "You are John, a senior security expert with 15 years of experience in penetration testing and secure code review.\n\nYour specialty areas:\n- Advanced injection attacks (second-order SQLi, blind XXE)\n- Authentication bypass techniques\n- Business logic exploitation\n- Cloud security (AWS, GCP, Azure misconfigurations)\n\nScan the codebase and find issues that junior scanners might miss.\n\nFor EACH finding, output:\n```json\n{\n \"id\": \"JOHN-XXX\",\n \"title\": \"...\",\n \"severity\": \"critical|high|medium|low\",\n \"category\": \"security\",\n \"file\": \"path/to/file\",\n \"line\": 123,\n \"code\": \"vulnerable code snippet\",\n \"description\": \"What is the issue\",\n \"impact\": \"What an attacker could do\",\n \"recommendation\": \"How to fix it\",\n \"confidence\": 85\n}\n```"
|
|
4
|
+
"name": "John",
|
|
5
|
+
"task": "Check all .env files and environment variables for exposed secrets, API keys, and sensitive configuration"
|
|
11
6
|
},
|
|
12
7
|
{
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"phase": "discovery",
|
|
16
|
-
"priority": 2,
|
|
17
|
-
"idPrefix": "COMP",
|
|
18
|
-
"prompt": "Check for compliance issues:\n- GDPR data handling\n- PCI-DSS requirements for payment data\n- HIPAA for health data\n- SOC2 controls\n\nOutput findings in standard JSON format with id prefix COMP-XXX."
|
|
8
|
+
"name": "Sarah",
|
|
9
|
+
"task": "Find all regex patterns in the code and check if any are vulnerable to ReDoS attacks"
|
|
19
10
|
},
|
|
20
11
|
{
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"phase": "validation",
|
|
24
|
-
"priority": 1,
|
|
25
|
-
"idPrefix": "VAL",
|
|
26
|
-
"prompt": "You understand our specific business domain.\n\nReview findings and mark as false positive if:\n- The 'vulnerability' is actually our intended behavior\n- There's domain-specific context that makes it safe\n- Our architecture already handles this elsewhere\n\nOutput: { confirmed: [...], falsePositives: [{id, reason}] }"
|
|
12
|
+
"name": "DevOps Expert",
|
|
13
|
+
"task": "Review Dockerfile, docker-compose, and Kubernetes configs for security misconfigurations"
|
|
27
14
|
}
|
|
28
|
-
]
|
|
29
|
-
"settings": {
|
|
30
|
-
"runCustomAgentsInParallel": true,
|
|
31
|
-
"customAgentTimeout": 120000
|
|
32
|
-
}
|
|
15
|
+
]
|
|
33
16
|
}
|
package/package.json
CHANGED
package/src/cli/index.ts
CHANGED
|
@@ -49,44 +49,12 @@ const agentCmd = program
|
|
|
49
49
|
.command('agent')
|
|
50
50
|
.description('Manage custom agents');
|
|
51
51
|
|
|
52
|
-
agentCmd
|
|
53
|
-
.command('init')
|
|
54
|
-
.description('Create .coverme/agents.json with example custom agents')
|
|
55
|
-
.action(() => {
|
|
56
|
-
const covermeDir = join(process.cwd(), '.coverme');
|
|
57
|
-
if (!existsSync(covermeDir)) {
|
|
58
|
-
mkdirSync(covermeDir, { recursive: true });
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
const agentsPath = join(covermeDir, 'agents.json');
|
|
62
|
-
if (existsSync(agentsPath)) {
|
|
63
|
-
console.log(`agents.json already exists at ${agentsPath}`);
|
|
64
|
-
console.log('Use "coverme agent add" to add a new agent');
|
|
65
|
-
return;
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
const exampleAgents = {
|
|
69
|
-
customAgents: [],
|
|
70
|
-
settings: {
|
|
71
|
-
runCustomAgentsInParallel: true,
|
|
72
|
-
customAgentTimeout: 120000
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
|
-
writeFileSync(agentsPath, JSON.stringify(exampleAgents, null, 2));
|
|
77
|
-
console.log(`Created ${agentsPath}`);
|
|
78
|
-
console.log('Use "coverme agent add" to add custom agents');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
52
|
agentCmd
|
|
82
53
|
.command('add')
|
|
83
|
-
.description('Add a new custom agent
|
|
84
|
-
.
|
|
85
|
-
.
|
|
86
|
-
.
|
|
87
|
-
.option('--prefix <prefix>', 'Finding ID prefix (2-6 uppercase letters)')
|
|
88
|
-
.option('--prompt <prompt>', 'Agent prompt/instructions')
|
|
89
|
-
.action((options) => {
|
|
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) => {
|
|
90
58
|
const covermeDir = join(process.cwd(), '.coverme');
|
|
91
59
|
const agentsPath = join(covermeDir, 'agents.json');
|
|
92
60
|
|
|
@@ -94,52 +62,16 @@ agentCmd
|
|
|
94
62
|
mkdirSync(covermeDir, { recursive: true });
|
|
95
63
|
}
|
|
96
64
|
|
|
97
|
-
let agents: any = {
|
|
65
|
+
let agents: any = { agents: [] };
|
|
98
66
|
if (existsSync(agentsPath)) {
|
|
99
67
|
agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
68
|
+
if (!agents.agents) agents.agents = [];
|
|
100
69
|
}
|
|
101
70
|
|
|
102
|
-
|
|
103
|
-
console.log(`
|
|
104
|
-
Usage: coverme agent add --id <id> --name <name> --phase <phase> --prefix <prefix> --prompt <prompt>
|
|
105
|
-
|
|
106
|
-
Example:
|
|
107
|
-
coverme agent add \\
|
|
108
|
-
--id "dror" \\
|
|
109
|
-
--name "Dror - Security Expert" \\
|
|
110
|
-
--phase "discovery" \\
|
|
111
|
-
--prefix "DROR" \\
|
|
112
|
-
--prompt "You are Dror, a security expert. Find advanced vulnerabilities..."
|
|
113
|
-
|
|
114
|
-
Phases:
|
|
115
|
-
discovery - Runs in Phase 1 with security scanners
|
|
116
|
-
validation - Runs in Phase 2 with validators
|
|
117
|
-
consensus - Runs in Phase 3 during consensus building
|
|
118
|
-
`);
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const newAgent = {
|
|
123
|
-
id: options.id,
|
|
124
|
-
name: options.name,
|
|
125
|
-
phase: options.phase,
|
|
126
|
-
priority: 5,
|
|
127
|
-
idPrefix: options.prefix || options.id.toUpperCase().slice(0, 4),
|
|
128
|
-
prompt: options.prompt,
|
|
129
|
-
enabled: true,
|
|
130
|
-
runInBackground: true
|
|
131
|
-
};
|
|
132
|
-
|
|
133
|
-
// Check for duplicate ID
|
|
134
|
-
if (agents.customAgents.some((a: any) => a.id === newAgent.id)) {
|
|
135
|
-
console.error(`Agent with id "${newAgent.id}" already exists`);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
agents.customAgents.push(newAgent);
|
|
71
|
+
agents.agents.push({ name, task });
|
|
140
72
|
writeFileSync(agentsPath, JSON.stringify(agents, null, 2));
|
|
141
|
-
console.log(`Added agent "${
|
|
142
|
-
console.log(`
|
|
73
|
+
console.log(`Added agent "${name}"`);
|
|
74
|
+
console.log(`Task: ${task}`);
|
|
143
75
|
});
|
|
144
76
|
|
|
145
77
|
agentCmd
|
|
@@ -148,31 +80,29 @@ agentCmd
|
|
|
148
80
|
.action(() => {
|
|
149
81
|
const agentsPath = join(process.cwd(), '.coverme', 'agents.json');
|
|
150
82
|
if (!existsSync(agentsPath)) {
|
|
151
|
-
console.log('No custom agents
|
|
83
|
+
console.log('No custom agents. Add one with: coverme agent add "John" "Check .env files for secrets"');
|
|
152
84
|
return;
|
|
153
85
|
}
|
|
154
86
|
|
|
155
87
|
const agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
156
|
-
if (!agents.
|
|
157
|
-
console.log('No custom agents
|
|
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"');
|
|
158
90
|
return;
|
|
159
91
|
}
|
|
160
92
|
|
|
161
93
|
console.log('\nCustom Agents:\n');
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
console.log(`
|
|
165
|
-
console.log(` ID: ${agent.id} | Phase: ${agent.phase} | Prefix: ${agent.idPrefix}`);
|
|
166
|
-
console.log(` Prompt: ${agent.prompt.slice(0, 60)}...`);
|
|
94
|
+
agents.agents.forEach((agent: any, i: number) => {
|
|
95
|
+
console.log(` ${i + 1}. ${agent.name}`);
|
|
96
|
+
console.log(` Task: ${agent.task}`);
|
|
167
97
|
console.log('');
|
|
168
|
-
}
|
|
98
|
+
});
|
|
169
99
|
});
|
|
170
100
|
|
|
171
101
|
agentCmd
|
|
172
102
|
.command('remove')
|
|
173
103
|
.description('Remove a custom agent')
|
|
174
|
-
.argument('<
|
|
175
|
-
.action((
|
|
104
|
+
.argument('<name>', 'Agent name to remove')
|
|
105
|
+
.action((name: string) => {
|
|
176
106
|
const agentsPath = join(process.cwd(), '.coverme', 'agents.json');
|
|
177
107
|
if (!existsSync(agentsPath)) {
|
|
178
108
|
console.error('No agents.json found');
|
|
@@ -180,49 +110,15 @@ agentCmd
|
|
|
180
110
|
}
|
|
181
111
|
|
|
182
112
|
const agents = JSON.parse(readFileSync(agentsPath, 'utf-8'));
|
|
183
|
-
const idx = agents.
|
|
113
|
+
const idx = agents.agents.findIndex((a: any) => a.name.toLowerCase() === name.toLowerCase());
|
|
184
114
|
if (idx === -1) {
|
|
185
|
-
console.error(`Agent "${
|
|
115
|
+
console.error(`Agent "${name}" not found`);
|
|
186
116
|
return;
|
|
187
117
|
}
|
|
188
118
|
|
|
189
|
-
const removed = agents.
|
|
119
|
+
const removed = agents.agents.splice(idx, 1)[0];
|
|
190
120
|
writeFileSync(agentsPath, JSON.stringify(agents, null, 2));
|
|
191
121
|
console.log(`Removed agent "${removed.name}"`);
|
|
192
122
|
});
|
|
193
123
|
|
|
194
|
-
agentCmd
|
|
195
|
-
.command('example')
|
|
196
|
-
.description('Show example agent configurations')
|
|
197
|
-
.action(() => {
|
|
198
|
-
const examplePath = join(__dirname, '..', 'templates', 'agents.example.json');
|
|
199
|
-
if (existsSync(examplePath)) {
|
|
200
|
-
console.log(readFileSync(examplePath, 'utf-8'));
|
|
201
|
-
} else {
|
|
202
|
-
console.log(`
|
|
203
|
-
Example agents.json:
|
|
204
|
-
|
|
205
|
-
{
|
|
206
|
-
"customAgents": [
|
|
207
|
-
{
|
|
208
|
-
"id": "dror",
|
|
209
|
-
"name": "Dror - Senior Security Expert",
|
|
210
|
-
"phase": "discovery",
|
|
211
|
-
"priority": 1,
|
|
212
|
-
"idPrefix": "DROR",
|
|
213
|
-
"prompt": "You are Dror, a senior security expert with 15 years of experience..."
|
|
214
|
-
},
|
|
215
|
-
{
|
|
216
|
-
"id": "compliance",
|
|
217
|
-
"name": "Compliance Checker",
|
|
218
|
-
"phase": "discovery",
|
|
219
|
-
"idPrefix": "COMP",
|
|
220
|
-
"prompt": "Check for GDPR, PCI-DSS, HIPAA, SOC2 compliance issues..."
|
|
221
|
-
}
|
|
222
|
-
]
|
|
223
|
-
}
|
|
224
|
-
`);
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
|
|
228
124
|
program.parse();
|
package/src/cli/init.ts
CHANGED
|
@@ -657,16 +657,13 @@ Reports saved to: .coverme/
|
|
|
657
657
|
- scan_YYYY-MM-DD_HH-MM-SS.json
|
|
658
658
|
|
|
659
659
|
Custom Agents:
|
|
660
|
-
Add your own
|
|
660
|
+
Add your own experts to the scan:
|
|
661
661
|
|
|
662
|
-
coverme agent add
|
|
663
|
-
|
|
664
|
-
--name "John - Security Expert" \\
|
|
665
|
-
--phase "discovery" \\
|
|
666
|
-
--prefix "JOHN" \\
|
|
667
|
-
--prompt "You are John, a senior security expert..."
|
|
662
|
+
coverme agent add "John" "Check all .env files for exposed secrets"
|
|
663
|
+
coverme agent add "Sarah" "Find regex patterns vulnerable to ReDoS"
|
|
668
664
|
|
|
669
|
-
|
|
665
|
+
List agents: coverme agent list
|
|
666
|
+
Remove agent: coverme agent remove "John"
|
|
670
667
|
|
|
671
668
|
The .coverme/ folder is automatically added to .gitignore
|
|
672
669
|
|
|
@@ -1,33 +1,16 @@
|
|
|
1
1
|
{
|
|
2
|
-
"
|
|
3
|
-
"customAgents": [
|
|
2
|
+
"agents": [
|
|
4
3
|
{
|
|
5
|
-
"
|
|
6
|
-
"
|
|
7
|
-
"phase": "discovery",
|
|
8
|
-
"priority": 1,
|
|
9
|
-
"idPrefix": "JOHN",
|
|
10
|
-
"prompt": "You are John, a senior security expert with 15 years of experience in penetration testing and secure code review.\n\nYour specialty areas:\n- Advanced injection attacks (second-order SQLi, blind XXE)\n- Authentication bypass techniques\n- Business logic exploitation\n- Cloud security (AWS, GCP, Azure misconfigurations)\n\nScan the codebase and find issues that junior scanners might miss.\n\nFor EACH finding, output:\n```json\n{\n \"id\": \"JOHN-XXX\",\n \"title\": \"...\",\n \"severity\": \"critical|high|medium|low\",\n \"category\": \"security\",\n \"file\": \"path/to/file\",\n \"line\": 123,\n \"code\": \"vulnerable code snippet\",\n \"description\": \"What is the issue\",\n \"impact\": \"What an attacker could do\",\n \"recommendation\": \"How to fix it\",\n \"confidence\": 85\n}\n```"
|
|
4
|
+
"name": "John",
|
|
5
|
+
"task": "Check all .env files and environment variables for exposed secrets, API keys, and sensitive configuration"
|
|
11
6
|
},
|
|
12
7
|
{
|
|
13
|
-
"
|
|
14
|
-
"
|
|
15
|
-
"phase": "discovery",
|
|
16
|
-
"priority": 2,
|
|
17
|
-
"idPrefix": "COMP",
|
|
18
|
-
"prompt": "Check for compliance issues:\n- GDPR data handling\n- PCI-DSS requirements for payment data\n- HIPAA for health data\n- SOC2 controls\n\nOutput findings in standard JSON format with id prefix COMP-XXX."
|
|
8
|
+
"name": "Sarah",
|
|
9
|
+
"task": "Find all regex patterns in the code and check if any are vulnerable to ReDoS attacks"
|
|
19
10
|
},
|
|
20
11
|
{
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"phase": "validation",
|
|
24
|
-
"priority": 1,
|
|
25
|
-
"idPrefix": "VAL",
|
|
26
|
-
"prompt": "You understand our specific business domain.\n\nReview findings and mark as false positive if:\n- The 'vulnerability' is actually our intended behavior\n- There's domain-specific context that makes it safe\n- Our architecture already handles this elsewhere\n\nOutput: { confirmed: [...], falsePositives: [{id, reason}] }"
|
|
12
|
+
"name": "DevOps Expert",
|
|
13
|
+
"task": "Review Dockerfile, docker-compose, and Kubernetes configs for security misconfigurations"
|
|
27
14
|
}
|
|
28
|
-
]
|
|
29
|
-
"settings": {
|
|
30
|
-
"runCustomAgentsInParallel": true,
|
|
31
|
-
"customAgentTimeout": 120000
|
|
32
|
-
}
|
|
15
|
+
]
|
|
33
16
|
}
|