diff --git a/.aider.conventions.md b/.aider.conventions.md index a48af53..ecfd5ff 100644 --- a/.aider.conventions.md +++ b/.aider.conventions.md @@ -36,6 +36,18 @@ These rules apply to every task across every project, regardless of harness. 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). +5. **Trunk-Based Development — commit directly to main.** Every commit is one + logical change (one tool, one fix, one test) with passing tests. Main is always + deployable. Never create long-lived feature branches. + + **Exception — parallel agents on same repo:** If another agent is known to be + actively working on the same repo simultaneously, create a short-lived branch + (`agent/`), finish the task, and merge to main within the same + session. Do not leave agent branches open between sessions. + + **Exception — external contributor or client four-eyes requirement:** Use + PR flow only when a human reviewer outside the project is required. Document + the reason in PROJECT.md. ## Default stack @@ -49,6 +61,7 @@ These rules apply to every task across every project, regardless of harness. | Search | pgvector (vector), BM25 | Qdrant (when >1M vectors or hybrid retrieval) | — | | Logging | slog (structured) | — | — | | Testing | Table-driven, testify | — | — | +| Agents (Go) | google.golang.org/adk + pkg/litellm adapter | — | — | Exploratory: Rust, Zig — I'll tell you when I want these. @@ -58,9 +71,12 @@ Exploratory: Rust, Zig — I'll tell you when I want these. - **Errors**: `fmt.Errorf("operation: %w", err)` — never naked, never log-and-return - **Naming**: stdlib conventions, no stuttering - **Architecture**: prefer stdlib over frameworks, constructor injection, env-var config parsed into typed structs -- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), one concern per PR, PR describes *why* not *what* +- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), commit directly to main, + one logical change per commit, CI is the quality gate +- **Never**: long-lived feature branches, PRs for solo work, direct push without + passing `task check` locally first - **Security**: no secrets in code, govulncheck before adding deps, SOPS for encrypted config -- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc are pre-approved; anything else needs justification in the commit message +- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc, google.golang.org/adk (agent projects only) are pre-approved; anything else needs justification in the commit message ## Infrastructure @@ -251,95 +267,25 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production. diff --git a/.context/PROJECT.md b/.context/PROJECT.md index 64260d2..1d967a9 100644 --- a/.context/PROJECT.md +++ b/.context/PROJECT.md @@ -80,95 +80,25 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production. diff --git a/.context/system-prompt.txt b/.context/system-prompt.txt index 23b35d4..a597838 100644 --- a/.context/system-prompt.txt +++ b/.context/system-prompt.txt @@ -41,6 +41,18 @@ These rules apply to every task across every project, regardless of harness. 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). +5. **Trunk-Based Development — commit directly to main.** Every commit is one + logical change (one tool, one fix, one test) with passing tests. Main is always + deployable. Never create long-lived feature branches. + + **Exception — parallel agents on same repo:** If another agent is known to be + actively working on the same repo simultaneously, create a short-lived branch + (`agent/`), finish the task, and merge to main within the same + session. Do not leave agent branches open between sessions. + + **Exception — external contributor or client four-eyes requirement:** Use + PR flow only when a human reviewer outside the project is required. Document + the reason in PROJECT.md. ## Default stack @@ -54,6 +66,7 @@ These rules apply to every task across every project, regardless of harness. | Search | pgvector (vector), BM25 | Qdrant (when >1M vectors or hybrid retrieval) | — | | Logging | slog (structured) | — | — | | Testing | Table-driven, testify | — | — | +| Agents (Go) | google.golang.org/adk + pkg/litellm adapter | — | — | Exploratory: Rust, Zig — I'll tell you when I want these. @@ -63,9 +76,12 @@ Exploratory: Rust, Zig — I'll tell you when I want these. - **Errors**: `fmt.Errorf("operation: %w", err)` — never naked, never log-and-return - **Naming**: stdlib conventions, no stuttering - **Architecture**: prefer stdlib over frameworks, constructor injection, env-var config parsed into typed structs -- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), one concern per PR, PR describes *why* not *what* +- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), commit directly to main, + one logical change per commit, CI is the quality gate +- **Never**: long-lived feature branches, PRs for solo work, direct push without + passing `task check` locally first - **Security**: no secrets in code, govulncheck before adding deps, SOPS for encrypted config -- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc are pre-approved; anything else needs justification in the commit message +- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc, google.golang.org/adk (agent projects only) are pre-approved; anything else needs justification in the commit message ## Infrastructure @@ -256,97 +272,27 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production. --- diff --git a/.cursorrules b/.cursorrules index cc7d254..ba26911 100644 --- a/.cursorrules +++ b/.cursorrules @@ -39,6 +39,18 @@ These rules apply to every task across every project, regardless of harness. 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). +5. **Trunk-Based Development — commit directly to main.** Every commit is one + logical change (one tool, one fix, one test) with passing tests. Main is always + deployable. Never create long-lived feature branches. + + **Exception — parallel agents on same repo:** If another agent is known to be + actively working on the same repo simultaneously, create a short-lived branch + (`agent/`), finish the task, and merge to main within the same + session. Do not leave agent branches open between sessions. + + **Exception — external contributor or client four-eyes requirement:** Use + PR flow only when a human reviewer outside the project is required. Document + the reason in PROJECT.md. ## Default stack @@ -52,6 +64,7 @@ These rules apply to every task across every project, regardless of harness. | Search | pgvector (vector), BM25 | Qdrant (when >1M vectors or hybrid retrieval) | — | | Logging | slog (structured) | — | — | | Testing | Table-driven, testify | — | — | +| Agents (Go) | google.golang.org/adk + pkg/litellm adapter | — | — | Exploratory: Rust, Zig — I'll tell you when I want these. @@ -61,9 +74,12 @@ Exploratory: Rust, Zig — I'll tell you when I want these. - **Errors**: `fmt.Errorf("operation: %w", err)` — never naked, never log-and-return - **Naming**: stdlib conventions, no stuttering - **Architecture**: prefer stdlib over frameworks, constructor injection, env-var config parsed into typed structs -- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), one concern per PR, PR describes *why* not *what* +- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), commit directly to main, + one logical change per commit, CI is the quality gate +- **Never**: long-lived feature branches, PRs for solo work, direct push without + passing `task check` locally first - **Security**: no secrets in code, govulncheck before adding deps, SOPS for encrypted config -- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc are pre-approved; anything else needs justification in the commit message +- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc, google.golang.org/adk (agent projects only) are pre-approved; anything else needs justification in the commit message ## Infrastructure @@ -254,95 +270,25 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production. diff --git a/AGENTS.md b/AGENTS.md index a48af53..ecfd5ff 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -36,6 +36,18 @@ These rules apply to every task across every project, regardless of harness. 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). +5. **Trunk-Based Development — commit directly to main.** Every commit is one + logical change (one tool, one fix, one test) with passing tests. Main is always + deployable. Never create long-lived feature branches. + + **Exception — parallel agents on same repo:** If another agent is known to be + actively working on the same repo simultaneously, create a short-lived branch + (`agent/`), finish the task, and merge to main within the same + session. Do not leave agent branches open between sessions. + + **Exception — external contributor or client four-eyes requirement:** Use + PR flow only when a human reviewer outside the project is required. Document + the reason in PROJECT.md. ## Default stack @@ -49,6 +61,7 @@ These rules apply to every task across every project, regardless of harness. | Search | pgvector (vector), BM25 | Qdrant (when >1M vectors or hybrid retrieval) | — | | Logging | slog (structured) | — | — | | Testing | Table-driven, testify | — | — | +| Agents (Go) | google.golang.org/adk + pkg/litellm adapter | — | — | Exploratory: Rust, Zig — I'll tell you when I want these. @@ -58,9 +71,12 @@ Exploratory: Rust, Zig — I'll tell you when I want these. - **Errors**: `fmt.Errorf("operation: %w", err)` — never naked, never log-and-return - **Naming**: stdlib conventions, no stuttering - **Architecture**: prefer stdlib over frameworks, constructor injection, env-var config parsed into typed structs -- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), one concern per PR, PR describes *why* not *what* +- **Git**: conventional commits (`feat:`, `fix:`, `chore:`), commit directly to main, + one logical change per commit, CI is the quality gate +- **Never**: long-lived feature branches, PRs for solo work, direct push without + passing `task check` locally first - **Security**: no secrets in code, govulncheck before adding deps, SOPS for encrypted config -- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc are pre-approved; anything else needs justification in the commit message +- **Dependencies**: prefer stdlib. testify, slog, templ, sqlc, google.golang.org/adk (agent projects only) are pre-approved; anything else needs justification in the commit message ## Infrastructure @@ -251,95 +267,25 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production. diff --git a/CLAUDE.md b/CLAUDE.md index 64260d2..1d967a9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -80,95 +80,25 @@ When acting as a coding agent on this project: 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) +## Current state — v0.2.5 (2026-05-17) -### 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. +All v0.2 work is complete and deployed. No active sprint. -This sprint fixes three remaining gaps found during code review on 2026-05-14. -These are blockers for `hyperguild new-project`. +### What shipped -### Issues to fix (all three in one PR: `fix/v02-patch`) +| Tag | PR | Tools / fixes | +|-----|----|---------------| +| v0.2.2 | #21 | repo_create, repo_update, repo_mirror_push | +| v0.2.3 | #22 | repo_tree, repo_topics_update, file_read dir fix | +| v0.2.4 | #23 | issue_get, release_create, repo_delete | +| v0.2.5 | #26 | repo_update archived+template, create_project_from_template template_name, pr_files_diff loop fix | -#### #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 +Current main: `e31fd3f`. CI green. Deployed via Flux. -Add to `UpdateRepoArgs`: -```go -Archived *bool -Template *bool -``` +### Next up -Add to tool input schema: -```json -"archived": { - "type": "boolean", - "description": "Mark repo as archived (read-only). Requires confirm=." -}, -"template": { - "type": "boolean", - "description": "Toggle template repo flag." -} -``` +1. **`hyperguild new-project` v1** — primary next target. + See brain node `adr-new-project-gitea-first-github-mirror` for full flow spec. -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=` -- [ ] `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. +2. **Issue #19** — end-to-end mirror flow verification. + `repo_mirror_push` is implemented but the full flow (create repo → add push mirror → verify sync to GitHub) has not been tested manually. Do this before relying on it in production.