refactor(agentic): adopt core.Env() + core.Path() across package
Replace all os.UserHomeDir/os.Getenv/os.Hostname with core.Env(). Replace all filepath.Base/Dir/Glob/IsAbs with core.PathBase/PathDir/ PathGlob/PathIsAbs. 10 files migrated: paths, prep, review_queue, remote, dispatch, ingest, mirror, plan, verify, watch. Imports eliminated: 5x os, 7x filepath. All file I/O and path construction now routes through Core primitives. Bumps dappco.re/go/core to v0.6.0. Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
3022f05fb8
commit
6393bfe4da
12 changed files with 42 additions and 53 deletions
4
go.mod
4
go.mod
|
|
@ -3,13 +3,13 @@ module dappco.re/go/agent
|
|||
go 1.26.0
|
||||
|
||||
require (
|
||||
dappco.re/go/core v0.5.0
|
||||
dappco.re/go/core v0.6.0
|
||||
dappco.re/go/core/api v0.2.0
|
||||
dappco.re/go/core/process v0.3.0
|
||||
dappco.re/go/core/ws v0.3.0
|
||||
forge.lthn.ai/core/api v0.1.6
|
||||
forge.lthn.ai/core/cli v0.3.7
|
||||
forge.lthn.ai/core/mcp v0.4.4
|
||||
forge.lthn.ai/core/mcp v0.4.8
|
||||
github.com/gin-gonic/gin v1.12.0
|
||||
github.com/gorilla/websocket v1.5.3
|
||||
github.com/modelcontextprotocol/go-sdk v1.4.1
|
||||
|
|
|
|||
11
go.sum
11
go.sum
|
|
@ -1,13 +1,18 @@
|
|||
dappco.re/go/core v0.5.0 h1:P5DJoaCiK5Q+af5UiTdWqUIW4W4qYKzpgGK50thm21U=
|
||||
dappco.re/go/core v0.5.0/go.mod h1:f2/tBZ3+3IqDrg2F5F598llv0nmb/4gJVCFzM5geE4A=
|
||||
dappco.re/go/core v0.6.0 h1:0wmuO/UmCWXxJkxQ6XvVLnqkAuWitbd49PhxjCsplyk=
|
||||
dappco.re/go/core v0.6.0/go.mod h1:f2/tBZ3+3IqDrg2F5F598llv0nmb/4gJVCFzM5geE4A=
|
||||
dappco.re/go/core/api v0.2.0 h1:5OcN9nawpp18Jp6dB1OwI2CBfs0Tacb0y0zqxFB6TJ0=
|
||||
dappco.re/go/core/api v0.2.0/go.mod h1:AtgNAx8lDY+qhVObFdNQOjSUQrHX1BeiDdMuA6RIfzo=
|
||||
dappco.re/go/core/i18n v0.2.0/go.mod h1:9eSVJXr3OpIGWQvDynfhqcp27xnLMwlYLgsByU+p7ok=
|
||||
dappco.re/go/core/io v0.2.0 h1:zuudgIiTsQQ5ipVt97saWdGLROovbEB/zdVyy9/l+I4=
|
||||
dappco.re/go/core/io v0.2.0/go.mod h1:1QnQV6X9LNgFKfm8SkOtR9LLaj3bDcsOIeJOOyjbL5E=
|
||||
dappco.re/go/core/log v0.1.0 h1:pa71Vq2TD2aoEUQWFKwNcaJ3GBY8HbaNGqtE688Unyc=
|
||||
dappco.re/go/core/log v0.1.0/go.mod h1:Nkqb8gsXhZAO8VLpx7B8i1iAmohhzqA20b9Zr8VUcJs=
|
||||
dappco.re/go/core/process v0.3.0 h1:BPF9R79+8ZWe34qCIy/sZy+P4HwbaO95js2oPJL7IqM=
|
||||
dappco.re/go/core/process v0.3.0/go.mod h1:qwx8kt6x+J9gn7fu8lavuess72Ye9jPBODqDZQ9K0as=
|
||||
dappco.re/go/core/scm v0.4.0/go.mod h1:ufb7si6HBkaT6zC8L67kLm8zzBaD1aQoTn4OsVAM1aI=
|
||||
dappco.re/go/core/store v0.2.0/go.mod h1:QQGJiruayjna3nywbf0N2gcO502q/oEkPoSpBpSKbLM=
|
||||
dappco.re/go/core/ws v0.3.0 h1:ZxR8y5pfrWvnCHVN7qExXz7fdP5a063uNqyqE0Ab8pQ=
|
||||
dappco.re/go/core/ws v0.3.0/go.mod h1:aLyXrJnbCOGL0SW9rC1EHAAIS83w3djO374gHIz4Nic=
|
||||
forge.lthn.ai/core/api v0.1.5 h1:NwZrcOyBjaiz5/cn0n0tnlMUodi8Or6FHMx59C7Kv2o=
|
||||
|
|
@ -42,6 +47,12 @@ forge.lthn.ai/core/mcp v0.4.0 h1:t4HMTI6CpoGB/VmE1aTklSEM8EI4Z/uKWyjGHxa1f4M=
|
|||
forge.lthn.ai/core/mcp v0.4.0/go.mod h1:eU35WT/8Mc0oJDVWdKaXEtNp27+Hc8KvnTKPf4DAqXE=
|
||||
forge.lthn.ai/core/mcp v0.4.4 h1:VTCOA1Dj/L7S8JCRg9BfYw7KfowW/Vvrp39bxc0dYyw=
|
||||
forge.lthn.ai/core/mcp v0.4.4/go.mod h1:eU35WT/8Mc0oJDVWdKaXEtNp27+Hc8KvnTKPf4DAqXE=
|
||||
forge.lthn.ai/core/mcp v0.4.6 h1:jZY72sfPiCppKU4YyX7Gwy7ynbgVzUto+3S6oAj5Qs4=
|
||||
forge.lthn.ai/core/mcp v0.4.6/go.mod h1:eU35WT/8Mc0oJDVWdKaXEtNp27+Hc8KvnTKPf4DAqXE=
|
||||
forge.lthn.ai/core/mcp v0.4.7 h1:Iy/83laUpkaH8W2EoDlVMJbyv60xJ4aMgQe6sOcwL7k=
|
||||
forge.lthn.ai/core/mcp v0.4.7/go.mod h1:eU35WT/8Mc0oJDVWdKaXEtNp27+Hc8KvnTKPf4DAqXE=
|
||||
forge.lthn.ai/core/mcp v0.4.8 h1:nd1x3AL8AkUfl0kziltoJUX96Nx1BeFWEbgHmfrkKz8=
|
||||
forge.lthn.ai/core/mcp v0.4.8/go.mod h1:eU35WT/8Mc0oJDVWdKaXEtNp27+Hc8KvnTKPf4DAqXE=
|
||||
github.com/99designs/gqlgen v0.17.88 h1:neMQDgehMwT1vYIOx/w5ZYPUU/iMNAJzRO44I5Intoc=
|
||||
github.com/99designs/gqlgen v0.17.88/go.mod h1:qeqYFEgOeSKqWedOjogPizimp2iu4E23bdPvl4jTYic=
|
||||
github.com/KyleBanks/depth v1.2.1 h1:5h8fQADFrWtarTdtDudMmGsC7GPbOAu6RVB3ffsVFHc=
|
||||
|
|
|
|||
|
|
@ -4,8 +4,6 @@ package agentic
|
|||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"syscall"
|
||||
"time"
|
||||
|
||||
|
|
@ -101,8 +99,7 @@ func agentCommand(agent, prompt string) (string, []string, error) {
|
|||
}
|
||||
return "coderabbit", args, nil
|
||||
case "local":
|
||||
home, _ := os.UserHomeDir()
|
||||
script := core.JoinPath(home, "Code", "core", "agent", "scripts", "local-agent.sh")
|
||||
script := core.JoinPath(core.Env("DIR_HOME"), "Code", "core", "agent", "scripts", "local-agent.sh")
|
||||
return "bash", []string{script, prompt}, nil
|
||||
default:
|
||||
return "", nil, core.E("agentCommand", "unknown agent: "+agent, nil)
|
||||
|
|
@ -191,7 +188,7 @@ func (s *PrepSubsystem) spawnAgent(agent, prompt, wsDir, srcDir string) (int, st
|
|||
}
|
||||
|
||||
// Emit completion event with actual status
|
||||
emitCompletionEvent(agent, filepath.Base(wsDir), finalStatus)
|
||||
emitCompletionEvent(agent, core.PathBase(wsDir), finalStatus)
|
||||
|
||||
// Notify monitor immediately (push to connected clients)
|
||||
if s.onComplete != nil {
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import (
|
|||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
)
|
||||
|
|
@ -21,7 +19,7 @@ func (s *PrepSubsystem) ingestFindings(wsDir string) {
|
|||
}
|
||||
|
||||
// Read the log file
|
||||
logFiles, _ := filepath.Glob(core.JoinPath(wsDir, "agent-*.log"))
|
||||
logFiles := core.PathGlob(core.JoinPath(wsDir, "agent-*.log"))
|
||||
if len(logFiles) == 0 {
|
||||
return
|
||||
}
|
||||
|
|
@ -92,8 +90,7 @@ func (s *PrepSubsystem) createIssueViaAPI(repo, title, description, issueType, p
|
|||
}
|
||||
|
||||
// Read the agent API key from file
|
||||
home, _ := os.UserHomeDir()
|
||||
r := fs.Read(core.JoinPath(home, ".claude", "agent-api.key"))
|
||||
r := fs.Read(core.JoinPath(core.Env("DIR_HOME"), ".claude", "agent-api.key"))
|
||||
if !r.OK {
|
||||
return
|
||||
}
|
||||
|
|
|
|||
|
|
@ -60,8 +60,7 @@ func (s *PrepSubsystem) mirror(ctx context.Context, _ *mcp.CallToolRequest, inpu
|
|||
|
||||
basePath := s.codePath
|
||||
if basePath == "" {
|
||||
home, _ := os.UserHomeDir()
|
||||
basePath = core.JoinPath(home, "Code", "core")
|
||||
basePath = core.JoinPath(core.Env("DIR_HOME"), "Code", "core")
|
||||
} else {
|
||||
basePath = core.JoinPath(basePath, "core")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
package agentic
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
"strconv"
|
||||
"unsafe"
|
||||
|
|
@ -45,11 +44,10 @@ func WorkspaceRoot() string {
|
|||
//
|
||||
// root := agentic.CoreRoot()
|
||||
func CoreRoot() string {
|
||||
if root := os.Getenv("CORE_WORKSPACE"); root != "" {
|
||||
if root := core.Env("CORE_WORKSPACE"); root != "" {
|
||||
return root
|
||||
}
|
||||
home, _ := os.UserHomeDir()
|
||||
return core.JoinPath(home, "Code", ".core")
|
||||
return core.JoinPath(core.Env("DIR_HOME"), "Code", ".core")
|
||||
}
|
||||
|
||||
// PlansRoot returns the root directory for agent plans.
|
||||
|
|
@ -64,11 +62,10 @@ func PlansRoot() string {
|
|||
//
|
||||
// name := agentic.AgentName() // "cladius" on Snider's Mac, "charon" elsewhere
|
||||
func AgentName() string {
|
||||
if name := os.Getenv("AGENT_NAME"); name != "" {
|
||||
if name := core.Env("AGENT_NAME"); name != "" {
|
||||
return name
|
||||
}
|
||||
hostname, _ := os.Hostname()
|
||||
h := core.Lower(hostname)
|
||||
h := core.Lower(core.Env("HOSTNAME"))
|
||||
if core.Contains(h, "snider") || core.Contains(h, "studio") || core.Contains(h, "mac") {
|
||||
return "cladius"
|
||||
}
|
||||
|
|
@ -102,7 +99,7 @@ func DefaultBranch(repoDir string) string {
|
|||
//
|
||||
// org := agentic.GitHubOrg() // "dAppCore"
|
||||
func GitHubOrg() string {
|
||||
if org := os.Getenv("GITHUB_ORG"); org != "" {
|
||||
if org := core.Env("GITHUB_ORG"); org != "" {
|
||||
return org
|
||||
}
|
||||
return "dAppCore"
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ import (
|
|||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
|
|
@ -341,7 +340,7 @@ func (s *PrepSubsystem) planList(_ context.Context, _ *mcp.CallToolRequest, inpu
|
|||
|
||||
func planPath(dir, id string) string {
|
||||
// Sanitise ID to prevent path traversal
|
||||
safe := filepath.Base(id)
|
||||
safe := core.PathBase(id)
|
||||
if safe == "." || safe == ".." || safe == "" {
|
||||
safe = "invalid"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,9 +10,7 @@ import (
|
|||
"encoding/json"
|
||||
goio "io"
|
||||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -56,14 +54,14 @@ var _ coremcp.Subsystem = (*PrepSubsystem)(nil)
|
|||
// sub.SetCompletionNotifier(monitor)
|
||||
// sub.RegisterTools(server)
|
||||
func NewPrep() *PrepSubsystem {
|
||||
home, _ := os.UserHomeDir()
|
||||
home := core.Env("DIR_HOME")
|
||||
|
||||
forgeToken := os.Getenv("FORGE_TOKEN")
|
||||
forgeToken := core.Env("FORGE_TOKEN")
|
||||
if forgeToken == "" {
|
||||
forgeToken = os.Getenv("GITEA_TOKEN")
|
||||
forgeToken = core.Env("GITEA_TOKEN")
|
||||
}
|
||||
|
||||
brainKey := os.Getenv("CORE_BRAIN_KEY")
|
||||
brainKey := core.Env("CORE_BRAIN_KEY")
|
||||
if brainKey == "" {
|
||||
if r := fs.Read(core.JoinPath(home, ".claude", "brain.key")); r.OK {
|
||||
brainKey = core.Trim(r.Value.(string))
|
||||
|
|
@ -89,7 +87,7 @@ func (s *PrepSubsystem) SetCompletionNotifier(n CompletionNotifier) {
|
|||
}
|
||||
|
||||
func envOr(key, fallback string) string {
|
||||
if v := os.Getenv(key); v != "" {
|
||||
if v := core.Env(key); v != "" {
|
||||
return v
|
||||
}
|
||||
return fallback
|
||||
|
|
@ -192,7 +190,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
|
|||
out := PrepOutput{WorkspaceDir: wsDir}
|
||||
|
||||
// Source repo path — sanitise to prevent path traversal
|
||||
repoName := filepath.Base(input.Repo) // strips ../ and absolute paths
|
||||
repoName := core.PathBase(input.Repo) // strips ../ and absolute paths
|
||||
if repoName == "." || repoName == ".." || repoName == "" {
|
||||
return nil, PrepOutput{}, core.E("prep", "invalid repo name: "+input.Repo, nil)
|
||||
}
|
||||
|
|
@ -573,7 +571,7 @@ func (s *PrepSubsystem) findConsumers(repo, wsDir string) int {
|
|||
}
|
||||
modData := mr.Value.(string)
|
||||
if core.Contains(modData, modulePath) && !core.HasPrefix(modData, "module "+modulePath) {
|
||||
consumers = append(consumers, filepath.Base(dir))
|
||||
consumers = append(consumers, core.PathBase(dir))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
|
|
@ -180,17 +179,17 @@ func resolveHost(host string) string {
|
|||
func remoteToken(host string) string {
|
||||
// Check environment first
|
||||
envKey := core.Sprintf("AGENT_TOKEN_%s", core.Upper(host))
|
||||
if token := os.Getenv(envKey); token != "" {
|
||||
if token := core.Env(envKey); token != "" {
|
||||
return token
|
||||
}
|
||||
|
||||
// Fallback to shared agent token
|
||||
if token := os.Getenv("MCP_AUTH_TOKEN"); token != "" {
|
||||
if token := core.Env("MCP_AUTH_TOKEN"); token != "" {
|
||||
return token
|
||||
}
|
||||
|
||||
// Try reading from file
|
||||
home, _ := os.UserHomeDir()
|
||||
home := core.Env("DIR_HOME")
|
||||
tokenFiles := []string{
|
||||
core.Sprintf("%s/.core/tokens/%s.token", home, core.Lower(host)),
|
||||
core.Sprintf("%s/.core/agent-token", home),
|
||||
|
|
|
|||
|
|
@ -339,8 +339,7 @@ func (s *PrepSubsystem) buildReviewCommand(ctx context.Context, repoDir, reviewe
|
|||
|
||||
// storeReviewOutput saves raw review output for training data collection.
|
||||
func (s *PrepSubsystem) storeReviewOutput(repoDir, repo, reviewer, output string) {
|
||||
home, _ := os.UserHomeDir()
|
||||
dataDir := core.JoinPath(home, ".core", "training", "reviews")
|
||||
dataDir := core.JoinPath(core.Env("DIR_HOME"), ".core", "training", "reviews")
|
||||
fs.EnsureDir(dataDir)
|
||||
|
||||
timestamp := time.Now().Format("2006-01-02T15-04-05")
|
||||
|
|
@ -374,16 +373,14 @@ func (s *PrepSubsystem) storeReviewOutput(repoDir, repo, reviewer, output string
|
|||
|
||||
// saveRateLimitState persists rate limit info for cross-run awareness.
|
||||
func (s *PrepSubsystem) saveRateLimitState(info *RateLimitInfo) {
|
||||
home, _ := os.UserHomeDir()
|
||||
path := core.JoinPath(home, ".core", "coderabbit-ratelimit.json")
|
||||
path := core.JoinPath(core.Env("DIR_HOME"), ".core", "coderabbit-ratelimit.json")
|
||||
data, _ := json.Marshal(info)
|
||||
fs.Write(path, string(data))
|
||||
}
|
||||
|
||||
// loadRateLimitState reads persisted rate limit info.
|
||||
func (s *PrepSubsystem) loadRateLimitState() *RateLimitInfo {
|
||||
home, _ := os.UserHomeDir()
|
||||
path := core.JoinPath(home, ".core", "coderabbit-ratelimit.json")
|
||||
path := core.JoinPath(core.Env("DIR_HOME"), ".core", "coderabbit-ratelimit.json")
|
||||
r := fs.Read(path)
|
||||
if !r.OK {
|
||||
return nil
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ import (
|
|||
"net/http"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
|
|
@ -130,7 +129,7 @@ func (s *PrepSubsystem) rebaseBranch(srcDir, branch string) bool {
|
|||
}
|
||||
|
||||
// Force-push the rebased branch to Forge (origin is local clone)
|
||||
st, _ := readStatus(filepath.Dir(srcDir))
|
||||
st, _ := readStatus(core.PathDir(srcDir))
|
||||
org := "core"
|
||||
repo := ""
|
||||
if st != nil {
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ package agentic
|
|||
|
||||
import (
|
||||
"context"
|
||||
"path/filepath"
|
||||
"time"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
|
|
@ -192,20 +191,17 @@ func (s *PrepSubsystem) watch(ctx context.Context, req *mcp.CallToolRequest, inp
|
|||
// findActiveWorkspaces returns workspace names that are running or queued.
|
||||
func (s *PrepSubsystem) findActiveWorkspaces() []string {
|
||||
wsRoot := WorkspaceRoot()
|
||||
entries, err := filepath.Glob(core.JoinPath(wsRoot, "*/status.json"))
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
entries := core.PathGlob(core.JoinPath(wsRoot, "*/status.json"))
|
||||
|
||||
var active []string
|
||||
for _, entry := range entries {
|
||||
wsDir := filepath.Dir(entry)
|
||||
wsDir := core.PathDir(entry)
|
||||
st, err := readStatus(wsDir)
|
||||
if err != nil {
|
||||
continue
|
||||
}
|
||||
if st.Status == "running" || st.Status == "queued" {
|
||||
active = append(active, filepath.Base(wsDir))
|
||||
active = append(active, core.PathBase(wsDir))
|
||||
}
|
||||
}
|
||||
return active
|
||||
|
|
@ -213,7 +209,7 @@ func (s *PrepSubsystem) findActiveWorkspaces() []string {
|
|||
|
||||
// resolveWorkspaceDir converts a workspace name to full path.
|
||||
func (s *PrepSubsystem) resolveWorkspaceDir(name string) string {
|
||||
if filepath.IsAbs(name) {
|
||||
if core.PathIsAbs(name) {
|
||||
return name
|
||||
}
|
||||
return core.JoinPath(WorkspaceRoot(), name)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue