4 Commits

Author SHA1 Message Date
Mathias
60212fc5d2 feat: issue_list + workflow_run_list tools (#28, #29)
All checks were successful
CD / Lint / Test / Vet (push) Successful in 6s
CD / Build & Import (push) Successful in 12s
CD / Deploy via GitOps (push) Has been skipped
Adds the *_list partners that the existing *_get tools have been
missing. Same pattern as repo_list — owner allowlisted, capLimit
helper for pagination, next_page surfaced when the page is full.

internal/gitea/issues.go:
- ListIssues(owner, repo, args) hitting
  GET /api/v1/repos/{owner}/{repo}/issues with type=issues server-side
  so PRs don't leak in (gitea conflates them on this endpoint).
- ListIssuesArgs struct: State, Labels, Since (ISO 8601), Page, Limit.

internal/gitea/workflows.go:
- ListWorkflowRuns(owner, repo, args) hitting
  GET /api/v1/repos/{owner}/{repo}/actions/runs.
- Expanded WorkflowRun struct with DisplayTitle, Event, HeadSHA,
  HeadBranch, WorkflowID, RunNumber, UpdatedAt, Actor so callers
  can pin runs to a commit / branch without a second lookup.
- ListWorkflowRunsArgs: Branch, HeadSHA, Status, Event, Workflow,
  Page, Limit. Status/Event 'all' treated as no-filter.

internal/tools/issue_list.go:
- Default state=open, default limit=30 (matches repo_list).
- next_page returned only when len(issues) == limit.

internal/tools/workflow_run_list.go:
- Default limit=10 (most common use is 'what just happened',
  not paging).
- Returns runs + total + optional next_page.

Tests: table-driven for both — happy path, empty result, filter
combinations, allowlist rejection. workflow_run_list also asserts
the 'status=all is no-op' behavior (no query param emitted).

Closes #28
Closes #29
2026-05-18 08:06:11 +02:00
Mathias
dc907fb7e0 feat: issue_close + issue_reopen tools (#30)
All checks were successful
CD / Lint / Test / Vet (push) Successful in 7s
CD / Build & Import (push) Successful in 12s
CD / Deploy via GitOps (push) Has been skipped
Adds two MCP tools that PATCH /api/v1/repos/{owner}/{name}/issues/{number}
with {"state":"closed"} or {"state":"open"}. Both use a shared
SetIssueState helper on the gitea client.

- internal/gitea/issues.go: SetIssueState method using the existing
  PatchJSON + MapStatus + json.Unmarshal pattern from GetIssue.
- internal/tools/issue_close.go: IssueClose tool. owner+name+number
  args. Owner allowlist enforced. Returns the updated issue. Reversible
  via issue_reopen, classified LOW risk.
- internal/tools/issue_reopen.go: mirror of IssueClose with
  state="open". Same risk profile.
- Registered both tools in cmd/gitea-mcp/main.go.
- Tests for both: success (asserts PATCH method, path, body), 404,
  and allowlist rejection — same shape as issue_get_test.go.

Closes #30
2026-05-18 07:51:17 +02:00
Mathias Bergqvist
d4dddbdb6c feat(tools): issue_get, release_create, repo_delete (#11, #17, #20)
All checks were successful
CD / Lint / Test / Vet (pull_request) Successful in 7s
CD / Build & Import (pull_request) Has been skipped
CD / Deploy via GitOps (pull_request) Has been skipped
issue_get: GET /repos/{owner}/{repo}/issues/{number} — full issue with labels, assignees, comment count
release_create: POST /repos/{owner}/{repo}/releases — create release and tag in one call
repo_delete: DELETE /repos/{owner}/{repo} — confirm=<repo name> required, blocks accidents
2026-05-15 13:59:06 +02:00
Mathias Bergqvist
6f43ff216f feat(tools): issue_create with identity footer
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-04 22:51:40 +02:00