@seanyao/roll 0.5.0 → 2.602.1
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 +717 -0
- package/LICENSE +21 -0
- package/README.md +65 -165
- package/bin/dream-test-quality-scan +110 -0
- package/bin/roll +14897 -815
- package/conventions/config.yaml +17 -1
- package/conventions/global/AGENTS.md +146 -100
- package/conventions/global/CLAUDE.md +1 -21
- package/conventions/global/GEMINI.md +8 -22
- package/conventions/global/project_rules.md +9 -0
- package/conventions/templates/backend-service/AGENTS.md +30 -81
- package/conventions/templates/backend-service/GEMINI.md +3 -3
- package/conventions/templates/backend-service/project_rules.md +16 -0
- package/conventions/templates/cli/AGENTS.md +31 -58
- package/conventions/templates/cli/CLAUDE.md +3 -5
- package/conventions/templates/cli/GEMINI.md +3 -3
- package/conventions/templates/cli/project_rules.md +16 -0
- package/conventions/templates/frontend-only/AGENTS.md +29 -64
- package/conventions/templates/frontend-only/GEMINI.md +3 -3
- package/conventions/templates/frontend-only/project_rules.md +14 -0
- package/conventions/templates/fullstack/AGENTS.md +31 -79
- package/conventions/templates/fullstack/CLAUDE.md +1 -1
- package/conventions/templates/fullstack/GEMINI.md +3 -3
- package/conventions/templates/fullstack/project_rules.md +15 -0
- package/lib/README.md +42 -0
- package/lib/__pycache__/github_sync.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop-fmt.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_result_eval.cpython-314.pyc +0 -0
- package/lib/__pycache__/loop_unstick.cpython-314.pyc +0 -0
- package/lib/__pycache__/model_prices.cpython-314.pyc +0 -0
- package/lib/__pycache__/prices_fetcher.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-home.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll-loop-status.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_git.cpython-314.pyc +0 -0
- package/lib/__pycache__/roll_render.cpython-314.pyc +0 -0
- package/lib/__pycache__/slides-render.cpython-314.pyc +0 -0
- package/lib/agent_usage/README.md +49 -0
- package/lib/agent_usage/__init__.py +108 -0
- package/lib/agent_usage/__pycache__/__init__.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/gemini.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/kimi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/openai.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/pi_emit.cpython-314.pyc +0 -0
- package/lib/agent_usage/__pycache__/qwen.cpython-314.pyc +0 -0
- package/lib/agent_usage/gemini.py +127 -0
- package/lib/agent_usage/kimi.py +278 -0
- package/lib/agent_usage/kimi_emit.py +123 -0
- package/lib/agent_usage/openai.py +126 -0
- package/lib/agent_usage/pi.py +200 -0
- package/lib/agent_usage/pi_emit.py +135 -0
- package/lib/agent_usage/qwen.py +128 -0
- package/lib/backfill-pi-usage.py +243 -0
- package/lib/changelog_audit.py +155 -0
- package/lib/changelog_generate.py +263 -0
- package/lib/context_feed_budget.sh +194 -0
- package/lib/github_sync.py +876 -0
- package/lib/i18n/README.md +54 -0
- package/lib/i18n/agent.sh +75 -0
- package/lib/i18n/alert.sh +20 -0
- package/lib/i18n/backlog.sh +96 -0
- package/lib/i18n/brief.sh +5 -0
- package/lib/i18n/changelog.sh +5 -0
- package/lib/i18n/ci.sh +15 -0
- package/lib/i18n/debug.sh +0 -0
- package/lib/i18n/doctor.sh +44 -0
- package/lib/i18n/dream.sh +0 -0
- package/lib/i18n/init.sh +91 -0
- package/lib/i18n/lang.sh +10 -0
- package/lib/i18n/loop.sh +140 -0
- package/lib/i18n/migrate.sh +74 -0
- package/lib/i18n/offboard.sh +31 -0
- package/lib/i18n/onboard.sh +0 -0
- package/lib/i18n/peer.sh +41 -0
- package/lib/i18n/peer_help.sh +25 -0
- package/lib/i18n/peer_reset.sh +7 -0
- package/lib/i18n/peer_status.sh +5 -0
- package/lib/i18n/prices.sh +3 -0
- package/lib/i18n/prices_refresh.sh +17 -0
- package/lib/i18n/prices_show.sh +7 -0
- package/lib/i18n/propose.sh +0 -0
- package/lib/i18n/release.sh +0 -0
- package/lib/i18n/research.sh +0 -0
- package/lib/i18n/review_pr.sh +0 -0
- package/lib/i18n/sentinel.sh +0 -0
- package/lib/i18n/setup.sh +3 -0
- package/lib/i18n/shared.sh +157 -0
- package/lib/i18n/skills/roll-brief.sh +47 -0
- package/lib/i18n/skills/roll-build.sh +97 -0
- package/lib/i18n/skills/roll-design.sh +18 -0
- package/lib/i18n/skills/roll-fix.sh +53 -0
- package/lib/i18n/skills/roll-loop.sh +28 -0
- package/lib/i18n/skills/roll-onboard.sh +33 -0
- package/lib/i18n/skills_catalog.sh +30 -0
- package/lib/i18n/slides.sh +3 -0
- package/lib/i18n/slides_build.sh +38 -0
- package/lib/i18n/slides_delete.sh +19 -0
- package/lib/i18n/slides_list.sh +14 -0
- package/lib/i18n/slides_logs.sh +12 -0
- package/lib/i18n/slides_new.sh +15 -0
- package/lib/i18n/slides_preview.sh +14 -0
- package/lib/i18n/slides_templates.sh +7 -0
- package/lib/i18n/status.sh +21 -0
- package/lib/i18n/update.sh +24 -0
- package/lib/i18n.sh +211 -0
- package/lib/loop-exit-summary.py +393 -0
- package/lib/loop-fmt.py +589 -0
- package/lib/loop_pick_agent.py +316 -0
- package/lib/loop_result_eval.py +469 -0
- package/lib/loop_unstick.py +180 -0
- package/lib/model_prices.py +186 -0
- package/lib/prices/README.md +35 -0
- package/lib/prices/snapshot-2026-05-22.json +22 -0
- package/lib/prices/snapshot-2026-05-23-deepseek.json +15 -0
- package/lib/prices/snapshot-2026-05-23-kimi.json +14 -0
- package/lib/prices_fetcher.py +285 -0
- package/lib/roll-backlog.py +225 -0
- package/lib/roll-brief.py +286 -0
- package/lib/roll-help.py +158 -0
- package/lib/roll-home.py +556 -0
- package/lib/roll-init.py +156 -0
- package/lib/roll-loop-status.py +1683 -0
- package/lib/roll-loop-story.py +191 -0
- package/lib/roll-onboard-render.py +378 -0
- package/lib/roll-peer.py +252 -0
- package/lib/roll-plan-validate.py +386 -0
- package/lib/roll-setup.py +102 -0
- package/lib/roll-status.py +367 -0
- package/lib/roll_git.py +41 -0
- package/lib/roll_render.py +414 -0
- package/lib/slides/components/README.md +123 -0
- package/lib/slides/components/cards-2.html +9 -0
- package/lib/slides/components/cards-3.html +9 -0
- package/lib/slides/components/cards-4.html +9 -0
- package/lib/slides/components/compare.html +22 -0
- package/lib/slides/components/highlight.html +9 -0
- package/lib/slides/components/pipeline.html +12 -0
- package/lib/slides/components/plain.html +7 -0
- package/lib/slides/components/quote.html +4 -0
- package/lib/slides/components/timeline.html +9 -0
- package/lib/slides/templates/introduction-v3.html +571 -0
- package/lib/slides/templates/pitch.html +0 -0
- package/lib/slides-render.py +778 -0
- package/lib/slides-validate.py +357 -0
- package/lib/test_quality_gate.py +143 -0
- package/package.json +8 -7
- package/skills/roll-.changelog/SKILL.md +406 -33
- package/skills/roll-.clarify/SKILL.md +5 -2
- package/skills/roll-.dream/SKILL.md +374 -0
- package/skills/roll-.echo/SKILL.md +5 -2
- package/skills/roll-.qa/SKILL.md +57 -3
- package/skills/roll-.review/SKILL.md +42 -3
- package/skills/roll-brief/SKILL.md +209 -0
- package/skills/roll-build/SKILL.md +308 -63
- package/skills/roll-debug/SKILL.md +341 -162
- package/skills/roll-debug/injectable-bb.js +263 -0
- package/skills/roll-deck/SKILL.md +296 -0
- package/skills/roll-design/ENGINEERING_CHECKLIST.md +1 -1
- package/skills/roll-design/SKILL.md +727 -94
- package/skills/roll-doc/SKILL.md +595 -0
- package/skills/roll-doctor/SKILL.md +192 -0
- package/skills/roll-fix/SKILL.md +149 -32
- package/skills/{roll-jot → roll-idea}/SKILL.md +18 -10
- package/skills/roll-loop/SKILL.md +578 -0
- package/skills/roll-notes/SKILL.md +103 -0
- package/skills/roll-onboard/SKILL.md +234 -0
- package/skills/roll-peer/SKILL.md +336 -0
- package/skills/roll-propose/SKILL.md +157 -0
- package/skills/roll-review-pr/SKILL.md +58 -0
- package/skills/roll-sentinel/SKILL.md +11 -2
- package/skills/roll-spar/SKILL.md +8 -6
- package/template/.github/workflows/ci.yml +5 -2
- package/template/AGENTS.md +20 -74
- package/skills/roll-research/SKILL.md +0 -307
- package/skills/roll-research/references/schema.json +0 -162
- package/skills/roll-research/scripts/md_to_pdf.py +0 -289
- package/tools/roll-fetch/SKILL.md +0 -182
- package/tools/roll-fetch/package.json +0 -15
- package/tools/roll-fetch/smart-web-fetch.js +0 -558
- package/tools/roll-probe/SKILL.md +0 -84
- /package/template/{BACKLOG.md → .roll/backlog.md} +0 -0
|
@@ -0,0 +1,595 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: roll-doc
|
|
3
|
+
license: MIT
|
|
4
|
+
allowed-tools: "Read, Write, Edit, Glob, Grep, Bash(date:*,find:*,stat:*,wc:*)"
|
|
5
|
+
description: "Legacy project documentation automation. Scans all docs, builds/updates docs/INDEX.md, identifies undocumented modules, and generates draft fills for gaps. Works on any project."
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# roll-doc
|
|
9
|
+
|
|
10
|
+
Four-phase legacy documentation automation (plus deep-read Phase 3b): scan → index → gap analysis → fill (directory-level) → deep read (cross-directory topics).
|
|
11
|
+
|
|
12
|
+
Works on any project root. No manual mode switching — reads the project state and decides what to do.
|
|
13
|
+
|
|
14
|
+
## When to Use
|
|
15
|
+
|
|
16
|
+
- Starting to work on a legacy project with scattered or missing documentation
|
|
17
|
+
- `docs/INDEX.md` is out of date or doesn't exist yet
|
|
18
|
+
- `roll-.dream` Scan 6 flagged undocumented modules (REFACTOR entry referencing roll-doc)
|
|
19
|
+
- You want a complete picture of what's documented and what isn't
|
|
20
|
+
|
|
21
|
+
## When Not to Use
|
|
22
|
+
|
|
23
|
+
- The project has up-to-date, maintained docs — no need to rebuild the index
|
|
24
|
+
- You need authoritative documentation reviewed and approved (drafts only; human reviews and commits)
|
|
25
|
+
- You want to write a specific known doc from scratch — write it directly
|
|
26
|
+
|
|
27
|
+
## Invocation
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
$roll-doc # Full four-phase run
|
|
31
|
+
$roll-doc --dry-run # Phases 1–2 only; print Phase 3 plan without writing any files
|
|
32
|
+
$roll-doc --force # Re-generate drafts even for existing files
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Phase 1 — Scan & Index
|
|
36
|
+
|
|
37
|
+
Scan the project root for all `*.md` files and known convention files.
|
|
38
|
+
|
|
39
|
+
**Exclusions — never scan these directories:**
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
node_modules/ .git/ dist/ build/ .shared/ .roll/dream/ .roll/briefs/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
**Convention files — detect by filename anywhere in the tree:**
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
AGENTS.md CLAUDE.md GEMINI.md CONVENTIONS.md CONTRIBUTING.md
|
|
49
|
+
ARCHITECTURE.md ADR-*.md
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**Classification rules:**
|
|
53
|
+
|
|
54
|
+
| Category | Criteria |
|
|
55
|
+
|----------|----------|
|
|
56
|
+
| `guide` | Path under `guide/` |
|
|
57
|
+
| `domain` | Path under `.roll/domain/` |
|
|
58
|
+
| `convention` | Filename matches convention markers list above |
|
|
59
|
+
| `module` | File is `<dir>/README.md` for a source directory |
|
|
60
|
+
| `stray` | None of the above (top-level, unorganized, or orphaned) |
|
|
61
|
+
|
|
62
|
+
**Output — produce/update `docs/INDEX.md`:**
|
|
63
|
+
|
|
64
|
+
```markdown
|
|
65
|
+
# Documentation Index
|
|
66
|
+
|
|
67
|
+
> Auto-generated by roll-doc on YYYY-MM-DD. Edit individual docs, not this file.
|
|
68
|
+
|
|
69
|
+
## Index
|
|
70
|
+
|
|
71
|
+
| Path | Title | Category | Last Modified |
|
|
72
|
+
|------|-------|----------|---------------|
|
|
73
|
+
| guide/en/loop.md | Loop User Guide | guide | 2026-05-01 |
|
|
74
|
+
| AGENTS.md | Agent Conventions | convention | 2026-04-28 |
|
|
75
|
+
|
|
76
|
+
## Coverage Summary
|
|
77
|
+
|
|
78
|
+
- Total docs indexed: N
|
|
79
|
+
- By category: guide (N) / domain (N) / convention (N) / module (N) / stray (N)
|
|
80
|
+
|
|
81
|
+
## Gap Report
|
|
82
|
+
|
|
83
|
+
Directories with ≥3 source files and no linked documentation:
|
|
84
|
+
|
|
85
|
+
| Directory | Source Files | Missing Doc |
|
|
86
|
+
|-----------|-------------|-------------|
|
|
87
|
+
| src/commands/ | 8 | README.md |
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
`docs/INDEX.md` is always overwritten on each run — it is a derived artifact, not authoritative content.
|
|
91
|
+
|
|
92
|
+
## Phase 2 — Gap Analysis
|
|
93
|
+
|
|
94
|
+
Walk every directory (applying Phase 1 exclusions):
|
|
95
|
+
|
|
96
|
+
1. Count non-hidden, non-`.md` source files directly in the directory
|
|
97
|
+
2. If count ≥ 3 AND no `README.md` in that directory AND no `docs/INDEX.md` entry links to it → **module gap**
|
|
98
|
+
3. **High fan-in gap**: a directory imported by **≥ 5 other source files** is a gap targeting `<dir>/README.md`, **even if it has < 3 source files** — critical low-volume modules (shared utils, single-file core) must not be skipped by the file-count threshold. The existing count ≥ 3 rule (rule 2) continues to apply independently; high fan-in only widens what qualifies, it never overrides rule 2.
|
|
99
|
+
|
|
100
|
+
**Special gaps (checked once per project):**
|
|
101
|
+
- No `.roll/domain/` directory or empty → gap: `.roll/domain/context-map.md`
|
|
102
|
+
- No `CONVENTIONS.md` or `docs/CONVENTIONS.md` exists → gap: `docs/CONVENTIONS.md`
|
|
103
|
+
|
|
104
|
+
**Threshold**: a directory qualifies for a module README gap when **file count ≥ 3 OR imported by ≥ 5 other source files** (default). The fan-in count comes from the Phase 3b symbol table `imports` edges; exclude test files (`*.test.*`, `*.spec.*`, `tests/`) when counting referencing files. An existing `<dir>/README.md` is never overwritten unless `--force`. Tune by editing the skill.
|
|
105
|
+
|
|
106
|
+
Record all gaps — they become Phase 3 input.
|
|
107
|
+
|
|
108
|
+
## Phase 3 — Fill
|
|
109
|
+
|
|
110
|
+
**Skip this phase entirely when:**
|
|
111
|
+
- `--dry-run` was passed (print the fill plan to stdout, write nothing)
|
|
112
|
+
- Phase 2 found zero gaps
|
|
113
|
+
|
|
114
|
+
**Idempotency rule**: Without `--force`, re-running when no new gaps exist is a **no-op** — no files are written, no existing drafts are modified.
|
|
115
|
+
|
|
116
|
+
For each gap:
|
|
117
|
+
1. Read up to 20 source files from the target directory to infer module purpose, key exports, dependencies, and configuration patterns
|
|
118
|
+
2. Generate a draft document at the conventional location (see table below)
|
|
119
|
+
3. **Skip if the target file already exists**, unless `--force` was passed
|
|
120
|
+
|
|
121
|
+
**Draft locations by gap type:**
|
|
122
|
+
|
|
123
|
+
| Gap Type | Draft Location |
|
|
124
|
+
|----------|---------------|
|
|
125
|
+
| Module with no README | `<dir>/README.md` |
|
|
126
|
+
| No `.roll/domain/` entries | `.roll/domain/context-map.md` |
|
|
127
|
+
| No conventions doc | `docs/CONVENTIONS.md` |
|
|
128
|
+
| Missing `AGENTS.md` `## Where to Look` section | `AGENTS.md` (append or create) |
|
|
129
|
+
|
|
130
|
+
**AGENTS.md Where to Look bootstrap:**
|
|
131
|
+
|
|
132
|
+
When `AGENTS.md` has no `## Where to Look` section, generate and append one:
|
|
133
|
+
|
|
134
|
+
1. Scan which doc directories actually exist: `.roll/domain/`, `.roll/features/`, `.roll/verification/`, etc.
|
|
135
|
+
2. Generate pointer lines **only for directories that actually exist** — never fabricate pointers to missing paths
|
|
136
|
+
3. If `.roll/domain/context-map.md` exists, read it to extract Bounded Context names for a one-line summary
|
|
137
|
+
4. Append the section to the end of `AGENTS.md` with the standard draft header
|
|
138
|
+
5. **Idempotency**: if `## Where to Look` already present, do not overwrite or duplicate — skip this gap
|
|
139
|
+
|
|
140
|
+
Draft output format:
|
|
141
|
+
|
|
142
|
+
```markdown
|
|
143
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
144
|
+
|
|
145
|
+
## Where to Look
|
|
146
|
+
- **Domain model**: `.roll/domain/context-map.md` — Contexts: {list from context-map, or "see file"}
|
|
147
|
+
- **Story details**: `.roll/features/` — AC, implementation specs, dependencies
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Only include lines for directories that already exist in the project.
|
|
151
|
+
|
|
152
|
+
**Every generated file starts with this exact header line:**
|
|
153
|
+
|
|
154
|
+
```
|
|
155
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
156
|
+
```
|
|
157
|
+
|
|
158
|
+
**Minimum draft content:**
|
|
159
|
+
|
|
160
|
+
- Module README: purpose (1–2 sentences), key files with one-line descriptions, dependencies (imports from / depended on by)
|
|
161
|
+
- Context map: bounded contexts identified in the project, their responsibilities, relationships
|
|
162
|
+
- Conventions: detected patterns — ENV vars, naming conventions, repeated file structure templates
|
|
163
|
+
|
|
164
|
+
Do not fabricate details — infer only from source files actually read.
|
|
165
|
+
|
|
166
|
+
## Phase 3b — Deep Read
|
|
167
|
+
|
|
168
|
+
Deep-read phase that builds a full project symbol table (without truncation) and auto-detects
|
|
169
|
+
cross-directory topics that directory-level Phase 3 alone cannot discover.
|
|
170
|
+
|
|
171
|
+
**Trigger conditions** — Phase 3b runs when either is true:
|
|
172
|
+
- Phase 2 found any gap (module or special gap)
|
|
173
|
+
- The project exhibits code characteristics that Phase 3a cannot capture:
|
|
174
|
+
cross-directory import chains spanning ≥ 3 directories, state enums referenced by
|
|
175
|
+
multiple files, external URL/endpoint calls, or CI pipeline configuration files
|
|
176
|
+
|
|
177
|
+
Pure documentation-only projects (no source code gaps, no code characteristics) skip Phase 3b.
|
|
178
|
+
|
|
179
|
+
### Step 1 — Build Symbol Table
|
|
180
|
+
|
|
181
|
+
Read each source file through the context-feed budget (US-CTX-001), not by hard-stuffing whole
|
|
182
|
+
files unconditionally. The existing Phase 3 "up to 20 source files" count limit does not apply —
|
|
183
|
+
Phase 3b aims for a complete project symbol table — but per-file material still goes through the
|
|
184
|
+
feed budget: files within budget are read in full, and over-budget files are summarized/chunked
|
|
185
|
+
with an explicit notice (never silently truncated) so the inner agent's context window is not
|
|
186
|
+
blown. This replaces the previous "read every source file in full, no truncation" unbounded path.
|
|
187
|
+
|
|
188
|
+
**Exclusion directories** (same as Phase 1):
|
|
189
|
+
|
|
190
|
+
```
|
|
191
|
+
node_modules/ .git/ dist/ build/ .shared/ .roll/dream/ .roll/briefs/
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
**Symbol table fields:**
|
|
195
|
+
|
|
196
|
+
| Field | Content |
|
|
197
|
+
|-------|---------|
|
|
198
|
+
| `exports` | class / interface / type / function / const declarations, per file |
|
|
199
|
+
| `imports` | source file → target file mapping (dependency graph edges) |
|
|
200
|
+
| `enums` | enum declarations with enumerated values, per file |
|
|
201
|
+
| `external_urls` | `fetch(...)` / `axios` / `http.*` calls, `API_ENDPOINT` / `*_URL` / `*_HOST` constants, hardcoded `https?://` strings (exclude comments and test fixtures) |
|
|
202
|
+
| `configs` | CI workflow YAML files, build config paths, test framework config file paths |
|
|
203
|
+
|
|
204
|
+
**`--dry-run` behavior:** print symbol table summary counts per category (e.g. "exports: 42, imports: 156, enums: 7, external_urls: 4, configs: 3") plus top-N examples per category. Write nothing to disk.
|
|
205
|
+
|
|
206
|
+
**`--force` behavior:** unchanged — `--force` only affects draft generation (Phase 3/3b output files).
|
|
207
|
+
The symbol table itself is rebuilt from scratch on every run regardless of flags.
|
|
208
|
+
|
|
209
|
+
### Step 2 — Topic Detection
|
|
210
|
+
|
|
211
|
+
Using the symbol table from Step 1, detect cross-directory topics. Each topic type has a
|
|
212
|
+
detection rule and a target output file. Skip any topic whose target file already exists
|
|
213
|
+
(unless `--force`). Skip any topic whose detection rule finds no matches.
|
|
214
|
+
|
|
215
|
+
| Topic | Detection Rule | Output |
|
|
216
|
+
|-------|---------------|--------|
|
|
217
|
+
| 数据流 / 调用链 | Entry files (`bin/`, `cmd/`, `main.*`, `index.*`) → trace import chain to leaf nodes; require ≥ 1 chain spanning ≥ 3 directories | `docs/data-flows.md` |
|
|
218
|
+
| 状态机 | Enums matching `*State` / `*Status` referenced by ≥ 2 source files | `docs/state-machines.md` |
|
|
219
|
+
| 外部集成 | `external_urls` entries from symbol table (exclude comment/test-fixture matches) | `docs/integrations.md` |
|
|
220
|
+
| 部署管线 | `.github/workflows/*.yml` / `.gitlab-ci.yml` / `circle.yml` / `Jenkinsfile` present, with deploy URL patterns detected | `docs/deployment.md` |
|
|
221
|
+
| Agent 入口 (AGENTS.md) | Project root has no `AGENTS.md` AND `src/` (or equivalent source root) has ≥ 3 subdirectories | `AGENTS.md` |
|
|
222
|
+
| 高引用目录 | Directory imported by ≥ 5 other source files, even if directory itself has < 3 source files | `<dir>/README.md` |
|
|
223
|
+
|
|
224
|
+
#### Data Flow / Import Chain Tracing
|
|
225
|
+
|
|
226
|
+
**Entry point selection:** start from entry files — any file matching patterns:
|
|
227
|
+
`bin/*`, `cmd/**/*`, `main.*` (e.g. `main.ts`, `main.py`), `index.*` (e.g. `index.ts`, `index.jsx`),
|
|
228
|
+
`App.*`, `server.*`. Exclude `node_modules/`, `dist/`, `build/`, test files (`*.test.*`, `*.spec.*`, `tests/`).
|
|
229
|
+
|
|
230
|
+
**Chain construction:**
|
|
231
|
+
1. For each entry file, read its imports from the symbol table's `imports` field.
|
|
232
|
+
2. Recursively follow each imported file to its own imports, building a directed call graph.
|
|
233
|
+
3. Stop at leaf nodes — files that import nothing or whose imports all point to:
|
|
234
|
+
- External packages (node_modules / stdlib / third-party)
|
|
235
|
+
- Already-visited nodes (cycle termination)
|
|
236
|
+
4. Each distinct path from an entry file to a leaf is one call chain.
|
|
237
|
+
|
|
238
|
+
**Threshold (cross-directory filter):**
|
|
239
|
+
A call chain is valid for inclusion only if it spans **≥ 3 distinct source directories**.
|
|
240
|
+
Count based on the unique parent directories of files in the chain:
|
|
241
|
+
`src/cli/main.ts → src/commands/build.ts → lib/utils/fs.ts` = 3 directories ✅
|
|
242
|
+
`src/cli/main.ts → src/cli/config.ts → lib/utils/fs.ts` = 2 directories ❌
|
|
243
|
+
If no chain meets the ≥ 3 directory threshold, skip generation entirely (no empty `docs/data-flows.md`).
|
|
244
|
+
|
|
245
|
+
**Output document structure** (`docs/data-flows.md`):
|
|
246
|
+
|
|
247
|
+
```markdown
|
|
248
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
249
|
+
|
|
250
|
+
# Data Flows
|
|
251
|
+
|
|
252
|
+
## Flow: {short descriptive name from entry file purpose}
|
|
253
|
+
|
|
254
|
+
**Entry point:** `{entry_file}:{line}`
|
|
255
|
+
**Directories spanned:** N ({comma-separated list})
|
|
256
|
+
|
|
257
|
+
### Complete Call Chain
|
|
258
|
+
|
|
259
|
+
{entry_file}
|
|
260
|
+
→ import {symbol} from "{file}" ({line})
|
|
261
|
+
→ import {symbol} from "{file}" ({line})
|
|
262
|
+
→ ... (leaf node)
|
|
263
|
+
|
|
264
|
+
### Files Involved
|
|
265
|
+
|
|
266
|
+
| Step | File:Line | Function / Method |
|
|
267
|
+
|------|-----------|-------------------|
|
|
268
|
+
| 1 | `path/to/file:12` | `functionName` |
|
|
269
|
+
| 2 | `path/to/file:34` | `otherFunction` |
|
|
270
|
+
| ... | ... | ... |
|
|
271
|
+
```
|
|
272
|
+
|
|
273
|
+
- Sort flows by number of directories spanned, descending (widest cross-cutting flow first).
|
|
274
|
+
- If an entry file produces multiple distinct call chains, list each one as a separate flow entry.
|
|
275
|
+
- `file:line` annotations must come from actual symbol table records — do not fabricate.
|
|
276
|
+
|
|
277
|
+
**Idempotency:** skip (do not overwrite) if `docs/data-flows.md` already exists, unless `--force`.
|
|
278
|
+
|
|
279
|
+
#### State Machine
|
|
280
|
+
|
|
281
|
+
**Detection rule:** enums whose name matches `*State` or `*Status` (case-insensitive)
|
|
282
|
+
AND that are imported/referenced by **≥ 2 distinct source files**. Only count
|
|
283
|
+
imports from source files — exclude test files (`*.test.*`, `*.spec.*`, `tests/`)
|
|
284
|
+
and declaration files (`*.d.ts`).
|
|
285
|
+
|
|
286
|
+
**Threshold:** if no enum meets the ≥ 2 cross-file reference threshold, skip
|
|
287
|
+
generation entirely (no empty `docs/state-machines.md`).
|
|
288
|
+
|
|
289
|
+
**Output document structure** (`docs/state-machines.md`):
|
|
290
|
+
|
|
291
|
+
```markdown
|
|
292
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
293
|
+
|
|
294
|
+
# State Machines
|
|
295
|
+
|
|
296
|
+
## State: `{EnumName}`
|
|
297
|
+
|
|
298
|
+
**Defined in:** `{file}:{line}`
|
|
299
|
+
|
|
300
|
+
### States
|
|
301
|
+
{list of all enum values}
|
|
302
|
+
|
|
303
|
+
### Referenced By
|
|
304
|
+
|
|
305
|
+
| File:Line | Context |
|
|
306
|
+
|-----------|---------|
|
|
307
|
+
| `path/to/file:12` | `function processOrder(status: OrderState)` |
|
|
308
|
+
| `path/to/file:34` | `if (status === OrderState.Pending)` |
|
|
309
|
+
|
|
310
|
+
### Inferred Transitions
|
|
311
|
+
|
|
312
|
+
| From | To | Evidence |
|
|
313
|
+
|------|----|----------|
|
|
314
|
+
| `Pending` | `Processing` | `order.ts:45` — `if (status === Pending) { status = Processing }` |
|
|
315
|
+
| `Processing` | `Shipped` | `handler.ts:78` — assignment after `ship()` call |
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
**Transition inference:** scan the referencing files for patterns where an enum
|
|
319
|
+
value is checked (`if (status === X)`, `case X:`) and the status variable is
|
|
320
|
+
reassigned to another enum value in the same block. Record each distinct
|
|
321
|
+
`{from, to, evidence file:line}` pair. Only include transitions backed by
|
|
322
|
+
explicit code — do not fabricate implied transitions.
|
|
323
|
+
|
|
324
|
+
**Output rules:**
|
|
325
|
+
- One top-level `## State:` section per qualifying enum, sorted alphabetically.
|
|
326
|
+
- Each enum section lists all defined values under `### States`.
|
|
327
|
+
- `file:line` annotations must come from actual symbol table records — do not fabricate.
|
|
328
|
+
- Existing `docs/state-machines.md` → skip unless `--force`.
|
|
329
|
+
- No qualifying enum → skip generation entirely (no empty document).
|
|
330
|
+
|
|
331
|
+
#### External Integrations
|
|
332
|
+
|
|
333
|
+
**Detection rule:** scan `external_urls` from the symbol table —
|
|
334
|
+
`fetch(...)` / `axios` / `http.get` (and `http.*`) calls, constants shaped like
|
|
335
|
+
`API_ENDPOINT` / `*_URL` / `*_HOST`, and hardcoded `https?://` strings. Exclude
|
|
336
|
+
matches inside comments and test fixtures (`*.test.*`, `*.spec.*`, `tests/`,
|
|
337
|
+
`fixtures/`).
|
|
338
|
+
|
|
339
|
+
**Threshold:** if no external integration is detected, skip generation entirely
|
|
340
|
+
(no empty `docs/integrations.md`).
|
|
341
|
+
|
|
342
|
+
**Output document structure** (`docs/integrations.md`):
|
|
343
|
+
|
|
344
|
+
```markdown
|
|
345
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
346
|
+
|
|
347
|
+
# External Integrations
|
|
348
|
+
|
|
349
|
+
## Integration: `{endpoint URL}`
|
|
350
|
+
|
|
351
|
+
### Call Sites
|
|
352
|
+
|
|
353
|
+
| File:Line | Timeout | Error Handling / Fallback |
|
|
354
|
+
|-----------|---------|---------------------------|
|
|
355
|
+
| `path/to/file:12` | `timeout: 5000` | `.catch` retry fallback |
|
|
356
|
+
| `path/to/file:48` | — | try/catch |
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
**Per-integration fields:**
|
|
360
|
+
- **endpoint URL** — the external URL / endpoint reached.
|
|
361
|
+
- **call file:line** — every source location calling this endpoint.
|
|
362
|
+
- **timeout config** — the value if the calling code carries a `timeout: N` field,
|
|
363
|
+
otherwise `—`.
|
|
364
|
+
- **error handling / fallback** — recorded when the calling code has a `.catch`
|
|
365
|
+
handler or a `try` / `catch` block around the call, otherwise `—`.
|
|
366
|
+
|
|
367
|
+
**Output rules:**
|
|
368
|
+
- The same endpoint reached from multiple sites is merged into **one** integration
|
|
369
|
+
section that lists **all** its call sites — never one section per call.
|
|
370
|
+
- One top-level `## Integration:` section per distinct endpoint, sorted alphabetically.
|
|
371
|
+
- `file:line` annotations must come from actual symbol table records — do not fabricate.
|
|
372
|
+
- Existing `docs/integrations.md` → skip unless `--force`.
|
|
373
|
+
- No external integration detected → skip generation entirely (no empty document).
|
|
374
|
+
|
|
375
|
+
#### Deployment Pipeline
|
|
376
|
+
|
|
377
|
+
**Detection rule:** the project has at least one CI configuration file —
|
|
378
|
+
`.github/workflows/*.yml` (or `*.yaml`) / `.gitlab-ci.yml` / `circle.yml` /
|
|
379
|
+
`.circleci/config.yml` / `Jenkinsfile` — AND a deploy URL pattern appears in the
|
|
380
|
+
code or CI config (vercel / netlify / cloudflare / firebase, or hostnames ending
|
|
381
|
+
in `*.app` / `*.dev`). Pull deploy URLs from the `configs` and `external_urls`
|
|
382
|
+
fields of the symbol table.
|
|
383
|
+
|
|
384
|
+
**Threshold:** if no CI configuration file is detected, skip generation entirely
|
|
385
|
+
(no empty `docs/deployment.md`).
|
|
386
|
+
|
|
387
|
+
**Output document structure** (`docs/deployment.md`):
|
|
388
|
+
|
|
389
|
+
```markdown
|
|
390
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
391
|
+
|
|
392
|
+
# Deployment
|
|
393
|
+
|
|
394
|
+
## Pipeline: `{ci config file}`
|
|
395
|
+
|
|
396
|
+
**CI Platform:** GitHub Actions
|
|
397
|
+
**Trigger events:** push (main), pull_request, release
|
|
398
|
+
|
|
399
|
+
### Key Jobs
|
|
400
|
+
|
|
401
|
+
| Job | File:Line | Purpose |
|
|
402
|
+
|-----|-----------|---------|
|
|
403
|
+
| `test` | `.github/workflows/deploy.yml:18` | run test suite |
|
|
404
|
+
| `build` | `.github/workflows/deploy.yml:25` | compile artifacts |
|
|
405
|
+
| `deploy` | `.github/workflows/deploy.yml:33` | deploy to Vercel |
|
|
406
|
+
|
|
407
|
+
### Deploy Targets
|
|
408
|
+
|
|
409
|
+
| URL | File:Line |
|
|
410
|
+
|-----|-----------|
|
|
411
|
+
| `https://my-app.vercel.app` | `.github/workflows/deploy.yml:14` |
|
|
412
|
+
|
|
413
|
+
### Environment Variables
|
|
414
|
+
|
|
415
|
+
| Name | File:Line |
|
|
416
|
+
|------|-----------|
|
|
417
|
+
| `NODE_ENV` | `.github/workflows/deploy.yml:11` |
|
|
418
|
+
| `VERCEL_TOKEN` | `.github/workflows/deploy.yml:12` |
|
|
419
|
+
```
|
|
420
|
+
|
|
421
|
+
**Per-pipeline fields:**
|
|
422
|
+
- **CI platform** — inferred from which config file is present (GitHub Actions /
|
|
423
|
+
GitLab CI / CircleCI / Jenkins).
|
|
424
|
+
- **trigger events** — the events that start the pipeline (`push` / `pull_request` /
|
|
425
|
+
`tag` / `release`), read from the CI config.
|
|
426
|
+
- **key jobs** — each job / stage name with its `file:line` location.
|
|
427
|
+
- **deploy target URL** — the deploy URL(s) matched by the detection rule.
|
|
428
|
+
- **environment variable names** — every env var name referenced in the CI config,
|
|
429
|
+
listed **without values** (never emit secret values, only names).
|
|
430
|
+
|
|
431
|
+
**Output rules:**
|
|
432
|
+
- One top-level `## Pipeline:` section per CI configuration file, sorted alphabetically.
|
|
433
|
+
- `file:line` annotations must come from actual symbol table / CI config records — do not fabricate.
|
|
434
|
+
- Existing `docs/deployment.md` → skip unless `--force`.
|
|
435
|
+
- No CI configuration detected → skip generation entirely (no empty document).
|
|
436
|
+
|
|
437
|
+
#### Agent Entrypoint (AGENTS.md)
|
|
438
|
+
|
|
439
|
+
This topic handles the **「文件不存在 → 创建」** case: when a project has no agent-facing
|
|
440
|
+
convention file at all, generate a complete baseline `AGENTS.md`. It is complementary to the
|
|
441
|
+
Phase 2 **"AGENTS.md Where to Look bootstrap"** rule, which handles the **「文件存在 → 补章节」**
|
|
442
|
+
case (append a missing `## Where to Look` section to an existing `AGENTS.md`). The two rules
|
|
443
|
+
never overlap — this one only fires when no `AGENTS.md` exists.
|
|
444
|
+
|
|
445
|
+
**Detection rule:** project root has **no** `AGENTS.md` AND the source root (`src/`, or the
|
|
446
|
+
equivalent — `lib/`, `app/`, `pkg/`, etc.) contains **≥ 3 subdirectories**. If `AGENTS.md`
|
|
447
|
+
already exists, skip entirely (do not overwrite unless `--force`). If the source root has
|
|
448
|
+
fewer than 3 subdirectories, skip — the project is too small to warrant a baseline doc.
|
|
449
|
+
|
|
450
|
+
**Output document structure** (`AGENTS.md`) — at minimum three required sections:
|
|
451
|
+
|
|
452
|
+
```markdown
|
|
453
|
+
> **Draft** — auto-generated by roll-doc on YYYY-MM-DD. Review before treating as authoritative.
|
|
454
|
+
|
|
455
|
+
# {Project Name}
|
|
456
|
+
|
|
457
|
+
{One-sentence positioning: what this project is, inferred from README / package metadata.}
|
|
458
|
+
|
|
459
|
+
## Where to Look
|
|
460
|
+
|
|
461
|
+
- **Domain model**: `.roll/domain/context-map.md` — Contexts: {list, or "see file"}
|
|
462
|
+
- **Story details**: `.roll/features/` — AC, implementation specs, dependencies
|
|
463
|
+
- **Doc index**: `docs/INDEX.md` — generated documentation map
|
|
464
|
+
|
|
465
|
+
## Source Layout
|
|
466
|
+
|
|
467
|
+
| Directory | Purpose |
|
|
468
|
+
|-----------|---------|
|
|
469
|
+
| `src/parser/` | tokenize and parse input (≤ 2 lines each) |
|
|
470
|
+
| `src/codegen/` | emit output artifacts |
|
|
471
|
+
| `src/cli/` | command-line entry and option wiring |
|
|
472
|
+
```
|
|
473
|
+
|
|
474
|
+
**Per-section rules:**
|
|
475
|
+
- **Project positioning** — a single sentence describing what the project does, inferred from
|
|
476
|
+
the README / package metadata; never fabricate beyond what the source supports.
|
|
477
|
+
- **`## Where to Look`** — pointer lines **only for directories that actually exist**
|
|
478
|
+
(`.roll/domain/`, `.roll/features/`, `docs/INDEX.md`, etc.); never fabricate pointers to
|
|
479
|
+
missing paths. If `.roll/domain/context-map.md` exists, read it for Bounded Context names.
|
|
480
|
+
- **Source Layout** — one row per key source subdirectory, each description **≤ 2 lines**,
|
|
481
|
+
inferred from the files actually read in the symbol table.
|
|
482
|
+
|
|
483
|
+
**Output rules:**
|
|
484
|
+
- Existing `AGENTS.md` → skip unless `--force` (never overwrite a human-authored file).
|
|
485
|
+
- Source root with < 3 subdirectories → skip generation entirely (no empty `AGENTS.md`).
|
|
486
|
+
- All three sections must be present in the generated file.
|
|
487
|
+
|
|
488
|
+
#### High Fan-in Directory (README)
|
|
489
|
+
|
|
490
|
+
This topic complements the Phase 2 file-count threshold. A directory may hold only one or two
|
|
491
|
+
source files yet be imported across the whole codebase (shared utils, a single-file core
|
|
492
|
+
module). The file-count rule (≥ 3 files) alone skips such hot paths, so high fan-in widens the
|
|
493
|
+
threshold to **「文件数 ≥ 3 OR 被 ≥ 5 个文件引用」**.
|
|
494
|
+
|
|
495
|
+
**Detection rule:** using the symbol table's `imports` edges, count the **distinct source files
|
|
496
|
+
that import any file in the directory**. If that count is **≥ 5**, the directory qualifies for a
|
|
497
|
+
`<dir>/README.md` gap, **even when it contains < 3 source files**. Only count referencing files
|
|
498
|
+
that are source files — exclude test files (`*.test.*`, `*.spec.*`, `tests/`) and files inside
|
|
499
|
+
the directory itself. This rule operates **in addition to** the Phase 2 count ≥ 3 rule, never
|
|
500
|
+
replacing it: directories meeting either condition get a README.
|
|
501
|
+
|
|
502
|
+
**Output rules:**
|
|
503
|
+
- Target file is `<dir>/README.md`, generated with the same Module README content as Phase 3
|
|
504
|
+
(purpose, key files, dependencies).
|
|
505
|
+
- Existing `<dir>/README.md` → skip unless `--force` (never overwrite).
|
|
506
|
+
- Directory imported by < 5 source files **and** holding < 3 source files → skip (no gap).
|
|
507
|
+
- A directory already qualifying under the count ≥ 3 rule is not double-counted — one README.
|
|
508
|
+
|
|
509
|
+
### Step 3 — Source Annotations
|
|
510
|
+
|
|
511
|
+
Every topic document generated in Step 2 must cite `file:line` for each claim (function call,
|
|
512
|
+
endpoint URL, state transition, CI job, import path). Annotations must come from actual
|
|
513
|
+
symbol table records — do not fabricate line numbers. Follows the same "Do not fabricate"
|
|
514
|
+
rule as Phase 3.
|
|
515
|
+
|
|
516
|
+
**Mandatory `file:line` column** — each topic document's source-reference tables MUST carry a
|
|
517
|
+
dedicated `file:line` column so the reader can jump straight to the code:
|
|
518
|
+
- 「涉及文件」/ Files Involved table → one `file:line` per row.
|
|
519
|
+
- 「引用文件」/ Referenced By table → one `file:line` per referencing site.
|
|
520
|
+
- 「调用链」/ Complete Call Chain table → one `file:line` per hop.
|
|
521
|
+
|
|
522
|
+
Do **not** fabricate a `file:line` value: every annotation MUST come from an actual symbol
|
|
523
|
+
table record (the same "Do not fabricate" rule as above). If the symbol table has no line for
|
|
524
|
+
a claim, omit the row rather than invent a location.
|
|
525
|
+
|
|
526
|
+
---
|
|
527
|
+
|
|
528
|
+
## Phase 4 — Report
|
|
529
|
+
|
|
530
|
+
After all phases complete, output a summary:
|
|
531
|
+
|
|
532
|
+
```
|
|
533
|
+
📚 roll-doc complete
|
|
534
|
+
|
|
535
|
+
Phase 1 — Index
|
|
536
|
+
N docs scanned, docs/INDEX.md updated
|
|
537
|
+
Categories: guide(N) domain(N) convention(N) module(N) stray(N)
|
|
538
|
+
|
|
539
|
+
Phase 2 — Gaps
|
|
540
|
+
N undocumented module directories found
|
|
541
|
+
N special gaps (domain map / conventions)
|
|
542
|
+
|
|
543
|
+
Phase 3 — Fill
|
|
544
|
+
N drafts generated: [list of paths]
|
|
545
|
+
N skipped (already exist; use --force to regenerate)
|
|
546
|
+
|
|
547
|
+
Phase 3b — Deep Read
|
|
548
|
+
Symbol table: exports(N) imports(N) enums(N) external_urls(N) configs(N)
|
|
549
|
+
N topic documents generated:
|
|
550
|
+
- docs/dataflow.md (data-flow) source entries: N
|
|
551
|
+
- docs/state-machines.md (state-machine) source entries: N
|
|
552
|
+
- docs/integrations.md (external-integration) source entries: N
|
|
553
|
+
N topics skipped (no matches or already exist; use --force to regenerate)
|
|
554
|
+
|
|
555
|
+
📋 Review priority (largest / most active modules first):
|
|
556
|
+
1. src/commands/README.md — 8 source files
|
|
557
|
+
2. docs/CONVENTIONS.md — 6 patterns detected
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
Each generated topic document is listed with its **path**, **type**, and **来源条目数 /
|
|
561
|
+
source entries** (how many symbol-table records back the document). When Phase 3b produced no
|
|
562
|
+
subject-level documents, print exactly one line and do **not** error:
|
|
563
|
+
|
|
564
|
+
```
|
|
565
|
+
Phase 3b: no subject-level drafts generated
|
|
566
|
+
```
|
|
567
|
+
|
|
568
|
+
If `--dry-run`, the `Phase 3b — Deep Read` section is shown the same way but every generated
|
|
569
|
+
line is tagged `(plan)` — matching Phase 3's dry-run convention (nothing is written):
|
|
570
|
+
|
|
571
|
+
```
|
|
572
|
+
Phase 3b — Deep Read (plan)
|
|
573
|
+
N topic documents would be generated:
|
|
574
|
+
- docs/dataflow.md (data-flow) source entries: N (plan)
|
|
575
|
+
```
|
|
576
|
+
|
|
577
|
+
If no gaps were found:
|
|
578
|
+
|
|
579
|
+
```
|
|
580
|
+
✅ roll-doc: no gaps found. docs/INDEX.md updated.
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
If `--dry-run`:
|
|
584
|
+
|
|
585
|
+
```
|
|
586
|
+
🔍 roll-doc --dry-run: N drafts would be generated (nothing written).
|
|
587
|
+
```
|
|
588
|
+
|
|
589
|
+
## Rules
|
|
590
|
+
|
|
591
|
+
- Never modify existing documentation files — only generate new drafts
|
|
592
|
+
- `docs/INDEX.md` is the only existing file that may be overwritten (derived artifact)
|
|
593
|
+
- Draft files are never committed by this skill — human reviews and commits them
|
|
594
|
+
- Works on any project; always read project structure before acting
|
|
595
|
+
- Do not fabricate module details — infer only from source files actually read
|