更新日志
每个版本新增、改进和修复了什么。
53 个版本 · 2026.06 起
1.3.4
最新修复 physics 宏包的两处公式渲染错误:裸 \dd 不再让整块公式变成红色原文,\qty(...) / \qty[...] 的定界符形式按自动缩放括号渲染。
修复
- 裸
\dd让整块公式报错:\dd原先声明了#1,\frac{\dd}{\dd{t}}里分子位置的裸\dd会把后面的}当作参数吞掉,整块公式(如积分形式的麦克斯韦方程组、欧拉-拉格朗日方程)退化成红色原文。现在\dd展开为不带参数的\mathrm{d},\dd{x}、\dd x仍渲染为直立的 d 紧跟后面的内容。服务端 KaTeX 与编辑器预览同步修改。 \qty(...)/\qty[...]渲染成多余括号:宏表里的\qty只能吃花括号参数,\qty(\dfrac{a}{b})会把(当成参数,渲染出「(()a/b)」且不报错。现在渲染前按 TeX 记号预转译为\left(...\right)/\left[...\right]:控制序列整体跳过(\\qty、\(不参与配对),只在同一花括号层级内配对同种括号,嵌套的\qty(各自替换,括号不闭合时保留原文;\qty{...}仍走宏表。服务端与编辑器预览共用同一规则。- 已保存文章的渲染结果存在数据库里,要让上述修复对旧文章生效,请在后台「文章 → 更多操作 → 重建全部渲染」重建一次。
1.3.3
公开页 HTML 可由 EdgeOne 节点缓存(后台「边缘缓存时长」),内容变更与发版后自动清除;查询串变体、搜索与 404 页不再进 CDN 缓存;Feed 缓存渲染并压缩好的成品;rustdoc 哈希文件长期缓存;SSR 缓存单页上限提到 2 MiB 并可在后台配置。
新增
- 公开页 HTML 可由 CDN 缓存,内容变更后自动清除:经 EdgeOne 访问时 HTML 每次回源,TTFB 约 80–130 ms,而节点命中只要约 17 ms。后台「页面缓存」新增「边缘缓存时长」(环境变量
SSR_CACHE_EDGE_TTL_SECS首次播种,默认 0 不启用,需重启):大于 0 时首页、归档、友链、关于、更新日志与文章、分页、标签页的匿名响应改为public, max-age=0, s-maxage=<秒>,浏览器仍每次校验,CDN 按该时长缓存。配置EDGEONE_ZONE_ID、TENCENTCLOUD_SECRET_ID、TENCENTCLOUD_SECRET_KEY后,源站 HTML 缓存每次失效(文章、标签、设置写入,跨实例通知,发版启动)都会清除 EdgeOne 上的这些目录与页面:防抖 2 秒合并突发写入,30 秒后再清一次(EdgeOne 完成一次清除实测要 9–20 秒),挡住写入前已开始渲染、清除期间才返回的旧页面;失败重试 3 次。
改进
- 其它 HTML 不再进 CDN 缓存:带查询串的页面(如带
?utm_source=的分享链接)、搜索结果和 404 页原先返回public, max-age=300, stale-while-revalidate=3600,EdgeOne 会缓存 5 分钟,文章修改或删除后这些地址仍显示旧内容,源站也无从清除。现在服务端渲染的 HTML 只有上述白名单匿名页可被共享缓存,其余一律public, no-cache;/doc/下的静态 rustdoc 页面不变。 - rustdoc 哈希文件长期缓存:
/doc/static.files/<名字>-<8 位哈希>.*(样式、脚本、字体)与/doc/search.index/<列>/<哈希>.js文件名带内容哈希,却按固定路径处理:样式和脚本是no-cache,每次都经 CDN 回源校验(70–650 ms),字体只缓存 5 分钟,而/doc/占了 CDN 出流量的大头。现在这些文件返回public, max-age=31536000, immutable;search.index/root.js、doc-shell.js、theme.css等固定文件名不变。同时 immutable 只发给成功响应:哈希文件名的 404(含/pkg/分包)改为no-cache,不再让浏览器和 CDN 把「不存在」记一年。 - Feed 缓存成品并去掉代码高亮标记:
/feed.xml、/feed.json原先每个请求都把 20 篇全文重新渲染一遍再现压,线上未压缩 6.2 MB,源站每次 225–270 ms。现在缓存的是两种格式的成品连同各启用算法的压缩结果,命中按Accept-Encoding直接返回(数十微秒);带ETag并支持If-None-Match,lastBuildDate改取最近一篇的更新时间,内容没变时阅读器拿到 304。<pre>里的高亮<span>在阅读器中没有样式,一并去掉,RSS 未压缩体积少约三成,brotli 后 422 → 367 KB。 - SSR 缓存单页上限提到 2 MiB,并可配置:图表多的长文渲染后超过 1 MiB(线上最长一篇 1.14 MB),进不了缓存,每个请求都完整 SSR 再现压(约 37 ms)。上限改为 2 MiB,总量仍受 32 MiB 约束。上限不再写死:后台设置新增「页面缓存」分区(64 KB–32 MiB),环境变量
SSR_CACHE_MAX_PAGE_BYTES只在首次部署时播种,之后以面板值为准;修改后需重启生效。
1.3.2
服务端首屏性能:SSR 缓存页面写入后预压缩一次,动态压缩按正文长度选 brotli 窗口,文章页水合数据不再重复正文;新增 Markdown 渲染与 HTTP 基准;修复评论灯箱收录头像、表格窄列中文逐字折行;CI 与发布流程调整。
新增
- 性能基准:
make bench-markdown用 criterion 测render_markdown_enhanced(语料为 4 篇线上文章,位于benches/fixtures/,BENCH_ARGS='--save-baseline base'/'--baseline base'做前后对比);make bench-http(scripts/bench-http.ts)用一次性 PostgreSQL 拉起 release 产物,oha 以固定到达率压首页、归档与文章页,SSR 缓存命中与未命中分开测,支持BENCH_TARGETS=A,B同机 ABBA 交替对比(每轮重启服务端)并给出精确置换检验的显著性判定。渲染后超过 1 MiB 的文章页不进 SSR 缓存,只测未命中场景。
改进
- SSR 缓存命中不再每次现压:压缩层在 HTML 缓存外侧,缓存命中的页面原先每个请求都要做一遍 brotli 7,服务端 CPU 有 98% 花在这里。现在页面写入缓存后,在阻塞线程池按
COMPRESSION_ALGORITHMS启用的算法高档压缩一次(brotli 11、gzip 9),命中时按Accept-Encoding直接返回压缩结果并带Vary: Accept-Encoding;压缩完成前的命中仍走现压。协商规则(q 值、*、identity;q=0回 406)与压缩层一致,抽到新的compression模块。并发未命中写入相同内容时只压缩一次;页面失效或被替换后,在途的压缩结果丢弃。同机 A/B(make bench-http,固定到达率):命中 p50 从 1.1–4.3 ms 降到 0.06 ms,闭环容量从 680–3,400 rps 升到约 16–17 万 rps(压测客户端已成为瓶颈),brotli 响应小 7–13%。 - 动态压缩按正文长度选 brotli 窗口:tower-http 的压缩层只能设质量,brotli 固定用 4 MiB 窗口,超过约 64 KB 的页面每个请求都要分配并清零 4 MiB 环形缓冲区。现在由
compression::compress中间件接管动态压缩:协商与跳过规则(图片除 SVG、gRPC、SSE、32 字节以下、已带Content-Encoding/Content-Range,拒绝 identity 时回 406)与原压缩层一致;长度未知的正文先缓冲,上游一口气给完且不超过 1 MiB 时取刚好容纳全文的窗口(下限 lgwin 18:q7 在 16 时换用另一种哈希,反而慢 4 倍)。上游中途暂停(流式 SSR)时与原来一样先 flush 已收到的部分,之后按 4 MiB 窗口流式压缩。tower-http去掉compression-full,不再依赖async-compression。同机 A/B(缓存未命中):110–220 KB 的文章页 p50 −12%~−16%、p99 −14%~−20%,首页、归档(流式)与超过 1 MiB 的长文无显著变化,响应大小不变。q7 每次还要清零约 8 MiB 的匹配哈希表,这部分与窗口无关,只能靠降低质量减少。 - 文章页水合数据不再重复一遍正文:路由数据原先把整个
PublicPostResponse编成 JSON 写进__RESOLVED_RESOURCES,正文与目录在页面里出现两次(再经{:?}转义,1.08 MB 的正文变成 1.31 MB 水合数据),服务端还要把刚编码的 JSON 解析回来才能渲染。现在 SSR 视图直接克隆取数结果(RawJson带类型擦除的原值),JSON 只用于水合;PageJson::with_hydration让文章页的水合数据只带正文骨架:普通 HTML 段换成<!---->占位,可运行代码块原样保留,目录换成占位(inner_html水合时不改写服务端 DOM),客户端据此建出与 SSR 相同的组件树。SPA 导航与悬停预取照旧拿完整数据。同机 A/B(缓存未命中):文章页 p50 −33%~−48%,HTML 61 KB~1.16 MB 的页面体积约减半,brotli 传输小 13%~31%;math-heavy 从 1.26 MB 降到 0.72 MB,回到 SSR 缓存的 1 MiB 上限之内。
修复
- 评论图片灯箱收录头像:评论区的灯箱把评论者头像也当作可放大的图片收进图集。现在只收录评论正文里的图片。
- 文章表格窄列里的中文被逐字折行:表格宽于正文列而横向滚动时,列缩到最小内容宽度,
th为nowrap且字号小于td,导致首列「首页」之类短词被挤成一字一行。.md-content td现在设min-width: 6em,至少容纳 4 个字。 - 发布 CI 被 rustdoc 断链阻断:
PostMeta改为文章模块内部组件后,PostHeaderData的文档仍尝试链接该符号,触发发布构建的零告警门禁。现在只链接公开的PostHeader,内部元信息组件改用文字说明;门禁保持不变。
1.3.1
站点空白处加入吉祥物像素贴图;灯箱打开/关闭动画改为 medium-zoom 风格,滚动关闭逐帧跟手;组件图鉴首屏不再抖动;Rust 依赖升级(leptos 0.8.23 等)。
新增
- 吉祥物像素贴图:在站点空白处放上橙发女孩的 11 种表情(
public/images/mascot/*.webp,256×256),通过components::mascot::Mascot枚举调用,纯装饰、对读屏隐藏。首页开场(挥手)、404 与无搜索结果(慌张,搜索页与命令面板共用)、评论区无评论(爱心)、只有一侧相邻文章时空着的那格(坐着)、登录页(好奇,登录出错时换成生气);EmptyState新增mascot参数,加载失败(哭)、翻到最后(犯困)、无笔记/无标签文章(打盹)、后台无待审评论(和平)、回收站为空(满足)、素材库为空(坐着)改用贴图替换线条图标。 - 改密时可选吊销全部 MCP 令牌:个人资料页的「修改密码」新增「同时吊销我的全部 MCP 令牌」,默认不勾选。MCP 令牌是有独立过期与吊销的长期凭据,改密默认不影响 AI 客户端;怀疑密码泄露(泄露期间可能被签出令牌)时勾选,与改密在同一事务内把本人全部未吊销令牌标为已吊销,令牌列表如实显示,成功提示带吊销数量。
改进
- 组件图鉴「文章」分组精简:面包屑
Breadcrumbs、文章元信息PostMeta、相邻文章导航PostNavLinks只是页眉、页脚的组成部分,改为components::post模块内可见,并从图鉴中移除(分组 8 → 5 项,「面包屑」不再与通用Breadcrumb重名)。「文章页头」新增无标签样例(面包屑只剩「文章」),说明并入面包屑与元信息规则;「文章页脚」接收单侧、无相邻文章样例与键盘说明,不再与相邻文章导航显示两份相同的卡片。/about/components/{breadcrumbs,post-meta,post-nav-links}返回 404。 - 依赖升级:
leptos0.8.22 → 0.8.23,resvg0.48 → 0.49,sysinfo0.39 → 0.40,fancy-regex0.19 → 0.20,另有rmcp3.8、uuid1.29、zenwebp0.4.6、wasm-bindgen0.2.130 等兼容更新。sysinfo0.40 的系统指标改返回Result:不支持的系统上采样任务记录警告后退出,磁盘空间预检按探测失败降级。skrifa仍保持 0.44,与usvg0.49 内部使用的版本一致。 - 灯箱打开/关闭动画改为 medium-zoom 风格:图片从页面原位置不透明地飞到视口中央,关闭时原路飞回,原图在灯箱期间隐藏;时长 300 ms,曲线
cubic-bezier(0.2, 0, 0.2, 1),背景与界面层与图片同曲线同步淡入淡出。背景改为跟随站点明暗的毛玻璃(浅色blur(2.5rem) brightness(1.1),深色brightness(0.85)),顶栏、工具条、缩略条与提示文字的配色随主题切换。缩略图布局盒与原图宽高比相差超过 2%(object-fit裁切过的缩略图)时,仍走透明度淡入淡出。
修复
- 同秒并发备份互相截断,两个任务都报成功:备份文件名只精确到秒,pg_dump 路径先用
std::fs::write截断写签名头、再以追加方式接 pg_dump 输出,手动备份每次请求直接tokio::spawn一个任务;双击、两个标签页或脚本重试会让两个任务写同一个文件,产出签名合法但内容交错的备份。现在同一进程同一时刻只允许一个备份:已有备份在跑时手动备份提示「已有备份正在进行,请等待完成后再试」,自动备份跳过本次并记为失败。文件名改为<前缀>_YYYYmmdd_HHMMSS_mmm_<6 位随机>.sql,各段定宽,自动轮转仍按字典序判断新旧;SQL 与 uploads 归档都以create_new独占新建,同名文件已存在时报错,不再截断。 - MCP 只读工具回传数据库错误原文:
search_posts、get_post、list_tags失败时把 tokio-postgres 错误(含 SQL 片段与列名)原样放进 MCP 错误消息,持有最低级 read 令牌即可在数据库故障时看到表结构。现在与其他 MCP 工具一样只回「<工具名> failed」,详情只写服务端日志。 /mcp预鉴权限流全站共用一个桶:/mcp鉴权中间件与/api/mcp/upload在解析令牌前按 IP 限流,但取 IP 时没带 TCP 对端地址,未配置TRUSTED_PROXY_COUNT时所有请求都记在unknown下;任何人用伪造 Bearer 打满 30 次/秒(突发 100)后,所有合法 AI 客户端一起收到 429。现在两处都按启动时注入的ConnectInfo对端地址计数,与其他上传路由一致。- 组件图鉴首屏抖动:页面边下载边绘制时,排在全部卡片之后的右侧详情栏晚到约 0.5 s,卡片网格先占满整行,随后收窄成两列窄卡;水合后瀑布流脚本再把卡片从按行对齐改成按自然高度排列,后面的卡片上移或换列。现在目录用两列 grid 先给详情栏留出 20rem;网格前内联一段脚本,在解析过程中每张卡片一闭合就写好它的
grid-row-end,浏览器中途绘制出来的就是最终位置,showcase-masonry.ts接管后算出的跨度相同,不再移动。CPU 降速 6 倍实测,首屏卡片移动从 57 次降为 0。 - 在途旧密码登录可跨过改密:登录先校验密码、后锁用户行,签发时直接取最新会话世代;改密若在两者之间提交,已验证的旧密码仍能拿到新世代会话。现在加锁时一并复核
password_hash与admin角色未变,不符按凭据错误处理。改密的UPDATE同样以已验证的旧哈希为条件,并发改密后旧密码不能再覆盖新凭据;当前会话行已被并发改密删除时整体回滚,不再借缓存刷新复活已吊销的 token。 - 封禁唯一管理员后注册重新开放:注册始终插入
role='admin',只靠部分唯一索引idx_one_admin拦截后续注册;唯一的管理员被改成blocked(例如在 SQL 控制台里)后索引不再约束,匿名访客即可注册成为新管理员。现在注册只在users表为空时成功,站点一旦有用户即视为初始化完成,与管理员角色无关;并发首次注册仍由idx_one_admin保证只有一个成功。 - 素材清理会删掉刚建立的文章引用:每日定时清理不加锁选出孤儿、先删文件、最后删 DB 行,文章保存若在此期间写入
asset_refs,删除会经ON DELETE CASCADE把新引用一起删掉,磁盘文件也已没了。管理端「一键清理」与批量删除虽然FOR UPDATE锁行,但引用判定写在加锁语句里:保存事务先插入引用、清理在其外键锁上等待,保存提交后 Postgres 不重新求值WHERE,仍会删掉引用。现在三者共用同一流程:事务内先锁候选行,再由DELETE … AND NOT <引用判定>用新快照复核,提交后才删文件与派生缓存;定时任务只负责读开关与保留天数。 - 素材目录读取失败时重建索引会清空素材表:「重建素材索引」把
uploads/及其子目录的读取失败当成空目录,随后删除所有未扫描到的素材行,asset_refs级联清空;目录未挂载或权限异常时整表被删。现在任一目录或目录项读取失败即中止重建并报「素材目录读取失败」,数据库不做任何改动。 - 评论与头像引用的素材可被删除:评论、用户头像、友链头像对素材的引用不落表,删除与清理时按 URL 文本临时匹配,
FOR UPDATE行锁挡不住并发写入,写入时也不检查素材是否存在;回收站评论引用的图片还会被当作孤儿清理。现在三类引用各有带外键的引用表(迁移 032 从现有内容回填):写入时先以FOR KEY SHARE锁住引用的素材并确认存在,缺失则拒绝,提示「评论中的图片不存在或已被删除,请重新上传」或「头像素材不存在或已被删除,请重新上传」;资料或友链里未改动的旧失效头像不阻止保存,后台排序不受影响。回收站评论的引用继续保护素材,只随评论被彻底删除而消失。删除、清理、引用明细与重建索引统一查引用表。 - 下调会话上限后旧会话不收敛:登录超出「每用户最大会话数」时只淘汰最早的一条再签发新会话,上限从 10 调到 3 后每次登录仍保留 10 个有效会话。现在登录时一次删掉除最新
上限 - 1个之外的全部有效会话,下一次登录即收敛到新上限。 - 重复标题目录跳错:标题锚点只由文本转 slug,同名标题或只差标点的标题(
FAQ?与FAQ!)得到相同id,目录里后面的条目都跳到第一个。现在同一篇文档内重复的锚点依次追加-1、-2(与 GitHub 一致),首次出现的锚点不变;已发布文章重新保存后生效。 - 灯箱栏位淡出后 Tab 焦点泄漏:放大后顶栏、底栏与箭头空闲淡出(
opacity: 0),焦点约束按透明度筛掉全部控件后直接放行默认 Tab,Shift+Tab 会聚焦到灯箱背后的页面按钮。现在 Tab 与指针活动一样唤醒栏位,焦点约束不再按透明度过滤并始终接管 Tab,没有可聚焦控件时焦点留在灯箱本身。 - SQL 格式数据导出把非标量列写成 NULL:逐行拼
INSERT时只解码整数、float8与布尔,其余一律按 RustString读取;timestamptz、uuid、text[]、jsonb、bytea、float4等类型读取失败后静默写成NULL,浮点NaN还会输出成非法的裸字面量,导出的文件回灌时在created_at NOT NULL等约束处失败。现在查询包进子查询、在数据库端逐列::text,任意类型都按 PostgreSQL 文本表示导出(按位置取列,重名列不冲突,末尾分号与注释先去掉);有限数值不加引号,NaN/Infinity加引号。EXPLAIN不能作子查询,文本格式照旧导出,FORMAT JSON/XML改为直接报「该语句的结果列无法导出为 SQL」。 - 上传中删掉占位图后无法保存文章:编辑器的图片上传结束后不复查占位图是否还在。上传途中点移除、关掉提示或退格删除占位图,计数已经减过一次:上传成功会再减一次,计数变成负数;上传失败则把已移除的图片记成失败,保存时检查到「有上传失败的图片」一直拒绝保存,且该图片已不在列表里,无法再移除。现在上传结果到达时占位图已移除就直接丢弃。另外,重试时没有把图片状态改回「上传中」,重试期间移除会扣错计数;连续点重试会重复上传。现在重试会改回上传中,且只对失败的图片生效。
- 重传图片补不回丢失的素材文件:上传按内容哈希去重,命中已登记素材就直接返回旧 URL,不检查磁盘上文件是否还在。素材记录还在但文件丢失(如跨机同步遗漏)时,重传同一张图只会拿到一个永久 404 的地址,本次上传的字节被丢弃,只能先删记录再重传。现在去重命中时确认文件存在;不存在就照常校验、转码并写回原路径,文章里已有的图片地址随之恢复;转码后扩展名与原路径不同时,记录改指向新文件。落盘改为先写临时文件再改名,并发补写同一路径时不会读到写了一半的文件。
- MCP 改状态会改写创建时间、拼错状态会下线文章:
update_post只要带status,就把推导出的published_at同时写进created_at,已发布文章再传一次published也会把创建时间改成发布时间;状态值不是draft/published(如Published)时静默当成草稿,已发布文章被悄悄下线。现在只有显式传published_at时才同步created_at(与create_post一致);创建与更新文章时状态拼写不对直接报「status 无效,只能是 draft 或 published」。 - 未配置可信代理时上传限流全站共享:服务启动未注入连接信息,图片上传、评论图片上传与备份导入在
TRUSTED_PROXY_COUNT=0(默认)时取不到 TCP 对端地址,所有人共用unknown限流桶,匿名评论上传的每日 30 张变成全站共享额度。现在启动时注入ConnectInfo,这些接口按对端地址限流。 - 注册关闭后仍为每次请求计算密码哈希:注册先无条件算 Argon2(每次约 19 MiB 内存、占一个阻塞线程),再由
INSERT … WHERE NOT EXISTS判断站点是否已有用户;站点初始化后每个匿名注册请求都白算一次哈希,限流额度内即可占满内存与阻塞线程池。现在先查users是否为空,非空直接返回注册已关闭,不再计算哈希;并发首次注册仍由插入条件兜底。 - 搜索
C++、R&D的链接丢字:站内地址拼查询参数时不编码+、&、=、%,搜索C++的链接被解析成C加两个空格,R&D被截成R。现在这四个字符都按百分号编码。 - SQL 控制台执行不了
SHOW和EXPLAIN:只读语句一律包成SELECT * FROM (…) AS q LIMIT 501取结果,勾选「执行计划」时再加EXPLAIN前缀,SHOW search_path与EXPLAIN SELECT …包裹后都是语法错误。现在只有查询语句才加EXPLAIN前缀和子查询包裹,SHOW/EXPLAIN原样执行,结果仍按 500 行截断。 - 多键设置保存中途失败会部分生效:安全、限流、代码运行器、图片缓存与尺寸限制、WebP、素材清理、备份、回收站设置逐键写入,第二个键起写入失败时页面报错,已写入的键却会在缓存过期后生效(例如站点地址已改成 http、
cookie_secure仍为真,http 下无法登录)。现在一组配置用一条INSERT … SELECT FROM UNNEST … ON CONFLICT写入,要么全部生效、要么全部不变。 - 后台保存途中切换页面可致前端崩溃:友链编辑、个人资料、评论回复在请求返回后调用父组件回调,期间若已切换编辑对象(如友链保存中点了另一条)或离开页面,回调所在作用域已释放,
Callback::runpanic,release 前端 panic 即 trap,页面失去响应。现在改用try_run,作用域已释放时丢弃迟到结果。 - 灯箱键盘与连按:放大后栏位空闲淡出不看焦点,Tab 停在按钮上 2.5 s 后按钮变透明;现在焦点在栏内控件上时不淡出。换图淡出的 150 ms 内连按方向键或箭头按钮,第二次仍以旧序号为基准,两次只前进一张;现在以已排队的目标为基准。
- 代码块退格切断 emoji:代码块的退格按 UTF-16 码元删一位,emoji 留下孤立代理,ZWJ 组合表情被拆开;现在按字形簇删除(无
Intl.Segmenter时按码点)。代码块运行中被改成不可运行或删除时,结束后不再因按钮已置空抛出未处理的异常。 - 灯箱滚动关闭逐帧跟手:页面滚动缩回原图时,原先每次滚动事件都给图片设 100 ms 过渡,过渡每次重设目标都从头起步,图片总是落后于页面上的原图。现在逐次直写
transform与不透明度,不再加 CSS 过渡;停止滚动 150 ms 后收尾:缩回进度达到 35% 继续飞回原图并关闭(ease-out cubic,最短 120 ms,接住滚动中的运动),不足则 180 ms 回弹到完全打开,并以当前滚动位置重新起算。 - 组件图鉴若干样式:评论卡片沿用生产样式,代码运行器卡片完整显示;素材上传弹窗卡片预览完整显示文件列表;输入栏聚焦时不再叠加图鉴的内层描边。
1.3.0
Mermaid 改为服务端渲染并补全各类图表的明暗配色;前台页面数据在 HTML 中不再重复三份;新增本地双架构镜像构建脚本,并修复代码运行器与折叠块的若干版式问题。
新增
- 本地双架构镜像构建脚本:新增
fish scripts/build-docker.fish,开启CN_MIRROR=true,使用本机 Docker 分别构建并加载yggdrasil:amd64、yggdrasil:arm64,不推送、不部署。复用 Makefile 的 Git 构建信息和版本标签,新增make docker-arm64;构建前检查平台支持,构建后核对镜像架构。
改进
- 镜像推送脚本支持开发与正式标签:
scripts/push-dev-image.fish重命名为scripts/push-docker.fish,支持[dev|release]参数;默认推送hub.rua.plus/yggdrasil:<版本>-dev,release推送<版本>,不更新latest。修复version与 Fish 只读变量同名导致镜像误用 Fish 版本号的问题;远端架构检查跟随PLATFORMS,仅选择 amd64 时不再安装 arm64 模拟支持。 - 动态压缩质量 6 → 7:
COMPRESSION_ALGORITHMS压缩层的 brotli 再小 1.9–2.9%(feed.xml232,472 → 227,470 B),耗时增加几毫秒;make precompress补上manifest.webmanifest的.br。 - Mermaid 改为服务端渲染:文章保存时用 merman(Mermaid 12.1 的 Rust 实现)把每个
```mermaid块渲染成浅色、深色两份内联 SVG,随主题由 CSS 切换,读者不再下载 1.33 MB 的mermaid.js,也不再在主线程上每张图花 160–370 ms 排版。标签字宽取 SF Pro Text、Selawik、Roboto、Liberation Sans、Noto Sans 五款字体实测宽度的最大值(libs/shared的mermaid-font-metrics生成字宽表),线上 31 张图在这几款字体下标签都不溢出;子图框重叠时自动加大节点间距重排,子图标题绘制在所有子图之上。渲染失败的图显示源码,文章照常保存。后台编辑器预览改为调用同一套服务端渲染;RSS/JSON Feed 只输出浅色图。删除libs/mermaid-renderer及前台主题切换时的异步重渲染。部署后需在后台文章列表执行一次「重建全部渲染」,旧文章才会从代码块变成图表。
修复
- 代码运行器骨架屏错位:运行时的占位条垂直居中、左缘 14 px,而终端首行在顶部、左缘 8 px,结果出现时文字相对占位条上移、左移。现在占位条自顶部起按终端行高(1.4rem)排布、左缘同为 0.5rem,与 xterm 首、二行的中心对齐;输出区表头改为固定高度,避免右侧等宽中文回退字体撑高行盒,结果出现时整个输出区下移。
- 代码运行器动效:运行时的骨架条被 xterm 盖住(骨架没有层叠层级,DOM 在后的终端画在它上面),「正在启动容器…」还单独占一行,准备中进入运行时整个运行器先长高 35.5 px 再收回,下方正文跟着下跳;「运行」变「再次运行」时按钮变宽,标题栏右侧的状态、Vim、复制按钮一起左移。现在骨架自成一层并承载阶段提示(排队提示同样收进去),从点击运行到结束高度不变,运行按钮按最长文案预留宽度。
- Mermaid 非流程图类图表配色:站点配色原先只给了通用主题变量,甘特图、ER、时间线、思维导图、看板、git 图、饼图、XY 图、雷达图、矩形树图、数据包图、架构图、C4 的专用颜色都由白色节点色推导,结果是一片灰,深色模式下还有浅底白字(ER 属性行、已完成任务)、黑色分支与扇区、看不见的字节编号与关系标签。现在这些图都显式使用站点的系列色(陶土、鼠尾草、石板蓝、赭黄、梅紫、青……)和对应的分区浅底。另修:方块图组合块变成 50% 黑框(半透明子图底色被
fade()改了透明度,主题色一律改为不透明);甘特图网格线跟随正文变成黑线;ER「零」基数圆圈在深色下是实心白点;桑基图连线在深色背景上用正片叠底几乎全黑,深色改为滤色;C4 横向关系标签压到两侧形状上。同样需要「重建全部渲染」后生效。 - Mermaid 时序图自调用标签:自调用消息的标签居中压在生命线上,开了
autonumber时序号圆点还压住标签下沿。现在自调用标签上移 8 px 让开序号;所有消息标签描一圈背景色,穿过的生命线在文字处断开。 - 页面数据在 HTML 里重复三份:前台布局把
<Outlet/>包在<Suspense>里,服务端渲染时 Suspense 会遍历子树三次,每次都重新调用懒加载路由的data(),同一份页面数据被取三次、写进内联水合脚本三次,而客户端只读第一份。现在服务端在同一请求内按(取数函数, 参数)复用路由数据资源。《Markdown 全特性测试文章》页面从 5,135,022 B 降到 2,498,104 B,首页 145,586 → 105,310 B,/changelog808,181 → 453,021 B。上游问题见 leptos-rs/leptos#4985。 - 折叠块内代码块缩进与留白:
<details>展开后,内容缩进原先用padding,代码块、表格、引用等自带外框的子元素被撑满整行,只把内容往里挤,末尾子元素的底部内边距还让代码块框多出一截。现在缩进改用margin,底部留白放在details上;展开后内容左右各留 1em,两侧对称,手机上折叠块内的代码块也不再贴边去圆角。 - 后台预览目录点击滚动:后台文章预览里点击目录条目现在会滚动到对应标题。
1.2.5
代码高亮统一为 Clay 配色,缩减公开页首屏 WASM 与阻塞渲染样式;服务端请求 panic 改为隔离并返回不可缓存的 500,常驻后台任务仍在 panic 后交由容器重启恢复。
改进
- 代码高亮改用 Clay 配色:文章代码块、Tiptap 与 CodeMirror 编辑器、运行器终端和 rustdoc 文档的亮色、暗色代码配色改为移植自 clay.nvim 的 Clay 设计规范:层级靠亮度而不是色相,变量最醒目,关键字与函数调用退后,标点和注释最淡;只有字符串带一点暖灰,函数定义用陶土色标出。Diff 的新增、删除改为亮、暗两档灰,终端 ANSI 色同样映射回灰阶。所有语法色在代码块底色上的对比度仍不低于 4.5:1。函数调用不再把整个参数列表染成函数色,JSON、TOML 的键名按成员着色;TypeScript、TSX、JSX 语法区分函数定义与调用,此前 TypeScript 把所有
name(都当作定义,TSX、JSX 则把function name当作调用。 - 服务端改回 panic=unwind:
panic = "abort"从[profile.release]移到 WASM 专用的[profile.wasm-release],前端产物不变。此前服务端任何一个请求里的 panic 都会让整个进程退出,在线请求一起中断,直到容器重启;现在只中断出错的那个连接,mhchem 化学公式转译里的catch_unwind在 release 下也真正生效,坏公式只退回原文。常驻后台任务(清理、备份、跨实例缓存同步、日志落库、限流器回收、系统采样)改由tasks::spawn_supervised派生:panic 时记录错误并终止进程,保持原先「崩溃后由容器重启」的恢复方式,避免任务静默停摆。 - 前端首屏体积再减一轮:路由数据资源改为类型擦除,所有路由共用一份资源代码,页脚也改走同一路径。客户端日期改用自带的格式化函数和严格 RFC 3339 解析,不再带入 chrono 的 strftime 和宽松解析器。release 前端开启
-Zfmt-debug=none -Zlocation-detail=none,因此浏览器端的{:?}输出为空,原先依赖它的评论列表 key 和图鉴错误文案已改掉。主包 Brotli 从 310,782 B 降到 287,544 B,各公开路由首屏 WASM 少 17–44 KB。后台与组件图鉴的样式拆成单独的admin.css,只在/admin…和/about/components…加载,公开页阻塞渲染的样式从 40,260 B 降到 24,896 B(Brotli)。后台登录守卫改为按路径段匹配/admin,同前缀的/admin.css不受守卫拦截。
修复
- 请求 panic 返回 500,不再断开连接:改为 unwind 后,请求处理中的 panic 只结束那一个请求,但客户端看到的是连接被直接断开,经 nginx/EdgeOne 后变成 502。现在整个路由最外层挂了
CatchPanicLayer:响应头发出前发生的 panic 一律返回500,正文固定为「服务器内部错误」,不含 panic 内容,并带Cache-Control: no-store防止 CDN 缓存;panic 消息写入错误日志。前端调用服务端函数遇到这个响应时显示「服务暂时不可用,请稍后再试」。响应体已开始输出后(流式 SSR、SSE)的 panic 仍只能中断连接。
1.2.4
修复后台笔记列表的垂直对齐与悬停底色、页头搜索入口的视觉对齐,以及点击页头导航时的文字暗闪。
修复
- 后台笔记列表垂直对齐:复选框、类型图标、主内容和右侧信息统一按整行垂直居中,修复复选框低于类型图标的错位;移动端标题与标签换行时保持居中,回收站的恢复操作区域同步对齐。
- 后台笔记列表悬停底色统一:移除编辑链接重复叠加的半透明悬停背景,复选框区域与笔记内容由整行统一高亮,勾选后再悬停也不再出现深浅分区。
- 页头搜索入口视觉对齐:明确文字与快捷键的行高,搜索文字下移 0.5px,快捷键键帽固定高度并调整内部留白,减轻中文笔画与
⌘K相对放大镜偏上的观感;图标与键帽外框仍保持垂直居中。 - 点击页头导航时文字不再暗闪:点击栏目后,被点的链接会先从悬停的高亮色退回普通灰色,约 2–3 帧后才恢复,同时指针变回箭头。原因是视图过渡从截图到动画就绪之间,浏览器按规范把命中测试全部交给
<html>,链接失去悬停态,而截图那一帧会一直冻结到动画开始。现在点击时给链接加标记,在过渡期间保持悬停色;指针变箭头属浏览器行为,无法消除。
1.2.3
修复下拉面板的水平对齐与筛选框右侧留白,以及页头胶囊滑动时遮住导航文字。
修复
- 下拉面板对齐:紧凑下拉(如系统监控的自动刷新间隔)展开的选项面板比触发器宽时,不再向右偏出,而是相对触发器水平居中。
- 带筛选框的下拉不再在输入框右侧留白:选项多于 8 个时,筛选框原先和选项一起在同一个滚动区里,出现滚动条(如接了鼠标的 macOS、Windows 和 Linux 的经典滚动条,占 11–15 px)后,筛选框只通到滚动条左边,右侧一条空白。现在筛选框移到滚动区外,始终通到面板右缘,滚动条只贴着选项列表;选项列表同时去掉了经典滚动条下多出的横向滚动条。
role="listbox"也只包含选项,筛选框不再混在里面。 - 页头胶囊滑动时不再遮住导航文字:栏目切换时,胶囊从旧栏目滑向新栏目,原来会盖住排在新栏目前面的导航文字:从「友链」切到「关于」时,「友链」消失约 3 帧;从「笔记」切到「友链」时,「笔记」和「归档」被依次盖掉。原因是每个导航项各自形成层叠上下文,胶囊只能垫在自己那一项的文字下面。现在由整个导航栏共用一个层叠上下文,胶囊滑过任何一项都垫在文字下面。
1.2.2
后台笔记列表支持批量公开与 AI 知识库收录,MCP 新增对应的笔记公开与收录管理工具;发版后不再预热 EdgeOne,避免节点缓存未压缩版本后由 CDN 自行压缩、长期返回大 15–25% 的 br;修复从文章页点页头导航时页头透字闪烁。
新增
- 笔记批量管理:后台笔记列表支持逐条勾选、全选当前页和取消选择,可批量设为公开或私密、收录到 AI 知识库或移出。公开与收录前确认使用当前工作稿,两个状态互不影响;整批校验所有权、版本和内容后在同一事务中提交,任一条冲突都不会部分生效。切换筛选、翻页或刷新会清空选择,筛选末页被批量移空时自动返回有效页;移动端操作栏自动换行。
- MCP 笔记公开与收录管理:新增
publish_note、unpublish_note、include_note_in_knowledge、exclude_note_from_knowledge,分别公开当前工作稿、撤回公开、收录当前工作稿或移出 AI 知识库。复用独立notes_write授权,已有笔记写入令牌即可使用;在笔记行锁与同一事务内检查笔记本范围和工作稿版本,不能操作他人、范围外或回收站笔记。get_note(draft=true)返回公开与收录版本号;创建和编辑仍不自动公开或收录。后台令牌授权说明同步明确新增能力。
移除
- 发版后不再预热 EdgeOne:删除
scripts/edgeone-prefetch.ts、deploy.fish中的调用和 CI 的prefetch-cdn作业。EdgeOne 预热不理会请求里的Accept-Encoding: br,回源时用 Range 请求拿未压缩文件;节点缓存的是未压缩版本时,浏览器请求 br 拿到的是 EdgeOne 自己压缩的结果,比源站预压缩的.br大 15–25%(主 WASM 316 KB → 396 KB),文件按 immutable 缓存一年都是这个大小。部署后预热回源期间,主 WASM 还出现过 16 秒无数据、页面一直不水合。不预热时由浏览器请求触发回源,节点缓存的是源站的.br。
修复
- 文章页点页头导航不再闪烁:文章页不属于任何栏目,原来从它跳到其他页面走整页过渡:页头单独截图、只显示新页面的页头,新页面在顶部时页头是透明的,滚动后原本被页头遮住的正文会以全对比度叠在导航文字上,约 200ms 后才消失;整页淡入淡出也在约 50ms 内基本完成,看起来像硬切。现在前台外壳内没有文章标题或封面共享过渡的导航,都和栏目切换一样只截取正文、页头保持实时:两个不同栏目之间仍横向滑动,其余(文章、同栏目内、分页、更新日志等)原地淡入淡出,从文章回到栏目时导航胶囊原地淡入。旧正文快照保持自身尺寸和原位置,文章栏(1240px)比栏目栏(880px)宽时不会被等比缩小或错位,右侧目录也不会被裁掉。
1.2.1
第二轮首屏优化:分包数量再减半,当前路由的分包随主包一起预载,固定路径样式与脚本按内容版本长期缓存,发版后自动预热 EdgeOne 中间层。本地模拟 EdgeOne 的对照中,回访水合快 30–40%,移动端冷加载水合再提前 150–250 ms。另修复源站复用连接每响应慢 40 ms、快速切换栏目闪烁与点击无响应、正文图片间距错位。
改进
- WASM 分包再减半:线上 EdgeOne 对同一客户端的并发请求大致逐个处理,每个约 2–3 ms,首页 60 个 1–5 KB 的分包整批要排 120–200 ms,开发者工具里每个小文件都显示 200 ms 上下。release 前端的分包合并代价(
WASM_SPLIT_CHUNK_LOAD_COST)由补丁默认的 1024 调到 8192:首页 60 → 21 个、文章页 70 → 26 个、归档 32 → 11 个.wasm,各路由首屏 WASM 总量变化不到 ±5%(关于页等小页面多 20–40 KB)。 - 当前路由的分包随主包一起预载:此前分包要等主 WASM 下载并实例化、水合开始后才发出请求,整批多等一轮。现在 HTML 只为当前路由的视图分包输出
<link rel="preload" fetchpriority="low">(不再像 Leptos 默认那样展开全部懒加载取数函数的分包),低优先级保证不与 CSS 抢带宽。本地模拟 EdgeOne 的对照中,首次绘制不变,冷加载水合桌面提前 55–135 ms、移动端(1.6 Mbps、CPU 降速 4 倍)提前 150–250 ms(关于页持平),回访水合快 30–40%。对照数据见docs/首屏性能实测-2026-10-28.md「第二轮」。 - 全局样式与脚本可长期缓存:
style.css、highlight.css、KaTeX 样式、yggdrasil-core与灯箱、编辑器、终端、Mermaid 等固定路径资源,原来靠手写的?v=N区分版本、响应no-cache,EdgeOne 每次回源(实测 65–360 ms,在首屏关键路径上),回访也要整份重下。现在服务端按文件内容生成版本号写进地址,页面头部下发版本表供前端按需加载时使用;版本号与当前文件一致时返回immutable,旧版本号仍需校验,不再手动维护?v=。 - 发版后预热 CDN:新增
scripts/edgeone-prefetch.ts,读取线上首页引用的全部分包、入口和版本化资源,调用 EdgeOne 预热到中间层(带Accept-Encoding: br,与浏览器请求的缓存变体一致)。scripts/deploy.fish在 primary 部署成功后执行;CI 新增prefetch-cdn作业,需配置EDGEONE_ZONE_ID变量与TENCENTCLOUD_SECRET_ID/KEY,未配置时跳过。
修复
- 源站复用连接的响应慢 40 ms:服务端没有关闭 Nagle,hyper 分两次写响应头和包体,nginx 反向代理的 keepalive 连接上每个响应都要等对端约 40 ms 的延迟 ACK。线上约三成回源请求因此是 41 ms 而不是 1 ms。现在接入的连接都设置
TCP_NODELAY,同一连接上的连续请求由 40 ms 降到 0.1 ms。 - 快速切换栏目不再闪烁:栏目切换时,旧正文 140ms 内几乎淡完,新正文按 410ms 弹簧曲线才开始浮现,中途两者合计只剩约 30% 不透明,深色主题下正文区会黑一下。现在新旧正文用同一条 140ms 曲线互补淡入淡出,滑入仍用弹簧。动画播放中再点下一个栏目时,不再跳过当前过渡重新截图(刚进入的页面会跳回全亮、冻住一两百毫秒、再淡出一次),而是在播放中的过渡里直接换页;浏览器暂停绘制、等上一页渲染的那段时间里的点击先记下,等动画开始后接着跳转。
- 过渡期间点页头不再无反应:截图到动画开始之间(每次切页约 80–200ms),以及普通页面过渡的整段动画里,浏览器把点击都落在
<html>上,页头链接的点击会被吞掉。现在按点击坐标在页头、页脚和后台侧栏里找回被点的链接。 - 正文图片上方空隙过大、底部被裁:站内图片外框
.blur-img里两层绝对定位的<img>被正文通用图片规则加上了1.6em上下外边距(该规则特异性高于images.css的重置),图层整体下移 26px,图片上方的空隙比下方大一倍,底部同样高度的一条被外框裁掉。通用规则现在排除这两层图,间距只由外框负责。
1.2.0
首屏与回访加载优化:HTML 不再附带数百条 WASM 分包预载,入口按内容命名后可以长期缓存,分包数量减少 3–5 倍。线上实测移动端(1.6 Mbps、CPU 降速 4 倍)首次绘制由 2.1–4.9 秒降到 1.1–1.4 秒,每页请求由 300–700 个降到 95–180 个;回访不再重新下载主 WASM,水合约 1–1.5 秒。实测与对照数据见 docs/首屏性能实测-2026-10-28.md。release 前端需要用 make install-cargo-leptos 安装分包合并补丁版 cargo-leptos。
新增
- 本机部署脚本:
fish scripts/deploy.fish在本机用国内镜像源(清华 Debian/Alpine、rsproxy、npmmirror、gh-proxy)构建 amd64 镜像,经docker save | ssh podman load直传 xun / rua,不经过 GHCR。流程与 CI 部署一致:按ROLE先部署 primary(重建 app,检查/readyz与x-yggdrasil-hash,失败自动回滚),primary 成功后再给 standby 预置镜像。支持--skip-build、--with-runners、--only xun|rua、--allow-dirty。
改进
- HTML 不再预载 WASM 分包:Leptos 会为服务端渲染时调用过的每个懒加载取数函数展开全部分包
<link rel="preload">,且不去重,首页<head>里有 363 条。弱网下它们与 CSS 抢带宽,移动端首次绘制慢 0.5–2.5 秒,水合并不更快。现在只预载主包和分包加载器,其余分包由加载器按需请求。 - 入口 JS / WASM 可长期缓存:发布装配按入口 JS、主 WASM 与分包加载器三者的最终内容重新命名它们,并在
hash.txt写入entry: content-addressed;带该标记时,服务端对入口返回immutable。此前入口只能no-cache,而 EdgeOne 不缓存no-cache资源,也不把条件请求转给源站,回访每打开一页都要整包重下 317 KB 的主 WASM。未经发布装配的 dev 与回归构建,入口仍每次校验。 - WASM 分包数量减少 3–5 倍:release 前端改用打了分包合并补丁的 cargo-leptos 0.3.11(
wasm_split_cli_support换成VOD-Studio/wasm-split-prototype的ygg/chunk-merge分支)。原版按「需要它的分包集合」逐一切出共享分包,59 个懒加载点切出 1121 个共享分包,半数不到 200 字节,打开一篇文章要请求 379 个.wasm。补丁把合并后收益为正的小分包贪心合并,共享分包降到 262 个,文章页降到 70 个.wasm,各路由首屏 WASM 总量基本不变(文章页少 31 KB)。在模拟移动网络(1.6 Mbps、150 ms、CPU 降速 4 倍)下,水合完成提前 0.3–2.2 秒。make install-cargo-leptos安装补丁版;release 前端构建会检查,test-release-split增加每条路由不超过 150 个.wasm的门槛。
1.1.1
生产环境改为 xun 主、rua 热备的双机主备部署:CI 按节点角色部署,补齐运维文档与线上脚本。v1.1.0 的发版流水线中途取消、未部署,本版本一并上线 v1.1.0 的全部改动。
新增
- 双机主备运维文档:
docs/双机主备/记录生产 xun / rua 的拓扑、为什么只能主备不能双活、日常检查、故障切换、回切、重建热备与回源密钥轮换,并收录两台服务器实际安装的 compose、systemd 单元与ygg-failover、ygg-rebuild-standby、ygg-standby-sync、ygg-origin-auth脚本(不含 IP 与密钥)。
改进
- CI 双机改为主备部署:xun、rua 按部署目录下的
ROLE文件(primary/standby,缺省primary)区分角色。primary 照旧重建 app、健康检查与失败回滚;standby 只预拉 app 与 runner 镜像,不启动 app(热备库只读,app 启动迁移会直接退出)。deploy-rua 改为在 deploy-xun 之后运行:standby 仅在 xun 部署成功后预拉,使故障切换时启动的版本与 xun 一致;rua 已切为 primary 时不受 xun 结果影响。
修复
- 停止服务不再被强制杀掉:收到 SIGTERM 后,后台实时日志与代码运行的 SSE 长连接立即结束,不再拖住优雅关闭;其余在途请求最多再等 5 秒。此前只要还有一条 SSE 连接没断,进程就会一直等到容器 10 秒停止超时被 SIGKILL,每次部署和主备切换都多等 10 秒。
- 非法页码稳定返回 404:
/page/abc这类非数字页码此前约 2% 的请求返回 200,且这个 200 会被 SSR 缓存 60 秒。原因是前台页面都包在布局的 Suspense 里,流式渲染时 404 能否赶在首个响应块之前写入取决于线程调度。/page/:page改为等渲染完成再输出(首页/仍流式输出),首页标题也改为在渲染时定值,避免注入<head>时读到已释放的页码。
1.1.0
前端框架由 Dioxus 迁移到 Leptos 0.8,启用路由级 WASM 分包与链接悬停预取;部署后仍开着的旧标签页需刷新(接口地址与错误载荷协议已变)。
新增
- 链接悬停预取:鼠标停留、键盘聚焦或触屏按下站内链接时提前下载目标页面的 WASM 分包与页面数据,点击后不再等待下载和首次请求,文章标题与封面的共享元素过渡也不再因加载超时丢失;触屏设备在空闲时预取视口内链接的分包;省流量模式与 2G 网络下不预取。
改进
- 脚本统一为 Bun TypeScript:
scripts/的全部 22 个.cjs工具迁移为.ts,补齐发布装配、字体/图标生成、测试编排与 Playwright 浏览器回归的严格类型;Makefile、Docker、CI 和文档同步切换调用路径,工作区类型检查与 CI 纳入脚本检查,Bash/Fish 运维脚本保持不变。 - 分享图字体工具统一到 Bun:字体裁剪改用
scripts/subset-og-fonts.ts与 HarfBuzz WASM,不再依赖 Python/fontTools;保留 GB 2312 的 6763 个汉字、原有标点范围、字体名称与排版特性,并排除 GBK 解码器额外映射的五个空位。 - Bun 构建工具升级:生产、交叉编译与开发 Docker 镜像统一升级到 Bun 1.4.4,工作区与 CI 同步使用该版本。
- 前端框架迁移到 Leptos 0.8:Dioxus 0.7 整体替换为 Leptos 0.8.22 + cargo-leptos(
--split路由级 WASM 分包),删除 reader / full 双 flavor:前台、后台、登录与组件图鉴全部是懒加载路由,每条公开路由首屏 Brotli WASM 不超过原 reader 产物体积。站内导航仍由yggdrasil-core持有 history 与视图过渡。 - 接口地址不再带哈希后缀:server function 由
/api/<name><哈希>变为/api/<name>,发布切换瞬间仍开着的旧标签页需要刷新。 - 发布产物:前端静态产物位于
public/pkg/,服务端启动时校验同目录hash.txt与pkg/文件配套;YGG_PREVIOUS_PUBLIC_DIR回退/pkg/下已删除的分包。DIOXUS_PUBLIC_PATH改为LEPTOS_SITE_ROOT。分包与加载器长期缓存,入口yggdrasil.<哈希>.{js,wasm}每次向服务器校验:入口文件名不随其中引用的加载器变化,长期缓存会让回访浏览器在发布后用旧入口加载已删除的分包。
修复
- 浏览器回归假通过:页面冒烟改用
/about/writing,检查 HTTP 200、无重定向、完整水合与路由标记,并核对写作指南标题;404 页或仅加载了导航脚本不再视为通过。移除已无对应列表 UI 的封面过渡场景,未知场景参数明确报错,同步清理过期的导航与 rustdoc 回归说明。 - 写作指南直达标题错误:
/about/writing的页面标题移到数据挂起边界之外,流式 SSR 首个响应即带「写作指南 · Yggdrasil」,不再保留全站默认标题。 - 客户端切页丢失分享信息:站点分享上下文由应用根组件随 SSR 页面传给浏览器;从文章页返回首页、或客户端进入文章页后,描述、Open Graph 地址与分享图保持和直达页面一致,不再变为空串或相对地址。
- SQL 控制台执行中按快捷键重复提交:执行按钮在运行时禁用,但 Ctrl/Cmd+Enter 仍会调用同一个执行入口,发出并发的
execute_sql请求:最先返回的请求把按钮提前复位,写操作还可能被重复执行。现在入口检查是否正在执行,执行中按快捷键直接忽略,写操作确认弹窗也只出现一次。 - Server function 错误失去类型:统一使用 JSON 编码的
ApiError,区分未认证、无权限、资源不存在、业务拒绝、服务不可用与内部故障;网络和编解码错误保留框架类别。数据库连接、SQL 与事务细节继续只记服务端日志,SSR 资源往返不丢错误类型,页面与 ErrorBoundary 不再按not_found文本判断 404。错误载荷协议已切换,部署后旧标签页需刷新;HTTP 状态仍沿用 Leptos server function 的错误响应约定,应用类别读取code字段。 - 后台会话验证失败误跳登录页:网络中断或服务错误不再视为未登录,保留当前后台地址并显示可原位重试的验证失败提示;验证成功前不加载后台子页面,只有明确返回未登录时才跳转
/login。 - 慢网络切页不再空白:目标页分包加载超过 300ms 时,旧正文淡出后立即显示目标页骨架屏,骨架的位置与宽度和目标页正文一致(从文章页切到窄页面不会被拉宽,从窄页面切到更宽的组件图鉴也不会被压窄),页面挂载后骨架不再额外延迟 200ms。
make build全程零警告:修复站点 rustdoc 的 34 条链接告警——模块//!文档与声明处///外层文档合并后按父作用域解析,未限定路径的链接断链或指到错误条目,现改为显式路径链接;私有实现项的链接在--document-private-items文档中属预期,放行对应 lint;另删除 cargo-leptos 不识别的env = "DEV"元数据键。- 发布构建告警门禁:修复错误契约与错误展示模块的 3 处 rustdoc 断链;CI 对完整
make build的标准输出、错误输出与退出码执行检查,warning/error 不再因工具返回成功而漏过,并保留完整构建日志。 - 慢分包中断回归漏检:移除挂起中后退的 WASM panic 豁免,使用请求屏障分别覆盖后退与再次导航;检查迟到分包不会覆盖当前页,且后续真实 SPA 导航的正文、文档身份与运行时错误均符合预期,不再仅凭旧页面重新可见判定通过。
- 构建入口可靠性:修复
make -j build在资源或文档尚未生成时启动前端构建,以及预压缩查找或执行失败却返回成功的问题;本地与 Docker 共用预压缩规则,两个发布目标共用装配流程,前端全量构建冻结锁文件,make clean补齐生成的浏览器资源目录清理。 - 懒加载页面切换偶发闪白:目标页分包超过 300ms 时,旧正文先淡出再由新页淡入,不再从满屏内容一帧变空。
- 页面加载中点站内链接后整站点不动:懒加载页面的分包还在水合时点导航,路由器中途换页,水合不匹配 panic 让 WASM 失效,此后地址栏会变、页面不再切换。现在整棵树水合完毕才接管站内链接,之前的点击交给浏览器整页跳转(也不再被 Leptos 自带的链接拦截抢走)。
- 后台文章预览目录进度恒为 0%:预览在
.admin-scroll内滚动,目录进度只监听窗口滚动,进度停在初始值。现在未指定滚动容器时取正文最近的可滚动祖先,窗口滚动的前台文章行为不变。 - 懒加载页面切换时外壳先变:点击文章后,主区宽度、导航激活项与分享信息会先切到新页面,旧页面被放进错误版式停留到新分包加载完。外壳改为跟随已显示的页面,切换超过 300ms 时页面顶端显示进度条;后台侧栏、面包屑同样修正。
- 站点地址缺协议导致全站写请求 403:「可信来源」填
localhost:8080这类缺少http(s)://的值时,所有 POST(含登录)都被 CSRF 拒绝,只能改库恢复。现在保存时拒绝此类值,库里已有的按未配置处理;未配置时只比对来源主机与请求 Host(协议不限),本地 http 开发无需设置。
1.0.1
包含 v1.0 全站重设计与安全修复;v1.0.0 标签因浏览器冒烟误判未生成正式发布产物。
修复
- 手机后台发布检查:浏览器冒烟改为等待可见的主内容区,不再要求按响应式设计隐藏的页面标题可见,避免发布流水线超时。
- 笔记保存回归:删除对原始 HTTP 错误文案的依赖,继续验证失败提示、内容保留与重试持久化行为。
- 代码块弹窗回归:离开有未保存修改的编辑页时明确接受离开确认,再验证弹窗与编辑器清理,不再把取消导航误判为卸载失败。
- 公开阅读性能回归:以未激活代码块实际可读的源码验证静态输出,不再断言已退役的占位 CSS 类;等待客户端路由就绪后操作归档,保留懒加载、零自动执行和归档完整性检查。
1.0.0
v1.0 全站重设计:陶土橙单一品牌色、系统字体与衬线标题、Lucide 图标、弹簧动效与暖调代码配色,前台与后台全部页面按新设计重写。
安全
- 改密 /
ADMIN_PASSWORD轮换后旧会话仍有效:此前只有缓存命中路径比对会话世代,缓存被逐出后的下一次请求会重新放行并回填,被盗 cookie 最长 30 天有效。迁移 031 给sessions加generation快照列(登录时写入),两条校验路径都要求其等于users.session_generation;存量会话按当前世代回填。 - 数据导出只读校验:
/api/database/export的query:来源拒绝EXPLAIN ANALYZE(含EXPLAIN (ANALYZE)写法)、data-modifying CTE、SELECT INTO与行锁子句;SQL 格式导出放进只读事务执行。此前一次跨站 GET 即可让管理员浏览器执行任意 DML。SQL 控制台的读写分类改用同一判定,这类语句改走写路径(受 WHERE 护栏约束并触发缓存失效)。 - 数据导出拒绝跨站触发:
/api/database/export仍为 GET 下载,但只接受Sec-Fetch-Site: same-origin;不带该头的客户端回退到 Origin/Referer 本站校验,来源缺失返回 403。 - MCP 令牌随账号状态失效:bearer 鉴权每次校验持有人当前角色,账号被封禁后其名下令牌(含
/api/mcp/upload)立即失效,无需逐个吊销。 - 后台路由守卫:会话失效、过期或代际不匹配的 cookie 访问
/admin改为跳转登录页,仅数据库错误时放行。 - 头像路径校验:个人资料头像与友链头像共用同一安全谓词,拒绝
..、空路径、双斜杠与 NUL。 - URL 抓取 SSRF:NAT64(
64:ff9b::/96、64:ff9b:1::/48)与 6to4(2002::/16)内嵌的 IPv4 按 IPv4 规则校验,Teredo(2001::/32)直接拒绝。
新增
- 编辑器 GFM 提示块与定义列表:
> [!NOTE]等五种提示块、术语+: 定义定义列表可在富文本里无损往返,提示块、H5/H6 与任务列表样式与前台一致。 - 编辑器折叠块:
<details>/<summary>作为节点显示并原样往返(规范写法:开标签、summary 行、空行、正文、空行、闭标签)。 - 关于页插图:标题旁新增像素风插图,悬停时切换表情。
- ⌘K 面板:前台搜索(文章建议接口、最近搜索、范围标签)与后台命令面板。
- 首页书桌:最新一篇目录预览、按月索引、可配置标语。
- 笔记阅读上下文:笔记本目录、上一篇/下一篇、
?book=,以及笔记本目录页。 - 分享图与网站图标:
/og/site.png、/og/post/{slug}.png,明暗 SVG 图标与 manifest。 - 细节补全:404 推荐文章、交换友链信息、关于页统计、仪表盘发布节奏、侧栏数量、回收站剩余天数、设置统一保存条、笔记版本面板、密码强度条、新建文章起步模板、草稿预览宽度切换、灯箱缩略条与缩放档位、MCP 令牌接入配置。
- 组件原语:
SegmentedControl(窄宽只留图标)与Composer输入栏族(Composer、ComposerInput、ComposerSend),组件图鉴同步收录。
改进
- 文档站点化:
/doc(rustdoc)换成与博客一致的顶栏、页脚与手机抽屉,导航新增「文档」;主题只由顶栏三档(浅色/深色/跟随系统)切换,不再提供 ayu。左栏只做模块导航并带筛选框,右栏为「本页」目录与阅读进度;标题区、条目表、字段、impl 卡片、Trait chip、文档正文、搜索结果与源码页全部重排,界面文字改为中文。crate 首页按「界面 / 服务端 / 共享 / 其他」分组。 - MCP 限流进后台:MCP 请求与 MCP 传图两组按令牌计的限流并入「后台设置 → 接口限流」,修改后重启生效。
RATE_LIMIT_MCP_PER_SEC/_BURST/RATE_LIMIT_MCP_UPLOAD_PER_SEC/_BURST改为仅在对应设置键不存在时首启播种,与其他RATE_LIMIT_*一致;已部署实例升级后首次启动会把当前环境变量值写入数据库,之后不再被环境变量覆盖。 - 全站重设计:设计 token、系统字体栈、深色模式重新调色、页面转场改用 snappy 弹簧与 out-expo 曲线。
- 后台改为桌面应用式外壳:可折叠、可拖宽的侧栏,面包屑,表格发丝线分隔。
- 发丝线:2 倍及以上高分屏为 0.5px,其余为 1px(
--hairline)。 - 搜索面板:关闭时 120ms 淡出,手机全屏时输入框旁为「取消」。
- 后台失败提示:改为可读文案,不再拼接 server function 原始错误。
移除
- Catppuccin 主题、
paper-*样式与桥接层、线条小狗插画、Material 图标、PostCard、FilterTabs(由SegmentedControl取代)、SproutPlaceholder(更名为ImagePlaceholder)。
修复
- 工作流校验安装失败:
actionlint改为下载官方固定版本发行包并校验 SHA-256,不再经不支持该工具的 Rust 安装器回退到 Cargo,修复lint-workflows在校验前退出的问题。 - 后台编辑器载入文章后内容错位:块级公式
$$只在行首起算,行内代码里的$$不再把后面所有公式配对错位、吞掉整节;脚注定义同样只认行首,引用前不再被换行切断,并支持空行后缩进的多段脚注;H4–H6 不再显示成 H1。 - 富文本保存会改写原文:文章写作页载入正文、或从源码切回富文本时,由服务端比较「原文」与「编辑器往返后的 Markdown」渲染出的 HTML;不一致就锁定在源码模式并给出提示,原文不会被改写,也不会误判为未保存。
- 前台任务列表嵌套项:嵌套列表不再排到父项文字右侧,改为换到下一行并从父项文字处缩进。
- 表格行「⋯」菜单被裁切:操作菜单改用
position: fixed,按触发器矩形定位,不再被表格面板的overflow: clip截掉下半截;下方放不下时自动向上展开,滚轮滚动时收起。 - 后台编辑器往返改写原文:
~x~/^x^成为真正的下标/上标(词内H~2~O、x^2^保持字面量);CJK 标点旁的转义不再丢失;©等 HTML 实体原样保留;<kbd><mark><abbr><sub><sup>成对标签变为可见格式,其他行内原始 HTML 原样保留;参考式链接与定义行、松散列表、编号列表项内的代码块、多行块级公式不再被改写;裸 URL / 裸邮箱不再自动成链。 - 服务端 KaTeX 输出每次不同:
katex-rs的 SVG 属性顺序随机,同一公式两次渲染的 HTML 不同,含根号等 SVG 的正文在往返守卫里永远被判为有损。现在输出前按属性名排序。 - 编辑器公式预览:支持
\ce{}/\pu{}(mhchem)与服务端物理宏表(\RR\dv\ket等),不再显示红字。 - 后台分页列表翻页回跳:快速翻页或切换筛选时,过期响应不再覆盖最新结果。
- 日志页切换筛选泄漏:实时日志的 SSE 回调随连接一同释放,不再每次切换都
forget一组闭包。 - 流式代码运行器可能挂死:
wait出错时 kill 容器,结束后限时排空日志,并发许可与容器必然释放。 /mcp与 MCP 上传伪造令牌洪泛:令牌解析(要查库)前先按 IP 限流(每秒 30 次、突发 100 次),超限返回 429。- 文章写入越界:标题(200)、摘要(500)、封面地址(500)、标签数(16)与单标签(50)在写库前校验,返回明确提示,不再以数据库 22001 报错。
- MCP 评论工具与后台行为不一致:评论列表与审核改为委托后台同一实现;
set_comment_status(approved)也会递归通过待审祖先,list_comments(trash)返回回收站评论。 - 全量重建渲染超时:按 id 游标每批 100 篇、事务外渲染、乐观写回,前端循环续传。
- 文章 PATCH 更新持行锁渲染:正文渲染移到行锁事务之外。
- SQL 导出整表入内存:改为流式输出,行在只读事务中逐批推送。
- 提示条不自动消失:计时任务挂到提供者 scope,提示后立即跳转也会按时消失。
- 后台页面 SSR 白发查询:设置各分区、MCP、日志、代码运行器、系统状态页的首屏数据只在浏览器端加载。
- 代码块编辑器/终端创建失败无提示:显示「初始化失败」并可重试,运行按钮不再一直转圈。
- 笔记本页失败误报:目录请求失败时显示「笔记本暂时没能加载」并可重试,不再误报「不存在」;「加载更多」失败时给出提示。
- 代码块复制失败仍显示已复制:改走统一的剪贴板封装,失败时显示「复制失败」。
- MCP 令牌页接入片段站点地址:优先使用设置面板中的站点地址,不再只读环境变量。
- 化学公式兼容:mhchem 的箭头与化学键改用 KaTeX 支持的命令,避免公式渲染失败。
- 写作页属性抽屉:进入编辑页时不再重复播放入场动画。
- 图片灯箱拖动平移:鼠标拖动在 fit 倍率下也能平移图片,不再触发下拉关闭;放大后仍小于视口的方向也可平移(只限制不移出视口,不再强制居中);双击回 fit 时重新居中。触屏 fit 态仍保留竖直拖拽关闭。
- 代码运行器:非流式执行在等待容器出错时也会终止容器,读取日志有超时上限,不再永久占用运行信号量。
- MCP 标签工具:
create_tag/rename_tag同时失效文章列表、标签页与 SSR 缓存,改名后公开页面立即更新。 - 长度校验按字符计:用户名、评论昵称与评论内容按字符数而非字节数校验,与提示一致(中文昵称不再只能写约 16 字)。
- 设置上限:图片磁盘缓存容量与保留时长、限流速率、运行器输出与源码字节数补齐上限钳制,极大值不再关掉限制。
- 可信代理段数说明:README、
.env.example与「后台设置 → 安全」面板改为说明TRUSTED_PROXY_COUNT是 X-Forwarded-For 中真实客户端 IP 右侧的段数,而非代理层数;面板该项更名为「可信代理段数」。CDN + 源站反代应填 1,按原说明填 2 会信任伪造的 XFF 段。 - 素材库列表查询:本页引用计数改由已取回的引用明细派生,不再为每行跑 5 个关联子查询;tabs 汇总改为每个素材只判定一次引用(原先同一判定每行算 4 遍);
note_asset_refs补asset_id索引(迁移 030)。
内部
- 消毒白名单预构建为静态实例;回收站批量恢复与彻底删除改为一次批量查询标签;
replacement()返回已校验字段,去掉依赖非局部不变量的expect()。 - 收敛重复实现:HTML 转义、settings 单键 upsert、原生路由 admin 前置校验、评论内容哈希、
group_digits、主题过渡探测;删除未使用的常量、组件、CSS 规则、codemirror依赖与过时的dead_code豁免。 - 测试改为调用生产函数:健康检查、上传转码;删除源码字符串断言测试;两个 TEMP 表数据库回归改读
DATABASE_URL并写入测试文档;scripts/test-dev-assets.ts从mk/assets.mk读取输出清单;清理 FreeBSD 残留忽略规则。 - 代码运行器流式执行超时只推送一个
done事件(此前 runner 与调用方各推一个);run_in_container_stream去掉恒为false的timed_out返回值,与非流式路径统一为 4 元组。 public/下的libs/构建产物(codemirror、lightbox、tiptap、xterm、yggdrasil-core)移出 git 索引,与.gitignore一致;构建产物一律不入库,由make build-libs/make dev-assets生成。- 收拢组件:新增
StatusDot,后台 9 处手写.status-dot改用它;StatusBadge增加class附加类,更新日志「最新」与文章标题「草稿」徽章改用它;友链、笔记本、代码运行器表单标签改用FormLabel并删除三份重复样式;删除仅展示页使用的旧接口LoadingButton与已无引用的骨架屏样式。
0.25.0
新增
- 前台音乐播放:新增仅在前台布局挂载的全局音乐播放器,通过公开启动配置与按需加载的 Web Components 接入 Kite;支持切页续播、主题同步、刷新恢复队列与进度,离开前台时暂停,默认不自动播放。
- 双机部署:提供独立的 Kite 公开服务 Quadlet,复用现有 HTTPS 域名的
/player/v1/反代路径;公开服务与管理实例隔离,两台博客使用同一公开地址与歌单白名单。
改进
- 全局音乐播放器:将
@violetjs/kite-player从0.1.0升级并锁定到0.3.0,沿用按需加载的 Web Components 接入,获得音质切换、试听标记、无封面占位及新版展开/歌词交互;新增浏览器回归覆盖音质切换不中断进度及刷新后偏好恢复,保留前台切页续播、主题同步与退出暂停行为。
0.24.2
改进
- 组件图鉴:移除骨架屏展示条目、页面布局分类及其独立详情预览,清理对应预览代码与样式;骨架屏和页面布局组件仍保留在正式业务页面中使用。同步更新目录完整性检查、浏览器回归断言及图鉴维护文档。
0.24.1
修复
- Docker 构建:
.dockerignore放行 release 装配脚本build-release.ts及其导入的release-bootstrap.cjs,修复 P3b 把 flavor 装配移进容器执行后构建上下文缺文件报 Module not found 的问题;其余scripts/保持排除。 - 构建入口:补回 P3b 误删的
make build-clientrecipe。此前.PHONY保留了同名目标,make 会静默跳过无 recipe 的 phony 目标,导致build-linux与 Dockerfile / Dockerfile.cross 的首个客户端构建变成空操作,CI Docker 构建在snapshot-flavor处失败。
0.24.0
新增
- 读者版双客户端:公开阅读路径默认加载编译期裁剪的 reader 客户端,后台、登录与图鉴路由被编译剔除,匿名阅读不再下载完整应用;reader WASM Brotli 体积较优化前基线下降 49.9%(989.4 → 495.6 KiB)。跨入口进入后台属整页导航,按设计另载 full 产物(首次阅读到进入后台累计下载约 2.2 MiB,已随验收报告公开)。
- 双产物发布流水线:
make build顺序产出 full/reader 两个客户端并按发布清单合并;装配改为临时目录原子换入,中断不再破坏既有发布目录;SSR 缓存按 release×flavor 命名空间隔离,组合变化整表失效。 - 旧发布资源保留窗口:新增
YGG_PREVIOUS_PUBLIC_DIR,滚动更新期间旧标签页仍可加载新发布已删除的内容寻址资源,窗口与清理由部署流程控制。 - WASM preload:发布装配期从模板解析 WASM 入口并注入
<link rel="preload">,解析失败或两 flavor 入口重合时在覆盖旧发布前失败;附真实请求链冷/热缓存 A/B 回归。 - 按需增强脚本:全局阻塞脚本拆分为启动核心与增强 IIFE,灯箱与文章增强、Mermaid、目录、图鉴瀑布流、更新日志导航改由组件按需声明注入,配缺失函数补执行队列;全局阻塞传输下降 17.6%(69.2 → 57.0 KiB),head 阻塞请求 7 → 5。KaTeX 与高亮样式保持全局加载以避免首跳裸样式闪烁。
- 发布测量与回归:新增 release 产物测量脚本、双产物浏览器回归(缓存、旧资源窗口、完整应用回退等 74 项断言)与 preload A/B 测试;发布清单与 preload 一致性检查并入
make test与 CI。
改进
- 浏览器日志链:release 客户端不再启用 Dioxus 默认日志订阅器(开发期经
dev-loggerfeature 保留),WASM Brotli 再降约 20 KiB;线上错误诊断依赖组件级错误 UI。 - 代码运行器:可运行代码块接近视口时才加载 CodeMirror 并创建实例,激活前展示服务端高亮的静态代码(顺带修复 SSR 只有骨架条、代码文本对爬虫不可见的问题);滚出视口不销毁实例,运行意图在编辑器就绪后执行一次。
- 公开笔记数据:笔记详情改用精简 DTO,不再下发编辑用 Markdown 与内部字段;切换发布状态前已打开的旧标签页仍可反序列化新响应。
- 正文渲染开销:正文片段解析结果按内容哈希做进程内有界缓存,主题切换等重渲染零重新解析;页眉、元信息与页脚组件改收小型字段集,不再复制或深比较完整正文。
修复
- 正文复制按钮:点击不再误触发编辑器激活,加载提示区分失败状态。
- 跨产物导航:reader 与 full 的跨入口链接统一渲染为普通
<a>整页导航,修复 reader 路径下 hydration 监听器标记失配导致的页面崩溃。
0.23.4
修复
- SSR 缓存崩溃:公开页 HTML 缓存的响应流结束后被压缩层再次 poll 时不再 panic;此前 release 的
panic = "abort"会使进程反复退出,导致 nginx 间歇返回 502。
0.23.3
改进
- 前端体积:组件图鉴数据与写作技能源码只嵌入服务端,改由水合数据或 server function 下发,WASM 减少约 110 KB(brotli 后约 13 KB)。
- 动态压缩:
COMPRESSION_ALGORITHMS压缩层统一使用质量 6,brotli 比 gzip-6 小 10–17%(tower-http 默认 brotli 4 仅小 2–4%);生产推荐br, gzip,all会让 Chrome 协商到体积更大的 zstd。
修复
- 订阅源压缩:
/feed.xml与/feed.json挂到压缩层,修复含全文的 Feed(线上约 2.5 MB / 1.9 MB)未经任何压缩传输的问题。
0.23.2
改进
- 公开文章传输:阅读页使用独立的轻量响应,不再重复携带原始 Markdown;后台编辑、预览及原有完整接口保持兼容。
- 评论编辑器:顶层评论框接近视口或获得操作焦点后才加载 Tiptap,减少文章首访资源;回复表单仍在打开时加载。
- 公开页缓存:采用最多 32 MiB 的进程内 HTML 缓存,默认 TTL 60 秒,支持 ETag/304;认证请求、笔记、查询参数和不可缓存响应不进入共享缓存。
- 双机缓存同步:新增内容版本与事务提交通知;各实例通过 PostgreSQL LISTEN/NOTIFY 失效派生数据,每 5 秒核对持久化版本并在断线重连后补偿更新。
- 性能回归:新增双实例数据库及浏览器验收,覆盖事务回滚、通知断线、缓存失效、归档分页和评论延迟加载,并接入 CI。
修复
- 归档完整性:改用每页 100 条的轻量归档接口,可继续加载更早文章,修复原接口最多返回 50 条导致的遗漏。
- SSR 缓存:消除非 root 容器无法写入
/app/static导致缓存静默失效的问题;写入后真正清除内存快照,并阻止旧世代的在途响应回填。 - 后台状态:修复备份刷新后旧错误残留,以及笔记类型切换时闪回骨架屏的问题。
- 编辑器弹窗:同步恢复编辑器焦点,避免快速重开可运行代码配置框时被旧的延迟焦点任务抢走键盘输入。
- MCP 工具 schema:零参数工具显式声明
properties,修复 OpenAI 兼容上游(如 MCA)因工具 schema 非法而拒绝整个请求的问题。 - 持续集成:真实数据库回归固定在 GitHub-hosted runner 运行,修复 self-hosted runner 无法使用 sudo 安装 PostgreSQL 客户端而阻断发布的问题。
0.23.1
改进
- 文章写入校验:后台与 MCP 统一使用同一事务和业务校验,保持文章创建、更新与回收站操作规则一致。
- 后台与前端模块:按职责拆分备份恢复、后台页面、公共界面组件和灯箱库,补充架构边界说明。
- 持续集成:严格执行前端与 WASM 检查,并纳入文章数据库回归。
修复
- 编辑器布局:分离编辑器生命周期与保存状态,修复窄屏布局问题。
- 图片灯箱:修复会话清理和切换图片时的状态处理。
0.23.0
改进
- 更新日志导航:版本目录改为高度受限的独立滚动卡片,加入滑动高亮、边缘渐隐与阅读进度;阅读时自动保持当前版本可见,小屏使用横向版本条,支持减少动态效果。
- 开发启动:
make dev按源码、配置及依赖变化增量构建前端库、高亮 CSS 和 KaTeX 资源,自动补建缺失产物;共享代码变化会重建使用它的库,失败的构建不会更新缓存记录。新增make dev-assets与缓存失效回归脚本。 - Rust 依赖:更新 rmcp 至 3.5.1、sqlparser 至 0.63.0,并更新 Tokio、Reqwest、UUID、正则与 WASM 依赖;wasm-bindgen 工具缓存同步至 0.2.129。
- 前端依赖:更新 Tiptap 至 3.31.4、CodeMirror、KaTeX 0.19.0、Mermaid 12.1.0、Vite、Vitest 与 Biome;按新版重新生成 Markdown 补丁,合并 CodeMirror 的 state/view 依赖实例。Mermaid 显式沿用 dagre 布局、classic 外观和现有配色,更新资源版本以刷新浏览器缓存。
- 构建工具:前端包管理在 workspace、Makefile、Docker 与 CI 中统一迁移至 Bun 1.4.2,Docker 构建器使用 Rust 1.99 和 Tailwind CSS 4.3.3;Makefile 拆分为入口与资源、工具缓存、Docker 模块,默认显示目标帮助,并统一发布资源流水线与工具检查。
修复
- 首页开始阅读:修复平滑滚动被路由恢复打断及重复点击失效的问题,同页锚点保持当前文档与历史记录,适配键盘操作、手机和减少动态效果。
- WASM 发布构建:显式禁止在 wasm-bindgen 运行前剥离 WASM 自定义段,修复 Rust 1.99/LLVM 23 下继承
strip = "symbols"导致绑定元数据丢失的问题;新增最小导出回归脚本。wasm-bindgen 缓存下载失败时立即停止,避免误报安装成功。
0.22.0
新增
- 组件图鉴:新增
/about/components和组件独立详情页,收录 83 个组件;支持分类与搜索,展示属性、源码位置与高亮用法,从关于页可直接进入。 - 真实组件预览:图鉴复用正式页面的组件,提供素材弹窗、评论、文章目录、编辑器、终端和灯箱等交互演示,支持恢复默认状态;业务样例使用固定资料与局部状态。
改进
- 图鉴布局与浏览:采用自然高度的瀑布流卡片,支持整卡进入详情、返回后恢复筛选与滚动位置,并完善手机、明暗主题和减少动态效果下的展示。
- 文章阅读界面:优化文章页头、元信息、标签与相邻文章导航的排版,同步完善面包屑、评论和页面布局的图鉴样例。
- 笔记管理:搜索框统一使用公共输入组件,补充清除筛选操作,改善快速记录的聚焦反馈;笔记本目录编排面板增加折叠展开动效。
- 空状态插画:空列表默认从 18 张小狗插画中随机选择,保留自定义配图与行动按钮。
- 样式构建:Tailwind 样式改为在开发和发布构建时生成,不再跟踪生成的
public/style.css。
修复
- 修复浮层键盘监听和弹窗焦点行为,完善浏览器组件卸载后的清理。
- 修复响应式分页布局,以及素材上传状态行的稳定键未生效问题。
0.21.1
改进
- MCP 令牌管理:支持编辑已签发令牌的权限,可追加或收回笔记读写授权,并限制到指定笔记本;修改后原令牌继续有效。
0.21.0
新增
- 笔记与知识库:新增
/notes、/admin/notes和/admin/notebooks,支持随记、主题笔记、笔记本编排、标签搜索、公开状态与知识库收录状态筛选。 - 笔记版本工作流:工作稿、公开版和知识库收录版使用独立快照;支持自动保存、历史版本恢复、乐观锁、发布/撤回、回收站恢复以及笔记本归档/恢复。
- MCP 笔记工具:新增
search_knowledge、get_note、list_notebooks、get_notebook、create_note、update_note;笔记读取和写入使用独立授权,可限制到指定笔记本,AI 写入只生成工作稿,不会自动发布或收录。 - 笔记私密图片:新增受保护的
/note-media/<uuid>存储与鉴权,单图限制 5 MiB,并保护历史版本、回收站和素材引用不被误删。
改进
- 编辑体验:快速记录与笔记编辑器增加标签页恢复副本、未保存离开保护和保存期间输入保护。
- MCP 令牌管理:增加笔记授权表单的必填校验、错误提示和失败后自动聚焦。
修复
- 统一笔记筛选器、笔记本与编辑器选择控件及编辑页侧栏样式。
- 补齐
rua部署所需的代码运行器镜像拉取与完整性校验;镜像缺失时阻止应用重启。
0.20.2
新增
- MCP 草稿与回收站工具:新增
list_posts(按status查询草稿,支持标题query)、get_post_by_id(读取完整编辑内容及updated_at)、list_trashed_posts、restore_post(恢复保留原发布状态,slug 冲突自动追加后缀);均需write/admin令牌且仅访问令牌用户自己的文章,公开的search_posts/get_post行为不变。 - MCP 文章更新乐观锁:
update_post支持携带expected_updated_at做版本冲突检测,版本不匹配返回conflict及当前版本且不写入更改;不传版本保留原有行为。 - MCP 素材管理工具:新增
list_assets、update_asset_alt、delete_asset、batch_delete_assets、purge_orphan_assets、rebuild_assets_index(均需admin令牌),与后台共用引用保护,草稿及回收站文章引用同样受保护。 - MCP 上传返回素材 ID:
upload_media与本地 multipart 上传通道统一返回asset_id/alt/url/尺寸/最终 MIME/reused;alt持久化到素材库,重复上传按内容去重返回相同素材 ID。 - Agent 写作指南页面:关于页新增入口卡片,新增
/about/writing页面展示写作 skill 说明、安装步骤与 MCP 客户端配置,新增public/skills/yggdrasil-writing/SKILL.md供 Agent 直接安装。
0.20.1
新增
- Codex MCP 接入配置:MCP 令牌页面新增可直接复制的 Codex TOML 配置,支持用户级或项目级
config.toml通过 Bearer Token 连接站点 MCP 服务。 - 后台单选框组件:新增主题化原生 Radio 组件,保留键盘、互斥与表单语义;数据导出页的导出模式切换改用该组件。
0.20.0
新增
- 全站视图过渡与双向状态恢复:引入原生 View Transitions API,实现前台跨页面平滑视图过渡;顶栏导航支持栏目平移切换动效与下划线共享过渡;实现文章列表与文章详情页的双向滚动位置与浏览状态精确恢复,隔离主题切换动画并协调过渡中断。
- 前台公共页面重构:
- 数字花园首页:全新设计首页文章流与卡片层次、列表悬停与进入动效,重设计错误态与重试交互反馈。
- 归档时间线与标签合并:重设计归档时间线与响应式阅读层次;顶部新增默认折叠的标签索引,支持平滑折叠、标签错峰显隐与悬停反馈;旧
/tags地址永久重定向至/archives。 - 搜索索引与交互:重设计文字索引展示,支持防抖自动搜索、中文输入法保护与实时高亮。
- 花园刊物专题:重设计标签刊物专题页面(
/tags/:slug)及响应式排版与交互动效。 - 友链名片与世界树关于页:重设计友链名片悬停反馈与头像加载动效,重构关于页设计与排版。
- 前端库按需加载:CodeMirror 编辑器、Tiptap 富文本、Mermaid 流程图、xterm 终端等重量级前端库按需动态加载,重构 Mermaid 共享渲染器加载与竞态处理,显著优化首屏包体积与资源加载策略。
- 构建与环境增强:
- 在
make与make dev前增加 CLI 工具依赖检查与llvm-tools组件检查。 - Docker 支持
build-runners镜像构建参数。
- 在
改进
- 前端依赖升级:更新 CodeMirror、Tiptap 3.31.3、Mermaid 11.17.2 与公共构建测试工具,迁移 Markdown 转义补丁;编辑器公式渲染与全局样式统一到 KaTeX 0.18.7。pnpm 升级至 12.3.4,Docker 与 CI 通过 npm 安装其原生二进制;Vitest 升级至 5.0.0,开发环境要求 Node 22.12+(22.x / 24.x / 26+)。
- 架构与构建精简:移除 FreeBSD 交叉编译配置与构建目标,精简仓库文档与冗余上下文文件。
- 设置页与运行器重构:复用回收站配置的数据库读写,整理冗余常量与代码运行器配置解析。
修复
- UI 与交互修复:
- 统一全站文字选区为主题绿色。
- 修复首屏主题图标与保存模式的同步逻辑,修复三态循环与刷新后的主题图标状态。
- 统一头像与文章封面占位回退,为加载失败的封面添加占位样式,修复客户端导航后的封面高度与灯箱点击。
- 恢复图片灯箱滚动缩回原图的过渡动画。
- 修复 SPA 切换文章后目录高亮失效的问题。
- 修复后台文章独立滚动区域在导航后的位置恢复,统一文章预览入口以保留返回状态。
- 编辑器与构建修复:
- 修复双击编辑行内或块级公式时,键盘输入被外层编辑器接管、整条公式被替换为普通文本的问题。
- 清理 Vite 配置的
__dirname兼容警告与 Mermaid 的重复打包选项;同步 wasm-bindgen 预缓存版本至 0.2.128,避免与锁文件不一致导致重复下载。
0.12.5
改进
- 文章阅读版式:正文收敛到 720px 阅读宽度,降低标题与摘要的视觉重量,优化章节间距、引用和页尾导航。桌面悬浮目录保持原样;移动端折叠目录改用轻边框、44px 链接点击区与限高滚动,保留原生键盘展开和章节跳转。
- 首页阅读版式:首页及后续分页共用侧栏与文章流,移动端分页使用紧凑页头,分页导航显示当前页与总页数。移除呼吸徽标和重复导航胶囊;所有文章统一使用轻量列表和可选缩略图,不再单独强调最新一篇。同步深浅主题、键盘焦点与加载占位,保留现有搜索、标签和分页路由。
- Rust 依赖升级:升级至 rmcp 3.2、reqwest 0.13、Argon2 0.6、rand 0.10、AES-GCM 0.11、SHA-2 / MD5 0.11、fancy-regex 0.19、katex-rs 0.3 与 serial_test 4,并更新兼容范围内的锁定依赖。rmcp 不再精确固定预发布版本。
- 密码与令牌兼容:适配新版密码哈希、随机数和加密 API,保留既有 Argon2 PHC、MCP token 密文与哈希格式;操作系统随机源失败时返回错误,不中止服务进程。
- 公式渲染升级:同步 npm KaTeX 0.18.6 样式与字体,移除上游已修复的文本中间点兼容补丁。迁移 026 在事务内更新文章、评论中已保存的公式布局 class,涵盖草稿和回收站,保留原始正文、状态及时间戳;启动时清理公共页面和预览页的旧 SSR 缓存。
- HTTPS 信任配置:reqwest 切换到新版 Rustls / AWS-LC 与平台证书验证器,两种 Docker 运行时镜像显式安装
ca-certificates。
部署注意:首次启动新版前备份数据库并停止所有旧版实例,避免迁移完成后旧渲染器继续写入不兼容的公式 HTML。回滚时须同步恢复旧版公式 HTML 与静态资源,不能仅回退二进制。
0.12.4
新增
- 终端尺寸自适应:代码运行器容器尺寸变化时自动重新计算终端列宽,适配侧栏切换、窗口调整和输出面板展开。
改进
- 后台组件与骨架屏收敛:导航、分页、表单、文章/SQL 表格和骨架屏统一复用共享原子,并补齐列表稳定 key,减少重复实现。
- 启动与部署链路加固:生产监听改为直接绑定,强化启动引导与路由生命周期;部署时强制重建应用镜像。
- WASM 质量门禁增强:为 web-only 目标补充 Clippy 检查。
修复
- 修复 CodeMirror 中 Go 注释高亮错误。
- 修复可运行代码块编辑弹窗语言下拉触发器未挂载、控件样式与主题不一致的问题。
- 修复列表项内代码块与正文间距过小。
- 修复后台侧栏子菜单在组内分页时被强制重新展开,以及菜单 effect 自触发导致页面卡死的问题。
- 修复评论作者网站链接无文字、回复表单切换时草稿丢失的问题。
- 修复素材单图上传绕过文件大小/MIME 校验、关闭按钮缺少键盘焦点样式及弹窗语义不完整的问题。
安全
- 写请求在无法确定本站 origin 或来源头缺失时改为拒绝,修复 CSRF fail-open。
- 修复 IPv4-mapped IPv6 地址绕过 URL 抓取内网地址拦截的问题。
- 会话缓存命中时重新校验会话存在性、过期时间、管理员角色和 session generation;限制密码最大长度为 256 字节。
- 备份导入不再把
DATABASE_URL传入pg_dump/psql参数,拒绝非允许的 psql 元命令,并在恢复后清理全部相关缓存。 - 修复素材删除与孤儿清理的并发窗口,避免新增引用被误删。
0.12.3
新增
- 后台运行日志查看器:新增
/admin/logs「运行日志」页,支持级别与模块筛选、关键字搜索、SSE 实时滚动、历史游标翻页和按筛选导出.log;可配置日志保留策略,后台任务按龄期与行数自动裁剪。 - MCP 文章发布时间控制:创建或更新文章时可通过
published_at指定或调整发布时间。
修复
- 修复运行日志页面 target 下拉框与搜索框的样式和垂直对齐问题。
- 修复文档中的 Rust API 链接。
0.12.2
新增
- 前台首页与文章卡片现代排版重构:
- 首页 Hero 区域:新增状态呼吸徽标、编辑风大字主标题与探索胶囊(快速直达搜索、归档、标签与友链)。
- 分页与面包屑导航:翻页模式(
/page/:page)下自动呈现精简面包屑,提升阅读聚焦度。 - 头条与文章卡片:首篇支持 Featured 专属排版展示;卡片集成 Retina 高清缩略图适配、阅读时长与字数统计、悬浮平滑动效与现代化视觉设计。
- 骨架屏对齐:重构
HomeSkeleton与PostCardSkeleton,保持占位结构与真实文章卡片的几何比例严密契合。
0.12.1
新增
- 素材引用明细浮层:素材管理支持查看文章、评论和头像的全部引用来源。
修复
- 修复素材引用统计未计入头像图片。
- CI 双机并行部署:xun 与 rua 拆为独立 job,在 GHCR 镜像发布后并行拉取并滚动重启;runner 镜像改用公开标签,避免独立私有包无法匿名拉取。
- CI runner 镜像完整性门禁:发布任务核对 GHCR 的 6 个 runner tag,部署前核对 xun 本地最终 tag,缺失时阻止 app 重启,避免代码运行器返回 404。
0.12.0
新增
- 登录用户免表单直发评论:文章评论区在登录态下切换为「身份行(头像 + 显示名)+ 内容框」,免去昵称/邮箱/网站字段与蜜罐,评论直发 approved 免审核,名字旁显示「作者」徽章。
comments表新增user_id外键(迁移 024),读取时 LEFT JOIN users 实时解析显示名与头像;改名或换头像后历史评论自动跟随。 - 后台个人信息与头像:新增
/admin/profile个人资料页,支持显示名称、邮箱、头像素材选择、移除头像与修改密码;密码修改会使其他设备会话失效,侧栏新增用户身份卡片,并统一复用UserAvatar组件。 - 评论富文本与图片上传:评论表单接入精简版 Tiptap 所见即所得编辑器,支持按钮上传和粘贴图片;新增评论图片上传端点、匿名双层限流与评论 HTML 图片标签放行。
- 备份导入恢复:新增备份导入接口,支持 multipart 流式落盘、签名校验、同名冲突拒绝、磁盘空间预检、临时文件原子入库与
BACKUP_IMPORT_MAX_MB单文件上限。 - 评论引用感知的孤儿素材清理:新增孤儿素材定期清理任务,识别评论中的素材引用并按保留期回收未引用上传文件。
- 后台页面体验重构:重做文章、回收站、评论、写作、素材、友链、MCP、代码试运行、系统与设置等管理页面,统一卡片化布局、导航、操作反馈和诊断信息展示。
改进
- 编辑器与界面组件统一:增加 Tiptap
full/comment变体机制,统一文章编辑器与后台/前台 Checkbox 样式,收敛公共表单、Tooltip、Popover 等组件。 - 后台交互细节收紧:评论和素材相关操作采用一致的上传错误清理、过渡动画、表格滚动与按钮对齐行为。
修复
- 修复回收站和评论管理表格出现双滚动条的问题。
- 修复 Tiptap
full变体因浅合并editorProps覆盖默认配置而挂载崩溃。 - 修复取消代码运行后容器清理不完整的问题。
- 修复后台骨架屏重复页头造成的高度溢出与滚动条抖动,以及 Tooltip 的
group命名空间冲突。 - 修复从后台切回前台后文章列表点击失效、评论提交按钮尺寸对齐异常等问题。
- 修复跨环境备份恢复的数据库属主兼容性与失败回滚,确保任一 SQL 失败时不留下半恢复数据库。
安全
- 评论图片上传增加匿名分层限流,降低滥用风险。
0.11.0
新增
- 站点配置页分区化重构:设置页重制为「左侧导航 + 右侧独立滚动内容区」分区化布局;安全配置与图片缓存配置改为 DB 驱动即时生效层(改完即生效);限流 / WebP / 图片 / 运行器等 Tier B 配置提供可编辑 UI(重启后生效)。
- 定时自动备份:新增备份后端——设置模型 / API、定时调度任务、uploads 打包、自动轮转保留;备份恢复 tab 顶部新增自动备份设置卡片与备份列表配对展示;封装
TimePicker替换原生时间输入。可通过BACKUP_*环境变量在首次部署时播种。 ADMIN_*环境变量启动同步初始管理员:启动时自动创建或覆盖密码并确保管理员角色,每次启动均同步(env 优先于 DB),免手动首注册流程。- 后台全页面过渡动画:仪表盘、文章列表、回收站、评论、写作、素材、友链、MCP、代码试运行、系统、设置等页面统一增加进场动画(页头 / 行 / 卡片 stagger),分区切换与切语言时重播。
- 编辑器接入素材库多选插图:写作页正文编辑器新增 slash 命令「素材库」与
insertImagesFromLibrary实例方法;AssetPickerModal多选模式,一次插入多张站内图片。 - 素材上传弹窗增强:改为 worker 池并发上传,并发数(1–8,默认 3)可在站点配置或
UPLOAD_CONCURRENCY环境变量调整;新增上传状态展示与弹窗内分页。 - 友链头像素材库选择:后台友链头像支持从素材库挑选,统一素材弹窗样式。
- 灯箱查看器操控:图片灯箱新增底部毛玻璃工具栏(缩小/放大/顺时针旋转 90°/重置/下载原图/关闭),支持滚轮锚定光标缩放、双击切换 2.5×、放大后拖拽平移、移动端双指捏合缩放与竖直拖拽关闭,快捷键
+/-缩放、R旋转、0重置;按钮/旋转/重置带 180ms 过渡动画,缩放时浮现倍率徽标,工具栏空闲 2.5s 自动隐藏。 - 灯箱图片加载失败错误态:图片加载失败时退避重试、显示
is-error占位、灯箱内给出提示而非闪退。 - 仪表盘 30 日发文 sparkline:总文章数卡内嵌近 30 个自然日每日新建文章数迷你折线(真实数据,
get_post_stats附带activity_30d序列,随统计缓存),折线 + 淡色面积填充,全零时如实呈现平线。 - 仪表盘接口失败重试:统计、近期文章、待审评论三路加载各自带失败态,接口失败显示「加载失败 + 重试」,不再骨架屏永转,也不回退成 0。
- 写作页封面图增强:封面图点击放大灯箱、拖拽替换、hover 工具栏,加载期间显示骨架占位。
- 页脚可配置 GitHub 图标:页脚宽度对齐 header,新增可配置 GitHub 图标。
x-yggdrasil-hash响应头:服务端新增暴露 git commit hash 的响应头(EXPOSE_VERSION_HEADERS控制)。- 图标系统化:搜索框清除按钮、编辑器切换按钮等改用 Material Symbols 图标,并新增图标工作流 skill 规范化内联 SVG 流程。
- 双机部署脚本:新增
both.fish双机部署脚本(xun Primary + rua Replica)。
改进
- WASM 体积优化:声明
wasm-releaseprofile(opt-level="z"/lto="fat",夺回 dx 默认注入的opt-level="s",WASM 产物 ~2.7MB vs 原 3.47MB);全部静态文本资源(WASM / JS / CSS)构建期预压缩为.br旁车,服务端经precompressed_br()直发,零运行时 CPU,wire size 降至 ~732KB。 - 部署改为 pull-based:xun 从 GHCR 拉取镜像部署(替代 scp 推送),并接入 rua DR 副本可选自动部署(best-effort);runtime 镜像由 scratch 换为 alpine + postgresql16-client,支持
pg_dump/psql备份。 - 图片限流按缓存 miss 计费:图片处理限流改为按缓存 miss 计费 + 并发处理上限 + 429 响应携带
Retry-After,避免对缓存命中请求误限。 - 仪表盘趋势徽章真实化:总文章数卡写死的「+12%」改为真实的近 30 天新增篇数(
PostStats.recent_30d),>0 时绿色徽章 + ↑ 箭头双编码(WCAG 2.2 SC 1.4.1),+0 走中性描边;「活跃」「待处理」占位徽章移除。 - 仪表盘动效预算收紧:卡片 hover 过渡 300→200ms、入场去掉内联 600ms 回退到 400ms 类默认、CountUp 数字滚动 900→450ms;数值补
tabular-nums防滚动宽度跳动;待审卡 amber 文字提亮至amber-600/dark:amber-400达 AA 对比;近期文章行 hover 浮现 → 箭头。 - 灯箱滚轮行为:桌面端滚轮由「滚动关闭页面」改为缩放图片(2026 图片查看器惯例);关闭手势在移动端由滚动驱动改为竖直拖拽直接驱动,行程阈值保持 120px。
- Checkbox 组件统一:封装带描边勾画动画的
CHECKBOX_CLASS,迁移全项目调用方。 - 后台公共组件收敛:统一复用
FormInput/FormSelect/Popover等公共组件,消除内联重复样式与信息泄漏;components模块按可复用层级重组并加导航文档。
修复
- 数据库备份恢复可移植性与原子性:新备份不再写入数据库属主/ACL 元数据;恢复旧备份时安全移除 pg_dump 属主语句,并用单事务执行,目标环境缺少源库角色或任一 SQL 失败时不再留下半恢复数据库。
- 素材重建索引误删大图片 (#30):重建索引此前对大体积 WebP/JPEG 重新转码并误删,现保留原图、保留原始文件名;动图(GIF/WebP animation)保留动画绕过处理流水线。
- 灯箱操控动画:修复打开灯箱后首下缩放/旋转出现非均匀缩放回弹与起始帧跳变(强制 reflow 提交归一化基态矩阵后启动过渡);旋转改为绕照片中心原地进行;关闭飞行不再反向空转;打开时背景遮罩不再闪烁;加载失败时不再遗留不可见遮罩层。
- admin 卡片 hover 无过渡动画:
ADMIN_CARD_CLASS/ADMIN_TABLE_CLASS尾部的transition-colors在 Tailwind v4 编译产物中排在.transition-all之后,覆盖了组件追加的transition-all,导致 hover 位移/阴影瞬时跳变;改为裸transition。 - 仪表盘近期文章不可点击:行容器由
div+cursor-pointer改为Link,整行跳转/admin/preview/:slug只读预览,草稿亦可预览。 - migration 005 幂等:005 迁移的 comments 触发器改为幂等,重复执行不再报错。
- 限流日志与错误:无法获取客户端 IP 的 WARN 改为进程级 warn-once,避免日志刷屏;图片限流响应错误装箱修复。
- 构建链修复:空
RUSTC_WRAPPER规避 sccache 与 dx 的 rustc 包装链冲突;清理双目标构建 warning;发布构建前检查 brotli 可用性;make fix/ docker-fix 移除dx fmt。 - 友链管理:修复后台友链头像不显示、默认排序值缺失、素材库头像路径、删除确认改用 Tooltip、素材弹窗定位偏移等问题。
- 素材弹窗与卡片:弹窗关闭动画失效、提示框消失缺退出动画、媒体卡片圆角不统一等细节修复。
0.10.1
新增
- 草稿预览页:登录后可在
/admin/preview/:slug预览草稿文章,并配置专属骨架屏。 - 生产镜像版本 tag:生产 Docker 镜像支持按版本号打 tag。
改进
- 镜像构建加速:预缓存 wasm-bindgen-cli 与 cargo buildx cache mount,缩短镜像构建时间。
修复
- 预览页空白闪烁:修复预览页骨架屏结束后主内容区出现空白闪烁的问题。
- 骨架屏宽度坍缩:修复预览骨架屏在登录校验期间宽度坍缩的问题。
0.10.0
新增
- WGSL 代码高亮:新增 WGSL 语言语法高亮支持。
- 文章外链图片灯箱与混合图集:Lightbox 支持直接放大文章外链图片,并与站内图片无缝组合为混合图集。
- 素材管理与上传弹窗:素材管理页新增内嵌上传弹窗,支持开合/状态切换过渡动画与素材网格入场阶梯动画。
- 后台导航菜单分组:侧边栏引入「内容管理」与「工具」可折叠子菜单组,整合回收站、试运行、MCP 与系统设置页面。
- 自定义 Checkbox 与操作栏动画:统一后台 Checkbox 样式为主题色自定义方框,增加批量操作栏展开/收起过渡效果。
- Code Runner 就绪探测与优化:增加 Docker 启动期就绪探测与运行时错误分类;Go 语言代码块实现跨运行共享卷构建缓存提升执行效率;跨语言切换时自动重载编辑组件。
改进
- 性能与内存优化:sanitizer 热路径消除每元素 HashSet 分配,借用替代 clone 减少冗余分配。
- Dioxus 依赖升级:升级 Dioxus 核心框架依赖至 0.7.10。
修复
- Markdown 复杂表格与公式:修复 Markdown 表格内公式导致单元格错渲染为
<th>的问题,优化复杂表格样式。 - KaTeX · 符号渲染:修复
\text{}内·(U+00B7) 渲染为红字\cdotp的问题 (#13)。 - 切页评论与选择器残留:切换文章时强制重载评论组件防止历史评论残留 (#10);修复批量操作栏收起后残存间距与重建按钮 Tooltip 裁切问题。
- 素材粘帖上传与弹窗动画:修复原生监听器内 spawn 空 scope 栈 panic 以及上传弹窗关闭动画失效问题。
- 开发与容器环境:修复 Docker 开发容器下挂载 uploads 目录导致的素材图 404 及 pnpm 旧模块清理。
0.9.0
新增
- 桌面端悬浮目录(TOC):文章页新增少数派风格悬浮目录,支持滚动监听(scroll-spy)、悬浮展开与固定(pin)模式。
- 移动端导航动画:为移动端顶部导航菜单添加双向平滑展开/折叠与图标微动动画。
- 友链管理功能:新增后台友链 CRUD 管理、前台
/friends列表展示及 moka 高效缓存。 - 订阅 Feed 端点:新增 RSS 2.0 (
/feed.xml//rss.xml) 与 JSON Feed 1.1 (/feed.json) 订阅生成与输出端点。 - Changelog 结构化时间线:版本变更日志升级为结构化解析 + 时间线卡片 UI。
修复
- Changelog 导航高亮:修复 CHANGELOG 侧栏版本导航高亮未能精准跟随当前阅读位置的问题。
- 友链删除回调:修复后台友链删除确认框弹窗回调语法错误。
- CI 多架构构建:修复 GHCR 镜像构建脚本中
docker image inspect获取 Architecture 标识的问题。
0.8.3
新增
- Mermaid 流程图全屏放大浮层:复杂/宽流程图支持全屏点击放大查看,离散缩放支持 200ms 平滑过渡,交互与图片灯箱统一(支持 FLIP 飞行开关动画、滚动驱动关闭、拖拽平移、滚轮/捏合/双击缩放与 Esc/✕ 关闭)。
- CI GHCR 镜像归档:GitHub Actions 新增主应用多架构(amd64/arm64)Manifest 镜像及 6 个 Code Runner 沙箱镜像向 GHCR (
ghcr.io) 自动推送与归档。
修复
- Mermaid 异常容器清理:修复
mermaid.render解析失败时在document.body遗留临时#d${id}容器导致页面底部出现错误块的视觉问题。 - Mermaid 宽图放大居中偏位:修复
fitToScreen居中计算未乘以fitScale导致宽图放大浮层整体向左上偏位的问题。
改进
- Mermaid 预加载与渲染体验:在浏览器空闲期(
requestIdleCallback)自动预加载 mermaid bundle 模块,并在图像渲染过程中增加转圈角标提示。 - CI 构建流程优化:限定
build-amd64触发条件(仅主干分支、tag 及手动触发),增加镜像无 DB 启动冒烟测试与 Runner 目录变更检测,提升 CI 执行效率。 - 后台管理 UI 细节优化:优化后台管理页面 UI 布局结构与风格样式。
0.8.2
安全
- session_generation 自动失效旧会话:
users.session_generation版本化机制此前只有读侧(get_user_by_token命中缓存后回查版本号,不匹配即逐出),但写侧无任何自动 bump——降级/封禁用户后已签发会话仍长期有效。新增 BEFORE UPDATE 触发器(migration 018):仅在role真正变化(IS DISTINCT FROM)时 bump 世代号,其它列更新不误伤,触发器内修改NEW不递归。端到端语义由既有读侧逐出逻辑承接。
修复
- 评论「审核中」徽章永久残留(issue #9 回归):评论审核通过后前端轮询从一次性
use_future改为use_resource(依赖 pending 列表自动重启),并加去重use_effect兜底,根治 pending 占位项残留。 - mermaid 多行节点标签 descender 裁切:
foreignObject默认overflow:hidden在部分浏览器 sub-pixel 渲染下裁切多行节点下沉笔画(g/p/y)。注入 SVGoverflow="visible"presentation attribute 修复(CSSoverflow对 foreignObject 无效,须写属性)。 - 全文搜索 trigram 索引:恢复
posts.search_text的 trigram GIN 索引(migration 014 以错误理由删除——gin_trgm_ops本就是为%pat%包含匹配设计的;migration 019 按 004 原定义重建)。search_posts与 MCPsearch_published的 ILIKE 不再全表扫。 - 后台表格列换行:日期/状态/操作列加固定宽度与
whitespace-nowrap,避免窄屏换行。 - 线上容器无法创建备份:scratch 镜像缺
backups/目录且属主为 root、进程以 nobody 运行不可写。修复.dockerignore放行backups/.gitkeep、Dockerfile 预建目录;备份写入失败改为携带真实io::Error。 - rustdoc 线上 404:镜像内生成 rustdoc 修复
/doc路由 404;订正 rustdoc intra-doc 断链与无效 HTML 标签。 - Docker 构建:cargo-chef tarball 解压去子目录层;docker-tests 缺少 alpine 镜像时跳过而非 panic。
- release 后 changelog 测试失败:修复发布后遗留的测试断言失败。
改进
- CI 迁移到 GitHub Actions:从 Gitea Actions 迁移到 GitHub Actions,新增 SSH 部署到 xun;
test+build-amd64改为每次推送触发,build-arm64/release/deploy改为仅 tag 推送(v*)或workflow_dispatch触发。 - arm64 原生构建 + GitHub Release 自动发布:新增 arm64 原生构建(
ubuntu-24.04-armrunner),GitHub Release 自动发布三件产物(amd64 镜像 / arm64 镜像 / x86_64 musl 静态二进制 + public 资源)。 - CI 缓存优化:cargo-chef 依赖分层 + BuildKit GHA 层缓存;升级所有 actions 到 node24 兼容版本。
- lint 增强:Makefile
lint目标增加cargo fmt -- --check;全仓库 cargo fmt 统一格式。
内部
- 订正
.cargo/config.toml过时的 cross build 叙事;修正 CHANGELOG 代码围栏 Markdown 转义。
0.8.1
新增
- MCP
update_post部分更新:update_post改为 PATCH 语义,UpdatePostParams所有可改字段(title / content_md / summary / slug / tags / status / cover_image)改为Option,仅post_id必填;服务端按提供的字段动态构建UPDATE SET子句,未提供content_md时跳过 Markdown 重新渲染,省去spawn_blocking开销。语义要点:summary随正文联动(正文变且未给则自动提取);slug仅显式提供才改动;tags为None不改、Some替换(空列表清空);cover_image为None不改、空串清空、URL 设置;status变化时首发自动填published_at。旧的全量调用(同时传 title+content_md)行为不变,向后兼容。
0.8.0
新增
- TOML 语法高亮:
toml代码块此前回退为纯文本(syntect 默认精选集不含 TOML);现已引入官方 sublimehq TOML v2 语法,支持日期时间、数组表、内联表与多行字符串。 - Docker 开发环境:新增
Dockerfile.dev+docker-compose.dev.yml,内置 dx 0.7.9、tailwindcss v4、Node 22/pnpm 与 wasm32 target;源码 bind mount 实现热重载,cargo/pnpm 缓存跨重启持久化,直连宿主原生 PostgreSQL。新增make docker-dev/docker-dev-down/docker-dev-shell便利 target。 - x86_64 镜像零 QEMU 交叉编译:改用
Dockerfile.cross三阶段构建(Trixie 编前端 + Alpine/zig 交叉编 server + scratch 合并产物),arm64 Mac 上不再经 QEMU/Rosetta 翻译,告别 cross 工具链容器在 Rosetta 下的 SIGSEGV 崩溃。
改进
- MCP 媒体上传改为带外传输,彻底移除 base64:
upload_media工具改为接收 URL,由服务端经 SSRF 防护抓取(强制 https、DNS 解析即锁 IP 杜绝 rebinding、禁重定向、流式体积上限、超时);新增POST /api/mcp/uploadbearer multipart 端点,供 host/shell 直接 POST 二进制。二进制不再进 JSON-RPC,不再受 4MiB 请求体上限(原 base64 路径实际仅约 2.8MiB 原始图)约束。新增 server-only 依赖reqwest(rustls-tls,musl 静态链接友好),移除base64依赖。
修复
- 交叉编译部署后登录 405:Dioxus 0.7.9 的 server-fn URL 末尾去冲突后缀为
xxh64(CARGO_MANIFEST_DIR + module_path!, 0);host 交叉编译与容器内编译的CARGO_MANIFEST_DIR不同,导致前后端算出不同 URL 后缀,POST 落入 SSR 兜底 GET 路由返回 405。改由.cargo/config.toml固定SERVER_FN_OVERRIDE_KEY,两次编译读到同一哈希 key。 - Dockerfile 漏拷 workspace 包:两个 Dockerfile 的 pnpm manifest COPY 此前只拷了 4/7 个包,补齐
shared/xterm-terminal/mermaid-renderer。
0.7.0
新增
- MCP 服务器:博客现在是一个 Model Context Protocol 服务器(
POST /mcp,Streamable HTTP,无状态),管理员的 AI 客户端(Claude Code / Cursor / Cline)可经 bearer token 连接,把已发布文章当知识库检索,并执行几乎所有后台操作。- 认证:管理员在
/admin/mcp签发令牌,三档作用域(read / write / admin),可选有效期(1/7/30/90 天 / 永不过期)。令牌明文经 AES-GCM-256 静态加密存储(可重查),SHA-256 哈希做每请求查找。 - 知识库(read):
search_posts/get_post/list_tags工具 + 已发布文章作为可枚举的 MCP Resources(post://{slug},游标分页)。 - 写操作(write):文章 CRUD(含草稿)、评论审核、标签管理、媒体上传(base64 → WebP 转码去重)。
- 管理(admin):站点设置读写、代码运行器(沙箱执行)。
- 加固:token-keyed 限流(默认 10/s burst 30,超限 429)、
last_used_at节流刷新、鉴权审计日志、Origin→403(spec 强制,rmcp 内置)、协议版本头校验、4MiB 请求体上限。 - 配置生成:后台一键复制 4 种客户端配置(Claude Code / Cursor / Cline / 通用 JSON + CLI)。
- 传输用官方
rmcpcrate(=3.0.0-beta.3,3.x 才有 Origin 校验等 spec 强制项)挂载于 axum。新增依赖rmcp、aes-gcm、base64(均 server-only)。 - 新增环境变量
MCP_TOKEN_ENC_KEY(hex 编码 32 字节 AES-256 密钥,openssl rand -hex 32生成)、RATE_LIMIT_MCP_PER_SEC/RATE_LIMIT_MCP_BURST。
- 认证:管理员在
- 素材管理(媒体库):新增
media_assets注册表数据层与/admin/assets管理页,把上传的图片当作一等公民管理。- 只读列表页:素材网格 + 引用/未引用(孤儿)筛选;引用徽标展示被哪些文章引用。
- 删除保护、孤儿清理与 alt 编辑:被引用素材不可删除;可一键清理无引用的孤儿素材;就地编辑 alt 文本。
- 全量索引重建:扫描
posts.content_html重建每张图片的引用关系(批量 500)。 - 封面「从素材库选择」联动:写文章页封面图改为从媒体库挑选,封面与素材库打通。
- 灯箱预览:素材网格接入 Lightbox,支持图集切换浏览。
- 搜索与防抖:素材页搜索框 300ms 防抖。
- 多选与批量删除。
- 上传去重:上传图片按内容 SHA-256 计算指纹,重复上传直接复用已登记素材,不再产生冗余文件。
- Pagination 页码跳转:素材列表分页支持页码直跳(
Pagination组件新增跳转能力)。
- 关于页重设计:关于页重制为「世界树与遗忘」主题叙事,新增年轮式链接区。
/changelog页面:新增更新日志页,内嵌渲染CHANGELOG.md,并在年轮区接入入口。- 后台仪表盘动画:仪表盘分块进场动画 + 数字滚动,节奏可调。
FormSelect主题化下拉组件:封装自定义主题化下拉弹层,替代原生<select>(OS 弹窗无法跟随主题);全项目原生<select>统一替换为FormSelect。- 后台文章搜索:文章列表支持按标题搜索。
- MCP 配置生成 UI:客户端配置代码块加语法高亮、复制按钮就地反馈;令牌列表与配置生成 loading 替换为骨架屏;新增 OpenCode 客户端配置片段。
改进
- 重构系列 R2–R6:抽取
tools/common.rs消除 MCP helper 四重拷贝(R2);放宽 posts helpers 可见性并删除 MCP 内的平行拷贝(R3);抽取render_post_fields消除文章渲染 + 字数/阅读时间度量的重复(R4);抽取fetch_post_tags消除 9+ 处标签查询重复(R5);抽取invalidate_for_post_write统一写后缓存失效序列(R6)。 - utils 常量集中:集中
hash_token/EMAIL_REGEX/MAX_FILE_SIZE的重复定义;集中MIGRATE_STARTUP_TIMEOUT_SECS解析;提取formatted_date公共实现;统一 LIKE 模式转义(consts)。 - 输入框统一
FormInput:后台文章搜索框、SQL 控制台输入框等统一改用FormInput公共组件。 - 代码运行器执行层:抽取
spawn_exec_task消除start_exec/stream重复(M10)。
修复
- KaTeX
\pu转译:修复\pu预转译的 off-by-one 与 UTF-8 破坏(C1+C2)。 - 代码运行器:流式执行超限时回收挂起的容器,避免泄漏(C3);移除
source_prop_signal的渲染纯净性违规(C4)。 - 图片缓存清理任务:防溢出/下溢 panic(C5)。
- MCP 工具归属与缓存:trash/delete 补归属校验 +
publish_post标签缓存失效(M1+M6);标签文章数计数 + 批量删除 SSR 失效(M2+M5)。 - 备份/恢复:
pg_dump/psql移入spawn_blocking并按行读取,避免阻塞异步线程(M3)。 - 评论:评论 markdown 渲染移入
spawn_blocking(M4)。 - 标签页缓存:移除未使用且永不失效的
PostsByTagPage缓存键(M7)。 - 限流:键控限流器定期 GC + XFF 伪造风险文档化(M8),GC 任务派生守卫运行时可用性。
- 数据导出:不再向 HTTP 响应泄露原始 DB 错误(M9)。
- SQL 控制台:读路径追加
LIMIT避免全表物化(M11);SHOW只读分类修正。 - 后台文章列表:渲染拉取失败的错误态(M12)。
- 素材管理:uuid 参数序列化失败导致上传 500;
SUM(size_bytes)显式转 bigint 修复列表 500;引用徽标加z-10修复被 blur-img 遮盖;灯箱图集切换不重算几何导致图片压扁;删除返回「素材不存在」时刷新网格自愈过期数据;工具栏右侧按钮沉入FilterTabs区域紧贴横幅;操作横幅上下间距不对称(40/8 → 24/24)。 - MCP:reveal/revoke 令牌时将字符串 id 解析为
Uuid;FormSelect面板水平居中修复双倍位移;客户端配置格式修正(Claude Code / Cursor / Cline,联网核实 2026);配置生成use_effect死循环;开发期放行0.0.0.0Host 让 dx 代理可用、Host 白名单加入APP_BASE_URL域名。 - 文档:修正文档漂移(AGENTS.md / DEPLOYMENT / .env.example 等)。
移除
- 死代码清理 D1–D12:删除死模块
resources.rs、死User结构体、未用参数、mhchem 冗余分支、死导出与文档化死分支、未使用且永不失效的缓存键等;收窄模块级 allow。 - 迁移后补回/移除测试中失效的
sha2::Digest导入。
0.6.2
修复
- web-only 构建失败:
sleep_ms原用#[cfg(not(target_arch = "wasm32"))]guard tokio 分支,但 tokio 是 server-only optional 依赖。该 guard 在「非 wasm32 主机 + 仅 web feature」组合下误激活导致编译失败(长期被 dev-dependencies 中的 tokio 掩盖,只有排除 dev-deps 的生产构建才暴露)。修复为#[cfg(all(feature = "server", not(target_arch = "wasm32")))],符合 dual-target gating 规范。 - 404 页「返回首页」卡死:文章详情页对不存在的 slug 抛出 404 错误后,Dioxus
ErrorBoundary捕获错误渲染 fallback,但点击「返回首页」仅更新 URL 不切换页面(ErrorBoundary需显式clear_errors()才能恢复渲染 children)。修复:返回首页改用 button,onclick 内先clear_errors()再导航。
0.6.1
改进
- 消除非测试代码中的裸
unwrap():在panic = "abort"全局下,任何裸unwrap()都会直接崩溃整个进程且无法恢复。将所有非测试代码中的unwrap()改写为带不变量说明的expect()(消息需解释为何不可能失败),并在 AGENTS.md 规范 #16 中固化该约束。
修复
- mhchem 转译器三处 panic 修复:修复
panic = "abort"下化学公式转译器的三处崩溃:". __* "正则转录错误、find_observe_end逐字节扫描多字节字符越界、以及re!宏编译失败时未降级为不匹配导致直接 panic。前两处为输入触发的运行时 panic,第三处补上缺失的防御性边界。 - Docker 构建缺
patches/目录:构建镜像时未复制patches/目录导致pnpm install报 ENOENT,补充复制修复。
0.6.0
新增
- 编辑器 mermaid 实时预览:Tiptap 代码块在编辑器内实时渲染 mermaid 流程图,所见即所得。
- 编辑器脚注所见即所得:Tiptap 富文本编辑器内脚注直接可见,不再依赖 Markdown 源码。
- mhchem 化学公式:移植 mhchem 转译器,支持
\ce/\pu化学方程式语法转 LaTeX 渲染。 - KaTeX 物理学宏表:注册 16 个物理学宏(如
\d、\od、\textsubscript等),适配物理学公式写作习惯。 - 新建文章默认直接发布:
/admin/write新建文章的默认发布状态改为直接发布。
改进
- mermaid 主题变量下沉:将 Catppuccin 主题变量从 tiptap-editor 下沉到
@yggdrasil/shared共享包,统一管理。 - 中间件抽取:将
ssr_generation/version_headers中间件从main.rs抽出至src/middleware.rs。
修复
- 窄表格边框裁切:修复窄表格在
table-wrap容器内边框被裁切的问题。 - 移动端表格滚动:修复移动端表格无法横向滚动的问题。
- 空工具栏顶栏:隐藏无语言标识代码块的空工具栏顶栏。
- KaTeX sanitizer 拦截:允许 KaTeX 渲染所需的
svg、path标签及绘图属性通过 sanitizer。 - tiptap-markdown 过度转义:修复 tiptap-markdown 过度转义导致内容显示损坏。
- 脚注序列化转义失效:修复 tiptap 序列化转义脚注语法
[^id]→\[^id\]导致脚注失效。 - SQL 控制台写后缓存失效:SQL 控制台执行写操作后全量失效相关缓存。
0.5.0
新增
- 文章数学公式 SSR 渲染(KaTeX):引入
katex-rs在服务端把$...$/$$...$$TeX 渲染成视觉层 HTML span(OutputFormat::Html,不含 MathML,XSS 面最小;throw_on_error=false坏公式渲染成红色错误而非中断);自托管 KaTeX CSS + woff2 字体到public/katex/(make katex-css从 npmkatexdist 拷贝)。 - 评论数学公式渲染:评论路径同步开启
ENABLE_MATH,span 白名单加style保留 KaTeX 内联定位样式。 - 编辑器数学公式节点:Tiptap 数学公式节点带 KaTeX 预览,根治编辑器序列化破坏 LaTeX 的问题。
- mermaid 流程图懒加载渲染:文章页
language-mermaid代码块经 IntersectionObserver 视口可见时动态import('/mermaid/mermaid.js')(独立 IIFE bundle,~3.4MB / gzip ~900KB,非全局注入),mermaid.render产 SVG 注入;主题经__initMermaid传入,securityLevel: 'strict',幂等守卫防重复渲染;渲染失败保留源码并加.mermaid-errorclass。 - 流程图配色对齐 Catppuccin:mermaid 配色对齐 Catppuccin 主题,容器美化。
- 流程图主题切换动画:流程图主题切换跟随 View Transitions 圆形扩散动画,主题切换时重渲染已渲染的流程图。
- bun 代码运行器:新增
yggdrasil-runner-bun沙箱镜像(官方bun.sh/install脚本 + musl 变体 +libstdc++/libgccC++ 运行时);admin 代码试运行沙箱加 bun 语言按钮;CodeMirror 加 TypeScript 模式;语言别名归一化(ts/typescript→bun,在parse_fence_info统一,LANGUAGES.get只见规范化 key)。 - 文章页脚注完整支持:语义化 + back-link + 样式。
- Vue SFC 语法高亮:文章页代码块支持 Vue SFC 语法高亮。
- 搜索入口改为图标按钮:header 搜索入口从文字改为图标按钮。
- 正文折叠块卡片化:
<details>折叠块卡片化,自绘 chevron + hover/focus 态。 - task-list checkbox 自绘:文章页 task-list checkbox 改用
appearance:none自绘圆角方框。 - 代码块字号调整:文章页代码块字号从 13.6px 调整为 16px。
- 响应头暴露版本信息:server 通过
Server/X-Yggdrasil-Version/X-Yggdrasil-Git响应头主动暴露版本与 git 描述信息(EXPOSE_VERSION_HEADERS可关)。 - Docker multi-arch 构建目标:
make docker-amd64与make docker-apple构建 x86_64 镜像。 - 服务器端口占用优雅退出:端口被占用时优雅退出而非 panic。
- 压缩算法默认 off:
COMPRESSION_ALGORITHMS中间件默认值改为 off。
改进
- mimalloc 全局分配器:用 mimalloc 替换系统全局分配器(
#[global_allocator],双 cfg 门控:server feature + 非 wasm32;musl 静态链接友好)。 - 性能优化系列:
escape_html链式 5 次 replace 改单遍扫描;slugify单遍状态机重写(分配 4→1);Markdown 渲染消除双解析 +format!改write!直写;upload 消除data.to_vec()多次全文件深拷贝;cache_key单次拼接 +detect_format零分配后缀匹配;posts list/search 零 capacity Vec 改 collect 预分配 + helpers retain。 - 重构系列:admin
/admin/posts与/admin/posts/trash合并为单路由 + tab 切换;Pagination支持可选on_prev/on_next回调;抽取@yggdrasil/shared内部源共享包消除跨 IIFE 库的类型/常量重复;抽main.rs中间件到src/middleware.rs;为Response类型添加构造器消除 51 处样板;抽invalidate_post_metadata()/upload_error()等消除样板;统一 WASM sleep 到utils::time::sleep_ms;删除死代码(delayed_loading.rs/ui.rs EmptyState/CommentActions/未用 re-export);拆分system.rs为system/目录(按 tab 分文件);图片处理合并维度读取函数共享image_reader_limits。 - 依赖升级:TypeScript 升级至 7.0.2(Go 原生编译器)。
修复
- SSR 缓存失效根治:文章写入后物理删除 SSR 磁盘缓存目录,根治「重建后内容不更新」(Dioxus 0.7 增量渲染器只暴露 TTL 失效手段,通过删文件绕过限制);build 前清除
static/SSR 缓存目录。 - Docker 构建/部署:Docker 构建透传 git 信息修复
x-yggdrasil-git恒为 unknown;预装 binaryen 避免 dx 运行时下载 wasm-opt 失败;补齐 Dockerfile 缺失的 katex-css 与 restore-webp 步骤;升级 builder 至 trixie 满足 dx 对 GLIBC_2.39 的需求;用 tmpfsmode=1777替换 uid/gid 选项兼容 Podman;GitHub Releases 下载最终改用直连(移除 gh-proxy)。 - 线上代码高亮缺失:编译期内嵌自定义语法,修复线上 Docker 镜像代码高亮缺失(原先运行时加载语法文件在打包镜像中找不到)。
- mermaid 渲染:改用 script 标签加载 IIFE bundle 修正全局变量取值;修复 tsc 类型错误;主题切换时重渲染已渲染的流程图。
- 文章锚点导航:
scrollToHash增加一次性守卫,切主题不再跳回 URL hash;增加 ResizeObserver 布局稳定期,修正 mermaid 异步渲染导致的锚点落点偏移。 - WASM 双端编译:hooks 模块移出 server gate 双端可见(原先 WASM 编译失败)。
- 评论代码块转义:统一
escape_html,修复代码块单引号未转义。 - Docker daemon 容错:Docker daemon 不可用/断连时不再 panic(集成测试在无 daemon 环境优雅跳过)。
- 后台布局:重建结果消息改绝对定位,避免撑高容器顶起按钮。
- 图片 cfg 门控:为
ImageFmt别名补上#[cfg(feature = "server")]门控。 - clippy/lint:修复 rust-1.97 clippy
useless_borrows_in_formatting告警、Biome 告警。 - 安全测试:补齐安全关键路径的单元测试盲区。
内部
- skills 体系:新增
optimizing-rust-performance与rust-advanced-performance性能优化技能;清理已卸载的第三方 skills 及 lock 注册;deploy-to-linux添加手动部署模式。 - 部署脚本:新增 xun 服务器全量部署脚本。
- 文档:AGENTS.md 补充别名归一化与 bun 镜像说明、数学公式与流程图架构说明、xterm-terminal/shared 库说明;补全
.env.example缺失的 5 个环境变量。
0.4.0
新增
- 代码运行器(Code Runner):读者可在文章页直接运行
lang runnable ``` 代码块,在隔离的 Docker 容器中执行,支持 Python / Node.js / Go / Rust 四种语言;admin 侧/admin/runner试验沙箱页支持任意代码试跑(跳过速率限制)。三层架构:src/infra/docker.rs(bollard 执行层,只读 rootfs + tmpfs + 资源/能力限制 +ContainerGuardDrop 强制清理)、src/api/code_runner/(任务注册表、语言注册表、双速率限制 + 白名单 + 大小检查)、Markdown 渲染层(PostContent拆分Html/Runnable片段,每块渲染为真实<CodeRunner>vdom 元素)。所有CODE_RUNNER_*环境变量可调,支持 per-IP 速率与每日上限。 - 流式代码执行(SSE + xterm.js):CodeRunner 切换为 SSE + xterm.js 流式输出方案。新增
xterm-terminalIIFE 子工程(xterm.js 6.0)、xterm_bridge.rswasm-bindgen 绑定、/api/exec/streamSSE 端点、Docker 执行层流式路径(wait 与 log 读取并发);支持无缓冲 stdout(python -u)、SSE done 事件回传duration_ms、运行前隐藏输出区 + skeleton 占位。 /admin/system管理后台:全新管理区,5 个 tab —— 数据库状态(表统计/活跃连接/迁移版本)、服务器状态(sysinfo 主机指标 + moka 缓存命中率轮询)、SQL 控制台(全读写,4 道护栏:sqlparser AST 门 + WHERE 缺失拒绝 + 查询超时 + 前端确认;单元格类型化渲染 NULL/布尔/数字、表头 sticky、行截断展开)、数据导出(Axum 流式 SQL/CSV)、备份恢复(pg_dump优先 + COPY 回退、DashMap 任务进度表 + 轮询、备份文件签名校验 + 路径白名单)。- UI 重新设计(工业极简 + Catppuccin):全站配色迁移到 Catppuccin(Latte/Mocha),移除 Rust 中硬编码颜色,统一语义色阶;后台重设计为现代极简侧边栏布局(写文章页改为左右两栏、编辑器自适应高度);圆角 token 化为三档梯度(32/16/8)并统一所有组件;Markdown 表格重设计 + 表格单元格圆角防背景溢出;全局路由切换平滑挂载动画 + View Transitions 圆形展开主题切换动画;编辑器背景图(线条小狗)有内容时自动调淡透明度。
- 编辑器可运行代码块 NodeView:CodeBlock 改用
CodeBlockLowlight+ Catppuccin 高亮配色;新增 CodeBlockNodeView(语言标签 + 运行按钮 + 结果区),点语言标签可编辑语言与配置;斜杠菜单新增「可运行代码块」条目 + 模态框配置 runnable fence info;make_run_code_closure桥接编辑器内运行代码。 - 编辑器任务列表手动输入:支持
- [ ]逐字符输入创建任务列表(appendTransaction,非 InputRule 全量替换);前台与编辑器 checkbox 垂直中线对齐。 - SQL 控制台 Ctrl+Enter:
/admin/systemSQL 控制台接通 Ctrl/Cmd+Enter 运行快捷键。 - CodeMirror Vim 模式:admin CodeRunner 沙箱编辑器支持 Vim 模式开关,默认开启;CodeMirror 编辑器高度自适应与滚动限制。
- 文章重建内容按钮:文章列表操作列新增「重建内容」按钮,重建支持并发 loading(spinner 覆盖文字)。
- 中文 slug 自动转拼音:中文标题自动转拼音生成 URL slug。
- FreeBSD x86_64 交叉编译:
make build-freebsd+make freebsd-sysroot,clang + lld + sysroot。 - 构建信息注入:启动时打印 git/rustc/构建时间信息。
- 404 页面提交 HTTP 404 状态码(SSR 层);
ErrorBoundary包裹公开路由,文章详情页 404 等错误上抛至ErrorLayout。 - SSR 层 admin 认证守卫:未登录访问 admin 直接在 SSR 跳转登录页,避免闪烁。
- 登录表单回车提交;网站 favicon;评论背景图自动调淡。
改进
- pnpm workspace 重构:JS 子项目从 npm 迁移到 pnpm workspace,根工作区在
libs/,单一libs/pnpm-lock.yaml+ 共享libs/tsconfig.base.json;引入 Biome v2.5 monorepo 配置并全量格式化;Makefile 整合lint/fix/test目标。 - 消除
js_sys::eval:DOM 互操作全面从字符串求值迁移到 wasm-bindgen 绑定层(tiptap_bridge、codemirror_bridge、xterm_bridge),清理 wasm32 target 残留 clippy lint。 - 通用 hooks 抽取:新增
use_paginated(分页加载)、use_event_listener(通用事件监听,解决use_hook+use_effect+use_drop资源所有权陷阱)。 - SQL 控制台组件化:
SqlConsoleTab改用独立SqlResultTable组件。 - 按钮 token 化:新增
BTN_PRIMARY/BTN_OUTLINE等按钮令牌与LoadingButton组件,消除样式散落。 - 骨架屏统一延迟:统一骨架屏延迟机制,200ms 内加载完成不显示骨架,避免快网络闪烁。
- 后台菜单边距收紧:后台所有页面左右边距统一(
px-10 → px-6),写文章页移除页头条。 - 回收站合并入文章列表:
/admin/trash合并为/admin/posts的 URL 驱动 tab,PostStats新增回收站计数 badge。 - 依赖升级:cargo 与 pnpm 依赖全量升级到最新版本;新增
tokio-stream(SSE)、bollard(Docker)。 - Runner 配置:
CODE_RUNNER_LANGUAGES默认开放全部语言;admin runner 页展示 Go/Rust。 - Tooltip 组件抽取:文章列表操作按钮用
Tooltip包裹。
修复
- 反应式 hook 不追踪普通 prop 的陷阱:修复同一路由变体间导航(如
/post/a → /post/b)后文章正文/列表/标签不更新的严重 bug —— 根因是use_server_future/use_memo/use_resource不追踪非 signal 依赖。改为在闭包内读router.current()signal 或直接内联计算。同理修复评论区CommentSection依赖追踪与 SSR hydration 不匹配。 - 主题切换动画:修复 VT 动画期间 CodeMirror/xterm 主题同步(避免圆形展开动画期间直接跳变)、清理 VT 期间的
animate-page-entertransform(修复代码块被覆盖)、跟随系统模式系统偏好变化时同步 dark class(改回瞬切避免动画冲突)、prefers-reduced-motion降级。 - 备份恢复假成功:修复备份恢复实际不写入数据却返回成功(
psql未加ON_ERROR_STOP=1导致语句全错仍 exit 0);修复备份/恢复任务轮询永不启动导致按钮卡在 loading。 - 可运行代码块容器清理:修复容器清理失败静默泄漏(重试 + 日志告警)、编译型语言需
/tmptmpfs 执行权、去掉nproculimit 修复容器启动 EAGAIN。 - 文章锚点导航:修复直接访问
#hash时标题被 sticky header 遮住、hydration 后点击标题锚点触发整页刷新、hash 锚点跳转失效。 - Tiptap 编辑器:修复斜杠命令创建可运行代码块时模态框被立即关闭、斜杠命令文本残留进新节点(
/code带入 codeBlock)、代码块内 Backspace 删整块(ignoreMutation误忽略 contentDOM 编辑)、Backspace 在 lowlight decoration 重建后失效、runnable 块classList.add抛InvalidCharacterError、语言下拉展开时 Enter 误触发插入、空项 Enter 不退出列表(畸形文档根因)、TaskInputRule 升级后光标被甩到下一行、升级后折叠行被撑高 + 折叠图标垂直不居中、CodeMirror 折叠图标垂直不居中。 - CodeMirror 编辑器:修复编辑回退反馈循环(editing reversion loop)、编辑器塌缩导致上下背景割裂(
height:100%失效)、行号区背景与代码区割裂、未撑满容器、SQL 编辑器 gutter 与 content 背景割裂。 - 后台骨架屏:修复后台骨架屏不可见、骨架屏→认证→正常页面布局闪烁、写文章页骨架屏高度不撑满(多次迭代)。
- 路由与分页:修复 SQL 控制台 Ctrl+Enter 触发 panic(无 dioxus scope)、上下篇切换后可运行代码块消失。
- UI 细节:修复 markdown 表格水平填充渲染、admin 布局滚动条位置、写文章页滚动性、
--font-sans补齐 CJK sans 字体栈、暗色 type 色值。 - 数据库错误日志:展开迁移错误的 source chain 全链路。
- 其他构建、CI、Docker 镜像(multi-arch buildx、HTTPS Debian 镜像绕过 HTTP 透明拦截、apk 清华镜像)、格式化与测试修复。
安全
- SQL 控制台护栏加固:
DROP DATABASE/DROP SCHEMA/CREATE DATABASE绝对禁止(字符串预检 + AST 门);DROP/TRUNCATE/ALTER需确认;UPDATE/DELETE无WHERE拒绝;多语句默认禁用;结果上限 500 行。 - 备份文件校验:备份文件携带签名头,restore 拒绝非系统文件;
backup_path路径穿越漏洞修复(补单测);pg_dump --clean --if-exists使 restore 幂等(drop+recreate 而非 relation 已存在报错)。 - 备份恢复补单测:
backup_path路径穿越漏洞补表驱动单测。
内部
- 新子工程
xterm-terminal:xterm.js 6.0 IIFE 库 + smoke 测试。 - 新子工程
codemirror-editor:CodeMirror 编辑器 + Rust bridge,Ctrl/Cmd+Enter 运行快捷键。 - Docker runner 镜像:
docker/build-runners.sh构建 base → python → node → go → rust 链;Go 镜像重定向GOCACHE/GOPATH到/tmp,Rust 镜像封装run-rust.sh两步编译+运行 wrapper。 - 新增 Rust 单测:SQL 控制台护栏表驱动单测、备份恢复单测、markdown
wrap_images_with_blur解耦文件系统依赖。 - codemirror-editor smoke 测试、
xterm-terminalsmoke 测试。 - AGENTS.md 文档扩充:Code Runner 架构说明、双 target 验证陷阱、custom hook 资源所有权陷阱、反应式 hook 不追踪普通 prop 的踩坑记录、Tiptap 交互 bug Playwright 调试方法论。
- matt-pocock engineering skills 引入。
0.3.0
新增
- 评论系统:完整的访客评论功能,包含昵称/邮箱/URL、嵌套回复、管理后台审核(通过/标垃圾/删除)、待审评论 localStorage 持久化与 pending 状态轮询、相对时间显示。
- 文章回收站:删除文章进入回收站,支持恢复、彻底删除、批量操作与清空;新增
/admin/trash管理页面、settings键值表与可配置的自动清理后台任务(保留天数、上限数量)。 - 主题切换动画:基于 View Transitions API 的圆形展开动画(纯 CSS 实现,从点击点扩散),支持
prefers-reduced-motion降级。 - 编辑器图片上传协调器:Tiptap 自定义 Image 扩展,带上传中占位图(模糊 + spinner + 错误态)、失败重试、保存拦截、上传计数;支持 slash 命令、粘贴、拖拽。
- 封面图上传:文章编辑器支持封面图上传(拖拽/点击/粘贴),封面区空态矮横条 + 可滚动主体布局。
- Blur-up 渐进式图片加载:Markdown 图片包裹双层结构(低清模糊 + 高清淡入),基于图片尺寸缓存的宽高比占位。
- Lightbox 子工程:
libs/lightbox/TypeScript 项目,图库导航(淡入、箭头、键盘)、原点感知缩放、滚动关闭、防止背景滚动与闪烁。 - yggdrasil-core 子工程:核心 JS bundle 子工程,迁移
post-content复制按钮与主题切换逻辑,删除public/js/。 - 新增语法高亮:TypeScript、JSX、TSX、Zig;补全 Swift 高亮;大小写不敏感的语法名匹配。
- Markdown 源码视图切换:编辑器可在富文本与源码视图间切换,按滚动比例同步位置。
- 健康检查端点:新增
healthz与readyz。 - 内嵌数据库迁移:启动时自动运行迁移(advisory lock + 逐迁移事务),迁移失败以友好退出 + 可配置重试窗口(
MIGRATE_STARTUP_TIMEOUT_SECS)替代 panic;启动期自动创建目标数据库。 - 会话安全:Session token 以 SHA-256 哈希存储(不再存明文);可配置的单用户 session 数量上限(行锁串行化);角色/状态变更通过 generation 失效所有会话。
- CSRF 防护:基于 Origin 的写接口 CSRF 检查,
APP_BASE_URL未设置时启动告警。 - Cookie 安全:
COOKIE_SECURE环境变量控制 session cookie 的 Secure 标志。 - 真实客户端 IP:从
X-Forwarded-For按TRUSTED_PROXY_COUNT提取真实 IP;未知 IP 时使用宽松限流桶。 - 图片响应缓存:
Cache-Control与ETag头,支持If-None-Match304(RFC 7232 合规);图片内存缓存改用bytes::Bytes,新增按文件年龄与总大小淘汰的磁盘缓存定时清理任务。 - 图片上限可配置:
MAX_IMAGE_DIMENSION、MAX_IMAGE_PIXELS、WEBP_QUALITY、WEBP_METHOD等环境变量,默认值翻倍;统一各格式大小上限。 posts表字数与阅读时间:新增word_count/reading_time列并在写入时维护;列表/搜索接口不再返回正文,读取预存的字数与阅读时间。PostListItem轻量 DTO:列表/标签/搜索接口不再返回完整正文,显著降低缓存与序列化体积。- 会话与搜索缓存:基于 moka 的会话内存缓存(缓存对象不含密码哈希);搜索结果短 TTL 缓存(10 秒,key 规范化)。
- 空状态与配图:首页、归档、标签、搜索、后台文章/评论/回收站均接入
EmptyState组件与装饰性配图(线条小狗等),配图圆角 + 暗色模式降亮。 - UI 重新设计:温暖色调 + 鼠尾草绿主色,统一
paper-*主题变量;后台对齐前台主题变量,新增次要按钮冷调玫瑰色。 - 后台交互改进:文章管理分页、重建内容按钮(带 tooltip)、重建缓存栏;评论状态筛选
FilterTabs组件带滑动指示动画;回收站自动清理面板带滑入动画。 - HTTP 压缩:默认启用所有压缩算法,可通过
COMPRESSION_ALGORITHMS配置;公共页面与静态资源Cache-Control。 - Dockerfile:静态 musl 镜像构建(release 二进制 strip 符号)。
- Gitea Actions CI:CI 工作流。
改进
- 写路径缓存失效从「全量清空」改为「精确到 slug / tag / 列表页」,并在读取 slug/tag 元数据时使用事务 +
FOR UPDATE避免并发竞态;批量恢复、清空、重建等路径均采用精确失效。 get_post_stats将 3 次独立COUNT(*)合并为单次条件聚合查询。- 图片解码、缩放、编码逻辑通过
tokio::task::spawn_blocking移至阻塞线程池;Argon2 hash/verify、Markdown 渲染、GIF/WebP 原始校验同样 offload 到阻塞线程池。 - 为非图片路由启用
CompressionLayer与TimeoutLayer,/uploads/*图片路由跳过压缩与全局超时。 - 连接池回收方法从
Verified改为Fast;重试从固定 2s 改为指数退避 + 抖动;新增statement_timeout(STATEMENT_TIMEOUT_SECS)。 - 为
deadpool-postgres显式指定 Tokio1 runtime;删除无效的 trgm GIN 索引。 - Tiptap 编辑器升级到 Vite 8 / Vitest 4 / TypeScript 6 / Tiptap 3.27(Rolldown),并从
js_sys::eval迁移到 wasm-bindgen 绑定层(tiptap_bridge),EditorOptions/onReady/onUploadEvent 回调替代轮询。 - Lightbox 与 post-content 从
include_str!内联改为配置驱动初始化;移除旧ImageViewer组件。 - JS 子项目从 npm 迁移到 pnpm。
- 封面图比例统一为 21:9;卡片重构使用原生
blur-img结构。 - 邮箱正则、sanitizer allowlist 用
LazyLock静态化以避免每次调用分配。 - Markdown 渲染读取 DB 中预渲染的
content_html/toc_html,写入时存储toc_html。 - 大量「上帝组件」拆分为子组件:
CoverUploader、FilterTabs、AutoPurgeSettings、RebuildCacheBar,共享EmptyState组件。
修复
- 修复
/uploads/{*path}路径因缺少ConnectInfo扩展而返回 HTTP 500 的问题。 - 修复并发重复评论提交(advisory lock);重复检查改为事务内原子操作并对
content_hash建索引。 - 修复评论表单:服务端 honeypot、a11y label、回复布局;待审评论嵌套显示于父评论下;评论项添加
md-content类修复高亮与空行。 - 修复时序枚举攻击:不存在用户执行 dummy Argon2 verify;对
check_pending_status限流防止状态枚举。 - 修复图片磁盘缓存清理跳过符号链接,防止遍历到缓存目录外部;过期 session 清理同时失效会话内存缓存。
- 修复 SSR hydration 不匹配、暗色模式 FOUC、ThemeToggle 状态同步。
- 修复 Tiptap 二次导航空白、链接命令顺序与 URL scheme 校验、blob 泄漏(节点销毁时 revoke)。
- 修复 404 页面、首页卡片嵌套锚点、封面图高度塌陷、暗色模式封面灰背景。
- 修复 WASM 构建假阳性 warning(27 处
cfggate)、Tailwind v4 与 Tiptap 构建问题。 - 修复 dev 模式 SSR 缓存导致渲染陈旧 HTML;
/doc路由与静态托管冲突的 panic。 - 修复
b7afd12起的 highlight 大小写匹配导致 Haskell 等高亮失效。 - 其他构建、CI、格式化与测试修复。
安全
- Session token 以 SHA-256 哈希存储;可配置单用户 session 上限并以行锁串行化。
- 基于 Origin 的写接口 CSRF 防护;
COOKIE_SECURE控制 Secure 标志。 - 不存在用户执行 dummy Argon2 verify 防时序枚举;
check_pending_status限流。 - 图片路径
canonicalize前缀检查(纵深防御);拒绝不可解码图片返回 422,原始文件上限 20MB;所有图片响应加X-Content-Type-Options: nosniff。 - 分页参数
per_page与page上限钳制,消除公开接口 DoS 与无界 OFFSET / 缓存键扇出。 - 磁盘缓存写入改为 temp-file + rename 原子操作。
内部
- 新增 vitest 测试套件:
tiptap-editor(UploadCoordinator、UploadImageNodeView、isValidUrl)、lightbox(geometry、lightbox 生命周期)、yggdrasil-core(post-content、theme-transition 降级)。 - 扩充 Rust 单元测试覆盖:AppError、sanitizer、WebP、theme、cache、db(迁移注册校验)、PostListItem 等。
- 补齐大量中文文档注释;更新 AGENTS.md、新增 DEVELOPMENT.md 与生产部署指南。
- Makefile 完善
test(cargo test + vitest)、clippy、fix、doc(ayu 主题)、build-lightbox等目标。 - 仓库安全审查(
449a545)修复多项关键问题。
0.2.0
新增
- 404 Not Found 页面
- 基于 moka 的内存缓存模块(文章、标签、统计查询缓存)
- 读写操作缓存支持:读操作命中缓存,写操作自动失效相关缓存
- 文章列表返回准确的总条目数,前台首页/归档/标签页分页使用准确总数
- WebP 图片编码支持(zenwebp),上传图片自动转换为 WebP 以节省存储空间
- 图片变体磁盘级缓存
改进
posts.rsAPI 拆分为模块目录结构- 统一错误处理为
AppError枚举 - 缓存层优化:直接返回命中结果,COUNT(*) 结果单独缓存
- 提取 WebP 编码辅助函数减少重复代码
- 简化 TraceLayer 配置并重新格式化路由定义
修复
- 修复多处
#[cfg(feature = "server")]门控缺失导致的编译问题 - 缓存正确失效旧 slug 和新 slug
- WebP 解码缓冲区大小限制,防止恶意大分配
- 代码块复制按钮点击处理
- 其他细节修复
内部
- 新增缓存、WebP 配置测试用例
- 添加 release 自动化技能
0.1.0
新增
- Dioxus 0.7 全栈项目脚手架
- PostgreSQL 数据库建表(用户、文章、标签、会话)
- 用户认证系统:注册、登录、Session 管理
- 首个注册用户自动成为 admin,后续注册关闭
- HttpOnly cookie 会话机制
- 后台管理页面与路由
- Tiptap 富文本编辑器集成(Markdown 模式)
- Slash 命令、表格、任务列表、图片和链接扩展
- 图片粘贴/拖拽上传
- 文章 CRUD:创建、编辑(含数据回填)、列表、删除
- 文章封面图支持
- Markdown 渲染:TOC 目录、锚点链接、字数统计、预计阅读时间
- 代码高亮(syntect + catppuccin 主题),支持 Swift/Kotlin 自定义语法
- XSS 防护(ammonia 清洗 HTML)
- 前台博客页面(PaperMod 风格)
- 首页(个人简介 + 文章列表 + 分页)
- 归档页(按年月分组)
- 标签页(标签云 + 标签详情)
- 文章详情页(目录、上下篇导航)
- 搜索页
- 关于页
- 暗色模式(系统偏好检测 + 手动切换,SSR 安全)
- SSR 预渲染(首页、文章、归档、标签)+ 增量缓存
- 骨架屏加载动画(各页面独立骨架,防闪烁)
- 图片处理:缩放、缩略图、旋转、格式转换(moka 缓存)
- 图片灯箱查看器
- pg_trgm 全文搜索
- Rate limiting(注册、登录、上传接口)
- 数据库连接池重试逻辑
- Session 过期自动清理(每小时)
- 数据库性能索引(posts/tags/sessions)
- 数据库迁移脚本(migrate.sh)
- 122 个单元测试覆盖 12 个模块
- 项目开发指南(AGENTS.md)
改进
- Tailwind CSS v4 + 独立 CLI 构建
- admin 模块重构为共享组件 + card 布局
- 全局使用 Dioxus 客户端路由替代原生导航
- 提取公共组件:FormInput/FormLabel/AlertBox、SkeletonLine/SkeletonBox/SkeletonCard
- 提取工具模块:slug、markdown、tags、text、time、session
- API 层 DRY 重构(错误处理、N+1 查询修复 via JOIN+array_agg)
- 文章 slug ASCII 化 + 时间戳回退
- Tiptap 编辑器 Vite 构建输出固定文件名
- 首页 HomeInfo 个人简介替代原始首区
修复
- 修复 admin 路由切换闪烁
- 修复编辑器暗色主题和列表样式
- 修复 Footer 滚动监听器未清理
- 修复 CJK 字数统计
- 修复代码块 Tailwind
.block类冲突 - 修复 SSR 水合不匹配(ThemeToggle)
- 修复 WASM 生产环境 404(symlink 修复)
- 修复图片上传 500 错误
- 修复 Markdown 渲染中 data URI 丢失
- 修复暗色模式 FOUC 和状态同步
- 修复登录后 UserContext 未重置
- 修复文章 slug 唯一性检查(含已删除文章)
- 修复 Tiptap 编辑器二次导航空白问题
- 修复模板 hydration 不匹配警告
- 修复 Clippy 和编译器警告