关于 Veto
Veto 是本地运行的 MCP 服务和命令行工具,为 AI 编码环境提供专家 Agent、代码与安全审查、记忆及工作流工具。它支持多种 AI 命令行客户端,并提供可通过宿主端或 MCP Sampling 使用 LLM 推理的确定性 Agent。
主要功能
- 0193 个 MCP 工具和 49 个专家 Agent
- 02代码、安全和依赖审查
- 03跨平台持久化记忆
- 04并行 Agent 执行与 Council 辩论
- 05自学习任务路由
- 06精简工具发现模式
适用场景
- 01审查代码并扫描安全问题
- 02安装前验证待用软件包
- 03协调专家 Agent 处理开发任务
- 04跨会话保留决策和上下文
MCP 相关
Veto 通过 MCP 服务提供 Agent、审查、记忆、路由和开发工具,可注册到支持的 AI 客户端;在可用时借助宿主 Agent 推理或 MCP Sampling。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
veto
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 |
| Agent | veto_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 PR | veto_pr_review | 获取差异,并返回可直接发布的评论 |
记住信息
| 想要…… | 使用 |
|---|---|
| 保存/找回解决方案、决策或参考资料 | veto_memory_store / veto_memory_search |
| 跟踪反复出现的代码规范 | veto_pattern_store / veto_patterns_list |
| 无需扫描文件系统即可浏览代码库 | veto_project_map_get(通过 veto_project_map_update 刷新) |
运行多步骤任务
| 想要…… | 使用 |
|---|---|
| 针对一项任务同时运行多个 Agent | veto_execute_parallel |
| 运行带有通过/失败门禁的顺序工作流 | veto_workflow |
| 将 PRD / 自然语言转换为任务 DAG | veto_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-audit | OWASP 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 个。 - 新增:
vetoskill。veto init会将其写入 Claude Code、Codex 和 Antigravity/Gemini 的 skill 文件夹。这是 Veto 未加载时 AI 仍能看到的唯一指令:说明 Veto 未加载、使用 CLI,并且绝不读取数据库。它绝不会替换你自己编写的vetoskill。 - 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 MBmcp-publisher.exe。所有人的 npx 冷启动都会更快。
2.7.2
veto init会自动修复失效的 Claude Code 注册项。 如果用户级vetoMCP 条目通过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— 连锁错误断路器。 扫描近期工具调用轨迹,查找连续失败、重复错误消息和单一工具反复调用等情况,然后运行debuggerAgent,提供具体的恢复步骤。参见连锁错误断路器。- 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.ts | 15 | 单 Agent 工作器委派(code_review、security_scan、explain 等) |
generators.ts | 11 | 单 Agent 产物生成器(adr、diagram、rca、doc_gen、onboard 等) |
memory.ts | 9 | 知识库、模式、项目地图 |
observability.ts | 7 | 健康状态、指标、使用情况、审计、上下文/速率状态 |
advisors.ts | 8 | 项目扫描器(dep、query、bundle、dead-code、flag、openapi、HITL、drift-check) |
session.ts | 6 | 保存 · 恢复 · 列出 · 交接 · 继续 · 重放 |
review.ts | 5 | diff · CI · PR · 完整评审 + 提交前工作流 |
git.ts | 5 | blame · 更新日志 · 提交消息 · PR 描述/发布 |
core.ts | 5 | 状态 · 路由 · 平台设置 · 文档获取 · 发现 |
agents.ts | 5 | agent_plan · execute_parallel · delegate · workflow · task_parse |
devtools.ts | 5 | 插件 · 本地大模型 · 克隆检测器 · compose · 通知 IDE |
council.ts | 3 | council_debate · benchmark · new_feature |
learning.ts | 3 | record_outcome · learning_stats · learning_apply |
watch.ts | 3 | 监视 · 轮询 · 停止 |
可共享且可独立测试的内部模块位于 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
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。