codex-wrapped-noyrlimit 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 ADDED
@@ -0,0 +1,141 @@
1
+ <div align="center">
2
+
3
+ # codex-wrapped-noyrlimit
4
+
5
+ **Your year in code, beautifully visualized.**
6
+
7
+ <p>
8
+ <strong>Credit:</strong> Built on top of
9
+ <a href="https://github.com/moddi3/opencode-wrapped">opencode-wrapped</a>
10
+ by moddi3 (<a href="https://x.com/moddi3io">@moddi3io</a>).
11
+ </p>
12
+ <p>
13
+ Found this useful? Follow <a href="https://x.com/nummanali">@nummanali</a> for more AI tooling!
14
+ </p>
15
+
16
+ Generate a personalized "Spotify Wrapped"-style summary of your [Codex](https://openai.com/codex) usage.
17
+
18
+ [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)
19
+ [![Bun](https://img.shields.io/badge/Bun-%23000000.svg?logo=bun&logoColor=white)](https://bun.sh)
20
+
21
+ <img src="./assets/images/demo-wrapped.png" alt="Codex Wrapped Example" width="600" />
22
+
23
+ </div>
24
+
25
+ ---
26
+
27
+ ## Installation
28
+
29
+ ### Quick Start
30
+
31
+ Run directly without installing:
32
+
33
+ ```bash
34
+ npx codex-wrapped-noyrlimit # or bunx, or yarn/pnpm dlx
35
+ ```
36
+
37
+ ### Global Install
38
+
39
+ ```bash
40
+ npm install -g codex-wrapped-noyrlimit # or bun/yarn/pnpm
41
+ ```
42
+
43
+ Then run anywhere:
44
+
45
+ ```bash
46
+ codex-wrapped-noyrlimit
47
+ ```
48
+
49
+ ## Usage Options
50
+
51
+ | Option | Description |
52
+ | --------------- | ------------------------------------ |
53
+ | `--year, -y` | Generate wrapped for a specific year |
54
+ | `--help, -h` | Show help message |
55
+ | `--version, -v` | Show version number |
56
+
57
+ ## Features
58
+
59
+ - Sessions, messages, tokens, projects, and streaks
60
+ - GitHub-style activity heatmap
61
+ - Top models and providers breakdown
62
+ - Usage cost (when available)
63
+ - Shareable PNG image
64
+ - Inline image display (Ghostty, Kitty, iTerm2, WezTerm, Konsole)
65
+ - Auto-copy to clipboard
66
+
67
+ ## Terminal Support
68
+
69
+ The wrapped image displays natively in terminals that support inline images:
70
+
71
+ | Terminal | Protocol | Status |
72
+ | ------------------------------------------ | -------------- | --------------------------- |
73
+ | [Ghostty](https://ghostty.org) | Kitty Graphics | Full support |
74
+ | [Kitty](https://sw.kovidgoyal.net/kitty/) | Kitty Graphics | Full support |
75
+ | [WezTerm](https://wezfurlong.org/wezterm/) | Kitty + iTerm2 | Full support |
76
+ | [iTerm2](https://iterm2.com) | iTerm2 Inline | Full support |
77
+ | [Konsole](https://konsole.kde.org) | Kitty Graphics | Full support |
78
+ | Other terminals | — | Image saved to file only |
79
+
80
+ ## Output
81
+
82
+ The tool generates:
83
+
84
+ 1. **Terminal Summary** — Quick stats overview in your terminal
85
+ 2. **PNG Image** — A beautiful, shareable wrapped card saved to your home directory
86
+ 3. **Clipboard** — Automatically copies the image to your clipboard
87
+
88
+ ## Data Source
89
+
90
+ Codex Wrapped reads data from your local Codex CLI installation:
91
+
92
+ ```
93
+ ~/.codex/ (history.jsonl, sessions, logs)
94
+ ```
95
+
96
+ No data is sent anywhere. Everything is processed locally.
97
+
98
+ ## Building
99
+
100
+ ### Development
101
+
102
+ ```bash
103
+ # Run in development mode with hot reload
104
+ bun run dev
105
+ ```
106
+
107
+ ### Production Build
108
+
109
+ ```bash
110
+ # Build for all platforms
111
+ bun run build
112
+ ```
113
+
114
+ ### Releasing
115
+
116
+ Releases are automated via [semantic-release](https://semantic-release.gitbook.io). Merging PRs with [conventional commits](https://www.conventionalcommits.org) to `main` triggers a release.
117
+
118
+ ## Tech Stack
119
+
120
+ - **Runtime**: [Bun](https://bun.sh)
121
+ - **Image Generation**: [Satori](https://github.com/vercel/satori) + [Resvg](https://github.com/nicolo-ribaudo/resvg-js)
122
+ - **CLI UI**: [@clack/prompts](https://github.com/natemoo-re/clack)
123
+ - **Font**: IBM Plex Mono
124
+
125
+ ## Contributing
126
+
127
+ Contributions are welcome! Please feel free to submit a Pull Request.
128
+
129
+ ## License
130
+
131
+ MIT License - see [LICENSE](LICENSE) for details.
132
+
133
+ ---
134
+
135
+ <div align="center">
136
+
137
+ Built for the Codex community
138
+
139
+ Credit: <a href="https://github.com/ryoppippi/ccusage">ccusage</a>
140
+
141
+ </div>
@@ -0,0 +1 @@
1
+ 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EREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREREUll+n+9jCCOzonctAAAAABJRU5ErkJggg==
Binary file
Binary file
@@ -0,0 +1,79 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { spawnSync } from "node:child_process";
4
+ import fs from "node:fs";
5
+ import { dirname, join } from "node:path";
6
+ import { platform as osPlatform, arch as osArch } from "node:os";
7
+ import { fileURLToPath } from "node:url";
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+
12
+ function run(target) {
13
+ const result = spawnSync(target, process.argv.slice(2), {
14
+ stdio: "inherit",
15
+ });
16
+ if (result.error) {
17
+ console.error(result.error.message);
18
+ process.exit(1);
19
+ }
20
+ const code = typeof result.status === "number" ? result.status : 0;
21
+ process.exit(code);
22
+ }
23
+
24
+ const platformMap = {
25
+ darwin: "darwin",
26
+ linux: "linux",
27
+ win32: "windows",
28
+ };
29
+ const archMap = {
30
+ x64: "x64",
31
+ arm64: "arm64",
32
+ };
33
+
34
+ let platform = platformMap[osPlatform()];
35
+ if (!platform) {
36
+ platform = osPlatform();
37
+ }
38
+ let arch = archMap[osArch()];
39
+ if (!arch) {
40
+ arch = osArch();
41
+ }
42
+ const base = "codex-wrapped-noyrlimit-" + platform + "-" + arch;
43
+ const binary = platform === "windows" ? "codex-wrapped-noyrlimit.exe" : "codex-wrapped-noyrlimit";
44
+
45
+ function findBinary(startDir) {
46
+ let current = startDir;
47
+ for (;;) {
48
+ const modules = join(current, "node_modules");
49
+ if (fs.existsSync(modules)) {
50
+ const entries = fs.readdirSync(modules);
51
+ for (const entry of entries) {
52
+ if (!entry.startsWith(base)) {
53
+ continue;
54
+ }
55
+ const candidate = join(modules, entry, "bin", binary);
56
+ if (fs.existsSync(candidate)) {
57
+ return candidate;
58
+ }
59
+ }
60
+ }
61
+ const parent = dirname(current);
62
+ if (parent === current) {
63
+ return;
64
+ }
65
+ current = parent;
66
+ }
67
+ }
68
+
69
+ const resolved = findBinary(__dirname);
70
+ if (!resolved) {
71
+ console.error(
72
+ 'It seems that your package manager failed to install the right version of codex-wrapped-noyrlimit CLI for your platform. You can try manually installing "' +
73
+ base +
74
+ '" package'
75
+ );
76
+ process.exit(1);
77
+ }
78
+
79
+ run(resolved);
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "codex-wrapped-noyrlimit",
3
+ "version": "1.0.0",
4
+ "description": "Generate a personalized Spotify Wrapped-style summary of your Codex usage",
5
+ "bin": {
6
+ "codex-wrapped-noyrlimit": "bin/codex-wrapped-noyrlimit"
7
+ },
8
+ "scripts": {
9
+ "postinstall": "node ./postinstall.mjs"
10
+ },
11
+ "optionalDependencies": {
12
+ "codex-wrapped-noyrlimit-linux-arm64": "1.0.0",
13
+ "codex-wrapped-noyrlimit-linux-x64": "1.0.0",
14
+ "codex-wrapped-noyrlimit-linux-x64-baseline": "1.0.0",
15
+ "codex-wrapped-noyrlimit-linux-arm64-musl": "1.0.0",
16
+ "codex-wrapped-noyrlimit-linux-x64-musl": "1.0.0",
17
+ "codex-wrapped-noyrlimit-linux-x64-baseline-musl": "1.0.0",
18
+ "codex-wrapped-noyrlimit-darwin-arm64": "1.0.0",
19
+ "codex-wrapped-noyrlimit-darwin-x64": "1.0.0",
20
+ "codex-wrapped-noyrlimit-darwin-x64-baseline": "1.0.0",
21
+ "codex-wrapped-noyrlimit-windows-x64": "1.0.0",
22
+ "codex-wrapped-noyrlimit-windows-x64-baseline": "1.0.0"
23
+ },
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "https://github.com/numman-ali/codex-wrapped.git"
27
+ },
28
+ "homepage": "https://github.com/numman-ali/codex-wrapped",
29
+ "bugs": {
30
+ "url": "https://github.com/numman-ali/codex-wrapped/issues"
31
+ },
32
+ "keywords": [
33
+ "codex",
34
+ "openai",
35
+ "wrapped",
36
+ "codex-wrapped"
37
+ ],
38
+ "author": {
39
+ "name": "Numman Ali",
40
+ "email": "numman.ali@gmail.com"
41
+ },
42
+ "license": "MIT"
43
+ }
@@ -0,0 +1,244 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Postinstall script for codex-wrapped-noyrlimit
5
+ *
6
+ * This script runs after npm install and symlinks the correct platform-specific
7
+ * binary to the bin directory. It auto-detects:
8
+ * - Platform (darwin, linux, windows)
9
+ * - Architecture (arm64, x64)
10
+ * - Libc (glibc, musl) for Linux
11
+ * - AVX2 support (baseline vs optimized) for x64
12
+ */
13
+
14
+ import fs from "fs";
15
+ import path from "path";
16
+ import os from "os";
17
+ import { execSync } from "child_process";
18
+ import { fileURLToPath } from "url";
19
+ import { createRequire } from "module";
20
+
21
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
22
+ const require = createRequire(import.meta.url);
23
+
24
+ /**
25
+ * Detect if the system uses musl libc (Alpine Linux, etc.)
26
+ */
27
+ function detectMusl() {
28
+ if (os.platform() !== "linux") return false;
29
+
30
+ try {
31
+ // Method 1: Check ldd output
32
+ const lddOutput = execSync("ldd --version 2>&1 || true", { encoding: "utf8" });
33
+ if (lddOutput.toLowerCase().includes("musl")) {
34
+ return true;
35
+ }
36
+
37
+ // Method 2: Check for musl loader
38
+ const files = fs.readdirSync("/lib").filter((f) => f.startsWith("ld-musl-"));
39
+ if (files.length > 0) {
40
+ return true;
41
+ }
42
+ } catch {
43
+ // Ignore errors
44
+ }
45
+
46
+ return false;
47
+ }
48
+
49
+ /**
50
+ * Detect if the CPU supports AVX2 instructions
51
+ */
52
+ function detectAVX2() {
53
+ if (os.arch() !== "x64") return true; // Only relevant for x64
54
+
55
+ try {
56
+ if (os.platform() === "linux") {
57
+ const cpuinfo = fs.readFileSync("/proc/cpuinfo", "utf8");
58
+ return cpuinfo.toLowerCase().includes("avx2");
59
+ }
60
+
61
+ if (os.platform() === "darwin") {
62
+ const output = execSync("sysctl -n machdep.cpu.features 2>/dev/null || true", {
63
+ encoding: "utf8",
64
+ });
65
+ return output.toLowerCase().includes("avx2");
66
+ }
67
+
68
+ if (os.platform() === "win32") {
69
+ // Windows: Assume AVX2 support on modern systems
70
+ // A more robust check would require native code
71
+ return true;
72
+ }
73
+ } catch {
74
+ // If we can't detect, assume AVX2 is supported
75
+ }
76
+
77
+ return true;
78
+ }
79
+
80
+ /**
81
+ * Get the platform-specific package name
82
+ */
83
+ function getPackageName() {
84
+ let platform;
85
+ switch (os.platform()) {
86
+ case "darwin":
87
+ platform = "darwin";
88
+ break;
89
+ case "linux":
90
+ platform = "linux";
91
+ break;
92
+ case "win32":
93
+ platform = "windows";
94
+ break;
95
+ default:
96
+ return null;
97
+ }
98
+
99
+ let arch;
100
+ switch (os.arch()) {
101
+ case "x64":
102
+ arch = "x64";
103
+ break;
104
+ case "arm64":
105
+ arch = "arm64";
106
+ break;
107
+ default:
108
+ return null;
109
+ }
110
+
111
+ // Build package name parts
112
+ const parts = ["codex-wrapped-noyrlimit", platform, arch];
113
+
114
+ // Add baseline suffix for x64 without AVX2
115
+ if (arch === "x64" && !detectAVX2()) {
116
+ parts.push("baseline");
117
+ }
118
+
119
+ // Add musl suffix for Linux with musl libc
120
+ if (platform === "linux" && detectMusl()) {
121
+ parts.push("musl");
122
+ }
123
+
124
+ return parts.join("-");
125
+ }
126
+
127
+ /**
128
+ * Find the binary from the platform package
129
+ */
130
+ function findBinary(packageName) {
131
+ const binaryName =
132
+ os.platform() === "win32" ? "codex-wrapped-noyrlimit.exe" : "codex-wrapped-noyrlimit";
133
+
134
+ try {
135
+ const packageJsonPath = require.resolve(`${packageName}/package.json`);
136
+ const packageDir = path.dirname(packageJsonPath);
137
+ const binaryPath = path.join(packageDir, "bin", binaryName);
138
+
139
+ if (fs.existsSync(binaryPath)) {
140
+ return { binaryPath, binaryName };
141
+ }
142
+ } catch {
143
+ // Package not found via require.resolve
144
+ }
145
+
146
+ // Fallback: try common paths
147
+ const fallbackPaths = [
148
+ path.join(__dirname, "..", packageName, "bin", binaryName),
149
+ path.join(__dirname, "node_modules", packageName, "bin", binaryName),
150
+ ];
151
+
152
+ for (const p of fallbackPaths) {
153
+ if (fs.existsSync(p)) {
154
+ return { binaryPath: p, binaryName };
155
+ }
156
+ }
157
+
158
+ return null;
159
+ }
160
+
161
+ /**
162
+ * Prepare the bin directory
163
+ */
164
+ function prepareBinDirectory(binaryName) {
165
+ const binDir = path.join(__dirname, "bin");
166
+ const targetPath = path.join(binDir, binaryName);
167
+
168
+ // Ensure bin directory exists
169
+ if (!fs.existsSync(binDir)) {
170
+ fs.mkdirSync(binDir, { recursive: true });
171
+ }
172
+
173
+ // Remove existing binary/symlink if it exists
174
+ if (fs.existsSync(targetPath)) {
175
+ fs.unlinkSync(targetPath);
176
+ }
177
+
178
+ return { binDir, targetPath };
179
+ }
180
+
181
+ /**
182
+ * Create symlink (or copy on Windows)
183
+ */
184
+ function linkBinary(sourcePath, binaryName) {
185
+ const { targetPath } = prepareBinDirectory(binaryName);
186
+
187
+ if (os.platform() === "win32") {
188
+ // Windows: copy instead of symlink (symlinks require admin)
189
+ fs.copyFileSync(sourcePath, targetPath);
190
+ } else {
191
+ fs.symlinkSync(sourcePath, targetPath);
192
+ }
193
+
194
+ // Verify the file exists
195
+ if (!fs.existsSync(targetPath)) {
196
+ throw new Error(`Failed to create binary at ${targetPath}`);
197
+ }
198
+ }
199
+
200
+ async function main() {
201
+ try {
202
+ const packageName = getPackageName();
203
+
204
+ if (!packageName) {
205
+ console.error(`codex-wrapped-noyrlimit: Unsupported platform: ${os.platform()}-${os.arch()}`);
206
+ console.error("Please download the binary manually from:");
207
+ console.error("https://github.com/numman-ali/codex-wrapped/releases");
208
+ process.exit(0); // Exit gracefully
209
+ }
210
+
211
+ console.log(`codex-wrapped-noyrlimit: Detected platform package: ${packageName}`);
212
+
213
+ const result = findBinary(packageName);
214
+
215
+ if (!result) {
216
+ // Try fallback without baseline/musl
217
+ const baseParts = packageName.split("-").slice(0, 3);
218
+ const basePackage = baseParts.join("-");
219
+
220
+ if (basePackage !== packageName) {
221
+ console.log(`codex-wrapped-noyrlimit: Trying fallback package: ${basePackage}`);
222
+ const fallbackResult = findBinary(basePackage);
223
+
224
+ if (fallbackResult) {
225
+ linkBinary(fallbackResult.binaryPath, fallbackResult.binaryName);
226
+ return;
227
+ }
228
+ }
229
+
230
+ console.error(`codex-wrapped-noyrlimit: Could not find binary for ${packageName}`);
231
+ console.error("The optional dependency may have failed to install.");
232
+ console.error("Please download the binary manually from:");
233
+ console.error("https://github.com/numman-ali/codex-wrapped/releases");
234
+ process.exit(0);
235
+ }
236
+
237
+ linkBinary(result.binaryPath, result.binaryName);
238
+ } catch (error) {
239
+ console.error("codex-wrapped-noyrlimit: Postinstall error:", error.message);
240
+ process.exit(0); // Exit gracefully to not break npm install
241
+ }
242
+ }
243
+
244
+ main();