本地文件
Terminality 把 Rust 原生文件管理器作为一等窗格类型。WebView 永远不会直接接触文件系统。
安全设计
文件操作是相对目录描述符且受代际约束的:
- 每条路径必须是绝对、规范化,并位于已注册的根能力内。
- 目录组件用 no-follow 语义打开,替换后的符号链接不能改变遍历目标。
- 修改操作只接受当前列表的
(generation, index)引用,不接受调用者路径。 - 批处理不能为空、不能重复,并限制在 100 项以内。
身份校验
每个缓存条目都带有原生身份:Unix 使用 (device, inode),Windows 使用 (volume, file index)。核心通过保留的父目录能力验证三次:确认前、确认后、每次副作用前。
同名同类型的替换对象会失败为 stale,而不会继承旧授权。
功能
- 面包屑、返回父级、返回主目录与平台根目录。
- 对大型目录分页渲染,并设置硬性条目上限。
- 代际约束的多选。
- 创建与重命名只接受一个文件名组件,原子 no-replace,不能静默覆盖并发目标。
- 删除只进入系统废纸篓 / 回收站;没有永久删除回退。
- 在系统文件管理器中原生显示。
删除使用有界、过期、单次的准备令牌冻结选择,并由平台适配器在第一次副作用前显示本地化确认。
React 能看到什么
React 只接收展示路径、有界元数据快照,以及 navigateTo、create、rename、trash、reveal 等类型化命令。非 UTF-8 名称会跳过并计数,不会被有损转换成可操作路径。
React FilePane
→ FileServiceViewModel
→ FileService (Rust)
→ openat2 / CreateFile2替换窗格会轮换 PaneContentId,使子 ViewModel 与目录快照失效;过期异步结果不能发布到新的窗格代际。