chrome-devtools-mcp-for-extension 0.9.20 → 0.9.22
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/build/src/tools/chatgpt-web.js +117 -13
- package/package.json +1 -1
|
@@ -114,9 +114,15 @@ export const askChatGPTWeb = defineTool({
|
|
|
114
114
|
.boolean()
|
|
115
115
|
.optional()
|
|
116
116
|
.describe('Force creation of a new chat instead of reusing existing project chat. Default: false'),
|
|
117
|
+
useDeepResearch: z
|
|
118
|
+
.boolean()
|
|
119
|
+
.optional()
|
|
120
|
+
.describe('Enable DeepResearch mode for complex research tasks requiring comprehensive analysis. ' +
|
|
121
|
+
'Use when the question involves market research, comparative analysis, trend analysis, ' +
|
|
122
|
+
'or requires gathering information from multiple sources. Default: false'),
|
|
117
123
|
},
|
|
118
124
|
handler: async (request, response, context) => {
|
|
119
|
-
const { question, projectName, createNewChat = false } = request.params;
|
|
125
|
+
const { question, projectName, createNewChat = false, useDeepResearch = false } = request.params;
|
|
120
126
|
// Sanitize question
|
|
121
127
|
const sanitizedQuestion = sanitizeQuestion(question);
|
|
122
128
|
// Determine project name
|
|
@@ -184,6 +190,45 @@ export const askChatGPTWeb = defineTool({
|
|
|
184
190
|
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
185
191
|
}
|
|
186
192
|
}
|
|
193
|
+
// Step 3.5: Enable DeepResearch mode if requested
|
|
194
|
+
if (useDeepResearch) {
|
|
195
|
+
response.appendResponseLine('DeepResearchモードを有効化中...');
|
|
196
|
+
// Click the "+" button to open tools menu
|
|
197
|
+
const menuOpened = await page.evaluate(() => {
|
|
198
|
+
const buttons = Array.from(document.querySelectorAll('button'));
|
|
199
|
+
const plusButton = buttons.find((btn) => {
|
|
200
|
+
const aria = btn.getAttribute('aria-label') || '';
|
|
201
|
+
const desc = btn.getAttribute('description') || '';
|
|
202
|
+
return (aria.includes('ファイルの追加') ||
|
|
203
|
+
desc.includes('ファイルの追加'));
|
|
204
|
+
});
|
|
205
|
+
if (plusButton) {
|
|
206
|
+
plusButton.click();
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
return false;
|
|
210
|
+
});
|
|
211
|
+
if (menuOpened) {
|
|
212
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
213
|
+
// Click "Deep Research" menu item
|
|
214
|
+
const deepResearchEnabled = await page.evaluate(() => {
|
|
215
|
+
const menuItems = Array.from(document.querySelectorAll('[role="menuitemradio"]'));
|
|
216
|
+
const deepResearchItem = menuItems.find((item) => item.textContent?.includes('Deep Research'));
|
|
217
|
+
if (deepResearchItem) {
|
|
218
|
+
deepResearchItem.click();
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
221
|
+
return false;
|
|
222
|
+
});
|
|
223
|
+
if (deepResearchEnabled) {
|
|
224
|
+
response.appendResponseLine('✅ DeepResearchモード有効化完了');
|
|
225
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
response.appendResponseLine('⚠️ DeepResearchオプションが見つかりませんでした');
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}
|
|
187
232
|
// Step 4: Send question
|
|
188
233
|
response.appendResponseLine('質問を送信中...');
|
|
189
234
|
const questionSent = await page.evaluate((questionText) => {
|
|
@@ -221,17 +266,64 @@ export const askChatGPTWeb = defineTool({
|
|
|
221
266
|
return messages.length > 0;
|
|
222
267
|
}, { timeout: 10000 });
|
|
223
268
|
response.appendResponseLine('✅ 質問送信完了');
|
|
224
|
-
// Step 5: Monitor streaming with progress updates
|
|
225
|
-
|
|
269
|
+
// Step 5: Monitor streaming/research with progress updates
|
|
270
|
+
if (useDeepResearch) {
|
|
271
|
+
response.appendResponseLine('DeepResearchを実行中... (10秒ごとに進捗を表示)');
|
|
272
|
+
}
|
|
273
|
+
else {
|
|
274
|
+
response.appendResponseLine('ChatGPTの回答を待機中... (10秒ごとに進捗を表示)');
|
|
275
|
+
}
|
|
226
276
|
const startTime = Date.now();
|
|
227
277
|
let lastText = '';
|
|
278
|
+
let lastProgress = '';
|
|
228
279
|
while (true) {
|
|
229
280
|
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
230
|
-
const status = await page.evaluate(() => {
|
|
231
|
-
//
|
|
281
|
+
const status = await page.evaluate((isDeepResearch) => {
|
|
282
|
+
// DeepResearch progress detection
|
|
283
|
+
if (isDeepResearch) {
|
|
284
|
+
// Look for research progress indicators
|
|
285
|
+
const progressElements = Array.from(document.querySelectorAll('[role="status"], [aria-live="polite"]'));
|
|
286
|
+
const progressText = progressElements
|
|
287
|
+
.map((el) => el.textContent)
|
|
288
|
+
.join(' ');
|
|
289
|
+
// Check if DeepResearch is still running
|
|
290
|
+
const buttons = Array.from(document.querySelectorAll('button'));
|
|
291
|
+
const isRunning = buttons.some((btn) => {
|
|
292
|
+
const text = btn.textContent || '';
|
|
293
|
+
const aria = btn.getAttribute('aria-label') || '';
|
|
294
|
+
return (text.includes('停止') ||
|
|
295
|
+
text.includes('リサーチを停止') ||
|
|
296
|
+
aria.includes('停止'));
|
|
297
|
+
});
|
|
298
|
+
if (!isRunning) {
|
|
299
|
+
// Research completed - get the report
|
|
300
|
+
const assistantMessages = document.querySelectorAll('[data-message-author-role="assistant"]');
|
|
301
|
+
if (assistantMessages.length === 0)
|
|
302
|
+
return { completed: false, progress: progressText };
|
|
303
|
+
const latestMessage = assistantMessages[assistantMessages.length - 1];
|
|
304
|
+
return {
|
|
305
|
+
completed: true,
|
|
306
|
+
text: latestMessage.textContent || '',
|
|
307
|
+
isDeepResearch: true,
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
completed: false,
|
|
312
|
+
streaming: true,
|
|
313
|
+
progress: progressText,
|
|
314
|
+
currentText: progressText.substring(0, 200),
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
// Normal streaming detection
|
|
232
318
|
const buttons = Array.from(document.querySelectorAll('button'));
|
|
233
|
-
const isStreaming = buttons.some((btn) =>
|
|
234
|
-
btn.textContent
|
|
319
|
+
const isStreaming = buttons.some((btn) => {
|
|
320
|
+
const text = btn.textContent || '';
|
|
321
|
+
const aria = btn.getAttribute('aria-label') || '';
|
|
322
|
+
return (text.includes('ストリーミングの停止') ||
|
|
323
|
+
text.includes('停止') ||
|
|
324
|
+
aria.includes('ストリーミングの停止') ||
|
|
325
|
+
aria.includes('停止'));
|
|
326
|
+
});
|
|
235
327
|
if (!isStreaming) {
|
|
236
328
|
// Get final response
|
|
237
329
|
const assistantMessages = document.querySelectorAll('[data-message-author-role="assistant"]');
|
|
@@ -259,9 +351,12 @@ export const askChatGPTWeb = defineTool({
|
|
|
259
351
|
streaming: true,
|
|
260
352
|
currentText,
|
|
261
353
|
};
|
|
262
|
-
});
|
|
354
|
+
}, useDeepResearch);
|
|
263
355
|
if (status.completed) {
|
|
264
|
-
|
|
356
|
+
const completionMessage = useDeepResearch
|
|
357
|
+
? `\n✅ DeepResearch完了 (所要時間: ${Math.floor((Date.now() - startTime) / 1000)}秒)`
|
|
358
|
+
: `\n✅ 回答完了 (所要時間: ${Math.floor((Date.now() - startTime) / 1000)}秒)`;
|
|
359
|
+
response.appendResponseLine(completionMessage);
|
|
265
360
|
if (status.thinkingTime) {
|
|
266
361
|
response.appendResponseLine(`🤔 思考時間: ${status.thinkingTime}秒`);
|
|
267
362
|
}
|
|
@@ -300,10 +395,13 @@ export const askChatGPTWeb = defineTool({
|
|
|
300
395
|
}
|
|
301
396
|
// Save conversation log
|
|
302
397
|
const chatUrl = page.url();
|
|
398
|
+
const modelName = useDeepResearch
|
|
399
|
+
? 'ChatGPT DeepResearch'
|
|
400
|
+
: 'ChatGPT 5 Thinking';
|
|
303
401
|
const logPath = await saveConversationLog(project, sanitizedQuestion, status.text || '', {
|
|
304
402
|
thinkingTime: status.thinkingTime,
|
|
305
403
|
chatUrl,
|
|
306
|
-
model:
|
|
404
|
+
model: modelName,
|
|
307
405
|
});
|
|
308
406
|
response.appendResponseLine(`📝 会話ログ保存: ${logPath}`);
|
|
309
407
|
response.appendResponseLine(`🔗 チャットURL: ${chatUrl}`);
|
|
@@ -314,9 +412,15 @@ export const askChatGPTWeb = defineTool({
|
|
|
314
412
|
}
|
|
315
413
|
// Show progress every 10 seconds
|
|
316
414
|
const elapsedSeconds = Math.floor((Date.now() - startTime) / 1000);
|
|
317
|
-
if (elapsedSeconds % 10 === 0
|
|
318
|
-
|
|
319
|
-
|
|
415
|
+
if (elapsedSeconds % 10 === 0) {
|
|
416
|
+
if (useDeepResearch && status.progress !== lastProgress) {
|
|
417
|
+
lastProgress = status.progress || '';
|
|
418
|
+
response.appendResponseLine(`⏱️ ${elapsedSeconds}秒経過 - 進捗: ${lastProgress.substring(0, 100)}...`);
|
|
419
|
+
}
|
|
420
|
+
else if (status.currentText !== lastText) {
|
|
421
|
+
lastText = status.currentText || '';
|
|
422
|
+
response.appendResponseLine(`⏱️ ${elapsedSeconds}秒経過 - 現在のテキスト: ${lastText.substring(0, 100)}...`);
|
|
423
|
+
}
|
|
320
424
|
}
|
|
321
425
|
}
|
|
322
426
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "chrome-devtools-mcp-for-extension",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.22",
|
|
4
4
|
"description": "MCP server for Chrome extension development with Web Store automation. Fork of chrome-devtools-mcp with extension-specific tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": "./build/src/index.js",
|