Files
marketplace/plugins/tea/skills/use/SKILL.md
T
naudachu 83f73c5cea refactor: turn the repo into a two-plugin marketplace
tea and tdl were two repositories, each carrying its own
.claude-plugin/marketplace.json — two marketplaces to register for what
is one collection. Fold them into one.

The repo root is now the marketplace and nothing else: a single
.claude-plugin/marketplace.json whose entries point at ./plugins/tea and
./plugins/tdl. A plugin's root is its own directory under plugins/, so
${CLAUDE_PLUGIN_ROOT} still resolves inside it and every path a plugin
uses stays relative to itself — the hooks and the test roots needed no
adjustment beyond the move.

tea's files move with git mv, so its history and blame follow. tdl
arrives as a plain copy; its history stays in claude-skills/threedotslab.

test_payload_root asserted `tmp/` was ignored by REPO/.gitignore. The
rule is that tmp/ is ignored, not which file says so, and git reads every
.gitignore on the way up — so the test now walks up to the repo root the
same way git does.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-11 00:25:28 +05:00

170 lines
7.8 KiB
Markdown

---
name: use
description: Reference docs for the `tea` CLI — Gitea's command-line client. Load when the user asks about Gitea repos, pulls, releases, milestones, labels, actions, webhooks, or other Gitea entities, to look up the right `tea` command and flags. Always write the login as the literal placeholder --login "$GITEA_LOGIN" — the tea-guard hook substitutes the operator-pinned login; set it with /tea:auth. Issues are NOT handled here: use /tea:issue to work on them and /tea:sync to move them to and from Gitea.
---
# /tea:use — tea CLI reference
Reference material for the `tea` CLI (Gitea's official command-line client).
Use these docs to look up commands, flags, filters, and output fields before
running `tea` via Bash.
## 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 |
|---|---|
| `/tea:issue` | issues as units of work — create, read, grep, validate, dependency graph. Offline. |
| `/tea:sync` | moving issues between the local store and Gitea — pull, push, comment. |
This skill covers everything else Gitea has: pulls, releases, milestones,
labels, repos, branches, actions, webhooks, notifications, times.
## Login: always write the placeholder, never a name (enforced)
Every `tea` invocation that touches Gitea MUST carry the login as the **literal
placeholder** `--login "$GITEA_LOGIN"` (or `-l "$GITEA_LOGIN"`). Do **not**
substitute an actual login name yourself.
The **`tea-guard`** PreToolUse hook enforces this and resolves it:
- no `--login` → blocked.
- `--login "$GITEA_LOGIN"` → the hook reads the operator's pinned login from
`.claude/settings.local.json` (`env.GITEA_LOGIN`) **at call time** and
rewrites the command to use that literal before it runs.
- `--login <some-name>` or any other variable → blocked. You may not choose the
login; only the operator does (via `/tea:auth`).
- no login pinned → blocked with a pointer to run `/tea:auth`.
Why: without an explicit login `tea` silently falls back to the machine's
default (possibly the user's personal account), and a login *you* pick may be
the wrong identity. Pinning is the operator's decision; the hook guarantees it.
The pin takes effect immediately — no restart. Only `tea logins list` and
`tea --version/--help` are exempt from the guard.
## 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 with the placeholder login, e.g.
`tea pulls list --login "$GITEA_LOGIN" --repo owner/repo --state open`.
(The hook rewrites `"$GITEA_LOGIN"` to the operator-pinned login.)
`tea` auto-detects owner/repo from `$PWD` inside a git repo; otherwise pass
`--repo owner/repo` (or `-r`). Login is **not** auto-detected — it is pinned
per-project by the operator (see `/tea:auth`) and injected by the guard.
Config lives in `$XDG_CONFIG_HOME/tea`.
### `--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 --login "$GITEA_LOGIN" --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 --login "$GITEA_LOGIN" --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 --login "$GITEA_LOGIN" -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 moved to
[`../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 `$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 `/tea:sync` rather than
hand-rolling their JSON. 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 --login "$GITEA_LOGIN" \
-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" --login "$GITEA_LOGIN"`)
are still fine via entity commands. Always the placeholder, never a login name.
## 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).
- If a `tea` command is blocked by `tea-guard`: either you forgot
`--login "$GITEA_LOGIN"`, you wrote a literal login name instead of the
placeholder (not allowed — let the guard substitute), or no login is pinned
(run `/tea:auth`).