infinite-talk-cli
v2.1.0
Published
infinite-talk 字幕墙 CLI:设备授权登录、推送/拉取消息、管理设备 token。取代旧的 push_quotes.mjs 单脚本版(v1.0.2)。
Maintainers
Readme
infinite-talk-cli
v2.0.0 起:完整 CLI 客户端,取代 v1.x 单脚本
push_quotes.mjs。
通过设备授权登录 infinite-talk 字幕墙,远程推送 / 拉取 / 管理消息。
安装
npm install -g infinite-talk-cli或本地用 npx:
npx infinite-talk-cli --help首次使用
新部署的环境有两种用户创建路径,互不重叠:
| 角色 | 创建方式 | 首次动作 |
|---|---|---|
| 超级管理员(superadmin)| 由部署方配 env ADMIN_USERNAME / ADMIN_PASSWORD,首次 web 登录强制改密 | 浏览器登录 /admin 改密 → 后续可在 /admin/users 审批注册申请 |
| 普通用户 | CLI:infinite-talk register <用户名> --password <密码>(或 web /register)| 通知 admin 审批 → 等通过后跑 infinite-talk login 走 device-flow |
注意:
- 普通用户不能用注册时的密码登 web:web 路径仅 superadmin 可走,且 web 首次登录强制改密。
- superadmin 也需要先跑 CLI
login(device-flow),拿到 CLI token 后才能用post/push-quotes。
命令速查
| 命令 | 说明 |
|---|---|
| infinite-talk register <username> --password <pw> | 提交账号注册申请(pending);审批通过后跑 login |
| infinite-talk login | 设备授权登录(打印 8 位授权码 + 打开浏览器;30 天有效 token) |
| infinite-talk logout | 清本地凭证(~/.config/infinite-talk/credentials.json) |
| infinite-talk whoami | 显示当前登录 + 服务端校验 token 活性 |
| infinite-talk post <text> | 推一条消息上墙(≤ 800 字、author 默认登录用户名) |
| infinite-talk list [-n N] [-q KW] [--author N] [-b TS] [--admin] | 列出墙上的消息,支持搜索 + 翻页(默认公开 /api/wall,--admin 走后端 /api/admin/messages) |
| infinite-talk devices list\|ls | 列出本账号下的 CLI 设备 token(revoke / delete 请到 web 后台 /admin/devices) |
| infinite-talk push-quotes --file <path> | 批量推送 wall-quotes.json(兼容 v1.0.2 的 JSON 结构;author 缺时回退到登录用户名) |
post 的署名逻辑
post 的 --author(-a)三态:
| 调用 | 行为 |
|---|---|
| post "hi" | author = 当前登录用户名 |
| post -a "@xxx" "hi" | author = @xxx(显式覆盖) |
| post -a "" "hi" | 强制匿名(author = undefined) |
| 未登录 / username 缺失 | 直接 fail,提示重跑 login |
push-quotes 的署名逻辑
JSON 条目里 author 字段缺失时,回退到登录用户名(不再静默变成 (匿名))。JSON 里有 author 的条目以 JSON 为准。
--dry-run 模式下无凭证 → 维持原行为(fallback 静默为空)。
register 的注册流程
register <username> --password <pw> 调后端 POST /api/auth/register 创建一个 status: pending 的普通用户账号。注册成功 ≠ 可登录——必须等 superadmin 在 /admin/users 审批通过。
infinite-talk register alice --password 'correct horse battery staple'
# → 注册申请已提交!
# Server: https://infinite-talk.mixlab.top
# Username: alice
# Status: pending
#
# 下一步:通知 admin 在 /admin/users 批准后,跑 `infinite-talk login` 走设备授权登录。约束(后端强制)
| 字段 | 规则 |
|---|---|
| username | 4-32 字符,匹配 ^[a-zA-Z0-9_\-.]+$(字母/数字/下划线/中横线/点)|
| password | 至少 8 位 |
| 限流 | 3 次 / IP / 小时(429 返回 Retry-After)|
| 禁用账号 | ADMIN_USERNAME 环境变量所配的超级管理员名(防抢注)|
重要约束
- 注册不会自动登录。CLI 不写凭证到
credentials.json——必须等 admin 审批。 - 审批通过后登录走 device-flow(
infinite-talk login),不能用注册时的密码直接登 web:web 路径首次登录会强制改密 + 仅 superadmin 可走。 - 重复注册同一账号返回 409(
账号已被注册);账号名不合规返回 400。
list 的搜索 / 翻页
list 支持四类 query 参数(-q / --author / -b / -n),全部走 server 端过滤,CLI 不再本地 slice。
| Flag | 别名 | 含义 |
|---|---|---|
| -q <kw> | --q | 关键词,case-insensitive substring,同时匹配 text + author |
| --author <name> | — | 作者精确匹配,case-insensitive;与 -q 是 AND |
| -b <ts> | --before | 翻页 cursor(毫秒时间戳),拿 createdAt < ts 的下一页 |
| -n <n> | --limit | 单页条数:admin 默认 100(上限 500)、公开默认 0=不限 |
server 响应里 nextCursor 是下一页第一条的 createdAt,banner 末尾会自动打印翻页提示,例如:
$ infinite-talk list --q hello --limit 3
...
还有未显示的命中条目 → 翻页:--before 1734567890000
$ infinite-talk list --q hello --limit 3 --before 1734567890000
...注意:
-n 0保留旧语义(不渲染任何条目,只看 banner / 命中数)。- 公开模式走
/api/wall的带 query 路径(不走 ETag,适合 CLI / 一次性请求);前端 1s 轮询仍走老路径,行为不变。 maxMessages是物理上限(默认 120)。再老的"历史"早已被 trim,--before翻到底也看不到。
配置(环境变量)
| 变量 | 说明 | 默认 |
|---|---|---|
| INFINITE_TALK_SERVER | server URL 覆盖。优先级最高(见下方说明) | https://infinite-talk.mixlab.top |
| INFINITE_TALK_HOME | 凭证目录覆盖(CI/测试场景) | ~/.config/infinite-talk |
| INFINITE_TALK_NO_UPDATE_CHECK | 设为 1 跳过启动时的版本检查(脚本场景) | 未设(默认开启) |
⚠️
--server参数只在login/register命令下生效。
INFINITE_TALK_SERVER的优先级规则(按命令分):| 命令 | 优先级 | |---|---| |
login/register|--server> env >~/.config/infinite-talk/config.json> 默认 | |list(公开接口)| env >credentials.json的server字段 > 默认 | |push-quotes --dry-run| env > 默认 | |push-quotes(非 dry-run)/post/devices/whoami|credentials.json的server字段 > 默认(env 被忽略) |鉴权命令忽略 env 是有意为之:token 是发给登录时的 server 的,发到别处一定 401。 想换 server 请重新
infinite-talk login --server <新地址>。
自动版本检查
每次执行 CLI 的主命令时(--help / --version / 无参数 / CI=1 / 非 TTY stderr / INFINITE_TALK_NO_UPDATE_CHECK=1 时跳过),异步打一下 https://registry.npmjs.org/infinite-talk-cli/latest,有新版就在 stderr 打提示:
⬆ infinite-talk-cli 2.0.4 → 2.1.0 可用
升级:`npm i -g infinite-talk-cli@latest`(或重新跑 setup 脚本)- 异步 + 不阻塞:跑在
parseAsync之后的.then(),3s 超时不影响主命令退出 - 缓存:
~/.config/infinite-talk/update-check.json,24h 窗口(窗口内不重打 npm) - 不打 stdout:避免破坏
infinite-talk list | jq这类管道消费 - 可关闭:
INFINITE_TALK_NO_UPDATE_CHECK=1
从 v1.0.2 迁移
| v1.0.2 | v2.0.0 |
|---|---|
| push-quotes --file wall-quotes.json --key <API_KEY> | infinite-talk push-quotes --file wall-quotes.json |
| WALL_API_KEY 环境变量 | 已废弃。改用 infinite-talk login(device-flow) |
| WALL_TOKEN / --key | 不再需要。CLI 自动从凭证文件读取 |
| 单文件零依赖 | 需要 Node ≥ 20 + commander(已打包进 dist/cli.js,无需额外 npm install) |
推送 wall-quotes.json 格式
兼容 v1.0.2 三种结构:
// 1. 数组(直接是金句)
[ { "text": "...", "author": "...", "source": "..." } ]
// 2. { quotes: [...] }
{ "quotes": [ { "text": "..." } ] }
// 3. { meta, quotes }(skill 默认输出)
{
"meta": { "recommendedTop": [1, 2, 3] },
"quotes": [
{ "id": 1, "author": "石总", "source": "孵化访谈", "text": "以项目作为统一入口..." }
]
}每条 text ≤ 800 字、author ≤ 40 字,超限自动跳过并计数。
设计要点
- 零依赖运行时:esbuild
--bundle把commander等全部打成一个自包含dist/cli.js,npm install -g后无需任何额外依赖。 - 设备授权(RFC 8628):跟浏览器登录
/admin一致的认证通道,唯一程序化凭证。 - CLI 不写后台:所有变更操作(清屏、撤销 token、删除消息)必须 admin session,CLI 只读 + 上墙。
register是唯一的写账号动作:提交注册申请(pending 用户),不直接登录;其它写动作(post / push-quotes)仍只走已审批用户。- 凭证文件
chmod 600:存在~/.config/infinite-talk/credentials.json,可升级到 keytar/libsecret。
本地开发(infinite-talk 主仓库内)
cd cli
npm install
npm run build # 编译到 dist/cli.js
npm run smoke # 跑 --help 验证主仓库用 bin/infinite-talk.js wrapper 通过项目内的 tsx 直接跑源码(npm run cli -- <cmd>)。发布前 cd cli && npm run build + npm publish。
License
MIT
