Skip to content

新增 Bug 报告投递:契约与桌面端双通道 - #7

Draft
KuramiWan wants to merge 6 commits into
mainfrom
feat/bug-report-contract
Draft

KuramiWan wants to merge 6 commits into
mainfrom
feat/bug-report-contract

Conversation

@KuramiWan

@KuramiWan KuramiWan commented Oct 27, 2026 •

Copy link
Copy Markdown
Owner

新增 Bug 报告投递:契约、桌面端收集与三条投递通道

What changed(改了什么)

用户从社区弹窗点「报告问题」,看到主进程收集并已脱敏的报告,自己选一条通道送出:

  • 邮件:mailto: 拉起默认邮件客户端;正文可带邮件列表名与订阅地址,报告人想跟进才订阅。
  • 收件箱仓库 issue:预填 issues/new 链接,正文第一行是隐藏签名块,供收件箱仓库的 workflow 按签名折叠。
  • 代发(可选,默认关闭):配了 Web3Forms / Formspree,或自有 eleckoi-relay Worker 时显示「直接发送」;Worker 会回执(issue 编号)。
  • 兜底:退出时不变——复制报告到剪贴板、导出 JSON。

两个不做的事,都写进了 ADR 0041:不常驻上报(不启动 crashReporter、不引入 Sentry/Bugsnag),不自动建 issue(客户端不带 token;Worker 中转那条是显式 opt-in,见 ADR 决定 10)。

底层:

  • 主进程 modules/diagnostics:从日志的 session.started / session.ended 配对判断上次会话是否异常结束(跨天、跨轮转文件),收集失败行(只认 phase: 'failure' + 字符串契约码),拼报告后出口即脱敏(家目录 / Android 沙箱 / POSIX / macOS 路径、用户名、邮箱、token= 类参数)。
  • 契约 packages/shared/src/contracts/bugReport/:形状与校验、脱敏、邮件正文与 mailto:、issue Markdown 与隐藏签名块、代发请求(含自有 Worker 信封与回执解析)。
  • 收件邮箱、收件仓库、代发配置全部来自环境变量,仓库里不硬编码地址。

Architecture route(架构归属)

  • Main 新文件仅承担桌面壳职责,位于 host / modules / platform / i18n
  • Shared 新文件位于闭合集合:contracts / foundation
  • 产品跨 Host/Client 查询与命令使用生成的 Typert Remote;会话事件、分页与 projection 使用 DSH Connection 正式协议,未新增业务 IPC 或私有桥(本次只新增壳自己的最小 IPC 通道,见 contracts/desktopShell.ts)
  • Renderer 未直接访问 Electron、Node、SQLite 或 DSH SDK
  • 官方运行时装配隔离在 @eleckoi/dsh-runtime;本次未触碰
  • 新业务进入 DSH Host/Client 插件;本次不涉及产品数据
  • 长生命周期资源已注册为 Host/Cordis Plugin,并能反向释放(diagnosticsPlugin 注销自己的 IPC handler)
  • 新增失败带契约码、用户可见文案只在渲染层产生(check:error-contract 0 处)

Data and compatibility(数据与兼容)

  • Schema 改动:无
  • 没有把会话、消息、角色或模型配置写入 localStorage
  • 取消路径:保存对话框取消 → { saved: false },不写文件;收集失败 → 对话框显示错误,不发送
  • 报告格式带 schemaVersion,字段只增不改

Verification(验证)

  • pnpm test:bug-report 相关 3 个文件共 65 条用例(契约 40、桌面侧 20、对话框 5)
  • bash gates.sh 全绿(check:docs / check:architecture / check:plugin-types / check:plugin-docs / typecheck 等 10 步)
  • node scripts/check-error-contract.mjs:四条规则 0 处
  • Windows 真机验收:清单在 win-dev/checklists/bug-report.md,1–8 步通过(2026-10-27,dev 窗口 889644f)
  • 没有启动 Android、Docker、QEMU 或 ARM64 DSH 核心编译
  • UI 未定稿阶段没有借底层改造擅自改变样式(新对话框只新增 .bug-report-* 类)

已知与本改动无关的失败:apps/web/tests/chat/chat-display-preview.test.jsx 与
apps/web/tests/mobile/mobile-settings.test.jsx 各有 1 条在干净树上同样失败(已用 git stash 复跑确认)。

Review scope(审查范围)

  • docs/adr/0041-bug-report-delivery.md、docs/adr/README.md
  • packages/shared/src/contracts/bugReport/(report.ts / redact.ts / mailto.ts / issue.ts / relay.ts / delivery.ts)
  • packages/shared/src/contracts/desktopShell.ts、logActions.ts
  • apps/desktop/src/main/modules/diagnostics/
  • apps/desktop/src/preload/preload.ts、apps/desktop/src/main/host/DesktopHost.ts
  • apps/web/src/app/windows/shell/components/BugReportDialog.jsx、CommunityDialog.jsx、apps/web/src/app/windows/MainWindow.jsx
  • 测试:packages/shared/tests/bug-report.test.ts、apps/desktop/tests/bug-report-collection.test.ts、apps/web/tests/ui/bug-report-dialog.test.jsx

特别希望被挑战的点:

  1. 脱敏是否够。当前只处理有明确形态的东西(路径前缀、用户名全词、邮箱、凭据参数),刻意不猜 QQ 号、角色名、对话内容。日志尾默认关闭,用户勾选才带;但 details.what 里可能出现角色名。
  2. ADR 0040 决定 1 的解释:「不引入运行时错误服务」是否容得下「用户发起的导出」与「显式 opt-in 的代发」。
  3. 代发通道的边界:Web3Forms / Formspree 的公开标识会被提取并耗掉免费额度;ADR 承认这是取舍而非防线。

@coderabbitai

coderabbitai Bot commented Oct 27, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@KuramiWan KuramiWan changed the title test-pr-creation 新增 Bug 报告投递:契约与桌面端双通道 Oct 27, 2026
报告是用户发起的导出:同一份 BugReport 契约,邮件与收件箱仓库 issue 二选一。
不常驻上报、不自动建 issue、不收件端点。收件邮箱与收件仓库由发布配置注入,
不写死在本仓库里。

- contracts/bugReport/report.ts:形状、签名、主题、失败折叠与日志尾截断
- contracts/bugReport/redact.ts:家目录 / 沙箱路径 / 用户名 / 邮箱 / 凭据脱敏
- contracts/bugReport/mailto.ts:正文与 mailto 链接,编码后长度守卫,超限降级摘要
- contracts/bugReport/issue.ts:Markdown 正文、隐藏签名块与预填 issue 链接
- tests/bug-report.test.ts:32 个用例守住签名、校验、脱敏与两条通道
用户从社区弹窗点「报告问题」,看到主进程收集好的报告,再自己选邮件或
收件箱仓库 issue 发出去。不常驻上报、不自动建 issue。

- 主进程 diagnostics 模块:从日志判断上次会话是否异常结束(start 无 end),
  收集失败行并折叠,出口统一脱敏;预览 / 导出 / 打开通道三条 IPC。
- 收件邮箱与收件仓库来自环境变量,不写死在仓库里;为空时界面不显示对应按钮。
- 渲染层:报告对话框展示版本、平台、上次会话与失败列表,日志尾默认不带,
  备注可选;提供邮件、GitHub、复制、导出四个动作。
- 契约:投递形状、隐藏签名块、平台名补 macos / linux(开发机报告也要能落形)。
- 单测:契约 32 条、桌面侧 18 条、对话框 4 条。
邮件目的地可以是一个邮件列表:配置里另给显示名与订阅地址,正文页脚写明
投递去向与订阅方式,报告人想跟进才订阅。配置了托管代发服务时,对话框
显示「直接发送」,由主进程 POST 出去;没配就回到 mailto 与剪贴板。

- 契约:BugReportLetterOptions(列表名 / 订阅地址 / 长度上限)、
  relay.ts(Web3Forms 与 Formspree 两种公开标识的请求形状,端点必须 https)
- 主进程:bugReportSend 通道,15 秒超时,连不上 / 超时 / 非 2xx 一律折成
  net/operation-failed;没配代发时拒绝而不是假装成功
- 渲染层:代发优先,其次 mailto;按钮与正文都跟着配置走
- ADR 0041:补决定 9 与代价(第三方中转、额度、境外可达性)
- 单测:契约 38 条、桌面侧 20 条、对话框 4 条
代发服务在境外,连不上是常见结局。配了代发仍显示邮件按钮(降为次级),
失败时还有第二条路,不用只剩复制与导出。
客户端多一个代发 provider:eleckoi-relay。入口不需要密钥,整份已脱敏报告
进信封(schemaVersion + report + letter),由 Worker 校验、清洗、聚合后再
落 issue 或进每日摘要。Worker 回执(issue 编号)显示在对话框里。

- 契约:BUG_REPORT_RELAY_PROVIDERS 加 eleckoi-relay、信封形状与版本、
  bugReportRelayReceipt(只认自有 Worker 的响应,托管表单服务不给回执)
- 主进程:代发成功后解析回执并随结果返回;响应体原样交给纯函数判断
- ADR 0041:决定 10——双写、清洗三层、签名派生与去重、限流与保留期;
  原「端点代建 issue」从否决表改为已采纳并限定
- 单测:契约 40 条、桌面侧 20 条、对话框 4 条
代发通道没有邮件客户端可看,勾了日志尾用户也看不到将发出什么。补一个可展开
的全文预览,和 ADR「发送前可预览可删改」对齐。
@KuramiWan
KuramiWan force-pushed the feat/bug-report-contract branch from 889644f to 7335bc8 Compare October 28, 2026 08:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant