--- name: use description: Reference docs for the `tea` CLI — Gitea's own command-line client, and the way to reach every Gitea entity the `kettle` binary does not cover. Load when the user asks about pull requests, releases, milestones, labels, repos, branches, actions, webhooks, notifications or times, to look up the right `tea` command and flags. `tea` keeps its own configuration and its own logins, entirely separate from kettle's. Issues are NOT handled here: /kettle:issue works on them offline and /kettle:sync moves them to and from the tracker. --- # /kettle:use — tea CLI reference Reference material for `tea`, Gitea's official command-line client. Use these docs to look up commands, flags, filters and output fields before running `tea` via Bash. `kettle` covers issues and nothing else. Everything else Gitea has — pulls, releases, milestones, labels, repos, branches, actions, webhooks, notifications, times — is reached through `tea`, and this skill is how. ## Issues are somewhere else Do **not** reach for `tea issues` or `tea api …/issues/…` to read or create an issue. Two skills own that, and they keep the payload out of your context: | Skill | Scope | |---|---| | `/kettle:issue` | issues as units of work — create, read, grep, validate, tick, dependency graph. Offline. | | `/kettle:sync` | moving issues between the local store and the tracker — pull, push, comment, close, evict. | ## Login: `tea` has its own configuration, and it is not kettle's Two tools, two credential stores, no connection between them: | tool | where its logins live | how they are managed | |---|---|---| | `tea` | `$XDG_CONFIG_HOME/tea` | `tea logins list`, `tea logins add` (interactive), `tea logins default` | | `kettle` | `~/.config/kettle/logins.yaml` + `/.kettle/config.yaml` | `kettle auth`, `kettle init --login` (`/kettle:auth`) | **Configuring one configures nothing in the other.** `/kettle:auth` does not give `tea` a credential, and `tea logins add` does not give `kettle` one. A project whose `kettle` commands work fine can still have no `tea` login at all, and the error you get will be about the login `tea` chose for itself. **There is no `$GITEA_LOGIN` placeholder and no hook that substitutes one.** The PreToolUse guard that used to rewrite it was deleted along with the Python scripts; writing `--login "$GITEA_LOGIN"` now passes an empty variable to `tea` and fails in a way that reads like a `tea` bug. If you find that spelling anywhere, it is stale. How to name a login honestly: - Inside a checkout, `tea` auto-detects owner, repo and login from the git remote. That is usually right and usually enough — run the command without `--login`. - When the machine holds more than one login, or you are outside a checkout, pass `--login ` with a name out of `tea logins list`. **Which one is the operator's call**: ask with `AskUserQuestion` rather than picking the one that looks likely. A wrong identity writes to a real tracker under somebody else's account. - `no gitea login detected, falling back to login '…'` is a **hard failure**, not a warning. Stop, do not act on the result, surface the line. - **Never mutate login state**: no `tea logins add/edit/delete/default`, no `tea logout`. `tea logins list` is the only login command that is yours to run, and adding a login is interactive — the operator does it in their own terminal. ## How to use 1. Identify the entity in the request: pulls, labels, milestones, releases, times, repos, branches, actions, webhooks, notifications, etc. 2. Find the matching command in the index below. 3. Run it via Bash, e.g. `tea pulls list --repo owner/repo --state open`. `tea` auto-detects owner/repo from `$PWD` inside a git repo; otherwise pass `--repo owner/repo` (or `-r`). ### `--repo` takes a slug — except where a checkout is required A few commands touch local git, not just the API, and for those `--repo` **must be a path to a checkout**; a slug is rejected: ``` Error: local repository required: execute from a repo dir, or specify a path with --repo ``` The message reads like the flag is missing even when it was passed. Confirmed for `pulls create`, `pulls checkout` and `pulls clean` (tea 0.14.x). Everything that is only an API call — `pulls list`, `milestones`, `releases`, `times`, `labels`, `issues` — takes the slug from any directory. Three working forms for `pulls create`: ```bash # 1. cwd inside the checkout, no --repo at all tea pulls create --head feat/x --base main --title "…" --description "…" # 2. from anywhere, --repo as a PATH (this is also the git-worktree answer: # point it at the main checkout) tea pulls create --repo /path/to/checkout \ --head feat/x --base main --title "…" --description "…" # 3. no checkout in reach — POST it, where owner/repo is a slug again tea api -X POST -d @tmp/pull/x.json repos/{owner}/{repo}/pulls ``` ## Index - [tea CLI overview](references/tea/index.md) — global flags, common options, output formats - [ENTITIES](references/tea/entities.md) — issues, pulls, labels, milestones, releases, times, repos, branches, actions, webhooks, comment - [HELPERS](references/tea/helpers.md) — open, notifications, clone, api - [MISC](references/tea/misc.md) — whoami, admin - [SETUP](references/tea/setup.md) — logins, logout, ssh-keys The canonical issue format lives in [`../issue/references/format.md`](../issue/references/format.md) — it describes local files, not `tea` commands. ## Rich payloads — write to `$PWD/tmp/` first, then `tea api` Entity subcommands (`tea comment`, `tea pulls create`, `tea releases create`, …) are built for humans at a TTY. With a large or formatted body they can hang silently — an empty-looking positional arg triggers the `$EDITOR` fallback, or a scope/confirm prompt waits on a TTY that doesn't exist. The harness eventually kills the process (e.g. exit 144 = 128 + SIGURG on macOS). **Rule:** for any non-trivial body (multi-line, or containing markdown / code fences / backticks / pipes / tables), bypass entity commands. Save the full request payload to `$PWD/tmp/` first, then POST via `tea api`. Issues and issue comments are already wrapped — use `/kettle:sync` rather than hand-rolling their JSON. `.kettle/payload/` is kettle's own scratchpad and is written by kettle only; do not put hand-made bodies there. The procedure below covers everything else. ### Procedure 1. Ensure the target dir exists: `mkdir -p tmp/{kind}` where `{kind}` is `pull`, `release`, etc. 2. Write the **complete request body as JSON** to `$PWD/tmp/{kind}/.json`. One file = one request. Use a quoted heredoc to avoid shell expansion: ```bash mkdir -p tmp/release cat > tmp/release/v0-2-0.json <<'EOF' {"tag_name": "v0.2.0", "name": "v0.2.0", "body": "## Changes\n\nMulti-line markdown with `code`."} EOF ``` Newlines inside the body must be encoded as `\n` in the JSON string. If composing programmatically, pipe through `jq -Rs '{body: .}' < body.md > tmp/release/v0-2-0.json`. 3. POST with `tea api`, passing the file with `-d @`: ```bash tea api -X POST -d @tmp/release/v0-2-0.json repos/{owner}/{repo}/releases ``` 4. Keep the file. `tmp/` should be gitignored; the saved payload is useful for retries, edits (`PATCH`), and debugging failed posts. ### Common endpoints | Action | Method + endpoint | |---|---| | Create PR | `POST repos/{owner}/{repo}/pulls` | | Edit PR body or title | `PATCH repos/{owner}/{repo}/issues/{n}` | | Comment on a PR | `POST repos/{owner}/{repo}/issues/{n}/comments` | | Edit comment | `PATCH repos/{owner}/{repo}/issues/comments/{id}` | | Create release | `POST repos/{owner}/{repo}/releases` | | Create milestone | `POST repos/{owner}/{repo}/milestones` | Short single-line bodies (e.g. `tea comment 42 "lgtm"`) are still fine via entity commands. ## Tips - Pass `-o json` for structured output when parsing programmatically — on **entity commands only**. On `tea api`, `-o` is a *file name*: `-o json` writes the response body to a file called `json` and leaves stdout empty. The response is already JSON, so there is nothing to format; use `-` for stdout, or leave the flag off. - Use `--fields, -f` to narrow columns. - Pagination: `--page, -p ` and `--limit, --lm ` (defaults 1 / 30). - A `tea` command that fails on identity is a login problem in **tea's** own config, never in kettle's — `tea logins list`, and the operator decides.