@farming-labs/docs 0.2.87 → 0.2.89

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.
@@ -2,7 +2,7 @@ import { B as findDocsMarkdownPage, at as renderDocsMarkdownDocument } from "./a
2
2
  import { v as normalizePageAgentFrontmatter, x as stripGeneratedPageAgentContractMarkdown } from "./markdown-sections-7OoA7ylx.mjs";
3
3
  import { c as hashGeneratedAgentContent, d as serializeGeneratedAgentDocument, s as GENERATED_AGENT_PROVENANCE_VERSION, u as parseGeneratedAgentDocument } from "./content-change-hydration-DLBinuFR.mjs";
4
4
  import { createFilesystemDocsMcpSource } from "./mcp.mjs";
5
- import { _ as resolveDocsContentDir, a as loadDocsConfigModule, c as loadProjectEnv, d as readNavTitle, f as readNumberProperty, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral, u as readEnvReferenceProperty } from "./config-Wcdj-D0a.mjs";
5
+ import { _ as resolveDocsContentDir, a as loadDocsConfigModule, c as loadProjectEnv, d as readNavTitle, f as readNumberProperty, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral, u as readEnvReferenceProperty } from "./config-BtxaQTPP.mjs";
6
6
  import { createRequire } from "node:module";
7
7
  import matter from "gray-matter";
8
8
  import { existsSync, mkdirSync, readFileSync, readdirSync, statSync, writeFileSync } from "node:fs";
@@ -10,7 +10,7 @@ import "./agent-evals-DCptRrdP.mjs";
10
10
  import { createFilesystemDocsMcpSource, resolveDocsMcpConfig } from "./mcp.mjs";
11
11
  import "./code-blocks-0wjOsqdJ.mjs";
12
12
  import "./server.mjs";
13
- import { _ as resolveDocsContentDir, a as loadDocsConfigModule, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, m as readTopLevelBooleanProperty, p as readStringProperty, r as extractTopLevelConfigObject, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
13
+ import { _ as resolveDocsContentDir, a as loadDocsConfigModule, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, m as readTopLevelBooleanProperty, p as readStringProperty, r as extractTopLevelConfigObject, t as extractNestedObjectLiteral } from "./config-BtxaQTPP.mjs";
14
14
  import { t as detectFramework } from "./utils-DpiIioYb.mjs";
15
15
  import { existsSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, rmSync, writeFileSync } from "node:fs";
16
16
  import path from "node:path";
@@ -8,7 +8,7 @@ import "./agent-evals-DCptRrdP.mjs";
8
8
  import { resolveDocsMcpConfig } from "./mcp.mjs";
9
9
  import "./code-blocks-0wjOsqdJ.mjs";
10
10
  import "./server.mjs";
11
- import { a as loadDocsConfigModule, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
11
+ import { a as loadDocsConfigModule, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-BtxaQTPP.mjs";
12
12
  import { t as detectFramework } from "./utils-DpiIioYb.mjs";
13
13
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
14
14
  import path from "node:path";
@@ -108,43 +108,43 @@ async function main() {
108
108
  ]
109
109
  };
110
110
  if (!parsedCommand.command || parsedCommand.command === "init") {
111
- const { init } = await import("../init-D0GcUKJ0.mjs");
111
+ const { init } = await import("../init-CuLodGjP.mjs");
112
112
  await init(initOptions);
113
113
  } else if (parsedCommand.command === "dev") {
114
- const { dev } = await import("../dev-kjaxOOla.mjs");
114
+ const { dev } = await import("../dev-BFBPvjnk.mjs");
115
115
  await dev(devOptions);
116
116
  } else if (parsedCommand.command === "deploy") {
117
- const { runCloudDeploy } = await import("../cloud-pdNC-tyj.mjs");
117
+ const { runCloudDeploy } = await import("../cloud-DwhH_b_q.mjs");
118
118
  await runCloudDeploy(cloudOptions);
119
119
  } else if (parsedCommand.command === "preview") {
120
- const { runCloudPreview } = await import("../cloud-pdNC-tyj.mjs");
120
+ const { runCloudPreview } = await import("../cloud-DwhH_b_q.mjs");
121
121
  await runCloudPreview(cloudOptions);
122
122
  } else if (parsedCommand.command === "cloud" && subcommand === "deploy") {
123
- const { runCloudDeploy } = await import("../cloud-pdNC-tyj.mjs");
123
+ const { runCloudDeploy } = await import("../cloud-DwhH_b_q.mjs");
124
124
  await runCloudDeploy(cloudOptions);
125
125
  } else if (parsedCommand.command === "cloud" && subcommand === "preview") {
126
- const { runCloudPreview } = await import("../cloud-pdNC-tyj.mjs");
126
+ const { runCloudPreview } = await import("../cloud-DwhH_b_q.mjs");
127
127
  await runCloudPreview(cloudOptions);
128
128
  } else if (parsedCommand.command === "cloud" && subcommand === "init") {
129
- const { runCloudInit } = await import("../cloud-pdNC-tyj.mjs");
129
+ const { runCloudInit } = await import("../cloud-DwhH_b_q.mjs");
130
130
  await runCloudInit(cloudOptions);
131
131
  } else if (parsedCommand.command === "cloud" && subcommand === "sync") {
132
- const { syncCloudConfig } = await import("../cloud-pdNC-tyj.mjs");
132
+ const { syncCloudConfig } = await import("../cloud-DwhH_b_q.mjs");
133
133
  await syncCloudConfig(cloudOptions);
134
134
  } else if (parsedCommand.command === "cloud" && subcommand === "check") {
135
- const { runCloudCheck } = await import("../cloud-pdNC-tyj.mjs");
135
+ const { runCloudCheck } = await import("../cloud-DwhH_b_q.mjs");
136
136
  await runCloudCheck(cloudOptions);
137
137
  } else if (parsedCommand.command === "cloud") {
138
138
  console.error(pc.red(`Unknown cloud subcommand: ${subcommand ?? "(missing)"}`));
139
139
  console.error();
140
- const { printCloudHelp } = await import("../cloud-pdNC-tyj.mjs");
140
+ const { printCloudHelp } = await import("../cloud-DwhH_b_q.mjs");
141
141
  printCloudHelp();
142
142
  process.exit(1);
143
143
  } else if (parsedCommand.command === "mcp") {
144
- const { runMcp } = await import("../mcp-7bvRe9Da.mjs");
144
+ const { runMcp } = await import("../mcp-D8Hw2blN.mjs");
145
145
  await runMcp(mcpOptions);
146
146
  } else if (parsedCommand.command === "agent" && subcommand === "compact") {
147
- const { compactAgentDocs, parseAgentCompactArgs, printAgentCompactHelp } = await import("../agent-FyPQ2AZ4.mjs").then((n) => n.t);
147
+ const { compactAgentDocs, parseAgentCompactArgs, printAgentCompactHelp } = await import("../agent-Jvn1a78y.mjs").then((n) => n.t);
148
148
  const agentCompactOptions = parseAgentCompactArgs(args.slice(2));
149
149
  if (agentCompactOptions.help) {
150
150
  printAgentCompactHelp();
@@ -152,7 +152,7 @@ async function main() {
152
152
  }
153
153
  await compactAgentDocs(agentCompactOptions);
154
154
  } else if (parsedCommand.command === "agent" && subcommand === "export") {
155
- const { exportAgentBundle, parseAgentExportArgs, printAgentExportHelp } = await import("../agent-export-Di1Ofstb.mjs");
155
+ const { exportAgentBundle, parseAgentExportArgs, printAgentExportHelp } = await import("../agent-export-B4Xos6gi.mjs");
156
156
  const agentExportOptions = parseAgentExportArgs(args.slice(2));
157
157
  if (agentExportOptions.help) {
158
158
  printAgentExportHelp();
@@ -162,13 +162,13 @@ async function main() {
162
162
  } else if (parsedCommand.command === "agent") {
163
163
  console.error(pc.red(`Unknown agent subcommand: ${subcommand ?? "(missing)"}`));
164
164
  console.error();
165
- const { printAgentCompactHelp } = await import("../agent-FyPQ2AZ4.mjs").then((n) => n.t);
166
- const { printAgentExportHelp } = await import("../agent-export-Di1Ofstb.mjs");
165
+ const { printAgentCompactHelp } = await import("../agent-Jvn1a78y.mjs").then((n) => n.t);
166
+ const { printAgentExportHelp } = await import("../agent-export-B4Xos6gi.mjs");
167
167
  printAgentCompactHelp();
168
168
  printAgentExportHelp();
169
169
  process.exit(1);
170
170
  } else if (parsedCommand.command === "agents" && subcommand === "generate") {
171
- const { generateAgents, parseAgentsGenerateArgs, printAgentsGenerateHelp } = await import("../agents-DjUz5voa.mjs");
171
+ const { generateAgents, parseAgentsGenerateArgs, printAgentsGenerateHelp } = await import("../agents-DRCl1URL.mjs");
172
172
  const agentsOptions = parseAgentsGenerateArgs(args.slice(2));
173
173
  if (agentsOptions.help) {
174
174
  printAgentsGenerateHelp();
@@ -178,11 +178,11 @@ async function main() {
178
178
  } else if (parsedCommand.command === "agents") {
179
179
  console.error(pc.red(`Unknown agents subcommand: ${subcommand ?? "(missing)"}`));
180
180
  console.error();
181
- const { printAgentsGenerateHelp } = await import("../agents-DjUz5voa.mjs");
181
+ const { printAgentsGenerateHelp } = await import("../agents-DRCl1URL.mjs");
182
182
  printAgentsGenerateHelp();
183
183
  process.exit(1);
184
184
  } else if (parsedCommand.command === "skills" && subcommand === "scaffold") {
185
- const { parseSkillScaffoldArgs, printSkillScaffoldHelp, scaffoldSkillFromContracts } = await import("../skills-CPDwsMq4.mjs");
185
+ const { parseSkillScaffoldArgs, printSkillScaffoldHelp, scaffoldSkillFromContracts } = await import("../skills-35ecRZtd.mjs");
186
186
  const skillOptions = parseSkillScaffoldArgs(args.slice(2));
187
187
  if (skillOptions.help) {
188
188
  printSkillScaffoldHelp();
@@ -190,16 +190,16 @@ async function main() {
190
190
  }
191
191
  await scaffoldSkillFromContracts(skillOptions);
192
192
  } else if (parsedCommand.command === "skills" && (subcommand === "--help" || subcommand === "-h")) {
193
- const { printSkillScaffoldHelp } = await import("../skills-CPDwsMq4.mjs");
193
+ const { printSkillScaffoldHelp } = await import("../skills-35ecRZtd.mjs");
194
194
  printSkillScaffoldHelp();
195
195
  } else if (parsedCommand.command === "skills") {
196
196
  console.error(pc.red(`Unknown skills subcommand: ${subcommand ?? "(missing)"}`));
197
197
  console.error();
198
- const { printSkillScaffoldHelp } = await import("../skills-CPDwsMq4.mjs");
198
+ const { printSkillScaffoldHelp } = await import("../skills-35ecRZtd.mjs");
199
199
  printSkillScaffoldHelp();
200
200
  process.exit(1);
201
201
  } else if (parsedCommand.command === "doctor") {
202
- const { parseDoctorArgs, printDoctorHelp, runDoctor } = await import("../doctor-DUnOjP9T.mjs");
202
+ const { parseDoctorArgs, printDoctorHelp, runDoctor } = await import("../doctor-C3IG5hqb.mjs");
203
203
  const doctorOptions = parseDoctorArgs(args.slice(1));
204
204
  if (doctorOptions.help) {
205
205
  printDoctorHelp();
@@ -207,7 +207,7 @@ async function main() {
207
207
  }
208
208
  await runDoctor(doctorOptions);
209
209
  } else if (parsedCommand.command === "review") {
210
- const { parseReviewArgs, printReviewHelp, runReview } = await import("../review-DEnzotkg.mjs");
210
+ const { parseReviewArgs, printReviewHelp, runReview } = await import("../review-R39cQsvi.mjs");
211
211
  const reviewOptions = parseReviewArgs(args.slice(1));
212
212
  if (reviewOptions.help) {
213
213
  printReviewHelp();
@@ -215,7 +215,7 @@ async function main() {
215
215
  }
216
216
  await runReview(reviewOptions);
217
217
  } else if ((parsedCommand.command === "codeblocks" || parsedCommand.command === "code-blocks") && subcommand === "validate") {
218
- const { parseCodeBlocksValidateArgs, printCodeBlocksValidateHelp, runCodeBlocksValidate } = await import("../codeblocks-CPA6Ae5r.mjs");
218
+ const { parseCodeBlocksValidateArgs, printCodeBlocksValidateHelp, runCodeBlocksValidate } = await import("../codeblocks-B5lsz3sx.mjs");
219
219
  const codeBlocksOptions = parseCodeBlocksValidateArgs(args.slice(2));
220
220
  if (codeBlocksOptions.help) {
221
221
  printCodeBlocksValidateHelp();
@@ -225,11 +225,11 @@ async function main() {
225
225
  } else if (parsedCommand.command === "codeblocks" || parsedCommand.command === "code-blocks") {
226
226
  console.error(pc.red(`Unknown codeblocks subcommand: ${subcommand ?? "(missing)"}`));
227
227
  console.error();
228
- const { printCodeBlocksValidateHelp } = await import("../codeblocks-CPA6Ae5r.mjs");
228
+ const { printCodeBlocksValidateHelp } = await import("../codeblocks-B5lsz3sx.mjs");
229
229
  printCodeBlocksValidateHelp();
230
230
  process.exit(1);
231
231
  } else if (parsedCommand.command === "search" && subcommand === "sync") {
232
- const { syncSearch } = await import("../search-DznddPqw.mjs");
232
+ const { syncSearch } = await import("../search-3TUBKtz5.mjs");
233
233
  await syncSearch(searchSyncOptions);
234
234
  } else if (parsedCommand.command === "search") {
235
235
  console.error(pc.red(`Unknown search subcommand: ${subcommand ?? "(missing)"}`));
@@ -237,7 +237,7 @@ async function main() {
237
237
  printHelp();
238
238
  process.exit(1);
239
239
  } else if (parsedCommand.command === "sitemap" && subcommand === "generate") {
240
- const { generateSitemap, parseSitemapGenerateArgs, printSitemapGenerateHelp } = await import("../sitemap-DCsrVSPf.mjs");
240
+ const { generateSitemap, parseSitemapGenerateArgs, printSitemapGenerateHelp } = await import("../sitemap-DrILEtYo.mjs");
241
241
  const sitemapOptions = parseSitemapGenerateArgs(args.slice(2));
242
242
  if (sitemapOptions.help) {
243
243
  printSitemapGenerateHelp();
@@ -247,11 +247,11 @@ async function main() {
247
247
  } else if (parsedCommand.command === "sitemap") {
248
248
  console.error(pc.red(`Unknown sitemap subcommand: ${subcommand ?? "(missing)"}`));
249
249
  console.error();
250
- const { printSitemapGenerateHelp } = await import("../sitemap-DCsrVSPf.mjs");
250
+ const { printSitemapGenerateHelp } = await import("../sitemap-DrILEtYo.mjs");
251
251
  printSitemapGenerateHelp();
252
252
  process.exit(1);
253
253
  } else if (parsedCommand.command === "robots" && subcommand === "generate") {
254
- const { generateRobots, parseRobotsGenerateArgs, printRobotsGenerateHelp } = await import("../robots-DXy1xW3D.mjs");
254
+ const { generateRobots, parseRobotsGenerateArgs, printRobotsGenerateHelp } = await import("../robots-C-Nh0xH6.mjs");
255
255
  const robotsOptions = parseRobotsGenerateArgs(args.slice(2));
256
256
  if (robotsOptions.help) {
257
257
  printRobotsGenerateHelp();
@@ -261,7 +261,7 @@ async function main() {
261
261
  } else if (parsedCommand.command === "robots") {
262
262
  console.error(pc.red(`Unknown robots subcommand: ${subcommand ?? "(missing)"}`));
263
263
  console.error();
264
- const { printRobotsGenerateHelp } = await import("../robots-DXy1xW3D.mjs");
264
+ const { printRobotsGenerateHelp } = await import("../robots-C-Nh0xH6.mjs");
265
265
  printRobotsGenerateHelp();
266
266
  process.exit(1);
267
267
  } else if (parsedCommand.command === "downgrade") {
@@ -398,6 +398,8 @@ ${pc.dim("Options for doctor:")}
398
398
  ${pc.cyan("doctor --site")} Score the current docs app for reader-facing docs quality
399
399
  ${pc.cyan("doctor --human")} Alias for ${pc.cyan("doctor --site")}
400
400
  ${pc.cyan("doctor --json")} Print the report as JSON for CI, scripts, and automation
401
+ ${pc.cyan("doctor --json-output <path>")} Write the JSON report to a file, including alongside ${pc.cyan("--ci")}
402
+ ${pc.cyan("doctor --ci")} Emit actionable GitHub annotations in GitHub Actions
401
403
  ${pc.cyan("doctor --strict")} Exit with failure when any doctor check warns or fails
402
404
  ${pc.cyan("doctor --agent --fix")} Refresh stale generated ${pc.dim("agent.md")} files and token-budget missing outputs
403
405
  ${pc.cyan("doctor --agent --fix --dry-run")} Report the fix command without writing generated ${pc.dim("agent.md")} files
@@ -1,5 +1,5 @@
1
1
  import { n as markCliErrorReported } from "./errors-DbOhkE1h.mjs";
2
- import { _ as resolveDocsContentDir, a as loadDocsConfigModule, c as loadProjectEnv, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, m as readTopLevelBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
2
+ import { _ as resolveDocsContentDir, a as loadDocsConfigModule, c as loadProjectEnv, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, m as readTopLevelBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-BtxaQTPP.mjs";
3
3
  import { i as detectPackageManagerFromProject, t as detectFramework } from "./utils-DpiIioYb.mjs";
4
4
  import fs from "node:fs";
5
5
  import path from "node:path";
@@ -1,5 +1,5 @@
1
1
  import { a as validateCodeBlocks, r as resolveDocsCodeBlocksValidateConfig } from "./code-blocks-0wjOsqdJ.mjs";
2
- import { _ as resolveDocsContentDir, a as loadDocsConfigModule, f as readNumberProperty, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
2
+ import { _ as resolveDocsContentDir, a as loadDocsConfigModule, f as readNumberProperty, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, p as readStringProperty, t as extractNestedObjectLiteral } from "./config-BtxaQTPP.mjs";
3
3
  import { existsSync, readFileSync } from "node:fs";
4
4
  import pc from "picocolors";
5
5
 
@@ -82,6 +82,31 @@ function resolveDocsConfigPath(rootDir, explicitPath) {
82
82
  }
83
83
  throw new Error("Could not find docs.config.ts or docs.config.tsx in the current project. Use --config to point at a custom path.");
84
84
  }
85
+ /**
86
+ * Resolve the application root that owns a docs config selected from another
87
+ * working directory. This keeps config-relative paths anchored to a nested
88
+ * workspace package without changing the behavior of configs stored below a
89
+ * project's root (for example, src/lib/docs.config.ts).
90
+ */
91
+ function resolveDocsProjectRoot(rootDir, configPath) {
92
+ const invocationRoot = resolve(rootDir);
93
+ const configDir = dirname(resolve(configPath));
94
+ const relativeConfigDir = relative(invocationRoot, configDir);
95
+ const configIsInsideInvocationRoot = relativeConfigDir === "" || relativeConfigDir !== ".." && !relativeConfigDir.startsWith(`..${sep}`);
96
+ const fallbackRoot = configIsInsideInvocationRoot ? invocationRoot : configDir;
97
+ let currentDir = configDir;
98
+ while (true) {
99
+ if (existsSync(join(currentDir, "package.json"))) return currentDir;
100
+ if (configIsInsideInvocationRoot && currentDir === invocationRoot) return invocationRoot;
101
+ const parentDir = dirname(currentDir);
102
+ if (parentDir === currentDir) return fallbackRoot;
103
+ if (configIsInsideInvocationRoot) {
104
+ const relativeParent = relative(invocationRoot, parentDir);
105
+ if (relativeParent === ".." || relativeParent.startsWith(`..${sep}`)) return invocationRoot;
106
+ }
107
+ currentDir = parentDir;
108
+ }
109
+ }
85
110
  function readStringProperty(content, key) {
86
111
  return content.match(createPropertyPattern(key, `["']([^"']+)["']`))?.[1];
87
112
  }
@@ -366,4 +391,4 @@ async function loadDocsConfigModuleResultWithProjectEnv(rootDir, explicitPath, o
366
391
  }
367
392
 
368
393
  //#endregion
369
- export { resolveDocsContentDir as _, loadDocsConfigModule as a, loadProjectEnv as c, readNavTitle as d, readNumberProperty as f, resolveDocsConfigPath as g, readTopLevelStringProperty as h, hasTopLevelProperty as i, readBooleanProperty as l, readTopLevelBooleanProperty as m, extractObjectLiteral as n, loadDocsConfigModuleResult as o, readStringProperty as p, extractTopLevelConfigObject as r, loadDocsConfigModuleResultWithProjectEnv as s, extractNestedObjectLiteral as t, readEnvReferenceProperty as u };
394
+ export { resolveDocsContentDir as _, loadDocsConfigModule as a, loadProjectEnv as c, readNavTitle as d, readNumberProperty as f, resolveDocsConfigPath as g, readTopLevelStringProperty as h, hasTopLevelProperty as i, readBooleanProperty as l, readTopLevelBooleanProperty as m, extractObjectLiteral as n, loadDocsConfigModuleResult as o, readStringProperty as p, extractTopLevelConfigObject as r, loadDocsConfigModuleResultWithProjectEnv as s, extractNestedObjectLiteral as t, readEnvReferenceProperty as u, resolveDocsProjectRoot as v };
@@ -1,5 +1,5 @@
1
1
  import { i as detectPackageManagerFromProject } from "./utils-DpiIioYb.mjs";
2
- import { Ct as tsconfigTemplate, Y as rootLayoutTemplate, g as docsLayoutTemplate, q as postcssConfigTemplate, v as globalCssTemplate } from "./templates-C6avM0U3.mjs";
2
+ import { Ct as tsconfigTemplate, Y as rootLayoutTemplate, g as docsLayoutTemplate, q as postcssConfigTemplate, v as globalCssTemplate } from "./templates-Co7I_Okv.mjs";
3
3
  import fs from "node:fs";
4
4
  import path from "node:path";
5
5
  import { spawn } from "node:child_process";
@@ -141,6 +141,12 @@ const THEME_PRESETS = {
141
141
  importPath: "@farming-labs/theme/ledger",
142
142
  factory: "ledger"
143
143
  },
144
+ shadcn: {
145
+ configName: "shadcn",
146
+ templateTheme: "shadcn",
147
+ importPath: "@farming-labs/theme/shadcn",
148
+ factory: "shadcn"
149
+ },
144
150
  greentree: {
145
151
  configName: "greentree",
146
152
  templateTheme: "greentree",
@@ -1,4 +1,4 @@
1
- import { i as scanDocsPageTargets, n as compactAgentDocs, r as inspectAgentCompactionState } from "./agent-FyPQ2AZ4.mjs";
1
+ import { i as scanDocsPageTargets, n as compactAgentDocs, r as inspectAgentCompactionState } from "./agent-Jvn1a78y.mjs";
2
2
  import { d as httpLinkHeaderHasTargetRelation, f as AGENT_SKILL_ARCHIVE_MAX_UNCOMPRESSED_BYTES, p as readAgentSkillDocumentFromTar } from "./prompt-references-B6gxePm8.mjs";
3
3
  import { A as buildDocsAgentDiscoverySpec, At as DEFAULT_SITEMAP_XML_ROUTE, F as buildDocsMcpEndpointCandidates, Gn as getDocsMcpProtectedResourceMetadataRoutes, It as resolveDocsSitemapConfig, Jn as isDocsMcpOAuthScopeToken, M as buildDocsConfigMap, Ot as DEFAULT_SITEMAP_MD_ROUTE, Qn as normalizeDocsMcpAuthorizationServerUrls, S as DEFAULT_SKILL_MD_WELL_KNOWN_ROUTE, T as DOCS_CONFIG_MAP_TOP_LEVEL_KEYS, Un as DEFAULT_MCP_WELL_KNOWN_ROUTE, Vn as DEFAULT_MCP_PUBLIC_ROUTE, c as DEFAULT_AGENT_SPEC_WELL_KNOWN_JSON_ROUTE, h as DEFAULT_LLMS_FULL_TXT_ROUTE, i as DEFAULT_AGENT_FEEDBACK_ROUTE, kt as DEFAULT_SITEMAP_MD_WELL_KNOWN_ROUTE, l as DEFAULT_AGENT_SPEC_WELL_KNOWN_ROUTE, n as DEFAULT_AGENTS_MD_WELL_KNOWN_ROUTE, pn as resolveAskAISearchRequestConfig, t as DEFAULT_AGENTS_MD_ROUTE, v as DEFAULT_LLMS_TXT_ROUTE, x as DEFAULT_SKILL_MD_ROUTE } from "./agent-CTOUI2BK.mjs";
4
4
  import { f as PAGE_AGENT_CONTRACT_FIELDS } from "./markdown-sections-7OoA7ylx.mjs";
@@ -13,11 +13,11 @@ import { t as runDocsGoldenTasks } from "./agent-evals-DCptRrdP.mjs";
13
13
  import { createFilesystemDocsMcpSource, getDocsConfigSchema, resolveDocsMcpConfig } from "./mcp.mjs";
14
14
  import "./code-blocks-0wjOsqdJ.mjs";
15
15
  import "./server.mjs";
16
- import { _ as resolveDocsContentDir, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, r as extractTopLevelConfigObject, s as loadDocsConfigModuleResultWithProjectEnv, t as extractNestedObjectLiteral } from "./config-Wcdj-D0a.mjs";
16
+ import { _ as resolveDocsContentDir, d as readNavTitle, g as resolveDocsConfigPath, h as readTopLevelStringProperty, l as readBooleanProperty, r as extractTopLevelConfigObject, s as loadDocsConfigModuleResultWithProjectEnv, t as extractNestedObjectLiteral, v as resolveDocsProjectRoot } from "./config-BtxaQTPP.mjs";
17
17
  import { t as detectFramework } from "./utils-DpiIioYb.mjs";
18
- import { i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-CNDwoUOe.mjs";
18
+ import { i as createAgentUsefulnessPagesFromMcp, n as analyzeAgentSurfaceDrift, r as analyzeAgentUsefulness, t as resolveGoldenEvaluationInput } from "./golden-evaluations-DyeYD50F.mjs";
19
19
  import { t as analyzeConfiguredAgentSkillsProgressiveDisclosure } from "./agent-skills-progressive-disclosure-BVvj7nM8.mjs";
20
- import { existsSync, lstatSync, readFileSync, readdirSync } from "node:fs";
20
+ import { existsSync, lstatSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
21
21
  import path from "node:path";
22
22
  import { createHash } from "node:crypto";
23
23
  import { gunzipSync } from "node:zlib";
@@ -73,6 +73,23 @@ function parseDoctorArgs(argv) {
73
73
  parsed.json = true;
74
74
  continue;
75
75
  }
76
+ if (arg.startsWith("--json-output=")) {
77
+ const value = parseInlineFlag(arg).value;
78
+ if (!value) throw new Error("Missing value for --json-output.");
79
+ parsed.jsonOutputPath = value;
80
+ continue;
81
+ }
82
+ if (arg === "--json-output") {
83
+ const value = argv[index + 1];
84
+ if (!value || value.startsWith("--")) throw new Error("Missing value for --json-output.");
85
+ parsed.jsonOutputPath = value;
86
+ index += 1;
87
+ continue;
88
+ }
89
+ if (arg === "--ci") {
90
+ parsed.ci = true;
91
+ continue;
92
+ }
76
93
  if (arg === "--strict") {
77
94
  parsed.strict = true;
78
95
  continue;
@@ -170,6 +187,8 @@ ${pc.dim("Options:")}
170
187
  ${pc.cyan("--human")} Alias for ${pc.cyan("--site")}
171
188
  ${pc.cyan("--only <mode>")} Run only one doctor suite: ${pc.cyan("agent")} or ${pc.cyan("site")}
172
189
  ${pc.cyan("--json")} Print the report as JSON for CI, scripts, and other agents
190
+ ${pc.cyan("--json-output <path>")} Write the JSON report to a file; use with ${pc.cyan("--ci")} to keep annotation stdout valid
191
+ ${pc.cyan("--ci")} Emit actionable GitHub annotations when running in GitHub Actions
173
192
  ${pc.cyan("--strict")} Exit with failure when any check warns or fails
174
193
  ${pc.cyan("--fix")} Refresh stale generated agent.md files and token-budget missing outputs
175
194
  ${pc.cyan("--dry-run")} With ${pc.cyan("--fix")}, report the compaction command without writing files
@@ -1631,7 +1650,7 @@ async function buildHostedAgentChecks(url, pages) {
1631
1650
  checks
1632
1651
  };
1633
1652
  }
1634
- function makeCheck(id, title, status, score, maxScore, detail, recommendation) {
1653
+ function makeCheck(id, title, status, score, maxScore, detail, recommendation, findings) {
1635
1654
  return {
1636
1655
  id,
1637
1656
  title,
@@ -1639,19 +1658,38 @@ function makeCheck(id, title, status, score, maxScore, detail, recommendation) {
1639
1658
  score,
1640
1659
  maxScore,
1641
1660
  detail,
1642
- recommendation
1643
- };
1661
+ recommendation,
1662
+ findings
1663
+ };
1664
+ }
1665
+ function toDoctorCommandFindings(findings) {
1666
+ return findings.filter((finding) => finding.category === "command" && Boolean(finding.command) && Boolean(finding.proposedCorrection)).map((finding) => ({
1667
+ code: finding.code,
1668
+ severity: finding.severity,
1669
+ file: finding.file,
1670
+ line: finding.line,
1671
+ command: finding.command,
1672
+ reason: finding.message,
1673
+ proposedCorrection: finding.proposedCorrection
1674
+ }));
1644
1675
  }
1645
1676
  async function inspectAgentReadiness(options = {}) {
1646
- const rootDir = process.cwd();
1647
- const files = listProjectFiles(rootDir);
1648
- const framework = detectFramework(rootDir) ?? detectFrameworkFromFiles(files) ?? "unknown";
1677
+ const invocationRoot = process.cwd();
1678
+ let rootDir = invocationRoot;
1679
+ let files = [];
1680
+ let framework = "unknown";
1649
1681
  const configCheckMax = 10;
1650
1682
  let configPath;
1651
1683
  try {
1652
- configPath = resolveDocsConfigPath(rootDir, options.configPath);
1684
+ configPath = resolveDocsConfigPath(invocationRoot, options.configPath);
1685
+ rootDir = resolveDocsProjectRoot(invocationRoot, configPath);
1686
+ files = listProjectFiles(rootDir);
1687
+ framework = detectFramework(rootDir) ?? detectFrameworkFromFiles(files) ?? "unknown";
1653
1688
  } catch (error) {
1654
- const checks = [makeCheck("config", "Docs config", "fail", 0, configCheckMax, error instanceof Error ? error.message : String(error), "Add docs.config.ts[x] or pass --config so the doctor can inspect the docs app.")];
1689
+ const message = error instanceof Error ? error.message : String(error);
1690
+ const invocationFiles = listProjectFiles(invocationRoot);
1691
+ framework = detectFramework(invocationRoot) ?? detectFrameworkFromFiles(invocationFiles) ?? "unknown";
1692
+ const checks = [makeCheck("config", "Docs config", "fail", 0, configCheckMax, message, "Add docs.config.ts[x] or pass --config so the doctor can inspect the docs app.")];
1655
1693
  return {
1656
1694
  mode: "agent",
1657
1695
  framework,
@@ -1678,7 +1716,7 @@ async function inspectAgentReadiness(options = {}) {
1678
1716
  };
1679
1717
  }
1680
1718
  const configContent = readFileSync(configPath, "utf-8");
1681
- const configLoad = await loadDocsConfigModuleResultWithProjectEnv(rootDir, options.configPath);
1719
+ const configLoad = await loadDocsConfigModuleResultWithProjectEnv(rootDir, configPath);
1682
1720
  const config = configLoad.status === "evaluated" ? configLoad.config : void 0;
1683
1721
  let configuredAgentSkillNames;
1684
1722
  let configuredAgentSkillsError;
@@ -1727,6 +1765,7 @@ async function inspectAgentReadiness(options = {}) {
1727
1765
  pages: createAgentUsefulnessPagesFromMcp(rootDir, pages),
1728
1766
  projectFramework: framework === "unknown" ? void 0 : framework
1729
1767
  });
1768
+ const commandFindings = toDoctorCommandFindings(usefulness.findings);
1730
1769
  const evaluationInput = config?.agent?.evaluations;
1731
1770
  const evaluation = resolveGoldenEvaluationInput(evaluationInput);
1732
1771
  const evaluationBaseUrl = config ? resolveDocsMetadataBaseUrl(config) : void 0;
@@ -1874,7 +1913,7 @@ async function inspectAgentReadiness(options = {}) {
1874
1913
  checks.push(makeCheck("agent-context-quality", "Agent context usefulness", contextQualityResult.status, contextQualityResult.score, 15, usefulness.metrics.agentBlocks.total > 0 ? `${usefulness.metrics.agentBlocks.useful}/${usefulness.metrics.agentBlocks.total} agent-only blocks are specific and non-repetitive (${usefulness.metrics.agentBlocks.duplicate} duplicate, ${usefulness.metrics.agentBlocks.boilerplate} boilerplate, ${usefulness.metrics.agentBlocks.generic} generic).` : "No embedded agent-only blocks were present; page contracts and sibling agent.md files remain available as alternatives.", usefulness.metrics.agentBlocks.total > 0 && usefulness.metrics.agentBlocks.useful === usefulness.metrics.agentBlocks.total ? void 0 : "Replace repeated agent-only boilerplate with page-specific constraints, commands, files, expected results, and recovery guidance."));
1875
1914
  checks.push(makeCheck("agent-task-completeness", "Agent task completeness", taskCompletenessResult.status, taskCompletenessResult.score, 15, `${usefulness.metrics.taskCompleteness.completePages}/${usefulness.metrics.actionablePages} actionable pages include prerequisites, an expected result, and recovery guidance (${usefulness.metrics.taskCompleteness.coverage}% complete).`, usefulness.metrics.actionablePages > 0 && usefulness.metrics.taskCompleteness.coverage >= 80 ? void 0 : "Add prerequisites, observable outcomes or verification expectations, and rollback or resolved failure modes to actionable pages."));
1876
1915
  checks.push(makeCheck("agent-applicability", "Framework and version applicability", applicabilityResult.status, applicabilityResult.score, 10, `${usefulness.metrics.applicability.conflictingPages} conflicting, ${usefulness.metrics.applicability.ambiguousPages} ambiguous, and ${usefulness.metrics.applicability.mismatchedPages} project-mismatched actionable pages.`, usefulness.metrics.actionablePages > 0 && applicabilityIssueCount === 0 ? void 0 : "Declare consistent framework/version metadata in page frontmatter and agent.appliesTo so retrieval can select the right variant."));
1877
- checks.push(makeCheck("command-health", "Documented command health", commandHealthResult.status, commandHealthResult.score, 10, `${usefulness.metrics.commands.healthy}/${usefulness.metrics.commands.total} statically inspected commands are healthy; ${usefulness.metrics.commands.unhealthy} are unhealthy and ${usefulness.metrics.commands.unverified} could not be verified safely.`, usefulness.metrics.commands.total > 0 && usefulness.metrics.commands.unhealthy === 0 && usefulness.metrics.commands.unverified === 0 ? void 0 : "Update broken or stale commands and make workspace selectors resolvable so scripts, working directories, package managers, and docs CLI subcommands can be verified."));
1916
+ checks.push(makeCheck("command-health", "Documented command health", commandHealthResult.status, commandHealthResult.score, 10, `${usefulness.metrics.commands.healthy}/${usefulness.metrics.commands.total} statically inspected commands are healthy; ${usefulness.metrics.commands.unhealthy} are unhealthy and ${usefulness.metrics.commands.unverified} could not be verified safely.`, usefulness.metrics.commands.total > 0 && usefulness.metrics.commands.unhealthy === 0 && usefulness.metrics.commands.unverified === 0 ? void 0 : "Update broken or stale commands and make workspace selectors resolvable so scripts, working directories, package managers, and docs CLI subcommands can be verified.", commandFindings));
1878
1917
  checks.push(makeCheck("related-coverage", "Related-page task coverage", relatedCoverageResult.status, relatedCoverageResult.score, 5, `${usefulness.metrics.related.coveredActionablePages}/${usefulness.metrics.actionablePages} actionable pages link to a valid related docs route; ${usefulness.metrics.related.brokenLinks} related links are broken.`, usefulness.metrics.actionablePages > 0 && usefulness.metrics.related.coverage >= 80 && usefulness.metrics.related.brokenLinks === 0 ? void 0 : "Add and validate related routes on actionable pages so agents can expand context without guessing."));
1879
1918
  checks.push(makeCheck("compact", "Agent compaction freshness", compactionResult.status, compactionResult.score, 5, `${compactionCoverage.freshGeneratedPages} fresh, ${compactionCoverage.staleGeneratedPages} stale, ${compactionCoverage.modifiedGeneratedPages} modified, ${compactionCoverage.unknownGeneratedPages} unknown, ${compactionCoverage.tokenBudgetMissingPages} token-budget missing, and ${compactionCoverage.otherMissingPages} other missing page${compactionCoverage.otherMissingPages === 1 ? "" : "s"} across compactable docs pages.` + (compactConfigured ? " agent.compact defaults are configured." : " No agent.compact defaults were found in docs config."), compactionResult.recommendation));
1880
1919
  const averageMetric = (values) => values.length === 0 ? 0 : Math.round(values.reduce((total, value) => total + value, 0) / values.length * 100) / 100;
@@ -1902,15 +1941,22 @@ async function inspectAgentReadiness(options = {}) {
1902
1941
  };
1903
1942
  }
1904
1943
  async function inspectHumanReadiness(options = {}) {
1905
- const rootDir = process.cwd();
1906
- const files = listProjectFiles(rootDir);
1907
- const framework = detectFramework(rootDir) ?? detectFrameworkFromFiles(files) ?? "unknown";
1944
+ const invocationRoot = process.cwd();
1945
+ let rootDir = invocationRoot;
1946
+ let files = [];
1947
+ let framework = "unknown";
1908
1948
  const configCheckMax = 10;
1909
1949
  let configPath;
1910
1950
  try {
1911
- configPath = resolveDocsConfigPath(rootDir, options.configPath);
1951
+ configPath = resolveDocsConfigPath(invocationRoot, options.configPath);
1952
+ rootDir = resolveDocsProjectRoot(invocationRoot, configPath);
1953
+ files = listProjectFiles(rootDir);
1954
+ framework = detectFramework(rootDir) ?? detectFrameworkFromFiles(files) ?? "unknown";
1912
1955
  } catch (error) {
1913
- const checks = [makeCheck("config", "Docs config", "fail", 0, configCheckMax, error instanceof Error ? error.message : String(error), "Add docs.config.ts[x] or pass --config so the doctor can inspect the docs app.")];
1956
+ const message = error instanceof Error ? error.message : String(error);
1957
+ const invocationFiles = listProjectFiles(invocationRoot);
1958
+ framework = detectFramework(invocationRoot) ?? detectFrameworkFromFiles(invocationFiles) ?? "unknown";
1959
+ const checks = [makeCheck("config", "Docs config", "fail", 0, configCheckMax, message, "Add docs.config.ts[x] or pass --config so the doctor can inspect the docs app.")];
1914
1960
  return {
1915
1961
  mode: "human",
1916
1962
  framework,
@@ -1931,7 +1977,7 @@ async function inspectHumanReadiness(options = {}) {
1931
1977
  };
1932
1978
  }
1933
1979
  const configContent = readFileSync(configPath, "utf-8");
1934
- const configLoad = await loadDocsConfigModuleResultWithProjectEnv(rootDir, options.configPath);
1980
+ const configLoad = await loadDocsConfigModuleResultWithProjectEnv(rootDir, configPath);
1935
1981
  const config = configLoad.status === "evaluated" ? configLoad.config : void 0;
1936
1982
  const entry = config?.entry ?? readTopLevelStringProperty(configContent, "entry") ?? "docs";
1937
1983
  const contentDir = config?.contentDir ?? resolveDocsContentDir(rootDir, configContent, entry);
@@ -1996,6 +2042,12 @@ function printAgentDoctorReport(report) {
1996
2042
  for (const check of report.checks) {
1997
2043
  console.log(`${formatStatus(check.status)} ${check.title} ${pc.dim(`(${check.score}/${check.maxScore})`)}`);
1998
2044
  console.log(` ${check.detail}`);
2045
+ for (const finding of check.findings ?? []) {
2046
+ const location = `${finding.file}${finding.line ? `:${finding.line}` : ""}`;
2047
+ console.log(` ${pc.dim(location)} ${pc.bold("Command:")} ${finding.command}`);
2048
+ console.log(` ${pc.bold("Reason:")} ${finding.reason}`);
2049
+ console.log(` ${pc.bold("Proposed correction:")} ${finding.proposedCorrection}`);
2050
+ }
1999
2051
  }
2000
2052
  if (report.recommendations.length > 0) {
2001
2053
  console.log();
@@ -2032,6 +2084,30 @@ function serializeDoctorJsonReport(report) {
2032
2084
  function printDoctorJsonReport(report) {
2033
2085
  console.log(JSON.stringify(serializeDoctorJsonReport(report), null, 2));
2034
2086
  }
2087
+ function writeDoctorJsonReport(report, outputPath) {
2088
+ const resolvedPath = path.resolve(process.cwd(), outputPath);
2089
+ mkdirSync(path.dirname(resolvedPath), { recursive: true });
2090
+ writeFileSync(resolvedPath, `${JSON.stringify(serializeDoctorJsonReport(report), null, 2)}\n`, "utf-8");
2091
+ }
2092
+ function escapeGitHubAnnotationData(value) {
2093
+ return value.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
2094
+ }
2095
+ function escapeGitHubAnnotationProperty(value) {
2096
+ return escapeGitHubAnnotationData(value).replaceAll(":", "%3A").replaceAll(",", "%2C");
2097
+ }
2098
+ function emitDoctorGitHubAnnotations(report) {
2099
+ if (process.env.GITHUB_ACTIONS !== "true" || report.mode !== "agent") return;
2100
+ for (const check of report.checks) for (const finding of check.findings ?? []) {
2101
+ const command = finding.severity === "error" ? "error" : finding.severity === "warning" ? "warning" : "notice";
2102
+ const location = [
2103
+ `file=${escapeGitHubAnnotationProperty(finding.file)}`,
2104
+ finding.line ? `line=${finding.line}` : void 0,
2105
+ `title=${escapeGitHubAnnotationProperty(check.title)}`
2106
+ ].filter(Boolean).join(",");
2107
+ const message = `Command: ${finding.command} Reason: ${finding.reason} Proposed correction: ${finding.proposedCorrection}`;
2108
+ console.log(`::${command} ${location}::${escapeGitHubAnnotationData(message)}`);
2109
+ }
2110
+ }
2035
2111
  function hasNonPassingDoctorCheck(report) {
2036
2112
  return report.checks.some((check) => check.status !== "pass");
2037
2113
  }
@@ -2093,15 +2169,18 @@ async function runAgentDoctorFixes(report, options) {
2093
2169
  return fixes;
2094
2170
  }
2095
2171
  async function runDoctor(options = {}) {
2172
+ if (options.ci && options.json) throw new Error("doctor --ci and --json cannot share stdout. Use --ci --json-output <path> to emit GitHub annotations and persist the JSON report in one run.");
2096
2173
  if (options.mode === "human") {
2097
2174
  if (options.fix) throw new Error("doctor --fix is currently only supported with --agent.");
2098
2175
  const report = await inspectHumanReadiness(options);
2099
2176
  applyDoctorExitCode(report, options);
2177
+ if (options.jsonOutputPath) writeDoctorJsonReport(report, options.jsonOutputPath);
2100
2178
  if (options.json) {
2101
2179
  printDoctorJsonReport(report);
2102
2180
  return report;
2103
2181
  }
2104
2182
  printHumanDoctorReport(report);
2183
+ if (options.ci) emitDoctorGitHubAnnotations(report);
2105
2184
  return report;
2106
2185
  }
2107
2186
  let report = await inspectAgentReadiness(options);
@@ -2117,11 +2196,13 @@ async function runDoctor(options = {}) {
2117
2196
  };
2118
2197
  }
2119
2198
  applyDoctorExitCode(report, options);
2199
+ if (options.jsonOutputPath) writeDoctorJsonReport(report, options.jsonOutputPath);
2120
2200
  if (options.json) {
2121
2201
  printDoctorJsonReport(report);
2122
2202
  return report;
2123
2203
  }
2124
2204
  printAgentDoctorReport(report);
2205
+ if (options.ci) emitDoctorGitHubAnnotations(report);
2125
2206
  return report;
2126
2207
  }
2127
2208