cortexhawk 3.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.
Files changed (136) hide show
  1. package/.cortexhawk-team.yml +65 -0
  2. package/CHANGELOG.md +268 -0
  3. package/CLAUDE.md +96 -0
  4. package/LICENSE +21 -0
  5. package/PACKS.md +14 -0
  6. package/README.md +418 -0
  7. package/REGISTRY.md +23 -0
  8. package/agents/architect.md +46 -0
  9. package/agents/brainstormer.md +57 -0
  10. package/agents/code-simplifier.md +56 -0
  11. package/agents/codebase-mapper.md +63 -0
  12. package/agents/copywriter.md +48 -0
  13. package/agents/debugger.md +44 -0
  14. package/agents/designer.md +53 -0
  15. package/agents/devops.md +49 -0
  16. package/agents/docs-manager.md +50 -0
  17. package/agents/fullstack-developer.md +55 -0
  18. package/agents/git-manager.md +63 -0
  19. package/agents/implementer.md +30 -0
  20. package/agents/journal-writer.md +53 -0
  21. package/agents/planner.md +52 -0
  22. package/agents/project-manager.md +50 -0
  23. package/agents/researcher.md +46 -0
  24. package/agents/reviewer.md +63 -0
  25. package/agents/security-auditor.md +92 -0
  26. package/agents/teacher.md +71 -0
  27. package/agents/tester.md +41 -0
  28. package/commands/api-gen.md +17 -0
  29. package/commands/backlog.md +26 -0
  30. package/commands/bootstrap.md +32 -0
  31. package/commands/brainstorm.md +18 -0
  32. package/commands/build.md +16 -0
  33. package/commands/chain.md +46 -0
  34. package/commands/changelog.md +16 -0
  35. package/commands/check.md +40 -0
  36. package/commands/ci.md +32 -0
  37. package/commands/context.md +35 -0
  38. package/commands/debug.md +16 -0
  39. package/commands/deploy.md +16 -0
  40. package/commands/doc.md +15 -0
  41. package/commands/export.md +17 -0
  42. package/commands/journal.md +18 -0
  43. package/commands/learn.md +16 -0
  44. package/commands/map.md +16 -0
  45. package/commands/migrate.md +17 -0
  46. package/commands/monitor.md +16 -0
  47. package/commands/optimize.md +17 -0
  48. package/commands/plan.md +17 -0
  49. package/commands/pulse.md +46 -0
  50. package/commands/refactor.md +16 -0
  51. package/commands/research.md +18 -0
  52. package/commands/review.md +16 -0
  53. package/commands/scan.md +19 -0
  54. package/commands/ship.md +17 -0
  55. package/commands/simplify.md +16 -0
  56. package/commands/task.md +32 -0
  57. package/commands/tdd.md +17 -0
  58. package/commands/test.md +16 -0
  59. package/commands/upgrade.md +27 -0
  60. package/cortexhawk +450 -0
  61. package/hooks/agent-analytics.sh +67 -0
  62. package/hooks/branch-guard.sh +56 -0
  63. package/hooks/codex-dispatcher.sh +84 -0
  64. package/hooks/commit-guard.sh +71 -0
  65. package/hooks/compose.yml +47 -0
  66. package/hooks/dependency-check.sh +56 -0
  67. package/hooks/file-guard.sh +69 -0
  68. package/hooks/hooks.json +46 -0
  69. package/hooks/self-review.sh +71 -0
  70. package/hooks/session-start.sh +132 -0
  71. package/hooks/session-telemetry.sh +60 -0
  72. package/hooks/test-reminder.sh +75 -0
  73. package/install.sh +3805 -0
  74. package/mcp/README.md +37 -0
  75. package/mcp/context7.json +8 -0
  76. package/mcp/puppeteer.json +8 -0
  77. package/mcp/sequential-thinking.json +8 -0
  78. package/modes/default.md +5 -0
  79. package/modes/fast.md +5 -0
  80. package/modes/learn.md +9 -0
  81. package/modes/orchestration.md +5 -0
  82. package/modes/pair.md +10 -0
  83. package/modes/research.md +5 -0
  84. package/modes/review.md +5 -0
  85. package/package.json +32 -0
  86. package/profiles/api.json +27 -0
  87. package/profiles/data.json +23 -0
  88. package/profiles/fullstack.json +27 -0
  89. package/scripts/autodetect-profile.sh +68 -0
  90. package/scripts/benchmark.sh +106 -0
  91. package/scripts/chain-post-save.sh +23 -0
  92. package/scripts/generate-plans-index.sh +50 -0
  93. package/scripts/git-workflow-init.sh +115 -0
  94. package/scripts/install-codex.sh +128 -0
  95. package/scripts/interactive-init.sh +264 -0
  96. package/scripts/post-install-audit.sh +130 -0
  97. package/scripts/validate.sh +214 -0
  98. package/settings.json +90 -0
  99. package/setup.sh +67 -0
  100. package/skills/databases/schema-designer/SKILL.md +54 -0
  101. package/skills/databases/sql-optimizer/SKILL.md +37 -0
  102. package/skills/devops/ci-cd/SKILL.md +59 -0
  103. package/skills/devops/deployment/SKILL.md +49 -0
  104. package/skills/devops/docker/SKILL.md +57 -0
  105. package/skills/frameworks/api-design/SKILL.md +103 -0
  106. package/skills/frameworks/fastapi/SKILL.md +68 -0
  107. package/skills/frameworks/nextjs/SKILL.md +74 -0
  108. package/skills/frameworks/python/SKILL.md +89 -0
  109. package/skills/frameworks/react/SKILL.md +83 -0
  110. package/skills/frameworks/sveltekit/SKILL.md +69 -0
  111. package/skills/frameworks/tailwindcss/SKILL.md +75 -0
  112. package/skills/frameworks/typescript/SKILL.md +94 -0
  113. package/skills/meta/mcp-builder/SKILL.md +54 -0
  114. package/skills/meta/skill-creator/SKILL.md +43 -0
  115. package/skills/optimization/performance/SKILL.md +70 -0
  116. package/skills/quality/complexity-analyzer/SKILL.md +52 -0
  117. package/skills/quality/error-handling/SKILL.md +123 -0
  118. package/skills/quality/log-analyzer/SKILL.md +31 -0
  119. package/skills/quality/pattern-detector/SKILL.md +50 -0
  120. package/skills/security/auth-analyzer/SKILL.md +96 -0
  121. package/skills/security/compliance-checker/SKILL.md +92 -0
  122. package/skills/security/container-security/SKILL.md +128 -0
  123. package/skills/security/dependency-auditor/SKILL.md +100 -0
  124. package/skills/security/encryption/SKILL.md +94 -0
  125. package/skills/security/incident-response/SKILL.md +127 -0
  126. package/skills/security/secrets/SKILL.md +93 -0
  127. package/skills/security/security-headers/SKILL.md +83 -0
  128. package/skills/security/security-logging/SKILL.md +107 -0
  129. package/skills/security/vulnerability-scanner/SKILL.md +114 -0
  130. package/skills/testing/e2e-testing/SKILL.md +119 -0
  131. package/skills/testing/tdd/SKILL.md +40 -0
  132. package/skills/testing/test-generator/SKILL.md +39 -0
  133. package/skills/workflow/commit/SKILL.md +61 -0
  134. package/skills/workflow/confidence-check/SKILL.md +90 -0
  135. package/skills/workflow/pr-review-comments/SKILL.md +81 -0
  136. package/skills/workflow/pr-review-comments/scripts/fetch_comments.py +237 -0
package/cortexhawk ADDED
@@ -0,0 +1,450 @@
1
+ #!/usr/bin/env bash
2
+ # cortexhawk — CLI wrapper for CortexHawk development toolkit
3
+ # Install via: npm install -g cortexhawk | ./setup.sh | git clone
4
+
5
+ set -e
6
+
7
+ # Resolve CORTEXHAWK_HOME: env var > script location > default
8
+ if [ -z "$CORTEXHAWK_HOME" ]; then
9
+ # Resolve symlinks to find the actual script location (npm global symlinks)
10
+ SOURCE="${BASH_SOURCE[0]}"
11
+ while [ -L "$SOURCE" ]; do
12
+ DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
13
+ SOURCE="$(readlink "$SOURCE")"
14
+ [[ $SOURCE != /* ]] && SOURCE="$DIR/$SOURCE"
15
+ done
16
+ SCRIPT_DIR="$(cd -P "$(dirname "$SOURCE")" && pwd)"
17
+
18
+ if [ -f "$SCRIPT_DIR/install.sh" ]; then
19
+ CORTEXHAWK_HOME="$SCRIPT_DIR"
20
+ else
21
+ CORTEXHAWK_HOME="$HOME/.cortexhawk"
22
+ fi
23
+ fi
24
+
25
+ INSTALL_SH="$CORTEXHAWK_HOME/install.sh"
26
+
27
+ green() { printf "\033[32m%s\033[0m\n" "$1"; }
28
+ yellow() { printf "\033[33m%s\033[0m\n" "$1"; }
29
+ red() { printf "\033[31m%s\033[0m\n" "$1"; }
30
+
31
+ get_version() {
32
+ grep -m1 '## \[' "$CORTEXHAWK_HOME/CHANGELOG.md" 2>/dev/null | sed 's/.*\[\([^]]*\)\].*/\1/' || echo "unknown"
33
+ }
34
+
35
+ # --- validate command ---
36
+ do_validate() {
37
+ local project_root="${1:-.}"
38
+ local ok=0 fail=0 warn=0
39
+
40
+ echo "CortexHawk Validate"
41
+ echo "======================"
42
+ echo " Project: $(cd "$project_root" && pwd)"
43
+ echo ""
44
+
45
+ # Detect installed targets
46
+ local targets_found=()
47
+ [ -f "$project_root/.claude/.cortexhawk-manifest" ] && targets_found+=("claude")
48
+ [ -f "$project_root/.kimi/.cortexhawk-manifest" ] && targets_found+=("kimi")
49
+ [ -f "$project_root/.codex/.cortexhawk-manifest" ] && targets_found+=("codex")
50
+
51
+ if [ ${#targets_found[@]} -eq 0 ]; then
52
+ red " No CortexHawk installation found in this directory."
53
+ echo " Run: cortexhawk install"
54
+ return 1
55
+ fi
56
+
57
+ echo " Targets found: ${targets_found[*]}"
58
+ echo ""
59
+
60
+ check() {
61
+ local label="$1" result="$2"
62
+ if [ "$result" = "ok" ]; then
63
+ printf " \033[32m[OK]\033[0m %s\n" "$label"
64
+ ok=$((ok + 1))
65
+ elif [ "$result" = "warn" ]; then
66
+ printf " \033[33m[!!]\033[0m %s\n" "$label"
67
+ warn=$((warn + 1))
68
+ else
69
+ printf " \033[31m[FAIL]\033[0m %s\n" "$label"
70
+ fail=$((fail + 1))
71
+ fi
72
+ }
73
+
74
+ for target in "${targets_found[@]}"; do
75
+ echo "--- $target ---"
76
+ local target_dir=""
77
+ case "$target" in
78
+ claude) target_dir="$project_root/.claude" ;;
79
+ kimi) target_dir="$project_root/.kimi" ;;
80
+ codex) target_dir="$project_root/.codex" ;;
81
+ esac
82
+
83
+ # 1. Manifest
84
+ if [ -f "$target_dir/.cortexhawk-manifest" ]; then
85
+ local ver
86
+ ver=$(grep -o '"version": "[^"]*"' "$target_dir/.cortexhawk-manifest" 2>/dev/null | head -1 | cut -d'"' -f4)
87
+ check "Manifest present (v$ver)" "ok"
88
+ else
89
+ check "Manifest missing" "fail"
90
+ fi
91
+
92
+ # 2. Skills count
93
+ local skills_count=0
94
+ if [ -d "$target_dir/skills" ]; then
95
+ skills_count=$(find "$target_dir/skills" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
96
+ fi
97
+ if [ "$skills_count" -gt 0 ]; then
98
+ check "Skills: $skills_count files found" "ok"
99
+ else
100
+ check "Skills: none found in $target_dir/skills/" "fail"
101
+ fi
102
+
103
+ # 3. Target-specific checks
104
+ case "$target" in
105
+ claude)
106
+ # Agents
107
+ local agent_count=0
108
+ [ -d "$target_dir/agents" ] && agent_count=$(find "$target_dir/agents" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
109
+ [ "$agent_count" -gt 0 ] && check "Agents: $agent_count files" "ok" || check "Agents: none found" "fail"
110
+
111
+ # Commands
112
+ local cmd_count=0
113
+ [ -d "$target_dir/commands" ] && cmd_count=$(find "$target_dir/commands" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
114
+ [ "$cmd_count" -gt 0 ] && check "Commands: $cmd_count files" "ok" || check "Commands: none found" "fail"
115
+
116
+ # Hooks
117
+ local hook_count=0
118
+ [ -d "$target_dir/hooks" ] && hook_count=$(find "$target_dir/hooks" -name "*.sh" -type f 2>/dev/null | wc -l | tr -d ' ')
119
+ [ "$hook_count" -gt 0 ] && check "Hooks: $hook_count files" "ok" || check "Hooks: none found" "warn"
120
+
121
+ # settings.json
122
+ if [ -f "$target_dir/settings.json" ]; then
123
+ if python3 -c "import json; json.load(open('$target_dir/settings.json'))" 2>/dev/null || \
124
+ node -e "JSON.parse(require('fs').readFileSync('$target_dir/settings.json'))" 2>/dev/null; then
125
+ check "settings.json valid JSON" "ok"
126
+ else
127
+ check "settings.json invalid JSON" "fail"
128
+ fi
129
+ else
130
+ check "settings.json missing" "warn"
131
+ fi
132
+
133
+ # Modes
134
+ local mode_count=0
135
+ [ -d "$target_dir/modes" ] && mode_count=$(find "$target_dir/modes" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
136
+ [ "$mode_count" -gt 0 ] && check "Modes: $mode_count files" "ok" || check "Modes: none found" "warn"
137
+ ;;
138
+
139
+ kimi)
140
+ # AGENTS.md at project root
141
+ if [ -f "$project_root/AGENTS.md" ] && grep -q "CortexHawk" "$project_root/AGENTS.md" 2>/dev/null; then
142
+ check "AGENTS.md in project root" "ok"
143
+ else
144
+ check "AGENTS.md missing or not CortexHawk" "fail"
145
+ fi
146
+
147
+ # Commands as skills
148
+ local cmd_skills=0
149
+ cmd_skills=$(find "$target_dir/skills/cmd-"* -maxdepth 0 -type d 2>/dev/null | wc -l | tr -d ' ')
150
+ [ "$cmd_skills" -gt 0 ] && check "Commands as skills: $cmd_skills" "ok" || check "Commands as skills: none" "fail"
151
+
152
+ # Hooks as skills
153
+ local hook_skills=0
154
+ hook_skills=$(find "$target_dir/skills/hook-"* -maxdepth 0 -type d 2>/dev/null | wc -l | tr -d ' ')
155
+ [ "$hook_skills" -gt 0 ] && check "Hooks as skills: $hook_skills" "ok" || check "Hooks as skills: none" "warn"
156
+
157
+ # Agents as skills
158
+ local agent_skills=0
159
+ agent_skills=$(find "$target_dir/skills/agent-"* -maxdepth 0 -type d 2>/dev/null | wc -l | tr -d ' ')
160
+ [ "$agent_skills" -gt 0 ] && check "Agents as skills: $agent_skills" "ok" || check "Agents as skills: none" "fail"
161
+
162
+ # Modes as skills
163
+ local mode_skills=0
164
+ [ -d "$target_dir/skills/modes" ] && mode_skills=$(find "$target_dir/skills/modes" -maxdepth 1 -type d 2>/dev/null | wc -l | tr -d ' ')
165
+ mode_skills=$((mode_skills - 1)) 2>/dev/null || mode_skills=0
166
+ [ "$mode_skills" -gt 0 ] && check "Modes as skills: $mode_skills" "ok" || check "Modes as skills: none" "warn"
167
+
168
+ # .envrc
169
+ if [ -f "$project_root/.envrc" ] && grep -q "KIMI_SHARE_DIR" "$project_root/.envrc" 2>/dev/null; then
170
+ check ".envrc with KIMI_SHARE_DIR" "ok"
171
+ else
172
+ check ".envrc missing KIMI_SHARE_DIR (sessions will use global)" "warn"
173
+ fi
174
+ ;;
175
+
176
+ codex)
177
+ local agents_dir="$project_root/.agents"
178
+
179
+ # AGENTS.md at project root
180
+ if [ -f "$project_root/AGENTS.md" ] && grep -q "CortexHawk" "$project_root/AGENTS.md" 2>/dev/null; then
181
+ check "AGENTS.md in project root" "ok"
182
+ else
183
+ check "AGENTS.md missing or not CortexHawk" "fail"
184
+ fi
185
+
186
+ # .agents/ directory
187
+ if [ -d "$agents_dir/skills" ]; then
188
+ local codex_skills=0
189
+ codex_skills=$(find "$agents_dir/skills" -name "*.md" -type f 2>/dev/null | wc -l | tr -d ' ')
190
+ check ".agents/skills/: $codex_skills files" "ok"
191
+ else
192
+ check ".agents/skills/ missing" "fail"
193
+ fi
194
+
195
+ # config.toml
196
+ if [ -f "$target_dir/config.toml" ]; then
197
+ check "config.toml present" "ok"
198
+ else
199
+ check "config.toml missing" "fail"
200
+ fi
201
+ ;;
202
+ esac
203
+ echo ""
204
+ done
205
+
206
+ # Shared checks
207
+ echo "--- shared ---"
208
+
209
+ # .gitignore
210
+ if [ -f "$project_root/.gitignore" ]; then
211
+ local ignored=0
212
+ for target in "${targets_found[@]}"; do
213
+ case "$target" in
214
+ claude) grep -qx ".claude/" "$project_root/.gitignore" 2>/dev/null && ignored=$((ignored + 1)) ;;
215
+ kimi) grep -qx ".kimi/" "$project_root/.gitignore" 2>/dev/null && ignored=$((ignored + 1)) ;;
216
+ codex) grep -qx ".codex/" "$project_root/.gitignore" 2>/dev/null && ignored=$((ignored + 1)) ;;
217
+ esac
218
+ done
219
+ [ "$ignored" -eq "${#targets_found[@]}" ] && check "All targets in .gitignore" "ok" || check "Some targets missing from .gitignore" "warn"
220
+ else
221
+ check ".gitignore missing" "warn"
222
+ fi
223
+
224
+ # docs/ workspace
225
+ if [ -d "$project_root/docs" ]; then
226
+ check "docs/ workspace present" "ok"
227
+ else
228
+ check "docs/ workspace missing" "warn"
229
+ fi
230
+
231
+ # git-workflow.conf
232
+ local found_conf=false
233
+ for target in "${targets_found[@]}"; do
234
+ case "$target" in
235
+ claude) [ -f "$project_root/.claude/git-workflow.conf" ] && found_conf=true ;;
236
+ esac
237
+ done
238
+ [ "$found_conf" = true ] && check "git-workflow.conf configured" "ok" || check "git-workflow.conf not found" "warn"
239
+
240
+ echo ""
241
+ echo "============================="
242
+ echo " OK: $ok | WARN: $warn | FAIL: $fail"
243
+ if [ "$fail" -gt 0 ]; then
244
+ red " Some checks failed. Run 'cortexhawk doctor' or reinstall."
245
+ return 1
246
+ elif [ "$warn" -gt 0 ]; then
247
+ yellow " All critical checks passed. Some warnings to review."
248
+ else
249
+ green " All checks passed!"
250
+ fi
251
+ }
252
+
253
+ # Verify CortexHawk source exists
254
+ check_home() {
255
+ if [ ! -f "$INSTALL_SH" ]; then
256
+ red "CortexHawk not found in $CORTEXHAWK_HOME"
257
+ echo ""
258
+ echo "Install with:"
259
+ echo " git clone https://github.com/Spechawk94/CortexHawk.git ~/.cortexhawk"
260
+ echo ""
261
+ echo "Or set CORTEXHAWK_HOME to your clone location."
262
+ exit 1
263
+ fi
264
+ }
265
+
266
+ show_help() {
267
+ echo "CortexHawk CLI v$(get_version)"
268
+ echo ""
269
+ echo "Usage: cortexhawk <command> [options]"
270
+ echo ""
271
+ echo "Setup:"
272
+ echo " init Interactive setup wizard (auto-detects CLIs)"
273
+ echo " install [opts] Install CortexHawk (--target, --profile, --global, --pack)"
274
+ echo " update [--force] Update existing installation"
275
+ echo " uninstall Remove CortexHawk installation"
276
+ echo ""
277
+ echo "Diagnostics:"
278
+ echo " validate [path] Verify skills/agents discovery per target"
279
+ echo " doctor Check installation health"
280
+ echo " stats Show installation overview"
281
+ echo " quickstart Getting-started guide"
282
+ echo " demo Create sandbox project with intentional bugs"
283
+ echo ""
284
+ echo "Skills:"
285
+ echo " search <keyword> Search community skills (SkillsMP or local)"
286
+ echo " add-skill <url> Install skill from GitHub"
287
+ echo " publish <path> Publish local skill to GitHub"
288
+ echo ""
289
+ echo "Snapshots:"
290
+ echo " snapshot [--portable] Save installation state"
291
+ echo " snapshots List saved snapshots"
292
+ echo " restore <file> Restore from snapshot"
293
+ echo " diff [file] [file] Compare states"
294
+ echo ""
295
+ echo "Hooks:"
296
+ echo " hooks List all hooks with status"
297
+ echo " enable-hook <name> Enable a hook"
298
+ echo " disable-hook <name> Disable a hook"
299
+ echo " test-hooks Dry-run hooks with synthetic inputs"
300
+ echo ""
301
+ echo "Other:"
302
+ echo " self-update Update CortexHawk source (git pull)"
303
+ echo " version Show version"
304
+ echo " help Show this help"
305
+ echo ""
306
+ echo "All install.sh flags also work: cortexhawk --dry-run --target kimi"
307
+ echo ""
308
+ echo "CORTEXHAWK_HOME=$CORTEXHAWK_HOME"
309
+ }
310
+
311
+ # Main dispatcher
312
+ cmd="${1:-help}"
313
+
314
+ case "$cmd" in
315
+ init)
316
+ check_home
317
+ shift
318
+ bash "$INSTALL_SH" --init "$@"
319
+ ;;
320
+ install)
321
+ check_home
322
+ shift
323
+ bash "$INSTALL_SH" "$@"
324
+ ;;
325
+ update)
326
+ check_home
327
+ shift
328
+ bash "$INSTALL_SH" --update "$@"
329
+ ;;
330
+ uninstall)
331
+ check_home
332
+ shift
333
+ bash "$INSTALL_SH" --uninstall "$@"
334
+ ;;
335
+ validate)
336
+ shift
337
+ do_validate "$@"
338
+ ;;
339
+ doctor)
340
+ check_home
341
+ shift
342
+ bash "$INSTALL_SH" --doctor "$@"
343
+ ;;
344
+ stats)
345
+ check_home
346
+ shift
347
+ bash "$INSTALL_SH" --stats "$@"
348
+ ;;
349
+ quickstart)
350
+ check_home
351
+ shift
352
+ bash "$INSTALL_SH" --quickstart "$@"
353
+ ;;
354
+ demo)
355
+ check_home
356
+ shift
357
+ bash "$INSTALL_SH" --demo "$@"
358
+ ;;
359
+ search)
360
+ check_home
361
+ shift
362
+ bash "$INSTALL_SH" --search "$@"
363
+ ;;
364
+ add-skill)
365
+ check_home
366
+ shift
367
+ bash "$INSTALL_SH" --add-skill "$@"
368
+ ;;
369
+ publish)
370
+ check_home
371
+ shift
372
+ bash "$INSTALL_SH" --publish-skill "$@"
373
+ ;;
374
+ snapshot)
375
+ check_home
376
+ shift
377
+ bash "$INSTALL_SH" --snapshot "$@"
378
+ ;;
379
+ snapshots)
380
+ check_home
381
+ shift
382
+ bash "$INSTALL_SH" --snapshots "$@"
383
+ ;;
384
+ restore)
385
+ check_home
386
+ shift
387
+ bash "$INSTALL_SH" --restore "$@"
388
+ ;;
389
+ diff)
390
+ check_home
391
+ shift
392
+ bash "$INSTALL_SH" --diff "$@"
393
+ ;;
394
+ hooks)
395
+ check_home
396
+ shift
397
+ bash "$INSTALL_SH" --list-hooks "$@"
398
+ ;;
399
+ enable-hook)
400
+ check_home
401
+ shift
402
+ bash "$INSTALL_SH" --enable-hook "$@"
403
+ ;;
404
+ disable-hook)
405
+ check_home
406
+ shift
407
+ bash "$INSTALL_SH" --disable-hook "$@"
408
+ ;;
409
+ test-hooks)
410
+ check_home
411
+ shift
412
+ bash "$INSTALL_SH" --test-hooks "$@"
413
+ ;;
414
+ self-update)
415
+ check_home
416
+ if [ ! -d "$CORTEXHAWK_HOME/.git" ]; then
417
+ yellow "CortexHawk installed via npm — use: npm update -g cortexhawk"
418
+ exit 0
419
+ fi
420
+ echo "Updating CortexHawk source..."
421
+ cd "$CORTEXHAWK_HOME"
422
+ local_version=$(get_version)
423
+ git pull --quiet
424
+ new_version=$(get_version)
425
+ if [ "$local_version" = "$new_version" ]; then
426
+ green "Already up to date (v$new_version)"
427
+ else
428
+ green "Updated: v$local_version → v$new_version"
429
+ echo "Run 'cortexhawk update' to apply changes to your projects."
430
+ fi
431
+ ;;
432
+ version|--version|-v)
433
+ check_home
434
+ echo "cortexhawk v$(get_version)"
435
+ echo "Source: $CORTEXHAWK_HOME"
436
+ ;;
437
+ help|--help|-h)
438
+ show_help
439
+ ;;
440
+ -*)
441
+ # Raw flags passthrough to install.sh
442
+ check_home
443
+ bash "$INSTALL_SH" "$@"
444
+ ;;
445
+ *)
446
+ red "Unknown command: $cmd"
447
+ echo "Run 'cortexhawk help' for usage."
448
+ exit 1
449
+ ;;
450
+ esac
@@ -0,0 +1,67 @@
1
+ #!/bin/bash
2
+ # agent-analytics — Track agent invocations via docs/ writes
3
+ # Hook type: PostToolUse (Write|Edit)
4
+
5
+ # Read file_path from stdin JSON (Claude Code hook protocol)
6
+ if [ -n "$CORTEXHAWK_FILE_PATH" ]; then
7
+ FILE_PATH="$CORTEXHAWK_FILE_PATH"
8
+ else
9
+ INPUT=$(cat)
10
+ FILE_PATH=$(printf '%s' "$INPUT" | grep -o '"file_path" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
11
+ fi
12
+
13
+ if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
14
+ exit 0
15
+ fi
16
+
17
+ # Reject directory traversal or suspicious characters
18
+ if [[ "$FILE_PATH" =~ \.\. ]] || [[ "$FILE_PATH" =~ [^a-zA-Z0-9/_.\-] ]]; then
19
+ exit 0
20
+ fi
21
+
22
+ # Only track docs/ writes
23
+ case "$FILE_PATH" in
24
+ docs/*) ;;
25
+ *) exit 0 ;;
26
+ esac
27
+
28
+ # Skip _shared.md (auto-generated by session-start)
29
+ case "$FILE_PATH" in
30
+ docs/.context/_shared.md) exit 0 ;;
31
+ esac
32
+
33
+ # Map directory to agent
34
+ AGENT=""
35
+ case "$FILE_PATH" in
36
+ docs/brainstorms/*) AGENT="brainstormer" ;;
37
+ docs/plans/*) AGENT="planner" ;;
38
+ docs/decisions/*) AGENT="architect" ;;
39
+ docs/research/*) AGENT="researcher" ;;
40
+ docs/audits/*) AGENT="security-auditor" ;;
41
+ docs/conversations/*) AGENT="copywriter" ;;
42
+ docs/chains/*) AGENT="chain" ;;
43
+ docs/.context/*) AGENT="context-update" ;;
44
+ *) exit 0 ;;
45
+ esac
46
+
47
+ # Compute metrics
48
+ SIZE_BYTES=$(wc -c < "$FILE_PATH" | tr -d ' ')
49
+ ESTIMATED_TOKENS=$((SIZE_BYTES / 4))
50
+ TIMESTAMP=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
51
+ TODAY=$(date +"%Y-%m-%d")
52
+
53
+ # Ensure metrics directory exists
54
+ METRICS_DIR="docs/.metrics"
55
+ mkdir -p "$METRICS_DIR"
56
+
57
+ # Escape strings for safe JSON output
58
+ json_escape() { printf '%s' "$1" | sed 's/\\/\\\\/g; s/"/\\"/g'; }
59
+
60
+ # Append JSONL entry
61
+ FILENAME=$(json_escape "$(basename "$FILE_PATH")")
62
+ FILEPATH_ESC=$(json_escape "$FILE_PATH")
63
+ printf '{"timestamp":"%s","agent":"%s","file":"%s","path":"%s","size_bytes":%d,"estimated_tokens":%d}\n' \
64
+ "$TIMESTAMP" "$AGENT" "$FILENAME" "$FILEPATH_ESC" "$SIZE_BYTES" "$ESTIMATED_TOKENS" \
65
+ >> "$METRICS_DIR/$TODAY.jsonl"
66
+
67
+ exit 0
@@ -0,0 +1,56 @@
1
+ #!/bin/bash
2
+ # branch-guard — Prevents direct push to protected branches
3
+ # Hook type: PreToolUse (Bash)
4
+
5
+ # Read command from stdin JSON (Claude Code hook protocol)
6
+ if [ -n "$CORTEXHAWK_COMMAND" ]; then
7
+ CMD="$CORTEXHAWK_COMMAND"
8
+ else
9
+ INPUT=$(cat)
10
+ CMD=$(printf '%s' "$INPUT" | grep -o '"command" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
11
+ fi
12
+
13
+ if [[ -z "$CMD" ]]; then
14
+ exit 0
15
+ fi
16
+
17
+ PROTECTED_BRANCHES=("main" "master" "production" "release")
18
+
19
+ # Load git workflow config — allow direct-main push if configured
20
+ CONF_FILE="$(git rev-parse --show-toplevel 2>/dev/null)/.claude/git-workflow.conf"
21
+ if [[ -f "$CONF_FILE" ]]; then
22
+ _BRANCHING=$(grep '^BRANCHING=' "$CONF_FILE" | cut -d= -f2)
23
+ if [[ "$_BRANCHING" == "direct-main" ]]; then
24
+ PROTECTED_BRANCHES=("master" "production" "release")
25
+ fi
26
+ fi
27
+
28
+ # Check for git push to protected branches
29
+ if echo "$CMD" | grep -qE 'git\s+push'; then
30
+ CURRENT_BRANCH=$(git branch --show-current 2>/dev/null)
31
+
32
+ for branch in "${PROTECTED_BRANCHES[@]}"; do
33
+ # Direct push: git push origin main
34
+ if echo "$CMD" | grep -qE "git\s+push\s+\S+\s+${branch}(\s|$)"; then
35
+ echo "BLOCKED: Direct push to '$branch' denied by branch-guard" >&2
36
+ echo "Use a feature branch and create a PR instead" >&2
37
+ exit 2
38
+ fi
39
+
40
+ # Push current branch if it's protected: git push (while on main)
41
+ if [[ "$CURRENT_BRANCH" == "$branch" ]]; then
42
+ echo "BLOCKED: Push from protected branch '$branch' denied by branch-guard" >&2
43
+ echo "Use a feature branch and create a PR instead" >&2
44
+ exit 2
45
+ fi
46
+ done
47
+
48
+ # Block force push
49
+ if echo "$CMD" | grep -qE 'git\s+push\s+.*(-f|--force|--force-with-lease)'; then
50
+ echo "BLOCKED: Force push denied by branch-guard" >&2
51
+ echo "Force push can destroy remote history — use with extreme caution" >&2
52
+ exit 2
53
+ fi
54
+ fi
55
+
56
+ exit 0
@@ -0,0 +1,84 @@
1
+ #!/bin/bash
2
+ # codex-dispatcher.sh — Bridges Codex after_tool_use events to CortexHawk PostToolUse hooks
3
+ # Reads JSON payload from stdin, extracts modified files, dispatches to hooks
4
+ # Hook type: Codex after_tool_use
5
+
6
+ # Read payload from stdin
7
+ PAYLOAD=$(cat)
8
+
9
+ # Require jq for JSON parsing
10
+ if ! command -v jq >/dev/null 2>&1; then
11
+ exit 0
12
+ fi
13
+
14
+ # Extract fields from payload
15
+ EVENT_TYPE=$(echo "$PAYLOAD" | jq -r '.hook_event.event_type // empty')
16
+ if [ "$EVENT_TYPE" != "after_tool_use" ]; then
17
+ exit 0
18
+ fi
19
+
20
+ SUCCESS=$(echo "$PAYLOAD" | jq -r '.hook_event.success // false')
21
+ if [ "$SUCCESS" != "true" ]; then
22
+ exit 0
23
+ fi
24
+
25
+ MUTATING=$(echo "$PAYLOAD" | jq -r '.hook_event.mutating // false')
26
+ if [ "$MUTATING" != "true" ]; then
27
+ exit 0
28
+ fi
29
+
30
+ CWD=$(echo "$PAYLOAD" | jq -r '.cwd // empty')
31
+
32
+ # Extract modified file paths — two strategies:
33
+ # 1. From output_preview (apply_patch output: "M filename" lines)
34
+ # 2. From tool_input (apply_patch input: "*** Update File: filename" lines)
35
+ FILES=""
36
+
37
+ # Strategy 1: output_preview → fromjson → .output → grep "^[MA] "
38
+ OUTPUT_FILES=$(echo "$PAYLOAD" | jq -r '(.hook_event.output_preview | fromjson).output // empty' 2>/dev/null \
39
+ | grep -E '^[MA] ' | sed 's/^[MA] //' || true)
40
+ if [ -n "$OUTPUT_FILES" ]; then
41
+ FILES="$OUTPUT_FILES"
42
+ fi
43
+
44
+ # Strategy 2: tool_input.input → grep "Update File:"
45
+ if [ -z "$FILES" ]; then
46
+ INPUT_FILES=$(echo "$PAYLOAD" | jq -r '.hook_event.tool_input.input // empty' 2>/dev/null \
47
+ | grep 'Update File:' | sed 's/.*Update File: *//' || true)
48
+ FILES="$INPUT_FILES"
49
+ fi
50
+
51
+ if [ -z "$FILES" ]; then
52
+ exit 0
53
+ fi
54
+
55
+ # Locate hooks directory (relative to this script)
56
+ HOOKS_DIR="$(cd "$(dirname "$0")" && pwd)"
57
+
58
+ # Dispatch each modified file to PostToolUse hooks
59
+ while IFS= read -r file; do
60
+ [ -z "$file" ] && continue
61
+
62
+ # Resolve to absolute path
63
+ if [[ "$file" != /* ]]; then
64
+ file="$CWD/$file"
65
+ fi
66
+
67
+ # Pass file path via env var (hooks read CORTEXHAWK_FILE_PATH or stdin JSON)
68
+ export CORTEXHAWK_FILE_PATH="$file"
69
+
70
+ # self-review
71
+ [ -f "$HOOKS_DIR/self-review.sh" ] && bash "$HOOKS_DIR/self-review.sh" < /dev/null 2>/dev/null || true
72
+
73
+ # dependency-check
74
+ [ -f "$HOOKS_DIR/dependency-check.sh" ] && bash "$HOOKS_DIR/dependency-check.sh" < /dev/null 2>/dev/null || true
75
+
76
+ # test-reminder
77
+ [ -f "$HOOKS_DIR/test-reminder.sh" ] && bash "$HOOKS_DIR/test-reminder.sh" < /dev/null 2>/dev/null || true
78
+
79
+ # agent-analytics
80
+ [ -f "$HOOKS_DIR/agent-analytics.sh" ] && bash "$HOOKS_DIR/agent-analytics.sh" < /dev/null 2>/dev/null || true
81
+
82
+ done <<< "$FILES"
83
+
84
+ exit 0