【免费下载链接】puppyone-desktop项目地址https://gitcode.com/gh_mirrors/pu/puppyone-desktop点击查看免费下载puppyone 桌面版puppyone-desktop是一款本地优先local-first的 AI 桌面编辑器支持在一个应用实例中打开多个独立工作窗口。本文将带你完整看懂 puppyone 的多窗口与多根工作区窗口架构设计为什么一个应用能安全地并行打开多个项目窗口、每个窗口如何隔离自己的状态以及底层内核如何用同一套模型支撑从 0 到 N 个文件夹的工作区组合。 为什么需要多窗口与多根工作区真实的开发场景往往是同时和两个项目打交道一个窗口里让 Agent 跑测试另一个窗口自己读代码或者前后端两个仓库需要对照着改。puppyone 桌面版的答案是一个应用实例 多个原生窗口每个窗口拥有完全独立的工作区状态。当前产品层刻意保留了两条简单直观的约束一个仓库repo同一时间最多只能在一个 puppyone 窗口中打开一个 puppyone 窗口同一时间最多持有一个活动仓库。但要注意这是产品发布边界不是内核的能力上限。在内核层面一个窗口的工作区早已是0 个、1 个或 N 个文件夹的有序组合——多根工作区的地基已经就位只是还没有向 UI 开放。 多窗口架构一个应用实例多个原生窗口主进程统一维护跨窗口状态Electron 主进程是全局状态的唯一持有者维护着三个关键索引windowsByIdwebContents.id到每个BrowserWindow的映射windowStateById每个窗口的WindowWorkspaceState包含有序的文件夹组合与最后聚焦时间workspaceWindowByPath规范化工作区路径到拥有它的窗口的映射是防止重复窗口的权威索引。所有路径在比较前都会先做realpath规范化因此通过符号链接打开同一个底层文件夹不会意外创建出第二个窗口。窗口状态的实现见 window-workspace-state.mjs。重复打开仓库时自动聚焦已有窗口所有打开工作区的路径都必须经过主进程命令如window:get-initial-workspace、workspace:open-current、workspace:open-new-window每条命令只有三种结果分配给请求窗口、创建新窗口、或聚焦已拥有的窗口返回focused-existing。渲染进程从不自己猜测别的窗口是否已经打开了这个工作区——收到focused-existing时它只把动作视为由另一个窗口完成的完成态不改变当前窗口。挂载事务对重复路径的处理非常直接路径若已被别的窗口拥有就直接revealWindow聚焦过去。完整事务见 window-workspace-composition.mjs。渲染进程状态完全按窗口隔离每个BrowserWindow都挂载独立的 React 树因此编辑器选中、预览缓存、Git 状态、Cloud 路由状态、侧边栏状态、终端 UI 状态永远不会在原生窗口之间共享。关闭一个仓库窗口不会误伤其他窗口的终端、watcher 与状态。原生窗口的几何同样有固定契约最小宽度 640、最小高度 520见 window-layout-contract.mjs。 多根工作区内核一套模型支撑 0 到 N 个文件夹三层身份模型内核刻意拆出三个彼此独立的身份避免工作区 文件夹 文件的混用WorkbenchWorkspace —— 一个原生窗口内 0/1/N 个文件夹的有序组合 WorkspaceFolder —— 一个已挂载的本地或未来云端根目录 ResourceUri —— 一个全局无歧义的文件或目录身份单根行为就是folders.length 1而不是单独一条 reducer、一套 IPC、一张缓存图或一个兼容模式。当前 UI 只是把folders[0]投影成旧字段。类型定义见 workbenchWorkspace.ts。资源 URI同名文件不再撞车多根场景下两个文件夹里很可能都有src/App.tsx。内核给每个文件一个稳定的逻辑身份puppyone-local://workspace/folder-id/src/App.tsx编辑器把身份id/resourceUri与展示label、工作区相对路径彻底分开两个文件夹可以同时打开同名相对路径而不会共享同一个编辑器 ID旧的只存路径编辑器记录会在解析时自动迁移。URI 的构造与路径穿越防护见 resourceUri.ts。挂载与移除事务化的文件夹变更挂载attach是一条严格流水线候选选择 → 主进程规范化与符号链接策略 → 稳定 Folder 身份 → 跨窗口所有权检查 → provider 准备 → 发布不可变快照 → 发出onDidChange(added)。移除detach则先发onWillChange(removed)让脏的工作副本、Agent 会话、终端资源登记持久化屏障屏障全部完成后才发布新 revision并只吊销该文件夹的权限、只销毁该文件夹的服务。发布前任何一步失败旧快照仍然是权威状态——不存在半成品。 权限边界渲染进程不能自封工作区多根带来的最大风险是权限扩散puppyone 的防线是fail closed渲染进程只能复述主进程分配给它的根目录不能铸造新的本地根权限双方路径都会 realpath 后比对见 workspace-authorization.mjs挂载了多个根却没指定目标根时请求直接失败An explicit Workspace Folder root is required没有隐式默认值最近使用历史、Cloud 项目、资源管理器里可见的行统统只是元数据永远不能变成授权凭证。 窗口关闭时的资源清理策略窗口关闭的清理严格按webContents.id作用域进行关闭该窗口的终端会话、退订该窗口的 workspace watcherwatcher 只在无剩余订阅者时才关闭、释放该窗口的所有权。更细一层清理还是按文件夹作用域的终端会话与 Agent 会话各自记录自己的规范化 Workspace Root移除 Folder A 只回收 A 的资源绝不触碰 Folder B——这正是移除一个根永不重置兄弟根资源这条不变量的落地。 架构文档与源码路径速查主题路径多窗口工作区设计文档desktop-multi-window-workspaces.md多根工作区内核文档desktop-multi-root-workspace-kernel.md窗口文件夹组合状态window-workspace-state.mjs挂载/移除事务服务window-workspace-composition.mjs窗口根目录授权workspace-authorization.mjs工作区快照与变更上下文workbenchWorkspace.ts资源 URI 身份体系resourceUri.ts小结puppyone 桌面版的窗口架构可以浓缩成三句话主进程独占全局窗口状态渲染进程只负责本窗口展示跨窗口防重复靠主进程的唯一索引裁决多根工作区不是第二套内核而是同一套 0/1/N 文件夹模型的天然扩展——单根只是folders.length 1一切文件夹变更都是事务化的快照发布权限边界清晰、清理按作用域隔离。理解了这套设计你就理解了 puppyone 为什么既能一窗一仓地简单稳定地运行又已经为多根工作区预留好了完整的地基。赞分享【免费下载链接】puppyone-desktop项目地址https://gitcode.com/gh_mirrors/pu/puppyone-desktop点击查看免费下载相关推荐Gopeed 桌面多窗口 Capability RPC 架构解析主窗口与子窗口的通信契约设计与实现Gopeed 桌面多窗口 Capability RPC 架构解析主窗口与子窗口的通信契约设计与实现 导读 Gopeed 桌面端基于 Flutter 实现了多窗网络CLI后端CANN/ge测试标准规范Naming Conventions 1. File Naming Split files and name them at the feature granu人工智能深度学习模型编译模型优化编译器Ascend终极dnSpy多窗口管理指南主窗口与工具窗口布局设计完全解析终极dnSpy多窗口管理指南主窗口与工具窗口布局设计完全解析 dnSpy作为一款功能强大的.NET程序集调试器和编辑器其多窗口管理系统为用户提供了极大的灵活开发工具调试器逆向工程桌面应用创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考