aped-method 1.0.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.
@@ -0,0 +1,345 @@
1
+ export function scripts(c) {
2
+ const a = c.apedDir;
3
+ const o = c.outputDir;
4
+ return [
5
+ {
6
+ path: `${a}/aped-a/scripts/validate-brief.sh`,
7
+ executable: true,
8
+ content: `#!/usr/bin/env bash
9
+ # Validate product brief has all required sections
10
+ # Usage: validate-brief.sh <brief-file>
11
+ # Exit 0 if valid, exit 1 with missing sections listed
12
+
13
+ set -euo pipefail
14
+
15
+ if [[ $# -ne 1 ]]; then
16
+ echo "Usage: $0 <brief-file>"
17
+ exit 1
18
+ fi
19
+
20
+ FILE="$1"
21
+
22
+ if [[ ! -f "$FILE" ]]; then
23
+ echo "ERROR: File not found: $FILE"
24
+ exit 1
25
+ fi
26
+
27
+ REQUIRED_SECTIONS=(
28
+ "## Executive Summary"
29
+ "## Core Vision"
30
+ "## Target Users"
31
+ "## Success Metrics"
32
+ "## MVP Scope"
33
+ )
34
+
35
+ MISSING=()
36
+
37
+ for section in "\${REQUIRED_SECTIONS[@]}"; do
38
+ if ! grep -q "$section" "$FILE"; then
39
+ MISSING+=("$section")
40
+ fi
41
+ done
42
+
43
+ if [[ \${#MISSING[@]} -gt 0 ]]; then
44
+ echo "VALIDATION FAILED — Missing sections:"
45
+ for m in "\${MISSING[@]}"; do
46
+ echo " - $m"
47
+ done
48
+ exit 1
49
+ fi
50
+
51
+ echo "VALIDATION PASSED — All required sections present"
52
+ exit 0
53
+ `,
54
+ },
55
+ {
56
+ path: `${a}/aped-p/scripts/validate-prd.sh`,
57
+ executable: true,
58
+ content: `#!/usr/bin/env bash
59
+ # Validate PRD has required sections, FR format, and no anti-patterns
60
+ # Usage: validate-prd.sh <prd-file>
61
+ # Exit 0 if valid, exit 1 with issues listed
62
+
63
+ set -euo pipefail
64
+
65
+ if [[ $# -ne 1 ]]; then
66
+ echo "Usage: $0 <prd-file>"
67
+ exit 1
68
+ fi
69
+
70
+ FILE="$1"
71
+
72
+ if [[ ! -f "$FILE" ]]; then
73
+ echo "ERROR: File not found: $FILE"
74
+ exit 1
75
+ fi
76
+
77
+ ISSUES=()
78
+
79
+ # Check required sections
80
+ REQUIRED_SECTIONS=(
81
+ "## Executive Summary"
82
+ "## Success Criteria"
83
+ "## Product Scope"
84
+ "## User Journeys"
85
+ "## Functional Requirements"
86
+ "## Non-Functional Requirements"
87
+ )
88
+
89
+ for section in "\${REQUIRED_SECTIONS[@]}"; do
90
+ if ! grep -q "$section" "$FILE"; then
91
+ ISSUES+=("MISSING SECTION: $section")
92
+ fi
93
+ done
94
+
95
+ # Check FR format
96
+ FR_LINES=$(grep -E '^FR[0-9]+:' "$FILE" 2>/dev/null || true)
97
+ FR_COUNT=0
98
+ if [[ -n "$FR_LINES" ]]; then
99
+ FR_COUNT=$(echo "$FR_LINES" | wc -l | tr -d ' ')
100
+ fi
101
+
102
+ if [[ "$FR_COUNT" -lt 10 ]]; then
103
+ ISSUES+=("FR COUNT TOO LOW: Found $FR_COUNT FRs (minimum 10)")
104
+ fi
105
+
106
+ if [[ "$FR_COUNT" -gt 80 ]]; then
107
+ ISSUES+=("FR COUNT TOO HIGH: Found $FR_COUNT FRs (maximum 80)")
108
+ fi
109
+
110
+ # Check for anti-pattern words in FR lines
111
+ ANTI_PATTERNS=("easy" "intuitive" "fast" "responsive" "simple" "multiple" "several" "various")
112
+
113
+ for pattern in "\${ANTI_PATTERNS[@]}"; do
114
+ MATCHES=$(grep -inE "^FR[0-9]+:.*\\b\${pattern}\\b" "$FILE" 2>/dev/null || true)
115
+ if [[ -n "$MATCHES" ]]; then
116
+ ISSUES+=("ANTI-PATTERN '$pattern' found in FR: $MATCHES")
117
+ fi
118
+ done
119
+
120
+ # Report results
121
+ if [[ \${#ISSUES[@]} -gt 0 ]]; then
122
+ echo "VALIDATION FAILED — Issues found:"
123
+ for issue in "\${ISSUES[@]}"; do
124
+ echo " - $issue"
125
+ done
126
+ exit 1
127
+ fi
128
+
129
+ echo "VALIDATION PASSED — PRD is valid ($FR_COUNT FRs, all sections present, no anti-patterns)"
130
+ exit 0
131
+ `,
132
+ },
133
+ {
134
+ path: `${a}/aped-e/scripts/validate-coverage.sh`,
135
+ executable: true,
136
+ content: `#!/usr/bin/env bash
137
+ # Validate that all FRs from PRD are covered in epics
138
+ # Usage: validate-coverage.sh <epics-file> <prd-file>
139
+ # Exit 0 if all covered, exit 1 with missing FRs listed
140
+
141
+ set -euo pipefail
142
+
143
+ if [[ $# -ne 2 ]]; then
144
+ echo "Usage: $0 <epics-file> <prd-file>"
145
+ exit 1
146
+ fi
147
+
148
+ EPICS_FILE="$1"
149
+ PRD_FILE="$2"
150
+
151
+ if [[ ! -f "$EPICS_FILE" ]]; then
152
+ echo "ERROR: Epics file not found: $EPICS_FILE"
153
+ exit 1
154
+ fi
155
+
156
+ if [[ ! -f "$PRD_FILE" ]]; then
157
+ echo "ERROR: PRD file not found: $PRD_FILE"
158
+ exit 1
159
+ fi
160
+
161
+ # Extract FR numbers
162
+ PRD_FRS=$(grep -oE 'FR[0-9]+' "$PRD_FILE" | sort -u || true)
163
+ EPIC_FRS=$(grep -oE 'FR[0-9]+' "$EPICS_FILE" | sort -u || true)
164
+
165
+ if [[ -z "$PRD_FRS" ]]; then
166
+ echo "WARNING: No FRs found in PRD file"
167
+ exit 0
168
+ fi
169
+
170
+ # Find missing FRs
171
+ MISSING=()
172
+ for fr in $PRD_FRS; do
173
+ [[ -z "$fr" ]] && continue
174
+ if ! echo "$EPIC_FRS" | grep -q "^\${fr}$"; then
175
+ MISSING+=("$fr")
176
+ fi
177
+ done
178
+
179
+ PRD_COUNT=$(echo "$PRD_FRS" | grep -c . || echo 0)
180
+ EPIC_COUNT=$(echo "$EPIC_FRS" | grep -c . || echo 0)
181
+
182
+ if [[ \${#MISSING[@]} -gt 0 ]]; then
183
+ echo "COVERAGE VALIDATION FAILED"
184
+ echo "PRD FRs: $PRD_COUNT | Epics FRs: $EPIC_COUNT"
185
+ echo "Missing FRs (in PRD but not in epics):"
186
+ for fr in "\${MISSING[@]}"; do
187
+ echo " - $fr"
188
+ done
189
+ exit 1
190
+ fi
191
+
192
+ echo "COVERAGE VALIDATION PASSED — All $PRD_COUNT FRs covered in epics"
193
+ exit 0
194
+ `,
195
+ },
196
+ {
197
+ path: `${a}/aped-d/scripts/run-tests.sh`,
198
+ executable: true,
199
+ content: `#!/usr/bin/env bash
200
+ # Auto-detect test framework and run tests
201
+ # Usage: run-tests.sh [test-path]
202
+ # Exit code matches the test runner's exit code
203
+
204
+ set -euo pipefail
205
+
206
+ TEST_PATH="\${1:-}"
207
+
208
+ # Auto-detect test framework
209
+ if [[ -f "package.json" ]]; then
210
+ echo "Detected: Node.js project"
211
+ if grep -q '"vitest"' package.json 2>/dev/null; then
212
+ echo "Runner: vitest"
213
+ npx vitest run \${TEST_PATH:+"$TEST_PATH"}
214
+ elif grep -q '"jest"' package.json 2>/dev/null; then
215
+ echo "Runner: jest"
216
+ npx jest \${TEST_PATH:+"$TEST_PATH"}
217
+ else
218
+ echo "Runner: npm test"
219
+ npm test \${TEST_PATH:+-- "$TEST_PATH"}
220
+ fi
221
+ elif [[ -f "setup.py" ]] || [[ -f "pyproject.toml" ]] || [[ -f "setup.cfg" ]]; then
222
+ echo "Detected: Python project"
223
+ if [[ -n "$TEST_PATH" ]]; then
224
+ python -m pytest "$TEST_PATH" -v
225
+ else
226
+ python -m pytest -v
227
+ fi
228
+ elif [[ -f "Cargo.toml" ]]; then
229
+ echo "Detected: Rust project"
230
+ if [[ -n "$TEST_PATH" ]]; then
231
+ cargo test "$TEST_PATH"
232
+ else
233
+ cargo test
234
+ fi
235
+ elif [[ -f "go.mod" ]]; then
236
+ echo "Detected: Go project"
237
+ if [[ -n "$TEST_PATH" ]]; then
238
+ go test "$TEST_PATH" -v
239
+ else
240
+ go test ./... -v
241
+ fi
242
+ else
243
+ echo "ERROR: No recognized test framework found"
244
+ echo "Supported: package.json (Node), setup.py/pyproject.toml (Python), Cargo.toml (Rust), go.mod (Go)"
245
+ exit 1
246
+ fi
247
+ `,
248
+ },
249
+ {
250
+ path: `${a}/aped-r/scripts/git-audit.sh`,
251
+ executable: true,
252
+ content: `#!/usr/bin/env bash
253
+ # Compare git changes vs story file list
254
+ # Usage: git-audit.sh <story-file> [commits-back]
255
+ # Exit 0 if clean, exit 1 if HIGH severity discrepancies
256
+
257
+ set -euo pipefail
258
+
259
+ if [[ $# -lt 1 ]]; then
260
+ echo "Usage: $0 <story-file> [commits-back]"
261
+ exit 1
262
+ fi
263
+
264
+ STORY_FILE="$1"
265
+ COMMITS_BACK="\${2:-10}"
266
+
267
+ if [[ ! -f "$STORY_FILE" ]]; then
268
+ echo "ERROR: Story file not found: $STORY_FILE"
269
+ exit 1
270
+ fi
271
+
272
+ # Check if we're in a git repo
273
+ if ! git rev-parse --is-inside-work-tree &>/dev/null; then
274
+ echo "WARNING: Not a git repository. Skipping git audit."
275
+ exit 0
276
+ fi
277
+
278
+ # Extract file list from story's Dev Agent Record section
279
+ STORY_FILES=$(sed -n '/^### File List/,/^##/p' "$STORY_FILE" | grep -E '^\\s*[-*]' | sed 's/^[[:space:]]*[-*][[:space:]]*//' | sort -u)
280
+
281
+ # Get git changed files
282
+ GIT_FILES=$(git diff --name-only "HEAD~\${COMMITS_BACK}" HEAD 2>/dev/null | sort -u)
283
+
284
+ if [[ -z "$GIT_FILES" ]]; then
285
+ echo "WARNING: No git changes found in last $COMMITS_BACK commits"
286
+ exit 0
287
+ fi
288
+
289
+ # Compare
290
+ IN_GIT_NOT_STORY=()
291
+ IN_STORY_NOT_GIT=()
292
+
293
+ while IFS= read -r file; do
294
+ if [[ -n "$file" ]] && ! echo "$STORY_FILES" | grep -qF "$file"; then
295
+ IN_GIT_NOT_STORY+=("$file")
296
+ fi
297
+ done <<< "$GIT_FILES"
298
+
299
+ while IFS= read -r file; do
300
+ if [[ -n "$file" ]] && ! echo "$GIT_FILES" | grep -qF "$file"; then
301
+ IN_STORY_NOT_GIT+=("$file")
302
+ fi
303
+ done <<< "$STORY_FILES"
304
+
305
+ # Report
306
+ echo "=== GIT AUDIT REPORT ==="
307
+ echo "Story: $STORY_FILE"
308
+ echo "Git range: HEAD~\${COMMITS_BACK}..HEAD"
309
+ echo ""
310
+
311
+ HAS_ISSUES=false
312
+
313
+ if [[ \${#IN_GIT_NOT_STORY[@]} -gt 0 ]]; then
314
+ echo "[MEDIUM] Files changed in git but NOT listed in story:"
315
+ for f in "\${IN_GIT_NOT_STORY[@]}"; do
316
+ echo " - $f"
317
+ done
318
+ echo ""
319
+ HAS_ISSUES=true
320
+ fi
321
+
322
+ if [[ \${#IN_STORY_NOT_GIT[@]} -gt 0 ]]; then
323
+ echo "[HIGH] Files listed in story but NO git changes:"
324
+ for f in "\${IN_STORY_NOT_GIT[@]}"; do
325
+ echo " - $f"
326
+ done
327
+ echo ""
328
+ HAS_ISSUES=true
329
+ fi
330
+
331
+ if [[ "$HAS_ISSUES" == "false" ]]; then
332
+ echo "No discrepancies found. Git changes match story file list."
333
+ exit 0
334
+ fi
335
+
336
+ # Exit 1 if HIGH severity items found
337
+ if [[ \${#IN_STORY_NOT_GIT[@]} -gt 0 ]]; then
338
+ exit 1
339
+ fi
340
+
341
+ exit 0
342
+ `,
343
+ },
344
+ ];
345
+ }