@open-agent-toolkit/cli 0.3.23 → 0.3.25
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/workflows.md +90 -11
- package/assets/docs/reference/cli-reference.md +1 -1
- package/assets/docs/reference/configuration.md +6 -2
- package/assets/public-package-versions.json +4 -4
- package/assets/skills/authoring-docs/SKILL.md +18 -8
- package/assets/skills/authoring-docs/references/guidance-sources.md +95 -0
- package/assets/skills/authoring-docs/references/information-architecture.md +121 -86
- package/assets/skills/authoring-docs/references/page-types.md +35 -7
- package/assets/skills/authoring-docs/references/review-rubric.md +12 -12
- package/assets/skills/authoring-docs/references/templates.md +54 -0
- package/assets/skills/authoring-docs/references/workflow.md +6 -1
- package/assets/skills/authoring-docs/references/writing-style.md +1 -1
- package/assets/skills/authoring-docs/scripts/resolve-guidance.mjs +53 -0
- package/assets/skills/oat-docs-analyze/SKILL.md +140 -7
- package/assets/skills/oat-docs-analyze/references/analysis-artifact-template.md +54 -2
- package/assets/skills/oat-docs-analyze/scripts/package-drift.mjs +129 -0
- package/assets/skills/oat-docs-apply/SKILL.md +148 -11
- package/assets/skills/oat-docs-apply/references/apply-plan-template.md +67 -14
- package/assets/skills/oat-docs-authoring/SKILL.md +20 -8
- package/assets/skills/oat-docs-bootstrap/SKILL.md +74 -15
- package/dist/commands/config/index.d.ts.map +1 -1
- package/dist/commands/config/index.js +118 -1
- package/dist/config/oat-config.d.ts +21 -0
- package/dist/config/oat-config.d.ts.map +1 -1
- package/dist/config/oat-config.js +96 -4
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +5 -1
- package/package.json +2 -2
|
@@ -98,6 +98,30 @@ Rules:
|
|
|
98
98
|
- Include verification, rollback, and escalation.
|
|
99
99
|
- Avoid long historical background before recovery steps.
|
|
100
100
|
|
|
101
|
+
## Feature Guide
|
|
102
|
+
|
|
103
|
+
Describe intended user behavior, the problem solved, prerequisites, boundaries
|
|
104
|
+
and linked Engineering/QA counterparts when the IA declares them. Distinguish
|
|
105
|
+
concept names from verified literal screen text; do not infer behavior from a UI.
|
|
106
|
+
|
|
107
|
+
## Validation Matrix
|
|
108
|
+
|
|
109
|
+
Specify scenarios, preconditions, actions and expected outcomes independently
|
|
110
|
+
of implementation details. Link the canonical feature and only cite test IDs
|
|
111
|
+
that exist. Keep duplicate or contradictory scenarios out of the matrix.
|
|
112
|
+
|
|
113
|
+
## Solution
|
|
114
|
+
|
|
115
|
+
Explain how supported capabilities combine to solve one end-to-end problem.
|
|
116
|
+
State constraints, tradeoffs, integration steps and verification; link exact
|
|
117
|
+
contracts rather than duplicating reference facts.
|
|
118
|
+
|
|
119
|
+
## Decision Record
|
|
120
|
+
|
|
121
|
+
Record an accepted choice with context, alternatives, reasoning, consequences
|
|
122
|
+
and status. Link the authoritative decision surface when it lives elsewhere;
|
|
123
|
+
keep planning and execution evidence out of reader docs.
|
|
124
|
+
|
|
101
125
|
## Mixed Pages
|
|
102
126
|
|
|
103
127
|
Some pages legitimately mix types. A landing page can include orientation,
|
|
@@ -110,10 +134,14 @@ and keep everything else subordinate.
|
|
|
110
134
|
|
|
111
135
|
## Smell Test
|
|
112
136
|
|
|
113
|
-
| If the Reader Asks
|
|
114
|
-
|
|
|
115
|
-
| I am new. Walk me through this.
|
|
116
|
-
| How do I do X?
|
|
117
|
-
| What does this option mean?
|
|
118
|
-
| Why does this behave this way?
|
|
119
|
-
| Production is broken. What now?
|
|
137
|
+
| If the Reader Asks | They Need | Do Not Give Them |
|
|
138
|
+
| ------------------------------------------- | ----------------- | ---------------------------- |
|
|
139
|
+
| I am new. Walk me through this. | Tutorial | Full API reference |
|
|
140
|
+
| How do I do X? | How-to guide | Architecture essay |
|
|
141
|
+
| What does this option mean? | Reference | A blog post |
|
|
142
|
+
| Why does this behave this way? | Explanation | A command list |
|
|
143
|
+
| Production is broken. What now? | Runbook | Historical background first |
|
|
144
|
+
| What behavior should this feature provide? | Feature guide | Implementation internals |
|
|
145
|
+
| How do I verify that behavior? | Validation matrix | Unverified test IDs |
|
|
146
|
+
| How do these capabilities solve my problem? | Solution | Disconnected reference dumps |
|
|
147
|
+
| Why was this choice accepted? | Decision record | A transient project plan |
|
|
@@ -53,18 +53,18 @@ Production runbooks should be especially strong on operational safety.
|
|
|
53
53
|
Public-facing docs should be especially strong on examples, accuracy, and
|
|
54
54
|
audience boundary.
|
|
55
55
|
|
|
56
|
-
| Area | 0 | 1 | 2 | 3
|
|
57
|
-
| ------------------------ | --------------------------- | ---------------------- | --------------------------- |
|
|
58
|
-
| Purpose | No clear reason page exists | Purpose is implied | Purpose is stated | Purpose, reader, and outcome are clear
|
|
59
|
-
| Accuracy | Incorrect or invented | Partially accurate | Mostly accurate | Grounded and verified
|
|
60
|
-
| Structure | Hard to scan | Some headings | Clear sections |
|
|
61
|
-
| Task support | Cannot complete task | Can partially complete | Can complete with some gaps | Can complete safely with verification
|
|
62
|
-
| Reference quality | Missing facts | Facts scattered | Most fields documented | Types, defaults, constraints, examples, errors documented
|
|
63
|
-
| Operational safety | Risky or absent | Mentions risk | Includes basic verification | Includes verification, rollback, escalation, failure modes
|
|
64
|
-
| Agent usefulness | Ambiguous | Some exact data | Mostly explicit | Exact commands, paths, constraints, and uncertainty
|
|
65
|
-
| Maintainability | Duplicated or stale | Hard to update | Mostly maintainable | Clear source of truth and generated markers where needed
|
|
66
|
-
| Public/internal boundary | Leaks or omits key context | Boundary unclear | Mostly appropriate | Correct assumptions and safe content
|
|
67
|
-
| Links and navigation | Broken or absent | Sparse | Useful | Strong cross-links and clear next steps
|
|
56
|
+
| Area | 0 | 1 | 2 | 3 |
|
|
57
|
+
| ------------------------ | --------------------------- | ---------------------- | --------------------------- | ------------------------------------------------------------------------- |
|
|
58
|
+
| Purpose | No clear reason page exists | Purpose is implied | Purpose is stated | Purpose, reader, and outcome are clear |
|
|
59
|
+
| Accuracy | Incorrect or invented | Partially accurate | Mostly accurate | Grounded and verified |
|
|
60
|
+
| Structure | Hard to scan | Some headings | Clear sections | Reader-first [IA method](information-architecture.md) and strong headings |
|
|
61
|
+
| Task support | Cannot complete task | Can partially complete | Can complete with some gaps | Can complete safely with verification |
|
|
62
|
+
| Reference quality | Missing facts | Facts scattered | Most fields documented | Types, defaults, constraints, examples, errors documented |
|
|
63
|
+
| Operational safety | Risky or absent | Mentions risk | Includes basic verification | Includes verification, rollback, escalation, failure modes |
|
|
64
|
+
| Agent usefulness | Ambiguous | Some exact data | Mostly explicit | Exact commands, paths, constraints, and uncertainty |
|
|
65
|
+
| Maintainability | Duplicated or stale | Hard to update | Mostly maintainable | Clear source of truth and generated markers where needed |
|
|
66
|
+
| Public/internal boundary | Leaks or omits key context | Boundary unclear | Mostly appropriate | Correct assumptions and safe content |
|
|
67
|
+
| Links and navigation | Broken or absent | Sparse | Useful | Strong cross-links and clear next steps |
|
|
68
68
|
|
|
69
69
|
## Minimum Acceptable Scores
|
|
70
70
|
|
|
@@ -547,3 +547,57 @@ docs/
|
|
|
547
547
|
|
|
548
548
|
- <Explicitly out-of-scope docs>
|
|
549
549
|
```
|
|
550
|
+
|
|
551
|
+
## IA Proposal
|
|
552
|
+
|
|
553
|
+
Use for bootstrap or an existing-tree `--ia` analysis. This proposes structure;
|
|
554
|
+
it neither persists an IA decision nor materializes a preset. Feature and QA
|
|
555
|
+
validation page templates are not included; use the page-type guidance to
|
|
556
|
+
plan their content.
|
|
557
|
+
|
|
558
|
+
````markdown
|
|
559
|
+
# IA Proposal: {surface}
|
|
560
|
+
|
|
561
|
+
## Evidence and guidance
|
|
562
|
+
|
|
563
|
+
- Resolved sources, in order: {path/URL, provenance: explicit/conversation/shared/user/builtin}
|
|
564
|
+
- Local authority: {AGENTS/contributing paths and relevant rules}
|
|
565
|
+
- Repo signals: {manifests, navigators, bin, routers, IaC, e2e, docs, units}
|
|
566
|
+
- Readers and work contexts: {who must succeed at what}
|
|
567
|
+
- Entry key per track: {task/domain/capability/unit/command/page type}
|
|
568
|
+
- Page purposes: {one primary job per representative page}
|
|
569
|
+
- Verification overlay: {triad/agent-only/none and evidence}
|
|
570
|
+
- Size gate: {page count and amount of structure justified}
|
|
571
|
+
- Canonical facts elsewhere and links to preserve: {paths/URLs}
|
|
572
|
+
- Unresolved conflicts: {ask_user finding with source citations, or none}
|
|
573
|
+
|
|
574
|
+
## Candidate A: {reader-facing name}
|
|
575
|
+
|
|
576
|
+
Nearest preset: {approved label}. Choose when: {signals and tradeoffs}.
|
|
577
|
+
|
|
578
|
+
```text
|
|
579
|
+
{track-or-section}/
|
|
580
|
+
{page.md} — {page's one job}
|
|
581
|
+
{page.md} — {page's one job}
|
|
582
|
+
{track-or-section}/
|
|
583
|
+
{page.md} — {page's one job}
|
|
584
|
+
{page.md} — {page's one job}
|
|
585
|
+
{page.md} — {page's one job}
|
|
586
|
+
```
|
|
587
|
+
|
|
588
|
+
Use a two-level tree and 5–8 representative page placements. For Flat Small,
|
|
589
|
+
first-level labels are grouped headings in one index, not new directories.
|
|
590
|
+
|
|
591
|
+
## Candidate B: {alternative reader-facing name}
|
|
592
|
+
|
|
593
|
+
Nearest preset: {approved label}. Choose when: {different plausible signals}.
|
|
594
|
+
|
|
595
|
+
{Second two-level tree with 5–8 representative page placements and page jobs.}
|
|
596
|
+
|
|
597
|
+
## Recommendation and open decisions
|
|
598
|
+
|
|
599
|
+
{Preferred candidate, evidence and tradeoffs. Ask only decision-changing
|
|
600
|
+
questions. Record an explicit choice before replacement or a second app.
|
|
601
|
+
Existing docs default to analyze → apply of approved recommendations.
|
|
602
|
+
No private exemplar text, copied external contents or unapproved moves.}
|
|
603
|
+
````
|
|
@@ -80,7 +80,12 @@ Most docs serve one or more of these readers:
|
|
|
80
80
|
- support engineer
|
|
81
81
|
- AI agent making future changes
|
|
82
82
|
|
|
83
|
-
|
|
83
|
+
Map personas to tracks by work context: consumers and CLI/API users usually
|
|
84
|
+
enter through tasks or contracts; maintainers through domains and operations;
|
|
85
|
+
product stakeholders through behavior; independent QA through validation;
|
|
86
|
+
agents through exact task inputs and checks. One person may use several tracks.
|
|
87
|
+
Use the five axes in [Information Architecture](information-architecture.md)
|
|
88
|
+
before naming a preset. Write pages for actual tasks, not org-chart abstractions.
|
|
84
89
|
|
|
85
90
|
## 5. Decide the Minimum Useful Set
|
|
86
91
|
|
|
@@ -93,7 +93,7 @@ Use notes for useful context, not ordinary tips.
|
|
|
93
93
|
- Use one `#` heading per page.
|
|
94
94
|
- Do not skip heading levels.
|
|
95
95
|
- Use fenced code blocks with language identifiers.
|
|
96
|
-
- Use `
|
|
96
|
+
- Use `bash` for shell commands unless the example is POSIX-only (`sh`) or local repository conventions require another fence.
|
|
97
97
|
- Use `txt` for command output.
|
|
98
98
|
- Do not include shell prompts unless the prompt itself matters.
|
|
99
99
|
- Use angle brackets for placeholders, such as `<environment>`.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
2
|
+
import { parseArgs } from 'node:util';
|
|
3
|
+
|
|
4
|
+
// Select inputs only. The consuming skill reads Markdown and checks Contents,
|
|
5
|
+
// local authority and conflicts; this helper never fetches or writes a source.
|
|
6
|
+
const { values } = parseArgs({
|
|
7
|
+
options: {
|
|
8
|
+
builtin: { type: 'string' },
|
|
9
|
+
'ia-guidance': { type: 'string', multiple: true },
|
|
10
|
+
'conversation-guidance': { type: 'string', multiple: true },
|
|
11
|
+
},
|
|
12
|
+
});
|
|
13
|
+
const explicit = values['ia-guidance'];
|
|
14
|
+
const conversation = values['conversation-guidance'];
|
|
15
|
+
if (explicit && conversation) {
|
|
16
|
+
throw new Error(
|
|
17
|
+
'Use one explicit source list; reconcile argument/conversation disagreement with the user first.',
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
const input = JSON.parse(readFileSync(0, 'utf8'));
|
|
21
|
+
if (input.status !== 'ok' || input.key !== 'documentation.guidance') {
|
|
22
|
+
throw new Error(
|
|
23
|
+
'Expected successful oat config get documentation.guidance --json output.',
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
let locations;
|
|
27
|
+
let source;
|
|
28
|
+
if (explicit || conversation) {
|
|
29
|
+
locations = explicit ?? conversation;
|
|
30
|
+
source = explicit ? 'explicit' : 'conversation';
|
|
31
|
+
} else if (input.value !== null && input.value !== undefined) {
|
|
32
|
+
if (!['shared', 'user'].includes(input.source)) {
|
|
33
|
+
throw new Error(
|
|
34
|
+
`Unsupported documentation.guidance config source: ${input.source}`,
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
locations = Array.isArray(input.value) ? input.value : [input.value];
|
|
38
|
+
source = input.source;
|
|
39
|
+
} else {
|
|
40
|
+
locations = [values.builtin];
|
|
41
|
+
source = 'builtin';
|
|
42
|
+
}
|
|
43
|
+
if (
|
|
44
|
+
!locations.length ||
|
|
45
|
+
locations.some((location) => typeof location !== 'string' || !location.trim())
|
|
46
|
+
) {
|
|
47
|
+
throw new Error(
|
|
48
|
+
'Guidance requires non-empty path/URL strings (or --builtin for fallback).',
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
process.stdout.write(
|
|
52
|
+
`${JSON.stringify({ sources: locations.map((location) => ({ location: location.trim(), source })) }, null, 2)}\n`,
|
|
53
|
+
);
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
---
|
|
2
2
|
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
|
+
argument-hint: '[target] [--ia] [--ia-guidance <path|url>]'
|
|
4
5
|
disable-model-invocation: true
|
|
5
6
|
user-invocable: true
|
|
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
|
+
allowed-tools: Read, Write, Bash(git:*), Bash(oat config:*), Bash(oat docs nav sync --check:*), Bash(pnpm:*), Bash(bash:*), Bash(jq:*), Bash(node:*), Bash(mkdir:*), Bash(date:*), Bash(echo:*), Bash(cd:*), Bash(pwd:*), Glob, Grep, AskUserQuestion, Task
|
|
7
8
|
metadata:
|
|
8
|
-
version: '1.
|
|
9
|
+
version: '1.7.1'
|
|
9
10
|
---
|
|
10
11
|
|
|
11
12
|
# Docs Analysis
|
|
@@ -85,6 +86,39 @@ When executing this skill, provide lightweight progress feedback so the user can
|
|
|
85
86
|
|
|
86
87
|
## Process
|
|
87
88
|
|
|
89
|
+
### Shared authoring method and optional IA proposal
|
|
90
|
+
|
|
91
|
+
Independently probe each exact `authoring-docs/SKILL.md` in order:
|
|
92
|
+
`${SKILL_DIR}/..` from the loaded skill (`SKILL_DIR` is the absolute directory
|
|
93
|
+
containing that loaded `SKILL.md`), `${HOME}/.agents/skills`, then
|
|
94
|
+
`<repo-root>/.agents/skills`. Bind the first matching `authoring-docs` directory
|
|
95
|
+
once as `AUTHORING_DOCS_ROOT`; load `${AUTHORING_DOCS_ROOT}/SKILL.md` and use
|
|
96
|
+
that same root for every authoring-docs reference and script, never ambient
|
|
97
|
+
discovery. If none is found, name `authoring-docs`, stop this handoff, and give
|
|
98
|
+
the intended-scope recovery command: `oat tools install docs --scope <user|project>`
|
|
99
|
+
or `oat tools update --pack docs --scope <user|project>`.
|
|
100
|
+
|
|
101
|
+
Always use its landing-page contract, section entries and one-purpose-per-page
|
|
102
|
+
rule for the quality pass even without `--ia`. For IA work, read
|
|
103
|
+
`${AUTHORING_DOCS_ROOT}/references/guidance-sources.md` and use the source-aware config-get
|
|
104
|
+
interface/helper: explicit `--ia-guidance` or conversation → repo → user →
|
|
105
|
+
built-in. Preserve selected source order and cite locators/provenance in the
|
|
106
|
+
analysis artifact. External Markdown packs require `index.md` and `## Contents`;
|
|
107
|
+
non-repo inputs stay read-only and private contents never enter the artifact.
|
|
108
|
+
|
|
109
|
+
`--ia` is a skill argument, not a CLI docs command. It adds the shared IA Proposal
|
|
110
|
+
to the **same analysis artifact and existing artifact-review loop**. Read manifests,
|
|
111
|
+
UI navigators/journeys, CLI `bin`, routers, IaC, `e2e/`/`.maestro/`, existing docs
|
|
112
|
+
and independent monorepo units. Ask only decision-changing questions about reader
|
|
113
|
+
work contexts, independent verification, canonical facts and link survival.
|
|
114
|
+
Use the five axes before presets and show two plausible two-level trees with
|
|
115
|
+
5–8 representative page placements each, page jobs, nearest approved presets
|
|
116
|
+
and tradeoffs. A UI alone does not justify Product/Engineering/QA; size chooses
|
|
117
|
+
depth, not audience. For an existing tree respect AGENTS/contributing authority;
|
|
118
|
+
conflicts are `ask_user`, with both source citations. Analyze remains read-only:
|
|
119
|
+
propose `record-ia` or `restructure` recommendations for apply; never persist
|
|
120
|
+
IA or materialize scaffolds from analysis.
|
|
121
|
+
|
|
88
122
|
### Step 0: Resolve Docs Target and Analysis Mode
|
|
89
123
|
|
|
90
124
|
Determine the documentation root using explicit docs-app evidence before generic
|
|
@@ -267,8 +301,8 @@ For each evaluated page or directory:
|
|
|
267
301
|
syntax intentionally shown inside inline code, fenced examples, or template
|
|
268
302
|
snippets.
|
|
269
303
|
4. Check Markdown hygiene: opening code fences need language identifiers; shell
|
|
270
|
-
examples should follow local fence conventions, defaulting to `
|
|
271
|
-
|
|
304
|
+
examples should follow local fence conventions, defaulting to `bash` unless
|
|
305
|
+
the example is POSIX-only (`sh`) or local guidance requires another fence.
|
|
272
306
|
5. Flag empty headings, multiple document-level H1s outside intentional imported
|
|
273
307
|
README contexts, overlong frontmatter descriptions when local guidance
|
|
274
308
|
defines a limit, ellipsis-truncated descriptions, and README-copy metadata
|
|
@@ -284,6 +318,37 @@ For each evaluated page or directory:
|
|
|
284
318
|
In `delta` mode, always evaluate changed docs files plus the nearest parent `index.md` pages.
|
|
285
319
|
In `full` mode, evaluate the whole docs surface.
|
|
286
320
|
|
|
321
|
+
### Information Architecture Fit
|
|
322
|
+
|
|
323
|
+
Read the authored IA decision and `## Information architecture` section in the
|
|
324
|
+
docs-app AGENTS.md (Fumadocs/MkDocs) or contributing page (Markdown).
|
|
325
|
+
`documentation.ia` is a repository-only mirror: compare preset, decision path,
|
|
326
|
+
tracks/principles and verification overlay to those authored sources. The
|
|
327
|
+
authored record is authoritative; missing/broken records or contradictory
|
|
328
|
+
mirrors become `ask_user` findings. No recorded IA means `ask_user` to choose
|
|
329
|
+
and record one, not an inferred preset. Keep ordinary contract analysis useful
|
|
330
|
+
while those recommendations are blocked.
|
|
331
|
+
|
|
332
|
+
In the artifact's **Information Architecture Fit** section, cite whether the
|
|
333
|
+
landing page routes each declared audience, all declared sections exist and are
|
|
334
|
+
reachable, page reader/purpose matches placement, root breadth is usable, and an
|
|
335
|
+
app's docs avoid merely mirroring implementation directories. Review coverage
|
|
336
|
+
only for declared readers: Product features/journeys/screens/states; QA scenario
|
|
337
|
+
tables with seeds and automation references; consumer first-success/task guides;
|
|
338
|
+
agent entrypoints, canonical sources and verification commands. Do not demand
|
|
339
|
+
these tracks from every repository or implement the later P24 source checks.
|
|
340
|
+
|
|
341
|
+
Top-level IA misroutes a declared audience: `High` when the reader cannot find
|
|
342
|
+
a normal first-success or required verification path; `Medium` when that path
|
|
343
|
+
is reachable but its placement causes material detours/confusion. Cite the
|
|
344
|
+
declared audience, route and concrete reader impact. This rule overrides Low
|
|
345
|
+
organization polish; do not upgrade purely cosmetic differences.
|
|
346
|
+
|
|
347
|
+
For framework apps read `documentation.navOwner` independently of IA. Missing
|
|
348
|
+
means **undeclared**: issue `ask_user` to choose `nav-sync` or `hand-authored`,
|
|
349
|
+
and run only read-only membership/order comparisons. Never assume nav sync owns
|
|
350
|
+
existing navigation. Markdown ignores navOwner and never runs nav sync.
|
|
351
|
+
|
|
287
352
|
### Step 4: Verify Substantive Claims Against Repo Sources
|
|
288
353
|
|
|
289
354
|
Add a dedicated accuracy verification pass between page-quality assessment and nav/drift checks.
|
|
@@ -405,8 +470,8 @@ If a generated root index or manifest exists:
|
|
|
405
470
|
files, and representative links for each finding.
|
|
406
471
|
5. Prefer source-of-truth fixes over generated-file edits.
|
|
407
472
|
|
|
408
|
-
|
|
409
|
-
`docs/**/meta.json`
|
|
473
|
+
For a Fumadocs app with recorded `navOwner: nav-sync`, compare generated
|
|
474
|
+
`docs/**/meta.json` with authored `## Contents`:
|
|
410
475
|
|
|
411
476
|
1. Flag a docs directory with an `index.md` but no `meta.json` as a missing
|
|
412
477
|
generated artifact.
|
|
@@ -430,6 +495,13 @@ If the app is Fumadocs (a `source.config.ts` beside `docs/`), its sidebar comes
|
|
|
430
495
|
1 when either exists. The skill grants only this `--check` form; plain
|
|
431
496
|
`oat docs nav sync` writes files and is not part of analysis.
|
|
432
497
|
|
|
498
|
+
For `hand-authored` or undeclared Fumadocs navigation, compare current meta.json
|
|
499
|
+
membership/order with Contents without assuming strict generator output; do not
|
|
500
|
+
flag rest entries merely because they are hand-authored. Report missing reader
|
|
501
|
+
routes and differences with local ownership evidence; recommend no automatic
|
|
502
|
+
regeneration. For nav-sync-owned MkDocs, use the same explicit-target read-only
|
|
503
|
+
`oat docs nav sync --check --target-dir <docs-app-dir>`.
|
|
504
|
+
|
|
433
505
|
If `mkdocs.yml` exists:
|
|
434
506
|
|
|
435
507
|
1. Compare nav entries with the docs tree.
|
|
@@ -443,6 +515,53 @@ site nav generation or builds. Lack of `mkdocs.yml`, a generated manifest, or an
|
|
|
443
515
|
app package is expected, not a migration finding. For other unconfigured surfaces,
|
|
444
516
|
record whether app migration is relevant only when evidence or user intent supports it.
|
|
445
517
|
|
|
518
|
+
### Offline docs-package drift
|
|
519
|
+
|
|
520
|
+
For framework apps read their package.json and installed docs packages against
|
|
521
|
+
the running CLI's bundled `assets/public-package-versions.json`, without network.
|
|
522
|
+
Run this skill's production helper after resolving this skill's own directory:
|
|
523
|
+
|
|
524
|
+
```bash
|
|
525
|
+
node "$SKILL_DIR/scripts/package-drift.mjs" --app "<docs-app-dir>" --cli "$(command -v oat)"
|
|
526
|
+
```
|
|
527
|
+
|
|
528
|
+
If a package-manager wrapper prevents locating the CLI root, discover the bundle
|
|
529
|
+
from that invoked installation offline. Inspect `command -v oat` and, for a shell
|
|
530
|
+
shim, read its `exec` lines or `cmd-shim-target` comment (for example,
|
|
531
|
+
`sed -n '1,160p' "$(command -v oat)"`). Resolve a relative JavaScript target from
|
|
532
|
+
the shim's directory; do not evaluate copied shell text. Locate that target's
|
|
533
|
+
package root containing `package.json` named `@open-agent-toolkit/cli` and
|
|
534
|
+
`assets/public-package-versions.json`. `pnpm root -g` or `npm root -g` can help
|
|
535
|
+
locate it, but newer pnpm installations may nest it in a hashed directory; use
|
|
536
|
+
the actual shim target, never another checkout's bundle. Bind the inspected paths:
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
OAT_INSTALLED_ENTRY="<absolute JavaScript target from the invoked shim>"
|
|
540
|
+
OAT_INSTALLED_ROOT="<that installed @open-agent-toolkit/cli package root>"
|
|
541
|
+
# Both must equal the invoked oat version; stop if either differs.
|
|
542
|
+
test "$(node "$OAT_INSTALLED_ENTRY" --version)" = "$(oat --version)" &&
|
|
543
|
+
test "$(node -p 'JSON.parse(require("node:fs").readFileSync(process.argv[1], "utf8")).version' "$OAT_INSTALLED_ROOT/package.json")" = "$(oat --version)" &&
|
|
544
|
+
node "$SKILL_DIR/scripts/package-drift.mjs" --app "<docs-app-dir>" --versions "$OAT_INSTALLED_ROOT/assets/public-package-versions.json"
|
|
545
|
+
```
|
|
546
|
+
|
|
547
|
+
Never substitute registry latest or this target repo's package version. Missing
|
|
548
|
+
bundle metadata, missing installed packages, or non-orderable versions (including
|
|
549
|
+
prereleases) mean unverified, never an upgrade. The helper compares stable numeric
|
|
550
|
+
version components: older installed packages are `drift`; equal versions are
|
|
551
|
+
`current`; newer installed packages are `ahead`, with no upgrade command. For
|
|
552
|
+
`ahead`, report that the running CLI is stale and ask the operator to update or
|
|
553
|
+
select the intended CLI installation before re-analysis; do not recommend a docs
|
|
554
|
+
package downgrade. `unverified` also has no package command and needs manual
|
|
555
|
+
verification. Neither status authorizes a tooling update.
|
|
556
|
+
|
|
557
|
+
The helper reports declared and installed versions, target versions and commands
|
|
558
|
+
for orderable targets. If the app uses a different package manager, translate the
|
|
559
|
+
command to its documented equivalent preserving package, exact target and
|
|
560
|
+
dependency section. Cite the manifest, installed package path, bundle path and
|
|
561
|
+
exact command. Report older-package drift as `tooling-update`, `approval: explicit`;
|
|
562
|
+
describe unsupported scaffold repairs separately as `manual`. Markdown has no
|
|
563
|
+
app-package drift check. This helper reads only and never upgrades anything.
|
|
564
|
+
|
|
446
565
|
### Step 7: Severity-Rate Findings
|
|
447
566
|
|
|
448
567
|
Use these defaults:
|
|
@@ -452,6 +571,19 @@ Use these defaults:
|
|
|
452
571
|
- `Medium`: incomplete `## Contents`, `overview.md` still in use, plugin/contributor guidance gaps, moderate duplication
|
|
453
572
|
- `Low`: polish, wording, or organization improvements
|
|
454
573
|
|
|
574
|
+
### Recommendation handoff
|
|
575
|
+
|
|
576
|
+
Give every recommendation a unique stable ID (`R-001`, etc.) and
|
|
577
|
+
`approval: explicit | default`; preserve IDs through review and never reuse a
|
|
578
|
+
retired ID for a different change. `explicit` covers docs-package updates,
|
|
579
|
+
restructure blocks and anything outside the Markdown scope (including authored
|
|
580
|
+
IA decision/config writes). `default` covers ordinary in-scope content repairs.
|
|
581
|
+
Missing evidence, `omit` and `ask_user` remain independent blockers regardless
|
|
582
|
+
of approval class. Capture exact targets and commands; an explicit class is not
|
|
583
|
+
permission to perform unsupported work. Apply's one input is this artifact plus
|
|
584
|
+
a list of approved recommendation IDs. Blanket or unattended approval never
|
|
585
|
+
covers explicit recommendations; apply reports skipped IDs with reasons.
|
|
586
|
+
|
|
455
587
|
### Step 8: Write Analysis Artifact
|
|
456
588
|
|
|
457
589
|
Use `references/analysis-artifact-template.md`.
|
|
@@ -473,7 +605,8 @@ Populate the artifact with:
|
|
|
473
605
|
- Accuracy verification verdicts for repo-checkable claims
|
|
474
606
|
- Content opportunities for missing or thin docs coverage
|
|
475
607
|
- Navigation/drift findings
|
|
476
|
-
-
|
|
608
|
+
- Information Architecture Fit and offline package drift
|
|
609
|
+
- Ordered recommendations with stable IDs and approval classes
|
|
477
610
|
- Exact evidence references for each finding and recommendation
|
|
478
611
|
- Confidence for each recommendation
|
|
479
612
|
- Progressive disclosure decisions (`inline`, `link_only`, `omit`, `ask_user`)
|
|
@@ -15,6 +15,51 @@ oat_analysis_commit: { commitHash }
|
|
|
15
15
|
**Surface Type:** {mkdocs-app|oat-fumadocs-app|docs-tree|root-markdown}
|
|
16
16
|
**Commit:** {short-hash}
|
|
17
17
|
|
|
18
|
+
## IA guidance and proposal
|
|
19
|
+
|
|
20
|
+
- Selected sources in order: {locator + explicit/conversation/shared/user/builtin provenance}
|
|
21
|
+
- Resolved index entries: {entry paths/URLs; external Markdown has index.md + Contents}
|
|
22
|
+
- Local authority: {AGENTS/contributing source citations}
|
|
23
|
+
- Conflicts/unreadable sources: {ask_user with both citations, or none}
|
|
24
|
+
- IA proposal: {when --ia, embed the shared authoring-docs IA Proposal template:
|
|
25
|
+
two two-level trees, 5–8 placements each, page jobs, nearest approved presets,
|
|
26
|
+
evidence and tradeoffs; otherwise not requested}
|
|
27
|
+
|
|
28
|
+
Do not copy private guidance contents or persist an IA decision from this report.
|
|
29
|
+
|
|
30
|
+
## Information Architecture Fit
|
|
31
|
+
|
|
32
|
+
- Authored decision and Information architecture section: {paths/lines or missing}
|
|
33
|
+
- Config mirror: {preset, decision, tracks/principles, verification; agrees/conflicts}
|
|
34
|
+
- Missing IA / conflicting authority: {ask_user recommendation ID or none}
|
|
35
|
+
- Sidebar owner: {nav-sync / hand-authored / undeclared; Markdown: ignored}
|
|
36
|
+
- Undeclared framework owner: {ask_user recommendation ID or none}
|
|
37
|
+
|
|
38
|
+
| Declared reader/track | Landing route and section reachability | Placement/coverage evidence | Reader impact | Severity |
|
|
39
|
+
| -------------------------------------------------------- | -------------------------------------- | ----------------------------------------- | -------------------------------------------------------------- | --------------------- |
|
|
40
|
+
| {Product / QA / consumer / agent / other declared track} | {exact links} | {sources; page purpose; missing coverage} | {blocked first success/verification, material detour, or none} | {High / Medium / N/A} |
|
|
41
|
+
|
|
42
|
+
Assess root breadth and implementation-directory mirroring using reader evidence.
|
|
43
|
+
Do not invent missing audiences or choose an IA without approval.
|
|
44
|
+
|
|
45
|
+
## Offline Package Drift
|
|
46
|
+
|
|
47
|
+
- Bundle metadata: {running CLI public-package-versions.json path or unverified}
|
|
48
|
+
- Docs app manifest: {path; Markdown: not applicable}
|
|
49
|
+
|
|
50
|
+
| Package | Declared / installed | Bundled | Status | Exact upgrade command | Recommendation ID |
|
|
51
|
+
| ----------------------------- | ----------------------------------- | --------- | -------------------------------------- | ------------------------------------------------------------------------------ | ------------------------------------------------------- |
|
|
52
|
+
| {@open-agent-toolkit/docs-\*} | {range / actual version or missing} | {version} | {current / drift / ahead / unverified} | {drift only: helper upgrade command adapted to actual manager; otherwise none} | {drift only: R-NNN; approval: explicit; otherwise none} |
|
|
53
|
+
|
|
54
|
+
Only older installed packages (`drift`) receive a package-upgrade command and
|
|
55
|
+
stable recommendation ID with `approval: explicit`. `current` needs no tooling
|
|
56
|
+
recommendation, even if the helper emits a reinstall command. For `ahead`, select
|
|
57
|
+
or update the intended CLI installation, then re-analyze; do not recommend a docs
|
|
58
|
+
package downgrade. `unverified` requires manual verification before a package
|
|
59
|
+
recommendation.
|
|
60
|
+
|
|
61
|
+
Unsupported app config/routes/scripts: {manual changes required; never automatic}.
|
|
62
|
+
|
|
18
63
|
## Summary
|
|
19
64
|
|
|
20
65
|
- **Files evaluated:** {N}
|
|
@@ -258,14 +303,18 @@ canonical docs/config/examples.
|
|
|
258
303
|
|
|
259
304
|
1. **{Action}** — {rationale}
|
|
260
305
|
- Target: `{path}`
|
|
261
|
-
-
|
|
306
|
+
- ID: {R-NNN; unique and stable}
|
|
307
|
+
- approval: {explicit | default}
|
|
308
|
+
- Action Type: {create / update / move / scaffold / sync-nav / record-ia / restructure / tooling-update / manual}
|
|
262
309
|
- Evidence: {exact refs}
|
|
263
310
|
- Confidence: {high | medium | low}
|
|
264
311
|
- Disclosure: {inline | link_only | omit | ask_user}
|
|
265
312
|
- Link Targets: {path or URL / N/A}
|
|
266
313
|
2. **{Action}** — {rationale}
|
|
267
314
|
- Target: `{path}`
|
|
268
|
-
-
|
|
315
|
+
- ID: {R-NNN; unique and stable}
|
|
316
|
+
- approval: {explicit | default}
|
|
317
|
+
- Action Type: {create / update / move / scaffold / sync-nav / record-ia / restructure / tooling-update / manual}
|
|
269
318
|
- Evidence: {exact refs}
|
|
270
319
|
- Confidence: {high | medium | low}
|
|
271
320
|
- Disclosure: {inline | link_only | omit | ask_user}
|
|
@@ -274,6 +323,9 @@ canonical docs/config/examples.
|
|
|
274
323
|
|
|
275
324
|
## Apply Contract
|
|
276
325
|
|
|
326
|
+
- `oat-docs-apply` input is this artifact path plus approved recommendation IDs.
|
|
327
|
+
- Every recommendation has a unique stable ID and approval: explicit | default.
|
|
328
|
+
- Explicit items need individual approval by ID; blanket/unattended approval skips them and reports the reason.
|
|
277
329
|
- `oat-docs-apply` may only implement recommendations backed by evidence in this artifact.
|
|
278
330
|
- Findings based on contradicted claims must be resolved against cited repo sources before `oat-docs-apply` acts on them.
|
|
279
331
|
- Generated artifacts must not be hand-edited by `oat-docs-apply`. If a
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// Read-only, offline comparison used by oat-docs-analyze. No package resolution or install.
|
|
3
|
+
import { readFile, realpath } from 'node:fs/promises';
|
|
4
|
+
import { dirname, join, resolve } from 'node:path';
|
|
5
|
+
import { parseArgs } from 'node:util';
|
|
6
|
+
|
|
7
|
+
const shellQuote = (value) =>
|
|
8
|
+
`'${value.replaceAll("'", String.fromCharCode(39, 92, 39, 39))}'`;
|
|
9
|
+
|
|
10
|
+
async function versionsForCli(executable) {
|
|
11
|
+
if (!executable)
|
|
12
|
+
throw new Error(
|
|
13
|
+
'Provide --cli with the installed oat executable or --versions with its bundled public-package-versions.json.',
|
|
14
|
+
);
|
|
15
|
+
let directory = dirname(await realpath(executable));
|
|
16
|
+
for (;;) {
|
|
17
|
+
try {
|
|
18
|
+
const pkg = JSON.parse(
|
|
19
|
+
await readFile(join(directory, 'package.json'), 'utf8'),
|
|
20
|
+
);
|
|
21
|
+
if (pkg.name === '@open-agent-toolkit/cli')
|
|
22
|
+
return join(directory, 'assets/public-package-versions.json');
|
|
23
|
+
} catch (error) {
|
|
24
|
+
if (error.code !== 'ENOENT') throw error;
|
|
25
|
+
}
|
|
26
|
+
const parent = dirname(directory);
|
|
27
|
+
if (parent === directory)
|
|
28
|
+
throw new Error(
|
|
29
|
+
'Cannot locate the running CLI bundle through this wrapper; supply --versions from that installed CLI.',
|
|
30
|
+
);
|
|
31
|
+
directory = parent;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
try {
|
|
36
|
+
const { values } = parseArgs({
|
|
37
|
+
options: {
|
|
38
|
+
app: { type: 'string' },
|
|
39
|
+
versions: { type: 'string' },
|
|
40
|
+
cli: { type: 'string' },
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
if (!values.app) throw new Error('Required: --app <docs-app-directory>.');
|
|
44
|
+
const versionsPath = resolve(
|
|
45
|
+
values.versions ?? (await versionsForCli(values.cli)),
|
|
46
|
+
);
|
|
47
|
+
const versions = JSON.parse(await readFile(versionsPath, 'utf8'));
|
|
48
|
+
const appPath = resolve(values.app);
|
|
49
|
+
const manifest = JSON.parse(
|
|
50
|
+
await readFile(join(appPath, 'package.json'), 'utf8'),
|
|
51
|
+
);
|
|
52
|
+
const packages = [];
|
|
53
|
+
for (const section of [
|
|
54
|
+
'dependencies',
|
|
55
|
+
'devDependencies',
|
|
56
|
+
'optionalDependencies',
|
|
57
|
+
]) {
|
|
58
|
+
for (const [name, declared] of Object.entries(manifest[section] ?? {})) {
|
|
59
|
+
if (
|
|
60
|
+
![
|
|
61
|
+
'@open-agent-toolkit/docs-config',
|
|
62
|
+
'@open-agent-toolkit/docs-theme',
|
|
63
|
+
'@open-agent-toolkit/docs-transforms',
|
|
64
|
+
].includes(name)
|
|
65
|
+
)
|
|
66
|
+
continue;
|
|
67
|
+
const bundled = versions[name.slice('@open-agent-toolkit/'.length)];
|
|
68
|
+
if (
|
|
69
|
+
typeof bundled !== 'string' ||
|
|
70
|
+
!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(bundled)
|
|
71
|
+
)
|
|
72
|
+
throw new Error(`Missing/invalid bundled version for ${name}.`);
|
|
73
|
+
// Report installed package bytes when available, not just a declared range.
|
|
74
|
+
let installed = null;
|
|
75
|
+
try {
|
|
76
|
+
const installedManifest = JSON.parse(
|
|
77
|
+
await readFile(
|
|
78
|
+
join(appPath, 'node_modules', name, 'package.json'),
|
|
79
|
+
'utf8',
|
|
80
|
+
),
|
|
81
|
+
);
|
|
82
|
+
if (typeof installedManifest.version !== 'string')
|
|
83
|
+
throw new Error(`Invalid installed version for ${name}.`);
|
|
84
|
+
installed = installedManifest.version;
|
|
85
|
+
} catch (error) {
|
|
86
|
+
if (error.code !== 'ENOENT') throw error;
|
|
87
|
+
}
|
|
88
|
+
// Only stable numeric releases are orderable here; prereleases and other
|
|
89
|
+
// package-manager version forms need manual verification, never an upgrade.
|
|
90
|
+
const stable = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
91
|
+
let status = 'unverified';
|
|
92
|
+
if (
|
|
93
|
+
installed !== null &&
|
|
94
|
+
stable.test(installed) &&
|
|
95
|
+
stable.test(bundled)
|
|
96
|
+
) {
|
|
97
|
+
const left = installed.split('.').map(BigInt);
|
|
98
|
+
const right = bundled.split('.').map(BigInt);
|
|
99
|
+
const differing = left.findIndex(
|
|
100
|
+
(part, index) => part !== right[index],
|
|
101
|
+
);
|
|
102
|
+
status =
|
|
103
|
+
differing === -1
|
|
104
|
+
? 'current'
|
|
105
|
+
: left[differing] < right[differing]
|
|
106
|
+
? 'drift'
|
|
107
|
+
: 'ahead';
|
|
108
|
+
}
|
|
109
|
+
packages.push({
|
|
110
|
+
name,
|
|
111
|
+
section,
|
|
112
|
+
declared,
|
|
113
|
+
installed,
|
|
114
|
+
bundled,
|
|
115
|
+
status,
|
|
116
|
+
upgradeCommand:
|
|
117
|
+
status === 'drift' || status === 'current'
|
|
118
|
+
? `pnpm --dir ${shellQuote(appPath)} add${section === 'devDependencies' ? ' --save-dev' : section === 'optionalDependencies' ? ' --save-optional' : ''} ${name}@${bundled}`
|
|
119
|
+
: null,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
process.stdout.write(
|
|
124
|
+
`${JSON.stringify({ versionsPath, appPath, packages }, null, 2)}\n`,
|
|
125
|
+
);
|
|
126
|
+
} catch (error) {
|
|
127
|
+
process.stderr.write(`${error.message}\n`);
|
|
128
|
+
process.exitCode = 1;
|
|
129
|
+
}
|