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,95 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# SessionStart hook - Loads relevant skills based on current TODO context
|
|
3
|
+
#
|
|
4
|
+
# P2: Context-aware skill loading
|
|
5
|
+
#
|
|
6
|
+
# Reads current TODO from progress.yaml, checks file patterns,
|
|
7
|
+
# and outputs relevant skill content to inject into Claude's context.
|
|
8
|
+
#
|
|
9
|
+
# Skill triggers:
|
|
10
|
+
# - .ts/.tsx files → TypeScript skill
|
|
11
|
+
# - React/Next.js patterns → Frontend skill
|
|
12
|
+
# - API/route files → Backend skill
|
|
13
|
+
# - Prisma/database files → Database skill
|
|
14
|
+
# - Test files → Testing skill
|
|
15
|
+
|
|
16
|
+
# Check if we're in a codecruise project
|
|
17
|
+
if [[ ! -f "progress.yaml" ]]; then
|
|
18
|
+
exit 0
|
|
19
|
+
fi
|
|
20
|
+
|
|
21
|
+
# Get current TODO
|
|
22
|
+
CURRENT_TODO=$(grep -A5 "current:" progress.yaml 2>/dev/null | grep "todo:" | sed 's/.*todo: //' | tr -d ' "' || echo "")
|
|
23
|
+
|
|
24
|
+
if [[ -z "$CURRENT_TODO" || "$CURRENT_TODO" == "null" ]]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Find the roadmap file containing this TODO
|
|
29
|
+
ROADMAP_FILE=$(grep -rl "id: $CURRENT_TODO" roadmap/ 2>/dev/null | head -1 || echo "")
|
|
30
|
+
|
|
31
|
+
if [[ -z "$ROADMAP_FILE" ]]; then
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
# Extract files from TODO
|
|
36
|
+
TODO_FILES=$(awk "/id: $CURRENT_TODO/,/^[[:space:]]*- id:/" "$ROADMAP_FILE" | grep -E "^\s+-\s+" | grep -v "id:" | sed 's/.*- //' || echo "")
|
|
37
|
+
|
|
38
|
+
# Determine which skills to load based on file patterns
|
|
39
|
+
SKILLS_TO_LOAD=""
|
|
40
|
+
|
|
41
|
+
# Check file patterns
|
|
42
|
+
for file in $TODO_FILES; do
|
|
43
|
+
# TypeScript
|
|
44
|
+
if [[ "$file" == *.ts || "$file" == *.tsx ]]; then
|
|
45
|
+
SKILLS_TO_LOAD="$SKILLS_TO_LOAD typescript"
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
# Frontend (React/Next.js)
|
|
49
|
+
if [[ "$file" == *"/components/"* || "$file" == *"/app/"* || "$file" == *"/pages/"* || "$file" == *.tsx ]]; then
|
|
50
|
+
SKILLS_TO_LOAD="$SKILLS_TO_LOAD frontend"
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
# Backend (API routes)
|
|
54
|
+
if [[ "$file" == *"/api/"* || "$file" == *"/routes/"* || "$file" == *"/server/"* || "$file" == *"/services/"* ]]; then
|
|
55
|
+
SKILLS_TO_LOAD="$SKILLS_TO_LOAD backend"
|
|
56
|
+
fi
|
|
57
|
+
|
|
58
|
+
# Database
|
|
59
|
+
if [[ "$file" == *"prisma"* || "$file" == *"/db/"* || "$file" == *"/database/"* || "$file" == *"/models/"* ]]; then
|
|
60
|
+
SKILLS_TO_LOAD="$SKILLS_TO_LOAD database"
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Testing
|
|
64
|
+
if [[ "$file" == *.test.* || "$file" == *.spec.* || "$file" == *"__tests__"* ]]; then
|
|
65
|
+
SKILLS_TO_LOAD="$SKILLS_TO_LOAD testing"
|
|
66
|
+
fi
|
|
67
|
+
done
|
|
68
|
+
|
|
69
|
+
# Remove duplicates
|
|
70
|
+
SKILLS_TO_LOAD=$(echo "$SKILLS_TO_LOAD" | tr ' ' '\n' | sort -u | tr '\n' ' ')
|
|
71
|
+
|
|
72
|
+
# Output loaded skills (this gets injected into Claude's context)
|
|
73
|
+
if [[ -n "$SKILLS_TO_LOAD" ]]; then
|
|
74
|
+
echo "=== Context Skills Loaded for TODO: $CURRENT_TODO ==="
|
|
75
|
+
echo ""
|
|
76
|
+
|
|
77
|
+
for skill in $SKILLS_TO_LOAD; do
|
|
78
|
+
SKILL_FILE="$HOME/.claude/skills/${skill}/patterns.md"
|
|
79
|
+
SKILL_FILE_ALT="$HOME/.claude/skills/${skill}.md"
|
|
80
|
+
|
|
81
|
+
if [[ -f "$SKILL_FILE" ]]; then
|
|
82
|
+
echo "--- $skill patterns ---"
|
|
83
|
+
head -100 "$SKILL_FILE" # First 100 lines to avoid context bloat
|
|
84
|
+
echo ""
|
|
85
|
+
elif [[ -f "$SKILL_FILE_ALT" ]]; then
|
|
86
|
+
echo "--- $skill patterns ---"
|
|
87
|
+
head -100 "$SKILL_FILE_ALT"
|
|
88
|
+
echo ""
|
|
89
|
+
fi
|
|
90
|
+
done
|
|
91
|
+
|
|
92
|
+
echo "=== End Context Skills ==="
|
|
93
|
+
fi
|
|
94
|
+
|
|
95
|
+
exit 0
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Sends notifications to configured channel
|
|
3
|
+
# Used by autonomous mode for blockers, completions, and alerts
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
EVENT_TYPE=$(echo "$INPUT" | jq -r '.event // "info"')
|
|
7
|
+
MESSAGE=$(echo "$INPUT" | jq -r '.message // "Notification from codecruise"')
|
|
8
|
+
TODO_ID=$(echo "$INPUT" | jq -r '.todo_id // empty')
|
|
9
|
+
CHANNEL=${PILOT_NOTIFY_CHANNEL:-none}
|
|
10
|
+
|
|
11
|
+
# Skip if no channel configured
|
|
12
|
+
if [[ "$CHANNEL" == "none" || -z "$CHANNEL" ]]; then
|
|
13
|
+
exit 0
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
# Build notification payload
|
|
17
|
+
EMOJI="ℹ️"
|
|
18
|
+
case "$EVENT_TYPE" in
|
|
19
|
+
blocker)
|
|
20
|
+
EMOJI="🚨"
|
|
21
|
+
;;
|
|
22
|
+
complete)
|
|
23
|
+
EMOJI="✅"
|
|
24
|
+
;;
|
|
25
|
+
error)
|
|
26
|
+
EMOJI="❌"
|
|
27
|
+
;;
|
|
28
|
+
warning)
|
|
29
|
+
EMOJI="⚠️"
|
|
30
|
+
;;
|
|
31
|
+
esac
|
|
32
|
+
|
|
33
|
+
PAYLOAD="$EMOJI PILOT: $MESSAGE"
|
|
34
|
+
if [[ -n "$TODO_ID" ]]; then
|
|
35
|
+
PAYLOAD="$PAYLOAD\n📍 TODO: $TODO_ID"
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
case "$CHANNEL" in
|
|
39
|
+
slack)
|
|
40
|
+
if [[ -z "$SLACK_WEBHOOK_URL" ]]; then
|
|
41
|
+
echo "Error: SLACK_WEBHOOK_URL not set" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
curl -s -X POST "$SLACK_WEBHOOK_URL" \
|
|
46
|
+
-H "Content-Type: application/json" \
|
|
47
|
+
-d "{\"text\": \"$PAYLOAD\"}" \
|
|
48
|
+
> /dev/null 2>&1
|
|
49
|
+
;;
|
|
50
|
+
|
|
51
|
+
webhook)
|
|
52
|
+
if [[ -z "$PILOT_WEBHOOK_URL" ]]; then
|
|
53
|
+
echo "Error: PILOT_WEBHOOK_URL not set" >&2
|
|
54
|
+
exit 1
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
curl -s -X POST "$PILOT_WEBHOOK_URL" \
|
|
58
|
+
-H "Content-Type: application/json" \
|
|
59
|
+
-d "{\"event\": \"$EVENT_TYPE\", \"message\": \"$MESSAGE\", \"todo_id\": \"$TODO_ID\", \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"}" \
|
|
60
|
+
> /dev/null 2>&1
|
|
61
|
+
;;
|
|
62
|
+
|
|
63
|
+
telegram)
|
|
64
|
+
if [[ -z "$TELEGRAM_BOT_TOKEN" || -z "$TELEGRAM_CHAT_ID" ]]; then
|
|
65
|
+
echo "Error: TELEGRAM_BOT_TOKEN or TELEGRAM_CHAT_ID not set" >&2
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
|
|
69
|
+
curl -s -X POST "https://api.telegram.org/bot$TELEGRAM_BOT_TOKEN/sendMessage" \
|
|
70
|
+
-H "Content-Type: application/json" \
|
|
71
|
+
-d "{\"chat_id\": \"$TELEGRAM_CHAT_ID\", \"text\": \"$PAYLOAD\", \"parse_mode\": \"HTML\"}" \
|
|
72
|
+
> /dev/null 2>&1
|
|
73
|
+
;;
|
|
74
|
+
|
|
75
|
+
*)
|
|
76
|
+
echo "Unknown notification channel: $CHANNEL" >&2
|
|
77
|
+
exit 1
|
|
78
|
+
;;
|
|
79
|
+
esac
|
|
80
|
+
|
|
81
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/sh
|
|
2
|
+
# Pre-commit hook - runs quality checks before allowing commit
|
|
3
|
+
#
|
|
4
|
+
# Installation:
|
|
5
|
+
# cp ~/.claude/hooks/pre-commit.sample .git/hooks/pre-commit
|
|
6
|
+
# chmod +x .git/hooks/pre-commit
|
|
7
|
+
#
|
|
8
|
+
# Or with Husky:
|
|
9
|
+
# npx husky add .husky/pre-commit "npm run check"
|
|
10
|
+
|
|
11
|
+
# Detect package manager and run quality command
|
|
12
|
+
if [ -f "package.json" ]; then
|
|
13
|
+
if [ -f "pnpm-lock.yaml" ]; then
|
|
14
|
+
pnpm run check || exit 1
|
|
15
|
+
elif [ -f "yarn.lock" ]; then
|
|
16
|
+
yarn check || exit 1
|
|
17
|
+
elif [ -f "bun.lockb" ]; then
|
|
18
|
+
bun run check || exit 1
|
|
19
|
+
else
|
|
20
|
+
npm run check || exit 1
|
|
21
|
+
fi
|
|
22
|
+
elif [ -f "pyproject.toml" ]; then
|
|
23
|
+
# Python projects
|
|
24
|
+
if command -v ruff &> /dev/null; then
|
|
25
|
+
ruff check . || exit 1
|
|
26
|
+
fi
|
|
27
|
+
if command -v mypy &> /dev/null; then
|
|
28
|
+
mypy . || exit 1
|
|
29
|
+
fi
|
|
30
|
+
if command -v pytest &> /dev/null; then
|
|
31
|
+
pytest --tb=short || exit 1
|
|
32
|
+
fi
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
echo "✓ Pre-commit checks passed"
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# PreToolUse hook - blocks modification of critical files
|
|
3
|
+
# Prevents accidental corruption of state, secrets, and lock files
|
|
4
|
+
|
|
5
|
+
INPUT=$(cat)
|
|
6
|
+
TOOL=$(echo "$INPUT" | jq -r '.tool_name // empty')
|
|
7
|
+
FILE=$(echo "$INPUT" | jq -r '.tool_input.file_path // empty')
|
|
8
|
+
|
|
9
|
+
# Skip if not a write operation
|
|
10
|
+
if [[ "$TOOL" != "Edit" && "$TOOL" != "Write" ]]; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
# Skip if no file path
|
|
15
|
+
if [[ -z "$FILE" ]]; then
|
|
16
|
+
exit 0
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Default protected patterns
|
|
20
|
+
PROTECTED=(
|
|
21
|
+
"progress.yaml"
|
|
22
|
+
"roadmap/"
|
|
23
|
+
".env"
|
|
24
|
+
".env.*"
|
|
25
|
+
"package-lock.json"
|
|
26
|
+
"pnpm-lock.yaml"
|
|
27
|
+
"yarn.lock"
|
|
28
|
+
"Gemfile.lock"
|
|
29
|
+
"poetry.lock"
|
|
30
|
+
"Cargo.lock"
|
|
31
|
+
".git/"
|
|
32
|
+
".ssh/"
|
|
33
|
+
".aws/"
|
|
34
|
+
".gnupg/"
|
|
35
|
+
"credentials"
|
|
36
|
+
"secrets"
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
# Add custom patterns from environment
|
|
40
|
+
if [[ -n "$PILOT_PROTECTED_FILES" ]]; then
|
|
41
|
+
IFS=',' read -ra CUSTOM <<< "$PILOT_PROTECTED_FILES"
|
|
42
|
+
PROTECTED+=("${CUSTOM[@]}")
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
# Check if file matches any protected pattern
|
|
46
|
+
for pattern in "${PROTECTED[@]}"; do
|
|
47
|
+
# Handle glob patterns
|
|
48
|
+
if [[ "$FILE" == *"$pattern"* ]]; then
|
|
49
|
+
cat <<EOF
|
|
50
|
+
{
|
|
51
|
+
"hookSpecificOutput": {
|
|
52
|
+
"hookEventName": "PreToolUse",
|
|
53
|
+
"permissionDecision": "deny",
|
|
54
|
+
"permissionDecisionReason": "Cannot modify protected file matching pattern: $pattern. Use dedicated commands (/run, /found) or edit config/hooks/protect-files.sh to adjust."
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
EOF
|
|
58
|
+
exit 0
|
|
59
|
+
fi
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# Allow the operation
|
|
63
|
+
exit 0
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# track-agents.sh — PostToolUse hook for tracking agent delegations
|
|
3
|
+
#
|
|
4
|
+
# Logs when Task tool is used to spawn subagents
|
|
5
|
+
# Answers: "Which of the 12 agents actually get used?"
|
|
6
|
+
#
|
|
7
|
+
# Writes to .codecruise/metrics/agents.jsonl
|
|
8
|
+
|
|
9
|
+
AGENTS_LOG="${CODECRUISE_AGENTS_LOG:-.codecruise/metrics/agents.jsonl}"
|
|
10
|
+
|
|
11
|
+
mkdir -p "$(dirname "$AGENTS_LOG")"
|
|
12
|
+
|
|
13
|
+
INPUT=$(cat)
|
|
14
|
+
|
|
15
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
|
|
16
|
+
|
|
17
|
+
# Only track Task tool usage (agent delegation)
|
|
18
|
+
if [[ "$TOOL_NAME" != "Task" ]]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
23
|
+
PROJECT=$(basename "$PWD")
|
|
24
|
+
|
|
25
|
+
# Extract agent info from tool input
|
|
26
|
+
SUBAGENT_TYPE=$(echo "$INPUT" | jq -r '.tool_input.subagent_type // "unknown"')
|
|
27
|
+
DESCRIPTION=$(echo "$INPUT" | jq -r '.tool_input.description // ""' | cut -c1-100)
|
|
28
|
+
MODEL=$(echo "$INPUT" | jq -r '.tool_input.model // "default"')
|
|
29
|
+
|
|
30
|
+
# Get current TODO if available
|
|
31
|
+
CURRENT_TODO=""
|
|
32
|
+
if [[ -f "progress.yaml" ]]; then
|
|
33
|
+
CURRENT_TODO=$(grep -oE "todo-[0-9]+\.[0-9]+[a-z]?-[0-9]+" progress.yaml 2>/dev/null | head -1 || echo "")
|
|
34
|
+
fi
|
|
35
|
+
|
|
36
|
+
# Escape description for JSON
|
|
37
|
+
ESCAPED_DESC=$(echo "$DESCRIPTION" | sed 's/"/\\"/g')
|
|
38
|
+
|
|
39
|
+
echo "{\"timestamp\":\"$TIMESTAMP\",\"project\":\"$PROJECT\",\"agent\":\"$SUBAGENT_TYPE\",\"model\":\"$MODEL\",\"todo\":\"$CURRENT_TODO\",\"description\":\"$ESCAPED_DESC\"}" >> "$AGENTS_LOG"
|
|
40
|
+
|
|
41
|
+
exit 0
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# track-commands.sh — Tracks which codecruise commands are actually used
|
|
3
|
+
#
|
|
4
|
+
# PostToolUse hook that detects Skill tool invocations
|
|
5
|
+
# Answers: "Which of the 34 commands actually get used?"
|
|
6
|
+
#
|
|
7
|
+
# Writes to .codecruise/metrics/commands.jsonl
|
|
8
|
+
|
|
9
|
+
COMMANDS_LOG="${CODECRUISE_COMMANDS_LOG:-.codecruise/metrics/commands.jsonl}"
|
|
10
|
+
|
|
11
|
+
mkdir -p "$(dirname "$COMMANDS_LOG")"
|
|
12
|
+
|
|
13
|
+
INPUT=$(cat)
|
|
14
|
+
|
|
15
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
|
|
16
|
+
|
|
17
|
+
# Only track Skill tool usage (command invocation)
|
|
18
|
+
if [[ "$TOOL_NAME" != "Skill" ]]; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
23
|
+
PROJECT=$(basename "$PWD")
|
|
24
|
+
|
|
25
|
+
# Extract command info
|
|
26
|
+
SKILL_NAME=$(echo "$INPUT" | jq -r '.tool_input.skill // "unknown"')
|
|
27
|
+
ARGS=$(echo "$INPUT" | jq -r '.tool_input.args // ""' | cut -c1-50)
|
|
28
|
+
|
|
29
|
+
# Get current TODO if available
|
|
30
|
+
CURRENT_TODO=""
|
|
31
|
+
if [[ -f "progress.yaml" ]]; then
|
|
32
|
+
CURRENT_TODO=$(grep -oE "todo-[0-9]+\.[0-9]+[a-z]?-[0-9]+" progress.yaml 2>/dev/null | head -1 || echo "")
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
echo "{\"timestamp\":\"$TIMESTAMP\",\"project\":\"$PROJECT\",\"command\":\"$SKILL_NAME\",\"args\":\"$ARGS\",\"todo\":\"$CURRENT_TODO\"}" >> "$COMMANDS_LOG"
|
|
36
|
+
|
|
37
|
+
exit 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# track-enforcement.sh — Logs enforcement events for dogfooding analysis
|
|
3
|
+
#
|
|
4
|
+
# Called by other hooks when they block or warn
|
|
5
|
+
# Writes to .codecruise/metrics/enforcement.jsonl
|
|
6
|
+
#
|
|
7
|
+
# Usage (from other hooks):
|
|
8
|
+
# source "$(dirname "$0")/track-enforcement.sh"
|
|
9
|
+
# track_enforcement "tdd_block" "No test file for src/auth.ts"
|
|
10
|
+
# track_enforcement "rationalization_caught" "detected: 'good enough for now'"
|
|
11
|
+
# track_enforcement "state_invalid" "pending -> done not allowed"
|
|
12
|
+
# track_enforcement "quality_block" "tests failed, cannot mark done"
|
|
13
|
+
|
|
14
|
+
ENFORCEMENT_LOG="${CODECRUISE_ENFORCEMENT_LOG:-.codecruise/metrics/enforcement.jsonl}"
|
|
15
|
+
|
|
16
|
+
track_enforcement() {
|
|
17
|
+
local event_type="$1"
|
|
18
|
+
local detail="$2"
|
|
19
|
+
local hook_name="${3:-unknown}"
|
|
20
|
+
|
|
21
|
+
mkdir -p "$(dirname "$ENFORCEMENT_LOG")"
|
|
22
|
+
|
|
23
|
+
local timestamp
|
|
24
|
+
timestamp=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
25
|
+
|
|
26
|
+
# Get current TODO if available
|
|
27
|
+
local current_todo=""
|
|
28
|
+
if [[ -f "progress.yaml" ]]; then
|
|
29
|
+
current_todo=$(grep -oE "todo-[0-9]+\.[0-9]+[a-z]?-[0-9]+" progress.yaml 2>/dev/null | head -1 || echo "")
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
# Get project name from directory
|
|
33
|
+
local project
|
|
34
|
+
project=$(basename "$PWD")
|
|
35
|
+
|
|
36
|
+
# Escape detail for JSON
|
|
37
|
+
local escaped_detail
|
|
38
|
+
escaped_detail=$(echo "$detail" | sed 's/"/\\"/g' | tr '\n' ' ')
|
|
39
|
+
|
|
40
|
+
echo "{\"timestamp\":\"$timestamp\",\"project\":\"$project\",\"event\":\"$event_type\",\"hook\":\"$hook_name\",\"todo\":\"$current_todo\",\"detail\":\"$escaped_detail\"}" >> "$ENFORCEMENT_LOG"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
# Export function for sourcing
|
|
44
|
+
export -f track_enforcement 2>/dev/null || true
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# track-ooda.sh — Tracks OODA loop phases and decisions
|
|
3
|
+
#
|
|
4
|
+
# PostToolUse hook that detects OODA-related patterns in tool results
|
|
5
|
+
# Answers: "Is OODA's ORIENT phase actually calculating meaningful confidence?"
|
|
6
|
+
#
|
|
7
|
+
# Detects patterns like:
|
|
8
|
+
# - "OBSERVE:" / "ORIENT:" / "DECIDE:" / "ACT:" in outputs
|
|
9
|
+
# - Confidence levels mentioned
|
|
10
|
+
# - Decisions made (execute, skip, replan, escalate)
|
|
11
|
+
#
|
|
12
|
+
# Writes to .codecruise/metrics/ooda.jsonl
|
|
13
|
+
|
|
14
|
+
OODA_LOG="${CODECRUISE_OODA_LOG:-.codecruise/metrics/ooda.jsonl}"
|
|
15
|
+
|
|
16
|
+
mkdir -p "$(dirname "$OODA_LOG")"
|
|
17
|
+
|
|
18
|
+
INPUT=$(cat)
|
|
19
|
+
|
|
20
|
+
TOOL_NAME=$(echo "$INPUT" | jq -r '.tool_name // empty')
|
|
21
|
+
TOOL_RESULT=$(echo "$INPUT" | jq -r '.tool_result // empty' 2>/dev/null || echo "")
|
|
22
|
+
|
|
23
|
+
# Skip if no result to analyze
|
|
24
|
+
if [[ -z "$TOOL_RESULT" ]]; then
|
|
25
|
+
exit 0
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
TIMESTAMP=$(date -u +%Y-%m-%dT%H:%M:%SZ)
|
|
29
|
+
PROJECT=$(basename "$PWD")
|
|
30
|
+
|
|
31
|
+
# Get current TODO
|
|
32
|
+
CURRENT_TODO=""
|
|
33
|
+
if [[ -f "progress.yaml" ]]; then
|
|
34
|
+
CURRENT_TODO=$(grep -oE "todo-[0-9]+\.[0-9]+[a-z]?-[0-9]+" progress.yaml 2>/dev/null | head -1 || echo "")
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Detect OODA phases in output
|
|
38
|
+
PHASE=""
|
|
39
|
+
if echo "$TOOL_RESULT" | grep -qiE "OBSERVE:"; then
|
|
40
|
+
PHASE="observe"
|
|
41
|
+
elif echo "$TOOL_RESULT" | grep -qiE "ORIENT:"; then
|
|
42
|
+
PHASE="orient"
|
|
43
|
+
elif echo "$TOOL_RESULT" | grep -qiE "DECIDE:"; then
|
|
44
|
+
PHASE="decide"
|
|
45
|
+
elif echo "$TOOL_RESULT" | grep -qiE "ACT:"; then
|
|
46
|
+
PHASE="act"
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Skip if no OODA phase detected
|
|
50
|
+
if [[ -z "$PHASE" ]]; then
|
|
51
|
+
exit 0
|
|
52
|
+
fi
|
|
53
|
+
|
|
54
|
+
# Extract confidence if in ORIENT phase
|
|
55
|
+
CONFIDENCE=""
|
|
56
|
+
if [[ "$PHASE" == "orient" ]]; then
|
|
57
|
+
CONFIDENCE=$(echo "$TOOL_RESULT" | grep -oiE "confidence[=: ]*(high|medium|low|[0-9.]+)" | head -1 | sed 's/.*[=: ]//')
|
|
58
|
+
fi
|
|
59
|
+
|
|
60
|
+
# Extract decision if in DECIDE phase
|
|
61
|
+
DECISION=""
|
|
62
|
+
if [[ "$PHASE" == "decide" ]]; then
|
|
63
|
+
if echo "$TOOL_RESULT" | grep -qiE "execute"; then
|
|
64
|
+
DECISION="execute"
|
|
65
|
+
elif echo "$TOOL_RESULT" | grep -qiE "skip"; then
|
|
66
|
+
DECISION="skip"
|
|
67
|
+
elif echo "$TOOL_RESULT" | grep -qiE "replan"; then
|
|
68
|
+
DECISION="replan"
|
|
69
|
+
elif echo "$TOOL_RESULT" | grep -qiE "escalate"; then
|
|
70
|
+
DECISION="escalate"
|
|
71
|
+
fi
|
|
72
|
+
fi
|
|
73
|
+
|
|
74
|
+
# Log the event
|
|
75
|
+
echo "{\"timestamp\":\"$TIMESTAMP\",\"project\":\"$PROJECT\",\"todo\":\"$CURRENT_TODO\",\"phase\":\"$PHASE\",\"confidence\":\"$CONFIDENCE\",\"decision\":\"$DECISION\"}" >> "$OODA_LOG"
|
|
76
|
+
|
|
77
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Validates commit message follows conventional commit format
|
|
3
|
+
# Used by PreToolUse hook for git commit commands
|
|
4
|
+
#
|
|
5
|
+
# Format: type(scope): description
|
|
6
|
+
# Types: feat, fix, docs, style, refactor, test, chore
|
|
7
|
+
#
|
|
8
|
+
# Exit codes:
|
|
9
|
+
# 0 - Valid commit message
|
|
10
|
+
# 2 - Invalid (blocks the tool)
|
|
11
|
+
|
|
12
|
+
MSG="$1"
|
|
13
|
+
|
|
14
|
+
# Pattern: type(optional-scope): description (max 50 chars for description)
|
|
15
|
+
PATTERN='^(feat|fix|docs|style|refactor|test|chore)(\([a-z0-9_-]+\))?: .{1,50}$'
|
|
16
|
+
|
|
17
|
+
if [[ -z "$MSG" ]]; then
|
|
18
|
+
# No message provided, let git handle it
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
if [[ ! "$MSG" =~ $PATTERN ]]; then
|
|
23
|
+
echo "Blocked: Commit message must follow conventional format" >&2
|
|
24
|
+
echo "" >&2
|
|
25
|
+
echo "Format: type(scope): description" >&2
|
|
26
|
+
echo "Types: feat, fix, docs, style, refactor, test, chore" >&2
|
|
27
|
+
echo "" >&2
|
|
28
|
+
echo "Examples:" >&2
|
|
29
|
+
echo " feat(auth): add password reset flow" >&2
|
|
30
|
+
echo " fix(cart): resolve quantity update bug" >&2
|
|
31
|
+
echo " docs: update README installation steps" >&2
|
|
32
|
+
exit 2
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
exit 0
|