@kunworlds/novel-cli
v0.2.3
Published
Agent-first creation and diagnostics CLI for the Jujing Novel system
Maintainers
Readme
Novel CLI
@kunworlds/novel-cli 是剧鲸 Novel 面向 Agent 的创作与诊断 CLI。它既能调度需要明确确认的创作工作,也能把问答、工具调用、Skill、运行快照和产物证据导出到本地,供 Codex、Claude Code 等外部 Agent 或开发者继续处理。
它通过 Novel 服务的鉴权 HTTP API 读取项目、单条问答、QA 诊断运行、创作产物和爆款分析;不会改写项目,也不会把令牌保存到配置文件。
适用场景
- 发起需要用户确认的爆款拆分等创作工作,并查询处理结果。
- 定位一次创作问答为什么没有调用预期 Skill、工具或审核链路。
- 把一个项目、单条消息或爆款分析的证据导出到本地,交给更强的外部 Agent 排查。
- 在 CI 之外的本机或 Agent runtime 中检查诊断接口、配置和鉴权是否可用。
不适用于直接生成、改写、删除 Novel 项目内容;这些创作写操作不会进入诊断 CLI 的命令面。命令面有两类显式写操作:project audit 只追加带正文/rubric 哈希的审核证据;analysis breakdown ... --yes 可创建或复用爆款记录并提交拆分任务。两者都不修改创作产物,后者必须先预览并得到用户明确确认。
安装与登录
需要 Node.js 22 或更高版本。系统钥匙串持久登录支持 macOS 和 Windows;Linux Agent 使用令牌注入,不使用持久钥匙串。
macOS / Windows
以下命令在 macOS Terminal 和 Windows PowerShell 中相同。首次登录默认连接 https://novel.kunworlds.com,浏览器确认后令牌写入 macOS Keychain 或 Windows Credential Locker:
npm install -g @kunworlds/novel-cli
novel login
novel doctor --json裸 novel login 始终登录生产环境,并保存到 default profile;历史 default profile 和 JUJING_API 都不会改变这次登录目标。除 login 外的命令使用 default profile,但不会在缺少配置时静默连接生产环境,而是返回 API_REQUIRED。
macOS / Windows 连接开发或测试环境时,必须显式配置独立 profile,再登录:
novel config set --profile dev --api http://localhost:7005
novel login --profile dev
novel whoami --profile dev --jsonLinux Agent / CI
Linux 当前可以打开浏览器授权页,但授权完成后无法写入系统钥匙串,novel login 最终会返回 KEYCHAIN_UNAVAILABLE,因此不能形成持久登录。先保存仅含 API 地址的 profile:
npm install -g @kunworlds/novel-cli
novel config set --profile prod --api https://novel.kunworlds.combash / sh 的当前 shell 可注入环境变量:
export JUJING_TOKEN='YOUR_TOKEN_FROM_SECURE_SOURCE'
novel doctor --profile prod --jsonWindows PowerShell 在临时会话或 CI 调试时也可用同一环境变量契约:
$env:JUJING_TOKEN = "YOUR_TOKEN_FROM_SECURE_SOURCE"
novel doctor --profile prod --json示例中的值只是占位符。CI 应从 secret manager 注入 JUJING_TOKEN;本地只在当前私密 shell 设置,结束后清除。不要把真实 token 写进 profile、脚本或 shell history。一次性 --token 是最后兜底,也应引用已安全注入的变量,不要把真实值直接写在命令行,例如 novel doctor --profile prod --token "$JUJING_TOKEN" --json。
查看、切换或删除环境配置时,配置文件只包含 API 地址和可选标签,不包含令牌:
novel config list --json
novel config get --profile dev --json
novel config remove --profile dev --json给 Agent 的 30 秒开始
查看 CLI 内置帮助:
novel --help
novel project audit --help查看和升级版本:
novel --version
novel upgrade --check
novel upgrade交互终端启动普通命令时会读取本地版本缓存;缓存超过 24 小时才访问 npm Registry。发现新版本只在 stderr 提示,不会自动安装。--json、非交互终端和 novel mcp 不显示启动提示,避免污染 Agent 协议。断网或 Registry 暂时不可用不会阻断登录、诊断和导出命令。
novel mcp 与 CLI 同属 @kunworlds/novel-cli。升级 CLI 会同时升级 MCP 适配器,不需要安装或更新第二个 MCP 包。
让 Agent 先发现当前稳定的命令面:
novel doctor --schema --json然后按问题范围读取证据:
# 导出一条 assistant message 及其工具调用
novel message diagnose <message-id> --profile dev --json
# 精确导出评审页选中的历史运行(不会退化成“项目最近一次”)
novel run diagnose <run-id> --profile dev --json
# 导出项目当前产物和诊断线索
novel project export <project-id> --profile dev --json
# 对当前持久化正文发起一次显式质量审核
novel project audit <project-id> --phase phase3 --profile dev --json
# 导出项目关联的全部 QAchat 对话和工具调用
novel project conversation <project-id> --profile dev --json
# 导出单个线程;新轮次同时给出 run、Skill 与发布技能包的精确关联
novel thread pull <thread-id> --profile dev --json
# 导出一个爆款分析及其产品
novel analysis pull <analysis-id> --profile dev --jsonAgent 必须渐进取数:先识别 run/message/thread/project/artifact/analysis 目标和精确 ID,优先执行单个 inspect/diagnose;只有明确证据缺口需要工具参数、结果或中间消息时,才升级到 --include-raw、完整 thread 或 project conversation。证据足够后立即停止,避免上下文和 token 无边界增长。
thread pull 和 project conversation 的导出文件包含 attribution。status=exact 表示工具调用已通过持久化的 run_id + provider_tool_call_id 精确关联到冻结技能包;partial 表示存在 run 但缺少部分锚点或结构化调用;unavailable 表示历史线程没有 qa_runs 快照。CLI 不会根据 Skill 名称猜测技能包。
--json 的 stdout 始终只输出一个 JSON 值。文件会写到 files 字段所列的绝对路径,外部 Agent 应优先读取这些文件,而不是解析终端文案。
爆款分析:渐进拉取与拆分
对老板或 Agent,最稳妥的顺序是“搜索 → 看摘要 → 只拉需要的正文 → 预览拆分 → 用户确认后提交”。先执行三条只读命令:
novel analysis list --search "替身新娘" --json
novel analysis inspect "替身新娘" --json
novel analysis pull "替身新娘" --include overview,creative-card --out ./.jujing/analyses --json需要拆分云盘内容时,单独执行预览命令。不要添加 --yes:
novel analysis breakdown "https://pan.quark.cn/s/share-id" --title "替身新娘" --content-type "短剧/微短剧" --genre-code urban-setting --tags "情感框架,逆袭" --json暂停,不要自动提交: 必须先读取外层
ok和data.stage。只有data.stage为awaiting_confirmation时,才向用户展示并核对完整data.summary(以及可能的data.reuseAnalysisId)。等待用户在看到这些信息后明确确认;Agent 不得在同一轮串行执行 preview 和--yes,也不得把“看看”“分析一下”推断为确认。其它 stage 按下表处理,不执行确认命令。
用户明确确认后,在后续一步中单独执行:
novel analysis breakdown "https://pan.quark.cn/s/share-id" --title "替身新娘" --content-type "短剧/微短剧" --genre-code urban-setting --tags "情感框架,逆袭" --yes --json前三条是渐进读取。list 返回轻量列表,inspect 返回单条元数据、运行状态和产品清单,pull 才会把正文写到 --out 指定的本地目录。--include 可选 overview、source、reports、creative-card、products、all,默认只拉 overview,creative-card。先从最小分组开始;证据足够就停止,避免完整正文和全部产品造成上下文、token 膨胀。
名称可以用于 inspect 和 pull。如果服务返回 AMBIGUOUS_ANALYSIS_NAME,表示存在多个同名爆款;不要猜测,也不要重复用名称。应从 error.details.candidates 选择正确 ID,把原命令中的名称替换成该 ID 后重试。未找到时也可检查候选 ID,或回到 analysis list --search ...。
预览命令不带 --yes,只做云盘检测、必填项检查、查重和提交预览;它不会创建爆款记录,也不会提交任务。确认命令只能在上述暂停和用户明确确认之后单独执行。
breakdown 的 HTTP 请求成功时,CLI 外层 JSON envelope 的 ok 为 true;工作流结果在 data 内,必须按 data.stage 分支,不能只看文案:
| data.stage | 含义 | 下一步 |
| --- | --- | --- |
| needs_input | 缺少标题、内容类型、题材代码或标签。 | 按 data.missingFields 补齐,再运行不带 --yes 的预览。 |
| awaiting_confirmation | 预检完成,尚未创建或提交。 | 展示 data.summary,等待用户明确确认;确认后才运行带 --yes 的命令。 |
| duplicate_found | 找到可见重复项,或检测到不可见的同资源冲突。 | 停止创建;可见时检查 data.duplicateCandidates,不可见时联系管理员确认权限。 |
| already_running | 同一资源已有活动任务,或任务准入复用了现有任务。 | 不重复提交;用返回的 analysisId 执行 analysis inspect。 |
| already_completed | 同一资源已有完成且可用的分析。 | 用返回的 analysisId 直接 inspect,需要正文时再 pull。 |
| started | 新任务已提交,爆款记录可能是新建,也可能是复用。 | 保存 analysisId 与 taskId,用 analysis inspect <analysisId> 跟踪。 |
| created_pipeline_failed | 爆款记录已创建或复用,但任务提交失败。 | 保留 analysisId;稍后用同一云盘链接和已确认参数重新运行带 --yes 的命令,系统会尝试复用记录。 |
data.ok: false 也可能是可处理的工作流分支(如 needs_input、duplicate_found、created_pipeline_failed),不等同于 CLI 传输失败。真正的 CLI 失败会让外层 envelope 的 ok 为 false,并在 error.code/message/hint/details 给出原因。
本地开发
在仓库根目录的 server/ 下构建和运行:
pnpm --filter @kunworlds/novel-cli build
node packages/novel-cli/dist/index.js config set --profile dev --api http://localhost:7005
node packages/novel-cli/dist/index.js doctor --profile dev --json运行 doctor 前按上方平台说明提供凭证:macOS / Windows 使用 login,Linux Agent 注入 JUJING_TOKEN。
打包前先执行(不要在验证流程中运行 npm publish):
pnpm --filter @kunworlds/novel-cli test
pnpm --dir packages/novel-cli pack --dry-run包已具备公开 registry 的发布清单,并发布在 npm 组织 kunworlds 的公共 scope 下。
命令
所有读取命令都接受:
--api <origin> 本次调用覆盖 profile 的 API 地址
--profile <name> profile 名;默认 default
JUJING_API 无 --api/profile 时的环境地址覆盖
--token <token> 本次调用令牌(优先级最高)
--out <directory> 本地导出目录;默认 ./.jujing/diagnostics
--json 输出机器可读 JSON envelope| 命令 | 用途 |
| --- | --- |
| novel --help / novel <命令> --help | 查看总帮助或当前命令的参数与示例;不访问网络。 |
| novel --version | 查看当前安装版本,不访问网络。 |
| novel upgrade --check | 强制查询 npm Registry,只检查是否有新版本。 |
| novel upgrade | 通过 npm 全局安装最新版;不自动使用 sudo 或提升权限。 |
| novel config set --profile <name> --api <origin> | 创建或更新环境 profile;兼容别名为 novel setconfig。 |
| novel config get --profile <name> | 查看一个环境配置,不读取或显示令牌。 |
| novel config list | 列出全部环境配置。 |
| novel config remove --profile <name> | 删除 profile 配置,不隐式删除系统钥匙串凭证。 |
| novel login [--api <origin>] [--profile <name>] | 拉起浏览器登录;裸命令始终使用生产地址,其他环境必须显式指定。 |
| novel logout [--profile <name>] | 清除当前 profile 的系统钥匙串凭证。 |
| novel whoami [--profile <name>] | 验证当前登录身份和凭证来源。 |
| novel init --api <origin> [--profile <name>] --yes | 非交互式保存 API profile;不保存令牌。 |
| novel doctor | 检查诊断 API,并报告令牌来源而非令牌内容。 |
| novel run diagnose <run-id> | 按唯一 run ID 导出冻结配置、事件、产物关联和审核证据。 |
| novel project diagnose <project-id> | 定位最近一条 QA diagnostic run 并导出运行证据。 |
| novel project audit <project-id> --phase <phase> [--run <run-id>] | 审核当前持久化正文,并按正文/rubric 哈希复用或创建审核记录。 |
| novel project inspect <project-id> | 导出项目阶段与诊断概览。 |
| novel project export <project-id> | 导出项目概览和当前阶段产物。 |
| novel project conversation <project-id> | 导出项目关联的完整 QAchat 对话、工具调用及 run/Skill/技能包归因。 |
| novel message diagnose <message-id> | 导出一条消息、其关联用户消息和工具调用。 |
| novel thread pull <thread-id> | 按线程导出完整问答、工具调用及精确/部分归因状态。 |
| novel artifact pull <project-id> <phase> | 拉取一个阶段的当前产物。 |
| novel analysis list [--search <text>] | 分页搜索可访问的爆款;--all 必须与 --out 同用。 |
| novel analysis inspect <name-or-id> | 查看爆款元数据、运行状态和产品清单,不写文件。 |
| novel analysis pull <name-or-id> [--include <groups>] | 按分组导出爆款正文和产品 Markdown。 |
| novel analysis breakdown <cloud-url> ... [--yes] | 无 --yes 只预览;得到用户明确确认后,带 --yes 才可创建/复用记录并提交任务。 |
| novel mcp [--profile <name>] | 启动本地 stdio MCP,供 Codex / Claude Code 调用有边界的创作与诊断工具。 |
| novel auth set-token --token <token> [--profile <name>] --yes | 显式写入当前 profile 的系统钥匙串。 |
| novel auth clear-token [--profile <name>] --yes | 显式清除当前 profile 的系统钥匙串令牌。 |
| novel <任一有效命令> --schema --json | 返回当前命令面的机器可读能力说明。 |
Profile 和认证
profile 只保存 API 地址与可选标签。默认路径为:
| 平台 | 配置路径 |
| --- | --- |
| macOS | ~/Library/Application Support/jujing-novel/config.json |
| Windows | %APPDATA%\jujing-novel\config.json |
| Linux | $XDG_CONFIG_HOME/jujing-novel/config.json,或 ~/.config/jujing-novel/config.json |
普通读取命令的 API 地址解析优先级为:--api、profile、JUJING_API。登录命令单独遵循:显式 --api、显式 --profile、生产地址;裸 novel login 始终使用 https://novel.kunworlds.com 并更新 default profile。
服务端本地开发还有一个权限旁路:ALLOW_MISSING_IAM_PERMISSION_SOURCE=true。它只在 IAM 权限源完全不可用、值严格为 true,且 NODE_ENV 和 BUILD_ENV 都不是 production 时生效,仅用于非生产本地环境。任何生产标记都会忽略这个旁路并 fail closed(拒绝授权);不要把它写入生产配置,也不要把它当作 CLI 登录替代品。
友好错误
默认人类输出会说明错误、当前 profile、相关 API 地址和可直接执行的下一条命令。网络错误会区分连接拒绝、DNS、超时与 TLS,不再只输出 fetch failed。--json 模式继续输出稳定的 error.code/message/hint/details,并且不会包含 token、Authorization header、设备 secret 或内部堆栈。
令牌解析优先级:
--tokenJUJING_TOKEN- 系统钥匙串(macOS Keychain / Windows Credential Locker)
- 缺失
对 Agent,推荐从当前 shell 或 CI secret 注入短生命周期环境变量。macOS / Windows 用户也可通过 login,或显式使用 novel auth set-token --token … --yes 写入受支持的系统钥匙串;Linux 不支持该持久化路径。避免把真实 --token 值放进 shell history 或共享脚本;profile 配置文件始终不含令牌。
JSON 契约
成功:
{
"ok": true,
"schema_version": 1,
"environment": "dev",
"data": {},
"files": ["/absolute/path/evidence.json"],
"warnings": []
}失败:
{
"ok": false,
"schema_version": 1,
"environment": "unknown",
"error": {
"code": "AUTH_REQUIRED",
"message": "Novel API token is required.",
"hint": "Pass --token or set JUJING_TOKEN."
}
}schema_version 只在不兼容变更时递增。外部 Agent 必须按 ok 分支处理结果,不得从 message 推断状态。message diagnose 默认不返回工具输入/输出和原始 message parts;只有 --include-raw 才会请求完整单轮 raw parts。历史消息缺少精确 QA run 锚点时返回 partial,不会用时间窗伪装 exact。
本地开发使用共享调试密钥时,可额外显式传入 --debug-user-id <id>;它只会作为本次请求的 X-Debug-User-Id 头发送,不写入 profile 或钥匙串。常规使用仍应配置用户自己的 MCP Token。
本地证据结构
诊断命令的默认导出目录为 ./.jujing/diagnostics。消息和项目导出常见结构:
.jujing/diagnostics/
├── <message-id>/
│ ├── README.md
│ ├── message.json
│ ├── user-message.md
│ ├── assistant-message.md
│ └── tool-calls.json
├── <project-id>/
│ ├── README.md
│ ├── project-export.json
│ └── artifacts/
│ ├── phase3.json
│ └── phase3.mdanalysis pull --out <out> 使用独立的原子快照结构。只有请求的 --include 分组且服务状态为 included 时才会出现对应文件;空的可选正文不会生成文件:
<out>/
└── <analysis-id>/
├── manifest.json
├── overview.json
├── source/
│ ├── metadata.json
│ └── reference.md
├── reports/
│ ├── summary.md
│ └── deep.md
└── products/
├── <portable-product-name>.md
└── <portable-product-name>.jsonmanifest.json 是 analysis pull 的读取入口和哈希索引:它记录 analysis ID、各 section / product group 的状态,以及每个实际文件的相对路径、SHA-256 哈希、字节数和所属 product ID。先读 manifest,再只打开任务需要的文件;产品名会经过跨平台安全化和碰撞消解,不能自行拼接文件名。
消息和项目等诊断导出会生成 README.md,说明导出对象、ID、raw/快照完整度、实际文件用途和推荐阅读顺序;它们的 JSON 文件仍是机器读取的事实源。analysis pull 不生成 README.md 或 analysis.json,入口始终是上面的 manifest.json。
这些文件可能包含创作正文、工具参数和用户输入。请把它们视作项目敏感资料:不要提交到 Git,不要未经确认上传到第三方服务。
与 MCP、Skill 的边界
- CLI:批量导出、本地落盘、
doctor、未来的差异与归档。 - MCP:向模型返回受大小限制的只读查询结果,避免把完整项目正文塞进上下文。
- Skill:给 Codex / Claude Code 提供排查决策流程,而非重复 HTTP API 定义。
MCP 是 CLI 包内的薄 stdio 适配器,通过 novel mcp 启动。它与 CLI 共享版本和诊断实现,因此 novel upgrade 会同时更新二者。
当前 CLI 已具备 --schema、单请求项目证据导出、默认安全的 message 诊断,以及 stdio MCP。MCP 提供 novel.project.inspect、novel.message.diagnose、novel.analysis.inspect、novel.diagnostic.run 四个只读工具;每个字符串字段限制为 24,000 字符,出现 truncated: true 时改用 CLI 导出完整本地证据。
随包附带的 Agent diagnosis Skill 规定了 CLI/MCP 选择、证据引用和历史消息没有 QA run 时的降级流程。
排错
| 现象 | 处理 |
| --- | --- |
| API_REQUIRED | 先运行 novel login;开发环境也可使用 --api、JUJING_API 或 novel init。 |
| AUTH_REQUIRED | 运行 novel login;CI 可使用 JUJING_TOKEN 或当前命令的 --token。 |
| doctor 显示 healthy: false | 先补令牌;随后确认 API 地址与诊断路由可访问。 |
| 项目没有 QA run | 这是历史数据或 collector 未启用时的正常结果;用 message diagnose 拉取单条消息,必要时再查项目原始会话。 |
| 导出文件过大 | 先用 project inspect 或 analysis inspect 缩小范围,再拉取单个产物或消息。 |
设计原则
- 只读优先:诊断不会改变用户创作和项目状态。
- 证据优先:任何结论都应能回到导出的运行、消息、工具调用或产物。
- Agent 稳定:JSON schema、错误码、文件路径和命令语义优先保证兼容。
- 安全默认:令牌不入 profile;敏感原文导出必须由调用者明确承担数据边界。
