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>
1329 lines
40 KiB
Markdown
1329 lines
40 KiB
Markdown
# 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 = `
|
|
<!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)
|
|
|
|
```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*
|