@jigyasudham/veto 2.1.2 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/.mcp-tools/LICENSE +216 -0
  2. package/.mcp-tools/README.md +153 -0
  3. package/.mcp-tools/mcp-publisher.exe +0 -0
  4. package/LAUNCH-KIT.md +226 -0
  5. package/README.md +106 -14
  6. package/VETO-MCP-DIAGNOSTIC.md +73 -0
  7. package/dist/agents/security/dep-verify.d.ts +23 -0
  8. package/dist/agents/security/dep-verify.d.ts.map +1 -0
  9. package/dist/agents/security/dep-verify.js +229 -0
  10. package/dist/agents/security/dep-verify.js.map +1 -0
  11. package/dist/cli/statusline.d.ts +31 -0
  12. package/dist/cli/statusline.d.ts.map +1 -0
  13. package/dist/cli/statusline.js +307 -0
  14. package/dist/cli/statusline.js.map +1 -0
  15. package/dist/cli.js +63 -5
  16. package/dist/cli.js.map +1 -1
  17. package/dist/council/decision-engine.d.ts.map +1 -1
  18. package/dist/council/decision-engine.js +11 -2
  19. package/dist/council/decision-engine.js.map +1 -1
  20. package/dist/council/lead-developer.js +2 -2
  21. package/dist/council/lead-developer.js.map +1 -1
  22. package/dist/council/product-manager.js +2 -2
  23. package/dist/council/product-manager.js.map +1 -1
  24. package/dist/council/security.js +2 -2
  25. package/dist/council/security.js.map +1 -1
  26. package/dist/council/ux-designer.js +2 -2
  27. package/dist/council/ux-designer.js.map +1 -1
  28. package/dist/memory/config.d.ts +1 -0
  29. package/dist/memory/config.d.ts.map +1 -1
  30. package/dist/memory/config.js +6 -2
  31. package/dist/memory/config.js.map +1 -1
  32. package/dist/memory/decisions.d.ts +33 -0
  33. package/dist/memory/decisions.d.ts.map +1 -0
  34. package/dist/memory/decisions.js +125 -0
  35. package/dist/memory/decisions.js.map +1 -0
  36. package/dist/memory/local.d.ts +7 -0
  37. package/dist/memory/local.d.ts.map +1 -1
  38. package/dist/memory/local.js +17 -1
  39. package/dist/memory/local.js.map +1 -1
  40. package/dist/memory/schema.d.ts +2 -1
  41. package/dist/memory/schema.d.ts.map +1 -1
  42. package/dist/memory/schema.js +30 -0
  43. package/dist/memory/schema.js.map +1 -1
  44. package/dist/router/implicit-outcomes.d.ts +7 -0
  45. package/dist/router/implicit-outcomes.d.ts.map +1 -0
  46. package/dist/router/implicit-outcomes.js +88 -0
  47. package/dist/router/implicit-outcomes.js.map +1 -0
  48. package/dist/router/learning-updater.d.ts.map +1 -1
  49. package/dist/router/learning-updater.js +15 -6
  50. package/dist/router/learning-updater.js.map +1 -1
  51. package/dist/router/model-selector.d.ts.map +1 -1
  52. package/dist/router/model-selector.js +33 -5
  53. package/dist/router/model-selector.js.map +1 -1
  54. package/dist/router/rate-monitor.d.ts +1 -0
  55. package/dist/router/rate-monitor.d.ts.map +1 -1
  56. package/dist/router/rate-monitor.js +1 -0
  57. package/dist/router/rate-monitor.js.map +1 -1
  58. package/dist/server/handlers/advisors.d.ts.map +1 -1
  59. package/dist/server/handlers/advisors.js +214 -0
  60. package/dist/server/handlers/advisors.js.map +1 -1
  61. package/dist/server/handlers/devtools.d.ts.map +1 -1
  62. package/dist/server/handlers/devtools.js +20 -3
  63. package/dist/server/handlers/devtools.js.map +1 -1
  64. package/dist/server/handlers/learning.d.ts.map +1 -1
  65. package/dist/server/handlers/learning.js +15 -0
  66. package/dist/server/handlers/learning.js.map +1 -1
  67. package/dist/server/handlers/memory.d.ts.map +1 -1
  68. package/dist/server/handlers/memory.js +47 -0
  69. package/dist/server/handlers/memory.js.map +1 -1
  70. package/dist/server/handlers/observability.d.ts.map +1 -1
  71. package/dist/server/handlers/observability.js +60 -1
  72. package/dist/server/handlers/observability.js.map +1 -1
  73. package/dist/server/handlers/review.d.ts.map +1 -1
  74. package/dist/server/handlers/review.js +22 -4
  75. package/dist/server/handlers/review.js.map +1 -1
  76. package/dist/server.d.ts.map +1 -1
  77. package/dist/server.js +95 -2
  78. package/dist/server.js.map +1 -1
  79. package/dist/tools/compact.d.ts +12 -0
  80. package/dist/tools/compact.d.ts.map +1 -0
  81. package/dist/tools/compact.js +98 -0
  82. package/dist/tools/compact.js.map +1 -0
  83. package/dist/tools/definitions.d.ts +111 -2
  84. package/dist/tools/definitions.d.ts.map +1 -1
  85. package/dist/tools/definitions.js +62 -3
  86. package/dist/tools/definitions.js.map +1 -1
  87. package/package.json +2 -2
  88. package/server.json +3 -3
@@ -0,0 +1,307 @@
1
+ // veto statusline — a compact, always-on Veto line beneath the AI CLI prompt.
2
+ //
3
+ // Lives in the CLI (not the VS Code extension) so EVERY Veto user gets it in any
4
+ // terminal. Claude Code natively supports a custom `statusLine` command in
5
+ // settings.json; `veto statusline install` wires this command in.
6
+ //
7
+ // The `print` subcommand is a HOT PATH: it runs on every prompt render, so it
8
+ // must be read-only, fast (<50ms), and crash-proof. It opens a dedicated
9
+ // read-only DB connection (no migrations, no table creation, no writes) and on
10
+ // ANY problem — missing DB, locked DB (WAL / SQLITE_BUSY), bad row — it prints a
11
+ // neutral `⬡ veto` and exits 0. It never throws and never blocks the prompt.
12
+ import { createRequire } from 'node:module';
13
+ import { existsSync, readFileSync, writeFileSync, mkdirSync, unlinkSync } from 'node:fs';
14
+ import { join, dirname } from 'node:path';
15
+ import { homedir } from 'node:os';
16
+ import { getDbPath, getDb } from '../memory/local.js';
17
+ import { getConfig } from '../memory/config.js';
18
+ // node:sqlite is a Node 22.5+ built-in — use createRequire so bundlers skip it.
19
+ const _require = createRequire(import.meta.url);
20
+ const DbSync = _require('node:sqlite').DatabaseSync;
21
+ const EMPTY = {
22
+ verdict: null, routerPct: null, platform: null, ratePct: null, memCount: null,
23
+ };
24
+ // Open the veto DB read-only. Returns null if it can't (missing/locked/corrupt).
25
+ function openReadOnly(path) {
26
+ try {
27
+ const db = new DbSync(path, { readOnly: true });
28
+ // query_only is belt-and-suspenders; busy_timeout keeps us from blocking the
29
+ // prompt if a writer holds the WAL lock — fail fast to the neutral fallback.
30
+ db.exec('PRAGMA query_only = ON');
31
+ db.exec('PRAGMA busy_timeout = 50');
32
+ return db;
33
+ }
34
+ catch {
35
+ return null;
36
+ }
37
+ }
38
+ // Crash-proof read of everything the statusline shows. Never throws.
39
+ export function readStatuslineData() {
40
+ let db = null;
41
+ let closeAfter = false;
42
+ try {
43
+ const path = getDbPath();
44
+ if (path === ':memory:') {
45
+ // In-memory (tests / special cases): a fresh read-only handle would be a
46
+ // different empty DB, so reuse the shared reader.
47
+ db = getDb();
48
+ }
49
+ else {
50
+ if (!existsSync(path))
51
+ return EMPTY;
52
+ db = openReadOnly(path);
53
+ closeAfter = true;
54
+ if (!db)
55
+ return EMPTY;
56
+ }
57
+ return queryStatusline(db);
58
+ }
59
+ catch {
60
+ return EMPTY;
61
+ }
62
+ finally {
63
+ if (closeAfter && db) {
64
+ try {
65
+ db.close();
66
+ }
67
+ catch { /* ignore */ }
68
+ }
69
+ }
70
+ }
71
+ function queryStatusline(db) {
72
+ const data = { ...EMPTY };
73
+ // Each block is independently guarded: a missing/older table degrades that one
74
+ // segment to null rather than blanking the whole line.
75
+ try {
76
+ const row = db.prepare('SELECT verdict FROM council_outcomes ORDER BY debated_at DESC LIMIT 1').get();
77
+ const v = (row?.verdict ?? '').toUpperCase();
78
+ if (v === 'GREEN' || v === 'YELLOW' || v === 'RED')
79
+ data.verdict = v;
80
+ }
81
+ catch { /* segment off */ }
82
+ try {
83
+ // Top confidence among learned patterns. Exclude router.* threshold rows and
84
+ // composed_agent:* definitions — those carry config/JSON, not a learning score.
85
+ const row = db.prepare(`SELECT confidence FROM patterns
86
+ WHERE pattern_key NOT LIKE 'router.%' AND pattern_key NOT LIKE 'composed_agent:%'
87
+ ORDER BY confidence DESC, seen_count DESC LIMIT 1`).get();
88
+ if (typeof row?.confidence === 'number') {
89
+ data.routerPct = Math.max(0, Math.min(100, Math.round(row.confidence * 100)));
90
+ }
91
+ }
92
+ catch { /* segment off */ }
93
+ try {
94
+ const row = db.prepare('SELECT platform FROM sessions ORDER BY created_at DESC LIMIT 1').get();
95
+ if (row?.platform)
96
+ data.platform = row.platform;
97
+ }
98
+ catch { /* segment off */ }
99
+ // Rate % for the active platform today — mirrors router/rate-monitor semantics
100
+ // (min(100, round(tokens / dailyBudget * 100))).
101
+ if (data.platform) {
102
+ try {
103
+ const today = new Date().toISOString().slice(0, 10);
104
+ const row = db.prepare('SELECT token_count FROM rate_usage WHERE platform = ? AND date_key = ?').get(data.platform, today);
105
+ const tokens = row?.token_count ?? 0;
106
+ const budgets = getConfig().dailyTokenBudget;
107
+ const budget = budgets[data.platform];
108
+ if (budget && budget > 0) {
109
+ data.ratePct = Math.min(100, Math.round((tokens / budget) * 100));
110
+ }
111
+ }
112
+ catch { /* segment off */ }
113
+ }
114
+ try {
115
+ const row = db.prepare('SELECT COUNT(*) AS n FROM knowledge_base').get();
116
+ if (typeof row?.n === 'number')
117
+ data.memCount = row.n;
118
+ }
119
+ catch { /* segment off */ }
120
+ return data;
121
+ }
122
+ const ANSI = {
123
+ reset: '\x1b[0m',
124
+ dim: '\x1b[2m',
125
+ green: '\x1b[32m',
126
+ yellow: '\x1b[33m',
127
+ red: '\x1b[31m',
128
+ };
129
+ export function composeStatusline(data, opts = {}) {
130
+ const color = opts.color ?? !process.env.NO_COLOR;
131
+ const ascii = opts.ascii ?? Boolean(process.env.VETO_STATUSLINE_ASCII);
132
+ const paint = (s, code) => (color ? `${code}${s}${ANSI.reset}` : s);
133
+ const head = `${ascii ? '#' : '⬡'} veto`;
134
+ const segments = [];
135
+ if (data.verdict) {
136
+ const code = data.verdict === 'GREEN' ? ANSI.green
137
+ : data.verdict === 'YELLOW' ? ANSI.yellow
138
+ : ANSI.red;
139
+ segments.push(paint(data.verdict, code));
140
+ }
141
+ if (data.routerPct !== null) {
142
+ segments.push(`router ${data.routerPct}%`);
143
+ }
144
+ if (data.platform && data.ratePct !== null) {
145
+ // Color the rate % using the same thresholds as rate-monitor (warn ≥70, crit ≥90).
146
+ const label = `${data.platform} ${data.ratePct}%`;
147
+ const code = data.ratePct >= 90 ? ANSI.red : data.ratePct >= 70 ? ANSI.yellow : '';
148
+ segments.push(code ? paint(label, code) : label);
149
+ }
150
+ if (data.memCount !== null) {
151
+ segments.push(`mem ${data.memCount}`);
152
+ }
153
+ if (segments.length === 0)
154
+ return head; // neutral fallback
155
+ return `${head} ${segments.join(' · ')}`;
156
+ }
157
+ // The hot path: read + render + print. Never throws, always exits 0.
158
+ export function printStatusline(opts = {}) {
159
+ let line;
160
+ try {
161
+ line = composeStatusline(readStatuslineData(), opts);
162
+ }
163
+ catch {
164
+ line = composeStatusline(EMPTY, opts);
165
+ }
166
+ process.stdout.write(line + '\n');
167
+ }
168
+ // Resolve the settings.json for a client. Only Claude Code exposes a documented
169
+ // `statusLine` command hook today; others are gated behind --client as a stretch.
170
+ function resolveClient(client) {
171
+ const HOME = homedir();
172
+ switch (client) {
173
+ case 'claude':
174
+ // VETO_STATUSLINE_SETTINGS overrides the path (used by tests).
175
+ return {
176
+ name: 'Claude Code',
177
+ settingsPath: process.env.VETO_STATUSLINE_SETTINGS ?? join(HOME, '.claude', 'settings.json'),
178
+ };
179
+ default:
180
+ return null;
181
+ }
182
+ }
183
+ const STATUSLINE_VALUE = { type: 'command', command: 'veto statusline print' };
184
+ const BACKUP_SUFFIX = '.veto-statusline-backup';
185
+ const NO_ORIGINAL = '__VETO_NO_ORIGINAL_FILE__';
186
+ function isOurStatusLine(v) {
187
+ return Boolean(v) && typeof v === 'object'
188
+ && v.command === STATUSLINE_VALUE.command;
189
+ }
190
+ export function installStatusline(client = 'claude', opts = {}) {
191
+ const target = resolveClient(client);
192
+ if (!target) {
193
+ return { ok: false, message: `Unknown client "${client}". Supported: claude.` };
194
+ }
195
+ const { settingsPath } = target;
196
+ const existed = existsSync(settingsPath);
197
+ let settings = {};
198
+ let rawOriginal = '';
199
+ if (existed) {
200
+ try {
201
+ rawOriginal = readFileSync(settingsPath, 'utf8');
202
+ settings = JSON.parse(rawOriginal);
203
+ }
204
+ catch {
205
+ return { ok: false, message: `Refusing to touch ${settingsPath}: it is not valid JSON.` };
206
+ }
207
+ }
208
+ const current = settings.statusLine;
209
+ if (isOurStatusLine(current)) {
210
+ return { ok: true, changed: false, message: `Already installed for ${target.name} (${settingsPath}).` };
211
+ }
212
+ if (current !== undefined && !opts.force) {
213
+ return {
214
+ ok: false,
215
+ message: `${target.name} already has a custom statusLine. Re-run with --force to replace it `
216
+ + `(your original is backed up and restored on uninstall).`,
217
+ };
218
+ }
219
+ if (opts.dryRun) {
220
+ return {
221
+ ok: true,
222
+ changed: false,
223
+ message: `[dry-run] Would set statusLine → ${JSON.stringify(STATUSLINE_VALUE)} in ${settingsPath}`
224
+ + (current !== undefined ? ` (replacing existing statusLine).` : `.`),
225
+ };
226
+ }
227
+ // Back up byte-for-byte so uninstall can restore exactly. Only create the
228
+ // backup once (a re-install must not overwrite the true original).
229
+ const backupPath = settingsPath + BACKUP_SUFFIX;
230
+ if (!existsSync(backupPath)) {
231
+ writeFileSync(backupPath, existed ? rawOriginal : NO_ORIGINAL, 'utf8');
232
+ }
233
+ settings.statusLine = { ...STATUSLINE_VALUE };
234
+ if (!existed)
235
+ mkdirSync(dirname(settingsPath), { recursive: true });
236
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
237
+ return {
238
+ ok: true,
239
+ changed: true,
240
+ backupPath,
241
+ message: `Installed Veto statusline for ${target.name}.\n ${settingsPath}\n backup: ${backupPath}`
242
+ + (current !== undefined ? `\n (replaced your previous statusLine — restored on uninstall)` : ``),
243
+ };
244
+ }
245
+ export function uninstallStatusline(client = 'claude') {
246
+ const target = resolveClient(client);
247
+ if (!target) {
248
+ return { ok: false, message: `Unknown client "${client}". Supported: claude.` };
249
+ }
250
+ const { settingsPath } = target;
251
+ const backupPath = settingsPath + BACKUP_SUFFIX;
252
+ if (existsSync(backupPath)) {
253
+ const backup = readFileSync(backupPath, 'utf8');
254
+ if (backup === NO_ORIGINAL) {
255
+ // There was no settings file before us — remove our key; delete the file if
256
+ // it now holds nothing else.
257
+ if (existsSync(settingsPath)) {
258
+ try {
259
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
260
+ delete settings.statusLine;
261
+ if (Object.keys(settings).length === 0) {
262
+ unlinkSync(settingsPath);
263
+ }
264
+ else {
265
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
266
+ }
267
+ }
268
+ catch { /* leave as-is if unreadable */ }
269
+ }
270
+ }
271
+ else {
272
+ // Restore the original file byte-for-byte.
273
+ writeFileSync(settingsPath, backup, 'utf8');
274
+ }
275
+ unlinkSync(backupPath);
276
+ return { ok: true, changed: true, message: `Uninstalled Veto statusline for ${target.name} (restored ${settingsPath}).` };
277
+ }
278
+ // No backup — best-effort removal of our key only.
279
+ if (existsSync(settingsPath)) {
280
+ try {
281
+ const settings = JSON.parse(readFileSync(settingsPath, 'utf8'));
282
+ if (isOurStatusLine(settings.statusLine)) {
283
+ delete settings.statusLine;
284
+ writeFileSync(settingsPath, JSON.stringify(settings, null, 2) + '\n', 'utf8');
285
+ return { ok: true, changed: true, message: `Removed Veto statusline from ${settingsPath}.` };
286
+ }
287
+ }
288
+ catch { /* fall through */ }
289
+ }
290
+ return { ok: true, changed: false, message: `Veto statusline was not installed for ${target.name}.` };
291
+ }
292
+ export function statuslineStatusInfo(client = 'claude') {
293
+ const target = resolveClient(client);
294
+ const sample = composeStatusline(readStatuslineData());
295
+ if (!target)
296
+ return { installed: false, settingsPath: null, sample };
297
+ let installed = false;
298
+ if (existsSync(target.settingsPath)) {
299
+ try {
300
+ const settings = JSON.parse(readFileSync(target.settingsPath, 'utf8'));
301
+ installed = isOurStatusLine(settings.statusLine);
302
+ }
303
+ catch { /* installed stays false */ }
304
+ }
305
+ return { installed, settingsPath: target.settingsPath, sample };
306
+ }
307
+ //# sourceMappingURL=statusline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusline.js","sourceRoot":"","sources":["../../src/cli/statusline.ts"],"names":[],"mappings":"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"}
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import { homedir } from 'node:os';
9
9
  import { fileURLToPath } from 'node:url';
10
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
11
11
  const { version: VERSION } = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf8'));
12
- const TAGLINE = '89 agentic tools. 49 specialists. Every major AI CLI. Self-learning. Zero extra cost on subscriptions.';
12
+ const TAGLINE = '93 agentic tools. 49 specialists. Every major AI CLI. Self-learning. Zero extra cost on subscriptions.';
13
13
  const VETO_DIR = join(homedir(), '.veto');
14
14
  const HOME = homedir();
15
15
  const c = {
@@ -307,7 +307,7 @@ async function initCommand() {
307
307
  console.log('');
308
308
  const VETO_GUIDE = `# Veto MCP Server
309
309
 
310
- Veto is active. 89 tools across 6 categories:
310
+ Veto is active. 93 tools across 6 categories:
311
311
 
312
312
  **Session & Context** — veto_status · veto_session_save · veto_continue · veto_handoff
313
313
  Save work at 60–70% context capacity. veto_status triggers auto-save above 70%.
@@ -863,9 +863,59 @@ async function patternsCommand() {
863
863
  }
864
864
  console.log('');
865
865
  }
866
+ async function statuslineCommand() {
867
+ const sub = process.argv[3] ?? 'status';
868
+ const args = process.argv.slice(4);
869
+ const clientArg = args.find(a => a.startsWith('--client='))?.split('=')[1] ?? 'claude';
870
+ const force = args.includes('--force') || args.includes('--yes') || args.includes('-y');
871
+ const dryRun = args.includes('--dry-run');
872
+ const sl = await import('./cli/statusline.js');
873
+ // Hot path: one line to stdout, nothing else. No banner, no colors-config noise.
874
+ if (sub === 'print') {
875
+ sl.printStatusline();
876
+ return;
877
+ }
878
+ if (sub === 'install') {
879
+ const r = sl.installStatusline(clientArg, { force, dryRun });
880
+ console.log('');
881
+ console.log((r.ok ? c.green(' ✓ ') : c.red(' ✗ ')) + r.message.replace(/\n/g, '\n '));
882
+ if (r.ok && r.changed)
883
+ console.log(c.dim('\n Restart your AI CLI to see the Veto line. Remove with: veto statusline uninstall'));
884
+ console.log('');
885
+ if (!r.ok)
886
+ process.exit(1);
887
+ return;
888
+ }
889
+ if (sub === 'uninstall') {
890
+ const r = sl.uninstallStatusline(clientArg);
891
+ console.log('');
892
+ console.log((r.ok ? c.green(' ✓ ') : c.red(' ✗ ')) + r.message);
893
+ console.log('');
894
+ if (!r.ok)
895
+ process.exit(1);
896
+ return;
897
+ }
898
+ if (sub === 'status') {
899
+ const info = sl.statuslineStatusInfo(clientArg);
900
+ console.log('');
901
+ console.log(c.bold(' Veto Statusline'));
902
+ console.log(c.dim(' ─────────────────────────────────────────────────────'));
903
+ console.log(` Installed: ${info.installed ? c.green('yes') : c.dim('no')}`);
904
+ if (info.settingsPath)
905
+ console.log(` Settings: ${c.dim(info.settingsPath)}`);
906
+ console.log(` Sample: ${info.sample}`);
907
+ console.log('');
908
+ console.log(c.dim(' Install: veto statusline install [--client=claude] [--force] [--dry-run]'));
909
+ console.log('');
910
+ return;
911
+ }
912
+ console.error(c.red(` Unknown statusline subcommand: ${sub}`));
913
+ console.error(c.dim(' Usage: veto statusline <install|uninstall|print|status>'));
914
+ process.exit(1);
915
+ }
866
916
  function shortHelpCommand() {
867
917
  console.log('');
868
- console.log(c.bold(c.cyan(' veto')) + c.dim(` v${VERSION}`) + c.dim(` — 89 agentic tools. 49 specialists. Every major AI CLI. Zero extra cost on subscriptions.`));
918
+ console.log(c.bold(c.cyan(' veto')) + c.dim(` v${VERSION}`) + c.dim(` — 93 agentic tools. 49 specialists. Every major AI CLI. Zero extra cost on subscriptions.`));
869
919
  console.log('');
870
920
  console.log(c.bold(' CLI Commands'));
871
921
  console.log(c.dim(' ─────────────────────────────────────────────────────'));
@@ -879,6 +929,8 @@ function shortHelpCommand() {
879
929
  console.log(` ${c.cyan('veto patterns')} ${c.dim('[prefix]')} List learned agent/routing patterns`);
880
930
  console.log(` ${c.cyan('veto routing')} ${c.dim('[status|enable|disable|reset|log]')}`);
881
931
  console.log(` Routing feedback loop (opt-in signal storage)`);
932
+ console.log(` ${c.cyan('veto statusline')} ${c.dim('[install|uninstall|print|status]')}`);
933
+ console.log(` Compact Veto line under your AI CLI prompt`);
882
934
  console.log(` ${c.cyan('veto version')} Show version (alias for status)`);
883
935
  console.log(` ${c.cyan('veto hook install')} Install pre-commit secrets scan hook`);
884
936
  console.log(` ${c.cyan('veto hook remove')} Remove the veto pre-commit hook`);
@@ -886,9 +938,9 @@ function shortHelpCommand() {
886
938
  console.log(` ${c.cyan('veto help')} Show this help`);
887
939
  console.log(` ${c.cyan('veto help --troubleshoot')} Show troubleshooting guide`);
888
940
  console.log('');
889
- console.log(c.bold(' MCP Tools (89 Agentic Tools)'));
941
+ console.log(c.bold(' MCP Tools (93 Agentic Tools)'));
890
942
  console.log(c.dim(' ─────────────────────────────────────────────────────'));
891
- console.log(` ${c.dim('Session')} veto_status · veto_session_save · veto_session_restore · veto_sessions_list · veto_session_replay · veto_autosave_status`);
943
+ console.log(` ${c.dim('Session')} veto_status · veto_session_save · veto_session_restore · veto_sessions_list · veto_session_replay · veto_autosave_status · veto_snapshot`);
892
944
  console.log(` ${c.dim('Council')} veto_council_debate · veto_benchmark · veto_adr`);
893
945
  console.log(` ${c.dim('Intelligence')} veto_agent_plan · veto_execute_parallel · veto_explain · veto_delegate · veto_compose_agents`);
894
946
  console.log(` ${c.dim('Scanning')} veto_code_review · veto_security_scan · veto_secrets_scan · veto_diff_review · veto_full_review · veto_pr_review`);
@@ -1331,6 +1383,12 @@ switch (command) {
1331
1383
  process.exit(1);
1332
1384
  });
1333
1385
  break;
1386
+ case 'statusline':
1387
+ statuslineCommand().catch((err) => {
1388
+ console.error(c.red(`Error: ${err.message}`));
1389
+ process.exit(1);
1390
+ });
1391
+ break;
1334
1392
  case 'hook':
1335
1393
  hookCommand().catch((err) => {
1336
1394
  console.error(c.red(`Error: ${err.message}`));