feat: add phase 3 readonly models
This commit is contained in:
92
internal/projects/store.go
Normal file
92
internal/projects/store.go
Normal file
@@ -0,0 +1,92 @@
|
||||
package projects
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"codex-agent-manager/internal/codexhome"
|
||||
)
|
||||
|
||||
type Store struct {
|
||||
CodexHome string
|
||||
}
|
||||
|
||||
func (s Store) List() ([]Project, error) {
|
||||
configPath, err := codexhome.ResolveInside(s.CodexHome, "config.toml")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
data, err := os.ReadFile(configPath)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return []Project{}, nil
|
||||
}
|
||||
return nil, err
|
||||
}
|
||||
|
||||
projects := parseProjectsConfig(string(data), configPath)
|
||||
sort.Slice(projects, func(i, j int) bool {
|
||||
return projects[i].Path < projects[j].Path
|
||||
})
|
||||
for i := range projects {
|
||||
if projects[i].DisplayName == "" {
|
||||
projects[i].DisplayName = filepath.Base(projects[i].Path)
|
||||
}
|
||||
if info, err := os.Stat(projects[i].Path); err == nil && info.IsDir() {
|
||||
projects[i].DirectoryExists = true
|
||||
}
|
||||
}
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func parseProjectsConfig(input string, sourcePath string) []Project {
|
||||
var result []Project
|
||||
var current *Project
|
||||
scanner := bufio.NewScanner(strings.NewReader(input))
|
||||
for scanner.Scan() {
|
||||
line := strings.TrimSpace(scanner.Text())
|
||||
if line == "" || strings.HasPrefix(line, "#") {
|
||||
continue
|
||||
}
|
||||
if strings.HasPrefix(line, "[") && strings.HasSuffix(line, "]") {
|
||||
current = nil
|
||||
section := strings.TrimSuffix(strings.TrimPrefix(line, "["), "]")
|
||||
if !strings.HasPrefix(section, "projects.") {
|
||||
continue
|
||||
}
|
||||
path, err := strconv.Unquote(strings.TrimPrefix(section, "projects."))
|
||||
if err != nil || path == "" {
|
||||
continue
|
||||
}
|
||||
result = append(result, Project{
|
||||
Path: path,
|
||||
Source: SourceEvidence{Kind: "config_toml", Path: sourcePath, Confidence: "high"},
|
||||
TrustLevel: "unknown",
|
||||
})
|
||||
current = &result[len(result)-1]
|
||||
continue
|
||||
}
|
||||
if current == nil {
|
||||
continue
|
||||
}
|
||||
key, raw, ok := strings.Cut(line, "=")
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
value, err := strconv.Unquote(strings.TrimSpace(raw))
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
switch strings.TrimSpace(key) {
|
||||
case "trust_level":
|
||||
current.TrustLevel = value
|
||||
case "display_name":
|
||||
current.DisplayName = value
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
Reference in New Issue
Block a user