本 Changelog 自 2026-05-22 起以 HTML 格式维护。此前之变更可从 main 分支 git log 取得;下表为近期较显著之 commit。
2026-07-31 — 全客户端正式命名、认证迁移与构建分发收口
Windows、macOS、iPhone、iPad、Web 与服务端完成一次面向用户文本和可诊断协议面的统一。正式产品名固定为 Commilitia Drop;桌面端移除 “Desktop” 后缀,每个平台只保留一份正式客户端。
- 正式客户端矩阵:Windows 使用 Wails x86-64;macOS 继续使用 Wails ARM64;iPhone 与 iPad 共用 SwiftUI target;Web 使用 React SPA / PWA。原生 macOS target 仍是迁移候选,在功能对等、签名扩展和真机验收完成前不切换,也不作为第二个 macOS 客户端发布
- 用户可见命名与协议:应用显示名统一为 “Commilitia Drop”;登录回调改为
commilitia-drop://auth-callback;DataChannel 与 iOS 文件流 Scheme 改为commilitia-drop-file;Bonjour 服务类型改为_commilitia-drop._tcp;Auth Broker application key 原位迁移为commilitia-drop - 内部身份兼容边界:Bundle ID、App Group、Keychain service、LaunchAgent label、环境变量、数据库与配置目录在不直接决定系统显示名时保持稳定,以保留既有权限、钥匙串和配置。稳定 AppId 本身不作为用户可见命名迁移对象
- 认证链修复:Broker、Caddy 与服务端 application key 同步后,修复桌面端“无法连接”以及 iPhone / iPad 在 Broker 批准后显示“登录失败”的问题;旧 session 允许失效,双移动端已重新登录验证
- macOS 分发:复用既有 Developer ID Application 证书,对 Wails ARM64 app 与 DMG 完成 hardened runtime 签名、Apple 公证、staple 与 Gatekeeper 验证;正式分发只保留公证 DMG
- Windows 与 iOS 安装:Windows x86-64 客户端已以唯一正式文件安装并更新登录启动项,当前产物尚无 Authenticode 签名;iPhone 与 iPad 全程使用 CLI、复用既有 Apple Development 证书覆盖安装,不打开 Xcode GUI、不创建新证书
- 分支收口:
native-transfer的原生数据面工作已并入main,旧分支不再作为开发或发布入口 - 流程文档与验证:新增 全客户端构建与安装手册,记录 Web / 服务端、Broker、Windows、macOS、iPhone、iPad 的构建、签名、安装、分发和验证步骤。代码落点为 main commit
c480f0d
2026-06-28 — 原生数据面收口:桌面 pion + iOS libwebrtc,逃离 WebView WebRTC 限制
P2P 数据面(DataChannel 字节收发)从系统 WebView 的 JS 移出、改跑原生:桌面用 pion/webrtc(Go 进程),iOS 用 libwebrtc(RTCPeerConnection)。两端逃出 WebKit 写死的 256KB SCTP 接收窗与渲染器节流;JS 仅留信令 / 会话 / presence / 消息 / relay 编排。
- 桌面 pion 数据面:吞吐专项定位两根因 —— WebView2 的 SCTP 处理活在渲染器进程内、窗口隐藏即被 backgrounding 节流(Windows host↔host 仍 100KB/s),WebKit usrsctp 接收窗写死 256KB。改由 Go
pion/webrtc跑数据面(SetSCTPMaxReceiveBufferSize大 rwnd、真实 IP host 候选去 mDNS、Go 直接读写磁盘去 base64 桥),窗口状态与网络栈彻底解耦;引入p2pBackend抽象使transfer.ts编排零改动(isDesktop()走 Go 桥、web / iOS 走 JS)。Win↔Mac 实测约 10MB/s - iOS libwebrtc 数据面(U1→U2 翻案):先试 gomobile + pion(与桌面同引擎,U1),真机 POC 证伪 —— Go raw BSD socket 不与 iOS Network framework 集成(连接时好时坏 + 中途断流)。按闸退到 libwebrtc.framework(stasel/WebRTC M149 经 SPM、pin
149.0.0),新增LibWebRtcEngine.swift端口桌面线协议;libwebrtc 原生集成 iOS 网络栈 + DcSCTP ~5MB 默认 rwnd - 三端线协议逐字节对齐:DataChannel 当时名为
cdrop-file(2026-07-31 已迁移为commilitia-drop-file),采用 ordered、meta/ 二进制分片(64KB) /done/ack帧、16MB-4MB 水位背压、接收端 ack 追平完成、不冲突落盘 —— 桌面 pion ↔ iOS libwebrtc ↔ 浏览器 JS 互通。新增结构化日志把 pion 内部日志路由到宿主(真机无 stderr 时诊断连接);进度回调 ~10Hz 节流(高吞吐下每片一回调打满宿主主线程) - 验证:环回端到端 20MB 逐字节完整性 + 模拟器全 app 编译 + web typecheck / build 过;iOS 真机已装、用户反馈“传输总体良好”,真网吞吐互通为剩余闸。设计依据见
desktop/NATIVE-TRANSFER.md§7/§8、ios/PLAN.md决策 F - commit
ab57afd(桌面 pion)·f1a00d1·349d94a(iOS libwebrtc,native-transfer 分支)
2026-06-28 — iOS UX 重构:发送预览 · 按设备会话 · 品牌与字体系统 · 全平台平均速度
真机使用后落地的一组用户可见改造:发送流程改“先预览后发”、消息按设备聚合成会话、引入与 web 对齐的品牌 logo 与字体栈,并统一传输完成后显示平均速度。
- 发送预览界面:选文件 / 图片或经分享进入后,先进发送预览(文件名 + 大小 + 选目标设备),不再即弹设备框;手动入口支持多选。分享经 Share Extension 暂存 App Group → 唤起主程序直入预览,并以
scenePhase回前台兜底重扫(修“分享后必须重启 app 才能传”) - 消息按设备会话:从扁平流改为按设备聚合的会话列表(社交 app 模型)—— 会话项 = 有历史或当前可达的设备,非 APNs 离线设备不可发但历史可查;未读粒度下放到每设备(各显未读红点、“消息”标签显总数);可删单条消息与整设备历史,避免废 session 堆积
- 品牌 logo 与字体:引入吉祥物 logo + “Commilitia Drop” Fredoka 字标(登录 / 传输空态 / 设置头 / 控制中心控件);界面字体用系统原生(SF 语义样式 + Dynamic Type,日志等宽用原生 monospaced),仅品牌字标保留自定义字体 Fredoka(
UIAppFonts,不入库、just ios-fonts拉取)。(同轮曾试引入 Orbit Gothic / Maple Mono 自定义 UI 字体栈,后统一撤回系统原生。) - iPad 适配:
TabView经.tabViewStyle(.sidebarAdaptable)双形态(iPad 侧边栏 / iPhone 底部标签栏)+ 消息线程可读宽度居中 + 全 4 向方向支持 - 全平台平均速度:传输完成后速度列显平均速度(总字节 / 总耗时)而非末次瞬时值;web / iOS 一致(桌面共享 web store,需重建分发方落地)
- commit
349d94a(native-transfer 分支)
2026-06-27 — iOS 原生客户端落地:应用内登录 · 流式发送 · 后台续传 · APNs · Share · 控件 · 通知 · 小组件
iOS 原生 SwiftUI 客户端(液态玻璃壳 + 离屏无头 WebView 复用传输引擎)从计划走到真机预备,并经一整天真机反馈迭代成熟。
- 计划主体落地:发送端流式(整文件不进 WebView 内存)/ 后台续传(
BGContinuedProcessingTask)/ APNs(后端internal/apnsES256 + 原生注册,push_subscriptions加platform列 +POST /api/push/apns/register)/ Share Extension(App Group 收件箱 + 深链)/ 控制中心剪贴板两控件(专用 broker 设备会话、纯原生 REST) - Broker 应用内登录 + 设备名解耦:iOS 接入 Auth Broker 应用内登录、消息 / 图库 / 记录持久化;设备名与令牌解耦
- 后台 / 会话三诉求:子会话(一台设备一会话)+ 离线消息队列 + 被登出推送 + 后台唤醒层;后台 / 墓碑态 iOS 可作可唤醒传输目标,发送端等其回前台再传
- 真机反馈迭代:隔夜重登修复(单飞刷新)+ 通知系统重做 + 未读红点 + 日志独立界面 + 扫码登他端 + 主屏小组件 + 长条行交互统一;取消即时落终态 + 行操作统一 + 记录按用户分桶 + 发送端进度 / 完成对齐接收端(接收端字节 ACK 回传)
- 计划与同步检查单见
ios/PLAN.md/ios/PARITY.md;commit4409606·127070e·1b94df1·a2cad11·2caf1ab·c1dda67(main)
2026-06-26 — 鉴权并入 Auth Broker:委派设备会话统一模型 · 四端迁移 · 显示名与头像修复
cdrop 的登录 / 会话 / 设备 / 令牌生命周期并入既有 Auth Broker(边缘身份中介),删去 cdrop 内的自建鉴权副本;浏览器、桌面、手机一律收敛为同一套“委派设备会话”模型,统一管理;并修复部分客户端显示名为账户 UUID、头像缺失的回归。
- 后端委托 Auth Broker(路径 A):删自建 OIDC 交换 / 自签会话 / step-up / shortcut /
web_sessions/accounts及验证链,cdrop 不再存任何凭证;鉴权中间件改读边缘broker { app cdrop }注入的X-Auth-Subject/Name/Avatar/Scope/Meta头。新增internal/brokerclient(委托铸造 / 吊销 / 续期 / 列举) - 统一会话模型“委派设备会话”:每个客户端 = 一条带
meta(device_id) +label(设备名) 的 broker 机器会话,Broker 作设备会话唯一注册表。浏览器全局 SSO、桌面设备授权(RFC 8252 loopback PKCE)、扫码批准,登录后一律“代铸”出设备会话(同一 device_id 幂等轮换、不再堆重复设备);cdrop 退化为薄覆盖层,会话真相与吊销授权一律走 Broker - 设备管理:浏览器 / 桌面 / 手机统一进一个设备列表,显示在线、当前设备与类型,可吊销、可改名(同 device_id 重铸换名、不产生重复行)。修复迁移引入的一组回归:设备列表为空 / 重复无名设备 / 看不到在线的另一台 / 吊销报“设备不存在”
- 显示名与头像修复:经 Broker 端到端补
X-Auth-Name/X-Auth-Avatar,浏览器与桌面恢复真实显示名与头像(此前部分客户端显示账户 UUID、无头像)。桌面新增启动期HealIdentity——注入前从/api/me自愈旧版烤进会话的陈旧身份并持久化,根治偶发 UUID - 四端迁移:后端、Web 前端、iOS、桌面(Wails)客户端同步迁移;存量会话于翻闸时失效、需重新登录
- commit
10cf36e(main)
2026-06-23 — P2P 传输修复:接收混合落盘 sink · 发送进度与完成语义 · 文字累积 · 速度显示
修复 iOS PWA → Mac 桌面客户端大文件 P2P 传输约 15MB 处死锁,及随之暴露的两处发送端语义问题;并修一类前端 CJK 文字累积 bug、为传输卡片增设实时速度。
- 接收端混合有界内存 sink(桌面):
wails://自定义 scheme 无持久 WebView 存储 → OPFS 降级、createWritable回压不畅,把接收 promise 链堵死、饿死dc.onmessage→ 接收方 SCTPrwnd=0→ 发送方bufferedAmount卡死 16MiB(即“PWA 16.0MB / Mac 0B、约 15MB 卡住”)。改为:小文件(暂存 < 256MB)纯内存、close整文件过 Go 写盘;超上限大文件流式 spill 到 Go 临时文件(每 64MB 一批),内存恒定有界。浏览器 / iOS 接收仍走 OPFS(其内存预算紧、又无 Go 落盘,OPFS 才有意义) - 桌面流式落盘:
download.go新增Begin/Append/Finalize/AbortStreamingDownload(复用SaveDownload的目录解析 / 文件名 sanitize / 不可写回退 / reveal,临时文件与目标同目录便于 finalize 原子 rename),app.go加 4 个绑定 +net/desktop.tsbase64 封装;IncomingSink.close()返回SinkResult(blob| 已落盘path),deliverIncoming统一落地;relay 接收一并改用,桌面大文件经中继也有界落盘。含单测download_stream_test.go - 发送端进度按“已交付字节”计:原先用
bytesSent(已塞进本地 16MiB buffer 的量),buffer 被秒满后定格、长 backpressure 等待期误报“疑似卡住”。改用bytesSent − bufferedAmount(已离开本地 buffer ≈ 已交付)+ 250ms 轮询在等待期持续刷新,进度随接收端实际收程平滑爬升、不误判 stalled - 发送端等抽干再宣告完成:原先送完入 buffer 即
setState("completed"),此时仍可能有多达 16MiB 在途,与接收端“仍在下载”状态不一致。改为送完 + done 帧后等bufferedAmount落到 0(字节已全部交付网络)再宣告完成 - 前端动态 CJK 文字累积修复:聚珍 shim 把会就地更新的 CJK 文本节点 charify 拆段后,旧碎片成了 React 不再追踪的兄弟节点残留、每更新一次累积一个多余字(典型“发送到 X”切设备后多出的“到”)。新增
DynText(key=文本内容,内容一变即整体卸载旧 span、连同 shim 碎片,再挂新 span 交 shim 处理一次——既消累积又保留中西排版,区别于data-jz-skip那样关掉排版),应用于发送按钮 / 设备名 / 在线数 / 相对时间 / 会话与令牌活跃时间 / 消息计数 / 剪贴板来源 / 问候语等就地更新处 - 传输卡片实时速度:store
upsertTransfer据相邻样本的字节 / 时间差分 + EMA(α=0.3)平滑算bytesPerSec;TransferRow仅在字节流动且未卡死、且速率为正时以“X/秒”展示(点分隔 meta 行追加),卡死时既有“似乎卡住了”状态已表达停滞、不显误导性 0 速 - commit
0451549(main)
2026-06-22 — 账户与登录子系统:扫码快登 · 自签会话 · OIDC 统一 · 即时吊销 · 设备=会话
“OAuth 为账户来源与凭证提供者、cdrop 自维护薄账户层 + 自签会话”的折中架构落地(蓝本见仓库 AUTH.md)。一台设备 = 一条会话,吊销即时生效、被吊销设备自动回到未登录态。
- 扫码快速登录:陌生设备显码、已登录手机扫码批准(微信 / WhatsApp 网页版模型)。三密钥分离(
request_id/approval_code/ 仅新设备私有的poll_secret),偷拍 QR 无法领取会话;会话只经新设备自身轮询连接下发 cookie。两档:“信任此设备”(scope=full、7 天滑动) / “仅此次”(scope=guest、1 小时受限),默认偏安全的“仅此次”。访客会话服务端强制受限(requireFullSession守门) - 薄账户层 + 自签会话令牌:新增
accounts表(cdrop 侧账户数据、不含凭证,存稳定match_key供管理员开启迁移时跨源关联);web_sessions泛化出kind/scope/granted_by/stepped_up_at。access token 改 cdrop 自签 HS256(密钥自CDROP_SESSION_SECRET域分离派生),脱离 IdP refresh、短 TTL(默认 900s)、载sid - OIDC 统一到自签 token:浏览器登录(含 OIDC)一律持自签 token ——
/auth/exchange先 JWKS 验id_token签名(唯一信任锚)再签自签 token,/auth/refresh仍打 IdP 轮换 refresh_token 但回自签 token。RS256 退出浏览器每请求热路径,仅保留分支供桌面端 loopback 直带 IdP token - 吊销即时 + 设备自知:
verifySelfToken每请求按sid查会话行,行删即拒 → 吊销在下次请求即生效(不等 TTL)。前端仅在“服务端以 401 确证失效”时清登录态回登录页(短期连接失败 / 5xx 不误清);离线设备下次使用即知,在线设备经Hub.Kick关流、约 1s 重连撞 401 即知 - 设备列表 = 会话列表:“登录会话”面板统一
web_sessions与原生客户端设备(桌面 / iOS,自devices登记呈现,native=true)。吊销网页会话连带删其设备登记、即时从所有列表消失;孤儿browser设备由清扫器(DeleteOrphanBrowserDevices)自动清除。原生设备“登出”走DELETE /api/devices/{name}(同要求 step-up) - 2FA step-up 钩子(默认关,
CDROP_STEP_UP_ENABLED):批准扫码设备 / 吊销会话 / 注销设备等敏感动作要求一次现场prompt=login再认证(provider 的 2FA 即在此过),按会话绑定、StepUpMaxAgeSeconds(默认 300s)窗口内不复要求。auth_time可选(Casdoor 不下发) - 应用内扫码器 + 聚珍崩溃修复:登录页内置
getUserMedia+ jsqr 扫码(不再外跳系统应用、避免开错浏览器);扫码 / 批准等三状态机页整页跳过聚珍(data-jz-skip),修 MutationObserver 与 React 重渲染同子树冲突的insertBefore崩溃 - 蓝本
AUTH.md;commit 待提交
2026-06-18 — 推送通知:网页 / PWA Web Push + 桌面原生通知
页面 / PWA 关闭、或桌面窗口非前台时也能收到系统通知;判定统一为“页面打开走应用内提示,关闭则系统通知”,三端各自落地。
- 网页 / PWA(Web Push, VAPID):服务端在事件未经 SSE 投递到设备时(即该设备页面已关)发 Web Push —— 收到文件、消息、传输完成 / 失败均可。新增
push_subscriptions表(含locale,主键为 endpoint 的 SHA-256 以幂等 upsert)+/api/push/{vapid-key, subscribe}端点 +internal/push发送器(404 / 410 自动清理死订阅)。文案按订阅设备语言在服务端渲染(中简 / 中繁 / 英)。覆盖浏览器 / Android / iOS 16.4+ 已安装 PWA - 桌面客户端原生通知:仅窗口非前台时弹原生系统通知(前台仍走应用内提示),复用 WebView 事件分发 + 客户端本地化。macOS 走
UNUserNotificationCenter(未签名时安全空操作,待签名 / 公证后显示)、Windows 走原生 toast - 判定复用既有信号:网页端“页面是否打开”直接取
Hub.SendTo的投递结果,零额外状态;离线消息改返 202,文本随推送送达 - 开关与配置:设置页新增“推送通知”面板(仅浏览器 / PWA),登录后自动把既有订阅重新登记到当前用户;prod 可选设
CDROP_VAPID_PUBLIC_KEY+CDROP_VAPID_PRIVATE_KEY(just vapid-keygen生成一对,二者须同时设置,都留空则推送惰性关闭) - commit
92a03ae
2026-06-16 — 浏览器免重登 + 设备名持久化
浏览器端不再每次重启都要重新登录;长寿命 refresh_token 从此完全不进 JS,改由服务端 HttpOnly cookie 会话持有。对长寿命凭据而言比原先(refresh_token 在 JS 内存、开页期 XSS 可读)严格更安全。
- 服务端会话表 + cookie:新增
web_sessions表(sqlc)。/auth/exchange换完 token 后建会话并下发 cookie(HttpOnly; Secure; SameSite=Lax; Path=/api/auth),响应体不再回传 refresh_token;refresh_token 以 AES-256-GCM 落盘(密钥取自CDROP_SESSION_SECRET,在 env、不在库内),cookie 只放不透明随机串、表 id 存其 SHA-256 —— DB 单独泄露既换不出可用 cookie、也解不出 token - 开机静默免重登:
/auth/refresh改为 cookie 驱动(7 天滑动失活)—— 这条同时就是开机静默免重登路径,前端首屏渲染前bootstrapAuth用 cookie 续期,命中直接进已登录态、避免登录页闪现;新增/auth/logout(删会话 + 清 cookie)、/auth/device(写设备名入会话) - 设备名持久化:设备名随会话存,开机 refresh 带回前端,抗 iOS PWA 存储清除 —— localStorage 被驱逐也能恢复,不再误跳设置页
- 多 tab 并发 refresh 防护:同一用户多 tab 共享一个 cookie → 一个 refresh_token,加 striped per-session 锁串行化并发 refresh,防一次性 refresh_token 被花两次而把用户从所有 tab 一起登出
- 凭据面收紧:前端 store 彻底移除
refreshToken字段,浏览器侧长寿命凭据不再触及 JS。CSRF 由 SameSite=Lax + Origin 校验双保险。桌面端不受影响(自有 loopback flow + 系统密钥库,不碰这两端点) - 部署要求:prod 须设
CDROP_SESSION_SECRET(任意长度高熵串,内部 SHA-256 派生 AES-256 密钥),缺则拒启动 - commit
e51666c
2026-06-15 — PWA 安装支持 + Safari OAuth 回跳卡顿修复
- PWA 安装支持:web 可“添加到主屏幕”独立启动(manifest + iOS meta + 同源静态壳 service worker)。SW 绝不拦截
/api(SSE / 剪贴板 / 中继需活连接)、亦不拦导航;PKCE verifier 改localStorage,使独立 PWA 在 OAuth 回跳重启上下文后仍能完成登录。面向用户短名统一小写cdrop - Safari OAuth 回跳卡顿修复:Safari / iOS PWA 从 IdP 回跳登录后,
setup.js与头像约 2 分钟拿不到连接(Chrome 正常)。根因是oauth.callback登录成功后用路由软导航,复用了 OAuth 流程遗留的 HTTP 连接,这些连接在 Safari 下卡死后续资源请求;改为整页跳转(window.location.replace)拿全新连接绕开。曾误判 service worker / h3 为主因,均已排除 - commit
5c28ddf(PWA 安装)/7082ccc(短名)/af754dc·8f550ad(Safari 修复)
2026-06-14 — 安全加固:中继会话防耗尽 + 令牌入系统密钥库 + 鉴权 / 限流多项收紧
多 agent 安全审计后的一轮加固,按信任模型(信任账号所有者 + 服务端;不信任跨用户 / 网络 hop peer / 本机其他软件)逐项收紧。
- 中继会话防耗尽重构:中继改为“预登记”模型 —— 传输进入
RELAY_ACTIVE时由服务端登记其两个合法参与方,之后仅已登记会话可接入、且调用方须为 sender / receiver。叠加 per-user 配额(3)+ 全局上限(8)+ 空闲回收(2min)+ ring 单 reader 断言。一举堵住“任意 id 凭空铸造会话耗尽全实例并钉 512 MiB”“幽灵会话”“id 泄露后无第二道防线”“双 reader 撕裂数据”四类问题 - 桌面 refresh_token 入系统密钥库:长效 refresh_token 不再明文落盘,改存系统密钥库(macOS Keychain 经
security/ Windows Credential Manager·DPAPI / Linux Secret Service),同机软件无法直读冒充;会话文件只留短效 access_token。遗留明文文件首次启动自动迁移并抹除 - HS256 token 强制 jti:HS256 路径只签 clipboard 限域的快捷指令 token(必带 jti),无 jti 的有效签名一律拒签,把密钥泄露的爆炸半径压回 clipboard-only
- prod 强制 OIDC audience:prod 下
CDROP_OIDC_AUDIENCE为空即拒绝启动 —— 空 audience 会跳过校验、令同一 JWKS 下兄弟应用的 token 也能验过(跨 app 冒充)。部署要求:prod 须设该变量(web + 桌面 client_id 逗号分隔) - 请求面收紧:信令 / 文本消息加请求体上限(防 OOM);内置 TURN 凭据 TTL 由 24h 降至 1h(缩泄露窗口 24×);
/auth/exchange与/auth/refresh加 per-IP 限流(防把服务当 OIDC 暴力跳板) - commit
bcdc2b4(中继 / HS256 / 密钥库 / body 上限)·c536a35(audience / TURN TTL / 限流)
2026-06-14 — 桌面文件落盘可配置 + 传输列表行内操作 + macOS 下载兜底修正
- 桌面端接收文件落盘到可配置目录(默认系统
~/Downloads):设置页加“下载目录”+ 原生目录选择框(ChooseDownloadDir→ WailsOpenDirectoryDialog)。机制为 Go 绑定写盘 —— 桌面模式下downloadBlob改走SaveDownload(blob → base64 过桥 → Go 写盘),对端文件名经sanitizeFileName剥目录成分防路径穿越、重名加(n)、落盘后open -R/explorer /select揭示 - macOS 下载兜底修正:WKWebView 不处理
<a download>的blob:,原“失败回退浏览器下载”在 macOS 是空操作、会静默丢文件;改为写配置目录失败时自动改写系统~/Downloads,连默认目录也失败才显式报错(toast.error),不再丢文件 - 传输列表行内操作:每行加 —— 非终态“取消”(拆本端 P2P / relay +
POST /transfer/{id}/cancel)、终态“删除”(从 active + history 移除)、发送方仍在试 P2P 时“立即中继”(清 30s ICE watchdog +POST /transfer/{id}/fallback,跳过等待) - 双端桌面客户端(macOS universal
.app+ Windows.exe)重构并同步;web 端 prod 部署(drop.commilitia.net) - commit
43ddf36(下载路径)/10a4c99(传输 UX + 兜底修正)
2026-06-12 — 接入聚珍(Juzhen)2.0 综合 CJK 排版:全角式 + 功能分级 + 本地优先字体
- submodule
cjk-autospace升级a5faec5 → a3c94dd:v1 自动空格 shim 从零重写为“聚珍(Juzhen)”2.0 综合排版引擎 —— 中西间隙 / 标点挤压(全角式)/ 禁则避头尾 / 垂悬字避免 / 长英文断词 / 功能分级;JS 只注入jz-*结构、视觉尺寸全在juzhen.css(必配) - 功能分级:功能分文本级(中西间隙 / 标点挤压,任意文本片段适用)与段落级(禁则 / 垂悬字 / 长词断字,需行段布局,对单行 UI 文本无意义甚至有害)。薄壳
level:{text:".juzhen"}令全树默认文本级(cdrop 绝大多数是 UI chrome);消息正文 / 剪贴板内容 / Callout / Toast 正文 / Field hint / 登录说明等 8 处流动正文加data-jz-level="paragraph"opt-in 段落级,失败模式良性 - 字体逐 region 明确化(
fonts.css,:lang()切 SC/TC/JP/KR):Sans = Orbit Gothic CJK;Serif = Noto Serif CJK(本地合一)+ Noto Serif <R>(Web 子集、跨区并集覆盖);Mono = Maple Mono + Orbit Gothic CJK - 本地优先字体层(新增
fontface.css):CDN 的@font-face无local()且 family 名与本机安装同名 → 被捕获、永远走网络。本层在 CDN<link>之后用src: local(), url()重声明项目用到的字重,本机命中即零网络、否则回退 CDN(swap) - Badge 加固(children 包单个 inline span,防聚珍注入元素在
inline-flexgap 中各成 flex item 致 gap 叠加);术语“Pangu”统一改“聚珍”;commit907d132/b3c74a6
2026-05-22 — README 补 clone 注意事项
- 新 clone 之 repo 预设不自动 fetch submodule,
web/src/lib/cjk-autospace/为空时vite build会因找不到 import 而失败;错误信息虽含路径但不直观 README.md顶部加“克隆”小节,指引git clone --recurse-submodules <URL>或补拉git submodule update --init --recursive- commit
1443543
2026-05-22 — cjk-autospace 抽出为共用 submodule
- 把原内联在
web/src/utils/cjkAutospace.ts的 Pangu shim 抽出为上游 git 仓库 cjk-autospace(双 pass 架构:跨样式标签透明 + 行内块边界,commitc3defc4) - 以 git submodule 引入
web/src/lib/cjk-autospace/;cjkAutospace.ts缩为 ~50 行薄壳,只负责 cdrop 的pillSelector="code, kbd, .cjk-pill"配置 + React 下的 MutationObserver 增量观察(自反馈防护、queueMicrotask防同 batch 重排) - 单一真实源:lib 修改一次三端(HTML 模板 / Peek.nvim shim / cdrop)同步生效;本仓库 deploy 时 Vite 把 submodule 检出之文件当一般 TS / JS 模块打包,运行时不读 Dropbox 也不依赖 git 元数据
- 架构文档(
PROJECT_BRIEF.md+FRONTEND_DESIGN.md)+ Changelog 移到 docs 分支(本档)
历史变更(移转前未以本档记录)
| commit | 说明 |
|---|---|
aa80793 | CJK 排版子系统:Pangu.js v7.2.1 端口 + cjk.css + Button label 包裹 |
4e8c541 | 前端视觉重塑后续迭代 + i18n 本地化清理 |
81dfbe1 | 前端重设计:tokens 变量化 + features-first + 原子组件 + 首页重画 + Toast + Dracula Pro 主题 |
6db6444 | 新增繁体中文(臺灣)+ locale 检测按 Hans / Hant + 区域子标签细分 |