antigravity-usage 0.2.0 → 0.2.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/README.md CHANGED
@@ -107,11 +107,19 @@ Tables automatically adapt to your terminal size, switching between "Compact" an
107
107
  Alias for `quota`. Fetches and displays usage data.
108
108
 
109
109
  ```bash
110
- antigravity-usage # Auto-detect (Local -> Cloud)
111
- antigravity-usage --all # Fetch ALL accounts
112
- antigravity-usage --method local # Force local IDE connection
110
+ antigravity-usage # Auto-detect (Local -> Cloud)
111
+ antigravity-usage --all # Fetch ALL accounts
112
+ antigravity-usage --method local # Force local IDE connection
113
113
  antigravity-usage --method google # Force google IDE connection
114
- antigravity-usage --json # Output JSON for scripts
114
+ antigravity-usage --json # Output JSON for scripts
115
+ antigravity-usage --version # Show version number
116
+ ```
117
+
118
+ ### `antigravity-usage --version`
119
+ Display the current version of the CLI tool.
120
+
121
+ ```bash
122
+ antigravity-usage --version # or -V
115
123
  ```
116
124
 
117
125
  ### `antigravity-usage accounts`
package/dist/index.js CHANGED
@@ -4,7 +4,14 @@
4
4
  import { Command } from "commander";
5
5
 
6
6
  // src/version.ts
7
- var version = "0.1.0";
7
+ import { readFileSync } from "fs";
8
+ import { join, dirname } from "path";
9
+ import { fileURLToPath } from "url";
10
+ var __filename = fileURLToPath(import.meta.url);
11
+ var __dirname = dirname(__filename);
12
+ var packageJsonPath = join(__dirname, "../package.json");
13
+ var packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
14
+ var version = packageJson.version;
8
15
 
9
16
  // src/core/logger.ts
10
17
  var debugMode = false;
@@ -52,12 +59,12 @@ var DEFAULT_CONFIG = {
52
59
  };
53
60
 
54
61
  // src/accounts/storage.ts
55
- import { existsSync, mkdirSync, readFileSync, writeFileSync, readdirSync, rmSync } from "fs";
56
- import { join as join2 } from "path";
62
+ import { existsSync, mkdirSync, readFileSync as readFileSync2, writeFileSync, readdirSync, rmSync } from "fs";
63
+ import { join as join3 } from "path";
57
64
 
58
65
  // src/core/env.ts
59
66
  import { homedir, platform } from "os";
60
- import { join } from "path";
67
+ import { join as join2 } from "path";
61
68
  function getPlatform() {
62
69
  const p = platform();
63
70
  if (p === "win32") return "windows";
@@ -69,26 +76,26 @@ function getConfigDir() {
69
76
  const home = homedir();
70
77
  switch (p) {
71
78
  case "windows":
72
- return join(process.env.APPDATA || join(home, "AppData", "Roaming"), "antigravity-usage");
79
+ return join2(process.env.APPDATA || join2(home, "AppData", "Roaming"), "antigravity-usage");
73
80
  case "macos":
74
- return join(home, "Library", "Application Support", "antigravity-usage");
81
+ return join2(home, "Library", "Application Support", "antigravity-usage");
75
82
  case "linux":
76
83
  default:
77
- return join(process.env.XDG_CONFIG_HOME || join(home, ".config"), "antigravity-usage");
84
+ return join2(process.env.XDG_CONFIG_HOME || join2(home, ".config"), "antigravity-usage");
78
85
  }
79
86
  }
80
87
  function getTokensPath() {
81
- return join(getConfigDir(), "tokens.json");
88
+ return join2(getConfigDir(), "tokens.json");
82
89
  }
83
90
  function getAccountsDir() {
84
- return join(getConfigDir(), "accounts");
91
+ return join2(getConfigDir(), "accounts");
85
92
  }
86
93
  function getAccountDir(email) {
87
94
  const safeName = email.replace(/[^a-zA-Z0-9@._-]/g, "_");
88
- return join(getAccountsDir(), safeName);
95
+ return join2(getAccountsDir(), safeName);
89
96
  }
90
97
  function getGlobalConfigPath() {
91
- return join(getConfigDir(), "config.json");
98
+ return join2(getConfigDir(), "config.json");
92
99
  }
93
100
 
94
101
  // src/accounts/storage.ts
@@ -109,7 +116,7 @@ function ensureAccountDir(email) {
109
116
  }
110
117
  function accountExists(email) {
111
118
  const dir = getAccountDir(email);
112
- return existsSync(dir) && existsSync(join2(dir, "tokens.json"));
119
+ return existsSync(dir) && existsSync(join3(dir, "tokens.json"));
113
120
  }
114
121
  function listAccountEmails() {
115
122
  const accountsDir = getAccountsDir();
@@ -121,7 +128,7 @@ function listAccountEmails() {
121
128
  const emails = [];
122
129
  for (const entry of entries) {
123
130
  if (entry.isDirectory()) {
124
- const tokensPath = join2(accountsDir, entry.name, "tokens.json");
131
+ const tokensPath = join3(accountsDir, entry.name, "tokens.json");
125
132
  if (existsSync(tokensPath)) {
126
133
  emails.push(entry.name);
127
134
  }
@@ -135,18 +142,18 @@ function listAccountEmails() {
135
142
  }
136
143
  function saveAccountTokens(email, tokens) {
137
144
  ensureAccountDir(email);
138
- const path = join2(getAccountDir(email), "tokens.json");
145
+ const path = join3(getAccountDir(email), "tokens.json");
139
146
  debug("accounts-storage", `Saving tokens for ${email}`);
140
147
  writeFileSync(path, JSON.stringify(tokens, null, 2), { mode: 384 });
141
148
  }
142
149
  function loadAccountTokens(email) {
143
- const path = join2(getAccountDir(email), "tokens.json");
150
+ const path = join3(getAccountDir(email), "tokens.json");
144
151
  if (!existsSync(path)) {
145
152
  debug("accounts-storage", `No tokens file for ${email}`);
146
153
  return null;
147
154
  }
148
155
  try {
149
- const content = readFileSync(path, "utf-8");
156
+ const content = readFileSync2(path, "utf-8");
150
157
  return JSON.parse(content);
151
158
  } catch (err) {
152
159
  debug("accounts-storage", `Failed to parse tokens for ${email}`, err);
@@ -155,17 +162,17 @@ function loadAccountTokens(email) {
155
162
  }
156
163
  function saveAccountMetadata(email, metadata) {
157
164
  ensureAccountDir(email);
158
- const path = join2(getAccountDir(email), "metadata.json");
165
+ const path = join3(getAccountDir(email), "metadata.json");
159
166
  debug("accounts-storage", `Saving metadata for ${email}`);
160
167
  writeFileSync(path, JSON.stringify(metadata, null, 2), { mode: 384 });
161
168
  }
162
169
  function loadAccountMetadata(email) {
163
- const path = join2(getAccountDir(email), "metadata.json");
170
+ const path = join3(getAccountDir(email), "metadata.json");
164
171
  if (!existsSync(path)) {
165
172
  return null;
166
173
  }
167
174
  try {
168
- const content = readFileSync(path, "utf-8");
175
+ const content = readFileSync2(path, "utf-8");
169
176
  return JSON.parse(content);
170
177
  } catch (err) {
171
178
  debug("accounts-storage", `Failed to parse metadata for ${email}`, err);
@@ -181,17 +188,17 @@ function updateLastUsed(email) {
181
188
  }
182
189
  function saveAccountCache(email, cache) {
183
190
  ensureAccountDir(email);
184
- const path = join2(getAccountDir(email), "cache.json");
191
+ const path = join3(getAccountDir(email), "cache.json");
185
192
  debug("accounts-storage", `Saving cache for ${email}`);
186
193
  writeFileSync(path, JSON.stringify(cache, null, 2));
187
194
  }
188
195
  function loadAccountCache(email) {
189
- const path = join2(getAccountDir(email), "cache.json");
196
+ const path = join3(getAccountDir(email), "cache.json");
190
197
  if (!existsSync(path)) {
191
198
  return null;
192
199
  }
193
200
  try {
194
- const content = readFileSync(path, "utf-8");
201
+ const content = readFileSync2(path, "utf-8");
195
202
  return JSON.parse(content);
196
203
  } catch (err) {
197
204
  debug("accounts-storage", `Failed to parse cache for ${email}`, err);
@@ -215,8 +222,8 @@ function deleteAccount(email) {
215
222
  }
216
223
 
217
224
  // src/accounts/config.ts
218
- import { existsSync as existsSync2, readFileSync as readFileSync2, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
219
- import { dirname } from "path";
225
+ import { existsSync as existsSync2, readFileSync as readFileSync3, writeFileSync as writeFileSync2, mkdirSync as mkdirSync2 } from "fs";
226
+ import { dirname as dirname2 } from "path";
220
227
  function loadConfig() {
221
228
  const path = getGlobalConfigPath();
222
229
  if (!existsSync2(path)) {
@@ -224,7 +231,7 @@ function loadConfig() {
224
231
  return { ...DEFAULT_CONFIG };
225
232
  }
226
233
  try {
227
- const content = readFileSync2(path, "utf-8");
234
+ const content = readFileSync3(path, "utf-8");
228
235
  const config = JSON.parse(content);
229
236
  return {
230
237
  ...DEFAULT_CONFIG,
@@ -241,7 +248,7 @@ function loadConfig() {
241
248
  }
242
249
  function saveConfig(config) {
243
250
  const path = getGlobalConfigPath();
244
- const dir = dirname(path);
251
+ const dir = dirname2(path);
245
252
  if (!existsSync2(dir)) {
246
253
  mkdirSync2(dir, { recursive: true });
247
254
  }
@@ -858,13 +865,13 @@ async function refreshAccessToken(refreshToken) {
858
865
  }
859
866
 
860
867
  // src/google/storage.ts
861
- import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync3, writeFileSync as writeFileSync3, unlinkSync } from "fs";
862
- import { dirname as dirname2 } from "path";
868
+ import { existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync4, writeFileSync as writeFileSync3, unlinkSync } from "fs";
869
+ import { dirname as dirname3 } from "path";
863
870
  function saveTokens(tokens) {
864
871
  const email = tokens.email;
865
872
  if (!email) {
866
873
  const path = getTokensPath();
867
- const dir = dirname2(path);
874
+ const dir = dirname3(path);
868
875
  debug("storage", `Saving tokens to legacy path ${path}`);
869
876
  if (!existsSync3(dir)) {
870
877
  mkdirSync3(dir, { recursive: true });
@@ -894,7 +901,7 @@ function loadTokens() {
894
901
  return null;
895
902
  }
896
903
  try {
897
- const content = readFileSync3(legacyPath, "utf-8");
904
+ const content = readFileSync4(legacyPath, "utf-8");
898
905
  const tokens = JSON.parse(content);
899
906
  debug("storage", "Tokens loaded successfully from legacy path");
900
907
  return tokens;
@@ -3152,14 +3159,14 @@ function getDefaultConfig() {
3152
3159
  }
3153
3160
 
3154
3161
  // src/wakeup/storage.ts
3155
- import { join as join3 } from "path";
3156
- import { readFileSync as readFileSync4, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
3162
+ import { join as join4 } from "path";
3163
+ import { readFileSync as readFileSync5, writeFileSync as writeFileSync4, existsSync as existsSync4, mkdirSync as mkdirSync4 } from "fs";
3157
3164
  var WAKEUP_DIR_NAME = "wakeup";
3158
3165
  var CONFIG_FILE_NAME = "config.json";
3159
3166
  var HISTORY_FILE_NAME = "history.json";
3160
3167
  var MAX_HISTORY_ENTRIES = 100;
3161
3168
  function getWakeupDir() {
3162
- return join3(getConfigDir(), WAKEUP_DIR_NAME);
3169
+ return join4(getConfigDir(), WAKEUP_DIR_NAME);
3163
3170
  }
3164
3171
  function ensureWakeupDir() {
3165
3172
  const dir = getWakeupDir();
@@ -3169,10 +3176,10 @@ function ensureWakeupDir() {
3169
3176
  }
3170
3177
  }
3171
3178
  function readJsonFile(filename, defaultValue) {
3172
- const filepath = join3(getWakeupDir(), filename);
3179
+ const filepath = join4(getWakeupDir(), filename);
3173
3180
  try {
3174
3181
  if (existsSync4(filepath)) {
3175
- const content = readFileSync4(filepath, "utf-8");
3182
+ const content = readFileSync5(filepath, "utf-8");
3176
3183
  return JSON.parse(content);
3177
3184
  }
3178
3185
  } catch (err) {
@@ -3182,7 +3189,7 @@ function readJsonFile(filename, defaultValue) {
3182
3189
  }
3183
3190
  function writeJsonFile(filename, data) {
3184
3191
  ensureWakeupDir();
3185
- const filepath = join3(getWakeupDir(), filename);
3192
+ const filepath = join4(getWakeupDir(), filename);
3186
3193
  try {
3187
3194
  writeFileSync4(filepath, JSON.stringify(data, null, 2), "utf-8");
3188
3195
  debug("wakeup-storage", `Wrote ${filename}`);
@@ -3419,26 +3426,46 @@ import { execSync, exec as exec3 } from "child_process";
3419
3426
  import { promisify as promisify3 } from "util";
3420
3427
  var execAsync3 = promisify3(exec3);
3421
3428
  var CRON_COMMENT_MARKER = "antigravity-usage-wakeup";
3422
- function getBinaryPath() {
3429
+ function getBinDirectories() {
3430
+ const dirs = /* @__PURE__ */ new Set();
3431
+ try {
3432
+ const nodePath = process.execPath;
3433
+ const nodeDir = nodePath.substring(0, nodePath.lastIndexOf("/"));
3434
+ if (nodeDir) {
3435
+ dirs.add(nodeDir);
3436
+ debug("cron-installer", `Found node bin dir: ${nodeDir}`);
3437
+ }
3438
+ } catch {
3439
+ debug("cron-installer", "Could not determine node bin directory");
3440
+ }
3423
3441
  try {
3424
- const path = execSync("which antigravity-usage", {
3442
+ const npmBin = execSync("npm bin -g", {
3425
3443
  encoding: "utf-8",
3426
3444
  stdio: ["pipe", "pipe", "pipe"]
3427
3445
  }).trim();
3428
- if (path) {
3429
- debug("cron-installer", `Found binary at: ${path}`);
3430
- return path;
3446
+ if (npmBin) {
3447
+ dirs.add(npmBin);
3448
+ debug("cron-installer", `Found npm bin dir: ${npmBin}`);
3431
3449
  }
3432
3450
  } catch {
3433
- debug("cron-installer", "Could not find antigravity-usage via which");
3451
+ debug("cron-installer", "Could not determine npm bin directory");
3434
3452
  }
3435
- if (process.argv[1]) {
3436
- const nodePath = process.execPath;
3437
- const scriptPath = process.argv[1];
3438
- debug("cron-installer", `Using node + script: ${nodePath} ${scriptPath}`);
3439
- return `${nodePath} ${scriptPath}`;
3453
+ if (process.env.PATH) {
3454
+ const userPaths = process.env.PATH.split(":").filter((p) => {
3455
+ return p.includes("node") || p.includes("npm") || p.includes("nvm") || p.includes(".local") || p === "/usr/local/bin" || p === "/opt/homebrew/bin";
3456
+ });
3457
+ userPaths.forEach((p) => {
3458
+ if (p) {
3459
+ dirs.add(p);
3460
+ debug("cron-installer", `Added user PATH: ${p}`);
3461
+ }
3462
+ });
3440
3463
  }
3441
- throw new Error("Could not determine binary path for cron job");
3464
+ dirs.add("/usr/local/bin");
3465
+ dirs.add("/usr/bin");
3466
+ dirs.add("/bin");
3467
+ dirs.add("/opt/homebrew/bin");
3468
+ return Array.from(dirs);
3442
3469
  }
3443
3470
  async function loadCrontab() {
3444
3471
  try {
@@ -3484,14 +3511,19 @@ async function installCronJob(cronExpression) {
3484
3511
  };
3485
3512
  }
3486
3513
  try {
3487
- const binaryPath = getBinaryPath();
3514
+ const binDirs = getBinDirectories();
3515
+ const pathValue = binDirs.join(":");
3488
3516
  const lines = await loadCrontab();
3489
3517
  const filteredLines = removeWakeupEntries(lines);
3490
- const command = `${binaryPath} wakeup trigger --scheduled`;
3491
- const cronLine = `${cronExpression} ${command} # ${CRON_COMMENT_MARKER}`;
3518
+ const hasPath = filteredLines.some((line) => line.startsWith("PATH="));
3519
+ if (!hasPath) {
3520
+ filteredLines.unshift(`PATH=${pathValue}`);
3521
+ }
3522
+ const cronLine = `${cronExpression} antigravity-usage wakeup trigger --scheduled # ${CRON_COMMENT_MARKER}`;
3492
3523
  filteredLines.push(cronLine);
3493
3524
  await saveCrontab(filteredLines);
3494
3525
  debug("cron-installer", `Installed cron job: ${cronLine}`);
3526
+ debug("cron-installer", `Using PATH: ${pathValue}`);
3495
3527
  return {
3496
3528
  success: true,
3497
3529
  cronExpression
@@ -3499,11 +3531,10 @@ async function installCronJob(cronExpression) {
3499
3531
  } catch (err) {
3500
3532
  const errorMessage = err instanceof Error ? err.message : String(err);
3501
3533
  debug("cron-installer", `Failed to install cron job: ${errorMessage}`);
3502
- const binaryPath = tryGetBinaryPath();
3503
3534
  return {
3504
3535
  success: false,
3505
3536
  error: errorMessage,
3506
- manualInstructions: getManualInstructions(cronExpression, binaryPath)
3537
+ manualInstructions: getManualInstructions(cronExpression)
3507
3538
  };
3508
3539
  }
3509
3540
  }
@@ -3548,21 +3579,17 @@ async function getCronStatus() {
3548
3579
  return { installed: false };
3549
3580
  }
3550
3581
  }
3551
- function tryGetBinaryPath() {
3552
- try {
3553
- return getBinaryPath();
3554
- } catch {
3555
- return "antigravity-usage";
3556
- }
3557
- }
3558
- function getManualInstructions(cronExpression, binaryPath) {
3582
+ function getManualInstructions(cronExpression) {
3583
+ const binDirs = getBinDirectories();
3584
+ const pathValue = binDirs.join(":");
3559
3585
  return `
3560
3586
  Failed to automatically install cron job. Please add manually:
3561
3587
 
3562
3588
  1. Open terminal and run: crontab -e
3563
3589
 
3564
- 2. Add this line at the end:
3565
- ${cronExpression} ${binaryPath} wakeup trigger --scheduled # ${CRON_COMMENT_MARKER}
3590
+ 2. Add these lines:
3591
+ PATH=${pathValue}
3592
+ ${cronExpression} antigravity-usage wakeup trigger --scheduled # ${CRON_COMMENT_MARKER}
3566
3593
 
3567
3594
  3. Save and exit the editor
3568
3595