agent-docs-bootstrap 0.0.0-stage → 0.2.0
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/CHANGELOG.md +39 -0
- package/LICENSE +21 -0
- package/README.md +188 -2
- package/THIRD_PARTY.md +33 -0
- package/agents/docs-reader.md +36 -0
- package/agents/docs-scout.md +65 -0
- package/install.mjs +180 -0
- package/package.json +11 -4
- package/skills/docs-bootstrap/SKILL.md +154 -0
- package/skills/docs-bootstrap/agents/openai.yaml +3 -0
- package/skills/docs-bootstrap/references/agents-md-format.md +70 -0
- package/skills/docs-bootstrap/references/c4-format.md +32 -0
- package/skills/docs-bootstrap/references/scout-briefs.md +76 -0
- package/skills/docs-bootstrap/references/signals.md +26 -0
- package/skills/docs-bootstrap/templates/AGENTS.starter.md +43 -0
- package/skills/docs-bootstrap/templates/bootstrap-state.md +30 -0
- package/skills/docs-bootstrap/templates/sources.md +19 -0
- package/skills/docs-check/SKILL.md +114 -0
- package/skills/docs-check/agents/openai.yaml +3 -0
- package/skills/docs-check/scripts/reader-run.mjs +177 -0
- package/skills/docs-check/templates/reader-tests.md +29 -0
- package/skills/third-party/diataxis-audit/LICENSE +21 -0
- package/skills/third-party/diataxis-audit/SKILL.md +180 -0
- package/skills/third-party/doc-coauthoring/LICENSE +202 -0
- package/skills/third-party/doc-coauthoring/SKILL.md +375 -0
- package/skills/third-party/domain-modeling/ADR-FORMAT.md +47 -0
- package/skills/third-party/domain-modeling/CONTEXT-FORMAT.md +60 -0
- package/skills/third-party/domain-modeling/LICENSE +21 -0
- package/skills/third-party/domain-modeling/SKILL.md +74 -0
- package/skills/third-party/domain-modeling/agents/openai.yaml +3 -0
- package/skills/third-party/grill-with-docs/LICENSE +21 -0
- package/skills/third-party/grill-with-docs/SKILL.md +7 -0
- package/skills/third-party/grill-with-docs/agents/openai.yaml +5 -0
- package/skills/third-party/grilling/LICENSE +21 -0
- package/skills/third-party/grilling/SKILL.md +28 -0
- package/skills/third-party/grilling/agents/openai.yaml +3 -0
- package/skills/third-party/writing-for-agents/LICENSE +21 -0
- package/skills/third-party/writing-for-agents/SKILL-MECHANICS.md +22 -0
- package/skills/third-party/writing-for-agents/SKILL.md +81 -0
- package/skills/third-party/writing-for-agents/agents/openai.yaml +3 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
// docs-check steps 2–3: a history-free snapshot outside the repository and a fresh reader started as a
|
|
3
|
+
// separate process of your harness. Works the same from bash, PowerShell and cmd; needs git and Node 18+.
|
|
4
|
+
//
|
|
5
|
+
// node <skills>/docs-check/scripts/reader-run.mjs <run dir> <N> --harness claude|codex|opencode [--reader <path>]
|
|
6
|
+
// node <skills>/docs-check/scripts/reader-run.mjs <run dir> <N> --snapshot-only
|
|
7
|
+
//
|
|
8
|
+
// <run dir> holds tasks.json: { "tasks": [ { "n": 1, "parent": "<hash>", "task": "<wording>" } ] }.
|
|
9
|
+
// Writes rt-<N>-plan.md (the reader's answer) and rt-<N>-log.md there; prints a short summary.
|
|
10
|
+
|
|
11
|
+
import fs from 'node:fs';
|
|
12
|
+
import path from 'node:path';
|
|
13
|
+
import os from 'node:os';
|
|
14
|
+
import { execFileSync, spawn } from 'node:child_process';
|
|
15
|
+
|
|
16
|
+
const a = parseArgs(process.argv.slice(2));
|
|
17
|
+
if (a.help || a._.length < 2) {
|
|
18
|
+
console.log(fs.readFileSync(new URL(import.meta.url), 'utf8').split('\n').slice(1, 10).map(l => l.replace(/^\/\/ ?/, '')).join('\n'));
|
|
19
|
+
process.exit(a.help ? 0 : 1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const ROOT = git(['rev-parse', '--show-toplevel'], process.cwd()).trim();
|
|
23
|
+
const RUN = path.resolve(a._[0]);
|
|
24
|
+
const N = Number(a._[1]);
|
|
25
|
+
const spec = JSON.parse(read(path.join(RUN, 'tasks.json'), 'no tasks.json in the run directory'));
|
|
26
|
+
const task = (spec.tasks || []).find(t => Number(t.n) === N) || die(`tasks.json has no task n=${N}`);
|
|
27
|
+
if (!task.parent || !task.task) die(`task ${N} has no parent or task`);
|
|
28
|
+
|
|
29
|
+
const SNAPS = path.join(os.tmpdir(), `agent-docs-check-${path.basename(ROOT)}`);
|
|
30
|
+
const SNAP = path.join(SNAPS, `rt-${N}`);
|
|
31
|
+
const TIMEOUT_MS = Number(a['timeout-min'] || 12) * 60 * 1000;
|
|
32
|
+
const win = process.platform === 'win32';
|
|
33
|
+
|
|
34
|
+
// Documents the kit builds; kit-installed paths and its run files never reach the reader.
|
|
35
|
+
const kitPaths = read(path.join(ROOT, '.agent-docs-bootstrap'), '', true).split('\n').filter(l => l && !l.startsWith('version='));
|
|
36
|
+
const isKit = (p) => p === '.agent-docs-bootstrap' || p.startsWith('docs/agents/') || kitPaths.some(k => p === k || p.startsWith(k + '/'));
|
|
37
|
+
const isDoc = (p) => /(^|\/)(AGENTS\.md|CONTEXT[^/]*\.md)$/.test(p) || p === 'CLAUDE.md' || p.startsWith('docs/');
|
|
38
|
+
|
|
39
|
+
// ---------- snapshot: the parent's code without documents, today's documents from the working tree on top
|
|
40
|
+
fs.rmSync(SNAP, { recursive: true, force: true });
|
|
41
|
+
fs.mkdirSync(SNAP, { recursive: true });
|
|
42
|
+
exportParent(p => !isKit(p) && !isDoc(p));
|
|
43
|
+
// Tracked and new documents, committed or not; git-ignored and deleted ones are skipped.
|
|
44
|
+
const docs = git(['ls-files', '-z', '--cached', '--others', '--exclude-standard'], ROOT).split('\0')
|
|
45
|
+
.filter(p => p && isDoc(p) && !isKit(p) && fs.existsSync(path.join(ROOT, p)));
|
|
46
|
+
for (const p of docs) {
|
|
47
|
+
fs.mkdirSync(path.dirname(path.join(SNAP, p)), { recursive: true });
|
|
48
|
+
fs.copyFileSync(path.join(ROOT, p), path.join(SNAP, p));
|
|
49
|
+
}
|
|
50
|
+
// An empty repository stops harnesses from loading AGENTS.md / CLAUDE.md from parent directories.
|
|
51
|
+
git(['init', '-q', SNAP], SNAP);
|
|
52
|
+
|
|
53
|
+
const files = walk(SNAP).filter(p => !p.startsWith('.git/'));
|
|
54
|
+
const leaked = files.filter(isKit);
|
|
55
|
+
if (leaked.length) die(`kit files in the snapshot: ${leaked.slice(0, 5).join(', ')}`);
|
|
56
|
+
if (a['snapshot-only']) { console.log(SNAP); process.exit(0); }
|
|
57
|
+
|
|
58
|
+
// ---------- reader
|
|
59
|
+
const harness = a.harness || die('pass --harness claude|codex|opencode: the harness you are running in');
|
|
60
|
+
const defaults = { claude: '.claude/agents/docs-reader.md', codex: '.codex/agents/docs-reader.toml', opencode: '.opencode/agents/docs-reader.md' };
|
|
61
|
+
if (!defaults[harness]) die(`unknown harness '${harness}'`);
|
|
62
|
+
const readerFile = path.resolve(ROOT, a.reader || defaults[harness]);
|
|
63
|
+
const reader = parseReader(read(readerFile, `no docs-reader for ${harness} (installed with --target ${harness}? pass --reader <path>)`));
|
|
64
|
+
const ask = `Task: ${task.task.trim()}\n\nMake a plan: files, changes, verification commands. Do not edit anything. Separately list everything you had to search the code for or guess, and your questions to the team.`;
|
|
65
|
+
const plan = path.join(RUN, `rt-${N}-plan.md`);
|
|
66
|
+
fs.mkdirSync(RUN, { recursive: true });
|
|
67
|
+
|
|
68
|
+
let cmd, args, env = { ...process.env }, input, fromFile = false;
|
|
69
|
+
if (harness === 'claude') {
|
|
70
|
+
// --restricted: no shell tools, file tools confined to the snapshot, no settings files; no MCP servers.
|
|
71
|
+
cmd = 'claude';
|
|
72
|
+
args = ['-p', '--restricted', '--strict-mcp-config', '--no-session-persistence', '--output-format', 'text',
|
|
73
|
+
...(reader.model ? ['--model', reader.model] : []), '--tools', 'Read,Grep,Glob'];
|
|
74
|
+
input = `${reader.prompt}\n\n${ask}`;
|
|
75
|
+
} else if (harness === 'codex') {
|
|
76
|
+
cmd = 'codex';
|
|
77
|
+
args = ['exec', '-C', SNAP, '-s', 'read-only', '--skip-git-repo-check', '--ephemeral', ...codexMcpOff(),
|
|
78
|
+
...(reader.model ? ['-m', reader.model] : []), '-o', plan, '-'];
|
|
79
|
+
input = `${reader.prompt}\n\n${ask}`;
|
|
80
|
+
fromFile = true;
|
|
81
|
+
} else {
|
|
82
|
+
// The agent definition goes to a config dir outside the snapshot; its permissions do the confining.
|
|
83
|
+
const cfg = path.join(SNAPS, 'opencode');
|
|
84
|
+
fs.mkdirSync(path.join(cfg, 'agents'), { recursive: true });
|
|
85
|
+
fs.copyFileSync(readerFile, path.join(cfg, 'agents', 'docs-reader.md'));
|
|
86
|
+
env = { ...env, OPENCODE_CONFIG_DIR: cfg, OPENCODE_DISABLE_CLAUDE_CODE: '1' };
|
|
87
|
+
cmd = 'opencode';
|
|
88
|
+
args = ['run', '--pure', '--dir', SNAP, '--agent', 'docs-reader'];
|
|
89
|
+
input = ask;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// On Windows the CLIs are often .cmd shims that only a shell can start. The task goes through stdin,
|
|
93
|
+
// so quotes and non-ASCII text never pass through the shell.
|
|
94
|
+
const child = spawn(win ? [cmd, ...args].map(q).join(' ') : cmd, win ? [] : args,
|
|
95
|
+
{ cwd: SNAP, env, shell: win, stdio: ['pipe', 'pipe', 'pipe'] });
|
|
96
|
+
child.stdin.end(input);
|
|
97
|
+
let out = '', err = '';
|
|
98
|
+
child.stdout.on('data', d => { out += d; });
|
|
99
|
+
child.stderr.on('data', d => { err += d; });
|
|
100
|
+
const timer = setTimeout(() => { err += `\nstopped after ${TIMEOUT_MS / 60000} min`; child.kill(); }, TIMEOUT_MS);
|
|
101
|
+
child.on('error', e => die(`${cmd} did not start: ${e.message}`));
|
|
102
|
+
child.on('close', code => {
|
|
103
|
+
clearTimeout(timer);
|
|
104
|
+
if (!fromFile || !fs.existsSync(plan)) fs.writeFileSync(plan, out);
|
|
105
|
+
const text = read(plan, '', true).trim();
|
|
106
|
+
fs.writeFileSync(path.join(RUN, `rt-${N}-log.md`), `# rt-${N}: ${harness} reader output\n\n## stdout\n\n\`\`\`\n${out.trim()}\n\`\`\`\n\n## stderr\n\n\`\`\`\n${err.trim()}\n\`\`\`\n`);
|
|
107
|
+
console.log([
|
|
108
|
+
`task ${N}, parent ${task.parent}, harness ${harness}`,
|
|
109
|
+
`snapshot: ${SNAP} (${files.length} files, ${docs.length} documents)`,
|
|
110
|
+
`reader: exit ${code}, plan ${text ? 'written' : 'EMPTY'}: ${path.relative(ROOT, plan)}`,
|
|
111
|
+
].join('\n'));
|
|
112
|
+
process.exit(code === 0 && text ? 0 : 1);
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
// ---------- helpers
|
|
116
|
+
function exportParent(keep) {
|
|
117
|
+
const list = git(['ls-tree', '-r', '-z', '--name-only', task.parent], ROOT).split('\0').filter(Boolean).filter(keep);
|
|
118
|
+
if (!list.length) return;
|
|
119
|
+
const index = path.join(SNAPS, `index-${N}`);
|
|
120
|
+
const genv = { ...process.env, GIT_INDEX_FILE: index };
|
|
121
|
+
try {
|
|
122
|
+
// A temporary index: the repository's own index and working tree are untouched, no tar needed.
|
|
123
|
+
execFileSync('git', ['read-tree', task.parent], { cwd: ROOT, env: genv, stdio: ['ignore', 'ignore', 'pipe'] });
|
|
124
|
+
execFileSync('git', ['checkout-index', '-f', '-z', '--stdin', `--prefix=${SNAP.split(path.sep).join('/')}/`],
|
|
125
|
+
{ cwd: ROOT, env: genv, input: list.join('\0'), stdio: ['pipe', 'ignore', 'pipe'] });
|
|
126
|
+
} finally { fs.rmSync(index, { force: true }); }
|
|
127
|
+
}
|
|
128
|
+
// `-c mcp_servers={}` is merged into the user's table and disables nothing. Plugin and app servers go with
|
|
129
|
+
// their features; every server from config.toml is switched off by name. A name with a dot cannot be
|
|
130
|
+
// addressed in a `-c` path.
|
|
131
|
+
function codexMcpOff() {
|
|
132
|
+
const off = ['--disable', 'plugins', '--disable', 'apps'];
|
|
133
|
+
const ls = [...off, 'mcp', 'list', '--json'];
|
|
134
|
+
let list;
|
|
135
|
+
try {
|
|
136
|
+
const out = execFileSync(win ? ['codex', ...ls].join(' ') : 'codex', win ? [] : ls,
|
|
137
|
+
{ cwd: SNAP, encoding: 'utf8', shell: win, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
138
|
+
list = JSON.parse(out);
|
|
139
|
+
} catch (e) { die(`codex mcp list --json failed, cannot turn MCP servers off: ${(e.stderr || e.message).toString().trim()}`); }
|
|
140
|
+
const names = list.filter(s => s.enabled !== false).map(s => s.name);
|
|
141
|
+
const dotted = names.filter(n => n.includes('.'));
|
|
142
|
+
if (dotted.length) die(`MCP server names with a dot cannot be turned off for the reader: ${dotted.join(', ')}`);
|
|
143
|
+
return [...off, ...names.flatMap(n => ['-c', `mcp_servers.${n}.enabled=false`])];
|
|
144
|
+
}
|
|
145
|
+
// The installed docs-reader: Markdown with frontmatter (Claude Code, OpenCode) or TOML (Codex).
|
|
146
|
+
function parseReader(text) {
|
|
147
|
+
if (readerFile.endsWith('.toml')) {
|
|
148
|
+
return { prompt: (text.match(/developer_instructions = '''\n?([\s\S]*?)'''/) || die(`${readerFile}: no developer_instructions`))[1].trim(),
|
|
149
|
+
model: (text.match(/^model = "(.*)"$/m) || [])[1] };
|
|
150
|
+
}
|
|
151
|
+
const m = text.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/) || die(`${readerFile}: no frontmatter`);
|
|
152
|
+
return { prompt: m[2].trim(), model: (m[1].match(/^model: (.+)$/m) || [])[1] };
|
|
153
|
+
}
|
|
154
|
+
function git(args, cwd) {
|
|
155
|
+
try { return execFileSync('git', args, { cwd, encoding: 'utf8', maxBuffer: 256 * 1024 * 1024, stdio: ['ignore', 'pipe', 'pipe'] }); }
|
|
156
|
+
catch (e) { die(`git ${args.join(' ')}: ${(e.stderr || e.message).toString().trim()}`); }
|
|
157
|
+
}
|
|
158
|
+
function walk(dir, base = dir) {
|
|
159
|
+
return fs.readdirSync(dir, { withFileTypes: true }).flatMap(e => {
|
|
160
|
+
const p = path.join(dir, e.name);
|
|
161
|
+
return e.isDirectory() ? walk(p, base) : [path.relative(base, p).split(path.sep).join('/')];
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
function q(s) { return /^[\w./:\\=,-]+$/.test(s) ? s : `"${s}"`; }
|
|
165
|
+
function read(p, msg, optional) { try { return fs.readFileSync(p, 'utf8').replace(/\r\n/g, '\n'); } catch { return optional ? '' : die(`${msg}: ${p}`); } }
|
|
166
|
+
function die(msg) { console.error(`reader-run: ${msg}`); process.exit(1); }
|
|
167
|
+
function parseArgs(argv) {
|
|
168
|
+
const o = { _: [] };
|
|
169
|
+
for (let i = 0; i < argv.length; i++) {
|
|
170
|
+
const k = argv[i];
|
|
171
|
+
if (k === '-h' || k === '--help') o.help = true;
|
|
172
|
+
else if (k === '--snapshot-only') o['snapshot-only'] = true;
|
|
173
|
+
else if (k.startsWith('--')) o[k.slice(2)] = argv[++i];
|
|
174
|
+
else o._.push(k);
|
|
175
|
+
}
|
|
176
|
+
return o;
|
|
177
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Reader test tasks
|
|
2
|
+
|
|
3
|
+
Tasks for the `docs-check` skill, an optional check the team runs when it wants to. History tasks are three typical project tasks from git history, picked by the agent; own tasks are given by a human.
|
|
4
|
+
|
|
5
|
+
Wording — what a developer would understand without the ticket: no file names, hashes or tracker links. Reference — files and areas of code and tests from `git show --stat`, without unrelated changes; commands only those the reader can find in the repository. Documentation, CI scans and deploys are not part of the reference.
|
|
6
|
+
|
|
7
|
+
Status: `ready` — goes into the next check; `used` — the documents hold its answer (they were fixed for it or mention the solution), replace it; `replaced` — the solution was already in the parent's code, or the task was swapped.
|
|
8
|
+
|
|
9
|
+
## History tasks
|
|
10
|
+
|
|
11
|
+
| # | Commit (hash) | Parent | Task (wording for the reader) | Expected files/areas | Expected commands | Area | Status |
|
|
12
|
+
|---|---|---|---|---|---|---|---|
|
|
13
|
+
| 1 | | | | | | | ready |
|
|
14
|
+
| 2 | | | | | | | ready |
|
|
15
|
+
| 3 | | | | | | | ready |
|
|
16
|
+
|
|
17
|
+
## Own tasks
|
|
18
|
+
|
|
19
|
+
| Date | Commit the snapshot ran on | Task (wording for the reader) | Given by |
|
|
20
|
+
|---|---|---|---|
|
|
21
|
+
| | | | |
|
|
22
|
+
|
|
23
|
+
## Runs
|
|
24
|
+
|
|
25
|
+
Plans and reader logs are in `docs/agents/scratch/reader-runs/<date>/`. For an own task, the gaps are what the human said the documents should have answered; snapshot artifacts do not apply.
|
|
26
|
+
|
|
27
|
+
| Date | Task | Gaps found | Snapshot artifacts | Fixes applied |
|
|
28
|
+
|---|---|---|---|---|
|
|
29
|
+
| | | | | |
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Georges Martin
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: diataxis-audit
|
|
3
|
+
description: >
|
|
4
|
+
Audit existing documentation against the Diátaxis framework's four quadrants.
|
|
5
|
+
Use when reviewing documentation that feels unclear, when assessing documentation
|
|
6
|
+
quality, or when preparing for a documentation reorganization.
|
|
7
|
+
metadata:
|
|
8
|
+
author: "Georges Martin <jrjsmrtn@gmail.com>"
|
|
9
|
+
version: "0.1.5"
|
|
10
|
+
license: MIT
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Diátaxis Documentation Audit
|
|
14
|
+
|
|
15
|
+
Audit existing documentation against the [Diátaxis](https://diataxis.fr/) framework to identify mixed quadrants, gaps, and quality issues.
|
|
16
|
+
|
|
17
|
+
## Diátaxis Compass
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
Practical Theoretical
|
|
21
|
+
+----------------+------------------+
|
|
22
|
+
Study | TUTORIALS | EXPLANATION |
|
|
23
|
+
| (learning) | (understanding) |
|
|
24
|
+
+----------------+------------------+
|
|
25
|
+
Work | HOW-TO | REFERENCE |
|
|
26
|
+
| (problem) | (information) |
|
|
27
|
+
+----------------+------------------+
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
**Key principle**: These quadrants must remain distinct. Blurring boundaries is the most common documentation problem.
|
|
31
|
+
|
|
32
|
+
## When to Use
|
|
33
|
+
|
|
34
|
+
- Reviewing documentation that feels unclear or difficult to use
|
|
35
|
+
- Assessing documentation quality before a release or handoff
|
|
36
|
+
- Preparing for a documentation reorganization
|
|
37
|
+
- Onboarding to an unfamiliar project and evaluating its docs
|
|
38
|
+
|
|
39
|
+
## Required Inputs
|
|
40
|
+
|
|
41
|
+
1. **Documentation path(s)**: Files or directories to audit
|
|
42
|
+
2. **Scope** (optional): Full audit or quick spot-check
|
|
43
|
+
|
|
44
|
+
## Workflow
|
|
45
|
+
|
|
46
|
+
### Phase 1: Inventory
|
|
47
|
+
|
|
48
|
+
Read all documentation files in the target path. For each file, record:
|
|
49
|
+
- File path
|
|
50
|
+
- Apparent intent (what quadrant it seems to target)
|
|
51
|
+
- Length and structure
|
|
52
|
+
|
|
53
|
+
### Phase 2: Classify
|
|
54
|
+
|
|
55
|
+
For each document or section, classify using these questions:
|
|
56
|
+
|
|
57
|
+
| Question | If Yes → |
|
|
58
|
+
|----------|----------|
|
|
59
|
+
| Is it a guided learning experience building to a result? | **Tutorial** |
|
|
60
|
+
| Does it solve a specific, practical problem? | **How-to guide** |
|
|
61
|
+
| Does it describe the system factually and completely? | **Reference** |
|
|
62
|
+
| Does it explain why things work the way they do? | **Explanation** |
|
|
63
|
+
|
|
64
|
+
If a section answers multiple questions, it is **mixed** — flag it.
|
|
65
|
+
|
|
66
|
+
### Phase 3: Detect Red Flags
|
|
67
|
+
|
|
68
|
+
Check each document against its quadrant's anti-patterns:
|
|
69
|
+
|
|
70
|
+
**Tutorials that**:
|
|
71
|
+
- Explain concepts before showing action
|
|
72
|
+
- Offer choices or alternatives
|
|
73
|
+
- Assume prior knowledge of the system
|
|
74
|
+
- Don't build to a concrete, testable result
|
|
75
|
+
|
|
76
|
+
**How-to guides that**:
|
|
77
|
+
- Teach from scratch instead of assuming competence
|
|
78
|
+
- Explain theory instead of giving directions
|
|
79
|
+
- Don't state the goal upfront
|
|
80
|
+
- Have only one rigid path (no flexibility)
|
|
81
|
+
|
|
82
|
+
**Reference that**:
|
|
83
|
+
- Includes step-by-step instructions
|
|
84
|
+
- Uses conversational or narrative tone
|
|
85
|
+
- Is incomplete or inconsistent in coverage
|
|
86
|
+
- Mixes in opinions or recommendations
|
|
87
|
+
|
|
88
|
+
**Explanation that**:
|
|
89
|
+
- Is just a list of bare facts
|
|
90
|
+
- Includes procedural steps
|
|
91
|
+
- Doesn't connect to the "why"
|
|
92
|
+
- Lacks context or historical perspective
|
|
93
|
+
|
|
94
|
+
### Phase 4: Gap Analysis
|
|
95
|
+
|
|
96
|
+
Check which quadrants are missing entirely:
|
|
97
|
+
- No tutorials? New users have no guided onboarding.
|
|
98
|
+
- No how-to guides? Experienced users can't solve specific problems.
|
|
99
|
+
- No reference? Developers can't look up details.
|
|
100
|
+
- No explanation? Nobody understands the design rationale.
|
|
101
|
+
|
|
102
|
+
### Phase 5: Quality Assessment
|
|
103
|
+
|
|
104
|
+
For documents that are correctly classified, assess quality:
|
|
105
|
+
|
|
106
|
+
**Tutorial quality**:
|
|
107
|
+
- Could a complete beginner succeed on first try?
|
|
108
|
+
- Does it build to a concrete result?
|
|
109
|
+
- Are steps small and testable?
|
|
110
|
+
- Does it inspire confidence and motivation?
|
|
111
|
+
|
|
112
|
+
**How-to quality**:
|
|
113
|
+
- Does it solve a real problem users actually have?
|
|
114
|
+
- Can users adapt the steps to their situation?
|
|
115
|
+
- Does it assume appropriate competence?
|
|
116
|
+
- Is the goal stated clearly upfront?
|
|
117
|
+
|
|
118
|
+
**Reference quality**:
|
|
119
|
+
- Can users find information quickly?
|
|
120
|
+
- Is coverage consistent and comprehensive?
|
|
121
|
+
- Is it authoritative and trustworthy?
|
|
122
|
+
- Is it structured for scanning, not reading?
|
|
123
|
+
|
|
124
|
+
**Explanation quality**:
|
|
125
|
+
- Does it produce understanding ("aha!" moments)?
|
|
126
|
+
- Does it connect concepts to motivations?
|
|
127
|
+
- Does it discuss trade-offs honestly?
|
|
128
|
+
- Does it help users make better decisions?
|
|
129
|
+
|
|
130
|
+
## Outputs
|
|
131
|
+
|
|
132
|
+
Generate an audit report containing:
|
|
133
|
+
|
|
134
|
+
- [ ] **Summary table**: Each document with its classification, quality rating, and issues
|
|
135
|
+
- [ ] **Mixed content**: Specific sections that blend quadrants, with extraction recommendations
|
|
136
|
+
- [ ] **Gap analysis**: Missing quadrants and their impact
|
|
137
|
+
- [ ] **Priority recommendations**: Ordered list of improvements, highest impact first
|
|
138
|
+
- [ ] **Cross-linking opportunities**: Where documents should reference each other
|
|
139
|
+
|
|
140
|
+
## Report Format
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
# Diátaxis Audit Report
|
|
144
|
+
|
|
145
|
+
## Summary
|
|
146
|
+
|
|
147
|
+
| Document | Intended Quadrant | Actual Quadrant(s) | Quality | Issues |
|
|
148
|
+
|----------|-------------------|---------------------|---------|--------|
|
|
149
|
+
| ... | ... | ... | ... | ... |
|
|
150
|
+
|
|
151
|
+
## Mixed Content (requires splitting)
|
|
152
|
+
|
|
153
|
+
### [filename]
|
|
154
|
+
- Lines N-M: Tutorial content mixed into reference → extract to tutorials/
|
|
155
|
+
- Lines X-Y: Explanation mixed into how-to → extract to explanation/
|
|
156
|
+
|
|
157
|
+
## Missing Quadrants
|
|
158
|
+
|
|
159
|
+
- [ ] Tutorial: [impact of absence]
|
|
160
|
+
- [ ] How-to: [impact of absence]
|
|
161
|
+
- [ ] Reference: [impact of absence]
|
|
162
|
+
- [ ] Explanation: [impact of absence]
|
|
163
|
+
|
|
164
|
+
## Recommendations (priority order)
|
|
165
|
+
|
|
166
|
+
1. [Highest impact action]
|
|
167
|
+
2. ...
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
## Validation
|
|
171
|
+
|
|
172
|
+
- Every document is classified into exactly one quadrant (or flagged as mixed)
|
|
173
|
+
- Red flags are specific: cite the document, section, and line range
|
|
174
|
+
- Recommendations are actionable and prioritized
|
|
175
|
+
|
|
176
|
+
## Related Skills
|
|
177
|
+
|
|
178
|
+
- `diataxis-convert`: Split mixed documents identified by this audit
|
|
179
|
+
- `diataxis-create`: Fill gaps identified by this audit
|
|
180
|
+
- `diataxis-plan`: Design the target documentation architecture
|
|
@@ -0,0 +1,202 @@
|
|
|
1
|
+
|
|
2
|
+
Apache License
|
|
3
|
+
Version 2.0, January 2004
|
|
4
|
+
http://www.apache.org/licenses/
|
|
5
|
+
|
|
6
|
+
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
|
7
|
+
|
|
8
|
+
1. Definitions.
|
|
9
|
+
|
|
10
|
+
"License" shall mean the terms and conditions for use, reproduction,
|
|
11
|
+
and distribution as defined by Sections 1 through 9 of this document.
|
|
12
|
+
|
|
13
|
+
"Licensor" shall mean the copyright owner or entity authorized by
|
|
14
|
+
the copyright owner that is granting the License.
|
|
15
|
+
|
|
16
|
+
"Legal Entity" shall mean the union of the acting entity and all
|
|
17
|
+
other entities that control, are controlled by, or are under common
|
|
18
|
+
control with that entity. For the purposes of this definition,
|
|
19
|
+
"control" means (i) the power, direct or indirect, to cause the
|
|
20
|
+
direction or management of such entity, whether by contract or
|
|
21
|
+
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
|
22
|
+
outstanding shares, or (iii) beneficial ownership of such entity.
|
|
23
|
+
|
|
24
|
+
"You" (or "Your") shall mean an individual or Legal Entity
|
|
25
|
+
exercising permissions granted by this License.
|
|
26
|
+
|
|
27
|
+
"Source" form shall mean the preferred form for making modifications,
|
|
28
|
+
including but not limited to software source code, documentation
|
|
29
|
+
source, and configuration files.
|
|
30
|
+
|
|
31
|
+
"Object" form shall mean any form resulting from mechanical
|
|
32
|
+
transformation or translation of a Source form, including but
|
|
33
|
+
not limited to compiled object code, generated documentation,
|
|
34
|
+
and conversions to other media types.
|
|
35
|
+
|
|
36
|
+
"Work" shall mean the work of authorship, whether in Source or
|
|
37
|
+
Object form, made available under the License, as indicated by a
|
|
38
|
+
copyright notice that is included in or attached to the work
|
|
39
|
+
(an example is provided in the Appendix below).
|
|
40
|
+
|
|
41
|
+
"Derivative Works" shall mean any work, whether in Source or Object
|
|
42
|
+
form, that is based on (or derived from) the Work and for which the
|
|
43
|
+
editorial revisions, annotations, elaborations, or other modifications
|
|
44
|
+
represent, as a whole, an original work of authorship. For the purposes
|
|
45
|
+
of this License, Derivative Works shall not include works that remain
|
|
46
|
+
separable from, or merely link (or bind by name) to the interfaces of,
|
|
47
|
+
the Work and Derivative Works thereof.
|
|
48
|
+
|
|
49
|
+
"Contribution" shall mean any work of authorship, including
|
|
50
|
+
the original version of the Work and any modifications or additions
|
|
51
|
+
to that Work or Derivative Works thereof, that is intentionally
|
|
52
|
+
submitted to Licensor for inclusion in the Work by the copyright owner
|
|
53
|
+
or by an individual or Legal Entity authorized to submit on behalf of
|
|
54
|
+
the copyright owner. For the purposes of this definition, "submitted"
|
|
55
|
+
means any form of electronic, verbal, or written communication sent
|
|
56
|
+
to the Licensor or its representatives, including but not limited to
|
|
57
|
+
communication on electronic mailing lists, source code control systems,
|
|
58
|
+
and issue tracking systems that are managed by, or on behalf of, the
|
|
59
|
+
Licensor for the purpose of discussing and improving the Work, but
|
|
60
|
+
excluding communication that is conspicuously marked or otherwise
|
|
61
|
+
designated in writing by the copyright owner as "Not a Contribution."
|
|
62
|
+
|
|
63
|
+
"Contributor" shall mean Licensor and any individual or Legal Entity
|
|
64
|
+
on behalf of whom a Contribution has been received by Licensor and
|
|
65
|
+
subsequently incorporated within the Work.
|
|
66
|
+
|
|
67
|
+
2. Grant of Copyright License. Subject to the terms and conditions of
|
|
68
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
69
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
70
|
+
copyright license to reproduce, prepare Derivative Works of,
|
|
71
|
+
publicly display, publicly perform, sublicense, and distribute the
|
|
72
|
+
Work and such Derivative Works in Source or Object form.
|
|
73
|
+
|
|
74
|
+
3. Grant of Patent License. Subject to the terms and conditions of
|
|
75
|
+
this License, each Contributor hereby grants to You a perpetual,
|
|
76
|
+
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
|
77
|
+
(except as stated in this section) patent license to make, have made,
|
|
78
|
+
use, offer to sell, sell, import, and otherwise transfer the Work,
|
|
79
|
+
where such license applies only to those patent claims licensable
|
|
80
|
+
by such Contributor that are necessarily infringed by their
|
|
81
|
+
Contribution(s) alone or by combination of their Contribution(s)
|
|
82
|
+
with the Work to which such Contribution(s) was submitted. If You
|
|
83
|
+
institute patent litigation against any entity (including a
|
|
84
|
+
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
|
85
|
+
or a Contribution incorporated within the Work constitutes direct
|
|
86
|
+
or contributory patent infringement, then any patent licenses
|
|
87
|
+
granted to You under this License for that Work shall terminate
|
|
88
|
+
as of the date such litigation is filed.
|
|
89
|
+
|
|
90
|
+
4. Redistribution. You may reproduce and distribute copies of the
|
|
91
|
+
Work or Derivative Works thereof in any medium, with or without
|
|
92
|
+
modifications, and in Source or Object form, provided that You
|
|
93
|
+
meet the following conditions:
|
|
94
|
+
|
|
95
|
+
(a) You must give any other recipients of the Work or
|
|
96
|
+
Derivative Works a copy of this License; and
|
|
97
|
+
|
|
98
|
+
(b) You must cause any modified files to carry prominent notices
|
|
99
|
+
stating that You changed the files; and
|
|
100
|
+
|
|
101
|
+
(c) You must retain, in the Source form of any Derivative Works
|
|
102
|
+
that You distribute, all copyright, patent, trademark, and
|
|
103
|
+
attribution notices from the Source form of the Work,
|
|
104
|
+
excluding those notices that do not pertain to any part of
|
|
105
|
+
the Derivative Works; and
|
|
106
|
+
|
|
107
|
+
(d) If the Work includes a "NOTICE" text file as part of its
|
|
108
|
+
distribution, then any Derivative Works that You distribute must
|
|
109
|
+
include a readable copy of the attribution notices contained
|
|
110
|
+
within such NOTICE file, excluding those notices that do not
|
|
111
|
+
pertain to any part of the Derivative Works, in at least one
|
|
112
|
+
of the following places: within a NOTICE text file distributed
|
|
113
|
+
as part of the Derivative Works; within the Source form or
|
|
114
|
+
documentation, if provided along with the Derivative Works; or,
|
|
115
|
+
within a display generated by the Derivative Works, if and
|
|
116
|
+
wherever such third-party notices normally appear. The contents
|
|
117
|
+
of the NOTICE file are for informational purposes only and
|
|
118
|
+
do not modify the License. You may add Your own attribution
|
|
119
|
+
notices within Derivative Works that You distribute, alongside
|
|
120
|
+
or as an addendum to the NOTICE text from the Work, provided
|
|
121
|
+
that such additional attribution notices cannot be construed
|
|
122
|
+
as modifying the License.
|
|
123
|
+
|
|
124
|
+
You may add Your own copyright statement to Your modifications and
|
|
125
|
+
may provide additional or different license terms and conditions
|
|
126
|
+
for use, reproduction, or distribution of Your modifications, or
|
|
127
|
+
for any such Derivative Works as a whole, provided Your use,
|
|
128
|
+
reproduction, and distribution of the Work otherwise complies with
|
|
129
|
+
the conditions stated in this License.
|
|
130
|
+
|
|
131
|
+
5. Submission of Contributions. Unless You explicitly state otherwise,
|
|
132
|
+
any Contribution intentionally submitted for inclusion in the Work
|
|
133
|
+
by You to the Licensor shall be under the terms and conditions of
|
|
134
|
+
this License, without any additional terms or conditions.
|
|
135
|
+
Notwithstanding the above, nothing herein shall supersede or modify
|
|
136
|
+
the terms of any separate license agreement you may have executed
|
|
137
|
+
with Licensor regarding such Contributions.
|
|
138
|
+
|
|
139
|
+
6. Trademarks. This License does not grant permission to use the trade
|
|
140
|
+
names, trademarks, service marks, or product names of the Licensor,
|
|
141
|
+
except as required for reasonable and customary use in describing the
|
|
142
|
+
origin of the Work and reproducing the content of the NOTICE file.
|
|
143
|
+
|
|
144
|
+
7. Disclaimer of Warranty. Unless required by applicable law or
|
|
145
|
+
agreed to in writing, Licensor provides the Work (and each
|
|
146
|
+
Contributor provides its Contributions) on an "AS IS" BASIS,
|
|
147
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
148
|
+
implied, including, without limitation, any warranties or conditions
|
|
149
|
+
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
|
150
|
+
PARTICULAR PURPOSE. You are solely responsible for determining the
|
|
151
|
+
appropriateness of using or redistributing the Work and assume any
|
|
152
|
+
risks associated with Your exercise of permissions under this License.
|
|
153
|
+
|
|
154
|
+
8. Limitation of Liability. In no event and under no legal theory,
|
|
155
|
+
whether in tort (including negligence), contract, or otherwise,
|
|
156
|
+
unless required by applicable law (such as deliberate and grossly
|
|
157
|
+
negligent acts) or agreed to in writing, shall any Contributor be
|
|
158
|
+
liable to You for damages, including any direct, indirect, special,
|
|
159
|
+
incidental, or consequential damages of any character arising as a
|
|
160
|
+
result of this License or out of the use or inability to use the
|
|
161
|
+
Work (including but not limited to damages for loss of goodwill,
|
|
162
|
+
work stoppage, computer failure or malfunction, or any and all
|
|
163
|
+
other commercial damages or losses), even if such Contributor
|
|
164
|
+
has been advised of the possibility of such damages.
|
|
165
|
+
|
|
166
|
+
9. Accepting Warranty or Additional Liability. While redistributing
|
|
167
|
+
the Work or Derivative Works thereof, You may choose to offer,
|
|
168
|
+
and charge a fee for, acceptance of support, warranty, indemnity,
|
|
169
|
+
or other liability obligations and/or rights consistent with this
|
|
170
|
+
License. However, in accepting such obligations, You may act only
|
|
171
|
+
on Your own behalf and on Your sole responsibility, not on behalf
|
|
172
|
+
of any other Contributor, and only if You agree to indemnify,
|
|
173
|
+
defend, and hold each Contributor harmless for any liability
|
|
174
|
+
incurred by, or claims asserted against, such Contributor by reason
|
|
175
|
+
of your accepting any such warranty or additional liability.
|
|
176
|
+
|
|
177
|
+
END OF TERMS AND CONDITIONS
|
|
178
|
+
|
|
179
|
+
APPENDIX: How to apply the Apache License to your work.
|
|
180
|
+
|
|
181
|
+
To apply the Apache License to your work, attach the following
|
|
182
|
+
boilerplate notice, with the fields enclosed by brackets "[]"
|
|
183
|
+
replaced with your own identifying information. (Don't include
|
|
184
|
+
the brackets!) The text should be enclosed in the appropriate
|
|
185
|
+
comment syntax for the file format. We also recommend that a
|
|
186
|
+
file or class name and description of purpose be included on the
|
|
187
|
+
same "printed page" as the copyright notice for easier
|
|
188
|
+
identification within third-party archives.
|
|
189
|
+
|
|
190
|
+
Copyright [yyyy] [name of copyright owner]
|
|
191
|
+
|
|
192
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
|
193
|
+
you may not use this file except in compliance with the License.
|
|
194
|
+
You may obtain a copy of the License at
|
|
195
|
+
|
|
196
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
197
|
+
|
|
198
|
+
Unless required by applicable law or agreed to in writing, software
|
|
199
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
|
200
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
201
|
+
See the License for the specific language governing permissions and
|
|
202
|
+
limitations under the License.
|