Skip to content

feat(desktop): 支持插件声明一级主视图 - #3219

Open
Evol1213 wants to merge 5 commits into
makecindy:mainfrom
Evol1213:codex/plugin-main-view
Open

feat(desktop): 支持插件声明一级主视图#3219
Evol1213 wants to merge 5 commits into
makecindy:mainfrom
Evol1213:codex/plugin-main-view

Conversation

@Evol1213

@Evol1213 Evol1213 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

这次改了什么

摘要

为 Ghost 插件增加通用的一级主视图能力。插件可以在 ghost.json 中通过 main-view slot 与 mainView 元数据声明一个由 Cindy 承载的管理界面;Cindy 负责协议校验、侧边栏导航、显示偏好和沙箱 WebView,业务逻辑仍由插件实现。

这是一项通用插件基础设施能力,不与 xd-sites、其 API 或 OIDC 流程耦合。

变更类型

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

范围

  • 关联 Issue / 需求:插件一级主视图基础设施
  • 本 PR 包含:Ghost main-view / mainView manifest 契约;系统线性图标枚举;展开与折叠侧边栏入口;主视图路由和沙箱承载;插件详情页显示开关;作者手册、兼容性文档、五语文案和自动化测试
  • 明确不包含:任何具体插件管理面板;xd-sites API、OIDC 或业务模型;根级插件品牌图片 icon 协议变更;cindy-xd-plugin 改动;Desktop-only 的 library 槽公共协议扩面
  • 用户可见变化:启用且声明主视图的插件可以在侧边栏显示插件自定义名称的一级入口;用户可在插件详情页关闭或重新打开该入口。主视图不参与插件卡片或详情页原有主动作判断
  • 是否存在 breaking change:无。未声明新能力的存量插件保持原有安装、批准、启用和操作逻辑,无需重装、重新确认或重新配置

main-view 插件必须声明合法 SemVer 的 minCindyVersion。首个正式支持版本尚未确定,本 PR 不提供占位版本;插件发布时需填写最终裁决的正式 Cindy 版本。

Review 修复

  • library 是既有 Desktop-only 能力,本 PR 不把它加入跨消费者 plugin-protocol;文档登记该唯一例外,避免在正式支持版本未确定时猜测版本门槛。
  • 主视图显示偏好由 Renderer localStorage 迁到 Main 的 owner-scoped sidebar settings store;写入经过 owner/generation fence、跨进程锁、原子合并和多窗口广播。Renderer 只镜像 Main 快照,并忽略旧 generation 的广播与迟到结果。
  • 新增同一 owner generation 前进时丢弃排队旧写入,以及输入边界、持久空 override、多窗口广播等回归测试。
  • mainView.html 新增与公共协议一致的 Windows 设备保留名校验和 assets/AUX.html 回归测试;只收紧本 PR 新字段,不改变旧 entry / panel / settingsHtml 的存量接受范围。

UI 变化

  • 侧边栏新增由插件声明的一级主视图入口,复用 Cindy 原生导航项的尺寸、对齐、激活态和 hover 行为;折叠态使用同一系统线性图标并提供可访问名称
  • 插件详情页新增“在侧边栏显示”开关;该设置只控制入口可见性,不改变插件启用状态或原有主动作
  • 效果证据:已使用本地测试插件在 macOS 开发环境完成手工检查;本地测试插件及 HTML 预览不属于本 PR 交付内容。以下 HTML 摘要展示实际交互结构,便于在不引入测试插件文件的前提下复核侧边栏入口与详情页开关:
<nav aria-label="插件主视图">
  <button aria-current="page">
    <svg aria-hidden="true"><!-- mainView.icon 对应的 Cindy 系统线性图标 --></svg>
    <span>站点管理</span>
  </button>
</nav>
<label>
  <span>在侧边栏显示</span>
  <input type="checkbox" role="switch" checked>
</label>
  • 引用的设计规范:
    • docs/design-rules/DESIGN.md §10:新增颜色使用语义 token,并按 Light / Dark 双模式契约实现
    • docs/design-rules/DESIGN.md §11:侧边栏与设置文案保持简短、描述结果,不暴露内部 slot 名称
    • docs/design-rules/DESIGN.md §14.6:折叠态图标入口保留可访问名称与提示语义
    • docs/design-rules/DESIGN.md §15.10:导航和开关沿用中性状态,不引入品牌红作为普通主操作

怎么验证的

自动验证

NODE_OPTIONS='--experimental-webstorage --localstorage-file=<temp>' TMPDIR=/private/tmp pnpm test:unit:related
结果:通过。由于 fork 的 origin/main 与上游分叉,本地 planner 保守退回全仓 unit 超集;Desktop、Mobile、全部 required packages 与 runner 均通过。

pnpm --filter desktop run --if-present typecheck
pnpm --filter @cindy/plugin-protocol build
pnpm check:i18n
pnpm check:i18n-glossary
git diff --check
pnpm check:dco
结果:全部通过

说明:本机默认 Node 22.12 缺少主干测试使用的 Zstd API,因此门禁使用仓库允许的 Node 24,并按 vitest.config.ts 的既有 WebStorage 兼容路径切换到 forks;测试后已把 better-sqlite3 恢复到默认 Node 22 ABI。

手工验证

  • macOS Desktop 开发环境安装本地测试插件,检查插件卡片和详情页原有主动作不受 mainView 影响
  • 检查详情页显示开关、侧边栏展开 / 折叠入口、图标、文字对齐、hover / active 状态及进入主视图后的路由
  • 检查同一测试插件同时声明 settings、tool / command 与 mainView 时,原有入口和调用逻辑保持独立

未执行的验证

  • 未在 Windows 实机验证
  • Dark 模式使用现有语义 token 实现并由测试覆盖状态类名,但未进行 Dark 实机目检

风险

风险分类

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

影响与回滚

  • 影响范围:Desktop Ghost manifest 解析、插件详情页、侧边栏导航与插件 HTML 沙箱承载;不涉及 Mobile、服务端、数据库 migration 或原生层
  • 协议兼容:main-view / mainView 是可选新增能力;跨消费者协议正本、Desktop runtime validator、作者手册和测试已同步。既有 Desktop-only library 不在本 PR 中扩入公共协议
  • 安全边界:主视图复用既有插件 HTML 沙箱与 Host 能力边界,不新增权限、凭证桥、网络代理或文件能力;新增偏好 IPC 校验可信 sender、参数边界与 owner generation
  • 配置语义:默认显示;只持久化隐藏插件 id 集合。恢复显示即移除对应 id,未自定义用户继续跟随默认值
  • 存量插件影响:无。旧插件在升级后无需重装、重新批准或重新配置;新可见性偏好默认开启,仅对实际声明并获准启用 main-view 的插件生效
  • 跨平台:Renderer 实现共用,Windows 单测在前一版提交的 CI 已通过;本地只完成 macOS 手工验证,更新后的 Windows 结果以后续 CI 为准
  • 回滚 / 降级方式:回滚本 PR 即可移除新入口和 manifest 能力;未声明该能力的插件及其既有数据不受影响。由于本 PR 修改插件基座,合并前需要仓库指定把关人明确 Approve

提交前检查

  • 已 review 完整 diff
  • 每个 commit 都带 DCO 签名(git commit -s,见 DCO)
  • UI 改动已在「UI 变化」注明引用的设计规范章节
  • 未提交凭证、令牌或授权文件
  • 已补充必要文档
  • 已确认测试结果或说明未执行原因

Windows CI 稳定性修复

  • device-link 的“确认 ACK 丢失后自动有界重发”用例改为 Vitest fake timer 显式推进,消除 Windows runner 对 20ms 真实定时器的调度抖动;没有修改生产状态机、协议、默认超时或重试预算。
  • 协议不变量继续覆盖:首个确认 ACK 被丢弃、无额外业务流量即可自动恢复、重试次数有界、确认不跨 linkRequestId 代际、恢复后可靠业务正常往返。
  • 故障半径:触发条件仅为该测试中的单个确认重试定时器调度;修复动作仅限测试时钟;生产 1:N peer 拓扑行为零变化,现有多 peer 隔离用例继续通过。
  • 新增验证:目标用例连续运行 30 次通过;@cindy/device-link 217 项单测与 TypeScript build 通过;使用仓库指定 Node 22.22.3 和规范化临时目录运行 pnpm test:unit:related -- --workspace-concurrency=1,所有 required workspace 通过。

@Evol1213
Evol1213 requested a review from a team as a code owner August 21, 2026 21:14
@greptile-apps

greptile-apps Bot commented Aug 21, 2026

Copy link
Copy Markdown

Greptile Summary

本 PR 为 Ghost 插件新增由 Cindy 承载的一级主视图能力,并保持既有 Desktop-only library 协议边界不变。

  • 在公共协议与 Desktop 校验器中加入配对的 main-view / mainView 契约、最低版本要求、路径及图标校验
  • 新增插件主视图路由、沙箱 WebView、展开与折叠侧边栏入口,以及详情页显示开关
  • 将显示偏好持久化到 Main 进程的 owner-scoped sidebar settings store,并加入 generation fence、多窗口广播与输入校验
  • 补充作者手册、协议兼容性说明、五语文案及相关自动化测试

Confidence Score: 5/5

当前未发现仍需阻止合并的故障,PR 看起来可以安全合并。

先前关于 library 缺少版本门槛的问题已通过撤回其公共协议扩面解决:共享协议不接受 library,Desktop 本地校验仍保留既有支持,且兼容性文档已明确记录该例外;当前没有遗留的阻塞性故障。

Important Files Changed

Filename Overview
packages/plugin-protocol/src/manifest.ts 新增跨消费者 main-view 清单契约与最低版本约束,同时保持 library 不进入公共 slot 集合。
apps/desktop/src/shared/ghost.ts 同步 Desktop runtime 的主视图校验、WebView 入口白名单和本地化处理,并保留既有 Desktop-only library 支持。
apps/desktop/src/main/sidebarSettingsStore.ts 将隐藏主视图插件 ID 纳入 owner-scoped 设置存储、并发写入防护和多窗口广播。
apps/desktop/src/renderer/cindy-brain/mainViewVisibilityStore.ts 镜像 Main 进程快照并处理主视图可见性更新及 owner generation 切换。
apps/desktop/src/renderer/features/plugin/GhostMainViewHost.tsx 使用既有 Ghost WebView 安全边界承载插件一级主视图。
apps/desktop/src/renderer/components/sidebar/GhostMainViewNavEntries.tsx 为已批准、启用且可见的插件主视图生成展开与折叠侧边栏入口。
docs/dev-rules/protocol-compatibility.md 明确记录 library 是唯一 Desktop-only slot 例外,并区分公共的 main-view 能力。

Sequence Diagram

sequenceDiagram
  participant Plugin as Ghost 插件清单
  participant Main as Desktop Main
  participant Store as Sidebar Settings Store
  participant Renderer as Renderer
  participant WebView as 沙箱 WebView
  Plugin->>Main: 声明 main-view / mainView
  Main->>Main: 校验协议、版本与 HTML 入口
  Main-->>Renderer: 提供已批准且启用的主视图
  Store-->>Renderer: 广播 owner-scoped 显示偏好快照
  Renderer->>Renderer: 渲染侧边栏入口与详情页开关
  Renderer->>WebView: 进入插件主视图路由
  Main->>WebView: 校验分区、入口白名单与插件状态
Loading

Reviews (5): Last reviewed commit: "test(device-link): stabilize link confir..." | Re-trigger Greptile

Comment thread packages/plugin-protocol/src/manifest.ts Outdated

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 2c8e363623

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/renderer/lib/sidebarOwnerStorage.ts Outdated
@MagicLizi

Copy link
Copy Markdown
Contributor

@Evol1213 👋 这个 PR 还有 2 条 review conversation 没 resolve(packages/plugin-protocol/src/manifest.ts / apps/desktop/src/renderer/lib/sidebarOwnerStorage.ts),auto-review 因此暂时跳过、没法继续审查 / 合并。

如果你已经按评论改完或回应了,请到对应 thread 上点 Resolve conversation;全部 resolve 后,下一轮 auto-review 会自动重新审查这个 PR。

@MagicLizi MagicLizi added awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:plugin-base 改动碰到插件基座(review-pr 自动维护,仅展示) touches:product-ui 改动碰到产品 / UI 面(review-pr 自动维护,仅展示) touches:rules 改动碰到规则 / 规范文档(review-pr 自动维护,仅展示) labels Aug 21, 2026
@MagicLizi

Copy link
Copy Markdown
Contributor

这条 PR 需要维护者确认后才能合并。

它加了插件可声明的一级主视图(侧边栏入口 + 详情页显示开关),同时改到 Ghost manifest / 插件协议 / 基座投影,确认门当前在拦的是 product,并叠了 pluginBase。

请维护者在本 PR 上 Approve;若要改,请 Request Changes。讨论 issue:#3220

@MagicLizi

Copy link
Copy Markdown
Contributor

命中 UI 路径(apps/desktop/src/renderer/cindy-brain/GhostPermissionList.tsx / apps/desktop/src/renderer/cindy-brain/ghostMainViews.ts / apps/desktop/src/renderer/cindy-brain/ghostPanelBody.tsx 等)但 description 未附界面效果证据——建议补充改动后效果:截图/录屏,或改动后界面的 HTML 页面(```html 代码块、.html 附件或在线预览链接),便于确认界面符合 DESIGN.md 设计规范

Signed-off-by: xutianqi <xutianqi@xd.com>
Signed-off-by: xutianqi <xutianqi@xd.com>
@Evol1213
Evol1213 force-pushed the codex/plugin-main-view branch from 2c8e363 to fb09310 Compare August 21, 2026 22:38
@Evol1213

Copy link
Copy Markdown
Contributor Author

@codex review

@Evol1213

Copy link
Copy Markdown
Contributor Author

关于 Greptile 第二轮摘要再次提到的 library 最低版本:已复核,当前不改 Desktop validator。library 是本 PR 之前已存在的 Desktop-only 能力;本 PR 已撤回它在 packages/plugin-protocol 中的意外扩面,因此不会新增分发端接受范围。此时强制既有 Desktop manifest 补 minCindyVersion,一方面没有可填写的正式版本,另一方面会让已安装且未声明该字段的存量插件失效,违反插件兼容红线。后续应在 library 正式进入跨消费者发布契约、版本确定且迁移方案就绪时单独处理。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fb0931082d

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Comment thread apps/desktop/src/shared/ghost.ts Outdated
Signed-off-by: xutianqi <xutianqi@xd.com>
@Evol1213

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Keep it up!

Reviewed commit: ab8ef7e664

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

@Evol1213

Copy link
Copy Markdown
Contributor Author

已补充 PR Description:新增当前 HEAD 的 Windows 保留路径修复记录,并在「UI 变化」中加入可直接审阅的 HTML 结构证据。测试插件与本地预览仍不纳入交付代码。

@Evol1213

Evol1213 commented Aug 21, 2026

Copy link
Copy Markdown
Contributor Author

CI 复核结论(已在最新 HEAD a46c953 再现):两轮 Windows unit tests (1/2) 都只失败于 packages/device-link/src/tests/client.test.ts 的既有时序用例“新确认阶段:确认 ACK 丢失后自动有界重发,无需等待下一条控制端业务”,报错均为 MemoryRelay.settleUntil timed out(157 项中 156 通过)。PR 文件列表不包含 packages/device-link、CI/测试调度或依赖;同一 base 6ab605f 的 main client-ci 完整通过,因此判断为与本 PR 无关的 Windows 时序 flake,不应在本 PR 修改 device-link 或放宽测试。失败运行:32534909750、32537181376。当前账号无 Actions rerun 权限,请维护者重新运行失败 job。

Signed-off-by: xutianqi <xutianqi@xd.com>
@Evol1213

Copy link
Copy Markdown
Contributor Author

@codex review

补充独立复核:发现规则文档把 library 写成了整个 Desktop validator 的“唯一例外”,范围过大。a46c95317 已将口径精确收窄为 GHOST_SLOTS 槽位集合中的唯一 Desktop-only 例外,并明确不代表两套 validator 的其它历史字段语义完全同构。独立 reviewer 复核后确认该 P1 已解决。

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. 🚀

Reviewed commit: a46c953173

ℹ️ About Codex in GitHub

Codex has been enabled to automatically 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".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".

Signed-off-by: xutianqi <xutianqi@xd.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

awaiting-discussion 等待维护者讨论(review-pr) touches:core 改动碰到架构核心路径(review-pr 自动维护,仅展示) touches:large-diff 改动量较大(review-pr 自动维护,仅展示) touches:plugin-base 改动碰到插件基座(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.

2 participants