Files
gemini-skill/src/demo.js

122 lines
3.4 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* demo.js — 使用示例
*
* 两种启动方式:
*
* 方式 1推荐先手动启动浏览器再运行 demo
* chrome --remote-debugging-port=9222 --user-data-dir="~/.gemini-skill/browser-data"
* (也可以用 Edgemsedge --remote-debugging-port=9222 --user-data-dir=...
* node src/demo.js
*
* 方式 2让 skill 自动检测并启动浏览器
* node src/demo.js
* 或指定路径BROWSER_PATH="C:/..." node src/demo.js
*
* 所有配置项见 .env可直接编辑或通过命令行设环境变量。
*/
import { execSync } from 'node:child_process';
import { platform } from 'node:os';
import { createGeminiSession, disconnect } from './index.js';
// ── Demo 专用:杀掉所有 Chromium 系浏览器进程 ──
function killAllBrowserProcesses() {
const os = platform();
const commands = os === 'win32'
? [
'taskkill /F /IM msedge.exe /T',
'taskkill /F /IM chrome.exe /T',
'taskkill /F /IM chromium.exe /T',
]
: [
'pkill -f msedge || true',
'pkill -f chrome || true',
'pkill -f chromium || true',
];
for (const cmd of commands) {
try {
execSync(cmd, { stdio: 'ignore', timeout: 5000 });
} catch {
// 进程不存在时会报错,忽略
}
}
console.log('[demo] 已清理所有浏览器进程');
}
/** 异步等待 */
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
/**
* 创建会话,如果因浏览器目录被锁而失败,自动杀掉全部浏览器进程后重试一次
*/
async function createSessionWithRetry() {
// 禁止 Puppeteer 在 Ctrl+C 等信号时自动杀浏览器进程,
// 由 demo 自己处理 SIGINT → disconnect浏览器保持运行可复用。
const opts = {
debugOpts: {
handleSIGINT: false,
handleSIGTERM: false,
handleSIGHUP: false,
},
};
try {
return await createGeminiSession(opts);
} catch (err) {
const msg = err.message || '';
const isLocked = msg.includes('EPERM') || msg.includes('lock') || msg.includes('already');
if (!isLocked) throw err;
console.warn(
`[demo] 浏览器数据目录被占用,正在清理所有浏览器进程后重试...\n` +
` 原始错误:${msg}`
);
killAllBrowserProcesses();
await sleep(2000);
// 重试一次,还失败就直接抛出
return await createGeminiSession(opts);
}
}
async function main() {
console.log('=== Gemini Skill Demo ===\n');
// 创建会话:自带杀进程重试逻辑
const { ops } = await createSessionWithRetry();
// ── Ctrl+C 时只断开连接,不杀浏览器进程(下次可复用) ──
process.on('SIGINT', () => {
console.log('\n[demo] Ctrl+C 收到,断开浏览器连接(浏览器保持运行)...');
disconnect();
process.exit(0);
});
try {
// 1. 探测页面状态
console.log('[1] 探测页面元素...');
const probe = await ops.probe();
console.log('probe:', JSON.stringify(probe, null, 2));
// 2. 发送一句话
console.log('\n[2] 发送提示词...');
const result = await ops.sendAndWait('Hello Gemini!', {
timeout: 60_000,
onPoll(poll) {
console.log(` polling... status=${poll.status}`);
},
});
console.log('result:', JSON.stringify(result, null, 2));
} catch (err) {
console.error('Error:', err);
} finally {
disconnect();
console.log('\n[done]');
}
}
main().catch(console.error);