Files
gitea-mcp/.context/PROJECT.md
mathias a414222610
All checks were successful
CD / Lint / Test / Vet (push) Successful in 8s
CD / Build & Import (push) Successful in 13s
CD / Deploy via GitOps (push) Successful in 3s
docs: update sprint to v0.2 patch — fixes #12, #24, #25
2026-05-16 20:43:29 +00:00

175 lines
6.7 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*
- **Branch protection:** always work on a feature branch, open a PR, never push directly to main
### 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. Always work on a feature branch and open a PR — never push directly to main
7. For client projects: never send code or context to cloud APIs — use local models via LiteLLM
## Current sprint — gitea-mcp v0.2 patch (2026-05-14)
### Context
The main v0.2 batch (repo_create, repo_update, repo_mirror_push, repo_delete,
repo_tree, repo_topics_update, file_read dir-fix, issue_get, release_create,
create_project_from_template) was implemented and pushed directly to main.
This sprint fixes three remaining gaps found during code review on 2026-05-14.
These are blockers for `hyperguild new-project`.
### Issues to fix (all three in one PR: `fix/v02-patch`)
#### #12 — repo_update: add `archived` and `template` fields
**File:** `internal/gitea/repos.go``UpdateRepoArgs` struct
**File:** `internal/tools/repo_update.go` → input schema + args struct
Add to `UpdateRepoArgs`:
```go
Archived *bool
Template *bool
```
Add to tool input schema:
```json
"archived": {
"type": "boolean",
"description": "Mark repo as archived (read-only). Requires confirm=<repo name>."
},
"template": {
"type": "boolean",
"description": "Toggle template repo flag."
}
```
Add confirm-guard for `archived=true` (same pattern as `private=false`):
```go
if args.Archived != nil && *args.Archived {
if args.Confirm != args.Name {
return nil, fmt.Errorf("setting archived=true is irreversible: set confirm=%q to proceed", args.Name)
}
}
```
New test cases to add in `repo_update_test.go`:
- `TestRepoUpdateTool_Archive` — happy path with confirm
- `TestRepoUpdateTool_ArchiveRequiresConfirm` — missing confirm returns error
- `TestRepoUpdateTool_SetTemplate` — no confirm needed
#### #24 — create_project_from_template: make template selectable
**File:** `internal/tools/create_project_from_template.go`
Add optional `template_name` param to input schema:
```json
"template_name": {
"type": "string",
"enum": ["template-go-web", "template-go-agent"],
"description": "Template repo to generate from. Defaults to template-go-web.",
"default": "template-go-web"
}
```
The tool should use `args.TemplateName` if set, fall back to the hardcoded default.
Remove the hardcoded template name from `cmd/gitea-mcp/main.go` constructor call —
the tool resolves it internally.
New test case: `TestCreateProjectFromTemplate_AgentTemplate`
#### #25 — pr_files_diff: fix same diff returned for all files
**File:** `internal/tools/pr_files_diff.go`
There is a loop bug where all file entries in the response contain the same diff
(the first file's diff is reused for every subsequent file). Find the loop and
ensure each iteration reads and assigns the correct diff for its own file.
Reproduce: call `pr_files_diff` on any PR with 3+ files, verify each file has
a distinct diff.
### Definition of done
- [ ] `task check` passes
- [ ] `repo_update` accepts `archived` and `template` params
- [ ] `archived=true` requires `confirm=<repo name>`
- [ ] `create_project_from_template` accepts `template_name` param, defaults to `template-go-web`
- [ ] `pr_files_diff` returns distinct diff per file
- [ ] All new test cases pass
- [ ] PR `fix/v02-patch` merged to main via PR (not direct push)
### After this sprint
Next: `hyperguild new-project` v1 implementation.
See brain node `adr-new-project-gitea-first-github-mirror` for the full flow spec.
Also: verify end-to-end mirror flow (issue #19) once `repo_mirror_push` is confirmed working.