diff --git a/pkg/agentic/commands.go b/pkg/agentic/commands.go index 2cc1245..629c987 100644 --- a/pkg/agentic/commands.go +++ b/pkg/agentic/commands.go @@ -277,31 +277,12 @@ func (s *PrepSubsystem) runDispatchLoop(label string) core.Result { func (s *PrepSubsystem) cmdPrep(options core.Options) core.Result { repo := options.String("_arg") if repo == "" { - core.Print(nil, "usage: core-agent prep --issue=N|--pr=N|--branch=X --task=\"...\"") + core.Print(nil, "usage: core-agent prep --issue=N|--pr=N|--branch=X --task=\"...\" [--plan-template=bug-fix] [--variables='{\"key\":\"value\"}']") return core.Result{Value: core.E("agentic.cmdPrep", "repo is required", nil), OK: false} } - prepInput := PrepInput{ - Repo: repo, - Org: options.String("org"), - Task: options.String("task"), - Template: options.String("template"), - Persona: options.String("persona"), - DryRun: options.Bool("dry-run"), - } - - if value := options.String("issue"); value != "" { - prepInput.Issue = parseIntString(value) - } - if value := options.String("pr"); value != "" { - prepInput.PR = parseIntString(value) - } - if value := options.String("branch"); value != "" { - prepInput.Branch = value - } - if value := options.String("tag"); value != "" { - prepInput.Tag = value - } + prepInput := prepInputFromCommandOptions(options) + prepInput.Repo = repo if prepInput.Issue == 0 && prepInput.PR == 0 && prepInput.Branch == "" && prepInput.Tag == "" { prepInput.Branch = "dev" @@ -715,28 +696,20 @@ func (s *PrepSubsystem) cmdStatus(options core.Options) core.Result { func (s *PrepSubsystem) cmdPrompt(options core.Options) core.Result { repo := options.String("_arg") if repo == "" { - core.Print(nil, "usage: core-agent prompt --task=\"...\"") + core.Print(nil, "usage: core-agent prompt --task=\"...\" [--plan-template=bug-fix] [--variables='{\"key\":\"value\"}']") return core.Result{Value: core.E("agentic.cmdPrompt", "repo is required", nil), OK: false} } - org := options.String("org") - if org == "" { - org = "core" + prepInput := prepInputFromCommandOptions(options) + prepInput.Repo = repo + if prepInput.Org == "" { + prepInput.Org = "core" } - task := options.String("task") - if task == "" { - task = "Review and report findings" + if prepInput.Task == "" { + prepInput.Task = "Review and report findings" } - repoPath := core.JoinPath(HomeDir(), "Code", org, repo) - - prepInput := PrepInput{ - Repo: repo, - Org: org, - Task: task, - Template: options.String("template"), - Persona: options.String("persona"), - } + repoPath := core.JoinPath(HomeDir(), "Code", prepInput.Org, prepInput.Repo) prompt, memories, consumers := s.BuildPrompt(context.Background(), prepInput, "dev", repoPath) core.Print(nil, "memories: %d", memories) @@ -746,6 +719,16 @@ func (s *PrepSubsystem) cmdPrompt(options core.Options) core.Result { return core.Result{OK: true} } +func prepInputFromCommandOptions(options core.Options) PrepInput { + commandOptions := core.NewOptions(options.Items()...) + if commandOptions.String("repo") == "" { + if repo := optionStringValue(options, "_arg"); repo != "" { + commandOptions.Set("repo", repo) + } + } + return prepInputFromOptions(commandOptions) +} + func (s *PrepSubsystem) cmdPromptVersion(options core.Options) core.Result { workspace := optionStringValue(options, "workspace", "_arg") if workspace == "" { diff --git a/pkg/agentic/commands_test.go b/pkg/agentic/commands_test.go index 84631eb..cfc683a 100644 --- a/pkg/agentic/commands_test.go +++ b/pkg/agentic/commands_test.go @@ -967,6 +967,29 @@ func TestCommands_CmdPrompt_Good_DefaultTask(t *testing.T) { assert.True(t, r.OK) } +func TestCommands_CmdPrompt_Good_PlanTemplateVariables(t *testing.T) { + home := t.TempDir() + t.Setenv("CORE_HOME", home) + + repoDir := core.JoinPath(home, "Code", "core", "go-io") + fs.EnsureDir(repoDir) + fs.Write(core.JoinPath(repoDir, "go.mod"), "module example.com/go-io\n\ngo 1.24\n") + + s, _ := testPrepWithCore(t, nil) + output := captureStdout(t, func() { + r := s.cmdPrompt(core.NewOptions( + core.Option{Key: "_arg", Value: "go-io"}, + core.Option{Key: "task", Value: "Add a login flow"}, + core.Option{Key: "plan_template", Value: "new-feature"}, + core.Option{Key: "variables", Value: `{"feature_name":"Authentication"}`}, + )) + assert.True(t, r.OK) + }) + + assert.Contains(t, output, "PLAN:") + assert.Contains(t, output, "Authentication") +} + func TestCommands_CmdGenerate_Bad_MissingPrompt(t *testing.T) { s, _ := testPrepWithCore(t, nil) r := s.cmdGenerate(core.NewOptions()) @@ -1483,6 +1506,8 @@ func TestCommands_CmdPrep_Ugly_AllOptionalFields(t *testing.T) { core.Option{Key: "tag", Value: "v1.0.0"}, core.Option{Key: "task", Value: "do stuff"}, core.Option{Key: "template", Value: "coding"}, + core.Option{Key: "plan_template", Value: "new-feature"}, + core.Option{Key: "variables", Value: `{"feature_name":"Authentication"}`}, core.Option{Key: "persona", Value: "engineering"}, core.Option{Key: "dry-run", Value: "true"}, ))