# Agent Note: 原生工作区目录选择器

Status: implemented

[English](2026-07-27-native-workspace-directory-picker.md) | 中文

## 问题

桌面端 GUI 在添加现有工作区时要求用户输入绝对路径。相比使用操作系统原生选择器选取目录，这种操作速度更慢，也更容易出错。GUI 由本地 Web 载体提供，因此打开原生对话框也会形成一条特权边界，普通远程请求不得越过这条边界。

## 决策

新增一个用于选择单个文件夹的 `host.pickDirectory` RPC，并通过 `WorkspacesService` 暴露该 RPC。工作区菜单提供两个平铺操作：**打开本地文件夹…** 和 **创建新工作区**。选定文件夹后，系统复用现有的 `workspace.create({ path })` 流程，选中返回的工作区，并启动一个空白会话。

工作区管理器必须在选择回调运行前插入或更新返回的工作区。因此，新纳入的目录会立即显示其 basename。再次打开已注册的路径时，则保留该工作区现有的标题。

## 交互契约

- 在 macOS、Windows 和 Linux 上，选择器一次只允许选择一个目录。
- 取消系统对话框不会显示提示，并返回 `null`。
- 路径重复时，选中现有工作区。
- 如果路径不同，但其派生标题与另一个工作区冲突，则显示明确指出该冲突的错误提示，其中包含 **重新选择** 和 **取消** 操作。
- 选择器的其他故障会显示简洁且可重试的错误提示。
- 现有的按名称创建流程保持不变。

## 宿主边界

只有来自回环套接字、且携带同源浏览器元数据的请求才能调用原生对话框 RPC。该 RPC 不使用默认的 30 秒请求超时，因为系统对话框可能无限期保持打开；调用方中止或连接中止仍会传递至平台进程。

平台适配器不经 shell，直接调用原生工具：

- macOS：`osascript` 和系统文件夹选择器。
- Windows：采用 STA 模式的 PowerShell 和 `FolderBrowserDialog`。
- Linux：使用 `zenity`；Zenity 不可用时回退到 `kdialog`。

## 考虑过的替代方案

- 自定义目录浏览器会重复实现操作系统的行为和权限逻辑，而且应属于 Web 实现，而非本次仅面向桌面端的变更。
- 继续使用手动路径字段会保留当前容易出错的交互方式。
- 为一个本地原生对话框添加身份认证基础设施，会使变更范围超出其威胁模型；对当前载体而言，回环与同源检查已经足够。

## 后果

当前 GUI 可以在 macOS、Windows 和 Linux 上通过原生选择器打开一个本地文件夹。取消操作不会改变任何状态，故障仍可重试；重复路径的处理具有幂等性，标题冲突则要求用户明确重新选择。选中的工作区及其显示名称会在启动新的空白会话前完成刷新。现有的按名称创建工作区功能仍可使用。

新增的宿主、运行时、组件和 GUI 测试覆盖原生边界、请求信任校验、取消与故障处理、已有路径复用、标题冲突和可见名称即时更新。该特权 RPC 仍仅面向本地桌面载体；远程 Web 目录浏览器不属于本次决策范围。

## 风险

- Linux 桌面环境可能不提供任何一种受支持的选择器。GUI 会报告这项限制，而不会回退到要求用户输入路径。
- 在受支持的本地载体之外，浏览器元数据可能有所不同。对于无法证明其满足所需本地同源上下文的请求，该端点会按设计拒绝。
