Reference
Configuration Reference
Complete reference for sourcepress.config.ts. All fields, types, and defaults for repository, ai, collections, knowledge, intent, evals, approval, media, jobs, cache, and sync.
Configuration Reference
sourcepress.config.ts is the single source of truth for your SourcePress project. It uses the defineConfig DSL exported from @sourcepress/core.
import { defineConfig } from '@sourcepress/core'
export default defineConfig({
// fields documented below
})
repository
Identifies the GitHub repository where approved content is written.
| Field | Type | Required | Description |
|---|---|---|---|
owner | string | Yes | GitHub organization or user name |
repo | string | Yes | Repository name |
branch | string | No | Target branch. Defaults to main |
contentPath | string | No | Root path for generated content files. Defaults to content/ |
repository: {
owner: 'acme-corp',
repo: 'acme-website',
branch: 'main',
contentPath: 'content/',
}
Errors referencing this block will cite repository.owner or repository.repo by field name. Verify both if GitHub returns 404.
ai
Controls which AI provider and model the pipeline uses, and sets spend limits.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | AI provider identifier. Currently supports 'anthropic' |
model | string | Yes | Model string passed to the Vercel AI SDK |
budget | object | No | Daily spend limits |
budget.dailyLimit | number | No | Maximum USD spend per calendar day |
budget.currency | string | No | Currency code. Defaults to 'USD' |
ai: {
provider: 'anthropic',
model: 'claude-opus-4-5',
budget: {
dailyLimit: 20,
currency: 'USD',
},
}
BudgetTracker in @sourcepress/ai enforces budget.dailyLimit. When the limit is reached, generation jobs are rejected until the next calendar day.
collections
Defines the content types the pipeline generates. Each collection maps to a directory under contentPath and produces a typed schema.
defineCollection
import { defineCollection, field, relation } from '@sourcepress/core'
collections: {
posts: defineCollection({
name: 'posts',
fields: { /* field helpers */ },
relations: { /* relation helpers */ },
}),
}
Field helpers (field)
All field helpers are imported from @sourcepress/core.
| Helper | Description |
|---|---|
field.text() | Single-line string |
field.richText() | Long-form content, rendered as HTML or Markdown |
field.number() | Numeric value |
field.boolean() | Boolean flag |
field.date() | ISO 8601 date string |
field.slug() | URL-safe identifier. Validated against /^[a-z0-9-]+$/ |
field.image() | Reference to a media asset |
field.select(options) | Enumerated string value |
field.array(inner) | Array of another field type |
Each helper accepts an options object:
field.text({ required: true, description: 'Page title' })
field.select(['draft', 'published', 'archived'], { required: true })
Relation helpers (relation)
| Helper | Description |
|---|---|
relation.hasOne(collection) | Single reference to another collection |
relation.hasMany(collection) | Array of references to another collection |
relation.belongsTo(collection) | Inverse of hasOne or hasMany |
import { defineCollection, field, relation } from '@sourcepress/core'
collections: {
posts: defineCollection({
name: 'posts',
fields: {
title: field.text({ required: true }),
slug: field.slug({ required: true }),
publishedAt: field.date(),
status: field.select(['draft', 'published'], { required: true }),
body: field.richText({ required: true }),
},
relations: {
author: relation.hasOne('authors'),
tags: relation.hasMany('tags'),
},
}),
authors: defineCollection({
name: 'authors',
fields: {
name: field.text({ required: true }),
slug: field.slug({ required: true }),
},
}),
}
Schema codegen runs at build time and emits TypeScript types for each collection.
knowledge
Configures the knowledge ingestion pipeline.
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Directory containing source documents, URLs, and transcripts |
graph | object | No | Knowledge graph backend options |
graph.backend | string | No | Storage backend for the entity graph. Defaults to 'memory' |
knowledge: {
path: 'knowledge/',
graph: {
backend: 'memory',
},
}
KnowledgeEngine reads from knowledge.path, runs classify and extract, then passes entities and relations to GraphBuilder. GraphBuilder deduplicates entities and uses union-find clustering.
intent
Declares what content the pipeline should produce. Intent files describe goals; the AI uses them to prioritize generation and gap detection.
intent: {
path: 'intent/',
}
| Field | Type | Required | Description |
|---|---|---|---|
path | string | Yes | Directory containing intent definition files |
evals
Controls the generate-judge-improve loop in EvalRunner.
| Field | Type | Required | Description |
|---|---|---|---|
threshold | number | Yes | Minimum score (0–1) a piece of content must reach before it is submitted for approval |
maxIterations | number | No | Maximum number of generate-judge-improve cycles per content item |
evals: {
threshold: 0.8,
maxIterations: 5,
}
The eval loop runs until the judge score meets or exceeds evals.threshold, or maxIterations is exhausted. Content that does not reach the threshold is not submitted for approval.
approval
Configures the approval provider that creates pull requests for reviewed content.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | Yes | Approval provider identifier. 'github' uses GitHubPRApprovalProvider |
rules | object | No | Rules applied before a PR is opened |
rules.requireScore | number | No | Minimum eval score. Overrides evals.threshold for the approval gate if set |
rules.requireHumanReview | boolean | No | When true, PRs are never auto-merged |
rules.labels | string[] | No | GitHub labels applied to every generated PR |
approval: {
provider: 'github',
rules: {
requireScore: 0.85,
requireHumanReview: true,
labels: ['ai-generated', 'needs-review'],
},
}
GitHubPRApprovalProvider is implemented in @sourcepress/github. Each PR includes a provenance block recording source knowledge files, model, score, and approver.
media
Configures media asset storage.
| Field | Type | Required | Description |
|---|---|---|---|
backend | string | Yes | Storage backend. 'git' uses GitMediaStorage |
path | string | No | Directory for stored media files. Defaults to public/media/ |
maxFileSizeBytes | number | No | Upload size limit in bytes |
allowedMimeTypes | string[] | No | Permitted MIME types for upload validation |
media: {
backend: 'git',
path: 'public/media/',
maxFileSizeBytes: 5242880,
allowedMimeTypes: ['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml'],
}
MediaStorage and GitMediaStorage are implemented in @sourcepress/media. Paths are sanitized before write.
jobs
Configures the background job runner used for ingestion, generation, and sync tasks.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | No | Job provider identifier. Defaults to 'in-process' |
concurrency | number | No | Maximum concurrent jobs |
jobs: {
provider: 'in-process',
concurrency: 4,
}
InProcessJobProvider in @sourcepress/jobs supports progress tracking and cancellation. It runs within the same Node.js process as the server.
cache
Configures response and computation caching.
| Field | Type | Required | Description |
|---|---|---|---|
provider | string | No | Cache provider identifier. Defaults to 'memory' |
ttl | number | No | Default time-to-live in seconds |
cache: {
provider: 'memory',
ttl: 3600,
}
CacheProvider interface and MemoryCache implementation are in @sourcepress/cache.
sync
Controls how generated content is written back to the repository.
| Field | Type | Required | Description |
|---|---|---|---|
outputPath | string | No | Directory where synced files are written. Defaults to repository.contentPath |
deleteOrphans | boolean | No | When true, removes files in outputPath that no longer correspond to a collection entry |
dryRun | boolean | No | When true, logs planned writes without modifying the filesystem |
sync: {
outputPath: 'content/',
deleteOrphans: false,
dryRun: false,
}
The sync CLI command and @sourcepress/astro integration both read from this block.
Complete example
import { defineConfig, defineCollection, field, relation } from '@sourcepress/core'
export default defineConfig({
repository: {
owner: 'acme-corp',
repo: 'acme-website',
branch: 'main',
contentPath: 'content/',
},
ai: {
provider: 'anthropic',
model: 'claude-opus-4-5',
budget: {
dailyLimit: 20,
currency: 'USD',
},
},
collections: {
posts: defineCollection({
name: 'posts',
fields: {
title: field.text({ required: true }),
slug: field.slug({ required: true }),
publishedAt: field.date(),
status: field.select(['draft', 'published'], { required: true }),
body: field.richText({ required: true }),
},
relations: {
author: relation.hasOne('authors'),
tags: relation.hasMany('tags'),
},
}),
authors: defineCollection({
name: 'authors',
fields: {
name: field.text({ required: true }),
slug: field.slug({ required: true }),
},
}),
},
knowledge: {
path: 'knowledge/',
graph: {
backend: 'memory',
},
},
intent: {
path: 'intent/',
},
evals: {
threshold: 0.8,
maxIterations: 5,
},
approval: {
provider: 'github',
rules: {
requireScore: 0.85,
requireHumanReview: true,
labels: ['ai-generated', 'needs-review'],
},
},
media: {
backend: 'git',
path: 'public/media/',
maxFileSizeBytes: 5242880,
allowedMimeTypes: ['image/png', 'image/jpeg', 'image/webp', 'image/svg+xml'],
},
jobs: {
provider: 'in-process',
concurrency: 4,
},
cache: {
provider: 'memory',
ttl: 3600,
},
sync: {
outputPath: 'content/',
deleteOrphans: false,
dryRun: false,
},
})