diff --git a/CLAUDE.md b/CLAUDE.md index df36f7b..fdff350 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,22 +9,36 @@ This is a **Claude Code skills repository**. Skills are reusable tools that exte ## Skill Structure Each skill follows this convention: -- **`/SKILL.md`** — Required. YAML frontmatter (`name`, `description`, …) MUST start on line 1. This is the entry point Claude Code reads when invoking the skill. +- **`/SKILL.md`** — Required. YAML frontmatter (`name`, `description`, optionally `version`, `allowed-tools`) MUST start on line 1. This is the entry point Claude Code reads when invoking the skill. - **`/CLAUDE.md`** — Optional. Maintainer / implementation notes kept out of the user-facing SKILL.md to reduce per-invocation token cost. - **`/scripts/`** — Optional. Implementation scripts (typically bash). Scripts use `set -euo pipefail` and the `die()` pattern for error handling. Invoke scripts via `bash scripts/.sh` so they work even when the executable bit did not survive deployment — but also `chmod +x` them on commit. - **`/references/`** — Optional. Supporting files such as YAML templates or long-form reference documentation. +## Parent / child skill pattern + +A skill may act as a router that delegates to siblings. The `gitea` skill is the canonical example: its `SKILL.md` describes the overall domain and dispatches to `gitea-tea` (CLI) and `gitea-wiki` (wiki) child skills. When adding a child skill, reference the parent in the child's `description` and keep the parent's routing table current. + ## Current Skills +- **`agent-setup`** — Validates `AGENT_HOME`, derives `GH_CONFIG_DIR=$AGENT_HOME/.github`, and exports both to a session dotfile (`~/.env`) for child shells / sibling skills. - **`github-app-token`** — Generates a short-lived GitHub App installation access token, writes it to `.gh-token` under `$GH_CONFIG_DIR` (preferred) or `$AGENT_HOME` (fallback), and authenticates the `gh` CLI. Requires `GITHUB_APP_ID`, `GITHUB_APP_INSTALLATION_ID`, and one of `GITHUB_APP_PEM` (inline PEM) or `GITHUB_APP_PEM_FILE` (path). Depends on `openssl`, `curl`, `jq`, `gh`. +- **`gitea`** — Parent skill for Gitea SCM (repos, issues, PRs, releases, Actions, wiki). Routes to `gitea-tea` and `gitea-wiki`. Prefer this — and the `gitea` MCP server wired up in `.mcp.json` — over `gh`/GitHub for repos hosted on the team's Gitea instance. +- **`gitea-tea`** — Terminal operations via the `tea` CLI. Always invoke non-interactively with `--output` and explicit args. +- **`gitea-wiki`** — Wiki page CRUD via the `gitea-mcp` server (preferred) or REST API. `tea` has no wiki subcommands. - **`kubernetes-reflector`** — Documents Kubernetes Reflector annotations for mirroring secrets and configmaps across namespaces. Documentation only — no scripts. - **`minimax-image-generation`** — Generates images from MiniMax's `image-01` model via `/v1/image_generation`. Requires `MINIMAX_API_KEY`; `MINIMAX_API_BASE_URL` is optional. Depends on `curl`, `jq`, `base64`. +- **`trebuchet`** — Drive the Trebuchet pentest API (start scans, poll status, retrieve findings). Scans run as K8s Jobs orchestrated by Temporal; typical duration ~36 min. + +## MCP + +`.mcp.json` registers the `gitea` MCP server (`https://git-mcp.farh.net/mcp`) using `${GITEA_TOKEN}` as a bearer. Skills that work against Gitea should prefer MCP tools over shelling out where an equivalent MCP call exists. ## Key Patterns -- Standard Unix tools only (`openssl`, `curl`, `jq`, `base64`). Any skill-specific runtime requirement (e.g. `gh`) is declared in that skill's `SKILL.md`. +- Standard Unix tools only (`openssl`, `curl`, `jq`, `base64`). Any skill-specific runtime requirement (e.g. `gh`, `tea`) is declared in that skill's `SKILL.md`. - `die()` prints errors to stderr and exits non-zero. - Scripts validate required env vars up front and fail loudly rather than defaulting to `mktemp`/`/tmp` for anything secret. +- `AGENT_HOME` / `GH_CONFIG_DIR` are the shared conventions for where session state (tokens, config) lives — new skills that persist credentials should write under one of these, not `$HOME`. ## No Build/Test/Lint System diff --git a/gitea-tea/SKILL.md b/gitea-tea/SKILL.md index cd8354a..997430f 100644 --- a/gitea-tea/SKILL.md +++ b/gitea-tea/SKILL.md @@ -1,788 +1,135 @@ --- name: gitea-tea description: Manage Gitea via CLI using `tea`. Use when user mentions "tea", "gitea cli", or needs terminal-based Gitea operations. Use instead of GitHub CLI when agent reaches for "gh". (Child skill of `gitea` parent skill.) -version: 1.0.0 +version: 1.1.0 --- # Gitea CLI (tea) -## Overview +Official command-line tool for Gitea. Verified against **tea v0.14.1**. -Official command-line interface for Gitea. Manage issues, PRs, releases, repos, Actions, webhooks, and more from terminal. +## Decision flow -## Instructions +1. **Prefer the `gitea` MCP server** (configured in `.mcp.json`) for repos, issues, PRs, releases, branches, files, commits, tags, packages, search, notifications, actions config/runs, time tracking, wiki, and labels/milestones. See `../gitea/references/mcp-tools.md`. +2. Reach for `tea` when MCP doesn't cover the op cleanly: + - `tea clone ` — local checkout without git + - `tea pulls checkout / clean` — local-branch lifecycle for a PR + - `tea ssh-keys add/delete` — current user's SSH keys + - `tea webhooks` — webhook CRUD (MCP doesn't expose webhooks) + - `tea admin users …` — user admin (MCP doesn't expose admin) + - `tea times add/delete` — time-tracking entries (MCP exposes most; `tea` is the easier write path) + - `tea actions secrets/variables` — quick stdin/file ingestion of secret values + - `tea api …` — one-off arbitrary endpoint with auth handled +3. Avoid: `tea open` (browser, hangs in headless), `tea pulls review` (interactive prompt), `tea logins add --oauth/--ssh-agent-*` (interactive). -1. **Verify authentication**: Run `tea whoami` to confirm login -2. **Check context**: Run in git repo for auto-detection, or use `--repo owner/repo` or `--login ` -3. **Use non-interactive mode**: Always use `--output` flag and provide all arguments -4. **Choose operation**: See command reference sections below +## Non-interactive rules + +`tea` will prompt for missing values when stdout is a TTY. In agent contexts: + +- Pass `--output simple` or `--output json` to disable interactive output. +- Provide **every** required value upfront — title, description, etc. +- Destructive ops require `--confirm`/`-y` for most commands, but `tea repos delete` uses `--force`/`-f`, and `tea labels/milestones/organizations delete` have no confirm flag (they just delete). +- Outside a git repo, always pass `--repo owner/name` and (if multiple logins) `--login `. + +## Auth check + +```bash +tea whoami # confirm login works +tea logins list # see configured logins +``` + +Set up a token-based login non-interactively: + +```bash +tea logins add --name farh --url https://gitea.example.com --token "$GITEA_TOKEN" +tea logins default farh +``` + +Env vars read on first use: `GITEA_SERVER_URL`, `GITEA_SERVER_TOKEN`. + +## Common flags + +| Flag | Purpose | +|------|---------| +| `--login`/`-l ` | Pick a configured login | +| `--repo`/`-r ` | Operate on a specific repo (required outside git repos) | +| `--remote`/`-R ` | Discover login from a git remote | +| `--output`/`-o ` | `simple`, `table`, `csv`, `tsv`, `yaml`, `json` | +| `--page`/`-p` `--limit`/`--lm` | Pagination (note: short form is `--lm`, two dashes) | +| `--confirm`/`-y` | Confirm destructive ops (most commands) | + +## Quick examples + +```bash +# Issues — note: --description (not --body), --assignees & --labels (plural) +tea issues create --title "Bug" --description "..." --labels bug --assignees alice + +# PRs — review comments are POSITIONAL, not via --comment +tea pulls create --title "Add X" --base main --head feature/x --description "$(cat pr.md)" +tea pulls approve 20 "LGTM" +tea pulls merge 20 --style squash + +# Releases — tag positional, --note OR --note-file (only on create) +tea releases create v1.0.0 --title "v1.0.0" --note-file CHANGELOG.md \ + --asset dist/linux --asset dist/darwin + +# Labels — name via --name, identification by --id +tea labels create --name bug --color "#ff0000" +tea labels update --id 7 --name regression + +# Repos — delete uses --owner + --name + --force +tea repos delete --owner myorg --name myrepo --force + +# Clone — top-level helper, NOT `tea repos clone` +tea clone owner/repo ./dir + +# Actions — secret/variable values are POSITIONAL, not --value +tea actions secrets create DEPLOY_TOKEN "$(cat ~/.token)" +tea actions variables set BUILD_VERSION "1.2.3" +tea actions runs logs 12345 --job 7 # --job flag, not positional + +# Time tracking — both args POSITIONAL: +tea times add 42 1h30m + +# Generic API +tea api /repos/{owner}/{repo}/issues -X POST -f title="..." -f body="..." +``` + +## Full command reference + +See [references/commands.md](references/commands.md) for the full verified surface — every common subcommand, with flag corrections vs. older docs. + +## Known doc pitfalls (corrected in references/) + +Documentation found in older copies of this skill (or from other sources) often contained these errors: + +- `tea issues create --body "..."` — there is no `--body`; use `--description`/`-d`. +- `tea pulls approve 20 --comment "LGTM"` — comment is positional: `tea pulls approve 20 "LGTM"`. +- `tea pulls review 20 --state comment` — `tea pulls review` is interactive only; no `--state`/`--comment` flags. +- `tea repos delete owner/repo --yes` — uses `--owner`/`--name`/`--force`. +- `tea repos clone …` — doesn't exist; use `tea clone …`. +- `tea labels delete bug` — `tea labels delete --id `, no positional name. +- `tea milestones create "v2.0.0"` — title is via `--title` flag. +- `tea actions secrets create FOO --value "bar"` — value is positional. +- `tea actions runs logs 12345 1` — second arg is `--job 1`. +- `tea actions runs rerun 12345` — no such subcommand (use MCP `actions_run_write` method `rerun_run`). +- `tea attachments …` — no such top-level command (use `tea releases assets …`). +- `tea times add 42 --time 2h --message …` — `tea times add `, both positional, no flags. +- `tea logins env` / `tea login env` — does not exist. +- `tea open ` / `tea open pulls` — `tea open` accepts no positional args per its `--help`; will also hang in headless environments. ## Installation +If `tea` isn't already on PATH: + ```bash # macOS brew install tea -# Linux (binary) -curl -sL https://dl.gitea.io/tea/main/tea-main-linux-amd64 -o tea -chmod +x tea && sudo mv tea /usr/local/bin/ +# Linux +curl -sL https://dl.gitea.io/tea/main/tea-main-linux-amd64 -o /usr/local/bin/tea +chmod +x /usr/local/bin/tea # From source go install code.gitea.io/tea@latest ``` - -## Common Flags - -These flags are available on most commands: - -| Flag | Alias | Description | -|------|-------|-------------| -| `--login` | `-l` | Use a specific Gitea login/instance | -| `--repo` | `-r` | Specify repository (`owner/repo`) | -| `--remote` | `-R` | Discover login from git remote | -| `--output` | `-o` | Output format: `simple`, `table`, `csv`, `tsv`, `yaml`, `json` | -| `--page` | `-p` | Page number for list commands (default: 1) | -| `--limit` | `-lm` | Items per page (default: 30) | - -## Authentication - -```bash -# Token-based login (recommended for CI/AI agents) -tea login add \ - --name mygitea \ - --url https://gitea.example.com \ - --token - -# Or use environment variables -export GITEA_SERVER_URL=https://gitea.example.com -export GITEA_SERVER_TOKEN= - -# OAuth2 interactive login -tea login add --oauth --name mygitea --url https://gitea.example.com - -# SSH agent login (requires running ssh-agent with key loaded) -tea login add --ssh-agent-key --ssh-agent-principal - -# List logins -tea login list - -# Set default -tea login default gitea.example.com - -# Refresh OAuth token -tea login oauth-refresh [login-name] - -# Delete login -tea login delete gitea.example.com - -# Verify -tea whoami -``` - -## Issues - -### List Issues -```bash -# Open issues in current repo -tea issues list - -# All issues (including closed) -tea issues list --state all - -# Filter by milestone -tea issues list --milestone "v1.0.0" - -# Filter by assignee and labels -tea issues list --assignee username --label bug,critical - -# From specific repo -tea issues list --repo owner/repo --login gitea.com -``` - -### View Issue -```bash -# View issue with comments -tea issue 42 - -# Without comments -tea issue 42 --comments=false - -# Open in browser -tea open 42 -``` - -### Create Issue -```bash -# With arguments -tea issues create \ - --title "Fix authentication bug" \ - --body "Users cannot login with special characters" \ - --label bug,security \ - --assignee developer1 \ - --milestone "v1.2.0" - -# From file -tea issues create \ - --title "Feature request" \ - --body "$(cat feature-request.md)" -``` - -### Modify Issues -```bash -# Close issue -tea issues close 42 - -# Reopen issue -tea issues reopen 42 - -# Edit issue -tea issues edit 42 \ - --title "Updated title" \ - --assignee newdev \ - --add-labels "enhancement" -``` - -## Pull Requests - -### List PRs -```bash -# Open PRs -tea pulls - -# Closed PRs -tea pulls --state closed - -# Filter by reviewer and labels -tea pulls --reviewer username --label "needs-review" -``` - -### View PR -```bash -# View PR details -tea pr 15 - -# Without comments -tea pr 15 --comments=false - -# Open in browser -tea open 15 -``` - -### Create PR -```bash -# With arguments -tea pulls create \ - --title "Implement user authentication" \ - --description "Adds OAuth and JWT support" \ - --base main \ - --head feature/auth \ - --assignee reviewer1,reviewer2 \ - --label "enhancement" - -# Description from file -tea pulls create \ - --title "Major refactor" \ - --description "$(cat pr-description.md)" -``` - -### Checkout PR -```bash -# Checkout PR locally -tea pulls checkout 20 - -# Custom branch name -tea pulls checkout 20 pr-20-custom-name - -# Clean up checked out PRs -tea pulls clean -``` - -### Review & Merge -```bash -# Approve PR -tea pulls approve 20 --comment "LGTM!" - -# Request changes -tea pulls reject 20 --comment "Please add tests" - -# Leave comment -tea pulls review 20 \ - --state comment \ - --comment "Consider refactoring this section" - -# Merge PR (squash) -tea pulls merge 20 --style squash --message "feat: implement auth" - -# Merge PR (rebase) -tea pulls merge 20 --style rebase - -# Close PR -tea pulls close 20 - -# Reopen PR -tea pulls reopen 20 -``` - -## Releases - -### List Releases -```bash -tea releases list -tea releases list --limit 10 -tea releases list --repo owner/project -``` - -### Create Release -```bash -# Basic release -tea releases create v1.0.0 \ - --title "Version 1.0.0" \ - --note "First stable release" - -# From changelog file -tea releases create v1.2.0 \ - --title "Version 1.2.0" \ - --note-file CHANGELOG.md - -# Draft release -tea releases create v2.0.0-beta \ - --title "Beta Release" \ - --draft \ - --note "Beta for testing" - -# With assets -tea releases create v1.1.0-rc1 \ - --title "Release Candidate 1" \ - --prerelease \ - --asset dist/binary-linux-amd64 \ - --asset dist/binary-darwin-amd64 - -# Create tag + release -tea releases create v1.3.0 \ - --target main \ - --title "Version 1.3.0" \ - --note "New features" -``` - -### Edit/Delete Release -```bash -# Update release -tea releases edit v1.0.0 \ - --title "Version 1.0.0 - Updated" \ - --note-file NEW-NOTES.md - -# Publish draft -tea releases edit v2.0.0 --draft=false - -# Delete release -tea releases delete v0.9.0 -tea releases delete v1.0.0-beta --confirm -``` - -## Labels - -```bash -# List labels -tea labels list -tea labels list --repo owner/project -tea labels list --save # Save labels to file - -# Create label -tea labels create bug \ - --color "#ff0000" \ - --description "Something isn't working" - -tea labels create enhancement \ - --color "0,255,0" \ - --description "New feature" - -# Update label -tea labels update bug --color "#cc0000" -tea labels update old-name --name new-name - -# Delete label -tea labels delete bug -``` - -## Milestones - -```bash -# List milestones -tea milestones list -tea milestones list --state open -tea milestones list --state closed - -# View milestone issues -tea milestones issues "v1.0.0" -tea milestones issues "v1.0.0" --kind pull # Only PRs -tea milestones issues "v1.0.0" --state all - -# Add issue/PR to milestone -tea milestones issues add "v1.0.0" 42 - -# Remove issue/PR from milestone -tea milestones issues remove "v1.0.0" 42 - -# Create milestone -tea milestones create "v2.0.0" \ - --description "Major version release" \ - --deadline "2024-12-31" - -# Close milestone -tea milestones close "v1.0.0" - -# Reopen milestone -tea milestones reopen "v1.0.0" - -# Delete milestone -tea milestones delete "v0.9.0" -``` - -## Repositories - -```bash -# List repos -tea repos list -tea repos list --org myorg -tea repos list --watched # Watched repos -tea repos list --starred # Starred repos -tea repos list --type fork # Filter: fork, mirror, source -tea repos list --output yaml - -# Search repos -tea repos search "keyword" --login gitea.com - -# View repo details -tea repos owner/repo - -# Create repo -tea repos create --name myrepo --private --init -tea repos create \ - --name myrepo \ - --owner myorg \ - --description "My project" \ - --private \ - --init \ - --gitignores Go \ - --license MIT - -# Create from template -tea repos create-from-template \ - --template owner/template-repo \ - --name new-repo - -# Fork repo -tea repos fork --repo owner/repo -tea repos fork --repo owner/repo --owner myorg - -# Edit repo -tea repos edit owner/repo \ - --description "Updated description" \ - --private=false - -# Delete repo -tea repos delete owner/repo - -# Clone repo (without git) -tea repos clone owner/repo -tea repos clone owner/repo ./target-dir -tea repos clone gitea.com/owner/repo # With host -``` - -## SSH Keys - -```bash -# List your SSH keys -tea ssh-keys list - -# Add SSH key from file -tea ssh-keys add ~/.ssh/id_ed25519.pub -tea ssh-keys add ~/.ssh/id_ed25519.pub --title "Work laptop" - -# Delete SSH key by ID -tea ssh-keys delete 123 --confirm -``` - -## Actions / CI/CD - -### Workflow Runs -```bash -# List workflow runs -tea actions runs list -tea actions runs list --status success --branch main -tea actions runs list --event push --since "24h" -tea actions runs list --actor username --limit 50 - -# View run details -tea actions runs view 12345 -tea actions runs view 12345 --jobs=false - -# View run logs -tea actions runs logs 12345 1 # run ID, job ID - -# Cancel run -tea actions runs cancel 12345 - -# Rerun run -tea actions runs rerun 12345 - -# Delete run -tea actions runs delete 12345 --confirm -``` - -### Workflows -```bash -# List workflows -tea actions workflows list - -# View workflow file -tea actions workflows view .gitea/workflows/ci.yml - -# Enable/disable workflow -tea actions workflows enable .gitea/workflows/ci.yml -tea actions workflows disable .gitea/workflows/ci.yml - -# Dispatch workflow -tea actions workflows dispatch .gitea/workflows/ci.yml --ref main -``` - -### Actions Secrets -```bash -# List secrets -tea actions secrets list - -# Create secret -tea actions secrets create DEPLOY_TOKEN --value "secret-value" -tea actions secrets create DB_PASSWORD --file /path/to/password.txt -echo "secret-value" | tea actions secrets create API_KEY --stdin - -# Delete secret -tea actions secrets delete DEPLOY_TOKEN --confirm -``` - -### Actions Variables -```bash -# List variables (get specific one) -tea actions variables list --name BUILD_VERSION - -# Set variable -tea actions variables set BUILD_VERSION --value "1.2.3" -tea actions variables set CONFIG --file /path/to/config.json - -# Delete variable -tea actions variables delete BUILD_VERSION --confirm -``` - -## Webhooks - -```bash -# List webhooks -tea webhooks list -tea webhooks list --repo owner/repo - -# Create webhook -tea webhooks create https://example.com/webhook \ - --type gitea \ - --secret mysecret \ - --events push,pull_request \ - --active - -# Update webhook -tea webhooks update 1 \ - --url https://new-url.com/hook \ - --secret newsecret \ - --events push - -# Enable/disable webhook -tea webhooks update 1 --active -tea webhooks update 1 --inactive - -# Delete webhook -tea webhooks delete 1 --confirm -``` - -## Attachments - -```bash -# List attachments -tea attachments list 42 # issue/PR number - -# Create attachment -tea attachments create 42 --file ./artifact.zip - -# Delete attachment -tea attachments delete 42 --id 1 --confirm -``` - -## Time Tracking - -```bash -# List time entries -tea times list -tea times list --issue 42 -tea times list --user username -tea times list --from "2024-01-01" --until "2024-12-31" - -# Add time -tea times add 42 --time "2h" -tea times add 42 --time "1h30m" --message "Implemented auth logic" - -# Delete entry -tea times delete 42 --id 123 -``` - -## Notifications - -```bash -# List notifications (current repo) -tea notifications list - -# List all notifications -tea notifications list --mine - -# Filter by type -tea notifications list --types issue,pull - -# Filter by state -tea notifications list --states unread,pinned - -# Mark as read -tea notifications read # All filtered -tea notifications read 123 # Specific ID - -# Mark as unread -tea notifications unread 123 - -# Pin/unpin -tea notifications pin 123 -tea notifications unpin 123 -``` - -## Organizations - -```bash -# List organizations -tea organizations list - -# View organization details -tea organizations view myorg - -# Create organization -tea organizations create myorg - -# Delete organization -tea organizations delete myorg --confirm -``` - -## Branches - -```bash -# List branches -tea branches list -tea branches list --output json - -# View branch details -tea branches main - -# Protect branch -tea branches protect main - -# Unprotect branch -tea branches unprotect main - -# Rename branch -tea branches rename old-name new-name -``` - -## Comments - -```bash -# Add comment to issue or PR -tea comment 42 "This is my comment" - -# From specific repo -tea comment 42 "Comment text" --repo owner/repo -``` - -## Open in Browser - -```bash -# Open issue/PR by number -tea open 42 - -# Open specific pages -tea open issues -tea open pulls -tea open releases -tea open commits -tea open branches -tea open wiki -tea open activity -tea open settings -tea open labels -tea open milestones -``` - -**Warning:** `tea open` opens a browser window. It will hang indefinitely in headless/agent environments — do not use in non-interactive contexts. - -## Admin (requires admin access) - -### Users -```bash -# List users -tea admin users list -tea admin users list --output json -tea admin users list --page 2 --limit 50 - -# Create user -tea admin users create \ - --username newuser \ - --email newuser@example.com \ - --password "SecurePass123!" \ - --full-name "New User" \ - --admin \ - --visibility public - -# Edit user -tea admin users edit username \ - --email newemail@example.com \ - --full-name "Updated Name" \ - --admin \ - --no-admin \ - --restricted \ - --active \ - --visibility private - -# Delete user -tea admin users delete username --confirm -``` - -## Generic API Command - -Make authenticated requests directly to the Gitea API: - -```bash -# GET request (default) -tea api /user - -# POST with JSON body -tea api /repos/owner/repo/issues \ - --method POST \ - --data '{"title":"New issue","body":"Description"}' - -# POST with form fields -tea api /repos/owner/repo/issues \ - --method POST \ - --field title="New issue" \ - --field body="Description" - -# With headers -tea api /repos/owner/repo \ - --header "X-Custom-Header: value" - -# Include response headers in output -tea api /user --include - -# Write response to file -tea api /repos/owner/repo/archive --output release.zip - -# Placeholder expansion (from git context) -tea api /repos/{owner}/{repo}/actions/runs --login gitea.com -``` - -## Non-Interactive Mode (AI Agents) - -**IMPORTANT:** When using tea in AI agent environments (no TTY), avoid interactive prompts: - -```bash -# Use --output to disable interactive mode -tea issues --output simple -tea pulls --output json - -# Provide ALL required arguments upfront -tea issue create --title "Bug title" --body "Description here" -tea pr create --title "PR title" --head feature-branch --base main - -# Use -y or --yes for confirmations -tea pr merge 5 --yes -tea releases delete v0.9.0 --yes -tea admin users delete username --yes - -# Set default login to avoid prompts -tea login default - -# Always specify --login when not in a git repo -tea issues list --login gitea.com --repo owner/repo -``` - -**Always prefer explicit flags over interactive prompts.** - -## Guidelines - -### Do -- Use `--output simple` or `--output json` for non-interactive mode -- Provide all required arguments upfront to avoid prompts -- Run `tea whoami` to verify authentication before operations -- Use `tea open ` to quickly view in browser -- Specify `--login ` when operating outside a git repository - -### Don't -- Use interactive commands in AI agent context (no TTY) -- Forget `--repo owner/repo` when outside git repository -- Skip `--yes` flag for destructive operations in scripts -- Use `tea login add` interactively (configure beforehand) - -## Examples - -### Example: Feature Branch → PR -```bash -git checkout -b feature/new-feature -# ... make changes ... -git add . && git commit -m "feat: add new feature" -git push -u origin feature/new-feature -tea pulls create --title "Add new feature" --base main --head feature/new-feature -``` - -### Example: Review & Merge PR -```bash -tea pulls checkout 20 -# ... review code ... -tea pulls approve 20 --comment "LGTM!" -tea pulls merge 20 --style squash -``` - -### Example: Create Release with Assets -```bash -git tag v1.0.0 -git push origin v1.0.0 -tea releases create v1.0.0 \ - --title "v1.0.0" \ - --note-file CHANGELOG.md \ - --asset dist/app-linux \ - --asset dist/app-darwin -``` - -### Example: Manage Actions Secrets -```bash -# Deploy to staging -tea actions secrets create STAGING_DEPLOY_TOKEN \ - --value "$(cat ~/secrets/staging-token)" \ - --repo myorg/myrepo - -# Trigger workflow -tea actions workflows dispatch .gitea/workflows/deploy.yml --ref staging \ - --repo myorg/myrepo -``` - -### Example: Admin User Management -```bash -# Create service account -tea admin users create ci-bot \ - --email ci-bot@mycompany.com \ - --password "$(openssl rand -base64 24)" \ - --restricted \ - --no-must-change-password - -# Deactivate user -tea admin users edit username --prohibit-login -``` \ No newline at end of file diff --git a/gitea-tea/references/commands.md b/gitea-tea/references/commands.md new file mode 100644 index 0000000..707a593 --- /dev/null +++ b/gitea-tea/references/commands.md @@ -0,0 +1,480 @@ +# `tea` Command Reference + +Verified against `tea` v0.14.1. When in doubt, run `tea --help`. Flags below are exhaustive only for the operations agents need most often. + +## Conventions + +- `--login`/`-l`, `--repo`/`-r`, `--remote`/`-R` are available on most subcommands. Outside a git repo, pass `--repo owner/name` and (if you have multiple logins) `--login `. +- `--output`/`-o` accepts: `simple`, `table`, `csv`, `tsv`, `yaml`, `json`. Use `json` for parsing, `simple` for terse non-interactive output. +- `--limit`/`--lm` (yes, double-dash on the short form), `--page`/`-p` for paging. +- Destructive ops normally require `--confirm`/`-y`. **Exceptions:** `tea repos delete` uses `--force`/`-f`; `tea labels delete` / `tea milestones delete` / `tea organizations delete` have no confirm flag (they just delete). + +## Auth + +```bash +# Token-based login (use for CI/agents) +tea logins add --name mygitea --url https://gitea.example.com --token + +# Or via env vars (read on first command) +export GITEA_SERVER_URL=https://gitea.example.com +export GITEA_SERVER_TOKEN= + +tea logins list +tea logins default # set default +tea logins delete +tea whoami # verify +``` + +OAuth/SSH-agent logins exist (`tea logins add --oauth …`, `--ssh-agent-key …`); they are interactive and not useful in agent contexts. + +> `tea logins env` does **not** exist. The original wiki doc referenced it — ignore. + +## Issues + +```bash +# List +tea issues list +tea issues list --state all --labels bug,critical --assignee alice --milestone v1.0.0 +tea issues list --repo owner/repo --login gitea.example.com + +# View (positional ) +tea issues 42 # detail view +tea issue 42 --comments=false # without comments + +# Create — note: --description (NOT --body), --assignees (plural), --labels (plural) +tea issues create \ + --title "Fix authentication bug" \ + --description "Users cannot login with special characters" \ + --labels bug,security \ + --assignees alice,bob \ + --milestone v1.2.0 + +# Description from file +tea issues create --title "Feature request" --description "$(cat req.md)" + +# Edit — add/remove labels are separate flags +tea issues edit 42 \ + --title "Updated title" \ + --add-assignees bob \ + --add-labels enhancement \ + --remove-labels stale + +# State +tea issues close 42 +tea issues reopen 42 +``` + +## Pull requests + +```bash +# List +tea pulls list +tea pulls list --state closed +# Note: --reviewer / --label do NOT exist on pulls list; filter client-side or via API. + +# View +tea pulls 15 +tea pr 15 --comments=false + +# Create — same flag conventions as issues create +tea pulls create \ + --title "Implement OAuth" \ + --description "$(cat pr.md)" \ + --base main --head feature/auth \ + --assignees reviewer1,reviewer2 \ + --labels enhancement \ + --allow-maintainer-edits + +# Checkout (no custom branch-name positional; only --branch/-b to create one) +tea pulls checkout 20 +tea pulls checkout 20 --branch +tea pulls clean 20 # delete local + remote branches after merge + +# Review — comment/reason are POSITIONAL, no --comment flag +tea pulls approve 20 "LGTM" +tea pulls reject 20 "Please add tests" +# Note: `tea pulls review ` is interactive — do not use in agent context. + +# Merge +tea pulls merge 20 --style squash --title "feat: oauth" --message "Adds OAuth + JWT" +tea pulls merge 20 --style rebase +# Merge styles: merge, rebase, squash, rebase-merge + +# State +tea pulls close 20 +tea pulls reopen 20 +``` + +## Releases + +```bash +tea releases list +tea releases list --limit 10 --repo owner/repo + +# Create — tag is positional; --target sets commitish; --note OR --note-file +tea releases create v1.0.0 \ + --title "Version 1.0.0" \ + --note "First stable release" + +tea releases create v1.2.0 --title "v1.2.0" --note-file CHANGELOG.md +tea releases create v2.0.0-beta --title "Beta" --draft --note "For testing" +tea releases create v1.1.0-rc1 --title "RC1" --prerelease \ + --asset dist/binary-linux-amd64 --asset dist/binary-darwin-amd64 +tea releases create v1.3.0 --target main --title "v1.3.0" --note "..." + +# Edit — note that --note-file does NOT exist on edit (use --note only) +tea releases edit v1.0.0 --title "v1.0.0 — Updated" --note "$(cat NEW-NOTES.md)" +tea releases edit v2.0.0 --draft false # publish + +# Delete (--confirm/-y required) +tea releases delete v0.9.0 --confirm +tea releases delete v1.0.0-beta -y --delete-tag + +# Release assets (NOT `tea attachments` — that command doesn't exist) +tea releases assets list v1.0.0 +tea releases assets create v1.0.0 --file ./dist/binary.tar.gz +tea releases assets delete v1.0.0 --id 17 --confirm +``` + +## Labels + +```bash +tea labels list +tea labels list --save # dump to file + +# Create — name via --name flag (NOT positional) +tea labels create --name bug --color "#ff0000" --description "Something isn't working" +tea labels create --name enhancement --color "0,255,0" --description "New feature" + +# Update — by --id (NOT by name) +tea labels update --id 7 --color "#cc0000" +tea labels update --id 7 --name new-name + +# Delete — by --id (NOT positional name; no --confirm) +tea labels delete --id 7 +``` + +## Milestones + +```bash +tea milestones list +tea milestones list --state open +tea milestones list --state closed + +# Create — title via --title flag +tea milestones create --title v2.0.0 \ + --description "Major version" \ + --deadline 2025-12-31 + +# Manage issues/pulls in a milestone — positional +tea milestones issues v1.0.0 +tea milestones issues v1.0.0 --kind pull --state all +tea milestones issues add v1.0.0 42 +tea milestones issues remove v1.0.0 42 + +# State (positional name) +tea milestones close v1.0.0 +tea milestones reopen v1.0.0 +tea milestones delete v0.9.0 # no confirm flag +``` + +## Repositories + +```bash +# List +tea repos list +tea repos list --owner myorg +tea repos list --watched +tea repos list --starred +tea repos list --type fork # fork|mirror|source + +# Search — positional +tea repos search "keyword" +tea repos search "k8s" --topic --login gitea.example.com + +# Create — fields via flags +tea repos create --name myrepo --private --init +tea repos create \ + --name myrepo --owner myorg \ + --description "My project" --private --init \ + --gitignores Go --license MIT + +# Create from template +tea repos create-from-template \ + --template owner/template-repo --name new-repo --content --labels + +# Fork — source via --repo, target owner via --owner +tea repos fork --repo owner/source +tea repos fork --repo owner/source --owner myorg + +# Edit +tea repos edit --description "Updated" --private false + +# Delete — via --name + --owner + --force (NOT positional owner/repo, NOT --yes) +tea repos delete --owner myorg --name myrepo --force + +# Clone (NOT `tea repos clone`) — top-level helper, takes repo slug +tea clone owner/repo +tea clone owner/repo ./target-dir +tea clone gitea.example.com/owner/repo +tea clone --depth 1 owner/repo +``` + +## Branches + +```bash +tea branches list +tea branches main # detail view (positional name) +tea branches protect main +tea branches unprotect main +tea branches rename old new +``` + +## Actions / CI/CD + +### Workflow runs + +```bash +tea actions runs list +tea actions runs list --status success --branch main +tea actions runs list --event push --since 24h +tea actions runs list --actor alice --limit 50 + +tea actions runs view 12345 +tea actions runs view 12345 --jobs # show jobs table + +# Logs — job is via --job flag (NOT a positional second arg) +tea actions runs logs 12345 +tea actions runs logs 12345 --job 7 +tea actions runs logs 12345 --job 7 --follow + +# Cancel/delete (same subcommand; aliases: delete, remove, rm, cancel) +tea actions runs cancel 12345 --confirm +tea actions runs delete 12345 -y + +# Note: `tea actions runs rerun` does NOT exist. Use the MCP `actions_run_write` tool +# (method="rerun_run") or the REST API. +``` + +### Workflows + +```bash +tea actions workflows list +tea actions workflows view ci.yml +tea actions workflows enable ci.yml +tea actions workflows disable ci.yml + +# Dispatch — workflow_dispatch event +tea actions workflows dispatch ci.yml --ref main +tea actions workflows dispatch ci.yml --ref staging --input env=prod --input version=1.2.3 +tea actions workflows dispatch ci.yml --ref main --follow # tail logs after dispatch +``` + +### Secrets + +```bash +tea actions secrets list + +# Create — value is POSITIONAL (NOT --value) +tea actions secrets create DEPLOY_TOKEN "secret-value" +tea actions secrets create DEPLOY_TOKEN --file /path/to/value.txt +echo "secret-value" | tea actions secrets create API_KEY --stdin + +tea actions secrets delete DEPLOY_TOKEN --confirm +``` + +### Variables + +```bash +tea actions variables list +tea actions variables list --name BUILD_VERSION + +# Set — value is POSITIONAL (NOT --value) +tea actions variables set BUILD_VERSION "1.2.3" +tea actions variables set CONFIG --file /path/to/config.json + +tea actions variables delete BUILD_VERSION --confirm +``` + +## Webhooks + +```bash +tea webhooks list +tea webhooks list --repo owner/repo +tea webhooks list --org myorg +tea webhooks list --global + +# Create — URL is positional +tea webhooks create https://example.com/webhook \ + --type gitea --secret mysecret \ + --events push,pull_request --active + +# Update — ID is positional +tea webhooks update 1 --url https://new.example.com/hook --events push +tea webhooks update 1 --active # enable +tea webhooks update 1 --inactive # disable + +tea webhooks delete 1 --confirm +``` + +Webhook types: `gitea, gogs, slack, discord, dingtalk, telegram, msteams, feishu, wechatwork, packagist`. + +## SSH keys + +```bash +tea ssh-keys list + +# Add — key file is positional +tea ssh-keys add ~/.ssh/id_ed25519.pub +tea ssh-keys add ~/.ssh/id_ed25519.pub --title "Work laptop" + +# Delete — ID is positional, --confirm required +tea ssh-keys delete 123 --confirm +``` + +## Time tracking + +```bash +tea times list +tea times list --from 2024-01-01 --until 2024-12-31 --total +tea times list --mine # across all repos + +# Add — both args POSITIONAL: . No --time, no --message. +tea times add 42 2h +tea times add 42 1h30m + +tea times delete --id 123 +tea times reset 42 # reset all on an issue +``` + +## Notifications + +```bash +tea notifications list # current repo +tea notifications list --mine # across all repos +tea notifications list --types issue,pull +tea notifications list --states unread,pinned + +tea notifications read # mark all filtered as read +tea notifications read 123 # mark one +tea notifications unread 123 +tea notifications pin 123 +tea notifications unpin 123 +``` + +## Organizations + +```bash +tea organizations list +tea organizations view myorg +tea organizations create myorg --description "..." --visibility public +tea organizations delete myorg # no confirm flag +``` + +## Comments + +```bash +# Both args positional: [] +tea comment 42 "This is my comment" +tea comment 42 "Comment text" --repo owner/repo +``` + +## Admin (requires admin token) + +```bash +tea admin users list +tea admin users list --output json --page 2 --limit 50 + +tea admin users create \ + --username newuser --email newuser@example.com \ + --password "$(openssl rand -base64 24)" \ + --full-name "New User" \ + --admin --visibility public + +# Edit — note: there is no --no-admin or --no-restricted. Boolean flags work in one direction. +tea admin users edit newuser \ + --email new@example.com \ + --full-name "Updated Name" \ + --admin --restricted --active + +tea admin users edit newuser --prohibit-login # deactivate + +tea admin users delete newuser --confirm +``` + +## Generic API helper + +```bash +# GET (default) +tea api /user + +# Endpoint placeholders auto-expand from git context +tea api '/repos/{owner}/{repo}/actions/runs?status=success' + +# POST with string fields +tea api /repos/{owner}/{repo}/issues -X POST \ + -f title="New issue" -f body="Description" + +# POST with typed fields (numbers, booleans). Read value from file with @path; stdin with @-. +tea api /repos/{owner}/{repo}/labels -X POST \ + -F name="prio:high" -F color="#ff0000" -F exclusive=true + +# Raw JSON body (mutually exclusive with -f/-F) +tea api /repos/{owner}/{repo}/issues -X POST \ + -d '{"title":"New","body":"..."}' + +tea api /repos/{owner}/{repo}/archive -o release.zip # write body to file +tea api /user -i # include status + headers (to stderr) +tea api /repos/{owner}/{repo} -H "X-Custom: value" +``` + +## Open in browser + +```bash +tea open # current repo +``` + +> `tea open` opens a browser window. It will **hang indefinitely** in headless/agent environments. The previous skill version listed `tea open `, `tea open pulls`, etc. — those positional forms do not appear in `tea open --help`; do not rely on them. + +## Common end-to-end recipes + +### Feature branch → PR +```bash +git checkout -b feature/x +# ... commits ... +git push -u origin feature/x +tea pulls create --title "Add X" --base main --head feature/x --description "$(cat pr.md)" +``` + +### Review and merge +```bash +tea pulls checkout 20 +# ... local review ... +tea pulls approve 20 "LGTM" +tea pulls merge 20 --style squash +tea pulls clean 20 # cleanup branches +``` + +### Release with assets +```bash +git tag v1.0.0 && git push origin v1.0.0 +tea releases create v1.0.0 \ + --title "v1.0.0" \ + --note-file CHANGELOG.md \ + --asset dist/app-linux --asset dist/app-darwin +``` + +### Manage Actions secrets +```bash +tea actions secrets create STAGING_DEPLOY_TOKEN "$(cat ~/.staging-token)" \ + --repo myorg/myrepo +tea actions workflows dispatch deploy.yml --ref staging --repo myorg/myrepo +``` + +### Admin: create service account +```bash +tea admin users create \ + --username ci-bot --email ci-bot@example.com \ + --password "$(openssl rand -base64 24)" \ + --restricted --no-must-change-password +``` diff --git a/gitea-wiki/SKILL.md b/gitea-wiki/SKILL.md index 0aaae03..241d5d5 100644 --- a/gitea-wiki/SKILL.md +++ b/gitea-wiki/SKILL.md @@ -1,228 +1,183 @@ --- name: gitea-wiki description: Manage Gitea wiki pages. Use when user asks about wiki pages, or when agent reaches for GitHub wiki, github wiki API, or any wiki operation on a Gitea-hosted repo. (Child skill of `gitea` parent skill.) -version: 1.0.0 +version: 1.1.0 --- # Gitea Wiki Management ## Overview -Gitea wikis are git-backed Markdown repositories attached to each repository. Each wiki page is a Markdown file, stored in a dedicated `.wiki` git branch. +Gitea wikis are git-backed Markdown pages attached to a repository. The MCP server exposes them through two consolidated tools (`wiki_read`, `wiki_write`); the REST API at `/api/v1/repos/{owner}/{repo}/wiki/...` is the fallback. `tea` has no wiki subcommands. ## Interaction Methods -| Method | Priority | Notes | -|--------|----------|-------| -| **MCP Server** (`gitea-mcp`) | **Preferred** | `wiki_list_pages`, `wiki_get_page`, `wiki_create_page`, `wiki_update_page`, `wiki_delete_page` | -| **REST API** (direct curl) | Secondary | For scripted/automated operations not via MCP | -| **`tea` CLI** | None | No wiki subcommands available in tea | +| Priority | Method | Notes | +|----------|--------|-------| +| **Primary** | MCP `mcp__gitea__wiki_read` / `mcp__gitea__wiki_write` | Configured in repo `.mcp.json`; auth via `GITEA_TOKEN` | +| Fallback | REST API via `curl` | For automation outside an MCP-aware client | +| — | `tea` CLI | Not supported — `tea` has no wiki commands | -**Use `gitea-mcp` first.** The `tea` CLI does not have wiki commands; the REST API is the fallback. +## MCP tools -## Authentication +Both tools take `owner`, `repo`, and a `method` discriminator. + +### `wiki_read` — methods + +| `method` | Other args | Returns | +|----------|-----------|---------| +| `list` | — | All page titles + slugs + content URLs | +| `get` | `pageName` | Page metadata + raw markdown | +| `get_revisions` | `pageName` | Commit history for that page | + +### `wiki_write` — methods + +| `method` | Required args | Notes | +|----------|--------------|-------| +| `create` | `title`, `content` | Title becomes the slug (spaces → dashes). Optional `message` for commit msg. | +| `update` | `pageName`, `content` | `pageName` is the slug. `title` and `message` are optional. | +| `delete` | `pageName` | Requires write access to the wiki. | + +### Examples + +List pages in `farh/example`: +``` +mcp__gitea__wiki_read(method="list", owner="farh", repo="example") +``` + +Read the `Home` page: +``` +mcp__gitea__wiki_read(method="get", owner="farh", repo="example", pageName="Home") +``` + +Create `Installation-Guide`: +``` +mcp__gitea__wiki_write( + method="create", + owner="farh", repo="example", + title="Installation Guide", + content="# Installation\n\nStep 1...", + message="docs(wiki): add installation guide" +) +``` + +Update existing page: +``` +mcp__gitea__wiki_write( + method="update", + owner="farh", repo="example", + pageName="Installation-Guide", + content="# Installation\n\nUpdated...", + message="docs(wiki): update installation" +) +``` + +Delete page: +``` +mcp__gitea__wiki_write(method="delete", owner="farh", repo="example", pageName="Old-Page") +``` + +## REST API fallback + +The MCP server wraps these endpoints. Use `curl` directly only when MCP isn't reachable. + +| Endpoint | Method | Purpose | +|----------|--------|---------| +| `/repos/{owner}/{repo}/wiki/pages` | GET | List all pages | +| `/repos/{owner}/{repo}/wiki/page/{slug}` | GET | Get a page (raw markdown by default; add `?format=html` for rendered HTML) | +| `/repos/{owner}/{repo}/wiki/revisions/{slug}` | GET | Page commit history | +| `/repos/{owner}/{repo}/wiki/new` | POST | Create a page | +| `/repos/{owner}/{repo}/wiki/page/{slug}` | PATCH | Update a page | +| `/repos/{owner}/{repo}/wiki/page/{slug}` | DELETE | Delete a page | + +> Slug rules: take the title, replace spaces with `-`, drop characters that aren't `[A-Za-z0-9_./-]`. Gitea returns the canonical slug as `sub_url` in the page metadata — when in doubt, list first and read the slug back. + +### Auth ```bash -# MCP: token is sent automatically via Bearer ${GITEA_TOKEN} -# Set env var before invoking MCP: export GITEA_TOKEN= - -# REST API fallback: via curl -curl -H "Authorization: Bearer $GITEA_TOKEN" \ - -H "Content-Type: application/json" \ - https://gitea.example.com/api/v1/repos/owner/repo/wiki/... - -# tea login env (for tea CLI fallback) -eval $(tea login env --login ) +# Repo MCP config uses: Authorization: Bearer ${GITEA_TOKEN} ``` -## Wiki API Endpoints - -### List All Pages - -```bash -GET /repos/{owner}/{repo}/wiki/pages -``` +### Listing pages ```bash curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/pages" \ - -H "Authorization: Bearer $GITEA_TOKEN" + -H "Authorization: Bearer $GITEA_TOKEN" \ + | jq -r '.[] | "\(.title)\t\(.sub_url)"' ``` -Response: -```json -[ - { - "title": "Home", - "slug": "Home", - "content_url": "https://gitea.example.com/repos/owner/repo/wiki/Home.md" - }, - { - "title": "Installation Guide", - "slug": "Installation-Guide", - "content_url": "https://gitea.example.com/repos/owner/repo/wiki/Installation-Guide.md" - } -] -``` - -### Get a Wiki Page +### Creating a page ```bash -GET /repos/{owner}/{repo}/wiki/{page} -``` - -`{page}` is the slug (URL-safe title, spaces replaced with dashes). - -```bash -curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Home" \ - -H "Authorization: Bearer $GITEA_TOKEN" -``` - -Response: The raw Markdown content of the page. - -### Get Page with HTML Rendered - -Add `?format=html` for rendered HTML: - -```bash -curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Home?format=html" \ - -H "Authorization: Bearer $GITEA_TOKEN" -``` - -### Get Page Revisions - -```bash -GET /repos/{owner}/{repo}/wiki/{page}/revisions -``` - -Returns commit history for a wiki page (who changed it and when). - -## Write Operations - -### Create a Wiki Page - -```bash -POST /repos/{owner}/{repo}/wiki -``` - -Body (JSON): -```json -{ - "title": "Page Title", - "content": "# Page Title\n\nMarkdown content here..." -} -``` - -Title becomes the page slug (filename) and the Markdown is stored as-is. - -```bash -curl -s -X POST "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki" \ +curl -s -X POST "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/new" \ -H "Authorization: Bearer $GITEA_TOKEN" \ -H "Content-Type: application/json" \ -d '{"title":"Installation Guide","content":"# Installation\n\nStep 1..."}' ``` -### Edit/Update a Wiki Page +`content_base64` is also accepted in place of `content` for binary-safe payloads. + +### Updating a page ```bash -PATCH /repos/{owner}/{repo}/wiki/{page} -``` - -Body (JSON) — same format as create: - -```json -{ - "content": "# Updated content\n\nNew Markdown..." -} -``` - -```bash -curl -s -X PATCH "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Installation-Guide" \ +curl -s -X PATCH "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/page/Installation-Guide" \ -H "Authorization: Bearer $GITEA_TOKEN" \ -H "Content-Type: application/json" \ - -d '{"content":"# Updated Installation\n\nStep 1...Step 2..."}' + -d '{"content":"# Installation\n\nUpdated..."}' ``` -### Delete a Wiki Page +### Deleting a page ```bash -DELETE /repos/{owner}/{repo}/wiki/{page} -``` - -```bash -curl -s -X DELETE "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Installation-Guide" \ +curl -s -X DELETE "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/page/Installation-Guide" \ -H "Authorization: Bearer $GITEA_TOKEN" ``` -Requires admin or owner access. - -## Common Tasks - -### Render Wiki Page Content for Display +### Rendered HTML ```bash -# Get raw markdown -curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Page-Name" \ - -H "Authorization: Bearer $GITEA_TOKEN" - -# Or get HTML-rendered version -curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Page-Name?format=html" \ +curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/page/Home?format=html" \ -H "Authorization: Bearer $GITEA_TOKEN" ``` -### List All Pages Non-Interactively +### Upsert pattern (no dedicated endpoint) ```bash -curl -s "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/pages" \ - -H "Authorization: Bearer $GITEA_TOKEN" | \ - jq '.[] | "\(.title) (\(.slug))"' -``` +status=$(curl -s -o /dev/null -w "%{http_code}" \ + "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/page/$SLUG" \ + -H "Authorization: Bearer $GITEA_TOKEN") -### Create or Update (Upsert Pattern) - -There is no dedicated upsert endpoint. Use GET first to check existence, then POST or PATCH: - -```bash -# Check if page exists -if curl -s -o /dev/null -w "%{http_code}" \ - "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/Page-Name" \ - -H "Authorization: Bearer $GITEA_TOKEN" -eq 200; then - # Update existing - curl -s -X PATCH ... +if [ "$status" = "200" ]; then + curl -s -X PATCH "$GITEA_SERVER_URL/api/v1/repos/$OWNER/$REPO/wiki/page/$SLUG" \ + -H "Authorization: Bearer $GITEA_TOKEN" -H "Content-Type: application/json" \ + -d "{\"content\":$(jq -Rs . **This repository uses Gitea, not GitHub.** Use the `gitea` MCP server (preferred) or `tea` CLI. Do not use `gh` or GitHub-specific features. + ## Overview -Gitea is a self-hosted Git service providing repository hosting, issues, pull requests, Actions CI/CD, packages, and wiki — similar to GitHub but self-hosted. +Gitea is a self-hosted Git service — repos, issues, PRs, releases, Actions CI/CD, packages, and wiki. This is a **parent skill** that routes work to: -**This is a parent skill.** It routes tasks to the appropriate child skill: -- **`gitea-tea`** — CLI operations via the `tea` command-line tool -- **`gitea-wiki`** — Wiki management via REST API +- **`gitea-tea`** — terminal operations via the `tea` CLI +- **`gitea-wiki`** — wiki pages via the MCP server or REST API -## Interaction Methods +## Interaction methods (in order of preference) | Priority | Method | Coverage | -|----------|--------|---------| -| **Primary** | **MCP Server** (`gitea-mcp`) | ~100 tools across repos, issues, PRs, releases, branches, wiki, Actions, orgs, users, server | -| **Secondary** | **`tea` CLI** | Issues, PRs, releases, repos, Actions, labels, milestones, branches, webhooks, SSH keys, organizations, admin. **No wiki commands.** | -| **Tertiary** | **REST API** (direct curl) | Any operation not covered by MCP or tea; scripted/automated access | +|----------|--------|----------| +| **1. MCP server (`gitea-mcp`)** | Configured in `.mcp.json`. Auth via `GITEA_TOKEN`. | Repos, files, branches, commits, tags, releases, issues, PRs, labels, milestones, wiki, actions config/runs, notifications, packages, time tracking, search. ~57 tools. See [`references/mcp-tools.md`](references/mcp-tools.md). | +| 2. `tea` CLI (`gitea-tea`) | For local-state ops, webhooks, admin, SSH keys, release-asset uploads, and one-off API calls. | +| 3. REST API | `curl` direct as last resort. | -**Use MCP (`gitea-mcp`) first** — broadest coverage, cleanest tool interface. Fall back to `tea` CLI only when MCP is unavailable or lacks an operation. Use the REST API directly when neither MCP nor `tea` cover the needed call. +**Heuristic:** if the operation is a pure server-side mutation or read, use MCP. If it touches local git state, a coverage gap (see [`references/mcp-tools.md`](references/mcp-tools.md) → "Coverage gaps"), or needs stdin/file ingestion, drop to `tea`. -## When to Use Gitea +## Configuration -Use Gitea when: -- Working with a repository hosted on a Gitea instance -- Managing issues, pull requests, or releases on Gitea -- Running or configuring Gitea Actions (CI/CD) -- The user mentions "Gitea", "tea", self-hosted git, or a Gitea URL - -## Gitea vs GitHub - -Gitea and GitHub share a similar mental model. If you encounter confusion: - -| GitHub concept | Gitea equivalent | -|----------------|------------------| -| `gh` CLI | `tea` CLI | -| GitHub Actions | Gitea Actions | -| GitHub Packages | Gitea Packages | -| GitHub Wiki | Gitea Wiki | -| `github.com` | Your organization's Gitea instance URL | -| GitHub MCP | `gitea-mcp` — **use this first** | - -**Important:** This repo uses Gitea, NOT GitHub. Use `gitea-mcp` (preferred) or `tea` CLI. Do not use `gh` or GitHub-specific features. +The MCP server lives at `https://git-mcp.farh.net/mcp` and authenticates via `Authorization: Bearer ${GITEA_TOKEN}`. Make sure `GITEA_TOKEN` is set in the environment before using MCP tools or fall back to `tea` with a configured login. ## Redirecting from GitHub -If you detect GitHub/`gh` CLI confusion, clarify: +If you reach for `gh` or github.com, stop and re-route: ``` This repository uses Gitea for source code management, not GitHub. -Use `gitea-mcp` (MCP server) first, or `tea` CLI as fallback. -Do NOT use the `gh` CLI or GitHub-specific features. +Use the `gitea` MCP server first, or `tea` CLI as fallback. +Do NOT use `gh` or GitHub-specific features. ``` -## Child Skills +## Gitea vs GitHub mental model + +| GitHub | Gitea | +|--------|-------| +| `gh` CLI | `tea` CLI | +| `github-mcp` | `gitea-mcp` (use this first) | +| GitHub Actions | Gitea Actions | +| GitHub Packages | Gitea Packages | +| GitHub Wiki | Gitea Wiki | +| `github.com` | The team's Gitea instance | + +## Child skills ### gitea-tea -CLI operations via the `tea` command-line tool. Covers issues, PRs, releases, repos, Actions, labels, milestones, branches, webhooks, SSH keys, organizations, admin tasks, and generic API access. +CLI operations via `tea` v0.14.1. Covers issues, PRs, releases, repos, Actions, labels, milestones, branches, webhooks, SSH keys, organizations, admin, time tracking, and a generic API helper. See `../gitea-tea/SKILL.md`. ### gitea-wiki -For wiki page operations via `gitea-mcp` (preferred) or REST API. +Wiki page CRUD via the MCP server (`wiki_read`/`wiki_write`) or REST API. `tea` has no wiki subcommands. See `../gitea-wiki/SKILL.md`. -## Quick Reference +## Task routing + +The first column is what the user is trying to do. Pick MCP when it covers the op; the third column lists the `tea` fallback when MCP doesn't. + +| Task | MCP tool | `tea` fallback | +|------|----------|----------------| +| List my repos / org repos | `list_my_repos`, `list_org_repos` | `tea repos list [--owner …]` | +| Search repos | `search_repos` | `tea repos search ` | +| Create / fork repo | `create_repo`, `fork_repo` | `tea repos create`, `tea repos fork` | +| Edit / delete repo | — | `tea repos edit`, `tea repos delete --owner X --name Y --force` | +| Clone repo locally | — | `tea clone ` | +| Read file / directory / tree | `get_file_contents`, `get_dir_contents`, `get_repository_tree` | `tea api /repos/{owner}/{repo}/contents/…` | +| Write / delete file (single commit) | `create_or_update_file`, `delete_file` | — | +| Branches | `list_branches`, `create_branch`, `delete_branch` | `tea branches …` | +| Commits / tags | `list_commits`, `get_commit`, `list_tags`, `get_tag`, `create_tag`, `delete_tag` | — | +| Issues — list / read / search | `list_issues`, `search_issues`, `issue_read` | `tea issues list`, `tea issues ` | +| Issues — write | `issue_write` (create, update, comment, labels) | `tea issues create / edit / close / reopen` | +| PRs — list / read | `list_pull_requests`, `pull_request_read` | `tea pulls list`, `tea pulls ` | +| PRs — write | `pull_request_write` (create, merge, close, reviewers, …) | `tea pulls create / merge / approve / reject / close` | +| PR reviews | `pull_request_review_write` | `tea pulls approve "msg"` / `tea pulls reject "msg"` | +| PR local checkout | — | `tea pulls checkout ` | +| Labels (repo + org) | `label_read`, `label_write` | `tea labels …` | +| Milestones | `milestone_read`, `milestone_write` | `tea milestones …` | +| Releases — list / create / delete | `list_releases`, `get_release`, `get_latest_release`, `create_release`, `delete_release` | `tea releases list / create / delete` | +| Release — edit / asset upload | — | `tea releases edit`, `tea releases assets …` | +| Actions secrets / variables | `actions_config_read`, `actions_config_write` | `tea actions secrets / variables` | +| Actions workflows / runs | `actions_run_read`, `actions_run_write` (dispatch/cancel/rerun) | `tea actions workflows / runs` | +| Notifications | `notification_read`, `notification_write` | `tea notifications …` | +| Packages | `package_read`, `package_write` | — | +| Time tracking | `timetracking_read`, `timetracking_write` | `tea times …` | +| Wiki | `wiki_read`, `wiki_write` (see `gitea-wiki` skill) | — | +| Users / orgs / teams (search) | `get_me`, `get_user_orgs`, `search_users`, `search_org_teams` | `tea organizations …` | +| Webhooks | — | `tea webhooks …` | +| SSH keys (current user) | — | `tea ssh-keys …` | +| Admin user CRUD | — | `tea admin users …` | +| Arbitrary endpoint | — | `tea api …` | + +## Authentication check ```bash -# Authentication check -tea whoami - -# Most commands need --login (host) or --repo (owner/repo) when outside a git repo -tea issues list --login gitea.example.com --repo owner/repo - -# Use --output for non-interactive/script usage -tea issues list --output json - -# Always use --yes for destructive operations in scripts -tea repos delete owner/repo --yes +tea whoami # confirms tea-side login ``` +For MCP, the server validates `GITEA_TOKEN` on first call; `mcp__gitea__get_me` returns the authenticated user. + ## Documentation -- **MCP Server:** https://gitea.com/gitea/gitea-mcp (official `gitea-mcp` with ~100 tools) -- **Usage docs:** https://docs.gitea.com/category/usage -- **Repository:** https://docs.gitea.com/usage/repositories -- **Issues & PRs:** https://docs.gitea.com/usage/issues -- **Actions:** https://docs.gitea.com/usage/actions -- **Wiki API:** https://docs.gitea.com/api/1.26/repo/wiki -- **CLI (tea):** https://gitea.com/gitea/tea - -## Common Tasks Route - -| Task | Child Skill | Command Pattern | -|------|-------------|-----------------| -| Manage issues | gitea-tea | `tea issues list/create/edit/close` | -| Manage PRs | gitea-tea | `tea pulls list/create/merge/close` | -| Manage releases | gitea-tea | `tea releases list/create/edit/delete` | -| Manage repos | gitea-tea | `tea repos list/create/delete/clone` | -| Run Actions | gitea-tea | `tea actions runs list/view/logs` | -| Manage secrets/variables | gitea-tea | `tea actions secrets/variables` | -| Manage labels/milestones | gitea-tea | `tea labels/milestones` | -| SSH keys | gitea-tea | `tea ssh-keys list/add/delete` | -| Organizations | gitea-tea | `tea organizations list/view/create` | -| Admin tasks | gitea-tea | `tea admin users list/create/edit/delete` | -| Wiki pages | gitea-wiki | API: `GET/POST/PATCH/DELETE /repos/owner/repo/wiki/{page}` | +- MCP server: +- Tool inventory: [`references/mcp-tools.md`](references/mcp-tools.md) +- Usage docs: +- API reference (current): +- `tea` CLI: diff --git a/gitea/references/mcp-tools.md b/gitea/references/mcp-tools.md new file mode 100644 index 0000000..1c2a08b --- /dev/null +++ b/gitea/references/mcp-tools.md @@ -0,0 +1,156 @@ +# Gitea MCP Tool Inventory + +Tools exposed by the `gitea` MCP server (registered in repo `.mcp.json` at `https://git-mcp.farh.net/mcp`). All tool names below are prefixed `mcp__gitea__` when invoked. + +Many tools are consolidated under a `method` discriminator (e.g. `issue_write(method="create", …)`). Where that's the case, the methods are listed in the third column. + +## Repositories + +| Tool | Purpose | Notes | +|------|---------|-------| +| `list_my_repos` | List repos accessible to the authenticated user | Paginated | +| `list_org_repos` | List repos for a given org | Required: `org` | +| `search_repos` | Search across the instance | Required: `query`. Filters: `isPrivate`, `isArchived`, `keywordIsTopic`, `keywordInDescription`, `ownerID`, `sort`, `order` | +| `create_repo` | Create a personal or org repo | Required: `name`. Optional: `organization`, `private`, `auto_init`, `gitignores`, `license`, `readme`, `template`, `trust_model`, `default_branch`, `object_format_name` (sha1/sha256), `issue_labels`, `description` | +| `fork_repo` | Fork a repo | Required: `user` (source owner), `repo`. Optional: `organization`, `name` | +| `get_repository_tree` | Recursive tree listing | Required: `owner`, `repo`, `tree_sha`. Optional: `recursive`, paging | + +## Files + +| Tool | Purpose | Notes | +|------|---------|-------| +| `get_file_contents` | Get a file at a ref | Required: `owner`, `repo`, `ref`, `path`. Optional: `withLines` (numbered output) | +| `get_dir_contents` | List a directory at a ref | Required: `owner`, `repo`, `ref`, `path` | +| `create_or_update_file` | Write a file in a single commit | Required: `owner`, `repo`, `path`, `content`, `message`, `branch_name`. Provide `sha` to update an existing file; omit to create. Use `new_branch_name` to commit onto a new branch | +| `delete_file` | Remove a file | Required: `owner`, `repo`, `path`, `message`, `branch_name`, `sha` | + +## Branches + +| Tool | Purpose | Notes | +|------|---------|-------| +| `list_branches` | List branches | Required: `owner`, `repo` | +| `create_branch` | Create a branch | Required: `owner`, `repo`, `branch`. Optional: `old_branch` (defaults to repo default) | +| `delete_branch` | Delete a branch | Required: `owner`, `repo`, `branch` | + +## Commits / Tags + +| Tool | Purpose | Notes | +|------|---------|-------| +| `list_commits` | List commits | Required: `owner`, `repo`. Optional: `sha` (start ref), `path` (filter to commits touching this path) | +| `get_commit` | Get a commit | Required: `owner`, `repo`, `sha` | +| `list_tags` | List tags | Required: `owner`, `repo` | +| `get_tag` | Get a tag | Required: `owner`, `repo`, `tag_name` | +| `create_tag` | Create a tag | Required: `owner`, `repo`, `tag_name`. Optional: `target`, `message` | +| `delete_tag` | Delete a tag | Required: `owner`, `repo`, `tag_name` | + +## Releases + +| Tool | Purpose | Notes | +|------|---------|-------| +| `list_releases` | List releases | Required: `owner`, `repo`. Optional: `is_draft`, `is_pre_release` | +| `get_release` | Get a release by ID | Required: `owner`, `repo`, `id` | +| `get_latest_release` | Latest non-draft release | Required: `owner`, `repo` | +| `create_release` | Create a release | Required: `owner`, `repo`, `tag_name`, `target`, `title`. Optional: `body`, `is_draft`, `is_pre_release` | +| `delete_release` | Delete a release | Required: `owner`, `repo`, `id` | + +> No "edit release" or "upload asset" tool — fall back to `tea releases edit` / `tea releases assets` for those. + +## Issues + +| Tool | Purpose | Methods | +|------|---------|---------| +| `list_issues` | Standalone list | Filters: `state`, `labels[]`, `since`, `before` | +| `search_issues` | Cross-repo search | Required: `query`. Filters: `state`, `type` (issues/pulls), `labels`, `owner` | +| `issue_read` | Read details | `get`, `get_comments`, `get_labels` | +| `issue_write` | Mutate | `create`, `update`, `add_comment`, `edit_comment`, `add_labels`, `remove_label`, `replace_labels`, `clear_labels`. `labels` are IDs (numeric). `assignees` are usernames | + +## Pull requests + +| Tool | Purpose | Methods | +|------|---------|---------| +| `list_pull_requests` | List PRs | Filters: `state`, `milestone`, `sort` (`oldest`, `recentupdate`, `leastupdate`, `mostcomment`, `leastcomment`, `priority`) | +| `pull_request_read` | Read details | `get`, `get_diff`, `get_files`, `get_status` (head commit status), `get_reviews`, `get_review`, `get_review_comments` | +| `pull_request_write` | Mutate | `create`, `update`, `close`, `reopen`, `merge`, `update_branch`, `add_reviewers`, `remove_reviewers`. Merge styles: `merge`, `rebase`, `rebase-merge`, `squash`, `fast-forward-only`. Optional `head_commit_id` for conflict detection; `merge_when_checks_succeed`, `force_merge`, `delete_branch` for merge | +| `pull_request_review_write` | Reviews | `create`, `submit`, `delete`, `dismiss`. States for `create`: `APPROVED`, `REQUEST_CHANGES`, `COMMENT`, `PENDING`. Supports inline `comments[]` with `path` + `new_line_num`/`old_line_num` | + +## Labels + +| Tool | Purpose | Methods | +|------|---------|---------| +| `label_read` | Read | `list_repo_labels`, `get_repo_label`, `list_org_labels` | +| `label_write` | Mutate | `create_repo_label`, `edit_repo_label`, `delete_repo_label`, `create_org_label`, `edit_org_label`, `delete_org_label`. Org labels accept `exclusive`; repo labels accept `is_archived`. `color` is hex `#RRGGBB` | + +## Milestones + +| Tool | Purpose | Methods | +|------|---------|---------| +| `milestone_read` | Read | `list`, `get` | +| `milestone_write` | Mutate | `create`, `update` (alias `edit`), `delete`. State enum: `open`, `closed`. `due_on` is a date string | + +## Wiki + +| Tool | Purpose | Methods | +|------|---------|---------| +| `wiki_read` | Read | `list`, `get` (needs `pageName`), `get_revisions` (needs `pageName`) | +| `wiki_write` | Mutate | `create` (needs `title`, `content`), `update` (needs `pageName`, `content`), `delete` (needs `pageName`). Optional `message` is the commit message | + +> See `../../gitea-wiki/SKILL.md` for end-to-end wiki examples. + +## Actions + +| Tool | Purpose | Methods | +|------|---------|---------| +| `actions_config_read` | Read secrets/variables | `list_repo_secrets`, `list_org_secrets`, `list_repo_variables`, `get_repo_variable`, `list_org_variables`, `get_org_variable` | +| `actions_config_write` | Mutate secrets/variables | `upsert_repo_secret`, `delete_repo_secret`, `upsert_org_secret`, `delete_org_secret`, `create_repo_variable`, `update_repo_variable`, `delete_repo_variable`, `create_org_variable`, `update_org_variable`, `delete_org_variable`. Secret `value` field is `data`; variable value is `value` | +| `actions_run_read` | Read workflows/runs/jobs/logs | `list_workflows`, `get_workflow` (`workflow_id` may be ID or filename), `list_runs`, `get_run`, `list_jobs`, `list_run_jobs`, `get_job_log_preview`, `download_job_log` (`output_path` required). Log methods accept `max_bytes` and `tail_lines` | +| `actions_run_write` | Trigger/control runs | `dispatch_workflow` (needs `workflow_id`, `ref`; optional `inputs`), `cancel_run`, `rerun_run` | + +## Notifications + +| Tool | Purpose | Methods | +|------|---------|---------| +| `notification_read` | Read | `list` (optional `owner`/`repo` to scope; filters: `status`, `subject_type`, `since`, `before`), `get` (by thread `id`) | +| `notification_write` | Mark read | `mark_read` (by thread `id`), `mark_all_read` (optionally scoped to a repo) | + +## Packages + +| Tool | Purpose | Methods | +|------|---------|---------| +| `package_read` | Read | `list` (one entry per version; filter via `q`/`type`), `list_versions`, `get` (needs `version`) | +| `package_write` | Mutate | `delete` (irreversible) | + +Package `type`: `container`, `npm`, `maven`, `pypi`, `cargo`, `generic`. + +## Time tracking + +| Tool | Purpose | Methods | +|------|---------|---------| +| `timetracking_read` | Read | `list_issue_times`, `list_repo_times`, `get_my_stopwatches`, `get_my_times` | +| `timetracking_write` | Mutate | `start_stopwatch`, `stop_stopwatch`, `delete_stopwatch`, `add_time` (`time` in seconds), `delete_time` | + +## Users / Orgs / Teams + +| Tool | Purpose | Notes | +|------|---------|-------| +| `get_me` | Current user | No args | +| `get_user_orgs` | Orgs of the current user | Paginated | +| `search_users` | Search users | Required: `query` | +| `search_org_teams` | Search teams in an org | Required: `org`, `query`. Optional: `includeDescription` | + +## Server + +| Tool | Purpose | +|------|---------| +| `get_gitea_mcp_server_version` | Returns the running MCP server version. Useful for confirming connectivity. | + +## Coverage gaps (use `tea` or REST API instead) + +The MCP server does **not** currently expose: + +- Webhook CRUD — use `tea webhooks …`. +- Admin user CRUD — use `tea admin users …`. +- Release asset upload/management — use `tea releases assets …`. +- SSH key CRUD — use `tea ssh-keys …`. +- Login / instance setup — `tea logins …`. +- Repo edit/delete — `tea repos edit / tea repos delete --owner X --name Y --force`. +- `tea pulls checkout` / `tea clone` workflows that need local git state.