Write
Functions
writeDocs
async function writeDocs(docs: GeneratedDoc[], outputPath: string, primarySourcePath: string, isMultiSource: boolean, options: WriteDocsOptions): Promise<WriteDocsResult>
Use writeDocs to persist AI-generated documentation to disk, automatically choosing the right file layout based on how your source was scanned.
Call this after skrypt generate has produced your GeneratedDoc[] array — it's the final step that turns in-memory doc objects into .mdx files your documentation site can serve. It handles three distinct output strategies (by-topic grouping, multi-source, and single-source) so you don't need to branch that logic yourself.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
docs | GeneratedDoc[] | Yes | The documentation objects returned by the generation step. Each entry maps to one or more output files. |
outputPath | string | Yes | Absolute or relative path to the directory where .mdx files will be written. Created automatically if it doesn't exist. |
primarySourcePath | string | Yes | Path to the root of the scanned source — used to compute relative file paths and preserve directory structure in the output. |
isMultiSource | boolean | Yes | Set to true when docs were generated from multiple source directories. Affects how output files are namespaced to avoid collisions. |
options | WriteDocsOptions | Yes | Controls output strategy: pass byTopic: true to group related elements into topic pages instead of mirroring source file structure. |
Returns
Returns a Promise<WriteDocsResult> that resolves once all files are written. The result contains the list of files created and a manifest entry you can pass to subsequent refresh or search-index steps.
Heads up
outputPathis written to eagerly — existing.mdxfiles at conflicting paths will be overwritten without warning. Point it at a dedicated output directory, not your source tree.- When
byTopicandisMultiSourceare bothtrue, topic grouping takes precedence and source namespacing is applied within each topic file.
Example:
import { writeFile, mkdir } from "fs/promises";
import { join } from "path";
// Inline types — do not import from autodocs
interface GeneratedDoc {
title: string;
slug: string;
content: string;
sourceFile: string;
topic?: string;
}
interface WriteDocsOptions {
byTopic?: boolean;
}
interface WriteDocsResult {
filesWritten: string[];
manifest: Record<string, string>;
}
// Minimal self-contained implementation for demonstration
async function writeDocs(
docs: GeneratedDoc[],
outputPath: string,
primarySourcePath: string,
isMultiSource: boolean,
options: WriteDocsOptions
): Promise<WriteDocsResult> {
await mkdir(outputPath, { recursive: true });
const filesWritten: string[] = [];
const manifest: Record<string, string> = {};
for (const doc of docs) {
const subdir = options.byTopic && doc.topic ? doc.topic : "";
const dir = subdir ? join(outputPath, subdir) : outputPath;
await mkdir(dir, { recursive: true });
const filename = `${doc.slug}.mdx`;
const filePath = join(dir, filename);
await writeFile(filePath, doc.content, "utf-8");
filesWritten.push(filePath);
manifest[doc.slug] = filePath;
}
return { filesWritten, manifest };
}
// Realistic usage: write docs generated from a payments SDK
const generatedDocs: GeneratedDoc[] = [
{
title: "createCharge",
slug: "create-charge",
content: "# createCharge\n\nUse `createCharge` to initiate a payment...",
sourceFile: "/projects/payments-sdk/src/charges.ts",
topic: "payments",
},
{
title: "refundCharge",
slug: "refund-charge",
content: "# refundCharge\n\nUse `refundCharge` to reverse a captured payment...",
sourceFile: "/projects/payments-sdk/src/charges.ts",
topic: "payments",
},
{
title: "createCustomer",
slug: "create-customer",
content: "# createCustomer\n\nUse `createCustomer` to store a payer's details...",
sourceFile: "/projects/payments-sdk/src/customers.ts",
topic: "customers",
},
];
async function main() {
try {
const result = await writeDocs(
generatedDocs,
"./content/docs/api",
"/projects/payments-sdk/src",
false,
{ byTopic: true }
);
console.log("Files written:", result.filesWritten);
// Files written: [
// './content/docs/api/payments/create-charge.mdx',
// './content/docs/api/payments/refund-charge.mdx',
// './content/docs/api/customers/create-customer.mdx'
// ]
console.log("Manifest:", result.manifest);
// Manifest: {
// 'create-charge': './content/docs/api/payments/create-charge.mdx',
// 'refund-charge': './content/docs/api/payments/refund-charge.mdx',
// 'create-customer': './content/docs/api/customers/create-customer.mdx'
// }
} catch (err) {
console.error("Failed to write docs:", err);
}
}
main();
writeAssets
async function writeAssets(docs: GeneratedDoc[], allElements: APIElement[], outputPath: string, primarySourcePath: string, configOutputPath: string, filesWritten: number, options: WriteAssetsOptions): Promise<void>
Use writeAssets to finalize a documentation generation run by writing all supplementary output files — the OpenAPI spec copy, llms.txt, AGENTS.md, and the doc manifest — after your primary MDX files have been generated.
Call this as the last step in a custom generation pipeline, after you've scanned source files and generated doc content. It handles everything that isn't the per-element MDX files themselves: machine-readable indexes, AI agent context files, and the manifest that powers incremental regeneration.
writeAssets coordinates several output concerns in one call: it copies any OpenAPI spec found at the source path, builds an llms.txt summary of your API surface for LLM consumption, generates an AGENTS.md file describing the codebase for AI coding agents, and writes a manifest used by skrypt generate to skip unchanged files on future runs.
| Name | Type | Required | Description |
|---|---|---|---|
docs | GeneratedDoc[] | Yes | The generated documentation objects produced earlier in the pipeline — used to build the manifest and llms.txt index. |
allElements | APIElement[] | Yes | Every API element scanned from source, including those that may not have generated docs — ensures the manifest and agent files reflect the full API surface. |
outputPath | string | Yes | Absolute or relative path to the directory where all asset files will be written. Must already exist or be creatable. |
primarySourcePath | string | Yes | Path to the root of the scanned source — used to locate the OpenAPI spec and compute relative paths in the manifest. |
configOutputPath | string | Yes | Path to the config file written during skrypt init — embedded in the manifest so incremental runs can find it. |
filesWritten | number | Yes | Count of MDX files written before this call — included in the manifest summary so you can audit what changed between runs. |
options | WriteAssetsOptions | Yes | Controls optional behaviors: whether to generate llms.txt, AGENTS.md, topic grouping, and multi-language example output. |
Returns Promise<void>. This function writes directly to disk and has no return value — check your outputPath directory for the generated files after it resolves.
Heads up:
filesWrittenshould reflect only the MDX doc files written before this call, not the assets this function writes itself — passing the wrong count will produce a misleading manifest diff on the next incremental run.- If
outputPathdoesn't exist,writeAssetswill attempt to create it. If the path is invalid or write permissions are missing, it will throw a filesystem error with no cleanup of partial writes.
Example:
import { promises as fs } from 'fs'
import path from 'path'
// Inline types — do not import from autodocs
interface GeneratedDoc {
elementName: string
filePath: string
content: string
topic?: string
}
interface APIElement {
name: string
kind: 'function' | 'class' | 'interface' | 'type'
filePath: string
signature: string
}
interface WriteAssetsOptions {
generateLlmsTxt?: boolean
generateAgentsMd?: boolean
byTopic?: boolean
multiLang?: boolean
}
// Minimal self-contained mock of writeAssets
async function writeAssets(
docs: GeneratedDoc[],
allElements: APIElement[],
outputPath: string,
primarySourcePath: string,
configOutputPath: string,
filesWritten: number,
options: WriteAssetsOptions
): Promise<void> {
await fs.mkdir(outputPath, { recursive: true })
// Write llms.txt — a plain-text index of the API surface for LLM consumption
if (options.generateLlmsTxt) {
const lines = [
'# API Surface',
`Generated from: ${primarySourcePath}`,
'',
...allElements.map(el => `${el.kind} ${el.name}: ${el.signature}`)
]
await fs.writeFile(path.join(outputPath, 'llms.txt'), lines.join('\n'))
}
// Write AGENTS.md — codebase context for AI coding agents
if (options.generateAgentsMd) {
const agentsMd = [
'# AGENTS.md',
'',
`This codebase exposes ${allElements.length} public API elements.`,
`Documentation lives in: ${outputPath}`,
`Config: ${configOutputPath}`,
].join('\n')
await fs.writeFile(path.join(outputPath, 'AGENTS.md'), agentsMd)
}
// Write manifest for incremental regeneration
const manifest = {
generatedAt: new Date().toISOString(),
sourcePath: primarySourcePath,
configPath: configOutputPath,
filesWritten,
totalElements: allElements.length,
docs: docs.map(d => ({ name: d.elementName, file: d.filePath }))
}
await fs.writeFile(
path.join(outputPath, 'manifest.json'),
JSON.stringify(manifest, null, 2)
)
}
// --- Usage ---
const generatedDocs: GeneratedDoc[] = [
{ elementName: 'createUser', filePath: 'src/users.ts', content: '# createUser\n...', topic: 'Users' },
{ elementName: 'deleteUser', filePath: 'src/users.ts', content: '# deleteUser\n...', topic: 'Users' },
]
const apiElements: APIElement[] = [
{ name: 'createUser', kind: 'function', filePath: 'src/users.ts', signature: 'createUser(email: string): Promise<User>' },
{ name: 'deleteUser', kind: 'function', filePath: 'src/users.ts', signature: 'deleteUser(id: string): Promise<void>' },
]
const options: WriteAssetsOptions = {
generateLlmsTxt: true,
generateAgentsMd: true,
byTopic: false,
multiLang: false,
}
;(async () => {
try {
await writeAssets(
generatedDocs,
apiElements,
'./docs/output',
'./src',
'./skrypt.config.json',
2, // 2 MDX files were written before this call
options
)
const manifest = JSON.parse(
await fs.readFile('./docs/output/manifest.json', 'utf-8') as string
)
console.log('Assets written successfully')
console.log(`Manifest: ${manifest.filesWritten} files, ${manifest.totalElements} elements, generated at ${manifest.generatedAt}`)
// → Assets written successfully
// → Manifest: 2 files, 2 elements, generated at 2024-11-15T10:23:41.000Z
} catch (err) {
console.error('Failed to write assets:', err)
process.exit(1)
}
})()