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.

FieldTypeRequiredDescription
ownerstringYesGitHub organization or user name
repostringYesRepository name
branchstringNoTarget branch. Defaults to main
contentPathstringNoRoot 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.

FieldTypeRequiredDescription
providerstringYesAI provider identifier. Currently supports 'anthropic'
modelstringYesModel string passed to the Vercel AI SDK
budgetobjectNoDaily spend limits
budget.dailyLimitnumberNoMaximum USD spend per calendar day
budget.currencystringNoCurrency 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.

HelperDescription
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)

HelperDescription
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.

FieldTypeRequiredDescription
pathstringYesDirectory containing source documents, URLs, and transcripts
graphobjectNoKnowledge graph backend options
graph.backendstringNoStorage 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/',
}
FieldTypeRequiredDescription
pathstringYesDirectory containing intent definition files

evals

Controls the generate-judge-improve loop in EvalRunner.

FieldTypeRequiredDescription
thresholdnumberYesMinimum score (0–1) a piece of content must reach before it is submitted for approval
maxIterationsnumberNoMaximum 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.

FieldTypeRequiredDescription
providerstringYesApproval provider identifier. 'github' uses GitHubPRApprovalProvider
rulesobjectNoRules applied before a PR is opened
rules.requireScorenumberNoMinimum eval score. Overrides evals.threshold for the approval gate if set
rules.requireHumanReviewbooleanNoWhen true, PRs are never auto-merged
rules.labelsstring[]NoGitHub 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.

FieldTypeRequiredDescription
backendstringYesStorage backend. 'git' uses GitMediaStorage
pathstringNoDirectory for stored media files. Defaults to public/media/
maxFileSizeBytesnumberNoUpload size limit in bytes
allowedMimeTypesstring[]NoPermitted 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.

FieldTypeRequiredDescription
providerstringNoJob provider identifier. Defaults to 'in-process'
concurrencynumberNoMaximum 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.

FieldTypeRequiredDescription
providerstringNoCache provider identifier. Defaults to 'memory'
ttlnumberNoDefault 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.

FieldTypeRequiredDescription
outputPathstringNoDirectory where synced files are written. Defaults to repository.contentPath
deleteOrphansbooleanNoWhen true, removes files in outputPath that no longer correspond to a collection entry
dryRunbooleanNoWhen 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,
  },
})