@jeremyy_prt/cc-config 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 +159 -0
- package/agents/corriger-orthographe.md +49 -0
- package/agents/explorer-code.md +63 -0
- package/agents/explorer-docs.md +87 -0
- package/agents/recherche-web.md +46 -0
- package/cli.js +213 -0
- package/commands/commit.md +47 -0
- package/commands/corriger-orthographe.md +59 -0
- package/commands/creer-agent.md +126 -0
- package/commands/creer-commande.md +225 -0
- package/commands/liste-commande.md +103 -0
- package/commands/memoire-claude.md +190 -0
- package/commands/surveiller-ci.md +65 -0
- package/package.json +44 -0
- package/scripts/statusline/CLAUDE.md +178 -0
- package/scripts/statusline/README.md +105 -0
- package/scripts/statusline/biome.json +34 -0
- package/scripts/statusline/bun.lockb +0 -0
- package/scripts/statusline/data/.gitignore +5 -0
- package/scripts/statusline/fixtures/test-input.json +25 -0
- package/scripts/statusline/package.json +21 -0
- package/scripts/statusline/src/commands/CLAUDE.md +3 -0
- package/scripts/statusline/src/commands/spend-month.ts +60 -0
- package/scripts/statusline/src/commands/spend-today.ts +42 -0
- package/scripts/statusline/src/index.ts +199 -0
- package/scripts/statusline/src/lib/context.ts +103 -0
- package/scripts/statusline/src/lib/formatters.ts +218 -0
- package/scripts/statusline/src/lib/git.ts +100 -0
- package/scripts/statusline/src/lib/spend.ts +119 -0
- package/scripts/statusline/src/lib/types.ts +25 -0
- package/scripts/statusline/src/lib/usage-limits.ts +147 -0
- package/scripts/statusline/statusline.config.ts +125 -0
- package/scripts/statusline/test.ts +20 -0
- package/scripts/statusline/tsconfig.json +27 -0
- package/scripts/validate-command.js +707 -0
- package/scripts/validate-command.readme.md +283 -0
- package/settings.json +42 -0
- package/song/finish.mp3 +0 -0
- package/song/need-human.mp3 +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
---
|
|
2
|
+
description: Surveiller et corriger automatiquement les erreurs de CI GitHub Actions
|
|
3
|
+
allowed-tools: Bash(gh :*), Bash(git :*), Bash(sleep :*)
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
Tu es un outil de surveillance et correction automatique de CI. Surveille les runs GitHub Actions et corrige les erreurs jusqu'à ce que tout passe (max 3 tentatives).
|
|
7
|
+
|
|
8
|
+
## Workflow
|
|
9
|
+
|
|
10
|
+
1. **ATTENDRE LE DÉMARRAGE**: Laisser le temps au CI de démarrer
|
|
11
|
+
- `sleep 10` pour attendre que le workflow démarre
|
|
12
|
+
- **CRITIQUE**: Le CI met quelques secondes à apparaître après un push
|
|
13
|
+
|
|
14
|
+
2. **SURVEILLER LE RUN**: Observer le pipeline en temps réel
|
|
15
|
+
- `gh run list --limit 1` pour obtenir l'ID du dernier run
|
|
16
|
+
- `gh run watch <run-id>` pour surveiller en direct
|
|
17
|
+
- **ATTENDRE**: Que le run se termine (succès ou échec)
|
|
18
|
+
|
|
19
|
+
3. **SI SUCCÈS**: Nettoyer et terminer
|
|
20
|
+
- Supprimer les artifacts téléchargés s'il y en a
|
|
21
|
+
- Afficher le statut final avec `gh run view <run-id>`
|
|
22
|
+
- **STOP**: Mission accomplie
|
|
23
|
+
|
|
24
|
+
4. **SI ÉCHEC**: Analyser et corriger (max 3 tentatives)
|
|
25
|
+
- `gh run view <run-id> --log-failed` pour récupérer les logs d'erreur
|
|
26
|
+
- Analyser les erreurs pour identifier la cause racine
|
|
27
|
+
- Faire les corrections ciblées dans le code
|
|
28
|
+
- Commit avec message descriptif: `fix(ci): [ce qui a été corrigé]`
|
|
29
|
+
- `git push` pour déclencher un nouveau run
|
|
30
|
+
- **INCRÉMENTER**: Le compteur de tentatives
|
|
31
|
+
- **BOUCLER**: Retourner à l'étape 1 (sauf si 3 tentatives atteintes)
|
|
32
|
+
|
|
33
|
+
5. **SI 3 ÉCHECS**: Rapporter et arrêter
|
|
34
|
+
- Afficher un résumé des 3 tentatives et erreurs
|
|
35
|
+
- **STOP**: L'intervention humaine est nécessaire
|
|
36
|
+
|
|
37
|
+
## Règles d'Exécution
|
|
38
|
+
|
|
39
|
+
- **MAX 3 TENTATIVES**: Éviter les boucles infinies
|
|
40
|
+
- **CORRECTIONS CIBLÉES**: Corriger uniquement les erreurs CI, pas de refactoring
|
|
41
|
+
- **MESSAGES DESCRIPTIFS**: Chaque commit doit expliquer la correction
|
|
42
|
+
- **VÉRIFIER AVANT DE PUSH**: S'assurer que la correction a du sens
|
|
43
|
+
- **FOCUS CI**: Rester concentré sur les erreurs de pipeline uniquement
|
|
44
|
+
|
|
45
|
+
## Exemples de Messages de Commit
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
fix(ci): install missing dependency @types/node
|
|
49
|
+
fix(ci): update node version to 18 in workflow
|
|
50
|
+
fix(ci): fix eslint errors in api routes
|
|
51
|
+
fix(ci): add missing env variables for tests
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Outils Autorisés
|
|
55
|
+
|
|
56
|
+
- `gh run list` - Lister les runs
|
|
57
|
+
- `gh run watch <id>` - Surveiller un run
|
|
58
|
+
- `gh run view <id>` - Voir les détails d'un run
|
|
59
|
+
- `gh run view <id> --log-failed` - Logs des échecs
|
|
60
|
+
- `git add`, `git commit`, `git push` - Corrections
|
|
61
|
+
- `sleep` - Attendre le démarrage du CI
|
|
62
|
+
|
|
63
|
+
## Priorité
|
|
64
|
+
|
|
65
|
+
Précision des corrections > Vitesse. Bien comprendre l'erreur avant de corriger.
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@jeremyy_prt/cc-config",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Configuration personnalisée pour Claude Code avec commandes et agents en français",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"cc-config": "cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"setup": "node cli.js setup"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"claude",
|
|
14
|
+
"claude-code",
|
|
15
|
+
"config",
|
|
16
|
+
"français",
|
|
17
|
+
"commands",
|
|
18
|
+
"agents",
|
|
19
|
+
"jeremy",
|
|
20
|
+
"productivity"
|
|
21
|
+
],
|
|
22
|
+
"author": "Jeremy (@jeremyy_prt)",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/jeremy-prt/cc-config.git"
|
|
27
|
+
},
|
|
28
|
+
"homepage": "https://github.com/jeremy-prt/cc-config#readme",
|
|
29
|
+
"bugs": {
|
|
30
|
+
"url": "https://github.com/jeremy-prt/cc-config/issues"
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"commands/",
|
|
34
|
+
"agents/",
|
|
35
|
+
"scripts/",
|
|
36
|
+
"song/",
|
|
37
|
+
"settings.json",
|
|
38
|
+
"cli.js",
|
|
39
|
+
"README.md"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=16.0.0"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
# Claude Code Statusline - Project Memory
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
Clean, type-safe statusline implementation for Claude Code using Bun + TypeScript. Displays real-time session information, git status, context usage, and Claude API rate limits.
|
|
6
|
+
|
|
7
|
+
## Project Setup & Configuration
|
|
8
|
+
|
|
9
|
+
### Dependencies
|
|
10
|
+
- **Bun**: Runtime (uses `$` for shell commands)
|
|
11
|
+
- **@biomejs/biome**: Linting & formatting
|
|
12
|
+
- **TypeScript**: Type safety
|
|
13
|
+
|
|
14
|
+
No external npm packages required - pure Bun APIs.
|
|
15
|
+
|
|
16
|
+
### Configuration in Claude Code
|
|
17
|
+
|
|
18
|
+
Add to `~/.claude/settings.json`:
|
|
19
|
+
|
|
20
|
+
```json
|
|
21
|
+
{
|
|
22
|
+
"statusLine": {
|
|
23
|
+
"type": "command",
|
|
24
|
+
"command": "bun /Users/melvynx/.claude/scripts/statusline/src/index.ts",
|
|
25
|
+
"padding": 0
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
### Authentication
|
|
31
|
+
|
|
32
|
+
OAuth token stored in macOS Keychain:
|
|
33
|
+
- **Service**: `Claude Code-credentials`
|
|
34
|
+
- **Format**: JSON with `claudeAiOauth.accessToken`
|
|
35
|
+
- **Token type**: `sk-ant-oat01-...` (OAuth token, not API key)
|
|
36
|
+
- **Access**: `security find-generic-password -s "Claude Code-credentials" -w`
|
|
37
|
+
|
|
38
|
+
## Architecture
|
|
39
|
+
|
|
40
|
+
### Modular Design
|
|
41
|
+
|
|
42
|
+
The project follows a clean architecture with separated concerns:
|
|
43
|
+
|
|
44
|
+
```
|
|
45
|
+
src/
|
|
46
|
+
├── index.ts # Main entry - orchestrates all components
|
|
47
|
+
└── lib/
|
|
48
|
+
├── types.ts # TypeScript interfaces (HookInput)
|
|
49
|
+
├── git.ts # Git operations (branch, changes)
|
|
50
|
+
├── context.ts # Transcript parsing & context calculation
|
|
51
|
+
├── usage-limits.ts # Claude OAuth API integration
|
|
52
|
+
└── formatters.ts # Display utilities & colors
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### Data Flow
|
|
56
|
+
|
|
57
|
+
```
|
|
58
|
+
Claude Code Hook → stdin JSON → index.ts
|
|
59
|
+
↓
|
|
60
|
+
┌───────────────┴───────────────┐
|
|
61
|
+
↓ ↓
|
|
62
|
+
[Get Git Status] [Get Context Data]
|
|
63
|
+
↓ ↓
|
|
64
|
+
[Format Branch] [Get Usage Limits]
|
|
65
|
+
↓ ↓
|
|
66
|
+
└───────────────┬───────────────┘
|
|
67
|
+
↓
|
|
68
|
+
[Build Output Lines]
|
|
69
|
+
↓
|
|
70
|
+
stdout (2 lines)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Component Specifications
|
|
74
|
+
|
|
75
|
+
### Context Calculation (`lib/context.ts`)
|
|
76
|
+
- **Purpose**: Calculate token usage from Claude Code transcript files
|
|
77
|
+
- **Algorithm**: Parses `.jsonl` transcript, finds most recent main-chain entry
|
|
78
|
+
- **Tokens counted**: `input_tokens + cache_read_input_tokens + cache_creation_input_tokens`
|
|
79
|
+
- **Excludes**: Sidechain entries (agent calls), API error messages
|
|
80
|
+
- **Output**: `{ tokens: number, percentage: number }` (0-100% of 200k context)
|
|
81
|
+
|
|
82
|
+
### Usage Limits (`lib/usage-limits.ts`)
|
|
83
|
+
- **Purpose**: Fetch Claude API rate limits from OAuth endpoint
|
|
84
|
+
- **Auth**: Retrieves OAuth token from macOS Keychain (`Claude Code-credentials`)
|
|
85
|
+
- **API**: `https://api.anthropic.com/api/oauth/usage`
|
|
86
|
+
- **Data**: Five-hour window utilization + reset time
|
|
87
|
+
- **Error handling**: Fails silently, returns null on errors
|
|
88
|
+
|
|
89
|
+
### Git Status (`lib/git.ts`)
|
|
90
|
+
- **Purpose**: Show current branch and uncommitted changes
|
|
91
|
+
- **Detection**: Checks both staged and unstaged changes
|
|
92
|
+
- **Output**: Branch name + line additions/deletions
|
|
93
|
+
- **Display**: `main* (+123 -45)` with color coding
|
|
94
|
+
|
|
95
|
+
### Formatters (`lib/formatters.ts`)
|
|
96
|
+
- **Colors**: ANSI color codes for terminal output
|
|
97
|
+
- **Token display**: `62.5K`, `1.2M` format
|
|
98
|
+
- **Time formatting**: `3h21m`, `45m` for countdowns
|
|
99
|
+
- **Reset time**: Calculates difference between API reset time and now
|
|
100
|
+
|
|
101
|
+
## Output Specification
|
|
102
|
+
|
|
103
|
+
### Line 1: Session Info
|
|
104
|
+
```
|
|
105
|
+
main* (+123 -45) | ~/.claude | Sonnet 4.5
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### Line 2: Metrics
|
|
109
|
+
```
|
|
110
|
+
$0.17 (6m) | 62.5K tokens | 31% | 15% (3h27m)
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
**Components:**
|
|
114
|
+
- `$0.17` - Session cost (USD)
|
|
115
|
+
- `(6m)` - Session duration
|
|
116
|
+
- `62.5K tokens` - Context tokens used (from transcript)
|
|
117
|
+
- `31%` - Context percentage (tokens / 200k)
|
|
118
|
+
- `15%` - Five-hour usage (from Claude API)
|
|
119
|
+
- `(3h27m)` - Time until rate limit resets
|
|
120
|
+
|
|
121
|
+
## Development
|
|
122
|
+
|
|
123
|
+
### Testing
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
# Run test with fixture
|
|
127
|
+
bun run test
|
|
128
|
+
|
|
129
|
+
# Use custom fixture
|
|
130
|
+
bun run test fixtures/custom.json
|
|
131
|
+
|
|
132
|
+
# Manual test
|
|
133
|
+
echo '{ ... }' | bun run start
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Code Conventions
|
|
137
|
+
|
|
138
|
+
- **ALWAYS** use camelCase for variables and functions
|
|
139
|
+
- Use TypeScript strict mode
|
|
140
|
+
- Follow Biome formatting rules
|
|
141
|
+
|
|
142
|
+
### Error Handling & Performance
|
|
143
|
+
|
|
144
|
+
**Error Handling** - All components fail silently:
|
|
145
|
+
- Missing transcript → 0 tokens, 0%
|
|
146
|
+
- API failure → No usage limits shown
|
|
147
|
+
- Git errors → "no-git" branch
|
|
148
|
+
- Keychain access denied → No usage limits
|
|
149
|
+
|
|
150
|
+
This ensures statusline never crashes Claude Code.
|
|
151
|
+
|
|
152
|
+
**Performance Benchmarks:**
|
|
153
|
+
- Context calculation: ~10-50ms (depends on transcript size)
|
|
154
|
+
- API call: ~100-300ms (cached by Claude API)
|
|
155
|
+
- Git operations: ~20-50ms
|
|
156
|
+
- Total: < 500ms typical
|
|
157
|
+
|
|
158
|
+
## Maintenance Guide
|
|
159
|
+
|
|
160
|
+
### Adding New Metrics
|
|
161
|
+
|
|
162
|
+
1. Add interface to `lib/types.ts`
|
|
163
|
+
2. Create fetcher in `lib/*.ts`
|
|
164
|
+
3. Import in `index.ts`
|
|
165
|
+
4. Add to `buildSecondLine()`
|
|
166
|
+
|
|
167
|
+
### Modifying Display
|
|
168
|
+
|
|
169
|
+
- Colors: Edit `lib/formatters.ts` colors constant
|
|
170
|
+
- Layout: Modify `buildFirstLine()` / `buildSecondLine()`
|
|
171
|
+
- Formatting: Add functions to `lib/formatters.ts`
|
|
172
|
+
|
|
173
|
+
## Known Limitations
|
|
174
|
+
|
|
175
|
+
- macOS only (uses Keychain)
|
|
176
|
+
- Requires `git` CLI for git status
|
|
177
|
+
- Requires Claude Code OAuth (not API key)
|
|
178
|
+
- Transcript must be accessible (permissions)
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
# Claude Code Statusline
|
|
2
|
+
|
|
3
|
+
Clean, modular statusline for Claude Code with TypeScript + Bun.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🌿 Git branch with changes (+added -deleted)
|
|
8
|
+
- 💰 Session cost and duration
|
|
9
|
+
- 🧩 Context tokens used
|
|
10
|
+
- 📊 Context percentage (0-100%)
|
|
11
|
+
- ⏱️ Five-hour usage limit with reset time
|
|
12
|
+
|
|
13
|
+
## Structure
|
|
14
|
+
|
|
15
|
+
```
|
|
16
|
+
src/
|
|
17
|
+
├── index.ts # Main entry point
|
|
18
|
+
└── lib/
|
|
19
|
+
├── types.ts # TypeScript interfaces
|
|
20
|
+
├── git.ts # Git status
|
|
21
|
+
├── context.ts # Context calculation from transcript
|
|
22
|
+
├── usage-limits.ts # Claude API usage limits
|
|
23
|
+
└── formatters.ts # Formatting utilities
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Development
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
# Install dependencies
|
|
30
|
+
bun install
|
|
31
|
+
|
|
32
|
+
# Run the statusline (needs stdin JSON)
|
|
33
|
+
echo '{ ... }' | bun run start
|
|
34
|
+
|
|
35
|
+
# View today's spending
|
|
36
|
+
bun run spend:today
|
|
37
|
+
|
|
38
|
+
# View this month's spending
|
|
39
|
+
bun run spend:month
|
|
40
|
+
|
|
41
|
+
# Format code
|
|
42
|
+
bun run format
|
|
43
|
+
|
|
44
|
+
# Lint code
|
|
45
|
+
bun run lint
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Spend Tracking
|
|
49
|
+
|
|
50
|
+
The statusline automatically saves session data to `data/spend.json`. You can view your spending with:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
# Today's sessions and cost
|
|
54
|
+
bun run spend:today
|
|
55
|
+
|
|
56
|
+
# This month's sessions grouped by date
|
|
57
|
+
bun run spend:month
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Each session tracks:
|
|
61
|
+
- Cost (USD)
|
|
62
|
+
- Duration
|
|
63
|
+
- Lines added/removed
|
|
64
|
+
- Working directory
|
|
65
|
+
|
|
66
|
+
## Usage in Claude Code
|
|
67
|
+
|
|
68
|
+
Update your `~/.claude/settings.json`:
|
|
69
|
+
|
|
70
|
+
```json
|
|
71
|
+
{
|
|
72
|
+
"statusLine": {
|
|
73
|
+
"type": "command",
|
|
74
|
+
"command": "bun /Users/melvynx/.claude/scripts/statusline/src/index.ts",
|
|
75
|
+
"padding": 0
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
echo '{
|
|
84
|
+
"session_id": "test",
|
|
85
|
+
"transcript_path": "/path/to/transcript.jsonl",
|
|
86
|
+
"cwd": "/path",
|
|
87
|
+
"model": {
|
|
88
|
+
"id": "claude-sonnet-4-5",
|
|
89
|
+
"display_name": "Sonnet 4.5"
|
|
90
|
+
},
|
|
91
|
+
"workspace": {
|
|
92
|
+
"current_dir": "/path",
|
|
93
|
+
"project_dir": "/path"
|
|
94
|
+
},
|
|
95
|
+
"version": "2.0.31",
|
|
96
|
+
"output_style": { "name": "default" },
|
|
97
|
+
"cost": {
|
|
98
|
+
"total_cost_usd": 0.15,
|
|
99
|
+
"total_duration_ms": 300000,
|
|
100
|
+
"total_api_duration_ms": 200000,
|
|
101
|
+
"total_lines_added": 100,
|
|
102
|
+
"total_lines_removed": 50
|
|
103
|
+
}
|
|
104
|
+
}' | bun run start
|
|
105
|
+
```
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false
|
|
10
|
+
},
|
|
11
|
+
"formatter": {
|
|
12
|
+
"enabled": true,
|
|
13
|
+
"indentStyle": "tab"
|
|
14
|
+
},
|
|
15
|
+
"linter": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"rules": {
|
|
18
|
+
"recommended": true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"javascript": {
|
|
22
|
+
"formatter": {
|
|
23
|
+
"quoteStyle": "double"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"assist": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"actions": {
|
|
29
|
+
"source": {
|
|
30
|
+
"organizeImports": "on"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"session_id": "06a7b019-03f8-4083-a9db-410d95cb01e6",
|
|
3
|
+
"transcript_path": "/Users/melvynx/.claude/projects/-Users-melvynx--claude/06a7b019-03f8-4083-a9db-410d95cb01e6.jsonl",
|
|
4
|
+
"cwd": "/Users/melvynx/.claude",
|
|
5
|
+
"model": {
|
|
6
|
+
"id": "claude-sonnet-4-5-20250929",
|
|
7
|
+
"display_name": "Sonnet 4.5"
|
|
8
|
+
},
|
|
9
|
+
"workspace": {
|
|
10
|
+
"current_dir": "/Users/melvynx/.claude",
|
|
11
|
+
"project_dir": "/Users/melvynx/.claude"
|
|
12
|
+
},
|
|
13
|
+
"version": "2.0.31",
|
|
14
|
+
"output_style": {
|
|
15
|
+
"name": "default"
|
|
16
|
+
},
|
|
17
|
+
"cost": {
|
|
18
|
+
"total_cost_usd": 0.17468000000000003,
|
|
19
|
+
"total_duration_ms": 385160,
|
|
20
|
+
"total_api_duration_ms": 252694,
|
|
21
|
+
"total_lines_added": 185,
|
|
22
|
+
"total_lines_removed": 75
|
|
23
|
+
},
|
|
24
|
+
"exceeds_200k_tokens": false
|
|
25
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "statusline",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"module": "src/index.ts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "bun run src/index.ts",
|
|
8
|
+
"test": "bun run test.ts",
|
|
9
|
+
"spend:today": "bun run src/commands/spend-today.ts",
|
|
10
|
+
"spend:month": "bun run src/commands/spend-month.ts",
|
|
11
|
+
"lint": "biome check --write .",
|
|
12
|
+
"format": "biome format --write ."
|
|
13
|
+
},
|
|
14
|
+
"devDependencies": {
|
|
15
|
+
"@biomejs/biome": "^2.3.2",
|
|
16
|
+
"@types/bun": "latest"
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5.0.0"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { formatCost, formatDuration } from "../lib/formatters";
|
|
4
|
+
import {
|
|
5
|
+
calculateTotalCost,
|
|
6
|
+
calculateTotalDuration,
|
|
7
|
+
filterSessionsByDate,
|
|
8
|
+
getMonthStart,
|
|
9
|
+
loadSpendData,
|
|
10
|
+
} from "../lib/spend";
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
const data = await loadSpendData();
|
|
14
|
+
const monthStart = getMonthStart();
|
|
15
|
+
const monthSessions = filterSessionsByDate(data.sessions, monthStart);
|
|
16
|
+
|
|
17
|
+
if (monthSessions.length === 0) {
|
|
18
|
+
console.log("📊 No sessions this month");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const totalCost = calculateTotalCost(monthSessions);
|
|
23
|
+
const totalDuration = calculateTotalDuration(monthSessions);
|
|
24
|
+
|
|
25
|
+
// Group by date
|
|
26
|
+
const sessionsByDate = monthSessions.reduce(
|
|
27
|
+
(acc, session) => {
|
|
28
|
+
if (!acc[session.date]) {
|
|
29
|
+
acc[session.date] = [];
|
|
30
|
+
}
|
|
31
|
+
acc[session.date].push(session);
|
|
32
|
+
return acc;
|
|
33
|
+
},
|
|
34
|
+
{} as Record<string, typeof monthSessions>,
|
|
35
|
+
);
|
|
36
|
+
|
|
37
|
+
const monthName = monthStart.toLocaleString("default", { month: "long" });
|
|
38
|
+
|
|
39
|
+
console.log(`\n📊 ${monthName}'s Spend\n`);
|
|
40
|
+
console.log(`Sessions: ${monthSessions.length}`);
|
|
41
|
+
console.log(`Total Cost: $${formatCost(totalCost)}`);
|
|
42
|
+
console.log(`Total Duration: ${formatDuration(totalDuration)}`);
|
|
43
|
+
console.log(`\n📅 By Date:\n`);
|
|
44
|
+
|
|
45
|
+
const sortedDates = Object.keys(sessionsByDate).sort();
|
|
46
|
+
|
|
47
|
+
for (const date of sortedDates) {
|
|
48
|
+
const sessions = sessionsByDate[date];
|
|
49
|
+
const dayCost = calculateTotalCost(sessions);
|
|
50
|
+
const dayDuration = calculateTotalDuration(sessions);
|
|
51
|
+
|
|
52
|
+
console.log(
|
|
53
|
+
` ${date}: $${formatCost(dayCost)} (${formatDuration(dayDuration)}) - ${sessions.length} session(s)`,
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
console.log("");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
main();
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { formatCost, formatDuration } from "../lib/formatters";
|
|
4
|
+
import {
|
|
5
|
+
calculateTotalCost,
|
|
6
|
+
calculateTotalDuration,
|
|
7
|
+
filterSessionsByDate,
|
|
8
|
+
getTodayStart,
|
|
9
|
+
loadSpendData,
|
|
10
|
+
} from "../lib/spend";
|
|
11
|
+
|
|
12
|
+
async function main() {
|
|
13
|
+
const data = await loadSpendData();
|
|
14
|
+
const today = getTodayStart();
|
|
15
|
+
const todaySessions = filterSessionsByDate(data.sessions, today);
|
|
16
|
+
|
|
17
|
+
if (todaySessions.length === 0) {
|
|
18
|
+
console.log("📊 No sessions today");
|
|
19
|
+
return;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const totalCost = calculateTotalCost(todaySessions);
|
|
23
|
+
const totalDuration = calculateTotalDuration(todaySessions);
|
|
24
|
+
|
|
25
|
+
console.log(`\n📊 Today's Spend\n`);
|
|
26
|
+
console.log(`Sessions: ${todaySessions.length}`);
|
|
27
|
+
console.log(`Total Cost: $${formatCost(totalCost)}`);
|
|
28
|
+
console.log(`Total Duration: ${formatDuration(totalDuration)}`);
|
|
29
|
+
console.log(`\n📝 Sessions:\n`);
|
|
30
|
+
|
|
31
|
+
for (const session of todaySessions) {
|
|
32
|
+
console.log(
|
|
33
|
+
` • $${formatCost(session.cost)} (${formatDuration(session.duration_ms)})`,
|
|
34
|
+
);
|
|
35
|
+
console.log(` ${session.cwd}`);
|
|
36
|
+
console.log(
|
|
37
|
+
` +${session.lines_added} -${session.lines_removed} lines\n`,
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
main();
|