axel-setup 0.2.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/CHANGELOG.md +218 -0
- package/CONTRIBUTING.md +58 -0
- package/LICENSE +21 -0
- package/README.md +518 -0
- package/agents/api-design.md +51 -0
- package/agents/bughunter.md +136 -0
- package/agents/changelog.md +89 -0
- package/agents/cleanup.md +126 -0
- package/agents/compare-branch.md +35 -0
- package/agents/cross-repo.md +97 -0
- package/agents/db-check.md +14 -0
- package/agents/debug.md +47 -0
- package/agents/deploy-check.md +100 -0
- package/agents/draft-message.md +19 -0
- package/agents/excelsior-coordinator.md +75 -0
- package/agents/excelsior-verifier.md +94 -0
- package/agents/feature.md +48 -0
- package/agents/harness-optimizer.md +40 -0
- package/agents/incident.md +48 -0
- package/agents/linear-task.md +18 -0
- package/agents/onboard.md +24 -0
- package/agents/perf.md +44 -0
- package/agents/production-validator.md +96 -0
- package/agents/review.md +113 -0
- package/agents/security-check.md +29 -0
- package/agents/sprint-summary.md +15 -0
- package/agents/tdd-mainder.md +178 -0
- package/agents/test-gen.md +39 -0
- package/axel-manifest.json +129 -0
- package/bin/axel-setup.js +597 -0
- package/bootstrap.sh +1087 -0
- package/commands/create-pr.md +13 -0
- package/commands/daily.md +182 -0
- package/commands/deslop.md +13 -0
- package/commands/draft-message.md +23 -0
- package/commands/eod-review.md +154 -0
- package/commands/execute-prp.md +37 -0
- package/commands/generate-prp.md +75 -0
- package/commands/multi-repo-feature.md +60 -0
- package/commands/roadmap.md +31 -0
- package/commands/sprint-status.md +486 -0
- package/commands/style.md +68 -0
- package/commands/visualize.md +17 -0
- package/docs/roadmap/multi-runtime.md +73 -0
- package/docs/superpowers/plans/2026-06-12-setup-hardening-roadmap.md +61 -0
- package/hooks/desktop-notify.sh +26 -0
- package/hooks/enforce-agent-model.jq +14 -0
- package/hooks/gsd-context-monitor.js +156 -0
- package/hooks/linear-lifecycle-sync.sh +112 -0
- package/hooks/memory-dedup.sh +122 -0
- package/hooks/memory-extractor.sh +218 -0
- package/hooks/post-commit-memory-trigger.sh +16 -0
- package/hooks/post-commit-verify.sh +41 -0
- package/hooks/post-edit-lint.sh +43 -0
- package/hooks/precompact-save-context.sh +124 -0
- package/hooks/priority-map-staleness.sh +29 -0
- package/hooks/proactive-resolver.sh +104 -0
- package/hooks/session-auto-title.sh +165 -0
- package/hooks/session-checkpoint.sh +97 -0
- package/hooks/session-cost-log.sh +77 -0
- package/hooks/session-log-action.sh +36 -0
- package/hooks/session-log-prompt.sh +25 -0
- package/hooks/session-restore.sh +45 -0
- package/hooks/session-save.sh +81 -0
- package/hooks/session-summarize.sh +154 -0
- package/hooks/validate-commit-format.sh +38 -0
- package/hooks/weekly-priority-map-review.sh +143 -0
- package/install.sh +46 -0
- package/package.json +67 -0
- package/scripts/ci/bootstrap-dry-run.sh +40 -0
- package/scripts/ci/check.sh +65 -0
- package/scripts/posthog-snapshot-loader.sh +112 -0
- package/skills/context-budget/SKILL.md +86 -0
- package/skills/memory-review/SKILL.md +100 -0
- package/skills/model-routing/SKILL.md +70 -0
- package/skills/posthog-weekly/SKILL.md +271 -0
- package/skills/ui-ux-pro-max/SKILL.md +377 -0
- package/skills/ui-ux-pro-max/data/charts.csv +26 -0
- package/skills/ui-ux-pro-max/data/colors.csv +97 -0
- package/skills/ui-ux-pro-max/data/icons.csv +101 -0
- package/skills/ui-ux-pro-max/data/landing.csv +31 -0
- package/skills/ui-ux-pro-max/data/products.csv +97 -0
- package/skills/ui-ux-pro-max/data/react-performance.csv +45 -0
- package/skills/ui-ux-pro-max/data/stacks/astro.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/flutter.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/html-tailwind.csv +56 -0
- package/skills/ui-ux-pro-max/data/stacks/jetpack-compose.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nextjs.csv +53 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxt-ui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/nuxtjs.csv +59 -0
- package/skills/ui-ux-pro-max/data/stacks/react-native.csv +52 -0
- package/skills/ui-ux-pro-max/data/stacks/react.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/shadcn.csv +61 -0
- package/skills/ui-ux-pro-max/data/stacks/svelte.csv +54 -0
- package/skills/ui-ux-pro-max/data/stacks/swiftui.csv +51 -0
- package/skills/ui-ux-pro-max/data/stacks/vue.csv +50 -0
- package/skills/ui-ux-pro-max/data/styles.csv +68 -0
- package/skills/ui-ux-pro-max/data/typography.csv +58 -0
- package/skills/ui-ux-pro-max/data/ui-reasoning.csv +101 -0
- package/skills/ui-ux-pro-max/data/ux-guidelines.csv +100 -0
- package/skills/ui-ux-pro-max/data/web-interface.csv +31 -0
- package/skills/ui-ux-pro-max/scripts/core.py +253 -0
- package/skills/ui-ux-pro-max/scripts/design_system.py +1067 -0
- package/skills/ui-ux-pro-max/scripts/search.py +114 -0
- package/templates/AGENTS.runtime.md +17 -0
- package/templates/CLAUDE.md +252 -0
- package/templates/claude-monitor.plist +35 -0
- package/templates/keybindings.json +13 -0
- package/templates/merge-settings.jq +53 -0
- package/templates/review-upgrades.md +44 -0
- package/templates/settings.json +255 -0
- package/templates/statusline-command.sh +182 -0
- package/tests/fixtures/hooks/events.json +32 -0
- package/tools/session-costs-view.sh +128 -0
- package/tools/session-dashboard-gen.sh +369 -0
- package/tools/session-live.sh +173 -0
- package/tools/session-server.js +441 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Validates commit message format: tipo (Modelo/Archivo): Mensaje
|
|
3
|
+
# Reads $TOOL_INPUT as JSON, extracts the command, then validates the commit message
|
|
4
|
+
# Valid types: feat|fix|chore|refactor|test|docs|style|perf|ci|build|revert
|
|
5
|
+
|
|
6
|
+
TOOL_JSON="$TOOL_INPUT"
|
|
7
|
+
|
|
8
|
+
# Extract the command field from the Bash tool JSON input
|
|
9
|
+
CMD=$(echo "$TOOL_JSON" | jq -r '.command // empty' 2>/dev/null)
|
|
10
|
+
[ -z "$CMD" ] && CMD="$TOOL_JSON"
|
|
11
|
+
|
|
12
|
+
# Only check git commit commands
|
|
13
|
+
echo "$CMD" | grep -qE 'git commit' || exit 0
|
|
14
|
+
|
|
15
|
+
# Extract commit message from -m flag
|
|
16
|
+
# Handles: -m "msg", -m 'msg', -m "$(cat <<'EOF'\nmsg\nEOF\n)"
|
|
17
|
+
MSG=$(echo "$CMD" | sed -n 's/.*-m[[:space:]]*["'\'']\{0,1\}\(.*\)/\1/p' | sed 's/["'\'']\{0,1\}[[:space:]]*$//' | head -1)
|
|
18
|
+
|
|
19
|
+
# For heredoc pattern: extract the first content line
|
|
20
|
+
if echo "$MSG" | grep -q '<<'; then
|
|
21
|
+
MSG=$(echo "$CMD" | tr '\n' '|' | sed 's/.*<<[^|]*|//' | sed 's/|.*//' | sed 's/^[[:space:]]*//')
|
|
22
|
+
fi
|
|
23
|
+
|
|
24
|
+
# If we couldn't extract a message, skip validation (might be --amend or interactive)
|
|
25
|
+
[ -z "$MSG" ] && exit 0
|
|
26
|
+
|
|
27
|
+
# Validate format: tipo (Scope): message
|
|
28
|
+
if ! echo "$MSG" | grep -qE '^(feat|fix|chore|refactor|test|docs|style|perf|ci|build|revert)\s*\('; then
|
|
29
|
+
echo "BLOCKED: Commit format is incorrect." >&2
|
|
30
|
+
echo "Required: type (Scope): Descriptive message" >&2
|
|
31
|
+
echo "Canonical example: feat (AuthController): add OAuth2 login flow" >&2
|
|
32
|
+
echo "Valid types: feat|fix|chore|refactor|test|docs|style|perf|ci|build|revert" >&2
|
|
33
|
+
echo "Do not use --no-verify to bypass this check. Fix the message instead." >&2
|
|
34
|
+
echo "Got: $MSG" >&2
|
|
35
|
+
exit 1
|
|
36
|
+
fi
|
|
37
|
+
|
|
38
|
+
exit 0
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# Weekly priority-map review — intended to run every Monday 9am via LaunchAgent/cron.
|
|
3
|
+
# Analyzes git activity from the last 7 days + current priority-map and writes
|
|
4
|
+
# an update proposal. Does not modify priority-map directly — user reviews and applies.
|
|
5
|
+
#
|
|
6
|
+
# Configuration (env vars):
|
|
7
|
+
# PRIORITY_MAP_REPOS — space-separated list of absolute repo paths to scan.
|
|
8
|
+
# Example: "$HOME/work/api $HOME/work/web"
|
|
9
|
+
# If unset/empty, the git-evidence section is skipped.
|
|
10
|
+
|
|
11
|
+
set -e
|
|
12
|
+
|
|
13
|
+
MEMORY_DIR="$HOME/.claude/memory"
|
|
14
|
+
PRIORITY_MAP="$MEMORY_DIR/priority-map.md"
|
|
15
|
+
ARCHIVE="$MEMORY_DIR/MEMORY-archive.md"
|
|
16
|
+
LOG_DIR="$HOME/.claude/logs"
|
|
17
|
+
mkdir -p "$LOG_DIR"
|
|
18
|
+
LOG_FILE="$LOG_DIR/priority-map-review.log"
|
|
19
|
+
|
|
20
|
+
TIMESTAMP=$(date +%Y-%m-%d)
|
|
21
|
+
PROPOSAL_FILE="$MEMORY_DIR/priority-map.proposed-${TIMESTAMP}.md"
|
|
22
|
+
REVIEW_SUMMARY="$MEMORY_DIR/priority-map-review-${TIMESTAMP}.md"
|
|
23
|
+
|
|
24
|
+
echo "=== priority-map review $(date) ===" >> "$LOG_FILE"
|
|
25
|
+
|
|
26
|
+
if [[ ! -f "$PRIORITY_MAP" ]]; then
|
|
27
|
+
echo "ERROR: priority-map.md does not exist at $MEMORY_DIR" >> "$LOG_FILE"
|
|
28
|
+
exit 1
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Anti-recursion guard: prevents infinite loops if this hook is wired into a
|
|
32
|
+
# lifecycle event that fires during the claude -p subprocess below.
|
|
33
|
+
if [[ -n "$CLAUDE_HOOK_RUNNING" ]]; then
|
|
34
|
+
echo "SKIP: CLAUDE_HOOK_RUNNING set — avoiding recursion" >> "$LOG_FILE"
|
|
35
|
+
exit 0
|
|
36
|
+
fi
|
|
37
|
+
export CLAUDE_HOOK_RUNNING=1
|
|
38
|
+
|
|
39
|
+
# Isolated JSONL session to avoid polluting /resume history.
|
|
40
|
+
ISOLATED_SESSION_DIR=$(mktemp -d)
|
|
41
|
+
export CLAUDE_SESSION_DIR="$ISOLATED_SESSION_DIR"
|
|
42
|
+
|
|
43
|
+
# Collect git evidence from the last 7 days across configured repos.
|
|
44
|
+
REPOS="${PRIORITY_MAP_REPOS:-}"
|
|
45
|
+
GIT_EVIDENCE=$(
|
|
46
|
+
if [[ -z "$REPOS" ]]; then
|
|
47
|
+
echo "(PRIORITY_MAP_REPOS not set — skipping git evidence collection)"
|
|
48
|
+
else
|
|
49
|
+
for repo in $REPOS; do
|
|
50
|
+
[ -d "$repo/.git" ] || continue
|
|
51
|
+
repo_name=$(basename "$repo")
|
|
52
|
+
echo "## $repo_name"
|
|
53
|
+
cd "$repo" 2>/dev/null && {
|
|
54
|
+
git fetch origin --quiet 2>/dev/null || true
|
|
55
|
+
echo "### Merged PRs last 7 days"
|
|
56
|
+
git log --first-parent origin/main --since="7 days ago" --pretty=format:'- %s' 2>/dev/null | head -30
|
|
57
|
+
echo ""
|
|
58
|
+
echo "### New branches (not merged to main)"
|
|
59
|
+
if [[ "$(uname)" == "Darwin" ]]; then
|
|
60
|
+
SEVEN_DAYS_AGO=$(date -v-7d +%Y-%m-%d)
|
|
61
|
+
else
|
|
62
|
+
SEVEN_DAYS_AGO=$(date -d '7 days ago' +%Y-%m-%d)
|
|
63
|
+
fi
|
|
64
|
+
git for-each-ref --sort=-committerdate --format='%(refname:short) %(committerdate:short)' refs/remotes/origin 2>/dev/null | awk -v d="$SEVEN_DAYS_AGO" '$2 >= d {print "- " $0}' | head -20
|
|
65
|
+
echo ""
|
|
66
|
+
}
|
|
67
|
+
done
|
|
68
|
+
fi
|
|
69
|
+
)
|
|
70
|
+
|
|
71
|
+
PROMPT=$(cat <<PROMPT_EOF
|
|
72
|
+
It is Monday morning. Your task: review the user priority-map.md and propose an update based on recent git activity.
|
|
73
|
+
|
|
74
|
+
**Input 1 — current priority-map:**
|
|
75
|
+
\`\`\`
|
|
76
|
+
$(cat "$PRIORITY_MAP")
|
|
77
|
+
\`\`\`
|
|
78
|
+
|
|
79
|
+
**Input 2 — git activity last 7 days (tracked repos):**
|
|
80
|
+
\`\`\`
|
|
81
|
+
$GIT_EVIDENCE
|
|
82
|
+
\`\`\`
|
|
83
|
+
|
|
84
|
+
**Input 3 — current archive:**
|
|
85
|
+
\`\`\`
|
|
86
|
+
$(cat "$ARCHIVE" 2>/dev/null || echo "empty")
|
|
87
|
+
\`\`\`
|
|
88
|
+
|
|
89
|
+
**Expected output — write TWO files:**
|
|
90
|
+
|
|
91
|
+
1. \`$REVIEW_SUMMARY\` — short analysis summary:
|
|
92
|
+
- P0 items in the priority-map that look CLOSED based on git (matching merged PR)
|
|
93
|
+
- P1 items in the priority-map that look CLOSED based on git
|
|
94
|
+
- New items detected in git that should be promoted to P0/P1 (large features, recent PRs with no card in the map)
|
|
95
|
+
- P0/P1 items with NO activity in 7 days → flag as stale
|
|
96
|
+
- Concrete question at the end: "Confirm moving items [X, Y, Z] to archive and adding [A, B] to P0/P1?"
|
|
97
|
+
|
|
98
|
+
2. \`$PROPOSAL_FILE\` — full proposal for the new priority-map.md:
|
|
99
|
+
- Same structure as current
|
|
100
|
+
- Closed items removed
|
|
101
|
+
- New items added in the matching bucket
|
|
102
|
+
- Updated field set to $TIMESTAMP
|
|
103
|
+
- Sprint field only if you can infer it from context, otherwise leave it
|
|
104
|
+
- Do NOT overwrite \`$PRIORITY_MAP\` directly — only the .proposed file
|
|
105
|
+
|
|
106
|
+
**Rules:**
|
|
107
|
+
- Conservative: if an item does not clearly match a merged PR, do NOT move it to the archive.
|
|
108
|
+
- If there is not enough evidence to propose changes → write "No changes suggested — priority-map looks up to date" in the review summary.
|
|
109
|
+
- Do not invent new P0s without git evidence.
|
|
110
|
+
PROMPT_EOF
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Resolve claude CLI: prefer PATH, fall back gracefully if not found.
|
|
114
|
+
CLAUDE_BIN=$(command -v claude || true)
|
|
115
|
+
if [[ -z "$CLAUDE_BIN" ]]; then
|
|
116
|
+
echo "ERROR: claude CLI not found in PATH" >> "$LOG_FILE"
|
|
117
|
+
rm -rf "$ISOLATED_SESSION_DIR"
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
echo "Running claude -p..." >> "$LOG_FILE"
|
|
122
|
+
"$CLAUDE_BIN" -p "$PROMPT" \
|
|
123
|
+
--allowed-tools "Read,Write,Edit,Bash,Glob,Grep" \
|
|
124
|
+
>> "$LOG_FILE" 2>&1 || {
|
|
125
|
+
echo "ERROR: claude -p failed" >> "$LOG_FILE"
|
|
126
|
+
/usr/bin/osascript -e 'display notification "claude -p failed — check ~/.claude/logs/priority-map-review.log" with title "Priority Map Review"' 2>/dev/null || true
|
|
127
|
+
rm -rf "$ISOLATED_SESSION_DIR"
|
|
128
|
+
exit 1
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
rm -rf "$ISOLATED_SESSION_DIR"
|
|
132
|
+
|
|
133
|
+
# Notify via macOS notification center (no-op on Linux).
|
|
134
|
+
if [[ -f "$REVIEW_SUMMARY" ]]; then
|
|
135
|
+
/usr/bin/osascript -e "display notification \"Review $REVIEW_SUMMARY and $PROPOSAL_FILE\" with title \"Priority Map Review — Monday\" sound name \"Purr\"" 2>/dev/null || true
|
|
136
|
+
echo "OK — files generated: $REVIEW_SUMMARY, $PROPOSAL_FILE" >> "$LOG_FILE"
|
|
137
|
+
else
|
|
138
|
+
/usr/bin/osascript -e 'display notification "Review produced no files — check ~/.claude/logs/priority-map-review.log" with title "Priority Map Review"' 2>/dev/null || true
|
|
139
|
+
echo "WARNING: claude -p finished but $REVIEW_SUMMARY is missing" >> "$LOG_FILE"
|
|
140
|
+
fi
|
|
141
|
+
|
|
142
|
+
echo "=== end $(date) ===" >> "$LOG_FILE"
|
|
143
|
+
exit 0
|
package/install.sh
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
#!/usr/bin/env sh
|
|
2
|
+
set -eu
|
|
3
|
+
|
|
4
|
+
AXEL_PACKAGE="${AXEL_SETUP_PACKAGE:-axel-setup@latest}"
|
|
5
|
+
AXEL_NPX="${AXEL_SETUP_NPX:-npx}"
|
|
6
|
+
|
|
7
|
+
die() {
|
|
8
|
+
printf '%s\n' "AXEL install error: $*" >&2
|
|
9
|
+
exit 1
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
require_command() {
|
|
13
|
+
if ! command -v "$1" >/dev/null 2>&1; then
|
|
14
|
+
die "$2"
|
|
15
|
+
fi
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
uses_non_claude_target() {
|
|
19
|
+
target="claude"
|
|
20
|
+
while [ "$#" -gt 0 ]; do
|
|
21
|
+
case "$1" in
|
|
22
|
+
--target=*)
|
|
23
|
+
target="${1#*=}"
|
|
24
|
+
;;
|
|
25
|
+
--target)
|
|
26
|
+
shift
|
|
27
|
+
target="${1:-claude}"
|
|
28
|
+
;;
|
|
29
|
+
esac
|
|
30
|
+
[ "$#" -gt 0 ] || break
|
|
31
|
+
shift
|
|
32
|
+
done
|
|
33
|
+
|
|
34
|
+
[ "$target" = "codex" ] || [ "$target" = "generic" ]
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
require_command zsh "zsh is required. Install Xcode Command Line Tools or a zsh package before running AXEL."
|
|
38
|
+
require_command jq "jq is required. On macOS, install it with: brew install jq"
|
|
39
|
+
require_command node "Node.js is required because the packaged AXEL CLI runs through npx. Install Node 18 or newer."
|
|
40
|
+
require_command "$AXEL_NPX" "npx is required. Install npm with Node.js, then rerun this installer."
|
|
41
|
+
|
|
42
|
+
if ! uses_non_claude_target "$@" && [ "${AXEL_SETUP_SKIP_CLAUDE_CHECK:-false}" != "true" ]; then
|
|
43
|
+
require_command claude "Claude Code CLI is required for the default target. Install Claude Code, pass --target codex or --target generic, or set AXEL_SETUP_SKIP_CLAUDE_CHECK=true."
|
|
44
|
+
fi
|
|
45
|
+
|
|
46
|
+
exec "$AXEL_NPX" -y "$AXEL_PACKAGE" "$@"
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "axel-setup",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Claude Code-first team configuration package with hooks, agents, commands, skills, plugins, and repeatable bootstrap tooling.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": {
|
|
7
|
+
"name": "Cristian Vera Lyon",
|
|
8
|
+
"url": "https://github.com/cveralyon"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"claude-code",
|
|
12
|
+
"ai-agents",
|
|
13
|
+
"developer-tools",
|
|
14
|
+
"automation",
|
|
15
|
+
"devex",
|
|
16
|
+
"mcp",
|
|
17
|
+
"agentic-engineering",
|
|
18
|
+
"codex",
|
|
19
|
+
"multi-runtime",
|
|
20
|
+
"bootstrap"
|
|
21
|
+
],
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "git+https://github.com/cveralyon/axel-setup.git"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/cveralyon/axel-setup#readme",
|
|
27
|
+
"bugs": {
|
|
28
|
+
"url": "https://github.com/cveralyon/axel-setup/issues"
|
|
29
|
+
},
|
|
30
|
+
"bin": {
|
|
31
|
+
"axel-setup": "bin/axel-setup.js"
|
|
32
|
+
},
|
|
33
|
+
"files": [
|
|
34
|
+
"agents",
|
|
35
|
+
"commands",
|
|
36
|
+
"hooks",
|
|
37
|
+
"scripts",
|
|
38
|
+
"skills",
|
|
39
|
+
"templates",
|
|
40
|
+
"tools",
|
|
41
|
+
"docs",
|
|
42
|
+
"bin",
|
|
43
|
+
"tests/fixtures",
|
|
44
|
+
"install.sh",
|
|
45
|
+
"bootstrap.sh",
|
|
46
|
+
"axel-manifest.json",
|
|
47
|
+
"CHANGELOG.md",
|
|
48
|
+
"CONTRIBUTING.md",
|
|
49
|
+
"LICENSE",
|
|
50
|
+
"README.md",
|
|
51
|
+
"!skills/**/__pycache__",
|
|
52
|
+
"!skills/**/*.pyc"
|
|
53
|
+
],
|
|
54
|
+
"scripts": {
|
|
55
|
+
"check": "bash scripts/ci/check.sh",
|
|
56
|
+
"smoke": "bash scripts/ci/bootstrap-dry-run.sh",
|
|
57
|
+
"pack:dry-run": "npm pack --dry-run",
|
|
58
|
+
"publish:dry-run": "npm publish --dry-run",
|
|
59
|
+
"prepublishOnly": "npm run check"
|
|
60
|
+
},
|
|
61
|
+
"engines": {
|
|
62
|
+
"node": ">=18"
|
|
63
|
+
},
|
|
64
|
+
"publishConfig": {
|
|
65
|
+
"access": "public"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
5
|
+
TMP_HOME="$(mktemp -d)"
|
|
6
|
+
TMP_BIN="$(mktemp -d)"
|
|
7
|
+
|
|
8
|
+
cleanup() {
|
|
9
|
+
rm -rf "$TMP_HOME" "$TMP_BIN"
|
|
10
|
+
}
|
|
11
|
+
trap cleanup EXIT
|
|
12
|
+
|
|
13
|
+
cat >"$TMP_BIN/claude" <<'STUB'
|
|
14
|
+
#!/usr/bin/env bash
|
|
15
|
+
case "${1:-}" in
|
|
16
|
+
--version)
|
|
17
|
+
echo "Claude Code 1.0.0"
|
|
18
|
+
;;
|
|
19
|
+
plugins)
|
|
20
|
+
exit 0
|
|
21
|
+
;;
|
|
22
|
+
*)
|
|
23
|
+
echo "claude stub"
|
|
24
|
+
;;
|
|
25
|
+
esac
|
|
26
|
+
STUB
|
|
27
|
+
chmod +x "$TMP_BIN/claude"
|
|
28
|
+
|
|
29
|
+
PATH="$TMP_BIN:$PATH" \
|
|
30
|
+
HOME="$TMP_HOME" \
|
|
31
|
+
bash "$ROOT/bootstrap.sh" \
|
|
32
|
+
--dry-run \
|
|
33
|
+
--user-name "CI Bot" \
|
|
34
|
+
--user-context "CI smoke test" \
|
|
35
|
+
--language english
|
|
36
|
+
|
|
37
|
+
if [ -e "$TMP_HOME/.claude" ]; then
|
|
38
|
+
echo "Dry run created $TMP_HOME/.claude" >&2
|
|
39
|
+
exit 1
|
|
40
|
+
fi
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
5
|
+
cd "$ROOT"
|
|
6
|
+
|
|
7
|
+
echo "Checking shell syntax"
|
|
8
|
+
while IFS= read -r -d '' file; do
|
|
9
|
+
if head -n 1 "$file" | grep -q "zsh"; then
|
|
10
|
+
zsh -n "$file"
|
|
11
|
+
else
|
|
12
|
+
bash -n "$file"
|
|
13
|
+
fi
|
|
14
|
+
done < <(find . -path ./.git -prune -o -type f -name "*.sh" -print0)
|
|
15
|
+
|
|
16
|
+
if command -v shellcheck >/dev/null 2>&1; then
|
|
17
|
+
echo "Running shellcheck"
|
|
18
|
+
while IFS= read -r -d '' file; do
|
|
19
|
+
if head -n 1 "$file" | grep -q "zsh"; then
|
|
20
|
+
continue
|
|
21
|
+
fi
|
|
22
|
+
shellcheck -S error "$file"
|
|
23
|
+
done < <(find . -path ./.git -prune -o -type f -name "*.sh" -print0)
|
|
24
|
+
else
|
|
25
|
+
echo "Skipping shellcheck (not installed)"
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
if command -v shfmt >/dev/null 2>&1; then
|
|
29
|
+
echo "Checking shell formatting"
|
|
30
|
+
shfmt -d -i 2 -ci scripts/ci/*.sh tests/*.sh
|
|
31
|
+
else
|
|
32
|
+
echo "Skipping shfmt (not installed)"
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
echo "Checking Node CLI syntax"
|
|
36
|
+
node --check bin/axel-setup.js
|
|
37
|
+
|
|
38
|
+
echo "Checking jq filters"
|
|
39
|
+
while IFS= read -r -d '' file; do
|
|
40
|
+
jq -n -f "$file" >/dev/null
|
|
41
|
+
done < <(find . -path ./.git -prune -o -type f -name "*.jq" -print0)
|
|
42
|
+
|
|
43
|
+
echo "Checking JSON files"
|
|
44
|
+
jq empty package.json axel-manifest.json templates/settings.json templates/keybindings.json
|
|
45
|
+
|
|
46
|
+
echo "Running bootstrap dry run smoke test"
|
|
47
|
+
bash scripts/ci/bootstrap-dry-run.sh
|
|
48
|
+
|
|
49
|
+
echo "Running bootstrap behavior tests"
|
|
50
|
+
bash tests/bootstrap-behavior.sh
|
|
51
|
+
|
|
52
|
+
echo "Running one-line installer tests"
|
|
53
|
+
bash tests/install-one-line.sh
|
|
54
|
+
|
|
55
|
+
echo "Running hook harness tests"
|
|
56
|
+
bash tests/hook-harness.sh
|
|
57
|
+
|
|
58
|
+
echo "Running CLI doctor tests"
|
|
59
|
+
bash tests/cli-doctor.sh
|
|
60
|
+
|
|
61
|
+
echo "Running settings merge fixture tests"
|
|
62
|
+
bash tests/merge-settings.sh
|
|
63
|
+
|
|
64
|
+
echo "Checking npm package contents"
|
|
65
|
+
npm pack --dry-run >/dev/null
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# posthog-snapshot-loader.sh
|
|
3
|
+
# Reads ~/.claude/cache/posthog-snapshot.json and prints a markdown summary
|
|
4
|
+
# for inclusion in larger reports (e.g. /sprint-status, /eod-review, /daily).
|
|
5
|
+
#
|
|
6
|
+
# Output contract:
|
|
7
|
+
# - If snapshot does not exist: prints a one-line nudge ("📊 No PostHog snapshot…").
|
|
8
|
+
# - If snapshot exists and is < 14 days old: prints a structured markdown block
|
|
9
|
+
# with critical findings, wins, and improvements.
|
|
10
|
+
# - If snapshot exists and is > 14 days old: prints a stale warning instead of
|
|
11
|
+
# the full block, so callers don't quote outdated insights at users.
|
|
12
|
+
#
|
|
13
|
+
# The snapshot is generated by the /posthog-weekly skill. This loader is
|
|
14
|
+
# read-only: it never refreshes data. To refresh, the user runs /posthog-weekly.
|
|
15
|
+
#
|
|
16
|
+
# Output format is plain markdown so callers can either include it verbatim
|
|
17
|
+
# in a larger report or pipe it to another tool. Exit code is always 0 — this
|
|
18
|
+
# script never blocks the caller, even when the snapshot is missing or stale.
|
|
19
|
+
|
|
20
|
+
set -e
|
|
21
|
+
|
|
22
|
+
SNAPSHOT="$HOME/.claude/cache/posthog-snapshot.json"
|
|
23
|
+
STALE_DAYS="${POSTHOG_SNAPSHOT_STALE_DAYS:-14}"
|
|
24
|
+
|
|
25
|
+
# Case 1: no snapshot at all → silent nudge, single line
|
|
26
|
+
if [ ! -f "$SNAPSHOT" ]; then
|
|
27
|
+
echo "📊 _No PostHog snapshot yet — run \`/posthog-weekly\` to generate one._"
|
|
28
|
+
exit 0
|
|
29
|
+
fi
|
|
30
|
+
|
|
31
|
+
# Case 2: snapshot exists but is unreadable / not valid JSON
|
|
32
|
+
if ! jq empty "$SNAPSHOT" 2>/dev/null; then
|
|
33
|
+
echo "⚠️ _PostHog snapshot at \`$SNAPSHOT\` is not valid JSON — re-run \`/posthog-weekly\` to regenerate._"
|
|
34
|
+
exit 0
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
# Compute snapshot age in days. The snapshot stores its timestamp as ISO 8601
|
|
38
|
+
# UTC. macOS `date -j -f` parses it; Linux `date -d` is the GNU equivalent.
|
|
39
|
+
TS=$(jq -r '.timestamp // empty' "$SNAPSHOT")
|
|
40
|
+
if [ -z "$TS" ]; then
|
|
41
|
+
echo "⚠️ _PostHog snapshot has no timestamp — re-run \`/posthog-weekly\` to regenerate._"
|
|
42
|
+
exit 0
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
NOW_EPOCH=$(date +%s)
|
|
46
|
+
SNAP_EPOCH=$(date -j -f "%Y-%m-%dT%H:%M:%SZ" "$TS" +%s 2>/dev/null \
|
|
47
|
+
|| date -d "$TS" +%s 2>/dev/null \
|
|
48
|
+
|| echo 0)
|
|
49
|
+
|
|
50
|
+
if [ "$SNAP_EPOCH" -eq 0 ]; then
|
|
51
|
+
echo "⚠️ _PostHog snapshot timestamp \`$TS\` could not be parsed — re-run \`/posthog-weekly\`._"
|
|
52
|
+
exit 0
|
|
53
|
+
fi
|
|
54
|
+
|
|
55
|
+
AGE_DAYS=$(( (NOW_EPOCH - SNAP_EPOCH) / 86400 ))
|
|
56
|
+
|
|
57
|
+
# Case 3: stale snapshot → short warning, no quoted findings
|
|
58
|
+
if [ "$AGE_DAYS" -gt "$STALE_DAYS" ]; then
|
|
59
|
+
echo "⚠️ _PostHog snapshot is **${AGE_DAYS} days old** (stale > ${STALE_DAYS}d). Run \`/posthog-weekly\` to refresh before quoting._"
|
|
60
|
+
exit 0
|
|
61
|
+
fi
|
|
62
|
+
|
|
63
|
+
# Case 4: fresh snapshot → full block
|
|
64
|
+
PROJECT_NAME=$(jq -r '.project_name // "PostHog"' "$SNAPSHOT")
|
|
65
|
+
PROJECT_URL=$(jq -r '.project_url // empty' "$SNAPSHOT")
|
|
66
|
+
|
|
67
|
+
echo "## 📊 PostHog Insights — ${PROJECT_NAME}"
|
|
68
|
+
echo ""
|
|
69
|
+
echo "_Snapshot from ${AGE_DAYS} day(s) ago — generated by \`/posthog-weekly\`_"
|
|
70
|
+
echo ""
|
|
71
|
+
|
|
72
|
+
# Critical findings — most important, always shown first
|
|
73
|
+
CRITICAL_COUNT=$(jq -r '.critical_findings | length' "$SNAPSHOT")
|
|
74
|
+
if [ "$CRITICAL_COUNT" -gt 0 ]; then
|
|
75
|
+
echo "### 🚨 Critical findings"
|
|
76
|
+
jq -r '.critical_findings[] | "- \(.)"' "$SNAPSHOT"
|
|
77
|
+
echo ""
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# Regressions / anomalies
|
|
81
|
+
REGRESSION_COUNT=$(jq -r '.regressions // [] | length' "$SNAPSHOT")
|
|
82
|
+
if [ "$REGRESSION_COUNT" -gt 0 ]; then
|
|
83
|
+
echo "### 📉 Regressions & anomalies"
|
|
84
|
+
jq -r '.regressions[] | "- \(.)"' "$SNAPSHOT"
|
|
85
|
+
echo ""
|
|
86
|
+
fi
|
|
87
|
+
|
|
88
|
+
# Wins
|
|
89
|
+
WIN_COUNT=$(jq -r '.wins // [] | length' "$SNAPSHOT")
|
|
90
|
+
if [ "$WIN_COUNT" -gt 0 ]; then
|
|
91
|
+
echo "### ✅ Wins"
|
|
92
|
+
jq -r '.wins[] | "- \(.)"' "$SNAPSHOT"
|
|
93
|
+
echo ""
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Improvement opportunities
|
|
97
|
+
IMPROVEMENT_COUNT=$(jq -r '.improvements // [] | length' "$SNAPSHOT")
|
|
98
|
+
if [ "$IMPROVEMENT_COUNT" -gt 0 ]; then
|
|
99
|
+
echo "### 🎯 Improvement opportunities"
|
|
100
|
+
jq -r '.improvements[] | "- \(.)"' "$SNAPSHOT"
|
|
101
|
+
echo ""
|
|
102
|
+
fi
|
|
103
|
+
|
|
104
|
+
# Project link if available
|
|
105
|
+
if [ -n "$PROJECT_URL" ]; then
|
|
106
|
+
echo "_Project: <${PROJECT_URL}>_"
|
|
107
|
+
echo ""
|
|
108
|
+
fi
|
|
109
|
+
|
|
110
|
+
echo "_For deeper analysis, run \`/posthog-weekly\` to refresh this snapshot._"
|
|
111
|
+
|
|
112
|
+
exit 0
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: context-budget
|
|
3
|
+
description: Audits Claude Code context consumption across agents, skills, commands, hooks, MCP servers, and the CLAUDE.md/MEMORY chain. Identifies bloat and redundancy, then produces prioritized token-savings recommendations. Backs the /context-budget command.
|
|
4
|
+
origin: ECC (adapted)
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Context Budget
|
|
8
|
+
|
|
9
|
+
Estimate the token overhead of everything loaded into a Claude Code session and surface concrete ways to reclaim context space. Adapted from ECC's context-budget for a single-runtime (Claude Code) setup on a large Opus window.
|
|
10
|
+
|
|
11
|
+
## When to Use
|
|
12
|
+
|
|
13
|
+
- The setup has grown (many agents, hooks, skills, MCP servers) and you want the real load cost.
|
|
14
|
+
- Output quality degrades, or the context monitor fires earlier than expected.
|
|
15
|
+
- Before adding more agents, skills, or MCP servers: check headroom first.
|
|
16
|
+
- Running the `/context-budget` command (this skill backs it).
|
|
17
|
+
|
|
18
|
+
## How It Works
|
|
19
|
+
|
|
20
|
+
Token estimation: prose uses `words × 1.3`, code or JSON uses `chars / 4`.
|
|
21
|
+
|
|
22
|
+
### Phase 1 — Inventory
|
|
23
|
+
|
|
24
|
+
Scan each source and estimate tokens.
|
|
25
|
+
|
|
26
|
+
- **Agents** (`~/.claude/agents/*.md`): tokens per file. Flag files over 200 lines (heavy) and a `description` over 30 words (it loads into every Task tool invocation, even for agents never spawned).
|
|
27
|
+
- **Skills** (`~/.claude/skills/*/SKILL.md`): tokens per SKILL.md. Flag over 400 lines.
|
|
28
|
+
- **Commands** (`~/.claude/commands/*.md`): tokens per file. Flag stale or duplicated entries.
|
|
29
|
+
- **Hooks** (`~/.claude/hooks/` plus the wiring in `settings.json`): count active hooks. Flag heavy or overlapping ones.
|
|
30
|
+
- **MCP servers** (active MCP config): count servers and total tools. Estimate ~500 tokens per tool schema. Flag servers over 20 tools, and servers that wrap a CLI already available for free (gh, git, vercel, supabase).
|
|
31
|
+
- **CLAUDE.md and memory chain** (`~/CLAUDE.md`, `~/.claude/memory/MEMORY.md`, any project CLAUDE.md): tokens per file. Flag a combined total over 400 lines, or a MEMORY index that carries detail instead of one-line pointers.
|
|
32
|
+
|
|
33
|
+
Note on RTK: it compresses Bash OUTPUT at runtime. It does not reduce the LOAD cost of this setup. Measure the load cost (the files above), not RTK-filtered command output.
|
|
34
|
+
|
|
35
|
+
### Phase 2 — Classify
|
|
36
|
+
|
|
37
|
+
| Bucket | Criteria | Action |
|
|
38
|
+
|--------|----------|--------|
|
|
39
|
+
| Always needed | Referenced in CLAUDE.md, backs an active command, or matches current work | Keep |
|
|
40
|
+
| Sometimes needed | Domain-specific, not referenced in CLAUDE.md | On-demand or lazy-load |
|
|
41
|
+
| Rarely needed | No reference, overlapping content, no project match | Remove or archive |
|
|
42
|
+
|
|
43
|
+
### Phase 3 — Detect Issues
|
|
44
|
+
|
|
45
|
+
- Bloated agent descriptions (over 30 words): present in every Task tool context.
|
|
46
|
+
- Heavy agents (over 200 lines): inflate Task context on every spawn.
|
|
47
|
+
- Redundant components: skills that duplicate agent logic, memory entries that duplicate CLAUDE.md rules.
|
|
48
|
+
- MCP over-subscription: many servers, or servers wrapping free CLI tools.
|
|
49
|
+
- CLAUDE.md or MEMORY bloat: verbose sections, stale rules, MEMORY entries carrying detail instead of a one-line hook.
|
|
50
|
+
|
|
51
|
+
### Phase 4 — Report
|
|
52
|
+
|
|
53
|
+
```
|
|
54
|
+
Context Budget Report
|
|
55
|
+
═══════════════════════════════════════
|
|
56
|
+
Window: Opus (1M tokens)
|
|
57
|
+
Total estimated setup overhead: ~XX,XXX tokens (XX% of 1M)
|
|
58
|
+
Effective working context: ~XXX,XXX tokens
|
|
59
|
+
|
|
60
|
+
Component Breakdown:
|
|
61
|
+
┌───────────────┬───────┬──────────┐
|
|
62
|
+
│ Component │ Count │ Tokens │
|
|
63
|
+
├───────────────┼───────┼──────────┤
|
|
64
|
+
│ Agents │ N │ ~X,XXX │
|
|
65
|
+
│ Skills │ N │ ~X,XXX │
|
|
66
|
+
│ Commands │ N │ ~X,XXX │
|
|
67
|
+
│ Hooks │ N │ ~X,XXX │
|
|
68
|
+
│ MCP tools │ N │ ~XX,XXX │
|
|
69
|
+
│ CLAUDE+memory │ N │ ~X,XXX │
|
|
70
|
+
└───────────────┴───────┴──────────┘
|
|
71
|
+
|
|
72
|
+
Top 3 Optimizations (ranked by savings):
|
|
73
|
+
1. [action] → ~X,XXX tokens
|
|
74
|
+
2. [action] → ~X,XXX tokens
|
|
75
|
+
3. [action] → ~X,XXX tokens
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
In verbose mode, add per-file token counts, the heaviest files line-counted, and the MCP tool list with per-tool schema estimates.
|
|
79
|
+
|
|
80
|
+
## Best Practices
|
|
81
|
+
|
|
82
|
+
- MCP is usually the biggest lever. One 30-tool server can cost more than every skill combined.
|
|
83
|
+
- Agent descriptions load always, even for agents never invoked. Keep them tight.
|
|
84
|
+
- On a 1M window the absolute overhead matters less than redundancy and menu noise. Prioritize removing stale or duplicated surface over shaving raw tokens.
|
|
85
|
+
- Re-audit after adding any agent, skill, or MCP server to catch creep early.
|
|
86
|
+
- Pairs with the `harness-optimizer` agent, which consumes this report as its baseline.
|