@farming-labs/docs 0.1.62 → 0.1.63
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.mjs
CHANGED
|
@@ -80,7 +80,7 @@ async function main() {
|
|
|
80
80
|
const { init } = await import("../init-CcgI3D7-.mjs");
|
|
81
81
|
await init(initOptions);
|
|
82
82
|
} else if (parsedCommand.command === "dev") {
|
|
83
|
-
const { dev } = await import("../dev-
|
|
83
|
+
const { dev } = await import("../dev-B_o7hWSI.mjs");
|
|
84
84
|
await dev(devOptions);
|
|
85
85
|
} else if (parsedCommand.command === "mcp") {
|
|
86
86
|
const { runMcp } = await import("../mcp-BANLcwQ0.mjs");
|
|
@@ -139,7 +139,7 @@ ${pc.dim("Usage:")}
|
|
|
139
139
|
|
|
140
140
|
${pc.dim("Commands:")}
|
|
141
141
|
${pc.cyan("init")} Scaffold docs in your project (default)
|
|
142
|
-
${pc.cyan("dev")} Run frameworkless docs locally from ${pc.dim("docs.
|
|
142
|
+
${pc.cyan("dev")} Run frameworkless docs locally from ${pc.dim("docs.json")}
|
|
143
143
|
${pc.cyan("agent")} Agent utilities (${pc.dim("compact")} to generate sibling agent.md files)
|
|
144
144
|
${pc.cyan("doctor")} Inspect and score agent or reader-facing docs quality
|
|
145
145
|
${pc.cyan("mcp")} Run the built-in docs MCP server over stdio
|
|
@@ -63,7 +63,8 @@ function printDevBanner({ name = "@farming-labs/docs", version = "v0.0.0", port,
|
|
|
63
63
|
|
|
64
64
|
//#endregion
|
|
65
65
|
//#region src/cli/dev.ts
|
|
66
|
-
const
|
|
66
|
+
const PRIMARY_MANAGED_CONFIG_FILE = "docs.json";
|
|
67
|
+
const LEGACY_MANAGED_CONFIG_FILE = "docs.cloud.json";
|
|
67
68
|
const DEFAULT_RUNTIME_ROOT = ".docs/site";
|
|
68
69
|
const DEFAULT_DOCS_ROOT = "docs";
|
|
69
70
|
const DEFAULT_API_REFERENCE_ROOT = "api-reference";
|
|
@@ -426,19 +427,31 @@ function detectNearestPackageManager(startDir) {
|
|
|
426
427
|
current = parent;
|
|
427
428
|
}
|
|
428
429
|
}
|
|
430
|
+
function resolveManagedConfigPath(projectRoot) {
|
|
431
|
+
const primaryPath = path.join(projectRoot, PRIMARY_MANAGED_CONFIG_FILE);
|
|
432
|
+
if (fs.existsSync(primaryPath)) return {
|
|
433
|
+
configPath: primaryPath,
|
|
434
|
+
configFileName: PRIMARY_MANAGED_CONFIG_FILE
|
|
435
|
+
};
|
|
436
|
+
const legacyPath = path.join(projectRoot, LEGACY_MANAGED_CONFIG_FILE);
|
|
437
|
+
if (fs.existsSync(legacyPath)) return {
|
|
438
|
+
configPath: legacyPath,
|
|
439
|
+
configFileName: LEGACY_MANAGED_CONFIG_FILE
|
|
440
|
+
};
|
|
441
|
+
throw new Error(`Could not find ${PRIMARY_MANAGED_CONFIG_FILE} in ${projectRoot}. Frameworkless dev expects ${PRIMARY_MANAGED_CONFIG_FILE}, ${DEFAULT_DOCS_ROOT}/, and optionally ${DEFAULT_API_REFERENCE_ROOT}/. ${LEGACY_MANAGED_CONFIG_FILE} is still supported for older repos.`);
|
|
442
|
+
}
|
|
429
443
|
function readManagedDocsProject(projectRoot) {
|
|
430
|
-
const configPath =
|
|
431
|
-
if (!fs.existsSync(configPath)) throw new Error(`Could not find ${MANAGED_CONFIG_FILE} in ${projectRoot}. Frameworkless dev expects ${MANAGED_CONFIG_FILE}, ${DEFAULT_DOCS_ROOT}/, and optionally ${DEFAULT_API_REFERENCE_ROOT}/.`);
|
|
444
|
+
const { configPath, configFileName } = resolveManagedConfigPath(projectRoot);
|
|
432
445
|
let parsedJson;
|
|
433
446
|
try {
|
|
434
447
|
parsedJson = JSON.parse(fs.readFileSync(configPath, "utf-8"));
|
|
435
448
|
} catch (error) {
|
|
436
|
-
throw new Error(`Could not parse ${
|
|
449
|
+
throw new Error(`Could not parse ${configFileName}. The file must be valid JSON.${error instanceof Error ? ` ${error.message}` : ""}`);
|
|
437
450
|
}
|
|
438
451
|
const parsed = managedConfigSchema.safeParse(parsedJson);
|
|
439
|
-
if (!parsed.success) throw new Error(`Invalid ${
|
|
452
|
+
if (!parsed.success) throw new Error(`Invalid ${configFileName}: ${formatZodError(parsed.error)}`);
|
|
440
453
|
const docsConfig = parsed.data.docs;
|
|
441
|
-
if (("mode" in docsConfig ? docsConfig.mode : docsConfig.framework === "managed" ? "frameworkless" : "framework") !== "frameworkless") throw new Error(`${
|
|
454
|
+
if (("mode" in docsConfig ? docsConfig.mode : docsConfig.framework === "managed" ? "frameworkless" : "framework") !== "frameworkless") throw new Error(`${configFileName} uses docs.mode = "framework". ${pc.cyan("docs dev")} only supports frameworkless projects right now.`);
|
|
442
455
|
const runtimeFramework = "runtime" in docsConfig && docsConfig.runtime ? docsConfig.runtime : "nextjs";
|
|
443
456
|
if (runtimeFramework !== "nextjs") throw new Error(`Frameworkless ${pc.cyan("docs dev")} currently supports only docs.runtime = "nextjs".`);
|
|
444
457
|
const docsRoot = parsed.data.content?.docsRoot ?? DEFAULT_DOCS_ROOT;
|
|
@@ -452,6 +465,7 @@ function readManagedDocsProject(projectRoot) {
|
|
|
452
465
|
const theme = resolveThemePreset(parsed.data.theme?.preset);
|
|
453
466
|
return {
|
|
454
467
|
configPath,
|
|
468
|
+
configFileName,
|
|
455
469
|
projectRoot,
|
|
456
470
|
runtimeDir,
|
|
457
471
|
runtimeFramework,
|
|
@@ -665,7 +679,7 @@ function validateManagedOpenApiSpec(project) {
|
|
|
665
679
|
if (!sourcePath) return;
|
|
666
680
|
if (!fs.existsSync(sourcePath) || !fs.statSync(sourcePath).isFile()) {
|
|
667
681
|
const relativePath = path.relative(project.projectRoot, sourcePath) || sourcePath;
|
|
668
|
-
throw new Error(`OpenAPI source not found at ${relativePath}. Update ${
|
|
682
|
+
throw new Error(`OpenAPI source not found at ${relativePath}. Update ${project.configFileName} or add the spec file and try again.`);
|
|
669
683
|
}
|
|
670
684
|
}
|
|
671
685
|
function renderAlternateSectionLayout(configImportPath) {
|
|
@@ -895,7 +909,7 @@ function materializeManagedRuntime(projectRoot) {
|
|
|
895
909
|
const hasDocsMarkdown = directoryHasMarkdown(docsSourceDir);
|
|
896
910
|
const hasApiReferenceMarkdown = directoryHasMarkdown(apiReferenceSourceDir);
|
|
897
911
|
validateManagedOpenApiSpec(project);
|
|
898
|
-
if (!hasDocsMarkdown && !hasApiReferenceMarkdown && !hasOpenApiSpec) throw new Error(`No docs content found. Add markdown files under ${project.docsRoot}/ or ${project.apiReferenceRoot}/, or point content.openapi at an OpenAPI file in ${
|
|
912
|
+
if (!hasDocsMarkdown && !hasApiReferenceMarkdown && !hasOpenApiSpec) throw new Error(`No docs content found. Add markdown files under ${project.docsRoot}/ or ${project.apiReferenceRoot}/, or point content.openapi at an OpenAPI file in ${project.configFileName}.`);
|
|
899
913
|
const templateConfig = {
|
|
900
914
|
entry: "docs",
|
|
901
915
|
theme: project.theme.templateTheme,
|
|
@@ -1140,9 +1154,9 @@ async function dev(options = {}) {
|
|
|
1140
1154
|
const runtimeInstallStamp = getRuntimeInstallStamp(project);
|
|
1141
1155
|
console.log(pc.dim("Preparing local preview..."));
|
|
1142
1156
|
if (options.verbose) {
|
|
1143
|
-
logLine("source", `${pc.cyan(
|
|
1157
|
+
logLine("source", `${pc.cyan(project.configFileName)} drives ${pc.cyan(`${project.docsRoot}/`)} and ${pc.cyan(`${project.apiReferenceRoot}/`)}`);
|
|
1144
1158
|
logLine("runtime", `Generated runtime at ${pc.cyan(path.relative(projectRoot, project.runtimeDir) || project.runtimeDir)}`);
|
|
1145
|
-
logLine("watch", `Watching ${project.docsRoot}/, ${project.apiReferenceRoot}/, and ${
|
|
1159
|
+
logLine("watch", `Watching ${project.docsRoot}/, ${project.apiReferenceRoot}/, and ${project.configFileName}`);
|
|
1146
1160
|
logLine("sync", `Loaded ${initial.docs.pageCount} docs page${initial.docs.pageCount === 1 ? "" : "s"} and ${initial.apiReference.pageCount} api-reference page${initial.apiReference.pageCount === 1 ? "" : "s"}`);
|
|
1147
1161
|
}
|
|
1148
1162
|
if (!fs.existsSync(runtimeNodeModules) || !fs.existsSync(runtimeInstallMarker) || fs.readFileSync(runtimeInstallMarker, "utf-8") !== runtimeInstallStamp) {
|