Library API
The npm package @wisent-ai/kronika exposes the same selection, generation,
audit, and sync contract as the CLI, as a dependency-free ES module for
Node.js 22+. The entry point is dist/src/index.js; everything below is a
named export of the package root.
The completion boundary
All model access goes through one interface, so any client can substitute for Brama in tests or embeddings:
interface CompletionClient {
complete(request: {
messages: { role: "system" | "user" | "assistant"; content: string }[];
model: string;
maxTokens: number;
}): Promise<{ content: string; model?: string }>;
}
BramaClient— the production implementation. Constructor options:url,apiKey, optionalagentId/authSecret(both or neither),timeoutMs(default120000), andfetchImplto inject a fetch. The request and header contract is in configuration.signedHeaders(body, agentId, authSecret, timestampSeconds?)— the HMAC header set (x-agent-id,x-agent-timestamp,x-agent-signature) for a given JSON body, exported so other callers can sign identically.
The seam is real, not theoretical: checkDocumentation,
writeDocumentation, and syncDocumentation all take the client as their
second argument, so a test double is one object:
import { checkDocumentation, type CompletionClient } from "@wisent-ai/kronika";
const canned: CompletionClient = {
async complete() {
return { content: JSON.stringify({ passed: true, summary: "covered", findings: [] }) };
},
};
const audit = await checkDocumentation({
repo: "/path/to/project",
output: "docs/usage.md",
sources: ["src"],
base: "origin/main",
head: "HEAD",
model: "any",
maxTokens: 8_000,
maxInputBytes: 200_000,
maxFileBytes: 64_000,
maxDiffBytes: 200_000,
}, canned);
The verdict still passes through parseDocumentationCheck — a double that
answers malformed JSON fails exactly like a misbehaving model
(runbook).
Selection
collectSources(options: SourceOptions): SourceCollection— builds the bounded source manifest; the rules are in sources.SourceOptionsis{ repo, sources?, output, maxInputBytes, maxFileBytes }; the result is{ documents, skipped, totalBytes }. Non-positive budgets throwSource byte limits must be positive— a library-only sentence, since the CLI validates its flags first.
Generation
writeDocumentation(options: WriteDocumentationOptions, client): Promise<WriteDocumentationResult>— one completion over the selected sources; withapply: truethe output file is atomically replaced. The result carriescontent,outputPath,applied,model?,sources, andskipped.buildDocumentationMessages(options, collection): ChatMessage[]— the exact write prompt (system rules plus source payload), exported for inspection or reuse.
Audit
checkDocumentation(options: CheckDocumentationOptions, client): Promise<CheckDocumentationResult>— audits onebase...headrange; the semantics are in cli.diffPathsrestricts the audited diff to given pathspecs — sync passes each document's declared sources here.buildDocumentationCheckMessages(options, collection, change): ChatMessage[]— the exact audit prompt.parseDocumentationCheck(content)— the strict verdict parser: JSON only (a surrounding code fence is tolerated), validated finding shape, kebab-case codes, and apassedvalue that must equal "no blockers".
Sync
syncDocumentation(options: SyncOptions, client): Promise<SyncResult>— one reconciliation tick over a manifest; the state machine is in sync.SyncOptionsis{ repo, manifestPath, statePath, dryRun, defaults }; the result is{ headSha, outcomes, stateWritten }. Committing and pushing are CLI concerns, not library ones. Manifest and state validation sentences are in the runbook.loadSyncManifest(path): SyncManifest— reads and validates a manifest.SYNC_MANIFEST_FILE,SYNC_STATE_FILE— the default file names,kronika.sync.jsonandkronika.sync-state.json.
Types
All contract types are exported: ChatMessage, CompletionClient,
CompletionRequest, CompletionResult, SourceOptions, SourceDocument,
SkippedSource, SourceCollection, DocumentationFinding,
CheckDocumentationOptions, CheckDocumentationResult,
WriteDocumentationOptions, WriteDocumentationResult, SyncDefaults,
SyncDocument, SyncManifest, SyncOptions, SyncOutcome, SyncResult,
and SyncState.
Example
import { BramaClient, writeDocumentation } from "@wisent-ai/kronika";
const client = new BramaClient({
url: process.env.BRAMA_URL!,
apiKey: process.env.BRAMA_API_KEY!,
});
const result = await writeDocumentation({
repo: "/path/to/project",
output: "docs/architecture.md",
sources: ["src", "README.md"],
instruction: "Document components, request flow, and failure modes.",
model: "any",
maxInputBytes: 200_000,
maxFileBytes: 64_000,
maxTokens: 8_000,
apply: false,
}, client);
process.stdout.write(result.content);