mcpField
V
Veto

Veto

本地服务
github.com开发工具44 周前更新

关于 Veto

Veto 是本地运行的 MCP 服务和命令行工具,为 AI 编码环境提供专家 Agent、代码与安全审查、记忆及工作流工具。它支持多种 AI 命令行客户端,并提供可通过宿主端或 MCP Sampling 使用 LLM 推理的确定性 Agent。

主要功能

  1. 0193 个 MCP 工具和 49 个专家 Agent
  2. 02代码、安全和依赖审查
  3. 03跨平台持久化记忆
  4. 04并行 Agent 执行与 Council 辩论
  5. 05自学习任务路由
  6. 06精简工具发现模式

适用场景

  1. 01审查代码并扫描安全问题
  2. 02安装前验证待用软件包
  3. 03协调专家 Agent 处理开发任务
  4. 04跨会话保留决策和上下文

MCP 相关

Veto 通过 MCP 服务提供 Agent、审查、记忆、路由和开发工具,可注册到支持的 AI 客户端;在可用时借助宿主 Agent 推理或 MCP Sampling。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"veto": {
"command": "npx",
"args": [
"-y",
"@jigyasudham/veto"
]
}
}
}
启动命令npx -y @jigyasudham/veto

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@jigyasudham/veto3.9.0

工具

还没有获取到工具列表

本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。

详细介绍

veto

npm version npm downloads license

93 个 Agent 工具。49 位专家。支持所有主流 AI 命令行工具。可自我学习。使用订阅服务不产生额外费用。

一个在本机运行的 MCP 服务,可通过你现有的订阅接入 Claude Code、Codex CLI、Gemini CLI、Antigravity CLI、Cursor、Windsurf、Zed 和 JetBrains — 为每个 AI 配备由专家 Agent 组成的顾问团、本地 LLM 支持、SDD Agent、Playwright 自动化、跨平台持久记忆、每记录 20 个任务结果便自动重新调整层级阈值的自学习路由器(评审会替你记录结果;可通过 auto_apply_learning 配置)、CI/CD 门禁、工作区发现功能,以及双向 IDE 通信。

账单说明:“零成本”适用于订阅计划(Claude Max、Gemini Advanced 等)。如果你使用按 API 调用量/令牌计费的方式,Veto Agent 执行的 LLM 推理(通过 Agent 工作循环或 MCP Sampling)会像其他调用一样计入你的令牌用量。veto init 会检测 API 密钥环境变量,并自动向你发出警告。


开始使用

# 1. Install the CLI — puts the bare `veto` command on your PATH
npm i -g @jigyasudham/veto

# 2. Register Veto with every AI client you use (Claude Code, Gemini, Codex, Cursor, …)
veto init

不想安装任何内容?所有命令也都可以通过 npx 运行:

npx -y @jigyasudham/veto@latest init

这两者经过有意设计,彼此独立。veto init 会写入 MCP 配置,使用 npx -y --package @jigyasudham/veto@latest veto-server 启动服务 — 每次客户端重启时,npx 都会从注册表重新解析 @latest,因此 MCP 服务会自动更新,全局安装的副本也不会将其固定在旧版本。全局安装仅提供命令行工具(veto doctor、veto sessions、状态栏等);当 veto doctor 提示版本过旧时,使用 npm i -g @jigyasudham/veto@latest 保持更新。


Agent 的工作方式

无需 API 密钥,不产生额外费用。 每个工作 Agent 的核心都是确定性专家模块,并可选叠加两层 LLM 推理 — 所有推理都交由你已经付费使用的 AI 完成。

默认 — 确定性专家模块

开箱即用时,42 个工作 Agent 中的每一个都以手写的专家模块(src/agents/ 中的 plan()/analyze())运行 — 不是 LLM。它们始终运行,可离线工作,且不消耗令牌。其深度因设计而异:分析 Agent(安全扫描器、密钥、依赖项审计、克隆检测器、隐私、身份验证、性能、兼容性等)会应用实际算法 — 正则表达式/AST 检测、OWASP/CWE 规则、基于哈希的克隆匹配 — 而规划 Agent(编码器、调试器、测试器等)则是结构化的专家操作手册:针对相应任务类别整理好的步骤、检查清单和易错点,旨在让你已经付费使用的 AI 对其进行推理,而不是由这些模块自行推理。

路径 A — Agent 工作循环(大多数客户端:Claude Code、Cursor、Windsurf)

Veto 会将专家的角色、评估标准和输出约定作为 llm_upgrade 提示词返回。宿主 AI 会以专家身份进行推理,并返回结构化 JSON 以完成操作。这是主要路径 — 除现有订阅费用外不产生任何费用,并且适用于所有客户端。

路径 B — MCP Sampling(支持 server.createMessage 的客户端)

支持 Sampling 时,同样的升级会在服务端完成,无需额外往返。注意:2026 年 7 月的 MCP 规范修订案将在整个协议范围内弃用 Sampling(设有 12 个月的过渡期),因此 Agent 工作循环(路径 A)是 Veto 的长期默认方案;在支持 Sampling 的地方,它仍会作为透明的优化方式保留。

由 7 个 Agent 组成的 Council 优先使用 LLM — 其价值在于多 Agent 辩论 — 但当没有可用的 LLM 路径时,也会回退到确定性结论。多个 Agent 同时运行时,会并行执行。


专家角色

**49 位专家:6 个领域中的 42 个确定性工作 Agent + 由 7 位成员组成的委员会。**委员会会在你开始构建之前讨论权衡取舍;工作 Agent 则负责实际分析和规划。每位专家都是可升级为大模型推理的确定性专家模块 — 参见Agent 的工作方式。随时使用 veto agents 列出他们。

委员会(7 位) Lead Dev · PM · Architect · UX · Devil's Advocate · Legal · Security

开发(12 位) Coder · Code Reviewer · Tester · Debugger · Refactor · Database · API · Frontend · Backend · DevOps · Performance · Migration

安全(6 位) Security Scanner · Auth Agent · Data Privacy · Secrets Agent · Dependency Audit · Penetration Tester

记忆(5 位) Context Manager · Decision Logger · Project Mapper · Pattern Learner · Knowledge Base

研究(7 位) Researcher · Tech Advisor · Cost Analyzer · Competitor Analyzer · Risk Assessor · Estimator · Ethics & Bias

质量(5 位) Code Quality · Documentation · Accessibility · Compatibility · Error Handling

工作流(7 位) Task Planner · Task Coordinator · File Manager · Git Agent · Search Agent · Reporter · Automation


MCP 工具(93 个)

类别工具
会话veto_status · veto_session_save · veto_session_restore · veto_sessions_list · veto_autosave_status · veto_session_replay
路由器veto_route_task · veto_rate_status
委员会veto_council_debate · veto_benchmark · veto_adr
Agentveto_agent_plan · veto_execute_parallel · veto_explain · veto_compose_agents · veto_delegate
审查veto_code_review · veto_security_scan · veto_secrets_scan · veto_diff_review · veto_full_review · veto_pr_review
流水线veto_ci_gate · veto_pre_commit · veto_new_feature · veto_workflow · veto_task_parse
高级veto_local_llm · veto_semantic_search · veto_sdd_agent · veto_playwright · veto_notify_ide
质量veto_clone_detector · veto_lint_rules · veto_api_contract · veto_a11y_advisor · veto_type_coverage · veto_test_gaps
顾问veto_dep_advisor · veto_dep_verify · veto_query_advisor · veto_bundle_advisor · veto_dead_code · veto_hitl_checkpoint · veto_drift_check
监控veto_watch · veto_watch_poll · veto_watch_stop
记忆veto_memory_store · veto_memory_search · veto_memory_delete · veto_decisions · veto_project_map_update · veto_project_map_get · veto_pattern_store · veto_patterns_list · veto_memory_export · veto_memory_import
学习veto_record_outcome · veto_learning_stats · veto_learning_apply
交接veto_handoff · veto_continue · veto_platform_setup
可观测性veto_usage_status · veto_audit_log · veto_health · veto_metrics · veto_snapshot
发现veto_discover · veto_summarize · veto_git_blame · veto_changelog · veto_onboard · veto_debt_register
开发工具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
插件veto_plugins

精简模式 — 93 个工具,不再占用上下文

93 个工具架构会在用户输入任何内容之前,占用客户端约 20K 个上下文 token。精简模式提供的接口小 5–6 倍:七个核心工具(veto_status、veto_session_save、veto_session_restore、veto_route_task、veto_council_debate、veto_memory_search、veto_record_outcome),以及两个元工具——veto_find_tools 按关键词搜索完整目录,并按需返回匹配的架构;veto_call 按名称调用目录中的任意工具。在两种模式下,每个工具仍都可直接调用;精简模式只改变预先公布的工具。

在 MCP 服务配置的 env 中设置 VETO_COMPACT=1,或在 ~/.veto/config.json 中设置 "compact_tools": true,即可启用:

{
  "mcpServers": {
    "veto": {
      "command": "npx",
      "args": ["-y", "--package", "@jigyasudham/veto@latest", "veto-server"],
      "env": { "VETO_COMPACT": "1" }
    }
  }
}

依赖项幻觉防护

大模型会提出看似合理但实际不存在的软件包名称,而攻击者会在公共注册表中注册这些名称(slopsquatting)——这是一类供应链攻击,在大多数 AI 工作流中都没有安装前检查。veto_dep_verify 会在安装之前,先对照实时注册表检查每个拟议的软件包:

veto_dep_verify { packages: ["axios", "axois", "left-padd"], ecosystem: "npm" }
→ axios      verified    (14 years old, 40M downloads/month)
→ axois      HIGH_RISK   (1 edit from "axios" — possible typosquat)
→ left-padd  NOT_FOUND   (likely hallucinated — do NOT retry the install later:
                          nonexistent AI-suggested names are prime slopsquat targets)

每个软件包的信号:注册表中是否存在、存在时长、月下载量、版本历史、弃用状态,以及与热门软件包的拼写距离。支持 npm、PyPI 和 crates.io。网络故障会返回 unverifiable——绝不会默默判定为安全。

决策漂移强制执行

AI 助手会忘记架构决策,并在几次会话之后重新讨论这些决策——这是长期运行的 AI 项目中最常见的抱怨。Veto 的记忆不只是存储决策,还会强制执行这些决策。将决策记录为机器可检查的约束,一次即可:

veto_decisions {
  action: "add",
  rule: "We use Postgres — no Mongo",
  why: "Decided 2026-05: relational data, team expertise",
  forbidden_patterns: ["mongoose", "mongodb"],
  severity: "block"
}

此后,veto_diff_review 和 veto_ci_gate 会自动拦截新增行匹配禁用模式的任何差异——如果 AI 在几次会话后悄悄将 mongoose 添加到导入中,审查就会失败,并附上规则和理由。模式是不区分大小写的正则表达式(并支持子字符串回退),可选按文件 glob(src/**/*.ts)限定范围,可按项目或全局应用,严重级别为 block 或 warn。通过 action: list / check / disable / enable 管理。

你不必记得这样做。当评议会裁决(由大模型支持的裁决)或 ADR 确定某项决策后,其结果会附带一次性的 constraint_invitation:你的 AI 会询问一次是否应将其设为规则,并将你的回答作为 add 或 decline 连同 invitation_id 一起传回。对于同一项裁决,它绝不会询问两次。action: list 会显示已发出、已接受和已拒绝的邀请数量;此计数只保存在你的机器上。

规则不能拖住你的审查。add 会拒绝可能导致检查挂起的模式:长度超过 200 个字符,或重复组自身也会重复的模式,例如 (a+)+。每次检查也都有时间限制,因此缓慢的规则会转为警告,而不是阻止 veto_ci_gate。

错误累积断路器

Agent 可能会在循环中悄无声息地失败——重试同一个出错的调用、反复遇到同一个错误、在两个工具之间来回切换——直到有人发现时,整个会话已被耗尽。veto_drift_check 会在运行过程中扫描近期的工具调用轨迹,检测此类模式,并在问题不断累积之前触发断路器:

veto_drift_check
→ DRIFT DETECTED
  • 4 consecutive failed calls (veto_diff_review)
  • same error repeated 3× ("no diff provided")
  • tool veto_route_task called 6× in a row
→ remediation (debugger agent): stop retrying; the diff is empty —
  point at a project_dir with uncommitted changes or pass `diff` explicitly.

它会检测三种漂移信号——连续失败、重复错误消息和单一工具反复调用;任一信号触发时,它都会让 debugger Agent 检查调用轨迹并给出具体的恢复步骤,而不是放任循环继续。在长时间运行的 Agent 工作流中,可将其作为定期检查点调用。

我应该使用哪个工具?

有些工具在设计上存在功能重叠(粒度或入口点不同)。快速指南:

审查代码

你有……使用备注
一段代码或单个文件veto_code_review不要用 veto_diff_review,它读取的是 git diff
未提交或已更改的文件(git diff)veto_diff_review并行扫描代码、安全性和密钥
为提交设置门禁(发现密钥时硬性阻止)veto_pre_commit针对提交时使用进行了优化
为 CI 设置门禁(退出代码 + 通过/警告/失败)veto_ci_gate适用于 GitHub Actions / GitLab CI
更深入的合并前/发布前检查(含质量检查)veto_full_review比 veto_diff_review 更全面
通过编号/URL 指定 GitHub PRveto_pr_review获取差异,并返回可直接发布的评论

记住信息

想要……使用
保存/找回解决方案、决策或参考资料veto_memory_store / veto_memory_search
跟踪反复出现的代码规范veto_pattern_store / veto_patterns_list
无需扫描文件系统即可浏览代码库veto_project_map_get(通过 veto_project_map_update 刷新)

运行多步骤任务

想要……使用
针对一项任务同时运行多个 Agentveto_execute_parallel
运行带有通过/失败门禁的顺序工作流veto_workflow
将 PRD / 自然语言转换为任务 DAGveto_task_parse(为 veto_workflow 提供输入)
端到端规划新功能(评审会 → 计划 → 任务)veto_new_feature

会话

想要……使用
使用完整的已保存上下文恢复工作veto_session_restore(或使用 veto_continue 恢复最新会话)
查看会话的事件/工具调用时间线veto_session_replay
将工作移交给其他 AI 工具veto_handoff → veto_continue

MCP 资源

URI返回内容
veto://sessions各平台上保存的所有会话
veto://project-map?dir=<path>已存储的项目结构图
veto://memory?q=<query>知识库搜索结果
veto://patterns已学习的编码模式

MCP 提示词

提示词功能
code-review完整的代码审查——粘贴代码,获取带评分的问题发现
security-auditOWASP Top 10 扫描,并附 CWE 参考信息
deploy-checklist发布前由评审会审查你的部署计划
explain-file专家讲解任意文件,并根据类型自动路由

CLI 命令

这些命令可在任何终端中独立运行——无需 AI 客户端。裸命令 veto 来自全局安装(npm i -g @jigyasudham/veto,参见快速开始);如果没有全局安装,请在任意命令前加上 npx -y @jigyasudham/veto@latest。

veto init                        # Register Veto with every AI app found + scan project
veto doctor                      # Per app: does it list Veto, does Veto start, has the app started it?
veto doctor --quick              # Same, without launching the server to test it
veto doctor --fix                # Also move aside old Veto guides left in Codex/Gemini files
veto status                      # Version, DB path, session/memory/outcome counts
veto version                     # Alias for veto status
veto sessions [words]            # Newest 20 saved sessions, and how many exist ([auto] = auto-save)
veto sessions --all | --limit N  # All of them, or N; add --json for machine output
veto sessions --clean            # Remove auto-saves older than 7 days
veto continue <id> --as <client> # Restore a session from a terminal (8-character id prefix is enough) —
                                 #   the same code as veto_continue, for an app that did not load Veto
veto memory [query]              # Search knowledge base (blank = all entries)
veto patterns [prefix]           # List learned agent/routing patterns
veto tools [filter]              # List all 93 MCP tools (--json for machine output)
veto agents [filter]             # List all 49 specialists — workers + council (--json)
veto routing [status|log|reset]  # Inspect the opt-in routing feedback loop
veto transcripts <sub>           # Opt-in transcript capture (off by default) —
                                 #   enable|status|sources|list|show|purge|disable
veto lessons <sub>               # Opt-in note sharing between your AIs (off by default) —
                                 #   on|status|list|why|forget|flows|off|exclude|include|alias|recheck
veto statusline <sub>            # Veto line under the Claude Code prompt, or beside
                                 #   Codex/Gemini — install|status|print|watch|uninstall
veto api <command>               # JSON for editor extensions — version|snapshot|recall search|
                                 #   recall expand|diagnostics (see "For editor extensions" below)
veto hook install                # Install pre-commit secrets scan hook
veto hook remove                 # Remove the veto pre-commit hook
veto check                       # Scan staged changes for secrets (used by hook)
veto help                        # Commands + MCP tools reference
veto help --troubleshoot         # Full troubleshooting guide
veto doctor
veto doctor

  Veto Doctor — system health check
  ─────────────────────────────────────────────────────
  ✓ Node.js v22.13.0 (this terminal)
  ✓ ~/.veto exists
  ✓ Database ~/.veto/veto.db
    17 sessions · 12 memories · 3 patterns

  AI apps — registration · launch test · last start
  ─────────────────────────────────────────────────────
  ✓ Claude Code — connected
      source: claude mcp list
      launch test: answered in 1.2 s — Veto 3.7.0, 93 tools
      last started by claude-code 2.1.0 3 h ago — Veto 3.7.0, Node v22.13.0
  ✗ Antigravity — Veto is only in ~/.gemini/antigravity-cli/mcp_config.json, a file Antigravity no longer reads
      fix: veto init   (then fully restart the app)
  · Gemini CLI — not installed

  Fallback guidance — what an AI is told when Veto did not load
  ─────────────────────────────────────────────────────
  ✓ ~/.claude/skills/veto/SKILL.md

  ⚠  1 issue found. Each has its fix above.

每个 ✓ 都会说明其依据。注册状态是应用自己的 mcp list 报告的内容(如果应用的 CLI 不在 PATH 中,则以应用读取的文件为准)。启动测试会运行准确配置的命令并完成 MCP 握手,因此可以发现 npx 无法访问注册表,或服务启动后立即退出的问题。上次启动的信息来自服务本身:每次应用启动 Veto 时,Veto 都会记录是哪个应用、使用哪个 Node,以及 SQLite 是否在该应用的运行时中加载(~/.veto/host-starts.json)。这是唯一能发现 GUI 应用启动 Veto 时使用的 Node 与终端中的 Node 不同的检查。veto doctor 发现问题时会以状态码 1 退出,因此脚本可以依赖这一行为。

如果 AI 所用的应用未加载 Veto, Veto 的 veto 技能(由 veto init 写入 Claude Code、Codex 和 Antigravity/Gemini 技能文件夹)会指示它说明这一点,并改用 veto continue / veto sessions / veto doctor,而不是手动读取 Veto 的数据库。

此版本之前的 veto init 会将 Veto 指南写入 ~/.gemini/GEMINI.md(Gemini 自己的记忆文件),以及 ~/.codex/AGENTS.override.md(Codex 会读取此文件,而不是你的 ~/.codex/AGENTS.md)。当前版本绝不会写入这两个文件。veto doctor 会报告任何残留副本,而 veto doctor --fix(或 veto init)会将副本重命名为 *.veto-backup——但仅当文件内容完全是 Veto 提供的指南时才会这样做。如果文件中还有其他内容,例如 Gemini 保存于指南下方的记忆,则只会报告,不会触碰。旧版 init 覆盖的内容无法恢复。

面向编辑器扩展:veto api

显示 Veto 状态的扩展应通过 veto api 读取状态,而不是打开 Veto 的数据库。每个响应都是 stdout 上的一个 JSON 信封(包含 contract、command、backend_version、state,以及在 state 不为 ok 时包含 message / next_action)。其结构的版本独立于 Veto。在 contract 1 中,只会新增字段,因此可以忽略不认识的字段。

命令请求返回内容
version—contract 版本、命令、CLI 的路径、SQLite 是否已加载
snapshot{ project, db? }捕获状态、该项目的归档数量、课程分享情况及数量、试用进度。只读,并返回数量而非路径
recall search{ project, query, limit?, source?, db? }该项目已归档聊天中的屏蔽后匹配结果,以及匹配聊天的片段
recall expand{ project, event_id } 或 { project, archive_id, segment_index }单轮或单个片段的屏蔽后文本,仅当其属于该项目时返回
diagnostics{ checks?: ["host_cli", "probe"], db? }veto doctor 的逐应用检查结果。耗时较长的检查仅在指定时运行

通过 stdin 发送 JSON 请求,并使用参数数组且不调用 shell 来启动 CLI:execFile(process.execPath, [cliPath, 'api', 'recall', 'search', '--stdin']),其中 cliPath 来自 veto api version。在 Windows 上,veto 是只能由 shell 启动的 .cmd 垫片;通过 shell 传递搜索查询会将其变成命令行。project 始终为必填项;如果 db 不是 Veto 使用的数据库,将拒绝请求并返回 db_mismatch,而不会从错误的数据库中作答。关闭捕获后保留的归档仍可搜索,每个响应都会说明捕获处于什么状态。使用 veto transcripts purge 删除这些归档。JSON Schema 和响应示例随软件包一起发布,位于 contracts/api-v1/ 下。

veto statusline

在 Claude Code 中,veto statusline install 会在提示词下方添加一行 Veto 信息:最新的议会裁决、路由器置信度、实时上下文和速率限制使用情况,以及记忆大小。启用笔记共享时,还会显示 Veto 持有的笔记数量(notes 178);关闭共享时,则会省略此计数,而不是显示为 0。

Codex 和 Gemini 无法运行自定义状态栏——它们各自只显示内置项目(Codex:openai/codex#20244)。因此,这一行会在 AI 旁边的小型分屏窗格中运行,并跟随当前文件夹中的会话:

veto statusline watch                    # follows whichever AI is working in this folder
veto statusline watch --client=codex     # or pin one: claude | codex | gemini
veto statusline install --client=codex   # prints the split-pane setup for your terminal; writes nothing

对于 Codex,它会从 Codex 自己的会话文件中读取上下文和速率限制使用情况;Gemini 不会记录使用数据,因此其状态栏只显示实时会话,不显示仪表数据。veto statusline print --client=codex 会打印一行信息,可用于 tmux 状态栏或脚本。


议会辩论

两阶段流程——无需 API 密钥,可在 Claude Code、Gemini CLI、Antigravity CLI 和 Codex CLI 上运行:

# Phase 1 — call with task, get instant deterministic result + LLM upgrade prompt
veto_council_debate {
  task: "migrate auth from sessions to JWTs",
  project_dir: "/your/project",
  strictness: "standard"
}
→ {
    llm_backed: false,
    final_verdict: "YELLOW",
    votes: { lead_dev: {...}, architect: {...}, security: {...}, ... },
    llm_upgrade: {
      available: true,
      instruction: "Read debate_prompt, reason as all 7 agents, call again with agent_responses",
      debate_prompt: "You are running a Veto Council debate. Analyze the task as each specialist..."
    }
  }

# Phase 2 — reason as all 7 agents, pass responses back → get LLM-backed verdict
veto_council_debate {
  task: "migrate auth from sessions to JWTs",
  agent_responses: {
    lead_dev:  { verdict: "warn",    reason: "Stateless JWTs complicate logout — need blocklist", concerns: ["Refresh token rotation must be atomic"], recommendation: "Use short-lived access tokens (15m) + httpOnly refresh tokens" },
    pm:        { verdict: "approve", reason: "JWT migration unblocks mobile clients", concerns: [], recommendation: "Ship behind a feature flag, roll back if logout issues" },
    architect: { verdict: "approve", reason: "Good fit for stateless microservice boundary", concerns: ["Clock skew can break expiry across services"], recommendation: "Add NTP sync check; use relative expiry not absolute timestamps" },
    ux:        { verdict: "approve", reason: "No user-visible change if migration is seamless", concerns: [], recommendation: "Silent migration — no logout required for existing sessions" },
    devil:     { verdict: "warn",    reason: "What if the refresh token store goes down at 2AM?", concerns: ["Redis outage = all users logged out"], recommendation: "Fallback to session auth if Redis is down; use short rotation window" },
    legal:     { verdict: "approve", reason: "JWTs are industry standard, no new compliance risk", concerns: [], recommendation: "Document token storage in privacy policy" },
    security:  { verdict: "warn",    reason: "Refresh token rotation must be atomic — TOCTOU risk", concerns: ["localStorage storage of access token is XSS-vulnerable"], recommendation: "Store access token in memory only; refresh token in httpOnly Secure SameSite=Strict cookie" }
  }
}
→ {
    llm_backed: true,
    final_verdict: "YELLOW",
    warnings: ["Refresh token rotation must be atomic...", "What if the refresh token store goes down..."],
    recommended: "Proceed with JWT. Use httpOnly cookies for refresh tokens, memory-only for access tokens..."
  }
议会的 strictness
veto_council_debate { task: "...", strictness: "fast" }     # 3 agents, instant
veto_council_debate { task: "...", strictness: "standard" } # 7 agents, default
veto_council_debate { task: "...", strictness: "strict" }   # 7 + devil rebuttal

会话标记与搜索

veto_session_save {
  auto_summarize: true,
  tags: ["auth", "jwt", "middleware"]
}

veto_sessions_list { query: "auth" }
→ sessions matching "auth" in summary, context, tags, or project_dir

Token 使用量需手动报告——将 token_count 传给 veto_status 或 veto_session_save,Veto 就会按平台、按天存储。veto_rate_status 会显示你报告的用量;不会自动统计任何数据。


工作区发现

veto_discover { "project_dir": "/your/project" }
→ {
    git:        { branch: "main", commit: "a3f2b1", dirty_files: [], recent_commits: [...] },
    ecosystems: { node: "my-app v2.1.0" },
    tech_stack: ["TypeScript", "React", "Prisma"],
    key_files:  ["tsconfig.json", "prisma/schema.prisma", ".env.example"],
    total_files: 142
  }

差异审查

veto_diff_review { project_dir: "/your/project" }
→ {
    verdict: "warn",
    files_changed: 4,
    code_review: { score: 78, critical: 0, high: 2, findings: [...] },
    security:    { score: 91, critical: 0, high: 0, findings: [...] },
    secrets:     { findings: [] },
    summary: "⚠️  WARN — 4 file(s) changed..."
  }

顺序管道

veto_workflow {
  steps: [
    { id: "code",     agent: "coder",           task: "implement auth middleware", gate: 70 },
    { id: "review",   agent: "reviewer",         task: "review the implementation", gate: 75 },
    { id: "security", agent: "security-scanner", task: "scan for vulnerabilities",  gate: 80 },
    { id: "test",     agent: "tester",           task: "write test cases" }
  ],
  project_dir: "/your/project"
}
→ { verdict: "passed", steps_passed: 4, steps_failed: 0, results: [...] }

自学习路由器

每个 Agent 工具完成时都会自动记录质量信号。每次工作会话结束后,veto_learning_stats 会显示实时数据,而 veto_learning_apply 会在约 20 次调用后自动调整层级阈值。

此循环还会隐式地自我反馈:veto_learning_stats 会从工具调用轨迹中挖掘无人手动记录的信号——由 Agent 支持的工具返回错误,或同一会话中在几分钟内重新运行相同的分析工具(这通常意味着第一次的回答未能满足需求)——并自动将其记录为低质量结果。

veto_route_task { task: "debug auth issue", file_ext: ".ts" }
→ { ..., recommended_agent: "debugger" }   # ← predicted from history

插件系统

// ~/.veto/agents/my-agent.js
export function plan(task, context) {
  return {
    agent: 'my-agent', task, tier: 2,
    approach: 'Your custom approach...',
    steps: ['Step 1', 'Step 2'],
    checklist: ['[ ] Check 1'],
    pitfalls: ['Pitfall 1'],
    patterns: ['Pattern 1'],
    duration_estimate: '1-2 hours',
  };
}

跨平台交接

Claude at 90%  →  veto_handoff { summary, context }
Open Gemini    →  veto_continue { resuming_as: "gemini" }
Full context restored. Continue exactly where you stopped.

平台切换需手动进行——Veto 会通过 veto_rate_status 显示哪些平台还剩余可用额度,你可以自行决定何时切换。

平台支持情况
Claude Code✅ 原生 MCP
Gemini CLI✅ 支持 MCP
Antigravity CLI✅ 支持 MCP
Codex CLI✅ 支持 MCP
Cursor✅ 支持 MCP
Windsurf✅ 支持 MCP
Zed✅ 支持 MCP(context_servers)

会话转录捕获(可选启用)

veto_session_save 会写入一份约 1k 个 token 的摘要。这足以恢复会话,却不足以回答 “三周前,我们究竟得出了什么结论?是什么时候?” 转录捕获会保留摘要舍弃的细节,并让这些内容可供搜索——无需 API 密钥、无需按查询付费,也不会有任何内容离开你的设备。它由元数据目录和基于纯 SQLite 构建的可移植 BM25 索引组成——不依赖 FTS5,因此适用于所有受支持的 Node 版本;再结合本地语义搜索,并由你的 AI 负责重排。

⚠️ 启用前请阅读

Veto 会复制 AI 客户端自身的对话记录。 保存时,Veto 会将宿主 CLI 的转录文件逐字节存档到自己的本地存储中——包括你发送的每条消息、收到的每条回复以及所有工具活动。

  • 副本独立存在。 原始文件绝不会被修改,但 Veto 的副本会比它保留得更久。清除 AI 客户端的历史记录,或客户端轮换自己的日志,都不会删除存档。只有运行 veto transcripts purge 或等待保留期限结束才会删除。
  • 会话中的内容都会被一并保存。 密钥、客户数据、第三方信息——只要你粘贴过,就会出现在存档中。检测到的密钥会在所有 AI 可读取的位置被屏蔽,但磁盘上的原始存档属于私人数据。请像对待 shell 历史记录一样对待它。
  • 仅限本地。 不会上传或共享任何内容。存档目录会刻意避开云同步文件夹;若检测到同步路径,系统会将其标记出来。
  • 默认关闭,需你主动启用。 默认禁用捕获。运行 veto transcripts enable 会完整显示此声明并记录带版本号的同意;如果声明有重大变更,系统会再次征求你的同意。
veto transcripts enable          # Opt in — prints what/where/retention, records consent
veto transcripts status          # State, archive dir, retention, disk usage
veto transcripts sources         # Per-CLI: where sessions live + what Veto can see
veto transcripts list            # Archived sessions
veto transcripts show <id>       # One session's table-of-contents + facts (any AI's session id)
veto transcripts purge <id>      # Delete an archive (also --project=<dir> | --all; --source=codex to narrow)
veto transcripts disable         # Stop capturing (existing archives are kept)
支持 Claude Code、Codex CLI、Gemini CLI 和 Antigravity CLI

这四种 CLI 都通过同一套流程捕获和回忆,各自使用对应的格式适配器,而且 Veto 会自行识别当前运行的宿主——MCP 握手会标明宿主,因此不依赖 AI 正确报告。保存时,Veto 会在磁盘上查找各宿主的会话文件(安装了 Claude Code 状态栏时,它也会实时报告会话)。无论宿主如何记录项目文件夹,都能匹配——例如,Gemini 将保存到 D:\Veto 的文件夹记录为 d:\veto。Antigravity 的对话会通过 Antigravity 自身的对话索引与项目匹配;Veto 以只读方式打开该索引。 veto transcripts sources 会准确显示各宿主可访问的内容;如果保存时没有存档任何内容,响应会说明原因。

每个适配器都是基于真实转录内容而非文档编写的,因此解决了两个格式陷阱:Codex 会在两个并行流中记录每条消息,而 Gemini 的聊天日志每次增长时都会追加一份消息副本。否则,这两种情况都会导致同一条消息在索引中出现多份。

回忆通过 veto_session_replay 以两次调用的循环运行——先搜索,再展开:

{ query: "npm E404 publish" }   →  table-of-contents + top hits with snippets
{ expand: { event_id: 412 } }   →  the exact lines, masked, with a turn + timestamp citation
不必询问,直接使用过往会话

只有 AI 想到去查找历史记录时,回忆功能才有帮助,但大多数时候它并不会主动查找。因此,对于历史记录会影响答案的工具,Veto 会自动附上所有已存档聊天中的相关内容,无论对话当时使用的是哪种 AI:

  • veto_continue / veto_session_restore 会列出已保存会话背后的聊天记录(例如,一段 Codex 聊天和两段 Claude Code 聊天),以及每段聊天最后提出的问题。
  • veto_memory_search 会在已存储的记忆旁返回过往聊天中的匹配摘录。
  • Veto 交给模型的每条提示词——包括 Agent 工具和 council——都会附带最多三段相关摘录。

只有当摘录属于对话内容(而非工具载荷)且与问题至少有两个词相同时,才会附加该摘录;关闭捕获时不会附加任何摘录。摘录会标记为历史数据,而非指令;确定性分析器永远不会收到这些摘录,因此旧摘录不会变成分析结果。

语义回忆——找回你记不太清的内容

关键词搜索无法回答你真正想问的问题。你记得的是当时做了什么决定,而不是文档中写下来的用词——所以搜索“为什么上传失败”永远找不到那条写着“凭据已过期”的记录。

Veto 不仅搜索词语,也搜索含义。每条捕获的事件都会拆分为相互重叠的窗口,并在本地生成嵌入;查询也以同样的方式生成嵌入,然后融合关键词和语义这两种排名,避免任何一方压过另一方。像 E404 这样的精确标识符仍会排在第一位,而查询和答案没有共同词汇时,也仍然能找到答案。

所有操作都在你的机器上完成。 无需 API 密钥,没有单次查询费用,文本不会离开磁盘,并且可以离线使用。实现这一点的代价是:作为常规依赖安装一个 7 MB 的嵌入表:

  • 由 npm 的共享缓存每台机器只下载一次,而非每个项目各下载一次。
  • 无论是否启用转录捕获,Veto 都会附带此嵌入表。这是这种设计必须付出的代价:固定使用不可变的软件包,意味着已发布版本中的字节永远不会变化;同时也省去了按需获取模式所需的运行时下载、校验和镜像机制。
  • 仅在首次语义查询时延迟加载,启动时绝不加载。 如果文件缺失或损坏,搜索会静默回退为仅使用关键词,Veto 仍可继续工作。

该表由 Minish Lab 提供,为 potion-base-8M(MIT),由 baai/bge-base-en-v1.5 蒸馏而来,并重新打包为 int8。它是静态查找表,而非神经网络:查询时不会运行模型,因此搜索只需几毫秒。推理代码由 Veto 自行提供。

在你的各个 AI 之间共享笔记(自愿加入,试用阶段)

Claude、Codex 和 Gemini 都会在各自的记忆中保留笔记:Claude 的项目专属记忆文件夹、~/.codex/AGENTS.md、~/.gemini/GEMINI.md。每个 AI 都会学到一些东西,但其他 AI 永远无从知晓;同一条经验会在两个项目中被学两遍。Veto 会读取这些笔记,并在有帮助时共享:在你的各个项目之间,以及在你的各个 AI 之间。

⚠️ 启用后意味着什么
  • **在你的各个项目之间:**你在一个项目中工作时写下的、关于你或这台电脑的笔记,可能会共享到你的其他项目中。
  • **在你的各个 AI 之间:**Claude 写下的笔记可能会传给 Codex 和 Gemini,反之亦然。交给某个 AI 的笔记会作为对话的一部分发送给该 AI 所属的公司,就像你发送的其他内容一样。
  • **只读。**Veto 绝不会更改或删除 AI 的记忆文件。它会在自己的本地数据库中保存每条笔记的副本,并在保存前移除电子邮件地址、你的主文件夹路径,以及任何看起来像密码或密钥的内容。Veto 本身不会上传任何内容。
  • 只有你明确同意后才会启用。veto lessons on 会显示此说明,并要求你在自己的终端中输入 yes。如果由 AI 运行该命令,操作会被拒绝,因此任何 AI 都无法替你开启共享。升级永远不会开启共享;如果共享的内容发生实质性变化,系统会再次征求你的同意。
  • **目前处于试用阶段。**Veto 目前不会把任何笔记提供给 AI。开启共享不会启动其他操作:只有你亲自运行 veto lessons trial,才会启动单独的试用流程;该流程可以记录 Veto 本来会提供给你的 Codex 会话的笔记,并会先征求你的同意;请参阅试用。在 Veto 开始向你的 AI 提供笔记之前,它会再次征求你的同意。

大多数笔记都不会离开其所属项目。如果笔记与该项目有关,或包含命令、网址、凭据,或要求获取、发送或运行内容的指示,它就会留在原处;涉及秘密或个人信息的笔记绝不会离开其所属项目。只有关于你的笔记(Claude 的 user 和 feedback 笔记、CLI 的全局指令)或关于这台电脑的笔记(其 shell、控制台或网络)才可能被共享。共享的笔记会标记为来自另一个 AI 会话的信息,绝不会作为指令。

veto lessons on                  # Read the disclosure; type yes to accept (your own terminal only)
veto lessons trial               # The trial: its lists and progress; starts it when you type yes (your own terminal only)
veto lessons trial ignore [dir]  # Before it starts: record sessions in this project as skipped (also: use [dir], clear)
veto lessons                     # Status: notes found, how many may travel, anything switched off, and the trial so far
veto lessons list                # Every note Veto has read, by project (--shared, --held, --scope=, --source=, --json)
veto lessons why <id>            # One note: who wrote it, when, why it stays or travels, where it may go
veto lessons flows               # Where each AI's notes may go, per project
veto lessons forget <id>         # Stop one note for good, with its copies in your other checkouts
veto lessons exclude [dir]       # Keep a project out entirely: nothing leaves it, nothing enters it
veto lessons include [dir]       # Undo exclude: the project's notes are read again
veto lessons alias               # Memory on a drive that isn't plugged in: suggests the command that links it
veto lessons recheck <ai>        # Read an AI's memory again after Veto stopped because its format changed
veto lessons off                 # Turn sharing off and delete everything Veto copied, trial records included
保存时自动收集

开启共享后,每次执行 veto_session_save 时,都会重新读取各个 AI 的记忆,并记录发生的变化,因此 AI 今天写下的笔记无需你运行任何操作就能被收集。未发生变化的文件只需检查一次大小和日期,这会使保存过程增加约 20 ms。每次检查最多持续 150 ms,未检查到的内容会留待下次保存处理,而且绝不会导致保存失败。开启共享时会一次性读取所有内容;veto lessons 命令则始终会检查每个文件。若要仅停止保存时的检查,请在 ~/.veto/config.json 中将 lessons.harvest_on_save 设为 false。

试用

在 Veto 将任何笔记提供给 AI 之前,必须先证明它准备提供的笔记真实且有用。试用就是为此而设:记录 Veto 本来会提供哪些笔记,但不实际提供。试用需要单独选择加入:开启共享不会启动试用。

  • 选择项目(可选): 开始前,使用 veto lessons trial ignore <dir> 将该项目的会话记录为已跳过;使用 veto lessons trial use <dir> 则仅将你列出的项目计入。veto lessons trial clear 会清空这两个列表。项目根据其 git 历史进行匹配,因此同一项目的每个检出版本都视为相同;没有 git 的文件夹则根据路径匹配。任何人(包括你的 AI)都可以设置这些列表,它们仅保存在你的 ~/.veto/config.json 中。

  • 开始: veto lessons trial 会显示试用记录的内容和两个列表;只有当你在自己的终端中输入 yes 后,试用才会开始。AI 无法代你启动。试用运行后,列表便无法更改。

  • 停止条件: 满 10 周,或已选出 12 条笔记时停止,以先达到者为准。

  • 计入条件: 项目中有可供选择的笔记的 Codex 会话。会将会话的首个请求与该会话开始时 Veto 持有的笔记进行匹配,因此之后收到或更改的笔记不计入。子 Agent 不会重复计数。被忽略项目中的会话会记录为已跳过:其消息不会被使用,也不会为其选择笔记。Claude Code 会话不属于本次试用:Claude 已会加载其自身项目的笔记,因此几乎没有额外内容可添加。

  • 你需要做的事: 在有笔记的项目中使用 Codex 完成实际工作,并在每次会话开始时妥善描述任务,因为笔记就是根据这项描述进行匹配的。

  • 你会看到的内容: veto lessons 和 veto lessons trial 会显示试用进展。如果连续多个会话都没有产生任何请求,系统也会发出警告;这很可能意味着 Codex 更改了格式,而非没有合适的笔记。

    Trial:        day 18 of 70 · 4 of 12 notes chosen
                  23 Codex sessions counted · 3 with notes chosen · 20 with none that fitted · 9 skipped
    
  • 记录由你掌管: 记录会保留在你的设备上,Veto 不会收集任何内容。veto lessons off 会将其删除。如果启用了转录捕获,已完成且计入试用的会话也会归档,其中包括你从未使用 Veto 保存的 Codex 会话,以保留每次选择所依据的证据。

  • 决定是否交付: 在 Veto 作者自己的设备上,根据任何记录开始前就已撰写并封存的规则进行试用。试用结束后,由一名独立的 AI 评审员对每条已选笔记进行一次评分,评估它与对应会话后续操作的契合度。如果笔记并未明确展现真实性和实用性,就不会发布交付功能。如果展现了,便可以设计交付功能;在任何笔记提供给 AI 之前,Veto 都会再次征求每位用户的同意。

从 3.6.0–3.8.0 升级

共享功能会保持开启,不会再次征求你的同意。这些版本在你接受共享时会自动启动试用;3.9.0 会在升级时停止试用,除非你自行使用 veto lessons trial 启动新的试用,否则不会再记录任何内容。旧试用记录会保留,并在 veto lessons 中显示为“Trial 1: ended”;veto lessons off 仍会将其删除。

从 3.5.0 升级

3.6.0 会再次征求你的同意,因为 3.5.0 的说明称 Veto 不会推断它会提供哪些笔记,而试用正是为此而设。在你于自己的终端运行 veto lessons on 并接受之前,共享功能会暂停:不会读取任何内容,保存时收集笔记的功能会停止,试用也不会启动。Veto 已持有的笔记会保留。


发布说明

3.9.0
  • 现在需要由你主动启动笔记试用。 过去,接受共享后,每台开启共享的电脑都会自动开始试用,尽管试用中的任何内容都不会离开电脑。现在,veto lessons trial 会显示试用记录哪些内容,并且只有当你在自己的终端中输入 yes 时才会启动;AI 无法替你启动。启动前,使用 veto lessons trial ignore <dir> 和 use <dir> 选择计入哪些项目。忽略项目中的会话会记录为已跳过,不会为其选择任何内容。试用会在 10 周或选出 12 条笔记后停止。请参阅试用。
  • 如果你在 3.6.0–3.8.0 中开启了共享: 共享会保持开启,不会出现新的询问,因为同意文本只是移除了自动开始试用的承诺。升级后,该试用会停止。其记录会保留,并显示为“Trial 1: ended”;veto lessons off 仍会删除这些记录。
  • 错误修复:试用已结束后,veto doctor 仍提示会在下次保存时检查 Codex 会话。 试用结束后不会检查任何内容,doctor 也不再这样提示。现在,当试用记录存在但没有正在运行的试用时,它也会发出警告,这意味着 Veto 的配置已损坏或被手动编辑。
  • veto api snapshot 会报告试用的 trial_id、stop_on、notes_chosen、notes_target 和 skipped 数量。这些字段已添加到 contract v1,不会移除任何内容,并且绝不会返回文件夹列表。
3.8.0
  • 新增:veto api,供编辑器扩展使用的 JSON 接口。 VS Code 扩展可以显示 Veto 的数据库,却无法获知转录捕获是否开启、笔记试用发现了什么,或过往聊天中的任何内容,因此只能显示“未知”。veto api snapshot 会报告项目的捕获、课程和试用状态。它只读,不会更改任何内容:使用只读连接,不运行迁移、采集或试用处理,并返回数量而不是你的文件夹。veto api recall search 和 recall expand 提供与 veto_session_replay 相同的搜索结果,搜索范围由 Veto 检查,符合编辑器所需。必须指定项目;来自其他项目的事件或片段会被拒绝,文本会被遮盖,且绝不会返回原始来源。veto api diagnostics 会以数据形式返回 veto doctor 对各应用的检查结果。请求以 JSON 形式通过 stdin 传入,因此搜索文本不会经过 shell。接口契约采用独立于 Veto 的版本管理,其 JSON Schemas 和示例随附于 contracts/api-v1/。请参阅面向编辑器扩展(Veto API)。
  • 错误修复:veto continue 和 veto sessions 在 Codex 沙盒内会失败。 当 Veto 的工具未在 Codex 中加载时,veto 技能会正确指引 Codex 使用 veto continue,但 Codex 的默认沙盒只允许命令在工作区内写入;而 Veto 每次打开数据库时都会写入,即使只是读取。这两个命令都会因 attempt to write a readonly database 而停止。现在,它们会回退为只读数据库,不进行写入。veto continue 仍会返回完整的已保存会话,并说明它无法执行的操作:记录是谁恢复了会话,以及添加过往会话摘录。已在 Codex 自带的沙盒(codex sandbox)中测试;3.7.1 会失败,而 3.8.0 可恢复会话。
  • 错误修复:Antigravity 聊天未被捕获。 开启转录捕获时,在 Antigravity 中保存不会归档任何内容,因为 Veto 无法读取 Antigravity 的聊天记录。现在,Veto 会从 ~/.gemini/antigravity-cli/brain/<conversation>/ 读取聊天记录,从 Antigravity 自己的会话索引中查找每个会话所属的项目(以只读方式打开),并跳过由其他会话启动的会话和来自 Antigravity 编辑器的会话。Antigravity 聊天现在可以像其他聊天一样搜索和展开;veto transcripts sources 会列出这些聊天,veto doctor 会检查其捕获是否正常。这属于你已授予的捕获同意范围,该同意从未指定特定应用。
3.7.1
  • 错误修复:Veto 不知道自己正在 Antigravity 中运行。 Antigravity 启动 Veto 时会将自身命名为 antigravity-client,而 Veto 无法识别这个名称。除非模型另有说明,否则在 Antigravity 中保存的会话会标记为 claude;在 Antigravity 中恢复的会话不会被记录为由 Antigravity 恢复;如果模型自称是 gemini,转录捕获就会将 Gemini CLI 聊天记录归档,而那其实是另一个应用的对话。现在,Antigravity 会被识别为独立应用。保存和恢复的会话会标记为 antigravity,捕获功能会跳过它(Veto 无法读取 Antigravity 的聊天记录),并且凡是工具询问你正在使用哪个应用的地方,都接受 antigravity 作为有效值。veto_health 也会报告应用名称。
  • 错误修复:Antigravity 一直找不到 veto 技能。 3.7.0 将它写入 ~/.gemini/skills,而 Antigravity 不会读取这个文件夹,因此即使没有 Veto 的工具,Antigravity 仍然得不到任何指引。现在技能会写入 ~/.gemini/config/skills,Antigravity 可以在这里列出它。我们在关闭 Veto 的情况下进行了测试:Antigravity 读取了该技能,表示 Veto 的工具未加载,并运行了 veto continue,而不是搜索磁盘。更新后运行 veto init,即可将技能安装到该位置。
3.7.0
  • Bug 修复:Antigravity 从未加载 Veto。 Antigravity 从 ~/.gemini/config/mcp_config.json 读取 MCP 服务;veto init 却写入 ~/.gemini/antigravity-cli/mcp_config.json,而 Antigravity 不会读取该文件,veto doctor 也检查了同一个文件并显示 ✓。现在,Init 会通过各应用自己的 CLI 注册(如果应用提供了 CLI),例如 claude mcp add、codex mcp add、agy mcp add,由应用决定配置文件的位置。没有对应 CLI 时,只会写入应用实际读取的文件。它会处理 Antigravity 创建的空文件,而旧版写入器会将其跳过并标记为“不可读取”;也不会重写带注释的文件(Zed 的配置文件)或损坏的 JSON。
  • **veto doctor 会检查各应用是否真的在运行 Veto,**而不是仅检查文件中是否提到了它。它会读取应用自身报告的内容(包括已禁用的条目),启动配置的命令以确认其能够响应,并显示各应用上次启动 Veto 的时间、使用的 Node,以及 SQLite 是否能正常工作。它还会检查转录捕获和 lessons 试用是否仍在正常运行;发现任何问题时都会以状态码 1 退出。它的 Node 检查也有误:此前会接受 22.5–22.12,但这些版本无法正常持久化。
  • 新增:veto continue <id> --as <client>,以及 veto sessions --all | --limit N | [words]。 如果 AI 所用的应用未加载 Veto,它可以通过终端恢复会话,使用的代码与 veto_continue 相同,无需读取 Veto 的数据库或导入其文件——此前的做法正是这样。veto_continue 和 veto continue 均接受列表中显示的 8 字符 ID 前缀。veto sessions 会显示会话总数,而不只是最新的 20 个。
  • 新增:veto skill。 veto init 会将其写入 Claude Code、Codex 和 Antigravity/Gemini 的 skill 文件夹。这是 Veto 未加载时 AI 仍能看到的唯一指令:说明 Veto 未加载、使用 CLI,并且绝不读取数据库。它绝不会替换你自己编写的 veto skill。
  • Bug 修复:工具返回的结果是填充文本。 如果没有 LLM 步骤,生成器会在输出中填入无关文本:veto_diagram 会返回 "mermaid": "Documentation looks complete.",veto_pr_description、veto_release_notes、veto_prompt_optimizer、veto_rca、veto_postmortem 和 veto_onboard 也会有同样的问题。现在,各工具只会返回实际计算出的内容(提交、路由、计数、错误预算计算结果、堆栈跟踪中的代码),并将其余内容标记为 generation: "needs_llm",同时附上完成生成所需的提示词。返回生成的输出前会进行检查:veto_doc_gen 会拒绝丢失代码的文件,veto_diagram 会拒绝非 Mermaid 文本,veto_openapi_gen 会拒绝非 OpenAPI 文档。
  • Bug 修复:工具会丢弃输入。 veto_secrets_scan 从未收到它的 text。veto_translate 从未收到文本或语言。veto_semantic_search 从未收到查询内容,veto_explain、veto_merge_conflict 和 veto_a11y_advisor 也从未读取它们的文件。现在,所有输入都会传给 Agent,文件都会被读取(找不到文件时会报错),分析工具会先运行 Veto 自带的扫描器,并且即使没有 LLM,也会返回扫描结果。
  • Bug 修复:扫描器永远无法发现任何内容。 veto_dead_code 和 veto_flag_auditor 将 GNU grep 选项传给了 git grep,因此总是报告未发现任何内容。现在两者都会进行实际扫描:查找没有其他文件使用的导出、注释掉的代码,以及带有位置的功能标记。安全扫描器漏掉了最常见的 SQL 注入形式("… id = '" + req.params.id),现在会报告其所在行。veto_clone_detector 会将代码判定为自身的克隆,并把同一份副本拆成多条发现结果。veto_openapi_gen 只会检查名为 route*/api* 的文件。
  • Bug 修复:数字错误。 veto_dep_advisor 会针对 ^4.19.2 依赖向 OSV 查询 4.0.0。现在它会使用已安装或锁定的版本,并返回每条安全公告的摘要、严重程度和修复版本。veto_debt_register 会将每个项目都标为“complexity, 2 hours”,还有一些工具会返回硬编码的空白或零作为结果。
  • Bug 修复:将基于关键词的结论包装成评审结果。 没有可用的 LLM 时,council 投票会由关键词规则决定。此类结论现在会标记为初步结论,不再保存为项目的最新结论,也不会作为决策存入记忆,更不会阻止 veto_new_feature。veto_benchmark 不再据此选出“赢家”。如果 council 答复缺少大多数成员的内容,就不会再声称其完全由 LLM 支持。
  • 其他修复。 veto_project_map_get 在地图保存为对象后会崩溃。veto_git_blame 忽略了 project_dir。veto_pr_post 发送了 GitHub 会拒绝的评审评论(现在会将其放入评审正文)。veto_env_setup 可能会用占位内容替换现有的 .env.example。veto_workflow 会运行格式错误的步骤。veto_notify_ide 会将 MCP 无法执行的操作报告为“已发送”。veto_code_review 现在会保存其说明中承诺保存的编辑器诊断信息。在 Windows 上,项目查找现在会匹配各应用对文件夹名称的实际大小写;veto memory export --format=markdown 也能再次找到项目条目。
  • Bug 修复:Claude Code 的 secrets 钩子从未运行。 veto init 安装的钩子会从 Claude Code 不会设置的环境变量中读取文件路径,因此放过了所有文件。该钩子已原位替换为一个会读取 Claude Code 钩子输入并向 Claude 报告发现结果的版本。Claude Code 不会运行的两个钩子文件已被移除,但仅当它们与 Veto 写入的内容完全一致时才会移除。
  • Windows:Veto 自带的后台命令不再闪现控制台窗口;更新检查失败后会每小时重试一次,而不是每次启动时都重试。
3.6.0
  • 共享笔记试用现在会衡量笔记是否有帮助。 在 Veto 将任何笔记提供给 AI 之前,它必须证明要提供的笔记真实且有用。在 8 周或 20 次 Codex 会话内(以先到者为准),Veto 会从 Codex 自己的会话文件中读取你项目里每次 Codex 会话的第一条消息,判断本来会为该会话提供哪些笔记,并且只记录这一选择。它绝不会保留你的消息,也仍然不会向任何 AI 提供笔记。会话是从 Codex 自己的文件中查找的,而不是通过 Veto 的连接,因为 Codex VS Code 扩展会在一个进程中运行许多对话,否则就会漏掉它们。只有会话开始时 Veto 已持有的笔记才会计入,子 Agent 不会重复计算。veto lessons 会显示试用进展情况,并在会话不再产生请求时发出警告,这意味着 Codex 更改了格式。如果开启了转录捕获,已结束的试用会话会被归档,以便之后检查每项选择。记录会保留在你的设备上,也不会有人对其作出判断;是否发布交付功能,由作者在其自己的设备上根据试用结果决定,相关规则已在试用开始前封存。
  • 共享功能会暂停,直到你再次同意。 同意版本升级到 3,因为版本 2 的文本称 Veto 不会判断要提供哪些笔记,而试用会使这一说法不再属实。所有在 3.5.0 中开启了共享功能的用户都会看到功能已暂停;在他们于自己的终端运行 veto lessons on 并接受新的文本之前,不会读取任何内容。此前已收集的内容不会删除。在实际向 AI 提供任何笔记之前,Veto 会再次征求同意。
  • 升级后追赶进度快得多。 每当 Veto 更改读取记忆文件的方式时,都需要重新读取所有记忆文件。过去,保存时收集需要保存 16 到 25 次才能追赶完毕,每次都会耗尽全部时间预算。几乎所有耗时都花在每次保存时为每个项目文件夹再次运行 git 上。现在 Veto 会记住每个文件夹所属的项目,追赶进度只需保存 3 到 5 次。veto lessons 命令仍会在每个文件夹中重新查找项目。
  • 已移除:未使用的影子日志。 3.4.0 和 3.5.0 创建了一个用于试用的表,但从未有任何内容写入其中。其设计会存储每次会话的提示词,而试用绝不能这样做。升级时,该表会趁其仍为空时被删除,并由试用专用的表取代,该表只存储选择。
3.5.0
  • 新增、选择加入且仍在试用:Veto 会读取 AI 记录的笔记。 Claude Code、Codex 和 Gemini 各自会把经验教训写入自己的记忆,但彼此听不到对方学到的内容。开启共享后,Veto 会读取这些笔记,在自己的本地数据库中保存一份经过脱敏的副本,并判断哪些笔记可以安全地在你的项目之间以及 AI 之间共享。目前,它不会把任何笔记提供给任何 AI。这是下一步,Veto 会在执行前再次征求你的同意。在你自己的终端中运行 veto lessons on 并输入 yes 之前,共享功能始终处于关闭状态。AI 运行此命令时会被拒绝,而且任何升级都不会开启共享。请参阅在 AI 之间共享笔记。
  • 新增:veto lessons。 查看 Veto 读取了哪些内容以及原因:list 按项目显示每条笔记,why <id> 显示笔记的来源和可能的去向,flows 显示每个 AI 的笔记可能流向何处。你可以使用 forget <id> 永久停止共享某条笔记,使用 exclude 完全排除某个项目,使用 alias 关联未连接驱动器上的记忆,以及使用 off 关闭共享并删除 Veto 复制的所有内容。
  • 你今天写的笔记会在保存时被读取。 开启共享后,veto_session_save 也会重新读取每个 AI 的记忆并记录变更,因此无需记得手动运行任何命令。未变更的文件只需一次 stat 操作;对于 90 个记忆文件,这会让保存过程增加约 20 ms。每次保存的读取时间最多为 150 ms;未能读取的内容会留到下次保存,而且绝不会导致保存失败。开启共享时会一次性读取所有内容。若只想停止保存时的读取,请在 ~/.veto/config.json 中将 lessons.harvest_on_save 设为 false。
  • 状态行会显示 Veto 保存的笔记数量(notes 175),但仅在开启共享时显示。它绝不会显示可能让人误以为笔记仍被保存的零值。
  • 错误修复:Agent 响应格式错误时仍被报告为结果。 Agent 响应架构中的每个字段都有默认值,因此 Veto 无法读取的响应通过验证后,会被视为由默认值组成的完整答案。对于分析,这意味着分数为 70,结论为“已批准,但有警告”。因此,无法读取的安全扫描会被报告为大体通过,没有任何发现;veto_execute_parallel 也会返回看似可信却内容为空的评审结果。现在,响应必须包含其声称包含的内容(计划需要有方法或步骤;分析需要有发现、分数、结论或摘要),否则就会报错,并列出实际收到的键。超出范围的字段仍会像以前一样修正,例如将 150 分截为 100 分。
  • 错误修复:评审委员会的七份分析可能会被悄无声息地丢弃。 veto_council_debate 只接受 JSON 对象形式的第二阶段响应,而模型经常会发送 JSON 字符串。字符串会被当作第一阶段响应处理,而第一阶段会返回一个看似真实结果的确定性结论,却没有说明已撰写的分析遭到丢弃。现在,字符串会像对象一样读取;确实无法读取的响应则会报错,说明实际收到的内容和预期内容。
3.4.0
  • 过去的会话现在会提供给所有 AI 中需要它们的工具。 只有 AI 主动询问时,才能利用对话记录回溯,但大多数时候它们不会询问。现在,veto_continue 和 veto_session_restore 会列出已保存会话背后的归档聊天记录——例如,参与该会话的 Codex 聊天记录和两段 Claude Code 聊天记录——以及每段聊天记录中的最后一个问题。veto_memory_search 会在返回已存储记忆的同时,提供匹配的摘录;Veto 交给模型的每条提示词,无论是面向 Agent 工具还是 council,都会附带最多三段相关摘录。只有对话内容才会作为摘录附加,原始工具载荷不会;而且摘录必须与问题至少共享两个词。关闭捕获时,不会附加任何内容。摘录会标记为历史数据,而非指令;确定性分析器永远不会收到这些摘录,因此旧摘录不会变成分析结果。
  • 新增:Codex 和 Gemini 旁边的 Veto 状态栏。 这两个命令行工具都不能运行自定义状态栏——它们各自只显示内置项——因此,veto statusline watch 会在 AI 旁边的小型分屏窗格中显示 Veto 的状态栏,并跟踪当前文件夹中的会话。对于 Codex,它会从 Codex 自己的会话文件中读取上下文和速率限制用量。Gemini 不记录用量数据,因此其状态栏会显示实时会话,但不显示仪表。veto statusline install --client=codex(或 gemini)会打印适用于 Windows Terminal、tmux 或 VS Code 的单行设置命令,不会进行任何更改。
  • 错误修复:veto init 覆盖了其他 AI 命令行工具自己的记忆文件。 从 1.4.5 开始,init 会将 Gemini 的记忆文件 ~/.gemini/GEMINI.md 替换为 Veto 指南,并写入 ~/.codex/AGENTS.override.md。Codex 会读取该文件而非你的 ~/.codex/AGENTS.md,导致你的全局 Codex 指令被隐藏。现在 init 不会写入这两个文件。veto doctor 会报告旧版本留下的副本;新的 veto doctor --fix(或 veto init)会将其重命名为 *.veto-backup,但前提是该文件与 Veto 附带的指南逐字节完全相同。如果文件中包含其他内容,例如 Gemini 在指南下方保存的记忆,则只会报告,不会触碰。只要残留文件还在,你的 AI 就会在每个会话中提示清理一次。旧版 init 覆盖的内容无法恢复。
  • 错误修复:对话记录捕获可能悄无声息地归档为空,或归档了错误的聊天记录。 Gemini 会用小写形式记录项目文件夹(d:\veto),而保存时使用的名称可能是 D:\Veto;由于匹配区分大小写,Windows 上的 Gemini 聊天记录始终无法找到。现在,Windows 上的文件夹匹配会忽略大小写和斜杠方向。veto transcripts show 和 purge 过去只会查找 Claude Code 聊天记录;清除 Codex 或 Gemini 聊天记录时,会显示“✓ Purged 0 archive(s)”且不删除任何内容。现在,这两个命令都接受任何 AI 的会话 ID;如果清除操作没有匹配项,也会明确说明。过去只有安装了 Veto 状态栏时,才会捕获 Claude Code 聊天记录;现在会从 Claude Code 自己的项目文件夹中查找。如果保存时没有指定项目,则不会捕获任何内容;现在会使用该会话已知的项目。现在,每次保存操作没有归档任何内容时,都会说明原因。
  • 错误修复:会话标签采用了模型自称的 AI。 由 Codex 保存、但自称是 Claude 的模型恢复会话时,会显示“restored from claude”。现在会记录实际连接的 AI;如果两者不一致,保存响应中会注明;恢复的会话会显示最后保存它的 AI。在 veto_continue 和 veto_session_restore 的输出中,created_by 现在改为 saved_by。
  • 错误修复:手动配置的状态栏会被误判为未安装。 Veto 只识别完全匹配的命令 veto statusline print,因此任何其他形式——node …/dist/cli.js statusline print、veto.cmd、npx 或 --capture——都会被视为缺失:每个会话都会带有“status line not enabled”提示,veto statusline status 会报告未启用,而 install 会要求使用 --force。现在,任何运行 Veto 的 statusline print 的命令都会被识别。卸载时仍只会删除 Veto 写入的完全匹配行,因此绝不会删除别人设置的命令。
  • 还包含但默认关闭:为共享各 AI 学到的内容打下基础。 Harvest-and-Share 将读取 Claude Code、Codex 和 Gemini 保存在各自记忆中的笔记,并提供给其他 AI。本次发布仅包含基础工作:不会读取或共享任何内容,目前也没有对应命令;还需要单独选择启用,任何升级都不会将其开启。
3.3.0
  • Veto 现在会询问是否要强制执行某项决策。 veto_decisions 长期以来都能将已记录的决策转化为规则,阻止任何重新引入已否决内容的差异,但只有在有人想到要编写规则时,规则才会存在,而且以前从未有任何提示。现在,当议会裁决(由大模型支持的裁决)或 ADR 敲定某件事时,结果会附带一次性邀请:你的 AI 会用一句话询问你是否要将该决策变成规则。回答“是”会使用邀请的 ID 和你自己的措辞执行 veto_decisions add;回答“否”则会执行新增的 decline 操作。对于同一项裁决,它绝不会询问两次;陷入僵局后也不会询问,并且会告知你的 AI 跳过那些没有敲定任何长期事项的裁决。veto_decisions list 会显示邀请的发出、接受和拒绝次数。此计数保存在你的设备上,绝不会上传。
  • 决策规则不再会拖住审查。 规则会在 veto_diff_review 和 veto_ci_gate 中运行,因此格式不当的模式可能导致任一工具卡住。现在,add 会拒绝可能造成此类问题的模式:超过 200 个字符的模式,或自身包含重复的重复组,例如 (a+)+。每次检查也都有时限。它只读取每条新增行的前 2,000 个字符,因此不会标记出现在超长行(例如压缩后的代码包)更后面位置的匹配项。运行两秒后会停止并报告,因此缓慢的规则只会产生警告,而不会阻止合并。早期版本保存的不符合这些检查要求的规则,现在会按纯文本匹配。
  • 错误修复:恢复的会话显示的是启动时间,而不是最近保存时间。 veto_continue 和 veto_session_restore 报告的是会话首次保存的时间,因此,一个开始 18 天后更新的会话,恢复时看起来就像已有 18 天未更新。底层原因是最近保存时间以两种格式存储,这还导致了另外两个问题。如果某个会话更新的当天,另一个会话首次保存,那么在未指定会话 ID 的情况下调用 veto_continue 可能会恢复错误的会话;VS Code 扩展也会以同样的方式选取最新会话。并且,对于当天保存且尚未更新的会话,veto_metrics 会将当天的会话数计为零。现有记录会在 3.3.0 首次打开数据库时自动转换一次;时间本身不会改变。现在,veto sessions 也会显示最近保存时间。
3.2.1
  • 错误修复:在 macOS 或 Linux 上通过 npm 或 npx 安装时,veto-server 无法启动。 进程会立即退出,不报错且状态为成功,因此客户端只会报告“初始化期间连接已关闭”。原因在于用于判断服务是直接运行还是仅被导入的检查:它会将正在运行的模块路径与其被调用时使用的路径进行比较,而在这些平台上,npm 会将命令安装为符号链接,因此一侧会通过链接解析,另一侧则不会。两者永远无法匹配,服务也就无法启动;自 2.1.0 以来的每个版本都存在这个问题。Windows 一直不受影响,因为 npm 在该平台上会创建另一种类型的 shim,并传递真实路径——这也解释了为何这个问题在本地测试中连续十个版本都未被发现。任何直接运行 node .../dist/server.js 的配置也不受影响,包括 Desktop Extension 软件包。现在,打包后的命令使用专用入口点,无条件启动,而不是推断自己是否应该启动;测试套件现在也会像包管理器那样启动构建产物,补上了之前缺失的检查。此问题由 @khaliqgant 在 #39 中报告、诊断并复现。
3.2.0
  • 现在不仅 Claude Code 支持转录捕获,Codex CLI 和 Gemini CLI 也支持了。 这三个 CLI 中任意一个会话,都可以通过同一条流水线进行归档、索引、回忆和展开,并遵循相同的同意、屏蔽和保留规则。两个适配器的编写依据不是文档,而是开发机器上的所有真实转录——包括涵盖 6 个 CLI 版本的 12 份 Codex rollout 和 2,365 个 Gemini 聊天文件——并且全部解析成功,没有任何无法识别的记录。通过这些数据还发现了两个仅凭单个示例文件无法察觉的格式陷阱:Codex 会在两条交错的数据流中写入每条消息,任何一条都不能单独构成完整记录;Gemini 的日志则是对 修订版 追加内容,而不是对消息追加内容,会随着文本增长而反复追加相同的消息 ID。如果不处理这两种情况,搜索就会把每条消息都计算两次。不会丢弃任何内容——重复副本仍会存储,也仍可按字节寻址——只是不会进入索引。
  • Veto 现在会自行查找 Codex 和 Gemini 会话。 只有 Claude Code 提供能将转录路径交给 Veto 的钩子,因此 Veto 会改为在磁盘上查找另外两个 CLI 的会话文件。veto transcripts sources 会报告它实际能在每个 CLI 中看到的内容,这能说明捕获功能是否已启用,以及它能否在你当前的环境中正常工作。
  • Veto 现在会根据 MCP 握手识别当前运行在哪个 CLI 中,而不再依赖模型的报告。 过去,捕获功能会根据 platform 参数选择转录,该参数默认值为 claude。因此,在 Codex 中运行的模型如果没有更改默认值,就不会归档任何内容,而且不会在任何地方报错。现在,主机 CLI 会从 initialize 握手中读取,这是关于进程的事实,而不是模型的声明。无法识别客户端时会跳过捕获,而不是猜测,因为归档错误 CLI 的会话比完全不归档更糟。veto doctor / veto_health 现在也会显示检测到的主机,以便诊断“没有捕获任何内容”的原因。
  • 深度回忆的第二次调用现在值得进行了。 回忆分为两次调用——先查询排名靠前的片段,再展开命中项以查看来源行——但测量结果显示,这个流程在实际使用中一次都没有完成。原因不在排名,而在两部分之间的校准:片段平均只有 97 个字符,太短而无法判断相关性;展开会不加限制地返回原始存储行,一次调用最多可产生 139 KB 的 JSON 封装内容——约占 128k 上下文窗口的三分之一;目录仅在所有结果都来自同一份归档会话时才会附上,因此在它最该发挥作用的多会话项目中反而不会出现。现在,片段宽度约扩大了 4 倍;展开会在明确的上限内返回易读的对话文本,并提示是否发生截断;目录则涵盖所有产生结果的会话。排名保持不变。raw: true 仍会返回与原始字节完全一致的内容,扩大后的两条路径也仍会进行屏蔽,并有回归测试确保粘贴的秘密信息不会通过其中任何一条路径泄露。
  • 新增:veto transcripts metric 会根据 Veto 已记录的工具调用跟踪信息,报告转录回忆是否确实被调用——无需新增埋点,并且只读取回忆调用的结构,绝不读取查询文本。它只读取一个本地数据库,不会将任何内容发送到机器外,因此这是对你自身使用情况的健康检查,而非关于其他人的证据。
3.1.2
  • Veto 安装的嵌入表现在是经过签名的制品。 Veto 将 @jigyasudham/veto-model 固定到确切版本,现在固定到的版本是 1.0.1。该版本由 CI 发布,并附带来源证明——一种签名证明,用于将软件包与构建它的仓库、工作流和提交关联起来。1.0.0 是手动发布的,无法获得来源证明,因此更新固定版本是弥补这一缺口的唯一办法。两个版本的有效载荷逐字节完全相同:嵌入、缩放系数、分词器和向量都相同。搜索行为、结果或排名均未改变。
3.1.1
  • Bug 修复:veto memory export --markdown 总是失败。 Markdown 导出构造查询时,将项目筛选条件放在了 ORDER BY 之后,这不符合 SQL 语法,因此导出会报告失败,而不是写入文件。由于 CLI 始终按当前项目筛选,该命令从未成功过;指定项目时,MCP 工具 veto_memory_export 也会以相同方式失败。不使用项目筛选条件的导出不受影响,因此这个问题一直未被发现。现已修正这两条查询,并添加回归测试。
3.1.0
  • 语义召回——搜索能找到你想表达的内容,而不只是你输入的词。 转录内容搜索现在会将现有关键词索引与本地语义搜索结合起来,因此,即使问题和答案没有共同词汇,也能找到答案:搜索“为什么上传失败”会找到写着“凭据已过期”的笔记。每个捕获的事件都会拆分成相互重叠的窗口,并按其中最佳匹配项评分,因为对整个事件生成嵌入会稀释那句回答问题的内容。精确标识符不受影响——E404 仍然排在首位。两种排名通过互惠排名融合,而不是混合分数,因此任何一种排名器都无法压过另一种。
  • 它在你的机器上离线运行,无需按查询付费。 为此付出的是一张 7 MB 的嵌入表——由 Minish Lab 提供的 potion-base-8M(MIT),从 baai/bge-base-en-v1.5 蒸馏而来,重新打包为 int8,并作为固定版本的软件包 @jigyasudham/veto-model 随附。npm 缓存会在每台机器上下载一次。无论是否启用捕获,该软件包都会随 Veto 一同安装:固定不可变版本意味着发布后字节永远不会改变,而且运行时无需下载、校验和或镜像机制。它是一张静态查找表,不是神经网络——查询时不会执行任何内容,推理代码由 Veto 自行提供。
  • 模型从不承担关键功能。 它会在首次语义查询时加载,而不是在启动时加载,因此,如果副本缺失或损坏,搜索会降级为仅关键词搜索,其他一切不受影响。Veto 自身的软件包大小没有变化;该表是依赖项,而非软件包内容。
  • 大规模场景下的搜索速度提升约 5 倍,关键词搜索也包括在内。 在包含 50 个会话的存档中,项目范围召回从 178 ms 降至 38 ms,纯关键词搜索从 65 ms 降至 13 ms,原因是索引只加载一次,而不是每次查询都重新读取。这也消除了影响 3.0.0 的延迟上限。在单个项目中存档会话数超过约 100 个后,召回效果会逐渐下降,但仍然可用。
  • 对 3.0.0 发行说明的更正: 说明中将转录内容搜索描述为“SQLite FTS5/BM25”。FTS5 在 3.0.0 发布前就已移除,原因正是部分 Node 构建中不提供该功能;该索引一直是基于核心 SQLite 的可移植 BM25。
3.0.0
  • 不再丢失会话——可选择开启转录捕获,并通过无向量检索回忆内容。 保存的会话始终包含约 1k 个 token 的摘要,足以恢复会话,但无法回答“我们三周前究竟得出了什么结论?当时是什么时候?”。现在,Veto 可以归档一份宿主命令行客户端自身对话转录的副本,并据此构建记忆金字塔——包含原始 gzip 压缩文件、确定性事实、对话主线和现有摘要——然后通过元数据目录和便携式 BM25 索引进行搜索。索引仅使用核心 SQLite,因此可在所有受支持的 Node 版本上运行。无需嵌入向量、模型下载、API 密钥或新增运行时依赖。回忆通过 veto_session_replay 进行两次调用:先查询目录和排序后的片段,再将命中项展开为带轮次和时间戳引文的确切源文本行。我们使用一个真实的 784 行会话进行了验证,回忆功能精准找到了摘要无法还原的结论。本次版本仅支持 Claude Code 适配器。
  • 在你开启之前,捕获功能默认关闭,并会明确说明启用后会发生什么。 veto transcripts enable 会以通俗语言告知:Veto 会复制 AI 客户端自身的会话记忆;该副本的保留时间会超过客户端自身历史记录;归档内容的敏感程度取决于你粘贴过的内容;以及归档文件在磁盘上的位置。随后会记录带版本号的同意;如果披露内容发生实质性变化,则会再次征求同意。归档文件始终保存在你的设备上,不会放入云同步目录,并会按可配置的保留期限清理。执行 veto transcripts purge 时会彻底级联删除,不留下孤立记录。
  • 机密信息不会流入 AI 上下文。 检测到的凭据在写入每个派生层时都会被遮蔽为 REDACTED[sha256:…];从原始归档中读取并返回任何字节范围时也会再次遮蔽。因此,即使未修改的原始文件中包含机密信息,也无法通过回忆功能传递给模型。回忆内容会作为数据而非指令返回,工具结果则会被视为不可信输入。
  • veto.db 不受影响。 所有捕获状态都保存在旁路数据库 transcripts.db 中,因此不会影响 VS Code HUD 的读取约定。
2.9.0
  • 又有 4 个 Agent 能进行实际分析了。 隐私、性能、身份验证和兼容性 Agent 原先只是结构化的操作手册;现在,它们已成为双模式分析器,并加入了手写的确定性检查,涵盖 PII/PHI 处理、运行时反模式、身份验证缺陷(例如 JWT alg: none)以及过时 API 的使用,使具备分析能力的 Agent 数量从 8 个增至 12 个。每个 Agent 都有明确的职责范围,以避免与安全扫描器和机密信息 Agent 的发现重复,并且都保留了 LLM 升级路径。
  • 由 Agent 支持的工具现在可以完成 LLM 升级的往返流程。 之前,所有 19 个由 Agent 支持的顾问、生成器和 git 工具都会输出 llm_upgrade 提示词,却无法接收推理结果。现在,每个工具都接受 agent_response 参数:调用工具,由相应的专业 Agent 进行推理,然后再次调用工具并传入结构化 JSON,即可获得升级后的结果。无论如何,工具始终会返回确定性答案;升级结果会附加在其旁边,而不会取代它。
  • 委员会裁决现在限定于项目范围。 VS Code HUD 和 CLI 状态行显示的最新裁决以前是全局最新的委员会辩论结果,因此可能显示来自其他工作区的结果。现在,委员会结果会携带 project_dir(一次性、幂等迁移会添加此列,并根据关联的会话回填现有行),状态行会将裁决限定在当前工作区内;未显式指定 project_dir 的辩论运行则会回退到当前项目,而不是以未限定范围的方式存储。如果项目尚无辩论记录,裁决部分会直接隐藏,而不会借用其他文件夹的结果。
  • 否决工具现在会被调用,而不是被重新实现。 能力较弱的模型(例如 Gemini Flash)有时会将裸露的 veto_* 命令理解为需要手动完成的任务——从源代码逆向分析工具、编写临时脚本并直接操作数据库,从而产生虚构且范围错误的结果。现在,始终存在的使用指令,以及针对 veto_continue / veto_handoff / veto_session_save 的明确触发说明,会告知每个客户端直接调用实时 MCP 工具。
2.8.0
  • 确定性委员会裁决终于恢复了准确性。 委员会在没有 LLM 支持的路径下运行时,每位专家以前都会输出预设且与任务无关的“主题”警告——宽泛的关键词匹配(任务中提到“测试”或“计划”)会产生套话式的担忧,这些内容不断累积,迫使裁决变为 YELLOW,却没有提供任何实际信息。现在,这些主题洞察已成为不参与投票的建议:Agent 会投赞成票,并将指导内容作为 💡 [advisory] 注释呈现,且不会改变裁决。Devil's Advocate 仍会始终提出质疑,但其主题探查不再升级风险。具体规则匹配(硬编码机密信息、localStorage 令牌、GPL 许可证、缺少速率限制,……)则与之前一样会升级风险。
  • VS Code HUD 现在能在每个工作区中找到会话和记忆。 会话和记忆通过 project_dir 与工作区匹配,但此前保存的值会保留调用方传入的驱动器盘符大小写(通常是大写的 D:\),而扩展使用 VS Code 的 fsPath 查询时,盘符为小写且区分大小写,因此即使保存成功,HUD 仍会显示“No active session” / “0 memory entries”。现在,每次读取和写入时都会规范化 project_dir(将 Windows 驱动器盘符转换为小写);一次性、幂等迁移会在下次启动时修复现有行。
2.7.4
  • 服务可在不支持 node:sqlite 的运行时中正常启动。 sqlite 内置模块(Node ≥ 22.5)现在会在首次使用数据库时延迟加载,而不是在导入时加载。在缺少该模块的运行时中——例如旧版 Node、注册表能力扫描器——服务现在可以启动、响应 initialize 并列出全部 93 个工具;只有持久化工具(记忆、会话、学习)会返回明确的“升级 Node”错误,而不会在 MCP 握手前导致整个进程崩溃。在受支持的 Node 上,行为没有变化:数据库、架构和查询都保持不变。
  • 防崩溃状态栏 print 也进行了相同处理:其只读数据库打开操作现在会在现有的绝不抛出异常保护中检查 sqlite。
2.7.3
  • 恢复将全局 CLI 安装作为文档推荐方式。 2.7.1 移除了所有 npm i -g 建议,因为全局副本可能会遮蔽 npx,并使 MCP 服务固定在旧版本上——但 2.7.1 自带的 @latest 固定版本让这种遮蔽不再可能,导致 README 只记录了 15 条裸 veto 命令,却没有说明如何让 veto 出现在 PATH 中。现在,npm i -g @jigyasudham/veto 是文档推荐的 CLI 安装方式(新增入门指南章节);无论如何,MCP 服务仍会通过固定版本的 npx 配置自动更新。
  • veto doctor 不再判定全局安装有问题。 现在它会将全局 CLI 安装报告为健康状态,仅在其版本落后于注册表时发出警告(并提供 npm i -g @latest 作为解决方法),如果不存在全局安装,则会显示提示信息。故障排除文本和启动时的更新提醒也已相应调整——改为“更新全局安装”,而不是“删除全局安装”。
  • veto statusline install 会检查 PATH。 状态栏的高频路径会直接调用裸 veto(每次渲染提示词都运行 npx 太慢),因此现在安装时如果 veto 不在 PATH 中会发出警告,而不再默默地什么也不显示。
  • npm 包解包体积从 22.6 MB 缩减至 2.2 MB。 package.json 现在包含一个 files 允许列表(dist/ + server.json),因此本地工作文件不再被打包,其中包括一个自 2.5.0 起一直被打包的 20 MB mcp-publisher.exe。所有人的 npx 冷启动都会更快。
2.7.2
  • veto init 会自动修复失效的 Claude Code 注册项。 如果用户级 veto MCP 条目通过 node <script> 启动,而该脚本已不存在——典型情况是旧条目指向全局安装中的 dist/server.js,但该文件在运行 npm rm -g 后被删除——init 现在会使用规范的固定版本 npx 命令重新注册,而不是以“已注册”为由跳过。它只会处理明显失效的 node 路径条目,不会改动有效或自定义配置。
  • Windows:Claude 注册使用 npx.cmd。 现在 veto init 在 Windows 上会使用 npx.cmd 注册 Claude Code(Claude Code 无法在此环境中解析裸 npx),与可可靠连接的形式保持一致。
2.7.1
  • 修复:npx 可能会静默运行旧版本。 生成的 MCP 配置使用了未固定版本的 --package @jigyasudham/veto,因此 npx 会复用缓存版本或全局安装版本,而不是获取最新版本——重新安装并重启也不会升级。现在,所有生成的配置和文档中的注册命令都固定为 @latest,npx 必须在每次启动时向注册表重新解析版本,因此客户端重启即可自动更新。已移除所有 npm i -g @jigyasudham/veto 建议(全局安装正是会优先于 npx 的原因)。
  • 启动时更新提示。 发布新版 Veto 后,正在运行的服务会通过 MCP instructions 字段向 Agent 显示一行“有可用更新——重启即可应用”的提示。此提示不会阻塞运行,且可在离线时安全使用:服务会读取缓存的最新版本,并且每天最多在后台刷新一次;版本已是最新时,提示会自动消失。
  • veto --version / -v。 以前会返回“Unknown command”。现在,veto doctor 也会报告是否有可用的新版本,并在检测到会造成遮蔽的全局安装时提示使用 npm rm -g 修复。
  • 诚实性修正。 注册表和目录中的描述已将“零 API 费用”改为“无需 API 密钥”(按 Token 计费的 API 调用会产生费用)。
2.7.0
  • 状态栏显示实时会话指标,而不是静态计数。 旧版 Token 区段读取的是 Veto 自己的 rate_usage 表,只有 Veto 的工具会增加其数值——因此正常使用时它会一直停滞。现在,veto statusline print 会从标准输入读取 Claude Code 传给 statusLine 命令的 JSON,并显示三个实时指标:ctx N%(上下文窗口使用量)、5h N%(5 小时速率限制)和 7d N%(每周速率限制)。各指标在 ≥70 时显示黄色、≥90 时显示红色,值不可用时(会话早期//compact 后)则隐藏。显示效果例如:⬡ veto GREEN · router 94% · ctx 37% · 5h 74% · 7d 8% · mem 15;不可用时会降级为中性的 ⬡ veto,并保持防崩溃、非阻塞(仅在 TTY 下运行,超时为 200 ms)。Veto 自身按平台统计的每日用量仍可通过 veto_rate_status / veto_snapshot 查看。
  • 首次运行时的状态栏提示。 安装状态栏之前,Veto 会通过 MCP instructions 字段向 Agent 显示一行提示,让用户发现此功能,而不必通过命令自行查找。尊重用户同意(未经用户同意绝不编辑 settings.json),并且会自行消失(安装后提示即消失)。
  • veto statusline print --capture <file>。 诊断辅助功能,会在渲染后的状态栏文本旁追加原始 Claude Code 负载,便于核对实时指标是否与客户端实际发送的值一致。默认关闭;尽力运行,绝不会阻塞渲染。
2.6.0
  • veto statusline——在任意 AI CLI 提示词下方显示精简的 Veto 状态栏。 veto statusline install 会将 statusLine 命令接入 Claude Code 的 settings.json(先备份;uninstall 会逐字节恢复)。print 的热路径只读、快速且防崩溃——例如会渲染 ⬡ veto GREEN · router 94% · claude 42% · mem 15;若 DB 缺失或被锁定,则降级为中性的 ⬡ veto。此功能内置于 CLI,因此所有 Veto 用户都能在任意终端中使用,而不只是 VS Code HUD。
  • veto_snapshot——一次调用即可获取编辑器/HUD 聚合数据。 通过一次只读调用返回 { session, council, routerTop, rate, memoryCount, health },让编辑器集成(veto-vscode)不再直接读取内部表。工具数量现为 93。
  • 稳定的读取契约版本控制。 现在,veto.db 每次打开时都会写入 PRAGMA user_version(VETO_DB_SCHEMA_VERSION),外部读取方因此可以检测架构变化并优雅降级,而不是静默返回空白。
2.5.0
  • veto_drift_check — 连锁错误断路器。 扫描近期工具调用轨迹,查找连续失败、重复错误消息和单一工具反复调用等情况,然后运行 debugger Agent,提供具体的恢复步骤。参见连锁错误断路器。
  • Council 校准修复。 收紧确定性 council 的模式触发条件,避免因通用词语(如“server”“transport”)或 v2.5.0 这类 semver 字符串而误触发,并移除了 Agent 推理中陈旧的硬编码工具数量。
2.4.0
  • veto_decisions — 决策漂移强制执行。 将架构决策记录为机器可检查的约束;之后,veto_diff_review 和 veto_ci_gate 会自动拒绝新增行重新引入禁用模式的任何差异。参见决策漂移强制执行。
2.3.0
  • veto_dep_verify — 依赖项幻觉防护。 安装前会通过 npm/PyPI/crates.io 实时注册表验证每个待安装的软件包,并标记虚构名称和仿冒拼写(防范 slopsquatting)。参见依赖项幻觉防护。
2.2.0
  • 紧凑模式(VETO_COMPACT=1)——仅公布 9 个工具,包括 veto_find_tools / veto_call 元工具,Schema 减少约 5–6 倍。参见紧凑模式——无需上下文开销即可使用 92 个工具。
  • 隐式结果挖掘——veto_learning_stats 现在会自动从工具调用轨迹中挖掘结果(出错的调用、快速重跑),无需手动调用 veto_record_outcome。
  • 实验性可流式传输的 HTTP 传输(veto-server --http)。参见 HTTP 传输。

HTTP 传输(实验性)

veto-server --http [port] 会通过 http://127.0.0.1:<port>/mcp 使用可流式传输的 HTTP 提供 MCP 服务(默认端口为 3939),而非 stdio——适用于网关、远程客户端,或任何无法启动子进程的场景。它以无状态模式运行(没有会话 ID——这是 2026 年 7 月 MCP 规范的发展方向),且仅绑定到回环地址;设置 VETO_HTTP_HOST 可主动将其对外开放。

项目结构

Veto 是一个独立的 MCP 服务(src/server.ts),负责注册 93 个工具、MCP 资源和提示词,随后通过按领域划分的处理器注册表分发每次工具调用——没有庞大的单体 switch。每个领域在 src/server/handlers/ 下都有自己的 HandlerMap 模块:

模块工具领域
workers.ts15单 Agent 工作器委派(code_review、security_scan、explain 等)
generators.ts11单 Agent 产物生成器(adr、diagram、rca、doc_gen、onboard 等)
memory.ts9知识库、模式、项目地图
observability.ts7健康状态、指标、使用情况、审计、上下文/速率状态
advisors.ts8项目扫描器(dep、query、bundle、dead-code、flag、openapi、HITL、drift-check)
session.ts6保存 · 恢复 · 列出 · 交接 · 继续 · 重放
review.ts5diff · CI · PR · 完整评审 + 提交前工作流
git.ts5blame · 更新日志 · 提交消息 · PR 描述/发布
core.ts5状态 · 路由 · 平台设置 · 文档获取 · 发现
agents.ts5agent_plan · execute_parallel · delegate · workflow · task_parse
devtools.ts5插件 · 本地大模型 · 克隆检测器 · compose · 通知 IDE
council.ts3council_debate · benchmark · new_feature
learning.ts3record_outcome · learning_stats · learning_apply
watch.ts3监视 · 轮询 · 停止

可共享且可独立测试的内部模块位于 src/server/:

  • registry.ts — ToolContext({ request, args, server })和 HandlerMap 类型
  • runtime.ts — 共享可变状态(活动项目目录、自动保存、服务健康状态、VERSION)
  • scan-core.ts — git diff 读取器、三重扫描和 Agent 工作器循环(经过单元测试)

每个处理器模块都可以独立导入,因此其行为由 tests/server/dispatch.test.ts(callTool 行为覆盖)和 tests/tools/definitions.test.ts(89 个工具的注册覆盖检查)保障。


技术栈

  • 语言: TypeScript(严格模式)
  • 运行时: Node.js 22.13+ 或 23.4+(内置 node:sqlite——无需本机编译)。该功能从 22.5 版开始提供,但当时只能通过 --experimental-sqlite 启用,因此 22.13 是实际最低版本。
  • 依赖项: 仅 @modelcontextprotocol/sdk——一个包,零本机扩展
  • 记忆: 本地 SQLite——无需配置,支持离线使用,可通过 JSON 导出实现可移植
  • 平台: Claude Code · Gemini CLI · Antigravity CLI · Codex CLI · Cursor · Windsurf · Zed

许可证

MIT © 2026 Jigyasu Dham

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。