@open-agent-toolkit/cli 0.3.22 → 0.3.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/docs-tooling/add-docs-to-a-repo.md +3 -9
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-docs/SKILL.md +14 -28
- package/assets/skills/oat-docs-analyze/SKILL.md +4 -2
- package/assets/skills/oat-docs-analyze/references/legacy-scaffold-checks.md +16 -0
- package/assets/skills/oat-docs-apply/SKILL.md +2 -2
- package/assets/skills/oat-docs-authoring/SKILL.md +2 -2
- package/assets/skills/oat-docs-authoring/references/lifecycle-boundaries.md +1 -2
- package/assets/skills/oat-docs-authoring/references/mkdocs-to-oat-fumadocs-refactor-guide.md +73 -0
- package/assets/skills/oat-docs-bootstrap/SKILL.md +44 -310
- package/assets/templates/docs-app-fuma/docs/contributing.md +6 -0
- package/assets/templates/docs-app-fuma/docs/getting-started.md +1 -1
- package/assets/templates/docs-app-fuma/next.config.js +5 -1
- package/dist/commands/docs/analyze.js +1 -1
- package/dist/commands/docs/apply.js +1 -1
- package/dist/commands/docs/init/scaffold.d.ts.map +1 -1
- package/dist/commands/docs/init/scaffold.js +35 -2
- package/package.json +2 -2
|
@@ -68,21 +68,15 @@ For framework apps, it wraps `oat docs init` with a seven-step guided flow: pref
|
|
|
68
68
|
What the framework path adds over the raw CLI:
|
|
69
69
|
|
|
70
70
|
- **Preflight + conflict resolution.** Detects existing `documentation` config / docs app dir / root `AGENTS.md` section and walks a deliberate resolution choice (replace, abort, repair, or deferred second-app) before any mutation.
|
|
71
|
-
- **Richer inputs.** Asks for a **site name** separate from the package name, so
|
|
72
|
-
- **
|
|
73
|
-
- **FP-11** — Turbopack `root` for nested-standalone Fumadocs apps (suppresses the multiple-lockfile warning)
|
|
74
|
-
- **FP-12** — `export const metadata = { title, description }` in `app/layout.tsx` (the only thing that populates page `<title>`, meta description, and Open Graph — `DocsLayout.branding.title` only renders nav chrome, and `createDocsConfig()` ignores `title` / `description` entirely)
|
|
75
|
-
- **FP-13** — four scaffold-content fixes (empty per-page `description:` frontmatter, bare install/build commands missing `--filter` or `cd`-prefix for monorepo/nested shapes, false `docs:lint` claim when `lint=none`, Node version line that doesn't match the consuming repo's `.nvmrc` / `engines.node`)
|
|
76
|
-
- **FP-15** — writes a task-framed `<appRoot>/AGENTS.md` bridge file when the CLI hasn't scaffolded one. The bridge is the docs app's runtime agent reference (separate audience from `docs/contributing.md`)
|
|
77
|
-
- **FP-16** — rewrites `docs/index.md` `## Contents` links to the `.md`-suffixed form that `@open-agent-toolkit/docs-transforms` normalizes at build time (agent-friendlier than extension-less; routes correctly)
|
|
78
|
-
- **FP-17** — trims `docs/contributing.md`'s "Agent guidance" section to a one-line pointer at the docs-app `AGENTS.md`, restoring the three-surfaces separation
|
|
71
|
+
- **Richer inputs.** Asks for a **site name** separate from the package name, so layout branding and page metadata converge on the same display title. `createDocsConfig()` handles runtime configuration, not titles.
|
|
72
|
+
- **AGENTS.md bridge.** FP-15 writes a task-framed `<appRoot>/AGENTS.md` only when the CLI does not scaffold it and no file already exists. Template content, metadata, command context, Node requirements, Contents links and generated-files guidance are CLI-owned. For nested-standalone repos only, the Fumadocs template passes an ESM-safe Turbopack root through `createDocsConfig` while preserving static export settings. Monorepo and single-package scaffolds use Next.js root discovery. Older scaffold shapes become analyze findings rather than post-patches.
|
|
79
73
|
- **Build verification.** Runs install + build, classifies failures against known patterns, stops on unknown errors rather than guessing.
|
|
80
74
|
- **Config inspection.** Reads `.oat/config.json` back, verifies paths exist on disk, handles the nested-standalone dual-config case, and collects the `requireForProjectCompletion` opt-in explicitly.
|
|
81
75
|
- **Root-build explanation.** When the CLI safely patches a compatible Turbo root `build` script, 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.
|
|
82
76
|
- **Educational walkthrough.** Seven sections covering the `documentation` config, the authored-source/generated-navigation model, the `## Contents` contract (with extension discipline), the three agent-instruction surfaces (root `AGENTS.md` pointer / docs-app `AGENTS.md` / `docs/contributing.md`), Fumadocs internals (or MkDocs Minimum Contract), and the OAT docs ecosystem (`oat-project-document`, `oat-docs-analyze`, `oat-docs-apply`).
|
|
83
77
|
- **Optional content kickoff.** Hands off to `oat-docs-analyze` + `oat-docs-apply` if you want to populate initial repo-specific content immediately.
|
|
84
78
|
|
|
85
|
-
Capability
|
|
79
|
+
Capability detection gates the remaining AGENTS bridge. Existing files are preserved; use analyze and reviewed recommendations to address older scaffold output.
|
|
86
80
|
|
|
87
81
|
### 3b. Direct CLI (deterministic / non-interactive)
|
|
88
82
|
|
|
@@ -6,7 +6,7 @@ disable-model-invocation: false
|
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Glob, Grep, AskUserQuestion
|
|
8
8
|
metadata:
|
|
9
|
-
version: 1.0.
|
|
9
|
+
version: 1.0.7
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# OAT Docs
|
|
@@ -89,29 +89,15 @@ Read the user's question from `$ARGUMENTS`. If no question was provided or the q
|
|
|
89
89
|
|
|
90
90
|
> "What would you like to know about OAT? I can help with workflows, CLI commands, skill authoring, configuration, project lifecycle, and more."
|
|
91
91
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
| ---------------- | --------------------------------------------------------------- | -------------------------------------------- |
|
|
96
|
-
| Getting started | `getting-started/quickstart.md`, `getting-started/bootstrap.md` | Installation, first project setup |
|
|
97
|
-
| Concepts | `getting-started/concepts.md` | Core OAT concepts and terminology |
|
|
98
|
-
| CLI commands | `reference/cli-reference.md` | Full CLI command reference |
|
|
99
|
-
| Tool packs | `getting-started/tool-packs.md` | Installing and managing skill packs |
|
|
100
|
-
| Skills | `contributing/skills.md` | Skill authoring, SKILL.md format |
|
|
101
|
-
| Workflows | `workflows/projects/` | Project lifecycle, state machine, artifacts |
|
|
102
|
-
| Ideas | `workflows/ideas/` | Idea capture and brainstorming |
|
|
103
|
-
| Provider sync | `provider-sync/` | Multi-provider sync, config, commands |
|
|
104
|
-
| Documentation | `docs-tooling/` | Docs analysis and apply workflows |
|
|
105
|
-
| Contributing | `contributing/` | Code contributions, design principles, hooks |
|
|
106
|
-
| File locations | `reference/file-locations.md` | Where OAT puts things |
|
|
107
|
-
| Directory layout | `reference/oat-directory-structure.md` | `.oat/` and `.agents/` structure |
|
|
108
|
-
| Troubleshooting | `reference/troubleshooting.md` | Common issues and fixes |
|
|
92
|
+
Read `DOCS_ROOT/index.md` and its `## Contents` section. Derive a temporary topic map from the installed labels, summaries, and link targets; do not assume OAT's repository layout or a fixed set of topic paths. Choose the entries that match the question and descend through their authored `index.md` Contents maps when needed. Resolve each link relative to its containing file and verify it exists before reading it.
|
|
93
|
+
|
|
94
|
+
If the installed index has no usable Contents or a linked target is missing, report that specific stale or incomplete installation. Search within `DOCS_ROOT` for the requested terms to find existing evidence, and recommend updating the installed docs when appropriate. Never invent a replacement path or fall back to the repository.
|
|
109
95
|
|
|
110
96
|
### Step 3: Search and Read Documentation
|
|
111
97
|
|
|
112
98
|
Based on the topic classification:
|
|
113
99
|
|
|
114
|
-
1. **Read the most relevant docs file(s)** — start with the primary match from the topic
|
|
100
|
+
1. **Read the most relevant docs file(s)** — start with the primary match from the topic map derived in Step 2. All paths are relative to `DOCS_ROOT` (`~/.oat/docs/`).
|
|
115
101
|
2. **Search for specific terms** — if the question mentions specific concepts, commands, or features, use Grep to find mentions across `~/.oat/docs/`.
|
|
116
102
|
3. **Follow cross-references** — if the primary doc references other pages, read those for complete context.
|
|
117
103
|
4. **Check the index** — read the `index.md` of relevant directories to discover additional relevant pages.
|
|
@@ -143,7 +129,7 @@ Frame these as suggestions, not automatic actions. Let the user decide.
|
|
|
143
129
|
```
|
|
144
130
|
Based on the docs, here's how OAT project workflows work: [answer]
|
|
145
131
|
|
|
146
|
-
|
|
132
|
+
Cite the installed workflow page discovered through Contents.
|
|
147
133
|
|
|
148
134
|
Would you like me to:
|
|
149
135
|
- Start a new project? (I'd invoke oat-project-lite for single-sitting work, oat-project-brief for one delivery planned as a Project Brief, oat-project-goal for an outcome delivered over several milestones, or oat-project-quick-start for a larger quick workflow)
|
|
@@ -190,7 +176,7 @@ Both create a project directory under your projects root
|
|
|
190
176
|
state.md, plan.md, and implementation.md; quick and spec-driven modes also use
|
|
191
177
|
discovery.md.
|
|
192
178
|
|
|
193
|
-
See:
|
|
179
|
+
See: the actual installed workflow and getting-started pages found through Contents.
|
|
194
180
|
|
|
195
181
|
Would you like me to create a project for you?
|
|
196
182
|
```
|
|
@@ -203,20 +189,20 @@ Would you like me to create a project for you?
|
|
|
203
189
|
|
|
204
190
|
```
|
|
205
191
|
Tool packs are bundles of related OAT skills that you install together.
|
|
206
|
-
|
|
192
|
+
Describe the packs listed by the installed tool-pack documentation, for example:
|
|
207
193
|
|
|
208
|
-
- **core** — Diagnostics and docs skills
|
|
209
|
-
|
|
194
|
+
- **core** — Diagnostics and docs skills.
|
|
195
|
+
Read the installed docs for scope and current membership.
|
|
210
196
|
- **workflows** — Project lifecycle skills (discover, plan, implement,
|
|
211
|
-
review, PR).
|
|
212
|
-
- **ideas** — Brainstorming and idea capture skills.
|
|
197
|
+
review, PR).
|
|
198
|
+
- **ideas** — Brainstorming and idea capture skills.
|
|
213
199
|
- **utility** — Cross-cutting tools (docs analysis, code review,
|
|
214
|
-
skill creation).
|
|
200
|
+
skill creation).
|
|
215
201
|
|
|
216
202
|
Install with: oat init tools
|
|
217
203
|
Manage with: oat tools list, oat tools update, oat tools outdated
|
|
218
204
|
|
|
219
|
-
See:
|
|
205
|
+
See: the installed tool-pack page discovered through Contents.
|
|
220
206
|
|
|
221
207
|
Would you like me to check which packs you have installed? (I'd run /oat-doctor --summary)
|
|
222
208
|
```
|
|
@@ -3,9 +3,9 @@ name: oat-docs-analyze
|
|
|
3
3
|
description: Run when you need to evaluate documentation structure, navigation, and coverage against the OAT documentation contract. Produces a severity-rated analysis artifact for oat-docs-apply.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
user-invocable: true
|
|
6
|
-
allowed-tools: Read, Write, Bash(git:*), Bash(oat docs nav sync --check:*), Glob, Grep, AskUserQuestion, Task
|
|
6
|
+
allowed-tools: Read, Write, Bash(git:*), Bash(oat config:*), Bash(oat docs nav sync --check:*), Bash(pnpm:*), Bash(bash:*), Bash(jq:*), Bash(mkdir:*), Bash(date:*), Bash(echo:*), Bash(cd:*), Bash(pwd:*), Glob, Grep, AskUserQuestion, Task
|
|
7
7
|
metadata:
|
|
8
|
-
version: '1.6.
|
|
8
|
+
version: '1.6.3'
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Docs Analysis
|
|
@@ -162,6 +162,8 @@ Capture the evidence sources that will justify later findings and recommendation
|
|
|
162
162
|
- existing `index.md` trees and repeated directory patterns
|
|
163
163
|
- exact missing or stale paths, commands, and page references
|
|
164
164
|
|
|
165
|
+
For framework apps, also read [Legacy scaffold checks](references/legacy-scaffold-checks.md). Apply those checks to the actual installed app, cite the observed file and source contract, and report discrepancies in Findings and Recommendations. These are read-only checks, not bootstrap post-patches. Do not change app-shell configuration during analysis or assume docs-apply can edit it; identify the manual upgrade needed when outside apply's current scope.
|
|
166
|
+
|
|
165
167
|
Do **not** infer docs structure conventions from a tiny sample of pages when the broader
|
|
166
168
|
tree or config disagrees.
|
|
167
169
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# Legacy scaffold checks
|
|
2
|
+
|
|
3
|
+
Evaluate existing framework apps against the current contracts below. A match produces an evidence-backed finding in the analysis artifact, never an automatic rewrite. Cite the actual app path and line, the missing contract, confidence and a specific repair. Respect intentional user customization; when intent is unclear, use `ask_user`.
|
|
4
|
+
|
|
5
|
+
| Observed older shape | Finding and repair | Contract source |
|
|
6
|
+
| ------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
7
|
+
| Fumadocs `next.config.js` replaces `createDocsConfig` with `createMDX()({ reactStrictMode: true, turbopack: { root: __dirname } })` | High: static-export settings are missing and `__dirname` is invalid in ESM. Recommend a manual app-config upgrade to `createDocsConfig({ basePath, turbopack: { root: dirname(fileURLToPath(import.meta.url)) } })`, preserving `output: 'export'`, `trailingSlash`, `images.unoptimized`, base path and client environment. Verify the installed docs-config supports forwarding the root first. | `@open-agent-toolkit/docs-config` factory and the current Fumadocs template |
|
|
8
|
+
| Layout lacks Next `metadata`, or site title differs between branding, metadata and authored headings | Medium: site identity or document metadata is inconsistent. Report exact mismatches; titles belong in layout metadata and branding, not `createDocsConfig`. | Fumadocs layout template and Next metadata export |
|
|
9
|
+
| Getting Started has an empty description, bare commands with no working directory, or claims lint runs when package scripts disable it | Medium: setup guidance disagrees with package scripts or page metadata. Recommend corrected prose backed by the actual scripts. | Rendered scaffold package scripts and page frontmatter |
|
|
10
|
+
| Node prerequisite is a fixed old major or tells readers to guess from repo pins | Medium: compare `.nvmrc` first, then root `package.json` `engines.node`; quote the detected requirement. When neither exists, disclose the CLI minimum rather than claiming a repo pin. | Repository Node pin and current scaffold renderer |
|
|
11
|
+
| Authored `docs/index.md` says it is generated, or contributing lacks the generated-files boundary | Medium: distinguish authored `docs/index.md` from the generated app-root manifest. Document committed `docs/**/meta.json` and `oat docs nav sync` separately. | `oat docs generate-index` and `oat docs nav sync` |
|
|
12
|
+
| Contents links omit `.md` despite real Markdown targets | Medium: recommend `.md`-suffixed source links, which the build transforms into routes. | Authored Contents contract and docs-transforms links plugin |
|
|
13
|
+
| Contributing duplicates agent runtime rules rather than pointing to app-root `AGENTS.md` | Low: recommend consolidating runtime instructions into the existing agent guidance after approval; preserve custom rules. | Docs-app guidance and contributing audience boundary |
|
|
14
|
+
| MkDocs setup says `setup-docs.sh` creates a virtual environment, config calls `tooling` an object, or index points at an assumed `docs/index.md` | Medium: verify the actual script and `.oat/config.json`. The scaffold installs with the selected Python, uses a framework string, and seeds index/config as `mkdocs.yml`. | MkDocs setup script, documentation schema and scaffold config |
|
|
15
|
+
|
|
16
|
+
A user-owned dynamic app may intentionally omit static export. Do not apply a static-export finding to it without evidence that static output is required. Likewise, verify commands and filenames against the target repository; these patterns identify discrepancies, not authority to overwrite customization.
|
|
@@ -3,9 +3,9 @@ name: oat-docs-apply
|
|
|
3
3
|
description: Run when you have a docs analysis artifact and want to generate or update documentation structure and content. Creates a branch, applies approved changes, and optionally opens a PR.
|
|
4
4
|
disable-model-invocation: true
|
|
5
5
|
user-invocable: true
|
|
6
|
-
allowed-tools: Read, Write, Edit, Bash(git:*), Bash(gh:*), Glob, Grep, AskUserQuestion
|
|
6
|
+
allowed-tools: Read, Write, Edit, Bash(git:*), Bash(gh:*), Bash(oat:*), Bash(pnpm:*), Bash(bash:*), Bash(jq:*), Bash(mkdir:*), Bash(date:*), Bash(echo:*), Bash(cd:*), Bash(pwd:*), Glob, Grep, AskUserQuestion
|
|
7
7
|
metadata:
|
|
8
|
-
version: '1.4.
|
|
8
|
+
version: '1.4.4'
|
|
9
9
|
---
|
|
10
10
|
|
|
11
11
|
# Docs Apply
|
|
@@ -3,10 +3,10 @@ name: oat-docs-authoring
|
|
|
3
3
|
description: Use when authoring or restructuring targeted content inside an existing OAT Markdown surface or OAT/Fumadocs docs app. Preserves OAT docs navigation, generated indexes, and validation boundaries.
|
|
4
4
|
argument-hint: '[docs task or target path]'
|
|
5
5
|
disable-model-invocation: false
|
|
6
|
-
allowed-tools: Read, Write, Bash, Glob, Grep, AskUserQuestion
|
|
6
|
+
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
7
7
|
user-invocable: true
|
|
8
8
|
metadata:
|
|
9
|
-
version: '1.1.
|
|
9
|
+
version: '1.1.3'
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# OAT Docs Authoring
|
|
@@ -42,8 +42,7 @@ Stop and reroute when you notice:
|
|
|
42
42
|
## Migration Pointer
|
|
43
43
|
|
|
44
44
|
Full MkDocs-to-OAT-Fumadocs migration is not bootstrap and is not targeted
|
|
45
|
-
authoring. Use the
|
|
46
|
-
when available, and keep the migration in an OAT project or explicit migration
|
|
45
|
+
authoring. Use the bundled [MkDocs-to-OAT-Fumadocs migration guide](mkdocs-to-oat-fumadocs-refactor-guide.md), and keep the migration in an OAT project or explicit migration
|
|
47
46
|
branch with owner-review items for unverifiable claims.
|
|
48
47
|
|
|
49
48
|
For migration-sensitive follow-up after the migration workflow has created a
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# MkDocs to OAT/Fumadocs migration guide
|
|
2
|
+
|
|
3
|
+
Use this standalone handoff for an explicitly approved migration of an existing MkDocs site. Bootstrap creates an app; targeted authoring edits content; neither performs a full migration. Keep migration work in an OAT project or an explicit migration branch, with the agreed scope and owner recorded before changes.
|
|
4
|
+
|
|
5
|
+
This guide is reconstructed from current OAT CLI, template and authoring contracts. The older project-local handoff mentioned in OAT's docs-authoring project summary was unavailable; this is not a copy of that historical document.
|
|
6
|
+
|
|
7
|
+
## Preflight: inventory before mutation
|
|
8
|
+
|
|
9
|
+
1. Read repository and docs-local instructions, `mkdocs.yml`, `.oat/config.json`, Python dependency files, docs package scripts and deployment workflows. Resolve the actual content root, published URL/base path and build output; do not assume `docs/` or GitHub Pages.
|
|
10
|
+
2. Inventory every source page, attachment, image, local link, anchor, nav entry and public URL. Record pages outside nav too. Keep a before/after mapping for every source path and URL; never silently drop an unlisted page.
|
|
11
|
+
3. Inventory MkDocs-specific features: admonitions, tabs, includes/macros, plugin-generated pages, API generation, Mermaid, custom assets/theme, search and redirects. Distinguish supported conversion from manual work and unsupported features.
|
|
12
|
+
4. Find claims requiring code/config evidence, confidential material, unresolved product behavior and owner-only knowledge. Record owner-review items rather than guessing or publishing uncertain claims.
|
|
13
|
+
5. Discover validation commands and required runtimes from scripts, CI and contributor instructions. Establish a baseline with exact commands and exit codes, including existing failures. Agree on the target app location, dependency policy, URL preservation strategy and deployment change with the user.
|
|
14
|
+
|
|
15
|
+
Produce an inventory and proposed migration scope for approval. Do not overwrite the MkDocs app, clear its configuration, delete Python tooling or switch deployment as a side effect of preparing a proposal.
|
|
16
|
+
|
|
17
|
+
## Phase 1: create the approved target app
|
|
18
|
+
|
|
19
|
+
Use `oat docs init --help` to inspect installed capabilities. Scaffold Fumadocs into an empty, approved destination with `--framework fumadocs`, a package/app name, site name, description and target directory. Bootstrap can guide this step, but creating a second app does not imply support for two active `documentation` entries: the current config describes one surface. Explicitly agree when the configured docs root will switch, and preserve the old config for rollback.
|
|
20
|
+
|
|
21
|
+
Read the rendered package scripts and configuration. The current Fumadocs template uses Next static export, trailing slashes and unoptimized images through `createDocsConfig`. For nested-standalone repos only, it forwards an ESM-safe app directory as `turbopack.root`; monorepo and single-package scaffolds use Next.js root discovery. Preserve the site's base path and `NEXT_PUBLIC_BASE_PATH`; set site identity through layout metadata and `DocsLayout` branding, not factory title options.
|
|
22
|
+
|
|
23
|
+
Install using the repository's package-manager conventions. Keep dependency or workspace changes visible in the migration diff. Do not delete the old site yet.
|
|
24
|
+
|
|
25
|
+
## Phase 2: migrate content without losing source
|
|
26
|
+
|
|
27
|
+
Copy approved content and assets into the target content root, retaining the source until parity is verified. Use the inventory to account for every file.
|
|
28
|
+
|
|
29
|
+
`oat docs migrate` converts supported MkDocs admonitions and injects missing frontmatter in `.md` files. It is a dry run by default; `--apply` writes changes. `--config` supplies MkDocs nav title hints, not a complete navigation or app migration. For example, from the repository root:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# Replace paths with the approved destination and preserved source config.
|
|
33
|
+
oat docs migrate --docs-dir apps/handbook/docs --config documentation/mkdocs.yml
|
|
34
|
+
# Review the preview and approve the content conversion before writing.
|
|
35
|
+
oat docs migrate --docs-dir apps/handbook/docs --config documentation/mkdocs.yml --apply
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
The command does not migrate app shells, deployment, plugins, macros, redirects or all Markdown extensions. Review seeded descriptions for meaningful content; metadata injection is not editorial completion. Convert unsupported syntax manually within the approved scope, preferring `.md` and using `.mdx` only where components require it. Preserve code examples, cautions, provenance and external attributions.
|
|
39
|
+
|
|
40
|
+
## Phase 3: preserve navigation, links and URLs
|
|
41
|
+
|
|
42
|
+
Create authored `index.md` pages with purpose and `## Contents` maps in each content directory. Map every retained page into the approved tree; use `.md` or `subdir/index.md` targets and the current dash-bullet Contents grammar. When consolidating `overview.md`, carry its content and inbound references into `index.md` and retain the old-URL mapping.
|
|
43
|
+
|
|
44
|
+
Run `oat docs nav sync --target-dir <app-root>` to generate committed `docs/**/meta.json` navigation from authored maps. Resolve unlisted pages explicitly. Do not hand-edit generated navigation. The separate app-root `index.md` manifest is generated by `oat docs generate-index` through the scaffold's `predev`/`prebuild`; it is not the authored root page.
|
|
45
|
+
|
|
46
|
+
Rewrite inbound links, relative assets and anchors using the before/after map. Test public URLs under the real base path. Choose an approved host-compatible recovery for moved URLs; do not assume Next redirects work with static export. If old URLs cannot be preserved, report the exact break and obtain a decision before deployment changes or source deletion.
|
|
47
|
+
|
|
48
|
+
## Phase 4: validate the migration
|
|
49
|
+
|
|
50
|
+
Discover and run the target app's actual lint, format, build and any link checks. Do not treat disabled/no-op scripts as validation. Run nav sync's read-only `--check` form to check committed navigation. Run existing repository gates required for package, config and workflow changes; keep exact exit codes and distinguish new failures from the baseline.
|
|
51
|
+
|
|
52
|
+
Inspect the static output and use the available browser to spot-check:
|
|
53
|
+
|
|
54
|
+
- landing and deeply nested pages, sidebar labels/order and search;
|
|
55
|
+
- old and new URLs, anchors, relative links and base-path assets;
|
|
56
|
+
- admonitions, tabs, tables, Mermaid, code blocks and custom components;
|
|
57
|
+
- title/description metadata, theme and layout behavior.
|
|
58
|
+
|
|
59
|
+
A successful build does not prove rendering or link parity. If a check cannot run, record the missing evidence and owner action; do not mark it verified. Review every inventory entry as migrated, deliberately retained, or explicitly approved for retirement, with a reason.
|
|
60
|
+
|
|
61
|
+
## Phase 5: review, switch and retain rollback
|
|
62
|
+
|
|
63
|
+
Present the content conservation diff, URL map, validation evidence, unresolved owner-review items, config changes and deployment proposal. Obtain user approval before switching the configured docs surface, changing publication workflows or retiring the old site. Use `oat-docs-analyze` for a read-only audit and the appropriate reviewed workflow for follow-up changes; do not assume docs-apply may edit app-shell or deployment configuration.
|
|
64
|
+
|
|
65
|
+
Only after parity and approval, remove obsolete MkDocs dependencies/configuration and update repository guidance to the new authored source, generated artifacts and commands. Keep an explicit rollback reference to the prior site/config/deployment. Package publishing and production deployment require their own authorization.
|
|
66
|
+
|
|
67
|
+
## Final report
|
|
68
|
+
|
|
69
|
+
Report the approved scope, changed files and commits; source-to-target page and URL dispositions; commands and exit codes; rendered spot checks; the configured docs root and publication behavior; known failures and unverified evidence; owner-review items and decisions; and the rollback reference. State whether the migration is ready for owner acceptance, rather than treating the absence of build errors as acceptance.
|
|
70
|
+
|
|
71
|
+
## Current contract references
|
|
72
|
+
|
|
73
|
+
Within this installed skill, read [lifecycle boundaries](lifecycle-boundaries.md), [the Fumadocs contract](oat-fumadocs-contract.md) and [validation](validation.md). Load `authoring-docs` from installed scope for universal evidence and writing guidance. Inspect installed CLI help and rendered templates before executing commands; the consuming repository's instructions and approved migration scope remain authoritative.
|
|
@@ -6,12 +6,12 @@ disable-model-invocation: true
|
|
|
6
6
|
user-invocable: true
|
|
7
7
|
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
|
8
8
|
metadata:
|
|
9
|
-
version: '1.3.
|
|
9
|
+
version: '1.3.3'
|
|
10
10
|
---
|
|
11
11
|
|
|
12
12
|
# Docs Bootstrap
|
|
13
13
|
|
|
14
|
-
Bootstrap or adopt documentation in this repo and guide the user through understanding how it works. Wraps `oat docs init` with preflight detection, richer input gathering, gated
|
|
14
|
+
Bootstrap or adopt documentation in this repo and guide the user through understanding how it works. Wraps `oat docs init` with preflight detection, richer input gathering, the gated FP-15 docs-app AGENTS.md bridge, build verification, post-scaffold config inspection, and an educational walkthrough covering the `index.md` + `## Contents` navigation contract, scaffolded agent-instruction surfaces, and the OAT docs ecosystem (`oat-project-document`, `oat-docs-analyze`, `oat-docs-apply`).
|
|
15
15
|
|
|
16
16
|
## Prerequisites
|
|
17
17
|
|
|
@@ -37,7 +37,7 @@ Bootstrap or adopt documentation in this repo and guide the user through underst
|
|
|
37
37
|
- Inspecting repo state read-only before any mutation
|
|
38
38
|
- Prompting the user for richer inputs than the CLI asks for (notably a site name separate from the package/app name)
|
|
39
39
|
- Invoking `oat docs init` non-interactively with collected flags
|
|
40
|
-
- Applying gated, idempotent post-patches for open CLI gaps (FP-
|
|
40
|
+
- Applying gated, idempotent post-patches for open CLI gaps (FP-15) only when capability detection shows the CLI has not addressed them
|
|
41
41
|
- Running install + build and classifying failures against known patterns
|
|
42
42
|
- Reading `.oat/config.json` back to verify paths and prompting for `requireForProjectCompletion`
|
|
43
43
|
- Narrating the scaffolded output as a chunked educational walkthrough
|
|
@@ -114,7 +114,7 @@ OAT ▸ DOCS BOOTSTRAP
|
|
|
114
114
|
|
|
115
115
|
The detailed framework procedures below apply to Fumadocs/MkDocs. When the selected tooling is `markdown`, use this path for Steps 2–7 instead; never run framework post-patches, the FP-15 AGENTS bridge, dependency discovery/install, package/Turbo patches, or a site build. Step 1 remains the shared read-only detector.
|
|
116
116
|
|
|
117
|
-
1. **Preflight and routing:** Read `documentation.tooling` as
|
|
117
|
+
1. **Preflight and routing:** Read `documentation.tooling` as a non-empty string. A non-string value (including a legacy object with a `framework` field) is invalid/undeclared tooling in the CLI; surface it for a user decision before proceeding, without silently clearing or retagging it. Declared tooling is authoritative: configured Markdown uses `documentation.root` literally, including when it contains a child named `docs`; declared frameworks or unknown stacks are not plain-doc adoption candidates. With no declared tooling, check framework evidence first (`mkdocs.yml`, Fumadocs/Next config and docs-app package scripts/dependencies), then inspect the chosen dedicated content directory for authored `.md`/`.mdx` pages. A repository-root README alone is insufficient; an empty selected directory is fresh setup. For a populated plain tree, lead with **adopt and audit**, **audit only**, or **abort**. Audit only delegates read-only to `oat-docs-analyze` and exits. Adoption requires the explicit user choice and CLI `--adopt`; `--yes` alone never authorizes it. An incompatible declared root/index/tooling requires a user decision, with no silent clearing or retagging. Keep the existing explicitly authorized framework replacement path when a framework is selected.
|
|
118
118
|
2. **Gather inputs:** Offer “Markdown (plain files), Fumadocs, or MkDocs?” Collect documentation title (`--site-name`), dedicated relative target directory (default `docs` in every repo shape), and optional description. Reuse an existing compatible configured Markdown root. Ask no app/package name, package-manager, site-runtime, or dependency questions. Lint and format default to `none`; describe selected existing repository tools only, without installing them. Validate a nonempty title and a dedicated in-repository target, excluding the repository root and escaping symlinks. Confirm fresh setup or additive adoption, title, root, and audit handoff. `appName` is absent and `conflictResolution` is `adopt`, `audit`, `abort`, or null for this path.
|
|
119
119
|
3. **Invoke CLI:** Probe `$CLI_CMD docs init --help` and require advertised Markdown/`--adopt` support before invocation; if missing, report the needed CLI update rather than fabricating scaffold files. Run `$CLI_CMD docs init --framework markdown --target-dir <root> --site-name <title> --description <description> --lint none --format none --yes`, adding `--adopt` only for explicit adoption. Pass the selected lint/format values when using existing tools. Never pass app-only flags. An optional `--dry-run` previews file/config/guidance changes without writes; it does not count as a completed bootstrap. Capture terminal/JSON results, exact exit, created/preserved files, config changes, guidance action, and audit advice. `partial`/exit 1 with manual-required or blocked guidance means unresolved guidance; real runs may have created files, whereas dry-runs have only planned files. Report actual state and stop before claiming completion. Other refusals also stop without post-patches. For success, read config back to resolve the actual content root and authored index.
|
|
120
120
|
4. **Verify files:** Print `[4/7] Verifying files…`. Check config root/index, baseline file existence, nonempty `title`/`description`, useful audience/scope context and populated `## Contents` links resolving to actual sibling pages or child `index.md`s. Honor excludes and asset-only exceptions; preserve local AGENTS instructions. Fresh setup creates only authored `index.md` and `contributing.md` in the target; verify no docs-root AGENTS, app package, framework config, dependencies, or root build changes. Run already documented lint/link/format checks when applicable; otherwise inspect files/links directly. Adoption preserves existing bytes and may leave missing child indexes, metadata, context, or links: record these as audit gaps for analyze/apply rather than repairing them or calling the tree fully conformant. Distinguish successful setup verification from content-conformance findings.
|
|
@@ -137,7 +137,7 @@ Check in order; the first match wins:
|
|
|
137
137
|
3. If both `$REPO_ROOT/apps/` and `$REPO_ROOT/packages/` directories exist → **`monorepo`**
|
|
138
138
|
4. Otherwise → **`single-package`**
|
|
139
139
|
|
|
140
|
-
Once `single-package` is identified, apply the nested-standalone heuristic: if the user will place the docs app in a subdirectory of the repo (the common case for single-package repos) and that subdirectory will have its own `pnpm-lock.yaml` after scaffold + install, treat the shape as **`nested-standalone`**. This is a single-package shape with its own docs-app lockfile, which affects the Turbopack root
|
|
140
|
+
Once `single-package` is identified, apply the nested-standalone heuristic: if the user will place the docs app in a subdirectory of the repo (the common case for single-package repos) and that subdirectory will have its own `pnpm-lock.yaml` after scaffold + install, treat the shape as **`nested-standalone`**. This is a single-package shape with its own docs-app lockfile, which affects the Turbopack app root and the install command pattern.
|
|
141
141
|
|
|
142
142
|
In practice: for Fumadocs, any single-package repo with a target subdirectory is `nested-standalone`. For MkDocs, the shape stays `single-package` because MkDocs doesn't have the Turbopack concern.
|
|
143
143
|
|
|
@@ -198,11 +198,11 @@ Preflight Result:
|
|
|
198
198
|
|
|
199
199
|
- **Read-only invariant.** Preflight never writes files, never modifies config, never runs scaffold. Every fix or prompt flows through later components.
|
|
200
200
|
- **Conflict surfacing is a list, not a branch.** Preflight returns all conflicts found; the Input Gatherer presents them together. This keeps Preflight single-purpose and predictable.
|
|
201
|
-
- **`nested-standalone` is a first-class shape** distinct from `single-package`. The CLI conflates them, but the skill treats them separately because Turbopack root
|
|
201
|
+
- **`nested-standalone` is a first-class shape** distinct from `single-package`. The CLI conflates them, but the skill treats them separately because Turbopack app root, build command patterns, and nested `.oat/config.json` handling all differ.
|
|
202
202
|
|
|
203
203
|
### Step 2: Input Gatherer
|
|
204
204
|
|
|
205
|
-
Collect the inputs needed to invoke `oat docs init` and apply post-scaffold patches. The skill asks for richer inputs than the CLI prompts for — most importantly, a **site name** separate from the package/app name
|
|
205
|
+
Collect the inputs needed to invoke `oat docs init` and apply post-scaffold patches. The skill asks for richer inputs than the CLI prompts for — most importantly, a **site name** separate from the package/app name. Ask one question at a time, surfacing defaults from the Preflight Result, and end with a coherence check before scaffold.
|
|
206
206
|
|
|
207
207
|
Print `[2/7] Gathering inputs…` at the start of this step.
|
|
208
208
|
|
|
@@ -217,7 +217,7 @@ If `conflicts[]` is empty, skip conflict handling and go to 2b.
|
|
|
217
217
|
Each question includes plain-language context explaining what the value affects. Defaults come from the Preflight Result. Ask sequentially — each answer can inform the next default.
|
|
218
218
|
|
|
219
219
|
- **Framework.** `"Which documentation tooling? Markdown (plain files), Fumadocs (Next.js), or MkDocs (Python)?"` Default: `fumadocs`. Selecting Markdown switches to the Markdown path above before app/site questions.
|
|
220
|
-
- **Site name.** `"What's the name of the product or project these docs are for?"` Default: `defaults.siteName` (humanized repo name). Explain: "This becomes the display title — what shows up in the site header, browser tab, and page headings. It is **not** the package name."
|
|
220
|
+
- **Site name.** `"What's the name of the product or project these docs are for?"` Default: `defaults.siteName` (humanized repo name). Explain: "This becomes the display title — what shows up in the site header, browser tab, and page headings. It is **not** the package name." The display title is distinct from `appName`.
|
|
221
221
|
- **Package / app name.** `"What should the docs package be called?"` Default: `defaults.appName`. Explain: "This becomes the `package.json` `name`, the directory name, and the pnpm filter (e.g., `pnpm --filter {appName} dev`). It does **not** show up in the UI."
|
|
222
222
|
- **Target directory.** `"Where should the docs app live?"` Default: `defaults.targetDir`. Explain: "Relative to repo root. Monorepos typically use `apps/{appName}`; single-package repos use `{appName}` as a subdirectory."
|
|
223
223
|
- **Site description.** `"One-sentence description of the docs site?"` Default: empty. Explain: "Used for search previews, social cards, and page metadata. Optional but strongly recommended."
|
|
@@ -229,7 +229,7 @@ Each question includes plain-language context explaining what the value affects.
|
|
|
229
229
|
- `appName`: no spaces, no uppercase, no leading/trailing hyphens, matches `^[a-z0-9][a-z0-9-]*[a-z0-9]$` or single lowercase char. Reject and re-prompt on failure.
|
|
230
230
|
- `siteName`: non-empty after trim. Reject empty.
|
|
231
231
|
- `targetDir`: must be relative (no leading `/`, no `..`), must be writable based on the chosen `conflictResolution` (e.g., `replace` requires the path to be empty-after-cleanup; `second-app` requires a fresh path that doesn't overlap with an existing docs app).
|
|
232
|
-
- `framework`: must be `fumadocs
|
|
232
|
+
- `framework`: must be `markdown`, `fumadocs`, or `mkdocs`. Markdown follows the file-only path before app questions.
|
|
233
233
|
- `lint`: must be `none` or `markdownlint-cli2`.
|
|
234
234
|
- `format`: must be `none` or `oxfmt`.
|
|
235
235
|
|
|
@@ -260,7 +260,7 @@ Record internally for the Scaffold Runner:
|
|
|
260
260
|
```
|
|
261
261
|
Input Result:
|
|
262
262
|
framework: 'markdown' | 'fumadocs' | 'mkdocs'
|
|
263
|
-
siteName: string //
|
|
263
|
+
siteName: string // display title distinct from appName
|
|
264
264
|
appName: string
|
|
265
265
|
targetDir: string
|
|
266
266
|
siteDescription: string
|
|
@@ -357,7 +357,7 @@ If any mutation fails or any invariant check fails, **stop the flow before scaff
|
|
|
357
357
|
|
|
358
358
|
### Step 3: Scaffold Runner
|
|
359
359
|
|
|
360
|
-
Invoke `oat docs init` with the collected inputs and then apply gated post-patches for any CLI gaps the Capability Detection sub-procedure reports as still-open. The Scaffold Runner
|
|
360
|
+
Invoke `oat docs init` with the collected inputs and then apply gated post-patches for any CLI gaps the Capability Detection sub-procedure reports as still-open. The Scaffold Runner probes CLI capabilities, invokes the CLI, and applies the AGENTS.md bridge if still needed. Template content is CLI-owned; report old-scaffold shapes through `oat-docs-analyze`.
|
|
361
361
|
|
|
362
362
|
Print `[3/7] Scaffolding…` at the start of this step.
|
|
363
363
|
|
|
@@ -379,73 +379,22 @@ Base flags (always passed):
|
|
|
379
379
|
|
|
380
380
|
Capability-gated flags (added only when the Capability Probe reports support):
|
|
381
381
|
|
|
382
|
-
- `--site-name {siteName}` — only if `capabilities.siteNameFlag === true
|
|
382
|
+
- `--site-name {siteName}` — only if `capabilities.siteNameFlag === true`. If absent, stop before scaffolding and recommend updating the CLI; do not rewrite the older template output.
|
|
383
383
|
- `--no-root-patch` — only if `capabilities.noRootPatchFlag === true` and the Preflight / Conflict Resolution result says root package mutation should be skipped. This is recommended for no-root-package repositories or when the user explicitly chose no root mutation; current CLI builds also auto-skip when no root `package.json` exists, so the flag is optional documentation of intent, not a recovery mechanism.
|
|
384
384
|
|
|
385
385
|
Do not pass flags the CLI doesn't advertise. Never assume a flag exists because the skill wants it — the Capability Probe is the source of truth for what's safe to pass.
|
|
386
386
|
|
|
387
387
|
**3b. Run Capability Detection.**
|
|
388
388
|
|
|
389
|
-
Before CLI invocation,
|
|
390
|
-
|
|
391
|
-
**CLI help probe.** Run `$CLI_CMD docs init --help` exactly once, capture stdout, and grep the flag list for known markers. Record boolean capability flags on the `capabilities` object:
|
|
392
|
-
|
|
393
|
-
- `siteNameFlag` — `true` if `--site-name` (or equivalent alias like `--title`) appears in the help output. Implies FP-12 upstream fix has landed.
|
|
394
|
-
- `turbopackRootFlag` — `true` if a flag for forwarding a Turbopack root (or a `--framework-config` passthrough that accepts `turbopack.root`) appears. Implies FP-11 fix has landed in some form.
|
|
395
|
-
- `agentsMdScaffoldFlag` — `true` if the help output mentions `AGENTS.md` scaffolding or the CLI's scaffold template list includes `AGENTS.md`. Implies FP-15 fix has landed.
|
|
396
|
-
- `noRootPatchFlag` — `true` if `--no-root-patch` appears in help output. If supported, pass it when root package mutation should be skipped rather than relying only on auto-skip behavior.
|
|
397
|
-
|
|
398
|
-
For FP-16, there is no CLI-level help-probe marker; the capability is detected purely by file-shape check on the scaffolded `docs/index.md` (see below). When the CLI scaffold template is fixed upstream, the file-shape check will classify as `patched-shape` and the FP-16 patch will skip automatically.
|
|
399
|
-
|
|
400
|
-
If the `--help` invocation fails (non-zero exit or empty stdout), treat all capabilities as `false` and record a warning in `Scaffold Result.cliLogs.stderr` — do not guess. Assuming a capability that doesn't exist leads to a broken scaffold; assuming absence just means an extra post-patch runs unnecessarily.
|
|
401
|
-
|
|
402
|
-
**File-shape checks per patch target.** After the CLI writes the scaffold (3c completes), but before 3d applies any patch, read the target file and classify it as one of three states: `scaffold-shape` (unmodified CLI output, patch is safe), `patched-shape` (already patched by a previous skill run, patch is a no-op), or `drift` (neither — the file has been hand-edited or third-party-modified).
|
|
403
|
-
|
|
404
|
-
For each patch, the classification rule is:
|
|
405
|
-
|
|
406
|
-
- **FP-12 targets** — the patch sets display-title references in four files:
|
|
407
|
-
- `<appRoot>/app/layout.tsx` (Fumadocs only): scaffold shape has `DocsLayout` with `branding` pointing at `{appName}` and no `export const metadata`; patched/upstream shape has `branding.title` using `{siteName}` and module-scope Next metadata. Code-file patches may use `/* FP-12 */` markers where syntactically valid.
|
|
408
|
-
- `<appRoot>/docs/index.md`: scaffold shape has frontmatter `title: '{appName}'` and `# {appName}` H1; patched/upstream shape substitutes `{siteName}` in both positions. Do not add hidden FP comments to rendered Markdown; use content shape for idempotency.
|
|
409
|
-
- `<appRoot>/docs/getting-started.md`: scaffold shape has a body reference to `{appName}`; patched/upstream shape uses `{siteName}`.
|
|
410
|
-
- `<appRoot>/docs/contributing.md`: scaffold shape has `# {appName}` H1; patched/upstream shape uses `{siteName}`.
|
|
411
|
-
- Classification: if the expected literal (`appName` for scaffold shape, `siteName` for patched/upstream shape) matches exactly, the file is in that shape. If neither pattern matches (e.g., the user already renamed things manually), classify as `drift`.
|
|
412
|
-
- **FP-11 target** — `<appRoot>/next.config.js` (Fumadocs, nested-standalone only):
|
|
413
|
-
- Scaffold shape: single-line `export default createDocsConfig()` or near-equivalent with no `turbopack` option.
|
|
414
|
-
- Patched shape (via passthrough): `createDocsConfig({ turbopack: { root: __dirname } })` plus `<!-- FP-11 patch -->` marker comment.
|
|
415
|
-
- Patched shape (via wrapper replacement): explicit `createMDX()` + hand-written config with `turbopack: { root: __dirname }` and the `<!-- FP-11 patch -->` marker.
|
|
416
|
-
- Classification: pattern-match on the wrapper call or the `createMDX()` import; any other shape is `drift`.
|
|
417
|
-
- **FP-13 targets** — the five sub-findings (empty descriptions, bare commands, false lint claim, old authored-file generated warning, Node version mismatch) each target a specific line or section. Scaffold shape for each is "unchanged historical CLI scaffold output"; patched/upstream shape is the corrected content. Markdown patches do not add hidden FP comments; they classify by content shape. Sub-finding E (Node version) additionally reads `.nvmrc` / `package.json` `engines.node` at scaffold time to determine the correct version to write.
|
|
418
|
-
- **FP-16 target** — `<appRoot>/docs/index.md` `## Contents` section (Fumadocs only):
|
|
419
|
-
- Scaffold shape: `## Contents` list items have extension-less link targets, e.g. `- [Getting Started](getting-started) - ...`. Detect by regex-matching bulleted list items where the link target is a slug (no file extension, no trailing slash) that corresponds to a real `.md` file in the same directory (or an `index.md` inside a matching subdirectory).
|
|
420
|
-
- Patched/upstream shape: `## Contents` list items have `.md`-suffixed link targets (e.g. `- [Getting Started](getting-started.md) - ...`). No hidden FP comments are added to rendered Markdown.
|
|
421
|
-
- Drift: neither scaffold nor patched shape — likely user-edited with mixed or inconsistent extensions. Record as `refused` with a suggested manual fix ("normalize all `## Contents` links to `.md`-suffixed form so the `docs-transforms` remark-links plugin handles routing").
|
|
422
|
-
- **FP-17 target** — `<appRoot>/docs/contributing.md` `## Agent guidance` section (Fumadocs only):
|
|
423
|
-
- Scaffold shape: the section contains a short bulleted list of generic agent advice (typically two bullets: treating `index.md` as truth, preferring links to source files). Detect by matching the `## Agent guidance` heading followed by a small bulleted list.
|
|
424
|
-
- Patched/upstream shape: the section contains a one-paragraph pointer to the docs-app `AGENTS.md`. No hidden FP comments are added to rendered Markdown.
|
|
425
|
-
- Drift: user-edited with content beyond the scaffold bullets (paragraphs, custom agent rules, links to other files). Classify as `refused` — do not collapse user-authored content; instead suggest the user move custom guidance into `<appRoot>/AGENTS.md` and trim `contributing.md` to the pointer form manually.
|
|
426
|
-
- **FP-15 target** — `<appRoot>/AGENTS.md`:
|
|
427
|
-
- Scaffold shape: file **does not exist** (current CLI doesn't scaffold it).
|
|
428
|
-
- Patched shape: file exists and begins with `# AGENTS —` (the template's H1 form).
|
|
429
|
-
- Any other state (file exists but has a different H1, file was hand-written) classifies as `drift`.
|
|
430
|
-
|
|
431
|
-
**Refuse-and-surface contract.** If any target classifies as `drift`, the associated patch **does not run**. Instead, record an entry in `Scaffold Result.patchesApplied` with `status: 'refused'`, the target path, the observed shape snippet, and a suggested manual fix for the user. Example:
|
|
389
|
+
Before CLI invocation, run `$CLI_CMD docs init --help` once. Record:
|
|
432
390
|
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
status: refused
|
|
437
|
-
target: /abs/path/apps/docs/app/layout.tsx
|
|
438
|
-
reason: drift — expected `branding: { title: 'docs' }` (scaffold) or patched-shape marker; found neither
|
|
439
|
-
suggestedFix: manually set `DocsLayout.branding.title` to {siteName} and ensure `export const metadata = { title, description }` is present
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
Continue with remaining patches; one `refused` entry does not stop the flow. The Post-Scaffold Inspector (Step 5) surfaces the refused list to the user so they can address it manually.
|
|
391
|
+
- `siteNameFlag`: whether `--site-name` is advertised.
|
|
392
|
+
- `agentsMdScaffoldFlag`: whether help or the installed template file list confirms native `AGENTS.md` scaffolding.
|
|
393
|
+
- `noRootPatchFlag`: whether `--no-root-patch` is advertised.
|
|
443
394
|
|
|
444
|
-
|
|
395
|
+
If the probe fails or returns no help, stop with the verbatim error and recommend updating or repairing the CLI. Never guess capabilities.
|
|
445
396
|
|
|
446
|
-
-
|
|
447
|
-
- The file-shape checks run **after** `oat docs init` (3c) so they operate on the actual scaffold output.
|
|
448
|
-
- The post-patch sub-procedures (3d, site-identity and scaffold-integrity) read the combined `capabilities` record and target classifications to decide whether to apply each patch.
|
|
397
|
+
After scaffolding, inspect `<appRoot>/AGENTS.md`: absent permits the FP-15 bridge; any existing file is preserved. Check template output against the current scaffold contract. Older output with missing metadata, unresolved Node-version advice, missing generated-files guidance, extension-less Contents links, duplicated agent instructions, or a Fumadocs wrapper that loses static export settings becomes a finding under `oat-docs-analyze`'s legacy scaffold checks (load that skill from installed scope and resolve `references/legacy-scaffold-checks.md` from its own directory). Record the observed path and evidence, then offer analyze; do not reinstate template patches. Ambiguous or user-authored shapes are reported for review, never overwritten.
|
|
449
398
|
|
|
450
399
|
**3c. Invoke the CLI.**
|
|
451
400
|
|
|
@@ -491,73 +440,14 @@ Capture both stdout and stderr. **Do not** stream output directly to the user; t
|
|
|
491
440
|
capabilities: { siteNameFlag: boolean, ... } // from Capability Detection (3b)
|
|
492
441
|
cliLogs: { stdout: string, stderr: string } // retained for Walkthrough
|
|
493
442
|
rootBuildPatch: { status, reason?, diff?, manualSnippet? } | null // parsed from CLI output when available
|
|
494
|
-
patchesApplied: [] // populated by
|
|
443
|
+
patchesApplied: [] // populated by the FP-15 bridge in 3d
|
|
495
444
|
```
|
|
496
445
|
|
|
497
446
|
The Walkthrough (Step 6) and Post-Scaffold Inspector (Step 5) both consume `Scaffold Result`; keep it structured and avoid shell-side ephemeral state.
|
|
498
447
|
|
|
499
|
-
**3d. Apply
|
|
500
|
-
|
|
501
|
-
Each patch:
|
|
502
|
-
|
|
503
|
-
- Reads the relevant capability flag from `Scaffold Result.capabilities` and the file-shape detection from Capability Detection (3b).
|
|
504
|
-
- Runs only if the capability is **absent** (the CLI didn't already address the gap) AND the file-shape check passes.
|
|
505
|
-
- Uses a marker comment only in code files where the comment syntax is valid (`/* FP-NN */` in TSX/JS, `// ...` where appropriate). Rendered Markdown patches do **not** add hidden `<!-- FP-NN -->` comments; they rely on content-shape idempotency and drift checks, and they defer to the project's normal comment conventions for user-facing prose.
|
|
506
|
-
- Is **idempotent** — running the patch twice is a no-op.
|
|
507
|
-
- Appends an entry to `Scaffold Result.patchesApplied` with `{ id, status: 'applied' | 'skipped' | 'refused', reason? }`.
|
|
508
|
-
|
|
509
|
-
##### Site-identity patches (FP-12 + FP-15)
|
|
510
|
-
|
|
511
|
-
These patches close the "site name + AGENTS.md" gaps. They run after `oat docs init` (3c) and before scaffold-integrity patches (see 3d ordering note below). Site-identity must run before scaffold-integrity because the FP-13 sub-findings may reference `{siteName}` strings that FP-12 has just written.
|
|
512
|
-
|
|
513
|
-
**FP-12: title patches.**
|
|
514
|
-
|
|
515
|
-
Gate: run **only if** `capabilities.siteNameFlag === false`. If the CLI wrote the site title itself, skip the entire FP-12 group and record `{ id: 'FP-12', status: 'skipped', reason: 'CLI --site-name flag supported' }`.
|
|
516
|
-
|
|
517
|
-
Per-file edits (Fumadocs only — MkDocs has no `layout.tsx`; its title handling is covered by the MkDocs Minimum Contract in Step 6). **Critical ordering: insert the `layout.tsx` metadata export first — it's the load-bearing change for HTML `<head>` (page title, meta description, Open Graph). Everything else below is display-title coherence.**
|
|
518
|
-
|
|
519
|
-
- **`<appRoot>/app/layout.tsx` — `export const metadata`.** This is the most important FP-12 edit: without it, the exported HTML has no `<title>`, no meta description, and no Open Graph tags. `DocsLayout`'s `branding.title` prop does **not** populate page metadata — it only renders nav chrome. `@open-agent-toolkit/docs-config`'s `createDocsConfig()` also does **not** accept or forward title/description — passing them there is a no-op (verified in the docs-config source: it reads `basePath` and ignores everything else). Next.js metadata must come from a module-scope `export const metadata`.
|
|
520
|
-
|
|
521
|
-
If no `export const metadata` exists in the file, insert it after the imports:
|
|
522
|
-
|
|
523
|
-
```tsx
|
|
524
|
-
/* FP-12 patch: site metadata */
|
|
525
|
-
export const metadata = {
|
|
526
|
-
title: '{siteName}',
|
|
527
|
-
description: '{siteDescription}',
|
|
528
|
-
};
|
|
529
|
-
/* /FP-12 patch */
|
|
530
|
-
```
|
|
531
|
-
|
|
532
|
-
(Use JS comment markers here — TSX does not allow HTML comments at module scope.) Idempotency: if `export const metadata` already exists anywhere in the file, skip; do not merge or replace user-authored metadata.
|
|
533
|
-
|
|
534
|
-
**Anti-patterns — do not do any of these (they look like they should work, they don't):**
|
|
535
|
-
- Passing `title` / `description` to `createDocsConfig()` in `next.config.js`. The wrapper ignores those keys; the exported HTML stays empty. Verify any `next.config.js` patch you consider against `@open-agent-toolkit/docs-config`'s actual exports.
|
|
536
|
-
- Setting `branding.title` alone and calling it done. `branding` populates nav chrome only; browser tab, search previews, and social cards all read `metadata`.
|
|
537
|
-
- Inserting `metadata` into a non-layout file (e.g., `page.tsx` under `[[...slug]]`). For site-wide metadata, `layout.tsx` is the authoritative location.
|
|
538
|
-
|
|
539
|
-
- **`<appRoot>/app/layout.tsx` — `branding.title`.** Scaffold shape has `branding: { title: '{appName}' }`. Replace the literal string value with `{siteName}` (the user-supplied display title). If adding a marker, put it inside the object literal where TSX accepts JavaScript comments:
|
|
540
|
-
|
|
541
|
-
```tsx
|
|
542
|
-
branding={{
|
|
543
|
-
/* FP-12 patch: branding title */
|
|
544
|
-
title: '{siteName}',
|
|
545
|
-
/* /FP-12 patch */
|
|
546
|
-
}}
|
|
547
|
-
```
|
|
548
|
-
|
|
549
|
-
Idempotency: if `branding.title` already equals `{siteName}` or the marker is already present, skip and record `status: 'skipped'`. This is the nav-chrome display title — a separate concern from the metadata export above.
|
|
448
|
+
**3d. Apply the remaining bridge.**
|
|
550
449
|
|
|
551
|
-
-
|
|
552
|
-
1. Frontmatter `title: '{appName}'` → `title: '{siteName}'`.
|
|
553
|
-
2. First H1 `# {appName}` → `# {siteName}`.
|
|
554
|
-
Do not add hidden FP comments. Idempotency: `{appName}` in both expected places = scaffold shape, safe to patch; `{siteName}` in both expected places = patched/upstream shape, skip; mixed or unexpected text = drift.
|
|
555
|
-
|
|
556
|
-
- **`<appRoot>/docs/getting-started.md`.** Body contains references to `{appName}` in the intro paragraph (per the historical scaffold template). Replace those references with `{siteName}`. Do not add hidden FP comments; classify by literal content shape.
|
|
557
|
-
|
|
558
|
-
- **`<appRoot>/docs/contributing.md`.** H1 `# {appName}` → `# {siteName}`. Do not add hidden FP comments; classify by literal content shape.
|
|
559
|
-
|
|
560
|
-
Failure handling: if Capability Detection (3b) classified any of these files as `drift`, the patch is already recorded as `refused` in `Scaffold Result.patchesApplied` — skip and move on. Do not re-check drift here.
|
|
450
|
+
FP-15 is the only post-scaffold patch. It is gated by detected capability and file absence, is idempotent, and appends `{ id, status: 'applied' | 'skipped', reason? }` to `Scaffold Result.patchesApplied`. All other scaffold content comes from the CLI template.
|
|
561
451
|
|
|
562
452
|
**FP-15: AGENTS.md write-if-missing (Fumadocs/MkDocs only).**
|
|
563
453
|
|
|
@@ -585,159 +475,7 @@ Procedure when gate passes:
|
|
|
585
475
|
|
|
586
476
|
When the CLI eventually scaffolds `AGENTS.md` natively and `agentsMdScaffoldFlag` becomes `true`, the bridge template in this skill can be retired (or folded back into the skill as a reference for how the CLI's template evolved).
|
|
587
477
|
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
These patches close the "scaffold works but produces inaccurate or incomplete output" gaps. They run after the site-identity patches so FP-13 sub-findings operate on the correct `{siteName}` text.
|
|
591
|
-
|
|
592
|
-
**FP-11: Turbopack root patch.**
|
|
593
|
-
|
|
594
|
-
Gate: run **only if** `repoShape === 'nested-standalone'` AND `framework === 'fumadocs'` AND `capabilities.turbopackRootFlag === false`. Monorepo and single-package shapes do not hit the multi-lockfile warning; MkDocs has no Turbopack concern. If any gate is unmet, record `{ id: 'FP-11', status: 'skipped', reason: '<gate that failed>' }`.
|
|
595
|
-
|
|
596
|
-
Two code paths, selected by the file-shape classification of `<appRoot>/next.config.js` from Capability Detection (3b):
|
|
597
|
-
|
|
598
|
-
- **Path A — `createDocsConfig` passthrough.** If `<appRoot>/next.config.js` is in scaffold shape using `createDocsConfig()` AND `@open-agent-toolkit/docs-config` exposes a `turbopack` passthrough option (determined by reading the installed package's type declarations or `package.json` exports), pass `{ root: __dirname }` through:
|
|
599
|
-
|
|
600
|
-
```js
|
|
601
|
-
// <!-- FP-11 patch: turbopack root passthrough -->
|
|
602
|
-
export default createDocsConfig({
|
|
603
|
-
turbopack: { root: __dirname },
|
|
604
|
-
});
|
|
605
|
-
// <!-- /FP-11 patch -->
|
|
606
|
-
```
|
|
607
|
-
|
|
608
|
-
Idempotency: if the marker is already present, skip with `status: 'skipped'`.
|
|
609
|
-
|
|
610
|
-
- **Path B — wrapper replacement.** If the passthrough isn't supported (the `@open-agent-toolkit/docs-config` version installed is older than the one that added it), replace the `createDocsConfig()` wrapper with an explicit `createMDX()` + hand-written Next config. Preserve any user-authored edits the wrapper had accumulated (by diffing against the known scaffold shape before replacing):
|
|
611
|
-
|
|
612
|
-
```js
|
|
613
|
-
// <!-- FP-11 patch: wrapper replaced for turbopack root -->
|
|
614
|
-
import createMDX from 'fumadocs-mdx/next';
|
|
615
|
-
|
|
616
|
-
const withMDX = createMDX();
|
|
617
|
-
|
|
618
|
-
/** @type {import('next').NextConfig} */
|
|
619
|
-
const config = {
|
|
620
|
-
reactStrictMode: true,
|
|
621
|
-
turbopack: { root: __dirname },
|
|
622
|
-
};
|
|
623
|
-
|
|
624
|
-
export default withMDX(config);
|
|
625
|
-
// <!-- /FP-11 patch -->
|
|
626
|
-
```
|
|
627
|
-
|
|
628
|
-
Before replacing, snapshot the original `next.config.js` to `next.config.js.pre-fp11.bak` in the same directory so the user can inspect the prior state. Record the backup path in `patchesApplied` so the Walkthrough can mention it.
|
|
629
|
-
|
|
630
|
-
Idempotency: if the marker is present, skip; if the wrapper replacement has already happened but without the marker (indicating a user-customized variant), classify as `drift` and refuse.
|
|
631
|
-
|
|
632
|
-
**FP-13: template-content patches.**
|
|
633
|
-
|
|
634
|
-
Five sub-findings, each with its own gate, target, and idempotency check. All sub-findings apply to Fumadocs; MkDocs handling lives in the Walkthrough's MkDocs Minimum Contract (Step 6, p05-t02) because the MkDocs scaffold's content layout differs and doesn't share these specific gaps.
|
|
635
|
-
|
|
636
|
-
- **Sub-finding A: Empty `description:` frontmatter.** Targets: `<appRoot>/docs/getting-started.md:3` and `<appRoot>/docs/contributing.md:3`.
|
|
637
|
-
- Gate: the target line matches `description: ''` (scaffold shape).
|
|
638
|
-
- Patch: replace with static defaults:
|
|
639
|
-
- `getting-started.md`: `description: 'Set up the local environment and preview the docs site.'`
|
|
640
|
-
- `contributing.md`: `description: 'Authoring conventions and navigation rules for this docs site.'`
|
|
641
|
-
- Do not add hidden FP comments. Idempotency: non-empty description matching the static default = patched/upstream shape, skip.
|
|
642
|
-
- Rationale: these are per-page descriptions, not site-level — do not template on `{siteDescription}`; use static text that describes the page's own purpose.
|
|
643
|
-
|
|
644
|
-
- **Sub-finding B: Bare install/build commands lack working-directory context.** Target: `<appRoot>/docs/getting-started.md` (the install/build code block, per scaffold lines 15-33 or nearest equivalent after FP-12 patches).
|
|
645
|
-
- Gate: the block contains a bare `pnpm install` / `pnpm dev` / `pnpm build` sequence with no `--filter` or `cd` prefix (scaffold shape).
|
|
646
|
-
- Patch: rewrite the block using the same command shapes as the CLI command renderer:
|
|
647
|
-
- `monorepo`: install `pnpm install` at repo root; dev `pnpm --filter {appName} dev`; build `pnpm --filter {appName} build`.
|
|
648
|
-
- `nested-standalone`: prefix each command with `cd {appDir} && ` (e.g., `cd apps/docs && pnpm install`).
|
|
649
|
-
- `single-package`: leave bare form when the app is at repo root; if the app lives in a subdirectory, use `cd {appDir} && pnpm <command>`.
|
|
650
|
-
- Do not add hidden FP comments. Idempotency: command block already matches the renderer output = patched/upstream shape, skip. If the block has drifted (not bare, not renderer-shaped), classify as `drift` and refuse.
|
|
651
|
-
|
|
652
|
-
- **Sub-finding C: False `docs:lint` claim.** Target: `<appRoot>/docs/contributing.md` line describing the `docs:lint` script (near line 31 per scaffold, may have shifted).
|
|
653
|
-
- Gate: `lint === 'none'` (Input Result) AND the line contains the exact scaffold string "Run Markdown formatting and linting as configured for this docs app."
|
|
654
|
-
- Patch: replace with "Run Markdown formatting as configured for this docs app." (dropping "and linting").
|
|
655
|
-
- If `lint === 'markdownlint-cli2'`, the original claim is accurate — skip with `status: 'skipped', reason: 'linting is configured'`.
|
|
656
|
-
- Do not add hidden FP comments. Idempotency: corrected sentence already present = patched/upstream shape, skip.
|
|
657
|
-
|
|
658
|
-
- **Sub-finding D: Generated-file guidance and old authored-header cleanup.** Two sub-targets:
|
|
659
|
-
- **D.1 — `contributing.md` explanatory section.** Append a "Generated files" section to `<appRoot>/docs/contributing.md` (before any closing References section if present). Two sentences:
|
|
660
|
-
|
|
661
|
-
```markdown
|
|
662
|
-
## Generated files
|
|
663
|
-
|
|
664
|
-
For Fumadocs apps, the root-level generated manifest at `<appRoot>/index.md` is regenerated from the Markdown file tree under `docs/` on every `predev` / `prebuild`. Do not hand-edit it; edit the authored source under `docs/` instead, and compare the generated manifest against authored `## Contents` when checking freshness. For MkDocs apps, the derived navigation artifact is the `nav:` section of `mkdocs.yml`, not a root manifest.
|
|
665
|
-
```
|
|
666
|
-
|
|
667
|
-
Idempotency: an existing `## Generated files` section with equivalent generated/root-manifest guidance = patched/upstream shape, skip. Do not add hidden FP comments.
|
|
668
|
-
|
|
669
|
-
- **D.2 — Authored `docs/index.md` false generated-header backstop.** Older scaffolds could place a generated-file warning on the authored source file at `<appRoot>/docs/index.md`. That warning is wrong: the authored file is edited by humans and agents; the generated Fumadocs manifest is `<appRoot>/index.md`.
|
|
670
|
-
- Gate: `<appRoot>/docs/index.md` contains the exact historical `AUTOGENERATED by \`oat docs generate-index\`` warning before the first H1.
|
|
671
|
-
- Patch: remove only that warning line, preserving frontmatter, the H1, and `## Contents`.
|
|
672
|
-
- Idempotency: no authored-file warning = patched/upstream shape, skip. If a different top comment is present, treat it as project prose and do not remove it.
|
|
673
|
-
- The generated root `<appRoot>/index.md` warning is CLI-owned. If it is missing after build, surface that as an Inspector warning; do not inject hooks into `package.json`.
|
|
674
|
-
|
|
675
|
-
- **E — Node version mismatch.** Target: `<appRoot>/docs/getting-started.md` "Prerequisites" section. The scaffold's `- Node.js 20+` claim (or any hard-coded major version) should reflect the **consuming repo's** actual Node requirement, not a scaffold-time default.
|
|
676
|
-
- Gate: always run when `<appRoot>/docs/getting-started.md` exists and has a `- Node.js` bullet in a "Prerequisites" section.
|
|
677
|
-
- Read (in priority order) `$REPO_ROOT/.nvmrc`, then `$REPO_ROOT/package.json` `engines.node`. If a version is found and it's different from the hard-coded version in the scaffold, rewrite the bullet to reference the detected version.
|
|
678
|
-
- Do not add hidden FP comments.
|
|
679
|
-
- If neither source is present or parseable, leave the scaffold default and record `{ id: 'FP-13/E', status: 'skipped', reason: 'no .nvmrc or engines.node to detect' }`.
|
|
680
|
-
- Idempotency: the bullet already reflects the detected version = patched/upstream shape, skip.
|
|
681
|
-
|
|
682
|
-
**FP-16: `## Contents` link-extension patch.**
|
|
683
|
-
|
|
684
|
-
Gate: run **only if** `framework === 'fumadocs'` AND the Capability Detection file-shape check classified `<appRoot>/docs/index.md` as `scaffold-shape` for FP-16 (extension-less `## Contents` links on real `.md` targets). If the scaffold has been fixed upstream and the file is already `patched-shape` (links are `.md`-suffixed), skip with `status: 'skipped', reason: 'CLI scaffold uses .md-suffixed links'`.
|
|
685
|
-
|
|
686
|
-
Target: `<appRoot>/docs/index.md` `## Contents` section. For each list item whose link target is extension-less:
|
|
687
|
-
|
|
688
|
-
- If the target corresponds to a sibling `.md` file (e.g., `getting-started` → `getting-started.md`), rewrite to append `.md`.
|
|
689
|
-
- If the target corresponds to a sibling subdirectory with an `index.md` (e.g., `reference` → `reference/`, with `reference/index.md`), rewrite to `reference/index.md`.
|
|
690
|
-
- Leave absolute URLs, anchors (`#section`), and already-suffixed links untouched.
|
|
691
|
-
|
|
692
|
-
Rewrite the `## Contents` block in place without hidden FP comments:
|
|
693
|
-
|
|
694
|
-
```markdown
|
|
695
|
-
## Contents
|
|
696
|
-
|
|
697
|
-
- [Getting Started](getting-started.md) - Set up the local docs toolchain and preview the site.
|
|
698
|
-
- [Contributing](contributing.md) - Authoring conventions and navigation rules.
|
|
699
|
-
```
|
|
700
|
-
|
|
701
|
-
Idempotency: if all local file links in `## Contents` are already `.md`-suffixed or `dir/index.md`-suffixed, skip with `status: 'skipped'`. If the `## Contents` section has drifted (mixed extensions, non-bulleted structure, extra prose between items), classify as `drift` per Capability Detection and record `refused` — do not attempt a partial rewrite.
|
|
702
|
-
|
|
703
|
-
**Rationale.** The `@open-agent-toolkit/docs-transforms` remark-links plugin strips `.md` / `dir/index.md` at build time for Fumadocs routing, so `.md`-suffixed authored links render correctly. `.md`-suffixed form is what `apps/oat-docs` uses in practice and is what agents can follow via direct file open without path inference. Extension-less links are the scaffold's historical form but are agent-hostile; FP-16 normalizes to the correct convention. When the CLI scaffold template is fixed upstream, the file-shape check will skip this patch automatically.
|
|
704
|
-
|
|
705
|
-
**FP-17: `contributing.md` three-surfaces cleanup.**
|
|
706
|
-
|
|
707
|
-
Gate: run **only if** `framework === 'fumadocs'` AND `<appRoot>/docs/contributing.md` exists AND contains a `## Agent guidance` section with scaffold-shape bullet content (short list of "treat index.md as truth", "prefer linking to source files", or similar).
|
|
708
|
-
|
|
709
|
-
Target: the `## Agent guidance` section in `<appRoot>/docs/contributing.md`. This section duplicates the role of the docs-app `AGENTS.md` (FP-15 bridge) and violates the three-surfaces discipline the Walkthrough Section D teaches:
|
|
710
|
-
|
|
711
|
-
- `docs/contributing.md` → human authoring conventions (Markdown features, frontmatter, linting).
|
|
712
|
-
- `<appRoot>/AGENTS.md` → agent runtime reference (how to add pages, restructure nav, audit/apply).
|
|
713
|
-
- Root `AGENTS.md` `## Documentation` section → repo-wide pointer.
|
|
714
|
-
|
|
715
|
-
Patch: replace the section body with a one-line pointer:
|
|
716
|
-
|
|
717
|
-
```markdown
|
|
718
|
-
## Agent guidance
|
|
719
|
-
|
|
720
|
-
See `AGENTS.md` in this directory for how agents should work inside this docs app. This `contributing.md` covers human authoring conventions; `AGENTS.md` covers agent runtime discipline (adding pages, restructuring nav, audit/apply, three agent-instruction surfaces). Keeping those concerns separate keeps each file useful to its audience.
|
|
721
|
-
```
|
|
722
|
-
|
|
723
|
-
Idempotency: if the section already contains the one-paragraph pointer to the docs-app `AGENTS.md`, skip with `status: 'skipped'`. If the `## Agent guidance` section has been edited beyond scaffold shape (more than the two or three default bullets; contains content that isn't "docs conventions already in AGENTS.md"), classify as `drift` and refuse — do not collapse user-authored content.
|
|
724
|
-
|
|
725
|
-
**Rationale.** Without this patch, agents reading `docs/contributing.md` find partial agent guidance that duplicates (and risks diverging from) the docs-app `AGENTS.md`. The three-surfaces model only works if each surface is the single-source-of-truth for its audience.
|
|
726
|
-
|
|
727
|
-
**Refuse-and-surface.** Every patch above respects the drift classification from Capability Detection. If a target was classified `drift`, the patch was already recorded as `refused` in 3b — skip here and do not re-check.
|
|
728
|
-
|
|
729
|
-
##### Post-patch ordering
|
|
730
|
-
|
|
731
|
-
Inside 3d, patches run in this order:
|
|
732
|
-
|
|
733
|
-
1. Site-identity patches (this section) — FP-12 before FP-15 is irrelevant; they target disjoint files.
|
|
734
|
-
2. Scaffold-integrity patches (p03-t04) — these run after site-identity because FP-13 sub-findings may reference strings FP-12 just rewrote.
|
|
735
|
-
|
|
736
|
-
**Design discipline:**
|
|
737
|
-
|
|
738
|
-
- **CLI is the source of truth for templates.** The Scaffold Runner never rewrites template content, re-renders frontmatter, or fabricates files the CLI was supposed to create. Post-patches only adjust specific known-gap locations and use either syntactically valid code markers or content-shape idempotency, depending on the target file type.
|
|
739
|
-
- **Capability Detection gates every patch.** No patch runs blindly; the file-shape check must pass, and the capability must be absent. This means the skill self-ratchets as CLI fixes land — when `--site-name` is supported upstream, FP-12 patches are skipped automatically.
|
|
740
|
-
- **Failure is loud, not silent.** CLI non-zero exit stops the flow with the verbatim error. Ambiguous file shapes record a `refused` patch status rather than guessing.
|
|
478
|
+
**Design discipline:** CLI errors stop the flow. Preserve existing files, report legacy output through analyze, and apply only the absent-file AGENTS bridge. Template upgrades belong to the CLI rather than bootstrap rewrites.
|
|
741
479
|
|
|
742
480
|
### Step 4: Build Verifier
|
|
743
481
|
|
|
@@ -779,10 +517,10 @@ Inspect the captured install and build output. For each known pattern below, che
|
|
|
779
517
|
- Handling: **auto-fix by rerunning install.** Re-run 4a once, then re-run 4b. If the second attempt still fails with the same pattern, escalate to surface-only — do not loop.
|
|
780
518
|
- **Turbopack "inferred workspace root" warning.**
|
|
781
519
|
- Detection: build stdout/stderr contains the Next.js/Turbopack inferred-root warning about multiple lockfiles.
|
|
782
|
-
- Handling:
|
|
783
|
-
- **
|
|
784
|
-
- Detection: build stdout contains repeated "Rewriting tsconfig..." lines
|
|
785
|
-
- Handling: **flag as regression.** PR #27 is supposed to have fixed this; if it still happens, add to `knownIssues[]` with note "
|
|
520
|
+
- Handling: flag the app's `next.config.js` and detected workspace root for analysis. Current nested-standalone scaffolds pass the ESM-safe app directory through `createDocsConfig`; monorepo and single-package scaffolds leave root discovery to Next.js. Older shapes need an analyze finding, not wrapper replacement.
|
|
521
|
+
- **Repeated tsconfig rewrite churn.**
|
|
522
|
+
- Detection: build stdout contains repeated "Rewriting tsconfig..." lines.
|
|
523
|
+
- Handling: **flag as regression.** PR #27 is supposed to have fixed this; if it still happens, add to `knownIssues[]` with note "tsconfig rewrite regression suspected — report to CLI maintainers". Build may still succeed, so do not halt the flow on this alone.
|
|
786
524
|
|
|
787
525
|
**4d. Unknown-error stop.**
|
|
788
526
|
|
|
@@ -795,7 +533,7 @@ If install or build fails with output that does not match any known pattern abov
|
|
|
795
533
|
|
|
796
534
|
**Auto-fix discipline.** Auto-fix is narrow by design — it applies only when there is a **single known-correct answer**. Everything else is surfaced. The goal is to save the user time on truly deterministic retries (like the `fumadocs-mdx` + missing-node_modules combination) without masking real failures under speculative "try again" loops.
|
|
797
535
|
|
|
798
|
-
**Cross-reference.**
|
|
536
|
+
**Cross-reference.** Template-content defects belong in an analyze finding. The Build Verifier classifies install/build failures; it does not rewrite Markdown or replace configuration wrappers.
|
|
799
537
|
|
|
800
538
|
**4e. Emit the Verification Result.**
|
|
801
539
|
|
|
@@ -838,10 +576,9 @@ If the `documentation` section is missing or malformed after a successful CLI in
|
|
|
838
576
|
For each field in `documentation`, check that the referenced path exists and has the expected type:
|
|
839
577
|
|
|
840
578
|
- `root`: must be a directory that exists on disk (absolute or resolved-relative to `$REPO_ROOT`).
|
|
841
|
-
- `index`: must be a file that exists on disk. For Fumadocs, this is the generated app-root manifest at `<appRoot>/index.md`, regenerated from the Markdown file tree under `docs/`. For MkDocs, this is the
|
|
842
|
-
- `config`:
|
|
843
|
-
- `tooling
|
|
844
|
-
- `tooling.lint` / `tooling.format`: must match Input Result values.
|
|
579
|
+
- `index`: must be a file that exists on disk. For Fumadocs, this is the generated app-root manifest at `<appRoot>/index.md`, regenerated from the Markdown file tree under `docs/`. For MkDocs, this is the configured nav/config surface at `<appRoot>/mkdocs.yml`; authored source remains `<appRoot>/docs/index.md`.
|
|
580
|
+
- `config`: optional framework configuration path. If present, verify it exists; examples are `<appRoot>/mkdocs.yml` and a Fumadocs `next.config.js`. Do not require it when absent.
|
|
581
|
+
- `tooling`: a string (`markdown`, `fumadocs`, or `mkdocs`) that must match the Input Result `framework`. Check lint and format against the generated package scripts, not properties of this string.
|
|
845
582
|
|
|
846
583
|
For each check that fails, append an entry to `issues[]`:
|
|
847
584
|
|
|
@@ -862,9 +599,8 @@ The parent config describes the repo's docs; the nested config (when present) sc
|
|
|
862
599
|
|
|
863
600
|
Beyond basic path existence, check for drift between the config and what the Scaffold Runner actually did:
|
|
864
601
|
|
|
865
|
-
-
|
|
866
|
-
-
|
|
867
|
-
- If Turbopack "inferred workspace root" was flagged in `Verification Result.knownIssues` despite FP-11 having been applied, record a `driftFinding` — FP-11's patch should have suppressed the warning.
|
|
602
|
+
- Surface legacy-scaffold findings with paths and suggested review actions. Preserve the CLI-owned wrapper and user-authored content.
|
|
603
|
+
- If Turbopack reports an unexpected inferred workspace root, record a `driftFinding` for the app config and installed docs-config version.
|
|
868
604
|
|
|
869
605
|
Each drift finding appends to `issues[]` with `severity: 'warning'` (user should address) or `severity: 'info'` (worth mentioning but not blocking).
|
|
870
606
|
|
|
@@ -877,7 +613,8 @@ Before asking, explain what it does:
|
|
|
877
613
|
```
|
|
878
614
|
OAT projects can optionally require that docs are updated before completion.
|
|
879
615
|
If enabled, `oat-project-complete` won't mark a project done until the
|
|
880
|
-
`
|
|
616
|
+
project documentation state records `oat_docs_updated: complete` or an explicit
|
|
617
|
+
skip (`oat_docs_updated: skipped`) after the `oat-project-document` prompt.
|
|
881
618
|
|
|
882
619
|
Enable this for {appName}? (default: no)
|
|
883
620
|
```
|
|
@@ -921,13 +658,13 @@ Ground this section in the `Inspection Result.parent.documentation` object read
|
|
|
921
658
|
Narrate each field actually present in their config (skip fields that are absent — don't teach MkDocs-only fields to a Fumadocs user):
|
|
922
659
|
|
|
923
660
|
- **`documentation.root`** — the scaffolded app directory. Downstream tools (`oat-project-document`, `oat-docs-analyze`, `oat-docs-apply`) use this to find "the docs" without the user having to tell them.
|
|
924
|
-
- **`documentation.tooling`** — framework
|
|
661
|
+
- **`documentation.tooling`** — a framework string (`markdown`, `fumadocs`, or `mkdocs`). Lint and format choices live in package scripts. The framework is also echoed into the `## Documentation` section the CLI wrote into root `AGENTS.md`.
|
|
925
662
|
- **`documentation.index`** — branch this narration on the inspected `documentation.tooling` and path; do not describe one meaning for every framework:
|
|
926
663
|
- **Fumadocs:** this should be the generated app-root manifest, usually `<appRoot>/index.md`, after the successful build ran `oat docs generate-index`. Explain that this machine-shaped file is how tools inspect the full Markdown file tree, and that the authored source map the user edits is a separate file at `<appRoot>/docs/index.md` with its own `## Contents`.
|
|
927
664
|
- **Fumadocs stale path warning:** if the inspected path still points inside `<appRoot>/docs/` after build verification, do not teach that as normal. Surface it as a warning that `oat docs generate-index` did not update `documentation.index` as expected, then point the user to Section B for the generated/authored split.
|
|
928
665
|
- **MkDocs:** this should point at the configured MkDocs nav/config surface, usually `<appRoot>/mkdocs.yml` and matching `documentation.config`. Explain that the YAML file contains the generated/derived `nav:` block when `oat docs nav sync` is used, while authored `docs/index.md` and nested `## Contents` sections remain the source maps the user edits.
|
|
929
|
-
- **`documentation.config`**
|
|
930
|
-
- **`documentation.requireForProjectCompletion`** — the opt-in collected in Step 5e. If `true`, `oat-project-complete` will block project completion until `oat-
|
|
666
|
+
- **`documentation.config`** — optional path to the framework configuration, such as `mkdocs.yml` or `next.config.js`. Inspect whichever path is actually configured.
|
|
667
|
+
- **`documentation.requireForProjectCompletion`** — the opt-in collected in Step 5e. If `true`, `oat-project-complete` will block project completion until the project records `oat_docs_updated: complete` or an explicit `skipped` after the `oat-project-document` prompt. Explain whichever value is set on this project.
|
|
931
668
|
|
|
932
669
|
If `Scaffold Result.rootBuildPatch` is present, narrate it here before moving on:
|
|
933
670
|
|
|
@@ -940,7 +677,7 @@ End with: "This config is how every OAT docs tool finds your docs. Editing it by
|
|
|
940
677
|
|
|
941
678
|
#### Section B (both frameworks) — Authored source and generated navigation
|
|
942
679
|
|
|
943
|
-
This section prevents
|
|
680
|
+
This section prevents a common generated-file mistake: users silently hand-edit the Fumadocs generated root `index.md` and wonder why their edits vanish on the next build.
|
|
944
681
|
|
|
945
682
|
Narrate:
|
|
946
683
|
|
|
@@ -964,7 +701,7 @@ Narrate:
|
|
|
964
701
|
- **The `## Contents` section is the machine-readable local map.** For Fumadocs, `oat docs nav sync` reads it to write the committed `meta.json` sidebar files, and agents compare it against the generated app-root manifest. For MkDocs, `oat docs nav sync` reads it to update `mkdocs.yml` `nav:`. `oat-docs-analyze` reads the same authored source to find orphaned pages and stale generated artifacts.
|
|
965
702
|
- **Anything not listed in `## Contents` is invisible to the tooling.** Adding a Markdown file is not enough — it must also appear under the parent `index.md`'s `## Contents`.
|
|
966
703
|
|
|
967
|
-
Show the user their own `docs/index.md` `## Contents` as a concrete example (read the file and paste the relevant 5–15 lines).
|
|
704
|
+
Show the user their own `docs/index.md` `## Contents` as a concrete example (read the file and paste the relevant 5–15 lines). Then note: "That's the pattern. Every directory you create from now on follows the same shape — `.md`-suffixed links, bulleted list, dash-separated summary per entry."
|
|
968
705
|
|
|
969
706
|
End with: "`## Contents` is how navigation stays in sync with filesystem. If the nav tooling seems confused, the answer is almost always 'check the nearest `## Contents`'. Always author with `.md` extensions; the build pipeline handles routing."
|
|
970
707
|
|
|
@@ -986,11 +723,11 @@ Skip this section entirely when `framework === 'mkdocs'`; the MkDocs equivalent
|
|
|
986
723
|
|
|
987
724
|
Narrate how the Fumadocs scaffold actually works, grounded in files the user can open alongside you:
|
|
988
725
|
|
|
989
|
-
- **`app/layout.tsx` — `DocsLayout` renders the chrome.** The `<DocsLayout>` component from `@open-agent-toolkit/docs-theme` wraps every docs page with the top nav, sidebar, and search UI. It accepts a `branding` prop with `title`, `logo`, etc. **Runtime insight (worth knowing):** the compiled theme bundle only forwards `branding.title` into the nav header chrome — it doesn't use it for page metadata, social cards, or browser tab titles.
|
|
726
|
+
- **`app/layout.tsx` — `DocsLayout` renders the chrome.** The `<DocsLayout>` component from `@open-agent-toolkit/docs-theme` wraps every docs page with the top nav, sidebar, and search UI. It accepts a `branding` prop with `title`, `logo`, etc. **Runtime insight (worth knowing):** the compiled theme bundle only forwards `branding.title` into the nav header chrome — it doesn't use it for page metadata, social cards, or browser tab titles. The CLI template also includes `export const metadata = { title, description }` in `layout.tsx`: the chrome title and the document title are two separate concerns, and both surfaces must be configured. **Anti-pattern to avoid:** passing `title` / `description` to `createDocsConfig()` in `next.config.js` is a no-op — the wrapper accepts `basePath` and `turbopack`, not metadata. If your HTML `<head>` comes back empty (no `<title>`, no meta description, no Open Graph), the `export const metadata` in `layout.tsx` is missing.
|
|
990
727
|
- **`next.config.js` — `createMDX()` picks up `docs/`.** The Fumadocs MDX pipeline uses `@open-agent-toolkit/docs-config`'s `createDocsConfig()` wrapper, which under the hood calls `createMDX()` with the docs directory hardcoded to `docs/`. Both `.md` and `.mdx` files are compiled at build time; frontmatter becomes typed metadata accessible from layouts and listings. **Default to `.md`** for plain content pages — agents, linters, grep rules, and the `remark-links` plugin all handle `.md` more predictably than `.mdx`. Reach for `.mdx` only when a page actually needs a JSX component inline (an embedded `<Callout>`, an interactive widget, a custom layout). FlexSearch indexes them identically.
|
|
991
728
|
- **FlexSearch static indexing.** Search is client-side — on build, Fumadocs scans every `.md`/`.mdx` file under `docs/` and emits a precomputed FlexSearch index that loads alongside the first route. No server; no search API call. That's also why renaming a page without a redirect loses deep links silently: the old index entry stops existing at the next build, and the new one doesn't know the old slug.
|
|
992
|
-
- **`@open-agent-toolkit/docs-theme` branding.** The theme package centralizes the nav/sidebar/footer look and forwards only a small surface of props. Don't expect `branding` to influence metadata; use the
|
|
993
|
-
- **
|
|
729
|
+
- **`@open-agent-toolkit/docs-theme` branding.** The theme package centralizes the nav/sidebar/footer look and forwards only a small surface of props. Don't expect `branding` to influence metadata; use the Next.js `metadata` export for that.
|
|
730
|
+
- **Turbopack app root.** For `nested-standalone` only, the template passes `dirname(fileURLToPath(import.meta.url))` through `createDocsConfig({ turbopack: { root } })`. Monorepo and single-package scaffolds leave root discovery to Next.js so workspace dependencies remain reachable. This works in ESM and retains static export, trailing slashes, unoptimized images, and base-path settings. Report older wrappers to analyze instead of replacing them.
|
|
994
731
|
|
|
995
732
|
End with: "Fumadocs gives you a typed MDX-capable pipeline with client-side search and code-owned chrome. Prefer `.md` for plain content, reach for `.mdx` only when you need embedded components. Branding is one layer (nav only); metadata is a separate, explicit concern. Most page-level edits are frontmatter + Markdown; only layout/theme changes go in `app/`."
|
|
996
733
|
|
|
@@ -1005,7 +742,7 @@ In scope (required — share these):
|
|
|
1005
742
|
- **`mkdocs.yml` is the root config.** Site name, nav, theme, plugins, Markdown extensions — all in one YAML file. The CLI scaffolded one tuned for the OAT conventions.
|
|
1006
743
|
- **Material theme provides the default UI.** Light/dark toggle, responsive sidebar, search UI. Config lives under `theme:` in `mkdocs.yml`.
|
|
1007
744
|
- **Plugins are pip-installed and named in `mkdocs.yml`.** The scaffold's `requirements.txt` pins the plugins currently wired in. Adding a new plugin = add to both files.
|
|
1008
|
-
- **Python environment via `requirements.txt` + `setup-docs.sh`.** The scaffold provides a `setup-docs.sh` that
|
|
745
|
+
- **Python environment via `requirements.txt` + `setup-docs.sh`.** The scaffold provides a `setup-docs.sh` that runs `PYTHON_BIN -m pip install -r requirements.txt`. It does not create or activate a virtual environment. Create and activate one first when desired (`python3 -m venv .venv` then `. .venv/bin/activate`), or set `PYTHON_BIN` to the intended environment's Python.
|
|
1009
746
|
- **The shared concepts still apply.** The `## Contents` contract (Section C), the authored-source/generated-navigation model (Section B), and the three agent-instruction surfaces (Section D) all transfer directly.
|
|
1010
747
|
|
|
1011
748
|
Deferred (out of scope for this skill — point, don't teach):
|
|
@@ -1095,9 +832,6 @@ Created:
|
|
|
1095
832
|
- <count> files (see `git status` or `git log -1` for the full list)
|
|
1096
833
|
|
|
1097
834
|
Patches applied:
|
|
1098
|
-
- FP-11 Turbopack root: {applied | skipped | refused | n/a}
|
|
1099
|
-
- FP-12 site title + metadata: {applied | skipped | refused}
|
|
1100
|
-
- FP-13 template content (A–D): {applied | skipped | refused} per sub-finding
|
|
1101
835
|
- FP-15 docs-app AGENTS.md: {applied | skipped}
|
|
1102
836
|
|
|
1103
837
|
Build:
|
|
@@ -1169,7 +903,7 @@ A successful `oat-docs-bootstrap` run satisfies every invariant below. Any failu
|
|
|
1169
903
|
**Ratcheting invariants:**
|
|
1170
904
|
|
|
1171
905
|
- When a CLI capability is detected as present (`capabilities.{flag} === true`), the corresponding post-patch is **skipped** — not applied redundantly. The skill self-ratchets as CLI fixes land.
|
|
1172
|
-
- Every patch's `status` is recorded in `Scaffold Result.patchesApplied` as `applied` / `skipped`
|
|
906
|
+
- Every patch's `status` is recorded in `Scaffold Result.patchesApplied` as `applied` / `skipped` with a `reason`. The Exit summary surfaces this so the user sees which CLI gaps the skill had to cover vs. which the CLI handled directly.
|
|
1173
907
|
- When `capabilities.agentsMdScaffoldFlag === true` (CLI has added native AGENTS.md scaffolding), the FP-15 bridge in this skill is skipped and can be retired from the assets directory.
|
|
1174
908
|
|
|
1175
909
|
**Stop-on-broken-state invariants:**
|
|
@@ -65,6 +65,12 @@ Built-in FlexSearch-powered static search for discovering content without browsi
|
|
|
65
65
|
|
|
66
66
|
Theme toggle is included in the layout. Mermaid diagrams re-render on mode switch.
|
|
67
67
|
|
|
68
|
+
## Generated files
|
|
69
|
+
|
|
70
|
+
The app-root `index.md` is the generated manifest, rebuilt from `docs/` on every `predev` and `prebuild` by `oat docs generate-index`. Edit the authored `docs/index.md` and its `## Contents`, then regenerate the manifest; do not hand-edit it.
|
|
71
|
+
|
|
72
|
+
The `docs/**/meta.json` sidebar files are committed derived navigation. After changing authored `## Contents`, run `oat docs nav sync --target-dir "{{APP_DIR}}"` from the repository root to update them. They are separate from the generated app-root manifest.
|
|
73
|
+
|
|
68
74
|
## Agent guidance
|
|
69
75
|
|
|
70
76
|
See `AGENTS.md` in this directory for how agents should work inside this docs app. This `contributing.md` covers human authoring conventions; `AGENTS.md` covers agent runtime discipline (adding pages, restructuring nav, audit/apply, three agent-instruction surfaces). Keeping those concerns separate keeps each file useful to its audience.
|
|
@@ -9,7 +9,7 @@ Use this guide to set up your local environment and preview {{SITE_NAME}}.
|
|
|
9
9
|
|
|
10
10
|
## Prerequisites
|
|
11
11
|
|
|
12
|
-
- Node.js
|
|
12
|
+
- Node.js {{NODE_REQUIREMENT}}
|
|
13
13
|
- pnpm 10+ (or npm/yarn)
|
|
14
14
|
|
|
15
15
|
## Install dependencies
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
// {{TURBOPACK_ROOT_IMPORTS}}
|
|
1
2
|
import { createDocsConfig } from '@open-agent-toolkit/docs-config';
|
|
2
3
|
|
|
3
4
|
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || undefined;
|
|
4
5
|
|
|
5
|
-
export default createDocsConfig(
|
|
6
|
+
export default createDocsConfig({
|
|
7
|
+
...(basePath ? { basePath } : {}),
|
|
8
|
+
// {{TURBOPACK_ROOT_OPTION}}
|
|
9
|
+
});
|
|
@@ -37,7 +37,7 @@ export function createDocsAnalyzeCommand(overrides = {}) {
|
|
|
37
37
|
...overrides,
|
|
38
38
|
};
|
|
39
39
|
return new Command('analyze')
|
|
40
|
-
.description('
|
|
40
|
+
.description('Show guidance for the oat-docs-analyze skill')
|
|
41
41
|
.action(async (_options, command) => {
|
|
42
42
|
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
43
43
|
await runDocsAnalyzeCommand(context);
|
|
@@ -37,7 +37,7 @@ export function createDocsApplyCommand(overrides = {}) {
|
|
|
37
37
|
...overrides,
|
|
38
38
|
};
|
|
39
39
|
return new Command('apply')
|
|
40
|
-
.description('
|
|
40
|
+
.description('Show guidance for the oat-docs-apply skill')
|
|
41
41
|
.action(async (_options, command) => {
|
|
42
42
|
const context = dependencies.buildCommandContext(readGlobalOptions(command));
|
|
43
43
|
await runDocsApplyCommand(context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/scaffold.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAMjE,OAAO,KAAK,EAEV,aAAa,EACb,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AAsF3B,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,sBAAsB,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,WAAW,2BAA2B;IAC1C,iBAAiB,EAAE,MAAM,YAAY,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACjE,0BAA0B,EAAE,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,YAAY,CAAC,OAAO,CAAC,CAAC;CAC5B;AAUD,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAgDD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAaxB;
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/init/scaffold.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,oBAAoB,CAAC;AAMjE,OAAO,KAAK,EAEV,aAAa,EACb,uBAAuB,EAExB,MAAM,mBAAmB,CAAC;AAsF3B,MAAM,WAAW,sBAAuB,SAAQ,uBAAuB;IACrE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mBAAmB,EAAE,sBAAsB,CAAC;CAC7C;AAED,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,OAAO,CAAC;IACnB,aAAa,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC3B,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC5C;AAED,KAAK,YAAY,CAAC,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;AAEtC,MAAM,WAAW,2BAA2B;IAC1C,iBAAiB,EAAE,MAAM,YAAY,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACjE,0BAA0B,EAAE,CAC1B,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,KACZ,YAAY,CAAC,OAAO,CAAC,CAAC;CAC5B;AAUD,eAAO,MAAM,aAAa,YAAY,CAAC;AAEvC,wBAAsB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAOxE;AAgDD,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,aAAa,CAAC,CAaxB;AA2MD;;;;;;;;GAQG;AACH,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,aAAa,EACxB,SAAS,EAAE,MAAM,GAChB,sBAAsB,CAsBxB;AA6CD,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,EAC/B,SAAS,GAAE,OAAO,CAAC,2BAA2B,CAAM,GACnD,OAAO,CAAC,qBAAqB,CAAC,CAwDhC"}
|
|
@@ -221,11 +221,18 @@ async function buildPackageManagerField(options, appRoot, dependencies) {
|
|
|
221
221
|
const version = normalizePnpmVersion(await dependencies.detectPnpmVersion());
|
|
222
222
|
return `,\n "packageManager": ${JSON.stringify(`pnpm@${version}`)}`;
|
|
223
223
|
}
|
|
224
|
-
function renderTemplate(template, options, depContext, packageManagerField) {
|
|
224
|
+
function renderTemplate(template, options, depContext, packageManagerField, nodeRequirement) {
|
|
225
225
|
const repoName = basename(options.repoRoot);
|
|
226
226
|
const commands = buildDocsCommands(options.repoShape, options.targetDir, options.appName);
|
|
227
227
|
const replacements = {
|
|
228
|
+
'// {{TURBOPACK_ROOT_IMPORTS}}\n': options.repoShape === 'nested-standalone'
|
|
229
|
+
? "import { dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\n\n"
|
|
230
|
+
: '',
|
|
231
|
+
' // {{TURBOPACK_ROOT_OPTION}}\n': options.repoShape === 'nested-standalone'
|
|
232
|
+
? ' turbopack: { root: dirname(fileURLToPath(import.meta.url)) },\n'
|
|
233
|
+
: '',
|
|
228
234
|
'{{APP_NAME}}': options.appName,
|
|
235
|
+
'{{NODE_REQUIREMENT}}': nodeRequirement,
|
|
229
236
|
'{{PACKAGE_NAME}}': options.appName,
|
|
230
237
|
'{{SITE_NAME}}': options.siteName,
|
|
231
238
|
'{{SITE_DESCRIPTION}}': options.siteDescription,
|
|
@@ -288,6 +295,31 @@ export function buildDocumentationConfig(framework, targetDir) {
|
|
|
288
295
|
index: join(targetDir, 'mkdocs.yml'),
|
|
289
296
|
};
|
|
290
297
|
}
|
|
298
|
+
async function detectNodeRequirement(repoRoot) {
|
|
299
|
+
try {
|
|
300
|
+
const nvmrc = (await readFile(join(repoRoot, '.nvmrc'), 'utf8')).trim();
|
|
301
|
+
if (/^v?\d+(?:\.\d+){0,2}$/.test(nvmrc) ||
|
|
302
|
+
/^(?:lts\/[a-z*]+|node|stable)$/.test(nvmrc)) {
|
|
303
|
+
return nvmrc;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
// Repositories need not pin Node with .nvmrc.
|
|
308
|
+
}
|
|
309
|
+
try {
|
|
310
|
+
const pkg = JSON.parse(await readFile(join(repoRoot, 'package.json'), 'utf8'));
|
|
311
|
+
const requirement = pkg.engines?.node;
|
|
312
|
+
if (typeof requirement === 'string' &&
|
|
313
|
+
requirement.trim() &&
|
|
314
|
+
!/[\r\n`]/.test(requirement)) {
|
|
315
|
+
return requirement.trim();
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
catch {
|
|
319
|
+
// Fall back to the CLI's supported minimum when no requirement is recorded.
|
|
320
|
+
}
|
|
321
|
+
return '>=22.17.0';
|
|
322
|
+
}
|
|
291
323
|
async function ensureTargetWritable(appRoot) {
|
|
292
324
|
if (!(await dirExists(appRoot))) {
|
|
293
325
|
return;
|
|
@@ -317,11 +349,12 @@ export async function scaffoldDocsApp(options, overrides = {}) {
|
|
|
317
349
|
await ensureTargetWritable(appRoot);
|
|
318
350
|
await ensureDir(appRoot);
|
|
319
351
|
const packageManagerField = await buildPackageManagerField(options, appRoot, dependencies);
|
|
352
|
+
const nodeRequirement = await detectNodeRequirement(options.repoRoot);
|
|
320
353
|
for (const templateFile of frameworkConfig.templateFiles) {
|
|
321
354
|
const source = join(templateRoot, templateFile.source);
|
|
322
355
|
const destination = join(appRoot, templateFile.destination);
|
|
323
356
|
const template = await readFile(source, 'utf8');
|
|
324
|
-
const rendered = renderTemplate(template, options, depContext, packageManagerField);
|
|
357
|
+
const rendered = renderTemplate(template, options, depContext, packageManagerField, nodeRequirement);
|
|
325
358
|
await ensureDir(dirname(destination));
|
|
326
359
|
await writeFile(destination, rendered, 'utf8');
|
|
327
360
|
createdFiles.push(templateFile.destination);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-agent-toolkit/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.23",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Open Agent Toolkit CLI",
|
|
6
6
|
"homepage": "https://github.com/voxmedia/open-agent-toolkit/tree/main/packages/cli",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"ora": "^9.0.0",
|
|
36
36
|
"yaml": "2.8.2",
|
|
37
37
|
"zod": "^3.25.76",
|
|
38
|
-
"@open-agent-toolkit/control-plane": "0.3.
|
|
38
|
+
"@open-agent-toolkit/control-plane": "0.3.23"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
41
|
"@types/node": "^22.10.0",
|