144 lines
6.0 KiB
Markdown
144 lines
6.0 KiB
Markdown
# Project context
|
|
|
|
<!-- Canonical project context. Edit this, run `task context:sync`.
|
|
Root agent context from ~/dev/.context/AGENT.md is automatically
|
|
prepended for harnesses that don't walk the directory tree. -->
|
|
|
|
## Identity
|
|
|
|
- **Name**: gitea-mcp
|
|
- **Owner**: Mathias
|
|
- **Client**: personal
|
|
- **Repo**: https://gitea.d-ma.be/mathias/gitea-mcp
|
|
- **Status**: active
|
|
|
|
## Stack
|
|
|
|
- **Primary language**: Go
|
|
- **UI layer**: HTMX + Templ (when applicable)
|
|
- **Fallback languages**: Python, TypeScript (justify in PR if used)
|
|
- **Build**: Task (taskfile.dev), not Make
|
|
- **Containers**: Docker (compose for dev, k3s for deploy)
|
|
- **Target infra**: koala (GPU workloads), iguana (services), flamingo (edge)
|
|
|
|
## Conventions
|
|
|
|
### Code style
|
|
- Go: follow `golines`, `gofumpt`, `golangci-lint` with project config
|
|
- Tests: table-driven, in `_test.go` next to source, `testify` for assertions
|
|
- Errors: wrap with `fmt.Errorf("operation: %w", err)`, no naked returns
|
|
- Naming: stdlib conventions, no stuttering (`http.Client` not `http.HTTPClient`)
|
|
|
|
### Architecture preferences
|
|
- Prefer standard library over frameworks (net/http over gin/echo)
|
|
- Dependency injection via constructor functions, not containers
|
|
- Configuration via environment variables, parsed at startup into a typed struct
|
|
- Structured logging via `slog`
|
|
|
|
### Git
|
|
- Conventional commits: `feat:`, `fix:`, `chore:`, `docs:`, `refactor:`
|
|
- Branch naming: `feat/short-description`, `fix/short-description`
|
|
- PRs: one concern per PR, description explains *why* not *what*
|
|
|
|
### Security
|
|
- No secrets in code, ever — use env vars or SOPS-encrypted files
|
|
- Client data never leaves local network unless explicitly cleared
|
|
- Dependencies: audit with `govulncheck` before adding
|
|
|
|
## Knowledge base access
|
|
|
|
This project can query the shared knowledge base via MCP or HTTP:
|
|
|
|
- **MCP endpoint**: `mcp://localhost:3100/knowledge`
|
|
- **HTTP fallback**: `http://localhost:3100/api/v1/search`
|
|
- **Scoping**: queries are filtered to collection `personal` + `public`
|
|
|
|
## Behavior rules
|
|
|
|
These rules apply to every task in this project, regardless of harness.
|
|
|
|
1. **No assumptions.** Don't hide confusion — surface it. Surface tradeoffs explicitly.
|
|
Think before coding; if the problem is unclear, ask or state assumptions before acting.
|
|
2. **Minimum viable code.** Solve with the smallest change that works. Nothing
|
|
speculative, no "while we're here" cleanups, no premature abstractions. Simplicity first.
|
|
3. **Surgical changes.** Touch only what the task requires. Leave unrelated code,
|
|
files, and formatting alone. Diffs should be small and reviewable.
|
|
4. **Goal-driven execution.** Define clear success criteria up front for every task.
|
|
Loop — implement, verify, refine — until those criteria are met. Don't claim
|
|
completion without evidence (tests pass, command output, observed behavior).
|
|
|
|
## Agent instructions
|
|
|
|
When acting as a coding agent on this project:
|
|
|
|
1. Read this file and all `SKILL.md` files in `.skills/` before starting work
|
|
2. Run `task check` before committing (lint + test + vet)
|
|
3. If unsure about a convention, check `DECISIONS.md` or ask
|
|
4. Never modify files outside the project root without explicit permission
|
|
5. When adding a dependency, explain why in the commit message
|
|
6. For client projects: never send code or context to cloud APIs — use local models via LiteLLM
|
|
|
|
## Current sprint — gitea-mcp v0.2 (2026-05-14)
|
|
|
|
### Context
|
|
This sprint implements new MCP tools needed for `hyperguild new-project` —
|
|
the automated project creation flow triggered from claude.ai. See brain knowledge
|
|
nodes `adr-new-project-gitea-first-github-mirror` and `roadmap-github-ingestion-pipeline`
|
|
for full background.
|
|
|
|
### Issues to implement (priority order)
|
|
|
|
**Batch 1 — blockers (do first, one PR: `feat/repo-crud`)**
|
|
|
|
| Issue | Tool | Gitea API |
|
|
|-------|------|-----------|
|
|
| #13 | `repo_create` | POST /api/v1/user/repos or /api/v1/orgs/{org}/repos |
|
|
| #16 | `repo_mirror_push` (add/list/delete) | POST/GET/DELETE /api/v1/repos/{owner}/{repo}/push_mirrors |
|
|
| #12 | `repo_update` | PATCH /api/v1/repos/{owner}/{repo} |
|
|
|
|
**Batch 2 — quality of life (second PR: `feat/repo-ux`)**
|
|
|
|
| Issue | Tool | Gitea API |
|
|
|-------|------|-----------|
|
|
| #15 | `file_read` dir-path fix | existing endpoint, detect array vs object response |
|
|
| #14 | `repo_tree` | GET /api/v1/repos/{owner}/{repo}/git/trees/{sha}?recursive=true |
|
|
| #18 | `repo_topics_update` | PUT /api/v1/repos/{owner}/{repo}/topics |
|
|
|
|
**Batch 3 — can wait**
|
|
|
|
| Issue | Tool | Note |
|
|
|-------|------|------|
|
|
| #11 | `repo_delete` | HIGH risk — needs `confirm` param == repo name |
|
|
| #17 | `release_create` | POST /api/v1/repos/{owner}/{repo}/releases |
|
|
|
|
### How to add a tool (pattern)
|
|
|
|
Every tool = 4 files following `internal/tools/repo_get.go` exactly:
|
|
|
|
1. `internal/gitea/<domain>.go` — API client method (use PostJSON/PatchJSON/DeleteJSON)
|
|
2. `internal/tools/repo_<name>.go` — tool handler with Descriptor() + Call()
|
|
3. `internal/tools/repo_<name>_test.go` — table-driven tests with httptest.NewServer
|
|
4. Registration in main — find where `NewRepoGet` is registered, add new tool same place
|
|
|
|
Key rules:
|
|
- Always call `t.a.Check(args.Owner)` before any API call (allowlist guard)
|
|
- Use `textOK(result)` for success output
|
|
- For `repo_mirror_push`: NEVER log or return `remote_password` in any output
|
|
- For `repo_update` with `private: false` and `repo_delete`: require `confirm` param == repo name
|
|
|
|
### Token permissions needed
|
|
|
|
New tools require these additional Gitea token scopes:
|
|
- `write:repository` — repo_create, repo_update, repo_mirror_push, repo_topics_update, release_create
|
|
- `delete_repo` — repo_delete
|
|
|
|
Check current token: `curl -H "Authorization: token $GITEA_TOKEN" https://gitea.d-ma.be/api/v1/user`
|
|
If scopes are missing, update token in Gitea settings before running tests.
|
|
|
|
### Definition of done
|
|
|
|
- `task check` passes (all tools, all batches)
|
|
- Each new tool manually callable via `claude mcp call`
|
|
- PR #1 (batch 1) merged before starting batch 2
|
|
- Issue #19 (mirror flow e2e test) verified manually after batch 1 is deployed
|