Novelist 0.2.4 — 图床上传与一键发布
新增两套核心功能:把 Markdown 里的本地图片自动上传到你常用的图床(七牛 / OSS / S3·R2 / imgur / sm.ms / 自定义),以及一键发布到 Ghost / WordPress / Medium。同时附带一批日常工作流的细节打磨。
0.2.4 是个主版本:终于把”写完一篇文章 → 把它发出去”的最后一步搬进了编辑器。Markdown 里的本地图片可以直接传到你自己的图床;写好的稿子可以一键发到 Ghost / WordPress / Medium,全程不用再在四五个标签页之间倒腾。
图床上传
内置六个供应商,再加一个最小化的”自定义 HTTP”接口:
- 七牛 Kodo — HMAC-SHA1 上传凭证,multipart POST
- 阿里云 OSS — HMAC-SHA1 头部签名,virtual-hosted PUT
- Amazon S3 — 手写 SigV4 path-style PUT(同时支持 Cloudflare R2、MinIO,通过 endpoint override)
- imgur — Client-ID Bearer
- sm.ms — 可选 API token,处理
image_repeated去重 - 自定义 — multipart POST,可选 Bearer,从响应里读
url或data.url
入口:
- Settings → 图床面板:增删改、设置默认图床、每个 host 都有 Test 按钮(上传一张 1×1 PNG 验证凭证,不会留下噪音文件)
- 编辑器里右键任意本地图片 → 上传到图床,原地把 Markdown URL 替换掉
- 命令面板 Upload all local images:扫一遍当前文档,逐张上传,一次性 CodeMirror transaction 完成所有 URL 替换;部分失败会用 toast 报告
- 可选的”粘贴/拖入即上传”:默认关,开启后每次粘贴或拖入图片立即传到当前默认图床
桶类图床的对象 key 自动加日期前缀:{yyyy}/{mm}/{dd}/{8字符 blake3}-{清洗后文件名}.{ext},远端目录自然按日期归档,也不会撞名。
凭证安全:明文凭证只存在全局设置里,项目级别只能覆盖”当前激活的图床指针”,不会把 secret 写进可能被 git 跟踪的项目文件。
一键发布
四个发布平台,每个都是一个独立 adapter:
- Ghost — Admin API key 签成 5 分钟 HS256 JWT,用
?source=html提交,Ghost 服务端把 HTML 转成 Lexical - WordPress(自托管) — Application Passwords(HTTP Basic),完整支持标签名 → ID 解析 + 自动创建标签,原始 body 上传媒体
- WordPress.com — OAuth2 Personal Access Token(Bearer),同样的 REST 形态加
/sites/<id>前缀 - Medium — 旧版 Integration Token Bearer;原生 Markdown body,最多 3 个 tag。注意:Medium 在 2024 年底下架了 Integration Token UI;老 token 仍能用,但新用户基本拿不到
入口:
- 编辑器右上角 分享 按钮 → Upload Local Images to… + 每个已配置渠道一个 Publish to
入口(mweb 风格,单一发现点) - 发布对话框:标题(自动从 H1 预填)、tags(chip 输入)、摘要、slug(自动 kebab-case)、各平台自己的 status 下拉、可拖拽封面图。失败有内联报错 + 重试,成功显示 banner + 在浏览器中打开
发布前自动上传图片:正文里的本地图片会先上传到目标平台自己的媒体接口、改写 body 再提交。也就是说光发布到 Ghost 不需要外部图床;当然,如果你更想统一走自己的图床,可以先手动跑一次 Upload Local Images to…。
不追踪发布历史:每次发布都创建一篇新文章。重新发布修改稿会在平台侧产生重复,需要你自己删;frontmatter 里写回文章 ID 这个能力暂时不在 0.2.4 范围内。
转换链路:Ghost / WordPress / WordPress.com 走 Pandoc Markdown → HTML;Medium 直接吃 Markdown。
UX 打磨
- 双语命令面板 — Cmd+Shift+P 现在大字号显示当前 locale 的标签,下方小字显示另一语言的标签;搜索匹配两边都命中。中文用户搜 outline 或 大纲 都能找到 Toggle Outline
- 侧栏双击重命名 — 双击文件行直接进入 inline rename(文件夹双击仍是展开/折叠)。重命名输入框现在原地渲染在被改的节点下,而不是固定在侧栏顶部
- 右侧面板快捷键 — 改成 Cmd+Shift+1/2/3/4(大纲 / 草稿 / 快照 / 字数)。macOS 用户可能需要先在系统设置里关掉 Cmd+Shift+3/4 截屏快捷键。模板切换仍是 Cmd+Alt+5(Cmd+Shift+5 被 macOS 截屏工具栏占用)
- 侧栏拖到分屏 — 拖动侧栏文件时,编辑区会显示两个 drop overlay:当前 pane + 右侧”split right”区域;放下就在那个 pane 打开。Tab bar 也接受同样的拖拽
- 长文件名换行 — Settings → Editor 多了一个开关,让长文件名按多行显示,而不是省略号截断
- 侧栏边缘的折叠按钮 — resize handle 上多一个 ◁ / ▷,可以鼠标点开/收起侧栏,不用记快捷键
- 编辑器最大宽度变成滑块 + 数字输入(480–9999px),不再是固定下拉
- 新文件名宏 —
{yyyy}{mm}{dd}{HH}{MM}{ss}在新文件模板里展开,设置项下方有实时预览 - 可搜索的设置面板 — 顶部过滤框按 label / hint / 关键词缩窄面板和行(中文别名也搜得到)
- 发布对话框打磨 — 粘贴板按钮、Ghost tag 自动补全、重做的 pill grid tag picker、原生 clipboard 读取、能真正打到平台的 Test 按钮、凭证行的编辑按钮 + secret 显示、全量本地化
{title}-only 文件名模板 — 新文件模板可以只写{title}不带{N}(首次渲染Untitled.md,撞名时变Untitled 2.mdUntitled 3.md;后续 H1 自动重命名直接替换 stem)。错拼成{cN}或{Title}会被拒,避免 typo 默默变成字面量- 侧栏按创建时间排序 — 侧栏视图菜单新增 创建时间(最新) / 创建时间(最早)。文件系统不暴露 birth time 时回退到 mtime
- 命令面板快捷键 chip 用 UI 字体 — Apple 修饰符(⇧⌘⌥⌃)和后面的字母字重一致
- 设置勾选项与首行文字对齐 — Settings → Editor 里那个”长文件名换行”复选框现在不再悬在 baseline 上方
- 侧栏文件夹右键多了 Expand All / Collapse All — 整个子树递归展开(懒加载 BFS);折叠保留缓存,再展开瞬间到位。空白处右键也有同样两项,作用于项目根
Changed
- 文件名跟随 H1 标题,每次保存都同步(之前只在首次保存)。手动重命名后会断开同步。规格见
docs/superpowers/specs/2026-05-12-h1-filename-ongoing-sync-design.md - 新文件模板里有
{title}= 自动开启 H1 同步。原来”Sync filename with H1 on save”那个独立勾选项删掉了 —— 模板里有没有{title}就是开关。出厂默认第{N}章-{title}是开的;想关掉就把{title}删了 - 侧栏感知章节模式始终开启。“Detect chapter pattern from folder” 勾选项删掉了 ——
inferNextName永远会读当前文件夹,模板里有{N}就自动续号;没有{N}的模板不受影响
Fixed
- 文件名宏提示气泡(默认文件名模板旁边的
?)改成向右弹出,不再被面板左边切掉 - 侧栏数字排序:第九 < 第十 < 第十一;后面带后缀的(如
第十章终稿.md)也不再错位 - 项目内搜索:Unicode 大小写不敏感、用 UTF-16 偏移,CJK 和带变音符的拉丁字符不再高亮错位置;空查询直接短路不再扫整个项目
- 文件 watcher 在 Windows / macOS 重命名/删除时刷新正确的父目录,单独发
directory-changed事件,每 15 秒兜底轮询,外部工具或别的窗口改完之后侧栏不再有 ghost 行;.canvas/.kanban走和 Markdown 一样的外部打开路径 - 没有
.novelist/project.toml的普通文件夹保持全局作用域,不再尝试往里写视图设置 - Cmd+S 保存一个干净的 tab 时,如果没保存的编辑里出现了新 H1,依然会跑 H1 → 文件名重命名检查
- 外链通过
tauri-plugin-shell打开,真正用系统浏览器,不再被 WebKit 内部捕获 - Pandoc 自动发现 + 用户覆盖 — 不再依赖以前自带的 Pandoc 二进制,回退到 PATH 探测,可在 Settings → Editor 手动指定路径
Security
- 模板 zip 导入 改用
zipcrate(不再 shell out 到unzip),拒绝符号链接 / NUL 字节 / 路径穿越,archive 限制 2048 entries / 50 MiB 解压后体积;template id 进文件系统前先校验为[a-z0-9-]{1,96} - WebDAV 同步 在下载前校验远端文件路径,绝对路径、
..段、点开头的 path 段都拒收,恶意服务端无法写到项目根之外
Platform
- macOS bundle 通过新
core/Info.plist声明CFBundleLocalizations:en和zh-Hans,中文用户能拿到本地化的应用菜单和系统对话框
Removed
- Run Release Benchmark 命令 — 内部诊断用,不面向用户。常规 perf benchmark 仍在
- Settings → Editor → Sync filename with H1 on save 勾选项 — 改用模板里
{title}。已有 project config 里的auto_rename_from_h1仍能解析但不再读取 - Settings → Editor → Auto-detect chapter pattern from folder 勾选项 — 现在永远开
给开发者的注
tauri-spectacodegen 上游目前坏了(specta-serde 拒绝ProjectConfig现有字段上的skip_serializing_if)。0.2.4 的新 IPC 命令和类型手工补到app/lib/ipc/commands.ts。文件仍然是@ts-nocheck,所以消费方层面是类型安全的。下个版本会修- 新图床和发布 UI 的 E2E 覆盖暂未补全。Rust + 前端单测覆盖很完整(一千五百多个 case),UI 走人工冒烟
其他
- 完整细节见 上游 CHANGELOG