feat(agentic): make plan delete a hard delete

Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
Virgil 2026-04-01 16:14:16 +00:00
parent ab0460da61
commit 7dde6b7769
5 changed files with 33 additions and 11 deletions

View file

@ -1094,10 +1094,11 @@ func TestCommands_CmdPlanDelete_Good(t *testing.T) {
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())
assert.False(t, fs.Exists(created.Path))
_, err = readPlan(PlansRoot(), created.ID)
require.Error(t, err)
assert.Contains(t, err.Error(), "not found")
}
func TestCommands_CmdExtract_Good(t *testing.T) {

View file

@ -454,7 +454,7 @@ func (s *PrepSubsystem) planUpdate(_ context.Context, _ *mcp.CallToolRequest, in
}
func (s *PrepSubsystem) planDelete(_ context.Context, _ *mcp.CallToolRequest, input PlanDeleteInput) (*mcp.CallToolResult, PlanDeleteOutput, error) {
plan, err := archivePlanResult(input, "id is required", "planDelete")
plan, err := deletePlanResult(input, "id is required", "planDelete")
if err != nil {
return nil, PlanDeleteOutput{}, err
}

View file

@ -364,3 +364,25 @@ func archivePlanResult(input PlanDeleteInput, missingMessage, op string) (*Plan,
return plan, nil
}
func deletePlanResult(input PlanDeleteInput, missingMessage, op string) (*Plan, error) {
ref := planReference(input.ID, input.Slug)
if ref == "" {
return nil, core.E(op, missingMessage, nil)
}
plan, err := readPlan(PlansRoot(), ref)
if err != nil {
return nil, err
}
if result := fs.Delete(planPath(PlansRoot(), plan.ID)); !result.OK {
deleteErr, _ := result.Value.(error)
if deleteErr == nil {
deleteErr = core.E(op, "failed to delete plan", nil)
}
return nil, core.E(op, "failed to delete plan", deleteErr)
}
return plan, nil
}

View file

@ -268,12 +268,11 @@ func TestPlan_PlanDelete_Good(t *testing.T) {
assert.True(t, delOut.Success)
assert.Equal(t, createOut.ID, delOut.Deleted)
assert.True(t, fs.Exists(createOut.Path))
assert.False(t, fs.Exists(createOut.Path))
plan, readErr := readPlan(PlansRoot(), createOut.ID)
require.NoError(t, readErr)
assert.Equal(t, "archived", plan.Status)
assert.False(t, plan.ArchivedAt.IsZero())
_, readErr := readPlan(PlansRoot(), createOut.ID)
require.Error(t, readErr)
assert.Contains(t, readErr.Error(), "not found")
}
func TestPlan_PlanDelete_Bad_MissingID(t *testing.T) {

View file

@ -187,7 +187,7 @@ func (s *PrepSubsystem) OnStartup(ctx context.Context) core.Result {
c.Action("plan.from.issue", s.handlePlanFromIssue).Description = "Create a plan from a tracked issue"
c.Action("plan.check", s.handlePlanCheck).Description = "Check whether a plan or phase is complete"
c.Action("plan.archive", s.handlePlanArchive).Description = "Archive an implementation plan by slug"
c.Action("plan.delete", s.handlePlanDelete).Description = "Archive an implementation plan by ID"
c.Action("plan.delete", s.handlePlanDelete).Description = "Delete an implementation plan by ID"
c.Action("plan.list", s.handlePlanList).Description = "List implementation plans with optional filters"
c.Action("phase.get", s.handlePhaseGet).Description = "Read a plan phase by slug and order"
c.Action("phase.update_status", s.handlePhaseUpdateStatus).Description = "Update plan phase status by slug and order"