cc-haha/tests/doc/feature-summary.md
yangzexuan 12f9674976 feat: workspace file tree 增强 — 隐藏文件控制、文件监听、公式/PlantUML 渲染
解决了以下问题:

1. 文件树不展示隐藏文件:新增"显示隐藏文件"按钮,默认仅隐藏 .git 目
   录,开启 toggle 后显示全部文件。通过 query 参数 showHidden 从
   前端 store 贯穿到后端 readTree,过滤逻辑改为可切换而非硬编码。

2. 文件树不自动同步文件变化:在 WebSocket 连接建立后对 workDir 启
   动 fs.watch 递归监听,200ms 防抖后通过新增的 file_changed
   ServerMessage 推送到前端。前端 handleFileChanged 收到后自动刷新
   变化文件的父目录树和已打开的预览标签,保持展开状态不变。

3. 手动刷新文件树后展开节点内容丢失:修复 handleRefresh 逻辑,去掉
   invalidateExpandedTreeCache 的破坏性清除,改为先清缓存再并行加
   载所有展开路径,避免展开节点数据被删除后未重新加载。

4. Mermaid 流程图节点文本不显示:DOMPurify 的 svg profile 默认
   过滤 foreignObject 元素(Mermaid 用其渲染节点文本),添加
   ADD_TAGS: ["foreignObject"] 允许通过。

5. 新增 KaTeX 公式渲染:支持行内公式 $...$ 和块级公式 $$...$$,
   在 marked 解析前预处理避免特殊字符被转义。

6. 新增 PlantUML 图表渲染:服务端 POST /api/settings/plantuml/render
   通过本地 plantuml.jar 渲染 SVG,前端设置页面支持配置 jar 路径。
   未配置时回退为语法高亮代码块。

7. 文件预览 Tab 新增刷新按钮:只刷新当前文件内容,不影响文件树。

8. 浏览器模式开发支持:vite.config.ts 添加 proxy 将 /health、/api、
   /ws 代理到后端 127.0.0.1:3456。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-01 00:51:41 +08:00

4.3 KiB
Raw Blame History

功能改动说明

分支feature/workspace-enhancements

一、文件树增强

1.1 隐藏文件控制

入口:文件树工具栏 👁 按钮

行为

  • 默认关闭(showHiddenFiles: false),不显示 . 开头的文件/目录
  • 开启后仅过滤 .git,其余隐藏文件可见
  • 状态通过 workspacePanelStore.showHiddenFiles 管理
  • 传递给后端 readTreeshowHidden 参数

涉及文件

文件 改动
src/server/services/workspaceService.ts readTree 添加 showHidden 参数,默认 false 过滤 . 前缀,true 仅过滤 .git
src/server/api/sessions.ts 从 query string 读取 showHidden 参数传给 readTree
desktop/src/api/sessions.ts getWorkspaceTree 添加 showHidden 参数,拼接到请求 query
desktop/src/stores/workspacePanelStore.ts 添加 showHiddenFiles 状态 + toggleShowHiddenFiles 方法,loadTree 传递参数
desktop/src/components/workspace/WorkspacePanel.tsx 工具栏区域添加 👁 按钮

1.2 软连接支持

行为

  • 文件树中软连接条目显示 🔗 (link) 图标
  • 通过 Dirent.isSymbolicLink() 检测,无需额外 stat 调用

涉及文件

文件 改动
src/server/services/workspaceService.ts WorkspaceTreeEntry 添加 isSymlink: booleanreadTree 中调用 entry.isSymbolicLink()
desktop/src/api/sessions.ts 前端 WorkspaceTreeEntry 类型同步添加 isSymlink
desktop/src/components/workspace/WorkspacePanel.tsx 文件节点和目录节点添加 link 图标(isSymlinktrue 时)

1.3 文件监听

行为

  • WebSocket 连接建立后,对会话 workDir 启动 fs.watch({ recursive: true })
  • 文件变化 200ms 防抖后通过 sendToSession 推送 { type: 'file_changed', sessionId, path }
  • 前端收到后自动刷新展开的树节点和预览标签
  • 不监听 node_modules

涉及文件

文件 改动
src/server/ws/events.ts ServerMessage 添加 file_changed 消息类型
src/server/services/workspaceService.ts 新增 startWatcher(sessionId, workDir) / stopWatcher(sessionId) 方法
src/server/ws/handler.ts open() 中启动 watcherclose() 中停止 watcher
desktop/src/stores/workspacePanelStore.ts 注册 file_changed handler刷新树和预览标签

二、PlantUML 渲染

2.1 前端渲染组件

行为

  • Markdown 中 @@@plantuml / @startuml ... @enduml 代码块自动渲染为 SVG 图表
  • 渲染结果经过 DOMPurify.sanitize() 安全清洗
  • 渲染失败时显示错误信息

涉及文件

文件 改动
desktop/src/components/chat/PlantUMLRenderer.tsx 渲染组件:调用后端 API 获取 SVGDOMPurify 清洗error 状态
desktop/src/components/markdown/MarkdownRenderer.tsx 添加 shouldRenderAsPlantUML 判定,分发到 PlantUMLRenderer
desktop/src/components/chat/PlantUMLRenderer.test.tsx 5 个测试SVG 渲染、头部、预览弹窗、空 SVG 回退、错误状态

2.2 后端 Pipe 渲染

行为

  • execFile + 临时文件 改为 spawn -pipe 模式
  • stdin 写入 PlantUML 源码stdout 读取 SVG
  • -Djava.awt.headless=true 避免 macOS Dock 图标
  • 去掉临时文件 I/O

涉及文件

文件 改动
src/server/api/settings.ts handlePlantumlRender 改用 spawn('java', ['-Djava.awt.headless=true', '-jar', jarPath, '-tsvg', '-pipe'])

三、KaTeX 公式渲染

行为

  • Markdown 中 $...$ 行内公式和 $$...$$ 块级公式自动渲染
  • 通过 marked 标记扩展在渲染 Pipeline 中处理

涉及文件

文件 改动
desktop/src/components/markdown/MarkdownRenderer.tsx 添加 KaTeX 渲染逻辑,katex.renderToString 处理行内/块级公式

四、开发工具

4.1 start-dev.sh

位置docs/script/start-dev.sh

行为

  • 启动后端 bun run src/server/index.ts (port 3456)
  • 启动前端 cd desktop && bun run dev (Vite port 1420)
  • 浏览器打开 http://localhost:1420

4.2 Vite Proxy

位置desktop/vite.config.ts

行为

  • /api/*, /healthhttp://127.0.0.1:3456
  • /wsws://127.0.0.1:3456