Compare commits
12 Commits
v2.0.1
...
14369ae103
| Author | SHA1 | Date | |
|---|---|---|---|
| 14369ae103 | |||
| 696079cf3e | |||
| a17f65db22 | |||
| 7d30c454ca | |||
| 0c7dd04a46 | |||
| 3de8ff5d15 | |||
| fd837b87d9 | |||
| a3853f78b1 | |||
| 5854961c1f | |||
| 4e98df7445 | |||
| 0d2a6cd839 | |||
| 12f60f42b7 |
109
docs/adr/0011-gitea-skill-deep-modules.md
Normal file
109
docs/adr/0011-gitea-skill-deep-modules.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Gitea skill splits into deep modules under `plugins/gitea/`, replacing the flat `plugins/bin/skills/gitea/`
|
||||
|
||||
The gitea skill originated under kyberforge (`b9c73cc`), moved to `plugins/bin/skills/gitea/`
|
||||
(`4f603cd`), and covers only 5 of gitea-mcp's ~15 tool domains (issues, labels, milestones, PRs,
|
||||
branches) in one flat `SKILL.md` mixing routing logic with execution detail. Meanwhile
|
||||
`plugins/gitea/` already existed as a plugin scaffold holding comprehensive research docs (all 55
|
||||
MCP tool schemas, code-derived from gitea-mcp source, at
|
||||
`plugins/gitea/docs/research/docs/gitea/`) but empty `skills/`, `agents/`, and `.mcp.json`. This
|
||||
ADR records the decisions from a grill-with-docs session on issue #6 that splits the flat skill
|
||||
into deep modules and relocates it to `plugins/gitea/`.
|
||||
|
||||
**Relocation.** The new deep-module skill structure is built in `plugins/gitea/`, not
|
||||
`plugins/bin/`, making the gitea plugin self-contained — bundling its own skills, agents, and MCP
|
||||
config — matching this repo's Plugin glossary definition (the deployable unit that bundles skills,
|
||||
agents, hooks, and MCP servers into a single installable directory) and mirroring the existing
|
||||
`plugins/git/` plugin's shape. The old flat skill stays at `plugins/bin/skills/gitea/` untouched
|
||||
for now, kept as a reference/fallback — not deleted in this pass; removal is a future cleanup once
|
||||
the new structure is validated in practice.
|
||||
|
||||
**Scope expansion.** Coverage expands beyond the original 5 domains to 3 new domains verified
|
||||
working with the current token scope (`write:issue`, `write:repository`) per
|
||||
`plugins/bin/skills/gitea/references/token-access.md`: Files (get/create/update/delete file, dir
|
||||
contents, repo tree), Commits (list/get), and Releases & Tags (full CRUD). Domains not added:
|
||||
repo/org listing, user identity, notifications, and packages are blocked by token scope
|
||||
(`read:user`, `read:organization`, `read:notification`, `read:package`); Actions/CI (list_runs and
|
||||
secrets return 403, writes untested) and Wiki (404 on this repo, writes untested) are partially
|
||||
broken or unverified. All are deferred to future issues once scope is expanded or the domain is
|
||||
verified safe elsewhere.
|
||||
|
||||
**Domain skill split.** The flat skill becomes 6 domain skills plus a workflow orchestrator and an
|
||||
agent counterpart, composed per the Skill composition pattern:
|
||||
|
||||
- `gitea-issues` — issues only (list/read/write/search); closes out 4 enrichments deferred from
|
||||
issue #6 comment #848 — milestone assignment on create, assignee on create (documented
|
||||
workaround since `get_me`/`read:user` is blocked), dependency-linking convention ("Depends on
|
||||
#N" in body, since gitea-mcp has no native dependency field) — and delegates label inference to
|
||||
`gitea-labels-milestones`.
|
||||
- `gitea-labels-milestones` — split out as its own shared skill since labels/milestones are
|
||||
cross-cutting (apply to both issues and PRs), rather than bundled under `gitea-issues`; owns the
|
||||
label inference guide (context-pattern → Kind/*/Priority/*/Status/* taxonomy mapping).
|
||||
- `gitea-prs` — pull requests + reviews, composes `gitea-labels-milestones` for label/milestone
|
||||
application.
|
||||
- `gitea-branches` — branches + commits bundled together (commits are read-only history within
|
||||
branches, a natural pairing).
|
||||
- `gitea-files` — new domain.
|
||||
- `gitea-releases` — releases + tags bundled together.
|
||||
- `gitea-workflow` — thin human-facing orchestrator mirroring `git-workflow`
|
||||
(`plugins/git/skills/git-workflow/`). Preserves the original flat skill's default no-args status
|
||||
view (composes `gitea-issues` + `gitea-prs`) and routes ambiguous requests to the right domain
|
||||
skill. Named `gitea-workflow`, not bare `gitea`, for naming consistency with the other 6 skills,
|
||||
despite breaking the old `/gitea` invocation muscle memory — an explicit accepted tradeoff.
|
||||
- `gitea-orchestrate` (agent, not skill) — agent-facing deterministic counterpart mirroring
|
||||
`git-orchestrate`, for multi-step composition when the caller is an agent rather than a human.
|
||||
|
||||
**Reference-file signature sourcing.** Each new skill's `references/*.md` restates verified MCP
|
||||
call signatures cross-checked live via `ToolSearch` at authoring time, not copied from
|
||||
`api-reference.md`, which could drift from the deployed MCP server version. This resolves issue #6
|
||||
comment #849's root-cause question about the original `type` parameter bug, which happened
|
||||
because the skill was authored from Gitea REST API docs instead of the actual MCP tool schema.
|
||||
This is applied manually during this authoring pass; the `kyberforge:skill-author` meta-skill
|
||||
itself is not changed — comment #849's "option 2" process fix is considered and explicitly
|
||||
deferred as out of scope for this PR.
|
||||
|
||||
**MCP config deferred.** `plugins/gitea/.mcp.json` is deliberately left as an empty `mcpServers`
|
||||
block — the real gitea-mcp server config continues to live in the user's `~/.claude.json` rather
|
||||
than being wired into the plugin manifest. This means the gitea plugin is not yet installable
|
||||
standalone via `claude plugin install gitea@holocron` without manual MCP setup. A follow-up Gitea
|
||||
issue tracks closing this gap.
|
||||
|
||||
**Research backfill.** The existing research docs
|
||||
(`plugins/gitea/docs/research/docs/gitea/`) are 100% code-derived from gitea-mcp source with zero
|
||||
external/best-practice content (the original docs.gitea.com fetch timed out and was never
|
||||
retried). Context7 has `/websites/gitea` (official docs mirror) and `/git_gitea_com/gitea_tea` (Tea
|
||||
CLI) available now — backfilled via a parallel research pass before skill-authoring, so the
|
||||
Provenance chain (`source_keys` → `sources.md` → research doc) has real external sources for
|
||||
workflow/convention guidance, not just API mechanics.
|
||||
|
||||
**Authoring route.** All 8 artifacts (7 skills + 1 agent) are authored via `kyberforge:forge`, not
|
||||
direct `skill-author`/`agent-author` calls, even though `forge`'s own routing rule would normally
|
||||
bypass itself here since the target artifact types are already known — chosen deliberately for
|
||||
uniform audit/recheck coverage across every artifact.
|
||||
|
||||
## Considered options
|
||||
|
||||
**5-skill split, labels+milestones bundled under `gitea-issues` (rejected)** — simpler, one fewer
|
||||
skill, but re-buries label/milestone logic inside an issues-specific skill even though PRs need it
|
||||
equally, forcing `gitea-prs` to either duplicate the guide or reach into `gitea-issues`'
|
||||
`references/` — breaking the self-contained skill boundary.
|
||||
|
||||
**8-skill split, one skill per raw API domain, no bundling (rejected)** — e.g. separate
|
||||
`gitea-commits` and `gitea-tags` skills. Rejected as over-fragmentation: commits are read-only
|
||||
history naturally scoped to branches, and tags are naturally scoped to releases, so bundling
|
||||
avoids two near-empty skills each routing to a single tool family.
|
||||
|
||||
## Consequences
|
||||
|
||||
- `plugins/gitea/` gains `skills/gitea-issues/`, `skills/gitea-labels-milestones/`,
|
||||
`skills/gitea-prs/`, `skills/gitea-branches/`, `skills/gitea-files/`, `skills/gitea-releases/`,
|
||||
`skills/gitea-workflow/`, and `agents/gitea-orchestrate.md` (+ Copilot counterpart), each with
|
||||
its own `references/` and provenance records.
|
||||
- `plugins/gitea/.mcp.json` stays an empty `mcpServers` block until the follow-up issue wires in
|
||||
the real gitea-mcp server config; the plugin is not standalone-installable until then.
|
||||
- `plugins/bin/skills/gitea/` remains in place, unreferenced by new work, until a future cleanup
|
||||
issue removes it once the new structure is validated in practice.
|
||||
- Follow-up issues are needed for: the deferred domains (Actions/CI, Wiki, Notifications,
|
||||
Packages, User/Org), the `.mcp.json` wiring gap, and the eventual removal of
|
||||
`plugins/bin/skills/gitea/`.
|
||||
- Future domain-plugin work in this repo can point to this ADR as the template for splitting an
|
||||
MCP-wrapping skill into deep modules.
|
||||
@@ -10,9 +10,10 @@
|
||||
"issues",
|
||||
"prs",
|
||||
"milestones",
|
||||
"releases"
|
||||
"releases",
|
||||
"branches"
|
||||
],
|
||||
"license": "MIT",
|
||||
"name": "gitea",
|
||||
"version": "1.0.0"
|
||||
"version": "1.1.0"
|
||||
}
|
||||
|
||||
@@ -20,3 +20,17 @@
|
||||
- **Description:** Gitea REST API swagger documentation covering underlying endpoints for issues, PRs, labels, milestones, and branches
|
||||
- **Contributing files:** (see notes below)
|
||||
- **Status:** `no content extracted` — source fetch timed out; all reference content derived from gitea-mcp source files which are authoritative for MCP tool usage
|
||||
|
||||
## context7-websites-gitea
|
||||
|
||||
- **URL:** context7:/websites/gitea
|
||||
- **Description:** Official Gitea docs mirror on Context7 (docs.gitea.com content) — scoped/exclusive label conventions, branch protection and PR review/merge rules, release and webhook semantics, issue/PR automatic cross-reference linking. Backfills the external/best-practice gap left by the original docs.gitea.com fetch timeout.
|
||||
- **Contributing files:** workflow-conventions.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## context7-gitea-tea-cli
|
||||
|
||||
- **URL:** context7:/git_gitea_com/gitea_tea
|
||||
- **Description:** Official `tea` CLI (reference Gitea client) docs on Context7 — practitioner command patterns for issues, PRs, and releases, including semver tag/release conventions, draft/prerelease flags, and release-notes-from-file conventions.
|
||||
- **Contributing files:** workflow-conventions.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
topic: workflow-conventions
|
||||
source_keys:
|
||||
- context7-websites-gitea
|
||||
- context7-gitea-tea-cli
|
||||
---
|
||||
|
||||
# Gitea Workflow Conventions
|
||||
|
||||
Practitioner conventions and platform behavior that inform *how* to use the mechanics already
|
||||
documented in `api-reference.md` — not additional tool schemas.
|
||||
|
||||
## Scoped, exclusive labels
|
||||
|
||||
Gitea labels support a scoped-label convention: a `/` delimiter in the label name (e.g.
|
||||
`Priority/High`) plus an `exclusive: true` flag means only one label from that scope can be applied
|
||||
to an issue or PR at a time — applying a new `Priority/*` label automatically replaces the previous
|
||||
one. This is exactly the `Kind/*` / `Priority/*` / `Status/*` taxonomy already used in this repo's
|
||||
own label set, confirming the taxonomy follows Gitea's native scoped-label convention rather than an
|
||||
ad hoc naming scheme. When defining or inferring labels, a scope prefix implies mutual exclusivity —
|
||||
label inference logic should replace, not add to, existing labels in the same scope.
|
||||
|
||||
Repositories can also seed a predefined label set at creation time from a YAML label file
|
||||
(`name`, `color`, `description`, `exclusive`), which is where the base `Kind/Priority/Status` sets
|
||||
typically originate.
|
||||
|
||||
## Milestone and label state as first-class transitions
|
||||
|
||||
Both issues and PRs treat labeling and milestoning as discrete state-transition events
|
||||
(`label_updated`/`label_cleared`, `milestoned`/`demilestoned`), not passive metadata fields. This
|
||||
reinforces treating `gitea-labels-milestones` as a shared skill: the same transition semantics apply
|
||||
whether the target is an issue or a PR.
|
||||
|
||||
## Automatic cross-reference linking
|
||||
|
||||
Gitea auto-renders issue/PR references in body text without any API call: `#1234` and `!1234` both
|
||||
resolve to issue/PR 1234 in the same repo (issues and PRs share one number space, consistent with
|
||||
`data-model.md`); cross-repo references use `owner/repo#1234` (issue) or `owner/repo!1234` (PR). This
|
||||
directly validates the dependency-linking convention decided for `gitea-issues` (issue #6, comment
|
||||
#848): writing `Depends on #N` in an issue body is not just a text convention — Gitea renders it as
|
||||
a real clickable cross-reference automatically, with no separate API call required. For
|
||||
external-issue-tracker repos, the same syntax renders as an external link instead, so the skill
|
||||
should assume same-repo internal linking unless told otherwise.
|
||||
|
||||
## Pull request review workflow
|
||||
|
||||
The reviewer flow is: comment, request changes, or approve; the author pushes updates to the same
|
||||
branch, which the PR auto-tracks; maintainers merge once approved. Protected branches can layer
|
||||
additional constraints on top of this base flow:
|
||||
|
||||
- An allowlist of users/teams may be required to approve before merge is possible.
|
||||
- A minimum approval count can be enforced.
|
||||
- Stale approvals (approvals given before new commits were pushed) can be auto-dismissed or ignored.
|
||||
- Merge can be blocked if any review requests changes, if requested reviewers haven't reviewed yet,
|
||||
or if the branch is outdated relative to its base.
|
||||
- Repository admins are not exempt from these rules by default — an explicit
|
||||
"administrators must follow branch protection rules" setting is what removes their force-merge
|
||||
bypass.
|
||||
|
||||
A skill that merges PRs should treat "CI passing" and "reviews satisfied" as two independently
|
||||
checkable gates — `get_status` covers CI, but review/approval state and branch-protection
|
||||
constraints are a separate check the merge call itself will enforce server-side and return as an
|
||||
error if unmet.
|
||||
|
||||
## Release and tag conventions
|
||||
|
||||
Releases are conceptually separate from tags but always tied to one: a release wraps a tag with a
|
||||
title, notes, and optional binary assets. Practitioner convention (per the `tea` CLI, the reference
|
||||
Gitea client) is:
|
||||
|
||||
- Tag names are semver-style, typically `v`-prefixed (`v1.2.0`, `v2.0.0-beta.1`).
|
||||
- Release notes are commonly sourced from a changelog file rather than typed inline.
|
||||
- Draft and prerelease are separate boolean flags, not states inferred from the tag name — a
|
||||
prerelease is anything with a `-beta`/`-rc` style suffix by convention, but Gitea does not enforce
|
||||
this; the skill should treat `draft`/`prerelease` as flags the caller sets explicitly rather than
|
||||
something to infer from the tag string.
|
||||
- Deleting a release does not delete its tag by default — the two are separate destructive
|
||||
operations (confirmed by `delete_release` taking a numeric release ID per `troubleshooting.md`,
|
||||
distinct from `delete_tag`).
|
||||
|
||||
## File editing: direct commit vs. PR
|
||||
|
||||
Gitea's own UI defaults to prompting for a target branch when creating/editing a file directly
|
||||
through the web interface, and supports pre-filling a new file's path and content via query
|
||||
parameters — reflecting that direct-commit file edits are a first-class, expected workflow (not just
|
||||
an API escape hatch). This supports `create_or_update_file`/`delete_file` being used directly against
|
||||
a working branch as a normal editing action, with the SHA-currency requirement (`troubleshooting.md`)
|
||||
being the main gotcha rather than direct-commit being an anti-pattern to avoid.
|
||||
@@ -11,7 +11,8 @@
|
||||
"issues",
|
||||
"prs",
|
||||
"milestones",
|
||||
"releases"
|
||||
"releases",
|
||||
"branches"
|
||||
],
|
||||
"license": "MIT",
|
||||
"mcpServers": ".mcp.json",
|
||||
@@ -19,5 +20,5 @@
|
||||
"skills": [
|
||||
"skills/"
|
||||
],
|
||||
"version": "1.0.0"
|
||||
"version": "1.1.0"
|
||||
}
|
||||
|
||||
35
plugins/gitea/skills/gitea-branches/README.md
Normal file
35
plugins/gitea/skills/gitea-branches/README.md
Normal file
@@ -0,0 +1,35 @@
|
||||
# gitea-branches
|
||||
|
||||
Manage Gitea repository branches and inspect commit history via the Gitea MCP server.
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles branch lifecycle operations (list, create, delete) and read-only commit
|
||||
history (list commits, get a single commit's full detail) against a Gitea repository. It resolves
|
||||
`owner`/`repo` from the git remote, dispatches to the right MCP tool, and applies safety and
|
||||
pagination conventions specific to Gitea's API (e.g. refusing to delete a protected branch without
|
||||
explicit confirmation, and treating unexpected 404s as possible masked 403s).
|
||||
|
||||
## Before you start
|
||||
|
||||
Requires a Gitea MCP server configured with a token. `list_branches`, `list_commits`, and
|
||||
`get_commit` work with `write:issue` alone; `create_branch` and `delete_branch` need
|
||||
`write:repository`. Requires a git remote named `origin` pointing at the Gitea instance.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/gitea-branches
|
||||
```
|
||||
|
||||
Describe your task: list/create/delete a branch, or list/inspect commits. See `SKILL.md`'s
|
||||
dispatch table for the full set of recognized invocations.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents — dispatch table, gotchas |
|
||||
| `references/branches.md` | Verified call signatures and mechanics for list/create/delete branch |
|
||||
| `references/commits.md` | Verified call signatures and mechanics for list/get commit |
|
||||
| `references/sources.md` | Research sources backing the branch/commit guidance |
|
||||
66
plugins/gitea/skills/gitea-branches/SKILL.md
Normal file
66
plugins/gitea/skills/gitea-branches/SKILL.md
Normal file
@@ -0,0 +1,66 @@
|
||||
---
|
||||
name: gitea-branches
|
||||
|
||||
description: >
|
||||
Use when managing Gitea repository branches — listing, creating, or deleting
|
||||
branches — or inspecting commit history within a Gitea repo: listing commits
|
||||
(optionally filtered by branch or file path) or getting full detail for a
|
||||
single commit by SHA. Triggers on "list branches", "create a branch",
|
||||
"delete a branch", "what commits are on this branch", "show commit <sha>",
|
||||
"what changed in that commit" — even if the user doesn't say "Gitea"
|
||||
explicitly, as long as the repo's remote is a Gitea instance. Do not use for
|
||||
local git branch/commit operations on your working copy (use git-branches or
|
||||
git-history) or for PR-side branch references like cross-repo fork PR heads
|
||||
(use gitea-prs).
|
||||
|
||||
compatibility: Requires Gitea MCP server configured with a token; list_branches, list_commits, and get_commit work with write:issue alone, create_branch and delete_branch require write:repository. Requires git remote "origin" pointing to the Gitea instance.
|
||||
|
||||
metadata:
|
||||
category: integration
|
||||
version: "0.1.0"
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
- context7-websites-gitea
|
||||
|
||||
allowed-tools: Bash mcp__gitea__list_branches mcp__gitea__create_branch mcp__gitea__delete_branch mcp__gitea__list_commits mcp__gitea__get_commit
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Never delete a protected branch (`main`/`master` by name, or `protected: true` from `list_branches`) without explicit confirmation.** `delete_branch` is a direct API call, not a local `git push` — there is no client-side force-push guard protecting it. Name-matching `main`/`master` is a convenient default but not authoritative — a repo can protect a differently-named default branch. When in doubt, call `list_branches` first and check `protected` on the target; treat deletion of any protected branch as a hard refusal unless the user explicitly confirms in the conversation.
|
||||
- **404 may actually mean 403.** Gitea hides permission errors as not-found to avoid leaking resource existence. If any of these five tools returns 404 unexpectedly, check token scope (see `references/branches.md` / `references/commits.md`) before concluding the branch or commit doesn't exist.
|
||||
- **Pagination is manual.** `list_branches` and `list_commits` return one page at a time — no auto-pagination in the MCP layer. When you need a complete list, iterate `page: 1, 2, ...` until the returned count is less than `per_page`.
|
||||
- **Owner/repo always come from the git remote, never from `get_me`.** Resolve them via `git remote get-url origin` (Step 1 below). `get_me`/`list_my_repos` are blocked under the token scopes this skill assumes.
|
||||
- **`create_branch`'s source is `old_branch`, not "wherever gitea-mcp feels like."** Omitting `old_branch` forks from the repo's server-side default branch — not necessarily the branch you're currently working on locally. If you want to branch from your current checkout, pass `old_branch` explicitly.
|
||||
|
||||
## Step 1 — Resolve owner and repo
|
||||
|
||||
Before any tool call, extract `owner` and `repo` from the git remote:
|
||||
|
||||
```bash
|
||||
git remote get-url origin
|
||||
```
|
||||
|
||||
If origin is not set or the URL is not a Gitea URL, stop and report: "No Gitea remote found — set origin to your Gitea instance URL."
|
||||
|
||||
## Step 2 — Dispatch
|
||||
|
||||
| Invocation | Action |
|
||||
|---|---|
|
||||
| `/gitea-branches` or `/gitea-branches list` | List branches |
|
||||
| `/gitea-branches create <name> [from <base>]` | Create branch |
|
||||
| `/gitea-branches delete <name>` | Delete branch |
|
||||
| `/gitea-branches commits [on <branch>] [touching <path>]` | List commit history |
|
||||
| `/gitea-branches commit <sha>` | Get full detail for one commit |
|
||||
|
||||
For branch operations (list/create/delete), read `references/branches.md`.
|
||||
For commit operations (list/get), read `references/commits.md`.
|
||||
|
||||
## Step 3 — Report
|
||||
|
||||
For reads: display branches as name + protected flag; display commits as SHA (short), message summary, author, date.
|
||||
|
||||
For writes (create/delete): confirm the action taken, the branch name, and (for create) the base it forked from.
|
||||
|
||||
For errors: surface the HTTP code and message. If a 404 is unexpected, re-check token scope per the Gotchas above before reporting "not found" to the user.
|
||||
78
plugins/gitea/skills/gitea-branches/references/branches.md
Normal file
78
plugins/gitea/skills/gitea-branches/references/branches.md
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
topic: branches
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Branch operations
|
||||
|
||||
Call signatures below were verified live against the deployed `gitea-mcp` server via `ToolSearch`
|
||||
at authoring time, not copied from research docs — this is deliberate: research docs are generated
|
||||
from source code at a point in time and can drift from the server actually deployed. Re-verify
|
||||
against the live schema if these tools appear to behave differently than documented here.
|
||||
|
||||
## `list_branches`
|
||||
|
||||
**Parameters:**
|
||||
- `owner` (string, required)
|
||||
- `repo` (string, required)
|
||||
- `page` (number, optional, default: `1`)
|
||||
- `per_page` (number, optional, default: `30`)
|
||||
|
||||
**Call:**
|
||||
```
|
||||
list_branches owner: <owner> repo: <repo>
|
||||
```
|
||||
|
||||
**Response:** one object per branch: `name`, `protected` (bool), `commit_sha` (present when the
|
||||
underlying commit data is available).
|
||||
|
||||
Paginate if you need the full list (see Gotchas in SKILL.md) — iterate `page` until the returned
|
||||
count is less than `per_page`.
|
||||
|
||||
## `create_branch`
|
||||
|
||||
**Parameters:**
|
||||
- `owner` (string, required)
|
||||
- `repo` (string, required)
|
||||
- `branch` (string, required) — new branch name
|
||||
- `old_branch` (string, optional) — source branch; if omitted, defaults to the repo's default
|
||||
branch server-side (not necessarily your current local checkout)
|
||||
|
||||
**Call:**
|
||||
```
|
||||
create_branch owner: <owner> repo: <repo> branch: <new-name> old_branch: <source-branch>
|
||||
```
|
||||
|
||||
Default dispatch: if the user gives a base ("branch off of X", "from X"), pass it as `old_branch`.
|
||||
If they don't specify a base and you're mid-task on a local branch, pass your current branch
|
||||
(`git branch --show-current`) as `old_branch` so the new branch forks from where you're actually
|
||||
working, rather than silently falling back to the repo default. If neither applies (e.g. a fresh
|
||||
top-level request with no working branch context), omit `old_branch` and let it default server-side.
|
||||
|
||||
A branch name collision returns `409 Conflict`.
|
||||
|
||||
## `delete_branch`
|
||||
|
||||
**Parameters:**
|
||||
- `owner` (string, required)
|
||||
- `repo` (string, required)
|
||||
- `branch` (string, required)
|
||||
|
||||
**Call:**
|
||||
```
|
||||
delete_branch owner: <owner> repo: <repo> branch: <name>
|
||||
```
|
||||
|
||||
Before calling this, see the hard-refusal Gotcha in SKILL.md. If the target branch's name isn't
|
||||
obviously a scratch/feature branch, call `list_branches` first and check `protected` on the
|
||||
matching entry — name-matching `main`/`master` alone isn't authoritative, since a repo can protect
|
||||
a differently-named default branch. Confirm explicitly with the user before deleting anything
|
||||
protected, every time, regardless of how the request is phrased.
|
||||
|
||||
## Token scope
|
||||
|
||||
`list_branches` works with `write:issue` alone. `create_branch` and `delete_branch` need
|
||||
`write:repository`. All three are verified working empirically under a token with both scopes
|
||||
(`write:issue` + `write:repository`).
|
||||
67
plugins/gitea/skills/gitea-branches/references/commits.md
Normal file
67
plugins/gitea/skills/gitea-branches/references/commits.md
Normal file
@@ -0,0 +1,67 @@
|
||||
---
|
||||
topic: commits
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Commit operations
|
||||
|
||||
Read-only commit history, scoped to a repo (optionally to one branch or one path). Call signatures
|
||||
below were verified live against the deployed `gitea-mcp` server via `ToolSearch` at authoring time,
|
||||
not copied from research docs, for the same drift-avoidance reason noted in `references/branches.md`.
|
||||
|
||||
This domain has no prior skill precedent — it's new coverage added alongside branches because commit
|
||||
history is naturally scoped to a branch (a "what happened on this branch" question), not because it
|
||||
shares any tool family with branch create/delete.
|
||||
|
||||
## `list_commits`
|
||||
|
||||
**Parameters:**
|
||||
- `owner` (string, required)
|
||||
- `repo` (string, required)
|
||||
- `sha` (string, optional) — starting SHA or branch name; if omitted, gitea-mcp uses the repo's
|
||||
default branch
|
||||
- `path` (string, optional) — restrict results to commits that touched this file/path
|
||||
- `page` (number, optional, default: `1`, minimum: `1`)
|
||||
- `per_page` (number, optional, default: `30`, minimum: `1`)
|
||||
|
||||
**Call:**
|
||||
```
|
||||
list_commits owner: <owner> repo: <repo> sha: <branch-or-sha> path: <optional-path>
|
||||
```
|
||||
|
||||
Dispatch defaults:
|
||||
- "commits on `<branch>`" → pass `<branch>` as `sha`.
|
||||
- "commits touching `<path>`" (no branch mentioned) → pass `path` alone, `sha` omitted (defaults to
|
||||
the repo's default branch).
|
||||
- Both given → pass both; the result is history for that path, walked from that branch/SHA.
|
||||
- Neither given → omit both; this returns default-branch history, which is a reasonable default for
|
||||
an open-ended "what's the recent history here" question.
|
||||
|
||||
**Response:** one object per commit: `sha`, `html_url`, `created`, `message` (when available),
|
||||
`author` (`{name, email, date}`, when available).
|
||||
|
||||
Paginate per the manual-pagination Gotcha in SKILL.md if you need more than one page of history.
|
||||
|
||||
## `get_commit`
|
||||
|
||||
**Parameters:**
|
||||
- `owner` (string, required)
|
||||
- `repo` (string, required)
|
||||
- `sha` (string, required)
|
||||
|
||||
**Call:**
|
||||
```
|
||||
get_commit owner: <owner> repo: <repo> sha: <commit-sha>
|
||||
```
|
||||
|
||||
**Response:** same shape as a `list_commits` entry, but always fully populated (`message` and
|
||||
`author` are guaranteed present, not conditional). Use this when the user asks about one specific
|
||||
commit by SHA rather than browsing history — `list_commits` entries may omit `message`/`author` in
|
||||
edge cases, `get_commit` will not.
|
||||
|
||||
## Token scope
|
||||
|
||||
Both tools are read-only and work with `write:issue` alone (no `write:repository` needed), verified
|
||||
empirically against the deployed server.
|
||||
41
plugins/gitea/skills/gitea-branches/references/sources.md
Normal file
41
plugins/gitea/skills/gitea-branches/references/sources.md
Normal file
@@ -0,0 +1,41 @@
|
||||
# Sources
|
||||
|
||||
**Note on call signatures:** per `docs/adr/0011-gitea-skill-deep-modules.md`, the tool parameter
|
||||
signatures in `references/branches.md` and `references/commits.md` were re-verified live via
|
||||
`ToolSearch` against the deployed `gitea-mcp` server at authoring time — they are not copied
|
||||
verbatim from `api-reference.md` below. This resolves issue #6 comment #849's root-cause finding
|
||||
that a prior skill was authored from API docs that had drifted from the actual MCP tool schema.
|
||||
The research docs cited here informed gotchas, response shapes, and workflow context, not the
|
||||
parameter lists themselves.
|
||||
|
||||
## gitea-mcp-repo
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp
|
||||
- **Description:** Official gitea-mcp repository (v1.3.0); operation/*.go source files documenting all 55 MCP tools, their parameters, and CLI flags. Informed the dispatch table and pagination / 404-may-mean-403 gotchas in SKILL.md, and the list/create/delete branch and list/get commit mechanics (including 409 conflict and default-branch fallback behavior) in references/branches.md and references/commits.md.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md, references/branches.md, references/commits.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## gitea-mcp-slim-go
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/repo/slim.go
|
||||
- **Description:** Slim response shape structs from gitea-mcp source; defines exactly which fields the MCP server returns for branches (name, protected, commit_sha) and commits (sha, html_url, created, message, author), and informed get_commit's always-populated guarantee vs. list_commits' conditional fields.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** references/branches.md, references/commits.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## context7-websites-gitea
|
||||
|
||||
- **URL:** context7:/websites/gitea
|
||||
- **Description:** Official Gitea docs mirror on Context7 — informed the protected-branch gotcha in SKILL.md (protected branches can block server-side operations regardless of client-side checks; admins aren't exempt by default).
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## context7-gitea-tea-cli
|
||||
|
||||
- **URL:** context7:/git_gitea_com/gitea_tea
|
||||
- **Description:** Official `tea` CLI docs on Context7 — practitioner conventions for issues, PRs, and releases (semver tags, draft/prerelease flags). Consulted as part of the shared research pass but its content is scoped to releases/tags, out of scope for branches/commits — no content from it was used in this skill.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** (none)
|
||||
- **Status:** `extracted`
|
||||
23
plugins/gitea/skills/gitea-files/README.md
Normal file
23
plugins/gitea/skills/gitea-files/README.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# gitea-files
|
||||
|
||||
Read and write individual files and directory/repository trees in a Gitea repository via the Gitea MCP server.
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles file-domain operations within the Gitea integration suite: reading a single file's contents, listing one directory level, walking a full repository tree (optionally recursive), creating or updating a file, and deleting a file. It owns the SHA-based optimistic-concurrency pattern that Gitea requires for file writes — the domain's sharpest gotcha — and defers branch creation, commit history, and pull request mechanics to `gitea-branches` and `gitea-prs`.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/gitea-files
|
||||
```
|
||||
|
||||
Describe the file task: read a file or directory, walk a tree, create/update a file, or delete a file. Provide `owner`/`repo`/branch (or ask the user if not given) — this skill does not resolve them from a git remote itself.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `references/examples.md` | Canonical call sequences: branch + file + PR, recovering a missing SHA before an update, deleting a file |
|
||||
| `references/sources.md` | Research sources backing the SHA/concurrency and direct-commit-vs-PR guidance |
|
||||
53
plugins/gitea/skills/gitea-files/SKILL.md
Normal file
53
plugins/gitea/skills/gitea-files/SKILL.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: gitea-files
|
||||
|
||||
description: >
|
||||
Use when reading or writing individual files or directory trees in a Gitea repository via the
|
||||
Gitea MCP server: reading a file's contents, listing a directory, walking a full repository
|
||||
tree, creating a new file, updating an existing file, or deleting a file. Triggers on "read this
|
||||
file from the repo", "what's in this directory", "show me the repo tree", "create/update a file
|
||||
in Gitea", "commit this file to the branch", "delete this file from the repo" — even when the
|
||||
user doesn't say "Gitea" explicitly, as long as the target is a Gitea-hosted repository. Do not
|
||||
use for local filesystem file operations (use Read/Write/Edit), for branch or commit history
|
||||
(use gitea-branches), or for opening a pull request around a file change (use gitea-prs after
|
||||
the file write completes here).
|
||||
|
||||
compatibility: Requires the Gitea MCP server configured with a token scoped to at least
|
||||
write:repository. Tested with a token holding write:issue + write:repository; write:issue
|
||||
is not actually required for any of this domain's five tools.
|
||||
|
||||
metadata:
|
||||
category: gitea
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
- context7-websites-gitea
|
||||
|
||||
allowed-tools: mcp__gitea__get_file_contents mcp__gitea__get_dir_contents mcp__gitea__get_repository_tree mcp__gitea__create_or_update_file mcp__gitea__delete_file
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **SHA is the concurrency token for every write — and it lives at the top level of `get_file_contents`'s response, not nested under `content`.** `create_or_update_file` without `sha` is always treated as a *create*: if the path already exists, Gitea returns HTTP 409. `delete_file` has no optional path at all — omitting `sha` returns HTTP 422. The safe sequence for any update or delete is always: call `get_file_contents` first, read the top-level `sha` field, then pass that exact value to the write call. Never guess or reuse a stale SHA — a mismatched SHA is rejected the same as a missing one.
|
||||
- **`get_dir_contents` and `get_repository_tree` are not SHA sources for a specific file's write.** `get_dir_contents` entries carry no `sha` at all. `get_repository_tree` entries do carry a `sha` (a blob/tree hash), but fetching it means an extra round trip with no content — `get_file_contents` is the canonical path since it returns the decoded content and the write-ready `sha` in one call.
|
||||
- **`owner` and `repo` are always caller-supplied inputs, never resolved here.** This skill doesn't infer them from a git remote. If invoked directly by a human, ask for them if not stated. If invoked by `gitea-workflow` or an orchestrating agent, expect them to already be resolved and passed in.
|
||||
- **Direct commits to a branch are a first-class action, not a workaround.** Gitea's own web UI defaults to editing files directly against a branch — `create_or_update_file`/`delete_file` used that way is normal, not an API escape hatch to avoid. The SHA-currency requirement above is the actual risk to manage, not the act of committing directly.
|
||||
- **`ref` (reads) vs. `branch_name` (writes) are different parameters for the same concept.** `get_file_contents`, `get_dir_contents`, and `get_repository_tree` (as `tree_sha`) all accept a branch name, tag, or commit SHA to select what to read. `create_or_update_file` and `delete_file` instead take `branch_name` — the branch the commit lands on. Don't conflate the two when chaining a read into a write.
|
||||
- **Content is base64.** `create_or_update_file`'s `content` parameter is base64-encoded file content, not raw text — encode before calling. `get_file_contents`'s response content is likewise base64-encoded (decode after reading), unless `withLines: true` is passed for a numbered-line view.
|
||||
|
||||
## Reading
|
||||
|
||||
- **Single file:** `get_file_contents(owner, repo, ref, path)`. Pass `withLines: true` only when you need line numbers for referencing specific lines (e.g. quoting a snippet back to the user); omit it for a normal content fetch.
|
||||
- **One directory level:** `get_dir_contents(owner, repo, ref, path)` — returns immediate entries only (name, path, type, size), no recursion, no SHA, no content.
|
||||
- **Whole tree:** `get_repository_tree(owner, repo, tree_sha, recursive)` — `tree_sha` accepts a SHA, branch, or tag name despite the name. Set `recursive: true` to walk subdirectories in one call. Response includes `truncated: true` when a page doesn't hold every entry — page through with `page`/`per_page` (default `page: 1`, `per_page: 30`) until you get fewer results than `per_page`.
|
||||
|
||||
## Writing
|
||||
|
||||
- **Creating a new file:** call `create_or_update_file(owner, repo, path, content, message, branch_name)` with `sha` omitted entirely.
|
||||
- **Updating an existing file:** call `get_file_contents(owner, repo, ref: branch_name, path)` first, take the top-level `sha`, then call `create_or_update_file(..., sha: <that value>)`.
|
||||
- **Deleting a file:** call `get_file_contents` first the same way, then `delete_file(owner, repo, path, message, branch_name, sha: <that value>)` — `sha` is required, no create-style fallback exists.
|
||||
- **Creating a new branch as part of the write:** pass `new_branch_name` on `create_or_update_file` to branch off before the commit lands, instead of calling a separate branch-creation step.
|
||||
|
||||
If the change needs review before merging, or targets a protected branch, hand off to `gitea-prs` after the write lands here to open the pull request — this skill's scope ends at the commit.
|
||||
|
||||
If you need the full multi-call sequence rather than the single-call summary above — e.g. branching off as part of a file push ahead of opening a PR, or recovering a SHA you didn't capture earlier — read `references/examples.md`.
|
||||
65
plugins/gitea/skills/gitea-files/references/examples.md
Normal file
65
plugins/gitea/skills/gitea-files/references/examples.md
Normal file
@@ -0,0 +1,65 @@
|
||||
---
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Canonical call sequences
|
||||
|
||||
## Push a file to a new branch, then open a PR
|
||||
|
||||
```
|
||||
1. get_repository_tree or get_file_contents on the base branch — only needed if the
|
||||
new file is actually replacing an existing one; skip for a brand-new path.
|
||||
|
||||
2. create_or_update_file
|
||||
owner, repo
|
||||
path: "docs/example.md"
|
||||
content: "<base64-encoded content>"
|
||||
message: "docs: add example"
|
||||
branch_name: "main"
|
||||
new_branch_name: "feat/add-example" ← branches off before the commit lands
|
||||
(sha omitted — this is a new file)
|
||||
|
||||
3. Hand off to gitea-prs to open a PR from "feat/add-example" into "main".
|
||||
```
|
||||
|
||||
`new_branch_name` on `create_or_update_file` replaces a separate branch-creation call — the branch is created and the commit lands on it in one step.
|
||||
|
||||
## Update a file when you don't already have its SHA
|
||||
|
||||
SHA is mandatory for updates. If it wasn't captured earlier in the conversation:
|
||||
|
||||
```
|
||||
1. get_file_contents
|
||||
owner, repo
|
||||
ref: "main"
|
||||
path: "docs/example.md"
|
||||
→ read the top-level `sha` field (not content.sha)
|
||||
|
||||
2. create_or_update_file
|
||||
owner, repo
|
||||
path: "docs/example.md"
|
||||
content: "<new base64-encoded content>"
|
||||
message: "docs: update example"
|
||||
branch_name: "main"
|
||||
sha: "<sha from step 1>"
|
||||
```
|
||||
|
||||
Do not guess or omit the SHA — the write either fails (409 on create-path fallback) or is rejected outright.
|
||||
|
||||
## Delete a file
|
||||
|
||||
Same SHA-first pattern, no fallback path:
|
||||
|
||||
```
|
||||
1. get_file_contents owner, repo, ref: "main", path: "docs/old-example.md"
|
||||
→ read the top-level `sha` field
|
||||
|
||||
2. delete_file
|
||||
owner, repo
|
||||
path: "docs/old-example.md"
|
||||
message: "docs: remove old example"
|
||||
branch_name: "main"
|
||||
sha: "<sha from step 1>"
|
||||
```
|
||||
36
plugins/gitea/skills/gitea-files/references/sources.md
Normal file
36
plugins/gitea/skills/gitea-files/references/sources.md
Normal file
@@ -0,0 +1,36 @@
|
||||
# Sources
|
||||
|
||||
## gitea-mcp-repo
|
||||
|
||||
**Description:** Official gitea-mcp repository (v1.3.0); operation/*.go source files documenting all 55 MCP tools, their parameters, and CLI flags.
|
||||
|
||||
**Source:** https://gitea.com/gitea/gitea-mcp
|
||||
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Gotchas, Reading, Writing — tool parameters and SHA/concurrency behavior, cross-checked live against the deployed MCP tool schemas via ToolSearch)
|
||||
- references/examples.md (canonical call sequences)
|
||||
|
||||
## gitea-mcp-slim-go
|
||||
|
||||
**Description:** Slim response shape structs from gitea-mcp source; defines exactly which fields the MCP server returns for files (top-level `sha`, no nested `content.sha`) and directory/tree entries.
|
||||
|
||||
**Source:** https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/repo/slim.go
|
||||
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Gotchas — top-level `sha` field location, `get_dir_contents`/`get_repository_tree` not being usable SHA sources for a file write)
|
||||
- references/examples.md (SHA-first update/delete sequences)
|
||||
|
||||
## context7-websites-gitea
|
||||
|
||||
**Description:** Official Gitea docs mirror on Context7 (docs.gitea.com content) — confirms direct-commit file editing through the web UI is a first-class, expected workflow rather than an API-only escape hatch.
|
||||
|
||||
**Source:** context7:/websites/gitea
|
||||
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Gotchas — "Direct commits to a branch are a first-class action, not a workaround")
|
||||
25
plugins/gitea/skills/gitea-labels-milestones/README.md
Normal file
25
plugins/gitea/skills/gitea-labels-milestones/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# gitea-labels-milestones
|
||||
|
||||
Read and write Gitea labels and milestones, and resolve label/milestone identity for the skills that apply them to issues and PRs.
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles label and milestone CRUD (`label_read`/`label_write`, `milestone_read`/`milestone_write`) — listing repo or org labels, creating/editing/deleting a label, resolving a label name to the numeric ID required for any write, and listing/creating/updating/closing/deleting a milestone. It also owns label inference: mapping conversation context (bug report, feature request, urgency language) to this repo's `Kind/*`/`Priority/*`/`Status/*` taxonomy. It is a cross-cutting shared skill composed by `gitea-issues` and `gitea-prs`, which call into it for label/milestone resolution before their own `issue_write`/`pull_request_write` calls apply the resolved IDs.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/gitea-labels-milestones
|
||||
```
|
||||
|
||||
Describe the label or milestone task: list labels, resolve a name to an ID, create/edit/delete a label, or list/create/update/close/delete a milestone. For applying already-resolved labels or a milestone to a specific issue or PR, use `gitea-issues` or `gitea-prs` instead.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents — dispatch table and Gotchas |
|
||||
| `references/labels.md` | Execution detail for `label_read`/`label_write` |
|
||||
| `references/milestones.md` | Execution detail for `milestone_read`/`milestone_write` |
|
||||
| `references/label-inference.md` | Context-pattern → `Kind/*`/`Priority/*`/`Status/*` label inference guide |
|
||||
| `references/sources.md` | Research sources backing the label/milestone guidance |
|
||||
58
plugins/gitea/skills/gitea-labels-milestones/SKILL.md
Normal file
58
plugins/gitea/skills/gitea-labels-milestones/SKILL.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
name: gitea-labels-milestones
|
||||
|
||||
description: >
|
||||
Use when reading or writing Gitea labels or milestones — listing repo/org labels, creating,
|
||||
editing, or deleting a label, resolving label names to the numeric IDs required for applying
|
||||
them to an issue or PR, or listing, creating, updating, closing, or deleting a milestone. This is
|
||||
a cross-cutting shared skill: `gitea-issues` and `gitea-prs` both compose it whenever they need to
|
||||
apply labels or assign a milestone, rather than duplicating label/milestone logic. Also use for
|
||||
label inference — mapping a bug report, feature request, or urgency signal in conversation
|
||||
context to the repo's `Kind/*`/`Priority/*`/`Status/*` label taxonomy. Do not use for applying
|
||||
already-resolved label IDs or milestone IDs to a specific issue or PR — that write goes through
|
||||
`issue_write`/`pull_request_write` in `gitea-issues`/`gitea-prs`, not here.
|
||||
|
||||
compatibility: Requires Gitea MCP server configured with write:issue and write:repository token scopes.
|
||||
|
||||
metadata:
|
||||
category: integration
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
- context7-websites-gitea
|
||||
- context7-gitea-tea-cli
|
||||
version: "0.1.0"
|
||||
|
||||
allowed-tools: mcp__gitea__label_read mcp__gitea__label_write mcp__gitea__milestone_read mcp__gitea__milestone_write
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Label writes take IDs, reads return names.** `label_read` is the only tool that returns full label objects (`id`, `name`, `color`, `description`). Issue/PR responses slim labels down to name strings. Before any label is applied to an issue or PR (in `gitea-issues`/`gitea-prs`), resolve names → IDs here via `label_read method: "list_repo_labels"` — never pass a name string where an ID is expected.
|
||||
- **Milestones are referenced by ID everywhere, never by title.** `milestone_write` update/delete take `id`. The one place titles show up as the sole handle is the `pull_request_read` response (see next gotcha).
|
||||
- **Milestone representation differs between issues and PRs.** `issue_read` returns `milestone: {id, title}` — an object. `pull_request_read` returns `milestone: "title string"` — title only, no ID. You cannot recover a milestone ID from a PR response directly; call `milestone_read method: "list"` and match by title instead.
|
||||
- **Repo labels and org labels are separate pools, never mixed in one call.** `label_read`/`label_write` take either `owner`+`repo` (repo-scoped methods) or `org` (org-scoped methods) — passing both or neither for a given method is a caller error, not something the schema enforces for you. Repo and org labels can both apply to the same issue, but you list/create/edit them through different method values.
|
||||
- **`milestone_write` accepts `"update"` and `"edit"` as the same operation.** Both method values map to the identical update call. Prefer `"update"` for consistency with `issue_write`/`pull_request_write`.
|
||||
- **A `/` in a label name plus `exclusive: true` means mutual exclusivity, not just a naming convention.** This repo's `Kind/*`, `Priority/*`, `Status/*` labels follow Gitea's native scoped-label feature: applying a new label within a scope (e.g. `Priority/High`) is expected to replace any existing label in that same scope, not add alongside it. Label inference (see `references/label-inference.md`) must respect this — replace, don't stack.
|
||||
- **Pagination is manual on every list call.** `label_read` and `milestone_read` both default to `per_page: 30`. Iterate `page: 1, 2, ...` until the result count is less than `per_page` — there is no cursor or auto-pagination.
|
||||
- **Schema requiredness differs between the two tool families.** `milestone_read`/`milestone_write` have `owner` and `repo` as hard-required parameters (the call fails validation without them). `label_read`/`label_write` only hard-require `method` — `owner`/`repo`/`org` are functionally required per method but not schema-enforced, so passing none produces a runtime error from Gitea, not a client-side validation error.
|
||||
|
||||
## Dispatch
|
||||
|
||||
| Task | Tool | method |
|
||||
|---|---|---|
|
||||
| List repo labels | `label_read` | `"list_repo_labels"` |
|
||||
| Get one repo label by ID | `label_read` | `"get_repo_label"` |
|
||||
| List org labels | `label_read` | `"list_org_labels"` |
|
||||
| Create a repo/org label | `label_write` | `"create_repo_label"` / `"create_org_label"` |
|
||||
| Edit a repo/org label | `label_write` | `"edit_repo_label"` / `"edit_org_label"` |
|
||||
| Delete a repo/org label | `label_write` | `"delete_repo_label"` / `"delete_org_label"` |
|
||||
| List milestones | `milestone_read` | `"list"` |
|
||||
| Get one milestone by ID | `milestone_read` | `"get"` |
|
||||
| Create a milestone | `milestone_write` | `"create"` |
|
||||
| Update / close a milestone | `milestone_write` | `"update"` |
|
||||
| Delete a milestone | `milestone_write` | `"delete"` |
|
||||
|
||||
For full parameter detail and step-by-step call sequences, read `references/labels.md` (label operations) or `references/milestones.md` (milestone operations). For mapping conversation context to a label to apply, read `references/label-inference.md`.
|
||||
|
||||
Applying resolved label IDs or a milestone ID to a specific issue or PR is out of scope here — that's `issue_write`/`pull_request_write` in the composing skill (`gitea-issues`/`gitea-prs`).
|
||||
@@ -0,0 +1,64 @@
|
||||
---
|
||||
topic: label-inference
|
||||
source_keys:
|
||||
- context7-websites-gitea
|
||||
- gitea-mcp-repo
|
||||
---
|
||||
|
||||
# Label inference guide
|
||||
|
||||
Maps context-pattern signals from conversation content (an issue being drafted, a bug report, a PR
|
||||
description) to this repo's `Kind/*` / `Priority/*` / `Status/*` label taxonomy. Used by
|
||||
`gitea-issues` and `gitea-prs` before creating or updating an issue/PR, and directly when the user
|
||||
asks to label something without naming exact labels.
|
||||
|
||||
## Scoped labels are mutually exclusive — replace, don't stack
|
||||
|
||||
Each of `Kind/*`, `Priority/*`, `Status/*` is a Gitea scoped-label group (the `/` delimiter plus
|
||||
`exclusive: true` on the label). Applying a new label within a scope is expected to replace any
|
||||
existing label in that same scope on the target issue/PR, not add alongside it. When inference
|
||||
selects a `Priority/High` label and the issue already carries `Priority/Medium`, the write should
|
||||
result in only `Priority/High` remaining — use `replace_labels` scoped to that group's labels, or at
|
||||
minimum remove the superseded label before adding the new one. Never leave two labels from the same
|
||||
scope applied at once.
|
||||
|
||||
## Signal → label mapping
|
||||
|
||||
**`Kind/*`** (what kind of work this is):
|
||||
|
||||
| Signal in context | Label |
|
||||
|---|---|
|
||||
| Bug report, error, crash, unexpected behavior, "broken", "doesn't work" | `Kind/Bug` |
|
||||
| New capability, "add support for", net-new functionality | `Kind/Feature` |
|
||||
| Improvement to existing behavior, "make X better", refactor with behavior change | `Kind/Enhancement` |
|
||||
| Docs-only change, README/comment/guide updates | `Kind/Documentation` |
|
||||
| Vulnerability, credential exposure, injection risk, auth bypass | `Kind/Security` |
|
||||
|
||||
**`Priority/*`** (urgency):
|
||||
|
||||
| Signal in context | Label |
|
||||
|---|---|
|
||||
| "blocking", "critical", "urgent", production-down | `Priority/Critical` |
|
||||
| "soon", "high priority", "should do this sprint" | `Priority/High` |
|
||||
| No urgency signal present | `Priority/Medium` (default) |
|
||||
|
||||
**`Status/*`** (workflow state):
|
||||
|
||||
| Signal in context | Label |
|
||||
|---|---|
|
||||
| Explicit statement that the work is blocked on something else | `Status/Blocked` |
|
||||
|
||||
## Procedure
|
||||
|
||||
1. Read the conversation context (issue/PR title, body, or the triggering discussion) for the
|
||||
signals above.
|
||||
2. Call `label_read method: "list_repo_labels"` (see `references/labels.md`) to get the current
|
||||
label set with IDs — inference must never guess an ID, only a name, then resolve it.
|
||||
3. Match inferred label names against the resolved list (case-insensitive). If a scope group
|
||||
already has a different label applied on the target and a new one is inferred for that same
|
||||
scope, plan to replace rather than add (see above).
|
||||
4. **Low-confidence inference omits the label.** If no signal confidently maps to a `Kind/*` value,
|
||||
do not guess — omit `Kind/*` entirely rather than default to one. `Priority/Medium` is the one
|
||||
exception: it's the explicit default when no urgency signal is present, not a guess.
|
||||
5. Hand the resolved IDs (plus which scopes to replace) to the caller's `issue_write`/
|
||||
`pull_request_write` call — this skill does not apply labels to an issue or PR itself.
|
||||
@@ -0,0 +1,97 @@
|
||||
---
|
||||
topic: labels
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Label operations
|
||||
|
||||
Execution detail for `label_read` and `label_write`. Both tools operate on either **repo-scoped**
|
||||
or **org-scoped** labels — never both in one call. Pick the method family (`*_repo_label*` vs.
|
||||
`*_org_label*`) that matches the target, and pass `owner`+`repo` or `org` accordingly.
|
||||
|
||||
## Verified live schemas
|
||||
|
||||
`label_read` — required: `method`.
|
||||
|
||||
| Param | Type | Notes |
|
||||
|---|---|---|
|
||||
| `method` | string (enum) | `"list_repo_labels"` \| `"get_repo_label"` \| `"list_org_labels"` |
|
||||
| `owner` | string | for repo methods |
|
||||
| `repo` | string | for repo methods |
|
||||
| `org` | string | for org methods |
|
||||
| `id` | number | label ID, required for `"get_repo_label"` |
|
||||
| `page` | number | default `1` |
|
||||
| `per_page` | number | default `30` |
|
||||
|
||||
`label_write` — required: `method`.
|
||||
|
||||
| Param | Type | Notes |
|
||||
|---|---|---|
|
||||
| `method` | string (enum) | `"create_repo_label"` \| `"edit_repo_label"` \| `"delete_repo_label"` \| `"create_org_label"` \| `"edit_org_label"` \| `"delete_org_label"` |
|
||||
| `owner` | string | for repo methods |
|
||||
| `repo` | string | for repo methods |
|
||||
| `org` | string | for org methods |
|
||||
| `id` | number | for edit/delete |
|
||||
| `name` | string | required for create |
|
||||
| `color` | string | hex `#RRGGBB`, required for create |
|
||||
| `description` | string | optional |
|
||||
| `exclusive` | boolean | org labels only |
|
||||
| `is_archived` | boolean | repo labels only |
|
||||
|
||||
Note: unlike `milestone_read`/`milestone_write`, `owner`/`repo`/`org` are **not** schema-required on
|
||||
either label tool — only `method` is. Passing none for a repo/org method still fails, just as a
|
||||
runtime error from Gitea rather than a client-side validation error.
|
||||
|
||||
## List repo labels
|
||||
|
||||
```
|
||||
label_read method: "list_repo_labels" owner: <owner> repo: <repo> per_page: 50
|
||||
```
|
||||
|
||||
Paginate (`page: 1, 2, ...`) until the returned count is less than `per_page`. This is the only way
|
||||
to build a complete name → ID map — there is no lookup-by-name endpoint.
|
||||
|
||||
## Get one label
|
||||
|
||||
```
|
||||
label_read method: "get_repo_label" owner: <owner> repo: <repo> id: <id>
|
||||
```
|
||||
|
||||
## Resolve a name to an ID
|
||||
|
||||
There is no direct name lookup. List all repo labels (paginating if needed), scan for a
|
||||
case-insensitive name match, and extract `id`. This is the required first step before any label
|
||||
application on an issue or PR — the actual `add_labels`/`replace_labels`/`remove_label` call lives
|
||||
in `gitea-issues`/`gitea-prs` via `issue_write`/`pull_request_write`, which take numeric IDs only.
|
||||
|
||||
## Create a label
|
||||
|
||||
```
|
||||
label_write method: "create_repo_label"
|
||||
owner: <owner> repo: <repo>
|
||||
name: "Kind/Bug"
|
||||
color: "#d73a4a"
|
||||
description: "Confirmed bug"
|
||||
```
|
||||
|
||||
For an org label, use `method: "create_org_label"` with `org:` instead of `owner`/`repo`, and
|
||||
`exclusive: true` if the label belongs to a mutually-exclusive scope group.
|
||||
|
||||
## Edit a label
|
||||
|
||||
```
|
||||
label_write method: "edit_repo_label" owner: <owner> repo: <repo> id: <id> color: "#ff0000"
|
||||
```
|
||||
|
||||
Only pass the fields being changed — `id` plus any of `name`/`color`/`description`/`is_archived`.
|
||||
|
||||
## Delete a label
|
||||
|
||||
```
|
||||
label_write method: "delete_repo_label" owner: <owner> repo: <repo> id: <id>
|
||||
```
|
||||
|
||||
Deleting a label does not remove it from historical issue/PR timeline events — it disappears only
|
||||
from current label lists.
|
||||
@@ -0,0 +1,98 @@
|
||||
---
|
||||
topic: milestones
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Milestone operations
|
||||
|
||||
Execution detail for `milestone_read` and `milestone_write`. Milestones are always repo-scoped —
|
||||
there is no org-level milestone concept, unlike labels.
|
||||
|
||||
## Verified live schemas
|
||||
|
||||
`milestone_read` — required: `method`, `owner`, `repo`.
|
||||
|
||||
| Param | Type | Notes |
|
||||
|---|---|---|
|
||||
| `method` | string (enum) | `"get"` \| `"list"` |
|
||||
| `owner` | string | required |
|
||||
| `repo` | string | required |
|
||||
| `id` | number | milestone ID, required for `"get"` |
|
||||
| `name` | string | title filter, for `"list"` |
|
||||
| `state` | string | default `"all"` — conventional values `"open"`/`"closed"`/`"all"`, but **not enforced by an enum in the live schema** (plain string). Any other value is passed through to Gitea rather than rejected client-side. |
|
||||
| `page` | number | default `1` |
|
||||
| `per_page` | number | default `30` |
|
||||
|
||||
`milestone_write` — required: `method`, `owner`, `repo`.
|
||||
|
||||
| Param | Type | Notes |
|
||||
|---|---|---|
|
||||
| `method` | string (enum) | `"create"` \| `"update"` \| `"edit"` \| `"delete"` — `"update"`/`"edit"` are aliases for the same operation; prefer `"update"` |
|
||||
| `owner` | string | required |
|
||||
| `repo` | string | required |
|
||||
| `id` | number | required for update/delete |
|
||||
| `title` | string | required for create |
|
||||
| `description` | string | optional |
|
||||
| `due_on` | string | due date — the live tool schema only describes this as an opaque "due date" string with no enforced format; ISO 8601 (e.g. `"2025-03-01T00:00:00Z"`) is the conventional value Gitea's REST API accepts, not something confirmed by the live MCP schema itself |
|
||||
| `state` | string (enum) | `"open"` \| `"closed"` — **this one is schema-enforced**, unlike `milestone_read`'s `state` |
|
||||
|
||||
Note: unlike `label_read`/`label_write`, both milestone tools hard-require `owner` and `repo` at the
|
||||
schema level — there's no scope variant to omit them for.
|
||||
|
||||
## List milestones
|
||||
|
||||
```
|
||||
milestone_read method: "list" owner: <owner> repo: <repo> state: "open"
|
||||
```
|
||||
|
||||
Report each as: id, title, state, due date, open/closed issue counts.
|
||||
|
||||
## Get one milestone
|
||||
|
||||
```
|
||||
milestone_read method: "get" owner: <owner> repo: <repo> id: <id>
|
||||
```
|
||||
|
||||
## Resolve a milestone ID from a title
|
||||
|
||||
Needed whenever the only handle available is a title — e.g. a `pull_request_read` response, which
|
||||
returns `milestone` as a bare title string rather than `{id, title}`. Call:
|
||||
|
||||
```
|
||||
milestone_read method: "list" owner: <owner> repo: <repo> name: <title>
|
||||
```
|
||||
|
||||
and take the `id` of the matching result. If `name` filtering returns no match (e.g. due to a
|
||||
title typo or case mismatch), fall back to listing without the filter and matching manually.
|
||||
|
||||
## Create a milestone
|
||||
|
||||
```
|
||||
milestone_write method: "create"
|
||||
owner: <owner> repo: <repo>
|
||||
title: "v1.0"
|
||||
description: "First stable release"
|
||||
due_on: "2025-03-01T00:00:00Z"
|
||||
```
|
||||
|
||||
Report the returned ID — the caller (`gitea-issues`/`gitea-prs`) needs it to assign issues/PRs to
|
||||
this milestone via `issue_write`/`pull_request_write`.
|
||||
|
||||
## Update or close a milestone
|
||||
|
||||
```
|
||||
milestone_write method: "update" owner: <owner> repo: <repo> id: <id> state: "closed"
|
||||
```
|
||||
|
||||
Only pass the fields being changed — `id` plus any of `title`/`description`/`due_on`/`state`.
|
||||
|
||||
## Delete a milestone
|
||||
|
||||
```
|
||||
milestone_write method: "delete" owner: <owner> repo: <repo> id: <id>
|
||||
```
|
||||
|
||||
Deleting a milestone does not delete or unassign the issues/PRs that referenced it — they simply
|
||||
lose the milestone reference.
|
||||
@@ -0,0 +1,33 @@
|
||||
# Sources
|
||||
|
||||
## gitea-mcp-repo
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp
|
||||
- **Description:** Official gitea-mcp repository (v1.3.0); operation/*.go source files documenting all 55 MCP tools, their parameters, and CLI flags
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md, references/labels.md, references/milestones.md, references/label-inference.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## gitea-mcp-slim-go
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/issue/slim.go, https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/pull/slim.go, https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/repo/slim.go
|
||||
- **Description:** Slim response shape structs from gitea-mcp source; defines exactly which fields the MCP server returns for issues, PRs, branches, commits, tags, releases, and files — including the label name-vs-ID and milestone object-vs-string representation quirks this skill's Gotchas document
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md, references/labels.md, references/milestones.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## context7-websites-gitea
|
||||
|
||||
- **URL:** context7:/websites/gitea
|
||||
- **Description:** Official Gitea docs mirror on Context7 (docs.gitea.com content) — scoped/exclusive label conventions and milestone/label state-transition semantics
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md, references/label-inference.md
|
||||
- **Status:** `extracted`
|
||||
|
||||
## context7-gitea-tea-cli
|
||||
|
||||
- **URL:** context7:/git_gitea_com/gitea_tea
|
||||
- **Description:** Official `tea` CLI (reference Gitea client) docs on Context7 — practitioner command patterns for labels and milestones
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/sources.md
|
||||
- **Contributing files:** SKILL.md
|
||||
- **Status:** `extracted`
|
||||
24
plugins/gitea/skills/gitea-releases/README.md
Normal file
24
plugins/gitea/skills/gitea-releases/README.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# gitea-releases
|
||||
|
||||
Manage Gitea releases and tags — list, create, and delete releases (with draft/prerelease flags and notes) and their underlying tags.
|
||||
|
||||
## What it does
|
||||
|
||||
This skill handles release and tag operations for a Gitea repository. It creates releases from a tag/target commitish with title, notes, and draft/prerelease flags; lists and paginates releases and tags; retrieves the latest release; and deletes releases and tags as separate, independent destructive operations. It resolves the numeric release id required for deletion instead of assuming a tag name will work.
|
||||
|
||||
## Usage
|
||||
|
||||
```
|
||||
/gitea-releases
|
||||
```
|
||||
|
||||
Describe your release/tag task: list releases, get the latest release, create a release (with a tag, target, and title), or delete a release or tag. The skill handles resolving the numeric release id where required and keeps release/tag deletion as distinct operations.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Purpose |
|
||||
|------|---------|
|
||||
| `SKILL.md` | Skill instructions for agents |
|
||||
| `references/call-signatures.md` | Verified tool parameters and response shapes for all 9 release/tag tools |
|
||||
| `references/conventions.md` | Semver/draft/prerelease practitioner conventions and pagination behavior |
|
||||
| `references/sources.md` | Research sources backing the call signatures and conventions |
|
||||
52
plugins/gitea/skills/gitea-releases/SKILL.md
Normal file
52
plugins/gitea/skills/gitea-releases/SKILL.md
Normal file
@@ -0,0 +1,52 @@
|
||||
---
|
||||
name: gitea-releases
|
||||
|
||||
description: >
|
||||
Use when managing Gitea releases and tags for a repository: listing, creating, or deleting
|
||||
releases (with draft/prerelease flags and release notes), and listing, creating, or deleting the
|
||||
underlying git tags. Use even if the user doesn't say "release" explicitly — "cut a v1.2.0",
|
||||
"publish a prerelease", "tag this commit", or "what's the latest release" all apply. Do not use
|
||||
for git branch or commit history operations (use gitea-branches) or for issue/PR management (use
|
||||
gitea-issues / gitea-prs).
|
||||
|
||||
metadata:
|
||||
category: gitea
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
- context7-websites-gitea
|
||||
- context7-gitea-tea-cli
|
||||
---
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **`delete_release` takes a numeric `id`, never a tag name.** `delete_tag` is the mirror opposite — it takes the `tag_name` string, never a numeric id. These two tools are asymmetric on purpose; passing a tag name to `delete_release` or a numeric id to `delete_tag` fails. Always resolve the numeric release id via `list_releases` or `get_release` first if you only have a tag name in hand.
|
||||
- **Deleting a release does not delete its tag.** They are separate destructive operations against separate resources — a release is a wrapper (title, notes, draft/prerelease flags, assets) around a tag, not the tag itself. If the intent is to remove both, call `delete_release` and `delete_tag` separately.
|
||||
- **`list_releases`/`list_tags` default to `per_page: 20`**, unlike most other gitea-mcp tools which default to 30. There is no auto-pagination in the MCP layer — to get a complete result set, loop `page` upward until a page returns fewer than `per_page` results.
|
||||
- **`draft`/`is_pre_release` are explicit booleans the caller sets on `create_release` — never inferred from `tag_name`.** Practitioner convention (per the `tea` CLI) uses `-beta`/`-rc` suffixes for prereleases (e.g. `v2.0.0-beta.1`), but Gitea does not enforce or infer this from the tag string. If the user names a tag that looks like a prerelease, set `is_pre_release: true` explicitly rather than assuming the flag is redundant with the name.
|
||||
- **Tag names are conventionally semver, `v`-prefixed** (`v1.2.0`, `v2.0.0-beta.1`), but this is a practitioner convention, not a Gitea constraint — don't reject or rewrite a caller-supplied tag name that doesn't follow it.
|
||||
|
||||
## Dispatch table
|
||||
|
||||
| Action | Tool | Required params | Optional params |
|
||||
|---|---|---|---|
|
||||
| List releases | `list_releases` | `owner`, `repo` | `is_draft`, `is_pre_release`, `page` (default 1), `per_page` (default 20) |
|
||||
| Get one release | `get_release` | `owner`, `repo`, `id` (number) | — |
|
||||
| Get latest release | `get_latest_release` | `owner`, `repo` | — |
|
||||
| Create release | `create_release` | `owner`, `repo`, `tag_name`, `target`, `title` | `body`, `is_draft`, `is_pre_release` |
|
||||
| Delete release | `delete_release` | `owner`, `repo`, `id` (number) | — |
|
||||
| List tags | `list_tags` | `owner`, `repo` | `page` (default 1), `per_page` (default 20) |
|
||||
| Get one tag | `get_tag` | `owner`, `repo`, `tag_name` | — |
|
||||
| Create tag | `create_tag` | `owner`, `repo`, `tag_name` | `target`, `message` |
|
||||
| Delete tag | `delete_tag` | `owner`, `repo`, `tag_name` | — |
|
||||
|
||||
`target` (on `create_release`/`create_tag`) is a commitish — a branch name, existing tag, or commit SHA — the point the new tag is cut from. See `references/call-signatures.md` for response shapes.
|
||||
|
||||
## Workflow
|
||||
|
||||
- [ ] **Creating a release:** Call `create_release` directly with `tag_name` + `target` + `title` — it creates the underlying tag automatically if `tag_name` doesn't already exist, so a separate `create_tag` call is only needed when you want to tag a commit without wrapping it in a release yet. Set `is_pre_release`/`is_draft` explicitly per the Gotchas above; don't leave them to default inference.
|
||||
- [ ] **Deleting a release safely:** Resolve the numeric id first — call `list_releases` (paginate if needed, see Gotchas) or `get_release` if the id is already known, find the entry matching the target `tag_name`, then call `delete_release` with that `id`. Never pass `tag_name` to `delete_release`.
|
||||
- [ ] **Deleting a tag along with its release:** Delete the release first (frees the id lookup), then call `delete_tag` with the `tag_name` separately — confirm both are intended before proceeding, since each is an independent irreversible operation.
|
||||
- [ ] **Listing completely:** If the caller needs all releases or tags (not just the first page), loop `page: 1, 2, 3...` until a response has fewer than `per_page` entries.
|
||||
|
||||
If exact response field shapes or additional conventions are needed, read `references/call-signatures.md` and `references/conventions.md`.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
topic: call-signatures
|
||||
source_keys:
|
||||
- gitea-mcp-repo
|
||||
- gitea-mcp-slim-go
|
||||
---
|
||||
|
||||
# Release and tag call signatures
|
||||
|
||||
Verified against the live MCP tool schemas at authoring time (not copied from upstream API docs,
|
||||
which can drift from the deployed gitea-mcp version). `owner` and `repo` are required strings on
|
||||
every tool below and are omitted from the per-tool lists for brevity.
|
||||
|
||||
## Releases
|
||||
|
||||
**`list_releases`**
|
||||
- Optional: `is_draft` (boolean), `is_pre_release` (boolean), `page` (number, default 1), `per_page` (number, default 20)
|
||||
- Returns an array of release objects (shape below), one page at a time.
|
||||
|
||||
**`get_release`**
|
||||
- Required: `id` (number) — the release's numeric id, not its tag name.
|
||||
- Returns a single release object.
|
||||
|
||||
**`get_latest_release`**
|
||||
- No parameters beyond `owner`/`repo`.
|
||||
- Returns a single release object for the most recently published (non-draft, non-prerelease by Gitea's own "latest" definition) release.
|
||||
|
||||
**`create_release`**
|
||||
- Required: `tag_name` (string), `target` (string — branch, tag, or commit SHA to cut the tag from), `title` (string)
|
||||
- Optional: `body` (string — release notes), `is_draft` (boolean), `is_pre_release` (boolean)
|
||||
- If `tag_name` doesn't already exist as a tag, Gitea creates it against `target` as part of this call.
|
||||
|
||||
**`delete_release`**
|
||||
- Required: `id` (number) — same numeric id as `get_release`. Does not accept `tag_name`.
|
||||
- Does not delete the underlying tag.
|
||||
|
||||
**Release object shape** (returned by list/get/create/latest):
|
||||
```
|
||||
id, tag_name, target, title, body, draft, prerelease, html_url, author, created_at, published_at
|
||||
```
|
||||
`author` is the creator's login. `body` holds the release notes.
|
||||
|
||||
## Tags
|
||||
|
||||
**`list_tags`**
|
||||
- Optional: `page` (number, default 1), `per_page` (number, default 20)
|
||||
- Returns an array of `{ name, commit_sha }` — no `message` field on list responses.
|
||||
|
||||
**`get_tag`**
|
||||
- Required: `tag_name` (string)
|
||||
- Returns `{ name, message, commit_sha }` — the only tag call that returns `message`.
|
||||
|
||||
**`create_tag`**
|
||||
- Required: `tag_name` (string)
|
||||
- Optional: `target` (string — commitish to tag; if omitted, Gitea tags the default branch tip), `message` (string — annotated tag message)
|
||||
|
||||
**`delete_tag`**
|
||||
- Required: `tag_name` (string). Does not accept a numeric id.
|
||||
- Does not delete any release wrapping the tag.
|
||||
|
||||
## Pagination
|
||||
|
||||
None of the list tools auto-paginate. To collect a full result set, call with `page: 1`, then
|
||||
`page: 2`, etc., stopping when a page returns fewer items than `per_page`. `list_releases` and
|
||||
`list_tags` default `per_page` to 20 — lower than the 30-default used by most other gitea-mcp list
|
||||
tools, so a caller assuming 30 will under-count pages needed for a fixed total.
|
||||
@@ -0,0 +1,40 @@
|
||||
---
|
||||
topic: conventions
|
||||
source_keys:
|
||||
- context7-websites-gitea
|
||||
- context7-gitea-tea-cli
|
||||
---
|
||||
|
||||
# Release and tag conventions
|
||||
|
||||
Practitioner conventions that inform *how* to use the mechanics in `call-signatures.md` — not
|
||||
additional tool schemas.
|
||||
|
||||
## Release wraps a tag, not the reverse
|
||||
|
||||
A release is a title, body (notes), and draft/prerelease flags layered on top of an existing or
|
||||
newly-created tag. The tag is the git-level object (a name pointing at a commit); the release is a
|
||||
Gitea-level metadata wrapper around it. This is why `delete_release` and `delete_tag` are separate
|
||||
calls with separate identifiers (numeric id vs. tag name) — removing the wrapper never implies
|
||||
removing the underlying pointer, and vice versa.
|
||||
|
||||
## Semver tag naming
|
||||
|
||||
Per the `tea` CLI (the reference Gitea client), tag names conventionally follow semver with a `v`
|
||||
prefix: `v1.2.0`, `v2.0.0-beta.1`. This is a convention observed by tooling and humans, not a
|
||||
Gitea-enforced constraint — the API accepts any string as `tag_name`. Don't validate or rewrite a
|
||||
caller-supplied tag name against semver; just pass it through.
|
||||
|
||||
## Draft and prerelease are explicit flags
|
||||
|
||||
`draft` and `is_pre_release`/`prerelease` are booleans the caller sets directly on `create_release`
|
||||
— Gitea does not infer either from the tag name, even though the `-beta`/`-rc` suffix convention
|
||||
above is commonly used to signal a prerelease to humans. When a user asks to "cut a beta" or
|
||||
"publish a release candidate," set `is_pre_release: true` explicitly in the same call rather than
|
||||
relying on the tag string to carry that meaning.
|
||||
|
||||
## Release notes sourcing
|
||||
|
||||
Practitioner convention (per `tea`) is to source release notes (`body`) from a changelog file
|
||||
rather than typing them inline for each release — useful context when a caller asks to "generate"
|
||||
or "use the changelog for" release notes rather than write them from scratch.
|
||||
48
plugins/gitea/skills/gitea-releases/references/sources.md
Normal file
48
plugins/gitea/skills/gitea-releases/references/sources.md
Normal file
@@ -0,0 +1,48 @@
|
||||
# Sources
|
||||
|
||||
## gitea-mcp-repo
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp
|
||||
- **Description:** Official gitea-mcp repository (v1.3.0); operation/*.go source files documenting all 55 MCP tools, their parameters, and CLI flags.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/api-reference.md (Releases and Tags section); plugins/gitea/docs/research/docs/gitea/troubleshooting.md (`delete_release` numeric-id gotcha, `per_page` defaults)
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Dispatch table, Gotchas)
|
||||
- references/call-signatures.md
|
||||
|
||||
**Status:** `extracted`
|
||||
|
||||
## gitea-mcp-slim-go
|
||||
|
||||
- **URL:** https://gitea.com/gitea/gitea-mcp/raw/branch/main/operation/repo/slim.go
|
||||
- **Description:** Slim response shape structs from gitea-mcp source; defines exactly which fields the MCP server returns for tags and releases.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/api-reference.md (Releases and Tags response shapes)
|
||||
|
||||
**Contributing files:**
|
||||
- references/call-signatures.md (release/tag object shapes)
|
||||
|
||||
**Status:** `extracted`
|
||||
|
||||
## context7-websites-gitea
|
||||
|
||||
- **URL:** context7:/websites/gitea
|
||||
- **Description:** Official Gitea docs mirror on Context7 (docs.gitea.com content) — release and tag semantics, draft/prerelease behavior.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/workflow-conventions.md (Release and tag conventions section)
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Gotchas — draft/prerelease as explicit flags)
|
||||
- references/conventions.md
|
||||
|
||||
**Status:** `extracted`
|
||||
|
||||
## context7-gitea-tea-cli
|
||||
|
||||
- **URL:** context7:/git_gitea_com/gitea_tea
|
||||
- **Description:** Official `tea` CLI (reference Gitea client) docs on Context7 — practitioner release/tag command patterns, semver tag conventions, draft/prerelease flags, release-notes-from-file conventions.
|
||||
- **Research doc:** plugins/gitea/docs/research/docs/gitea/workflow-conventions.md (Release and tag conventions section)
|
||||
|
||||
**Contributing files:**
|
||||
- SKILL.md (Gotchas — semver tag naming)
|
||||
- references/conventions.md
|
||||
|
||||
**Status:** `extracted`
|
||||
Reference in New Issue
Block a user