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,255 @@
|
|
|
1
|
+
{
|
|
2
|
+
"env": {
|
|
3
|
+
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1",
|
|
4
|
+
"CLAUDE_AUTO_BACKGROUND_TASKS": "1",
|
|
5
|
+
"CLAUDE_CODE_IDLE_THRESHOLD_MINUTES": "30",
|
|
6
|
+
"CLAUDE_CODE_IDLE_TOKEN_THRESHOLD": "50000"
|
|
7
|
+
},
|
|
8
|
+
"permissions": {
|
|
9
|
+
"allow": [
|
|
10
|
+
"Bash(*)",
|
|
11
|
+
"Read(*)",
|
|
12
|
+
"Edit(*)",
|
|
13
|
+
"Write(*)",
|
|
14
|
+
"Glob(*)",
|
|
15
|
+
"Grep(*)",
|
|
16
|
+
"Agent(*)",
|
|
17
|
+
"mcp__*"
|
|
18
|
+
],
|
|
19
|
+
"deny": [
|
|
20
|
+
"Bash(rm -rf *)",
|
|
21
|
+
"Bash(dd *)"
|
|
22
|
+
],
|
|
23
|
+
"defaultMode": "bypassPermissions"
|
|
24
|
+
},
|
|
25
|
+
"hooks": {
|
|
26
|
+
"PreToolUse": [
|
|
27
|
+
{
|
|
28
|
+
"matcher": "Bash",
|
|
29
|
+
"hooks": [
|
|
30
|
+
{
|
|
31
|
+
"type": "command",
|
|
32
|
+
"command": "echo \"$TOOL_INPUT\" | grep -qE '\\-\\-no-verify' && echo 'BLOCKED: --no-verify is prohibited' >&2 && exit 2 || exit 0"
|
|
33
|
+
}
|
|
34
|
+
]
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
"matcher": "Bash",
|
|
38
|
+
"hooks": [
|
|
39
|
+
{
|
|
40
|
+
"type": "command",
|
|
41
|
+
"command": "bash $HOME/.claude/hooks/validate-commit-format.sh"
|
|
42
|
+
}
|
|
43
|
+
]
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
"matcher": "Bash",
|
|
47
|
+
"hooks": [
|
|
48
|
+
{
|
|
49
|
+
"type": "command",
|
|
50
|
+
"command": "echo \"$TOOL_INPUT\" | grep -qE 'RAILS_ENV=staging' && echo 'WARNING: staging = PRODUCTION. Confirm with the user.' >&2 && exit 1 || exit 0"
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"matcher": "Agent",
|
|
56
|
+
"hooks": [
|
|
57
|
+
{
|
|
58
|
+
"type": "command",
|
|
59
|
+
"command": "jq -c -f $HOME/.claude/hooks/enforce-agent-model.jq",
|
|
60
|
+
"timeout": 5,
|
|
61
|
+
"statusMessage": "Checking Agent model routing..."
|
|
62
|
+
}
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
],
|
|
66
|
+
"PostToolUse": [
|
|
67
|
+
{
|
|
68
|
+
"matcher": "Bash",
|
|
69
|
+
"hooks": [
|
|
70
|
+
{
|
|
71
|
+
"type": "command",
|
|
72
|
+
"command": "bash $HOME/.claude/hooks/proactive-resolver.sh",
|
|
73
|
+
"timeout": 30
|
|
74
|
+
}
|
|
75
|
+
]
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"matcher": "Edit",
|
|
79
|
+
"hooks": [
|
|
80
|
+
{
|
|
81
|
+
"type": "command",
|
|
82
|
+
"command": "bash $HOME/.claude/hooks/post-edit-lint.sh",
|
|
83
|
+
"async": true
|
|
84
|
+
}
|
|
85
|
+
]
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"matcher": "Write",
|
|
89
|
+
"hooks": [
|
|
90
|
+
{
|
|
91
|
+
"type": "command",
|
|
92
|
+
"command": "bash $HOME/.claude/hooks/post-edit-lint.sh",
|
|
93
|
+
"async": true
|
|
94
|
+
}
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
{
|
|
98
|
+
"matcher": "Bash|Edit|Write|MultiEdit|Agent|Task",
|
|
99
|
+
"hooks": [
|
|
100
|
+
{
|
|
101
|
+
"type": "command",
|
|
102
|
+
"command": "node \"$HOME/.claude/hooks/gsd-context-monitor.js\"",
|
|
103
|
+
"timeout": 3
|
|
104
|
+
}
|
|
105
|
+
]
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"matcher": "Bash|Edit|Write|Agent",
|
|
109
|
+
"hooks": [
|
|
110
|
+
{
|
|
111
|
+
"type": "command",
|
|
112
|
+
"command": "bash $HOME/.claude/hooks/session-log-action.sh",
|
|
113
|
+
"async": true
|
|
114
|
+
}
|
|
115
|
+
]
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
"matcher": "Bash|Edit|Write|Agent",
|
|
119
|
+
"hooks": [
|
|
120
|
+
{
|
|
121
|
+
"type": "command",
|
|
122
|
+
"command": "bash $HOME/.claude/hooks/session-checkpoint.sh",
|
|
123
|
+
"async": true
|
|
124
|
+
}
|
|
125
|
+
]
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"matcher": "Bash",
|
|
129
|
+
"hooks": [
|
|
130
|
+
{
|
|
131
|
+
"type": "command",
|
|
132
|
+
"command": "bash $HOME/.claude/hooks/post-commit-verify.sh",
|
|
133
|
+
"async": true
|
|
134
|
+
}
|
|
135
|
+
]
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
"matcher": "Bash",
|
|
139
|
+
"hooks": [
|
|
140
|
+
{
|
|
141
|
+
"type": "command",
|
|
142
|
+
"command": "bash $HOME/.claude/hooks/post-commit-memory-trigger.sh",
|
|
143
|
+
"async": true
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
"matcher": "Bash",
|
|
149
|
+
"hooks": [
|
|
150
|
+
{
|
|
151
|
+
"type": "command",
|
|
152
|
+
"command": "bash $HOME/.claude/hooks/linear-lifecycle-sync.sh",
|
|
153
|
+
"async": true
|
|
154
|
+
}
|
|
155
|
+
]
|
|
156
|
+
}
|
|
157
|
+
],
|
|
158
|
+
"UserPromptSubmit": [
|
|
159
|
+
{
|
|
160
|
+
"hooks": [
|
|
161
|
+
{
|
|
162
|
+
"type": "command",
|
|
163
|
+
"command": "bash $HOME/.claude/hooks/session-auto-title.sh"
|
|
164
|
+
}
|
|
165
|
+
]
|
|
166
|
+
}
|
|
167
|
+
],
|
|
168
|
+
"Stop": [
|
|
169
|
+
{
|
|
170
|
+
"hooks": [
|
|
171
|
+
{
|
|
172
|
+
"type": "command",
|
|
173
|
+
"command": "bash $HOME/.claude/hooks/session-cost-log.sh",
|
|
174
|
+
"async": true
|
|
175
|
+
}
|
|
176
|
+
]
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
"hooks": [
|
|
180
|
+
{
|
|
181
|
+
"type": "command",
|
|
182
|
+
"command": "bash $HOME/.claude/hooks/session-summarize.sh",
|
|
183
|
+
"async": true
|
|
184
|
+
}
|
|
185
|
+
]
|
|
186
|
+
},
|
|
187
|
+
{
|
|
188
|
+
"hooks": [
|
|
189
|
+
{
|
|
190
|
+
"type": "command",
|
|
191
|
+
"command": "bash $HOME/.claude/hooks/memory-extractor.sh",
|
|
192
|
+
"async": true
|
|
193
|
+
}
|
|
194
|
+
]
|
|
195
|
+
},
|
|
196
|
+
{
|
|
197
|
+
"hooks": [
|
|
198
|
+
{
|
|
199
|
+
"type": "command",
|
|
200
|
+
"command": "bash $HOME/.claude/hooks/desktop-notify.sh",
|
|
201
|
+
"async": true
|
|
202
|
+
}
|
|
203
|
+
]
|
|
204
|
+
}
|
|
205
|
+
],
|
|
206
|
+
"PreCompact": [
|
|
207
|
+
{
|
|
208
|
+
"hooks": [
|
|
209
|
+
{
|
|
210
|
+
"type": "command",
|
|
211
|
+
"command": "bash $HOME/.claude/hooks/precompact-save-context.sh"
|
|
212
|
+
}
|
|
213
|
+
]
|
|
214
|
+
}
|
|
215
|
+
],
|
|
216
|
+
"SessionStart": [
|
|
217
|
+
{
|
|
218
|
+
"hooks": [
|
|
219
|
+
{
|
|
220
|
+
"type": "command",
|
|
221
|
+
"command": "bash $HOME/.claude/hooks/session-restore.sh"
|
|
222
|
+
}
|
|
223
|
+
]
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
},
|
|
227
|
+
"statusLine": {
|
|
228
|
+
"type": "command",
|
|
229
|
+
"command": "bash $HOME/.claude/statusline-command.sh"
|
|
230
|
+
},
|
|
231
|
+
"enabledPlugins": {
|
|
232
|
+
"frontend-design@claude-plugins-official": true,
|
|
233
|
+
"context7@claude-plugins-official": true,
|
|
234
|
+
"ruby-lsp@claude-plugins-official": true,
|
|
235
|
+
"typescript-lsp@claude-plugins-official": true,
|
|
236
|
+
"pyright-lsp@claude-plugins-official": true,
|
|
237
|
+
"code-simplifier@claude-plugins-official": true,
|
|
238
|
+
"hookify@claude-plugins-official": true,
|
|
239
|
+
"claude-md-management@claude-plugins-official": true,
|
|
240
|
+
"commit-commands@claude-plugins-official": true,
|
|
241
|
+
"pr-review-toolkit@claude-plugins-official": true
|
|
242
|
+
},
|
|
243
|
+
"language": "spanish",
|
|
244
|
+
"alwaysThinkingEnabled": true,
|
|
245
|
+
"effortLevel": "high",
|
|
246
|
+
"autoCompactWindow": 500000,
|
|
247
|
+
"promptSuggestionEnabled": true,
|
|
248
|
+
"voiceEnabled": true,
|
|
249
|
+
"channelsEnabled": true,
|
|
250
|
+
"autoMemoryEnabled": true,
|
|
251
|
+
"autoMemoryDirectory": "~/.claude/memory",
|
|
252
|
+
"autoDreamEnabled": true,
|
|
253
|
+
"showThinkingSummaries": true,
|
|
254
|
+
"skipDangerousModePermissionPrompt": true
|
|
255
|
+
}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Claude Code status line script
|
|
3
|
+
# Reads JSON from stdin and prints a compact status line
|
|
4
|
+
# Also persists last-known stats for session cost logging
|
|
5
|
+
|
|
6
|
+
input=$(cat)
|
|
7
|
+
|
|
8
|
+
# --- Session ID (for per-session stat files) ---
|
|
9
|
+
session_id=$(echo "$input" | jq -r '.session_id // empty')
|
|
10
|
+
|
|
11
|
+
# --- Directory ---
|
|
12
|
+
cwd=$(echo "$input" | jq -r '.workspace.current_dir // .cwd // empty')
|
|
13
|
+
if [ -n "$cwd" ]; then
|
|
14
|
+
dir=$(basename "$cwd")
|
|
15
|
+
else
|
|
16
|
+
dir=$(basename "$(pwd)")
|
|
17
|
+
fi
|
|
18
|
+
|
|
19
|
+
# --- Git branch (skip optional locks) ---
|
|
20
|
+
branch=$(GIT_OPTIONAL_LOCKS=0 git -C "$cwd" symbolic-ref --short HEAD 2>/dev/null \
|
|
21
|
+
|| GIT_OPTIONAL_LOCKS=0 git -C "$cwd" rev-parse --short HEAD 2>/dev/null)
|
|
22
|
+
|
|
23
|
+
# --- Detect project type from cwd ---
|
|
24
|
+
node_ver=""
|
|
25
|
+
ruby_ver=""
|
|
26
|
+
|
|
27
|
+
# Node version — try .nvmrc in the cwd, then `node` on PATH
|
|
28
|
+
if [ -f "$cwd/.nvmrc" ]; then
|
|
29
|
+
node_ver="node:$(cat "$cwd/.nvmrc" | tr -d '[:space:]')"
|
|
30
|
+
elif command -v node &>/dev/null; then
|
|
31
|
+
node_ver="node:$(node --version 2>/dev/null | sed 's/v//')"
|
|
32
|
+
fi
|
|
33
|
+
|
|
34
|
+
# Ruby version — prefer .ruby-version in the cwd, then `ruby` on PATH
|
|
35
|
+
if [ -f "$cwd/.ruby-version" ]; then
|
|
36
|
+
ruby_ver="ruby:$(cat "$cwd/.ruby-version" | tr -d '[:space:]')"
|
|
37
|
+
elif command -v ruby &>/dev/null; then
|
|
38
|
+
ruby_ver="ruby:$(ruby --version 2>/dev/null | awk '{print $2}')"
|
|
39
|
+
fi
|
|
40
|
+
|
|
41
|
+
# --- Context window ---
|
|
42
|
+
remaining=$(echo "$input" | jq -r '.context_window.remaining_percentage // empty')
|
|
43
|
+
ctx_used=$(echo "$input" | jq -r '.context_window.used_percentage // empty')
|
|
44
|
+
total_input=$(echo "$input" | jq -r '.context_window.total_input_tokens // empty')
|
|
45
|
+
total_output=$(echo "$input" | jq -r '.context_window.total_output_tokens // empty')
|
|
46
|
+
|
|
47
|
+
# --- Cost ---
|
|
48
|
+
cost_usd=$(echo "$input" | jq -r '.cost.total_cost_usd // empty')
|
|
49
|
+
|
|
50
|
+
# --- Rate limits ---
|
|
51
|
+
five_h_pct=$(echo "$input" | jq -r '.rate_limits.five_hour.used_percentage // empty')
|
|
52
|
+
five_h_resets=$(echo "$input" | jq -r '.rate_limits.five_hour.resets_at // empty')
|
|
53
|
+
|
|
54
|
+
# --- Model short name ---
|
|
55
|
+
model=$(echo "$input" | jq -r '.model.display_name // empty' | sed 's/Claude //' | sed 's/ (.*)//')
|
|
56
|
+
|
|
57
|
+
# --- Persist last-known stats for Stop hook ---
|
|
58
|
+
if [ -n "$session_id" ]; then
|
|
59
|
+
stats_file="$HOME/.claude/session-stats-${session_id}.json"
|
|
60
|
+
echo "$input" | jq -c '{
|
|
61
|
+
session_id: .session_id,
|
|
62
|
+
cwd: (.workspace.current_dir // .cwd),
|
|
63
|
+
cost_usd: (.cost.total_cost_usd // 0),
|
|
64
|
+
total_input_tokens: (.context_window.total_input_tokens // 0),
|
|
65
|
+
total_output_tokens: (.context_window.total_output_tokens // 0),
|
|
66
|
+
ctx_used_pct: (.context_window.used_percentage // 0),
|
|
67
|
+
five_h_pct: (.rate_limits.five_hour.used_percentage // 0),
|
|
68
|
+
five_h_resets: (.rate_limits.five_hour.resets_at // 0),
|
|
69
|
+
model: (.model.display_name // ""),
|
|
70
|
+
timestamp: now | todate
|
|
71
|
+
}' > "$stats_file" 2>/dev/null
|
|
72
|
+
|
|
73
|
+
# Save starting 5h% once (first non-zero value = baseline before this session)
|
|
74
|
+
start_file="$HOME/.claude/session-stats-${session_id}-start.json"
|
|
75
|
+
if [ ! -f "$start_file" ] && [ -n "$five_h_pct" ] && [ "$five_h_pct" != "0" ]; then
|
|
76
|
+
echo "{\"five_h_pct_start\": $five_h_pct}" > "$start_file"
|
|
77
|
+
fi
|
|
78
|
+
fi
|
|
79
|
+
|
|
80
|
+
# --- Colors (ANSI) ---
|
|
81
|
+
CYAN='\033[0;36m'
|
|
82
|
+
GREEN='\033[0;32m'
|
|
83
|
+
YELLOW='\033[0;33m'
|
|
84
|
+
MAGENTA='\033[0;35m'
|
|
85
|
+
BLUE='\033[0;34m'
|
|
86
|
+
RED='\033[0;31m'
|
|
87
|
+
DIM='\033[2m'
|
|
88
|
+
RESET='\033[0m'
|
|
89
|
+
|
|
90
|
+
parts=()
|
|
91
|
+
|
|
92
|
+
# Directory
|
|
93
|
+
parts+=("$(printf "${CYAN}%s${RESET}" "$dir")")
|
|
94
|
+
|
|
95
|
+
# Git branch
|
|
96
|
+
if [ -n "$branch" ]; then
|
|
97
|
+
parts+=("$(printf "${GREEN}(%s)${RESET}" "$branch")")
|
|
98
|
+
fi
|
|
99
|
+
|
|
100
|
+
# Project runtime versions (only show what's relevant to the project)
|
|
101
|
+
is_node=false
|
|
102
|
+
is_ruby=false
|
|
103
|
+
[ -f "$cwd/package.json" ] || [ -f "$cwd/pnpm-lock.yaml" ] || [ -f "$cwd/.nvmrc" ] && is_node=true
|
|
104
|
+
[ -f "$cwd/Gemfile" ] || [ -f "$cwd/.ruby-version" ] && is_ruby=true
|
|
105
|
+
|
|
106
|
+
if $is_node && [ -n "$node_ver" ]; then
|
|
107
|
+
parts+=("$(printf "${YELLOW}%s${RESET}" "$node_ver")")
|
|
108
|
+
fi
|
|
109
|
+
if $is_ruby && [ -n "$ruby_ver" ]; then
|
|
110
|
+
parts+=("$(printf "${MAGENTA}%s${RESET}" "$ruby_ver")")
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
# Model
|
|
114
|
+
if [ -n "$model" ]; then
|
|
115
|
+
parts+=("$(printf "${BLUE}%s${RESET}" "$model")")
|
|
116
|
+
fi
|
|
117
|
+
|
|
118
|
+
# Context remaining
|
|
119
|
+
if [ -n "$remaining" ]; then
|
|
120
|
+
ctx_int=$(printf "%.0f" "$remaining")
|
|
121
|
+
if [ "$ctx_int" -le 20 ]; then
|
|
122
|
+
ctx_color="$RED"
|
|
123
|
+
else
|
|
124
|
+
ctx_color="$GREEN"
|
|
125
|
+
fi
|
|
126
|
+
parts+=("$(printf "${ctx_color}ctx:%s%%${RESET}" "$ctx_int")")
|
|
127
|
+
fi
|
|
128
|
+
|
|
129
|
+
# Cost — format: $1.26 (2 decimals if >= $0.10, 3 if smaller)
|
|
130
|
+
if [ -n "$cost_usd" ] && [ "$cost_usd" != "0" ]; then
|
|
131
|
+
cost_big=$(awk "BEGIN {exit !($cost_usd >= 0.10)}" 2>/dev/null && echo 1 || echo 0)
|
|
132
|
+
if [ "$cost_big" = "1" ]; then
|
|
133
|
+
cost_fmt=$(printf "%.2f" "$cost_usd" 2>/dev/null)
|
|
134
|
+
else
|
|
135
|
+
cost_fmt=$(printf "%.3f" "$cost_usd" 2>/dev/null)
|
|
136
|
+
fi
|
|
137
|
+
parts+=("$(printf "${YELLOW}\$%s${RESET}" "$cost_fmt")")
|
|
138
|
+
fi
|
|
139
|
+
|
|
140
|
+
# Rate limit 5h — shows acum% and +delta% for this session
|
|
141
|
+
if [ -n "$five_h_pct" ] && [ "$five_h_pct" != "0" ]; then
|
|
142
|
+
five_int=$(printf "%.0f" "$five_h_pct" 2>/dev/null)
|
|
143
|
+
if [ "$five_int" -ge 80 ]; then
|
|
144
|
+
rl_color="$RED"
|
|
145
|
+
elif [ "$five_int" -ge 50 ]; then
|
|
146
|
+
rl_color="$YELLOW"
|
|
147
|
+
else
|
|
148
|
+
rl_color="$DIM"
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Per-session delta
|
|
152
|
+
delta_str=""
|
|
153
|
+
if [ -n "$session_id" ]; then
|
|
154
|
+
start_file_check="$HOME/.claude/session-stats-${session_id}-start.json"
|
|
155
|
+
if [ -f "$start_file_check" ]; then
|
|
156
|
+
five_h_start_val=$(jq -r '.five_h_pct_start // 0' "$start_file_check" 2>/dev/null)
|
|
157
|
+
five_h_delta_val=$(awk "BEGIN {d=$five_h_pct-$five_h_start_val; printf \"%.1f\", (d<0?0:d)}")
|
|
158
|
+
delta_str=" (+${five_h_delta_val}%)"
|
|
159
|
+
fi
|
|
160
|
+
fi
|
|
161
|
+
|
|
162
|
+
# Show reset time if close to limit
|
|
163
|
+
reset_str=""
|
|
164
|
+
if [ "$five_int" -ge 70 ] && [ -n "$five_h_resets" ] && [ "$five_h_resets" != "0" ]; then
|
|
165
|
+
reset_time=$(date -r "$five_h_resets" '+%H:%M' 2>/dev/null || date -d "@$five_h_resets" '+%H:%M' 2>/dev/null)
|
|
166
|
+
[ -n "$reset_time" ] && reset_str=" reset@${reset_time}"
|
|
167
|
+
fi
|
|
168
|
+
parts+=("$(printf "${rl_color}5h:%s%%%s%s${RESET}" "$five_int" "$delta_str" "$reset_str")")
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
# Join with separator
|
|
172
|
+
sep=" | "
|
|
173
|
+
result=""
|
|
174
|
+
for part in "${parts[@]}"; do
|
|
175
|
+
if [ -z "$result" ]; then
|
|
176
|
+
result="$part"
|
|
177
|
+
else
|
|
178
|
+
result="$result$sep$part"
|
|
179
|
+
fi
|
|
180
|
+
done
|
|
181
|
+
|
|
182
|
+
printf "%b\n" "$result"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"preToolUseAgentMissingModel": {
|
|
3
|
+
"hook_event_name": "PreToolUse",
|
|
4
|
+
"tool_name": "Agent",
|
|
5
|
+
"tool_input": {
|
|
6
|
+
"description": "Audit installer behavior",
|
|
7
|
+
"prompt": "Review bootstrap profile side effects."
|
|
8
|
+
}
|
|
9
|
+
},
|
|
10
|
+
"preToolUseAgentWithModel": {
|
|
11
|
+
"hook_event_name": "PreToolUse",
|
|
12
|
+
"tool_name": "Agent",
|
|
13
|
+
"tool_input": {
|
|
14
|
+
"description": "Audit installer behavior",
|
|
15
|
+
"prompt": "Review bootstrap profile side effects.",
|
|
16
|
+
"model": "sonnet"
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"postToolUseEdit": {
|
|
20
|
+
"hook_event_name": "PostToolUse",
|
|
21
|
+
"tool_name": "Edit",
|
|
22
|
+
"tool_input": {
|
|
23
|
+
"file_path": "src/example.js",
|
|
24
|
+
"old_string": "const enabled = false;",
|
|
25
|
+
"new_string": "const enabled = true;"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"sessionStop": {
|
|
29
|
+
"hook_event_name": "Stop",
|
|
30
|
+
"session_id": "fixture-session"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# session-costs-view.sh
|
|
3
|
+
# Pretty-print the session costs log
|
|
4
|
+
# Usage:
|
|
5
|
+
# ~/.claude/tools/session-costs-view.sh → all sessions (last 30)
|
|
6
|
+
# ~/.claude/tools/session-costs-view.sh today → today only
|
|
7
|
+
# ~/.claude/tools/session-costs-view.sh week → last 7 days
|
|
8
|
+
# ~/.claude/tools/session-costs-view.sh summary → totals by day
|
|
9
|
+
|
|
10
|
+
LOG_FILE="$HOME/.claude/session-costs.log"
|
|
11
|
+
MODE="${1:-all}"
|
|
12
|
+
TODAY=$(date +%Y-%m-%d)
|
|
13
|
+
WEEK_AGO=$(date -v-7d +%Y-%m-%d 2>/dev/null || date -d "7 days ago" +%Y-%m-%d 2>/dev/null)
|
|
14
|
+
|
|
15
|
+
if [ ! -f "$LOG_FILE" ]; then
|
|
16
|
+
echo "No hay datos todavía. El log se crea al cerrar la primera sesión con actividad."
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
# ANSI colors
|
|
21
|
+
BOLD='\033[1m'
|
|
22
|
+
CYAN='\033[0;36m'
|
|
23
|
+
GREEN='\033[0;32m'
|
|
24
|
+
YELLOW='\033[0;33m'
|
|
25
|
+
RED='\033[0;31m'
|
|
26
|
+
DIM='\033[2m'
|
|
27
|
+
RESET='\033[0m'
|
|
28
|
+
|
|
29
|
+
# Filter rows based on mode (skip header)
|
|
30
|
+
case "$MODE" in
|
|
31
|
+
today)
|
|
32
|
+
DATA=$(tail -n +2 "$LOG_FILE" | grep "^${TODAY}")
|
|
33
|
+
TITLE="Sesiones de hoy (${TODAY})"
|
|
34
|
+
;;
|
|
35
|
+
week)
|
|
36
|
+
DATA=$(tail -n +2 "$LOG_FILE" | awk -F',' -v cutoff="$WEEK_AGO" '$1 >= cutoff')
|
|
37
|
+
TITLE="Últimos 7 días"
|
|
38
|
+
;;
|
|
39
|
+
summary)
|
|
40
|
+
echo -e "${BOLD}=== Resumen por día ===${RESET}"
|
|
41
|
+
echo ""
|
|
42
|
+
tail -n +2 "$LOG_FILE" | awk -F',' '
|
|
43
|
+
{
|
|
44
|
+
day[$1] += $5
|
|
45
|
+
sessions[$1]++
|
|
46
|
+
tokens[$1] += ($6 + $7)
|
|
47
|
+
five_h_delta[$1] += $10
|
|
48
|
+
}
|
|
49
|
+
END {
|
|
50
|
+
for (d in day) {
|
|
51
|
+
printf "%s sesiones: %2d costo: $%.2f tokens: %5dk limite-5h usado: %.1f%%\n",
|
|
52
|
+
d, sessions[d], day[d], tokens[d]/1000, five_h_delta[d]
|
|
53
|
+
}
|
|
54
|
+
}' | sort -r
|
|
55
|
+
echo ""
|
|
56
|
+
TOTAL=$(tail -n +2 "$LOG_FILE" | awk -F',' '{sum+=$5} END {printf "%.2f", sum}')
|
|
57
|
+
SESSIONS=$(tail -n +2 "$LOG_FILE" | wc -l | tr -d ' ')
|
|
58
|
+
TOTAL_5H=$(tail -n +2 "$LOG_FILE" | awk -F',' '{sum+=$10} END {printf "%.1f", sum}')
|
|
59
|
+
echo -e "${BOLD}Total acumulado: \$${TOTAL} en ${SESSIONS} sesión(es) — ${TOTAL_5H}% del límite de 5h consumido en total${RESET}"
|
|
60
|
+
exit 0
|
|
61
|
+
;;
|
|
62
|
+
*)
|
|
63
|
+
DATA=$(tail -n +2 "$LOG_FILE" | tail -30)
|
|
64
|
+
TITLE="Últimas 30 sesiones"
|
|
65
|
+
;;
|
|
66
|
+
esac
|
|
67
|
+
|
|
68
|
+
if [ -z "$DATA" ]; then
|
|
69
|
+
echo "Sin datos para el período seleccionado."
|
|
70
|
+
exit 0
|
|
71
|
+
fi
|
|
72
|
+
|
|
73
|
+
echo -e "${BOLD}=== ${TITLE} ===${RESET}"
|
|
74
|
+
echo ""
|
|
75
|
+
# Header: date time session project cost in out ctx% 5h-acum% 5h-sesion%
|
|
76
|
+
printf "${BOLD}%-12s %-6s %-10s %-18s %7s %7s %7s %6s %8s %9s${RESET}\n" \
|
|
77
|
+
"Fecha" "Hora" "Session" "Proyecto" "Costo" "In-tok" "Out-tok" "Ctx%" "5h-acum" "5h-sesion"
|
|
78
|
+
echo "────────────────────────────────────────────────────────────────────────────────────────────"
|
|
79
|
+
|
|
80
|
+
TOTAL_COST=0
|
|
81
|
+
TOTAL_5H_DELTA=0
|
|
82
|
+
while IFS=',' read -r date time sess proj cost in_tok out_tok ctx_pct five_h_end five_h_delta model; do
|
|
83
|
+
# Color cost
|
|
84
|
+
cost_cents=$(awk "BEGIN {printf \"%.0f\", ${cost:-0} * 100}" 2>/dev/null)
|
|
85
|
+
if [ "${cost_cents:-0}" -gt 100 ]; then
|
|
86
|
+
cost_color="$RED"
|
|
87
|
+
elif [ "${cost_cents:-0}" -gt 30 ]; then
|
|
88
|
+
cost_color="$YELLOW"
|
|
89
|
+
else
|
|
90
|
+
cost_color="$GREEN"
|
|
91
|
+
fi
|
|
92
|
+
|
|
93
|
+
# Color 5h acumulado
|
|
94
|
+
five_end_int=$(printf "%.0f" "${five_h_end:-0}" 2>/dev/null)
|
|
95
|
+
if [ "${five_end_int:-0}" -ge 80 ]; then
|
|
96
|
+
five_end_color="$RED"
|
|
97
|
+
elif [ "${five_end_int:-0}" -ge 50 ]; then
|
|
98
|
+
five_end_color="$YELLOW"
|
|
99
|
+
else
|
|
100
|
+
five_end_color="$DIM"
|
|
101
|
+
fi
|
|
102
|
+
|
|
103
|
+
# Color 5h delta de esta sesión
|
|
104
|
+
five_delta_int=$(printf "%.0f" "${five_h_delta:-0}" 2>/dev/null)
|
|
105
|
+
if [ "${five_delta_int:-0}" -ge 20 ]; then
|
|
106
|
+
five_delta_color="$RED"
|
|
107
|
+
elif [ "${five_delta_int:-0}" -ge 10 ]; then
|
|
108
|
+
five_delta_color="$YELLOW"
|
|
109
|
+
else
|
|
110
|
+
five_delta_color="$CYAN"
|
|
111
|
+
fi
|
|
112
|
+
|
|
113
|
+
in_k=$(awk "BEGIN {printf \"%.0f\", ${in_tok:-0}/1000}" 2>/dev/null)k
|
|
114
|
+
out_k=$(awk "BEGIN {printf \"%.0f\", ${out_tok:-0}/1000}" 2>/dev/null)k
|
|
115
|
+
|
|
116
|
+
printf "${DIM}%-12s %-6s${RESET} ${CYAN}%-10s${RESET} %-18s ${cost_color}%7s${RESET} %7s %7s %5s%% ${five_end_color}%7s%%${RESET} ${five_delta_color}%8s%%${RESET}\n" \
|
|
117
|
+
"$date" "$time" "$sess" "${proj:0:18}" "\$$cost" "$in_k" "$out_k" "$ctx_pct" "$five_h_end" "$five_h_delta"
|
|
118
|
+
|
|
119
|
+
TOTAL_COST=$(awk "BEGIN {printf \"%.2f\", $TOTAL_COST + ${cost:-0}}" 2>/dev/null)
|
|
120
|
+
TOTAL_5H_DELTA=$(awk "BEGIN {printf \"%.1f\", $TOTAL_5H_DELTA + ${five_h_delta:-0}}" 2>/dev/null)
|
|
121
|
+
done <<< "$DATA"
|
|
122
|
+
|
|
123
|
+
echo "────────────────────────────────────────────────────────────────────────────────────────────"
|
|
124
|
+
COUNT=$(echo "$DATA" | wc -l | tr -d ' ')
|
|
125
|
+
echo -e "${BOLD}Total: \$${TOTAL_COST} en ${COUNT} sesión(es) — ${TOTAL_5H_DELTA}% del límite de 5h consumido${RESET}"
|
|
126
|
+
echo ""
|
|
127
|
+
echo -e "${DIM}Columna '5h-sesion' = cuánto del límite de 5h consumió esta sesión específica${RESET}"
|
|
128
|
+
echo -e "${DIM}Modos: $(basename "$0") [today|week|summary|all]${RESET}"
|