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,54 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const selectPageTool = {
4
+ name: 'select_page',
5
+ description: [
6
+ 'Switch the shared PageSession to a specific page id returned by `list_pages`.',
7
+ 'Default attach picks the first non-worker WKWebView page on the first device. Use this when multiple pages exist (host app keeps several WKWebView instances) or to target a JSCore worker explicitly.',
8
+ 'Side effects: closes the current ws, drops console/network buffers, re-runs Console.enable / Network.enable / Runtime.enable on the new target. Existing PageSession state is NOT preserved.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ pageId: z.string().min(1).describe('Target page id from `list_pages` (e.g. "7").'),
12
+ proxyDeviceListUrl: z
13
+ .string()
14
+ .url()
15
+ .optional()
16
+ .describe('Override `ios_webkit_debug_proxy` device-list URL (default http://127.0.0.1:9221).'),
17
+ },
18
+ handler: async ({ pageId, proxyDeviceListUrl, }) => {
19
+ PageSession.reset();
20
+ let ps;
21
+ try {
22
+ ps = await PageSession.get({ pageId, proxyDeviceListUrl });
23
+ }
24
+ catch (e) {
25
+ return errorResult(`Failed to attach to pageId ${JSON.stringify(pageId)}: ${describe(e)}`);
26
+ }
27
+ const info = ps.attachInfo;
28
+ const lines = [
29
+ `# select_page ✓ pageId=${info.pageId}`,
30
+ '',
31
+ `Title: ${info.pageTitle || '(no title)'}`,
32
+ `URL: ${info.pageUrl || '(no url)'}`,
33
+ `Device: ${info.deviceId.slice(0, 12)}… · iOS ${info.deviceOSVersion ?? '?'}`,
34
+ `Attached at: ${new Date(info.attachedAt).toISOString()}`,
35
+ ];
36
+ if (ps.enableErrors.length > 0) {
37
+ lines.push('');
38
+ lines.push(`⚠ enable errors on new target: ${ps.enableErrors.map(e => `${e.method}(${e.error})`).join(', ')}`);
39
+ }
40
+ lines.push('');
41
+ lines.push('Console / Network buffers reset. Trigger page activity then re-read.');
42
+ return textResult(lines.join('\n'));
43
+ },
44
+ };
45
+ function textResult(text) {
46
+ return { content: [{ type: 'text', text }] };
47
+ }
48
+ function errorResult(text) {
49
+ return { content: [{ type: 'text', text }], isError: true };
50
+ }
51
+ function describe(e) {
52
+ return e instanceof Error ? e.message : String(e);
53
+ }
54
+ //# sourceMappingURL=select_page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"select_page.js","sourceRoot":"","sources":["../../../src/tools/select_page.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,IAAI,EAAE,aAAa;IACnB,WAAW,EAAE;QACX,+EAA+E;QAC/E,wMAAwM;QACxM,8LAA8L;KAC/L,CAAC,IAAI,CAAC,GAAG,CAAC;IAEX,WAAW,EAAE;QACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,8CAA8C,CAAC;QAClF,kBAAkB,EAAE,CAAC;aAClB,MAAM,EAAE;aACR,GAAG,EAAE;aACL,QAAQ,EAAE;aACV,QAAQ,CAAC,oFAAoF,CAAC;KAClG;IAED,OAAO,EAAE,KAAK,EAAE,EACd,MAAM,EACN,kBAAkB,GAInB,EAAE,EAAE;QACH,WAAW,CAAC,KAAK,EAAE,CAAC;QACpB,IAAI,EAAe,CAAC;QACpB,IAAI,CAAC;YACH,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,8BAA8B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7F,CAAC;QAED,MAAM,IAAI,GAAG,EAAE,CAAC,UAAW,CAAC;QAC5B,MAAM,KAAK,GAAG;YACZ,0BAA0B,IAAI,CAAC,MAAM,EAAE;YACvC,EAAE;YACF,UAAU,IAAI,CAAC,SAAS,IAAI,YAAY,EAAE;YAC1C,QAAQ,IAAI,CAAC,OAAO,IAAI,UAAU,EAAE;YACpC,WAAW,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,WAAW,IAAI,CAAC,eAAe,IAAI,GAAG,EAAE;YAC7E,gBAAgB,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE,EAAE;SAC1D,CAAC;QACF,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,KAAK,CAAC,IAAI,CACR,kCAAkC,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CACnG,CAAC;QACJ,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,sEAAsE,CAAC,CAAC;QACnF,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AACD,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AACD,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export declare const setExtraHttpHeadersTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ headers: z.ZodRecord<z.ZodString, z.ZodString>;
7
+ };
8
+ handler: ({ headers }: {
9
+ headers: Record<string, string>;
10
+ }) => Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ };
@@ -0,0 +1,55 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const setExtraHttpHeadersTool = {
4
+ name: 'set_extra_http_headers',
5
+ description: [
6
+ 'Set extra HTTP headers attached to every subsequent request issued by the inspected iOS WebView page. Wraps WIP `Network.setExtraHTTPHeaders` (one of the few `Network.*` methods present on WIP — verified 2026-05-16 probe).',
7
+ 'Use this to inject `Authorization` / `X-User-Id` / experiment-bucket headers when debugging gated APIs.',
8
+ 'NOTE: WIP does NOT expose `Network.setUserAgentOverride` or any other Emulation domain (probe ❌ NOT_FOUND). For UA override on iOS, use the dedicated `set_user_agent` tool (Apple WIP `Page.overrideUserAgent` + reload).',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ headers: z
12
+ .record(z.string())
13
+ .describe('Header name → value map. Pass `{}` to clear previously-set extras.'),
14
+ },
15
+ handler: async ({ headers }) => {
16
+ let ps;
17
+ try {
18
+ ps = await PageSession.get();
19
+ }
20
+ catch (e) {
21
+ return errorResult(`Unable to attach to a WKWebView page: ${describe(e)}`);
22
+ }
23
+ try {
24
+ await ps.session.send('Network.setExtraHTTPHeaders', { headers }, 5_000);
25
+ }
26
+ catch (e) {
27
+ return errorResult(`Network.setExtraHTTPHeaders failed: ${describe(e)}`);
28
+ }
29
+ const lines = [
30
+ `# set_extra_http_headers ✓ ${Object.keys(headers).length} header(s)`,
31
+ '',
32
+ ];
33
+ if (Object.keys(headers).length === 0) {
34
+ lines.push('(Cleared all previously-set extra headers.)');
35
+ }
36
+ else {
37
+ for (const [k, v] of Object.entries(headers)) {
38
+ lines.push(`- ${k}: ${v}`);
39
+ }
40
+ }
41
+ lines.push('');
42
+ lines.push('Applies to subsequent requests from the page only. Already-issued requests are unaffected.');
43
+ return textResult(lines.join('\n'));
44
+ },
45
+ };
46
+ function textResult(text) {
47
+ return { content: [{ type: 'text', text }] };
48
+ }
49
+ function errorResult(text) {
50
+ return { content: [{ type: 'text', text }], isError: true };
51
+ }
52
+ function describe(e) {
53
+ return e instanceof Error ? e.message : String(e);
54
+ }
55
+ //# sourceMappingURL=set_extra_http_headers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set_extra_http_headers.js","sourceRoot":"","sources":["../../../src/tools/set_extra_http_headers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,IAAI,EAAE,wBAAwB;IAC9B,WAAW,EAAE;QACX,gOAAgO;QAChO,yGAAyG;QACzG,4NAA4N;KAC7N,CAAC,IAAI,CAAC,GAAG,CAAC;IAEX,WAAW,EAAE;QACX,OAAO,EAAE,CAAC;aACP,MAAM,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;aAClB,QAAQ,CAAC,oEAAoE,CAAC;KAClF;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,OAAO,EAAuC,EAAE,EAAE;QAClE,IAAI,EAAe,CAAC;QACpB,IAAI,CAAC;YACH,EAAE,GAAG,MAAM,WAAW,CAAC,GAAG,EAAE,CAAC;QAC/B,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,yCAAyC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,6BAA6B,EAAE,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3E,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,WAAW,CAAC,uCAAuC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3E,CAAC;QAED,MAAM,KAAK,GAAG;YACZ,8BAA8B,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,YAAY;YACrE,EAAE;SACH,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACtC,KAAK,CAAC,IAAI,CAAC,6CAA6C,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7C,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC7B,CAAC;QACH,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,4FAA4F,CAAC,CAAC;QACzG,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;AACxD,CAAC;AACD,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;AACvE,CAAC;AACD,SAAS,QAAQ,CAAC,CAAU;IAC1B,OAAO,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AACpD,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { z } from 'zod';
2
+ export declare const setInitScriptTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ source: z.ZodString;
7
+ };
8
+ handler: ({ source }: {
9
+ source: string;
10
+ }) => Promise<{
11
+ content: {
12
+ type: "text";
13
+ text: string;
14
+ }[];
15
+ }>;
16
+ };
@@ -0,0 +1,43 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const setInitScriptTool = {
4
+ name: 'set_init_script',
5
+ description: [
6
+ 'Install a JavaScript snippet that runs on EVERY subsequent navigation of the inspected iOS WebView page via WIP `Page.setBootstrapScript` (Apple-specific, probe-confirmed 2026-05-16).',
7
+ 'NOTE: WIP does NOT expose `Page.addScriptToEvaluateOnNewDocument` (the chrome-devtools-mcp counterpart) — `Page.setBootstrapScript` is the Apple equivalent. Only ONE script can be active at a time; calling again replaces the previous one. Pass `source=""` (empty) to clear.',
8
+ 'Useful for persistent test hooks (e.g. install `handle_dialog` overrides before every page load).',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ source: z.string().describe('JavaScript source to run on each navigation. Empty string clears the bootstrap script.'),
12
+ },
13
+ handler: async ({ source }) => {
14
+ let ps;
15
+ try {
16
+ ps = await PageSession.get();
17
+ }
18
+ catch (e) {
19
+ return errorResult(`Unable to attach: ${describe(e)}`);
20
+ }
21
+ try {
22
+ await ps.session.send('Page.setBootstrapScript', { source }, 10_000);
23
+ }
24
+ catch (e) {
25
+ return errorResult(`Page.setBootstrapScript failed: ${describe(e)}`);
26
+ }
27
+ const lines = [`# set_init_script ✓ ${source.length === 0 ? '(cleared)' : `${source.length} char(s) installed`}`, ''];
28
+ if (source.length > 0) {
29
+ const preview = source.length > 200 ? source.slice(0, 200) + '…' : source;
30
+ lines.push('## installed snippet (preview)');
31
+ lines.push('```js');
32
+ lines.push(preview);
33
+ lines.push('```');
34
+ }
35
+ lines.push('');
36
+ lines.push('Runs on EVERY subsequent navigation (incl. SPA programmatic ones if they trigger document reload). One script max — recall to replace.');
37
+ return textResult(lines.join('\n'));
38
+ },
39
+ };
40
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
41
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
42
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
43
+ //# sourceMappingURL=set_init_script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set_init_script.js","sourceRoot":"","sources":["../../../src/tools/set_init_script.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAEjD,MAAM,CAAC,MAAM,iBAAiB,GAAG;IAC/B,IAAI,EAAE,iBAAiB;IACvB,WAAW,EAAE;QACX,yLAAyL;QACzL,mRAAmR;QACnR,mGAAmG;KACpG,CAAC,IAAI,CAAC,GAAG,CAAC;IAEX,WAAW,EAAE;QACX,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,wFAAwF,CAAC;KACtH;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,MAAM,EAAsB,EAAE,EAAE;QAChD,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,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;QAAC,CAAC;QAC7E,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,WAAW,CAAC,mCAAmC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;QACnF,MAAM,KAAK,GAAG,CAAC,uBAAuB,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,oBAAoB,EAAE,EAAE,EAAE,CAAC,CAAC;QACtH,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC;YAC1E,KAAK,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;YAC7C,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACpB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACf,KAAK,CAAC,IAAI,CAAC,wIAAwI,CAAC,CAAC;QACrJ,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IACtC,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5F,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 setOuterHtmlTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ selector: z.ZodString;
7
+ outerHTML: z.ZodString;
8
+ };
9
+ handler: ({ selector, outerHTML }: {
10
+ selector: string;
11
+ outerHTML: string;
12
+ }) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ }>;
18
+ };
@@ -0,0 +1,52 @@
1
+ import { z } from 'zod';
2
+ import { PageSession } from '../page-session.js';
3
+ export const setOuterHtmlTool = {
4
+ name: 'set_outer_html',
5
+ description: [
6
+ 'Replace an element\'s outerHTML in place on the inspected iOS WebView page via WIP `DOM.setOuterHTML` (Apple-specific, probe-confirmed 2026-05-16).',
7
+ 'Resolves selector → nodeId via `DOM.getDocument` + `DOM.querySelector` then sets new HTML. Useful for fix-in-place experiments (test a CSS tweak / fix a typo without reload).',
8
+ 'WARNING: mutates the live DOM — if the page later re-renders via React/Vue/Lynx, your patch is lost. Treat as a one-shot probe, not a persistent fix.',
9
+ ].join(' '),
10
+ inputSchema: {
11
+ selector: z.string().min(1).describe('CSS selector for the element to replace.'),
12
+ outerHTML: z.string().describe('New outerHTML to substitute in. Must be a single root element.'),
13
+ },
14
+ handler: async ({ selector, outerHTML }) => {
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 nodeId;
23
+ try {
24
+ const doc = await ps.session.send('DOM.getDocument', { depth: 0 }, 10_000);
25
+ const qs = await ps.session.send('DOM.querySelector', { nodeId: doc.root.nodeId, selector }, 10_000);
26
+ if (qs.nodeId === 0)
27
+ return errorResult(`# set_outer_html — no match for \`${selector}\``);
28
+ nodeId = qs.nodeId;
29
+ }
30
+ catch (e) {
31
+ return errorResult(`DOM resolve failed: ${describe(e)}`);
32
+ }
33
+ try {
34
+ await ps.session.send('DOM.setOuterHTML', { nodeId, outerHTML }, 10_000);
35
+ }
36
+ catch (e) {
37
+ return errorResult(`DOM.setOuterHTML failed: ${describe(e)}`);
38
+ }
39
+ return textResult([
40
+ `# set_outer_html ✓`,
41
+ '',
42
+ `selector: \`${selector}\` (nodeId=${nodeId})`,
43
+ `new HTML: ${outerHTML.length} bytes`,
44
+ '',
45
+ '⚠ Live DOM mutated. If the page re-renders via framework, your patch will be overwritten. For persistent patches use `set_init_script`.',
46
+ ].join('\n'));
47
+ },
48
+ };
49
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
50
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
51
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
52
+ //# sourceMappingURL=set_outer_html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set_outer_html.js","sourceRoot":"","sources":["../../../src/tools/set_outer_html.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAKjD,MAAM,CAAC,MAAM,gBAAgB,GAAG;IAC9B,IAAI,EAAE,gBAAgB;IACtB,WAAW,EAAE;QACX,qJAAqJ;QACrJ,gLAAgL;QAChL,uJAAuJ;KACxJ,CAAC,IAAI,CAAC,GAAG,CAAC;IAEX,WAAW,EAAE;QACX,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,0CAA0C,CAAC;QAChF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,gEAAgE,CAAC;KACjG;IAED,OAAO,EAAE,KAAK,EAAE,EAAE,QAAQ,EAAE,SAAS,EAA2C,EAAE,EAAE;QAClF,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;QAE3G,IAAI,MAAc,CAAC;QACnB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAe,iBAAiB,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACzF,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAc,mBAAmB,EAAE,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,EAAE,MAAM,CAAC,CAAC;YAClH,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,WAAW,CAAC,qCAAqC,QAAQ,IAAI,CAAC,CAAC;YAC3F,MAAM,GAAG,EAAE,CAAC,MAAM,CAAC;QACrB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,WAAW,CAAC,uBAAuB,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;QAEzE,IAAI,CAAC;YAAC,MAAM,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,MAAM,EAAE,SAAS,EAAE,EAAE,MAAM,CAAC,CAAC;QAAC,CAAC;QACjF,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,WAAW,CAAC,4BAA4B,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAAC,CAAC;QAE5E,OAAO,UAAU,CACf;YACE,oBAAoB;YACpB,EAAE;YACF,eAAe,QAAQ,cAAc,MAAM,GAAG;YAC9C,aAAa,SAAS,CAAC,MAAM,QAAQ;YACrC,EAAE;YACF,yIAAyI;SAC1I,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IACJ,CAAC;CACF,CAAC;AAEF,SAAS,UAAU,CAAC,IAAY,IAAI,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;AAC5F,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,40 @@
1
+ /**
2
+ * `set_user_agent` (batch-14, Apple WIP `Page.overrideUserAgent`).
3
+ *
4
+ * Probe-confirmed (2026-05-17) on iOS 26.5.0 + Apple system WKWebView:
5
+ * - Method exists; `Page.overrideUserAgent({value})` returns `{}` immediately.
6
+ * - **Override applies on next navigation only** — `navigator.userAgent` and
7
+ * outgoing request `User-Agent` header keep the OLD value until the page
8
+ * reloads. Setting + reloading: navigator.userAgent + first xhs fetch
9
+ * header both showed `wdm-probe/2.0` ✅.
10
+ *
11
+ * This tool eliminates the spec §"Future optimization §1" claim that UA
12
+ * override required a host-side native bridge — Page.overrideUserAgent
13
+ * is the official upstream answer (no condition / always available, see
14
+ * `Source/JavaScriptCore/inspector/protocol/Page.json`).
15
+ *
16
+ * Semantics:
17
+ * - `value: <non-empty string>` → set override, default-reload to apply
18
+ * - `value: ""` or omitted → clear override (default-reload to restore)
19
+ * - `reload: false` → don't reload; user must reload manually for change
20
+ * to take effect (rare — useful when chaining several overrides before a
21
+ * single reload).
22
+ */
23
+ import { z } from 'zod';
24
+ export declare const setUserAgentTool: {
25
+ name: string;
26
+ description: string;
27
+ inputSchema: {
28
+ value: z.ZodOptional<z.ZodString>;
29
+ reload: z.ZodOptional<z.ZodBoolean>;
30
+ };
31
+ handler: ({ value, reload }: {
32
+ value?: string;
33
+ reload?: boolean;
34
+ }) => Promise<{
35
+ content: {
36
+ type: "text";
37
+ text: string;
38
+ }[];
39
+ }>;
40
+ };
@@ -0,0 +1,83 @@
1
+ /**
2
+ * `set_user_agent` (batch-14, Apple WIP `Page.overrideUserAgent`).
3
+ *
4
+ * Probe-confirmed (2026-05-17) on iOS 26.5.0 + Apple system WKWebView:
5
+ * - Method exists; `Page.overrideUserAgent({value})` returns `{}` immediately.
6
+ * - **Override applies on next navigation only** — `navigator.userAgent` and
7
+ * outgoing request `User-Agent` header keep the OLD value until the page
8
+ * reloads. Setting + reloading: navigator.userAgent + first xhs fetch
9
+ * header both showed `wdm-probe/2.0` ✅.
10
+ *
11
+ * This tool eliminates the spec §"Future optimization §1" claim that UA
12
+ * override required a host-side native bridge — Page.overrideUserAgent
13
+ * is the official upstream answer (no condition / always available, see
14
+ * `Source/JavaScriptCore/inspector/protocol/Page.json`).
15
+ *
16
+ * Semantics:
17
+ * - `value: <non-empty string>` → set override, default-reload to apply
18
+ * - `value: ""` or omitted → clear override (default-reload to restore)
19
+ * - `reload: false` → don't reload; user must reload manually for change
20
+ * to take effect (rare — useful when chaining several overrides before a
21
+ * single reload).
22
+ */
23
+ import { z } from 'zod';
24
+ import { PageSession } from '../page-session.js';
25
+ export const setUserAgentTool = {
26
+ name: 'set_user_agent',
27
+ description: [
28
+ 'Override the User-Agent header on the inspected iOS WebView page via WIP `Page.overrideUserAgent` (✅ probe 2026-05-17).',
29
+ 'Override applies on next navigation only — this tool reloads the page by default (`reload: true`) so the change takes effect immediately. After reload, both `navigator.userAgent` (JS) and outgoing `User-Agent` request header (network) reflect the new value.',
30
+ 'Pass `value: ""` (empty) to clear the override and restore the original WebKit UA. Pass `reload: false` if you plan to chain other overrides before reloading.',
31
+ ].join(' '),
32
+ inputSchema: {
33
+ value: z.string().optional().describe('UA string to send. Empty / omitted = clear override.'),
34
+ reload: z
35
+ .boolean()
36
+ .optional()
37
+ .describe('Reload the page after setting (default true). Set false if chaining multiple overrides for a single reload.'),
38
+ },
39
+ handler: async ({ value = '', reload = true }) => {
40
+ let ps;
41
+ try {
42
+ ps = await PageSession.get();
43
+ }
44
+ catch (e) {
45
+ return errorResult(`Unable to attach: ${describe(e)}`);
46
+ }
47
+ // Page.enable is idempotent; ensure it lazily.
48
+ try {
49
+ await ps.session.send('Page.enable', undefined, 5_000);
50
+ }
51
+ catch { /* ignore */ }
52
+ try {
53
+ await ps.session.send('Page.overrideUserAgent', { value }, 5_000);
54
+ }
55
+ catch (e) {
56
+ return errorResult(`Page.overrideUserAgent failed: ${describe(e)}`);
57
+ }
58
+ let reloadResult = '';
59
+ if (reload) {
60
+ try {
61
+ await ps.session.send('Page.reload', { ignoreCache: true }, 10_000);
62
+ // Allow main document to start loading before tool returns.
63
+ await new Promise(r => setTimeout(r, 800));
64
+ reloadResult = '\nPage reloaded; UA now in effect on this navigation onward.';
65
+ }
66
+ catch (e) {
67
+ reloadResult = `\n⚠ Page.reload failed: ${describe(e)} — UA override is queued; manually reload to apply.`;
68
+ }
69
+ }
70
+ else {
71
+ reloadResult = '\n⚠ `reload: false` — UA override queued; will take effect on the next navigation.';
72
+ }
73
+ if (!value) {
74
+ return textResult(`# set_user_agent ✓ cleared\n\nUser-Agent override removed. WebKit will use its default UA on next navigation.${reloadResult}`);
75
+ }
76
+ return textResult(`# set_user_agent ✓ \`${value.length > 80 ? value.slice(0, 77) + '…' : value}\`\n\n` +
77
+ `Override registered via \`Page.overrideUserAgent\`.${reloadResult}`);
78
+ },
79
+ };
80
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
81
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
82
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
83
+ //# sourceMappingURL=set_user_agent.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"set_user_agent.js","sourceRoot":"","sources":["../../../src/tools/set_user_agent.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * `summarize_console_errors` (batch-14 composite, fka `fix_console_errors` in
3
+ * cross-review v2.0.1 — renamed because the tool surfaces signals; "fixing" is
4
+ * LLM-side work).
5
+ *
6
+ * Reads `PageSession.consoleBuffer` directly (already populated by the
7
+ * `Console.messageAdded` + `Runtime.exceptionThrown` subscribers in
8
+ * `PageSession.init`), filters to warning/error level, groups by message
9
+ * similarity (first 80 chars of `text` + url:line), returns top-N groups by
10
+ * frequency with one stack trace each.
11
+ *
12
+ * Useful when the AI agent asks "what's broken here?" — saves it from paging
13
+ * through `list_console_messages` + N × `get_console_message`.
14
+ */
15
+ import { z } from 'zod';
16
+ import { type ConsoleEntry } from '../page-session.js';
17
+ export declare const summarizeConsoleErrorsTool: {
18
+ name: string;
19
+ description: string;
20
+ inputSchema: {
21
+ minLevel: z.ZodOptional<z.ZodEnum<["log", "info", "warning", "error"]>>;
22
+ topN: z.ZodOptional<z.ZodNumber>;
23
+ includeStackTrace: z.ZodOptional<z.ZodBoolean>;
24
+ };
25
+ handler: ({ minLevel, topN, includeStackTrace }: {
26
+ minLevel?: "log" | "info" | "warning" | "error";
27
+ topN?: number;
28
+ includeStackTrace?: boolean;
29
+ }) => Promise<{
30
+ content: {
31
+ type: "text";
32
+ text: string;
33
+ }[];
34
+ }>;
35
+ };
36
+ export declare const LEVEL_RANK: Record<string, number>;
37
+ export declare function _normalizeLevel(level: string): 'log' | 'info' | 'warning' | 'error';
38
+ export declare function _groupKey(e: ConsoleEntry): string;
39
+ export declare function _extractFrames(stackTrace: unknown): string[];
40
+ export declare function _truncate(s: string, n: number): string;
@@ -0,0 +1,131 @@
1
+ /**
2
+ * `summarize_console_errors` (batch-14 composite, fka `fix_console_errors` in
3
+ * cross-review v2.0.1 — renamed because the tool surfaces signals; "fixing" is
4
+ * LLM-side work).
5
+ *
6
+ * Reads `PageSession.consoleBuffer` directly (already populated by the
7
+ * `Console.messageAdded` + `Runtime.exceptionThrown` subscribers in
8
+ * `PageSession.init`), filters to warning/error level, groups by message
9
+ * similarity (first 80 chars of `text` + url:line), returns top-N groups by
10
+ * frequency with one stack trace each.
11
+ *
12
+ * Useful when the AI agent asks "what's broken here?" — saves it from paging
13
+ * through `list_console_messages` + N × `get_console_message`.
14
+ */
15
+ import { z } from 'zod';
16
+ import { PageSession } from '../page-session.js';
17
+ export const summarizeConsoleErrorsTool = {
18
+ name: 'summarize_console_errors',
19
+ description: [
20
+ 'Summarize buffered console errors and warnings on the inspected iOS WebView page: filter level ≥ warning, group by message similarity (text + source location), return top-N groups by frequency with one representative stack trace each.',
21
+ 'Reads from PageSession in-memory buffer (default cap 200 entries). Older entries are evicted as new ones arrive.',
22
+ 'Use as a one-call "what is broken here?" — saves N × `get_console_message` round-trips. Pair with `clear_console` if you want a clean window after a fix attempt.',
23
+ ].join(' '),
24
+ inputSchema: {
25
+ minLevel: z
26
+ .enum(['log', 'info', 'warning', 'error'])
27
+ .optional()
28
+ .describe('Minimum severity to include (default `warning`).'),
29
+ topN: z
30
+ .number()
31
+ .int()
32
+ .min(1)
33
+ .max(50)
34
+ .optional()
35
+ .describe('Top-N groups by frequency (default 10).'),
36
+ includeStackTrace: z
37
+ .boolean()
38
+ .optional()
39
+ .describe('Include the first occurrence\'s stack trace per group (default true). Set false for compact output.'),
40
+ },
41
+ handler: async ({ minLevel = 'warning', topN = 10, includeStackTrace = true }) => {
42
+ let ps;
43
+ try {
44
+ ps = await PageSession.get();
45
+ }
46
+ catch (e) {
47
+ return errorResult(`Unable to attach: ${describe(e)}`);
48
+ }
49
+ const minRank = LEVEL_RANK[minLevel];
50
+ const filtered = ps.consoleBuffer.filter(e => (LEVEL_RANK[_normalizeLevel(e.level)] ?? -1) >= minRank);
51
+ if (filtered.length === 0) {
52
+ return textResult(`# summarize_console_errors\n\nNo entries at level ≥ ${minLevel} in the current buffer (${ps.consoleBuffer.length} total entries).`);
53
+ }
54
+ const groups = new Map();
55
+ for (const e of filtered) {
56
+ const key = _groupKey(e);
57
+ const cur = groups.get(key);
58
+ if (cur)
59
+ cur.count += 1;
60
+ else
61
+ groups.set(key, { count: 1, first: e, level: _normalizeLevel(e.level) });
62
+ }
63
+ const sorted = [...groups.entries()]
64
+ .sort((a, b) => b[1].count - a[1].count)
65
+ .slice(0, topN);
66
+ const lines = [
67
+ `# summarize_console_errors — ${filtered.length} entries (≥ ${minLevel})`,
68
+ '',
69
+ `Groups: ${groups.size}, showing top ${sorted.length}.`,
70
+ '',
71
+ ];
72
+ for (const [, { count, first, level }] of sorted) {
73
+ lines.push(`## [${level}] × ${count} — \`${_truncate(first.text, 100)}\``);
74
+ const loc = formatLoc(first);
75
+ if (loc)
76
+ lines.push(loc);
77
+ if (includeStackTrace && first.stackTrace) {
78
+ const frames = _extractFrames(first.stackTrace);
79
+ if (frames.length > 0) {
80
+ lines.push('');
81
+ lines.push('```');
82
+ for (const f of frames.slice(0, 8))
83
+ lines.push(f);
84
+ if (frames.length > 8)
85
+ lines.push(`… ${frames.length - 8} more frames`);
86
+ lines.push('```');
87
+ }
88
+ }
89
+ lines.push('');
90
+ }
91
+ return textResult(lines.join('\n'));
92
+ },
93
+ };
94
+ // Helpers exported for tests (underscore prefix = internal but reachable).
95
+ export const LEVEL_RANK = { log: 0, info: 1, warning: 2, error: 3 };
96
+ export function _normalizeLevel(level) {
97
+ if (level === 'error')
98
+ return 'error';
99
+ if (level === 'warning' || level === 'warn')
100
+ return 'warning';
101
+ if (level === 'info')
102
+ return 'info';
103
+ return 'log';
104
+ }
105
+ export function _groupKey(e) {
106
+ const text = (e.text || '').slice(0, 80).trim().replace(/\s+/g, ' ');
107
+ const loc = e.url ? `${e.url}:${e.line ?? '?'}` : '(no-loc)';
108
+ return `${text}|${loc}`;
109
+ }
110
+ function formatLoc(e) {
111
+ if (!e.url)
112
+ return '';
113
+ return `Source: \`${e.url}\`${e.line !== undefined ? `:${e.line}` : ''}${e.column !== undefined ? `:${e.column}` : ''}`;
114
+ }
115
+ export function _extractFrames(stackTrace) {
116
+ if (!stackTrace || typeof stackTrace !== 'object')
117
+ return [];
118
+ const st = stackTrace;
119
+ if (!Array.isArray(st.callFrames))
120
+ return [];
121
+ return st.callFrames.map(f => ` at ${f.functionName || '<anon>'} (${f.url || '?'}:${f.lineNumber ?? '?'}:${f.columnNumber ?? '?'})`);
122
+ }
123
+ export function _truncate(s, n) {
124
+ if (!s)
125
+ return '';
126
+ return s.length > n ? s.slice(0, n - 1) + '…' : s;
127
+ }
128
+ function textResult(text) { return { content: [{ type: 'text', text }] }; }
129
+ function errorResult(text) { return { content: [{ type: 'text', text }], isError: true }; }
130
+ function describe(e) { return e instanceof Error ? e.message : String(e); }
131
+ //# sourceMappingURL=summarize_console_errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"summarize_console_errors.js","sourceRoot":"","sources":["../../../src/tools/summarize_console_errors.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import { z } from 'zod';
2
+ export declare const takeMemorySnapshotTool: {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: {
6
+ includeRaw: z.ZodOptional<z.ZodBoolean>;
7
+ maxRawChars: z.ZodOptional<z.ZodNumber>;
8
+ };
9
+ handler: ({ includeRaw, maxRawChars, }: {
10
+ includeRaw?: boolean;
11
+ maxRawChars?: number;
12
+ }) => Promise<{
13
+ content: {
14
+ type: "text";
15
+ text: string;
16
+ }[];
17
+ }>;
18
+ };