diff --git a/docs/AGENTS.md b/docs/AGENTS.md index a3f502ff9f..a095ff7b4f 100644 --- a/docs/AGENTS.md +++ b/docs/AGENTS.md @@ -36,6 +36,7 @@ Treat `docs/` as the source of truth for published content and AI-agent Markdown - Use `$$nemoclaw` for host CLI command examples on shared OpenClaw, Hermes, and Deep Agents pages. - Use literal command names on pages that have only one agent variant. - Use `` blocks only when content differs by behavior, setup flow, state layout, or agent-specific wording. +- Treat `` as a non-nested build-time directive with opening and closing tags at the first column on their own lines; do not import a runtime component for it. - Use route-style links without `.mdx` extensions for links between docs pages. - Update `docs/index.yml` when navigation, slugs, or page placement changes. diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index 22352e3ae9..578df76028 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -178,6 +178,9 @@ Use literal command names on those single-variant pages rather than `$$nemoclaw` Run `npm run docs:sync-agent-variants` after editing shared variant source pages or navigation. Run `npm run docs` before opening a PR to verify the generated pages, rewritten relative links, and Fern navigation. If content differs by behavior, setup flow, state layout, or agent-specific wording, keep using `` blocks for that content. +Treat `` as a build-time directive rather than a React component, and do not import it from `AgentGuide.tsx`. +Put each opening and closing tag at the first column on its own line, and do not nest the blocks. +The generated pages must contain only statically resolved content, with no `AgentGuide` imports or runtime agent components. ## Route-Style Links diff --git a/docs/_components/AgentGuide.tsx b/docs/_components/AgentGuide.tsx deleted file mode 100644 index 5e84c13092..0000000000 --- a/docs/_components/AgentGuide.tsx +++ /dev/null @@ -1,136 +0,0 @@ -/* - * SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * Resolves OpenClaw, Hermes, or Deep Agents user-guide variant from injected route data. - * Prefer passing `variant` or `pathname` from the page or route that renders the - * component so SSR output does not depend on browser-only globals. The window - * fallback preserves the current client-side behavior for unwrapped pages. - */ -declare const React: unknown; - -export type GuideVariant = "openclaw" | "hermes" | "deepagents"; -export type GuideVariantSource = - | GuideVariant - | string - | { - variant?: GuideVariant | null; - activeVariant?: GuideVariant | null; - pathname?: string | null; - } - | null - | undefined; - -type GuideContextProps = { - variant?: GuideVariant | null; - activeVariant?: GuideVariant | null; - pathname?: string | null; -}; - -const GUIDE_PATH = "/user-guide/"; -const DEEPAGENTS_PATH = `${GUIDE_PATH}deepagents`; -const HERMES_PATH = `${GUIDE_PATH}hermes`; -const OPENCLAW_PATH = `${GUIDE_PATH}openclaw`; - -export function getGuideVariant(source?: GuideVariantSource): GuideVariant { - return resolveGuideVariant(source) ?? resolveGuideVariant(readWindowPathname()) ?? "openclaw"; -} - -export function guideBasePath(source?: GuideVariantSource): string { - const pathname = resolveGuidePathname(source) ?? readWindowPathname(); - if (!pathname) return ""; - const guideIndex = pathname.indexOf(GUIDE_PATH); - return guideIndex === -1 ? "" : pathname.slice(0, guideIndex); -} - -/** Full site path for the active guide variant (includes /user-guide/{variant}). */ -export function guidePath(suffix: string, source?: GuideVariantSource): string { - const normalized = suffix.startsWith("/") ? suffix : `/${suffix}`; - return `${guideBasePath(source)}${GUIDE_PATH}${getGuideVariant(source)}${normalized}`; -} - -export function AgentCli(props: GuideContextProps = {}) { - const variant = getGuideVariant(props); - if (variant === "hermes") return nemohermes; - if (variant === "deepagents") return nemo-deepagents; - return nemoclaw; -} - -export function AgentProductName(props: GuideContextProps = {}) { - const variant = getGuideVariant(props); - if (variant === "hermes") return <>NemoHermes; - if (variant === "deepagents") return <>NemoDeepAgents; - return <>NemoClaw; -} - -export function AgentOnly({ - variant, - activeVariant, - pathname, - children, -}: { - variant: GuideVariant | string; - activeVariant?: GuideVariant | null; - pathname?: string | null; - children: unknown; -}) { - const active = getGuideVariant({ activeVariant, pathname }); - const variants = variant.split(",").map((item) => item.trim()); - if (!variants.includes(active)) { - return null; - } - return <>{children}; -} - -export function GuideLink({ - href, - variant, - activeVariant, - pathname, - children, -}: { - href: string; - variant?: GuideVariant | null; - activeVariant?: GuideVariant | null; - pathname?: string | null; - children: unknown; -}) { - const resolved = - href.startsWith("http://") || href.startsWith("https://") - ? href - : guidePath(href, { variant, activeVariant, pathname }); - return {children}; -} - -function resolveGuideVariant(source?: GuideVariantSource): GuideVariant | null { - if (!source) return null; - if (source === "openclaw" || source === "hermes" || source === "deepagents") return source; - if (typeof source === "string") return resolveGuideVariantFromPathname(source); - return ( - source.activeVariant ?? - source.variant ?? - resolveGuideVariantFromPathname(source.pathname ?? null) - ); -} - -function resolveGuidePathname(source?: GuideVariantSource): string | null { - if (!source || source === "openclaw" || source === "hermes" || source === "deepagents") { - return null; - } - if (typeof source === "string") return source; - return source.pathname ?? null; -} - -function resolveGuideVariantFromPathname(pathname: string | null): GuideVariant | null { - if (!pathname) return null; - if (pathname.includes(DEEPAGENTS_PATH)) return "deepagents"; - if (pathname.includes(HERMES_PATH)) return "hermes"; - if (pathname.includes(OPENCLAW_PATH)) return "openclaw"; - return null; -} - -function readWindowPathname(): string | null { - return typeof window === "undefined" ? null : window.location.pathname; -} diff --git a/docs/about/how-it-works.mdx b/docs/about/how-it-works.mdx index 21e6f02242..214cbb9e58 100644 --- a/docs/about/how-it-works.mdx +++ b/docs/about/how-it-works.mdx @@ -9,8 +9,6 @@ keywords: ["how nemoclaw works", "nemoclaw sandbox lifecycle blueprint"] content: type: "concept" --- -import { AgentCli, AgentOnly } from "../_components/AgentGuide"; - This page explains how NemoClaw runs supported agents inside an OpenShell sandbox and how the gateway connects the agent to inference, integrations, and policy. NemoClaw does not replace OpenShell or your chosen agent runtime. @@ -106,16 +104,21 @@ NemoClaw follows these architecture principles. Versioned blueprint : Host-side orchestration uses a versioned blueprint and runner that can evolve on its own release cadence. - The OpenClaw sandbox plugin stays small and stable inside the container. + + + +The OpenClaw sandbox plugin stays small and stable inside the container. + + Respect CLI boundaries -: The CLI is the primary interface for sandbox management. +: The `$$nemoclaw` CLI is the primary interface for sandbox management. Supply chain safety : Blueprint artifacts are immutable, versioned, and digest-verified before execution. OpenShell-backed lifecycle -: NemoClaw orchestrates OpenShell resources under the hood, but onboard is the supported operator entry point for creating or recreating NemoClaw-managed sandboxes. +: NemoClaw orchestrates OpenShell resources under the hood, but `$$nemoclaw onboard` is the supported operator entry point for creating or recreating NemoClaw-managed sandboxes. Reproducible setup : Running setup again recreates the sandbox from the same blueprint and policy definitions. @@ -149,7 +152,7 @@ This separation keeps agent-specific sandbox assets focused and lets host orches ## Sandbox Creation -When you run onboard, NemoClaw creates an OpenShell sandbox that runs your selected agent in an isolated container. +When you run `$$nemoclaw onboard`, NemoClaw creates an OpenShell sandbox that runs your selected agent in an isolated container. The host CLI and blueprint runner orchestrate this process through the OpenShell CLI: 1. NemoClaw resolves the blueprint, checks version compatibility, and verifies the digest. @@ -166,7 +169,7 @@ During onboarding, NemoClaw validates the selected provider and model, configure The sandbox then talks to `inference.local`, while the host owns the actual provider credential and upstream endpoint. When you select the Model Router provider, `inference.local` routes to a host-side router that chooses from the configured NVIDIA model pool for each request. -For Hermes, `inference set` updates `/sandbox/.hermes/config.yaml` at runtime without rebuilding the sandbox. +For Hermes, `$$nemoclaw inference set` updates `/sandbox/.hermes/config.yaml` at runtime without rebuilding the sandbox. For Deep Agents, the managed `dcode` runtime reads the OpenAI-compatible route that NemoClaw writes into `/sandbox/.deepagents/config.toml`. diff --git a/docs/about/overview.mdx b/docs/about/overview.mdx index af107034b9..0996e8a561 100644 --- a/docs/about/overview.mdx +++ b/docs/about/overview.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentCli, AgentOnly } from "../_components/AgentGuide"; - NVIDIA NemoClaw is an open-source reference stack for running always-on AI agents more safely inside OpenShell containers. @@ -31,7 +29,7 @@ These controls help agents run in clouds, on-premises environments, RTX PCs, and NemoClaw pairs hosted inference providers or local model endpoints with a hardened sandbox, routed inference, and declarative egress policy. This keeps deployments repeatable and easier to constrain. The sandbox runtime comes from [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell). -NemoClaw adds the blueprint, CLI, onboarding, and related tooling as the reference way to run supported agents there. +NemoClaw adds the blueprint, `$$nemoclaw` CLI, onboarding, and related tooling as the reference way to run supported agents there. | Capability | Description | |-------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------| @@ -72,7 +70,7 @@ NemoClaw provides these benefits to mitigate those risks. | Sandboxed execution | Every agent runs inside an OpenShell sandbox with Landlock, seccomp, and network namespace isolation. The sandbox grants no access by default. | | Routed inference | The OpenShell gateway routes model traffic to your selected provider, transparent to the agent. You can switch providers or models. Refer to [Choose an Inference Provider](../inference/learn-and-choose/choose-inference-provider). | | Declarative network policy | YAML defines egress rules. OpenShell blocks unknown hosts and surfaces them to the operator for approval. | -| Single CLI | The command orchestrates the full stack: gateway, sandbox, inference provider, and network policy. | +| Single CLI | The `$$nemoclaw` command orchestrates the full stack: gateway, sandbox, inference provider, and network policy. | | Blueprint lifecycle | Versioned blueprints handle sandbox creation, digest verification, and reproducible setup. | ## Use Cases diff --git a/docs/configure-agents/progressive-tool-disclosure.mdx b/docs/configure-agents/progressive-tool-disclosure.mdx index cc8b732b8e..600bb1e95d 100644 --- a/docs/configure-agents/progressive-tool-disclosure.mdx +++ b/docs/configure-agents/progressive-tool-disclosure.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw tool disclosure", "progressive tool disclosure", "search_to content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Progressive tool disclosure limits the tool schemas placed in the model's initial context. Each supported agent keeps its native discovery mechanism and configuration schema. diff --git a/docs/deployment/set-up-mcp-bridge.mdx b/docs/deployment/set-up-mcp-bridge.mdx index cbe5e03e10..06c270ecb9 100644 --- a/docs/deployment/set-up-mcp-bridge.mdx +++ b/docs/deployment/set-up-mcp-bridge.mdx @@ -11,8 +11,6 @@ content: skill: priority: 30 --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw lets a sandboxed agent use authenticated Streamable HTTP MCP servers without copying external service credentials into the sandbox. The integration has three parts: diff --git a/docs/get-started/prerequisites.mdx b/docs/get-started/prerequisites.mdx index e88ce953de..52a7f8fcae 100644 --- a/docs/get-started/prerequisites.mdx +++ b/docs/get-started/prerequisites.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw prerequisites", "nemoclaw supported platforms", "nemoclaw h content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - Before you start, verify that your machine has the software and hardware needed to run NemoClaw. ## Hardware diff --git a/docs/get-started/windows-preparation.mdx b/docs/get-started/windows-preparation.mdx index 3d279e46fe..2ee991aeee 100644 --- a/docs/get-started/windows-preparation.mdx +++ b/docs/get-started/windows-preparation.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw windows wsl2 setup", "nemoclaw install windows docker deskt content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - Run NemoClaw inside Windows Subsystem for Linux (WSL 2) on Windows. Complete these steps before following the [Quickstart](../quickstart). diff --git a/docs/inference/choose-compatible-inference-api.mdx b/docs/inference/choose-compatible-inference-api.mdx index abbfe46638..17b2a46b63 100644 --- a/docs/inference/choose-compatible-inference-api.mdx +++ b/docs/inference/choose-compatible-inference-api.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw preferred api", "openai responses api", "chat completions e content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - Custom OpenAI-compatible endpoints use `/v1/chat/completions` at runtime by default. Choose the Responses API only when your endpoint implements the required streaming and tool-calling behavior. diff --git a/docs/inference/choose-inference-provider.mdx b/docs/inference/choose-inference-provider.mdx index 34d587c9c1..57ea72a860 100644 --- a/docs/inference/choose-inference-provider.mdx +++ b/docs/inference/choose-inference-provider.mdx @@ -9,8 +9,6 @@ keywords: ["choose inference provider", "nemoclaw providers", "hosted local infe content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - Choose a provider based on where the model runs, which API it exposes, and which credential you can supply. NemoClaw validates the provider and model before it creates the sandbox. diff --git a/docs/inference/choose-local-inference-server.mdx b/docs/inference/choose-local-inference-server.mdx index bda9feb3b3..fc383bdf26 100644 --- a/docs/inference/choose-local-inference-server.mdx +++ b/docs/inference/choose-local-inference-server.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw local inference", "ollama vllm nim", "local inference serve content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw supports Ollama, vLLM, and NVIDIA NIM as local inference servers. Choose the option that matches your host, model, and operational needs. diff --git a/docs/inference/configure-inference-timeouts.mdx b/docs/inference/configure-inference-timeouts.mdx index 5bda664304..4f9ece74ce 100644 --- a/docs/inference/configure-inference-timeouts.mdx +++ b/docs/inference/configure-inference-timeouts.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw inference timeout", "local inference timeout", "sandbox rea content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw uses separate time budgets for agent requests, local provider validation, and sandbox readiness. Change the budget that matches the phase that times out. diff --git a/docs/inference/configure-model-limits.mdx b/docs/inference/configure-model-limits.mdx index 9f18cbdb69..75fa62efe2 100644 --- a/docs/inference/configure-model-limits.mdx +++ b/docs/inference/configure-model-limits.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw context window", "nemoclaw max tokens", "model limits"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Configure model limits before onboarding so NemoClaw can bake them into the sandbox image. Changing a build-time model limit on an existing sandbox requires fresh recreation. diff --git a/docs/inference/how-inference-routing-works.mdx b/docs/inference/how-inference-routing-works.mdx index 9f3bd0a277..2b20a5ea0c 100644 --- a/docs/inference/how-inference-routing-works.mdx +++ b/docs/inference/how-inference-routing-works.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw inference routing", "inference.local", "openshell inference content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw gives agents one managed inference route while OpenShell handles the selected upstream provider on the host. This design keeps provider selection and credentials outside the sandbox. diff --git a/docs/inference/model-capability-audit.mdx b/docs/inference/model-capability-audit.mdx index 6c7799b9aa..57a9dd9808 100644 --- a/docs/inference/model-capability-audit.mdx +++ b/docs/inference/model-capability-audit.mdx @@ -15,7 +15,6 @@ audience: ["maintainers", "contributors"] status: "maintained" exclude-from-skills-gen: true --- -import { AgentOnly } from "../_components/AgentGuide"; Use this matrix to maintain model and provider audit evidence for NemoClaw agent behavior. Use it to determine whether a supported model works as an agent model, not only whether it can answer a one-shot chat prompt. diff --git a/docs/inference/set-up-anthropic-compatible-endpoint.mdx b/docs/inference/set-up-anthropic-compatible-endpoint.mdx index 148729cd13..f82bb586eb 100644 --- a/docs/inference/set-up-anthropic-compatible-endpoint.mdx +++ b/docs/inference/set-up-anthropic-compatible-endpoint.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw anthropic compatible", "custom anthropic endpoint", "anthro content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Use the custom Anthropic-compatible provider to configure a custom base URL and model with `COMPATIBLE_ANTHROPIC_API_KEY`. The runtime API differs by agent capability. diff --git a/docs/inference/set-up-ollama.mdx b/docs/inference/set-up-ollama.mdx index 8dba0446a7..b35e0630d4 100644 --- a/docs/inference/set-up-ollama.mdx +++ b/docs/inference/set-up-ollama.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use Ollama when you want the default local inference setup path. NemoClaw detects Ollama on the host and can install, start, or upgrade it on supported systems. diff --git a/docs/inference/switch-models.mdx b/docs/inference/switch-models.mdx index 20a906a86b..18d977632a 100644 --- a/docs/inference/switch-models.mdx +++ b/docs/inference/switch-models.mdx @@ -9,8 +9,6 @@ keywords: ["switch nemoclaw model", "change inference model", "nemoclaw inferenc content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Change the model on an existing provider route with a runtime update or a fresh sandbox recreation. The command requires both the provider and model even when the provider does not change. diff --git a/docs/inference/switch-providers.mdx b/docs/inference/switch-providers.mdx index 699ecb824d..abd40c393d 100644 --- a/docs/inference/switch-providers.mdx +++ b/docs/inference/switch-providers.mdx @@ -9,8 +9,6 @@ keywords: ["switch nemoclaw provider", "change inference provider", "nemoclaw in content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Move a sandbox to another provider family while keeping the OpenShell route, agent configuration, and host registry aligned. Use onboarding first when the target provider is not registered. diff --git a/docs/inference/understand-provider-validation.mdx b/docs/inference/understand-provider-validation.mdx index e0e15b2185..1d9dfd36dc 100644 --- a/docs/inference/understand-provider-validation.mdx +++ b/docs/inference/understand-provider-validation.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw provider validation", "inference validation", "compatible e content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw validates the selected provider and model before it creates a sandbox. The exact request depends on the provider API that the agent uses. diff --git a/docs/inference/verify-inference-route.mdx b/docs/inference/verify-inference-route.mdx index 2f9d8c1d8c..e17f3a05e1 100644 --- a/docs/inference/verify-inference-route.mdx +++ b/docs/inference/verify-inference-route.mdx @@ -9,8 +9,6 @@ keywords: ["verify inference.local", "nemoclaw inference route", "sandbox infere content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Verify inference through the same `inference.local` path that the agent uses inside the sandbox. Reading the active route confirms configuration, but it does not authenticate a model request. diff --git a/docs/manage-sandboxes/add-channels-after-onboarding.mdx b/docs/manage-sandboxes/add-channels-after-onboarding.mdx index 754da5a9f6..a7d185319c 100644 --- a/docs/manage-sandboxes/add-channels-after-onboarding.mdx +++ b/docs/manage-sandboxes/add-channels-after-onboarding.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw channels add", "add messaging channel", "channels list"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Run channel commands from the host, not from inside the sandbox. ## Select and Add a Channel diff --git a/docs/manage-sandboxes/add-mcp-server.mdx b/docs/manage-sandboxes/add-mcp-server.mdx index 77af168a32..6eaefae04a 100644 --- a/docs/manage-sandboxes/add-mcp-server.mdx +++ b/docs/manage-sandboxes/add-mcp-server.mdx @@ -11,8 +11,6 @@ content: skill: priority: 40 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use the same host-side workflow for OpenClaw, Hermes, and Deep Agents Code sandboxes. NemoClaw selects the agent-specific adapter from the sandbox registry. diff --git a/docs/manage-sandboxes/backup-restore.mdx b/docs/manage-sandboxes/backup-restore.mdx index 02530ba1fb..e810bd3db6 100644 --- a/docs/manage-sandboxes/backup-restore.mdx +++ b/docs/manage-sandboxes/backup-restore.mdx @@ -11,8 +11,6 @@ content: skill: priority: 20 --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw snapshots preserve manifest-defined sandbox state before destructive or state-changing operations. They are the preferred backup and restore path. diff --git a/docs/manage-sandboxes/gateway-lifecycle-control.mdx b/docs/manage-sandboxes/gateway-lifecycle-control.mdx index 3503fa26f5..fb23397a5e 100644 --- a/docs/manage-sandboxes/gateway-lifecycle-control.mdx +++ b/docs/manage-sandboxes/gateway-lifecycle-control.mdx @@ -11,8 +11,6 @@ content: skill: priority: 20 --- -import { AgentOnly } from "../_components/AgentGuide"; - Built-in OpenClaw and Hermes images support two direct-container lifecycle topologies for `recover` and `gateway restart`. | Topology | Process ownership | Lifecycle and trust boundary | diff --git a/docs/manage-sandboxes/lifecycle.mdx b/docs/manage-sandboxes/lifecycle.mdx index 4cf1eda4cc..2169ac18a5 100644 --- a/docs/manage-sandboxes/lifecycle.mdx +++ b/docs/manage-sandboxes/lifecycle.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use these commands to inspect registered sandboxes and collect evidence before changing a sandbox. diff --git a/docs/manage-sandboxes/manage-mcp-servers.mdx b/docs/manage-sandboxes/manage-mcp-servers.mdx index c8ef00518f..f8a07a20ed 100644 --- a/docs/manage-sandboxes/manage-mcp-servers.mdx +++ b/docs/manage-sandboxes/manage-mcp-servers.mdx @@ -11,8 +11,6 @@ content: skill: priority: 50 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use the host-side MCP commands to inspect and change registered servers. ## List and Inspect Servers diff --git a/docs/manage-sandboxes/manage-messaging-channels.mdx b/docs/manage-sandboxes/manage-messaging-channels.mdx index 147026622d..c172f68acc 100644 --- a/docs/manage-sandboxes/manage-messaging-channels.mdx +++ b/docs/manage-sandboxes/manage-messaging-channels.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw channels remove", "nemoclaw channels stop", "messaging cred content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Use host-side channel commands to change a configured messaging channel. ## Rotate Credentials diff --git a/docs/manage-sandboxes/messaging-channels.mdx b/docs/manage-sandboxes/messaging-channels.mdx index ce90d2d75f..425370170f 100644 --- a/docs/manage-sandboxes/messaging-channels.mdx +++ b/docs/manage-sandboxes/messaging-channels.mdx @@ -11,8 +11,6 @@ content: skill: priority: 30 --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw supports Telegram, Discord, Slack, WeChat, WhatsApp, and Microsoft Teams for OpenClaw and Hermes sandboxes. OpenShell-managed processes and gateway resources carry channel traffic. diff --git a/docs/manage-sandboxes/recover-rebuild-sandboxes.mdx b/docs/manage-sandboxes/recover-rebuild-sandboxes.mdx index 0a6e9f496f..cfbe1eab2a 100644 --- a/docs/manage-sandboxes/recover-rebuild-sandboxes.mdx +++ b/docs/manage-sandboxes/recover-rebuild-sandboxes.mdx @@ -11,8 +11,6 @@ content: skill: priority: 30 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use the lightest recovery operation that repairs the sandbox while preserving its supported state. ## Recover the Agent Runtime diff --git a/docs/manage-sandboxes/run-sandboxes.mdx b/docs/manage-sandboxes/run-sandboxes.mdx index ca4cfd3968..64ba68e29a 100644 --- a/docs/manage-sandboxes/run-sandboxes.mdx +++ b/docs/manage-sandboxes/run-sandboxes.mdx @@ -11,8 +11,6 @@ content: skill: priority: 20 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use these workflows to keep existing sandboxes reachable and control the resources they consume. diff --git a/docs/manage-sandboxes/runtime-controls.mdx b/docs/manage-sandboxes/runtime-controls.mdx index 5fbcab5c40..bc6a0f81f3 100644 --- a/docs/manage-sandboxes/runtime-controls.mdx +++ b/docs/manage-sandboxes/runtime-controls.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use this matrix to choose the operation that makes a sandbox change take effect. NemoClaw applies its security posture in three layers: what onboarding writes into the sandbox image, what the running sandbox can hot-reload, and what requires a rebuild or re-onboard. diff --git a/docs/manage-sandboxes/set-up-discord.mdx b/docs/manage-sandboxes/set-up-discord.mdx index 2c7d2b2367..934da24414 100644 --- a/docs/manage-sandboxes/set-up-discord.mdx +++ b/docs/manage-sandboxes/set-up-discord.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw discord", "discord bot token", "discord server id"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Create a Discord bot and choose its server and user access before you enable the channel. ## Prepare Discord Settings diff --git a/docs/manage-sandboxes/set-up-microsoft-teams.mdx b/docs/manage-sandboxes/set-up-microsoft-teams.mdx index 8539d5921b..57cb44e381 100644 --- a/docs/manage-sandboxes/set-up-microsoft-teams.mdx +++ b/docs/manage-sandboxes/set-up-microsoft-teams.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw teams", "microsoft teams bot framework", "teams webhook"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Microsoft Teams support is experimental and uses a public Bot Framework webhook that forwards to the sandbox. ## Configure the Webhook diff --git a/docs/manage-sandboxes/set-up-slack.mdx b/docs/manage-sandboxes/set-up-slack.mdx index 0f8e95fb0d..03e7ce249b 100644 --- a/docs/manage-sandboxes/set-up-slack.mdx +++ b/docs/manage-sandboxes/set-up-slack.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw slack", "slack socket mode", "slack app token", "slack allo content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Slack uses Socket Mode and requires both a bot token and an app-level token. ## Prepare and Validate Tokens diff --git a/docs/manage-sandboxes/set-up-telegram.mdx b/docs/manage-sandboxes/set-up-telegram.mdx index 6bfe53a28e..4017c870b9 100644 --- a/docs/manage-sandboxes/set-up-telegram.mdx +++ b/docs/manage-sandboxes/set-up-telegram.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw telegram", "telegram bot token", "telegram allowed ids"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - Create a Telegram bot and choose the direct-message and group behavior before you enable the channel. ## Create the Bot Token diff --git a/docs/manage-sandboxes/set-up-whatsapp.mdx b/docs/manage-sandboxes/set-up-whatsapp.mdx index 3acca9b84a..8e5ae75cae 100644 --- a/docs/manage-sandboxes/set-up-whatsapp.mdx +++ b/docs/manage-sandboxes/set-up-whatsapp.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw whatsapp", "whatsapp qr pairing", "whatsapp session"] content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - WhatsApp support is experimental and pairs inside the sandbox rather than through a host-side token or OpenShell credential provider. ## Pair the Sandbox diff --git a/docs/manage-sandboxes/transfer-state-manually.mdx b/docs/manage-sandboxes/transfer-state-manually.mdx index ff2e9d5b10..0ade7d9ed4 100644 --- a/docs/manage-sandboxes/transfer-state-manually.mdx +++ b/docs/manage-sandboxes/transfer-state-manually.mdx @@ -11,8 +11,6 @@ content: skill: priority: 30 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use manual transfer when you need to inspect or move specific state files. Use [Create and Restore Snapshots](create-and-restore-snapshots) for normal backup, rebuild, and restore workflows. diff --git a/docs/manage-sandboxes/update-sandboxes.mdx b/docs/manage-sandboxes/update-sandboxes.mdx index 35d8a460e0..595b3f57eb 100644 --- a/docs/manage-sandboxes/update-sandboxes.mdx +++ b/docs/manage-sandboxes/update-sandboxes.mdx @@ -11,8 +11,6 @@ content: skill: priority: 40 --- -import { AgentOnly } from "../_components/AgentGuide"; - Update the host CLI first, then check whether existing sandboxes need rebuilds. The standard installer follows the admin-promoted `lkg` release tag by default. diff --git a/docs/manage-sandboxes/workspace-files.mdx b/docs/manage-sandboxes/workspace-files.mdx index 2a89ce604d..2389e31c31 100644 --- a/docs/manage-sandboxes/workspace-files.mdx +++ b/docs/manage-sandboxes/workspace-files.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw workspace files", "deepagents state", "soul.md", "agents.md content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - OpenClaw stores its personality, user context, and behavioral configuration in a set of Markdown files inside the sandbox. diff --git a/docs/monitoring/monitor-sandbox-activity.mdx b/docs/monitoring/monitor-sandbox-activity.mdx index e4119c87a2..142618f4a3 100644 --- a/docs/monitoring/monitor-sandbox-activity.mdx +++ b/docs/monitoring/monitor-sandbox-activity.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use NemoClaw status commands, log streams, and OpenShell TUI views to inspect sandbox health, trace agent behavior, and diagnose problems. ## Prerequisites diff --git a/docs/network-policy/customize-network-policy.mdx b/docs/network-policy/customize-network-policy.mdx index 750587dc9a..87c9e59f15 100644 --- a/docs/network-policy/customize-network-policy.mdx +++ b/docs/network-policy/customize-network-policy.mdx @@ -11,8 +11,6 @@ content: skill: priority: 10 --- -import { AgentOnly } from "../_components/AgentGuide"; - Add, remove, or modify the endpoints the sandbox can reach. The NemoClaw repository declares the sandbox policy in a YAML file, and [NVIDIA OpenShell](https://github.com/NVIDIA/OpenShell) enforces it at runtime. diff --git a/docs/network-policy/integration-policy-examples.mdx b/docs/network-policy/integration-policy-examples.mdx index 131642a9c8..da3d29f7db 100644 --- a/docs/network-policy/integration-policy-examples.mdx +++ b/docs/network-policy/integration-policy-examples.mdx @@ -11,8 +11,6 @@ content: skill: priority: 15 --- -import { AgentOnly } from "../_components/AgentGuide"; - Use these examples when a sandbox is already installed and an integration needs network access. This page covers only integrations that NemoClaw currently ships as maintained policy preset YAML under `nemoclaw-blueprint/policies/presets/`. For complete blueprint examples that combine a model, agent harness, OpenShell policy, and integration workflow, refer to [Community Solutions](../resources/community-contributions). diff --git a/docs/reference/architecture.mdx b/docs/reference/architecture.mdx index 372e567671..6516123a63 100644 --- a/docs/reference/architecture.mdx +++ b/docs/reference/architecture.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw architecture", "nemoclaw agent architecture", "nemoclaw plu content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw combines a host CLI, an in-sandbox integration layer, and a versioned YAML blueprint that defines the sandbox image, policies, and inference profiles applied through OpenShell. ## System Overview diff --git a/docs/reference/cli-selection-guide.mdx b/docs/reference/cli-selection-guide.mdx index 6b421f23f1..933f07ba83 100644 --- a/docs/reference/cli-selection-guide.mdx +++ b/docs/reference/cli-selection-guide.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw vs openshell", "which cli", "nemoclaw cli", "openshell cli" content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw uses two host-side CLIs. Use `$$nemoclaw` for NemoClaw-managed workflows. Use `openshell` when you need a lower-level OpenShell operation that NemoClaw intentionally leaves available. diff --git a/docs/reference/commands.mdx b/docs/reference/commands.mdx index 8cb43dbdbf..b917ee4f07 100644 --- a/docs/reference/commands.mdx +++ b/docs/reference/commands.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw cli commands", "nemoclaw command reference", "nemo-deepagen content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - The `$$nemoclaw` CLI is the primary interface for managing NemoClaw sandboxes. diff --git a/docs/reference/enterprise-readiness.mdx b/docs/reference/enterprise-readiness.mdx index 82c3015a87..6d7ce2e216 100644 --- a/docs/reference/enterprise-readiness.mdx +++ b/docs/reference/enterprise-readiness.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw enterprise readiness", "nemoclaw support boundaries", "nemo content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - This page helps field teams and enterprise evaluators distinguish what NemoClaw supports today, what an operator must handle manually, what the OpenShell platform or inference provider owns, and what remains roadmap-only. Use it to answer enterprise readiness and support-boundary questions consistently instead of inferring answers from individual bug fixes. diff --git a/docs/reference/host-files-and-state.mdx b/docs/reference/host-files-and-state.mdx index 00e93aab05..abb95336a0 100644 --- a/docs/reference/host-files-and-state.mdx +++ b/docs/reference/host-files-and-state.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw host files", "nemoclaw state directory", "nemoclaw sandboxe content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw stores host-side configuration, registry metadata, operational state, transient install state, and local backups under `~/.nemoclaw/`. Use this page when you need to identify what a file does before deleting, backing up, or sharing diagnostics. diff --git a/docs/reference/network-policies.mdx b/docs/reference/network-policies.mdx index 01a22ecb64..9baf8db73f 100644 --- a/docs/reference/network-policies.mdx +++ b/docs/reference/network-policies.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw network policy", "sandbox egress control operator approval" content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw runs with a deny-by-default network policy. The sandbox can only reach endpoints that are explicitly allowed. OpenShell intercepts any request to an unlisted destination and prompts the operator to approve or deny it in real time through the TUI. diff --git a/docs/reference/troubleshoot-mcp-servers.mdx b/docs/reference/troubleshoot-mcp-servers.mdx index 5e7c9bf3b5..04ba9cb261 100644 --- a/docs/reference/troubleshoot-mcp-servers.mdx +++ b/docs/reference/troubleshoot-mcp-servers.mdx @@ -9,8 +9,6 @@ keywords: ["troubleshoot nemoclaw mcp", "mcp credential resolution", "mcp policy content: type: "troubleshooting" --- -import { AgentOnly } from "../_components/AgentGuide"; - Use the reported status or lifecycle error to choose the matching remediation. ## Credential Resolution Is Unknown diff --git a/docs/reference/troubleshooting.mdx b/docs/reference/troubleshooting.mdx index ad84ce43b2..36cbe512e4 100644 --- a/docs/reference/troubleshooting.mdx +++ b/docs/reference/troubleshooting.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw troubleshooting", "nemoclaw debug sandbox issues", "opencla content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - {/* markdownlint-disable MD014 */} This page covers common installation, onboarding, and runtime issues, along with resolution steps. diff --git a/docs/resources/engineer-agentic-documentation.mdx b/docs/resources/engineer-agentic-documentation.mdx new file mode 100644 index 0000000000..9f900751ca --- /dev/null +++ b/docs/resources/engineer-agentic-documentation.mdx @@ -0,0 +1,523 @@ +--- +# SPDX-FileCopyrightText: Copyright (c) 2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved. +# SPDX-License-Identifier: Apache-2.0 +title: "Engineer Documentation for AI Agents" +sidebar-title: "Engineer Agentic Docs" +description: "A practical architecture and operating model for making technical documentation reliable for both people and AI agents." +description-agent: "Explains how to engineer agent-ready documentation with one canonical source, Markdown and MCP delivery, thin routing skills, workflow automation, variants, governance, and deterministic quality gates. Use when designing agentic documentation, docs engineering systems, AI documentation workflows, or docs-as-code automation." +keywords: ["agentic documentation", "agent-ready docs", "documentation engineering", "AI documentation workflow", "docs as code", "llms.txt", "docs MCP server"] +content: + type: "how_to" +--- + +Agentic documentation is a documentation system that helps an AI agent find the right source, apply it to the user's context, take bounded action, and verify the result. +It serves people and agents from one governed source instead of maintaining a website, prompt library, and skill catalog as separate bodies of content. +It also places agents inside the documentation lifecycle so product changes arrive with accurate documentation instead of becoming a later handoff to a writing team. + +This guide turns the current NemoClaw documentation architecture into a reusable model for other engineering teams. +The file names and tools are NemoClaw examples, but the contracts apply to any docs-as-code stack. + + +Making HTML available to a model is not enough. +An agent-ready system needs explicit retrieval paths, task metadata, stable routes, safety boundaries, and evidence that the published guidance still matches the product. + + +## Define the Product Contract + +Start with observable outcomes instead of selecting tools. +A reliable agentic documentation system supports the following contract. + +| Capability | Contract | Evidence | +|---|---|---| +| Discover | The agent can identify the relevant document for a user task. | A task query returns the intended page and variant. | +| Retrieve | The agent can fetch clean, current, citable content. | A stable Markdown route or read-only search tool returns the canonical source. | +| Apply | The guidance includes decisions, prerequisites, steps, and boundaries. | The agent produces instructions scoped to the user's environment. | +| Act | The agent knows which operations are safe, which need approval, and which are out of scope. | Workflow instructions stop before credentials, destructive changes, or unsupported surfaces. | +| Verify | Every procedure ends with an observable success check. | The agent runs or recommends the documented validation step. | +| Maintain | Product changes can be traced to documentation owners and release evidence. | Pull-request gates detect stale, missing, or unpublished guidance. | + +Treat failures in any row as documentation defects. +A polished site with weak retrieval or verification is not agent-ready. + +## Move Documentation Into the Engineering Loop + +Many documentation workflows begin after engineering work is complete. +The writer identifies which features are shipping, finds the responsible engineers, interviews them to reconstruct the behavior, and then creates a separate documentation change. +This manual intake phase consumes time and can lose important context between implementation and publication. + +NemoClaw moves routine documentation work into the developer's engineering pull request. +The agent working on the developer's machine can inspect the code, tests, issue, and pull-request context while the change is still fresh. +Repository instructions tell that agent when documentation is required, where the content belongs, how to write it, and which checks prove the result. + +| Stage | Separate documentation handoff | Repository-embedded workflow | +|---|---|---| +| Discover changes | A writer collects release scope from meetings, messages, and issue lists. | The developer's agent inspects the current diff, issue, and changed behavior. | +| Transfer knowledge | A writer interviews engineers and reconstructs implementation details. | The agent reads the implementation and tests, then asks only when a decision or supported contract is unclear. | +| Draft documentation | A writer creates a later documentation task or pull request. | The agent updates the canonical page in the engineering pull request. | +| Review accuracy | Documentation and implementation may be reviewed at different times. | Reviewers see the behavior, tests, and documentation together. | +| Prepare a release | A writer performs a broad catch-up pass before publication. | Continuous updates reduce catch-up work, while the release workflow verifies completeness and creates the canonical changelog entry. | + +The repository provides a control stack for this workflow: + +- The root `AGENTS.md` defines repository-wide success criteria, product scope, and documentation expectations. +- `docs/AGENTS.md` defines the documentation role, source-of-truth rules, variant patterns, and verification requirements. +- `docs/CONTRIBUTING.md` defines the public writing, navigation, release, and review contracts. +- The `nemoclaw-contributor-update-docs` skill maps product changes to canonical pages and produces an evidence-backed documentation update. +- Build scripts, tests, hooks, previews, and publication workflows enforce the contracts after the agent edits the files. + +The expected pull-request loop is direct: + +1. The developer's agent reads the repository and documentation instructions. +2. It inspects the implemented behavior and its tests. +3. It decides whether the change has user-facing documentation impact. +4. It updates the canonical page in the same pull request when documentation is required. +5. It runs the relevant documentation and product-parity checks. +6. It reports the pages changed, behavior represented, and verification evidence. + +This model removes the need for a writer to manually reconstruct every incremental product change. +It does not remove documentation ownership. +It shifts the writer's role toward designing the system, maintaining the instructions, monitoring outcomes, and handling work that requires editorial judgment. +When the instructions are working, the writer can review by exception. +Routine pull-request updates that already meet the documentation contract do not need line editing, so the writer can focus on unclear product scope, structural pressure, and recurring failure patterns. + +## Use a Layered Architecture + +Keep content, delivery, routing, workflow, and assurance separate so each layer has one responsibility. + +```mermaid +flowchart TB + PRODUCT["Authoritative product sources
Code, schemas, commands, support data"] + SOURCE["Canonical task-oriented source
Concepts, procedures, reference, troubleshooting"] + BUILD["Deterministic build
Metadata, variants, prompts, route graph"] + HUMAN["Human delivery
Rendered documentation site"] + MACHINE["Machine delivery
Markdown routes, llms.txt, read-only docs search"] + ROUTING["Agent routing
Starter prompt and thin docs skill"] + WORKFLOW["Engineering workflows
Update, refactor, review, release"] + ASSURANCE["Assurance
Parity checks, links, previews, publication gates"] + PEOPLE["Readers"] + AGENTS["User-facing agents"] + + PRODUCT --> WORKFLOW + SOURCE --> BUILD + BUILD --> HUMAN + BUILD --> MACHINE + HUMAN --> PEOPLE + MACHINE --> ROUTING + ROUTING --> AGENTS + WORKFLOW --> SOURCE + PRODUCT --> ASSURANCE + ASSURANCE --> BUILD + ASSURANCE --> WORKFLOW +``` + +The source remains authoritative throughout the loop. +Prompts, skills, generated variants, search indexes, and rendered pages are delivery or control artifacts, not alternate sources of truth. + +## Establish One Canonical Owner + +Write each fact once in its authoritative layer, then produce the human and machine experiences from one publication source. +Product behavior may be authoritative in code, schemas, command metadata, or support data, while the documentation corpus remains the canonical published explanation. +Generate structured reference content from product sources when practical and use parity tests when prose must remain hand-written. + +NemoClaw uses MDX under `docs/` as its user-facing source of truth and generates agent-specific pages during the docs build. + +Apply these source rules: + +- Give each page one primary concept or user task. +- Organize procedures around the reader journey from choosing through setup, operation, validation, and troubleshooting. +- Keep reusable troubleshooting and reference facts with one canonical owner, then link to that owner. +- Generate tables and reference values from authoritative product data when that removes manual synchronization. +- Store navigation, slugs, and variant membership in a machine-readable index. +- Treat generated pages as disposable build output and never edit them by hand. +- Preserve published routes with direct redirects when content moves. + +Use frontmatter to describe the page for both people and retrieval systems. +The human description explains the value of the page, while the agent description states what the page helps with and when to select it. + +```yaml +--- +title: "Configure a Private Package Registry" +description: "Connect the product to a private package registry and verify authenticated downloads." +description-agent: "Configures and validates private package registry access. Use when users ask about registry credentials, package download failures, or enterprise package mirrors." +keywords: ["private registry", "package authentication", "enterprise mirror"] +content: + type: "how_to" +--- +``` + +Good routing metadata names the user intent, scope, and likely trigger phrases. +It does not repeat the page body or make unsupported product claims. + +## Publish Machine-Readable Delivery Paths + +Publish clean content through more than one retrieval path because agent environments have different capabilities. +Use this retrieval order: + +1. Search a read-only documentation service when the client supports a structured tool such as MCP. +2. Fetch a lightweight documentation index such as `llms.txt` when structured search is unavailable. +3. Fetch the specific Markdown page returned by search or listed in the index. +4. Fall back to rendered HTML only when a clean machine-readable route is unavailable. + +Each path should resolve to the same release and canonical page. +Do not make the agent reconcile copied content from several repositories or prompt bundles. + +Machine delivery is ready when the following checks pass: + +- Every published task page has a stable Markdown representation. +- The documentation index contains the current public route set. +- Search results return source URLs that an answer can cite. +- Variant-specific queries do not silently mix incompatible instructions. +- Moved pages redirect directly to a current published destination. +- Private drafts and unsupported features do not enter the public index. + +NemoClaw exposes its canonical pages through Markdown routes, `llms.txt`, and a read-only docs MCP server. +The [Use NemoClaw Docs with Your Coding Agents](agent-skills) page shows the user-facing retrieval flow. + +## Keep Agent Routing Thin + +Use prompts and skills to route the agent, not to store another copy of the docs. +A routing layer should tell the agent where to look, how to choose a source, and what response constraints to follow. + +A small routing skill needs only the following elements: + +- The canonical search endpoint and fallback documentation index. +- The preferred order for retrieving pages. +- The main task areas and their starting pages. +- Variant or platform selection rules. +- Safety requirements for approvals, credentials, and destructive actions. +- Citation and verification requirements. + +This pattern keeps the routing artifact stable while the product documentation changes frequently. +It also avoids large generated skills that drift from the public site, consume context, and create ambiguous ownership. + +Pair the routing skill with a starter prompt for users who have not installed project instructions. +Keep the starter prompt in a standalone canonical file, generate any website component from that file, and test that embedded or pinned copies still match it. + +## Encode Documentation Work as Agent Workflows + +Agentic docs include the workflows that maintain the corpus, not only the content agents retrieve. +Turn repeatable documentation engineering practices into bounded skills or repository instructions with explicit inputs, stop conditions, and evidence. + +| Workflow | Trigger | Required inputs | Completion evidence | +|---|---|---|---| +| Update docs | Product behavior changes or docs fall behind code. | Commit range, changed files, product scope, current pages. | Each user-visible change maps to an updated page or a documented no-impact decision. | +| Refactor information architecture | A section is oversized, duplicated, or hard to navigate. | Heading inventory, ownership map, inbound routes, supported variants. | One owner per topic, migrated routes, readable pages, and no content loss. | +| Review docs | A pull request changes a public procedure or reference. | Product implementation, tests, rendered preview, style policy. | Accuracy, links, route publication, and task verification pass. | +| Prepare a release | A release candidate is ready for documentation. | Merged change set, release scope, target version and date. | Canonical changelog entry lands before the release tag. | +| Publish | A docs change merges or a release tag is created. | Validated source, approved environment, immutable revision. | Staging or public output points to the expected revision. | + +NemoClaw applies this model through layered repository instructions and specialized contributor and maintainer skills. +The update workflow scans commits, respects a documentation skip list, maps behavior to canonical pages, and verifies the build. +The refactor workflow inventories every topic, defines ownership and URL migration contracts, and validates every supported variant. + +Design each workflow to produce evidence instead of a generic statement that the docs were updated. +The agent should report the files changed, source behavior represented, checks run, and intentionally deferred work. + +## Let the Corpus Grow and Tend It + +Do not require every engineering pull request to redesign the documentation structure. +Let agents make small, accurate updates to the current canonical page while the product evolves. +Restructure the corpus after repeated changes reveal its real shape. + +This is continuous growth with periodic curation. +The daily engineering loop keeps behavior and documentation aligned, while a daily or weekly maintenance pass improves sections that have outgrown their original purpose. + +Use observable signals to start a restructuring pass: + +- A page serves several distinct user tasks. +- A section has become difficult to scan or navigate. +- A paragraph contains several decisions, procedures, or failure modes. +- The same guidance appears in several pages. +- A common task is buried under an unrelated heading or navigation group. +- Product variants have started to drift because their shared and distinct behavior is unclear. + +During the maintenance pass, split overgrown pages, clarify headings, move reusable reference material to one owner, remove duplication, and preserve published routes. +If agents repeatedly produce the same structural or style problem, improve the repository instructions or workflow skill so later pull requests correct the pattern at its source. + +This cadence avoids premature reorganization while keeping the documentation usable as it grows. +It also reserves the writer's time for structure, user journeys, and editorial quality instead of routine transcription. + +## Generate Variants Without Duplicating Sources + +Many products publish documentation for editions, platforms, runtimes, or deployment models. +Generate a variant only when most of the source is shared. + +Use these rules: + +- Replace a build-time placeholder when only a literal name or command differs. +- Use a conditional block when the workflow, behavior, state layout, or security boundary differs. +- Use a separate source page when most of the procedure is variant-specific. +- Keep variant membership and route slugs in the navigation model. +- Regenerate every variant before route and link validation. +- Inspect rendered variants for broken lists, joined paragraphs, and missing context. + +NemoClaw generates shared OpenClaw, Hermes, and Deep Agents pages from one MDX source. +Its build rewrites the host CLI placeholder, removes inapplicable conditional blocks, and publishes a distinct route for each supported agent. + +### Separate the Source from Its Variant Targets + +Authors edit the normal source page under `docs/`. +For this guide, the only source is `docs/resources/engineer-agentic-documentation.mdx`. +The repository does not maintain separate OpenClaw, Hermes, and Deep Agents source copies. + +### Author Shared and Variant-Specific Content + +Write ordinary prose once when the meaning is the same for every supported agent. +Use the $$nemoclaw placeholder when the only difference is the host CLI binary name. +The variant build resolves that placeholder as follows: + +| Generated variant | Placeholder output | +|---|---| +| OpenClaw | `nemoclaw`. | +| Hermes | `nemohermes`. | +| Deep Agents | `nemo-deepagents`. | + +Use the placeholder in prose, inline code, and fenced command examples on shared source pages. +Do not duplicate a paragraph or command block only to change the binary name. +Do not use the placeholder on a single-variant source page because that page does not pass through variant generation and would publish the placeholder literally. + +Use an `` block when the content differs by behavior, workflow, state layout, support, or agent-specific wording. +For example, start a Hermes-only block with <AgentOnly variant="hermes"> and close it with </AgentOnly>. +The `variant` attribute can name one variant or a comma-separated set such as `openclaw,hermes`. + +Do not import `AgentOnly` from a React component. +The canonical page is an intermediate source that the variant resolver compiles before Fern reads it. +The resolver removes the directive tags and keeps the block body only when the target variant appears in the `variant` attribute. + +Apply this decision rule: + +- Use ordinary shared prose when the meaning is identical. +- Use the host CLI placeholder when only the binary name differs. +- Use `` when the meaning or procedure differs. +- Use a separate source page when most of the page is specific to one agent. + +This page encodes the two dollar signs as character entities so a future generated variant can display the literal placeholder instead of resolving it. + +### Treat `AgentOnly` as a Build-Time Directive + +The `` syntax resembles an MDX component, but NemoClaw treats it as a build-time directive. +Agent variant selection does not depend on pathname detection or client-side logic in the rendered site. +The canonical source does not need an import because Fern receives only the resolved generated page. + +For each navigation target, `scripts/sync-agent-variant-docs.mts` reads the requested variant from `docs/index.yml` and parses the canonical source as text. +When an `` directive lists the active variant, the resolver copies its content into the generated page. +When the retained content starts with a Markdown list item, it discards blank lines immediately inside the opening and closing tags so wrapper formatting does not split the list. +For other retained content, it preserves those boundary blank lines and all interior blank lines so paragraphs and code sections keep their intended separation. +When the directive does not list the active variant, the resolver omits the body. +In both cases, it removes the opening and closing directive tags before writing the generated MDX. + +Keep the opening and closing `` tags at the first column on their own lines, and do not nest these blocks. +That line-oriented structure is the generator's authoring interface, and the resolver reports nested, unexpected, or unclosed blocks as errors. + +The `CLI_SENTINEL` constant and replacement table live in `scripts/sync-agent-variant-docs.mts` so placeholders can be resolved inside frontmatter, ordinary prose, inline code, and fenced command blocks before Fern renders the page. +Use $$nemoclaw for all shared host CLI references and wrap it in backticks when it should render as inline code. + +The resolver rejects a generated page if it still contains an unresolved line-oriented `` directive or a runtime agent component. +These checks make static resolution a publishing invariant instead of relying on client-side hydration to correct variant content. + +Variant membership is explicit in `docs/index.yml`. +Each agent variant contains its own navigation tree, and a shared page appears in a tree through a generated target path with this contract: + +```text +_build/agent-variants//..generated.mdx +``` + +The `` value is `openclaw`, `hermes`, or `deepagents`. +The directory and base name before the variant suffix must match the canonical source path under `docs/`. + +If this source-only guide is added to Fern navigation, it would use the following mapping: + +| Variant | Generated target in `docs/index.yml` | Published route suffix | +|---|---|---| +| OpenClaw | `_build/agent-variants/resources/engineer-agentic-documentation.openclaw.generated.mdx` | `/user-guide/openclaw/resources/engineer-agentic-documentation`. | +| Hermes | `_build/agent-variants/resources/engineer-agentic-documentation.hermes.generated.mdx` | `/user-guide/hermes/resources/engineer-agentic-documentation`. | +| Deep Agents | `_build/agent-variants/resources/engineer-agentic-documentation.deepagents.generated.mdx` | `/user-guide/deepagents/resources/engineer-agentic-documentation`. | + +The site and version prefixes are added by the Fern site configuration. +The route suffix above comes from the variant, section, and page slug hierarchy in `docs/index.yml`. + +### Use the Fern Index as the Mapping Layer + +The version entry in `fern/docs.yml` points Fern to `docs/index.yml`. +That index defines the navigation and published route tree for every supported agent variant. + +An OpenClaw navigation entry for this guide would use the following shape: + +```yaml +- page: "Engineer Agentic Docs" + path: _build/agent-variants/resources/engineer-agentic-documentation.openclaw.generated.mdx + slug: engineer-agentic-documentation +``` + +The `path` tells Fern which generated MDX file to render. +The `slug` tells Fern the page's final route segment. +The surrounding `resources` section and `openclaw` variant contribute the parent route segments. + +This separation has several consequences: + +- A source file's filesystem location does not independently define its public URL. +- The same source can be published in several variant trees with the same page slug. +- A source can remain single-variant by pointing navigation directly to its source MDX file instead of a generated target. +- Moving or renaming a published page requires a navigation update and a redirect review, even when the source file stays in the same directory. +- Generated filenames are an interface with the generator and should not use an arbitrary naming pattern. + +### Resolve and Render Each Target + +The resolver is `scripts/sync-agent-variant-docs.mts`. +Run it directly through `npm run docs:sync-agent-variants`, or let `npm run docs` invoke it through the shared `docs:prepare` step. + +The script reads `docs/index.yml` before it reads shared source pages. +For each recognized generated path, it performs the following work: + +1. It reads the active navigation variant from the `openclaw`, `hermes`, or `deepagents` tree. +2. It removes the `_build/agent-variants/` prefix and the `..generated.mdx` suffix. +3. It resolves the remaining path to one canonical `.mdx` source under `docs/`. +4. It renders that source for the active variant. +5. It writes the result under `docs/_build/agent-variants/` using the path declared in the index. +6. It removes stale generated files that no longer have a navigation target. + +Rendering replaces the host CLI placeholder with the correct binary name, removes conditional blocks that do not apply to the active variant, and adjusts relative image and component-import paths for the deeper generated directory. +Route-style links between documentation pages stay tied to the published navigation model instead of the generated filesystem location. + +The generated directory is ignored by Git. +Contributors commit the canonical source and `docs/index.yml` mapping, while the docs build recreates the variant files locally and in CI. + +### Validate the Complete Route Graph + +The `npm run docs` command prepares generated content before Fern validation. +The validation sequence checks the starter prompt, regenerates the agent variants, verifies generated-page freshness, derives published routes from `docs/index.yml`, and runs the pinned Fern checker. + +This order matters because Fern cannot validate a variant route until the generated target named by `docs/index.yml` exists. +It also ensures that source edits, variant transforms, navigation mappings, and published routes are tested as one contract. + +## Treat Documentation as an Executable Product Surface + +Build deterministic checks around the contracts that matter to users and agents. +Syntax validation alone does not catch behavioral drift. + +| Gate | Defect it prevents | NemoClaw example | +|---|---|---| +| Source formatting | Unreadable diffs and inconsistent authoring. | Markdown linting, one sentence per source line, and copyable command rules. | +| Generated freshness | Stale prompts or agent variants. | Build-time generation followed by read-only freshness checks. | +| Route graph | Links or redirects that target unpublished pages. | Published-route validation derived from `docs/index.yml`. | +| Product parity | Reference documentation that disagrees with the product. | CLI command, flag, installer, and environment-variable parity checks. | +| Pull-request preview | Layout or navigation failures hidden by source checks. | An isolated Fern preview for each docs pull request. | +| Staging publish | A merge that cannot produce the deployed site. | Validation and publication from `main`. | +| Public release gate | Public docs from an unapproved or detached revision. | Release-tag publication only when the tagged commit is reachable from `main`. | + +Run the narrowest checks on every relevant change and keep broader checks at integration or release boundaries. +Tests should derive routes and behavior from the same source models used by the product instead of maintaining a second hard-coded catalog. + +## Govern What Agents May Publish + +Fast documentation automation needs a stronger scope gate, not a weaker one. +Documentation can accidentally turn an experiment into an apparent supported product surface. + +Define the following controls: + +- Require an accepted product decision before documenting a new integration, recipe, or supported workflow as canonical behavior. +- Maintain an explicit skip list for merged features that are not ready for public documentation. +- Block restricted terms and private implementation details from generated output. +- Separate public user guidance from contributor and maintainer procedures. +- Require agent workflows to stop before handling secrets, changing accounts, or performing destructive operations without approval. +- Assign an owner and lifecycle expectation to every canonical page and generated artifact. + +NemoClaw applies the same scope gate to code review and documentation review. +A working example and a green build establish technical evidence, but they do not establish product approval. + +## Keep High-Judgment Work Human-Owned + +Agents execute documented rules well when the repository gives them accurate context and deterministic checks. +People remain responsible for decisions that create or change those rules. + +Keep human ownership over the following work: + +- Decide whether a feature, integration, or workflow is a supported product surface. +- Decide which user problem a page owns and where readers should encounter it. +- Resolve conflicts between implementation details, product intent, security requirements, and user expectations. +- Restructure sections when accumulated changes reveal a better organization. +- Set the editorial voice, evidence standard, release narrative, and publication policy. +- Review recurring agent mistakes and improve the instructions, skills, tests, or source structure that allowed them. + +Formal information-architecture terminology can help teams discuss this work, but the terminology is not the source of quality. +If you can recognize that a page is doing too many jobs, decide where a user expects to find a topic, and give each topic one clear owner, you are already practicing the part of information architecture that this operating model needs. + +The durable division of labor is concise. +Agents handle repeatable work close to the engineering source, while people own product meaning, system design, exceptions, and editorial judgment. + +## Measure Retrieval and Task Quality + +Measure whether agents can complete documentation-backed tasks, not only whether pages receive traffic. + +Track a small evaluation set across common and high-risk user journeys: + +- Retrieval accuracy, measured by whether the intended canonical page appears in the first results. +- Variant accuracy, measured by whether the answer stays within the selected platform or product edition. +- Citation coverage, measured by whether behavior claims point to the current source page. +- Task completion, measured by whether the documented procedure reaches its success check. +- Safety compliance, measured by whether the agent stops at approval, credential, and destructive-action boundaries. +- Freshness, measured by the delay between a product change and its verified documentation update. +- Editorial intervention, measured by how often routine documentation changes require a manual rewrite after the agent follows the repository workflow. +- Drift detection, measured by which parity gate catches an intentionally stale fixture. + +Keep evaluation prompts versioned with the documentation system. +Add a regression case when a user report or review reveals that an agent selected the wrong source, mixed variants, skipped a safety boundary, or failed to verify the outcome. + +## Adopt the Model in Phases + +Build the smallest complete loop first, then add sophistication where evidence shows a need. + +| Phase | Deliverable | Exit condition | +|---|---|---| +| Foundation | One canonical, task-oriented Markdown or MDX corpus. | Humans can complete one priority journey from the source docs. | +| Machine delivery | Stable Markdown routes and a lightweight index. | An agent can retrieve and cite the same priority journey without scraping HTML. | +| Routing | A starter prompt and thin routing skill. | The agent selects the correct page, variant, and verification step. | +| Workflow | Repository instructions and an update-docs workflow. | A product change produces a traceable docs-impact decision. | +| Assurance | Route, link, generation, parity, and preview gates. | A deliberately stale or broken fixture fails before merge. | +| Scale | Variants, structured docs search, release automation, and evaluation suites. | Additional products or platforms do not create parallel content ownership. | + +Do not begin with a large generated skill catalog or autonomous publishing workflow. +Begin with one high-value user journey and prove the complete source-to-retrieval-to-verification loop. + +## Map the NemoClaw Implementation + +The current NemoClaw repository provides concrete examples for each layer. + +| Concern | NemoClaw implementation | +|---|---| +| Canonical content | `docs/**/*.mdx`. | +| Repository-wide documentation contract | `AGENTS.md`. | +| Authoring and review policy | `docs/CONTRIBUTING.md` and `docs/AGENTS.md`. | +| Navigation and variants | `docs/index.yml`. | +| Site and redirect configuration | `fern/docs.yml` and `fern/fern.config.json`. | +| Machine delivery | Published Markdown routes, `llms.txt`, and the read-only docs MCP server. | +| Routing skill | `.agents/skills/nemoclaw-user-guide/SKILL.md`. | +| Starter prompt | `docs/resources/starter-prompt.md` and `scripts/generate-starter-prompt.mts`. | +| Product-owned generated facts | `ci/platform-matrix.json` and `scripts/generate-platform-docs.py`. | +| Variant generation | `scripts/sync-agent-variant-docs.mts`. | +| Route validation | `scripts/check-docs-published-routes.mts`. | +| Update workflow | `.agents/skills/nemoclaw-contributor-update-docs/SKILL.md`. | +| Information-architecture workflow | `.agents/skills/nemoclaw-maintainer-refactor-docs/SKILL.md`. | +| Pull-request assurance | Docs link, product parity, and preview workflows under `.github/workflows/`. | +| Release history | Dated entries under `docs/changelog/` that land before the release tag. | +| Release publication | Staging publication from `main` and public publication from release tags. | + +Use this map as a reference architecture, not a requirement to adopt the same vendor or repository layout. +Preserve the contracts when adapting the implementation. + +## Review Readiness + +Before calling a documentation system agent-ready, confirm the following conditions: + +- One governed source produces the human and machine documentation experiences. +- Every priority task has routing metadata, a stable machine-readable route, and a verification step. +- Search, the docs index, and rendered navigation resolve to the same release and canonical owner. +- Routing prompts and skills point to the source instead of copying it. +- Variant generation is deterministic and variant behavior is tested. +- Agent workflows define scope, approvals, stop conditions, and completion evidence. +- Pull requests validate generated output, routes, links, product parity, and rendered previews. +- Release publication uses an approved immutable revision. +- Retrieval, citation, task, variant, safety, and freshness regressions have repeatable evaluations. + +The first practical milestone is one product journey that passes every condition above. +Expand the system only after that loop is reliable. diff --git a/docs/security/best-practices.mdx b/docs/security/best-practices.mdx index cac58db0f6..acd2c2059b 100644 --- a/docs/security/best-practices.mdx +++ b/docs/security/best-practices.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw security best practices", "sandbox security controls risk f content: type: "concept" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw ships with deny-by-default security controls across five layers: network, filesystem, process, gateway authentication, and inference. You can tune every control, but each change shifts the risk profile. This page documents each configurable control, its default, what it protects, the concrete risk of relaxing it, and a recommendation for common use cases. diff --git a/docs/security/credential-rotation.mdx b/docs/security/credential-rotation.mdx index 11cb270d3c..a33ab41547 100644 --- a/docs/security/credential-rotation.mdx +++ b/docs/security/credential-rotation.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw credential rotation", "rotate api key", "update inference k content: type: "how_to" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw uses different rotation paths for inference, messaging, and web search credentials. Inference credentials can normally be updated while reusing the existing sandbox. Messaging tokens and web search settings require a rebuild or recreation because their configuration is applied when the sandbox image starts. diff --git a/docs/security/credential-storage.mdx b/docs/security/credential-storage.mdx index 1cf51df669..a52818044b 100644 --- a/docs/security/credential-storage.mdx +++ b/docs/security/credential-storage.mdx @@ -9,8 +9,6 @@ keywords: ["nemoclaw credential storage", "openshell provider", "api key securit content: type: "reference" --- -import { AgentOnly } from "../_components/AgentGuide"; - NemoClaw does not persist provider credentials to host disk. The OpenShell gateway is the only system of record for stored credentials. diff --git a/scripts/sync-agent-variant-docs.mts b/scripts/sync-agent-variant-docs.mts index e92d1be2c2..64ef567e7e 100644 --- a/scripts/sync-agent-variant-docs.mts +++ b/scripts/sync-agent-variant-docs.mts @@ -100,7 +100,9 @@ function stripAgentOnlyBlocksForVariant(body: string, activeVariant: AgentVarian throw new Error(`nested AgentOnly block at body line ${index + 1}`); } if (line.match(/^<\/AgentOnly>\s*$/)) { - if (openBlock.include) renderedLines.push(...openBlock.lines); + if (openBlock.include) { + renderedLines.push(...trimAgentOnlyListBoundaryBlankLines(openBlock.lines)); + } openBlock = undefined; continue; } @@ -132,6 +134,19 @@ function stripAgentOnlyBlocksForVariant(body: string, activeVariant: AgentVarian return renderedLines.join("\n"); } +function trimAgentOnlyListBoundaryBlankLines(lines: string[]): string[] { + const firstContentLine = lines.find((line) => line.trim() !== ""); + if (!firstContentLine?.match(/^\s*(?:[-+*]|\d{1,9}[.)])\s+/)) return lines; + + let start = 0; + let end = lines.length; + + while (start < end && lines[start].trim() === "") start += 1; + while (end > start && lines[end - 1].trim() === "") end -= 1; + + return lines.slice(start, end); +} + function agentOnlyVariantMatches(variant: string, activeVariant: AgentVariant): boolean { return variant .split(",") @@ -139,6 +154,29 @@ function agentOnlyVariantMatches(variant: string, activeVariant: AgentVariant): .includes(activeVariant); } +function assertStaticallyResolvedVariantPage( + body: string, + activeVariant: AgentVariant, + sourcePath?: string, +): void { + const unresolved: string[] = []; + if (/^\s*import\s+.*AgentGuide["'];?\s*$/m.test(body)) { + unresolved.push("AgentGuide import"); + } + if (/^\s*<\/?AgentOnly\b/m.test(body)) { + unresolved.push("AgentOnly directive"); + } + if (/<(?:AgentCli|AgentProductName|GuideLink)\b/m.test(body)) { + unresolved.push("runtime agent component"); + } + if (unresolved.length === 0) return; + + const source = sourcePath ? path.relative(repoRoot, sourcePath) : "agent variant source"; + throw new Error( + `${source} left unresolved ${unresolved.join(", ")} in the ${activeVariant} generated variant`, + ); +} + export function renderAgentVariantPage( source: string, variant: AgentVariant, @@ -147,10 +185,7 @@ export function renderAgentVariantPage( const { frontmatter, body } = splitFrontmatter(source); const commandsReference = isCommandsReferenceSource(options.sourcePath); const renderedFrontmatter = renderFrontmatter(frontmatter, variant, commandsReference); - let renderedBody = stripAgentOnlyBlocksForVariant( - body.replace(/^import \{ AgentOnly \} from "\.\.\/_components\/AgentGuide";\n\n?/m, ""), - variant, - ); + let renderedBody = stripAgentOnlyBlocksForVariant(body, variant); if (commandsReference) { renderedBody = transformNemoclawCliInvocations(renderedBody, variant); } @@ -158,6 +193,7 @@ export function renderAgentVariantPage( .replaceAll(CLI_SENTINEL, cliForVariant(variant)) .replace(/\n{3,}/g, "\n\n") .trimStart(); + assertStaticallyResolvedVariantPage(renderedBody, variant, options.sourcePath); if (options.sourcePath && options.outputPath) { renderedBody = rewriteRelativePaths(renderedBody, options.sourcePath, options.outputPath); diff --git a/test/agent-variant-docs.test.ts b/test/agent-variant-docs.test.ts index 134b6b4feb..4dfd4c713d 100644 --- a/test/agent-variant-docs.test.ts +++ b/test/agent-variant-docs.test.ts @@ -11,8 +11,6 @@ const source = `--- title: "Example" description-agent: "Use when looking up $$nemoclaw commands." --- -import { AgentCli, AgentOnly } from "../_components/AgentGuide"; - OpenClaw only. @@ -30,7 +28,7 @@ Gateway agents only. $$nemoclaw list \`\`\` -Use for the current variant. +Use \`$$nemoclaw\` for the current variant. `; describe("agent variant docs", () => { @@ -83,10 +81,14 @@ title: "Example" ## Prerequisites + - NemoClaw installed. + + - NemoHermes installed. + - A local model server running. `, @@ -98,6 +100,27 @@ title: "Example" expect(rendered).not.toContain("NemoHermes installed."); }); + it("preserves paragraph boundaries around retained variant prose", () => { + const rendered = renderAgentVariantPage( + `--- +title: "Example" +--- +Shared paragraph. + + + +OpenClaw paragraph. + + +Following paragraph. +`, + "openclaw", + ); + + expect(rendered).toContain("Shared paragraph.\n\nOpenClaw paragraph."); + expect(rendered).toContain("OpenClaw paragraph.\n\nFollowing paragraph."); + }); + it("rejects nested AgentOnly blocks before they leak into generated variants", () => { const nested = `--- title: "Example" @@ -113,9 +136,45 @@ OpenClaw content. expect(() => renderAgentVariantPage(nested, "openclaw")).toThrow("nested AgentOnly block"); }); + it("rejects inline AgentOnly directives before they reach Fern", () => { + const inline = `--- +title: "Example" +--- +OpenClaw only. +`; + + expect(() => renderAgentVariantPage(inline, "openclaw")).toThrow( + "unresolved AgentOnly directive", + ); + }); + + it("rejects runtime agent components before they reach Fern", () => { + const runtimeComponent = `--- +title: "Example" +--- +Use for the current variant. +`; + + expect(() => renderAgentVariantPage(runtimeComponent, "hermes")).toThrow( + "unresolved runtime agent component", + ); + }); + + it("rejects AgentGuide imports before they reach Fern", () => { + const runtimeImport = `--- +title: "Example" +--- +import { AgentOnly } from "../_components/AgentGuide"; +`; + + expect(() => renderAgentVariantPage(runtimeImport, "deepagents")).toThrow( + "unresolved AgentGuide import", + ); + }); + it("rewrites relative imports but preserves Fern route links for generated build output", () => { const rendered = renderAgentVariantPage( - `${source}\nSee [Commands](../reference/commands#$$nemoclaw-list).\nSee [Backup](backup-restore).\n![Diagram](images/diagram.png)\n`, + `${source}\nimport { Example } from "../_components/Example";\n\nSee [Commands](../reference/commands#$$nemoclaw-list).\nSee [Backup](backup-restore).\n![Diagram](images/diagram.png)\n`, "hermes", { outputPath: @@ -124,9 +183,7 @@ OpenClaw content. }, ); - expect(rendered).toContain( - 'import { AgentCli, AgentOnly } from "../../../_components/AgentGuide";', - ); + expect(rendered).toContain('import { Example } from "../../../_components/Example";'); expect(rendered).toContain("[Commands](../reference/commands#nemohermes-list)"); expect(rendered).toContain("[Backup](backup-restore)"); expect(rendered).toContain("![Diagram](../../../manage-sandboxes/images/diagram.png)"); diff --git a/test/check-docs-published-routes.test.ts b/test/check-docs-published-routes.test.ts index 368029d89b..5ae2e6cbe6 100644 --- a/test/check-docs-published-routes.test.ts +++ b/test/check-docs-published-routes.test.ts @@ -90,8 +90,6 @@ description: "Commands." description-agent: "Commands." keywords: ["commands"] --- -import { AgentOnly } from "../_components/AgentGuide"; - ${body} `; } diff --git a/test/sync-agent-variant-docs.test.ts b/test/sync-agent-variant-docs.test.ts index 3ab5f912ab..d6c49b3ba2 100644 --- a/test/sync-agent-variant-docs.test.ts +++ b/test/sync-agent-variant-docs.test.ts @@ -34,8 +34,6 @@ describe("sync-agent-variant-docs", () => { it("rewrites only NemoClaw CLI invocations for the NemoHermes reference", () => { const rendered = renderHermesCommandsVariant(`${FRONTMATTER} -import { AgentOnly } from "../_components/AgentGuide"; - ### \`nemoclaw list\` \`\`\`bash @@ -66,8 +64,6 @@ The gateway state path is \`~/.local/state/nemoclaw\`. it("rewrites only NemoClaw CLI invocations for the NemoDeepAgents reference", () => { const rendered = renderDeepAgentsCommandsVariant(`${FRONTMATTER} -import { AgentOnly } from "../_components/AgentGuide"; - ### \`nemoclaw list\` \`\`\`bash