What problem does this solve?
环境:Windows 11 x64 / Percho 0.6.0。
现象:把内置桌宠 ds-whale-maid-q 拖到别的角落,重启 Percho 之后又回到右下角。
查下来问题不在桌宠,而是宿主没有给 UI 插件任何持久化通道:
-
桌宠的位置只是组件 state ——
packages/desktop/resources/ui-plugins/builtin/ds-whale-maid-q/src/index.tsx:
const [offset, setOffset] = useState({ x: 0, y: 0 }); // :119
style={{ transform: `translate(${offset.x}px, ${offset.y}px)` }} // :228
setOffset(clampOffset(d.baseX + dx, d.baseY + dy)); // :275 拖拽结束
全文件没有任何落盘路径。
-
packages/desktop/resources/ui-plugins/SPEC.md 的插件纪律(91–93 行)把可能的通道都堵死了:
❌ 禁止 Node API(process/fs/path/require 等都不存在——代码跑在浏览器沙箱渲染进程);
❌ 禁止 fetch/网络请求、localStorage(宿主未授权,且 CSP 会拦);
❌ 禁止直接访问 window.pi 做任何 IPC 调用(信任模型边界,插件只准用 window.PerchoUI 暴露的能力)。
-
packages/desktop/resources/ui-plugins/percho-ui.d.ts 里 @percho/plugin-api 的导出只有
version / components / helpers / hooks / stores(外加类型和几个 store hook)——
没有任何 storage / kv / persist 之类的写入能力(grep storage|persist 零命中)。
也就是说这是结构性的:任何 UI 插件都做不到「记住用户状态」。受影响的不是只有这一个桌宠:
builtin/ds-whale-maid、以及随包提供的示例 examples/overlay-pet(同属 app.overlay 区域)
都一样;再往上,第三方插件连「用户把它折叠了」这种状态也存不下来。
Proposed solution
两条路,任选:
方案 A(通用基建):给 @percho/plugin-api 加一个命名空间化的 KV 存储,例如
storage.get(key) / storage.set(key, value),由宿主按插件名隔离落盘到 userData
(值限 JSON 可序列化 + 体积上限)。
方案 B(宿主托管 overlay 位置):app.overlay 区域本来就是宿主按 anchor 九宫格给一个
fixed inset-0 z-20 容器的(见 SPEC 槽位表),位置语义在宿主手里。可以让宿主统一记住每个
overlay 贡献的 anchor + offset,插件零改动,上面提到的几个 overlay 一起修好。
如果只想先修内置桌宠,B 的成本大概比 A 更低;但 A 是插件生态更缺的那块基建。
Alternatives considered
- 每次打开再手动拖一次(现状);
- 让插件自己想办法存 —— 做不到:
localStorage 被禁、无 Node API、无 window.pi IPC 权限,
window.PerchoUI 也没暴露任何写入能力,没有任何可用通道。
What problem does this solve?
环境:Windows 11 x64 / Percho 0.6.0。
现象:把内置桌宠
ds-whale-maid-q拖到别的角落,重启 Percho 之后又回到右下角。查下来问题不在桌宠,而是宿主没有给 UI 插件任何持久化通道:
桌宠的位置只是组件 state ——
packages/desktop/resources/ui-plugins/builtin/ds-whale-maid-q/src/index.tsx:全文件没有任何落盘路径。
packages/desktop/resources/ui-plugins/SPEC.md的插件纪律(91–93 行)把可能的通道都堵死了:packages/desktop/resources/ui-plugins/percho-ui.d.ts里@percho/plugin-api的导出只有version/components/helpers/hooks/stores(外加类型和几个 store hook)——没有任何
storage/kv/persist之类的写入能力(grepstorage|persist零命中)。也就是说这是结构性的:任何 UI 插件都做不到「记住用户状态」。受影响的不是只有这一个桌宠:
builtin/ds-whale-maid、以及随包提供的示例examples/overlay-pet(同属app.overlay区域)都一样;再往上,第三方插件连「用户把它折叠了」这种状态也存不下来。
Proposed solution
两条路,任选:
方案 A(通用基建):给
@percho/plugin-api加一个命名空间化的 KV 存储,例如storage.get(key)/storage.set(key, value),由宿主按插件名隔离落盘到userData(值限 JSON 可序列化 + 体积上限)。
方案 B(宿主托管 overlay 位置):
app.overlay区域本来就是宿主按 anchor 九宫格给一个fixed inset-0 z-20容器的(见 SPEC 槽位表),位置语义在宿主手里。可以让宿主统一记住每个overlay 贡献的
anchor + offset,插件零改动,上面提到的几个 overlay 一起修好。如果只想先修内置桌宠,B 的成本大概比 A 更低;但 A 是插件生态更缺的那块基建。
Alternatives considered
localStorage被禁、无 Node API、无window.piIPC 权限,window.PerchoUI也没暴露任何写入能力,没有任何可用通道。