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,65 @@
1
+ /**
2
+ * ADB Bridge — Core subprocess wrapper for all ADB interactions.
3
+ *
4
+ * Every ADB command in DeepADB flows through this module.
5
+ * Handles: subprocess spawning, timeout enforcement, error normalization,
6
+ * device serial routing, output capture, and transient failure retry.
7
+ */
8
+ import { ChildProcess } from "child_process";
9
+ import { Logger } from "../middleware/logger.js";
10
+ export interface AdbResult {
11
+ stdout: string;
12
+ stderr: string;
13
+ exitCode: number;
14
+ timedOut: boolean;
15
+ bufferExceeded: boolean;
16
+ device?: string;
17
+ }
18
+ export interface AdbExecOptions {
19
+ /** Target device serial. Falls back to config.defaultDevice. */
20
+ device?: string;
21
+ /** Timeout in ms. Falls back to config.commandTimeout. */
22
+ timeout?: number;
23
+ /** If true, don't throw on non-zero exit codes */
24
+ ignoreExitCode?: boolean;
25
+ /** Override retry count for this call (0 = no retry) */
26
+ retries?: number;
27
+ }
28
+ export declare class AdbBridge {
29
+ private adbPath;
30
+ private logger;
31
+ constructor(logger: Logger);
32
+ /**
33
+ * Execute an ADB command with automatic retry on transient failures.
34
+ * This is the single entry point for all ADB subprocess calls.
35
+ */
36
+ exec(args: string[], options?: AdbExecOptions): Promise<AdbResult>;
37
+ private sleep;
38
+ /**
39
+ * Single-attempt ADB execution (no retry).
40
+ */
41
+ private execOnce;
42
+ /** Execute an ADB shell command on the device. */
43
+ shell(command: string, options?: AdbExecOptions): Promise<AdbResult>;
44
+ /** Execute a root shell command (via su). */
45
+ rootShell(command: string, options?: AdbExecOptions): Promise<AdbResult>;
46
+ /** Verify ADB is accessible and return version info. */
47
+ version(): Promise<string>;
48
+ /** Check if ADB server is running and reachable. */
49
+ ping(): Promise<boolean>;
50
+ /**
51
+ * Spawn a long-running ADB command as a streaming child process.
52
+ * Used by logcat watchers and RIL interceptors that need continuous output.
53
+ * Returns the ChildProcess — caller manages stdout/stderr/lifecycle.
54
+ *
55
+ * In ADB mode: spawns `adb -s <serial> <args...>`
56
+ * LocalBridge overrides this to spawn commands directly.
57
+ */
58
+ spawnStreaming(args: string[], device?: string): ChildProcess;
59
+ }
60
+ /** Structured error type for ADB failures. */
61
+ export declare class AdbError extends Error {
62
+ readonly result: AdbResult;
63
+ constructor(message: string, result: AdbResult);
64
+ }
65
+ //# sourceMappingURL=adb-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/adb-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAoC,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/E,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD,MAAM,WAAW,SAAS;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,OAAO,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,0DAA0D;IAC1D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,kDAAkD;IAClD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,wDAAwD;IACxD,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAkBD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM;IAK1B;;;OAGG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IAuB5E,OAAO,CAAC,KAAK;IAIb;;OAEG;YACW,QAAQ;IAiEtB,kDAAkD;IAC5C,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IAI9E,6CAA6C;IACvC,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IAIlF,wDAAwD;IAClD,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IAKhC,oDAAoD;IAC9C,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAS9B;;;;;;;OAOG;IACH,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;CAe9D;AAED,8CAA8C;AAC9C,qBAAa,QAAS,SAAQ,KAAK;IACjC,SAAgB,MAAM,EAAE,SAAS,CAAC;gBAEtB,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS;CAK/C"}
@@ -0,0 +1,164 @@
1
+ /**
2
+ * ADB Bridge — Core subprocess wrapper for all ADB interactions.
3
+ *
4
+ * Every ADB command in DeepADB flows through this module.
5
+ * Handles: subprocess spawning, timeout enforcement, error normalization,
6
+ * device serial routing, output capture, and transient failure retry.
7
+ */
8
+ import { execFile, spawn } from "child_process";
9
+ import { config } from "../config/config.js";
10
+ import { shellEscape } from "../middleware/sanitize.js";
11
+ /** Patterns in stderr/message that indicate a transient, retryable failure. */
12
+ const TRANSIENT_PATTERNS = [
13
+ "device not found",
14
+ "device offline",
15
+ "no devices/emulators found",
16
+ "protocol fault",
17
+ "closed",
18
+ "Connection reset",
19
+ "ECONNRESET",
20
+ ];
21
+ function isTransientError(error) {
22
+ const msg = error instanceof Error ? error.message : String(error);
23
+ return TRANSIENT_PATTERNS.some((p) => msg.includes(p));
24
+ }
25
+ export class AdbBridge {
26
+ adbPath;
27
+ logger;
28
+ constructor(logger) {
29
+ this.adbPath = config.adbPath;
30
+ this.logger = logger;
31
+ }
32
+ /**
33
+ * Execute an ADB command with automatic retry on transient failures.
34
+ * This is the single entry point for all ADB subprocess calls.
35
+ */
36
+ async exec(args, options = {}) {
37
+ const maxRetries = options.retries ?? config.retryCount;
38
+ let lastError;
39
+ for (let attempt = 0; attempt <= maxRetries; attempt++) {
40
+ try {
41
+ return await this.execOnce(args, options);
42
+ }
43
+ catch (error) {
44
+ lastError = error;
45
+ if (attempt < maxRetries && isTransientError(error)) {
46
+ const delay = config.retryBaseDelay * Math.pow(2, attempt);
47
+ this.logger.warn(`Transient ADB failure (attempt ${attempt + 1}/${maxRetries + 1}), retrying in ${delay}ms: ${error instanceof Error ? error.message : error}`);
48
+ await this.sleep(delay);
49
+ continue;
50
+ }
51
+ throw error;
52
+ }
53
+ }
54
+ throw lastError; // Should never reach here, but TypeScript needs it
55
+ }
56
+ sleep(ms) {
57
+ return new Promise((resolve) => setTimeout(resolve, ms));
58
+ }
59
+ /**
60
+ * Single-attempt ADB execution (no retry).
61
+ */
62
+ async execOnce(args, options) {
63
+ const device = options.device || config.defaultDevice;
64
+ const timeout = options.timeout || config.commandTimeout;
65
+ const fullArgs = [];
66
+ if (device) {
67
+ fullArgs.push("-s", device);
68
+ }
69
+ fullArgs.push(...args);
70
+ this.logger.debug(`adb ${fullArgs.join(" ")}`);
71
+ return new Promise((resolve, reject) => {
72
+ const execOptions = {
73
+ timeout,
74
+ maxBuffer: config.maxOutputSize * 2,
75
+ windowsHide: true,
76
+ };
77
+ execFile(this.adbPath, fullArgs, execOptions, (error, stdout, stderr) => {
78
+ const bufferExceeded = error?.code === "ERR_CHILD_PROCESS_STDIO_MAXBUFFER"
79
+ || error?.message?.includes("maxBuffer") === true;
80
+ const timedOut = error?.killed === true && !bufferExceeded;
81
+ const exitCode = error?.code != null
82
+ ? (typeof error.code === "number" ? error.code : 1)
83
+ : 0;
84
+ const result = {
85
+ stdout: stdout?.toString() ?? "",
86
+ stderr: stderr?.toString() ?? "",
87
+ exitCode,
88
+ timedOut,
89
+ bufferExceeded,
90
+ device: device || undefined,
91
+ };
92
+ this.logger.debug(`Exit: ${exitCode}, timedOut: ${timedOut}, bufferExceeded: ${bufferExceeded}, stdout: ${result.stdout.length} chars`);
93
+ if (timedOut) {
94
+ reject(new AdbError(`Command timed out after ${timeout}ms: adb ${fullArgs.join(" ")}`, result));
95
+ return;
96
+ }
97
+ if (bufferExceeded) {
98
+ this.logger.warn(`Output exceeded maxBuffer, returning partial result`);
99
+ resolve(result);
100
+ return;
101
+ }
102
+ if (exitCode !== 0 && !options.ignoreExitCode) {
103
+ reject(new AdbError(`ADB command failed (exit ${exitCode}): ${result.stderr || result.stdout}`.trim(), result));
104
+ return;
105
+ }
106
+ resolve(result);
107
+ });
108
+ });
109
+ }
110
+ /** Execute an ADB shell command on the device. */
111
+ async shell(command, options = {}) {
112
+ return this.exec(["shell", command], options);
113
+ }
114
+ /** Execute a root shell command (via su). */
115
+ async rootShell(command, options = {}) {
116
+ return this.exec(["shell", `su -c '${shellEscape(command)}'`], options);
117
+ }
118
+ /** Verify ADB is accessible and return version info. */
119
+ async version() {
120
+ const result = await this.exec(["version"], { retries: 0 });
121
+ return result.stdout.trim();
122
+ }
123
+ /** Check if ADB server is running and reachable. */
124
+ async ping() {
125
+ try {
126
+ await this.exec(["devices"], { timeout: 5000, retries: 0 });
127
+ return true;
128
+ }
129
+ catch {
130
+ return false;
131
+ }
132
+ }
133
+ /**
134
+ * Spawn a long-running ADB command as a streaming child process.
135
+ * Used by logcat watchers and RIL interceptors that need continuous output.
136
+ * Returns the ChildProcess — caller manages stdout/stderr/lifecycle.
137
+ *
138
+ * In ADB mode: spawns `adb -s <serial> <args...>`
139
+ * LocalBridge overrides this to spawn commands directly.
140
+ */
141
+ spawnStreaming(args, device) {
142
+ const serial = device || config.defaultDevice;
143
+ const fullArgs = [];
144
+ if (serial) {
145
+ fullArgs.push("-s", serial);
146
+ }
147
+ fullArgs.push(...args);
148
+ this.logger.debug(`spawn: adb ${fullArgs.join(" ")}`);
149
+ return spawn(this.adbPath, fullArgs, {
150
+ windowsHide: true,
151
+ stdio: ["ignore", "pipe", "pipe"],
152
+ });
153
+ }
154
+ }
155
+ /** Structured error type for ADB failures. */
156
+ export class AdbError extends Error {
157
+ result;
158
+ constructor(message, result) {
159
+ super(message);
160
+ this.name = "AdbError";
161
+ this.result = result;
162
+ }
163
+ }
164
+ //# sourceMappingURL=adb-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adb-bridge.js","sourceRoot":"","sources":["../../src/bridge/adb-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Device Manager — Discovery, caching, state tracking, and device selection.
3
+ *
4
+ * Includes a TTL-based device list cache to avoid redundant `adb devices`
5
+ * calls on every tool invocation. Cache is automatically invalidated on
6
+ * connection-related errors.
7
+ */
8
+ import { AdbBridge } from "./adb-bridge.js";
9
+ export interface DeviceInfo {
10
+ serial: string;
11
+ state: "device" | "offline" | "unauthorized" | "no permissions" | string;
12
+ model?: string;
13
+ product?: string;
14
+ transportId?: string;
15
+ }
16
+ export declare class DeviceManager {
17
+ private bridge;
18
+ private cache;
19
+ constructor(bridge: AdbBridge);
20
+ /**
21
+ * List all connected devices with their properties.
22
+ * Results are cached for config.deviceCacheTtl milliseconds.
23
+ */
24
+ listDevices(): Promise<DeviceInfo[]>;
25
+ /**
26
+ * Force-refresh the device cache on next call.
27
+ * Call this after connect/disconnect/pair operations.
28
+ */
29
+ invalidateCache(): void;
30
+ /**
31
+ * Get a single device, auto-selecting if only one is connected.
32
+ * Throws if zero or multiple devices and no serial specified.
33
+ */
34
+ resolveDevice(serial?: string): Promise<DeviceInfo>;
35
+ /**
36
+ * Get detailed device properties via getprop.
37
+ */
38
+ getDeviceProps(serial?: string): Promise<Record<string, string>>;
39
+ private parseDeviceLine;
40
+ }
41
+ //# sourceMappingURL=device-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-manager.d.ts","sourceRoot":"","sources":["../../src/bridge/device-manager.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAG5C,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,QAAQ,GAAG,SAAS,GAAG,cAAc,GAAG,gBAAgB,GAAG,MAAM,CAAC;IACzE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAOD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,KAAK,CAA4B;gBAE7B,MAAM,EAAE,SAAS;IAI7B;;;OAGG;IACG,WAAW,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;IAkB1C;;;OAGG;IACH,eAAe,IAAI,IAAI;IAIvB;;;OAGG;IACG,aAAa,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IA6CzD;;OAEG;IACG,cAAc,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IActE,OAAO,CAAC,eAAe;CAgBxB"}
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Device Manager — Discovery, caching, state tracking, and device selection.
3
+ *
4
+ * Includes a TTL-based device list cache to avoid redundant `adb devices`
5
+ * calls on every tool invocation. Cache is automatically invalidated on
6
+ * connection-related errors.
7
+ */
8
+ import { config } from "../config/config.js";
9
+ export class DeviceManager {
10
+ bridge;
11
+ cache = null;
12
+ constructor(bridge) {
13
+ this.bridge = bridge;
14
+ }
15
+ /**
16
+ * List all connected devices with their properties.
17
+ * Results are cached for config.deviceCacheTtl milliseconds.
18
+ */
19
+ async listDevices() {
20
+ const now = Date.now();
21
+ if (this.cache && (now - this.cache.timestamp) < config.deviceCacheTtl) {
22
+ return this.cache.devices;
23
+ }
24
+ const result = await this.bridge.exec(["devices", "-l"]);
25
+ const lines = result.stdout.split("\n").slice(1); // Skip header
26
+ const devices = lines
27
+ .map((line) => line.trim())
28
+ .filter((line) => line.length > 0)
29
+ .map((line) => this.parseDeviceLine(line));
30
+ this.cache = { devices, timestamp: now };
31
+ return devices;
32
+ }
33
+ /**
34
+ * Force-refresh the device cache on next call.
35
+ * Call this after connect/disconnect/pair operations.
36
+ */
37
+ invalidateCache() {
38
+ this.cache = null;
39
+ }
40
+ /**
41
+ * Get a single device, auto-selecting if only one is connected.
42
+ * Throws if zero or multiple devices and no serial specified.
43
+ */
44
+ async resolveDevice(serial) {
45
+ const devices = await this.listDevices();
46
+ const online = devices.filter((d) => d.state === "device");
47
+ if (serial) {
48
+ const found = devices.find((d) => d.serial === serial);
49
+ if (!found) {
50
+ // Invalidate cache — device might have just connected
51
+ this.invalidateCache();
52
+ throw new Error(`Device ${serial} not found. Connected: ${devices.map((d) => d.serial).join(", ") || "none"}`);
53
+ }
54
+ if (found.state !== "device") {
55
+ throw new Error(`Device ${serial} is ${found.state}. ` +
56
+ (found.state === "unauthorized"
57
+ ? "Check the device screen for the RSA key approval dialog."
58
+ : "Verify the device is online and USB debugging is enabled."));
59
+ }
60
+ return found;
61
+ }
62
+ if (online.length === 0) {
63
+ this.invalidateCache(); // Force refresh next time
64
+ const unauthorized = devices.filter((d) => d.state === "unauthorized");
65
+ if (unauthorized.length > 0) {
66
+ throw new Error(`No authorized devices. ${unauthorized.length} device(s) pending USB debugging authorization. ` +
67
+ `Check the device screen for the RSA key approval dialog.`);
68
+ }
69
+ throw new Error("No devices connected. Verify USB connection and USB debugging is enabled.");
70
+ }
71
+ if (online.length > 1) {
72
+ throw new Error(`Multiple devices connected. Specify a device serial: ${online.map((d) => d.serial).join(", ")}`);
73
+ }
74
+ return online[0];
75
+ }
76
+ /**
77
+ * Get detailed device properties via getprop.
78
+ */
79
+ async getDeviceProps(serial) {
80
+ const device = await this.resolveDevice(serial);
81
+ const result = await this.bridge.shell("getprop", { device: device.serial });
82
+ const props = {};
83
+ for (const line of result.stdout.split("\n")) {
84
+ const match = line.trim().match(/^\[(.+?)\]: \[(.*)?\]$/);
85
+ if (match) {
86
+ props[match[1]] = match[2] ?? "";
87
+ }
88
+ }
89
+ return props;
90
+ }
91
+ parseDeviceLine(line) {
92
+ const parts = line.split(/\s+/);
93
+ const serial = parts[0];
94
+ const state = parts[1];
95
+ const info = { serial, state };
96
+ // Parse key:value pairs like model:Pixel_6a product:bluejay
97
+ for (let i = 2; i < parts.length; i++) {
98
+ const [key, value] = parts[i].split(":");
99
+ if (key === "model")
100
+ info.model = value;
101
+ else if (key === "product")
102
+ info.product = value;
103
+ else if (key === "transport_id")
104
+ info.transportId = value;
105
+ }
106
+ return info;
107
+ }
108
+ }
109
+ //# sourceMappingURL=device-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-manager.js","sourceRoot":"","sources":["../../src/bridge/device-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Local Bridge — On-device execution without ADB.
3
+ *
4
+ * Drop-in replacement for AdbBridge when DeepADB runs directly on the Android
5
+ * device (e.g., inside Termux). All commands execute locally via sh/su instead
6
+ * of routing through adb over USB.
7
+ *
8
+ * Extends AdbBridge so it is type-compatible with the entire tool suite —
9
+ * no tool module changes required. The override of exec() is the single
10
+ * interception point; shell() and rootShell() flow through it automatically.
11
+ *
12
+ * Environment detection: see config.ts isOnDevice().
13
+ */
14
+ import { ChildProcess } from "child_process";
15
+ import { AdbBridge, AdbResult, AdbExecOptions } from "./adb-bridge.js";
16
+ import { Logger } from "../middleware/logger.js";
17
+ export declare class LocalBridge extends AdbBridge {
18
+ private localLogger;
19
+ private deviceInfoCache;
20
+ /**
21
+ * Cached root availability. null = not yet checked, true/false = checked.
22
+ * Probed lazily on first command that needs elevation.
23
+ */
24
+ private rootAvailable;
25
+ /**
26
+ * Android system commands that require shell-user (uid=2000) or root privileges.
27
+ * In ADB mode, all shell commands run as uid=2000 automatically.
28
+ * In on-device mode (Termux app user), these need su elevation.
29
+ *
30
+ * SECURITY: This is a FROZEN allowlist — hardcoded and immutable.
31
+ * Not configurable via environment variables or runtime API.
32
+ * Only commands explicitly listed here get routed through su.
33
+ */
34
+ private static readonly ELEVATED_COMMANDS;
35
+ constructor(logger: Logger);
36
+ /** Quote a string for safe use as a shell argument (wraps in single quotes with escaping). */
37
+ private shellQuote;
38
+ /**
39
+ * Check if root (su) is available. Result is cached after first probe.
40
+ * Uses a fast, side-effect-free check: `su -c id`.
41
+ */
42
+ private checkRootAvailable;
43
+ /**
44
+ * Wrap a command in `su -c '...'` for privilege elevation.
45
+ * Uses shellEscape() to safely handle single quotes in the inner command.
46
+ * This is the same escaping path used by AdbBridge.rootShell().
47
+ */
48
+ private elevate;
49
+ /**
50
+ * Android filesystem paths that require elevated access in on-device mode.
51
+ * Commands referencing these paths need su to bypass scoped storage restrictions.
52
+ * In ADB mode (uid=2000), these paths are accessible by default.
53
+ */
54
+ private static readonly RESTRICTED_PATH_PATTERNS;
55
+ /**
56
+ * Check if a shell command needs privilege elevation.
57
+ * Two criteria (either triggers elevation):
58
+ * 1. Command name is in the frozen ELEVATED_COMMANDS allowlist (system tools)
59
+ * 2. Command references restricted filesystem paths (scoped storage bypass)
60
+ *
61
+ * Security note: all commands reaching this point have already been validated
62
+ * by validateShellArg/shellEscape at the tool layer. The su -c '...' wrapper
63
+ * uses shellEscape() to prevent injection within the single-quote context.
64
+ */
65
+ private commandNeedsElevation;
66
+ /**
67
+ * Execute an "ADB command" locally by translating the subcommand.
68
+ * This is the single interception point — shell(), rootShell(), and all
69
+ * tool calls to exec() flow through here.
70
+ */
71
+ exec(args: string[], options?: AdbExecOptions): Promise<AdbResult>;
72
+ /** Execute a command directly on the local device via sh. */
73
+ private execLocal;
74
+ /**
75
+ * Synthesize an `adb devices -l` response for DeviceManager.
76
+ * Reads device properties once and caches them.
77
+ */
78
+ private syntheticDeviceList;
79
+ /** Create a successful AdbResult from a string. */
80
+ private makeResult;
81
+ /** Always reachable — we are the device. */
82
+ ping(): Promise<boolean>;
83
+ /** Return local version info. */
84
+ version(): Promise<string>;
85
+ /**
86
+ * Spawn a long-running streaming command locally.
87
+ * In ADB mode the args are ["logcat", ...flags] prefixed with "adb -s serial".
88
+ * Here we strip the ADB layer and spawn the command directly.
89
+ */
90
+ spawnStreaming(args: string[], _device?: string): ChildProcess;
91
+ }
92
+ //# sourceMappingURL=local-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"local-bridge.d.ts","sourceRoot":"","sources":["../../src/bridge/local-bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAoC,YAAY,EAAE,MAAM,eAAe,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAY,MAAM,iBAAiB,CAAC;AAEjF,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAC;AAGjD,qBAAa,WAAY,SAAQ,SAAS;IACxC,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,eAAe,CAAuB;IAE9C;;;OAGG;IACH,OAAO,CAAC,aAAa,CAAwB;IAE7C;;;;;;;;OAQG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAiBrC;gBAEQ,MAAM,EAAE,MAAM;IAK1B,8FAA8F;IAC9F,OAAO,CAAC,UAAU;IAIlB;;;OAGG;YACW,kBAAkB;IAkBhC;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAIf;;;;OAIG;IACH,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,wBAAwB,CAAuC;IAEvF;;;;;;;;;OASG;IACH,OAAO,CAAC,qBAAqB;IAa7B;;;;OAIG;IACY,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,SAAS,CAAC;IA0HrF,6DAA6D;IAC7D,OAAO,CAAC,SAAS;IAqDjB;;;OAGG;YACW,mBAAmB;IAmBjC,mDAAmD;IACnD,OAAO,CAAC,UAAU;IAWlB,4CAA4C;IAC7B,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC;IAIvC,iCAAiC;IAClB,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC;IASzC;;;;OAIG;IACM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,YAAY;CA0BxE"}