文件树与基础文件管理

侧边栏与中央 Files 页面使用官方 @pierre/trees:默认 30px 行高、密度 1、选择与焦点状态、键盘导航和虚拟滚动。目录箭头替换为原有 Lucide 开合文件夹,其余树形显示使用框架实现。

当前状态:官方组件已接入,默认 App 已更新;394 项 Web 测试、完整构建和独立复核通过。

文件列

侧边栏与中心 Files 共用带固定表头的文件树,列顺序为 Name、Size、Date Modified、Kind。宽度小于 720 像素时,名称和大小占满初始可见区域;横向滚动显示后两列。宽视图完整显示四列。名称使用剩余宽度并保持中间缩略;大小保留 100 像素,修改时间 200 像素,类型 140 像素。表头和文件行共享列边界及横向滚动位置,纵向滚动时表头保持可见。

已安装的 Pierre Trees 1.0.0-beta.6 公共 renderRowDecoration 支持文本片段,但没有原生可排序列。保留其虚拟行、层级、固定祖先行及键盘交互,通过三个固定文本片段、unsafeCSS 和外置表头实现列显示。同步原生横向滚动元素与表头;ResizeObserver 测量包含滚动条影响的实际视口,卸载时移除观察器和监听器。不引入新的表格框架或逐文件元数据请求。

目录与搜索响应已有秒级 mtime,传给共享树并按当前语言和本地时区显示。类型显示文件夹、扩展名加文件,或无扩展名文件。缺少时间及搜索结果的合成祖先目录留空。目录列标题切换已有按项目保存的服务端排序,保留文件夹优先、隐藏和忽略项设置。搜索保持相关性排序,列标题不提供排序操作。元数据权限、取消、刷新和大小缓存仍由已有控制器管理。

验收使用真实 Chromium 中公开的 FileTree 和 PierreFileTree:默认名称与大小可见、横向滚动同步与列对齐、宽视图、嵌套与固定行、时间及类型值、排序请求与偏好保留、搜索相关性和纵向滚动恢复。本次不包括列拖动排序、手动调宽、额外元数据字段或文件系统监听。

实现状态

共享列实现通过独立规格和质量审查。真实 Chromium 验证默认名称与大小可见、四列对齐、横向同步、键盘显示右侧列、固定祖先行,以及窄面板中的十层缩进。元数据显示、排序请求、偏好保留、搜索相关性和滚动恢复均通过公开组件检查。

文件名缩略

元数据列保留各自规定宽度,文件名使用名称列内的剩余空间并保持 Pierre 中间缩略。深层目录缩进限制在名称列内部,为图标和名称保留空间,确保各列对齐。未知目录大小仍留空;内联重命名保持组件既有的大小隐藏行为。

目录大小持久缓存

Files 重新打开和 worker 重启后复用已结束的统计结果。默认状态目录保存最多 256 条结果,React 共用队列在缓存命中后不递归读取目录。刷新与重新计算触发新扫描。Files 修改成功后,后端清除受影响祖先与子目录的内存和磁盘样本,并取消相关活动扫描,包含根目录重叠的项目。跳过条目的不完整结果保留来源状态,活动扫描 token 不持久保存。

采用现有原子 JSON 写入函数;缓存损坏或不可写时仍可扫描。Python sqlite3 支持持久事务,但此处只有一个 worker 和有限样本,不增加数据库。Pierre 树和 React 两并发队列保持现有作用。

缓存以验证后的目录绝对路径索引,并检查设备和 inode,避免项目重绑定或目录替换后读取另一目录的结果。深层编辑可能使缓存过期,详情保留时间和完整性;大小排序保持近期完整样本规则。不增加文件监听、递归新鲜度验证、内容读取或额外 profile。

验收通过 project_folder_size 和 Files:缓存重新加载后无需递归扫描;损坏缓存不阻断查询;不完整结果不变成完整结果;目录替换不复用旧值;重新打开和详情不重复扫描,刷新与重新计算仍更新大小。

实现状态

后端持久化和 Files 复用通过公开入口回归、独立规格审查和质量审查。新 worker 保留完整与跳过条目结果;Files 修改使持久祖先样本与根目录扫描失效;重新挂载复用已结束的统计,刷新和重新计算仍执行扫描。

真实组件预览

此框架交互预览使用实际 Pierre 组件及产品文件夹配置,演示层级和选择操作;列布局通过共享产品组件单独验证。数据和大小为示例,不读取或修改真实文件。可展开目录、选择条目、键盘导航、过滤和切换主题。新建图标仅展示产品按钮外观。

OpenProgram

边界与功能接入

能力当前设计
显示与交互Pierre 负责行布局、层级、选中、焦点、虚拟滚动、键盘导航。目录使用 icons.remap 与自定义 sprite;展开状态切换开合路径,禁止旋转文件夹。
路径与工具栏文件树与导航、工具栏统一使用 8px 左右外留白。第一行 14px 自适应面包屑,点击路径优先在已加载的目录条目中定位并展开祖先,不重新读取列表或重算大小;仅缺失目标时补充查询。路径按钮至少 32px 高、水平内边距保持 8px,箭头两侧不加 gap,并各向相邻按钮靠近 4px,按钮内边距与宽度保持不变,不显示重复名称的悬浮提示,右端复制完整绝对路径,成功后显示 1.5 秒勾选反馈;路径按钮右键可复制所点位置的相对路径、绝对路径和名称;第二行搜索、新建文件、新建目录、刷新、排序、信息;第三行按需展开搜索。保留现有按钮与圆角菜单。
查询与排序project_file_tree 仍按目录懒加载、分页及排序。框架比较器保持后端顺序,支持名称、类型、修改时间、大小与文件夹优先;不擅自回到字母排序。
文件与文件夹大小普通文件显示字节数;可见目录复用有界后台统计,搜索忽略目录(如 .cache、node_modules)仍可查看元数据与计算大小,保留缓存、扫描中、完整、部分、取消、错误状态。列表直接显示大小数值,不附加 ≈ 或 ≥;正在统计且已有数值时,仅该数值以灰色缓慢明暗变化,数值继续更新;统计停止后恢复正常,不新增文字或图标;暂无数值时留空,不显示占位横线;估算、统计下界及完成状态保留在详细信息中,详细信息可继续计算。
搜索与定位搜索仍使用后端权限范围与分页。结果使用 Pierre 层级显示;高亮模式保留目录。模糊匹配继续由后端判定,以匹配标记及当前项原生选中状态表示;字面查询使用框架文本高亮。定位通过控制器展开与滚动,不依赖旧手写行 DOM。
新建、重命名与右键现有新建与重命名表单验证后再提交;不允许框架内部移动替代服务端操作。右键继续提供详情、系统定位、创建、复制路径、剪切、复制、粘贴、重命名及删除确认。
刷新与错误保留选中路径、展开目录和已加载分页;等待刷新时保留旧行。父目录收起后保持关闭,即使内部子目录曾展开;重新展开时恢复子目录状态。滚动接近已加载目录末尾时自动读取下一页,不设置固定分页按钮;失败时停止自动重试并提供显式重试。蓝色选中行不显示边框;未选中行的键盘焦点指示保留。文件管理工具栏与列表之间不显示分隔线;文件树取消上下额外内边距,横向外边距缩至 4px。目录加载与分页失败给出路径及重试入口,不显示虚假的文件条目。
状态与权限工作区范围、请求取消、过期响应隔离、草稿保护和服务端幂等变更保持现有合同。框架不接触真实文件内容和权限判定。

参考与选择

采用 Pierre Trees 官方 React 接口,固定版本 1.0.0-beta.6。已核对本机 Codex 的文件树实现及同源 SVG。保留 Lucide 文件夹与产品导航图标;不继续维护手写递归行、固定 27px 缩进和自定义横向连线。不启用会绕过服务端验证的客户端拖放移动。

共享文件类型图标见 图标设计;文件内容、草稿与恢复合同见 文件操作设计。Apache 2.0 与图标 MIT 许可随产品发布。

实现状态

已接入官方组件。394 项 Web 测试、511 项合同测试、Web 检查、类型检查、生产构建和独立复核通过。默认 App 深色界面已核验目录开合、虚拟滚动、文件大小、文件标签页、原生右键菜单、排序菜单及刷新后的路径保留。嵌套父目录关闭、收紧的边距及无按钮自动分页已在 App 验证;关闭父目录后的刷新会保留内部已展开目录及其祖先缓存,真实组件回归测试覆盖这一过程。独立 HTML 预览受本地浏览器 URL 策略限制,未完成浏览器可视验收;浅色模式未单独人工验收。