fix: remove hardcoded paths, gitignore binaries

- Add paths.go with WorkspaceRoot(), CoreRoot(), PlansRoot()
- All workspace paths now check CORE_WORKSPACE env var first
- Fallback: ~/Code/.core/workspace (works on any machine)
- Remove committed core-agent and mcp binaries from tracking
- Add .gitignore for compiled binaries

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Snider 2026-03-17 18:13:44 +00:00
parent 0622982fa7
commit e677d15bdd
13 changed files with 53 additions and 32 deletions

4
.gitignore vendored
View file

@ -2,3 +2,7 @@
.core/
docker/.env
ui/node_modules
# Compiled binaries
core-agent
mcp
*.exe

Binary file not shown.

BIN
mcp

Binary file not shown.

View file

@ -4,7 +4,6 @@ package agentic
import (
"encoding/json"
"os"
"path/filepath"
"time"
@ -24,12 +23,7 @@ type CompletionEvent struct {
// emitCompletionEvent appends a completion event to the events log.
// The plugin's hook watches this file to notify the orchestrating agent.
func emitCompletionEvent(agent, workspace string) {
home, err := os.UserHomeDir()
if err != nil {
return
}
eventsFile := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace", "events.jsonl")
eventsFile := filepath.Join(WorkspaceRoot(), "events.jsonl")
event := CompletionEvent{
Type: "agent_completed",

29
pkg/agentic/paths.go Normal file
View file

@ -0,0 +1,29 @@
// SPDX-License-Identifier: EUPL-1.2
package agentic
import (
"os"
"path/filepath"
)
// WorkspaceRoot returns the root directory for agent workspaces.
// Checks CORE_WORKSPACE env var first, falls back to ~/Code/.core/workspace.
func WorkspaceRoot() string {
return filepath.Join(CoreRoot(), "workspace")
}
// CoreRoot returns the root directory for core ecosystem files.
// Checks CORE_WORKSPACE env var first, falls back to ~/Code/.core.
func CoreRoot() string {
if root := os.Getenv("CORE_WORKSPACE"); root != "" {
return root
}
home, _ := os.UserHomeDir()
return filepath.Join(home, "Code", ".core")
}
// PlansRoot returns the root directory for agent plans.
func PlansRoot() string {
return filepath.Join(CoreRoot(), "plans")
}

View file

@ -313,8 +313,7 @@ func (s *PrepSubsystem) planList(_ context.Context, _ *mcp.CallToolRequest, inpu
// --- Helpers ---
func (s *PrepSubsystem) plansDir() string {
home, _ := os.UserHomeDir()
return filepath.Join(home, "Code", "host-uk", "core", ".core", "plans")
return PlansRoot()
}
func planPath(dir, id string) string {

View file

@ -54,8 +54,7 @@ func (s *PrepSubsystem) createPR(ctx context.Context, _ *mcp.CallToolRequest, in
return nil, CreatePROutput{}, coreerr.E("createPR", "no Forge token configured", nil)
}
home, _ := os.UserHomeDir()
wsDir := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace", input.Workspace)
wsDir := filepath.Join(WorkspaceRoot(), input.Workspace)
srcDir := filepath.Join(wsDir, "src")
if _, err := os.Stat(srcDir); err != nil {

View file

@ -58,13 +58,13 @@ func NewPrep() *PrepSubsystem {
}
return &PrepSubsystem{
forgeURL: envOr("FORGE_URL", "https://forge.lthn.ai"),
forgeToken: forgeToken,
brainURL: envOr("CORE_BRAIN_URL", "https://api.lthn.sh"),
brainKey: brainKey,
specsPath: envOr("SPECS_PATH", filepath.Join(home, "Code", "host-uk", "specs")),
codePath: envOr("CODE_PATH", filepath.Join(home, "Code")),
client: &http.Client{Timeout: 30 * time.Second},
forgeURL: envOr("FORGE_URL", "https://forge.lthn.ai"),
forgeToken: forgeToken,
brainURL: envOr("CORE_BRAIN_URL", "https://api.lthn.sh"),
brainKey: brainKey,
specsPath: envOr("SPECS_PATH", filepath.Join(home, "Code", "specs")),
codePath: envOr("CODE_PATH", filepath.Join(home, "Code")),
client: &http.Client{Timeout: 30 * time.Second},
}
}
@ -152,8 +152,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
}
// Workspace root: .core/workspace/{repo}-{timestamp}/
home, _ := os.UserHomeDir()
wsRoot := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
wsRoot := WorkspaceRoot()
wsName := fmt.Sprintf("%s-%d", input.Repo, time.Now().Unix())
wsDir := filepath.Join(wsRoot, wsName)

View file

@ -104,8 +104,7 @@ func (s *PrepSubsystem) delayForAgent(agent string) time.Duration {
// countRunningByAgent counts running workspaces for a specific agent type.
func (s *PrepSubsystem) countRunningByAgent(agent string) int {
home, _ := os.UserHomeDir()
wsRoot := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
wsRoot := WorkspaceRoot()
entries, err := os.ReadDir(wsRoot)
if err != nil {
@ -163,8 +162,7 @@ func (s *PrepSubsystem) canDispatch() bool {
// drainQueue finds the oldest queued workspace and spawns it if a slot is available.
// Applies rate-based delay between spawns.
func (s *PrepSubsystem) drainQueue() {
home, _ := os.UserHomeDir()
wsRoot := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
wsRoot := WorkspaceRoot()
entries, err := os.ReadDir(wsRoot)
if err != nil {

View file

@ -43,8 +43,7 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu
return nil, ResumeOutput{}, coreerr.E("resume", "workspace is required", nil)
}
home, _ := os.UserHomeDir()
wsDir := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace", input.Workspace)
wsDir := filepath.Join(WorkspaceRoot(), input.Workspace)
srcDir := filepath.Join(wsDir, "src")
// Verify workspace exists

View file

@ -97,8 +97,7 @@ func (s *PrepSubsystem) registerStatusTool(server *mcp.Server) {
}
func (s *PrepSubsystem) status(ctx context.Context, _ *mcp.CallToolRequest, input StatusInput) (*mcp.CallToolResult, StatusOutput, error) {
home, _ := os.UserHomeDir()
wsRoot := filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
wsRoot := WorkspaceRoot()
entries, err := os.ReadDir(wsRoot)
if err != nil {

View file

@ -5,7 +5,6 @@ package agentic
import (
"context"
"fmt"
"os"
"path/filepath"
"time"
@ -196,6 +195,5 @@ func (s *PrepSubsystem) resolveWorkspaceDir(name string) string {
// workspaceRoot returns the root directory for agent workspaces.
func (s *PrepSubsystem) workspaceRoot() string {
home, _ := os.UserHomeDir()
return filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
return WorkspaceRoot()
}

View file

@ -366,8 +366,11 @@ func (m *Subsystem) agentStatusResource(ctx context.Context, req *mcp.ReadResour
}
func workspaceRoot() string {
if root := os.Getenv("CORE_WORKSPACE"); root != "" {
return filepath.Join(root, "workspace")
}
home, _ := os.UserHomeDir()
return filepath.Join(home, "Code", "host-uk", "core", ".core", "workspace")
return filepath.Join(home, "Code", ".core", "workspace")
}
func agentName() string {