deepadb 1.0.0

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 (247) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +631 -0
  3. package/build/bridge/adb-bridge.d.ts +65 -0
  4. package/build/bridge/adb-bridge.d.ts.map +1 -0
  5. package/build/bridge/adb-bridge.js +164 -0
  6. package/build/bridge/adb-bridge.js.map +1 -0
  7. package/build/bridge/device-manager.d.ts +41 -0
  8. package/build/bridge/device-manager.d.ts.map +1 -0
  9. package/build/bridge/device-manager.js +109 -0
  10. package/build/bridge/device-manager.js.map +1 -0
  11. package/build/bridge/local-bridge.d.ts +92 -0
  12. package/build/bridge/local-bridge.d.ts.map +1 -0
  13. package/build/bridge/local-bridge.js +345 -0
  14. package/build/bridge/local-bridge.js.map +1 -0
  15. package/build/config/config.d.ts +39 -0
  16. package/build/config/config.d.ts.map +1 -0
  17. package/build/config/config.js +84 -0
  18. package/build/config/config.js.map +1 -0
  19. package/build/graphql-api.d.ts +36 -0
  20. package/build/graphql-api.d.ts.map +1 -0
  21. package/build/graphql-api.js +296 -0
  22. package/build/graphql-api.js.map +1 -0
  23. package/build/http-transport.d.ts +26 -0
  24. package/build/http-transport.d.ts.map +1 -0
  25. package/build/http-transport.js +105 -0
  26. package/build/http-transport.js.map +1 -0
  27. package/build/index.d.ts +14 -0
  28. package/build/index.d.ts.map +1 -0
  29. package/build/index.js +66 -0
  30. package/build/index.js.map +1 -0
  31. package/build/middleware/chipset.d.ts +29 -0
  32. package/build/middleware/chipset.d.ts.map +1 -0
  33. package/build/middleware/chipset.js +123 -0
  34. package/build/middleware/chipset.js.map +1 -0
  35. package/build/middleware/cleanup.d.ts +24 -0
  36. package/build/middleware/cleanup.d.ts.map +1 -0
  37. package/build/middleware/cleanup.js +53 -0
  38. package/build/middleware/cleanup.js.map +1 -0
  39. package/build/middleware/fetch-utils.d.ts +19 -0
  40. package/build/middleware/fetch-utils.d.ts.map +1 -0
  41. package/build/middleware/fetch-utils.js +64 -0
  42. package/build/middleware/fetch-utils.js.map +1 -0
  43. package/build/middleware/logger.d.ts +17 -0
  44. package/build/middleware/logger.d.ts.map +1 -0
  45. package/build/middleware/logger.js +38 -0
  46. package/build/middleware/logger.js.map +1 -0
  47. package/build/middleware/output-processor.d.ts +57 -0
  48. package/build/middleware/output-processor.d.ts.map +1 -0
  49. package/build/middleware/output-processor.js +162 -0
  50. package/build/middleware/output-processor.js.map +1 -0
  51. package/build/middleware/sanitize.d.ts +30 -0
  52. package/build/middleware/sanitize.d.ts.map +1 -0
  53. package/build/middleware/sanitize.js +46 -0
  54. package/build/middleware/sanitize.js.map +1 -0
  55. package/build/middleware/security.d.ts +52 -0
  56. package/build/middleware/security.d.ts.map +1 -0
  57. package/build/middleware/security.js +123 -0
  58. package/build/middleware/security.js.map +1 -0
  59. package/build/middleware/ui-dump.d.ts +23 -0
  60. package/build/middleware/ui-dump.d.ts.map +1 -0
  61. package/build/middleware/ui-dump.js +59 -0
  62. package/build/middleware/ui-dump.js.map +1 -0
  63. package/build/server.d.ts +18 -0
  64. package/build/server.d.ts.map +1 -0
  65. package/build/server.js +133 -0
  66. package/build/server.js.map +1 -0
  67. package/build/tool-context.d.ts +22 -0
  68. package/build/tool-context.d.ts.map +1 -0
  69. package/build/tool-context.js +9 -0
  70. package/build/tool-context.js.map +1 -0
  71. package/build/tools/accessibility.d.ts +10 -0
  72. package/build/tools/accessibility.d.ts.map +1 -0
  73. package/build/tools/accessibility.js +259 -0
  74. package/build/tools/accessibility.js.map +1 -0
  75. package/build/tools/at-commands.d.ts +20 -0
  76. package/build/tools/at-commands.d.ts.map +1 -0
  77. package/build/tools/at-commands.js +378 -0
  78. package/build/tools/at-commands.js.map +1 -0
  79. package/build/tools/baseband.d.ts +15 -0
  80. package/build/tools/baseband.d.ts.map +1 -0
  81. package/build/tools/baseband.js +323 -0
  82. package/build/tools/baseband.js.map +1 -0
  83. package/build/tools/build.d.ts +6 -0
  84. package/build/tools/build.d.ts.map +1 -0
  85. package/build/tools/build.js +80 -0
  86. package/build/tools/build.js.map +1 -0
  87. package/build/tools/ci.d.ts +9 -0
  88. package/build/tools/ci.d.ts.map +1 -0
  89. package/build/tools/ci.js +163 -0
  90. package/build/tools/ci.js.map +1 -0
  91. package/build/tools/control.d.ts +10 -0
  92. package/build/tools/control.d.ts.map +1 -0
  93. package/build/tools/control.js +197 -0
  94. package/build/tools/control.js.map +1 -0
  95. package/build/tools/device-farm.d.ts +10 -0
  96. package/build/tools/device-farm.d.ts.map +1 -0
  97. package/build/tools/device-farm.js +140 -0
  98. package/build/tools/device-farm.js.map +1 -0
  99. package/build/tools/device-profiles.d.ts +16 -0
  100. package/build/tools/device-profiles.d.ts.map +1 -0
  101. package/build/tools/device-profiles.js +272 -0
  102. package/build/tools/device-profiles.js.map +1 -0
  103. package/build/tools/device.d.ts +6 -0
  104. package/build/tools/device.d.ts.map +1 -0
  105. package/build/tools/device.js +72 -0
  106. package/build/tools/device.js.map +1 -0
  107. package/build/tools/diagnostics.d.ts +7 -0
  108. package/build/tools/diagnostics.d.ts.map +1 -0
  109. package/build/tools/diagnostics.js +153 -0
  110. package/build/tools/diagnostics.js.map +1 -0
  111. package/build/tools/emulator.d.ts +9 -0
  112. package/build/tools/emulator.d.ts.map +1 -0
  113. package/build/tools/emulator.js +223 -0
  114. package/build/tools/emulator.js.map +1 -0
  115. package/build/tools/files.d.ts +6 -0
  116. package/build/tools/files.d.ts.map +1 -0
  117. package/build/tools/files.js +78 -0
  118. package/build/tools/files.js.map +1 -0
  119. package/build/tools/firmware-analysis.d.ts +24 -0
  120. package/build/tools/firmware-analysis.d.ts.map +1 -0
  121. package/build/tools/firmware-analysis.js +623 -0
  122. package/build/tools/firmware-analysis.js.map +1 -0
  123. package/build/tools/forwarding.d.ts +7 -0
  124. package/build/tools/forwarding.d.ts.map +1 -0
  125. package/build/tools/forwarding.js +64 -0
  126. package/build/tools/forwarding.js.map +1 -0
  127. package/build/tools/health.d.ts +7 -0
  128. package/build/tools/health.d.ts.map +1 -0
  129. package/build/tools/health.js +112 -0
  130. package/build/tools/health.js.map +1 -0
  131. package/build/tools/logcat-watch.d.ts +11 -0
  132. package/build/tools/logcat-watch.d.ts.map +1 -0
  133. package/build/tools/logcat-watch.js +209 -0
  134. package/build/tools/logcat-watch.js.map +1 -0
  135. package/build/tools/logs.d.ts +6 -0
  136. package/build/tools/logs.d.ts.map +1 -0
  137. package/build/tools/logs.js +83 -0
  138. package/build/tools/logs.js.map +1 -0
  139. package/build/tools/mirroring.d.ts +14 -0
  140. package/build/tools/mirroring.d.ts.map +1 -0
  141. package/build/tools/mirroring.js +243 -0
  142. package/build/tools/mirroring.js.map +1 -0
  143. package/build/tools/multi-device.d.ts +9 -0
  144. package/build/tools/multi-device.d.ts.map +1 -0
  145. package/build/tools/multi-device.js +138 -0
  146. package/build/tools/multi-device.js.map +1 -0
  147. package/build/tools/network-capture.d.ts +10 -0
  148. package/build/tools/network-capture.d.ts.map +1 -0
  149. package/build/tools/network-capture.js +143 -0
  150. package/build/tools/network-capture.js.map +1 -0
  151. package/build/tools/network-discovery.d.ts +21 -0
  152. package/build/tools/network-discovery.d.ts.map +1 -0
  153. package/build/tools/network-discovery.js +284 -0
  154. package/build/tools/network-discovery.js.map +1 -0
  155. package/build/tools/ota-monitor.d.ts +16 -0
  156. package/build/tools/ota-monitor.d.ts.map +1 -0
  157. package/build/tools/ota-monitor.js +211 -0
  158. package/build/tools/ota-monitor.js.map +1 -0
  159. package/build/tools/packages.d.ts +6 -0
  160. package/build/tools/packages.d.ts.map +1 -0
  161. package/build/tools/packages.js +237 -0
  162. package/build/tools/packages.js.map +1 -0
  163. package/build/tools/plugins.d.ts +22 -0
  164. package/build/tools/plugins.d.ts.map +1 -0
  165. package/build/tools/plugins.js +118 -0
  166. package/build/tools/plugins.js.map +1 -0
  167. package/build/tools/prompts.d.ts +9 -0
  168. package/build/tools/prompts.d.ts.map +1 -0
  169. package/build/tools/prompts.js +94 -0
  170. package/build/tools/prompts.js.map +1 -0
  171. package/build/tools/qemu.d.ts +18 -0
  172. package/build/tools/qemu.d.ts.map +1 -0
  173. package/build/tools/qemu.js +791 -0
  174. package/build/tools/qemu.js.map +1 -0
  175. package/build/tools/registry.d.ts +13 -0
  176. package/build/tools/registry.d.ts.map +1 -0
  177. package/build/tools/registry.js +221 -0
  178. package/build/tools/registry.js.map +1 -0
  179. package/build/tools/regression.d.ts +10 -0
  180. package/build/tools/regression.d.ts.map +1 -0
  181. package/build/tools/regression.js +215 -0
  182. package/build/tools/regression.js.map +1 -0
  183. package/build/tools/resources.d.ts +10 -0
  184. package/build/tools/resources.d.ts.map +1 -0
  185. package/build/tools/resources.js +77 -0
  186. package/build/tools/resources.js.map +1 -0
  187. package/build/tools/ril-intercept.d.ts +24 -0
  188. package/build/tools/ril-intercept.d.ts.map +1 -0
  189. package/build/tools/ril-intercept.js +273 -0
  190. package/build/tools/ril-intercept.js.map +1 -0
  191. package/build/tools/screen-record.d.ts +9 -0
  192. package/build/tools/screen-record.d.ts.map +1 -0
  193. package/build/tools/screen-record.js +95 -0
  194. package/build/tools/screen-record.js.map +1 -0
  195. package/build/tools/screenshot-diff.d.ts +13 -0
  196. package/build/tools/screenshot-diff.d.ts.map +1 -0
  197. package/build/tools/screenshot-diff.js +370 -0
  198. package/build/tools/screenshot-diff.js.map +1 -0
  199. package/build/tools/selinux-audit.d.ts +17 -0
  200. package/build/tools/selinux-audit.d.ts.map +1 -0
  201. package/build/tools/selinux-audit.js +301 -0
  202. package/build/tools/selinux-audit.js.map +1 -0
  203. package/build/tools/shell.d.ts +6 -0
  204. package/build/tools/shell.d.ts.map +1 -0
  205. package/build/tools/shell.js +63 -0
  206. package/build/tools/shell.js.map +1 -0
  207. package/build/tools/snapshot.d.ts +9 -0
  208. package/build/tools/snapshot.d.ts.map +1 -0
  209. package/build/tools/snapshot.js +192 -0
  210. package/build/tools/snapshot.js.map +1 -0
  211. package/build/tools/split-apk.d.ts +13 -0
  212. package/build/tools/split-apk.d.ts.map +1 -0
  213. package/build/tools/split-apk.js +229 -0
  214. package/build/tools/split-apk.js.map +1 -0
  215. package/build/tools/test-gen.d.ts +14 -0
  216. package/build/tools/test-gen.d.ts.map +1 -0
  217. package/build/tools/test-gen.js +252 -0
  218. package/build/tools/test-gen.js.map +1 -0
  219. package/build/tools/testing.d.ts +9 -0
  220. package/build/tools/testing.d.ts.map +1 -0
  221. package/build/tools/testing.js +144 -0
  222. package/build/tools/testing.js.map +1 -0
  223. package/build/tools/thermal-power.d.ts +19 -0
  224. package/build/tools/thermal-power.d.ts.map +1 -0
  225. package/build/tools/thermal-power.js +330 -0
  226. package/build/tools/thermal-power.js.map +1 -0
  227. package/build/tools/ui.d.ts +6 -0
  228. package/build/tools/ui.d.ts.map +1 -0
  229. package/build/tools/ui.js +266 -0
  230. package/build/tools/ui.js.map +1 -0
  231. package/build/tools/wireless.d.ts +7 -0
  232. package/build/tools/wireless.d.ts.map +1 -0
  233. package/build/tools/wireless.js +78 -0
  234. package/build/tools/wireless.js.map +1 -0
  235. package/build/tools/workflow-market.d.ts +17 -0
  236. package/build/tools/workflow-market.d.ts.map +1 -0
  237. package/build/tools/workflow-market.js +237 -0
  238. package/build/tools/workflow-market.js.map +1 -0
  239. package/build/tools/workflow.d.ts +32 -0
  240. package/build/tools/workflow.d.ts.map +1 -0
  241. package/build/tools/workflow.js +374 -0
  242. package/build/tools/workflow.js.map +1 -0
  243. package/build/ws-transport.d.ts +30 -0
  244. package/build/ws-transport.d.ts.map +1 -0
  245. package/build/ws-transport.js +133 -0
  246. package/build/ws-transport.js.map +1 -0
  247. package/package.json +37 -0
@@ -0,0 +1,77 @@
1
+ /**
2
+ * MCP Resources — Read-only device state surfaces.
3
+ *
4
+ * Exposes device information as MCP Resources that clients can
5
+ * read on demand. Semantically better than tools for "give me
6
+ * current state" operations.
7
+ */
8
+ import { ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
9
+ import { OutputProcessor } from "../middleware/output-processor.js";
10
+ export function registerResources(ctx) {
11
+ // Dynamic resource: device info by serial
12
+ ctx.server.resource("device-info", new ResourceTemplate("device://info/{serial}", { list: undefined }), { description: "Device properties (model, OS version, build, ABI)" }, async (uri, { serial }) => {
13
+ try {
14
+ const resolved = await ctx.deviceManager.resolveDevice(serial || undefined);
15
+ const props = await ctx.deviceManager.getDeviceProps(resolved.serial);
16
+ const info = [
17
+ `Model: ${props["ro.product.model"] ?? "unknown"}`,
18
+ `Manufacturer: ${props["ro.product.manufacturer"] ?? "unknown"}`,
19
+ `Android: ${props["ro.build.version.release"] ?? "unknown"} (SDK ${props["ro.build.version.sdk"] ?? "?"})`,
20
+ `Build: ${props["ro.build.display.id"] ?? "unknown"}`,
21
+ `Security Patch: ${props["ro.build.version.security_patch"] ?? "unknown"}`,
22
+ `ABI: ${props["ro.product.cpu.abi"] ?? "unknown"}`,
23
+ `Serial: ${resolved.serial}`,
24
+ ].join("\n");
25
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: info }] };
26
+ }
27
+ catch (error) {
28
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: OutputProcessor.formatError(error) }] };
29
+ }
30
+ });
31
+ // Dynamic resource: battery status by serial
32
+ ctx.server.resource("device-battery", new ResourceTemplate("device://battery/{serial}", { list: undefined }), { description: "Battery status, level, temperature, and charging info" }, async (uri, { serial }) => {
33
+ try {
34
+ const resolved = await ctx.deviceManager.resolveDevice(serial || undefined);
35
+ const result = await ctx.bridge.shell("dumpsys battery", { device: resolved.serial });
36
+ const parsed = OutputProcessor.parseBattery(result.stdout);
37
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: parsed }] };
38
+ }
39
+ catch (error) {
40
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: OutputProcessor.formatError(error) }] };
41
+ }
42
+ });
43
+ // Dynamic resource: telephony state by serial
44
+ ctx.server.resource("device-telephony", new ResourceTemplate("device://telephony/{serial}", { list: undefined }), { description: "Telephony state: cell info, signal strength, network registration" }, async (uri, { serial }) => {
45
+ try {
46
+ const resolved = await ctx.deviceManager.resolveDevice(serial || undefined);
47
+ const result = await ctx.bridge.shell("dumpsys telephony.registry", {
48
+ device: resolved.serial, timeout: 15000,
49
+ });
50
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: OutputProcessor.process(result.stdout, 20000) }] };
51
+ }
52
+ catch (error) {
53
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: OutputProcessor.formatError(error) }] };
54
+ }
55
+ });
56
+ // Static resource: list connected devices
57
+ ctx.server.resource("devices-list", "device://list", { description: "List of all connected Android devices" }, async (uri) => {
58
+ try {
59
+ const devices = await ctx.deviceManager.listDevices();
60
+ const text = devices.length === 0
61
+ ? "No devices connected."
62
+ : devices.map((d) => {
63
+ const parts = [`${d.serial} (${d.state})`];
64
+ if (d.model)
65
+ parts.push(`model: ${d.model}`);
66
+ if (d.product)
67
+ parts.push(`product: ${d.product}`);
68
+ return parts.join(" | ");
69
+ }).join("\n");
70
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text }] };
71
+ }
72
+ catch (error) {
73
+ return { contents: [{ uri: uri.href, mimeType: "text/plain", text: OutputProcessor.formatError(error) }] };
74
+ }
75
+ });
76
+ }
77
+ //# sourceMappingURL=resources.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resources.js","sourceRoot":"","sources":["../../src/tools/resources.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * RIL Message Interception — Passive radio interface layer monitoring.
3
+ *
4
+ * Captures and parses RIL (Radio Interface Layer) messages from the
5
+ * Android radio logcat buffer. RIL sits between the telephony framework
6
+ * and the baseband modem — intercepting these messages provides visibility
7
+ * into network attach, authentication, handover, paging, and registration
8
+ * events useful for radio diagnostics and cellular network research.
9
+ *
10
+ * Parsed message categories:
11
+ * - Registration: VOICE_REGISTRATION_STATE, DATA_REGISTRATION_STATE
12
+ * - Cell info: GET_CELL_INFO_LIST responses
13
+ * - Signal: SIGNAL_STRENGTH updates
14
+ * - Network: OPERATOR, QUERY_NETWORK_SELECTION_MODE
15
+ * - Security: AUTHENTICATION events, cipher indicators
16
+ * - Handover: Tracking area updates, cell reselection
17
+ *
18
+ * Uses spawned logcat processes (like logcat-watch) with radio buffer
19
+ * filtering. Root access optional but recommended for kernel-level
20
+ * modem messages via dmesg.
21
+ */
22
+ import { ToolContext } from "../tool-context.js";
23
+ export declare function registerRilInterceptTools(ctx: ToolContext): void;
24
+ //# sourceMappingURL=ril-intercept.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ril-intercept.d.ts","sourceRoot":"","sources":["../../src/tools/ril-intercept.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAyEjD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA2OhE"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * RIL Message Interception — Passive radio interface layer monitoring.
3
+ *
4
+ * Captures and parses RIL (Radio Interface Layer) messages from the
5
+ * Android radio logcat buffer. RIL sits between the telephony framework
6
+ * and the baseband modem — intercepting these messages provides visibility
7
+ * into network attach, authentication, handover, paging, and registration
8
+ * events useful for radio diagnostics and cellular network research.
9
+ *
10
+ * Parsed message categories:
11
+ * - Registration: VOICE_REGISTRATION_STATE, DATA_REGISTRATION_STATE
12
+ * - Cell info: GET_CELL_INFO_LIST responses
13
+ * - Signal: SIGNAL_STRENGTH updates
14
+ * - Network: OPERATOR, QUERY_NETWORK_SELECTION_MODE
15
+ * - Security: AUTHENTICATION events, cipher indicators
16
+ * - Handover: Tracking area updates, cell reselection
17
+ *
18
+ * Uses spawned logcat processes (like logcat-watch) with radio buffer
19
+ * filtering. Root access optional but recommended for kernel-level
20
+ * modem messages via dmesg.
21
+ */
22
+ import { z } from "zod";
23
+ import { OutputProcessor } from "../middleware/output-processor.js";
24
+ import { registerCleanup } from "../middleware/cleanup.js";
25
+ /** Active RIL capture sessions by ID. */
26
+ const sessions = new Map();
27
+ let sessionCounter = 0;
28
+ const MAX_RIL_SESSIONS = 5;
29
+ /** RIL message category patterns. */
30
+ const RIL_CATEGORIES = [
31
+ { pattern: /VOICE_REGISTRATION_STATE|DATA_REGISTRATION_STATE|REGISTRATION_FAILED/i, category: "registration" },
32
+ { pattern: /CELL_INFO|CellInfo|mCellInfo/i, category: "cell_info" },
33
+ { pattern: /SIGNAL_STRENGTH|SignalStrength/i, category: "signal" },
34
+ { pattern: /OPERATOR|COPS|operator/i, category: "network" },
35
+ { pattern: /AUTH|CPIN|SIM_STATUS|IMSI/i, category: "security" },
36
+ { pattern: /HANDOVER|TAU|TRACKING_AREA|RESELECT/i, category: "handover" },
37
+ { pattern: /SETUP_DATA_CALL|DEACTIVATE_DATA|DATA_CALL_LIST/i, category: "data" },
38
+ { pattern: /RADIO_STATE|CFUN|RADIO_POWER/i, category: "radio_state" },
39
+ { pattern: /SMS|CDMA_SMS|NEW_SMS/i, category: "sms" },
40
+ { pattern: /NAS|EMM|5GMM|ATTACH|DETACH/i, category: "nas" },
41
+ ];
42
+ function categorizeMessage(line) {
43
+ for (const { pattern, category } of RIL_CATEGORIES) {
44
+ if (pattern.test(line))
45
+ return category;
46
+ }
47
+ return "other";
48
+ }
49
+ function parseRilLine(line) {
50
+ // Standard logcat format: "MM-DD HH:MM:SS.mmm PID TID PRIORITY TAG: message"
51
+ const match = line.match(/^(\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d{3})\s+\d+\s+\d+\s+([VDIWEF])\s+(.+?):\s+(.*)/);
52
+ if (!match)
53
+ return null;
54
+ return {
55
+ timestamp: match[1],
56
+ priority: match[2],
57
+ tag: match[3].trim(),
58
+ raw: match[4],
59
+ category: categorizeMessage(match[4]),
60
+ };
61
+ }
62
+ // Register cleanup via shared registry
63
+ function ensureCleanupRegistered() {
64
+ registerCleanup("ril-intercept", () => {
65
+ for (const [, session] of sessions) {
66
+ try {
67
+ session.process.kill();
68
+ }
69
+ catch { /* ignore */ }
70
+ }
71
+ sessions.clear();
72
+ });
73
+ }
74
+ export function registerRilInterceptTools(ctx) {
75
+ ensureCleanupRegistered();
76
+ ctx.server.tool("adb_ril_start", "Start capturing RIL (Radio Interface Layer) messages from the radio logcat buffer. Captures network registration, cell info, signal strength, authentication, handover, and NAS events. Useful for radio diagnostics and cellular network research.", {
77
+ bufferSize: z.number().min(100).max(50000).optional().default(5000).describe("Max messages to keep in ring buffer (100-50000, default 5000)"),
78
+ includeKernel: z.boolean().optional().default(false).describe("Also capture from main and kernel logcat buffers for modem framework and kernel-level radio messages"),
79
+ device: z.string().optional().describe("Device serial"),
80
+ }, async ({ bufferSize, includeKernel, device }) => {
81
+ try {
82
+ if (sessions.size >= MAX_RIL_SESSIONS) {
83
+ return {
84
+ content: [{ type: "text", text: `Maximum RIL sessions reached (${MAX_RIL_SESSIONS}). Stop an existing session first.` }],
85
+ isError: true,
86
+ };
87
+ }
88
+ const resolved = await ctx.deviceManager.resolveDevice(device);
89
+ const serial = resolved.serial;
90
+ const id = `ril_${++sessionCounter}`;
91
+ // Spawn logcat with radio buffer (and main buffer if includeKernel for modem framework messages)
92
+ const buffers = includeKernel ? "radio,main,kernel" : "radio";
93
+ const logcatArgs = ["logcat", "-b", buffers, "-v", "time"];
94
+ // Spawn via bridge — works in both ADB and on-device modes
95
+ const proc = ctx.bridge.spawnStreaming(logcatArgs, serial);
96
+ const session = {
97
+ process: proc,
98
+ buffer: [],
99
+ rawBuffer: [],
100
+ readCursor: 0,
101
+ maxMessages: bufferSize,
102
+ startedAt: Date.now(),
103
+ device: serial,
104
+ includeKernel,
105
+ };
106
+ let partial = "";
107
+ proc.stdout?.on("data", (chunk) => {
108
+ const text = partial + chunk.toString();
109
+ const lines = text.split("\n");
110
+ partial = lines.pop() ?? "";
111
+ for (const line of lines) {
112
+ const trimmed = line.trim();
113
+ if (!trimmed)
114
+ continue;
115
+ const parsed = parseRilLine(trimmed);
116
+ if (parsed) {
117
+ session.buffer.push(parsed);
118
+ session.rawBuffer.push(trimmed);
119
+ // Ring buffer management
120
+ if (session.buffer.length > session.maxMessages) {
121
+ const overflow = session.buffer.length - session.maxMessages;
122
+ session.buffer.splice(0, overflow);
123
+ session.rawBuffer.splice(0, overflow);
124
+ session.readCursor = Math.max(0, session.readCursor - overflow);
125
+ }
126
+ }
127
+ }
128
+ });
129
+ proc.stderr?.on("data", (chunk) => {
130
+ const msg = chunk.toString().trim();
131
+ if (msg)
132
+ ctx.logger.warn(`[${id}] radio logcat stderr: ${msg}`);
133
+ });
134
+ proc.on("error", (err) => {
135
+ ctx.logger.error(`[${id}] Failed to spawn radio logcat: ${err.message}`);
136
+ sessions.delete(id);
137
+ });
138
+ proc.on("exit", (code) => {
139
+ ctx.logger.info(`[${id}] radio logcat exited (code: ${code})`);
140
+ sessions.delete(id);
141
+ });
142
+ sessions.set(id, session);
143
+ return {
144
+ content: [{
145
+ type: "text",
146
+ text: `RIL capture started: ${id}\nDevice: ${serial}\nBuffer: ${bufferSize} messages\nLogcat buffers: ${includeKernel ? "radio + main + kernel" : "radio only"}\n\nCapturing: registration, cell info, signal, network, security, handover, NAS events\nUse adb_ril_poll to retrieve captured messages.`,
147
+ }],
148
+ };
149
+ }
150
+ catch (error) {
151
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
152
+ }
153
+ });
154
+ ctx.server.tool("adb_ril_poll", "Retrieve captured RIL messages since the last poll. Optionally filter by category (registration, cell_info, signal, network, security, handover, data, radio_state, nas).", {
155
+ session: z.string().describe("Session ID from adb_ril_start (e.g., 'ril_1')"),
156
+ category: z.string().optional().describe("Filter by category: registration, cell_info, signal, network, security, handover, data, radio_state, sms, nas, other"),
157
+ maxMessages: z.number().min(1).max(10000).optional().default(100).describe("Max messages to return per poll (1-10000)"),
158
+ raw: z.boolean().optional().default(false).describe("Return raw logcat lines instead of parsed messages"),
159
+ }, async ({ session: sessionId, category, maxMessages, raw }) => {
160
+ try {
161
+ const session = sessions.get(sessionId);
162
+ if (!session) {
163
+ const active = Array.from(sessions.keys());
164
+ return {
165
+ content: [{ type: "text", text: `Session "${sessionId}" not found. Active: ${active.join(", ") || "none"}` }],
166
+ isError: true,
167
+ };
168
+ }
169
+ const available = session.buffer.length - session.readCursor;
170
+ if (available <= 0) {
171
+ const elapsed = ((Date.now() - session.startedAt) / 1000).toFixed(0);
172
+ // Show category distribution of existing buffer
173
+ const counts = {};
174
+ for (const msg of session.buffer) {
175
+ counts[msg.category] = (counts[msg.category] ?? 0) + 1;
176
+ }
177
+ const dist = Object.entries(counts)
178
+ .sort(([, a], [, b]) => b - a)
179
+ .map(([cat, n]) => `${cat}: ${n}`)
180
+ .join(", ");
181
+ return {
182
+ content: [{
183
+ type: "text",
184
+ text: `No new messages. Running ${elapsed}s, buffer: ${session.buffer.length}/${session.maxMessages}\nCategory distribution: ${dist || "(empty)"}`,
185
+ }],
186
+ };
187
+ }
188
+ // Get new messages
189
+ const startIdx = session.readCursor;
190
+ let messages = [];
191
+ for (let i = startIdx; i < session.buffer.length; i++) {
192
+ messages.push({ parsed: session.buffer[i], raw: session.rawBuffer[i] });
193
+ }
194
+ // Filter by category
195
+ if (category) {
196
+ messages = messages.filter((m) => m.parsed.category === category);
197
+ }
198
+ // Limit
199
+ const limited = messages.slice(0, maxMessages);
200
+ // Advance cursor (always, regardless of filter)
201
+ session.readCursor = session.buffer.length;
202
+ if (limited.length === 0) {
203
+ return {
204
+ content: [{ type: "text", text: `${available} new message(s) but none match category "${category}".` }],
205
+ };
206
+ }
207
+ let output;
208
+ if (raw) {
209
+ output = limited.map((m) => m.raw).join("\n");
210
+ }
211
+ else {
212
+ output = limited.map((m) => {
213
+ const p = m.parsed;
214
+ return `[${p.timestamp}] [${p.category}] ${p.tag}: ${p.raw}`;
215
+ }).join("\n");
216
+ }
217
+ const remaining = messages.length - limited.length;
218
+ if (remaining > 0) {
219
+ output += `\n\n--- ${remaining} more messages available, poll again ---`;
220
+ }
221
+ return { content: [{ type: "text", text: OutputProcessor.process(output) }] };
222
+ }
223
+ catch (error) {
224
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
225
+ }
226
+ });
227
+ ctx.server.tool("adb_ril_stop", "Stop a RIL capture session. Shows a summary of captured message categories.", {
228
+ session: z.string().describe("Session ID to stop (e.g., 'ril_1'), or 'all' to stop all"),
229
+ }, async ({ session: sessionId }) => {
230
+ try {
231
+ if (sessionId === "all") {
232
+ const count = sessions.size;
233
+ for (const [, s] of sessions) {
234
+ try {
235
+ s.process.kill();
236
+ }
237
+ catch { /* ignore */ }
238
+ }
239
+ sessions.clear();
240
+ return { content: [{ type: "text", text: `Stopped ${count} RIL session(s).` }] };
241
+ }
242
+ const session = sessions.get(sessionId);
243
+ if (!session) {
244
+ return { content: [{ type: "text", text: `Session "${sessionId}" not found.` }], isError: true };
245
+ }
246
+ const elapsed = ((Date.now() - session.startedAt) / 1000).toFixed(1);
247
+ // Category summary
248
+ const counts = {};
249
+ for (const msg of session.buffer) {
250
+ counts[msg.category] = (counts[msg.category] ?? 0) + 1;
251
+ }
252
+ const dist = Object.entries(counts)
253
+ .sort(([, a], [, b]) => b - a)
254
+ .map(([cat, n]) => ` ${cat}: ${n}`)
255
+ .join("\n");
256
+ try {
257
+ session.process.kill();
258
+ }
259
+ catch { /* ignore */ }
260
+ sessions.delete(sessionId);
261
+ const summary = [];
262
+ summary.push(`Stopped ${sessionId}. Duration: ${elapsed}s, Total messages: ${session.buffer.length}`);
263
+ if (dist) {
264
+ summary.push(`\nMessage categories:\n${dist}`);
265
+ }
266
+ return { content: [{ type: "text", text: summary.join("\n") }] };
267
+ }
268
+ catch (error) {
269
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
270
+ }
271
+ });
272
+ }
273
+ //# sourceMappingURL=ril-intercept.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ril-intercept.js","sourceRoot":"","sources":["../../src/tools/ril-intercept.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Screen Recording Tools — Start/stop video capture on the device.
3
+ *
4
+ * Uses `adb shell screenrecord` with a background process pattern.
5
+ * The recording runs on-device; stop pulls the mp4 locally.
6
+ */
7
+ import { ToolContext } from "../tool-context.js";
8
+ export declare function registerScreenRecordTools(ctx: ToolContext): void;
9
+ //# sourceMappingURL=screen-record.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-record.d.ts","sourceRoot":"","sources":["../../src/tools/screen-record.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAcjD,wBAAgB,yBAAyB,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CA8GhE"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Screen Recording Tools — Start/stop video capture on the device.
3
+ *
4
+ * Uses `adb shell screenrecord` with a background process pattern.
5
+ * The recording runs on-device; stop pulls the mp4 locally.
6
+ */
7
+ import { z } from "zod";
8
+ import { join } from "path";
9
+ import { OutputProcessor } from "../middleware/output-processor.js";
10
+ import { shellEscape } from "../middleware/sanitize.js";
11
+ /** Only one recording per device at a time. Key = device serial. */
12
+ const recordings = new Map();
13
+ export function registerScreenRecordTools(ctx) {
14
+ ctx.server.tool("adb_screenrecord_start", "Start recording the device screen. Recording runs on-device. Use adb_screenrecord_stop to finish and pull the video file.", {
15
+ maxDuration: z.number().min(1).max(180).optional().default(60)
16
+ .describe("Maximum recording duration in seconds (1-180, default 60)"),
17
+ device: z.string().optional().describe("Device serial"),
18
+ }, async ({ maxDuration, device }) => {
19
+ try {
20
+ const resolved = await ctx.deviceManager.resolveDevice(device);
21
+ const serial = resolved.serial;
22
+ if (recordings.has(serial)) {
23
+ return { content: [{ type: "text", text: `Recording already in progress on ${serial}. Stop it first with adb_screenrecord_stop.` }], isError: true };
24
+ }
25
+ const filename = `screenrecord_${Date.now()}.mp4`;
26
+ const remotePath = `/sdcard/${filename}`;
27
+ // Start screenrecord in background via shell nohup
28
+ // screenrecord auto-stops at --time-limit
29
+ await ctx.bridge.shell(`nohup screenrecord --time-limit ${maxDuration} '${shellEscape(remotePath)}' > /dev/null 2>&1 &`, { device: serial, ignoreExitCode: true });
30
+ recordings.set(serial, {
31
+ device: serial,
32
+ remotePath,
33
+ startedAt: Date.now(),
34
+ maxDuration,
35
+ });
36
+ return {
37
+ content: [{
38
+ type: "text",
39
+ text: `Recording started on ${serial}\nMax duration: ${maxDuration}s\nDevice path: ${remotePath}\nUse adb_screenrecord_stop to finish and pull the video.`,
40
+ }],
41
+ };
42
+ }
43
+ catch (error) {
44
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
45
+ }
46
+ });
47
+ ctx.server.tool("adb_screenrecord_stop", "Stop an active screen recording and pull the video file locally. If the recording has already finished (hit time limit), this just pulls the file.", {
48
+ device: z.string().optional().describe("Device serial"),
49
+ }, async ({ device }) => {
50
+ let resolvedSerial;
51
+ try {
52
+ const resolved = await ctx.deviceManager.resolveDevice(device);
53
+ resolvedSerial = resolved.serial;
54
+ const serial = resolved.serial;
55
+ const session = recordings.get(serial);
56
+ if (!session) {
57
+ return { content: [{ type: "text", text: `No active recording on ${serial}.` }], isError: true };
58
+ }
59
+ // Kill the screenrecord process writing to our specific file.
60
+ // Uses pgrep (by binary name) + /proc/cmdline grep to avoid the pkill -f
61
+ // self-match bug: on-device, pkill -f runs through su -c whose cmdline
62
+ // contains the pattern, causing pkill to kill itself instead of screenrecord.
63
+ const recordFilename = session.remotePath.split("/").pop() ?? "";
64
+ await ctx.bridge.shell(`pgrep screenrecord | while read p; do grep -q '${recordFilename}' /proc/$p/cmdline 2>/dev/null && kill $p; done 2>/dev/null; true`, { device: serial, ignoreExitCode: true, timeout: 5000 });
65
+ // Brief wait for file to finalize
66
+ await new Promise((r) => setTimeout(r, 1500));
67
+ // Pull the file locally
68
+ const localFilename = session.remotePath.split("/").pop() ?? "recording.mp4";
69
+ const localPath = join(ctx.config.tempDir, localFilename);
70
+ await ctx.bridge.exec(["pull", session.remotePath, localPath], {
71
+ device: serial, timeout: 60000,
72
+ });
73
+ // Clean up device file
74
+ await ctx.bridge.shell(`rm '${shellEscape(session.remotePath)}'`, {
75
+ device: serial, ignoreExitCode: true,
76
+ });
77
+ const elapsed = ((Date.now() - session.startedAt) / 1000).toFixed(1);
78
+ recordings.delete(serial);
79
+ return {
80
+ content: [{
81
+ type: "text",
82
+ text: `Recording saved: ${localPath}\nDuration: ~${elapsed}s`,
83
+ }],
84
+ };
85
+ }
86
+ catch (error) {
87
+ // Clean up session state even on error
88
+ if (resolvedSerial) {
89
+ recordings.delete(resolvedSerial);
90
+ }
91
+ return { content: [{ type: "text", text: OutputProcessor.formatError(error) }], isError: true };
92
+ }
93
+ });
94
+ }
95
+ //# sourceMappingURL=screen-record.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screen-record.js","sourceRoot":"","sources":["../../src/tools/screen-record.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Screenshot Diffing Tools — Pixel-level screenshot comparison for visual regression detection.
3
+ *
4
+ * Extends the regression detection capabilities with visual comparison.
5
+ * Captures baseline screenshots, compares current screen state against them,
6
+ * and reports differences. Uses raw screencap data for pixel-level comparison
7
+ * without external image processing dependencies.
8
+ *
9
+ * Baselines are saved as PNG files in {tempDir}/screenshot-baselines/.
10
+ */
11
+ import { ToolContext } from "../tool-context.js";
12
+ export declare function registerScreenshotDiffTools(ctx: ToolContext): void;
13
+ //# sourceMappingURL=screenshot-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot-diff.d.ts","sourceRoot":"","sources":["../../src/tools/screenshot-diff.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAkOjD,wBAAgB,2BAA2B,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,CAiMlE"}