Skip to content

Latest commit

 

History

History
125 lines (76 loc) · 6.53 KB

File metadata and controls

125 lines (76 loc) · 6.53 KB

贡献指南

感谢你愿意为 ClaudeViewer 出力。这份文档只讲两件事:哪些底线不能碰,以及怎么提 PR 最容易被合并。


一、四条产品底线

这些不是代码风格偏好,是产品定义。违背其中任何一条的改动,无论实现多好都不会被合并。

  1. 本地优先 — 数据只在浏览器内处理,绝不上传,不引入后端。
  2. 单文件优先 — 核心查看器永远是一个可双击打开的 HTML,不依赖任何外壳、运行时或安装步骤。 重型能力只能做成可选伴侣:伴侣可以放进主仓(见五、可选平台伴侣), 但绝不能成为使用查看器的前提——删掉整个伴侣目录,网页版必须照常工作。
  3. 零外部请求 — 不得新增 CDN 链接、外部字体、对第三方的 fetch,不得埋点追踪。 自 v6.0 起页面声明了 CSP(default-src 'none'; connect-src 'none'),这条由浏览器强制执行——违反会直接被拦下。
  4. file:// 直接打开必须可用 — 因此不能依赖 fetch 本地文件、module script、Service Worker 等受 origin 限制的能力。

完整背景见 docs/ROADMAP.md 的「设计原则」与「明确不做」两节。


二、动手之前

项目形态

整个应用就是 claude_viewer.html 一个文件(约 960 KB,含内联依赖)。没有构建系统、没有包管理器、没有测试框架。改代码 = 直接编辑这一个文件,改完在浏览器里刷新即可验证。

不要碰的区域

  • <!-- vendor:start … vendor:end --> 区块(约第 21–46 行)由 build/build.py 生成,禁止手改。需要升级或新增三方库时改 build/build.py 并重新运行它。
  • 文件头部的 GPL-3.0 版权声明与作者署名注释,以及页面内的 .u-credit / .sb-credit 署名区块,任何修改都必须保留。
  • 版本号只有一处:JS 顶部的 APP_VERSION。<head> 里的静态 <title> 不带版本号,请不要往里加。

新增三方库

先问一句值不值:它会被 base64 内联进单文件,直接增加所有用户的下载体积。能用二三十行原生代码解决的,就别引库。


三、提 PR 的方式

一个 PR 只做一件事

这是最重要的一条。一个同时包含「新功能 + 若干无关 bug 修复 + 一个新平台的原生外壳」的 PR,会卡住所有部分——好的那部分明明能立刻合,却要陪着有争议的部分一起等。

拆开提:bug 修复一个 PR,新功能一个 PR,探索性的大改动先开 Issue 讨论。

新增数据来源,请写适配器

ccToConv() 是现成的样板:把新来源归一化成与导出包同构的 conv 对象,塞进缓存,渲染层零改动复用。 不要在渲染层加 if (来源 === X) 分支——那会让每加一个来源就要改十几处。

影响消息高度的改动

虚拟滚动模式下,任何会改变消息高度的操作(折叠块展开、图片加载、KaTeX 渲染完成)必须调用 reflowMsgHeight(wrap) 回填高度,否则后续消息位置全错。取消息位置一律走 msgTop(idx),不要直接读 offsets。

安全

任何插入用户/对话文本的地方,innerHTML 场景走 esc(),其余走 textContent。 不要写内联 onclick——v6.0 已经把它们全部改成 data-* 属性 + 事件委托,既是为了 CSP,也是因为内联属性里的字符串拼接极易漏转义。

代码风格

跟随周围写法即可:原生 API、紧凑单行、中文注释并标注版本来源(如 // v6.0: …)。DOM 用 $(id) 取。


四、验证清单

没有自动化测试,合并前请手动跑一遍:

  • 导入新版分片导出(整个文件夹)→ 对话 / 项目 / 记忆 / 回顾 / 账户五类数据都在
  • 导入旧版单 ZIP → 完全不回归
  • 对话渲染:thinking / 工具调用 / LaTeX / 附件 / 空消息占位
  • 对话内搜索、全局搜索
  • 统计页、数据体检
  • 导出 MD / PDF / 批量 ZIP
  • 档案库:添加、切换、重命名、导出整套、取出原件、移除
  • 深色模式、移动端窄屏
  • Claude Code 模式
  • 用 file:// 直接双击打开跑一遍上述关键路径

五、可选平台伴侣

主仓接受「把网页核心包进原生外壳」的可选伴侣(目前有 macos/),但它们是附属品,不是产品的一部分。以下几条是收下它们的前提。

主仓收什么

只收源码:外壳代码、适配器、构建脚本、说明文档、测试。 不收编译产物——.app / .exe 之类作为独立发布产物提供,不进版本库。

伴侣不得改动网页核心

伴侣必须复用未经修改的 claude_viewer.html。需要接管存储或文件访问时,走注入式适配器:构建时替换少数几处明确的接缝,并且接缝对不上就构建失败(fail closed),不允许「尽力而为」地降级。

伴侣内部可以有自己的 UI 文案与平台惯例,但不得为了迁就外壳去改网页版的行为。

版本滞后是允许的,主仓发版不等伴侣

这一条最重要,写死以免将来扯皮:

  • 主仓发版不阻塞在任何伴侣上。 claude_viewer.html 该改就改、该发就发,不需要先确认伴侣是否还能构建。
  • 伴侣通过 VIEWER_SHA256 之类的版本锁钉住自己实测通过的那一版网页核心。上游一变,伴侣构建会立刻失败——这是设计如此,不是 bug。
  • 伴侣落后于主仓属于正常状态,不算未修复缺陷。由该平台的维护者在方便时重新验证并升锁。
  • 因此:伴侣的 README 必须写明它当前对应、且实测通过的上游版本。

维护者只在自己有设备实测的平台上做验证。没有对应设备的平台,其构建产物由该平台的贡献者验证并署名。

提伴侣 PR 时请附上

  • 实测环境(系统版本、芯片架构、工具链版本)
  • 构建与测试的完整命令及输出
  • 当前锁定的上游版本,以及「这一版实测跑通了什么」
  • 明确说明哪些没测(其他架构、其他系统版本、真实数据 vs 合成数据)

六、署名

被采用的代码会在 commit 里以 Co-authored-by: 署名,并记入 README 的致谢。如果你希望用不同的邮箱署名,请在 PR 里说明。

本项目以 GPL-3.0 开源,提交即表示同意你的贡献以同一许可证发布。