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
+- 
+- 
+- 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*