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>
40 KiB
AI & Developer Experience Enhancements
Version: 1.0 Date: January 2026 Status: Draft - Awaiting Review
Table of Contents
- AI-Friendly API Improvements
- AI-Powered Wiki System
- User Experience Improvements
- Developer Tooling
- Data Integrity & Optimization
- 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
- Manual: Repo admin requests wiki generation
- Scheduled: Regenerate on release or milestone
- 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
- Client sends chunk hash before upload
- Server checks if chunk exists in storage
- If exists, skip upload and reference existing chunk
- 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)
-
Week 1-2: Structured error responses
- Define error code taxonomy
- Implement APIError type
- Migrate existing endpoints
-
Week 2-3: OpenAPI improvements
- Add detailed descriptions
- Add request/response examples
- Generate improved client SDKs
-
Week 3-4: Batch operations
- Batch files endpoint
- Batch issues endpoint
- Transaction handling
-
Week 4-5: AI context endpoints
- Repository summary
- Navigation hints
Phase 2: Wiki AI System (6-8 weeks)
-
Week 1-2: Wiki generation infrastructure
- Generation queue and workers
- Template system for different page types
- Source code analysis integration
-
Week 3-4: Review workflow
- Review UI components
- State machine for page lifecycle
- Diff viewer for AI vs human edits
-
Week 5-6: Suggestions system
- Outdated content detection
- Missing documentation detection
- Suggestion management API
-
Week 7-8: Code sync
- Watch path configuration
- Drift detection algorithm
- Notification system
Phase 3: User Experience (3-4 weeks)
-
Week 1: Progress reporting
- SSE endpoint implementation
- Progress aggregation for multi-step operations
-
Week 2: Webhooks
- New event types
- Payload schemas
- Delivery reliability
-
Week 3-4: Web UI uploads
- Drag-and-drop component
- Progress visualization
- Pause/resume functionality
- LocalStorage persistence
Phase 4: Developer Tools (3-4 weeks)
-
Week 1-2: CLI tool
- Upload command implementation
- Progress display
- Resume functionality
-
Week 3-4: SDK libraries
- Go SDK updates
- Python SDK
- JavaScript/TypeScript SDK
Phase 5: Data Integrity (2-3 weeks)
-
Week 1: Checksum verification
- SHA256 calculation
- Verification flow
- Error handling for mismatches
-
Week 2: Compression
- Gzip support
- Content-Encoding handling
- Size tracking
-
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