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,110 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const fillFormTool = {
4
+ name: 'fill_form',
5
+ description: [
6
+ 'Fill multiple form fields in one round-trip on the inspected iOS WebView page.',
7
+ 'Each entry mirrors the behavior of `fill`: native `value` setter (React `onChange` compatible) + synthetic `input` + `change` events. WIP has no `Input.*` domain so all events are `isTrusted=false`.',
8
+ 'Selector matches via `document.querySelectorAll(selector)[nth]`. Per-field failures are reported but do NOT abort the rest of the batch.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ fields: z
12
+ .array(z.object({
13
+ selector: z.string().min(1).describe('CSS selector for the input/textarea/contenteditable.'),
14
+ value: z.string().describe('Text to fill (empty string clears).'),
15
+ nth: z.number().int().min(0).optional().describe('Nth match (default 0).'),
16
+ }))
17
+ .min(1)
18
+ .max(50)
19
+ .describe('Form fields to fill in order.'),
20
+ waitAfterMs: z
21
+ .number()
22
+ .int()
23
+ .min(0)
24
+ .max(10_000)
25
+ .optional()
26
+ .describe('Block after the whole batch for this long (default 150).'),
27
+ },
28
+ handler: async ({ fields, waitAfterMs = 150, }) => {
29
+ let ps;
30
+ try {
31
+ ps = await PageSession.get();
32
+ }
33
+ catch (e) {
34
+ return errorResult(`Unable to attach to a WKWebView page: ${describe(e)}`);
35
+ }
36
+ const fieldsJson = JSON.stringify(fields.map(f => ({ selector: f.selector, value: f.value, nth: f.nth ?? 0 })));
37
+ const expression = `
38
+ (() => {
39
+ const fields = ${fieldsJson};
40
+ const results = [];
41
+ for (const f of fields) {
42
+ const matches = document.querySelectorAll(f.selector);
43
+ if (matches.length === 0) { results.push({ selector: f.selector, ok: false, reason: 'no_match' }); continue; }
44
+ if (f.nth >= matches.length) { results.push({ selector: f.selector, ok: false, reason: 'nth_out_of_range', found: matches.length }); continue; }
45
+ const el = matches[f.nth];
46
+ const tag = el.tagName.toLowerCase();
47
+ const isInput = tag === 'input' || tag === 'textarea';
48
+ const isCE = el.isContentEditable === true;
49
+ if (!isInput && !isCE) { results.push({ selector: f.selector, ok: false, reason: 'not_fillable', tag }); continue; }
50
+ try {
51
+ el.focus();
52
+ if (isInput) {
53
+ const proto = tag === 'input' ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype;
54
+ const setter = Object.getOwnPropertyDescriptor(proto, 'value') && Object.getOwnPropertyDescriptor(proto, 'value').set;
55
+ if (setter) setter.call(el, f.value); else el.value = f.value;
56
+ } else {
57
+ el.textContent = f.value;
58
+ }
59
+ el.dispatchEvent(new Event('input', { bubbles: true }));
60
+ el.dispatchEvent(new Event('change', { bubbles: true }));
61
+ } catch (e) { results.push({ selector: f.selector, ok: false, reason: 'fill_threw', error: String(e), tag }); continue; }
62
+ results.push({ selector: f.selector, ok: true, tag, valueLen: f.value.length });
63
+ }
64
+ return results;
65
+ })()
66
+ `;
67
+ let result;
68
+ try {
69
+ result = await ps.session.send('Runtime.evaluate', { expression, returnByValue: true, awaitPromise: false }, 15_000);
70
+ }
71
+ catch (e) {
72
+ return errorResult(`Runtime.evaluate (fill_form) failed: ${describe(e)}`);
73
+ }
74
+ if (waitAfterMs > 0) {
75
+ await new Promise(r => setTimeout(r, waitAfterMs));
76
+ }
77
+ const results = result?.result?.value;
78
+ if (!Array.isArray(results)) {
79
+ return errorResult(`# fill_form: unexpected return\n\n${JSON.stringify(result?.result)}`);
80
+ }
81
+ const ok = results.filter(r => r.ok === true).length;
82
+ const failed = results.length - ok;
83
+ const lines = [`# fill_form ${failed === 0 ? '✓' : '⚠'} ${ok}/${results.length} fields filled`, ''];
84
+ results.forEach((r, i) => {
85
+ if (r.ok) {
86
+ lines.push(`- [${i + 1}] ✓ \`${r.selector}\` ← \`<${r.tag}>\` (len ${r.valueLen})`);
87
+ }
88
+ else {
89
+ lines.push(`- [${i + 1}] ✗ \`${r.selector}\` → ${r.reason}${r.tag ? ` (tag: ${r.tag})` : ''}${r.found != null ? ` (found ${r.found})` : ''}${r.error ? ` (${r.error})` : ''}`);
90
+ }
91
+ });
92
+ if (failed > 0) {
93
+ lines.push('');
94
+ lines.push('⚠ Per-field failures do not abort the batch. Re-run with corrected selectors.');
95
+ }
96
+ lines.push('');
97
+ lines.push('⚠ Synthetic `value=…` + `input`/`change` events (isTrusted=false). Use `type_text` per-field for per-keystroke listeners.');
98
+ return textResult(lines.join('\n'));
99
+ },
100
+ };
101
+ function textResult(text) {
102
+ return { content: [{ type: 'text', text }] };
103
+ }
104
+ function errorResult(text) {
105
+ return { content: [{ type: 'text', text }], isError: true };
106
+ }
107
+ function describe(e) {
108
+ return e instanceof Error ? e.message : String(e);
109
+ }
110
+ //# sourceMappingURL=fill_form.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill_form.js","sourceRoot":"","sources":["../../../src/tools/fill_form.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export declare const gcHeapTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ measureDelta: z.ZodOptional<z.ZodBoolean>;
7
+ };
8
+ handler: ({ measureDelta }: {
9
+ measureDelta?: boolean;
10
+ }) => Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ };
@@ -0,0 +1,66 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const gcHeapTool = {
4
+ name: 'gc_heap',
5
+ description: [
6
+ 'Force JavaScript garbage collection via WIP `Heap.gc` (Apple-specific, probe-confirmed 2026-05-16).',
7
+ 'Useful before `take_memory_snapshot` to surface only "live" objects, or to confirm objects are eligible for GC after closing modals / unmounting components.',
8
+ 'Optionally measure heap size delta via `Runtime.evaluate("performance.memory")` (Apple WebKit exposes a Chrome-compatible `performance.memory.usedJSHeapSize`).',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ measureDelta: z.boolean().optional().describe('Read `performance.memory.usedJSHeapSize` before + after gc and report the delta. Default true.'),
12
+ },
13
+ handler: async ({ measureDelta = true }) => {
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 before = null;
22
+ let after = null;
23
+ if (measureDelta) {
24
+ try {
25
+ const r = await ps.session.send('Runtime.evaluate', {
26
+ expression: '(performance.memory && performance.memory.usedJSHeapSize) || -1',
27
+ returnByValue: true,
28
+ }, 5_000);
29
+ before = r?.result?.value ?? null;
30
+ }
31
+ catch { }
32
+ }
33
+ try {
34
+ await ps.session.send('Heap.gc', undefined, 30_000);
35
+ }
36
+ catch (e) {
37
+ return errorResult(`Heap.gc failed: ${describe(e)}`);
38
+ }
39
+ if (measureDelta) {
40
+ try {
41
+ const r = await ps.session.send('Runtime.evaluate', {
42
+ expression: '(performance.memory && performance.memory.usedJSHeapSize) || -1',
43
+ returnByValue: true,
44
+ }, 5_000);
45
+ after = r?.result?.value ?? null;
46
+ }
47
+ catch { }
48
+ }
49
+ const lines = [`# gc_heap ✓`, ''];
50
+ if (before != null && after != null && before > 0 && after > 0) {
51
+ const fmt = (n) => `${(n / 1024 / 1024).toFixed(2)} MB`;
52
+ const delta = after - before;
53
+ lines.push(`heap usedJSHeapSize: ${fmt(before)} → ${fmt(after)} (Δ ${delta >= 0 ? '+' : ''}${fmt(Math.abs(delta))})`);
54
+ }
55
+ else if (measureDelta) {
56
+ lines.push('⚠ `performance.memory` unavailable on this WebView — delta not measured.');
57
+ }
58
+ lines.push('');
59
+ lines.push('Run `take_memory_snapshot` next for the post-GC heap distribution.');
60
+ return textResult(lines.join('\n'));
61
+ },
62
+ };
63
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
64
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
65
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
66
+ //# sourceMappingURL=gc_heap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gc_heap.js","sourceRoot":"","sources":["../../../src/tools/gc_heap.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export declare const getCapabilitySnapshotTool: {
2
+ name: string;
3
+ description: string;
4
+ inputSchema: {};
5
+ handler: () => Promise<{
6
+ content: {
7
+ type: "text";
8
+ text: string;
9
+ }[];
10
+ isError: boolean;
11
+ } | {
12
+ content: {
13
+ type: "text";
14
+ text: string;
15
+ }[];
16
+ }>;
17
+ };
@@ -0,0 +1,50 @@
1
+ /**
2
+ * `get_capability_snapshot` — expose the WIP capability discovery snapshot to
3
+ * LLM agents. Useful when the agent's earlier tool call hits a domain timeout
4
+ * and it wants to know "is this method known to be unsupported on this device,
5
+ * or is it just a transient timeout?".
6
+ *
7
+ * Surface mirrors `CapabilitySnapshot` from src/capability.ts — see spec
8
+ * §"Capability discovery 架构 (v2.0.1)".
9
+ */
10
+ import { PageSession } from '../page-session.js';
11
+ export const getCapabilitySnapshotTool = {
12
+ name: 'get_capability_snapshot',
13
+ description: [
14
+ 'Return the WIP capability discovery snapshot for the currently-attached page session.',
15
+ 'Tells you which Apple WIP domains the connected WebKit build supports (when `Schema.getDomains` is available; many iOS builds do NOT expose Schema, in which case `supportedDomains` is null and tool calls fall back to optimistic + tool-level timeout).',
16
+ 'Use to interpret prior `*_DOMAIN_UNAVAILABLE` errors or to plan whether to attempt CSS / Audit / Animation / Memory etc. methods.',
17
+ ].join(' '),
18
+ inputSchema: {},
19
+ handler: async () => {
20
+ let ps;
21
+ try {
22
+ ps = await PageSession.get();
23
+ }
24
+ catch (e) {
25
+ return errorResult(`Unable to attach: ${describe(e)}`);
26
+ }
27
+ const snap = await ps.capability();
28
+ const out = {
29
+ probedAt: snap.probedAt,
30
+ probeDurationMs: snap.probeDurationMs,
31
+ schemaProbeSucceeded: snap.schemaProbeSucceeded,
32
+ supportedDomains: snap.supportedDomains ? [...snap.supportedDomains].sort() : null,
33
+ sentinels: snap.sentinels,
34
+ notes: snap.notes,
35
+ attachInfo: ps.attachInfo
36
+ ? {
37
+ deviceOSVersion: ps.attachInfo.deviceOSVersion,
38
+ pageTitle: ps.attachInfo.pageTitle,
39
+ pageUrl: ps.attachInfo.pageUrl,
40
+ attachedAt: ps.attachInfo.attachedAt,
41
+ }
42
+ : null,
43
+ };
44
+ const text = '# get_capability_snapshot\n\n```json\n' + JSON.stringify(out, null, 2) + '\n```';
45
+ return { content: [{ type: 'text', text }] };
46
+ },
47
+ };
48
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
49
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
50
+ //# sourceMappingURL=get_capability_snapshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_capability_snapshot.js","sourceRoot":"","sources":["../../../src/tools/get_capability_snapshot.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,IAAI,EAAE,yBAAyB;IAC/B,WAAW,EAAE;QACX,uFAAuF;QACvF,4PAA4P;QAC5P,mIAAmI;KACpI,CAAC,IAAI,CAAC,GAAG,CAAC;IACX,WAAW,EAAE,EAAE;IACf,OAAO,EAAE,KAAK,IAAI,EAAE;QAClB,IAAI,EAAe,CAAC;QACpB,IAAI,CAAC;YAAC,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;QAAC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,WAAW,CAAC,qBAAqB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;QAC3G,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,UAAU,EAAE,CAAC;QACnC,MAAM,GAAG,GAAG;YACV,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,oBAAoB,EAAE,IAAI,CAAC,oBAAoB;YAC/C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI;YAClF,SAAS,EAAE,IAAI,CAAC,SAAS;YACzB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,UAAU,EAAE,EAAE,CAAC,UAAU;gBACvB,CAAC,CAAC;oBACE,eAAe,EAAE,EAAE,CAAC,UAAU,CAAC,eAAe;oBAC9C,SAAS,EAAE,EAAE,CAAC,UAAU,CAAC,SAAS;oBAClC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO;oBAC9B,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,UAAU;iBACrC;gBACH,CAAC,CAAC,IAAI;SACT,CAAC;QACF,MAAM,IAAI,GAAG,wCAAwC,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC;QAC/F,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;IACxD,CAAC;CACF,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;AAC5G,SAAS,QAAQ,CAAC,CAAU,IAAI,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ export declare const getConsoleMessageTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ index: z.ZodNumber;
7
+ argMaxLen: z.ZodOptional<z.ZodNumber>;
8
+ };
9
+ handler: ({ index, argMaxLen, }: {
10
+ index: number;
11
+ argMaxLen?: number;
12
+ }) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ }>;
18
+ };
@@ -0,0 +1,92 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const getConsoleMessageTool = {
4
+ name: 'get_console_message',
5
+ description: [
6
+ 'Return the full detail of a single console message from the rolling buffer (filled by `Console.messageAdded` + `Runtime.exceptionThrown`).',
7
+ 'Indexing: `index` is 0-based against the current buffer ordering (oldest → newest). Negative values count from the end (`-1` = newest).',
8
+ 'Returns level, source, text, url:line:col, full args (with truncation), and full stack trace if present.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ index: z
12
+ .number()
13
+ .int()
14
+ .describe('0-based index into the rolling console buffer. Negative counts from the end (-1 = newest).'),
15
+ argMaxLen: z
16
+ .number()
17
+ .int()
18
+ .min(50)
19
+ .max(20_000)
20
+ .optional()
21
+ .describe('Per-arg stringification cap (default 1000).'),
22
+ },
23
+ handler: async ({ index, argMaxLen = 1000, }) => {
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
+ const buf = ps.consoleBuffer;
32
+ if (buf.length === 0) {
33
+ return errorResult('Console buffer is empty. Trigger page activity and call again.');
34
+ }
35
+ let i = index;
36
+ if (i < 0)
37
+ i = buf.length + i;
38
+ if (i < 0 || i >= buf.length) {
39
+ return errorResult(`Index ${index} out of range (buffer has ${buf.length} entries; valid: 0..${buf.length - 1} or -${buf.length}..-1).`);
40
+ }
41
+ const e = buf[i];
42
+ const lines = [];
43
+ const ts = typeof e.timestamp === 'number' ? new Date(e.timestamp * 1000).toISOString() : '(no timestamp)';
44
+ lines.push(`# console[${i}] / ${i + 1}-of-${buf.length} · ${e.level} · ${e.source}`);
45
+ lines.push('');
46
+ lines.push(`Time: ${ts}`);
47
+ if (e.url)
48
+ lines.push(`At: ${e.url}${e.line != null ? `:${e.line}` : ''}${e.column != null ? `:${e.column}` : ''}`);
49
+ lines.push('');
50
+ lines.push('## text');
51
+ lines.push('```');
52
+ lines.push(e.text);
53
+ lines.push('```');
54
+ if (e.args && e.args.length > 0) {
55
+ lines.push('');
56
+ lines.push(`## args (${e.args.length})`);
57
+ e.args.forEach((arg, idx) => {
58
+ lines.push(`### args[${idx}]`);
59
+ lines.push('```json');
60
+ lines.push(safeStringify(arg, argMaxLen));
61
+ lines.push('```');
62
+ });
63
+ }
64
+ if (e.stackTrace) {
65
+ lines.push('');
66
+ lines.push('## stackTrace');
67
+ lines.push('```json');
68
+ lines.push(safeStringify(e.stackTrace, 5_000));
69
+ lines.push('```');
70
+ }
71
+ return textResult(lines.join('\n'));
72
+ },
73
+ };
74
+ function textResult(text) {
75
+ return { content: [{ type: 'text', text }] };
76
+ }
77
+ function errorResult(text) {
78
+ return { content: [{ type: 'text', text }], isError: true };
79
+ }
80
+ function describe(e) {
81
+ return e instanceof Error ? e.message : String(e);
82
+ }
83
+ function safeStringify(o, maxLen) {
84
+ try {
85
+ const s = JSON.stringify(o, null, 2);
86
+ return s && s.length > maxLen ? s.slice(0, maxLen) + `\n… (truncated, full length ${s.length})` : (s ?? String(o));
87
+ }
88
+ catch {
89
+ return String(o);
90
+ }
91
+ }
92
+ //# sourceMappingURL=get_console_message.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_console_message.js","sourceRoot":"","sources":["../../../src/tools/get_console_message.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { z } from 'zod';
2
+ export declare const getCookiesTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ urlSubstring: z.ZodOptional<z.ZodString>;
7
+ nameSubstring: z.ZodOptional<z.ZodString>;
8
+ limit: z.ZodOptional<z.ZodNumber>;
9
+ };
10
+ handler: ({ urlSubstring, nameSubstring, limit, }: {
11
+ urlSubstring?: string;
12
+ nameSubstring?: string;
13
+ limit?: number;
14
+ }) => Promise<{
15
+ content: {
16
+ type: "text";
17
+ text: string;
18
+ }[];
19
+ }>;
20
+ };
@@ -0,0 +1,59 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const getCookiesTool = {
4
+ name: 'get_cookies',
5
+ description: [
6
+ 'List cookies visible to the inspected iOS WebView page via WIP `Page.getCookies` (Apple-specific, probe-confirmed 2026-05-16).',
7
+ 'NOTE: WIP\'s `Network.*Cookies` methods are NOT exposed on iOS — only the `Page.getCookies` / `Page.deleteCookie` pair works. Filter by URL substring or domain locally.',
8
+ ].join(' '),
9
+ inputSchema: {
10
+ urlSubstring: z.string().optional().describe('Case-insensitive substring filter on cookie URL/domain.'),
11
+ nameSubstring: z.string().optional().describe('Case-insensitive substring filter on cookie name.'),
12
+ limit: z.number().int().min(1).max(500).optional().describe('Max cookies returned (default 100).'),
13
+ },
14
+ handler: async ({ urlSubstring, nameSubstring, limit = 100, }) => {
15
+ let ps;
16
+ try {
17
+ ps = await PageSession.get();
18
+ }
19
+ catch (e) {
20
+ return errorResult(`Unable to attach: ${describe(e)}`);
21
+ }
22
+ let r;
23
+ try {
24
+ r = await ps.session.send('Page.getCookies', undefined, 10_000);
25
+ }
26
+ catch (e) {
27
+ return errorResult(`Page.getCookies failed: ${describe(e)}`);
28
+ }
29
+ let cookies = r.cookies ?? [];
30
+ if (urlSubstring) {
31
+ const n = urlSubstring.toLowerCase();
32
+ cookies = cookies.filter(c => (`${c.domain ?? ''}${c.path ?? ''}`).toLowerCase().includes(n));
33
+ }
34
+ if (nameSubstring) {
35
+ const n = nameSubstring.toLowerCase();
36
+ cookies = cookies.filter(c => String(c.name ?? '').toLowerCase().includes(n));
37
+ }
38
+ const total = cookies.length;
39
+ cookies = cookies.slice(0, limit);
40
+ const lines = [`# get_cookies — ${cookies.length} of ${total} total`, ''];
41
+ if (cookies.length === 0) {
42
+ lines.push('(no cookies match filters)');
43
+ return textResult(lines.join('\n'));
44
+ }
45
+ lines.push('| name | value | domain | path | expires | secure | httpOnly | session |');
46
+ lines.push('|---|---|---|---|---|---|---|---|');
47
+ for (const c of cookies) {
48
+ const value = String(c.value ?? '');
49
+ const v = value.length > 40 ? value.slice(0, 40) + '…' : value;
50
+ const exp = typeof c.expires === 'number' && c.expires > 0 ? new Date(c.expires * 1000).toISOString().slice(0, 19) : '-';
51
+ lines.push(`| ${c.name} | ${v.replace(/\|/g, '\\|')} | ${c.domain ?? ''} | ${c.path ?? '/'} | ${exp} | ${c.secure ? '✓' : ''} | ${c.httpOnly ? '✓' : ''} | ${c.session ? '✓' : ''} |`);
52
+ }
53
+ return textResult(lines.join('\n'));
54
+ },
55
+ };
56
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
57
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
58
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
59
+ //# sourceMappingURL=get_cookies.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get_cookies.js","sourceRoot":"","sources":["../../../src/tools/get_cookies.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * `get_event_listeners` (batch-13 Must) — list event listeners bound to a DOM
3
+ * node via WIP `DOM.getEventListenersForNode`.
4
+ *
5
+ * Probe-confirmed 2026-05-17 (capability matrix v2): the method exists and
6
+ * returns `-32000 Missing node for given nodeId` when called without a valid
7
+ * id, so chain through DOM.getDocument → querySelector first.
8
+ *
9
+ * Returns one row per listener with type / useCapture / passive / sourceURL +
10
+ * line. Distinguishes inline (set via attribute) vs addEventListener.
11
+ */
12
+ import { z } from 'zod';
13
+ export declare const getEventListenersTool: {
14
+ name: string;
15
+ description: string;
16
+ inputSchema: {
17
+ selector: z.ZodString;
18
+ includeAncestors: z.ZodOptional<z.ZodBoolean>;
19
+ };
20
+ handler: ({ selector, includeAncestors }: {
21
+ selector: string;
22
+ includeAncestors?: boolean;
23
+ }) => Promise<{
24
+ content: {
25
+ type: "text";
26
+ text: string;
27
+ }[];
28
+ }>;
29
+ };