配置在 ~/.config/jiandu/config.json(多站点共存:{ default, sites: { <别名>: {…} } }),可被 JIANDU_SERVER / JIANDU_TOKEN 覆盖。成功的 push 只在 stdout 打印文档 URL,进度与目标站点在 stderr。
包名 @monoedge/jdu-cli,命令名 jdu。需要 Node.js 22+。官方上架命令从 0.2.0 起提供。0.4.0 起 jdu init 废弃,登录统一走 jdu login——没有默认站点,必须用 --server / --local 指明目标。
登录(选站点 + 拿凭据)
jdu login --server <url> # 指定站点;站点支持时打开浏览器,会话里点一次「授权」
jdu login --local # 本机自部署(http://127.0.0.1:8080)
jdu login --server <url> --token <t> # 没有浏览器的机器:直接用 token 登录
jdu login --server <url> --no-browser # 站点支持浏览器授权也不开,只给 token 指引
jdu login --server <url> --json # 机器可读输出,给 agent 联动用;从不开浏览器
login 会探测目标的 /healthz、写好本地配置,登录方式听 server 声明的 cliAuth.methods:有 browser 就开授权页换 token,有 oidc(forward-auth)就地走完 SSO,只有 token 就在 next 里告诉你去哪拿。--json 输出 { target, server, alias, previousDefault, authProvider, authMethods, loggedIn, configPath, next },loggedIn: true 即可直接 jdu push。
多站点(本地实例 + 团队站点 + 自部署站点)
一台机器可以同时登录多台简牍,凭据按别名各存一格,登录 / 刷新一台不会覆盖另一台。
jdu login --server https://docs.example.com --alias work # 起个短别名;不给则取地址的 host
jdu site list # DEFAULT / ALIAS / SERVER / AUTH / READY(不输出凭据)
jdu site list --json # 给 agent:{ default, sites: [{ alias, server, auth, ready, default }] }
jdu site use work # 切默认上传目标
jdu site rm work # 只删本机凭据,不碰实例,也不动别的站点
jdu push notes/hello.md --site work # 这一次写到 work(push / template push / widget push / blob push 同款)
目标站点解析顺序:--site <别名> > JIANDU_SERVER(一次性覆盖,如 CI)> 默认站点 > 唯一站点。
登录哪台,哪台就成为默认目标(换了会在输出里说明)。多台又没有默认站点时:终端里会列出别名问你选一个,
非交互(管道 / CI / MCP)则直接报错并列出可用别名,不按文档 id 或上次状态猜——免得把稿子发到错的实例。
其他登录形态
怎么登由站点的 /healthz 决定,你不用先知道它是 password 还是 forward-auth——jdu login --server <url> 一条命令,
支持浏览器的就开浏览器(passkey 授权或 SSO),不支持的会告诉你 token 去哪拿。
jdu login --server <url> --token <token> # 没有浏览器的机器(CI、SSH 远端)
jdu login --server <url> --issuer <oidc> --client-id <id> # forward-auth:healthz 没带 OIDC 参数时手动指定
# forward-auth 直连(容器内推 widget/blob、网关外运维):跳过 SSO,请求注入身份头
jdu login --server <url> --user <owner> [--proxy-secret <网关共享密钥>]
forward-auth 的 --user 等价于环境变量 JIANDU_FORWARD_AUTH_USER;fail-closed 实例必须同时给共享密钥(--proxy-secret / JIANDU_PROXY_SECRET),否则 server 不认身份头。
token
jdu token list # 我的 CLI token:ID / LABEL(主机名或 initial)/ CREATED / LAST_USED / CURRENT
jdu token rm <id> # 吊销;正在使用的那枚不能删
文档
jdu push <entry.md> [--title t] [--visibility private|public] [--id <docId>] [--tag 名]... [--official]
jdu list [--all]
jdu versions <docId>
jdu rollback <docId> <seq>
jdu archive <docId> [--undo]
jdu delete <docId> [--hard]
jdu reset <docId>
jdu rerender <docId>
| 命令 | 说明 |
|---|---|
push | 收集本地引用、增量上传、预渲染。--id 发新版本;--official 上架官方库 |
list | 文档列表;--all 含归档 |
versions | 版本序号 / 时间 / hash |
rollback | 把当前显示指回指定序号 |
archive | 归档;--undo 取消 |
delete | 默认软删(归档);--hard 物理删 |
reset | 清空该文档全部版本与产物 |
rerender | 刷这一篇的渲染缓存并预热 |
push 不传 --visibility / --title / --tag 时:新文档分别是 private、首个一级标题、无标签;已有文档保持原值。
模板
jdu template list # 我的 + 官方模板(打了 template 标签的文档)
jdu template pull <docId> [--out 文件.md] # 取原文,按骨架填完再 jdu push
jdu template push <file.md> [--title t] [--id <docId>] [--official]
见 用模板写文档。
接到本机 agent
claude mcp add jiandu -- jdu mcp # Claude Code;codex / dsh 按各自 stdio server 配置法填 jdu mcp
工具:list_docs(给 query 就是搜)/ read_doc / list_versions / list_templates / get_syntax / push_doc / share_doc / archive_doc / list_comments / reply_comment,凭据复用本机配置。
可见性
jdu share <docId> --visibility private|public
改可见性不用重传正文,链接不变。link 档已废除。
官方知识库
npx @monoedge/jdu-cli official list
npx @monoedge/jdu-cli official add <docId>
npx @monoedge/jdu-cli official rm <docId>
上架需管理员。official 是独立档位:公开可读、只进官方库列表。rm 下架后回落到 private,想公开再 jdu share --visibility public。
标签
jdu tag list
jdu tag add <docId> 架构 后端
jdu tag set <docId> 架构
jdu tag set <docId>
jdu tag rename 旧名 新名
jdu tag merge 废名 保留名
jdu tag rm 废名
add 追加,set 覆盖。rename 全站改名,merge 把文档并到目标标签,rm 只解绑不删文档。
Widget
jdu widget push <dir>
jdu widget list
jdu widget enable personal/StarRating@1.0.0
jdu widget disable personal/StarRating@1.0.0
jdu widget approve official/Alert@1.0.0
jdu widget reject personal/Foo@1.0.0
<dir> 下要有 widget.json + index.js(index.css 可选)。引用格式 scope/name@version,照 widget list 抄。approve / reject 需要管理员。
blob
jdu blob push dist/_runtime/*.js
按内容 hash 上传原始资产,stdout 每行一个 /blob/<hash>。Widget 的平台档 runtime 走这条;写普通文档不必用。
环境变量
| 变量 | 作用 |
|---|---|
JIANDU_SERVER | 站点根地址 |
JIANDU_TOKEN | 访问 token |
JIANDU_FORWARD_AUTH_USER | forward-auth 直连身份(注入 X-Forwarded-User 头) |
JIANDU_PROXY_SECRET | forward-auth 网关共享密钥(注入 X-Jiandu-Proxy-Secret 头) |
JIANDU_OIDC_ISSUER | SSO issuer(login 时 healthz 没带才需要) |
JIANDU_OIDC_CLIENT_ID | SSO client id |
退出与输出
- 使用错误(文件不存在、可见性写错、未登录)走
jdu: ...加一行提示,不带堆栈 - 未预期错误带堆栈,当作程序问题
push把 URL 打在 stdout,其它命令的表格也在 stdout,方便管道
教程目录:使用简牍