codecruise 0.1.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/LICENSE +21 -0
- package/README.md +111 -0
- package/bin/codecruise.js +68 -0
- package/config/CLAUDE.md +107 -0
- package/config/agents/analyst.md +48 -0
- package/config/agents/architect-reviewer.md +161 -0
- package/config/agents/architect.md +119 -0
- package/config/agents/critic.md +63 -0
- package/config/agents/developer.md +96 -0
- package/config/agents/devops.md +81 -0
- package/config/agents/orchestrator.md +91 -0
- package/config/agents/planner.md +139 -0
- package/config/agents/retro.md +52 -0
- package/config/agents/reviewer.md +101 -0
- package/config/agents/security-reviewer.md +57 -0
- package/config/agents/stack/expo/AGENT.md +473 -0
- package/config/agents/stack/expo/rules/critical.md +427 -0
- package/config/agents/stack/expo/rules/native.md +455 -0
- package/config/agents/stack/expo/rules/navigation.md +445 -0
- package/config/agents/stack/expo/rules/performance.md +415 -0
- package/config/agents/stack/fastify/AGENT.md +397 -0
- package/config/agents/stack/fastify/rules/api-design.md +283 -0
- package/config/agents/stack/fastify/rules/critical.md +232 -0
- package/config/agents/stack/fastify/rules/queues.md +303 -0
- package/config/agents/stack/fastify/rules/security.md +384 -0
- package/config/agents/stack/index.yaml +48 -0
- package/config/agents/stack/nextjs/AGENT.md +421 -0
- package/config/agents/stack/nextjs/rules/components.md +413 -0
- package/config/agents/stack/nextjs/rules/critical.md +391 -0
- package/config/agents/stack/nextjs/rules/performance.md +403 -0
- package/config/agents/stack/nextjs/rules/styling.md +334 -0
- package/config/agents/stack/shared-ts/AGENT.md +384 -0
- package/config/agents/stack/shared-ts/rules/critical.md +315 -0
- package/config/agents/stack/shared-ts/rules/patterns.md +384 -0
- package/config/agents/stack/shared-ts/rules/zod.md +427 -0
- package/config/agents/tester.md +79 -0
- package/config/commands/architect-discuss.md +366 -0
- package/config/commands/architect-list.md +160 -0
- package/config/commands/architect-review.md +111 -0
- package/config/commands/architect.md +118 -0
- package/config/commands/compact.md +118 -0
- package/config/commands/companion.md +279 -0
- package/config/commands/dashboard.md +152 -0
- package/config/commands/doctor.md +227 -0
- package/config/commands/dogfood-report.md +101 -0
- package/config/commands/flags/run-autonomous.md +110 -0
- package/config/commands/flags/run-pause.md +80 -0
- package/config/commands/ingest.md +173 -0
- package/config/commands/init.md +128 -0
- package/config/commands/metrics.md +87 -0
- package/config/commands/parallel.md +320 -0
- package/config/commands/pause.md +55 -0
- package/config/commands/plan-review.md +130 -0
- package/config/commands/plan.md +216 -0
- package/config/commands/production-check.md +308 -0
- package/config/commands/refine.md +323 -0
- package/config/commands/resume.md +72 -0
- package/config/commands/retro.md +121 -0
- package/config/commands/retry.md +75 -0
- package/config/commands/role.md +310 -0
- package/config/commands/run.md +417 -0
- package/config/commands/scope.md +85 -0
- package/config/commands/setup-permissions.md +104 -0
- package/config/commands/skip.md +75 -0
- package/config/commands/spec-forge.md +213 -0
- package/config/commands/spec-help.md +194 -0
- package/config/commands/spec-patch.md +342 -0
- package/config/commands/spec-resolve.md +110 -0
- package/config/commands/spec-review.md +153 -0
- package/config/commands/status.md +114 -0
- package/config/commands/sync.md +131 -0
- package/config/commands/task.md +138 -0
- package/config/commands/verify.md +124 -0
- package/config/hooks/README.md +632 -0
- package/config/hooks/activity-log.sh +187 -0
- package/config/hooks/anti-rationalize.sh +52 -0
- package/config/hooks/capture-verification.sh +112 -0
- package/config/hooks/collect-metrics.sh +135 -0
- package/config/hooks/enforce-file-scope.sh +75 -0
- package/config/hooks/enforce-state-machine.sh +161 -0
- package/config/hooks/enforce-tdd.sh +180 -0
- package/config/hooks/format.sh +40 -0
- package/config/hooks/lib/activity-helpers.sh +162 -0
- package/config/hooks/lib/read-settings.sh +71 -0
- package/config/hooks/load-context-skills.sh +95 -0
- package/config/hooks/notify.sh +81 -0
- package/config/hooks/pre-commit.sample +35 -0
- package/config/hooks/protect-files.sh +63 -0
- package/config/hooks/track-agents.sh +41 -0
- package/config/hooks/track-commands.sh +37 -0
- package/config/hooks/track-enforcement.sh +44 -0
- package/config/hooks/track-ooda.sh +77 -0
- package/config/hooks/validate-commit-msg.sh +35 -0
- package/config/hooks/validate-plan.sh +213 -0
- package/config/hooks/verify-criteria.sh +46 -0
- package/config/hooks/verify-todo-completion.sh +140 -0
- package/config/rules/comments.md +25 -0
- package/config/rules/decision-rules.md +308 -0
- package/config/rules/hygiene.md +247 -0
- package/config/rules/pattern-detection.md +372 -0
- package/config/rules/profiles.md +193 -0
- package/config/rules/recovery.md +83 -0
- package/config/rules/scope-detection.md +213 -0
- package/config/rules/standards.md +127 -0
- package/config/rules/workflow.md +121 -0
- package/config/schemas.md +767 -0
- package/config/settings.json +195 -0
- package/config/skills/backend/SKILL.md +734 -0
- package/config/skills/database/SKILL.md +426 -0
- package/config/skills/frontend/SKILL.md +434 -0
- package/config/skills/git/SKILL.md +396 -0
- package/config/skills/index.yaml +36 -0
- package/config/skills/observability/SKILL.md +430 -0
- package/config/skills/package-dev/SKILL.md +498 -0
- package/config/skills/performance/SKILL.md +378 -0
- package/config/skills/resilience/SKILL.md +573 -0
- package/config/skills/testing/SKILL.md +398 -0
- package/config/skills/testing-patterns/SKILL.md +276 -0
- package/config/skills/typescript/SKILL.md +152 -0
- package/config/templates/CLAUDE.md +70 -0
- package/config/templates/README.md +117 -0
- package/config/templates/steering/adr-template.md +102 -0
- package/config/templates/steering/product.md +60 -0
- package/config/templates/steering/rfc-template.md +159 -0
- package/config/templates/steering/structure.md +146 -0
- package/config/templates/steering/tech.md +85 -0
- package/package.json +40 -0
- package/src/install.js +163 -0
- package/src/report.js +310 -0
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# validate-plan.sh — Plan consistency validation
|
|
3
|
+
#
|
|
4
|
+
# Called by /doctor --validate-plan
|
|
5
|
+
# Checks roadmap vs progress.yaml for consistency
|
|
6
|
+
#
|
|
7
|
+
# Outputs JSON to .codecruise/validation-results.json
|
|
8
|
+
#
|
|
9
|
+
# Checks:
|
|
10
|
+
# 1. Orphan TODOs (in queue but not roadmap)
|
|
11
|
+
# 2. Missing TODOs (in roadmap but not queue)
|
|
12
|
+
# 3. Circular dependencies
|
|
13
|
+
# 4. Invalid depends_on references
|
|
14
|
+
# 5. Stale state detection
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
ROADMAP_DIR="roadmap"
|
|
19
|
+
PROGRESS_FILE="progress.yaml"
|
|
20
|
+
OUTPUT_FILE=".codecruise/validation-results.json"
|
|
21
|
+
|
|
22
|
+
# Ensure output directory exists
|
|
23
|
+
mkdir -p "$(dirname "$OUTPUT_FILE")"
|
|
24
|
+
|
|
25
|
+
# Initialize results
|
|
26
|
+
ORPHANS=()
|
|
27
|
+
MISSING=()
|
|
28
|
+
INVALID_DEPS=()
|
|
29
|
+
HAS_CYCLES=false
|
|
30
|
+
STALE_STATE=""
|
|
31
|
+
|
|
32
|
+
# --- Helper Functions ---
|
|
33
|
+
|
|
34
|
+
# Extract all TODO IDs from roadmap files
|
|
35
|
+
get_roadmap_todos() {
|
|
36
|
+
if [[ -d "$ROADMAP_DIR" ]]; then
|
|
37
|
+
find "$ROADMAP_DIR" -name "*.yaml" -exec grep -ohE "todo-[0-9]+\.[0-9]+[a-z]-[0-9]+" {} \; 2>/dev/null | sort -u
|
|
38
|
+
fi
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
# Extract all TODO IDs from progress.yaml queues
|
|
42
|
+
get_queue_todos() {
|
|
43
|
+
if [[ -f "$PROGRESS_FILE" ]]; then
|
|
44
|
+
grep -ohE "todo-[0-9]+\.[0-9]+[a-z]-[0-9]+" "$PROGRESS_FILE" 2>/dev/null | sort -u
|
|
45
|
+
fi
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
# Extract depends_on relationships from roadmap
|
|
49
|
+
get_dependencies() {
|
|
50
|
+
if [[ -d "$ROADMAP_DIR" ]]; then
|
|
51
|
+
# Output: "dependent_todo dependency_todo" pairs
|
|
52
|
+
find "$ROADMAP_DIR" -name "*.yaml" -exec awk '
|
|
53
|
+
/^[[:space:]]*-[[:space:]]*id:/ { current_id = $3 }
|
|
54
|
+
/depends_on:/ {
|
|
55
|
+
gsub(/[\[\],]/, " ")
|
|
56
|
+
for (i=2; i<=NF; i++) {
|
|
57
|
+
if ($i ~ /todo-/) {
|
|
58
|
+
print $i, current_id
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
' {} \; 2>/dev/null
|
|
63
|
+
fi
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
# Check for circular dependencies using tsort
|
|
67
|
+
check_circular_deps() {
|
|
68
|
+
local deps
|
|
69
|
+
deps=$(get_dependencies)
|
|
70
|
+
|
|
71
|
+
if [[ -z "$deps" ]]; then
|
|
72
|
+
echo "false"
|
|
73
|
+
return
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# tsort returns non-zero if cycle detected
|
|
77
|
+
if echo "$deps" | tsort >/dev/null 2>&1; then
|
|
78
|
+
echo "false"
|
|
79
|
+
else
|
|
80
|
+
echo "true"
|
|
81
|
+
fi
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
# Check stale state (paused too long)
|
|
85
|
+
check_stale_state() {
|
|
86
|
+
if [[ ! -f "$PROGRESS_FILE" ]]; then
|
|
87
|
+
return
|
|
88
|
+
fi
|
|
89
|
+
|
|
90
|
+
local paused_at
|
|
91
|
+
paused_at=$(grep "paused_at:" "$PROGRESS_FILE" 2>/dev/null | head -1 | sed 's/.*paused_at:[[:space:]]*//' | tr -d '"' || echo "")
|
|
92
|
+
|
|
93
|
+
if [[ -z "$paused_at" ]] || [[ "$paused_at" == "null" ]]; then
|
|
94
|
+
return
|
|
95
|
+
fi
|
|
96
|
+
|
|
97
|
+
# Calculate hours since pause (rough calculation)
|
|
98
|
+
local pause_date
|
|
99
|
+
pause_date=$(echo "$paused_at" | cut -d'T' -f1)
|
|
100
|
+
local today
|
|
101
|
+
today=$(date "+%Y-%m-%d")
|
|
102
|
+
|
|
103
|
+
if [[ "$pause_date" != "$today" ]]; then
|
|
104
|
+
# Different day, check how many days
|
|
105
|
+
local pause_epoch today_epoch days_diff
|
|
106
|
+
|
|
107
|
+
# macOS uses -j -f, Linux uses -d
|
|
108
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
109
|
+
pause_epoch=$(date -j -f "%Y-%m-%d" "$pause_date" "+%s" 2>/dev/null || echo 0)
|
|
110
|
+
today_epoch=$(date "+%s")
|
|
111
|
+
else
|
|
112
|
+
pause_epoch=$(date -d "$pause_date" "+%s" 2>/dev/null || echo 0)
|
|
113
|
+
today_epoch=$(date "+%s")
|
|
114
|
+
fi
|
|
115
|
+
|
|
116
|
+
if [[ "$pause_epoch" -gt 0 ]]; then
|
|
117
|
+
days_diff=$(( (today_epoch - pause_epoch) / 86400 ))
|
|
118
|
+
|
|
119
|
+
if [[ "$days_diff" -gt 7 ]]; then
|
|
120
|
+
echo "stale_7d"
|
|
121
|
+
elif [[ "$days_diff" -gt 1 ]]; then
|
|
122
|
+
echo "stale_24h"
|
|
123
|
+
fi
|
|
124
|
+
fi
|
|
125
|
+
fi
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
# --- Main Validation ---
|
|
129
|
+
|
|
130
|
+
echo "Validating plan consistency..." >&2
|
|
131
|
+
|
|
132
|
+
# Get TODO lists
|
|
133
|
+
ROADMAP_TODOS=$(get_roadmap_todos)
|
|
134
|
+
QUEUE_TODOS=$(get_queue_todos)
|
|
135
|
+
|
|
136
|
+
# Find orphan TODOs (in queue but not roadmap)
|
|
137
|
+
if [[ -n "$QUEUE_TODOS" ]] && [[ -n "$ROADMAP_TODOS" ]]; then
|
|
138
|
+
while IFS= read -r todo; do
|
|
139
|
+
if ! echo "$ROADMAP_TODOS" | grep -q "^$todo$"; then
|
|
140
|
+
ORPHANS+=("$todo")
|
|
141
|
+
fi
|
|
142
|
+
done <<< "$QUEUE_TODOS"
|
|
143
|
+
fi
|
|
144
|
+
|
|
145
|
+
# Find missing TODOs (in roadmap but not queue)
|
|
146
|
+
if [[ -n "$ROADMAP_TODOS" ]] && [[ -n "$QUEUE_TODOS" ]]; then
|
|
147
|
+
while IFS= read -r todo; do
|
|
148
|
+
if ! echo "$QUEUE_TODOS" | grep -q "^$todo$"; then
|
|
149
|
+
MISSING+=("$todo")
|
|
150
|
+
fi
|
|
151
|
+
done <<< "$ROADMAP_TODOS"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
# Check for circular dependencies
|
|
155
|
+
HAS_CYCLES=$(check_circular_deps)
|
|
156
|
+
|
|
157
|
+
# Validate depends_on references
|
|
158
|
+
DEPS=$(get_dependencies)
|
|
159
|
+
if [[ -n "$DEPS" ]]; then
|
|
160
|
+
while read -r dep_todo dependent_todo; do
|
|
161
|
+
if ! echo "$ROADMAP_TODOS" | grep -q "^$dep_todo$"; then
|
|
162
|
+
INVALID_DEPS+=("$dependent_todo references invalid $dep_todo")
|
|
163
|
+
fi
|
|
164
|
+
done <<< "$DEPS"
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
# Check stale state
|
|
168
|
+
STALE_STATE=$(check_stale_state)
|
|
169
|
+
|
|
170
|
+
# --- Generate Output ---
|
|
171
|
+
|
|
172
|
+
# Convert arrays to JSON
|
|
173
|
+
orphans_json=$(printf '%s\n' "${ORPHANS[@]}" | jq -R . | jq -s .)
|
|
174
|
+
missing_json=$(printf '%s\n' "${MISSING[@]}" | jq -R . | jq -s .)
|
|
175
|
+
invalid_deps_json=$(printf '%s\n' "${INVALID_DEPS[@]}" | jq -R . | jq -s .)
|
|
176
|
+
|
|
177
|
+
# Handle empty arrays
|
|
178
|
+
[[ "$orphans_json" == "null" ]] && orphans_json="[]"
|
|
179
|
+
[[ "$missing_json" == "null" ]] && missing_json="[]"
|
|
180
|
+
[[ "$invalid_deps_json" == "null" ]] && invalid_deps_json="[]"
|
|
181
|
+
|
|
182
|
+
# Determine overall status
|
|
183
|
+
STATUS="pass"
|
|
184
|
+
if [[ ${#ORPHANS[@]} -gt 0 ]] || [[ ${#INVALID_DEPS[@]} -gt 0 ]] || [[ "$HAS_CYCLES" == "true" ]]; then
|
|
185
|
+
STATUS="fail"
|
|
186
|
+
elif [[ ${#MISSING[@]} -gt 0 ]] || [[ -n "$STALE_STATE" ]]; then
|
|
187
|
+
STATUS="warn"
|
|
188
|
+
fi
|
|
189
|
+
|
|
190
|
+
# Write results
|
|
191
|
+
cat << EOF > "$OUTPUT_FILE"
|
|
192
|
+
{
|
|
193
|
+
"timestamp": "$(date -u +%Y-%m-%dT%H:%M:%SZ)",
|
|
194
|
+
"status": "$STATUS",
|
|
195
|
+
"orphan_todos": $orphans_json,
|
|
196
|
+
"missing_todos": $missing_json,
|
|
197
|
+
"invalid_dependencies": $invalid_deps_json,
|
|
198
|
+
"has_circular_deps": $HAS_CYCLES,
|
|
199
|
+
"stale_state": "${STALE_STATE:-null}",
|
|
200
|
+
"roadmap_todo_count": $(echo "$ROADMAP_TODOS" | grep -c . || echo 0),
|
|
201
|
+
"queue_todo_count": $(echo "$QUEUE_TODOS" | grep -c . || echo 0)
|
|
202
|
+
}
|
|
203
|
+
EOF
|
|
204
|
+
|
|
205
|
+
# Output results to stdout for /doctor
|
|
206
|
+
cat "$OUTPUT_FILE"
|
|
207
|
+
|
|
208
|
+
# Exit with appropriate code
|
|
209
|
+
case "$STATUS" in
|
|
210
|
+
pass) exit 0 ;;
|
|
211
|
+
warn) exit 1 ;;
|
|
212
|
+
fail) exit 2 ;;
|
|
213
|
+
esac
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Stop hook helper - Extracts TODO criteria for agent verification
|
|
3
|
+
#
|
|
4
|
+
# This script reads the current TODO and outputs context for the agent hook
|
|
5
|
+
# to verify that acceptance criteria have been met.
|
|
6
|
+
#
|
|
7
|
+
# Used by the Stop agent hook to get criteria context.
|
|
8
|
+
|
|
9
|
+
# Check if we're in a codecruise project
|
|
10
|
+
if [[ ! -f "progress.yaml" ]]; then
|
|
11
|
+
echo "Not in a codecruise project"
|
|
12
|
+
exit 0
|
|
13
|
+
fi
|
|
14
|
+
|
|
15
|
+
# Get current TODO ID
|
|
16
|
+
CURRENT_TODO=$(grep -A5 "current:" progress.yaml | grep "todo:" | sed 's/.*todo: //' | tr -d ' "' || echo "")
|
|
17
|
+
|
|
18
|
+
if [[ -z "$CURRENT_TODO" || "$CURRENT_TODO" == "null" ]]; then
|
|
19
|
+
echo "No active TODO"
|
|
20
|
+
exit 0
|
|
21
|
+
fi
|
|
22
|
+
|
|
23
|
+
# Find the roadmap file containing this TODO
|
|
24
|
+
ROADMAP_FILE=$(grep -rl "id: $CURRENT_TODO" roadmap/ 2>/dev/null | head -1 || echo "")
|
|
25
|
+
|
|
26
|
+
if [[ -z "$ROADMAP_FILE" ]]; then
|
|
27
|
+
echo "TODO $CURRENT_TODO not found in roadmap/"
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Extract TODO block with criteria
|
|
32
|
+
echo "=== Current TODO: $CURRENT_TODO ==="
|
|
33
|
+
echo ""
|
|
34
|
+
|
|
35
|
+
# Use awk to extract the TODO block
|
|
36
|
+
awk "/id: $CURRENT_TODO/,/^[[:space:]]*- id:/" "$ROADMAP_FILE" | head -n -1
|
|
37
|
+
|
|
38
|
+
echo ""
|
|
39
|
+
echo "=== Verification Checklist ==="
|
|
40
|
+
echo ""
|
|
41
|
+
echo "Check each criterion above against the current codebase:"
|
|
42
|
+
echo "1. Read the files listed in 'files:' section"
|
|
43
|
+
echo "2. Verify each item in 'criteria:' is implemented"
|
|
44
|
+
echo "3. Verify each item in 'tests:' has a passing test"
|
|
45
|
+
echo ""
|
|
46
|
+
echo "Return {\"ok\": true} if ALL criteria met, or {\"ok\": false, \"reason\": \"what's missing\"}"
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Stop hook - Verifies TODO completion before allowing Claude to stop
|
|
3
|
+
#
|
|
4
|
+
# P0 Enforcement: Prevents "false done" by requiring:
|
|
5
|
+
# 1. Tests exist for implementation files
|
|
6
|
+
# 2. All tests pass
|
|
7
|
+
# 3. Lint passes
|
|
8
|
+
# 4. Typecheck passes (if TypeScript)
|
|
9
|
+
#
|
|
10
|
+
# Configuration (highest to lowest priority):
|
|
11
|
+
# 1. Command flag: /run --enforce=off
|
|
12
|
+
# 2. Project: .claude/settings.json → codecruise.enforce_quality
|
|
13
|
+
# 3. User: ~/.claude/settings.json → codecruise.enforce_quality
|
|
14
|
+
# 4. Default: strict
|
|
15
|
+
|
|
16
|
+
set -e
|
|
17
|
+
|
|
18
|
+
# Load settings library
|
|
19
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
20
|
+
if [[ -f "$SCRIPT_DIR/lib/read-settings.sh" ]]; then
|
|
21
|
+
source "$SCRIPT_DIR/lib/read-settings.sh"
|
|
22
|
+
elif [[ -f "$HOME/.claude/hooks/lib/read-settings.sh" ]]; then
|
|
23
|
+
source "$HOME/.claude/hooks/lib/read-settings.sh"
|
|
24
|
+
else
|
|
25
|
+
# Fallback if library not found
|
|
26
|
+
get_enforce_mode() { echo "${CODECRUISE_ENFORCE:-strict}"; }
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Load enforcement tracking
|
|
30
|
+
if [[ -f "$SCRIPT_DIR/track-enforcement.sh" ]]; then
|
|
31
|
+
source "$SCRIPT_DIR/track-enforcement.sh"
|
|
32
|
+
elif [[ -f "$HOME/.claude/hooks/track-enforcement.sh" ]]; then
|
|
33
|
+
source "$HOME/.claude/hooks/track-enforcement.sh"
|
|
34
|
+
else
|
|
35
|
+
track_enforcement() { :; }
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
INPUT=$(cat)
|
|
39
|
+
|
|
40
|
+
# Get enforcement mode from settings hierarchy
|
|
41
|
+
ENFORCE_MODE=$(get_enforce_mode "quality")
|
|
42
|
+
|
|
43
|
+
# If enforcement is off, allow stop
|
|
44
|
+
if [[ "$ENFORCE_MODE" == "off" ]]; then
|
|
45
|
+
exit 0
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
|
|
49
|
+
|
|
50
|
+
# Prevent infinite loop - if we already triggered continuation, allow stop
|
|
51
|
+
if [[ "$STOP_HOOK_ACTIVE" == "true" ]]; then
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
# Check if we're in a codecruise execution context
|
|
56
|
+
if [[ ! -f "progress.yaml" ]]; then
|
|
57
|
+
exit 0
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Get current TODO from progress.yaml
|
|
61
|
+
CURRENT_TODO=$(grep -A1 "current:" progress.yaml | grep "todo:" | sed 's/.*todo: //' | tr -d ' "' || echo "")
|
|
62
|
+
|
|
63
|
+
# If no current TODO, allow stop
|
|
64
|
+
if [[ -z "$CURRENT_TODO" || "$CURRENT_TODO" == "null" ]]; then
|
|
65
|
+
exit 0
|
|
66
|
+
fi
|
|
67
|
+
|
|
68
|
+
# Get execution status
|
|
69
|
+
EXEC_STATUS=$(grep "status:" progress.yaml | head -1 | sed 's/.*status: //' | tr -d ' "' || echo "")
|
|
70
|
+
|
|
71
|
+
# Only enforce during active execution
|
|
72
|
+
if [[ "$EXEC_STATUS" != "running" && "$EXEC_STATUS" != "in_progress" ]]; then
|
|
73
|
+
exit 0
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
VERIFY_DIR=".codecruise/verification"
|
|
77
|
+
SUMMARY_FILE="$VERIFY_DIR/summary.json"
|
|
78
|
+
|
|
79
|
+
# Run verification if summary doesn't exist or is stale (> 2 min old)
|
|
80
|
+
if [[ ! -f "$SUMMARY_FILE" ]] || [[ $(find "$SUMMARY_FILE" -mmin +2 2>/dev/null) ]]; then
|
|
81
|
+
if [[ -f ".claude/hooks/capture-verification.sh" ]]; then
|
|
82
|
+
bash .claude/hooks/capture-verification.sh 2>/dev/null || true
|
|
83
|
+
elif [[ -f "$HOME/.claude/hooks/capture-verification.sh" ]]; then
|
|
84
|
+
bash "$HOME/.claude/hooks/capture-verification.sh" 2>/dev/null || true
|
|
85
|
+
fi
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Check verification results
|
|
89
|
+
if [[ -f "$SUMMARY_FILE" ]]; then
|
|
90
|
+
LINT_EXIT=$(jq -r '.lint.exit_code // -1' "$SUMMARY_FILE")
|
|
91
|
+
TSC_EXIT=$(jq -r '.typecheck.exit_code // -1' "$SUMMARY_FILE")
|
|
92
|
+
TEST_EXIT=$(jq -r '.tests.exit_code // -1' "$SUMMARY_FILE")
|
|
93
|
+
TEST_FAILED=$(jq -r '.tests.failed // 0' "$SUMMARY_FILE")
|
|
94
|
+
|
|
95
|
+
FAILURES=""
|
|
96
|
+
|
|
97
|
+
# Check lint (skip if -1 meaning not configured)
|
|
98
|
+
if [[ "$LINT_EXIT" != "-1" && "$LINT_EXIT" != "0" ]]; then
|
|
99
|
+
FAILURES="$FAILURES lint"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
# Check typecheck (skip if -1 meaning not configured)
|
|
103
|
+
if [[ "$TSC_EXIT" != "-1" && "$TSC_EXIT" != "0" ]]; then
|
|
104
|
+
FAILURES="$FAILURES typecheck"
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
# Check tests (skip if -1 meaning not configured)
|
|
108
|
+
if [[ "$TEST_EXIT" != "-1" && "$TEST_EXIT" != "0" ]]; then
|
|
109
|
+
FAILURES="$FAILURES tests"
|
|
110
|
+
fi
|
|
111
|
+
|
|
112
|
+
# Check for failed tests even if exit was 0
|
|
113
|
+
if [[ "$TEST_FAILED" != "0" && "$TEST_FAILED" != "null" ]]; then
|
|
114
|
+
FAILURES="$FAILURES tests($TEST_FAILED failed)"
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
if [[ -n "$FAILURES" ]]; then
|
|
118
|
+
if [[ "$ENFORCE_MODE" == "ask" ]]; then
|
|
119
|
+
track_enforcement "quality_ask" "Failed:$FAILURES for $CURRENT_TODO" "verify-todo-completion"
|
|
120
|
+
cat <<EOF
|
|
121
|
+
{
|
|
122
|
+
"decision": "ask",
|
|
123
|
+
"reason": "Quality gates failed:$FAILURES. Continue anyway and mark TODO $CURRENT_TODO complete?"
|
|
124
|
+
}
|
|
125
|
+
EOF
|
|
126
|
+
else
|
|
127
|
+
track_enforcement "quality_block" "Failed:$FAILURES for $CURRENT_TODO" "verify-todo-completion"
|
|
128
|
+
cat <<EOF
|
|
129
|
+
{
|
|
130
|
+
"decision": "block",
|
|
131
|
+
"reason": "Quality gates failed:$FAILURES. Fix issues before completing TODO $CURRENT_TODO. Run 'pnpm quality' or check .codecruise/verification/ for details."
|
|
132
|
+
}
|
|
133
|
+
EOF
|
|
134
|
+
fi
|
|
135
|
+
exit 0
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
|
|
139
|
+
# All gates passed, allow stop
|
|
140
|
+
exit 0
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# Comments
|
|
2
|
+
|
|
3
|
+
Document WHY, not WHAT. Code shows what it does; comments explain why it matters.
|
|
4
|
+
|
|
5
|
+
## JSDoc: When Required
|
|
6
|
+
|
|
7
|
+
- Exported functions with non-obvious behavior
|
|
8
|
+
- Security/PII/money handling
|
|
9
|
+
- Module entry points (`index.ts`)
|
|
10
|
+
- Complex algorithms, edge cases
|
|
11
|
+
|
|
12
|
+
## JSDoc: Skip
|
|
13
|
+
|
|
14
|
+
- Obvious methods (`getUserById`)
|
|
15
|
+
- Types with clear property names
|
|
16
|
+
- Private helpers, simple getters
|
|
17
|
+
|
|
18
|
+
## Inline Comments
|
|
19
|
+
|
|
20
|
+
```typescript
|
|
21
|
+
// Design decision D-073: Using optimistic locking
|
|
22
|
+
// TODO(JIRA-123): Remove after v2.0 migration
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
Avoid: obvious comments, changelog, commented-out code, decorative boxes.
|