@jigyasudham/veto 2.5.0 → 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.
package/LAUNCH-KIT.md CHANGED
@@ -1,9 +1,15 @@
1
1
  # Veto Launch Kit
2
2
 
3
- Ready-to-paste copy for distribution. Facts current as of v2.1.2 (npm latest + official MCP Registry).
4
- Core hook: **89 agentic tools + a 49-specialist agent council for every major AI CLI, at zero extra
3
+ Ready-to-paste copy for distribution. Facts current as of v2.5.0 (npm latest + official MCP Registry).
4
+ Core hook: **93 agentic tools + a 49-specialist agent council for every major AI CLI, at zero extra
5
5
  token cost on subscription plans.**
6
6
 
7
+ > **New in v2.2–2.5 (lead with these — they're the cleanest expression of the "Veto" name):**
8
+ > a guardrail layer that catches AI mistakes before they ship —
9
+ > `veto_dep_verify` (dependency-hallucination guard: flags packages the AI invented),
10
+ > `veto_decisions` (decision-drift enforcement: stops the AI quietly reversing an agreed choice), and
11
+ > `veto_drift_check` (compounding-error circuit breaker). This is the launch's strongest story.
12
+
7
13
  Canonical links:
8
14
  - npm: https://www.npmjs.com/package/@jigyasudham/veto
9
15
  - GitHub: https://github.com/jigyasudham/veto
@@ -24,7 +30,7 @@ Canonical links:
24
30
  **Entry line (alphabetical by `owner/name` within the section):**
25
31
 
26
32
  ```
27
- - [jigyasudham/veto](https://github.com/jigyasudham/veto) 📇 🏠 🍎 🪟 🐧 - 89 agentic tools and a 49-specialist agent council (Lead Dev, Architect, Security…) for every major AI CLI — Claude Code, Codex, Gemini, Cursor, Windsurf. Self-learning router, cross-platform memory, deterministic agents that optionally upgrade to LLM. Zero extra token cost on subscriptions.
33
+ - [jigyasudham/veto](https://github.com/jigyasudham/veto) 📇 🏠 🍎 🪟 🐧 - 93 agentic tools and a 49-specialist agent council (Lead Dev, Architect, Security…) for every major AI CLI — Claude Code, Codex, Gemini, Cursor, Windsurf. Self-learning router, cross-platform memory, dependency-hallucination + decision-drift guards, deterministic agents that optionally upgrade to LLM. Zero extra token cost on subscriptions.
28
34
  ```
29
35
 
30
36
  **Submit steps:**
@@ -32,9 +38,9 @@ Canonical links:
32
38
  gh repo fork punkpeye/awesome-mcp-servers --clone
33
39
  # add the line under the Coding Agents section, keeping alphabetical order
34
40
  git checkout -b add-veto
35
- git commit -am "Add Veto — 89 MCP tools + 49-agent council for every AI CLI"
41
+ git commit -am "Add Veto — 93 MCP tools + 49-agent council for every AI CLI"
36
42
  git push -u origin add-veto
37
- gh pr create --repo punkpeye/awesome-mcp-servers --title "Add Veto" --body "Adds Veto: an MCP server giving every major AI CLI a 49-specialist agent council + 89 tools, using existing subscriptions (no API keys). MIT, on the official MCP registry as io.github.jigyasudham/veto."
43
+ gh pr create --repo punkpeye/awesome-mcp-servers --title "Add Veto" --body "Adds Veto: an MCP server giving every major AI CLI a 49-specialist agent council + 93 tools, using existing subscriptions (no API keys). MIT, on the official MCP registry as io.github.jigyasudham/veto."
38
44
  ```
39
45
 
40
46
  ---
@@ -43,16 +49,16 @@ gh pr create --repo punkpeye/awesome-mcp-servers --title "Add Veto" --body "Adds
43
49
 
44
50
  **Title (submit the GitHub URL as the link):**
45
51
  ```
46
- Show HN: Veto – 89 MCP tools and a 49-agent council for every AI CLI
52
+ Show HN: Veto – 93 MCP tools and a 49-agent council for every AI CLI
47
53
  ```
48
54
 
49
55
  **First comment (post immediately after submitting):**
50
56
  ```
51
57
  Hi HN — I built Veto, a single MCP server that plugs into whatever AI CLI you already
52
- use (Claude Code, Codex, Gemini, Cursor, Windsurf, Zed, JetBrains) and gives it 89 tools
58
+ use (Claude Code, Codex, Gemini, Cursor, Windsurf, Zed, JetBrains) and gives it 93 tools
53
59
  and a council of 49 specialist agents — code review, security/secrets scanning, a 7-agent
54
- "should we build this" debate, CI gates, SDD agents, and persistent memory that follows you
55
- across CLIs.
60
+ "should we build this" debate, CI gates, SDD agents, guards that catch dependency
61
+ hallucinations and decision drift, and persistent memory that follows you across CLIs.
56
62
 
57
63
  The design decision I'd most like feedback on: the 42 worker agents are *deterministic
58
64
  expert modules by default* (regex/AST secret detection, OWASP/CWE rules, complexity metrics)
@@ -75,7 +81,7 @@ or the cross-CLI memory/handoff. What would you want a tool like this to NOT do?
75
81
  ```
76
82
 
77
83
  > HN tips: post Tue–Thu ~8–10am ET. Don't ask for upvotes. Reply fast and non-defensively;
78
- > the skeptical "isn't 89 tools bloat?" question is your best moment — answer it with the
84
+ > the skeptical "isn't 93 tools bloat?" question is your best moment — answer it with the
79
85
  > deterministic-vs-LLM architecture above.
80
86
 
81
87
  ---
@@ -86,7 +92,7 @@ or the cross-CLI memory/handoff. What would you want a tool like this to NOT do?
86
92
  **Title:** I gave Claude Code a 49-agent council + persistent memory across CLIs — open source, no API keys
87
93
  **Body:**
88
94
  ```
89
- Veto is an MCP server I've been building that adds 89 tools + 49 specialist agents to Claude
95
+ Veto is an MCP server I've been building that adds 93 tools + 49 specialist agents to Claude
90
96
  Code using your existing Claude subscription (no separate API key, no extra token bill on
91
97
  Max/Pro).
92
98
 
@@ -96,6 +102,9 @@ What it actually does day to day:
96
102
  debates a plan before you build it
97
103
  - memory that saves your session and restores it in Gemini CLI or Codex if you switch — the
98
104
  handoff carries full context
105
+ - guards that catch the AI's own mistakes: dependency-hallucination detection (flags packages
106
+ it invented), decision-drift enforcement (stops it reversing a choice you already made), and a
107
+ compounding-error circuit breaker
99
108
  - a self-learning router that re-tunes which model tier handles which task
100
109
 
101
110
  Most worker agents are deterministic (real OWASP/CWE/secret-detection code), and upgrade to
@@ -125,11 +134,11 @@ Repo: https://github.com/jigyasudham/veto — keen on feedback re: wiring it to
125
134
  ```
126
135
 
127
136
  ### r/ChatGPTCoding
128
- **Title:** Open-source MCP server: 89 tools + 49-agent council that works across Codex, Claude, Gemini & Cursor
137
+ **Title:** Open-source MCP server: 93 tools + 49-agent council that works across Codex, Claude, Gemini & Cursor
129
138
  **Body:**
130
139
  ```
131
140
  Veto is an MCP server that gives whatever AI coding CLI you use (Codex, Claude Code, Gemini,
132
- Cursor, Windsurf) a shared layer: 89 tools, a 49-specialist agent council, code review +
141
+ Cursor, Windsurf) a shared layer: 93 tools, a 49-specialist agent council, code review +
133
142
  security scanning, CI gates, and memory that follows you when you switch tools.
134
143
 
135
144
  The agents are deterministic by default and upgrade to LLM reasoning only when your client
@@ -150,7 +159,7 @@ https://github.com/jigyasudham/veto
150
159
 
151
160
  ```
152
161
  1/ I shipped Veto — one MCP server that gives every major AI CLI a council of 49 specialist
153
- agents + 89 tools, using your existing subscription. No API keys. No extra token bill.
162
+ agents + 93 tools, using your existing subscription. No API keys. No extra token bill.
154
163
 
155
164
  Claude Code, Codex, Gemini, Cursor, Windsurf, Zed, JetBrains — same superpowers everywhere.
156
165
  [attach veto.gif]
@@ -166,7 +175,11 @@ actual trade-offs. It's saved me from a few bad calls already.
166
175
  4/ And it remembers. Save a session in Claude Code, restore it in Gemini CLI mid-task — the
167
176
  handoff carries full context. Plus a router that re-tunes itself every 20 outcomes.
168
177
 
169
- 5/ MIT. On npm and the official MCP registry.
178
+ 5/ The newest part lives up to the name: a guardrail layer that vetoes the AI's own mistakes —
179
+ catches packages it hallucinated, blocks it from quietly reversing a decision you already made,
180
+ and trips a circuit breaker on compounding errors.
181
+
182
+ 6/ MIT. On npm and the official MCP registry.
170
183
 
171
184
  One command: npx @jigyasudham/veto init
172
185
 
@@ -189,23 +202,25 @@ self-learning, multi-agent, developer-tools
189
202
 
190
203
  **Short description (<=100 chars — matches server.json):**
191
204
  ```
192
- 89 agentic MCP tools, 49 specialist agents for every major AI CLI. Self-learning, zero API cost.
205
+ 93 agentic MCP tools, 49 specialist agents for every major AI CLI. Self-learning, zero API cost.
193
206
  ```
194
207
 
195
208
  **One-liner:**
196
209
  ```
197
- A council of 49 specialist agents + 89 tools for every AI CLI, using your existing subscription.
210
+ A council of 49 specialist agents + 93 tools for every AI CLI, using your existing subscription.
198
211
  ```
199
212
 
200
213
  **Long description:**
201
214
  ```
202
215
  Veto is a local MCP server that gives every major AI CLI — Claude Code, Codex, Gemini,
203
- Antigravity, Cursor, Windsurf, Zed, JetBrains — a shared layer of 89 agentic tools and 49
216
+ Antigravity, Cursor, Windsurf, Zed, JetBrains — a shared layer of 93 agentic tools and 49
204
217
  specialist agents. 42 worker agents (across dev, security, memory, research, quality, and
205
218
  workflow domains) run as deterministic expert modules by default and optionally upgrade to LLM
206
219
  reasoning via MCP Sampling; a 7-agent Council debates trade-offs before you build. It adds code
207
- review, security and secrets scanning, CI gates, SDD agents, Playwright automation, a
208
- self-learning router that re-tunes its thresholds every 20 outcomes, and persistent memory that
209
- hands off your session across CLIs. On a subscription it costs nothing extra; on API billing,
210
- Sampling calls count and it warns you. MIT licensed.
220
+ review, security and secrets scanning, CI gates, SDD agents, Playwright automation, a guardrail
221
+ layer that catches the AI's own mistakes (dependency-hallucination detection, decision-drift
222
+ enforcement, and a compounding-error circuit breaker), a self-learning router that re-tunes its
223
+ thresholds every 20 outcomes, and persistent memory that hands off your session across CLIs. On
224
+ a subscription it costs nothing extra; on API billing, Sampling calls count and it warns you.
225
+ MIT licensed.
211
226
  ```
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # veto
2
2
 
3
- > **92 agentic tools. 49 specialists. Every major AI CLI. Self-learning. Zero extra cost on subscriptions.**
3
+ > **93 agentic tools. 49 specialists. Every major AI CLI. Self-learning. Zero extra cost on subscriptions.**
4
4
 
5
5
  An MCP server that runs locally on your machine, plugs into Claude Code, Codex CLI, Gemini CLI, Antigravity CLI, Cursor, Windsurf, Zed, and JetBrains using your existing subscriptions — giving every AI a council of specialist agents, local LLM support, SDD agents, playwright automation, persistent cross-platform memory, a self-learning router that re-tunes its tier thresholds automatically every 20 recorded task outcomes (reviews record outcomes for you; configurable via `auto_apply_learning`), CI/CD gates, workspace discovery, and bidirectional IDE communication.
6
6
 
@@ -69,12 +69,12 @@ The 7-agent **Council** is LLM-first — its value is the multi-agent debate —
69
69
  | **Memory** | `veto_memory_store` · `veto_memory_search` · `veto_memory_delete` · `veto_project_map_update` · `veto_project_map_get` · `veto_pattern_store` · `veto_patterns_list` · `veto_memory_export` · `veto_memory_import` |
70
70
  | **Learning** | `veto_record_outcome` · `veto_learning_stats` · `veto_learning_apply` |
71
71
  | **Handoff** | `veto_handoff` · `veto_continue` · `veto_platform_setup` |
72
- | **Observability** | `veto_usage_status` · `veto_audit_log` · `veto_health` · `veto_metrics` |
72
+ | **Observability** | `veto_usage_status` · `veto_audit_log` · `veto_health` · `veto_metrics` · `veto_snapshot` |
73
73
  | **Discover** | `veto_discover` · `veto_summarize` · `veto_git_blame` · `veto_changelog` · `veto_onboard` · `veto_debt_register` |
74
74
  | **DevTools** | `veto_docs_fetch` · `veto_context_status` · `veto_openapi_gen` · `veto_flag_auditor` · `veto_env_setup` · `veto_commit_message` · `veto_pr_description` · `veto_pr_post` · `veto_prompt_optimizer` · `veto_sre_advisor` · `veto_diagram` · `veto_rca` · `veto_doc_gen` · `veto_postmortem` · `veto_release_notes` · `veto_translate` · `veto_merge_conflict` |
75
75
  | **Plugins** | `veto_plugins` |
76
76
 
77
- ## Compact Mode — 92 tools without the context tax
77
+ ## Compact Mode — 93 tools without the context tax
78
78
 
79
79
  92 tool schemas cost a client ~16K context tokens before the user types a word. Compact mode advertises a surface that is **5–6× smaller**: seven core tools (`veto_status`, `veto_session_save`, `veto_session_restore`, `veto_route_task`, `veto_council_debate`, `veto_memory_search`, `veto_record_outcome`) plus two meta-tools — `veto_find_tools` searches the full catalog by keyword and returns matching schemas on demand; `veto_call` invokes any catalog tool by name. Every tool remains directly callable in both modes; compact only changes what is advertised up front.
80
80
 
@@ -209,7 +209,7 @@ veto sessions # List last 20 saved sessions ([auto] badge on
209
209
  veto sessions --clean # Remove auto-saves older than 7 days
210
210
  veto memory [query] # Search knowledge base (blank = all entries)
211
211
  veto patterns [prefix] # List learned agent/routing patterns
212
- veto tools [filter] # List all 92 MCP tools (--json for machine output)
212
+ veto tools [filter] # List all 93 MCP tools (--json for machine output)
213
213
  veto agents [filter] # List all 49 specialists — workers + council (--json)
214
214
  veto routing [status|log|reset] # Inspect the opt-in routing feedback loop
215
215
  veto hook install # Install pre-commit secrets scan hook
@@ -417,6 +417,11 @@ Platform switching is manual — Veto surfaces which platform has budget remaini
417
417
 
418
418
  ## Release Notes
419
419
 
420
+ ### 2.6.0
421
+ - **`veto statusline` — a compact Veto line under any AI CLI prompt.** `veto statusline install` wires a `statusLine` command into Claude Code's settings.json (backed up; `uninstall` restores it byte-for-byte). The `print` hot path is read-only, fast, and crash-proof — it renders e.g. `⬡ veto GREEN · router 94% · claude 42% · mem 15` and degrades to a neutral `⬡ veto` if the DB is missing or locked. Lives in the CLI so every Veto user gets it in any terminal, not just the VS Code HUD.
422
+ - **`veto_snapshot` — one-call editor/HUD aggregate.** Returns `{ session, council, routerTop, rate, memoryCount, health }` in a single read-only call, so editor integrations (veto-vscode) can stop reading internal tables directly. Tool count is now **93**.
423
+ - **Stable read-contract versioning.** `veto.db` now stamps `PRAGMA user_version` (`VETO_DB_SCHEMA_VERSION`) on every open, so external readers can detect schema drift and degrade gracefully instead of silently blanking.
424
+
420
425
  ### 2.5.0
421
426
  - **`veto_drift_check` — compounding-error circuit breaker.** Scans the recent tool-call trace for consecutive failures, repeated error messages, and single-tool thrashing, then runs the `debugger` agent for a concrete recovery step. See [Compounding-Error Circuit Breaker](#compounding-error-circuit-breaker).
422
427
  - **Council calibration fixes.** Tightened the deterministic council's pattern triggers so they no longer false-fire on generic words (e.g. "server", "transport") or semver strings like `v2.5.0`, and removed stale hardcoded tool counts from agent reasoning.
@@ -438,7 +443,7 @@ Platform switching is manual — Veto surfaces which platform has budget remaini
438
443
 
439
444
  ## Project Structure
440
445
 
441
- Veto is a single MCP server (`src/server.ts`) that registers 92 tools, MCP Resources, and Prompts, then dispatches every tool call through a per-domain **handler registry** — there is no monolithic switch. Each domain owns a `HandlerMap` module under `src/server/handlers/`:
446
+ Veto is a single MCP server (`src/server.ts`) that registers 93 tools, MCP Resources, and Prompts, then dispatches every tool call through a per-domain **handler registry** — there is no monolithic switch. Each domain owns a `HandlerMap` module under `src/server/handlers/`:
442
447
 
443
448
  | Module | Tools | Domain |
444
449
  |---|---|---|
@@ -0,0 +1,31 @@
1
+ export interface StatuslineData {
2
+ verdict: 'GREEN' | 'YELLOW' | 'RED' | null;
3
+ routerPct: number | null;
4
+ platform: string | null;
5
+ ratePct: number | null;
6
+ memCount: number | null;
7
+ }
8
+ export declare function readStatuslineData(): StatuslineData;
9
+ export interface ComposeOptions {
10
+ color?: boolean;
11
+ ascii?: boolean;
12
+ }
13
+ export declare function composeStatusline(data: StatuslineData, opts?: ComposeOptions): string;
14
+ export declare function printStatusline(opts?: ComposeOptions): void;
15
+ export interface InstallResult {
16
+ ok: boolean;
17
+ message: string;
18
+ changed?: boolean;
19
+ backupPath?: string;
20
+ }
21
+ export declare function installStatusline(client?: string, opts?: {
22
+ force?: boolean;
23
+ dryRun?: boolean;
24
+ }): InstallResult;
25
+ export declare function uninstallStatusline(client?: string): InstallResult;
26
+ export declare function statuslineStatusInfo(client?: string): {
27
+ installed: boolean;
28
+ settingsPath: string | null;
29
+ sample: string;
30
+ };
31
+ //# sourceMappingURL=statusline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"statusline.d.ts","sourceRoot":"","sources":["../../src/cli/statusline.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,GAAG,QAAQ,GAAG,KAAK,GAAG,IAAI,CAAC;IAC3C,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB;AAqBD,wBAAgB,kBAAkB,IAAI,cAAc,CAuBnD;AA8DD,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAUD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,cAAc,EAAE,IAAI,GAAE,cAAmB,GAAG,MAAM,CAgCzF;AAGD,wBAAgB,eAAe,CAAC,IAAI,GAAE,cAAmB,GAAG,IAAI,CAQ/D;AAkCD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,SAAW,EAAE,IAAI,GAAE;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,OAAO,CAAA;CAAO,GAAG,aAAa,CA0DpH;AAED,wBAAgB,mBAAmB,CAAC,MAAM,SAAW,GAAG,aAAa,CA4CpE;AAED,wBAAgB,oBAAoB,CAAC,MAAM,SAAW,GAAG;IAAE,SAAS,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,CAY3H"}
@@ -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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"}