chrome-devtools-mcp-for-extension 0.9.23 → 0.9.24
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
|
|
@@ -128,38 +128,96 @@ function isCodeRelatedQuestion(question) {
|
|
|
128
128
|
*/
|
|
129
129
|
async function detectDeepResearchMode(page) {
|
|
130
130
|
return await page.evaluate(() => {
|
|
131
|
-
//
|
|
132
|
-
const
|
|
133
|
-
//
|
|
134
|
-
const
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
131
|
+
// Multi-language patterns for DeepResearch
|
|
132
|
+
const DEEP_RESEARCH_PATTERN = /deep\s*research|ディープ\s*リサーチ|深度研究|深入研究/i;
|
|
133
|
+
// Cache for performance (simple object-based cache instead of WeakRef for browser compatibility)
|
|
134
|
+
const cache = { timestamp: 0 };
|
|
135
|
+
const CACHE_TTL = 2000; // 2 seconds
|
|
136
|
+
// Step 1: Find scoped root element first
|
|
137
|
+
const findScopedRoot = () => {
|
|
138
|
+
// Try conversation root selectors
|
|
139
|
+
const candidates = [
|
|
140
|
+
document.querySelector('[data-testid="conversation-turns"]'),
|
|
141
|
+
document.querySelector('[role="main"]'),
|
|
142
|
+
document.querySelector('main'),
|
|
143
|
+
document.querySelector('[data-testid="conversation-root"]'),
|
|
144
|
+
];
|
|
145
|
+
return candidates.find((el) => el !== null) || document.body;
|
|
146
|
+
};
|
|
147
|
+
const scopedRoot = findScopedRoot();
|
|
148
|
+
if (!scopedRoot) {
|
|
149
|
+
return { isEnabled: false };
|
|
150
|
+
}
|
|
151
|
+
// Step 2: Try data-testid selectors FIRST (most reliable)
|
|
152
|
+
const dataTestIdSelectors = [
|
|
153
|
+
'[data-testid*="deep-research"]',
|
|
154
|
+
'[data-testid*="deepresearch"]',
|
|
155
|
+
'[data-testid*="research-mode"]',
|
|
156
|
+
];
|
|
157
|
+
for (const selector of dataTestIdSelectors) {
|
|
158
|
+
const element = scopedRoot.querySelector(selector);
|
|
159
|
+
if (element) {
|
|
160
|
+
return {
|
|
161
|
+
isEnabled: true,
|
|
162
|
+
indicator: `data-testid: ${element.getAttribute('data-testid')}`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
// Step 3: Try aria-* attributes SECOND
|
|
167
|
+
const ariaSelectors = [
|
|
168
|
+
'[aria-label*="Deep Research" i]',
|
|
169
|
+
'[aria-label*="ディープリサーチ" i]',
|
|
170
|
+
'[aria-checked="true"][role="menuitemradio"]',
|
|
171
|
+
];
|
|
172
|
+
for (const selector of ariaSelectors) {
|
|
173
|
+
const elements = Array.from(scopedRoot.querySelectorAll(selector));
|
|
174
|
+
for (const element of elements) {
|
|
175
|
+
const ariaLabel = element.getAttribute('aria-label') || '';
|
|
176
|
+
const role = element.getAttribute('role') || '';
|
|
177
|
+
// Check aria-label with pattern
|
|
178
|
+
if (DEEP_RESEARCH_PATTERN.test(ariaLabel)) {
|
|
179
|
+
return {
|
|
180
|
+
isEnabled: true,
|
|
181
|
+
indicator: `aria-label: ${ariaLabel.substring(0, 50)}`,
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
// Check menuitemradio with aria-checked
|
|
185
|
+
if (role === 'menuitemradio') {
|
|
186
|
+
const isChecked = element.getAttribute('aria-checked') === 'true';
|
|
187
|
+
const text = element.textContent || '';
|
|
188
|
+
if (isChecked && DEEP_RESEARCH_PATTERN.test(text)) {
|
|
189
|
+
return {
|
|
190
|
+
isEnabled: true,
|
|
191
|
+
indicator: 'menuitemradio (checked)',
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Step 4: Text matching as LAST resort (least reliable)
|
|
198
|
+
// Use cached result if available and fresh
|
|
199
|
+
const now = Date.now();
|
|
200
|
+
if (cache.element && now - cache.timestamp < CACHE_TTL) {
|
|
143
201
|
return {
|
|
144
202
|
isEnabled: true,
|
|
145
|
-
indicator:
|
|
146
|
-
'DeepResearch',
|
|
203
|
+
indicator: 'cached indicator',
|
|
147
204
|
};
|
|
148
205
|
}
|
|
149
|
-
//
|
|
150
|
-
const
|
|
151
|
-
const
|
|
152
|
-
const text =
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
206
|
+
// Search within scoped root only, not entire document
|
|
207
|
+
const textElements = Array.from(scopedRoot.querySelectorAll('div, span, button'));
|
|
208
|
+
for (const element of textElements) {
|
|
209
|
+
const text = element.textContent || '';
|
|
210
|
+
if (DEEP_RESEARCH_PATTERN.test(text)) {
|
|
211
|
+
// Update cache
|
|
212
|
+
cache.element = element;
|
|
213
|
+
cache.timestamp = now;
|
|
214
|
+
return {
|
|
215
|
+
isEnabled: true,
|
|
216
|
+
indicator: text.substring(0, 50),
|
|
217
|
+
};
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
return { isEnabled: false };
|
|
163
221
|
});
|
|
164
222
|
}
|
|
165
223
|
/**
|
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.24",
|
|
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",
|