Add or Adopt Docs in a Repo
Use this path when you want to add or adopt documentation and the docs analyze/apply workflow to a repository.
If you are developing inside the OAT repo itself, replace oat ... with
pnpm run cli -- ....
What this gives you
- plain Markdown files or a docs app scaffolded with OAT defaults (Fumadocs or MkDocs)
index.md-driven navigation- docs analysis and apply skills installed via the docs pack
- a repeatable workflow for finding gaps, verifying claims, and applying docs changes
1. Initialize OAT in the repo
oat init --scope projectThis sets up the base OAT structure used by the CLI and installed tool packs.
2. Install the docs workflow skills
Preferred direct path:
oat tools install docsInteractive path:
oat tools installLegacy pack-specific path:
oat init tools docsThe docs pack installs authoring-docs, oat-docs-authoring,
oat-docs-analyze, oat-docs-apply, oat-agent-instructions-analyze, and
oat-agent-instructions-apply. For this quickstart, the authoring and docs
analysis/apply skills are the parts you need immediately.
3. Set up the documentation surface
Choose Markdown files or a framework app, using the guided skill or direct CLI.
3a. Preferred: the oat-docs-bootstrap skill (guided)
/oat-docs-bootstrapThe docs-bootstrap skill offers Markdown, Fumadocs, and MkDocs. Configured tooling is authoritative; framework evidence is checked before plain-directory evidence. A root README alone does not trigger adoption, and an empty selected target stays fresh setup. Markdown uses file checks and an adopt/audit handoff, with no app questions, dependencies, framework patches, docs-root AGENTS, or site build.
For framework apps, it wraps oat docs init with a seven-step guided flow: preflight detection (repo shape + existing-setup conflict surfacing), richer input gathering (including a site name distinct from the package name), the CLI invocation itself, labeled post-patches for open CLI gaps, install + build verification, post-scaffold config inspection, and a chunked educational walkthrough.
What the framework path adds over the raw CLI:
- Preflight + conflict resolution. Detects existing
documentationconfig / docs app dir / rootAGENTS.mdsection and walks a deliberate resolution choice (replace, abort, repair, or deferred second-app) before any mutation. - Richer inputs. Asks for a site name separate from the package name, so
createDocsConfig()/ layout branding / page metadata all converge on the same display title. - Post-scaffold patches for open CLI gaps. Applied only when capability detection shows the CLI hasn't closed the gap. Each patch is labeled (e.g.,
<!-- FP-12 patch -->) so it can be removed deterministically when the upstream fix lands:- FP-11 — Turbopack
rootfor nested-standalone Fumadocs apps (suppresses the multiple-lockfile warning) - FP-12 —
export const metadata = { title, description }inapp/layout.tsx(the only thing that populates page<title>, meta description, and Open Graph —DocsLayout.branding.titleonly renders nav chrome, andcreateDocsConfig()ignorestitle/descriptionentirely) - FP-13 — four scaffold-content fixes (empty per-page
description:frontmatter, bare install/build commands missing--filterorcd-prefix for monorepo/nested shapes, falsedocs:lintclaim whenlint=none, Node version line that doesn't match the consuming repo's.nvmrc/engines.node) - FP-15 — writes a task-framed
<appRoot>/AGENTS.mdbridge file when the CLI hasn't scaffolded one. The bridge is the docs app's runtime agent reference (separate audience fromdocs/contributing.md) - FP-16 — rewrites
docs/index.md## Contentslinks to the.md-suffixed form that@open-agent-toolkit/docs-transformsnormalizes at build time (agent-friendlier than extension-less; routes correctly) - FP-17 — trims
docs/contributing.md's "Agent guidance" section to a one-line pointer at the docs-appAGENTS.md, restoring the three-surfaces separation
- FP-11 — Turbopack
- Build verification. Runs install + build, classifies failures against known patterns, stops on unknown errors rather than guessing.
- Config inspection. Reads
.oat/config.jsonback, verifies paths exist on disk, handles the nested-standalone dual-config case, and collects therequireForProjectCompletionopt-in explicitly. - Root-build explanation. When the CLI safely patches a compatible Turbo root
buildscript, the walkthrough explains why the filter was added, shows the diff shape, and documents how to adjust or revert it. When the CLI skips the patch, the walkthrough relays the recommended manual snippet. - Educational walkthrough. Seven sections covering the
documentationconfig, the authored-source/generated-navigation model, the## Contentscontract (with extension discipline), the three agent-instruction surfaces (rootAGENTS.mdpointer / docs-appAGENTS.md/docs/contributing.md), Fumadocs internals (or MkDocs Minimum Contract), and the OAT docs ecosystem (oat-project-document,oat-docs-analyze,oat-docs-apply). - Optional content kickoff. Hands off to
oat-docs-analyze+oat-docs-applyif you want to populate initial repo-specific content immediately.
Capability-gated: every post-patch self-ratchets off as CLI fixes land upstream. The skill's labeled markers (<!-- FP-NN patch -->) are how you find them later when the CLI catches up.
3b. Direct CLI (deterministic / non-interactive)
oat docs init --app-name my-docsIn interactive mode, you'll be prompted to choose a framework:
- Markdown — authored files, context indexes, and Contents maps without a site framework
- Fumadocs — Next.js-based static site with FlexSearch, Mermaid diagrams, dark/light mode, and code copy buttons
- MkDocs — MkDocs Material with the OAT contributor contract
Framework default placement:
- monorepo:
apps/my-docs - single-package repo:
my-docs/at repo root
You can override the target and framework explicitly:
# Fumadocs (non-interactive)
oat docs init --app-name my-docs --framework fumadocs --yes
# MkDocs (non-interactive)
oat docs init --app-name my-docs --framework mkdocs --yesUse 3b when you want a fully headless scaffold (CI, automation) and can accept the raw CLI output without the guided post-patches.
For compatible Turbo monorepos, the CLI also patches the repo-root
package.json by default so root pnpm build excludes the new docs app and a
root build:docs script is available for docs-only builds. Use
--no-root-patch to opt out. --dry-run is available only for Markdown
files/config/guidance; it does not preview framework package patches.
Plain Markdown: fresh setup or additive adoption
# Fresh default root: docs/ in every repository shape
oat docs init --framework markdown --site-name "Project Docs" --yes
# Existing content: preview, then explicitly adopt without overwriting files
oat docs init --framework markdown --target-dir handbook --adopt --dry-run --yes
oat docs init --framework markdown --target-dir handbook --adopt --yesMarkdown creates missing index.md and contributing.md baseline pages and
records documentation.tooling: "markdown", the literal root, and its authored
<root>/index.md. A nested <root>/docs remains a subsection. Root managed
Documentation guidance names these paths; bootstrap creates no docs-root
AGENTS.md and preserves one already present. It creates no app package,
framework config, dependencies, or install/dev/build commands. Lint/format
choices default to none and never install tools.
A default setup records:
{
"documentation": {
"tooling": "markdown",
"root": "docs",
"index": "docs/index.md"
}
}A populated target is refused without --adopt, including with --yes.
Adoption preserves existing page/index/local-instruction bytes and adds only
missing baseline files. Missing child indexes, metadata, context, or Contents
remain audit gaps: run oat-docs-analyze, then oat-docs-apply for approved
repairs. Successful config/guidance setup does not prove full content conformity.
See Markdown setup details for initial Contents
discovery and repair advice for optional child indexes and unreadable directories.
Incompatible declared tooling/root/index or unsafe paths are refused before
writes. Selecting a framework explicitly retains its existing replacement
prompt/--yes behavior, including over configured Markdown: config may change
while old Markdown files remain. This is not an automatic content migration.
Dry-run writes nothing. Manual-required or blocked guidance returns partial
and exit 1; files/config are planned, not completed. A real partial run may
already have created baseline files and config: follow its reported state and
preserve those files when retrying. Converged repeated adoption returns ok,
exit 0, and no changes.
Markdown indexes are authored. Optional inventories require external output:
oat docs generate-index --docs-dir handbook --output .oat/docs-manifest.mdDefault generation is refused for configured Markdown. External output cannot
be inside the full configured content root or overwrite its authored index,
even with a narrowed --docs-dir. It never repoints documentation.index.
3c. Existing MkDocs content
Bootstrap is not the migration workflow. If you have an existing MkDocs site and want to switch to Fumadocs, treat that as a separate migration workstream. The CLI migration helper can convert common Markdown syntax and frontmatter:
oat docs migrate --docs-dir docs --config mkdocs.yml --applyRun without --apply first to preview changes. For a full MkDocs-to-Fumadocs
refactor, use the assigned migration handoff guide or project plan; do not make
oat-docs-bootstrap own that migration.
4. Start authoring docs with the OAT contract
Use oat-docs-authoring for targeted OAT Markdown/Fumadocs content edits or local
restructuring. It uses authoring-docs for the portable documentation baseline
and adds the OAT-specific navigation, generated-index, and validation contract.
Core rules:
- every non-excluded Markdown-bearing docs directory should have an authored
index.md - preserve useful audience/scope context and nonempty title/description metadata
- honor asset-only exceptions, configured excludes, and existing local instructions
- every
index.mdshould include a## Contentssection - the
## Contentssection should map sibling pages and immediate child directories ## Contentslinks should use.md-suffixed relative targets, includingsubdir/index.mdfor child directories
Regenerate navigation after adding or moving pages. In MkDocs apps this
rewrites the nav: block in mkdocs.yml; in Fumadocs apps it writes the
committed meta.json files and reports any page no ## Contents map lists:
oat docs nav sync --target-dir apps/my-docsGenerated Fumadocs meta.json is strict: a page no ## Contents map lists
stays out of the sidebar. The prebuild script that oat docs init scaffolds
for Fumadocs does not run the read-only check. To make builds fail on stale
navigation or an unlisted page, as apps/oat-docs does, append
&& oat docs nav sync --check to it; the script runs from the app directory,
which --target-dir defaults to.
Fumadocs apps also have an app-root docs index manifest, generated from
the Markdown file tree automatically via predev/prebuild hooks. You can
also run it manually:
oat docs generate-index --docs-dir docsThe generated app-root index.md is machine-owned and now starts with an
AUTOGENERATED warning comment. Edit authored pages and ## Contents maps
under docs/, then compare the generated manifest against those maps when
checking freshness.
5. Analyze the docs surface
Use the skill, not the CLI stub, for the real analysis workflow.
If your host supports slash-skill invocation:
/oat-docs-analyzeOtherwise invoke the skill by name in your agent host.
What oat-docs-analyze checks:
- index contract coverage
- nav drift
- stale or contradicted repo-checkable claims
- missing or thin content coverage based on repo features
- contributor/setup guidance gaps
6. Review the artifact and apply approved changes
Run the apply skill after analysis:
/oat-docs-applyoat-docs-apply consumes the analysis artifact, asks for approval, and applies
only the approved, evidence-backed recommendations.
Important:
oat docs analyzeandoat docs applyare CLI guidance entrypoints- the actual analysis/apply workflow runs through the skills
Typical loop
oat init --scope projectoat tools install docsoat docs init --app-name my-docs- (optional) handle MkDocs migration as a separate workstream; use
oat docs migrate --docs-dir docs --config mkdocs.yml --applyonly for the syntax/frontmatter helper - Author docs with
index.md+## Contents - Check Markdown files/links, or refresh declared artifacts with
oat docs nav sync --target-dir apps/my-docs(both frameworks), plusoat docs generate-index(Fumadocs) /oat-docs-analyze/oat-docs-apply- Repeat as the codebase changes
Related docs
Choosing Markdown or a site framework
oat docs init --framework (and the oat-docs-bootstrap skill) sets up one of
three kinds of documentation. In all three, each folder's index.md has a
## Contents list of its pages.
| Framework | Choose it when | What you give up |
|---|---|---|
| Plain Markdown | People and agents read the docs in the repository; no site is needed | A rendered site and search. You keep each ## Contents list up to date by hand |
| Fumadocs | A Node/pnpm repository wants a hosted docs site | An app with dependencies and a build. A page missing from its folder's ## Contents list is hidden from the sidebar |
| MkDocs | The team already uses Python and MkDocs Material | Python setup (setup-docs.sh runs pip install). oat docs nav sync rewrites the whole nav: block of mkdocs.yml |
When nothing chooses for it (a non-interactive run or --yes), oat docs init
uses Fumadocs. That is only a default; pick the smallest option your readers
need.
- If you are a solo developer or a team that only needs guides readable in the repository, choose plain Markdown. It adds no app, dependencies, or build.
- If a Node/pnpm team wants a hosted site, choose Fumadocs. Its build hooks
regenerate the app-root
index.mdinventory but not the sidebar files, so runoat docs nav syncafter adding, moving, or renaming pages, commit themeta.jsonfiles it writes, and addoat docs nav sync --checkto your build or CI yourself, because the scaffold does not. - If your team uses Python and MkDocs Material, choose MkDocs. Run
oat docs nav sync --checkto see what would change before letting nav sync rewritenav:. - If the repository already has docs, do not initialize over them. Adopt
existing plain Markdown with
--adopt(try--dry-runfirst), and record an existing MkDocs site withoat init --setupinstead ofoat docs init. When moving an MkDocs site to Fumadocs,oat docs migrateconverts MkDocs syntax and frontmatter; it only previews changes until you pass--apply.