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 +12 -4
- package/dist/index.js +90 -63
- package/dist/index.js.map +1 -1
- package/package.json +2 -1
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
|
|
111
|
-
antigravity-usage --all
|
|
112
|
-
antigravity-usage --method local
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
|
79
|
+
return join2(process.env.APPDATA || join2(home, "AppData", "Roaming"), "antigravity-usage");
|
|
73
80
|
case "macos":
|
|
74
|
-
return
|
|
81
|
+
return join2(home, "Library", "Application Support", "antigravity-usage");
|
|
75
82
|
case "linux":
|
|
76
83
|
default:
|
|
77
|
-
return
|
|
84
|
+
return join2(process.env.XDG_CONFIG_HOME || join2(home, ".config"), "antigravity-usage");
|
|
78
85
|
}
|
|
79
86
|
}
|
|
80
87
|
function getTokensPath() {
|
|
81
|
-
return
|
|
88
|
+
return join2(getConfigDir(), "tokens.json");
|
|
82
89
|
}
|
|
83
90
|
function getAccountsDir() {
|
|
84
|
-
return
|
|
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
|
|
95
|
+
return join2(getAccountsDir(), safeName);
|
|
89
96
|
}
|
|
90
97
|
function getGlobalConfigPath() {
|
|
91
|
-
return
|
|
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(
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
|
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 =
|
|
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 =
|
|
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
|
|
862
|
-
import { dirname as
|
|
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 =
|
|
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 =
|
|
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
|
|
3156
|
-
import { readFileSync as
|
|
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
|
|
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 =
|
|
3179
|
+
const filepath = join4(getWakeupDir(), filename);
|
|
3173
3180
|
try {
|
|
3174
3181
|
if (existsSync4(filepath)) {
|
|
3175
|
-
const content =
|
|
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 =
|
|
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
|
|
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
|
|
3442
|
+
const npmBin = execSync("npm bin -g", {
|
|
3425
3443
|
encoding: "utf-8",
|
|
3426
3444
|
stdio: ["pipe", "pipe", "pipe"]
|
|
3427
3445
|
}).trim();
|
|
3428
|
-
if (
|
|
3429
|
-
|
|
3430
|
-
|
|
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
|
|
3451
|
+
debug("cron-installer", "Could not determine npm bin directory");
|
|
3434
3452
|
}
|
|
3435
|
-
if (process.
|
|
3436
|
-
const
|
|
3437
|
-
|
|
3438
|
-
|
|
3439
|
-
|
|
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
|
-
|
|
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
|
|
3514
|
+
const binDirs = getBinDirectories();
|
|
3515
|
+
const pathValue = binDirs.join(":");
|
|
3488
3516
|
const lines = await loadCrontab();
|
|
3489
3517
|
const filteredLines = removeWakeupEntries(lines);
|
|
3490
|
-
const
|
|
3491
|
-
|
|
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
|
|
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
|
|
3552
|
-
|
|
3553
|
-
|
|
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
|
|
3565
|
-
|
|
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
|
|