chrome-devtools-mcp-for-extension 0.9.23 → 0.9.25
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/index.js
CHANGED
|
File without changes
|
|
@@ -222,14 +222,62 @@ export const askChatGPTWeb = defineTool({
|
|
|
222
222
|
});
|
|
223
223
|
if (deepResearchEnabled) {
|
|
224
224
|
response.appendResponseLine('✅ DeepResearchモード有効化完了');
|
|
225
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
225
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
226
|
+
// Verify mode was actually enabled (check for composer-pill button)
|
|
227
|
+
const verified = await page.evaluate(() => {
|
|
228
|
+
const DEEP_RESEARCH_PATTERN = /リサーチ|deep\s*research|ディープ\s*リサーチ|深度研究|深入研究/i;
|
|
229
|
+
const promptTextarea = document.querySelector('#prompt-textarea');
|
|
230
|
+
if (promptTextarea) {
|
|
231
|
+
const form = promptTextarea.closest('form');
|
|
232
|
+
if (form) {
|
|
233
|
+
const pillButton = Array.from(form.querySelectorAll('button')).find((btn) => {
|
|
234
|
+
const text = btn.textContent?.trim() || '';
|
|
235
|
+
const ariaLabel = btn.getAttribute('aria-label') || '';
|
|
236
|
+
return (btn.className.includes('composer-pill') &&
|
|
237
|
+
DEEP_RESEARCH_PATTERN.test(text + ' ' + ariaLabel));
|
|
238
|
+
});
|
|
239
|
+
return !!pillButton;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return false;
|
|
243
|
+
});
|
|
244
|
+
if (verified) {
|
|
245
|
+
response.appendResponseLine('✅ モード確認完了: DeepResearch有効(composer-pill検出)');
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
response.appendResponseLine('⚠️ DeepResearchモードの確認に失敗しました');
|
|
249
|
+
}
|
|
226
250
|
}
|
|
227
251
|
else {
|
|
228
252
|
response.appendResponseLine('⚠️ DeepResearchオプションが見つかりませんでした');
|
|
229
253
|
}
|
|
230
254
|
}
|
|
231
255
|
}
|
|
232
|
-
// Step 4: Send question
|
|
256
|
+
// Step 4: Send question (with final mode verification)
|
|
257
|
+
if (useDeepResearch) {
|
|
258
|
+
const finalCheck = await page.evaluate(() => {
|
|
259
|
+
const DEEP_RESEARCH_PATTERN = /リサーチ|deep\s*research|ディープ\s*リサーチ|深度研究|深入研究/i;
|
|
260
|
+
const promptTextarea = document.querySelector('#prompt-textarea');
|
|
261
|
+
if (promptTextarea) {
|
|
262
|
+
const form = promptTextarea.closest('form');
|
|
263
|
+
if (form) {
|
|
264
|
+
const pillButton = Array.from(form.querySelectorAll('button')).find((btn) => {
|
|
265
|
+
const text = btn.textContent?.trim() || '';
|
|
266
|
+
const ariaLabel = btn.getAttribute('aria-label') || '';
|
|
267
|
+
return (btn.className.includes('composer-pill') &&
|
|
268
|
+
DEEP_RESEARCH_PATTERN.test(text + ' ' + ariaLabel));
|
|
269
|
+
});
|
|
270
|
+
return !!pillButton;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
return false;
|
|
274
|
+
});
|
|
275
|
+
if (!finalCheck) {
|
|
276
|
+
response.appendResponseLine('❌ エラー: DeepResearchモードが無効です(composer-pill未検出)。送信を中止します。');
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
response.appendResponseLine('✅ 送信前確認: DeepResearchモード有効(composer-pill検出)');
|
|
280
|
+
}
|
|
233
281
|
response.appendResponseLine('質問を送信中...');
|
|
234
282
|
const questionSent = await page.evaluate((questionText) => {
|
|
235
283
|
const prosemirror = document.querySelector('.ProseMirror[contenteditable="true"]');
|
|
@@ -128,38 +128,88 @@ function isCodeRelatedQuestion(question) {
|
|
|
128
128
|
*/
|
|
129
129
|
async function detectDeepResearchMode(page) {
|
|
130
130
|
return await page.evaluate(() => {
|
|
131
|
-
//
|
|
132
|
-
const
|
|
133
|
-
//
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
131
|
+
// Multi-language patterns for DeepResearch
|
|
132
|
+
const DEEP_RESEARCH_PATTERN = /リサーチ|deep\s*research|ディープ\s*リサーチ|深度研究|深入研究/i;
|
|
133
|
+
// Step 1: Check for the "リサーチ" pill button near prompt (MOST RELIABLE)
|
|
134
|
+
// When DeepResearch is ON, a pill button appears in the composer form
|
|
135
|
+
const promptTextarea = document.querySelector('#prompt-textarea');
|
|
136
|
+
if (promptTextarea) {
|
|
137
|
+
const form = promptTextarea.closest('form');
|
|
138
|
+
if (form) {
|
|
139
|
+
const pillButton = Array.from(form.querySelectorAll('button')).find((btn) => {
|
|
140
|
+
const text = btn.textContent?.trim() || '';
|
|
141
|
+
const ariaLabel = btn.getAttribute('aria-label') || '';
|
|
142
|
+
// Check for pill button with research text
|
|
143
|
+
return (btn.className.includes('composer-pill') &&
|
|
144
|
+
DEEP_RESEARCH_PATTERN.test(text + ' ' + ariaLabel));
|
|
145
|
+
});
|
|
146
|
+
if (pillButton) {
|
|
147
|
+
const text = pillButton.textContent?.trim() || '';
|
|
148
|
+
return {
|
|
149
|
+
isEnabled: true,
|
|
150
|
+
indicator: `composer-pill: "${text}"`,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
148
154
|
}
|
|
149
|
-
//
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
155
|
+
// Step 2: Try data-testid selectors
|
|
156
|
+
const dataTestIdSelectors = [
|
|
157
|
+
'[data-testid*="deep-research"]',
|
|
158
|
+
'[data-testid*="deepresearch"]',
|
|
159
|
+
'[data-testid*="research-mode"]',
|
|
160
|
+
];
|
|
161
|
+
for (const selector of dataTestIdSelectors) {
|
|
162
|
+
const element = document.querySelector(selector);
|
|
163
|
+
if (element) {
|
|
164
|
+
return {
|
|
165
|
+
isEnabled: true,
|
|
166
|
+
indicator: `data-testid: ${element.getAttribute('data-testid')}`,
|
|
167
|
+
};
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
// Step 3: Try aria-* attributes SECOND
|
|
171
|
+
const ariaSelectors = [
|
|
172
|
+
'[aria-label*="Deep Research" i]',
|
|
173
|
+
'[aria-label*="ディープリサーチ" i]',
|
|
174
|
+
'[aria-checked="true"][role="menuitemradio"]',
|
|
175
|
+
];
|
|
176
|
+
for (const selector of ariaSelectors) {
|
|
177
|
+
const elements = Array.from(document.querySelectorAll(selector));
|
|
178
|
+
for (const element of elements) {
|
|
179
|
+
const ariaLabel = element.getAttribute('aria-label') || '';
|
|
180
|
+
const role = element.getAttribute('role') || '';
|
|
181
|
+
// Check aria-label with pattern
|
|
182
|
+
if (DEEP_RESEARCH_PATTERN.test(ariaLabel)) {
|
|
183
|
+
return {
|
|
184
|
+
isEnabled: true,
|
|
185
|
+
indicator: `aria-label: ${ariaLabel.substring(0, 50)}`,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
// Check menuitemradio with aria-checked
|
|
189
|
+
if (role === 'menuitemradio') {
|
|
190
|
+
const isChecked = element.getAttribute('aria-checked') === 'true';
|
|
191
|
+
const text = element.textContent || '';
|
|
192
|
+
if (isChecked && DEEP_RESEARCH_PATTERN.test(text)) {
|
|
193
|
+
return {
|
|
194
|
+
isEnabled: true,
|
|
195
|
+
indicator: 'menuitemradio (checked)',
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
// Step 4: Text matching as LAST resort (least reliable)
|
|
202
|
+
const textElements = Array.from(document.querySelectorAll('div, span, button'));
|
|
203
|
+
for (const element of textElements) {
|
|
204
|
+
const text = element.textContent || '';
|
|
205
|
+
if (DEEP_RESEARCH_PATTERN.test(text)) {
|
|
206
|
+
return {
|
|
207
|
+
isEnabled: true,
|
|
208
|
+
indicator: `text match: ${text.substring(0, 50).trim()}`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
return { isEnabled: false };
|
|
163
213
|
});
|
|
164
214
|
}
|
|
165
215
|
/**
|
|
@@ -203,7 +253,16 @@ async function enableDeepResearchMode(page, response) {
|
|
|
203
253
|
return { success: false, error: deepResearchSelected.error };
|
|
204
254
|
}
|
|
205
255
|
response.appendResponseLine('✅ DeepResearchモード有効化');
|
|
206
|
-
await new Promise((resolve) => setTimeout(resolve,
|
|
256
|
+
await new Promise((resolve) => setTimeout(resolve, 1000));
|
|
257
|
+
// Verify mode was actually enabled
|
|
258
|
+
const verification = await detectDeepResearchMode(page);
|
|
259
|
+
if (!verification.isEnabled) {
|
|
260
|
+
return {
|
|
261
|
+
success: false,
|
|
262
|
+
error: 'DeepResearchモードの有効化に失敗しました(確認できませんでした)',
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
response.appendResponseLine(`✅ モード確認完了: DeepResearch有効 (${verification.indicator})`);
|
|
207
266
|
return { success: true };
|
|
208
267
|
}
|
|
209
268
|
catch (error) {
|
|
@@ -265,6 +324,15 @@ async function configureSources(page, response, enableGitHub) {
|
|
|
265
324
|
* Send question text and click send button
|
|
266
325
|
*/
|
|
267
326
|
async function sendQuestion(page, response, question) {
|
|
327
|
+
// Final verification before sending
|
|
328
|
+
const finalCheck = await detectDeepResearchMode(page);
|
|
329
|
+
if (!finalCheck.isEnabled) {
|
|
330
|
+
return {
|
|
331
|
+
success: false,
|
|
332
|
+
error: 'DeepResearchモードが無効です。送信前の最終確認に失敗しました。',
|
|
333
|
+
};
|
|
334
|
+
}
|
|
335
|
+
response.appendResponseLine(`✅ 送信前確認: DeepResearchモード有効 (${finalCheck.indicator})`);
|
|
268
336
|
response.appendResponseLine('リサーチテーマを送信中...');
|
|
269
337
|
const questionSent = await page.evaluate((questionText) => {
|
|
270
338
|
const prosemirror = document.querySelector('.ProseMirror[contenteditable="true"]');
|
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.25",
|
|
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",
|