all-for-claudecode 2.8.2 → 2.9.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/commands/analyze.md +3 -5
- package/commands/architect.md +3 -5
- package/commands/checkpoint.md +1 -1
- package/commands/clean.md +1 -1
- package/commands/consult.md +81 -3
- package/commands/doctor.md +1 -1
- package/commands/implement.md +8 -3
- package/commands/init.md +33 -14
- package/commands/plan.md +35 -4
- package/commands/principles.md +1 -1
- package/commands/qa.md +2 -5
- package/commands/resume.md +1 -1
- package/commands/review.md +41 -2
- package/commands/security.md +3 -5
- package/commands/spec.md +14 -2
- package/hooks/hooks.json +10 -0
- package/package.json +1 -1
- package/scripts/afc-doctor.sh +12 -0
- package/scripts/afc-subagent-context.sh +2 -27
- package/scripts/afc-tdd-guard.sh +108 -0
- package/scripts/afc-user-prompt-submit.sh +41 -23
- package/templates/afc-project.template.md +27 -0
- package/templates/afc.config.template.md +4 -3
|
@@ -6,14 +6,14 @@
|
|
|
6
6
|
},
|
|
7
7
|
"metadata": {
|
|
8
8
|
"description": "Automated pipeline for Claude Code — spec → plan → implement → review → clean",
|
|
9
|
-
"version": "2.
|
|
9
|
+
"version": "2.9.1"
|
|
10
10
|
},
|
|
11
11
|
"plugins": [
|
|
12
12
|
{
|
|
13
13
|
"name": "afc",
|
|
14
14
|
"source": "./",
|
|
15
15
|
"description": "Automated pipeline for Claude Code. Automates the full development cycle: spec → plan → implement → review → clean.",
|
|
16
|
-
"version": "2.
|
|
16
|
+
"version": "2.9.1",
|
|
17
17
|
"category": "automation",
|
|
18
18
|
"tags": ["pipeline", "automation", "spec", "plan", "implement", "review", "critic-loop"]
|
|
19
19
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "afc",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.9.1",
|
|
4
4
|
"description": "Automated pipeline for Claude Code. Automates the full development cycle: spec → plan → implement → review → clean.",
|
|
5
5
|
"author": { "name": "jhlee0409", "email": "relee6203@gmail.com" },
|
|
6
6
|
"homepage": "https://github.com/jhlee0409/all-for-claudecode",
|
package/commands/analyze.md
CHANGED
|
@@ -23,12 +23,10 @@ model: sonnet
|
|
|
23
23
|
|
|
24
24
|
## Config Load
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
- `## Code Style` — language, naming conventions, lint rules
|
|
29
|
-
- `## Project Context` — framework, state management, testing, etc.
|
|
26
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
27
|
+
Read `.claude/afc.config.md` if CI commands are needed.
|
|
30
28
|
|
|
31
|
-
If
|
|
29
|
+
If neither rules file nor config exists: read `CLAUDE.md` for architecture info. Proceed without config if neither exists.
|
|
32
30
|
|
|
33
31
|
## Execution Steps
|
|
34
32
|
|
package/commands/architect.md
CHANGED
|
@@ -26,12 +26,10 @@ model: sonnet
|
|
|
26
26
|
|
|
27
27
|
## Config Load
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- `## Code Style` — language, naming conventions, lint rules
|
|
32
|
-
- `## Project Context` — framework, state management, testing, etc.
|
|
29
|
+
Read `.claude/afc.config.md` if CI commands are needed.
|
|
30
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
33
31
|
|
|
34
|
-
If
|
|
32
|
+
If neither rules file nor config exists: read `CLAUDE.md` for architecture info. Assume "Layered Architecture" if no source has it.
|
|
35
33
|
|
|
36
34
|
## Execution Steps
|
|
37
35
|
|
package/commands/checkpoint.md
CHANGED
package/commands/clean.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: afc:clean
|
|
3
3
|
description: "Pipeline artifact cleanup and codebase hygiene — use when the user asks to clean up artifacts, remove pipeline files, or finalize after implementation"
|
|
4
4
|
argument-hint: "[feature name — defaults to current pipeline feature]"
|
|
5
|
-
model:
|
|
5
|
+
model: sonnet
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# /afc:clean — Pipeline Cleanup
|
package/commands/consult.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: afc:consult
|
|
3
|
-
description: "Expert consultation — use when the user asks for expert advice, wants to consult a specialist,
|
|
3
|
+
description: "Expert consultation — use when the user asks for expert advice, wants to consult a specialist, needs domain-specific guidance on backend, infra, PM, design, marketing, legal, or tech decisions, or wants to think together, brainstorm, discuss ideas, or have a structured dialogue"
|
|
4
4
|
argument-hint: "[domain?] \"[question]\" [brief|deep]"
|
|
5
5
|
model: sonnet
|
|
6
6
|
---
|
|
@@ -14,7 +14,7 @@ model: sonnet
|
|
|
14
14
|
## Arguments
|
|
15
15
|
|
|
16
16
|
- `$ARGUMENTS` — (optional) Format: `[domain] "[question]" [brief|deep]`
|
|
17
|
-
- `domain` — one of: `backend`, `infra`, `pm`, `design`, `marketing`, `legal`, `security`, `advisor` (optional, auto-detected if omitted)
|
|
17
|
+
- `domain` — one of: `backend`, `infra`, `pm`, `design`, `marketing`, `legal`, `security`, `advisor`, `peer` (optional, auto-detected if omitted)
|
|
18
18
|
- `question` — the consultation question (optional, enters exploratory mode if omitted)
|
|
19
19
|
- `brief|deep` — depth hint (optional, default: `auto`)
|
|
20
20
|
|
|
@@ -45,6 +45,7 @@ If `$ARGUMENTS` is empty → go to Step 2 (domain selection).
|
|
|
45
45
|
| legal | GDPR, CCPA, privacy, cookie, consent, license, GPL, MIT, compliance, terms of service, data protection, PII, HIPAA, regulation, policy |
|
|
46
46
|
| security | XSS, CSRF, injection, OWASP, vulnerability, attack, exploit, encryption, secret, credential, CORS, CSP, rate limit, brute force, penetration |
|
|
47
47
|
| advisor | library, framework, stack, tool, package, which to use, alternative, compare, choose, select, recommend, what exists, ecosystem, best option, switch to |
|
|
48
|
+
| peer | think together, brainstorm, discuss, explore idea, talk through, figure out, pros and cons, what if, should I, direction, approach, trade-off, opinion, weigh options |
|
|
48
49
|
|
|
49
50
|
Match rules:
|
|
50
51
|
- Case-insensitive keyword matching against the question
|
|
@@ -65,9 +66,79 @@ Options:
|
|
|
65
66
|
6. Legal — GDPR, privacy, licenses, compliance, terms of service
|
|
66
67
|
7. Security — application security, OWASP, threat modeling, secure coding
|
|
67
68
|
8. Advisor — technology/library/framework selection, ecosystem navigation, stack decisions
|
|
69
|
+
9. Peer — think together, brainstorm, discuss ideas, explore directions as equals
|
|
68
70
|
```
|
|
69
71
|
|
|
70
|
-
### 3.
|
|
72
|
+
### 3. Peer Mode (if domain is `peer`)
|
|
73
|
+
|
|
74
|
+
If the detected domain is `peer`, **do not delegate to a subagent**. Run the dialogue directly in the main context.
|
|
75
|
+
|
|
76
|
+
#### Behavior Principles
|
|
77
|
+
|
|
78
|
+
You are a thinking partner, not an expert giving answers. Follow these rules:
|
|
79
|
+
|
|
80
|
+
1. **Ask before answering.** Default to questions that deepen the user's thinking, not solutions. "What would happen if...?", "What are you optimizing for?"
|
|
81
|
+
2. **Challenge, don't agree.** Apply the Anti-Sycophancy Rules from `expert-protocol.md`. When the user states a direction, probe its weaknesses before supporting it.
|
|
82
|
+
3. **Present the strongest counter-argument.** Steel-man the opposing view: "The best case for NOT doing this is..."
|
|
83
|
+
4. **Name what's been decided and what hasn't.** Periodically summarize: "So far we've landed on X. Still open: Y and Z."
|
|
84
|
+
5. **Suggest convergence, don't force it.** When the discussion feels circular or key decisions are made, say so: "I think we have enough to move forward. Want to wrap up?"
|
|
85
|
+
|
|
86
|
+
#### Coaching Techniques
|
|
87
|
+
|
|
88
|
+
Use these as appropriate — not all at once, not in order:
|
|
89
|
+
|
|
90
|
+
- **5 Whys** — repeat "why?" to reach the root motivation
|
|
91
|
+
- **Pre-mortem** — "If this fails in 6 months, what went wrong?"
|
|
92
|
+
- **Constraint flip** — "What if you had half the time?" / "What if cost didn't matter?"
|
|
93
|
+
- **Steel-manning** — present the strongest version of the opposing view
|
|
94
|
+
- **Bisection** — "Is the core question A or B?" to narrow scope
|
|
95
|
+
|
|
96
|
+
#### Codebase Context
|
|
97
|
+
|
|
98
|
+
If the discussion involves the current project:
|
|
99
|
+
- Read relevant files (Read/Glob/Grep) to ground the conversation in reality
|
|
100
|
+
- Reference actual code, not hypothetical structures
|
|
101
|
+
- Note existing patterns that constrain or enable options
|
|
102
|
+
|
|
103
|
+
#### Wrapping Up
|
|
104
|
+
|
|
105
|
+
When the user signals completion (or agrees to your convergence suggestion):
|
|
106
|
+
|
|
107
|
+
1. Write `.claude/afc/discuss.md` with:
|
|
108
|
+
|
|
109
|
+
```markdown
|
|
110
|
+
# Discussion: {topic}
|
|
111
|
+
|
|
112
|
+
> Date: {YYYY-MM-DD}
|
|
113
|
+
> Seed: {original question/topic}
|
|
114
|
+
|
|
115
|
+
## Key Decisions
|
|
116
|
+
- [DECIDED] {decision} — {rationale}
|
|
117
|
+
|
|
118
|
+
## Open Questions
|
|
119
|
+
- [OPEN] {unresolved item}
|
|
120
|
+
|
|
121
|
+
## Summary
|
|
122
|
+
{3-5 sentence synthesis of what was discussed and concluded}
|
|
123
|
+
|
|
124
|
+
## Next Steps
|
|
125
|
+
- {recommended action, e.g., → /afc:spec "...", → /afc:plan "...", → /afc:research "..."}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
2. Output:
|
|
129
|
+
```
|
|
130
|
+
Discussion complete
|
|
131
|
+
├─ .claude/afc/discuss.md
|
|
132
|
+
├─ Decisions: {count}
|
|
133
|
+
├─ Open questions: {count}
|
|
134
|
+
└─ Suggested next: {command}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
**Skip Steps 4-6 and end here.**
|
|
138
|
+
|
|
139
|
+
---
|
|
140
|
+
|
|
141
|
+
### 3b. Construct Expert Prompt (non-peer domains)
|
|
71
142
|
|
|
72
143
|
Build the prompt for the expert agent:
|
|
73
144
|
|
|
@@ -146,6 +217,12 @@ Follow-up options:
|
|
|
146
217
|
# With depth hint
|
|
147
218
|
/afc:consult infra "How should I set up CI/CD?" deep
|
|
148
219
|
|
|
220
|
+
# Peer mode — think together (explicit)
|
|
221
|
+
/afc:consult peer "Should we split this into a monorepo or keep it separate?"
|
|
222
|
+
|
|
223
|
+
# Peer mode — auto-detected from keywords
|
|
224
|
+
/afc:consult "Let's think through the onboarding flow together"
|
|
225
|
+
|
|
149
226
|
# No arguments (domain selection prompt)
|
|
150
227
|
/afc:consult
|
|
151
228
|
```
|
|
@@ -158,3 +235,4 @@ Follow-up options:
|
|
|
158
235
|
- **Domain adapters**: Industry-specific guardrails (fintech, ecommerce, healthcare) auto-loaded based on project profile.
|
|
159
236
|
- **Pipeline-independent**: Works anytime, no active pipeline required. If a pipeline is active, experts consider the current phase context.
|
|
160
237
|
- **Cross-referral**: Experts may suggest consulting another domain expert when a question crosses boundaries.
|
|
238
|
+
- **Peer mode**: Unlike other domains, `peer` runs directly in the main context (no subagent). It produces `.claude/afc/discuss.md` on wrap-up. Overwritten on each new peer session — rename to preserve.
|
package/commands/doctor.md
CHANGED
package/commands/implement.md
CHANGED
|
@@ -313,9 +313,14 @@ This enables granular rollback: `git reset --hard afc/phase-{N}` restores state
|
|
|
313
313
|
For each task:
|
|
314
314
|
|
|
315
315
|
1. **Read files**: always read files before modifying them
|
|
316
|
-
2. **
|
|
317
|
-
|
|
318
|
-
|
|
316
|
+
2. **TDD cycle** (when plan.md Test Strategy classifies the task's target file as "required"):
|
|
317
|
+
- **Red**: write the test file first (failing test that defines expected behavior)
|
|
318
|
+
- **Green**: implement the minimum code to pass the test
|
|
319
|
+
- **Refactor**: clean up while keeping tests green
|
|
320
|
+
- If `{config.tdd}` is `strict` or `guide`: always follow this order. If `off` or unset: recommended but not enforced.
|
|
321
|
+
3. **Implement**: write code following the design in plan.md
|
|
322
|
+
4. **Type/Lint check**: verify new code passes `{config.gate}`
|
|
323
|
+
5. **Update tasks.md**: mark completed tasks as `[x]`
|
|
319
324
|
```markdown
|
|
320
325
|
- [x] T001 {description} ← complete
|
|
321
326
|
- [ ] T002 {description} ← incomplete
|
package/commands/init.md
CHANGED
|
@@ -7,7 +7,7 @@ allowed-tools:
|
|
|
7
7
|
- Write
|
|
8
8
|
- Bash
|
|
9
9
|
- Glob
|
|
10
|
-
model:
|
|
10
|
+
model: sonnet
|
|
11
11
|
---
|
|
12
12
|
|
|
13
13
|
# /afc:init — Project Initial Setup
|
|
@@ -125,7 +125,25 @@ Write sections as natural descriptions — **no YAML code blocks** except for CI
|
|
|
125
125
|
For items that cannot be inferred: note `TODO: Adjust for your project` inline.
|
|
126
126
|
Save to `.claude/afc.config.md`.
|
|
127
127
|
|
|
128
|
-
### 4.5. Generate Project
|
|
128
|
+
### 4.5. Generate Project Rules File
|
|
129
|
+
|
|
130
|
+
Generate `.claude/rules/afc-project.md` — a concise summary of project rules that Claude Code auto-loads for all conversations and sub-agents.
|
|
131
|
+
|
|
132
|
+
1. Create `.claude/rules/` directory if it does not exist
|
|
133
|
+
2. If `.claude/rules/afc-project.md` already exists:
|
|
134
|
+
- If it contains `<!-- afc:auto-generated` marker: overwrite silently (auto-generated file, safe to regenerate)
|
|
135
|
+
- If it does NOT contain the marker: ask user "Project rules file exists (user-managed). Overwrite with auto-generated version?" — skip if declined
|
|
136
|
+
3. Reference `${CLAUDE_PLUGIN_ROOT}/templates/afc-project.template.md` for section structure
|
|
137
|
+
4. Fill in from the analysis performed in Step 3:
|
|
138
|
+
- **Architecture**: pattern, key layers, import rules, path alias — concise bullet points
|
|
139
|
+
- **Code Style**: language, naming conventions, lint rules — concise bullet points
|
|
140
|
+
- **Project Context**: framework, state management, styling, testing, DB/ORM — concise bullet points
|
|
141
|
+
5. Include `<!-- afc:auto-generated — do not edit manually; regenerate with /afc:init -->` as the first line
|
|
142
|
+
6. Keep total length **under 30 lines** (excluding the marker comment) — rules only, no explanations
|
|
143
|
+
7. Save to `.claude/rules/afc-project.md`
|
|
144
|
+
8. Print: `Project rules: .claude/rules/afc-project.md (auto-loaded by Claude Code)`
|
|
145
|
+
|
|
146
|
+
### 4.6. Generate Project Profile
|
|
129
147
|
|
|
130
148
|
Generate `.claude/afc/project-profile.md` for expert consultation agents:
|
|
131
149
|
|
|
@@ -253,18 +271,18 @@ Classify the user's intent and route to the matching skill. Use semantic underst
|
|
|
253
271
|
2. **Compound intents**: Route to the primary intent. The pipeline handles sequencing internally.
|
|
254
272
|
3. **Design-first**: When scope is non-trivial (multiple files, architectural decisions needed), prefer `afc:auto` or `afc:plan` over direct `afc:implement`.
|
|
255
273
|
|
|
256
|
-
User-only (not auto-triggered —
|
|
257
|
-
- `afc:doctor` —
|
|
258
|
-
- `afc:architect` —
|
|
259
|
-
- `afc:security` —
|
|
260
|
-
- `afc:checkpoint` —
|
|
261
|
-
- `afc:resume` —
|
|
262
|
-
- `afc:principles` —
|
|
263
|
-
- `afc:clean` —
|
|
264
|
-
- `afc:triage` —
|
|
265
|
-
- `afc:learner` —
|
|
266
|
-
- `afc:pr-comment` —
|
|
267
|
-
- `afc:release-notes` —
|
|
274
|
+
User-only (not auto-triggered — when user invokes directly via `/afc:X`, execute the skill immediately):
|
|
275
|
+
- `afc:doctor` — plugin health check
|
|
276
|
+
- `afc:architect` — architecture review
|
|
277
|
+
- `afc:security` — security scan
|
|
278
|
+
- `afc:checkpoint` — session save
|
|
279
|
+
- `afc:resume` — session restore
|
|
280
|
+
- `afc:principles` — project principles management
|
|
281
|
+
- `afc:clean` — pipeline cleanup (artifact cleanup, dead code scan, pipeline flag release)
|
|
282
|
+
- `afc:triage` — parallel PR/issue triage
|
|
283
|
+
- `afc:learner` — pattern learning or rule promotion
|
|
284
|
+
- `afc:pr-comment` — post PR review comments to GitHub
|
|
285
|
+
- `afc:release-notes` — generate release notes from git history
|
|
268
286
|
|
|
269
287
|
## Pipeline
|
|
270
288
|
|
|
@@ -302,6 +320,7 @@ The following rules were auto-generated to resolve conflicts:
|
|
|
302
320
|
```
|
|
303
321
|
all-for-claudecode initialization complete
|
|
304
322
|
├─ Config: .claude/afc.config.md
|
|
323
|
+
├─ Rules: .claude/rules/afc-project.md (auto-loaded)
|
|
305
324
|
├─ Framework: {detected framework}
|
|
306
325
|
├─ Architecture: {detected style}
|
|
307
326
|
├─ Package Manager: {detected manager}
|
package/commands/plan.md
CHANGED
|
@@ -26,7 +26,8 @@ model: sonnet
|
|
|
26
26
|
|
|
27
27
|
## Config Load
|
|
28
28
|
|
|
29
|
-
**Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above).
|
|
29
|
+
**Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above) — needed for CI Commands (YAML).
|
|
30
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
30
31
|
|
|
31
32
|
If config file is missing:
|
|
32
33
|
1. Ask the user: "`.claude/afc.config.md` not found. Run `/afc:init` to set up the project?"
|
|
@@ -40,7 +41,7 @@ If config file is missing:
|
|
|
40
41
|
1. Check **current branch** → `BRANCH_NAME`
|
|
41
42
|
2. Find **.claude/afc/specs/{feature}/spec.md**:
|
|
42
43
|
- Search under `.claude/afc/specs/` for a directory matching the current branch name or `$ARGUMENTS`
|
|
43
|
-
- If not found: print "spec.md not found.
|
|
44
|
+
- If not found: print "spec.md not found. Running `/afc:spec` to create it first." then **execute `/afc:spec`** with `$ARGUMENTS`. After spec completes, **restart this command** from the beginning with the original `$ARGUMENTS`
|
|
44
45
|
3. Read full **spec.md**
|
|
45
46
|
4. Read **.claude/afc/memory/principles.md** (if present)
|
|
46
47
|
5. Read **CLAUDE.md** project context
|
|
@@ -109,7 +110,7 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
|
|
|
109
110
|
{summary of core requirements from spec + technical approach, 3-5 sentences}
|
|
110
111
|
|
|
111
112
|
## Technical Context
|
|
112
|
-
{Summarize key project settings from afc.
|
|
113
|
+
{Summarize key project settings from .claude/rules/afc-project.md (auto-loaded) and afc.config.md}
|
|
113
114
|
- **Constraints**: {constraints extracted from spec}
|
|
114
115
|
|
|
115
116
|
## Principles Check
|
|
@@ -131,6 +132,35 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
|
|
|
131
132
|
### API Design (omit if not applicable)
|
|
132
133
|
{plan for new API endpoints or use of existing APIs}
|
|
133
134
|
|
|
135
|
+
## Test Strategy
|
|
136
|
+
|
|
137
|
+
> Written alongside the File Change Map. Classify each implementation file and decide test coverage level.
|
|
138
|
+
> Determines which files need test coverage and at what level.
|
|
139
|
+
|
|
140
|
+
### Code Classification
|
|
141
|
+
|
|
142
|
+
| File | Code Type | Test Need | Reason |
|
|
143
|
+
|------|-----------|:---------:|--------|
|
|
144
|
+
| {path} | {business-logic / pure-function / side-effect / framework / config / UI} | {required / optional / unnecessary} | {brief justification} |
|
|
145
|
+
|
|
146
|
+
> Classification guide:
|
|
147
|
+
> - **business-logic / pure-function**: Required — unit tests (AAA pattern)
|
|
148
|
+
> - **side-effect code** (external API, DB, file I/O): Required — integration tests with mocks
|
|
149
|
+
> - **framework / config / getter-setter / boilerplate**: Unnecessary — no test
|
|
150
|
+
> - **UI rendering** (no state logic): Optional — minimal snapshot or skip
|
|
151
|
+
|
|
152
|
+
### Test Pyramid
|
|
153
|
+
|
|
154
|
+
- **Unit tests**: {count} files ({which files})
|
|
155
|
+
- **Integration tests**: {count} files ({which files}, if applicable)
|
|
156
|
+
- **E2E tests**: {count} (if applicable, only for critical user flows)
|
|
157
|
+
|
|
158
|
+
### Required Test Cases (derived from spec EARS requirements)
|
|
159
|
+
|
|
160
|
+
{For each spec EARS requirement with `→ TC:` mapping, list the test case here}
|
|
161
|
+
- `should_{behavior}_when_{trigger}` → covers FR-{NNN}
|
|
162
|
+
- `should_{behavior}_while_{state}` → covers FR-{NNN}
|
|
163
|
+
|
|
134
164
|
## File Change Map
|
|
135
165
|
|
|
136
166
|
| File | Action | Description | Depends On | Phase |
|
|
@@ -139,6 +169,7 @@ Create `.claude/afc/specs/{feature}/plan.md`. **Must** follow the structure belo
|
|
|
139
169
|
|
|
140
170
|
> - **Depends On**: list file(s) that must be created/modified first (enables dependency-aware task generation in /afc:implement).
|
|
141
171
|
> - **Phase**: implementation phase number. Same-phase + no dependency + different file = parallelizable.
|
|
172
|
+
> - **Test files**: For each implementation file classified as "required" in Code Classification, include a corresponding test file in the same Phase. Test files are first-class citizens in the File Change Map.
|
|
142
173
|
|
|
143
174
|
## Implementation Context
|
|
144
175
|
|
|
@@ -215,7 +246,7 @@ Run the critic loop until convergence. Safety cap: 5 passes.
|
|
|
215
246
|
|
|
216
247
|
| Criterion | Validation |
|
|
217
248
|
|-----------|------------|
|
|
218
|
-
| **COMPLETENESS** | Are all requirements (FR-*) from spec.md reflected in the plan? |
|
|
249
|
+
| **COMPLETENESS** | Are all requirements (FR-*) from spec.md reflected in the plan? For each implementation file classified as "required" in Test Strategy Code Classification, does the File Change Map include a corresponding test file? Report: `{M}/{N} test pairs present`. |
|
|
219
250
|
| **FEASIBILITY** | Is it compatible with the existing codebase? Are dependencies available? |
|
|
220
251
|
| **ARCHITECTURE** | Does it comply with {config.architecture} rules? |
|
|
221
252
|
| **CROSS_CONSISTENCY** | Spec↔Plan cross-artifact validation (see checklist below) |
|
package/commands/principles.md
CHANGED
package/commands/qa.md
CHANGED
|
@@ -28,11 +28,8 @@ model: sonnet
|
|
|
28
28
|
|
|
29
29
|
## Config Load
|
|
30
30
|
|
|
31
|
-
**Always** read `.claude/afc.config.md` first
|
|
32
|
-
|
|
33
|
-
- `## Code Style` — language, naming conventions, lint rules
|
|
34
|
-
- `## CI Commands` — test, lint, gate commands (YAML)
|
|
35
|
-
- `## Project Context` — framework, state management, testing strategy
|
|
31
|
+
**Always** read `.claude/afc.config.md` first — needed for CI Commands (YAML: ci, gate, test).
|
|
32
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
36
33
|
|
|
37
34
|
If config file is missing: read `CLAUDE.md` for project info. Proceed without config if neither exists.
|
|
38
35
|
|
package/commands/resume.md
CHANGED
package/commands/review.md
CHANGED
|
@@ -9,6 +9,7 @@ allowed-tools:
|
|
|
9
9
|
- Glob
|
|
10
10
|
- Bash
|
|
11
11
|
- Task
|
|
12
|
+
- LSP
|
|
12
13
|
model: sonnet
|
|
13
14
|
---
|
|
14
15
|
|
|
@@ -28,7 +29,8 @@ model: sonnet
|
|
|
28
29
|
|
|
29
30
|
## Config Load
|
|
30
31
|
|
|
31
|
-
**Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above).
|
|
32
|
+
**Always** read `.claude/afc.config.md` first (read manually if not auto-loaded above) — needed for CI Commands (YAML).
|
|
33
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
32
34
|
|
|
33
35
|
If config file is missing:
|
|
34
36
|
1. Ask the user: "`.claude/afc.config.md` not found. Run `/afc:init` to set up the project?"
|
|
@@ -48,6 +50,33 @@ If config file is missing:
|
|
|
48
50
|
3. Read **full content** of each changed file (not just the diff — full context)
|
|
49
51
|
4. **Load spec context** (if available): Check for `.claude/afc/specs/{feature}/context.md` and `.claude/afc/specs/{feature}/spec.md`. If found, load them for SPEC_ALIGNMENT validation in the Critic Loop. If neither exists, SPEC_ALIGNMENT criterion is skipped with note "no spec artifacts available"
|
|
50
52
|
|
|
53
|
+
### 1.5. Reverse Impact Analysis
|
|
54
|
+
|
|
55
|
+
Before reviewing, identify **files affected by the changes** (not just the changed files themselves):
|
|
56
|
+
|
|
57
|
+
1. **For each changed file**, find files that depend on it:
|
|
58
|
+
- **LSP (preferred)**: `LSP(findReferences)` on exported symbols — tracks type references, function calls, re-exports
|
|
59
|
+
- **Grep (fallback)**: `Grep` for `import.*{filename}`, `require.*{filename}`, `source.*{filename}` patterns across the codebase
|
|
60
|
+
- LSP and Grep are complementary — use both when LSP is available (LSP catches type-level references Grep misses; Grep catches dynamic patterns LSP misses)
|
|
61
|
+
|
|
62
|
+
2. **Build impact map**:
|
|
63
|
+
```
|
|
64
|
+
Impact Map:
|
|
65
|
+
├─ src/auth/login.ts (changed)
|
|
66
|
+
│ └─ affected: src/pages/LoginPage.tsx, src/middleware/auth.ts
|
|
67
|
+
├─ scripts/afc-state.sh (changed)
|
|
68
|
+
│ └─ affected: scripts/afc-stop-gate.sh, scripts/afc-drift.sh (grep: source.*afc-state)
|
|
69
|
+
└─ Total: {N} changed files → {M} affected files
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
3. **Scope decision**:
|
|
73
|
+
- Affected files are NOT full review targets (that would explode scope)
|
|
74
|
+
- Instead, include them as **cross-reference context** in Step 2 and Step 3.5
|
|
75
|
+
- If an affected file has >3 references to a changed symbol → flag for closer inspection
|
|
76
|
+
|
|
77
|
+
4. **Limitations** (include in review output):
|
|
78
|
+
> ⚠ Dynamic dependencies not covered: runtime dispatch (`obj[method]()`), reflection, cross-language calls, config/env-driven branching. Manual verification recommended for these patterns.
|
|
79
|
+
|
|
51
80
|
### 2. Parallel Review (scaled by file count)
|
|
52
81
|
|
|
53
82
|
Choose review orchestration based on the number of changed files:
|
|
@@ -58,7 +87,8 @@ Before distributing files to review agents, collect cross-boundary context:
|
|
|
58
87
|
|
|
59
88
|
1. For each changed file, identify **outbound calls** to other changed files (imports + function calls)
|
|
60
89
|
2. For each outbound call target, extract: function signature + 1-line side-effect summary (e.g., "mutates playlist state", "triggers async cascade")
|
|
61
|
-
3. Include
|
|
90
|
+
3. Include the **Impact Map** from Step 1.5 — each agent receives the list of affected (non-changed) files that depend on its assigned files
|
|
91
|
+
4. Include this context in each review agent's prompt:
|
|
62
92
|
```
|
|
63
93
|
## Cross-File Context
|
|
64
94
|
This file calls:
|
|
@@ -176,6 +206,8 @@ After individual/parallel reviews complete, the **orchestrator** MUST perform a
|
|
|
176
206
|
|
|
177
207
|
**For 11+ file reviews**: This is especially critical because individual review agents cannot see cross-file interactions. The orchestrator MUST read callee implementations directly.
|
|
178
208
|
|
|
209
|
+
0. **Impact Map integration**: Use the Impact Map from Step 1.5 to prioritize verification. Affected files with >3 references to changed symbols should be read and checked for breakage — even if no finding was raised against them.
|
|
210
|
+
|
|
179
211
|
1. **Filter**: From all collected findings, select those involving:
|
|
180
212
|
- Call order changes (function A now calls B before C)
|
|
181
213
|
- Error handling modifications (try/catch scope changes, error propagation changes)
|
|
@@ -212,6 +244,13 @@ This step runs in the orchestrator context (not delegated), as it requires readi
|
|
|
212
244
|
| Warning | {N} | {summary} |
|
|
213
245
|
| Info | {N} | {summary} |
|
|
214
246
|
|
|
247
|
+
### Impact Analysis
|
|
248
|
+
| Changed File | Affected Files | Method |
|
|
249
|
+
|---|---|---|
|
|
250
|
+
| {path} | {affected file list} | LSP / Grep |
|
|
251
|
+
|
|
252
|
+
> ⚠ Dynamic dependencies (runtime dispatch, reflection, cross-language calls) require manual verification.
|
|
253
|
+
|
|
215
254
|
### Detailed Findings
|
|
216
255
|
|
|
217
256
|
#### C-{N}: {title}
|
package/commands/security.md
CHANGED
|
@@ -26,12 +26,10 @@ model: sonnet
|
|
|
26
26
|
|
|
27
27
|
## Config Load
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
- `## Architecture` — architecture pattern, layers, import rules
|
|
32
|
-
- `## Code Style` — language, naming conventions, lint rules
|
|
29
|
+
Architecture, Code Style, and Project Context are auto-loaded via `.claude/rules/afc-project.md`.
|
|
30
|
+
Read `.claude/afc.config.md` if CI commands are needed.
|
|
33
31
|
|
|
34
|
-
If
|
|
32
|
+
If neither rules file nor config exists: read `CLAUDE.md` for framework info. Assume "unknown" if no source has it.
|
|
35
33
|
|
|
36
34
|
For dependency audit command: infer from `packageManager` field in `package.json` or the lockfile (e.g., `npm audit`, `yarn audit`, `pnpm audit`).
|
|
37
35
|
|
package/commands/spec.md
CHANGED
|
@@ -99,8 +99,19 @@ Create `.claude/afc/specs/{feature-name}/spec.md`:
|
|
|
99
99
|
- [ ] Given {precondition}, When {action}, Then {result}
|
|
100
100
|
|
|
101
101
|
#### System Requirements (EARS notation)
|
|
102
|
-
|
|
103
|
-
|
|
102
|
+
|
|
103
|
+
> Use one of the 5 EARS patterns for each requirement. Each requirement must map to at least one expected test case (TC).
|
|
104
|
+
|
|
105
|
+
| Pattern | Template | Use When |
|
|
106
|
+
|---------|----------|----------|
|
|
107
|
+
| Ubiquitous | `THE System SHALL {behavior}` | Always-on property (no trigger needed) |
|
|
108
|
+
| Event-driven | `WHEN {trigger}, THE System SHALL {response}` | Specific event triggers a response |
|
|
109
|
+
| State-driven | `WHILE {state}, THE System SHALL {behavior}` | Behavior depends on system state |
|
|
110
|
+
| Unwanted | `IF {condition}, THE System SHALL {handling}` | Error/failure handling |
|
|
111
|
+
| Optional | `WHERE {feature/config active}, THE System SHALL {behavior}` | Feature flag or conditional capability |
|
|
112
|
+
|
|
113
|
+
- [ ] WHEN {trigger}, THE System SHALL {behavior} → TC: `should_{behavior}_when_{trigger}`
|
|
114
|
+
- [ ] WHILE {state}, THE System SHALL {behavior} → TC: `should_{behavior}_while_{state}`
|
|
104
115
|
|
|
105
116
|
### US2: {story title} [P2]
|
|
106
117
|
{same format}
|
|
@@ -172,6 +183,7 @@ Run the critic loop until convergence. Safety cap: 5 passes.
|
|
|
172
183
|
| **MEASURABILITY** | Are the success criteria measurable, not subjective? |
|
|
173
184
|
| **INDEPENDENCE** | Are implementation details (code, library names) absent from the spec? |
|
|
174
185
|
| **EDGE_CASES** | Are at least 2 edge cases identified? Any missing boundary conditions? |
|
|
186
|
+
| **TESTABILITY** | Does every System Requirement follow one of the 5 EARS patterns (WHEN/WHILE/IF/WHERE/SHALL)? Does each EARS requirement have a mapped TC (`→ TC: should_...`)? If not → FAIL and auto-fix: rewrite to EARS + generate TC mapping. |
|
|
175
187
|
|
|
176
188
|
**On FAIL**: auto-fix and continue to next pass.
|
|
177
189
|
**On ESCALATE**: pause, present options to user, apply choice, resume.
|
package/hooks/hooks.json
CHANGED
|
@@ -45,6 +45,16 @@
|
|
|
45
45
|
"statusMessage": "Checking spec immutability..."
|
|
46
46
|
}
|
|
47
47
|
]
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"matcher": "Edit|MultiEdit|Write|NotebookEdit",
|
|
51
|
+
"hooks": [
|
|
52
|
+
{
|
|
53
|
+
"type": "command",
|
|
54
|
+
"command": "\"${CLAUDE_PLUGIN_ROOT}/scripts/afc-tdd-guard.sh\"",
|
|
55
|
+
"statusMessage": "Checking TDD compliance..."
|
|
56
|
+
}
|
|
57
|
+
]
|
|
48
58
|
}
|
|
49
59
|
],
|
|
50
60
|
"PostToolUse": [
|
package/package.json
CHANGED
package/scripts/afc-doctor.sh
CHANGED
|
@@ -122,6 +122,18 @@ else
|
|
|
122
122
|
fail ".claude/afc.config.md not found" "run /afc:init"
|
|
123
123
|
fi
|
|
124
124
|
|
|
125
|
+
# Project rules file
|
|
126
|
+
RULES_FILE="$PROJECT_DIR/.claude/rules/afc-project.md"
|
|
127
|
+
if [ -f "$RULES_FILE" ]; then
|
|
128
|
+
if grep -q '<!-- afc:auto-generated' "$RULES_FILE" 2>/dev/null; then
|
|
129
|
+
pass "Project rules file exists (auto-generated)"
|
|
130
|
+
else
|
|
131
|
+
pass "Project rules file exists (user-managed)"
|
|
132
|
+
fi
|
|
133
|
+
else
|
|
134
|
+
warn "No .claude/rules/afc-project.md — project rules not auto-loaded" "run /afc:init to generate"
|
|
135
|
+
fi
|
|
136
|
+
|
|
125
137
|
# --- Category 3: CLAUDE.md Integration ---
|
|
126
138
|
section "CLAUDE.md Integration"
|
|
127
139
|
|
|
@@ -15,8 +15,6 @@ cleanup() {
|
|
|
15
15
|
}
|
|
16
16
|
trap cleanup EXIT
|
|
17
17
|
|
|
18
|
-
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
19
|
-
|
|
20
18
|
# Consume stdin (required -- pipe breaks if not consumed)
|
|
21
19
|
cat > /dev/null
|
|
22
20
|
|
|
@@ -34,31 +32,8 @@ PHASE=$(afc_state_read phase || echo "unknown")
|
|
|
34
32
|
# 3. Build context string
|
|
35
33
|
CONTEXT="[AFC PIPELINE] Feature: $FEATURE | Phase: $PHASE | [AFC] When this task matches an AFC skill (analyze, implement, review, debug, test, plan, spec, research, ideate), use the Skill tool to invoke it. Do not substitute with raw Task agents. When analyzing external systems, verify against official documentation."
|
|
36
34
|
|
|
37
|
-
# 4.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if [ -f "$CONFIG_FILE" ]; then
|
|
41
|
-
# Extract Architecture section (## Architecture to next ##)
|
|
42
|
-
# shellcheck disable=SC2001
|
|
43
|
-
ARCH=$(sed -n '/^## Architecture/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
|
|
44
|
-
if [ -n "$ARCH" ]; then
|
|
45
|
-
CONTEXT="$CONTEXT | Architecture: $ARCH"
|
|
46
|
-
fi
|
|
47
|
-
|
|
48
|
-
# Extract Code Style section (## Code Style to next ##)
|
|
49
|
-
# shellcheck disable=SC2001
|
|
50
|
-
STYLE=$(sed -n '/^## Code Style/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
|
|
51
|
-
if [ -n "$STYLE" ]; then
|
|
52
|
-
CONTEXT="$CONTEXT | Code Style: $STYLE"
|
|
53
|
-
fi
|
|
54
|
-
|
|
55
|
-
# Extract Project Context section (## Project Context to next ## or EOF)
|
|
56
|
-
# shellcheck disable=SC2001
|
|
57
|
-
PROJ_CTX=$(sed -n '/^## Project Context/,/^## /p' "$CONFIG_FILE" 2>/dev/null | sed '1d;/^## /d;/^$/d' | head -15 | tr '\n' ' ' | sed 's/ */ /g;s/^ *//;s/ *$//')
|
|
58
|
-
if [ -n "$PROJ_CTX" ]; then
|
|
59
|
-
CONTEXT="$CONTEXT | Project Context: $PROJ_CTX"
|
|
60
|
-
fi
|
|
61
|
-
fi
|
|
35
|
+
# 4. Architecture/Code Style/Project Context are auto-loaded via .claude/rules/afc-project.md
|
|
36
|
+
# No need to extract from afc.config.md — Claude Code loads rules files automatically
|
|
62
37
|
|
|
63
38
|
# 5. Output as hookSpecificOutput JSON (required for SubagentStart context injection)
|
|
64
39
|
if command -v jq &>/dev/null; then
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# PreToolUse Hook: TDD Guard — blocks non-test file writes during implement phase
|
|
4
|
+
# Only active when: pipeline active + phase=implement + tdd=strict (or warns on guide)
|
|
5
|
+
# tdd setting read from afc.config.md CI Commands YAML
|
|
6
|
+
|
|
7
|
+
# shellcheck source=afc-state.sh
|
|
8
|
+
. "$(dirname "$0")/afc-state.sh"
|
|
9
|
+
|
|
10
|
+
# shellcheck disable=SC2329
|
|
11
|
+
cleanup() {
|
|
12
|
+
:
|
|
13
|
+
}
|
|
14
|
+
trap cleanup EXIT
|
|
15
|
+
|
|
16
|
+
ALLOW='{"hookSpecificOutput":{"permissionDecision":"allow"}}'
|
|
17
|
+
|
|
18
|
+
# Consume stdin immediately (prevents SIGPIPE if exiting early)
|
|
19
|
+
INPUT=$(cat)
|
|
20
|
+
|
|
21
|
+
# If pipeline is inactive -> allow
|
|
22
|
+
if ! afc_state_is_active; then
|
|
23
|
+
printf '%s\n' "$ALLOW"
|
|
24
|
+
exit 0
|
|
25
|
+
fi
|
|
26
|
+
|
|
27
|
+
# Read current phase — only guard during implement
|
|
28
|
+
PHASE="$(afc_state_read phase || echo '')"
|
|
29
|
+
if [ "$PHASE" != "implement" ]; then
|
|
30
|
+
printf '%s\n' "$ALLOW"
|
|
31
|
+
exit 0
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Read tdd setting from afc.config.md (YAML in markdown — grep/sed parse)
|
|
35
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
36
|
+
CONFIG_FILE="$PROJECT_DIR/.claude/afc.config.md"
|
|
37
|
+
TDD_MODE="off"
|
|
38
|
+
|
|
39
|
+
if [ -f "$CONFIG_FILE" ]; then
|
|
40
|
+
TDD_MODE=$(grep -E '^tdd:' "$CONFIG_FILE" | head -1 | sed 's/^tdd:[[:space:]]*"//;s/".*$//' 2>/dev/null || echo "off")
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Normalize: empty or missing -> off
|
|
44
|
+
TDD_MODE="${TDD_MODE:-off}"
|
|
45
|
+
|
|
46
|
+
# If tdd is off -> allow immediately (0ms overhead goal)
|
|
47
|
+
if [ "$TDD_MODE" = "off" ]; then
|
|
48
|
+
printf '%s\n' "$ALLOW"
|
|
49
|
+
exit 0
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
if [ -z "$INPUT" ]; then
|
|
53
|
+
printf '%s\n' "$ALLOW"
|
|
54
|
+
exit 0
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
# Extract file_path from tool_input
|
|
58
|
+
FILE_PATH=""
|
|
59
|
+
if command -v jq &> /dev/null; then
|
|
60
|
+
FILE_PATH=$(printf '%s\n' "$INPUT" | jq -r '.tool_input.file_path // empty' 2>/dev/null || true)
|
|
61
|
+
else
|
|
62
|
+
FILE_PATH=$(printf '%s\n' "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*:[[:space:]]*"//;s/"$//' 2>/dev/null || true)
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
if [ -z "$FILE_PATH" ]; then
|
|
66
|
+
printf '%s\n' "$ALLOW"
|
|
67
|
+
exit 0
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
# Check if the file is a test file — always allow test file edits
|
|
71
|
+
# Patterns: *.test.*, *.spec.*, *_test.*, *_spec.*, *_test.go, spec/*, __tests__/*, test/*, tests/*
|
|
72
|
+
BASENAME=$(basename "$FILE_PATH")
|
|
73
|
+
if printf '%s' "$BASENAME" | grep -qE '\.(test|spec)\.[^.]+$'; then
|
|
74
|
+
printf '%s\n' "$ALLOW"
|
|
75
|
+
exit 0
|
|
76
|
+
fi
|
|
77
|
+
if printf '%s' "$BASENAME" | grep -qE '_(test|spec)\.[^.]+$'; then
|
|
78
|
+
printf '%s\n' "$ALLOW"
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
if printf '%s' "$FILE_PATH" | grep -qE '(^|/)(spec|__tests__|tests?)/'; then
|
|
82
|
+
printf '%s\n' "$ALLOW"
|
|
83
|
+
exit 0
|
|
84
|
+
fi
|
|
85
|
+
|
|
86
|
+
# Non-code files (markdown, json, yaml, config) — always allow
|
|
87
|
+
if printf '%s' "$BASENAME" | grep -qE '\.(md|json|ya?ml|toml|txt|csv|lock|gitignore)$'; then
|
|
88
|
+
printf '%s\n' "$ALLOW"
|
|
89
|
+
exit 0
|
|
90
|
+
fi
|
|
91
|
+
|
|
92
|
+
# At this point: implement phase + tdd is strict or guide + file is not a test file + file is code
|
|
93
|
+
# Sanitize BASENAME for JSON safety (remove double quotes and backslashes)
|
|
94
|
+
SAFE_BASENAME=$(printf '%s' "$BASENAME" | tr -d '"\\')
|
|
95
|
+
|
|
96
|
+
if [ "$TDD_MODE" = "strict" ]; then
|
|
97
|
+
printf '{"hookSpecificOutput":{"permissionDecision":"deny","permissionDecisionReason":"[afc:tdd-guard] TDD strict mode: write test file first before implementing. Target: %s"}}\n' "$SAFE_BASENAME"
|
|
98
|
+
exit 0
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
if [ "$TDD_MODE" = "guide" ]; then
|
|
102
|
+
printf '{"hookSpecificOutput":{"permissionDecision":"allow","additionalContext":"[afc:tdd-guard] TDD guide: consider writing tests first for %s"}}\n' "$SAFE_BASENAME"
|
|
103
|
+
exit 0
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Fallback: unknown tdd value -> allow
|
|
107
|
+
printf '%s\n' "$ALLOW"
|
|
108
|
+
exit 0
|
|
@@ -41,13 +41,17 @@ if ! afc_state_is_active; then
|
|
|
41
41
|
# Normalize: lowercase + truncate for matching
|
|
42
42
|
LOWER=$(printf '%s' "$USER_TEXT" | tr '[:upper:]' '[:lower:]' | cut -c1-500)
|
|
43
43
|
|
|
44
|
+
# Compact skill catalog: injected when regex misses, so the model classifies semantically
|
|
45
|
+
FALLBACK_HINT="[afc] Route via Skill tool if applicable — debug(bug/에러/수정/fix) | review(코드검토/리뷰/PR) | test(테스트/coverage) | spec(요구사항/스펙) | plan(설계/계획) | implement(구현/리팩터) | auto(새기능/feature) | consult(조언/상의/discuss) | analyze(분석/trace) | research(조사/리서치) | security(보안/취약점) | architect(아키텍처/설계) | qa(품질감사) | launch(릴리스/배포) | triage(PR정리/이슈분류) | clean(정리/cleanup) | ideate(아이디어/brainstorm) | doctor(진단/health) | release-notes(변경이력)"
|
|
46
|
+
|
|
44
47
|
# Early exit for empty prompts (context-only messages, malformed JSON)
|
|
45
48
|
if [ -z "$LOWER" ]; then
|
|
46
49
|
if command -v jq >/dev/null 2>&1; then
|
|
47
|
-
jq -n --arg c "
|
|
48
|
-
'{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
50
|
+
jq -n --arg c "$FALLBACK_HINT" '{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
49
51
|
else
|
|
50
|
-
|
|
52
|
+
SAFE_FALLBACK="${FALLBACK_HINT//\\/\\\\}"
|
|
53
|
+
SAFE_FALLBACK="${SAFE_FALLBACK//\"/\\\"}"
|
|
54
|
+
printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$SAFE_FALLBACK"
|
|
51
55
|
fi
|
|
52
56
|
exit 0
|
|
53
57
|
fi
|
|
@@ -55,43 +59,55 @@ if ! afc_state_is_active; then
|
|
|
55
59
|
# Intent detection: priority-ordered if/elif chain.
|
|
56
60
|
# Each pattern targets strong-signal phrases to minimize false positives.
|
|
57
61
|
# The model retains final authority — this is a hint, not enforcement.
|
|
62
|
+
# Patterns include Korean (한국어) variants for natural language coverage.
|
|
58
63
|
SKILL=""
|
|
59
64
|
# High confidence: distinctive multi-word or rare keywords
|
|
60
|
-
if printf '%s' "$LOWER" | grep -qE '(bug|broken|debug|not working|crash|exception)' 2>/dev/null; then
|
|
65
|
+
if printf '%s' "$LOWER" | grep -qE '(bug|broken|debug|not working|crash|exception|에러|버그|오류|안.?됨|안.?돼|안.?되|고장)' 2>/dev/null; then
|
|
61
66
|
SKILL="afc:debug"
|
|
62
|
-
elif printf '%s' "$LOWER" | grep -qE '(code review|pr review)' 2>/dev/null; then
|
|
67
|
+
elif printf '%s' "$LOWER" | grep -qE '(code review|pr review|코드.?리뷰|pr.?리뷰|코드.?검토)' 2>/dev/null; then
|
|
63
68
|
SKILL="afc:review"
|
|
64
|
-
elif printf '%s' "$LOWER" | grep -qE '(write test|add test|test coverage|improve coverage)' 2>/dev/null; then
|
|
69
|
+
elif printf '%s' "$LOWER" | grep -qE '(write test|add test|test coverage|improve coverage|unit test|integration test|e2e test|테스트.?작성|테스트.?추가|커버리지)' 2>/dev/null; then
|
|
65
70
|
SKILL="afc:test"
|
|
66
|
-
elif printf '%s' "$LOWER" | grep -qE '(security scan|security review|security audit|vulnerabilit)' 2>/dev/null; then
|
|
71
|
+
elif printf '%s' "$LOWER" | grep -qE '(security scan|security review|security audit|vulnerabilit|보안.?검사|보안.?스캔|보안.?리뷰|취약점)' 2>/dev/null; then
|
|
67
72
|
SKILL="afc:security"
|
|
68
|
-
elif printf '%s' "$LOWER" | grep -qE '(architecture|architect|system design)' 2>/dev/null; then
|
|
73
|
+
elif printf '%s' "$LOWER" | grep -qE '(architecture|architect|system design|아키텍처|시스템.?설계|구조.?설계)' 2>/dev/null; then
|
|
69
74
|
SKILL="afc:architect"
|
|
70
|
-
elif printf '%s' "$LOWER" | grep -qE '(doctor|health check|diagnose.*project)' 2>/dev/null; then
|
|
75
|
+
elif printf '%s' "$LOWER" | grep -qE '(doctor|health check|diagnose.*project|진단|상태.?확인|헬스.?체크)' 2>/dev/null; then
|
|
71
76
|
SKILL="afc:doctor"
|
|
72
|
-
elif printf '%s' "$LOWER" | grep -qE '(quality audit|qa audit|project quality)' 2>/dev/null; then
|
|
77
|
+
elif printf '%s' "$LOWER" | grep -qE '(quality audit|qa audit|project quality|품질.?감사|품질.?점검|qa.?점검)' 2>/dev/null; then
|
|
73
78
|
SKILL="afc:qa"
|
|
74
|
-
|
|
79
|
+
# NOTE: release-notes MUST come before launch — 릴리스.?노트 vs 릴리스 순서 의존
|
|
80
|
+
elif printf '%s' "$LOWER" | grep -qE '(release note|릴리스.?노트|변경.?이력|release.?note)' 2>/dev/null; then
|
|
81
|
+
SKILL="afc:release-notes"
|
|
82
|
+
elif printf '%s' "$LOWER" | grep -qE '(new release|version bump|changelog|publish.*package|릴리스|버전.?업|배포.?준비)' 2>/dev/null; then
|
|
75
83
|
SKILL="afc:launch"
|
|
84
|
+
elif printf '%s' "$LOWER" | grep -qE '(triage|pr.?정리|이슈.?정리|백로그.?정리|pr.?분류|이슈.?분류)' 2>/dev/null; then
|
|
85
|
+
SKILL="afc:triage"
|
|
76
86
|
# Medium confidence: still distinctive but broader
|
|
77
|
-
elif printf '%s' "$LOWER" | grep -qE '(specification|requirements|acceptance criteria)' 2>/dev/null; then
|
|
87
|
+
elif printf '%s' "$LOWER" | grep -qE '(specification|requirements|acceptance criteria|요구.?사항|기능.?정의|인수.?조건)' 2>/dev/null; then
|
|
78
88
|
SKILL="afc:spec"
|
|
79
|
-
elif printf '%s' "$LOWER" | grep -qE '(brainstorm|ideate|what to build|product brief)' 2>/dev/null; then
|
|
89
|
+
elif printf '%s' "$LOWER" | grep -qE '(brainstorm|ideate|what to build|product brief|아이디어|브레인스토밍|뭘.*만들)' 2>/dev/null; then
|
|
80
90
|
SKILL="afc:ideate"
|
|
81
|
-
elif printf '%s' "$LOWER" | grep -qE '(expert advice)' 2>/dev/null; then
|
|
91
|
+
elif printf '%s' "$LOWER" | grep -qE '(expert advice|discuss|advice|think together|같이.*생각|함께.*생각|상의|조언|의견.*구|자문|상담)' 2>/dev/null; then
|
|
82
92
|
SKILL="afc:consult"
|
|
83
|
-
elif printf '%s' "$LOWER" | grep -qE '(analyz|trace.*flow|how does.*work)' 2>/dev/null; then
|
|
93
|
+
elif printf '%s' "$LOWER" | grep -qE '(analyz|trace.*flow|how does.*work|분석|추적|어떻게.*동작|흐름.*파악)' 2>/dev/null; then
|
|
84
94
|
SKILL="afc:analyze"
|
|
85
|
-
elif printf '%s' "$LOWER" | grep -qE '(research|investigat|compare.*lib)' 2>/dev/null; then
|
|
95
|
+
elif printf '%s' "$LOWER" | grep -qE '(research|investigat|compare.*lib|조사|리서치|비교.*라이브러리|탐색)' 2>/dev/null; then
|
|
86
96
|
SKILL="afc:research"
|
|
87
|
-
|
|
88
|
-
|
|
97
|
+
elif printf '%s' "$LOWER" | grep -qE '(clean.*up|cleanup|아티팩트.?정리|파이프라인.?정리|산출물.?정리)' 2>/dev/null; then
|
|
98
|
+
SKILL="afc:clean"
|
|
99
|
+
# Lower confidence: common verbs — auto for non-trivial feature scopes
|
|
100
|
+
elif printf '%s' "$LOWER" | grep -qE '(새.*기능|신규.*기능|기능.*개발|기능.*만들|feature.*develop|build.*feature|develop.*feature|create.*feature)' 2>/dev/null; then
|
|
101
|
+
SKILL="afc:auto"
|
|
102
|
+
elif printf '%s' "$LOWER" | grep -qE '(implement|add feature|refactor|modify.*code|리팩터|리팩토링|코드.?수정)' 2>/dev/null; then
|
|
89
103
|
SKILL="afc:implement"
|
|
90
|
-
elif printf '%s' "$LOWER" | grep -qE '(
|
|
104
|
+
elif printf '%s' "$LOWER" | grep -qE '(fix|error|issue|problem|failing|수정|고쳐|문제)' 2>/dev/null; then
|
|
105
|
+
SKILL="afc:debug"
|
|
106
|
+
elif printf '%s' "$LOWER" | grep -qE '(review|검토|리뷰)' 2>/dev/null; then
|
|
91
107
|
SKILL="afc:review"
|
|
92
|
-
elif printf '%s' "$LOWER" | grep -qE '(spec[^a-z]|spec
|
|
108
|
+
elif printf '%s' "$LOWER" | grep -qE '(spec[^a-z]|spec$|스펙)' 2>/dev/null; then
|
|
93
109
|
SKILL="afc:spec"
|
|
94
|
-
elif printf '%s' "$LOWER" | grep -qE '(plan[^a-z]|plan
|
|
110
|
+
elif printf '%s' "$LOWER" | grep -qE '(plan[^a-z]|plan$|계획|설계)' 2>/dev/null; then
|
|
95
111
|
SKILL="afc:plan"
|
|
96
112
|
fi
|
|
97
113
|
|
|
@@ -99,13 +115,15 @@ if ! afc_state_is_active; then
|
|
|
99
115
|
if [ -n "$SKILL" ]; then
|
|
100
116
|
HINT="[afc:route -> ${SKILL}] Detected intent from user prompt. Invoke /${SKILL} via Skill tool."
|
|
101
117
|
else
|
|
102
|
-
HINT="
|
|
118
|
+
HINT="$FALLBACK_HINT"
|
|
103
119
|
fi
|
|
104
120
|
|
|
105
121
|
if command -v jq >/dev/null 2>&1; then
|
|
106
122
|
jq -n --arg c "$HINT" '{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
107
123
|
else
|
|
108
|
-
|
|
124
|
+
SAFE_HINT="${HINT//\\/\\\\}"
|
|
125
|
+
SAFE_HINT="${SAFE_HINT//\"/\\\"}"
|
|
126
|
+
printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$SAFE_HINT"
|
|
109
127
|
fi
|
|
110
128
|
exit 0
|
|
111
129
|
fi
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
<!-- afc:auto-generated — do not edit manually; regenerate with /afc:init -->
|
|
2
|
+
# Project Rules
|
|
3
|
+
|
|
4
|
+
> Auto-generated by /afc:init. Claude Code loads this file automatically for all conversations.
|
|
5
|
+
> For CI/gate/test commands, see .claude/afc.config.md.
|
|
6
|
+
|
|
7
|
+
## Architecture
|
|
8
|
+
|
|
9
|
+
- **Pattern**: (e.g., FSD, Clean Architecture, Layered, Modular, Flat)
|
|
10
|
+
- **Key layers**: (e.g., app, pages, widgets, features, entities, shared)
|
|
11
|
+
- **Import rule**: (e.g., upper layers may import lower only, no cross-feature imports)
|
|
12
|
+
- **Path alias**: (e.g., @/ → src/)
|
|
13
|
+
|
|
14
|
+
## Code Style
|
|
15
|
+
|
|
16
|
+
- **Language**: (e.g., TypeScript strict, JavaScript ESM, Python 3.12)
|
|
17
|
+
- **Naming**: (e.g., PascalCase components, camelCase functions, UPPER_SNAKE constants)
|
|
18
|
+
- **Lint**: (e.g., ESLint flat config + Prettier, Biome)
|
|
19
|
+
- **Key rules**: (e.g., import type separated, no any, prefer const)
|
|
20
|
+
|
|
21
|
+
## Project Context
|
|
22
|
+
|
|
23
|
+
- **Framework**: (e.g., Next.js 14 App Router, FastAPI, Express)
|
|
24
|
+
- **State**: (e.g., Zustand + TanStack Query, Redux Toolkit, Pinia)
|
|
25
|
+
- **Styling**: (e.g., Tailwind CSS, styled-components, CSS Modules)
|
|
26
|
+
- **Testing**: (e.g., Vitest + Playwright, Jest + Cypress)
|
|
27
|
+
- **DB/ORM**: (e.g., PostgreSQL + Prisma, MongoDB + Mongoose)
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# Project Configuration
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
>
|
|
3
|
+
> CI Commands are parsed by hook scripts — keep the YAML format intact.
|
|
4
|
+
> Architecture, Code Style, and Project Context sections below are detailed references.
|
|
5
|
+
> A concise summary is also generated in `.claude/rules/afc-project.md` (auto-loaded by Claude Code).
|
|
6
6
|
|
|
7
7
|
## CI Commands
|
|
8
8
|
|
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
ci: "npm run ci"
|
|
12
12
|
gate: "npm run typecheck && npm run lint"
|
|
13
13
|
test: "npm test"
|
|
14
|
+
tdd: "off" # TDD mode: "strict" (block impl without tests), "guide" (warn only), "off" (disabled)
|
|
14
15
|
```
|
|
15
16
|
|
|
16
17
|
## Architecture
|