Add forgejo_milestone_delete tool #25

Closed
opened 2026-08-18 02:34:21 +00:00 by david · 1 comment
Owner

Summary

Add a deleteMilestone() function to src/milestones.ts and register a forgejo_milestone_delete tool, completing the milestone CRUD lifecycle.

Background

Depends on: #20 (Add forgejo_milestone_create tool) (needs the milestonePath() helper and src/milestones.ts scaffolding).

The Forgejo API's milestone delete endpoint returns 204 No Content on success. The extension's forgejoApiCall() (src/api.ts) already handles this case generically: "Empty 2xx bodies (e.g. 204 No Content on DELETE) are a valid success" — it returns success(undefined as T). This matches how removeLabels() in src/issues.ts handles its own per-label DELETE calls (see its Result<void, ApiError> return type).

Implementation Details

Confirmed Forgejo/Gitea API v1 contract:

DELETE /repos/{owner}/{repo}/milestones/{id} (operationId issueDeleteMilestone)

No request body. Response: 204 (no content) on success, 404 if not found (via the standard mapHttpError table in src/api.ts).

Files to change:

  1. src/milestones.ts:

    • Add deleteMilestone(target: ForgejoTarget, id: number): Promise<Result<void, ApiError>>DELETE via forgejoApiCall, using milestonePath(target, id), no body.
  2. src/index.ts:

    • Import deleteMilestone from ./milestones.
    • Register forgejo_milestone_delete tool:
      • label: "Delete Milestone"
      • description: "Delete a Forgejo milestone. This does not delete issues assigned to it."
      • promptSnippet: "Delete a Forgejo milestone"
      • promptGuidelines: e.g. ["Deleting a milestone does not delete or unassign its issues/PRs."]
      • parameters: Type.Object({ ...targetOverrides, id: Type.Integer({ minimum: 1, description: "Milestone id" }) })
      • execute: resolve target, call deleteMilestone, on success return toolSuccess("Deleted milestone #<id>", { id }) (matching the plain-confirmation style of other destructive/void-returning tools), on failure toolError.
  3. tests/milestones.test.ts: add unit tests for deleteMilestone() — verify URL, DELETE method, no body sent, success (void) and 404-error propagation.

  4. Tool-registration tests: add coverage for forgejo_milestone_delete — schema shape, execute() success/error paths.

Acceptance Criteria

  • deleteMilestone() exists in src/milestones.ts, calls DELETE /repos/{owner}/{repo}/milestones/{id}, and returns Result<void, ApiError>.
  • forgejo_milestone_delete tool is registered with a required id param plus targetOverrides.
  • Successful deletion returns a clear confirmation message including the deleted milestone's id.
  • A 404 (milestone not found) surfaces the existing NOT_FOUND error message unchanged.
  • Unit tests cover deleteMilestone() and the tool registration/execution path.
  • npm test and npm run check pass with no regressions.

Test Plan

  1. Run npm test — new tests for deleteMilestone() and forgejo_milestone_delete pass; full suite green.
  2. Run npm run check — lint/typecheck passes.
  3. Manual smoke test: create a milestone, call forgejo_milestone_delete id=<id>, then call forgejo_list_milestones state="all" and confirm it no longer appears.
## Summary Add a `deleteMilestone()` function to `src/milestones.ts` and register a `forgejo_milestone_delete` tool, completing the milestone CRUD lifecycle. ## Background **Depends on:** #20 (Add forgejo_milestone_create tool) (needs the `milestonePath()` helper and `src/milestones.ts` scaffolding). The Forgejo API's milestone delete endpoint returns `204 No Content` on success. The extension's `forgejoApiCall()` (`src/api.ts`) already handles this case generically: "Empty 2xx bodies (e.g. 204 No Content on DELETE) are a valid success" — it returns `success(undefined as T)`. This matches how `removeLabels()` in `src/issues.ts` handles its own per-label `DELETE` calls (see its `Result<void, ApiError>` return type). ## Implementation Details **Confirmed Forgejo/Gitea API v1 contract:** `DELETE /repos/{owner}/{repo}/milestones/{id}` (operationId `issueDeleteMilestone`) No request body. Response: `204` (no content) on success, `404` if not found (via the standard `mapHttpError` table in `src/api.ts`). **Files to change:** 1. `src/milestones.ts`: - Add `deleteMilestone(target: ForgejoTarget, id: number): Promise<Result<void, ApiError>>` — `DELETE` via `forgejoApiCall`, using `milestonePath(target, id)`, no body. 2. `src/index.ts`: - Import `deleteMilestone` from `./milestones`. - Register `forgejo_milestone_delete` tool: - `label`: "Delete Milestone" - `description`: "Delete a Forgejo milestone. This does not delete issues assigned to it." - `promptSnippet`: "Delete a Forgejo milestone" - `promptGuidelines`: e.g. `["Deleting a milestone does not delete or unassign its issues/PRs."]` - `parameters`: `Type.Object({ ...targetOverrides, id: Type.Integer({ minimum: 1, description: "Milestone id" }) })` - `execute`: resolve target, call `deleteMilestone`, on success return `toolSuccess("Deleted milestone #<id>", { id })` (matching the plain-confirmation style of other destructive/void-returning tools), on failure `toolError`. 3. `tests/milestones.test.ts`: add unit tests for `deleteMilestone()` — verify URL, `DELETE` method, no body sent, success (void) and 404-error propagation. 4. Tool-registration tests: add coverage for `forgejo_milestone_delete` — schema shape, execute() success/error paths. ## Acceptance Criteria - [ ] `deleteMilestone()` exists in `src/milestones.ts`, calls `DELETE /repos/{owner}/{repo}/milestones/{id}`, and returns `Result<void, ApiError>`. - [ ] `forgejo_milestone_delete` tool is registered with a required `id` param plus `targetOverrides`. - [ ] Successful deletion returns a clear confirmation message including the deleted milestone's id. - [ ] A 404 (milestone not found) surfaces the existing `NOT_FOUND` error message unchanged. - [ ] Unit tests cover `deleteMilestone()` and the tool registration/execution path. - [ ] `npm test` and `npm run check` pass with no regressions. ## Test Plan 1. Run `npm test` — new tests for `deleteMilestone()` and `forgejo_milestone_delete` pass; full suite green. 2. Run `npm run check` — lint/typecheck passes. 3. Manual smoke test: create a milestone, call `forgejo_milestone_delete id=<id>`, then call `forgejo_list_milestones state="all"` and confirm it no longer appears.
david closed this issue 2026-08-18 08:36:25 +00:00
Author
Owner

pi-loop opened and merged a pull request for this issue: #39

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/39
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
david/pi-extensions-and-skills#25
No description provided.