xtrm-tools 2.4.1 → 2.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -6
- package/cli/dist/index.cjs +738 -239
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/hooks.json +10 -0
- package/config/pi/extensions/core/adapter.ts +2 -14
- package/config/pi/extensions/core/guard-rules.ts +70 -0
- package/config/pi/extensions/core/session-state.ts +59 -0
- package/config/pi/extensions/main-guard.ts +10 -14
- package/config/pi/extensions/plan-mode/README.md +65 -0
- package/config/pi/extensions/plan-mode/index.ts +340 -0
- package/config/pi/extensions/plan-mode/utils.ts +168 -0
- package/config/pi/extensions/service-skills.ts +51 -7
- package/config/pi/extensions/session-flow.ts +117 -0
- package/hooks/beads-claim-sync.mjs +123 -2
- package/hooks/beads-compact-restore.mjs +41 -9
- package/hooks/beads-compact-save.mjs +36 -5
- package/hooks/beads-gate-messages.mjs +27 -1
- package/hooks/beads-stop-gate.mjs +58 -8
- package/hooks/guard-rules.mjs +86 -0
- package/hooks/hooks.json +28 -18
- package/hooks/main-guard.mjs +3 -21
- package/hooks/quality-check.cjs +1286 -0
- package/hooks/quality-check.py +345 -0
- package/hooks/session-state.mjs +138 -0
- package/package.json +2 -1
- package/project-skills/quality-gates/.claude/settings.json +1 -24
- package/skills/creating-service-skills/SKILL.md +433 -0
- package/skills/creating-service-skills/references/script_quality_standards.md +425 -0
- package/skills/creating-service-skills/references/service_skill_system_guide.md +278 -0
- package/skills/creating-service-skills/scripts/bootstrap.py +326 -0
- package/skills/creating-service-skills/scripts/deep_dive.py +304 -0
- package/skills/creating-service-skills/scripts/scaffolder.py +482 -0
- package/skills/scoping-service-skills/SKILL.md +231 -0
- package/skills/scoping-service-skills/scripts/scope.py +74 -0
- package/skills/sync-docs/SKILL.md +235 -0
- package/skills/sync-docs/evals/evals.json +89 -0
- package/skills/sync-docs/references/doc-structure.md +104 -0
- package/skills/sync-docs/references/schema.md +103 -0
- package/skills/sync-docs/scripts/context_gatherer.py +246 -0
- package/skills/sync-docs/scripts/doc_structure_analyzer.py +495 -0
- package/skills/sync-docs/scripts/validate_doc.py +365 -0
- package/skills/sync-docs-workspace/iteration-1/benchmark.json +293 -0
- package/skills/sync-docs-workspace/iteration-1/benchmark.md +13 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/outputs/result.md +210 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/outputs/result.md +101 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-1/eval-doc-audit/without_skill/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/outputs/result.md +198 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/outputs/result.md +94 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-fix-mode/without_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/outputs/result.md +237 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/outputs/result.md +134 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/grading.json +28 -0
- package/skills/sync-docs-workspace/iteration-1/eval-sprint-closeout/without_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-2/benchmark.json +297 -0
- package/skills/sync-docs-workspace/iteration-2/benchmark.md +13 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/outputs/result.md +137 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/grading.json +92 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/outputs/result.md +134 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/grading.json +86 -0
- package/skills/sync-docs-workspace/iteration-2/eval-doc-audit/without_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/outputs/result.md +193 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/grading.json +72 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/outputs/result.md +211 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/grading.json +91 -0
- package/skills/sync-docs-workspace/iteration-2/eval-fix-mode/without_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/outputs/result.md +182 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/with_skill/run-1/timing.json +1 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/outputs/result.md +222 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/grading.json +88 -0
- package/skills/sync-docs-workspace/iteration-2/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/benchmark.json +298 -0
- package/skills/sync-docs-workspace/iteration-3/benchmark.md +13 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/outputs/result.md +125 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/grading.json +97 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/with_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/outputs/result.md +144 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/grading.json +78 -0
- package/skills/sync-docs-workspace/iteration-3/eval-doc-audit/without_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/outputs/result.md +104 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/grading.json +91 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/with_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/outputs/result.md +79 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/grading.json +82 -0
- package/skills/sync-docs-workspace/iteration-3/eval-fix-mode/without_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/eval_metadata.json +27 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase1_context.json +302 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase2_drift.txt +33 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase3_analysis.json +114 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase4_fix.txt +118 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/phase5_validate.txt +38 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/outputs/result.md +158 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/grading.json +95 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/with_skill/run-1/timing.json +5 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/outputs/result.md +71 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/grading.json +90 -0
- package/skills/sync-docs-workspace/iteration-3/eval-sprint-closeout/without_skill/run-1/timing.json +5 -0
- package/skills/updating-service-skills/SKILL.md +136 -0
- package/skills/updating-service-skills/scripts/drift_detector.py +222 -0
- package/skills/using-quality-gates/SKILL.md +254 -0
- package/skills/using-service-skills/SKILL.md +108 -0
- package/skills/using-service-skills/scripts/cataloger.py +74 -0
- package/skills/using-service-skills/scripts/skill_activator.py +152 -0
- package/skills/using-service-skills/scripts/test_skill_activator.py +58 -0
- package/skills/using-xtrm/SKILL.md +34 -38
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""
|
|
3
|
+
scope.py — Read service-registry.json and output a formatted service catalog.
|
|
4
|
+
|
|
5
|
+
Used by the /scope skill to provide registry data for agent reasoning before
|
|
6
|
+
any files are touched. The agent uses this output to map a task description
|
|
7
|
+
to the relevant registered service(s).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def find_registry() -> Path | None:
|
|
17
|
+
# 1. CLAUDE_PROJECT_DIR env var (set by Claude Code hooks)
|
|
18
|
+
project_dir = os.environ.get("CLAUDE_PROJECT_DIR")
|
|
19
|
+
if project_dir:
|
|
20
|
+
p = Path(project_dir) / ".claude" / "skills" / "service-registry.json"
|
|
21
|
+
if p.exists():
|
|
22
|
+
return p
|
|
23
|
+
|
|
24
|
+
# 2. Walk up from CWD until .git boundary
|
|
25
|
+
cwd = Path.cwd()
|
|
26
|
+
for parent in [cwd, *cwd.parents]:
|
|
27
|
+
p = parent / ".claude" / "skills" / "service-registry.json"
|
|
28
|
+
if p.exists():
|
|
29
|
+
return p
|
|
30
|
+
if (parent / ".git").exists():
|
|
31
|
+
break
|
|
32
|
+
|
|
33
|
+
return None
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def main() -> None:
|
|
37
|
+
registry_path = find_registry()
|
|
38
|
+
|
|
39
|
+
if not registry_path:
|
|
40
|
+
print("ERROR: service-registry.json not found.")
|
|
41
|
+
print("Run /creating-service-skills to set up service skills first.")
|
|
42
|
+
sys.exit(1)
|
|
43
|
+
|
|
44
|
+
try:
|
|
45
|
+
with open(registry_path, encoding="utf-8") as f:
|
|
46
|
+
registry = json.load(f)
|
|
47
|
+
except json.JSONDecodeError as e:
|
|
48
|
+
print(f"ERROR: service-registry.json is malformed: {e}")
|
|
49
|
+
sys.exit(1)
|
|
50
|
+
|
|
51
|
+
services = registry.get("services", {})
|
|
52
|
+
if not services:
|
|
53
|
+
print("Registry is empty — no services registered.")
|
|
54
|
+
sys.exit(0)
|
|
55
|
+
|
|
56
|
+
print(f"Registry : {registry_path}")
|
|
57
|
+
print(f"Version : {registry.get('version', 'unknown')}")
|
|
58
|
+
print(f"Services : {len(services)} registered")
|
|
59
|
+
print("─" * 60)
|
|
60
|
+
|
|
61
|
+
for service_id, info in services.items():
|
|
62
|
+
territories = ", ".join(info.get("territory", [])) or "—"
|
|
63
|
+
print(f"\n[{service_id}]")
|
|
64
|
+
print(f" Container : {info.get('container', 'unknown')}")
|
|
65
|
+
print(f" Territory : {territories}")
|
|
66
|
+
print(f" Skill : {info.get('skill_path', 'unknown')}")
|
|
67
|
+
print(f" Description: {info.get('description', '—')}")
|
|
68
|
+
|
|
69
|
+
print("\n" + "─" * 60)
|
|
70
|
+
print("Map the task description to the service(s) above, then load their skills.")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
if __name__ == "__main__":
|
|
74
|
+
main()
|
|
@@ -0,0 +1,235 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sync-docs
|
|
3
|
+
description: >-
|
|
4
|
+
Doc audit and structural sync for xtrm projects. Use whenever the README
|
|
5
|
+
feels too long, docs are out of sync after a sprint, the CHANGELOG is behind,
|
|
6
|
+
or the user asks to "sync docs", "doc audit", "split readme", "check docs
|
|
7
|
+
health", or "detect drift". Also triggers after closing bd issues or merging
|
|
8
|
+
PRs when documentation cleanup is implied. Reads bd issues, PRs, and memories
|
|
9
|
+
to understand what changed, then runs drift detection on README.md,
|
|
10
|
+
CHANGELOG.md, and docs/ — creating missing focused files instead of a
|
|
11
|
+
monolithic README. Prefer over /documenting for any structural reorganization
|
|
12
|
+
or multi-file sync work.
|
|
13
|
+
gemini-command: sync-docs
|
|
14
|
+
version: 1.0.0
|
|
15
|
+
---
|
|
16
|
+
|
|
17
|
+
# sync-docs
|
|
18
|
+
|
|
19
|
+
Keeps documentation in sync with reality. Reads what was done (bd issues, PRs, memories), finds what's stale or structurally wrong, and fixes it with Serena precision.
|
|
20
|
+
|
|
21
|
+
## Overview
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
Phase 1: Gather context — what was done recently?
|
|
25
|
+
Phase 2: Detect drift — what's stale in SSOT memories?
|
|
26
|
+
Phase 3: Analyze structure — what's in the wrong place?
|
|
27
|
+
Phase 4: Plan + execute — fix with Serena (SKIP if audit/read-only task)
|
|
28
|
+
Phase 5: Validate — schema-check all docs/
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
**Audit vs Execute mode:** If the user asked for an audit, report, or "just check", stop after Phase 3 — do not run `--fix` or edit any files. Only proceed to Phase 4 when the user explicitly wants changes made.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## MANDATORY FIRST STEP
|
|
36
|
+
|
|
37
|
+
Activate the Serena project before any file edits:
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
mcp__serena__activate_project({ project: "<cwd>" })
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
---
|
|
44
|
+
|
|
45
|
+
## Phase 1: Gather Context
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
# If skill is installed globally:
|
|
49
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/context_gatherer.py" [--since=30]
|
|
50
|
+
|
|
51
|
+
# If running from the repo directly:
|
|
52
|
+
python3 "skills/sync-docs/scripts/context_gatherer.py" [--since=30]
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Outputs a JSON report with:
|
|
56
|
+
- Recently closed bd issues (id, title, closed date)
|
|
57
|
+
- Merged PRs (subject, merge date) from git history
|
|
58
|
+
- bd memories persisted this cycle (`bd memory list` if available)
|
|
59
|
+
- Stale Serena memories (delegates to drift_detector.py)
|
|
60
|
+
|
|
61
|
+
If no `.beads/` directory exists, falls back to git-only context. All output is JSON — read it and keep the key findings in mind for Phase 3.
|
|
62
|
+
|
|
63
|
+
---
|
|
64
|
+
|
|
65
|
+
## Phase 2: Detect SSOT Drift
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python3 "$HOME/.claude/skills/documenting/scripts/drift_detector.py" scan
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
This checks which Serena memories have `tracks:` globs matching recently modified files. If something is stale, note the memory name. You will handle it in Phase 4 using the same update steps as `/documenting` — but with Serena tools (not Edit/Write).
|
|
72
|
+
|
|
73
|
+
> **Note:** `drift_detector.py` requires `pyyaml`. If you see `ModuleNotFoundError: No module named 'yaml'`, skip Phase 2 and note it — the rest of the skill works without it. Do not `pip install` unless the user explicitly approves.
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
## Phase 3: Analyze Document Structure
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
# Analysis only (no changes) — always safe to run:
|
|
81
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py"
|
|
82
|
+
# or from repo: python3 "skills/sync-docs/scripts/doc_structure_analyzer.py"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Checks:
|
|
86
|
+
1. **README.md bloat** — flags if > 200 lines or contains sections that belong in `docs/`
|
|
87
|
+
2. **CHANGELOG.md coverage** — date gap AND version gap (package.json vs latest changelog entry)
|
|
88
|
+
3. **docs/ gaps** — expected focused files that don't exist yet
|
|
89
|
+
4. **Schema validity** — existing docs/ files missing YAML frontmatter
|
|
90
|
+
|
|
91
|
+
Reports are categorized as `BLOATED`, `EXTRACTABLE`, `MISSING`, `STALE`, `INVALID_SCHEMA`, or `OK`.
|
|
92
|
+
|
|
93
|
+
**If the task is audit/analysis only → stop here.** Summarize findings and present to the user. Do not run `--fix` without explicit intent to make changes.
|
|
94
|
+
|
|
95
|
+
Read `references/doc-structure.md` for the complete guide on what belongs in each docs/ file.
|
|
96
|
+
|
|
97
|
+
---
|
|
98
|
+
|
|
99
|
+
## Phase 4: Decide and Execute
|
|
100
|
+
|
|
101
|
+
| Situation | Action |
|
|
102
|
+
|---|---|
|
|
103
|
+
| README bloated + section belongs in docs/ | Extract → new `docs/X.md`, replace with summary + link |
|
|
104
|
+
| docs/ file missing for existing subsystem | Create `docs/X.md` with schema frontmatter |
|
|
105
|
+
| Serena memory stale | Update memory using Serena tools (see below) |
|
|
106
|
+
| bd issue closed, no doc reflects it | Update CHANGELOG + relevant doc |
|
|
107
|
+
| docs/ file schema invalid | Fix frontmatter, regenerate INDEX |
|
|
108
|
+
| Everything clean | Report "All docs in sync" and stop |
|
|
109
|
+
|
|
110
|
+
### Editing with Serena (required for all doc edits)
|
|
111
|
+
|
|
112
|
+
Never use the raw `Edit` tool on documentation files. Always go through Serena:
|
|
113
|
+
|
|
114
|
+
```javascript
|
|
115
|
+
// 1. Map structure first
|
|
116
|
+
mcp__serena__get_symbols_overview({ relative_path: "README.md", depth: 1 })
|
|
117
|
+
|
|
118
|
+
// 2. Read only the relevant section
|
|
119
|
+
mcp__serena__find_symbol({ name: "Section Name", include_body: true })
|
|
120
|
+
|
|
121
|
+
// 3. Replace section content
|
|
122
|
+
mcp__serena__replace_symbol_body({ symbol_name: "Section Name", new_body: "..." })
|
|
123
|
+
|
|
124
|
+
// 4. Insert a new section after an existing one
|
|
125
|
+
mcp__serena__insert_after_symbol({ symbol_name: "Existing Section", new_symbol: "..." })
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
The reason this matters: Serena edits are atomic and reference-safe. Direct edits on large markdown files risk corrupting heading structure or inserting duplicates.
|
|
129
|
+
|
|
130
|
+
### Auto-scaffolding missing docs/ files (--fix)
|
|
131
|
+
|
|
132
|
+
For known subsystem patterns (hooks/, policies/, skills/, etc.), run `--fix` to generate all missing scaffolds at once:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py" --fix
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Combine with `--bd-remember` to persist a summary insight for future sessions:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/doc_structure_analyzer.py" --fix --bd-remember
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
`--fix` only handles known MISSING patterns. README extraction (BLOATED/EXTRACTABLE) still requires Serena — content judgment is needed to split correctly.
|
|
145
|
+
|
|
146
|
+
### Creating a single docs/ file manually
|
|
147
|
+
|
|
148
|
+
Generate the scaffold with valid frontmatter:
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/validate_doc.py" --generate docs/hooks.md \
|
|
152
|
+
--title "Hooks Reference" --scope "hooks" --category "reference" \
|
|
153
|
+
--source-for "hooks/**/*.mjs,policies/*.json"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Then fill content using Serena. See `references/schema.md` for all frontmatter fields.
|
|
157
|
+
|
|
158
|
+
### Updating Serena memories (when drift detected)
|
|
159
|
+
|
|
160
|
+
1. Read the `<!-- INDEX -->` block only — identify stale sections
|
|
161
|
+
2. Use `mcp__serena__search_for_pattern` to jump to stale content
|
|
162
|
+
3. Use `mcp__serena__replace_symbol_body` to update
|
|
163
|
+
4. Bump `version:` (patch = content fix, minor = new section) and `updated:` in frontmatter
|
|
164
|
+
5. Regenerate INDEX:
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
python3 "$HOME/.claude/skills/documenting/scripts/validate_metadata.py" <memory-file>
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Updating CHANGELOG
|
|
171
|
+
|
|
172
|
+
```bash
|
|
173
|
+
python3 "$HOME/.claude/skills/documenting/scripts/changelog/add_entry.py" \
|
|
174
|
+
CHANGELOG.md <type> "<summary>"
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
Types: `Added`, `Changed`, `Fixed`, `Removed`.
|
|
178
|
+
|
|
179
|
+
### Persisting insights via bd remember
|
|
180
|
+
|
|
181
|
+
After significant doc work (new docs/ files created, README reorganized, major drift fixed), persist a summary for future sessions:
|
|
182
|
+
|
|
183
|
+
```bash
|
|
184
|
+
bd remember "<what was done and why>" --key sync-docs-<scope>-<YYYY-MM-DD>
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Examples:
|
|
188
|
+
```bash
|
|
189
|
+
bd remember "docs/hooks.md created — extracted from README section + 12 hook scripts cataloged" --key sync-docs-hooks-2026-03-18
|
|
190
|
+
bd remember "README trimmed from 340 to 180 lines — policies, hooks, MCP moved to docs/" --key sync-docs-readme-trim-2026-03-18
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
This is done automatically when using `--fix --bd-remember`, but do it manually too when making structural changes via Serena.
|
|
194
|
+
|
|
195
|
+
---
|
|
196
|
+
|
|
197
|
+
## Phase 5: Validate
|
|
198
|
+
|
|
199
|
+
Run schema validation on all docs/ files before finishing:
|
|
200
|
+
|
|
201
|
+
```bash
|
|
202
|
+
python3 "$HOME/.claude/skills/sync-docs/scripts/validate_doc.py" docs/
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Exits 0 if all pass. Fix any errors before reporting completion.
|
|
206
|
+
|
|
207
|
+
---
|
|
208
|
+
|
|
209
|
+
## Standard docs/ Structure
|
|
210
|
+
|
|
211
|
+
See `references/doc-structure.md` for the complete guide. At minimum, a mature xtrm project should have:
|
|
212
|
+
|
|
213
|
+
```
|
|
214
|
+
docs/
|
|
215
|
+
├── hooks.md # Hook events, scripts, and their behavior
|
|
216
|
+
├── pi-extensions.md # Pi/Copilot extension catalog
|
|
217
|
+
├── architecture.md # System design, key components
|
|
218
|
+
└── plans/ # In-progress and completed work plans
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
If any of these are missing and the project has the relevant code, create them.
|
|
222
|
+
|
|
223
|
+
---
|
|
224
|
+
|
|
225
|
+
## Relationship to /documenting
|
|
226
|
+
|
|
227
|
+
| Use `/sync-docs` when | Use `/documenting` when |
|
|
228
|
+
|---|---|
|
|
229
|
+
| Finishing a feature cycle | Just adding a CHANGELOG entry |
|
|
230
|
+
| README feels too big | Creating a single Serena memory |
|
|
231
|
+
| After merging multiple PRs | Updating one stale memory |
|
|
232
|
+
| Need bd context to know what changed | The scope is already clear |
|
|
233
|
+
| Structural reorganization needed | No structural changes needed |
|
|
234
|
+
|
|
235
|
+
`/documenting` inherits the changelog scripts from this skill. Both can run in the same repo — they don't conflict.
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
{
|
|
2
|
+
"skill_name": "sync-docs",
|
|
3
|
+
"evals": [
|
|
4
|
+
{
|
|
5
|
+
"id": 1,
|
|
6
|
+
"prompt": "I just closed a bunch of bd issues this sprint and merged 3 PRs. The README.md is getting long — can you sync the docs and make sure everything's in order? Use sync-docs.",
|
|
7
|
+
"expected_output": "Runs context_gatherer.py and doc_structure_analyzer.py, reports what was found (closed issues, PRs, any drift), identifies README extraction candidates or MISSING docs/ files, and either fixes them or gives a clear plan with next steps.",
|
|
8
|
+
"files": [],
|
|
9
|
+
"assertions": [
|
|
10
|
+
{
|
|
11
|
+
"id": "ran-context-gatherer",
|
|
12
|
+
"description": "Ran context_gatherer.py and reported bd closed issues or merged PRs from the output",
|
|
13
|
+
"check": "result.md mentions context_gatherer or bd closed issues or merged PRs with specific data"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"id": "ran-structure-analyzer",
|
|
17
|
+
"description": "Ran doc_structure_analyzer.py and used its output to identify doc issues",
|
|
18
|
+
"check": "result.md references MISSING, STALE, EXTRACTABLE, or BLOATED status from the analyzer"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"id": "concrete-action",
|
|
22
|
+
"description": "Produced at least one concrete recommendation or action (not just a vague summary)",
|
|
23
|
+
"check": "result.md names a specific file (e.g. docs/hooks.md) or section with a specific next step"
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"id": "used-skill-scripts",
|
|
27
|
+
"description": "Used the skill scripts rather than just reading files manually",
|
|
28
|
+
"check": "result.md shows script execution output, not just manual file reading"
|
|
29
|
+
}
|
|
30
|
+
]
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"id": 2,
|
|
34
|
+
"prompt": "Run sync-docs --fix on this project and remember what you did with bd.",
|
|
35
|
+
"expected_output": "Runs doc_structure_analyzer.py --fix --bd-remember, creates scaffold files for any missing docs/ subsystems, persists a bd memory with the summary, then validates the created files with validate_doc.py.",
|
|
36
|
+
"files": [],
|
|
37
|
+
"assertions": [
|
|
38
|
+
{
|
|
39
|
+
"id": "ran-fix-flag",
|
|
40
|
+
"description": "Ran doc_structure_analyzer.py with --fix flag",
|
|
41
|
+
"check": "result.md shows the --fix command was executed"
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "ran-bd-remember",
|
|
45
|
+
"description": "Ran with --bd-remember or manually ran bd remember with a summary",
|
|
46
|
+
"check": "result.md shows bd remember was called and reports the memory key"
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
"id": "scaffold-created",
|
|
50
|
+
"description": "At least one scaffold file was created in docs/",
|
|
51
|
+
"check": "result.md lists a docs/*.md file created, OR reports no gaps found (valid outcome)"
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "validated-schema",
|
|
55
|
+
"description": "Ran validate_doc.py on created files to confirm schema",
|
|
56
|
+
"check": "result.md shows validate_doc.py was run and reports pass/fail for created files"
|
|
57
|
+
}
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"id": 3,
|
|
62
|
+
"prompt": "Do a doc audit. I think the README has sections that should be in docs/ but I'm not sure which ones.",
|
|
63
|
+
"expected_output": "Runs the full 5-phase sync-docs workflow: gathers context, runs drift detection, runs doc_structure_analyzer.py, identifies EXTRACTABLE/BLOATED sections with specific suggestions for what goes in which docs/ file, and uses Serena to map README structure before recommending or making changes.",
|
|
64
|
+
"files": [],
|
|
65
|
+
"assertions": [
|
|
66
|
+
{
|
|
67
|
+
"id": "ran-analyzer",
|
|
68
|
+
"description": "Ran doc_structure_analyzer.py and referenced its structured output",
|
|
69
|
+
"check": "result.md cites the analyzer output (EXTRACTABLE, BLOATED, line count, or specific section names from the report)"
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
"id": "named-specific-sections",
|
|
73
|
+
"description": "Named specific README sections with their suggested docs/ destination",
|
|
74
|
+
"check": "result.md lists at least 2 specific sections (e.g. '## Policy System → docs/policies.md') not just generic advice"
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
"id": "actionable-report",
|
|
78
|
+
"description": "Report is actionable — tells user exactly what to do next, not just observations",
|
|
79
|
+
"check": "result.md includes a prioritized list or clear next steps, not just 'the README could be shorter'"
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
"id": "no-edits-made",
|
|
83
|
+
"description": "Did not edit or create any files (audit only)",
|
|
84
|
+
"check": "result.md does not claim to have modified README.md or created docs/ files"
|
|
85
|
+
}
|
|
86
|
+
]
|
|
87
|
+
}
|
|
88
|
+
]
|
|
89
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# docs/ Structure Guide
|
|
2
|
+
|
|
3
|
+
This reference defines what belongs in each focused docs/ file vs README.md and `.serena/memories/`.
|
|
4
|
+
|
|
5
|
+
## The Rule
|
|
6
|
+
|
|
7
|
+
**README.md** is an entry point — a quick-start and orientation map. It should be < 200 lines. Anything that requires more than a few bullet points belongs in a focused docs/ file.
|
|
8
|
+
|
|
9
|
+
**docs/** holds focused, public-facing SSOT files for each subsystem. Each file:
|
|
10
|
+
- Has YAML frontmatter (see `schema.md`)
|
|
11
|
+
- Covers exactly one subsystem or concern
|
|
12
|
+
- Is linked from README.md with a single line
|
|
13
|
+
|
|
14
|
+
**.serena/memories/** holds internal AI memory — architecture decisions, patterns, workflows — for the AI agents themselves. These are not user docs.
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## What Goes Where
|
|
19
|
+
|
|
20
|
+
| Content Type | Location | When to Create |
|
|
21
|
+
|---|---|---|
|
|
22
|
+
| Quick start, one-liner install | `README.md` | Always |
|
|
23
|
+
| Feature overview table | `README.md` | Always, < 20 lines |
|
|
24
|
+
| Hook events, scripts, behavior | `docs/hooks.md` | When hooks/ dir exists |
|
|
25
|
+
| Pi/Copilot extension catalog | `docs/pi-extensions.md` | When config/pi/extensions/ exists |
|
|
26
|
+
| System architecture, components | `docs/architecture.md` | When > 2 major subsystems |
|
|
27
|
+
| Policy rules and enforcement | `docs/policies.md` | When policies/ dir exists |
|
|
28
|
+
| MCP server config and usage | `docs/mcp-servers.md` | When .mcp.json or mcp servers exist |
|
|
29
|
+
| Skills catalog | `docs/skills.md` | When skills/ dir has > 5 skills |
|
|
30
|
+
| CLI commands reference | `docs/cli-reference.md` | When CLI has > 10 commands |
|
|
31
|
+
| Troubleshooting and FAQs | `docs/troubleshooting.md` | When recurring issues exist |
|
|
32
|
+
| In-progress work plans | `docs/plans/` | Always for planning docs |
|
|
33
|
+
| Architecture decisions (AI) | `.serena/memories/*_ssot.md` | For AI context only |
|
|
34
|
+
| Implementation patterns (AI) | `.serena/memories/*_pattern.md` | For AI context only |
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Standard File Shapes
|
|
39
|
+
|
|
40
|
+
### docs/hooks.md
|
|
41
|
+
Covers: hook events, what triggers each hook, which scripts run, output format.
|
|
42
|
+
Section outline:
|
|
43
|
+
```
|
|
44
|
+
## Overview
|
|
45
|
+
## Hook Events
|
|
46
|
+
## Scripts Reference
|
|
47
|
+
## Adding a New Hook
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### docs/pi-extensions.md
|
|
51
|
+
Covers: what Pi extensions are installed, their events, behavior, and configuration.
|
|
52
|
+
Section outline:
|
|
53
|
+
```
|
|
54
|
+
## Overview
|
|
55
|
+
## Installed Extensions
|
|
56
|
+
## Extension Events
|
|
57
|
+
## Configuration
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### docs/architecture.md
|
|
61
|
+
Covers: system overview, key components, data flow, dependency diagram.
|
|
62
|
+
Section outline:
|
|
63
|
+
```
|
|
64
|
+
## System Overview
|
|
65
|
+
## Key Components
|
|
66
|
+
## Data Flow
|
|
67
|
+
## Directory Structure
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### docs/policies.md
|
|
71
|
+
Covers: what policies exist, what each enforces, runtime targets.
|
|
72
|
+
Section outline:
|
|
73
|
+
```
|
|
74
|
+
## Overview
|
|
75
|
+
## Policy Files
|
|
76
|
+
## Policy Compiler
|
|
77
|
+
## Adding a Policy
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Detecting When README is Too Big
|
|
83
|
+
|
|
84
|
+
The `doc_structure_analyzer.py` script flags README as `BLOATED` when:
|
|
85
|
+
1. Line count > 200, AND
|
|
86
|
+
2. At least one section has a matching `docs/` file that doesn't exist yet
|
|
87
|
+
|
|
88
|
+
The `EXTRACTABLE` status means sections are present but README isn't over threshold yet — worth noting but not urgent.
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## Extraction Process
|
|
93
|
+
|
|
94
|
+
When extracting a section from README to docs/:
|
|
95
|
+
|
|
96
|
+
1. Run `mcp__serena__get_symbols_overview` on README.md to map all sections
|
|
97
|
+
2. Use `mcp__serena__find_symbol` to read the target section body
|
|
98
|
+
3. Create `docs/X.md` with `validate_doc.py --generate`
|
|
99
|
+
4. Paste the section content into the new file
|
|
100
|
+
5. Use `mcp__serena__replace_symbol_body` to replace README section with:
|
|
101
|
+
```markdown
|
|
102
|
+
See [docs/X.md](docs/X.md) for the full reference.
|
|
103
|
+
```
|
|
104
|
+
6. Run `validate_doc.py docs/X.md` to confirm schema
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# docs/ File Schema
|
|
2
|
+
|
|
3
|
+
Every file in `docs/` must have YAML frontmatter. This is enforced by `validate_doc.py`.
|
|
4
|
+
|
|
5
|
+
## Frontmatter Fields
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
---
|
|
9
|
+
title: Human Readable Title # required — clear, descriptive
|
|
10
|
+
scope: kebab-case-identifier # required — unique slug for this doc
|
|
11
|
+
category: reference # required — see valid values below
|
|
12
|
+
version: 1.0.0 # required — semver (x.y.z)
|
|
13
|
+
updated: 2026-03-18 # required — ISO date of last update
|
|
14
|
+
description: "One-line summary" # optional
|
|
15
|
+
source_of_truth_for: # optional — glob patterns this doc describes
|
|
16
|
+
- "hooks/**/*.mjs"
|
|
17
|
+
- "policies/*.json"
|
|
18
|
+
domain: [hooks, claude, policy] # optional — cross-cutting tags
|
|
19
|
+
---
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Required Fields
|
|
23
|
+
|
|
24
|
+
| Field | Type | Description | Example |
|
|
25
|
+
|-------|------|-------------|---------|
|
|
26
|
+
| `title` | string | Clear, descriptive title | "Hooks Reference" |
|
|
27
|
+
| `scope` | string | Unique kebab-case slug | "hooks" |
|
|
28
|
+
| `category` | enum | Document type | "reference" |
|
|
29
|
+
| `version` | semver | x.y.z — bump on every update | "1.2.0" |
|
|
30
|
+
| `updated` | date | YYYY-MM-DD of last change | "2026-03-18" |
|
|
31
|
+
|
|
32
|
+
## Category Values
|
|
33
|
+
|
|
34
|
+
| Value | Purpose |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `reference` | Look-up table, cheat sheet, technical spec |
|
|
37
|
+
| `guide` | Step-by-step how-to documentation |
|
|
38
|
+
| `architecture` | System design and component overview |
|
|
39
|
+
| `api` | API contracts, interfaces, schemas |
|
|
40
|
+
| `plan` | Implementation plan or roadmap |
|
|
41
|
+
| `overview` | Summary introduction to a subsystem |
|
|
42
|
+
|
|
43
|
+
## Optional Fields
|
|
44
|
+
|
|
45
|
+
### source_of_truth_for
|
|
46
|
+
A list of glob patterns (fnmatch syntax) pointing to the source files this doc describes. Used by `drift_detector.py` and `doc_structure_analyzer.py` to detect when the source changed but the doc wasn't updated.
|
|
47
|
+
|
|
48
|
+
```yaml
|
|
49
|
+
source_of_truth_for:
|
|
50
|
+
- "hooks/**/*.mjs"
|
|
51
|
+
- "policies/*.json"
|
|
52
|
+
- "config/pi/extensions/**/*.ts"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### domain
|
|
56
|
+
Tags for cross-cutting concerns. Useful for searching related docs.
|
|
57
|
+
|
|
58
|
+
```yaml
|
|
59
|
+
domain: [hooks, claude, pi, enforcement]
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Version Bumping Rules
|
|
63
|
+
|
|
64
|
+
| Change | Bump |
|
|
65
|
+
|---|---|
|
|
66
|
+
| Fix a typo or outdated detail | `patch` (1.0.0 → 1.0.1) |
|
|
67
|
+
| Add a new section | `minor` (1.0.0 → 1.1.0) |
|
|
68
|
+
| Full rewrite or restructure | `major` (1.0.0 → 2.0.0) |
|
|
69
|
+
|
|
70
|
+
Always update `updated:` to today's date alongside the version bump.
|
|
71
|
+
|
|
72
|
+
## INDEX Block
|
|
73
|
+
|
|
74
|
+
`validate_doc.py` auto-generates a navigation table from `##` headings:
|
|
75
|
+
|
|
76
|
+
```markdown
|
|
77
|
+
<!-- INDEX: auto-generated by validate_doc.py — do not edit manually -->
|
|
78
|
+
| Section | Summary |
|
|
79
|
+
|---|---|
|
|
80
|
+
| [Overview](#overview) | ... |
|
|
81
|
+
| [Hook Events](#hook-events) | ... |
|
|
82
|
+
<!-- END INDEX -->
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
This block is regenerated every time `validate_doc.py` runs on the file. Do not edit it manually.
|
|
86
|
+
|
|
87
|
+
## Complete Example
|
|
88
|
+
|
|
89
|
+
```yaml
|
|
90
|
+
---
|
|
91
|
+
title: Hooks Reference
|
|
92
|
+
scope: hooks
|
|
93
|
+
category: reference
|
|
94
|
+
version: 1.1.0
|
|
95
|
+
updated: 2026-03-18
|
|
96
|
+
description: "All hook events, scripts, and behavior for the xtrm plugin"
|
|
97
|
+
source_of_truth_for:
|
|
98
|
+
- "hooks/**/*.mjs"
|
|
99
|
+
- "policies/beads.json"
|
|
100
|
+
- "policies/main-guard.json"
|
|
101
|
+
domain: [hooks, claude, enforcement]
|
|
102
|
+
---
|
|
103
|
+
```
|