7.3 KiB
TRUEREF-0013 — trueref.json Config File Support
Priority: P0 Status: Pending Depends On: TRUEREF-0003 Blocks: TRUEREF-0009
Overview
Support trueref.json configuration files placed in the root of a repository. This file allows repository owners to control how their repo is indexed: which folders to include, which to exclude, best-practice rules to inject into LLM responses, and versioning information. Also support context7.json as an alias for backward compatibility.
Acceptance Criteria
- Parser for
trueref.jsonandcontext7.json(same schema,trueref.jsontakes precedence) - Config applied during crawling to filter files (TRUEREF-0003, TRUEREF-0004)
- Config stored in
repository_configstable (TRUEREF-0001) - Config validated with descriptive error messages (invalid paths, oversized rules, etc.)
rulesinjected at the top of everyquery-docsresponsepreviousVersionsregistered asRepositoryVersionrecords- JSON Schema published at
/api/v1/schema/trueref-config.json - Unit tests for parser and validator
Config File Schema
// src/lib/server/config/trueref-config.schema.ts
export interface TrueRefConfig {
/**
* Override the display name for this library.
* 1–100 characters.
*/
projectTitle?: string;
/**
* Description of the library for search ranking.
* 10–500 characters.
*/
description?: string;
/**
* Folders to include in indexing (allowlist).
* Each entry is a path prefix or regex string.
* If empty/absent, all folders are included.
* Examples: ["src/", "docs/", "^packages/core"]
*/
folders?: string[];
/**
* Folders to exclude from indexing.
* Applied after `folders` allowlist.
* Examples: ["test/", "fixtures/", "__mocks__"]
*/
excludeFolders?: string[];
/**
* Exact filenames to exclude (no path, no regex).
* Examples: ["README.md", "CHANGELOG.md", "jest.config.ts"]
*/
excludeFiles?: string[];
/**
* Best practices / rules to inject at the top of every query-docs response.
* Each rule: 5–500 characters.
* Maximum 20 rules.
*/
rules?: string[];
/**
* Previously released versions to make available for versioned queries.
*/
previousVersions?: Array<{
tag: string; // git tag (e.g. "v1.2.3")
title: string; // human-readable (e.g. "Version 1.2.3")
}>;
}
Validation Rules
const CONFIG_CONSTRAINTS = {
projectTitle: { minLength: 1, maxLength: 100 },
description: { minLength: 10, maxLength: 500 },
folders: { maxItems: 50, maxLength: 200 }, // per entry
excludeFolders: { maxItems: 50, maxLength: 200 },
excludeFiles: { maxItems: 100, maxLength: 200 },
rules: { maxItems: 20, minLength: 5, maxLength: 500 },
previousVersions: { maxItems: 50 },
versionTag: { pattern: /^v?\d+\.\d+(\.\d+)?(-.*)?$/ }
};
Parser Implementation
// src/lib/server/config/config-parser.ts
export interface ParsedConfig {
config: TrueRefConfig;
source: 'trueref.json' | 'context7.json';
warnings: string[];
}
export function parseConfigFile(content: string, filename: string): ParsedConfig {
let raw: unknown;
try {
raw = JSON.parse(content);
} catch (e) {
throw new ConfigParseError(`${filename} is not valid JSON: ${(e as Error).message}`);
}
if (typeof raw !== 'object' || raw === null) {
throw new ConfigParseError(`${filename} must be a JSON object`);
}
const config = raw as Record<string, unknown>;
const validated: TrueRefConfig = {};
const warnings: string[] = [];
// projectTitle
if (config.projectTitle !== undefined) {
if (typeof config.projectTitle !== 'string') {
warnings.push('projectTitle must be a string, ignoring');
} else if (config.projectTitle.length > 100) {
validated.projectTitle = config.projectTitle.slice(0, 100);
warnings.push('projectTitle truncated to 100 characters');
} else {
validated.projectTitle = config.projectTitle;
}
}
// description
if (config.description !== undefined) {
if (typeof config.description === 'string') {
validated.description = config.description.slice(0, 500);
}
}
// folders / excludeFolders / excludeFiles — validated as string arrays
for (const field of ['folders', 'excludeFolders', 'excludeFiles'] as const) {
if (config[field] !== undefined) {
if (!Array.isArray(config[field])) {
warnings.push(`${field} must be an array, ignoring`);
} else {
validated[field] = (config[field] as unknown[])
.filter((item): item is string => {
if (typeof item !== 'string') {
warnings.push(`${field} entry must be a string, skipping: ${item}`);
return false;
}
return true;
})
.slice(0, field === 'excludeFiles' ? 100 : 50);
}
}
}
// rules
if (config.rules !== undefined) {
if (Array.isArray(config.rules)) {
validated.rules = (config.rules as unknown[])
.filter((r): r is string => typeof r === 'string' && r.length >= 5)
.map((r) => r.slice(0, 500))
.slice(0, 20);
}
}
// previousVersions
if (config.previousVersions !== undefined) {
if (Array.isArray(config.previousVersions)) {
validated.previousVersions = (config.previousVersions as unknown[])
.filter(
(v): v is { tag: string; title: string } =>
typeof v === 'object' &&
v !== null &&
typeof (v as Record<string, unknown>).tag === 'string' &&
typeof (v as Record<string, unknown>).title === 'string'
)
.slice(0, 50);
}
}
return {
config: validated,
source: filename.startsWith('trueref') ? 'trueref.json' : 'context7.json',
warnings
};
}
Integration with Crawlers
During crawl, the crawler:
- Looks for
trueref.jsonfirst, thencontext7.jsonin the root. - Downloads and parses the config before downloading other files.
- Applies
folders,excludeFolders,excludeFilesto the file list. - Returns the parsed config alongside crawl results.
The IndexingPipeline stores the config in repository_configs table and registers previousVersions as RepositoryVersion records (with state pending, triggering additional indexing jobs if configured).
Rules Injection
When query-docs returns results, rules from repository_configs are prepended:
// In formatters.ts
function buildContextResponse(snippets: Snippet[], config: RepositoryConfig | null): string {
const parts: string[] = [];
if (config?.rules?.length) {
parts.push('## Library Best Practices\n' + config.rules.map((r) => `- ${r}`).join('\n'));
}
// ... append snippet content
return parts.join('\n\n---\n\n');
}
JSON Schema Endpoint
GET /api/v1/schema/trueref-config.json
Returns the full JSON Schema for trueref.json so IDE validation (VS Code, etc.) can provide autocomplete:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "TrueRef Repository Configuration",
"type": "object",
"properties": {
"projectTitle": {
"type": "string",
"minLength": 1,
"maxLength": 100,
"description": "Override the display name for this library"
},
...
}
}
Files to Create
src/lib/server/config/config-parser.tssrc/lib/server/config/config-validator.tssrc/lib/server/config/trueref-config.schema.ts— TypeScript typessrc/lib/server/config/trueref-config.json— JSON Schemasrc/routes/api/v1/schema/trueref-config.json/+server.tssrc/lib/server/config/config-parser.test.ts