Add forgejo_milestone_close and forgejo_milestone_reopen tools #24

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

Summary

Add closeMilestone()/reopenMilestone() thin wrapper functions to src/milestones.ts and register forgejo_milestone_close/forgejo_milestone_reopen tools, mirroring forgejo_issue_close/forgejo_issue_reopen.

Background

Depends on: #23 (Add forgejo_milestone_edit tool) (these two functions are thin wrappers over editMilestone()).

In src/issues.ts, closeIssue()/reopenIssue() are implemented as one-line wrappers: return editIssue(target, index, { state: "closed" }) / { state: "open" }. This issue applies the identical pattern to milestones — no new API contract beyond what editMilestone() (from the prerequisite issue) already covers, since the Forgejo API has no dedicated close/reopen endpoint for milestones (state changes go through the same PATCH used for edits).

Implementation Details

Files to change:

  1. src/milestones.ts:

    • Add closeMilestone(target: ForgejoTarget, id: number): Promise<Result<ForgejoMilestone, ApiError>>return editMilestone(target, id, { state: "closed" });
    • Add reopenMilestone(target: ForgejoTarget, id: number): Promise<Result<ForgejoMilestone, ApiError>>return editMilestone(target, id, { state: "open" });
  2. src/index.ts:

    • Import closeMilestone, reopenMilestone from ./milestones.
    • Register forgejo_milestone_close tool:
      • label: "Close Milestone"
      • description: "Close a Forgejo milestone."
      • promptSnippet: "Close a Forgejo milestone"
      • parameters: Type.Object({ ...targetOverrides, id: Type.Integer({ minimum: 1, description: "Milestone id" }) })
      • execute: resolve target, call closeMilestone, return via formatMilestone(result.value, "Closed milestone").
    • Register forgejo_milestone_reopen tool: identical shape, calling reopenMilestone, action text "Reopened milestone".
  3. tests/milestones.test.ts: add unit tests for closeMilestone()/reopenMilestone() — verify they delegate to editMilestone with the correct state value (can be tested by mocking forgejoApiCall and asserting the body sent, same as the edit tests).

  4. Tool-registration tests: add coverage for both new tools — schema shape (id-only param), execute() success/error paths.

Acceptance Criteria

  • closeMilestone() and reopenMilestone() exist in src/milestones.ts as thin wrappers over editMilestone() with state: "closed"/"open" respectively.
  • forgejo_milestone_close and forgejo_milestone_reopen tools are registered, each taking only id plus targetOverrides.
  • Successful close/reopen returns the updated milestone (new state) in both text and details.
  • Unit tests cover both functions and both tool registrations.
  • npm test and npm run check pass with no regressions.

Test Plan

  1. Run npm test — new tests pass; full suite green.
  2. Run npm run check — lint/typecheck passes.
  3. Manual smoke test: create a milestone, call forgejo_milestone_close id=<id>, verify state: "closed" via forgejo_milestone_view; call forgejo_milestone_reopen id=<id>, verify state: "open" again.
## Summary Add `closeMilestone()`/`reopenMilestone()` thin wrapper functions to `src/milestones.ts` and register `forgejo_milestone_close`/`forgejo_milestone_reopen` tools, mirroring `forgejo_issue_close`/`forgejo_issue_reopen`. ## Background **Depends on:** #23 (Add forgejo_milestone_edit tool) (these two functions are thin wrappers over `editMilestone()`). In `src/issues.ts`, `closeIssue()`/`reopenIssue()` are implemented as one-line wrappers: `return editIssue(target, index, { state: "closed" })` / `{ state: "open" }`. This issue applies the identical pattern to milestones — no new API contract beyond what `editMilestone()` (from the prerequisite issue) already covers, since the Forgejo API has no dedicated close/reopen endpoint for milestones (state changes go through the same `PATCH` used for edits). ## Implementation Details **Files to change:** 1. `src/milestones.ts`: - Add `closeMilestone(target: ForgejoTarget, id: number): Promise<Result<ForgejoMilestone, ApiError>>` — `return editMilestone(target, id, { state: "closed" });` - Add `reopenMilestone(target: ForgejoTarget, id: number): Promise<Result<ForgejoMilestone, ApiError>>` — `return editMilestone(target, id, { state: "open" });` 2. `src/index.ts`: - Import `closeMilestone`, `reopenMilestone` from `./milestones`. - Register `forgejo_milestone_close` tool: - `label`: "Close Milestone" - `description`: "Close a Forgejo milestone." - `promptSnippet`: "Close a Forgejo milestone" - `parameters`: `Type.Object({ ...targetOverrides, id: Type.Integer({ minimum: 1, description: "Milestone id" }) })` - `execute`: resolve target, call `closeMilestone`, return via `formatMilestone(result.value, "Closed milestone")`. - Register `forgejo_milestone_reopen` tool: identical shape, calling `reopenMilestone`, action text "Reopened milestone". 3. `tests/milestones.test.ts`: add unit tests for `closeMilestone()`/`reopenMilestone()` — verify they delegate to `editMilestone` with the correct `state` value (can be tested by mocking `forgejoApiCall` and asserting the body sent, same as the edit tests). 4. Tool-registration tests: add coverage for both new tools — schema shape (id-only param), execute() success/error paths. ## Acceptance Criteria - [ ] `closeMilestone()` and `reopenMilestone()` exist in `src/milestones.ts` as thin wrappers over `editMilestone()` with `state: "closed"`/`"open"` respectively. - [ ] `forgejo_milestone_close` and `forgejo_milestone_reopen` tools are registered, each taking only `id` plus `targetOverrides`. - [ ] Successful close/reopen returns the updated milestone (new state) in both text and `details`. - [ ] Unit tests cover both functions and both tool registrations. - [ ] `npm test` and `npm run check` pass with no regressions. ## Test Plan 1. Run `npm test` — new tests pass; full suite green. 2. Run `npm run check` — lint/typecheck passes. 3. Manual smoke test: create a milestone, call `forgejo_milestone_close id=<id>`, verify `state: "closed"` via `forgejo_milestone_view`; call `forgejo_milestone_reopen id=<id>`, verify `state: "open"` again.
david closed this issue 2026-08-18 08:25:22 +00:00
Author
Owner

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

pi-loop opened and merged a pull request for this issue: https://git.excelera.net/david/pi-extensions-and-skills/pulls/38
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#24
No description provided.