Library API
The npm package @wisent-ai/kronika exposes the same adoption,
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.
Workspace adoption
initializeDocumentationWorkspace(options: InitializeWorkspaceOptions):
InitializeWorkspaceResult is the library boundary used by kronika init.
It validates existing Markdown and evidence paths within one repository, then
atomically creates or explicitly replaces the schema-version-1 sync manifest.
It does not read document bodies into its result, generate text, call Brama, or
execute repository commands.
import { initializeDocumentationWorkspace } from "@wisent-ai/kronika";
const result = initializeDocumentationWorkspace({
repo: "/path/to/existing-project",
manifestPath: "kronika.sync.json",
documents: ["README.md", "docs"],
sources: ["src"],
});
The result separates imported, unchanged,
conflicting, and rejected. An identical manifest is unchanged; a
different existing manifest is preserved unless replace: true. The accepted
paths, defaults, and failures are documented under kronika init.
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",
}, 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 }. An unset limit reads every selected source whole; a stated non-positive one throwsSource byte limits must be positive.
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: InitializeWorkspaceOptions,
InitializeWorkspaceResult, 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",
apply: false,
}, client);
process.stdout.write(result.content);