@kennethsolomon/shipkit 3.7.0 → 3.9.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/README.md +181 -257
- package/package.json +1 -1
- package/skills/sk:fast-track/SKILL.md +80 -0
- package/skills/sk:gates/SKILL.md +97 -0
- package/skills/sk:retro/SKILL.md +124 -0
- package/skills/sk:reverse-doc/SKILL.md +116 -0
- package/skills/sk:scope-check/SKILL.md +93 -0
- package/skills/sk:setup-claude/SKILL.md +55 -0
- package/skills/sk:setup-claude/scripts/apply_setup_claude.py +207 -6
- package/skills/sk:setup-claude/templates/.claude/agents/e2e-tester.md +46 -0
- package/skills/sk:setup-claude/templates/.claude/agents/linter.md +53 -0
- package/skills/sk:setup-claude/templates/.claude/agents/perf-auditor.md +43 -0
- package/skills/sk:setup-claude/templates/.claude/agents/security-auditor.md +47 -0
- package/skills/sk:setup-claude/templates/.claude/agents/test-runner.md +42 -0
- package/skills/sk:setup-claude/templates/.claude/rules/api.md.template +14 -0
- package/skills/sk:setup-claude/templates/.claude/rules/frontend.md.template +15 -0
- package/skills/sk:setup-claude/templates/.claude/rules/laravel.md.template +15 -0
- package/skills/sk:setup-claude/templates/.claude/rules/react.md.template +14 -0
- package/skills/sk:setup-claude/templates/.claude/rules/tests.md.template +16 -0
- package/skills/sk:setup-claude/templates/.claude/settings.json.template +76 -0
- package/skills/sk:setup-claude/templates/.claude/statusline.sh +50 -0
- package/skills/sk:setup-claude/templates/CLAUDE.md.template +18 -1
- package/skills/sk:setup-claude/templates/hooks/log-agent.sh +24 -0
- package/skills/sk:setup-claude/templates/hooks/pre-compact.sh +44 -0
- package/skills/sk:setup-claude/templates/hooks/session-start.sh +53 -0
- package/skills/sk:setup-claude/templates/hooks/session-stop.sh +33 -0
- package/skills/sk:setup-claude/templates/hooks/validate-commit.sh +81 -0
- package/skills/sk:setup-claude/templates/hooks/validate-push.sh +43 -0
- package/skills/sk:setup-claude/templates/tasks/cross-platform.md.template +31 -0
- package/skills/sk:setup-optimizer/SKILL.md +2 -1
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code statusline: Shows persistent status in CLI
|
|
3
|
+
# Receives JSON on stdin with context_window, model info
|
|
4
|
+
# Outputs a single formatted line
|
|
5
|
+
|
|
6
|
+
INPUT=$(cat)
|
|
7
|
+
|
|
8
|
+
# Parse context and model — use jq if available
|
|
9
|
+
if command -v jq >/dev/null 2>&1; then
|
|
10
|
+
MODEL=$(echo "$INPUT" | jq -r '.model // "unknown"' 2>/dev/null)
|
|
11
|
+
CTX_USED=$(echo "$INPUT" | jq -r '.context_window.used // 0' 2>/dev/null)
|
|
12
|
+
CTX_TOTAL=$(echo "$INPUT" | jq -r '.context_window.total // 1' 2>/dev/null)
|
|
13
|
+
else
|
|
14
|
+
MODEL="unknown"
|
|
15
|
+
CTX_USED=0
|
|
16
|
+
CTX_TOTAL=1
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# Calculate context percentage
|
|
20
|
+
if [ "$CTX_TOTAL" -gt 0 ] 2>/dev/null; then
|
|
21
|
+
CTX_PCT=$((CTX_USED * 100 / CTX_TOTAL))
|
|
22
|
+
else
|
|
23
|
+
CTX_PCT=0
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
# Branch
|
|
27
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "none")
|
|
28
|
+
|
|
29
|
+
# Current workflow step
|
|
30
|
+
STEP="—"
|
|
31
|
+
if [ -f "tasks/workflow-status.md" ]; then
|
|
32
|
+
NEXT_LINE=$(grep -E ">>\s*next\s*<<" "tasks/workflow-status.md" 2>/dev/null | head -1)
|
|
33
|
+
if [ -n "$NEXT_LINE" ]; then
|
|
34
|
+
# Extract step number and name from table row
|
|
35
|
+
STEP_NUM=$(echo "$NEXT_LINE" | grep -oE '^\|[[:space:]]*[0-9]+' | grep -oE '[0-9]+')
|
|
36
|
+
STEP_NAME=$(echo "$NEXT_LINE" | sed 's/.*| *>> next << *|.*//' | sed 's/|.*//;s/^ *//;s/ *$//')
|
|
37
|
+
if [ -n "$STEP_NUM" ]; then
|
|
38
|
+
STEP="Step ${STEP_NUM}"
|
|
39
|
+
fi
|
|
40
|
+
fi
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
# Task name from todo.md
|
|
44
|
+
TASK="—"
|
|
45
|
+
if [ -f "tasks/todo.md" ]; then
|
|
46
|
+
TASK=$(head -1 "tasks/todo.md" 2>/dev/null | sed 's/^# TODO.*— //' | cut -c1-40)
|
|
47
|
+
fi
|
|
48
|
+
|
|
49
|
+
# Output single line
|
|
50
|
+
echo "[${CTX_PCT}%] ${MODEL} | ${STEP} | ${BRANCH} | ${TASK}"
|
|
@@ -272,6 +272,21 @@ Use `run_in_background: true` for tasks that don't block your next step:
|
|
|
272
272
|
```
|
|
273
273
|
<!-- END:sub-agent-patterns -->
|
|
274
274
|
|
|
275
|
+
## Cross-Platform Tracking
|
|
276
|
+
|
|
277
|
+
This project may have a companion codebase (web <-> mobile). During implementation, **log every change that affects the other platform** to `tasks/cross-platform.md`.
|
|
278
|
+
|
|
279
|
+
**When to log:**
|
|
280
|
+
- API contract changes (new/modified endpoints, payload shapes, auth)
|
|
281
|
+
- Data model changes (new fields, type changes, validation rules)
|
|
282
|
+
- Business logic that must behave identically on both platforms
|
|
283
|
+
- UI/UX flows that should have parity
|
|
284
|
+
- Platform-specific deviations (intentional differences)
|
|
285
|
+
|
|
286
|
+
**How to log:** Append a new section using the template in `tasks/cross-platform.md`. Include enough context that a developer in the other codebase can implement without guessing.
|
|
287
|
+
|
|
288
|
+
**When to review:** At the start of every task, check `tasks/cross-platform.md` for pending items targeting this codebase.
|
|
289
|
+
|
|
275
290
|
## Project Memory
|
|
276
291
|
|
|
277
292
|
Read these files at the start of every task:
|
|
@@ -279,12 +294,14 @@ Read these files at the start of every task:
|
|
|
279
294
|
- `tasks/lessons.md` — past mistakes and how to avoid them
|
|
280
295
|
- `tasks/todo.md` — current plan
|
|
281
296
|
- `tasks/tech-debt.md` — known shortcuts, deferred work, and areas to revisit
|
|
297
|
+
- `tasks/cross-platform.md` — pending changes from the other codebase
|
|
282
298
|
|
|
283
299
|
Write to these files continuously:
|
|
284
300
|
- `tasks/progress.md` — every attempt, error, and resolution
|
|
285
301
|
- `tasks/findings.md` — anything important discovered mid-task
|
|
302
|
+
- `tasks/cross-platform.md` — any change that impacts the other platform
|
|
286
303
|
|
|
287
|
-
**Never overwrite** `tasks/lessons.md` or `tasks/
|
|
304
|
+
**Never overwrite** `tasks/lessons.md`, `tasks/security-findings.md`, or `tasks/cross-platform.md`.
|
|
288
305
|
|
|
289
306
|
## Lessons Capture
|
|
290
307
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code SubagentStart hook: Log agent invocations for audit trail
|
|
3
|
+
# Tracks which agents are being used and when
|
|
4
|
+
#
|
|
5
|
+
# Input schema (SubagentStart):
|
|
6
|
+
# { "agent_id": "agent-abc123", "agent_name": "linter", ... }
|
|
7
|
+
|
|
8
|
+
INPUT=$(cat)
|
|
9
|
+
|
|
10
|
+
# Parse agent name
|
|
11
|
+
if command -v jq >/dev/null 2>&1; then
|
|
12
|
+
AGENT_NAME=$(echo "$INPUT" | jq -r '.agent_name // "unknown"' 2>/dev/null)
|
|
13
|
+
else
|
|
14
|
+
AGENT_NAME=$(echo "$INPUT" | grep -oE '"agent_name"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/"agent_name"[[:space:]]*:[[:space:]]*"//;s/"$//')
|
|
15
|
+
[ -z "$AGENT_NAME" ] && AGENT_NAME="unknown"
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
TIMESTAMP=$(date +%Y%m%d_%H%M%S)
|
|
19
|
+
|
|
20
|
+
# Append to audit log (create tasks/ dir if needed)
|
|
21
|
+
mkdir -p tasks 2>/dev/null
|
|
22
|
+
echo "$TIMESTAMP | Agent invoked: $AGENT_NAME" >> "tasks/agent-audit.log" 2>/dev/null
|
|
23
|
+
|
|
24
|
+
exit 0
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code PreCompact hook: Preserve session state before context compression
|
|
3
|
+
# Outputs critical state so Claude retains it after compaction
|
|
4
|
+
|
|
5
|
+
echo "=== Pre-Compaction State Snapshot ==="
|
|
6
|
+
|
|
7
|
+
# Workflow status
|
|
8
|
+
if [ -f "tasks/workflow-status.md" ]; then
|
|
9
|
+
echo ""
|
|
10
|
+
echo "--- workflow-status.md ---"
|
|
11
|
+
cat "tasks/workflow-status.md" 2>/dev/null | head -30
|
|
12
|
+
TOTAL_LINES=$(wc -l < "tasks/workflow-status.md" 2>/dev/null | tr -d ' ')
|
|
13
|
+
if [ "$TOTAL_LINES" -gt 30 ]; then
|
|
14
|
+
echo " ... ($TOTAL_LINES total lines)"
|
|
15
|
+
fi
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Git status
|
|
19
|
+
echo ""
|
|
20
|
+
echo "--- Uncommitted Changes ---"
|
|
21
|
+
STAGED=$(git diff --cached --name-only 2>/dev/null)
|
|
22
|
+
UNSTAGED=$(git diff --name-only 2>/dev/null)
|
|
23
|
+
UNTRACKED=$(git ls-files --others --exclude-standard 2>/dev/null)
|
|
24
|
+
|
|
25
|
+
[ -n "$STAGED" ] && echo "Staged:" && echo "$STAGED" | sed 's/^/ /'
|
|
26
|
+
[ -n "$UNSTAGED" ] && echo "Unstaged:" && echo "$UNSTAGED" | sed 's/^/ /'
|
|
27
|
+
[ -n "$UNTRACKED" ] && echo "Untracked:" && echo "$UNTRACKED" | sed 's/^/ /'
|
|
28
|
+
|
|
29
|
+
if [ -z "$STAGED" ] && [ -z "$UNSTAGED" ] && [ -z "$UNTRACKED" ]; then
|
|
30
|
+
echo " (clean)"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
# Log compaction event
|
|
34
|
+
if [ -d "tasks" ]; then
|
|
35
|
+
echo "" >> "tasks/progress.md" 2>/dev/null
|
|
36
|
+
echo "### [$(date +%Y-%m-%d)] Context compaction occurred at $(date +%H:%M:%S)" >> "tasks/progress.md" 2>/dev/null
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
echo ""
|
|
40
|
+
echo "--- Recovery ---"
|
|
41
|
+
echo "Read tasks/workflow-status.md to restore current step."
|
|
42
|
+
echo "Read tasks/progress.md for recent work."
|
|
43
|
+
echo "==================================="
|
|
44
|
+
exit 0
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code SessionStart hook: Load project context at session start
|
|
3
|
+
# Outputs context that Claude sees when a session begins
|
|
4
|
+
|
|
5
|
+
echo "=== ShipKit — Session Context ==="
|
|
6
|
+
|
|
7
|
+
# Current branch
|
|
8
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
|
|
9
|
+
if [ -n "$BRANCH" ]; then
|
|
10
|
+
echo "Branch: $BRANCH"
|
|
11
|
+
echo ""
|
|
12
|
+
echo "Recent commits:"
|
|
13
|
+
git log --oneline -5 2>/dev/null | while read -r line; do
|
|
14
|
+
echo " $line"
|
|
15
|
+
done
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
# Current workflow step from workflow-status.md
|
|
19
|
+
if [ -f "tasks/workflow-status.md" ]; then
|
|
20
|
+
echo ""
|
|
21
|
+
NEXT_STEP=$(grep -E ">>\s*next\s*<<" "tasks/workflow-status.md" 2>/dev/null | head -1)
|
|
22
|
+
if [ -n "$NEXT_STEP" ]; then
|
|
23
|
+
echo "Workflow: $NEXT_STEP"
|
|
24
|
+
else
|
|
25
|
+
echo "Workflow: all steps complete or not started"
|
|
26
|
+
fi
|
|
27
|
+
fi
|
|
28
|
+
|
|
29
|
+
# Tech debt count
|
|
30
|
+
if [ -f "tasks/tech-debt.md" ]; then
|
|
31
|
+
TOTAL=$(grep -c "^### \[" "tasks/tech-debt.md" 2>/dev/null || echo 0)
|
|
32
|
+
RESOLVED=$(grep -c "^Resolved:" "tasks/tech-debt.md" 2>/dev/null || echo 0)
|
|
33
|
+
UNRESOLVED=$((TOTAL - RESOLVED))
|
|
34
|
+
if [ "$UNRESOLVED" -gt 0 ]; then
|
|
35
|
+
echo "Tech Debt: $UNRESOLVED unresolved item(s)"
|
|
36
|
+
fi
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
# Code health (skip on large codebases to keep session start fast)
|
|
40
|
+
if [ -d "src" ]; then
|
|
41
|
+
FILE_COUNT=$(find src/ -type f 2>/dev/null | head -1001 | wc -l | tr -d ' ')
|
|
42
|
+
if [ "$FILE_COUNT" -le 1000 ]; then
|
|
43
|
+
TODO_COUNT=$(grep -r "TODO" src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
44
|
+
FIXME_COUNT=$(grep -r "FIXME" src/ 2>/dev/null | wc -l | tr -d ' ')
|
|
45
|
+
if [ "$TODO_COUNT" -gt 0 ] || [ "$FIXME_COUNT" -gt 0 ]; then
|
|
46
|
+
echo ""
|
|
47
|
+
echo "Code health: ${TODO_COUNT} TODOs, ${FIXME_COUNT} FIXMEs in src/"
|
|
48
|
+
fi
|
|
49
|
+
fi
|
|
50
|
+
fi
|
|
51
|
+
|
|
52
|
+
echo "==================================="
|
|
53
|
+
exit 0
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code Stop hook: Log session accomplishments
|
|
3
|
+
# Runs when a Claude Code session ends
|
|
4
|
+
|
|
5
|
+
# Only log if tasks/ directory exists (ShipKit project)
|
|
6
|
+
if [ ! -d "tasks" ]; then
|
|
7
|
+
exit 0
|
|
8
|
+
fi
|
|
9
|
+
|
|
10
|
+
TIMESTAMP=$(date +%Y-%m-%d\ %H:%M:%S)
|
|
11
|
+
|
|
12
|
+
# Get current branch
|
|
13
|
+
BRANCH=$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo "unknown")
|
|
14
|
+
|
|
15
|
+
# Count commits in this session (last hour)
|
|
16
|
+
RECENT_COMMITS=$(git log --since="1 hour ago" --oneline 2>/dev/null | wc -l | tr -d ' ')
|
|
17
|
+
|
|
18
|
+
# Get current workflow step
|
|
19
|
+
CURRENT_STEP=""
|
|
20
|
+
if [ -f "tasks/workflow-status.md" ]; then
|
|
21
|
+
CURRENT_STEP=$(grep -E ">>\s*next\s*<<" "tasks/workflow-status.md" 2>/dev/null | head -1 | sed 's/.*| //' | sed 's/ |.*//')
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# Append session end to progress.md
|
|
25
|
+
{
|
|
26
|
+
echo ""
|
|
27
|
+
echo "### [$TIMESTAMP] Session ended"
|
|
28
|
+
echo "- Branch: $BRANCH"
|
|
29
|
+
echo "- Commits this session: $RECENT_COMMITS"
|
|
30
|
+
[ -n "$CURRENT_STEP" ] && echo "- Next step: $CURRENT_STEP"
|
|
31
|
+
} >> "tasks/progress.md" 2>/dev/null
|
|
32
|
+
|
|
33
|
+
exit 0
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code PreToolUse hook: Validates git commit commands
|
|
3
|
+
# Receives JSON on stdin with tool_input.command
|
|
4
|
+
# Exit 0 = allow, Exit 2 = block (stderr shown to Claude)
|
|
5
|
+
#
|
|
6
|
+
# Validates: conventional commit format, debug statements, hardcoded secrets
|
|
7
|
+
|
|
8
|
+
INPUT=$(cat)
|
|
9
|
+
|
|
10
|
+
# Parse command — use jq if available, fall back to grep
|
|
11
|
+
if command -v jq >/dev/null 2>&1; then
|
|
12
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
|
|
13
|
+
else
|
|
14
|
+
COMMAND=$(echo "$INPUT" | grep -oE '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/"command"[[:space:]]*:[[:space:]]*"//;s/"$//')
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Only process git commit commands
|
|
18
|
+
if ! echo "$COMMAND" | grep -qE '^git[[:space:]]+commit'; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
WARNINGS=""
|
|
23
|
+
|
|
24
|
+
# Extract commit message from -m flag
|
|
25
|
+
COMMIT_MSG=$(echo "$COMMAND" | grep -oE '\-m[[:space:]]+"[^"]*"' | sed 's/-m[[:space:]]*"//;s/"$//' || echo "")
|
|
26
|
+
if [ -z "$COMMIT_MSG" ]; then
|
|
27
|
+
COMMIT_MSG=$(echo "$COMMAND" | grep -oE "\-m[[:space:]]+'[^']*'" | sed "s/-m[[:space:]]*'//;s/'$//" || echo "")
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
# Validate conventional commit format (type(scope): message or type: message)
|
|
31
|
+
if [ -n "$COMMIT_MSG" ]; then
|
|
32
|
+
if ! echo "$COMMIT_MSG" | grep -qE '^(feat|fix|docs|refactor|chore|test|style|perf|ci|build|revert)(\([a-zA-Z0-9_-]+\))?(!)?:[[:space:]].+'; then
|
|
33
|
+
WARNINGS="$WARNINGS\nCOMMIT: Message does not follow conventional commit format: type(scope): message"
|
|
34
|
+
fi
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Check staged files for debug statements and secrets
|
|
38
|
+
STAGED=$(git diff --cached --name-only 2>/dev/null)
|
|
39
|
+
if [ -n "$STAGED" ]; then
|
|
40
|
+
# Read full staged diff once (avoids repeated git subprocess calls per file)
|
|
41
|
+
FULL_DIFF=$(git diff --cached 2>/dev/null)
|
|
42
|
+
|
|
43
|
+
while IFS= read -r file; do
|
|
44
|
+
if [ -f "$file" ]; then
|
|
45
|
+
FILE_DIFF=$(echo "$FULL_DIFF" | sed -n "/^diff --git a\/$file /,/^diff --git /p")
|
|
46
|
+
# JavaScript/TypeScript debug
|
|
47
|
+
if echo "$file" | grep -qE '\.(js|ts|jsx|tsx)$'; then
|
|
48
|
+
if echo "$FILE_DIFF" | grep -E '^\+.*console\.(log|debug|warn)\(' | grep -qv '//.*console'; then
|
|
49
|
+
WARNINGS="$WARNINGS\nDEBUG: $file has console.log/debug/warn in staged changes"
|
|
50
|
+
fi
|
|
51
|
+
if echo "$FILE_DIFF" | grep -qE '^\+.*debugger'; then
|
|
52
|
+
WARNINGS="$WARNINGS\nDEBUG: $file has debugger statement in staged changes"
|
|
53
|
+
fi
|
|
54
|
+
fi
|
|
55
|
+
# PHP debug
|
|
56
|
+
if echo "$file" | grep -qE '\.php$'; then
|
|
57
|
+
if echo "$FILE_DIFF" | grep -qE '^\+.*(dd\(|dump\(|var_dump\(|print_r\()'; then
|
|
58
|
+
WARNINGS="$WARNINGS\nDEBUG: $file has dd/dump/var_dump in staged changes"
|
|
59
|
+
fi
|
|
60
|
+
fi
|
|
61
|
+
# Python debug
|
|
62
|
+
if echo "$file" | grep -qE '\.py$'; then
|
|
63
|
+
if echo "$FILE_DIFF" | grep -qE '^\+.*(breakpoint\(\)|pdb\.set_trace\(\))'; then
|
|
64
|
+
WARNINGS="$WARNINGS\nDEBUG: $file has breakpoint/pdb in staged changes"
|
|
65
|
+
fi
|
|
66
|
+
fi
|
|
67
|
+
fi
|
|
68
|
+
done <<< "$STAGED"
|
|
69
|
+
|
|
70
|
+
# Check for potential hardcoded secrets (reuse FULL_DIFF)
|
|
71
|
+
if echo "$FULL_DIFF" | grep -qE '^\+.*(PRIVATE_KEY|SECRET_KEY|API_KEY|PASSWORD|TOKEN)[[:space:]]*=.*[a-zA-Z0-9]{16,}'; then
|
|
72
|
+
WARNINGS="$WARNINGS\nSECRET: Staged changes may contain hardcoded secrets. Review before committing."
|
|
73
|
+
fi
|
|
74
|
+
fi
|
|
75
|
+
|
|
76
|
+
# Print warnings (non-blocking) and allow commit
|
|
77
|
+
if [ -n "$WARNINGS" ]; then
|
|
78
|
+
echo -e "=== Commit Validation Warnings ===$WARNINGS\n================================" >&2
|
|
79
|
+
fi
|
|
80
|
+
|
|
81
|
+
exit 0
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Claude Code PreToolUse hook: Warns on push to protected branches
|
|
3
|
+
# Receives JSON on stdin with tool_input.command
|
|
4
|
+
# Exit 0 = allow (warnings only), Exit 2 = block
|
|
5
|
+
#
|
|
6
|
+
# Warns on: push to main/master/production/release, force push
|
|
7
|
+
|
|
8
|
+
INPUT=$(cat)
|
|
9
|
+
|
|
10
|
+
# Parse command
|
|
11
|
+
if command -v jq >/dev/null 2>&1; then
|
|
12
|
+
COMMAND=$(echo "$INPUT" | jq -r '.tool_input.command // empty')
|
|
13
|
+
else
|
|
14
|
+
COMMAND=$(echo "$INPUT" | grep -oE '"command"[[:space:]]*:[[:space:]]*"[^"]*"' | sed 's/"command"[[:space:]]*:[[:space:]]*"//;s/"$//')
|
|
15
|
+
fi
|
|
16
|
+
|
|
17
|
+
# Only process git push commands
|
|
18
|
+
if ! echo "$COMMAND" | grep -qE '^git[[:space:]]+push'; then
|
|
19
|
+
exit 0
|
|
20
|
+
fi
|
|
21
|
+
|
|
22
|
+
WARNINGS=""
|
|
23
|
+
|
|
24
|
+
# Check for protected branch names
|
|
25
|
+
for branch in main master production release; do
|
|
26
|
+
if echo "$COMMAND" | grep -qE "(origin[[:space:]]+${branch}|[[:space:]]${branch}$)"; then
|
|
27
|
+
WARNINGS="$WARNINGS\nPROTECTED: Pushing to '${branch}' — this is a protected branch. Confirm this is intentional."
|
|
28
|
+
fi
|
|
29
|
+
done
|
|
30
|
+
|
|
31
|
+
# Check for force push
|
|
32
|
+
if echo "$COMMAND" | grep -qE '\-\-force([[:space:]]|$)|\-f([[:space:]]|$)'; then
|
|
33
|
+
WARNINGS="$WARNINGS\nFORCE: Using --force push. This rewrites remote history and is destructive."
|
|
34
|
+
fi
|
|
35
|
+
if echo "$COMMAND" | grep -qE '\-\-force-with-lease'; then
|
|
36
|
+
WARNINGS="$WARNINGS\nFORCE: Using --force-with-lease. Safer than --force but still rewrites history."
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [ -n "$WARNINGS" ]; then
|
|
40
|
+
echo -e "=== Push Validation Warnings ===$WARNINGS\n================================" >&2
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
exit 0
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Cross-Platform Changes
|
|
2
|
+
|
|
3
|
+
Track changes that need to be replicated in the other codebase (web <-> mobile).
|
|
4
|
+
|
|
5
|
+
<!--
|
|
6
|
+
Format: One section per feature/task.
|
|
7
|
+
Each entry should have enough context for a developer (or Claude session)
|
|
8
|
+
in the other codebase to implement without guessing.
|
|
9
|
+
-->
|
|
10
|
+
|
|
11
|
+
<!-- TEMPLATE — copy this block for each new feature:
|
|
12
|
+
|
|
13
|
+
## [Feature Name] (YYYY-MM-DD)
|
|
14
|
+
Source: [web|mobile] — the codebase where this was implemented first
|
|
15
|
+
|
|
16
|
+
### API Changes
|
|
17
|
+
- [ ] Description of endpoint/payload/auth changes
|
|
18
|
+
|
|
19
|
+
### Data Model Changes
|
|
20
|
+
- [ ] New fields, renamed fields, type changes, validation rules
|
|
21
|
+
|
|
22
|
+
### Behavior Changes
|
|
23
|
+
- [ ] Business logic that must match across platforms
|
|
24
|
+
|
|
25
|
+
### UI/UX Parity
|
|
26
|
+
- [ ] Screens, flows, or interactions that should match
|
|
27
|
+
|
|
28
|
+
### Platform-Specific Notes
|
|
29
|
+
- [ ] Anything that differs intentionally between web and mobile
|
|
30
|
+
|
|
31
|
+
-->
|
|
@@ -39,7 +39,7 @@ The single command to keep your CLAUDE.md current. Diagnoses problems, updates t
|
|
|
39
39
|
|
|
40
40
|
Before making any changes, runs a diagnostic pass on the existing CLAUDE.md:
|
|
41
41
|
|
|
42
|
-
- **Missing sections** — checks for essential sections (Workflow, Sub-Agent Patterns, Project Memory, Lessons Capture, Testing, Commands, etc.)
|
|
42
|
+
- **Missing sections** — checks for essential sections (Workflow, Sub-Agent Patterns, Cross-Platform Tracking, Project Memory, Lessons Capture, Testing, Commands, etc.)
|
|
43
43
|
- **Stale content** — detects outdated info (stale model/route counts, removed dependencies, old command names like `/laravel-lint` instead of `/sk:lint`)
|
|
44
44
|
- **Inconsistencies** — compares documented vs actual project state (directories, scripts, workflows)
|
|
45
45
|
- **Section completeness** — flags sections that exist but are empty or have only placeholder text
|
|
@@ -63,6 +63,7 @@ Read → Explore → Design → Accessibility → Plan → Branch → Migrate
|
|
|
63
63
|
- Step completion summary rule (NON-NEGOTIABLE)
|
|
64
64
|
- Bug fix flow section
|
|
65
65
|
- Sub-Agent Patterns section (if missing)
|
|
66
|
+
- Cross-Platform Tracking section (if missing)
|
|
66
67
|
- Project Memory section (if missing)
|
|
67
68
|
- Lessons Capture section (if missing)
|
|
68
69
|
- Testing TDD section (if missing)
|