diff --git a/.project-docs/10-decisions/proposals/20260903-plugin-navigation-design-7c4e2a91__unified-plugin-workspace-spec.md b/.project-docs/10-decisions/proposals/20260903-plugin-navigation-design-7c4e2a91__unified-plugin-workspace-spec.md deleted file mode 100644 index cb58752..0000000 --- a/.project-docs/10-decisions/proposals/20260903-plugin-navigation-design-7c4e2a91__unified-plugin-workspace-spec.md +++ /dev/null @@ -1,576 +0,0 @@ -# MakeLore 统一插件工作台实施规范 - -## 0. 文档信息 - -| 字段 | 值 | -| --- | --- | -| Spec ID | `ML-PLUGIN-NAV-001` | -| 状态 | 产品方向已获用户确认;待实施 | -| 日期 | 2026-09-03 | -| Task | `20260903-plugin-navigation-design-7c4e2a91` | -| 客户端基线 | `e9875145b41a2cb1827de10d27a4fc6a352704ea` | -| 影响仓库 | MakeLore 客户端 | -| 服务端影响 | 无新接口、无 DTO 变化、无迁移 | -| 来源设计 | 将“插件中心 / 我的插件 / 项目插件”合并为一个 Codex 风格插件入口 | - -本文把已确认的产品方向收敛为可实施、可验证的客户端合同。关键词含义: - -- **MUST / 必须**:不满足即本次改造未完成。 -- **MUST NOT / 禁止**:实现不得出现。 -- **SHOULD / 应当**:默认实现方式;偏离时须在任务记录中说明理由。 -- **MAY / 可以**:不影响合同的实现选择。 - -## 1. 已确认事实与独立判断 - -### 1.1 当前事实 - -客户端目前存在三个独立页面和三个侧栏入口: - -- `/plugin-marketplace`:运营发布的官方目录、搜索、详情和免费获取。 -- `/my-plugins`:账号插件库、官方设备包状态和通过对话安装的本机 Device Package。 -- `/project-plugins`:当前项目启用状态、伙伴分配投影、计费能力与插件设置。 - -这些页面实际投影的是同一插件在不同阶段的状态,但底层权威并不相同: - -1. 官方目录与详情; -2. Account Library 免费获取状态; -3. 官方设备包的 Package Store 状态; -4. 本机 Device Package 状态; -5. 当前项目启用状态; -6. Agent Skill 分配状态; -7. runtime admission、后端与计费状态。 - -当前原生 Web Search 已是所选模型的核心工具,不再是 Marketplace Plugin。通过对话安装的 -第三方 Web Search、Skill 或 Pi extension 仍属于本机 Device Package。 - -### 1.2 结论 - -三个导航入口必须合并,但只能合并用户界面和只读投影,不能合并上述权威状态机。 - -若只是把三个旧页面放进三个 Tab,用户仍需理解“去哪里发现、去哪里下载、去哪里启用”的 -旧流程,且新插件类型会继续制造第四个页面。因此本规范采用: - -- 一个侧栏入口; -- 一个 canonical route; -- 一份统一列表; -- 范围、来源和状态筛选; -- 一个详情面板; -- 各 mutation 仍发送给原有 owner。 - -## 2. 目标结果 - -完成后必须实现以下产品结果: - -1. Code 侧栏只出现一个“插件”入口。 -2. `/plugins` 是唯一 canonical 页面。 -3. 官方目录、账号已获取插件、本机包和当前项目状态可以在同一列表中理解和操作。 -4. 用户无需先进入“我的插件”再跳转“项目插件”。 -5. 免费获取、设备交付、项目启用和 Agent 分配仍是显式且互不自动推进的步骤。 -6. 本机 Skill/extension 仍只能通过对话安装;页面只管理已安装内容。 -7. 任一远端投影失败时,其他来源仍可独立显示和操作。 -8. 旧书签和旧页面链接通过确定性 redirect 进入新的等价筛选状态。 -9. 原生模型 Web Search 不作为插件卡片出现。 - -## 3. 范围 - -### 3.1 包含 - -- Code 侧栏插件导航合并。 -- `/plugins` route 与旧 route redirects。 -- Renderer 统一插件只读投影 Module。 -- 统一搜索、范围、来源、状态筛选。 -- 官方、本机、项目保留项的统一卡片与详情面板。 -- 现有获取、移除、官方设备包、项目启用、本机启停/移除和 Data Service 设置入口。 -- 部分失败、缓存、账号切换和项目切换行为。 -- 单元测试、页面测试、路由测试和 Electron E2E 更新。 -- README 与 task-scoped 项目文档更新。 - -### 3.2 不包含 - -- 服务端 Marketplace、Library、Admission、Policy、Token Point 或 Provider 接口变化。 -- 新的 Renderer 持久化状态或第四份插件数据库。 -- 可见的 npm、Git、文件夹、ZIP 或 `SKILL.md` 安装入口。 -- 将本机 Device Package 改为项目级启用。 -- 将原生模型 Web Search 重新注册为 Marketplace Plugin。 -- 自动获取、自动下载、自动启用项目或自动分配 Agent。 -- 插件发布、运营端管理或 Release 生命周期改造。 -- 通用第三方插件审核或权限沙箱。 - -## 4. 不可变产品合同 - -### 4.1 导航 - -- `NAV-001`:侧栏 MUST 只有一个 `插件` 按钮,测试标识为 - `sidebar-nav-plugins`。 -- `NAV-002`:按钮在存在当前项目时 MUST 打开 - `/plugins?scope=project`;没有当前项目时 MUST 打开 - `/plugins?scope=all`。 -- `NAV-003`:`/plugins` MUST 是 Code 模块路由且是项目初始化安全路由。 -- `NAV-004`:`/plugins` MUST NOT 成为全页 Provider gate。目录和本机包不能因当前项目 - Provider 未配置而不可见。 -- `NAV-005`:旧路由 MUST 使用 replace redirect,不得继续挂载旧页面。 - -旧路由映射固定为: - -| 旧路由 | 新路由 | -| --- | --- | -| `/plugin-marketplace` | `/plugins?scope=all&source=official` | -| `/my-plugins` | `/plugins?scope=all&state=mine` | -| `/project-plugins` | `/plugins?scope=project` | - -### 4.2 状态推进 - -- `STATE-001`:免费获取只改变 Account Library。 -- `STATE-002`:免费获取 MUST NOT 自动下载、启用项目或分配 Agent。 -- `STATE-003`:项目启用 MUST 使用当前项目的显式 ID;项目切换后旧确认框不得作用于 - 新项目。 -- `STATE-004`:Agent 分配仍由项目配置拥有;统一页面只展示投影并跳转到现有分配入口。 -- `STATE-005`:本机包启停是设备全局行为,文案必须写明“所有项目”或“本机全局”, - 不得显示为“当前项目已启用”。 -- `STATE-006`:本机包安装仍是 prepare → 用户确认 → commit 的对话流程;页面不得提供 - install picker。 -- `STATE-007`:system-included 和 code-owned bundled 插件不得显示不适用的下载、更新、 - Beta、签名或设备删除动作。 -- `STATE-008`:项目中保留但当前无法解析的 plugin ID 必须继续显示,并只提供明确的 - “从项目禁用”动作。 - -### 4.3 Web Search - -- `WEB-001`:所选模型的原生 `makelore_web_search` MUST NOT 进入统一插件投影。 -- `WEB-002`:原生 Web Search 的可用性属于模型/Agent capability UI。 -- `WEB-003`:若用户通过对话安装第三方 Web Search package,它只以“本机”来源显示, - 并遵守 Device Package 的全局启停与新会话加载合同。 - -## 5. 页面信息架构 - -### 5.1 页面头部 - -页面标题固定为“插件”,说明文案必须同时表达: - -- 官方插件由 MakeLore 运营发布; -- 本机 Skill/extension 通过对话安装; -- 获取、项目启用和 Agent 分配是独立步骤。 - -页面提供一个刷新按钮。刷新 MUST 独立触发可用的数据源,不得因为一个 Promise reject -而跳过其他数据源。 - -### 5.2 筛选 - -筛选参数是 URL query 的 canonical 状态: - -```ts -type PluginWorkspaceScope = 'all' | 'project'; -type PluginWorkspaceSource = 'all' | 'official' | 'local'; -type PluginWorkspaceState = - | 'all' - | 'available' - | 'mine' - | 'enabled' - | 'update' - | 'unavailable'; -``` - -裸 `/plugins` 的默认 `scope` 与侧栏一致:存在当前项目时为 `project`,否则为 `all`。 -实现等待 workspace hydration 后只规范化一次 URL,禁止因后续异步投影反复改写用户选择。 -详情可以使用可选的 `plugin=` query;无效或已消失的 key 只关闭详情, -不影响其余筛选。 - -用户可见控件: - -- 范围:`全部插件` / `当前项目`; -- 来源:`全部来源` / `官方` / `本机`; -- 状态:`全部状态` / `可获取` / `我的` / `已启用` / `可更新` / `不可用`; -- 搜索:名称、简介、标签、package ID。 - -要求: - -- `FILTER-001`:未知 query 值 MUST 归一为默认值,不得导致白屏。 -- `FILTER-002`:`scope=project` 且没有当前项目时 MUST 回到 `scope=all`,并显示一次 - 非阻断说明。 -- `FILTER-003`:`state=mine` 表示官方 system-included/当前已获取项与全部本机安装项; - 不等同于“已下载到设备”。 -- `FILTER-004`:官方搜索词 MUST 发送给现有目录搜索;同一搜索词 MUST 同时在本地过滤 - 已知 Library、项目投影和 Device Package。 -- `FILTER-005`:远端搜索失败不得清空符合条件的本机结果。 -- `FILTER-006`:筛选只影响展示,不得触发 acquisition、install 或 enable mutation。 - -范围语义固定为: - -- `scope=all`:官方 catalog/Library/project 已知条目的并集、全部本机包,以及必要的 - project retained 条目; -- `scope=project`:当前 project projection 的官方条目、全部本机包和 retained IDs。 - 本机包必须放在“本机全局生效”分组,不能伪装成项目 assignment; -- `state=available`:当前可免费获取且尚未获取的官方条目; -- `state=mine`:system-included、当前已获取的官方条目及全部本机包; -- `state=enabled`:当前项目已启用的官方条目及本机全局已启用条目; -- `state=update`:现有官方设备包明确存在同频道更新的条目; -- `state=unavailable`:暂停、退役后不可重新获取、client incompatible、投影 unavailable - 或 retained 的条目。 - -默认排序不得依赖异步完成顺序:官方 catalog 项保持服务端目录顺序,随后是 Library-only、 -project-only、按显示名排序的本机包,最后是 retained IDs;`scope=project` 时先保持 project -projection 顺序,再列本机包和 retained IDs。 - -### 5.3 列表与卡片 - -每张卡片必须在一个位置展示适用的状态维度: - -- 来源:`官方` / `本机` / `配置保留`; -- 交付:`随 MakeLore 提供` / `账号已获取` / `本机已安装` / `尚未获取`; -- 当前项目:`已启用` / `未启用` / `暂不可用`; -- 本机包:`本机全局已启用` / `本机全局已停用`; -- Agent:已分配伙伴数量或“尚未分配”; -- 计费:`包含` / `按 Token Point` / `混合` / `无平台插件计费投影`; -- 更新、暂停、退役、缓存或不可用提示。 - -卡片不得用一个“已安装”标签混淆 Account Library、官方设备包和本机包。 - -### 5.4 详情面板 - -选择卡片后打开一个统一详情抽屉或同页详情面板,内容顺序固定为: - -1. 名称、来源、发布者和版本; -2. 介绍; -3. 当前账号/设备/项目状态; -4. 主动作; -5. 能力与权限; -6. Token Point 说明; -7. Agent 分配; -8. 插件专属设置。 - -官方详情按需调用现有 `loadDetail(pluginId)`。本机详情只能使用 Device Package 的安全 -Renderer 投影,不得读取包目录、任意 manifest 文件或绝对安装路径。 - -Data Service 设置 Surface 必须迁移到新详情面板,行为和 destructive confirmation 保持 -不变。 - -## 6. 统一投影 Module - -### 6.1 Seam - -在 Renderer 增加一个纯计算的 `PluginWorkspaceProjection` Module。它是页面唯一学习的 -聚合 Interface;它不发网络请求、不写 store、不持久化数据。 - -建议位置: - -```text -src/pages/Plugins/ - index.tsx - plugin-workspace-model.ts - PluginDetails.tsx -``` - -外部 Interface: - -```ts -interface PluginWorkspaceInputs { - catalog: MarketplaceCatalogPage | null; - details: Readonly>; - library: MarketplaceLibrarySnapshot | null; - marketplaceInstallations: Readonly>; - devicePackages: DevicePackageIndexV1 | null; - project: CodingPluginProject | null; - activeProject: { id: string; name: string } | null; - agentNames: Readonly>; - filters: PluginWorkspaceFilters; -} - -interface PluginWorkspaceProjection { - items: readonly PluginWorkspaceItem[]; - selected: PluginWorkspaceItem | null; - counts: Readonly>; - notices: readonly PluginWorkspaceNotice[]; -} - -function buildPluginWorkspaceProjection( - input: PluginWorkspaceInputs, -): PluginWorkspaceProjection; -``` - -页面可以保留短暂的 selected key 与 filter form state;不得新增第二个持久 Zustand authority。 - -### 6.2 稳定身份 - -统一条目 key 必须带来源,禁止按裸 ID 把本机包和官方插件合并: - -```ts -type PluginWorkspaceKey = - | `official:${string}` - | `local:${string}` - | `retained:${string}`; -``` - -投影算法: - -1. 按 `pluginId` 合并 catalog、detail、Library、官方设备包和 project item; -2. catalog 不含但 Library 或 project 仍存在的官方条目不得丢失; -3. 每个 Device Package 始终生成独立的 `local:` 条目; -4. `unknownPluginIds` 中仍未被官方条目解释的 ID 生成 `retained:` 条目; -5. 不得根据相同 Skill ID、显示名或 package ID 推断二者是同一插件。 - -### 6.3 Action union - -投影条目只暴露当前合法动作: - -```ts -type PluginWorkspaceCommand = - | { kind: 'acquire'; pluginId: string } - | { kind: 'reacquire'; pluginId: string } - | { kind: 'remove_from_library'; pluginId: string } - | { kind: 'install_stable'; pluginId: string } - | { kind: 'install_beta'; pluginId: string } - | { kind: 'update_official'; pluginId: string } - | { kind: 'remove_official_device_package'; pluginId: string } - | { kind: 'enable_project'; projectId: string; pluginId: string } - | { kind: 'disable_project'; projectId: string; pluginId: string } - | { kind: 'enable_local'; packageId: string } - | { kind: 'disable_local'; packageId: string } - | { kind: 'remove_local'; packageId: string } - | { kind: 'open_agent_assignment'; projectId: string; pluginId: string } - | { kind: 'open_settings'; projectId: string; pluginId: string }; -``` - -页面使用单一局部 dispatcher 将 command 交给现有三个 store。dispatcher 不是状态 authority, -不得复制 generation、pending 或 retry 逻辑。 - -### 6.4 Action matrix - -| 条目类型 | 账号动作 | 设备动作 | 项目动作 | Agent 动作 | -| --- | --- | --- | --- | --- | -| system-included 官方插件 | 无 | 无 | 启用/禁用 | 分配 | -| code-owned bundled、已获取 | 移除 | 无 | 启用/禁用 | 分配 | -| code-owned bundled、未获取 | 免费获取 | 无 | 无 | 无 | -| downloadable 官方插件、已获取 | 移除 | 下载/更新/Beta/删除设备包 | 交付就绪后启用/禁用 | 分配 | -| downloadable 官方插件、未获取 | 免费获取 | 无 | 无 | 无 | -| 本机 Device Package | 无 | 本机全局启用/停用/移除 | 无 | 无;自动进入符合条件的新/空闲 parent | -| retained project ID | 无 | 无 | 仅从项目禁用 | 无 | - -暂停、退役、removed、client-incompatible 或 unavailable 状态继续遵守现有 store/DTO 的 -fail-closed 语义;统一页面不得为了显示按钮而自行放宽。 - -## 7. 数据加载与错误隔离 - -### 7.1 首次加载 - -页面挂载时独立启动: - -1. `pluginMarketplaceStore.loadCatalog({ limit: 24 })`; -2. 登录时 `activateAccount(accountKey)` + `loadLibrary()`; -3. `devicePackageStore.load()`; -4. 存在当前项目时 `codingPluginsStore.load(projectId)`。 - -实现 MUST 使用独立 catch 或 `Promise.allSettled` 等价行为。禁止一个请求失败阻止其他请求。 - -### 7.2 部分失败 - -| 失败来源 | 必须保留的内容 | -| --- | --- | -| catalog | 可信缓存、Library 项、本机包、项目投影 | -| Library | 官方目录、本机包、项目保留配置;账号状态显示未知 | -| official Package Store | Library 和项目配置;保留旧设备版本与错误原因 | -| Device Packages | 官方目录、Library 和项目插件 | -| project projection | 官方目录、Library、本机包;当前项目区域显示独立错误 | - -- `ERR-001`:错误必须靠近对应来源显示,禁止整页 error boundary。 -- `ERR-002`:已有可信缓存时继续展示并标记 stale。 -- `ERR-003`:没有权威值时显示未知,不得从另一来源推断 acquisition、pricing 或 enablement。 -- `ERR-004`:账号或项目切换必须使旧 generation 结果失去提交资格;复用现有 store 保护, - 统一层不得另建竞态较弱的缓存。 -- `ERR-005`:选择项在新投影中消失时关闭详情;不得把 A 项详情显示到 B 项。 - -## 8. 计费与文案 - -- `BILL-001`:“免费获取”只描述加入账号插件库,不能写成“免费使用”。 -- `BILL-002`:列表只显示 `included`、`token_point`、`mixed` 的简洁摘要。 -- `BILL-003`:详情中的 operation 级价格只来自 Marketplace detail 或当前 project policy - projection;不得由客户端计算、缓存拼接或从 manifest 推断。 -- `BILL-004`:stale/unavailable pricing 必须显示对应状态,不作为新的 runtime admission 依据。 -- `BILL-005`:本机包显示“无 MakeLore 平台插件计费投影”,不得承诺其外部服务或模型调用 - 一定免费。 - -## 9. 交互与可访问性 - -- `A11Y-001`:范围、来源、状态必须有可读 label,并可用键盘完成选择。 -- `A11Y-002`:当前筛选状态必须同时体现在 URL 与控件状态中。 -- `A11Y-003`:状态不得只靠颜色表达,必须有文本。 -- `A11Y-004`:详情抽屉使用 dialog 语义、初始焦点、Esc 关闭,并在关闭后把焦点还给原卡片。 -- `A11Y-005`:loading 用 `role=status`,阻断错误用 `role=alert`。 -- `A11Y-006`:destructive action 必须继续使用确认对话框;确认文案包含具体插件名和作用域。 -- `A11Y-007`:按钮文字必须区分“从账号移除”“删除设备包”“从项目禁用”“移除本机包”。 -- `A11Y-008`:窄窗口中筛选可以换行,卡片主动作仍保持至少 40 px 点击高度。 - -## 10. 文件级改造建议 - -### 10.1 新增 - -| 文件 | 责任 | -| --- | --- | -| `src/pages/Plugins/index.tsx` | route orchestration、独立加载、query state、command dispatch | -| `src/pages/Plugins/plugin-workspace-model.ts` | 纯统一投影、identity、筛选、排序、actions、notices | -| `src/pages/Plugins/PluginDetails.tsx` | 详情、能力、计费、Agent 与 Data Service settings surface | -| `tests/unit/plugin-workspace-model.test.ts` | 深 Module Interface 测试 | -| `tests/unit/plugins-page.test.tsx` | 页面、部分失败、动作与可访问性测试 | - -文件名可以按仓库命名习惯微调,但 Module 责任不得重新散回三个页面。 - -### 10.2 修改 - -| 文件 | 改造 | -| --- | --- | -| `src/App.tsx` | 注册 `/plugins`;旧 route replace redirect;移除三个 lazy page | -| `src/components/layout/Sidebar.tsx` | 三入口收敛为 `sidebar-nav-plugins` | -| `src/components/layout/MainLayout.tsx` | `/plugins` 为 initialization-safe route | -| `src/lib/ai-modules.ts` | 新 route 加入 Code module;不加入全页 Provider gate | -| `tests/unit/plugin-marketplace-pages.test.tsx` | 迁移到统一页面行为或删除被替代测试 | -| `tests/unit/project-plugins-page.test.tsx` | 迁移项目投影/settings/unknown ID 行为 | -| `tests/unit/main-layout-module-gate.test.tsx` | 新 route 与 redirects | -| `tests/e2e/plugin-marketplace.spec.ts` | 统一导航、发现、我的、本机和部分失败 | -| `tests/e2e/project-plugins.spec.ts` | 当前项目筛选、启停、Agent 跳转与 settings | -| artifact proof tests | 更新 canonical route/marker,保持 Main authority 检查 | - -### 10.3 删除 - -完成行为迁移后删除: - -```text -src/pages/PluginMarketplace/ -src/pages/MyPlugins/ -src/pages/ProjectPlugins/ -``` - -禁止保留旧页面作为 hidden fallback 或让旧、新页面同时拥有产品行为。 - -### 10.4 保持不变 - -以下 Module 继续拥有现有 Interface: - -```text -src/stores/plugin-marketplace.ts -src/stores/device-packages.ts -src/stores/coding-plugins.ts -src/lib/plugin-marketplace.ts -src/lib/device-packages.ts -src/lib/coding-plugins.ts -electron/api/routes/plugin-marketplace.ts -electron/api/routes/device-packages.ts -electron/coding-plugins/** -electron/coding-packages/** -``` - -若实施证据显示必须改变这些 Interface,应先停止并修订本 Spec,不能静默扩大范围。 - -## 11. 验证合同 - -### 11.1 统一投影单元测试 - -至少覆盖: - -1. 同一官方 ID 从 catalog/Library/device/project 正确合并为一个条目; -2. 同名或同 ID 的本机 package 与官方插件保持两个来源 key; -3. Library-only retired/removed 条目不会因当前 catalog query 缺失而消失; -4. project-only unknown ID 生成 disable-only retained 条目; -5. system-included 无获取、下载、更新或移除动作; -6. code-owned bundled 无设备包动作; -7. generic downloadable 插件保留现有 stable/Beta/update/remove 行为; -8. 本机包只有全局启停和移除动作; -9. `mine`、`project`、source、state 与 search 组合筛选; -10. 原生模型 Web Search 不进入投影; -11. Token Point 摘要不把免费获取误写为免费使用; -12. 任一输入来源为 null/error 时其他条目仍存在。 - -### 11.2 Renderer 页面测试 - -至少覆盖: - -1. 仅一个页面标题和一组筛选控件; -2. catalog 失败时本机包仍显示; -3. Device Package 失败时官方条目仍显示; -4. 未登录时目录和本机包可见,账号动作要求登录; -5. 项目切换后旧 enable/disable confirmation 不得操作新项目; -6. 详情选择 A→B 时 A 的迟到 detail 不覆盖 B; -7. Data Service settings surface 行为迁移无回归; -8. local package 页面没有安装按钮、文件选择器或 source 输入框; -9. destructive action 的 label 与 confirmation 精确区分作用域; -10. keyboard、focus return、status/alert 语义。 - -### 11.3 路由与侧栏测试 - -- 侧栏只存在 `sidebar-nav-plugins`。 -- active project 与 no-project 点击目标正确。 -- 三个旧地址按第 4.1 节映射并使用 replace。 -- `/plugins` 受 Code module access 管理,但不被项目初始化或 Provider 全页 gate 阻断。 -- 登录回跳使用 `/plugins` canonical query,不再写旧 route。 - -### 11.4 Electron E2E - -至少覆盖四条真实 Renderer → Main Host API 流程: - -1. 官方目录 → 免费获取 → `state=mine` 可见,但项目仍未启用; -2. 当前项目启用/禁用插件,Agent 分配跳转仍正确; -3. catalog 503 时已安装本机 Skill 仍可见并可停用/启用; -4. system-included、code-owned bundled、本机包三类动作不会互相串线。 - -### 11.5 必跑命令 - -实施任务至少运行: - -```text -pnpm run typecheck -pnpm run lint:check -pnpm test -pnpm run build:vite -pnpm run test:e2e -- tests/e2e/plugin-marketplace.spec.ts tests/e2e/project-plugins.spec.ts -``` - -若仓库脚本不接受上述 E2E 过滤语法,可使用项目已有的等价精确命令并在任务记录中写明。 -任何失败必须区分本次回归、既有基线和环境阻塞,不得只报告总数。 - -## 12. 实施顺序 - -### `PN-01`:统一投影 Module - -所有权:`src/pages/Plugins/plugin-workspace-model.ts` 与其测试。 - -交付:identity、merge、filter、action matrix、partial-input 行为。此票据不改 route 或旧页面。 - -### `PN-02`:统一页面与详情 - -所有权:`src/pages/Plugins/**`、必要页面测试。 - -交付:加载协调、列表、详情、commands、Data Service settings、可访问性。调用现有 stores, -不改 Main contracts。 - -### `PN-03`:导航硬切换 - -所有权:`src/App.tsx`、Sidebar、MainLayout、`ai-modules.ts`、route/module tests。 - -交付:唯一侧栏入口、canonical route、legacy redirects、旧页面删除。依赖 `PN-02`。 - -### `PN-04`:回归与交付验证 - -所有权:插件 E2E、artifact markers、README 和 task-scoped evidence。 - -交付:全量静态/单元/build/Electron 验证,确认没有旧入口、hidden fallback 或安装 picker。 - -建议单仓串行实施 `PN-01 → PN-02 → PN-03 → PN-04`,避免多个任务同时改页面测试和路由。 - -## 13. Definition of Done - -只有同时满足以下条件才可宣称完成: - -1. 侧栏与 route 只剩一个 canonical 插件入口。 -2. 三个旧页面实现已删除,旧地址只做 redirect。 -3. 统一投影有独立 Interface 测试,页面不直接散落跨 store 合并判断。 -4. Catalog、Library、官方设备包、本机包、项目和 Agent 状态仍各自归原 owner。 -5. 官方、本机和 retained 项的动作矩阵全部通过测试。 -6. catalog 或 project 任一失败不会遮蔽本机包;Device Package 失败不会遮蔽官方目录。 -7. 没有可见本机安装入口。 -8. 原生模型 Web Search 不出现在插件列表;第三方本机包仍可出现。 -9. Data Service 设置、Game Resource 获取/项目启用和本机 Skill 启停均无回归。 -10. typecheck、lint、unit、Vite build 和目标 Electron E2E 通过。 -11. 实施任务完成项目文档门禁;canonical 架构更新只在 Integration Gate 进行。 - -## 14. 后续但不属于本次 - -若未来要让本机 Skill 按项目或 Agent 单独启用,必须另立领域设计:它会改变 Device Package -当前“本机全局、所有符合条件 parent 自动加载”的合同,不能作为本次导航合并的顺手功能。 diff --git a/.project-docs/20-architecture/module-map.md b/.project-docs/20-architecture/module-map.md index a6c8699..723f24b 100644 --- a/.project-docs/20-architecture/module-map.md +++ b/.project-docs/20-architecture/module-map.md @@ -10,7 +10,7 @@ | `electron/coding-runtime/pi/model-tools/**` and `shared/model-tools.ts` | Closed selected-model tool registry and provider-specific Web Search request shaping | The frozen selected model capability controls whether `makelore_web_search` exists. The tool uses that model/provider/credential and normal model billing; no Hosted Plugin adapter, Admission, Plugin Charge, or browser fallback exists. | | `electron/coding-packages/**`, `electron/api/routes/device-packages.ts`, `shared/device-packages.ts`, and `src/stores/device-packages.ts` | Main-owned conversation install preview/confirmation/commit, immutable local package generations, safe Renderer projection, and parent-worker refresh | Sources are npm, Git, absolute local Plugin directories, or loose `SKILL.md`. Lifecycle scripts are disabled; executable extensions run with desktop-user authority after explicit confirmation. Every generation projects all explicitly installed and currently enabled Skills/extensions; Device Packages never join Account Library, Marketplace Package Store, Release, Channel, or Admission state. | | `electron/coding-plugins/adapters/game-resource.ts` and `electron/services/game-resource-client.ts` | Provider-neutral `makelore.game-resource` hosted tool adapter and Main-owned Works Square transport | Tools materialize only from an eligible frozen `platform_hosted` parent snapshot. Metered mutations require explicit confirmation and stable logical operation identity; Renderer/Pi never receive Provider URLs, credentials, balances, raw responses, or Provider job IDs. | -| `electron/api/routes/plugin-marketplace.ts`, `src/stores/plugin-marketplace.ts`, `src/pages/PluginMarketplace/`, `src/pages/MyPlugins/`, and `src/pages/ProjectPlugins/` | Bounded Main routes and Renderer projections for Marketplace catalog, Account Library, official package-device state, local Device Packages, and project actions | Renderer receives no Account token, filesystem path, Admission, package bytes, signed download URL, or install-source picker. My Plugins separates Official Plugins from Device Installed. Catalog/Library/device/project generations prevent stale A/B or cross-action results from replacing current state. | +| `electron/api/routes/plugin-marketplace.ts`, `src/stores/{plugin-marketplace,device-packages,coding-plugins}.ts`, and `src/pages/Plugins/` | Existing Main/store authorities plus the pure unified Renderer projection for official catalog, Account Library, official package-device state, local Device Packages, retained IDs, and current-project actions | `/plugins` is the sole canonical surface; legacy Plugin routes only replace-redirect into deterministic filters. `official:`, `local:`, and `retained:` identities stay separate, source failures are isolated, and no Account token, filesystem path, Admission, package bytes, signed URL, or visible install-source picker enters Renderer. | | `src/components/works/ProjectPublishAction.tsx` | 可发布项目的一键提交、云构建轮询与用户可理解状态 | 只通过 Renderer API 提交非敏感元数据;绑定告警不终止轮询 | | `src/lib/works-square.ts` | Renderer 侧 Works Square Host API 契约与安全错误映射 | 不接触 Token、ZIP、本地绝对路径或自动部署状态 | | `electron/api/routes/works.ts` | Works Host API、Renderer capability 门禁、上游安全投影 | 发布凭据、打包、上传与本地绑定均在 Main 内完成 | @@ -88,4 +88,4 @@ ## Last Updated -2026-08-31 +2026-09-03 diff --git a/.project-docs/30-worklog/current-state.md b/.project-docs/30-worklog/current-state.md index 04fac7f..7030e0a 100644 --- a/.project-docs/30-worklog/current-state.md +++ b/.project-docs/30-worklog/current-state.md @@ -4,6 +4,20 @@ This file is the integrated default-branch snapshot. Feature tasks record progre ## Integrated Through +- Unified Plugin workspace product head + `d7058e6383f1e9dd72c32570cf83b9f439d91033` is integrated on local `main` by + task `20260903-plugin-navigation-integration-4f7c2a96` after fixed-range R4 + Standards and Spec review passed with zero findings. Code now has one canonical + `/plugins` route and one `插件` sidebar entry; the former Marketplace, My Plugins, + and Project Plugins routes are replace-only redirects into deterministic filters. + A pure Renderer projection composes official catalog/Library/device state, local + Device Packages, current-project state, and retained IDs while preserving their + existing owners and source-qualified identities. Local Skill/extension installation + remains conversation-only, native selected-model Web Search remains outside the + Plugin list, and partial source failures do not erase other sources. Focused 83-test, + typecheck, full-unit, lint, Vite, and targeted 4/4 Electron evidence passed across + implementation, remediation, and final acceptance. No server contract, runtime, + billing, package, deployment, publication, or user-machine installation changed. - Packaged Device Package preparation source `5a2f0eb6785b59d8b455ed5cb1d9773351ff895a` from task `20260902-local-skill-install-fix-6b3e91a4` and installed-resource activation @@ -53,8 +67,9 @@ This file is the integrated default-branch snapshot. Feature tasks record progre loose `SKILL.md` sources. Preview and a distinct confirmation turn precede immutable local commit; lifecycle scripts stay disabled; new and idle parent workers refresh automatically while active workers switch after settlement; child workers remain - empty. My Plugins now separates Official Plugins from Device Installed packages and - exposes no visible install picker. The later packaged prepare and multi-extension + empty. At that frontier My Plugins separated Official Plugins from Device Installed + packages and exposed no visible install picker; the unified `/plugins` workspace + recorded above now presents those sources together without merging authority. The later packaged prepare and multi-extension activation corrections are recorded above; rebuilt exact-main installed-client acceptance and real selected-model search remain external gates. No paid Provider request, production install, publish, push, or PR is claimed. @@ -261,8 +276,9 @@ This file is the integrated default-branch snapshot. Feature tasks record progre `20260830-integrate-plugin-marketplace-client-6e3b9d82`. Electron Main now owns the authenticated Marketplace/Library client, immutable Package Store, trusted release verification, effective installed-plugin resolution, and frozen Pi worker - materialization; Renderer exposes Marketplace, My Plugins, and Project Plugins - projections without receiving credentials, paths, Admissions, or signed URLs. + materialization. Its original Marketplace, My Plugins, and Project Plugins Renderer + surfaces are superseded by the unified `/plugins` projection recorded above; + Renderer still receives no credentials, paths, Admissions, or signed URLs. Data Service remains system-included and consumes zero Token Points. R7 Standards and Spec reviews passed with zero findings, and XMA-01 passed all twelve live groups against real PostgreSQL and a signed-in packaged Windows client. The later @@ -530,4 +546,4 @@ Robot 绑定设备默认先显示“引导配网 / 已有激活码”路径选 ## Last Updated -2026-09-02 +2026-09-03 diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-design-7c4e2a91.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-design-7c4e2a91.md deleted file mode 100644 index 5841aed..0000000 --- a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-design-7c4e2a91.md +++ /dev/null @@ -1,88 +0,0 @@ -# Task: Design unified MakeLore plugin navigation - -## Identity - -- Task ID: 20260903-plugin-navigation-design-7c4e2a91 -- Mode: Feature -- Branch: codex/20260903-plugin-navigation-design-7c4e2a91-plugin-navigation-design -- Worktree: D:\Datas\OthersProjects\makelore-plugin-navigation-design-7c4e2a91 -- Base commit: e9875145b41a2cb1827de10d27a4fc6a352704ea -- Owner: codex-root-plugin-nav -- Status: Ready for Integration - -## Scope - -- Product and architecture assessment of the current Plugin Marketplace, My Plugins, - Project Plugins, local Device Package, and sidebar/router surfaces. -- Compare the current navigation model with OpenAI's documented Codex Plugins - directory and propose one unified MakeLore Plugin surface. -- Write the task-owned implementation proposal - `10-decisions/proposals/20260903-plugin-navigation-design-7c4e2a91__unified-plugin-workspace-spec.md`. -- No product, route, state, server contract, package, or canonical shared-memory - changes. - -## Intent And Constraints - -- Preserve the independent authorities for catalog, Account Library, device bytes, - project enablement, Agent assignment, runtime admission, and billing even though - their user interface is consolidated. -- Keep local npm/Git/Plugin/loose-Skill installation conversation-only; the unified - page may manage installed Device Packages but must not add an install picker. -- Treat selected-model Web Search as a model tool, not a Marketplace Plugin. -- Avoid semantic overlap with concurrent task - `20260903-design-message-send-client-8d3f2a71`, whose owner confirmed it does not - touch Plugin navigation, pages, sidebar, or router. - -## Outcome - -- Recommend one sidebar entry and canonical `/plugins` page. -- The page should use one searchable list with source/status/scope filters rather - than three destination tabs: official catalog and locally installed packages are - source projections; acquired/installed/enabled are status filters; the active - project is a scope filter. -- One Plugin detail panel should compose description, capabilities, Token Point - summary, account/device state, current-project enablement, Agent assignments, and - plugin-specific settings while dispatching each mutation to its existing owner. -- Legacy `/plugin-marketplace`, `/my-plugins`, and `/project-plugins` routes should - redirect to deterministic `/plugins` query states during the navigation cutover. -- Official Data Service and Game Resource remain Plugin entries. Model Web Search - belongs in selected-model capabilities and should not appear as a Plugin card. -- A unified projection must tolerate partial backend failure: cached official data - and local Device Packages remain visible independently. -- The accepted direction is now frozen as Spec `ML-PLUGIN-NAV-001`, including the - pure Renderer projection Interface, source-qualified item identity, action matrix, - exact legacy redirects, partial-failure behavior, accessibility contract, file - ownership, tests, four implementation stages, and Definition of Done. - -## Verification - -- Concurrent Task Gate PASS after the peer owner confirmed disjoint scope. -- Planning Gate PASS after reading the required project memory, architecture, - domain rules, and current integrated state. -- Inspected current sidebar/router and all three Renderer Plugin pages on exact base - `e9875145b41a2cb1827de10d27a4fc6a352704ea`. -- Reviewed official OpenAI Plugins documentation for the single directory, - marketplace-source grouping, Installed projection, enable/disable behavior, and - new-session activation semantics. -- Re-ran the Concurrent and Planning Gates before writing the implementation Spec; - the AI Design peer still has disjoint file and semantic ownership. -- Re-inspected current Renderer stores, DTO projections, page actions, route/module - guards, sidebar entries, unit tests, E2E seams, and canonical Device Package/model - tool rules on the recorded base. -- No executable tests were run because this task makes no product changes; tests - would not alter the design conclusion. - -## Follow-ups - -- Implement `PN-01` through `PN-04` serially in an isolated client task after explicit - implementation authorization. -- Run fresh Standards and Spec review over the implementation range before promotion - to `main`. - -## Promotion Candidates - -- If accepted, promote the single-Plugin-surface navigation and state-as-filter - distinction into the architecture/module map during the later Integration Gate. -- Promote the explicit distinction between native selected-model tools and Plugin - entries into the user-facing glossary if future UI work makes that distinction - visible outside Code. diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-implementation-a4c7e291.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-implementation-a4c7e291.md deleted file mode 100644 index 8418e22..0000000 --- a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-implementation-a4c7e291.md +++ /dev/null @@ -1,162 +0,0 @@ -# Task: Implement unified plugin workspace ML-PLUGIN-NAV-001 - -## Identity - -- Task ID: 20260903-plugin-navigation-implementation-a4c7e291 -- Mode: Feature -- Branch: codex/20260903-plugin-navigation-implementation-a4c7e291-plugin-navigation-implementation -- Worktree: C:\Users\7brot\.codex\worktrees\1721\makelore -- Base commit: 959e2faf03dfacb3c8e2035e44774436c752d4b0 -- Owner: codex -- Status: Ready for Integration - -## Scope - -- Implement approved Spec `ML-PLUGIN-NAV-001` serially as PN-01 through PN-04: - a pure source-qualified Renderer projection, one `/plugins` workspace and detail - surface, a hard route/sidebar cutover with exact replace redirects, removal of the - three superseded page implementations, and focused/full/Electron verification. -- Own only the Spec-listed Renderer page/navigation/tests/artifact-marker/README - paths plus this task record. Preserve the existing Marketplace, Device Package, - Coding Plugin, Agent assignment, runtime admission, and billing authorities. - -## Intent And Constraints - -- Concurrent Task Gate passed for the exact identity/base/worktree above. The - superseded exact-overlap task `20260903-plugin-navigation-implementation-6b4d9e21` - was released from the registry after source-thread adjudication; its worktree, - branch, and record were not removed or modified by this task. -- Planning Gate passed after reading repository guidance, the complete Spec, startup - project memory, architecture/domain rules, relevant indexes, and the completed AI - Design peer record. That peer explicitly excludes plugin pages, navigation, - Sidebar, and router, so no semantic overlap remains. -- Confirmed public test seams are `buildPluginWorkspaceProjection`, the unified - Renderer page/local dispatcher/detail dialog, route/sidebar/module guards, and the - targeted Renderer-to-Main Electron flows. Work vertically red -> green at those - seams rather than mocking internal modules. -- Use `official:`, `local:`, and `retained:` identity without inferred cross-source - merging. Keep local installation conversation-only, native selected-model Web - Search out of the projection, system-included actions restricted, and local package - state explicitly device-global. -- Do not change Server, Electron Main/plugin contracts, the three existing stores, - Package Store/runtime/billing authority, app identity/global paths, or add a - persistent Zustand authority, compatibility layer, feature flag, or visible local - installation picker. -- Do not write or clean `D:\\Datas\\OthersProjects\\makelore`; do not push, create a - PR, deploy, publish, install a package, or merge `main`. - -## Project Context Loaded - -- Project goal: present official, acquired, local-device, project, and Agent Plugin - state through one understandable UI while preserving each existing authority. -- Current integrated focus: curated Marketplace Release A, system-included Data - Service, code-owned bundled Game Resource, conversation-only Device Packages, and - selected-model native Web Search are already integrated contracts. -- Decisions affecting this task: acquisition/device delivery/project enablement/Agent - assignment/runtime admission/billing remain independent; Device Packages are - device-global and child workers remain empty; Renderer access stays behind typed - Host API facades. -- Relevant evidence: the integrated Marketplace and Device Package suites establish - the current DTO/authority behavior; installed-client Device Package activation is a - separate release gate and is not claimed by this UI task. -- Likely modules: `src/pages/{PluginMarketplace,MyPlugins,ProjectPlugins,Plugins}`, - `src/App.tsx`, layout navigation/guards, `src/lib/ai-modules.ts`, their unit/E2E and - artifact marker tests, and `README.md`. -- Unknown to verify before implementation: whether the current public Renderer DTOs - express every Spec field without contract changes. A real interface conflict blocks - that range rather than authorizing a wrapper or compatibility path. -- Non-blocking stale context: canonical `module-map.md` still names the old three-page - UI and must be proposed for later Integration Gate promotion, not edited in feature - mode. - -## Outcome - -- `PN-01` added the pure `buildPluginWorkspaceProjection` interface, canonical - query parser/serializer, and a local command dispatcher. The projection keeps - `official:`, `local:`, and `retained:` identities separate; preserves - catalog/Library/project-only/local/retained entries under partial failures; - excludes only the native selected-model `makelore_web_search`; and derives the - Spec action matrix without writing a store. -- `PN-02` replaced the three page-specific views with one `/plugins` workspace and - one detail dialog. It independently loads Catalog, Library, Device Packages, and - current-project projection; exposes URL-backed scope/source/state/search/detail - state; keeps source errors local; dispatches every action to its existing owner; - embeds the existing Data Service settings surface; resets project-scoped - confirmation on project change; and provides dialog focus, Escape, focus-return, - status, alert, and destructive-scope semantics. -- `PN-03` reduced the Code sidebar to `sidebar-nav-plugins`, registered the - initialization-safe and non-provider-gated canonical route, added the three exact - replace redirects, and deleted the old Marketplace, My Plugins, and Project - Plugins implementations and their superseded page tests. No hidden fallback - implementation remains. -- `PN-04` updated the targeted Electron flows, product artifact markers, and - `README.md`. The E2E authenticated fixture now starts a fresh Renderer document - against a Main-owned session and `/api/auth/me` identity; this removed a measured - reload/localStorage setup race without changing product authentication code. -- Actual changed scope is limited to `src/pages/Plugins/**`, the listed route/layout - files, deletion of the three old page directories, focused unit/Electron tests, - `scripts/lib/pi-product-artifact.mjs`, `README.md`, and this task record. No - Server, Electron Main, Marketplace/Device/Coding store, Package Store, runtime, - billing, or persistence authority was changed; no fourth Zustand authority was - added. - -## Verification - -- `corepack pnpm run typecheck` — passed after the final E2E fixture edit. -- `corepack pnpm run lint:check` — passed with 0 errors. Five pre-existing warnings - remain in untouched files: one `react-hooks/exhaustive-deps` warning in - `src/pages/Home/index.tsx` and four `react-refresh/only-export-components` - warnings in `src/pages/Makelore/index.tsx`. -- `corepack pnpm test` — passed: 225 regular test files with 1821 passed and 2 - skipped tests, followed by the isolated pressure file with 1 passed test. -- `corepack pnpm run build:vite` — passed for Renderer, Electron Main, Preload, and - utility worker. Existing warnings remain for stale Browserslist data, - static/dynamic imports, and the existing large Renderer chunk. -- `corepack pnpm run test:e2e -- tests/e2e/plugin-marketplace.spec.ts - tests/e2e/project-plugins.spec.ts --reporter=line` — passed after its production - build with all 4 targeted Renderer-to-Main flows. -- `corepack pnpm exec playwright test tests/e2e/plugin-marketplace.spec.ts -g - "keeps system, bundled, and local actions" --repeat-each=10 --workers=1 - --reporter=line` — 10/10 passed after stabilizing the authenticated fixture. -- `corepack pnpm exec vitest run tests/unit/pi-product-artifact.test.ts - --maxWorkers=1` — passed: 15/15 artifact proof tests. -- Focused projection/query/controller/page/navigation/Main-layout suites passed; - the final page suite passed 5/5, including project-switch confirmation reset and - dialog initial-focus/Escape/focus-return behavior. -- Existing parent/child/worker lifecycle coverage passed in the full suite through - `coding-plugin-effective-resolver`, `pi-managed-worker-opener`, - `device-package-manager`, and `device-package-routes` tests. -- `check_doc_drift.py --task-id - 20260903-plugin-navigation-implementation-a4c7e291` — passed the feature-task - ownership boundary check. -- `git diff --check` passed before Task Documentation Gate finalization. -- One full-suite run transiently failed the untouched Marketplace client temp - Package Store install case; its exact isolated rerun passed 1/1 and the subsequent - full suite passed as recorded above. An earlier targeted E2E run exposed the - test-only auth reload race; trace inspection showed no Library request and a - signed-out persisted fixture, after which the clean-document Main-session fixture - passed 10/10 and the formal targeted command passed 4/4. - -## Follow-ups - -- No implementation follow-up or product deviation is known. The canonical module - map promotion below remains intentionally deferred to an Integration Gate. - -## Promotion Candidates - -- Target: `.project-docs/20-architecture/module-map.md`. -- Proposal: replace the three legacy Renderer plugin pages with the pure unified - projection, `/plugins` workspace/detail surface, canonical query state, and exact - legacy redirects; keep Catalog, Library, official Package Store, Device Packages, - project enablement, Agent assignment, admission, and billing under their existing - owners. -- Evidence: approved Spec `ML-PLUGIN-NAV-001`, this task's single implementation - commit, pure projection/action tests, route/page tests, artifact proof, full unit - suite, production build, and 4/4 targeted Electron flows. -- Future impact: architecture readers will use `/plugins` and - `src/pages/Plugins/plugin-workspace-model.ts` as the Renderer aggregation seam and - will not extend the deleted page implementations. -- Semantic conflicts: none known; the concurrent AI Design task owns no plugin - navigation or plugin authority surface. -- Human confirmation: no new product-direction decision is required, but promotion - must still occur only in an exclusively owned Integration Gate. diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-integration-4f7c2a96.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-integration-4f7c2a96.md new file mode 100644 index 0000000..2ee157b --- /dev/null +++ b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-integration-4f7c2a96.md @@ -0,0 +1,92 @@ +# Task: Integrate unified plugin workspace into client main + +## Identity + +- Task ID: 20260903-plugin-navigation-integration-4f7c2a96 +- Mode: Integration +- Branch: main +- Worktree: D:\Datas\OthersProjects\makelore +- Base commit: e9875145b41a2cb1827de10d27a4fc6a352704ea +- Owner: codex-root +- Status: Ready for Integration + +## Scope + +- Fast-forward client `main` from exact base + `e9875145b41a2cb1827de10d27a4fc6a352704ea` through the approved unified Plugin + workspace design and reviewed product head + `d7058e6383f1e9dd72c32570cf83b9f439d91033`. +- Promote only the accepted Integration-Gate memory changes: record the unified + `/plugins` surface in current state and replace the stale three-page entry in the + architecture module map. +- Preserve the three pre-existing untracked task records in the client root exactly; + do not stash, reset, clean, delete, move, or adopt them. +- Run bounded integration verification, complete the task documentation gate, and + release the root integration lock. + +## Intent And Constraints + +- The fixed product range is + `959e2faf03dfacb3c8e2035e44774436c752d4b0...d7058e6383f1e9dd72c32570cf83b9f439d91033`. + R4 task `20260903-plugin-navigation-acceptance-r4-9c2f6a41` independently passed + Standards and Spec with zero findings. +- Preserve the existing Catalog, Account Library, official Package Store, Device + Package, project enablement, Agent assignment, runtime admission, and billing + authorities. This integration changes only the already-reviewed Renderer product + and canonical project memory. +- Keep local Skill/extension installation conversation-only and keep selected-model + native Web Search outside the Plugin projection. +- Related task `20260903-design-message-send-client-8d3f2a71` is Ready for Integration + and explicitly excludes Plugin pages, navigation, Sidebar, and router code; no + semantic or file ownership conflict exists. +- Do not push, open a PR, deploy, publish, package, or install a client. + +## Project Context Loaded + +- Startup memory, integrated current state, decisions, system overview, module map, + data flow, business rules, success criteria, glossary, evidence, commitments, and + stale-item registry were read from the exact client base. +- The approved `ML-PLUGIN-NAV-001` specification and the implementation, three + remediation, and final R4 acceptance records were read in full. +- `main` at `e9875145b41a2cb1827de10d27a4fc6a352704ea` is an exact ancestor of the + reviewed product head, so the product integration is eligible for `--ff-only`. +- Concurrent Task Gate: Passed. Planning Gate: Passed. + +## Outcome + +- Fast-forwarded local client `main` from + `e9875145b41a2cb1827de10d27a4fc6a352704ea` to the exact reviewed product head + `d7058e6383f1e9dd72c32570cf83b9f439d91033`; no merge conflict or product + rewrite occurred. +- The canonical Code Plugin surface is now one sidebar entry and one `/plugins` + workspace. The three old routes remain replace-only redirects and the deleted old + page implementations do not remain as fallbacks. +- Promoted the implementation task's architecture candidate into `module-map.md`, + recorded the integrated product and R4 evidence in `current-state.md`, and corrected + the obsolete My Plugins wording in the durable Device Package rule. +- Preserved all three pre-existing untracked client-root task records exactly. No + push, PR, deployment, publication, package, or user-machine installation occurred. + +## Verification + +- Pre-integration ancestry check proved the root base is an ancestor of the reviewed + product head; `git merge --ff-only` advanced through exactly five commits (approved + design plus implementation and three remediations). +- Final R4 acceptance record reports Standards PASS and Spec PASS with zero findings + over `959e2faf03dfacb3c8e2035e44774436c752d4b0...d7058e6383f1e9dd72c32570cf83b9f439d91033`. +- Post-merge focused verification passed: 8 files / 83 tests. +- Post-merge `corepack pnpm run typecheck` passed. +- Source evidence retained by R4: full unit 1842 passed / 2 skipped plus pressure 1 + passed; lint 0 errors with 5 pre-existing warnings; all Vite targets passed; targeted + Electron Plugin E2E passed 4/4. +- `check_project_docs`, task-aware document drift, staged diff check, exact branch/HEAD, + and final root-status checks are part of the closing gate. + +## Follow-ups + +- A rebuilt and installed client smoke remains a separate release activity; it was not + authorized or required by this source integration. + +## Promotion Candidates + +- None recorded. diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-c5e8a731.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-c5e8a731.md deleted file mode 100644 index 2f8aca8..0000000 --- a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-c5e8a731.md +++ /dev/null @@ -1,148 +0,0 @@ -# Task: Plugin navigation remediation - -## Identity - -- Task ID: 20260903-plugin-navigation-remediation-c5e8a731 -- Mode: Feature -- Branch: codex/20260903-plugin-navigation-remediation-c5e8a731-plugin-navigation-remediation -- Worktree: C:\Users\7brot\.codex\worktrees\plugin-nav-remediation-c5e8a731\makelore -- Base commit: 1b1f206dd8aeb7bf69e61b0cd684f70accce9e26 -- Owner: codex-01a0656d -- Status: Ready for Integration - -## Scope - -- Remediate the five fixed-range Spec failures reported by task - `20260903-plugin-navigation-acceptance-5e8b3c72` on implementation head - `1b1f206dd8aeb7bf69e61b0cd684f70accce9e26`. -- Own only `src/pages/Plugins/**`, their focused unit/page tests, and this task - record. No store, Electron Main, server, runtime, billing authority, sidebar, - module guard, or legacy redirect change is in scope. -- Deliver one remediation commit for a fresh fixed-range Standards + Spec review; - do not merge `main`, push, create a PR, deploy, publish, package, or install. - -## Intent And Constraints - -- Concurrent Task Gate passed for the exact identity/base/worktree above. The - prior implementation and acceptance tasks are Ready for Integration and are - read-only. The AI Design peer explicitly excludes Plugin pages/navigation, so - no file or semantic ownership overlap exists. -- Planning Gate passed after reading the exact project-memory tree, authoritative - Spec `ML-PLUGIN-NAV-001`, ADR-006, prior implementation/acceptance records, and - the current Renderer projection/page/controller plus Marketplace DTO/store - contracts. -- Confirmed public TDD seams are the pure projection/query resolver, the local - command dispatcher, and `PluginsView`/route composition. Tests must fail before - each production correction and observe URL, commands, copy, and detail output - rather than private implementation calls. -- Continuously canonicalize invalid URL state without a one-shot ref or replace - loop, while preserving one visible no-project fallback notice. -- Preserve a source-qualified `retained:` project selection even when Catalog or - Library recognizes the same ID; it may use those sources only for display - metadata and may dispatch only disable for the projection's original project ID. -- Treat `status=unavailable` plus retained version/channel/reason as an existing - device package for cleanup and same-channel update semantics. Show its reason, - mark retained snapshots stale after refresh failure, and distinguish suspended - from retired without inferring state across sources. -- Render operation-level pricing only from Marketplace detail or current project - policy, deduplicated by capability/operation identity and without client-side - price calculation. -- Distinguish signed-out acquisition from authenticated Library failure. Signed-out - users receive an explicit login command; authenticated unknown Library state - remains fail-closed. -- Existing DTOs already expose every required field, so no authority/interface - conflict is present. If later evidence contradicts that conclusion, stop the - affected range rather than add a compatibility layer or broaden ownership. -- Preserve the root workspace and all peer worktrees; in particular do not write - or clean `D:\\Datas\\OthersProjects\\makelore`. - -## Project Context Loaded - -- Product goal: one understandable Plugin workspace that composes, but never - merges, Catalog, Library, device package, project, Agent, admission, and billing - authorities. -- Current state: official bundled Plugins, conversation-only Device Packages, and - selected-model native Web Search already have separate delivery/runtime rules; - the unified Renderer implementation is complete but failed five acceptance roots. -- Relevant decisions: Electron Main retains runtime/credential ownership; Device - Packages are device-global and child workers remain empty; account acquisition, - device delivery, project enablement, Agent assignment, admission, and billing do - not advance one another. -- Relevant evidence: the acceptance record identifies unreachable scope fallback, - lost recognized retained IDs, mishandled unavailable installations/stale status, - omitted detail operations/pricing, and missing signed-out action as exact failures. -- Canonical-memory candidate remains the prior implementation task's deferred - module-map promotion; this feature remediation does not edit integrated memory. -- Known documentation drift: `read-before-planning.md` names old locations for - `memory-index.md` and `current-state.md`; the exact existing files were resolved - with `rg --files` and read successfully, so this is non-blocking. - -## Outcome - -- Replaced one-shot URL normalization with a pure query resolution result and a - Router-location marker that carries the no-project fallback notice across the - canonical replace. Canonical URL and scope controls now remain aligned when the - active project changes or the same mounted route receives a new invalid query, - without a `setSearchParams` loop or effect-owned React state. -- Preserved catalog/Library-recognized `unknownPluginIds` as source-qualified - `retained:` rows in both project and all scopes. They reuse only recognizable - display metadata and expose exactly one mutation: disable against the project - ID recorded by the project projection. -- Treated `MarketplaceInstallation.status=unavailable` with a retained version - and channel as an existing device package for same-channel update and device - removal, while keeping runtime/project actions fail-closed. Cards and details - display the retained version reason, failed retained snapshots show `缓存`, and - suspended/retired states have distinct copy. -- Added a read-only detail operation projection. Marketplace detail operations - render without a project; the current project policy replaces a duplicate - operation as one complete server-owned billing projection, while detail-only - operations remain visible. No pricing is calculated or inferred locally. -- Added an explicit `sign_in` command for signed-out free catalog entries and - dispatch it to the existing `/login` route. Authenticated Library failure still - reports unknown delivery and exposes no acquisition mutation. -- No route, store, Electron Main, server, runtime, billing authority, sidebar, or - E2E file changed. No new authority, fallback, feature flag, compatibility layer, - or visible local-package installation entry was added. -- This task supplies a remediation candidate only. It does not claim the fresh - fixed-range Standards + Spec review has passed. - -## Verification - -- TDD URL RED: focused query/page tests failed because the production composition - erased `scope=project` before the fallback notice and only normalized the first - URL. GREEN: the final query + page run passed 2 files / 13 tests. -- TDD projection/action RED: focused model/controller/page tests produced the six - expected failures for retained unavailable installation semantics, stale and - lifecycle copy, recognized retained IDs, signed-out action, login dispatch, and - visible status copy. GREEN: the focused five-file suite passed 5 files / 34 tests. -- TDD detail RED: the two new page assertions failed because Marketplace detail - operations were absent without a project and a detail-only operation disappeared - when project policy existed. GREEN: `tests/unit/plugins-page.test.tsx` passed all - 9 tests with server pricing output and duplicate identity coverage. -- `corepack pnpm run typecheck`: passed (`tsc --noEmit`). -- `corepack pnpm run lint:check`: passed with zero errors. Five pre-existing - warnings remain in `src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`; - neither file is owned or changed by this task. -- `corepack pnpm test`: passed 225 files / 1830 tests with 2 skipped, followed by - the isolated pressure file passing 1 file / 1 test (aggregate 226 files / 1831 - passed / 2 skipped). -- `corepack pnpm run build:vite`: passed all Renderer, Electron Main, Preload, and - release utility builds. Existing Browserslist-age, mixed dynamic/static import, - and large-chunk warnings remain non-blocking. -- `corepack pnpm run test:e2e -- tests/e2e/plugin-marketplace.spec.ts tests/e2e/project-plugins.spec.ts --reporter=line`: - passed the existing 4/4 Electron flows. The command also rebuilt all production - targets successfully. The E2E set was not expanded because the remediation is - covered at the production composition/pure projection seams and did not require - a route or Host API change. -- `git diff --check`: passed before documentation closeout. - -## Follow-ups - -- Run fresh fixed-range Standards + Spec review over - `959e2faf03dfacb3c8e2035e44774436c752d4b0...remediation HEAD`; do not integrate - or merge `main` before that independent acceptance completes. - -## Promotion Candidates - -- None. This remediation changes no durable authority or architecture decision; - the prior implementation task's module-map candidate remains the correct owner. diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r2-b8e4d317.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r2-b8e4d317.md deleted file mode 100644 index 83ff643..0000000 --- a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r2-b8e4d317.md +++ /dev/null @@ -1,125 +0,0 @@ -# Task: Plugin navigation R2 remediation - -## Identity - -- Task ID: 20260903-plugin-navigation-remediation-r2-b8e4d317 -- Mode: Feature -- Branch: codex/20260903-plugin-navigation-remediation-r2-b8e4d317-plugin-navigation-remediation-r2 -- Worktree: C:\Users\7brot\.codex\worktrees\plugin-nav-remediation-r2-b8e4d317\makelore -- Base commit: c5020ae22c9bef1b5bc8190469998127842c4513 -- Owner: codex-01a0656d -- Status: Ready for Integration - -## Scope - -- Remediate the three R2 Spec findings against product base - `c5020ae22c9bef1b5bc8190469998127842c4513`. -- Preserve the exact canonical `/plugins?...` route through a successful login, - while accepting only safe internal return paths and retaining `/module-select` - as the default. -- Pass device/project refresh-failure provenance into the pure plugin workspace - projection so retained snapshots stay visible and are labelled as cached. -- Surface `CodingPluginProject.policyStatus` (`stale` or `unavailable`) beside - affected project policy/pricing; leave `current` unmarked. -- Add focused projection, page, controller, login/route regressions and run the - required unit, typecheck, lint, Vite, and relevant Electron verification. -- Produce one remediation commit and a clean READY_FOR_INTEGRATION handoff. - -## Intent And Constraints - -- Follow the authoritative unified plugin workspace Spec and the exact three - findings recorded by R2 review commit - `a698c41b39f11b4ebe15fd0f74b5fb8457ae3514`. -- Work test-first through public projection, page, controller, and router seams. -- Keep Catalog, Library, Package Store, Device Packages, project enablement, - Agent Skill assignment, runtime admission, and billing authorities unchanged. -- Do not modify stores, Electron Main, server/runtime/billing contracts, or add - a new cache/authority, compatibility layer, feature flag, or wrapper layer. -- Limit product edits to `src/pages/Plugins/**` and `src/pages/Login/index.tsx`; - a minimal existing route seam is permitted only if required by the login - regression. Corresponding unit/page/route tests and this task record are owned. -- Keep original R1 fixes covered and unchanged in semantics. -- Do not merge main, push, create a PR, deploy, publish, or install to a user - machine. Do not modify or clean any other worktree or the repository root. - -## Project Context Loaded - -- Product goal: finish ML-PLUGIN-NAV-001 R2 remediation without merging existing - backend or runtime authorities into the Renderer projection. -- Current state: base `c5020ae22c9bef1b5bc8190469998127842c4513` - contains the initial implementation and R1 remediation; R2 Standards passed - with zero findings and R2 Spec reported exactly three Medium roots. -- Relevant decisions: `/plugins` is the canonical Code-owned, initialization-safe - route; auth return uses router state; source-qualified identities and - fail-closed partial-source behavior remain intact; Renderer displays but does - not calculate or authorize project policy/billing state. -- Evidence: the authoritative Spec, R2 review record, current App/Login/Plugins - composition, device-package and coding-plugin snapshot-preservation stores, - and existing unit/Electron fixtures were inspected. -- Likely modules: `src/pages/Plugins/plugin-workspace-controller.ts`, - `src/pages/Plugins/plugin-workspace-model.ts`, `src/pages/Plugins/index.tsx`, - `src/pages/Plugins/PluginDetails.tsx`, `src/pages/Login/index.tsx`, and focused - tests under `tests/unit` (plus relevant existing Electron coverage if needed). -- Unknowns/risks: dependency availability in the fresh worktree must be checked; - the stable public route unit seam may be more appropriate than expanding the - Electron fixture for the login-return contract. -- Concurrent task assessment: the authoritative task owner exactly matches this - managed worktree, branch, and base. Same-topic implementation/remediation/review - tasks are READY_FOR_INTEGRATION; remaining planning peers declare no overlapping - ownership of the scoped Plugin/Login files or semantics. -- Concurrent Task Gate: Passed. -- Planning Gate: Passed. - -## Outcome - -- Plugin acquisition sign-in now carries the exact canonical workspace path - (including scope/source/state/search/selected-plugin query) in router state. - Login returns to that same path after successful credential and model sync. -- Login accepts only supported same-app absolute return paths with one leading - slash. Absolute external and protocol-relative targets fall back to - `/module-select`; the existing no-return default is unchanged. -- The pure workspace projection now receives bounded device/project refresh - failure provenance. Preserved local package, project-backed official, and - retained unknown rows stay visible and render as cached; project failure does - not mark catalog-only official rows. -- Project policy status is projected verbatim onto project-associated official - and retained rows. Details explain `stale` and `unavailable` beside billing, - while `current` remains unmarked. No status changes commands, admission, or - client-side pricing. -- No stores, Electron Main, server, runtime, billing authority, dependencies, - legacy routes, or unrelated product files were changed. - -## Verification - -- TDD login/controller RED: 2 expected failures (bare `/login`, fixed - `/module-select`); GREEN: 2 files, 18 tests passed. -- TDD refresh provenance RED: 2 expected failures (`stale=false` in model/page); - GREEN: 2 files, 26 tests passed. -- TDD policy status RED: 5 expected failures (missing projection and copy); - GREEN: 2 files, 32 tests passed. -- Focused plugin/login/route suite: 6 files, 58 tests passed. -- `pnpm run typecheck`: passed. -- `pnpm run lint:check`: passed with 0 errors and 5 pre-existing warnings in - `src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`, outside this diff. -- `pnpm test`: 225 files / 1841 tests passed / 2 skipped, plus the isolated - coding-chat pressure file 1/1 passed. -- `pnpm run build:vite`: passed. Existing Browserslist age, mixed static/dynamic - import, and chunk-size warnings remained non-failing. -- Targeted Electron E2E (`plugin-marketplace.spec.ts` and - `project-plugins.spec.ts`): final combined rerun 4/4 passed. The first combined - run was 3/4: one case timed out waiting for the test fixture to observe - `/api/auth/me` before any plugin assertion. Playwright trace showed successful - Electron launch and reload with no console/renderer crash; the isolated rerun - passed 1/1, then the full targeted rerun passed 4/4. -- Public router Login regression covers exact canonical return plus rejected - external/protocol-relative targets and unchanged default behavior. - -## Follow-ups - -- Source task will run a fresh fixed-range Standards + Spec acceptance review. -- Do not merge to main before that independent acceptance. - -## Promotion Candidates - -- None. The changes implement the already-authoritative ML-PLUGIN-NAV-001 Spec - and do not introduce a new shared architecture or product decision. diff --git a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r3-f3a8c4d1.md b/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r3-f3a8c4d1.md deleted file mode 100644 index 66c08dc..0000000 --- a/.project-docs/30-worklog/tasks/20260903-plugin-navigation-remediation-r3-f3a8c4d1.md +++ /dev/null @@ -1,112 +0,0 @@ -# Task: Plugin navigation R3 detail retry remediation - -## Identity - -- Task ID: 20260903-plugin-navigation-remediation-r3-f3a8c4d1 -- Mode: Feature -- Branch: codex/20260903-plugin-navigation-remediation-r3-f3a8c4d1-plugin-navigation-remediation-r3 -- Worktree: C:\Users\7brot\.codex\worktrees\plugin-nav-remediation-r3-f3a8c4d1\makelore -- Base commit: 0bfabc0df24fdd41c37af498f7a4e49bc00d31db -- Owner: codex-01a0656d -- Status: Ready for Integration - -## Scope - -- Remediate the R3 detail-loading retry loop against exact product base - `0bfabc0df24fdd41c37af498f7a4e49bc00d31db`. -- Make automatic official-detail loading selection-scoped: at most one automatic - request per detail open, a stable local error after rejection, and one new - attempt after explicitly closing and reopening the same detail. -- Add a public Renderer/page regression for reject/settle and close/reopen, while - preserving the existing A-to-B late-detail protection. -- Produce one remediation commit and a clean READY_FOR_INTEGRATION handoff. - -## Intent And Constraints - -- Follow the authoritative ML-PLUGIN-NAV-001 Spec, especially section 5.4 and - ERR-001/ERR-005 in section 7.2, plus the exact R3 acceptance finding supplied - by the source task. -- Work test-first through the public `Plugins` Renderer/page seam. -- Limit product edits to `src/pages/Plugins/index.tsx` and the necessary focused - plugin page test. This task record is the only project-document write owned by - the task. -- Do not modify stores, Electron Main, server, runtime, billing, router, Login, - dependencies, or any other worktree/root checkout. -- Do not add a cache, persistent authority, compatibility layer, feature flag, - broad retry framework, or speculative UI. -- Do not merge main, push, create a PR, deploy, publish, or install the app. - -## Project Context Loaded - -- Product goal: close the R3 P1 finding without changing the unified plugin - workspace's authority boundaries or its existing R1/R2 behavior. -- Current state: exact HEAD and merge-base are - `0bfabc0df24fdd41c37af498f7a4e49bc00d31db`; only this newly created task - record is untracked. Marketplace `loadDetail` sets `loading`, then `error` and - rejects on a supported request failure. The current page effect observes that - error and immediately calls it again. -- Relevant decisions: official detail is loaded on demand; source failures must - remain local and stable; Renderer must not create a second cache or retry - authority; stale A detail must never replace selected B. -- Evidence inspected: the complete ML-PLUGIN-NAV-001 Spec, current project - memory, the R2 task record, `src/pages/Plugins/index.tsx`, the Marketplace - store detail transition, and existing public page/model tests. -- Likely modules: `src/pages/Plugins/index.tsx` and - `tests/unit/plugins-page.test.tsx` only. -- Risks: an already-loading detail must count as the current open's automatic - attempt so a later failure cannot trigger a compensating request; changing or - clearing selection must reset the attempt boundary without weakening store - generation protection. -- Concurrent task assessment: task_context identity, worktree, branch, and base - match exactly. Remaining Planning peers are old Marketplace/ML-07 reviews or - unrelated modules and declare no ownership of this page/test or retry - semantic. Concurrent Task Gate: Passed. Planning Gate: Passed. - -## Outcome - -- `Plugins` now records the official detail selection's automatic attempt before - observing later `loading` or `error` state. A rejected request therefore - settles as one stable local detail failure instead of immediately starting an - unbounded retry loop. -- Clearing selection resets that local attempt boundary. Closing and reopening - the same official detail permits exactly one new automatic request; changing - A to B likewise establishes B's own attempt without changing Marketplace - store generation or late-result protection. -- The public page regression drives the real route composition, reproduces the - supported store `error` transition, proves one call while open, observes the - existing detail error surface, closes the dialog, and proves one additional - call only after reopening. -- No store, Electron Main, server, runtime, billing, router, Login, dependency, - or unrelated product file was changed. - -## Verification - -- TDD RED: `tests/unit/plugins-page.test.tsx` reported the new contract failure - exactly: `loadDetail` expected 1 call after the detail error settled but - received 2 (13 existing tests passed, 1 new test failed). -- TDD GREEN: `tests/unit/plugins-page.test.tsx` passed 14/14. -- Focused plugin suite (`plugins-page`, projection model, query, controller): - 4 files / 39 tests passed, including the existing A-to-B late-detail model - regression and the prior R1/R2 behavior. -- `pnpm run typecheck`: passed. -- `pnpm run lint:check`: passed with 0 errors and 5 pre-existing warnings in - `src/pages/Home/index.tsx` and `src/pages/Makelore/index.tsx`, outside this - diff. -- `pnpm test`: 225 files / 1842 tests passed / 2 skipped; the separately run - coding-chat pressure test passed 1/1. -- `pnpm run build:vite`: Renderer, Electron Main, Preload, and utility worker - builds passed. Existing Browserslist age, mixed static/dynamic import, and - large-chunk warnings remained non-failing. -- Targeted Electron E2E (`plugin-marketplace.spec.ts` and - `project-plugins.spec.ts`): 4/4 passed after the script's production rebuild. -- `git diff --check`: passed; the product diff is limited to - `src/pages/Plugins/index.tsx` and `tests/unit/plugins-page.test.tsx`. - -## Follow-ups - -- Source task will run a fresh fixed-range R4 Standards + Spec review. Do not - merge to main before that independent acceptance. - -## Promotion Candidates - -- None recorded. diff --git a/.project-docs/40-domain/business-rules.md b/.project-docs/40-domain/business-rules.md index 764a531..272a945 100644 --- a/.project-docs/40-domain/business-rules.md +++ b/.project-docs/40-domain/business-rules.md @@ -56,9 +56,10 @@ never run. Pi extensions execute with desktop-user authority after that fact is shown in confirmation. New and idle parent workers refresh automatically, active parents switch only after settlement, and child workers never inherit Device Package resources. -- Device Packages appear separately from Official Plugins in My Plugins and never enter - Account Library, Marketplace Package Store, Release, Channel, Admission, project - enablement, Agent assignment, or server billing state. +- Device Packages appear as a separate `本机` source beside Official Plugins in the + unified `/plugins` workspace and never enter Account Library, Marketplace Package + Store, Release, Channel, Admission, project enablement, Agent assignment, or server + billing state. - 面向用户的 AI 编程新建流程必须在 `mini_game`、`mini_program`、`custom` 中选择;`ProjectType` 是产品类型,创建后不能通过 UI 或 Host API 修改,未传类型的兼容 API 调用按 `custom` 处理。 - 新建小游戏和小程序会生成平台固定版本的受控 Vite 发布模板,并可使用项目配置中的单一“提交审核”入口;`custom` 和缺少类型字段的旧项目不提供一键发布。 - `ProjectType` 不等于 `BuildPreset`:第一期两个可发布产品类型都映射到内部受控 Vite preset;本地 `projectType` 不是授权边界,Main-owned 安全打包、Host API 和服务端包体校验仍必须执行。 @@ -138,4 +139,4 @@ ## Last Reviewed -2026-08-31 +2026-09-03