npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@vertu-tech/vps-cli

v0.1.10

Published

Vertu CLI - bridge Odoo ai_cli + ai_skills to a local Node.js command and one-click install skills into Cursor / Claude Code / Trae.

Downloads

93

Readme

@vertu-tech/vps-cli

把 Odoo ai_cli + ai_skills 两个模块的 HTTP 网关包装成一个本地 CLI(vertu),并支持把服务端定义的 Skill 一键安装到 Cursor / Claude Code / Trae / OpenClaw / Hermes 这些 AI Agent 的用户级目录。

  • CLI 是运行时:调用真实的 /ai/cli/v1/execute/ai/skills/v1/execute 等接口
  • Skill 是知识层SKILL.md 告诉 AI Agent 在什么场景下、用什么参数去调 vertu

设计理念、接口契约的更深背景见 vertu_addons/ai_cli/README.mdvertu_addons/ai_skills/README.md

特性

  • 单二进制 vertu,子命令分组:login / logout / whoami / caps / <program> <leaf...> / skill ...
  • 统一认证:用户登录走 /ai/cli/v1/login,session_id 写 OS 钥匙串(keytar),不可用时降级到 ~/.vertu/config.json(POSIX 0600);CI 走 VERTU_BOT_INBOUND_KEY 环境变量
  • 动态命令:每次启动按需读取 /ai/cli/v1/capabilities,根据 leaves[].argv_prefix 还原嵌套命令、按 parameters_schema 渲染 --<flag>,并按 invoke_kind 自动选择 payload.arguments(ai_tool)或 payload.json_params(http_json)
  • Skill 跨 Agent 同步vertu skill update 默认扫描全部 Adapter 的 .vertu-manifest.json,按 (agent, skill_key) → sha256 与远端比对:内容漂移会重写、远端新增的 skill 会自动安装到「已经在用此 Agent」的本机、远端已删除的 skill 会本地物理 prune;--dry-run 仅打印对齐表,--no-include-new / --no-prune 可分别关闭新增/删除同步
  • 支持的 Agent 安装目标(仅用户级):
    • Cursor → ~/.cursor/skills/<skill_key>/
    • Claude Code → ~/.claude/skills/<skill_key>/
    • Trae 国际版 → ~/.trae/skills/<skill_key>/
    • Trae 国内版 → ~/.trae-cn/skills/<skill_key>/(与国际版完全分离)
    • OpenClaw → ~/.openclaw/skills/<skill_key>/(OpenClaw 的 Managed/local skills 根目录,可被 ~/.openclaw/openclaw.json 的 allowlist 进一步过滤)
    • Hermes → ~/.hermes/skills/<skill_key>/(Nous Research Hermes Agent 的唯一 source-of-truth 目录)
    • 任意目录(v0.1.5+)→ 通过 --dir <path> 直接安装到自定义路径,用于尚未在内置列表里的「未知 Agent」;支持 ~ 与相对路径,可与 --agent 混用
  • AI-friendly 输入纠错(v0.1.3+):
    • required: string 字段的 leaf 自动暴露 positional shorthandvertu odoo knowledge business "罗来" 等价于 ... business --query "罗来",无需先 --help 一次再写
    • 智能 unknown-flag 提示:--model(Did you mean one of --model-name, --model-name-file?)--field(Did you mean --fields?),覆盖 commander 默认 maxDistance=3 算法漏掉的「短前缀 vs 长 kebab 名」常见 AI 误用

一句话自举(推荐,AI Agent 引导安装)

把「装 vertu + 登录 + 把业务 skills 同步到当前 agent」交给 AI agent 完成。bootstrap skill 由 Odoo ai_skills 静态托管,无需登录即可访问:

https://admin.vertu.cn/ai_skills/static/skills/vps-cli/SKILL.md

仓库内真源:vertu-erp/vertu_addons/ai_skills/static/skills/vps-cli/SKILL.md

在 Cursor / Claude Code / Trae / OpenClaw / Hermes 里跟 agent 说(或等价表述):

安装 https://admin.vertu.cn/ai_skills/static/skills/vps-cli/SKILL.md 这个 skill,并按 skill 初始化 vertu CLI、把业务 skill 装到当前 agent

agent 会自行 wget/curl 该文件到本机 agent 的 skills/vps-cli/,再按 SKILL.md 走完:检测 Node 20+ → npm i -g @vertu-tech/vps-cli@latest → 引导你 vertu login(密码须本人填写)→ vertu skill update(或 vertu skill install --all --agent all -y)→ vertu whoami / vertu caps list 自检。

Hermes 用户对照:与「先装 hermes-agent skill 再自举」类似;区别是 bootstrap skill 由 Odoo 静态托管,agent 按 URL 拉取即可。

快速开始(手动)

公网安装(推荐,使用方)

npm install -g @vertu-tech/vps-cli
vertu --version
vertu login              # 默认登录 https://admin.vertu.cn,无需 --base-url / --db
vertu --help

最低 Node 版本 20+(包内已声明 engines.node)。

从源码安装(贡献方)

git clone https://gitee.com/he-linyan/vps-cli.git
cd vps-cli
npm install
npm run build
node dist/vertu.cjs --help

# 或者把工作区链成全局 `vertu`,改 `src/` 后只需 `npm run build` 即生效:
npm link
vertu --help

完整流程示例见 examples/README.md

升级 / 卸载

npm update -g @vertu-tech/vps-cli       # 升级到最新
npm uninstall -g @vertu-tech/vps-cli    # 卸载

命令一览

会话与缓存

| 命令 | 说明 | |------|------| | vertu login [--base-url --db --login --password] | 调用 /ai/cli/v1/login,把 session 存进钥匙串。--base-url 省略时默认 https://admin.vertu.cn(Vertu 正式环境,单 db,无需传 --db;仅当本机还没登记过任何 endpoint 时生效) | | vertu logout [--forget] | 调用 /ai/cli/v1/logout,清除本地 session(--forget 同时清理整个 profile) | | vertu whoami | 调用 /ai/cli/v1/whoami,附带打印凭据来源、缓存路径 | | vertu caps refresh | 强刷 /ai/cli/v1/capabilities 缓存 | | vertu caps list [--program --json] | 渲染当前缓存里的命令树 |

动态命令

vertu <program_slug> <segment...> 会从 capabilities 里找到对应 leaf,根据 JSON Schema 渲染 --<flag>flag 名是 schema key 的 kebab-casemodel_name--model-nameknowledge_types--knowledge-types);snake_case 也接受,会在入口被归一化:

# 标准 ai_tool leaf:每个字段都是 --kebab-flag
vertu odoo data search --model-name res.partner --domain '[]' --fields 'id,name' --limit 5

# 单 required string 字段的 leaf 支持 positional shorthand(v0.1.3+)
vertu odoo knowledge business "罗来"
# 等价于:vertu odoo knowledge business --query "罗来"

# http_json leaf
vertu odoo skills execute --skill-key sample --params '{"foo":1}'

# 兜底:直接传整个 payload
vertu odoo data search --payload-json '{"arguments":{"model_name":"res.partner","limit":3}}'

写错 flag 名时(--model 这种 AI 高频肌肉记忆)会得到上下文相关的提示:

$ vertu odoo data search --model res.users --domain "..."
error: unknown option '--model'
(Did you mean one of --model-name, --model-name-file?)
(use -h or --help for usage)

Skill 子命令

| 命令 | 说明 | |------|------| | vertu skill list [--source remote\|caps] [--json] | 列出所有可用 skill | | vertu skill pull <skill_key\|all> [--out DIR] | 仅下载 SKILL.md + assets,不写入 Agent | | vertu skill run <skill_key> [--script-key --params --validate-only] | 调用 /ai/skills/v1/execute | | vertu skill install [skill_keys...] [--all] [--agent ...] [--dir ...] [-y] | 交互式多选向导(不传任何参数时进入),亦可显式列 key 或用 --all;TTY 缺省会同时让你多选 Agent,并在末尾要求确认 | | vertu skill update [--agent --dir --skill-key --dry-run --no-include-new --no-prune] | 跨 Agent 同步:默认扫描所有 builtin agent + ~/.vertu/known-dirs.json 中所有自定义目录,比对远端 sha256,自动重写漂移、安装远端新增、prune 远端已删除 | | vertu skill uninstall <skill_key> [--agent ...] [--dir ...] | 从一个/若干/全部目标移除(默认与 update 同源:含全部 builtin agent + 全部已登记的自定义目录) | | vertu skill known-dirs list / add <path> / forget <path> / scrub | 维护 ~/.vertu/known-dirs.json 注册表(普通流程不需要直接调用,install/uninstall 会自动维护) |

--agent 接受逗号或空格分隔的 id:cursor / claude / claude-code / trae(国际版) / trae-cn(国内版) / openclaw(别名 open-claw / claw) / hermes(别名 hermes-agent / nous),或 all

--dir <path...>(v0.1.5+)支持把同一份 skill 安装/更新/卸载到任意自定义目录,专门用于尚未在 builtin agent 列表里的「未知 Agent」。每个 <path> 会被展开成 <path>/<skill_key>/SKILL.md 并写一份 .vertu-manifest.json,所以后续 vertu skill update 可以同步该目录。要点:

  • 支持 ~ 展开(~/Library/AgentX/skills)与相对路径(按当前 shell 的 cwd 解析)
  • 多路径用空格或逗号分隔:--dir ./skills ./agents/foo/skills--dir "./a,./b"
  • --agent 可混用;同一物理路径只会写一次(按绝对路径去重)
  • 与 builtin adapter 不同的是:dir adapter 不会改写 frontmatter(不加 disable-model-invocation、不加 allowed-tools),仅保证 name 字段存在 —— 让目标 Agent 自己解释 frontmatter
  • install --dir <path> 会自动把绝对路径登记到 ~/.vertu/known-dirs.json,让后续不带任何参数的 vertu skill updatevertu skill uninstall 也会自动覆盖这些目录(详见下一节)
# 安装到自定义目录(首次会自动建目录 + 登记到 known-dirs)
vertu skill install hello-world --dir ~/work/my-agent/skills

# 同时装到 cursor + 一个本地原型 agent
vertu skill install --all --agent cursor --dir ./prototype-agent/skills

# 不带任何参数即可同步全部目标(含 known-dirs 中的自定义目录)
vertu skill update

# 仅同步指定目录(跳过 known-dirs 自动发现)
vertu skill update --dir ~/work/my-agent/skills

# 仅同步特定 builtin agent(跳过 known-dirs 自动发现)
vertu skill update --agent cursor

# 移除(不带参数同样会扫到 known-dirs)
vertu skill uninstall hello-world

自动发现自定义目录:~/.vertu/known-dirs.json

为了让用户无需在每次 update 都重复 --dir <path>,CLI 维护一份全局注册表 ~/.vertu/known-dirs.json

{
  "version": 1,
  "dirs": [
    {
      "path": "C:\\work\\my-agent\\skills",
      "registeredAt": "2026-05-08T...",
      "lastUsedAt":  "2026-05-08T..."
    }
  ]
}

生命周期完全自动:

  • install --dir <path> 成功后把绝对路径写入注册表(已存在则刷新 lastUsedAt
  • update / uninstall 在「未传 --agent 也未传 --dir」时,把注册表内全部还活着的目录展开为 dir:<abs> adapter 一并参与同步;扫描前会自动 scrub 掉两类过期条目:
    • 目录已被手动删掉(stat 返回 ENOENT)
    • 目录还在,但 .vertu-manifest.json 已空(最后一条 skill 已被 uninstall)
  • uninstall <skill> 把某 dir 的最后一条 skill 移除后,会主动从注册表中删除该路径

「显式优先」:一旦传了 --agent--dir不会再去展开 known-dirs,遵循 commander 一贯的"用户给了就尊重"语义。

如果需要手动管理注册表,使用 vertu skill known-dirs 子命令簇:

vertu skill known-dirs list                  # 看现在 update 会自动覆盖哪些目录
vertu skill known-dirs add ~/foo/skills      # 把已经手动拷过 skill 文件的目录纳入自动同步
vertu skill known-dirs forget ~/foo/skills   # 从注册表移除(不删盘上文件)
vertu skill known-dirs scrub                 # 主动 scrub 一遍

vertu skill install 的交互规则(v0.1.4+):

  • TTY 下「skill 维度」与「agent 维度」中任意一个没有显式给出就会进入对应的 inquirer 多选面板(<space> 切换、<a> 全选、<i> 反选、<enter> 确认)。
  • 多选 Agent 默认会勾选「该 Agent 的 manifest 已经至少装过一个 skill」的本机已有 Agent;首次使用则全部预选。
  • 进入过任一交互面板后,末尾默认还会有一次预览 + Confirm?,加 -y / --yes 跳过。
  • CI 或纯命令行场景:完整给出 <skill_keys> / --all--agent 即可绕过所有交互;想强制非交互(让缺参数直接报错而不是 prompt)可加 --no-interactive

跨 Agent 同步是怎么工作的

vertu skill install 时会在每个目标 Agent 的根目录写一份 .vertu-manifest.json,结构:

{
  "version": 1,
  "entries": {
    "hello-world": {
      "skillKey": "hello-world",
      "baseUrl": "https://erp.example.com",
      "installedAt": "2026-...",
      "skillMdSha256": "ab12...",
      "files": [
        { "path": "SKILL.md", "sha256": "ab12..." },
        { "path": "reference.md", "sha256": "cd34..." }
      ],
      "sourceRoute": "/ai/skills/v1/skill_file"
    }
  }
}

vertu skill update 流程:

  1. 扫描各 Adapter 的 .vertu-manifest.json(Cursor / Claude Code / Trae 国际版 / Trae 国内版 / OpenClaw / Hermes)→ 汇总 (agent, skill_key) → installed_sha256,并记下「该 Agent 是否已经至少装过任意 skill」
  2. 一次性 POST /ai/skills/v1/catalog 取远端 content_sha256 与全量 skill_key 列表
  3. 计算并打印对齐表:AGENT SKILL_KEY LOCAL_SHA REMOTE_SHA ACTION(skip|update|install|prune|orphan)
    • install:远端有但本地未装;默认自动补装到「已经在用此 Agent」(manifest 非空)的目录,避免给从未碰过的 Agent 创建文件夹。--no-include-new 关掉这一类
    • prune:本地装过但远端已不存在;默认物理删除目录 + 移除 manifest 条目。--no-prune 关掉后会以 orphan 仅展示不动手
  4. --dry-run 时,对 update / install 复用一份缓存 ~/.vertu/skills-cache/<base_hash>/<skill_key>/ 后分发到各 Agent;对 prune 调用 uninstallSkillFromAdapter 清理本地

凭据与缓存路径

| 类型 | 默认位置 | |------|----------| | 钥匙串条目 | service=vertu-cliaccount=session:<base_url> / account=bearer:<base_url> | | 配置文件(钥匙串不可用时) | %USERPROFILE%\.vertu\config.json(Windows) / ~/.vertu/config.json(macOS/Linux),mode 0600 | | Capabilities 缓存 | ~/.vertu/capabilities.<sha1(base_url)[:12]>.json,TTL 1h | | Skill 文件缓存 | ~/.vertu/skills-cache/<sha1(base_url)[:12]>/<skill_key>/ | | Cursor Skill 安装位置 | ~/.cursor/skills/<skill_key>/ | | Claude Code Skill 安装位置 | ~/.claude/skills/<skill_key>/ | | Trae 国际版 Skill 安装位置 | ~/.trae/skills/<skill_key>/ | | Trae 国内版 Skill 安装位置 | ~/.trae-cn/skills/<skill_key>/ | | OpenClaw Skill 安装位置 | ~/.openclaw/skills/<skill_key>/ | | Hermes Skill 安装位置 | ~/.hermes/skills/<skill_key>/ | | 自定义目录(--dir) | <--dir 给的绝对路径>/<skill_key>/,每个目录一份独立 .vertu-manifest.json | | 已注册自定义目录的全局注册表 | ~/.vertu/known-dirs.json(v0.1.5+,install --dir 自动写入,update / uninstall 默认扫描) |

环境变量

| 变量 | 说明 | |------|------| | VERTU_BASE_URL | 默认 base URL(优先级:--base-url > VERTU_BASE_URL > ~/.vertu/config.jsondefaultBaseUrl > 内置默认值 https://admin.vertu.cn) | | VERTU_BOT_INBOUND_KEY | Bot Bearer token;设了就走 Bearer 模式(CI 推荐) | | VERTU_DISABLE_KEYTAR=1 | 强制走文件存储(CI/容器/裸机调试用) | | VERTU_DEBUG=1 | 打印 dynamic capabilities 加载失败的原因 |

常见问题

1. npm install 报 keytar 编译失败? keytar 是可选依赖。设 VERTU_DISABLE_KEYTAR=1npm install --no-optional,CLI 会自动降级到文件存储。Windows 上若需要 keytar,先装 windows-build-tools(或者直接用文件模式,零依赖)。

2. 我能用 user session 调 /ai/skills/v1/* 吗? 本 CLI 始终用同一个 session/Bearer 头,对 CLI 网关与 Skills 网关无差别处理。前提是 Odoo 侧的 skills_gateway.py 已改造成统一认证(你已确认会做此改造)。

3. 同一台机器同时装了 Trae 国际版和国内版会冲突吗? 不会,但两版互不共享 SKILL 目录:国际版读写 ~/.trae/skills/,国内版读写 ~/.trae-cn/skills/vertu skill install --all 默认会同时写入两份;如果只装了其中一版,可用 --agent trae--agent trae-cn 限定。

4. 怎么把 SKILL.md 提供给项目级的 .cursor/rules/*.mdcAGENTS.md 当前版本只覆盖用户级目录。如需项目级或者 AGENTS.md 整合,请提 issue 说明使用场景,会作为后续 adapter 类型加入。

开发

npm install        # 含 keytar(可选)
npm run dev -- --help
npm run typecheck
npm test
npm run build

测试用 vitest,覆盖:JSON-RPC 客户端(用 undici MockAgent)、Schema → Commander Option、Frontmatter 解析/改写、Adapter 写入、跨 Adapter manifest 扫描。