all-for-claudecode 2.2.0 → 2.3.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/MIGRATION.md +24 -0
- package/README.md +85 -17
- package/agents/afc-architect.md +7 -0
- package/agents/afc-security.md +6 -0
- package/commands/analyze.md +53 -75
- package/commands/architect.md +1 -1
- package/commands/auto.md +42 -22
- package/commands/doctor.md +16 -2
- package/commands/implement.md +2 -2
- package/commands/init.md +7 -5
- package/commands/launch.md +1 -1
- package/commands/plan.md +4 -4
- package/commands/resume.md +8 -3
- package/commands/review.md +1 -1
- package/commands/spec.md +3 -2
- package/commands/tasks.md +2 -2
- package/commands/validate.md +125 -0
- package/docs/phase-gate-protocol.md +17 -5
- package/hooks/hooks.json +2 -4
- package/package.json +1 -1
- package/scripts/afc-consistency-check.sh +32 -7
- package/scripts/afc-dag-validate.sh +3 -2
- package/scripts/afc-notify.sh +5 -6
- package/scripts/afc-parallel-validate.sh +3 -5
- package/scripts/afc-permission-request.sh +16 -2
- package/scripts/afc-pipeline-manage.sh +16 -0
- package/scripts/afc-state.sh +22 -26
- package/scripts/afc-stop-todo-check.sh +83 -0
- package/scripts/afc-task-completed-gate.sh +7 -1
- package/scripts/pre-compact-checkpoint.sh +19 -4
- package/scripts/session-start-context.sh +11 -3
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
# Stop TODO Check: Scan recently changed files for leftover TODO/FIXME/HACK
|
|
4
|
+
# Replaces the haiku agent hook — runs as command for zero-overhead when pipeline inactive.
|
|
5
|
+
#
|
|
6
|
+
# Returns exit 2 (block stop) if unresolved markers found in pipeline files.
|
|
7
|
+
# Returns exit 0 (allow stop) otherwise.
|
|
8
|
+
|
|
9
|
+
# shellcheck source=afc-state.sh
|
|
10
|
+
. "$(dirname "$0")/afc-state.sh"
|
|
11
|
+
|
|
12
|
+
# shellcheck disable=SC2329
|
|
13
|
+
cleanup() {
|
|
14
|
+
:
|
|
15
|
+
}
|
|
16
|
+
trap cleanup EXIT
|
|
17
|
+
|
|
18
|
+
# Consume stdin
|
|
19
|
+
INPUT=$(cat)
|
|
20
|
+
|
|
21
|
+
# Exit immediately if pipeline is not active (zero overhead)
|
|
22
|
+
if ! afc_state_is_active; then
|
|
23
|
+
exit 0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Parse stop_hook_active to prevent infinite loop
|
|
27
|
+
STOP_HOOK_ACTIVE=""
|
|
28
|
+
if command -v jq &>/dev/null; then
|
|
29
|
+
STOP_HOOK_ACTIVE=$(printf '%s\n' "$INPUT" | jq -r '.stop_hook_active // empty' 2>/dev/null || true)
|
|
30
|
+
else
|
|
31
|
+
if printf '%s\n' "$INPUT" | grep -q '"stop_hook_active"[[:space:]]*:[[:space:]]*true' 2>/dev/null; then
|
|
32
|
+
STOP_HOOK_ACTIVE="true"
|
|
33
|
+
fi
|
|
34
|
+
fi
|
|
35
|
+
if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Read current phase — only check in implementation/review/clean phases
|
|
40
|
+
CURRENT_PHASE="$(afc_state_read phase || echo '')"
|
|
41
|
+
if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Read changed files from state
|
|
46
|
+
CHANGES=""
|
|
47
|
+
CHANGES=$(afc_state_read_changes 2>/dev/null || true)
|
|
48
|
+
|
|
49
|
+
if [ -z "$CHANGES" ]; then
|
|
50
|
+
exit 0
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Check up to 5 recently changed files for TODO/FIXME/HACK markers
|
|
54
|
+
FOUND_MARKERS=""
|
|
55
|
+
COUNT=0
|
|
56
|
+
PROJECT_DIR="${CLAUDE_PROJECT_DIR:-$(pwd)}"
|
|
57
|
+
|
|
58
|
+
while IFS= read -r file_path; do
|
|
59
|
+
[ -z "$file_path" ] && continue
|
|
60
|
+
COUNT=$((COUNT + 1))
|
|
61
|
+
[ "$COUNT" -gt 5 ] && break
|
|
62
|
+
|
|
63
|
+
# Handle both absolute paths (from Claude tool_input) and relative paths
|
|
64
|
+
if [ "${file_path#/}" != "$file_path" ]; then
|
|
65
|
+
FULL_PATH="$file_path"
|
|
66
|
+
else
|
|
67
|
+
FULL_PATH="$PROJECT_DIR/$file_path"
|
|
68
|
+
fi
|
|
69
|
+
[ -f "$FULL_PATH" ] || continue
|
|
70
|
+
|
|
71
|
+
MARKERS=$(grep -nE '\b(TODO|FIXME|HACK)\b' "$FULL_PATH" 2>/dev/null | head -3 || true)
|
|
72
|
+
if [ -n "$MARKERS" ]; then
|
|
73
|
+
FOUND_MARKERS="${FOUND_MARKERS}${file_path}:\n${MARKERS}\n\n"
|
|
74
|
+
fi
|
|
75
|
+
done <<< "$CHANGES"
|
|
76
|
+
|
|
77
|
+
if [ -n "$FOUND_MARKERS" ]; then
|
|
78
|
+
printf "[afc:todo-check] Unresolved markers found in changed files:\n%b" "$FOUND_MARKERS" >&2
|
|
79
|
+
printf "[afc:todo-check] Resolve TODO/FIXME/HACK markers before completing the pipeline.\n" >&2
|
|
80
|
+
exit 2
|
|
81
|
+
fi
|
|
82
|
+
|
|
83
|
+
exit 0
|
|
@@ -37,7 +37,13 @@ if afc_is_ci_exempt "${CURRENT_PHASE:-}"; then
|
|
|
37
37
|
exit 0
|
|
38
38
|
fi
|
|
39
39
|
|
|
40
|
-
# Implement
|
|
40
|
+
# Implement phase: allow individual task completions without CI
|
|
41
|
+
# CI runs AFTER all tasks finish. Stop gate enforces CI at pipeline stop.
|
|
42
|
+
if [ "${CURRENT_PHASE:-}" = "implement" ]; then
|
|
43
|
+
exit 0
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
# Review/Clean phases require CI to pass
|
|
41
47
|
CI_TIME="$(afc_state_read ciPassedAt 2>/dev/null || echo '')"
|
|
42
48
|
CI_TIME="$(printf '%s' "$CI_TIME" | tr -dc '0-9')"
|
|
43
49
|
CI_TIME="${CI_TIME:-0}"
|
|
@@ -27,11 +27,18 @@ ENCODED_PATH="${PROJECT_PATH//\//-}"
|
|
|
27
27
|
MEMORY_DIR="$HOME/.claude/projects/$ENCODED_PATH/memory"
|
|
28
28
|
CHECKPOINT="$MEMORY_DIR/checkpoint.md"
|
|
29
29
|
|
|
30
|
-
#
|
|
30
|
+
# Project-local checkpoint path (used by /afc:resume)
|
|
31
|
+
LOCAL_MEMORY_DIR="$PROJECT_DIR/.claude/afc/memory"
|
|
32
|
+
LOCAL_CHECKPOINT="$LOCAL_MEMORY_DIR/checkpoint.md"
|
|
33
|
+
|
|
34
|
+
# Create both memory directories
|
|
31
35
|
mkdir -p "$MEMORY_DIR"
|
|
36
|
+
mkdir -p "$LOCAL_MEMORY_DIR"
|
|
32
37
|
|
|
33
38
|
# Collect current git status
|
|
34
39
|
BRANCH=$(cd "$PROJECT_DIR" 2>/dev/null && git branch --show-current 2>/dev/null || echo "unknown")
|
|
40
|
+
COMMIT_HASH=$(cd "$PROJECT_DIR" 2>/dev/null && git rev-parse --short HEAD 2>/dev/null || echo "none")
|
|
41
|
+
COMMIT_MSG=$(cd "$PROJECT_DIR" 2>/dev/null && git log -1 --format='%s' 2>/dev/null || echo "no commits")
|
|
35
42
|
|
|
36
43
|
ALL_MODIFIED=$(cd "$PROJECT_DIR" 2>/dev/null && git diff --name-only 2>/dev/null || true)
|
|
37
44
|
MODIFIED=$(printf '%s\n' "$ALL_MODIFIED" | head -10)
|
|
@@ -84,14 +91,15 @@ else
|
|
|
84
91
|
STAGED_LIST=" (none)"
|
|
85
92
|
fi
|
|
86
93
|
|
|
87
|
-
#
|
|
88
|
-
|
|
94
|
+
# Build checkpoint content (shared between both locations)
|
|
95
|
+
CHECKPOINT_CONTENT="$(cat << EOF
|
|
89
96
|
# Auto Checkpoint (Pre-Compact)
|
|
90
97
|
> Auto-generated: $(date '+%Y-%m-%d %H:%M:%S')
|
|
91
98
|
> Trigger: context compaction
|
|
92
99
|
|
|
93
100
|
## Git Status
|
|
94
101
|
- Branch: $BRANCH
|
|
102
|
+
- Commit: $COMMIT_HASH — $COMMIT_MSG
|
|
95
103
|
- Modified files: ${MODIFIED_COUNT}
|
|
96
104
|
$MODIFIED_LIST
|
|
97
105
|
|
|
@@ -107,8 +115,15 @@ $STAGED_LIST
|
|
|
107
115
|
/afc:resume
|
|
108
116
|
\`\`\`
|
|
109
117
|
EOF
|
|
118
|
+
)"
|
|
119
|
+
|
|
120
|
+
# Write to auto-memory (Claude context recovery after compaction)
|
|
121
|
+
printf '%s\n' "$CHECKPOINT_CONTENT" > "$CHECKPOINT"
|
|
122
|
+
|
|
123
|
+
# Write to project-local path (used by /afc:resume command)
|
|
124
|
+
printf '%s\n' "$CHECKPOINT_CONTENT" > "$LOCAL_CHECKPOINT"
|
|
110
125
|
|
|
111
126
|
# Inject context via stdout (Claude can see this info after compaction)
|
|
112
|
-
echo "Auto-checkpoint saved
|
|
127
|
+
echo "Auto-checkpoint saved (branch: $BRANCH, commit: $COMMIT_HASH, pipeline: ${PIPELINE_FEATURE:-inactive})"
|
|
113
128
|
|
|
114
129
|
exit 0
|
|
@@ -51,9 +51,17 @@ if afc_state_is_active; then
|
|
|
51
51
|
fi
|
|
52
52
|
fi
|
|
53
53
|
|
|
54
|
-
# 2. Check if checkpoint exists
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
# 2. Check if checkpoint exists (project-local first, fallback to auto-memory)
|
|
55
|
+
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"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
if [ -n "$CHECKPOINT_FILE" ]; then
|
|
64
|
+
RAW_LINE=$(grep 'Auto-generated:' "$CHECKPOINT_FILE" 2>/dev/null || echo "")
|
|
57
65
|
FIRST_LINE=$(echo "$RAW_LINE" | head -1)
|
|
58
66
|
CHECKPOINT_DATE="${FIRST_LINE##*Auto-generated: }"
|
|
59
67
|
if [ -n "$CHECKPOINT_DATE" ]; then
|