cortexhawk 3.1.0 → 3.1.1
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/CHANGELOG.md +10 -0
- package/README.md +13 -3
- package/commands/chain.md +10 -1
- package/commands/pulse.md +11 -1
- package/cortexhawk +90 -0
- package/hooks/branch-guard.sh +6 -1
- package/hooks/commit-guard.sh +16 -3
- package/hooks/file-guard.sh +40 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,13 @@
|
|
|
3
3
|
All notable changes to CortexHawk are documented here.
|
|
4
4
|
Format: [Keep a Changelog](https://keepachangelog.com/)
|
|
5
5
|
|
|
6
|
+
## [3.1.1] - 2026-02-15
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
- `branch-guard` / `commit-guard` hooks: JSON parsing via `jq` with regex fallback — fixes false "hook error" on commands containing quotes or HEREDOC
|
|
10
|
+
- `commit-guard`: multi-format commit message extraction (HEREDOC, single/double quotes)
|
|
11
|
+
- `file-guard`: match on basename only — `*secret*`/`*credentials*` no longer false-positive on legitimate files (e.g., `oauth_service.py`); `.env.example`/`.env.sample`/`.env.template` whitelisted; `docker-compose*.yml` unblocked
|
|
12
|
+
|
|
6
13
|
## [3.1.0] - 2026-02-14
|
|
7
14
|
|
|
8
15
|
### Added
|
|
@@ -11,6 +18,9 @@ Format: [Keep a Changelog](https://keepachangelog.com/)
|
|
|
11
18
|
- `--target auto`: auto-detects installed CLIs (claude, kimi, codex) and installs for all found — no need to specify which CLIs are available
|
|
12
19
|
- `cortexhawk validate [path]`: post-install diagnostic that verifies skills/agents/commands/hooks discovery per target — checks manifest, file counts, settings.json validity, .gitignore coverage
|
|
13
20
|
- npm distribution: `npm install -g cortexhawk` installs the CLI globally — auto-resolves `CORTEXHAWK_HOME` from symlinked binary, `self-update` detects npm install and suggests `npm update -g`
|
|
21
|
+
- `/pulse --unused`: detects installed skills that don't match the project's tech stack — scans for technology markers, maps framework skills to stacks, reports potentially unused skills
|
|
22
|
+
- `/chain --browse`: lists all available chain presets (built-in + custom from `.cortexhawk-chains.yml`) and recent chain runs from `docs/chains/`
|
|
23
|
+
- `cortexhawk sync [path] [from]`: syncs modified skills across installed CLI targets — compares checksums, copies changed skills, skips generated content (cmd-*, hook-*, agent-*)
|
|
14
24
|
|
|
15
25
|
## [3.0.0] - 2026-02-14
|
|
16
26
|
|
package/README.md
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/Spechawk94/CortexHawk/stargazers)
|
|
4
4
|
[](LICENSE)
|
|
5
|
-
[](CHANGELOG.md)
|
|
6
|
+
[](https://www.npmjs.com/package/cortexhawk)
|
|
6
7
|
[](https://skillsmp.com)
|
|
7
8
|
[](#whats-inside)
|
|
8
9
|
|
|
@@ -10,19 +11,28 @@ An open-source, community-driven development toolkit for Claude Code.
|
|
|
10
11
|
|
|
11
12
|
CortexHawk provides a modular collection of optimized agents, skills, commands, hooks, and behavioral modes that transform Claude Code into a full-stack development team. Every prompt has been written for maximum efficiency — less token bloat, sharper instructions, better agent coordination.
|
|
12
13
|
|
|
13
|
-
### What's New in v3.
|
|
14
|
+
### What's New in v3.1
|
|
15
|
+
|
|
16
|
+
- **`npm install -g cortexhawk`** — available on npm, auto-resolves source from symlinked binary
|
|
17
|
+
- **`cortexhawk` CLI wrapper** — clean subcommands (init, install, update, doctor, validate, search, snapshot, etc.) instead of `bash install.sh --flags`
|
|
18
|
+
- **`--target auto`** — auto-detects installed CLIs (claude, kimi, codex) and installs for all found
|
|
19
|
+
- **`cortexhawk validate`** — post-install diagnostic verifying skills/agents discovery per target
|
|
20
|
+
|
|
21
|
+
<details>
|
|
22
|
+
<summary>v3.0 changes</summary>
|
|
14
23
|
|
|
15
24
|
- **`--init` wizard overhaul** — reordered flow with git workflow config, auto `git init` + `.gitignore` creation, branching strategies (direct-main, dev-branch, git-flow)
|
|
16
25
|
- **`/bootstrap --smart`** — researcher agent scans roadmap, compares stacks, recommends, then scaffolds
|
|
17
26
|
- **Post-install gitignore** — auto-adds `.claude/`, `.kimi/`, `.codex/` to `.gitignore`, asks about `docs/`
|
|
18
27
|
- **`--update` checksum detection** — compares file checksums instead of just version numbers to detect changes
|
|
19
28
|
- **Kimi CLI overhaul** — agents, commands, hooks all converted to skills; AGENTS.md at project root; MCP optional; auto `.envrc` for local install
|
|
20
|
-
- **Codex CLI fixes** — config.toml format fixes (flat model key, save-all persistence)
|
|
21
29
|
- **`--demo` flag** — sandbox project in `/tmp/` with intentional bugs for testing
|
|
22
30
|
- **`/upgrade` command** — check for updates, show changelog diff, propose `--update`
|
|
23
31
|
- **`--publish-skill`** — publish local skills to GitHub with auto-generated README
|
|
24
32
|
- **Cursor CLI removed** — too unstable for maintained support
|
|
25
33
|
|
|
34
|
+
</details>
|
|
35
|
+
|
|
26
36
|
## Quick Start
|
|
27
37
|
|
|
28
38
|
```bash
|
package/commands/chain.md
CHANGED
|
@@ -11,7 +11,7 @@ Execute a declared sequence of agents with automatic context passing. Topic: `$A
|
|
|
11
11
|
|
|
12
12
|
**Custom presets**: Define in `.cortexhawk-chains.yml` at project root — custom presets override built-in presets with the same name
|
|
13
13
|
|
|
14
|
-
**Flags**: `--gate` = pause between steps | `--copy` = physical copy to plans/ | `--replay <slug>` = re-run a previous chain
|
|
14
|
+
**Flags**: `--gate` = pause between steps | `--copy` = physical copy to plans/ | `--replay <slug>` = re-run a previous chain | `--browse` = list all available presets + recent chains
|
|
15
15
|
|
|
16
16
|
**Mapping**: plan=planner, build=implementer, test=tester, review=reviewer, scan=security-auditor, debug=debugger, doc=docs-manager, ship=git-manager, refactor=code-simplifier, research=researcher
|
|
17
17
|
|
|
@@ -38,6 +38,15 @@ When detected in a step's output:
|
|
|
38
38
|
2. Save as `{N}a-{delegated-agent}.md` (sub-step)
|
|
39
39
|
3. Feed original output + delegation result to the next step
|
|
40
40
|
|
|
41
|
+
## Browse mode (`--browse`)
|
|
42
|
+
|
|
43
|
+
List all available chains from 3 sources:
|
|
44
|
+
1. **Built-in presets** — default, security, ship (table: name, sequence, description)
|
|
45
|
+
2. **Custom presets** — read `.cortexhawk-chains.yml` if present (table: name, sequence, description, gate)
|
|
46
|
+
3. **Recent chains** — scan `docs/chains/*/SUMMARY.md`, extract date/slug/sequence/result (table: date, slug, sequence, status — last 10)
|
|
47
|
+
|
|
48
|
+
Output all 3 tables. End with usage hint: `/chain <preset> <topic>`
|
|
49
|
+
|
|
41
50
|
## Rules
|
|
42
51
|
|
|
43
52
|
- Max 8 agents per chain (delegations count toward this limit)
|
package/commands/pulse.md
CHANGED
|
@@ -7,7 +7,7 @@ description: Project health dashboard — code quality metrics at a glance.
|
|
|
7
7
|
|
|
8
8
|
Activate the **project-manager** agent in health-check mode. Scope: `$ARGUMENTS`
|
|
9
9
|
|
|
10
|
-
**Flags**: `--history Nd` = show metrics trends over N days
|
|
10
|
+
**Flags**: `--history Nd` = show metrics trends over N days | `--unused` = detect potentially unused skills
|
|
11
11
|
|
|
12
12
|
## Standard mode (no flag)
|
|
13
13
|
|
|
@@ -44,3 +44,13 @@ Avg: [tokens/day] tokens/day, [duration] min/session
|
|
|
44
44
|
```
|
|
45
45
|
|
|
46
46
|
If scope is specified, limit checks to those files/directories.
|
|
47
|
+
|
|
48
|
+
## Unused skills mode (`--unused`)
|
|
49
|
+
|
|
50
|
+
Detect installed skills that don't match the project's tech stack.
|
|
51
|
+
|
|
52
|
+
1. **List installed skills** from `.claude/skills/` (or target equivalent)
|
|
53
|
+
2. **Detect stack** — scan for: `package.json`/`*.ts` → js/ts, `requirements.txt`/`*.py` → python, `go.mod` → go, `Cargo.toml` → rust, `Dockerfile` → docker, `*.svelte` → svelte, `next.config.*` → nextjs, `tailwind.config.*` → tailwind
|
|
54
|
+
3. **Map framework skills** — `frameworks/react` → js, `frameworks/nextjs` → nextjs, `frameworks/sveltekit` → svelte, `frameworks/fastapi` → python, `frameworks/python` → python, `frameworks/typescript` → ts, `frameworks/tailwindcss` → tailwind, `devops/docker` → docker
|
|
55
|
+
4. **Universal skills** (security/\*, quality/\*, testing/\*, meta/\*, databases/\*, workflow/\*, optimization/\*) → always relevant, skip
|
|
56
|
+
5. **Output** — table with skill, required stack, OK/UNUSED status. Count unused. Suggest `cortexhawk install --profile autodetect`
|
package/cortexhawk
CHANGED
|
@@ -250,6 +250,91 @@ do_validate() {
|
|
|
250
250
|
fi
|
|
251
251
|
}
|
|
252
252
|
|
|
253
|
+
# --- sync command ---
|
|
254
|
+
do_sync() {
|
|
255
|
+
local project_root="${1:-.}"
|
|
256
|
+
local from_target="${2:-}"
|
|
257
|
+
|
|
258
|
+
# Detect installed targets
|
|
259
|
+
local targets=()
|
|
260
|
+
[ -f "$project_root/.claude/.cortexhawk-manifest" ] && targets+=("claude")
|
|
261
|
+
[ -f "$project_root/.kimi/.cortexhawk-manifest" ] && targets+=("kimi")
|
|
262
|
+
[ -f "$project_root/.codex/.cortexhawk-manifest" ] && targets+=("codex")
|
|
263
|
+
|
|
264
|
+
if [ "${#targets[@]}" -lt 2 ]; then
|
|
265
|
+
yellow "Sync requires at least 2 targets installed. Found: ${targets[*]:-none}"
|
|
266
|
+
exit 1
|
|
267
|
+
fi
|
|
268
|
+
|
|
269
|
+
# Determine source target
|
|
270
|
+
if [ -z "$from_target" ]; then
|
|
271
|
+
from_target="${targets[0]}"
|
|
272
|
+
fi
|
|
273
|
+
|
|
274
|
+
# Map target to skills directory
|
|
275
|
+
target_skills_dir() {
|
|
276
|
+
case "$1" in
|
|
277
|
+
claude) echo "$project_root/.claude/skills" ;;
|
|
278
|
+
kimi) echo "$project_root/.kimi/skills" ;;
|
|
279
|
+
codex) echo "$project_root/.agents/skills" ;;
|
|
280
|
+
esac
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
local src_dir
|
|
284
|
+
src_dir=$(target_skills_dir "$from_target")
|
|
285
|
+
if [ ! -d "$src_dir" ]; then
|
|
286
|
+
red "Source skills dir not found: $src_dir"
|
|
287
|
+
exit 1
|
|
288
|
+
fi
|
|
289
|
+
|
|
290
|
+
echo "CortexHawk Sync"
|
|
291
|
+
echo "==============="
|
|
292
|
+
echo " Source: $from_target ($src_dir)"
|
|
293
|
+
echo " Targets: ${targets[*]}"
|
|
294
|
+
echo ""
|
|
295
|
+
|
|
296
|
+
local synced=0
|
|
297
|
+
for target in "${targets[@]}"; do
|
|
298
|
+
[ "$target" = "$from_target" ] && continue
|
|
299
|
+
local dst_dir
|
|
300
|
+
dst_dir=$(target_skills_dir "$target")
|
|
301
|
+
[ ! -d "$dst_dir" ] && continue
|
|
302
|
+
|
|
303
|
+
# Sync each skill category/name
|
|
304
|
+
for skill_file in "$src_dir"/*/SKILL.md "$src_dir"/*/*/SKILL.md; do
|
|
305
|
+
[ ! -f "$skill_file" ] && continue
|
|
306
|
+
local rel_path="${skill_file#"$src_dir/"}"
|
|
307
|
+
local dst_file="$dst_dir/$rel_path"
|
|
308
|
+
|
|
309
|
+
# Skip generated skills (cmd-*, hook-*, agent-*, modes/)
|
|
310
|
+
case "$rel_path" in
|
|
311
|
+
cmd-*|hook-*|agent-*|modes/*) continue ;;
|
|
312
|
+
esac
|
|
313
|
+
|
|
314
|
+
# Compare checksums
|
|
315
|
+
if [ -f "$dst_file" ]; then
|
|
316
|
+
local src_md5 dst_md5
|
|
317
|
+
src_md5=$(md5sum "$skill_file" 2>/dev/null | cut -d' ' -f1)
|
|
318
|
+
dst_md5=$(md5sum "$dst_file" 2>/dev/null | cut -d' ' -f1)
|
|
319
|
+
[ "$src_md5" = "$dst_md5" ] && continue
|
|
320
|
+
fi
|
|
321
|
+
|
|
322
|
+
# Copy
|
|
323
|
+
mkdir -p "$(dirname "$dst_file")"
|
|
324
|
+
cp "$skill_file" "$dst_file"
|
|
325
|
+
echo " [SYNC] $rel_path → $target"
|
|
326
|
+
synced=$((synced + 1))
|
|
327
|
+
done
|
|
328
|
+
done
|
|
329
|
+
|
|
330
|
+
echo ""
|
|
331
|
+
if [ "$synced" -eq 0 ]; then
|
|
332
|
+
green "All targets already in sync."
|
|
333
|
+
else
|
|
334
|
+
green "Synced $synced file(s)."
|
|
335
|
+
fi
|
|
336
|
+
}
|
|
337
|
+
|
|
253
338
|
# Verify CortexHawk source exists
|
|
254
339
|
check_home() {
|
|
255
340
|
if [ ! -f "$INSTALL_SH" ]; then
|
|
@@ -276,6 +361,7 @@ show_help() {
|
|
|
276
361
|
echo ""
|
|
277
362
|
echo "Diagnostics:"
|
|
278
363
|
echo " validate [path] Verify skills/agents discovery per target"
|
|
364
|
+
echo " sync [path] [from] Sync skills across installed CLI targets"
|
|
279
365
|
echo " doctor Check installation health"
|
|
280
366
|
echo " stats Show installation overview"
|
|
281
367
|
echo " quickstart Getting-started guide"
|
|
@@ -336,6 +422,10 @@ case "$cmd" in
|
|
|
336
422
|
shift
|
|
337
423
|
do_validate "$@"
|
|
338
424
|
;;
|
|
425
|
+
sync)
|
|
426
|
+
shift
|
|
427
|
+
do_sync "$@"
|
|
428
|
+
;;
|
|
339
429
|
doctor)
|
|
340
430
|
check_home
|
|
341
431
|
shift
|
package/hooks/branch-guard.sh
CHANGED
|
@@ -7,7 +7,12 @@ if [ -n "$CORTEXHAWK_COMMAND" ]; then
|
|
|
7
7
|
CMD="$CORTEXHAWK_COMMAND"
|
|
8
8
|
else
|
|
9
9
|
INPUT=$(cat)
|
|
10
|
-
|
|
10
|
+
if command -v jq &>/dev/null; then
|
|
11
|
+
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
12
|
+
fi
|
|
13
|
+
if [[ -z "$CMD" ]]; then
|
|
14
|
+
CMD=$(printf '%s' "$INPUT" | grep -o '"command" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
|
|
15
|
+
fi
|
|
11
16
|
fi
|
|
12
17
|
|
|
13
18
|
if [[ -z "$CMD" ]]; then
|
package/hooks/commit-guard.sh
CHANGED
|
@@ -7,7 +7,12 @@ if [ -n "$CORTEXHAWK_COMMAND" ]; then
|
|
|
7
7
|
CMD="$CORTEXHAWK_COMMAND"
|
|
8
8
|
else
|
|
9
9
|
INPUT=$(cat)
|
|
10
|
-
|
|
10
|
+
if command -v jq &>/dev/null; then
|
|
11
|
+
CMD=$(printf '%s' "$INPUT" | jq -r '.tool_input.command // empty' 2>/dev/null)
|
|
12
|
+
fi
|
|
13
|
+
if [[ -z "$CMD" ]]; then
|
|
14
|
+
CMD=$(printf '%s' "$INPUT" | grep -o '"command" *: *"[^"]*"' | head -1 | sed 's/.*: *"//;s/"$//')
|
|
15
|
+
fi
|
|
11
16
|
fi
|
|
12
17
|
|
|
13
18
|
if [[ -z "$CMD" ]]; then
|
|
@@ -20,9 +25,17 @@ if ! echo "$CMD" | grep -qE 'git\s+commit'; then
|
|
|
20
25
|
fi
|
|
21
26
|
|
|
22
27
|
# Extract commit message from -m flag
|
|
23
|
-
|
|
28
|
+
# Handle: -m "msg", -m 'msg', -m "$(cat <<'EOF'\nmsg\nEOF\n)"
|
|
29
|
+
COMMIT_MSG=$(echo "$CMD" | sed -n 's/.*-m[[:space:]]*"\$(cat <<.*//p' 2>/dev/null)
|
|
30
|
+
if [[ -n "$COMMIT_MSG" ]]; then
|
|
31
|
+
# HEREDOC style — extract first non-empty line after the heredoc opener
|
|
32
|
+
COMMIT_MSG=$(echo "$CMD" | sed -n '/cat <</{n;p;}' | sed 's/^[[:space:]]*//' 2>/dev/null)
|
|
33
|
+
fi
|
|
34
|
+
if [[ -z "$COMMIT_MSG" ]]; then
|
|
35
|
+
COMMIT_MSG=$(echo "$CMD" | grep -oP "(?<=-m\s[\"'])(.+?)(?=[\"'](\s|$))" 2>/dev/null | head -1)
|
|
36
|
+
fi
|
|
24
37
|
if [[ -z "$COMMIT_MSG" ]]; then
|
|
25
|
-
COMMIT_MSG=$(echo "$CMD" | grep -oP '(?<=-m\s)
|
|
38
|
+
COMMIT_MSG=$(echo "$CMD" | grep -oP '(?<=-m\s)\S+' 2>/dev/null | head -1)
|
|
26
39
|
fi
|
|
27
40
|
|
|
28
41
|
# Load git workflow config — skip conventional check if freeform
|
package/hooks/file-guard.sh
CHANGED
|
@@ -2,20 +2,28 @@
|
|
|
2
2
|
# file-guard — Blocks Claude from accessing sensitive files
|
|
3
3
|
# Hook type: PreToolUse (Read|Edit|Write)
|
|
4
4
|
|
|
5
|
+
# Patterns matched against BASENAME only
|
|
5
6
|
BLOCKED_PATTERNS=(
|
|
6
7
|
".env"
|
|
7
|
-
".env.*"
|
|
8
8
|
"*.pem"
|
|
9
9
|
"*.key"
|
|
10
|
-
"*credentials*"
|
|
11
|
-
"*secret*"
|
|
12
10
|
"id_rsa"
|
|
13
11
|
"id_ed25519"
|
|
14
|
-
".ssh/*"
|
|
15
12
|
"*.p12"
|
|
16
13
|
"*.pfx"
|
|
17
14
|
"*.keystore"
|
|
18
|
-
"
|
|
15
|
+
"credentials.json"
|
|
16
|
+
"credentials.yml"
|
|
17
|
+
"credentials.yaml"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
# Basename patterns that are .env.* but NOT .env.example/.env.sample/.env.template
|
|
21
|
+
BLOCKED_ENV_GLOB=".env.*"
|
|
22
|
+
ALLOWED_ENV_NAMES=(".env.example" ".env.sample" ".env.template")
|
|
23
|
+
|
|
24
|
+
# Path patterns — only match directory components
|
|
25
|
+
BLOCKED_PATH_PATTERNS=(
|
|
26
|
+
".ssh/"
|
|
19
27
|
)
|
|
20
28
|
|
|
21
29
|
# Read file_path from stdin JSON (Claude Code hook protocol)
|
|
@@ -42,10 +50,35 @@ BASENAME=$(basename "$RESOLVED")
|
|
|
42
50
|
# Also check against the full resolved path
|
|
43
51
|
RELPATH="$RESOLVED"
|
|
44
52
|
|
|
53
|
+
# Check basename against exact patterns
|
|
45
54
|
for pattern in "${BLOCKED_PATTERNS[@]}"; do
|
|
46
|
-
if [[ "$BASENAME" == $pattern ]]
|
|
55
|
+
if [[ "$BASENAME" == $pattern ]]; then
|
|
56
|
+
echo "BLOCKED: Access to '$FILE_ARG' denied by file-guard" >&2
|
|
57
|
+
echo "Matched pattern: '$pattern'" >&2
|
|
58
|
+
exit 2
|
|
59
|
+
fi
|
|
60
|
+
done
|
|
61
|
+
|
|
62
|
+
# Check .env.* files (allow .env.example/.env.sample/.env.template)
|
|
63
|
+
if [[ "$BASENAME" == $BLOCKED_ENV_GLOB ]]; then
|
|
64
|
+
ALLOWED=false
|
|
65
|
+
for name in "${ALLOWED_ENV_NAMES[@]}"; do
|
|
66
|
+
if [[ "$BASENAME" == "$name" ]]; then
|
|
67
|
+
ALLOWED=true
|
|
68
|
+
break
|
|
69
|
+
fi
|
|
70
|
+
done
|
|
71
|
+
if [[ "$ALLOWED" == false ]]; then
|
|
72
|
+
echo "BLOCKED: Access to '$FILE_ARG' denied by file-guard" >&2
|
|
73
|
+
echo "Matched pattern: '$BLOCKED_ENV_GLOB'" >&2
|
|
74
|
+
exit 2
|
|
75
|
+
fi
|
|
76
|
+
fi
|
|
77
|
+
|
|
78
|
+
# Check path patterns (directory components)
|
|
79
|
+
for pattern in "${BLOCKED_PATH_PATTERNS[@]}"; do
|
|
80
|
+
if [[ "$RELPATH" == *"$pattern"* ]]; then
|
|
47
81
|
echo "BLOCKED: Access to '$FILE_ARG' denied by file-guard" >&2
|
|
48
|
-
echo "Resolved path: $RESOLVED" >&2
|
|
49
82
|
echo "Matched pattern: '$pattern'" >&2
|
|
50
83
|
exit 2
|
|
51
84
|
fi
|