ios-webkit-mcp 0.18.3

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 (171) hide show
  1. package/CONTRIBUTING.md +61 -0
  2. package/LICENSE +202 -0
  3. package/NOTICE +16 -0
  4. package/README.md +187 -0
  5. package/build/src/bin/ios-webkit-mcp.d.ts +2 -0
  6. package/build/src/bin/ios-webkit-mcp.js +14 -0
  7. package/build/src/bin/ios-webkit-mcp.js.map +1 -0
  8. package/build/src/capability.d.ts +61 -0
  9. package/build/src/capability.js +146 -0
  10. package/build/src/capability.js.map +1 -0
  11. package/build/src/index.d.ts +1 -0
  12. package/build/src/index.js +2 -0
  13. package/build/src/index.js.map +1 -0
  14. package/build/src/page-session.d.ts +108 -0
  15. package/build/src/page-session.js +331 -0
  16. package/build/src/page-session.js.map +1 -0
  17. package/build/src/server.d.ts +11 -0
  18. package/build/src/server.js +144 -0
  19. package/build/src/server.js.map +1 -0
  20. package/build/src/tools/analyze_performance.d.ts +40 -0
  21. package/build/src/tools/analyze_performance.js +112 -0
  22. package/build/src/tools/analyze_performance.js.map +1 -0
  23. package/build/src/tools/breakpoints.d.ts +80 -0
  24. package/build/src/tools/breakpoints.js +167 -0
  25. package/build/src/tools/breakpoints.js.map +1 -0
  26. package/build/src/tools/clear_console.d.ts +11 -0
  27. package/build/src/tools/clear_console.js +32 -0
  28. package/build/src/tools/clear_console.js.map +1 -0
  29. package/build/src/tools/click.d.ts +20 -0
  30. package/build/src/tools/click.js +88 -0
  31. package/build/src/tools/click.js.map +1 -0
  32. package/build/src/tools/debug_element.d.ts +36 -0
  33. package/build/src/tools/debug_element.js +66 -0
  34. package/build/src/tools/debug_element.js.map +1 -0
  35. package/build/src/tools/debugger.d.ts +44 -0
  36. package/build/src/tools/debugger.js +117 -0
  37. package/build/src/tools/debugger.js.map +1 -0
  38. package/build/src/tools/delete_cookie.d.ts +18 -0
  39. package/build/src/tools/delete_cookie.js +33 -0
  40. package/build/src/tools/delete_cookie.js.map +1 -0
  41. package/build/src/tools/drag.d.ts +40 -0
  42. package/build/src/tools/drag.js +202 -0
  43. package/build/src/tools/drag.js.map +1 -0
  44. package/build/src/tools/evaluate_script.d.ts +24 -0
  45. package/build/src/tools/evaluate_script.js +172 -0
  46. package/build/src/tools/evaluate_script.js.map +1 -0
  47. package/build/src/tools/fill.d.ts +22 -0
  48. package/build/src/tools/fill.js +104 -0
  49. package/build/src/tools/fill.js.map +1 -0
  50. package/build/src/tools/fill_form.d.ts +34 -0
  51. package/build/src/tools/fill_form.js +110 -0
  52. package/build/src/tools/fill_form.js.map +1 -0
  53. package/build/src/tools/gc_heap.d.ts +16 -0
  54. package/build/src/tools/gc_heap.js +66 -0
  55. package/build/src/tools/gc_heap.js.map +1 -0
  56. package/build/src/tools/get_capability_snapshot.d.ts +17 -0
  57. package/build/src/tools/get_capability_snapshot.js +50 -0
  58. package/build/src/tools/get_capability_snapshot.js.map +1 -0
  59. package/build/src/tools/get_console_message.d.ts +18 -0
  60. package/build/src/tools/get_console_message.js +92 -0
  61. package/build/src/tools/get_console_message.js.map +1 -0
  62. package/build/src/tools/get_cookies.d.ts +20 -0
  63. package/build/src/tools/get_cookies.js +59 -0
  64. package/build/src/tools/get_cookies.js.map +1 -0
  65. package/build/src/tools/get_event_listeners.d.ts +29 -0
  66. package/build/src/tools/get_event_listeners.js +129 -0
  67. package/build/src/tools/get_event_listeners.js.map +1 -0
  68. package/build/src/tools/get_network_request.d.ts +22 -0
  69. package/build/src/tools/get_network_request.js +121 -0
  70. package/build/src/tools/get_network_request.js.map +1 -0
  71. package/build/src/tools/get_performance_metrics.d.ts +27 -0
  72. package/build/src/tools/get_performance_metrics.js +185 -0
  73. package/build/src/tools/get_performance_metrics.js.map +1 -0
  74. package/build/src/tools/get_resource_tree.d.ts +18 -0
  75. package/build/src/tools/get_resource_tree.js +82 -0
  76. package/build/src/tools/get_resource_tree.js.map +1 -0
  77. package/build/src/tools/handle_dialog.d.ts +39 -0
  78. package/build/src/tools/handle_dialog.js +182 -0
  79. package/build/src/tools/handle_dialog.js.map +1 -0
  80. package/build/src/tools/highlight_node.d.ts +41 -0
  81. package/build/src/tools/highlight_node.js +95 -0
  82. package/build/src/tools/highlight_node.js.map +1 -0
  83. package/build/src/tools/hover.d.ts +20 -0
  84. package/build/src/tools/hover.js +89 -0
  85. package/build/src/tools/hover.js.map +1 -0
  86. package/build/src/tools/intercept.d.ts +81 -0
  87. package/build/src/tools/intercept.js +161 -0
  88. package/build/src/tools/intercept.js.map +1 -0
  89. package/build/src/tools/list_console_messages.d.ts +20 -0
  90. package/build/src/tools/list_console_messages.js +105 -0
  91. package/build/src/tools/list_console_messages.js.map +1 -0
  92. package/build/src/tools/list_indexeddb.d.ts +16 -0
  93. package/build/src/tools/list_indexeddb.js +55 -0
  94. package/build/src/tools/list_indexeddb.js.map +1 -0
  95. package/build/src/tools/list_network_requests.d.ts +25 -0
  96. package/build/src/tools/list_network_requests.js +108 -0
  97. package/build/src/tools/list_network_requests.js.map +1 -0
  98. package/build/src/tools/list_pages.d.ts +17 -0
  99. package/build/src/tools/list_pages.js +113 -0
  100. package/build/src/tools/list_pages.js.map +1 -0
  101. package/build/src/tools/navigate_page.d.ts +18 -0
  102. package/build/src/tools/navigate_page.js +73 -0
  103. package/build/src/tools/navigate_page.js.map +1 -0
  104. package/build/src/tools/network_runtime.d.ts +51 -0
  105. package/build/src/tools/network_runtime.js +101 -0
  106. package/build/src/tools/network_runtime.js.map +1 -0
  107. package/build/src/tools/press_key.d.ts +32 -0
  108. package/build/src/tools/press_key.js +108 -0
  109. package/build/src/tools/press_key.js.map +1 -0
  110. package/build/src/tools/query_dom_node.d.ts +22 -0
  111. package/build/src/tools/query_dom_node.js +103 -0
  112. package/build/src/tools/query_dom_node.js.map +1 -0
  113. package/build/src/tools/record_cpu_profile.d.ts +38 -0
  114. package/build/src/tools/record_cpu_profile.js +174 -0
  115. package/build/src/tools/record_cpu_profile.js.map +1 -0
  116. package/build/src/tools/record_memory_tracking.d.ts +32 -0
  117. package/build/src/tools/record_memory_tracking.js +103 -0
  118. package/build/src/tools/record_memory_tracking.js.map +1 -0
  119. package/build/src/tools/record_timeline.d.ts +20 -0
  120. package/build/src/tools/record_timeline.js +110 -0
  121. package/build/src/tools/record_timeline.js.map +1 -0
  122. package/build/src/tools/reload_page.d.ts +18 -0
  123. package/build/src/tools/reload_page.js +59 -0
  124. package/build/src/tools/reload_page.js.map +1 -0
  125. package/build/src/tools/select_page.d.ts +18 -0
  126. package/build/src/tools/select_page.js +54 -0
  127. package/build/src/tools/select_page.js.map +1 -0
  128. package/build/src/tools/set_extra_http_headers.d.ts +16 -0
  129. package/build/src/tools/set_extra_http_headers.js +55 -0
  130. package/build/src/tools/set_extra_http_headers.js.map +1 -0
  131. package/build/src/tools/set_init_script.d.ts +16 -0
  132. package/build/src/tools/set_init_script.js +43 -0
  133. package/build/src/tools/set_init_script.js.map +1 -0
  134. package/build/src/tools/set_outer_html.d.ts +18 -0
  135. package/build/src/tools/set_outer_html.js +52 -0
  136. package/build/src/tools/set_outer_html.js.map +1 -0
  137. package/build/src/tools/set_user_agent.d.ts +40 -0
  138. package/build/src/tools/set_user_agent.js +83 -0
  139. package/build/src/tools/set_user_agent.js.map +1 -0
  140. package/build/src/tools/summarize_console_errors.d.ts +40 -0
  141. package/build/src/tools/summarize_console_errors.js +131 -0
  142. package/build/src/tools/summarize_console_errors.js.map +1 -0
  143. package/build/src/tools/take_memory_snapshot.d.ts +18 -0
  144. package/build/src/tools/take_memory_snapshot.js +88 -0
  145. package/build/src/tools/take_memory_snapshot.js.map +1 -0
  146. package/build/src/tools/take_node_screenshot.d.ts +29 -0
  147. package/build/src/tools/take_node_screenshot.js +57 -0
  148. package/build/src/tools/take_node_screenshot.js.map +1 -0
  149. package/build/src/tools/take_screenshot.d.ts +51 -0
  150. package/build/src/tools/take_screenshot.js +108 -0
  151. package/build/src/tools/take_screenshot.js.map +1 -0
  152. package/build/src/tools/take_snapshot.d.ts +22 -0
  153. package/build/src/tools/take_snapshot.js +142 -0
  154. package/build/src/tools/take_snapshot.js.map +1 -0
  155. package/build/src/tools/type_text.d.ts +34 -0
  156. package/build/src/tools/type_text.js +203 -0
  157. package/build/src/tools/type_text.js.map +1 -0
  158. package/build/src/tools/wait_for.d.ts +24 -0
  159. package/build/src/tools/wait_for.js +93 -0
  160. package/build/src/tools/wait_for.js.map +1 -0
  161. package/build/src/tools/wip_send.d.ts +22 -0
  162. package/build/src/tools/wip_send.js +81 -0
  163. package/build/src/tools/wip_send.js.map +1 -0
  164. package/build/src/wip-client/iwdp-http.d.ts +17 -0
  165. package/build/src/wip-client/iwdp-http.js +98 -0
  166. package/build/src/wip-client/iwdp-http.js.map +1 -0
  167. package/build/src/wip-client/ws-session.d.ts +41 -0
  168. package/build/src/wip-client/ws-session.js +290 -0
  169. package/build/src/wip-client/ws-session.js.map +1 -0
  170. package/docs/spec.md +689 -0
  171. package/package.json +77 -0
@@ -0,0 +1,88 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const takeMemorySnapshotTool = {
4
+ name: 'take_memory_snapshot',
5
+ description: [
6
+ 'Capture a JavaScript heap snapshot from the inspected iOS WebView page using WIP `Heap.snapshot`.',
7
+ 'IMPORTANT: The snapshot is in **Apple Inspector heap format** (`{version, type, nodes, edges, …}`), NOT the V8 / Chrome `.heapsnapshot` format. Tools that ingest CDP `HeapProfiler.takeHeapSnapshot` output will not understand this directly.',
8
+ 'Returns a summary (node count, edge count, root count) plus optionally the raw JSON.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ includeRaw: z
12
+ .boolean()
13
+ .optional()
14
+ .describe('Include the full raw `snapshotData` JSON in output (large; default false — only summary).'),
15
+ maxRawChars: z
16
+ .number()
17
+ .int()
18
+ .min(1_000)
19
+ .max(2_000_000)
20
+ .optional()
21
+ .describe('Cap raw JSON output length when includeRaw=true (default 50_000, truncated with "…" marker).'),
22
+ },
23
+ handler: async ({ includeRaw = false, maxRawChars = 50_000, }) => {
24
+ let ps;
25
+ try {
26
+ ps = await PageSession.get();
27
+ }
28
+ catch (e) {
29
+ return errorResult(`Unable to attach to a WKWebView page: ${describe(e)}`);
30
+ }
31
+ let result;
32
+ try {
33
+ result = await ps.session.send('Heap.snapshot', {}, 60_000);
34
+ }
35
+ catch (e) {
36
+ return errorResult(`Heap.snapshot failed: ${describe(e)}`);
37
+ }
38
+ let parsed;
39
+ try {
40
+ parsed = JSON.parse(result.snapshotData);
41
+ }
42
+ catch {
43
+ // raw output may not be JSON in some unforeseen cases
44
+ }
45
+ const lines = [];
46
+ lines.push(`# take_memory_snapshot`);
47
+ lines.push('');
48
+ if (ps.attachInfo) {
49
+ lines.push(`Target: page id ${ps.attachInfo.pageId} (${ps.attachInfo.pageTitle || ps.attachInfo.pageUrl})`);
50
+ }
51
+ lines.push(`Timestamp (WIP): ${result.timestamp}`);
52
+ lines.push(`Raw size: ${result.snapshotData.length} chars`);
53
+ if (parsed) {
54
+ const nodes = Array.isArray(parsed['nodes']) ? parsed['nodes'].length : '(unknown)';
55
+ const edges = Array.isArray(parsed['edges']) ? parsed['edges'].length : '(unknown)';
56
+ const roots = Array.isArray(parsed['roots']) ? parsed['roots'].length : '(unknown)';
57
+ const version = parsed['version'];
58
+ const type = parsed['type'];
59
+ lines.push(`Format: ${type ?? '(unknown type)'} v${version ?? '?'}`);
60
+ lines.push(`Nodes: ${nodes} · Edges: ${edges} · Roots: ${roots}`);
61
+ }
62
+ else {
63
+ lines.push('(snapshotData was not parseable JSON — content shown below as-is)');
64
+ }
65
+ lines.push('');
66
+ lines.push('⚠ Apple Inspector heap format — NOT V8 `.heapsnapshot`. Chrome DevTools cannot load this directly.');
67
+ if (includeRaw) {
68
+ lines.push('');
69
+ lines.push('## Raw snapshotData');
70
+ lines.push('```json');
71
+ lines.push(result.snapshotData.length > maxRawChars
72
+ ? result.snapshotData.slice(0, maxRawChars) + `…\n(truncated, ${result.snapshotData.length - maxRawChars} more chars)`
73
+ : result.snapshotData);
74
+ lines.push('```');
75
+ }
76
+ return textResult(lines.join('\n'));
77
+ },
78
+ };
79
+ function textResult(text) {
80
+ return { content: [{ type: 'text', text }] };
81
+ }
82
+ function errorResult(text) {
83
+ return { content: [{ type: 'text', text }], isError: true };
84
+ }
85
+ function describe(e) {
86
+ return e instanceof Error ? e.message : String(e);
87
+ }
88
+ //# sourceMappingURL=take_memory_snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"take_memory_snapshot.js","sourceRoot":"","sources":["../../../src/tools/take_memory_snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ import { z } from 'zod';
2
+ export declare const takeNodeScreenshotTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ selector: z.ZodString;
7
+ };
8
+ handler: ({ selector }: {
9
+ selector: string;
10
+ }) => Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ isError: boolean;
16
+ } | {
17
+ content: ({
18
+ type: "image";
19
+ data: string;
20
+ mimeType: string;
21
+ text?: undefined;
22
+ } | {
23
+ type: "text";
24
+ text: string;
25
+ data?: undefined;
26
+ mimeType?: undefined;
27
+ })[];
28
+ }>;
29
+ };
@@ -0,0 +1,57 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const takeNodeScreenshotTool = {
4
+ name: 'take_node_screenshot',
5
+ description: [
6
+ 'Capture a screenshot of a specific element on the inspected iOS WebView page via WIP `Page.snapshotNode` (Apple-specific, probe-confirmed 2026-05-16).',
7
+ 'Resolves selector → nodeId via `DOM.getDocument` + `DOM.querySelector`, then snapshots the element only (not the surrounding viewport).',
8
+ 'Returns base64 PNG. More context-efficient than `take_screenshot` when AI only needs to see one widget.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ selector: z.string().min(1).describe('CSS selector for the element to screenshot.'),
12
+ },
13
+ handler: async ({ selector }) => {
14
+ let ps;
15
+ try {
16
+ ps = await PageSession.get();
17
+ }
18
+ catch (e) {
19
+ return errorResult(`Unable to attach: ${describe(e)}`);
20
+ }
21
+ let nodeId;
22
+ try {
23
+ const doc = await ps.session.send('DOM.getDocument', { depth: 0 }, 10_000);
24
+ const qs = await ps.session.send('DOM.querySelector', { nodeId: doc.root.nodeId, selector }, 10_000);
25
+ if (qs.nodeId === 0)
26
+ return errorResult(`# take_node_screenshot — no match for \`${selector}\``);
27
+ nodeId = qs.nodeId;
28
+ }
29
+ catch (e) {
30
+ return errorResult(`DOM resolve failed: ${describe(e)}`);
31
+ }
32
+ let r;
33
+ try {
34
+ r = await ps.session.send('Page.snapshotNode', { nodeId }, 30_000);
35
+ }
36
+ catch (e) {
37
+ return errorResult(`Page.snapshotNode failed: ${describe(e)}`);
38
+ }
39
+ if (!r.dataURL?.startsWith('data:image/'))
40
+ return errorResult(`Unexpected dataURL: ${String(r.dataURL).slice(0, 60)}`);
41
+ const m = r.dataURL.match(/^data:(image\/[^;]+);base64,(.+)$/);
42
+ if (!m)
43
+ return errorResult('Unrecognized dataURL format.');
44
+ const mimeType = m[1];
45
+ const base64 = m[2];
46
+ const sizeKb = Math.round((base64.length * 3) / 4 / 1024);
47
+ return {
48
+ content: [
49
+ { type: 'image', data: base64, mimeType },
50
+ { type: 'text', text: `# take_node_screenshot · ${mimeType} (~${sizeKb} KB)\n\nselector: \`${selector}\` · nodeId: ${nodeId}` },
51
+ ],
52
+ };
53
+ },
54
+ };
55
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
56
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
57
+ //# sourceMappingURL=take_node_screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"take_node_screenshot.js","sourceRoot":"","sources":["../../../src/tools/take_node_screenshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,51 @@
1
+ import { z } from 'zod';
2
+ export declare const takeScreenshotTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ rect: z.ZodOptional<z.ZodObject<{
7
+ x: z.ZodNumber;
8
+ y: z.ZodNumber;
9
+ width: z.ZodNumber;
10
+ height: z.ZodNumber;
11
+ }, "strip", z.ZodTypeAny, {
12
+ x: number;
13
+ y: number;
14
+ width: number;
15
+ height: number;
16
+ }, {
17
+ x: number;
18
+ y: number;
19
+ width: number;
20
+ height: number;
21
+ }>>;
22
+ coordinateSystem: z.ZodOptional<z.ZodEnum<["Viewport", "Page"]>>;
23
+ };
24
+ handler: ({ rect, coordinateSystem, }: {
25
+ rect?: {
26
+ x: number;
27
+ y: number;
28
+ width: number;
29
+ height: number;
30
+ };
31
+ coordinateSystem?: "Viewport" | "Page";
32
+ }) => Promise<{
33
+ content: {
34
+ type: "text";
35
+ text: string;
36
+ }[];
37
+ isError: boolean;
38
+ } | {
39
+ content: ({
40
+ type: "image";
41
+ data: string;
42
+ mimeType: string;
43
+ text?: undefined;
44
+ } | {
45
+ type: "text";
46
+ text: string;
47
+ data?: undefined;
48
+ mimeType?: undefined;
49
+ })[];
50
+ }>;
51
+ };
@@ -0,0 +1,108 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const takeScreenshotTool = {
4
+ name: 'take_screenshot',
5
+ description: [
6
+ 'Capture a screenshot of the inspected iOS WebView page using WIP `Page.snapshotRect` (Apple-specific; the CDP-style `Page.captureScreenshot` is NOT implemented on iOS — verified `-32601 not found`).',
7
+ 'Returns a base64 PNG image. By default captures the current viewport at the device DPR; pass an explicit `rect` for a sub-region.',
8
+ 'Note: WIP only captures the rect you specify — there is no built-in "full page" mode like Chrome\'s. To screenshot a region you can see, leave rect empty and accept the current viewport.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ rect: z
12
+ .object({
13
+ x: z.number().int().min(0),
14
+ y: z.number().int().min(0),
15
+ width: z.number().int().min(1),
16
+ height: z.number().int().min(1),
17
+ })
18
+ .optional()
19
+ .describe('Optional viewport rect (CSS pixels). Defaults to (0,0, viewportW, viewportH).'),
20
+ coordinateSystem: z
21
+ .enum(['Viewport', 'Page'])
22
+ .optional()
23
+ .describe('WIP coordinate system. `Viewport` (default) treats rect as CSS-pixel offsets within the visible viewport; `Page` is full-page coords.'),
24
+ },
25
+ handler: async ({ rect, coordinateSystem = 'Viewport', }) => {
26
+ let ps;
27
+ try {
28
+ ps = await PageSession.get();
29
+ }
30
+ catch (e) {
31
+ return errorResult(`Unable to attach to a WKWebView page: ${describe(e)}`);
32
+ }
33
+ // If no rect supplied, query viewport dimensions via Runtime.evaluate.
34
+ let useRect = rect;
35
+ let viewport;
36
+ if (!useRect) {
37
+ try {
38
+ const r = await ps.session.send('Runtime.evaluate', {
39
+ expression: 'JSON.stringify({innerWidth: window.innerWidth, innerHeight: window.innerHeight, scrollX: window.scrollX, scrollY: window.scrollY, dpr: window.devicePixelRatio})',
40
+ returnByValue: false,
41
+ });
42
+ // The string value comes back as JSON-of-JSON; with returnByValue:false we get description; flip approach
43
+ }
44
+ catch {
45
+ // ignore
46
+ }
47
+ try {
48
+ const r2 = await ps.session.send('Runtime.evaluate', {
49
+ expression: 'JSON.stringify({innerWidth: window.innerWidth, innerHeight: window.innerHeight, scrollX: window.scrollX, scrollY: window.scrollY, dpr: window.devicePixelRatio})',
50
+ returnByValue: true,
51
+ });
52
+ if (r2?.result?.value) {
53
+ viewport = JSON.parse(r2.result.value);
54
+ useRect = { x: viewport.scrollX, y: viewport.scrollY, width: viewport.innerWidth, height: viewport.innerHeight };
55
+ }
56
+ }
57
+ catch {
58
+ // fallback
59
+ }
60
+ if (!useRect) {
61
+ useRect = { x: 0, y: 0, width: 390, height: 844 }; // iPhone 14/15-ish default
62
+ }
63
+ }
64
+ let result;
65
+ try {
66
+ result = await ps.session.send('Page.snapshotRect', {
67
+ x: useRect.x,
68
+ y: useRect.y,
69
+ width: useRect.width,
70
+ height: useRect.height,
71
+ coordinateSystem,
72
+ }, 30_000);
73
+ }
74
+ catch (e) {
75
+ return errorResult(`Page.snapshotRect failed: ${describe(e)}`);
76
+ }
77
+ if (!result.dataURL || !result.dataURL.startsWith('data:image/')) {
78
+ return errorResult(`Page.snapshotRect returned no valid dataURL (got: ${String(result.dataURL).slice(0, 80)})`);
79
+ }
80
+ const m = result.dataURL.match(/^data:(image\/[^;]+);base64,(.+)$/);
81
+ if (!m) {
82
+ return errorResult('Unrecognized dataURL format from Page.snapshotRect.');
83
+ }
84
+ const mimeType = m[1];
85
+ const base64 = m[2];
86
+ const sizeKb = Math.round((base64.length * 3) / 4 / 1024);
87
+ return {
88
+ content: [
89
+ {
90
+ type: 'image',
91
+ data: base64,
92
+ mimeType,
93
+ },
94
+ {
95
+ type: 'text',
96
+ text: `# take_screenshot · ${mimeType} (~${sizeKb} KB)\n\nRect: ${useRect.x},${useRect.y} ${useRect.width}×${useRect.height} (${coordinateSystem})${viewport ? ` · viewport ${viewport.innerWidth}×${viewport.innerHeight} dpr ${viewport.dpr}` : ''}`,
97
+ },
98
+ ],
99
+ };
100
+ },
101
+ };
102
+ function errorResult(text) {
103
+ return { content: [{ type: 'text', text }], isError: true };
104
+ }
105
+ function describe(e) {
106
+ return e instanceof Error ? e.message : String(e);
107
+ }
108
+ //# sourceMappingURL=take_screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"take_screenshot.js","sourceRoot":"","sources":["../../../src/tools/take_screenshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,22 @@
1
+ import { z } from 'zod';
2
+ export declare const takeSnapshotTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ depth: z.ZodOptional<z.ZodNumber>;
7
+ pierce: z.ZodOptional<z.ZodBoolean>;
8
+ format: z.ZodOptional<z.ZodEnum<["outline", "raw_json"]>>;
9
+ maxNodes: z.ZodOptional<z.ZodNumber>;
10
+ };
11
+ handler: ({ depth, pierce, format, maxNodes, }: {
12
+ depth?: number;
13
+ pierce?: boolean;
14
+ format?: "outline" | "raw_json";
15
+ maxNodes?: number;
16
+ }) => Promise<{
17
+ content: {
18
+ type: "text";
19
+ text: string;
20
+ }[];
21
+ }>;
22
+ };
@@ -0,0 +1,142 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const takeSnapshotTool = {
4
+ name: 'take_snapshot',
5
+ description: [
6
+ 'Capture a DOM snapshot of the inspected iOS WebView page.',
7
+ 'Wraps WIP `DOM.getDocument` with optional depth + pierce (shadow DOM / iframes).',
8
+ 'Returns a compact markdown outline by default. Set `format=raw_json` to get the full DOM tree JSON.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ depth: z
12
+ .number()
13
+ .int()
14
+ .min(-1)
15
+ .max(20)
16
+ .optional()
17
+ .describe('Recursion depth. -1 = full tree (default), 1 = root only.'),
18
+ pierce: z
19
+ .boolean()
20
+ .optional()
21
+ .describe('Include shadow DOM and iframe content (default true).'),
22
+ format: z
23
+ .enum(['outline', 'raw_json'])
24
+ .optional()
25
+ .describe('Output format: `outline` (default, compact tree) or `raw_json` (full DOM.getDocument result).'),
26
+ maxNodes: z
27
+ .number()
28
+ .int()
29
+ .min(10)
30
+ .max(2_000)
31
+ .optional()
32
+ .describe('In outline mode, cap nodes rendered (default 200).'),
33
+ },
34
+ handler: async ({ depth = -1, pierce = true, format = 'outline', maxNodes = 200, }) => {
35
+ let ps;
36
+ try {
37
+ ps = await PageSession.get();
38
+ }
39
+ catch (e) {
40
+ return errorResult(`Unable to attach to a WKWebView page: ${describe(e)}`);
41
+ }
42
+ let result;
43
+ try {
44
+ result = await ps.session.send('DOM.getDocument', { depth, pierce }, 20_000);
45
+ }
46
+ catch (e) {
47
+ return errorResult(`DOM.getDocument failed: ${describe(e)}`);
48
+ }
49
+ if (format === 'raw_json') {
50
+ return textResult('```json\n' + JSON.stringify(result, null, 2) + '\n```');
51
+ }
52
+ const lines = [];
53
+ lines.push(`# DOM snapshot`);
54
+ lines.push('');
55
+ if (ps.attachInfo) {
56
+ lines.push(`Page: \`${ps.attachInfo.pageTitle || ps.attachInfo.pageUrl}\` (page id ${ps.attachInfo.pageId})`);
57
+ lines.push('');
58
+ }
59
+ const outline = [];
60
+ const ctx = { count: 0, cap: maxNodes };
61
+ renderNode(result.root, 0, outline, ctx);
62
+ if (ctx.count >= ctx.cap) {
63
+ outline.push(`… (truncated at ${ctx.cap} nodes; use \`format: "raw_json"\` for full tree)`);
64
+ }
65
+ lines.push('```');
66
+ lines.push(...outline);
67
+ lines.push('```');
68
+ return textResult(lines.join('\n'));
69
+ },
70
+ };
71
+ function renderNode(node, indent, out, ctx) {
72
+ if (!node)
73
+ return;
74
+ if (ctx.count >= ctx.cap)
75
+ return;
76
+ ctx.count++;
77
+ const pad = ' '.repeat(indent);
78
+ if (node.nodeType === 3) {
79
+ // text
80
+ const text = (node.nodeValue ?? '').trim();
81
+ if (text) {
82
+ const truncated = text.length > 80 ? text.slice(0, 80) + '…' : text;
83
+ out.push(`${pad}"${truncated.replace(/"/g, '\\"')}"`);
84
+ }
85
+ return;
86
+ }
87
+ if (node.nodeType === 8) {
88
+ out.push(`${pad}<!-- ${(node.nodeValue ?? '').slice(0, 80)} -->`);
89
+ return;
90
+ }
91
+ const name = (node.localName ?? node.nodeName ?? '?').toLowerCase();
92
+ const attrs = renderAttrs(node.attributes);
93
+ out.push(`${pad}<${name}${attrs}>`);
94
+ if (node.children) {
95
+ for (const c of node.children) {
96
+ renderNode(c, indent + 1, out, ctx);
97
+ }
98
+ }
99
+ if (node.contentDocument)
100
+ renderNode(node.contentDocument, indent + 1, out, ctx);
101
+ if (node.shadowRoots) {
102
+ for (const r of node.shadowRoots) {
103
+ out.push(`${' '.repeat(indent + 1)}#shadow-root`);
104
+ renderNode(r, indent + 2, out, ctx);
105
+ }
106
+ }
107
+ }
108
+ function renderAttrs(arr) {
109
+ if (!arr || arr.length === 0)
110
+ return '';
111
+ const pairs = [];
112
+ for (let i = 0; i < arr.length; i += 2) {
113
+ const k = arr[i];
114
+ const v = arr[i + 1];
115
+ if (k == null)
116
+ continue;
117
+ if (k === 'class' || k === 'id') {
118
+ pairs.push(`${k}="${(v ?? '').slice(0, 80)}"`);
119
+ }
120
+ else if (k === 'src' || k === 'href') {
121
+ const short = (v ?? '').slice(0, 60);
122
+ pairs.push(`${k}="${short}${(v?.length ?? 0) > 60 ? '…' : ''}"`);
123
+ }
124
+ else {
125
+ // Skip noisy attrs in outline mode (style/data-*); keep tag terse.
126
+ if (k.startsWith('data-') || k === 'style')
127
+ continue;
128
+ pairs.push(`${k}${v ? `="${(v ?? '').slice(0, 40)}"` : ''}`);
129
+ }
130
+ }
131
+ return pairs.length > 0 ? ' ' + pairs.join(' ') : '';
132
+ }
133
+ function textResult(text) {
134
+ return { content: [{ type: 'text', text }] };
135
+ }
136
+ function errorResult(text) {
137
+ return { content: [{ type: 'text', text }], isError: true };
138
+ }
139
+ function describe(e) {
140
+ return e instanceof Error ? e.message : String(e);
141
+ }
142
+ //# sourceMappingURL=take_snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"take_snapshot.js","sourceRoot":"","sources":["../../../src/tools/take_snapshot.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * WIP gotcha: `Runtime.evaluate` with `awaitPromise:true` does NOT correctly
4
+ * serialize the resolved value of a returned Promise — even `Promise.resolve(42)`
5
+ * comes back as `{}`. So this tool MUST keep the inner expression synchronous.
6
+ * Per-char delay is implemented by issuing one Runtime.evaluate per character
7
+ * from TS land when `delayMs > 0`. When `delayMs === 0`, a single sync IIFE
8
+ * types the whole string in one round-trip.
9
+ */
10
+ export declare const typeTextTool: {
11
+ name: string;
12
+ description: string;
13
+ inputSchema: {
14
+ text: z.ZodString;
15
+ selector: z.ZodOptional<z.ZodString>;
16
+ nth: z.ZodOptional<z.ZodNumber>;
17
+ clearFirst: z.ZodOptional<z.ZodBoolean>;
18
+ delayMs: z.ZodOptional<z.ZodNumber>;
19
+ waitAfterMs: z.ZodOptional<z.ZodNumber>;
20
+ };
21
+ handler: ({ text, selector, nth, clearFirst, delayMs, waitAfterMs, }: {
22
+ text: string;
23
+ selector?: string;
24
+ nth?: number;
25
+ clearFirst?: boolean;
26
+ delayMs?: number;
27
+ waitAfterMs?: number;
28
+ }) => Promise<{
29
+ content: {
30
+ type: "text";
31
+ text: string;
32
+ }[];
33
+ }>;
34
+ };