From bd12c0a31aaedce0860edd5362f6cf7f78499085 Mon Sep 17 00:00:00 2001 From: Virgil Date: Mon, 30 Mar 2026 22:54:19 +0000 Subject: [PATCH] fix(ax): align code comments with AX principles Co-Authored-By: Virgil --- pkg/agentic/actions.go | 176 ++++++++++++++++------------------ pkg/agentic/auto_pr.go | 3 +- pkg/agentic/commands_forge.go | 8 +- pkg/agentic/deps.go | 13 +-- pkg/agentic/dispatch.go | 16 +--- pkg/agentic/epic.go | 20 ++-- pkg/agentic/mirror.go | 22 +---- pkg/agentic/paths.go | 76 ++++----------- pkg/agentic/pid.go | 6 +- pkg/agentic/plan.go | 60 +++--------- pkg/agentic/pr.go | 4 - pkg/agentic/prep.go | 12 --- pkg/agentic/queue.go | 17 +--- pkg/agentic/remote.go | 2 - pkg/agentic/remote_status.go | 2 - pkg/agentic/review_queue.go | 43 +++------ pkg/agentic/runner.go | 17 +--- pkg/agentic/status.go | 2 - pkg/agentic/transport.go | 76 ++++----------- pkg/brain/tools.go | 48 ++++------ pkg/lib/lib.go | 75 ++++----------- pkg/messages/messages.go | 8 -- pkg/monitor/harvest.go | 12 +-- pkg/runner/paths.go | 2 +- pkg/runner/queue.go | 44 +++------ pkg/runner/runner.go | 12 +-- 26 files changed, 239 insertions(+), 537 deletions(-) diff --git a/pkg/agentic/actions.go b/pkg/agentic/actions.go index 55f5a45..d1d2d37 100644 --- a/pkg/agentic/actions.go +++ b/pkg/agentic/actions.go @@ -17,14 +17,12 @@ import ( core "dappco.re/go/core" ) -// --- Dispatch & Workspace --- - -// handleDispatch dispatches a subagent to work on a repo task. +// result := c.Action("agentic.dispatch").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.dispatch").Run(ctx, core.NewOptions( -// core.Option{Key: "repo", Value: "go-io"}, -// core.Option{Key: "task", Value: "Fix tests"}, -// )) +// core.Option{Key: "repo", Value: "go-io"}, +// core.Option{Key: "task", Value: "Fix tests"}, +// +// )) func (s *PrepSubsystem) handleDispatch(ctx context.Context, options core.Options) core.Result { input := DispatchInput{ Repo: options.String("repo"), @@ -39,12 +37,12 @@ func (s *PrepSubsystem) handleDispatch(ctx context.Context, options core.Options return core.Result{Value: out, OK: true} } -// handlePrep prepares a workspace without dispatching an agent. +// result := c.Action("agentic.prep").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.prep").Run(ctx, core.NewOptions( -// core.Option{Key: "repo", Value: "go-io"}, -// core.Option{Key: "issue", Value: 42}, -// )) +// core.Option{Key: "repo", Value: "go-io"}, +// core.Option{Key: "issue", Value: 42}, +// +// )) func (s *PrepSubsystem) handlePrep(ctx context.Context, options core.Options) core.Result { input := PrepInput{ Repo: options.String("repo"), @@ -58,9 +56,7 @@ func (s *PrepSubsystem) handlePrep(ctx context.Context, options core.Options) co return core.Result{Value: out, OK: true} } -// handleStatus lists workspace statuses. -// -// result := c.Action("agentic.status").Run(ctx, core.NewOptions()) +// result := c.Action("agentic.status").Run(ctx, core.NewOptions()) func (s *PrepSubsystem) handleStatus(ctx context.Context, options core.Options) core.Result { input := StatusInput{ Workspace: options.String("workspace"), @@ -74,11 +70,11 @@ func (s *PrepSubsystem) handleStatus(ctx context.Context, options core.Options) return core.Result{Value: out, OK: true} } -// handleResume resumes a blocked workspace. +// result := c.Action("agentic.resume").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.resume").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, -// )) +// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, +// +// )) func (s *PrepSubsystem) handleResume(ctx context.Context, options core.Options) core.Result { input := ResumeInput{ Workspace: options.String("workspace"), @@ -91,9 +87,7 @@ func (s *PrepSubsystem) handleResume(ctx context.Context, options core.Options) return core.Result{Value: out, OK: true} } -// handleScan scans forge repos for actionable issues. -// -// result := c.Action("agentic.scan").Run(ctx, core.NewOptions()) +// result := c.Action("agentic.scan").Run(ctx, core.NewOptions()) func (s *PrepSubsystem) handleScan(ctx context.Context, options core.Options) core.Result { input := ScanInput{ Org: options.String("org"), @@ -106,11 +100,11 @@ func (s *PrepSubsystem) handleScan(ctx context.Context, options core.Options) co return core.Result{Value: out, OK: true} } -// handleWatch watches a workspace for completion. +// result := c.Action("agentic.watch").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.watch").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, -// )) +// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, +// +// )) func (s *PrepSubsystem) handleWatch(ctx context.Context, options core.Options) core.Result { input := WatchInput{ PollInterval: options.Int("poll_interval"), @@ -126,58 +120,56 @@ func (s *PrepSubsystem) handleWatch(ctx context.Context, options core.Options) c return core.Result{Value: out, OK: true} } -// handlePrompt reads an embedded prompt by slug. +// result := c.Action("agentic.prompt").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.prompt").Run(ctx, core.NewOptions( -// core.Option{Key: "slug", Value: "coding"}, -// )) +// core.Option{Key: "slug", Value: "coding"}, +// +// )) func (s *PrepSubsystem) handlePrompt(_ context.Context, options core.Options) core.Result { return lib.Prompt(options.String("slug")) } -// handleTask reads an embedded task plan by slug. +// result := c.Action("agentic.task").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.task").Run(ctx, core.NewOptions( -// core.Option{Key: "slug", Value: "bug-fix"}, -// )) +// core.Option{Key: "slug", Value: "bug-fix"}, +// +// )) func (s *PrepSubsystem) handleTask(_ context.Context, options core.Options) core.Result { return lib.Task(options.String("slug")) } -// handleFlow reads an embedded flow by slug. +// result := c.Action("agentic.flow").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.flow").Run(ctx, core.NewOptions( -// core.Option{Key: "slug", Value: "go"}, -// )) +// core.Option{Key: "slug", Value: "go"}, +// +// )) func (s *PrepSubsystem) handleFlow(_ context.Context, options core.Options) core.Result { return lib.Flow(options.String("slug")) } -// handlePersona reads an embedded persona by path. +// result := c.Action("agentic.persona").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.persona").Run(ctx, core.NewOptions( -// core.Option{Key: "path", Value: "code/backend-architect"}, -// )) +// core.Option{Key: "path", Value: "code/backend-architect"}, +// +// )) func (s *PrepSubsystem) handlePersona(_ context.Context, options core.Options) core.Result { return lib.Persona(options.String("path")) } -// --- Pipeline --- - -// handleComplete runs the named completion task. +// result := c.Action("agentic.complete").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.complete").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "/srv/.core/workspace/core/go-io/task-42"}, -// )) +// core.Option{Key: "workspace", Value: "/srv/.core/workspace/core/go-io/task-42"}, +// +// )) func (s *PrepSubsystem) handleComplete(ctx context.Context, options core.Options) core.Result { return s.Core().Task("agent.completion").Run(ctx, s.Core(), options) } -// handleQA runs build+test on a completed workspace. +// result := c.Action("agentic.qa").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.qa").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "/path/to/workspace"}, -// )) +// core.Option{Key: "workspace", Value: "/path/to/workspace"}, +// +// )) func (s *PrepSubsystem) handleQA(ctx context.Context, options core.Options) core.Result { // Feature flag gate — skip QA if disabled if s.ServiceRuntime != nil && !s.Config().Enabled("auto-qa") { @@ -215,11 +207,11 @@ func (s *PrepSubsystem) handleQA(ctx context.Context, options core.Options) core return core.Result{Value: passed, OK: passed} } -// handleAutoPR creates a PR for a completed workspace. +// result := c.Action("agentic.auto-pr").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.auto-pr").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "/path/to/workspace"}, -// )) +// core.Option{Key: "workspace", Value: "/path/to/workspace"}, +// +// )) func (s *PrepSubsystem) handleAutoPR(ctx context.Context, options core.Options) core.Result { if s.ServiceRuntime != nil && !s.Config().Enabled("auto-pr") { return core.Result{OK: true} @@ -246,11 +238,11 @@ func (s *PrepSubsystem) handleAutoPR(ctx context.Context, options core.Options) return core.Result{OK: true} } -// handleVerify verifies and auto-merges a PR. +// result := c.Action("agentic.verify").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.verify").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "/path/to/workspace"}, -// )) +// core.Option{Key: "workspace", Value: "/path/to/workspace"}, +// +// )) func (s *PrepSubsystem) handleVerify(ctx context.Context, options core.Options) core.Result { if s.ServiceRuntime != nil && !s.Config().Enabled("auto-merge") { return core.Result{OK: true} @@ -285,11 +277,11 @@ func (s *PrepSubsystem) handleVerify(ctx context.Context, options core.Options) return core.Result{OK: true} } -// handleIngest creates issues from agent findings. +// result := c.Action("agentic.ingest").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.ingest").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "/path/to/workspace"}, -// )) +// core.Option{Key: "workspace", Value: "/path/to/workspace"}, +// +// )) func (s *PrepSubsystem) handleIngest(ctx context.Context, options core.Options) core.Result { workspaceDir := options.String("workspace") if workspaceDir == "" { @@ -307,11 +299,11 @@ func (s *PrepSubsystem) handlePoke(ctx context.Context, _ core.Options) core.Res return core.Result{OK: true} } -// handleMirror mirrors agent branches to GitHub. +// result := c.Action("agentic.mirror").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.mirror").Run(ctx, core.NewOptions( -// core.Option{Key: "repo", Value: "go-io"}, -// )) +// core.Option{Key: "repo", Value: "go-io"}, +// +// )) func (s *PrepSubsystem) handleMirror(ctx context.Context, options core.Options) core.Result { input := MirrorInput{ Repo: options.String("repo"), @@ -323,8 +315,6 @@ func (s *PrepSubsystem) handleMirror(ctx context.Context, options core.Options) return core.Result{Value: out, OK: true} } -// --- Forge --- - // handleIssueGet retrieves a forge issue. // // result := c.Action("agentic.issue.get").Run(ctx, core.NewOptions( @@ -335,21 +325,21 @@ func (s *PrepSubsystem) handleIssueGet(ctx context.Context, options core.Options return s.cmdIssueGet(options) } -// handleIssueList lists forge issues. +// result := c.Action("agentic.issue.list").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.issue.list").Run(ctx, core.NewOptions( -// core.Option{Key: "_arg", Value: "go-io"}, -// )) +// core.Option{Key: "_arg", Value: "go-io"}, +// +// )) func (s *PrepSubsystem) handleIssueList(ctx context.Context, options core.Options) core.Result { return s.cmdIssueList(options) } -// handleIssueCreate creates a forge issue. +// result := c.Action("agentic.issue.create").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.issue.create").Run(ctx, core.NewOptions( -// core.Option{Key: "_arg", Value: "go-io"}, -// core.Option{Key: "title", Value: "Bug report"}, -// )) +// core.Option{Key: "_arg", Value: "go-io"}, +// core.Option{Key: "title", Value: "Bug report"}, +// +// )) func (s *PrepSubsystem) handleIssueCreate(ctx context.Context, options core.Options) core.Result { return s.cmdIssueCreate(options) } @@ -364,11 +354,11 @@ func (s *PrepSubsystem) handlePRGet(ctx context.Context, options core.Options) c return s.cmdPRGet(options) } -// handlePRList lists forge PRs. +// result := c.Action("agentic.pr.list").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.pr.list").Run(ctx, core.NewOptions( -// core.Option{Key: "_arg", Value: "go-io"}, -// )) +// core.Option{Key: "_arg", Value: "go-io"}, +// +// )) func (s *PrepSubsystem) handlePRList(ctx context.Context, options core.Options) core.Result { return s.cmdPRList(options) } @@ -383,13 +373,11 @@ func (s *PrepSubsystem) handlePRMerge(ctx context.Context, options core.Options) return s.cmdPRMerge(options) } -// --- Review --- - -// handleReviewQueue runs CodeRabbit review on a workspace. +// result := c.Action("agentic.review-queue").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.review-queue").Run(ctx, core.NewOptions( -// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, -// )) +// core.Option{Key: "workspace", Value: "core/go-io/task-5"}, +// +// )) func (s *PrepSubsystem) handleReviewQueue(ctx context.Context, options core.Options) core.Result { input := ReviewQueueInput{ Limit: options.Int("limit"), @@ -403,13 +391,11 @@ func (s *PrepSubsystem) handleReviewQueue(ctx context.Context, options core.Opti return core.Result{Value: out, OK: true} } -// --- Epic --- - -// handleEpic creates an epic (multi-repo task breakdown). +// result := c.Action("agentic.epic").Run(ctx, core.NewOptions( // -// result := c.Action("agentic.epic").Run(ctx, core.NewOptions( -// core.Option{Key: "task", Value: "Update all repos to v0.8.0"}, -// )) +// core.Option{Key: "task", Value: "Update all repos to v0.8.0"}, +// +// )) func (s *PrepSubsystem) handleEpic(ctx context.Context, options core.Options) core.Result { input := EpicInput{ Repo: options.String("repo"), diff --git a/pkg/agentic/auto_pr.go b/pkg/agentic/auto_pr.go index 8d9519c..992687b 100644 --- a/pkg/agentic/auto_pr.go +++ b/pkg/agentic/auto_pr.go @@ -9,8 +9,7 @@ import ( core "dappco.re/go/core" ) -// autoCreatePR pushes the agent's branch and creates a PR on Forge -// if the agent made any commits beyond the initial clone. +// s.autoCreatePR("/srv/.core/workspace/core/go-io/task-5") func (s *PrepSubsystem) autoCreatePR(workspaceDir string) { result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) diff --git a/pkg/agentic/commands_forge.go b/pkg/agentic/commands_forge.go index ff3d1ba..e2e55e5 100644 --- a/pkg/agentic/commands_forge.go +++ b/pkg/agentic/commands_forge.go @@ -71,7 +71,13 @@ func pullRequestAuthor(pr pullRequestView) string { return pr.User.Login } -// parseForgeArgs extracts org and repo from options. +// org, repo, num := parseForgeArgs(core.NewOptions( +// +// core.Option{Key: "org", Value: "core"}, +// core.Option{Key: "_arg", Value: "go-io"}, +// core.Option{Key: "number", Value: "42"}, +// +// )) func parseForgeArgs(options core.Options) (org, repo string, num int64) { org = options.String("org") if org == "" { diff --git a/pkg/agentic/deps.go b/pkg/agentic/deps.go index 0ded1fc..6525757 100644 --- a/pkg/agentic/deps.go +++ b/pkg/agentic/deps.go @@ -13,11 +13,7 @@ import ( core "dappco.re/go/core" ) -// cloneWorkspaceDeps clones Core ecosystem dependencies into the workspace. -// After this, the workspace go.work includes ./repo and all ./dep-* dirs, -// giving the agent everything needed to build and test. -// -// s.cloneWorkspaceDeps(ctx, workspaceDir, repoDir, "core") +// 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) @@ -80,11 +76,8 @@ type coreDep struct { dir string // e.g. "core-go" (workspace subdir) } -// parseCoreDeps extracts direct Core ecosystem dependencies from go.mod content. -// Skips indirect deps — only clones what the repo directly imports. -// -// deps := parseCoreDeps(goMod) -// if len(deps) > 0 { core.Println(deps[0].repo) } +// deps := parseCoreDeps(goMod) +// if len(deps) > 0 { core.Println(deps[0].repo) } func parseCoreDeps(gomod string) []coreDep { var deps []coreDep seen := make(map[string]bool) diff --git a/pkg/agentic/dispatch.go b/pkg/agentic/dispatch.go index 60d92c8..41a6568 100644 --- a/pkg/agentic/dispatch.go +++ b/pkg/agentic/dispatch.go @@ -226,16 +226,13 @@ func containerCommand(command string, args []string, repoDir, metaDir string) (s return "docker", dockerArgs } -// --- spawnAgent: decomposed into testable steps --- - -// agentOutputFile returns the log file path for an agent's output. +// outputFile := agentOutputFile(workspaceDir, "codex") func agentOutputFile(workspaceDir, agent string) string { agentBase := core.SplitN(agent, ":", 2)[0] return core.JoinPath(WorkspaceMetaDir(workspaceDir), core.Sprintf("agent-%s.log", agentBase)) } -// detectFinalStatus reads workspace state after agent exit to determine outcome. -// Returns (status, question) — "completed", "blocked", or "failed". +// status, question := detectFinalStatus(repoDir, 0, "completed") func detectFinalStatus(repoDir string, exitCode int, processStatus string) (string, string) { blockedPath := core.JoinPath(repoDir, "BLOCKED.md") if blockedResult := fs.Read(blockedPath); blockedResult.OK && core.Trim(blockedResult.Value.(string)) != "" { @@ -342,8 +339,6 @@ func (s *PrepSubsystem) broadcastComplete(agent, workspaceDir, finalStatus strin } } -// onAgentComplete handles all post-completion logic for a spawned agent. -// Called from the monitoring goroutine after the process exits. func (s *PrepSubsystem) onAgentComplete(agent, workspaceDir, outputFile string, exitCode int, processStatus, output string) { // Save output if output != "" { @@ -384,9 +379,7 @@ func (s *PrepSubsystem) onAgentComplete(agent, workspaceDir, outputFile string, } } -// 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. +// pid, processID, outputFile, err := s.spawnAgent(agent, prompt, workspaceDir) func (s *PrepSubsystem) spawnAgent(agent, prompt, workspaceDir string) (int, string, string, error) { command, args, err := agentCommand(agent, prompt) if err != nil { @@ -472,8 +465,7 @@ func (m *agentCompletionMonitor) run(_ context.Context, _ core.Options) core.Res return core.Result{OK: true} } -// runQA runs build + test checks on the repo after agent completion. -// Returns true if QA passes, false if build or tests fail. +// passed := s.runQA(workspaceDir) func (s *PrepSubsystem) runQA(workspaceDir string) bool { ctx := context.Background() repoDir := WorkspaceRepoDir(workspaceDir) diff --git a/pkg/agentic/epic.go b/pkg/agentic/epic.go index 9137334..e18a2df 100644 --- a/pkg/agentic/epic.go +++ b/pkg/agentic/epic.go @@ -9,11 +9,7 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_create_epic --- - -// EpicInput is the input for agentic_create_epic. -// -// input := agentic.EpicInput{Repo: "go-scm", Title: "Port agentic plans", Tasks: []string{"Read PHP flow", "Implement Go MCP tools"}} +// input := agentic.EpicInput{Repo: "go-scm", Title: "Port agentic plans", Tasks: []string{"Read PHP flow", "Implement Go MCP tools"}} type EpicInput struct { Repo string `json:"repo"` // Target repo (e.g. "go-scm") Org string `json:"org,omitempty"` // Forge org (default "core") @@ -26,9 +22,7 @@ type EpicInput struct { Template string `json:"template,omitempty"` // Prompt template for dispatch (default "coding") } -// EpicOutput is the output for agentic_create_epic. -// -// out := agentic.EpicOutput{Success: true, EpicNumber: 42, EpicURL: "https://forge.example/core/go-scm/issues/42"} +// out := agentic.EpicOutput{Success: true, EpicNumber: 42, EpicURL: "https://forge.example/core/go-scm/issues/42"} type EpicOutput struct { Success bool `json:"success"` EpicNumber int `json:"epic_number"` @@ -37,9 +31,7 @@ type EpicOutput struct { Dispatched int `json:"dispatched,omitempty"` } -// ChildRef references a child issue. -// -// child := agentic.ChildRef{Number: 43, Title: "Implement plan list", URL: "https://forge.example/core/go-scm/issues/43"} +// child := agentic.ChildRef{Number: 43, Title: "Implement plan list", URL: "https://forge.example/core/go-scm/issues/43"} type ChildRef struct { Number int `json:"number"` Title string `json:"title"` @@ -144,7 +136,7 @@ func (s *PrepSubsystem) createEpic(ctx context.Context, callRequest *mcp.CallToo return nil, out, nil } -// createIssue creates a single issue on Forge and returns its reference. +// child, err := s.createIssue(ctx, "core", "go-scm", "Port agentic plans", "", nil) func (s *PrepSubsystem) createIssue(ctx context.Context, org, repo, title, body string, labelIDs []int64) (ChildRef, error) { payload := map[string]any{ "title": title, @@ -176,7 +168,7 @@ func (s *PrepSubsystem) createIssue(ctx context.Context, org, repo, title, body }, nil } -// resolveLabelIDs looks up label IDs by name, creating labels that don't exist. +// labelIDs := s.resolveLabelIDs(ctx, "core", "go-scm", []string{"agentic", "epic"}) func (s *PrepSubsystem) resolveLabelIDs(ctx context.Context, org, repo string, names []string) []int64 { if len(names) == 0 { return nil @@ -216,7 +208,7 @@ func (s *PrepSubsystem) resolveLabelIDs(ctx context.Context, org, repo string, n return ids } -// createLabel creates a label on Forge and returns its ID. +// id := s.createLabel(ctx, "core", "go-scm", "agentic") func (s *PrepSubsystem) createLabel(ctx context.Context, org, repo, name string) int64 { colours := map[string]string{ "agentic": "#7c3aed", diff --git a/pkg/agentic/mirror.go b/pkg/agentic/mirror.go index 3c11f98..2ec5db5 100644 --- a/pkg/agentic/mirror.go +++ b/pkg/agentic/mirror.go @@ -9,20 +9,14 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_mirror tool --- - -// MirrorInput is the input for agentic_mirror. -// -// input := agentic.MirrorInput{Repo: "go-io", DryRun: true, MaxFiles: 50} +// input := agentic.MirrorInput{Repo: "go-io", DryRun: true, MaxFiles: 50} type MirrorInput struct { Repo string `json:"repo,omitempty"` // Specific repo, or empty for all DryRun bool `json:"dry_run,omitempty"` // Preview without pushing MaxFiles int `json:"max_files,omitempty"` // Max files per PR (default 50, CodeRabbit limit) } -// MirrorOutput is the output for agentic_mirror. -// -// out := agentic.MirrorOutput{Success: true, Count: 1, Synced: []agentic.MirrorSync{{Repo: "go-io"}}} +// out := agentic.MirrorOutput{Success: true, Count: 1, Synced: []agentic.MirrorSync{{Repo: "go-io"}}} type MirrorOutput struct { Success bool `json:"success"` Synced []MirrorSync `json:"synced"` @@ -30,9 +24,7 @@ type MirrorOutput struct { Count int `json:"count"` } -// MirrorSync records one repo sync. -// -// sync := agentic.MirrorSync{Repo: "go-io", CommitsAhead: 3, FilesChanged: 12} +// sync := agentic.MirrorSync{Repo: "go-io", CommitsAhead: 3, FilesChanged: 12} type MirrorSync struct { Repo string `json:"repo"` CommitsAhead int `json:"commits_ahead"` @@ -146,7 +138,7 @@ func (s *PrepSubsystem) mirror(ctx context.Context, _ *mcp.CallToolRequest, inpu }, nil } -// createGitHubPR creates a PR from dev → main using the gh CLI. +// url, err := s.createGitHubPR(ctx, repoDir, "go-io", 3, 12) func (s *PrepSubsystem) createGitHubPR(ctx context.Context, repoDir, repo string, commits, files int) (string, error) { ghRepo := core.Sprintf("%s/%s", GitHubOrg(), repo) process := s.Core().Process() @@ -183,17 +175,14 @@ func (s *PrepSubsystem) createGitHubPR(ctx context.Context, repoDir, repo string return "", nil } -// ensureDevBranch creates the dev branch on GitHub if it doesn't exist. func (s *PrepSubsystem) ensureDevBranch(repoDir string) { s.Core().Process().RunIn(context.Background(), repoDir, "git", "push", "github", "HEAD:refs/heads/dev") } -// hasRemote checks if a git remote exists. func (s *PrepSubsystem) hasRemote(repoDir, name string) bool { return s.Core().Process().RunIn(context.Background(), repoDir, "git", "remote", "get-url", name).OK } -// commitsAhead returns how many commits HEAD is ahead of the ref. func (s *PrepSubsystem) commitsAhead(repoDir, base, head string) int { r := s.Core().Process().RunIn(context.Background(), repoDir, "git", "rev-list", core.Concat(base, "..", head), "--count") if !r.OK { @@ -203,7 +192,6 @@ func (s *PrepSubsystem) commitsAhead(repoDir, base, head string) int { return parseInt(out) } -// filesChanged returns the number of files changed between two refs. func (s *PrepSubsystem) filesChanged(repoDir, base, head string) int { r := s.Core().Process().RunIn(context.Background(), repoDir, "git", "diff", "--name-only", core.Concat(base, "..", head)) if !r.OK { @@ -216,7 +204,6 @@ func (s *PrepSubsystem) filesChanged(repoDir, base, head string) int { return len(core.Split(out, "\n")) } -// listLocalRepos returns repo names that exist as directories in basePath. func (s *PrepSubsystem) listLocalRepos(basePath string) []string { paths := core.PathGlob(core.JoinPath(basePath, "*")) var repos []string @@ -233,7 +220,6 @@ func (s *PrepSubsystem) listLocalRepos(basePath string) []string { return repos } -// extractJSONField extracts a simple string field from JSON array output. func extractJSONField(jsonStr, field string) string { if jsonStr == "" || field == "" { return "" diff --git a/pkg/agentic/paths.go b/pkg/agentic/paths.go index fdba902..bd5d600 100644 --- a/pkg/agentic/paths.go +++ b/pkg/agentic/paths.go @@ -11,44 +11,30 @@ import ( core "dappco.re/go/core" ) -// fs provides unrestricted filesystem access (root "/" = no sandbox). -// -// r := fs.Read("/etc/hostname") -// if r.OK { core.Print(nil, "%s", r.Value.(string)) } +// r := fs.Read("/etc/hostname") +// if r.OK { core.Print(nil, "%s", r.Value.(string)) } var fs = (&core.Fs{}).NewUnrestricted() -// LocalFs returns an unrestricted filesystem instance for use by other packages. -// -// f := agentic.LocalFs() -// r := f.Read("/tmp/agent-status.json") +// f := agentic.LocalFs() +// r := f.Read("/tmp/agent-status.json") 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. -// -// workspaceDir := 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") } -// WorkspaceStatusPaths returns all workspace status files across supported layouts. -// -// paths := agentic.WorkspaceStatusPaths() +// paths := agentic.WorkspaceStatusPaths() func WorkspaceStatusPaths() []string { return workspaceStatusPaths(WorkspaceRoot()) } -// WorkspaceStatusPath returns the status file for a workspace directory. -// -// path := agentic.WorkspaceStatusPath("/srv/.core/workspace/core/go-io/task-5") +// path := agentic.WorkspaceStatusPath("/srv/.core/workspace/core/go-io/task-5") 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") +// name := agentic.WorkspaceName("/Users/snider/Code/.core/workspace/core/go-io/dev") func WorkspaceName(workspaceDir string) string { root := WorkspaceRoot() name := core.TrimPrefix(workspaceDir, root) @@ -59,10 +45,7 @@ func WorkspaceName(workspaceDir string) string { return name } -// CoreRoot returns the root directory for core ecosystem files. -// Checks CORE_WORKSPACE env var first, falls back to HomeDir()/Code/.core. -// -// root := agentic.CoreRoot() +// root := agentic.CoreRoot() func CoreRoot() string { if root := core.Env("CORE_WORKSPACE"); root != "" { return root @@ -70,9 +53,7 @@ func CoreRoot() string { return core.JoinPath(HomeDir(), "Code", ".core") } -// HomeDir returns the user home directory used by agentic path helpers. -// -// home := agentic.HomeDir() +// home := agentic.HomeDir() func HomeDir() string { if home := core.Env("CORE_HOME"); home != "" { return home @@ -127,9 +108,7 @@ func workspaceStatusPaths(workspaceRoot string) []string { return paths } -// WorkspaceRepoDir returns the checked-out repo directory for a workspace. -// -// repoDir := agentic.WorkspaceRepoDir("/srv/.core/workspace/core/go-io/task-5") +// repoDir := agentic.WorkspaceRepoDir("/srv/.core/workspace/core/go-io/task-5") func WorkspaceRepoDir(workspaceDir string) string { return core.JoinPath(workspaceDir, "repo") } @@ -138,9 +117,7 @@ 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") +// metaDir := agentic.WorkspaceMetaDir("/srv/.core/workspace/core/go-io/task-5") func WorkspaceMetaDir(workspaceDir string) string { return core.JoinPath(workspaceDir, ".meta") } @@ -149,9 +126,7 @@ 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") +// blocked := agentic.WorkspaceBlockedPath("/srv/.core/workspace/core/go-io/task-5") func WorkspaceBlockedPath(workspaceDir string) string { return core.JoinPath(WorkspaceRepoDir(workspaceDir), "BLOCKED.md") } @@ -160,9 +135,7 @@ 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") +// answer := agentic.WorkspaceAnswerPath("/srv/.core/workspace/core/go-io/task-5") func WorkspaceAnswerPath(workspaceDir string) string { return core.JoinPath(WorkspaceRepoDir(workspaceDir), "ANSWER.md") } @@ -171,9 +144,7 @@ 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") +// logs := agentic.WorkspaceLogFiles("/srv/.core/workspace/core/go-io/task-5") func WorkspaceLogFiles(workspaceDir string) []string { return core.PathGlob(core.JoinPath(WorkspaceMetaDir(workspaceDir), "agent-*.log")) } @@ -182,17 +153,12 @@ func workspaceLogFiles(workspaceDir string) []string { return WorkspaceLogFiles(workspaceDir) } -// PlansRoot returns the root directory for agent plans. -// -// plansDir := agentic.PlansRoot() +// plansDir := agentic.PlansRoot() func PlansRoot() string { return core.JoinPath(CoreRoot(), "plans") } -// AgentName returns the name of this agent based on hostname. -// Checks AGENT_NAME env var first. -// -// name := agentic.AgentName() // "cladius" on Snider's Mac, "charon" elsewhere +// name := agentic.AgentName() // "cladius" on Snider's Mac, "charon" elsewhere func AgentName() string { if name := core.Env("AGENT_NAME"); name != "" { return name @@ -204,9 +170,7 @@ func AgentName() string { return "charon" } -// DefaultBranch detects the default branch of a repo (main, master, etc.). -// -// base := s.DefaultBranch("./src") +// base := s.DefaultBranch("/srv/Code/core/go-io/repo") func (s *PrepSubsystem) DefaultBranch(repoDir string) string { ctx := context.Background() process := s.Core().Process() @@ -225,9 +189,7 @@ func (s *PrepSubsystem) DefaultBranch(repoDir string) string { return "main" } -// GitHubOrg returns the GitHub org for mirror operations. -// -// org := agentic.GitHubOrg() // "dAppCore" +// org := agentic.GitHubOrg() // "dAppCore" func GitHubOrg() string { if org := core.Env("GITHUB_ORG"); org != "" { return org diff --git a/pkg/agentic/pid.go b/pkg/agentic/pid.go index b4f0e50..e5f8110 100644 --- a/pkg/agentic/pid.go +++ b/pkg/agentic/pid.go @@ -7,10 +7,8 @@ import ( "dappco.re/go/core/process" ) -// ProcessAlive checks whether a managed process is still running. -// -// alive := agentic.ProcessAlive(c, proc.ID, proc.Info().PID) -// alive := agentic.ProcessAlive(c, "", 12345) // legacy PID fallback +// alive := agentic.ProcessAlive(c, proc.ID, proc.Info().PID) +// alive := agentic.ProcessAlive(c, "", 12345) // legacy PID fallback func ProcessAlive(c *core.Core, processID string, pid int) bool { if c == nil { return false diff --git a/pkg/agentic/plan.go b/pkg/agentic/plan.go index d17b392..60fade8 100644 --- a/pkg/agentic/plan.go +++ b/pkg/agentic/plan.go @@ -40,11 +40,7 @@ type Phase struct { Notes string `json:"notes,omitempty"` } -// --- Input/Output types --- - -// PlanCreateInput is the input for agentic_plan_create. -// -// input := agentic.PlanCreateInput{Title: "Migrate pkg/agentic", Objective: "Use Core primitives everywhere"} +// input := agentic.PlanCreateInput{Title: "Migrate pkg/agentic", Objective: "Use Core primitives everywhere"} type PlanCreateInput struct { Title string `json:"title"` Objective string `json:"objective"` @@ -54,33 +50,25 @@ type PlanCreateInput struct { Notes string `json:"notes,omitempty"` } -// PlanCreateOutput is the output for agentic_plan_create. -// -// out := agentic.PlanCreateOutput{Success: true, ID: "id-1-a3f2b1"} +// out := agentic.PlanCreateOutput{Success: true, ID: "id-1-a3f2b1"} type PlanCreateOutput struct { Success bool `json:"success"` ID string `json:"id"` Path string `json:"path"` } -// PlanReadInput is the input for agentic_plan_read. -// -// input := agentic.PlanReadInput{ID: "id-1-a3f2b1"} +// input := agentic.PlanReadInput{ID: "id-1-a3f2b1"} type PlanReadInput struct { ID string `json:"id"` } -// PlanReadOutput is the output for agentic_plan_read. -// -// out := agentic.PlanReadOutput{Success: true, Plan: agentic.Plan{ID: "id-1-a3f2b1"}} +// out := agentic.PlanReadOutput{Success: true, Plan: agentic.Plan{ID: "id-1-a3f2b1"}} type PlanReadOutput struct { Success bool `json:"success"` Plan Plan `json:"plan"` } -// PlanUpdateInput is the input for agentic_plan_update. -// -// input := agentic.PlanUpdateInput{ID: "id-1-a3f2b1", Status: "verified"} +// input := agentic.PlanUpdateInput{ID: "id-1-a3f2b1", Status: "verified"} type PlanUpdateInput struct { ID string `json:"id"` Status string `json:"status,omitempty"` @@ -91,48 +79,36 @@ type PlanUpdateInput struct { Agent string `json:"agent,omitempty"` } -// PlanUpdateOutput is the output for agentic_plan_update. -// -// out := agentic.PlanUpdateOutput{Success: true, Plan: agentic.Plan{Status: "verified"}} +// out := agentic.PlanUpdateOutput{Success: true, Plan: agentic.Plan{Status: "verified"}} type PlanUpdateOutput struct { Success bool `json:"success"` Plan Plan `json:"plan"` } -// PlanDeleteInput is the input for agentic_plan_delete. -// -// input := agentic.PlanDeleteInput{ID: "id-1-a3f2b1"} +// input := agentic.PlanDeleteInput{ID: "id-1-a3f2b1"} type PlanDeleteInput struct { ID string `json:"id"` } -// PlanDeleteOutput is the output for agentic_plan_delete. -// -// out := agentic.PlanDeleteOutput{Success: true, Deleted: "id-1-a3f2b1"} +// out := agentic.PlanDeleteOutput{Success: true, Deleted: "id-1-a3f2b1"} type PlanDeleteOutput struct { Success bool `json:"success"` Deleted string `json:"deleted"` } -// PlanListInput is the input for agentic_plan_list. -// -// input := agentic.PlanListInput{Repo: "go-io", Status: "ready"} +// input := agentic.PlanListInput{Repo: "go-io", Status: "ready"} type PlanListInput struct { Status string `json:"status,omitempty"` Repo string `json:"repo,omitempty"` } -// PlanListOutput is the output for agentic_plan_list. -// -// out := agentic.PlanListOutput{Success: true, Count: 2, Plans: []agentic.Plan{{ID: "id-1-a3f2b1"}}} +// out := agentic.PlanListOutput{Success: true, Count: 2, Plans: []agentic.Plan{{ID: "id-1-a3f2b1"}}} type PlanListOutput struct { Success bool `json:"success"` Count int `json:"count"` Plans []Plan `json:"plans"` } -// --- Registration --- - func (s *PrepSubsystem) registerPlanTools(server *mcp.Server) { mcp.AddTool(server, &mcp.Tool{ Name: "agentic_plan_create", @@ -160,8 +136,6 @@ func (s *PrepSubsystem) registerPlanTools(server *mcp.Server) { }, s.planList) } -// --- Handlers --- - func (s *PrepSubsystem) planCreate(_ context.Context, _ *mcp.CallToolRequest, input PlanCreateInput) (*mcp.CallToolResult, PlanCreateOutput, error) { if input.Title == "" { return nil, PlanCreateOutput{}, core.E("planCreate", "title is required", nil) @@ -356,17 +330,13 @@ func (s *PrepSubsystem) planList(_ context.Context, _ *mcp.CallToolRequest, inpu }, nil } -// --- Helpers --- - func planPath(dir, id string) string { safe := core.SanitisePath(id) return core.JoinPath(dir, core.Concat(safe, ".json")) } -// readPlanResult reads and decodes a plan file as core.Result. -// -// result := readPlanResult(PlansRoot(), "plan-id") -// if result.OK { plan := result.Value.(*Plan) } +// result := readPlanResult(PlansRoot(), "plan-id") +// if result.OK { plan := result.Value.(*Plan) } func readPlanResult(dir, id string) core.Result { r := fs.Read(planPath(dir, id)) if !r.OK { @@ -405,10 +375,8 @@ func readPlan(dir, id string) (*Plan, error) { return plan, nil } -// writePlanResult writes a plan file and returns core.Result. -// -// result := writePlanResult(PlansRoot(), plan) -// if result.OK { path := result.Value.(string) } +// result := writePlanResult(PlansRoot(), plan) +// if result.OK { path := result.Value.(string) } func writePlanResult(dir string, plan *Plan) core.Result { if plan == nil { return core.Result{Value: core.E("writePlan", "plan is required", nil), OK: false} diff --git a/pkg/agentic/pr.go b/pkg/agentic/pr.go index e8d6923..e24bd59 100644 --- a/pkg/agentic/pr.go +++ b/pkg/agentic/pr.go @@ -10,8 +10,6 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_create_pr --- - // CreatePRInput is the input for agentic_create_pr. // // input := agentic.CreatePRInput{Workspace: "core/go-io/task-42", Title: "Fix watcher panic"} @@ -179,8 +177,6 @@ func (s *PrepSubsystem) commentOnIssue(ctx context.Context, org, repo string, is s.forge.Issues.CreateComment(ctx, org, repo, int64(issue), comment) } -// --- agentic_list_prs --- - // ListPRsInput is the input for agentic_list_prs. // // input := agentic.ListPRsInput{Org: "core", Repo: "go-io", State: "open", Limit: 10} diff --git a/pkg/agentic/prep.go b/pkg/agentic/prep.go index d40c5e9..edb1e1d 100644 --- a/pkg/agentic/prep.go +++ b/pkg/agentic/prep.go @@ -287,8 +287,6 @@ func (s *PrepSubsystem) RegisterTools(server *mcp.Server) { // _ = subsystem.Shutdown(context.Background()) func (s *PrepSubsystem) Shutdown(_ context.Context) error { return nil } -// --- Input/Output types --- - // input := agentic.PrepInput{Repo: "go-io", Issue: 15, Task: "Migrate to Core primitives"} type PrepInput struct { Repo string `json:"repo"` // required: e.g. "go-io" @@ -511,8 +509,6 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques return nil, out, nil } -// --- Spec Injection --- - // copyRepoSpecs copies RFC spec files from the plans repo into the workspace specs/ folder. // Maps repo name to plans directory: go-io → core/go/io, agent → core/agent, core-bio → core/php/bio. // Preserves subdirectory structure so sub-package specs land in specs/{pkg}/RFC.md. @@ -574,8 +570,6 @@ func (s *PrepSubsystem) copyRepoSpecs(workspaceDir, repo string) { } } -// --- Public API for CLI testing --- - // TestPrepWorkspace exposes prepWorkspace for CLI testing. // // _, out, err := prep.TestPrepWorkspace(ctx, input) @@ -590,8 +584,6 @@ func (s *PrepSubsystem) TestBuildPrompt(ctx context.Context, input PrepInput, br return s.buildPrompt(ctx, input, branch, repoPath) } -// --- Prompt Building --- - // buildPrompt assembles all context into a single prompt string. // Context is gathered from: persona, flow, issue, brain, consumers, git log, wiki, plan. func (s *PrepSubsystem) buildPrompt(ctx context.Context, input PrepInput, branch, repoPath string) (string, int, int) { @@ -678,8 +670,6 @@ func (s *PrepSubsystem) buildPrompt(ctx context.Context, input PrepInput, branch return b.String(), memories, consumers } -// --- Context Helpers (return strings, not write files) --- - func (s *PrepSubsystem) getIssueBody(ctx context.Context, org, repo string, issue int) string { idx := core.Sprintf("%d", issue) iss, err := s.forge.Issues.Get(ctx, forge.Params{"owner": org, "repo": repo, "index": idx}) @@ -864,8 +854,6 @@ func (s *PrepSubsystem) renderPlan(templateSlug string, variables map[string]str return plan.String() } -// --- Detection helpers (unchanged) --- - func detectLanguage(repoPath string) string { checks := []struct { file string diff --git a/pkg/agentic/queue.go b/pkg/agentic/queue.go index 48f2688..fa2efb4 100644 --- a/pkg/agentic/queue.go +++ b/pkg/agentic/queue.go @@ -141,10 +141,7 @@ func (s *PrepSubsystem) delayForAgent(agent string) time.Duration { return time.Duration(rate.SustainedDelay) * time.Second } -// countRunningByAgent counts running workspaces for a specific agent type -// using the in-memory Registry. Falls back to disk scan if Registry is empty. -// -// n := s.countRunningByAgent("codex") // counts all codex:* variants +// n := s.countRunningByAgent("codex") func (s *PrepSubsystem) countRunningByAgent(agent string) int { var runtime *core.Core if s.ServiceRuntime != nil { @@ -182,10 +179,7 @@ func (s *PrepSubsystem) countRunningByAgentDisk(runtime *core.Core, agent string return count } -// countRunningByModel counts running workspaces for a specific agent:model string -// using the in-memory Registry. -// -// n := s.countRunningByModel("codex:gpt-5.4") // counts only that model +// n := s.countRunningByModel("codex:gpt-5.4") func (s *PrepSubsystem) countRunningByModel(agent string) int { var runtime *core.Core if s.ServiceRuntime != nil { @@ -268,11 +262,8 @@ func (s *PrepSubsystem) canDispatchAgent(agent string) bool { return true } -// modelVariant extracts the model name from an agent string. -// -// codex:gpt-5.4 → gpt-5.4 -// codex:gpt-5.3-codex-spark → gpt-5.3-codex-spark -// claude → "" +// model := modelVariant("codex:gpt-5.4") +// _ = model func modelVariant(agent string) string { parts := core.SplitN(agent, ":", 2) if len(parts) < 2 { diff --git a/pkg/agentic/remote.go b/pkg/agentic/remote.go index 09c16a7..3bf672d 100644 --- a/pkg/agentic/remote.go +++ b/pkg/agentic/remote.go @@ -8,8 +8,6 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_dispatch_remote tool --- - // RemoteDispatchInput dispatches a task to a remote core-agent over HTTP. // // input := agentic.RemoteDispatchInput{Host: "charon", Repo: "go-io", Task: "Run the review queue"} diff --git a/pkg/agentic/remote_status.go b/pkg/agentic/remote_status.go index 8d65021..fa1afc4 100644 --- a/pkg/agentic/remote_status.go +++ b/pkg/agentic/remote_status.go @@ -8,8 +8,6 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_status_remote tool --- - // RemoteStatusInput queries a remote core-agent for workspace status. // // input := agentic.RemoteStatusInput{Host: "charon"} diff --git a/pkg/agentic/review_queue.go b/pkg/agentic/review_queue.go index 34b782e..64d8d58 100644 --- a/pkg/agentic/review_queue.go +++ b/pkg/agentic/review_queue.go @@ -11,11 +11,7 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// --- agentic_review_queue tool --- - -// ReviewQueueInput controls the review queue runner. -// -// input := agentic.ReviewQueueInput{Reviewer: "coderabbit", Limit: 4, DryRun: true} +// input := agentic.ReviewQueueInput{Reviewer: "coderabbit", Limit: 4, DryRun: true} type ReviewQueueInput struct { Limit int `json:"limit,omitempty"` // Max PRs to process this run (default: 4) Reviewer string `json:"reviewer,omitempty"` // "coderabbit" (default), "codex", or "both" @@ -23,9 +19,7 @@ type ReviewQueueInput struct { LocalOnly bool `json:"local_only,omitempty"` // Run review locally, don't touch GitHub } -// ReviewQueueOutput reports what happened. -// -// out := agentic.ReviewQueueOutput{Success: true, Processed: []agentic.ReviewResult{{Repo: "go-io", Verdict: "clean"}}} +// out := agentic.ReviewQueueOutput{Success: true, Processed: []agentic.ReviewResult{{Repo: "go-io", Verdict: "clean"}}} type ReviewQueueOutput struct { Success bool `json:"success"` Processed []ReviewResult `json:"processed"` @@ -33,9 +27,7 @@ type ReviewQueueOutput struct { RateLimit *RateLimitInfo `json:"rate_limit,omitempty"` } -// ReviewResult is the outcome of reviewing one repo. -// -// result := agentic.ReviewResult{Repo: "go-io", Verdict: "findings", Findings: 3, Action: "fix_dispatched"} +// result := agentic.ReviewResult{Repo: "go-io", Verdict: "findings", Findings: 3, Action: "fix_dispatched"} type ReviewResult struct { Repo string `json:"repo"` Verdict string `json:"verdict"` // clean, findings, rate_limited, error @@ -44,9 +36,7 @@ type ReviewResult struct { Detail string `json:"detail,omitempty"` } -// RateLimitInfo tracks CodeRabbit rate limit state. -// -// limit := agentic.RateLimitInfo{Limited: true, Message: "retry after 2026-03-22T06:00:00Z"} +// limit := agentic.RateLimitInfo{Limited: true, Message: "retry after 2026-03-22T06:00:00Z"} type RateLimitInfo struct { Limited bool `json:"limited"` RetryAt time.Time `json:"retry_at,omitempty"` @@ -143,7 +133,7 @@ func (s *PrepSubsystem) reviewQueue(ctx context.Context, _ *mcp.CallToolRequest, }, nil } -// findReviewCandidates returns repos that are ahead of GitHub main. +// repos := s.findReviewCandidates("/srv/Code/core") func (s *PrepSubsystem) findReviewCandidates(basePath string) []string { paths := core.PathGlob(core.JoinPath(basePath, "*")) @@ -164,7 +154,7 @@ func (s *PrepSubsystem) findReviewCandidates(basePath string) []string { return candidates } -// reviewRepo runs CodeRabbit on a single repo and takes action. +// result := s.reviewRepo(ctx, repoDir, "go-io", "coderabbit", false, false) func (s *PrepSubsystem) reviewRepo(ctx context.Context, repoDir, repo, reviewer string, dryRun, localOnly bool) ReviewResult { result := ReviewResult{Repo: repo} process := s.Core().Process() @@ -253,7 +243,7 @@ func (s *PrepSubsystem) reviewRepo(ctx context.Context, repoDir, repo, reviewer return result } -// pushAndMerge pushes to GitHub dev and merges the PR. +// _ = s.pushAndMerge(ctx, repoDir, "go-io") func (s *PrepSubsystem) pushAndMerge(ctx context.Context, repoDir, repo string) error { process := s.Core().Process() if r := process.RunIn(ctx, repoDir, "git", "push", "github", "HEAD:refs/heads/dev", "--force"); !r.OK { @@ -270,7 +260,7 @@ func (s *PrepSubsystem) pushAndMerge(ctx context.Context, repoDir, repo string) return nil } -// dispatchFixFromQueue dispatches an opus agent to fix CodeRabbit findings. +// _ = s.dispatchFixFromQueue(ctx, "go-io", task) func (s *PrepSubsystem) dispatchFixFromQueue(ctx context.Context, repo, task string) error { // Use the dispatch system — creates workspace, spawns agent input := DispatchInput{ @@ -288,7 +278,7 @@ func (s *PrepSubsystem) dispatchFixFromQueue(ctx context.Context, repo, task str return nil } -// countFindings estimates the number of findings in CodeRabbit output. +// findings := countFindings(output) func countFindings(output string) int { // Count lines that look like findings count := 0 @@ -306,8 +296,7 @@ func countFindings(output string) int { return count } -// parseRetryAfter extracts the retry duration from a rate limit message. -// Example: "please try after 4 minutes and 56 seconds" +// delay := parseRetryAfter("please try after 4 minutes and 56 seconds") func parseRetryAfter(message string) time.Duration { if retryAfterPattern == nil { return 5 * time.Minute @@ -325,9 +314,7 @@ func parseRetryAfter(message string) time.Duration { return 5 * time.Minute } -// buildReviewCommand returns the command and args for the chosen reviewer. -// -// cmd, args := s.buildReviewCommand(repoDir, "coderabbit") +// cmd, args := s.buildReviewCommand(repoDir, "coderabbit") func (s *PrepSubsystem) buildReviewCommand(repoDir, reviewer string) (string, []string) { switch reviewer { case "codex": @@ -337,7 +324,7 @@ func (s *PrepSubsystem) buildReviewCommand(repoDir, reviewer string) (string, [] } } -// storeReviewOutput saves raw review output for training data collection. +// s.storeReviewOutput(repoDir, "go-io", "coderabbit", output) func (s *PrepSubsystem) storeReviewOutput(repoDir, repo, reviewer, output string) { dataDir := core.JoinPath(HomeDir(), ".core", "training", "reviews") fs.EnsureDir(dataDir) @@ -369,9 +356,7 @@ func (s *PrepSubsystem) storeReviewOutput(repoDir, repo, reviewer, output string core.WriteAll(r.Value, core.Concat(jsonLine, "\n")) } -// saveRateLimitState writes the current rate-limit snapshot. -// -// s.saveRateLimitState(&RateLimitInfo{Limited: true, RetryAt: time.Now().Add(30 * time.Minute)}) +// s.saveRateLimitState(&RateLimitInfo{Limited: true, RetryAt: time.Now().Add(30 * time.Minute)}) func (s *PrepSubsystem) saveRateLimitState(info *RateLimitInfo) { path := core.JoinPath(HomeDir(), ".core", "coderabbit-ratelimit.json") if r := fs.WriteAtomic(path, core.JSONMarshalString(info)); !r.OK { @@ -383,7 +368,7 @@ func (s *PrepSubsystem) saveRateLimitState(info *RateLimitInfo) { } } -// loadRateLimitState reads persisted rate limit info. +// info := s.loadRateLimitState() func (s *PrepSubsystem) loadRateLimitState() *RateLimitInfo { path := core.JoinPath(HomeDir(), ".core", "coderabbit-ratelimit.json") r := fs.Read(path) diff --git a/pkg/agentic/runner.go b/pkg/agentic/runner.go index 482a5fe..4925253 100644 --- a/pkg/agentic/runner.go +++ b/pkg/agentic/runner.go @@ -2,19 +2,10 @@ package agentic -// StartRunner preserves the legacy PrepSubsystem call after queue ownership moved to pkg/runner.Service. -// -// subsystem := agentic.NewPrep() -// subsystem.StartRunner() -// -// The runner service registers as core.WithService(runner.Register) and -// manages its own background loop, frozen state, and concurrency checks. +// subsystem := agentic.NewPrep() +// subsystem.StartRunner() func (s *PrepSubsystem) StartRunner() {} -// Poke preserves the legacy queue signal after queue ownership moved to pkg/runner.Service. -// -// subsystem := agentic.NewPrep() -// subsystem.Poke() -// -// Runner catches AgentCompleted via HandleIPCEvents and pokes itself. +// subsystem := agentic.NewPrep() +// subsystem.Poke() func (s *PrepSubsystem) Poke() {} diff --git a/pkg/agentic/status.go b/pkg/agentic/status.go index 4e9bef9..5c5e3bb 100644 --- a/pkg/agentic/status.go +++ b/pkg/agentic/status.go @@ -101,8 +101,6 @@ func workspaceStatusValue(result core.Result) (*WorkspaceStatus, bool) { return workspaceStatus, true } -// --- agentic_status tool --- - // input := agentic.StatusInput{Workspace: "core/go-io/task-42", Limit: 50} type StatusInput struct { Workspace string `json:"workspace,omitempty"` // specific workspace name, or empty for all diff --git a/pkg/agentic/transport.go b/pkg/agentic/transport.go index 168c137..296bb30 100644 --- a/pkg/agentic/transport.go +++ b/pkg/agentic/transport.go @@ -1,8 +1,6 @@ // SPDX-License-Identifier: EUPL-1.2 // HTTP transport for Core API streams. -// This is the ONE file in core/agent that imports net/http. -// All other files use the exported helpers: HTTPGet, HTTPPost, HTTPCall. package agentic @@ -26,10 +24,8 @@ type httpStream struct { response []byte } -// Send issues the configured HTTP request and caches the response body for Receive. -// -// stream := &httpStream{client: defaultClient, url: "https://forge.lthn.ai/api/v1/version", method: "GET"} -// _ = stream.Send(nil) +// stream := &httpStream{client: defaultClient, url: "https://forge.lthn.ai/api/v1/version", method: "GET"} +// _ = stream.Send(nil) func (s *httpStream) Send(data []byte) error { request, err := http.NewRequestWithContext(context.Background(), s.method, s.url, core.NewReader(string(data))) if err != nil { @@ -55,26 +51,20 @@ func (s *httpStream) Send(data []byte) error { return nil } -// Receive returns the cached response body from the last Send call. -// -// stream := &httpStream{response: []byte(`{"ok":true}`)} -// data, _ := stream.Receive() -// _ = data +// stream := &httpStream{response: []byte(`{"ok":true}`)} +// data, _ := stream.Receive() +// _ = data func (s *httpStream) Receive() ([]byte, error) { return s.response, nil } -// Close satisfies core.Stream for one-shot HTTP requests. -// -// stream := &httpStream{} -// _ = stream.Close() +// stream := &httpStream{} +// _ = stream.Close() func (s *httpStream) Close() error { return nil } -// RegisterHTTPTransport registers the HTTP/HTTPS protocol handler with Core API. -// -// agentic.RegisterHTTPTransport(c) +// agentic.RegisterHTTPTransport(c) func RegisterHTTPTransport(c *core.Core) { factory := func(handle *core.DriveHandle) (core.Stream, error) { token := handle.Options.String("token") @@ -89,50 +79,32 @@ func RegisterHTTPTransport(c *core.Core) { c.API().RegisterProtocol("https", factory) } -// --- REST helpers — all HTTP in core/agent routes through these --- - -// HTTPGet performs a GET request. Returns Result{Value: string (response body), OK: bool}. -// Auth is "token {token}" for Forge, "Bearer {token}" for Brain. -// -// result := agentic.HTTPGet(ctx, "https://forge.lthn.ai/api/v1/repos", "my-token", "token") +// result := agentic.HTTPGet(ctx, "https://forge.lthn.ai/api/v1/repos", "my-token", "token") func HTTPGet(ctx context.Context, url, token, authScheme string) core.Result { return httpDo(ctx, "GET", url, "", token, authScheme) } -// HTTPPost performs a POST request with a JSON body. Returns Result{Value: string, OK: bool}. -// -// result := agentic.HTTPPost(ctx, url, core.JSONMarshalString(payload), token, "token") +// result := agentic.HTTPPost(ctx, url, core.JSONMarshalString(payload), token, "token") func HTTPPost(ctx context.Context, url, body, token, authScheme string) core.Result { return httpDo(ctx, "POST", url, body, token, authScheme) } -// HTTPPatch performs a PATCH request with a JSON body. -// -// result := agentic.HTTPPatch(ctx, url, body, token, "token") +// result := agentic.HTTPPatch(ctx, url, body, token, "token") func HTTPPatch(ctx context.Context, url, body, token, authScheme string) core.Result { return httpDo(ctx, "PATCH", url, body, token, authScheme) } -// HTTPDelete performs a DELETE request. -// -// result := agentic.HTTPDelete(ctx, url, body, token, "Bearer") +// result := agentic.HTTPDelete(ctx, url, body, token, "Bearer") func HTTPDelete(ctx context.Context, url, body, token, authScheme string) core.Result { return httpDo(ctx, "DELETE", url, body, token, authScheme) } -// HTTPDo performs an HTTP request with the specified method. -// -// result := agentic.HTTPDo(ctx, "PUT", url, body, token, "token") +// result := agentic.HTTPDo(ctx, "PUT", url, body, token, "token") func HTTPDo(ctx context.Context, method, url, body, token, authScheme string) core.Result { return httpDo(ctx, method, url, body, token, authScheme) } -// --- Drive-aware REST helpers — route through c.Drive() for endpoint resolution --- - -// DriveGet performs a GET request using a named Drive endpoint. -// Reads base URL and token from the Drive handle registered in Core. -// -// result := DriveGet(c, "forge", "/api/v1/repos/core/go-io", "token") +// result := DriveGet(c, "forge", "/api/v1/repos/core/go-io", "token") func DriveGet(c *core.Core, drive, path, authScheme string) core.Result { base, token := driveEndpoint(c, drive) if base == "" { @@ -141,9 +113,7 @@ func DriveGet(c *core.Core, drive, path, authScheme string) core.Result { return httpDo(context.Background(), "GET", core.Concat(base, path), "", token, authScheme) } -// DrivePost performs a POST request using a named Drive endpoint. -// -// result := DrivePost(c, "forge", "/api/v1/repos/core/go-io/issues", body, "token") +// result := DrivePost(c, "forge", "/api/v1/repos/core/go-io/issues", body, "token") func DrivePost(c *core.Core, drive, path, body, authScheme string) core.Result { base, token := driveEndpoint(c, drive) if base == "" { @@ -152,9 +122,7 @@ func DrivePost(c *core.Core, drive, path, body, authScheme string) core.Result { return httpDo(context.Background(), "POST", core.Concat(base, path), body, token, authScheme) } -// DriveDo performs an HTTP request using a named Drive endpoint. -// -// result := DriveDo(c, "forge", "PATCH", "/api/v1/repos/core/go-io/pulls/5", body, "token") +// result := DriveDo(c, "forge", "PATCH", "/api/v1/repos/core/go-io/pulls/5", body, "token") func DriveDo(c *core.Core, drive, method, path, body, authScheme string) core.Result { base, token := driveEndpoint(c, drive) if base == "" { @@ -163,7 +131,6 @@ func DriveDo(c *core.Core, drive, method, path, body, authScheme string) core.Re return httpDo(context.Background(), method, core.Concat(base, path), body, token, authScheme) } -// driveEndpoint reads base URL and token from a named Drive handle. func driveEndpoint(c *core.Core, name string) (base, token string) { driveResult := c.Drive().Get(name) if !driveResult.OK { @@ -173,7 +140,6 @@ func driveEndpoint(c *core.Core, name string) (base, token string) { return driveHandle.Transport, driveHandle.Options.String("token") } -// httpDo is the single HTTP execution point. Every HTTP call in core/agent routes here. func httpDo(ctx context.Context, method, url, body, token, authScheme string) core.Result { var request *http.Request var err error @@ -210,10 +176,7 @@ func httpDo(ctx context.Context, method, url, body, token, authScheme string) co return core.Result{Value: readResult.Value.(string), OK: response.StatusCode < 400} } -// --- MCP Streamable HTTP Transport --- - -// mcpInitialize performs the MCP initialise handshake over Streamable HTTP. -// Returns the session ID from the Mcp-Session-Id header. +// sessionID, err := mcpInitialize(ctx, url, token) func mcpInitialize(ctx context.Context, url, token string) (string, error) { result := mcpInitializeResult(ctx, url, token) if !result.OK { @@ -285,7 +248,6 @@ func mcpInitializeResult(ctx context.Context, url, token string) core.Result { return core.Result{Value: sessionID, OK: true} } -// mcpCall sends a JSON-RPC request and returns the parsed response. func mcpCall(ctx context.Context, url, token, sessionID string, body []byte) ([]byte, error) { result := mcpCallResult(ctx, url, token, sessionID, body) if !result.OK { @@ -322,7 +284,6 @@ func mcpCallResult(ctx context.Context, url, token, sessionID string, body []byt return readSSEDataResult(response) } -// readSSEData reads an SSE response and extracts JSON from data: lines. func readSSEData(response *http.Response) ([]byte, error) { result := readSSEDataResult(response) if !result.OK { @@ -339,7 +300,6 @@ func readSSEData(response *http.Response) ([]byte, error) { return data, nil } -// readSSEDataResult parses an SSE response and extracts the first data: payload as core.Result. func readSSEDataResult(response *http.Response) core.Result { readResult := core.ReadAll(response.Body) if !readResult.OK { @@ -354,7 +314,6 @@ func readSSEDataResult(response *http.Response) core.Result { return core.Result{Value: core.E("readSSEData", "no data in SSE response", nil), OK: false} } -// mcpHeaders applies standard MCP HTTP headers. func mcpHeaders(request *http.Request, token, sessionID string) { request.Header.Set("Content-Type", "application/json") request.Header.Set("Accept", "application/json, text/event-stream") @@ -366,7 +325,6 @@ func mcpHeaders(request *http.Request, token, sessionID string) { } } -// drainSSE reads and discards an SSE response body. func drainSSE(response *http.Response) { core.ReadAll(response.Body) } diff --git a/pkg/brain/tools.go b/pkg/brain/tools.go index 6999c02..3fc18a1 100644 --- a/pkg/brain/tools.go +++ b/pkg/brain/tools.go @@ -11,11 +11,9 @@ import ( "github.com/modelcontextprotocol/go-sdk/mcp" ) -// -- Input/Output types ------------------------------------------------------- - // input := brain.RememberInput{ -// Content: "Use core.Env for system paths.", -// Type: "convention", +// Content: "Use core.Env for system paths.", +// Type: "convention", // } type RememberInput struct { Content string `json:"content"` @@ -28,8 +26,8 @@ type RememberInput struct { } // output := brain.RememberOutput{ -// Success: true, -// MemoryID: "mem_123", +// Success: true, +// MemoryID: "mem_123", // } type RememberOutput struct { Success bool `json:"success"` @@ -38,8 +36,8 @@ type RememberOutput struct { } // input := brain.RecallInput{ -// Query: "core.Env conventions", -// TopK: 5, +// Query: "core.Env conventions", +// TopK: 5, // } type RecallInput struct { Query string `json:"query"` @@ -48,8 +46,8 @@ type RecallInput struct { } // filter := brain.RecallFilter{ -// Project: "agent", -// Type: "convention", +// Project: "agent", +// Type: "convention", // } type RecallFilter struct { Project string `json:"project,omitempty"` @@ -59,8 +57,8 @@ type RecallFilter struct { } // output := brain.RecallOutput{ -// Success: true, -// Count: 1, +// Success: true, +// Count: 1, // } type RecallOutput struct { Success bool `json:"success"` @@ -69,9 +67,9 @@ type RecallOutput struct { } // memory := brain.Memory{ -// ID: "mem_123", -// Type: "convention", -// Content: "Use core.Env for system paths.", +// ID: "mem_123", +// Type: "convention", +// Content: "Use core.Env for system paths.", // } type Memory struct { ID string `json:"id"` @@ -88,8 +86,8 @@ type Memory struct { } // input := brain.ForgetInput{ -// ID: "mem_123", -// Reason: "superseded", +// ID: "mem_123", +// Reason: "superseded", // } type ForgetInput struct { ID string `json:"id"` @@ -97,8 +95,8 @@ type ForgetInput struct { } // output := brain.ForgetOutput{ -// Success: true, -// Forgotten: "mem_123", +// Success: true, +// Forgotten: "mem_123", // } type ForgetOutput struct { Success bool `json:"success"` @@ -107,8 +105,8 @@ type ForgetOutput struct { } // input := brain.ListInput{ -// Project: "agent", -// Limit: 20, +// Project: "agent", +// Limit: 20, // } type ListInput struct { Project string `json:"project,omitempty"` @@ -118,8 +116,8 @@ type ListInput struct { } // output := brain.ListOutput{ -// Success: true, -// Count: 2, +// Success: true, +// Count: 2, // } type ListOutput struct { Success bool `json:"success"` @@ -127,8 +125,6 @@ type ListOutput struct { Memories []Memory `json:"memories"` } -// -- Tool registration -------------------------------------------------------- - func (s *Subsystem) registerBrainTools(server *mcp.Server) { mcp.AddTool(server, &mcp.Tool{ Name: "brain_remember", @@ -151,8 +147,6 @@ func (s *Subsystem) registerBrainTools(server *mcp.Server) { }, s.brainList) } -// -- Tool handlers ------------------------------------------------------------ - func (s *Subsystem) brainRemember(_ context.Context, _ *mcp.CallToolRequest, input RememberInput) (*mcp.CallToolResult, RememberOutput, error) { if s.bridge == nil { return nil, RememberOutput{}, errBridgeNotAvailable diff --git a/pkg/lib/lib.go b/pkg/lib/lib.go index b421fca..3129dc6 100644 --- a/pkg/lib/lib.go +++ b/pkg/lib/lib.go @@ -125,12 +125,8 @@ func mountEmbed(filesystem embed.FS, baseDir string) core.Result { } } -// --- Prompts --- - -// Template tries Prompt then Task (backwards compat). -// -// r := lib.Template("coding") -// if r.OK { content := r.Value.(string) } +// r := lib.Template("coding") +// if r.OK { content := r.Value.(string) } func Template(slug string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -141,10 +137,8 @@ func Template(slug string) core.Result { return Task(slug) } -// Prompt reads a system prompt by slug. -// -// r := lib.Prompt("coding") -// if r.OK { content := r.Value.(string) } +// r := lib.Prompt("coding") +// if r.OK { content := r.Value.(string) } func Prompt(slug string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -152,10 +146,8 @@ func Prompt(slug string) core.Result { return promptFS.ReadString(core.Concat(slug, ".md")) } -// Task reads a structured task plan by slug. Tries .md, .yaml, .yml. -// -// r := lib.Task("code/review") -// if r.OK { content := r.Value.(string) } +// r := lib.Task("code/review") +// if r.OK { content := r.Value.(string) } func Task(slug string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -180,10 +172,8 @@ type Bundle struct { Files map[string]string } -// TaskBundle reads a task and its companion files. -// -// r := lib.TaskBundle("code/review") -// if r.OK { b := r.Value.(lib.Bundle) } +// r := lib.TaskBundle("code/review") +// if r.OK { b := r.Value.(lib.Bundle) } func TaskBundle(slug string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -212,10 +202,8 @@ func TaskBundle(slug string) core.Result { return core.Result{Value: b, OK: true} } -// Flow reads a build/release workflow by slug. -// -// r := lib.Flow("go") -// if r.OK { content := r.Value.(string) } +// r := lib.Flow("go") +// if r.OK { content := r.Value.(string) } func Flow(slug string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -223,10 +211,8 @@ func Flow(slug string) core.Result { return flowFS.ReadString(core.Concat(slug, ".md")) } -// Persona reads a domain/role persona by path. -// -// r := lib.Persona("secops/developer") -// if r.OK { content := r.Value.(string) } +// r := lib.Persona("secops/developer") +// if r.OK { content := r.Value.(string) } func Persona(path string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -234,8 +220,6 @@ func Persona(path string) core.Result { return personaFS.ReadString(core.Concat(path, ".md")) } -// --- Workspace Templates --- - // WorkspaceData is the data passed to workspace templates. // // data := &lib.WorkspaceData{ @@ -259,13 +243,11 @@ type WorkspaceData struct { TestCmd string } -// ExtractWorkspace creates an agent workspace from a template. -// Template names: "default", "security", "review". -// // r := lib.ExtractWorkspace("default", "/tmp/ws", &lib.WorkspaceData{ // Repo: "go-io", Task: "fix tests", Agent: "codex", // }) -// core.Println(r.OK) +// +// core.Println(r.OK) func ExtractWorkspace(templateName, targetDir string, data *WorkspaceData) core.Result { if result := ensureMounted(); !result.OK { if err, ok := result.Value.(error); ok { @@ -309,11 +291,8 @@ func ExtractWorkspace(templateName, targetDir string, data *WorkspaceData) core. return core.Result{Value: targetDir, OK: true} } -// WorkspaceFile reads a single file from a workspace template. -// Returns the file content as a string. -// -// r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl") -// if r.OK { content := r.Value.(string) } +// r := lib.WorkspaceFile("default", "CODEX-PHP.md.tmpl") +// if r.OK { content := r.Value.(string) } func WorkspaceFile(templateName, filename string) core.Result { if result := ensureMounted(); !result.OK { return result @@ -326,26 +305,16 @@ func WorkspaceFile(templateName, filename string) core.Result { return embed.ReadString(filename) } -// --- List Functions --- - -// ListPrompts returns available system prompt slugs. -// -// prompts := lib.ListPrompts() // ["coding", "review", ...] +// prompts := lib.ListPrompts() // ["coding", "review", ...] func ListPrompts() []string { return listNames("prompt") } -// ListFlows returns available build/release flow slugs. -// -// flows := lib.ListFlows() // ["go", "php", "node", ...] +// flows := lib.ListFlows() // ["go", "php", "node", ...] func ListFlows() []string { return listNames("flow") } -// ListWorkspaces returns available workspace template names. -// -// templates := lib.ListWorkspaces() // ["default", "security", ...] +// templates := lib.ListWorkspaces() // ["default", "security", ...] func ListWorkspaces() []string { return listNames("workspace") } -// ListTasks returns available task plan slugs, including nested paths. -// -// tasks := lib.ListTasks() // ["bug-fix", "code/review", "code/refactor", ...] +// tasks := lib.ListTasks() // ["bug-fix", "code/review", "code/refactor", ...] func ListTasks() []string { if result := ensureMounted(); !result.OK { return nil @@ -357,9 +326,7 @@ func ListTasks() []string { return names.AsSlice() } -// ListPersonas returns available persona paths, including nested directories. -// -// personas := lib.ListPersonas() // ["code/go", "secops/developer", ...] +// personas := lib.ListPersonas() // ["code/go", "secops/developer", ...] func ListPersonas() []string { if result := ensureMounted(); !result.OK { return nil diff --git a/pkg/messages/messages.go b/pkg/messages/messages.go index 6805d16..d943cac 100644 --- a/pkg/messages/messages.go +++ b/pkg/messages/messages.go @@ -3,8 +3,6 @@ // c.ACTION(messages.AgentCompleted{Agent: "codex", Repo: "go-io", Status: "completed"}) package messages -// --- Agent Lifecycle --- - // c.ACTION(messages.AgentStarted{Agent: "codex", Repo: "go-io", Workspace: "core/go-io/task-5"}) type AgentStarted struct { Agent string @@ -20,8 +18,6 @@ type AgentCompleted struct { Status string // completed, failed, blocked } -// --- QA & PR Pipeline --- - // c.ACTION(messages.QAResult{Workspace: "core/go-io/task-5", Repo: "go-io", Passed: true}) type QAResult struct { Workspace string @@ -53,8 +49,6 @@ type PRNeedsReview struct { Reason string } -// --- Queue --- - // c.ACTION(messages.QueueDrained{Completed: 3}) type QueueDrained struct { Completed int @@ -76,8 +70,6 @@ type RateLimitDetected struct { Duration string } -// --- Monitor Events --- - // c.ACTION(messages.HarvestComplete{Repo: "go-io", Branch: "agent/fix-tests", Files: 5}) type HarvestComplete struct { Repo string diff --git a/pkg/monitor/harvest.go b/pkg/monitor/harvest.go index b01d8a0..50a2117 100644 --- a/pkg/monitor/harvest.go +++ b/pkg/monitor/harvest.go @@ -1,10 +1,7 @@ // SPDX-License-Identifier: EUPL-1.2 // result := m.harvestWorkspace("/srv/.core/workspace/core/go-io/task-5") -// if result != nil && result.rejected == "" { /* ready-for-review */ } -// -// Completed workspaces are scanned, validated, and marked ready for review. -// The code does not auto-push; review remains an explicit action. +// if result != nil && result.rejected == "" { core.Print(nil, "%s", result.repo) } package monitor @@ -17,7 +14,6 @@ import ( core "dappco.re/go/core" ) -// harvestResult tracks what happened during harvest. type harvestResult struct { repo string branch string @@ -60,7 +56,7 @@ func (m *Subsystem) harvestCompleted() string { } // result := m.harvestWorkspace("/srv/.core/workspace/core/go-io/task-5") -// if result != nil && result.rejected == "" { /* ready-for-review */ } +// if result != nil && result.rejected == "" { core.Print(nil, "%s", result.repo) } func (m *Subsystem) harvestWorkspace(workspaceDir string) *harvestResult { statusResult := fs.Read(agentic.WorkspaceStatusPath(workspaceDir)) if !statusResult.OK { @@ -245,9 +241,7 @@ func (m *Subsystem) pushBranch(repoDir, branch string) error { return nil } -// updateStatus rewrites status.json after a harvest decision. -// -// updateStatus(workspaceDir, "ready-for-review", "") +// updateStatus(workspaceDir, "ready-for-review", "") func updateStatus(workspaceDir, status, question string) { statusResult := fs.Read(agentic.WorkspaceStatusPath(workspaceDir)) if !statusResult.OK { diff --git a/pkg/runner/paths.go b/pkg/runner/paths.go index 97bac78..d9b66ba 100644 --- a/pkg/runner/paths.go +++ b/pkg/runner/paths.go @@ -9,7 +9,7 @@ import ( core "dappco.re/go/core" ) -// fs reuses the shared unrestricted filesystem used by agentic. +// fs := agentic.LocalFs() var fs = agentic.LocalFs() func runnerWorkspaceStatusFromAgentic(status *agentic.WorkspaceStatus) *WorkspaceStatus { diff --git a/pkg/runner/queue.go b/pkg/runner/queue.go index c958d3a..31a2075 100644 --- a/pkg/runner/queue.go +++ b/pkg/runner/queue.go @@ -11,10 +11,8 @@ import ( "gopkg.in/yaml.v3" ) -// DispatchConfig mirrors the `dispatch:` block in `agents.yaml`. -// // config := runner.DispatchConfig{ -// DefaultAgent: "codex", DefaultTemplate: "coding", WorkspaceRoot: "/srv/core/workspace", +// DefaultAgent: "codex", DefaultTemplate: "coding", WorkspaceRoot: "/srv/core/workspace", // } type DispatchConfig struct { DefaultAgent string `yaml:"default_agent"` @@ -22,10 +20,8 @@ type DispatchConfig struct { WorkspaceRoot string `yaml:"workspace_root"` } -// RateConfig mirrors one agent pool under `rates:` in `agents.yaml`. -// // rate := runner.RateConfig{ -// ResetUTC: "06:00", DailyLimit: 200, SustainedDelay: 120, BurstWindow: 2, BurstDelay: 300, +// ResetUTC: "06:00", DailyLimit: 200, SustainedDelay: 120, BurstWindow: 2, BurstDelay: 300, // } type RateConfig struct { ResetUTC string `yaml:"reset_utc"` @@ -47,10 +43,8 @@ type ConcurrencyLimit struct { Models map[string]int } -// UnmarshalYAML handles both int and map forms for concurrency limits. -// -// var limit ConcurrencyLimit -// _ = yaml.Unmarshal([]byte("total: 5\ngpt-5.4: 1\n"), &limit) +// var limit ConcurrencyLimit +// _ = yaml.Unmarshal([]byte("total: 5\ngpt-5.4: 1\n"), &limit) func (c *ConcurrencyLimit) UnmarshalYAML(value *yaml.Node) error { var n int if err := value.Decode(&n); err == nil { @@ -71,11 +65,9 @@ func (c *ConcurrencyLimit) UnmarshalYAML(value *yaml.Node) error { return nil } -// AgentsConfig mirrors the full `agents.yaml` file. -// // config := runner.AgentsConfig{ -// Version: 1, -// Dispatch: runner.DispatchConfig{DefaultAgent: "codex", DefaultTemplate: "coding"}, +// Version: 1, +// Dispatch: runner.DispatchConfig{DefaultAgent: "codex", DefaultTemplate: "coding"}, // } type AgentsConfig struct { Version int `yaml:"version"` @@ -84,10 +76,8 @@ type AgentsConfig struct { Rates map[string]RateConfig `yaml:"rates"` } -// loadAgentsConfig reads `agents.yaml` from the Core root. -// -// config := s.loadAgentsConfig() -// core.Println(config.Dispatch.DefaultAgent) +// config := s.loadAgentsConfig() +// core.Println(config.Dispatch.DefaultAgent) func (s *Service) loadAgentsConfig() *AgentsConfig { paths := []string{ core.JoinPath(CoreRoot(), "agents.yaml"), @@ -115,9 +105,7 @@ func (s *Service) loadAgentsConfig() *AgentsConfig { } } -// canDispatchAgent checks both pool-level and per-model concurrency limits. -// -// if !s.canDispatchAgent("codex") { /* queue it */ } +// if can, reason := s.canDispatchAgent("codex"); !can { _ = reason } func (s *Service) canDispatchAgent(agent string) (bool, string) { var concurrency map[string]ConcurrencyLimit if s.ServiceRuntime != nil { @@ -157,9 +145,7 @@ func (s *Service) canDispatchAgent(agent string) (bool, string) { return true, "" } -// countRunningByAgent counts running workspaces using the in-memory Registry. -// -// n := s.countRunningByAgent("codex") +// n := s.countRunningByAgent("codex") func (s *Service) countRunningByAgent(agent string) int { var runtime *core.Core if s.ServiceRuntime != nil { @@ -180,9 +166,7 @@ func (s *Service) countRunningByAgent(agent string) int { return count } -// countRunningByModel counts running workspaces for a specific `agent:model`. -// -// n := s.countRunningByModel("codex:gpt-5.4") +// n := s.countRunningByModel("codex:gpt-5.4") func (s *Service) countRunningByModel(agent string) int { var runtime *core.Core if s.ServiceRuntime != nil { @@ -203,9 +187,7 @@ func (s *Service) countRunningByModel(agent string) int { return count } -// drainQueue fills any free concurrency slots from queued workspaces. -// -// s.drainQueue() +// s.drainQueue() func (s *Service) drainQueue() { if s.frozen { return @@ -336,8 +318,6 @@ func (s *Service) delayForAgent(agent string) time.Duration { return time.Duration(rate.SustainedDelay) * time.Second } -// --- Helpers --- - func baseAgent(agent string) string { return core.SplitN(agent, ":", 2)[0] } diff --git a/pkg/runner/runner.go b/pkg/runner/runner.go index 5f7bc25..97cb99c 100644 --- a/pkg/runner/runner.go +++ b/pkg/runner/runner.go @@ -250,8 +250,6 @@ func (s *Service) handleWorkspaceQuery(_ *core.Core, query core.Query) core.Resu return core.Result{Value: s.workspaces, OK: true} } -// --- Actions --- - func (s *Service) actionDispatch(_ context.Context, options core.Options) core.Result { if s.frozen { return core.Result{Value: core.E("runner.actionDispatch", "queue is frozen", nil), OK: false} @@ -342,8 +340,6 @@ func (s *Service) actionPoke(_ context.Context, _ core.Options) core.Result { return core.Result{OK: true} } -// --- Queue runner --- - func (s *Service) startRunner() { s.pokeCh = make(chan struct{}, 1) @@ -369,8 +365,6 @@ func (s *Service) runLoop() { } } -// --- Workspace hydration --- - func (s *Service) hydrateWorkspaces() { if s.workspaces == nil { s.workspaces = core.NewRegistry[*WorkspaceStatus]() @@ -392,8 +386,6 @@ func (s *Service) hydrateWorkspaces() { } } -// --- Types --- - // AgentNotification is the channel payload sent on `agent.status`. // // n := runner.AgentNotification{ @@ -419,9 +411,7 @@ type WorkspaceQuery struct { Status string } -// WorkspaceStatus tracks the state of an agent workspace. -// -// workspaceStatus := &runner.WorkspaceStatus{Status: "running", Agent: "codex", Repo: "go-io", PID: 12345} +// workspaceStatus := &runner.WorkspaceStatus{Status: "running", Agent: "codex", Repo: "go-io", PID: 12345} type WorkspaceStatus struct { Status string `json:"status"` Agent string `json:"agent"`