@open-agent-toolkit/cli 0.3.26 → 0.3.28
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/README.md +12 -0
- package/assets/bundle-metadata.json +1 -1
- package/assets/docs/contributing/documentation.md +48 -6
- package/assets/docs/contributing/markdown-features.md +14 -2
- package/assets/docs/docs-tooling/add-docs-to-a-repo.md +22 -9
- package/assets/docs/docs-tooling/check.md +154 -0
- package/assets/docs/docs-tooling/commands.md +15 -10
- package/assets/docs/docs-tooling/index.md +1 -0
- package/assets/docs/docs-tooling/meta.json +7 -1
- package/assets/docs/docs-tooling/workflows.md +18 -10
- package/assets/docs/getting-started/tool-packs.md +5 -3
- package/assets/docs/reference/cli-reference.md +2 -0
- package/assets/docs/reference/configuration.md +1 -0
- package/assets/docs/skills/index.md +8 -8
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/oat-docs-analyze/SKILL.md +14 -3
- package/assets/skills/oat-docs-analyze/references/legacy-scaffold-checks.md +4 -0
- package/assets/skills/oat-docs-authoring/SKILL.md +1 -1
- package/assets/skills/oat-docs-authoring/references/validation.md +4 -0
- package/assets/skills/oat-docs-bootstrap/SKILL.md +92 -61
- package/assets/skills/oat-docs-bootstrap/references/pr-ci.md +89 -0
- package/assets/templates/docs-app-fuma/AGENTS.md +57 -0
- package/assets/templates/docs-app-fuma/app/[[...slug]]/page.tsx +7 -3
- package/assets/templates/docs-app-fuma/app/llms/[...slug]/route.ts +15 -0
- package/assets/templates/docs-app-fuma/app/llms-full.txt/route.ts +7 -0
- package/assets/templates/docs-app-fuma/app/llms.txt/route.ts +7 -0
- package/assets/templates/docs-app-fuma/docs/contributing/docs-toolchain.md +85 -0
- package/assets/templates/docs-app-fuma/docs/contributing/index.md +13 -0
- package/assets/templates/docs-app-fuma/docs/contributing.md +83 -41
- package/assets/templates/docs-app-fuma/docs/getting-started.md +3 -33
- package/assets/templates/docs-app-fuma/docs/index.md +3 -3
- package/assets/templates/docs-app-fuma/gitignore.template +12 -0
- package/assets/templates/docs-app-fuma/lib/source.ts +5 -0
- package/assets/templates/docs-app-fuma/package.json.template +2 -1
- package/assets/templates/docs-app-fuma/pnpm-workspace.yaml +5 -0
- package/assets/templates/docs-app-mkdocs/AGENTS.md +48 -0
- package/assets/templates/docs-app-mkdocs/docs/contributing/docs-toolchain.md +46 -0
- package/assets/templates/docs-app-mkdocs/docs/contributing/index.md +13 -0
- package/assets/templates/docs-app-mkdocs/docs/contributing.md +111 -21
- package/assets/templates/docs-app-mkdocs/docs/getting-started.md +7 -25
- package/assets/templates/docs-app-mkdocs/docs/index.md +7 -2
- package/assets/templates/docs-app-mkdocs/gitignore.template +8 -0
- package/assets/templates/docs-app-mkdocs/mkdocs.yml +1 -0
- package/assets/templates/docs-app-mkdocs/package.json.template +3 -2
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +35 -3
- package/dist/commands/docs/check/check.d.ts +3 -0
- package/dist/commands/docs/check/check.d.ts.map +1 -0
- package/dist/commands/docs/check/check.js +48 -0
- package/dist/commands/docs/check/check.types.d.ts +17 -0
- package/dist/commands/docs/check/check.types.d.ts.map +1 -0
- package/dist/commands/docs/check/check.types.js +1 -0
- package/dist/commands/docs/check/checker.d.ts +8 -0
- package/dist/commands/docs/check/checker.d.ts.map +1 -0
- package/dist/commands/docs/check/checker.js +82 -0
- package/dist/commands/docs/check/commands.d.ts +5 -0
- package/dist/commands/docs/check/commands.d.ts.map +1 -0
- package/dist/commands/docs/check/commands.js +232 -0
- package/dist/commands/docs/check/diagrams.d.ts +5 -0
- package/dist/commands/docs/check/diagrams.d.ts.map +1 -0
- package/dist/commands/docs/check/diagrams.js +197 -0
- package/dist/commands/docs/check/files.d.ts +21 -0
- package/dist/commands/docs/check/files.d.ts.map +1 -0
- package/dist/commands/docs/check/files.js +121 -0
- package/dist/commands/docs/check/markdown.d.ts +60 -0
- package/dist/commands/docs/check/markdown.d.ts.map +1 -0
- package/dist/commands/docs/check/markdown.js +125 -0
- package/dist/commands/docs/check/mermaid-runtime.d.ts +3 -0
- package/dist/commands/docs/check/mermaid-runtime.d.ts.map +1 -0
- package/dist/commands/docs/check/mermaid-runtime.js +57 -0
- package/dist/commands/docs/check/navigation.d.ts +4 -0
- package/dist/commands/docs/check/navigation.d.ts.map +1 -0
- package/dist/commands/docs/check/navigation.js +104 -0
- package/dist/commands/docs/check/reader-rules.d.ts +6 -0
- package/dist/commands/docs/check/reader-rules.d.ts.map +1 -0
- package/dist/commands/docs/check/reader-rules.js +214 -0
- package/dist/commands/docs/index.d.ts.map +1 -1
- package/dist/commands/docs/index.js +2 -0
- package/dist/commands/docs/init/docs-commands.d.ts +1 -0
- package/dist/commands/docs/init/docs-commands.d.ts.map +1 -1
- package/dist/commands/docs/init/docs-commands.js +8 -3
- package/dist/commands/docs/init/index.d.ts +1 -0
- package/dist/commands/docs/init/index.d.ts.map +1 -1
- package/dist/commands/docs/init/index.js +8 -0
- package/dist/commands/docs/init/scaffold.d.ts +1 -0
- package/dist/commands/docs/init/scaffold.d.ts.map +1 -1
- package/dist/commands/docs/init/scaffold.js +61 -13
- package/dist/commands/docs/nav/contents.d.ts +4 -0
- package/dist/commands/docs/nav/contents.d.ts.map +1 -1
- package/dist/commands/docs/nav/contents.js +10 -0
- package/dist/commands/docs/nav/fumadocs.d.ts.map +1 -1
- package/dist/commands/docs/nav/fumadocs.js +32 -10
- package/dist/config/documentation-check.d.ts +38 -0
- package/dist/config/documentation-check.d.ts.map +1 -0
- package/dist/config/documentation-check.js +132 -0
- package/dist/config/oat-config.d.ts +2 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +4 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +1 -0
- package/dist/release/public-package-contract.d.ts.map +1 -1
- package/dist/release/public-package-contract.js +3 -0
- package/package.json +11 -2
- package/assets/skills/oat-docs-bootstrap/assets/AGENTS.md.template +0 -64
|
@@ -1,29 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Contributing
|
|
3
|
+
description: 'Authoring contract, generated files, supported syntax and validation.'
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# Contributing to {{SITE_NAME}}
|
|
2
7
|
|
|
3
|
-
|
|
8
|
+
Ship documentation with the behavior it explains. Use the [docs toolchain guide](contributing/docs-toolchain.md) for setup and validation and [contributor guides](contributing/index.md) as the local map.
|
|
9
|
+
|
|
10
|
+
Agent working rules: `../AGENTS.md` (app-root source file).
|
|
11
|
+
|
|
12
|
+
## Authored and generated files
|
|
13
|
+
|
|
14
|
+
| Surface | Owner and action |
|
|
15
|
+
| ---------------------------------------------------- | ------------------------------------------------------------------------- |
|
|
16
|
+
| `docs/**/*.md`, including `docs/**/index.md` | Authored source; edit purpose and Contents maps directly. |
|
|
17
|
+
| `AGENTS.md` and this contributor guide | Authored working rules and human guidance; keep their audiences separate. |
|
|
18
|
+
| `mkdocs.yml` outside `nav:` | Authored framework configuration. |
|
|
19
|
+
| `mkdocs.yml` `nav:` | Committed derived sidebar; regenerate with nav sync. |
|
|
20
|
+
| `site/` | Generated site output; do not edit. |
|
|
21
|
+
| `requirements.txt`, `setup-docs.sh`, package scripts | Authored toolchain; changing pins needs an explicit tooling review. |
|
|
22
|
+
|
|
23
|
+
MkDocs 1.4.2 has no configurable rendering exclusion: non-reader pages leave nav/manifest but still render as routes. Do not promise private draft routes or add an exclusion plugin as an implicit repair.
|
|
24
|
+
|
|
25
|
+
This MkDocs/Material scaffold is **legacy**. [Material's upstream changelog](https://squidfunk.github.io/mkdocs-material/changelog/) states that it is in maintenance mode, with critical bug fixes and security updates through **May 5, 2027**, then upstream maintenance ends. The team identifies [Zensical](https://zensical.org/) as its maintained successor. This date applies to Material, not MkDocs core. Existing Python pins remain unchanged; the maintenance statement does not promise backports to these exact old pins. Plan an explicit tooling review before adopting this path for a new site.
|
|
4
26
|
|
|
5
27
|
## Navigation contract
|
|
6
28
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
29
|
+
Fresh scaffolds set `use_directory_urls: false` in `mkdocs.yml`. Pages use `.html` URLs: `contributing.md` renders as `contributing.html`, and the local map `contributing/index.md` renders as `contributing/index.html`. Keep both source files and `.md`-suffixed authored links; MkDocs resolves them to the distinct rendered destinations. Changing this setting requires reviewing published URLs and inbound links.
|
|
30
|
+
|
|
31
|
+
Every content directory has an authored `index.md` with a useful purpose paragraph and one `## Contents` local map. Prefer `.md` pages with nonempty `title` and `description` frontmatter and exactly one document H1. `overview.md` is deprecated.
|
|
32
|
+
|
|
33
|
+
Within `## Contents`, use dash-only links to sibling pages or child indexes, optionally followed by a description. A `### Label` starts a group and must contain at least one authored entry before the next group/end. Entries before the first group are ungrouped. A `*` or `+` link bullet, or an empty authored group, is an error naming the file and line. The map ends at the next level-two heading; fenced examples are ignored. A self-index link retains the existing landing-page behavior. Optional Markdown inventories keep deterministic fallback when Contents is missing; MkDocs nav sync needs authored maps to construct navigation. The pinned MkDocs build can still render pages absent from its navigation.
|
|
34
|
+
|
|
35
|
+
```markdown
|
|
36
|
+
## Contents
|
|
37
|
+
|
|
38
|
+
- [Start here](getting-started.md) - The first safe result.
|
|
39
|
+
|
|
40
|
+
### Contributor guides
|
|
41
|
+
|
|
42
|
+
- [Toolchain](contributing/index.md) - Local setup and authoring.
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`documentation.navOwner: nav-sync` means nav sync owns derived navigation. With `hand-authored` or undeclared ownership, do not silently regenerate; agree the ownership/change first. Configured `documentation.nonReaderPaths` omits drafts/templates from navigation and manifests; an explicit Contents link does not override an exclusion. `documentation.excludes` affects only the manifest. Do not add an exclusion to hide an unlisted reader page.
|
|
46
|
+
|
|
47
|
+
## Add, move or rename a page
|
|
48
|
+
|
|
49
|
+
1. Read the nearest authored map and choose a path in its scope; create a child `index.md` when adding a directory.
|
|
50
|
+
2. Add useful title/description frontmatter, one H1, and the page's reader outcome. Use `.md`-suffixed source links such as `[Guide](guide.md)` and `[Section](section/index.md)`.
|
|
51
|
+
3. Update the nearest Contents map. For a move/rename, update both source and destination maps and every inbound link in the same change. Review old published URLs; agree a redirect or a static stub/recovery page when needed.
|
|
52
|
+
4. Refresh owned navigation, run the checks below and inspect the rendered links/navigation before committing. Never repair drift by hand-editing derived files.
|
|
53
|
+
|
|
54
|
+
## Supported Markdown features
|
|
11
55
|
|
|
12
|
-
|
|
56
|
+
Use the least complex layer that expresses the reader's need: **Markdown → existing transform → MDX**. Ordinary prose stays `.md`. Fumadocs MDX is for actual JSX/component needs; MkDocs does not compile MDX. MDX is excluded from OAT's Markdown manifest and the Fumadocs agent Markdown endpoints.
|
|
13
57
|
|
|
14
|
-
|
|
58
|
+
Tables, task lists, fenced code, callouts, Mermaid and `=== "Title"` tabs are supported by the configured framework pipeline. Tabs may contain links, GFM and nested tabs in Fumadocs. Use a language on every fence and `bash` for shell commands.
|
|
15
59
|
|
|
16
|
-
|
|
17
|
-
pnpm docs:setup
|
|
18
|
-
```
|
|
60
|
+
=== "Syntax"
|
|
19
61
|
|
|
20
|
-
|
|
62
|
+
````text
|
|
63
|
+
=== "Example"
|
|
21
64
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
```
|
|
65
|
+
> [!NOTE]
|
|
66
|
+
> Read the local map before editing.
|
|
25
67
|
|
|
26
|
-
|
|
68
|
+
| Check | Result |
|
|
69
|
+
| --- | --- |
|
|
70
|
+
| Reader links | Resolve |
|
|
71
|
+
|
|
72
|
+
```bash
|
|
73
|
+
cd {{APP_CWD}}
|
|
74
|
+
pnpm docs:lint
|
|
75
|
+
```
|
|
76
|
+
````
|
|
77
|
+
|
|
78
|
+
=== "Rendered"
|
|
79
|
+
|
|
80
|
+
=== "Example"
|
|
81
|
+
|
|
82
|
+
> [!NOTE]
|
|
83
|
+
> Read the local map before editing.
|
|
84
|
+
|
|
85
|
+
| Check | Result |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| Reader links | Resolve |
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
cd {{APP_CWD}}
|
|
91
|
+
pnpm docs:lint
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Not configured: arbitrary custom components, executable notebooks, API playgrounds or screenshot testing. Do not describe those as supported without an approved configuration and a working example. Check the actual package scripts: lint is {{LINT_STATUS}} and formatting is {{FORMAT_STATUS}}; disabled scripts only print a message.
|
|
95
|
+
|
|
96
|
+
## Diagrams and accessibility
|
|
97
|
+
|
|
98
|
+
Run the app’s docs:check script (from the repository root: `cd {{APP_CWD}} && pnpm docs:check`) before committing. It checks reader metadata/maps/links, navigation, contributor commands and real Mermaid syntax without building the site. Errors fail; warnings prompt review. Fix authored sources, then explicitly sync owned navigation and retry.
|
|
99
|
+
|
|
100
|
+
Mermaid is the diagram source of truth. Important or phone-sized diagrams also get matching `<name>-light.svg` and `<name>-dark.svg` assets. Change the Mermaid and both SVGs in the same commit, preserving nodes, edges and labels. Each SVG uses `role="img"`, a descriptive `<title>` and `<desc>` (connected with `aria-labelledby`), a legible viewBox and readable labels. Keep image alt text concise, about 155 characters or less, and describe the diagram's meaning without inventing claims.
|
|
101
|
+
|
|
102
|
+
=== "Syntax"
|
|
103
|
+
|
|
104
|
+
````text
|
|
105
|
+
=== "Mermaid source"
|
|
106
|
+
|
|
107
|
+
```mermaid
|
|
108
|
+
flowchart LR
|
|
109
|
+
A[Read local map] --> B[Make a focused edit]
|
|
110
|
+
```
|
|
111
|
+
````
|
|
112
|
+
|
|
113
|
+
=== "Rendered"
|
|
114
|
+
|
|
115
|
+
```mermaid
|
|
116
|
+
flowchart LR
|
|
117
|
+
accTitle: Documentation edit
|
|
118
|
+
accDescr: Read the local map before making a focused edit.
|
|
119
|
+
A[Read local map] --> B[Make a focused edit]
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
Put diagram assets under `docs/assets/diagrams/` and link relative to the source page. Keep both SVG variants with the source; automatic light/dark image selection is not configured in this MkDocs scaffold. Inspect theme contrast manually; do not claim the Fumadocs image/basePath behavior here.
|
|
27
123
|
|
|
28
124
|
## Installed plugins
|
|
29
125
|
|
|
@@ -112,9 +208,3 @@ Supports tabbed content blocks for related workflows or platform variants.
|
|
|
112
208
|
### `toc`
|
|
113
209
|
|
|
114
210
|
Adds table-of-contents anchors and permalinks for headings.
|
|
115
|
-
|
|
116
|
-
## Agent guidance
|
|
117
|
-
|
|
118
|
-
- Treat `index.md` plus its `## Contents` section as the local discovery source of truth.
|
|
119
|
-
- Prefer linking to source files and commands explicitly when documenting behavior.
|
|
120
|
-
- When adding a new plugin or extension, update this guide with what it does and how to use it.
|
|
@@ -1,28 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
## Prerequisites
|
|
6
|
-
|
|
7
|
-
- Node.js 22+
|
|
8
|
-
- pnpm 10+
|
|
9
|
-
- Python 3.11+ for MkDocs tooling
|
|
1
|
+
---
|
|
2
|
+
title: Getting Started
|
|
3
|
+
description: 'Reach the first safe reader result with {{SITE_NAME}}.'
|
|
4
|
+
---
|
|
10
5
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
pnpm docs:setup
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Run the docs locally
|
|
18
|
-
|
|
19
|
-
```bash
|
|
20
|
-
pnpm docs:dev
|
|
21
|
-
```
|
|
6
|
+
# Getting Started
|
|
22
7
|
|
|
23
|
-
|
|
8
|
+
Start with the [documentation map](index.md), choose the guide for your task, and confirm its prerequisites before changing anything. Your first safe result is to identify the right procedure and its expected outcome.
|
|
24
9
|
|
|
25
|
-
|
|
26
|
-
2. Check the preview site for formatting and navigation.
|
|
27
|
-
3. Run the formatter and linter before committing.
|
|
28
|
-
4. Keep every directory discoverable through its `index.md` file.
|
|
10
|
+
Replace this starter paragraph with one concrete, low-risk reader task for your product: the input, the command or action, and the result the reader can verify. Keep contributor setup in the [docs toolchain guide](contributing/docs-toolchain.md).
|
|
@@ -1,8 +1,13 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: '{{SITE_NAME}}'
|
|
3
|
+
description: '{{PAGE_DESCRIPTION}}'
|
|
4
|
+
---
|
|
5
|
+
|
|
1
6
|
# {{SITE_NAME}}
|
|
2
7
|
|
|
3
8
|
Use this site as the central documentation hub for the repository. It is organized to support both human readers and AI agents, with every directory exposing an `index.md` entrypoint.
|
|
4
9
|
|
|
5
10
|
## Contents
|
|
6
11
|
|
|
7
|
-
- [Getting Started](getting-started.md) -
|
|
8
|
-
- [Contributing](contributing.md) - Authoring
|
|
12
|
+
- [Getting Started](getting-started.md) - Reach the first safe reader result.
|
|
13
|
+
- [Contributing](contributing/index.md) - Authoring contract and local toolchain setup.
|
|
@@ -6,12 +6,13 @@
|
|
|
6
6
|
"description": "MkDocs Material documentation for {{SITE_NAME}}.",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"docs:dev": "mkdocs serve",
|
|
9
|
-
"docs:build": "{{NAV_SYNC_CHECK_CMD}} && mkdocs build",
|
|
9
|
+
"docs:build": "{{DOCS_CHECK_CMD}} && {{NAV_SYNC_CHECK_CMD}} && mkdocs build",
|
|
10
10
|
"docs:setup": "sh ./setup-docs.sh",
|
|
11
|
+
"docs:check": "{{DOCS_CHECK_CMD}}",
|
|
11
12
|
"docs:lint": "{{DOCS_LINT_SCRIPT}}",
|
|
12
13
|
"docs:format": "{{DOCS_FORMAT_SCRIPT}}",
|
|
13
14
|
"docs:format:check": "{{DOCS_FORMAT_CHECK_SCRIPT}}",
|
|
14
|
-
"test": "
|
|
15
|
+
"test": "{{DOCS_CHECK_CMD}}"
|
|
15
16
|
},
|
|
16
17
|
"devDependencies": {
|
|
17
18
|
"@open-agent-toolkit/cli": "{{OAT_CLI_DEP}}"{{DEV_DEPENDENCIES}}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,mBAAmB,EAAE,KAAK,cAAc,EAAE,MAAM,sBAAsB,CAAC;AAIhF,OAAO,EAEL,KAAK,aAAa,EACnB,MAAM,iCAAiC,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/commands/config/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -11,6 +11,7 @@ import { compileDispatchCeilingPreset } from '../../config/dispatch-ceiling-pres
|
|
|
11
11
|
import { normalizeDispatchMatrix, validateDispatchRouteTarget, walkDispatchMatrix, } from '../../config/dispatch-matrix.js';
|
|
12
12
|
import { formatDispatchNotices, terminalReviewerNoticesForMatrix, } from '../../config/dispatch-notices.js';
|
|
13
13
|
import { dispatchPolicyModeDescription, dispatchPolicyPolicyDescription, managedDispatchPolicyValueList, } from '../../config/dispatch-policy-options.js';
|
|
14
|
+
import { normalizeDocumentationCheck } from '../../config/documentation-check.js';
|
|
14
15
|
import { parseJsonConfig } from '../../config/json.js';
|
|
15
16
|
import { DEFAULT_INSTRUCTION_SYNC_STRATEGY, INSTRUCTION_SYNC_STRATEGIES, VALID_DISPATCH_POLICY_MODES, VALID_MANAGED_DISPATCH_POLICIES, MAX_GATE_TIMEOUT_MS, MIN_GATE_TIMEOUT_MS, isValidGateTimeoutMs, isValidProjectLogDigestBound, normalizeWorkflowPostImplementSequence, normalizeDocumentationGuidance, normalizeDocumentationIa, normalizeDocumentationNavOwner, readOatConfig, readOatConfigForDefaultScopeRepair, readOatConfigForDocumentationExcludesRepair, readOatConfigForInstructionPointerExcludesRepair, readOatConfigForInstructionSyncStrategyRepair, readOatConfigWithWarnings, readOatLocalConfig, readUserConfig, writeOatConfig, writeOatLocalConfig, writeUserConfig, VALID_POST_IMPLEMENT_LEGACY_SEQUENCES, } from '../../config/oat-config.js';
|
|
16
17
|
import { getOwnKey, setOwnKey } from '../../config/own-keys.js';
|
|
@@ -67,6 +68,7 @@ const KEY_ORDER = [
|
|
|
67
68
|
'archive.awsRegion',
|
|
68
69
|
'autoReviewAtCheckpoints',
|
|
69
70
|
'lastPausedProject',
|
|
71
|
+
'documentation.check',
|
|
70
72
|
'documentation.ia',
|
|
71
73
|
'documentation.nonReaderPaths',
|
|
72
74
|
'documentation.navOwner',
|
|
@@ -242,6 +244,17 @@ const CONFIG_CATALOG = [
|
|
|
242
244
|
description: 'Deprecated compatibility alias for workflow.autoReviewAtHillCheckpoints. Prefer `oat config set workflow.autoReviewAtHillCheckpoints <true|false>`.',
|
|
243
245
|
deprecated: { supersededBy: 'workflow.autoReviewAtHillCheckpoints' },
|
|
244
246
|
},
|
|
247
|
+
{
|
|
248
|
+
key: 'documentation.check',
|
|
249
|
+
group: 'Shared Repo (.oat/config.json)',
|
|
250
|
+
scope: 'shared repo',
|
|
251
|
+
file: '.oat/config.json',
|
|
252
|
+
type: 'JSON object',
|
|
253
|
+
defaultValue: 'null (portable checker defaults)',
|
|
254
|
+
mutability: 'read/write',
|
|
255
|
+
owningCommand: 'oat config set documentation.check <JSON>',
|
|
256
|
+
description: 'Portable docs rule severities, named thresholds, reason-bearing path exceptions, provenance patterns and diagram base ref.',
|
|
257
|
+
},
|
|
245
258
|
{
|
|
246
259
|
key: 'documentation.ia',
|
|
247
260
|
group: 'Shared Repo (.oat/config.json)',
|
|
@@ -1822,6 +1835,7 @@ async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, d
|
|
|
1822
1835
|
const effectiveSurface = surface === 'auto' ? defaultSurfaceForKey(key) : surface;
|
|
1823
1836
|
if (key === 'documentation.nonReaderPaths' ||
|
|
1824
1837
|
key === 'documentation.guidance' ||
|
|
1838
|
+
key === 'documentation.check' ||
|
|
1825
1839
|
key === 'documentation.ia' ||
|
|
1826
1840
|
key === 'documentation.navOwner') {
|
|
1827
1841
|
const configPath = effectiveSurface === 'user'
|
|
@@ -1831,7 +1845,13 @@ async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, d
|
|
|
1831
1845
|
const trimmed = rawValue.trim();
|
|
1832
1846
|
let value;
|
|
1833
1847
|
try {
|
|
1834
|
-
if (key === 'documentation.
|
|
1848
|
+
if (key === 'documentation.check') {
|
|
1849
|
+
const parsed = JSON.parse(trimmed);
|
|
1850
|
+
if (parsed === null)
|
|
1851
|
+
throw new Error('Expected a checker JSON object.');
|
|
1852
|
+
value = normalizeDocumentationCheck(parsed);
|
|
1853
|
+
}
|
|
1854
|
+
else if (key === 'documentation.nonReaderPaths') {
|
|
1835
1855
|
const paths = parseDocumentationExcludes(rawValue);
|
|
1836
1856
|
value = paths.length > 0 ? paths : undefined;
|
|
1837
1857
|
}
|
|
@@ -1848,8 +1868,10 @@ async function setConfigValue(repoRoot, userConfigDir, key, rawValue, surface, d
|
|
|
1848
1868
|
: normalizeDocumentationGuidance(trimmed.startsWith('[') ? JSON.parse(trimmed) : trimmed, configPath, effectiveSurface === 'user' ? 'user' : 'shared');
|
|
1849
1869
|
}
|
|
1850
1870
|
}
|
|
1851
|
-
catch {
|
|
1852
|
-
|
|
1871
|
+
catch (error) {
|
|
1872
|
+
if (key === 'documentation.check')
|
|
1873
|
+
throw error;
|
|
1874
|
+
throw new Error(`Invalid ${key} value: ${key === 'documentation.ia' ? 'expected IA JSON with preset, repo-relative decision, optional tracks and verification' : key === 'documentation.navOwner' ? 'expected nav-sync or hand-authored' : 'expected a non-empty path/URL string or ordered non-empty string array'}.`, { cause: error });
|
|
1853
1875
|
}
|
|
1854
1876
|
let raw = { version: 1 };
|
|
1855
1877
|
try {
|
|
@@ -2450,6 +2472,7 @@ async function unsetConfigValue(repoRoot, userConfigDir, key, surface, dependenc
|
|
|
2450
2472
|
async function removeFromSurface(repoRoot, userConfigDir, key, effectiveSurface, path, dependencies) {
|
|
2451
2473
|
if (key === 'documentation.nonReaderPaths' ||
|
|
2452
2474
|
key === 'documentation.guidance' ||
|
|
2475
|
+
key === 'documentation.check' ||
|
|
2453
2476
|
key === 'documentation.ia' ||
|
|
2454
2477
|
key === 'documentation.navOwner') {
|
|
2455
2478
|
const configPath = effectiveSurface === 'user'
|
|
@@ -2577,6 +2600,15 @@ async function removeConfigPathOnDisk(configPath, path) {
|
|
|
2577
2600
|
if (!isRecord(parsed)) {
|
|
2578
2601
|
return null;
|
|
2579
2602
|
}
|
|
2603
|
+
// Checker null is malformed rather than an inherited unset sentinel.
|
|
2604
|
+
if (path.join('.') === 'documentation.check' &&
|
|
2605
|
+
isRecord(parsed.documentation) &&
|
|
2606
|
+
Object.hasOwn(parsed.documentation, 'check')) {
|
|
2607
|
+
return {
|
|
2608
|
+
...parsed,
|
|
2609
|
+
documentation: withoutOwnKey(parsed.documentation, 'check'),
|
|
2610
|
+
};
|
|
2611
|
+
}
|
|
2580
2612
|
const { next, removed } = removeConfigPath(parsed, path);
|
|
2581
2613
|
return removed ? next : null;
|
|
2582
2614
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/check/check.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAKpC,wBAAgB,sBAAsB,IAAI,OAAO,CA4DhD"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { buildCommandContext } from '../../../app/command-context.js';
|
|
2
|
+
import { readGlobalOptions } from '../../shared/shared.utils.js';
|
|
3
|
+
import { Command } from 'commander';
|
|
4
|
+
import { checkDocs } from './checker.js';
|
|
5
|
+
export function createDocsCheckCommand() {
|
|
6
|
+
return new Command('check')
|
|
7
|
+
.description('Read-only portable reader, navigation, command and diagram validation')
|
|
8
|
+
.option('--target-dir <dir>', 'Docs app root or literal Markdown content root')
|
|
9
|
+
.option('--rule <id...>', 'Run only these stable rule IDs (repeatable)', (values, previous) => previous.concat(values), [])
|
|
10
|
+
.action(async (options, command) => {
|
|
11
|
+
const context = buildCommandContext(readGlobalOptions(command));
|
|
12
|
+
let result;
|
|
13
|
+
try {
|
|
14
|
+
result = await checkDocs({
|
|
15
|
+
cwd: context.cwd,
|
|
16
|
+
targetDir: options.targetDir,
|
|
17
|
+
rules: options.rule,
|
|
18
|
+
});
|
|
19
|
+
process.exitCode = result.summary.errors ? 1 : 0;
|
|
20
|
+
}
|
|
21
|
+
catch (error) {
|
|
22
|
+
const message = error.message;
|
|
23
|
+
result = {
|
|
24
|
+
summary: { errors: 1, warnings: 0 },
|
|
25
|
+
findings: [
|
|
26
|
+
{
|
|
27
|
+
ruleId: 'configuration',
|
|
28
|
+
severity: 'error',
|
|
29
|
+
path: '.oat/config.json',
|
|
30
|
+
message,
|
|
31
|
+
},
|
|
32
|
+
],
|
|
33
|
+
};
|
|
34
|
+
// Invalid input/config is actionable. Unexpected filesystem/runtime
|
|
35
|
+
// failures retain the CLI's separate runtime-error exit convention.
|
|
36
|
+
process.exitCode = error.code ? 2 : 1;
|
|
37
|
+
}
|
|
38
|
+
if (context.json)
|
|
39
|
+
context.logger.json(result);
|
|
40
|
+
else {
|
|
41
|
+
for (const f of result.findings) {
|
|
42
|
+
const location = `${f.path}${f.line === undefined ? '' : `:${f.line}`}`;
|
|
43
|
+
context.logger[f.severity === 'error' ? 'error' : 'warn'](`${location} [${f.ruleId}] ${f.message}`);
|
|
44
|
+
}
|
|
45
|
+
context.logger.info(`Docs check: ${result.summary.errors} error(s), ${result.summary.warnings} warning(s).`);
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { DocsCheckRule } from '../../../config/documentation-check.js';
|
|
2
|
+
export interface DocsFinding {
|
|
3
|
+
ruleId: DocsCheckRule | 'configuration';
|
|
4
|
+
severity: 'error' | 'warn';
|
|
5
|
+
path: string;
|
|
6
|
+
line?: number;
|
|
7
|
+
message: string;
|
|
8
|
+
}
|
|
9
|
+
export interface DocsCheckResult {
|
|
10
|
+
summary: {
|
|
11
|
+
errors: number;
|
|
12
|
+
warnings: number;
|
|
13
|
+
};
|
|
14
|
+
findings: DocsFinding[];
|
|
15
|
+
}
|
|
16
|
+
export type Report = (rule: DocsCheckRule, severity: 'error' | 'warn', path: string, message: string, line?: number) => void;
|
|
17
|
+
//# sourceMappingURL=check.types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"check.types.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/check/check.types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AACjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,aAAa,GAAG,eAAe,CAAC;IACxC,QAAQ,EAAE,OAAO,GAAG,MAAM,CAAC;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAC9C,QAAQ,EAAE,WAAW,EAAE,CAAC;CACzB;AACD,MAAM,MAAM,MAAM,GAAG,CACnB,IAAI,EAAE,aAAa,EACnB,QAAQ,EAAE,OAAO,GAAG,MAAM,EAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,IAAI,CAAC,EAAE,MAAM,KACV,IAAI,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { DocsCheckResult } from './check.types.js';
|
|
2
|
+
/** Read-only portable checker. Output paths are content-root-relative POSIX. */
|
|
3
|
+
export declare function checkDocs(options: {
|
|
4
|
+
cwd: string;
|
|
5
|
+
targetDir?: string;
|
|
6
|
+
rules?: string[];
|
|
7
|
+
}): Promise<DocsCheckResult>;
|
|
8
|
+
//# sourceMappingURL=checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checker.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/check/checker.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,eAAe,EAAuB,MAAM,eAAe,CAAC;AAQ1E,gFAAgF;AAChF,wBAAsB,SAAS,CAAC,OAAO,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,GAAG,OAAO,CAAC,eAAe,CAAC,CAwF3B"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { createExclusionMatcher, isExcludedPath, } from '../../docs/shared/exclusions.js';
|
|
2
|
+
import { DOCS_CHECK_RULES, } from '../../../config/documentation-check.js';
|
|
3
|
+
import { checkCommands } from './commands.js';
|
|
4
|
+
import { checkDiagrams } from './diagrams.js';
|
|
5
|
+
import { readPage, readerFiles, resolveCheckTarget } from './files.js';
|
|
6
|
+
import { checkNavigation } from './navigation.js';
|
|
7
|
+
import { checkProvenance, checkReaders } from './reader-rules.js';
|
|
8
|
+
/** Read-only portable checker. Output paths are content-root-relative POSIX. */
|
|
9
|
+
export async function checkDocs(options) {
|
|
10
|
+
const unknown = options.rules?.find((rule) => !DOCS_CHECK_RULES.includes(rule));
|
|
11
|
+
if (unknown)
|
|
12
|
+
throw new Error(`Unknown docs check rule "${unknown}". Choose: ${DOCS_CHECK_RULES.join(', ')}.`);
|
|
13
|
+
const target = await resolveCheckTarget(options.cwd, options.targetDir);
|
|
14
|
+
const policy = target.documentation.check;
|
|
15
|
+
const findings = [];
|
|
16
|
+
const exceptions = policy?.exceptions?.map((e) => ({
|
|
17
|
+
...e,
|
|
18
|
+
matcher: createExclusionMatcher([e.path]),
|
|
19
|
+
})) ?? [];
|
|
20
|
+
const report = (ruleId, defaultSeverity, path, message, line) => {
|
|
21
|
+
if (options.rules?.length && !options.rules.includes(ruleId))
|
|
22
|
+
return;
|
|
23
|
+
let severity = policy?.rules?.[ruleId] ?? defaultSeverity;
|
|
24
|
+
for (const e of exceptions)
|
|
25
|
+
if (e.rule === ruleId && isExcludedPath(e.matcher, path))
|
|
26
|
+
severity = e.severity ?? 'off';
|
|
27
|
+
if (severity === 'off')
|
|
28
|
+
return;
|
|
29
|
+
findings.push({
|
|
30
|
+
ruleId,
|
|
31
|
+
severity,
|
|
32
|
+
path,
|
|
33
|
+
...(line === undefined ? {} : { line }),
|
|
34
|
+
message,
|
|
35
|
+
});
|
|
36
|
+
};
|
|
37
|
+
const pages = [];
|
|
38
|
+
for (const path of await readerFiles(target)) {
|
|
39
|
+
try {
|
|
40
|
+
const page = await readPage(target, path);
|
|
41
|
+
pages.push(page);
|
|
42
|
+
if (page.frontmatterError)
|
|
43
|
+
report('frontmatter', 'error', path, page.frontmatterError, 1);
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
const code = error?.code;
|
|
47
|
+
const safeCode = typeof code === 'string' && /^[A-Z][A-Z0-9_]*$/.test(code)
|
|
48
|
+
? code
|
|
49
|
+
: 'UNKNOWN';
|
|
50
|
+
report('frontmatter', 'error', path, `Cannot read documentation source (${safeCode}); check file permissions and readability.`, 1);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
await checkReaders(target, pages, report);
|
|
54
|
+
checkProvenance(target, pages, report);
|
|
55
|
+
if (!options.rules?.length || options.rules.includes('navigation'))
|
|
56
|
+
await checkNavigation(target, report);
|
|
57
|
+
if (!options.rules?.length || options.rules.includes('commands'))
|
|
58
|
+
await checkCommands(target, pages, report);
|
|
59
|
+
if (!options.rules?.length ||
|
|
60
|
+
options.rules.some((r) => [
|
|
61
|
+
'mermaid',
|
|
62
|
+
'diagram-accessibility',
|
|
63
|
+
'diagram-pairs',
|
|
64
|
+
'diagram-freshness',
|
|
65
|
+
'image-alt',
|
|
66
|
+
].includes(r)))
|
|
67
|
+
await checkDiagrams(target, pages, report);
|
|
68
|
+
findings.sort((a, b) => a.path < b.path
|
|
69
|
+
? -1
|
|
70
|
+
: a.path > b.path
|
|
71
|
+
? 1
|
|
72
|
+
: (a.line ?? 0) - (b.line ?? 0) ||
|
|
73
|
+
a.ruleId.localeCompare(b.ruleId) ||
|
|
74
|
+
a.message.localeCompare(b.message));
|
|
75
|
+
return {
|
|
76
|
+
summary: {
|
|
77
|
+
errors: findings.filter((f) => f.severity === 'error').length,
|
|
78
|
+
warnings: findings.filter((f) => f.severity === 'warn').length,
|
|
79
|
+
},
|
|
80
|
+
findings,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { Report } from './check.types.js';
|
|
2
|
+
import { type CheckTarget } from './files.js';
|
|
3
|
+
import type { ParsedPage } from './markdown.js';
|
|
4
|
+
export declare function checkCommands(target: CheckTarget, pages: ParsedPage[], report: Report): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=commands.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../../../src/commands/docs/check/commands.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAA0B,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAgI7C,wBAAsB,aAAa,CACjC,MAAM,EAAE,WAAW,EACnB,KAAK,EAAE,UAAU,EAAE,EACnB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAyJf"}
|