/* This module persists bundled documentation topics to disk when `--save` is passed. It writes documentation under `./docs/`. */ import { mkdirSync, writeFileSync } from "node:fs"; import { dirname, join } from "node:path"; import type { CliProgram } from "../core/types.ts"; import { generatedFileHtmlComment, insertGeneratedHint } from "../skill/hint.ts"; import { docsTopicContent } from "./resolve.ts"; /** Relative output directory for `docs --save`. */ export const DOCS_SAVE_DIR = "docs"; /** Builtin docs topics generated by argsbarg (not consumer `docs.topics`). */ export const DOCS_GENERATED_SAVE_TOPICS = ["mcp", "cli", "http"] as const; /** Whether `--save` should prepend a generated-file hint (argsbarg writers only). */ export function docsTopicIsGeneratedByArgsbarg( /** Topic name. */ topic: string, ): boolean { return (DOCS_GENERATED_SAVE_TOPICS as readonly string[]).includes(topic); } /** HTML comment for generated markdown saved with `--save`. */ export function docsSaveGeneratedHint( /** Program definition. */ program: CliProgram, /** Topic name. */ topic: string, ): string { return generatedFileHtmlComment(`${program.key} docs ${topic} --save`); } /** Inserts save hint into markdown content. */ export function applySaveGeneratedHint( /** Program definition. */ program: CliProgram, /** Topic name. */ topic: string, /** Markdown text. */ content: string, ): string { if (!docsTopicIsGeneratedByArgsbarg(topic)) { return content; } const hint = docsSaveGeneratedHint(program, topic); return insertGeneratedHint(content, hint); } /** File body for `--save` (hint on argsbarg-generated markdown only). */ export function docsTopicContentForSave( /** Program definition. */ program: CliProgram, /** Topic name. */ topic: string, ): string { return applySaveGeneratedHint(program, topic, docsTopicContent(program, topic)); } /** Filename for a saved docs topic. */ export function docsSaveFilename( /** Topic name. */ topic: string, ): string { if (topic === "cli-schema") { return "cli-schema.json"; } if (topic === "openapi") { return "openapi.json"; } return `${topic}.md`; } /** Relative path under cwd for a saved docs topic. */ export function docsSaveRelativePath( /** Topic identifier. */ topic: string, /** Program root for resolving app-specific paths. */ _program?: CliProgram, ): string { return join(DOCS_SAVE_DIR, docsSaveFilename(topic)); } /** Writes one docs topic under `./docs/`; returns relative path written. */ export function saveDocsTopic( /** Program definition root. */ program: CliProgram, /** Topic identifier to save. */ topic: string, ): string { const rel = docsSaveRelativePath(topic, program); const abs = join(process.cwd(), rel); mkdirSync(dirname(abs), { recursive: true }); writeFileSync(abs, docsTopicContentForSave(program, topic), "utf8"); return rel; }