aether-mcp-server 2.0.2 → 2.1.1

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.
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ /**
3
+ * Logging / debugging and diagnostic functions extracted from CdpBridge.
4
+ *
5
+ * These standalone functions accept a CdpClient (and optionally a Logger)
6
+ * and return results — no `this` state required.
7
+ */
8
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
9
+ if (k2 === undefined) k2 = k;
10
+ var desc = Object.getOwnPropertyDescriptor(m, k);
11
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
12
+ desc = { enumerable: true, get: function() { return m[k]; } };
13
+ }
14
+ Object.defineProperty(o, k2, desc);
15
+ }) : (function(o, m, k, k2) {
16
+ if (k2 === undefined) k2 = k;
17
+ o[k2] = m[k];
18
+ }));
19
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
20
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
21
+ }) : function(o, v) {
22
+ o["default"] = v;
23
+ });
24
+ var __importStar = (this && this.__importStar) || (function () {
25
+ var ownKeys = function(o) {
26
+ ownKeys = Object.getOwnPropertyNames || function (o) {
27
+ var ar = [];
28
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
29
+ return ar;
30
+ };
31
+ return ownKeys(o);
32
+ };
33
+ return function (mod) {
34
+ if (mod && mod.__esModule) return mod;
35
+ var result = {};
36
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
37
+ __setModuleDefault(result, mod);
38
+ return result;
39
+ };
40
+ })();
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.getLogs = getLogs;
43
+ exports.getNetworkErrors = getNetworkErrors;
44
+ exports.getNetworkTraffic = getNetworkTraffic;
45
+ exports.getNetworkResponse = getNetworkResponse;
46
+ exports.getPerformanceMetrics = getPerformanceMetrics;
47
+ exports.startTracing = startTracing;
48
+ exports.stopTracing = stopTracing;
49
+ exports.cdpCommand = cdpCommand;
50
+ exports.evaluate = evaluate;
51
+ exports.assertCondition = assertCondition;
52
+ exports.getDOMStorage = getDOMStorage;
53
+ const Eval = __importStar(require("../eval-scripts"));
54
+ // ─── getLogs ──────────────────────────────────────────────────────────
55
+ async function getLogs(client, params) {
56
+ const limit = Math.max(1, Math.min(Number(params.limit ?? 50), 100));
57
+ const logs = await client.getConsoleLogs(limit);
58
+ return { count: logs.length, logs };
59
+ }
60
+ // ─── getNetworkErrors ─────────────────────────────────────────────────
61
+ async function getNetworkErrors(client, params) {
62
+ const limit = Math.max(1, Math.min(Number(params.limit ?? 20), 100));
63
+ const errors = (await client.getNetworkTraffic())
64
+ .filter((entry) => entry.type === 'error' || entry.status >= 400)
65
+ .slice(-limit);
66
+ return { count: errors.length, errors };
67
+ }
68
+ // ─── getNetworkTraffic ────────────────────────────────────────────────
69
+ async function getNetworkTraffic(client, _params) {
70
+ return await client.getNetworkTraffic();
71
+ }
72
+ // ─── getNetworkResponse ───────────────────────────────────────────────
73
+ async function getNetworkResponse(client, params) {
74
+ const requestId = params.requestId;
75
+ if (!requestId)
76
+ throw new Error('requestId required');
77
+ const result = await client.sendCommand('Network.getResponseBody', {
78
+ requestId,
79
+ });
80
+ return result;
81
+ }
82
+ // ─── getPerformanceMetrics ────────────────────────────────────────────
83
+ async function getPerformanceMetrics(client, _params) {
84
+ await client.sendCommand('Performance.enable', {});
85
+ const result = await client.sendCommand('Performance.getMetrics', {});
86
+ return result.metrics;
87
+ }
88
+ // ─── startTracing ─────────────────────────────────────────────────────
89
+ async function startTracing(client, params) {
90
+ await client.sendCommand('Tracing.start', {
91
+ categories: params.categories || 'devtools.timeline',
92
+ });
93
+ return 'Started tracing';
94
+ }
95
+ // ─── stopTracing ──────────────────────────────────────────────────────
96
+ async function stopTracing(client) {
97
+ await client.sendCommand('Tracing.end', {});
98
+ return 'Stopped tracing';
99
+ }
100
+ // ─── cdpCommand ───────────────────────────────────────────────────────
101
+ async function cdpCommand(client, params) {
102
+ return await client.sendCommand(params.command, params.args || {});
103
+ }
104
+ // ─── evaluate ─────────────────────────────────────────────────────────
105
+ async function evaluate(client, params) {
106
+ return await client.evaluate(params.script);
107
+ }
108
+ // ─── assertCondition ──────────────────────────────────────────────────
109
+ // Uses Eval.makeAssertionScript to build the evaluation script, then
110
+ // executes it in the page context and returns the result.
111
+ async function assertCondition(client, params) {
112
+ const assertionType = params.assertionType || 'element_exists';
113
+ const selector = params.selector;
114
+ const expectedText = params.expectedText || params.value || '';
115
+ const script = Eval.makeAssertionScript(selector, assertionType, expectedText);
116
+ const result = await client.evaluate(script);
117
+ return result || { success: false, message: 'Assertion failed' };
118
+ }
119
+ // ─── getDOMStorage ────────────────────────────────────────────────────
120
+ async function getDOMStorage(client, params) {
121
+ await client.sendCommand('DOMStorage.enable', {});
122
+ const origin = params.origin ||
123
+ (await client
124
+ .evaluate('window.location.origin')
125
+ .catch(() => ''));
126
+ const result = await client.sendCommand('DOMStorage.getDOMStorageItems', {
127
+ storageId: {
128
+ securityOrigin: origin,
129
+ isLocalStorage: params.type !== 'session',
130
+ },
131
+ });
132
+ return result.entries || [];
133
+ }
@@ -0,0 +1,302 @@
1
+ "use strict";
2
+ /**
3
+ * State/Inspection functions extracted from CdpBridge.
4
+ *
5
+ * These operate as standalone functions that accept their dependencies
6
+ * (CdpClient, PageSnapshotCache, LocatorEngine) as explicit parameters
7
+ * rather than relying on `this` state.
8
+ */
9
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ var desc = Object.getOwnPropertyDescriptor(m, k);
12
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
13
+ desc = { enumerable: true, get: function() { return m[k]; } };
14
+ }
15
+ Object.defineProperty(o, k2, desc);
16
+ }) : (function(o, m, k, k2) {
17
+ if (k2 === undefined) k2 = k;
18
+ o[k2] = m[k];
19
+ }));
20
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
21
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
22
+ }) : function(o, v) {
23
+ o["default"] = v;
24
+ });
25
+ var __importStar = (this && this.__importStar) || (function () {
26
+ var ownKeys = function(o) {
27
+ ownKeys = Object.getOwnPropertyNames || function (o) {
28
+ var ar = [];
29
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
30
+ return ar;
31
+ };
32
+ return ownKeys(o);
33
+ };
34
+ return function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ })();
42
+ Object.defineProperty(exports, "__esModule", { value: true });
43
+ exports.browserStatus = browserStatus;
44
+ exports.snapshotCompact = snapshotCompact;
45
+ exports.listInteractiveElements = listInteractiveElements;
46
+ exports.getState = getState;
47
+ exports.pageSnapshot = pageSnapshot;
48
+ exports.getPageText = getPageText;
49
+ exports.getAccessibilityTree = getAccessibilityTree;
50
+ exports.getDOMTree = getDOMTree;
51
+ exports.getDomSnapshot = getDomSnapshot;
52
+ exports.highlightElements = highlightElements;
53
+ exports.verifyUIState = verifyUIState;
54
+ exports.getComputedStyle = getComputedStyle;
55
+ exports.getEventListeners = getEventListeners;
56
+ const Eval = __importStar(require("../eval-scripts"));
57
+ // ─── browserStatus ────────────────────────────────────────────────────
58
+ async function browserStatus(client, params) {
59
+ const connected = client.isConnected();
60
+ const activeTarget = client.getActiveTarget();
61
+ let targets;
62
+ if (connected && params.includeTargets) {
63
+ targets = await client.getTabs().catch(() => []);
64
+ }
65
+ return {
66
+ connected,
67
+ activeTarget: activeTarget
68
+ ? {
69
+ id: activeTarget.id,
70
+ type: activeTarget.type,
71
+ title: activeTarget.title,
72
+ url: activeTarget.url,
73
+ }
74
+ : null,
75
+ targets,
76
+ };
77
+ }
78
+ // ─── snapshotCompact ──────────────────────────────────────────────────
79
+ async function snapshotCompact(client, snapshotCache, params) {
80
+ return snapshotCache.compact({
81
+ maxElements: params.maxElements ?? 30,
82
+ includeText: params.includeText !== false,
83
+ });
84
+ }
85
+ // ─── listInteractiveElements ──────────────────────────────────────────
86
+ async function listInteractiveElements(client, snapshotCache, locator, params) {
87
+ const maxElements = Math.max(0, Math.min(Number(params.maxElements ?? 50), 200));
88
+ const snapshot = await snapshotCache.compact({
89
+ maxElements,
90
+ includeText: true,
91
+ withOverlay: !!params.withOverlay,
92
+ });
93
+ return {
94
+ count: snapshot.elements.length,
95
+ cache: snapshot.cache,
96
+ elements: snapshot.elements,
97
+ };
98
+ }
99
+ // ─── getState ─────────────────────────────────────────────────────────
100
+ // Comprehensive state: screenshot, domSnapshot, elements, SoM, tabs
101
+ async function getState(client, snapshotCache, locator, params) {
102
+ const includeScreenshot = params.screenshot === true;
103
+ const includeDomSnapshot = params.domSnapshot === true || params.includeDOMSnapshot === true;
104
+ const includeElements = params.elements !== false;
105
+ const includeSoM = params.som === true || params.withOverlay === true;
106
+ const includeTabs = params.tabs === true;
107
+ const includeAccessibilityTree = params.accessibilityTree !== false;
108
+ const compact = includeElements
109
+ ? await snapshotCache.compact({
110
+ maxElements: 200,
111
+ includeText: true,
112
+ withOverlay: includeSoM,
113
+ })
114
+ : await snapshotCache.compact({ maxElements: 0, includeText: false });
115
+ const [screenshot, domSnapshot, tabs, accessibilityTree] = await Promise.all([
116
+ includeScreenshot
117
+ ? client
118
+ .screenshot(params.format, params.quality)
119
+ .catch(() => null)
120
+ : Promise.resolve(null),
121
+ includeDomSnapshot
122
+ ? client.getDOMSnapshot().catch(() => null)
123
+ : Promise.resolve(null),
124
+ includeTabs
125
+ ? client.getTabs().catch(() => [])
126
+ : Promise.resolve([]),
127
+ includeAccessibilityTree
128
+ ? client.getRichAXTree().catch(() => null)
129
+ : Promise.resolve(null),
130
+ ]);
131
+ if (includeSoM) {
132
+ await client.removeSoMOverlay().catch(() => { });
133
+ }
134
+ return {
135
+ title: compact.title,
136
+ url: compact.url,
137
+ screenshot,
138
+ domSnapshot,
139
+ elements: includeElements ? compact.elements : [],
140
+ accessibilityTree,
141
+ somInjected: includeSoM,
142
+ cache: compact.cache,
143
+ tabs,
144
+ };
145
+ }
146
+ // ─── pageSnapshot ─────────────────────────────────────────────────────
147
+ // Full page capture: title, url, screenshot, elements, forms,
148
+ // cookies, accessibility tree
149
+ async function pageSnapshot(client, params) {
150
+ try {
151
+ const includeScreenshot = params.screenshot === true;
152
+ const includeCookies = params.cookies === true;
153
+ const includeAccessibilityTree = params.accessibilityTree === true;
154
+ const [title, url, screenshot, domSnapshot, elements, forms, cookies, axTree,] = await Promise.all([
155
+ client.evaluate("document.title").catch(() => "Unknown"),
156
+ client
157
+ .evaluate("window.location.href")
158
+ .catch(() => "Unknown"),
159
+ includeScreenshot
160
+ ? client
161
+ .screenshot(params.fullPage ? "jpeg" : "jpeg", 70)
162
+ .catch(() => null)
163
+ : Promise.resolve(null),
164
+ params.includeDOMSnapshot
165
+ ? client.getDOMSnapshot().catch(() => null)
166
+ : Promise.resolve(undefined),
167
+ client
168
+ .getInteractiveElements(false)
169
+ .catch(() => ({ elements: [] })),
170
+ client
171
+ .evaluate(Eval.COLLECT_FORMS_SCRIPT)
172
+ .catch(() => []),
173
+ includeCookies
174
+ ? client
175
+ .sendCommand("Network.getCookies", {})
176
+ .catch(() => ({ cookies: [] }))
177
+ : Promise.resolve({ cookies: [] }),
178
+ includeAccessibilityTree
179
+ ? client
180
+ .getRichAXTree()
181
+ .catch(() => null)
182
+ : Promise.resolve(null),
183
+ ]);
184
+ return {
185
+ title,
186
+ url,
187
+ screenshot,
188
+ elements: elements.elements,
189
+ accessibilityTree: axTree,
190
+ forms: forms || [],
191
+ cookies: cookies.cookies || [],
192
+ domSnapshot: params.includeDOMSnapshot ? domSnapshot : undefined,
193
+ metadata: {
194
+ timestamp: Date.now(),
195
+ elementCount: elements.elements.length,
196
+ },
197
+ };
198
+ }
199
+ catch (e) {
200
+ return { success: false, error: e.message };
201
+ }
202
+ }
203
+ // ─── getPageText ──────────────────────────────────────────────────────
204
+ // Eval.makeGetPageTextScript(format, selector, includeLinks)
205
+ // with maxLength truncation
206
+ async function getPageText(client, params) {
207
+ const format = params.format === "text" ? "text" : "markdown";
208
+ const selector = params.selector ? String(params.selector) : "";
209
+ const maxLength = Math.max(500, Math.min(Number(params.maxLength ?? 20000), 200000));
210
+ const includeLinks = params.includeLinks !== false;
211
+ const extracted = await client
212
+ .evaluate(Eval.makeGetPageTextScript(format, selector, includeLinks))
213
+ .catch((e) => ({
214
+ title: "",
215
+ url: "",
216
+ text: "",
217
+ error: e?.message,
218
+ }));
219
+ const text = String(extracted?.text ?? "");
220
+ const truncated = text.length > maxLength;
221
+ return {
222
+ title: extracted?.title ?? "",
223
+ url: extracted?.url ?? "",
224
+ format,
225
+ length: text.length,
226
+ truncated,
227
+ text: truncated
228
+ ? text.slice(0, maxLength) + "\n\n…[truncated]"
229
+ : text,
230
+ };
231
+ }
232
+ // ─── getAccessibilityTree ─────────────────────────────────────────────
233
+ // client.getRichAXTree()
234
+ async function getAccessibilityTree(client) {
235
+ return await client.getRichAXTree();
236
+ }
237
+ // ─── getDOMTree ───────────────────────────────────────────────────────
238
+ // client.getDOMSnapshot()
239
+ async function getDOMTree(client) {
240
+ const result = await client.getDOMSnapshot();
241
+ return result;
242
+ }
243
+ // ─── getDomSnapshot ───────────────────────────────────────────────────
244
+ // Same as getDOMTree — kept for backward compatibility
245
+ async function getDomSnapshot(client, params) {
246
+ return await client.getDOMSnapshot();
247
+ }
248
+ // ─── highlightElements ────────────────────────────────────────────────
249
+ // client.getInteractiveElements(true)
250
+ async function highlightElements(client) {
251
+ const result = await client.getInteractiveElements(true);
252
+ return {
253
+ success: true,
254
+ elements: result.elements,
255
+ message: `Highlighted ${result.elements.length} elements`,
256
+ };
257
+ }
258
+ // ─── verifyUIState ────────────────────────────────────────────────────
259
+ // Eval.makeVerifyUIScript(selector)
260
+ async function verifyUIState(client, params) {
261
+ const selector = params.selector;
262
+ const result = await client.evaluate(Eval.makeVerifyUIScript(selector));
263
+ return result || { exists: false, visible: false };
264
+ }
265
+ // ─── getComputedStyle ─────────────────────────────────────────────────
266
+ // Eval.makeComputedStyleScript(selector, property)
267
+ async function getComputedStyle(client, params) {
268
+ const selector = params.selector;
269
+ const property = params.property;
270
+ if (!selector)
271
+ throw new Error("Selector required");
272
+ const result = await client.evaluate(Eval.makeComputedStyleScript(selector, property));
273
+ return result;
274
+ }
275
+ // ─── getEventListeners ────────────────────────────────────────────────
276
+ // Evaluate for DevTools protocol (note: getEventListeners is CDP-specific
277
+ // and not available in page context without the DevTools API)
278
+ async function getEventListeners(client, params) {
279
+ const selector = params.selector;
280
+ if (!selector)
281
+ throw new Error("Selector required");
282
+ // Attempt to use DOM.getEventListeners via CDP if available,
283
+ // otherwise fall back to a page-context message.
284
+ try {
285
+ const objectResult = await client.sendCommand("DOM.resolveNode", { selector }).catch(() => null);
286
+ if (objectResult?.object?.objectId) {
287
+ const listeners = await client.sendCommand("DOMDebugger.getEventListeners", { objectId: objectResult.object.objectId }).catch(() => null);
288
+ return listeners;
289
+ }
290
+ }
291
+ catch {
292
+ // Fallback to page-context message
293
+ }
294
+ const result = await client.evaluate(`
295
+ (function() {
296
+ const el = document.querySelector(${JSON.stringify(selector)});
297
+ if (!el) return null;
298
+ return { message: "getEventListeners requires DevTools protocol, not available in page context" };
299
+ })()
300
+ `);
301
+ return result;
302
+ }