botbrowser-mcp 0.1.4 → 0.1.5
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/bin/botbrowser-mcp.js +2 -1
- package/dist/cli.js +4 -6
- package/dist/cli.js.map +1 -1
- package/dist/db/database.d.ts +3 -0
- package/dist/db/database.js +71 -0
- package/dist/db/database.js.map +1 -0
- package/dist/db/repositories/account.d.ts +16 -0
- package/dist/db/repositories/account.js +44 -0
- package/dist/db/repositories/account.js.map +1 -0
- package/dist/db/repositories/instance.d.ts +18 -0
- package/dist/db/repositories/instance.js +45 -0
- package/dist/db/repositories/instance.js.map +1 -0
- package/dist/db/repositories/profile.d.ts +21 -0
- package/dist/db/repositories/profile.js +42 -0
- package/dist/db/repositories/profile.js.map +1 -0
- package/dist/index.d.ts +1 -14
- package/dist/index.js +76 -40
- package/dist/index.js.map +1 -1
- package/dist/playwright/manager.d.ts +43 -0
- package/dist/playwright/manager.js +171 -0
- package/dist/playwright/manager.js.map +1 -0
- package/dist/tools/account.d.ts +116 -0
- package/dist/tools/account.js +110 -0
- package/dist/tools/account.js.map +1 -0
- package/dist/tools/browser.d.ts +178 -0
- package/dist/tools/browser.js +211 -0
- package/dist/tools/browser.js.map +1 -0
- package/dist/tools/instance.d.ts +94 -0
- package/dist/tools/instance.js +97 -0
- package/dist/tools/instance.js.map +1 -0
- package/dist/tools/profile.d.ts +128 -0
- package/dist/tools/profile.js +98 -0
- package/dist/tools/profile.js.map +1 -0
- package/package.json +8 -7
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Playwright 浏览器实例管理器
|
|
3
|
+
*/
|
|
4
|
+
import { chromium } from 'playwright';
|
|
5
|
+
import { ProfileRepository } from '../db/repositories/profile.js';
|
|
6
|
+
import { InstanceRepository } from '../db/repositories/instance.js';
|
|
7
|
+
import { AccountRepository } from '../db/repositories/account.js';
|
|
8
|
+
import fs from 'fs/promises';
|
|
9
|
+
export class PlaywrightManager {
|
|
10
|
+
instances = new Map();
|
|
11
|
+
profileRepo = new ProfileRepository();
|
|
12
|
+
instanceRepo = new InstanceRepository();
|
|
13
|
+
accountRepo = new AccountRepository();
|
|
14
|
+
/**
|
|
15
|
+
* 启动浏览器实例
|
|
16
|
+
*/
|
|
17
|
+
async launchInstance(profileAlias, accountId) {
|
|
18
|
+
const profile = this.profileRepo.getByAlias(profileAlias);
|
|
19
|
+
if (!profile) {
|
|
20
|
+
throw new Error(`浏览器配置不存在: ${profileAlias}`);
|
|
21
|
+
}
|
|
22
|
+
// 验证账号
|
|
23
|
+
if (accountId) {
|
|
24
|
+
const account = this.accountRepo.getById(accountId);
|
|
25
|
+
if (!account || account.profile_alias !== profileAlias) {
|
|
26
|
+
throw new Error(`账号 ${accountId} 不属于配置 ${profileAlias}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
// 准备启动参数
|
|
30
|
+
const launchOptions = {
|
|
31
|
+
executablePath: profile.executable_path,
|
|
32
|
+
headless: false,
|
|
33
|
+
};
|
|
34
|
+
// 防指纹参数
|
|
35
|
+
if (profile.fingerprint_path) {
|
|
36
|
+
launchOptions.args = [`--bot-profile=${profile.fingerprint_path}`];
|
|
37
|
+
}
|
|
38
|
+
// 代理配置
|
|
39
|
+
if (profile.proxy_server) {
|
|
40
|
+
launchOptions.proxy = {
|
|
41
|
+
server: profile.proxy_server,
|
|
42
|
+
};
|
|
43
|
+
if (profile.proxy_username) {
|
|
44
|
+
launchOptions.proxy.username = profile.proxy_username;
|
|
45
|
+
launchOptions.proxy.password = profile.proxy_password || '';
|
|
46
|
+
}
|
|
47
|
+
if (profile.proxy_bypass) {
|
|
48
|
+
launchOptions.proxy.bypass = profile.proxy_bypass;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// 启动浏览器
|
|
52
|
+
const browser = await chromium.launch(launchOptions);
|
|
53
|
+
// 创建上下文 - 加载 storageState
|
|
54
|
+
const contextOptions = {};
|
|
55
|
+
try {
|
|
56
|
+
await fs.access(profile.storage_state_path);
|
|
57
|
+
contextOptions.storageState = profile.storage_state_path;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
// storageState 文件不存在,使用默认
|
|
61
|
+
}
|
|
62
|
+
const context = await browser.newContext(contextOptions);
|
|
63
|
+
// 保存到数据库
|
|
64
|
+
const instanceId = this.instanceRepo.create({
|
|
65
|
+
profile_alias: profileAlias,
|
|
66
|
+
account_id: accountId,
|
|
67
|
+
is_active: this.instances.size === 0 ? 1 : 0, // 第一个实例自动激活
|
|
68
|
+
});
|
|
69
|
+
// 保存到内存
|
|
70
|
+
this.instances.set(instanceId, {
|
|
71
|
+
id: instanceId,
|
|
72
|
+
browser,
|
|
73
|
+
context,
|
|
74
|
+
profileAlias,
|
|
75
|
+
accountId,
|
|
76
|
+
});
|
|
77
|
+
// 如果是第一个实例,设置为活跃
|
|
78
|
+
if (this.instances.size === 1) {
|
|
79
|
+
this.instanceRepo.setActive(instanceId);
|
|
80
|
+
}
|
|
81
|
+
// 更新配置的最后使用时间
|
|
82
|
+
this.profileRepo.updateLastUsed(profileAlias);
|
|
83
|
+
return instanceId;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* 切换活跃实例
|
|
87
|
+
*/
|
|
88
|
+
async switchActive(instanceId) {
|
|
89
|
+
if (!this.instances.has(instanceId)) {
|
|
90
|
+
throw new Error(`实例 ${instanceId} 不存在`);
|
|
91
|
+
}
|
|
92
|
+
this.instanceRepo.setActive(instanceId);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* 停止实例
|
|
96
|
+
*/
|
|
97
|
+
async stopInstance(instanceId) {
|
|
98
|
+
const instance = this.instances.get(instanceId);
|
|
99
|
+
if (!instance) {
|
|
100
|
+
throw new Error(`实例 ${instanceId} 不存在`);
|
|
101
|
+
}
|
|
102
|
+
// 保存 storageState
|
|
103
|
+
const profile = this.profileRepo.getByAlias(instance.profileAlias);
|
|
104
|
+
if (profile) {
|
|
105
|
+
const storageState = await instance.context.storageState();
|
|
106
|
+
await fs.writeFile(profile.storage_state_path, JSON.stringify(storageState, null, 2));
|
|
107
|
+
}
|
|
108
|
+
// 关闭浏览器
|
|
109
|
+
await instance.context.close();
|
|
110
|
+
await instance.browser.close();
|
|
111
|
+
// 从内存和数据库删除
|
|
112
|
+
this.instances.delete(instanceId);
|
|
113
|
+
this.instanceRepo.delete(instanceId);
|
|
114
|
+
// 如果删除的是活跃实例,激活第一个可用实例
|
|
115
|
+
const activeInstance = this.instanceRepo.getActive();
|
|
116
|
+
if (!activeInstance && this.instances.size > 0) {
|
|
117
|
+
const firstId = this.instances.keys().next().value;
|
|
118
|
+
if (firstId !== undefined) {
|
|
119
|
+
this.instanceRepo.setActive(firstId);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* 停止所有实例
|
|
125
|
+
*/
|
|
126
|
+
async stopAll() {
|
|
127
|
+
const ids = Array.from(this.instances.keys());
|
|
128
|
+
for (const id of ids) {
|
|
129
|
+
await this.stopInstance(id);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* 获取活跃实例的上下文
|
|
134
|
+
*/
|
|
135
|
+
getActiveContext() {
|
|
136
|
+
const activeInstance = this.instanceRepo.getActive();
|
|
137
|
+
if (!activeInstance)
|
|
138
|
+
return null;
|
|
139
|
+
const instance = this.instances.get(activeInstance.id);
|
|
140
|
+
if (!instance)
|
|
141
|
+
return null;
|
|
142
|
+
this.instanceRepo.updateLastActive(activeInstance.id);
|
|
143
|
+
return instance.context;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* 获取所有实例列表
|
|
147
|
+
*/
|
|
148
|
+
listInstances() {
|
|
149
|
+
return Array.from(this.instances.values()).map(inst => ({
|
|
150
|
+
id: inst.id,
|
|
151
|
+
profile_alias: inst.profileAlias,
|
|
152
|
+
account_id: inst.accountId,
|
|
153
|
+
is_active: this.instanceRepo.getActive()?.id === inst.id,
|
|
154
|
+
}));
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* 清理已停止的实例记录(实例在内存中不存在但数据库有记录)
|
|
158
|
+
*/
|
|
159
|
+
async cleanupOrphaned() {
|
|
160
|
+
const dbInstances = this.instanceRepo.getAll();
|
|
161
|
+
let cleaned = 0;
|
|
162
|
+
for (const dbInst of dbInstances) {
|
|
163
|
+
if (!this.instances.has(dbInst.id)) {
|
|
164
|
+
this.instanceRepo.delete(dbInst.id);
|
|
165
|
+
cleaned++;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return cleaned;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
//# sourceMappingURL=manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/playwright/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,QAAQ,EAA2B,MAAM,YAAY,CAAC;AAC/D,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,MAAM,aAAa,CAAC;AAU7B,MAAM,OAAO,iBAAiB;IACpB,SAAS,GAAiC,IAAI,GAAG,EAAE,CAAC;IACpD,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAC;IACtC,YAAY,GAAG,IAAI,kBAAkB,EAAE,CAAC;IACxC,WAAW,GAAG,IAAI,iBAAiB,EAAE,CAAC;IAE9C;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,YAAoB,EAAE,SAAkB;QAC3D,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;QAC1D,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,MAAM,IAAI,KAAK,CAAC,aAAa,YAAY,EAAE,CAAC,CAAC;QAC/C,CAAC;QAED,OAAO;QACP,IAAI,SAAS,EAAE,CAAC;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;YACpD,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,aAAa,KAAK,YAAY,EAAE,CAAC;gBACvD,MAAM,IAAI,KAAK,CAAC,MAAM,SAAS,UAAU,YAAY,EAAE,CAAC,CAAC;YAC3D,CAAC;QACH,CAAC;QAED,SAAS;QACT,MAAM,aAAa,GAAQ;YACzB,cAAc,EAAE,OAAO,CAAC,eAAe;YACvC,QAAQ,EAAE,KAAK;SAChB,CAAC;QAEF,QAAQ;QACR,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC;YAC7B,aAAa,CAAC,IAAI,GAAG,CAAC,iBAAiB,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;QACrE,CAAC;QAED,OAAO;QACP,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;YACzB,aAAa,CAAC,KAAK,GAAG;gBACpB,MAAM,EAAE,OAAO,CAAC,YAAY;aAC7B,CAAC;YACF,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;gBAC3B,aAAa,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;gBACtD,aAAa,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,cAAc,IAAI,EAAE,CAAC;YAC9D,CAAC;YACD,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;gBACzB,aAAa,CAAC,KAAK,CAAC,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;YACpD,CAAC;QACH,CAAC;QAED,QAAQ;QACR,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC;QAErD,0BAA0B;QAC1B,MAAM,cAAc,GAAQ,EAAE,CAAC;QAC/B,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;YAC5C,cAAc,CAAC,YAAY,GAAG,OAAO,CAAC,kBAAkB,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,0BAA0B;QAC5B,CAAC;QAED,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QAEzD,SAAS;QACT,MAAM,UAAU,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;YAC1C,aAAa,EAAE,YAAY;YAC3B,UAAU,EAAE,SAAS;YACrB,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,YAAY;SAC3D,CAAC,CAAC;QAEH,QAAQ;QACR,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,EAAE;YAC7B,EAAE,EAAE,UAAU;YACd,OAAO;YACP,OAAO;YACP,YAAY;YACZ,SAAS;SACV,CAAC,CAAC;QAEH,iBAAiB;QACjB,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;YAC9B,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAC1C,CAAC;QAED,cAAc;QACd,IAAI,CAAC,WAAW,CAAC,cAAc,CAAC,YAAY,CAAC,CAAC;QAE9C,OAAO,UAAU,CAAC;IACpB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,UAAkB;QACnC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;YACpC,MAAM,IAAI,KAAK,CAAC,MAAM,UAAU,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;IAC1C,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY,CAAC,UAAkB;QACnC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,EAAE,CAAC;YACd,MAAM,IAAI,KAAK,CAAC,MAAM,UAAU,MAAM,CAAC,CAAC;QAC1C,CAAC;QAED,kBAAkB;QAClB,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;QACnE,IAAI,OAAO,EAAE,CAAC;YACZ,MAAM,YAAY,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,YAAY,EAAE,CAAC;YAC3D,MAAM,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,kBAAkB,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACxF,CAAC;QAED,QAAQ;QACR,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/B,MAAM,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;QAE/B,YAAY;QACZ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAClC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QAErC,uBAAuB;QACvB,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QACrD,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,SAAS,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,IAAI,EAAE,CAAC,KAA2B,CAAC;YACzE,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,OAAO;QACX,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;YACrB,MAAM,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED;;OAEG;IACH,gBAAgB;QACd,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,CAAC;QACrD,IAAI,CAAC,cAAc;YAAE,OAAO,IAAI,CAAC;QAEjC,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACvD,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,IAAI,CAAC,YAAY,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QACtD,OAAO,QAAQ,CAAC,OAAO,CAAC;IAC1B,CAAC;IAED;;OAEG;IACH,aAAa;QACX,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACtD,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,aAAa,EAAE,IAAI,CAAC,YAAY;YAChC,UAAU,EAAE,IAAI,CAAC,SAAS;YAC1B,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC,EAAE;SACzD,CAAC,CAAC,CAAC;IACN,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,WAAW,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,EAAE,CAAC;QAC/C,IAAI,OAAO,GAAG,CAAC,CAAC;QAEhB,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACpC,OAAO,EAAE,CAAC;YACZ,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
export declare const accountTools: {
|
|
2
|
+
add_account: {
|
|
3
|
+
description: string;
|
|
4
|
+
inputSchema: {
|
|
5
|
+
type: string;
|
|
6
|
+
properties: {
|
|
7
|
+
profile_alias: {
|
|
8
|
+
type: string;
|
|
9
|
+
description: string;
|
|
10
|
+
};
|
|
11
|
+
username: {
|
|
12
|
+
type: string;
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
metadata: {
|
|
16
|
+
type: string;
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
required: string[];
|
|
21
|
+
};
|
|
22
|
+
handler: (args: any) => Promise<{
|
|
23
|
+
content: {
|
|
24
|
+
type: string;
|
|
25
|
+
text: string;
|
|
26
|
+
}[];
|
|
27
|
+
}>;
|
|
28
|
+
};
|
|
29
|
+
list_accounts: {
|
|
30
|
+
description: string;
|
|
31
|
+
inputSchema: {
|
|
32
|
+
type: string;
|
|
33
|
+
properties: {
|
|
34
|
+
profile_alias: {
|
|
35
|
+
type: string;
|
|
36
|
+
description: string;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
};
|
|
40
|
+
handler: (args: any) => Promise<{
|
|
41
|
+
content: {
|
|
42
|
+
type: string;
|
|
43
|
+
text: string;
|
|
44
|
+
}[];
|
|
45
|
+
}>;
|
|
46
|
+
};
|
|
47
|
+
find_account: {
|
|
48
|
+
description: string;
|
|
49
|
+
inputSchema: {
|
|
50
|
+
type: string;
|
|
51
|
+
properties: {
|
|
52
|
+
profile_alias: {
|
|
53
|
+
type: string;
|
|
54
|
+
description: string;
|
|
55
|
+
};
|
|
56
|
+
username: {
|
|
57
|
+
type: string;
|
|
58
|
+
description: string;
|
|
59
|
+
};
|
|
60
|
+
};
|
|
61
|
+
required: string[];
|
|
62
|
+
};
|
|
63
|
+
handler: (args: any) => Promise<{
|
|
64
|
+
content: {
|
|
65
|
+
type: string;
|
|
66
|
+
text: string;
|
|
67
|
+
}[];
|
|
68
|
+
}>;
|
|
69
|
+
};
|
|
70
|
+
update_account: {
|
|
71
|
+
description: string;
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: string;
|
|
74
|
+
properties: {
|
|
75
|
+
id: {
|
|
76
|
+
type: string;
|
|
77
|
+
description: string;
|
|
78
|
+
};
|
|
79
|
+
username: {
|
|
80
|
+
type: string;
|
|
81
|
+
description: string;
|
|
82
|
+
};
|
|
83
|
+
metadata: {
|
|
84
|
+
type: string;
|
|
85
|
+
description: string;
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
required: string[];
|
|
89
|
+
};
|
|
90
|
+
handler: (args: any) => Promise<{
|
|
91
|
+
content: {
|
|
92
|
+
type: string;
|
|
93
|
+
text: string;
|
|
94
|
+
}[];
|
|
95
|
+
}>;
|
|
96
|
+
};
|
|
97
|
+
delete_account: {
|
|
98
|
+
description: string;
|
|
99
|
+
inputSchema: {
|
|
100
|
+
type: string;
|
|
101
|
+
properties: {
|
|
102
|
+
id: {
|
|
103
|
+
type: string;
|
|
104
|
+
description: string;
|
|
105
|
+
};
|
|
106
|
+
};
|
|
107
|
+
required: string[];
|
|
108
|
+
};
|
|
109
|
+
handler: (args: any) => Promise<{
|
|
110
|
+
content: {
|
|
111
|
+
type: string;
|
|
112
|
+
text: string;
|
|
113
|
+
}[];
|
|
114
|
+
}>;
|
|
115
|
+
};
|
|
116
|
+
};
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 账号管理工具
|
|
3
|
+
*/
|
|
4
|
+
import { AccountRepository } from '../db/repositories/account.js';
|
|
5
|
+
const accountRepo = new AccountRepository();
|
|
6
|
+
export const accountTools = {
|
|
7
|
+
add_account: {
|
|
8
|
+
description: '添加账号到浏览器配置',
|
|
9
|
+
inputSchema: {
|
|
10
|
+
type: 'object',
|
|
11
|
+
properties: {
|
|
12
|
+
profile_alias: { type: 'string', description: '浏览器配置别名' },
|
|
13
|
+
username: { type: 'string', description: '账号用户名' },
|
|
14
|
+
metadata: { type: 'string', description: '账号元数据(密码、邮箱等信息,格式自由)' },
|
|
15
|
+
},
|
|
16
|
+
required: ['profile_alias', 'username'],
|
|
17
|
+
},
|
|
18
|
+
handler: async (args) => {
|
|
19
|
+
const id = accountRepo.create(args);
|
|
20
|
+
return {
|
|
21
|
+
content: [{
|
|
22
|
+
type: 'text',
|
|
23
|
+
text: `账号 "${args.username}" 添加成功,ID: ${id}`,
|
|
24
|
+
}],
|
|
25
|
+
};
|
|
26
|
+
},
|
|
27
|
+
},
|
|
28
|
+
list_accounts: {
|
|
29
|
+
description: '列出所有账号或指定配置的账号',
|
|
30
|
+
inputSchema: {
|
|
31
|
+
type: 'object',
|
|
32
|
+
properties: {
|
|
33
|
+
profile_alias: { type: 'string', description: '浏览器配置别名(可选)' },
|
|
34
|
+
},
|
|
35
|
+
},
|
|
36
|
+
handler: async (args) => {
|
|
37
|
+
const accounts = args.profile_alias
|
|
38
|
+
? accountRepo.getByProfile(args.profile_alias)
|
|
39
|
+
: accountRepo.getAll();
|
|
40
|
+
return {
|
|
41
|
+
content: [{
|
|
42
|
+
type: 'text',
|
|
43
|
+
text: JSON.stringify(accounts, null, 2),
|
|
44
|
+
}],
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
},
|
|
48
|
+
find_account: {
|
|
49
|
+
description: '查找指定配置下的账号',
|
|
50
|
+
inputSchema: {
|
|
51
|
+
type: 'object',
|
|
52
|
+
properties: {
|
|
53
|
+
profile_alias: { type: 'string', description: '浏览器配置别名' },
|
|
54
|
+
username: { type: 'string', description: '账号用户名' },
|
|
55
|
+
},
|
|
56
|
+
required: ['profile_alias', 'username'],
|
|
57
|
+
},
|
|
58
|
+
handler: async (args) => {
|
|
59
|
+
const account = accountRepo.findByUsername(args.profile_alias, args.username);
|
|
60
|
+
return {
|
|
61
|
+
content: [{
|
|
62
|
+
type: 'text',
|
|
63
|
+
text: account ? JSON.stringify(account, null, 2) : '未找到账号',
|
|
64
|
+
}],
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
},
|
|
68
|
+
update_account: {
|
|
69
|
+
description: '更新账号信息',
|
|
70
|
+
inputSchema: {
|
|
71
|
+
type: 'object',
|
|
72
|
+
properties: {
|
|
73
|
+
id: { type: 'number', description: '账号ID' },
|
|
74
|
+
username: { type: 'string', description: '新用户名' },
|
|
75
|
+
metadata: { type: 'string', description: '新元数据' },
|
|
76
|
+
},
|
|
77
|
+
required: ['id'],
|
|
78
|
+
},
|
|
79
|
+
handler: async (args) => {
|
|
80
|
+
const { id, ...updates } = args;
|
|
81
|
+
accountRepo.update(id, updates);
|
|
82
|
+
return {
|
|
83
|
+
content: [{
|
|
84
|
+
type: 'text',
|
|
85
|
+
text: `账号 ${id} 更新成功`,
|
|
86
|
+
}],
|
|
87
|
+
};
|
|
88
|
+
},
|
|
89
|
+
},
|
|
90
|
+
delete_account: {
|
|
91
|
+
description: '删除账号',
|
|
92
|
+
inputSchema: {
|
|
93
|
+
type: 'object',
|
|
94
|
+
properties: {
|
|
95
|
+
id: { type: 'number', description: '账号ID' },
|
|
96
|
+
},
|
|
97
|
+
required: ['id'],
|
|
98
|
+
},
|
|
99
|
+
handler: async (args) => {
|
|
100
|
+
accountRepo.delete(args.id);
|
|
101
|
+
return {
|
|
102
|
+
content: [{
|
|
103
|
+
type: 'text',
|
|
104
|
+
text: `账号 ${args.id} 删除成功`,
|
|
105
|
+
}],
|
|
106
|
+
};
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
};
|
|
110
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/tools/account.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 浏览器操作工具
|
|
3
|
+
* 基于 Playwright API 实现常用浏览器操作
|
|
4
|
+
*/
|
|
5
|
+
import { PlaywrightManager } from '../playwright/manager.js';
|
|
6
|
+
export declare function setManager(m: PlaywrightManager): void;
|
|
7
|
+
export declare const browserTools: {
|
|
8
|
+
browser_navigate: {
|
|
9
|
+
description: string;
|
|
10
|
+
inputSchema: {
|
|
11
|
+
type: string;
|
|
12
|
+
properties: {
|
|
13
|
+
url: {
|
|
14
|
+
type: string;
|
|
15
|
+
description: string;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
18
|
+
required: string[];
|
|
19
|
+
};
|
|
20
|
+
handler: (args: any) => Promise<{
|
|
21
|
+
content: {
|
|
22
|
+
type: string;
|
|
23
|
+
text: string;
|
|
24
|
+
}[];
|
|
25
|
+
}>;
|
|
26
|
+
};
|
|
27
|
+
browser_click: {
|
|
28
|
+
description: string;
|
|
29
|
+
inputSchema: {
|
|
30
|
+
type: string;
|
|
31
|
+
properties: {
|
|
32
|
+
selector: {
|
|
33
|
+
type: string;
|
|
34
|
+
description: string;
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
required: string[];
|
|
38
|
+
};
|
|
39
|
+
handler: (args: any) => Promise<{
|
|
40
|
+
content: {
|
|
41
|
+
type: string;
|
|
42
|
+
text: string;
|
|
43
|
+
}[];
|
|
44
|
+
}>;
|
|
45
|
+
};
|
|
46
|
+
browser_fill: {
|
|
47
|
+
description: string;
|
|
48
|
+
inputSchema: {
|
|
49
|
+
type: string;
|
|
50
|
+
properties: {
|
|
51
|
+
selector: {
|
|
52
|
+
type: string;
|
|
53
|
+
description: string;
|
|
54
|
+
};
|
|
55
|
+
value: {
|
|
56
|
+
type: string;
|
|
57
|
+
description: string;
|
|
58
|
+
};
|
|
59
|
+
};
|
|
60
|
+
required: string[];
|
|
61
|
+
};
|
|
62
|
+
handler: (args: any) => Promise<{
|
|
63
|
+
content: {
|
|
64
|
+
type: string;
|
|
65
|
+
text: string;
|
|
66
|
+
}[];
|
|
67
|
+
}>;
|
|
68
|
+
};
|
|
69
|
+
browser_screenshot: {
|
|
70
|
+
description: string;
|
|
71
|
+
inputSchema: {
|
|
72
|
+
type: string;
|
|
73
|
+
properties: {
|
|
74
|
+
path: {
|
|
75
|
+
type: string;
|
|
76
|
+
description: string;
|
|
77
|
+
};
|
|
78
|
+
fullPage: {
|
|
79
|
+
type: string;
|
|
80
|
+
description: string;
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
required: string[];
|
|
84
|
+
};
|
|
85
|
+
handler: (args: any) => Promise<{
|
|
86
|
+
content: {
|
|
87
|
+
type: string;
|
|
88
|
+
text: string;
|
|
89
|
+
}[];
|
|
90
|
+
}>;
|
|
91
|
+
};
|
|
92
|
+
browser_get_text: {
|
|
93
|
+
description: string;
|
|
94
|
+
inputSchema: {
|
|
95
|
+
type: string;
|
|
96
|
+
properties: {
|
|
97
|
+
selector: {
|
|
98
|
+
type: string;
|
|
99
|
+
description: string;
|
|
100
|
+
};
|
|
101
|
+
};
|
|
102
|
+
required: string[];
|
|
103
|
+
};
|
|
104
|
+
handler: (args: any) => Promise<{
|
|
105
|
+
content: {
|
|
106
|
+
type: string;
|
|
107
|
+
text: string;
|
|
108
|
+
}[];
|
|
109
|
+
}>;
|
|
110
|
+
};
|
|
111
|
+
browser_wait: {
|
|
112
|
+
description: string;
|
|
113
|
+
inputSchema: {
|
|
114
|
+
type: string;
|
|
115
|
+
properties: {
|
|
116
|
+
selector: {
|
|
117
|
+
type: string;
|
|
118
|
+
description: string;
|
|
119
|
+
};
|
|
120
|
+
timeout: {
|
|
121
|
+
type: string;
|
|
122
|
+
description: string;
|
|
123
|
+
};
|
|
124
|
+
};
|
|
125
|
+
};
|
|
126
|
+
handler: (args: any) => Promise<{
|
|
127
|
+
content: {
|
|
128
|
+
type: string;
|
|
129
|
+
text: string;
|
|
130
|
+
}[];
|
|
131
|
+
}>;
|
|
132
|
+
};
|
|
133
|
+
browser_evaluate: {
|
|
134
|
+
description: string;
|
|
135
|
+
inputSchema: {
|
|
136
|
+
type: string;
|
|
137
|
+
properties: {
|
|
138
|
+
script: {
|
|
139
|
+
type: string;
|
|
140
|
+
description: string;
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
required: string[];
|
|
144
|
+
};
|
|
145
|
+
handler: (args: any) => Promise<{
|
|
146
|
+
content: {
|
|
147
|
+
type: string;
|
|
148
|
+
text: string;
|
|
149
|
+
}[];
|
|
150
|
+
}>;
|
|
151
|
+
};
|
|
152
|
+
browser_new_page: {
|
|
153
|
+
description: string;
|
|
154
|
+
inputSchema: {
|
|
155
|
+
type: string;
|
|
156
|
+
properties: {};
|
|
157
|
+
};
|
|
158
|
+
handler: () => Promise<{
|
|
159
|
+
content: {
|
|
160
|
+
type: string;
|
|
161
|
+
text: string;
|
|
162
|
+
}[];
|
|
163
|
+
}>;
|
|
164
|
+
};
|
|
165
|
+
browser_get_url: {
|
|
166
|
+
description: string;
|
|
167
|
+
inputSchema: {
|
|
168
|
+
type: string;
|
|
169
|
+
properties: {};
|
|
170
|
+
};
|
|
171
|
+
handler: () => Promise<{
|
|
172
|
+
content: {
|
|
173
|
+
type: string;
|
|
174
|
+
text: string;
|
|
175
|
+
}[];
|
|
176
|
+
}>;
|
|
177
|
+
};
|
|
178
|
+
};
|