package tools import ( "os" "path/filepath" "strings" ) const ( // 嵌套指令最多注入 5 个文件、每个 20KB:这些内容每轮都会进 system, // 不设上限等于给模型塞一棵子树。 maxInstructionFiles = 5 maxInstructionBytes = 20 * 1024 ) // discoverInstructions 从 target(文件所在目录或目录本身)向上走到工作区根, // 把沿途的 AGENTS.md 交给 emit。根自己的 AGENTS.md 已在基础 system 提示里, // 这里跳过;工作区外的路径一律不发现。错误全部静默——读文件成功不该因为 // 顺带发现指令失败而失败。 func discoverInstructions(target string, isDir bool, root string, emit func(path, text string)) { if emit == nil { return } if root == "" { root, _ = os.Getwd() } rootAbs, ok := canonicalPath(root) if !ok { return } start := target if !isDir { start = filepath.Dir(target) } startAbs, ok := canonicalPath(start) if !ok { return } if !withinDir(rootAbs, startAbs) { return } found := 0 for dir := startAbs; ; dir = filepath.Dir(dir) { if dir == rootAbs || !withinDir(rootAbs, dir) { return } p := filepath.Join(dir, "AGENTS.md") data, err := os.ReadFile(p) if err == nil && len(data) > 0 && len(data) <= maxInstructionBytes { text := strings.TrimSpace(string(data)) if text != "" { emit(p, text) found++ if found >= maxInstructionFiles { return } } } parent := filepath.Dir(dir) if parent == dir { return } } } // canonicalPath 返回绝对路径,尽量解开符号链接(macOS 的 /var → /private/var)。 func canonicalPath(p string) (string, bool) { abs, err := filepath.Abs(p) if err != nil { return "", false } if resolved, err := filepath.EvalSymlinks(abs); err == nil { return resolved, true } return abs, true } // withinDir 报告 p 是否等于 root 或位于 root 之下(都已是绝对路径)。 func withinDir(root, p string) bool { rel, err := filepath.Rel(root, p) if err != nil { return false } return rel == "." || (rel != ".." && !strings.HasPrefix(rel, ".."+string(filepath.Separator))) }