gitea/ai_enhancements.md
logikonline 7eba24ea27 docs: add feature enhancement specifications
Add two specification documents for planned Gitea enhancements:

- enhancements.md: Organization public profile pages and Gitea Pages
  (repository landing pages with custom domains)

- ai_enhancements.md: AI and developer experience improvements
  including structured API errors, Scalar API docs, batch operations,
  AI-powered wiki generation, and SDK tooling

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-08 10:16:33 -05:00

40 KiB

AI & Developer Experience Enhancements

Version: 1.0 Date: January 2026 Status: Draft - Awaiting Review


Table of Contents

  1. AI-Friendly API Improvements
  2. AI-Powered Wiki System
  3. User Experience Improvements
  4. Developer Tooling
  5. Data Integrity & Optimization
  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

// Current: Inconsistent
{"message": "Not found"}
{"error": "unauthorized"}
"Something went wrong"

Proposed Standard

{
  "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

// 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

// 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 = `
<!DOCTYPE html>
<html>
<head>
    <title>{{AppName}} API Reference</title>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
        /* Custom theme to match Gitea */
        :root {
            --scalar-color-1: #4a90d9;
            --scalar-color-accent: #4a90d9;
        }
    </style>
</head>
<body>
    <script
        id="api-reference"
        data-url="/api/v1/swagger.json"
        data-proxy-url="https://proxy.scalar.com">
    </script>
    <script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>
</body>
</html>
`

Self-Hosted Scalar (No CDN)

// 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

# 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

// 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

// 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)

{"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
{
  "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
{
  "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
{
  "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

{
  "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
{
  "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
{
  "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

# .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
{
  "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

{
  "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

{
  "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"
    }
  }
}
{
  "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

// 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

# Via go install
go install code.gitea.io/gitea-cli@latest

# Via package managers
brew install gitea-cli
apt install gitea-cli

Usage

# 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

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

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

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

# 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

// 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

{
  "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

// 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