Files
ycode/docs/安装中心模块拆解-2026-10-17.md
T

37 KiB
Raw Blame History

安装中心模块拆解(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.。没有证据表明点击已执行;失败后停止重试。

证据边界

  1. 没有安装中心主页面 DOM、视觉、CSS 或 lazy chunk 正文。
  2. 没有“应用管理”导航的实际点击记录;当前截图只证明导航文字可见。
  3. 没有真实 catalog API 响应、账号/企业 header、登录跳转结果或 consent 页面截图。
  4. 没有安装、更新、卸载、重装、取消、失败、重试或部分成功的产品运行态。
  5. 没有浅色主题下的原版“发现应用”稳定截图;当前浅色验收来自 YCode 自身。
  6. REA DOM/layout 会省略文本和输入值,不能从布局节点单独证明中文文案。
  7. 运行时截图与 DOM/layout 是顺序观察,不是同一原子帧。
  8. 最新打开设置窗口探针在 REA 参数校验阶段失败;没有设置 target、buddyApps active 状态或主页面截图。
  9. 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

现有证据截图对应“应用管理”的导航行,但页面未打开。主协调补采时建议:

  1. 选择设置窗口自己的 REA target。历史设置 target 为 8E8A75786E23EA4A57CD049223F7099D;当前主窗口 target 1CAD78026104DDABDB43F9EB6BA7635D 不能默认代表设置窗口。
  2. 点击 button[data-settings-tab="buddyApps"]。
  3. 等待 .settings-navigation__item--active[data-settings-tab="buddyApps"]。
  4. 再等待 500–1000ms,确保 BuddyAppsPanel-vC0qX_Oo.js 与其 CSS 懒加载完成。
  5. 因主页面根 class 尚未知,先使用 .settings-modal__panel、.settings-modal__content 和 .settings-modal__panel > * 记录页面边界,不要先假定 .buddy-apps-panel。
  6. 同一次 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 flag buddyAppEnabled 控制是否可见。
  • 发现应用根据账号、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 契约。

选择流程:

  1. 请求 detail。
  2. 等待本地选择状态 hydrated,最长 8s。
  3. 校验账号在异步过程中没有切换。
  4. 调登录/授权状态接口,取得 authorized、application、redirect URI 和 granted scopes。
  5. 已授权则直接提交本地模板上下文。
  6. 未授权则显示 consent;用户可批准或跳过跳转。
  7. consent 后获得一次性 code 和 granted scopes。
  8. 根据模板配置安装/连接 MCP 依赖,并可能打开外部 authorization URL。
  9. 成功后提交模板选择、上报 usage、触发 onboarding,并返回主页。
  10. 退出当前应用时清空选择,并尝试移除该应用的 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

需要先决定的产品边界

用户此前要求移除“系统设置 → 应用管理”入口。若后续恢复安装中心,不应静默推翻该决定。可由主协调确认采用下列之一:

  1. 保留设置入口移除,只在侧栏“发现应用”中增加管理/浏览入口。
  2. 恢复“应用管理”设置页,同时保留“发现应用”作为切换器。
  3. 将两者合并为独立安装中心页面,设置与侧栏都指向同一路由。

本拆解建议先按“两个表面、一个状态源”设计:发现浮层负责快速发现/切换,安装中心管理页负责目录、安装、版本、授权和卸载;两侧共享同一 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。

精确未知项

主页面与产品信息架构

  1. 设置“应用管理”和侧栏“发现应用”是否共享同一个应用实体、选择状态和 installed 列表。
  2. 主页面是否只管理已安装应用,还是也展示市场目录。
  3. 主页面标题、分组、筛选、排序、搜索和详情进入方式。
  4. 是否支持企业目录、内置应用、本地应用和第三方 market 的混合列表。

安装语义

  1. “安装”是否下载本地包,还是只创建账号授权/云端绑定。
  2. 安装与应用“进入/激活”是否同一操作。
  3. 安装成功后是否立即成为当前应用,还是仍展示“进入”。
  4. 同一 application 是否可安装多个 template/version。

更新语义

  1. 更新源、版本比较规则和自动/手动检查时机。
  2. 更新通知显示位置、release note 来源和强制更新规则。
  3. 更新中能否使用当前版本,失败时是否回滚。

卸载语义

  1. 卸载按钮的确认文案和危险色层级。
  2. 本地数据、云端 grant、MCP dependency、recent snapshot 是否一起清除。
  3. active 应用或 dependency-disconnected 状态下的卸载限制。

状态与错误

  1. 完整状态枚举和 reason codes。
  2. 进度是否支持百分比、字节数、阶段文案。
  3. 取消、超时、断网、配额不足、企业策略、权限撤销、依赖失败的实际文案。
  4. 失败后 operation 是否保留、恢复或可重试次数。

数据与持久化

  1. 本机 registry 的 storage key、schema version、账号/企业隔离。
  2. 已安装包位置、完整性校验、签名和升级目录。
  3. recent/show/usage 的服务端与本地双层缓存。
  4. 应用图标 URL、缓存、CSP 和失败 fallback。

视觉

  1. “应用管理”主页面完整 DOM/CSS、默认数据量和空数据量。
  2. 浅色稳定态和深色稳定态。
  3. 安装/更新/卸载/授权弹窗与 toast。
  4. 菜单、hover、disabled、focus、loading、滚底、分页。
  5. 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 内是否出现新模块内容。

决策

  1. 不把发现浮层等同于安装中心。 两者共享可能的数据,但当前证据将它们拆为 switcher 与 manager 两个 surface。
  2. 不在主页面证据缺失时实现安装按钮。 后续先建立 registry/operation 状态,再接真实能力。
  3. 把 installed、active、authorized、dependency-ready 分开。 现有原版已证明选择/授权/依赖是独立步骤。
  4. 应用 ID 使用 applicationId 作为首选去重键。 templateId、version 和 schema 另存。
  5. 远端目录失败不等于空目录。 本地已安装 registry 必须离线可见,远端错误必须可恢复。
  6. 保留用户移除设置入口的决定。 安装中心的最终入口位置需要主协调明确,不能擅自恢复 buddyApps 设置项。
  7. 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

风险

  1. 把浮层当完整安装中心:会严重高估完成度。
  2. 把 MCP 依赖安装冒充应用安装:原版代码明确区分 dependency 与 application 选择。
  3. 恢复已移除设置入口而不确认:与用户此前要求冲突。
  4. 远端服务不可用时伪造状态:可产生虚假 installed/update 结果。
  5. 账号/企业隔离错误:可能把企业目录、授权或用量混进个人数据。
  6. 授权并发和账号切换:可能出现旧 consent 写入新账号。
  7. 安装/更新破坏用户内容:需要原子操作、备份、回滚和明确确认。
  8. 敏感信息泄漏:authorization code、token、secret 和完整远端 URL 不应进入日志/普通本地状态。
  9. 运行时动态条目被写死:sample app 名称、顺序和描述会随账号/服务变化。
  10. 主页面像素误判:当前没有该页面任何 REA 视觉,不能从浮层几何推导。

交接结论

本轮安装中心专项到此收口:已有足够证据拆出“发现浮层”和“安装中心主页面”两个 surface,以及目录、选择、授权、依赖和未知安装生命周期边界;但安装中心主页面仍没有 REA 运行时证据。下一步需要先获得可操作的原版设置窗口 target,再点击 [data-settings-tab="buddyApps"] 并同次采集 DOM、视觉、脚本和样式。补采成功后,优先恢复 BuddyAppsPanel 的 DOM/CSS 和页面状态,再决定 manager 的真实信息架构。YCode 已有浮层壳可以保留,但其数据层仍是本地能力适配,必须和后续云应用 registry 解耦。