diff --git a/pkg/agentic/commands.go b/pkg/agentic/commands.go index 7a48db2..042b012 100644 --- a/pkg/agentic/commands.go +++ b/pkg/agentic/commands.go @@ -300,7 +300,7 @@ func (s *PrepSubsystem) cmdBrainList(options core.Options) core.Result { return core.Result{Value: output, OK: true} } -func (s *PrepSubsystem) cmdStatus(_ core.Options) core.Result { +func (s *PrepSubsystem) cmdStatus(options core.Options) core.Result { workspaceRoot := WorkspaceRoot() filesystem := s.Core().Fs() listResult := filesystem.List(workspaceRoot) @@ -315,19 +315,36 @@ func (s *PrepSubsystem) cmdStatus(_ core.Options) core.Result { return core.Result{OK: true} } + requestedWorkspace := optionStringValue(options, "workspace", "_arg") + requestedStatus := optionStringValue(options, "status") + limit := optionIntValue(options, "limit") + matched := 0 + for _, sf := range statusFiles { workspaceDir := core.PathDir(sf) workspaceName := WorkspaceName(workspaceDir) + if !statusInputMatchesWorkspace(requestedWorkspace, workspaceDir, workspaceName) { + continue + } + result := ReadStatusResult(workspaceDir) workspaceStatus, ok := workspaceStatusValue(result) if !ok { continue } + if !statusInputMatchesStatus(requestedStatus, workspaceStatus.Status) { + continue + } + core.Print(nil, " %-8s %-8s %-10s %s", workspaceStatus.Status, workspaceStatus.Agent, workspaceStatus.Repo, workspaceName) if workspaceStatus.Question != "" { core.Print(nil, " question: %s", workspaceStatus.Question) } + matched++ + if limit > 0 && matched >= limit { + break + } } return core.Result{OK: true} } diff --git a/pkg/agentic/commands_test.go b/pkg/agentic/commands_test.go index 29abe69..71513e8 100644 --- a/pkg/agentic/commands_test.go +++ b/pkg/agentic/commands_test.go @@ -768,6 +768,68 @@ func TestCommands_CmdStatus_Good_BlockedQuestion(t *testing.T) { assert.Contains(t, output, "Which API version?") } +func TestCommands_CmdStatus_Good_WorkspaceFilter(t *testing.T) { + s, _ := testPrepWithCore(t, nil) + + wsA := core.JoinPath(WorkspaceRoot(), "core", "go-io", "task-9") + fs.EnsureDir(wsA) + fs.Write(core.JoinPath(wsA, "status.json"), core.JSONMarshalString(WorkspaceStatus{ + Status: "blocked", + Repo: "go-io", + Agent: "gemini", + })) + + wsB := core.JoinPath(WorkspaceRoot(), "core", "go-log", "task-4") + fs.EnsureDir(wsB) + fs.Write(core.JoinPath(wsB, "status.json"), core.JSONMarshalString(WorkspaceStatus{ + Status: "completed", + Repo: "go-log", + Agent: "codex", + })) + + output := captureStdout(t, func() { + r := s.cmdStatus(core.NewOptions(core.Option{Key: "workspace", Value: "core/go-io/task-9"})) + assert.True(t, r.OK) + }) + + assert.Contains(t, output, "core/go-io/task-9") + assert.NotContains(t, output, "core/go-log/task-4") +} + +func TestCommands_CmdStatus_Good_StatusFilterAndLimit(t *testing.T) { + s, _ := testPrepWithCore(t, nil) + + for _, workspace := range []struct { + name string + status string + repo string + }{ + {name: "ws-1", status: "blocked", repo: "go-io"}, + {name: "ws-2", status: "blocked", repo: "go-log"}, + {name: "ws-3", status: "completed", repo: "go-scm"}, + } { + ws := core.JoinPath(WorkspaceRoot(), workspace.name) + fs.EnsureDir(ws) + fs.Write(core.JoinPath(ws, "status.json"), core.JSONMarshalString(WorkspaceStatus{ + Status: workspace.status, + Repo: workspace.repo, + Agent: "codex", + })) + } + + output := captureStdout(t, func() { + r := s.cmdStatus(core.NewOptions( + core.Option{Key: "status", Value: "blocked"}, + core.Option{Key: "limit", Value: 1}, + )) + assert.True(t, r.OK) + }) + + assert.Contains(t, output, "ws-1") + assert.NotContains(t, output, "ws-2") + assert.NotContains(t, output, "ws-3") +} + func TestCommands_CmdPrompt_Bad_MissingRepo(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdPrompt(core.NewOptions())