@reinamaccredy/oh-my-opencode 3.0.0-beta.14 → 3.0.0-beta.16
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/dist/cli/config-manager.d.ts +3 -3
- package/dist/cli/index.js +158 -350
- package/dist/cli/types.d.ts +0 -1
- package/dist/config/index.d.ts +2 -2
- package/dist/config/schema.d.ts +215 -181
- package/dist/features/background-agent/index.d.ts +1 -1
- package/dist/features/background-agent/manager.d.ts +10 -0
- package/dist/features/background-agent/types.d.ts +4 -0
- package/dist/features/boulder-state/index.d.ts +1 -0
- package/dist/features/boulder-state/unified-state.d.ts +86 -0
- package/dist/features/maestro/hooks/index.d.ts +16 -0
- package/dist/features/maestro/index.d.ts +4 -0
- package/dist/features/maestro/skills/index.d.ts +4 -0
- package/dist/features/maestro/types.d.ts +42 -0
- package/dist/features/maestro/utils/index.d.ts +4 -0
- package/dist/features/workflow-engine/contracts/v1/types.d.ts +9 -0
- package/dist/hooks/background-notification/index.d.ts +10 -0
- package/dist/hooks/index.d.ts +3 -0
- package/dist/hooks/maestro-sisyphus-bridge/constants.d.ts +9 -0
- package/dist/hooks/maestro-sisyphus-bridge/index.d.ts +53 -0
- package/dist/hooks/tdd-enforcement/constants.d.ts +16 -0
- package/dist/hooks/tdd-enforcement/index.d.ts +54 -0
- package/dist/index.js +1851 -6022
- package/dist/shared/migration.d.ts +4 -0
- package/dist/tools/skill/tools.d.ts +1 -7
- package/dist/tools/slashcommand/tools.d.ts +1 -7
- package/package.json +2 -6
- package/dist/auth/antigravity/accounts.d.ts +0 -40
- package/dist/auth/antigravity/accounts.test.d.ts +0 -1
- package/dist/auth/antigravity/browser.d.ts +0 -27
- package/dist/auth/antigravity/browser.test.d.ts +0 -1
- package/dist/auth/antigravity/cli.d.ts +0 -2
- package/dist/auth/antigravity/cli.test.d.ts +0 -1
- package/dist/auth/antigravity/constants.d.ts +0 -98
- package/dist/auth/antigravity/constants.test.d.ts +0 -1
- package/dist/auth/antigravity/fetch.d.ts +0 -69
- package/dist/auth/antigravity/index.d.ts +0 -13
- package/dist/auth/antigravity/integration.test.d.ts +0 -10
- package/dist/auth/antigravity/message-converter.d.ts +0 -54
- package/dist/auth/antigravity/oauth.d.ts +0 -51
- package/dist/auth/antigravity/oauth.test.d.ts +0 -1
- package/dist/auth/antigravity/plugin.d.ts +0 -54
- package/dist/auth/antigravity/project.d.ts +0 -10
- package/dist/auth/antigravity/request.d.ts +0 -116
- package/dist/auth/antigravity/request.test.d.ts +0 -1
- package/dist/auth/antigravity/response.d.ts +0 -137
- package/dist/auth/antigravity/storage.d.ts +0 -5
- package/dist/auth/antigravity/storage.test.d.ts +0 -1
- package/dist/auth/antigravity/thinking.d.ts +0 -278
- package/dist/auth/antigravity/thinking.test.d.ts +0 -10
- package/dist/auth/antigravity/thought-signature-store.d.ts +0 -52
- package/dist/auth/antigravity/token.d.ts +0 -38
- package/dist/auth/antigravity/token.test.d.ts +0 -1
- package/dist/auth/antigravity/tools.d.ts +0 -119
- package/dist/auth/antigravity/types.d.ts +0 -229
- package/dist/cli/commands/auth.d.ts +0 -2
- package/dist/cli/config-manager.test.d.ts +0 -1
- package/dist/google-auth.d.ts +0 -3
- package/dist/google-auth.js +0 -3871
package/dist/google-auth.js
DELETED
|
@@ -1,3871 +0,0 @@
|
|
|
1
|
-
// @bun
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
4
|
-
var __defProp = Object.defineProperty;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __toESM = (mod, isNodeMode, target) => {
|
|
9
|
-
target = mod != null ? __create(__getProtoOf(mod)) : {};
|
|
10
|
-
const to = isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target;
|
|
11
|
-
for (let key of __getOwnPropNames(mod))
|
|
12
|
-
if (!__hasOwnProp.call(to, key))
|
|
13
|
-
__defProp(to, key, {
|
|
14
|
-
get: () => mod[key],
|
|
15
|
-
enumerable: true
|
|
16
|
-
});
|
|
17
|
-
return to;
|
|
18
|
-
};
|
|
19
|
-
var __moduleCache = /* @__PURE__ */ new WeakMap;
|
|
20
|
-
var __toCommonJS = (from) => {
|
|
21
|
-
var entry = __moduleCache.get(from), desc;
|
|
22
|
-
if (entry)
|
|
23
|
-
return entry;
|
|
24
|
-
entry = __defProp({}, "__esModule", { value: true });
|
|
25
|
-
if (from && typeof from === "object" || typeof from === "function")
|
|
26
|
-
__getOwnPropNames(from).map((key) => !__hasOwnProp.call(entry, key) && __defProp(entry, key, {
|
|
27
|
-
get: () => from[key],
|
|
28
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
29
|
-
}));
|
|
30
|
-
__moduleCache.set(from, entry);
|
|
31
|
-
return entry;
|
|
32
|
-
};
|
|
33
|
-
var __commonJS = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
34
|
-
var __export = (target, all) => {
|
|
35
|
-
for (var name in all)
|
|
36
|
-
__defProp(target, name, {
|
|
37
|
-
get: all[name],
|
|
38
|
-
enumerable: true,
|
|
39
|
-
configurable: true,
|
|
40
|
-
set: (newValue) => all[name] = () => newValue
|
|
41
|
-
});
|
|
42
|
-
};
|
|
43
|
-
var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
|
|
44
|
-
var __require = import.meta.require;
|
|
45
|
-
|
|
46
|
-
// node_modules/sisteransi/src/index.js
|
|
47
|
-
var require_src = __commonJS((exports, module) => {
|
|
48
|
-
var ESC = "\x1B";
|
|
49
|
-
var CSI = `${ESC}[`;
|
|
50
|
-
var beep = "\x07";
|
|
51
|
-
var cursor = {
|
|
52
|
-
to(x, y) {
|
|
53
|
-
if (!y)
|
|
54
|
-
return `${CSI}${x + 1}G`;
|
|
55
|
-
return `${CSI}${y + 1};${x + 1}H`;
|
|
56
|
-
},
|
|
57
|
-
move(x, y) {
|
|
58
|
-
let ret = "";
|
|
59
|
-
if (x < 0)
|
|
60
|
-
ret += `${CSI}${-x}D`;
|
|
61
|
-
else if (x > 0)
|
|
62
|
-
ret += `${CSI}${x}C`;
|
|
63
|
-
if (y < 0)
|
|
64
|
-
ret += `${CSI}${-y}A`;
|
|
65
|
-
else if (y > 0)
|
|
66
|
-
ret += `${CSI}${y}B`;
|
|
67
|
-
return ret;
|
|
68
|
-
},
|
|
69
|
-
up: (count = 1) => `${CSI}${count}A`,
|
|
70
|
-
down: (count = 1) => `${CSI}${count}B`,
|
|
71
|
-
forward: (count = 1) => `${CSI}${count}C`,
|
|
72
|
-
backward: (count = 1) => `${CSI}${count}D`,
|
|
73
|
-
nextLine: (count = 1) => `${CSI}E`.repeat(count),
|
|
74
|
-
prevLine: (count = 1) => `${CSI}F`.repeat(count),
|
|
75
|
-
left: `${CSI}G`,
|
|
76
|
-
hide: `${CSI}?25l`,
|
|
77
|
-
show: `${CSI}?25h`,
|
|
78
|
-
save: `${ESC}7`,
|
|
79
|
-
restore: `${ESC}8`
|
|
80
|
-
};
|
|
81
|
-
var scroll = {
|
|
82
|
-
up: (count = 1) => `${CSI}S`.repeat(count),
|
|
83
|
-
down: (count = 1) => `${CSI}T`.repeat(count)
|
|
84
|
-
};
|
|
85
|
-
var erase = {
|
|
86
|
-
screen: `${CSI}2J`,
|
|
87
|
-
up: (count = 1) => `${CSI}1J`.repeat(count),
|
|
88
|
-
down: (count = 1) => `${CSI}J`.repeat(count),
|
|
89
|
-
line: `${CSI}2K`,
|
|
90
|
-
lineEnd: `${CSI}K`,
|
|
91
|
-
lineStart: `${CSI}1K`,
|
|
92
|
-
lines(count) {
|
|
93
|
-
let clear = "";
|
|
94
|
-
for (let i = 0;i < count; i++)
|
|
95
|
-
clear += this.line + (i < count - 1 ? cursor.up() : "");
|
|
96
|
-
if (count)
|
|
97
|
-
clear += cursor.left;
|
|
98
|
-
return clear;
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
module.exports = { cursor, scroll, erase, beep };
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
// node_modules/picocolors/picocolors.js
|
|
105
|
-
var require_picocolors = __commonJS((exports, module) => {
|
|
106
|
-
var p = process || {};
|
|
107
|
-
var argv = p.argv || [];
|
|
108
|
-
var env = p.env || {};
|
|
109
|
-
var isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || (p.stdout || {}).isTTY && env.TERM !== "dumb" || !!env.CI);
|
|
110
|
-
var formatter = (open, close, replace = open) => (input) => {
|
|
111
|
-
let string = "" + input, index = string.indexOf(close, open.length);
|
|
112
|
-
return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close;
|
|
113
|
-
};
|
|
114
|
-
var replaceClose = (string, close, replace, index) => {
|
|
115
|
-
let result = "", cursor = 0;
|
|
116
|
-
do {
|
|
117
|
-
result += string.substring(cursor, index) + replace;
|
|
118
|
-
cursor = index + close.length;
|
|
119
|
-
index = string.indexOf(close, cursor);
|
|
120
|
-
} while (~index);
|
|
121
|
-
return result + string.substring(cursor);
|
|
122
|
-
};
|
|
123
|
-
var createColors = (enabled = isColorSupported) => {
|
|
124
|
-
let f = enabled ? formatter : () => String;
|
|
125
|
-
return {
|
|
126
|
-
isColorSupported: enabled,
|
|
127
|
-
reset: f("\x1B[0m", "\x1B[0m"),
|
|
128
|
-
bold: f("\x1B[1m", "\x1B[22m", "\x1B[22m\x1B[1m"),
|
|
129
|
-
dim: f("\x1B[2m", "\x1B[22m", "\x1B[22m\x1B[2m"),
|
|
130
|
-
italic: f("\x1B[3m", "\x1B[23m"),
|
|
131
|
-
underline: f("\x1B[4m", "\x1B[24m"),
|
|
132
|
-
inverse: f("\x1B[7m", "\x1B[27m"),
|
|
133
|
-
hidden: f("\x1B[8m", "\x1B[28m"),
|
|
134
|
-
strikethrough: f("\x1B[9m", "\x1B[29m"),
|
|
135
|
-
black: f("\x1B[30m", "\x1B[39m"),
|
|
136
|
-
red: f("\x1B[31m", "\x1B[39m"),
|
|
137
|
-
green: f("\x1B[32m", "\x1B[39m"),
|
|
138
|
-
yellow: f("\x1B[33m", "\x1B[39m"),
|
|
139
|
-
blue: f("\x1B[34m", "\x1B[39m"),
|
|
140
|
-
magenta: f("\x1B[35m", "\x1B[39m"),
|
|
141
|
-
cyan: f("\x1B[36m", "\x1B[39m"),
|
|
142
|
-
white: f("\x1B[37m", "\x1B[39m"),
|
|
143
|
-
gray: f("\x1B[90m", "\x1B[39m"),
|
|
144
|
-
bgBlack: f("\x1B[40m", "\x1B[49m"),
|
|
145
|
-
bgRed: f("\x1B[41m", "\x1B[49m"),
|
|
146
|
-
bgGreen: f("\x1B[42m", "\x1B[49m"),
|
|
147
|
-
bgYellow: f("\x1B[43m", "\x1B[49m"),
|
|
148
|
-
bgBlue: f("\x1B[44m", "\x1B[49m"),
|
|
149
|
-
bgMagenta: f("\x1B[45m", "\x1B[49m"),
|
|
150
|
-
bgCyan: f("\x1B[46m", "\x1B[49m"),
|
|
151
|
-
bgWhite: f("\x1B[47m", "\x1B[49m"),
|
|
152
|
-
blackBright: f("\x1B[90m", "\x1B[39m"),
|
|
153
|
-
redBright: f("\x1B[91m", "\x1B[39m"),
|
|
154
|
-
greenBright: f("\x1B[92m", "\x1B[39m"),
|
|
155
|
-
yellowBright: f("\x1B[93m", "\x1B[39m"),
|
|
156
|
-
blueBright: f("\x1B[94m", "\x1B[39m"),
|
|
157
|
-
magentaBright: f("\x1B[95m", "\x1B[39m"),
|
|
158
|
-
cyanBright: f("\x1B[96m", "\x1B[39m"),
|
|
159
|
-
whiteBright: f("\x1B[97m", "\x1B[39m"),
|
|
160
|
-
bgBlackBright: f("\x1B[100m", "\x1B[49m"),
|
|
161
|
-
bgRedBright: f("\x1B[101m", "\x1B[49m"),
|
|
162
|
-
bgGreenBright: f("\x1B[102m", "\x1B[49m"),
|
|
163
|
-
bgYellowBright: f("\x1B[103m", "\x1B[49m"),
|
|
164
|
-
bgBlueBright: f("\x1B[104m", "\x1B[49m"),
|
|
165
|
-
bgMagentaBright: f("\x1B[105m", "\x1B[49m"),
|
|
166
|
-
bgCyanBright: f("\x1B[106m", "\x1B[49m"),
|
|
167
|
-
bgWhiteBright: f("\x1B[107m", "\x1B[49m")
|
|
168
|
-
};
|
|
169
|
-
};
|
|
170
|
-
module.exports = createColors();
|
|
171
|
-
module.exports.createColors = createColors;
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
// src/auth/antigravity/types.ts
|
|
175
|
-
var MODEL_FAMILIES = ["claude", "gemini-flash", "gemini-pro"];
|
|
176
|
-
// src/auth/antigravity/constants.ts
|
|
177
|
-
var ANTIGRAVITY_CLIENT_ID = "1071006060591-tmhssin2h21lcre235vtolojh4g403ep.apps.googleusercontent.com";
|
|
178
|
-
var ANTIGRAVITY_CLIENT_SECRET = "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";
|
|
179
|
-
var ANTIGRAVITY_CALLBACK_PORT = 51121;
|
|
180
|
-
var ANTIGRAVITY_REDIRECT_URI = `http://localhost:${ANTIGRAVITY_CALLBACK_PORT}/oauth-callback`;
|
|
181
|
-
var ANTIGRAVITY_SCOPES = [
|
|
182
|
-
"https://www.googleapis.com/auth/cloud-platform",
|
|
183
|
-
"https://www.googleapis.com/auth/userinfo.email",
|
|
184
|
-
"https://www.googleapis.com/auth/userinfo.profile",
|
|
185
|
-
"https://www.googleapis.com/auth/cclog",
|
|
186
|
-
"https://www.googleapis.com/auth/experimentsandconfigs"
|
|
187
|
-
];
|
|
188
|
-
var ANTIGRAVITY_ENDPOINT_FALLBACKS = [
|
|
189
|
-
"https://daily-cloudcode-pa.sandbox.googleapis.com",
|
|
190
|
-
"https://daily-cloudcode-pa.googleapis.com",
|
|
191
|
-
"https://cloudcode-pa.googleapis.com"
|
|
192
|
-
];
|
|
193
|
-
var ANTIGRAVITY_API_VERSION = "v1internal";
|
|
194
|
-
var ANTIGRAVITY_HEADERS = {
|
|
195
|
-
"User-Agent": "google-api-nodejs-client/9.15.1",
|
|
196
|
-
"X-Goog-Api-Client": "google-cloud-sdk vscode_cloudshelleditor/0.1",
|
|
197
|
-
"Client-Metadata": JSON.stringify({
|
|
198
|
-
ideType: "IDE_UNSPECIFIED",
|
|
199
|
-
platform: "PLATFORM_UNSPECIFIED",
|
|
200
|
-
pluginType: "GEMINI"
|
|
201
|
-
})
|
|
202
|
-
};
|
|
203
|
-
var ANTIGRAVITY_DEFAULT_PROJECT_ID = "rising-fact-p41fc";
|
|
204
|
-
var GOOGLE_AUTH_URL = "https://accounts.google.com/o/oauth2/v2/auth";
|
|
205
|
-
var GOOGLE_TOKEN_URL = "https://oauth2.googleapis.com/token";
|
|
206
|
-
var GOOGLE_USERINFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo";
|
|
207
|
-
var ANTIGRAVITY_TOKEN_REFRESH_BUFFER_MS = 60000;
|
|
208
|
-
var SKIP_THOUGHT_SIGNATURE_VALIDATOR = "skip_thought_signature_validator";
|
|
209
|
-
var ANTIGRAVITY_SYSTEM_PROMPT = `<identity>
|
|
210
|
-
You are Antigravity, a powerful agentic AI coding assistant designed by the Google Deepmind team working on Advanced Agentic Coding.
|
|
211
|
-
You are pair programming with a USER to solve their coding task. The task may require creating a new codebase, modifying or debugging an existing codebase, or simply answering a question.
|
|
212
|
-
The USER will send you requests, which you must always prioritize addressing. Along with each USER request, we will attach additional metadata about their current state, such as what files they have open and where their cursor is.
|
|
213
|
-
This information may or may not be relevant to the coding task, it is up for you to decide.
|
|
214
|
-
</identity>
|
|
215
|
-
|
|
216
|
-
<tool_calling>
|
|
217
|
-
Call tools as you normally would. The following list provides additional guidance to help you avoid errors:
|
|
218
|
-
- **Absolute paths only**. When using tools that accept file path arguments, ALWAYS use the absolute file path.
|
|
219
|
-
</tool_calling>
|
|
220
|
-
|
|
221
|
-
<web_application_development>
|
|
222
|
-
## Technology Stack
|
|
223
|
-
Your web applications should be built using the following technologies:
|
|
224
|
-
1. **Core**: Use HTML for structure and Javascript for logic.
|
|
225
|
-
2. **Styling (CSS)**: Use Vanilla CSS for maximum flexibility and control. Avoid using TailwindCSS unless the USER explicitly requests it; in this case, first confirm which TailwindCSS version to use.
|
|
226
|
-
3. **Web App**: If the USER specifies that they want a more complex web app, use a framework like Next.js or Vite. Only do this if the USER explicitly requests a web app.
|
|
227
|
-
4. **New Project Creation**: If you need to use a framework for a new app, use \`npx\` with the appropriate script, but there are some rules to follow:
|
|
228
|
-
- Use \`npx -y\` to automatically install the script and its dependencies
|
|
229
|
-
- You MUST run the command with \`--help\` flag to see all available options first
|
|
230
|
-
- Initialize the app in the current directory with \`./\` (example: \`npx -y create-vite-app@latest ./\`)
|
|
231
|
-
</web_application_development>
|
|
232
|
-
`;
|
|
233
|
-
var REASONING_EFFORT_BUDGET_MAP = {
|
|
234
|
-
none: 0,
|
|
235
|
-
auto: -1,
|
|
236
|
-
minimal: 512,
|
|
237
|
-
low: 1024,
|
|
238
|
-
medium: 8192,
|
|
239
|
-
high: 24576,
|
|
240
|
-
xhigh: 32768
|
|
241
|
-
};
|
|
242
|
-
var ANTIGRAVITY_MODEL_CONFIGS = {
|
|
243
|
-
"gemini-2.5-flash": {
|
|
244
|
-
thinkingType: "numeric",
|
|
245
|
-
min: 0,
|
|
246
|
-
max: 24576,
|
|
247
|
-
zeroAllowed: true
|
|
248
|
-
},
|
|
249
|
-
"gemini-2.5-flash-lite": {
|
|
250
|
-
thinkingType: "numeric",
|
|
251
|
-
min: 0,
|
|
252
|
-
max: 24576,
|
|
253
|
-
zeroAllowed: true
|
|
254
|
-
},
|
|
255
|
-
"gemini-2.5-computer-use-preview-10-2025": {
|
|
256
|
-
thinkingType: "numeric",
|
|
257
|
-
min: 128,
|
|
258
|
-
max: 32768,
|
|
259
|
-
zeroAllowed: false
|
|
260
|
-
},
|
|
261
|
-
"gemini-3-pro-preview": {
|
|
262
|
-
thinkingType: "levels",
|
|
263
|
-
min: 128,
|
|
264
|
-
max: 32768,
|
|
265
|
-
zeroAllowed: false,
|
|
266
|
-
levels: ["low", "high"]
|
|
267
|
-
},
|
|
268
|
-
"gemini-3-flash-preview": {
|
|
269
|
-
thinkingType: "levels",
|
|
270
|
-
min: 128,
|
|
271
|
-
max: 32768,
|
|
272
|
-
zeroAllowed: false,
|
|
273
|
-
levels: ["minimal", "low", "medium", "high"]
|
|
274
|
-
},
|
|
275
|
-
"gemini-claude-sonnet-4-5-thinking": {
|
|
276
|
-
thinkingType: "numeric",
|
|
277
|
-
min: 1024,
|
|
278
|
-
max: 200000,
|
|
279
|
-
zeroAllowed: false
|
|
280
|
-
},
|
|
281
|
-
"gemini-claude-opus-4-5-thinking": {
|
|
282
|
-
thinkingType: "numeric",
|
|
283
|
-
min: 1024,
|
|
284
|
-
max: 200000,
|
|
285
|
-
zeroAllowed: false
|
|
286
|
-
}
|
|
287
|
-
};
|
|
288
|
-
function normalizeModelId(model) {
|
|
289
|
-
let normalized = model;
|
|
290
|
-
if (normalized.includes("/")) {
|
|
291
|
-
normalized = normalized.split("/").pop() || normalized;
|
|
292
|
-
}
|
|
293
|
-
if (normalized.startsWith("antigravity-")) {
|
|
294
|
-
normalized = normalized.substring("antigravity-".length);
|
|
295
|
-
}
|
|
296
|
-
normalized = normalized.replace(/-thinking-(low|medium|high)$/, "");
|
|
297
|
-
normalized = normalized.replace(/-(high|low)$/, "");
|
|
298
|
-
return normalized;
|
|
299
|
-
}
|
|
300
|
-
function alias2ModelName(modelName) {
|
|
301
|
-
if (modelName.startsWith("gemini-claude-")) {
|
|
302
|
-
return modelName.substring("gemini-".length);
|
|
303
|
-
}
|
|
304
|
-
return modelName;
|
|
305
|
-
}
|
|
306
|
-
// src/auth/antigravity/oauth.ts
|
|
307
|
-
async function buildAuthURL(projectId, clientId = ANTIGRAVITY_CLIENT_ID, port = ANTIGRAVITY_CALLBACK_PORT) {
|
|
308
|
-
const state = crypto.randomUUID().replace(/-/g, "");
|
|
309
|
-
const redirectUri = `http://localhost:${port}/oauth-callback`;
|
|
310
|
-
const url = new URL(GOOGLE_AUTH_URL);
|
|
311
|
-
url.searchParams.set("client_id", clientId);
|
|
312
|
-
url.searchParams.set("redirect_uri", redirectUri);
|
|
313
|
-
url.searchParams.set("response_type", "code");
|
|
314
|
-
url.searchParams.set("scope", ANTIGRAVITY_SCOPES.join(" "));
|
|
315
|
-
url.searchParams.set("state", state);
|
|
316
|
-
url.searchParams.set("access_type", "offline");
|
|
317
|
-
url.searchParams.set("prompt", "consent");
|
|
318
|
-
return {
|
|
319
|
-
url: url.toString(),
|
|
320
|
-
state
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
async function exchangeCode(code, redirectUri, clientId = ANTIGRAVITY_CLIENT_ID, clientSecret = ANTIGRAVITY_CLIENT_SECRET) {
|
|
324
|
-
const params = new URLSearchParams({
|
|
325
|
-
client_id: clientId,
|
|
326
|
-
client_secret: clientSecret,
|
|
327
|
-
code,
|
|
328
|
-
grant_type: "authorization_code",
|
|
329
|
-
redirect_uri: redirectUri
|
|
330
|
-
});
|
|
331
|
-
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
332
|
-
method: "POST",
|
|
333
|
-
headers: {
|
|
334
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
335
|
-
},
|
|
336
|
-
body: params
|
|
337
|
-
});
|
|
338
|
-
if (!response.ok) {
|
|
339
|
-
const errorText = await response.text();
|
|
340
|
-
throw new Error(`Token exchange failed: ${response.status} - ${errorText}`);
|
|
341
|
-
}
|
|
342
|
-
const data = await response.json();
|
|
343
|
-
return {
|
|
344
|
-
access_token: data.access_token,
|
|
345
|
-
refresh_token: data.refresh_token,
|
|
346
|
-
expires_in: data.expires_in,
|
|
347
|
-
token_type: data.token_type
|
|
348
|
-
};
|
|
349
|
-
}
|
|
350
|
-
async function fetchUserInfo(accessToken) {
|
|
351
|
-
const response = await fetch(`${GOOGLE_USERINFO_URL}?alt=json`, {
|
|
352
|
-
headers: {
|
|
353
|
-
Authorization: `Bearer ${accessToken}`
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
if (!response.ok) {
|
|
357
|
-
throw new Error(`Failed to fetch user info: ${response.status}`);
|
|
358
|
-
}
|
|
359
|
-
const data = await response.json();
|
|
360
|
-
return {
|
|
361
|
-
email: data.email || "",
|
|
362
|
-
name: data.name,
|
|
363
|
-
picture: data.picture
|
|
364
|
-
};
|
|
365
|
-
}
|
|
366
|
-
function startCallbackServer(timeoutMs = 5 * 60 * 1000) {
|
|
367
|
-
let server = null;
|
|
368
|
-
let timeoutId = null;
|
|
369
|
-
let resolveCallback = null;
|
|
370
|
-
let rejectCallback = null;
|
|
371
|
-
const cleanup = () => {
|
|
372
|
-
if (timeoutId) {
|
|
373
|
-
clearTimeout(timeoutId);
|
|
374
|
-
timeoutId = null;
|
|
375
|
-
}
|
|
376
|
-
if (server) {
|
|
377
|
-
server.stop();
|
|
378
|
-
server = null;
|
|
379
|
-
}
|
|
380
|
-
};
|
|
381
|
-
const fetchHandler = (request) => {
|
|
382
|
-
const url = new URL(request.url);
|
|
383
|
-
if (url.pathname === "/oauth-callback") {
|
|
384
|
-
const code = url.searchParams.get("code") || "";
|
|
385
|
-
const state = url.searchParams.get("state") || "";
|
|
386
|
-
const error = url.searchParams.get("error") || undefined;
|
|
387
|
-
let responseBody;
|
|
388
|
-
if (code && !error) {
|
|
389
|
-
responseBody = "<html><body><h1>Login successful</h1><p>You can close this window.</p></body></html>";
|
|
390
|
-
} else {
|
|
391
|
-
responseBody = "<html><body><h1>Login failed</h1><p>Please check the CLI output.</p></body></html>";
|
|
392
|
-
}
|
|
393
|
-
setTimeout(() => {
|
|
394
|
-
cleanup();
|
|
395
|
-
if (resolveCallback) {
|
|
396
|
-
resolveCallback({ code, state, error });
|
|
397
|
-
}
|
|
398
|
-
}, 100);
|
|
399
|
-
return new Response(responseBody, {
|
|
400
|
-
status: 200,
|
|
401
|
-
headers: { "Content-Type": "text/html" }
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
return new Response("Not Found", { status: 404 });
|
|
405
|
-
};
|
|
406
|
-
try {
|
|
407
|
-
server = Bun.serve({
|
|
408
|
-
port: ANTIGRAVITY_CALLBACK_PORT,
|
|
409
|
-
fetch: fetchHandler
|
|
410
|
-
});
|
|
411
|
-
} catch (error) {
|
|
412
|
-
server = Bun.serve({
|
|
413
|
-
port: 0,
|
|
414
|
-
fetch: fetchHandler
|
|
415
|
-
});
|
|
416
|
-
}
|
|
417
|
-
const actualPort = server.port;
|
|
418
|
-
const redirectUri = `http://localhost:${actualPort}/oauth-callback`;
|
|
419
|
-
const waitForCallback = () => {
|
|
420
|
-
return new Promise((resolve, reject) => {
|
|
421
|
-
resolveCallback = resolve;
|
|
422
|
-
rejectCallback = reject;
|
|
423
|
-
timeoutId = setTimeout(() => {
|
|
424
|
-
cleanup();
|
|
425
|
-
reject(new Error("OAuth callback timeout"));
|
|
426
|
-
}, timeoutMs);
|
|
427
|
-
});
|
|
428
|
-
};
|
|
429
|
-
return {
|
|
430
|
-
port: actualPort,
|
|
431
|
-
redirectUri,
|
|
432
|
-
waitForCallback,
|
|
433
|
-
close: cleanup
|
|
434
|
-
};
|
|
435
|
-
}
|
|
436
|
-
// src/auth/antigravity/token.ts
|
|
437
|
-
class AntigravityTokenRefreshError extends Error {
|
|
438
|
-
code;
|
|
439
|
-
description;
|
|
440
|
-
status;
|
|
441
|
-
statusText;
|
|
442
|
-
responseBody;
|
|
443
|
-
constructor(options) {
|
|
444
|
-
super(options.message);
|
|
445
|
-
this.name = "AntigravityTokenRefreshError";
|
|
446
|
-
this.code = options.code;
|
|
447
|
-
this.description = options.description;
|
|
448
|
-
this.status = options.status;
|
|
449
|
-
this.statusText = options.statusText;
|
|
450
|
-
this.responseBody = options.responseBody;
|
|
451
|
-
}
|
|
452
|
-
get isInvalidGrant() {
|
|
453
|
-
return this.code === "invalid_grant";
|
|
454
|
-
}
|
|
455
|
-
get isNetworkError() {
|
|
456
|
-
return this.status === 0;
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
function parseOAuthErrorPayload(text) {
|
|
460
|
-
if (!text) {
|
|
461
|
-
return {};
|
|
462
|
-
}
|
|
463
|
-
try {
|
|
464
|
-
const payload = JSON.parse(text);
|
|
465
|
-
let code;
|
|
466
|
-
if (typeof payload.error === "string") {
|
|
467
|
-
code = payload.error;
|
|
468
|
-
} else if (payload.error && typeof payload.error === "object") {
|
|
469
|
-
code = payload.error.status ?? payload.error.code;
|
|
470
|
-
}
|
|
471
|
-
return {
|
|
472
|
-
code,
|
|
473
|
-
description: payload.error_description
|
|
474
|
-
};
|
|
475
|
-
} catch {
|
|
476
|
-
return { description: text };
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
function isTokenExpired(tokens) {
|
|
480
|
-
const expirationTime = tokens.timestamp + tokens.expires_in * 1000;
|
|
481
|
-
return Date.now() >= expirationTime - ANTIGRAVITY_TOKEN_REFRESH_BUFFER_MS;
|
|
482
|
-
}
|
|
483
|
-
var MAX_REFRESH_RETRIES = 3;
|
|
484
|
-
var INITIAL_RETRY_DELAY_MS = 1000;
|
|
485
|
-
function calculateRetryDelay(attempt) {
|
|
486
|
-
return Math.min(INITIAL_RETRY_DELAY_MS * Math.pow(2, attempt), 1e4);
|
|
487
|
-
}
|
|
488
|
-
function isRetryableError(status) {
|
|
489
|
-
if (status === 0)
|
|
490
|
-
return true;
|
|
491
|
-
if (status === 429)
|
|
492
|
-
return true;
|
|
493
|
-
if (status >= 500 && status < 600)
|
|
494
|
-
return true;
|
|
495
|
-
return false;
|
|
496
|
-
}
|
|
497
|
-
async function refreshAccessToken(refreshToken, clientId = ANTIGRAVITY_CLIENT_ID, clientSecret = ANTIGRAVITY_CLIENT_SECRET) {
|
|
498
|
-
const params = new URLSearchParams({
|
|
499
|
-
grant_type: "refresh_token",
|
|
500
|
-
refresh_token: refreshToken,
|
|
501
|
-
client_id: clientId,
|
|
502
|
-
client_secret: clientSecret
|
|
503
|
-
});
|
|
504
|
-
let lastError;
|
|
505
|
-
for (let attempt = 0;attempt <= MAX_REFRESH_RETRIES; attempt++) {
|
|
506
|
-
try {
|
|
507
|
-
const response = await fetch(GOOGLE_TOKEN_URL, {
|
|
508
|
-
method: "POST",
|
|
509
|
-
headers: {
|
|
510
|
-
"Content-Type": "application/x-www-form-urlencoded"
|
|
511
|
-
},
|
|
512
|
-
body: params
|
|
513
|
-
});
|
|
514
|
-
if (response.ok) {
|
|
515
|
-
const data = await response.json();
|
|
516
|
-
return {
|
|
517
|
-
access_token: data.access_token,
|
|
518
|
-
refresh_token: data.refresh_token || refreshToken,
|
|
519
|
-
expires_in: data.expires_in,
|
|
520
|
-
token_type: data.token_type
|
|
521
|
-
};
|
|
522
|
-
}
|
|
523
|
-
const responseBody = await response.text().catch(() => {
|
|
524
|
-
return;
|
|
525
|
-
});
|
|
526
|
-
const parsed = parseOAuthErrorPayload(responseBody);
|
|
527
|
-
lastError = new AntigravityTokenRefreshError({
|
|
528
|
-
message: parsed.description || `Token refresh failed: ${response.status} ${response.statusText}`,
|
|
529
|
-
code: parsed.code,
|
|
530
|
-
description: parsed.description,
|
|
531
|
-
status: response.status,
|
|
532
|
-
statusText: response.statusText,
|
|
533
|
-
responseBody
|
|
534
|
-
});
|
|
535
|
-
if (parsed.code === "invalid_grant") {
|
|
536
|
-
throw lastError;
|
|
537
|
-
}
|
|
538
|
-
if (!isRetryableError(response.status)) {
|
|
539
|
-
throw lastError;
|
|
540
|
-
}
|
|
541
|
-
if (attempt < MAX_REFRESH_RETRIES) {
|
|
542
|
-
const delay = calculateRetryDelay(attempt);
|
|
543
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
544
|
-
}
|
|
545
|
-
} catch (error) {
|
|
546
|
-
if (error instanceof AntigravityTokenRefreshError) {
|
|
547
|
-
throw error;
|
|
548
|
-
}
|
|
549
|
-
lastError = new AntigravityTokenRefreshError({
|
|
550
|
-
message: error instanceof Error ? error.message : "Network error during token refresh",
|
|
551
|
-
status: 0,
|
|
552
|
-
statusText: "Network Error"
|
|
553
|
-
});
|
|
554
|
-
if (attempt < MAX_REFRESH_RETRIES) {
|
|
555
|
-
const delay = calculateRetryDelay(attempt);
|
|
556
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
throw lastError || new AntigravityTokenRefreshError({
|
|
561
|
-
message: "Token refresh failed after all retries",
|
|
562
|
-
status: 0,
|
|
563
|
-
statusText: "Max Retries Exceeded"
|
|
564
|
-
});
|
|
565
|
-
}
|
|
566
|
-
function parseStoredToken(stored) {
|
|
567
|
-
const parts = stored.split("|");
|
|
568
|
-
const [refreshToken, projectId, managedProjectId] = parts;
|
|
569
|
-
return {
|
|
570
|
-
refreshToken: refreshToken || "",
|
|
571
|
-
projectId: projectId || undefined,
|
|
572
|
-
managedProjectId: managedProjectId || undefined
|
|
573
|
-
};
|
|
574
|
-
}
|
|
575
|
-
function formatTokenForStorage(refreshToken, projectId, managedProjectId) {
|
|
576
|
-
return `${refreshToken}|${projectId}|${managedProjectId || ""}`;
|
|
577
|
-
}
|
|
578
|
-
// src/auth/antigravity/project.ts
|
|
579
|
-
var projectContextCache = new Map;
|
|
580
|
-
function debugLog(message) {
|
|
581
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
582
|
-
console.log(`[antigravity-project] ${message}`);
|
|
583
|
-
}
|
|
584
|
-
}
|
|
585
|
-
var CODE_ASSIST_METADATA = {
|
|
586
|
-
ideType: "IDE_UNSPECIFIED",
|
|
587
|
-
platform: "PLATFORM_UNSPECIFIED",
|
|
588
|
-
pluginType: "GEMINI"
|
|
589
|
-
};
|
|
590
|
-
function extractProjectId(project) {
|
|
591
|
-
if (!project)
|
|
592
|
-
return;
|
|
593
|
-
if (typeof project === "string") {
|
|
594
|
-
const trimmed = project.trim();
|
|
595
|
-
return trimmed || undefined;
|
|
596
|
-
}
|
|
597
|
-
if (typeof project === "object" && "id" in project) {
|
|
598
|
-
const id = project.id;
|
|
599
|
-
if (typeof id === "string") {
|
|
600
|
-
const trimmed = id.trim();
|
|
601
|
-
return trimmed || undefined;
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
return;
|
|
605
|
-
}
|
|
606
|
-
function getDefaultTierId(allowedTiers) {
|
|
607
|
-
if (!allowedTiers || allowedTiers.length === 0)
|
|
608
|
-
return;
|
|
609
|
-
for (const tier of allowedTiers) {
|
|
610
|
-
if (tier?.isDefault)
|
|
611
|
-
return tier.id;
|
|
612
|
-
}
|
|
613
|
-
return allowedTiers[0]?.id;
|
|
614
|
-
}
|
|
615
|
-
function isFreeTier(tierId) {
|
|
616
|
-
if (!tierId)
|
|
617
|
-
return true;
|
|
618
|
-
const lower = tierId.toLowerCase();
|
|
619
|
-
return lower === "free" || lower === "free-tier" || lower.startsWith("free");
|
|
620
|
-
}
|
|
621
|
-
function wait(ms) {
|
|
622
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
623
|
-
}
|
|
624
|
-
async function callLoadCodeAssistAPI(accessToken, projectId) {
|
|
625
|
-
const metadata = { ...CODE_ASSIST_METADATA };
|
|
626
|
-
if (projectId)
|
|
627
|
-
metadata.duetProject = projectId;
|
|
628
|
-
const requestBody = { metadata };
|
|
629
|
-
if (projectId)
|
|
630
|
-
requestBody.cloudaicompanionProject = projectId;
|
|
631
|
-
const headers = {
|
|
632
|
-
Authorization: `Bearer ${accessToken}`,
|
|
633
|
-
"Content-Type": "application/json",
|
|
634
|
-
"User-Agent": ANTIGRAVITY_HEADERS["User-Agent"],
|
|
635
|
-
"X-Goog-Api-Client": ANTIGRAVITY_HEADERS["X-Goog-Api-Client"],
|
|
636
|
-
"Client-Metadata": ANTIGRAVITY_HEADERS["Client-Metadata"]
|
|
637
|
-
};
|
|
638
|
-
for (const baseEndpoint of ANTIGRAVITY_ENDPOINT_FALLBACKS) {
|
|
639
|
-
const url = `${baseEndpoint}/${ANTIGRAVITY_API_VERSION}:loadCodeAssist`;
|
|
640
|
-
debugLog(`[loadCodeAssist] Trying: ${url}`);
|
|
641
|
-
try {
|
|
642
|
-
const response = await fetch(url, {
|
|
643
|
-
method: "POST",
|
|
644
|
-
headers,
|
|
645
|
-
body: JSON.stringify(requestBody)
|
|
646
|
-
});
|
|
647
|
-
if (!response.ok) {
|
|
648
|
-
debugLog(`[loadCodeAssist] Failed: ${response.status} ${response.statusText}`);
|
|
649
|
-
continue;
|
|
650
|
-
}
|
|
651
|
-
const data = await response.json();
|
|
652
|
-
debugLog(`[loadCodeAssist] Success: ${JSON.stringify(data)}`);
|
|
653
|
-
return data;
|
|
654
|
-
} catch (err) {
|
|
655
|
-
debugLog(`[loadCodeAssist] Error: ${err}`);
|
|
656
|
-
continue;
|
|
657
|
-
}
|
|
658
|
-
}
|
|
659
|
-
debugLog(`[loadCodeAssist] All endpoints failed`);
|
|
660
|
-
return null;
|
|
661
|
-
}
|
|
662
|
-
async function onboardManagedProject(accessToken, tierId, projectId, attempts = 10, delayMs = 5000) {
|
|
663
|
-
debugLog(`[onboardUser] Starting with tierId=${tierId}, projectId=${projectId || "none"}`);
|
|
664
|
-
const metadata = { ...CODE_ASSIST_METADATA };
|
|
665
|
-
if (projectId)
|
|
666
|
-
metadata.duetProject = projectId;
|
|
667
|
-
const requestBody = { tierId, metadata };
|
|
668
|
-
if (!isFreeTier(tierId)) {
|
|
669
|
-
if (!projectId) {
|
|
670
|
-
debugLog(`[onboardUser] Non-FREE tier requires projectId, returning undefined`);
|
|
671
|
-
return;
|
|
672
|
-
}
|
|
673
|
-
requestBody.cloudaicompanionProject = projectId;
|
|
674
|
-
}
|
|
675
|
-
const headers = {
|
|
676
|
-
Authorization: `Bearer ${accessToken}`,
|
|
677
|
-
"Content-Type": "application/json",
|
|
678
|
-
"User-Agent": ANTIGRAVITY_HEADERS["User-Agent"],
|
|
679
|
-
"X-Goog-Api-Client": ANTIGRAVITY_HEADERS["X-Goog-Api-Client"],
|
|
680
|
-
"Client-Metadata": ANTIGRAVITY_HEADERS["Client-Metadata"]
|
|
681
|
-
};
|
|
682
|
-
debugLog(`[onboardUser] Request body: ${JSON.stringify(requestBody)}`);
|
|
683
|
-
for (let attempt = 0;attempt < attempts; attempt++) {
|
|
684
|
-
debugLog(`[onboardUser] Attempt ${attempt + 1}/${attempts}`);
|
|
685
|
-
for (const baseEndpoint of ANTIGRAVITY_ENDPOINT_FALLBACKS) {
|
|
686
|
-
const url = `${baseEndpoint}/${ANTIGRAVITY_API_VERSION}:onboardUser`;
|
|
687
|
-
debugLog(`[onboardUser] Trying: ${url}`);
|
|
688
|
-
try {
|
|
689
|
-
const response = await fetch(url, {
|
|
690
|
-
method: "POST",
|
|
691
|
-
headers,
|
|
692
|
-
body: JSON.stringify(requestBody)
|
|
693
|
-
});
|
|
694
|
-
if (!response.ok) {
|
|
695
|
-
const errorText = await response.text().catch(() => "");
|
|
696
|
-
debugLog(`[onboardUser] Failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
697
|
-
continue;
|
|
698
|
-
}
|
|
699
|
-
const payload = await response.json();
|
|
700
|
-
debugLog(`[onboardUser] Response: ${JSON.stringify(payload)}`);
|
|
701
|
-
const managedProjectId = payload.response?.cloudaicompanionProject?.id;
|
|
702
|
-
if (payload.done && managedProjectId) {
|
|
703
|
-
debugLog(`[onboardUser] Success! Got managed project ID: ${managedProjectId}`);
|
|
704
|
-
return managedProjectId;
|
|
705
|
-
}
|
|
706
|
-
if (payload.done && projectId) {
|
|
707
|
-
debugLog(`[onboardUser] Done but no managed ID, using original: ${projectId}`);
|
|
708
|
-
return projectId;
|
|
709
|
-
}
|
|
710
|
-
debugLog(`[onboardUser] Not done yet, payload.done=${payload.done}`);
|
|
711
|
-
} catch (err) {
|
|
712
|
-
debugLog(`[onboardUser] Error: ${err}`);
|
|
713
|
-
continue;
|
|
714
|
-
}
|
|
715
|
-
}
|
|
716
|
-
if (attempt < attempts - 1) {
|
|
717
|
-
debugLog(`[onboardUser] Waiting ${delayMs}ms before next attempt...`);
|
|
718
|
-
await wait(delayMs);
|
|
719
|
-
}
|
|
720
|
-
}
|
|
721
|
-
debugLog(`[onboardUser] All attempts exhausted, returning undefined`);
|
|
722
|
-
return;
|
|
723
|
-
}
|
|
724
|
-
async function fetchProjectContext(accessToken) {
|
|
725
|
-
debugLog(`[fetchProjectContext] Starting...`);
|
|
726
|
-
const cached = projectContextCache.get(accessToken);
|
|
727
|
-
if (cached) {
|
|
728
|
-
debugLog(`[fetchProjectContext] Returning cached result: ${JSON.stringify(cached)}`);
|
|
729
|
-
return cached;
|
|
730
|
-
}
|
|
731
|
-
const loadPayload = await callLoadCodeAssistAPI(accessToken);
|
|
732
|
-
if (loadPayload?.cloudaicompanionProject) {
|
|
733
|
-
const projectId = extractProjectId(loadPayload.cloudaicompanionProject);
|
|
734
|
-
debugLog(`[fetchProjectContext] loadCodeAssist returned project: ${projectId}`);
|
|
735
|
-
if (projectId) {
|
|
736
|
-
const result = { cloudaicompanionProject: projectId };
|
|
737
|
-
projectContextCache.set(accessToken, result);
|
|
738
|
-
debugLog(`[fetchProjectContext] Using loadCodeAssist project ID: ${projectId}`);
|
|
739
|
-
return result;
|
|
740
|
-
}
|
|
741
|
-
}
|
|
742
|
-
if (!loadPayload) {
|
|
743
|
-
debugLog(`[fetchProjectContext] loadCodeAssist returned null, trying with fallback project ID`);
|
|
744
|
-
const fallbackPayload = await callLoadCodeAssistAPI(accessToken, ANTIGRAVITY_DEFAULT_PROJECT_ID);
|
|
745
|
-
const fallbackProjectId = extractProjectId(fallbackPayload?.cloudaicompanionProject);
|
|
746
|
-
if (fallbackProjectId) {
|
|
747
|
-
const result = { cloudaicompanionProject: fallbackProjectId };
|
|
748
|
-
projectContextCache.set(accessToken, result);
|
|
749
|
-
debugLog(`[fetchProjectContext] Using fallback project ID: ${fallbackProjectId}`);
|
|
750
|
-
return result;
|
|
751
|
-
}
|
|
752
|
-
debugLog(`[fetchProjectContext] Fallback also failed, using default: ${ANTIGRAVITY_DEFAULT_PROJECT_ID}`);
|
|
753
|
-
return { cloudaicompanionProject: ANTIGRAVITY_DEFAULT_PROJECT_ID };
|
|
754
|
-
}
|
|
755
|
-
const currentTierId = loadPayload.currentTier?.id;
|
|
756
|
-
debugLog(`[fetchProjectContext] currentTier: ${currentTierId}, allowedTiers: ${JSON.stringify(loadPayload.allowedTiers)}`);
|
|
757
|
-
if (currentTierId && !isFreeTier(currentTierId)) {
|
|
758
|
-
debugLog(`[fetchProjectContext] PAID tier detected (${currentTierId}), using fallback: ${ANTIGRAVITY_DEFAULT_PROJECT_ID}`);
|
|
759
|
-
return { cloudaicompanionProject: ANTIGRAVITY_DEFAULT_PROJECT_ID };
|
|
760
|
-
}
|
|
761
|
-
const defaultTierId = getDefaultTierId(loadPayload.allowedTiers);
|
|
762
|
-
const tierId = defaultTierId ?? "free-tier";
|
|
763
|
-
debugLog(`[fetchProjectContext] Resolved tierId: ${tierId}`);
|
|
764
|
-
if (!isFreeTier(tierId)) {
|
|
765
|
-
debugLog(`[fetchProjectContext] Non-FREE tier (${tierId}) without project, using fallback: ${ANTIGRAVITY_DEFAULT_PROJECT_ID}`);
|
|
766
|
-
return { cloudaicompanionProject: ANTIGRAVITY_DEFAULT_PROJECT_ID };
|
|
767
|
-
}
|
|
768
|
-
debugLog(`[fetchProjectContext] FREE tier detected (${tierId}), calling onboardUser...`);
|
|
769
|
-
const managedProjectId = await onboardManagedProject(accessToken, tierId);
|
|
770
|
-
if (managedProjectId) {
|
|
771
|
-
const result = {
|
|
772
|
-
cloudaicompanionProject: managedProjectId,
|
|
773
|
-
managedProjectId
|
|
774
|
-
};
|
|
775
|
-
projectContextCache.set(accessToken, result);
|
|
776
|
-
debugLog(`[fetchProjectContext] Got managed project ID: ${managedProjectId}`);
|
|
777
|
-
return result;
|
|
778
|
-
}
|
|
779
|
-
debugLog(`[fetchProjectContext] Failed to get managed project ID, using fallback: ${ANTIGRAVITY_DEFAULT_PROJECT_ID}`);
|
|
780
|
-
return { cloudaicompanionProject: ANTIGRAVITY_DEFAULT_PROJECT_ID };
|
|
781
|
-
}
|
|
782
|
-
function clearProjectContextCache(accessToken) {
|
|
783
|
-
if (accessToken) {
|
|
784
|
-
projectContextCache.delete(accessToken);
|
|
785
|
-
} else {
|
|
786
|
-
projectContextCache.clear();
|
|
787
|
-
}
|
|
788
|
-
}
|
|
789
|
-
function invalidateProjectContextByRefreshToken(_refreshToken) {
|
|
790
|
-
projectContextCache.clear();
|
|
791
|
-
debugLog(`[invalidateProjectContextByRefreshToken] Cleared all project context cache due to refresh token invalidation`);
|
|
792
|
-
}
|
|
793
|
-
// src/auth/antigravity/request.ts
|
|
794
|
-
function buildRequestHeaders(accessToken) {
|
|
795
|
-
return {
|
|
796
|
-
Authorization: `Bearer ${accessToken}`,
|
|
797
|
-
"Content-Type": "application/json",
|
|
798
|
-
"User-Agent": ANTIGRAVITY_HEADERS["User-Agent"],
|
|
799
|
-
"X-Goog-Api-Client": ANTIGRAVITY_HEADERS["X-Goog-Api-Client"],
|
|
800
|
-
"Client-Metadata": ANTIGRAVITY_HEADERS["Client-Metadata"]
|
|
801
|
-
};
|
|
802
|
-
}
|
|
803
|
-
function extractModelFromBody(body) {
|
|
804
|
-
const model = body.model;
|
|
805
|
-
if (typeof model === "string" && model.trim()) {
|
|
806
|
-
return model.trim();
|
|
807
|
-
}
|
|
808
|
-
return;
|
|
809
|
-
}
|
|
810
|
-
function extractModelFromUrl(url) {
|
|
811
|
-
const match = url.match(/\/models\/([^:]+):/);
|
|
812
|
-
if (match && match[1]) {
|
|
813
|
-
return match[1];
|
|
814
|
-
}
|
|
815
|
-
return;
|
|
816
|
-
}
|
|
817
|
-
function extractActionFromUrl(url) {
|
|
818
|
-
const match = url.match(/\/models\/[^:]+:(\w+)/);
|
|
819
|
-
if (match && match[1]) {
|
|
820
|
-
return match[1];
|
|
821
|
-
}
|
|
822
|
-
return;
|
|
823
|
-
}
|
|
824
|
-
function buildAntigravityUrl(baseEndpoint, action, streaming) {
|
|
825
|
-
const query = streaming ? "?alt=sse" : "";
|
|
826
|
-
return `${baseEndpoint}/${ANTIGRAVITY_API_VERSION}:${action}${query}`;
|
|
827
|
-
}
|
|
828
|
-
function getDefaultEndpoint() {
|
|
829
|
-
return ANTIGRAVITY_ENDPOINT_FALLBACKS[0];
|
|
830
|
-
}
|
|
831
|
-
function generateRequestId() {
|
|
832
|
-
return `agent-${crypto.randomUUID()}`;
|
|
833
|
-
}
|
|
834
|
-
function injectSystemPrompt(wrappedBody) {
|
|
835
|
-
if (!wrappedBody.request || typeof wrappedBody.request !== "object") {
|
|
836
|
-
return;
|
|
837
|
-
}
|
|
838
|
-
const req = wrappedBody.request;
|
|
839
|
-
if (req.systemInstruction && typeof req.systemInstruction === "object") {
|
|
840
|
-
const existing = req.systemInstruction;
|
|
841
|
-
if (existing.parts && Array.isArray(existing.parts)) {
|
|
842
|
-
const firstPart = existing.parts[0];
|
|
843
|
-
if (firstPart && typeof firstPart === "object" && "text" in firstPart) {
|
|
844
|
-
const text = firstPart.text;
|
|
845
|
-
if (text.includes("<identity>")) {
|
|
846
|
-
return;
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
const newParts = [{ text: ANTIGRAVITY_SYSTEM_PROMPT }];
|
|
852
|
-
if (req.systemInstruction && typeof req.systemInstruction === "object") {
|
|
853
|
-
const existing = req.systemInstruction;
|
|
854
|
-
if (existing.parts && Array.isArray(existing.parts)) {
|
|
855
|
-
for (const part of existing.parts) {
|
|
856
|
-
if (part && typeof part === "object" && "text" in part) {
|
|
857
|
-
newParts.push(part);
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
}
|
|
861
|
-
}
|
|
862
|
-
req.systemInstruction = {
|
|
863
|
-
role: "user",
|
|
864
|
-
parts: newParts
|
|
865
|
-
};
|
|
866
|
-
}
|
|
867
|
-
function wrapRequestBody(body, projectId, modelName, sessionId) {
|
|
868
|
-
const requestPayload = { ...body };
|
|
869
|
-
delete requestPayload.model;
|
|
870
|
-
let normalizedModel = modelName;
|
|
871
|
-
if (normalizedModel.startsWith("antigravity-")) {
|
|
872
|
-
normalizedModel = normalizedModel.substring("antigravity-".length);
|
|
873
|
-
}
|
|
874
|
-
const apiModel = alias2ModelName(normalizedModel);
|
|
875
|
-
debugLog2(`[MODEL] input="${modelName}" \u2192 normalized="${normalizedModel}" \u2192 api="${apiModel}"`);
|
|
876
|
-
const requestObj = {
|
|
877
|
-
...requestPayload,
|
|
878
|
-
sessionId,
|
|
879
|
-
toolConfig: {
|
|
880
|
-
...requestPayload.toolConfig || {},
|
|
881
|
-
functionCallingConfig: {
|
|
882
|
-
mode: "VALIDATED"
|
|
883
|
-
}
|
|
884
|
-
}
|
|
885
|
-
};
|
|
886
|
-
delete requestObj.safetySettings;
|
|
887
|
-
const wrappedBody = {
|
|
888
|
-
project: projectId,
|
|
889
|
-
model: apiModel,
|
|
890
|
-
userAgent: "antigravity",
|
|
891
|
-
requestType: "agent",
|
|
892
|
-
requestId: generateRequestId(),
|
|
893
|
-
request: requestObj
|
|
894
|
-
};
|
|
895
|
-
injectSystemPrompt(wrappedBody);
|
|
896
|
-
return wrappedBody;
|
|
897
|
-
}
|
|
898
|
-
function debugLog2(message) {
|
|
899
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
900
|
-
console.log(`[antigravity-request] ${message}`);
|
|
901
|
-
}
|
|
902
|
-
}
|
|
903
|
-
function injectThoughtSignatureIntoFunctionCalls(body, signature) {
|
|
904
|
-
const effectiveSignature = signature || SKIP_THOUGHT_SIGNATURE_VALIDATOR;
|
|
905
|
-
debugLog2(`[TSIG][INJECT] signature=${effectiveSignature.substring(0, 30)}... (${signature ? "provided" : "default"})`);
|
|
906
|
-
debugLog2(`[TSIG][INJECT] body keys: ${Object.keys(body).join(", ")}`);
|
|
907
|
-
const contents = body.contents;
|
|
908
|
-
if (!contents || !Array.isArray(contents)) {
|
|
909
|
-
debugLog2(`[TSIG][INJECT] No contents array! Has messages: ${!!body.messages}`);
|
|
910
|
-
return body;
|
|
911
|
-
}
|
|
912
|
-
debugLog2(`[TSIG][INJECT] Found ${contents.length} content blocks`);
|
|
913
|
-
let injectedCount = 0;
|
|
914
|
-
const modifiedContents = contents.map((content) => {
|
|
915
|
-
if (!content.parts || !Array.isArray(content.parts)) {
|
|
916
|
-
return content;
|
|
917
|
-
}
|
|
918
|
-
const modifiedParts = content.parts.map((part) => {
|
|
919
|
-
if (part.functionCall && !part.thoughtSignature) {
|
|
920
|
-
injectedCount++;
|
|
921
|
-
return {
|
|
922
|
-
...part,
|
|
923
|
-
thoughtSignature: effectiveSignature
|
|
924
|
-
};
|
|
925
|
-
}
|
|
926
|
-
return part;
|
|
927
|
-
});
|
|
928
|
-
return { ...content, parts: modifiedParts };
|
|
929
|
-
});
|
|
930
|
-
debugLog2(`[TSIG][INJECT] injected signature into ${injectedCount} functionCall(s)`);
|
|
931
|
-
return { ...body, contents: modifiedContents };
|
|
932
|
-
}
|
|
933
|
-
function isStreamingRequest(url, body) {
|
|
934
|
-
const action = extractActionFromUrl(url);
|
|
935
|
-
if (action === "streamGenerateContent") {
|
|
936
|
-
return true;
|
|
937
|
-
}
|
|
938
|
-
if (body.stream === true) {
|
|
939
|
-
return true;
|
|
940
|
-
}
|
|
941
|
-
return false;
|
|
942
|
-
}
|
|
943
|
-
function transformRequest(options) {
|
|
944
|
-
const {
|
|
945
|
-
url,
|
|
946
|
-
body,
|
|
947
|
-
accessToken,
|
|
948
|
-
projectId,
|
|
949
|
-
sessionId,
|
|
950
|
-
modelName,
|
|
951
|
-
endpointOverride,
|
|
952
|
-
thoughtSignature
|
|
953
|
-
} = options;
|
|
954
|
-
const effectiveModel = modelName || extractModelFromBody(body) || extractModelFromUrl(url) || "gemini-3-pro-high";
|
|
955
|
-
const streaming = isStreamingRequest(url, body);
|
|
956
|
-
const action = streaming ? "streamGenerateContent" : "generateContent";
|
|
957
|
-
const endpoint = endpointOverride || getDefaultEndpoint();
|
|
958
|
-
const transformedUrl = buildAntigravityUrl(endpoint, action, streaming);
|
|
959
|
-
const headers = buildRequestHeaders(accessToken);
|
|
960
|
-
if (streaming) {
|
|
961
|
-
headers["Accept"] = "text/event-stream";
|
|
962
|
-
}
|
|
963
|
-
const bodyWithSignature = injectThoughtSignatureIntoFunctionCalls(body, thoughtSignature);
|
|
964
|
-
const wrappedBody = wrapRequestBody(bodyWithSignature, projectId, effectiveModel, sessionId);
|
|
965
|
-
return {
|
|
966
|
-
url: transformedUrl,
|
|
967
|
-
headers,
|
|
968
|
-
body: wrappedBody,
|
|
969
|
-
streaming
|
|
970
|
-
};
|
|
971
|
-
}
|
|
972
|
-
// src/auth/antigravity/response.ts
|
|
973
|
-
function extractUsageFromHeaders(headers) {
|
|
974
|
-
const cached = headers.get("x-antigravity-cached-content-token-count");
|
|
975
|
-
const total = headers.get("x-antigravity-total-token-count");
|
|
976
|
-
const prompt = headers.get("x-antigravity-prompt-token-count");
|
|
977
|
-
const candidates = headers.get("x-antigravity-candidates-token-count");
|
|
978
|
-
if (!cached && !total && !prompt && !candidates) {
|
|
979
|
-
return;
|
|
980
|
-
}
|
|
981
|
-
const usage = {};
|
|
982
|
-
if (cached) {
|
|
983
|
-
const parsed = parseInt(cached, 10);
|
|
984
|
-
if (!isNaN(parsed)) {
|
|
985
|
-
usage.cachedContentTokenCount = parsed;
|
|
986
|
-
}
|
|
987
|
-
}
|
|
988
|
-
if (total) {
|
|
989
|
-
const parsed = parseInt(total, 10);
|
|
990
|
-
if (!isNaN(parsed)) {
|
|
991
|
-
usage.totalTokenCount = parsed;
|
|
992
|
-
}
|
|
993
|
-
}
|
|
994
|
-
if (prompt) {
|
|
995
|
-
const parsed = parseInt(prompt, 10);
|
|
996
|
-
if (!isNaN(parsed)) {
|
|
997
|
-
usage.promptTokenCount = parsed;
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
if (candidates) {
|
|
1001
|
-
const parsed = parseInt(candidates, 10);
|
|
1002
|
-
if (!isNaN(parsed)) {
|
|
1003
|
-
usage.candidatesTokenCount = parsed;
|
|
1004
|
-
}
|
|
1005
|
-
}
|
|
1006
|
-
return Object.keys(usage).length > 0 ? usage : undefined;
|
|
1007
|
-
}
|
|
1008
|
-
function extractRetryAfterMs(response, errorBody) {
|
|
1009
|
-
const retryAfterHeader = response.headers.get("Retry-After");
|
|
1010
|
-
if (retryAfterHeader) {
|
|
1011
|
-
const seconds = parseFloat(retryAfterHeader);
|
|
1012
|
-
if (!isNaN(seconds) && seconds > 0) {
|
|
1013
|
-
return Math.ceil(seconds * 1000);
|
|
1014
|
-
}
|
|
1015
|
-
}
|
|
1016
|
-
const retryAfterMsHeader = response.headers.get("retry-after-ms");
|
|
1017
|
-
if (retryAfterMsHeader) {
|
|
1018
|
-
const ms = parseInt(retryAfterMsHeader, 10);
|
|
1019
|
-
if (!isNaN(ms) && ms > 0) {
|
|
1020
|
-
return ms;
|
|
1021
|
-
}
|
|
1022
|
-
}
|
|
1023
|
-
if (!errorBody) {
|
|
1024
|
-
return;
|
|
1025
|
-
}
|
|
1026
|
-
const error = errorBody.error;
|
|
1027
|
-
if (!error?.details || !Array.isArray(error.details)) {
|
|
1028
|
-
return;
|
|
1029
|
-
}
|
|
1030
|
-
const retryInfo = error.details.find((detail) => detail["@type"] === "type.googleapis.com/google.rpc.RetryInfo");
|
|
1031
|
-
if (!retryInfo?.retryDelay || typeof retryInfo.retryDelay !== "string") {
|
|
1032
|
-
return;
|
|
1033
|
-
}
|
|
1034
|
-
const match = retryInfo.retryDelay.match(/^([\d.]+)s$/);
|
|
1035
|
-
if (match?.[1]) {
|
|
1036
|
-
const seconds = parseFloat(match[1]);
|
|
1037
|
-
if (!isNaN(seconds) && seconds > 0) {
|
|
1038
|
-
return Math.ceil(seconds * 1000);
|
|
1039
|
-
}
|
|
1040
|
-
}
|
|
1041
|
-
return;
|
|
1042
|
-
}
|
|
1043
|
-
function parseErrorBody(text) {
|
|
1044
|
-
try {
|
|
1045
|
-
const parsed = JSON.parse(text);
|
|
1046
|
-
if (parsed.error && typeof parsed.error === "object") {
|
|
1047
|
-
const errorObj = parsed.error;
|
|
1048
|
-
return {
|
|
1049
|
-
message: String(errorObj.message || "Unknown error"),
|
|
1050
|
-
type: errorObj.type ? String(errorObj.type) : undefined,
|
|
1051
|
-
code: errorObj.code
|
|
1052
|
-
};
|
|
1053
|
-
}
|
|
1054
|
-
if (parsed.message && typeof parsed.message === "string") {
|
|
1055
|
-
return {
|
|
1056
|
-
message: parsed.message,
|
|
1057
|
-
type: parsed.type ? String(parsed.type) : undefined,
|
|
1058
|
-
code: parsed.code
|
|
1059
|
-
};
|
|
1060
|
-
}
|
|
1061
|
-
return;
|
|
1062
|
-
} catch {
|
|
1063
|
-
return {
|
|
1064
|
-
message: text || "Unknown error"
|
|
1065
|
-
};
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
async function transformResponse(response) {
|
|
1069
|
-
const headers = new Headers(response.headers);
|
|
1070
|
-
const usage = extractUsageFromHeaders(headers);
|
|
1071
|
-
if (!response.ok) {
|
|
1072
|
-
const text = await response.text();
|
|
1073
|
-
const error = parseErrorBody(text);
|
|
1074
|
-
const retryAfterMs = extractRetryAfterMs(response, error ? { error } : undefined);
|
|
1075
|
-
let errorBody;
|
|
1076
|
-
try {
|
|
1077
|
-
errorBody = JSON.parse(text);
|
|
1078
|
-
} catch {
|
|
1079
|
-
errorBody = { error: { message: text } };
|
|
1080
|
-
}
|
|
1081
|
-
const retryMs = extractRetryAfterMs(response, errorBody) ?? retryAfterMs;
|
|
1082
|
-
if (retryMs) {
|
|
1083
|
-
headers.set("Retry-After", String(Math.ceil(retryMs / 1000)));
|
|
1084
|
-
headers.set("retry-after-ms", String(retryMs));
|
|
1085
|
-
}
|
|
1086
|
-
return {
|
|
1087
|
-
response: new Response(text, {
|
|
1088
|
-
status: response.status,
|
|
1089
|
-
statusText: response.statusText,
|
|
1090
|
-
headers
|
|
1091
|
-
}),
|
|
1092
|
-
usage,
|
|
1093
|
-
retryAfterMs: retryMs,
|
|
1094
|
-
error
|
|
1095
|
-
};
|
|
1096
|
-
}
|
|
1097
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
1098
|
-
const isJson = contentType.includes("application/json");
|
|
1099
|
-
if (!isJson) {
|
|
1100
|
-
return { response, usage };
|
|
1101
|
-
}
|
|
1102
|
-
try {
|
|
1103
|
-
const text = await response.text();
|
|
1104
|
-
const parsed = JSON.parse(text);
|
|
1105
|
-
let transformedBody = parsed;
|
|
1106
|
-
if (parsed.response !== undefined) {
|
|
1107
|
-
transformedBody = parsed.response;
|
|
1108
|
-
}
|
|
1109
|
-
return {
|
|
1110
|
-
response: new Response(JSON.stringify(transformedBody), {
|
|
1111
|
-
status: response.status,
|
|
1112
|
-
statusText: response.statusText,
|
|
1113
|
-
headers
|
|
1114
|
-
}),
|
|
1115
|
-
usage
|
|
1116
|
-
};
|
|
1117
|
-
} catch {
|
|
1118
|
-
return { response, usage };
|
|
1119
|
-
}
|
|
1120
|
-
}
|
|
1121
|
-
function transformSseLine(line) {
|
|
1122
|
-
if (!line.startsWith("data:")) {
|
|
1123
|
-
return line;
|
|
1124
|
-
}
|
|
1125
|
-
const json = line.slice(5).trim();
|
|
1126
|
-
if (!json || json === "[DONE]") {
|
|
1127
|
-
return line;
|
|
1128
|
-
}
|
|
1129
|
-
try {
|
|
1130
|
-
const parsed = JSON.parse(json);
|
|
1131
|
-
if (parsed.response !== undefined) {
|
|
1132
|
-
return `data: ${JSON.stringify(parsed.response)}`;
|
|
1133
|
-
}
|
|
1134
|
-
return line;
|
|
1135
|
-
} catch {
|
|
1136
|
-
return line;
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
function createSseTransformStream() {
|
|
1140
|
-
const decoder = new TextDecoder;
|
|
1141
|
-
const encoder = new TextEncoder;
|
|
1142
|
-
let buffer = "";
|
|
1143
|
-
return new TransformStream({
|
|
1144
|
-
transform(chunk, controller) {
|
|
1145
|
-
buffer += decoder.decode(chunk, { stream: true });
|
|
1146
|
-
const lines = buffer.split(`
|
|
1147
|
-
`);
|
|
1148
|
-
buffer = lines.pop() || "";
|
|
1149
|
-
for (const line of lines) {
|
|
1150
|
-
const transformed = transformSseLine(line);
|
|
1151
|
-
controller.enqueue(encoder.encode(transformed + `
|
|
1152
|
-
`));
|
|
1153
|
-
}
|
|
1154
|
-
},
|
|
1155
|
-
flush(controller) {
|
|
1156
|
-
if (buffer) {
|
|
1157
|
-
const transformed = transformSseLine(buffer);
|
|
1158
|
-
controller.enqueue(encoder.encode(transformed));
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
});
|
|
1162
|
-
}
|
|
1163
|
-
async function transformStreamingResponse(response) {
|
|
1164
|
-
const headers = new Headers(response.headers);
|
|
1165
|
-
const usage = extractUsageFromHeaders(headers);
|
|
1166
|
-
if (!response.ok) {
|
|
1167
|
-
const text = await response.text();
|
|
1168
|
-
const error = parseErrorBody(text);
|
|
1169
|
-
let errorBody;
|
|
1170
|
-
try {
|
|
1171
|
-
errorBody = JSON.parse(text);
|
|
1172
|
-
} catch {
|
|
1173
|
-
errorBody = { error: { message: text } };
|
|
1174
|
-
}
|
|
1175
|
-
const retryAfterMs = extractRetryAfterMs(response, errorBody);
|
|
1176
|
-
if (retryAfterMs) {
|
|
1177
|
-
headers.set("Retry-After", String(Math.ceil(retryAfterMs / 1000)));
|
|
1178
|
-
headers.set("retry-after-ms", String(retryAfterMs));
|
|
1179
|
-
}
|
|
1180
|
-
return {
|
|
1181
|
-
response: new Response(text, {
|
|
1182
|
-
status: response.status,
|
|
1183
|
-
statusText: response.statusText,
|
|
1184
|
-
headers
|
|
1185
|
-
}),
|
|
1186
|
-
usage,
|
|
1187
|
-
retryAfterMs,
|
|
1188
|
-
error
|
|
1189
|
-
};
|
|
1190
|
-
}
|
|
1191
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
1192
|
-
const isEventStream = contentType.includes("text/event-stream") || response.url.includes("alt=sse");
|
|
1193
|
-
if (!isEventStream) {
|
|
1194
|
-
const text = await response.text();
|
|
1195
|
-
try {
|
|
1196
|
-
const parsed = JSON.parse(text);
|
|
1197
|
-
let transformedBody2 = parsed;
|
|
1198
|
-
if (parsed.response !== undefined) {
|
|
1199
|
-
transformedBody2 = parsed.response;
|
|
1200
|
-
}
|
|
1201
|
-
return {
|
|
1202
|
-
response: new Response(JSON.stringify(transformedBody2), {
|
|
1203
|
-
status: response.status,
|
|
1204
|
-
statusText: response.statusText,
|
|
1205
|
-
headers
|
|
1206
|
-
}),
|
|
1207
|
-
usage
|
|
1208
|
-
};
|
|
1209
|
-
} catch {
|
|
1210
|
-
return {
|
|
1211
|
-
response: new Response(text, {
|
|
1212
|
-
status: response.status,
|
|
1213
|
-
statusText: response.statusText,
|
|
1214
|
-
headers
|
|
1215
|
-
}),
|
|
1216
|
-
usage
|
|
1217
|
-
};
|
|
1218
|
-
}
|
|
1219
|
-
}
|
|
1220
|
-
if (!response.body) {
|
|
1221
|
-
return { response, usage };
|
|
1222
|
-
}
|
|
1223
|
-
headers.delete("content-length");
|
|
1224
|
-
headers.delete("content-encoding");
|
|
1225
|
-
headers.set("content-type", "text/event-stream; charset=utf-8");
|
|
1226
|
-
const transformStream = createSseTransformStream();
|
|
1227
|
-
const transformedBody = response.body.pipeThrough(transformStream);
|
|
1228
|
-
return {
|
|
1229
|
-
response: new Response(transformedBody, {
|
|
1230
|
-
status: response.status,
|
|
1231
|
-
statusText: response.statusText,
|
|
1232
|
-
headers
|
|
1233
|
-
}),
|
|
1234
|
-
usage
|
|
1235
|
-
};
|
|
1236
|
-
}
|
|
1237
|
-
function isStreamingResponse(response) {
|
|
1238
|
-
const contentType = response.headers.get("content-type") ?? "";
|
|
1239
|
-
return contentType.includes("text/event-stream") || response.url.includes("alt=sse");
|
|
1240
|
-
}
|
|
1241
|
-
// src/auth/antigravity/tools.ts
|
|
1242
|
-
function normalizeToolsForGemini(tools) {
|
|
1243
|
-
if (!tools || tools.length === 0) {
|
|
1244
|
-
return;
|
|
1245
|
-
}
|
|
1246
|
-
const functionDeclarations = [];
|
|
1247
|
-
for (const tool of tools) {
|
|
1248
|
-
if (!tool || typeof tool !== "object") {
|
|
1249
|
-
continue;
|
|
1250
|
-
}
|
|
1251
|
-
const toolType = tool.type ?? "function";
|
|
1252
|
-
if (toolType === "function" && tool.function) {
|
|
1253
|
-
const declaration = {
|
|
1254
|
-
name: tool.function.name
|
|
1255
|
-
};
|
|
1256
|
-
if (tool.function.description) {
|
|
1257
|
-
declaration.description = tool.function.description;
|
|
1258
|
-
}
|
|
1259
|
-
if (tool.function.parameters) {
|
|
1260
|
-
declaration.parameters = tool.function.parameters;
|
|
1261
|
-
} else {
|
|
1262
|
-
declaration.parameters = { type: "object", properties: {} };
|
|
1263
|
-
}
|
|
1264
|
-
functionDeclarations.push(declaration);
|
|
1265
|
-
} else if (toolType !== "function" && process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
1266
|
-
console.warn(`[antigravity-tools] Unsupported tool type: "${toolType}". Tool will be skipped.`);
|
|
1267
|
-
}
|
|
1268
|
-
}
|
|
1269
|
-
if (functionDeclarations.length === 0) {
|
|
1270
|
-
return;
|
|
1271
|
-
}
|
|
1272
|
-
return { functionDeclarations };
|
|
1273
|
-
}
|
|
1274
|
-
// src/auth/antigravity/thinking.ts
|
|
1275
|
-
var DEFAULT_THINKING_BUDGET = 16000;
|
|
1276
|
-
function shouldIncludeThinking(model) {
|
|
1277
|
-
if (!model || typeof model !== "string") {
|
|
1278
|
-
return false;
|
|
1279
|
-
}
|
|
1280
|
-
const lowerModel = model.toLowerCase();
|
|
1281
|
-
if (lowerModel.endsWith("-high")) {
|
|
1282
|
-
return true;
|
|
1283
|
-
}
|
|
1284
|
-
if (lowerModel.includes("thinking")) {
|
|
1285
|
-
return true;
|
|
1286
|
-
}
|
|
1287
|
-
return false;
|
|
1288
|
-
}
|
|
1289
|
-
function isThinkingPart(part) {
|
|
1290
|
-
if (part.thought === true) {
|
|
1291
|
-
return true;
|
|
1292
|
-
}
|
|
1293
|
-
if (part.type === "thinking" || part.type === "reasoning") {
|
|
1294
|
-
return true;
|
|
1295
|
-
}
|
|
1296
|
-
return false;
|
|
1297
|
-
}
|
|
1298
|
-
function extractThinkingBlocks(response) {
|
|
1299
|
-
const thinkingBlocks = [];
|
|
1300
|
-
if (response.candidates && Array.isArray(response.candidates)) {
|
|
1301
|
-
for (const candidate of response.candidates) {
|
|
1302
|
-
const parts = candidate.content?.parts;
|
|
1303
|
-
if (!parts || !Array.isArray(parts)) {
|
|
1304
|
-
continue;
|
|
1305
|
-
}
|
|
1306
|
-
for (let i = 0;i < parts.length; i++) {
|
|
1307
|
-
const part = parts[i];
|
|
1308
|
-
if (!part || typeof part !== "object") {
|
|
1309
|
-
continue;
|
|
1310
|
-
}
|
|
1311
|
-
if (isThinkingPart(part)) {
|
|
1312
|
-
const block = {
|
|
1313
|
-
text: part.text || "",
|
|
1314
|
-
index: thinkingBlocks.length
|
|
1315
|
-
};
|
|
1316
|
-
if (part.thought === true && part.thoughtSignature) {
|
|
1317
|
-
block.signature = part.thoughtSignature;
|
|
1318
|
-
} else if (part.signature) {
|
|
1319
|
-
block.signature = part.signature;
|
|
1320
|
-
}
|
|
1321
|
-
thinkingBlocks.push(block);
|
|
1322
|
-
}
|
|
1323
|
-
}
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
if (response.content && Array.isArray(response.content)) {
|
|
1327
|
-
for (let i = 0;i < response.content.length; i++) {
|
|
1328
|
-
const item = response.content[i];
|
|
1329
|
-
if (!item || typeof item !== "object") {
|
|
1330
|
-
continue;
|
|
1331
|
-
}
|
|
1332
|
-
if (item.type === "thinking" || item.type === "reasoning") {
|
|
1333
|
-
thinkingBlocks.push({
|
|
1334
|
-
text: item.text || "",
|
|
1335
|
-
signature: item.signature,
|
|
1336
|
-
index: thinkingBlocks.length
|
|
1337
|
-
});
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
}
|
|
1341
|
-
const combinedThinking = thinkingBlocks.map((b) => b.text).join(`
|
|
1342
|
-
|
|
1343
|
-
`);
|
|
1344
|
-
return {
|
|
1345
|
-
thinkingBlocks,
|
|
1346
|
-
combinedThinking,
|
|
1347
|
-
hasThinking: thinkingBlocks.length > 0
|
|
1348
|
-
};
|
|
1349
|
-
}
|
|
1350
|
-
function transformCandidateThinking(candidate) {
|
|
1351
|
-
if (!candidate || typeof candidate !== "object") {
|
|
1352
|
-
return candidate;
|
|
1353
|
-
}
|
|
1354
|
-
const content = candidate.content;
|
|
1355
|
-
if (!content || typeof content !== "object" || !Array.isArray(content.parts)) {
|
|
1356
|
-
return candidate;
|
|
1357
|
-
}
|
|
1358
|
-
const thinkingTexts = [];
|
|
1359
|
-
const transformedParts = content.parts.map((part) => {
|
|
1360
|
-
if (part && typeof part === "object" && part.thought === true) {
|
|
1361
|
-
thinkingTexts.push(part.text || "");
|
|
1362
|
-
return {
|
|
1363
|
-
...part,
|
|
1364
|
-
type: "reasoning",
|
|
1365
|
-
thought: undefined
|
|
1366
|
-
};
|
|
1367
|
-
}
|
|
1368
|
-
return part;
|
|
1369
|
-
});
|
|
1370
|
-
const result = {
|
|
1371
|
-
...candidate,
|
|
1372
|
-
content: { ...content, parts: transformedParts }
|
|
1373
|
-
};
|
|
1374
|
-
if (thinkingTexts.length > 0) {
|
|
1375
|
-
result.reasoning_content = thinkingTexts.join(`
|
|
1376
|
-
|
|
1377
|
-
`);
|
|
1378
|
-
}
|
|
1379
|
-
return result;
|
|
1380
|
-
}
|
|
1381
|
-
function transformAnthropicThinking(content) {
|
|
1382
|
-
if (!content || !Array.isArray(content)) {
|
|
1383
|
-
return content;
|
|
1384
|
-
}
|
|
1385
|
-
return content.map((block) => {
|
|
1386
|
-
if (block && typeof block === "object" && block.type === "thinking") {
|
|
1387
|
-
return {
|
|
1388
|
-
type: "reasoning",
|
|
1389
|
-
text: block.text || "",
|
|
1390
|
-
...block.signature ? { signature: block.signature } : {}
|
|
1391
|
-
};
|
|
1392
|
-
}
|
|
1393
|
-
return block;
|
|
1394
|
-
});
|
|
1395
|
-
}
|
|
1396
|
-
function transformResponseThinking(response) {
|
|
1397
|
-
if (!response || typeof response !== "object") {
|
|
1398
|
-
return response;
|
|
1399
|
-
}
|
|
1400
|
-
const result = { ...response };
|
|
1401
|
-
if (Array.isArray(result.candidates)) {
|
|
1402
|
-
result.candidates = result.candidates.map(transformCandidateThinking);
|
|
1403
|
-
}
|
|
1404
|
-
if (Array.isArray(result.content)) {
|
|
1405
|
-
result.content = transformAnthropicThinking(result.content);
|
|
1406
|
-
}
|
|
1407
|
-
return result;
|
|
1408
|
-
}
|
|
1409
|
-
function extractThinkingConfig(requestPayload, generationConfig, extraBody) {
|
|
1410
|
-
const thinkingConfig = generationConfig?.thinkingConfig ?? extraBody?.thinkingConfig ?? requestPayload.thinkingConfig;
|
|
1411
|
-
if (thinkingConfig && typeof thinkingConfig === "object") {
|
|
1412
|
-
const config = thinkingConfig;
|
|
1413
|
-
return {
|
|
1414
|
-
includeThoughts: Boolean(config.includeThoughts),
|
|
1415
|
-
thinkingBudget: typeof config.thinkingBudget === "number" ? config.thinkingBudget : DEFAULT_THINKING_BUDGET
|
|
1416
|
-
};
|
|
1417
|
-
}
|
|
1418
|
-
const anthropicThinking = extraBody?.thinking ?? requestPayload.thinking;
|
|
1419
|
-
if (anthropicThinking && typeof anthropicThinking === "object") {
|
|
1420
|
-
const thinking = anthropicThinking;
|
|
1421
|
-
if (thinking.type === "enabled" || thinking.budgetTokens) {
|
|
1422
|
-
return {
|
|
1423
|
-
includeThoughts: true,
|
|
1424
|
-
thinkingBudget: typeof thinking.budgetTokens === "number" ? thinking.budgetTokens : DEFAULT_THINKING_BUDGET
|
|
1425
|
-
};
|
|
1426
|
-
}
|
|
1427
|
-
}
|
|
1428
|
-
const reasoningEffort = requestPayload.reasoning_effort ?? extraBody?.reasoning_effort;
|
|
1429
|
-
if (reasoningEffort && typeof reasoningEffort === "string") {
|
|
1430
|
-
const budget = REASONING_EFFORT_BUDGET_MAP[reasoningEffort];
|
|
1431
|
-
if (budget !== undefined) {
|
|
1432
|
-
if (reasoningEffort === "none") {
|
|
1433
|
-
return { deleteThinkingConfig: true };
|
|
1434
|
-
}
|
|
1435
|
-
return {
|
|
1436
|
-
includeThoughts: true,
|
|
1437
|
-
thinkingBudget: budget
|
|
1438
|
-
};
|
|
1439
|
-
}
|
|
1440
|
-
}
|
|
1441
|
-
return;
|
|
1442
|
-
}
|
|
1443
|
-
function getModelThinkingConfig(model) {
|
|
1444
|
-
const normalized = normalizeModelId(model);
|
|
1445
|
-
if (ANTIGRAVITY_MODEL_CONFIGS[normalized]) {
|
|
1446
|
-
return ANTIGRAVITY_MODEL_CONFIGS[normalized];
|
|
1447
|
-
}
|
|
1448
|
-
if (normalized.includes("gemini-3")) {
|
|
1449
|
-
return {
|
|
1450
|
-
thinkingType: "levels",
|
|
1451
|
-
min: 128,
|
|
1452
|
-
max: 32768,
|
|
1453
|
-
zeroAllowed: false,
|
|
1454
|
-
levels: ["low", "high"]
|
|
1455
|
-
};
|
|
1456
|
-
}
|
|
1457
|
-
if (normalized.includes("gemini-2.5")) {
|
|
1458
|
-
return {
|
|
1459
|
-
thinkingType: "numeric",
|
|
1460
|
-
min: 0,
|
|
1461
|
-
max: 24576,
|
|
1462
|
-
zeroAllowed: true
|
|
1463
|
-
};
|
|
1464
|
-
}
|
|
1465
|
-
if (normalized.includes("claude")) {
|
|
1466
|
-
return {
|
|
1467
|
-
thinkingType: "numeric",
|
|
1468
|
-
min: 1024,
|
|
1469
|
-
max: 200000,
|
|
1470
|
-
zeroAllowed: false
|
|
1471
|
-
};
|
|
1472
|
-
}
|
|
1473
|
-
return;
|
|
1474
|
-
}
|
|
1475
|
-
function budgetToLevel(budget, model) {
|
|
1476
|
-
const config = getModelThinkingConfig(model);
|
|
1477
|
-
if (!config?.levels) {
|
|
1478
|
-
return "medium";
|
|
1479
|
-
}
|
|
1480
|
-
const budgetMap = {
|
|
1481
|
-
512: "minimal",
|
|
1482
|
-
1024: "low",
|
|
1483
|
-
8192: "medium",
|
|
1484
|
-
24576: "high"
|
|
1485
|
-
};
|
|
1486
|
-
if (budgetMap[budget]) {
|
|
1487
|
-
return budgetMap[budget];
|
|
1488
|
-
}
|
|
1489
|
-
return config.levels[config.levels.length - 1] || "high";
|
|
1490
|
-
}
|
|
1491
|
-
function applyThinkingConfigToRequest(requestBody, model, config) {
|
|
1492
|
-
if ("deleteThinkingConfig" in config && config.deleteThinkingConfig) {
|
|
1493
|
-
if (requestBody.request && typeof requestBody.request === "object") {
|
|
1494
|
-
const req2 = requestBody.request;
|
|
1495
|
-
if (req2.generationConfig && typeof req2.generationConfig === "object") {
|
|
1496
|
-
const genConfig2 = req2.generationConfig;
|
|
1497
|
-
delete genConfig2.thinkingConfig;
|
|
1498
|
-
}
|
|
1499
|
-
}
|
|
1500
|
-
return;
|
|
1501
|
-
}
|
|
1502
|
-
const modelConfig = getModelThinkingConfig(model);
|
|
1503
|
-
if (!modelConfig) {
|
|
1504
|
-
return;
|
|
1505
|
-
}
|
|
1506
|
-
if (!requestBody.request || typeof requestBody.request !== "object") {
|
|
1507
|
-
return;
|
|
1508
|
-
}
|
|
1509
|
-
const req = requestBody.request;
|
|
1510
|
-
if (!req.generationConfig || typeof req.generationConfig !== "object") {
|
|
1511
|
-
req.generationConfig = {};
|
|
1512
|
-
}
|
|
1513
|
-
const genConfig = req.generationConfig;
|
|
1514
|
-
genConfig.thinkingConfig = {};
|
|
1515
|
-
const thinkingConfig = genConfig.thinkingConfig;
|
|
1516
|
-
thinkingConfig.include_thoughts = true;
|
|
1517
|
-
if (modelConfig.thinkingType === "numeric") {
|
|
1518
|
-
thinkingConfig.thinkingBudget = config.thinkingBudget;
|
|
1519
|
-
} else if (modelConfig.thinkingType === "levels") {
|
|
1520
|
-
const budget = config.thinkingBudget ?? DEFAULT_THINKING_BUDGET;
|
|
1521
|
-
let level = budgetToLevel(budget, model);
|
|
1522
|
-
level = level.toLowerCase();
|
|
1523
|
-
thinkingConfig.thinkingLevel = level;
|
|
1524
|
-
}
|
|
1525
|
-
}
|
|
1526
|
-
// src/auth/antigravity/thought-signature-store.ts
|
|
1527
|
-
var signatureStore = new Map;
|
|
1528
|
-
var sessionIdStore = new Map;
|
|
1529
|
-
function setThoughtSignature(sessionKey, signature) {
|
|
1530
|
-
if (sessionKey && signature) {
|
|
1531
|
-
signatureStore.set(sessionKey, signature);
|
|
1532
|
-
}
|
|
1533
|
-
}
|
|
1534
|
-
function getThoughtSignature(sessionKey) {
|
|
1535
|
-
return signatureStore.get(sessionKey);
|
|
1536
|
-
}
|
|
1537
|
-
function getOrCreateSessionId(fetchInstanceId, sessionId) {
|
|
1538
|
-
if (sessionId) {
|
|
1539
|
-
sessionIdStore.set(fetchInstanceId, sessionId);
|
|
1540
|
-
return sessionId;
|
|
1541
|
-
}
|
|
1542
|
-
const existing = sessionIdStore.get(fetchInstanceId);
|
|
1543
|
-
if (existing) {
|
|
1544
|
-
return existing;
|
|
1545
|
-
}
|
|
1546
|
-
const n = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
|
|
1547
|
-
const newSessionId = `-${n}`;
|
|
1548
|
-
sessionIdStore.set(fetchInstanceId, newSessionId);
|
|
1549
|
-
return newSessionId;
|
|
1550
|
-
}
|
|
1551
|
-
// src/auth/antigravity/message-converter.ts
|
|
1552
|
-
function debugLog3(message) {
|
|
1553
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
1554
|
-
console.log(`[antigravity-converter] ${message}`);
|
|
1555
|
-
}
|
|
1556
|
-
}
|
|
1557
|
-
function convertOpenAIToGemini(messages, thoughtSignature) {
|
|
1558
|
-
debugLog3(`Converting ${messages.length} messages, signature: ${thoughtSignature ? "present" : "none"}`);
|
|
1559
|
-
const contents = [];
|
|
1560
|
-
for (const msg of messages) {
|
|
1561
|
-
if (msg.role === "system") {
|
|
1562
|
-
contents.push({
|
|
1563
|
-
role: "user",
|
|
1564
|
-
parts: [{ text: typeof msg.content === "string" ? msg.content : "" }]
|
|
1565
|
-
});
|
|
1566
|
-
continue;
|
|
1567
|
-
}
|
|
1568
|
-
if (msg.role === "user") {
|
|
1569
|
-
const parts = convertContentToParts(msg.content);
|
|
1570
|
-
contents.push({ role: "user", parts });
|
|
1571
|
-
continue;
|
|
1572
|
-
}
|
|
1573
|
-
if (msg.role === "assistant") {
|
|
1574
|
-
const parts = [];
|
|
1575
|
-
if (msg.content) {
|
|
1576
|
-
parts.push(...convertContentToParts(msg.content));
|
|
1577
|
-
}
|
|
1578
|
-
if (msg.tool_calls && msg.tool_calls.length > 0) {
|
|
1579
|
-
for (const toolCall of msg.tool_calls) {
|
|
1580
|
-
let args = {};
|
|
1581
|
-
try {
|
|
1582
|
-
args = JSON.parse(toolCall.function.arguments);
|
|
1583
|
-
} catch {
|
|
1584
|
-
args = {};
|
|
1585
|
-
}
|
|
1586
|
-
const part = {
|
|
1587
|
-
functionCall: {
|
|
1588
|
-
name: toolCall.function.name,
|
|
1589
|
-
args
|
|
1590
|
-
}
|
|
1591
|
-
};
|
|
1592
|
-
part.thoughtSignature = thoughtSignature || SKIP_THOUGHT_SIGNATURE_VALIDATOR;
|
|
1593
|
-
debugLog3(`Injected signature into functionCall: ${toolCall.function.name} (${thoughtSignature ? "provided" : "default"})`);
|
|
1594
|
-
parts.push(part);
|
|
1595
|
-
}
|
|
1596
|
-
}
|
|
1597
|
-
if (parts.length > 0) {
|
|
1598
|
-
contents.push({ role: "model", parts });
|
|
1599
|
-
}
|
|
1600
|
-
continue;
|
|
1601
|
-
}
|
|
1602
|
-
if (msg.role === "tool") {
|
|
1603
|
-
let response = {};
|
|
1604
|
-
try {
|
|
1605
|
-
response = typeof msg.content === "string" ? JSON.parse(msg.content) : { result: msg.content };
|
|
1606
|
-
} catch {
|
|
1607
|
-
response = { result: msg.content };
|
|
1608
|
-
}
|
|
1609
|
-
const toolName = msg.name || "unknown";
|
|
1610
|
-
contents.push({
|
|
1611
|
-
role: "user",
|
|
1612
|
-
parts: [{
|
|
1613
|
-
functionResponse: {
|
|
1614
|
-
name: toolName,
|
|
1615
|
-
response
|
|
1616
|
-
}
|
|
1617
|
-
}]
|
|
1618
|
-
});
|
|
1619
|
-
continue;
|
|
1620
|
-
}
|
|
1621
|
-
}
|
|
1622
|
-
debugLog3(`Converted to ${contents.length} content blocks`);
|
|
1623
|
-
return contents;
|
|
1624
|
-
}
|
|
1625
|
-
function convertContentToParts(content) {
|
|
1626
|
-
if (!content) {
|
|
1627
|
-
return [{ text: "" }];
|
|
1628
|
-
}
|
|
1629
|
-
if (typeof content === "string") {
|
|
1630
|
-
return [{ text: content }];
|
|
1631
|
-
}
|
|
1632
|
-
const parts = [];
|
|
1633
|
-
for (const part of content) {
|
|
1634
|
-
if (part.type === "text" && part.text) {
|
|
1635
|
-
parts.push({ text: part.text });
|
|
1636
|
-
} else if (part.type === "image_url" && part.image_url?.url) {
|
|
1637
|
-
const url = part.image_url.url;
|
|
1638
|
-
if (url.startsWith("data:")) {
|
|
1639
|
-
const match = url.match(/^data:([^;]+);base64,(.+)$/);
|
|
1640
|
-
if (match) {
|
|
1641
|
-
parts.push({
|
|
1642
|
-
inlineData: {
|
|
1643
|
-
mimeType: match[1],
|
|
1644
|
-
data: match[2]
|
|
1645
|
-
}
|
|
1646
|
-
});
|
|
1647
|
-
}
|
|
1648
|
-
}
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
return parts.length > 0 ? parts : [{ text: "" }];
|
|
1652
|
-
}
|
|
1653
|
-
function hasOpenAIMessages(body) {
|
|
1654
|
-
return Array.isArray(body.messages) && body.messages.length > 0;
|
|
1655
|
-
}
|
|
1656
|
-
function convertRequestBody(body, thoughtSignature) {
|
|
1657
|
-
if (!hasOpenAIMessages(body)) {
|
|
1658
|
-
debugLog3("No messages array found, returning body as-is");
|
|
1659
|
-
return body;
|
|
1660
|
-
}
|
|
1661
|
-
const messages = body.messages;
|
|
1662
|
-
const contents = convertOpenAIToGemini(messages, thoughtSignature);
|
|
1663
|
-
const converted = { ...body };
|
|
1664
|
-
delete converted.messages;
|
|
1665
|
-
converted.contents = contents;
|
|
1666
|
-
debugLog3(`Converted body: messages \u2192 contents (${contents.length} blocks)`);
|
|
1667
|
-
return converted;
|
|
1668
|
-
}
|
|
1669
|
-
// src/auth/antigravity/storage.ts
|
|
1670
|
-
import { promises as fs } from "fs";
|
|
1671
|
-
import { join as join2, dirname } from "path";
|
|
1672
|
-
|
|
1673
|
-
// src/shared/data-path.ts
|
|
1674
|
-
import * as path from "path";
|
|
1675
|
-
import * as os from "os";
|
|
1676
|
-
function getDataDir() {
|
|
1677
|
-
return process.env.XDG_DATA_HOME ?? path.join(os.homedir(), ".local", "share");
|
|
1678
|
-
}
|
|
1679
|
-
function getOpenCodeStorageDir() {
|
|
1680
|
-
return path.join(getDataDir(), "opencode", "storage");
|
|
1681
|
-
}
|
|
1682
|
-
|
|
1683
|
-
// src/auth/antigravity/storage.ts
|
|
1684
|
-
function getDataDir2() {
|
|
1685
|
-
return join2(getDataDir(), "opencode");
|
|
1686
|
-
}
|
|
1687
|
-
function getStoragePath() {
|
|
1688
|
-
return join2(getDataDir2(), "oh-my-opencode-accounts.json");
|
|
1689
|
-
}
|
|
1690
|
-
async function loadAccounts(path2) {
|
|
1691
|
-
const storagePath = path2 ?? getStoragePath();
|
|
1692
|
-
try {
|
|
1693
|
-
const content = await fs.readFile(storagePath, "utf-8");
|
|
1694
|
-
const data = JSON.parse(content);
|
|
1695
|
-
if (!isValidAccountStorage(data)) {
|
|
1696
|
-
return null;
|
|
1697
|
-
}
|
|
1698
|
-
return data;
|
|
1699
|
-
} catch (error) {
|
|
1700
|
-
const errorCode = error.code;
|
|
1701
|
-
if (errorCode === "ENOENT") {
|
|
1702
|
-
return null;
|
|
1703
|
-
}
|
|
1704
|
-
if (error instanceof SyntaxError) {
|
|
1705
|
-
return null;
|
|
1706
|
-
}
|
|
1707
|
-
throw error;
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
async function saveAccounts(storage, path2) {
|
|
1711
|
-
const storagePath = path2 ?? getStoragePath();
|
|
1712
|
-
await fs.mkdir(dirname(storagePath), { recursive: true });
|
|
1713
|
-
const content = JSON.stringify(storage, null, 2);
|
|
1714
|
-
const tempPath = `${storagePath}.tmp.${process.pid}.${Date.now()}`;
|
|
1715
|
-
await fs.writeFile(tempPath, content, { encoding: "utf-8", mode: 384 });
|
|
1716
|
-
try {
|
|
1717
|
-
await fs.rename(tempPath, storagePath);
|
|
1718
|
-
} catch (error) {
|
|
1719
|
-
await fs.unlink(tempPath).catch(() => {});
|
|
1720
|
-
throw error;
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
function isValidAccountStorage(data) {
|
|
1724
|
-
if (typeof data !== "object" || data === null) {
|
|
1725
|
-
return false;
|
|
1726
|
-
}
|
|
1727
|
-
const obj = data;
|
|
1728
|
-
if (typeof obj.version !== "number") {
|
|
1729
|
-
return false;
|
|
1730
|
-
}
|
|
1731
|
-
if (!Array.isArray(obj.accounts)) {
|
|
1732
|
-
return false;
|
|
1733
|
-
}
|
|
1734
|
-
if (typeof obj.activeIndex !== "number") {
|
|
1735
|
-
return false;
|
|
1736
|
-
}
|
|
1737
|
-
return true;
|
|
1738
|
-
}
|
|
1739
|
-
|
|
1740
|
-
// src/auth/antigravity/accounts.ts
|
|
1741
|
-
function isRateLimitedForFamily(account, family) {
|
|
1742
|
-
const resetTime = account.rateLimits[family];
|
|
1743
|
-
return resetTime !== undefined && Date.now() < resetTime;
|
|
1744
|
-
}
|
|
1745
|
-
|
|
1746
|
-
class AccountManager {
|
|
1747
|
-
accounts = [];
|
|
1748
|
-
currentIndex = 0;
|
|
1749
|
-
activeIndex = 0;
|
|
1750
|
-
constructor(auth, storedAccounts) {
|
|
1751
|
-
if (storedAccounts && storedAccounts.accounts.length > 0) {
|
|
1752
|
-
const validActiveIndex = typeof storedAccounts.activeIndex === "number" && storedAccounts.activeIndex >= 0 && storedAccounts.activeIndex < storedAccounts.accounts.length ? storedAccounts.activeIndex : 0;
|
|
1753
|
-
this.activeIndex = validActiveIndex;
|
|
1754
|
-
this.currentIndex = validActiveIndex;
|
|
1755
|
-
this.accounts = storedAccounts.accounts.map((acc, index) => ({
|
|
1756
|
-
index,
|
|
1757
|
-
parts: {
|
|
1758
|
-
refreshToken: acc.refreshToken,
|
|
1759
|
-
projectId: acc.projectId,
|
|
1760
|
-
managedProjectId: acc.managedProjectId
|
|
1761
|
-
},
|
|
1762
|
-
access: index === validActiveIndex ? auth.access : acc.accessToken,
|
|
1763
|
-
expires: index === validActiveIndex ? auth.expires : acc.expiresAt,
|
|
1764
|
-
rateLimits: acc.rateLimits ?? {},
|
|
1765
|
-
lastUsed: 0,
|
|
1766
|
-
email: acc.email,
|
|
1767
|
-
tier: acc.tier
|
|
1768
|
-
}));
|
|
1769
|
-
} else {
|
|
1770
|
-
this.activeIndex = 0;
|
|
1771
|
-
this.currentIndex = 0;
|
|
1772
|
-
const parts = parseStoredToken(auth.refresh);
|
|
1773
|
-
this.accounts.push({
|
|
1774
|
-
index: 0,
|
|
1775
|
-
parts,
|
|
1776
|
-
access: auth.access,
|
|
1777
|
-
expires: auth.expires,
|
|
1778
|
-
rateLimits: {},
|
|
1779
|
-
lastUsed: 0
|
|
1780
|
-
});
|
|
1781
|
-
}
|
|
1782
|
-
}
|
|
1783
|
-
getAccountCount() {
|
|
1784
|
-
return this.accounts.length;
|
|
1785
|
-
}
|
|
1786
|
-
getCurrentAccount() {
|
|
1787
|
-
if (this.activeIndex >= 0 && this.activeIndex < this.accounts.length) {
|
|
1788
|
-
return this.accounts[this.activeIndex] ?? null;
|
|
1789
|
-
}
|
|
1790
|
-
return null;
|
|
1791
|
-
}
|
|
1792
|
-
getAccounts() {
|
|
1793
|
-
return [...this.accounts];
|
|
1794
|
-
}
|
|
1795
|
-
getCurrentOrNextForFamily(family) {
|
|
1796
|
-
for (const account of this.accounts) {
|
|
1797
|
-
this.clearExpiredRateLimits(account);
|
|
1798
|
-
}
|
|
1799
|
-
const current = this.getCurrentAccount();
|
|
1800
|
-
if (current) {
|
|
1801
|
-
if (!isRateLimitedForFamily(current, family)) {
|
|
1802
|
-
const betterTierAvailable = current.tier !== "paid" && this.accounts.some((a) => a.tier === "paid" && !isRateLimitedForFamily(a, family));
|
|
1803
|
-
if (!betterTierAvailable) {
|
|
1804
|
-
current.lastUsed = Date.now();
|
|
1805
|
-
return current;
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
const next = this.getNextForFamily(family);
|
|
1810
|
-
if (next) {
|
|
1811
|
-
this.activeIndex = next.index;
|
|
1812
|
-
}
|
|
1813
|
-
return next;
|
|
1814
|
-
}
|
|
1815
|
-
getNextForFamily(family) {
|
|
1816
|
-
const available = this.accounts.filter((a) => !isRateLimitedForFamily(a, family));
|
|
1817
|
-
if (available.length === 0) {
|
|
1818
|
-
return null;
|
|
1819
|
-
}
|
|
1820
|
-
const paidAvailable = available.filter((a) => a.tier === "paid");
|
|
1821
|
-
const pool = paidAvailable.length > 0 ? paidAvailable : available;
|
|
1822
|
-
const account = pool[this.currentIndex % pool.length];
|
|
1823
|
-
if (!account) {
|
|
1824
|
-
return null;
|
|
1825
|
-
}
|
|
1826
|
-
this.currentIndex++;
|
|
1827
|
-
account.lastUsed = Date.now();
|
|
1828
|
-
return account;
|
|
1829
|
-
}
|
|
1830
|
-
markRateLimited(account, retryAfterMs, family) {
|
|
1831
|
-
account.rateLimits[family] = Date.now() + retryAfterMs;
|
|
1832
|
-
}
|
|
1833
|
-
clearExpiredRateLimits(account) {
|
|
1834
|
-
const now = Date.now();
|
|
1835
|
-
for (const family of MODEL_FAMILIES) {
|
|
1836
|
-
if (account.rateLimits[family] !== undefined && now >= account.rateLimits[family]) {
|
|
1837
|
-
delete account.rateLimits[family];
|
|
1838
|
-
}
|
|
1839
|
-
}
|
|
1840
|
-
}
|
|
1841
|
-
addAccount(parts, access, expires, email, tier) {
|
|
1842
|
-
this.accounts.push({
|
|
1843
|
-
index: this.accounts.length,
|
|
1844
|
-
parts,
|
|
1845
|
-
access,
|
|
1846
|
-
expires,
|
|
1847
|
-
rateLimits: {},
|
|
1848
|
-
lastUsed: 0,
|
|
1849
|
-
email,
|
|
1850
|
-
tier
|
|
1851
|
-
});
|
|
1852
|
-
}
|
|
1853
|
-
removeAccount(index) {
|
|
1854
|
-
if (index < 0 || index >= this.accounts.length) {
|
|
1855
|
-
return false;
|
|
1856
|
-
}
|
|
1857
|
-
this.accounts.splice(index, 1);
|
|
1858
|
-
if (index < this.activeIndex) {
|
|
1859
|
-
this.activeIndex--;
|
|
1860
|
-
} else if (index === this.activeIndex) {
|
|
1861
|
-
this.activeIndex = Math.min(this.activeIndex, Math.max(0, this.accounts.length - 1));
|
|
1862
|
-
}
|
|
1863
|
-
if (index < this.currentIndex) {
|
|
1864
|
-
this.currentIndex--;
|
|
1865
|
-
} else if (index === this.currentIndex) {
|
|
1866
|
-
this.currentIndex = Math.min(this.currentIndex, Math.max(0, this.accounts.length - 1));
|
|
1867
|
-
}
|
|
1868
|
-
for (let i = 0;i < this.accounts.length; i++) {
|
|
1869
|
-
this.accounts[i].index = i;
|
|
1870
|
-
}
|
|
1871
|
-
return true;
|
|
1872
|
-
}
|
|
1873
|
-
async save(path2) {
|
|
1874
|
-
const storage = {
|
|
1875
|
-
version: 1,
|
|
1876
|
-
accounts: this.accounts.map((acc) => ({
|
|
1877
|
-
email: acc.email ?? "",
|
|
1878
|
-
tier: acc.tier ?? "free",
|
|
1879
|
-
refreshToken: acc.parts.refreshToken,
|
|
1880
|
-
projectId: acc.parts.projectId ?? "",
|
|
1881
|
-
managedProjectId: acc.parts.managedProjectId,
|
|
1882
|
-
accessToken: acc.access ?? "",
|
|
1883
|
-
expiresAt: acc.expires ?? 0,
|
|
1884
|
-
rateLimits: acc.rateLimits
|
|
1885
|
-
})),
|
|
1886
|
-
activeIndex: Math.max(0, this.activeIndex)
|
|
1887
|
-
};
|
|
1888
|
-
await saveAccounts(storage, path2);
|
|
1889
|
-
}
|
|
1890
|
-
toAuthDetails() {
|
|
1891
|
-
const current = this.getCurrentAccount() ?? this.accounts[0];
|
|
1892
|
-
if (!current) {
|
|
1893
|
-
throw new Error("No accounts available");
|
|
1894
|
-
}
|
|
1895
|
-
const allRefreshTokens = this.accounts.map((acc) => formatTokenForStorage(acc.parts.refreshToken, acc.parts.projectId ?? "", acc.parts.managedProjectId)).join("|||");
|
|
1896
|
-
return {
|
|
1897
|
-
type: "oauth",
|
|
1898
|
-
refresh: allRefreshTokens,
|
|
1899
|
-
access: current.access ?? "",
|
|
1900
|
-
expires: current.expires ?? 0
|
|
1901
|
-
};
|
|
1902
|
-
}
|
|
1903
|
-
}
|
|
1904
|
-
|
|
1905
|
-
// src/auth/antigravity/fetch.ts
|
|
1906
|
-
function debugLog4(message) {
|
|
1907
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
1908
|
-
console.log(`[antigravity-fetch] ${message}`);
|
|
1909
|
-
}
|
|
1910
|
-
}
|
|
1911
|
-
function isRetryableError2(status) {
|
|
1912
|
-
if (status === 0)
|
|
1913
|
-
return true;
|
|
1914
|
-
if (status === 429)
|
|
1915
|
-
return true;
|
|
1916
|
-
if (status >= 500 && status < 600)
|
|
1917
|
-
return true;
|
|
1918
|
-
return false;
|
|
1919
|
-
}
|
|
1920
|
-
function getModelFamilyFromModelName(modelName) {
|
|
1921
|
-
const lower = modelName.toLowerCase();
|
|
1922
|
-
if (lower.includes("claude") || lower.includes("anthropic"))
|
|
1923
|
-
return "claude";
|
|
1924
|
-
if (lower.includes("flash"))
|
|
1925
|
-
return "gemini-flash";
|
|
1926
|
-
if (lower.includes("gemini"))
|
|
1927
|
-
return "gemini-pro";
|
|
1928
|
-
return null;
|
|
1929
|
-
}
|
|
1930
|
-
function getModelFamilyFromUrl(url) {
|
|
1931
|
-
if (url.includes("claude"))
|
|
1932
|
-
return "claude";
|
|
1933
|
-
if (url.includes("flash"))
|
|
1934
|
-
return "gemini-flash";
|
|
1935
|
-
return "gemini-pro";
|
|
1936
|
-
}
|
|
1937
|
-
function getModelFamily(url, init) {
|
|
1938
|
-
if (init?.body && typeof init.body === "string") {
|
|
1939
|
-
try {
|
|
1940
|
-
const body = JSON.parse(init.body);
|
|
1941
|
-
if (typeof body.model === "string") {
|
|
1942
|
-
const fromModel = getModelFamilyFromModelName(body.model);
|
|
1943
|
-
if (fromModel)
|
|
1944
|
-
return fromModel;
|
|
1945
|
-
}
|
|
1946
|
-
} catch {}
|
|
1947
|
-
}
|
|
1948
|
-
return getModelFamilyFromUrl(url);
|
|
1949
|
-
}
|
|
1950
|
-
var GCP_PERMISSION_ERROR_PATTERNS = [
|
|
1951
|
-
"PERMISSION_DENIED",
|
|
1952
|
-
"does not have permission",
|
|
1953
|
-
"Cloud AI Companion API has not been used",
|
|
1954
|
-
"has not been enabled"
|
|
1955
|
-
];
|
|
1956
|
-
function isGcpPermissionError(text) {
|
|
1957
|
-
return GCP_PERMISSION_ERROR_PATTERNS.some((pattern) => text.includes(pattern));
|
|
1958
|
-
}
|
|
1959
|
-
function calculateRetryDelay2(attempt) {
|
|
1960
|
-
return Math.min(200 * Math.pow(2, attempt), 2000);
|
|
1961
|
-
}
|
|
1962
|
-
async function isRetryableResponse(response) {
|
|
1963
|
-
if (isRetryableError2(response.status))
|
|
1964
|
-
return true;
|
|
1965
|
-
if (response.status === 403) {
|
|
1966
|
-
try {
|
|
1967
|
-
const text = await response.clone().text();
|
|
1968
|
-
if (text.includes("SUBSCRIPTION_REQUIRED") || text.includes("Gemini Code Assist license")) {
|
|
1969
|
-
debugLog4(`[RETRY] 403 SUBSCRIPTION_REQUIRED detected, will retry with next endpoint`);
|
|
1970
|
-
return true;
|
|
1971
|
-
}
|
|
1972
|
-
} catch {}
|
|
1973
|
-
}
|
|
1974
|
-
return false;
|
|
1975
|
-
}
|
|
1976
|
-
async function attemptFetch(options) {
|
|
1977
|
-
const { endpoint, url, init, accessToken, projectId, sessionId, modelName, thoughtSignature } = options;
|
|
1978
|
-
debugLog4(`Trying endpoint: ${endpoint}`);
|
|
1979
|
-
try {
|
|
1980
|
-
const rawBody = init.body;
|
|
1981
|
-
if (rawBody !== undefined && typeof rawBody !== "string") {
|
|
1982
|
-
debugLog4(`Non-string body detected (${typeof rawBody}), signaling pass-through`);
|
|
1983
|
-
return "pass-through";
|
|
1984
|
-
}
|
|
1985
|
-
let parsedBody = {};
|
|
1986
|
-
if (rawBody) {
|
|
1987
|
-
try {
|
|
1988
|
-
parsedBody = JSON.parse(rawBody);
|
|
1989
|
-
} catch {
|
|
1990
|
-
parsedBody = {};
|
|
1991
|
-
}
|
|
1992
|
-
}
|
|
1993
|
-
debugLog4(`[BODY] Keys: ${Object.keys(parsedBody).join(", ")}`);
|
|
1994
|
-
debugLog4(`[BODY] Has contents: ${!!parsedBody.contents}, Has messages: ${!!parsedBody.messages}`);
|
|
1995
|
-
if (parsedBody.contents) {
|
|
1996
|
-
const contents = parsedBody.contents;
|
|
1997
|
-
debugLog4(`[BODY] contents length: ${contents.length}`);
|
|
1998
|
-
contents.forEach((c, i) => {
|
|
1999
|
-
debugLog4(`[BODY] contents[${i}].role: ${c.role}, parts: ${JSON.stringify(c.parts).substring(0, 200)}`);
|
|
2000
|
-
});
|
|
2001
|
-
}
|
|
2002
|
-
if (parsedBody.tools && Array.isArray(parsedBody.tools)) {
|
|
2003
|
-
const normalizedTools = normalizeToolsForGemini(parsedBody.tools);
|
|
2004
|
-
if (normalizedTools) {
|
|
2005
|
-
parsedBody.tools = normalizedTools;
|
|
2006
|
-
}
|
|
2007
|
-
}
|
|
2008
|
-
if (hasOpenAIMessages(parsedBody)) {
|
|
2009
|
-
debugLog4(`[CONVERT] Converting OpenAI messages to Gemini contents`);
|
|
2010
|
-
parsedBody = convertRequestBody(parsedBody, thoughtSignature);
|
|
2011
|
-
debugLog4(`[CONVERT] After conversion - Has contents: ${!!parsedBody.contents}`);
|
|
2012
|
-
}
|
|
2013
|
-
const transformed = transformRequest({
|
|
2014
|
-
url,
|
|
2015
|
-
body: parsedBody,
|
|
2016
|
-
accessToken,
|
|
2017
|
-
projectId,
|
|
2018
|
-
sessionId,
|
|
2019
|
-
modelName,
|
|
2020
|
-
endpointOverride: endpoint,
|
|
2021
|
-
thoughtSignature
|
|
2022
|
-
});
|
|
2023
|
-
const effectiveModel = modelName || transformed.body.model;
|
|
2024
|
-
const thinkingConfig = extractThinkingConfig(parsedBody, parsedBody.generationConfig, parsedBody);
|
|
2025
|
-
if (thinkingConfig) {
|
|
2026
|
-
debugLog4(`[THINKING] Applying thinking config for model: ${effectiveModel}`);
|
|
2027
|
-
applyThinkingConfigToRequest(transformed.body, effectiveModel, thinkingConfig);
|
|
2028
|
-
debugLog4(`[THINKING] Thinking config applied successfully`);
|
|
2029
|
-
}
|
|
2030
|
-
debugLog4(`[REQ] streaming=${transformed.streaming}, url=${transformed.url}`);
|
|
2031
|
-
const maxPermissionRetries = 10;
|
|
2032
|
-
for (let attempt = 0;attempt <= maxPermissionRetries; attempt++) {
|
|
2033
|
-
const response = await fetch(transformed.url, {
|
|
2034
|
-
method: init.method || "POST",
|
|
2035
|
-
headers: transformed.headers,
|
|
2036
|
-
body: JSON.stringify(transformed.body),
|
|
2037
|
-
signal: init.signal
|
|
2038
|
-
});
|
|
2039
|
-
debugLog4(`[RESP] status=${response.status} content-type=${response.headers.get("content-type") ?? ""} url=${response.url}`);
|
|
2040
|
-
if (response.status === 401) {
|
|
2041
|
-
debugLog4(`[401] Unauthorized response detected, signaling token refresh needed`);
|
|
2042
|
-
return "needs-refresh";
|
|
2043
|
-
}
|
|
2044
|
-
if (response.status === 403) {
|
|
2045
|
-
try {
|
|
2046
|
-
const text = await response.clone().text();
|
|
2047
|
-
if (isGcpPermissionError(text)) {
|
|
2048
|
-
if (attempt < maxPermissionRetries) {
|
|
2049
|
-
const delay = calculateRetryDelay2(attempt);
|
|
2050
|
-
debugLog4(`[RETRY] GCP permission error, retry ${attempt + 1}/${maxPermissionRetries} after ${delay}ms`);
|
|
2051
|
-
await new Promise((resolve) => setTimeout(resolve, delay));
|
|
2052
|
-
continue;
|
|
2053
|
-
}
|
|
2054
|
-
debugLog4(`[RETRY] GCP permission error, max retries exceeded`);
|
|
2055
|
-
}
|
|
2056
|
-
} catch {}
|
|
2057
|
-
}
|
|
2058
|
-
if (response.status === 429) {
|
|
2059
|
-
const retryAfter = response.headers.get("retry-after");
|
|
2060
|
-
let retryAfterMs = 60000;
|
|
2061
|
-
if (retryAfter) {
|
|
2062
|
-
const parsed = parseInt(retryAfter, 10);
|
|
2063
|
-
if (!isNaN(parsed) && parsed > 0) {
|
|
2064
|
-
retryAfterMs = parsed * 1000;
|
|
2065
|
-
} else {
|
|
2066
|
-
const httpDate = Date.parse(retryAfter);
|
|
2067
|
-
if (!isNaN(httpDate)) {
|
|
2068
|
-
retryAfterMs = Math.max(0, httpDate - Date.now());
|
|
2069
|
-
}
|
|
2070
|
-
}
|
|
2071
|
-
}
|
|
2072
|
-
debugLog4(`[429] Rate limited, retry-after: ${retryAfterMs}ms`);
|
|
2073
|
-
await response.body?.cancel();
|
|
2074
|
-
return { type: "rate-limited", retryAfterMs, status: 429 };
|
|
2075
|
-
}
|
|
2076
|
-
if (response.status >= 500 && response.status < 600) {
|
|
2077
|
-
debugLog4(`[5xx] Server error ${response.status}, marking for rotation`);
|
|
2078
|
-
await response.body?.cancel();
|
|
2079
|
-
return { type: "rate-limited", retryAfterMs: 300000, status: response.status };
|
|
2080
|
-
}
|
|
2081
|
-
if (!response.ok && await isRetryableResponse(response)) {
|
|
2082
|
-
debugLog4(`Endpoint failed: ${endpoint} (status: ${response.status}), trying next`);
|
|
2083
|
-
return null;
|
|
2084
|
-
}
|
|
2085
|
-
return response;
|
|
2086
|
-
}
|
|
2087
|
-
return null;
|
|
2088
|
-
} catch (error) {
|
|
2089
|
-
debugLog4(`Endpoint failed: ${endpoint} (${error instanceof Error ? error.message : "Unknown error"}), trying next`);
|
|
2090
|
-
return null;
|
|
2091
|
-
}
|
|
2092
|
-
}
|
|
2093
|
-
function extractSignatureFromResponse(parsed) {
|
|
2094
|
-
if (!parsed.candidates || !Array.isArray(parsed.candidates)) {
|
|
2095
|
-
return;
|
|
2096
|
-
}
|
|
2097
|
-
for (const candidate of parsed.candidates) {
|
|
2098
|
-
const parts = candidate.content?.parts;
|
|
2099
|
-
if (!parts || !Array.isArray(parts)) {
|
|
2100
|
-
continue;
|
|
2101
|
-
}
|
|
2102
|
-
for (const part of parts) {
|
|
2103
|
-
const sig = part.thoughtSignature || part.thought_signature;
|
|
2104
|
-
if (sig && typeof sig === "string") {
|
|
2105
|
-
return sig;
|
|
2106
|
-
}
|
|
2107
|
-
}
|
|
2108
|
-
}
|
|
2109
|
-
return;
|
|
2110
|
-
}
|
|
2111
|
-
async function transformResponseWithThinking(response, modelName, fetchInstanceId) {
|
|
2112
|
-
const streaming = isStreamingResponse(response);
|
|
2113
|
-
let result;
|
|
2114
|
-
if (streaming) {
|
|
2115
|
-
result = await transformStreamingResponse(response);
|
|
2116
|
-
} else {
|
|
2117
|
-
result = await transformResponse(response);
|
|
2118
|
-
}
|
|
2119
|
-
if (streaming) {
|
|
2120
|
-
return result.response;
|
|
2121
|
-
}
|
|
2122
|
-
try {
|
|
2123
|
-
const text = await result.response.clone().text();
|
|
2124
|
-
debugLog4(`[TSIG][RESP] Response text length: ${text.length}`);
|
|
2125
|
-
const parsed = JSON.parse(text);
|
|
2126
|
-
debugLog4(`[TSIG][RESP] Parsed keys: ${Object.keys(parsed).join(", ")}`);
|
|
2127
|
-
debugLog4(`[TSIG][RESP] Has candidates: ${!!parsed.candidates}, count: ${parsed.candidates?.length ?? 0}`);
|
|
2128
|
-
const signature = extractSignatureFromResponse(parsed);
|
|
2129
|
-
debugLog4(`[TSIG][RESP] Signature extracted: ${signature ? signature.substring(0, 30) + "..." : "NONE"}`);
|
|
2130
|
-
if (signature) {
|
|
2131
|
-
setThoughtSignature(fetchInstanceId, signature);
|
|
2132
|
-
debugLog4(`[TSIG][STORE] Stored signature for ${fetchInstanceId}`);
|
|
2133
|
-
} else {
|
|
2134
|
-
debugLog4(`[TSIG][WARN] No signature found in response!`);
|
|
2135
|
-
}
|
|
2136
|
-
if (shouldIncludeThinking(modelName)) {
|
|
2137
|
-
const thinkingResult = extractThinkingBlocks(parsed);
|
|
2138
|
-
if (thinkingResult.hasThinking) {
|
|
2139
|
-
const transformed = transformResponseThinking(parsed);
|
|
2140
|
-
return new Response(JSON.stringify(transformed), {
|
|
2141
|
-
status: result.response.status,
|
|
2142
|
-
statusText: result.response.statusText,
|
|
2143
|
-
headers: result.response.headers
|
|
2144
|
-
});
|
|
2145
|
-
}
|
|
2146
|
-
}
|
|
2147
|
-
} catch {}
|
|
2148
|
-
return result.response;
|
|
2149
|
-
}
|
|
2150
|
-
function createAntigravityFetch(getAuth, client, providerId, clientId, clientSecret, accountManager) {
|
|
2151
|
-
let cachedTokens = null;
|
|
2152
|
-
let cachedProjectId = null;
|
|
2153
|
-
let lastAccountIndex = null;
|
|
2154
|
-
const fetchInstanceId = crypto.randomUUID();
|
|
2155
|
-
let manager = accountManager || null;
|
|
2156
|
-
let accountsLoaded = false;
|
|
2157
|
-
const fetchFn = async (url, init = {}) => {
|
|
2158
|
-
debugLog4(`Intercepting request to: ${url}`);
|
|
2159
|
-
const auth = await getAuth();
|
|
2160
|
-
if (!auth.access || !auth.refresh) {
|
|
2161
|
-
throw new Error("Antigravity: No authentication tokens available");
|
|
2162
|
-
}
|
|
2163
|
-
let refreshParts = parseStoredToken(auth.refresh);
|
|
2164
|
-
if (!accountsLoaded && !manager && auth.refresh) {
|
|
2165
|
-
try {
|
|
2166
|
-
const storedAccounts = await loadAccounts();
|
|
2167
|
-
if (storedAccounts) {
|
|
2168
|
-
manager = new AccountManager({ refresh: auth.refresh, access: auth.access || "", expires: auth.expires || 0 }, storedAccounts);
|
|
2169
|
-
debugLog4(`[ACCOUNTS] Loaded ${manager.getAccountCount()} accounts from storage`);
|
|
2170
|
-
}
|
|
2171
|
-
} catch (error) {
|
|
2172
|
-
debugLog4(`[ACCOUNTS] Failed to load accounts, falling back to single-account: ${error instanceof Error ? error.message : "Unknown"}`);
|
|
2173
|
-
}
|
|
2174
|
-
accountsLoaded = true;
|
|
2175
|
-
}
|
|
2176
|
-
let currentAccount = null;
|
|
2177
|
-
if (manager) {
|
|
2178
|
-
const family = getModelFamily(url, init);
|
|
2179
|
-
currentAccount = manager.getCurrentOrNextForFamily(family);
|
|
2180
|
-
if (currentAccount) {
|
|
2181
|
-
debugLog4(`[ACCOUNTS] Using account ${currentAccount.index + 1}/${manager.getAccountCount()} for ${family}`);
|
|
2182
|
-
if (lastAccountIndex === null || lastAccountIndex !== currentAccount.index) {
|
|
2183
|
-
if (lastAccountIndex !== null) {
|
|
2184
|
-
debugLog4(`[ACCOUNTS] Account changed from ${lastAccountIndex + 1} to ${currentAccount.index + 1}, clearing cached state`);
|
|
2185
|
-
} else if (cachedProjectId) {
|
|
2186
|
-
debugLog4(`[ACCOUNTS] First account introduced, clearing cached state`);
|
|
2187
|
-
}
|
|
2188
|
-
cachedProjectId = null;
|
|
2189
|
-
cachedTokens = null;
|
|
2190
|
-
}
|
|
2191
|
-
lastAccountIndex = currentAccount.index;
|
|
2192
|
-
if (currentAccount.access && currentAccount.expires) {
|
|
2193
|
-
auth.access = currentAccount.access;
|
|
2194
|
-
auth.expires = currentAccount.expires;
|
|
2195
|
-
}
|
|
2196
|
-
refreshParts = {
|
|
2197
|
-
refreshToken: currentAccount.parts.refreshToken,
|
|
2198
|
-
projectId: currentAccount.parts.projectId,
|
|
2199
|
-
managedProjectId: currentAccount.parts.managedProjectId
|
|
2200
|
-
};
|
|
2201
|
-
}
|
|
2202
|
-
}
|
|
2203
|
-
if (!cachedTokens) {
|
|
2204
|
-
cachedTokens = {
|
|
2205
|
-
type: "antigravity",
|
|
2206
|
-
access_token: auth.access,
|
|
2207
|
-
refresh_token: refreshParts.refreshToken,
|
|
2208
|
-
expires_in: auth.expires ? Math.floor((auth.expires - Date.now()) / 1000) : 3600,
|
|
2209
|
-
timestamp: auth.expires ? auth.expires - 3600 * 1000 : Date.now()
|
|
2210
|
-
};
|
|
2211
|
-
} else {
|
|
2212
|
-
cachedTokens.access_token = auth.access;
|
|
2213
|
-
cachedTokens.refresh_token = refreshParts.refreshToken;
|
|
2214
|
-
}
|
|
2215
|
-
if (isTokenExpired(cachedTokens)) {
|
|
2216
|
-
debugLog4("Token expired, refreshing...");
|
|
2217
|
-
try {
|
|
2218
|
-
const newTokens = await refreshAccessToken(refreshParts.refreshToken, clientId, clientSecret);
|
|
2219
|
-
cachedTokens = {
|
|
2220
|
-
type: "antigravity",
|
|
2221
|
-
access_token: newTokens.access_token,
|
|
2222
|
-
refresh_token: newTokens.refresh_token,
|
|
2223
|
-
expires_in: newTokens.expires_in,
|
|
2224
|
-
timestamp: Date.now()
|
|
2225
|
-
};
|
|
2226
|
-
clearProjectContextCache();
|
|
2227
|
-
const formattedRefresh = formatTokenForStorage(newTokens.refresh_token, refreshParts.projectId || "", refreshParts.managedProjectId);
|
|
2228
|
-
await client.set(providerId, {
|
|
2229
|
-
access: newTokens.access_token,
|
|
2230
|
-
refresh: formattedRefresh,
|
|
2231
|
-
expires: Date.now() + newTokens.expires_in * 1000
|
|
2232
|
-
});
|
|
2233
|
-
debugLog4("Token refreshed successfully");
|
|
2234
|
-
} catch (error) {
|
|
2235
|
-
if (error instanceof AntigravityTokenRefreshError) {
|
|
2236
|
-
if (error.isInvalidGrant) {
|
|
2237
|
-
debugLog4(`[REFRESH] Token revoked (invalid_grant), clearing caches`);
|
|
2238
|
-
invalidateProjectContextByRefreshToken(refreshParts.refreshToken);
|
|
2239
|
-
clearProjectContextCache();
|
|
2240
|
-
}
|
|
2241
|
-
throw new Error(`Antigravity: Token refresh failed: ${error.description || error.message}${error.code ? ` (${error.code})` : ""}`);
|
|
2242
|
-
}
|
|
2243
|
-
throw new Error(`Antigravity: Token refresh failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
|
-
if (!cachedProjectId) {
|
|
2247
|
-
const projectContext = await fetchProjectContext(cachedTokens.access_token);
|
|
2248
|
-
cachedProjectId = projectContext.cloudaicompanionProject || "";
|
|
2249
|
-
debugLog4(`[PROJECT] Fetched project ID: "${cachedProjectId}"`);
|
|
2250
|
-
}
|
|
2251
|
-
const projectId = cachedProjectId;
|
|
2252
|
-
debugLog4(`[PROJECT] Using project ID: "${projectId}"`);
|
|
2253
|
-
let modelName;
|
|
2254
|
-
if (init.body) {
|
|
2255
|
-
try {
|
|
2256
|
-
const body = typeof init.body === "string" ? JSON.parse(init.body) : init.body;
|
|
2257
|
-
if (typeof body.model === "string") {
|
|
2258
|
-
modelName = body.model;
|
|
2259
|
-
}
|
|
2260
|
-
} catch {}
|
|
2261
|
-
}
|
|
2262
|
-
const maxEndpoints = Math.min(ANTIGRAVITY_ENDPOINT_FALLBACKS.length, 3);
|
|
2263
|
-
const sessionId = getOrCreateSessionId(fetchInstanceId);
|
|
2264
|
-
const thoughtSignature = getThoughtSignature(fetchInstanceId);
|
|
2265
|
-
debugLog4(`[TSIG][GET] sessionId=${sessionId}, signature=${thoughtSignature ? thoughtSignature.substring(0, 20) + "..." : "none"}`);
|
|
2266
|
-
let hasRefreshedFor401 = false;
|
|
2267
|
-
const executeWithEndpoints = async () => {
|
|
2268
|
-
for (let i = 0;i < maxEndpoints; i++) {
|
|
2269
|
-
const endpoint = ANTIGRAVITY_ENDPOINT_FALLBACKS[i];
|
|
2270
|
-
const response = await attemptFetch({
|
|
2271
|
-
endpoint,
|
|
2272
|
-
url,
|
|
2273
|
-
init,
|
|
2274
|
-
accessToken: cachedTokens.access_token,
|
|
2275
|
-
projectId,
|
|
2276
|
-
sessionId,
|
|
2277
|
-
modelName,
|
|
2278
|
-
thoughtSignature
|
|
2279
|
-
});
|
|
2280
|
-
if (response === "pass-through") {
|
|
2281
|
-
debugLog4("Non-string body detected, passing through with auth headers");
|
|
2282
|
-
const headersWithAuth = {
|
|
2283
|
-
...init.headers,
|
|
2284
|
-
Authorization: `Bearer ${cachedTokens.access_token}`
|
|
2285
|
-
};
|
|
2286
|
-
return fetch(url, { ...init, headers: headersWithAuth });
|
|
2287
|
-
}
|
|
2288
|
-
if (response === "needs-refresh") {
|
|
2289
|
-
if (hasRefreshedFor401) {
|
|
2290
|
-
debugLog4("[401] Already refreshed once, returning unauthorized error");
|
|
2291
|
-
return new Response(JSON.stringify({
|
|
2292
|
-
error: {
|
|
2293
|
-
message: "Authentication failed after token refresh",
|
|
2294
|
-
type: "unauthorized",
|
|
2295
|
-
code: "token_refresh_failed"
|
|
2296
|
-
}
|
|
2297
|
-
}), {
|
|
2298
|
-
status: 401,
|
|
2299
|
-
statusText: "Unauthorized",
|
|
2300
|
-
headers: { "Content-Type": "application/json" }
|
|
2301
|
-
});
|
|
2302
|
-
}
|
|
2303
|
-
debugLog4("[401] Refreshing token and retrying...");
|
|
2304
|
-
hasRefreshedFor401 = true;
|
|
2305
|
-
try {
|
|
2306
|
-
const newTokens = await refreshAccessToken(refreshParts.refreshToken, clientId, clientSecret);
|
|
2307
|
-
cachedTokens = {
|
|
2308
|
-
type: "antigravity",
|
|
2309
|
-
access_token: newTokens.access_token,
|
|
2310
|
-
refresh_token: newTokens.refresh_token,
|
|
2311
|
-
expires_in: newTokens.expires_in,
|
|
2312
|
-
timestamp: Date.now()
|
|
2313
|
-
};
|
|
2314
|
-
clearProjectContextCache();
|
|
2315
|
-
const formattedRefresh = formatTokenForStorage(newTokens.refresh_token, refreshParts.projectId || "", refreshParts.managedProjectId);
|
|
2316
|
-
await client.set(providerId, {
|
|
2317
|
-
access: newTokens.access_token,
|
|
2318
|
-
refresh: formattedRefresh,
|
|
2319
|
-
expires: Date.now() + newTokens.expires_in * 1000
|
|
2320
|
-
});
|
|
2321
|
-
debugLog4("[401] Token refreshed, retrying request...");
|
|
2322
|
-
return executeWithEndpoints();
|
|
2323
|
-
} catch (refreshError) {
|
|
2324
|
-
if (refreshError instanceof AntigravityTokenRefreshError) {
|
|
2325
|
-
if (refreshError.isInvalidGrant) {
|
|
2326
|
-
debugLog4(`[401] Token revoked (invalid_grant), clearing caches`);
|
|
2327
|
-
invalidateProjectContextByRefreshToken(refreshParts.refreshToken);
|
|
2328
|
-
clearProjectContextCache();
|
|
2329
|
-
}
|
|
2330
|
-
debugLog4(`[401] Token refresh failed: ${refreshError.description || refreshError.message}`);
|
|
2331
|
-
return new Response(JSON.stringify({
|
|
2332
|
-
error: {
|
|
2333
|
-
message: refreshError.description || refreshError.message,
|
|
2334
|
-
type: refreshError.isInvalidGrant ? "token_revoked" : "unauthorized",
|
|
2335
|
-
code: refreshError.code || "token_refresh_failed"
|
|
2336
|
-
}
|
|
2337
|
-
}), {
|
|
2338
|
-
status: 401,
|
|
2339
|
-
statusText: "Unauthorized",
|
|
2340
|
-
headers: { "Content-Type": "application/json" }
|
|
2341
|
-
});
|
|
2342
|
-
}
|
|
2343
|
-
debugLog4(`[401] Token refresh failed: ${refreshError instanceof Error ? refreshError.message : "Unknown error"}`);
|
|
2344
|
-
return new Response(JSON.stringify({
|
|
2345
|
-
error: {
|
|
2346
|
-
message: refreshError instanceof Error ? refreshError.message : "Unknown error",
|
|
2347
|
-
type: "unauthorized",
|
|
2348
|
-
code: "token_refresh_failed"
|
|
2349
|
-
}
|
|
2350
|
-
}), {
|
|
2351
|
-
status: 401,
|
|
2352
|
-
statusText: "Unauthorized",
|
|
2353
|
-
headers: { "Content-Type": "application/json" }
|
|
2354
|
-
});
|
|
2355
|
-
}
|
|
2356
|
-
}
|
|
2357
|
-
if (response && typeof response === "object" && "type" in response && response.type === "rate-limited") {
|
|
2358
|
-
const rateLimitInfo = response;
|
|
2359
|
-
const family = getModelFamily(url, init);
|
|
2360
|
-
if (rateLimitInfo.retryAfterMs > 5000 && manager && currentAccount) {
|
|
2361
|
-
manager.markRateLimited(currentAccount, rateLimitInfo.retryAfterMs, family);
|
|
2362
|
-
await manager.save();
|
|
2363
|
-
debugLog4(`[RATE-LIMIT] Account ${currentAccount.index + 1} rate-limited for ${family}, rotating...`);
|
|
2364
|
-
const nextAccount = manager.getCurrentOrNextForFamily(family);
|
|
2365
|
-
if (nextAccount && nextAccount.index !== currentAccount.index) {
|
|
2366
|
-
debugLog4(`[RATE-LIMIT] Switched to account ${nextAccount.index + 1}`);
|
|
2367
|
-
return fetchFn(url, init);
|
|
2368
|
-
}
|
|
2369
|
-
}
|
|
2370
|
-
const isLastEndpoint = i === maxEndpoints - 1;
|
|
2371
|
-
if (isLastEndpoint) {
|
|
2372
|
-
const isServerError = rateLimitInfo.status >= 500;
|
|
2373
|
-
debugLog4(`[RATE-LIMIT] No alternative account or endpoint, returning ${rateLimitInfo.status}`);
|
|
2374
|
-
return new Response(JSON.stringify({
|
|
2375
|
-
error: {
|
|
2376
|
-
message: isServerError ? `Server error (${rateLimitInfo.status}). Retry after ${Math.ceil(rateLimitInfo.retryAfterMs / 1000)} seconds` : `Rate limited. Retry after ${Math.ceil(rateLimitInfo.retryAfterMs / 1000)} seconds`,
|
|
2377
|
-
type: isServerError ? "server_error" : "rate_limit",
|
|
2378
|
-
code: isServerError ? "server_error" : "rate_limited"
|
|
2379
|
-
}
|
|
2380
|
-
}), {
|
|
2381
|
-
status: rateLimitInfo.status,
|
|
2382
|
-
statusText: isServerError ? "Server Error" : "Too Many Requests",
|
|
2383
|
-
headers: {
|
|
2384
|
-
"Content-Type": "application/json",
|
|
2385
|
-
"Retry-After": String(Math.ceil(rateLimitInfo.retryAfterMs / 1000))
|
|
2386
|
-
}
|
|
2387
|
-
});
|
|
2388
|
-
}
|
|
2389
|
-
debugLog4(`[RATE-LIMIT] No alternative account available, trying next endpoint`);
|
|
2390
|
-
continue;
|
|
2391
|
-
}
|
|
2392
|
-
if (response && response instanceof Response) {
|
|
2393
|
-
debugLog4(`Success with endpoint: ${endpoint}`);
|
|
2394
|
-
const transformedResponse = await transformResponseWithThinking(response, modelName || "", fetchInstanceId);
|
|
2395
|
-
return transformedResponse;
|
|
2396
|
-
}
|
|
2397
|
-
}
|
|
2398
|
-
const errorMessage = `All Antigravity endpoints failed after ${maxEndpoints} attempts`;
|
|
2399
|
-
debugLog4(errorMessage);
|
|
2400
|
-
return new Response(JSON.stringify({
|
|
2401
|
-
error: {
|
|
2402
|
-
message: errorMessage,
|
|
2403
|
-
type: "endpoint_failure",
|
|
2404
|
-
code: "all_endpoints_failed"
|
|
2405
|
-
}
|
|
2406
|
-
}), {
|
|
2407
|
-
status: 503,
|
|
2408
|
-
statusText: "Service Unavailable",
|
|
2409
|
-
headers: { "Content-Type": "application/json" }
|
|
2410
|
-
});
|
|
2411
|
-
};
|
|
2412
|
-
return executeWithEndpoints();
|
|
2413
|
-
};
|
|
2414
|
-
return fetchFn;
|
|
2415
|
-
}
|
|
2416
|
-
// node_modules/@clack/core/dist/index.mjs
|
|
2417
|
-
var import_sisteransi = __toESM(require_src(), 1);
|
|
2418
|
-
import { stdin as j, stdout as M } from "process";
|
|
2419
|
-
import O from "readline";
|
|
2420
|
-
import { Writable as X } from "stream";
|
|
2421
|
-
function DD({ onlyFirst: e = false } = {}) {
|
|
2422
|
-
const t = ["[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?(?:\\u0007|\\u001B\\u005C|\\u009C))", "(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]))"].join("|");
|
|
2423
|
-
return new RegExp(t, e ? undefined : "g");
|
|
2424
|
-
}
|
|
2425
|
-
var uD = DD();
|
|
2426
|
-
function P(e) {
|
|
2427
|
-
if (typeof e != "string")
|
|
2428
|
-
throw new TypeError(`Expected a \`string\`, got \`${typeof e}\``);
|
|
2429
|
-
return e.replace(uD, "");
|
|
2430
|
-
}
|
|
2431
|
-
function L(e) {
|
|
2432
|
-
return e && e.__esModule && Object.prototype.hasOwnProperty.call(e, "default") ? e.default : e;
|
|
2433
|
-
}
|
|
2434
|
-
var W = { exports: {} };
|
|
2435
|
-
(function(e) {
|
|
2436
|
-
var u = {};
|
|
2437
|
-
e.exports = u, u.eastAsianWidth = function(F) {
|
|
2438
|
-
var s = F.charCodeAt(0), i = F.length == 2 ? F.charCodeAt(1) : 0, D = s;
|
|
2439
|
-
return 55296 <= s && s <= 56319 && 56320 <= i && i <= 57343 && (s &= 1023, i &= 1023, D = s << 10 | i, D += 65536), D == 12288 || 65281 <= D && D <= 65376 || 65504 <= D && D <= 65510 ? "F" : D == 8361 || 65377 <= D && D <= 65470 || 65474 <= D && D <= 65479 || 65482 <= D && D <= 65487 || 65490 <= D && D <= 65495 || 65498 <= D && D <= 65500 || 65512 <= D && D <= 65518 ? "H" : 4352 <= D && D <= 4447 || 4515 <= D && D <= 4519 || 4602 <= D && D <= 4607 || 9001 <= D && D <= 9002 || 11904 <= D && D <= 11929 || 11931 <= D && D <= 12019 || 12032 <= D && D <= 12245 || 12272 <= D && D <= 12283 || 12289 <= D && D <= 12350 || 12353 <= D && D <= 12438 || 12441 <= D && D <= 12543 || 12549 <= D && D <= 12589 || 12593 <= D && D <= 12686 || 12688 <= D && D <= 12730 || 12736 <= D && D <= 12771 || 12784 <= D && D <= 12830 || 12832 <= D && D <= 12871 || 12880 <= D && D <= 13054 || 13056 <= D && D <= 19903 || 19968 <= D && D <= 42124 || 42128 <= D && D <= 42182 || 43360 <= D && D <= 43388 || 44032 <= D && D <= 55203 || 55216 <= D && D <= 55238 || 55243 <= D && D <= 55291 || 63744 <= D && D <= 64255 || 65040 <= D && D <= 65049 || 65072 <= D && D <= 65106 || 65108 <= D && D <= 65126 || 65128 <= D && D <= 65131 || 110592 <= D && D <= 110593 || 127488 <= D && D <= 127490 || 127504 <= D && D <= 127546 || 127552 <= D && D <= 127560 || 127568 <= D && D <= 127569 || 131072 <= D && D <= 194367 || 177984 <= D && D <= 196605 || 196608 <= D && D <= 262141 ? "W" : 32 <= D && D <= 126 || 162 <= D && D <= 163 || 165 <= D && D <= 166 || D == 172 || D == 175 || 10214 <= D && D <= 10221 || 10629 <= D && D <= 10630 ? "Na" : D == 161 || D == 164 || 167 <= D && D <= 168 || D == 170 || 173 <= D && D <= 174 || 176 <= D && D <= 180 || 182 <= D && D <= 186 || 188 <= D && D <= 191 || D == 198 || D == 208 || 215 <= D && D <= 216 || 222 <= D && D <= 225 || D == 230 || 232 <= D && D <= 234 || 236 <= D && D <= 237 || D == 240 || 242 <= D && D <= 243 || 247 <= D && D <= 250 || D == 252 || D == 254 || D == 257 || D == 273 || D == 275 || D == 283 || 294 <= D && D <= 295 || D == 299 || 305 <= D && D <= 307 || D == 312 || 319 <= D && D <= 322 || D == 324 || 328 <= D && D <= 331 || D == 333 || 338 <= D && D <= 339 || 358 <= D && D <= 359 || D == 363 || D == 462 || D == 464 || D == 466 || D == 468 || D == 470 || D == 472 || D == 474 || D == 476 || D == 593 || D == 609 || D == 708 || D == 711 || 713 <= D && D <= 715 || D == 717 || D == 720 || 728 <= D && D <= 731 || D == 733 || D == 735 || 768 <= D && D <= 879 || 913 <= D && D <= 929 || 931 <= D && D <= 937 || 945 <= D && D <= 961 || 963 <= D && D <= 969 || D == 1025 || 1040 <= D && D <= 1103 || D == 1105 || D == 8208 || 8211 <= D && D <= 8214 || 8216 <= D && D <= 8217 || 8220 <= D && D <= 8221 || 8224 <= D && D <= 8226 || 8228 <= D && D <= 8231 || D == 8240 || 8242 <= D && D <= 8243 || D == 8245 || D == 8251 || D == 8254 || D == 8308 || D == 8319 || 8321 <= D && D <= 8324 || D == 8364 || D == 8451 || D == 8453 || D == 8457 || D == 8467 || D == 8470 || 8481 <= D && D <= 8482 || D == 8486 || D == 8491 || 8531 <= D && D <= 8532 || 8539 <= D && D <= 8542 || 8544 <= D && D <= 8555 || 8560 <= D && D <= 8569 || D == 8585 || 8592 <= D && D <= 8601 || 8632 <= D && D <= 8633 || D == 8658 || D == 8660 || D == 8679 || D == 8704 || 8706 <= D && D <= 8707 || 8711 <= D && D <= 8712 || D == 8715 || D == 8719 || D == 8721 || D == 8725 || D == 8730 || 8733 <= D && D <= 8736 || D == 8739 || D == 8741 || 8743 <= D && D <= 8748 || D == 8750 || 8756 <= D && D <= 8759 || 8764 <= D && D <= 8765 || D == 8776 || D == 8780 || D == 8786 || 8800 <= D && D <= 8801 || 8804 <= D && D <= 8807 || 8810 <= D && D <= 8811 || 8814 <= D && D <= 8815 || 8834 <= D && D <= 8835 || 8838 <= D && D <= 8839 || D == 8853 || D == 8857 || D == 8869 || D == 8895 || D == 8978 || 9312 <= D && D <= 9449 || 9451 <= D && D <= 9547 || 9552 <= D && D <= 9587 || 9600 <= D && D <= 9615 || 9618 <= D && D <= 9621 || 9632 <= D && D <= 9633 || 9635 <= D && D <= 9641 || 9650 <= D && D <= 9651 || 9654 <= D && D <= 9655 || 9660 <= D && D <= 9661 || 9664 <= D && D <= 9665 || 9670 <= D && D <= 9672 || D == 9675 || 9678 <= D && D <= 9681 || 9698 <= D && D <= 9701 || D == 9711 || 9733 <= D && D <= 9734 || D == 9737 || 9742 <= D && D <= 9743 || 9748 <= D && D <= 9749 || D == 9756 || D == 9758 || D == 9792 || D == 9794 || 9824 <= D && D <= 9825 || 9827 <= D && D <= 9829 || 9831 <= D && D <= 9834 || 9836 <= D && D <= 9837 || D == 9839 || 9886 <= D && D <= 9887 || 9918 <= D && D <= 9919 || 9924 <= D && D <= 9933 || 9935 <= D && D <= 9953 || D == 9955 || 9960 <= D && D <= 9983 || D == 10045 || D == 10071 || 10102 <= D && D <= 10111 || 11093 <= D && D <= 11097 || 12872 <= D && D <= 12879 || 57344 <= D && D <= 63743 || 65024 <= D && D <= 65039 || D == 65533 || 127232 <= D && D <= 127242 || 127248 <= D && D <= 127277 || 127280 <= D && D <= 127337 || 127344 <= D && D <= 127386 || 917760 <= D && D <= 917999 || 983040 <= D && D <= 1048573 || 1048576 <= D && D <= 1114109 ? "A" : "N";
|
|
2440
|
-
}, u.characterLength = function(F) {
|
|
2441
|
-
var s = this.eastAsianWidth(F);
|
|
2442
|
-
return s == "F" || s == "W" || s == "A" ? 2 : 1;
|
|
2443
|
-
};
|
|
2444
|
-
function t(F) {
|
|
2445
|
-
return F.match(/[\uD800-\uDBFF][\uDC00-\uDFFF]|[^\uD800-\uDFFF]/g) || [];
|
|
2446
|
-
}
|
|
2447
|
-
u.length = function(F) {
|
|
2448
|
-
for (var s = t(F), i = 0, D = 0;D < s.length; D++)
|
|
2449
|
-
i = i + this.characterLength(s[D]);
|
|
2450
|
-
return i;
|
|
2451
|
-
}, u.slice = function(F, s, i) {
|
|
2452
|
-
textLen = u.length(F), s = s || 0, i = i || 1, s < 0 && (s = textLen + s), i < 0 && (i = textLen + i);
|
|
2453
|
-
for (var D = "", C = 0, n = t(F), E = 0;E < n.length; E++) {
|
|
2454
|
-
var a = n[E], o = u.length(a);
|
|
2455
|
-
if (C >= s - (o == 2 ? 1 : 0))
|
|
2456
|
-
if (C + o <= i)
|
|
2457
|
-
D += a;
|
|
2458
|
-
else
|
|
2459
|
-
break;
|
|
2460
|
-
C += o;
|
|
2461
|
-
}
|
|
2462
|
-
return D;
|
|
2463
|
-
};
|
|
2464
|
-
})(W);
|
|
2465
|
-
var tD = W.exports;
|
|
2466
|
-
var eD = L(tD);
|
|
2467
|
-
var FD = function() {
|
|
2468
|
-
return /\uD83C\uDFF4\uDB40\uDC67\uDB40\uDC62(?:\uDB40\uDC77\uDB40\uDC6C\uDB40\uDC73|\uDB40\uDC73\uDB40\uDC63\uDB40\uDC74|\uDB40\uDC65\uDB40\uDC6E\uDB40\uDC67)\uDB40\uDC7F|(?:\uD83E\uDDD1\uD83C\uDFFF\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFF\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFE])|(?:\uD83E\uDDD1\uD83C\uDFFE\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFE\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFD\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFD\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFC\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFC\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|(?:\uD83E\uDDD1\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83E\uDDD1|\uD83D\uDC69\uD83C\uDFFB\u200D\uD83E\uDD1D\u200D(?:\uD83D[\uDC68\uDC69]))(?:\uD83C[\uDFFC-\uDFFF])|\uD83D\uDC68(?:\uD83C\uDFFB(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFC-\uDFFF])|[\u2695\u2696\u2708]\uFE0F|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))?|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFF]))|\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D)?\uD83D\uDC68|(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFE])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB-\uDFFD\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFC\uDFFE\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83E\uDD1D\u200D\uD83D\uDC68(?:\uD83C[\uDFFB\uDFFD-\uDFFF])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])\uFE0F|\u200D(?:(?:\uD83D[\uDC68\uDC69])\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D[\uDC66\uDC67])|\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC)?|(?:\uD83D\uDC69(?:\uD83C\uDFFB\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|(?:\uD83C[\uDFFC-\uDFFF])\u200D\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69]))|\uD83E\uDDD1(?:\uD83C[\uDFFB-\uDFFF])\u200D\uD83E\uDD1D\u200D\uD83E\uDDD1)(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67]))|\uD83D\uDC69(?:\u200D(?:\u2764\uFE0F\u200D(?:\uD83D\uDC8B\u200D(?:\uD83D[\uDC68\uDC69])|\uD83D[\uDC68\uDC69])|\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83E\uDDD1(?:\u200D(?:\uD83E\uDD1D\u200D\uD83E\uDDD1|\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFF\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFE\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFD\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFC\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD])|\uD83C\uDFFB\u200D(?:\uD83C[\uDF3E\uDF73\uDF7C\uDF84\uDF93\uDFA4\uDFA8\uDFEB\uDFED]|\uD83D[\uDCBB\uDCBC\uDD27\uDD2C\uDE80\uDE92]|\uD83E[\uDDAF-\uDDB3\uDDBC\uDDBD]))|\uD83D\uDC69\u200D\uD83D\uDC66\u200D\uD83D\uDC66|\uD83D\uDC69\u200D\uD83D\uDC69\u200D(?:\uD83D[\uDC66\uDC67])|\uD83D\uDC69\u200D\uD83D\uDC67\u200D(?:\uD83D[\uDC66\uDC67])|(?:\uD83D\uDC41\uFE0F\u200D\uD83D\uDDE8|\uD83E\uDDD1(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDC69(?:\uD83C\uDFFF\u200D[\u2695\u2696\u2708]|\uD83C\uDFFE\u200D[\u2695\u2696\u2708]|\uD83C\uDFFD\u200D[\u2695\u2696\u2708]|\uD83C\uDFFC\u200D[\u2695\u2696\u2708]|\uD83C\uDFFB\u200D[\u2695\u2696\u2708]|\u200D[\u2695\u2696\u2708])|\uD83D\uDE36\u200D\uD83C\uDF2B|\uD83C\uDFF3\uFE0F\u200D\u26A7|\uD83D\uDC3B\u200D\u2744|(?:(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF])\u200D[\u2640\u2642]|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])\u200D[\u2640\u2642]|\uD83C\uDFF4\u200D\u2620|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])\u200D[\u2640\u2642]|[\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u2328\u23CF\u23ED-\u23EF\u23F1\u23F2\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB\u25FC\u2600-\u2604\u260E\u2611\u2618\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u2692\u2694-\u2697\u2699\u269B\u269C\u26A0\u26A7\u26B0\u26B1\u26C8\u26CF\u26D1\u26D3\u26E9\u26F0\u26F1\u26F4\u26F7\u26F8\u2702\u2708\u2709\u270F\u2712\u2714\u2716\u271D\u2721\u2733\u2734\u2744\u2747\u2763\u27A1\u2934\u2935\u2B05-\u2B07\u3030\u303D\u3297\u3299]|\uD83C[\uDD70\uDD71\uDD7E\uDD7F\uDE02\uDE37\uDF21\uDF24-\uDF2C\uDF36\uDF7D\uDF96\uDF97\uDF99-\uDF9B\uDF9E\uDF9F\uDFCD\uDFCE\uDFD4-\uDFDF\uDFF5\uDFF7]|\uD83D[\uDC3F\uDCFD\uDD49\uDD4A\uDD6F\uDD70\uDD73\uDD76-\uDD79\uDD87\uDD8A-\uDD8D\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA\uDECB\uDECD-\uDECF\uDEE0-\uDEE5\uDEE9\uDEF0\uDEF3])\uFE0F|\uD83C\uDFF3\uFE0F\u200D\uD83C\uDF08|\uD83D\uDC69\u200D\uD83D\uDC67|\uD83D\uDC69\u200D\uD83D\uDC66|\uD83D\uDE35\u200D\uD83D\uDCAB|\uD83D\uDE2E\u200D\uD83D\uDCA8|\uD83D\uDC15\u200D\uD83E\uDDBA|\uD83E\uDDD1(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83D\uDC69(?:\uD83C\uDFFF|\uD83C\uDFFE|\uD83C\uDFFD|\uD83C\uDFFC|\uD83C\uDFFB)?|\uD83C\uDDFD\uD83C\uDDF0|\uD83C\uDDF6\uD83C\uDDE6|\uD83C\uDDF4\uD83C\uDDF2|\uD83D\uDC08\u200D\u2B1B|\u2764\uFE0F\u200D(?:\uD83D\uDD25|\uD83E\uDE79)|\uD83D\uDC41\uFE0F|\uD83C\uDFF3\uFE0F|\uD83C\uDDFF(?:\uD83C[\uDDE6\uDDF2\uDDFC])|\uD83C\uDDFE(?:\uD83C[\uDDEA\uDDF9])|\uD83C\uDDFC(?:\uD83C[\uDDEB\uDDF8])|\uD83C\uDDFB(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDEE\uDDF3\uDDFA])|\uD83C\uDDFA(?:\uD83C[\uDDE6\uDDEC\uDDF2\uDDF3\uDDF8\uDDFE\uDDFF])|\uD83C\uDDF9(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDED\uDDEF-\uDDF4\uDDF7\uDDF9\uDDFB\uDDFC\uDDFF])|\uD83C\uDDF8(?:\uD83C[\uDDE6-\uDDEA\uDDEC-\uDDF4\uDDF7-\uDDF9\uDDFB\uDDFD-\uDDFF])|\uD83C\uDDF7(?:\uD83C[\uDDEA\uDDF4\uDDF8\uDDFA\uDDFC])|\uD83C\uDDF5(?:\uD83C[\uDDE6\uDDEA-\uDDED\uDDF0-\uDDF3\uDDF7-\uDDF9\uDDFC\uDDFE])|\uD83C\uDDF3(?:\uD83C[\uDDE6\uDDE8\uDDEA-\uDDEC\uDDEE\uDDF1\uDDF4\uDDF5\uDDF7\uDDFA\uDDFF])|\uD83C\uDDF2(?:\uD83C[\uDDE6\uDDE8-\uDDED\uDDF0-\uDDFF])|\uD83C\uDDF1(?:\uD83C[\uDDE6-\uDDE8\uDDEE\uDDF0\uDDF7-\uDDFB\uDDFE])|\uD83C\uDDF0(?:\uD83C[\uDDEA\uDDEC-\uDDEE\uDDF2\uDDF3\uDDF5\uDDF7\uDDFC\uDDFE\uDDFF])|\uD83C\uDDEF(?:\uD83C[\uDDEA\uDDF2\uDDF4\uDDF5])|\uD83C\uDDEE(?:\uD83C[\uDDE8-\uDDEA\uDDF1-\uDDF4\uDDF6-\uDDF9])|\uD83C\uDDED(?:\uD83C[\uDDF0\uDDF2\uDDF3\uDDF7\uDDF9\uDDFA])|\uD83C\uDDEC(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEE\uDDF1-\uDDF3\uDDF5-\uDDFA\uDDFC\uDDFE])|\uD83C\uDDEB(?:\uD83C[\uDDEE-\uDDF0\uDDF2\uDDF4\uDDF7])|\uD83C\uDDEA(?:\uD83C[\uDDE6\uDDE8\uDDEA\uDDEC\uDDED\uDDF7-\uDDFA])|\uD83C\uDDE9(?:\uD83C[\uDDEA\uDDEC\uDDEF\uDDF0\uDDF2\uDDF4\uDDFF])|\uD83C\uDDE8(?:\uD83C[\uDDE6\uDDE8\uDDE9\uDDEB-\uDDEE\uDDF0-\uDDF5\uDDF7\uDDFA-\uDDFF])|\uD83C\uDDE7(?:\uD83C[\uDDE6\uDDE7\uDDE9-\uDDEF\uDDF1-\uDDF4\uDDF6-\uDDF9\uDDFB\uDDFC\uDDFE\uDDFF])|\uD83C\uDDE6(?:\uD83C[\uDDE8-\uDDEC\uDDEE\uDDF1\uDDF2\uDDF4\uDDF6-\uDDFA\uDDFC\uDDFD\uDDFF])|[#\*0-9]\uFE0F\u20E3|\u2764\uFE0F|(?:\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD])(?:\uD83C[\uDFFB-\uDFFF])|(?:\u26F9|\uD83C[\uDFCB\uDFCC]|\uD83D\uDD75)(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|\uD83C\uDFF4|(?:[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5])(?:\uD83C[\uDFFB-\uDFFF])|(?:[\u261D\u270C\u270D]|\uD83D[\uDD74\uDD90])(?:\uFE0F|\uD83C[\uDFFB-\uDFFF])|[\u270A\u270B]|\uD83C[\uDF85\uDFC2\uDFC7]|\uD83D[\uDC08\uDC15\uDC3B\uDC42\uDC43\uDC46-\uDC50\uDC66\uDC67\uDC6B-\uDC6D\uDC72\uDC74-\uDC76\uDC78\uDC7C\uDC83\uDC85\uDC8F\uDC91\uDCAA\uDD7A\uDD95\uDD96\uDE2E\uDE35\uDE36\uDE4C\uDE4F\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1C\uDD1E\uDD1F\uDD30-\uDD34\uDD36\uDD77\uDDB5\uDDB6\uDDBB\uDDD2\uDDD3\uDDD5]|\uD83C[\uDFC3\uDFC4\uDFCA]|\uD83D[\uDC6E\uDC70\uDC71\uDC73\uDC77\uDC81\uDC82\uDC86\uDC87\uDE45-\uDE47\uDE4B\uDE4D\uDE4E\uDEA3\uDEB4-\uDEB6]|\uD83E[\uDD26\uDD35\uDD37-\uDD39\uDD3D\uDD3E\uDDB8\uDDB9\uDDCD-\uDDCF\uDDD4\uDDD6-\uDDDD]|\uD83D\uDC6F|\uD83E[\uDD3C\uDDDE\uDDDF]|[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF84\uDF86-\uDF93\uDFA0-\uDFC1\uDFC5\uDFC6\uDFC8\uDFC9\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC07\uDC09-\uDC14\uDC16-\uDC3A\uDC3C-\uDC3E\uDC40\uDC44\uDC45\uDC51-\uDC65\uDC6A\uDC79-\uDC7B\uDC7D-\uDC80\uDC84\uDC88-\uDC8E\uDC90\uDC92-\uDCA9\uDCAB-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDDA4\uDDFB-\uDE2D\uDE2F-\uDE34\uDE37-\uDE44\uDE48-\uDE4A\uDE80-\uDEA2\uDEA4-\uDEB3\uDEB7-\uDEBF\uDEC1-\uDEC5\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0D\uDD0E\uDD10-\uDD17\uDD1D\uDD20-\uDD25\uDD27-\uDD2F\uDD3A\uDD3F-\uDD45\uDD47-\uDD76\uDD78\uDD7A-\uDDB4\uDDB7\uDDBA\uDDBC-\uDDCB\uDDD0\uDDE0-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6]|(?:[\u231A\u231B\u23E9-\u23EC\u23F0\u23F3\u25FD\u25FE\u2614\u2615\u2648-\u2653\u267F\u2693\u26A1\u26AA\u26AB\u26BD\u26BE\u26C4\u26C5\u26CE\u26D4\u26EA\u26F2\u26F3\u26F5\u26FA\u26FD\u2705\u270A\u270B\u2728\u274C\u274E\u2753-\u2755\u2757\u2795-\u2797\u27B0\u27BF\u2B1B\u2B1C\u2B50\u2B55]|\uD83C[\uDC04\uDCCF\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE1A\uDE2F\uDE32-\uDE36\uDE38-\uDE3A\uDE50\uDE51\uDF00-\uDF20\uDF2D-\uDF35\uDF37-\uDF7C\uDF7E-\uDF93\uDFA0-\uDFCA\uDFCF-\uDFD3\uDFE0-\uDFF0\uDFF4\uDFF8-\uDFFF]|\uD83D[\uDC00-\uDC3E\uDC40\uDC42-\uDCFC\uDCFF-\uDD3D\uDD4B-\uDD4E\uDD50-\uDD67\uDD7A\uDD95\uDD96\uDDA4\uDDFB-\uDE4F\uDE80-\uDEC5\uDECC\uDED0-\uDED2\uDED5-\uDED7\uDEEB\uDEEC\uDEF4-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])|(?:[#\*0-9\xA9\xAE\u203C\u2049\u2122\u2139\u2194-\u2199\u21A9\u21AA\u231A\u231B\u2328\u23CF\u23E9-\u23F3\u23F8-\u23FA\u24C2\u25AA\u25AB\u25B6\u25C0\u25FB-\u25FE\u2600-\u2604\u260E\u2611\u2614\u2615\u2618\u261D\u2620\u2622\u2623\u2626\u262A\u262E\u262F\u2638-\u263A\u2640\u2642\u2648-\u2653\u265F\u2660\u2663\u2665\u2666\u2668\u267B\u267E\u267F\u2692-\u2697\u2699\u269B\u269C\u26A0\u26A1\u26A7\u26AA\u26AB\u26B0\u26B1\u26BD\u26BE\u26C4\u26C5\u26C8\u26CE\u26CF\u26D1\u26D3\u26D4\u26E9\u26EA\u26F0-\u26F5\u26F7-\u26FA\u26FD\u2702\u2705\u2708-\u270D\u270F\u2712\u2714\u2716\u271D\u2721\u2728\u2733\u2734\u2744\u2747\u274C\u274E\u2753-\u2755\u2757\u2763\u2764\u2795-\u2797\u27A1\u27B0\u27BF\u2934\u2935\u2B05-\u2B07\u2B1B\u2B1C\u2B50\u2B55\u3030\u303D\u3297\u3299]|\uD83C[\uDC04\uDCCF\uDD70\uDD71\uDD7E\uDD7F\uDD8E\uDD91-\uDD9A\uDDE6-\uDDFF\uDE01\uDE02\uDE1A\uDE2F\uDE32-\uDE3A\uDE50\uDE51\uDF00-\uDF21\uDF24-\uDF93\uDF96\uDF97\uDF99-\uDF9B\uDF9E-\uDFF0\uDFF3-\uDFF5\uDFF7-\uDFFF]|\uD83D[\uDC00-\uDCFD\uDCFF-\uDD3D\uDD49-\uDD4E\uDD50-\uDD67\uDD6F\uDD70\uDD73-\uDD7A\uDD87\uDD8A-\uDD8D\uDD90\uDD95\uDD96\uDDA4\uDDA5\uDDA8\uDDB1\uDDB2\uDDBC\uDDC2-\uDDC4\uDDD1-\uDDD3\uDDDC-\uDDDE\uDDE1\uDDE3\uDDE8\uDDEF\uDDF3\uDDFA-\uDE4F\uDE80-\uDEC5\uDECB-\uDED2\uDED5-\uDED7\uDEE0-\uDEE5\uDEE9\uDEEB\uDEEC\uDEF0\uDEF3-\uDEFC\uDFE0-\uDFEB]|\uD83E[\uDD0C-\uDD3A\uDD3C-\uDD45\uDD47-\uDD78\uDD7A-\uDDCB\uDDCD-\uDDFF\uDE70-\uDE74\uDE78-\uDE7A\uDE80-\uDE86\uDE90-\uDEA8\uDEB0-\uDEB6\uDEC0-\uDEC2\uDED0-\uDED6])\uFE0F|(?:[\u261D\u26F9\u270A-\u270D]|\uD83C[\uDF85\uDFC2-\uDFC4\uDFC7\uDFCA-\uDFCC]|\uD83D[\uDC42\uDC43\uDC46-\uDC50\uDC66-\uDC78\uDC7C\uDC81-\uDC83\uDC85-\uDC87\uDC8F\uDC91\uDCAA\uDD74\uDD75\uDD7A\uDD90\uDD95\uDD96\uDE45-\uDE47\uDE4B-\uDE4F\uDEA3\uDEB4-\uDEB6\uDEC0\uDECC]|\uD83E[\uDD0C\uDD0F\uDD18-\uDD1F\uDD26\uDD30-\uDD39\uDD3C-\uDD3E\uDD77\uDDB5\uDDB6\uDDB8\uDDB9\uDDBB\uDDCD-\uDDCF\uDDD1-\uDDDD])/g;
|
|
2469
|
-
};
|
|
2470
|
-
var sD = L(FD);
|
|
2471
|
-
function p(e, u = {}) {
|
|
2472
|
-
if (typeof e != "string" || e.length === 0 || (u = { ambiguousIsNarrow: true, ...u }, e = P(e), e.length === 0))
|
|
2473
|
-
return 0;
|
|
2474
|
-
e = e.replace(sD(), " ");
|
|
2475
|
-
const t = u.ambiguousIsNarrow ? 1 : 2;
|
|
2476
|
-
let F = 0;
|
|
2477
|
-
for (const s of e) {
|
|
2478
|
-
const i = s.codePointAt(0);
|
|
2479
|
-
if (i <= 31 || i >= 127 && i <= 159 || i >= 768 && i <= 879)
|
|
2480
|
-
continue;
|
|
2481
|
-
switch (eD.eastAsianWidth(s)) {
|
|
2482
|
-
case "F":
|
|
2483
|
-
case "W":
|
|
2484
|
-
F += 2;
|
|
2485
|
-
break;
|
|
2486
|
-
case "A":
|
|
2487
|
-
F += t;
|
|
2488
|
-
break;
|
|
2489
|
-
default:
|
|
2490
|
-
F += 1;
|
|
2491
|
-
}
|
|
2492
|
-
}
|
|
2493
|
-
return F;
|
|
2494
|
-
}
|
|
2495
|
-
var w = 10;
|
|
2496
|
-
var N = (e = 0) => (u) => `\x1B[${u + e}m`;
|
|
2497
|
-
var I = (e = 0) => (u) => `\x1B[${38 + e};5;${u}m`;
|
|
2498
|
-
var R = (e = 0) => (u, t, F) => `\x1B[${38 + e};2;${u};${t};${F}m`;
|
|
2499
|
-
var r = { modifier: { reset: [0, 0], bold: [1, 22], dim: [2, 22], italic: [3, 23], underline: [4, 24], overline: [53, 55], inverse: [7, 27], hidden: [8, 28], strikethrough: [9, 29] }, color: { black: [30, 39], red: [31, 39], green: [32, 39], yellow: [33, 39], blue: [34, 39], magenta: [35, 39], cyan: [36, 39], white: [37, 39], blackBright: [90, 39], gray: [90, 39], grey: [90, 39], redBright: [91, 39], greenBright: [92, 39], yellowBright: [93, 39], blueBright: [94, 39], magentaBright: [95, 39], cyanBright: [96, 39], whiteBright: [97, 39] }, bgColor: { bgBlack: [40, 49], bgRed: [41, 49], bgGreen: [42, 49], bgYellow: [43, 49], bgBlue: [44, 49], bgMagenta: [45, 49], bgCyan: [46, 49], bgWhite: [47, 49], bgBlackBright: [100, 49], bgGray: [100, 49], bgGrey: [100, 49], bgRedBright: [101, 49], bgGreenBright: [102, 49], bgYellowBright: [103, 49], bgBlueBright: [104, 49], bgMagentaBright: [105, 49], bgCyanBright: [106, 49], bgWhiteBright: [107, 49] } };
|
|
2500
|
-
Object.keys(r.modifier);
|
|
2501
|
-
var iD = Object.keys(r.color);
|
|
2502
|
-
var CD = Object.keys(r.bgColor);
|
|
2503
|
-
[...iD, ...CD];
|
|
2504
|
-
function rD() {
|
|
2505
|
-
const e = new Map;
|
|
2506
|
-
for (const [u, t] of Object.entries(r)) {
|
|
2507
|
-
for (const [F, s] of Object.entries(t))
|
|
2508
|
-
r[F] = { open: `\x1B[${s[0]}m`, close: `\x1B[${s[1]}m` }, t[F] = r[F], e.set(s[0], s[1]);
|
|
2509
|
-
Object.defineProperty(r, u, { value: t, enumerable: false });
|
|
2510
|
-
}
|
|
2511
|
-
return Object.defineProperty(r, "codes", { value: e, enumerable: false }), r.color.close = "\x1B[39m", r.bgColor.close = "\x1B[49m", r.color.ansi = N(), r.color.ansi256 = I(), r.color.ansi16m = R(), r.bgColor.ansi = N(w), r.bgColor.ansi256 = I(w), r.bgColor.ansi16m = R(w), Object.defineProperties(r, { rgbToAnsi256: { value: (u, t, F) => u === t && t === F ? u < 8 ? 16 : u > 248 ? 231 : Math.round((u - 8) / 247 * 24) + 232 : 16 + 36 * Math.round(u / 255 * 5) + 6 * Math.round(t / 255 * 5) + Math.round(F / 255 * 5), enumerable: false }, hexToRgb: { value: (u) => {
|
|
2512
|
-
const t = /[a-f\d]{6}|[a-f\d]{3}/i.exec(u.toString(16));
|
|
2513
|
-
if (!t)
|
|
2514
|
-
return [0, 0, 0];
|
|
2515
|
-
let [F] = t;
|
|
2516
|
-
F.length === 3 && (F = [...F].map((i) => i + i).join(""));
|
|
2517
|
-
const s = Number.parseInt(F, 16);
|
|
2518
|
-
return [s >> 16 & 255, s >> 8 & 255, s & 255];
|
|
2519
|
-
}, enumerable: false }, hexToAnsi256: { value: (u) => r.rgbToAnsi256(...r.hexToRgb(u)), enumerable: false }, ansi256ToAnsi: { value: (u) => {
|
|
2520
|
-
if (u < 8)
|
|
2521
|
-
return 30 + u;
|
|
2522
|
-
if (u < 16)
|
|
2523
|
-
return 90 + (u - 8);
|
|
2524
|
-
let t, F, s;
|
|
2525
|
-
if (u >= 232)
|
|
2526
|
-
t = ((u - 232) * 10 + 8) / 255, F = t, s = t;
|
|
2527
|
-
else {
|
|
2528
|
-
u -= 16;
|
|
2529
|
-
const C = u % 36;
|
|
2530
|
-
t = Math.floor(u / 36) / 5, F = Math.floor(C / 6) / 5, s = C % 6 / 5;
|
|
2531
|
-
}
|
|
2532
|
-
const i = Math.max(t, F, s) * 2;
|
|
2533
|
-
if (i === 0)
|
|
2534
|
-
return 30;
|
|
2535
|
-
let D = 30 + (Math.round(s) << 2 | Math.round(F) << 1 | Math.round(t));
|
|
2536
|
-
return i === 2 && (D += 60), D;
|
|
2537
|
-
}, enumerable: false }, rgbToAnsi: { value: (u, t, F) => r.ansi256ToAnsi(r.rgbToAnsi256(u, t, F)), enumerable: false }, hexToAnsi: { value: (u) => r.ansi256ToAnsi(r.hexToAnsi256(u)), enumerable: false } }), r;
|
|
2538
|
-
}
|
|
2539
|
-
var ED = rD();
|
|
2540
|
-
var d = new Set(["\x1B", "\x9B"]);
|
|
2541
|
-
var oD = 39;
|
|
2542
|
-
var y = "\x07";
|
|
2543
|
-
var V = "[";
|
|
2544
|
-
var nD = "]";
|
|
2545
|
-
var G = "m";
|
|
2546
|
-
var _ = `${nD}8;;`;
|
|
2547
|
-
var z = (e) => `${d.values().next().value}${V}${e}${G}`;
|
|
2548
|
-
var K = (e) => `${d.values().next().value}${_}${e}${y}`;
|
|
2549
|
-
var aD = (e) => e.split(" ").map((u) => p(u));
|
|
2550
|
-
var k = (e, u, t) => {
|
|
2551
|
-
const F = [...u];
|
|
2552
|
-
let s = false, i = false, D = p(P(e[e.length - 1]));
|
|
2553
|
-
for (const [C, n] of F.entries()) {
|
|
2554
|
-
const E = p(n);
|
|
2555
|
-
if (D + E <= t ? e[e.length - 1] += n : (e.push(n), D = 0), d.has(n) && (s = true, i = F.slice(C + 1).join("").startsWith(_)), s) {
|
|
2556
|
-
i ? n === y && (s = false, i = false) : n === G && (s = false);
|
|
2557
|
-
continue;
|
|
2558
|
-
}
|
|
2559
|
-
D += E, D === t && C < F.length - 1 && (e.push(""), D = 0);
|
|
2560
|
-
}
|
|
2561
|
-
!D && e[e.length - 1].length > 0 && e.length > 1 && (e[e.length - 2] += e.pop());
|
|
2562
|
-
};
|
|
2563
|
-
var hD = (e) => {
|
|
2564
|
-
const u = e.split(" ");
|
|
2565
|
-
let t = u.length;
|
|
2566
|
-
for (;t > 0 && !(p(u[t - 1]) > 0); )
|
|
2567
|
-
t--;
|
|
2568
|
-
return t === u.length ? e : u.slice(0, t).join(" ") + u.slice(t).join("");
|
|
2569
|
-
};
|
|
2570
|
-
var lD = (e, u, t = {}) => {
|
|
2571
|
-
if (t.trim !== false && e.trim() === "")
|
|
2572
|
-
return "";
|
|
2573
|
-
let F = "", s, i;
|
|
2574
|
-
const D = aD(e);
|
|
2575
|
-
let C = [""];
|
|
2576
|
-
for (const [E, a] of e.split(" ").entries()) {
|
|
2577
|
-
t.trim !== false && (C[C.length - 1] = C[C.length - 1].trimStart());
|
|
2578
|
-
let o = p(C[C.length - 1]);
|
|
2579
|
-
if (E !== 0 && (o >= u && (t.wordWrap === false || t.trim === false) && (C.push(""), o = 0), (o > 0 || t.trim === false) && (C[C.length - 1] += " ", o++)), t.hard && D[E] > u) {
|
|
2580
|
-
const c = u - o, f = 1 + Math.floor((D[E] - c - 1) / u);
|
|
2581
|
-
Math.floor((D[E] - 1) / u) < f && C.push(""), k(C, a, u);
|
|
2582
|
-
continue;
|
|
2583
|
-
}
|
|
2584
|
-
if (o + D[E] > u && o > 0 && D[E] > 0) {
|
|
2585
|
-
if (t.wordWrap === false && o < u) {
|
|
2586
|
-
k(C, a, u);
|
|
2587
|
-
continue;
|
|
2588
|
-
}
|
|
2589
|
-
C.push("");
|
|
2590
|
-
}
|
|
2591
|
-
if (o + D[E] > u && t.wordWrap === false) {
|
|
2592
|
-
k(C, a, u);
|
|
2593
|
-
continue;
|
|
2594
|
-
}
|
|
2595
|
-
C[C.length - 1] += a;
|
|
2596
|
-
}
|
|
2597
|
-
t.trim !== false && (C = C.map((E) => hD(E)));
|
|
2598
|
-
const n = [...C.join(`
|
|
2599
|
-
`)];
|
|
2600
|
-
for (const [E, a] of n.entries()) {
|
|
2601
|
-
if (F += a, d.has(a)) {
|
|
2602
|
-
const { groups: c } = new RegExp(`(?:\\${V}(?<code>\\d+)m|\\${_}(?<uri>.*)${y})`).exec(n.slice(E).join("")) || { groups: {} };
|
|
2603
|
-
if (c.code !== undefined) {
|
|
2604
|
-
const f = Number.parseFloat(c.code);
|
|
2605
|
-
s = f === oD ? undefined : f;
|
|
2606
|
-
} else
|
|
2607
|
-
c.uri !== undefined && (i = c.uri.length === 0 ? undefined : c.uri);
|
|
2608
|
-
}
|
|
2609
|
-
const o = ED.codes.get(Number(s));
|
|
2610
|
-
n[E + 1] === `
|
|
2611
|
-
` ? (i && (F += K("")), s && o && (F += z(o))) : a === `
|
|
2612
|
-
` && (s && o && (F += z(s)), i && (F += K(i)));
|
|
2613
|
-
}
|
|
2614
|
-
return F;
|
|
2615
|
-
};
|
|
2616
|
-
function Y(e, u, t) {
|
|
2617
|
-
return String(e).normalize().replace(/\r\n/g, `
|
|
2618
|
-
`).split(`
|
|
2619
|
-
`).map((F) => lD(F, u, t)).join(`
|
|
2620
|
-
`);
|
|
2621
|
-
}
|
|
2622
|
-
var xD = ["up", "down", "left", "right", "space", "enter", "cancel"];
|
|
2623
|
-
var B = { actions: new Set(xD), aliases: new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["\x03", "cancel"], ["escape", "cancel"]]) };
|
|
2624
|
-
function $(e, u) {
|
|
2625
|
-
if (typeof e == "string")
|
|
2626
|
-
return B.aliases.get(e) === u;
|
|
2627
|
-
for (const t of e)
|
|
2628
|
-
if (t !== undefined && $(t, u))
|
|
2629
|
-
return true;
|
|
2630
|
-
return false;
|
|
2631
|
-
}
|
|
2632
|
-
function BD(e, u) {
|
|
2633
|
-
if (e === u)
|
|
2634
|
-
return;
|
|
2635
|
-
const t = e.split(`
|
|
2636
|
-
`), F = u.split(`
|
|
2637
|
-
`), s = [];
|
|
2638
|
-
for (let i = 0;i < Math.max(t.length, F.length); i++)
|
|
2639
|
-
t[i] !== F[i] && s.push(i);
|
|
2640
|
-
return s;
|
|
2641
|
-
}
|
|
2642
|
-
var AD = globalThis.process.platform.startsWith("win");
|
|
2643
|
-
var S = Symbol("clack:cancel");
|
|
2644
|
-
function pD(e) {
|
|
2645
|
-
return e === S;
|
|
2646
|
-
}
|
|
2647
|
-
function m(e, u) {
|
|
2648
|
-
const t = e;
|
|
2649
|
-
t.isTTY && t.setRawMode(u);
|
|
2650
|
-
}
|
|
2651
|
-
var gD = Object.defineProperty;
|
|
2652
|
-
var vD = (e, u, t) => (u in e) ? gD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
2653
|
-
var h = (e, u, t) => (vD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
2654
|
-
|
|
2655
|
-
class x {
|
|
2656
|
-
constructor(u, t = true) {
|
|
2657
|
-
h(this, "input"), h(this, "output"), h(this, "_abortSignal"), h(this, "rl"), h(this, "opts"), h(this, "_render"), h(this, "_track", false), h(this, "_prevFrame", ""), h(this, "_subscribers", new Map), h(this, "_cursor", 0), h(this, "state", "initial"), h(this, "error", ""), h(this, "value");
|
|
2658
|
-
const { input: F = j, output: s = M, render: i, signal: D, ...C } = u;
|
|
2659
|
-
this.opts = C, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = i.bind(this), this._track = t, this._abortSignal = D, this.input = F, this.output = s;
|
|
2660
|
-
}
|
|
2661
|
-
unsubscribe() {
|
|
2662
|
-
this._subscribers.clear();
|
|
2663
|
-
}
|
|
2664
|
-
setSubscriber(u, t) {
|
|
2665
|
-
const F = this._subscribers.get(u) ?? [];
|
|
2666
|
-
F.push(t), this._subscribers.set(u, F);
|
|
2667
|
-
}
|
|
2668
|
-
on(u, t) {
|
|
2669
|
-
this.setSubscriber(u, { cb: t });
|
|
2670
|
-
}
|
|
2671
|
-
once(u, t) {
|
|
2672
|
-
this.setSubscriber(u, { cb: t, once: true });
|
|
2673
|
-
}
|
|
2674
|
-
emit(u, ...t) {
|
|
2675
|
-
const F = this._subscribers.get(u) ?? [], s = [];
|
|
2676
|
-
for (const i of F)
|
|
2677
|
-
i.cb(...t), i.once && s.push(() => F.splice(F.indexOf(i), 1));
|
|
2678
|
-
for (const i of s)
|
|
2679
|
-
i();
|
|
2680
|
-
}
|
|
2681
|
-
prompt() {
|
|
2682
|
-
return new Promise((u, t) => {
|
|
2683
|
-
if (this._abortSignal) {
|
|
2684
|
-
if (this._abortSignal.aborted)
|
|
2685
|
-
return this.state = "cancel", this.close(), u(S);
|
|
2686
|
-
this._abortSignal.addEventListener("abort", () => {
|
|
2687
|
-
this.state = "cancel", this.close();
|
|
2688
|
-
}, { once: true });
|
|
2689
|
-
}
|
|
2690
|
-
const F = new X;
|
|
2691
|
-
F._write = (s, i, D) => {
|
|
2692
|
-
this._track && (this.value = this.rl?.line.replace(/\t/g, ""), this._cursor = this.rl?.cursor ?? 0, this.emit("value", this.value)), D();
|
|
2693
|
-
}, this.input.pipe(F), this.rl = O.createInterface({ input: this.input, output: F, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), O.emitKeypressEvents(this.input, this.rl), this.rl.prompt(), this.opts.initialValue !== undefined && this._track && this.rl.write(this.opts.initialValue), this.input.on("keypress", this.onKeypress), m(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
|
|
2694
|
-
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(this.value);
|
|
2695
|
-
}), this.once("cancel", () => {
|
|
2696
|
-
this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), m(this.input, false), u(S);
|
|
2697
|
-
});
|
|
2698
|
-
});
|
|
2699
|
-
}
|
|
2700
|
-
onKeypress(u, t) {
|
|
2701
|
-
if (this.state === "error" && (this.state = "active"), t?.name && (!this._track && B.aliases.has(t.name) && this.emit("cursor", B.aliases.get(t.name)), B.actions.has(t.name) && this.emit("cursor", t.name)), u && (u.toLowerCase() === "y" || u.toLowerCase() === "n") && this.emit("confirm", u.toLowerCase() === "y"), u === "\t" && this.opts.placeholder && (this.value || (this.rl?.write(this.opts.placeholder), this.emit("value", this.opts.placeholder))), u && this.emit("key", u.toLowerCase()), t?.name === "return") {
|
|
2702
|
-
if (this.opts.validate) {
|
|
2703
|
-
const F = this.opts.validate(this.value);
|
|
2704
|
-
F && (this.error = F instanceof Error ? F.message : F, this.state = "error", this.rl?.write(this.value));
|
|
2705
|
-
}
|
|
2706
|
-
this.state !== "error" && (this.state = "submit");
|
|
2707
|
-
}
|
|
2708
|
-
$([u, t?.name, t?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
|
|
2709
|
-
}
|
|
2710
|
-
close() {
|
|
2711
|
-
this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
|
|
2712
|
-
`), m(this.input, false), this.rl?.close(), this.rl = undefined, this.emit(`${this.state}`, this.value), this.unsubscribe();
|
|
2713
|
-
}
|
|
2714
|
-
restoreCursor() {
|
|
2715
|
-
const u = Y(this._prevFrame, process.stdout.columns, { hard: true }).split(`
|
|
2716
|
-
`).length - 1;
|
|
2717
|
-
this.output.write(import_sisteransi.cursor.move(-999, u * -1));
|
|
2718
|
-
}
|
|
2719
|
-
render() {
|
|
2720
|
-
const u = Y(this._render(this) ?? "", process.stdout.columns, { hard: true });
|
|
2721
|
-
if (u !== this._prevFrame) {
|
|
2722
|
-
if (this.state === "initial")
|
|
2723
|
-
this.output.write(import_sisteransi.cursor.hide);
|
|
2724
|
-
else {
|
|
2725
|
-
const t = BD(this._prevFrame, u);
|
|
2726
|
-
if (this.restoreCursor(), t && t?.length === 1) {
|
|
2727
|
-
const F = t[0];
|
|
2728
|
-
this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.lines(1));
|
|
2729
|
-
const s = u.split(`
|
|
2730
|
-
`);
|
|
2731
|
-
this.output.write(s[F]), this._prevFrame = u, this.output.write(import_sisteransi.cursor.move(0, s.length - F - 1));
|
|
2732
|
-
return;
|
|
2733
|
-
}
|
|
2734
|
-
if (t && t?.length > 1) {
|
|
2735
|
-
const F = t[0];
|
|
2736
|
-
this.output.write(import_sisteransi.cursor.move(0, F)), this.output.write(import_sisteransi.erase.down());
|
|
2737
|
-
const s = u.split(`
|
|
2738
|
-
`).slice(F);
|
|
2739
|
-
this.output.write(s.join(`
|
|
2740
|
-
`)), this._prevFrame = u;
|
|
2741
|
-
return;
|
|
2742
|
-
}
|
|
2743
|
-
this.output.write(import_sisteransi.erase.down());
|
|
2744
|
-
}
|
|
2745
|
-
this.output.write(u), this.state === "initial" && (this.state = "active"), this._prevFrame = u;
|
|
2746
|
-
}
|
|
2747
|
-
}
|
|
2748
|
-
}
|
|
2749
|
-
|
|
2750
|
-
class dD extends x {
|
|
2751
|
-
get cursor() {
|
|
2752
|
-
return this.value ? 0 : 1;
|
|
2753
|
-
}
|
|
2754
|
-
get _value() {
|
|
2755
|
-
return this.cursor === 0;
|
|
2756
|
-
}
|
|
2757
|
-
constructor(u) {
|
|
2758
|
-
super(u, false), this.value = !!u.initialValue, this.on("value", () => {
|
|
2759
|
-
this.value = this._value;
|
|
2760
|
-
}), this.on("confirm", (t) => {
|
|
2761
|
-
this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = t, this.state = "submit", this.close();
|
|
2762
|
-
}), this.on("cursor", () => {
|
|
2763
|
-
this.value = !this.value;
|
|
2764
|
-
});
|
|
2765
|
-
}
|
|
2766
|
-
}
|
|
2767
|
-
var A;
|
|
2768
|
-
A = new WeakMap;
|
|
2769
|
-
var OD = Object.defineProperty;
|
|
2770
|
-
var PD = (e, u, t) => (u in e) ? OD(e, u, { enumerable: true, configurable: true, writable: true, value: t }) : e[u] = t;
|
|
2771
|
-
var J = (e, u, t) => (PD(e, typeof u != "symbol" ? u + "" : u, t), t);
|
|
2772
|
-
|
|
2773
|
-
class LD extends x {
|
|
2774
|
-
constructor(u) {
|
|
2775
|
-
super(u, false), J(this, "options"), J(this, "cursor", 0), this.options = u.options, this.cursor = this.options.findIndex(({ value: t }) => t === u.initialValue), this.cursor === -1 && (this.cursor = 0), this.changeValue(), this.on("cursor", (t) => {
|
|
2776
|
-
switch (t) {
|
|
2777
|
-
case "left":
|
|
2778
|
-
case "up":
|
|
2779
|
-
this.cursor = this.cursor === 0 ? this.options.length - 1 : this.cursor - 1;
|
|
2780
|
-
break;
|
|
2781
|
-
case "down":
|
|
2782
|
-
case "right":
|
|
2783
|
-
this.cursor = this.cursor === this.options.length - 1 ? 0 : this.cursor + 1;
|
|
2784
|
-
break;
|
|
2785
|
-
}
|
|
2786
|
-
this.changeValue();
|
|
2787
|
-
});
|
|
2788
|
-
}
|
|
2789
|
-
get _value() {
|
|
2790
|
-
return this.options[this.cursor];
|
|
2791
|
-
}
|
|
2792
|
-
changeValue() {
|
|
2793
|
-
this.value = this._value.value;
|
|
2794
|
-
}
|
|
2795
|
-
}
|
|
2796
|
-
|
|
2797
|
-
// node_modules/@clack/prompts/dist/index.mjs
|
|
2798
|
-
var import_picocolors = __toESM(require_picocolors(), 1);
|
|
2799
|
-
var import_sisteransi2 = __toESM(require_src(), 1);
|
|
2800
|
-
import y2 from "process";
|
|
2801
|
-
function ce() {
|
|
2802
|
-
return y2.platform !== "win32" ? y2.env.TERM !== "linux" : !!y2.env.CI || !!y2.env.WT_SESSION || !!y2.env.TERMINUS_SUBLIME || y2.env.ConEmuTask === "{cmd::Cmder}" || y2.env.TERM_PROGRAM === "Terminus-Sublime" || y2.env.TERM_PROGRAM === "vscode" || y2.env.TERM === "xterm-256color" || y2.env.TERM === "alacritty" || y2.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
|
|
2803
|
-
}
|
|
2804
|
-
var V2 = ce();
|
|
2805
|
-
var u = (t, n) => V2 ? t : n;
|
|
2806
|
-
var le = u("\u25C6", "*");
|
|
2807
|
-
var L2 = u("\u25A0", "x");
|
|
2808
|
-
var W2 = u("\u25B2", "x");
|
|
2809
|
-
var C = u("\u25C7", "o");
|
|
2810
|
-
var ue = u("\u250C", "T");
|
|
2811
|
-
var o = u("\u2502", "|");
|
|
2812
|
-
var d2 = u("\u2514", "\u2014");
|
|
2813
|
-
var k2 = u("\u25CF", ">");
|
|
2814
|
-
var P2 = u("\u25CB", " ");
|
|
2815
|
-
var A2 = u("\u25FB", "[\u2022]");
|
|
2816
|
-
var T = u("\u25FC", "[+]");
|
|
2817
|
-
var F = u("\u25FB", "[ ]");
|
|
2818
|
-
var $e = u("\u25AA", "\u2022");
|
|
2819
|
-
var _2 = u("\u2500", "-");
|
|
2820
|
-
var me = u("\u256E", "+");
|
|
2821
|
-
var de = u("\u251C", "+");
|
|
2822
|
-
var pe = u("\u256F", "+");
|
|
2823
|
-
var q = u("\u25CF", "\u2022");
|
|
2824
|
-
var D = u("\u25C6", "*");
|
|
2825
|
-
var U = u("\u25B2", "!");
|
|
2826
|
-
var K2 = u("\u25A0", "x");
|
|
2827
|
-
var b2 = (t) => {
|
|
2828
|
-
switch (t) {
|
|
2829
|
-
case "initial":
|
|
2830
|
-
case "active":
|
|
2831
|
-
return import_picocolors.default.cyan(le);
|
|
2832
|
-
case "cancel":
|
|
2833
|
-
return import_picocolors.default.red(L2);
|
|
2834
|
-
case "error":
|
|
2835
|
-
return import_picocolors.default.yellow(W2);
|
|
2836
|
-
case "submit":
|
|
2837
|
-
return import_picocolors.default.green(C);
|
|
2838
|
-
}
|
|
2839
|
-
};
|
|
2840
|
-
var G2 = (t) => {
|
|
2841
|
-
const { cursor: n, options: r2, style: i } = t, s = t.maxItems ?? Number.POSITIVE_INFINITY, c = Math.max(process.stdout.rows - 4, 0), a = Math.min(c, Math.max(s, 5));
|
|
2842
|
-
let l2 = 0;
|
|
2843
|
-
n >= l2 + a - 3 ? l2 = Math.max(Math.min(n - a + 3, r2.length - a), 0) : n < l2 + 2 && (l2 = Math.max(n - 2, 0));
|
|
2844
|
-
const $2 = a < r2.length && l2 > 0, g = a < r2.length && l2 + a < r2.length;
|
|
2845
|
-
return r2.slice(l2, l2 + a).map((p2, v, f) => {
|
|
2846
|
-
const j2 = v === 0 && $2, E = v === f.length - 1 && g;
|
|
2847
|
-
return j2 || E ? import_picocolors.default.dim("...") : i(p2, v + l2 === n);
|
|
2848
|
-
});
|
|
2849
|
-
};
|
|
2850
|
-
var ye = (t) => {
|
|
2851
|
-
const n = t.active ?? "Yes", r2 = t.inactive ?? "No";
|
|
2852
|
-
return new dD({ active: n, inactive: r2, initialValue: t.initialValue ?? true, render() {
|
|
2853
|
-
const i = `${import_picocolors.default.gray(o)}
|
|
2854
|
-
${b2(this.state)} ${t.message}
|
|
2855
|
-
`, s = this.value ? n : r2;
|
|
2856
|
-
switch (this.state) {
|
|
2857
|
-
case "submit":
|
|
2858
|
-
return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.dim(s)}`;
|
|
2859
|
-
case "cancel":
|
|
2860
|
-
return `${i}${import_picocolors.default.gray(o)} ${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}
|
|
2861
|
-
${import_picocolors.default.gray(o)}`;
|
|
2862
|
-
default:
|
|
2863
|
-
return `${i}${import_picocolors.default.cyan(o)} ${this.value ? `${import_picocolors.default.green(k2)} ${n}` : `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(n)}`} ${import_picocolors.default.dim("/")} ${this.value ? `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(r2)}` : `${import_picocolors.default.green(k2)} ${r2}`}
|
|
2864
|
-
${import_picocolors.default.cyan(d2)}
|
|
2865
|
-
`;
|
|
2866
|
-
}
|
|
2867
|
-
} }).prompt();
|
|
2868
|
-
};
|
|
2869
|
-
var ve = (t) => {
|
|
2870
|
-
const n = (r2, i) => {
|
|
2871
|
-
const s = r2.label ?? String(r2.value);
|
|
2872
|
-
switch (i) {
|
|
2873
|
-
case "selected":
|
|
2874
|
-
return `${import_picocolors.default.dim(s)}`;
|
|
2875
|
-
case "active":
|
|
2876
|
-
return `${import_picocolors.default.green(k2)} ${s} ${r2.hint ? import_picocolors.default.dim(`(${r2.hint})`) : ""}`;
|
|
2877
|
-
case "cancelled":
|
|
2878
|
-
return `${import_picocolors.default.strikethrough(import_picocolors.default.dim(s))}`;
|
|
2879
|
-
default:
|
|
2880
|
-
return `${import_picocolors.default.dim(P2)} ${import_picocolors.default.dim(s)}`;
|
|
2881
|
-
}
|
|
2882
|
-
};
|
|
2883
|
-
return new LD({ options: t.options, initialValue: t.initialValue, render() {
|
|
2884
|
-
const r2 = `${import_picocolors.default.gray(o)}
|
|
2885
|
-
${b2(this.state)} ${t.message}
|
|
2886
|
-
`;
|
|
2887
|
-
switch (this.state) {
|
|
2888
|
-
case "submit":
|
|
2889
|
-
return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "selected")}`;
|
|
2890
|
-
case "cancel":
|
|
2891
|
-
return `${r2}${import_picocolors.default.gray(o)} ${n(this.options[this.cursor], "cancelled")}
|
|
2892
|
-
${import_picocolors.default.gray(o)}`;
|
|
2893
|
-
default:
|
|
2894
|
-
return `${r2}${import_picocolors.default.cyan(o)} ${G2({ cursor: this.cursor, options: this.options, maxItems: t.maxItems, style: (i, s) => n(i, s ? "active" : "inactive") }).join(`
|
|
2895
|
-
${import_picocolors.default.cyan(o)} `)}
|
|
2896
|
-
${import_picocolors.default.cyan(d2)}
|
|
2897
|
-
`;
|
|
2898
|
-
}
|
|
2899
|
-
} }).prompt();
|
|
2900
|
-
};
|
|
2901
|
-
var J2 = `${import_picocolors.default.gray(o)} `;
|
|
2902
|
-
|
|
2903
|
-
// src/auth/antigravity/cli.ts
|
|
2904
|
-
async function promptAddAnotherAccount(currentCount) {
|
|
2905
|
-
if (!process.stdout.isTTY) {
|
|
2906
|
-
return false;
|
|
2907
|
-
}
|
|
2908
|
-
const result = await ye({
|
|
2909
|
-
message: `Add another Google account?
|
|
2910
|
-
Currently have ${currentCount} accounts (max 10)`
|
|
2911
|
-
});
|
|
2912
|
-
if (pD(result)) {
|
|
2913
|
-
return false;
|
|
2914
|
-
}
|
|
2915
|
-
return result;
|
|
2916
|
-
}
|
|
2917
|
-
async function promptAccountTier() {
|
|
2918
|
-
if (!process.stdout.isTTY) {
|
|
2919
|
-
return "free";
|
|
2920
|
-
}
|
|
2921
|
-
const tier = await ve({
|
|
2922
|
-
message: "Select account tier",
|
|
2923
|
-
options: [
|
|
2924
|
-
{ value: "free", label: "Free" },
|
|
2925
|
-
{ value: "paid", label: "Paid" }
|
|
2926
|
-
]
|
|
2927
|
-
});
|
|
2928
|
-
if (pD(tier)) {
|
|
2929
|
-
return "free";
|
|
2930
|
-
}
|
|
2931
|
-
return tier;
|
|
2932
|
-
}
|
|
2933
|
-
|
|
2934
|
-
// node_modules/open/index.js
|
|
2935
|
-
import process8 from "process";
|
|
2936
|
-
import path2 from "path";
|
|
2937
|
-
import { fileURLToPath } from "url";
|
|
2938
|
-
import childProcess3 from "child_process";
|
|
2939
|
-
import fs6, { constants as fsConstants2 } from "fs/promises";
|
|
2940
|
-
|
|
2941
|
-
// node_modules/wsl-utils/index.js
|
|
2942
|
-
import { promisify as promisify2 } from "util";
|
|
2943
|
-
import childProcess2 from "child_process";
|
|
2944
|
-
import fs5, { constants as fsConstants } from "fs/promises";
|
|
2945
|
-
|
|
2946
|
-
// node_modules/is-wsl/index.js
|
|
2947
|
-
import process2 from "process";
|
|
2948
|
-
import os2 from "os";
|
|
2949
|
-
import fs4 from "fs";
|
|
2950
|
-
|
|
2951
|
-
// node_modules/is-inside-container/index.js
|
|
2952
|
-
import fs3 from "fs";
|
|
2953
|
-
|
|
2954
|
-
// node_modules/is-docker/index.js
|
|
2955
|
-
import fs2 from "fs";
|
|
2956
|
-
var isDockerCached;
|
|
2957
|
-
function hasDockerEnv() {
|
|
2958
|
-
try {
|
|
2959
|
-
fs2.statSync("/.dockerenv");
|
|
2960
|
-
return true;
|
|
2961
|
-
} catch {
|
|
2962
|
-
return false;
|
|
2963
|
-
}
|
|
2964
|
-
}
|
|
2965
|
-
function hasDockerCGroup() {
|
|
2966
|
-
try {
|
|
2967
|
-
return fs2.readFileSync("/proc/self/cgroup", "utf8").includes("docker");
|
|
2968
|
-
} catch {
|
|
2969
|
-
return false;
|
|
2970
|
-
}
|
|
2971
|
-
}
|
|
2972
|
-
function isDocker() {
|
|
2973
|
-
if (isDockerCached === undefined) {
|
|
2974
|
-
isDockerCached = hasDockerEnv() || hasDockerCGroup();
|
|
2975
|
-
}
|
|
2976
|
-
return isDockerCached;
|
|
2977
|
-
}
|
|
2978
|
-
|
|
2979
|
-
// node_modules/is-inside-container/index.js
|
|
2980
|
-
var cachedResult;
|
|
2981
|
-
var hasContainerEnv = () => {
|
|
2982
|
-
try {
|
|
2983
|
-
fs3.statSync("/run/.containerenv");
|
|
2984
|
-
return true;
|
|
2985
|
-
} catch {
|
|
2986
|
-
return false;
|
|
2987
|
-
}
|
|
2988
|
-
};
|
|
2989
|
-
function isInsideContainer() {
|
|
2990
|
-
if (cachedResult === undefined) {
|
|
2991
|
-
cachedResult = hasContainerEnv() || isDocker();
|
|
2992
|
-
}
|
|
2993
|
-
return cachedResult;
|
|
2994
|
-
}
|
|
2995
|
-
|
|
2996
|
-
// node_modules/is-wsl/index.js
|
|
2997
|
-
var isWsl = () => {
|
|
2998
|
-
if (process2.platform !== "linux") {
|
|
2999
|
-
return false;
|
|
3000
|
-
}
|
|
3001
|
-
if (os2.release().toLowerCase().includes("microsoft")) {
|
|
3002
|
-
if (isInsideContainer()) {
|
|
3003
|
-
return false;
|
|
3004
|
-
}
|
|
3005
|
-
return true;
|
|
3006
|
-
}
|
|
3007
|
-
try {
|
|
3008
|
-
return fs4.readFileSync("/proc/version", "utf8").toLowerCase().includes("microsoft") ? !isInsideContainer() : false;
|
|
3009
|
-
} catch {
|
|
3010
|
-
return false;
|
|
3011
|
-
}
|
|
3012
|
-
};
|
|
3013
|
-
var is_wsl_default = process2.env.__IS_WSL_TEST__ ? isWsl : isWsl();
|
|
3014
|
-
|
|
3015
|
-
// node_modules/powershell-utils/index.js
|
|
3016
|
-
import process3 from "process";
|
|
3017
|
-
import { Buffer } from "buffer";
|
|
3018
|
-
import { promisify } from "util";
|
|
3019
|
-
import childProcess from "child_process";
|
|
3020
|
-
var execFile = promisify(childProcess.execFile);
|
|
3021
|
-
var powerShellPath = () => `${process3.env.SYSTEMROOT || process3.env.windir || String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;
|
|
3022
|
-
var executePowerShell = async (command, options = {}) => {
|
|
3023
|
-
const {
|
|
3024
|
-
powerShellPath: psPath,
|
|
3025
|
-
...execFileOptions
|
|
3026
|
-
} = options;
|
|
3027
|
-
const encodedCommand = executePowerShell.encodeCommand(command);
|
|
3028
|
-
return execFile(psPath ?? powerShellPath(), [
|
|
3029
|
-
...executePowerShell.argumentsPrefix,
|
|
3030
|
-
encodedCommand
|
|
3031
|
-
], {
|
|
3032
|
-
encoding: "utf8",
|
|
3033
|
-
...execFileOptions
|
|
3034
|
-
});
|
|
3035
|
-
};
|
|
3036
|
-
executePowerShell.argumentsPrefix = [
|
|
3037
|
-
"-NoProfile",
|
|
3038
|
-
"-NonInteractive",
|
|
3039
|
-
"-ExecutionPolicy",
|
|
3040
|
-
"Bypass",
|
|
3041
|
-
"-EncodedCommand"
|
|
3042
|
-
];
|
|
3043
|
-
executePowerShell.encodeCommand = (command) => Buffer.from(command, "utf16le").toString("base64");
|
|
3044
|
-
executePowerShell.escapeArgument = (value) => `'${String(value).replaceAll("'", "''")}'`;
|
|
3045
|
-
|
|
3046
|
-
// node_modules/wsl-utils/utilities.js
|
|
3047
|
-
function parseMountPointFromConfig(content) {
|
|
3048
|
-
for (const line of content.split(`
|
|
3049
|
-
`)) {
|
|
3050
|
-
if (/^\s*#/.test(line)) {
|
|
3051
|
-
continue;
|
|
3052
|
-
}
|
|
3053
|
-
const match = /^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(line);
|
|
3054
|
-
if (!match) {
|
|
3055
|
-
continue;
|
|
3056
|
-
}
|
|
3057
|
-
return match.groups.mountPoint.trim().replaceAll(/^["']|["']$/g, "");
|
|
3058
|
-
}
|
|
3059
|
-
}
|
|
3060
|
-
|
|
3061
|
-
// node_modules/wsl-utils/index.js
|
|
3062
|
-
var execFile2 = promisify2(childProcess2.execFile);
|
|
3063
|
-
var wslDrivesMountPoint = (() => {
|
|
3064
|
-
const defaultMountPoint = "/mnt/";
|
|
3065
|
-
let mountPoint;
|
|
3066
|
-
return async function() {
|
|
3067
|
-
if (mountPoint) {
|
|
3068
|
-
return mountPoint;
|
|
3069
|
-
}
|
|
3070
|
-
const configFilePath = "/etc/wsl.conf";
|
|
3071
|
-
let isConfigFileExists = false;
|
|
3072
|
-
try {
|
|
3073
|
-
await fs5.access(configFilePath, fsConstants.F_OK);
|
|
3074
|
-
isConfigFileExists = true;
|
|
3075
|
-
} catch {}
|
|
3076
|
-
if (!isConfigFileExists) {
|
|
3077
|
-
return defaultMountPoint;
|
|
3078
|
-
}
|
|
3079
|
-
const configContent = await fs5.readFile(configFilePath, { encoding: "utf8" });
|
|
3080
|
-
const parsedMountPoint = parseMountPointFromConfig(configContent);
|
|
3081
|
-
if (parsedMountPoint === undefined) {
|
|
3082
|
-
return defaultMountPoint;
|
|
3083
|
-
}
|
|
3084
|
-
mountPoint = parsedMountPoint;
|
|
3085
|
-
mountPoint = mountPoint.endsWith("/") ? mountPoint : `${mountPoint}/`;
|
|
3086
|
-
return mountPoint;
|
|
3087
|
-
};
|
|
3088
|
-
})();
|
|
3089
|
-
var powerShellPathFromWsl = async () => {
|
|
3090
|
-
const mountPoint = await wslDrivesMountPoint();
|
|
3091
|
-
return `${mountPoint}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`;
|
|
3092
|
-
};
|
|
3093
|
-
var powerShellPath2 = is_wsl_default ? powerShellPathFromWsl : powerShellPath;
|
|
3094
|
-
var canAccessPowerShellPromise;
|
|
3095
|
-
var canAccessPowerShell = async () => {
|
|
3096
|
-
canAccessPowerShellPromise ??= (async () => {
|
|
3097
|
-
try {
|
|
3098
|
-
const psPath = await powerShellPath2();
|
|
3099
|
-
await fs5.access(psPath, fsConstants.X_OK);
|
|
3100
|
-
return true;
|
|
3101
|
-
} catch {
|
|
3102
|
-
return false;
|
|
3103
|
-
}
|
|
3104
|
-
})();
|
|
3105
|
-
return canAccessPowerShellPromise;
|
|
3106
|
-
};
|
|
3107
|
-
var wslDefaultBrowser = async () => {
|
|
3108
|
-
const psPath = await powerShellPath2();
|
|
3109
|
-
const command = String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`;
|
|
3110
|
-
const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
|
|
3111
|
-
return stdout.trim();
|
|
3112
|
-
};
|
|
3113
|
-
var convertWslPathToWindows = async (path2) => {
|
|
3114
|
-
if (/^[a-z]+:\/\//i.test(path2)) {
|
|
3115
|
-
return path2;
|
|
3116
|
-
}
|
|
3117
|
-
try {
|
|
3118
|
-
const { stdout } = await execFile2("wslpath", ["-aw", path2], { encoding: "utf8" });
|
|
3119
|
-
return stdout.trim();
|
|
3120
|
-
} catch {
|
|
3121
|
-
return path2;
|
|
3122
|
-
}
|
|
3123
|
-
};
|
|
3124
|
-
|
|
3125
|
-
// node_modules/define-lazy-prop/index.js
|
|
3126
|
-
function defineLazyProperty(object, propertyName, valueGetter) {
|
|
3127
|
-
const define = (value) => Object.defineProperty(object, propertyName, { value, enumerable: true, writable: true });
|
|
3128
|
-
Object.defineProperty(object, propertyName, {
|
|
3129
|
-
configurable: true,
|
|
3130
|
-
enumerable: true,
|
|
3131
|
-
get() {
|
|
3132
|
-
const result = valueGetter();
|
|
3133
|
-
define(result);
|
|
3134
|
-
return result;
|
|
3135
|
-
},
|
|
3136
|
-
set(value) {
|
|
3137
|
-
define(value);
|
|
3138
|
-
}
|
|
3139
|
-
});
|
|
3140
|
-
return object;
|
|
3141
|
-
}
|
|
3142
|
-
|
|
3143
|
-
// node_modules/default-browser/index.js
|
|
3144
|
-
import { promisify as promisify6 } from "util";
|
|
3145
|
-
import process6 from "process";
|
|
3146
|
-
import { execFile as execFile6 } from "child_process";
|
|
3147
|
-
|
|
3148
|
-
// node_modules/default-browser-id/index.js
|
|
3149
|
-
import { promisify as promisify3 } from "util";
|
|
3150
|
-
import process4 from "process";
|
|
3151
|
-
import { execFile as execFile3 } from "child_process";
|
|
3152
|
-
var execFileAsync = promisify3(execFile3);
|
|
3153
|
-
async function defaultBrowserId() {
|
|
3154
|
-
if (process4.platform !== "darwin") {
|
|
3155
|
-
throw new Error("macOS only");
|
|
3156
|
-
}
|
|
3157
|
-
const { stdout } = await execFileAsync("defaults", ["read", "com.apple.LaunchServices/com.apple.launchservices.secure", "LSHandlers"]);
|
|
3158
|
-
const match = /LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(stdout);
|
|
3159
|
-
const browserId = match?.groups.id ?? "com.apple.Safari";
|
|
3160
|
-
if (browserId === "com.apple.safari") {
|
|
3161
|
-
return "com.apple.Safari";
|
|
3162
|
-
}
|
|
3163
|
-
return browserId;
|
|
3164
|
-
}
|
|
3165
|
-
|
|
3166
|
-
// node_modules/run-applescript/index.js
|
|
3167
|
-
import process5 from "process";
|
|
3168
|
-
import { promisify as promisify4 } from "util";
|
|
3169
|
-
import { execFile as execFile4, execFileSync } from "child_process";
|
|
3170
|
-
var execFileAsync2 = promisify4(execFile4);
|
|
3171
|
-
async function runAppleScript(script, { humanReadableOutput = true, signal } = {}) {
|
|
3172
|
-
if (process5.platform !== "darwin") {
|
|
3173
|
-
throw new Error("macOS only");
|
|
3174
|
-
}
|
|
3175
|
-
const outputArguments = humanReadableOutput ? [] : ["-ss"];
|
|
3176
|
-
const execOptions = {};
|
|
3177
|
-
if (signal) {
|
|
3178
|
-
execOptions.signal = signal;
|
|
3179
|
-
}
|
|
3180
|
-
const { stdout } = await execFileAsync2("osascript", ["-e", script, outputArguments], execOptions);
|
|
3181
|
-
return stdout.trim();
|
|
3182
|
-
}
|
|
3183
|
-
|
|
3184
|
-
// node_modules/bundle-name/index.js
|
|
3185
|
-
async function bundleName(bundleId) {
|
|
3186
|
-
return runAppleScript(`tell application "Finder" to set app_path to application file id "${bundleId}" as string
|
|
3187
|
-
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`);
|
|
3188
|
-
}
|
|
3189
|
-
|
|
3190
|
-
// node_modules/default-browser/windows.js
|
|
3191
|
-
import { promisify as promisify5 } from "util";
|
|
3192
|
-
import { execFile as execFile5 } from "child_process";
|
|
3193
|
-
var execFileAsync3 = promisify5(execFile5);
|
|
3194
|
-
var windowsBrowserProgIds = {
|
|
3195
|
-
MSEdgeHTM: { name: "Edge", id: "com.microsoft.edge" },
|
|
3196
|
-
MSEdgeBHTML: { name: "Edge Beta", id: "com.microsoft.edge.beta" },
|
|
3197
|
-
MSEdgeDHTML: { name: "Edge Dev", id: "com.microsoft.edge.dev" },
|
|
3198
|
-
AppXq0fevzme2pys62n3e0fbqa7peapykr8v: { name: "Edge", id: "com.microsoft.edge.old" },
|
|
3199
|
-
ChromeHTML: { name: "Chrome", id: "com.google.chrome" },
|
|
3200
|
-
ChromeBHTML: { name: "Chrome Beta", id: "com.google.chrome.beta" },
|
|
3201
|
-
ChromeDHTML: { name: "Chrome Dev", id: "com.google.chrome.dev" },
|
|
3202
|
-
ChromiumHTM: { name: "Chromium", id: "org.chromium.Chromium" },
|
|
3203
|
-
BraveHTML: { name: "Brave", id: "com.brave.Browser" },
|
|
3204
|
-
BraveBHTML: { name: "Brave Beta", id: "com.brave.Browser.beta" },
|
|
3205
|
-
BraveDHTML: { name: "Brave Dev", id: "com.brave.Browser.dev" },
|
|
3206
|
-
BraveSSHTM: { name: "Brave Nightly", id: "com.brave.Browser.nightly" },
|
|
3207
|
-
FirefoxURL: { name: "Firefox", id: "org.mozilla.firefox" },
|
|
3208
|
-
OperaStable: { name: "Opera", id: "com.operasoftware.Opera" },
|
|
3209
|
-
VivaldiHTM: { name: "Vivaldi", id: "com.vivaldi.Vivaldi" },
|
|
3210
|
-
"IE.HTTP": { name: "Internet Explorer", id: "com.microsoft.ie" }
|
|
3211
|
-
};
|
|
3212
|
-
var _windowsBrowserProgIdMap = new Map(Object.entries(windowsBrowserProgIds));
|
|
3213
|
-
|
|
3214
|
-
class UnknownBrowserError extends Error {
|
|
3215
|
-
}
|
|
3216
|
-
async function defaultBrowser(_execFileAsync = execFileAsync3) {
|
|
3217
|
-
const { stdout } = await _execFileAsync("reg", [
|
|
3218
|
-
"QUERY",
|
|
3219
|
-
" HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice",
|
|
3220
|
-
"/v",
|
|
3221
|
-
"ProgId"
|
|
3222
|
-
]);
|
|
3223
|
-
const match = /ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(stdout);
|
|
3224
|
-
if (!match) {
|
|
3225
|
-
throw new UnknownBrowserError(`Cannot find Windows browser in stdout: ${JSON.stringify(stdout)}`);
|
|
3226
|
-
}
|
|
3227
|
-
const { id } = match.groups;
|
|
3228
|
-
const browser = windowsBrowserProgIds[id];
|
|
3229
|
-
if (!browser) {
|
|
3230
|
-
throw new UnknownBrowserError(`Unknown browser ID: ${id}`);
|
|
3231
|
-
}
|
|
3232
|
-
return browser;
|
|
3233
|
-
}
|
|
3234
|
-
|
|
3235
|
-
// node_modules/default-browser/index.js
|
|
3236
|
-
var execFileAsync4 = promisify6(execFile6);
|
|
3237
|
-
var titleize = (string) => string.toLowerCase().replaceAll(/(?:^|\s|-)\S/g, (x2) => x2.toUpperCase());
|
|
3238
|
-
async function defaultBrowser2() {
|
|
3239
|
-
if (process6.platform === "darwin") {
|
|
3240
|
-
const id = await defaultBrowserId();
|
|
3241
|
-
const name = await bundleName(id);
|
|
3242
|
-
return { name, id };
|
|
3243
|
-
}
|
|
3244
|
-
if (process6.platform === "linux") {
|
|
3245
|
-
const { stdout } = await execFileAsync4("xdg-mime", ["query", "default", "x-scheme-handler/http"]);
|
|
3246
|
-
const id = stdout.trim();
|
|
3247
|
-
const name = titleize(id.replace(/.desktop$/, "").replace("-", " "));
|
|
3248
|
-
return { name, id };
|
|
3249
|
-
}
|
|
3250
|
-
if (process6.platform === "win32") {
|
|
3251
|
-
return defaultBrowser();
|
|
3252
|
-
}
|
|
3253
|
-
throw new Error("Only macOS, Linux, and Windows are supported");
|
|
3254
|
-
}
|
|
3255
|
-
|
|
3256
|
-
// node_modules/is-in-ssh/index.js
|
|
3257
|
-
import process7 from "process";
|
|
3258
|
-
var isInSsh = Boolean(process7.env.SSH_CONNECTION || process7.env.SSH_CLIENT || process7.env.SSH_TTY);
|
|
3259
|
-
var is_in_ssh_default = isInSsh;
|
|
3260
|
-
|
|
3261
|
-
// node_modules/open/index.js
|
|
3262
|
-
var fallbackAttemptSymbol = Symbol("fallbackAttempt");
|
|
3263
|
-
var __dirname2 = import.meta.url ? path2.dirname(fileURLToPath(import.meta.url)) : "";
|
|
3264
|
-
var localXdgOpenPath = path2.join(__dirname2, "xdg-open");
|
|
3265
|
-
var { platform, arch } = process8;
|
|
3266
|
-
var tryEachApp = async (apps, opener) => {
|
|
3267
|
-
if (apps.length === 0) {
|
|
3268
|
-
return;
|
|
3269
|
-
}
|
|
3270
|
-
const errors = [];
|
|
3271
|
-
for (const app of apps) {
|
|
3272
|
-
try {
|
|
3273
|
-
return await opener(app);
|
|
3274
|
-
} catch (error) {
|
|
3275
|
-
errors.push(error);
|
|
3276
|
-
}
|
|
3277
|
-
}
|
|
3278
|
-
throw new AggregateError(errors, "Failed to open in all supported apps");
|
|
3279
|
-
};
|
|
3280
|
-
var baseOpen = async (options) => {
|
|
3281
|
-
options = {
|
|
3282
|
-
wait: false,
|
|
3283
|
-
background: false,
|
|
3284
|
-
newInstance: false,
|
|
3285
|
-
allowNonzeroExitCode: false,
|
|
3286
|
-
...options
|
|
3287
|
-
};
|
|
3288
|
-
const isFallbackAttempt = options[fallbackAttemptSymbol] === true;
|
|
3289
|
-
delete options[fallbackAttemptSymbol];
|
|
3290
|
-
if (Array.isArray(options.app)) {
|
|
3291
|
-
return tryEachApp(options.app, (singleApp) => baseOpen({
|
|
3292
|
-
...options,
|
|
3293
|
-
app: singleApp,
|
|
3294
|
-
[fallbackAttemptSymbol]: true
|
|
3295
|
-
}));
|
|
3296
|
-
}
|
|
3297
|
-
let { name: app, arguments: appArguments = [] } = options.app ?? {};
|
|
3298
|
-
appArguments = [...appArguments];
|
|
3299
|
-
if (Array.isArray(app)) {
|
|
3300
|
-
return tryEachApp(app, (appName) => baseOpen({
|
|
3301
|
-
...options,
|
|
3302
|
-
app: {
|
|
3303
|
-
name: appName,
|
|
3304
|
-
arguments: appArguments
|
|
3305
|
-
},
|
|
3306
|
-
[fallbackAttemptSymbol]: true
|
|
3307
|
-
}));
|
|
3308
|
-
}
|
|
3309
|
-
if (app === "browser" || app === "browserPrivate") {
|
|
3310
|
-
const ids = {
|
|
3311
|
-
"com.google.chrome": "chrome",
|
|
3312
|
-
"google-chrome.desktop": "chrome",
|
|
3313
|
-
"com.brave.browser": "brave",
|
|
3314
|
-
"org.mozilla.firefox": "firefox",
|
|
3315
|
-
"firefox.desktop": "firefox",
|
|
3316
|
-
"com.microsoft.msedge": "edge",
|
|
3317
|
-
"com.microsoft.edge": "edge",
|
|
3318
|
-
"com.microsoft.edgemac": "edge",
|
|
3319
|
-
"microsoft-edge.desktop": "edge",
|
|
3320
|
-
"com.apple.safari": "safari"
|
|
3321
|
-
};
|
|
3322
|
-
const flags = {
|
|
3323
|
-
chrome: "--incognito",
|
|
3324
|
-
brave: "--incognito",
|
|
3325
|
-
firefox: "--private-window",
|
|
3326
|
-
edge: "--inPrivate"
|
|
3327
|
-
};
|
|
3328
|
-
let browser;
|
|
3329
|
-
if (is_wsl_default) {
|
|
3330
|
-
const progId = await wslDefaultBrowser();
|
|
3331
|
-
const browserInfo = _windowsBrowserProgIdMap.get(progId);
|
|
3332
|
-
browser = browserInfo ?? {};
|
|
3333
|
-
} else {
|
|
3334
|
-
browser = await defaultBrowser2();
|
|
3335
|
-
}
|
|
3336
|
-
if (browser.id in ids) {
|
|
3337
|
-
const browserName = ids[browser.id.toLowerCase()];
|
|
3338
|
-
if (app === "browserPrivate") {
|
|
3339
|
-
if (browserName === "safari") {
|
|
3340
|
-
throw new Error("Safari doesn't support opening in private mode via command line");
|
|
3341
|
-
}
|
|
3342
|
-
appArguments.push(flags[browserName]);
|
|
3343
|
-
}
|
|
3344
|
-
return baseOpen({
|
|
3345
|
-
...options,
|
|
3346
|
-
app: {
|
|
3347
|
-
name: apps[browserName],
|
|
3348
|
-
arguments: appArguments
|
|
3349
|
-
}
|
|
3350
|
-
});
|
|
3351
|
-
}
|
|
3352
|
-
throw new Error(`${browser.name} is not supported as a default browser`);
|
|
3353
|
-
}
|
|
3354
|
-
let command;
|
|
3355
|
-
const cliArguments = [];
|
|
3356
|
-
const childProcessOptions = {};
|
|
3357
|
-
let shouldUseWindowsInWsl = false;
|
|
3358
|
-
if (is_wsl_default && !isInsideContainer() && !is_in_ssh_default && !app) {
|
|
3359
|
-
shouldUseWindowsInWsl = await canAccessPowerShell();
|
|
3360
|
-
}
|
|
3361
|
-
if (platform === "darwin") {
|
|
3362
|
-
command = "open";
|
|
3363
|
-
if (options.wait) {
|
|
3364
|
-
cliArguments.push("--wait-apps");
|
|
3365
|
-
}
|
|
3366
|
-
if (options.background) {
|
|
3367
|
-
cliArguments.push("--background");
|
|
3368
|
-
}
|
|
3369
|
-
if (options.newInstance) {
|
|
3370
|
-
cliArguments.push("--new");
|
|
3371
|
-
}
|
|
3372
|
-
if (app) {
|
|
3373
|
-
cliArguments.push("-a", app);
|
|
3374
|
-
}
|
|
3375
|
-
} else if (platform === "win32" || shouldUseWindowsInWsl) {
|
|
3376
|
-
command = await powerShellPath2();
|
|
3377
|
-
cliArguments.push(...executePowerShell.argumentsPrefix);
|
|
3378
|
-
if (!is_wsl_default) {
|
|
3379
|
-
childProcessOptions.windowsVerbatimArguments = true;
|
|
3380
|
-
}
|
|
3381
|
-
if (is_wsl_default && options.target) {
|
|
3382
|
-
options.target = await convertWslPathToWindows(options.target);
|
|
3383
|
-
}
|
|
3384
|
-
const encodedArguments = ["$ProgressPreference = 'SilentlyContinue';", "Start"];
|
|
3385
|
-
if (options.wait) {
|
|
3386
|
-
encodedArguments.push("-Wait");
|
|
3387
|
-
}
|
|
3388
|
-
if (app) {
|
|
3389
|
-
encodedArguments.push(executePowerShell.escapeArgument(app));
|
|
3390
|
-
if (options.target) {
|
|
3391
|
-
appArguments.push(options.target);
|
|
3392
|
-
}
|
|
3393
|
-
} else if (options.target) {
|
|
3394
|
-
encodedArguments.push(executePowerShell.escapeArgument(options.target));
|
|
3395
|
-
}
|
|
3396
|
-
if (appArguments.length > 0) {
|
|
3397
|
-
appArguments = appArguments.map((argument) => executePowerShell.escapeArgument(argument));
|
|
3398
|
-
encodedArguments.push("-ArgumentList", appArguments.join(","));
|
|
3399
|
-
}
|
|
3400
|
-
options.target = executePowerShell.encodeCommand(encodedArguments.join(" "));
|
|
3401
|
-
if (!options.wait) {
|
|
3402
|
-
childProcessOptions.stdio = "ignore";
|
|
3403
|
-
}
|
|
3404
|
-
} else {
|
|
3405
|
-
if (app) {
|
|
3406
|
-
command = app;
|
|
3407
|
-
} else {
|
|
3408
|
-
const isBundled = !__dirname2 || __dirname2 === "/";
|
|
3409
|
-
let exeLocalXdgOpen = false;
|
|
3410
|
-
try {
|
|
3411
|
-
await fs6.access(localXdgOpenPath, fsConstants2.X_OK);
|
|
3412
|
-
exeLocalXdgOpen = true;
|
|
3413
|
-
} catch {}
|
|
3414
|
-
const useSystemXdgOpen = process8.versions.electron ?? (platform === "android" || isBundled || !exeLocalXdgOpen);
|
|
3415
|
-
command = useSystemXdgOpen ? "xdg-open" : localXdgOpenPath;
|
|
3416
|
-
}
|
|
3417
|
-
if (appArguments.length > 0) {
|
|
3418
|
-
cliArguments.push(...appArguments);
|
|
3419
|
-
}
|
|
3420
|
-
if (!options.wait) {
|
|
3421
|
-
childProcessOptions.stdio = "ignore";
|
|
3422
|
-
childProcessOptions.detached = true;
|
|
3423
|
-
}
|
|
3424
|
-
}
|
|
3425
|
-
if (platform === "darwin" && appArguments.length > 0) {
|
|
3426
|
-
cliArguments.push("--args", ...appArguments);
|
|
3427
|
-
}
|
|
3428
|
-
if (options.target) {
|
|
3429
|
-
cliArguments.push(options.target);
|
|
3430
|
-
}
|
|
3431
|
-
const subprocess = childProcess3.spawn(command, cliArguments, childProcessOptions);
|
|
3432
|
-
if (options.wait) {
|
|
3433
|
-
return new Promise((resolve, reject) => {
|
|
3434
|
-
subprocess.once("error", reject);
|
|
3435
|
-
subprocess.once("close", (exitCode) => {
|
|
3436
|
-
if (!options.allowNonzeroExitCode && exitCode !== 0) {
|
|
3437
|
-
reject(new Error(`Exited with code ${exitCode}`));
|
|
3438
|
-
return;
|
|
3439
|
-
}
|
|
3440
|
-
resolve(subprocess);
|
|
3441
|
-
});
|
|
3442
|
-
});
|
|
3443
|
-
}
|
|
3444
|
-
if (isFallbackAttempt) {
|
|
3445
|
-
return new Promise((resolve, reject) => {
|
|
3446
|
-
subprocess.once("error", reject);
|
|
3447
|
-
subprocess.once("spawn", () => {
|
|
3448
|
-
subprocess.once("close", (exitCode) => {
|
|
3449
|
-
subprocess.off("error", reject);
|
|
3450
|
-
if (exitCode !== 0) {
|
|
3451
|
-
reject(new Error(`Exited with code ${exitCode}`));
|
|
3452
|
-
return;
|
|
3453
|
-
}
|
|
3454
|
-
subprocess.unref();
|
|
3455
|
-
resolve(subprocess);
|
|
3456
|
-
});
|
|
3457
|
-
});
|
|
3458
|
-
});
|
|
3459
|
-
}
|
|
3460
|
-
subprocess.unref();
|
|
3461
|
-
return new Promise((resolve, reject) => {
|
|
3462
|
-
subprocess.once("error", reject);
|
|
3463
|
-
subprocess.once("spawn", () => {
|
|
3464
|
-
subprocess.off("error", reject);
|
|
3465
|
-
resolve(subprocess);
|
|
3466
|
-
});
|
|
3467
|
-
});
|
|
3468
|
-
};
|
|
3469
|
-
var open = (target, options) => {
|
|
3470
|
-
if (typeof target !== "string") {
|
|
3471
|
-
throw new TypeError("Expected a `target`");
|
|
3472
|
-
}
|
|
3473
|
-
return baseOpen({
|
|
3474
|
-
...options,
|
|
3475
|
-
target
|
|
3476
|
-
});
|
|
3477
|
-
};
|
|
3478
|
-
function detectArchBinary(binary) {
|
|
3479
|
-
if (typeof binary === "string" || Array.isArray(binary)) {
|
|
3480
|
-
return binary;
|
|
3481
|
-
}
|
|
3482
|
-
const { [arch]: archBinary } = binary;
|
|
3483
|
-
if (!archBinary) {
|
|
3484
|
-
throw new Error(`${arch} is not supported`);
|
|
3485
|
-
}
|
|
3486
|
-
return archBinary;
|
|
3487
|
-
}
|
|
3488
|
-
function detectPlatformBinary({ [platform]: platformBinary }, { wsl } = {}) {
|
|
3489
|
-
if (wsl && is_wsl_default) {
|
|
3490
|
-
return detectArchBinary(wsl);
|
|
3491
|
-
}
|
|
3492
|
-
if (!platformBinary) {
|
|
3493
|
-
throw new Error(`${platform} is not supported`);
|
|
3494
|
-
}
|
|
3495
|
-
return detectArchBinary(platformBinary);
|
|
3496
|
-
}
|
|
3497
|
-
var apps = {
|
|
3498
|
-
browser: "browser",
|
|
3499
|
-
browserPrivate: "browserPrivate"
|
|
3500
|
-
};
|
|
3501
|
-
defineLazyProperty(apps, "chrome", () => detectPlatformBinary({
|
|
3502
|
-
darwin: "google chrome",
|
|
3503
|
-
win32: "chrome",
|
|
3504
|
-
linux: ["google-chrome", "google-chrome-stable", "chromium", "chromium-browser"]
|
|
3505
|
-
}, {
|
|
3506
|
-
wsl: {
|
|
3507
|
-
ia32: "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",
|
|
3508
|
-
x64: ["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe", "/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]
|
|
3509
|
-
}
|
|
3510
|
-
}));
|
|
3511
|
-
defineLazyProperty(apps, "brave", () => detectPlatformBinary({
|
|
3512
|
-
darwin: "brave browser",
|
|
3513
|
-
win32: "brave",
|
|
3514
|
-
linux: ["brave-browser", "brave"]
|
|
3515
|
-
}, {
|
|
3516
|
-
wsl: {
|
|
3517
|
-
ia32: "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",
|
|
3518
|
-
x64: ["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe", "/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]
|
|
3519
|
-
}
|
|
3520
|
-
}));
|
|
3521
|
-
defineLazyProperty(apps, "firefox", () => detectPlatformBinary({
|
|
3522
|
-
darwin: "firefox",
|
|
3523
|
-
win32: String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,
|
|
3524
|
-
linux: "firefox"
|
|
3525
|
-
}, {
|
|
3526
|
-
wsl: "/mnt/c/Program Files/Mozilla Firefox/firefox.exe"
|
|
3527
|
-
}));
|
|
3528
|
-
defineLazyProperty(apps, "edge", () => detectPlatformBinary({
|
|
3529
|
-
darwin: "microsoft edge",
|
|
3530
|
-
win32: "msedge",
|
|
3531
|
-
linux: ["microsoft-edge", "microsoft-edge-dev"]
|
|
3532
|
-
}, {
|
|
3533
|
-
wsl: "/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"
|
|
3534
|
-
}));
|
|
3535
|
-
defineLazyProperty(apps, "safari", () => detectPlatformBinary({
|
|
3536
|
-
darwin: "Safari"
|
|
3537
|
-
}));
|
|
3538
|
-
var open_default = open;
|
|
3539
|
-
|
|
3540
|
-
// src/auth/antigravity/browser.ts
|
|
3541
|
-
function debugLog5(message) {
|
|
3542
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3543
|
-
console.log(`[antigravity-browser] ${message}`);
|
|
3544
|
-
}
|
|
3545
|
-
}
|
|
3546
|
-
async function openBrowserURL(url) {
|
|
3547
|
-
debugLog5(`Opening browser: ${url}`);
|
|
3548
|
-
try {
|
|
3549
|
-
await open_default(url);
|
|
3550
|
-
debugLog5("Browser opened successfully");
|
|
3551
|
-
return true;
|
|
3552
|
-
} catch (error) {
|
|
3553
|
-
debugLog5(`Failed to open browser: ${error instanceof Error ? error.message : String(error)}`);
|
|
3554
|
-
return false;
|
|
3555
|
-
}
|
|
3556
|
-
}
|
|
3557
|
-
|
|
3558
|
-
// src/auth/antigravity/plugin.ts
|
|
3559
|
-
var GOOGLE_PROVIDER_ID = "google";
|
|
3560
|
-
var MAX_ACCOUNTS = 10;
|
|
3561
|
-
function isOAuthAuth(auth) {
|
|
3562
|
-
return auth.type === "oauth";
|
|
3563
|
-
}
|
|
3564
|
-
async function createGoogleAntigravityAuthPlugin({
|
|
3565
|
-
client
|
|
3566
|
-
}) {
|
|
3567
|
-
let cachedClientId = ANTIGRAVITY_CLIENT_ID;
|
|
3568
|
-
let cachedClientSecret = ANTIGRAVITY_CLIENT_SECRET;
|
|
3569
|
-
const authHook = {
|
|
3570
|
-
provider: GOOGLE_PROVIDER_ID,
|
|
3571
|
-
loader: async (auth, provider) => {
|
|
3572
|
-
const currentAuth = await auth();
|
|
3573
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3574
|
-
console.log("[antigravity-plugin] loader called");
|
|
3575
|
-
console.log("[antigravity-plugin] auth type:", currentAuth?.type);
|
|
3576
|
-
console.log("[antigravity-plugin] auth keys:", Object.keys(currentAuth || {}));
|
|
3577
|
-
}
|
|
3578
|
-
if (!isOAuthAuth(currentAuth)) {
|
|
3579
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3580
|
-
console.log("[antigravity-plugin] NOT OAuth auth, returning empty");
|
|
3581
|
-
}
|
|
3582
|
-
return {};
|
|
3583
|
-
}
|
|
3584
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3585
|
-
console.log("[antigravity-plugin] OAuth auth detected, creating custom fetch");
|
|
3586
|
-
}
|
|
3587
|
-
let accountManager = null;
|
|
3588
|
-
try {
|
|
3589
|
-
const storedAccounts = await loadAccounts();
|
|
3590
|
-
if (storedAccounts) {
|
|
3591
|
-
accountManager = new AccountManager(currentAuth, storedAccounts);
|
|
3592
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3593
|
-
console.log(`[antigravity-plugin] Loaded ${accountManager.getAccountCount()} accounts from storage`);
|
|
3594
|
-
}
|
|
3595
|
-
} else if (currentAuth.refresh.includes("|||")) {
|
|
3596
|
-
const tokens = currentAuth.refresh.split("|||");
|
|
3597
|
-
const firstToken = tokens[0];
|
|
3598
|
-
accountManager = new AccountManager({ refresh: firstToken, access: currentAuth.access || "", expires: currentAuth.expires || 0 }, null);
|
|
3599
|
-
for (let i = 1;i < tokens.length; i++) {
|
|
3600
|
-
const parts = parseStoredToken(tokens[i]);
|
|
3601
|
-
accountManager.addAccount(parts);
|
|
3602
|
-
}
|
|
3603
|
-
await accountManager.save();
|
|
3604
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3605
|
-
console.log("[antigravity-plugin] Migrated multi-account auth to storage");
|
|
3606
|
-
}
|
|
3607
|
-
}
|
|
3608
|
-
} catch (error) {
|
|
3609
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3610
|
-
console.error(`[antigravity-plugin] Failed to load accounts: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3611
|
-
}
|
|
3612
|
-
}
|
|
3613
|
-
cachedClientId = provider.options?.clientId || ANTIGRAVITY_CLIENT_ID;
|
|
3614
|
-
cachedClientSecret = provider.options?.clientSecret || ANTIGRAVITY_CLIENT_SECRET;
|
|
3615
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1" && (cachedClientId !== ANTIGRAVITY_CLIENT_ID || cachedClientSecret !== ANTIGRAVITY_CLIENT_SECRET)) {
|
|
3616
|
-
console.log("[antigravity-plugin] Using custom credentials from provider.options");
|
|
3617
|
-
}
|
|
3618
|
-
const authClient = {
|
|
3619
|
-
set: async (providerId, authData) => {
|
|
3620
|
-
await client.auth.set({
|
|
3621
|
-
body: {
|
|
3622
|
-
type: "oauth",
|
|
3623
|
-
access: authData.access || "",
|
|
3624
|
-
refresh: authData.refresh || "",
|
|
3625
|
-
expires: authData.expires || 0
|
|
3626
|
-
},
|
|
3627
|
-
path: { id: providerId }
|
|
3628
|
-
});
|
|
3629
|
-
}
|
|
3630
|
-
};
|
|
3631
|
-
const getAuth = async () => {
|
|
3632
|
-
const authState = await auth();
|
|
3633
|
-
if (isOAuthAuth(authState)) {
|
|
3634
|
-
return {
|
|
3635
|
-
access: authState.access,
|
|
3636
|
-
refresh: authState.refresh,
|
|
3637
|
-
expires: authState.expires
|
|
3638
|
-
};
|
|
3639
|
-
}
|
|
3640
|
-
return {};
|
|
3641
|
-
};
|
|
3642
|
-
const antigravityFetch = createAntigravityFetch(getAuth, authClient, GOOGLE_PROVIDER_ID, cachedClientId, cachedClientSecret);
|
|
3643
|
-
return {
|
|
3644
|
-
fetch: antigravityFetch,
|
|
3645
|
-
apiKey: "antigravity-oauth",
|
|
3646
|
-
accountManager
|
|
3647
|
-
};
|
|
3648
|
-
},
|
|
3649
|
-
methods: [
|
|
3650
|
-
{
|
|
3651
|
-
type: "oauth",
|
|
3652
|
-
label: "OAuth with Google (Antigravity)",
|
|
3653
|
-
authorize: async () => {
|
|
3654
|
-
const serverHandle = startCallbackServer();
|
|
3655
|
-
const { url, state: expectedState } = await buildAuthURL(undefined, cachedClientId, serverHandle.port);
|
|
3656
|
-
const browserOpened = await openBrowserURL(url);
|
|
3657
|
-
return {
|
|
3658
|
-
url,
|
|
3659
|
-
instructions: browserOpened ? "Opening browser for sign-in. We'll automatically detect when you're done." : "Please open the URL above in your browser to sign in.",
|
|
3660
|
-
method: "auto",
|
|
3661
|
-
callback: async () => {
|
|
3662
|
-
try {
|
|
3663
|
-
const result = await serverHandle.waitForCallback();
|
|
3664
|
-
if (result.error) {
|
|
3665
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3666
|
-
console.error(`[antigravity-plugin] OAuth error: ${result.error}`);
|
|
3667
|
-
}
|
|
3668
|
-
return { type: "failed" };
|
|
3669
|
-
}
|
|
3670
|
-
if (!result.code) {
|
|
3671
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3672
|
-
console.error("[antigravity-plugin] No authorization code received");
|
|
3673
|
-
}
|
|
3674
|
-
return { type: "failed" };
|
|
3675
|
-
}
|
|
3676
|
-
if (result.state !== expectedState) {
|
|
3677
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3678
|
-
console.error("[antigravity-plugin] State mismatch - possible CSRF attack");
|
|
3679
|
-
}
|
|
3680
|
-
return { type: "failed" };
|
|
3681
|
-
}
|
|
3682
|
-
const redirectUri = `http://localhost:${serverHandle.port}/oauth-callback`;
|
|
3683
|
-
const tokens = await exchangeCode(result.code, redirectUri, cachedClientId, cachedClientSecret);
|
|
3684
|
-
if (!tokens.refresh_token) {
|
|
3685
|
-
serverHandle.close();
|
|
3686
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3687
|
-
console.error("[antigravity-plugin] OAuth response missing refresh_token");
|
|
3688
|
-
}
|
|
3689
|
-
return { type: "failed" };
|
|
3690
|
-
}
|
|
3691
|
-
let email;
|
|
3692
|
-
try {
|
|
3693
|
-
const userInfo = await fetchUserInfo(tokens.access_token);
|
|
3694
|
-
email = userInfo.email;
|
|
3695
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3696
|
-
console.log(`[antigravity-plugin] Authenticated as: ${email}`);
|
|
3697
|
-
}
|
|
3698
|
-
} catch {}
|
|
3699
|
-
const projectContext = await fetchProjectContext(tokens.access_token);
|
|
3700
|
-
const projectId = projectContext.cloudaicompanionProject || "";
|
|
3701
|
-
const tier = await promptAccountTier();
|
|
3702
|
-
const expires = Date.now() + tokens.expires_in * 1000;
|
|
3703
|
-
const accounts = [{
|
|
3704
|
-
parts: {
|
|
3705
|
-
refreshToken: tokens.refresh_token,
|
|
3706
|
-
projectId,
|
|
3707
|
-
managedProjectId: projectContext.managedProjectId
|
|
3708
|
-
},
|
|
3709
|
-
access: tokens.access_token,
|
|
3710
|
-
expires,
|
|
3711
|
-
email,
|
|
3712
|
-
tier,
|
|
3713
|
-
projectId
|
|
3714
|
-
}];
|
|
3715
|
-
await client.tui.showToast({
|
|
3716
|
-
body: {
|
|
3717
|
-
message: `Account 1 authenticated${email ? ` (${email})` : ""}`,
|
|
3718
|
-
variant: "success"
|
|
3719
|
-
}
|
|
3720
|
-
});
|
|
3721
|
-
while (accounts.length < MAX_ACCOUNTS) {
|
|
3722
|
-
const addAnother = await promptAddAnotherAccount(accounts.length);
|
|
3723
|
-
if (!addAnother)
|
|
3724
|
-
break;
|
|
3725
|
-
const additionalServerHandle = startCallbackServer();
|
|
3726
|
-
const { url: additionalUrl, state: expectedAdditionalState } = await buildAuthURL(undefined, cachedClientId, additionalServerHandle.port);
|
|
3727
|
-
const additionalBrowserOpened = await openBrowserURL(additionalUrl);
|
|
3728
|
-
if (!additionalBrowserOpened) {
|
|
3729
|
-
await client.tui.showToast({
|
|
3730
|
-
body: {
|
|
3731
|
-
message: `Please open in browser: ${additionalUrl}`,
|
|
3732
|
-
variant: "warning"
|
|
3733
|
-
}
|
|
3734
|
-
});
|
|
3735
|
-
}
|
|
3736
|
-
try {
|
|
3737
|
-
const additionalResult = await additionalServerHandle.waitForCallback();
|
|
3738
|
-
if (additionalResult.error || !additionalResult.code) {
|
|
3739
|
-
additionalServerHandle.close();
|
|
3740
|
-
await client.tui.showToast({
|
|
3741
|
-
body: {
|
|
3742
|
-
message: "Skipping this account...",
|
|
3743
|
-
variant: "warning"
|
|
3744
|
-
}
|
|
3745
|
-
});
|
|
3746
|
-
continue;
|
|
3747
|
-
}
|
|
3748
|
-
if (additionalResult.state !== expectedAdditionalState) {
|
|
3749
|
-
additionalServerHandle.close();
|
|
3750
|
-
await client.tui.showToast({
|
|
3751
|
-
body: {
|
|
3752
|
-
message: "State mismatch, skipping...",
|
|
3753
|
-
variant: "warning"
|
|
3754
|
-
}
|
|
3755
|
-
});
|
|
3756
|
-
continue;
|
|
3757
|
-
}
|
|
3758
|
-
const additionalRedirectUri = `http://localhost:${additionalServerHandle.port}/oauth-callback`;
|
|
3759
|
-
const additionalTokens = await exchangeCode(additionalResult.code, additionalRedirectUri, cachedClientId, cachedClientSecret);
|
|
3760
|
-
if (!additionalTokens.refresh_token) {
|
|
3761
|
-
additionalServerHandle.close();
|
|
3762
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3763
|
-
console.error("[antigravity-plugin] Additional account OAuth response missing refresh_token");
|
|
3764
|
-
}
|
|
3765
|
-
await client.tui.showToast({
|
|
3766
|
-
body: {
|
|
3767
|
-
message: "Account missing refresh token, skipping...",
|
|
3768
|
-
variant: "warning"
|
|
3769
|
-
}
|
|
3770
|
-
});
|
|
3771
|
-
continue;
|
|
3772
|
-
}
|
|
3773
|
-
let additionalEmail;
|
|
3774
|
-
try {
|
|
3775
|
-
const additionalUserInfo = await fetchUserInfo(additionalTokens.access_token);
|
|
3776
|
-
additionalEmail = additionalUserInfo.email;
|
|
3777
|
-
} catch {}
|
|
3778
|
-
const additionalProjectContext = await fetchProjectContext(additionalTokens.access_token);
|
|
3779
|
-
const additionalProjectId = additionalProjectContext.cloudaicompanionProject || "";
|
|
3780
|
-
const additionalTier = await promptAccountTier();
|
|
3781
|
-
const additionalExpires = Date.now() + additionalTokens.expires_in * 1000;
|
|
3782
|
-
accounts.push({
|
|
3783
|
-
parts: {
|
|
3784
|
-
refreshToken: additionalTokens.refresh_token,
|
|
3785
|
-
projectId: additionalProjectId,
|
|
3786
|
-
managedProjectId: additionalProjectContext.managedProjectId
|
|
3787
|
-
},
|
|
3788
|
-
access: additionalTokens.access_token,
|
|
3789
|
-
expires: additionalExpires,
|
|
3790
|
-
email: additionalEmail,
|
|
3791
|
-
tier: additionalTier,
|
|
3792
|
-
projectId: additionalProjectId
|
|
3793
|
-
});
|
|
3794
|
-
additionalServerHandle.close();
|
|
3795
|
-
await client.tui.showToast({
|
|
3796
|
-
body: {
|
|
3797
|
-
message: `Account ${accounts.length} authenticated${additionalEmail ? ` (${additionalEmail})` : ""}`,
|
|
3798
|
-
variant: "success"
|
|
3799
|
-
}
|
|
3800
|
-
});
|
|
3801
|
-
} catch (error) {
|
|
3802
|
-
additionalServerHandle.close();
|
|
3803
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3804
|
-
console.error(`[antigravity-plugin] Additional account OAuth failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3805
|
-
}
|
|
3806
|
-
await client.tui.showToast({
|
|
3807
|
-
body: {
|
|
3808
|
-
message: "Failed to authenticate additional account, skipping...",
|
|
3809
|
-
variant: "warning"
|
|
3810
|
-
}
|
|
3811
|
-
});
|
|
3812
|
-
continue;
|
|
3813
|
-
}
|
|
3814
|
-
}
|
|
3815
|
-
const firstAccount = accounts[0];
|
|
3816
|
-
try {
|
|
3817
|
-
const accountManager = new AccountManager({
|
|
3818
|
-
refresh: formatTokenForStorage(firstAccount.parts.refreshToken, firstAccount.projectId, firstAccount.parts.managedProjectId),
|
|
3819
|
-
access: firstAccount.access,
|
|
3820
|
-
expires: firstAccount.expires
|
|
3821
|
-
}, null);
|
|
3822
|
-
for (let i = 1;i < accounts.length; i++) {
|
|
3823
|
-
const acc = accounts[i];
|
|
3824
|
-
accountManager.addAccount(acc.parts, acc.access, acc.expires, acc.email, acc.tier);
|
|
3825
|
-
}
|
|
3826
|
-
const currentAccount = accountManager.getCurrentAccount();
|
|
3827
|
-
if (currentAccount) {
|
|
3828
|
-
currentAccount.email = firstAccount.email;
|
|
3829
|
-
currentAccount.tier = firstAccount.tier;
|
|
3830
|
-
}
|
|
3831
|
-
await accountManager.save();
|
|
3832
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3833
|
-
console.log(`[antigravity-plugin] Saved ${accounts.length} accounts to storage`);
|
|
3834
|
-
}
|
|
3835
|
-
} catch (error) {
|
|
3836
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3837
|
-
console.error(`[antigravity-plugin] Failed to save accounts: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3838
|
-
}
|
|
3839
|
-
}
|
|
3840
|
-
const allRefreshTokens = accounts.map((acc) => formatTokenForStorage(acc.parts.refreshToken, acc.projectId, acc.parts.managedProjectId)).join("|||");
|
|
3841
|
-
return {
|
|
3842
|
-
type: "success",
|
|
3843
|
-
access: firstAccount.access,
|
|
3844
|
-
refresh: allRefreshTokens,
|
|
3845
|
-
expires: firstAccount.expires
|
|
3846
|
-
};
|
|
3847
|
-
} catch (error) {
|
|
3848
|
-
serverHandle.close();
|
|
3849
|
-
if (process.env.ANTIGRAVITY_DEBUG === "1") {
|
|
3850
|
-
console.error(`[antigravity-plugin] OAuth flow failed: ${error instanceof Error ? error.message : "Unknown error"}`);
|
|
3851
|
-
}
|
|
3852
|
-
return { type: "failed" };
|
|
3853
|
-
}
|
|
3854
|
-
}
|
|
3855
|
-
};
|
|
3856
|
-
}
|
|
3857
|
-
}
|
|
3858
|
-
]
|
|
3859
|
-
};
|
|
3860
|
-
return {
|
|
3861
|
-
auth: authHook
|
|
3862
|
-
};
|
|
3863
|
-
}
|
|
3864
|
-
// src/google-auth.ts
|
|
3865
|
-
var GoogleAntigravityAuthPlugin = async (ctx) => {
|
|
3866
|
-
return createGoogleAntigravityAuthPlugin(ctx);
|
|
3867
|
-
};
|
|
3868
|
-
var google_auth_default = GoogleAntigravityAuthPlugin;
|
|
3869
|
-
export {
|
|
3870
|
-
google_auth_default as default
|
|
3871
|
-
};
|