@nurix/etna 0.1.2 → 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/README.md +34 -27
- package/bin/etna.js +82 -52
- package/data/harness-index.json +2 -8
- package/data/harnesses/code/CLAUDE.md +18 -9
- package/data/harnesses/code/agents/change-review.md +80 -0
- package/data/harnesses/code/agents/contract-monitor.md +65 -0
- package/data/harnesses/code/agents/dep-health.md +148 -0
- package/data/harnesses/code/agents/git-history.md +201 -0
- package/data/harnesses/code/agents/maintenance.md +112 -0
- package/data/harnesses/code/agents/review.md +109 -0
- package/data/harnesses/code/agents/spec-mode.md +56 -0
- package/data/harnesses/code/rules/general.md +96 -0
- package/data/harnesses/code/rules/nomenclature.md +34 -0
- package/data/harnesses/code/scripts/build-ownership-index.sh +138 -0
- package/data/harnesses/code/scripts/check-doc-drift.sh +125 -0
- package/data/harnesses/code/skills/documentation/SKILL.md +238 -0
- package/data/harnesses/code/skills/documentation/references/examples.md +193 -0
- package/data/harnesses/code/skills/documentation/references/style-guide.md +288 -0
- package/data/harnesses/code/skills/documentation/references/templates.md +901 -0
- package/data/harnesses/code/skills/introspect/SKILL.md +135 -0
- package/data/harnesses/code/skills/workflow-mapper/SKILL.md +430 -0
- package/data/harnesses/code/skills/workflow-mapper/references/patterns.md +214 -0
- package/data/harnesses/kb-agi/CLAUDE.md +57 -0
- package/data/harnesses/kb-agi/agents/kb-agi-init.md +276 -0
- package/data/harnesses/kb-agi/agents/kb-catch-stale.md +22 -0
- package/data/harnesses/kb-agi/agents/kb-find-gaps.md +27 -0
- package/data/harnesses/kb-agi/agents/kb-fix-links.md +22 -0
- package/data/harnesses/kb-agi/agents/kb-refresh-frontdoor.md +22 -0
- package/data/harnesses/kb-agi/agents/kb-refresh-summaries.md +22 -0
- package/data/harnesses/kb-agi/agents/kb-sync-metadata.md +25 -0
- package/data/harnesses/kb-agi/rules/kb.md +13 -0
- package/package.json +1 -1
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Technology Choices & Standards
|
|
6
|
+
|
|
7
|
+
Opinionated technology stack and implementation standards.
|
|
8
|
+
|
|
9
|
+
## Environment & Versions
|
|
10
|
+
|
|
11
|
+
### Runtime Versions
|
|
12
|
+
|
|
13
|
+
- **Node.js:** 22 LTS (latest)
|
|
14
|
+
- **Package manager:** project-determined — detect from lockfile (`pnpm-lock.yaml` → pnpm, `yarn.lock` → yarn, `package-lock.json` → npm). Use the matching command in scripts; don't hardcode a specific manager.
|
|
15
|
+
- **PostgreSQL:** 17
|
|
16
|
+
- **Redis:** 7.x (latest)
|
|
17
|
+
|
|
18
|
+
### Recommended Packages
|
|
19
|
+
|
|
20
|
+
No alternatives. No explanations for obvious choices. Just use these.
|
|
21
|
+
|
|
22
|
+
| Package | Version | Use | Don't use |
|
|
23
|
+
| ------------------------ | --------- | ---------------------- | ----------------------- |
|
|
24
|
+
| react | ^19.2.3 | UI components | - |
|
|
25
|
+
| vite | ^8.0.0 | Build tool, dev server | webpack, CRA |
|
|
26
|
+
| tailwindcss | ^4.1.18 | Styling | styled-components |
|
|
27
|
+
| @vitejs/plugin-react-swc | ^4.2.2 | JSX compilation | @vitejs/plugin-react |
|
|
28
|
+
| react-router-dom | ^7.11.0 | Routing | - |
|
|
29
|
+
| @reduxjs/toolkit | ^2.11.2 | State management | zustand, jotai |
|
|
30
|
+
| react-redux | ^9.2.0 | Redux React bindings | - |
|
|
31
|
+
| axios | ^1.13.2 | HTTP requests | fetch |
|
|
32
|
+
| date-fns | ^4.1.0 | Date formatting | moment, dayjs |
|
|
33
|
+
| @dnd-kit/core | ^6.3.1 | Drag and drop | react-beautiful-dnd |
|
|
34
|
+
| motion | ^12.23.26 | Animations | react-spring |
|
|
35
|
+
| sonner | ^2.0.7 | Toast notifications | react-toastify |
|
|
36
|
+
| react-window | ^2.2.3 | List virtualization | react-virtualized |
|
|
37
|
+
| nanoid | ^5.1.6 | ID generation | uuid |
|
|
38
|
+
| express | ^5.2.1 | HTTP server | fastify, koa |
|
|
39
|
+
| prisma | ^7.2.0 | Database ORM | sequelize, typeorm |
|
|
40
|
+
| @prisma/client | ^7.2.0 | Database queries | - |
|
|
41
|
+
| zod | ^4.2.1 | Schema validation | yup, joi |
|
|
42
|
+
| jose | ^6.1.3 | JWT handling | jsonwebtoken |
|
|
43
|
+
| microdiff | ^1.5.0 | JSON object diffing | deep-diff, just-diff |
|
|
44
|
+
| react18-json-view | ^0.2.9 | JSON tree view | react-json-view |
|
|
45
|
+
| @tiptap/react | ^3.11.1 | Rich text editor | slate, quill, draft-js |
|
|
46
|
+
| shiki | ^3.22.0 | Syntax highlighting | prism, highlight.js |
|
|
47
|
+
| lucide-react | ^0.562.0 | Icons | react-icons, heroicons |
|
|
48
|
+
| @pdfme/generator | ^5.5.8 | PDF generation | jspdf, pdfkit |
|
|
49
|
+
| cmdk | ^1.1.1 | Command palette | kbar, ninja-keys |
|
|
50
|
+
| @monaco-editor/react | ^4.7.0 | Code editor | codemirror, ace |
|
|
51
|
+
| localforage | ^1.10.0 | Client-side storage | idb, dexie |
|
|
52
|
+
| socket.io-client | ^4.7.0 | WebSocket client | native WebSocket, ws |
|
|
53
|
+
| react-markdown | ^10.1.0 | Markdown rendering | marked, markdown-it |
|
|
54
|
+
| fast-deep-equal | ^3.1.3 | Deep equality checks | lodash.isEqual |
|
|
55
|
+
| @ngneat/falso | latest | Fake data generation | @faker-js/faker, chance |
|
|
56
|
+
| pino | ^10.1.0 | Logging | winston |
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## Express 5.x Setup
|
|
61
|
+
|
|
62
|
+
```javascript
|
|
63
|
+
app.use(cors({ origin: process.env.FRONTEND_URL }));
|
|
64
|
+
app.use(compression());
|
|
65
|
+
app.use(express.json({ limit: "10mb" }));
|
|
66
|
+
app.use(rateLimit({ windowMs: 15 * 60 * 1000, max: 100 }));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
- Middleware order: body parsers, custom middleware, routes, error handlers
|
|
70
|
+
- Use Express Router for modular routes
|
|
71
|
+
- Centralized error handler as last middleware
|
|
72
|
+
- Use middleware for auth
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## API Response Format
|
|
77
|
+
|
|
78
|
+
```json
|
|
79
|
+
{
|
|
80
|
+
"status": 1,
|
|
81
|
+
"message": "Message sent successfully",
|
|
82
|
+
"data": { "delivered": [{ "user@example.com": 2 }] }
|
|
83
|
+
}
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
**Error:**
|
|
87
|
+
|
|
88
|
+
```json
|
|
89
|
+
{
|
|
90
|
+
"status": 0,
|
|
91
|
+
"message": "Error description",
|
|
92
|
+
"data": null
|
|
93
|
+
}
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
HTTP codes: `200`, `201` (created), `400`, `401` (not authenticated), `403` (not authorized), `404`, `500`
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
applyTo: "**"
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Nomenclature Guidelines
|
|
6
|
+
|
|
7
|
+
## Naming Guidelines
|
|
8
|
+
|
|
9
|
+
- Use descriptive names that reveal intent, purpose, and usage
|
|
10
|
+
- Names should explain why something exists and how it's used
|
|
11
|
+
- Favor clarity over brevity
|
|
12
|
+
- Maintain consistency within the codebase
|
|
13
|
+
- Avoid abbreviations unless they're universally understood
|
|
14
|
+
|
|
15
|
+
## Naming Styles
|
|
16
|
+
|
|
17
|
+
- Variables : Use nouns or noun phrases. Examples: `userData`, `firstName`, `paymentStatus`, `configOptions`
|
|
18
|
+
- Functions & Methods : Use verbs or verb phrases that describe the action. Examples: `calculateTotal`, `getUserInfo`, `validateInput`, `sendNotification`
|
|
19
|
+
- Boolean Variables : Prefix with is**, has**, can**, or should**. Examples: `isValid`, `hasPermission`, `canEdit`, `shouldRefresh`
|
|
20
|
+
- Arrays : Use plural nouns. Examples: `users`, `productList`, `errorMessages`, `activeConnections`
|
|
21
|
+
- Classes & Components : Use singular nouns or noun phrases. Examples: `RequestHandler`, `UserProfile`, `PaymentProcessor`, `DataValidator`
|
|
22
|
+
- Constants : Use uppercase with meaningful names. Examples: `DEFAULT_TIMEOUT`, `API_BASE_URL`, `MAX_RETRY_COUNT`, `COLOR_PRIMARY`
|
|
23
|
+
- Event Handlers : Use Prefix with handle or on. Examples: `handleSubmit`, `onUserLogin`, `handleInputChange`, `onPageLoad`
|
|
24
|
+
- Interfaces & Types : Use Consider prefixing with I for interfaces (if preferred). Examples: `IUserData`, `IConfigOptions`, `AuthResponse`, `RequestParams`
|
|
25
|
+
- Promises & Async Functions : Use Consider using future tense or suffixes like Async. Examples: `fetchUserData`, `getUserProfileAsync`, `loadConfigAsync`, `processPayment`
|
|
26
|
+
- File & Folder Structure : Use lowercase with descriptive names. Group by feature or function type. Example: `auth/login_service.js`
|
|
27
|
+
|
|
28
|
+
## Casing Styles
|
|
29
|
+
|
|
30
|
+
- camelCase : Used in Variables, function names, method names, property names. Examples: `userData`, `calculateTotal`, `firstName`, `isValidEmail`
|
|
31
|
+
- PascalCase : Used in Class names, component names, type definitions. Examples: `UserProfile`, `DataService`, `AuthProvider`, `RequestHandler`
|
|
32
|
+
- snake_case : Used in File names, folder names. Examples: `user_service`, `api_utils`, `auth_middleware`, `data_models`
|
|
33
|
+
- UPPER_SNAKE_CASE : Used in Constants, environment variables. Examples: `MAX_RETRY_COUNT`, `API_KEY`, `DEFAULT_TIMEOUT`, `COLOR_PRIMARY`
|
|
34
|
+
- kebab-case : Used in URLs, CSS class names, HTML IDs. Examples: `nav-container`, `user-profile`, `button-primary`, `form-wrapper`
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/build-ownership-index.sh - Generate docs/OWNERSHIP_INDEX.md from feature doc frontmatter
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
7
|
+
OUTPUT="$REPO_ROOT/docs/OWNERSHIP_INDEX.md"
|
|
8
|
+
FEATURES_DIR="$REPO_ROOT/docs/features"
|
|
9
|
+
TMP_OWNS=$(mktemp)
|
|
10
|
+
TMP_DEPS=$(mktemp)
|
|
11
|
+
TMP_DIRS=$(mktemp)
|
|
12
|
+
trap 'rm -f "$TMP_OWNS" "$TMP_DEPS" "$TMP_DIRS"' EXIT
|
|
13
|
+
|
|
14
|
+
# Extract YAML frontmatter list field values from a markdown file
|
|
15
|
+
extract_field() {
|
|
16
|
+
local file="$1" field="$2"
|
|
17
|
+
awk -v field="$field" '
|
|
18
|
+
/^---$/ { fm++; next }
|
|
19
|
+
fm == 1 && $0 ~ "^"field":" {
|
|
20
|
+
in_field = 1
|
|
21
|
+
sub("^"field":[ ]*", "")
|
|
22
|
+
if ($0 != "" && $0 !~ /^\[/) { print $0; in_field = 0 }
|
|
23
|
+
next
|
|
24
|
+
}
|
|
25
|
+
fm == 1 && in_field && /^ +- / {
|
|
26
|
+
sub("^ +- ", "")
|
|
27
|
+
gsub(/^[ \t]+|[ \t]+$/, "")
|
|
28
|
+
print
|
|
29
|
+
next
|
|
30
|
+
}
|
|
31
|
+
fm == 1 && in_field && /^[a-z]/ { in_field = 0 }
|
|
32
|
+
fm == 1 && in_field && /^---$/ { in_field = 0 }
|
|
33
|
+
fm >= 2 { exit }
|
|
34
|
+
' "$file"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
# Collect ownership and dependency data from all feature docs
|
|
38
|
+
find "$FEATURES_DIR" -name "*.md" ! -name "README.md" -print0 | sort -z | while IFS= read -r -d '' file; do
|
|
39
|
+
rel_path="${file#$REPO_ROOT/}"
|
|
40
|
+
|
|
41
|
+
extract_field "$file" "owns" | while IFS= read -r pattern; do
|
|
42
|
+
[ -z "$pattern" ] && continue
|
|
43
|
+
printf '%s\t%s\n' "$pattern" "$rel_path" >> "$TMP_OWNS"
|
|
44
|
+
done
|
|
45
|
+
|
|
46
|
+
deps=$(extract_field "$file" "depends_on" | tr '\n' ', ' | sed 's/,$//' | sed 's/, $//')
|
|
47
|
+
if [ -n "$deps" ]; then
|
|
48
|
+
printf '%s\t%s\n' "$rel_path" "$deps" >> "$TMP_DEPS"
|
|
49
|
+
fi
|
|
50
|
+
done
|
|
51
|
+
|
|
52
|
+
# Collect owned directory prefixes for unowned path detection
|
|
53
|
+
sed 's|/\*\*$||; s|/\*$||; s|/[^/]*$||' "$TMP_OWNS" | awk -F'\t' '{ print $1 }' | sort -u > "$TMP_DIRS"
|
|
54
|
+
|
|
55
|
+
# Find unowned src/ directories
|
|
56
|
+
unowned=""
|
|
57
|
+
if [ -d "$REPO_ROOT/src" ]; then
|
|
58
|
+
for dir in "$REPO_ROOT"/src/*/; do
|
|
59
|
+
[ -d "$dir" ] || continue
|
|
60
|
+
rel_dir="${dir#$REPO_ROOT/}"
|
|
61
|
+
rel_dir="${rel_dir%/}"
|
|
62
|
+
is_owned=0
|
|
63
|
+
while IFS= read -r owned; do
|
|
64
|
+
case "$rel_dir" in
|
|
65
|
+
"$owned"*) is_owned=1; break ;;
|
|
66
|
+
esac
|
|
67
|
+
case "$owned" in
|
|
68
|
+
"$rel_dir"*) is_owned=1; break ;;
|
|
69
|
+
esac
|
|
70
|
+
done < "$TMP_DIRS"
|
|
71
|
+
if [ "$is_owned" -eq 0 ]; then
|
|
72
|
+
unowned="${unowned}- \`${rel_dir}\`
|
|
73
|
+
"
|
|
74
|
+
fi
|
|
75
|
+
done
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Generate output
|
|
79
|
+
cat > "$OUTPUT" << 'HEADER'
|
|
80
|
+
# Ownership Index
|
|
81
|
+
|
|
82
|
+
> **Generated file** — do not edit manually.
|
|
83
|
+
> Regenerate with: `bash scripts/build-ownership-index.sh`
|
|
84
|
+
|
|
85
|
+
Machine-readable lookup table generated from feature doc frontmatter.
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
89
|
+
## By Code Path
|
|
90
|
+
|
|
91
|
+
| Code Path | Owning Doc |
|
|
92
|
+
|---|---|
|
|
93
|
+
HEADER
|
|
94
|
+
|
|
95
|
+
sort "$TMP_OWNS" | while IFS=$'\t' read -r pattern doc; do
|
|
96
|
+
echo "| \`$pattern\` | \`$doc\` |" >> "$OUTPUT"
|
|
97
|
+
done
|
|
98
|
+
|
|
99
|
+
cat >> "$OUTPUT" << 'SECTION'
|
|
100
|
+
|
|
101
|
+
---
|
|
102
|
+
|
|
103
|
+
## Unowned Paths
|
|
104
|
+
|
|
105
|
+
Top-level `src/` directories with no owning feature doc:
|
|
106
|
+
|
|
107
|
+
SECTION
|
|
108
|
+
|
|
109
|
+
if [ -z "$unowned" ]; then
|
|
110
|
+
echo "_All top-level src/ directories have owners._" >> "$OUTPUT"
|
|
111
|
+
else
|
|
112
|
+
printf '%s' "$unowned" >> "$OUTPUT"
|
|
113
|
+
fi
|
|
114
|
+
|
|
115
|
+
cat >> "$OUTPUT" << 'SECTION'
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## Dependency Graph
|
|
120
|
+
|
|
121
|
+
Feature docs and their declared `depends_on` relationships:
|
|
122
|
+
|
|
123
|
+
| Feature Doc | Depends On |
|
|
124
|
+
|---|---|
|
|
125
|
+
SECTION
|
|
126
|
+
|
|
127
|
+
if [ -s "$TMP_DEPS" ]; then
|
|
128
|
+
sort "$TMP_DEPS" | while IFS=$'\t' read -r doc deps; do
|
|
129
|
+
echo "| \`$doc\` | $deps |" >> "$OUTPUT"
|
|
130
|
+
done
|
|
131
|
+
fi
|
|
132
|
+
|
|
133
|
+
echo "" >> "$OUTPUT"
|
|
134
|
+
echo "---" >> "$OUTPUT"
|
|
135
|
+
echo "" >> "$OUTPUT"
|
|
136
|
+
echo "_Generated: $(date -u '+%Y-%m-%d %H:%M UTC')_" >> "$OUTPUT"
|
|
137
|
+
|
|
138
|
+
echo "Generated $OUTPUT"
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# scripts/check-doc-drift.sh - Detect potentially stale docs based on recent code changes
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
DAYS="${1:-14}"
|
|
7
|
+
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
8
|
+
FEATURES_DIR="$REPO_ROOT/docs/features"
|
|
9
|
+
TMP_OWNS=$(mktemp)
|
|
10
|
+
TMP_STALE=$(mktemp)
|
|
11
|
+
TMP_UNOWNED=$(mktemp)
|
|
12
|
+
trap 'rm -f "$TMP_OWNS" "$TMP_STALE" "$TMP_UNOWNED"' EXIT
|
|
13
|
+
|
|
14
|
+
echo "Checking for doc drift over the last $DAYS days..."
|
|
15
|
+
echo ""
|
|
16
|
+
|
|
17
|
+
# Extract owns patterns from a markdown file
|
|
18
|
+
extract_owns() {
|
|
19
|
+
local file="$1"
|
|
20
|
+
awk '
|
|
21
|
+
/^---$/ { fm++; next }
|
|
22
|
+
fm == 1 && /^owns:/ { in_owns = 1; next }
|
|
23
|
+
fm == 1 && in_owns && /^ +- / {
|
|
24
|
+
sub("^ +- ", "")
|
|
25
|
+
gsub(/^[ \t]+|[ \t]+$/, "")
|
|
26
|
+
print
|
|
27
|
+
next
|
|
28
|
+
}
|
|
29
|
+
fm == 1 && in_owns && /^[a-z]/ { exit }
|
|
30
|
+
fm >= 2 { exit }
|
|
31
|
+
' "$file"
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
# Get recently changed files
|
|
35
|
+
changed_files=$(cd "$REPO_ROOT" && git log --since="$DAYS days ago" --name-only --pretty=format:"" | sort -u | grep -v '^$' || true)
|
|
36
|
+
|
|
37
|
+
if [ -z "$changed_files" ]; then
|
|
38
|
+
echo "No files changed in the last $DAYS days."
|
|
39
|
+
exit 0
|
|
40
|
+
fi
|
|
41
|
+
|
|
42
|
+
changed_count=$(echo "$changed_files" | wc -l | tr -d ' ')
|
|
43
|
+
echo "Found $changed_count changed files in the last $DAYS days."
|
|
44
|
+
echo ""
|
|
45
|
+
|
|
46
|
+
# Build ownership map: pattern\tdoc
|
|
47
|
+
find "$FEATURES_DIR" -name "*.md" ! -name "README.md" -print0 | sort -z | while IFS= read -r -d '' file; do
|
|
48
|
+
rel_path="${file#$REPO_ROOT/}"
|
|
49
|
+
extract_owns "$file" | while IFS= read -r pattern; do
|
|
50
|
+
[ -z "$pattern" ] && continue
|
|
51
|
+
printf '%s\t%s\n' "$pattern" "$rel_path" >> "$TMP_OWNS"
|
|
52
|
+
done
|
|
53
|
+
done
|
|
54
|
+
|
|
55
|
+
# Check each changed file against ownership
|
|
56
|
+
echo "$changed_files" | while IFS= read -r changed_file; do
|
|
57
|
+
[ -z "$changed_file" ] && continue
|
|
58
|
+
# Skip non-source files
|
|
59
|
+
case "$changed_file" in
|
|
60
|
+
docs/*|.claude/*|.github/*|node_modules/*|package*.json|*.lock*|*.config*) continue ;;
|
|
61
|
+
esac
|
|
62
|
+
|
|
63
|
+
found_owner=0
|
|
64
|
+
while IFS=$'\t' read -r pattern doc; do
|
|
65
|
+
prefix="${pattern%%\*\**}"
|
|
66
|
+
prefix="${prefix%%\**}"
|
|
67
|
+
case "$changed_file" in
|
|
68
|
+
${prefix}*)
|
|
69
|
+
found_owner=1
|
|
70
|
+
# Check if the doc was also modified recently
|
|
71
|
+
if ! echo "$changed_files" | grep -q "^${doc}$"; then
|
|
72
|
+
printf '%s\t%s\n' "$doc" "$changed_file" >> "$TMP_STALE"
|
|
73
|
+
fi
|
|
74
|
+
break
|
|
75
|
+
;;
|
|
76
|
+
esac
|
|
77
|
+
done < "$TMP_OWNS"
|
|
78
|
+
|
|
79
|
+
if [ "$found_owner" -eq 0 ]; then
|
|
80
|
+
case "$changed_file" in
|
|
81
|
+
src/*|app/*|packages/*) echo "$changed_file" >> "$TMP_UNOWNED" ;;
|
|
82
|
+
esac
|
|
83
|
+
fi
|
|
84
|
+
done
|
|
85
|
+
|
|
86
|
+
# Report stale docs
|
|
87
|
+
if [ -s "$TMP_STALE" ]; then
|
|
88
|
+
echo "## Potentially Stale Docs"
|
|
89
|
+
echo ""
|
|
90
|
+
echo "These docs own code that changed recently, but the docs themselves were not updated:"
|
|
91
|
+
echo ""
|
|
92
|
+
current_doc=""
|
|
93
|
+
sort "$TMP_STALE" | while IFS=$'\t' read -r doc file; do
|
|
94
|
+
if [ "$doc" != "$current_doc" ]; then
|
|
95
|
+
[ -n "$current_doc" ] && echo ""
|
|
96
|
+
echo "**$doc**"
|
|
97
|
+
current_doc="$doc"
|
|
98
|
+
fi
|
|
99
|
+
echo " - $file"
|
|
100
|
+
done
|
|
101
|
+
echo ""
|
|
102
|
+
else
|
|
103
|
+
echo "## No Stale Docs Detected"
|
|
104
|
+
echo ""
|
|
105
|
+
echo "All docs whose owned code changed were also updated."
|
|
106
|
+
fi
|
|
107
|
+
|
|
108
|
+
echo ""
|
|
109
|
+
|
|
110
|
+
# Report unowned files
|
|
111
|
+
if [ -s "$TMP_UNOWNED" ]; then
|
|
112
|
+
unowned_count=$(wc -l < "$TMP_UNOWNED" | tr -d ' ')
|
|
113
|
+
echo "## Unowned Changed Files ($unowned_count)"
|
|
114
|
+
echo ""
|
|
115
|
+
echo "These changed source files have no owning feature doc:"
|
|
116
|
+
echo ""
|
|
117
|
+
sort -u "$TMP_UNOWNED" | head -30 | while IFS= read -r file; do
|
|
118
|
+
echo "- $file"
|
|
119
|
+
done
|
|
120
|
+
if [ "$unowned_count" -gt 30 ]; then
|
|
121
|
+
echo "- ... and $((unowned_count - 30)) more"
|
|
122
|
+
fi
|
|
123
|
+
else
|
|
124
|
+
echo "## No Unowned Changed Files"
|
|
125
|
+
fi
|
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: documentation
|
|
3
|
+
description: Create and maintain technical documentation. Use when the user asks to (1) baseline, audit, or reorganize docs — enforces an opinionated 6-folder structure (architecture, features, operations, history, memory, tests) with ownership frontmatter and scaffold files, (2) document a feature or module, (3) create or update a changelog entry, (4) document data flows or Redux state, (5) add to protected files, (6) create or update guardrails (cascading failure boundaries), (7) record an architecture decision (ADR), (8) create or update the project root README, (9) create or update a plan, or (10) co-author any technical doc. Triggers on "document this", "create docs", "update changelog", "baseline docs", "audit docs", "add to protected files", "guardrails", "ADR", "architecture decision", "root README", "plan".
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Technical Documentation Skill
|
|
7
|
+
|
|
8
|
+
Document contracts and architecture, not implementation details. Show function signatures and API shapes — never paste full implementations (they rot fast). Use ASCII diagrams over prose for flows. Only document state at persistence boundaries (Redux persistence, DB schemas, API shapes), not component-level or transient state. Mark deprecated fields with `// UNUSED:` comments. Breaking changes belong in changelogs only, not module docs.
|
|
9
|
+
|
|
10
|
+
**No redirect docs.** When moving a doc to a new location, delete the old file entirely. Update all references (routing, ownership index, memory files, frontmatter `depends_on`, cross-doc links) to point to the new path. Never leave a stub file that says "Moved to X" — redirect docs rot, clutter the repo, and create false search hits.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Decision Tree
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
User request
|
|
18
|
+
│
|
|
19
|
+
├─ "Baseline/audit docs" ──────────▶ Baseline Audit (below)
|
|
20
|
+
│
|
|
21
|
+
├─ "Document feature/module" ──────▶ Module Template
|
|
22
|
+
│
|
|
23
|
+
├─ "Create/update changelog" ──────▶ Changelog Template
|
|
24
|
+
│
|
|
25
|
+
├─ "Document data flow" ───────────▶ Module Template (Architecture section)
|
|
26
|
+
│
|
|
27
|
+
├─ "Document Redux/state" ─────────▶ Module Template (State section)
|
|
28
|
+
│
|
|
29
|
+
├─ "Add to protected files" ───────▶ Protected Files Template
|
|
30
|
+
│
|
|
31
|
+
├─ "Create/update guardrails" ─────▶ Guardrails Template
|
|
32
|
+
│
|
|
33
|
+
├─ "Record architecture decision" ─▶ ADR Template
|
|
34
|
+
│
|
|
35
|
+
├─ "Create/update root README" ────▶ Project Root README Template
|
|
36
|
+
│
|
|
37
|
+
├─ "Create/update plan" ───────────▶ Plan Template
|
|
38
|
+
│
|
|
39
|
+
├─ "Update existing doc" ──────────▶ Preserve existing structure
|
|
40
|
+
│
|
|
41
|
+
└─ No template matches ────────────▶ Co-Authoring Workflow (below)
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Baseline Audit
|
|
47
|
+
|
|
48
|
+
When asked to "baseline", "audit", or "review" docs, enforce the canonical 6-folder documentation structure. This is an opinionated reorganization — the target structure is non-negotiable.
|
|
49
|
+
|
|
50
|
+
### Target Structure
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
docs/
|
|
54
|
+
├── README.md # Documentation root — quick links table, section index
|
|
55
|
+
├── structure.md # Authority map, folder rules, health log
|
|
56
|
+
├── CODEBASE_MAP.md # Auto-generated directory map (optional)
|
|
57
|
+
├── faq.md # Common issues (optional)
|
|
58
|
+
├── architecture/ # System-wide decisions, patterns, technical references
|
|
59
|
+
│ ├── adr/ # Architecture Decision Records (numbered, immutable)
|
|
60
|
+
│ └── core/ # Core module internals (auth, state, routing)
|
|
61
|
+
├── features/ # Living feature specs with ownership frontmatter
|
|
62
|
+
│ └── {feature}/ # Subfolder for deep features (e.g., editor/)
|
|
63
|
+
├── operations/ # Setup, development, deployment, CI/CD
|
|
64
|
+
│ └── guardrails.md # Cascading failure boundaries (cross-module contracts)
|
|
65
|
+
├── history/ # Frozen/append-only records
|
|
66
|
+
│ ├── CHANGELOG.md # Master changelog index
|
|
67
|
+
│ ├── changelog/ # Individual changelog entries
|
|
68
|
+
│ ├── plans/ # Historical implementation plans (Status field required)
|
|
69
|
+
│ └── backlog.md # Tracked work items by priority (P0-P3)
|
|
70
|
+
├── memory/ # Agent memory files
|
|
71
|
+
└── tests/ # Test plans and automation docs (optional)
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
### Workflow
|
|
75
|
+
|
|
76
|
+
**Step 1: Inventory existing docs**
|
|
77
|
+
|
|
78
|
+
Glob all markdown files in the repo. Categorize each file:
|
|
79
|
+
|
|
80
|
+
| Category | Matches | Target |
|
|
81
|
+
|----------|---------|--------|
|
|
82
|
+
| Architecture | System design, patterns, config, API specs, tech decisions | `docs/architecture/` |
|
|
83
|
+
| Features | How a feature works, user-facing behavior, data models | `docs/features/` |
|
|
84
|
+
| Operations | Setup, dev workflow, deployment, CI/CD, runbooks | `docs/operations/` |
|
|
85
|
+
| Plans | Implementation plans, proposals, RFCs | `docs/history/plans/` |
|
|
86
|
+
| Changelogs | Change records, release notes | `docs/history/changelog/` |
|
|
87
|
+
| Backlogs/Tasks | Work items, TODOs, tech debt | Merge into `docs/history/backlog.md` |
|
|
88
|
+
| Stale/Deprecated | Self-marked deprecated, fully superseded, empty docs | Delete |
|
|
89
|
+
| Root docs | `README.md`, `CLAUDE.md`, `AGENTS.md` | Stay in root |
|
|
90
|
+
|
|
91
|
+
**Step 2: Detect duplicates and overlaps**
|
|
92
|
+
|
|
93
|
+
For each topic, identify all files covering it. Keep the most complete version as canonical. Extract unique content from others before deleting.
|
|
94
|
+
|
|
95
|
+
**Step 3: Present reorganization plan**
|
|
96
|
+
|
|
97
|
+
Present a table to the user:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
| File | Action | From | To | Reason |
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Actions: `Move`, `Merge into {target}`, `Delete`, `Keep`, `Create`
|
|
104
|
+
|
|
105
|
+
Ask: "Approve this plan? I'll execute all moves, merges, and deletions."
|
|
106
|
+
|
|
107
|
+
**Step 4: Execute reorganization**
|
|
108
|
+
|
|
109
|
+
After approval:
|
|
110
|
+
|
|
111
|
+
1. Create the full folder structure:
|
|
112
|
+
- `docs/architecture/`
|
|
113
|
+
- `docs/features/`
|
|
114
|
+
- `docs/operations/`
|
|
115
|
+
- `docs/history/plans/`
|
|
116
|
+
- `docs/history/changelog/`
|
|
117
|
+
- `docs/memory/`
|
|
118
|
+
- `docs/tests/` (if test docs exist)
|
|
119
|
+
2. Move files per the plan
|
|
120
|
+
3. Merge content where specified (extract unique content, append to target)
|
|
121
|
+
4. Delete stale/superseded files
|
|
122
|
+
5. Add `Status: Complete | In Progress | Draft | Abandoned` to all plan files
|
|
123
|
+
6. Add YAML frontmatter to feature docs (see Frontmatter Derivation below)
|
|
124
|
+
7. Merge scattered backlog/task files into `docs/history/backlog.md`
|
|
125
|
+
8. Scaffold standard files if missing:
|
|
126
|
+
- `docs/README.md` — from template (see `references/templates.md`)
|
|
127
|
+
- `docs/structure.md` — from template (see `references/templates.md`)
|
|
128
|
+
- `docs/operations/guardrails.md` — cascading failure boundaries (see `references/templates.md` for what to include/exclude)
|
|
129
|
+
- `docs/history/CHANGELOG.md` — master changelog index (header + table linking to entries)
|
|
130
|
+
- `docs/history/backlog.md` — work items by priority (P0-P3 sections, empty if nothing to merge)
|
|
131
|
+
- `docs/memory/index.md` — agent memory index (empty scaffold with section headers)
|
|
132
|
+
- `docs/memory/main.md` — main agent project memory (empty header + date marker)
|
|
133
|
+
- `docs/OWNERSHIP_INDEX.md` — generated table of feature doc ownership. Build it now from the frontmatter you derived in Step 6 (same shape the maintenance agent regenerates each run — see `references/templates.md`)
|
|
134
|
+
- `README.md` (repo root) — from §11 in `references/templates.md`, filled with concrete details from the repo (real package manager from the lockfile, real scripts, real layout). **Never overwrite an existing root README** — if one is present, leave it untouched.
|
|
135
|
+
9. Fix all internal links broken by moves
|
|
136
|
+
10. Record baseline in `docs/memory/index.md` with today's date (see template)
|
|
137
|
+
|
|
138
|
+
**Step 5: Verify**
|
|
139
|
+
|
|
140
|
+
1. Confirm all standard files exist: `docs/README.md`, `docs/structure.md`, `docs/operations/guardrails.md`, `docs/history/CHANGELOG.md`, `docs/history/backlog.md`, `docs/memory/index.md`, `docs/memory/main.md`, `docs/OWNERSHIP_INDEX.md`, `README.md` (repo root — must exist; either pre-existing untouched or freshly scaffolded)
|
|
141
|
+
2. Confirm no dead links in `docs/README.md`
|
|
142
|
+
3. Confirm every plan file has a `Status:` field
|
|
143
|
+
4. Confirm feature docs have ownership frontmatter
|
|
144
|
+
5. Confirm `docs/OWNERSHIP_INDEX.md` rows match the frontmatter on disk (no orphans, no missing entries)
|
|
145
|
+
6. Confirm no docs remain outside the 6-folder structure (except `README.md`, `structure.md`, `CODEBASE_MAP.md`, `faq.md`)
|
|
146
|
+
7. Confirm duplicates are eliminated — each topic has one canonical source
|
|
147
|
+
|
|
148
|
+
### Rules
|
|
149
|
+
|
|
150
|
+
- The 6-folder structure is mandatory. No `docs/guides/`, `docs/core/`, `docs/editor/`, `docs/pt/`, or any other top-level folder
|
|
151
|
+
- Guides about how-to-run → `operations/`. Guides about a feature → `features/`
|
|
152
|
+
- Core module docs → `docs/architecture/core/`. Editor module docs → `docs/features/editor/`
|
|
153
|
+
- Only `CLAUDE.md`, `AGENTS.md`, and `README.md` are allowed in the repository root (not inside `docs/`)
|
|
154
|
+
- Root-level `README.md` is for humans. `docs/README.md` is the agent/doc entry point
|
|
155
|
+
- One canonical source per topic — link, don't copy
|
|
156
|
+
- **No redirect docs** — when moving a file, delete the original and fix all references. Never leave a "Moved to X" stub.
|
|
157
|
+
- For 10+ files, use parallel sub-agents (5-8 files each)
|
|
158
|
+
|
|
159
|
+
### Naming & Lifecycle
|
|
160
|
+
|
|
161
|
+
- Features: `kebab-case.md` — living reference, status `Active`
|
|
162
|
+
- Plans: `YYYY-MM-DD-kebab-case.md` — frozen after `Complete` or `Abandoned`
|
|
163
|
+
- Changelogs: `YYYY-MM-DD-kebab-case.md` — append-only
|
|
164
|
+
- Memory: `{agent-name}.md` — agent-maintained
|
|
165
|
+
|
|
166
|
+
---
|
|
167
|
+
|
|
168
|
+
## Frontmatter Derivation
|
|
169
|
+
|
|
170
|
+
When creating or updating a feature doc in `docs/features/`, generate `owns`, `touches`, `depends_on` frontmatter from the source code the doc describes.
|
|
171
|
+
|
|
172
|
+
### When to run
|
|
173
|
+
|
|
174
|
+
- **Baseline audit Step 6** — for every feature doc missing frontmatter
|
|
175
|
+
- **New feature doc** — when creating a doc via the Module Documentation template
|
|
176
|
+
- **Doc update** — when updating an existing feature doc and the frontmatter is missing or the documented scope changed
|
|
177
|
+
|
|
178
|
+
### How to derive values
|
|
179
|
+
|
|
180
|
+
**1. Identify `owns` patterns**
|
|
181
|
+
|
|
182
|
+
Read the feature doc's content. Extract every source file path referenced in the doc (file listings, function locations, component paths). Group them into the narrowest glob patterns that cover all referenced files without overlapping other features.
|
|
183
|
+
|
|
184
|
+
| Doc references | `owns` pattern |
|
|
185
|
+
|---|---|
|
|
186
|
+
| Multiple files under one directory | `src/feature/**` |
|
|
187
|
+
| Specific files in a shared directory | List each file explicitly |
|
|
188
|
+
| A single entry-point file | The exact file path |
|
|
189
|
+
|
|
190
|
+
Verify patterns match real files — glob each pattern against the codebase. Remove any that match nothing.
|
|
191
|
+
|
|
192
|
+
**2. Identify `touches` patterns**
|
|
193
|
+
|
|
194
|
+
From the same source files the doc describes, find imports and calls to code outside the `owns` scope. These are files the feature uses but doesn't own.
|
|
195
|
+
|
|
196
|
+
Common `touches` candidates:
|
|
197
|
+
- Shared Redux slices the feature reads/writes
|
|
198
|
+
- Utility functions from other modules
|
|
199
|
+
- Shared hooks the feature calls
|
|
200
|
+
- API route files the feature's frontend calls
|
|
201
|
+
|
|
202
|
+
Keep `touches` to direct dependencies only — not transitive ones.
|
|
203
|
+
|
|
204
|
+
**3. Identify `depends_on` docs**
|
|
205
|
+
|
|
206
|
+
Check for explicit cross-references to other docs in `docs/features/` or `docs/architecture/`. Also check if the feature's `touches` paths are `owns`-ed by another feature doc — that doc is a dependency.
|
|
207
|
+
|
|
208
|
+
### Rules
|
|
209
|
+
|
|
210
|
+
- Every feature doc must have all three fields, even if empty (`depends_on: []`)
|
|
211
|
+
- Use glob patterns for directories, explicit paths for individual files
|
|
212
|
+
- Don't list paths that don't exist in the codebase
|
|
213
|
+
- When a doc covers a deep feature with sub-specs (e.g., `editor/`), each sub-spec gets its own frontmatter — don't duplicate ownership across siblings
|
|
214
|
+
- For baseline audits with 10+ files needing frontmatter, use parallel sub-agents to read and analyze the source files
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## Co-Authoring Workflow
|
|
219
|
+
|
|
220
|
+
For docs that don't match templates:
|
|
221
|
+
|
|
222
|
+
**Stage 1: Context Gathering**
|
|
223
|
+
- Ask: Audience? Purpose? Existing format?
|
|
224
|
+
- Have user dump all context, then ask 5-10 clarifying questions
|
|
225
|
+
|
|
226
|
+
**Stage 2: Structure & Draft**
|
|
227
|
+
- Propose section structure, draft section by section
|
|
228
|
+
- User indicates changes (don't edit directly — learn their style)
|
|
229
|
+
|
|
230
|
+
---
|
|
231
|
+
|
|
232
|
+
## Resources
|
|
233
|
+
|
|
234
|
+
| File | Use For |
|
|
235
|
+
|------|---------|
|
|
236
|
+
| `references/templates.md` | docs/README.md, structure.md, frontmatter, scaffolds (CHANGELOG, backlog, memory, OWNERSHIP_INDEX), guardrails, feature, changelog, plan, protected files, ADR, project root README templates |
|
|
237
|
+
| `references/style-guide.md` | Writing rules, formatting conventions |
|
|
238
|
+
| `references/examples.md` | Good vs bad documentation examples |
|