@jigyasudham/veto 1.4.4 → 2.0.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/AGENTS.md +134 -0
- package/README.md +26 -144
- package/dist/adapters/index.d.ts +3 -2
- package/dist/adapters/index.d.ts.map +1 -1
- package/dist/adapters/index.js +105 -1
- package/dist/adapters/index.js.map +1 -1
- package/dist/agents/executor.d.ts +2 -0
- package/dist/agents/executor.d.ts.map +1 -1
- package/dist/agents/executor.js +50 -3
- package/dist/agents/executor.js.map +1 -1
- package/dist/agents/llm-runner.d.ts +11 -0
- package/dist/agents/llm-runner.d.ts.map +1 -0
- package/dist/agents/llm-runner.js +252 -0
- package/dist/agents/llm-runner.js.map +1 -0
- package/dist/agents/local-llm.d.ts +14 -0
- package/dist/agents/local-llm.d.ts.map +1 -0
- package/dist/agents/local-llm.js +51 -0
- package/dist/agents/local-llm.js.map +1 -0
- package/dist/agents/manifest.d.ts +13 -0
- package/dist/agents/manifest.d.ts.map +1 -0
- package/dist/agents/manifest.js +55 -0
- package/dist/agents/manifest.js.map +1 -0
- package/dist/agents/quality/clone-detector.d.ts +16 -0
- package/dist/agents/quality/clone-detector.d.ts.map +1 -0
- package/dist/agents/quality/clone-detector.js +72 -0
- package/dist/agents/quality/clone-detector.js.map +1 -0
- package/dist/agents/types.d.ts +15 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validate.d.ts +11 -0
- package/dist/agents/validate.d.ts.map +1 -0
- package/dist/agents/validate.js +54 -0
- package/dist/agents/validate.js.map +1 -0
- package/dist/cli.js +331 -21
- package/dist/cli.js.map +1 -1
- package/dist/council/llm-council.d.ts.map +1 -1
- package/dist/council/llm-council.js +10 -9
- package/dist/council/llm-council.js.map +1 -1
- package/dist/council/types.d.ts +2 -0
- package/dist/council/types.d.ts.map +1 -1
- package/dist/memory/local.d.ts +12 -1
- package/dist/memory/local.d.ts.map +1 -1
- package/dist/memory/local.js +56 -2
- package/dist/memory/local.js.map +1 -1
- package/dist/memory/schema.d.ts +28 -43
- package/dist/memory/schema.d.ts.map +1 -1
- package/dist/memory/schema.js +31 -0
- package/dist/memory/schema.js.map +1 -1
- package/dist/memory/sync.d.ts +13 -0
- package/dist/memory/sync.d.ts.map +1 -1
- package/dist/memory/sync.js +113 -0
- package/dist/memory/sync.js.map +1 -1
- package/dist/repo-map/ignore.d.ts +8 -0
- package/dist/repo-map/ignore.d.ts.map +1 -0
- package/dist/repo-map/ignore.js +65 -0
- package/dist/repo-map/ignore.js.map +1 -0
- package/dist/repo-map/index.d.ts +29 -0
- package/dist/repo-map/index.d.ts.map +1 -0
- package/dist/repo-map/index.js +240 -0
- package/dist/repo-map/index.js.map +1 -0
- package/dist/router/context-compressor.d.ts +1 -1
- package/dist/router/context-compressor.d.ts.map +1 -1
- package/dist/router/context-compressor.js +9 -3
- package/dist/router/context-compressor.js.map +1 -1
- package/dist/router/index.d.ts +8 -3
- package/dist/router/index.d.ts.map +1 -1
- package/dist/router/index.js +20 -4
- package/dist/router/index.js.map +1 -1
- package/dist/router/learning-updater.d.ts +41 -0
- package/dist/router/learning-updater.d.ts.map +1 -1
- package/dist/router/learning-updater.js +62 -0
- package/dist/router/learning-updater.js.map +1 -1
- package/dist/router/model-selector.d.ts +4 -1
- package/dist/router/model-selector.d.ts.map +1 -1
- package/dist/router/model-selector.js +24 -28
- package/dist/router/model-selector.js.map +1 -1
- package/dist/server.js +3121 -1655
- package/dist/server.js.map +1 -1
- package/dist/tools/definitions.d.ts +1205 -171
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +678 -4
- package/dist/tools/definitions.js.map +1 -1
- package/dist/watcher/index.d.ts +1 -0
- package/dist/watcher/index.d.ts.map +1 -1
- package/dist/watcher/index.js +7 -6
- package/dist/watcher/index.js.map +1 -1
- package/dist/workflow/pipeline.d.ts +12 -2
- package/dist/workflow/pipeline.d.ts.map +1 -1
- package/dist/workflow/pipeline.js +395 -16
- package/dist/workflow/pipeline.js.map +1 -1
- package/p7.ts +6 -0
- package/package.json +8 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB,OAAO,GAAG,UAAU,GAAG,QAAQ,GAAG,UAAU,GAAG,UAAU,GACzD,UAAU,GAAG,KAAK,GAAG,UAAU,GAAG,SAAS,GAAG,QAAQ,GACtD,aAAa,GAAG,WAAW,GAC3B,kBAAkB,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GACnD,kBAAkB,GAAG,aAAa,GAClC,iBAAiB,GAAG,iBAAiB,GAAG,gBAAgB,GACxD,iBAAiB,GAAG,gBAAgB,GACpC,YAAY,GAAG,cAAc,GAAG,eAAe,GAC/C,qBAAqB,GAAG,eAAe,GAAG,WAAW,GACrD,aAAa,GACb,cAAc,GAAG,eAAe,GAAG,eAAe,GAAG,eAAe,GAAG,gBAAgB,GACvF,cAAc,GAAG,kBAAkB,GAAG,cAAc,GAAG,WAAW,GAClE,cAAc,GAAG,UAAU,GAAG,YAAY,CAAC;AAE/C,MAAM,MAAM,eAAe,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,GAAG,MAAM,CAAC;AAE9E,MAAM,WAAW,YAAY;IAC3B,QAAQ,EAAE,eAAe,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,iBAAiB,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,eAAe,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,UAAU,GAAG,wBAAwB,GAAG,gBAAgB,GAAG,UAAU,CAAC;IAC/E,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,OAAO;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,eAAe,CAAC;IAC1B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,SAAS,EAAE,OAAO,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,SAAS;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,eAAe,CAAC;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/agents/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { AgentPlan, AgentAnalysis, WorkerAgentType } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Validates and sanitizes an AgentPlan. Returns null if the value is not
|
|
4
|
+
* recoverable. Otherwise returns a clean plan using Zod.
|
|
5
|
+
*/
|
|
6
|
+
export declare function validateAgentPlan(raw: unknown, agentType: WorkerAgentType): AgentPlan | null;
|
|
7
|
+
/**
|
|
8
|
+
* Validates and sanitizes an AgentAnalysis. Returns null if not recoverable.
|
|
9
|
+
*/
|
|
10
|
+
export declare function validateAgentAnalysis(raw: unknown, agentType: WorkerAgentType): AgentAnalysis | null;
|
|
11
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../../src/agents/validate.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAiC,eAAe,EAAE,MAAM,YAAY,CAAC;AAmC3G;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAI5F;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,GAAG,aAAa,GAAG,IAAI,CAOpG"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
const findingSchema = z.object({
|
|
3
|
+
severity: z.enum(['critical', 'high', 'medium', 'low', 'info']).default('info').catch('info'),
|
|
4
|
+
category: z.string().default('general').catch('general'),
|
|
5
|
+
description: z.string().default('No description').catch('No description'),
|
|
6
|
+
fix: z.string().default('No fix provided').catch('No fix provided'),
|
|
7
|
+
location: z.string().optional().catch(undefined),
|
|
8
|
+
cwe: z.string().optional().catch(undefined),
|
|
9
|
+
owasp: z.string().optional().catch(undefined)
|
|
10
|
+
});
|
|
11
|
+
const planSchema = z.object({
|
|
12
|
+
agent: z.string().catch(''),
|
|
13
|
+
task: z.string().catch(''),
|
|
14
|
+
tier: z.union([z.literal(1), z.literal(2), z.literal(3)]).default(2).catch(2),
|
|
15
|
+
approach: z.string().default('').catch(''),
|
|
16
|
+
steps: z.array(z.string()).default([]).catch([]),
|
|
17
|
+
checklist: z.array(z.string()).default([]).catch([]),
|
|
18
|
+
pitfalls: z.array(z.string()).default([]).catch([]),
|
|
19
|
+
patterns: z.array(z.string()).default([]).catch([]),
|
|
20
|
+
duration_estimate: z.string().default('unknown').catch('unknown')
|
|
21
|
+
});
|
|
22
|
+
const analysisSchema = z.object({
|
|
23
|
+
agent: z.string().catch(''),
|
|
24
|
+
subject: z.string().default('').catch(''),
|
|
25
|
+
findings: z.array(findingSchema).default([]).catch([]),
|
|
26
|
+
score: z.number().min(0).max(100).default(70).catch(70),
|
|
27
|
+
verdict: z.enum(['approved', 'approved_with_warnings', 'needs_revision', 'rejected']).default('approved_with_warnings').catch('approved_with_warnings'),
|
|
28
|
+
summary: z.string().default('').catch(''),
|
|
29
|
+
critical_count: z.number().optional().catch(undefined),
|
|
30
|
+
high_count: z.number().optional().catch(undefined)
|
|
31
|
+
});
|
|
32
|
+
/**
|
|
33
|
+
* Validates and sanitizes an AgentPlan. Returns null if the value is not
|
|
34
|
+
* recoverable. Otherwise returns a clean plan using Zod.
|
|
35
|
+
*/
|
|
36
|
+
export function validateAgentPlan(raw, agentType) {
|
|
37
|
+
const parsed = planSchema.safeParse(raw);
|
|
38
|
+
if (!parsed.success)
|
|
39
|
+
return null;
|
|
40
|
+
return { ...parsed.data, agent: agentType };
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Validates and sanitizes an AgentAnalysis. Returns null if not recoverable.
|
|
44
|
+
*/
|
|
45
|
+
export function validateAgentAnalysis(raw, agentType) {
|
|
46
|
+
const parsed = analysisSchema.safeParse(raw);
|
|
47
|
+
if (!parsed.success)
|
|
48
|
+
return null;
|
|
49
|
+
const data = parsed.data;
|
|
50
|
+
const critical_count = data.critical_count ?? data.findings.filter(f => f.severity === 'critical').length;
|
|
51
|
+
const high_count = data.high_count ?? data.findings.filter(f => f.severity === 'high').length;
|
|
52
|
+
return { ...data, agent: agentType, critical_count, high_count };
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=validate.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.js","sourceRoot":"","sources":["../../src/agents/validate.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.js
CHANGED
|
@@ -162,8 +162,21 @@ async function initCommand() {
|
|
|
162
162
|
console.error(c.red(` Error initializing database: ${msg}`));
|
|
163
163
|
process.exit(1);
|
|
164
164
|
}
|
|
165
|
-
// 3. Auto-
|
|
165
|
+
// 3. Auto-import VETO_MEMORY.md if present in cwd
|
|
166
166
|
const cwd = resolve(process.cwd());
|
|
167
|
+
const vetoMemoryPath = join(cwd, 'VETO_MEMORY.md');
|
|
168
|
+
if (existsSync(vetoMemoryPath)) {
|
|
169
|
+
process.stdout.write(' · Importing VETO_MEMORY.md...');
|
|
170
|
+
try {
|
|
171
|
+
const { importMemoryMarkdown } = await import('./memory/sync.js');
|
|
172
|
+
const importResult = importMemoryMarkdown(vetoMemoryPath);
|
|
173
|
+
console.log(c.green(' ✓') + ` ${importResult.imported} knowledge entries imported`);
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
console.log(c.dim(' skipped'));
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
// 4. Auto-scan current project and store project map
|
|
167
180
|
const { updateProjectMap } = await import('./memory/local.js');
|
|
168
181
|
const { discoverProject } = await import('./discover.js');
|
|
169
182
|
try {
|
|
@@ -282,6 +295,171 @@ async function initCommand() {
|
|
|
282
295
|
}
|
|
283
296
|
}
|
|
284
297
|
console.log('');
|
|
298
|
+
// 5. Write platform-specific context guidance files
|
|
299
|
+
// These are read at session start by each AI client — zero tool calls needed.
|
|
300
|
+
console.log(' Writing context guidance files...');
|
|
301
|
+
console.log('');
|
|
302
|
+
const VETO_GUIDE = `# Veto MCP Server
|
|
303
|
+
|
|
304
|
+
Veto is active. 49 tools across 5 categories:
|
|
305
|
+
|
|
306
|
+
**Session & Context** — veto_status · veto_session_save · veto_continue · veto_handoff
|
|
307
|
+
Save work at 60–70% context capacity. veto_status triggers auto-save above 70%.
|
|
308
|
+
|
|
309
|
+
**Code Intelligence** — veto_diff_review · veto_code_review · veto_security_scan · veto_secrets_scan · veto_ci_gate
|
|
310
|
+
Run veto_diff_review before any merge — it runs all three scans in parallel.
|
|
311
|
+
|
|
312
|
+
**Council & Routing** — veto_council_debate · veto_route_task · veto_execute_parallel
|
|
313
|
+
Council = 7 specialist agents (Lead Dev, PM, Architect, UX, Devil's Advocate, Legal, Security).
|
|
314
|
+
Verdicts: GREEN (proceed) · YELLOW (warnings) · RED (blocked) · DEADLOCK (human decision needed).
|
|
315
|
+
Two-phase LLM-backed flow: call with { task } → get debate_prompt → reason as all 7 agents → call again with { task, agent_responses }.
|
|
316
|
+
|
|
317
|
+
**Memory & Discovery** — veto_discover · veto_summarize · veto_memory_store · veto_memory_search
|
|
318
|
+
Run veto_discover on any unfamiliar repo before touching files.
|
|
319
|
+
|
|
320
|
+
**Observability** — veto_usage_status · veto_health · veto_audit_log · veto_learning_stats
|
|
321
|
+
|
|
322
|
+
Recommended start sequence:
|
|
323
|
+
1. veto_status — confirm running
|
|
324
|
+
2. veto_discover — map the project
|
|
325
|
+
3. veto_route_task — pick the right agent
|
|
326
|
+
4. veto_diff_review — validate before shipping
|
|
327
|
+
5. veto_session_save — checkpoint before context fills
|
|
328
|
+
`;
|
|
329
|
+
let ctxWritten = 0;
|
|
330
|
+
// Gemini CLI: ~/.gemini/GEMINI.md
|
|
331
|
+
const geminiDir = join(HOME, '.gemini');
|
|
332
|
+
if (existsSync(geminiDir)) {
|
|
333
|
+
try {
|
|
334
|
+
writeFileSync(join(geminiDir, 'GEMINI.md'), VETO_GUIDE, 'utf8');
|
|
335
|
+
console.log(c.green(' ✓ ') + 'Gemini CLI — wrote ~/.gemini/GEMINI.md');
|
|
336
|
+
ctxWritten++;
|
|
337
|
+
}
|
|
338
|
+
catch {
|
|
339
|
+
console.log(c.yellow(' ⚠ ') + 'Gemini CLI — could not write GEMINI.md (permission denied?)');
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
// Codex CLI: project AGENTS.md + global ~/.codex/AGENTS.override.md
|
|
343
|
+
const codexDir2 = join(HOME, '.codex');
|
|
344
|
+
if (existsSync(codexDir2)) {
|
|
345
|
+
// Project-level: only write if not already present (user may have customized it)
|
|
346
|
+
const projectAgents = join(cwd, 'AGENTS.md');
|
|
347
|
+
if (!existsSync(projectAgents)) {
|
|
348
|
+
try {
|
|
349
|
+
writeFileSync(projectAgents, VETO_GUIDE, 'utf8');
|
|
350
|
+
console.log(c.green(' ✓ ') + `Codex CLI — wrote AGENTS.md in ${cwd}`);
|
|
351
|
+
ctxWritten++;
|
|
352
|
+
}
|
|
353
|
+
catch {
|
|
354
|
+
console.log(c.yellow(' ⚠ ') + 'Codex CLI — could not write AGENTS.md');
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
else {
|
|
358
|
+
console.log(c.dim(' · ') + c.dim('Codex CLI — AGENTS.md already exists, skipping'));
|
|
359
|
+
}
|
|
360
|
+
// Global override
|
|
361
|
+
try {
|
|
362
|
+
writeFileSync(join(codexDir2, 'AGENTS.override.md'), VETO_GUIDE, 'utf8');
|
|
363
|
+
console.log(c.green(' ✓ ') + 'Codex CLI — wrote ~/.codex/AGENTS.override.md');
|
|
364
|
+
ctxWritten++;
|
|
365
|
+
}
|
|
366
|
+
catch {
|
|
367
|
+
console.log(c.yellow(' ⚠ ') + 'Codex CLI — could not write AGENTS.override.md');
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
// Windsurf: ~/.codeium/windsurf/rules/veto.md
|
|
371
|
+
const windsurfRulesDir = join(HOME, '.codeium', 'windsurf', 'rules');
|
|
372
|
+
if (existsSync(join(HOME, '.codeium', 'windsurf'))) {
|
|
373
|
+
try {
|
|
374
|
+
mkdirSync(windsurfRulesDir, { recursive: true });
|
|
375
|
+
writeFileSync(join(windsurfRulesDir, 'veto.md'), VETO_GUIDE, 'utf8');
|
|
376
|
+
console.log(c.green(' ✓ ') + 'Windsurf — wrote ~/.codeium/windsurf/rules/veto.md');
|
|
377
|
+
ctxWritten++;
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
console.log(c.yellow(' ⚠ ') + 'Windsurf — could not write rules/veto.md');
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
if (ctxWritten > 0)
|
|
384
|
+
console.log('');
|
|
385
|
+
// 6. Write Claude Code hook templates to .claude/hooks/ in current project
|
|
386
|
+
// Hooks enforce secrets scanning on every file write and auto-save before compaction.
|
|
387
|
+
if (existsSync(claudeDir)) {
|
|
388
|
+
const hooksDir = join(cwd, '.claude', 'hooks');
|
|
389
|
+
const settingsPath = join(cwd, '.claude', 'settings.json');
|
|
390
|
+
try {
|
|
391
|
+
mkdirSync(hooksDir, { recursive: true });
|
|
392
|
+
// Secrets scan — bash (Mac/Linux)
|
|
393
|
+
const shLines = [
|
|
394
|
+
'#!/usr/bin/env bash',
|
|
395
|
+
'# Veto hook: scan written files for exposed secrets (no API key needed).',
|
|
396
|
+
'# Triggered by Claude Code PostToolUse after Write/Edit tool calls.',
|
|
397
|
+
'FILE="$1"',
|
|
398
|
+
'[ -z "$FILE" ] && exit 0',
|
|
399
|
+
'[ ! -f "$FILE" ] && exit 0',
|
|
400
|
+
"PATTERNS='(api[_-]?key|secret[_-]?key|password|passwd|token|access[_-]?key|private[_-]?key)\\s*[=:]\\s*[A-Za-z0-9+/]{20,}'",
|
|
401
|
+
'if grep -qiE "$PATTERNS" "$FILE" 2>/dev/null; then',
|
|
402
|
+
' echo "Veto: possible secret detected in $FILE — run veto_secrets_scan to confirm"',
|
|
403
|
+
' exit 1',
|
|
404
|
+
'fi',
|
|
405
|
+
'exit 0',
|
|
406
|
+
'',
|
|
407
|
+
];
|
|
408
|
+
writeFileSync(join(hooksDir, 'veto-secrets-scan.sh'), shLines.join('\n'), 'utf8');
|
|
409
|
+
// Secrets scan — PowerShell (Windows)
|
|
410
|
+
const ps1Lines = [
|
|
411
|
+
'# Veto hook: scan written files for exposed secrets (no API key needed).',
|
|
412
|
+
'param([string]$File)',
|
|
413
|
+
'if (-not $File -or -not (Test-Path $File)) { exit 0 }',
|
|
414
|
+
"$pattern = '(api[_-]?key|secret[_-]?key|password|passwd|token|access[_-]?key|private[_-]?key)\\s*[=:]\\s*[A-Za-z0-9+/]{20,}'",
|
|
415
|
+
'if (Select-String -Path $File -Pattern $pattern -Quiet -CaseSensitive:$false) {',
|
|
416
|
+
' Write-Host "Veto: possible secret detected in $File — run veto_secrets_scan to confirm"',
|
|
417
|
+
' exit 1',
|
|
418
|
+
'}',
|
|
419
|
+
'exit 0',
|
|
420
|
+
'',
|
|
421
|
+
];
|
|
422
|
+
writeFileSync(join(hooksDir, 'veto-secrets-scan.ps1'), ps1Lines.join('\n'), 'utf8');
|
|
423
|
+
// Phase 1.4: Write standard hook files that Claude Code looks for
|
|
424
|
+
const postFileWrite = process.platform === 'win32'
|
|
425
|
+
? `@powershell -NoProfile -ExecutionPolicy Bypass -File ".claude\\hooks\\veto-secrets-scan.ps1" "%1"`
|
|
426
|
+
: `#!/bin/sh\n./.claude/hooks/veto-secrets-scan.sh "$1"`;
|
|
427
|
+
const preCompact = process.platform === 'win32'
|
|
428
|
+
? `@npx -y @jigyasudham/veto veto_session_save --auto_summarize=true`
|
|
429
|
+
: `#!/bin/sh\nnpx -y @jigyasudham/veto veto_session_save --auto_summarize=true`;
|
|
430
|
+
writeFileSync(join(hooksDir, 'post-file-write'), postFileWrite, { mode: 0o755 });
|
|
431
|
+
writeFileSync(join(hooksDir, 'pre-compact'), preCompact, { mode: 0o755 });
|
|
432
|
+
// Wire hooks into .claude/settings.json if it exists or create it
|
|
433
|
+
let projectSettings = {};
|
|
434
|
+
if (existsSync(settingsPath)) {
|
|
435
|
+
try {
|
|
436
|
+
projectSettings = JSON.parse(readFileSync(settingsPath, 'utf8'));
|
|
437
|
+
}
|
|
438
|
+
catch { /* leave empty */ }
|
|
439
|
+
}
|
|
440
|
+
else {
|
|
441
|
+
mkdirSync(dirname(settingsPath), { recursive: true });
|
|
442
|
+
}
|
|
443
|
+
const hooks = projectSettings.hooks ?? {};
|
|
444
|
+
// Only add if not already configured
|
|
445
|
+
if (!hooks['PostToolUse']) {
|
|
446
|
+
const scanCmd = process.platform === 'win32'
|
|
447
|
+
? 'powershell -ExecutionPolicy Bypass -File .claude/hooks/veto-secrets-scan.ps1 "$CLAUDE_TOOL_INPUT_FILE_PATH"'
|
|
448
|
+
: 'bash .claude/hooks/veto-secrets-scan.sh "$CLAUDE_TOOL_INPUT_FILE_PATH"';
|
|
449
|
+
hooks['PostToolUse'] = [{ matcher: 'Write|Edit', hooks: [{ type: 'command', command: scanCmd }] }];
|
|
450
|
+
projectSettings.hooks = hooks;
|
|
451
|
+
writeFileSync(settingsPath, JSON.stringify(projectSettings, null, 2) + '\n', 'utf8');
|
|
452
|
+
console.log(c.green(' ✓ ') + 'Claude Code — wrote .claude/hooks/veto-secrets-scan + PostToolUse hook entry');
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
console.log(c.dim(' · ') + c.dim('Claude Code — PostToolUse hook already configured, skipping'));
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
catch {
|
|
459
|
+
console.log(c.yellow(' ⚠ ') + 'Claude Code — could not write hook templates (permission denied?)');
|
|
460
|
+
}
|
|
461
|
+
console.log('');
|
|
462
|
+
}
|
|
285
463
|
if (configured === 0 && skipped === 0) {
|
|
286
464
|
console.log(c.yellow(' ⚠ No AI tools detected.'));
|
|
287
465
|
console.log(' Install Claude Code, Gemini CLI, or Codex CLI and run veto init again.');
|
|
@@ -513,6 +691,57 @@ async function sessionsCommand() {
|
|
|
513
691
|
}
|
|
514
692
|
async function memoryCommand() {
|
|
515
693
|
const args = process.argv.slice(3);
|
|
694
|
+
const subcommand = args[0];
|
|
695
|
+
// veto memory export [--format=markdown] [--output=path]
|
|
696
|
+
if (subcommand === 'export') {
|
|
697
|
+
const formatArg = args.find(a => a.startsWith('--format='));
|
|
698
|
+
const outputArg = args.find(a => a.startsWith('--output='));
|
|
699
|
+
const format = formatArg?.split('=')[1] ?? 'json';
|
|
700
|
+
const outputPath = outputArg?.split('=')[1];
|
|
701
|
+
const { exportMemory, exportMemoryMarkdown } = await import('./memory/sync.js');
|
|
702
|
+
if (format === 'markdown') {
|
|
703
|
+
const cwd = resolve(process.cwd());
|
|
704
|
+
const result = exportMemoryMarkdown(cwd, outputPath);
|
|
705
|
+
if (result.success) {
|
|
706
|
+
console.log(c.green(' ✓') + ` VETO_MEMORY.md written to ${result.output_path}`);
|
|
707
|
+
console.log(c.dim(` Sections: ${JSON.stringify(result.sections)}`));
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
console.error(c.red(` ✗ Export failed: ${result.error}`));
|
|
711
|
+
}
|
|
712
|
+
}
|
|
713
|
+
else {
|
|
714
|
+
const result = exportMemory(outputPath);
|
|
715
|
+
if (result.success) {
|
|
716
|
+
console.log(c.green(' ✓') + ` Exported to ${result.export_path}`);
|
|
717
|
+
}
|
|
718
|
+
else {
|
|
719
|
+
console.error(c.red(` ✗ Export failed: ${result.error}`));
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
return;
|
|
723
|
+
}
|
|
724
|
+
// veto memory import [--format=markdown] <path>
|
|
725
|
+
if (subcommand === 'import') {
|
|
726
|
+
const formatArg = args.find(a => a.startsWith('--format='));
|
|
727
|
+
const format = formatArg?.split('=')[1] ?? 'json';
|
|
728
|
+
const inputPath = args.find(a => !a.startsWith('--')) ?? '';
|
|
729
|
+
const { importMemory, importMemoryMarkdown } = await import('./memory/sync.js');
|
|
730
|
+
if (format === 'markdown') {
|
|
731
|
+
if (!inputPath) {
|
|
732
|
+
console.error(c.red(' ✗ Provide a file path: veto memory import --format=markdown <path>'));
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
const result = importMemoryMarkdown(inputPath);
|
|
736
|
+
console.log(result.success ? c.green(' ✓') + ` ${result.message}` : c.red(` ✗ ${result.message}`));
|
|
737
|
+
}
|
|
738
|
+
else {
|
|
739
|
+
const result = importMemory(inputPath || undefined);
|
|
740
|
+
console.log(result.success ? c.green(' ✓') + ` Import complete` : c.red(` ✗ Import failed: ${result.error}`));
|
|
741
|
+
}
|
|
742
|
+
return;
|
|
743
|
+
}
|
|
744
|
+
// veto memory [query]
|
|
516
745
|
const query = args.join(' ') || undefined;
|
|
517
746
|
const { searchKnowledge } = await import('./memory/local.js');
|
|
518
747
|
const results = searchKnowledge({ query, limit: 20 });
|
|
@@ -554,7 +783,7 @@ async function patternsCommand() {
|
|
|
554
783
|
}
|
|
555
784
|
function shortHelpCommand() {
|
|
556
785
|
console.log('');
|
|
557
|
-
console.log(c.bold(c.cyan(' veto')) + c.dim(` v${VERSION}`) + c.dim(` —
|
|
786
|
+
console.log(c.bold(c.cyan(' veto')) + c.dim(` v${VERSION}`) + c.dim(` — 62 agentic tools. 50+ specialists. Zero cost.`));
|
|
558
787
|
console.log('');
|
|
559
788
|
console.log(c.bold(' CLI Commands'));
|
|
560
789
|
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
@@ -564,6 +793,8 @@ function shortHelpCommand() {
|
|
|
564
793
|
console.log(` ${c.cyan('veto sessions')} List last 20 saved sessions`);
|
|
565
794
|
console.log(` ${c.cyan('veto memory')} ${c.dim('[query]')} Search knowledge base`);
|
|
566
795
|
console.log(` ${c.cyan('veto patterns')} ${c.dim('[prefix]')} List learned agent/routing patterns`);
|
|
796
|
+
console.log(` ${c.cyan('veto routing')} ${c.dim('[status|enable|disable|reset|log]')}`);
|
|
797
|
+
console.log(` Routing feedback loop (opt-in signal storage)`);
|
|
567
798
|
console.log(` ${c.cyan('veto version')} Show version (alias for status)`);
|
|
568
799
|
console.log(` ${c.cyan('veto hook install')} Install pre-commit secrets scan hook`);
|
|
569
800
|
console.log(` ${c.cyan('veto hook remove')} Remove the veto pre-commit hook`);
|
|
@@ -571,26 +802,20 @@ function shortHelpCommand() {
|
|
|
571
802
|
console.log(` ${c.cyan('veto help')} Show this help`);
|
|
572
803
|
console.log(` ${c.cyan('veto help --troubleshoot')} Show troubleshooting guide`);
|
|
573
804
|
console.log('');
|
|
574
|
-
console.log(c.bold(' MCP Tools (
|
|
805
|
+
console.log(c.bold(' MCP Tools (62 Agentic Tools)'));
|
|
575
806
|
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
576
|
-
console.log(` ${c.dim('Session')} veto_status ·
|
|
577
|
-
console.log(` ${c.dim('
|
|
578
|
-
console.log(` ${c.dim('
|
|
579
|
-
console.log(` ${c.dim('
|
|
580
|
-
console.log(` ${c.dim('
|
|
581
|
-
console.log(` ${c.dim('
|
|
582
|
-
console.log(` ${c.dim('
|
|
583
|
-
console.log(` ${c.dim('
|
|
584
|
-
console.log(`
|
|
585
|
-
console.log(`
|
|
586
|
-
console.log(`
|
|
587
|
-
console.log(` ${c.dim('
|
|
588
|
-
console.log(` ${c.dim('Handoff')} veto_handoff · veto_continue · veto_platform_setup`);
|
|
589
|
-
console.log(` ${c.dim('Intelligence')} veto_docs_fetch · veto_context_status · veto_task_parse`);
|
|
590
|
-
console.log(` ${c.dim('Observability')} veto_usage_status · veto_audit_log · veto_health · veto_metrics`);
|
|
591
|
-
console.log(` ${c.dim('CI/CD')} veto_ci_gate · veto_pr_review`);
|
|
592
|
-
console.log(` ${c.dim('Discover')} veto_discover · veto_summarize · veto_git_blame · veto_changelog`);
|
|
593
|
-
console.log(` ${c.dim('Plugins')} veto_plugins`);
|
|
807
|
+
console.log(` ${c.dim('Session')} veto_status · veto_session_save · veto_session_restore · veto_sessions_list · veto_session_replay · veto_autosave_status`);
|
|
808
|
+
console.log(` ${c.dim('Council')} veto_council_debate · veto_benchmark · veto_adr`);
|
|
809
|
+
console.log(` ${c.dim('Intelligence')} veto_agent_plan · veto_execute_parallel · veto_explain · veto_delegate · veto_compose_agents`);
|
|
810
|
+
console.log(` ${c.dim('Scanning')} veto_code_review · veto_security_scan · veto_secrets_scan · veto_diff_review · veto_full_review · veto_pr_review`);
|
|
811
|
+
console.log(` ${c.dim('Pipelines')} veto_workflow · veto_task_parse · veto_new_feature · veto_pre_commit · veto_ci_gate`);
|
|
812
|
+
console.log(` ${c.dim('Watching')} veto_watch · veto_watch_poll · veto_watch_stop`);
|
|
813
|
+
console.log(` ${c.dim('Advanced')} veto_local_llm · veto_semantic_search · veto_sdd_agent · veto_playwright · veto_notify_ide · veto_translate · veto_a11y_advisor`);
|
|
814
|
+
console.log(` ${c.dim('Quality')} veto_type_coverage · veto_test_gaps · veto_clone_detector · veto_lint_rules · veto_api_contract`);
|
|
815
|
+
console.log(` ${c.dim('Discovery')} veto_discover · veto_summarize · veto_git_blame · veto_changelog · veto_onboard · veto_debt_register`);
|
|
816
|
+
console.log(` ${c.dim('DevTools')} veto_docs_fetch · veto_context_status · veto_openapi_gen · veto_flag_auditor · veto_env_setup · veto_diagram · veto_rca`);
|
|
817
|
+
console.log(` veto_commit_message · veto_pr_description · veto_pr_post · veto_prompt_optimizer · veto_sre_advisor · veto_merge_conflict`);
|
|
818
|
+
console.log(` ${c.dim('System')} veto_route_task · veto_rate_status · veto_audit_log · veto_health · veto_metrics · veto_learning_stats · veto_learning_apply · veto_handoff · veto_continue · veto_platform_setup · veto_plugins`);
|
|
594
819
|
console.log('');
|
|
595
820
|
console.log(c.bold(' MCP Resources'));
|
|
596
821
|
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
@@ -602,6 +827,7 @@ function shortHelpCommand() {
|
|
|
602
827
|
console.log(c.bold(' MCP Prompts'));
|
|
603
828
|
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
604
829
|
console.log(` ${c.cyan('code-review')} · ${c.cyan('security-audit')} · ${c.cyan('deploy-checklist')} · ${c.cyan('explain-file')}`);
|
|
830
|
+
console.log(` ${c.cyan('full-review')} · ${c.cyan('new-feature')} · ${c.cyan('debug-incident')} · ${c.cyan('onboard')}`);
|
|
605
831
|
console.log('');
|
|
606
832
|
console.log(c.bold(' Docs & Support'));
|
|
607
833
|
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
@@ -679,6 +905,84 @@ function troubleshootCommand() {
|
|
|
679
905
|
console.log(` ${c.dim('→')} Then restart the AI client on that machine`);
|
|
680
906
|
console.log('');
|
|
681
907
|
}
|
|
908
|
+
// ─── Routing Command ────────────────────────────────────────────────────────────
|
|
909
|
+
async function routingCommand() {
|
|
910
|
+
const { getRoutingFeedbackStats, resetRoutingFeedback, listRoutingFeedback, isFeedbackEnabled, setFeedbackEnabled } = await import('./router/learning-updater.js');
|
|
911
|
+
const sub = process.argv[3];
|
|
912
|
+
if (sub === 'enable') {
|
|
913
|
+
setFeedbackEnabled(true);
|
|
914
|
+
console.log('');
|
|
915
|
+
console.log(c.green(' ✓ Routing feedback enabled.'));
|
|
916
|
+
console.log(c.dim(' Every veto_route_task call now records a routing signal (30-day TTL).'));
|
|
917
|
+
console.log(c.dim(' Disable with: veto routing disable | Clear with: veto routing reset'));
|
|
918
|
+
console.log('');
|
|
919
|
+
return;
|
|
920
|
+
}
|
|
921
|
+
if (sub === 'disable') {
|
|
922
|
+
setFeedbackEnabled(false);
|
|
923
|
+
console.log('');
|
|
924
|
+
console.log(c.yellow(' ✓ Routing feedback disabled.'));
|
|
925
|
+
console.log(c.dim(' No new signals will be recorded. Existing data is retained.'));
|
|
926
|
+
console.log(c.dim(' Re-enable with: veto routing enable'));
|
|
927
|
+
console.log('');
|
|
928
|
+
return;
|
|
929
|
+
}
|
|
930
|
+
if (sub === 'reset') {
|
|
931
|
+
const result = resetRoutingFeedback();
|
|
932
|
+
console.log('');
|
|
933
|
+
console.log(c.green(' ✓ Routing feedback reset.'));
|
|
934
|
+
console.log(` ${c.dim('Deleted:')} ${c.cyan(String(result.deleted_feedback))} feedback signal${result.deleted_feedback !== 1 ? 's' : ''}`);
|
|
935
|
+
if (result.reset_thresholds) {
|
|
936
|
+
console.log(` ${c.dim('Thresholds:')} reset to defaults (30/70)`);
|
|
937
|
+
}
|
|
938
|
+
console.log('');
|
|
939
|
+
return;
|
|
940
|
+
}
|
|
941
|
+
if (sub === 'log') {
|
|
942
|
+
const limit = parseInt(process.argv[4] ?? '20', 10);
|
|
943
|
+
const entries = listRoutingFeedback(isNaN(limit) ? 20 : limit);
|
|
944
|
+
console.log('');
|
|
945
|
+
console.log(c.bold(' Routing Feedback Log') + c.dim(` (${entries.length})`));
|
|
946
|
+
console.log(c.dim(' ─────────────────────────────────────────────────────────────'));
|
|
947
|
+
if (entries.length === 0) {
|
|
948
|
+
console.log(c.dim(' No feedback signals yet. Enable feedback: veto routing enable'));
|
|
949
|
+
}
|
|
950
|
+
else {
|
|
951
|
+
for (const e of entries) {
|
|
952
|
+
const outcomeColor = e.outcome === 'accepted' ? c.green : e.outcome === 'overridden' ? c.yellow : c.dim;
|
|
953
|
+
const exp = new Date(e.expires_at).toLocaleDateString();
|
|
954
|
+
console.log(` ${c.dim(e.recorded_at.slice(0, 10))} T${e.model_tier} ${outcomeColor(e.outcome.padEnd(10))} ${c.dim(`q:${e.quality ?? '-'}`)} ${e.task_snippet.slice(0, 55)}`);
|
|
955
|
+
console.log(` ${c.dim(` expires: ${exp} agent: ${e.agent ?? 'dynamic'}`)}`);
|
|
956
|
+
console.log('');
|
|
957
|
+
}
|
|
958
|
+
}
|
|
959
|
+
return;
|
|
960
|
+
}
|
|
961
|
+
// Default: status
|
|
962
|
+
const stats = getRoutingFeedbackStats();
|
|
963
|
+
const enabled = isFeedbackEnabled();
|
|
964
|
+
const statusStr = enabled ? c.green('enabled') : c.dim('disabled');
|
|
965
|
+
console.log('');
|
|
966
|
+
console.log(c.bold(' Routing Feedback') + c.dim(' — loop status'));
|
|
967
|
+
console.log(c.dim(' ─────────────────────────────────────────────────────'));
|
|
968
|
+
console.log(` Status ${statusStr}`);
|
|
969
|
+
console.log(` TTL ${c.cyan(String(stats.ttl_days))} days`);
|
|
970
|
+
console.log(` Signals ${c.cyan(String(stats.active))} active · ${c.dim(String(stats.expired))} expired · ${String(stats.total)} total`);
|
|
971
|
+
if (Object.keys(stats.by_outcome).length > 0) {
|
|
972
|
+
const parts = Object.entries(stats.by_outcome).map(([k, v]) => `${k}: ${v}`).join(' · ');
|
|
973
|
+
console.log(` Outcomes ${c.dim(parts)}`);
|
|
974
|
+
}
|
|
975
|
+
if (Object.keys(stats.by_tier).length > 0) {
|
|
976
|
+
const parts = Object.entries(stats.by_tier).map(([tier, s]) => `T${tier}: ${s.count} (q${s.avg_quality ?? '-'})`).join(' · ');
|
|
977
|
+
console.log(` By tier ${c.dim(parts)}`);
|
|
978
|
+
}
|
|
979
|
+
if (stats.next_expiry) {
|
|
980
|
+
console.log(` Next expiry ${c.dim(new Date(stats.next_expiry).toLocaleDateString())}`);
|
|
981
|
+
}
|
|
982
|
+
console.log('');
|
|
983
|
+
console.log(c.dim(` Commands: veto routing enable · veto routing disable · veto routing reset · veto routing log`));
|
|
984
|
+
console.log('');
|
|
985
|
+
}
|
|
682
986
|
// ─── Hook installer ────────────────────────────────────────────────────────────
|
|
683
987
|
async function hookCommand() {
|
|
684
988
|
const sub = process.argv[3];
|
|
@@ -831,6 +1135,12 @@ switch (command) {
|
|
|
831
1135
|
process.exit(1);
|
|
832
1136
|
});
|
|
833
1137
|
break;
|
|
1138
|
+
case 'routing':
|
|
1139
|
+
routingCommand().catch((err) => {
|
|
1140
|
+
console.error(c.red(`Error: ${err.message}`));
|
|
1141
|
+
process.exit(1);
|
|
1142
|
+
});
|
|
1143
|
+
break;
|
|
834
1144
|
case 'hook':
|
|
835
1145
|
hookCommand().catch((err) => {
|
|
836
1146
|
console.error(c.red(`Error: ${err.message}`));
|