Phase 3: Organization Public Profile Page - Pinned repositories with groups - Public members display with roles - API endpoints for pinned repos and groups Phase 4: Gitea Pages Foundation - Landing page templates (simple, docs, product, portfolio) - Custom domain support with verification - YAML configuration parser (.gitea/landing.yaml) - Repository settings UI for pages Phase 5: Enhanced Wiki System with V2 API - Full CRUD operations via v2 API - Full-text search with WikiIndex table - Link graph visualization - Wiki health metrics (orphaned, dead links, outdated) - Designed for external AI plugin integration - Developer guide for .NET integration 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
355 lines
7.3 KiB
Markdown
355 lines
7.3 KiB
Markdown
# Phase 5: AI-Friendly Wiki API (v2)
|
|
|
|
**Version:** 2.0
|
|
**Date:** January 2026
|
|
**Status:** IN PROGRESS
|
|
|
|
---
|
|
|
|
## Overview
|
|
|
|
Phase 5 adds a v2 Wiki API designed for AI/LLM consumption and external plugin integration. This enhances the existing wiki functionality without modifying v1 endpoints.
|
|
|
|
### Goals
|
|
|
|
1. **AI-Ready Data** - Structured responses optimized for LLM consumption
|
|
2. **Full CRUD** - Complete wiki management via API
|
|
3. **Search** - Full-text search across wiki content
|
|
4. **Relationships** - Page link graph for navigation
|
|
5. **Health Metrics** - Wiki statistics and maintenance insights
|
|
6. **Plugin-Friendly** - Enable external tools (like .NET AI plugins) to build on top
|
|
|
|
---
|
|
|
|
## V2 API Endpoints
|
|
|
|
Base URL: `/api/v2/repos/{owner}/{repo}/wiki`
|
|
|
|
### Pages CRUD
|
|
|
|
#### List All Pages
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/pages
|
|
```
|
|
|
|
Query Parameters:
|
|
- `include_content` (bool, default: false) - Include full page content
|
|
- `page` (int) - Page number for pagination
|
|
- `limit` (int, default: 30) - Items per page
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"pages": [
|
|
{
|
|
"name": "Home",
|
|
"title": "Home",
|
|
"path": "Home.md",
|
|
"url": "/owner/repo/wiki/Home",
|
|
"word_count": 450,
|
|
"last_commit": {
|
|
"sha": "abc123",
|
|
"author": "username",
|
|
"message": "Updated home page",
|
|
"date": "2026-01-08T10:00:00Z"
|
|
},
|
|
"content": "# Home\n\nWelcome...", // if include_content=true
|
|
"content_html": "<h1>Home</h1>..." // if include_content=true
|
|
}
|
|
],
|
|
"total_count": 25,
|
|
"has_more": false
|
|
}
|
|
```
|
|
|
|
#### Get Single Page
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/pages/{pageName}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"name": "Installation",
|
|
"title": "Installation Guide",
|
|
"path": "Installation.md",
|
|
"url": "/owner/repo/wiki/Installation",
|
|
"content": "# Installation\n\n...",
|
|
"content_html": "<h1>Installation</h1>...",
|
|
"word_count": 1250,
|
|
"links_out": ["Home", "Configuration", "API-Reference"],
|
|
"links_in": ["Home", "Getting-Started"],
|
|
"sidebar": "...",
|
|
"footer": "...",
|
|
"last_commit": {
|
|
"sha": "def456",
|
|
"author": "username",
|
|
"message": "Added troubleshooting section",
|
|
"date": "2026-01-07T15:30:00Z"
|
|
},
|
|
"history_url": "/api/v2/repos/owner/repo/wiki/pages/Installation/revisions"
|
|
}
|
|
```
|
|
|
|
#### Create Page
|
|
```
|
|
POST /api/v2/repos/{owner}/{repo}/wiki/pages
|
|
```
|
|
|
|
Request:
|
|
```json
|
|
{
|
|
"name": "New-Page",
|
|
"title": "New Page Title",
|
|
"content": "# New Page\n\nContent here...",
|
|
"message": "Created new page"
|
|
}
|
|
```
|
|
|
|
Response: Same as Get Single Page
|
|
|
|
#### Update Page
|
|
```
|
|
PUT /api/v2/repos/{owner}/{repo}/wiki/pages/{pageName}
|
|
```
|
|
|
|
Request:
|
|
```json
|
|
{
|
|
"title": "Updated Title",
|
|
"content": "# Updated Content\n\n...",
|
|
"message": "Updated page content",
|
|
"rename_to": "new-page-name" // optional, to rename
|
|
}
|
|
```
|
|
|
|
Response: Same as Get Single Page
|
|
|
|
#### Delete Page
|
|
```
|
|
DELETE /api/v2/repos/{owner}/{repo}/wiki/pages/{pageName}
|
|
```
|
|
|
|
Request:
|
|
```json
|
|
{
|
|
"message": "Removed outdated page"
|
|
}
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"success": true
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Search
|
|
|
|
#### Full-Text Search
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/search?q={query}
|
|
```
|
|
|
|
Query Parameters:
|
|
- `q` (string, required) - Search query
|
|
- `limit` (int, default: 20) - Max results
|
|
- `include_content` (bool, default: false) - Include full content
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"query": "installation docker",
|
|
"results": [
|
|
{
|
|
"name": "Docker-Setup",
|
|
"title": "Docker Setup Guide",
|
|
"snippet": "...to run the <mark>installation</mark> in <mark>Docker</mark>, use the following...",
|
|
"score": 0.95,
|
|
"word_count": 800,
|
|
"last_updated": "2026-01-05T12:00:00Z"
|
|
}
|
|
],
|
|
"total_count": 3
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Link Graph
|
|
|
|
#### Get Page Relationships
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/graph
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"nodes": [
|
|
{"name": "Home", "word_count": 450},
|
|
{"name": "Installation", "word_count": 1250},
|
|
{"name": "Configuration", "word_count": 2100}
|
|
],
|
|
"edges": [
|
|
{"source": "Home", "target": "Installation"},
|
|
{"source": "Home", "target": "Configuration"},
|
|
{"source": "Installation", "target": "Configuration"}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Statistics & Health
|
|
|
|
#### Wiki Statistics
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/stats
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"total_pages": 25,
|
|
"total_words": 45000,
|
|
"total_commits": 142,
|
|
"last_updated": "2026-01-08T10:00:00Z",
|
|
"contributors": 5,
|
|
"health": {
|
|
"orphaned_pages": [
|
|
{"name": "Old-Notes", "word_count": 120}
|
|
],
|
|
"dead_links": [
|
|
{"page": "Home", "broken_link": "Deleted-Page"}
|
|
],
|
|
"outdated_pages": [
|
|
{"name": "Legacy-API", "last_edit": "2024-06-15T00:00:00Z", "days_old": 573}
|
|
],
|
|
"short_pages": [
|
|
{"name": "TODO", "word_count": 15}
|
|
]
|
|
},
|
|
"top_linked": [
|
|
{"name": "Home", "incoming_links": 12},
|
|
{"name": "Configuration", "incoming_links": 8}
|
|
]
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
### Revisions
|
|
|
|
#### Get Page History
|
|
```
|
|
GET /api/v2/repos/{owner}/{repo}/wiki/pages/{pageName}/revisions
|
|
```
|
|
|
|
Query Parameters:
|
|
- `page` (int) - Page number
|
|
- `limit` (int, default: 30) - Items per page
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"page_name": "Installation",
|
|
"revisions": [
|
|
{
|
|
"sha": "abc123",
|
|
"author": {
|
|
"username": "user1",
|
|
"email": "user1@example.com",
|
|
"avatar_url": "..."
|
|
},
|
|
"message": "Added troubleshooting section",
|
|
"date": "2026-01-07T15:30:00Z",
|
|
"additions": 45,
|
|
"deletions": 12
|
|
}
|
|
],
|
|
"total_count": 28
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Database Schema
|
|
|
|
### `wiki_index` (for full-text search)
|
|
|
|
| Column | Type | Description |
|
|
|--------|------|-------------|
|
|
| id | BIGINT | Primary key |
|
|
| repo_id | BIGINT | Repository ID |
|
|
| page_name | VARCHAR(255) | Wiki page name |
|
|
| page_path | VARCHAR(512) | Git file path |
|
|
| title | VARCHAR(255) | Page title |
|
|
| content | LONGTEXT | Full page content (for search) |
|
|
| content_hash | VARCHAR(64) | SHA256 for change detection |
|
|
| commit_sha | VARCHAR(64) | Last indexed commit |
|
|
| word_count | INT | Word count |
|
|
| links_out | TEXT | JSON array of outgoing links |
|
|
| updated_unix | BIGINT | Last update timestamp |
|
|
| created_unix | BIGINT | Creation timestamp |
|
|
|
|
**Indexes:** `(repo_id)`, `(repo_id, page_name) UNIQUE`, `FULLTEXT(title, content)`
|
|
|
|
---
|
|
|
|
## Implementation Plan
|
|
|
|
### Files to Create
|
|
|
|
**API Structs:**
|
|
- `modules/structs/repo_wiki_v2.go`
|
|
|
|
**API Router:**
|
|
- `routers/api/v2/repo/wiki.go`
|
|
|
|
**Services:**
|
|
- `services/wiki/wiki_index.go` - Search indexing
|
|
|
|
**Migration:**
|
|
- `models/migrations/v1_26/v328.go`
|
|
|
|
### Files to Modify
|
|
|
|
- `routers/api/v2/api.go` - Register wiki routes
|
|
- `models/repo/wiki_ai.go` - Simplify to just WikiIndex
|
|
|
|
---
|
|
|
|
## V2 vs V1 Comparison
|
|
|
|
| Feature | V1 | V2 |
|
|
|---------|----|----|
|
|
| Content encoding | Base64 | Plain JSON |
|
|
| HTML rendering | Separate call | Included in response |
|
|
| Word count | No | Yes |
|
|
| Link extraction | No | Yes |
|
|
| Search | No | Yes (full-text) |
|
|
| Graph | No | Yes |
|
|
| Statistics | No | Yes |
|
|
| Batch operations | No | Future |
|
|
|
|
---
|
|
|
|
## External Plugin Integration
|
|
|
|
Your .NET plugin can:
|
|
|
|
1. **Fetch all wiki content** via `GET /wiki/pages?include_content=true`
|
|
2. **Generate AI summaries** using your AI library
|
|
3. **Create/update pages** with AI-generated content
|
|
4. **Build Q&A system** by indexing content externally
|
|
5. **Analyze relationships** using the graph endpoint
|
|
|
|
The v2 API provides all the structured data needed for AI processing without building AI into Gitea itself.
|
|
|
|
---
|
|
|
|
*End of Specification*
|