跳到正文
ArchiveZaunEkko Docs
阅读设置
正文字号
字体
简体中文English
展开文档目录

命令行与 agent

状态
生效中
更新
2026-09-15
适用范围
ekko CLI

ekko 是 ZaunEkko 站内能力的命令行分身。你在网页上能看到什么,它就能读到什么——包括等级门禁后面的内容,因为它用的是你自己的身份。

它的设计目标不只是「给人用的命令行」,而是让别人的 agent 用起来和人访问网页一样顺畅。所以它有机器可读的能力清单、稳定的错误码,以及在管道里自动切换成 JSON 的输出。

安装

npm install -g @zaunekko/cli

包里是一个启动器加各平台已编译的二进制,装完就有 ekko 命令。

ekko version

不要从源码构建——那个仓库是私有的,那条路对你不通。

登录

ekko login

命令会打开浏览器,把你送到 ZaunEkko Account 的登录页;授权完成后浏览器会显示一行完成提示,终端同时拿到凭据。整个过程和你平时登录网站是同一个界面。

如果这台机器打不开浏览器(服务器、容器、SSH 会话),命令会自动改用验证码方式:终端打印一个网址和一串验证码,你在任意一台能上网的设备上打开那个网址、输入验证码即可。手机也行。

无论哪条路,终端始终会把网址打印出来——自动打开浏览器这件事在不少环境里会静默失败,只有打印出来才保证你还有办法继续。

ekko login --no-browser   # 不尝试自动打开,只打印链接
ekko login --device       # 直接走验证码,不尝试本机回调
ekko login --force        # 已登录时也重新授权

登录一次能用很久:凭据会自动续期,只有连续很长时间不用才会失效。

你授出去的是什么

同意页会列出这次授权的权限。其中 blog.read 值得单独说一句:它让命令行读到你自己能读到的全部 Blog 内容,包括等级门禁后面的。这正是这个工具存在的意义——让 agent 看到和你在浏览器里看到的一样——但你应当知道自己授出去的是什么。

全部是只读。 发文、发说说、评论、上传都不在里面。

撤销

在 Account 的「登录与安全」页面,「已授权的应用」一栏可以随时撤销。撤销后该机器无法再续期;已经签发出去的访问令牌最长还能再用 15 分钟。

ekko logout 只清除本机凭据,不撤销服务端的授权——机器丢了要用上面那个入口。

能做什么

登录
  ekko login                      浏览器登录;起不了监听时自动改用验证码
  ekko logout                     清除本机凭据
  ekko whoami                     本机凭据里的身份与权限;不联网
  ekko account                    等级、积分与站点角色的当下值;只读

服务目录与调用
  ekko catalog ls                 列出公开服务
  ekko catalog show <service>     服务详情;--version + --contract 看请求/响应契约
  ekko invoke <service>           发起一次调用(会消耗积分)
  ekko invocations ls             调用回执列表
  ekko invocations show <id>      单条回执
  ekko rate-limit                 当前调用窗口额度

服务状态
  ekko status                     公开服务健康摘要
  ekko status incidents           事件记录

ZaunEkko's Blog(只读)
  ekko blog posts ls              你能读到的文章
  ekko blog posts show <slug>     单篇文章
  ekko blog moments ls            说说

给 agent
  ekko schema                     机器可读的能力清单

未登录时除 login / logout / version / help / schema 外一律不工作,不提供匿名只读降级。这是刻意的:能匿名跑一半的工具会让你分不清「我没登录」和「这个东西不存在」,而在 Blog 这种有等级门禁的地方,那个区别就是你看到的是全部还是半份。

上架服务、登记服务主体这类不可逆的操作不在命令行里,请在 Marketplace 控制台完成。

发起调用

ekko invoke pixiv.daily-ranking \
  --version v1 \
  --idempotency-key daily-ranking-2026-09-15 \
  --input '{"mode":"daily"}'

--input 接三种形式:JSON 字面量、@文件路径、以及 @-(从标准输入读)。

--idempotency-key 是必填的,而且用错要花钱

它的作用是防止重复计费。网络超时、连接中断、重试——这些情况下你无法确定请求是否已经到达。此时用同一个 key 重发,平台会认出这是同一次调用,返回原来那次的结果,而不是产生第二笔消耗。

因此这个 key 必须:

一个可用的做法是把业务标识和时间窗拼进去,例如 daily-ranking-2026-09-15。

不要用随机值。 每次重试都换一个随机 key,等于把这个机制关掉——而关掉它的代价是重复扣费,且不会有任何报错。

契约的完整说明见认证与调用,那一页是调用面的权威。

两种凭据

ekko loginZAUNEKKO_API_KEY
适合你自己在终端里用无人值守的定时任务
能做全部命令只能调用服务
读 Blog能不能
有效期自动续期长期,可随时吊销

API key 在 Account 的「API key」页面创建。把它放进环境变量:

export ZAUNEKKO_API_KEY=zek_live_...
ekko invoke ... # 不需要登录

key 只能调用服务。治理类命令遇到它会明确报错,而不是让服务端回一个看不出原因的 403。

给 agent 的接入契约

输出形态由管道决定,不由参数决定

ekko catalog ls              # 人在终端里敲 → 表格
ekko catalog ls | jq         # 进管道 → JSON
ekko catalog ls > out.json   # 重定向 → JSON

这与 ls、git 对颜色的处理是同一个惯例。--json 与 --table 显式覆盖这个判断。

表格是给人看的,格式随时可能调整,不要解析它。 JSON 转发服务端响应原样。

退出码

码含义
0成功
2未登录——CI 里据此触发重新认证
1其他失败

2 单独留给未登录,是为了让脚本不必去 grep 错误文案——文案会改,改一个字你的判断就静默失效了。

错误体

JSON 输出时,错误也写在 stdout(错误也是结果的一种,写进 stderr 会让调用方在 stdout 上读到空然后去猜):

{
  "error": {
    "code": "RATE_LIMIT_EXCEEDED",
    "message": "...",
    "hint": "调用没有发生,也没有扣费;等 retryAfter 秒后再提交新的调用",
    "retryAfter": 37
  }
}

code 是稳定的:NOT_LOGGED_IN、USAGE、NETWORK、UNAUTHORIZED、FORBIDDEN、NOT_FOUND、RATE_LIMIT_EXCEEDED、SERVER_ERROR、UNKNOWN。

按 code 判断,不要按 message 判断。

自我描述

ekko schema

输出全部命令、参数、哪些需要登录、哪些会消耗积分,以及输出形态与退出码的约定。agent 不必先读文档就能知道这个工具能做什么。

这份清单本身也是契约,字段刻意少而稳;schemaVersion 变了说明形状变了。

配置

全部通过环境变量,没有配置文件——装在别人机器上的工具,配置文件会变成排查时看不见的那一层。

变量用途
ZAUNEKKO_API_KEY无人值守凭据
ZAUNEKKO_HOME凭据存放目录(默认 ~/.zaunekko)
ZAUNEKKO_DEVICE_NAME「已授权的应用」里显示的机器名;设成空串则不上报

版本

ekko 有自己的版本号,与站点发布无关。它永不假设自己和服务端同版本:版本过旧只提示不阻断,发现新版本只打印提示,绝不自动安装。

升级和安装是同一条命令:

npm install -g @zaunekko/cli