merge: integrate remote and local main histories

# Conflicts:
#	.project-docs/20-architecture/module-map.md
#	.project-docs/30-worklog/current-state.md
#	.project-docs/50-evidence/evidence-index.md
#	src/pages/MyPlugins/index.tsx
#	tests/unit/pi-agent-server-process-real.test.ts
#	tests/unit/pi-managed-worker-opener.test.ts
#	tests/unit/plugin-marketplace-pages.test.tsx
This commit is contained in:
inman
2026-09-03 10:44:04 +08:00
122 changed files with 10866 additions and 436 deletions

View File

@@ -6,7 +6,10 @@
|---|---|---|---|
| Marketplace catalog and Account Library | Signed-in Renderer intent | bounded Host API → Main Marketplace client/cache → Works Square catalog, Library, resolve, Admission, and download APIs | Main binds requests to the current Account and response generation. Free acquisition changes only Account Library; it does not install, enable a project, assign an Agent Skill, or authorize runtime execution. |
| Marketplace device installation | Account Library entry and explicit channel | Main resolve/Admission/download → descriptor/signature/archive/client compatibility verification → immutable Package Store index switch | Stable and explicit Beta remain distinct even when they resolve to the same immutable Release. Failed install/update retains the previous current release; explicit uninstall waits only for protecting worker/account references and completes after the final worker exits. |
| Effective Plugin worker snapshot | Installed trusted package + project selection + Agent assignments + current server policy | effective resolver → Registry/resource loader/Extension Host/tool catalog → parent Pi worker | One frozen snapshot supplies Skills, tools, package roots, and runtime authorization. Disable, account/project switch, logout, Renderer crash, Main shutdown, or worker generation change invalidates future actions without mutating persisted unknown assignments; child workers receive no Plugin projection. |
| Official bundled hosted Plugin acquisition | Account Library entry for Game Resource | server stable bundled Release/Admission + MakeLore resource package | Free acquisition changes Library only. No device download, update, Beta, signature, or device-uninstall action exists for this exact code-owned identity. Historical Hosted Web Search entries are ignored by current clients. |
| Selected-model Web Search | Parent Pi turn with an explicitly supported selected model | `makelore_web_search` core tool → frozen model/provider/credential request with provider-native forced search → ordinary model response/usage | No Marketplace Release, Account Library, Admission, Hosted Web Search client, Plugin Charge, or `agent_browser` fallback participates. Unsupported selected models expose no tool; child workers receive none. |
| Conversation-driven Device Package install | Agent tool inspects npm/Git/absolute local Plugin/loose Skill source | Main preview → distinct later user confirmation → immutable device-package generation → new/idle parent worker resources | Renderer has no install picker. Lifecycle scripts never run. Confirmation explicitly states that Pi extensions execute with desktop-user authority. Active workers retain their frozen generation until the turn settles; child workers remain empty. |
| Effective Plugin worker snapshot | Installed trusted package or acquired official bundled definition + project selection + Agent assignments + current server policy | effective resolver → Registry/resource loader/Extension Host/tool catalog → parent Pi worker | One frozen snapshot supplies Skills, tools, package roots, and runtime authorization. Disable, account/project switch, logout, Renderer crash, Main shutdown, or worker generation change invalidates future actions without mutating persisted unknown assignments; child workers receive no Plugin projection. |
| Hosted Game Resource operation | Eligible parent `makelore.game-resource` tool call plus explicit confirmation | frozen Plugin adapter → capability Registry → Main `GameResourceClient` → fixed Works Square game-resource route → provider-neutral receipt/result | Server policy owns pricing, payer, Admission and receipt state. Stable logical operation identity survives response loss/Main restart; `submission_unknown` is not replayed as a fresh request. Result saving uses a bounded project-relative path and the existing project write lease. |
| 桌面认证生命周期 | Renderer 登录、刷新与注销请求 | Host API → Main Works Session → Works Square `/api/auth/{login,mobile-login,refresh,logout}` → one-feel auth | Main 加密持有并先持久化轮换 token;客户端不携带 OAuth client secret;连续 7 天未使用才清除会话,终止性 `400`/`401` fail closed |
| 用户模块入口策略 | 会话恢复 / 登录 / 刷新 | Electron Main → Works `/api/auth/me` → 四布尔安全投影 → Renderer auth store → 卡片/路由/provider gate | 缺失对象或字段默认 `true`;`design` 映射 `painting`;终止性 `401` 清理 Main/Renderer 会话;全局 `/settings` 不受 Code gate |

View File

@@ -4,11 +4,13 @@
| Path | Responsibility | Owner Notes |
|---|---|---|
| `electron/coding-plugins/manifest.ts`, `release-descriptor.ts`, `signature-verifier.ts`, and `trusted-keys.ts` | Closed Plugin package/descriptor parsing, compatibility checks, canonical archive validation, and Ed25519 trust | Schema 1 bundled compatibility and schema 2 `skill_only`/declarative `platform_hosted` are parsed fail closed. The production trust store accepts no Marketplace package until the official public key is built in. |
| `electron/coding-plugins/manifest.ts`, `release-descriptor.ts`, `signature-verifier.ts`, and `trusted-keys.ts` | Closed Plugin package/descriptor parsing, fixed code-owned resource roots, compatibility checks, canonical archive validation, and Ed25519 trust | Data Service plus exact Game Resource roots are code-owned. Other schema-2 `skill_only`/`platform_hosted` packages remain signed Marketplace artifacts and fail closed without the official public key. Hosted Web Search is not a current Plugin root. |
| `electron/coding-plugins/account-plugin-cache.ts`, `marketplace-client.ts`, and `package-store.ts` | Main-owned Account Library cache, authenticated server client, and atomic immutable device installation store | Account acquisition and device installation are separate. Package bytes switch atomically only after descriptor, signature, archive, client-range, and provenance checks; failed updates preserve the prior current release. |
| `electron/coding-plugins/effective-resolver.ts`, `registry.ts`, `project-service.ts`, and `electron/coding-runtime/pi/**` | One effective installed-plugin projection and frozen parent logical-thread runtime snapshot | Project enablement and Agent Skill assignment are preserved independently. Only trusted, compatible, installed, policy-admitted resources enter a new parent logical thread; child workers remain empty and active threads retain frozen bytes until disposal. |
| `electron/coding-plugins/effective-resolver.ts`, `registry.ts`, `project-service.ts`, and `electron/coding-runtime/pi/**` | Effective official Plugin projection, selected-model tools, Device Package resources, and frozen parent logical-thread runtime snapshot | Project enablement and Agent Skill assignment are preserved independently. Trusted Marketplace artifacts, exact acquired official bundled definitions, and immutable local Device Package generations enter through distinct authorities. Child workers remain empty; active threads retain frozen resources until settlement/disposal. |
| `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. 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/components/plugins/PluginServices.tsx`, `src/lib/plugin-services.ts`, `src/pages/ProjectConfiguration/`, `src/pages/PluginMarketplace/`, `src/pages/MyPlugins/`, and `src/pages/ProjectPlugins/` | Bounded Main routes and one Project Configuration Plugin Services surface for catalog, Library, device, and project actions | Renderer receives no Account token, filesystem path, Admission, package bytes, or signed download URL. Discover/mine/project are URL-backed sheet tabs; former standalone routes only redirect to those tabs. 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.ts`, `src/components/plugins/PluginServices.tsx`, `src/lib/plugin-services.ts`, `src/pages/ProjectConfiguration/`, `src/pages/PluginMarketplace/`, `src/pages/MyPlugins/`, `src/pages/ProjectPlugins/`, and `src/stores/device-packages.ts` | Bounded Main routes and one Project Configuration Plugin Services surface 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. Discover/mine/project are URL-backed sheet tabs; former standalone routes only redirect to those tabs. My Plugins separates official Plugins from locally installed Device Packages. Catalog/Library/device/project generations prevent stale A/B or cross-action results from replacing current state. |
| `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 内完成 |

View File

@@ -21,8 +21,10 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
| Makelore Code Workspace | project/Agent/Conversation schema v2、产品中立 Snapshot/Patch、Composer 与时间线 | Conversation 本地创建且不等待 worker;旧 OpenCode 会话备份后不再继续,Renderer 不导入 Pi RPC/event 类型 |
| Coding Host API & Composition | 唯一 `/api/coding/*` composition、202 acceptance/dedupe、SSE、附件/文件/交互/诊断 | Electron Main 拥有 project/Conversation 服务、选中目标、认证和错误脱敏;SSE 公开面只有 Snapshot 与 `patch-batch` |
| Pi Conversation Runtime | 一个长驻 Pi `0.84.2` Agent Server 承载每条 active/warm Conversation 的隔离逻辑 Runtime/Session/JSONL channel | 严格 LF JSONL RPC、generation recovery、Snapshot hydration;top-level 逻辑 turn 并发 4、warm idle LRU 8;Server 退出统一使旧 channel 失效并按需单实例重启 |
| Pi Provider & Managed Resources | Provider catalog、thread-local secret projection、model/resource revision、Prompt/Skill/extension materialization | 父凭据只进入选中逻辑线程的内存 credential store,child 凭据只进入该短命进程;不扫描项目或用户的 `.pi/.agents/.codex`,不把 secret 放进 argv、catalog 或 Renderer |
| Pi Provider & Managed Resources | Provider catalog、thread-local secret projection、model/resource revision、Prompt/Skill/extension materialization、selected-model tools | 父凭据只进入选中逻辑线程的内存 credential store,child 凭据只进入该短命进程;Works `model_capabilities` 由 Main 严格归一化并作为安全 Provider metadata 持久化。Web Search 仅在精确 capability 存在时随冻结的 selected model/provider/credential 进入 parent tool catalog,并走普通模型计费;不回退 `agent_browser` 或独立 Hosted Provider。服务端 reasoning levels 优先于本地 profile,缺字段则清理 override 并回退;不扫描项目或用户的 `.pi/.agents/.codex`,不把 secret 或原始响应放进 argv、catalog 或 Renderer |
| Pi Extension, Subagents & Lifecycle | 唯一显式 Makelore extension、UI interaction、ephemeral child、write lease 与 background run lease | child 并发 4、单次最多 8、禁止递归;active/uncertain run 不因页面隐藏或 confirmation timeout 被停止,replacement/stop 必须可解释并清理所有 ownership |
| Official Hosted Plugins | Acquired code-owned bundled Game Resource package → effective parent snapshot → code-owned Main adapter → fixed Works Square hosted route | 无设备下载、更新、Beta 或签名步骤;Renderer/Package/Pi 不持有 Provider key、model 或 URL。每次计费操作要求显式确认,child 不继承 hosted tool。历史 Hosted Web Search 不再进入当前客户端。 |
| Device Packages | Conversation install tools → Main-owned inspect/preview/confirm/commit → immutable local generation → parent Skill/Pi-extension resources | 支持 npm、Git、绝对本地 Plugin 目录与 loose `SKILL.md`;没有可见安装入口、Account Library、Release、Admission 或 Marketplace Package Store。可执行 extension 拥有桌面用户权限且生命周期脚本禁用。新/idle parent 自动刷新,active parent 在 turn settled 后刷新,child 始终为空。 |
| AI Design Workspace & Living Form | 一个 Workspace 的当前 Direction、Current Specification、持久 Agent Session、conversation timeline、Tasks 与 Assets | Living Form 是服务端 Current Specification 的投影;Renderer 只持有草稿和已接受投影 |
| AI Design Input & Reconciliation | Chat、字段/集合编辑、decision、proposal、lock、Asset binding 与 restore | 全部进入同一 `design.input.apply` reducer;稳定 command/operation ID 支持 unknown-result 重放,revision conflict 刷新权威状态 |
| AI Design Gateway Routing | Main-owned Works Square V2 adapter 与 Direction event stream | Main 持有 Works Token、stream ticket、WebSocket、重试分类和错误脱敏;事件顺序与 Task progress 不构成 Specification 真值 |
@@ -56,6 +58,11 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
- Renderer 只消费共享的产品中立 project/Conversation/Snapshot/Patch DTO,并经 `src/lib/host-api.ts` 或 `src/lib/api-client.ts` 访问 Main。Pi RPC、event、Provider credential 和本地 runtime 路径保持 Main-private。
- accepted/uncertain Coding mutation 不得自动重放;RPC confirmation timeout 后仍保留 target run permit、process ownership 和 background lease,直到迟到 success/failure/exit/abort 权威收敛。其他 Conversation 必须继续可用。
- selected Provider credential 只投影到目标父逻辑线程的内存 credential store 或目标 child 进程;跨账号模型变化必须重建目标逻辑线程。确定性 Works user-context 缺失是 Provider-auth failure:失效缓存 credential、fail fast、固定脱敏提示,不得归类为 Pi crash。
- Works 下发的 per-model reasoning capability 是可选 Main-owned metadata,不是
Renderer 或 one-api 的权威。存在时只接受受支持的安全形状并覆盖目标模型的
本地 effort map;缺失时移除旧 override 并使用已验证本地 profile。`off` 在 Pi
wire 上表示 `thinking.type=disabled` 且不发送 `reasoning_effort`,启用档位保持
provider 原生值,当前 DeepSeek 产品投影为 `off`/`low`/`high`/`max`。
- Guided Hotspot Binding is implemented behind a Main-owned capability that is true by default; exact `NIANCODE_AI_HARDWARE_GUIDED_HOTSPOT_BINDING=0` disables it, while capability-read failure falls back to direct six-digit Binding. The guided state is process-local, opener failures expose only the same fixed address for manual copy, and Binding conflicts refresh the safe account overview.
- Robot hotspot scanning and connection are local Main operations that return before Works credentials/upstream access. Renderer may submit only an opaque candidate ID from the latest bounded scan; Main alone filters open printable `Xiaozhi-*` SSIDs, performs platform association, and verifies the exact current SSID.
- Hotspot discovery and connection do not authenticate a Robot. BSSID, interface/profile details, native diagnostics, location data, and Wi-Fi credentials never cross the Main boundary; permission or platform failure keeps the system-settings/manual path available.
@@ -87,8 +94,8 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
## Related Decisions
- 当前长期边界记录于 README、ADR-002 至 ADR-007(ADR-001 已由 ADR-007 supersede)及各 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Living Form/Specification 状态归属、Pi 单 runtime/worker/lease 边界、Learning/Marketplace 分发边界、Robot 配网边界或重新引入客户端部署协调器,应新增 ADR。
- 当前长期边界记录于 README、ADR-002 至 ADR-007(ADR-001 已由 ADR-007 supersede)及各 Integration Gate;后续如改变唯一入口、凭据所有权、构建执行边界、Living Form/Specification 状态归属、Pi 单 runtime/worker/lease 边界、Learning/Marketplace/Web Search 分发边界、Robot 配网边界或重新引入客户端部署协调器,应新增 ADR。
## Last Updated
2026-08-31
2026-09-01