antigravity-auth 1.6.0 → 1.7.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 +79 -41
- package/dist/cli.js +2868 -0
- package/dist/handler.js +25119 -0
- package/dist/index.js +25110 -5
- package/package.json +66 -54
- package/dist/antigravity/oauth.d.ts +0 -30
- package/dist/antigravity/oauth.js +0 -170
- package/dist/claude/login.d.ts +0 -7
- package/dist/claude/login.js +0 -480
- package/dist/claude/menu-helpers.d.ts +0 -22
- package/dist/claude/menu-helpers.js +0 -281
- package/dist/claude/proxy-manager.d.ts +0 -11
- package/dist/claude/proxy-manager.js +0 -129
- package/dist/claude/proxy.d.ts +0 -1
- package/dist/claude/proxy.js +0 -733
- package/dist/constants.d.ts +0 -138
- package/dist/constants.js +0 -216
- package/dist/hooks/auto-update-checker/cache.d.ts +0 -2
- package/dist/hooks/auto-update-checker/cache.js +0 -70
- package/dist/hooks/auto-update-checker/checker.d.ts +0 -15
- package/dist/hooks/auto-update-checker/checker.js +0 -233
- package/dist/hooks/auto-update-checker/constants.d.ts +0 -8
- package/dist/hooks/auto-update-checker/constants.js +0 -22
- package/dist/hooks/auto-update-checker/index.d.ts +0 -33
- package/dist/hooks/auto-update-checker/index.js +0 -121
- package/dist/hooks/auto-update-checker/logging.d.ts +0 -2
- package/dist/hooks/auto-update-checker/logging.js +0 -8
- package/dist/hooks/auto-update-checker/types.d.ts +0 -24
- package/dist/hooks/auto-update-checker/types.js +0 -1
- package/dist/index.d.ts +0 -6
- package/dist/opencode/hooks/auto-update-checker/cache.d.ts +0 -2
- package/dist/opencode/hooks/auto-update-checker/cache.js +0 -70
- package/dist/opencode/hooks/auto-update-checker/checker.d.ts +0 -15
- package/dist/opencode/hooks/auto-update-checker/checker.js +0 -233
- package/dist/opencode/hooks/auto-update-checker/constants.d.ts +0 -8
- package/dist/opencode/hooks/auto-update-checker/constants.js +0 -22
- package/dist/opencode/hooks/auto-update-checker/index.d.ts +0 -33
- package/dist/opencode/hooks/auto-update-checker/index.js +0 -121
- package/dist/opencode/hooks/auto-update-checker/logging.d.ts +0 -2
- package/dist/opencode/hooks/auto-update-checker/logging.js +0 -8
- package/dist/opencode/hooks/auto-update-checker/types.d.ts +0 -24
- package/dist/opencode/hooks/auto-update-checker/types.js +0 -1
- package/dist/opencode/plugin.d.ts +0 -29
- package/dist/opencode/plugin.js +0 -2954
- package/dist/plugin/accounts.d.ts +0 -173
- package/dist/plugin/accounts.js +0 -966
- package/dist/plugin/auth.d.ts +0 -20
- package/dist/plugin/auth.js +0 -44
- package/dist/plugin/cache/index.d.ts +0 -4
- package/dist/plugin/cache/index.js +0 -4
- package/dist/plugin/cache/signature-cache.d.ts +0 -110
- package/dist/plugin/cache/signature-cache.js +0 -347
- package/dist/plugin/cache.d.ts +0 -43
- package/dist/plugin/cache.js +0 -180
- package/dist/plugin/cli.d.ts +0 -26
- package/dist/plugin/cli.js +0 -126
- package/dist/plugin/config/index.d.ts +0 -15
- package/dist/plugin/config/index.js +0 -15
- package/dist/plugin/config/loader.d.ts +0 -38
- package/dist/plugin/config/loader.js +0 -150
- package/dist/plugin/config/models.d.ts +0 -26
- package/dist/plugin/config/models.js +0 -95
- package/dist/plugin/config/schema.d.ts +0 -144
- package/dist/plugin/config/schema.js +0 -458
- package/dist/plugin/config/updater.d.ts +0 -76
- package/dist/plugin/config/updater.js +0 -205
- package/dist/plugin/core/streaming/index.d.ts +0 -2
- package/dist/plugin/core/streaming/index.js +0 -2
- package/dist/plugin/core/streaming/transformer.d.ts +0 -9
- package/dist/plugin/core/streaming/transformer.js +0 -301
- package/dist/plugin/core/streaming/types.d.ts +0 -28
- package/dist/plugin/core/streaming/types.js +0 -1
- package/dist/plugin/debug.d.ts +0 -93
- package/dist/plugin/debug.js +0 -375
- package/dist/plugin/errors.d.ts +0 -27
- package/dist/plugin/errors.js +0 -41
- package/dist/plugin/fingerprint.d.ts +0 -69
- package/dist/plugin/fingerprint.js +0 -137
- package/dist/plugin/image-saver.d.ts +0 -24
- package/dist/plugin/image-saver.js +0 -78
- package/dist/plugin/logger.d.ts +0 -35
- package/dist/plugin/logger.js +0 -67
- package/dist/plugin/logging-utils.d.ts +0 -22
- package/dist/plugin/logging-utils.js +0 -91
- package/dist/plugin/project.d.ts +0 -32
- package/dist/plugin/project.js +0 -229
- package/dist/plugin/quota.d.ts +0 -34
- package/dist/plugin/quota.js +0 -261
- package/dist/plugin/recovery/constants.d.ts +0 -21
- package/dist/plugin/recovery/constants.js +0 -42
- package/dist/plugin/recovery/index.d.ts +0 -11
- package/dist/plugin/recovery/index.js +0 -11
- package/dist/plugin/recovery/storage.d.ts +0 -23
- package/dist/plugin/recovery/storage.js +0 -340
- package/dist/plugin/recovery/types.d.ts +0 -115
- package/dist/plugin/recovery/types.js +0 -6
- package/dist/plugin/recovery.d.ts +0 -60
- package/dist/plugin/recovery.js +0 -360
- package/dist/plugin/refresh-queue.d.ts +0 -99
- package/dist/plugin/refresh-queue.js +0 -235
- package/dist/plugin/request-helpers.d.ts +0 -281
- package/dist/plugin/request-helpers.js +0 -2200
- package/dist/plugin/request.d.ts +0 -110
- package/dist/plugin/request.js +0 -1489
- package/dist/plugin/rotation.d.ts +0 -182
- package/dist/plugin/rotation.js +0 -364
- package/dist/plugin/search.d.ts +0 -31
- package/dist/plugin/search.js +0 -185
- package/dist/plugin/server.d.ts +0 -22
- package/dist/plugin/server.js +0 -306
- package/dist/plugin/storage.d.ts +0 -136
- package/dist/plugin/storage.js +0 -599
- package/dist/plugin/stores/signature-store.d.ts +0 -4
- package/dist/plugin/stores/signature-store.js +0 -24
- package/dist/plugin/thinking-recovery.d.ts +0 -89
- package/dist/plugin/thinking-recovery.js +0 -289
- package/dist/plugin/token.d.ts +0 -18
- package/dist/plugin/token.js +0 -127
- package/dist/plugin/transform/claude.d.ts +0 -79
- package/dist/plugin/transform/claude.js +0 -256
- package/dist/plugin/transform/cross-model-sanitizer.d.ts +0 -34
- package/dist/plugin/transform/cross-model-sanitizer.js +0 -224
- package/dist/plugin/transform/gemini.d.ts +0 -132
- package/dist/plugin/transform/gemini.js +0 -659
- package/dist/plugin/transform/index.d.ts +0 -14
- package/dist/plugin/transform/index.js +0 -9
- package/dist/plugin/transform/model-resolver.d.ts +0 -98
- package/dist/plugin/transform/model-resolver.js +0 -320
- package/dist/plugin/transform/types.d.ts +0 -110
- package/dist/plugin/transform/types.js +0 -1
- package/dist/plugin/types.d.ts +0 -95
- package/dist/plugin/types.js +0 -1
- package/dist/plugin/ui/ansi.d.ts +0 -31
- package/dist/plugin/ui/ansi.js +0 -45
- package/dist/plugin/ui/auth-menu.d.ts +0 -47
- package/dist/plugin/ui/auth-menu.js +0 -199
- package/dist/plugin/ui/confirm.d.ts +0 -1
- package/dist/plugin/ui/confirm.js +0 -14
- package/dist/plugin/ui/select.d.ts +0 -22
- package/dist/plugin/ui/select.js +0 -243
- package/dist/plugin/version.d.ts +0 -18
- package/dist/plugin/version.js +0 -79
- package/dist/src/antigravity/oauth.d.ts +0 -30
- package/dist/src/antigravity/oauth.js +0 -170
- package/dist/src/constants.d.ts +0 -138
- package/dist/src/constants.js +0 -216
- package/dist/src/hooks/auto-update-checker/cache.d.ts +0 -2
- package/dist/src/hooks/auto-update-checker/cache.js +0 -70
- package/dist/src/hooks/auto-update-checker/checker.d.ts +0 -15
- package/dist/src/hooks/auto-update-checker/checker.js +0 -233
- package/dist/src/hooks/auto-update-checker/constants.d.ts +0 -8
- package/dist/src/hooks/auto-update-checker/constants.js +0 -22
- package/dist/src/hooks/auto-update-checker/index.d.ts +0 -33
- package/dist/src/hooks/auto-update-checker/index.js +0 -121
- package/dist/src/hooks/auto-update-checker/logging.d.ts +0 -2
- package/dist/src/hooks/auto-update-checker/logging.js +0 -8
- package/dist/src/hooks/auto-update-checker/types.d.ts +0 -24
- package/dist/src/hooks/auto-update-checker/types.js +0 -1
- package/dist/src/index.d.ts +0 -6
- package/dist/src/index.js +0 -5
- package/dist/src/plugin/accounts.d.ts +0 -173
- package/dist/src/plugin/accounts.js +0 -966
- package/dist/src/plugin/auth.d.ts +0 -20
- package/dist/src/plugin/auth.js +0 -44
- package/dist/src/plugin/cache/index.d.ts +0 -4
- package/dist/src/plugin/cache/index.js +0 -4
- package/dist/src/plugin/cache/signature-cache.d.ts +0 -110
- package/dist/src/plugin/cache/signature-cache.js +0 -347
- package/dist/src/plugin/cache.d.ts +0 -43
- package/dist/src/plugin/cache.js +0 -180
- package/dist/src/plugin/cli.d.ts +0 -26
- package/dist/src/plugin/cli.js +0 -126
- package/dist/src/plugin/config/index.d.ts +0 -15
- package/dist/src/plugin/config/index.js +0 -15
- package/dist/src/plugin/config/loader.d.ts +0 -38
- package/dist/src/plugin/config/loader.js +0 -150
- package/dist/src/plugin/config/models.d.ts +0 -26
- package/dist/src/plugin/config/models.js +0 -95
- package/dist/src/plugin/config/schema.d.ts +0 -144
- package/dist/src/plugin/config/schema.js +0 -458
- package/dist/src/plugin/config/updater.d.ts +0 -76
- package/dist/src/plugin/config/updater.js +0 -205
- package/dist/src/plugin/core/streaming/index.d.ts +0 -2
- package/dist/src/plugin/core/streaming/index.js +0 -2
- package/dist/src/plugin/core/streaming/transformer.d.ts +0 -9
- package/dist/src/plugin/core/streaming/transformer.js +0 -301
- package/dist/src/plugin/core/streaming/types.d.ts +0 -28
- package/dist/src/plugin/core/streaming/types.js +0 -1
- package/dist/src/plugin/debug.d.ts +0 -93
- package/dist/src/plugin/debug.js +0 -375
- package/dist/src/plugin/errors.d.ts +0 -27
- package/dist/src/plugin/errors.js +0 -41
- package/dist/src/plugin/fingerprint.d.ts +0 -69
- package/dist/src/plugin/fingerprint.js +0 -137
- package/dist/src/plugin/image-saver.d.ts +0 -24
- package/dist/src/plugin/image-saver.js +0 -78
- package/dist/src/plugin/logger.d.ts +0 -35
- package/dist/src/plugin/logger.js +0 -67
- package/dist/src/plugin/logging-utils.d.ts +0 -22
- package/dist/src/plugin/logging-utils.js +0 -91
- package/dist/src/plugin/project.d.ts +0 -32
- package/dist/src/plugin/project.js +0 -229
- package/dist/src/plugin/quota.d.ts +0 -34
- package/dist/src/plugin/quota.js +0 -261
- package/dist/src/plugin/recovery/constants.d.ts +0 -21
- package/dist/src/plugin/recovery/constants.js +0 -42
- package/dist/src/plugin/recovery/index.d.ts +0 -11
- package/dist/src/plugin/recovery/index.js +0 -11
- package/dist/src/plugin/recovery/storage.d.ts +0 -23
- package/dist/src/plugin/recovery/storage.js +0 -340
- package/dist/src/plugin/recovery/types.d.ts +0 -115
- package/dist/src/plugin/recovery/types.js +0 -6
- package/dist/src/plugin/recovery.d.ts +0 -60
- package/dist/src/plugin/recovery.js +0 -360
- package/dist/src/plugin/refresh-queue.d.ts +0 -99
- package/dist/src/plugin/refresh-queue.js +0 -235
- package/dist/src/plugin/request-helpers.d.ts +0 -281
- package/dist/src/plugin/request-helpers.js +0 -2200
- package/dist/src/plugin/request.d.ts +0 -110
- package/dist/src/plugin/request.js +0 -1489
- package/dist/src/plugin/rotation.d.ts +0 -182
- package/dist/src/plugin/rotation.js +0 -364
- package/dist/src/plugin/search.d.ts +0 -31
- package/dist/src/plugin/search.js +0 -185
- package/dist/src/plugin/server.d.ts +0 -22
- package/dist/src/plugin/server.js +0 -306
- package/dist/src/plugin/storage.d.ts +0 -136
- package/dist/src/plugin/storage.js +0 -599
- package/dist/src/plugin/stores/signature-store.d.ts +0 -4
- package/dist/src/plugin/stores/signature-store.js +0 -24
- package/dist/src/plugin/thinking-recovery.d.ts +0 -89
- package/dist/src/plugin/thinking-recovery.js +0 -289
- package/dist/src/plugin/token.d.ts +0 -18
- package/dist/src/plugin/token.js +0 -127
- package/dist/src/plugin/transform/claude.d.ts +0 -79
- package/dist/src/plugin/transform/claude.js +0 -256
- package/dist/src/plugin/transform/cross-model-sanitizer.d.ts +0 -34
- package/dist/src/plugin/transform/cross-model-sanitizer.js +0 -224
- package/dist/src/plugin/transform/gemini.d.ts +0 -132
- package/dist/src/plugin/transform/gemini.js +0 -659
- package/dist/src/plugin/transform/index.d.ts +0 -14
- package/dist/src/plugin/transform/index.js +0 -9
- package/dist/src/plugin/transform/model-resolver.d.ts +0 -98
- package/dist/src/plugin/transform/model-resolver.js +0 -320
- package/dist/src/plugin/transform/types.d.ts +0 -110
- package/dist/src/plugin/transform/types.js +0 -1
- package/dist/src/plugin/types.d.ts +0 -95
- package/dist/src/plugin/types.js +0 -1
- package/dist/src/plugin/ui/ansi.d.ts +0 -31
- package/dist/src/plugin/ui/ansi.js +0 -45
- package/dist/src/plugin/ui/auth-menu.d.ts +0 -47
- package/dist/src/plugin/ui/auth-menu.js +0 -199
- package/dist/src/plugin/ui/confirm.d.ts +0 -1
- package/dist/src/plugin/ui/confirm.js +0 -14
- package/dist/src/plugin/ui/select.d.ts +0 -22
- package/dist/src/plugin/ui/select.js +0 -243
- package/dist/src/plugin/version.d.ts +0 -18
- package/dist/src/plugin/version.js +0 -79
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* ANSI escape codes and key parsing for interactive CLI menus.
|
|
3
|
-
* Works cross-platform (Windows/Mac/Linux).
|
|
4
|
-
*/
|
|
5
|
-
export const ANSI = {
|
|
6
|
-
hide: '\x1b[?25l',
|
|
7
|
-
show: '\x1b[?25h',
|
|
8
|
-
up: (n = 1) => `\x1b[${n}A`,
|
|
9
|
-
down: (n = 1) => `\x1b[${n}B`,
|
|
10
|
-
clearLine: '\x1b[2K',
|
|
11
|
-
clearScreen: '\x1b[2J',
|
|
12
|
-
moveTo: (row, col) => `\x1b[${row};${col}H`,
|
|
13
|
-
cyan: '\x1b[36m',
|
|
14
|
-
green: '\x1b[32m',
|
|
15
|
-
red: '\x1b[31m',
|
|
16
|
-
yellow: '\x1b[33m',
|
|
17
|
-
dim: '\x1b[2m',
|
|
18
|
-
bold: '\x1b[1m',
|
|
19
|
-
reset: '\x1b[0m',
|
|
20
|
-
inverse: '\x1b[7m',
|
|
21
|
-
};
|
|
22
|
-
/**
|
|
23
|
-
* Parse raw keyboard input buffer into a key action.
|
|
24
|
-
* Handles Windows/Mac/Linux differences in arrow key sequences.
|
|
25
|
-
*/
|
|
26
|
-
export function parseKey(data) {
|
|
27
|
-
const s = data.toString();
|
|
28
|
-
if (s === '\x1b[A' || s === '\x1bOA')
|
|
29
|
-
return 'up';
|
|
30
|
-
if (s === '\x1b[B' || s === '\x1bOB')
|
|
31
|
-
return 'down';
|
|
32
|
-
if (s === '\r' || s === '\n')
|
|
33
|
-
return 'enter';
|
|
34
|
-
if (s === '\x03')
|
|
35
|
-
return 'escape';
|
|
36
|
-
if (s === '\x1b')
|
|
37
|
-
return 'escape-start';
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
/**
|
|
41
|
-
* Check if the terminal supports interactive input.
|
|
42
|
-
*/
|
|
43
|
-
export function isTTY() {
|
|
44
|
-
return Boolean(process.stdin.isTTY);
|
|
45
|
-
}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import { isTTY } from './ansi';
|
|
2
|
-
export type AccountStatus = 'active' | 'rate-limited' | 'expired' | 'verification-required' | 'unknown';
|
|
3
|
-
export interface AccountInfo {
|
|
4
|
-
email?: string;
|
|
5
|
-
index: number;
|
|
6
|
-
addedAt?: number;
|
|
7
|
-
lastUsed?: number;
|
|
8
|
-
status?: AccountStatus;
|
|
9
|
-
isCurrentAccount?: boolean;
|
|
10
|
-
enabled?: boolean;
|
|
11
|
-
}
|
|
12
|
-
export type AuthMenuAction = {
|
|
13
|
-
type: 'add';
|
|
14
|
-
} | {
|
|
15
|
-
type: 'select-account';
|
|
16
|
-
account: AccountInfo;
|
|
17
|
-
} | {
|
|
18
|
-
type: 'delete-all';
|
|
19
|
-
} | {
|
|
20
|
-
type: 'check';
|
|
21
|
-
} | {
|
|
22
|
-
type: 'verify';
|
|
23
|
-
} | {
|
|
24
|
-
type: 'verify-all';
|
|
25
|
-
} | {
|
|
26
|
-
type: 'configure-models';
|
|
27
|
-
} | {
|
|
28
|
-
type: 'proxies';
|
|
29
|
-
} | {
|
|
30
|
-
type: 'cancel';
|
|
31
|
-
};
|
|
32
|
-
export type AccountAction = 'back' | 'delete' | 'refresh' | 'toggle' | 'verify' | 'proxies' | 'cancel';
|
|
33
|
-
export declare function showAuthMenu(accounts: AccountInfo[]): Promise<AuthMenuAction>;
|
|
34
|
-
export declare function showAccountDetails(account: AccountInfo): Promise<AccountAction>;
|
|
35
|
-
export { isTTY };
|
|
36
|
-
export type ProxyMenuAction = {
|
|
37
|
-
action: 'add';
|
|
38
|
-
} | {
|
|
39
|
-
action: 'remove';
|
|
40
|
-
index: number;
|
|
41
|
-
} | {
|
|
42
|
-
action: 'clear';
|
|
43
|
-
} | {
|
|
44
|
-
action: 'back';
|
|
45
|
-
};
|
|
46
|
-
export declare function showProxyMenu(accountLabel: string, currentProxies: string[]): Promise<ProxyMenuAction>;
|
|
47
|
-
export declare function promptProxyUrl(): Promise<string | undefined>;
|
|
@@ -1,199 +0,0 @@
|
|
|
1
|
-
import { ANSI, isTTY } from './ansi';
|
|
2
|
-
import { select } from './select';
|
|
3
|
-
import { confirm } from './confirm';
|
|
4
|
-
function formatRelativeTime(timestamp) {
|
|
5
|
-
if (!timestamp)
|
|
6
|
-
return 'never';
|
|
7
|
-
const days = Math.floor((Date.now() - timestamp) / 86400000);
|
|
8
|
-
if (days === 0)
|
|
9
|
-
return 'today';
|
|
10
|
-
if (days === 1)
|
|
11
|
-
return 'yesterday';
|
|
12
|
-
if (days < 7)
|
|
13
|
-
return `${days}d ago`;
|
|
14
|
-
if (days < 30)
|
|
15
|
-
return `${Math.floor(days / 7)}w ago`;
|
|
16
|
-
return new Date(timestamp).toLocaleDateString();
|
|
17
|
-
}
|
|
18
|
-
function formatDate(timestamp) {
|
|
19
|
-
if (!timestamp)
|
|
20
|
-
return 'unknown';
|
|
21
|
-
return new Date(timestamp).toLocaleDateString();
|
|
22
|
-
}
|
|
23
|
-
function getStatusBadge(status) {
|
|
24
|
-
switch (status) {
|
|
25
|
-
case 'active': return `${ANSI.green}[active]${ANSI.reset}`;
|
|
26
|
-
case 'rate-limited': return `${ANSI.yellow}[rate-limited]${ANSI.reset}`;
|
|
27
|
-
case 'expired': return `${ANSI.red}[expired]${ANSI.reset}`;
|
|
28
|
-
case 'verification-required': return `${ANSI.red}[needs verification]${ANSI.reset}`;
|
|
29
|
-
default: return '';
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
export async function showAuthMenu(accounts) {
|
|
33
|
-
const items = [
|
|
34
|
-
{ label: 'Actions', value: { type: 'cancel' }, kind: 'heading' },
|
|
35
|
-
{ label: 'Add account', value: { type: 'add' }, color: 'cyan' },
|
|
36
|
-
{ label: 'Check quotas', value: { type: 'check' }, color: 'cyan' },
|
|
37
|
-
{ label: 'Verify one account', value: { type: 'verify' }, color: 'cyan' },
|
|
38
|
-
{ label: 'Verify all accounts', value: { type: 'verify-all' }, color: 'cyan' },
|
|
39
|
-
{ label: 'Configure models in opencode.json', value: { type: 'configure-models' }, color: 'cyan' },
|
|
40
|
-
{ label: 'Manage proxies', value: { type: 'proxies' }, color: 'cyan' },
|
|
41
|
-
{ label: '', value: { type: 'cancel' }, separator: true },
|
|
42
|
-
{ label: 'Accounts', value: { type: 'cancel' }, kind: 'heading' },
|
|
43
|
-
...accounts.map(account => {
|
|
44
|
-
const statusBadge = getStatusBadge(account.status);
|
|
45
|
-
const currentBadge = account.isCurrentAccount ? ` ${ANSI.cyan}[current]${ANSI.reset}` : '';
|
|
46
|
-
const disabledBadge = account.enabled === false ? ` ${ANSI.red}[disabled]${ANSI.reset}` : '';
|
|
47
|
-
const baseLabel = account.email || `Account ${account.index + 1}`;
|
|
48
|
-
const numbered = `${account.index + 1}. ${baseLabel}`;
|
|
49
|
-
const fullLabel = `${numbered}${currentBadge}${statusBadge ? ' ' + statusBadge : ''}${disabledBadge}`;
|
|
50
|
-
return {
|
|
51
|
-
label: fullLabel,
|
|
52
|
-
hint: account.lastUsed ? `used ${formatRelativeTime(account.lastUsed)}` : '',
|
|
53
|
-
value: { type: 'select-account', account },
|
|
54
|
-
};
|
|
55
|
-
}),
|
|
56
|
-
{ label: '', value: { type: 'cancel' }, separator: true },
|
|
57
|
-
{ label: 'Danger zone', value: { type: 'cancel' }, kind: 'heading' },
|
|
58
|
-
{ label: 'Delete all accounts', value: { type: 'delete-all' }, color: 'red' },
|
|
59
|
-
];
|
|
60
|
-
while (true) {
|
|
61
|
-
const result = await select(items, {
|
|
62
|
-
message: 'Google accounts (Antigravity)',
|
|
63
|
-
subtitle: 'Select an action or account',
|
|
64
|
-
clearScreen: true,
|
|
65
|
-
});
|
|
66
|
-
if (!result)
|
|
67
|
-
return { type: 'cancel' };
|
|
68
|
-
if (result.type === 'delete-all') {
|
|
69
|
-
const confirmed = await confirm('Delete ALL accounts? This cannot be undone.');
|
|
70
|
-
if (!confirmed)
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
return result;
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
export async function showAccountDetails(account) {
|
|
77
|
-
const label = account.email || `Account ${account.index + 1}`;
|
|
78
|
-
const badge = getStatusBadge(account.status);
|
|
79
|
-
const disabledBadge = account.enabled === false ? ` ${ANSI.red}[disabled]${ANSI.reset}` : '';
|
|
80
|
-
const header = `${label}${badge ? ' ' + badge : ''}${disabledBadge}`;
|
|
81
|
-
const subtitleParts = [
|
|
82
|
-
`Added: ${formatDate(account.addedAt)}`,
|
|
83
|
-
`Last used: ${formatRelativeTime(account.lastUsed)}`,
|
|
84
|
-
];
|
|
85
|
-
while (true) {
|
|
86
|
-
const result = await select([
|
|
87
|
-
{ label: 'Back', value: 'back' },
|
|
88
|
-
{ label: 'Verify account access', value: 'verify', color: 'cyan' },
|
|
89
|
-
{ label: account.enabled === false ? 'Enable account' : 'Disable account', value: 'toggle', color: account.enabled === false ? 'green' : 'yellow' },
|
|
90
|
-
{ label: 'Manage proxies', value: 'proxies', color: 'cyan' },
|
|
91
|
-
{ label: 'Refresh token', value: 'refresh', color: 'cyan' },
|
|
92
|
-
{ label: 'Delete this account', value: 'delete', color: 'red' },
|
|
93
|
-
], {
|
|
94
|
-
message: header,
|
|
95
|
-
subtitle: subtitleParts.join(' | '),
|
|
96
|
-
clearScreen: true,
|
|
97
|
-
});
|
|
98
|
-
if (result === 'delete') {
|
|
99
|
-
const confirmed = await confirm(`Delete ${label}?`);
|
|
100
|
-
if (!confirmed)
|
|
101
|
-
continue;
|
|
102
|
-
}
|
|
103
|
-
if (result === 'refresh') {
|
|
104
|
-
const confirmed = await confirm(`Re-authenticate ${label}?`);
|
|
105
|
-
if (!confirmed)
|
|
106
|
-
continue;
|
|
107
|
-
}
|
|
108
|
-
return result ?? 'cancel';
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
export { isTTY };
|
|
112
|
-
async function promptProxyMenuFallback(accountLabel, currentProxies) {
|
|
113
|
-
const readline = await import('node:readline/promises');
|
|
114
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
115
|
-
try {
|
|
116
|
-
console.log(`\nManage Proxies: ${accountLabel}`);
|
|
117
|
-
if (currentProxies.length > 0) {
|
|
118
|
-
console.log(`Current proxies:`);
|
|
119
|
-
currentProxies.forEach((p, i) => console.log(` ${i + 1}. ${p}`));
|
|
120
|
-
}
|
|
121
|
-
else {
|
|
122
|
-
console.log(`No proxies configured.`);
|
|
123
|
-
}
|
|
124
|
-
while (true) {
|
|
125
|
-
const options = currentProxies.length > 0 ? '(a)dd, (r)emove <num>, (c)lear, (b)ack' : '(a)dd, (b)ack';
|
|
126
|
-
const answer = await rl.question(`Choose action ${options}: `);
|
|
127
|
-
const normalized = answer.trim().toLowerCase();
|
|
128
|
-
if (normalized === 'a' || normalized === 'add') {
|
|
129
|
-
return { action: 'add' };
|
|
130
|
-
}
|
|
131
|
-
if (normalized === 'c' || normalized === 'clear') {
|
|
132
|
-
return { action: 'clear' };
|
|
133
|
-
}
|
|
134
|
-
if (normalized === 'b' || normalized === 'back') {
|
|
135
|
-
return { action: 'back' };
|
|
136
|
-
}
|
|
137
|
-
if (normalized.startsWith('r') || normalized.startsWith('remove')) {
|
|
138
|
-
const parts = normalized.split(/\s+/);
|
|
139
|
-
const idx = parseInt(parts[1] ?? '', 10) - 1;
|
|
140
|
-
if (!isNaN(idx) && idx >= 0 && idx < currentProxies.length) {
|
|
141
|
-
return { action: 'remove', index: idx };
|
|
142
|
-
}
|
|
143
|
-
console.log(`Invalid proxy number. Use 'r 1' to remove the first proxy.`);
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
finally {
|
|
148
|
-
rl.close();
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
export async function showProxyMenu(accountLabel, currentProxies) {
|
|
152
|
-
if (!isTTY()) {
|
|
153
|
-
return promptProxyMenuFallback(accountLabel, currentProxies);
|
|
154
|
-
}
|
|
155
|
-
while (true) {
|
|
156
|
-
const items = [
|
|
157
|
-
{ label: 'Back', value: { action: 'back' } },
|
|
158
|
-
{ label: 'Add proxy URL', value: { action: 'add' }, color: 'cyan' },
|
|
159
|
-
];
|
|
160
|
-
if (currentProxies.length > 0) {
|
|
161
|
-
items.push({ label: '', value: { action: 'back' }, separator: true });
|
|
162
|
-
items.push({ label: 'Current proxies', value: { action: 'back' }, kind: 'heading' });
|
|
163
|
-
currentProxies.forEach((proxy, idx) => {
|
|
164
|
-
items.push({
|
|
165
|
-
label: `Remove proxy ${idx + 1}`,
|
|
166
|
-
hint: proxy,
|
|
167
|
-
value: { action: 'remove', index: idx },
|
|
168
|
-
color: 'yellow'
|
|
169
|
-
});
|
|
170
|
-
});
|
|
171
|
-
items.push({ label: '', value: { action: 'back' }, separator: true });
|
|
172
|
-
items.push({ label: 'Clear all proxies', value: { action: 'clear' }, color: 'red' });
|
|
173
|
-
}
|
|
174
|
-
const result = await select(items, {
|
|
175
|
-
message: `Manage Proxies: ${accountLabel}`,
|
|
176
|
-
subtitle: `${currentProxies.length} proxies configured`,
|
|
177
|
-
clearScreen: true,
|
|
178
|
-
});
|
|
179
|
-
if (!result)
|
|
180
|
-
return { action: 'back' };
|
|
181
|
-
if (result.action === 'clear') {
|
|
182
|
-
const confirmed = await confirm('Clear ALL proxies for this account?');
|
|
183
|
-
if (!confirmed)
|
|
184
|
-
continue;
|
|
185
|
-
}
|
|
186
|
-
return result;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
export async function promptProxyUrl() {
|
|
190
|
-
const readline = await import('node:readline/promises');
|
|
191
|
-
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
192
|
-
try {
|
|
193
|
-
const answer = await rl.question(`\n${ANSI.cyan}?${ANSI.reset} Enter proxy URL (e.g. http://user:pass@host:port/): `);
|
|
194
|
-
return answer.trim() || undefined;
|
|
195
|
-
}
|
|
196
|
-
finally {
|
|
197
|
-
rl.close();
|
|
198
|
-
}
|
|
199
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export declare function confirm(message: string, defaultYes?: boolean): Promise<boolean>;
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { select } from './select';
|
|
2
|
-
export async function confirm(message, defaultYes = false) {
|
|
3
|
-
const items = defaultYes
|
|
4
|
-
? [
|
|
5
|
-
{ label: 'Yes', value: true },
|
|
6
|
-
{ label: 'No', value: false },
|
|
7
|
-
]
|
|
8
|
-
: [
|
|
9
|
-
{ label: 'No', value: false },
|
|
10
|
-
{ label: 'Yes', value: true },
|
|
11
|
-
];
|
|
12
|
-
const result = await select(items, { message });
|
|
13
|
-
return result ?? false;
|
|
14
|
-
}
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
export interface MenuItem<T = string> {
|
|
2
|
-
label: string;
|
|
3
|
-
value: T;
|
|
4
|
-
hint?: string;
|
|
5
|
-
disabled?: boolean;
|
|
6
|
-
separator?: boolean;
|
|
7
|
-
/** Non-selectable label row (section heading). */
|
|
8
|
-
kind?: 'heading';
|
|
9
|
-
color?: 'red' | 'green' | 'yellow' | 'cyan';
|
|
10
|
-
}
|
|
11
|
-
export interface SelectOptions {
|
|
12
|
-
message: string;
|
|
13
|
-
subtitle?: string;
|
|
14
|
-
/** Override the help line shown at the bottom of the menu. */
|
|
15
|
-
help?: string;
|
|
16
|
-
/**
|
|
17
|
-
* Clear the terminal before each render (opt-in).
|
|
18
|
-
* Useful for nested flows where previous logs make menus feel cluttered.
|
|
19
|
-
*/
|
|
20
|
-
clearScreen?: boolean;
|
|
21
|
-
}
|
|
22
|
-
export declare function select<T>(items: MenuItem<T>[], options: SelectOptions): Promise<T | null>;
|
|
@@ -1,243 +0,0 @@
|
|
|
1
|
-
import { ANSI, isTTY, parseKey } from './ansi';
|
|
2
|
-
const ESCAPE_TIMEOUT_MS = 50;
|
|
3
|
-
const ANSI_REGEX = new RegExp("\\x1b\\[[0-9;]*m", "g");
|
|
4
|
-
const ANSI_LEADING_REGEX = new RegExp("^\\x1b\\[[0-9;]*m");
|
|
5
|
-
function stripAnsi(input) {
|
|
6
|
-
return input.replace(ANSI_REGEX, '');
|
|
7
|
-
}
|
|
8
|
-
function truncateAnsi(input, maxVisibleChars) {
|
|
9
|
-
if (maxVisibleChars <= 0)
|
|
10
|
-
return '';
|
|
11
|
-
const visible = stripAnsi(input);
|
|
12
|
-
if (visible.length <= maxVisibleChars)
|
|
13
|
-
return input;
|
|
14
|
-
const suffix = maxVisibleChars >= 3 ? '...' : '.'.repeat(maxVisibleChars);
|
|
15
|
-
const keep = Math.max(0, maxVisibleChars - suffix.length);
|
|
16
|
-
let out = '';
|
|
17
|
-
let i = 0;
|
|
18
|
-
let kept = 0;
|
|
19
|
-
while (i < input.length && kept < keep) {
|
|
20
|
-
if (input[i] === '\x1b') {
|
|
21
|
-
const m = input.slice(i).match(ANSI_LEADING_REGEX);
|
|
22
|
-
if (m) {
|
|
23
|
-
out += m[0];
|
|
24
|
-
i += m[0].length;
|
|
25
|
-
continue;
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
out += input[i];
|
|
29
|
-
i += 1;
|
|
30
|
-
kept += 1;
|
|
31
|
-
}
|
|
32
|
-
if (out.includes('\x1b[')) {
|
|
33
|
-
return `${out}${ANSI.reset}${suffix}`;
|
|
34
|
-
}
|
|
35
|
-
return out + suffix;
|
|
36
|
-
}
|
|
37
|
-
function getColorCode(color) {
|
|
38
|
-
switch (color) {
|
|
39
|
-
case 'red': return ANSI.red;
|
|
40
|
-
case 'green': return ANSI.green;
|
|
41
|
-
case 'yellow': return ANSI.yellow;
|
|
42
|
-
case 'cyan': return ANSI.cyan;
|
|
43
|
-
default: return '';
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
export async function select(items, options) {
|
|
47
|
-
if (!isTTY()) {
|
|
48
|
-
throw new Error('Interactive select requires a TTY terminal');
|
|
49
|
-
}
|
|
50
|
-
if (items.length === 0) {
|
|
51
|
-
throw new Error('No menu items provided');
|
|
52
|
-
}
|
|
53
|
-
const isSelectable = (i) => !i.disabled && !i.separator && i.kind !== 'heading';
|
|
54
|
-
const enabledItems = items.filter(isSelectable);
|
|
55
|
-
if (enabledItems.length === 0) {
|
|
56
|
-
throw new Error('All items disabled');
|
|
57
|
-
}
|
|
58
|
-
if (enabledItems.length === 1) {
|
|
59
|
-
return enabledItems[0].value;
|
|
60
|
-
}
|
|
61
|
-
const { message, subtitle } = options;
|
|
62
|
-
const { stdin, stdout } = process;
|
|
63
|
-
let cursor = items.findIndex(isSelectable);
|
|
64
|
-
if (cursor === -1)
|
|
65
|
-
cursor = 0; // Fallback, though validation above should prevent this
|
|
66
|
-
let escapeTimeout = null;
|
|
67
|
-
let isCleanedUp = false;
|
|
68
|
-
let renderedLines = 0;
|
|
69
|
-
const render = () => {
|
|
70
|
-
const columns = stdout.columns ?? 80;
|
|
71
|
-
const rows = stdout.rows ?? 24;
|
|
72
|
-
const shouldClearScreen = options.clearScreen === true;
|
|
73
|
-
const previousRenderedLines = renderedLines;
|
|
74
|
-
if (shouldClearScreen) {
|
|
75
|
-
stdout.write(ANSI.clearScreen + ANSI.moveTo(1, 1));
|
|
76
|
-
}
|
|
77
|
-
else if (previousRenderedLines > 0) {
|
|
78
|
-
stdout.write(ANSI.up(previousRenderedLines));
|
|
79
|
-
}
|
|
80
|
-
let linesWritten = 0;
|
|
81
|
-
const writeLine = (line) => {
|
|
82
|
-
stdout.write(`${ANSI.clearLine}${line}\n`);
|
|
83
|
-
linesWritten += 1;
|
|
84
|
-
};
|
|
85
|
-
// 1) blank "│" spacer, 2) subtitle line, 3) blank line. Header is counted separately.
|
|
86
|
-
const subtitleLines = subtitle ? 3 : 0;
|
|
87
|
-
const fixedLines = 1 + subtitleLines + 2; // header + subtitle + (help + bottom)
|
|
88
|
-
const maxVisibleItems = Math.max(1, Math.min(items.length, rows - fixedLines - 1));
|
|
89
|
-
let windowStart = 0;
|
|
90
|
-
let windowEnd = items.length;
|
|
91
|
-
if (items.length > maxVisibleItems) {
|
|
92
|
-
windowStart = cursor - Math.floor(maxVisibleItems / 2);
|
|
93
|
-
windowStart = Math.max(0, Math.min(windowStart, items.length - maxVisibleItems));
|
|
94
|
-
windowEnd = windowStart + maxVisibleItems;
|
|
95
|
-
}
|
|
96
|
-
const visibleItems = items.slice(windowStart, windowEnd);
|
|
97
|
-
const headerMessage = truncateAnsi(message, Math.max(1, columns - 4));
|
|
98
|
-
writeLine(`${ANSI.dim}┌ ${ANSI.reset}${headerMessage}`);
|
|
99
|
-
if (subtitle) {
|
|
100
|
-
writeLine(`${ANSI.dim}│${ANSI.reset}`);
|
|
101
|
-
const sub = truncateAnsi(subtitle, Math.max(1, columns - 4));
|
|
102
|
-
writeLine(`${ANSI.cyan}◆${ANSI.reset} ${sub}`);
|
|
103
|
-
writeLine("");
|
|
104
|
-
}
|
|
105
|
-
for (let i = 0; i < visibleItems.length; i++) {
|
|
106
|
-
const itemIndex = windowStart + i;
|
|
107
|
-
const item = visibleItems[i];
|
|
108
|
-
if (!item)
|
|
109
|
-
continue;
|
|
110
|
-
if (item.separator) {
|
|
111
|
-
writeLine(`${ANSI.dim}│${ANSI.reset}`);
|
|
112
|
-
continue;
|
|
113
|
-
}
|
|
114
|
-
if (item.kind === 'heading') {
|
|
115
|
-
const heading = truncateAnsi(`${ANSI.dim}${ANSI.bold}${item.label}${ANSI.reset}`, Math.max(1, columns - 6));
|
|
116
|
-
writeLine(`${ANSI.cyan}│${ANSI.reset} ${heading}`);
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
const isSelected = itemIndex === cursor;
|
|
120
|
-
const colorCode = getColorCode(item.color);
|
|
121
|
-
let labelText;
|
|
122
|
-
if (item.disabled) {
|
|
123
|
-
labelText = `${ANSI.dim}${item.label} (unavailable)${ANSI.reset}`;
|
|
124
|
-
}
|
|
125
|
-
else if (isSelected) {
|
|
126
|
-
labelText = colorCode ? `${colorCode}${item.label}${ANSI.reset}` : item.label;
|
|
127
|
-
if (item.hint)
|
|
128
|
-
labelText += ` ${ANSI.dim}${item.hint}${ANSI.reset}`;
|
|
129
|
-
}
|
|
130
|
-
else {
|
|
131
|
-
labelText = colorCode
|
|
132
|
-
? `${ANSI.dim}${colorCode}${item.label}${ANSI.reset}`
|
|
133
|
-
: `${ANSI.dim}${item.label}${ANSI.reset}`;
|
|
134
|
-
if (item.hint)
|
|
135
|
-
labelText += ` ${ANSI.dim}${item.hint}${ANSI.reset}`;
|
|
136
|
-
}
|
|
137
|
-
labelText = truncateAnsi(labelText, Math.max(1, columns - 8));
|
|
138
|
-
if (isSelected) {
|
|
139
|
-
writeLine(`${ANSI.cyan}│${ANSI.reset} ${ANSI.green}●${ANSI.reset} ${labelText}`);
|
|
140
|
-
}
|
|
141
|
-
else {
|
|
142
|
-
writeLine(`${ANSI.cyan}│${ANSI.reset} ${ANSI.dim}○${ANSI.reset} ${labelText}`);
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
const windowHint = items.length > visibleItems.length
|
|
146
|
-
? ` (${windowStart + 1}-${windowEnd}/${items.length})`
|
|
147
|
-
: '';
|
|
148
|
-
const helpText = options.help ?? `Up/Down to select | Enter: confirm | Esc: back${windowHint}`;
|
|
149
|
-
const help = truncateAnsi(helpText, Math.max(1, columns - 6));
|
|
150
|
-
writeLine(`${ANSI.cyan}│${ANSI.reset} ${ANSI.dim}${help}${ANSI.reset}`);
|
|
151
|
-
writeLine(`${ANSI.cyan}└${ANSI.reset}`);
|
|
152
|
-
if (!shouldClearScreen && previousRenderedLines > linesWritten) {
|
|
153
|
-
const extra = previousRenderedLines - linesWritten;
|
|
154
|
-
for (let i = 0; i < extra; i++) {
|
|
155
|
-
writeLine("");
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
renderedLines = linesWritten;
|
|
159
|
-
};
|
|
160
|
-
return new Promise((resolve) => {
|
|
161
|
-
const wasRaw = stdin.isRaw ?? false;
|
|
162
|
-
const cleanup = () => {
|
|
163
|
-
if (isCleanedUp)
|
|
164
|
-
return;
|
|
165
|
-
isCleanedUp = true;
|
|
166
|
-
if (escapeTimeout) {
|
|
167
|
-
clearTimeout(escapeTimeout);
|
|
168
|
-
escapeTimeout = null;
|
|
169
|
-
}
|
|
170
|
-
try {
|
|
171
|
-
stdin.removeListener('data', onKey);
|
|
172
|
-
stdin.setRawMode(wasRaw);
|
|
173
|
-
stdin.pause();
|
|
174
|
-
stdout.write(ANSI.show);
|
|
175
|
-
}
|
|
176
|
-
catch {
|
|
177
|
-
}
|
|
178
|
-
process.removeListener('SIGINT', onSignal);
|
|
179
|
-
process.removeListener('SIGTERM', onSignal);
|
|
180
|
-
};
|
|
181
|
-
const onSignal = () => {
|
|
182
|
-
cleanup();
|
|
183
|
-
resolve(null);
|
|
184
|
-
};
|
|
185
|
-
const finishWithValue = (value) => {
|
|
186
|
-
cleanup();
|
|
187
|
-
resolve(value);
|
|
188
|
-
};
|
|
189
|
-
const findNextSelectable = (from, direction) => {
|
|
190
|
-
if (items.length === 0)
|
|
191
|
-
return from;
|
|
192
|
-
let next = from;
|
|
193
|
-
do {
|
|
194
|
-
next = (next + direction + items.length) % items.length;
|
|
195
|
-
} while (items[next]?.disabled || items[next]?.separator || items[next]?.kind === 'heading');
|
|
196
|
-
return next;
|
|
197
|
-
};
|
|
198
|
-
const onKey = (data) => {
|
|
199
|
-
if (escapeTimeout) {
|
|
200
|
-
clearTimeout(escapeTimeout);
|
|
201
|
-
escapeTimeout = null;
|
|
202
|
-
}
|
|
203
|
-
const action = parseKey(data);
|
|
204
|
-
switch (action) {
|
|
205
|
-
case 'up':
|
|
206
|
-
cursor = findNextSelectable(cursor, -1);
|
|
207
|
-
render();
|
|
208
|
-
return;
|
|
209
|
-
case 'down':
|
|
210
|
-
cursor = findNextSelectable(cursor, 1);
|
|
211
|
-
render();
|
|
212
|
-
return;
|
|
213
|
-
case 'enter':
|
|
214
|
-
finishWithValue(items[cursor]?.value ?? null);
|
|
215
|
-
return;
|
|
216
|
-
case 'escape':
|
|
217
|
-
finishWithValue(null);
|
|
218
|
-
return;
|
|
219
|
-
case 'escape-start':
|
|
220
|
-
escapeTimeout = setTimeout(() => {
|
|
221
|
-
finishWithValue(null);
|
|
222
|
-
}, ESCAPE_TIMEOUT_MS);
|
|
223
|
-
return;
|
|
224
|
-
default:
|
|
225
|
-
return;
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
process.once('SIGINT', onSignal);
|
|
229
|
-
process.once('SIGTERM', onSignal);
|
|
230
|
-
try {
|
|
231
|
-
stdin.setRawMode(true);
|
|
232
|
-
}
|
|
233
|
-
catch {
|
|
234
|
-
cleanup();
|
|
235
|
-
resolve(null);
|
|
236
|
-
return;
|
|
237
|
-
}
|
|
238
|
-
stdin.resume();
|
|
239
|
-
stdout.write(ANSI.hide);
|
|
240
|
-
render();
|
|
241
|
-
stdin.on('data', onKey);
|
|
242
|
-
});
|
|
243
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remote Antigravity version fetcher.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors the Antigravity-Manager's version resolution strategy:
|
|
5
|
-
* 1. Auto-updater API (plain text with semver)
|
|
6
|
-
* 2. Changelog page scrape (first 5000 chars)
|
|
7
|
-
* 3. Hardcoded fallback in constants.ts
|
|
8
|
-
*
|
|
9
|
-
* Called once at plugin startup to ensure headers use the latest
|
|
10
|
-
* supported version, avoiding "version no longer supported" errors.
|
|
11
|
-
*
|
|
12
|
-
* @see https://github.com/lbjlaq/Antigravity-Manager (src-tauri/src/constants.rs)
|
|
13
|
-
*/
|
|
14
|
-
/**
|
|
15
|
-
* Fetch the latest Antigravity version and update the global constant.
|
|
16
|
-
* Safe to call before logger is initialized (will silently skip logging).
|
|
17
|
-
*/
|
|
18
|
-
export declare function initAntigravityVersion(): Promise<void>;
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remote Antigravity version fetcher.
|
|
3
|
-
*
|
|
4
|
-
* Mirrors the Antigravity-Manager's version resolution strategy:
|
|
5
|
-
* 1. Auto-updater API (plain text with semver)
|
|
6
|
-
* 2. Changelog page scrape (first 5000 chars)
|
|
7
|
-
* 3. Hardcoded fallback in constants.ts
|
|
8
|
-
*
|
|
9
|
-
* Called once at plugin startup to ensure headers use the latest
|
|
10
|
-
* supported version, avoiding "version no longer supported" errors.
|
|
11
|
-
*
|
|
12
|
-
* @see https://github.com/lbjlaq/Antigravity-Manager (src-tauri/src/constants.rs)
|
|
13
|
-
*/
|
|
14
|
-
import { getAntigravityVersion, setAntigravityVersion } from "../constants";
|
|
15
|
-
import { createLogger } from "./logger";
|
|
16
|
-
const VERSION_URL = "https://antigravity-auto-updater-974169037036.us-central1.run.app";
|
|
17
|
-
const CHANGELOG_URL = "https://antigravity.google/changelog";
|
|
18
|
-
const FETCH_TIMEOUT_MS = 5000;
|
|
19
|
-
const CHANGELOG_SCAN_CHARS = 5000;
|
|
20
|
-
const VERSION_REGEX = /\d+\.\d+\.\d+/;
|
|
21
|
-
function parseVersion(text) {
|
|
22
|
-
const match = text.match(VERSION_REGEX);
|
|
23
|
-
return match ? match[0] : null;
|
|
24
|
-
}
|
|
25
|
-
async function tryFetchVersion(url, maxChars) {
|
|
26
|
-
const controller = new AbortController();
|
|
27
|
-
const timeout = setTimeout(() => controller.abort(), FETCH_TIMEOUT_MS);
|
|
28
|
-
try {
|
|
29
|
-
const response = await fetch(url, { signal: controller.signal });
|
|
30
|
-
if (!response.ok)
|
|
31
|
-
return null;
|
|
32
|
-
let text = await response.text();
|
|
33
|
-
if (maxChars)
|
|
34
|
-
text = text.slice(0, maxChars);
|
|
35
|
-
return parseVersion(text);
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
return null;
|
|
39
|
-
}
|
|
40
|
-
finally {
|
|
41
|
-
clearTimeout(timeout);
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Fetch the latest Antigravity version and update the global constant.
|
|
46
|
-
* Safe to call before logger is initialized (will silently skip logging).
|
|
47
|
-
*/
|
|
48
|
-
export async function initAntigravityVersion() {
|
|
49
|
-
const log = createLogger("version");
|
|
50
|
-
const fallback = getAntigravityVersion();
|
|
51
|
-
let version;
|
|
52
|
-
let source;
|
|
53
|
-
// 1. Try auto-updater API
|
|
54
|
-
version = await tryFetchVersion(VERSION_URL);
|
|
55
|
-
if (version) {
|
|
56
|
-
source = "api";
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
// 2. Try changelog page scrape
|
|
60
|
-
version = await tryFetchVersion(CHANGELOG_URL, CHANGELOG_SCAN_CHARS);
|
|
61
|
-
if (version) {
|
|
62
|
-
source = "changelog";
|
|
63
|
-
}
|
|
64
|
-
else {
|
|
65
|
-
// 3. Fall back to hardcoded
|
|
66
|
-
source = "fallback";
|
|
67
|
-
setAntigravityVersion(fallback);
|
|
68
|
-
log.info("version-fetch-failed", { fallback });
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
if (version !== fallback) {
|
|
73
|
-
log.info("version-updated", { version, source, previous: fallback });
|
|
74
|
-
}
|
|
75
|
-
else {
|
|
76
|
-
log.debug("version-unchanged", { version, source });
|
|
77
|
-
}
|
|
78
|
-
setAntigravityVersion(version);
|
|
79
|
-
}
|