chore: 从版本控制移除 tests/doc/,文件本地保留

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
yangzexuan 2026-06-01 01:07:15 +08:00
parent 40c5aa74b4
commit e948773e46
5 changed files with 0 additions and 484 deletions

View File

@ -1,105 +0,0 @@
# 开发指南
## 启动开发环境
```bash
./docs/script/start-dev.sh
```
浏览器打开 `http://localhost:1420`
## 测试覆盖
### 新增测试
| 测试文件 | 测试数 | 覆盖内容 |
|----------|:---:|------|
| `desktop/src/components/chat/PlantUMLRenderer.test.tsx` | 5 | SVG 渲染、预览弹窗、空 SVG 回退、错误状态 |
| `src/server/__tests__/workspace-service.test.ts` | +1 | 软连接检测专项测试 |
### 适配测试
| 测试文件 | 适配内容 |
|----------|----------|
| `desktop/src/stores/workspacePanelStore.test.ts` | `showHidden` 参数、`isSymlink` 字段 |
| `desktop/src/components/workspace/WorkspacePanel.test.tsx` | `isSymlink` 类型、`showHidden` 参数 |
| `src/server/__tests__/sessions.test.ts` | `isSymlink` 字段 |
### 已知 Flaky 测试(与本次改动无关)
- `WorkspacePanel > opens to all files when the current turn has no changed files`
- `WorkspacePanel > lazy loads the root tree...`
- `WorkspacePanel > can expand long file previews...`
- `workspacePanelStore > opens preview tabs...`(前提交 `showHidden` 参数导致 spy 调用次数变化)
- `H5AccessService > enable generates a token...`(环境依赖)
### 运行测试
```bash
# 桌面端
cd desktop && bun run lint && bun run test -- --run
# 服务端
cd .. && bun run check:server
```
## 数据流
### 文件树加载
```
WorkspacePanel UI 点击展开
→ workspacePanelStore.toggleTreeNode(sessionId, path)
→ workspacePanelStore.loadTree(sessionId, path, { showHidden })
→ sessionsApi.getWorkspaceTree(sessionId, path, showHidden)
→ GET /api/sessions/{id}/workspace/tree?showHidden=...
→ workspaceService.readTree(sessionId, relativePath, { showHidden })
→ fs.readdir({ withFileTypes: true })
→ filter + map → WorkspaceTreeEntry { name, path, isDirectory, isSymlink }
```
### 文件监听
```
ws/handler.ts open()
→ workspaceService.startWatcher(sessionId, workDir)
→ fs.watch(workDir, { recursive: true })
→ 200ms debounce
→ sendToSession({ type: 'file_changed', sessionId, path })
→ workspacePanelStore handleFileChanged()
→ 刷新展开的树节点 + 刷新匹配的预览标签
ws/handler.ts close()
→ workspaceService.stopWatcher(sessionId)
```
### PlantUML 渲染
```
MarkdownRenderer (识别 @startuml 代码块)
→ PlantUMLRenderer
→ POST /api/settings/plantuml/render { code }
→ handlePlantumlRender
→ spawn('java', ['-Djava.awt.headless=true', '-jar', jarPath, '-tsvg', '-pipe'])
→ stdin @startuml...@enduml → stdout SVG
→ DOMPurify.sanitize(svg)
→ dangerouslySetInnerHTML
```
### KaTeX 渲染
```
MarkdownRenderer (marked 解析)
→ 识别 $...$ (inline) / $$...$$ (block)
→ katex.renderToString(tex, { throwOnError: false })
→ 替换 marked HTML 占位符
→ dangerouslySetInnerHTML
```
## API 端点
| 方法 | 路径 | 说明 | 改动 |
|------|------|------|------|
| POST | `/api/settings/plantuml/render` | PlantUML 渲染pipe 模式) | 后端重写 |
| GET | `/api/sessions/{id}/workspace/tree` | 文件树(增加 `showHidden` 参数) | 参数新增 |
| WS | `file_changed` | 文件变化通知 | 消息类型新增 |

View File

@ -1,253 +0,0 @@
# 功能集成测试文档
> 本文档用于验证 `feature/workspace-enhancements` 分支的全部新增功能:
> 隐藏文件控制、软连接显示、Mermaid 流程图、PlantUML 图表、KaTeX 公式渲染。
---
## 一、Mermaid 流程图
### 1.1 文件树加载流程
```mermaid
graph TD
A[用户点击展开目录] --> B{是否为目录?}
B -->|是| C[workspacePanelStore.toggleTreeNode]
B -->|否| D[workspacePanelStore.openPreview]
C --> E[loadTree: sessionId, path, showHidden]
E --> F[GET /api/sessions/:id/workspace/tree]
F --> G[workspaceService.readTree]
G --> H[fs.readdir withFileTypes]
H --> I{entry 是否为 symlink?}
I -->|是| J[标记 isSymlink: true]
I -->|否| K[标记 isSymlink: false]
J --> L[UI 显示 link 图标]
K --> L
L --> M["返回 WorkspaceTreeEntry[]"]
M --> N["React 渲染文件树"]
```
### 1.2 文件监听流程
```mermaid
sequenceDiagram
participant Client as 前端
participant WS as WebSocket Server
participant Watcher as fs.watch
participant Store as workspacePanelStore
Client->>WS: WebSocket 连接建立
WS->>Watcher: startWatcher(sessionId, workDir)
Note over Watcher: fs.watch(workDir, recursive:true)
Watcher-->>WS: 文件变更事件
Note over WS: 200ms 防抖
WS->>Client: { type: 'file_changed', sessionId, path }
Client->>Store: handleFileChanged(sessionId, path)
Store->>Store: 刷新展开的树节点
Store->>Store: 刷新匹配的预览标签
Client->>WS: WebSocket 断开
WS->>Watcher: stopWatcher(sessionId)
```
---
## 二、PlantUML 图表
### 2.1 系统架构图
```plantuml
@startuml
!theme plain
package "桌面端 (desktop/)" {
component [React App] as React
component [PlantUMLRenderer] as PUML
component [MermaidRenderer] as MMD
component [MarkdownRenderer] as MD
}
package "服务端 (src/server/)" {
component [API Server :3456] as API
component [PlantUML Pipe] as Pipe
component [WebSocket] as WS
}
package "后端渲染" {
component [Java JVM] as Java
component [plantuml.jar] as Jar
}
React --> MD : Markdown 解析
MD --> PUML : @startuml 代码块
MD --> MMD : mermaid 代码块
PUML --> API : POST /api/settings/plantuml/render
API --> Pipe : spawn java -jar -pipe
Pipe --> Java : stdin @startuml...@enduml
Java --> Jar : 渲染
Jar --> Java : SVG
Java --> Pipe : stdout
Pipe --> API : SVG string
API --> PUML : { svg: "..." }
PUML --> React : DOMPurify.sanitize + dangerouslySetInnerHTML
WS --> React : file_changed 消息
@enduml
```
### 2.2 组件生命周期
```plantuml
@startuml
state "空闲" as Idle
state "加载中" as Loading
state "渲染失败" as Error
state "渲染成功" as Success
state "回退代码块" as Fallback
[*] --> Idle : 组件挂载
Idle --> Loading : code prop 变化
Loading --> Success : SVG 返回
Loading --> Error : 渲染异常
Loading --> Fallback : SVG 为 null无 jar 配置)
Success --> Loading : code 再次变化
Error --> Loading : code 再次变化
Fallback --> Loading : code 再次变化
@enduml
```
---
## 三、KaTeX 公式渲染
### 3.1 行内公式
爱因斯坦质能方程:$E = mc^2$
欧拉公式:$e^{i\pi} + 1 = 0$
二次方程求根公式:$x = \frac{-b \pm \sqrt{b^2 - 4ac}}{2a}$
### 3.2 块级公式
**贝叶斯定理:**
$$
P(A|B) = \frac{P(B|A) \cdot P(A)}{P(B)}
$$
**傅里叶变换:**
$$
\hat{f}(\xi) = \int_{-\infty}^{\infty} f(x) \cdot e^{-2\pi i x \xi} \, dx
$$
**矩阵乘法复杂度分析:**
$$
C_{i,j} = \sum_{k=1}^{n} A_{i,k} \cdot B_{k,j} \quad \Rightarrow \quad O(n^3)
$$
**梯度下降更新规则:**
$$
\theta_{t+1} = \theta_t - \eta \cdot \nabla_{\theta} J(\theta_t)
$$
---
## 四、代码块展示
### 4.1 TypeScript — 软连接检测
```typescript
// src/server/services/workspaceService.ts
export type WorkspaceTreeEntry = {
name: string
path: string
isDirectory: boolean
isSymlink: boolean
}
function readTree(sessionId: string, relativePath = '', showHidden = false) {
const entries = await fs.readdir(resolvedPath, { withFileTypes: true })
return entries
.filter(filterByShowHidden(showHidden))
.sort(directoriesFirst)
.map((entry) => ({
name: entry.name,
path: buildRelativePath(entry),
isDirectory: entry.isDirectory(),
isSymlink: entry.isSymbolicLink(),
}))
}
```
### 4.2 React 组件 — PlantUML 渲染
```tsx
// desktop/src/components/chat/PlantUMLRenderer.tsx
export function PlantUMLRenderer({ code }: Props) {
const [svg, setSvg] = useState<string | null>(null)
const [loading, setLoading] = useState(true)
const [error, setError] = useState<string | null>(null)
useEffect(() => {
api.post('/api/settings/plantuml/render', { code })
.then((result) => {
if (result.svg) {
setSvg(DOMPurify.sanitize(result.svg, {
ADD_TAGS: ['foreignObject'],
USE_PROFILES: { svg: true, svgFilters: true },
}))
}
})
.catch((e) => setError(e.message))
.finally(() => setLoading(false))
}, [code])
if (loading) return <LoadingSpinner />
if (error) return <ErrorBanner message={error} />
if (!svg) return <CodeViewer code={code} language="plantuml" />
return <div dangerouslySetInnerHTML={{ __html: svg }} />
}
```
### 4.3 Shell 脚本 — 启动命令
```bash
#!/usr/bin/env bash
# docs/script/start-dev.sh — 一键启动开发环境
SERVER_PORT=3456
echo "==> 启动后端..."
bun run src/server/index.ts &
SERVER_PID=$!
sleep 2
echo "==> 启动前端..."
cd desktop && bun run dev &
DESKTOP_PID=$!
# 清理
trap "kill $SERVER_PID $DESKTOP_PID" EXIT
wait
```
---
## 五、软连接测试
本目录下包含两个软连接,用于验证文件树的 `isSymlink` 显示功能:
| 软连接 | 目标 |
|--------|------|
| `symlink-summary` | `~/工作总结` |
| `symlink-ai-summary` | `~/个人总结/AI使用总结/ai使用分析/中英文 思维链对比分析_20260511.md` |
> 在文件树中展开本目录,软连接条目旁应显示 `🔗` 图标。

View File

@ -1,124 +0,0 @@
# 功能改动说明
## 分支feature/workspace-enhancements
### 一、文件树增强
#### 1.1 隐藏文件控制
**入口**:文件树工具栏 `👁` 按钮
**行为**
- 默认关闭(`showHiddenFiles: false`),不显示 `.` 开头的文件/目录
- 开启后仅过滤 `.git`,其余隐藏文件可见
- 状态通过 `workspacePanelStore.showHiddenFiles` 管理
- 传递给后端 `readTree``showHidden` 参数
**涉及文件**
| 文件 | 改动 |
|------|------|
| `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: boolean``readTree` 中调用 `entry.isSymbolicLink()` |
| `desktop/src/api/sessions.ts` | 前端 `WorkspaceTreeEntry` 类型同步添加 `isSymlink` |
| `desktop/src/components/workspace/WorkspacePanel.tsx` | 文件节点和目录节点添加 `link` 图标(`isSymlink``true` 时) |
#### 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()` 中启动 watcher`close()` 中停止 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/*`, `/health``http://127.0.0.1:3456`
- `/ws``ws://127.0.0.1:3456`

View File

@ -1 +0,0 @@
/Users/yangzexuan/个人总结/AI使用总结/ai使用分析/中英文 思维链对比分析_20260511.md

View File

@ -1 +0,0 @@
/Users/yangzexuan/工作总结