gemini-proxy-client 1.0.8 → 1.0.10
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/browser/manager.js +100 -64
- package/dist/cli.js +1 -1
- package/package.json +1 -1
package/dist/browser/manager.js
CHANGED
|
@@ -144,73 +144,88 @@ export class BrowserManager {
|
|
|
144
144
|
console.log(chalk.gray('未找到 "Continue to the app" 按钮,继续...'));
|
|
145
145
|
}
|
|
146
146
|
let clicked = false;
|
|
147
|
-
|
|
148
|
-
//
|
|
147
|
+
let buildAppFrame = null;
|
|
148
|
+
// 第二步:关闭可能存在的模态框
|
|
149
149
|
try {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
150
|
+
const modalSelectors = [
|
|
151
|
+
'.interaction-modal',
|
|
152
|
+
'[class*="modal"]',
|
|
153
|
+
'.overlay',
|
|
154
|
+
];
|
|
155
|
+
for (const selector of modalSelectors) {
|
|
156
|
+
try {
|
|
157
|
+
const modal = await this.page.$(selector);
|
|
158
|
+
if (modal) {
|
|
159
|
+
console.log(chalk.gray(`发现模态框: ${selector},尝试关闭...`));
|
|
160
|
+
await this.page.keyboard.press('Escape');
|
|
161
|
+
await sleep(500);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
catch (e) {
|
|
165
|
+
// 忽略
|
|
166
|
+
}
|
|
163
167
|
}
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
168
|
+
}
|
|
169
|
+
catch (e) {
|
|
170
|
+
// 忽略
|
|
171
|
+
}
|
|
172
|
+
// 第三步:使用 frames() API 访问 Build App iframe
|
|
173
|
+
try {
|
|
174
|
+
console.log(chalk.gray('查找 Build App iframe...'));
|
|
175
|
+
const frames = this.page.frames();
|
|
176
|
+
console.log(chalk.gray(`检查 ${frames.length} 个 frame...`));
|
|
177
|
+
for (const frame of frames) {
|
|
178
|
+
if (clicked)
|
|
179
|
+
break;
|
|
180
|
+
const frameUrl = frame.url();
|
|
181
|
+
// 查找 Build App iframe (可能是 blob: URL 或 scf.usercontent.goog)
|
|
182
|
+
if (frameUrl.includes('scf.usercontent.goog') || frameUrl.startsWith('blob:')) {
|
|
183
|
+
console.log(chalk.gray(`找到 Build App iframe: ${frameUrl.substring(0, 60)}...`));
|
|
184
|
+
buildAppFrame = frame;
|
|
185
|
+
// 等待 iframe 内容加载
|
|
186
|
+
try {
|
|
187
|
+
await frame.waitForLoadState('domcontentloaded');
|
|
188
|
+
}
|
|
189
|
+
catch (e) {
|
|
190
|
+
// 忽略
|
|
191
|
+
}
|
|
192
|
+
// 查找按钮
|
|
193
|
+
const buttons = await frame.$$('button');
|
|
194
|
+
console.log(chalk.gray(` iframe 中找到 ${buttons.length} 个按钮`));
|
|
195
|
+
for (const button of buttons) {
|
|
176
196
|
try {
|
|
177
|
-
await
|
|
197
|
+
const title = await button.getAttribute('title');
|
|
198
|
+
const text = await button.textContent();
|
|
199
|
+
console.log(chalk.gray(` 按钮: "${text?.trim()}" title="${title}"`));
|
|
200
|
+
if (title === 'Connect WebSocket Proxy' || (text && text.includes('Connect WS'))) {
|
|
201
|
+
// 使用 force: true 强制点击,忽略遮挡
|
|
202
|
+
await button.click({ force: true });
|
|
203
|
+
clicked = true;
|
|
204
|
+
console.log(chalk.green('✅ 点击了连接按钮'));
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
178
207
|
}
|
|
179
|
-
catch (
|
|
180
|
-
|
|
208
|
+
catch (btnErr) {
|
|
209
|
+
console.log(chalk.gray(` 点击失败: ${btnErr}`));
|
|
181
210
|
}
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
const
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
await button.click();
|
|
192
|
-
clicked = true;
|
|
193
|
-
console.log(chalk.green('✅ 点击了连接按钮 (frame API)'));
|
|
194
|
-
break;
|
|
211
|
+
}
|
|
212
|
+
// 如果遍历没找到,尝试 evaluate 直接执行点击
|
|
213
|
+
if (!clicked) {
|
|
214
|
+
try {
|
|
215
|
+
clicked = await frame.evaluate(() => {
|
|
216
|
+
const btn = document.querySelector('button[title="Connect WebSocket Proxy"]');
|
|
217
|
+
if (btn) {
|
|
218
|
+
btn.click();
|
|
219
|
+
return true;
|
|
195
220
|
}
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
221
|
+
return false;
|
|
222
|
+
});
|
|
223
|
+
if (clicked) {
|
|
224
|
+
console.log(chalk.green('✅ 点击了连接按钮 (evaluate)'));
|
|
199
225
|
}
|
|
200
226
|
}
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
try {
|
|
204
|
-
const button = await frame.$('button[title="Connect WebSocket Proxy"]');
|
|
205
|
-
if (button) {
|
|
206
|
-
await button.click();
|
|
207
|
-
clicked = true;
|
|
208
|
-
console.log(chalk.green('✅ 点击了连接按钮 (选择器)'));
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
catch (e) {
|
|
212
|
-
// 继续
|
|
213
|
-
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
console.log(chalk.gray(`evaluate 点击失败: ${e}`));
|
|
214
229
|
}
|
|
215
230
|
}
|
|
216
231
|
}
|
|
@@ -219,14 +234,35 @@ export class BrowserManager {
|
|
|
219
234
|
catch (e) {
|
|
220
235
|
console.log(chalk.gray(`iframe 访问失败: ${e}`));
|
|
221
236
|
}
|
|
222
|
-
// 第三步:设置服务器地址(如果有输入框)
|
|
223
|
-
await this.setServerAddress();
|
|
224
237
|
if (!clicked) {
|
|
225
238
|
console.log(chalk.yellow('⚠️ 未找到连接按钮,请手动点击连接'));
|
|
226
|
-
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
// 第四步:等待并验证连接成功(按钮文字变成 "Disconnect WS")
|
|
242
|
+
console.log(chalk.gray('等待 WebSocket 连接...'));
|
|
243
|
+
let connected = false;
|
|
244
|
+
for (let i = 0; i < 10; i++) { // 最多等待 10 秒
|
|
245
|
+
await sleep(1000);
|
|
246
|
+
if (buildAppFrame) {
|
|
247
|
+
try {
|
|
248
|
+
const buttonText = await buildAppFrame.evaluate(() => {
|
|
249
|
+
const btn = document.querySelector('button[title="Connect WebSocket Proxy"], button[title="Disconnect WebSocket Proxy"]');
|
|
250
|
+
return btn?.textContent?.trim() || '';
|
|
251
|
+
});
|
|
252
|
+
if (buttonText.includes('Disconnect')) {
|
|
253
|
+
connected = true;
|
|
254
|
+
console.log(chalk.green('✅ WebSocket 连接成功!'));
|
|
255
|
+
break;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
catch (e) {
|
|
259
|
+
// 忽略
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (!connected) {
|
|
264
|
+
console.log(chalk.yellow('⚠️ WebSocket 连接可能未成功,请检查'));
|
|
227
265
|
}
|
|
228
|
-
// 等待连接建立
|
|
229
|
-
await sleep(3000);
|
|
230
266
|
}
|
|
231
267
|
/**
|
|
232
268
|
* 设置服务器地址
|
package/dist/cli.js
CHANGED