From 228c12599883535d887a131e0266d83249f82196 Mon Sep 17 00:00:00 2001 From: Kinfe123 Date: Mon, 27 Apr 2026 23:25:55 +0300 Subject: [PATCH 1/3] feat: agent doctor cli for agents --- README.md | 18 +++ .../next/app/docs/changelogs/[slug]/page.tsx | 34 +----- examples/next/app/docs/changelogs/page.tsx | 34 +----- packages/docs/src/cli/doctor.test.ts | 111 +++++++++++++++++- packages/docs/src/cli/doctor.ts | 31 +++++ packages/docs/src/cli/index.ts | 1 + skills/farming-labs/cli/SKILL.md | 4 + website/app/docs/cli/page.mdx | 42 +++++++ 8 files changed, 215 insertions(+), 60 deletions(-) diff --git a/README.md b/README.md index 0dd5b1ea..518ddeba 100644 --- a/README.md +++ b/README.md @@ -173,6 +173,7 @@ structure, trust signals, and feedback. ```bash pnpm exec docs doctor --agent pnpm exec docs doctor --site +pnpm exec docs doctor --agent --json ``` Expected output looks like: @@ -216,6 +217,23 @@ agent-ready or agent-optimized, and it works well as a CI check for the machine- - reader feedback - reading-time cues +Use `--json` when the result needs to feed another system instead of a person reading the terminal: + +```bash +pnpm exec docs doctor --agent --json +pnpm exec docs doctor --site --json +``` + +That JSON form is useful for: + +- CI quality gates +- GitHub Actions summaries or PR comments +- dashboards that track docs quality over time +- automation that reruns `docs agent compact --stale` +- other agents that need structured readiness signals instead of terminal text + +Warnings still go to stderr, so stdout stays machine-parseable for scripts and CI. + ## Common Tasks Use the full docs for feature-specific setup: diff --git a/examples/next/app/docs/changelogs/[slug]/page.tsx b/examples/next/app/docs/changelogs/[slug]/page.tsx index f301848a..c9507616 100644 --- a/examples/next/app/docs/changelogs/[slug]/page.tsx +++ b/examples/next/app/docs/changelogs/[slug]/page.tsx @@ -18,16 +18,7 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-15", sourcePath: "app/docs/changelog/2026-04-15/page.mdx", Component: ChangelogEntry1, - metadata: { - title: "API Reference: OpenAPI mode is now the default", - description: - "The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.", - image: "/images/changelog/fumadocs-openapi-mode.png", - authors: ["Farming Labs"], - version: "v0.1.13", - tags: ["api-reference", "next"], - pinned: true, - }, + metadata: {"title":"API Reference: OpenAPI mode is now the default","description":"The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.","image":"/images/changelog/fumadocs-openapi-mode.png","authors":["Farming Labs"],"version":"v0.1.13","tags":["api-reference","next"],"pinned":true}, }, { slug: "2026-04-03", @@ -35,15 +26,7 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-03", sourcePath: "app/docs/changelog/2026-04-03/page.mdx", Component: ChangelogEntry2, - metadata: { - title: "Colorful theme cleanup across docs and API routes", - description: - "We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.", - image: "/images/changelog/colorful-theme-cleanup.png", - authors: ["Farming Labs"], - version: "v0.1.12", - tags: ["themes", "colorful"], - }, + metadata: {"title":"Colorful theme cleanup across docs and API routes","description":"We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.","image":"/images/changelog/colorful-theme-cleanup.png","authors":["Farming Labs"],"version":"v0.1.12","tags":["themes","colorful"]}, }, { slug: "2026-03-18", @@ -51,18 +34,11 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-03-18", sourcePath: "app/docs/changelog/2026-03-18/page.mdx", Component: ChangelogEntry3, - metadata: { - title: "Cloud page motion pass", - description: - "The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.", - image: "/images/changelog/cloud-motion-pass.png", - authors: ["Farming Labs"], - version: "v0.1.11", - tags: ["cloud", "website"], - }, - }, + metadata: {"title":"Cloud page motion pass","description":"The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.","image":"/images/changelog/cloud-motion-pass.png","authors":["Farming Labs"],"version":"v0.1.11","tags":["cloud","website"]}, + } ]; + export const generateStaticParams = createNextChangelogStaticParams(changelogEntries); export const generateMetadata = createNextChangelogEntryMetadata(docsConfig, changelogEntries); diff --git a/examples/next/app/docs/changelogs/page.tsx b/examples/next/app/docs/changelogs/page.tsx index cefe1697..ccdccf3e 100644 --- a/examples/next/app/docs/changelogs/page.tsx +++ b/examples/next/app/docs/changelogs/page.tsx @@ -17,16 +17,7 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-15", sourcePath: "app/docs/changelog/2026-04-15/page.mdx", Component: ChangelogEntry1, - metadata: { - title: "API Reference: OpenAPI mode is now the default", - description: - "The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.", - image: "/images/changelog/fumadocs-openapi-mode.png", - authors: ["Farming Labs"], - version: "v0.1.13", - tags: ["api-reference", "next"], - pinned: true, - }, + metadata: {"title":"API Reference: OpenAPI mode is now the default","description":"The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.","image":"/images/changelog/fumadocs-openapi-mode.png","authors":["Farming Labs"],"version":"v0.1.13","tags":["api-reference","next"],"pinned":true}, }, { slug: "2026-04-03", @@ -34,15 +25,7 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-03", sourcePath: "app/docs/changelog/2026-04-03/page.mdx", Component: ChangelogEntry2, - metadata: { - title: "Colorful theme cleanup across docs and API routes", - description: - "We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.", - image: "/images/changelog/colorful-theme-cleanup.png", - authors: ["Farming Labs"], - version: "v0.1.12", - tags: ["themes", "colorful"], - }, + metadata: {"title":"Colorful theme cleanup across docs and API routes","description":"We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.","image":"/images/changelog/colorful-theme-cleanup.png","authors":["Farming Labs"],"version":"v0.1.12","tags":["themes","colorful"]}, }, { slug: "2026-03-18", @@ -50,18 +33,11 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-03-18", sourcePath: "app/docs/changelog/2026-03-18/page.mdx", Component: ChangelogEntry3, - metadata: { - title: "Cloud page motion pass", - description: - "The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.", - image: "/images/changelog/cloud-motion-pass.png", - authors: ["Farming Labs"], - version: "v0.1.11", - tags: ["cloud", "website"], - }, - }, + metadata: {"title":"Cloud page motion pass","description":"The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.","image":"/images/changelog/cloud-motion-pass.png","authors":["Farming Labs"],"version":"v0.1.11","tags":["cloud","website"]}, + } ]; + export const metadata = createNextChangelogIndexMetadata(docsConfig); const ChangelogPage = createNextChangelogIndexPage(docsConfig, changelogEntries); diff --git a/packages/docs/src/cli/doctor.test.ts b/packages/docs/src/cli/doctor.test.ts index 2df8260c..b3ad0c18 100644 --- a/packages/docs/src/cli/doctor.test.ts +++ b/packages/docs/src/cli/doctor.test.ts @@ -1,11 +1,16 @@ -import { afterEach, beforeEach, describe, expect, it } from "vitest"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; import { createServer } from "node:http"; import { mkdtempSync, mkdirSync, readFileSync, rmSync, symlinkSync, writeFileSync } from "node:fs"; import os from "node:os"; import path from "node:path"; import type { AddressInfo } from "node:net"; import { compactAgentDocs } from "./agent.js"; -import { inspectAgentReadiness, inspectHumanReadiness, parseDoctorArgs } from "./doctor.js"; +import { + inspectAgentReadiness, + inspectHumanReadiness, + parseDoctorArgs, + runDoctor, +} from "./doctor.js"; function writePackageJson( rootDir: string, @@ -56,6 +61,17 @@ describe("parseDoctorArgs", () => { }); }); + it("parses json output mode", () => { + expect(parseDoctorArgs(["--json"])).toEqual({ + mode: "agent", + json: true, + }); + expect(parseDoctorArgs(["--site", "--json"])).toEqual({ + mode: "human", + json: true, + }); + }); + it("parses human mode aliases", () => { expect(parseDoctorArgs(["--human"])).toEqual({ mode: "human" }); expect(parseDoctorArgs(["human", "--config=docs.config.ts"])).toEqual({ @@ -996,4 +1012,95 @@ Welcome to the docs. expect(trustCheck?.status).toBe("pass"); expect(trustCheck?.detail).toBe("Edit links and last-updated metadata are configured."); }); + + it("prints agent reports as JSON for automation consumers", async () => { + writePackageJson(tmpDir, "doctor-agent-json", { next: "16.0.0" }); + + writeFileSync( + path.join(tmpDir, "docs.config.ts"), + `export default { + entry: "docs", + llmsTxt: { enabled: true }, +};`, + "utf-8", + ); + + mkdirSync(path.join(tmpDir, "docs"), { recursive: true }); + writeFileSync( + path.join(tmpDir, "docs", "page.mdx"), + `--- +title: "Overview" +description: "Docs home" +--- + +# Overview +`, + "utf-8", + ); + + process.chdir(tmpDir); + + const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined); + + try { + const report = await runDoctor({ mode: "agent", json: true }); + expect(report.mode).toBe("agent"); + expect(logSpy).toHaveBeenCalledTimes(1); + + const serialized = logSpy.mock.calls[0]?.[0]; + expect(typeof serialized).toBe("string"); + + const payload = JSON.parse(String(serialized)) as { mode: string; checks: unknown[] }; + expect(payload.mode).toBe("agent"); + expect(Array.isArray(payload.checks)).toBe(true); + } finally { + logSpy.mockRestore(); + } + }); + + it("prints site reports as JSON with the public mode name", async () => { + writePackageJson(tmpDir, "doctor-site-json", { next: "16.0.0" }); + + writeFileSync( + path.join(tmpDir, "docs.config.ts"), + `export default { + entry: "docs", + contentDir: "docs", + search: true, +};`, + "utf-8", + ); + + mkdirSync(path.join(tmpDir, "docs"), { recursive: true }); + writeFileSync( + path.join(tmpDir, "docs", "page.mdx"), + `--- +title: "Overview" +description: "Docs home" +--- + +# Overview +`, + "utf-8", + ); + + process.chdir(tmpDir); + + const logSpy = vi.spyOn(console, "log").mockImplementation(() => undefined); + + try { + const report = await runDoctor({ mode: "human", json: true }); + expect(report.mode).toBe("human"); + expect(logSpy).toHaveBeenCalledTimes(1); + + const serialized = logSpy.mock.calls[0]?.[0]; + expect(typeof serialized).toBe("string"); + + const payload = JSON.parse(String(serialized)) as { mode: string; checks: unknown[] }; + expect(payload.mode).toBe("site"); + expect(Array.isArray(payload.checks)).toBe(true); + } finally { + logSpy.mockRestore(); + } + }); }); diff --git a/packages/docs/src/cli/doctor.ts b/packages/docs/src/cli/doctor.ts index b2294a4b..84fcf4ae 100644 --- a/packages/docs/src/cli/doctor.ts +++ b/packages/docs/src/cli/doctor.ts @@ -37,6 +37,7 @@ type DoctorMode = "agent" | "human"; export interface DoctorOptions { configPath?: string; mode?: DoctorMode; + json?: boolean; } export interface ParsedDoctorArgs extends DoctorOptions { @@ -157,6 +158,11 @@ export function parseDoctorArgs(argv: string[]): ParsedDoctorArgs { continue; } + if (arg === "--json") { + parsed.json = true; + continue; + } + if (arg === "--human" || arg === "human" || arg === "--site" || arg === "site") { parsed.mode = "human"; continue; @@ -199,6 +205,7 @@ ${pc.dim("Usage:")} pnpm exec docs doctor pnpm exec docs doctor --agent pnpm exec docs doctor --site + pnpm exec docs doctor --agent --json pnpm exec docs doctor agent pnpm exec docs doctor site @@ -206,6 +213,7 @@ ${pc.dim("Options:")} ${pc.cyan("--agent")} Score agent-readiness for the current docs app (default) ${pc.cyan("--site")} Score reader-facing docs quality for the current docs app ${pc.cyan("--human")} Alias for ${pc.cyan("--site")} + ${pc.cyan("--json")} Print the report as JSON for CI, scripts, and other agents ${pc.cyan("--config ")} Use a custom docs config path instead of ${pc.dim("docs.config.ts[x]")} ${pc.cyan("-h, --help")} Show this help message `); @@ -1697,14 +1705,37 @@ export function printHumanDoctorReport(report: HumanDoctorReport) { } } +function serializeDoctorJsonReport(report: AgentDoctorReport | HumanDoctorReport) { + if (report.mode === "human") { + return { + ...report, + mode: "site" as const, + }; + } + + return report; +} + +export function printDoctorJsonReport(report: AgentDoctorReport | HumanDoctorReport) { + console.log(JSON.stringify(serializeDoctorJsonReport(report), null, 2)); +} + export async function runDoctor(options: DoctorOptions = {}) { if (options.mode === "human") { const report = await inspectHumanReadiness(options); + if (options.json) { + printDoctorJsonReport(report); + return report; + } printHumanDoctorReport(report); return report; } const report = await inspectAgentReadiness(options); + if (options.json) { + printDoctorJsonReport(report); + return report; + } printAgentDoctorReport(report); return report; } diff --git a/packages/docs/src/cli/index.ts b/packages/docs/src/cli/index.ts index 312ac424..c329cd7c 100644 --- a/packages/docs/src/cli/index.ts +++ b/packages/docs/src/cli/index.ts @@ -193,6 +193,7 @@ ${pc.dim("Options for doctor:")} ${pc.cyan("doctor --agent")} Same as ${pc.cyan("doctor")}; explicit agent scoring mode ${pc.cyan("doctor --site")} Score the current docs app for reader-facing docs quality ${pc.cyan("doctor --human")} Alias for ${pc.cyan("doctor --site")} + ${pc.cyan("doctor --json")} Print the report as JSON for CI, scripts, and automation ${pc.cyan("doctor agent")} Subcommand alias for agent scoring ${pc.cyan("doctor site")} Subcommand alias for reader-facing scoring ${pc.cyan("doctor human")} Legacy alias for reader-facing scoring diff --git a/skills/farming-labs/cli/SKILL.md b/skills/farming-labs/cli/SKILL.md index d9963d1b..68ad26ce 100644 --- a/skills/farming-labs/cli/SKILL.md +++ b/skills/farming-labs/cli/SKILL.md @@ -319,6 +319,7 @@ experience instead. pnpm exec docs doctor pnpm exec docs doctor --agent pnpm exec docs doctor --site +pnpm exec docs doctor --agent --json pnpm exec docs doctor agent pnpm exec docs doctor site pnpm exec docs doctor --agent --config docs.config.tsx @@ -362,6 +363,9 @@ How to explain it: GEO-friendly - low `Explicit agent-friendly pages` does **not** mean pages are invisible to agents; it means fewer pages have extra machine-only context through `agent.md` or `Agent` blocks +- `--json` is for CI, scripts, dashboards, and other agents that need structured output instead of + terminal formatting +- JSON stays on stdout while warnings stay on stderr, so CI parsers can consume it safely Useful checks: diff --git a/website/app/docs/cli/page.mdx b/website/app/docs/cli/page.mdx index e4cb26a9..5627e85d 100644 --- a/website/app/docs/cli/page.mdx +++ b/website/app/docs/cli/page.mdx @@ -356,6 +356,7 @@ Common forms: pnpm exec docs doctor pnpm exec docs doctor --agent pnpm exec docs doctor --site +pnpm exec docs doctor --agent --json pnpm exec docs doctor agent pnpm exec docs doctor site pnpm exec docs doctor --agent --config docs.config.tsx @@ -395,6 +396,46 @@ Reader-facing runs use the same overall shape, but print `doctor — site` and s - reader feedback - reading-time cues +When you need structured output instead of terminal text, add `--json`: + +```bash title="terminal" +pnpm exec docs doctor --agent --json +pnpm exec docs doctor --site --json +``` + +Sample shape: + +```json title="~" +{ + "mode": "agent", + "score": 87, + "maxScore": 100, + "grade": "Agent-ready", + "framework": "nextjs", + "entry": "docs", + "contentDir": "app/docs", + "coverage": { + "explicitPages": 10, + "totalPages": 41, + "explicitCoverage": 24 + }, + "checks": [ + { + "id": "api-route", + "title": "Docs API route", + "status": "pass", + "score": 10, + "maxScore": 10 + } + ], + "recommendations": [ + "Enable feedback.agent if you want agents to discover and post feedback through the shared docs API." + ] +} +``` + +Warnings still go to stderr, so stdout stays safe to parse in CI and automation. + How to read it: - the **score** is a quick summary, not the only thing that matters @@ -410,6 +451,7 @@ When to use it: - after changing `docs.config`, route wiring, `.well-known` endpoints, or MCP - before opening a PR for docs infrastructure work - in CI if you want a quick quality gate for the agent or human-facing surface +- when another agent, script, or dashboard needs structured results instead of terminal formatting How essential it is: From 4554f62a7079f77c1ad468ffc2b3fec0cae55136 Mon Sep 17 00:00:00 2001 From: Kinfe123 Date: Mon, 27 Apr 2026 23:26:17 +0300 Subject: [PATCH 2/3] chore: format --- .../next/app/docs/changelogs/[slug]/page.tsx | 34 ++++++++++++++++--- examples/next/app/docs/changelogs/page.tsx | 34 ++++++++++++++++--- 2 files changed, 58 insertions(+), 10 deletions(-) diff --git a/examples/next/app/docs/changelogs/[slug]/page.tsx b/examples/next/app/docs/changelogs/[slug]/page.tsx index c9507616..f301848a 100644 --- a/examples/next/app/docs/changelogs/[slug]/page.tsx +++ b/examples/next/app/docs/changelogs/[slug]/page.tsx @@ -18,7 +18,16 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-15", sourcePath: "app/docs/changelog/2026-04-15/page.mdx", Component: ChangelogEntry1, - metadata: {"title":"API Reference: OpenAPI mode is now the default","description":"The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.","image":"/images/changelog/fumadocs-openapi-mode.png","authors":["Farming Labs"],"version":"v0.1.13","tags":["api-reference","next"],"pinned":true}, + metadata: { + title: "API Reference: OpenAPI mode is now the default", + description: + "The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.", + image: "/images/changelog/fumadocs-openapi-mode.png", + authors: ["Farming Labs"], + version: "v0.1.13", + tags: ["api-reference", "next"], + pinned: true, + }, }, { slug: "2026-04-03", @@ -26,7 +35,15 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-03", sourcePath: "app/docs/changelog/2026-04-03/page.mdx", Component: ChangelogEntry2, - metadata: {"title":"Colorful theme cleanup across docs and API routes","description":"We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.","image":"/images/changelog/colorful-theme-cleanup.png","authors":["Farming Labs"],"version":"v0.1.12","tags":["themes","colorful"]}, + metadata: { + title: "Colorful theme cleanup across docs and API routes", + description: + "We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.", + image: "/images/changelog/colorful-theme-cleanup.png", + authors: ["Farming Labs"], + version: "v0.1.12", + tags: ["themes", "colorful"], + }, }, { slug: "2026-03-18", @@ -34,11 +51,18 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-03-18", sourcePath: "app/docs/changelog/2026-03-18/page.mdx", Component: ChangelogEntry3, - metadata: {"title":"Cloud page motion pass","description":"The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.","image":"/images/changelog/cloud-motion-pass.png","authors":["Farming Labs"],"version":"v0.1.11","tags":["cloud","website"]}, - } + metadata: { + title: "Cloud page motion pass", + description: + "The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.", + image: "/images/changelog/cloud-motion-pass.png", + authors: ["Farming Labs"], + version: "v0.1.11", + tags: ["cloud", "website"], + }, + }, ]; - export const generateStaticParams = createNextChangelogStaticParams(changelogEntries); export const generateMetadata = createNextChangelogEntryMetadata(docsConfig, changelogEntries); diff --git a/examples/next/app/docs/changelogs/page.tsx b/examples/next/app/docs/changelogs/page.tsx index ccdccf3e..cefe1697 100644 --- a/examples/next/app/docs/changelogs/page.tsx +++ b/examples/next/app/docs/changelogs/page.tsx @@ -17,7 +17,16 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-15", sourcePath: "app/docs/changelog/2026-04-15/page.mdx", Component: ChangelogEntry1, - metadata: {"title":"API Reference: OpenAPI mode is now the default","description":"The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.","image":"/images/changelog/fumadocs-openapi-mode.png","authors":["Farming Labs"],"version":"v0.1.13","tags":["api-reference","next"],"pinned":true}, + metadata: { + title: "API Reference: OpenAPI mode is now the default", + description: + "The Next example now ships with the faster OpenAPI experience, plus a tighter docs/API switcher.", + image: "/images/changelog/fumadocs-openapi-mode.png", + authors: ["Farming Labs"], + version: "v0.1.13", + tags: ["api-reference", "next"], + pinned: true, + }, }, { slug: "2026-04-03", @@ -25,7 +34,15 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-04-03", sourcePath: "app/docs/changelog/2026-04-03/page.mdx", Component: ChangelogEntry2, - metadata: {"title":"Colorful theme cleanup across docs and API routes","description":"We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.","image":"/images/changelog/colorful-theme-cleanup.png","authors":["Farming Labs"],"version":"v0.1.12","tags":["themes","colorful"]}, + metadata: { + title: "Colorful theme cleanup across docs and API routes", + description: + "We tightened the theme handoff so the colorful preset keeps its own identity when moving between docs and API reference.", + image: "/images/changelog/colorful-theme-cleanup.png", + authors: ["Farming Labs"], + version: "v0.1.12", + tags: ["themes", "colorful"], + }, }, { slug: "2026-03-18", @@ -33,11 +50,18 @@ export const changelogEntries: GeneratedChangelogEntry[] = [ url: "/docs/changelogs/2026-03-18", sourcePath: "app/docs/changelog/2026-03-18/page.mdx", Component: ChangelogEntry3, - metadata: {"title":"Cloud page motion pass","description":"The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.","image":"/images/changelog/cloud-motion-pass.png","authors":["Farming Labs"],"version":"v0.1.11","tags":["cloud","website"]}, - } + metadata: { + title: "Cloud page motion pass", + description: + "The cloud landing page picked up smoother looping motion, better path-based SVG behavior, and more stable theme controls.", + image: "/images/changelog/cloud-motion-pass.png", + authors: ["Farming Labs"], + version: "v0.1.11", + tags: ["cloud", "website"], + }, + }, ]; - export const metadata = createNextChangelogIndexMetadata(docsConfig); const ChangelogPage = createNextChangelogIndexPage(docsConfig, changelogEntries); From c74eaee76ac6779f8a63b1b7d3a81d8b44c890df Mon Sep 17 00:00:00 2001 From: Kinfe123 Date: Mon, 27 Apr 2026 23:33:36 +0300 Subject: [PATCH 3/3] chore: docs --- README.md | 3 ++- skills/farming-labs/cli/SKILL.md | 3 ++- website/app/docs/cli/page.mdx | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 518ddeba..43371a7a 100644 --- a/README.md +++ b/README.md @@ -232,7 +232,8 @@ That JSON form is useful for: - automation that reruns `docs agent compact --stale` - other agents that need structured readiness signals instead of terminal text -Warnings still go to stderr, so stdout stays machine-parseable for scripts and CI. +The JSON report itself is written to stdout. Separate loader notices, such as config fallback +warnings, are outside the JSON payload. ## Common Tasks diff --git a/skills/farming-labs/cli/SKILL.md b/skills/farming-labs/cli/SKILL.md index 68ad26ce..611d09e5 100644 --- a/skills/farming-labs/cli/SKILL.md +++ b/skills/farming-labs/cli/SKILL.md @@ -365,7 +365,8 @@ How to explain it: fewer pages have extra machine-only context through `agent.md` or `Agent` blocks - `--json` is for CI, scripts, dashboards, and other agents that need structured output instead of terminal formatting -- JSON stays on stdout while warnings stay on stderr, so CI parsers can consume it safely +- the JSON report itself is written to stdout; separate loader notices, such as config fallback + warnings, are outside the JSON payload Useful checks: diff --git a/website/app/docs/cli/page.mdx b/website/app/docs/cli/page.mdx index 5627e85d..e3fc41b9 100644 --- a/website/app/docs/cli/page.mdx +++ b/website/app/docs/cli/page.mdx @@ -434,7 +434,8 @@ Sample shape: } ``` -Warnings still go to stderr, so stdout stays safe to parse in CI and automation. +The JSON report itself is written to stdout. Separate loader notices, such as config fallback +warnings, are outside the JSON payload. How to read it: