diff --git a/pkg/agentic/commands_plan.go b/pkg/agentic/commands_plan.go index d926ffc..5478ddb 100644 --- a/pkg/agentic/commands_plan.go +++ b/pkg/agentic/commands_plan.go @@ -14,6 +14,7 @@ func (s *PrepSubsystem) registerPlanCommands() { c.Command("plan/show", core.Command{Description: "Show an implementation plan", Action: s.cmdPlanShow}) c.Command("plan/status", core.Command{Description: "Read or update an implementation plan status", Action: s.cmdPlanStatus}) c.Command("plan/archive", core.Command{Description: "Archive an implementation plan by slug or ID", Action: s.cmdPlanArchive}) + c.Command("plan/delete", core.Command{Description: "Delete an implementation plan by ID", Action: s.cmdPlanDelete}) } func (s *PrepSubsystem) cmdPlan(options core.Options) core.Result { @@ -193,3 +194,32 @@ func (s *PrepSubsystem) cmdPlanArchive(options core.Options) core.Result { core.Print(nil, "archived: %s", output.Archived) return core.Result{Value: output, OK: true} } + +func (s *PrepSubsystem) cmdPlanDelete(options core.Options) core.Result { + ctx := s.commandContext() + id := optionStringValue(options, "id", "_arg") + if id == "" { + core.Print(nil, "usage: core-agent plan delete [--reason=\"...\"]") + return core.Result{Value: core.E("agentic.cmdPlanDelete", "id is required", nil), OK: false} + } + + result := s.handlePlanDelete(ctx, core.NewOptions( + core.Option{Key: "id", Value: id}, + core.Option{Key: "reason", Value: optionStringValue(options, "reason")}, + )) + if !result.OK { + err := commandResultError("agentic.cmdPlanDelete", result) + core.Print(nil, "error: %v", err) + return core.Result{Value: err, OK: false} + } + + output, ok := result.Value.(PlanDeleteOutput) + if !ok { + err := core.E("agentic.cmdPlanDelete", "invalid plan delete output", nil) + core.Print(nil, "error: %v", err) + return core.Result{Value: err, OK: false} + } + + core.Print(nil, "deleted: %s", output.Deleted) + return core.Result{Value: output, OK: true} +} diff --git a/pkg/agentic/commands_test.go b/pkg/agentic/commands_test.go index c816448..854e752 100644 --- a/pkg/agentic/commands_test.go +++ b/pkg/agentic/commands_test.go @@ -961,6 +961,30 @@ func TestCommands_CmdPlanArchive_Good(t *testing.T) { assert.False(t, plan.ArchivedAt.IsZero()) } +func TestCommands_CmdPlanDelete_Good(t *testing.T) { + s, _ := testPrepWithCore(t, nil) + + _, created, err := s.planCreate(context.Background(), nil, PlanCreateInput{ + Title: "Delete Plan", + Objective: "Exercise delete command", + }) + require.NoError(t, err) + + output := captureStdout(t, func() { + r := s.cmdPlanDelete(core.NewOptions( + core.Option{Key: "_arg", Value: created.ID}, + )) + assert.True(t, r.OK) + }) + + assert.Contains(t, output, "deleted:") + + plan, err := readPlan(PlansRoot(), created.ID) + require.NoError(t, err) + assert.Equal(t, "archived", plan.Status) + assert.False(t, plan.ArchivedAt.IsZero()) +} + func TestCommands_CmdExtract_Good(t *testing.T) { s, _ := testPrepWithCore(t, nil) target := core.JoinPath(t.TempDir(), "extract-test") @@ -1030,6 +1054,7 @@ func TestCommands_RegisterCommands_Good_AllRegistered(t *testing.T) { assert.Contains(t, cmds, "plan/show") assert.Contains(t, cmds, "plan/status") assert.Contains(t, cmds, "plan/archive") + assert.Contains(t, cmds, "plan/delete") assert.Contains(t, cmds, "pr-manage") assert.Contains(t, cmds, "task") assert.Contains(t, cmds, "task/update")