# FileWatcher 设计文档

## 📋 需求分析

### 目标
实现文件变更监控，自动更新 ContextEngine 缓存

### 核心功能
1. ✅ 监控已缓存的文件
2. ✅ 检测文件变更（修改时间）
3. ✅ 自动更新缓存
4. ✅ 可选的变更通知

---

## 🎯 简化版实现方案（v1.0）

### 设计原则
1. **最小改动**：基于现有 ContextEngine
2. **简单可靠**：使用文件修改时间
3. **按需检查**：不使用后台线程
4. **可扩展**：预留接口

---

## 🏗️ 架构设计

### 核心类

```cangjie
// 文件变更信息
public class FileChange {
    public let path: Path
    public let changeType: ChangeType
    public let oldModTime: Int64
    public let newModTime: Int64
}

public enum ChangeType {
    | Modified
    | Deleted
}

// 文件监控器（简化版）
public class FileWatcher {
    // 文件修改时间缓存
    private var modTimes: HashMap<String, Int64>
    
    // 关联的 ContextEngine
    private var contextEngine: ContextEngine
    
    // 检查文件变更
    public func checkChanges(): Array<FileChange>
    
    // 同步上下文
    public func syncContext(): Unit
}
```

---

## 💡 实现策略

### 方案A：按需检查（推荐）
**特点**：
- 不使用后台线程
- 用户主动触发检查
- 简单可靠

**检查时机**：
1. 每次 @mention 引用文件时
2. 用户执行特定命令时（如 `/refresh`）
3. Agent 开始处理输入前

**实现**：
```cangjie
// 在 process_input.cj 中
func checkFileChanges(app: CliApp) {
    let changes = app.fileWatcher.checkChanges()
    if (changes.size > 0) {
        app.fileWatcher.syncContext()
        PrintUtils.printInfo("Detected ${changes.size} file changes, cache updated")
    }
}
```

---

### 方案B：定时检查（未来版本）
**特点**：
- 后台定时检查
- 自动更新
- 复杂度高

**暂不实现**：需要线程管理

---

## 📝 详细实现

### 1. FileChange 类
```cangjie
public class FileChange {
    public let path: Path
    public let changeType: ChangeType
    public let oldModTime: Int64
    public let newModTime: Int64
    
    public init(path: Path, changeType: ChangeType, oldModTime: Int64, newModTime: Int64) {
        this.path = path
        this.changeType = changeType
        this.oldModTime = oldModTime
        this.newModTime = newModTime
    }
    
    public func toString(): String {
        return "${changeType}: ${path.toString()}"
    }
}

public enum ChangeType {
    | Modified
    | Deleted
}
```

### 2. FileWatcher 类
```cangjie
public class FileWatcher {
    private var modTimes: HashMap<String, Int64>
    private var contextEngine: ContextEngine
    
    public init(contextEngine: ContextEngine) {
        this.modTimes = HashMap<String, Int64>()
        this.contextEngine = contextEngine
    }
    
    /**
     * 记录文件的修改时间
     */
    public func track(path: Path): Unit {
        if (exists(path)) {
            let modTime = getModTime(path)
            this.modTimes[path.toString()] = modTime
        }
    }
    
    /**
     * 检查所有已跟踪文件的变更
     */
    public func checkChanges(): Array<FileChange> {
        let changes = ArrayList<FileChange>()
        
        // 检查 ContextEngine 中的所有文件
        for (cachedPath in this.contextEngine.getAllFiles()) {
            let pathKey = cachedPath.toString()
            
            // 获取记录的修改时间
            let oldModTime = this.modTimes.get(pathKey)
            
            if (!exists(cachedPath)) {
                // 文件已删除
                if (let Some(oldTime) <- oldModTime) {
                    changes.add(FileChange(
                        cachedPath, 
                        ChangeType.Deleted, 
                        oldTime, 
                        0
                    ))
                }
            } else {
                // 检查是否修改
                let newModTime = getModTime(cachedPath)
                match (oldModTime) {
                    case Some(oldTime) =>
                        if (newModTime > oldTime) {
                            changes.add(FileChange(
                                cachedPath,
                                ChangeType.Modified,
                                oldTime,
                                newModTime
                            ))
                        }
                    case _ =>
                        // 第一次跟踪
                        this.modTimes[pathKey] = newModTime
                }
            }
        }
        
        return changes.toArray()
    }
    
    /**
     * 同步上下文：更新或移除变更的文件
     */
    public func syncContext(): Unit {
        let changes = this.checkChanges()
        
        for (change in changes) {
            match (change.changeType) {
                case ChangeType.Modified =>
                    // 重新读取文件
                    try {
                        let content = String.fromUtf8(File.readFrom(change.path))
                        this.contextEngine.addFile(change.path, content)
                        this.modTimes[change.path.toString()] = change.newModTime
                        LogUtils.info("Updated cache for modified file: ${change.path.toString()}")
                    } catch (e: Exception) {
                        LogUtils.error("Failed to update cache: ${e.message}")
                    }
                
                case ChangeType.Deleted =>
                    // 从缓存中移除
                    this.contextEngine.removeFile(change.path)
                    this.modTimes.remove(change.path.toString())
                    LogUtils.info("Removed deleted file from cache: ${change.path.toString()}")
            }
        }
    }
    
    /**
     * 获取文件修改时间（简化版：使用文件大小+时间近似）
     */
    private func getModTime(path: Path): Int64 {
        // TODO: 使用真实的文件修改时间 API
        // 暂时返回固定值（简化实现）
        return 0
    }
}
```

---

## 🔌 集成点

### 1. CliApp 集成
```cangjie
// cli_app.cj
protected class CliApp {
    protected let contextEngine: ContextEngine
    protected let fileWatcher: FileWatcher
    
    protected init() {
        // ...
        this.contextEngine = ContextEngine(maxCacheSize: 50)
        this.fileWatcher = FileWatcher(this.contextEngine)
    }
}
```

### 2. process_input 集成
```cangjie
// process_input.cj
private func executeAgentTask(app: CliApp, input: String): Unit {
    // 1. 检查文件变更
    let changes = app.fileWatcher.checkChanges()
    if (changes.size > 0) {
        app.fileWatcher.syncContext()
        PrintUtils.printInfo("📝 Updated ${changes.size} file(s)")
    }
    
    // 2. 解析 @mention
    let parseResult = MentionParser.parse(input)
    
    // 3. 跟踪新引用的文件
    for (mention in parseResult.mentions) {
        app.fileWatcher.track(mention.path)
    }
    
    // ...
}
```

---

## ⚠️ 限制和约束

### 当前限制（v1.0）
1. **只检查已缓存的文件**：不监控整个项目
2. **按需检查**：不是实时监控
3. **简化的修改时间**：可能不准确（需要真实 API）

### 未来改进（v2.0）
1. 使用真实的文件修改时间 API
2. 支持监控目录
3. 支持实时通知
4. 后台定时检查

---

## 📊 工作量估算

### 代码量
- `file_watcher.cj`：约 120 行
- `file_watcher_test.cj`：约 80 行
- 集成代码：约 20 行
- **总计**：约 220 行

### 时间估算
- 核心实现：0.5 天
- 集成测试：0.5 天
- **总计**：1 天

---

## ✅ 验收标准

1. ✅ 能检测文件修改
2. ✅ 能检测文件删除
3. ✅ 自动更新缓存
4. ✅ 编译通过
5. ✅ 测试通过
6. ✅ 与 ContextEngine 集成

---

## 🎯 成功指标

- **检测准确率**：100%（基于修改时间）
- **性能影响**：<10ms（每次检查）
- **内存占用**：<1KB（修改时间缓存）

---

**设计者**：AI Assistant  
**设计日期**：2024-10-24  
**版本**：v1.0 设计草案

