@jigyasudham/veto 0.8.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/.claude/settings.local.json +9 -0
- package/README.md +190 -0
- package/dist/adapters/claude.js +57 -0
- package/dist/adapters/codex.js +58 -0
- package/dist/adapters/gemini.js +58 -0
- package/dist/adapters/index.js +156 -0
- package/dist/agents/development/api.js +116 -0
- package/dist/agents/development/backend.js +82 -0
- package/dist/agents/development/coder.js +207 -0
- package/dist/agents/development/database.js +81 -0
- package/dist/agents/development/debugger.js +234 -0
- package/dist/agents/development/devops.js +84 -0
- package/dist/agents/development/frontend.js +83 -0
- package/dist/agents/development/migration.js +141 -0
- package/dist/agents/development/performance.js +142 -0
- package/dist/agents/development/refactor.js +85 -0
- package/dist/agents/development/reviewer.js +260 -0
- package/dist/agents/development/tester.js +143 -0
- package/dist/agents/executor.js +144 -0
- package/dist/agents/memory/context-manager.js +167 -0
- package/dist/agents/memory/decision-logger.js +157 -0
- package/dist/agents/memory/knowledge-base.js +120 -0
- package/dist/agents/memory/pattern-learner.js +140 -0
- package/dist/agents/memory/project-mapper.js +114 -0
- package/dist/agents/quality/accessibility.js +89 -0
- package/dist/agents/quality/code-quality.js +109 -0
- package/dist/agents/quality/compatibility.js +55 -0
- package/dist/agents/quality/documentation.js +95 -0
- package/dist/agents/quality/error-handling.js +87 -0
- package/dist/agents/research/competitor-analyzer.js +44 -0
- package/dist/agents/research/cost-analyzer.js +51 -0
- package/dist/agents/research/estimator.js +57 -0
- package/dist/agents/research/ethics-bias.js +111 -0
- package/dist/agents/research/researcher.js +112 -0
- package/dist/agents/research/risk-assessor.js +61 -0
- package/dist/agents/research/tech-advisor.js +52 -0
- package/dist/agents/security/auth.js +269 -0
- package/dist/agents/security/dependency-audit.js +273 -0
- package/dist/agents/security/penetration.js +245 -0
- package/dist/agents/security/privacy.js +259 -0
- package/dist/agents/security/scanner.js +288 -0
- package/dist/agents/security/secrets.js +212 -0
- package/dist/agents/types.js +2 -0
- package/dist/agents/workflow/automation.js +56 -0
- package/dist/agents/workflow/file-manager.js +49 -0
- package/dist/agents/workflow/git-agent.js +52 -0
- package/dist/agents/workflow/reporter.js +48 -0
- package/dist/agents/workflow/search-agent.js +39 -0
- package/dist/agents/workflow/task-coordinator.js +40 -0
- package/dist/agents/workflow/task-planner.js +46 -0
- package/dist/cli.js +132 -0
- package/dist/council/decision-engine.js +136 -0
- package/dist/council/devil-advocate.js +106 -0
- package/dist/council/index.js +37 -0
- package/dist/council/lead-developer.js +108 -0
- package/dist/council/legal-compliance.js +142 -0
- package/dist/council/product-manager.js +92 -0
- package/dist/council/security.js +162 -0
- package/dist/council/system-architect.js +122 -0
- package/dist/council/types.js +2 -0
- package/dist/council/ux-designer.js +109 -0
- package/dist/memory/local.js +182 -0
- package/dist/memory/schema.js +116 -0
- package/dist/memory/sync.js +199 -0
- package/dist/router/complexity-scorer.js +78 -0
- package/dist/router/context-compressor.js +58 -0
- package/dist/router/index.js +29 -0
- package/dist/router/learning-updater.js +186 -0
- package/dist/router/model-selector.js +51 -0
- package/dist/router/rate-monitor.js +73 -0
- package/dist/server.js +949 -0
- package/dist/skills/development/skill-api-design.js +313 -0
- package/dist/skills/development/skill-auth.js +255 -0
- package/dist/skills/development/skill-ci-cd.js +2 -0
- package/dist/skills/development/skill-crud.js +193 -0
- package/dist/skills/development/skill-db-schema.js +2 -0
- package/dist/skills/development/skill-docker.js +2 -0
- package/dist/skills/development/skill-env-setup.js +2 -0
- package/dist/skills/development/skill-scaffold.js +299 -0
- package/dist/skills/intelligence/skill-complexity-score.js +66 -0
- package/dist/skills/intelligence/skill-cost-track.js +36 -0
- package/dist/skills/intelligence/skill-learning-loop.js +66 -0
- package/dist/skills/intelligence/skill-pattern-detect.js +35 -0
- package/dist/skills/intelligence/skill-rate-watch.js +58 -0
- package/dist/skills/memory/skill-context-compress.js +82 -0
- package/dist/skills/memory/skill-cross-sync.js +88 -0
- package/dist/skills/memory/skill-decision-log.js +103 -0
- package/dist/skills/memory/skill-session-restore.js +44 -0
- package/dist/skills/memory/skill-session-save.js +78 -0
- package/dist/skills/quality/skill-accessibility.js +2 -0
- package/dist/skills/quality/skill-code-review.js +60 -0
- package/dist/skills/quality/skill-docs-gen.js +2 -0
- package/dist/skills/quality/skill-perf-audit.js +2 -0
- package/dist/skills/quality/skill-security-scan.js +67 -0
- package/dist/skills/quality/skill-test-suite.js +274 -0
- package/dist/skills/workflow/skill-deploy.js +2 -0
- package/dist/skills/workflow/skill-git-workflow.js +2 -0
- package/dist/skills/workflow/skill-rollback.js +2 -0
- package/dist/skills/workflow/skill-task-breakdown.js +2 -0
- package/package.json +30 -0
- package/src/adapters/claude.ts +70 -0
- package/src/adapters/codex.ts +71 -0
- package/src/adapters/gemini.ts +71 -0
- package/src/adapters/index.ts +217 -0
- package/src/agents/development/api.ts +120 -0
- package/src/agents/development/backend.ts +85 -0
- package/src/agents/development/coder.ts +213 -0
- package/src/agents/development/database.ts +83 -0
- package/src/agents/development/debugger.ts +238 -0
- package/src/agents/development/devops.ts +86 -0
- package/src/agents/development/frontend.ts +85 -0
- package/src/agents/development/migration.ts +144 -0
- package/src/agents/development/performance.ts +144 -0
- package/src/agents/development/refactor.ts +86 -0
- package/src/agents/development/reviewer.ts +268 -0
- package/src/agents/development/tester.ts +151 -0
- package/src/agents/executor.ts +158 -0
- package/src/agents/memory/context-manager.ts +171 -0
- package/src/agents/memory/decision-logger.ts +160 -0
- package/src/agents/memory/knowledge-base.ts +124 -0
- package/src/agents/memory/pattern-learner.ts +143 -0
- package/src/agents/memory/project-mapper.ts +118 -0
- package/src/agents/quality/accessibility.ts +99 -0
- package/src/agents/quality/code-quality.ts +115 -0
- package/src/agents/quality/compatibility.ts +58 -0
- package/src/agents/quality/documentation.ts +105 -0
- package/src/agents/quality/error-handling.ts +96 -0
- package/src/agents/research/competitor-analyzer.ts +45 -0
- package/src/agents/research/cost-analyzer.ts +54 -0
- package/src/agents/research/estimator.ts +60 -0
- package/src/agents/research/ethics-bias.ts +113 -0
- package/src/agents/research/researcher.ts +114 -0
- package/src/agents/research/risk-assessor.ts +63 -0
- package/src/agents/research/tech-advisor.ts +55 -0
- package/src/agents/security/auth.ts +287 -0
- package/src/agents/security/dependency-audit.ts +337 -0
- package/src/agents/security/penetration.ts +262 -0
- package/src/agents/security/privacy.ts +285 -0
- package/src/agents/security/scanner.ts +322 -0
- package/src/agents/security/secrets.ts +249 -0
- package/src/agents/types.ts +66 -0
- package/src/agents/workflow/automation.ts +59 -0
- package/src/agents/workflow/file-manager.ts +52 -0
- package/src/agents/workflow/git-agent.ts +55 -0
- package/src/agents/workflow/reporter.ts +51 -0
- package/src/agents/workflow/search-agent.ts +40 -0
- package/src/agents/workflow/task-coordinator.ts +41 -0
- package/src/agents/workflow/task-planner.ts +47 -0
- package/src/cli.ts +143 -0
- package/src/council/decision-engine.ts +171 -0
- package/src/council/devil-advocate.ts +116 -0
- package/src/council/index.ts +44 -0
- package/src/council/lead-developer.ts +118 -0
- package/src/council/legal-compliance.ts +152 -0
- package/src/council/product-manager.ts +102 -0
- package/src/council/security.ts +172 -0
- package/src/council/system-architect.ts +132 -0
- package/src/council/types.ts +33 -0
- package/src/council/ux-designer.ts +121 -0
- package/src/memory/local.ts +305 -0
- package/src/memory/schema.ts +174 -0
- package/src/memory/sync.ts +274 -0
- package/src/router/complexity-scorer.ts +96 -0
- package/src/router/context-compressor.ts +74 -0
- package/src/router/index.ts +60 -0
- package/src/router/learning-updater.ts +271 -0
- package/src/router/model-selector.ts +83 -0
- package/src/router/rate-monitor.ts +103 -0
- package/src/server.ts +1038 -0
- package/src/skills/development/skill-api-design.ts +329 -0
- package/src/skills/development/skill-auth.ts +271 -0
- package/src/skills/development/skill-ci-cd.ts +0 -0
- package/src/skills/development/skill-crud.ts +209 -0
- package/src/skills/development/skill-db-schema.ts +0 -0
- package/src/skills/development/skill-docker.ts +0 -0
- package/src/skills/development/skill-env-setup.ts +0 -0
- package/src/skills/development/skill-scaffold.ts +323 -0
- package/src/skills/intelligence/skill-complexity-score.ts +69 -0
- package/src/skills/intelligence/skill-cost-track.ts +39 -0
- package/src/skills/intelligence/skill-learning-loop.ts +69 -0
- package/src/skills/intelligence/skill-pattern-detect.ts +38 -0
- package/src/skills/intelligence/skill-rate-watch.ts +61 -0
- package/src/skills/memory/skill-context-compress.ts +98 -0
- package/src/skills/memory/skill-cross-sync.ts +104 -0
- package/src/skills/memory/skill-decision-log.ts +119 -0
- package/src/skills/memory/skill-session-restore.ts +59 -0
- package/src/skills/memory/skill-session-save.ts +94 -0
- package/src/skills/quality/skill-accessibility.ts +0 -0
- package/src/skills/quality/skill-code-review.ts +84 -0
- package/src/skills/quality/skill-docs-gen.ts +0 -0
- package/src/skills/quality/skill-perf-audit.ts +0 -0
- package/src/skills/quality/skill-security-scan.ts +91 -0
- package/src/skills/quality/skill-test-suite.ts +290 -0
- package/src/skills/workflow/skill-deploy.ts +0 -0
- package/src/skills/workflow/skill-git-workflow.ts +0 -0
- package/src/skills/workflow/skill-rollback.ts +0 -0
- package/src/skills/workflow/skill-task-breakdown.ts +0 -0
- package/tsconfig.json +20 -0
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// ─── plan ────────────────────────────────────────────────────────────────────
|
|
2
|
+
export function plan(task, _context) {
|
|
3
|
+
return {
|
|
4
|
+
agent: 'reviewer',
|
|
5
|
+
task,
|
|
6
|
+
tier: 2,
|
|
7
|
+
approach: 'Systematic code review: assess complexity, error handling, naming, magic literals, nesting depth, and test coverage. Produce scored findings with actionable fixes.',
|
|
8
|
+
steps: [
|
|
9
|
+
'Read the module top-to-bottom to understand its purpose and public contract',
|
|
10
|
+
'Identify all exported symbols and verify they are intentional',
|
|
11
|
+
'Check function lengths — flag any function exceeding 50 lines for extraction',
|
|
12
|
+
'Assess cyclomatic complexity — any function with more than 10 branches is a risk',
|
|
13
|
+
'Verify every async call is awaited or explicitly fire-and-forget',
|
|
14
|
+
'Check error handling — all try/catch blocks must do something meaningful',
|
|
15
|
+
'Scan for magic numbers and untyped string literals',
|
|
16
|
+
'Measure nesting depth — refactor anything deeper than 3 levels',
|
|
17
|
+
'Review naming — variables, functions, and types should be self-documenting',
|
|
18
|
+
'Check for TODO/FIXME comments and ensure each links to a tracking issue',
|
|
19
|
+
'Verify unused imports and variables are removed',
|
|
20
|
+
'Confirm test coverage exists for every public function',
|
|
21
|
+
'Assess consistency with the rest of the codebase style',
|
|
22
|
+
],
|
|
23
|
+
checklist: [
|
|
24
|
+
'[ ] No function exceeds 50 lines of executable code',
|
|
25
|
+
'[ ] No function has cyclomatic complexity > 10',
|
|
26
|
+
'[ ] Every await is inside an async function',
|
|
27
|
+
'[ ] Every try/catch logs or rethrows — no silent swallow',
|
|
28
|
+
'[ ] No magic numbers — use named constants',
|
|
29
|
+
'[ ] No deeply nested if/for (max 3 levels)',
|
|
30
|
+
'[ ] All TODO/FIXME comments reference a ticket number',
|
|
31
|
+
'[ ] No unused variables or imports',
|
|
32
|
+
'[ ] Naming is consistent with the project convention (camelCase, PascalCase for types)',
|
|
33
|
+
'[ ] No console.log left in production paths',
|
|
34
|
+
'[ ] Public functions have JSDoc',
|
|
35
|
+
'[ ] Every exported function has at least one test',
|
|
36
|
+
'[ ] No any types without an explanatory comment',
|
|
37
|
+
'[ ] No circular imports',
|
|
38
|
+
],
|
|
39
|
+
pitfalls: [
|
|
40
|
+
'Approving a PR because it "looks fine" without running it locally',
|
|
41
|
+
'Missing async bugs — a synchronous function calling an async one without await silently drops the Promise',
|
|
42
|
+
'Over-reviewing style while missing logic errors — focus on correctness first',
|
|
43
|
+
'Not reading the tests — tests reveal intent, bad tests reveal bad design',
|
|
44
|
+
'Ignoring error handling because the happy path looks clean',
|
|
45
|
+
],
|
|
46
|
+
patterns: [
|
|
47
|
+
'Guard clause pattern (early returns to reduce nesting)',
|
|
48
|
+
'Strategy pattern (replace long switch/if chains)',
|
|
49
|
+
'Extract function refactoring',
|
|
50
|
+
'Null Object pattern (replace null checks)',
|
|
51
|
+
'Result/Option type (replace throw-based error handling)',
|
|
52
|
+
],
|
|
53
|
+
duration_estimate: '1-2 hours',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
// ─── helpers ─────────────────────────────────────────────────────────────────
|
|
57
|
+
function countLines(code) {
|
|
58
|
+
return code.split('\n').length;
|
|
59
|
+
}
|
|
60
|
+
function detectFunctions(code) {
|
|
61
|
+
const results = [];
|
|
62
|
+
const lines = code.split('\n');
|
|
63
|
+
// Match function declarations and arrow functions assigned to const/let/var
|
|
64
|
+
const funcRegex = /(?:function\s+(\w+)|(?:const|let|var)\s+(\w+)\s*=\s*(?:async\s*)?\()/;
|
|
65
|
+
let i = 0;
|
|
66
|
+
while (i < lines.length) {
|
|
67
|
+
const match = lines[i].match(funcRegex);
|
|
68
|
+
if (match) {
|
|
69
|
+
const name = match[1] || match[2] || 'anonymous';
|
|
70
|
+
let depth = 0;
|
|
71
|
+
let started = false;
|
|
72
|
+
const bodyLines = [];
|
|
73
|
+
let j = i;
|
|
74
|
+
while (j < lines.length) {
|
|
75
|
+
for (const ch of lines[j]) {
|
|
76
|
+
if (ch === '{') {
|
|
77
|
+
depth++;
|
|
78
|
+
started = true;
|
|
79
|
+
}
|
|
80
|
+
if (ch === '}')
|
|
81
|
+
depth--;
|
|
82
|
+
}
|
|
83
|
+
bodyLines.push(lines[j]);
|
|
84
|
+
if (started && depth === 0)
|
|
85
|
+
break;
|
|
86
|
+
j++;
|
|
87
|
+
}
|
|
88
|
+
results.push({ name, body: bodyLines.join('\n'), start: i + 1 });
|
|
89
|
+
i = j + 1;
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
return results;
|
|
96
|
+
}
|
|
97
|
+
function maxNestingDepth(code) {
|
|
98
|
+
let max = 0;
|
|
99
|
+
let depth = 0;
|
|
100
|
+
for (const ch of code) {
|
|
101
|
+
if (ch === '{') {
|
|
102
|
+
depth++;
|
|
103
|
+
max = Math.max(max, depth);
|
|
104
|
+
}
|
|
105
|
+
if (ch === '}')
|
|
106
|
+
depth--;
|
|
107
|
+
}
|
|
108
|
+
return max;
|
|
109
|
+
}
|
|
110
|
+
// ─── analyze ─────────────────────────────────────────────────────────────────
|
|
111
|
+
export function analyze(code, context) {
|
|
112
|
+
const findings = [];
|
|
113
|
+
const lines = code.split('\n');
|
|
114
|
+
const totalLines = countLines(code);
|
|
115
|
+
const subject = context ?? `Code (${totalLines} lines)`;
|
|
116
|
+
// 1. Long functions
|
|
117
|
+
const functions = detectFunctions(code);
|
|
118
|
+
for (const fn of functions) {
|
|
119
|
+
const fnLines = fn.body.split('\n').length;
|
|
120
|
+
if (fnLines > 50) {
|
|
121
|
+
findings.push({
|
|
122
|
+
severity: 'medium',
|
|
123
|
+
category: 'Complexity',
|
|
124
|
+
description: `Function '${fn.name}' is ${fnLines} lines long (limit: 50).`,
|
|
125
|
+
fix: `Extract logical blocks into named helper functions. Aim for functions that do one thing and fit on one screen.`,
|
|
126
|
+
location: `Line ${fn.start}`,
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
// 2. Deep nesting
|
|
131
|
+
const nestingDepth = maxNestingDepth(code);
|
|
132
|
+
if (nestingDepth > 5) {
|
|
133
|
+
findings.push({
|
|
134
|
+
severity: 'medium',
|
|
135
|
+
category: 'Complexity',
|
|
136
|
+
description: `Maximum brace nesting depth is ${nestingDepth} (limit: 5). Deep nesting makes code hard to reason about.`,
|
|
137
|
+
fix: 'Apply guard clauses (early returns), extract inner blocks to functions, or flatten with Promise chains.',
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
// 3. Missing error handling — try without catch, or bare promise .then without .catch
|
|
141
|
+
const tryCatchBalance = (code.match(/\btry\b/g) || []).length;
|
|
142
|
+
const catchBalance = (code.match(/\bcatch\b/g) || []).length;
|
|
143
|
+
if (tryCatchBalance > catchBalance) {
|
|
144
|
+
findings.push({
|
|
145
|
+
severity: 'high',
|
|
146
|
+
category: 'Error Handling',
|
|
147
|
+
description: `Found ${tryCatchBalance} try block(s) but only ${catchBalance} catch block(s). Unmatched try blocks may silently swallow errors.`,
|
|
148
|
+
fix: 'Ensure every try has a corresponding catch. Log the error and either rethrow or return a typed error result.',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
// 4. Unhandled promise (.then without .catch)
|
|
152
|
+
lines.forEach((line, idx) => {
|
|
153
|
+
if (/\.then\s*\(/.test(line) && !/\.catch\s*\(/.test(line)) {
|
|
154
|
+
// Check next few lines for .catch
|
|
155
|
+
const window = lines.slice(idx, idx + 5).join(' ');
|
|
156
|
+
if (!/\.catch\s*\(/.test(window)) {
|
|
157
|
+
findings.push({
|
|
158
|
+
severity: 'high',
|
|
159
|
+
category: 'Error Handling',
|
|
160
|
+
description: `Promise .then() at line ${idx + 1} has no visible .catch() — unhandled rejection risk.`,
|
|
161
|
+
fix: 'Add .catch(err => { ... }) or convert to async/await with try/catch.',
|
|
162
|
+
location: `Line ${idx + 1}`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
});
|
|
167
|
+
// 5. Magic numbers
|
|
168
|
+
lines.forEach((line, idx) => {
|
|
169
|
+
// Skip comments and import lines
|
|
170
|
+
if (/^\s*(\/\/|\/\*|\*|import|export)/.test(line))
|
|
171
|
+
return;
|
|
172
|
+
// Match standalone numeric literals that aren't 0 or 1
|
|
173
|
+
const magicMatches = line.match(/(?<![.\w])(?:[2-9]\d*|\d{2,})(?!\w)/g);
|
|
174
|
+
if (magicMatches) {
|
|
175
|
+
findings.push({
|
|
176
|
+
severity: 'low',
|
|
177
|
+
category: 'Maintainability',
|
|
178
|
+
description: `Magic number(s) [${magicMatches.join(', ')}] at line ${idx + 1}. Bare literals obscure intent.`,
|
|
179
|
+
fix: 'Extract to a named constant: const MAX_RETRIES = 3; at the top of the file or in a constants module.',
|
|
180
|
+
location: `Line ${idx + 1}`,
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
});
|
|
184
|
+
// 6. TODO/FIXME without issue reference
|
|
185
|
+
lines.forEach((line, idx) => {
|
|
186
|
+
if (/\/\/.*\b(TODO|FIXME|HACK|XXX)\b/.test(line) && !/\b(#\d+|https?:\/\/|JIRA|GH-|issue)/i.test(line)) {
|
|
187
|
+
findings.push({
|
|
188
|
+
severity: 'low',
|
|
189
|
+
category: 'Technical Debt',
|
|
190
|
+
description: `Untracked TODO/FIXME at line ${idx + 1}: "${line.trim()}"`,
|
|
191
|
+
fix: 'Link to a tracking issue: // TODO(#123): fix this.',
|
|
192
|
+
location: `Line ${idx + 1}`,
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
});
|
|
196
|
+
// 7. Unused variable patterns (_var that is actually used, or var that starts with _ but is referenced)
|
|
197
|
+
lines.forEach((line, idx) => {
|
|
198
|
+
if (/const\s+_\w+\s*=/.test(line) || /let\s+_\w+\s*=/.test(line)) {
|
|
199
|
+
const varMatch = line.match(/(?:const|let)\s+(_\w+)/);
|
|
200
|
+
if (varMatch) {
|
|
201
|
+
const varName = varMatch[1];
|
|
202
|
+
const usedElsewhere = code.split('\n').filter((_, i) => i !== idx).some(l => l.includes(varName));
|
|
203
|
+
if (usedElsewhere) {
|
|
204
|
+
findings.push({
|
|
205
|
+
severity: 'info',
|
|
206
|
+
category: 'Naming',
|
|
207
|
+
description: `Variable '${varName}' starts with underscore (convention: unused) but is referenced elsewhere in the code.`,
|
|
208
|
+
fix: `Rename '${varName}' to '${varName.slice(1)}' since it is actively used.`,
|
|
209
|
+
location: `Line ${idx + 1}`,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
// 8. Consistent naming — detect mixed camelCase / snake_case for variables
|
|
216
|
+
const camelVars = (code.match(/\b(?:const|let|var)\s+([a-z][a-zA-Z0-9]*[A-Z][a-zA-Z0-9]*)\b/g) || []).length;
|
|
217
|
+
const snakeVars = (code.match(/\b(?:const|let|var)\s+([a-z][a-z0-9]*_[a-z][a-z0-9]*)\b/g) || []).length;
|
|
218
|
+
if (camelVars > 0 && snakeVars > 0) {
|
|
219
|
+
findings.push({
|
|
220
|
+
severity: 'low',
|
|
221
|
+
category: 'Naming',
|
|
222
|
+
description: `Mixed naming convention: ${camelVars} camelCase and ${snakeVars} snake_case variable declarations detected.`,
|
|
223
|
+
fix: 'Standardise on camelCase for variables and functions in TypeScript/JavaScript codebases.',
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
// ─── Score ────────────────────────────────────────────────────────────────
|
|
227
|
+
let score = 100;
|
|
228
|
+
const critical_count = findings.filter(f => f.severity === 'critical').length;
|
|
229
|
+
const high_count = findings.filter(f => f.severity === 'high').length;
|
|
230
|
+
const medium_count = findings.filter(f => f.severity === 'medium').length;
|
|
231
|
+
const low_count = findings.filter(f => f.severity === 'low').length;
|
|
232
|
+
score -= critical_count * 25;
|
|
233
|
+
score -= high_count * 15;
|
|
234
|
+
score -= medium_count * 8;
|
|
235
|
+
score -= low_count * 3;
|
|
236
|
+
score = Math.max(0, Math.min(100, score));
|
|
237
|
+
let verdict;
|
|
238
|
+
if (critical_count > 0)
|
|
239
|
+
verdict = 'rejected';
|
|
240
|
+
else if (high_count > 0)
|
|
241
|
+
verdict = 'needs_revision';
|
|
242
|
+
else if (medium_count > 0 || low_count > 2)
|
|
243
|
+
verdict = 'approved_with_warnings';
|
|
244
|
+
else
|
|
245
|
+
verdict = 'approved';
|
|
246
|
+
const summary = findings.length === 0
|
|
247
|
+
? 'Code looks clean — no significant issues detected.'
|
|
248
|
+
: `Found ${findings.length} issue(s): ${critical_count} critical, ${high_count} high, ${medium_count} medium, ${low_count} low. Score: ${score}/100.`;
|
|
249
|
+
return {
|
|
250
|
+
agent: 'reviewer',
|
|
251
|
+
subject,
|
|
252
|
+
findings,
|
|
253
|
+
score,
|
|
254
|
+
verdict,
|
|
255
|
+
summary,
|
|
256
|
+
critical_count,
|
|
257
|
+
high_count,
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=reviewer.js.map
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
function detectTestType(task, context) {
|
|
2
|
+
const combined = (task + ' ' + (context ?? '')).toLowerCase();
|
|
3
|
+
if (combined.includes('e2e') || combined.includes('end-to-end') || combined.includes('playwright') || combined.includes('cypress') || combined.includes('browser'))
|
|
4
|
+
return 'e2e';
|
|
5
|
+
if (combined.includes('integration') || combined.includes('database') || combined.includes('api') || combined.includes('endpoint') || combined.includes('http'))
|
|
6
|
+
return 'integration';
|
|
7
|
+
return 'unit';
|
|
8
|
+
}
|
|
9
|
+
const typeApproach = {
|
|
10
|
+
unit: 'Isolate the unit under test by mocking all dependencies. Cover happy path, error paths, boundary conditions, and type edge cases. Aim for 100% branch coverage on business logic.',
|
|
11
|
+
integration: 'Test the interaction between real components (DB, HTTP, filesystem). Use test containers or in-memory alternatives. Verify contracts and side effects, not just return values.',
|
|
12
|
+
e2e: 'Test user journeys from browser to backend. Run against a staging environment or local stack. Focus on critical paths — registration, login, core workflows. Avoid testing every permutation.',
|
|
13
|
+
};
|
|
14
|
+
const typeSteps = {
|
|
15
|
+
unit: [
|
|
16
|
+
'Identify the public interface of the unit under test',
|
|
17
|
+
'List all logical branches (if/else, switch, try/catch, null checks)',
|
|
18
|
+
'Create a test file co-located with the source file (*.test.ts)',
|
|
19
|
+
'Import the unit and mock all external dependencies at the top',
|
|
20
|
+
'Write the happy-path test first to establish baseline behaviour',
|
|
21
|
+
'Write a test for each error or exception path',
|
|
22
|
+
'Add boundary condition tests (empty array, zero, max value, null, undefined)',
|
|
23
|
+
'Add a test for each async path (resolved and rejected)',
|
|
24
|
+
'Verify mocks were called with the correct arguments',
|
|
25
|
+
'Run coverage report and fill gaps — target 90%+ branch coverage',
|
|
26
|
+
'Review test names — each should describe behaviour, not implementation',
|
|
27
|
+
'Run tests in watch mode and confirm they are deterministic across runs',
|
|
28
|
+
],
|
|
29
|
+
integration: [
|
|
30
|
+
'Identify the integration boundary (DB, HTTP, message queue, filesystem)',
|
|
31
|
+
'Set up a test database or mock server that resets between tests',
|
|
32
|
+
'Write fixtures / seed data helpers',
|
|
33
|
+
'Test the full request-response cycle for each endpoint/operation',
|
|
34
|
+
'Verify response body schema and HTTP status codes',
|
|
35
|
+
'Verify database state after mutations',
|
|
36
|
+
'Test authentication and authorisation (valid token, expired token, wrong role)',
|
|
37
|
+
'Test concurrent requests do not corrupt shared state',
|
|
38
|
+
'Test rollback on partial failure (transaction integrity)',
|
|
39
|
+
'Clean up all test data in afterEach/afterAll hooks',
|
|
40
|
+
'Run tests against the CI database, not a developer\'s local DB',
|
|
41
|
+
'Assert on error response shape, not just status code',
|
|
42
|
+
],
|
|
43
|
+
e2e: [
|
|
44
|
+
'Map the user journeys to test (registration, login, core workflow)',
|
|
45
|
+
'Set up a local or staging stack with predictable seed data',
|
|
46
|
+
'Write page object models (POMs) for each major screen',
|
|
47
|
+
'Implement the happy-path journey test first',
|
|
48
|
+
'Add negative journey tests (invalid login, blocked access)',
|
|
49
|
+
'Test form validation messages appear and are readable',
|
|
50
|
+
'Verify redirect behaviour after actions (post-login, post-submit)',
|
|
51
|
+
'Test on at least two viewport sizes (mobile and desktop)',
|
|
52
|
+
'Add accessibility checks (axe-core or Playwright a11y plugin)',
|
|
53
|
+
'Assert on URL changes to ensure navigation works',
|
|
54
|
+
'Run in headless mode in CI; headed mode for debugging',
|
|
55
|
+
'Keep each test independent — never rely on state from a previous test',
|
|
56
|
+
],
|
|
57
|
+
};
|
|
58
|
+
const typeChecklist = {
|
|
59
|
+
unit: [
|
|
60
|
+
'[ ] Every public function has at least one test',
|
|
61
|
+
'[ ] Every branch of a conditional is exercised',
|
|
62
|
+
'[ ] Error throw / rejection is tested explicitly',
|
|
63
|
+
'[ ] Mocks are reset between tests (beforeEach)',
|
|
64
|
+
'[ ] No test depends on another test\'s side effects',
|
|
65
|
+
'[ ] Test names use "should <behaviour> when <condition>" format',
|
|
66
|
+
'[ ] No production code altered to make tests pass (unless it improves design)',
|
|
67
|
+
'[ ] Tests run in under 5 seconds total',
|
|
68
|
+
'[ ] Coverage threshold enforced in jest/vitest config',
|
|
69
|
+
'[ ] Snapshot tests (if used) are committed and reviewed',
|
|
70
|
+
],
|
|
71
|
+
integration: [
|
|
72
|
+
'[ ] Test database is isolated from development database',
|
|
73
|
+
'[ ] Seed data is deterministic and version-controlled',
|
|
74
|
+
'[ ] All test data cleaned up after each test',
|
|
75
|
+
'[ ] Auth tokens generated fresh per test',
|
|
76
|
+
'[ ] Response schema validated against TypeScript types',
|
|
77
|
+
'[ ] Error response shape tested, not just status code',
|
|
78
|
+
'[ ] Transactions roll back correctly on failure',
|
|
79
|
+
'[ ] No hardcoded ports — use dynamic port allocation',
|
|
80
|
+
'[ ] CI pipeline runs integration tests in a Docker environment',
|
|
81
|
+
'[ ] Tests are tagged so unit and integration can run separately',
|
|
82
|
+
],
|
|
83
|
+
e2e: [
|
|
84
|
+
'[ ] Page object models used — no raw selectors in test bodies',
|
|
85
|
+
'[ ] data-testid attributes used for element selection (not CSS classes)',
|
|
86
|
+
'[ ] Each test is fully independent (own seed data)',
|
|
87
|
+
'[ ] Tests run in headless mode in CI',
|
|
88
|
+
'[ ] Mobile and desktop viewports both tested',
|
|
89
|
+
'[ ] Accessibility check passes on each major screen',
|
|
90
|
+
'[ ] Network errors are simulated for critical flows',
|
|
91
|
+
'[ ] Screenshots taken on failure for debugging',
|
|
92
|
+
'[ ] Test retries configured (max 2) to handle flakiness',
|
|
93
|
+
'[ ] Critical path coverage maps to product requirements',
|
|
94
|
+
],
|
|
95
|
+
};
|
|
96
|
+
const typePitfalls = {
|
|
97
|
+
unit: [
|
|
98
|
+
'Testing implementation details (private methods, internal state) — test behaviour, not internals',
|
|
99
|
+
'Mocking the module under test — only mock its dependencies',
|
|
100
|
+
'Asserting on mock call count without asserting on arguments',
|
|
101
|
+
'Writing tests after the fact without TDD discipline — causes incomplete coverage',
|
|
102
|
+
'Using Math.random() or Date.now() in tests without mocking — non-deterministic results',
|
|
103
|
+
],
|
|
104
|
+
integration: [
|
|
105
|
+
'Running integration tests against shared databases — causes test pollution between developers',
|
|
106
|
+
'Forgetting to rollback DB transactions — leaves dirty state that breaks subsequent tests',
|
|
107
|
+
'Hardcoding localhost ports — causes CI failures when ports are in use',
|
|
108
|
+
'Not testing the unhappy auth paths — security gap',
|
|
109
|
+
'Asserting only on status codes, not response body — misses contract violations',
|
|
110
|
+
],
|
|
111
|
+
e2e: [
|
|
112
|
+
'Using CSS class selectors — they change on style refactors and break tests',
|
|
113
|
+
'Sharing state between tests — one failure cascades to all subsequent tests',
|
|
114
|
+
'Testing every UI permutation — creates a massive suite that nobody maintains',
|
|
115
|
+
'Ignoring flaky tests — they erode trust in the entire suite',
|
|
116
|
+
'Not running e2e on CI — catching bugs only locally defeats the purpose',
|
|
117
|
+
],
|
|
118
|
+
};
|
|
119
|
+
const typePatterns = {
|
|
120
|
+
unit: ['Arrange-Act-Assert', 'Mock object pattern', 'Test data builder', 'Parameterised tests', 'Given-When-Then'],
|
|
121
|
+
integration: ['Test container pattern', 'Database cleaner pattern', 'Fixture factory', 'Contract testing', 'Seeding pattern'],
|
|
122
|
+
e2e: ['Page Object Model', 'Journey test pattern', 'Screenplay pattern', 'Seed-and-clean pattern', 'Visual regression testing'],
|
|
123
|
+
};
|
|
124
|
+
const typeDuration = {
|
|
125
|
+
unit: '1-3 hours',
|
|
126
|
+
integration: '3-6 hours',
|
|
127
|
+
e2e: '4-8 hours',
|
|
128
|
+
};
|
|
129
|
+
export function plan(task, context) {
|
|
130
|
+
const testType = detectTestType(task, context);
|
|
131
|
+
return {
|
|
132
|
+
agent: 'tester',
|
|
133
|
+
task,
|
|
134
|
+
tier: 2,
|
|
135
|
+
approach: typeApproach[testType],
|
|
136
|
+
steps: typeSteps[testType],
|
|
137
|
+
checklist: typeChecklist[testType],
|
|
138
|
+
pitfalls: typePitfalls[testType],
|
|
139
|
+
patterns: typePatterns[testType],
|
|
140
|
+
duration_estimate: typeDuration[testType],
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
//# sourceMappingURL=tester.js.map
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
// Development agents
|
|
2
|
+
import * as coder from './development/coder.js';
|
|
3
|
+
import * as reviewer from './development/reviewer.js';
|
|
4
|
+
import * as tester from './development/tester.js';
|
|
5
|
+
import * as debugger_ from './development/debugger.js';
|
|
6
|
+
import * as refactor from './development/refactor.js';
|
|
7
|
+
import * as database from './development/database.js';
|
|
8
|
+
import * as api from './development/api.js';
|
|
9
|
+
import * as frontend from './development/frontend.js';
|
|
10
|
+
import * as backend from './development/backend.js';
|
|
11
|
+
import * as devops from './development/devops.js';
|
|
12
|
+
import * as performance from './development/performance.js';
|
|
13
|
+
import * as migration from './development/migration.js';
|
|
14
|
+
// Security agents
|
|
15
|
+
import * as securityScanner from './security/scanner.js';
|
|
16
|
+
import * as auth from './security/auth.js';
|
|
17
|
+
import * as privacy from './security/privacy.js';
|
|
18
|
+
import * as secrets from './security/secrets.js';
|
|
19
|
+
import * as dependencyAudit from './security/dependency-audit.js';
|
|
20
|
+
import * as penetration from './security/penetration.js';
|
|
21
|
+
// Memory agents
|
|
22
|
+
import * as contextManager from './memory/context-manager.js';
|
|
23
|
+
import * as decisionLogger from './memory/decision-logger.js';
|
|
24
|
+
import * as projectMapper from './memory/project-mapper.js';
|
|
25
|
+
import * as patternLearner from './memory/pattern-learner.js';
|
|
26
|
+
import * as knowledgeBase from './memory/knowledge-base.js';
|
|
27
|
+
// Research agents
|
|
28
|
+
import * as researcher from './research/researcher.js';
|
|
29
|
+
import * as techAdvisor from './research/tech-advisor.js';
|
|
30
|
+
import * as costAnalyzer from './research/cost-analyzer.js';
|
|
31
|
+
import * as competitorAnalyzer from './research/competitor-analyzer.js';
|
|
32
|
+
import * as riskAssessor from './research/risk-assessor.js';
|
|
33
|
+
import * as estimator from './research/estimator.js';
|
|
34
|
+
import * as ethicsBias from './research/ethics-bias.js';
|
|
35
|
+
// Quality agents
|
|
36
|
+
import * as codeQuality from './quality/code-quality.js';
|
|
37
|
+
import * as documentation from './quality/documentation.js';
|
|
38
|
+
import * as accessibility from './quality/accessibility.js';
|
|
39
|
+
import * as compatibility from './quality/compatibility.js';
|
|
40
|
+
import * as errorHandling from './quality/error-handling.js';
|
|
41
|
+
// Workflow agents
|
|
42
|
+
import * as taskPlanner from './workflow/task-planner.js';
|
|
43
|
+
import * as taskCoordinator from './workflow/task-coordinator.js';
|
|
44
|
+
import * as fileManager from './workflow/file-manager.js';
|
|
45
|
+
import * as gitAgent from './workflow/git-agent.js';
|
|
46
|
+
import * as searchAgent from './workflow/search-agent.js';
|
|
47
|
+
import * as reporter from './workflow/reporter.js';
|
|
48
|
+
import * as automation from './workflow/automation.js';
|
|
49
|
+
// Agents that support analyze()
|
|
50
|
+
const ANALYZE_CAPABLE = new Set([
|
|
51
|
+
'reviewer',
|
|
52
|
+
'security-scanner',
|
|
53
|
+
'secrets',
|
|
54
|
+
'dependency-audit',
|
|
55
|
+
'code-quality',
|
|
56
|
+
'documentation',
|
|
57
|
+
'accessibility',
|
|
58
|
+
'error-handling',
|
|
59
|
+
]);
|
|
60
|
+
function resolveAgent(agentType) {
|
|
61
|
+
switch (agentType) {
|
|
62
|
+
case 'coder': return coder;
|
|
63
|
+
case 'reviewer': return reviewer;
|
|
64
|
+
case 'tester': return tester;
|
|
65
|
+
case 'debugger': return debugger_;
|
|
66
|
+
case 'refactor': return refactor;
|
|
67
|
+
case 'database': return database;
|
|
68
|
+
case 'api': return api;
|
|
69
|
+
case 'frontend': return frontend;
|
|
70
|
+
case 'backend': return backend;
|
|
71
|
+
case 'devops': return devops;
|
|
72
|
+
case 'performance': return performance;
|
|
73
|
+
case 'migration': return migration;
|
|
74
|
+
case 'security-scanner': return securityScanner;
|
|
75
|
+
case 'auth': return auth;
|
|
76
|
+
case 'privacy': return privacy;
|
|
77
|
+
case 'secrets': return secrets;
|
|
78
|
+
case 'dependency-audit': return dependencyAudit;
|
|
79
|
+
case 'penetration': return penetration;
|
|
80
|
+
case 'context-manager': return contextManager;
|
|
81
|
+
case 'decision-logger': return decisionLogger;
|
|
82
|
+
case 'project-mapper': return projectMapper;
|
|
83
|
+
case 'pattern-learner': return patternLearner;
|
|
84
|
+
case 'knowledge-base': return knowledgeBase;
|
|
85
|
+
case 'researcher': return researcher;
|
|
86
|
+
case 'tech-advisor': return techAdvisor;
|
|
87
|
+
case 'cost-analyzer': return costAnalyzer;
|
|
88
|
+
case 'competitor-analyzer': return competitorAnalyzer;
|
|
89
|
+
case 'risk-assessor': return riskAssessor;
|
|
90
|
+
case 'estimator': return estimator;
|
|
91
|
+
case 'ethics-bias': return ethicsBias;
|
|
92
|
+
case 'code-quality': return codeQuality;
|
|
93
|
+
case 'documentation': return documentation;
|
|
94
|
+
case 'accessibility': return accessibility;
|
|
95
|
+
case 'compatibility': return compatibility;
|
|
96
|
+
case 'error-handling': return errorHandling;
|
|
97
|
+
case 'task-planner': return taskPlanner;
|
|
98
|
+
case 'task-coordinator': return taskCoordinator;
|
|
99
|
+
case 'file-manager': return fileManager;
|
|
100
|
+
case 'git-agent': return gitAgent;
|
|
101
|
+
case 'search-agent': return searchAgent;
|
|
102
|
+
case 'reporter': return reporter;
|
|
103
|
+
case 'automation': return automation;
|
|
104
|
+
default:
|
|
105
|
+
throw new Error(`Unknown agent type: ${agentType}`);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export async function executeOne(task) {
|
|
109
|
+
const start = Date.now();
|
|
110
|
+
try {
|
|
111
|
+
const agent = resolveAgent(task.agent);
|
|
112
|
+
const useAnalyze = task.code !== undefined && ANALYZE_CAPABLE.has(task.agent);
|
|
113
|
+
if (useAnalyze && agent.analyze) {
|
|
114
|
+
const analysis = agent.analyze(task.code, task.context);
|
|
115
|
+
return {
|
|
116
|
+
id: task.id,
|
|
117
|
+
agent: task.agent,
|
|
118
|
+
analysis,
|
|
119
|
+
duration_ms: Date.now() - start,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const plan = agent.plan(task.task, task.context);
|
|
124
|
+
return {
|
|
125
|
+
id: task.id,
|
|
126
|
+
agent: task.agent,
|
|
127
|
+
plan,
|
|
128
|
+
duration_ms: Date.now() - start,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
catch (err) {
|
|
133
|
+
return {
|
|
134
|
+
id: task.id,
|
|
135
|
+
agent: task.agent,
|
|
136
|
+
duration_ms: Date.now() - start,
|
|
137
|
+
error: err instanceof Error ? err.message : String(err),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
export async function executeParallel(tasks) {
|
|
142
|
+
return Promise.all(tasks.map(task => executeOne(task)));
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=executor.js.map
|