Skip to content

Commit da67b83

Browse files
committed
chore(core): migrate project documentation to OpenSpec
- move project conventions, architecture, and tech stack details to `openspec/project.md` - introduce `AGENTS.md` for AI assistant instructions - update `CLAUDE.md` to reference `openspec/project.md` for project context
1 parent 7b749a7 commit da67b83

4 files changed

Lines changed: 756 additions & 117 deletions

File tree

AGENTS.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!-- OPENSPEC:START -->
2+
3+
# OpenSpec Instructions
4+
5+
These instructions are for AI assistants working in this project.
6+
7+
Always open `@/openspec/AGENTS.md` when the request:
8+
9+
- Mentions planning or proposals (words like proposal, spec, change, plan)
10+
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
11+
- Sounds ambiguous and you need the authoritative spec before coding
12+
13+
Use `@/openspec/AGENTS.md` to learn:
14+
15+
- How to create and apply change proposals
16+
- Spec format and conventions
17+
- Project structure and guidelines
18+
19+
Keep this managed block so 'openspec update' can refresh the instructions.
20+
21+
<!-- OPENSPEC:END -->

CLAUDE.md

Lines changed: 14 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -1,126 +1,23 @@
1-
# Style
1+
<!-- OPENSPEC:START -->
22

3-
- 当前项目使用 styled-components 库来定义样式组件,v1 的 style 构建机制已经被废弃
4-
- 优先使用 CSS 变量,而不是使用硬编码的样式值
5-
- 应避免硬编码尺寸和时长,改用 useTheme() 的 token(如 motionDurationMid、borderRadiusSM/MD 等)或集中定义的样式变量,以保证跨主题一致性和后续维护的便捷
6-
- CSS 样式文件位于 /Users/mark/MyProjects/echolab/src/renderer/src/assets/styles 目录
7-
- assets/styles 目录下的 SCSS(含 ant.scss)均为全局引入,会全局生效。
8-
- 项目优先使用 styled-components 而非全局 SCSS 来定制 antd 组件样式,应该用 styled(Component) 包装而不是全局 classNames,保持架构一致性和避免样式污染
9-
- 项目约定:所有图标统一使用 lucide-react,而不是 emoji。
10-
- 在布局实现上,后续优先使用 flex 布局(尽量避免使用 grid 作为默认方案)。
11-
- 项目优先使用 antd 组件库,如果组件可以被 antd 复用则优先使用 antd 而不是自定义开发
3+
# OpenSpec Instructions
124

13-
## 主题变量使用最佳实践
5+
These instructions are for AI assistants working in this project.
146

15-
项目启用了 Ant Design 的 CSS 变量模式 (`cssVar: true`),在 styled-components 中应采用分类使用策略:
7+
Always open `@/openspec/AGENTS.md` when the request:
168

17-
### 使用 CSS 变量的场景(主题相关属性):
9+
- Mentions planning or proposals (words like proposal, spec, change, plan)
10+
- Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
11+
- Sounds ambiguous and you need the authoritative spec before coding
1812

19-
- 颜色系统:`var(--ant-color-bg-elevated, fallback)`
20-
- 阴影效果:`var(--ant-box-shadow-secondary, fallback)`
21-
- 主题切换时会发生变化的属性
13+
Use `@/openspec/AGENTS.md` to learn:
2214

23-
### 使用 JS 变量的场景(设计系统常量):
15+
- How to create and apply change proposals
16+
- Spec format and conventions
17+
- Project structure and guidelines
2418

25-
- 尺寸间距:`${SPACING.XS}px``${BORDER_RADIUS.SM}px`
26-
- 动画配置:`${ANIMATION_DURATION.SLOW}``${EASING.APPLE}`
27-
- 层级关系:`${Z_INDEX.MODAL}`
28-
- 字体配置:`${FONT_SIZES.SM}px``${FONT_WEIGHTS.MEDIUM}`
29-
- 毛玻璃效果:`${GLASS_EFFECT.BACKGROUND_ALPHA.LIGHT}`
19+
Keep this managed block so 'openspec update' can refresh the instructions.
3020

31-
### 推荐模式:
21+
<!-- OPENSPEC:END -->
3222

33-
```typescript
34-
const StyledComponent = styled.div`
35-
/* 主题相关:使用 CSS 变量 */
36-
background: var(--ant-color-bg-elevated, rgba(0, 0, 0, ${GLASS_EFFECT.BACKGROUND_ALPHA.LIGHT}));
37-
color: var(--ant-color-white, #ffffff);
38-
box-shadow: var(--ant-box-shadow-secondary, ${SHADOWS.SM});
39-
40-
/* 设计系统常量:使用 JS 变量 */
41-
padding: ${SPACING.XS}px ${SPACING.MD}px;
42-
border-radius: ${BORDER_RADIUS.SM}px;
43-
font-size: ${FONT_SIZES.SM}px;
44-
transition: opacity ${ANIMATION_DURATION.SLOW} ${EASING.APPLE};
45-
z-index: ${Z_INDEX.MODAL};
46-
`
47-
```
48-
49-
这种混合模式既保持了类型安全和构建时优化,又支持主题的运行时切换,是当前架构下的最佳实践。
50-
51-
# State Management
52-
53-
- 项目使用 Zustand 作为状态管理库,配合 Immer 中间件支持不可变状态更新,使用自定义的中间件栈包含持久化、DevTools 和订阅选择器功能
54-
- 状态管理架构分为三层:stores(具体状态存储)、infrastructure(基础设施和中间件)、persistence(持久化管理),主要有 settings、shortcuts、runtime 三个核心 store
55-
- 使用 MiddlewarePresets 提供预设配置:basic(基础)、persistent(持久化)、full(完整)、temporary(临时),支持状态迁移和选择性持久化
56-
- 项目规则:Zustand 必须使用 selector(useStore(selector))在组件/Hook 顶层调用,禁止在 useMemo/useEffect 等内部调用 store Hook,避免 Hooks 顺序问题;player 页面已按该规则修复。
57-
- Player 页面修复方案:统一使用 Zustand selector 顶层调用并禁止在 useMemo/useEffect 中调用 store Hook,且为 useSubtitleEngine 增加 subtitles 入参防御处理;已在 SubtitleOverlay、SubtitleListPanel、usePlayerControls、useVideoEvents、VideoSurface、useSubtitleSync 中落地。
58-
- Zustand 使用规范:避免在组件中使用返回对象的 useStore 选择器(如 useStore(s => ({ action1: s.action1, action2: s.action2 }))),因为每次 store 更新都会返回新对象引用导致组件重渲染,在有 useEffect 写入 store 的场景下会形成渲染-写入循环,触发 Maximum update depth exceeded;应使用单字段选择器(如 const action1 = useStore(s => s.action1))或配合 shallow 比较器来避免此问题。
59-
- 新增团队规范:React「副作用与状态更新」开发规范(防止无限更新),涵盖基本原则(渲染纯函数、Effect 三分法、幂等更新、稳定引用、严格清理、禁止写回自身依赖、Provider 值 memo、外部状态 selector 稳定)、常用模板(订阅/定时器/Fetch/props→state/Zustand/Context)、PR 检查清单、常见反模式、StrictMode 心智、工具配置建议、针对时钟/播放器补充与最小验收标准;默认 TS + React 18。
60-
61-
# Test
62-
63-
- 使用 vitest 作为测试框架
64-
- **重要**:全局测试配置文件 `tests/setup.ts` 中 mock 了 `node:fs``node:fs/promises` 模块,这会影响需要真实文件系统操作的测试
65-
- 对于需要真实文件系统操作的测试(如文件清理、文件读写等),必须在测试文件开头使用 `vi.unmock('node:fs')``vi.unmock('node:fs/promises')` 来取消全局 mock
66-
- 示例:
67-
68-
```typescript
69-
// 在测试文件开头
70-
vi.unmock('node:fs')
71-
vi.unmock('node:fs/promises')
72-
73-
// 然后导入真实的 fs
74-
import * as fs from 'fs'
75-
```
76-
77-
# Package Management
78-
79-
- 项目使用 pnpm 作为包管理器
80-
81-
# Logging
82-
83-
- 项目统一使用 loggerService 记录日志而不是 console;示例:const logger = loggerService.withContext('<ComponentName>')
84-
85-
# Deprecated Code
86-
87-
- v1-deprecated 目录中的所有内容都是废弃的,只能用于学习业务逻辑,不能使用其中的任何组件和代码
88-
89-
# Important
90-
91-
- 不要执行任何杀掉进程和启动程序的命令,这些操作始终应该由用户来做,AI只负责提醒用户
92-
- 始终使用中文回复我
93-
- 任何组件或页面都不要支持写入currentTime,关于播放器的控制应该全权由编排器来控制
94-
- 包管理器工具请使用 pnpm
95-
- logger 的使用例子: `logger.error('Error in MediaClock listener:', { error: error })`, 第二参数必须接收为 `{}`
96-
97-
## Resource Management & Cleanup
98-
99-
- **临时文件清理规范**:所有生成临时文件的服务都应实现集中清理机制,参考 `FFmpegDownloadService.cleanupTempFiles()``SubtitleExtractorService.cleanupTempFiles()` 的实现模式
100-
- 临时文件清理的最佳实践:
101-
1. 在服务中实现 `cleanupTempFiles()` 方法,扫描并删除符合特定模式的临时文件
102-
2.`src/main/index.ts``app.on('will-quit')` 事件中调用清理方法
103-
3. 通过 IPC 通道暴露清理接口,允许渲染进程手动触发清理(如 `SubtitleExtractor_CleanupTemp`
104-
4. 使用正则表达式精确匹配临时文件模式,避免误删其他文件
105-
5. 包含完整的错误处理和日志记录,跳过正在使用或无法删除的文件
106-
- 临时文件命名规范:使用 `<prefix>_<timestamp>_<random>.<ext>` 格式(如 `subtitle_1234567890_abc123.srt`),便于模式匹配和清理
107-
108-
## File System Operations
109-
110-
- **禁止使用同步文件操作**:在主进程中必须使用异步文件 API(`fs.promises.*`),避免阻塞事件循环导致应用冻结
111-
- 文件操作最佳实践:
112-
- ❌ 错误示例:`fs.readdirSync()`, `fs.unlinkSync()`, `fs.readFileSync()`
113-
- ✅ 正确示例:`await fs.promises.readdir()`, `await fs.promises.unlink()`, `await fs.promises.readFile()`
114-
- 批量文件操作使用 `Promise.all()` 并行执行,提升性能
115-
- 所有文件操作方法应声明为 `async` 并返回 `Promise`
116-
117-
## Issues & Solutions
118-
119-
1. DictionaryPopover 组件主题兼容性问题已修复:将硬编码的深色主题颜色(白色文字、深色背景)替换为 Ant Design CSS 变量(如 `var(--ant-color-text)``var(--ant-color-bg-elevated)`),实现浅色和深色主题的自动适配,包括文字颜色、背景色、边框、滚动条和交互状态的完整主题化。
120-
121-
2. SubtitleExtractorService 临时文件清理机制已实现:在应用退出时自动清理系统临时目录中的字幕临时文件,防止磁盘空间浪费;支持通过 IPC 通道手动触发清理。
122-
123-
## Task Master AI Instructions
124-
125-
**Import Task Master's development workflow commands and guidelines, treat as if import is in the main CLAUDE.md file.**
126-
@./.taskmaster/CLAUDE.md
23+
> **注意**: 项目的详细技术规范、架构模式、代码风格等信息已迁移至 `@/openspec/project.md`,请参考该文件获取完整的项目上下文信息。

0 commit comments

Comments
 (0)