all-for-claudecode 2.1.0 → 2.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/.claude-plugin/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +1 -1
- package/README.md +62 -111
- package/commands/analyze.md +5 -6
- package/commands/architect.md +5 -7
- package/commands/auto.md +14 -12
- package/commands/checkpoint.md +0 -1
- package/commands/debug.md +1 -1
- package/commands/doctor.md +1 -2
- package/commands/ideate.md +191 -0
- package/commands/implement.md +4 -4
- package/commands/init.md +56 -46
- package/commands/launch.md +181 -0
- package/commands/plan.md +1 -7
- package/commands/principles.md +0 -1
- package/commands/resume.md +0 -1
- package/commands/review.md +2 -2
- package/commands/security.md +10 -13
- package/commands/test.md +4 -4
- package/docs/phase-gate-protocol.md +1 -1
- package/package.json +15 -9
- package/scripts/afc-consistency-check.sh +261 -0
- package/scripts/afc-permission-request.sh +11 -1
- package/scripts/afc-pipeline-manage.sh +8 -11
- package/scripts/afc-state.sh +20 -0
- package/scripts/afc-stop-gate.sh +4 -6
- package/scripts/afc-subagent-context.sh +7 -0
- package/scripts/afc-task-completed-gate.sh +4 -6
- package/templates/afc.config.template.md +12 -76
- package/templates/afc.config.express-api.md +0 -99
- package/templates/afc.config.monorepo.md +0 -98
- package/templates/afc.config.nextjs-fsd.md +0 -107
- package/templates/afc.config.react-spa.md +0 -96
|
@@ -0,0 +1,261 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# afc-consistency-check.sh — Cross-reference validation for project consistency
|
|
5
|
+
# Checks: config placeholders, agent names, hook scripts, test coverage
|
|
6
|
+
# Run as part of: npm run lint
|
|
7
|
+
|
|
8
|
+
# shellcheck disable=SC2329
|
|
9
|
+
cleanup() {
|
|
10
|
+
:
|
|
11
|
+
}
|
|
12
|
+
trap cleanup EXIT
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
|
15
|
+
PROJECT_DIR="${1:-$(cd "$SCRIPT_DIR/.." && pwd)}"
|
|
16
|
+
ERRORS=0
|
|
17
|
+
WARNINGS=0
|
|
18
|
+
|
|
19
|
+
# --- Helpers ---
|
|
20
|
+
|
|
21
|
+
fail() {
|
|
22
|
+
printf "[afc:consistency] FAIL: %s\n" "$1" >&2
|
|
23
|
+
ERRORS=$((ERRORS + 1))
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
warn() {
|
|
27
|
+
printf "[afc:consistency] WARN: %s\n" "$1" >&2
|
|
28
|
+
WARNINGS=$((WARNINGS + 1))
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
ok() {
|
|
32
|
+
printf "[afc:consistency] ✓ %s\n" "$1"
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
# --- Check 1: Config Placeholder Validation ---
|
|
36
|
+
# Verify all {config.*} references in commands/ and docs/ map to known config keys
|
|
37
|
+
|
|
38
|
+
check_config_placeholders() {
|
|
39
|
+
local template="$PROJECT_DIR/templates/afc.config.template.md"
|
|
40
|
+
if [ ! -f "$template" ]; then
|
|
41
|
+
warn "Config template not found: $template"
|
|
42
|
+
return
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Extract valid config keys from template
|
|
46
|
+
# YAML keys: ci, gate, test
|
|
47
|
+
local yaml_keys
|
|
48
|
+
yaml_keys=$(grep -oE '^\s*[a-z_]+:' "$template" 2>/dev/null | sed 's/[[:space:]]*//;s/://' | sort -u || true)
|
|
49
|
+
# Section headers → lowercase with underscores: Architecture → architecture, Code Style → code_style, Project Context → project_context
|
|
50
|
+
local section_keys
|
|
51
|
+
section_keys=$(grep -oE '^## [A-Za-z ]+' "$template" 2>/dev/null \
|
|
52
|
+
| sed 's/^## //' \
|
|
53
|
+
| tr '[:upper:]' '[:lower:]' \
|
|
54
|
+
| sed 's/ /_/g' \
|
|
55
|
+
| sort -u || true)
|
|
56
|
+
|
|
57
|
+
local valid_keys
|
|
58
|
+
valid_keys=$(printf '%s\n%s\n' "$yaml_keys" "$section_keys" | sort -u)
|
|
59
|
+
|
|
60
|
+
# Extract all {config.*} references from commands and docs
|
|
61
|
+
local refs
|
|
62
|
+
refs=$(grep -rohE '\{config\.[a-z_]+\}' "$PROJECT_DIR/commands/" "$PROJECT_DIR/docs/" 2>/dev/null \
|
|
63
|
+
| sed 's/{config\.//;s/}//' \
|
|
64
|
+
| sort -u || true)
|
|
65
|
+
|
|
66
|
+
local count=0
|
|
67
|
+
local invalid=0
|
|
68
|
+
for ref in $refs; do
|
|
69
|
+
count=$((count + 1))
|
|
70
|
+
if ! printf '%s\n' "$valid_keys" | grep -qxF "$ref"; then
|
|
71
|
+
fail "{config.$ref} referenced but not defined in config template"
|
|
72
|
+
invalid=$((invalid + 1))
|
|
73
|
+
fi
|
|
74
|
+
done
|
|
75
|
+
|
|
76
|
+
if [ "$invalid" -eq 0 ]; then
|
|
77
|
+
ok "Config placeholders: $count references, all valid"
|
|
78
|
+
fi
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
# --- Check 2: Agent Name Consistency ---
|
|
82
|
+
# Verify subagent_type references in commands match agent definitions
|
|
83
|
+
|
|
84
|
+
check_agent_names() {
|
|
85
|
+
local agents_dir="$PROJECT_DIR/agents"
|
|
86
|
+
if [ ! -d "$agents_dir" ]; then
|
|
87
|
+
warn "Agents directory not found"
|
|
88
|
+
return
|
|
89
|
+
fi
|
|
90
|
+
|
|
91
|
+
# Extract agent names from agent files (name: field in frontmatter)
|
|
92
|
+
local defined_agents
|
|
93
|
+
defined_agents=$(grep -h '^name:' "$agents_dir"/*.md 2>/dev/null \
|
|
94
|
+
| sed 's/^name:[[:space:]]*//' \
|
|
95
|
+
| tr -d '"' \
|
|
96
|
+
| sort -u || true)
|
|
97
|
+
|
|
98
|
+
# Extract subagent_type references from commands (afc:agent-name pattern)
|
|
99
|
+
local referenced_agents
|
|
100
|
+
referenced_agents=$(grep -rohE 'subagent_type:[[:space:]]*"afc:[^"]*"' "$PROJECT_DIR/commands/" 2>/dev/null \
|
|
101
|
+
| sed 's/.*"afc://;s/"//' \
|
|
102
|
+
| sort -u || true)
|
|
103
|
+
|
|
104
|
+
local count=0
|
|
105
|
+
local invalid=0
|
|
106
|
+
for ref in $referenced_agents; do
|
|
107
|
+
count=$((count + 1))
|
|
108
|
+
if ! printf '%s\n' "$defined_agents" | grep -qxF "$ref"; then
|
|
109
|
+
fail "subagent_type 'afc:$ref' referenced but no agents/$ref.md found"
|
|
110
|
+
invalid=$((invalid + 1))
|
|
111
|
+
fi
|
|
112
|
+
done
|
|
113
|
+
|
|
114
|
+
# Check for unprefixed subagent_type that should have afc: prefix
|
|
115
|
+
local unprefixed
|
|
116
|
+
unprefixed=$(grep -rohE 'subagent_type:[[:space:]]*"afc-[^"]*"' "$PROJECT_DIR/commands/" 2>/dev/null \
|
|
117
|
+
| sed 's/.*subagent_type:[[:space:]]*"//;s/".*//' \
|
|
118
|
+
| sort -u || true)
|
|
119
|
+
for ref in $unprefixed; do
|
|
120
|
+
if printf '%s\n' "$defined_agents" | grep -qxF "$ref"; then
|
|
121
|
+
fail "subagent_type '$ref' should use 'afc:$ref' prefix (found in agents/)"
|
|
122
|
+
invalid=$((invalid + 1))
|
|
123
|
+
fi
|
|
124
|
+
done
|
|
125
|
+
|
|
126
|
+
if [ "$invalid" -eq 0 ]; then
|
|
127
|
+
ok "Agent names: $count references, all consistent"
|
|
128
|
+
fi
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
# --- Check 3: Hook Script Existence ---
|
|
132
|
+
# Verify all scripts referenced in hooks.json actually exist
|
|
133
|
+
|
|
134
|
+
check_hook_scripts() {
|
|
135
|
+
local hooks_file="$PROJECT_DIR/hooks/hooks.json"
|
|
136
|
+
if [ ! -f "$hooks_file" ]; then
|
|
137
|
+
warn "hooks.json not found"
|
|
138
|
+
return
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
local scripts
|
|
142
|
+
scripts=$(grep -oE 'scripts/[^"]+\.sh' "$hooks_file" 2>/dev/null | sort -u || true)
|
|
143
|
+
|
|
144
|
+
local count=0
|
|
145
|
+
local missing=0
|
|
146
|
+
for script in $scripts; do
|
|
147
|
+
count=$((count + 1))
|
|
148
|
+
if [ ! -f "$PROJECT_DIR/$script" ]; then
|
|
149
|
+
fail "hooks.json references '$script' but file not found"
|
|
150
|
+
missing=$((missing + 1))
|
|
151
|
+
fi
|
|
152
|
+
done
|
|
153
|
+
|
|
154
|
+
if [ "$missing" -eq 0 ]; then
|
|
155
|
+
ok "Hook scripts: $count references, all exist"
|
|
156
|
+
fi
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
# --- Check 4: Test Coverage ---
|
|
160
|
+
# Verify each afc-*.sh script (except afc-state.sh library) has a spec file
|
|
161
|
+
|
|
162
|
+
check_test_coverage() {
|
|
163
|
+
local count=0
|
|
164
|
+
local missing=0
|
|
165
|
+
for script in "$PROJECT_DIR"/scripts/afc-*.sh; do
|
|
166
|
+
local scriptname
|
|
167
|
+
scriptname=$(basename "$script" .sh)
|
|
168
|
+
# Skip shared library and self (validation script)
|
|
169
|
+
if [ "$scriptname" = "afc-state" ] || [ "$scriptname" = "afc-consistency-check" ]; then
|
|
170
|
+
continue
|
|
171
|
+
fi
|
|
172
|
+
count=$((count + 1))
|
|
173
|
+
if [ ! -f "$PROJECT_DIR/spec/${scriptname}_spec.sh" ]; then
|
|
174
|
+
fail "scripts/$scriptname.sh has no spec/${scriptname}_spec.sh"
|
|
175
|
+
missing=$((missing + 1))
|
|
176
|
+
fi
|
|
177
|
+
done
|
|
178
|
+
|
|
179
|
+
if [ "$missing" -eq 0 ]; then
|
|
180
|
+
ok "Test coverage: $count scripts, all have specs"
|
|
181
|
+
fi
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
# --- Check 5: Version Sync ---
|
|
185
|
+
# Verify version numbers match across package.json, plugin.json, marketplace.json
|
|
186
|
+
|
|
187
|
+
check_version_sync() {
|
|
188
|
+
local pkg="$PROJECT_DIR/package.json"
|
|
189
|
+
local plugin="$PROJECT_DIR/.claude-plugin/plugin.json"
|
|
190
|
+
local market="$PROJECT_DIR/.claude-plugin/marketplace.json"
|
|
191
|
+
|
|
192
|
+
if [ ! -f "$pkg" ] || [ ! -f "$plugin" ] || [ ! -f "$market" ]; then
|
|
193
|
+
warn "One or more version files missing"
|
|
194
|
+
return
|
|
195
|
+
fi
|
|
196
|
+
|
|
197
|
+
local pkg_ver plugin_ver market_meta market_plugin
|
|
198
|
+
if command -v jq >/dev/null 2>&1; then
|
|
199
|
+
pkg_ver=$(jq -r '.version' "$pkg")
|
|
200
|
+
plugin_ver=$(jq -r '.version' "$plugin")
|
|
201
|
+
market_meta=$(jq -r '.metadata.version' "$market")
|
|
202
|
+
market_plugin=$(jq -r '.plugins[0].version' "$market")
|
|
203
|
+
else
|
|
204
|
+
pkg_ver=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$pkg" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
|
|
205
|
+
plugin_ver=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$plugin" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
|
|
206
|
+
market_meta=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$market" | head -1 | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
|
|
207
|
+
market_plugin=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$market" | sed -n '2p' | sed 's/.*"version"[[:space:]]*:[[:space:]]*"//;s/"//')
|
|
208
|
+
fi
|
|
209
|
+
|
|
210
|
+
if [ "$pkg_ver" = "$plugin_ver" ] && [ "$plugin_ver" = "$market_meta" ] && [ "$market_meta" = "$market_plugin" ]; then
|
|
211
|
+
ok "Version sync: $pkg_ver (all 4 match)"
|
|
212
|
+
else
|
|
213
|
+
fail "Version mismatch: package.json=$pkg_ver plugin.json=$plugin_ver marketplace.meta=$market_meta marketplace.plugin=$market_plugin"
|
|
214
|
+
fi
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
# --- Check 6: SSOT Phase Constants ---
|
|
218
|
+
# Verify SSOT phase list in afc-state.sh is not duplicated in other scripts
|
|
219
|
+
|
|
220
|
+
check_phase_ssot() {
|
|
221
|
+
# shellcheck source=afc-state.sh
|
|
222
|
+
. "$SCRIPT_DIR/afc-state.sh"
|
|
223
|
+
|
|
224
|
+
local dupes=0
|
|
225
|
+
# Look for hardcoded phase lists (pipe-separated patterns with 3+ known phases)
|
|
226
|
+
for script in "$PROJECT_DIR"/scripts/afc-*.sh; do
|
|
227
|
+
local scriptname
|
|
228
|
+
scriptname=$(basename "$script")
|
|
229
|
+
# Skip the SSOT source itself and this validation script
|
|
230
|
+
if [ "$scriptname" = "afc-state.sh" ] || [ "$scriptname" = "afc-consistency-check.sh" ]; then
|
|
231
|
+
continue
|
|
232
|
+
fi
|
|
233
|
+
# Check for hardcoded phase case patterns (spec|plan|...|clean style)
|
|
234
|
+
if grep -qE 'spec\|plan\|.*\|clean' "$script" 2>/dev/null; then
|
|
235
|
+
fail "$scriptname contains hardcoded phase list — use SSOT helpers from afc-state.sh"
|
|
236
|
+
dupes=$((dupes + 1))
|
|
237
|
+
fi
|
|
238
|
+
done
|
|
239
|
+
|
|
240
|
+
if [ "$dupes" -eq 0 ]; then
|
|
241
|
+
ok "Phase SSOT: no hardcoded phase lists found in scripts"
|
|
242
|
+
fi
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
# --- Run All Checks ---
|
|
246
|
+
|
|
247
|
+
printf "[afc:consistency] Running cross-reference validation...\n"
|
|
248
|
+
|
|
249
|
+
check_config_placeholders
|
|
250
|
+
check_agent_names
|
|
251
|
+
check_hook_scripts
|
|
252
|
+
check_test_coverage
|
|
253
|
+
check_version_sync
|
|
254
|
+
check_phase_ssot
|
|
255
|
+
|
|
256
|
+
printf "\n[afc:consistency] Done: %d errors, %d warnings\n" "$ERRORS" "$WARNINGS"
|
|
257
|
+
|
|
258
|
+
if [ "$ERRORS" -gt 0 ]; then
|
|
259
|
+
exit 1
|
|
260
|
+
fi
|
|
261
|
+
exit 0
|
|
@@ -59,7 +59,7 @@ if [ -f "$CONFIG_FILE" ]; then
|
|
|
59
59
|
# Extract ci, gate, test values from YAML code block
|
|
60
60
|
# Handles both quoted and unquoted: ci: "npm run lint" or ci: npm run lint
|
|
61
61
|
for key in ci gate test; do
|
|
62
|
-
val=$(grep -E "
|
|
62
|
+
val=$(grep -E "^\s*${key}:\s*\"[^\"]*\"" "$CONFIG_FILE" 2>/dev/null | head -1 | sed 's/.*'"${key}"': *"\([^"]*\)".*/\1/' || true)
|
|
63
63
|
if [ -n "$val" ] && [ "$val" != '""' ]; then
|
|
64
64
|
DYNAMIC_WHITELIST="${DYNAMIC_WHITELIST:+${DYNAMIC_WHITELIST}|}${val}"
|
|
65
65
|
# Generate PM-agnostic variants (npm → pnpm, yarn, bun)
|
|
@@ -97,6 +97,16 @@ if [ "$ALLOWED" = "false" ]; then
|
|
|
97
97
|
esac
|
|
98
98
|
fi
|
|
99
99
|
|
|
100
|
+
# Plugin's own scripts (auto-allow during pipeline execution)
|
|
101
|
+
PLUGIN_ROOT="${CLAUDE_PLUGIN_ROOT:-}"
|
|
102
|
+
if [ "$ALLOWED" = "false" ] && [ -n "$PLUGIN_ROOT" ]; then
|
|
103
|
+
case "$COMMAND" in
|
|
104
|
+
"\"${PLUGIN_ROOT}/scripts/"*|"${PLUGIN_ROOT}/scripts/"*)
|
|
105
|
+
ALLOWED=true
|
|
106
|
+
;;
|
|
107
|
+
esac
|
|
108
|
+
fi
|
|
109
|
+
|
|
100
110
|
# Prefix matching (allow paths after shellcheck, prettier, chmod +x)
|
|
101
111
|
if [ "$ALLOWED" = "false" ]; then
|
|
102
112
|
case "$COMMAND" in
|
|
@@ -73,17 +73,14 @@ case "$COMMAND" in
|
|
|
73
73
|
|
|
74
74
|
phase)
|
|
75
75
|
PHASE="${2:?Phase name required}"
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
exit 1
|
|
85
|
-
;;
|
|
86
|
-
esac
|
|
76
|
+
if afc_is_valid_phase "$PHASE"; then
|
|
77
|
+
afc_state_write "phase" "$PHASE"
|
|
78
|
+
afc_state_invalidate_ci
|
|
79
|
+
echo "Phase: $PHASE"
|
|
80
|
+
else
|
|
81
|
+
printf "[afc:pipeline] Invalid phase: %s\n → Valid phases: %s\n" "$PHASE" "$AFC_VALID_PHASES" >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
87
84
|
;;
|
|
88
85
|
|
|
89
86
|
ci-pass)
|
package/scripts/afc-state.sh
CHANGED
|
@@ -8,6 +8,26 @@
|
|
|
8
8
|
_AFC_STATE_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}/.claude"
|
|
9
9
|
_AFC_STATE_FILE="${_AFC_STATE_DIR}/.afc-state.json"
|
|
10
10
|
|
|
11
|
+
# --- Phase Constants (SSOT) ---
|
|
12
|
+
# All valid pipeline phases. Update HERE when adding a new phase.
|
|
13
|
+
AFC_VALID_PHASES="spec|plan|tasks|implement|review|clean|clarify|test-pre-gen|blast-radius|fast-path"
|
|
14
|
+
# Phases that do NOT require CI gate to pass (preparatory phases)
|
|
15
|
+
AFC_CI_EXEMPT_PHASES="spec|plan|tasks|clarify|test-pre-gen|blast-radius"
|
|
16
|
+
|
|
17
|
+
# Check if a phase name is valid
|
|
18
|
+
# Usage: afc_is_valid_phase <phase>
|
|
19
|
+
# Returns: 0 if valid, 1 if not
|
|
20
|
+
afc_is_valid_phase() {
|
|
21
|
+
printf '%s\n' "$AFC_VALID_PHASES" | tr '|' '\n' | grep -qxF "$1"
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
# Check if a phase is exempt from CI gate
|
|
25
|
+
# Usage: afc_is_ci_exempt <phase>
|
|
26
|
+
# Returns: 0 if exempt, 1 if CI required
|
|
27
|
+
afc_is_ci_exempt() {
|
|
28
|
+
printf '%s\n' "$AFC_CI_EXEMPT_PHASES" | tr '|' '\n' | grep -qxF "$1"
|
|
29
|
+
}
|
|
30
|
+
|
|
11
31
|
# --- Public API ---
|
|
12
32
|
|
|
13
33
|
# Check if pipeline is active (state file exists and has feature)
|
package/scripts/afc-stop-gate.sh
CHANGED
|
@@ -45,12 +45,10 @@ FEATURE="$(afc_state_read feature || echo '')"
|
|
|
45
45
|
# Check current Phase
|
|
46
46
|
CURRENT_PHASE="$(afc_state_read phase || echo '')"
|
|
47
47
|
|
|
48
|
-
#
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
;;
|
|
53
|
-
esac
|
|
48
|
+
# Preparatory phases do not require CI -> pass through
|
|
49
|
+
if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
54
52
|
|
|
55
53
|
# Implement/Review/Clean Phase (4-6) require CI to pass
|
|
56
54
|
CI_TIME="$(afc_state_read ciPassedAt 2>/dev/null || echo '')"
|
|
@@ -51,6 +51,13 @@ if [ -f "$CONFIG_FILE" ]; then
|
|
|
51
51
|
if [ -n "$STYLE" ]; then
|
|
52
52
|
CONTEXT="$CONTEXT | Code Style: $STYLE"
|
|
53
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
|
|
54
61
|
fi
|
|
55
62
|
|
|
56
63
|
# 5. Output as hookSpecificOutput JSON (required for SubagentStart context injection)
|
|
@@ -32,12 +32,10 @@ FEATURE="$(afc_state_read feature || echo '')"
|
|
|
32
32
|
# Check current Phase
|
|
33
33
|
CURRENT_PHASE="$(afc_state_read phase || echo '')"
|
|
34
34
|
|
|
35
|
-
#
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
;;
|
|
40
|
-
esac
|
|
35
|
+
# Preparatory phases do not require CI -> pass through
|
|
36
|
+
if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
|
|
37
|
+
exit 0
|
|
38
|
+
fi
|
|
41
39
|
|
|
42
40
|
# Implement/Review/Clean Phase (4-6) require CI to pass
|
|
43
41
|
CI_TIME="$(afc_state_read ciPassedAt 2>/dev/null || echo '')"
|
|
@@ -1,90 +1,26 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Project Configuration
|
|
2
2
|
|
|
3
|
-
>
|
|
4
|
-
>
|
|
5
|
-
>
|
|
3
|
+
> afc commands reference this file to determine project-specific behavior.
|
|
4
|
+
> CI Commands are parsed by scripts — keep the YAML format intact.
|
|
5
|
+
> All other sections are free-form markdown — write whatever best describes your project.
|
|
6
6
|
|
|
7
7
|
## CI Commands
|
|
8
8
|
|
|
9
|
+
<!-- DO NOT change the format below. Scripts parse these keys. -->
|
|
9
10
|
```yaml
|
|
10
|
-
ci: "npm run ci"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
lint_fix: "npm run lint:fix" # Auto-fix lint
|
|
14
|
-
gate: "npm run typecheck && npm run lint" # Phase gate (run repeatedly during implement)
|
|
15
|
-
test: "npm test" # Tests
|
|
11
|
+
ci: "npm run ci"
|
|
12
|
+
gate: "npm run typecheck && npm run lint"
|
|
13
|
+
test: "npm test"
|
|
16
14
|
```
|
|
17
15
|
|
|
18
16
|
## Architecture
|
|
19
17
|
|
|
20
|
-
|
|
21
|
-
style: "Layered" # e.g.: FSD, Clean Architecture, Modular Monolith, Layered
|
|
22
|
-
layers: [] # List from top to bottom layer
|
|
23
|
-
import_rule: "" # Import direction rule (e.g.: "upper → lower only")
|
|
24
|
-
segments: [] # Sub-segments for each layer
|
|
25
|
-
path_alias: "" # e.g.: "@/* → ./src/*"
|
|
26
|
-
```
|
|
27
|
-
|
|
28
|
-
## Framework
|
|
29
|
-
|
|
30
|
-
```yaml
|
|
31
|
-
name: "" # e.g.: Next.js 14, Vite, CRA
|
|
32
|
-
runtime: "" # e.g.: App Router, Pages Router
|
|
33
|
-
client_directive: "" # e.g.: 'use client' (leave empty if not applicable)
|
|
34
|
-
client_directive_rule: "" # Rule for applying client directives
|
|
35
|
-
server_client_boundary: false # Whether a server/client boundary exists
|
|
36
|
-
```
|
|
18
|
+
(init analyzes your project and writes this section in free-form)
|
|
37
19
|
|
|
38
20
|
## Code Style
|
|
39
21
|
|
|
40
|
-
|
|
41
|
-
language: "TypeScript"
|
|
42
|
-
strict_mode: true
|
|
43
|
-
type_keyword: "type" # type vs interface
|
|
44
|
-
import_type: true # Whether to use import type
|
|
45
|
-
component_style: "PascalCase"
|
|
46
|
-
props_position: "above component"
|
|
47
|
-
handler_naming: "handle[Event]"
|
|
48
|
-
boolean_naming: "is/has/can[State]"
|
|
49
|
-
constant_naming: "UPPER_SNAKE_CASE"
|
|
50
|
-
any_policy: "minimize"
|
|
51
|
-
```
|
|
52
|
-
|
|
53
|
-
## State Management
|
|
54
|
-
|
|
55
|
-
```yaml
|
|
56
|
-
global_state: "" # e.g.: Zustand, Redux, Pinia
|
|
57
|
-
server_state: "" # e.g.: React Query, SWR, Apollo
|
|
58
|
-
local_state: "" # e.g.: Context API, useState
|
|
59
|
-
store_location: "" # Store file location pattern
|
|
60
|
-
query_location: "" # Query file location pattern
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
## Styling
|
|
64
|
-
|
|
65
|
-
```yaml
|
|
66
|
-
framework: "" # e.g.: Tailwind CSS, styled-components, CSS Modules
|
|
67
|
-
```
|
|
68
|
-
|
|
69
|
-
## Testing
|
|
70
|
-
|
|
71
|
-
```yaml
|
|
72
|
-
framework: "" # e.g.: Jest, Vitest, Playwright
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Project-Specific Risks
|
|
76
|
-
|
|
77
|
-
> Project-specific risk patterns that must be checked in the Plan's RISK Critic
|
|
78
|
-
> Modify to match your project.
|
|
79
|
-
|
|
80
|
-
1. (example) Import order violation
|
|
81
|
-
2. (example) Circular reference
|
|
82
|
-
3. (example) Type safety bypass (as any)
|
|
83
|
-
|
|
84
|
-
## Mini-Review Checklist
|
|
22
|
+
(init analyzes your project and writes this section in free-form)
|
|
85
23
|
|
|
86
|
-
|
|
24
|
+
## Project Context
|
|
87
25
|
|
|
88
|
-
|
|
89
|
-
2. Code style pattern compliance
|
|
90
|
-
3. Dead code (unused imports, empty exports, dead code)
|
|
26
|
+
(init analyzes your project and writes this section in free-form — framework, state management, styling, testing, risks, etc.)
|
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# all-for-claudecode Configuration
|
|
2
|
-
|
|
3
|
-
> This file defines project-specific settings for the afc command system.
|
|
4
|
-
> All afc commands reference this file to determine project-specific behavior.
|
|
5
|
-
|
|
6
|
-
## CI Commands
|
|
7
|
-
|
|
8
|
-
```yaml
|
|
9
|
-
ci: "npm run build && npm run lint && npm run test" # Full CI (build + lint + test)
|
|
10
|
-
typecheck: "npx tsc --noEmit" # Typecheck only
|
|
11
|
-
lint: "npx eslint src/" # Lint only
|
|
12
|
-
lint_fix: "npx eslint src/ --fix" # Auto-fix lint
|
|
13
|
-
gate: "npx tsc --noEmit && npx eslint src/" # Phase gate (run repeatedly during implement)
|
|
14
|
-
test: "npx jest --runInBand" # Tests
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Architecture
|
|
18
|
-
|
|
19
|
-
```yaml
|
|
20
|
-
style: "Layered" # Layered architecture
|
|
21
|
-
layers: # Top → bottom order
|
|
22
|
-
- src/routes
|
|
23
|
-
- src/controllers
|
|
24
|
-
- src/services
|
|
25
|
-
- src/repositories
|
|
26
|
-
- src/models
|
|
27
|
-
- src/middleware
|
|
28
|
-
- src/lib
|
|
29
|
-
- src/types
|
|
30
|
-
- src/config
|
|
31
|
-
import_rule: "Upper layers (routes) depend only in order: controllers → services → repositories"
|
|
32
|
-
segments: []
|
|
33
|
-
path_alias: "@/* → ./src/*"
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Framework
|
|
37
|
-
|
|
38
|
-
```yaml
|
|
39
|
-
name: "Express.js"
|
|
40
|
-
runtime: "Node.js (CommonJS or ESM)"
|
|
41
|
-
client_directive: "" # Server-only — not applicable
|
|
42
|
-
server_client_boundary: false # Server-only application
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Code Style
|
|
46
|
-
|
|
47
|
-
```yaml
|
|
48
|
-
language: "TypeScript"
|
|
49
|
-
strict_mode: true
|
|
50
|
-
type_keyword: "type" # Use type instead of interface
|
|
51
|
-
import_type: true # Use import type { ... }
|
|
52
|
-
component_style: "" # No UI components
|
|
53
|
-
props_position: "" # No UI components
|
|
54
|
-
handler_naming: "camelCase"
|
|
55
|
-
boolean_naming: "is/has/can[State]"
|
|
56
|
-
constant_naming: "UPPER_SNAKE_CASE"
|
|
57
|
-
any_policy: "banned (use unknown with strict mode)"
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
## State Management
|
|
61
|
-
|
|
62
|
-
```yaml
|
|
63
|
-
global_state: "" # Server — stateless
|
|
64
|
-
server_state: ""
|
|
65
|
-
local_state: ""
|
|
66
|
-
store_location: ""
|
|
67
|
-
query_location: ""
|
|
68
|
-
```
|
|
69
|
-
|
|
70
|
-
## Styling
|
|
71
|
-
|
|
72
|
-
```yaml
|
|
73
|
-
framework: "" # Not applicable
|
|
74
|
-
```
|
|
75
|
-
|
|
76
|
-
## Testing
|
|
77
|
-
|
|
78
|
-
```yaml
|
|
79
|
-
framework: "Jest + Supertest"
|
|
80
|
-
```
|
|
81
|
-
|
|
82
|
-
## Project-Specific Risks
|
|
83
|
-
|
|
84
|
-
> Project-specific risk patterns that must be checked in the Plan's RISK Critic
|
|
85
|
-
|
|
86
|
-
1. Prisma migration and schema mismatch
|
|
87
|
-
2. Express middleware ordering errors (auth → validation → handler)
|
|
88
|
-
3. Missing async/await error handling (try-catch or wrapper)
|
|
89
|
-
4. Runtime errors when environment variables (.env) are not set
|
|
90
|
-
5. SQL injection (caution with raw queries when using Prisma)
|
|
91
|
-
|
|
92
|
-
## Mini-Review Checklist
|
|
93
|
-
|
|
94
|
-
> Items to inspect for each file in the Mini-Review of the Implement Phase gate
|
|
95
|
-
|
|
96
|
-
1. TypeScript strict mode violations
|
|
97
|
-
2. Error handling (try-catch or asyncHandler on async routes)
|
|
98
|
-
3. Input validation (type checking of req.body/params/query)
|
|
99
|
-
4. Unused imports / dead code
|