gemini-proxy-client 1.0.5 → 1.0.7

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.
@@ -128,6 +128,7 @@ export class BrowserManager {
128
128
  async clickConnectButton() {
129
129
  if (!this.page)
130
130
  throw new Error('Browser not launched');
131
+ console.log(chalk.gray('开始查找连接按钮...'));
131
132
  // 等待页面完全加载
132
133
  await sleep(3000);
133
134
  // 第一步:点击 "Continue to the app" 按钮(如果存在)
@@ -140,87 +141,126 @@ export class BrowserManager {
140
141
  }
141
142
  }
142
143
  catch (e) {
143
- // 按钮不存在,可能已经在 app 页面了
144
+ console.log(chalk.gray('未找到 "Continue to the app" 按钮,继续...'));
144
145
  }
145
- // 第二步:设置服务器地址(如果有输入框)
146
- await this.setServerAddress();
147
- // 第三步:点击 Connect WS 按钮
146
+ // 第二步:直接在主页面查找按钮(不通过 frames)
148
147
  let clicked = false;
149
- // 方法1: 通过 span 文字找到按钮
148
+ // 方法1: 使用 page.evaluate 直接在页面中查找并点击
150
149
  try {
151
- const button = await this.page.waitForSelector('button span:has-text("Connect WS")', { timeout: 5000 });
152
- if (button) {
153
- // 点击父元素 button
154
- await button.evaluate((el) => el.closest('button')?.click());
155
- clicked = true;
156
- console.log(chalk.green('✅ 点击了连接按钮'));
157
- }
158
- }
159
- catch (e) {
160
- // 继续尝试其他方法
161
- }
162
- // 方法2: 通过 aria-label
163
- if (!clicked) {
164
- try {
165
- const button = await this.page.waitForSelector('button[aria-label="Connect WebSocket Proxy"]', { timeout: 3000 });
166
- if (button) {
167
- await button.click();
168
- clicked = true;
169
- console.log(chalk.green('✅ 点击了连接按钮'));
150
+ console.log(chalk.gray('尝试在主页面查找按钮...'));
151
+ clicked = await this.page.evaluate(() => {
152
+ // 查找所有按钮
153
+ const buttons = document.querySelectorAll('button');
154
+ console.log('Found buttons:', buttons.length);
155
+ for (const button of buttons) {
156
+ const title = button.getAttribute('title');
157
+ const ariaLabel = button.getAttribute('aria-label');
158
+ const text = button.textContent || '';
159
+ if (title === 'Connect WebSocket Proxy' ||
160
+ ariaLabel === 'Connect WebSocket Proxy' ||
161
+ text.includes('Connect WS')) {
162
+ button.click();
163
+ return true;
164
+ }
170
165
  }
171
- }
172
- catch (e) {
173
- // 继续
166
+ return false;
167
+ });
168
+ if (clicked) {
169
+ console.log(chalk.green('✅ 点击了连接按钮 (主页面)'));
174
170
  }
175
171
  }
176
- // 方法3: 通过 title
177
- if (!clicked) {
178
- try {
179
- const button = await this.page.waitForSelector('button[title="Connect WebSocket Proxy"]', { timeout: 3000 });
180
- if (button) {
181
- await button.click();
182
- clicked = true;
183
- console.log(chalk.green('✅ 点击了连接按钮'));
184
- }
185
- }
186
- catch (e) {
187
- // 继续
188
- }
172
+ catch (e) {
173
+ console.log(chalk.gray(`主页面查找失败: ${e}`));
189
174
  }
190
- // 方法4: 通过绿色背景类名
175
+ // 方法2: 如果主页面没找到,检查 iframe
191
176
  if (!clicked) {
192
177
  try {
193
- const button = await this.page.waitForSelector('button.bg-green-500', { timeout: 3000 });
194
- if (button) {
195
- await button.click();
196
- clicked = true;
197
- console.log(chalk.green('✅ 点击了连接按钮'));
178
+ const frames = this.page.frames();
179
+ console.log(chalk.gray(`检查 ${frames.length} 个 frame...`));
180
+ for (const frame of frames) {
181
+ if (clicked)
182
+ break;
183
+ const frameUrl = frame.url();
184
+ console.log(chalk.gray(` Frame: ${frameUrl.substring(0, 80)}`));
185
+ try {
186
+ // 在每个 frame 中查找按钮
187
+ const buttons = await frame.$$('button');
188
+ console.log(chalk.gray(` 找到 ${buttons.length} 个按钮`));
189
+ for (const button of buttons) {
190
+ try {
191
+ const title = await button.getAttribute('title');
192
+ const ariaLabel = await button.getAttribute('aria-label');
193
+ const text = await button.textContent();
194
+ if (title === 'Connect WebSocket Proxy' ||
195
+ ariaLabel === 'Connect WebSocket Proxy' ||
196
+ (text && text.includes('Connect WS'))) {
197
+ await button.click();
198
+ clicked = true;
199
+ console.log(chalk.green('✅ 点击了连接按钮 (iframe)'));
200
+ break;
201
+ }
202
+ }
203
+ catch (btnErr) {
204
+ // 单个按钮处理失败,继续下一个
205
+ }
206
+ }
207
+ }
208
+ catch (frameErr) {
209
+ console.log(chalk.gray(` Frame 处理失败: ${frameErr}`));
210
+ }
198
211
  }
199
212
  }
200
213
  catch (e) {
201
- // 继续
214
+ console.log(chalk.gray(`Frame 遍历失败: ${e}`));
202
215
  }
203
216
  }
204
- // 方法5: 通过 XPath 找包含 Connect WS 文字的按钮
217
+ // 方法3: 使用 CSS 选择器直接查找
205
218
  if (!clicked) {
206
- try {
207
- const buttons = await this.page.$$('button');
208
- for (const button of buttons) {
209
- const text = await button.textContent();
210
- if (text && text.includes('Connect WS')) {
219
+ const selectors = [
220
+ 'button[title="Connect WebSocket Proxy"]',
221
+ 'button[aria-label="Connect WebSocket Proxy"]',
222
+ 'button:has-text("Connect WS")',
223
+ 'button.bg-green-500:has(span:text("Connect"))',
224
+ ];
225
+ for (const selector of selectors) {
226
+ try {
227
+ console.log(chalk.gray(`尝试选择器: ${selector}`));
228
+ const button = await this.page.$(selector);
229
+ if (button) {
211
230
  await button.click();
212
231
  clicked = true;
213
- console.log(chalk.green('✅ 点击了连接按钮'));
232
+ console.log(chalk.green(`✅ 点击了连接按钮 (选择器: ${selector})`));
214
233
  break;
215
234
  }
216
235
  }
217
- }
218
- catch (e) {
219
- // 继续
236
+ catch (e) {
237
+ // 继续尝试下一个选择器
238
+ }
220
239
  }
221
240
  }
241
+ // 第三步:设置服务器地址(如果有输入框)
242
+ await this.setServerAddress();
222
243
  if (!clicked) {
223
244
  console.log(chalk.yellow('⚠️ 未找到连接按钮,请手动点击连接'));
245
+ // 打印页面上所有按钮的信息以便调试
246
+ try {
247
+ const buttonInfo = await this.page.evaluate(() => {
248
+ const buttons = document.querySelectorAll('button');
249
+ return Array.from(buttons).map(b => ({
250
+ text: b.textContent?.trim().substring(0, 50),
251
+ title: b.getAttribute('title'),
252
+ ariaLabel: b.getAttribute('aria-label'),
253
+ className: b.className.substring(0, 50),
254
+ }));
255
+ });
256
+ console.log(chalk.gray('页面按钮信息:'));
257
+ buttonInfo.forEach((info, i) => {
258
+ console.log(chalk.gray(` ${i + 1}. text="${info.text}" title="${info.title}" aria="${info.ariaLabel}"`));
259
+ });
260
+ }
261
+ catch (e) {
262
+ // 忽略调试信息获取失败
263
+ }
224
264
  }
225
265
  // 等待连接建立
226
266
  await sleep(3000);
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ const program = new Command();
12
12
  program
13
13
  .name('gemini-client')
14
14
  .description('Gemini Proxy Build App 客户端 - 使用 Camoufox 自动保持连接')
15
- .version('1.0.0');
15
+ .version('1.0.7');
16
16
  program
17
17
  .command('start')
18
18
  .description('启动客户端,连接到代理服务器')
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gemini-proxy-client",
3
- "version": "1.0.5",
3
+ "version": "1.0.7",
4
4
  "description": "Gemini Proxy Build App 客户端 - 使用 Camoufox 自动保持连接",
5
5
  "main": "dist/index.js",
6
6
  "bin": {