aped-method 2.0.0 → 2.0.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/README.md +229 -0
- package/package.json +1 -1
- package/src/templates/guardrail.js +71 -69
- package/src/templates/scripts.js +3 -3
package/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# APED Method
|
|
2
|
+
|
|
3
|
+
Zero-dependency CLI that scaffolds a complete dev pipeline into any [Claude Code](https://claude.ai/download) project.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
npx aped-method
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
█████╗ ██████╗ ███████╗██████╗
|
|
11
|
+
██╔══██╗██╔══██╗██╔════╝██╔══██╗
|
|
12
|
+
███████║██████╔╝█████╗ ██║ ██║
|
|
13
|
+
██╔══██║██╔═══╝ ██╔══╝ ██║ ██║
|
|
14
|
+
██║ ██║██║ ███████╗██████╔╝
|
|
15
|
+
╚═╝ ╚═╝╚═╝ ╚══════╝╚═════╝
|
|
16
|
+
M E T H O D
|
|
17
|
+
|
|
18
|
+
Analyze → PRD → UX → Epics → Dev → Review
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## What it does
|
|
22
|
+
|
|
23
|
+
APED turns Claude Code into a disciplined dev pipeline. Instead of "code me an app", you get:
|
|
24
|
+
|
|
25
|
+
1. **Analyze** — 3 parallel research agents (market, domain, technical) produce a product brief
|
|
26
|
+
2. **PRD** — Autonomous generation with numbered FRs, validation scripts, domain detection
|
|
27
|
+
3. **UX** — ANF framework: Assemble design DNA, Normalize with a live React prototype, Fill all screens with user validation
|
|
28
|
+
4. **Epics** — Stories with ACs in Given/When/Then, FR coverage validation, ticket system integration
|
|
29
|
+
5. **Dev** — TDD red-green-refactor with 5-condition gate, parallel agents for context gathering
|
|
30
|
+
6. **Review** — Adversarial code review with minimum 3 findings, parallel agents (code-explorer + code-reviewer)
|
|
31
|
+
|
|
32
|
+
A guardrail hook blocks you from skipping steps. A state machine tracks progress. Everything chains automatically.
|
|
33
|
+
|
|
34
|
+
## Quick start
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
cd your-project
|
|
38
|
+
npx aped-method
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Interactive prompts ask for project name, author, languages, ticket system, and git provider. Or go non-interactive:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx aped-method --yes --project=my-app --author=Jane --lang=french --tickets=linear --git=github
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Then open Claude Code:
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
/aped-a # Start with analysis
|
|
51
|
+
/aped-all # Or run the full pipeline
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Pipeline commands
|
|
55
|
+
|
|
56
|
+
| Command | Phase | What it produces |
|
|
57
|
+
|---------|-------|-----------------|
|
|
58
|
+
| `/aped-a` | Analyze | Product brief from 3 parallel research agents |
|
|
59
|
+
| `/aped-p` | PRD | PRD with numbered FRs/NFRs, validated by script |
|
|
60
|
+
| `/aped-ux` | UX | Live React prototype (Vite), design spec, component catalog |
|
|
61
|
+
| `/aped-e` | Epics | Stories with ACs, tasks, FR coverage map |
|
|
62
|
+
| `/aped-d` | Dev | TDD implementation with 5-condition gate |
|
|
63
|
+
| `/aped-r` | Review | Adversarial review, minimum 3 findings |
|
|
64
|
+
|
|
65
|
+
## Utility commands
|
|
66
|
+
|
|
67
|
+
| Command | What it does |
|
|
68
|
+
|---------|-------------|
|
|
69
|
+
| `/aped-s` | Sprint status dashboard — progress, blockers, next actions |
|
|
70
|
+
| `/aped-c` | Correct course — manage scope changes with impact analysis |
|
|
71
|
+
| `/aped-ctx` | Brownfield analysis — generate project context from existing code |
|
|
72
|
+
| `/aped-qa` | Generate E2E and integration tests from acceptance criteria |
|
|
73
|
+
| `/aped-quick` | Quick fix/feature bypassing the full pipeline |
|
|
74
|
+
| `/aped-all` | Run the full pipeline A→P→UX→E→D→R with auto-resume |
|
|
75
|
+
|
|
76
|
+
## What gets scaffolded
|
|
77
|
+
|
|
78
|
+
```
|
|
79
|
+
.aped/ # Engine (immutable after install)
|
|
80
|
+
├── config.yaml # Project settings, integrations
|
|
81
|
+
├── hooks/guardrail.sh # Pipeline coherence hook
|
|
82
|
+
├── templates/ # Document templates (brief, PRD, epics, story, quick-spec)
|
|
83
|
+
├── aped-a/ # Analyze skill
|
|
84
|
+
│ ├── SKILL.md
|
|
85
|
+
│ ├── scripts/validate-brief.sh
|
|
86
|
+
│ └── references/research-prompts.md
|
|
87
|
+
├── aped-p/ # PRD skill
|
|
88
|
+
│ ├── SKILL.md
|
|
89
|
+
│ ├── scripts/validate-prd.sh
|
|
90
|
+
│ └── references/fr-rules.md, *.csv
|
|
91
|
+
├── aped-ux/ # UX skill (ANF framework)
|
|
92
|
+
│ ├── SKILL.md
|
|
93
|
+
│ ├── scripts/validate-ux.sh
|
|
94
|
+
│ └── references/ux-patterns.md # 99 priority-ranked UX rules
|
|
95
|
+
├── aped-e/ # Epics skill
|
|
96
|
+
│ ├── SKILL.md
|
|
97
|
+
│ ├── scripts/validate-coverage.sh
|
|
98
|
+
│ └── references/epic-rules.md
|
|
99
|
+
├── aped-d/ # Dev skill
|
|
100
|
+
│ ├── SKILL.md
|
|
101
|
+
│ ├── scripts/run-tests.sh
|
|
102
|
+
│ └── references/tdd-engine.md, ticket-git-workflow.md
|
|
103
|
+
├── aped-r/ # Review skill
|
|
104
|
+
│ ├── SKILL.md
|
|
105
|
+
│ ├── scripts/git-audit.sh
|
|
106
|
+
│ └── references/review-criteria.md
|
|
107
|
+
├── aped-s/ # Status dashboard
|
|
108
|
+
│ ├── SKILL.md
|
|
109
|
+
│ └── references/status-format.md
|
|
110
|
+
├── aped-c/ # Correct course
|
|
111
|
+
│ ├── SKILL.md
|
|
112
|
+
│ └── references/scope-change-guide.md
|
|
113
|
+
├── aped-ctx/ # Brownfield context
|
|
114
|
+
│ ├── SKILL.md
|
|
115
|
+
│ └── references/analysis-checklist.md
|
|
116
|
+
├── aped-qa/ # QA tests
|
|
117
|
+
│ ├── SKILL.md
|
|
118
|
+
│ └── references/test-patterns.md
|
|
119
|
+
├── aped-quick/SKILL.md # Quick fix
|
|
120
|
+
└── aped-all/SKILL.md # Orchestrator
|
|
121
|
+
|
|
122
|
+
docs/aped/ # Output (evolves during project)
|
|
123
|
+
├── state.yaml # Pipeline state machine
|
|
124
|
+
├── product-brief.md # From /aped-a
|
|
125
|
+
├── prd.md # From /aped-p
|
|
126
|
+
├── ux/ # From /aped-ux
|
|
127
|
+
│ ├── design-spec.md
|
|
128
|
+
│ ├── screen-inventory.md
|
|
129
|
+
│ ├── components.md
|
|
130
|
+
│ └── flows.md
|
|
131
|
+
├── epics.md # From /aped-e
|
|
132
|
+
├── stories/ # One file per story
|
|
133
|
+
└── quick-specs/ # From /aped-quick
|
|
134
|
+
|
|
135
|
+
.claude/
|
|
136
|
+
├── commands/aped-*.md # 12 slash commands
|
|
137
|
+
└── settings.local.json # Guardrail hook config
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Integrations
|
|
141
|
+
|
|
142
|
+
### Ticket systems
|
|
143
|
+
|
|
144
|
+
Configure during install or via `--tickets=`:
|
|
145
|
+
|
|
146
|
+
| Provider | Commit format | Auto-link |
|
|
147
|
+
|----------|--------------|-----------|
|
|
148
|
+
| `linear` | `feat(TEAM-XX): description` | `Part of TEAM-XX` / `Fixes TEAM-XX` |
|
|
149
|
+
| `jira` | `feat(PROJ-XX): description` | Smart commits |
|
|
150
|
+
| `github-issues` | `feat(#XX): description` | `Closes #XX` / `Fixes #XX` |
|
|
151
|
+
| `gitlab-issues` | `feat(#XX): description` | `Closes #XX` |
|
|
152
|
+
| `none` | `feat: description` | — |
|
|
153
|
+
|
|
154
|
+
### Git providers
|
|
155
|
+
|
|
156
|
+
Configure via `--git=`:
|
|
157
|
+
|
|
158
|
+
| Provider | PR/MR creation | Branch strategy |
|
|
159
|
+
|----------|---------------|-----------------|
|
|
160
|
+
| `github` | `gh pr create` | `feature/{ticket}-{slug}` |
|
|
161
|
+
| `gitlab` | `glab mr create` | `feature/{ticket}-{slug}` |
|
|
162
|
+
| `bitbucket` | Web UI | `feature/{ticket}-{slug}` |
|
|
163
|
+
|
|
164
|
+
## UX phase — ANF framework
|
|
165
|
+
|
|
166
|
+
The `/aped-ux` skill produces a live React prototype, not wireframes:
|
|
167
|
+
|
|
168
|
+
- **Assemble** — Collect design DNA: user inspirations, UI library (shadcn, MUI, Radix...), design tokens, branding
|
|
169
|
+
- **Normalize** — Scaffold Vite+React app with real PRD content (no lorem ipsum), working navigation, all screens
|
|
170
|
+
- **Fill** — Complete interaction states, responsive (3 breakpoints), dark mode, accessibility, then user review cycles until approved
|
|
171
|
+
|
|
172
|
+
The approved prototype becomes the UX spec that `/aped-e` consumes. Includes 99 priority-ranked UX rules and a pre-delivery checklist.
|
|
173
|
+
|
|
174
|
+
## Guardrail hook
|
|
175
|
+
|
|
176
|
+
Every prompt is intercepted by `guardrail.sh` which checks pipeline coherence:
|
|
177
|
+
|
|
178
|
+
| Situation | Reaction |
|
|
179
|
+
|-----------|----------|
|
|
180
|
+
| Coding without epics | Warns: run A→P→E first |
|
|
181
|
+
| PRD without brief | Warns: run /aped-a first |
|
|
182
|
+
| Modifying PRD during dev | Warns: use /aped-c for scope changes |
|
|
183
|
+
| Quick fix request | Bypasses (that's what /aped-quick is for) |
|
|
184
|
+
|
|
185
|
+
The hook injects context — it doesn't block. Claude explains the issue and asks for confirmation.
|
|
186
|
+
|
|
187
|
+
## Install / Update / Fresh
|
|
188
|
+
|
|
189
|
+
```bash
|
|
190
|
+
# First install
|
|
191
|
+
npx aped-method
|
|
192
|
+
|
|
193
|
+
# Re-run on existing project → auto-detects, offers:
|
|
194
|
+
# 1. Update engine (preserve config + artifacts)
|
|
195
|
+
# 2. Fresh install (delete everything, start over)
|
|
196
|
+
# 3. Cancel
|
|
197
|
+
|
|
198
|
+
# Non-interactive
|
|
199
|
+
npx aped-method --yes # Auto-update if exists
|
|
200
|
+
npx aped-method --yes --update # Explicit update
|
|
201
|
+
npx aped-method --yes --fresh # Nuke and redo
|
|
202
|
+
|
|
203
|
+
# Version check
|
|
204
|
+
npx aped-method --version # Shows current version
|
|
205
|
+
# If installed version < CLI version → "Upgrade available: v1.x → v2.x"
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Anthropic Skills Guide compliance
|
|
209
|
+
|
|
210
|
+
All 12 skills follow the [Complete Guide to Building Skills for Claude](https://www.anthropic.com/engineering/claude-skills-guide):
|
|
211
|
+
|
|
212
|
+
- YAML frontmatter with name, description (WHAT + WHEN + negative triggers), license, metadata
|
|
213
|
+
- Progressive disclosure: frontmatter → SKILL.md body → references/
|
|
214
|
+
- `disable-model-invocation: true` on side-effect skills (dev, review, correct, all)
|
|
215
|
+
- `allowed-tools` restrictions on read-only skills (status, context)
|
|
216
|
+
- Critical Rules section at top of pipeline skills
|
|
217
|
+
- Examples and Common Issues in every skill
|
|
218
|
+
- Validation scripts with clear exit codes
|
|
219
|
+
- Skill tool chaining (not slash notation)
|
|
220
|
+
- Third-person descriptions, <1024 chars, no XML tags
|
|
221
|
+
|
|
222
|
+
## Requirements
|
|
223
|
+
|
|
224
|
+
- [Claude Code](https://claude.ai/download)
|
|
225
|
+
- Node.js 18+
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
package/package.json
CHANGED
|
@@ -7,85 +7,86 @@ export function guardrail(c) {
|
|
|
7
7
|
executable: true,
|
|
8
8
|
content: `#!/usr/bin/env bash
|
|
9
9
|
# APED Guardrail — UserPromptSubmit hook
|
|
10
|
-
#
|
|
11
|
-
#
|
|
10
|
+
# Uses the official Claude Code hook output format.
|
|
11
|
+
# See: https://code.claude.com/docs/hooks
|
|
12
12
|
|
|
13
|
-
set -
|
|
13
|
+
# NOT using set -e or pipefail — grep returns exit 1 on no match
|
|
14
|
+
# which would kill the script. We handle errors explicitly.
|
|
14
15
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
CONFIG_FILE="$PROJECT_ROOT/${a}/config.yaml"
|
|
18
|
-
OUTPUT_DIR="$PROJECT_ROOT/${o}"
|
|
16
|
+
# ── Read stdin JSON ──
|
|
17
|
+
INPUT=$(cat < /dev/stdin)
|
|
19
18
|
|
|
20
|
-
#
|
|
21
|
-
|
|
22
|
-
|
|
19
|
+
# Extract prompt using simple string parsing (no jq dependency)
|
|
20
|
+
PROMPT=""
|
|
21
|
+
if command -v jq &>/dev/null; then
|
|
22
|
+
PROMPT=$(echo "$INPUT" | jq -r '.prompt // empty' 2>/dev/null || echo "")
|
|
23
|
+
else
|
|
24
|
+
PROMPT=$(echo "$INPUT" | grep -o '"prompt":"[^"]*"' | sed 's/"prompt":"//;s/"$//' 2>/dev/null || echo "")
|
|
25
|
+
fi
|
|
23
26
|
|
|
24
27
|
# If no prompt or empty, allow
|
|
25
28
|
if [[ -z "$PROMPT" ]]; then
|
|
26
29
|
exit 0
|
|
27
30
|
fi
|
|
28
31
|
|
|
32
|
+
# ── Resolve paths ──
|
|
33
|
+
PROJECT_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
|
|
34
|
+
STATE_FILE="$PROJECT_ROOT/${o}/state.yaml"
|
|
35
|
+
CONFIG_FILE="$PROJECT_ROOT/${a}/config.yaml"
|
|
36
|
+
OUTPUT_DIR="$PROJECT_ROOT/${o}"
|
|
37
|
+
|
|
29
38
|
# ── Read current phase from state.yaml ──
|
|
30
39
|
CURRENT_PHASE="none"
|
|
31
40
|
if [[ -f "$STATE_FILE" ]]; then
|
|
32
|
-
|
|
41
|
+
PHASE_LINE=$(grep 'current_phase:' "$STATE_FILE" 2>/dev/null || echo "")
|
|
42
|
+
if [[ -n "$PHASE_LINE" ]]; then
|
|
43
|
+
CURRENT_PHASE=$(echo "$PHASE_LINE" | sed 's/.*current_phase:[[:space:]]*//;s/"//g;s/^[[:space:]]*//;s/[[:space:]]*$//' || echo "none")
|
|
44
|
+
fi
|
|
33
45
|
fi
|
|
34
46
|
|
|
35
47
|
# ── Read communication language from config ──
|
|
36
|
-
|
|
48
|
+
COMM_LANG="english"
|
|
37
49
|
if [[ -f "$CONFIG_FILE" ]]; then
|
|
38
|
-
|
|
50
|
+
LANG_LINE=$(grep 'communication_language:' "$CONFIG_FILE" 2>/dev/null || echo "")
|
|
51
|
+
if [[ -n "$LANG_LINE" ]]; then
|
|
52
|
+
COMM_LANG=$(echo "$LANG_LINE" | sed 's/.*communication_language:[[:space:]]*//' | tr -d ' ' || echo "english")
|
|
53
|
+
fi
|
|
39
54
|
fi
|
|
40
55
|
|
|
41
|
-
# ── Detect
|
|
56
|
+
# ── Detect intent from prompt ──
|
|
42
57
|
PROMPT_LOWER=$(echo "$PROMPT" | tr '[:upper:]' '[:lower:]')
|
|
43
58
|
|
|
44
|
-
# Detect APED command invocations
|
|
45
59
|
WANTS_ANALYZE=false
|
|
46
60
|
WANTS_PRD=false
|
|
47
61
|
WANTS_EPICS=false
|
|
48
62
|
WANTS_DEV=false
|
|
49
63
|
WANTS_REVIEW=false
|
|
50
64
|
WANTS_ALL=false
|
|
51
|
-
WANTS_CODE=false
|
|
52
|
-
|
|
53
|
-
[[ "$PROMPT_LOWER" =~ (aped-a|/aped-a|analyze|analyse|research) ]] && WANTS_ANALYZE=true
|
|
54
|
-
[[ "$PROMPT_LOWER" =~ (aped-p|/aped-p|prd|product.req) ]] && WANTS_PRD=true
|
|
55
|
-
[[ "$PROMPT_LOWER" =~ (aped-e|/aped-e|epic|stories|story) ]] && WANTS_EPICS=true
|
|
56
|
-
[[ "$PROMPT_LOWER" =~ (aped-d|/aped-d|dev|implement|code|build|create.*component|create.*service) ]] && WANTS_DEV=true
|
|
57
|
-
[[ "$PROMPT_LOWER" =~ (aped-r|/aped-r|review|audit) ]] && WANTS_REVIEW=true
|
|
58
|
-
[[ "$PROMPT_LOWER" =~ (aped-all|/aped-all|full.pipeline|start.from.scratch) ]] && WANTS_ALL=true
|
|
59
65
|
WANTS_QUICK=false
|
|
66
|
+
WANTS_CODE=false
|
|
60
67
|
|
|
61
|
-
|
|
62
|
-
|
|
68
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-a|/aped-a|analyze|analyse|research)' && WANTS_ANALYZE=true
|
|
69
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-p|/aped-p|prd|product.req)' && WANTS_PRD=true
|
|
70
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-e|/aped-e|epic|stories|story)' && WANTS_EPICS=true
|
|
71
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-d|/aped-d|dev|implement|build|create.*component|create.*service)' && WANTS_DEV=true
|
|
72
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-r|/aped-r|review|audit)' && WANTS_REVIEW=true
|
|
73
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-all|/aped-all|full.pipeline|start.from.scratch)' && WANTS_ALL=true
|
|
74
|
+
echo "$PROMPT_LOWER" | grep -qE '(aped-quick|/aped-quick|quick.fix|quick.feature|hotfix)' && WANTS_QUICK=true
|
|
75
|
+
echo "$PROMPT_LOWER" | grep -qE '(code|implement|write.*function|create.*file|add.*feature|fix.*bug|refactor)' && WANTS_CODE=true
|
|
63
76
|
|
|
64
77
|
# ── Check artifact existence ──
|
|
65
78
|
HAS_BRIEF=false
|
|
66
79
|
HAS_PRD=false
|
|
67
80
|
HAS_EPICS=false
|
|
68
81
|
|
|
69
|
-
[[ -
|
|
70
|
-
|
|
71
|
-
|
|
82
|
+
if [[ -d "$OUTPUT_DIR" ]]; then
|
|
83
|
+
test -n "$(find "$OUTPUT_DIR" -maxdepth 1 -name '*brief*' 2>/dev/null | head -1)" && HAS_BRIEF=true
|
|
84
|
+
test -n "$(find "$OUTPUT_DIR" -maxdepth 1 -name '*prd*' 2>/dev/null | head -1)" && HAS_PRD=true
|
|
85
|
+
test -n "$(find "$OUTPUT_DIR" -maxdepth 1 -name '*epic*' 2>/dev/null | head -1)" && HAS_EPICS=true
|
|
86
|
+
fi
|
|
72
87
|
|
|
73
88
|
# ── Phase-aware guardrail logic ──
|
|
74
|
-
WARNINGS=
|
|
75
|
-
|
|
76
|
-
# Phase transition map: none → analyze → prd → ux → epics → dev ↔ review → done
|
|
77
|
-
PHASE_ORDER="none analyze prd ux epics dev review done"
|
|
78
|
-
|
|
79
|
-
phase_index() {
|
|
80
|
-
local i=0
|
|
81
|
-
for p in $PHASE_ORDER; do
|
|
82
|
-
[[ "$p" == "$1" ]] && echo "$i" && return
|
|
83
|
-
i=$((i + 1))
|
|
84
|
-
done
|
|
85
|
-
echo "0"
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
CURRENT_IDX=$(phase_index "$CURRENT_PHASE")
|
|
89
|
+
WARNINGS=""
|
|
89
90
|
|
|
90
91
|
# Rule 0: Quick mode bypasses pipeline checks
|
|
91
92
|
if [[ "$WANTS_QUICK" == "true" ]]; then
|
|
@@ -95,65 +96,66 @@ fi
|
|
|
95
96
|
# Rule 1: Trying to code without epics/stories
|
|
96
97
|
if [[ "$WANTS_CODE" == "true" || "$WANTS_DEV" == "true" ]] && [[ "$CURRENT_PHASE" != "dev" && "$CURRENT_PHASE" != "review" ]]; then
|
|
97
98
|
if [[ "$HAS_EPICS" == "false" ]]; then
|
|
98
|
-
WARNINGS
|
|
99
|
+
WARNINGS="$WARNINGS\\nSKIP_DETECTED: Attempting dev/code without epics. Current phase: $CURRENT_PHASE. Run /aped-a, /aped-p, /aped-e first."
|
|
99
100
|
elif [[ "$HAS_PRD" == "false" ]]; then
|
|
100
|
-
WARNINGS
|
|
101
|
+
WARNINGS="$WARNINGS\\nSKIP_DETECTED: Attempting dev/code without PRD. Current phase: $CURRENT_PHASE. Run /aped-a, /aped-p first."
|
|
101
102
|
fi
|
|
102
103
|
fi
|
|
103
104
|
|
|
104
105
|
# Rule 2: PRD without brief
|
|
105
106
|
if [[ "$WANTS_PRD" == "true" ]] && [[ "$HAS_BRIEF" == "false" ]] && [[ "$CURRENT_PHASE" != "prd" ]]; then
|
|
106
|
-
WARNINGS
|
|
107
|
+
WARNINGS="$WARNINGS\\nMISSING_ARTIFACT: No product brief found. Run /aped-a first."
|
|
107
108
|
fi
|
|
108
109
|
|
|
109
110
|
# Rule 3: Epics without PRD
|
|
110
111
|
if [[ "$WANTS_EPICS" == "true" ]] && [[ "$HAS_PRD" == "false" ]]; then
|
|
111
|
-
WARNINGS
|
|
112
|
+
WARNINGS="$WARNINGS\\nMISSING_ARTIFACT: No PRD found. Run /aped-p first."
|
|
112
113
|
fi
|
|
113
114
|
|
|
114
115
|
# Rule 4: Review without dev
|
|
115
116
|
if [[ "$WANTS_REVIEW" == "true" ]] && [[ "$CURRENT_PHASE" != "dev" && "$CURRENT_PHASE" != "review" ]]; then
|
|
116
|
-
WARNINGS
|
|
117
|
+
WARNINGS="$WARNINGS\\nPREMATURE_REVIEW: No story developed yet. Run /aped-d first."
|
|
117
118
|
fi
|
|
118
119
|
|
|
119
|
-
# Rule 5:
|
|
120
|
+
# Rule 5: Modifying upstream during dev
|
|
120
121
|
if [[ "$CURRENT_PHASE" == "dev" || "$CURRENT_PHASE" == "review" ]]; then
|
|
121
122
|
if [[ "$WANTS_PRD" == "true" || "$WANTS_ANALYZE" == "true" ]]; then
|
|
122
|
-
WARNINGS
|
|
123
|
+
WARNINGS="$WARNINGS\\nSCOPE_CHANGE: Phase is '$CURRENT_PHASE'. Modifying PRD/brief invalidates epics and stories. Use /aped-c instead."
|
|
123
124
|
fi
|
|
124
125
|
fi
|
|
125
126
|
|
|
126
127
|
# Rule 6: Skipping phases
|
|
127
|
-
if [[ "$WANTS_DEV" == "true" ]] && [[ "$
|
|
128
|
+
if [[ "$WANTS_DEV" == "true" ]] && [[ "$WANTS_ALL" == "false" ]]; then
|
|
128
129
|
if [[ "$CURRENT_PHASE" == "none" || "$CURRENT_PHASE" == "analyze" ]]; then
|
|
129
|
-
WARNINGS
|
|
130
|
+
WARNINGS="$WARNINGS\\nPHASE_SKIP: Jumping from '$CURRENT_PHASE' to dev skips critical steps. Pipeline: Analyze -> PRD -> Epics -> Dev."
|
|
130
131
|
fi
|
|
131
132
|
fi
|
|
132
133
|
|
|
133
|
-
# ──
|
|
134
|
-
if [[
|
|
135
|
-
# No issues, allow silently
|
|
134
|
+
# ── No warnings = allow silently ──
|
|
135
|
+
if [[ -z "$WARNINGS" ]]; then
|
|
136
136
|
exit 0
|
|
137
137
|
fi
|
|
138
138
|
|
|
139
|
-
# Build
|
|
140
|
-
CONTEXT="[APED GUARDRAIL
|
|
141
|
-
CONTEXT+="Current phase: $CURRENT_PHASE\\n"
|
|
142
|
-
CONTEXT+="Artifacts: brief=\${HAS_BRIEF}, prd=\${HAS_PRD}, epics=\${HAS_EPICS}\\n"
|
|
143
|
-
CONTEXT+="\\nWarnings detected:\\n"
|
|
144
|
-
|
|
145
|
-
for w in "\${WARNINGS[@]}"; do
|
|
146
|
-
CONTEXT+=" ⚠ $w\\n"
|
|
147
|
-
done
|
|
139
|
+
# ── Build context for Claude ──
|
|
140
|
+
CONTEXT="[APED GUARDRAIL] Pipeline coherence check.\\nCurrent phase: $CURRENT_PHASE | Artifacts: brief=$HAS_BRIEF, prd=$HAS_PRD, epics=$HAS_EPICS\\nWarnings:$WARNINGS"
|
|
148
141
|
|
|
149
|
-
if [[ "$
|
|
150
|
-
CONTEXT
|
|
142
|
+
if [[ "$COMM_LANG" == "french" ]] || [[ "$COMM_LANG" == "français" ]]; then
|
|
143
|
+
CONTEXT="$CONTEXT\\n\\nINSTRUCTION: Signale ces avertissements a l utilisateur en francais AVANT d executer quoi que ce soit. Explique le probleme et propose le chemin correct. Demande confirmation pour continuer."
|
|
151
144
|
else
|
|
152
|
-
CONTEXT
|
|
145
|
+
CONTEXT="$CONTEXT\\n\\nINSTRUCTION: Report these warnings to the user BEFORE executing anything. Explain the issue and suggest the correct pipeline path. Ask for confirmation to proceed."
|
|
153
146
|
fi
|
|
154
147
|
|
|
155
|
-
# Output
|
|
156
|
-
|
|
148
|
+
# ── Output using official Claude Code hook format ──
|
|
149
|
+
# UserPromptSubmit: use hookSpecificOutput.additionalContext to inject context
|
|
150
|
+
# Does NOT block — injects context so Claude warns the user
|
|
151
|
+
cat << HOOKEOF
|
|
152
|
+
{
|
|
153
|
+
"hookSpecificOutput": {
|
|
154
|
+
"hookEventName": "UserPromptSubmit",
|
|
155
|
+
"additionalContext": "$(echo "$CONTEXT" | sed 's/"/\\\\"/g')"
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
HOOKEOF
|
|
157
159
|
`,
|
|
158
160
|
},
|
|
159
161
|
{
|
package/src/templates/scripts.js
CHANGED
|
@@ -92,8 +92,8 @@ for section in "\${REQUIRED_SECTIONS[@]}"; do
|
|
|
92
92
|
fi
|
|
93
93
|
done
|
|
94
94
|
|
|
95
|
-
# Check FR format
|
|
96
|
-
FR_LINES=$(grep -E '
|
|
95
|
+
# Check FR format — accepts: FR1:, - FR1:, **FR1:**, * FR1:, etc.
|
|
96
|
+
FR_LINES=$(grep -E '(^|[-*>[:space:]])\\*{0,2}FR[0-9]+\\*{0,2}\\s*:' "$FILE" 2>/dev/null || true)
|
|
97
97
|
FR_COUNT=0
|
|
98
98
|
if [[ -n "$FR_LINES" ]]; then
|
|
99
99
|
FR_COUNT=$(echo "$FR_LINES" | wc -l | tr -d ' ')
|
|
@@ -111,7 +111,7 @@ fi
|
|
|
111
111
|
ANTI_PATTERNS=("easy" "intuitive" "fast" "responsive" "simple" "multiple" "several" "various")
|
|
112
112
|
|
|
113
113
|
for pattern in "\${ANTI_PATTERNS[@]}"; do
|
|
114
|
-
MATCHES=$(grep -inE
|
|
114
|
+
MATCHES=$(grep -inE 'FR[0-9]+.*:.*\\b\${pattern}\\b' "$FILE" 2>/dev/null || true)
|
|
115
115
|
if [[ -n "$MATCHES" ]]; then
|
|
116
116
|
ISSUES+=("ANTI-PATTERN '$pattern' found in FR: $MATCHES")
|
|
117
117
|
fi
|