diff --git a/.claude-plugin/commands/ci-ci.md b/.claude-plugin/commands/ci-ci.md new file mode 100644 index 0000000..2471186 --- /dev/null +++ b/.claude-plugin/commands/ci-ci.md @@ -0,0 +1,80 @@ +--- +name: ci +description: Check CI status and manage workflows +args: [status|run|logs|fix] +--- + +# CI Integration + +Check GitHub Actions status and manage CI workflows. + +## Commands + +### Status (default) +``` +/ci:ci +/ci:ci status +``` + +Check current CI status for the repo/branch. + +### Run workflow +``` +/ci:ci run +/ci:ci run tests +``` + +Trigger a workflow run. + +### View logs +``` +/ci:ci logs +/ci:ci logs 12345 +``` + +View logs from a workflow run. + +### Fix failing CI +``` +/ci:ci fix +``` + +Analyse failing CI and suggest fixes. + +## Implementation + +### Check status +```bash +gh run list --limit 5 +gh run view --log-failed +``` + +### Trigger workflow +```bash +gh workflow run tests.yml +``` + +### View logs +```bash +gh run view 12345 --log +``` + +## CI Status Report + +```markdown +## CI Status: main + +| Workflow | Status | Duration | Commit | +|----------|--------|----------|--------| +| Tests | ✓ passing | 2m 34s | abc123 | +| Lint | ✓ passing | 45s | abc123 | +| Build | ✗ failed | 1m 12s | abc123 | + +### Failing: Build +``` +Error: go build failed + pkg/api/handler.go:42: undefined: ErrNotFound +``` + +**Suggested fix**: Add missing error definition +``` diff --git a/.claude-plugin/commands/ci-fix.md b/.claude-plugin/commands/ci-fix.md new file mode 100644 index 0000000..722592d --- /dev/null +++ b/.claude-plugin/commands/ci-fix.md @@ -0,0 +1,97 @@ +--- +name: fix +description: Analyse and fix failing CI +--- + +# Fix CI + +Analyse failing CI runs and suggest/apply fixes. + +## Process + +1. **Get failing run** + ```bash + gh run list --status failure --limit 1 + gh run view --log-failed + ``` + +2. **Analyse failure** + - Parse error messages + - Identify root cause + - Check if local issue or CI-specific + +3. **Suggest fix** + - Code changes if needed + - CI config changes if needed + +4. **Apply fix** (if approved) + +## Common CI Failures + +### Test Failures +``` +Error: go test failed +--- FAIL: TestFoo +``` +→ Fix the failing test locally, then push + +### Lint Failures +``` +Error: golangci-lint failed +file.go:42: undefined: X +``` +→ Fix lint issue locally + +### Build Failures +``` +Error: go build failed +cannot find package +``` +→ Run `go mod tidy`, check imports + +### Dependency Issues +``` +Error: go mod download failed +``` +→ Check go.mod, clear cache, retry + +### Timeout +``` +Error: Job exceeded time limit +``` +→ Optimise tests or increase timeout in workflow + +## Output + +```markdown +## CI Failure Analysis + +**Run**: #12345 +**Workflow**: Tests +**Failed at**: 2024-01-15 14:30 + +### Error +``` +--- FAIL: TestCreateUser (0.02s) + handler_test.go:45: expected 200, got 500 +``` + +### Analysis +The test expects a 200 response but gets 500. This indicates the handler is returning an error. + +### Root Cause +Looking at recent changes, `ErrNotFound` was removed but still referenced. + +### Fix +Add the missing error definition: +```go +var ErrNotFound = errors.New("not found") +``` + +### Commands +```bash +# Apply fix and push +git add . && git commit -m "fix: add missing ErrNotFound" +git push +``` +``` diff --git a/.claude-plugin/commands/ci-run.md b/.claude-plugin/commands/ci-run.md new file mode 100644 index 0000000..7a501ae --- /dev/null +++ b/.claude-plugin/commands/ci-run.md @@ -0,0 +1,76 @@ +--- +name: run +description: Trigger a CI workflow run +args: [workflow-name] +--- + +# Run Workflow + +Manually trigger a GitHub Actions workflow. + +## Usage + +``` +/ci:run # Run default workflow +/ci:run tests # Run specific workflow +/ci:run release # Trigger release workflow +``` + +## Process + +1. **List available workflows** + ```bash + gh workflow list + ``` + +2. **Trigger workflow** + ```bash + gh workflow run tests.yml + gh workflow run tests.yml --ref feature-branch + ``` + +3. **Watch progress** + ```bash + gh run watch + ``` + +## Common Workflows + +| Workflow | Trigger | Purpose | +|----------|---------|---------| +| `tests.yml` | Push, PR | Run test suite | +| `lint.yml` | Push, PR | Run linters | +| `build.yml` | Push | Build artifacts | +| `release.yml` | Tag | Create release | +| `deploy.yml` | Manual | Deploy to environment | + +## Output + +```markdown +## Workflow Triggered + +**Workflow**: tests.yml +**Branch**: feature/add-auth +**Run ID**: 12345 + +Watching progress... + +``` +⠋ Tests running... + ✓ Setup (12s) + ✓ Install dependencies (45s) + ⠋ Run tests (running) +``` + +**Run completed in 2m 34s** ✓ +``` + +## Options + +```bash +# Run with inputs (for workflows that accept them) +gh workflow run deploy.yml -f environment=staging + +# Run on specific ref +gh workflow run tests.yml --ref main +``` diff --git a/.claude-plugin/commands/ci-status.md b/.claude-plugin/commands/ci-status.md new file mode 100644 index 0000000..afd7d99 --- /dev/null +++ b/.claude-plugin/commands/ci-status.md @@ -0,0 +1,63 @@ +--- +name: status +description: Show CI status for current branch +--- + +# CI Status + +Show GitHub Actions status for the current branch. + +## Usage + +``` +/ci:status +/ci:status --all # All recent runs +/ci:status --branch X # Specific branch +``` + +## Commands + +```bash +# Current branch status +gh run list --branch $(git branch --show-current) --limit 5 + +# Get details of latest run +gh run view --log-failed + +# Watch running workflow +gh run watch +``` + +## Output + +```markdown +## CI Status: feature/add-auth + +| Workflow | Status | Duration | Commit | When | +|----------|--------|----------|--------|------| +| Tests | ✓ pass | 2m 34s | abc123 | 5m ago | +| Lint | ✓ pass | 45s | abc123 | 5m ago | +| Build | ✓ pass | 1m 12s | abc123 | 5m ago | + +**All checks passing** ✓ + +--- + +Or if failing: + +| Workflow | Status | Duration | Commit | When | +|----------|--------|----------|--------|------| +| Tests | ✗ fail | 1m 45s | abc123 | 5m ago | +| Lint | ✓ pass | 45s | abc123 | 5m ago | +| Build | - skip | - | abc123 | 5m ago | + +**1 workflow failing** + +### Tests Failure +``` +--- FAIL: TestCreateUser + expected 200, got 500 +``` + +Run `/ci:fix` to analyse and fix. +``` diff --git a/.claude-plugin/commands/ci-workflow.md b/.claude-plugin/commands/ci-workflow.md new file mode 100644 index 0000000..a98b974 --- /dev/null +++ b/.claude-plugin/commands/ci-workflow.md @@ -0,0 +1,76 @@ +--- +name: workflow +description: Create or update GitHub Actions workflow +args: +--- + +# Workflow Generator + +Create or update GitHub Actions workflows. + +## Workflow Types + +### test +Standard test workflow for Go/PHP projects. + +### lint +Linting workflow with golangci-lint or PHPStan. + +### release +Release workflow with goreleaser or similar. + +### deploy +Deployment workflow (requires configuration). + +## Usage + +``` +/ci:workflow test +/ci:workflow lint +/ci:workflow release +``` + +## Templates + +### Go Test Workflow +```yaml +name: Tests + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-go@v5 + with: + go-version: '1.22' + - run: go test -v ./... +``` + +### PHP Test Workflow +```yaml +name: Tests + +on: + push: + branches: [main] + pull_request: + branches: [main] + +jobs: + test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: shivammathur/setup-php@v2 + with: + php-version: '8.3' + - run: composer install + - run: composer test +``` diff --git a/.claude-plugin/commands/coolify-deploy.md b/.claude-plugin/commands/coolify-deploy.md new file mode 100644 index 0000000..b14948b --- /dev/null +++ b/.claude-plugin/commands/coolify-deploy.md @@ -0,0 +1,162 @@ +--- +name: deploy +description: Deploy a service to Coolify via browser automation +args: [service-name] +flags: + project: + description: Target project name (default Software Staging) + type: string + default: Software Staging + search: + description: Search term if different from service name + type: string +--- + +# Deploy Service to Coolify + +Deploy applications, databases, or one-click services to Coolify using browser automation. + +## Usage + +```bash +/coolify:deploy open-webui +/coolify:deploy litellm +/coolify:deploy flowise --search "flowise with databases" +/coolify:deploy n8n --project "My first project" +``` + +## Browser Automation Workflow + +### 1. Load Required Tools + +``` +ToolSearch: select:mcp__claude-in-chrome__tabs_context_mcp +ToolSearch: select:mcp__claude-in-chrome__computer +ToolSearch: select:mcp__claude-in-chrome__read_page +``` + +### 2. Get Tab Context + +``` +mcp__claude-in-chrome__tabs_context_mcp(createIfEmpty: true) +``` + +### 3. Navigate to New Resource Page + +``` +# Default to localhost (local dev instance) +COOLIFY_URL="${COOLIFY_URL:-http://localhost:8000}" + +mcp__claude-in-chrome__navigate( + tabId: , + url: "$COOLIFY_URL/project//environment//new" +) +``` + +Or navigate via UI: +1. Click "Projects" in sidebar +2. Click target project +3. Click target environment +4. Click "+ New" button + +### 4. Search for Service + +``` +mcp__claude-in-chrome__read_page(tabId, filter: "interactive") +# Find search textbox ref (usually "Type / to search...") +mcp__claude-in-chrome__computer(action: "left_click", ref: "ref_XX") +mcp__claude-in-chrome__computer(action: "type", text: "") +``` + +### 5. Select Service + +``` +mcp__claude-in-chrome__computer(action: "screenshot") +# Find service card in results +mcp__claude-in-chrome__computer(action: "left_click", coordinate: [x, y]) +``` + +### 6. Deploy + +``` +mcp__claude-in-chrome__computer(action: "screenshot") +# Click Deploy button (usually top right) +mcp__claude-in-chrome__computer(action: "left_click", coordinate: [1246, 115]) +``` + +### 7. Wait for Completion + +``` +mcp__claude-in-chrome__computer(action: "wait", duration: 5) +mcp__claude-in-chrome__computer(action: "screenshot") +# Check logs in Service Startup modal +# Close modal when complete +``` + +## Available AI Services + +| Service | Search Term | Components | +|---------|-------------|------------| +| Open WebUI | `ollama` or `openwebui` | open-webui | +| LiteLLM | `litellm` | litellm, postgres, redis | +| Flowise | `flowise` | flowise | +| Flowise With Databases | `flowise` (second option) | flowise, qdrant, postgres, redis | +| LibreChat | `librechat` | librechat, rag-api, meilisearch, mongodb, vectordb | +| SearXNG | `searxng` | searxng, redis | + +## Post-Deploy Configuration + +### Connect to Ollama + +For services needing Ollama access, add environment variable: +``` +OLLAMA_BASE_URL=http://host.docker.internal:11434 +``` + +### View Environment Variables + +1. Click service in breadcrumb +2. Click "Environment Variables" in left sidebar +3. **Use "Developer View"** for raw text editing +4. Save and restart if needed + +## Service Types + +### Databases +- `postgresql` - PostgreSQL 16 +- `mysql` - MySQL 8.0 +- `redis` - Redis 7 +- `mongodb` - MongoDB 8 +- `mariadb` - MariaDB 11 +- `clickhouse` - ClickHouse + +### One-Click Services (90+) +- `n8n` - Workflow automation +- `code-server` - VS Code in browser +- `uptime-kuma` - Uptime monitoring +- `grafana` - Dashboards +- `minio` - S3-compatible storage + +### Applications +- **Docker Image** - Deploy from any registry +- **Public Repository** - Deploy from public git +- **Private Repository** - Deploy with GitHub App or deploy key +- **Dockerfile** - Build from Dockerfile +- **Docker Compose** - Multi-container apps + +## Troubleshooting + +### Service Not Found +- Try alternative search terms +- Check "Filter by category" dropdown +- Some services like Langflow aren't in catalog - use Docker Image + +### Deployment Fails +- Check logs in Service Startup modal +- Verify server has enough resources +- Check for port conflicts + +### Container Unhealthy +- View container logs via "Logs" tab +- Check environment variables +- Verify dependent services are running diff --git a/.claude-plugin/commands/coolify-status.md b/.claude-plugin/commands/coolify-status.md new file mode 100644 index 0000000..56ad559 --- /dev/null +++ b/.claude-plugin/commands/coolify-status.md @@ -0,0 +1,142 @@ +--- +name: status +description: Check Coolify deployment status via browser or API +args: [project-or-service] +flags: + api: + description: Use API instead of browser automation + type: boolean + default: false + team: + description: Team to query (default Agentic) + type: string + default: Agentic +--- + +# Check Coolify Status + +Query deployment status for projects, services, and resources. + +## Usage + +```bash +/coolify:status # View all projects +/coolify:status "Software Staging" # View specific project +/coolify:status --api # Use API instead of browser +``` + +## Browser Automation (Preferred) + +### 1. Load Tools + +``` +ToolSearch: select:mcp__claude-in-chrome__tabs_context_mcp +ToolSearch: select:mcp__claude-in-chrome__computer +ToolSearch: select:mcp__claude-in-chrome__read_page +``` + +### 2. Navigate to Projects + +``` +# Default to localhost (local dev instance) +COOLIFY_URL="${COOLIFY_URL:-http://localhost:8000}" + +mcp__claude-in-chrome__tabs_context_mcp(createIfEmpty: true) +mcp__claude-in-chrome__navigate(tabId, url: "$COOLIFY_URL/projects") +``` + +### 3. Read Project List + +``` +mcp__claude-in-chrome__computer(action: "screenshot") +``` + +### 4. Check Specific Project + +1. Click project name +2. Click environment (usually "production") +3. View service cards with status indicators + +## Status Indicators + +| Indicator | Meaning | +|-----------|---------| +| 🟢 Green dot | Running (healthy) | +| 🔴 Red dot | Exited / Failed | +| 🟡 Yellow dot | Deploying / Starting | +| ⚪ Grey dot | Stopped | + +## View Service Details + +1. Click service card +2. Check tabs: + - **Configuration** - General settings + - **Logs** - Container output + - **Links** - Access URLs + +## API Method + +### List All Resources + +```bash +# Set Coolify URL and token +COOLIFY_URL="${COOLIFY_URL:-http://localhost:8000}" +TOKEN="your-api-token" + +# List servers +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/servers" | jq + +# List projects +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/projects" | jq + +# List services (one-click apps) +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/services" | jq + +# List applications +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/applications" | jq + +# List databases +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/databases" | jq +``` + +### Get Specific Resource + +```bash +# Get service by UUID +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/services/{uuid}" | jq + +# Get service logs +curl -s -H "Authorization: Bearer $TOKEN" "$COOLIFY_URL/api/v1/services/{uuid}/logs" | jq +``` + +## SSH Verification (Advanced) + +For direct container verification when API/UI insufficient: + +```bash +# SSH to Coolify server +ssh user@your-coolify-host + +# List all containers +docker ps --format 'table {{.Names}}\t{{.Status}}' +``` + +## Response Fields (API) + +| Field | Description | +|-------|-------------| +| `uuid` | Unique identifier | +| `name` | Resource name | +| `status` | running, stopped, deploying, failed | +| `fqdn` | Fully qualified domain name | +| `created_at` | Creation timestamp | +| `updated_at` | Last update timestamp | + +## Team Switching + +In browser, use team dropdown in top navigation: +1. Click current team name (e.g., "Agentic") +2. Select target team from dropdown +3. Resources will reload for selected team + +API tokens are team-scoped - each token only sees its team's resources. diff --git a/.claude-plugin/commands/issue-close.md b/.claude-plugin/commands/issue-close.md new file mode 100644 index 0000000..730383b --- /dev/null +++ b/.claude-plugin/commands/issue-close.md @@ -0,0 +1,11 @@ +--- +name: close +description: Close an issue with a commit +hooks: + PreToolUse: + - hooks: + - type: command + command: "${CLAUDE_PLUGIN_ROOT}/scripts/close.sh" +--- + +# Close an issue with a commit diff --git a/.claude-plugin/commands/issue-list.md b/.claude-plugin/commands/issue-list.md new file mode 100644 index 0000000..6a6846a --- /dev/null +++ b/.claude-plugin/commands/issue-list.md @@ -0,0 +1,11 @@ +--- +name: list +description: List open issues +hooks: + PreToolUse: + - hooks: + - type: command + command: "${CLAUDE_PLUGIN_ROOT}/scripts/list.sh" +--- + +# List open issues diff --git a/.claude-plugin/commands/issue-start.md b/.claude-plugin/commands/issue-start.md new file mode 100644 index 0000000..a2dcead --- /dev/null +++ b/.claude-plugin/commands/issue-start.md @@ -0,0 +1,11 @@ +--- +name: start +description: Start working on an issue +hooks: + PreToolUse: + - hooks: + - type: command + command: "${CLAUDE_PLUGIN_ROOT}/scripts/start.sh" +--- + +# Start working on an issue diff --git a/.claude-plugin/commands/issue-view.md b/.claude-plugin/commands/issue-view.md new file mode 100644 index 0000000..32e7a0b --- /dev/null +++ b/.claude-plugin/commands/issue-view.md @@ -0,0 +1,11 @@ +--- +name: view +description: View issue details +hooks: + PreToolUse: + - hooks: + - type: command + command: "${CLAUDE_PLUGIN_ROOT}/scripts/view.sh" +--- + +# View issue details diff --git a/.claude-plugin/plugin.json b/.claude-plugin/plugin.json index d549533..bd67564 100644 --- a/.claude-plugin/plugin.json +++ b/.claude-plugin/plugin.json @@ -6,64 +6,69 @@ "name": "Host UK", "email": "hello@host.uk.com" }, - "homepage": "https://forge.lthn.ai/core/go-devops", - "repository": { - "type": "git", - "url": "ssh://git@forge.lthn.ai:2223/core/go-devops.git" - }, "license": "EUPL-1.2", - "commands": { - "ci": { + "commands": [ + { + "name": "ci", "description": "Check CI status and manage workflows", - "source": "ci/commands/ci.md" + "file": "ci/commands/ci.md" }, - "ci:status": { + { + "name": "ci:status", "description": "Show CI status for current branch", - "source": "ci/commands/status.md" + "file": "ci/commands/status.md" }, - "ci:run": { + { + "name": "ci:run", "description": "Trigger a CI workflow run", - "source": "ci/commands/run.md" + "file": "ci/commands/run.md" }, - "ci:fix": { + { + "name": "ci:fix", "description": "Analyse and fix failing CI", - "source": "ci/commands/fix.md" + "file": "ci/commands/fix.md" }, - "ci:workflow": { + { + "name": "ci:workflow", "description": "Create or update GitHub Actions workflow", - "source": "ci/commands/workflow.md" + "file": "ci/commands/workflow.md" }, - "coolify:deploy": { + { + "name": "coolify:deploy", "description": "Deploy a service to Coolify via browser automation", - "source": "coolify/commands/deploy.md" + "file": "coolify/commands/deploy.md" }, - "coolify:status": { - "description": "Check Coolify deployment status via browser or API", - "source": "coolify/commands/status.md" + { + "name": "coolify:status", + "description": "Check Coolify deployment status", + "file": "coolify/commands/status.md" }, - "issue:list": { + { + "name": "issue:list", "description": "List open issues", - "source": "issue/commands/list.md" + "file": "issue/commands/list.md" }, - "issue:view": { + { + "name": "issue:view", "description": "View issue details", - "source": "issue/commands/view.md" + "file": "issue/commands/view.md" }, - "issue:start": { + { + "name": "issue:start", "description": "Start working on an issue", - "source": "issue/commands/start.md" + "file": "issue/commands/start.md" }, - "issue:close": { + { + "name": "issue:close", "description": "Close an issue with a commit", - "source": "issue/commands/close.md" + "file": "issue/commands/close.md" } - }, + ], "keywords": [ "devops", "ci", "coolify", "issue", - "deployment", - "host-uk" + "deployment" ] } diff --git a/CLAUDE.md b/CLAUDE.md index 3d957b2..4015262 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -1,6 +1,6 @@ -# CLAUDE.md — go-devops Agent Instructions +# CLAUDE.md -You are a dedicated domain expert for `forge.lthn.ai/core/go-devops`. Virgil (in core/go) orchestrates your work via TODO.md. Pick up tasks in phase order, mark `[x]` when done, commit and push. +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands @@ -11,55 +11,67 @@ go test -race ./... # Race detector go vet ./... # Static analysis ``` -## Local Dependencies +## Workspace Context -| Module | Local Path | Notes | -|--------|-----------|-------| -| `forge.lthn.ai/core/go` | `../go` | Framework (core.E, io.Medium, config, i18n, log) | +This module (`forge.lthn.ai/core/go-devops`) is part of a 57-module Go workspace rooted at `/Users/snider/Code/go.work`. The parent framework module `forge.lthn.ai/core/go` (at `../go`) provides core libraries: `core.E` errors, `io.Medium` filesystem abstraction, config, i18n, and logging. -## Key Interfaces +Most implementation code (ansible engine, build system, infra clients, release pipeline, devkit, SDK generators) lives in the parent framework. This repo contains CLI commands that wire those packages together, plus deployment integrations and infrastructure playbooks. -```go -// build/builders/ -type Builder interface { - Name() string - Detect(fs io.Medium, dir string) (bool, error) - Build(ctx context.Context, cfg *Config, targets []Target) ([]Artifact, error) -} +## Architecture -// release/publishers/ -type Publisher interface { - Name() string - Publish(ctx context.Context, release *Release, pubCfg PublisherConfig, relCfg ReleaseConfig, dryRun bool) error -} +### Package Layout -// container/ -type Hypervisor interface { - Name() string - Available() bool - Run(ctx context.Context, opts RunOptions) (*process.Handle, error) -} +- **`cmd/dev/`** — Multi-repo developer commands registered under `core dev`. The main CLI surface (~4,400 LOC across 21 files). +- **`cmd/deploy/`** — `core deploy servers` — Coolify PaaS server/app listing. +- **`cmd/docs/`** — `core docs sync` — Documentation sync across the multi-repo workspace. +- **`cmd/setup/`** — `core setup repo` — Generate `.core` configuration for a project. +- **`cmd/gitcmd/`** — Git helper commands. +- **`cmd/vanity-import/`** — Vanity import path server (the default build target in `.core/build.yaml`). +- **`cmd/community/`** — Community-related commands. +- **`deploy/coolify/`** — Coolify PaaS API HTTP client. +- **`deploy/python/`** — Embedded Python 3.13 runtime wrapper (adds ~50 MB to binary). +- **`snapshot/`** — `core.json` release manifest generation. +- **`playbooks/`** — Ansible YAML playbooks for production infrastructure (Galera, Redis). Executed by the native Go Ansible engine, not `ansible-playbook`. -// devops/sources/ -type ImageSource interface { - Name() string - Available() bool - Download(ctx context.Context, name, version string, progress func(downloaded, total int64)) (string, error) -} +### Key CLI Commands (`cmd/dev/`) -// build/signing/ -type Signer interface { - Name() string - Available() bool - Sign(filePath, keyID string) ([]byte, error) -} +| Command | Purpose | +|---------|---------| +| `core dev work` | Combined git status/commit/push workflow | +| `core dev commit` | Claude-assisted commit generation | +| `core dev push/pull` | Push/pull repos with pending changes | +| `core dev issues` | List open Forgejo issues | +| `core dev reviews` | List PRs needing review | +| `core dev ci` | Check CI/workflow status | +| `core dev impact` | Analyse dependency impact across workspace | +| `core dev vm` | Boot, stop, shell, serve dev environments | +| `core dev workflow` | List/sync CI workflows across repos | +| `core dev file-sync` | Safe file sync for AI agents | +| `core dev apply` | Apply safe changes (AI-friendly) | -// sdk/generators/ -type Generator interface { - Language() string - Generate(ctx context.Context, spec, outputDir string, config *Config) error -} -``` +### Extension Interfaces (in parent framework) + +All extensible subsystems follow a plugin/provider pattern with small interfaces: + +| Interface | Package | Implementations | +|-----------|---------|-----------------| +| `Builder` | `build/builders/` | Go, Wails, Docker, C++, LinuxKit, Taskfile | +| `Publisher` | `release/publishers/` | GitHub, Docker, Homebrew, npm, AUR, Scoop, Chocolatey, LinuxKit | +| `Signer` | `build/signing/` | macOS codesign, GPG, Windows signtool | +| `Hypervisor` | `container/` | QEMU (Linux), Hyperkit (macOS) | +| `ImageSource` | `devops/sources/` | GitHub Releases, S3/CDN | +| `Generator` | `sdk/generators/` | TypeScript, Python, Go, PHP | + +### Shared API Client Pattern + +`infra/client.go` (parent module) provides HTTP client abstraction with exponential backoff retry (3 retries, 100ms–5s), HTTP 429 rate-limit handling with Retry-After parsing, and configurable auth (Bearer, Basic, query params). Used by Hetzner Cloud/Robot, CloudNS, and Forgejo clients. + +### Build & Release Flow + +`core build` → auto-detects project type → produces artifacts in `dist/` +`core build release` → version detection → changelog generation → publish via configured publishers + +Configuration lives in `.core/build.yaml` (targets, ldflags) and `.core/release.yaml` (publishers, changelog filters). ## Coding Standards @@ -69,18 +81,16 @@ type Generator interface { - **Co-Author**: `Co-Authored-By: Virgil ` - **Licence**: EUPL-1.2 - **Imports**: stdlib → forge.lthn.ai → third-party, each group separated by blank line +- **Errors**: `core.E()` for contextual errors, or `fmt.Errorf("%w", err)` for wrapping ## Forge - **Repo**: `forge.lthn.ai/core/go-devops` - **Push via SSH**: `git push forge main` (remote: `ssh://git@forge.lthn.ai:2223/core/go-devops.git`) +- **Issues/PRs**: Managed via Forgejo SDK (`code.gitea.io/sdk/gitea`), not GitHub ## Documentation -- Architecture: `docs/architecture.md` -- Development guide: `docs/development.md` -- Project history: `docs/history.md` - -## Task Queue - -See `TODO.md` for prioritised work. +- Architecture deep-dive: `docs/architecture.md` +- Development guide & testing patterns: `docs/development.md` +- Project history & known limitations: `docs/history.md`