# TRUEREF-0010 — REST API (Search & Context Endpoints)

**Priority:** P0
**Status:** Pending
**Depends On:** TRUEREF-0006, TRUEREF-0009
**Blocks:** TRUEREF-0011

---

## Overview

Implement the public-facing REST API endpoints that replicate context7's `/api/v2/libs/search` and `/api/v2/context` interfaces. These are the endpoints that the MCP server, CLI tools, and external integrations call. The response format is designed to be compatible with context7's API surface so that tools built for context7 can be pointed at TrueRef with minimal changes.

---

## Acceptance Criteria

- [ ] `GET /api/v1/libs/search` — search libraries by name (equivalent to context7's `/api/v2/libs/search`)
- [ ] `GET /api/v1/context` — fetch documentation for a library (equivalent to context7's `/api/v2/context`)
- [ ] Both endpoints support `type=json` (structured) and `type=txt` (plain text for LLMs)
- [ ] `libraryId` supports `/owner/repo` (default branch) and `/owner/repo/version` (specific version)
- [ ] Rules from `trueref.json` are prepended to context responses
- [ ] CORS headers set (allow all origins) for browser-accessible usage
- [ ] Response times < 500ms p99 for typical queries
- [ ] Integration tests covering both endpoints

---

## Endpoint: `GET /api/v1/libs/search`

**Equivalent to:** `GET https://context7.com/api/v2/libs/search`

### Query Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `libraryName` | string | Yes | Library name to search for |
| `query` | string | No | User's question for relevance ranking |
| `limit` | integer | No | Max results (default: 10, max: 50) |

### Response `200` (`type=json`, default):

```json
{
  "results": [
    {
      "id": "/facebook/react",
      "title": "React",
      "description": "A JavaScript library for building user interfaces",
      "branch": "main",
      "lastUpdateDate": "2026-03-22T10:00:00Z",
      "state": "finalized",
      "totalTokens": 142000,
      "totalSnippets": 1247,
      "stars": 228000,
      "trustScore": 9.2,
      "benchmarkScore": 87,
      "versions": ["v18.3.0", "v17.0.2"],
      "source": "https://github.com/facebook/react"
    }
  ]
}
```

Note: `state: "finalized"` maps from TrueRef's `state: "indexed"` for compatibility.

### State Mapping

| TrueRef state | context7 state |
|---------------|---------------|
| `pending` | `initial` |
| `indexing` | `initial` |
| `indexed` | `finalized` |
| `error` | `error` |

---

## Endpoint: `GET /api/v1/context`

**Equivalent to:** `GET https://context7.com/api/v2/context`

### Query Parameters

| Parameter | Type | Required | Description |
|-----------|------|----------|-------------|
| `libraryId` | string | Yes | Library ID, e.g. `/facebook/react` or `/facebook/react/v18.3.0` |
| `query` | string | Yes | Specific question about the library |
| `type` | string | No | `json` (default) or `txt` (plain text for LLM injection) |
| `tokens` | integer | No | Approximate max token count for response (default: 10000) |

### Response `200` (`type=json`):

```json
{
  "snippets": [
    {
      "type": "code",
      "title": "Basic Component",
      "description": "Getting Started > Components",
      "language": "tsx",
      "codeList": [
        {
          "language": "tsx",
          "code": "function MyComponent() {\n  return <div>Hello</div>;\n}"
        }
      ],
      "id": "uuid",
      "tokenCount": 45,
      "pageTitle": "Getting Started"
    },
    {
      "type": "info",
      "text": "React components let you split the UI into independent...",
      "breadcrumb": "Core Concepts > Components",
      "pageId": "uuid",
      "tokenCount": 120
    }
  ],
  "rules": ["Always use functional components", "..."],
  "totalTokens": 2840
}
```

### Response `200` (`type=txt`):

Plain text formatted for direct LLM context injection:

```
## Library Rules
- Always use functional components
- Use hooks for state management

---

### Basic Component
*Getting Started > Components*

```tsx
function MyComponent() {
  return <div>Hello</div>;
}
```

---

### React components let you split the UI...
*Core Concepts > Components*

React components let you split the UI into independent, reusable pieces...
```

---

## LibraryId Parsing

```typescript
function parseLibraryId(libraryId: string): {
  repositoryId: string;  // "/facebook/react"
  version?: string;      // "v18.3.0"
} {
  // Match: /owner/repo or /owner/repo/version
  const match = libraryId.match(/^(\/[^/]+\/[^/]+)(\/(.+))?$/);
  if (!match) throw new Error(`Invalid libraryId: ${libraryId}`);

  return {
    repositoryId: match[1],
    version: match[3],
  };
}
```

---

## Token Budget

The `tokens` parameter limits the total response size. Snippets are added greedily until the budget is exhausted:

```typescript
function selectSnippetsWithinBudget(
  snippets: Snippet[],
  maxTokens: number
): Snippet[] {
  const selected: Snippet[] = [];
  let usedTokens = 0;

  for (const snippet of snippets) {
    if (usedTokens + (snippet.tokenCount ?? 0) > maxTokens) break;
    selected.push(snippet);
    usedTokens += snippet.tokenCount ?? 0;
  }

  return selected;
}
```

Default token budget: 10,000 tokens (~7,500 words) — enough for ~20 medium snippets.

---

## Error Responses

```json
// 400 Bad Request
{ "error": "libraryId is required", "code": "MISSING_PARAMETER" }

// 404 Not Found
{ "error": "Library /facebook/react not found or not yet indexed", "code": "LIBRARY_NOT_FOUND" }

// 503 Service Unavailable
{ "error": "Library is currently being indexed, please try again shortly", "code": "INDEXING_IN_PROGRESS" }
```

---

## CORS Configuration

All API routes include:
```
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PATCH, DELETE, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization
```

Set via `src/hooks.server.ts` handle function.

---

## SvelteKit Route Structure

```
src/routes/api/v1/
  libs/
    search/
      +server.ts          — GET /api/v1/libs/search
    +server.ts            — GET (list), POST (add)
    [id]/
      +server.ts          — GET, PATCH, DELETE
      index/
        +server.ts        — POST (trigger indexing)
  context/
    +server.ts            — GET /api/v1/context
  jobs/
    +server.ts            — GET (list jobs)
    [id]/
      +server.ts          — GET (single job)
  settings/
    embedding/
      +server.ts          — GET, PUT
```

---

## Files to Create

- `src/routes/api/v1/libs/search/+server.ts`
- `src/routes/api/v1/context/+server.ts`
- `src/lib/server/api/formatters.ts` — JSON ↔ txt response formatting
- `src/lib/server/api/library-id.ts` — ID parsing
- `src/lib/server/api/token-budget.ts`
- `src/hooks.server.ts` — CORS + startup recovery
- Integration tests in `src/lib/server/api/*.test.ts`
