all-for-claudecode 2.5.0 → 2.7.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 +4 -2
- package/README.md +15 -3
- package/agents/afc-architect.md +1 -1
- package/agents/afc-security.md +1 -1
- package/commands/analyze.md +1 -1
- package/commands/architect.md +1 -1
- package/commands/auto.md +2 -2
- package/commands/checkpoint.md +1 -1
- package/commands/clarify.md +1 -1
- package/commands/clean.md +126 -0
- package/commands/consult.md +1 -1
- package/commands/debug.md +1 -1
- package/commands/doctor.md +64 -23
- package/commands/ideate.md +1 -1
- package/commands/implement.md +1 -1
- package/commands/init.md +10 -6
- package/commands/launch.md +1 -1
- package/commands/plan.md +1 -1
- package/commands/pr-comment.md +1 -1
- package/commands/principles.md +1 -1
- package/commands/qa.md +191 -0
- package/commands/release-notes.md +1 -1
- package/commands/research.md +1 -1
- package/commands/resume.md +2 -2
- package/commands/review.md +1 -1
- package/commands/security.md +1 -1
- package/commands/spec.md +1 -1
- package/commands/tasks.md +1 -1
- package/commands/test.md +1 -1
- package/commands/triage.md +1 -1
- package/commands/validate.md +1 -1
- package/docs/phase-gate-protocol.md +1 -1
- package/hooks/hooks.json +1 -0
- package/package.json +5 -3
- package/schemas/hooks.schema.json +4 -0
- package/schemas/plugin.schema.json +5 -1
- package/scripts/afc-bash-guard.sh +3 -3
- package/scripts/afc-config-change.sh +8 -0
- package/scripts/afc-consistency-check.sh +58 -19
- package/scripts/afc-dag-validate.sh +1 -1
- package/scripts/afc-doctor.sh +445 -0
- package/scripts/afc-failure-hint.sh +24 -2
- package/scripts/afc-qa-audit.sh +536 -0
- package/scripts/afc-state.sh +3 -3
- package/scripts/afc-sync-cache.sh +49 -0
- package/scripts/afc-triage.sh +14 -3
- package/scripts/afc-user-prompt-submit.sh +98 -13
- package/scripts/pre-compact-checkpoint.sh +2 -2
- package/scripts/session-start-context.sh +39 -10
- package/scripts/track-afc-changes.sh +3 -3
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
set -euo pipefail
|
|
3
3
|
|
|
4
4
|
# UserPromptSubmit Hook: Two modes of operation:
|
|
5
|
-
# 1. Pipeline INACTIVE:
|
|
5
|
+
# 1. Pipeline INACTIVE: Detect user intent from prompt and inject specific skill routing hint
|
|
6
6
|
# 2. Pipeline ACTIVE: Inject Phase/Feature context + drift checkpoint at thresholds
|
|
7
|
-
# Exit 0 immediately if no action needed (minimize overhead)
|
|
8
7
|
|
|
9
8
|
# shellcheck source=afc-state.sh
|
|
10
9
|
. "$(dirname "$0")/afc-state.sh"
|
|
@@ -15,30 +14,116 @@ cleanup() {
|
|
|
15
14
|
}
|
|
16
15
|
trap cleanup EXIT
|
|
17
16
|
|
|
18
|
-
#
|
|
19
|
-
cat
|
|
17
|
+
# Read stdin (contains user prompt JSON)
|
|
18
|
+
INPUT=$(cat)
|
|
20
19
|
|
|
21
|
-
# --- Branch: Pipeline INACTIVE
|
|
22
|
-
#
|
|
23
|
-
#
|
|
20
|
+
# --- Branch: Pipeline INACTIVE -> intent-based skill routing ---
|
|
21
|
+
# The model has CLAUDE.md routing table but static instructions lose effectiveness
|
|
22
|
+
# as context grows. Reading the actual prompt and suggesting a SPECIFIC skill
|
|
23
|
+
# is far more actionable than a generic "check routing table" reminder.
|
|
24
24
|
if ! afc_state_is_active; then
|
|
25
|
+
|
|
26
|
+
# Extract prompt text from stdin JSON
|
|
27
|
+
USER_TEXT=""
|
|
28
|
+
if command -v jq >/dev/null 2>&1; then
|
|
29
|
+
USER_TEXT=$(printf '%s' "$INPUT" | jq -r '.prompt // empty' 2>/dev/null || true)
|
|
30
|
+
else
|
|
31
|
+
# shellcheck disable=SC2001
|
|
32
|
+
# Note: sed fallback truncates at first embedded escaped quote — acceptable for keyword matching
|
|
33
|
+
USER_TEXT=$(printf '%s' "$INPUT" | sed 's/.*"prompt"[[:space:]]*:[[:space:]]*"//;s/".*//' 2>/dev/null || true)
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Skip if prompt is already an explicit slash command
|
|
37
|
+
if printf '%s' "$USER_TEXT" | grep -qE '^\s*/afc:' 2>/dev/null; then
|
|
38
|
+
exit 0
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# Normalize: lowercase + truncate for matching
|
|
42
|
+
LOWER=$(printf '%s' "$USER_TEXT" | tr '[:upper:]' '[:lower:]' | cut -c1-500)
|
|
43
|
+
|
|
44
|
+
# Early exit for empty prompts (context-only messages, malformed JSON)
|
|
45
|
+
if [ -z "$LOWER" ]; then
|
|
46
|
+
if command -v jq >/dev/null 2>&1; then
|
|
47
|
+
jq -n --arg c "[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table." \
|
|
48
|
+
'{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
49
|
+
else
|
|
50
|
+
printf '{"hookSpecificOutput":{"additionalContext":"[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table."}}\n'
|
|
51
|
+
fi
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Intent detection: priority-ordered if/elif chain.
|
|
56
|
+
# Each pattern targets strong-signal phrases to minimize false positives.
|
|
57
|
+
# The model retains final authority — this is a hint, not enforcement.
|
|
58
|
+
SKILL=""
|
|
59
|
+
# 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
|
|
61
|
+
SKILL="afc:debug"
|
|
62
|
+
elif printf '%s' "$LOWER" | grep -qE '(code review|pr review)' 2>/dev/null; then
|
|
63
|
+
SKILL="afc:review"
|
|
64
|
+
elif printf '%s' "$LOWER" | grep -qE '(write test|add test|test coverage|improve coverage)' 2>/dev/null; then
|
|
65
|
+
SKILL="afc:test"
|
|
66
|
+
elif printf '%s' "$LOWER" | grep -qE '(security scan|security review|security audit|vulnerabilit)' 2>/dev/null; then
|
|
67
|
+
SKILL="afc:security"
|
|
68
|
+
elif printf '%s' "$LOWER" | grep -qE '(architecture|architect|system design)' 2>/dev/null; then
|
|
69
|
+
SKILL="afc:architect"
|
|
70
|
+
elif printf '%s' "$LOWER" | grep -qE '(doctor|health check|diagnose.*project)' 2>/dev/null; then
|
|
71
|
+
SKILL="afc:doctor"
|
|
72
|
+
elif printf '%s' "$LOWER" | grep -qE '(quality audit|qa audit|project quality)' 2>/dev/null; then
|
|
73
|
+
SKILL="afc:qa"
|
|
74
|
+
elif printf '%s' "$LOWER" | grep -qE '(new release|version bump|changelog|publish.*package)' 2>/dev/null; then
|
|
75
|
+
SKILL="afc:launch"
|
|
76
|
+
# Medium confidence: still distinctive but broader
|
|
77
|
+
elif printf '%s' "$LOWER" | grep -qE '(specification|requirements|acceptance criteria)' 2>/dev/null; then
|
|
78
|
+
SKILL="afc:spec"
|
|
79
|
+
elif printf '%s' "$LOWER" | grep -qE '(brainstorm|ideate|what to build|product brief)' 2>/dev/null; then
|
|
80
|
+
SKILL="afc:ideate"
|
|
81
|
+
elif printf '%s' "$LOWER" | grep -qE '(expert advice)' 2>/dev/null; then
|
|
82
|
+
SKILL="afc:consult"
|
|
83
|
+
elif printf '%s' "$LOWER" | grep -qE '(analyz|trace.*flow|how does.*work)' 2>/dev/null; then
|
|
84
|
+
SKILL="afc:analyze"
|
|
85
|
+
elif printf '%s' "$LOWER" | grep -qE '(research|investigat|compare.*lib)' 2>/dev/null; then
|
|
86
|
+
SKILL="afc:research"
|
|
87
|
+
# Lower confidence: common verbs
|
|
88
|
+
elif printf '%s' "$LOWER" | grep -qE '(implement|add feature|refactor|modify.*code)' 2>/dev/null; then
|
|
89
|
+
SKILL="afc:implement"
|
|
90
|
+
elif printf '%s' "$LOWER" | grep -qE '(review)' 2>/dev/null; then
|
|
91
|
+
SKILL="afc:review"
|
|
92
|
+
elif printf '%s' "$LOWER" | grep -qE '(spec[^a-z]|spec$)' 2>/dev/null; then
|
|
93
|
+
SKILL="afc:spec"
|
|
94
|
+
elif printf '%s' "$LOWER" | grep -qE '(plan[^a-z]|plan$)' 2>/dev/null; then
|
|
95
|
+
SKILL="afc:plan"
|
|
96
|
+
fi
|
|
97
|
+
|
|
98
|
+
# Build output (no TASK HYGIENE in inactive mode — stop-gate handles cleanup scope)
|
|
99
|
+
if [ -n "$SKILL" ]; then
|
|
100
|
+
HINT="[afc:route -> ${SKILL}] Detected intent from user prompt. Invoke /${SKILL} via Skill tool."
|
|
101
|
+
else
|
|
102
|
+
HINT="[afc] If this request matches an afc skill, invoke it via Skill tool. See CLAUDE.md routing table."
|
|
103
|
+
fi
|
|
104
|
+
|
|
105
|
+
if command -v jq >/dev/null 2>&1; then
|
|
106
|
+
jq -n --arg c "$HINT" '{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
107
|
+
else
|
|
108
|
+
printf '{"hookSpecificOutput":{"additionalContext":"%s"}}\n' "$HINT"
|
|
109
|
+
fi
|
|
25
110
|
exit 0
|
|
26
111
|
fi
|
|
27
112
|
|
|
28
|
-
# --- Branch: Pipeline ACTIVE
|
|
113
|
+
# --- Branch: Pipeline ACTIVE -> existing Phase/Feature context ---
|
|
29
114
|
|
|
30
|
-
# Read Feature/Phase + JSON-safe processing (strip special characters)
|
|
115
|
+
# Read Feature/Phase + JSON-safe processing (strip special characters + newlines)
|
|
31
116
|
FEATURE="$(afc_state_read feature || echo '')"
|
|
32
|
-
FEATURE="$(printf '%s' "$FEATURE" | tr -d '"' | cut -c1-100)"
|
|
117
|
+
FEATURE="$(printf '%s' "$FEATURE" | tr -d '"\n\r' | cut -c1-100)"
|
|
33
118
|
PHASE="$(afc_state_read phase || echo 'unknown')"
|
|
34
|
-
PHASE="$(printf '%s' "$PHASE" | tr -d '"' | cut -c1-100)"
|
|
119
|
+
PHASE="$(printf '%s' "$PHASE" | tr -d '"\n\r' | cut -c1-100)"
|
|
35
120
|
|
|
36
121
|
# Increment per-phase prompt counter + pipeline-wide total
|
|
37
122
|
CALL_COUNT=$(afc_state_increment promptCount 2>/dev/null || echo 0)
|
|
38
123
|
afc_state_increment totalPromptCount >/dev/null 2>&1 || echo "[afc:prompt-submit] totalPromptCount increment failed" >&2
|
|
39
124
|
|
|
40
125
|
# Build context message
|
|
41
|
-
CONTEXT="[Pipeline: ${FEATURE}] [Phase: ${PHASE}]"
|
|
126
|
+
CONTEXT="[Pipeline: ${FEATURE}] [Phase: ${PHASE}] [TASK HYGIENE: Mark completed tasks via TaskUpdate(status: completed) -- do not leave stale tasks]"
|
|
42
127
|
|
|
43
128
|
# Drift checkpoint: inject plan constraints at every N prompts during implement/review
|
|
44
129
|
# AFC_DRIFT_THRESHOLD sourced from afc-state.sh (SSOT)
|
|
@@ -53,7 +138,7 @@ fi
|
|
|
53
138
|
|
|
54
139
|
# Output additionalContext to stdout (injected into Claude context)
|
|
55
140
|
# Use jq for safe JSON encoding; printf fallback strips remaining quotes
|
|
56
|
-
if command -v jq
|
|
141
|
+
if command -v jq >/dev/null 2>&1; then
|
|
57
142
|
jq -n --arg c "$CONTEXT" '{"hookSpecificOutput":{"additionalContext":$c}}'
|
|
58
143
|
else
|
|
59
144
|
SAFE_CONTEXT="${CONTEXT//\\/\\\\}"
|
|
@@ -79,14 +79,14 @@ fi
|
|
|
79
79
|
# Guard against empty lists
|
|
80
80
|
if [ -n "$MODIFIED" ]; then
|
|
81
81
|
# shellcheck disable=SC2001
|
|
82
|
-
MODIFIED_LIST=$(
|
|
82
|
+
MODIFIED_LIST=$(printf '%s\n' "$MODIFIED" | sed 's/^/ - /')
|
|
83
83
|
else
|
|
84
84
|
MODIFIED_LIST=" (none)"
|
|
85
85
|
fi
|
|
86
86
|
|
|
87
87
|
if [ -n "$STAGED" ]; then
|
|
88
88
|
# shellcheck disable=SC2001
|
|
89
|
-
STAGED_LIST=$(
|
|
89
|
+
STAGED_LIST=$(printf '%s\n' "$STAGED" | sed 's/^/ - /')
|
|
90
90
|
else
|
|
91
91
|
STAGED_LIST=" (none)"
|
|
92
92
|
fi
|
|
@@ -30,9 +30,11 @@ ENCODED_PATH="${PROJECT_PATH//\//-}"
|
|
|
30
30
|
MEMORY_DIR="$HOME/.claude/projects/$ENCODED_PATH/memory"
|
|
31
31
|
CHECKPOINT="$MEMORY_DIR/checkpoint.md"
|
|
32
32
|
OUTPUT=""
|
|
33
|
+
PIPELINE_ACTIVE=0
|
|
33
34
|
|
|
34
35
|
# 1. Check for active pipeline
|
|
35
36
|
if afc_state_is_active; then
|
|
37
|
+
PIPELINE_ACTIVE=1
|
|
36
38
|
FEATURE=$(afc_state_read feature || true)
|
|
37
39
|
OUTPUT="[AFC PIPELINE ACTIVE] Feature: $FEATURE"
|
|
38
40
|
|
|
@@ -49,20 +51,47 @@ if afc_state_is_active; then
|
|
|
49
51
|
if [ -n "$CI_TIMESTAMP" ]; then
|
|
50
52
|
OUTPUT="$OUTPUT | Last CI: PASSED ($CI_TIMESTAMP)"
|
|
51
53
|
fi
|
|
54
|
+
elif [ -f "$PROJECT_DIR/.claude/.afc-state.json" ]; then
|
|
55
|
+
# 1a. Zombie state cleanup — file exists but afc_state_is_active returned false
|
|
56
|
+
rm -f "$PROJECT_DIR/.claude/.afc-state.json"
|
|
57
|
+
OUTPUT="${OUTPUT:+$OUTPUT | }[ZOMBIE STATE CLEANED] Removed invalid .afc-state.json"
|
|
52
58
|
fi
|
|
53
59
|
|
|
54
|
-
#
|
|
60
|
+
# 1b. Version mismatch detection
|
|
61
|
+
PLUGIN_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
|
62
|
+
if [ -f "$PLUGIN_ROOT/package.json" ]; then
|
|
63
|
+
# Read plugin version
|
|
64
|
+
if command -v jq >/dev/null 2>&1; then
|
|
65
|
+
PLUGIN_VERSION=$(jq -r '.version // empty' "$PLUGIN_ROOT/package.json" 2>/dev/null || true)
|
|
66
|
+
else
|
|
67
|
+
PLUGIN_VERSION=$(grep -o '"version"[[:space:]]*:[[:space:]]*"[^"]*"' "$PLUGIN_ROOT/package.json" 2>/dev/null | head -1 | sed 's/.*: *"//;s/"//') || true
|
|
68
|
+
fi
|
|
69
|
+
|
|
70
|
+
if [ -n "${PLUGIN_VERSION:-}" ]; then
|
|
71
|
+
# Read AFC block version from global CLAUDE.md
|
|
72
|
+
GLOBAL_CLAUDE="$HOME/.claude/CLAUDE.md"
|
|
73
|
+
if [ -f "$GLOBAL_CLAUDE" ]; then
|
|
74
|
+
BLOCK_VERSION=$(grep -o 'AFC:VERSION:[0-9][0-9.]*' "$GLOBAL_CLAUDE" 2>/dev/null | head -1 | sed 's/AFC:VERSION://' || true)
|
|
75
|
+
if [ -n "${BLOCK_VERSION:-}" ] && [ "$BLOCK_VERSION" != "$PLUGIN_VERSION" ]; then
|
|
76
|
+
OUTPUT="${OUTPUT:+$OUTPUT | }[AFC VERSION MISMATCH] v$PLUGIN_VERSION installed but CLAUDE.md block is v$BLOCK_VERSION. Run /afc:init to update."
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
fi
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# 2. Auto-memory checkpoint cleanup (prevent stale context pollution)
|
|
83
|
+
# Auto-memory files are auto-loaded into every conversation by Claude Code.
|
|
84
|
+
# Stale checkpoints from previous sessions can confuse the model.
|
|
85
|
+
# Only remove auto-memory when project-local copy also exists (prevents stranded checkpoint data loss).
|
|
55
86
|
LOCAL_CHECKPOINT="$PROJECT_DIR/.claude/afc/memory/checkpoint.md"
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
CHECKPOINT_FILE="$LOCAL_CHECKPOINT"
|
|
59
|
-
elif [ -f "$CHECKPOINT" ]; then
|
|
60
|
-
CHECKPOINT_FILE="$CHECKPOINT"
|
|
87
|
+
if [ "$PIPELINE_ACTIVE" -eq 0 ] && [ -f "$CHECKPOINT" ] && [ -f "$LOCAL_CHECKPOINT" ]; then
|
|
88
|
+
rm -f "$CHECKPOINT"
|
|
61
89
|
fi
|
|
62
90
|
|
|
63
|
-
if
|
|
64
|
-
|
|
65
|
-
|
|
91
|
+
# 3. Check if project-local checkpoint exists (for user notification only)
|
|
92
|
+
if [ -f "$LOCAL_CHECKPOINT" ]; then
|
|
93
|
+
RAW_LINE=$(grep 'Auto-generated:' "$LOCAL_CHECKPOINT" 2>/dev/null || echo "")
|
|
94
|
+
FIRST_LINE=$(printf '%s\n' "$RAW_LINE" | head -1)
|
|
66
95
|
CHECKPOINT_DATE="${FIRST_LINE##*Auto-generated: }"
|
|
67
96
|
if [ -n "$CHECKPOINT_DATE" ]; then
|
|
68
97
|
if [ -n "$OUTPUT" ]; then
|
|
@@ -73,7 +102,7 @@ if [ -n "$CHECKPOINT_FILE" ]; then
|
|
|
73
102
|
fi
|
|
74
103
|
fi
|
|
75
104
|
|
|
76
|
-
#
|
|
105
|
+
# 4. Check for safety tag
|
|
77
106
|
HAS_SAFETY_TAG=$(cd "$PROJECT_DIR" 2>/dev/null && git tag -l 'afc/pre-*' 2>/dev/null | head -1 || echo "")
|
|
78
107
|
if [ -n "$HAS_SAFETY_TAG" ]; then
|
|
79
108
|
if [ -n "$OUTPUT" ]; then
|
|
@@ -14,14 +14,14 @@ cleanup() {
|
|
|
14
14
|
}
|
|
15
15
|
trap cleanup EXIT
|
|
16
16
|
|
|
17
|
+
# Consume stdin immediately (prevents SIGPIPE if exiting early)
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
|
|
17
20
|
# If pipeline is inactive -> skip
|
|
18
21
|
if ! afc_state_is_active; then
|
|
19
22
|
exit 0
|
|
20
23
|
fi
|
|
21
24
|
|
|
22
|
-
# Parse tool input from stdin
|
|
23
|
-
INPUT=$(cat)
|
|
24
|
-
|
|
25
25
|
# Skip if stdin is empty
|
|
26
26
|
if [ -z "$INPUT" ]; then
|
|
27
27
|
exit 0
|