ai-wrapped 1.2.0 → 1.3.1
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/bin/cli.ts +238 -0
- package/dist/assets/index-BL7674T7.js +43 -0
- package/dist/assets/index-CFTgb0TD.css +1 -0
- package/{src/mainview → dist}/index.html +2 -1
- package/dist/tray-icon.png +0 -0
- package/dist/tray-icon@2x.png +0 -0
- package/package.json +24 -4
- package/tsconfig.json +1 -1
- package/.0spec/config.toml +0 -50
- package/.0spec/flows/ai-stats-build.toml +0 -291
- package/.0spec/flows/ai-stats-fix.toml +0 -285
- package/.0spec/flows/ai-stats.toml +0 -400
- package/.github/workflows/pages.yml +0 -31
- package/.github/workflows/publish.yml +0 -34
- package/.releaserc.json +0 -9
- package/AGENTS.md +0 -120
- package/bun.lock +0 -635
- package/docs/CNAME +0 -1
- package/docs/icon.png +0 -0
- package/docs/index.html +0 -581
- package/src/mainview/App.tsx +0 -40
- package/src/mainview/components/AgentBadge.tsx +0 -17
- package/src/mainview/components/Dashboard.tsx +0 -343
- package/src/mainview/components/DashboardCharts.tsx +0 -663
- package/src/mainview/components/EmptyState.tsx +0 -17
- package/src/mainview/components/Sidebar.tsx +0 -128
- package/src/mainview/components/StatsCards.tsx +0 -118
- package/src/mainview/hooks/modelKeys.test.ts +0 -35
- package/src/mainview/hooks/modelKeys.ts +0 -15
- package/src/mainview/hooks/useDashboardData.ts +0 -436
- package/src/mainview/hooks/useRPC.ts +0 -29
- package/src/mainview/index.css +0 -203
- package/src/mainview/index.ts +0 -12
- package/src/mainview/lib/constants.ts +0 -32
- package/src/mainview/lib/formatters.test.ts +0 -14
- package/src/mainview/lib/formatters.ts +0 -82
- package/src/types/electrobun-bun.d.ts +0 -117
- package/src/types/electrobun-root.d.ts +0 -3
- package/src/types/electrobun-view.d.ts +0 -38
- package/tsconfig.typecheck.json +0 -11
- package/vite.config.ts +0 -23
package/bin/cli.ts
ADDED
|
@@ -0,0 +1,238 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
|
|
3
|
+
import { dirname, join } from "node:path";
|
|
4
|
+
|
|
5
|
+
const PKG_ROOT = join(dirname(Bun.main), "..");
|
|
6
|
+
const HOME = Bun.env.HOME || Bun.env.USERPROFILE || "";
|
|
7
|
+
const CACHE_DIR = `${HOME}/.ai-wrapped/app`;
|
|
8
|
+
const VERSION_FILE = `${CACHE_DIR}/version.json`;
|
|
9
|
+
|
|
10
|
+
interface CachedBuild {
|
|
11
|
+
version: string;
|
|
12
|
+
platform: string;
|
|
13
|
+
arch: string;
|
|
14
|
+
builtAt: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async function readCachedBuild(): Promise<CachedBuild | null> {
|
|
18
|
+
const file = Bun.file(VERSION_FILE);
|
|
19
|
+
if (!(await file.exists())) return null;
|
|
20
|
+
try {
|
|
21
|
+
return (await file.json()) as CachedBuild;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async function getPackageVersion(): Promise<string> {
|
|
28
|
+
const pkg = await Bun.file(join(PKG_ROOT, "package.json")).json();
|
|
29
|
+
return pkg.version;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function ensureRuntimeBuildDependencies(): Promise<void> {
|
|
33
|
+
const electrobunPkg = Bun.file(
|
|
34
|
+
join(PKG_ROOT, "node_modules", "electrobun", "package.json"),
|
|
35
|
+
);
|
|
36
|
+
if (await electrobunPkg.exists()) return;
|
|
37
|
+
|
|
38
|
+
// bunx extracts ai-wrapped without node_modules, but electrobun expects
|
|
39
|
+
// ./node_modules/electrobun relative to the app root when building.
|
|
40
|
+
console.log(" Installing build dependencies...\n");
|
|
41
|
+
const proc = Bun.spawn([process.execPath, "install", "--production"], {
|
|
42
|
+
cwd: PKG_ROOT,
|
|
43
|
+
stdout: "inherit",
|
|
44
|
+
stderr: "inherit",
|
|
45
|
+
env: { ...process.env },
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const exitCode = await proc.exited;
|
|
49
|
+
if (exitCode !== 0) {
|
|
50
|
+
throw new Error(`Dependency install failed with exit code ${exitCode}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function buildApp(): Promise<string> {
|
|
55
|
+
const platform = process.platform;
|
|
56
|
+
const arch = process.arch;
|
|
57
|
+
|
|
58
|
+
// Electrobun build needs to run from the package root
|
|
59
|
+
console.log(" Building app (first run only)...\n");
|
|
60
|
+
await ensureRuntimeBuildDependencies();
|
|
61
|
+
|
|
62
|
+
// Run electrobun build from the package directory
|
|
63
|
+
const proc = Bun.spawn(["bunx", "electrobun", "build"], {
|
|
64
|
+
cwd: PKG_ROOT,
|
|
65
|
+
stdout: "inherit",
|
|
66
|
+
stderr: "inherit",
|
|
67
|
+
env: { ...process.env },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
const exitCode = await proc.exited;
|
|
71
|
+
if (exitCode !== 0) {
|
|
72
|
+
throw new Error(`Build failed with exit code ${exitCode}`);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// Find the built .app
|
|
76
|
+
// Electrobun outputs to build/dev-{platform}-{arch}/ by default
|
|
77
|
+
const platformLabel =
|
|
78
|
+
platform === "darwin" ? "macos" : platform === "win32" ? "win" : "linux";
|
|
79
|
+
const buildDir = join(PKG_ROOT, "build", `dev-${platformLabel}-${arch}`);
|
|
80
|
+
|
|
81
|
+
if (platform === "darwin") {
|
|
82
|
+
const appPath = join(buildDir, "AI Wrapped-dev.app");
|
|
83
|
+
const exists = await Bun.file(join(appPath, "Contents", "Info.plist")).exists();
|
|
84
|
+
if (!exists) {
|
|
85
|
+
throw new Error(
|
|
86
|
+
`Build completed but app not found at ${appPath}. Check build output.`,
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
return appPath;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Linux/Windows: return the build directory
|
|
93
|
+
return buildDir;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function installToCache(builtPath: string): Promise<void> {
|
|
97
|
+
const platform = process.platform;
|
|
98
|
+
|
|
99
|
+
await Bun.$`mkdir -p ${CACHE_DIR}`.quiet();
|
|
100
|
+
|
|
101
|
+
if (platform === "darwin") {
|
|
102
|
+
// Copy .app bundle to cache
|
|
103
|
+
await Bun.$`rm -rf ${CACHE_DIR}/"AI Wrapped.app"`.quiet();
|
|
104
|
+
await Bun.$`cp -R ${builtPath} ${CACHE_DIR}/"AI Wrapped.app"`.quiet();
|
|
105
|
+
} else {
|
|
106
|
+
// Copy all files for linux/windows
|
|
107
|
+
await Bun.$`rm -rf ${CACHE_DIR}/app-files`.quiet();
|
|
108
|
+
await Bun.$`cp -R ${builtPath} ${CACHE_DIR}/app-files`.quiet();
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
async function launch(): Promise<void> {
|
|
113
|
+
const platform = process.platform;
|
|
114
|
+
|
|
115
|
+
if (platform === "darwin") {
|
|
116
|
+
const appPath = `${CACHE_DIR}/AI Wrapped.app`;
|
|
117
|
+
const plist = Bun.file(`${appPath}/Contents/Info.plist`);
|
|
118
|
+
if (!(await plist.exists())) {
|
|
119
|
+
throw new Error(
|
|
120
|
+
`App not found at ${appPath}. Try running with --rebuild.`,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
console.log(" Launching AI Wrapped...");
|
|
124
|
+
await Bun.$`open ${appPath}`.quiet();
|
|
125
|
+
} else if (platform === "linux") {
|
|
126
|
+
console.log(" Launching AI Wrapped...");
|
|
127
|
+
Bun.spawn(["sh", "-c", `"${CACHE_DIR}/app-files/launcher" &`], {
|
|
128
|
+
stdout: "ignore",
|
|
129
|
+
stderr: "ignore",
|
|
130
|
+
});
|
|
131
|
+
} else if (platform === "win32") {
|
|
132
|
+
console.log(" Launching AI Wrapped...");
|
|
133
|
+
Bun.spawn(
|
|
134
|
+
["cmd", "/c", "start", "", `${CACHE_DIR}\\app-files\\AI Wrapped.exe`],
|
|
135
|
+
{ stdout: "ignore", stderr: "ignore" },
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
async function main() {
|
|
141
|
+
const platform = process.platform;
|
|
142
|
+
const arch = process.arch;
|
|
143
|
+
|
|
144
|
+
console.log("");
|
|
145
|
+
console.log(" \x1b[1mAI Wrapped\x1b[0m");
|
|
146
|
+
console.log(" Your year in AI\n");
|
|
147
|
+
|
|
148
|
+
// --help
|
|
149
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
150
|
+
console.log(" Usage: ai-wrapped [options]\n");
|
|
151
|
+
console.log(" Options:");
|
|
152
|
+
console.log(" --version, -v Show installed version");
|
|
153
|
+
console.log(" --rebuild Force rebuild the app");
|
|
154
|
+
console.log(" --uninstall Remove cached app");
|
|
155
|
+
console.log(" --help, -h Show this help");
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// --version
|
|
160
|
+
if (process.argv.includes("--version") || process.argv.includes("-v")) {
|
|
161
|
+
const cached = await readCachedBuild();
|
|
162
|
+
const pkgVersion = await getPackageVersion();
|
|
163
|
+
console.log(` Package: v${pkgVersion}`);
|
|
164
|
+
console.log(
|
|
165
|
+
cached
|
|
166
|
+
? ` Installed: v${cached.version} (${cached.platform}/${cached.arch})`
|
|
167
|
+
: " Not built yet",
|
|
168
|
+
);
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// --uninstall
|
|
173
|
+
if (process.argv.includes("--uninstall")) {
|
|
174
|
+
console.log(" Removing ~/.ai-wrapped...");
|
|
175
|
+
if (platform === "win32") {
|
|
176
|
+
await Bun.$`powershell -Command "Remove-Item -Recurse -Force '${HOME}/.ai-wrapped' -ErrorAction SilentlyContinue"`.quiet();
|
|
177
|
+
} else {
|
|
178
|
+
await Bun.$`rm -rf ${HOME}/.ai-wrapped`.quiet();
|
|
179
|
+
}
|
|
180
|
+
console.log(" Done.");
|
|
181
|
+
return;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const forceRebuild = process.argv.includes("--rebuild");
|
|
185
|
+
|
|
186
|
+
// Check if we need to build
|
|
187
|
+
const pkgVersion = await getPackageVersion();
|
|
188
|
+
const cached = await readCachedBuild();
|
|
189
|
+
const platformLabel =
|
|
190
|
+
platform === "darwin" ? "macos" : platform === "win32" ? "win" : "linux";
|
|
191
|
+
const needsBuild =
|
|
192
|
+
forceRebuild ||
|
|
193
|
+
!cached ||
|
|
194
|
+
cached.version !== pkgVersion ||
|
|
195
|
+
cached.platform !== platformLabel ||
|
|
196
|
+
cached.arch !== arch;
|
|
197
|
+
|
|
198
|
+
if (needsBuild) {
|
|
199
|
+
if (cached && !forceRebuild) {
|
|
200
|
+
console.log(
|
|
201
|
+
` Upgrading v${cached.version} \u2192 v${pkgVersion}`,
|
|
202
|
+
);
|
|
203
|
+
} else if (!forceRebuild) {
|
|
204
|
+
console.log(` First run — building v${pkgVersion}...`);
|
|
205
|
+
} else {
|
|
206
|
+
console.log(` Rebuilding v${pkgVersion}...`);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const builtPath = await buildApp();
|
|
210
|
+
await installToCache(builtPath);
|
|
211
|
+
|
|
212
|
+
// Write version cache
|
|
213
|
+
await Bun.write(
|
|
214
|
+
VERSION_FILE,
|
|
215
|
+
JSON.stringify(
|
|
216
|
+
{
|
|
217
|
+
version: pkgVersion,
|
|
218
|
+
platform: platformLabel,
|
|
219
|
+
arch,
|
|
220
|
+
builtAt: new Date().toISOString(),
|
|
221
|
+
},
|
|
222
|
+
null,
|
|
223
|
+
2,
|
|
224
|
+
),
|
|
225
|
+
);
|
|
226
|
+
|
|
227
|
+
console.log(`\n Built and cached v${pkgVersion}\n`);
|
|
228
|
+
} else {
|
|
229
|
+
console.log(` v${pkgVersion} ready\n`);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
await launch();
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
main().catch((err) => {
|
|
236
|
+
console.error(`\n Error: ${(err as Error).message}`);
|
|
237
|
+
process.exit(1);
|
|
238
|
+
});
|