@farming-labs/docs 0.2.0 → 0.2.1

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.
@@ -27,7 +27,11 @@ function parseFlags(argv) {
27
27
  "algolia",
28
28
  "verbose",
29
29
  "host",
30
- "json"
30
+ "json",
31
+ "network",
32
+ "analytics",
33
+ "ask-ai",
34
+ "deploy"
31
35
  ]);
32
36
  for (let i = 0; i < argv.length; i++) {
33
37
  const arg = argv[i];
@@ -85,36 +89,45 @@ async function main() {
85
89
  apiBaseUrl: typeof flags["api-base-url"] === "string" ? flags["api-base-url"] : typeof flags.url === "string" ? flags.url : void 0,
86
90
  apiKey: typeof flags["api-key"] === "string" ? flags["api-key"] : void 0,
87
91
  apiKeyEnv: typeof flags["api-key-env"] === "string" ? flags["api-key-env"] : void 0,
88
- json: typeof flags.json === "boolean" ? flags.json : void 0
92
+ json: typeof flags.json === "boolean" ? flags.json : void 0,
93
+ network: typeof flags.network === "boolean" ? flags.network : void 0,
94
+ checkTargets: [
95
+ ...flags.deploy === true ? ["deploy"] : [],
96
+ ...flags.analytics === true ? ["analytics"] : [],
97
+ ...flags["ask-ai"] === true ? ["ask-ai"] : []
98
+ ]
89
99
  };
90
100
  if (!parsedCommand.command || parsedCommand.command === "init") {
91
- const { init } = await import("../init-CZx_vasZ.mjs");
101
+ const { init } = await import("../init-BHUB2nUr.mjs");
92
102
  await init(initOptions);
93
103
  } else if (parsedCommand.command === "dev") {
94
104
  const { dev } = await import("../dev-D58nBPBv.mjs");
95
105
  await dev(devOptions);
96
106
  } else if (parsedCommand.command === "deploy") {
97
- const { runCloudDeploy } = await import("../cloud-BBg-41RG.mjs");
107
+ const { runCloudDeploy } = await import("../cloud-CHeiSRTt.mjs");
98
108
  await runCloudDeploy(cloudOptions);
99
109
  } else if (parsedCommand.command === "preview") {
100
- const { runCloudPreview } = await import("../cloud-BBg-41RG.mjs");
110
+ const { runCloudPreview } = await import("../cloud-CHeiSRTt.mjs");
101
111
  await runCloudPreview(cloudOptions);
102
112
  } else if (parsedCommand.command === "cloud" && subcommand === "deploy") {
103
- const { runCloudDeploy } = await import("../cloud-BBg-41RG.mjs");
113
+ const { runCloudDeploy } = await import("../cloud-CHeiSRTt.mjs");
104
114
  await runCloudDeploy(cloudOptions);
105
115
  } else if (parsedCommand.command === "cloud" && subcommand === "preview") {
106
- const { runCloudPreview } = await import("../cloud-BBg-41RG.mjs");
116
+ const { runCloudPreview } = await import("../cloud-CHeiSRTt.mjs");
107
117
  await runCloudPreview(cloudOptions);
108
118
  } else if (parsedCommand.command === "cloud" && subcommand === "init") {
109
- const { runCloudInit } = await import("../cloud-BBg-41RG.mjs");
119
+ const { runCloudInit } = await import("../cloud-CHeiSRTt.mjs");
110
120
  await runCloudInit(cloudOptions);
111
121
  } else if (parsedCommand.command === "cloud" && subcommand === "sync") {
112
- const { syncCloudConfig } = await import("../cloud-BBg-41RG.mjs");
122
+ const { syncCloudConfig } = await import("../cloud-CHeiSRTt.mjs");
113
123
  await syncCloudConfig(cloudOptions);
124
+ } else if (parsedCommand.command === "cloud" && subcommand === "check") {
125
+ const { runCloudCheck } = await import("../cloud-CHeiSRTt.mjs");
126
+ await runCloudCheck(cloudOptions);
114
127
  } else if (parsedCommand.command === "cloud") {
115
128
  console.error(pc.red(`Unknown cloud subcommand: ${subcommand ?? "(missing)"}`));
116
129
  console.error();
117
- const { printCloudHelp } = await import("../cloud-BBg-41RG.mjs");
130
+ const { printCloudHelp } = await import("../cloud-CHeiSRTt.mjs");
118
131
  printCloudHelp();
119
132
  process.exit(1);
120
133
  } else if (parsedCommand.command === "mcp") {
@@ -253,7 +266,7 @@ ${pc.dim("Commands:")}
253
266
  ${pc.cyan("dev")} Run frameworkless docs locally from ${pc.dim("docs.json")}
254
267
  ${pc.cyan("deploy")} Sync cloud config and deploy hosted preview docs
255
268
  ${pc.cyan("preview")} Alias for ${pc.cyan("deploy")}
256
- ${pc.cyan("cloud")} Docs Cloud utilities (${pc.dim("init")}, ${pc.dim("deploy")}, ${pc.dim("preview")}, ${pc.dim("sync")})
269
+ ${pc.cyan("cloud")} Docs Cloud utilities (${pc.dim("init")}, ${pc.dim("check")}, ${pc.dim("deploy")}, ${pc.dim("preview")}, ${pc.dim("sync")})
257
270
  ${pc.cyan("agent")} Agent utilities (${pc.dim("compact")} to generate sibling agent.md files)
258
271
  ${pc.cyan("agents")} AGENTS.md utilities (${pc.dim("generate")} for static agent instructions)
259
272
  ${pc.cyan("doctor")} Inspect and score agent or reader-facing docs quality
@@ -289,17 +302,22 @@ ${pc.dim("Options for dev:")}
289
302
  ${pc.cyan("--host [host]")} Expose the preview on your network; optionally pass a host value
290
303
  ${pc.cyan("--verbose")} Show raw runtime logs in addition to branded CLI output
291
304
 
292
- ${pc.dim("Options for cloud deploy:")}
305
+ ${pc.dim("Options for cloud:")}
293
306
  ${pc.cyan("cloud init")} Add Docs Cloud config to ${pc.dim("docs.config.ts")} and ${pc.dim("docs.json")}
294
307
  ${pc.cyan("deploy")} Sync ${pc.dim("docs.config.ts")} into ${pc.dim("docs.json")} and deploy hosted preview docs
295
308
  ${pc.cyan("cloud deploy")} Same as ${pc.cyan("deploy")}
296
309
  ${pc.cyan("preview")} Alias for ${pc.cyan("deploy")}
297
310
  ${pc.cyan("cloud preview")} Compatibility alias for ${pc.cyan("cloud deploy")}
298
311
  ${pc.cyan("cloud sync")} Only materialize cloud settings into ${pc.dim("docs.json")}
312
+ ${pc.cyan("cloud check")} Validate Docs Cloud config, analytics envs, API key, and Ask AI wiring
299
313
  ${pc.cyan("--config <path>")} Use a custom docs config path
300
314
  ${pc.cyan("--api-key-env <name>")} Env var that stores the Docs Cloud API key
301
315
  ${pc.cyan("--api-base-url <url>")} Override the Docs Cloud API base URL
302
316
  ${pc.cyan("--api-key <key>")} Use an API key directly; prefer ${pc.dim("cloud.apiKey.env")}
317
+ ${pc.cyan("--analytics")} Only check Docs Cloud analytics integration
318
+ ${pc.cyan("--ask-ai")} Only check Docs Cloud Ask AI integration
319
+ ${pc.cyan("--deploy")} Only check Docs Cloud deploy integration
320
+ ${pc.cyan("--no-network")} Skip live Docs Cloud API validation for ${pc.cyan("cloud check")}
303
321
  ${pc.cyan("--json")} Print machine-readable output
304
322
  ${pc.dim("required scopes")} project:read, preview:write, jobs:read
305
323
 
@@ -20,6 +20,13 @@ const REQUIRED_PREVIEW_API_KEY_SCOPES = [
20
20
  "preview:write",
21
21
  "jobs:read"
22
22
  ];
23
+ const DOCS_CLOUD_PROJECT_ID_ENVS = ["NEXT_PUBLIC_DOCS_CLOUD_PROJECT_ID", "DOCS_CLOUD_PROJECT_ID"];
24
+ const DEFAULT_PUBLIC_DOCS_CLOUD_API_KEY_ENV = "NEXT_PUBLIC_DOCS_CLOUD_API_KEY";
25
+ const CLOUD_CHECK_TARGETS = [
26
+ "deploy",
27
+ "analytics",
28
+ "ask-ai"
29
+ ];
23
30
  function isRecord(value) {
24
31
  return Boolean(value && typeof value === "object" && !Array.isArray(value));
25
32
  }
@@ -593,6 +600,90 @@ async function materializeCloudConfig(options = {}) {
593
600
  updated
594
601
  };
595
602
  }
603
+ function readCombinedEnv(rootDir) {
604
+ const env = { ...loadProjectEnv(rootDir) };
605
+ for (const [key, value] of Object.entries(process.env)) if (typeof value === "string") env[key] = value;
606
+ return env;
607
+ }
608
+ function readEnvValue(env, name) {
609
+ if (!name) return void 0;
610
+ const value = env[name]?.trim();
611
+ return value ? value : void 0;
612
+ }
613
+ function readFirstEnv(env, names) {
614
+ for (const name of names) {
615
+ const value = readEnvValue(env, name);
616
+ if (value) return {
617
+ name,
618
+ value
619
+ };
620
+ }
621
+ }
622
+ function readConfiguredCloudApiKeyEnv(snapshot) {
623
+ const moduleEnv = snapshot.config?.cloud?.apiKey?.env?.trim();
624
+ if (moduleEnv) return moduleEnv;
625
+ const apiKeyBlock = extractNestedObjectLiteral(snapshot.content ?? "", ["cloud", "apiKey"]);
626
+ return (apiKeyBlock ? readStringProperty(apiKeyBlock, "env") : void 0)?.trim() || void 0;
627
+ }
628
+ function readAiProvider(snapshot) {
629
+ const moduleProvider = (snapshot.config?.ai)?.provider;
630
+ if (typeof moduleProvider === "string" && moduleProvider.trim()) return moduleProvider.trim();
631
+ const aiBlock = extractNestedObjectLiteral(snapshot.content ?? "", ["ai"]);
632
+ return (aiBlock ? readStringProperty(aiBlock, "provider") : void 0)?.trim() || void 0;
633
+ }
634
+ function readRuntimeAnalyticsDisabled(snapshot) {
635
+ const moduleAnalytics = snapshot.config?.analytics;
636
+ if (moduleAnalytics === false) return true;
637
+ if (isRecord(moduleAnalytics) && moduleAnalytics.enabled === false) return true;
638
+ if (readTopLevelBooleanProperty(snapshot.content ?? "", "analytics") === false) return true;
639
+ const analyticsBlock = extractNestedObjectLiteral(snapshot.content ?? "", ["analytics"]);
640
+ return (analyticsBlock ? readTopLevelBooleanProperty(analyticsBlock, "enabled") : void 0) === false;
641
+ }
642
+ function isCloudAnalyticsEnabled(analytics) {
643
+ if (analytics === false) return false;
644
+ if (isRecord(analytics) && analytics.enabled === false) return false;
645
+ return typeof analytics !== "undefined";
646
+ }
647
+ function createCheck(name, status, message, details) {
648
+ return {
649
+ name,
650
+ status,
651
+ message,
652
+ ...details ? { details } : {}
653
+ };
654
+ }
655
+ function summarizeIdentity(identity) {
656
+ if (!isRecord(identity)) return void 0;
657
+ const workspace = isRecord(identity.workspace) ? identity.workspace : void 0;
658
+ const apiKey = isRecord(identity.apiKey) ? identity.apiKey : void 0;
659
+ const scopes = readApiKeyScopes(identity);
660
+ return {
661
+ ...workspace ? { workspace: {
662
+ ...typeof workspace.id === "string" ? { id: workspace.id } : {},
663
+ ...typeof workspace.name === "string" ? { name: workspace.name } : {}
664
+ } } : {},
665
+ ...apiKey ? { apiKey: {
666
+ ...typeof apiKey.id === "string" ? { id: apiKey.id } : {},
667
+ ...scopes.length > 0 ? { scopes } : {}
668
+ } } : {}
669
+ };
670
+ }
671
+ function formatCheckStatus(status) {
672
+ if (status === "pass") return pc.green("ok");
673
+ if (status === "warn") return pc.yellow("warn");
674
+ return pc.red("fail");
675
+ }
676
+ function countChecks(checks, status) {
677
+ return checks.filter((check) => check.status === status).length;
678
+ }
679
+ function resolveCloudCheckTargets(options) {
680
+ const targets = new Set(options.checkTargets);
681
+ if (targets.size > 0) return targets;
682
+ return new Set(CLOUD_CHECK_TARGETS);
683
+ }
684
+ function formatCloudCheckTargets(targets) {
685
+ return targets.join(", ");
686
+ }
596
687
  function resolveApiBaseUrl(options) {
597
688
  return (options.apiBaseUrl ?? process.env.DOCS_CLOUD_API_URL ?? process.env.NEXT_PUBLIC_DOCS_CLOUD_URL ?? DEFAULT_DOCS_CLOUD_API_BASE_URL).replace(/\/+$/, "");
598
689
  }
@@ -849,6 +940,129 @@ function createSpinner(initialMessage, options = {}) {
849
940
  }
850
941
  };
851
942
  }
943
+ async function checkCloudConfig(options = {}) {
944
+ const rootDir = options.rootDir ?? process.cwd();
945
+ const docsJsonPath = path.join(rootDir, DOCS_JSON_FILE);
946
+ const existing = readExistingDocsJson(docsJsonPath);
947
+ const snapshot = await loadDocsConfigSnapshot(rootDir, options.configPath);
948
+ const config = materializeDocsJsonObject({
949
+ rootDir,
950
+ snapshot,
951
+ existing
952
+ });
953
+ const serialized = serializeMaterializedDocsJson(config);
954
+ const previous = existing ? fs.readFileSync(docsJsonPath, "utf-8") : void 0;
955
+ const apiBaseUrl = resolveApiBaseUrl(options);
956
+ const apiKeyEnv = config.cloud?.apiKey?.env ?? DOCS_CLOUD_DEFAULT_API_KEY_ENV;
957
+ const env = readCombinedEnv(rootDir);
958
+ const checks = [];
959
+ const configPath = snapshot.path ?? docsJsonPath;
960
+ const network = options.network !== false;
961
+ const explicitApiKey = options.apiKey?.trim();
962
+ const targetSet = resolveCloudCheckTargets(options);
963
+ const targets = CLOUD_CHECK_TARGETS.filter((target) => targetSet.has(target));
964
+ const checkDeploy = targetSet.has("deploy");
965
+ const checkAnalytics = targetSet.has("analytics");
966
+ const checkAskAi = targetSet.has("ask-ai");
967
+ const checkProjectEnv = checkAnalytics || checkAskAi;
968
+ let identity;
969
+ checks.push(createCheck("config", snapshot.path ? "pass" : "warn", snapshot.path ? `Loaded ${path.relative(rootDir, snapshot.path) || "docs.config.ts"}` : `No docs.config.* found; checking ${DOCS_JSON_FILE} defaults instead.`));
970
+ checks.push(createCheck("docs.json", !existing ? "warn" : previous === serialized ? "pass" : "warn", !existing ? `${DOCS_JSON_FILE} is missing. Run docs cloud sync to materialize cloud config.` : previous === serialized ? `${DOCS_JSON_FILE} is in sync with docs.config.` : `${DOCS_JSON_FILE} is stale. Run docs cloud sync before deploying.`));
971
+ const apiKey = explicitApiKey || readEnvValue(env, apiKeyEnv);
972
+ if (checkDeploy) {
973
+ try {
974
+ normalizeEnvName(apiKeyEnv, DOCS_CLOUD_DEFAULT_API_KEY_ENV);
975
+ checks.push(createCheck("apiKey.config", "pass", `Using cloud.apiKey.env ${apiKeyEnv}.`));
976
+ } catch (error) {
977
+ checks.push(createCheck("apiKey.config", "fail", error instanceof Error ? error.message : `Invalid API key env ${apiKeyEnv}.`));
978
+ }
979
+ checks.push(createCheck("apiKey.value", apiKey ? "pass" : "fail", apiKey ? explicitApiKey ? "Docs Cloud API key was provided with --api-key." : `Docs Cloud API key is present in ${apiKeyEnv}.` : `Missing Docs Cloud API key. Set ${apiKeyEnv} or pass --api-key.`, {
980
+ env: apiKeyEnv,
981
+ source: explicitApiKey ? "flag" : apiKey ? "env" : "missing"
982
+ }));
983
+ }
984
+ checks.push(createCheck("cloud.enabled", config.cloud?.enabled === false ? "fail" : "pass", config.cloud?.enabled === false ? "Docs Cloud is disabled by cloud.enabled: false." : "Docs Cloud is enabled."));
985
+ if (checkDeploy) {
986
+ if (config.cloud?.deploy?.enabled === false) checks.push(createCheck("deploy.enabled", "fail", "Docs Cloud deployment is disabled by cloud.deploy.enabled: false."));
987
+ else checks.push(createCheck("deploy.enabled", "pass", "Docs Cloud deployment is enabled."));
988
+ if (config.cloud?.preview?.enabled === false) checks.push(createCheck("preview.enabled", "fail", "Docs Cloud preview deployment is disabled by cloud.preview.enabled: false."));
989
+ }
990
+ const runtimeAnalyticsDisabled = readRuntimeAnalyticsDisabled(snapshot);
991
+ const cloudAnalyticsEnabled = isCloudAnalyticsEnabled(config.cloud?.analytics);
992
+ if (checkAnalytics) {
993
+ if (runtimeAnalyticsDisabled) checks.push(createCheck("analytics.runtime", "fail", "Runtime analytics is disabled by analytics: false or analytics.enabled: false."));
994
+ else checks.push(createCheck("analytics.runtime", "pass", "Runtime analytics is not disabled."));
995
+ checks.push(createCheck("analytics.cloud", cloudAnalyticsEnabled ? "pass" : "warn", cloudAnalyticsEnabled ? "Docs Cloud analytics is enabled in cloud.analytics." : "cloud.analytics is not enabled; run docs cloud init to add the recommended analytics config."));
996
+ }
997
+ const projectEnv = readFirstEnv(env, DOCS_CLOUD_PROJECT_ID_ENVS);
998
+ const analyticsNeedsProjectId = cloudAnalyticsEnabled && !runtimeAnalyticsDisabled;
999
+ if (checkProjectEnv) checks.push(createCheck("project.env", projectEnv ? "pass" : analyticsNeedsProjectId || checkAskAi ? "fail" : "warn", projectEnv ? `Docs Cloud project id is present in ${projectEnv.name}.` : `Missing Docs Cloud project id. Set ${DOCS_CLOUD_PROJECT_ID_ENVS.join(" or ")} for analytics and docs-cloud Ask AI.`, projectEnv ? { env: projectEnv.name } : void 0));
1000
+ const aiProvider = readAiProvider(snapshot);
1001
+ if (checkAskAi) if (aiProvider === "docs-cloud") {
1002
+ checks.push(createCheck("askAi.provider", "pass", "Ask AI is configured with provider: \"docs-cloud\"."));
1003
+ const configuredApiKeyEnv = readConfiguredCloudApiKeyEnv(snapshot);
1004
+ const directApiKeyEnv = configuredApiKeyEnv ? configuredApiKeyEnv.startsWith("NEXT_PUBLIC_") ? configuredApiKeyEnv : void 0 : DEFAULT_PUBLIC_DOCS_CLOUD_API_KEY_ENV;
1005
+ const directApiKey = readEnvValue(env, directApiKeyEnv);
1006
+ if (directApiKeyEnv) checks.push(createCheck("askAi.direct", directApiKey && projectEnv ? "pass" : "fail", directApiKey && projectEnv ? `Ask AI can call the Docs Cloud knowledge endpoint directly with ${directApiKeyEnv}.` : `Ask AI docs-cloud direct mode needs ${directApiKeyEnv} and a Docs Cloud project id.`, { apiKeyEnv: directApiKeyEnv }));
1007
+ } else if (aiProvider) checks.push(createCheck("askAi.provider", "pass", `Ask AI provider is ${aiProvider}.`));
1008
+ else checks.push(createCheck("askAi.provider", "warn", "Ask AI is not configured with provider: \"docs-cloud\"."));
1009
+ if (checkDeploy) if (!network) checks.push(createCheck("apiKey.network", "warn", "Skipped Docs Cloud API validation because --no-network was passed."));
1010
+ else if (!apiKey) checks.push(createCheck("apiKey.network", "warn", "Skipped Docs Cloud API validation because no API key value was available."));
1011
+ else try {
1012
+ const response = await fetchCloudJson({
1013
+ url: `${apiBaseUrl}/api/cloud/me`,
1014
+ apiKey
1015
+ });
1016
+ identity = summarizeIdentity(response);
1017
+ checks.push(createCheck("apiKey.network", "pass", `Validated API key with ${apiBaseUrl}.`, identity));
1018
+ const scopes = readApiKeyScopes(response);
1019
+ if (scopes.length === 0) checks.push(createCheck("apiKey.scopes", "warn", "Docs Cloud validated the API key but did not return scope metadata."));
1020
+ else {
1021
+ const missing = REQUIRED_PREVIEW_API_KEY_SCOPES.filter((scope) => !scopes.includes(scope));
1022
+ checks.push(createCheck("apiKey.scopes", missing.length === 0 ? "pass" : "fail", missing.length === 0 ? `API key has required deploy scopes: ${REQUIRED_PREVIEW_API_KEY_SCOPES.join(", ")}.` : `API key is missing required deploy scope${missing.length === 1 ? "" : "s"}: ${missing.join(", ")}.`, { scopes }));
1023
+ }
1024
+ } catch (error) {
1025
+ checks.push(createCheck("apiKey.network", "fail", error instanceof Error ? error.message : "Could not validate Docs Cloud API key."));
1026
+ }
1027
+ return {
1028
+ ok: countChecks(checks, "fail") === 0,
1029
+ apiBaseUrl,
1030
+ configPath,
1031
+ docsJsonPath,
1032
+ apiKeyEnv,
1033
+ analyticsProjectIdEnv: projectEnv?.name,
1034
+ network,
1035
+ targets,
1036
+ checks,
1037
+ ...identity ? { identity } : {}
1038
+ };
1039
+ }
1040
+ async function runCloudCheck(options = {}) {
1041
+ const result = await checkCloudConfig(options);
1042
+ if (options.json) console.log(JSON.stringify(result, null, 2));
1043
+ else {
1044
+ console.log(pc.bold("Docs Cloud check"));
1045
+ console.log(`${pc.dim("api")} ${result.apiBaseUrl}`);
1046
+ console.log(`${pc.dim("scope")} ${formatCloudCheckTargets(result.targets)}`);
1047
+ console.log();
1048
+ for (const check of result.checks) console.log(`${formatCheckStatus(check.status)} ${pc.bold(check.name)} ${check.message}`);
1049
+ console.log();
1050
+ if (result.ok) {
1051
+ const warnings = countChecks(result.checks, "warn");
1052
+ const suffix = warnings > 0 ? ` with ${warnings} warning${warnings === 1 ? "" : "s"}` : "";
1053
+ console.log(`${pc.green("ok")} Docs Cloud check passed${suffix}.`);
1054
+ } else {
1055
+ const failures = countChecks(result.checks, "fail");
1056
+ console.log(`${pc.red("fail")} Docs Cloud check failed with ${failures} failed check${failures === 1 ? "" : "s"}.`);
1057
+ }
1058
+ }
1059
+ if (!result.ok) {
1060
+ const error = /* @__PURE__ */ new Error("Docs Cloud check failed.");
1061
+ markCliErrorReported(error);
1062
+ throw error;
1063
+ }
1064
+ return result;
1065
+ }
852
1066
  async function syncCloudConfig(options = {}) {
853
1067
  const result = await materializeCloudConfig(options);
854
1068
  if (options.json) {
@@ -970,6 +1184,7 @@ ${pc.bold("@farming-labs/docs cloud")}
970
1184
 
971
1185
  ${pc.dim("Usage:")}
972
1186
  ${pc.cyan("docs cloud init")} Add Docs Cloud config to ${pc.dim("docs.config.ts")} and ${pc.dim("docs.json")}
1187
+ ${pc.cyan("docs cloud check")} Validate Docs Cloud config, analytics envs, API key, and Ask AI wiring
973
1188
  ${pc.cyan("docs deploy")} Sync ${pc.dim("docs.config.ts")} to ${pc.dim("docs.json")} and deploy hosted preview docs
974
1189
  ${pc.cyan("docs cloud deploy")} Same as ${pc.cyan("docs deploy")}
975
1190
  ${pc.cyan("docs preview")} Compatibility alias for ${pc.cyan("docs deploy")}
@@ -981,6 +1196,10 @@ ${pc.dim("Options:")}
981
1196
  ${pc.cyan("--api-key-env <name>")} Env var that stores the Docs Cloud API key
982
1197
  ${pc.cyan("--api-base-url <url>")} Override Docs Cloud API base URL
983
1198
  ${pc.cyan("--api-key <key>")} Use an API key directly; prefer ${pc.dim("cloud.apiKey.env")}
1199
+ ${pc.cyan("--analytics")} Only check Docs Cloud analytics integration
1200
+ ${pc.cyan("--ask-ai")} Only check Docs Cloud Ask AI integration
1201
+ ${pc.cyan("--deploy")} Only check Docs Cloud deploy integration
1202
+ ${pc.cyan("--no-network")} Skip live Docs Cloud API validation for ${pc.cyan("cloud check")}
984
1203
  ${pc.cyan("--json")} Print machine-readable output
985
1204
 
986
1205
  ${pc.dim("API key scopes:")}
@@ -997,4 +1216,4 @@ ${pc.dim("Config example:")}
997
1216
  }
998
1217
 
999
1218
  //#endregion
1000
- export { initCloudConfig, printCloudHelp, runCloudDeploy, runCloudInit, runCloudPreview, syncCloudConfig };
1219
+ export { initCloudConfig, printCloudHelp, runCloudCheck, runCloudDeploy, runCloudInit, runCloudPreview, syncCloudConfig };
@@ -188,7 +188,7 @@ async function configureDocsCloudOnboarding(options) {
188
188
  enabled = cloudAnswer;
189
189
  }
190
190
  if (!enabled) return;
191
- const { initCloudConfig } = await import("./cloud-BBg-41RG.mjs");
191
+ const { initCloudConfig } = await import("./cloud-CHeiSRTt.mjs");
192
192
  printDocsCloudOnboardingInstructions(await initCloudConfig({
193
193
  rootDir: options.rootDir,
194
194
  configPath: getDocsCloudConfigPathForFramework(options.framework)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@farming-labs/docs",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Modern, flexible MDX-based docs framework — core types, config, and CLI",
5
5
  "keywords": [
6
6
  "docs",