e628ad6fd9
BREAKING: the plugin is `kettle`, not `tea`, and its commands are `/kettle:*`. It also now needs a binary on PATH that it did not need before; the README and every skill say how to get one and what a missing one looks like. The plugin was 3800 lines of Python doing what a compiled binary does better, and the name pointed at a tool that no longer takes part: `tea` is Gitea's CLI, and since the transport moved into the binary nothing here shells out to it for issues at all. A plugin named after it was going to keep suggesting otherwise. Deleted: 19 scripts, the 14-file unittest suite, and the tea-guard hook. The guard blocked any `tea` invocation that would run under a login the model picked instead of the operator; the binary holds its own credentials and reads the pinned login out of the project's own config, so that failure is no longer expressible and there is nothing left to police. agents-sync stays — it is about AGENTS.md symlinks and has nothing to do with any of this. What the plugin keeps is what only a plugin can carry: the rules an operator states and a binary cannot enforce. `init` still refuses to run inside a linked worktree and still may not be model-invoked, because which directory is the project is a statement a person makes. The issue format reference stays here and stays the source of truth. The runner subagent is still for batches and still may not decide what an issue says. The command reference in the issue, sync and project skills is GENERATED from the binary's own command registry, between markers, so a flag that changed cannot ship with a skill that recommends the old one. `kettle gen skills --check` exits non-zero when they drift. The generator owns the region and nothing outside it: the frontmatter description, which is what decides whether a skill loads at all, stays hand-written. `use` survives and is the one place `tea` is still named — for releases, webhooks and actions, which kettle does not cover. Its instruction to write `--login "$GITEA_LOGIN"` and let the hook substitute the pin was true until this commit and is now rewritten: `tea` keeps its own configuration, kettle keeps its own, and configuring one configures nothing in the other. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
177 lines
8.3 KiB
Markdown
177 lines
8.3 KiB
Markdown
---
|
|
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` + `<project>/.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 <name>` 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}/<slug>.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 @<path>`:
|
|
```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 <n>` and `--limit, --lm <n>` (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.
|