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>
21 KiB
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):
- Authenticate -- Log in via API token (stored in 1Password)
- Create a project -- Set up a project board for organizing work
- Create tasks -- File issues within a repository and associate them with the project
- 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:
- No authentication via 1Password (
op injectorop read) - No project column/board management (create columns, move issues between columns)
- No milestone management (create, update, list, close)
- No workflow patterns (agent-oriented: ready/claim/implement/close)
- No idempotency patterns (check-before-create)
- No JSON output parsing patterns for machine consumption
- No issue template patterns (standardized issue bodies)
- 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 injectwithop://TerraphimPlatform/...references - Source auth:
source ~/op_zesticai_non_prod.shsetsOP_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
--jsonflag 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 "[FEATURE] API for projects" -- opened Jan 2021, still OPEN as of Feb 2026, assigned to milestone 1.26.0
- PR #28111 adding project API endpoints -- still in DRAFT status, targeted for 1.26.0
- GitHub Issue #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/projectsreturns HTTP 404 ("404 page not found")GET /api/v1/repos/terraphim/gitea-infrastructure/projectsreturns 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)
- ~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)
- 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)
- 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-progressautomatically removesstatus/backlog - Applying
priority/P0-criticalautomatically removespriority/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:
# 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:
- Create the token manually via Gitea Web UI (Settings -> Applications -> Generate New Token)
- Store the token in 1Password under
TerraphimPlatform/gitea-api-token - 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 issuesread:repository+write:repository-- Access repo metadataread:user-- Read user information for assigneesread:organization-- Access org reposwrite: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 credentialsgitea-s3-- S3 storage credentialsGitea.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-aiterraphim/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-progressvia PUT (replace) -- onlystatus/in-progressremained - Then applied
status/backlogvia POST (add) --status/in-progresswas automatically removed, onlystatus/backlogremained - 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):
POST /repos/{owner}/{repo}/issues/{index}/dependencies
Body: {"owner": "root", "repo": "skill-test-temp", "index": 2}
GET .../dependenciesreturns the list of issues that block this oneGET .../blocksreturns 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_issuesandclosed_issuesupdate 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:
-
Verify live API behavior -- Test project, milestone, and scoped label endpoints against https://git.terraphim.cloud
-
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)
-
Create a label initialization script that sets up the standard label set in a repository
-
Document the 1Password setup for the Gitea API token
-
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.