vibetracking 0.1.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.
Files changed (46) hide show
  1. package/README.md +77 -0
  2. package/dist/auth.d.ts +17 -0
  3. package/dist/auth.d.ts.map +1 -0
  4. package/dist/auth.js +162 -0
  5. package/dist/auth.js.map +1 -0
  6. package/dist/cli.d.ts +8 -0
  7. package/dist/cli.d.ts.map +1 -0
  8. package/dist/cli.js +440 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/credentials.d.ts +36 -0
  11. package/dist/credentials.d.ts.map +1 -0
  12. package/dist/credentials.js +82 -0
  13. package/dist/credentials.js.map +1 -0
  14. package/dist/cursor.d.ts +136 -0
  15. package/dist/cursor.d.ts.map +1 -0
  16. package/dist/cursor.js +400 -0
  17. package/dist/cursor.js.map +1 -0
  18. package/dist/graph-types.d.ts +152 -0
  19. package/dist/graph-types.d.ts.map +1 -0
  20. package/dist/graph-types.js +6 -0
  21. package/dist/graph-types.js.map +1 -0
  22. package/dist/native-runner.d.ts +11 -0
  23. package/dist/native-runner.d.ts.map +1 -0
  24. package/dist/native-runner.js +61 -0
  25. package/dist/native-runner.js.map +1 -0
  26. package/dist/native.d.ts +98 -0
  27. package/dist/native.d.ts.map +1 -0
  28. package/dist/native.js +309 -0
  29. package/dist/native.js.map +1 -0
  30. package/dist/sessions/types.d.ts +28 -0
  31. package/dist/sessions/types.d.ts.map +1 -0
  32. package/dist/sessions/types.js +27 -0
  33. package/dist/sessions/types.js.map +1 -0
  34. package/dist/spinner.d.ts +75 -0
  35. package/dist/spinner.d.ts.map +1 -0
  36. package/dist/spinner.js +203 -0
  37. package/dist/spinner.js.map +1 -0
  38. package/dist/submit.d.ts +23 -0
  39. package/dist/submit.d.ts.map +1 -0
  40. package/dist/submit.js +144 -0
  41. package/dist/submit.js.map +1 -0
  42. package/dist/table.d.ts +6 -0
  43. package/dist/table.d.ts.map +1 -0
  44. package/dist/table.js +10 -0
  45. package/dist/table.js.map +1 -0
  46. package/package.json +61 -0
package/dist/cli.js ADDED
@@ -0,0 +1,440 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Vibetracking CLI
4
+ * Track AI coding assistant usage across Claude Code, Codex, Cursor, and more.
5
+ * Browser-first experience - data is viewed and shared on vibetracking.dev
6
+ */
7
+ import { Command } from "commander";
8
+ import { createRequire } from "module";
9
+ const require = createRequire(import.meta.url);
10
+ const pkg = require("../package.json");
11
+ import pc from "picocolors";
12
+ import open from "open";
13
+ import pako from "pako";
14
+ import { getApiBaseUrl, loadCredentials } from "./credentials.js";
15
+ import { login, logout, whoami } from "./auth.js";
16
+ import { loadCursorCredentials, saveCursorCredentials, clearCursorCredentials, validateCursorSession, readCursorUsage, getCursorCredentialsPath, syncCursorCache, isCursorLoggedIn, isCursorInstalled, } from "./cursor.js";
17
+ import { parseLocalSourcesAsync, finalizeGraphAsync, } from "./native.js";
18
+ import { createSpinner } from "./spinner.js";
19
+ // =============================================================================
20
+ // Helpers
21
+ // =============================================================================
22
+ function formatNumber(num) {
23
+ return num.toLocaleString("en-US");
24
+ }
25
+ function formatCurrency(amount) {
26
+ return `$${amount.toFixed(2)}`;
27
+ }
28
+ // =============================================================================
29
+ // Data Encoding for Browser Import
30
+ // =============================================================================
31
+ function encodeDataForBrowser(data) {
32
+ const jsonString = JSON.stringify(data);
33
+ const compressed = pako.gzip(jsonString);
34
+ // Convert to base64url
35
+ const base64 = Buffer.from(compressed).toString("base64");
36
+ return base64.replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
37
+ }
38
+ // =============================================================================
39
+ // Main Functions
40
+ // =============================================================================
41
+ async function main() {
42
+ const program = new Command();
43
+ program
44
+ .name("vibetracking")
45
+ .description("Vibetracking - Track AI coding costs across Claude Code, Codex, Cursor, and more")
46
+ .version(pkg.version);
47
+ // Default command: sync if authenticated, else open browser
48
+ program
49
+ .command("default", { isDefault: true, hidden: true })
50
+ .action(async () => {
51
+ const credentials = loadCredentials();
52
+ if (credentials) {
53
+ await syncAndPrintProfile(credentials);
54
+ }
55
+ else {
56
+ await openBrowserWithData();
57
+ }
58
+ });
59
+ // Authentication commands
60
+ program.command("login").description("Login to vibetracking.dev").action(login);
61
+ program.command("logout").description("Logout from vibetracking.dev").action(logout);
62
+ program.command("whoami").description("Show current user").action(whoami);
63
+ // Sync command for cron jobs
64
+ program
65
+ .command("sync")
66
+ .description("Sync usage data to vibetracking.dev (for cron jobs)")
67
+ .option("--quiet", "No output on success")
68
+ .action(async (options) => {
69
+ await handleSyncCommand(options);
70
+ });
71
+ // Cursor IDE integration
72
+ const cursorCommand = program
73
+ .command("cursor")
74
+ .description("Cursor IDE integration commands");
75
+ cursorCommand
76
+ .command("login")
77
+ .description("Login to Cursor (paste your session token)")
78
+ .action(async () => {
79
+ await cursorLogin();
80
+ });
81
+ cursorCommand
82
+ .command("logout")
83
+ .description("Logout from Cursor")
84
+ .action(async () => {
85
+ await cursorLogout();
86
+ });
87
+ cursorCommand
88
+ .command("status")
89
+ .description("Check Cursor authentication status")
90
+ .action(async () => {
91
+ await cursorStatus();
92
+ });
93
+ await program.parseAsync();
94
+ }
95
+ // =============================================================================
96
+ // Default Command: Sync if authenticated, else open browser
97
+ // =============================================================================
98
+ async function syncAndPrintProfile(credentials) {
99
+ const spinner = createSpinner({ color: "cyan" });
100
+ spinner.start(pc.gray("Syncing usage data..."));
101
+ const allSources = ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid'];
102
+ const localSources = allSources.filter(s => s !== 'cursor');
103
+ const { cursorSync, localMessages } = await loadDataSourcesParallel(localSources);
104
+ if (!localMessages) {
105
+ spinner.error("No data found to sync.");
106
+ process.exit(1);
107
+ }
108
+ const graphData = await finalizeGraphAsync({
109
+ localMessages,
110
+ includeCursor: cursorSync.synced,
111
+ });
112
+ const baseUrl = getApiBaseUrl();
113
+ const response = await fetch(`${baseUrl}/api/sync`, {
114
+ method: "POST",
115
+ headers: {
116
+ "Authorization": `Bearer ${credentials.token}`,
117
+ "Content-Type": "application/json",
118
+ },
119
+ body: JSON.stringify({ data: graphData }),
120
+ });
121
+ if (!response.ok) {
122
+ spinner.error(`Sync failed: ${response.statusText}`);
123
+ process.exit(1);
124
+ }
125
+ spinner.stop();
126
+ console.log(pc.green("\n Synced successfully!"));
127
+ console.log(pc.cyan(` ${baseUrl}/@${credentials.username}\n`));
128
+ }
129
+ /**
130
+ * Prompt user to login to Cursor during first-run if Cursor is installed
131
+ * Returns true if user successfully logged in, false otherwise
132
+ */
133
+ async function promptForCursorLogin() {
134
+ const readline = await import("node:readline");
135
+ const rl = readline.createInterface({
136
+ input: process.stdin,
137
+ output: process.stdout,
138
+ });
139
+ // Ask y/n question
140
+ const shouldLogin = await new Promise((resolve) => {
141
+ rl.question(pc.white(" Would you like to include your Cursor usage data? (y/n): "), (answer) => {
142
+ resolve(answer.trim().toLowerCase() === "y");
143
+ });
144
+ });
145
+ if (!shouldLogin) {
146
+ rl.close();
147
+ console.log();
148
+ return false;
149
+ }
150
+ // Open browser to Cursor dashboard
151
+ console.log(pc.gray("\n Opening Cursor dashboard in your browser..."));
152
+ await open("https://www.cursor.com/dashboard");
153
+ // Show instructions - token is HttpOnly so must use Network tab
154
+ const isMac = process.platform === "darwin";
155
+ const devtoolsShortcut = isMac ? "Cmd+Option+I" : "F12";
156
+ console.log(pc.white("\n To get your token:"));
157
+ console.log(pc.gray(` 1. Press ${pc.white(devtoolsShortcut)} to open DevTools`));
158
+ console.log(pc.gray(` 2. Go to ${pc.white("Network")} tab, click any request to cursor.com`));
159
+ console.log(pc.gray(` 3. In the ${pc.white("Cookies")} tab, find ${pc.white("WorkosCursorSessionToken")}`));
160
+ console.log(pc.gray(` 4. Copy the value (starts with "eyJ...")`));
161
+ console.log();
162
+ // Prompt for token
163
+ const token = await new Promise((resolve) => {
164
+ rl.question(pc.white(" Paste your session token: "), (answer) => {
165
+ rl.close();
166
+ resolve(answer.trim());
167
+ });
168
+ });
169
+ if (!token) {
170
+ console.log(pc.yellow("\n Skipped. You can run 'vibetracking cursor login' later.\n"));
171
+ return false;
172
+ }
173
+ // Validate and save
174
+ console.log(pc.gray("\n Validating token..."));
175
+ const validation = await validateCursorSession(token);
176
+ if (!validation.valid) {
177
+ console.log(pc.red(`\n Invalid token: ${validation.error}`));
178
+ console.log(pc.gray(" Continuing without Cursor data. Run 'vibetracking cursor login' later.\n"));
179
+ return false;
180
+ }
181
+ saveCursorCredentials({
182
+ sessionToken: token,
183
+ createdAt: new Date().toISOString(),
184
+ });
185
+ console.log(pc.green("\n Success! Logged in to Cursor."));
186
+ if (validation.membershipType) {
187
+ console.log(pc.gray(` Membership: ${validation.membershipType}`));
188
+ }
189
+ console.log();
190
+ return true;
191
+ }
192
+ async function openBrowserWithData() {
193
+ // Check if Cursor is installed but not logged in - prompt user to setup
194
+ const cursorInstalled = isCursorInstalled();
195
+ const cursorLoggedIn = isCursorLoggedIn();
196
+ console.log(pc.cyan("\n Vibetracking\n"));
197
+ if (cursorInstalled && !cursorLoggedIn) {
198
+ console.log(pc.white(" We detected Cursor IDE installed."));
199
+ await promptForCursorLogin();
200
+ }
201
+ const spinner = createSpinner({ color: "cyan" });
202
+ spinner.start(pc.gray("Scanning AI coding tool data..."));
203
+ const allSources = ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid'];
204
+ const localSources = allSources.filter(s => s !== 'cursor');
205
+ const includeCursor = isCursorLoggedIn();
206
+ const { cursorSync, localMessages } = await loadDataSourcesParallel(localSources);
207
+ // Check if we have any data - either from local sources or Cursor
208
+ const hasLocalData = localMessages && localMessages.messages.length > 0;
209
+ const hasCursorData = includeCursor && cursorSync.synced && cursorSync.rows > 0;
210
+ if (!hasLocalData && !hasCursorData) {
211
+ spinner.error("No AI coding tool data found on this machine.");
212
+ console.log(pc.gray("\n Supported tools:"));
213
+ console.log(pc.gray(" - Claude Code (~/.claude/projects/)"));
214
+ console.log(pc.gray(" - Codex (~/.codex/)"));
215
+ console.log(pc.gray(" - Cursor (use 'vibetracking cursor login' first)"));
216
+ if (cursorSync.error) {
217
+ console.log(pc.gray(`\n Cursor sync error: ${cursorSync.error}`));
218
+ }
219
+ console.log();
220
+ process.exit(1);
221
+ }
222
+ spinner.update(pc.gray("Building data export..."));
223
+ // Get graph data for encoding
224
+ // Use empty ParsedMessages if no local data (Cursor-only scenario)
225
+ const emptyParsedMessages = {
226
+ messages: [],
227
+ opencodeCount: 0,
228
+ claudeCount: 0,
229
+ codexCount: 0,
230
+ geminiCount: 0,
231
+ ampCount: 0,
232
+ droidCount: 0,
233
+ processingTimeMs: 0,
234
+ };
235
+ const messagesForGraph = localMessages ?? emptyParsedMessages;
236
+ const graphData = await finalizeGraphAsync({
237
+ localMessages: messagesForGraph,
238
+ includeCursor: includeCursor && cursorSync.synced,
239
+ });
240
+ spinner.stop();
241
+ // Show summary
242
+ const totalTokens = graphData.summary.totalTokens;
243
+ const totalCost = graphData.summary.totalCost;
244
+ const sources = graphData.summary.sources;
245
+ console.log(pc.white(` Found ${formatNumber(totalTokens)} tokens from ${sources.length} tool${sources.length > 1 ? "s" : ""}`));
246
+ console.log(pc.gray(` Estimated cost: ${pc.green(formatCurrency(totalCost))}`));
247
+ console.log(pc.gray(` Sources: ${sources.join(", ")}`));
248
+ console.log();
249
+ // Encode data and open browser
250
+ const encoded = encodeDataForBrowser(graphData);
251
+ const baseUrl = getApiBaseUrl();
252
+ const url = `${baseUrl}/import#${encoded}`;
253
+ console.log(pc.white(" Opening browser to import your data..."));
254
+ console.log(pc.gray(` ${url.slice(0, 60)}...\n`));
255
+ await open(url);
256
+ }
257
+ // =============================================================================
258
+ // Sync Command (for cron jobs)
259
+ // =============================================================================
260
+ async function handleSyncCommand(options) {
261
+ const credentials = loadCredentials();
262
+ if (!credentials) {
263
+ if (!options.quiet) {
264
+ console.log(pc.yellow("\n Not authenticated."));
265
+ console.log(pc.gray(" Run 'vibetracking' first to authenticate via browser.\n"));
266
+ }
267
+ process.exit(1);
268
+ }
269
+ const allSources = ['opencode', 'claude', 'codex', 'gemini', 'cursor', 'amp', 'droid'];
270
+ const localSources = allSources.filter(s => s !== 'cursor');
271
+ const { cursorSync, localMessages } = await loadDataSourcesParallel(localSources);
272
+ if (!localMessages) {
273
+ if (!options.quiet) {
274
+ console.log(pc.yellow("\n No data to sync.\n"));
275
+ }
276
+ process.exit(1);
277
+ }
278
+ const graphData = await finalizeGraphAsync({
279
+ localMessages,
280
+ includeCursor: cursorSync.synced,
281
+ });
282
+ const baseUrl = getApiBaseUrl();
283
+ const response = await fetch(`${baseUrl}/api/sync`, {
284
+ method: "POST",
285
+ headers: {
286
+ "Authorization": `Bearer ${credentials.token}`,
287
+ "Content-Type": "application/json",
288
+ },
289
+ body: JSON.stringify({ data: graphData }),
290
+ });
291
+ if (!response.ok) {
292
+ if (!options.quiet) {
293
+ console.log(pc.red(`\n Sync failed: ${response.statusText}\n`));
294
+ }
295
+ process.exit(1);
296
+ }
297
+ if (!options.quiet) {
298
+ console.log(pc.green("\n Synced successfully!"));
299
+ console.log(pc.cyan(` ${baseUrl}/@${credentials.username}\n`));
300
+ }
301
+ }
302
+ // =============================================================================
303
+ // Data Loading
304
+ // =============================================================================
305
+ async function syncCursorData() {
306
+ const credentials = loadCursorCredentials();
307
+ if (!credentials) {
308
+ return { attempted: false, synced: false, rows: 0 };
309
+ }
310
+ const result = await syncCursorCache();
311
+ return {
312
+ attempted: true,
313
+ synced: result.synced,
314
+ rows: result.rows,
315
+ error: result.error,
316
+ };
317
+ }
318
+ async function loadDataSourcesParallel(localSources) {
319
+ const shouldParseLocal = localSources.length > 0;
320
+ const [cursorResult, localResult] = await Promise.allSettled([
321
+ syncCursorData(),
322
+ shouldParseLocal
323
+ ? parseLocalSourcesAsync({
324
+ sources: localSources.filter(s => s !== 'cursor'),
325
+ })
326
+ : Promise.resolve(null),
327
+ ]);
328
+ const cursorSync = cursorResult.status === 'fulfilled'
329
+ ? cursorResult.value
330
+ : { attempted: true, synced: false, rows: 0, error: 'Cursor sync failed' };
331
+ const localMessages = localResult.status === 'fulfilled'
332
+ ? localResult.value
333
+ : null;
334
+ return { cursorSync, localMessages };
335
+ }
336
+ // =============================================================================
337
+ // Cursor IDE Authentication
338
+ // =============================================================================
339
+ async function cursorLogin() {
340
+ const credentials = loadCursorCredentials();
341
+ if (credentials) {
342
+ console.log(pc.yellow("\n Already logged in to Cursor."));
343
+ console.log(pc.gray(" Run 'vibetracking cursor logout' to sign out first.\n"));
344
+ return;
345
+ }
346
+ console.log(pc.cyan("\n Cursor IDE - Login\n"));
347
+ // Open browser to Cursor dashboard
348
+ console.log(pc.gray(" Opening Cursor dashboard in your browser..."));
349
+ await open("https://www.cursor.com/dashboard");
350
+ // Show instructions - token is HttpOnly so must use Network tab
351
+ const isMac = process.platform === "darwin";
352
+ const devtoolsShortcut = isMac ? "Cmd+Option+I" : "F12";
353
+ console.log(pc.white("\n To get your token:"));
354
+ console.log(pc.gray(` 1. Press ${pc.white(devtoolsShortcut)} to open DevTools`));
355
+ console.log(pc.gray(` 2. Go to ${pc.white("Network")} tab, click any request to cursor.com`));
356
+ console.log(pc.gray(` 3. In the ${pc.white("Cookies")} tab, find ${pc.white("WorkosCursorSessionToken")}`));
357
+ console.log(pc.gray(` 4. Copy the value (starts with "eyJ...")`));
358
+ console.log();
359
+ const readline = await import("node:readline");
360
+ const rl = readline.createInterface({
361
+ input: process.stdin,
362
+ output: process.stdout,
363
+ });
364
+ const token = await new Promise((resolve) => {
365
+ rl.question(pc.white(" Paste your session token: "), (answer) => {
366
+ rl.close();
367
+ resolve(answer.trim());
368
+ });
369
+ });
370
+ if (!token) {
371
+ console.log(pc.red("\n No token provided. Login cancelled.\n"));
372
+ return;
373
+ }
374
+ console.log(pc.gray("\n Validating token..."));
375
+ const validation = await validateCursorSession(token);
376
+ if (!validation.valid) {
377
+ console.log(pc.red(`\n Invalid token: ${validation.error}`));
378
+ console.log(pc.gray(" Please try again with a valid session token.\n"));
379
+ return;
380
+ }
381
+ saveCursorCredentials({
382
+ sessionToken: token,
383
+ createdAt: new Date().toISOString(),
384
+ });
385
+ console.log(pc.green("\n Success! Logged in to Cursor."));
386
+ if (validation.membershipType) {
387
+ console.log(pc.gray(` Membership: ${validation.membershipType}`));
388
+ }
389
+ console.log(pc.gray(" Your usage data will now be included in reports.\n"));
390
+ }
391
+ async function cursorLogout() {
392
+ const credentials = loadCursorCredentials();
393
+ if (!credentials) {
394
+ console.log(pc.yellow("\n Not logged in to Cursor.\n"));
395
+ return;
396
+ }
397
+ const cleared = clearCursorCredentials();
398
+ if (cleared) {
399
+ console.log(pc.green("\n Logged out from Cursor.\n"));
400
+ }
401
+ else {
402
+ console.error(pc.red("\n Failed to clear Cursor credentials.\n"));
403
+ process.exit(1);
404
+ }
405
+ }
406
+ async function cursorStatus() {
407
+ const credentials = loadCursorCredentials();
408
+ if (!credentials) {
409
+ console.log(pc.yellow("\n Not logged in to Cursor."));
410
+ console.log(pc.gray(" Run 'vibetracking cursor login' to authenticate.\n"));
411
+ return;
412
+ }
413
+ console.log(pc.cyan("\n Cursor IDE - Status\n"));
414
+ console.log(pc.gray(" Checking session validity..."));
415
+ const validation = await validateCursorSession(credentials.sessionToken);
416
+ if (validation.valid) {
417
+ console.log(pc.green(" Session is valid"));
418
+ if (validation.membershipType) {
419
+ console.log(pc.white(` Membership: ${validation.membershipType}`));
420
+ }
421
+ console.log(pc.gray(` Logged in: ${new Date(credentials.createdAt).toLocaleDateString()}`));
422
+ try {
423
+ const usage = await readCursorUsage();
424
+ const totalCost = usage.byModel.reduce((sum, m) => sum + m.cost, 0);
425
+ console.log(pc.gray(` Models used: ${usage.byModel.length}`));
426
+ console.log(pc.gray(` Total usage events: ${usage.rows.length}`));
427
+ console.log(pc.gray(` Total cost: $${totalCost.toFixed(2)}`));
428
+ }
429
+ catch {
430
+ // Ignore fetch errors for status check
431
+ }
432
+ }
433
+ else {
434
+ console.log(pc.red(` Session invalid: ${validation.error}`));
435
+ console.log(pc.gray(" Run 'vibetracking cursor login' to re-authenticate."));
436
+ }
437
+ console.log(pc.gray(`\n Credentials: ${getCursorCredentialsPath()}\n`));
438
+ }
439
+ main().catch(console.error);
440
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Vibetracking CLI Credentials Manager
3
+ * Stores and retrieves API tokens for authenticated CLI operations
4
+ */
5
+ export interface Credentials {
6
+ token: string;
7
+ username: string;
8
+ avatarUrl?: string;
9
+ createdAt: string;
10
+ }
11
+ /**
12
+ * Save credentials to disk
13
+ */
14
+ export declare function saveCredentials(credentials: Credentials): void;
15
+ /**
16
+ * Load credentials from disk
17
+ * Returns null if no credentials are stored or file is invalid
18
+ */
19
+ export declare function loadCredentials(): Credentials | null;
20
+ /**
21
+ * Clear stored credentials
22
+ */
23
+ export declare function clearCredentials(): boolean;
24
+ /**
25
+ * Check if user is logged in
26
+ */
27
+ export declare function isLoggedIn(): boolean;
28
+ /**
29
+ * Get the API base URL
30
+ */
31
+ export declare function getApiBaseUrl(): string;
32
+ /**
33
+ * Get the credentials file path (for debugging)
34
+ */
35
+ export declare function getCredentialsPath(): string;
36
+ //# sourceMappingURL=credentials.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAMH,MAAM,WAAW,WAAW;IAC1B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;CACnB;AAcD;;GAEG;AACH,wBAAgB,eAAe,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI,CAM9D;AAED;;;GAGG;AACH,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAiBpD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,IAAI,OAAO,CAU1C;AAED;;GAEG;AACH,wBAAgB,UAAU,IAAI,OAAO,CAEpC;AAED;;GAEG;AACH,wBAAgB,aAAa,IAAI,MAAM,CAEtC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,IAAI,MAAM,CAE3C"}
@@ -0,0 +1,82 @@
1
+ /**
2
+ * Vibetracking CLI Credentials Manager
3
+ * Stores and retrieves API tokens for authenticated CLI operations
4
+ */
5
+ import * as fs from "node:fs";
6
+ import * as path from "node:path";
7
+ import * as os from "node:os";
8
+ const CONFIG_DIR = path.join(os.homedir(), ".vibetracking");
9
+ const CREDENTIALS_FILE = path.join(CONFIG_DIR, "credentials.json");
10
+ /**
11
+ * Ensure the config directory exists
12
+ */
13
+ function ensureConfigDir() {
14
+ if (!fs.existsSync(CONFIG_DIR)) {
15
+ fs.mkdirSync(CONFIG_DIR, { recursive: true, mode: 0o700 });
16
+ }
17
+ }
18
+ /**
19
+ * Save credentials to disk
20
+ */
21
+ export function saveCredentials(credentials) {
22
+ ensureConfigDir();
23
+ fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(credentials, null, 2), {
24
+ encoding: "utf-8",
25
+ mode: 0o600, // Read/write for owner only
26
+ });
27
+ }
28
+ /**
29
+ * Load credentials from disk
30
+ * Returns null if no credentials are stored or file is invalid
31
+ */
32
+ export function loadCredentials() {
33
+ try {
34
+ if (!fs.existsSync(CREDENTIALS_FILE)) {
35
+ return null;
36
+ }
37
+ const data = fs.readFileSync(CREDENTIALS_FILE, "utf-8");
38
+ const parsed = JSON.parse(data);
39
+ // Validate structure
40
+ if (!parsed.token || !parsed.username) {
41
+ return null;
42
+ }
43
+ return parsed;
44
+ }
45
+ catch {
46
+ return null;
47
+ }
48
+ }
49
+ /**
50
+ * Clear stored credentials
51
+ */
52
+ export function clearCredentials() {
53
+ try {
54
+ if (fs.existsSync(CREDENTIALS_FILE)) {
55
+ fs.unlinkSync(CREDENTIALS_FILE);
56
+ return true;
57
+ }
58
+ return false;
59
+ }
60
+ catch {
61
+ return false;
62
+ }
63
+ }
64
+ /**
65
+ * Check if user is logged in
66
+ */
67
+ export function isLoggedIn() {
68
+ return loadCredentials() !== null;
69
+ }
70
+ /**
71
+ * Get the API base URL
72
+ */
73
+ export function getApiBaseUrl() {
74
+ return process.env.VIBETRACKING_API_URL || "https://vibetracking.dev";
75
+ }
76
+ /**
77
+ * Get the credentials file path (for debugging)
78
+ */
79
+ export function getCredentialsPath() {
80
+ return CREDENTIALS_FILE;
81
+ }
82
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAS9B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,eAAe,CAAC,CAAC;AAC5D,MAAM,gBAAgB,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;AAEnE;;GAEG;AACH,SAAS,eAAe;IACtB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC/B,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,WAAwB;IACtD,eAAe,EAAE,CAAC;IAClB,EAAE,CAAC,aAAa,CAAC,gBAAgB,EAAE,IAAI,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE;QACvE,QAAQ,EAAE,OAAO;QACjB,IAAI,EAAE,KAAK,EAAE,4BAA4B;KAC1C,CAAC,CAAC;AACL,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe;IAC7B,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,GAAG,EAAE,CAAC,YAAY,CAAC,gBAAgB,EAAE,OAAO,CAAC,CAAC;QACxD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAEhC,qBAAqB;QACrB,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;YACtC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,MAAqB,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB;IAC9B,IAAI,CAAC;QACH,IAAI,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,EAAE,CAAC;YACpC,EAAE,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU;IACxB,OAAO,eAAe,EAAE,KAAK,IAAI,CAAC;AACpC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa;IAC3B,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,0BAA0B,CAAC;AACxE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB;IAChC,OAAO,gBAAgB,CAAC;AAC1B,CAAC"}