Skip to content

feat(mobile): 支持群邀请预览与确认加入 - #7930

Merged
MagicLizi merged 9 commits into
makecindy:mainfrom
nanaco666:feat-mobile-group-invites
Oct 30, 2026
Merged

MagicLizi merged 9 commits into
makecindy:mainfrom
nanaco666:feat-mobile-group-invites

Conversation

@nanaco666

@nanaco666 nanaco666 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

手机收到群邀请链接后,现在可以先查看真实群身份,再明确确认加入。首页手动粘贴、App 收到的邀请深链和前台剪贴板识别共用一个邀请面板;取消、换账号和重复打开不会留下错误提示或错误导航。客户端收到深链的验证,不代表微信等宿主已能将 cindy:// 显示为可点击链接。

变更类型

  • feat 新功能
  • fix 缺陷修复
  • refactor / perf 重构或性能优化
  • docs / test / chore 文档、测试或工程维护
  • 其他:

范围

  • 关联 Issue / 需求:用户已批准的手机群邀请与剪贴板识别需求,合同见 docs/product-rules/bot-group-chat.md §8.4;服务端配套 xindong/cindy-server#1131 已合并。尚无对应独立客户端 Issue,不借用其他需求编号。
  • 本 PR 包含:手机邀请入口、真实头像/人数预览、显式加入、登录续接、账号与迟到回调隔离、取消和重复处理、关闭后导航;Desktop 在 Global/中国大陆生成公开页链接,Dev 保留既有 scheme;相关语言、回归与文档。
  • 明确不包含:新版群邀请网页 UI(已独立保存至二期分支 design-group-invite-landing-phase2,未发布)、微信点击唤起与安装后续接的完整验收;以及话题、附件上传、推送身份、建群表单、服务端代码、数据库、原生配置、依赖或 lockfile 变更。不依赖未合并的 feat(bots): 简化私聊建群并统一邀请弹窗 #7902。
  • 用户可见变化:未连接电脑也可从首页加号选择加入群聊;只读预览不会入群;已加入时显示打开群聊;未知加入结果沿同一请求重试;处理过的剪贴板邀请不因回前台反复弹出。
  • 站外入口边界:cindy://chat-invite/... 是 App 协议地址,不能当作 HTTP 网页;微信等宿主可能不识别或拦截。此时可复制完整邀请,在 Cindy 手动粘贴或由已有剪贴板入口继续。Global / 中国大陆的 HTTPS 生成逻辑只有加载本 PR 的 Desktop 才会生效,使用的是现有公共页;Dev 与回环地址仍生成 scheme。尚未以真实微信点击、Safari 接力及首次安装流程验收,不能宣称完整站外入群链路已交付。
  • 是否存在 breaking change:无。沿用已有预览/接受接口与解析器,可选身份字段缺省时显示未知人数或默认群标识;不从链接主机选择登录区域或服务地址。

UI 变化

iOS 26.5 / iPhone 17 Pro,截图来自业务提交 b6b10eac35,真实 Dev 群;本轮仅同步主干修复,邀请 UI 未变,未重拍截图。以下为完整 App 截图(804×1748),保留邀请面板全部内容、关闭按钮与底部操作,展示加入后的 3 人 / 已加入状态。

截图前仅在模拟器内存中将邀请人显示名替换为示例名 QA User,截图后已恢复;未修改服务端账号或源码,群头像、人数和状态仍来自真实 Dev。背景为空白新建页面,不含账号或电脑信息。

浅色:

iOS 群邀请完整界面·浅色(已加入)

深色:

iOS 群邀请完整界面·深色(已加入)

  • 引用的设计规范:docs/design-rules/DESIGN.md §3 Typography Rules、§4 Inputs & Forms / Dialog & Modal、§5 Layout Principles、§15 Mobile;用户批准的邀请细则登记于 apps/mobile/docs/mobile-design-guide.md「群邀请 V9」。颜色与图标均用语义 token;iOS 复用 Expo 原生 BottomSheet 和原生 TextInput;Android 复用现有 CompanionSheet;无原生指纹变动。

怎么验证的

自动验证

当前提交 16137ae2d8fc8c4c3b86bb173d715552a0bd32f1 同步 main@4146107162e2a78a84b4972e06ed9ef98fa4429a,解决 3 文件的真实冲突:Mobile chatServerClient.ts、对应测试和自动生成的设计台账。保留邀请预览/接受,以及主干新增的话题失败缓存清除;两边既有测试全部保留。台账从 main 原文按合并树重新生成,人工区与 surface IDs 保留。

相对新 main 仍为原 36 文件;其中 35 个业务、测试及文档文件的增删内容与同步前邀请补丁完全一致,台账统计随合并源码更新。未扩需求、未混入二期网页、未修改服务端、依赖或原生输入。此次是 base sync,不增加业务修复轮。

本轮实际验证:Mobile 13 文件 / 433 项通过(13.09s,含邀请、Chat Server client、手机话题/群入口回归);Desktop 邀请 50 项通过(4.39s)。Mobile typecheck 通过(24.71s),Desktop typecheck 通过(139.86s)。设计台账、dev-docs、术语、test-hygiene、diff 与 DCO 检查通过。未重做模拟器、物理设备或生产验收;历史截图和运行证据继续保留各自提交标识。本地全量门禁未执行,等待 PR CI。

上一 head ad10e4e7f7397169c84a1c7af6f13bba6b0a29fe 的完整 CI 已通过,Greptile reviewed SHA 匹配并为 5/5(check-run 123918957028),无剩余实际 finding;这些结果不替代当前 head 的 CI/评分。新 head 的检查与审查单独核对,不复用旧分。

新版群邀请网页设计保留在独立本地分支 design-group-invite-landing-phase2,未发布、未部署,也不在本 PR。

上一业务修复提交 b6b10eac35 修复手动粘贴 cindycn:// / cindydev:// 邀请误报不完整的问题:复用现有链接归一化,保留裸邀请码、手动编辑和当前账号的服务端选择。两个回归修复前失败,修复后与截断链接负例通过。此前 9623d2a7a5 已同步 main@1dbff37a89 并保留首页双方测试;本次仅修改邀请 hook 与其回归,相对 main 仍为 36 文件。

Mobile:vitest run 下表 11 个 Mobile 文件 --maxWorkers=1
结果:212 项通过,墙钟 8.19s。
Desktop:pnpm --filter desktop exec vitest run src/main/maker-ipc/__tests__/chatServerInvitations.test.ts --maxWorkers=1
结果:50 项通过,墙钟 4.78s(复用 9623d2a7a5,本轮 Desktop 源码及输入未变)。
覆盖合计:12 文件 / 262 项;本轮执行 Mobile 11 文件 / 212 项,Desktop 沿用上述记录。

首页 17 项回归已包含在本轮 Mobile 212 项结果中,未另跑单文件。
pnpm --filter mobile run --if-present typecheck
pnpm --filter desktop run --if-present typecheck
结果:Mobile 本轮通过,25.36s;Desktop 沿用 9623d2a7a5 的通过记录,165.43s。
pnpm check:test-hygiene
pnpm check:i18n-glossary
pnpm check:dev-docs
pnpm check:design-inventory
git diff --cached --check
pnpm check:dco
结果:通过。

以下为初始提交 43579ceb 的全量验证记录;此次主干同步按当前仓库影响面规则执行上面的定向回归,未重跑整仓。最新 head 的完整门禁继续由 PR CI 执行,历史结果不冒充新 head CI。

pnpm test:unit --workspace-concurrency=1
首轮:根 runner 612 项及 27 个 workspace 通过;Desktop worker SIGSEGV,Mobile 两项图标 token 守门,maker-core 一项宿主环境断言失败。
修复:Mobile 改用等值图标 token;测试子进程移除继承的 CINDY_INPUT_HANDOFF_ROUTE;通过官方 runPlannedTests 按原集合重跑 3 个失败 workspace,Desktop 使用 forks / maxWorkers=2。
最终汇总:30 个 workspace 通过;Desktop 63894 项,Mobile 10732 项,maker-core 5985 项通过。未删除、跳过或弱化原断言;原有 skip 保留。

新增/改写测试均通过生产入口验证可观察结果,tier 为 unit;请求、原生关闭和账号交叉使用进程内集成 fixture,不依赖真实网络或登录。下表说明覆盖缺口与最小输入;逐文件耗时为 43579ce / 51eca5b 阶段的历史实测,仅供量级参考。本轮实际结果以上述合计和墙钟时间为准。

文件 依据、真实入口及最小失败输入 单文件耗时
chatServerInvitations.test.ts(Desktop) createInvite:构建区域、公开页路径/fragment 和回环端点;保留 Dev scheme,拒绝不安全端点 4.99s
BotGroupAvatars.test.tsx ChatInviteAvatar:1–5 成员轮廓、未知/坏图首字槽;防止图片失败改变身份顺序 1.71s
ChatInviteHost.test.tsx Host:登录暂隐、替换账号、旧 intent 回调与关闭后成功导航;旧闭包不得影响新目标 1.42s
ChatInviteView.ios.test.tsx 实际 SwiftUI View:输入/预览/加入状态,固定操作位置、尺寸变化及加入中禁用 1.08s
HomeTeammatesSection.test.tsx 真实首页:无电脑、空名册、加载、仅段头和折叠头像偏好下保留紧凑邀请;不出现空创建行,搜索无匹配隐藏;合并直接取主干条件时 3 项先红,修复后 17 项全绿 3.05s
TeammateCreateController.test.tsx 真实菜单 controller:无创建电脑仍可邀请;旧账号菜单回调不触发新账号操作 1.06s
chatInviteIntegration.test.tsx 真实 Host/Sheet/hooks/intent:手动预览后同链接、取消与前后台交叉;原代码会误提示并重弹 1.41s
chatServerClient.test.ts 真实 client:只 POST token 的预览、显式接受、可选摘要与人数、坏响应不导航;不获取完整成员名册 1.37s
nativeIntent.test.ts 原生深链入口:冷/暖与路径形式,残缺链接、登录/账号切换及旧关闭;保留 main 新增的中转入口 1.05s
themeTokens.test.ts 实际 token 导出:登记批准的邀请标题 22pt,其他字号保留原值 0.67s
useChatInvite.test.tsx 真实 hook:预览/取消、未知结果同 operationId 重试;旧账号四个操作、旧 dismissal 及 accept+edit 六项竞态先红后绿;手动客户端 scheme 两例先红后绿,截断链接不发请求 1.35s
useClipboardChatInvite.test.tsx 真实 hook:前台识别、权限、剪贴板变化、账号与后台迟到读取;不替换已确认中的另一邀请 1.38s

初始独立审查、修复复核与 PR 范围核对已完成;本次主干同步由 owner 核对全部邀请增量,保留主干的自建中转入口、群活动排序和本地化入群摘要。无用 onClosed prop、未使用导出、历史注释及三项旧有效期文案已清理;实际 model.closed() 保留。

手工验证

  • 业务验收提交 b6b10eac35b5588a9b8ad9234d6899f2c86c5860:分支 feat-mobile-group-invites、worktree Cindy-feat-mobile-group-invites,本任务 Metro 8084。身份 healthy / native-matched / target-fresh;实际页面标识 feat-mobile-group-invites@b6b10eac3 · v0.1.0 (2026072301)。
  • 上述业务提交在 iOS 26.5 独立 QA 模拟器上读取真实 Dev 邀请,头像集合、3 人和已加入状态正确;完整 Light/Dark 截图已实看并恢复 Light,取消后已返回 Home。原生指纹仍为 574cfd3a9e369a2652988e1a82be132e8472e943,未重建;邀请人示例名仅截图时在内存替换,已恢复。
  • 手动粘贴 cindydev:// 与 cindycn:// 均已在真实 Dev iOS 读取同一测试群的头像、3 人和已加入状态,保留 Edit Link。行为验证源码的 SHA256 与最终提交一致;提交后已刷新本 head 的页面标识、预览及双主题截图。
  • 本次同步验收摘要。
  • 51eca5b 已验证无在线电脑、首页仅段头仍可 Join Group、手动粘贴、同一外链不误提示且保留 Edit、Open Group 进入正确群并返回 Home;相关生产邀请增量本轮未变。本轮不冒称重新完整执行了这些路径。
  • 初始 43579ce 已完成真实 Dev 首次加入 2→3、唯一成员关系/唯一入群事件、取消回前台不重弹及冷启动剪贴板。初始验收摘要。新 head 未再创建未加入群。
  • Global/中国大陆公开邀请页此前 HTTP 200;未操作生产账号入群。QA Bot 无可用模型属于测试账号设置,未修改。

未执行的验证

  • Android 原生 UI、物理设备和生产账号没有本轮复验;Android 仍使用既有面板,自动化覆盖两平台逻辑分支。
  • 微信将邀请显示为可点击链接、浏览器唤起、下载安装后重开及生产区域真实端到端没有本轮证据;不声明已支持群邀请 Universal Links。网页 HTTP 200 和脚本注入的深链测试均不能代替这些验收。
  • 上一 head ad10e4e7f7397169c84a1c7af6f13bba6b0a29fe 的完整 CI 和 Greptile 5/5 已核实;新 head 的完整 CI、评分仍单独跟进,旧结果不沿用。手动 scheme 的唯一 finding 已修复、回复并 Resolve。辅助 Codex 在初始旧 head 未完成审查。
  • 更早历史 head 的 Windows CI 曾有两组失败:remote connection pool 的 EPERM 已在主干 a1532bf1c1 的同一用例复现;browserExtensionSlot 的桥接启动断言在 25ms 等待后未就绪,归因尚未确认。保留原失败证据,本轮新 CI 重新验证,不将历史失败写为通过。
  • 尚无独立客户端需求 Issue,维护者最终交接前保留该缺口;未擅自建单。

风险

风险分类

  • 无已知风险
  • SQLite / migration
  • system prompt
  • 协议兼容
  • 权限 / 安全 / 用户数据
  • 存量插件兼容(批准状态 / 指纹 / manifest 校验 / 安装布局 / 包格式)
  • 原生层 / fingerprint / OTA
  • 跨平台差异
  • 其他:

影响与回滚

  • 影响范围:Mobile 邀请呈现和当前账号的既有 Chat Server 调用;Desktop 创建邀请的链接形态。预览摘要可选,不扩大成员/历史授权;邀请口令与剪贴板仅存内存,不进入路由、日志或持久去重。
  • 加入结果未知时保留操作 ID;旧账号、旧面板与迟到请求不能关闭新面板或消费新账号回执。真实预览请求只发到当前账号配置的 Chat Server。
  • 无 package、lockfile、原生配置或模块输入变更,无需因本 PR 冷更。干净提交树的验收包 fingerprint 为 574cfd3a9e369a2652988e1a82be132e8472e943;该包最初已按干净 PR 工作树安装,并在 b6b10eac35 的业务验收时原生匹配;本轮未重新执行原生身份核对或安装。
  • 回滚 / 降级方式:回退本客户端提交即可恢复旧邀请入口/生成方式;不删除已加入群、成员、消息或服务器邀请。旧端仍可沿公开页唤起已有 scheme;不做运行期部署探测或环境自动切换。

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO)
  • UI 改动已在「UI 变化」注明引用的设计规范章节(不涉及 UI 则跳过)
  • 未提交凭证、令牌或授权文件
  • 已核对受影响的文档,行为变化涉及的旧结论已同步修订(不涉及则无需修改文档)
  • 已确认测试结果或说明未执行原因

Signed-off-by: nana <823073145@qq.com>
@nanaco666
nanaco666 requested a review from a team as a code owner October 29, 2026 16:22
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ⚠️ Failed 2026-10-29T16:26:03.792884Z
We couldn’t complete this review. Comment @codex review to try again.
43579ce PR opened
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@greptile-apps

greptile-apps Bot commented Oct 29, 2026 •

Copy link
Copy Markdown

RetriggerView in GreptileConfidence Score: 5/5

[Medium impact] 当前未发现阻止合并的问题。

Summary

手机新增统一的群邀请预览与确认加入流程,覆盖手动粘贴、深链和前台剪贴板识别。

  • Mobile invitations show a group preview before anyone joins.
  • One invitation panel handles Home, app links, and clipboard links.
  • Global and China desktop builds create public HTTPS invitation links.

本轮未发现需要新增评论的问题;未执行测试或原生界面复验。

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
  A[手动粘贴] --> D[统一邀请面板]
  B[原生深链] --> C[内存中的邀请目标]
  E[前台剪贴板识别] --> C
  C --> F{登录与账号就绪}
  F -->|是| D
  D --> G[只读预览群身份]
  G --> H{用户选择}
  H -->|取消| I[清除本次目标]
  H -->|确认加入| J[当前账号发起加入请求]
  J -->|结果未知| K[沿同一请求重试]
  K --> J
  J -->|成功| L[面板关闭后打开群聊]
  H -->|已是成员,打开群聊| L
Loading

Reviews (8) · Last reviewed commit: "chore(mobile): 同步主干并解决群邀请冲突" · Reviewed by Greptile

@MagicLizi

Copy link
Copy Markdown
Contributor

@nanaco666 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

@MagicLizi MagicLizi added status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Oct 29, 2026
Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

已合并 main@a1532bf1c1 并解除冲突,当前提交 51eca5b0448d0d03ca3c1897035d1861cd88b38f。同时保留主干首页折叠/头像偏好和无电脑邀请入口;256 项相关测试、Mobile/Desktop 类型检查及 iOS Dev 入口、真实预览、打开群聊与返回回归通过。PR 正文已更新当前提交的完整浅色/深色截图和验证边界,等待本提交的 CI 与审查。

@greptileai Please review the latest changes at commit 51eca5b.

Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

已处理主干再次更新产生的测试、五语言与台账冲突并推送 69af80da8492774d4facb1fac4874210f9582613。259 项相关测试、Mobile/Desktop 类型检查及当前 iOS Dev 真实邀请预览和完整 Light/Dark 截图通过,生产邀请增量与上一轮审查一致;已重新核对 GitHub 无合并冲突。上一条修复后的状态不代替本次新 head 检查。

@greptileai Please review the latest changes at commit 69af80d.

Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

@greptileai Please review the latest changes at commit 9623d2a.

Comment thread apps/mobile/src/chat/useChatInvite.ts Resolved
Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

@greptileai Please review the latest changes at commit b6b10ea.

nana added 2 commits October 30, 2026 12:06
Signed-off-by: nana <823073145@qq.com>
Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

@greptileai Please review the latest changes at commit a83d3e6.

Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

@greptileai Please review the latest changes at commit ad10e4e.

@MagicLizi MagicLizi removed the status:conflict 与目标分支有冲突(review-pr 自动维护,仅展示) label Oct 30, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

PR #7930 独立代码审查报告(standard 档)

  • PR: feat(mobile): 支持群邀请预览与确认加入 #7930 「feat(mobile): 支持群邀请预览与确认加入」
  • 审查 head ad10e4e7f7397169c84a1c7af6f13bba6b0a29fe / base d8ccef49fa296eb20880cf44923eec9df2032fe1(main)
  • diffHash 949491465499f695526f3393c1083f462e95ec92637a1b0a1a02968906986eb1(与冻结证据一致,复用同 head/base diff)
  • 档位 standard(不跑 security-scan;security.softHits 1 条已在下文逐条定性)
  • 维护者确认门:product / rules / arch 三类触发均已由最终维护者集合成员 zqchris 以 GitHub Approve 放行(2026-10-29T16:22:48Z),无待办讨论 issue;thread 0 条未解决;CI 全绿。

Findings

没有 P0/P1。(P2 级风格建议按规则不列不阻断。)

安全软命中定性:apps/desktop/src/main/maker-ipc/__tests__/chatServerInvitations.test.ts:109(email 命中)实为 URL userinfo 测试桩 https://user:fixture@…(拒绝带用户信息端点的负例),非真实凭证或个人数据,放行。

Rule coverage

按 rule-map 读取并逐项核对(只审本次新增/修改代码):

  • AGENTS.md、docs/dev-rules/development-workflow.md、.github/PULL_REQUEST_TEMPLATE.md:PR 模板三段齐全,验证记录具体(命令 + 项数 + 墙钟),未执行项(Android 原生、微信唤起、生产端到端)如实声明未验证,未冒充通过;DCO 各 commit 均带签名。
  • docs/dev-rules/mobile-development.md(冷更边界):diff 不含 app.json / app.config.js / eas.json / apps/mobile/package.json / plugins/ / modules/ 等指纹输入,无 lockfile、依赖或原生模块变动,不触发冷更;PR 正文有原生 fingerprint 保持记录。
  • docs/dev-rules/remote-and-mobile-adaptation.md:新增 Mobile 入口(首页加号「加入群聊」、深链 +native-intent.ts、前台剪贴板识别)与常驻 ChatInviteHost 均在内存暂存目标、不落盘口令;账号切换/迟到回调有 owner generation 围栏(isMobileAuthOwnerCurrent、state.owner 比对),旧账号结果不得导航或消费新账号回执。
  • docs/dev-rules/protocol-compatibility.md(本次同步更新,与实现一致):公开页链接 <deviceLinkBase>/chat-invite/join#<token>[?app=cindy|cindycn] 由 parseChatInvitationToken 统一解析,token 只在 fragment;链接主机只验形状、从不作为请求地址或切换账号/服务端的依据;口令只以 POST 正文发往当前账号的 Chat Server(/invite-links/preview、/invite-links/accept,与 Desktop chatServer.ts 既有合同逐字段一致:{token} / {token, operationId},validInvite 语义(expiresAt=null 必须 reusable=true)两端等价)。
  • Desktop 侧 chatServer.ts:invitationPage() 对 deviceLinkApiBaseUrl 做形状校验(http/https、无 userinfo/query/hash、非本机回环),非法端点直接失败(ok:false)而不是伪装成 scheme 回退;dev 构建与回环端点保留旧 cindy:// 链接;createInvite 仍先调用服务端创建接口,token 43 位 base64url 正则先行校验。Global→app=cindy、CN→app=cindycn 的构建身份提示与 brandRegion 语义一致。
  • 凭证与用户数据(credentials-and-local-storage.md):剪贴板内容、邀请口令、去重集合全部只存内存(handledLinks/lastVersion ref),不进路由、日志或持久化;剪贴板读取仅前台、仅识别完整链接、iOS 变化计数去重避免重复授权提示;预览只发 token,不拉成员名单、不外发其它数据。
  • UI / DESIGN.md(§3/§4/§5/§15)与 mobile-design-guide.md「群邀请 V9」:颜色全部走 useTheme 语义 token(Light/Dark 同一 token 流,双模式由主题系统承载,附双主题截图);新增 typeScale.inviteTitle=22 登记在册并有 themeTokens.test.ts 守门;50pt 胶囊输入、88pt 头像集合、22/28 群名、13/18 人数与批准的 V9 说明一致;iOS 用 Expo 原生 BottomSheet/TextInput、Android 复用 CompanionSheet,无硬编码色值、无自造组件顶替设计系统组件。
  • i18n:en/ja/ko/zh-CN/zh-TW 五语言 groupChat.invitation.* 齐全,pnpm check:i18n-glossary 通过。
  • 固定问题:单一目的(手机群邀请预览/确认 + Desktop 邀请链接形态 + 合同文档),描述与 diff/测试一致;共享符号(parseChatInvitationToken、chatHttpsUrl、chatMemberAvatar、botGroupMemberAvatar)的调用方与回退路径已核;错误路径(format/invalid/expired/forbidden/auth/network/uncertain)与超时(预览 15s / 加入 30s)、AbortController、幂等 operationId 重试均覆盖测试;无新增依赖;无流程塞进 Core 或重复实现既有能力。

Verification

实际执行(worktree 内,完整日志落盘,退出码取命令自身):

  • pnpm install --frozen-lockfile --prefer-offline --prod=false → EXIT=0(pr-7930-install.log)
  • Mobile 11 个邀请相关测试文件 vitest run --maxWorkers=1 → EXIT=0,212 项全部通过,5.83s(pr-7930-mobile-tests.log)
  • Desktop chatServerInvitations.test.ts vitest run --maxWorkers=1 → EXIT=0,50 项全部通过(pr-7930-desktop-tests.log)
  • pnpm --filter mobile run typecheck → EXIT=0(pr-7930-typecheck-mobile.log)
  • pnpm --filter desktop run typecheck → EXIT=0(pr-7930-typecheck-desktop.log)
  • pnpm check:i18n-glossary / check:test-hygiene / check:dev-docs / check:design-inventory → 均 EXIT=0(对应 pr-7930-check-*.log)

未执行:Android 原生 UI 实机、微信唤起/安装续接、生产区域端到端(PR 正文已声明未验证,非本 PR 范围);security-scan.mjs(standard 档不执行)。UI 证据为 PR 正文内嵌 Light/Dark 完整截图(804×1748,含加入后 3 人/已加入状态),与 diff 的身份区/操作区一致,未做下载渲染逐项对照。

Intent alignment

  • 原目标(PR 标题/正文,关联 docs/product-rules/bot-group-chat.md §8.4 合同与服务端配套 xindong/cindy-server#1131):手机收到群邀请后先看真实群身份再显式确认加入;首页手动粘贴、深链、前台剪贴板共用同一邀请面板;取消/换账号/重复打开不留错误提示或错误导航;Desktop 在 Global/中国大陆生成公开页 HTTPS 邀请、Dev 保留既有 scheme;不包含微信点击唤起完整验收、话题/上传/推送等。
  • 初始实现:43579ceb017be8c47048f0835c11fafdc32292f7(feat,36 文件,已实读该 revision 的 useChatInvite.ts / chatInviteIntent.ts / ChatInviteHost.tsx / chatServer.ts 对应代码)。
  • 待合并 head:ad10e4e7f7397169c84a1c7af6f13bba6b0a29fe。中间 5 个 chore: 同步主干… 提交只做 base 合流并保留主干侧行为(首页折叠/头像偏好、自建中转入口、本地化入群摘要、台账再生成),邀请业务增量未变(PR 正文有 36 文件增量哈希一致性记录)。
  • 唯一行为修复 b6b10eac35b5588a9b8ad9234d6899f2c86c5860:手动粘贴 cindycn:// / cindydev:// 客户端 scheme 邀请被误报「链接不完整」,改为读取前复用 parseChatInviteLink 归一化,保留裸邀请码与手动编辑。对应 Greptile thread(useChatInvite.ts:53,P2)作者回复修复并已 Resolve——缺陷修复服务于原目标,不属偏离;未据 bot 意见扩大功能范围。
  • 对照结论:核心功能(预览→显式加入、三入口一面板、登录续接与账号隔离、幂等重试、Desktop 链接形态按区域切换)与初始实现一致,验证口径还收紧(非法公开端点从静默 scheme 回退改为显式失败);明确边界(不声明微信 Universal Link、不入群即只读预览、不持久化口令)在实现与文案中保持。无偏离、无未落实的讨论要求、无扩范围。

Overall

pass —— 没有 P0/P1。 可进入受保护 Approve 与合并。
合并后注意:机器人静默期超时放行(copilot-pull-request-reviewer、chatgpt-codex-connector 未在静默窗口内表态,其意见可能在合并后到达);Android 原生 UI 与微信唤起链路按 PR 声明仍待单独验收。

@MagicLizi

Copy link
Copy Markdown
Contributor

@nanaco666 👋 这个 PR 目前与 main 有合并冲突,auto-review 因此暂时跳过、没法继续审查 / 合并。

请在本地 merge 最新的 origin/main 解决冲突后推送;冲突解除后,下一轮 auto-review 会自动重新处理这个 PR。

Signed-off-by: nana <823073145@qq.com>

Copy link
Copy Markdown
Contributor Author

已在 16137ae2d8fc8c4c3b86bb173d715552a0bd32f1 同步 main@4146107162e2a78a84b4972e06ed9ef98fa4429a,解决 Mobile Chat Server client、对应测试和设计台账的 3 处文件冲突。保留两边逻辑及既有测试,PR 仍为原 36 文件,未扩需求、未合并。

Mobile 433 项与 Desktop 邀请 50 项定向测试、两端类型检查和适用检查通过。新 head CI 已启动;旧 head 的 5/5 不沿用。

@greptileai Please review the latest changes at commit 16137ae.

@MagicLizi

Copy link
Copy Markdown
Contributor

PR #7930 独立代码审查报告(head 16137ae)

审查分档:standard(独立审查 agent,rule-map 逐项对照)。结论:pass,没有 P0/P1。

Findings

  • 无 P0/P1。逐项核验要点:
    • 凭证/隐私软命中定性:apps/desktop/src/main/maker-ipc/__tests__/chatServerInvitations.test.ts:109 的 email 形软命中是测试桩 URL(https://user:fixture@…,占位符 fixture),且该行本身就是「端点带用户信息必须拒绝」的负例断言——不是真实凭证/个人数据,放行。
    • 邀请口令只存在于 URL fragment / 请求正文,不进路由状态、日志或落盘:chatServer.ts 生成链接 pathname 不含 token(有断言),chatInviteIntent.ts 明确注释「Never a route parameter」,useClipboardChatInvite.ts 的去重集合与剪贴板内容仅驻内存;无持久化。
    • 链接主机只校验形状、从不作为请求地址或切区依据(packages/device-link/src/chatInvitation.ts、chatServerClient.ts 只向当前账号 Chat Server 发 token),无新增数据外发面。
    • expiresAt===null ⇒ reusable===true 的校验移动端与 Desktop validInvite 一致;未知人数不当 0、坏图保留首字槽位、摘要≤5 且不授予成员名单读取,符合 §8.4 合同。
    • UI 颜色全部走语义 token(useTheme().colors + typeScale/radius/lineSpacing),新档 inviteTitle: 22 有 themeTokens.test.ts 登记;Light/Dark 均由 token 承载,无硬编码色值(对新增文件 grep #hex/rgb( 为零命中)。
    • 无冷更输入变更:diff 未触及 app.json/app.config.js/eas.json/apps/mobile/package.json/modules//plugins//pnpm-lock.yaml(git diff --stat 空);@expo/ui、expo-clipboard、expo-crypto 均为既有依赖。
    • 手机端收到邀请仅在用户明确点「接受并加入」后才调用 accept;已是成员只展示并「打开群聊」;同一 operationId 重试、迟到结果按 owner/generation 围栏丢弃(useChatInvite.ts + 完整单测覆盖)。
    • Greptile 唯一 thread(P2:手动粘贴 cindycn:///cindydev:// 误报「链接不完整」)已由 b6b10ea 修复(read() 复用 parseChatInviteLink 归一 scheme,保留裸口令),修复在当前 head 中核实无回归;thread 已 Resolve。P2 不作为阻断。
    • 机器人意见差异如实说明:Codex review 显示 failed(未能完成审查、无待处理 findings);Greptile 结论「未发现阻止合并的问题」。另 botSettle 超时放行:copilot-pull-request-reviewer、chatgpt-codex-connector 至今未对当前 head 表态,其意见可能在合并后到达(非阻断,按超时规则放行)。

Rule coverage — 读取的规则文件及逐项结论

  • AGENTS.md / docs/dev-rules/development-workflow.md / .github/PULL_REQUEST_TEMPLATE.md:PR 模板三大段齐全、变更类型勾选、验证与风险边界如实(含「微信点击唤起未验收」等未验证声明);P0/P1/P2 口径按其定义执行。
  • docs/dev-rules/mobile-development.md「冷更边界」:无 runtime fingerprint 输入改动,不触发冷更;不需要冷更批准。
  • docs/dev-rules/remote-and-mobile-adaptation.md Review 清单:无新增 IPC/push(走既有 Chat Server HTTP 请求器);手机版入口/UA 适配即本 PR 主体;Description 给出三选一结论;不触及断链恢复半径。
  • docs/dev-rules/credentials-and-local-storage.md Review 清单:无仓库/工作区写盘;测试无真实凭证;剪贴板内容、邀请口令、去重摘要均不落盘,生命周期限内存,测试断言覆盖。
  • docs/dev-rules/engineering-conventions.md Review 清单:无裸 console.log;main 侧改动带主路径+错误路径测试(chatServerInvitations.test.ts 50 例);UI 文案全部走 t()、5 语言齐全(pnpm check:i18n 14496 key 一致,pnpm check:i18n-glossary 无新增违规);新增模块均带职责注释。
  • docs/dev-rules/architecture-invariants.md Review 清单:无 package 依赖方向变化、无布局树改动、无运行时动态 import。
  • docs/design-rules/DESIGN.md / cindy-design-system.md(UI):语义 token 全覆盖、复用既有组件基座(CompanionSheet/ContextSheetRow/RemoteCompanionAvatar/原生 BottomSheet)、50pt 胶囊 CTA、44pt 关闭目标,无硬编码颜色/自造组件顶替设计系统的硬伤;PR 正文附浅色/深色截图证据(存在性已核,未逐像素比对)。双模式由 token 承载。
  • docs/product-rules/bot-group-chat.md §8.4(PR head 正文)与 docs/dev-rules/protocol-compatibility.md(PR head 正文):本次对判据的修改是新增手机邀请合同与生成出口切换说明,不放宽既有拒绝条件(无效链接、到期、权限拒绝路径不变),也未借机为本 PR 开脱;与实现、测试一致。规则文档变更已由维护者确认门(rules 触发,zqchris Approve)放行。
  • docs/product-rules/core-product-principles.md / 任务对话命名:UI 文案用「群聊/邀请/消息」语义与术语表无冲突(glossary 门禁通过)。
  • 固定问题 1–9 逐项:单一目的(手机群邀请预览+确认加入及配套链接生成);共享符号(parseChatInvitationToken/CHAT_INVITATION_PATH/CURRENT_CINDY_REGION/remotePresentation.clipboardVersion)的调用方与错误路径已追踪;权限/凭据/跨端安全;无新增依赖;测试覆盖 mobile/desktop/i18n/协议路径;无组织流程塞进 Core;UI 证据与 diff 一致;无冷更;仅 P2 不报告。

Verification — 实际运行的命令、结果、未执行项及原因

(worktree = PR head 16137ae,pnpm install --frozen-lockfile EXIT=0)

命令 结果 退出码
npx vitest run src/main/maker-ipc/__tests__/chatServerInvitations.test.ts(desktop) 50 passed 0
npx vitest run 11 个移动定向测试文件(ChatInviteHost/ChatInviteView.ios/chatInviteIntegration/useChatInvite/useClipboardChatInvite/chatServerClient/nativeIntent/BotGroupAvatars/HomeTeammatesSection/TeammateCreateController/themeTokens) 227 passed 0
pnpm --filter mobile run typecheck 通过 0
pnpm --filter desktop run typecheck 通过 0
pnpm check:i18n 14496 key 五语言一致(存量警告 1389 处,与本 PR 无关) 0
pnpm check:i18n-glossary 无新增违规(存量 proposed 术语告警 18 处,不阻断) 0

未执行:iOS/Android 真机原生验收(PR 正文已声明原生验收由主控统一完成、微信点击唤起未验收);heavy 档 security-scan(本 PR 为 standard 档,不适用)。CI client-ci、pr-design-basis 均绿(gate.ci.status=pass)。

Intent alignment

描述来源:PR 正文(当前版,2026-10-30 随提交更新)+ docs/product-rules/bot-group-chat.md §8.4 需求合同。初始实现 SHA:43579ceb017be8c47048f0835c11fafdc32292f7(首个提交即完整功能批次,36 文件 +2062/−55,含移动端邀请流、Desktop 生成出口、测试与文档);待合并 head:16137ae2d8fc8c4c3b86bb173d715552a0bd32f1。

原目标/初始行为 最终行为与影响 代码/提交证据 变化依据或待确认问题
手机收到群邀请先看真实群身份、显式确认加入;手动粘贴/深链/剪贴板共用一个面板 不变,且覆盖登录续接、换账号围栏、取消与去重 apps/mobile/src/chat/*(初始 43579ce = 最终行为) 一致
Desktop Global/中国大陆生成公开页 HTTPS 邀请、Dev 保留 scheme 不变;Invalid/缺失端点显式失败而非伪装成功 apps/desktop/src/main/maker-ipc/chatServer.ts:invitationPage() 一致
手动粘贴 cindycn:///cindydev:// 完整链接应可预览(Greptile thread 提出的缺陷) read() 归一 scheme 后解析,保留裸口令/编辑 b6b10ea(useChatInvite.ts + 2 例回归) 围绕同一目标的缺陷修复,非偏离
同步主干的 8 个 merge/sync 提交 仅解决冲突、保留既有合同,无行为扩范围 51eca5b…16137ae2 各提交仅冲突解决/台账重建 一致

结论:一致,无确认偏离。多轮修复未改变用户原目标;核心目标(预览不入群、显式确认、账号隔离、去重、关闭后导航)均可在当前 head 代码与测试中核实。

Overall

pass(明确:没有 P0/P1)。零 P0/P1、原意一致性复核完成、无待裁定核心方向问题;合并前提(CI 全绿、thread 全 Resolve、维护者确认门 released、无冲突、无受保护路径、无冷更)均已核验。备注:机器人静默期按超时放行,copilot-pull-request-reviewer / chatgpt-codex-connector 的意见可能在合并后到达。

@MagicLizi
MagicLizi merged commit bc354b1 into makecindy:main Oct 30, 2026
17 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants