feat(gitea-skill): Rewrite Gitea agent skill with verified API patterns

Rewrites SKILL.md with patterns verified against live Gitea 1.22.6:
- Milestones as project containers (project board API does not exist)
- Scoped workflow labels with mutual exclusivity
- Issue dependencies using IssueMeta format
- 1Password token retrieval via op read
- Default repo terraphim/agent-tasks with env var overrides

Adds setup-labels.sh for idempotent repo and label creation.
Includes research and design documents from disciplined development.
Adds pre-commit config adapted for infrastructure project.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-18 12:41:19 +01:00
parent 776b8a618e
commit c6d425be63
6 changed files with 1838 additions and 309 deletions
+469
View File
@@ -0,0 +1,469 @@
# Research Document: Gitea Skill for AI Agent Project/Task Management
**Status**: Draft -- Awaiting Approval
**Author**: Claude (Phase 1 Research)
**Date**: 2026-02-18
**Reviewers**: Alex
---
## 1. Problem Statement
### Description
Enhance the existing Gitea skill (`.agents/skills/gitea/SKILL.md`) so that an AI agent can perform end-to-end project and task management on the Gitea instance at https://git.terraphim.cloud (Gitea 1.22.6):
1. **Authenticate** -- Log in via API token (stored in 1Password)
2. **Create a project** -- Set up a project board for organizing work
3. **Create tasks** -- File issues within a repository and associate them with the project
4. **Track progress** -- Update issue state, add comments, move between workflow stages
### Success Criteria
- [ ] Agent can authenticate to Gitea API using a token retrieved from 1Password
- [ ] Agent can create a "project" (or equivalent organizational unit) to group tasks
- [ ] Agent can create issues (tasks) with title, body, labels, assignees, milestones
- [ ] Agent can update issue state (open/closed), add comments, change labels
- [ ] Agent can track workflow progress (backlog -> in-progress -> done or equivalent)
- [ ] Skill document is self-contained and usable by any AI agent without external docs
- [ ] Operations are idempotent where possible (re-running does not create duplicates)
---
## 2. Existing System Analysis
### 2.1 Current Gitea Skill (`/home/alex/projects/terraphim/gitea-infrastructure/.agents/skills/gitea/SKILL.md`)
The existing skill covers:
- **Users**: Admin CLI creation, API listing/info
- **Organizations**: Create, list repos
- **Repositories**: Create, delete, list (user and org)
- **Issues**: Create, list, get, update, close/reopen, add comments, add/remove labels
- **Pull Requests**: List, get, merge
- **Projects**: Create (user/org), list, add issue to project
- **Labels**: Create
- **Releases**: Create
- **Helper functions**: Bash alias for common operations
- **Error handling**: HTTP status codes, jq parsing
**Gaps in the current skill:**
1. No authentication via 1Password (`op inject` or `op read`)
2. No project column/board management (create columns, move issues between columns)
3. No milestone management (create, update, list, close)
4. No workflow patterns (agent-oriented: ready/claim/implement/close)
5. No idempotency patterns (check-before-create)
6. No JSON output parsing patterns for machine consumption
7. No issue template patterns (standardized issue bodies)
8. No dependency management between issues
### 2.2 Infrastructure Context (`/home/alex/projects/terraphim/gitea-infrastructure/HANDOVER.md`)
- **Instance**: Gitea 1.22.6 at https://git.terraphim.cloud
- **Server**: bigbox (100.106.66.7) via Tailscale
- **1Password Vault**: `TerraphimPlatform` (already has gitea-postgres, gitea-s3)
- **Secrets pattern**: `op inject` with `op://TerraphimPlatform/...` references
- **Source auth**: `source ~/op_zesticai_non_prod.sh` sets `OP_SERVICE_ACCOUNT_TOKEN`
### 2.3 Reference Patterns from Terraphim Ecosystem
**br (beads_rust) pattern:**
- CLI issue tracking: `br ready`, `br create`, `br update`, `br close`, `br sync`
- Priorities P0-P4, types (bug, feature, task, epic, chore)
- Agent workflow: ready -> claim -> implement -> close -> sync
- `--json` flag for machine parsing
**bv (beads viewer) pattern:**
- Robot flags: `--robot-triage`, `--robot-next`, `--robot-plan`
- Dependency-aware scheduling, PageRank, critical path
- Graph-aware triage engine
**MCP Agent Mail pattern:**
- Multi-agent coordination via messaging
- Projects, identities, inbox/outbox
- File reservations to avoid conflicts
---
## 3. Critical Finding: Gitea Project Board API Status
### 3.1 Project Board API is NOT Available in Gitea 1.22.6
This is the single most important finding of this research.
**Evidence:**
- GitHub Issue [#14299](https://github.com/go-gitea/gitea/issues/14299) "[FEATURE] API for projects" -- opened Jan 2021, still **OPEN** as of Feb 2026, assigned to milestone **1.26.0**
- PR [#28111](https://github.com/go-gitea/gitea/pull/28111) adding project API endpoints -- still in **DRAFT** status, targeted for 1.26.0
- GitHub Issue [#31769](https://github.com/go-gitea/gitea/issues/31769) "API support for columns" -- opened Aug 2024, still **OPEN**, type/proposal
**Proposed but NOT yet merged endpoints from PR #28111:**
```
POST /user/projects
POST /orgs/{org}/projects
POST /repos/{owner}/{repo}/projects
GET /user/projects
GET /orgs/{org}/projects
GET /repos/{owner}/{repo}/projects
GET /projects/{id}
PATCH /projects/{id}
DELETE /projects/{id}
```
**Column management endpoints from Issue #31769 (proposed, NOT implemented):**
```
PATCH /projects/{project_id}/columns/move
PATCH /projects/{project_id}/columns/{column_id}/move
```
**VERIFIED 2026-02-18**: Tested against live instance at https://git.terraphim.cloud:
- `GET /api/v1/user/projects` returns **HTTP 404** ("404 page not found")
- `GET /api/v1/repos/terraphim/gitea-infrastructure/projects` returns **HTTP 404**
- The existing skill's "Projects" section (lines 222-263 of SKILL.md) documents endpoints that **do not work** on Gitea 1.22.6 and must be removed or replaced.
### 3.2 What IS Available in Gitea 1.22.6 API
The following endpoints ARE confirmed available and functional:
**Issues (full CRUD):**
```
POST /repos/{owner}/{repo}/issues -- Create issue
GET /repos/{owner}/{repo}/issues -- List issues
GET /repos/{owner}/{repo}/issues/{index} -- Get issue
PATCH /repos/{owner}/{repo}/issues/{index} -- Update issue (title, body, state, milestone, assignees)
POST /repos/{owner}/{repo}/issues/{index}/comments -- Add comment
POST /repos/{owner}/{repo}/issues/{index}/labels -- Add labels
DELETE /repos/{owner}/{repo}/issues/{index}/labels/{id} -- Remove label
```
**Labels (full CRUD):**
```
POST /repos/{owner}/{repo}/labels -- Create label
GET /repos/{owner}/{repo}/labels -- List labels
PATCH /repos/{owner}/{repo}/labels/{id} -- Update label
DELETE /repos/{owner}/{repo}/labels/{id} -- Delete label
```
**Milestones (full CRUD):**
```
POST /repos/{owner}/{repo}/milestones -- Create milestone
GET /repos/{owner}/{repo}/milestones -- List milestones
GET /repos/{owner}/{repo}/milestones/{id} -- Get milestone
PATCH /repos/{owner}/{repo}/milestones/{id} -- Update milestone
DELETE /repos/{owner}/{repo}/milestones/{id} -- Delete milestone
```
**API Token Management:**
```
POST /users/{username}/tokens -- Create token (requires BasicAuth, NOT token auth)
GET /users/{username}/tokens -- List tokens (requires BasicAuth)
DELETE /users/{username}/tokens/{id} -- Delete token (requires BasicAuth)
```
**Note on token creation**: The `/users/{username}/tokens` endpoint requires HTTP BasicAuth with username:password. You **cannot** create a new token using an existing token -- this is a Gitea security restriction.
### 3.3 Existing MCP Servers for Gitea
Two MCP servers exist that could complement or replace the curl-based skill:
**1. Official Gitea MCP Server** ([gitea.com/gitea/gitea-mcp](https://gitea.com/gitea/gitea-mcp))
- ~80+ tools covering repos, branches, issues, PRs, releases, wiki, actions, tags, labels
- **Does NOT support project boards or columns**
- **Does NOT support milestones** (except as a field when editing PRs)
- Supports stdio and SSE modes
- Config: `GITEA_HOST`, `GITEA_ACCESS_TOKEN`, `GITEA_INSECURE`
- Written in Go, MIT licensed
**2. forgejo-mcp** ([github.com/raohwork/forgejo-mcp](https://github.com/raohwork/forgejo-mcp))
- Supports issues, labels, milestones, comments, attachments, dependencies
- **Does NOT support project boards or columns**
- **Does support milestone CRUD** (create, edit, delete)
- Supports stdio and HTTP modes
- Config: `FORGEJOMCP_SERVER`, `FORGEJOMCP_TOKEN`
- Written in Go, MPL-2.0 licensed
**3. Tea CLI** ([gitea.com/gitea/tea](https://gitea.com/gitea/tea))
- Official command-line tool for Gitea
- Supports issues, milestones, labels, PRs, time tracking, notifications
- Milestone issue management: add/remove issues from milestones
- **Does NOT mention project board support**
---
## 4. Recommended Architecture: Milestones as Projects
### 4.1 Rationale
Since the Project Board API is not available in Gitea 1.22.6, we need an alternative. The best available option is to use **milestones** as the primary organizational unit (i.e., "project" equivalent), combined with **labels** for workflow state tracking.
| Concept | br/bv equivalent | Gitea Implementation |
|---------|-------------------|---------------------|
| Project | br project / bv graph | Milestone |
| Task | br bead / issue | Issue |
| Status | br state (ready/claimed/done) | Labels: `status/backlog`, `status/in-progress`, `status/done` |
| Priority | br P0-P4 | Labels: `priority/P0-critical`, `priority/P1-high`, `priority/P2-medium`, `priority/P3-low` |
| Type | br type (bug/feature/task) | Labels: `type/bug`, `type/feature`, `type/task`, `type/epic`, `type/chore` |
| Agent claim | br claim | Assignee field + `status/in-progress` label |
| Workflow column | Project board column | Scoped labels (`status/*`) |
### 4.2 Scoped Labels for Workflow State
Gitea supports **scoped labels** (format: `scope/name`). When a scoped label is applied, it automatically removes any other label with the same scope. This means:
- Applying `status/in-progress` automatically removes `status/backlog`
- Applying `priority/P0-critical` automatically removes `priority/P2-medium`
This provides kanban-like exclusivity without project board columns.
### 4.3 Agent Workflow
```
1. AUTHENTICATE
- Read token from 1Password: op read "op://TerraphimPlatform/gitea-api-token/credential"
- Export: GITEA_TOKEN=$(op read ...)
2. CREATE PROJECT (milestone)
- POST /repos/{owner}/{repo}/milestones
- Body: { "title": "Sprint 2026-W08", "description": "...", "due_on": "2026-02-28T00:00:00Z" }
3. SETUP LABELS (one-time per repo)
- Create scoped labels for status, priority, type
- Idempotent: check existing labels before creating
4. CREATE TASK (issue)
- POST /repos/{owner}/{repo}/issues
- Body: { "title": "...", "body": "...", "milestone": <milestone_id>, "labels": [<label_ids>], "assignees": [...] }
5. TRACK PROGRESS
- Change status: Replace labels (POST label, DELETE old label -- or use scoped labels)
- Add comment: POST /repos/{owner}/{repo}/issues/{index}/comments
- Close: PATCH /repos/{owner}/{repo}/issues/{index} with { "state": "closed" }
6. QUERY STATUS
- List by milestone: GET /repos/{owner}/{repo}/issues?milestone={name}&state=open
- List by label: GET /repos/{owner}/{repo}/issues?labels=status/in-progress
- Get milestone progress: GET /repos/{owner}/{repo}/milestones/{id}
(returns open_issues and closed_issues counts)
```
---
## 5. Authentication Strategy
### 5.1 1Password Integration
The existing infrastructure already uses 1Password (`TerraphimPlatform` vault) for secrets. The pattern should be:
```bash
# Store token in 1Password (one-time setup, done manually or via op CLI)
# Item name: gitea-api-token
# Field: credential (contains the token value)
# Agent retrieval at runtime:
export GITEA_TOKEN=$(op read "op://TerraphimPlatform/gitea-api-token/credential")
```
**Note**: Creating a Gitea API token programmatically requires BasicAuth (username + password), which is harder to automate securely. The recommended approach is:
1. Create the token manually via Gitea Web UI (Settings -> Applications -> Generate New Token)
2. Store the token in 1Password under `TerraphimPlatform/gitea-api-token`
3. Agent reads from 1Password at runtime using `op read`
### 5.2 Token Scopes Required
The agent needs the following scopes:
- `read:issue` + `write:issue` -- Create and update issues
- `read:repository` + `write:repository` -- Access repo metadata
- `read:user` -- Read user information for assignees
- `read:organization` -- Access org repos
- `write:misc` -- Needed for some label operations
Alternatively, use `all` scope for simplicity (less secure but simpler).
---
## 6. Constraints and Risks
### 6.1 Technical Constraints
| Constraint | Impact | Mitigation |
|------------|--------|------------|
| No Project Board API in 1.22.6 | Cannot use true kanban boards via API | Use milestones + scoped labels as alternative |
| Token creation requires BasicAuth | Cannot automate token creation with token auth | Manual token creation, store in 1Password |
| Gitea MCP server lacks milestone support | Cannot use MCP for full workflow | Use curl-based skill for now; MCP for repo/PR ops |
| Scoped labels require Gitea 1.20+ | Must verify instance supports scoped labels | VERIFIED: Gitea 1.22.6 supports scoped labels with mutual exclusivity |
| Issue dependency API body format differs from intuition | Must use IssueMeta format {owner, repo, index} | VERIFIED: Works with correct format, supports cross-repo deps |
### 6.2 Risks
| Risk | Likelihood | Impact | Mitigation |
|------|------------|--------|------------|
| Existing "Projects" endpoints in SKILL.md do not work | High | Skill provides wrong info | Verify against live instance; remove or caveat |
| Milestone-as-project is semantically confusing | Medium | Agent confusion | Clear naming conventions and docs |
| Label sprawl across repos | Medium | Maintenance burden | Standardized label set, setup automation |
| Token leaked in logs/output | Low | Security breach | Never echo token; use 1Password op read inline |
| Gitea upgrade to 1.26 changes API surface | Low | Skill needs update | Document version, plan for upgrade path |
### 6.3 Assumptions
| Assumption | Basis | Risk if Wrong |
|------------|-------|---------------|
| Gitea 1.22.6 supports scoped labels | Feature added in 1.20 | Fall back to manual label management |
| Milestone API is fully functional | Standard Gitea feature | Skill cannot create "projects" |
| 1Password `op read` available in agent env | Existing infra pattern | Agent cannot authenticate |
| Issues can be filtered by milestone name | API docs indicate this | Need milestone ID lookup step |
| Agent runs in environment with curl and jq | Standard tooling | Need alternative HTTP client |
---
## 7. Open Questions -- ANSWERED via Live Testing (2026-02-18)
### Q1: Do the existing project endpoints work on 1.22.6?
**ANSWER: NO.** Both `/api/v1/user/projects` and `/api/v1/repos/{owner}/{repo}/projects` return HTTP 404. Milestones-only approach confirmed.
### Q2: Is there an existing Gitea API token in 1Password?
**ANSWER: YES.** The admin token is at `op://TerraphimPlatform/git.terraphim.cloud-admin-token/credential`. Authenticated user is `root` (id=1, is_admin=true). Existing 1Password items:
- `git.terraphim.cloud-admin-token` -- admin API token (working)
- `gitea-postgres` -- database credentials
- `gitea-s3` -- S3 storage credentials
- `Gitea.Terraphim.io` -- legacy item (2 years old)
### Q3: Which repository should be the "default" for agent task tracking?
**TO DECIDE.** Available repos on instance:
- `terraphim/terraphim-ai`
- `terraphim/terraphim-skills`
- Orgs: `terraphim`, `zestic-ai`, `private`
### Q4: Do scoped labels work as expected on 1.22.6?
**ANSWER: YES.** Verified with live test:
- Created `status/backlog` (exclusive=true), `status/in-progress` (exclusive=true), `status/done` (exclusive=true)
- Applied `status/in-progress` via PUT (replace) -- only `status/in-progress` remained
- Then applied `status/backlog` via POST (add) -- `status/in-progress` was **automatically removed**, only `status/backlog` remained
- Scoped label mutual exclusivity is enforced by Gitea on both POST and PUT
### Q5: Do issue dependencies work?
**ANSWER: YES**, but the body format is `IssueMeta` (not `depends_on_id`):
```json
POST /repos/{owner}/{repo}/issues/{index}/dependencies
Body: {"owner": "root", "repo": "skill-test-temp", "index": 2}
```
- `GET .../dependencies` returns the list of issues that block this one
- `GET .../blocks` returns the list of issues this one blocks
- Cross-repo dependencies are supported (owner/repo fields)
### Q6: Do milestones work as project containers?
**ANSWER: YES.** Full CRUD verified:
- Create milestone with title, description, due_on -- returns id, state, open/closed counts
- Issues created with `"milestone": <id>` are linked to the milestone
- Progress tracking works: `open_issues` and `closed_issues` update automatically when issues are opened/closed
- Filter issues by milestone name: `?milestones=Sprint%202026-W08`
- Filter issues by label: `?labels=status/backlog`
### Q7: Does time tracking work?
**ANSWER: YES.** Stopwatch start/stop returns HTTP 201. Tracked times accessible via `GET .../times`.
### Q3: Which repository should be the "default" for agent task tracking?
**ANSWER: `terraphim/agent-tasks`** (user decision 2026-02-18). Configurable via `GITEA_OWNER` and `GITEA_REPO` env vars. Default repo created during setup if it doesn't exist. All open questions resolved.
---
## 8. Recommended Next Steps
### If Approved, Phase 2 (Design) Should:
1. **Verify live API behavior** -- Test project, milestone, and scoped label endpoints against https://git.terraphim.cloud
2. **Design the enhanced SKILL.md** with these sections:
- Authentication (1Password + op read)
- Project Management (milestones as projects)
- Task Management (issues with scoped labels)
- Workflow Operations (agent lifecycle: create -> claim -> update -> close)
- Label Setup (standardized scoped labels for status, priority, type)
- Query Patterns (list by milestone, by label, by state)
- Idempotency Patterns (check-before-create)
- JSON Output Parsing (jq patterns for machine consumption)
3. **Create a label initialization script** that sets up the standard label set in a repository
4. **Document the 1Password setup** for the Gitea API token
5. **Decide on MCP integration** -- whether to recommend gitea-mcp or forgejo-mcp alongside the curl skill
### Scope Recommendation
**Minimal Viable Skill (Phase 2 target):**
- 1Password authentication
- Milestone CRUD (as project proxy)
- Issue CRUD with labels and milestone assignment
- Scoped label workflow (status/backlog -> status/in-progress -> status/done)
- Comment-based progress tracking
- Query by milestone and label filters
**Future Enhancement (Phase 3+, when Gitea 1.26 ships):**
- True project board API integration
- Column management
- Issue-to-project linking
- MCP server integration
---
## 9. Appendix
### A. File Inventory
| File | Path | Relevance |
|------|------|-----------|
| Current skill | `/home/alex/projects/terraphim/gitea-infrastructure/.agents/skills/gitea/SKILL.md` | Primary file to enhance |
| Handover doc | `/home/alex/projects/terraphim/gitea-infrastructure/HANDOVER.md` | Infrastructure context |
| Docker compose template | `/home/alex/projects/terraphim/gitea-infrastructure/docker-compose.yml.template` | 1Password patterns |
| Repository setup | `/home/alex/projects/terraphim/gitea-infrastructure/REPOSITORY-SETUP.md` | Deployment patterns |
| Prior research | `/home/alex/projects/terraphim/gitea-infrastructure/.docs/RESEARCH-gitea-bigbox-deployment.md` | Infrastructure research |
### B. External References
- Gitea API docs: https://docs.gitea.com/api/1.22/
- Gitea Project API feature request: https://github.com/go-gitea/gitea/issues/14299
- Gitea Column API proposal: https://github.com/go-gitea/gitea/issues/31769
- Gitea Project API draft PR: https://github.com/go-gitea/gitea/pull/28111
- Official Gitea MCP server: https://gitea.com/gitea/gitea-mcp
- forgejo-mcp: https://github.com/raohwork/forgejo-mcp
- Tea CLI: https://gitea.com/gitea/tea
- Gitea scoped labels blog: https://blog.gitea.com/introducing-new-features-of-labels-and-projects/
### C. Gitea MCP Server Tool Inventory (for reference)
The official gitea-mcp provides ~80 tools:
- **User**: get_my_user_info, get_user_orgs, search_users
- **Repos**: create_repo, fork_repo, list_my_repos, search_repos
- **Branches**: create_branch, delete_branch, list_branches
- **Tags**: create_tag, delete_tag, get_tag, list_tags
- **Releases**: create_release, delete_release, get_release, get_latest_release, list_releases
- **Files**: get_file_content, get_dir_content, create_file, update_file, delete_file
- **Commits**: list_repo_commits
- **Issues**: get_issue_by_index, list_repo_issues, create_issue, create_issue_comment, edit_issue, edit_issue_comment, get_issue_comments_by_index
- **PRs**: get/list/create/merge pull requests, reviewer management, review CRUD
- **Org labels**: list/create/edit/delete org labels
- **Actions/CI**: workflow, run, job, secret, variable management (~25 tools)
- **Wiki**: list/get/create/update/delete wiki pages
**Not covered by gitea-mcp**: milestones, project boards, repo labels (only org labels), issue labels, issue assignees, issue deadlines
### D. forgejo-mcp Tool Inventory (for reference)
forgejo-mcp provides:
- Issues: create, edit, view, labels (add/remove/replace), comments, attachments, dependencies
- Milestones: create, edit, delete, progress reporting
- Labels: create, edit, delete
- Repos: search, list
- Releases: manage, attachments
- PRs: view
- Wiki: manage
- Actions: view tasks
**Key advantage over gitea-mcp**: Full milestone CRUD support, issue dependency management, issue label management.