@kennethsolomon/shipkit 3.10.2 → 3.11.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 (30) hide show
  1. package/README.md +92 -4
  2. package/commands/sk/context-budget.md +5 -0
  3. package/commands/sk/eval.md +5 -0
  4. package/commands/sk/health.md +5 -0
  5. package/commands/sk/help.md +32 -8
  6. package/commands/sk/learn.md +5 -0
  7. package/commands/sk/resume-session.md +5 -0
  8. package/commands/sk/safety-guard.md +5 -0
  9. package/commands/sk/save-session.md +5 -0
  10. package/commands/sk/set-profile.md +8 -0
  11. package/package.json +1 -1
  12. package/skills/sk:brainstorming/SKILL.md +13 -0
  13. package/skills/sk:context-budget/SKILL.md +126 -0
  14. package/skills/sk:eval/SKILL.md +188 -0
  15. package/skills/sk:health/SKILL.md +146 -0
  16. package/skills/sk:learn/SKILL.md +138 -0
  17. package/skills/sk:resume-session/SKILL.md +95 -0
  18. package/skills/sk:safety-guard/SKILL.md +134 -0
  19. package/skills/sk:save-session/SKILL.md +84 -0
  20. package/skills/sk:setup-claude/SKILL.md +39 -2
  21. package/skills/sk:setup-claude/templates/.claude/settings.json.template +110 -26
  22. package/skills/sk:setup-claude/templates/CLAUDE.md.template +8 -1
  23. package/skills/sk:setup-claude/templates/hooks/config-protection.sh +71 -0
  24. package/skills/sk:setup-claude/templates/hooks/console-log-warning.sh +42 -0
  25. package/skills/sk:setup-claude/templates/hooks/cost-tracker.sh +26 -0
  26. package/skills/sk:setup-claude/templates/hooks/post-edit-format.sh +53 -0
  27. package/skills/sk:setup-claude/templates/hooks/safety-guard.sh +72 -0
  28. package/skills/sk:setup-claude/templates/hooks/suggest-compact.sh +35 -0
  29. package/skills/sk:setup-optimizer/SKILL.md +59 -8
  30. package/skills/sk:start/SKILL.md +25 -0
@@ -26,50 +26,134 @@
26
26
  "hooks": {
27
27
  "SessionStart": [
28
28
  {
29
- "type": "command",
30
- "command": "bash .claude/hooks/session-start.sh",
31
- "timeout": 10000
29
+ "matcher": "",
30
+ "hooks": [
31
+ {
32
+ "type": "command",
33
+ "command": "bash .claude/hooks/session-start.sh",
34
+ "timeout": 10000
35
+ }
36
+ ]
32
37
  }
33
38
  ],
34
39
  "PreCompact": [
35
40
  {
36
- "type": "command",
37
- "command": "bash .claude/hooks/pre-compact.sh",
38
- "timeout": 10000
41
+ "matcher": "",
42
+ "hooks": [
43
+ {
44
+ "type": "command",
45
+ "command": "bash .claude/hooks/pre-compact.sh",
46
+ "timeout": 10000
47
+ }
48
+ ]
39
49
  }
40
50
  ],
41
51
  "PreToolUse": [
42
52
  {
43
- "type": "command",
44
- "command": "bash .claude/hooks/validate-commit.sh",
45
- "timeout": 10000,
46
- "matcher": {
47
- "tool_name": "Bash",
48
- "command_pattern": "git commit*"
49
- }
53
+ "matcher": "Bash",
54
+ "hooks": [
55
+ {
56
+ "type": "command",
57
+ "command": "bash .claude/hooks/validate-commit.sh",
58
+ "timeout": 10000
59
+ }
60
+ ]
50
61
  },
51
62
  {
52
- "type": "command",
53
- "command": "bash .claude/hooks/validate-push.sh",
54
- "timeout": 5000,
55
- "matcher": {
56
- "tool_name": "Bash",
57
- "command_pattern": "git push*"
58
- }
63
+ "matcher": "Bash",
64
+ "hooks": [
65
+ {
66
+ "type": "command",
67
+ "command": "bash .claude/hooks/validate-push.sh",
68
+ "timeout": 5000
69
+ }
70
+ ]
71
+ },
72
+ {
73
+ "matcher": "Edit|Write",
74
+ "hooks": [
75
+ {
76
+ "type": "command",
77
+ "command": "bash .claude/hooks/config-protection.sh",
78
+ "timeout": 5000
79
+ }
80
+ ]
81
+ },
82
+ {
83
+ "matcher": "Edit|Write",
84
+ "hooks": [
85
+ {
86
+ "type": "command",
87
+ "command": "bash .claude/hooks/suggest-compact.sh",
88
+ "timeout": 3000
89
+ }
90
+ ]
91
+ },
92
+ {
93
+ "matcher": "Bash|Edit|Write",
94
+ "hooks": [
95
+ {
96
+ "type": "command",
97
+ "command": "bash .claude/hooks/safety-guard.sh",
98
+ "timeout": 5000
99
+ }
100
+ ]
101
+ }
102
+ ],
103
+ "PostToolUse": [
104
+ {
105
+ "matcher": "Edit",
106
+ "hooks": [
107
+ {
108
+ "type": "command",
109
+ "command": "bash .claude/hooks/post-edit-format.sh",
110
+ "timeout": 10000
111
+ }
112
+ ]
59
113
  }
60
114
  ],
61
115
  "SubagentStart": [
62
116
  {
63
- "type": "command",
64
- "command": "bash .claude/hooks/log-agent.sh",
65
- "timeout": 5000
117
+ "matcher": "",
118
+ "hooks": [
119
+ {
120
+ "type": "command",
121
+ "command": "bash .claude/hooks/log-agent.sh",
122
+ "timeout": 5000
123
+ }
124
+ ]
66
125
  }
67
126
  ],
68
127
  "Stop": [
69
128
  {
70
- "type": "command",
71
- "command": "bash .claude/hooks/session-stop.sh",
72
- "timeout": 10000
129
+ "matcher": "",
130
+ "hooks": [
131
+ {
132
+ "type": "command",
133
+ "command": "bash .claude/hooks/session-stop.sh",
134
+ "timeout": 10000
135
+ }
136
+ ]
137
+ },
138
+ {
139
+ "matcher": "",
140
+ "hooks": [
141
+ {
142
+ "type": "command",
143
+ "command": "bash .claude/hooks/console-log-warning.sh",
144
+ "timeout": 10000
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "matcher": "",
150
+ "hooks": [
151
+ {
152
+ "type": "command",
153
+ "command": "bash .claude/hooks/cost-tracker.sh",
154
+ "timeout": 5000
155
+ }
156
+ ]
73
157
  }
74
158
  ]
75
159
  }
@@ -281,26 +281,33 @@ Create entries in: `[ARCH_CHANGELOG_DIR]`
281
281
  | `/sk:accessibility` | WCAG 2.1 AA audit — runs after design, before implementation |
282
282
  | `/sk:api-design` | Design API contracts (endpoints, payloads, auth, errors) before implementation |
283
283
  | `/sk:autopilot` | Hands-free workflow — all 8 steps, auto-skip, auto-advance, auto-commit |
284
- | `/sk:brainstorm` | Explore requirements and design |
284
+ | `/sk:brainstorm` | Explore requirements and design (includes search-first research) |
285
285
  | `/sk:branch` | Create feature branch auto-named from current task |
286
286
  | `/sk:change` | Handle mid-workflow requirement changes — re-enter at correct step |
287
287
  | `/sk:context` | Load all context files + output session brief for fast session start |
288
+ | `/sk:context-budget` | Audit context window token consumption and find savings |
288
289
  | `/sk:dashboard` | Read-only workflow Kanban board — localhost server, multi-worktree |
289
290
  | `/sk:debug` | Investigate and debug issues (bug fix entry point) |
290
291
  | `/sk:e2e` | E2E behavioral verification using agent-browser (final quality gate) |
292
+ | `/sk:eval` | Define, run, and report on evaluations for agent reliability |
291
293
  | `/sk:execute-plan` | Execute `tasks/todo.md` checkboxes in batches |
292
294
  | `/sk:fast-track` | Abbreviated workflow for small changes — skip planning, keep all gates |
293
295
  | `/sk:features` | Sync feature specs with shipped implementation |
294
296
  | `/sk:finish-feature` | Changelog + PR creation |
295
297
  | `/sk:frontend-design` | UI mockup before implementation. Prompts to create Pencil visual mockup |
296
298
  | `/sk:gates` | Run all quality gates in optimized parallel batches |
299
+ | `/sk:health` | Harness self-audit scorecard (7 categories, 0-70) |
297
300
  | `/sk:hotfix` | Emergency fix workflow — skip design/TDD, quality gates enforced |
301
+ | `/sk:learn` | Extract reusable patterns from sessions into learned instincts |
298
302
  | `/sk:lint` | Auto-detect and run all project linters + dependency audits |
299
303
  | `/sk:perf` | Performance audit — bundle, N+1, Core Web Vitals, memory |
300
304
  | `/sk:release` | Version bump + changelog + tag |
305
+ | `/sk:resume-session` | Resume a previously saved session with full context restoration |
301
306
  | `/sk:retro` | Post-ship retrospective: velocity, blockers, action items |
302
307
  | `/sk:reverse-doc` | Generate architecture/design docs from existing code |
303
308
  | `/sk:review` | Self-review with simplify pre-pass + multi-dimensional review |
309
+ | `/sk:safety-guard` | Protect against destructive ops (careful/freeze/guard modes) |
310
+ | `/sk:save-session` | Save current session state for cross-session continuity |
304
311
  | `/sk:scope-check` | Compare implementation against plan, detect scope creep |
305
312
  | `/sk:security-check` | OWASP security audit on changed files |
306
313
  | `/sk:seo-audit` | SEO audit — dual-mode (source templates + dev server), ask-before-fix |
@@ -0,0 +1,71 @@
1
+ #!/usr/bin/env bash
2
+ # config-protection.sh — PreToolUse hook for Edit/Write
3
+ # Blocks modifications to linter/formatter configs.
4
+ # Override: SHIPKIT_ALLOW_CONFIG_EDIT=1
5
+
6
+ set -euo pipefail
7
+
8
+ if [[ "${SHIPKIT_ALLOW_CONFIG_EDIT:-0}" == "1" ]]; then
9
+ exit 0
10
+ fi
11
+
12
+ # Read the tool input from stdin
13
+ INPUT=$(cat)
14
+
15
+ # Extract the file path from the tool input
16
+ FILE_PATH=$(echo "$INPUT" | grep -oE '"file_path"\s*:\s*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
17
+
18
+ if [[ -z "$FILE_PATH" ]]; then
19
+ exit 0
20
+ fi
21
+
22
+ BASENAME=$(basename "$FILE_PATH")
23
+
24
+ # Protected config patterns
25
+ PROTECTED_CONFIGS=(
26
+ ".eslintrc"
27
+ ".eslintrc.js"
28
+ ".eslintrc.cjs"
29
+ ".eslintrc.json"
30
+ ".eslintrc.yml"
31
+ ".eslintrc.yaml"
32
+ "eslint.config.js"
33
+ "eslint.config.mjs"
34
+ "eslint.config.cjs"
35
+ ".prettierrc"
36
+ ".prettierrc.js"
37
+ ".prettierrc.cjs"
38
+ ".prettierrc.json"
39
+ ".prettierrc.yml"
40
+ ".prettierrc.yaml"
41
+ "prettier.config.js"
42
+ "prettier.config.mjs"
43
+ "biome.json"
44
+ "biome.jsonc"
45
+ ".stylelintrc"
46
+ ".stylelintrc.json"
47
+ ".stylelintrc.js"
48
+ "stylelint.config.js"
49
+ "phpstan.neon"
50
+ "phpstan.neon.dist"
51
+ "pint.json"
52
+ "rector.php"
53
+ ".php-cs-fixer.php"
54
+ ".php-cs-fixer.dist.php"
55
+ ".rubocop.yml"
56
+ ".golangci.yml"
57
+ ".golangci.yaml"
58
+ "rustfmt.toml"
59
+ ".clang-format"
60
+ )
61
+
62
+ for config in "${PROTECTED_CONFIGS[@]}"; do
63
+ if [[ "$BASENAME" == "$config" ]]; then
64
+ echo "BLOCKED: Modifying linter/formatter config '$BASENAME'."
65
+ echo "Fix the code instead of weakening the rules."
66
+ echo "Override: set SHIPKIT_ALLOW_CONFIG_EDIT=1"
67
+ exit 2
68
+ fi
69
+ done
70
+
71
+ exit 0
@@ -0,0 +1,42 @@
1
+ #!/usr/bin/env bash
2
+ # console-log-warning.sh — Stop hook
3
+ # Scans git-modified files for debug statements and warns if found.
4
+
5
+ set -uo pipefail
6
+
7
+ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
8
+ cd "$PROJECT_ROOT"
9
+
10
+ MODIFIED_FILES=$(git diff --name-only --diff-filter=ACMR 2>/dev/null)
11
+ STAGED_FILES=$(git diff --cached --name-only --diff-filter=ACMR 2>/dev/null)
12
+ ALL_FILES=$(echo -e "${MODIFIED_FILES}\n${STAGED_FILES}" | sort -u | grep -v '^$')
13
+
14
+ if [[ -z "$ALL_FILES" ]]; then
15
+ exit 0
16
+ fi
17
+
18
+ DEBUG_PATTERNS='console\.log\|console\.warn\|console\.error\|console\.debug\|console\.trace\|debugger\b\|\bdd(\|\bdump(\|\bvar_dump(\|\bprint_r(\|\blog\.Print\|log\.Debug\|\bpdb\.set_trace\|\bbreakpoint()'
19
+
20
+ FOUND=0
21
+ REPORT=""
22
+
23
+ while IFS= read -r file; do
24
+ [[ -z "$file" || ! -f "$file" ]] && continue
25
+ MATCHES=$(grep -n "$DEBUG_PATTERNS" "$file" 2>/dev/null || true)
26
+ if [[ -n "$MATCHES" ]]; then
27
+ FOUND=$((FOUND + 1))
28
+ REPORT+=" $file:\n"
29
+ while IFS= read -r match; do
30
+ REPORT+=" $match\n"
31
+ done <<< "$MATCHES"
32
+ fi
33
+ done <<< "$ALL_FILES"
34
+
35
+ if [[ $FOUND -gt 0 ]]; then
36
+ echo ""
37
+ echo "WARNING: Debug statements found in $FOUND modified file(s):"
38
+ echo -e "$REPORT"
39
+ echo "Consider removing before committing."
40
+ fi
41
+
42
+ exit 0
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env bash
2
+ # cost-tracker.sh — Stop hook (async)
3
+ # Logs session metadata to .claude/sessions/cost-log.jsonl
4
+
5
+ set -uo pipefail
6
+
7
+ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
8
+ SESSIONS_DIR="$PROJECT_ROOT/.claude/sessions"
9
+ LOG_FILE="$SESSIONS_DIR/cost-log.jsonl"
10
+
11
+ mkdir -p "$SESSIONS_DIR"
12
+
13
+ BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")
14
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
15
+ DATE=$(date +"%Y-%m-%d")
16
+
17
+ # Count commits made during this session (last 8 hours)
18
+ RECENT_COMMITS=$(git log --since="8 hours ago" --oneline 2>/dev/null | wc -l | tr -d ' ')
19
+
20
+ # Count modified files
21
+ MODIFIED_COUNT=$(git diff --name-only 2>/dev/null | wc -l | tr -d ' ')
22
+ STAGED_COUNT=$(git diff --cached --name-only 2>/dev/null | wc -l | tr -d ' ')
23
+
24
+ echo "{\"timestamp\":\"$TIMESTAMP\",\"date\":\"$DATE\",\"branch\":\"$BRANCH\",\"commits\":$RECENT_COMMITS,\"modified_files\":$MODIFIED_COUNT,\"staged_files\":$STAGED_COUNT}" >> "$LOG_FILE"
25
+
26
+ exit 0
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env bash
2
+ # post-edit-format.sh — PostToolUse hook for Edit
3
+ # Auto-formats the edited file using the project's formatter.
4
+
5
+ set -uo pipefail
6
+
7
+ INPUT=$(cat)
8
+ FILE_PATH=$(echo "$INPUT" | grep -oE '"file_path"\s*:\s*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
9
+
10
+ if [[ -z "$FILE_PATH" || ! -f "$FILE_PATH" ]]; then
11
+ exit 0
12
+ fi
13
+
14
+ EXT="${FILE_PATH##*.}"
15
+ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
16
+
17
+ format_file() {
18
+ # Biome (JS/TS/JSON)
19
+ if [[ -f "$PROJECT_ROOT/biome.json" || -f "$PROJECT_ROOT/biome.jsonc" ]]; then
20
+ if [[ "$EXT" =~ ^(js|jsx|ts|tsx|json|jsonc)$ ]]; then
21
+ npx biome format --write "$FILE_PATH" 2>/dev/null && return 0
22
+ fi
23
+ fi
24
+
25
+ # Prettier (JS/TS/CSS/HTML/MD)
26
+ if [[ -f "$PROJECT_ROOT/.prettierrc" || -f "$PROJECT_ROOT/.prettierrc.json" || -f "$PROJECT_ROOT/.prettierrc.js" || -f "$PROJECT_ROOT/.prettierrc.cjs" || -f "$PROJECT_ROOT/prettier.config.js" || -f "$PROJECT_ROOT/prettier.config.mjs" ]]; then
27
+ if [[ "$EXT" =~ ^(js|jsx|ts|tsx|css|scss|html|md|json|yaml|yml|vue|svelte)$ ]]; then
28
+ npx prettier --write "$FILE_PATH" 2>/dev/null && return 0
29
+ fi
30
+ fi
31
+
32
+ # Pint (PHP)
33
+ if [[ -f "$PROJECT_ROOT/pint.json" || -f "$PROJECT_ROOT/vendor/bin/pint" ]]; then
34
+ if [[ "$EXT" == "php" ]]; then
35
+ "$PROJECT_ROOT/vendor/bin/pint" "$FILE_PATH" 2>/dev/null && return 0
36
+ fi
37
+ fi
38
+
39
+ # gofmt (Go)
40
+ if [[ "$EXT" == "go" ]]; then
41
+ command -v gofmt &>/dev/null && gofmt -w "$FILE_PATH" 2>/dev/null && return 0
42
+ fi
43
+
44
+ # cargo fmt (Rust)
45
+ if [[ "$EXT" == "rs" ]]; then
46
+ command -v rustfmt &>/dev/null && rustfmt "$FILE_PATH" 2>/dev/null && return 0
47
+ fi
48
+
49
+ return 0
50
+ }
51
+
52
+ format_file
53
+ exit 0
@@ -0,0 +1,72 @@
1
+ #!/usr/bin/env bash
2
+ # safety-guard.sh — PreToolUse hook for Bash/Edit/Write
3
+ # Reads .claude/safety-guard.json for active mode and directory constraints.
4
+
5
+ set -uo pipefail
6
+
7
+ PROJECT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
8
+ GUARD_CONFIG="$PROJECT_ROOT/.claude/safety-guard.json"
9
+
10
+ if [[ ! -f "$GUARD_CONFIG" ]]; then
11
+ exit 0
12
+ fi
13
+
14
+ INPUT=$(cat)
15
+ MODE=$(python3 -c "import json; print(json.load(open('$GUARD_CONFIG')).get('mode', 'off'))" 2>/dev/null || echo "off")
16
+
17
+ if [[ "$MODE" == "off" ]]; then
18
+ exit 0
19
+ fi
20
+
21
+ # Extract tool info
22
+ TOOL_NAME="${TOOL_NAME:-}"
23
+ FILE_PATH=$(echo "$INPUT" | grep -oE '"file_path"\s*:\s*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
24
+ COMMAND=$(echo "$INPUT" | grep -oE '"command"\s*:\s*"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
25
+
26
+ # Careful mode: block destructive commands
27
+ if [[ "$MODE" == "careful" || "$MODE" == "guard" ]]; then
28
+ if [[ -n "$COMMAND" ]]; then
29
+ DESTRUCTIVE_PATTERNS=(
30
+ "rm -rf"
31
+ "rm -fr"
32
+ "git push --force"
33
+ "git push -f"
34
+ "git reset --hard"
35
+ "git clean -f"
36
+ "DROP TABLE"
37
+ "DROP DATABASE"
38
+ "chmod 777"
39
+ "chmod -R 777"
40
+ "--no-verify"
41
+ )
42
+ for pattern in "${DESTRUCTIVE_PATTERNS[@]}"; do
43
+ if echo "$COMMAND" | grep -qi "$pattern"; then
44
+ echo "BLOCKED by safety-guard (careful mode): destructive command detected."
45
+ echo " Command: $COMMAND"
46
+ echo " Pattern: $pattern"
47
+ echo " Disable: /sk:safety-guard off"
48
+ exit 2
49
+ fi
50
+ done
51
+ fi
52
+ fi
53
+
54
+ # Freeze mode: block writes outside specified directory
55
+ if [[ "$MODE" == "freeze" || "$MODE" == "guard" ]]; then
56
+ FREEZE_DIR=$(python3 -c "import json; print(json.load(open('$GUARD_CONFIG')).get('freeze_dir', ''))" 2>/dev/null || echo "")
57
+ if [[ -n "$FREEZE_DIR" && -n "$FILE_PATH" ]]; then
58
+ # Resolve to absolute paths for comparison
59
+ ABS_FREEZE=$(cd "$PROJECT_ROOT" && cd "$FREEZE_DIR" 2>/dev/null && pwd || echo "$PROJECT_ROOT/$FREEZE_DIR")
60
+ ABS_FILE=$(cd "$(dirname "$FILE_PATH")" 2>/dev/null && echo "$(pwd)/$(basename "$FILE_PATH")" || echo "$FILE_PATH")
61
+
62
+ if [[ "$ABS_FILE" != "$ABS_FREEZE"* ]]; then
63
+ echo "BLOCKED by safety-guard (freeze mode): write outside frozen directory."
64
+ echo " File: $FILE_PATH"
65
+ echo " Allowed: $FREEZE_DIR"
66
+ echo " Disable: /sk:safety-guard off"
67
+ exit 2
68
+ fi
69
+ fi
70
+ fi
71
+
72
+ exit 0
@@ -0,0 +1,35 @@
1
+ #!/usr/bin/env bash
2
+ # suggest-compact.sh — PreToolUse hook for Edit/Write
3
+ # Tracks tool call count and suggests /compact at threshold.
4
+
5
+ set -uo pipefail
6
+
7
+ THRESHOLD="${SHIPKIT_COMPACT_THRESHOLD:-50}"
8
+ REPEAT_INTERVAL=25
9
+
10
+ # Use a session-scoped counter file
11
+ COUNTER_FILE="/tmp/shipkit-tool-count-${PPID:-$$}"
12
+
13
+ # Read current count
14
+ COUNT=0
15
+ if [[ -f "$COUNTER_FILE" ]]; then
16
+ COUNT=$(cat "$COUNTER_FILE" 2>/dev/null || echo "0")
17
+ fi
18
+
19
+ COUNT=$((COUNT + 1))
20
+ echo "$COUNT" > "$COUNTER_FILE"
21
+
22
+ # Check if we should suggest compaction
23
+ if [[ $COUNT -eq $THRESHOLD ]]; then
24
+ echo ""
25
+ echo "HINT: You've made $COUNT+ tool calls this session."
26
+ echo "Consider running /compact if context feels heavy."
27
+ elif [[ $COUNT -gt $THRESHOLD ]]; then
28
+ PAST_THRESHOLD=$((COUNT - THRESHOLD))
29
+ if [[ $((PAST_THRESHOLD % REPEAT_INTERVAL)) -eq 0 ]]; then
30
+ echo ""
31
+ echo "HINT: $COUNT tool calls this session. Consider /compact."
32
+ fi
33
+ fi
34
+
35
+ exit 0
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: sk:setup-optimizer
3
- description: "Diagnose, update workflow, enrich, and maintain CLAUDE.md. The single command to keep any CLAUDE.md current."
3
+ description: "Diagnose, update workflow, deploy hooks, enrich CLAUDE.md, and keep project infrastructure current. The single command for ongoing ShipKit maintenance."
4
4
  triggers:
5
5
  - optimize claude
6
6
  - optimize setup
@@ -20,14 +20,15 @@ allowed-tools:
20
20
 
21
21
  ## Overview
22
22
 
23
- The single command to keep your CLAUDE.md current. Diagnoses problems, updates the workflow to the latest version, scans your codebase, and enriches with project context — all while preserving your customizations.
23
+ The single command to keep your entire ShipKit project infrastructure current. Diagnoses problems, updates the workflow, deploys missing hooks, scans your codebase, and enriches CLAUDE.md with project context — all while preserving your customizations.
24
24
 
25
25
  ### What It Does
26
26
 
27
27
  1. **Diagnoses** — finds missing sections, stale info, inconsistencies, and gaps
28
28
  2. **Updates workflow** — refreshes the workflow section to the latest template version
29
- 3. **Discovers** — scans project structure, docs, and workflows
30
- 4. **Enriches** — merges discoveries into CLAUDE.md while preserving your edits
29
+ 3. **Deploys hooks** — installs missing hooks and updates settings.json wiring
30
+ 4. **Discovers** — scans project structure, docs, and workflows
31
+ 5. **Enriches** — merges discoveries into CLAUDE.md while preserving your edits
31
32
 
32
33
  ## Usage
33
34
 
@@ -44,9 +45,10 @@ Before making any changes, runs a diagnostic pass on the existing CLAUDE.md:
44
45
  - **Inconsistencies** — compares documented vs actual project state (directories, scripts, workflows)
45
46
  - **Section completeness** — flags sections that exist but are empty or have only placeholder text
46
47
  - **Outdated workflow** — checks if the workflow matches the current 8-step flow with `/sk:gates` as single gate step
47
- - **Missing commands** — checks for `sk:start`, `sk:autopilot`, `sk:team` in the Commands table
48
+ - **Missing commands** — checks for `sk:start`, `sk:autopilot`, `sk:team`, `sk:learn`, `sk:context-budget`, `sk:health`, `sk:save-session`, `sk:resume-session`, `sk:safety-guard`, `sk:eval` in the Commands table
48
49
  - **Auto-skip rules** — checks for auto-skip detection rules in the workflow section
49
50
  - **Stale tracker references** — checks for `tasks/workflow-status.md` references (removed — progress tracked via git branch + todo.md checkboxes)
51
+ - **Missing hooks** — checks if `.claude/hooks/` exists and contains both core and enhanced hooks
50
52
 
51
53
  Reports findings before proceeding. If issues are found, they inform subsequent steps.
52
54
 
@@ -89,6 +91,54 @@ Explore → Design → Plan → Branch → Write Tests + Implement → Commit
89
91
  4. Insert missing sections (Sub-Agent Patterns, Project Memory, etc.) in their correct positions
90
92
  5. Preserve all `<!-- LOCK -->` and project-specific sections
91
93
 
94
+ ### Step 1.5: Hooks Deployment
95
+
96
+ After updating the workflow, check and deploy hooks:
97
+
98
+ 1. **Check if `.claude/hooks/` exists** — if not, create it
99
+ 2. **Check for core hooks** — `session-start.sh`, `session-stop.sh`, `pre-compact.sh`, `validate-commit.sh`, `validate-push.sh`, `log-agent.sh`
100
+ 3. **Check for enhanced hooks** — `config-protection.sh`, `post-edit-format.sh`, `console-log-warning.sh`, `cost-tracker.sh`, `suggest-compact.sh`, `safety-guard.sh`
101
+ 4. **Check `.claude/settings.json`** — verify hooks are wired correctly
102
+
103
+ **Report status and prompt:**
104
+
105
+ > "Hooks: [X/6 core, Y/6 enhanced] installed
106
+ > Install missing hooks? [y/n]"
107
+
108
+ **If yes:**
109
+
110
+ 1. **Locate templates** — resolve the ShipKit templates directory:
111
+ - `~/.claude/skills/sk:setup-claude/templates/hooks/` (symlinked install)
112
+ - Or the npm global path if installed via `npm install -g`
113
+
114
+ 2. **Deploy missing hook scripts** (create-if-missing, never overwrite existing):
115
+ ```bash
116
+ # For each missing hook file:
117
+ cp "$TEMPLATE_DIR/hooks/<hook>.sh" ".claude/hooks/<hook>.sh"
118
+ chmod +x ".claude/hooks/<hook>.sh"
119
+ ```
120
+
121
+ 3. **Update `.claude/settings.json`** — read the latest `settings.json.template` and merge new hook entries into the existing settings.json:
122
+ - **Preserve** existing hooks, permissions, statusline config
123
+ - **Add** only missing hook entries (new PreToolUse, PostToolUse, Stop entries)
124
+ - **Never remove** existing entries — additive merge only
125
+
126
+ 4. **Report what was deployed:**
127
+ ```
128
+ Deployed hooks:
129
+ + config-protection.sh (PreToolUse — blocks linter config edits)
130
+ + post-edit-format.sh (PostToolUse — auto-format after edits)
131
+ + console-log-warning.sh (Stop — warn on debug statements)
132
+ + cost-tracker.sh (Stop — session metadata logging)
133
+ + suggest-compact.sh (PreToolUse — compact suggestions)
134
+ + safety-guard.sh (PreToolUse — freeze/careful mode)
135
+ ~ Updated .claude/settings.json with new hook wiring
136
+ ```
137
+
138
+ **If no:** skip hook deployment, continue to Step 2.
139
+
140
+ **Idempotency:** Never overwrite existing hook files — the user may have customized them. Only deploy hooks that don't exist yet. For settings.json, merge additively.
141
+
92
142
  ### Step 2: Scan & Enrich
93
143
 
94
144
  After workflow update, proceeds with codebase discovery and enrichment:
@@ -183,10 +233,11 @@ This content will never be regenerated.
183
233
 
184
234
  ## When to Use
185
235
 
186
- ✅ **Use `/optimize-claude` when:**
236
+ ✅ **Use `/sk:setup-optimizer` when:**
237
+ - ShipKit was updated and your project needs the latest hooks/commands
187
238
  - You've added new directories to your project
188
239
  - You've created documentation files
189
240
  - You want to refresh project context
190
- - Monthly maintenance of CLAUDE.md
241
+ - Monthly maintenance of CLAUDE.md and hooks
191
242
 
192
- ✅ **Safe to run multiple times during development** - Your customizations are always preserved!
243
+ ✅ **Safe to run multiple times** existing customizations and hook files are never overwritten.
@@ -53,6 +53,31 @@ Read the task description from arguments. Scan for signal keywords to determine
53
53
  | `backend` only | `solo` |
54
54
  | `unknown` | `solo` (default) |
55
55
 
56
+ ### Step 1.5 — Missing Context Detection (automatic, no prompt)
57
+
58
+ After classification, scan the task description for gaps. This is informational only — does NOT block.
59
+
60
+ **Critical context checks:**
61
+
62
+ | Check | How to detect | Auto-resolve |
63
+ |-------|--------------|--------------|
64
+ | Tech stack specified? | Look for framework/language keywords | Auto-detect from package.json, composer.json, go.mod, Cargo.toml |
65
+ | Acceptance criteria present? | Look for "should", "must", "when", "given" | Cannot auto-resolve — flag for user |
66
+ | Scope boundaries stated? | Look for "only", "not", "exclude", "just" | Cannot auto-resolve — flag for user |
67
+ | Security requirements? | Check if task involves auth, user data, payments, tokens | Flag: "This touches auth/user data — consider security requirements" |
68
+ | Testing expectations? | Look for "test", "coverage", "spec" | Default: 100% coverage on new code (per workflow) |
69
+
70
+ **If 3+ critical items are missing**, include in the recommendation output:
71
+
72
+ ```
73
+ Missing Context (3 items — consider clarifying):
74
+ - No acceptance criteria detected
75
+ - No scope boundaries stated (what should NOT change?)
76
+ - Task involves user data but no security requirements mentioned
77
+ ```
78
+
79
+ This check runs silently. If <3 items missing, no output.
80
+
56
81
  ### Step 2 — Recommend (one prompt, user confirms or overrides)
57
82
 
58
83
  Present the classification and recommendation: