- Environment/Deployment XORM models + migration 010 - Full CRUD API: GET/POST/PATCH/DELETE /environments + /deployments - Deployment status update endpoint, publishes deployment.* NATS events - EnvironmentsPage with deploy cards, history accordion, deploy modal - Sidebar Environments nav item between Pipelines and Settings - Repo page deployment status badges (env name + SHA pill per environment) - Environment/Deployment types in types/api.ts + environments.ts query hooks
9.6 KiB
AGENTS.md — ForgeBucket AI Agent Guide
This file is for AI coding agents (Claude Code, GitHub Copilot, etc.) working in this repository. Read it before making changes.
Mission
ForgeBucket is a unified operating system for software delivery — not a Git repository viewer with CI attached. The guiding philosophy:
Repositories are runtime systems. The dashboard is a command center. GitOps is first-class.
Every feature decision should answer: does this reduce cognitive load? Does this improve operational awareness? Does this improve developer flow?
The full product vision lives in ai_agent_master_prompt_for_building_modern_git_platform.md.
Architecture Map
cmd/forgebucket/ — binary entry point (main.go)
internal/
api/
router.go — Chi router, all route definitions (~26 routes)
middleware/ — auth, CSRF, RBAC, logging
handlers/ — one file per domain (repo, pr, issue, auth, user, ssh...)
domain/
git/ — sanitized git binary wrapper (exec.Command only, no shell)
federation/ — ActivityPub / ForgeFed (DATA LAYER ONLY — no handlers yet)
ci/ — CI orchestrator (EMPTY — Phase 2 stub)
models/ — XORM structs + 7 migration files
config/ — ENV-driven config, fails fast on missing secrets
web/ — //go:embed target for the built React SPA
frontend/
src/
pages/ — 20 route-level page components
components/ — shared UI (AppShell, Sidebar, Header, DiffViewer, etc.)
ui/
tokens.ts — SINGLE SOURCE OF TRUTH for all design tokens
hooks/ — custom React hooks
api/ — typed API client (fetch wrappers)
Middleware chain — this order is fixed, do not reorder:
Logger → RealIP → Recoverer → CORS → CSRF → SessionAuth → RBAC → Handler
Current Phase Status
Understand the phases before adding code — don't build Phase 3 infrastructure when Phase 2 is incomplete.
| Phase | Scope | Status |
|---|---|---|
| 1 | Auth, Git HTTP, repos, PRs, issues, RBAC, webhooks, LFS, design system, 20-page SPA | Complete |
| 2A | NATS event bus, WebSocket hub upgrade, audit log | Complete |
| 2B | CI orchestrator, runner manager, Docker executor, artifact registry | Complete |
| 2C | Pipeline DAG visualization, dashboard CI upgrade, command palette wiring | Complete |
| 3A | Environment model + deployment tracking | Active |
| 3B | Unified operational timeline | Planned |
| 3C | Secret management hierarchy | Planned |
| 3D | GitOps controller + drift detection | Planned |
| 3E | Observability (Prometheus, health sparklines) | Planned |
| 3F | Federation handlers (ActivityPub inbox/outbox) | Planned |
| 4 | AI diagnostics, signed artifacts, OCI registry, secret/dep scanning | Planned |
Do not implement Phase 3+ features without explicit discussion. The domain/federation/ directory is an intentional stub — the data model exists but no HTTP handlers should be wired until Phase 3F.
Phase 3A — What to Build
Backend and frontend are both net-new for Phase 3A. Nothing exists yet.
Backend:
internal/models/environment.go—Environment(id, repoId, name, url, protectionRules JSON) +Deployment(id, envId, repoId, sha, ref, status, triggeredBy, description, runId, startedAt, finishedAt)internal/models/migrations/010_environments.go—Run010()syncing both structs; call from001_init.gointernal/api/handlers/environment.go—ListEnvironments,CreateEnvironment,GetEnvironment,UpdateEnvironment,DeleteEnvironment,ListDeployments,CreateDeployment,UpdateDeploymentStatus; publishdeployment.*NATS eventsinternal/api/router.go— wire routes under/{owner}/{repo}/environmentsand/{owner}/{repo}/environments/{envName}/deployments
Frontend:
5. frontend/src/types/api.ts — add Environment, Deployment, DeployStatus types
6. frontend/src/api/queries/environments.ts — useEnvironments, useEnvironment, useCreateEnvironment, useUpdateEnvironment, useDeleteEnvironment, useDeployments, useCreateDeployment, useUpdateDeploymentStatus
7. frontend/src/pages/EnvironmentsPage.tsx — environment cards each showing latest deployment status, SHA, who deployed, time; "New environment" flow; deployment history per env
8. frontend/src/components/layout/Sidebar.tsx — add Environments nav item between Pipelines and Settings in RepoSubNav
9. frontend/src/pages/RepoPage.tsx — surface deployment status badges in the repo header (latest deploy per env at a glance)
10. frontend/src/App.tsx — add route repos/:owner/:repo/environments
Go Conventions
Git commands — critical rule
Always use exec.Command("git", arg1, arg2, ...) with discrete arguments. Never build a shell string from user input.
// CORRECT
cmd := exec.Command("git", "clone", "--bare", repoURL, destPath)
// WRONG — never do this
cmd := exec.Command("sh", "-c", "git clone "+userInput)
This rule is non-negotiable. It prevents command injection.
Router / handlers
- Chi router. Route definitions in
internal/api/router.go. - One handler file per domain area. Keep handlers thin — business logic belongs in domain packages.
- All POST/PUT/DELETE routes require
X-CSRF-Tokenheader matching the session cookie. The middleware enforces this, but don't remove it from routes.
Database
- XORM for all DB access. Structs in
internal/models/. - Migrations are numbered files in
internal/models/migrations/. Always add a new migration file; never edit existing ones. - No raw SQL strings built from user input.
Secrets and config
- All secrets come from environment variables via
internal/config/. - Never hardcode secrets, tokens, or credentials anywhere.
SESSION_SECRET≥ 32 chars.CSRF_SECRET= exactly 32 chars.
Error handling
- Return errors up the call stack. Don't swallow them silently.
- HTTP handlers use consistent JSON error responses — follow the pattern in existing handlers.
TypeScript / React Conventions
Design tokens — critical rule
All spacing, color, and sizing values must come from frontend/src/ui/tokens.ts. Do not introduce new hardcoded pixel values or color hex codes.
// CORRECT — use token classes via Tailwind
<div className="p-sm gap-xs">
// WRONG — arbitrary values
<div style={{ padding: "12px" }}>
Grid system
- Base unit: 8px. All spacing is multiples of 4px (
xs) or 8px (sm). - Touch targets: 44px minimum height/width on all interactive elements (buttons, links, icon buttons).
Dark mode
- Use Tailwind v4
@variant dark— not hardcoded dark: classes unless inside a component that explicitly handles both. - Colors must work in both light and dark modes. Test both.
Component patterns
AppShellwraps all authenticated pages. Don't bypass it.Sidebarhas three states: expanded (320px), collapsed (56px), mobile bottom bar. Respect all three.- Mobile-first: design for 375px, enhance for 1440px. Use the
BottomTabBarfor mobile nav — don't add new nav patterns. - Loading states: use
Skeletoncomponents for perceived performance, not spinners. - Mobile code review: use the
MobileCommentbottom-sheet pattern — not modals.
API calls
- Use the typed API client in
frontend/src/api/— don't write rawfetchcalls in components. - Always include
X-CSRF-Tokenheader on mutating requests.
What NOT to Do
- No shell string injection — see Go conventions above
- No hardcoded secrets — everything via env
- No skipping CSRF — all mutating routes require it
- No arbitrary design values — tokens.ts is the law
- No Phase 3+ features without discussion — don't wire up GitOps, federation handlers, or the command palette until Phase 2 is complete
- No new color tokens — if the design requires a new color, discuss it; don't invent one
- No modal-heavy UX — this platform uses progressive disclosure; avoid deep modal chains
- No YAML-centric UI — pipeline and environment config should feel operational, not config-file editing
Testing
make test # Go tests (go test ./...) + Vitest (frontend unit tests)
make lint # go vet + ESLint
- Go: test files live alongside source files (
*_test.go) - Frontend: Vitest for unit tests, component tests alongside components
- All UI changes must be manually verified at 1440px desktop and 375px mobile
Key Files Reference
| File | Purpose |
|---|---|
internal/api/router.go |
All route definitions — start here for backend |
internal/models/ |
XORM models + migrations — all DB schemas |
internal/config/config.go |
Env-driven config, required vars |
internal/domain/git/ |
Git binary wrapper — safe exec patterns |
frontend/src/ui/tokens.ts |
Design token source of truth |
frontend/src/components/AppShell.tsx |
Root layout wrapper |
frontend/src/components/Sidebar.tsx |
3-state navigation sidebar |
frontend/src/pages/ |
All 20 route-level pages |
frontend/src/api/ |
Typed API client |
.env.example |
All required environment variables |
CLAUDE.md |
Developer guide (rules overlap with this file — CLAUDE.md takes precedence on conflicts) |
Running Locally
cp .env.example .env # fill SESSION_SECRET and CSRF_SECRET
make docker-up # PostgreSQL via Docker Compose
make migrate # run XORM migrations
make dev # Go :8080 + Vite :5173