pdlab-cli
v0.7.3
Published
开源共建平台(problem-driven-lab)的命令行工具:项目、内容的增删改查,浏览器授权登录
Maintainers
Readme
pdlab
1836 开源共建平台的命令行工具。
它是平台现有 REST API 的薄封装——没有任何绕过后端的旁路,权限、审核、积分规则一律由服务端判定。 你在网页上是什么角色,在命令行里就是什么角色。
npm install -g pdlab-cli需要 Node 18 或更高(用到了全局 fetch)。
包名是
pdlab-cli,但装完之后敲的命令是pdlab。 (包名叫pdlab会被 npm 的防仿冒过滤判定为与已有包lab过于相似,无法发布。)
快速开始
pdlab login # 打印 8 位授权码并打开浏览器授权;默认连官方部署 https://www.1836.online,
# 首次登录会隐式建 profile 'www.1836.online' 作为默认
pdlab whoami # 看看当前是谁
pdlab project list # 列出项目
pdlab schema # 一次性 JSON 输出全部命令、参数、权限要求、示例、环境变量和退出码含义——给 agent/脚本用默认地址是
https://www.1836.online(带www,以src/config.ts的DEFAULT_API_URL为准)。 不用裸域名1836.online:它会 308 跳到www,而跨域名重定向会让 fetch 丢掉Authorization头,带 token 的请求会静默变成匿名请求。
给 agent / 脚本用
pdlab schema # 先读这个:命令树、参数、权限、环境变量、输出约定、退出码
pdlab whoami --json # 全局 --json:login/logout/register/whoami/profile/config 也输出 JSON
PDLAB_TOKEN=pdlab_xxx pdlab post list --status pending # CI / 无人值守:用环境变量传 token,免交互 login
pdlab login --no-browser --json # 不开浏览器;stderr 先输出一行 {"event":"authorization_pending","code":"ABCD2345","verifyUrl":...}- stdout:成功时恒为一个 JSON 文档。资源命令(project / post / collection / comment / like / notification / search / token / taxonomy)一直如此;账号/配置类命令默认是中文文本,加
--json(或PDLAB_JSON=1)后改为 JSON。 - stderr:过程提示(如「等待授权中…」);
--json下是逐行 JSON 事件。失败时是结构化错误 JSON(见下方「报错与退出码」)。 PDLAB_TOKEN:优先级高于 profile 里保存的 token,不落盘。token 可以在任意机器上pdlab login后从~/.pdlab/config.json取得,撤销用pdlab token revoke <id>或网页「个人中心 → API Token」。- 分页:列表返回
nextCursor,原样传给--cursor取下一页,null表示没有更多。
切换多账号 / 多站点
需要同时管官方部署 + 自建 staging?用 profile:
pdlab profile create staging --api-url https://staging.example.com # 创建一个空 profile
pdlab login --profile staging # 在 staging 上登录
pdlab profile set-default staging # 之后未传 --profile 都走 staging
# 任意命令都可临时切
pdlab project list # 看 default(staging)
pdlab project list --profile www.1836.online # 临时切到官方部署login 不带 --profile 时会用 apiUrl 的 host 当 profile id(如 www.1836.online、staging.example.com;带端口时 : 换成 -,如 localhost-3000),并自动设为默认(仅首次)。带 --profile <id> 时严格使用用户给的名字,重名报错不会自动追加 -2。
自建实例
pdlab login --api-url https://your-1836-instance.example.com
pdlab login --api-url https://your-1836-instance.example.com --no-browser # 远程 SSH / 容器里:只打印链接login 会打印一个 8 位授权码和授权链接,并(除非传了 --no-browser)打开浏览器。你在网页上核对授权码、
确认「以 XX 身份授权 pdlab 命令行工具」之后,终端会自动拿到凭证。整个过程不需要在命令行里输入密码。
登录时带的 --api-url 会存进 profile;首次登录的 profile 会成为默认,之后的命令不用再带 --api-url。
命令
| 命令 | 说明 |
|---|---|
| pdlab login [--no-browser] | 浏览器授权登录(打印 8 位授权码 + 链接)。凭证长期有效,直到被撤销 |
| pdlab register [--no-browser] | 提交注册申请。注册后需管理员审核,不会自动登录 |
| pdlab logout | 清除本地凭证(不撤销服务端的,用 pdlab token revoke) |
| pdlab whoami | 查看当前登录账号 |
| pdlab config get / set <key> <value> | 查看/修改本地配置 |
| pdlab profile list | 列出所有 profile(每个 profile 一份凭证) |
| pdlab profile create <id> [--api-url <url>] | 创建空 profile(不登录) |
| pdlab profile set-default <id> | 设置未传 --profile 时默认使用的 profile |
| pdlab profile rename <old> <new> | 重命名 profile;是 default 时 defaultProfile 自动跟随 |
| pdlab profile delete <id> | 删除 profile;是 default 时拒 |
| pdlab schema | JSON 输出完整命令树 + 权限要求 + 示例 + 环境变量 + 输出约定 + 退出码含义 |
| pdlab project list \| get \| create \| update \| delete | 项目的增删改查 |
| pdlab project join \| leave <id> | 报名共建 / 撤回申请或退出共建 |
| pdlab project member review \| set-role \| remove <projectId> <userId> | 审核报名、设置协作者角色、移除参与者(仅项目发起人本人) |
| pdlab project revenue <id> | 查看项目的积分分成明细(只读) |
| pdlab collection list \| get \| create \| update \| delete | 项目集合(「解决方案云展厅」)的增删改查(public 集合公开只读,写操作需 collection:manage) |
| pdlab post list \| get \| create \| update \| delete | 内容的增删改查(create 的 --project-id 选填:不传即为独立发布;传了则须是该项目发起人或已通过审核的参与者) |
| pdlab post review <id> --action approve\|reject | 审核一条待审内容 |
| pdlab taxonomy list \| create \| update \| delete | 分类标签的增删改查(列表公开只读,写操作需 taxonomy:manage) |
| pdlab taxonomy dimension list \| create \| update \| delete <key> | 分类维度的增删改查(内置维度不可删) |
| pdlab comment list \| add --post-id <id> \| --project-id <id> | 列出 / 发表留言(发表需 social:comment,免审即时可见) |
| pdlab comment delete <id> | 删除留言(本人、宿主作者/发起人或管理员) |
| pdlab like toggle --target-type post\|project\|comment --target-id <id> [--state on\|off] | 点赞 / 取消点赞,输出 { liked, count } |
| pdlab notification list [--limit] [--cursor] | 通知列表(游标分页,含全量 unreadCount) |
| pdlab notification read <id> \| --all | 标记已读 |
| pdlab search <q> | 全站搜索(公开可用,登录后按可见范围扩展) |
| pdlab token list \| revoke <id> | 列出 / 撤销当前账号的 API Token |
任何命令加 --help 看具体参数——示例已经直接打在 --help 末尾,不用等一次报错才能看到。
所有资源命令都支持 --api-url <url> 和 --profile <id> 两个 flag,
前者临时覆盖地址、后者临时切 profile(同时用该 profile 的 token 和 apiUrl);环境变量对应 PDLAB_API_URL / PDLAB_PROFILE。
全局 --json 可以放在命令行任意位置。
报错与退出码
失败时,一个 JSON 对象会打到 stderr(不是人类可读的长句),方便脚本/agent 解析:
{ "error": "无权限执行此操作", "code": "forbidden", "status": 403, "apiCode": "FORBIDDEN" }校验类错误还会带上 fields(哪个字段、什么问题)和 hint(对应命令的示例);
apiCode 是服务端响应里的机器可读 code(如 RATE_LIMITED),429 / 423 时还有 retryAfter(秒)。
CLI 的 code 优先按服务端 apiCode 判定,老版本服务端没有时再按 HTTP 状态码。
退出码和 code 一一对应,pdlab schema 的 exitCodes / errorCodes 字段里也有同一份:
| 退出码 | code | 含义 | 建议的处理 |
|---|---|---|---|
| 0 | — | 成功 | — |
| 2 | validation | 参数校验失败(本地或服务端) | 按 fields/hint 改参数重试 |
| 3 | unauthenticated | 未登录或 token 已失效 | pdlab login,或设置 PDLAB_TOKEN |
| 4 | forbidden | 无权限 | 不要重试,告知用户 |
| 5 | not_found | 资源不存在 | 检查 id 是否正确 |
| 6 | conflict | 状态冲突(如重复审核) | 不要重试,状态已经变了 |
| 7 | network | 连不上 API 服务器 | 检查 --api-url/网络后重试 |
| 8 | locked | 账号因多次登录失败被临时锁定(423) | 等 retryAfter 秒后再试 |
| 9 | rate_limited | 请求过于频繁被限流(429) | 等 retryAfter 秒后重试 |
| 10 | expired | 浏览器授权 / 注册握手已过期 | 重新运行 pdlab login / pdlab register |
| 1 | unknown / 未分类 | 其他 | 按错误信息人工排查 |
配置
配置存在 ~/.pdlab/config.json(目录 0700、文件 0600):
{
"defaultProfile": "www.1836.online",
"profiles": {
"www.1836.online": { "apiUrl": "https://www.1836.online", "token": "pdlab_…" },
"staging": { "apiUrl": "https://staging.example.com", "token": "pdlab_…" }
}
}解析顺序
每条命令都按以下顺序解析 apiUrl 与 token(高优先级覆盖低优先级):
| 字段 | 顺序(高 → 低) |
|---|---|
| apiUrl | --api-url flag > PDLAB_API_URL env > 当前 profile 的 apiUrl > 默认 https://www.1836.online |
| profile | --profile flag > PDLAB_PROFILE env > 配置的 defaultProfile > 内置 default(hostFrom(DEFAULT_API_URL)) |
| token | PDLAB_TOKEN env > 当前 profile 的 token |
--api-url 与 profile 是独立的两条链:
- profile 决定用谁的 token(identity)
- apiUrl 决定指向哪个服务器(endpoint)
所以你可以用 staging profile 的 token + 临时指向 production URL 排查问题,或者反过来。
跨机器迁移
config.json 整文件复制即可。不要给 token 加密(仍是明文 + 0600 文件权限,依赖 OS 文件权限隔离)。
profile id 合法性
^[a-z0-9._-]+$,禁止 --(避免命令行 --profile foo 被 commander 误读成 --profile flag 后接 foo)。
老 config 自动迁移
如果你升级前是 { "apiUrl": "...", "token": "..." } 扁平格式,第一次 pdlab login / pdlab whoami 读 config 时会自动迁移成 { defaultProfile: <host>, profiles: { <host>: { apiUrl, token } } } 并写回。一次迁移、永久新格式。
