@beeos-ai/device-mcp-server 0.2.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 (62) hide show
  1. package/LICENSE +201 -0
  2. package/dist/backends/android-adb-runner.d.ts +32 -0
  3. package/dist/backends/android-adb-runner.js +15 -0
  4. package/dist/backends/android-adb-runner.js.map +1 -0
  5. package/dist/backends/android-adb.d.ts +153 -0
  6. package/dist/backends/android-adb.js +723 -0
  7. package/dist/backends/android-adb.js.map +1 -0
  8. package/dist/backends/base.d.ts +150 -0
  9. package/dist/backends/base.js +116 -0
  10. package/dist/backends/base.js.map +1 -0
  11. package/dist/backends/desktop.d.ts +62 -0
  12. package/dist/backends/desktop.js +176 -0
  13. package/dist/backends/desktop.js.map +1 -0
  14. package/dist/backends/index.d.ts +63 -0
  15. package/dist/backends/index.js +105 -0
  16. package/dist/backends/index.js.map +1 -0
  17. package/dist/backends/linux.d.ts +69 -0
  18. package/dist/backends/linux.js +230 -0
  19. package/dist/backends/linux.js.map +1 -0
  20. package/dist/backends/mac.d.ts +154 -0
  21. package/dist/backends/mac.js +881 -0
  22. package/dist/backends/mac.js.map +1 -0
  23. package/dist/backends/stubs/ios.d.ts +17 -0
  24. package/dist/backends/stubs/ios.js +32 -0
  25. package/dist/backends/stubs/ios.js.map +1 -0
  26. package/dist/backends/stubs/macos.d.ts +13 -0
  27. package/dist/backends/stubs/macos.js +27 -0
  28. package/dist/backends/stubs/macos.js.map +1 -0
  29. package/dist/backends/stubs/windows.d.ts +69 -0
  30. package/dist/backends/stubs/windows.js +191 -0
  31. package/dist/backends/stubs/windows.js.map +1 -0
  32. package/dist/cli.d.ts +37 -0
  33. package/dist/cli.js +177 -0
  34. package/dist/cli.js.map +1 -0
  35. package/dist/index.d.ts +13 -0
  36. package/dist/index.js +14 -0
  37. package/dist/index.js.map +1 -0
  38. package/dist/server/action-mapping.d.ts +21 -0
  39. package/dist/server/action-mapping.js +153 -0
  40. package/dist/server/action-mapping.js.map +1 -0
  41. package/dist/server/app.d.ts +23 -0
  42. package/dist/server/app.js +157 -0
  43. package/dist/server/app.js.map +1 -0
  44. package/dist/server/tool-registry.d.ts +50 -0
  45. package/dist/server/tool-registry.js +504 -0
  46. package/dist/server/tool-registry.js.map +1 -0
  47. package/dist/util/adb-files.d.ts +92 -0
  48. package/dist/util/adb-files.js +221 -0
  49. package/dist/util/adb-files.js.map +1 -0
  50. package/dist/util/adb-shell.d.ts +80 -0
  51. package/dist/util/adb-shell.js +102 -0
  52. package/dist/util/adb-shell.js.map +1 -0
  53. package/dist/util/android-apps.d.ts +10 -0
  54. package/dist/util/android-apps.js +103 -0
  55. package/dist/util/android-apps.js.map +1 -0
  56. package/dist/util/image-dim.d.ts +27 -0
  57. package/dist/util/image-dim.js +37 -0
  58. package/dist/util/image-dim.js.map +1 -0
  59. package/dist/util/ui-xml.d.ts +20 -0
  60. package/dist/util/ui-xml.js +184 -0
  61. package/dist/util/ui-xml.js.map +1 -0
  62. package/package.json +56 -0
@@ -0,0 +1,504 @@
1
+ /**
2
+ * MCP tool registry — verbs exposed by the device sandbox.
3
+ *
4
+ * Each tool entry carries:
5
+ * - a name (the MCP tool identifier, e.g. `click`)
6
+ * - a JSON schema describing the expected `arguments` payload
7
+ * - a `handler` that maps `arguments` → `SandboxBackend` method call.
8
+ *
9
+ * Filtering is driven entirely by `backend.tools` (a flat
10
+ * `ReadonlySet<string>` declared on each backend). The registry is
11
+ * purely a name → schema/handler lookup table; it does not encode
12
+ * support gates of its own. `listToolDescriptorsFor(backend)` filters
13
+ * via `backend.tools.has(name)`; `getToolFor(name, backend)` mirrors
14
+ * the same gate so `/mcp/tools/call` returns 404 (instead of 200 +
15
+ * runtime `unsupported`) for any tool the active backend doesn't
16
+ * advertise.
17
+ *
18
+ * Inspired by the Python `mcp_tools/registry.py` reference; verbs are kept
19
+ * verbatim for cross-runtime compatibility.
20
+ */
21
+ import { formatUiXmlToolOutput } from "../util/ui-xml.js";
22
+ /* ----------------------------------------------------------------------- */
23
+ /* Helpers */
24
+ /* ----------------------------------------------------------------------- */
25
+ function n(args, key) {
26
+ const v = args[key];
27
+ if (typeof v !== "number" || !Number.isFinite(v)) {
28
+ throw new TypeError(`argument '${key}' must be a finite number`);
29
+ }
30
+ return v;
31
+ }
32
+ function s(args, key) {
33
+ const v = args[key];
34
+ if (typeof v !== "string") {
35
+ throw new TypeError(`argument '${key}' must be a string`);
36
+ }
37
+ return v;
38
+ }
39
+ function optS(args, key) {
40
+ const v = args[key];
41
+ if (v === undefined || v === null)
42
+ return undefined;
43
+ if (typeof v !== "string")
44
+ throw new TypeError(`argument '${key}' must be a string`);
45
+ return v;
46
+ }
47
+ function optN(args, key) {
48
+ const v = args[key];
49
+ if (v === undefined || v === null)
50
+ return undefined;
51
+ if (typeof v !== "number" || !Number.isFinite(v)) {
52
+ throw new TypeError(`argument '${key}' must be a finite number`);
53
+ }
54
+ return v;
55
+ }
56
+ const xy = {
57
+ type: "object",
58
+ properties: {
59
+ x: { type: "number" },
60
+ y: { type: "number" },
61
+ },
62
+ required: ["x", "y"],
63
+ };
64
+ /* ----------------------------------------------------------------------- */
65
+ /* Tool definitions */
66
+ /* ----------------------------------------------------------------------- */
67
+ export const TOOLS = {
68
+ /* — observation — */
69
+ screenshot: {
70
+ descriptor: {
71
+ name: "screenshot",
72
+ description: "Capture a screenshot. Returns base64 image bytes plus actual " +
73
+ "image dimensions (width/height) and click coordinate-system " +
74
+ "dimensions (deviceWidth/deviceHeight).",
75
+ inputSchema: { type: "object", properties: {} },
76
+ },
77
+ handler: async (_args, { backend }) => {
78
+ // 0.2.3 split: `width/height` reflect the actual encoded bytes
79
+ // (so an agent that decodes `b64` always agrees with these
80
+ // numbers), while `deviceWidth/deviceHeight` carry the click
81
+ // coordinate-system size used by `tap(x, y)` / `click(x, y)`.
82
+ const shot = await backend.screenshot();
83
+ const size = await backend
84
+ .screenSize()
85
+ .catch(() => ({ w: shot.width, h: shot.height }));
86
+ return {
87
+ b64: shot.data.toString("base64"),
88
+ format: shot.format,
89
+ width: shot.width,
90
+ height: shot.height,
91
+ deviceWidth: size.w,
92
+ deviceHeight: size.h,
93
+ };
94
+ },
95
+ },
96
+ ui_dump: {
97
+ descriptor: {
98
+ name: "ui_dump",
99
+ description: "Dump the active UI hierarchy. Optional `query` filters nodes server-side.",
100
+ inputSchema: {
101
+ type: "object",
102
+ properties: {
103
+ query: { type: "string" },
104
+ format: { type: "string", enum: ["compact", "raw"] },
105
+ },
106
+ },
107
+ },
108
+ handler: async (args, { backend }) => {
109
+ const out = await backend.uiDump();
110
+ if (!out.supported)
111
+ return { supported: false };
112
+ const fmt = optS(args, "format") ?? "compact";
113
+ const query = optS(args, "query");
114
+ if (fmt === "raw")
115
+ return { supported: true, content: out.content ?? "" };
116
+ const compact = formatUiXmlToolOutput(out.content ?? "", query);
117
+ return { supported: true, content: compact };
118
+ },
119
+ },
120
+ device_info: {
121
+ descriptor: {
122
+ name: "device_info",
123
+ description: "Return DeviceInfo (type, name, screen size, capabilities, metadata).",
124
+ inputSchema: { type: "object", properties: {} },
125
+ },
126
+ // Always available — every backend has `info()` (platform metadata
127
+ // is the one thing even a stub backend can report). Backends still
128
+ // need to include `device_info` in their `tools` set to advertise
129
+ // it; the iOS stub uses this as its single advertised tool so the
130
+ // health check has something to call.
131
+ handler: async (_args, { backend }) => backend.info(),
132
+ },
133
+ screen_size: {
134
+ descriptor: {
135
+ name: "screen_size",
136
+ description: "Return current screen size (w, h).",
137
+ inputSchema: { type: "object", properties: {} },
138
+ },
139
+ handler: async (_args, { backend }) => backend.screenSize(),
140
+ },
141
+ /* — pointer / gesture — */
142
+ click: {
143
+ descriptor: {
144
+ name: "click",
145
+ description: "Mouse click at (x, y). Equivalent to tap on touch backends.",
146
+ inputSchema: {
147
+ type: "object",
148
+ properties: {
149
+ ...xy.properties,
150
+ button: { type: "string", enum: ["left", "right", "middle"] },
151
+ clicks: { type: "number" },
152
+ },
153
+ required: ["x", "y"],
154
+ },
155
+ },
156
+ handler: async (args, { backend }) => {
157
+ await backend.click(n(args, "x"), n(args, "y"), optS(args, "button") ?? "left", optN(args, "clicks") ?? 1);
158
+ return { ok: true };
159
+ },
160
+ },
161
+ double_click: {
162
+ descriptor: {
163
+ name: "double_click",
164
+ description: "Double click at (x, y).",
165
+ inputSchema: { ...xy },
166
+ },
167
+ handler: async (args, { backend }) => {
168
+ await backend.doubleClick(n(args, "x"), n(args, "y"));
169
+ return { ok: true };
170
+ },
171
+ },
172
+ right_click: {
173
+ descriptor: {
174
+ name: "right_click",
175
+ description: "Right click at (x, y).",
176
+ inputSchema: { ...xy },
177
+ },
178
+ handler: async (args, { backend }) => {
179
+ await backend.rightClick(n(args, "x"), n(args, "y"));
180
+ return { ok: true };
181
+ },
182
+ },
183
+ tap: {
184
+ descriptor: {
185
+ name: "tap",
186
+ description: "Tap at (x, y) on a touch device.",
187
+ inputSchema: { ...xy },
188
+ },
189
+ handler: async (args, { backend }) => {
190
+ await backend.tap(n(args, "x"), n(args, "y"));
191
+ return { ok: true };
192
+ },
193
+ },
194
+ long_press: {
195
+ descriptor: {
196
+ name: "long_press",
197
+ description: "Long-press at (x, y) for `durationMs` (default 3000).",
198
+ inputSchema: {
199
+ type: "object",
200
+ properties: {
201
+ ...xy.properties,
202
+ durationMs: { type: "number" },
203
+ },
204
+ required: ["x", "y"],
205
+ },
206
+ },
207
+ handler: async (args, { backend }) => {
208
+ await backend.longPress(n(args, "x"), n(args, "y"), optN(args, "durationMs"));
209
+ return { ok: true };
210
+ },
211
+ },
212
+ drag: {
213
+ descriptor: {
214
+ name: "drag",
215
+ description: "Drag from (x1, y1) to (x2, y2).",
216
+ inputSchema: {
217
+ type: "object",
218
+ properties: {
219
+ x1: { type: "number" },
220
+ y1: { type: "number" },
221
+ x2: { type: "number" },
222
+ y2: { type: "number" },
223
+ durationMs: { type: "number" },
224
+ },
225
+ required: ["x1", "y1", "x2", "y2"],
226
+ },
227
+ },
228
+ handler: async (args, { backend }) => {
229
+ await backend.drag(n(args, "x1"), n(args, "y1"), n(args, "x2"), n(args, "y2"), optN(args, "durationMs"));
230
+ return { ok: true };
231
+ },
232
+ },
233
+ swipe: {
234
+ descriptor: {
235
+ name: "swipe",
236
+ description: "Swipe from (x1, y1) to (x2, y2).",
237
+ inputSchema: {
238
+ type: "object",
239
+ properties: {
240
+ x1: { type: "number" },
241
+ y1: { type: "number" },
242
+ x2: { type: "number" },
243
+ y2: { type: "number" },
244
+ durationMs: { type: "number" },
245
+ },
246
+ required: ["x1", "y1", "x2", "y2"],
247
+ },
248
+ },
249
+ handler: async (args, { backend }) => {
250
+ await backend.swipe(n(args, "x1"), n(args, "y1"), n(args, "x2"), n(args, "y2"), optN(args, "durationMs"));
251
+ return { ok: true };
252
+ },
253
+ },
254
+ scroll: {
255
+ descriptor: {
256
+ name: "scroll",
257
+ description: "Scroll at (x, y) in `direction` (up | down | left | right).",
258
+ inputSchema: {
259
+ type: "object",
260
+ properties: {
261
+ x: { type: "number" },
262
+ y: { type: "number" },
263
+ direction: { type: "string", enum: ["up", "down", "left", "right"] },
264
+ amount: { type: "number" },
265
+ },
266
+ required: ["direction"],
267
+ },
268
+ },
269
+ handler: async (args, { backend }) => {
270
+ await backend.scroll(optN(args, "x") ?? 0, optN(args, "y") ?? 0, s(args, "direction"), optN(args, "amount"));
271
+ return { ok: true };
272
+ },
273
+ },
274
+ /* — keyboard — */
275
+ type: {
276
+ descriptor: {
277
+ name: "type",
278
+ description: "Type the given Unicode `text` into the focused field.",
279
+ inputSchema: {
280
+ type: "object",
281
+ properties: { text: { type: "string" } },
282
+ required: ["text"],
283
+ },
284
+ },
285
+ handler: async (args, { backend }) => {
286
+ await backend.typeText(s(args, "text"));
287
+ return { ok: true };
288
+ },
289
+ },
290
+ key: {
291
+ descriptor: {
292
+ name: "key",
293
+ description: "Press a single named key (e.g. `KEYCODE_HOME`, `Escape`).",
294
+ inputSchema: {
295
+ type: "object",
296
+ properties: { key: { type: "string" } },
297
+ required: ["key"],
298
+ },
299
+ },
300
+ handler: async (args, { backend }) => {
301
+ await backend.pressKey(s(args, "key"));
302
+ return { ok: true };
303
+ },
304
+ },
305
+ hotkey: {
306
+ descriptor: {
307
+ name: "hotkey",
308
+ description: "Press a hotkey combo, e.g. ['Cmd', 'Shift', 'P'].",
309
+ inputSchema: {
310
+ type: "object",
311
+ properties: {
312
+ keys: { type: "array", items: { type: "string" } },
313
+ },
314
+ required: ["keys"],
315
+ },
316
+ },
317
+ handler: async (args, { backend }) => {
318
+ const keys = args.keys;
319
+ if (!Array.isArray(keys) || keys.some((k) => typeof k !== "string")) {
320
+ throw new TypeError("argument 'keys' must be a string[]");
321
+ }
322
+ await backend.hotkey(...keys);
323
+ return { ok: true };
324
+ },
325
+ },
326
+ /* — system nav — */
327
+ back: {
328
+ descriptor: {
329
+ name: "back",
330
+ description: "Press the system back button (Android) / browser back.",
331
+ inputSchema: { type: "object", properties: {} },
332
+ },
333
+ handler: async (_args, { backend }) => {
334
+ await backend.back();
335
+ return { ok: true };
336
+ },
337
+ },
338
+ home: {
339
+ descriptor: {
340
+ name: "home",
341
+ description: "Press the system home button (Android).",
342
+ inputSchema: { type: "object", properties: {} },
343
+ },
344
+ handler: async (_args, { backend }) => {
345
+ await backend.home();
346
+ return { ok: true };
347
+ },
348
+ },
349
+ /* — app — */
350
+ launch_app: {
351
+ descriptor: {
352
+ name: "launch_app",
353
+ description: "Launch app by package or display name.",
354
+ inputSchema: {
355
+ type: "object",
356
+ properties: {
357
+ pkg: { type: "string" },
358
+ activity: { type: "string" },
359
+ },
360
+ required: ["pkg"],
361
+ },
362
+ },
363
+ handler: async (args, { backend }) => {
364
+ await backend.launchApp(s(args, "pkg"), optS(args, "activity"));
365
+ return { ok: true };
366
+ },
367
+ },
368
+ /* — shell / files — */
369
+ execute_command: {
370
+ descriptor: {
371
+ name: "execute_command",
372
+ description: "Run a shell command on the sandbox. Returns stdout/stderr/exitCode.",
373
+ inputSchema: {
374
+ type: "object",
375
+ properties: {
376
+ body: { type: "string" },
377
+ timeoutS: { type: "number" },
378
+ cwd: { type: "string" },
379
+ },
380
+ required: ["body"],
381
+ },
382
+ },
383
+ handler: async (args, { backend }) => backend.executeCommand(s(args, "body"), {
384
+ timeoutS: optN(args, "timeoutS"),
385
+ cwd: optS(args, "cwd"),
386
+ }),
387
+ },
388
+ file_read: {
389
+ descriptor: {
390
+ name: "file_read",
391
+ description: "Read a file from the sandbox. Returns base64 content.",
392
+ inputSchema: {
393
+ type: "object",
394
+ properties: { path: { type: "string" } },
395
+ required: ["path"],
396
+ },
397
+ },
398
+ handler: async (args, { backend }) => {
399
+ const buf = await backend.fileRead(s(args, "path"));
400
+ return { contentB64: buf.toString("base64"), bytes: buf.length };
401
+ },
402
+ },
403
+ file_write: {
404
+ descriptor: {
405
+ name: "file_write",
406
+ description: "Write base64 content to a file in the sandbox.",
407
+ inputSchema: {
408
+ type: "object",
409
+ properties: {
410
+ path: { type: "string" },
411
+ contentB64: { type: "string" },
412
+ },
413
+ required: ["path", "contentB64"],
414
+ },
415
+ },
416
+ handler: async (args, { backend }) => {
417
+ const buf = Buffer.from(s(args, "contentB64"), "base64");
418
+ await backend.fileWrite(s(args, "path"), buf);
419
+ return { ok: true, bytes: buf.length };
420
+ },
421
+ },
422
+ list_directory: {
423
+ descriptor: {
424
+ name: "list_directory",
425
+ description: "List directory entries.",
426
+ inputSchema: {
427
+ type: "object",
428
+ properties: { path: { type: "string" } },
429
+ required: ["path"],
430
+ },
431
+ },
432
+ handler: async (args, { backend }) => {
433
+ const entries = await backend.listDirectory(s(args, "path"));
434
+ return { entries };
435
+ },
436
+ },
437
+ /**
438
+ * `install_package` — backend-agnostic native-package install.
439
+ *
440
+ * Dispatches to whichever installer the backend implements (APK on
441
+ * Android, DMG/PKG on macOS, MSI/EXE on Windows, DEB/RPM on Linux).
442
+ * Wire-compatible alias `install_apk` is kept registered for
443
+ * existing agents that still hardcode the Android verb name.
444
+ *
445
+ * Reference: plan §3.4 — "工具命名上,去掉 backend 私有词".
446
+ */
447
+ install_package: installToolEntry("install_package"),
448
+ install_apk: installToolEntry("install_apk"),
449
+ };
450
+ function installToolEntry(name) {
451
+ return {
452
+ descriptor: {
453
+ name,
454
+ description: name === "install_package"
455
+ ? "Install a native package at `path`. Backend-agnostic — dispatches " +
456
+ "to APK / DMG / MSI / DEB based on the active backend."
457
+ : "Install an APK at `path` (Android only). Alias for `install_package`.",
458
+ inputSchema: {
459
+ type: "object",
460
+ properties: { path: { type: "string" } },
461
+ required: ["path"],
462
+ },
463
+ },
464
+ handler: async (args, { backend }) => {
465
+ await backend.install(s(args, "path"));
466
+ return { ok: true };
467
+ },
468
+ };
469
+ }
470
+ /* ----------------------------------------------------------------------- */
471
+ /* Public API */
472
+ /* ----------------------------------------------------------------------- */
473
+ /**
474
+ * Return ALL registered tool descriptors regardless of backend support.
475
+ *
476
+ * Useful for documentation / tests that want to enumerate the catalog.
477
+ * Wire callers SHOULD use `listToolDescriptorsFor(backend)` so the list
478
+ * only contains tools the active backend can actually execute.
479
+ */
480
+ export function listToolDescriptors() {
481
+ return Object.values(TOOLS).map((t) => t.descriptor);
482
+ }
483
+ /** Return tool descriptors filtered by the backend's advertised tool set. */
484
+ export function listToolDescriptorsFor(backend) {
485
+ return Object.values(TOOLS)
486
+ .filter((t) => backend.tools.has(t.descriptor.name))
487
+ .map((t) => t.descriptor);
488
+ }
489
+ /** Look up a tool by name, ignoring backend tool-set gates. */
490
+ export function getTool(name) {
491
+ return TOOLS[name];
492
+ }
493
+ /**
494
+ * Look up a tool by name, **gated** on the backend's advertised tool
495
+ * set. Returns `undefined` for tools the active backend cannot
496
+ * satisfy — the `/mcp/tools/call` route uses this and returns 404,
497
+ * mirroring the filtering applied at `/mcp/tools/list`.
498
+ */
499
+ export function getToolFor(name, backend) {
500
+ if (!backend.tools.has(name))
501
+ return undefined;
502
+ return TOOLS[name];
503
+ }
504
+ //# sourceMappingURL=tool-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tool-registry.js","sourceRoot":"","sources":["../../src/server/tool-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * adb-files — file-IO and listing primitives over the native `adb`
3
+ * `pull` / `push` / `shell ls` protocols.
4
+ *
5
+ * # Why this module exists
6
+ *
7
+ * Earlier versions of the Android backend did file IO with two ad-hoc
8
+ * tricks:
9
+ *
10
+ * - `fileRead` → `adb exec-out cat <path>` and decoded the bytes from
11
+ * stdout. This silently swallowed device-side `cat` errors because
12
+ * `adb exec-out` does NOT propagate the remote command's exit code
13
+ * back to the host adb client (the host always exits 0 when the
14
+ * channel closes cleanly), so reading a non-existent path returned
15
+ * `cat`'s stderr text base64-encoded as if it were file content.
16
+ *
17
+ * - `fileWrite` → `adb shell sh -c "echo <b64> | base64 -d > <path>"`.
18
+ * Because `adb shell` joins argv with spaces and re-evaluates through
19
+ * `sh -c`, the shell saw `sh -c sh -c echo <b64> | base64 -d > path`,
20
+ * which dropped the pipeline body, ran `sh -c echo` with no args, and
21
+ * left an empty file on the device. The bug went undetected because
22
+ * the host-side `adb` still returned exit 0.
23
+ *
24
+ * The right tools for this job are `adb pull` and `adb push`: they speak
25
+ * the file-sync protocol designed for binary transfer, the host-side
26
+ * `adb` exits with a non-zero code when the device-side path is missing
27
+ * or unwritable, and they side-step the shell tokeniser entirely. This
28
+ * module wraps those primitives in async-friendly helpers and routes
29
+ * every error through `wrapAdbFailure` so callers see the familiar
30
+ * `DeviceError` shape.
31
+ *
32
+ * `adbListDir` exists in this module rather than in the backend so the
33
+ * "use `ls -laL` to dereference symlinks" rule has a single home. The
34
+ * raw `ls -la` form does not deref symlinks (so listing `/sdcard` returns
35
+ * the symlink itself instead of the contents of `/storage/self/primary`,
36
+ * which is almost never what callers want).
37
+ */
38
+ import type { AdbRunner } from "../backends/android-adb-runner.js";
39
+ import type { ListDirectoryEntry } from "../backends/base.js";
40
+ export interface AdbFileOpOptions {
41
+ /** Hard timeout for the underlying `adb` invocation. */
42
+ timeoutMs: number;
43
+ /** Optional override for the host-side temp directory (tests). */
44
+ tmpdir?: () => string;
45
+ /** Cap stdout buffer for pull (defaults to 64 MiB). */
46
+ maxBufferBytes?: number;
47
+ }
48
+ /**
49
+ * Prepend `["-s", serial]` when a serial is set. Mirrors the private
50
+ * `adbArgs()` helper in the backend so the helpers here can build their
51
+ * own argv without leaking the backend's internal state.
52
+ */
53
+ export declare function withSerial(serial: string | undefined, args: readonly string[]): string[];
54
+ /**
55
+ * `adb pull <remote> <hostTmp>` followed by an in-memory read of the
56
+ * temp file. Throws `DeviceError(file_not_found)` when the device path
57
+ * does not exist (host-side adb exits with code 1 and prints
58
+ * `adb: error: failed to stat remote object ... No such file or directory`),
59
+ * and the generic `adb_failed` shape for everything else.
60
+ */
61
+ export declare function adbPull(runner: AdbRunner, serial: string | undefined, remote: string, opts: AdbFileOpOptions): Promise<Buffer>;
62
+ /**
63
+ * `adb push <hostTmp> <remote>`. The buffer is written to a temp file
64
+ * first because `adb push` reads from disk; piping into stdin is not
65
+ * supported by the file-sync protocol.
66
+ */
67
+ export declare function adbPush(runner: AdbRunner, serial: string | undefined, remote: string, content: Buffer, opts: AdbFileOpOptions): Promise<void>;
68
+ /**
69
+ * `ls -laL <path>` over `adb shell` (single-string command, properly
70
+ * quoted via `sh\`...\``). The `-L` flag dereferences symlinks so callers
71
+ * who pass `/sdcard` (a symlink to `/storage/self/primary` on stock AOSP)
72
+ * see the contents of the linked directory rather than a single
73
+ * `lrwxrwxrwx ... /sdcard -> /storage/self/primary` row.
74
+ *
75
+ * The runner contract is: throws on non-zero adb exit (the call site
76
+ * handles that with `wrapAdbFailure`); on success, parses the textual
77
+ * output via `parseLsOutput`.
78
+ */
79
+ export declare function adbListDir(runner: AdbRunner, serial: string | undefined, pathArg: string, opts: AdbFileOpOptions): Promise<ListDirectoryEntry[]>;
80
+ /**
81
+ * Parse the output of `ls -la` / `ls -laL` from Android's toybox `ls`
82
+ * into structured entries. Tolerates header lines (`total 12`) and skips
83
+ * the canonical `.` / `..` entries.
84
+ *
85
+ * Entry layout (toybox): `perms links owner group size month day time name`.
86
+ * We index by whitespace-split position rather than parsing each column
87
+ * type-by-type because Android's `ls` output is stable across releases.
88
+ *
89
+ * Exported here (not in the backend) so the symlink-dereferencing rule
90
+ * lives next to the `ls -laL` invocation it depends on.
91
+ */
92
+ export declare function parseLsOutput(out: string): ListDirectoryEntry[];