aiblueprint-cli 1.0.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/README.md +120 -0
- package/claude-code-config/agents/epct/code.md +28 -0
- package/claude-code-config/agents/epct/explore-orchestrator.md +32 -0
- package/claude-code-config/agents/epct/explore.md +28 -0
- package/claude-code-config/agents/epct/plan.md +14 -0
- package/claude-code-config/agents/epct/test.md +12 -0
- package/claude-code-config/agents/product/feedback-synthesizer.md +146 -0
- package/claude-code-config/agents/product/sprint-prioritizer.md +102 -0
- package/claude-code-config/agents/product/trend-researcher.md +157 -0
- package/claude-code-config/agents/tasks/app-store-optimizer.md +192 -0
- package/claude-code-config/agents/tasks/backend-reliability-engineer.md +126 -0
- package/claude-code-config/agents/tasks/code.md +12 -0
- package/claude-code-config/agents/tasks/frontend-ux-specialist.md +136 -0
- package/claude-code-config/agents/tasks/growth-hacker.md +209 -0
- package/claude-code-config/agents/tasks/prd-writer.md +141 -0
- package/claude-code-config/agents/tasks/senior-software-engineer.md +75 -0
- package/claude-code-config/agents/tasks/twitter-engager.md +126 -0
- package/claude-code-config/commands/commit.md +15 -0
- package/claude-code-config/commands/create-pull-request.md +31 -0
- package/claude-code-config/commands/deep-code-analysis.md +37 -0
- package/claude-code-config/commands/deploy.md +20 -0
- package/claude-code-config/commands/epct-agent.md +28 -0
- package/claude-code-config/commands/epct.md +41 -0
- package/claude-code-config/commands/fix-pr-comments.md +10 -0
- package/claude-code-config/commands/run-tasks.md +50 -0
- package/claude-code-config/commands/watch-ci.md +22 -0
- package/claude-code-config/output-styles/assistant.md +15 -0
- package/claude-code-config/output-styles/honnest.md +9 -0
- package/claude-code-config/output-styles/senior-dev.md +14 -0
- package/claude-code-config/scripts/statusline-ccusage.sh +156 -0
- package/claude-code-config/scripts/statusline.readme.md +194 -0
- package/claude-code-config/scripts/validate-command.js +621 -0
- package/claude-code-config/scripts/validate-command.readme.md +283 -0
- package/claude-code-config/song/finish.mp3 +0 -0
- package/claude-code-config/song/need-human.mp3 +0 -0
- package/dist/cli.js +5395 -0
- package/package.json +46 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# ANSI color codes
|
|
4
|
+
GREEN='\033[0;32m'
|
|
5
|
+
RED='\033[0;31m'
|
|
6
|
+
PURPLE='\033[0;35m'
|
|
7
|
+
GRAY='\033[0;90m'
|
|
8
|
+
LIGHT_GRAY='\033[0;37m'
|
|
9
|
+
RESET='\033[0m'
|
|
10
|
+
|
|
11
|
+
# Read JSON input from stdin
|
|
12
|
+
input=$(cat)
|
|
13
|
+
|
|
14
|
+
# Extract current session ID and model info from Claude Code input
|
|
15
|
+
session_id=$(echo "$input" | jq -r '.session_id // empty')
|
|
16
|
+
model_name=$(echo "$input" | jq -r '.model.display_name // empty')
|
|
17
|
+
current_dir=$(echo "$input" | jq -r '.workspace.current_dir // empty')
|
|
18
|
+
cwd=$(echo "$input" | jq -r '.cwd // empty')
|
|
19
|
+
output_style=$(echo "$input" | jq -r '.output_style.name // empty')
|
|
20
|
+
|
|
21
|
+
# Get current git branch with error handling
|
|
22
|
+
if git rev-parse --git-dir >/dev/null 2>&1; then
|
|
23
|
+
branch=$(git branch --show-current 2>/dev/null || echo "detached")
|
|
24
|
+
if [ -z "$branch" ]; then
|
|
25
|
+
branch="detached"
|
|
26
|
+
fi
|
|
27
|
+
|
|
28
|
+
# Check for pending changes (staged or unstaged)
|
|
29
|
+
if ! git diff-index --quiet HEAD -- 2>/dev/null || ! git diff-index --quiet --cached HEAD -- 2>/dev/null; then
|
|
30
|
+
# Get line changes for unstaged and staged changes
|
|
31
|
+
unstaged_stats=$(git diff --numstat 2>/dev/null | awk '{added+=$1; deleted+=$2} END {print added+0, deleted+0}')
|
|
32
|
+
staged_stats=$(git diff --cached --numstat 2>/dev/null | awk '{added+=$1; deleted+=$2} END {print added+0, deleted+0}')
|
|
33
|
+
|
|
34
|
+
# Parse the stats
|
|
35
|
+
unstaged_added=$(echo $unstaged_stats | cut -d' ' -f1)
|
|
36
|
+
unstaged_deleted=$(echo $unstaged_stats | cut -d' ' -f2)
|
|
37
|
+
staged_added=$(echo $staged_stats | cut -d' ' -f1)
|
|
38
|
+
staged_deleted=$(echo $staged_stats | cut -d' ' -f2)
|
|
39
|
+
|
|
40
|
+
# Total changes
|
|
41
|
+
total_added=$((unstaged_added + staged_added))
|
|
42
|
+
total_deleted=$((unstaged_deleted + staged_deleted))
|
|
43
|
+
|
|
44
|
+
# Build the branch display with changes (with colors)
|
|
45
|
+
changes=""
|
|
46
|
+
if [ $total_added -gt 0 ]; then
|
|
47
|
+
changes="${GREEN}+$total_added${RESET}"
|
|
48
|
+
fi
|
|
49
|
+
if [ $total_deleted -gt 0 ]; then
|
|
50
|
+
if [ -n "$changes" ]; then
|
|
51
|
+
changes="$changes ${RED}-$total_deleted${RESET}"
|
|
52
|
+
else
|
|
53
|
+
changes="${RED}-$total_deleted${RESET}"
|
|
54
|
+
fi
|
|
55
|
+
fi
|
|
56
|
+
|
|
57
|
+
if [ -n "$changes" ]; then
|
|
58
|
+
branch="$branch${PURPLE}*${RESET} ($changes)"
|
|
59
|
+
else
|
|
60
|
+
branch="$branch${PURPLE}*${RESET}"
|
|
61
|
+
fi
|
|
62
|
+
fi
|
|
63
|
+
else
|
|
64
|
+
branch="no-git"
|
|
65
|
+
fi
|
|
66
|
+
|
|
67
|
+
# Get basename of current directory
|
|
68
|
+
dir_name=$(basename "$current_dir")
|
|
69
|
+
|
|
70
|
+
# Get today's date in YYYYMMDD format
|
|
71
|
+
today=$(date +%Y%m%d)
|
|
72
|
+
|
|
73
|
+
# Function to format numbers
|
|
74
|
+
format_cost() {
|
|
75
|
+
printf "%.2f" "$1"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
format_tokens() {
|
|
79
|
+
local tokens=$1
|
|
80
|
+
if [ "$tokens" -ge 1000000 ]; then
|
|
81
|
+
printf "%.1fM" "$(echo "scale=1; $tokens / 1000000" | bc -l)"
|
|
82
|
+
elif [ "$tokens" -ge 1000 ]; then
|
|
83
|
+
printf "%.1fK" "$(echo "scale=1; $tokens / 1000" | bc -l)"
|
|
84
|
+
else
|
|
85
|
+
printf "%d" "$tokens"
|
|
86
|
+
fi
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
format_time() {
|
|
90
|
+
local minutes=$1
|
|
91
|
+
local hours=$((minutes / 60))
|
|
92
|
+
local mins=$((minutes % 60))
|
|
93
|
+
if [ "$hours" -gt 0 ]; then
|
|
94
|
+
printf "%dh %dm" "$hours" "$mins"
|
|
95
|
+
else
|
|
96
|
+
printf "%dm" "$mins"
|
|
97
|
+
fi
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
# Initialize variables with defaults
|
|
101
|
+
session_cost="0.00"
|
|
102
|
+
session_tokens=0
|
|
103
|
+
daily_cost="0.00"
|
|
104
|
+
block_cost="0.00"
|
|
105
|
+
remaining_time="N/A"
|
|
106
|
+
|
|
107
|
+
# Get current session data using ccusage session --id
|
|
108
|
+
if command -v ccusage >/dev/null 2>&1 && [ -n "$session_id" ] && [ "$session_id" != "empty" ]; then
|
|
109
|
+
# Use the new ccusage session --id functionality to get session data
|
|
110
|
+
session_data=$(ccusage session --id "$session_id" --json 2>/dev/null)
|
|
111
|
+
|
|
112
|
+
if [ $? -eq 0 ] && [ -n "$session_data" ] && [ "$session_data" != "null" ]; then
|
|
113
|
+
# Extract cost and tokens from the JSON response
|
|
114
|
+
session_cost=$(echo "$session_data" | jq -r '.totalCost // 0')
|
|
115
|
+
# Calculate only input + output tokens (exclude cache tokens for meaningful display)
|
|
116
|
+
session_tokens=$(echo "$session_data" | jq -r '.entries | map(.inputTokens + .outputTokens) | add // 0')
|
|
117
|
+
fi
|
|
118
|
+
fi
|
|
119
|
+
|
|
120
|
+
if command -v ccusage >/dev/null 2>&1; then
|
|
121
|
+
# Get daily data
|
|
122
|
+
daily_data=$(ccusage daily --json --since "$today" 2>/dev/null)
|
|
123
|
+
if [ $? -eq 0 ] && [ -n "$daily_data" ]; then
|
|
124
|
+
daily_cost=$(echo "$daily_data" | jq -r '.totals.totalCost // 0')
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Get active block data
|
|
128
|
+
block_data=$(ccusage blocks --active --json 2>/dev/null)
|
|
129
|
+
if [ $? -eq 0 ] && [ -n "$block_data" ]; then
|
|
130
|
+
active_block=$(echo "$block_data" | jq -r '.blocks[] | select(.isActive == true) // empty')
|
|
131
|
+
if [ -n "$active_block" ] && [ "$active_block" != "null" ]; then
|
|
132
|
+
block_cost=$(echo "$active_block" | jq -r '.costUSD // 0')
|
|
133
|
+
remaining_minutes=$(echo "$active_block" | jq -r '.projection.remainingMinutes // 0')
|
|
134
|
+
if [ "$remaining_minutes" != "0" ] && [ "$remaining_minutes" != "null" ]; then
|
|
135
|
+
remaining_time=$(format_time "$remaining_minutes")
|
|
136
|
+
fi
|
|
137
|
+
fi
|
|
138
|
+
fi
|
|
139
|
+
fi
|
|
140
|
+
|
|
141
|
+
# Format the output
|
|
142
|
+
formatted_session_cost=$(format_cost "$session_cost")
|
|
143
|
+
formatted_daily_cost=$(format_cost "$daily_cost")
|
|
144
|
+
formatted_block_cost=$(format_cost "$block_cost")
|
|
145
|
+
formatted_tokens=$(format_tokens "$session_tokens")
|
|
146
|
+
|
|
147
|
+
# Build the status line with colors (light gray as default)
|
|
148
|
+
status_line="${LIGHT_GRAY}🌿 $branch ${GRAY}|${LIGHT_GRAY} 💄 $output_style ${GRAY}|${LIGHT_GRAY} 📁 $dir_name ${GRAY}|${LIGHT_GRAY} 🤖 $model_name ${GRAY}|${LIGHT_GRAY} 💰 \$$formatted_session_cost ${GRAY}/${LIGHT_GRAY} 📅 \$$formatted_daily_cost ${GRAY}/${LIGHT_GRAY} 🧊 \$$formatted_block_cost"
|
|
149
|
+
|
|
150
|
+
if [ "$remaining_time" != "N/A" ]; then
|
|
151
|
+
status_line="$status_line ($remaining_time left)"
|
|
152
|
+
fi
|
|
153
|
+
|
|
154
|
+
status_line="$status_line ${GRAY}|${LIGHT_GRAY} 🧩 ${formatted_tokens} ${GRAY}tokens${RESET}"
|
|
155
|
+
|
|
156
|
+
printf "%b\n" "$status_line"
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Claude Code Statusline with ccusage Integration
|
|
2
|
+
|
|
3
|
+
A custom statusline script that integrates with [ccusage](https://github.com/ryoppippi/ccusage) to display real-time Claude Code usage statistics, including session costs, daily usage, and token counts.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🌿 **Git branch status** with change indicators (+/-)
|
|
8
|
+
- 📁 **Current directory** name
|
|
9
|
+
- 🤖 **Claude model** being used
|
|
10
|
+
- 💰 **Session cost** for current conversation
|
|
11
|
+
- 📅 **Daily cost** total
|
|
12
|
+
- 🧊 **Block cost** with remaining time
|
|
13
|
+
- 🧩 **Token count** for current session (input + output only)
|
|
14
|
+
|
|
15
|
+
## Requirements
|
|
16
|
+
|
|
17
|
+
- [ccusage](https://github.com/ryoppippi/ccusage) v15.9.4 or later (for `--id` support)
|
|
18
|
+
- `jq` for JSON parsing
|
|
19
|
+
- `git` for repository information
|
|
20
|
+
|
|
21
|
+
## Installation
|
|
22
|
+
|
|
23
|
+
```bash
|
|
24
|
+
# Install ccusage
|
|
25
|
+
npm install -g ccusage
|
|
26
|
+
|
|
27
|
+
# Make script executable
|
|
28
|
+
chmod +x statusline-ccusage.sh
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
The script expects Claude Code input format via stdin:
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
echo '{"session_id":"your-session-id","model":{"display_name":"Claude 3.5 Sonnet"},"workspace":{"current_dir":"/path/to/project"}}' | ./statusline-ccusage.sh
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## How It Works
|
|
40
|
+
|
|
41
|
+
### Session Data Retrieval
|
|
42
|
+
|
|
43
|
+
The script uses the new `ccusage session --id` functionality (added in ccusage v15.9.4) to fetch session data:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
ccusage session --id "$session_id" --json
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
This returns detailed session information including:
|
|
50
|
+
- Total cost for the session
|
|
51
|
+
- Individual message entries with token counts
|
|
52
|
+
- Cache usage statistics
|
|
53
|
+
|
|
54
|
+
### Token Calculation
|
|
55
|
+
|
|
56
|
+
**Important**: The script calculates only meaningful conversation tokens:
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
# Only input + output tokens (excludes cache tokens)
|
|
60
|
+
session_tokens=$(echo "$session_data" | jq -r '.entries | map(.inputTokens + .outputTokens) | add // 0')
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
**Why exclude cache tokens?**
|
|
64
|
+
- Cache tokens represent context being stored/reused internally
|
|
65
|
+
- They don't represent the actual conversation size
|
|
66
|
+
- Including them inflates counts (e.g., 433K vs 2.7K tokens)
|
|
67
|
+
- For statusline display, conversation tokens are more meaningful
|
|
68
|
+
|
|
69
|
+
## Finding Your Claude Code Session ID
|
|
70
|
+
|
|
71
|
+
### Method 1: From Session Files
|
|
72
|
+
|
|
73
|
+
Session IDs are stored as `.jsonl` files in your Claude directory:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
# Find recent session files
|
|
77
|
+
find ~/.claude -name "*.jsonl" | head -5
|
|
78
|
+
|
|
79
|
+
# Example output:
|
|
80
|
+
# /Users/user/.claude/projects/project-name/428e9ec6-86f3-43c1-a0cd-9a3986d82229.jsonl
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
The session ID is the UUID part: `428e9ec6-86f3-43c1-a0cd-9a3986d82229`
|
|
84
|
+
|
|
85
|
+
### Method 2: From ccusage Session List
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# List all sessions to see available IDs
|
|
89
|
+
ccusage session
|
|
90
|
+
|
|
91
|
+
# The session names in the first column can sometimes be used as IDs
|
|
92
|
+
# But UUID-based IDs are more reliable
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Method 3: Test with Known Session
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
# Test if a session ID works
|
|
99
|
+
ccusage session --id "your-session-id" --json
|
|
100
|
+
|
|
101
|
+
# Returns session data if valid, or null if not found
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
## Testing the Script
|
|
105
|
+
|
|
106
|
+
### 1. Test with a Real Session ID
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
# Find a session ID
|
|
110
|
+
SESSION_ID=$(find ~/.claude -name "*.jsonl" | head -1 | xargs basename -s .jsonl)
|
|
111
|
+
|
|
112
|
+
# Test the script
|
|
113
|
+
echo "{\"session_id\":\"$SESSION_ID\",\"model\":{\"display_name\":\"Claude 3.5 Sonnet\"},\"workspace\":{\"current_dir\":\"$(pwd)\"}}" | ./statusline-ccusage.sh
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
### 2. Test Individual Components
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
# Test session data retrieval
|
|
120
|
+
ccusage session --id "your-session-id" --json
|
|
121
|
+
|
|
122
|
+
# Test token calculation
|
|
123
|
+
ccusage session --id "your-session-id" --json | jq '.entries | map(.inputTokens + .outputTokens) | add'
|
|
124
|
+
|
|
125
|
+
# Test daily usage
|
|
126
|
+
ccusage daily --json --since "$(date +%Y%m%d)"
|
|
127
|
+
|
|
128
|
+
# Test active blocks
|
|
129
|
+
ccusage blocks --active --json
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### 3. Expected Output
|
|
133
|
+
|
|
134
|
+
The statusline should display something like:
|
|
135
|
+
```
|
|
136
|
+
🌿 main* (+15 -3) | 📁 project-name | 🤖 Claude 3.5 Sonnet | 💰 $0.26 / 📅 $8.03 / 🧊 $8.03 (2h 45m left) | 🧩 2.7K tokens
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
## Troubleshooting
|
|
140
|
+
|
|
141
|
+
### ccusage Version Issues
|
|
142
|
+
|
|
143
|
+
Ensure you have the latest version with `--id` support:
|
|
144
|
+
|
|
145
|
+
```bash
|
|
146
|
+
# Check version (needs 15.9.4+)
|
|
147
|
+
ccusage --version
|
|
148
|
+
|
|
149
|
+
# Update if needed
|
|
150
|
+
npm update -g ccusage
|
|
151
|
+
|
|
152
|
+
# Verify --id option exists
|
|
153
|
+
ccusage session --help | grep -A5 -B5 "id"
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Session ID Not Found
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
# Returns null - session doesn't exist
|
|
160
|
+
ccusage session --id "invalid-id" --json
|
|
161
|
+
|
|
162
|
+
# Check if session files exist
|
|
163
|
+
ls ~/.claude/projects/*/your-session-id.jsonl
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### Permission Issues
|
|
167
|
+
|
|
168
|
+
```bash
|
|
169
|
+
# Make script executable
|
|
170
|
+
chmod +x statusline-ccusage.sh
|
|
171
|
+
|
|
172
|
+
# Check file permissions
|
|
173
|
+
ls -la statusline-ccusage.sh
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Integration with Claude Code
|
|
177
|
+
|
|
178
|
+
This script is designed to work with Claude Code's statusline feature. Configure it in your Claude Code settings to display real-time usage information during your coding sessions.
|
|
179
|
+
|
|
180
|
+
## What We Improved
|
|
181
|
+
|
|
182
|
+
### Before (Custom Logic)
|
|
183
|
+
- 50+ lines of complex session file parsing
|
|
184
|
+
- Manual JSONL file searching and parsing
|
|
185
|
+
- Inconsistent cost calculations
|
|
186
|
+
- Included cache tokens (inflated counts)
|
|
187
|
+
|
|
188
|
+
### After (ccusage Integration)
|
|
189
|
+
- ~10 lines using official ccusage API
|
|
190
|
+
- Reliable session data via `ccusage session --id`
|
|
191
|
+
- Consistent cost calculations matching ccusage
|
|
192
|
+
- Only meaningful conversation tokens displayed
|
|
193
|
+
|
|
194
|
+
The new approach is more maintainable, accurate, and leverages the official ccusage functionality instead of duplicating complex logic.
|