diff --git a/pkg/agentic/commands_workspace.go b/pkg/agentic/commands_workspace.go index 2f71b40..10be260 100644 --- a/pkg/agentic/commands_workspace.go +++ b/pkg/agentic/commands_workspace.go @@ -92,22 +92,12 @@ func (s *PrepSubsystem) cmdWorkspaceClean(options core.Options) core.Result { // input := DispatchInput{Repo: "go-io", Task: "Fix the failing tests", Issue: 12} func (s *PrepSubsystem) cmdWorkspaceDispatch(options core.Options) core.Result { - repo := options.String("_arg") - if repo == "" { - core.Print(nil, "usage: core-agent workspace dispatch --task=\"...\" --issue=N|--pr=N|--branch=X [--agent=codex]") + input := workspaceDispatchInputFromOptions(options) + if input.Repo == "" { + core.Print(nil, "usage: core-agent workspace dispatch --task=\"...\" --issue=N|--pr=N|--branch=X [--agent=codex] [--template=coding] [--plan-template=bug-fix] [--persona=code/reviewer] [--tag=v0.8.0] [--dry-run]") return core.Result{Value: core.E("agentic.cmdWorkspaceDispatch", "repo is required", nil), OK: false} } - input := DispatchInput{ - Repo: repo, - Task: options.String("task"), - Agent: options.String("agent"), - Org: options.String("org"), - Template: options.String("template"), - Branch: options.String("branch"), - Issue: parseIntString(options.String("issue")), - PR: parseIntString(options.String("pr")), - } _, out, err := s.dispatch(context.Background(), nil, input) if err != nil { core.Print(nil, "dispatch failed: %s", err.Error()) @@ -117,7 +107,7 @@ func (s *PrepSubsystem) cmdWorkspaceDispatch(options core.Options) core.Result { if agent == "" { agent = "codex" } - core.Print(nil, "dispatched %s to %s", agent, repo) + core.Print(nil, "dispatched %s to %s", agent, input.Repo) if out.WorkspaceDir != "" { core.Print(nil, " workspace: %s", out.WorkspaceDir) } @@ -126,3 +116,13 @@ func (s *PrepSubsystem) cmdWorkspaceDispatch(options core.Options) core.Result { } return core.Result{OK: true} } + +func workspaceDispatchInputFromOptions(options core.Options) DispatchInput { + dispatchOptions := core.NewOptions(options.Items()...) + if dispatchOptions.String("repo") == "" { + if repo := optionStringValue(options, "_arg", "repo"); repo != "" { + dispatchOptions.Set("repo", repo) + } + } + return dispatchInputFromOptions(dispatchOptions) +} diff --git a/pkg/agentic/commands_workspace_test.go b/pkg/agentic/commands_workspace_test.go index ceec326..160e98a 100644 --- a/pkg/agentic/commands_workspace_test.go +++ b/pkg/agentic/commands_workspace_test.go @@ -157,3 +157,35 @@ func TestCommandsworkspace_CmdWorkspaceDispatch_Ugly_AllFieldsSet(t *testing.T) // The test verifies the CLI correctly passes all fields through to dispatch. assert.False(t, r.OK) } + +func TestCommandsworkspace_WorkspaceDispatchInputFromOptions_Good_MapsFullContract(t *testing.T) { + input := workspaceDispatchInputFromOptions(core.NewOptions( + core.Option{Key: "_arg", Value: "go-io"}, + core.Option{Key: "task", Value: "ship the release"}, + core.Option{Key: "agent", Value: "codex:gpt-5.4"}, + core.Option{Key: "org", Value: "core"}, + core.Option{Key: "template", Value: "coding"}, + core.Option{Key: "plan_template", Value: "bug-fix"}, + core.Option{Key: "variables", Value: map[string]any{"ISSUE": 42, "MODE": "deep"}}, + core.Option{Key: "persona", Value: "code/reviewer"}, + core.Option{Key: "issue", Value: "42"}, + core.Option{Key: "pr", Value: 7}, + core.Option{Key: "branch", Value: "feature/release"}, + core.Option{Key: "tag", Value: "v0.8.0"}, + core.Option{Key: "dry_run", Value: true}, + )) + + assert.Equal(t, "go-io", input.Repo) + assert.Equal(t, "ship the release", input.Task) + assert.Equal(t, "codex:gpt-5.4", input.Agent) + assert.Equal(t, "core", input.Org) + assert.Equal(t, "coding", input.Template) + assert.Equal(t, "bug-fix", input.PlanTemplate) + assert.Equal(t, map[string]string{"ISSUE": "42", "MODE": "deep"}, input.Variables) + assert.Equal(t, "code/reviewer", input.Persona) + assert.Equal(t, 42, input.Issue) + assert.Equal(t, 7, input.PR) + assert.Equal(t, "feature/release", input.Branch) + assert.Equal(t, "v0.8.0", input.Tag) + assert.True(t, input.DryRun) +}