web-fetcher-mcp 1.0.0

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.
Files changed (58) hide show
  1. package/README.md +185 -0
  2. package/dist/index.d.ts +3 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +278 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/tools/click-element.d.ts +3 -0
  7. package/dist/tools/click-element.d.ts.map +1 -0
  8. package/dist/tools/click-element.js +166 -0
  9. package/dist/tools/click-element.js.map +1 -0
  10. package/dist/tools/focus-input.d.ts +3 -0
  11. package/dist/tools/focus-input.d.ts.map +1 -0
  12. package/dist/tools/focus-input.js +78 -0
  13. package/dist/tools/focus-input.js.map +1 -0
  14. package/dist/tools/tapd-bug-fetcher.d.ts +20 -0
  15. package/dist/tools/tapd-bug-fetcher.d.ts.map +1 -0
  16. package/dist/tools/tapd-bug-fetcher.js +376 -0
  17. package/dist/tools/tapd-bug-fetcher.js.map +1 -0
  18. package/dist/tools/type-input.d.ts +3 -0
  19. package/dist/tools/type-input.d.ts.map +1 -0
  20. package/dist/tools/type-input.js +97 -0
  21. package/dist/tools/type-input.js.map +1 -0
  22. package/dist/tools/utils/utils.d.ts +2 -0
  23. package/dist/tools/utils/utils.d.ts.map +1 -0
  24. package/dist/tools/utils/utils.js +7 -0
  25. package/dist/tools/utils/utils.js.map +1 -0
  26. package/dist/tools/web-page-fetcher.d.ts +3 -0
  27. package/dist/tools/web-page-fetcher.d.ts.map +1 -0
  28. package/dist/tools/web-page-fetcher.js +100 -0
  29. package/dist/tools/web-page-fetcher.js.map +1 -0
  30. package/dist/types/index.d.ts +73 -0
  31. package/dist/types/index.d.ts.map +1 -0
  32. package/dist/types/index.js +3 -0
  33. package/dist/types/index.js.map +1 -0
  34. package/dist/utils/browser.d.ts +6 -0
  35. package/dist/utils/browser.d.ts.map +1 -0
  36. package/dist/utils/browser.js +95 -0
  37. package/dist/utils/browser.js.map +1 -0
  38. package/dist/utils/config.d.ts +7 -0
  39. package/dist/utils/config.d.ts.map +1 -0
  40. package/dist/utils/config.js +11 -0
  41. package/dist/utils/config.js.map +1 -0
  42. package/dist/utils/cookies.d.ts +5 -0
  43. package/dist/utils/cookies.d.ts.map +1 -0
  44. package/dist/utils/cookies.js +46 -0
  45. package/dist/utils/cookies.js.map +1 -0
  46. package/dist/utils/images.d.ts +5 -0
  47. package/dist/utils/images.d.ts.map +1 -0
  48. package/dist/utils/images.js +59 -0
  49. package/dist/utils/images.js.map +1 -0
  50. package/dist/utils/login-check.d.ts +4 -0
  51. package/dist/utils/login-check.d.ts.map +1 -0
  52. package/dist/utils/login-check.js +110 -0
  53. package/dist/utils/login-check.js.map +1 -0
  54. package/dist/utils/page-content.d.ts +4 -0
  55. package/dist/utils/page-content.d.ts.map +1 -0
  56. package/dist/utils/page-content.js +139 -0
  57. package/dist/utils/page-content.js.map +1 -0
  58. package/package.json +47 -0
@@ -0,0 +1,3 @@
1
+ import { FocusInputResult } from '../types/index.js';
2
+ export declare function focusInputElement(url: string, selector: string, useExistingPage?: boolean): Promise<FocusInputResult>;
3
+ //# sourceMappingURL=focus-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-input.d.ts","sourceRoot":"","sources":["../../src/tools/focus-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAIrD,wBAAsB,iBAAiB,CACrC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CA6F3B"}
@@ -0,0 +1,78 @@
1
+ import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
2
+ // 获取输入框焦点
3
+ export async function focusInputElement(url, selector, useExistingPage = true) {
4
+ let browserConnection = null;
5
+ try {
6
+ // 获取浏览器实例
7
+ browserConnection = await getBrowser();
8
+ const { browser, useExistingBrowser } = browserConnection;
9
+ // 获取页面
10
+ const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
11
+ // 如果需要导航到指定 URL
12
+ if (!useExistingPage && url !== 'current') {
13
+ await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
14
+ }
15
+ console.error(`正在查找元素: ${selector}`);
16
+ // 等待元素出现
17
+ await page.waitForSelector(selector, { timeout: 10000 });
18
+ // 获取元素信息并设置焦点
19
+ const elementInfo = await page.evaluate((sel) => {
20
+ const element = document.querySelector(sel);
21
+ if (!element) {
22
+ return null;
23
+ }
24
+ // 获取元素信息
25
+ const info = {
26
+ tagName: element.tagName.toLowerCase(),
27
+ type: element.getAttribute('type') || undefined,
28
+ name: element.getAttribute('name') || undefined,
29
+ id: element.id || undefined,
30
+ className: element.className || undefined,
31
+ placeholder: element.getAttribute('placeholder') || undefined,
32
+ value: element.value || undefined
33
+ };
34
+ // 聚焦元素
35
+ element.focus();
36
+ element.click();
37
+ // 滚动到元素可见
38
+ element.scrollIntoView({ behavior: 'smooth', block: 'center' });
39
+ return info;
40
+ }, selector);
41
+ if (!elementInfo) {
42
+ await closeBrowser(browser, useExistingBrowser, true);
43
+ return {
44
+ success: false,
45
+ error: `未找到元素: ${selector}`
46
+ };
47
+ }
48
+ // 验证是否是可输入元素
49
+ const inputTagNames = ['input', 'textarea', 'select'];
50
+ const isContentEditable = await page.evaluate((sel) => {
51
+ const el = document.querySelector(sel);
52
+ return el && el.isContentEditable;
53
+ }, selector);
54
+ if (!inputTagNames.includes(elementInfo.tagName) && !isContentEditable) {
55
+ console.error(`警告: 元素 ${elementInfo.tagName} 不是标准输入元素,但已尝试获取焦点`);
56
+ }
57
+ console.error(`成功获取焦点,元素类型: ${elementInfo.tagName}`);
58
+ // 保持浏览器打开,让用户可以继续操作
59
+ await closeBrowser(browser, useExistingBrowser, true);
60
+ return {
61
+ success: true,
62
+ elementInfo
63
+ };
64
+ }
65
+ catch (error) {
66
+ console.error('获取焦点失败:', error);
67
+ // 发生错误时保持浏览器打开,方便调试
68
+ if (browserConnection) {
69
+ const { browser, useExistingBrowser } = browserConnection;
70
+ await closeBrowser(browser, useExistingBrowser, true);
71
+ }
72
+ return {
73
+ success: false,
74
+ error: error.message || '未知错误'
75
+ };
76
+ }
77
+ }
78
+ //# sourceMappingURL=focus-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"focus-input.js","sourceRoot":"","sources":["../../src/tools/focus-input.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExE,UAAU;AACV,MAAM,CAAC,KAAK,UAAU,iBAAiB,CACrC,GAAW,EACX,QAAgB,EAChB,kBAA2B,IAAI;IAE/B,IAAI,iBAAiB,GAAG,IAAI,CAAC;IAE7B,IAAI,CAAC;QACH,UAAU;QACV,iBAAiB,GAAG,MAAM,UAAU,EAAE,CAAC;QACvC,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,CAAC;QAE1D,OAAO;QACP,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAE3F,gBAAgB;QAChB,IAAI,CAAC,eAAe,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YAC1C,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QACtE,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,WAAW,QAAQ,EAAE,CAAC,CAAC;QAErC,SAAS;QACT,MAAM,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAEzD,cAAc;QACd,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;YAC9C,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAkD,CAAC;YAE7F,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,OAAO,IAAI,CAAC;YACd,CAAC;YAED,SAAS;YACT,MAAM,IAAI,GAAG;gBACX,OAAO,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE;gBACtC,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS;gBAC/C,IAAI,EAAE,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS;gBAC/C,EAAE,EAAE,OAAO,CAAC,EAAE,IAAI,SAAS;gBAC3B,SAAS,EAAE,OAAO,CAAC,SAAS,IAAI,SAAS;gBACzC,WAAW,EAAE,OAAO,CAAC,YAAY,CAAC,aAAa,CAAC,IAAI,SAAS;gBAC7D,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;aAClC,CAAC;YAEF,OAAO;YACP,OAAO,CAAC,KAAK,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,EAAE,CAAC;YAEhB,UAAU;YACV,OAAO,CAAC,cAAc,CAAC,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;YAEhE,OAAO,IAAI,CAAC;QACd,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEb,IAAI,CAAC,WAAW,EAAE,CAAC;YACjB,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;YACtD,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,UAAU,QAAQ,EAAE;aAC5B,CAAC;QACJ,CAAC;QAED,aAAa;QACb,MAAM,aAAa,GAAG,CAAC,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAC;QACtD,MAAM,iBAAiB,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,CAAC,GAAG,EAAE,EAAE;YACpD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAgB,CAAC;YACtD,OAAO,EAAE,IAAI,EAAE,CAAC,iBAAiB,CAAC;QACpC,CAAC,EAAE,QAAQ,CAAC,CAAC;QAEb,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACvE,OAAO,CAAC,KAAK,CAAC,UAAU,WAAW,CAAC,OAAO,oBAAoB,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,CAAC,KAAK,CAAC,gBAAgB,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;QAErD,oBAAoB;QACpB,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAEtD,OAAO;YACL,OAAO,EAAE,IAAI;YACb,WAAW;SACZ,CAAC;IAEJ,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QACpB,OAAO,CAAC,KAAK,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;QAEhC,oBAAoB;QACpB,IAAI,iBAAiB,EAAE,CAAC;YACtB,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,GAAG,iBAAiB,CAAC;YAC1D,MAAM,YAAY,CAAC,OAAO,EAAE,kBAAkB,EAAE,IAAI,CAAC,CAAC;QACxD,CAAC;QAED,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,KAAK,CAAC,OAAO,IAAI,MAAM;SAC/B,CAAC;IACJ,CAAC;AACH,CAAC"}
@@ -0,0 +1,20 @@
1
+ interface BugContent {
2
+ text: string;
3
+ images: string[];
4
+ downloadedImages: DownloadedImage[];
5
+ }
6
+ interface DownloadedImage {
7
+ originalUrl: string;
8
+ localPath: string;
9
+ base64: string;
10
+ filename: string;
11
+ }
12
+ interface FetchBugResult {
13
+ success: boolean;
14
+ content?: BugContent;
15
+ error?: string;
16
+ loginRequired?: boolean;
17
+ }
18
+ export declare function fetchTAPDBug(bugUrl: string, loginMode?: 'auto' | 'manual', contentSelector?: string): Promise<FetchBugResult>;
19
+ export {};
20
+ //# sourceMappingURL=tapd-bug-fetcher.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tapd-bug-fetcher.d.ts","sourceRoot":"","sources":["../../src/tools/tapd-bug-fetcher.ts"],"names":[],"mappings":"AAWA,UAAU,UAAU;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gBAAgB,EAAE,eAAe,EAAE,CAAC;CACrC;AAED,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,UAAU,cAAc;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,UAAU,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AA4JD,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,GAAE,MAAM,GAAG,QAAiB,EAAE,eAAe,GAAE,MAAwB,GAAG,OAAO,CAAC,cAAc,CAAC,CAiN5J"}
@@ -0,0 +1,376 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.fetchTAPDBug = fetchTAPDBug;
40
+ const puppeteer_1 = __importDefault(require("puppeteer"));
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const axios_1 = __importDefault(require("axios"));
45
+ // 数据存储目录:用户主目录下的 .tapd-mcp
46
+ const DATA_DIR = path.join(os.homedir(), '.tapd-mcp');
47
+ const COOKIE_FILE = path.join(DATA_DIR, 'tapd_cookies.json');
48
+ const IMAGES_DIR = path.join(DATA_DIR, 'tapd_images');
49
+ // 保存 Cookie 到文件
50
+ async function saveCookies(cookies) {
51
+ try {
52
+ fs.writeFileSync(COOKIE_FILE, JSON.stringify(cookies, null, 2));
53
+ console.error('Cookie 已保存到:', COOKIE_FILE);
54
+ }
55
+ catch (error) {
56
+ console.error('保存 Cookie 失败:', error);
57
+ }
58
+ }
59
+ // 从文件加载 Cookie
60
+ async function loadCookies() {
61
+ try {
62
+ if (fs.existsSync(COOKIE_FILE)) {
63
+ const cookies = JSON.parse(fs.readFileSync(COOKIE_FILE, 'utf-8'));
64
+ console.error('已从文件加载 Cookie');
65
+ return cookies;
66
+ }
67
+ }
68
+ catch (error) {
69
+ console.error('加载 Cookie 失败:', error);
70
+ }
71
+ return [];
72
+ }
73
+ // 检查是否已登录
74
+ async function isLoggedIn(page) {
75
+ try {
76
+ // 检查是否存在登录相关的元素或者重定向
77
+ const currentUrl = page.url();
78
+ if (currentUrl.includes('login')) {
79
+ return false;
80
+ }
81
+ // 尝试查找登录按钮或登录页面特征
82
+ const loginElement = await page.$('#loginForm, .login-box, [data-action="login"]');
83
+ return !loginElement;
84
+ }
85
+ catch (error) {
86
+ console.error('检查登录状态失败:', error);
87
+ return false;
88
+ }
89
+ }
90
+ // 提取 bug 详情内容
91
+ async function extractBugContent(page, contentSelector = '.app__content') {
92
+ const content = await page.evaluate((selector) => {
93
+ let detailElement = document.querySelector(selector);
94
+ let text = '';
95
+ let images = [];
96
+ if (detailElement) {
97
+ // 提取文本内容
98
+ text = detailElement.innerText || '';
99
+ // 提取图片
100
+ const imgElements = detailElement.querySelectorAll('img');
101
+ imgElements.forEach((img) => {
102
+ const src = img.getAttribute('src') || img.getAttribute('data-src');
103
+ if (src) {
104
+ images.push(src);
105
+ }
106
+ });
107
+ }
108
+ else {
109
+ // 如果找不到指定元素,获取整个 HTML
110
+ text = document.documentElement.innerText || '';
111
+ // 提取整个页面的图片
112
+ const imgElements = document.querySelectorAll('img');
113
+ imgElements.forEach((img) => {
114
+ const src = img.getAttribute('src') || img.getAttribute('data-src');
115
+ if (src) {
116
+ images.push(src);
117
+ }
118
+ });
119
+ }
120
+ return {
121
+ text,
122
+ images,
123
+ downloadedImages: []
124
+ };
125
+ }, contentSelector);
126
+ return content;
127
+ }
128
+ // 下载并转换图片为 Base64
129
+ async function downloadAndConvertImage(imageUrl, cookies) {
130
+ try {
131
+ console.error(`正在下载图片:${imageUrl}`);
132
+ // 确保图片目录存在
133
+ if (!fs.existsSync(IMAGES_DIR)) {
134
+ fs.mkdirSync(IMAGES_DIR, { recursive: true });
135
+ }
136
+ // 生成文件名
137
+ const filename = `bug_image_${Date.now()}_${Math.random().toString(36).substring(7)}.png`;
138
+ const localPath = path.join(IMAGES_DIR, filename);
139
+ // 使用 puppeteer 下载图片(因为需要 Cookie 认证)
140
+ // 注意:puppeteer 的 cookie 对象属性是 name 和 value(不是方法)
141
+ const cookieString = cookies.map((c) => `${c.name}=${c.value}`).join('; ');
142
+ const response = await axios_1.default.get(imageUrl, {
143
+ responseType: 'arraybuffer',
144
+ headers: {
145
+ 'Cookie': cookieString
146
+ },
147
+ timeout: 30000
148
+ });
149
+ // 保存为本地文件
150
+ fs.writeFileSync(localPath, response.data);
151
+ console.error(`图片已保存到:${localPath}`);
152
+ // 转换为 Base64
153
+ const base64 = Buffer.from(response.data).toString('base64');
154
+ return {
155
+ originalUrl: imageUrl,
156
+ localPath,
157
+ base64,
158
+ filename
159
+ };
160
+ }
161
+ catch (error) {
162
+ console.error(`下载图片失败 ${imageUrl}:`, error.message);
163
+ return null;
164
+ }
165
+ }
166
+ // 分析图片内容(使用多模态 AI)
167
+ // 注意:这里可以集成各种 AI API,如 Claude API、GPT-4V 等
168
+ // 由于 MCP Server 本身不直接支持多模态,我们返回 Base64 数据,让 Client 端调用 AI 分析
169
+ async function analyzeImage(imageBase64, imageUrl) {
170
+ try {
171
+ console.error('正在分析图片内容...');
172
+ // 方案 1:返回 Base64,让 MCP Client 调用 AI 分析(推荐)
173
+ // 在 index.ts 中,我们可以返回图片的 Base64 数据
174
+ // Client 端可以使用多模态模型(如 Claude 3)来分析图片
175
+ // 方案 2:在这里集成 AI API(需要配置 API Key)
176
+ // 例如:调用 Anthropic Claude API、OpenAI GPT-4V 等
177
+ // 由于图片分析需要多模态 AI 能力,我们返回一个标记
178
+ // 告诉 Client 端这是一张需要分析的图片
179
+ return `[图片待分析:${imageUrl}]`;
180
+ }
181
+ catch (error) {
182
+ console.error('分析图片失败:', error);
183
+ return '图片分析失败';
184
+ }
185
+ }
186
+ // 主函数:获取 TAPD bug 详情
187
+ async function fetchTAPDBug(bugUrl, loginMode = 'auto', contentSelector = '.app__content') {
188
+ let browser = null;
189
+ let useExistingBrowser = false;
190
+ try {
191
+ const chromePath = 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe';
192
+ const userDataDir = path.join(DATA_DIR, 'chrome-user-data');
193
+ const debuggingPort = 9222;
194
+ // 确保数据目录存在
195
+ if (!fs.existsSync(DATA_DIR)) {
196
+ fs.mkdirSync(DATA_DIR, { recursive: true });
197
+ }
198
+ if (!fs.existsSync(userDataDir)) {
199
+ fs.mkdirSync(userDataDir, { recursive: true });
200
+ }
201
+ // 优先尝试连接已有的 Chrome 实例(用户日常使用的浏览器)
202
+ // 需要用户以以下命令启动 Chrome:
203
+ // "C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222
204
+ try {
205
+ console.error('尝试连接到已有的 Chrome 实例 (端口 9222)...');
206
+ browser = await puppeteer_1.default.connect({
207
+ browserURL: `http://127.0.0.1:${debuggingPort}`,
208
+ defaultViewport: null
209
+ });
210
+ useExistingBrowser = true;
211
+ console.error('成功连接到已有的 Chrome 实例!');
212
+ }
213
+ catch (connectError) {
214
+ console.error('无法连接到已有 Chrome 实例,将启动独立实例...');
215
+ console.error('提示:如需使用日常浏览器的书签和登录状态,请先用以下命令启动 Chrome:');
216
+ console.error(` "${chromePath}" --remote-debugging-port=${debuggingPort}`);
217
+ }
218
+ // 如果连接失败,启动独立的 Chrome 实例
219
+ if (!browser) {
220
+ try {
221
+ browser = await puppeteer_1.default.launch({
222
+ headless: false,
223
+ executablePath: fs.existsSync(chromePath) ? chromePath : undefined,
224
+ userDataDir: userDataDir,
225
+ args: [
226
+ '--no-sandbox',
227
+ '--disable-setuid-sandbox',
228
+ '--disable-dev-shm-usage',
229
+ '--disable-gpu'
230
+ ]
231
+ });
232
+ console.error('已启动独立的 Chrome 实例');
233
+ }
234
+ catch (launchError) {
235
+ console.error('Chrome 启动失败:', launchError.message);
236
+ return {
237
+ success: false,
238
+ error: `无法启动浏览器:${launchError.message}。请确保已安装 Google Chrome 浏览器。`
239
+ };
240
+ }
241
+ }
242
+ // 获取或创建页面
243
+ let page;
244
+ if (useExistingBrowser) {
245
+ // 连接到已有浏览器时,使用现有页面或新建
246
+ const pages = await browser.pages();
247
+ page = pages.length > 0 ? pages[0] : await browser.newPage();
248
+ }
249
+ else {
250
+ page = await browser.newPage();
251
+ }
252
+ // 设置较大的视口
253
+ await page.setViewport({ width: 1920, height: 1080 });
254
+ // 设置较大的视口
255
+ await page.setViewport({ width: 1920, height: 1080 });
256
+ console.error('正在访问 TAPD bug 页面...');
257
+ await page.goto(bugUrl, {
258
+ waitUntil: 'networkidle2',
259
+ timeout: 60000
260
+ });
261
+ // 检查是否需要登录
262
+ const loggedIn = await isLoggedIn(page);
263
+ if (!loggedIn) {
264
+ console.error('检测到未登录状态');
265
+ if (loginMode === 'auto') {
266
+ // 尝试加载保存的 Cookie
267
+ const cookies = await loadCookies();
268
+ if (cookies.length > 0) {
269
+ console.error('尝试使用保存的 Cookie 自动登录...');
270
+ await page.setCookie(...cookies);
271
+ await page.reload({ waitUntil: 'networkidle2', timeout: 60000 });
272
+ const stillNotLoggedIn = await isLoggedIn(page);
273
+ if (stillNotLoggedIn) {
274
+ console.error('Cookie 已过期,需要手动登录');
275
+ await saveCookies([]); // 清除过期的 Cookie
276
+ return {
277
+ success: false,
278
+ error: 'Cookie 已过期,需要手动登录。请使用 loginMode: "manual" 重新调用此工具。',
279
+ loginRequired: true
280
+ };
281
+ }
282
+ }
283
+ else {
284
+ return {
285
+ success: false,
286
+ error: '需要登录才能访问 TAPD bug 页面。请使用 loginMode: "manual" 重新调用此工具,在浏览器中完成登录后,Cookie 会被保存。',
287
+ loginRequired: true
288
+ };
289
+ }
290
+ }
291
+ if (loginMode === 'manual' || !loggedIn) {
292
+ console.error('请在打开的浏览器中完成 TAPD 登录...');
293
+ console.error('登录完成后,系统将自动保存 Cookie 以便下次使用。');
294
+ // 等待用户登录(最长等待 5 分钟)
295
+ let attempts = 0;
296
+ const maxAttempts = 60; // 5 分钟
297
+ while (attempts < maxAttempts) {
298
+ await new Promise(resolve => setTimeout(resolve, 5000)); // 每 5 秒检查一次
299
+ const nowLoggedIn = await isLoggedIn(page);
300
+ if (nowLoggedIn) {
301
+ console.error('检测到登录成功!');
302
+ break;
303
+ }
304
+ attempts++;
305
+ console.error(`等待登录中... (${attempts * 5 / 60}分钟)`);
306
+ }
307
+ // 保存 Cookie
308
+ const cookies = await page.cookies();
309
+ await saveCookies(cookies);
310
+ // 重新加载页面以应用登录状态
311
+ await page.reload({ waitUntil: 'networkidle2', timeout: 60000 });
312
+ }
313
+ }
314
+ // 再次检查登录状态
315
+ const finalLoggedIn = await isLoggedIn(page);
316
+ if (!finalLoggedIn) {
317
+ return {
318
+ success: false,
319
+ error: '登录失败或 Cookie 无效',
320
+ loginRequired: true
321
+ };
322
+ }
323
+ // 提取 bug 详情内容
324
+ console.error(`正在提取 bug 详情内容... (选择器: ${contentSelector})`);
325
+ const bugContent = await extractBugContent(page, contentSelector);
326
+ // 下载并分析图片
327
+ const downloadedImages = [];
328
+ if (bugContent.images.length > 0) {
329
+ console.error(`找到 ${bugContent.images.length} 张图片,开始下载...`);
330
+ // 获取当前页面的 Cookie
331
+ const cookies = await page.cookies();
332
+ // 下载所有图片
333
+ for (const imageUrl of bugContent.images) {
334
+ const downloadedImage = await downloadAndConvertImage(imageUrl, cookies);
335
+ if (downloadedImage) {
336
+ downloadedImages.push(downloadedImage);
337
+ // 分析图片内容
338
+ const analysis = await analyzeImage(downloadedImage.base64, downloadedImage.originalUrl);
339
+ console.error(`图片分析结果:${analysis}`);
340
+ }
341
+ }
342
+ console.error(`成功下载 ${downloadedImages.length} 张图片`);
343
+ }
344
+ return {
345
+ success: true,
346
+ content: {
347
+ ...bugContent,
348
+ downloadedImages
349
+ }
350
+ };
351
+ }
352
+ catch (error) {
353
+ console.error('获取 bug 详情失败:', error);
354
+ return {
355
+ success: false,
356
+ error: error.message || '未知错误'
357
+ };
358
+ }
359
+ finally {
360
+ if (browser) {
361
+ if (useExistingBrowser) {
362
+ // 连接模式:断开连接,不关闭浏览器
363
+ browser.disconnect();
364
+ console.error('已断开与 Chrome 的连接');
365
+ }
366
+ else {
367
+ // 独立模式:保持浏览器打开,只关闭页面
368
+ const pages = await browser.pages();
369
+ if (pages.length > 0) {
370
+ await pages[pages.length - 1].close();
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ //# sourceMappingURL=tapd-bug-fetcher.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tapd-bug-fetcher.js","sourceRoot":"","sources":["../../src/tools/tapd-bug-fetcher.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { TypeInputResult } from '../types/index.js';
2
+ export declare function typeInputElement(url: string, selector: string, text: string, clearFirst?: boolean, pressEnter?: boolean, useExistingPage?: boolean): Promise<TypeInputResult>;
3
+ //# sourceMappingURL=type-input.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-input.d.ts","sourceRoot":"","sources":["../../src/tools/type-input.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAIpD,wBAAsB,gBAAgB,CACpC,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,EACZ,UAAU,GAAE,OAAc,EAC1B,UAAU,GAAE,OAAe,EAC3B,eAAe,GAAE,OAAc,GAC9B,OAAO,CAAC,eAAe,CAAC,CAiH1B"}
@@ -0,0 +1,97 @@
1
+ import { getBrowser, getPage, closeBrowser } from '../utils/browser.js';
2
+ // 在输入框中输入内容
3
+ export async function typeInputElement(url, selector, text, clearFirst = true, pressEnter = false, useExistingPage = true) {
4
+ let browserConnection = null;
5
+ try {
6
+ // 获取浏览器实例
7
+ browserConnection = await getBrowser();
8
+ const { browser, useExistingBrowser } = browserConnection;
9
+ // 获取页面
10
+ const page = await getPage(browser, useExistingBrowser, useExistingPage ? 'current' : url);
11
+ // 如果需要导航到指定 URL
12
+ if (!useExistingPage && url !== 'current') {
13
+ await page.goto(url, { waitUntil: 'networkidle2', timeout: 60000 });
14
+ }
15
+ console.error(`正在查找元素: ${selector}`);
16
+ // 等待元素出现
17
+ await page.waitForSelector(selector, { timeout: 10000 });
18
+ // 获取元素信息并输入内容
19
+ const elementInfo = await page.evaluate((sel) => {
20
+ const element = document.querySelector(sel);
21
+ if (!element) {
22
+ return null;
23
+ }
24
+ // 获取元素信息
25
+ return {
26
+ tagName: element.tagName.toLowerCase(),
27
+ type: element.getAttribute('type') || undefined,
28
+ name: element.getAttribute('name') || undefined,
29
+ id: element.id || undefined,
30
+ className: element.className || undefined,
31
+ placeholder: element.getAttribute('placeholder') || undefined,
32
+ value: element.value || undefined
33
+ };
34
+ }, selector);
35
+ if (!elementInfo) {
36
+ await closeBrowser(browser, useExistingBrowser, true);
37
+ return {
38
+ success: false,
39
+ error: `未找到元素: ${selector}`
40
+ };
41
+ }
42
+ // 聚焦元素
43
+ await page.focus(selector);
44
+ // 如果需要,先清空输入框
45
+ if (clearFirst) {
46
+ await page.evaluate((sel) => {
47
+ const element = document.querySelector(sel);
48
+ if (element) {
49
+ element.value = '';
50
+ element.dispatchEvent(new Event('input', { bubbles: true }));
51
+ element.dispatchEvent(new Event('change', { bubbles: true }));
52
+ }
53
+ }, selector);
54
+ // 使用键盘快捷键清空
55
+ await page.keyboard.down('Control');
56
+ await page.keyboard.down('a');
57
+ await page.keyboard.up('a');
58
+ await page.keyboard.up('Control');
59
+ await page.keyboard.press('Delete');
60
+ }
61
+ // 输入文本
62
+ await page.keyboard.type(text, { delay: 10 });
63
+ console.error(`成功输入内容: ${text}`);
64
+ // 如果需要按回车
65
+ if (pressEnter) {
66
+ await page.keyboard.press('Enter');
67
+ console.error('已按下回车键');
68
+ }
69
+ // 获取输入后的值
70
+ const finalValue = await page.evaluate((sel) => {
71
+ const element = document.querySelector(sel);
72
+ return element ? element.value : null;
73
+ }, selector);
74
+ // 保持浏览器打开
75
+ await closeBrowser(browser, useExistingBrowser, true);
76
+ return {
77
+ success: true,
78
+ elementInfo: {
79
+ ...elementInfo,
80
+ value: finalValue || text
81
+ }
82
+ };
83
+ }
84
+ catch (error) {
85
+ console.error('输入内容失败:', error);
86
+ // 发生错误时保持浏览器打开
87
+ if (browserConnection) {
88
+ const { browser, useExistingBrowser } = browserConnection;
89
+ await closeBrowser(browser, useExistingBrowser, true);
90
+ }
91
+ return {
92
+ success: false,
93
+ error: error.message || '未知错误'
94
+ };
95
+ }
96
+ }
97
+ //# sourceMappingURL=type-input.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-input.js","sourceRoot":"","sources":["../../src/tools/type-input.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function handleClick(selector: string): void;
2
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/tools/utils/utils.ts"],"names":[],"mappings":"AACA,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,QAC3C"}
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.handleClick = handleClick;
4
+ // 点击按钮函数,参数是类名或者id
5
+ function handleClick(selector) {
6
+ }
7
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../../src/tools/utils/utils.ts"],"names":[],"mappings":";;AACA,kCACC;AAFD,mBAAmB;AACnB,SAAgB,WAAW,CAAC,QAAgB;AAC5C,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { FetchPageResult } from '../types/index.js';
2
+ export declare function fetchWebPage(url: string, contentSelector?: string, downloadImages?: boolean, loginMode?: 'auto' | 'manual' | 'skip', waitForLogin?: boolean): Promise<FetchPageResult>;
3
+ //# sourceMappingURL=web-page-fetcher.d.ts.map