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.
Files changed (51) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +4 -2
  3. package/README.md +15 -3
  4. package/agents/afc-architect.md +1 -1
  5. package/agents/afc-security.md +1 -1
  6. package/commands/analyze.md +1 -1
  7. package/commands/architect.md +1 -1
  8. package/commands/auto.md +2 -2
  9. package/commands/checkpoint.md +1 -1
  10. package/commands/clarify.md +1 -1
  11. package/commands/clean.md +126 -0
  12. package/commands/consult.md +1 -1
  13. package/commands/debug.md +1 -1
  14. package/commands/doctor.md +64 -23
  15. package/commands/ideate.md +1 -1
  16. package/commands/implement.md +1 -1
  17. package/commands/init.md +10 -6
  18. package/commands/launch.md +1 -1
  19. package/commands/plan.md +1 -1
  20. package/commands/pr-comment.md +1 -1
  21. package/commands/principles.md +1 -1
  22. package/commands/qa.md +191 -0
  23. package/commands/release-notes.md +1 -1
  24. package/commands/research.md +1 -1
  25. package/commands/resume.md +2 -2
  26. package/commands/review.md +1 -1
  27. package/commands/security.md +1 -1
  28. package/commands/spec.md +1 -1
  29. package/commands/tasks.md +1 -1
  30. package/commands/test.md +1 -1
  31. package/commands/triage.md +1 -1
  32. package/commands/validate.md +1 -1
  33. package/docs/phase-gate-protocol.md +1 -1
  34. package/hooks/hooks.json +1 -0
  35. package/package.json +5 -3
  36. package/schemas/hooks.schema.json +4 -0
  37. package/schemas/plugin.schema.json +5 -1
  38. package/scripts/afc-bash-guard.sh +3 -3
  39. package/scripts/afc-config-change.sh +8 -0
  40. package/scripts/afc-consistency-check.sh +58 -19
  41. package/scripts/afc-dag-validate.sh +1 -1
  42. package/scripts/afc-doctor.sh +445 -0
  43. package/scripts/afc-failure-hint.sh +24 -2
  44. package/scripts/afc-qa-audit.sh +536 -0
  45. package/scripts/afc-state.sh +3 -3
  46. package/scripts/afc-sync-cache.sh +49 -0
  47. package/scripts/afc-triage.sh +14 -3
  48. package/scripts/afc-user-prompt-submit.sh +98 -13
  49. package/scripts/pre-compact-checkpoint.sh +2 -2
  50. package/scripts/session-start-context.sh +39 -10
  51. 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: No action (routing handled by CLAUDE.md intent-based skill table)
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
- # Consume stdin (required -- pipe breaks if not consumed)
19
- cat > /dev/null
17
+ # Read stdin (contains user prompt JSON)
18
+ INPUT=$(cat)
20
19
 
21
- # --- Branch: Pipeline INACTIVE no action needed ---
22
- # Routing is handled by CLAUDE.md intent-based skill routing table.
23
- # The main model classifies user intent natively no hook-level keyword matching.
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 existing Phase/Feature context ---
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 &> /dev/null; then
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=$(echo "$MODIFIED" | sed 's/^/ - /')
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=$(echo "$STAGED" | sed 's/^/ - /')
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
- # 2. Check if checkpoint exists (project-local first, fallback to auto-memory)
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
- CHECKPOINT_FILE=""
57
- if [ -f "$LOCAL_CHECKPOINT" ]; then
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 [ -n "$CHECKPOINT_FILE" ]; then
64
- RAW_LINE=$(grep 'Auto-generated:' "$CHECKPOINT_FILE" 2>/dev/null || echo "")
65
- FIRST_LINE=$(echo "$RAW_LINE" | head -1)
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
- # 3. Check for safety tag
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