@da-trollefsen/claude-wrapped 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/.env.example ADDED
@@ -0,0 +1,42 @@
1
+ # Claude Code Wrapped - Environment Configuration
2
+ #
3
+ # Copy this file to .env and customize for your setup
4
+
5
+ # ============================================================================
6
+ # BACKUP DIRECTORIES
7
+ # ============================================================================
8
+ #
9
+ # FORMAT: Comma-separated list on a SINGLE LINE (no line breaks!)
10
+ #
11
+ # EXAMPLE (copy and edit one of these):
12
+ #
13
+ # CLAUDE_BACKUP_DIRS=/path/to/first,/path/to/second,/path/to/third
14
+ # CLAUDE_BACKUP_DIRS=~/Dropbox/claude-backups/.claude,~/.claude/backups/projects
15
+ # CLAUDE_BACKUP_DIRS=/Users/you/exported-chats
16
+ #
17
+ # ============================================================================
18
+
19
+ # Uncomment and edit the line below:
20
+ # CLAUDE_BACKUP_DIRS=
21
+
22
+ # ============================================================================
23
+ # DIRECTORY STRUCTURES SUPPORTED (auto-detected)
24
+ # ============================================================================
25
+ #
26
+ # 1. Standard ~/.claude structure (has projects/ subdirectory)
27
+ # 2. Projects folder itself (subdirectories with *.jsonl files)
28
+ # 3. Flat structure (*.jsonl files directly in directory)
29
+ #
30
+ # ============================================================================
31
+ # IMPORTANT: ORDER MATTERS!
32
+ # ============================================================================
33
+ #
34
+ # Later directories override earlier ones for duplicate messages.
35
+ # Put your most complete/authoritative backup LAST.
36
+ #
37
+ # Example: Pre-compaction backups should come AFTER other sources:
38
+ # CLAUDE_BACKUP_DIRS=~/old-exports,~/.claude/backups/projects
39
+ # ^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^
40
+ # scanned first scanned LAST (wins duplicates)
41
+ #
42
+ # ============================================================================
@@ -0,0 +1 @@
1
+ 3.13
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Mert Deveci
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,397 @@
1
+ # Claude Code Wrapped
2
+
3
+ ```
4
+ ░█████╗░██╗░░░░░░█████╗░██╗░░░██╗██████╗░███████╗
5
+ ██╔══██╗██║░░░░░██╔══██╗██║░░░██║██╔══██╗██╔════╝
6
+ ██║░░╚═╝██║░░░░░███████║██║░░░██║██║░░██║█████╗░░
7
+ ██║░░██╗██║░░░░░██╔══██║██║░░░██║██║░░██║██╔══╝░░
8
+ ╚█████╔╝███████╗██║░░██║╚██████╔╝██████╔╝███████╗
9
+ ░╚════╝░╚══════╝╚═╝░░╚═╝░╚═════╝░╚═════╝░╚══════╝
10
+
11
+ C O D E W R A P P E D
12
+ by Banker.so
13
+ ```
14
+
15
+ **Your year with Claude Code, Spotify Wrapped style.** ✨
16
+
17
+ A beautiful terminal experience that analyzes your local Claude Code conversation history and presents your coding year in a cinematic, Spotify Wrapped-inspired format.
18
+
19
+ ---
20
+
21
+ ## 🚀 Quick Start
22
+
23
+ **No installation needed** - Just run one of these commands:
24
+
25
+ ```bash
26
+ # Using uvx (recommended - Python, no install)
27
+ uvx claude-wrapped
28
+
29
+ # Using npx (Node.js, no install)
30
+ npx @da-trollefsen/claude-wrapped
31
+
32
+ # Or install once and run anytime
33
+ pip install claude-wrapped
34
+ claude-wrapped
35
+ ```
36
+
37
+ The tool launches in **interactive mode** with arrow-key prompts to guide you through all options. Press `Enter` to advance through your personalized stats!
38
+
39
+ > **☕ Pro tip:** Using Claude Code? Just paste this repo URL (`https://github.com/da-troll/claude-wrapped`) into your conversation and ask Claude to install and run it for you. Sit back, sip your coffee, and let Claude handle the setup while you wait for your stats. Meta, right? 😎
40
+
41
+ ---
42
+
43
+ ## ✨ Features
44
+
45
+ ### 📊 Comprehensive Stats
46
+ - **Total messages** exchanged with Claude
47
+ - **Coding sessions** and project counts
48
+ - **Tokens processed** (input, output, cache)
49
+ - **Cost estimates** based on official Anthropic pricing
50
+ - **Longest coding streak** with start and end dates
51
+ - **Current streak** to keep you motivated
52
+
53
+ ### 🎬 Cinematic Experience
54
+ - **Dramatic reveals** - Stats appear one at a time, Spotify Wrapped style
55
+ - **GitHub-style contribution graph** - Visualize your coding patterns
56
+ - **Movie-style credits** - Featuring your top tools, projects, and models
57
+ - **Fun facts & insights** - Like "You coded after midnight 47 times"
58
+
59
+ ### 🎭 Personality Types
60
+ Based on your coding habits, discover your type:
61
+ - 🦉 **Night Owl** - The quiet hours are your sanctuary
62
+ - 🔥 **Streak Master** - Consistency is your superpower
63
+ - ⚡ **Terminal Warrior** - Command line is your domain
64
+ - 🎨 **The Refactorer** - You see beauty in clean code
65
+ - 🚀 **Empire Builder** - Building across multiple projects
66
+ - 🌙 **Weekend Warrior** - Passion fuels your weekends
67
+ - 🎯 **Perfectionist** - Only the best will do
68
+ - 💻 **Dedicated Dev** - Steady and reliable
69
+
70
+ ### 📤 Export Options
71
+ - **HTML export** - Beautiful web page with interactive graphs
72
+ - **Markdown export** - Clean, readable format for sharing
73
+ - **JSON export** - Raw data for your own analysis
74
+ - **Timestamped filenames** - Never overwrite previous exports
75
+
76
+ ---
77
+
78
+ ## 🎯 Usage
79
+
80
+ ### Two Ways to Use
81
+
82
+ **🎨 Interactive Mode (Recommended for beginners)**
83
+
84
+ Simply run the command without any arguments:
85
+
86
+ ```bash
87
+ claude-wrapped
88
+ ```
89
+
90
+ You'll be guided through beautiful prompts to select:
91
+ - ⏳ **Time period** - Current year, specific year, or all-time
92
+ - 📤 **Export format** - Terminal only, HTML, Markdown, or JSON
93
+ - 🎬 **Animations** - Show dramatic reveals or skip to dashboard
94
+ - 📝 **Custom filename** - Optional custom name for exports
95
+
96
+ No need to remember complex command-line arguments!
97
+
98
+ **⚡ CLI Mode (For power users & scripts)**
99
+
100
+ Pass arguments directly for quick access:
101
+
102
+ ```bash
103
+ # Full cinematic experience (current year)
104
+ claude-wrapped 2025
105
+
106
+ # Skip animations, go straight to dashboard
107
+ claude-wrapped --no-animate
108
+
109
+ # All-time statistics
110
+ claude-wrapped all
111
+
112
+ # Export to HTML
113
+ claude-wrapped --html
114
+
115
+ # Export to Markdown
116
+ claude-wrapped --markdown
117
+
118
+ # All-time stats with exports
119
+ claude-wrapped all --html --markdown
120
+
121
+ # Export raw data as JSON
122
+ claude-wrapped --json
123
+ ```
124
+
125
+ ### Custom Output Filename
126
+
127
+ ```bash
128
+ # Custom filename (without extension)
129
+ claude-wrapped --html --output my-wrapped-2025
130
+ # Creates: my-wrapped-2025.html
131
+
132
+ # Default timestamped filenames
133
+ claude-wrapped --html
134
+ # Creates: claude-wrapped-2025-20260102-1430.html
135
+ ```
136
+
137
+ ---
138
+
139
+ ## 💾 Including Backup Directories
140
+
141
+ Have Claude Code backups in Dropbox, external drives, or exported conversations? Include them all:
142
+
143
+ ### Setup
144
+
145
+ ```bash
146
+ # 1. Create a .env file
147
+ cp .env.example .env
148
+
149
+ # 2. Edit .env and add your backup locations (comma-separated)
150
+ CLAUDE_BACKUP_DIRS=~/Dropbox/claude-backups/.claude,~/exported-chats,/Volumes/backup/.claude
151
+
152
+ # 3. Run as normal - automatically combines all data
153
+ claude-code-wrapped
154
+ ```
155
+
156
+ ### Supported Directory Structures
157
+
158
+ The tool auto-detects three different directory layouts:
159
+
160
+ #### 1. Standard `~/.claude` Structure
161
+ ```
162
+ backup-dir/
163
+ ├── projects/
164
+ │ └── -Users-you-code-project/
165
+ │ └── session-uuid.jsonl
166
+ └── history.jsonl (optional)
167
+ ```
168
+
169
+ #### 2. Projects Folder
170
+ ```
171
+ projects-dir/
172
+ ├── -Users-you-code-project1/
173
+ │ └── session.jsonl
174
+ └── -Users-you-code-project2/
175
+ └── session.jsonl
176
+ ```
177
+
178
+ #### 3. Flat Structure
179
+ ```
180
+ backup-dir/
181
+ ├── session1.jsonl
182
+ ├── session2.jsonl
183
+ └── session3.jsonl
184
+ ```
185
+
186
+ ### Deduplication
187
+
188
+ - Messages are automatically deduplicated by `message_id`
189
+ - **Order matters**: Later directories override earlier ones for duplicates
190
+ - List most authoritative/complete sources **last**
191
+
192
+ **Example:**
193
+ ```bash
194
+ # CORRECT: Pre-compaction backups listed last (highest priority)
195
+ CLAUDE_BACKUP_DIRS=~/.claude/backups/old,~/external-drive/pre-compaction
196
+
197
+ # WRONG: Pre-compaction backups will be overridden
198
+ CLAUDE_BACKUP_DIRS=~/external-drive/pre-compaction,~/.claude/backups/old
199
+ ```
200
+
201
+ ---
202
+
203
+ ## 📋 Requirements
204
+
205
+ - **Python 3.12+** (with uvx, pipx, or pip)
206
+ - **Or Node.js 16+** (for npx)
207
+ - **Claude Code installed** (`~/.claude/` directory exists)
208
+
209
+ ---
210
+
211
+ ## 🔒 Privacy
212
+
213
+ This tool is **100% local and private**:
214
+
215
+ - ✅ **No network requests** - All data read from local `~/.claude/` directory
216
+ - ✅ **No data collection** - Nothing sent to any server
217
+ - ✅ **No API keys needed** - Works entirely offline
218
+ - ✅ **No secrets exposed** - Only aggregated stats shown, not conversation content
219
+ - ✅ **Open source** - Inspect the code yourself
220
+
221
+ Your conversations never leave your machine.
222
+
223
+ ---
224
+
225
+ ## 🎨 What You'll See
226
+
227
+ ### Dashboard View
228
+ ```
229
+ ════════════════════════════════════════════════════════
230
+ CLAUDE CODE WRAPPED 2025
231
+ ════════════════════════════════════════════════════════
232
+
233
+ 71,108 263 2.9B 40d
234
+ messages sessions tokens best streak
235
+
236
+ ╭─────────────── Activity · 90 of 365 days ────────────╮
237
+ │ Mon ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ │
238
+ │ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ │
239
+ │ Wed ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ ■ │
240
+ │ │
241
+ │ Less ■ ■ ■ ■ ■ More │
242
+ ╰──────────────────────────────────────────────────────╯
243
+ ```
244
+
245
+ ### Credits Sequence
246
+ - 💵 **THE NUMBERS** - Cost breakdown by model, total tokens
247
+ - 📅 **TIMELINE** - Journey start, active days, peak coding hour
248
+ - 📊 **AVERAGES** - Messages and cost per day/week/month
249
+ - 🔥 **LONGEST STREAK** - Your best consecutive coding days with dates
250
+ - 💬 **LONGEST CONVERSATION** - Your epic coding session stats
251
+ - ⭐ **STARRING** - Your favorite Claude models
252
+ - 📁 **PROJECTS** - Top projects by message count
253
+
254
+ ---
255
+
256
+ ## 🛠️ How It Works
257
+
258
+ Reads your local Claude Code conversation history from `~/.claude/projects/` and aggregates:
259
+
260
+ - **Message counts** and timestamps
261
+ - **Token usage** (input, output, cache reads/writes)
262
+ - **Tool usage** (Bash, Read, Edit, Grep, etc.)
263
+ - **MCP server usage** (extracted from tool names)
264
+ - **Model preferences** (Opus, Sonnet, Haiku)
265
+ - **Project activity** (intelligently aggregates common subdirectories)
266
+ - **Coding patterns** (hourly distribution, weekday patterns, streaks)
267
+ - **Cost estimates** (based on official Anthropic API pricing)
268
+
269
+ ### Intelligent Project Aggregation
270
+
271
+ The tool recognizes common subdirectories and aggregates them properly:
272
+
273
+ ```python
274
+ # Both of these become "my-project":
275
+ /Users/you/code/my-project/app
276
+ /Users/you/code/my-project/src
277
+
278
+ # Common subdirectories recognized:
279
+ app, src, lib, frontend, backend, api, server, client,
280
+ test, tests, public, static, dist, build, etc.
281
+ ```
282
+
283
+ ---
284
+
285
+ ## 📦 Installation Methods
286
+
287
+ ### 🚀 No Install Required (Recommended)
288
+
289
+ **uvx** (Python ecosystem - most reliable):
290
+ ```bash
291
+ uvx claude-wrapped
292
+ ```
293
+ - ✅ No installation needed
294
+ - ✅ Always runs latest version
295
+ - ✅ Isolated environment
296
+ - ✅ Requires Python 3.12+ or `uv` installed
297
+
298
+ **npx** (Node.js ecosystem):
299
+ ```bash
300
+ npx claude-wrapped
301
+ ```
302
+ - ✅ No installation needed
303
+ - ✅ Works if you have Node.js 16+
304
+ - ⚠️ Wrapper script that calls Python version
305
+
306
+ ### 📥 Install Globally
307
+
308
+ **pip** (system-wide Python install):
309
+ ```bash
310
+ pip install claude-wrapped
311
+ claude-wrapped
312
+ ```
313
+ - Installs `claude-wrapped` command globally
314
+ - Requires Python 3.12+
315
+
316
+ **pipx** (isolated Python install):
317
+ ```bash
318
+ pipx install claude-wrapped
319
+ claude-wrapped
320
+ ```
321
+ - ✅ Best of both worlds: installed command + isolated environment
322
+ - ✅ Doesn't pollute global Python packages
323
+ - Requires `pipx` ([installation guide](https://pipx.pypa.io/stable/installation/))
324
+
325
+ **Homebrew** (macOS/Linux package manager):
326
+ ```bash
327
+ brew tap da-troll/claude-wrapped
328
+ brew install claude-wrapped
329
+ ```
330
+ - ✅ Native macOS/Linux package manager
331
+ - ✅ Easy updates with `brew upgrade`
332
+ - Tap repository: [homebrew-claude-wrapped](https://github.com/da-troll/homebrew-claude-wrapped)
333
+
334
+ ### 🔧 Development Mode
335
+
336
+ **From source** (for contributors):
337
+ ```bash
338
+ git clone https://github.com/da-troll/claude-wrapped.git
339
+ cd claude-wrapped
340
+ uv sync
341
+ uv run python -m claude_code_wrapped
342
+ ```
343
+
344
+ **Editable install** (makes `claude-wrapped` command available locally):
345
+ ```bash
346
+ uv pip install -e .
347
+ claude-wrapped
348
+ ```
349
+
350
+ ---
351
+
352
+ ## 🤝 Contributing
353
+
354
+ Contributions are welcome! This project is open source and community-driven.
355
+
356
+ ### Development Setup
357
+
358
+ ```bash
359
+ # Clone the repository
360
+ git clone https://github.com/da-troll/claude-wrapped.git
361
+ cd claude-wrapped
362
+
363
+ # Install dependencies with uv
364
+ uv sync
365
+
366
+ # Run from source
367
+ uv run python -m claude_code_wrapped
368
+
369
+ # Run tests
370
+ uv run python -m claude_code_wrapped.reader
371
+ uv run python -m claude_code_wrapped.stats
372
+ ```
373
+
374
+ ---
375
+
376
+ ## 📄 License
377
+
378
+ MIT - see [LICENSE](LICENSE) for details.
379
+
380
+ ---
381
+
382
+ ## ⭐ Show Your Support
383
+
384
+ If you found this useful, consider:
385
+ - Giving it a star on GitHub ⭐
386
+ - Sharing your wrapped on social media
387
+ - Contributing improvements
388
+
389
+ ---
390
+
391
+ **Built with ❤️ for the Claude Code community**
392
+
393
+ ---
394
+
395
+ ## 💡 Inspired By
396
+
397
+ Originally inspired by [Mert Deveci](https://x.com/gm_mertd)'s concept. This project has since evolved into a completely independent codebase with a different architecture and feature set.
package/bin/cli.js ADDED
@@ -0,0 +1,62 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn, spawnSync } = require('child_process');
4
+
5
+ // Pass through all arguments
6
+ const args = process.argv.slice(2);
7
+
8
+ // Check if a command exists
9
+ function commandExists(cmd) {
10
+ const result = spawnSync(cmd, ['--version'], { stdio: 'ignore' });
11
+ return result.status === 0;
12
+ }
13
+
14
+ // Check if Python module is installed
15
+ function pythonModuleExists() {
16
+ const result = spawnSync('python3', ['-c', 'import claude_code_wrapped'], { stdio: 'ignore' });
17
+ return result.status === 0;
18
+ }
19
+
20
+ // Try to find the best way to run the Python package
21
+ function findExecutor() {
22
+ // Try uvx first (recommended)
23
+ if (commandExists('uvx')) {
24
+ return { cmd: 'uvx', args: ['claude-wrapped', ...args] };
25
+ }
26
+
27
+ // Try pipx
28
+ if (commandExists('pipx')) {
29
+ return { cmd: 'pipx', args: ['run', 'claude-wrapped', ...args] };
30
+ }
31
+
32
+ // Try direct python module
33
+ if (pythonModuleExists()) {
34
+ return { cmd: 'python3', args: ['-m', 'claude_code_wrapped', ...args] };
35
+ }
36
+
37
+ // No executor found
38
+ console.error('claude-wrapped requires Python 3.12+ and one of: uvx, pipx, or pip');
39
+ console.error('');
40
+ console.error('Recommended: Install uv (https://docs.astral.sh/uv/) then run:');
41
+ console.error(' uvx claude-wrapped');
42
+ console.error('');
43
+ console.error('Or install with pip:');
44
+ console.error(' pip install claude-wrapped');
45
+ console.error(' claude-wrapped');
46
+ process.exit(1);
47
+ }
48
+
49
+ const executor = findExecutor();
50
+ const child = spawn(executor.cmd, executor.args, {
51
+ stdio: 'inherit',
52
+ env: process.env
53
+ });
54
+
55
+ child.on('close', (code) => {
56
+ process.exit(code || 0);
57
+ });
58
+
59
+ child.on('error', (err) => {
60
+ console.error('Failed to start:', err.message);
61
+ process.exit(1);
62
+ });
@@ -0,0 +1,3 @@
1
+ """Claude Code Wrapped - Your year with Claude Code, Spotify Wrapped style."""
2
+
3
+ __version__ = "0.1.11"
@@ -0,0 +1,6 @@
1
+ """Allow running as python -m claude_code_wrapped."""
2
+
3
+ from .main import main
4
+
5
+ if __name__ == "__main__":
6
+ main()
@@ -0,0 +1,6 @@
1
+ """Exporters for Claude Code Wrapped - HTML and Markdown generation."""
2
+
3
+ from .html_exporter import export_to_html
4
+ from .markdown_exporter import export_to_markdown
5
+
6
+ __all__ = ["export_to_html", "export_to_markdown"]