diff --git a/ai_enhancements.md b/ai_enhancements.md new file mode 100644 index 0000000000..e680164447 --- /dev/null +++ b/ai_enhancements.md @@ -0,0 +1,1328 @@ +# AI & Developer Experience Enhancements + +**Version:** 1.0 +**Date:** January 2026 +**Status:** Draft - Awaiting Review + +--- + +## Table of Contents + +1. [AI-Friendly API Improvements](#1-ai-friendly-api-improvements) +2. [AI-Powered Wiki System](#2-ai-powered-wiki-system) +3. [User Experience Improvements](#3-user-experience-improvements) +4. [Developer Tooling](#4-developer-tooling) +5. [Data Integrity & Optimization](#5-data-integrity--optimization) +6. [Implementation Phases](#6-implementation-phases) + +--- + +## 1. AI-Friendly API Improvements + +### Overview + +Modern AI assistants (Claude, GPT, etc.) need predictable, well-structured APIs to effectively interact with Gitea. These improvements make Gitea a first-class citizen for AI-assisted development workflows. + +### 1.1 Structured JSON Error Responses + +Current error responses are often plain text or inconsistently formatted. AI agents need structured errors to handle failures gracefully. + +#### Current Problem + +```json +// Current: Inconsistent +{"message": "Not found"} +{"error": "unauthorized"} +"Something went wrong" +``` + +#### Proposed Standard + +```json +{ + "error": { + "code": "REPO_NOT_FOUND", + "message": "Repository 'owner/repo' does not exist or you don't have access", + "status": 404, + "details": { + "owner": "acme", + "repo": "missing-repo", + "suggestion": "Did you mean 'acme/missing-repos'?" + }, + "documentation_url": "https://docs.gitea.com/api/errors#REPO_NOT_FOUND", + "request_id": "req_abc123xyz" + } +} +``` + +#### Error Code Categories + +| Prefix | Category | Examples | +|--------|----------|----------| +| `AUTH_` | Authentication | `AUTH_TOKEN_EXPIRED`, `AUTH_INVALID_SCOPE` | +| `PERM_` | Permissions | `PERM_REPO_READ_DENIED`, `PERM_ORG_ADMIN_REQUIRED` | +| `REPO_` | Repository | `REPO_NOT_FOUND`, `REPO_ARCHIVED`, `REPO_TRANSFER_PENDING` | +| `FILE_` | File operations | `FILE_TOO_LARGE`, `FILE_NOT_FOUND`, `FILE_CONFLICT` | +| `GIT_` | Git operations | `GIT_REF_NOT_FOUND`, `GIT_MERGE_CONFLICT` | +| `RATE_` | Rate limiting | `RATE_LIMIT_EXCEEDED`, `RATE_QUOTA_EXHAUSTED` | +| `VAL_` | Validation | `VAL_INVALID_NAME`, `VAL_MISSING_FIELD` | + +#### Implementation + +```go +// modules/structs/api_error.go +type APIError struct { + Code string `json:"code"` + Message string `json:"message"` + Status int `json:"status"` + Details map[string]any `json:"details,omitempty"` + DocumentationURL string `json:"documentation_url,omitempty"` + RequestID string `json:"request_id"` + Suggestions []string `json:"suggestions,omitempty"` +} + +// Usage +func (ctx *Context) APIError(code string, status int, details map[string]any) { + ctx.JSON(status, APIErrorResponse{ + Error: APIError{ + Code: code, + Message: errorMessages[code], + Status: status, + Details: details, + DocumentationURL: fmt.Sprintf("%s/api/errors#%s", setting.AppURL, code), + RequestID: ctx.RequestID(), + }, + }) +} +``` + +### 1.2 OpenAPI Schema & Scalar API Documentation + +Enhance the existing OpenAPI spec and replace Swagger UI with Scalar for a modern API documentation experience. + +#### Why Scalar over Swagger UI + +| Feature | Swagger UI | Scalar | +|---------|-----------|--------| +| UI Design | Dated, cluttered | Modern, clean | +| Dark Mode | Limited | Native support | +| Search | Basic | Full-text across endpoints | +| Try It | Yes | Yes, with better UX | +| Code Examples | Limited | Auto-generated for multiple languages | +| Performance | Heavier | Lighter, faster loading | +| Customization | Complex | Theme-friendly, CSS variables | +| AI-Friendly | Basic | Better structured for LLM consumption | + +#### Scalar Integration + +```go +// routers/api/v1/swagger.go +package v1 + +import ( + "code.gitea.io/gitea/modules/context" + "code.gitea.io/gitea/modules/setting" +) + +// RegisterScalarUI serves the Scalar API documentation UI +func RegisterScalarUI(m *web.Router) { + m.Get("/api/v1/docs", func(ctx *context.Context) { + ctx.HTML(200, tplScalar) + }) +} + +// Scalar HTML template +const tplScalar = ` + + + + {{AppName}} API Reference + + + + + + + + + +` +``` + +#### Self-Hosted Scalar (No CDN) + +```go +// For air-gapped installations, bundle Scalar assets +// assets/scalar/api-reference.min.js + +m.Get("/api/v1/docs/assets/*", func(ctx *context.Context) { + ctx.ServeFile(path.Join(setting.StaticRootPath, "assets/scalar", ctx.Params("*"))) +}) +``` + +#### OpenAPI Schema Improvements + +| Area | Enhancement | +|------|-------------| +| **Descriptions** | Detailed field descriptions with examples | +| **Examples** | Request/response examples for every endpoint | +| **Deprecation** | Clear deprecation notices with migration paths | +| **Schemas** | Reusable schema components with validation rules | +| **Tags** | Logical grouping with descriptions | +| **x-scalar-** | Scalar-specific extensions for enhanced docs | + +#### Example Enhancement + +```yaml +# Before +/repos/{owner}/{repo}/contents/{filepath}: + get: + summary: Get file contents + +# After +/repos/{owner}/{repo}/contents/{filepath}: + get: + operationId: getRepositoryContents + summary: Get file or directory contents + description: | + Retrieves the contents of a file or directory in a repository. + + For files, returns the content (base64 encoded if binary). + For directories, returns a list of entries. + + **Rate limit:** 5000 requests/hour (authenticated) + + **AI Usage Notes:** + - Use `ref` parameter for specific branches/commits + - Large files (>1MB) return download_url instead of content + - Check `type` field: "file", "dir", "symlink", "submodule" + parameters: + - name: filepath + description: | + Path to the file or directory. + Use empty string or "/" for repository root. + example: "src/main.go" + responses: + 200: + description: File or directory contents + content: + application/json: + schema: + oneOf: + - $ref: '#/components/schemas/ContentsResponse' + - type: array + items: + $ref: '#/components/schemas/ContentsResponse' + examples: + file: + summary: Single file + value: + type: file + name: main.go + path: src/main.go + size: 1234 + encoding: base64 + content: cGFja2FnZSBtYWluCg== + directory: + summary: Directory listing + value: + - type: file + name: main.go + path: src/main.go + - type: dir + name: utils + path: src/utils +``` + +### 1.3 Batch Operations Endpoints + +AI agents often need to perform multiple operations efficiently. Batch endpoints reduce API calls and improve performance. + +#### New Batch Endpoints + +``` +POST /api/v1/batch/files +POST /api/v1/batch/issues +POST /api/v1/batch/labels +POST /api/v1/batch/webhooks +GET /api/v1/batch/status/{batch_id} +``` + +#### Batch Files API + +```json +// POST /api/v1/repos/{owner}/{repo}/batch/files +{ + "branch": "main", + "message": "Update configuration files", + "operations": [ + { + "operation": "create", + "path": "config/app.yaml", + "content": "base64-encoded-content" + }, + { + "operation": "update", + "path": "README.md", + "content": "base64-encoded-content", + "sha": "abc123" // Required for updates + }, + { + "operation": "delete", + "path": "old-config.json", + "sha": "def456" + }, + { + "operation": "move", + "path": "docs/old-name.md", + "new_path": "docs/new-name.md" + } + ], + "author": { + "name": "AI Assistant", + "email": "ai@example.com" + } +} + +// Response +{ + "commit": { + "sha": "xyz789", + "message": "Update configuration files", + "url": "https://gitea.example.com/owner/repo/commit/xyz789" + }, + "results": [ + {"path": "config/app.yaml", "status": "created", "sha": "new-sha-1"}, + {"path": "README.md", "status": "updated", "sha": "new-sha-2"}, + {"path": "old-config.json", "status": "deleted"}, + {"path": "docs/new-name.md", "status": "moved", "sha": "new-sha-3"} + ] +} +``` + +#### Batch Issues API + +```json +// POST /api/v1/repos/{owner}/{repo}/batch/issues +{ + "operations": [ + { + "operation": "create", + "title": "Fix login bug", + "body": "Description...", + "labels": ["bug", "priority:high"] + }, + { + "operation": "update", + "issue": 123, + "state": "closed", + "labels": {"add": ["resolved"], "remove": ["in-progress"]} + }, + { + "operation": "comment", + "issue": 124, + "body": "This is being tracked in #123" + } + ] +} +``` + +### 1.4 Streaming Responses for Large Results + +For large queries (repo tree, search results, activity feeds), streaming prevents timeouts and allows incremental processing. + +#### Streaming Endpoints + +``` +GET /api/v1/repos/{owner}/{repo}/git/trees/{sha}?stream=true +GET /api/v1/repos/{owner}/{repo}/search?stream=true +GET /api/v1/repos/{owner}/{repo}/commits?stream=true +``` + +#### Response Format (NDJSON) + +```jsonl +{"type":"meta","total":15000,"estimated":true} +{"type":"item","data":{"path":"src/main.go","type":"file","sha":"abc123"}} +{"type":"item","data":{"path":"src/utils/","type":"dir","sha":"def456"}} +{"type":"item","data":{"path":"src/utils/helpers.go","type":"file","sha":"ghi789"}} +... +{"type":"done","count":15000,"truncated":false} +``` + +#### Server-Sent Events Alternative + +``` +GET /api/v1/repos/{owner}/{repo}/git/trees/{sha} +Accept: text/event-stream + +event: meta +data: {"total":15000} + +event: item +data: {"path":"src/main.go","type":"file"} + +event: item +data: {"path":"src/utils/","type":"dir"} + +event: done +data: {"count":15000} +``` + +### 1.5 AI Context Endpoints + +New endpoints specifically designed for AI assistants to quickly understand a repository. + +#### Repository Summary + +``` +GET /api/v1/repos/{owner}/{repo}/ai/summary +``` + +```json +{ + "overview": { + "name": "myproject", + "description": "A tool for doing X", + "primary_language": "Go", + "languages": {"Go": 75.5, "TypeScript": 20.3, "Shell": 4.2}, + "size_bytes": 15234567, + "file_count": 342, + "last_commit": "2026-01-08T10:30:00Z" + }, + "structure": { + "has_readme": true, + "has_license": true, + "license_type": "MIT", + "has_contributing": true, + "has_ci": true, + "ci_system": "gitea-actions", + "package_managers": ["go.mod", "package.json"], + "frameworks_detected": ["gin", "react"] + }, + "activity": { + "commits_last_30d": 47, + "contributors_last_30d": 5, + "open_issues": 12, + "open_prs": 3, + "stars": 234, + "forks": 45 + }, + "key_files": [ + {"path": "README.md", "description": "Project documentation"}, + {"path": "go.mod", "description": "Go module definition"}, + {"path": "Makefile", "description": "Build commands"}, + {"path": ".gitea/workflows/ci.yaml", "description": "CI pipeline"} + ], + "entry_points": [ + {"path": "cmd/server/main.go", "description": "Main application entry"}, + {"path": "cmd/cli/main.go", "description": "CLI tool entry"} + ] +} +``` + +#### Code Navigation Hints + +``` +GET /api/v1/repos/{owner}/{repo}/ai/navigation +``` + +```json +{ + "architecture": "monorepo", + "modules": [ + { + "name": "api", + "path": "services/api/", + "description": "REST API service", + "entry_point": "services/api/main.go", + "dependencies": ["database", "auth"] + }, + { + "name": "worker", + "path": "services/worker/", + "description": "Background job processor", + "entry_point": "services/worker/main.go" + } + ], + "common_patterns": { + "handlers": "services/*/handlers/*.go", + "models": "internal/models/*.go", + "tests": "**/*_test.go", + "configs": "configs/*.yaml" + }, + "important_files": [ + { + "path": "internal/config/config.go", + "reason": "Central configuration" + }, + { + "path": "internal/database/migrations/", + "reason": "Database schema history" + } + ] +} +``` + +--- + +## 2. AI-Powered Wiki System + +### Overview + +Enable AI assistants to automatically generate and maintain wiki documentation by analyzing the repository, while keeping humans in control through a review workflow. + +### 2.1 Wiki Generation from Repository + +AI can analyze the codebase and generate comprehensive wiki pages. + +#### Trigger Methods + +1. **Manual:** Repo admin requests wiki generation +2. **Scheduled:** Regenerate on release or milestone +3. **API:** External AI service calls generation endpoint + +#### Generation API + +``` +POST /api/v1/repos/{owner}/{repo}/wiki/ai/generate +``` + +```json +{ + "scope": "full", // full | incremental | section + "sections": [ + "architecture", + "api-reference", + "getting-started", + "contributing", + "configuration", + "deployment", + "troubleshooting" + ], + "options": { + "include_code_examples": true, + "include_diagrams": true, // Mermaid diagrams + "language": "en", + "detail_level": "comprehensive", // brief | standard | comprehensive + "source_refs": true // Link back to source files + }, + "ai_provider": "internal", // internal | openai | anthropic | custom + "review_required": true +} +``` + +#### Response + +```json +{ + "generation_id": "gen_abc123", + "status": "processing", + "estimated_pages": 15, + "webhook_url": "/api/v1/repos/{owner}/{repo}/wiki/ai/generations/gen_abc123", + "review_url": "https://gitea.example.com/owner/repo/wiki/_review/gen_abc123" +} +``` + +### 2.2 Generated Wiki Structure + +``` +wiki/ +├── Home.md # Auto-generated overview +├── Architecture.md # System design, components +├── Getting-Started/ +│ ├── Installation.md +│ ├── Quick-Start.md +│ └── Configuration.md +├── API-Reference/ +│ ├── Overview.md +│ ├── Authentication.md +│ └── Endpoints/ +│ ├── Users.md +│ └── Projects.md +├── Development/ +│ ├── Setup.md +│ ├── Testing.md +│ └── Contributing.md +├── Deployment/ +│ ├── Docker.md +│ ├── Kubernetes.md +│ └── Configuration.md +└── Troubleshooting.md +``` + +### 2.3 Wiki Review Workflow + +All AI-generated content goes through human review before publishing. + +#### States + +``` +┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐ +│ Draft │────►│ Review │────►│ Approved │────►│ Published │ +│(AI Gen) │ │ (Human) │ │ │ │ │ +└───────────┘ └─────┬─────┘ └───────────┘ └───────────┘ + │ + ▼ + ┌───────────┐ + │ Rejected │──► Edit ──► Back to Review + └───────────┘ +``` + +#### Review UI + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ 📝 Wiki Review: Architecture.md [AI Generated] │ +│ │ +│ Generated: Jan 8, 2026 10:30 AM │ +│ Confidence: 87% │ +│ Sources: 15 files analyzed │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────┬─────────────────────────────────────┐ │ +│ │ AI Generated │ Your Edits │ │ +│ │ │ │ │ +│ │ # Architecture │ # Architecture │ │ +│ │ │ │ │ +│ │ MyProject uses a │ MyProject uses a │ │ +│ │ microservices arch... │ microservices arch... │ │ +│ │ │ │ │ +│ │ ## Components │ ## Core Components │ │ ← Edit +│ │ │ │ │ +│ │ - API Server │ - API Server (Go/Gin) │ │ ← Enhanced +│ │ - Worker │ - Background Worker │ │ +│ │ - Database │ - PostgreSQL Database │ │ +│ │ │ │ │ +│ └─────────────────────────┴─────────────────────────────────────┘ │ +│ │ +│ 📎 Source References: │ +│ • cmd/server/main.go:15-45 │ +│ • internal/config/config.go │ +│ • docker-compose.yaml │ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐│ +│ │ 💬 Review Comments ││ +│ │ ││ +│ │ @alice: "Component section needs more detail about the worker" ││ +│ │ @bob: "LGTM after Alice's feedback addressed" ││ +│ └─────────────────────────────────────────────────────────────────┘│ +│ │ +│ [✓ Approve & Publish] [✏️ Request Changes] [❌ Reject] [💾 Save]│ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 2.4 Wiki Improvement Suggestions + +AI can continuously analyze wiki pages and suggest improvements. + +#### Suggestion Types + +| Type | Description | Example | +|------|-------------|---------| +| `outdated` | Content doesn't match current code | "Function `doThing()` was renamed to `performAction()`" | +| `incomplete` | Missing documentation | "New endpoint `/api/v1/users/search` is undocumented" | +| `broken_link` | Dead internal/external links | "Link to `#configuration` section doesn't exist" | +| `clarity` | Confusing or unclear content | "This section could be clearer with a code example" | +| `structure` | Organization improvements | "Consider splitting this into multiple pages" | +| `coverage` | Missing topics | "No documentation for error handling patterns" | + +#### Suggestions API + +``` +GET /api/v1/repos/{owner}/{repo}/wiki/ai/suggestions +``` + +```json +{ + "suggestions": [ + { + "id": "sug_001", + "type": "outdated", + "severity": "high", + "page": "API-Reference/Authentication.md", + "line": 45, + "current_text": "Use the `/api/v1/auth/login` endpoint", + "issue": "Endpoint was changed to `/api/v1/users/tokens`", + "suggested_text": "Use the `/api/v1/users/tokens` endpoint to create access tokens", + "evidence": { + "source_file": "routers/api/v1/user/token.go", + "commit": "abc123", + "date": "2026-01-05" + }, + "confidence": 0.95 + }, + { + "id": "sug_002", + "type": "incomplete", + "severity": "medium", + "page": null, + "issue": "New feature 'Webhooks' has no wiki documentation", + "suggested_action": "Generate new page: Webhooks.md", + "evidence": { + "source_files": [ + "routers/api/v1/repo/webhook.go", + "models/webhook.go" + ], + "feature_commits": ["def456", "ghi789"] + }, + "confidence": 0.88 + }, + { + "id": "sug_003", + "type": "clarity", + "severity": "low", + "page": "Getting-Started/Installation.md", + "line": 12, + "current_text": "Run the setup script", + "issue": "Missing information about prerequisites", + "suggested_text": "Before running the setup script, ensure you have:\n- Go 1.21+\n- PostgreSQL 14+\n- Node.js 18+\n\nThen run the setup script:", + "confidence": 0.72 + } + ], + "summary": { + "total": 15, + "by_severity": {"high": 2, "medium": 8, "low": 5}, + "by_type": {"outdated": 3, "incomplete": 5, "clarity": 4, "broken_link": 2, "coverage": 1} + }, + "last_analysis": "2026-01-08T10:00:00Z", + "next_analysis": "2026-01-09T10:00:00Z" +} +``` + +#### Apply Suggestion + +``` +POST /api/v1/repos/{owner}/{repo}/wiki/ai/suggestions/{id}/apply +``` + +```json +{ + "action": "apply", // apply | dismiss | edit_and_apply + "edited_text": "Optional: manually edited version", + "review_required": true +} +``` + +### 2.5 Wiki Sync with Code + +Keep documentation in sync with code changes. + +#### Sync Configuration + +```yaml +# .gitea/wiki-sync.yaml +sync: + enabled: true + trigger: + - on_release + - on_milestone_close + - weekly + + watch_paths: + - "routers/api/**" # API changes + - "models/**" # Data model changes + - "docs/**" # Inline documentation + - "*.md" # Root markdown files + + notifications: + - type: issue + title: "Wiki Update Required" + assignees: ["docs-team"] + + - type: webhook + url: "https://example.com/wiki-updates" +``` + +#### Sync Status + +``` +GET /api/v1/repos/{owner}/{repo}/wiki/ai/sync/status +``` + +```json +{ + "last_sync": "2026-01-07T15:00:00Z", + "last_code_change": "2026-01-08T09:30:00Z", + "status": "outdated", + "drift_score": 0.15, // 0 = fully synced, 1 = completely outdated + "changed_areas": [ + { + "code_path": "routers/api/v1/repo/release.go", + "wiki_page": "API-Reference/Releases.md", + "change_type": "api_signature_changed", + "details": "New parameter 'prerelease' added to create endpoint" + } + ], + "pending_updates": 3 +} +``` + +--- + +## 3. User Experience Improvements + +### 3.1 Progress Reporting for Long Operations + +Real-time progress for uploads, clones, and other long-running operations. + +#### Progress API + +``` +GET /api/v1/operations/{operation_id}/progress +Accept: text/event-stream +``` + +``` +event: progress +data: {"phase":"uploading","current":52428800,"total":104857600,"percent":50,"speed_bps":5242880,"eta_seconds":10} + +event: progress +data: {"phase":"uploading","current":78643200,"total":104857600,"percent":75,"speed_bps":5500000,"eta_seconds":5} + +event: progress +data: {"phase":"processing","message":"Verifying checksums..."} + +event: complete +data: {"status":"success","result":{"id":123,"name":"release.zip"}} +``` + +#### Progress Response Schema + +```json +{ + "operation_id": "op_abc123", + "type": "chunked_upload", + "status": "in_progress", + "phases": [ + {"name": "uploading", "status": "complete", "progress": 100}, + {"name": "assembling", "status": "in_progress", "progress": 45}, + {"name": "verifying", "status": "pending", "progress": 0} + ], + "current": { + "phase": "assembling", + "progress": 45, + "message": "Assembling chunks 23/50", + "bytes_processed": 241172480, + "bytes_total": 524288000 + }, + "timing": { + "started_at": "2026-01-08T10:30:00Z", + "elapsed_seconds": 45, + "estimated_remaining_seconds": 55 + } +} +``` + +### 3.2 Webhook Notifications + +Webhook events for upload and long operation completion. + +#### New Webhook Events + +```json +{ + "event": "upload_complete", + "payload": { + "type": "release_attachment", + "release": { + "id": 123, + "tag_name": "v1.0.0" + }, + "attachment": { + "id": 456, + "name": "myapp-v1.0.0.zip", + "size": 524288000, + "download_url": "https://..." + }, + "upload_method": "chunked", + "duration_seconds": 120, + "uploader": { + "id": 1, + "login": "developer" + } + } +} +``` + +```json +{ + "event": "wiki_updated", + "payload": { + "action": "ai_generated", + "pages_affected": ["Architecture.md", "API-Reference.md"], + "generation_id": "gen_abc123", + "status": "pending_review", + "review_url": "https://..." + } +} +``` + +### 3.3 Web UI for Chunked Uploads + +Browser-based chunked upload with pause/resume capability. + +#### UI Features + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ Upload Release Assets │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────────────────────────────────────────────────────┐│ +│ │ ┌─────┐ ││ +│ │ │ │ Drop files here or click to browse ││ +│ │ │ + │ ││ +│ │ │ │ Maximum file size: 2GB ││ +│ │ └─────┘ ││ +│ └─────────────────────────────────────────────────────────────────┘│ +│ │ +│ Uploading: │ +│ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ 📦 myapp-linux-amd64.tar.gz 245 MB / 500 MB│ │ +│ │ ████████████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 49% │ │ +│ │ Speed: 5.2 MB/s • ETA: 49 seconds [⏸ Pause] │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ 📦 myapp-darwin-arm64.tar.gz ⏸️ │ │ +│ │ ████████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 25% │ │ +│ │ Paused • 125 MB uploaded [▶ Resume] │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ ┌──────────────────────────────────────────────────────────────┐ │ +│ │ ✅ myapp-windows-amd64.zip Done! │ │ +│ │ 450 MB • Uploaded in 1m 32s │ │ +│ └──────────────────────────────────────────────────────────────┘ │ +│ │ +│ ⚠️ Uploads will resume automatically if you close this page │ +│ and return within 24 hours. │ +│ │ +│ [Cancel All] [Upload More] │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +#### LocalStorage Persistence + +```javascript +// Persist upload state for resume +const uploadState = { + sessionId: "sess_abc123", + fileName: "myapp.tar.gz", + fileSize: 524288000, + chunkSize: 10485760, + completedChunks: [0, 1, 2, 3, 4, 5], + fileHash: "sha256:abc123...", // For integrity verification + expiresAt: 1704931200 +}; +localStorage.setItem(`upload_${sessionId}`, JSON.stringify(uploadState)); +``` + +--- + +## 4. Developer Tooling + +### 4.1 CLI Tool for Chunked Uploads + +A dedicated CLI tool for reliable large file uploads. + +#### Installation + +```bash +# Via go install +go install code.gitea.io/gitea-cli@latest + +# Via package managers +brew install gitea-cli +apt install gitea-cli +``` + +#### Usage + +```bash +# Basic upload +gitea-cli upload release-asset \ + --repo owner/repo \ + --release v1.0.0 \ + --file ./dist/app.tar.gz + +# With options +gitea-cli upload release-asset \ + --repo owner/repo \ + --release v1.0.0 \ + --file ./dist/app.tar.gz \ + --chunk-size 50MB \ + --parallel 4 \ + --verify-checksum \ + --progress + +# Resume interrupted upload +gitea-cli upload resume --session sess_abc123 + +# List pending uploads +gitea-cli upload list --repo owner/repo +``` + +#### Output + +``` +Uploading app-v1.0.0.tar.gz (524 MB) +Creating upload session... done (sess_abc123) +Uploading chunks (4 parallel workers): + + [████████████████████████████████████████████] 100% + + Chunks: 50/50 complete + Speed: 8.5 MB/s (avg) + Time: 1m 02s + +Finalizing... done +Verifying checksum... ✓ SHA256 matches + +✅ Upload complete! + Asset ID: 456 + Download: https://gitea.example.com/attachments/xyz789 +``` + +### 4.2 SDK Client Libraries + +Official SDK support for popular languages. + +#### Go SDK + +```go +import "code.gitea.io/sdk/gitea" + +client, _ := gitea.NewClient("https://gitea.example.com", + gitea.SetToken("your_token")) + +// Chunked upload +upload, _ := client.CreateChunkedUpload(ctx, "owner", "repo", 123, + gitea.ChunkedUploadOptions{ + FileName: "app.tar.gz", + ChunkSize: 10 * 1024 * 1024, + }) + +file, _ := os.Open("app.tar.gz") +result, _ := upload.Upload(ctx, file, + gitea.WithProgress(func(p gitea.Progress) { + fmt.Printf("\r%d%%", p.Percent) + }), + gitea.WithParallel(4)) +``` + +#### Python SDK + +```python +from gitea import GiteaClient, ChunkedUpload + +client = GiteaClient("https://gitea.example.com", token="your_token") + +# Chunked upload with progress +with open("app.tar.gz", "rb") as f: + result = client.upload_release_asset( + owner="myorg", + repo="myrepo", + release_id=123, + file=f, + filename="app.tar.gz", + chunk_size=10*1024*1024, + parallel=4, + progress_callback=lambda p: print(f"{p.percent}%") + ) + +print(f"Uploaded: {result.browser_download_url}") +``` + +#### JavaScript/TypeScript SDK + +```typescript +import { GiteaClient } from '@gitea/sdk'; + +const client = new GiteaClient({ + baseUrl: 'https://gitea.example.com', + token: 'your_token' +}); + +// Chunked upload with progress +const file = new File([...], 'app.tar.gz'); +const result = await client.releases.uploadAssetChunked({ + owner: 'myorg', + repo: 'myrepo', + releaseId: 123, + file, + chunkSize: 10 * 1024 * 1024, + parallel: 4, + onProgress: (progress) => { + console.log(`${progress.percent}%`); + } +}); +``` + +--- + +## 5. Data Integrity & Optimization + +### 5.1 Checksum Verification + +End-to-end integrity verification using SHA256. + +#### Client-Side + +```bash +# Calculate before upload +SHA256=$(sha256sum app.tar.gz | cut -d' ' -f1) + +# Include in upload session creation +curl -X POST ".../upload-session?name=app.tar.gz&size=524288000&sha256=$SHA256" +``` + +#### Server Verification + +```json +// Create session with checksum +POST /api/v1/repos/{owner}/{repo}/releases/{id}/assets/upload-session +{ + "name": "app.tar.gz", + "size": 524288000, + "checksum": { + "algorithm": "sha256", + "value": "abc123def456..." + } +} + +// Complete response includes verification +POST /api/v1/repos/{owner}/{repo}/uploads/{session}/complete +{ + "id": 456, + "name": "app.tar.gz", + "size": 524288000, + "checksum_verified": true, + "checksum": { + "algorithm": "sha256", + "value": "abc123def456..." + } +} +``` + +### 5.2 Compression Support + +Optional server-side compression for text-based files. + +#### Request Compression + +``` +PUT /api/v1/repos/{owner}/{repo}/uploads/{session}/chunks/0 +Content-Encoding: gzip +X-Original-Size: 10485760 + +[gzip-compressed chunk data] +``` + +#### Response + +```json +{ + "chunk_number": 0, + "received_size": 3145728, // Compressed size + "original_size": 10485760, // Uncompressed size + "compression_ratio": 0.30 +} +``` + +### 5.3 Deduplication + +Detect and reuse identical chunks across uploads. + +#### How It Works + +1. Client sends chunk hash before upload +2. Server checks if chunk exists in storage +3. If exists, skip upload and reference existing chunk +4. Reduces storage and upload time for similar files + +#### API + +```json +// Check if chunks exist +POST /api/v1/repos/{owner}/{repo}/uploads/{session}/chunks/check +{ + "chunks": [ + {"number": 0, "sha256": "abc123..."}, + {"number": 1, "sha256": "def456..."}, + {"number": 2, "sha256": "ghi789..."} + ] +} + +// Response +{ + "existing": [ + {"number": 0, "sha256": "abc123...", "exists": true}, + {"number": 1, "sha256": "def456...", "exists": false}, + {"number": 2, "sha256": "ghi789...", "exists": true} + ], + "upload_required": [1], + "bytes_saved": 20971520 +} +``` + +--- + +## 6. Implementation Phases + +### Phase 1: API Foundation (4-5 weeks) + +1. **Week 1-2:** Structured error responses + - Define error code taxonomy + - Implement APIError type + - Migrate existing endpoints + +2. **Week 2-3:** OpenAPI improvements + - Add detailed descriptions + - Add request/response examples + - Generate improved client SDKs + +3. **Week 3-4:** Batch operations + - Batch files endpoint + - Batch issues endpoint + - Transaction handling + +4. **Week 4-5:** AI context endpoints + - Repository summary + - Navigation hints + +### Phase 2: Wiki AI System (6-8 weeks) + +1. **Week 1-2:** Wiki generation infrastructure + - Generation queue and workers + - Template system for different page types + - Source code analysis integration + +2. **Week 3-4:** Review workflow + - Review UI components + - State machine for page lifecycle + - Diff viewer for AI vs human edits + +3. **Week 5-6:** Suggestions system + - Outdated content detection + - Missing documentation detection + - Suggestion management API + +4. **Week 7-8:** Code sync + - Watch path configuration + - Drift detection algorithm + - Notification system + +### Phase 3: User Experience (3-4 weeks) + +1. **Week 1:** Progress reporting + - SSE endpoint implementation + - Progress aggregation for multi-step operations + +2. **Week 2:** Webhooks + - New event types + - Payload schemas + - Delivery reliability + +3. **Week 3-4:** Web UI uploads + - Drag-and-drop component + - Progress visualization + - Pause/resume functionality + - LocalStorage persistence + +### Phase 4: Developer Tools (3-4 weeks) + +1. **Week 1-2:** CLI tool + - Upload command implementation + - Progress display + - Resume functionality + +2. **Week 3-4:** SDK libraries + - Go SDK updates + - Python SDK + - JavaScript/TypeScript SDK + +### Phase 5: Data Integrity (2-3 weeks) + +1. **Week 1:** Checksum verification + - SHA256 calculation + - Verification flow + - Error handling for mismatches + +2. **Week 2:** Compression + - Gzip support + - Content-Encoding handling + - Size tracking + +3. **Week 3:** Deduplication + - Chunk hash storage + - Lookup optimization + - Storage savings reporting + +--- + +## Appendix A: Error Code Reference + +### Authentication Errors (AUTH_) + +| Code | Status | Description | +|------|--------|-------------| +| `AUTH_TOKEN_MISSING` | 401 | No authentication token provided | +| `AUTH_TOKEN_INVALID` | 401 | Token is malformed or invalid | +| `AUTH_TOKEN_EXPIRED` | 401 | Token has expired | +| `AUTH_SCOPE_INSUFFICIENT` | 403 | Token lacks required scope | +| `AUTH_2FA_REQUIRED` | 401 | Two-factor authentication required | + +### Permission Errors (PERM_) + +| Code | Status | Description | +|------|--------|-------------| +| `PERM_REPO_READ_DENIED` | 403 | Cannot read repository | +| `PERM_REPO_WRITE_DENIED` | 403 | Cannot write to repository | +| `PERM_REPO_ADMIN_REQUIRED` | 403 | Repository admin access required | +| `PERM_ORG_MEMBER_REQUIRED` | 403 | Must be organization member | + +### Repository Errors (REPO_) + +| Code | Status | Description | +|------|--------|-------------| +| `REPO_NOT_FOUND` | 404 | Repository does not exist | +| `REPO_ARCHIVED` | 403 | Repository is archived | +| `REPO_DISABLED` | 403 | Repository is disabled | +| `REPO_TRANSFER_PENDING` | 409 | Repository has pending transfer | + +### File Errors (FILE_) + +| Code | Status | Description | +|------|--------|-------------| +| `FILE_NOT_FOUND` | 404 | File does not exist | +| `FILE_TOO_LARGE` | 413 | File exceeds size limit | +| `FILE_CONFLICT` | 409 | File was modified (SHA mismatch) | +| `FILE_BINARY` | 400 | Cannot perform text operation on binary file | + +### Upload Errors (UPLOAD_) + +| Code | Status | Description | +|------|--------|-------------| +| `UPLOAD_SESSION_NOT_FOUND` | 404 | Upload session does not exist | +| `UPLOAD_SESSION_EXPIRED` | 410 | Upload session has expired | +| `UPLOAD_CHUNK_INVALID` | 400 | Chunk number out of range | +| `UPLOAD_CHUNK_SIZE_MISMATCH` | 400 | Chunk size doesn't match expected | +| `UPLOAD_CHECKSUM_MISMATCH` | 400 | File checksum verification failed | +| `UPLOAD_INCOMPLETE` | 400 | Not all chunks have been uploaded | + +--- + +*End of Specification* diff --git a/enhancements.md b/enhancements.md new file mode 100644 index 0000000000..23233c40b9 --- /dev/null +++ b/enhancements.md @@ -0,0 +1,983 @@ +# Feature Enhancements Specification + +**Version:** 1.0 +**Date:** January 2026 +**Status:** Approved for Development + +--- + +## Table of Contents + +1. [Organization Public Profile Page](#1-organization-public-profile-page) +2. [Repository Landing Pages (Gitea Pages)](#2-repository-landing-pages-gitea-pages) +3. [Database Schema Changes](#3-database-schema-changes) +4. [API Endpoints](#4-api-endpoints) +5. [Implementation Phases](#5-implementation-phases) + +--- + +## 1. Organization Public Profile Page + +### Overview + +A new **Overview** tab becomes the default landing page for organizations, replacing the Repositories tab as the first view. This page showcases the organization's identity, featured projects, and public members. + +### Tab Structure + +``` +[Overview] [Repositories] [Projects] [Packages] [People] [Settings] + ↑ + DEFAULT +``` + +### 1.1 Pinned Repositories + +Organizations can pin and group unlimited repositories to highlight on their profile. + +#### Features + +| Feature | Specification | +|---------|---------------| +| **Count** | Unlimited pinned repos | +| **Grouping** | Repos can be organized into named groups | +| **Ordering** | Drag-and-drop reordering within groups | +| **Metadata Displayed** | Stars, forks, primary language badge, description | + +#### Data Model + +```go +// models/organization/pinned_repo.go +type OrgPinnedRepo struct { + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"INDEX NOT NULL"` + RepoID int64 `xorm:"INDEX NOT NULL"` + GroupName string `xorm:"DEFAULT ''"` // Empty = ungrouped + DisplayOrder int `xorm:"DEFAULT 0"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` +} + +type OrgPinnedGroup struct { + ID int64 `xorm:"pk autoincr"` + OrgID int64 `xorm:"INDEX NOT NULL"` + Name string `xorm:"NOT NULL"` + DisplayOrder int `xorm:"DEFAULT 0"` + Collapsed bool `xorm:"DEFAULT false"` // Allow collapsible groups +} +``` + +#### UI Layout + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ 📌 Featured Projects │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ▼ Core Products │ +│ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ +│ │ [icon] │ │ [icon] │ │ [icon] │ │ +│ │ main-app │ │ api-server │ │ web-client │ │ +│ │ ⭐ 2.1k 🍴 432│ │ ⭐ 1.8k 🍴 289│ │ ⭐ 956 🍴 178 │ │ +│ │ ● TypeScript │ │ ● Go │ │ ● React │ │ +│ │ "Our flagship │ │ "Backend API │ │ "Frontend │ │ +│ │ application" │ │ services" │ │ application" │ │ +│ └───────────────┘ └───────────────┘ └───────────────┘ │ +│ │ +│ ▼ Libraries & Tools │ +│ ┌───────────────┐ ┌───────────────┐ │ +│ │ [icon] │ │ [icon] │ │ +│ │ shared-utils │ │ cli-tool │ │ +│ │ ⭐ 445 🍴 67 │ │ ⭐ 312 🍴 45 │ │ +│ │ ● TypeScript │ │ ● Rust │ │ +│ └───────────────┘ └───────────────┘ │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 1.2 Public Members Display + +Members can opt-in to be displayed publicly on the organization profile. + +#### Features + +| Feature | Specification | +|---------|---------------| +| **Visibility** | Member chooses to be displayed (opt-in) | +| **Roles Shown** | Owner, Admin, Member | +| **Overflow** | "and X more" with link to People tab | +| **Layout** | Avatar grid with username and role | + +#### Data Model + +```go +// Add to existing OrgUser model +type OrgUser struct { + // ... existing fields + IsPublic bool `xorm:"DEFAULT false"` // Member opts in to public display +} +``` + +#### UI Layout + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ 👥 Public Members [View All →]│ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ ┌─────┐ │ +│ │ 👤 │ │ 👤 │ │ 👤 │ │ 👤 │ │ 👤 │ │ 👤 │ ... and 18 more │ +│ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ └─────┘ │ +│ @alice @bob @carol @david @emma @frank │ +│ Owner Admin Admin Member Member Member │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 1.3 Promotional Region / About Section + +Organizations can create a rich profile page with custom content. + +#### Storage + +Content is stored in a **private repository** within the organization: + +``` +Repository: {org}/.profile (private) +Files: + - README.md # Main profile content (Markdown) + - assets/ # Images, videos, badges + - logo.png + - banner.jpg + - team-photo.jpg + - style.css # Optional custom CSS (sandboxed) +``` + +#### Features + +| Feature | Specification | +|---------|---------------| +| **Content Format** | Markdown (README.md) | +| **Editor** | Markdown editor + optional WYSIWYG toggle | +| **Media** | Images, videos, badges stored in `.profile` repo | +| **Custom CSS** | Allowed within sandboxed constraints | +| **Version Control** | Full Git history via `.profile` repo | + +#### Content Capabilities + +```markdown +# Allowed in README.md: + +## Standard Markdown +- Headers, lists, links, code blocks +- Tables, blockquotes +- Task lists + +## Extended Features +- ![Images](./assets/logo.png) +- ![Badges](https://img.shields.io/badge/...) +- Embedded videos (iframe allowlist: YouTube, Vimeo) +- HTML subset (safe tags only) + +## Organization-specific +- {{MEMBER_COUNT}} - Dynamic member count +- {{REPO_COUNT}} - Dynamic repo count +- {{PINNED_REPOS}} - Renders pinned repos widget +``` + +#### CSS Sandboxing + +```css +/* style.css - Allowed properties */ +.profile-content { + /* Typography */ + font-family: ...; /* From approved list */ + font-size: ...; + color: ...; + + /* Layout */ + margin: ...; + padding: ...; + + /* Backgrounds */ + background-color: ...; + background-image: url('./assets/...'); /* Local only */ + + /* Borders */ + border: ...; + border-radius: ...; +} + +/* Blocked: position:fixed, z-index manipulation, external URLs, + animations (except approved), JavaScript injection */ +``` + +#### UI Layout + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ ┌────────────┐ │ +│ │ │ Acme Corporation │ +│ │ [LOGO] │ ━━━━━━━━━━━━━━━━ │ +│ │ │ "Building the future, one commit at a time" │ +│ └────────────┘ │ +│ │ +│ 🌐 acme.com 📍 San Francisco, CA 📧 hello@acme.com │ +│ 🐦 @acmecorp 💼 500+ employees │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ## About Us │ +│ │ +│ We are a team of passionate developers building open source │ +│ tools that empower developers worldwide. Founded in 2015, │ +│ we've grown to become a leader in developer productivity. │ +│ │ +│ ### What We Do │ +│ │ +│ 🚀 **Developer Tools** - IDE plugins, CLI utilities │ +│ 🔧 **Infrastructure** - Deployment, monitoring, scaling │ +│ 📚 **Education** - Tutorials, documentation, courses │ +│ │ +│ ┌──────────────────────────────────────────────────────┐ │ +│ │ [TEAM PHOTO] │ │ +│ │ │ │ +│ └──────────────────────────────────────────────────────┘ │ +│ │ +│ ### Join Us │ +│ We're always looking for talented people! Check out our │ +│ [careers page](https://acme.com/careers). │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 2. Repository Landing Pages (Gitea Pages) + +### Overview + +Repository owners can create a **standalone landing page** that acts as a public-facing project website. This page is independent of the repository's visibility—a private repo can have a public landing page. + +### Key Characteristics + +| Aspect | Specification | +|--------|---------------| +| **Independence** | Landing page visibility separate from repo visibility | +| **Domain** | Custom domain OR auto-generated subdomain | +| **SSL/TLS** | Automatic via Let's Encrypt | +| **Templates** | 4 built-in templates, switchable without data loss | +| **Configuration** | `.gitea/landing.yaml` (precedence) + DB fallback | + +### 2.1 Domain Mapping + +#### Option 1: Auto-Generated Subdomain + +``` +Format: {repo}.{owner}.pages.{gitea-domain} +Example: myproject.acme.pages.gitea.example.com +``` + +- Automatically available when landing page is enabled +- No DNS configuration required +- SSL certificate auto-provisioned + +#### Option 2: Custom Domain + +``` +User Configuration: +1. Add CNAME record: myproject.com → pages.gitea.example.com +2. Configure domain in repo settings +3. SSL certificate auto-provisioned via Let's Encrypt +``` + +#### DNS Verification + +```go +// Verify domain ownership before enabling +type PagesDomain struct { + ID int64 `xorm:"pk autoincr"` + RepoID int64 `xorm:"INDEX NOT NULL"` + Domain string `xorm:"UNIQUE NOT NULL"` + Verified bool `xorm:"DEFAULT false"` + VerificationTXT string // TXT record for verification + SSLCertID string // Reference to cert storage + CreatedUnix timeutil.TimeStamp + VerifiedUnix timeutil.TimeStamp +} +``` + +### 2.2 Templates + +Four built-in templates with consistent configuration: + +#### Template 1: Simple + +Clean, minimal design focused on the README. + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ │ +│ [PROJECT LOGO] │ +│ │ +│ MyProject │ +│ "A better way to do things" │ +│ │ +│ [⬇️ Download v2.1.0] [📖 View Docs] │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ # MyProject │ +│ │ +│ MyProject is a tool that helps you accomplish X faster and │ +│ more reliably than ever before. │ +│ │ +│ ## Installation │ +│ ```bash │ +│ npm install myproject │ +│ ``` │ +│ │ +│ ## Quick Start │ +│ ... │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ ⭐ 2,341 stars │ 🍴 456 forks │ 📝 MIT License │ v2.1.0 │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +#### Template 2: Documentation + +Sidebar navigation with documentation pages from `/docs` folder. + +``` +┌──────────────┬──────────────────────────────────────────────────────┐ +│ │ │ +│ [Logo] │ Getting Started │ +│ MyProject │ ══════════════════════════════════════════════════ │ +│ │ │ +│ 🔍 Search │ Welcome to MyProject! This guide will walk you │ +│ │ through installation and basic usage. │ +│ ────────── │ │ +│ │ ## Prerequisites │ +│ 📖 DOCS │ │ +│ Getting │ Before you begin, ensure you have: │ +│ Started ● │ - Node.js 18+ │ +│ Install │ - npm or yarn │ +│ Config │ │ +│ Usage │ ## Installation │ +│ │ │ +│ 📚 API │ ```bash │ +│ Overview │ npm install -g myproject │ +│ Reference │ ``` │ +│ Examples │ │ +│ │ ## Verify Installation │ +│ ────────── │ │ +│ 📦 v2.1.0 │ ```bash │ +│ ⭐ 2,341 │ myproject --version │ +│ │ ``` │ +│ [GitHub] │ │ +│ [Discord] │ [Next: Configuration →] │ +│ │ │ +└──────────────┴──────────────────────────────────────────────────────┘ +``` + +#### Template 3: Product + +Marketing-style landing page with features, screenshots, and CTAs. + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░ [HERO BACKGROUND] ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░ MyProject ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░ "Ship faster with confidence" ░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░ [Get Started] [View Source] ░░░░░░░░░░░░░░░░░░░░░░░░░░│ +│░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░│ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ +│ │ 🚀 │ │ 🔒 │ │ 🔌 │ │ +│ │ Blazing Fast │ │ Secure │ │ Extensible │ │ +│ │ │ │ │ │ │ │ +│ │ Built on Rust │ │ SOC2 compliant │ │ Plugin system │ │ +│ │ for maximum │ │ with E2E │ │ with 200+ │ │ +│ │ performance │ │ encryption │ │ integrations │ │ +│ └─────────────────┘ └─────────────────┘ └─────────────────┘ │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌───────────────────────────────────────────────────────────┐ │ +│ │ │ │ +│ │ [SCREENSHOT/DEMO] │ │ +│ │ │ │ +│ └───────────────────────────────────────────────────────────┘ │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ Latest Releases Contributors │ +│ ──────────────── ──────────── │ +│ 📦 v2.1.0 - Jan 8, 2026 [👤][👤][👤][👤][👤] +47 │ +│ 📦 v2.0.2 - Dec 15, 2025 │ +│ 📦 v2.0.1 - Dec 1, 2025 Trusted by 10,000+ developers │ +│ │ +│ [⭐ Star on Gitea] │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ [Home] [Docs] [Blog] [GitHub] [Discord] © 2026 Acme Corp │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +#### Template 4: Portfolio/Gallery + +Visual showcase for design, art, or media projects. + +``` +┌─────────────────────────────────────────────────────────────────────┐ +│ │ +│ Design System │ +│ "A visual component library" │ +│ │ +│ [View Components] [Download] │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ │ │ │ │ │ │ │ │ +│ │ [img 1] │ │ [img 2] │ │ [img 3] │ │ [img 4] │ │ +│ │ │ │ │ │ │ │ │ │ +│ │ Buttons │ │ Forms │ │ Cards │ │ Modals │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ +│ │ │ │ │ │ │ │ │ │ +│ │ [img 5] │ │ [img 6] │ │ [img 7] │ │ [img 8] │ │ +│ │ │ │ │ │ │ │ │ │ +│ │ Tables │ │ Nav │ │ Icons │ │ Colors │ │ +│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │ +│ │ +├─────────────────────────────────────────────────────────────────────┤ +│ │ +│ ## About This Project │ +│ │ +│ A comprehensive design system built for modern web applications. │ +│ Includes 50+ components, dark mode support, and full │ +│ accessibility compliance. │ +│ │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +### 2.3 Configuration + +Configuration lives in `.gitea/landing.yaml` with DB fallback. File takes precedence. + +#### Full Configuration Schema + +```yaml +# .gitea/landing.yaml +# Landing Page Configuration for Gitea Pages + +#────────────────────────────────────────────────────────────────────── +# BASIC SETTINGS +#────────────────────────────────────────────────────────────────────── + +enabled: true +template: product # simple | documentation | product | portfolio + +# Custom domain (optional - subdomain is always available) +domain: myproject.com + +#────────────────────────────────────────────────────────────────────── +# BRANDING +#────────────────────────────────────────────────────────────────────── + +branding: + logo: ./assets/logo.png + logo_dark: ./assets/logo-dark.png # Optional dark mode variant + favicon: ./assets/favicon.ico + + # Color scheme + primary_color: "#4a90d9" + secondary_color: "#2ecc71" + accent_color: "#e74c3c" + + # Theme + dark_mode: auto # auto | light | dark | both (toggle) + + # Custom fonts (from approved list) + heading_font: "Inter" + body_font: "system-ui" + +#────────────────────────────────────────────────────────────────────── +# HERO SECTION +#────────────────────────────────────────────────────────────────────── + +hero: + title: "MyProject" + tagline: "The best thing since sliced bread" + + # Background options + background: ./assets/hero-bg.jpg + # OR gradient: "linear-gradient(135deg, #667eea 0%, #764ba2 100%)" + # OR color: "#1a1a2e" + + # Call-to-action buttons + cta_primary: + text: "Get Started" + link: "#installation" + # OR link: releases/latest (auto-resolves to latest release) + + cta_secondary: + text: "View Documentation" + link: /docs + style: outline # outline | ghost + +#────────────────────────────────────────────────────────────────────── +# FEATURES (for product template) +#────────────────────────────────────────────────────────────────────── + +features: + - icon: rocket # Built-in icons: rocket, shield, puzzle, zap, etc. + title: "Blazingly Fast" + description: "Built with performance in mind from day one." + + - icon: shield + title: "Secure by Default" + description: "Enterprise-grade security out of the box." + + - icon: ./assets/custom-icon.svg # Custom icon + title: "Extensible" + description: "Plugin system for unlimited customization." + + - icon: puzzle + title: "Easy Integration" + description: "Works with your existing tools and workflows." + +#────────────────────────────────────────────────────────────────────── +# SECTIONS +#────────────────────────────────────────────────────────────────────── + +sections: + - type: features # Renders features array above + + - type: screenshot + image: ./assets/screenshot.png + caption: "MyProject in action" + + - type: readme + file: README.md # Default + + - type: releases + limit: 3 + show_notes: true # Show release notes excerpt + + - type: contributors + limit: 12 + show_count: true # "and 47 more contributors" + + - type: custom + file: ./docs/features.md + title: "Why MyProject?" + +#────────────────────────────────────────────────────────────────────── +# DOCUMENTATION (for documentation template) +#────────────────────────────────────────────────────────────────────── + +documentation: + source: ./docs # Folder containing markdown files + + # Search + search: true + + # Table of contents in each page + toc: true + + # Sidebar navigation + sidebar: + - title: "Getting Started" + items: + - intro.md + - installation.md + - quick-start.md + + - title: "Guides" + items: + - configuration.md + - deployment.md + - troubleshooting.md + + - title: "API Reference" + collapsed: true # Collapsed by default + items: + - api/overview.md + - api/authentication.md + - api/endpoints.md + + # "Edit this page" links + edit_links: + enabled: true + text: "Edit this page" + # Link auto-generated to repo file + +#────────────────────────────────────────────────────────────────────── +# GALLERY (for portfolio template) +#────────────────────────────────────────────────────────────────────── + +gallery: + source: ./gallery # Folder containing images + columns: 4 # 2, 3, or 4 + lightbox: true # Click to enlarge + captions: true # Show image filename as caption + + # Or explicit items: + items: + - image: ./gallery/buttons.png + title: "Button Components" + link: /docs/buttons + + - image: ./gallery/forms.png + title: "Form Elements" + link: /docs/forms + +#────────────────────────────────────────────────────────────────────── +# FOOTER +#────────────────────────────────────────────────────────────────────── + +footer: + # Link columns + links: + - title: "Resources" + items: + - text: "Documentation" + url: /docs + - text: "API Reference" + url: /docs/api + - text: "Examples" + url: /examples + + - title: "Community" + items: + - text: "Discord" + url: https://discord.gg/xxx + - text: "Twitter" + url: https://twitter.com/myproject + - text: "GitHub Discussions" + url: https://github.com/org/repo/discussions + + - title: "Company" + items: + - text: "About" + url: https://company.com/about + - text: "Blog" + url: https://company.com/blog + - text: "Careers" + url: https://company.com/careers + + # Copyright + copyright: "© 2026 Acme Corporation. Released under MIT License." + + # Show "Powered by Gitea" badge + show_powered_by: true + +#────────────────────────────────────────────────────────────────────── +# SEO & SOCIAL +#────────────────────────────────────────────────────────────────────── + +seo: + title: "MyProject - Ship Faster with Confidence" + description: "MyProject helps development teams ship code faster and more reliably." + keywords: + - developer tools + - productivity + - open source + + # Open Graph / Social sharing + og_image: ./assets/og-image.png + twitter_card: summary_large_image + twitter_site: "@myproject" + +#────────────────────────────────────────────────────────────────────── +# ANALYTICS (optional) +#────────────────────────────────────────────────────────────────────── + +analytics: + # Privacy-friendly options + plausible: myproject.com + # OR + umami: + website_id: "xxx" + url: "https://analytics.example.com" + # OR + google_analytics: "G-XXXXXXXXXX" + +#────────────────────────────────────────────────────────────────────── +# ADVANCED +#────────────────────────────────────────────────────────────────────── + +advanced: + # Custom CSS file + custom_css: ./assets/custom.css + + # Custom head content (limited HTML) + custom_head: | + + + # Redirects + redirects: + /old-docs: /docs + /github: https://github.com/org/repo +``` + +### 2.4 URL Structure & Routing + +#### Standalone Architecture + +Landing pages are **completely independent** of the repository view: + +``` +Landing Page: https://myproject.com + https://repo.owner.pages.gitea.example.com + +Repository: https://gitea.example.com/owner/repo + (May be private - landing page still accessible) +``` + +#### Routing Flow + +``` + ┌─────────────────────┐ + Request ──────► │ Gitea Router │ + └──────────┬──────────┘ + │ + ┌────────────────┼────────────────┐ + │ │ │ + ▼ ▼ ▼ + ┌─────────────────┐ ┌───────────┐ ┌───────────────────┐ + │ pages.gitea.com │ │ Custom │ │ gitea.example.com │ + │ *.pages.gitea.. │ │ Domain │ │ (main app) │ + └────────┬────────┘ └─────┬─────┘ └───────────────────┘ + │ │ + ▼ ▼ + ┌─────────────────────────────────┐ + │ Pages Handler │ + │ - Lookup repo by domain │ + │ - Load .gitea/landing.yaml │ + │ - Render template │ + └─────────────────────────────────┘ +``` + +#### Navigation Between Landing and Repo + +The landing page is responsible for providing links to the source repository: + +```yaml +# In landing.yaml +hero: + cta_secondary: + text: "View Source" + link: https://gitea.example.com/owner/repo + +footer: + links: + - title: "Developers" + items: + - text: "Source Code" + url: https://gitea.example.com/owner/repo + - text: "Issues" + url: https://gitea.example.com/owner/repo/issues +``` + +--- + +## 3. Database Schema Changes + +### New Tables + +```sql +-- Organization pinned repositories +CREATE TABLE org_pinned_repo ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + org_id BIGINT NOT NULL, + repo_id BIGINT NOT NULL, + group_id BIGINT DEFAULT NULL, + display_order INT DEFAULT 0, + created_unix BIGINT, + FOREIGN KEY (org_id) REFERENCES organization(id), + FOREIGN KEY (repo_id) REFERENCES repository(id), + FOREIGN KEY (group_id) REFERENCES org_pinned_group(id), + UNIQUE KEY (org_id, repo_id) +); + +-- Organization pinned repo groups +CREATE TABLE org_pinned_group ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + org_id BIGINT NOT NULL, + name VARCHAR(255) NOT NULL, + display_order INT DEFAULT 0, + collapsed BOOLEAN DEFAULT FALSE, + FOREIGN KEY (org_id) REFERENCES organization(id) +); + +-- Pages domain mapping +CREATE TABLE pages_domain ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + repo_id BIGINT NOT NULL, + domain VARCHAR(255) NOT NULL UNIQUE, + verified BOOLEAN DEFAULT FALSE, + verification_token VARCHAR(64), + ssl_status VARCHAR(32) DEFAULT 'pending', + ssl_cert_expiry BIGINT, + created_unix BIGINT, + verified_unix BIGINT, + FOREIGN KEY (repo_id) REFERENCES repository(id) +); + +-- Pages configuration cache (parsed from .gitea/landing.yaml) +CREATE TABLE pages_config ( + id BIGINT PRIMARY KEY AUTO_INCREMENT, + repo_id BIGINT NOT NULL UNIQUE, + enabled BOOLEAN DEFAULT FALSE, + template VARCHAR(32) DEFAULT 'simple', + config_json TEXT, -- Cached parsed config + config_hash VARCHAR(64), -- For invalidation + updated_unix BIGINT, + FOREIGN KEY (repo_id) REFERENCES repository(id) +); +``` + +### Modified Tables + +```sql +-- Add to org_user table +ALTER TABLE org_user ADD COLUMN is_public BOOLEAN DEFAULT FALSE; + +-- Add to repository table +ALTER TABLE repository ADD COLUMN pages_enabled BOOLEAN DEFAULT FALSE; +ALTER TABLE repository ADD COLUMN pages_subdomain VARCHAR(255); +``` + +--- + +## 4. API Endpoints + +### Organization Profile API + +``` +# Pinned repos +GET /api/v1/orgs/{org}/pinned +POST /api/v1/orgs/{org}/pinned +PUT /api/v1/orgs/{org}/pinned/reorder +DELETE /api/v1/orgs/{org}/pinned/{repo} + +# Pinned groups +GET /api/v1/orgs/{org}/pinned/groups +POST /api/v1/orgs/{org}/pinned/groups +PUT /api/v1/orgs/{org}/pinned/groups/{id} +DELETE /api/v1/orgs/{org}/pinned/groups/{id} + +# Public members +GET /api/v1/orgs/{org}/public_members +PUT /api/v1/orgs/{org}/public_members/{username} # Opt-in +DELETE /api/v1/orgs/{org}/public_members/{username} # Opt-out + +# Profile content (via .profile repo) +# Uses standard repo file API +``` + +### Pages API + +``` +# Pages configuration +GET /api/v1/repos/{owner}/{repo}/pages +PUT /api/v1/repos/{owner}/{repo}/pages +DELETE /api/v1/repos/{owner}/{repo}/pages + +# Custom domains +GET /api/v1/repos/{owner}/{repo}/pages/domains +POST /api/v1/repos/{owner}/{repo}/pages/domains +DELETE /api/v1/repos/{owner}/{repo}/pages/domains/{domain} +POST /api/v1/repos/{owner}/{repo}/pages/domains/{domain}/verify + +# SSL certificates +GET /api/v1/repos/{owner}/{repo}/pages/domains/{domain}/ssl +POST /api/v1/repos/{owner}/{repo}/pages/domains/{domain}/ssl/renew +``` + +--- + +## 5. Implementation Phases + +### Phase 1: Organization Profile (4-6 weeks) + +1. **Week 1-2:** Database schema, models, migrations +2. **Week 2-3:** Pinned repos API and UI +3. **Week 3-4:** Public members opt-in system +4. **Week 4-5:** Profile content from `.profile` repo +5. **Week 5-6:** WYSIWYG editor integration, CSS sandboxing + +### Phase 2: Gitea Pages Foundation (6-8 weeks) + +1. **Week 1-2:** Pages router, subdomain handling +2. **Week 2-3:** Configuration parser (`.gitea/landing.yaml`) +3. **Week 3-4:** Simple template implementation +4. **Week 4-6:** Documentation template with sidebar +5. **Week 6-7:** Product and Portfolio templates +6. **Week 7-8:** Settings UI, template switching + +### Phase 3: Custom Domains & SSL (3-4 weeks) + +1. **Week 1:** Domain verification system +2. **Week 2:** Let's Encrypt integration +3. **Week 3:** DNS routing and Host header handling +4. **Week 4:** SSL certificate renewal, monitoring + +### Phase 4: Polish & Advanced Features (2-3 weeks) + +1. Analytics integration +2. Search functionality (docs template) +3. Image optimization +4. CDN integration options +5. Performance optimization + +--- + +## Appendix: File Structure + +### Organization `.profile` Repository + +``` +{org}/.profile/ +├── README.md # Main profile content +├── style.css # Optional custom CSS +└── assets/ + ├── logo.png + ├── logo-dark.png + ├── banner.jpg + └── team-photo.jpg +``` + +### Repository Landing Page + +``` +{repo}/ +├── .gitea/ +│ └── landing.yaml # Landing page configuration +├── docs/ # Documentation (for docs template) +│ ├── intro.md +│ ├── installation.md +│ └── api/ +│ └── endpoints.md +├── gallery/ # Images (for portfolio template) +│ ├── screenshot1.png +│ └── screenshot2.png +└── assets/ # Landing page assets + ├── logo.png + ├── favicon.ico + ├── hero-bg.jpg + ├── og-image.png + └── custom.css +``` + +--- + +*End of Specification*