fix: harden auth, sse, search, and docs

This commit is contained in:
OpenClaw Agent
2026-03-15 04:47:03 +08:00
parent f4574e6190
commit 80440077cf
4 changed files with 275 additions and 52 deletions

View File

@@ -2,6 +2,7 @@ package main
import (
"fmt"
"io"
"os"
"os/exec"
"path/filepath"
@@ -13,8 +14,10 @@ import (
// --- 道 (Config & State) ---
type Config struct {
MemoryRoot string
Port string
MemoryRoot string
Port string
SearchRoot string
MaxSearchFiles int
}
type TaoServer struct {
@@ -415,14 +418,14 @@ func (s *TaoServer) HousekeepMemory(targetMonth string) (string, error) {
if entry.IsDir() && strings.HasPrefix(entry.Name(), "W") {
src := filepath.Join(monthDir, entry.Name())
dst := filepath.Join(archiveRoot, entry.Name())
if err := os.Rename(src, dst); err != nil {
if err := movePath(src, dst); err != nil {
return "", err
}
}
if !entry.IsDir() && entry.Name() != "Month_Summary.md" {
src := filepath.Join(monthDir, entry.Name())
dst := filepath.Join(archiveRoot, entry.Name())
if err := os.Rename(src, dst); err != nil {
if err := movePath(src, dst); err != nil {
return "", err
}
}
@@ -434,6 +437,72 @@ func (s *TaoServer) HousekeepMemory(targetMonth string) (string, error) {
return fmt.Sprintf("归档完成: %s", archiveRoot), nil
}
func movePath(src string, dst string) error {
if err := os.Rename(src, dst); err == nil {
return nil
}
info, err := os.Stat(src)
if err != nil {
return err
}
if info.IsDir() {
return copyDir(src, dst)
}
if err := copyFile(src, dst); err != nil {
return err
}
return os.RemoveAll(src)
}
func copyDir(src string, dst string) error {
if err := os.MkdirAll(dst, 0755); err != nil {
return err
}
entries, err := os.ReadDir(src)
if err != nil {
return err
}
for _, entry := range entries {
sPath := filepath.Join(src, entry.Name())
dPath := filepath.Join(dst, entry.Name())
if entry.IsDir() {
if err := copyDir(sPath, dPath); err != nil {
return err
}
} else {
if err := copyFile(sPath, dPath); err != nil {
return err
}
}
}
return nil
}
func copyFile(src string, dst string) error {
in, err := os.Open(src)
if err != nil {
return err
}
defer in.Close()
if err := os.MkdirAll(filepath.Dir(dst), 0755); err != nil {
return err
}
out, err := os.Create(dst)
if err != nil {
return err
}
defer out.Close()
if _, err := io.Copy(out, in); err != nil {
return err
}
if err := out.Sync(); err != nil {
return err
}
return nil
}
func mustAtoi(s string) int {
n, _ := strconv.Atoi(s)
return n
@@ -447,8 +516,23 @@ func (s *TaoServer) InspectAndPropose(repoPath string) (string, error) {
repoPath = "/root/.openclaw/workspace/tao_mcp_go"
}
// 1) 拉取最新代码(若失败则继续)
_ = exec.Command("git", "-C", repoPath, "pull").Run()
allowed := getEnv("TAO_ALLOWED_REPOS", repoPath)
allowList := strings.Split(allowed, ",")
permitted := false
for _, item := range allowList {
item = strings.TrimSpace(item)
if item != "" && repoPath == item {
permitted = true
break
}
}
if !permitted {
return "repo_path not allowed", fmt.Errorf("repo_path not allowed: %s", repoPath)
}
if getEnvBool("TAO_ALLOW_GIT_PULL", false) {
_ = exec.Command("git", "-C", repoPath, "pull").Run()
}
// 2) 收集灵感(包含 #Todo/#Fix
inspDir := filepath.Join(s.config.MemoryRoot, "Inspirations")
@@ -568,7 +652,7 @@ func (s *TaoServer) RecordSummary(content string, weekOffset int) (string, error
return summaryPath, nil
}
// SearchMemory 遍历所有 Markdown 文件,寻找包含关键词的内容
// SearchMemoryAdvanced 遍历所有 Markdown 文件,寻找包含关键词的内容
func (s *TaoServer) SearchMemoryAdvanced(keyword string, related []string, causal bool, includeArchive bool) ([]string, error) {
s.mu.Lock()
defer s.mu.Unlock()
@@ -589,14 +673,19 @@ func (s *TaoServer) SearchMemoryAdvanced(keyword string, related []string, causa
}
}
err := filepath.Walk(s.config.MemoryRoot, func(path string, info os.FileInfo, err error) error {
scanned := 0
err := filepath.Walk(s.config.SearchRoot, func(path string, info os.FileInfo, err error) error {
if err != nil {
return err
}
if s.config.MaxSearchFiles > 0 && scanned >= s.config.MaxSearchFiles {
return filepath.SkipDir
}
if !includeArchive && info.IsDir() && strings.Contains(path, string(filepath.Separator)+"_Archive"+string(filepath.Separator)) {
return filepath.SkipDir
}
if !info.IsDir() && filepath.Ext(path) == ".md" {
scanned++
if !includeArchive && strings.Contains(path, string(filepath.Separator)+"_Archive"+string(filepath.Separator)) {
return nil
}
@@ -607,7 +696,7 @@ func (s *TaoServer) SearchMemoryAdvanced(keyword string, related []string, causa
text := string(content)
for _, term := range terms {
if term != "" && strings.Contains(text, term) {
rel, _ := filepath.Rel(s.config.MemoryRoot, path)
rel, _ := filepath.Rel(s.config.SearchRoot, path)
label := "命中"
isCausal := term != keyword
if isCausal {