Files
marketplace/AGENTS.md
T
naudachu d8bd927f1d feat: add the tea-runner execution agent
The skills carry meaning, the scripts carry work. Splitting the second
half onto a cheap model keeps the main session's context for the part
that needs judgement.

tea-runner is a Haiku subagent with Bash/Read/Grep/Glob/Skill and
nothing else. It loads /tea:sync or /tea:issue for the command table
rather than carrying its own copy, so the skills stay the single source
of truth for the script surface.

It executes and reports; it decides nothing. No Edit and no Write, so an
issue body is out of reach. No raw tea, no --force, no closing or
retitling, no pushing past the set it was handed, one retry maximum. A
failed validation, a missing type, an unpushed dependency come back as a
question in a `blocked:` line. The reply is a fixed receipt — commands
with ok/FAIL, touched paths, stderr verbatim — never a payload dump.

Knowledge still flows one way: nothing under skills/ knows the agent
exists, and deleting agents/ changes nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-10 15:02:34 +05:00

87 lines
4.1 KiB
Markdown

# AGENTS.md
## Project goals
1. **Unify and systematize issue workflow** for the development team with
minimal context usage. Issue operations are wrapped in scripts so agents
spend tokens on the task, not on re-deriving commands and formats.
2. **Keep the tracker out of the work.** An issue is a unit of work first and a
Gitea row second. The two are separate layers, and the first one does not
know the second exists.
3. **Route all Gitea interaction through the `tea` CLI via scripts** instead of
direct ad-hoc calls wherever possible. Scripts give deterministic,
reviewable behavior; the `tea-guard` hook enforces that every `tea`
invocation runs under the operator-pinned login.
## Layers
The hard rule of this repo. Knowledge flows one way only:
```
skills/issue DOMAIN what an issue is: format, validation, dependency graph
▲ offline — no tracker, no network, stdlib imports only
│ imports
skills/sync BRIDGE map.py md <-> Gitea JSON, pure functions, no I/O
_gitea.py login pin, tea api, pagination, filters
skills/use REFERENCE tea CLI docs for everything that is not an issue
skills/auth IDENTITY pin the login the whole tracker side runs under
│ calls
agents/ EXECUTION tea-runner: runs the scripts, reports a receipt
```
`skills/issue` never imports from `skills/sync`. Delete `skills/sync` and the
domain layer keeps working. The check is mechanical — every import under
`skills/issue/scripts/` is stdlib, and `subprocess` is not among them:
```bash
grep -rh '^import \|^from ' skills/issue/scripts/ | sort -u
```
If a tracker concept (issue number, login, HTTP call, label color) shows up in
the domain layer, it is in the wrong place.
## Repo layout
- `skills/auth` — pin the Gitea login used by `tea` (`/tea:auth`)
- `skills/issue` — issues as units of work (`/tea:issue`), entirely offline
- `references/format.md` — canonical issue format; single source of truth
- `scripts/issue.py` — domain module: slug identity, parse/render, validation,
taxonomy, dependency graph
- `scripts/issue_new.py` — create a local issue from its type template
- `scripts/issue_check.py` — validate against the format
- `scripts/issue_tree.py` — draw the dependency graph
- `scripts/issue_index.py` — rebuild `tmp/issues/INDEX.md`
- `skills/sync` — move issues between the local store and Gitea (`/tea:sync`)
- `scripts/map.py` — md ↔ Gitea JSON, pure, no I/O; label colors live here
- `scripts/_gitea.py` — transport: login pin, `tea api`, pagination, filters,
label ids, the remote-id map
- `scripts/pull.py`, `push.py`, `remote.py`, `comment.py`
- `skills/use``tea` CLI reference for everything that is not an issue
(`/tea:use`); `references/tea/` holds the command docs
- `agents/tea-runner.md` — subagent on Haiku that executes the scripts and
returns a compact receipt. Delegate batches (bulk pull, push a named set,
bootstrap labels, rebuild the index), never the thinking: it has no `Edit`
and no `Write`, may not `--force`, and may not decide what an issue says.
Delegating a single call costs more than running it inline — the win is the
loop, the retry, and the error triage.
- `hooks/` — PreToolUse hooks: `tea-guard` blocks or rewrites `tea` invocations
that don't use the pinned login; `agents-sync` keeps every directory canonical
(`AGENTS.md` real file, `CLAUDE.md` symlink to it)
## Local issue store
`tmp/issues/` (gitignored) is **the store, not a cache of Gitea**. One flat
markdown file per issue, named by its slug, with one metadata field per line so
plain grep works without a parser.
- Identity is the slug (`wire-sqlc-appclick.md`), never a tracker number.
Numbers live in the `gitea:` field.
- `origin: local` is a durable state. An issue that never leaves this machine is
complete and valid, not a draft.
- Pushing is additive: the file is never deleted, it gains `gitea:` / `url:` /
`synced:`.
- Pulling overwrites the body — a fetch, not a merge.
- No drift tracking. `synced:` tells you how old your copy is; re-pull when it
matters.