From 1cc8fb50e15c60c3ca4a372c4803acfd2d2ecf32 Mon Sep 17 00:00:00 2001 From: Virgil Date: Mon, 30 Mar 2026 21:22:54 +0000 Subject: [PATCH] fix(ax): continue workspace naming cleanup Co-Authored-By: Virgil --- cmd/core-agent/commands.go | 8 +-- pkg/agentic/actions.go | 36 +++++++------- pkg/agentic/auto_pr.go | 18 +++---- pkg/agentic/commands.go | 6 +-- pkg/agentic/commands_workspace.go | 16 +++--- pkg/agentic/deps.go | 10 ++-- pkg/agentic/dispatch.go | 82 +++++++++++++++---------------- pkg/agentic/dispatch_sync.go | 8 +-- pkg/agentic/handlers.go | 32 ++++++------ pkg/agentic/ingest.go | 6 +-- pkg/agentic/paths.go | 58 +++++++++++----------- pkg/agentic/pr.go | 8 +-- pkg/agentic/prep.go | 38 +++++++------- pkg/agentic/queue.go | 10 ++-- pkg/agentic/resume.go | 14 +++--- pkg/agentic/status.go | 30 +++++------ pkg/agentic/verify.go | 14 +++--- pkg/lib/lib.go | 20 ++++---- pkg/monitor/harvest.go | 22 ++++----- pkg/monitor/monitor.go | 2 +- pkg/runner/paths.go | 8 +-- pkg/runner/queue.go | 12 ++--- pkg/setup/config.go | 10 ++-- pkg/setup/detect.go | 18 +++---- pkg/setup/setup.go | 68 ++++++++++++------------- 25 files changed, 277 insertions(+), 277 deletions(-) diff --git a/cmd/core-agent/commands.go b/cmd/core-agent/commands.go index 4660bae..e6d5203 100644 --- a/cmd/core-agent/commands.go +++ b/cmd/core-agent/commands.go @@ -116,12 +116,12 @@ func (commands appCommandSet) check(_ core.Options) core.Result { core.Print(nil, " agents: %s (MISSING)", agentsPath) } - wsRoot := agentic.WorkspaceRoot() - if fs.IsDir(wsRoot) { + workspaceRoot := agentic.WorkspaceRoot() + if fs.IsDir(workspaceRoot) { statusFiles := agentic.WorkspaceStatusPaths() - core.Print(nil, " workspace: %s (%d workspaces)", wsRoot, len(statusFiles)) + core.Print(nil, " workspace: %s (%d workspaces)", workspaceRoot, len(statusFiles)) } else { - core.Print(nil, " workspace: %s (MISSING)", wsRoot) + core.Print(nil, " workspace: %s (MISSING)", workspaceRoot) } core.Print(nil, " services: %d registered", len(commands.core.Services())) diff --git a/pkg/agentic/actions.go b/pkg/agentic/actions.go index 75c5a66..a12afbe 100644 --- a/pkg/agentic/actions.go +++ b/pkg/agentic/actions.go @@ -183,31 +183,31 @@ func (s *PrepSubsystem) handleQA(ctx context.Context, options core.Options) core if s.ServiceRuntime != nil && !s.Config().Enabled("auto-qa") { return core.Result{Value: true, OK: true} } - wsDir := options.String("workspace") - if wsDir == "" { + workspaceDir := options.String("workspace") + if workspaceDir == "" { return core.Result{Value: core.E("agentic.qa", "workspace is required", nil), OK: false} } - passed := s.runQA(wsDir) + passed := s.runQA(workspaceDir) if !passed { - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatus, ok := workspaceStatusValue(result) if ok { workspaceStatus.Status = "failed" workspaceStatus.Question = "QA check failed — build or tests did not pass" - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) } } } // Emit QA result for observability (monitor picks this up) if s.ServiceRuntime != nil { - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) repo := "" if ok { repo = workspaceStatus.Repo } s.Core().ACTION(messages.QAResult{ - Workspace: WorkspaceName(wsDir), + Workspace: WorkspaceName(workspaceDir), Repo: repo, Passed: passed, }) @@ -224,15 +224,15 @@ func (s *PrepSubsystem) handleAutoPR(ctx context.Context, options core.Options) if s.ServiceRuntime != nil && !s.Config().Enabled("auto-pr") { return core.Result{OK: true} } - wsDir := options.String("workspace") - if wsDir == "" { + workspaceDir := options.String("workspace") + if workspaceDir == "" { return core.Result{Value: core.E("agentic.auto-pr", "workspace is required", nil), OK: false} } - s.autoCreatePR(wsDir) + s.autoCreatePR(workspaceDir) // Emit PRCreated for observability if s.ServiceRuntime != nil { - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if ok && workspaceStatus.PRURL != "" { s.Core().ACTION(messages.PRCreated{ @@ -255,15 +255,15 @@ func (s *PrepSubsystem) handleVerify(ctx context.Context, options core.Options) if s.ServiceRuntime != nil && !s.Config().Enabled("auto-merge") { return core.Result{OK: true} } - wsDir := options.String("workspace") - if wsDir == "" { + workspaceDir := options.String("workspace") + if workspaceDir == "" { return core.Result{Value: core.E("agentic.verify", "workspace is required", nil), OK: false} } - s.autoVerifyAndMerge(wsDir) + s.autoVerifyAndMerge(workspaceDir) // Emit merge/review events for observability if s.ServiceRuntime != nil { - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if ok { if workspaceStatus.Status == "merged" { @@ -291,11 +291,11 @@ func (s *PrepSubsystem) handleVerify(ctx context.Context, options core.Options) // core.Option{Key: "workspace", Value: "/path/to/workspace"}, // )) func (s *PrepSubsystem) handleIngest(ctx context.Context, options core.Options) core.Result { - wsDir := options.String("workspace") - if wsDir == "" { + workspaceDir := options.String("workspace") + if workspaceDir == "" { return core.Result{Value: core.E("agentic.ingest", "workspace is required", nil), OK: false} } - s.ingestFindings(wsDir) + s.ingestFindings(workspaceDir) return core.Result{OK: true} } diff --git a/pkg/agentic/auto_pr.go b/pkg/agentic/auto_pr.go index 1610f8b..48ba0ce 100644 --- a/pkg/agentic/auto_pr.go +++ b/pkg/agentic/auto_pr.go @@ -11,15 +11,15 @@ import ( // autoCreatePR pushes the agent's branch and creates a PR on Forge // if the agent made any commits beyond the initial clone. -func (s *PrepSubsystem) autoCreatePR(wsDir string) { - result := ReadStatusResult(wsDir) +func (s *PrepSubsystem) autoCreatePR(workspaceDir string) { + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok || workspaceStatus.Branch == "" || workspaceStatus.Repo == "" { return } ctx := context.Background() - repoDir := WorkspaceRepoDir(wsDir) + repoDir := WorkspaceRepoDir(workspaceDir) process := s.Core().Process() // PRs target dev — agents never merge directly to main @@ -44,13 +44,13 @@ func (s *PrepSubsystem) autoCreatePR(wsDir string) { // Push the branch to forge forgeRemote := core.Sprintf("ssh://git@forge.lthn.ai:2223/%s/%s.git", org, workspaceStatus.Repo) if !process.RunIn(ctx, repoDir, "git", "push", forgeRemote, workspaceStatus.Branch).OK { - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatusUpdate, ok := workspaceStatusValue(result) if !ok { return } workspaceStatusUpdate.Question = "PR push failed" - writeStatusResult(wsDir, workspaceStatusUpdate) + writeStatusResult(workspaceDir, workspaceStatusUpdate) } return } @@ -64,25 +64,25 @@ func (s *PrepSubsystem) autoCreatePR(wsDir string) { prURL, _, err := s.forgeCreatePR(ctx, org, workspaceStatus.Repo, workspaceStatus.Branch, base, title, body) if err != nil { - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatusUpdate, ok := workspaceStatusValue(result) if !ok { return } workspaceStatusUpdate.Question = core.Sprintf("PR creation failed: %v", err) - writeStatusResult(wsDir, workspaceStatusUpdate) + writeStatusResult(workspaceDir, workspaceStatusUpdate) } return } // Update status with PR URL - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatusUpdate, ok := workspaceStatusValue(result) if !ok { return } workspaceStatusUpdate.PRURL = prURL - writeStatusResult(wsDir, workspaceStatusUpdate) + writeStatusResult(workspaceDir, workspaceStatusUpdate) } } diff --git a/pkg/agentic/commands.go b/pkg/agentic/commands.go index 30540df..83ba96e 100644 --- a/pkg/agentic/commands.go +++ b/pkg/agentic/commands.go @@ -152,11 +152,11 @@ func (s *PrepSubsystem) cmdPrep(options core.Options) core.Result { } func (s *PrepSubsystem) cmdStatus(_ core.Options) core.Result { - wsRoot := WorkspaceRoot() + workspaceRoot := WorkspaceRoot() fsys := s.Core().Fs() - listResult := fsys.List(wsRoot) + listResult := fsys.List(workspaceRoot) if !listResult.OK { - core.Print(nil, "no workspaces found at %s", wsRoot) + core.Print(nil, "no workspaces found at %s", workspaceRoot) return core.Result{OK: true} } diff --git a/pkg/agentic/commands_workspace.go b/pkg/agentic/commands_workspace.go index df9e977..e2a1455 100644 --- a/pkg/agentic/commands_workspace.go +++ b/pkg/agentic/commands_workspace.go @@ -22,9 +22,9 @@ func (s *PrepSubsystem) cmdWorkspaceList(_ core.Options) core.Result { statusFiles := WorkspaceStatusPaths() count := 0 for _, sf := range statusFiles { - wsDir := core.PathDir(sf) - wsName := WorkspaceName(wsDir) - result := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(sf) + wsName := WorkspaceName(workspaceDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { continue @@ -39,7 +39,7 @@ func (s *PrepSubsystem) cmdWorkspaceList(_ core.Options) core.Result { } func (s *PrepSubsystem) cmdWorkspaceClean(options core.Options) core.Result { - wsRoot := WorkspaceRoot() + workspaceRoot := WorkspaceRoot() fsys := s.Core().Fs() filter := options.String("_arg") if filter == "" { @@ -50,9 +50,9 @@ func (s *PrepSubsystem) cmdWorkspaceClean(options core.Options) core.Result { var toRemove []string for _, sf := range statusFiles { - wsDir := core.PathDir(sf) - wsName := WorkspaceName(wsDir) - result := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(sf) + wsName := WorkspaceName(workspaceDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { continue @@ -85,7 +85,7 @@ func (s *PrepSubsystem) cmdWorkspaceClean(options core.Options) core.Result { } for _, name := range toRemove { - path := core.JoinPath(wsRoot, name) + path := core.JoinPath(workspaceRoot, name) fsys.DeleteAll(path) core.Print(nil, " removed %s", name) } diff --git a/pkg/agentic/deps.go b/pkg/agentic/deps.go index 035c70d..df31142 100644 --- a/pkg/agentic/deps.go +++ b/pkg/agentic/deps.go @@ -17,8 +17,8 @@ import ( // After this, the workspace go.work includes ./repo and all ./dep-* dirs, // giving the agent everything needed to build and test. // -// s.cloneWorkspaceDeps(ctx, wsDir, repoDir, "core") -func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, wsDir, repoDir, org string) { +// s.cloneWorkspaceDeps(ctx, workspaceDir, repoDir, "core") +func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, workspaceDir, repoDir, org string) { goModPath := core.JoinPath(repoDir, "go.mod") r := fs.Read(goModPath) if !r.OK { @@ -48,14 +48,14 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, wsDir, repoDir, // Clone each dependency var cloned []string for _, dep := range deps { - depDir := core.JoinPath(wsDir, dep.dir) + depDir := core.JoinPath(workspaceDir, dep.dir) if fs.IsDir(core.JoinPath(depDir, ".git")) { cloned = append(cloned, dep.dir) // already cloned (resume) continue } repoURL := forgeSSHURL(org, dep.repo) - if result := process.RunIn(ctx, wsDir, "git", "clone", "--depth=1", repoURL, dep.dir); result.OK { + if result := process.RunIn(ctx, workspaceDir, "git", "clone", "--depth=1", repoURL, dep.dir); result.OK { cloned = append(cloned, dep.dir) } } @@ -69,7 +69,7 @@ func (s *PrepSubsystem) cloneWorkspaceDeps(ctx context.Context, wsDir, repoDir, b.WriteString(core.Concat("\t./", dir, "\n")) } b.WriteString(")\n") - fs.Write(core.JoinPath(wsDir, "go.work"), b.String()) + fs.Write(core.JoinPath(workspaceDir, "go.work"), b.String()) } } diff --git a/pkg/agentic/dispatch.go b/pkg/agentic/dispatch.go index f7bb38b..c8a54ba 100644 --- a/pkg/agentic/dispatch.go +++ b/pkg/agentic/dispatch.go @@ -233,9 +233,9 @@ func containerCommand(agentType, command string, args []string, repoDir, metaDir // --- spawnAgent: decomposed into testable steps --- // agentOutputFile returns the log file path for an agent's output. -func agentOutputFile(wsDir, agent string) string { +func agentOutputFile(workspaceDir, agent string) string { agentBase := core.SplitN(agent, ":", 2)[0] - return core.JoinPath(WorkspaceMetaDir(wsDir), core.Sprintf("agent-%s.log", agentBase)) + return core.JoinPath(WorkspaceMetaDir(workspaceDir), core.Sprintf("agent-%s.log", agentBase)) } // detectFinalStatus reads workspace state after agent exit to determine outcome. @@ -278,11 +278,11 @@ func (s *PrepSubsystem) trackFailureRate(agent, status string, startedAt time.Ti } // startIssueTracking starts a Forge stopwatch on the workspace's issue. -func (s *PrepSubsystem) startIssueTracking(wsDir string) { +func (s *PrepSubsystem) startIssueTracking(workspaceDir string) { if s.forge == nil { return } - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok || workspaceStatus.Issue == 0 { return @@ -295,11 +295,11 @@ func (s *PrepSubsystem) startIssueTracking(wsDir string) { } // stopIssueTracking stops a Forge stopwatch on the workspace's issue. -func (s *PrepSubsystem) stopIssueTracking(wsDir string) { +func (s *PrepSubsystem) stopIssueTracking(workspaceDir string) { if s.forge == nil { return } - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok || workspaceStatus.Issue == 0 { return @@ -312,9 +312,9 @@ func (s *PrepSubsystem) stopIssueTracking(wsDir string) { } // broadcastStart emits IPC + audit events for agent start. -func (s *PrepSubsystem) broadcastStart(agent, wsDir string) { - wsName := WorkspaceName(wsDir) - result := ReadStatusResult(wsDir) +func (s *PrepSubsystem) broadcastStart(agent, workspaceDir string) { + wsName := WorkspaceName(workspaceDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) repo := "" if ok { @@ -329,11 +329,11 @@ func (s *PrepSubsystem) broadcastStart(agent, wsDir string) { } // broadcastComplete emits IPC + audit events for agent completion. -func (s *PrepSubsystem) broadcastComplete(agent, wsDir, finalStatus string) { - wsName := WorkspaceName(wsDir) +func (s *PrepSubsystem) broadcastComplete(agent, workspaceDir, finalStatus string) { + wsName := WorkspaceName(workspaceDir) emitCompletionEvent(agent, wsName, finalStatus) if s.ServiceRuntime != nil { - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) repo := "" if ok { @@ -348,34 +348,34 @@ func (s *PrepSubsystem) broadcastComplete(agent, wsDir, finalStatus string) { // onAgentComplete handles all post-completion logic for a spawned agent. // Called from the monitoring goroutine after the process exits. -func (s *PrepSubsystem) onAgentComplete(agent, wsDir, outputFile string, exitCode int, procStatus, output string) { +func (s *PrepSubsystem) onAgentComplete(agent, workspaceDir, outputFile string, exitCode int, procStatus, output string) { // Save output if output != "" { fs.Write(outputFile, output) } - repoDir := WorkspaceRepoDir(wsDir) + repoDir := WorkspaceRepoDir(workspaceDir) finalStatus, question := detectFinalStatus(repoDir, exitCode, procStatus) // Update workspace status (disk + registry) - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if ok { workspaceStatus.Status = finalStatus workspaceStatus.PID = 0 workspaceStatus.Question = question - writeStatusResult(wsDir, workspaceStatus) - s.TrackWorkspace(WorkspaceName(wsDir), workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) + s.TrackWorkspace(WorkspaceName(workspaceDir), workspaceStatus) // Rate-limit tracking s.trackFailureRate(agent, finalStatus, workspaceStatus.StartedAt) } // Forge time tracking - s.stopIssueTracking(wsDir) + s.stopIssueTracking(workspaceDir) // Broadcast completion - s.broadcastComplete(agent, wsDir, finalStatus) + s.broadcastComplete(agent, workspaceDir, finalStatus) // Run completion pipeline via PerformAsync for successful agents. // Gets ActionTaskStarted/Completed broadcasts + WaitGroup integration for graceful shutdown. @@ -383,7 +383,7 @@ func (s *PrepSubsystem) onAgentComplete(agent, wsDir, outputFile string, exitCod // c.PerformAsync("agentic.complete", options) → runs agent.completion Task in background if finalStatus == "completed" && s.ServiceRuntime != nil { s.Core().PerformAsync("agentic.complete", core.NewOptions( - core.Option{Key: "workspace", Value: wsDir}, + core.Option{Key: "workspace", Value: workspaceDir}, )) } } @@ -391,18 +391,18 @@ func (s *PrepSubsystem) onAgentComplete(agent, wsDir, outputFile string, exitCod // spawnAgent launches an agent inside a Docker container. // The repo/ directory is mounted at /workspace, agent runs sandboxed. // Output is captured and written to .meta/agent-{agent}.log on completion. -func (s *PrepSubsystem) spawnAgent(agent, prompt, wsDir string) (int, string, string, error) { +func (s *PrepSubsystem) spawnAgent(agent, prompt, workspaceDir string) (int, string, string, error) { command, args, err := agentCommand(agent, prompt) if err != nil { return 0, "", "", err } - repoDir := WorkspaceRepoDir(wsDir) - metaDir := WorkspaceMetaDir(wsDir) - outputFile := agentOutputFile(wsDir, agent) + repoDir := WorkspaceRepoDir(workspaceDir) + metaDir := WorkspaceMetaDir(workspaceDir) + outputFile := agentOutputFile(workspaceDir, agent) // Clean up stale BLOCKED.md from previous runs - fs.Delete(WorkspaceBlockedPath(wsDir)) + fs.Delete(WorkspaceBlockedPath(workspaceDir)) // All agents run containerised agentBase := core.SplitN(agent, ":", 2)[0] @@ -426,16 +426,16 @@ func (s *PrepSubsystem) spawnAgent(agent, prompt, wsDir string) (int, string, st pid := proc.Info().PID processID := proc.ID - s.broadcastStart(agent, wsDir) - s.startIssueTracking(wsDir) + s.broadcastStart(agent, workspaceDir) + s.startIssueTracking(workspaceDir) // Register a one-shot Action that monitors this agent, then run it via PerformAsync. // PerformAsync tracks it in Core's WaitGroup — ServiceShutdown waits for it. - monitorAction := core.Concat("agentic.monitor.", core.Replace(WorkspaceName(wsDir), "/", ".")) + monitorAction := core.Concat("agentic.monitor.", core.Replace(WorkspaceName(workspaceDir), "/", ".")) monitor := &agentCompletionMonitor{ service: s, agent: agent, - workspaceDir: wsDir, + workspaceDir: workspaceDir, outputFile: outputFile, process: proc, } @@ -453,7 +453,7 @@ type completionProcess interface { // agentCompletionMonitor waits for a spawned process to finish, then finalises the workspace. // -// monitor := &agentCompletionMonitor{service: s, agent: "codex", workspaceDir: wsDir, outputFile: outputFile, process: proc} +// monitor := &agentCompletionMonitor{service: s, agent: "codex", workspaceDir: workspaceDir, outputFile: outputFile, process: proc} // s.Core().Action("agentic.monitor.core.go-io.task-5", monitor.run) type agentCompletionMonitor struct { service *PrepSubsystem @@ -479,9 +479,9 @@ func (m *agentCompletionMonitor) run(_ context.Context, _ core.Options) core.Res // runQA runs build + test checks on the repo after agent completion. // Returns true if QA passes, false if build or tests fail. -func (s *PrepSubsystem) runQA(wsDir string) bool { +func (s *PrepSubsystem) runQA(workspaceDir string) bool { ctx := context.Background() - repoDir := WorkspaceRepoDir(wsDir) + repoDir := WorkspaceRepoDir(workspaceDir) process := s.Core().Process() if fs.IsFile(core.JoinPath(repoDir, "go.mod")) { @@ -552,7 +552,7 @@ func (s *PrepSubsystem) dispatch(ctx context.Context, req *mcp.CallToolRequest, return nil, DispatchOutput{}, core.E("dispatch", "prep workspace failed", err) } - wsDir := prepOut.WorkspaceDir + workspaceDir := prepOut.WorkspaceDir prompt := prepOut.Prompt if input.DryRun { @@ -560,7 +560,7 @@ func (s *PrepSubsystem) dispatch(ctx context.Context, req *mcp.CallToolRequest, Success: true, Agent: input.Agent, Repo: input.Repo, - WorkspaceDir: wsDir, + WorkspaceDir: workspaceDir, Prompt: prompt, }, nil } @@ -584,22 +584,22 @@ func (s *PrepSubsystem) dispatch(ctx context.Context, req *mcp.CallToolRequest, StartedAt: time.Now(), Runs: 0, } - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) if runnerSvc, ok := core.ServiceFor[workspaceTracker](s.Core(), "runner"); ok { - runnerSvc.TrackWorkspace(WorkspaceName(wsDir), workspaceStatus) + runnerSvc.TrackWorkspace(WorkspaceName(workspaceDir), workspaceStatus) } return nil, DispatchOutput{ Success: true, Agent: input.Agent, Repo: input.Repo, - WorkspaceDir: wsDir, + WorkspaceDir: workspaceDir, OutputFile: "queued — at concurrency limit or frozen", }, nil } } // Step 3: Spawn agent in repo/ directory - pid, processID, outputFile, err := s.spawnAgent(input.Agent, prompt, wsDir) + pid, processID, outputFile, err := s.spawnAgent(input.Agent, prompt, workspaceDir) if err != nil { return nil, DispatchOutput{}, err } @@ -616,11 +616,11 @@ func (s *PrepSubsystem) dispatch(ctx context.Context, req *mcp.CallToolRequest, StartedAt: time.Now(), Runs: 1, } - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) // Track in runner's registry (runner owns workspace state) if s.ServiceRuntime != nil { if runnerSvc, ok := core.ServiceFor[workspaceTracker](s.Core(), "runner"); ok { - runnerSvc.TrackWorkspace(WorkspaceName(wsDir), workspaceStatus) + runnerSvc.TrackWorkspace(WorkspaceName(workspaceDir), workspaceStatus) } } @@ -628,7 +628,7 @@ func (s *PrepSubsystem) dispatch(ctx context.Context, req *mcp.CallToolRequest, Success: true, Agent: input.Agent, Repo: input.Repo, - WorkspaceDir: wsDir, + WorkspaceDir: workspaceDir, PID: pid, OutputFile: outputFile, }, nil diff --git a/pkg/agentic/dispatch_sync.go b/pkg/agentic/dispatch_sync.go index 1a96f98..0e9ae19 100644 --- a/pkg/agentic/dispatch_sync.go +++ b/pkg/agentic/dispatch_sync.go @@ -56,14 +56,14 @@ func (s *PrepSubsystem) DispatchSync(ctx context.Context, input DispatchSyncInpu return DispatchSyncResult{Err: core.E("agentic.DispatchSync", "prep failed", nil)} } - wsDir := prepOut.WorkspaceDir + workspaceDir := prepOut.WorkspaceDir prompt := prepOut.Prompt - core.Print(nil, " workspace: %s", wsDir) + core.Print(nil, " workspace: %s", workspaceDir) core.Print(nil, " branch: %s", prepOut.Branch) // Spawn agent directly — no queue, no concurrency check - pid, processID, _, err := s.spawnAgent(input.Agent, prompt, wsDir) + pid, processID, _, err := s.spawnAgent(input.Agent, prompt, workspaceDir) if err != nil { return DispatchSyncResult{Err: core.E("agentic.DispatchSync", "spawn agent failed", err)} } @@ -87,7 +87,7 @@ func (s *PrepSubsystem) DispatchSync(ctx context.Context, input DispatchSyncInpu case <-ticker.C: if pid > 0 && !ProcessAlive(runtime, processID, pid) { // Process exited — read final status - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) st, ok := workspaceStatusValue(result) if !ok { err, _ := result.Value.(error) diff --git a/pkg/agentic/handlers.go b/pkg/agentic/handlers.go index 51a6660..9d0c7de 100644 --- a/pkg/agentic/handlers.go +++ b/pkg/agentic/handlers.go @@ -21,33 +21,33 @@ func (s *PrepSubsystem) HandleIPCEvents(c *core.Core, msg core.Message) core.Res case messages.AgentCompleted: // Ingest findings (feature-flag gated) if c.Config().Enabled("auto-ingest") { - if wsDir := resolveWorkspace(ev.Workspace); wsDir != "" { - s.ingestFindings(wsDir) + if workspaceDir := resolveWorkspace(ev.Workspace); workspaceDir != "" { + s.ingestFindings(workspaceDir) } } case messages.SpawnQueued: // Runner asks agentic to spawn a queued workspace - wsDir := resolveWorkspace(ev.Workspace) - if wsDir == "" { + workspaceDir := resolveWorkspace(ev.Workspace) + if workspaceDir == "" { break } prompt := core.Concat("TASK: ", ev.Task, "\n\nResume from where you left off. Read CODEX.md for conventions. Commit when done.") - pid, processID, outputFile, err := s.spawnAgent(ev.Agent, prompt, wsDir) + pid, processID, outputFile, err := s.spawnAgent(ev.Agent, prompt, workspaceDir) if err != nil { break } // Update status with real PID - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatus, ok := workspaceStatusValue(result) if !ok { break } workspaceStatus.PID = pid workspaceStatus.ProcessID = processID - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) if runnerSvc, ok := core.ServiceFor[workspaceTracker](c, "runner"); ok { - runnerSvc.TrackWorkspace(WorkspaceName(wsDir), workspaceStatus) + runnerSvc.TrackWorkspace(WorkspaceName(workspaceDir), workspaceStatus) } } _ = outputFile @@ -59,10 +59,10 @@ func (s *PrepSubsystem) HandleIPCEvents(c *core.Core, msg core.Message) core.Res // SpawnFromQueue spawns an agent in a pre-prepped workspace. // Called by runner.Service via ServiceFor interface matching. // -// spawnResult := prep.SpawnFromQueue("codex", prompt, wsDir) +// spawnResult := prep.SpawnFromQueue("codex", prompt, workspaceDir) // pid := spawnResult.Value.(int) -func (s *PrepSubsystem) SpawnFromQueue(agent, prompt, wsDir string) core.Result { - pid, _, _, err := s.spawnAgent(agent, prompt, wsDir) +func (s *PrepSubsystem) SpawnFromQueue(agent, prompt, workspaceDir string) core.Result { + pid, _, _, err := s.spawnAgent(agent, prompt, workspaceDir) if err != nil { return core.Result{ Value: core.E("agentic.SpawnFromQueue", "failed to spawn queued agent", err), @@ -75,8 +75,8 @@ func (s *PrepSubsystem) SpawnFromQueue(agent, prompt, wsDir string) core.Result // // resolveWorkspace("core/go-io/task-5") → "/Users/snider/Code/.core/workspace/core/go-io/task-5" func resolveWorkspace(name string) string { - wsRoot := WorkspaceRoot() - path := core.JoinPath(wsRoot, name) + workspaceRoot := WorkspaceRoot() + path := core.JoinPath(workspaceRoot, name) if fs.IsDir(path) { return path } @@ -87,14 +87,14 @@ func resolveWorkspace(name string) string { // Scans running/completed workspaces for a matching repo+branch combination. func findWorkspaceByPR(repo, branch string) string { for _, path := range WorkspaceStatusPaths() { - wsDir := core.PathDir(path) - statusResult := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(path) + statusResult := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(statusResult) if !ok { continue } if workspaceStatus.Repo == repo && workspaceStatus.Branch == branch { - return wsDir + return workspaceDir } } return "" diff --git a/pkg/agentic/ingest.go b/pkg/agentic/ingest.go index 9cccd73..55630e6 100644 --- a/pkg/agentic/ingest.go +++ b/pkg/agentic/ingest.go @@ -8,14 +8,14 @@ import ( core "dappco.re/go/core" ) -func (s *PrepSubsystem) ingestFindings(wsDir string) { - statusResult := ReadStatusResult(wsDir) +func (s *PrepSubsystem) ingestFindings(workspaceDir string) { + statusResult := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(statusResult) if !ok || workspaceStatus.Status != "completed" { return } - logFiles := workspaceLogFiles(wsDir) + logFiles := workspaceLogFiles(workspaceDir) if len(logFiles) == 0 { return } diff --git a/pkg/agentic/paths.go b/pkg/agentic/paths.go index cc0cd20..fdba902 100644 --- a/pkg/agentic/paths.go +++ b/pkg/agentic/paths.go @@ -26,7 +26,7 @@ func LocalFs() *core.Fs { return fs } // WorkspaceRoot returns the root directory for agent workspaces. // Checks CORE_WORKSPACE env var first, falls back to HomeDir()/Code/.core/workspace. // -// wsDir := core.JoinPath(agentic.WorkspaceRoot(), "core", "go-io", "task-42") +// workspaceDir := core.JoinPath(agentic.WorkspaceRoot(), "core", "go-io", "task-42") func WorkspaceRoot() string { return core.JoinPath(CoreRoot(), "workspace") } @@ -41,20 +41,20 @@ func WorkspaceStatusPaths() []string { // WorkspaceStatusPath returns the status file for a workspace directory. // // path := agentic.WorkspaceStatusPath("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceStatusPath(wsDir string) string { - return core.JoinPath(wsDir, "status.json") +func WorkspaceStatusPath(workspaceDir string) string { + return core.JoinPath(workspaceDir, "status.json") } // WorkspaceName extracts the unique workspace name from a full path. // Given /Users/snider/Code/.core/workspace/core/go-io/dev → core/go-io/dev // // name := agentic.WorkspaceName("/Users/snider/Code/.core/workspace/core/go-io/dev") -func WorkspaceName(wsDir string) string { +func WorkspaceName(workspaceDir string) string { root := WorkspaceRoot() - name := core.TrimPrefix(wsDir, root) + name := core.TrimPrefix(workspaceDir, root) name = core.TrimPrefix(name, "/") if name == "" { - return core.PathBase(wsDir) + return core.PathBase(workspaceDir) } return name } @@ -83,8 +83,8 @@ func HomeDir() string { return core.Env("DIR_HOME") } -func workspaceStatusPaths(wsRoot string) []string { - if wsRoot == "" { +func workspaceStatusPaths(workspaceRoot string) []string { + if workspaceRoot == "" { return nil } @@ -122,7 +122,7 @@ func workspaceStatusPaths(wsRoot string) []string { } } - walk(wsRoot, 0) + walk(workspaceRoot, 0) sort.Strings(paths) return paths } @@ -130,56 +130,56 @@ func workspaceStatusPaths(wsRoot string) []string { // WorkspaceRepoDir returns the checked-out repo directory for a workspace. // // repoDir := agentic.WorkspaceRepoDir("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceRepoDir(wsDir string) string { - return core.JoinPath(wsDir, "repo") +func WorkspaceRepoDir(workspaceDir string) string { + return core.JoinPath(workspaceDir, "repo") } -func workspaceRepoDir(wsDir string) string { - return WorkspaceRepoDir(wsDir) +func workspaceRepoDir(workspaceDir string) string { + return WorkspaceRepoDir(workspaceDir) } // WorkspaceMetaDir returns the metadata directory for a workspace. // // metaDir := agentic.WorkspaceMetaDir("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceMetaDir(wsDir string) string { - return core.JoinPath(wsDir, ".meta") +func WorkspaceMetaDir(workspaceDir string) string { + return core.JoinPath(workspaceDir, ".meta") } -func workspaceMetaDir(wsDir string) string { - return WorkspaceMetaDir(wsDir) +func workspaceMetaDir(workspaceDir string) string { + return WorkspaceMetaDir(workspaceDir) } // WorkspaceBlockedPath returns the BLOCKED.md path for a workspace. // // blocked := agentic.WorkspaceBlockedPath("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceBlockedPath(wsDir string) string { - return core.JoinPath(WorkspaceRepoDir(wsDir), "BLOCKED.md") +func WorkspaceBlockedPath(workspaceDir string) string { + return core.JoinPath(WorkspaceRepoDir(workspaceDir), "BLOCKED.md") } -func workspaceBlockedPath(wsDir string) string { - return WorkspaceBlockedPath(wsDir) +func workspaceBlockedPath(workspaceDir string) string { + return WorkspaceBlockedPath(workspaceDir) } // WorkspaceAnswerPath returns the ANSWER.md path for a workspace. // // answer := agentic.WorkspaceAnswerPath("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceAnswerPath(wsDir string) string { - return core.JoinPath(WorkspaceRepoDir(wsDir), "ANSWER.md") +func WorkspaceAnswerPath(workspaceDir string) string { + return core.JoinPath(WorkspaceRepoDir(workspaceDir), "ANSWER.md") } -func workspaceAnswerPath(wsDir string) string { - return WorkspaceAnswerPath(wsDir) +func workspaceAnswerPath(workspaceDir string) string { + return WorkspaceAnswerPath(workspaceDir) } // WorkspaceLogFiles returns captured agent log files for a workspace. // // logs := agentic.WorkspaceLogFiles("/srv/.core/workspace/core/go-io/task-5") -func WorkspaceLogFiles(wsDir string) []string { - return core.PathGlob(core.JoinPath(WorkspaceMetaDir(wsDir), "agent-*.log")) +func WorkspaceLogFiles(workspaceDir string) []string { + return core.PathGlob(core.JoinPath(WorkspaceMetaDir(workspaceDir), "agent-*.log")) } -func workspaceLogFiles(wsDir string) []string { - return WorkspaceLogFiles(wsDir) +func workspaceLogFiles(workspaceDir string) []string { + return WorkspaceLogFiles(workspaceDir) } // PlansRoot returns the root directory for agent plans. diff --git a/pkg/agentic/pr.go b/pkg/agentic/pr.go index 3f23fb6..1a3d895 100644 --- a/pkg/agentic/pr.go +++ b/pkg/agentic/pr.go @@ -51,15 +51,15 @@ func (s *PrepSubsystem) createPR(ctx context.Context, _ *mcp.CallToolRequest, in return nil, CreatePROutput{}, core.E("createPR", "no Forge token configured", nil) } - wsDir := core.JoinPath(WorkspaceRoot(), input.Workspace) - repoDir := WorkspaceRepoDir(wsDir) + workspaceDir := core.JoinPath(WorkspaceRoot(), input.Workspace) + repoDir := WorkspaceRepoDir(workspaceDir) if !fs.IsDir(core.JoinPath(repoDir, ".git")) { return nil, CreatePROutput{}, core.E("createPR", core.Concat("workspace not found: ", input.Workspace), nil) } // Read workspace status for repo, branch, issue context - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { err, _ := result.Value.(error) @@ -126,7 +126,7 @@ func (s *PrepSubsystem) createPR(ctx context.Context, _ *mcp.CallToolRequest, in // Update status with PR URL workspaceStatus.PRURL = prURL - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) // Comment on issue if tracked if workspaceStatus.Issue > 0 { diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index 9366e95..066e8f5 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -234,13 +234,13 @@ func (s *PrepSubsystem) hydrateWorkspaces() { s.workspaces = core.NewRegistry[*WorkspaceStatus]() } for _, path := range WorkspaceStatusPaths() { - wsDir := core.PathDir(path) - result := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(path) + result := ReadStatusResult(workspaceDir) st, ok := workspaceStatusValue(result) if !ok { continue } - s.workspaces.Set(WorkspaceName(wsDir), st) + s.workspaces.Set(WorkspaceName(workspaceDir), st) } } @@ -362,17 +362,17 @@ func workspaceDir(org, repo string, input PrepInput) (string, error) { } return "", err } - wsDir, ok := r.Value.(string) - if !ok || wsDir == "" { + workspaceDir, ok := r.Value.(string) + if !ok || workspaceDir == "" { return "", core.E("workspaceDir", "invalid workspace directory result", nil) } - return wsDir, nil + return workspaceDir, nil } // workspaceDirResult resolves the workspace path and returns core.Result. // // r := workspaceDirResult("core", "go-io", PrepInput{Issue: 15}) -// if r.OK { wsDir := r.Value.(string) } +// if r.OK { workspaceDir := r.Value.(string) } func workspaceDirResult(org, repo string, input PrepInput) core.Result { orgName := core.ValidateName(org) if !orgName.OK { @@ -421,14 +421,14 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques } return nil, PrepOutput{}, err } - wsDir, ok := wsDirResult.Value.(string) - if !ok || wsDir == "" { + workspaceDir, ok := wsDirResult.Value.(string) + if !ok || workspaceDir == "" { return nil, PrepOutput{}, core.E("prepWorkspace", "invalid workspace path", nil) } - repoDir := workspaceRepoDir(wsDir) - metaDir := workspaceMetaDir(wsDir) - out := PrepOutput{WorkspaceDir: wsDir, RepoDir: repoDir} + repoDir := workspaceRepoDir(workspaceDir) + metaDir := workspaceMetaDir(workspaceDir) + out := PrepOutput{WorkspaceDir: workspaceDir, RepoDir: repoDir} // Source repo path — org and repo were validated by workspaceDirResult. repoPath := core.JoinPath(s.codePath, input.Org, input.Repo) @@ -467,7 +467,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques } // Extract default workspace template (go.work etc.) - if result := lib.ExtractWorkspace("default", wsDir, &lib.WorkspaceData{ + if result := lib.ExtractWorkspace("default", workspaceDir, &lib.WorkspaceData{ Repo: input.Repo, Branch: "", Task: input.Task, @@ -515,7 +515,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques lang := detectLanguage(repoPath) if lang == "php" { if r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl"); r.OK { - codexPath := core.JoinPath(wsDir, "CODEX.md") + codexPath := core.JoinPath(workspaceDir, "CODEX.md") fs.Write(codexPath, r.Value.(string)) } } @@ -523,11 +523,11 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques // Clone workspace dependencies — Core modules needed to build the repo. // Reads go.mod, finds dappco.re/go/core/* imports, clones from Forge, // and updates go.work so the agent can build inside the workspace. - s.cloneWorkspaceDeps(ctx, wsDir, repoDir, input.Org) + s.cloneWorkspaceDeps(ctx, workspaceDir, repoDir, input.Org) // Clone ecosystem docs into .core/reference/ so agents have full documentation. // The docs site (core.help) has architecture guides, specs, and API references. - docsDir := core.JoinPath(wsDir, ".core", "reference", "docs") + docsDir := core.JoinPath(workspaceDir, ".core", "reference", "docs") if !fs.IsDir(docsDir) { docsRepo := core.JoinPath(s.codePath, input.Org, "docs") if fs.IsDir(core.JoinPath(docsRepo, ".git")) { @@ -537,7 +537,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques // Copy RFC specs from plans repo into workspace specs/ folder. // Maps repo name to plans directory: go-io → core/go/io/, go-process → core/go/process/, etc. - s.copyRepoSpecs(wsDir, input.Repo) + s.copyRepoSpecs(workspaceDir, input.Repo) // Build the rich prompt with all context out.Prompt, out.Memories, out.Consumers = s.buildPrompt(ctx, input, out.Branch, repoPath) @@ -554,7 +554,7 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques // // s.copyRepoSpecs("/tmp/ws", "go-io") // copies plans/core/go/io/**/RFC*.md → /tmp/ws/specs/ // s.copyRepoSpecs("/tmp/ws", "core-bio") // copies plans/core/php/bio/**/RFC*.md → /tmp/ws/specs/ -func (s *PrepSubsystem) copyRepoSpecs(wsDir, repo string) { +func (s *PrepSubsystem) copyRepoSpecs(workspaceDir, repo string) { fs := (&core.Fs{}).NewUnrestricted() // Plans repo base — look for it relative to codePath @@ -587,7 +587,7 @@ func (s *PrepSubsystem) copyRepoSpecs(wsDir, repo string) { // Glob RFC*.md at each depth level (root, 1 deep, 2 deep, 3 deep). // Preserves subdirectory structure: specDir/pkg/sub/RFC.md → specs/pkg/sub/RFC.md - specsDir := core.JoinPath(wsDir, "specs") + specsDir := core.JoinPath(workspaceDir, "specs") fs.EnsureDir(specsDir) patterns := []string{ diff --git a/pkg/agentic/queue.go b/pkg/agentic/queue.go index 015603d..36fc74e 100644 --- a/pkg/agentic/queue.go +++ b/pkg/agentic/queue.go @@ -327,8 +327,8 @@ func (s *PrepSubsystem) drainQueue() { // Returns true if a task was spawned, false if nothing to do. func (s *PrepSubsystem) drainOne() bool { for _, statusPath := range WorkspaceStatusPaths() { - wsDir := core.PathDir(statusPath) - result := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(statusPath) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok || workspaceStatus.Status != "queued" { continue @@ -357,7 +357,7 @@ func (s *PrepSubsystem) drainOne() bool { prompt := core.Concat("TASK: ", workspaceStatus.Task, "\n\nResume from where you left off. Read CODEX.md for conventions. Commit when done.") - pid, processID, _, err := s.spawnAgent(workspaceStatus.Agent, prompt, wsDir) + pid, processID, _, err := s.spawnAgent(workspaceStatus.Agent, prompt, workspaceDir) if err != nil { continue } @@ -366,8 +366,8 @@ func (s *PrepSubsystem) drainOne() bool { workspaceStatus.PID = pid workspaceStatus.ProcessID = processID workspaceStatus.Runs++ - writeStatusResult(wsDir, workspaceStatus) - s.TrackWorkspace(WorkspaceName(wsDir), workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) + s.TrackWorkspace(WorkspaceName(workspaceDir), workspaceStatus) return true } diff --git a/pkg/agentic/resume.go b/pkg/agentic/resume.go index 8973f19..f95e2e0 100644 --- a/pkg/agentic/resume.go +++ b/pkg/agentic/resume.go @@ -43,8 +43,8 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu return nil, ResumeOutput{}, core.E("resume", "workspace is required", nil) } - wsDir := core.JoinPath(WorkspaceRoot(), input.Workspace) - repoDir := WorkspaceRepoDir(wsDir) + workspaceDir := core.JoinPath(WorkspaceRoot(), input.Workspace) + repoDir := WorkspaceRepoDir(workspaceDir) // Verify workspace exists if !fs.IsDir(core.JoinPath(repoDir, ".git")) { @@ -52,7 +52,7 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu } // Read current status - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { err, _ := result.Value.(error) @@ -71,7 +71,7 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu // Write ANSWER.md if answer provided if input.Answer != "" { - answerPath := workspaceAnswerPath(wsDir) + answerPath := workspaceAnswerPath(workspaceDir) content := core.Sprintf("# Answer\n\n%s\n", input.Answer) if writeResult := fs.Write(answerPath, content); !writeResult.OK { err, _ := writeResult.Value.(error) @@ -96,7 +96,7 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu } // Spawn agent via go-process - pid, processID, _, err := s.spawnAgent(agent, prompt, wsDir) + pid, processID, _, err := s.spawnAgent(agent, prompt, workspaceDir) if err != nil { return nil, ResumeOutput{}, err } @@ -107,13 +107,13 @@ func (s *PrepSubsystem) resume(ctx context.Context, _ *mcp.CallToolRequest, inpu workspaceStatus.ProcessID = processID workspaceStatus.Runs++ workspaceStatus.Question = "" - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) return nil, ResumeOutput{ Success: true, Workspace: input.Workspace, Agent: agent, PID: pid, - OutputFile: agentOutputFile(wsDir, agent), + OutputFile: agentOutputFile(workspaceDir, agent), }, nil } diff --git a/pkg/agentic/status.go b/pkg/agentic/status.go index 7f9cfe4..e5fe796 100644 --- a/pkg/agentic/status.go +++ b/pkg/agentic/status.go @@ -26,8 +26,8 @@ import ( // WorkspaceStatus represents the current state of an agent workspace. // -// result := ReadStatusResult(wsDir) -// if result.OK && result.Value.(*WorkspaceStatus).Status == "completed" { autoCreatePR(wsDir) } +// result := ReadStatusResult(workspaceDir) +// if result.OK && result.Value.(*WorkspaceStatus).Status == "completed" { autoCreatePR(workspaceDir) } type WorkspaceStatus struct { Status string `json:"status"` // running, completed, blocked, failed Agent string `json:"agent"` // gemini, claude, codex @@ -56,8 +56,8 @@ type WorkspaceQuery struct { Status string // filter by status (empty = all) } -func writeStatus(wsDir string, status *WorkspaceStatus) error { - r := writeStatusResult(wsDir, status) +func writeStatus(workspaceDir string, status *WorkspaceStatus) error { + r := writeStatusResult(workspaceDir, status) if !r.OK { err, _ := r.Value.(error) if err == nil { @@ -72,12 +72,12 @@ func writeStatus(wsDir string, status *WorkspaceStatus) error { // // result := writeStatusResult("/srv/core/workspace/core/go-io/task-5", &WorkspaceStatus{Status: "running"}) // if result.OK { return } -func writeStatusResult(wsDir string, status *WorkspaceStatus) core.Result { +func writeStatusResult(workspaceDir string, status *WorkspaceStatus) core.Result { if status == nil { return core.Result{Value: core.E("writeStatus", "status is required", nil), OK: false} } status.UpdatedAt = time.Now() - statusPath := WorkspaceStatusPath(wsDir) + statusPath := WorkspaceStatusPath(workspaceDir) if r := fs.WriteAtomic(statusPath, core.JSONMarshalString(status)); !r.OK { err, _ := r.Value.(error) if err == nil { @@ -94,14 +94,14 @@ func writeStatusResult(wsDir string, status *WorkspaceStatus) core.Result { // // result := ReadStatusResult("/path/to/workspace") // if result.OK { workspaceStatus := result.Value.(*WorkspaceStatus) } -func ReadStatusResult(wsDir string) core.Result { - r := fs.Read(WorkspaceStatusPath(wsDir)) +func ReadStatusResult(workspaceDir string) core.Result { + r := fs.Read(WorkspaceStatusPath(workspaceDir)) if !r.OK { err, _ := r.Value.(error) if err == nil { return core.Result{Value: core.E("ReadStatusResult", "status not found", nil), OK: false} } - return core.Result{Value: core.E("ReadStatusResult", core.Concat("status not found for ", wsDir), err), OK: false} + return core.Result{Value: core.E("ReadStatusResult", core.Concat("status not found for ", workspaceDir), err), OK: false} } var s WorkspaceStatus if parseResult := core.JSONUnmarshalString(r.Value.(string), &s); !parseResult.OK { @@ -177,10 +177,10 @@ func (s *PrepSubsystem) status(ctx context.Context, _ *mcp.CallToolRequest, inpu var out StatusOutput for _, statusPath := range statusFiles { - wsDir := core.PathDir(statusPath) - name := WorkspaceName(wsDir) + workspaceDir := core.PathDir(statusPath) + name := WorkspaceName(workspaceDir) - result := ReadStatusResult(wsDir) + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { out.Total++ @@ -191,19 +191,19 @@ func (s *PrepSubsystem) status(ctx context.Context, _ *mcp.CallToolRequest, inpu // If status is "running", check whether the managed process is still alive. if workspaceStatus.Status == "running" && (workspaceStatus.ProcessID != "" || workspaceStatus.PID > 0) { if !ProcessAlive(runtime, workspaceStatus.ProcessID, workspaceStatus.PID) { - blockedPath := workspaceBlockedPath(wsDir) + blockedPath := workspaceBlockedPath(workspaceDir) if r := fs.Read(blockedPath); r.OK { workspaceStatus.Status = "blocked" workspaceStatus.Question = core.Trim(r.Value.(string)) } else { - if len(workspaceLogFiles(wsDir)) == 0 { + if len(workspaceLogFiles(workspaceDir)) == 0 { workspaceStatus.Status = "failed" workspaceStatus.Question = "Agent process died (no output log)" } else { workspaceStatus.Status = "completed" } } - writeStatusResult(wsDir, workspaceStatus) + writeStatusResult(workspaceDir, workspaceStatus) } } diff --git a/pkg/agentic/verify.go b/pkg/agentic/verify.go index dcb45cb..43d404e 100644 --- a/pkg/agentic/verify.go +++ b/pkg/agentic/verify.go @@ -16,14 +16,14 @@ import ( // For deeper review (security, conventions), dispatch a separate task: // // agentic_dispatch repo=go-crypt template=verify persona=engineering/engineering-security-engineer -func (s *PrepSubsystem) autoVerifyAndMerge(wsDir string) { - result := ReadStatusResult(wsDir) +func (s *PrepSubsystem) autoVerifyAndMerge(workspaceDir string) { + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok || workspaceStatus.PRURL == "" || workspaceStatus.Repo == "" { return } - repoDir := WorkspaceRepoDir(wsDir) + repoDir := WorkspaceRepoDir(workspaceDir) org := workspaceStatus.Org if org == "" { org = "core" @@ -36,13 +36,13 @@ func (s *PrepSubsystem) autoVerifyAndMerge(wsDir string) { // markMerged is a helper to avoid repeating the status update. markMerged := func() { - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { st2, ok := workspaceStatusValue(result) if !ok { return } st2.Status = "merged" - writeStatusResult(wsDir, st2) + writeStatusResult(workspaceDir, st2) } } @@ -66,13 +66,13 @@ func (s *PrepSubsystem) autoVerifyAndMerge(wsDir string) { // Both attempts failed — flag for human review s.flagForReview(org, workspaceStatus.Repo, prNum, mergeOutcome) - if result := ReadStatusResult(wsDir); result.OK { + if result := ReadStatusResult(workspaceDir); result.OK { workspaceStatusUpdate, ok := workspaceStatusValue(result) if !ok { return } workspaceStatusUpdate.Question = "Flagged for review — auto-merge failed after retry" - writeStatusResult(wsDir, workspaceStatusUpdate) + writeStatusResult(workspaceDir, workspaceStatusUpdate) } } diff --git a/pkg/lib/lib.go b/pkg/lib/lib.go index a35e503..6612d41 100644 --- a/pkg/lib/lib.go +++ b/pkg/lib/lib.go @@ -269,30 +269,30 @@ type WorkspaceData struct { // Repo: "go-io", Task: "fix tests", Agent: "codex", // }) // core.Println(r.OK) -func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) core.Result { +func ExtractWorkspace(templateName, targetDir string, data *WorkspaceData) core.Result { if result := ensureMounted(); !result.OK { if err, ok := result.Value.(error); ok { return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", tmplName), err), + Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", templateName), err), OK: false, } } return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", tmplName), nil), + Value: core.E("lib.ExtractWorkspace", core.Concat("mount workspace template ", templateName), nil), OK: false, } } - r := workspaceFS.Sub(tmplName) + r := workspaceFS.Sub(templateName) if !r.OK { if err, ok := r.Value.(error); ok { return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", tmplName), err), + Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", templateName), err), OK: false, } } return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", tmplName), nil), + Value: core.E("lib.ExtractWorkspace", core.Concat("template not found: ", templateName), nil), OK: false, } } @@ -300,12 +300,12 @@ func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) core.Resu if !result.OK { if err, ok := result.Value.(error); ok { return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", tmplName), err), + Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", templateName), err), OK: false, } } return core.Result{ - Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", tmplName), nil), + Value: core.E("lib.ExtractWorkspace", core.Concat("extract workspace template ", templateName), nil), OK: false, } } @@ -317,11 +317,11 @@ func ExtractWorkspace(tmplName, targetDir string, data *WorkspaceData) core.Resu // // r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl") // if r.OK { content := r.Value.(string) } -func WorkspaceFile(tmplName, filename string) core.Result { +func WorkspaceFile(templateName, filename string) core.Result { if result := ensureMounted(); !result.OK { return result } - r := workspaceFS.Sub(tmplName) + r := workspaceFS.Sub(templateName) if !r.OK { return r } diff --git a/pkg/monitor/harvest.go b/pkg/monitor/harvest.go index 02be512..baedd81 100644 --- a/pkg/monitor/harvest.go +++ b/pkg/monitor/harvest.go @@ -32,8 +32,8 @@ func (m *Subsystem) harvestCompleted() string { var harvested []harvestResult for _, entry := range agentic.WorkspaceStatusPaths() { - wsDir := core.PathDir(entry) - result := m.harvestWorkspace(wsDir) + workspaceDir := core.PathDir(entry) + result := m.harvestWorkspace(workspaceDir) if result != nil { harvested = append(harvested, *result) } @@ -61,8 +61,8 @@ func (m *Subsystem) harvestCompleted() string { } // harvestWorkspace checks a single workspace and pushes if ready. -func (m *Subsystem) harvestWorkspace(wsDir string) *harvestResult { - statusResult := fs.Read(agentic.WorkspaceStatusPath(wsDir)) +func (m *Subsystem) harvestWorkspace(workspaceDir string) *harvestResult { + statusResult := fs.Read(agentic.WorkspaceStatusPath(workspaceDir)) if !statusResult.OK { return nil } @@ -85,7 +85,7 @@ func (m *Subsystem) harvestWorkspace(wsDir string) *harvestResult { return nil } - repoDir := agentic.WorkspaceRepoDir(wsDir) + repoDir := agentic.WorkspaceRepoDir(workspaceDir) if !fs.IsDir(repoDir) { return nil } @@ -108,7 +108,7 @@ func (m *Subsystem) harvestWorkspace(wsDir string) *harvestResult { // Safety checks before pushing if reason := m.checkSafety(repoDir); reason != "" { - updateStatus(wsDir, "rejected", reason) + updateStatus(workspaceDir, "rejected", reason) return &harvestResult{repo: workspaceStatus.Repo, branch: branch, rejected: reason} } @@ -118,7 +118,7 @@ func (m *Subsystem) harvestWorkspace(wsDir string) *harvestResult { // Mark ready for review — do NOT auto-push. // Pushing is a high-impact mutation that should happen during // explicit review (/review command), not silently in the background. - updateStatus(wsDir, "ready-for-review", "") + updateStatus(workspaceDir, "ready-for-review", "") return &harvestResult{repo: workspaceStatus.Repo, branch: branch, files: files} } @@ -247,9 +247,9 @@ func (m *Subsystem) pushBranch(srcDir, branch string) error { // updateStatus rewrites status.json after a harvest decision. // -// updateStatus(wsDir, "ready-for-review", "") -func updateStatus(wsDir, status, question string) { - statusResult := fs.Read(agentic.WorkspaceStatusPath(wsDir)) +// updateStatus(workspaceDir, "ready-for-review", "") +func updateStatus(workspaceDir, status, question string) { + statusResult := fs.Read(agentic.WorkspaceStatusPath(workspaceDir)) if !statusResult.OK { return } @@ -267,7 +267,7 @@ func updateStatus(wsDir, status, question string) { } else { delete(workspaceStatus, "question") // clear stale question from previous state } - statusPath := agentic.WorkspaceStatusPath(wsDir) + statusPath := agentic.WorkspaceStatusPath(workspaceDir) if writeResult := fs.WriteAtomic(statusPath, core.JSONMarshalString(workspaceStatus)); !writeResult.OK { if err, ok := writeResult.Value.(error); ok { core.Warn("monitor.updateStatus: failed to write status", "path", statusPath, "reason", err) diff --git a/pkg/monitor/monitor.go b/pkg/monitor/monitor.go index 945e89c..a2e26d3 100644 --- a/pkg/monitor/monitor.go +++ b/pkg/monitor/monitor.go @@ -19,7 +19,7 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// readResult := fs.Read(core.JoinPath(wsRoot, name, "status.json")) +// readResult := fs.Read(core.JoinPath(workspaceRoot, name, "status.json")) // if text, ok := resultString(readResult); ok { _ = core.JSONUnmarshalString(text, &workspaceStatus) } var fs = agentic.LocalFs() diff --git a/pkg/runner/paths.go b/pkg/runner/paths.go index 9252e5c..5d55f28 100644 --- a/pkg/runner/paths.go +++ b/pkg/runner/paths.go @@ -68,8 +68,8 @@ func CoreRoot() string { // // result := ReadStatusResult("/srv/core/workspace/core/go-io/task-5") // if result.OK { workspaceStatus := result.Value.(*WorkspaceStatus) } -func ReadStatusResult(wsDir string) core.Result { - statusResult := agentic.ReadStatusResult(wsDir) +func ReadStatusResult(workspaceDir string) core.Result { + statusResult := agentic.ReadStatusResult(workspaceDir) if !statusResult.OK { err, _ := statusResult.Value.(error) if err == nil { @@ -93,7 +93,7 @@ func ReadStatusResult(wsDir string) core.Result { // // result := runner.WriteStatus("/srv/core/workspace/core/go-io/task-5", &runner.WorkspaceStatus{Status: "running", Agent: "codex"}) // core.Println(result.OK) -func WriteStatus(wsDir string, status *WorkspaceStatus) core.Result { +func WriteStatus(workspaceDir string, status *WorkspaceStatus) core.Result { if status == nil { return core.Result{Value: core.E("runner.WriteStatus", "status is required", nil), OK: false} } @@ -103,7 +103,7 @@ func WriteStatus(wsDir string, status *WorkspaceStatus) core.Result { return core.Result{Value: core.E("runner.WriteStatus", "status conversion failed", nil), OK: false} } agenticStatus.UpdatedAt = time.Now() - if writeResult := fs.WriteAtomic(agentic.WorkspaceStatusPath(wsDir), core.JSONMarshalString(agenticStatus)); !writeResult.OK { + if writeResult := fs.WriteAtomic(agentic.WorkspaceStatusPath(workspaceDir), core.JSONMarshalString(agenticStatus)); !writeResult.OK { err, _ := writeResult.Value.(error) if err == nil { return core.Result{Value: core.E("runner.WriteStatus", "failed to write status", nil), OK: false} diff --git a/pkg/runner/queue.go b/pkg/runner/queue.go index cfb930a..c1106be 100644 --- a/pkg/runner/queue.go +++ b/pkg/runner/queue.go @@ -220,8 +220,8 @@ func (s *Service) drainQueue() { func (s *Service) drainOne() bool { for _, statusPath := range agentic.WorkspaceStatusPaths() { - wsDir := core.PathDir(statusPath) - statusResult := ReadStatusResult(wsDir) + workspaceDir := core.PathDir(statusPath) + statusResult := ReadStatusResult(workspaceDir) if !statusResult.OK { continue } @@ -251,7 +251,7 @@ func (s *Service) drainOne() bool { // Ask agentic to spawn — runner owns the gate, // agentic owns the actual process launch. // Workspace name is relative path from workspace root (e.g. "core/go-ai/dev") - wsName := agentic.WorkspaceName(wsDir) + wsName := agentic.WorkspaceName(workspaceDir) core.Info("drainOne: found queued workspace", "workspace", wsName, "agent", workspaceStatus.Agent) // Spawn directly — agentic is a Core service, use ServiceFor to get it @@ -259,7 +259,7 @@ func (s *Service) drainOne() bool { continue } type spawner interface { - SpawnFromQueue(agent, prompt, wsDir string) core.Result + SpawnFromQueue(agent, prompt, workspaceDir string) core.Result } agenticService, ok := core.ServiceFor[spawner](s.Core(), "agentic") if !ok { @@ -267,7 +267,7 @@ func (s *Service) drainOne() bool { continue } prompt := core.Concat("TASK: ", workspaceStatus.Task, "\n\nResume from where you left off. Read CODEX.md for conventions. Commit when done.") - spawnResult := agenticService.SpawnFromQueue(workspaceStatus.Agent, prompt, wsDir) + spawnResult := agenticService.SpawnFromQueue(workspaceStatus.Agent, prompt, workspaceDir) if !spawnResult.OK { core.Error("drainOne: spawn failed", "workspace", wsName, "reason", core.Sprint(spawnResult.Value)) continue @@ -282,7 +282,7 @@ func (s *Service) drainOne() bool { workspaceStatus.Status = "running" workspaceStatus.PID = pid workspaceStatus.Runs++ - if writeResult := WriteStatus(wsDir, workspaceStatus); !writeResult.OK { + if writeResult := WriteStatus(workspaceDir, workspaceStatus); !writeResult.OK { core.Error("drainOne: failed to write workspace status", "workspace", wsName, "reason", core.Sprint(writeResult.Value)) continue } diff --git a/pkg/setup/config.go b/pkg/setup/config.go index 72bd5fc..df7b4d3 100644 --- a/pkg/setup/config.go +++ b/pkg/setup/config.go @@ -52,19 +52,19 @@ type configValue struct { // // r := setup.GenerateBuildConfig("/srv/repos/agent", setup.TypeGo) // if r.OK { content := r.Value.(string) } -func GenerateBuildConfig(path string, projType ProjectType) core.Result { +func GenerateBuildConfig(path string, projectType ProjectType) core.Result { name := core.PathBase(path) sections := []configSection{ { Key: "project", Values: []configValue{ {Key: "name", Value: name}, - {Key: "type", Value: string(projType)}, + {Key: "type", Value: string(projectType)}, }, }, } - switch projType { + switch projectType { case TypeGo, TypeWails: sections = append(sections, configSection{ Key: "build", @@ -99,10 +99,10 @@ func GenerateBuildConfig(path string, projType ProjectType) core.Result { // // r := setup.GenerateTestConfig(setup.TypeGo) // if r.OK { content := r.Value.(string) } -func GenerateTestConfig(projType ProjectType) core.Result { +func GenerateTestConfig(projectType ProjectType) core.Result { var sections []configSection - switch projType { + switch projectType { case TypeGo, TypeWails: sections = []configSection{ { diff --git a/pkg/setup/detect.go b/pkg/setup/detect.go index c2b975e..a7b8060 100644 --- a/pkg/setup/detect.go +++ b/pkg/setup/detect.go @@ -11,8 +11,8 @@ import ( // ProjectType records what setup detected in a repository path. // -// projType := setup.Detect("/srv/repos/agent") -// if projType == setup.TypeGo { /* generate Go defaults */ } +// projectType := setup.Detect("/srv/repos/agent") +// if projectType == setup.TypeGo { /* generate Go defaults */ } type ProjectType string const ( @@ -28,12 +28,12 @@ var fs = (&core.Fs{}).NewUnrestricted() // Detect inspects a repository path and returns the primary project type. // -// projType := setup.Detect("./repo") +// projectType := setup.Detect("./repo") func Detect(path string) ProjectType { base := absolutePath(path) checks := []struct { - file string - projType ProjectType + file string + projectType ProjectType }{ {"wails.json", TypeWails}, {"go.mod", TypeGo}, @@ -42,7 +42,7 @@ func Detect(path string) ProjectType { } for _, candidate := range checks { if fs.IsFile(core.JoinPath(base, candidate.file)) { - return candidate.projType + return candidate.projectType } } return TypeUnknown @@ -55,8 +55,8 @@ func DetectAll(path string) []ProjectType { base := absolutePath(path) var projectTypes []ProjectType checks := []struct { - file string - projType ProjectType + file string + projectType ProjectType }{ {"go.mod", TypeGo}, {"composer.json", TypePHP}, @@ -65,7 +65,7 @@ func DetectAll(path string) []ProjectType { } for _, candidate := range checks { if fs.IsFile(core.JoinPath(base, candidate.file)) { - projectTypes = append(projectTypes, candidate.projType) + projectTypes = append(projectTypes, candidate.projectType) } } return projectTypes diff --git a/pkg/setup/setup.go b/pkg/setup/setup.go index d8d2be7..b87bf24 100644 --- a/pkg/setup/setup.go +++ b/pkg/setup/setup.go @@ -28,45 +28,45 @@ func (s *Service) Run(options Options) core.Result { } options.Path = absolutePath(options.Path) - projType := Detect(options.Path) + projectType := Detect(options.Path) allTypes := DetectAll(options.Path) core.Print(nil, "Project: %s", core.PathBase(options.Path)) - core.Print(nil, "Type: %s", projType) + core.Print(nil, "Type: %s", projectType) if len(allTypes) > 1 { core.Print(nil, "Also: %v (polyglot)", allTypes) } - var tmplName string + var templateName string if options.Template != "" { - templateResult := resolveTemplateName(options.Template, projType) + templateResult := resolveTemplateName(options.Template, projectType) if !templateResult.OK { return templateResult } - tmplName = templateResult.Value.(string) - if !templateExists(tmplName) { + templateName = templateResult.Value.(string) + if !templateExists(templateName) { return core.Result{ - Value: core.E("setup.Run", core.Concat("template not found: ", tmplName), nil), + Value: core.E("setup.Run", core.Concat("template not found: ", templateName), nil), OK: false, } } } // Generate .core/ config files - if result := setupCoreDir(options, projType); !result.OK { + if result := setupCoreDir(options, projectType); !result.OK { return result } // Scaffold from dir template if requested - if tmplName != "" { - return s.scaffoldTemplate(options, projType, tmplName) + if templateName != "" { + return s.scaffoldTemplate(options, projectType, templateName) } return core.Result{Value: options.Path, OK: true} } // setupCoreDir creates .core/ with build.yaml and test.yaml. -func setupCoreDir(options Options, projType ProjectType) core.Result { +func setupCoreDir(options Options, projectType ProjectType) core.Result { coreDir := core.JoinPath(options.Path, ".core") if options.DryRun { @@ -83,7 +83,7 @@ func setupCoreDir(options Options, projType ProjectType) core.Result { } // build.yaml - buildConfig := GenerateBuildConfig(options.Path, projType) + buildConfig := GenerateBuildConfig(options.Path, projectType) if !buildConfig.OK { err, _ := buildConfig.Value.(error) return core.Result{ @@ -96,7 +96,7 @@ func setupCoreDir(options Options, projType ProjectType) core.Result { } // test.yaml - testConfig := GenerateTestConfig(projType) + testConfig := GenerateTestConfig(projectType) if !testConfig.OK { err, _ := testConfig.Value.(error) return core.Result{ @@ -112,37 +112,37 @@ func setupCoreDir(options Options, projType ProjectType) core.Result { } // scaffoldTemplate extracts a dir template into the target path. -func (s *Service) scaffoldTemplate(options Options, projType ProjectType, tmplName string) core.Result { - core.Print(nil, "Template: %s", tmplName) +func (s *Service) scaffoldTemplate(options Options, projectType ProjectType, templateName string) core.Result { + core.Print(nil, "Template: %s", templateName) data := &lib.WorkspaceData{ Repo: core.PathBase(options.Path), Branch: "main", - Task: core.Sprintf("Initialise %s project tooling.", projType), + Task: core.Sprintf("Initialise %s project tooling.", projectType), Agent: "setup", - Language: string(projType), + Language: string(projectType), Prompt: "This workspace was scaffolded by pkg/setup. Review the repository and continue from the generated context files.", - Flow: formatFlow(projType), + Flow: formatFlow(projectType), RepoDescription: s.DetectGitRemote(options.Path), - BuildCmd: defaultBuildCommand(projType), - TestCmd: defaultTestCommand(projType), + BuildCmd: defaultBuildCommand(projectType), + TestCmd: defaultTestCommand(projectType), } if options.DryRun { - core.Print(nil, "Would extract workspace/%s to %s", tmplName, options.Path) - core.Print(nil, " Template found: %s", tmplName) + core.Print(nil, "Would extract workspace/%s to %s", templateName, options.Path) + core.Print(nil, " Template found: %s", templateName) return core.Result{Value: options.Path, OK: true} } - if result := lib.ExtractWorkspace(tmplName, options.Path, data); !result.OK { + if result := lib.ExtractWorkspace(templateName, options.Path, data); !result.OK { if err, ok := result.Value.(error); ok { return core.Result{ - Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", tmplName), err), + Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", templateName), err), OK: false, } } return core.Result{ - Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", tmplName), nil), + Value: core.E("setup.scaffoldTemplate", core.Concat("extract workspace template ", templateName), nil), OK: false, } } @@ -171,7 +171,7 @@ func writeConfig(path, content string, options Options) core.Result { return core.Result{Value: path, OK: true} } -func resolveTemplateName(name string, projType ProjectType) core.Result { +func resolveTemplateName(name string, projectType ProjectType) core.Result { if name == "" { return core.Result{ Value: core.E("setup.resolveTemplateName", "template is required", nil), @@ -180,7 +180,7 @@ func resolveTemplateName(name string, projType ProjectType) core.Result { } if name == "auto" { - switch projType { + switch projectType { case TypeGo, TypeWails, TypePHP, TypeNode, TypeUnknown: return core.Result{Value: "default", OK: true} } @@ -205,8 +205,8 @@ func templateExists(name string) bool { return false } -func defaultBuildCommand(projType ProjectType) string { - switch projType { +func defaultBuildCommand(projectType ProjectType) string { + switch projectType { case TypeGo, TypeWails: return "go build ./..." case TypePHP: @@ -218,8 +218,8 @@ func defaultBuildCommand(projType ProjectType) string { } } -func defaultTestCommand(projType ProjectType) string { - switch projType { +func defaultTestCommand(projectType ProjectType) string { + switch projectType { case TypeGo, TypeWails: return "go test ./..." case TypePHP: @@ -231,13 +231,13 @@ func defaultTestCommand(projType ProjectType) string { } } -func formatFlow(projType ProjectType) string { +func formatFlow(projectType ProjectType) string { builder := core.NewBuilder() builder.WriteString("- Build: `") - builder.WriteString(defaultBuildCommand(projType)) + builder.WriteString(defaultBuildCommand(projectType)) builder.WriteString("`\n") builder.WriteString("- Test: `") - builder.WriteString(defaultTestCommand(projType)) + builder.WriteString(defaultTestCommand(projectType)) builder.WriteString("`") return builder.String() }