37 KiB
安装中心模块拆解(2026-10-17)
范围订正:本文件不再是当前实施任务。 用户已明确第18项是“设置 → 安全中心”,此前按应用安装管理理解有误。本文件保留历史证据与分析,不作为安全中心的需求、实现方案或完成度。当前入口见安全中心范围订正与待拆解项。已有发现应用功能保留;下文安装/更新/卸载等批次不再列入本次四模块计划。
文档范围与结论
本文只做模块拆解、证据归档和分批实施方案,不实现业务代码,不触发安装、更新、卸载、授权或保存。本文形成后通过 REA 对 WorkBuddy 5.8.3 做了一次只读 target 枚举、一次无操作的声明式探针,以及一次打开设置窗口的声明式探针尝试;没有执行产品写操作,也没有修改 REA 配置。
当前结论:
- 既有 REA 证据已经证明 WorkBuddy 5.8.3 侧栏“发现应用”浮层的入口、稳定打开态、主要几何、CSS 和客户端请求/授权逻辑。
- 既有证据没有采集“设置 → 应用管理/安装中心”的懒加载主页面。现有脚本清单只出现
BuddyAppsPanel-vC0qX_Oo.js和BuddyAppsPanel-OzkcFEe0.css的文件名,没有这两个资源的正文。 - 2026-10-17 的最新 REA 枚举只返回主窗口
1CAD78026104DDABDB43F9EB6BA7635D,没有设置窗口 target。一次无操作声明式探针成功(ev_a3ca56f518f5c5101d2ae6e64f24794a564956da643c11e622c56b5cbb245000),但没有导航。 - 打开设置窗口的声明式探针被 REA 以
invalid_request / invalid_input拒绝,未产生 Evidence ID、设置 target 或data-settings-tab="buddyApps"页面。这次结果只记为工具输入失败,不能反推 WorkBuddy 没有应用管理页,也不能反推 REA 不支持该动作。 - “发现应用”是应用切换/发现浮层,不能据此推定安装中心主页面的列表、已安装状态、版本、更新、卸载、授权按钮和失败恢复。
- YCode 当前只有同壳适配的本地“发现应用”浮层,映射到专家、技能、连接器三个本地能力入口;没有云应用目录、应用详情、安装/更新/卸载、授权、依赖安装或应用管理主页。
- 因此 TODO 18 只能保持“部分实现”。本轮不能把它标记为完成,也不能把浮层通过当作安装中心 1:1 验收。
本文证据标签:
| 标签 | 含义 |
|---|---|
REA-RUNTIME |
REA 运行时观察到的页面、DOM、布局、视觉或声明式输入结果 |
REA-STATIC |
REA 保存的 renderer script/CSS/manifest 正文静态结论 |
YCODE-SOURCE |
当前 YCode 源码事实 |
INFERENCE |
基于证据的工程建议,不能当成原版事实 |
REA 证据清单
目标版本均为 WorkBuddy 5.8.3,Windows,Chrome 138 / Electron 37.10.3。主要观察在暗色主题、1336×1240 主窗口或 900×680 设置窗口下完成。
| 用途 | Evidence ID | 保存位置 | 时间(UTC) | 观察范围与边界 |
|---|---|---|---|---|
| 主窗口基线 | ev_ab93f4313af45f559597bfa886f218257edb9b8c1c1c056c446b2ed26a2352e9 |
.tmp/rea-todo18-main-visual.json、.tmp/rea-todo18-main/ |
2026-10-17T05:44:14.389Z |
暗色主窗口、1336×1240、无浮层的基线。截图 SHA-256 b561129cfa37a5b6220e449fd13de7eadc2bc88b68cf48b5c647052aff4a8591。不能证明打开态。 |
| 设置窗口基线 | ev_5b635ae361c0988fa459b5d58897d40ab52ae2e814394b8c21080d1eb9bcb6a1 |
.tmp/rea-todo18-settings.json、.tmp/rea-todo18-settings/ |
2026-10-17T05:44:00.912Z |
暗色设置窗口、900×680,停在“记忆与进化”。截图可见“数据与安全”分组下的“应用管理”导航,但右侧不是应用管理页。截图 SHA-256 5fe5eb779151e04e1415198cd5e3a2958f02395381cc743713f3cddf9961bc3c。 |
| 打开后复核 | ev_43e8726c4cfac93184509ea30ae0d1305f4ad9c4a186f6ce7a20a7b16810316c |
.tmp/rea-todo18-discover-after.json、.tmp/rea-todo18-discover-after/ |
2026-10-17T05:45:42.851Z |
截图 SHA 与主窗口基线完全相同,画面未出现浮层。它不能作为“发现应用”打开态证据。 |
| 键盘打开过程 | ev_d3527391f609e4a8cb4d194a24ee17dcbbdfc0a2d58db240ef3686119694d85f |
.tmp/rea-todo18-discover-key.json、.tmp/rea-todo18-discover-key/ |
2026-10-17T05:49:07.439Z |
REA 对 .industry-template-switcher__trigger 执行 Enter,动作完成并等待 500ms;frame-000.png 显示浮层。最终截图 SHA 65f7ce3cd1d81f4f01f9fabe745b50c0236831f55e69b2012f0fe4e2135271cc。只证明入口可打开,不证明搜索、选择、滚动到底和授权。 |
| 稳定打开态 | ev_bd22e46c95d3887daba16dbe319389ad74e10afea8f71af9a7639e8bce95ebb4 |
.tmp/rea-todo18-discover-state.json、.tmp/rea-todo18-discover-state/ |
2026-10-17T05:49:49.145Z |
暗色浮层稳定截图 SHA-256 f5284085280418769f8c6f022c1e2451f167815783227373c2a90d766ea2bd40。含布局树,但 REA 布局不含文本/input value,应用名称与描述需结合同次截图。 |
| renderer 脚本源 | ev_2b8db4eb73c59a8d3d80c3e37db5ea9b5bf1d13390d5238d81ff2cc53d11dc09 |
.tmp/rea-todo18-main-scripts.json;恢复件 .tmp/rea-todo18-matches/contexts-DgzzFjnf.js |
采集于 2026-10-17 | REA 捕获 321 个当前已加载脚本。contexts-DgzzFjnf.js 为 7,553,508 bytes,SHA-256 8d0c375f141cf724c7f77233ee1d54dd21c9cc86286b79d119711f34a6236746。其中包含发现浮层、API、登录、consent、依赖和缓存逻辑。 |
| 样式源 | ev_7eb66ea8d5949eb7d872f1a93a97894a811b3beb7a02eabd81a500409f1045e4 |
.tmp/rea-todo18-styles-current.json、.tmp/rea-todo18-current-contexts.css、.tmp/rea-todo18-industry.css |
采集于 2026-10-17 | contexts-BkjwYSZT.css 为 1,600,789 bytes,SHA-256 50cbd673f7f35fc7f966bdddc6c9f5677fdfe944cb904888d214619fca259380。恢复出的行业浮层规则文件为 21,085 bytes,SHA-256 ab1771d8109a137d566e19d24901fa088f893354553900172e5719684de58a5d,只是原 CSS 的子集。 |
| 当前 target 枚举 | ev_2504239bed6d570c1e1e274465ffb9989058ba81ea503f7b295db6add4e380f1 |
.tmp/rea-four-modules-install-targets.json |
采集于 2026-10-17 | WorkBuddy 5.8.3 / Electron 37.10.3;只枚举到主窗口 target 1CAD78026104DDABDB43F9EB6BA7635D,没有设置窗口。 |
| 无操作探针确认 | ev_a3ca56f518f5c5101d2ae6e64f24794a564956da643c11e622c56b5cbb245000 |
.tmp/rea-four-modules-install-probe-minimal.json |
2026-10-17T10:04:39.891Z |
使用仅含 wait 的 REA 声明式探针;probe.status=completed,0 个探针帧。视觉 viewport 为 1336×902,PNG SHA-256 d6ef3903bee943b69272a003d8ac7753e7bef882d4949d10104ccac06f70115f。没有点击、导航或设置窗口证据。 |
| 打开设置探针失败 | 无;工具拒绝后未生成 Evidence ID | .tmp/rea-four-modules-install-open-settings.json、.tmp/rea-four-modules-install-open-settings-retry.json |
2026-10-17 | 两个文件均 295 bytes;返回 code=invalid_request、category=invalid_input、message=Analysis input is invalid. Check the arguments and try again.。没有证据表明点击已执行;失败后停止重试。 |
证据边界
- 没有安装中心主页面 DOM、视觉、CSS 或 lazy chunk 正文。
- 没有“应用管理”导航的实际点击记录;当前截图只证明导航文字可见。
- 没有真实 catalog API 响应、账号/企业 header、登录跳转结果或 consent 页面截图。
- 没有安装、更新、卸载、重装、取消、失败、重试或部分成功的产品运行态。
- 没有浅色主题下的原版“发现应用”稳定截图;当前浅色验收来自 YCode 自身。
- REA DOM/layout 会省略文本和输入值,不能从布局节点单独证明中文文案。
- 运行时截图与 DOM/layout 是顺序观察,不是同一原子帧。
- 最新打开设置窗口探针在 REA 参数校验阶段失败;没有设置 target、
buddyAppsactive 状态或主页面截图。 BuddyAppsPanel-*是否已在当前窗口加载仍未证明;没有打开主页面就不能把“未观察到”写成“不存在”。
可用入口与选择器
设置主页面入口
REA-STATIC 已从保存的 renderer 正文确认设置导航项稳定带有 data-settings-tab:
[data-settings-tab="buddyApps"]
.settings-navigation__item[data-settings-tab="buddyApps"]
.settings-navigation__item--active[data-settings-tab="buddyApps"]
设置窗口外层可用的稳定选择器:
body.settings-window
.settings-window-root
.settings-modal__nav
.settings-navigation
.settings-modal__content
.settings-modal__panel
现有证据截图对应“应用管理”的导航行,但页面未打开。主协调补采时建议:
- 选择设置窗口自己的 REA target。历史设置 target 为
8E8A75786E23EA4A57CD049223F7099D;当前主窗口 target1CAD78026104DDABDB43F9EB6BA7635D不能默认代表设置窗口。 - 点击
button[data-settings-tab="buddyApps"]。 - 等待
.settings-navigation__item--active[data-settings-tab="buddyApps"]。 - 再等待 500–1000ms,确保
BuddyAppsPanel-vC0qX_Oo.js与其 CSS 懒加载完成。 - 因主页面根 class 尚未知,先使用
.settings-modal__panel、.settings-modal__content和.settings-modal__panel > *记录页面边界,不要先假定.buddy-apps-panel。 - 同一次 lifecycle 同时采集视觉、script sources 和 style sources;只采稳定页面,不点击安装、更新、卸载或授权动作。
发现应用浮层
REA-RUNTIME 与 REA-STATIC 共同确认的稳定选择器:
.industry-template-switcher__trigger
.industry-template-switcher__trigger--general
.industry-template-switcher__trigger--application
.industry-template-switcher__reset-button
.industry-template-switcher__popover[role="dialog"]
.industry-template-switcher__panel
.industry-template-switcher__search-header
.industry-template-switcher__search
.industry-template-switcher__search .wb-input__inner
.industry-template-switcher__list
.industry-template-switcher__group
.industry-template-switcher__group-items
.industry-template-switcher__item[data-template-id]
.industry-template-switcher__item-action-btn
.industry-template-switcher__retry
.industry-template-switcher__more
.industry-template-switcher__back
.industry-template-switcher__recent-grid
.industry-template-switcher__empty
说明:
data-template-id在运行时实际承载applicationId值。- 选中项在原版是
role="option"的非按钮div,未选中项是可点击button。 - 不应依赖样式哈希类名
src-*或_tag_*,这些类名跨构建不稳定。
原版可证行为
1. 功能开关、登录与入口
REA-STATIC:
- 设置路由
buddyApps由 feature flagbuddyAppEnabled控制是否可见。 - 发现应用根据账号、API route 和 feature flag 决定是否出现。
- 未登录时点击打开入口会先走登录,不会直接展示云目录。
- API route 分个人与企业两种;企业路线把 enterprise id 编入路径。
REA-RUNTIME:
- 暗色主窗口侧栏顶部存在“发现应用”胶囊入口。
- 当前截图中的入口是通用态,文案“发现应用”,不是已选中某个业务应用的状态。
2. 浮层结构与分组
REA-RUNTIME 稳定打开态:
| 结构 | 实测 |
|---|---|
| 触发按钮 | [173.28125,48,98,28];12/500/20;暗色背景 rgb(46,46,46);圆角 100px |
| 浮层 | [31,82,240,420];固定定位;padding 8;圆角 16;暗色背景 rgb(36,36,36) |
| 内面板 | [40,91,222,402] |
| 搜索区 | [40,91,222,33],输入框 [40,91,222,28] |
| 列表视口 | [40,128,222,365];gap 4;纵向滚动 |
| 推荐组 | 标题高 24,条目列表高 960;按 48px 行高可容纳 20 项后继续滚动 |
| 条目 | 218×48;padding 8;gap 12;圆角 8 |
| 图标 | 24×24;列表中圆形,暗色背景 rgb(41,41,41) |
| 标题/描述 | 13/16、11/14;描述为 50% 暗色文字 |
当前截图可见的推荐样例为“通达信、企鹅教师助手、美图设计室、腾讯自选股、腾讯电子签AI合同助手、Alpha派 Lite、广发证券”。这些是随账号/服务变化的运行时数据样例,不得写死为 YCode 目录契约。
3. 列表、搜索和分页
REA-STATIC:
recent与recommended各按场景请求 20 项。- 默认只展示 recent 前 6 项;recommended 会过滤掉已在 recent 中出现的
applicationId。 - recent 超过 6 项或
hasMore时有“更多”,进入独立 recent 网格视图并可返回。 - 非搜索模式滚动到距底部 80px 内时调用对应场景的
loadMore()。 - 搜索输入有 250ms debounce;搜索模式隐藏 recent/recommended 分组,只显示搜索结果。
- 搜索有 loading、error/retry、空结果非搜索和搜索无结果状态。
- 请求使用 owner key 隔离个人/企业账号;旧请求有 generation guard。
REA-RUNTIME 只覆盖默认非空推荐列表;上述分页、搜索、错误和空态属于代码事实,未逐态截图。
4. 条目身份与选择
列表 summary 的核心字段来自 REA-STATIC:
interface BuddyApplicationSummary {
applicationId: string
name: string
description?: string
icon?: string
operationTag?: {
title: string
description: string
}
}
条目行为:
- 未选中行悬停/聚焦显示“进入”动作;选中行显示品牌色对勾与“退出”。
- 选中项由当前应用/模板选择状态决定,不由列表自带 installed 布尔值决定。
- 点击未选中 summary 后,浮层先关闭,再请求 detail。
5. 应用详情、激活与授权
REA-STATIC 证明的 detail 字段:
interface BuddyApplicationTemplate {
templateId: string
applicationId: string
name: string
templateName: string
description?: string
category?: string
operationTag?: { title: string; description: string }
icon?: string
schemaVersion: number
templateVersion: number
versionNo: number
requiredScopes: string[]
allowedOrigins: string[]
templateConfig: unknown
releaseNote?: string
publishedAt?: string
}
上面的 templateConfig 在实际代码里还有 schema 校验;这里保留为 unknown,避免把未经原文逐项恢复的完整 schema 当成 YCode 契约。
选择流程:
- 请求 detail。
- 等待本地选择状态 hydrated,最长 8s。
- 校验账号在异步过程中没有切换。
- 调登录/授权状态接口,取得
authorized、application、redirect URI 和 granted scopes。 - 已授权则直接提交本地模板上下文。
- 未授权则显示 consent;用户可批准或跳过跳转。
- consent 后获得一次性 code 和 granted scopes。
- 根据模板配置安装/连接 MCP 依赖,并可能打开外部 authorization URL。
- 成功后提交模板选择、上报 usage、触发 onboarding,并返回主页。
- 退出当前应用时清空选择,并尝试移除该应用的 MCP dependency。
全局同一时间只允许一个应用切换流程,避免并发授权。
6. 远程 API 事实
REA-STATIC 中可确认的个人账号端点:
| 功能 | 方法 | 路径/参数 |
|---|---|---|
| 场景列表 | GET | /api/v1/open-platform/buddy_application?limit={limit}&scene={recent|recommended}[&cursor=...] |
| 搜索 | POST | /api/v1/open-platform/buddy_application/search,body { keyword } |
| 详情 | POST | /api/v1/open-platform/buddy_application/detail,body { application_id } |
| 使用上报 | POST | /api/v2/open-platform/asset-usage/report,body { asset_id, asset_type: "buddy_app" } |
| 入口可用性 | GET | /api/v2/open-platform/buddy/entrance |
企业账号使用 /v2/enterprises/{enterpriseId} 前缀和对应子路径。
列表响应可确认字段包括 applications、has_more、next_cursor。请求会按需附加 X-GPU-DEVICE-NAME。
**目前没有证据证明以下接口:**应用包下载、安装、更新、卸载、版本检查、安装进度、取消、回滚、权限撤销、已安装列表。不能用上述 discovery/usage 端点臆造完整安装 API。
7. 设置页中的应用管理
REA-STATIC 已确认:
- 设置 route id 为
buddyApps。 - 入口是
button[data-settings-tab="buddyApps"],中文截图显示“应用管理”。 - 页面是懒加载
BuddyAppsPanel-vC0qX_Oo.js,配套BuddyAppsPanel-OzkcFEe0.css。 - route 可用性受
buddyAppEnabled控制。
尚不能确认:
- 主页面标题、分组、搜索、筛选和排序。
- 是否显示市场目录、已安装应用或两者共存。
- installed 的判定规则,以及安装与应用激活是否同一概念。
- 版本、更新提示、自动更新、更新检查、发布说明。
- 安装、更新、卸载、打开、停用、退出、重试、取消的入口和确认方式。
- loading、empty、error、partial、offline、unauthorized、dependency-missing 状态。
- 主页面的所有几何、深层深浅主题和动画。
这是主协调下一步最优先的 REA 补采目标。
2026-10-17 补采结果:
- 设置窗口 target 不在当前 REA endpoint 的 target 列表中,只有一个主窗口。
- 计划中的
open-account-menu → open-settings-window探针没有进入动作生命周期;REA 在输入校验阶段返回invalid_request / invalid_input,因此没有 Evidence ID 和声明式动作步骤。 - 没有采集
button[data-settings-tab="buddyApps"]、.settings-navigation__item--active[data-settings-tab="buddyApps"]或.settings-modal__panel的主页面内容。 - 本专项按用户要求停止重复尝试。安装中心主页面的布局、状态、版本更新、卸载和错误恢复仍为明确未知,等待后续设置窗口 target 和新 Evidence 补证。
YCode 当前状态
已实现
| 能力 | 状态 | 主要源码 |
|---|---|---|
| “发现应用”入口与浮层 | 已实现可交互壳 | src/renderer/src/components/AppDiscoverPopover.tsx |
| 浮层几何、搜索、空态、键盘、外部点击、焦点恢复 | 已实现本地版本 | 同上、app-discover-popover.css |
| 最近使用 | 已实现 localStorage 版,最多 6 个本地能力 ID | ycode.app-discover.recent.v1 |
| 应用选择 | 映射到 experts / skills / connectors 三个本地能力页 | Sidebar.tsx、App.tsx、CapabilityCenter.tsx |
| 选中态退出 | 从本地能力页回到聊天 | AppDiscoverPopover 的 onExit |
| 本地能力 | 专家、本地技能、自定义 MCP 已有各自页面和数据层 | src/renderer/src/capabilities/ |
占位
| 能力 | 现状 |
|---|---|
| 技能市场 | 技能页对未连接目录显示本地空态,可导入本地技能 |
| 连接器目录 | 当前以自定义 MCP 为主,云目录和第三方 OAuth 未接 |
| 最近使用 | 只保存本地三个 capability ID,不是原版账号级应用使用历史 |
| 应用图标 | 使用本地 SVG,不是远端应用图标和失败 fallback |
缺失
| 能力 | 缺口 |
|---|---|
| 安装中心主页面 | 完全缺失;设置导航中 buddyApps 还被用户明确移除 |
| 云应用目录 | 无列表、搜索、detail、最近、推荐和分页 API |
| 应用身份模型 | 无 applicationId/templateId/version/scopes 数据 |
| 安装状态机 | 无 installed/installing/updating/uninstalling/failed |
| 安装来源 | 无市场、企业、URL、本地包或内置来源模型 |
| 更新与版本 | 无版本比较、release note、更新检查 |
| 卸载与恢复 | 无卸载确认、部分失败、重试、回滚 |
| 授权 | 无 login、consent、scope grant、redirect URI |
| 应用依赖 | 无应用级 MCP dependency 安装/移除 |
| 使用上报/onboarding | 无 usage report、show observer、onboarding 状态 |
| 管理入口 | SettingsDialog.tsx 的 REMOVED_SETTINGS_TABS 包含 buddyApps |
需要先决定的产品边界
用户此前要求移除“系统设置 → 应用管理”入口。若后续恢复安装中心,不应静默推翻该决定。可由主协调确认采用下列之一:
- 保留设置入口移除,只在侧栏“发现应用”中增加管理/浏览入口。
- 恢复“应用管理”设置页,同时保留“发现应用”作为切换器。
- 将两者合并为独立安装中心页面,设置与侧栏都指向同一路由。
本拆解建议先按“两个表面、一个状态源”设计:发现浮层负责快速发现/切换,安装中心管理页负责目录、安装、版本、授权和卸载;两侧共享同一 registry,避免出现两套 installed 状态。
建议数据契约
以下是 INFERENCE,用于 YCode 后续实现;字段名尽量贴近 REA 静态事实,但不冒充原版完整 schema。
type BuddyAppSource = 'builtin' | 'marketplace' | 'enterprise' | 'local'
type BuddyAppAvailability = 'available' | 'unavailable' | 'entitlement-required'
type BuddyAppLifecycle =
| 'not-installed'
| 'installing'
| 'installed'
| 'active'
| 'updating'
| 'update-available'
| 'uninstalling'
| 'failed'
| 'unauthorized'
| 'dependency-missing'
interface BuddyAppSummary {
applicationId: string
templateId?: string
name: string
description?: string
iconUrl?: string
operationTag?: { title: string; description?: string }
source: BuddyAppSource
availability?: BuddyAppAvailability
}
interface BuddyAppDetail extends BuddyAppSummary {
name: string
versionNo: number
templateVersion?: number
schemaVersion?: number
category?: string
requiredScopes: string[]
allowedOrigins: string[]
templateConfig: unknown
releaseNote?: string
publishedAt?: string
}
interface BuddyAppRegistryEntry {
applicationId: string
templateId?: string
installedVersion?: number
availableVersion?: number
lifecycle: BuddyAppLifecycle
source: BuddyAppSource
installedAt?: number
lastOpenedAt?: number
lastError?: string
operationId?: string
dependencies: BuddyAppDependencyState[]
}
interface BuddyAppDependencyState {
kind: 'mcp' | 'connector'
key: string
state: 'missing' | 'installing' | 'connected' | 'needs-auth' | 'error'
error?: string
}
interface BuddyAppOperation {
operationId: string
applicationId: string
kind: 'install' | 'update' | 'uninstall' | 'activate' | 'deactivate'
phase: 'queued' | 'downloading' | 'verifying' | 'applying' | 'authorizing' | 'connected' | 'done' | 'failed' | 'cancelled'
progress?: number
message?: string
startedAt: number
finishedAt?: number
}
工程约束:
applicationId与templateId分开;现有原版列表以applicationId去重。- 版本、scope、origin、redirect URI 必须保存快照,避免更新过程中配置变化。
- installed、active、authorized、dependency-ready 必须分开。
- operationId 用于 UI 去重和恢复;不能只靠 loading 布尔值。
- token、authorization code、secret 不进入 renderer 持久状态或日志。
本地功能与远端依赖边界
| 能力 | 本地可完成 | 依赖远端/宿主 |
|---|---|---|
| 浮层/主页面布局 | 是 | 否 |
| 列表缓存、最近使用、当前选择 | 是 | 初次目录数据需要远端 |
| 本地 registry 和 operation journal | 是 | 状态变更需要服务端确认 |
| 目录列表、搜索、详情 | 否 | 是 |
| 登录、consent、scope grant | 否 | 是 |
| 应用包下载、校验、安装、更新、卸载 | 否 | 是;若 YCode 自建安装包生态则另立本地协议 |
| 应用模板 config 和 allowed origin | 可缓存 | 更新源来自远端 |
| MCP dependency 本地注册 | 是 | 授权/远端 connector 仍可能需要服务端 |
| usage report、show/click telemetry | 可本地排队 | 上报需要远端 |
| entitlement、企业策略、配额 | 否 | 是 |
| 错误文案和恢复 UI | 是 | 具体 reason code 来自宿主/服务端 |
| 安装 provenance/checksum | 可实现本地校验器 | 可信摘要/签名来源需可信配置 |
原则:没有真实安装结果时,UI 只能显示“未接入/等待服务”,不能显示“安装成功”。
建议模块拆分
A. buddyAppCatalog
职责:
- recent/recommended/search/detail。
- 500ms 内搜索 debounce 的内部实现可沿用 250ms 事实,但需要统一 abort/generation。
- 账号、企业、feature flag 作为请求 key。
- summary/detail 校验、去重、缓存和 stale 响应丢弃。
不负责安装状态。
B. buddyAppRegistry
职责:
- 已安装列表、版本、来源、最近打开时间。
- selected application/template。
- install/update/uninstall/active 状态。
- 操作日志、错误和恢复。
本地 registry 必须可以独立启动;远端 catalog 失败不能让已安装应用消失。
C. buddyAppInstaller
职责:
- 下载、完整性校验、解包/安装、原子切换、失败回滚。
- operation progress/cancel。
- 安装来源差异。
此模块是否存在原版真实包安装流程目前未知;不得把“安装 MCP dependency”改名为“安装应用”。
D. buddyAppAuthorization
职责:
- login/authorized 状态。
- consent、scope diff、grant。
- redirect/MCP 授权的衔接。
- 账号切换取消未完成操作。
E. buddyAppUi
包含两个 surface:
- switcher:快速发现、最近、推荐、搜索、切换/退出。
- manager:已安装、目录、版本、更新、卸载、授权、依赖、错误恢复。
两者共享 Registry/Store,但各自保留 surface-specific UI state。
F. buddyAppObservability
- 展示曝光、点击、进入、consent、授权失败、usage report。
- 事件失败不能破坏业务主流程。
- 脱敏 app id/version,不记录 token/code/secret。
分批任务与验收标准
批次 0:补采应用管理主页面
范围:
- 主协调通过现有 REA lifecycle,在设置窗口点击
[data-settings-tab="buddyApps"]。 - 同次 capture 开启 scripts、styles、visuals。
验收:
- 捕获到
BuddyAppsPanel-vC0qX_Oo.js正文或其新的 build hash。 - 捕获到
BuddyAppsPanel-*.css正文。 - 新 Evidence ID、target、captured_at、script/CSS SHA-256、viewport、theme 全部记录。
- 产出主页面 DOM/layout/稳定截图,至少覆盖默认稳定态。
- 明确没有触发安装、更新、卸载、授权等有副作用动作。
当前状态:已尝试,未完成。 最新 target 枚举只有主窗口;打开设置窗口的探针在 REA 参数校验阶段失败,没有设置 target。批次 0 未通过,阻塞条件正是设置页面 source/lifecycle,而不是已有静态结论不足。
取消条件:
- 只采到导航 active class,未加载 lazy chunk。
- 只采到
.settings-modal__panel但内容仍为其他设置页。
批次 1:数据契约与只读 registry
范围:
- 建
BuddyAppSummary/Detail/RegistryEntry/Operation/Dependency类型。 - 建立按账号/企业隔离的本地 registry。
- 无远端时显示真实“目录未连接”,已安装本地条目仍可展示。
验收:
- ID 身份稳定;同 application 不会因 template 版本重复成多张卡。
- 本地 registry 跨重启保留。
- account/enterprise 切换不会串数据。
- 没有真实 installed 数据时不伪造 installed 状态。
批次 2:应用管理页壳与本地状态
范围:
- 安装中心主页面骨架、搜索、筛选、分组。
- 列表、空态、加载态、错误态和 operation banner。
- 配置入口决定:独立页或恢复设置入口由主协调拍板。
验收:
- 在 900×680 设置窗口和主窗口布局无溢出。
- 浅色/深色、正常/窄宽、空/错/loading 可稳定渲染。
[data-settings-tab="buddyApps"]或替代入口的导航语义明确。- 不依赖云端即可打开本地 manager shell。
批次 3:目录列表、搜索和详情
范围:
- recent/recommended/search/detail adapter。
- summary 去重、分页、stale guard、请求取消。
验收:
- 空查询、250ms 搜索、无结果、失败重试、下一页、末尾停止。
- recent 与 recommended 去重。
- account/enterprise 切换取消旧请求。
- 远端不可达时返回可恢复错误,不显示空目录冒充成功。
批次 4:安装/激活状态机
范围:
not-installed → installing → installed → active等状态。- 同一 application 的并发操作锁。
- failure、retry、cancel、app restart 恢复。
验收:
- 双击安装只产生一个 operation。
- UI 进度来自 operation 状态,不由定时器模拟。
- 失败不会部分标记 installed。
- 重启后未完成操作可查询、恢复或明确标记未知。
- “安装应用”与“安装 MCP dependency”在产品文案和状态上分开。
批次 5:更新、卸载与恢复
范围:
- 版本比较、release note、确认流程。
- 卸载对 active 应用、MCP dependency、云端授权和本地数据的影响。
验收:
- 同版本、旧版本、新版本、降级、unknown version均有明确状态。
- 更新失败回滚到旧版本和旧 selected template。
- 卸载前明确是否保留本地数据与授权。
- 卸载失败可重试,不把卡片直接删掉。
批次 6:登录、consent、scope 和依赖授权
范围:
- login/authorization adapter。
- consent summary、scope diff、取消、拒绝、跳转失败、回到桌面。
- MCP/builtin/custom/joint auth 分支。
验收:
- 账号切换时取消旧流程。
- redirect URI、scopes、template version 在授权期间发生变化则拒绝提交。
- 取消/失败不会写入 ready 状态。
- code/token 不落盘、不打印。
- 依赖失败与应用安装状态可区分。
批次 7:像素与全状态验收
范围:
- switcher 与 manager 的原版同数据、同主题、同尺寸对照。
验收:
- 入口、popover、manager 默认态在浅/深色完成截图和几何比对。
- 搜索、loading、error、empty、scroll、load-more、hover、focus、selected、disabled。
- 安装、更新、卸载、授权、依赖、失败、重启恢复。
- 键盘、focus trap、Escape/外部点击、IME 和窄窗。
- 不以 YCode 专项 PASS 代替 WorkBuddy 同状态 1:1。
精确未知项
主页面与产品信息架构
- 设置“应用管理”和侧栏“发现应用”是否共享同一个应用实体、选择状态和 installed 列表。
- 主页面是否只管理已安装应用,还是也展示市场目录。
- 主页面标题、分组、筛选、排序、搜索和详情进入方式。
- 是否支持企业目录、内置应用、本地应用和第三方 market 的混合列表。
安装语义
- “安装”是否下载本地包,还是只创建账号授权/云端绑定。
- 安装与应用“进入/激活”是否同一操作。
- 安装成功后是否立即成为当前应用,还是仍展示“进入”。
- 同一 application 是否可安装多个 template/version。
更新语义
- 更新源、版本比较规则和自动/手动检查时机。
- 更新通知显示位置、release note 来源和强制更新规则。
- 更新中能否使用当前版本,失败时是否回滚。
卸载语义
- 卸载按钮的确认文案和危险色层级。
- 本地数据、云端 grant、MCP dependency、recent snapshot 是否一起清除。
- active 应用或 dependency-disconnected 状态下的卸载限制。
状态与错误
- 完整状态枚举和 reason codes。
- 进度是否支持百分比、字节数、阶段文案。
- 取消、超时、断网、配额不足、企业策略、权限撤销、依赖失败的实际文案。
- 失败后 operation 是否保留、恢复或可重试次数。
数据与持久化
- 本机 registry 的 storage key、schema version、账号/企业隔离。
- 已安装包位置、完整性校验、签名和升级目录。
- recent/show/usage 的服务端与本地双层缓存。
- 应用图标 URL、缓存、CSP 和失败 fallback。
视觉
- “应用管理”主页面完整 DOM/CSS、默认数据量和空数据量。
- 浅色稳定态和深色稳定态。
- 安装/更新/卸载/授权弹窗与 toast。
- 菜单、hover、disabled、focus、loading、滚底、分页。
- 900×680 设置窗口之外的独立页面尺寸。
补采检查表
主协调下一次统一补采应至少保存:
- 设置 target id、窗口 URL 和 viewport。
[data-settings-tab="buddyApps"]点击前后稳定帧。- 主页面
.settings-modal__panel的 DOM、layout、可见文本和截图。 BuddyAppsPanel-vC0qX_Oo.js/新 hash 的完整 REA script source。BuddyAppsPanel-OzkcFEe0.css/新 hash 的完整 REA style source。- 默认列表数量及至少一个已安装、一个未安装、一个有更新条目的字段。
- 主操作的 DOM selector、文案、disabled 条件和确认弹窗。
- 浅色与深色稳定态;若窗口主题由设置控制,记录切换证据。
- 只读网络/状态来源证据;不在主页面直接执行真实安装或卸载。
建议的探针起点:
[
{
"kind": "click",
"selector": "[data-settings-tab=\"buddyApps\"]",
"frames": 0
},
{
"kind": "wait",
"duration_ms": 750,
"frames": 1
}
]
探针完成后以 .settings-navigation__item--active[data-settings-tab="buddyApps"] 确认路由,再检查 .settings-modal__panel 内是否出现新模块内容。
决策
- 不把发现浮层等同于安装中心。 两者共享可能的数据,但当前证据将它们拆为 switcher 与 manager 两个 surface。
- 不在主页面证据缺失时实现安装按钮。 后续先建立 registry/operation 状态,再接真实能力。
- 把 installed、active、authorized、dependency-ready 分开。 现有原版已证明选择/授权/依赖是独立步骤。
- 应用 ID 使用
applicationId作为首选去重键。templateId、version 和 schema 另存。 - 远端目录失败不等于空目录。 本地已安装 registry 必须离线可见,远端错误必须可恢复。
- 保留用户移除设置入口的决定。 安装中心的最终入口位置需要主协调明确,不能擅自恢复
buddyApps设置项。 - sample app 名称只作截图样例。 通达信等运行时条目不得写死。
本轮核对命令
本轮没有运行测试或构建。除下方明确列出的 REA target 枚举和两次声明式探针外,其余核对均为静态读取。
rg --files docs | rg '安装|应用|发现|中心|模块拆解'
Get-ChildItem .tmp -Recurse | Where-Object FullName -match 'rea-todo18'
rg -n '安装中心|发现应用|Discover|app discover|install' docs src scripts
Get-Content docs/复刻待办清单-2026-10-17.md
Get-Content src/renderer/src/components/AppDiscoverPopover.tsx
Get-Content src/renderer/src/components/app-discover-popover.css
Get-Content src/renderer/src/capabilities/CapabilityCenter.tsx
Get-Content scripts/verify-app-discover.cjs
Get-Content .tmp/rea-todo18-BuddyAppDiscoverPanel.js
Get-Content .tmp/rea-todo18-BuddyAppIcon.js
Python 解析 .tmp/rea-todo18-*.json 的 evidence_id、target、captured_at、viewport、artifact SHA-256、limitations
Python 解析 .tmp/rea-todo18-main-scripts.json 的 contexts-DgzzFjnf.js source artifact
Python 解析 .tmp/rea-todo18-styles-current.json 的 contexts-BkjwYSZT.css source artifact
Python 解析 .tmp/rea-todo18-discover-state/layout.json 的浮层几何
Python 解析 .tmp/rea-todo18-settings/layout.json 的设置导航结构
Python 在保存的 contexts-DgzzFjnf.js 中检索 API、selection、consent、dependency、settings route
2026-10-17 新增的 REA 读取与失败记录:
node .tmp/rea-css-runtime/scripts/rea.mjs list-electron-targets http://127.0.0.1:9223
REA inspect-electron-page:主窗口 + 仅 wait 的 visual_probe
REA inspect-electron-page:主窗口 + 打开账户菜单/设置窗口的 visual_probe
结果:target list 成功;无操作探针成功;设置打开探针 invalid_request,未生成 Evidence ID
保存:.tmp/rea-four-modules-install-targets.json
.tmp/rea-four-modules-install-probe-minimal.json
.tmp/rea-four-modules-install-open-settings.json
.tmp/rea-four-modules-install-open-settings-retry.json
风险
- 把浮层当完整安装中心:会严重高估完成度。
- 把 MCP 依赖安装冒充应用安装:原版代码明确区分 dependency 与 application 选择。
- 恢复已移除设置入口而不确认:与用户此前要求冲突。
- 远端服务不可用时伪造状态:可产生虚假 installed/update 结果。
- 账号/企业隔离错误:可能把企业目录、授权或用量混进个人数据。
- 授权并发和账号切换:可能出现旧 consent 写入新账号。
- 安装/更新破坏用户内容:需要原子操作、备份、回滚和明确确认。
- 敏感信息泄漏:authorization code、token、secret 和完整远端 URL 不应进入日志/普通本地状态。
- 运行时动态条目被写死:sample app 名称、顺序和描述会随账号/服务变化。
- 主页面像素误判:当前没有该页面任何 REA 视觉,不能从浮层几何推导。
交接结论
本轮安装中心专项到此收口:已有足够证据拆出“发现浮层”和“安装中心主页面”两个 surface,以及目录、选择、授权、依赖和未知安装生命周期边界;但安装中心主页面仍没有 REA 运行时证据。下一步需要先获得可操作的原版设置窗口 target,再点击 [data-settings-tab="buddyApps"] 并同次采集 DOM、视觉、脚本和样式。补采成功后,优先恢复 BuddyAppsPanel 的 DOM/CSS 和页面状态,再决定 manager 的真实信息架构。YCode 已有浮层壳可以保留,但其数据层仍是本地能力适配,必须和后续云应用 registry 解耦。