@kennethsolomon/shipkit 3.6.0 → 3.8.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 (46) hide show
  1. package/README.md +14 -15
  2. package/commands/sk/security-check.md +10 -4
  3. package/commands/sk/update-task.md +9 -0
  4. package/commands/sk/write-plan.md +5 -0
  5. package/package.json +1 -1
  6. package/skills/sk:context/SKILL.md +4 -0
  7. package/skills/sk:e2e/SKILL.md +19 -2
  8. package/skills/sk:fast-track/SKILL.md +80 -0
  9. package/skills/sk:frontend-design/SKILL.md +12 -5
  10. package/skills/sk:gates/SKILL.md +97 -0
  11. package/skills/sk:lint/SKILL.md +27 -6
  12. package/skills/sk:perf/SKILL.md +15 -4
  13. package/skills/sk:retro/SKILL.md +124 -0
  14. package/skills/sk:reverse-doc/SKILL.md +116 -0
  15. package/skills/sk:review/SKILL.md +19 -11
  16. package/skills/sk:schema-migrate/SKILL.md +22 -0
  17. package/skills/sk:scope-check/SKILL.md +93 -0
  18. package/skills/sk:setup-claude/SKILL.md +53 -0
  19. package/skills/sk:setup-claude/scripts/apply_setup_claude.py +206 -6
  20. package/skills/sk:setup-claude/templates/.claude/agents/e2e-tester.md +46 -0
  21. package/skills/sk:setup-claude/templates/.claude/agents/linter.md +53 -0
  22. package/skills/sk:setup-claude/templates/.claude/agents/perf-auditor.md +43 -0
  23. package/skills/sk:setup-claude/templates/.claude/agents/security-auditor.md +47 -0
  24. package/skills/sk:setup-claude/templates/.claude/agents/test-runner.md +42 -0
  25. package/skills/sk:setup-claude/templates/.claude/rules/api.md.template +14 -0
  26. package/skills/sk:setup-claude/templates/.claude/rules/frontend.md.template +15 -0
  27. package/skills/sk:setup-claude/templates/.claude/rules/laravel.md.template +15 -0
  28. package/skills/sk:setup-claude/templates/.claude/rules/react.md.template +14 -0
  29. package/skills/sk:setup-claude/templates/.claude/rules/tests.md.template +16 -0
  30. package/skills/sk:setup-claude/templates/.claude/settings.json.template +76 -0
  31. package/skills/sk:setup-claude/templates/.claude/statusline.sh +50 -0
  32. package/skills/sk:setup-claude/templates/CLAUDE.md.template +31 -42
  33. package/skills/sk:setup-claude/templates/commands/brainstorm.md.template +1 -1
  34. package/skills/sk:setup-claude/templates/commands/execute-plan.md.template +1 -1
  35. package/skills/sk:setup-claude/templates/commands/finish-feature.md.template +1 -1
  36. package/skills/sk:setup-claude/templates/commands/security-check.md.template +1 -1
  37. package/skills/sk:setup-claude/templates/commands/write-plan.md.template +1 -1
  38. package/skills/sk:setup-claude/templates/hooks/log-agent.sh +24 -0
  39. package/skills/sk:setup-claude/templates/hooks/pre-compact.sh +44 -0
  40. package/skills/sk:setup-claude/templates/hooks/session-start.sh +53 -0
  41. package/skills/sk:setup-claude/templates/hooks/session-stop.sh +33 -0
  42. package/skills/sk:setup-claude/templates/hooks/validate-commit.sh +81 -0
  43. package/skills/sk:setup-claude/templates/hooks/validate-push.sh +43 -0
  44. package/skills/sk:setup-claude/templates/tasks/workflow-status.md.template +10 -16
  45. package/skills/sk:setup-optimizer/SKILL.md +4 -4
  46. package/skills/sk:test/SKILL.md +6 -2
@@ -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
@@ -16,19 +16,13 @@
16
16
  | 9 | Write Tests (`/sk:write-tests`) | not yet | |
17
17
  | 10 | Implement (`/sk:execute-plan`) | not yet | |
18
18
  | 11 | Commit (`/sk:smart-commit`) | not yet | |
19
- | 12 | **Lint + Dep Audit** (`/sk:lint`) | not yet | HARD GATE — loop until clean |
20
- | 13 | Commit (`/sk:smart-commit`) | not yet | conditional |
21
- | 14 | **Verify Tests** (`/sk:test`) | not yet | HARD GATE — 100% coverage |
22
- | 15 | Commit (`/sk:smart-commit`) | not yet | conditional |
23
- | 16 | **Security** (`/sk:security-check`) | not yet | HARD GATE — 0 issues |
24
- | 17 | Commit (`/sk:smart-commit`) | not yet | conditional |
25
- | 18 | Performance (`/sk:perf`) | not yet | optional gate |
26
- | 19 | Commit (`/sk:smart-commit`) | not yet | conditional |
27
- | 20 | **Review + Simplify** (`/sk:review`) | not yet | HARD GATE 0 issues |
28
- | 21 | Commit (`/sk:smart-commit`) | not yet | conditional |
29
- | 22 | **E2E** (`/sk:e2e`) | not yet | HARD GATE — all E2E scenarios must pass |
30
- | 23 | Commit (`/sk:smart-commit`) | not yet | conditional — skip if E2E was clean |
31
- | 24 | Update (`/sk:update-task`) | not yet | |
32
- | 25 | Finalize (`/sk:finish-feature`) | not yet | |
33
- | 26 | Sync Features (`/sk:features`) | not yet | required — sync feature specs after ship |
34
- | 27 | Release (`/sk:release`) | not yet | optional |
19
+ | 12 | **Lint + Dep Audit** (`/sk:lint`) | not yet | HARD GATE — loop until clean, gates own their commits |
20
+ | 13 | **Verify Tests** (`/sk:test`) | not yet | HARD GATE — 100% coverage, gates own their commits |
21
+ | 14 | **Security** (`/sk:security-check`) | not yet | HARD GATE — 0 issues, gates own their commits |
22
+ | 15 | Performance (`/sk:perf`) | not yet | optional gate, gates own their commits |
23
+ | 16 | **Review + Simplify** (`/sk:review`) | not yet | HARD GATE — 0 issues, gates own their commits |
24
+ | 17 | **E2E** (`/sk:e2e`) | not yet | HARD GATE — all E2E scenarios must pass, gates own their commits |
25
+ | 18 | Update (`/sk:update-task`) | not yet | |
26
+ | 19 | Finalize (`/sk:finish-feature`) | not yet | |
27
+ | 20 | Sync Features (`/sk:features`) | not yet | requiredsync feature specs after ship |
28
+ | 21 | Release (`/sk:release`) | not yet | optional |
@@ -43,7 +43,7 @@ Before making any changes, runs a diagnostic pass on the existing CLAUDE.md:
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
46
- - **Outdated workflow** — checks if the workflow matches the current 27-step TDD flow with hard gates
46
+ - **Outdated workflow** — checks if the workflow matches the current 21-step TDD flow with hard gates
47
47
 
48
48
  Reports findings before proceeding. If issues are found, they inform subsequent steps.
49
49
 
@@ -51,15 +51,15 @@ Reports findings before proceeding. If issues are found, they inform subsequent
51
51
 
52
52
  If the workflow section is outdated or missing, replace it with the latest version:
53
53
 
54
- **Current workflow (27 steps, TDD with hard gates):**
54
+ **Current workflow (21 steps, TDD with hard gates):**
55
55
  ```
56
56
  Read → Explore → Design → Accessibility → Plan → Branch → Migrate → Write Tests → Implement → Lint → Verify Tests → Security → Performance → Review → E2E Tests → Finish → Sync Features
57
57
  ```
58
58
 
59
59
  **What gets updated:**
60
- - Workflow table (27 steps with correct commands: `/sk:write-tests`, `/sk:lint`, `/sk:test`, `/sk:accessibility`, `/sk:perf`, `/sk:e2e`)
60
+ - Workflow table (21 steps with correct commands: `/sk:write-tests`, `/sk:lint`, `/sk:test`, `/sk:accessibility`, `/sk:perf`, `/sk:e2e`)
61
61
  - Step details (TDD red/green/verify descriptions)
62
- - Tracker rules (hard gates at 12, 14, 16, 20, 22; optional steps 4, 5, 8, 18, 27)
62
+ - Tracker rules (hard gates at 12, 14, 16, 20, 17; optional steps 4, 5, 8, 18, 21)
63
63
  - Step completion summary rule (NON-NEGOTIABLE)
64
64
  - Bug fix flow section
65
65
  - Sub-Agent Patterns section (if missing)
@@ -126,8 +126,12 @@ Sub-agent 3: [FE command]
126
126
  - Read the failure output carefully — identify the root cause
127
127
  - Fix the failing **implementation code** or test setup, not the test assertions (tests define expected behavior)
128
128
  - Do NOT skip, mark incomplete, or delete failing tests
129
- - Re-run the failing suite until all tests pass
130
- - If a fix changes behavior, confirm with the user before applying
129
+ - Auto-commit with message `fix(test): resolve failing tests` — do NOT ask the user
130
+ - Re-run the failing suite
131
+ - Loop until all pass
132
+ - Fix the implementation and auto-commit. If the fix is a logic change (new behavior, changed contract), update the relevant tests to reflect the new behavior before committing.
133
+
134
+ > Gates own their commits — the fix-commit-rerun loop is fully internal. No manual commit step needed after this gate.
131
135
 
132
136
  ### 5. Verify Coverage
133
137