@autenai/sdk 0.3.0 → 0.5.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.
- package/README.md +154 -0
- package/bin/auten.js +2 -0
- package/dist/cli/add-phone.d.ts +2 -0
- package/dist/cli/add-phone.d.ts.map +1 -0
- package/dist/cli/add-phone.js +254 -0
- package/dist/cli/add-phone.js.map +1 -0
- package/dist/cli/autocomplete.d.ts +31 -0
- package/dist/cli/autocomplete.d.ts.map +1 -0
- package/dist/cli/autocomplete.js +438 -0
- package/dist/cli/autocomplete.js.map +1 -0
- package/dist/cli/build-apk.d.ts +2 -0
- package/dist/cli/build-apk.d.ts.map +1 -0
- package/dist/cli/build-apk.js +97 -0
- package/dist/cli/build-apk.js.map +1 -0
- package/dist/cli/creds.d.ts +2 -0
- package/dist/cli/creds.d.ts.map +1 -0
- package/dist/cli/creds.js +147 -0
- package/dist/cli/creds.js.map +1 -0
- package/dist/cli/devices.d.ts +2 -0
- package/dist/cli/devices.d.ts.map +1 -0
- package/dist/cli/devices.js +38 -0
- package/dist/cli/devices.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +111 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/keys.d.ts +2 -0
- package/dist/cli/keys.d.ts.map +1 -0
- package/dist/cli/keys.js +88 -0
- package/dist/cli/keys.js.map +1 -0
- package/dist/cli/login.d.ts +2 -0
- package/dist/cli/login.d.ts.map +1 -0
- package/dist/cli/login.js +35 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/logo.d.ts +2 -0
- package/dist/cli/logo.d.ts.map +1 -0
- package/dist/cli/logo.js +11 -0
- package/dist/cli/logo.js.map +1 -0
- package/dist/cli/me.d.ts +2 -0
- package/dist/cli/me.d.ts.map +1 -0
- package/dist/cli/me.js +19 -0
- package/dist/cli/me.js.map +1 -0
- package/dist/cli/shell.d.ts +2 -0
- package/dist/cli/shell.d.ts.map +1 -0
- package/dist/cli/shell.js +22 -0
- package/dist/cli/shell.js.map +1 -0
- package/dist/cli/task.d.ts +2 -0
- package/dist/cli/task.d.ts.map +1 -0
- package/dist/cli/task.js +148 -0
- package/dist/cli/task.js.map +1 -0
- package/dist/cli/tasks.d.ts +2 -0
- package/dist/cli/tasks.d.ts.map +1 -0
- package/dist/cli/tasks.js +76 -0
- package/dist/cli/tasks.js.map +1 -0
- package/dist/cli/util.d.ts +46 -0
- package/dist/cli/util.d.ts.map +1 -0
- package/dist/cli/util.js +134 -0
- package/dist/cli/util.js.map +1 -0
- package/dist/package.json +56 -0
- package/dist/src/client.d.ts +81 -0
- package/dist/src/client.d.ts.map +1 -0
- package/dist/src/client.js +116 -0
- package/dist/src/client.js.map +1 -0
- package/dist/src/errors.d.ts +16 -0
- package/dist/src/errors.d.ts.map +1 -0
- package/dist/src/errors.js +31 -0
- package/dist/src/errors.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/phone.d.ts +115 -0
- package/dist/src/phone.d.ts.map +1 -0
- package/dist/src/phone.js +123 -0
- package/dist/src/phone.js.map +1 -0
- package/dist/src/transport.d.ts +14 -0
- package/dist/src/transport.d.ts.map +1 -0
- package/dist/src/transport.js +71 -0
- package/dist/src/transport.js.map +1 -0
- package/dist/src/types.d.ts +138 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/package.json +43 -26
- package/dist/index.d.mts +0 -424
- package/dist/index.d.ts +0 -424
- package/dist/index.js +0 -411
- package/dist/index.mjs +0 -379
package/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# auten
|
|
2
|
+
|
|
3
|
+
Programmatic control of Android phones through the Auten relay.
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
npm install @autenai/sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
Or install the CLI globally:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install -g @autenai/sdk
|
|
13
|
+
auten login
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Quickstart
|
|
17
|
+
|
|
18
|
+
### 1. Get a key
|
|
19
|
+
|
|
20
|
+
Sign up at https://auten.ai (or contact the operator of your relay) to receive an API key.
|
|
21
|
+
|
|
22
|
+
### 2. Save it
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
$ auten login
|
|
26
|
+
Relay base URL [https://relay.auten.ai]:
|
|
27
|
+
API key: ********************************
|
|
28
|
+
✓ Authenticated as my-team — 1 device(s), 0 task(s).
|
|
29
|
+
✓ Saved to ~/.autenrc
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The CLI also reads `AUTEN_API_KEY` and `AUTEN_BASE_URL` from the environment, so you don't need `.autenrc` in CI.
|
|
33
|
+
|
|
34
|
+
### 3. Send a task
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
$ auten devices
|
|
38
|
+
STATUS SERIAL MODEL SCREEN LASTSEEN
|
|
39
|
+
────── ──────────────── ──────── ───────── ───────────────────
|
|
40
|
+
online a4e0eff201d020fd SM-A556B 1080x2116 2026-05-04 09:00:00
|
|
41
|
+
|
|
42
|
+
$ auten task --speed lightning "open the calculator and compute 999÷3"
|
|
43
|
+
auten task
|
|
44
|
+
Phone: a4e0eff201d020fd
|
|
45
|
+
Speed: lightning
|
|
46
|
+
Prompt: open the calculator and compute 999÷3
|
|
47
|
+
|
|
48
|
+
✓ Task 0f3789ec-68b1-4322-9fe2-15b33dfd8dc6 dispatched.
|
|
49
|
+
→ Live: https://relay.auten.ai/w/a4e0eff201d020fd?t=...
|
|
50
|
+
→ status: running
|
|
51
|
+
→ status: completed
|
|
52
|
+
|
|
53
|
+
✓ done (10992ms, $0.0308) — Calculator displays 333.
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## SDK
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
import { Auten } from "@autenai/sdk";
|
|
60
|
+
|
|
61
|
+
const auten = new Auten({ apiKey: process.env.AUTEN_API_KEY! });
|
|
62
|
+
|
|
63
|
+
// Identity & devices
|
|
64
|
+
const me = await auten.me();
|
|
65
|
+
const devices = await auten.devices.list();
|
|
66
|
+
|
|
67
|
+
// Run a task and wait for the result
|
|
68
|
+
const result = await auten.tasks.run({
|
|
69
|
+
device: devices[0].serial,
|
|
70
|
+
prompt: "open instagram, scroll the feed for 30 seconds",
|
|
71
|
+
speed: "lightning",
|
|
72
|
+
});
|
|
73
|
+
console.log(result.status, result.verified, result.result?.summary);
|
|
74
|
+
|
|
75
|
+
// Or fire-and-forget + poll later
|
|
76
|
+
const { task_id } = await auten.tasks.create({ device, prompt });
|
|
77
|
+
const final = await auten.tasks.wait(task_id);
|
|
78
|
+
|
|
79
|
+
// Direct phone control
|
|
80
|
+
const phone = auten.phone(devices[0].serial);
|
|
81
|
+
const screen = await phone.look(); // SoM screenshot + element list
|
|
82
|
+
await phone.tap(500, 800);
|
|
83
|
+
await phone.type("hello", { x: 540, y: 700 });
|
|
84
|
+
await phone.openUrl("https://news.tv3.lt");
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Per-device credentials
|
|
88
|
+
|
|
89
|
+
Login data is encrypted server-side and only ever decrypted into the agent's
|
|
90
|
+
runtime when it actually needs to fill a form.
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
$ auten creds add --device a4e0eff... --service instagram \
|
|
94
|
+
--username myaccount --password secret
|
|
95
|
+
$ auten creds ls --device a4e0eff...
|
|
96
|
+
$ auten creds rm --device a4e0eff... instagram
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
From code:
|
|
100
|
+
|
|
101
|
+
```ts
|
|
102
|
+
const phone = auten.phone(serial);
|
|
103
|
+
await phone.credentials.save({ service: "instagram", username: "x", password: "y" });
|
|
104
|
+
const list = await phone.credentials.list();
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## API keys
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
$ auten keys # list yours
|
|
111
|
+
$ auten keys create laptop # mint a new key
|
|
112
|
+
✓ Key created.
|
|
113
|
+
sk_live_abcdef0123456789... # printed once
|
|
114
|
+
Save this key now — it will never be shown again.
|
|
115
|
+
$ auten keys revoke <id> # disable instantly
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Speed presets
|
|
119
|
+
|
|
120
|
+
`--speed` controls every artificial delay during replay:
|
|
121
|
+
|
|
122
|
+
| preset | settle | post-action | look-after-each |
|
|
123
|
+
|-------------|--------|-------------|-----------------|
|
|
124
|
+
| `fast` | 250ms | 350ms | yes (default) |
|
|
125
|
+
| `instant` | 50ms | 100ms | yes |
|
|
126
|
+
| `lightning` | 10ms | 30ms | no (skipped) |
|
|
127
|
+
|
|
128
|
+
`lightning` is the fastest but skips per-action verification — only use it for
|
|
129
|
+
flows that have already been verified once at `fast`.
|
|
130
|
+
|
|
131
|
+
## Configuration
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
AUTEN_API_KEY Your key (can be set in ~/.autenrc instead)
|
|
135
|
+
AUTEN_BASE_URL Relay URL — default https://relay.auten.ai
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Errors
|
|
139
|
+
|
|
140
|
+
```ts
|
|
141
|
+
import { AuthError, ApiError, DeviceOfflineError } from "@autenai/sdk";
|
|
142
|
+
|
|
143
|
+
try {
|
|
144
|
+
await auten.tasks.create({ device, prompt });
|
|
145
|
+
} catch (err) {
|
|
146
|
+
if (err instanceof DeviceOfflineError) /* phone disconnected from WS */;
|
|
147
|
+
if (err instanceof AuthError) /* bad / revoked key */;
|
|
148
|
+
if (err instanceof ApiError && err.status >= 500) /* relay error */;
|
|
149
|
+
}
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## License
|
|
153
|
+
|
|
154
|
+
MIT
|
package/bin/auten.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-phone.d.ts","sourceRoot":"","sources":["../../cli/add-phone.ts"],"names":[],"mappings":"AA6IA,wBAAsB,eAAe,IAAI,OAAO,CAAC,IAAI,CAAC,CAkGrD"}
|
|
@@ -0,0 +1,254 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Walk the user through adding a new phone:
|
|
3
|
+
* USB plug-in → ADB authorization → APK install → service config → WS verify.
|
|
4
|
+
*
|
|
5
|
+
* Uses the SDK to verify the WS connection appears against the relay.
|
|
6
|
+
*/
|
|
7
|
+
import { execFileSync } from "child_process";
|
|
8
|
+
import { existsSync, statSync } from "fs";
|
|
9
|
+
import { resolve } from "path";
|
|
10
|
+
import { homedir } from "os";
|
|
11
|
+
import { Auten } from "../src/index.js";
|
|
12
|
+
import { C, banner, step, ok, warn, info, fail, sleep, loadConfig } from "./util.js";
|
|
13
|
+
const PACKAGE = "com.sce.agent";
|
|
14
|
+
function adb(args, timeoutMs = 10_000) {
|
|
15
|
+
return execFileSync("adb", args, { encoding: "utf-8", timeout: timeoutMs }).trim();
|
|
16
|
+
}
|
|
17
|
+
function adbDevices() {
|
|
18
|
+
return adb(["devices"]).split("\n").slice(1)
|
|
19
|
+
.map(l => l.trim()).filter(Boolean)
|
|
20
|
+
.map(l => { const [serial, status] = l.split(/\s+/); return { serial, status }; });
|
|
21
|
+
}
|
|
22
|
+
function getDeviceInfo(serial) {
|
|
23
|
+
const prop = (k) => adb(["-s", serial, "shell", "getprop", k]).trim();
|
|
24
|
+
const model = prop("ro.product.model");
|
|
25
|
+
const androidVersion = prop("ro.build.version.release");
|
|
26
|
+
const sizeOut = adb(["-s", serial, "shell", "wm", "size"]);
|
|
27
|
+
const m = sizeOut.match(/(\d+)x(\d+)/);
|
|
28
|
+
const ipOut = adb(["-s", serial, "shell", "ip", "route"]);
|
|
29
|
+
const ipLine = ipOut.split("\n").find(l => l.includes("wlan0") && l.includes("src")) || "";
|
|
30
|
+
const tokens = ipLine.split(/\s+/);
|
|
31
|
+
const srcIdx = tokens.indexOf("src");
|
|
32
|
+
return {
|
|
33
|
+
serial,
|
|
34
|
+
model,
|
|
35
|
+
androidVersion,
|
|
36
|
+
screenWidth: m ? parseInt(m[1], 10) : 0,
|
|
37
|
+
screenHeight: m ? parseInt(m[2], 10) : 0,
|
|
38
|
+
wifiIp: srcIdx >= 0 && tokens[srcIdx + 1] ? tokens[srcIdx + 1] : "",
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function findApk() {
|
|
42
|
+
const candidates = [
|
|
43
|
+
process.env.APK_PATH,
|
|
44
|
+
resolve(process.cwd(), "../mobile-agent-apk/app/build/outputs/apk/debug/app-debug.apk"),
|
|
45
|
+
resolve(process.cwd(), "mobile-agent-apk/app/build/outputs/apk/debug/app-debug.apk"),
|
|
46
|
+
resolve(homedir(), ".sce-agent/apk/app-debug.apk"),
|
|
47
|
+
].filter(Boolean);
|
|
48
|
+
return candidates.find(p => existsSync(p)) || null;
|
|
49
|
+
}
|
|
50
|
+
function installApk(serial, apkPath) {
|
|
51
|
+
try {
|
|
52
|
+
const out = execFileSync("adb", ["-s", serial, "install", "-r", apkPath], { encoding: "utf-8", timeout: 120_000 });
|
|
53
|
+
if (out.includes("Success"))
|
|
54
|
+
return { ok: true };
|
|
55
|
+
return { ok: false, reinstallNeeded: false, error: out };
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
const e = err;
|
|
59
|
+
const msg = String(e.stderr || e.stdout || e.message || "");
|
|
60
|
+
if (msg.includes("INSTALL_FAILED_UPDATE_INCOMPATIBLE") || msg.includes("signatures do not match")) {
|
|
61
|
+
return { ok: false, reinstallNeeded: true, error: msg };
|
|
62
|
+
}
|
|
63
|
+
return { ok: false, reinstallNeeded: false, error: msg };
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
function configureServices(serial) {
|
|
67
|
+
adb(["-s", serial, "shell", "settings", "put", "secure", "enabled_accessibility_services",
|
|
68
|
+
`${PACKAGE}/${PACKAGE}.AgentAccessibilityService`]);
|
|
69
|
+
adb(["-s", serial, "shell", "settings", "put", "secure", "accessibility_enabled", "1"]);
|
|
70
|
+
adb(["-s", serial, "shell", "ime", "enable", `${PACKAGE}/.AgentIME`]);
|
|
71
|
+
adb(["-s", serial, "shell", "ime", "set", `${PACKAGE}/.AgentIME`]);
|
|
72
|
+
// Disable factory keyboards so they can't reclaim the default IME slot —
|
|
73
|
+
// AgentIME is headless and draws no UI; if any of these were active the
|
|
74
|
+
// user would still see a real keyboard pop up on EditText focus.
|
|
75
|
+
for (const kb of ["com.samsung.android.honeyboard", "com.google.android.inputmethod.latin", "com.touchtype.swiftkey"]) {
|
|
76
|
+
try {
|
|
77
|
+
adb(["-s", serial, "shell", "ime", "disable", kb]);
|
|
78
|
+
}
|
|
79
|
+
catch { }
|
|
80
|
+
}
|
|
81
|
+
for (const perm of ["android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.READ_EXTERNAL_STORAGE"]) {
|
|
82
|
+
try {
|
|
83
|
+
adb(["-s", serial, "shell", "pm", "grant", PACKAGE, perm]);
|
|
84
|
+
}
|
|
85
|
+
catch { }
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
function forceRestartApk(serial) {
|
|
89
|
+
// Toggle accessibility off then on so Android rebinds the service after force-stop.
|
|
90
|
+
try {
|
|
91
|
+
adb(["-s", serial, "shell", "am", "force-stop", PACKAGE]);
|
|
92
|
+
}
|
|
93
|
+
catch { }
|
|
94
|
+
adb(["-s", serial, "shell", "settings", "put", "secure", "accessibility_enabled", "0"]);
|
|
95
|
+
adb(["-s", serial, "shell", "settings", "put", "secure", "enabled_accessibility_services",
|
|
96
|
+
`${PACKAGE}/${PACKAGE}.AgentAccessibilityService`]);
|
|
97
|
+
adb(["-s", serial, "shell", "settings", "put", "secure", "accessibility_enabled", "1"]);
|
|
98
|
+
}
|
|
99
|
+
async function waitForDevice() {
|
|
100
|
+
let prompted = false;
|
|
101
|
+
while (true) {
|
|
102
|
+
const devs = adbDevices();
|
|
103
|
+
if (devs.length === 0) {
|
|
104
|
+
if (!prompted) {
|
|
105
|
+
warn("No phone detected.");
|
|
106
|
+
info("Plug in the phone via USB.");
|
|
107
|
+
info("Settings → About phone → tap 'Build number' 7 times to unlock Developer options.");
|
|
108
|
+
info("Settings → Developer options → enable 'USB debugging'.");
|
|
109
|
+
info("Waiting...");
|
|
110
|
+
prompted = true;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
else if (devs.length > 1) {
|
|
114
|
+
fail(`Multiple phones detected: ${devs.map(d => d.serial).join(", ")}`);
|
|
115
|
+
fail("Connect only one phone at a time.");
|
|
116
|
+
process.exit(1);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
return devs[0];
|
|
120
|
+
}
|
|
121
|
+
await sleep(2000);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
async function waitForAuthorization(serial) {
|
|
125
|
+
let prompted = false;
|
|
126
|
+
while (true) {
|
|
127
|
+
const d = adbDevices().find(x => x.serial === serial);
|
|
128
|
+
if (!d)
|
|
129
|
+
throw new Error(`Phone ${serial} disconnected.`);
|
|
130
|
+
if (d.status === "device")
|
|
131
|
+
return;
|
|
132
|
+
if (d.status === "unauthorized" && !prompted) {
|
|
133
|
+
warn("Authorization required.");
|
|
134
|
+
info("Unlock the phone, accept the 'Allow USB debugging' dialog, check 'Always allow'.");
|
|
135
|
+
info("Waiting...");
|
|
136
|
+
prompted = true;
|
|
137
|
+
}
|
|
138
|
+
else if (d.status !== "unauthorized" && d.status !== "device") {
|
|
139
|
+
fail(`Phone state '${d.status}' — try replugging USB.`);
|
|
140
|
+
process.exit(1);
|
|
141
|
+
}
|
|
142
|
+
await sleep(2000);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
export async function addPhoneCommand() {
|
|
146
|
+
const cfg = loadConfig();
|
|
147
|
+
banner("═════════════════════════════════════");
|
|
148
|
+
banner(" auten — Add Phone");
|
|
149
|
+
banner("═════════════════════════════════════");
|
|
150
|
+
console.log(`${C.dim}Relay: ${cfg.baseUrl}${C.reset}`);
|
|
151
|
+
try {
|
|
152
|
+
execFileSync("adb", ["version"], { encoding: "utf-8", timeout: 3000 });
|
|
153
|
+
}
|
|
154
|
+
catch {
|
|
155
|
+
fail("`adb` not found. Install Android platform-tools.");
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
const apkPath = findApk();
|
|
159
|
+
if (!apkPath) {
|
|
160
|
+
fail("APK not found.");
|
|
161
|
+
info("Build it first: `auten build-apk`");
|
|
162
|
+
info("Or set APK_PATH=/path/to/app-debug.apk");
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|
|
165
|
+
const apkAge = (Date.now() - statSync(apkPath).mtimeMs) / 1000 / 86400;
|
|
166
|
+
if (apkAge > 30)
|
|
167
|
+
warn(`APK is ${apkAge.toFixed(0)} days old — consider rebuilding (auten build-apk).`);
|
|
168
|
+
step(1, 6, "Detect connected phone");
|
|
169
|
+
const dev = await waitForDevice();
|
|
170
|
+
ok(`Phone detected: ${dev.serial}`);
|
|
171
|
+
step(2, 6, "Authorize USB debugging");
|
|
172
|
+
if (dev.status === "device")
|
|
173
|
+
ok("Already authorized.");
|
|
174
|
+
else {
|
|
175
|
+
await waitForAuthorization(dev.serial);
|
|
176
|
+
ok("Authorized.");
|
|
177
|
+
}
|
|
178
|
+
step(3, 6, "Read device info");
|
|
179
|
+
const dInfo = getDeviceInfo(dev.serial);
|
|
180
|
+
ok(`Model: ${dInfo.model} (Android ${dInfo.androidVersion})`);
|
|
181
|
+
ok(`Screen: ${dInfo.screenWidth}x${dInfo.screenHeight}`);
|
|
182
|
+
if (dInfo.wifiIp)
|
|
183
|
+
ok(`WiFi IP: ${dInfo.wifiIp}`);
|
|
184
|
+
else
|
|
185
|
+
warn("No WiFi IP detected — connect the phone to WiFi for the agent to reach the relay.");
|
|
186
|
+
step(4, 6, "Install APK");
|
|
187
|
+
let installResult = installApk(dev.serial, apkPath);
|
|
188
|
+
if (!installResult.ok && installResult.reinstallNeeded) {
|
|
189
|
+
warn("Existing install was signed with a different key — uninstalling and reinstalling.");
|
|
190
|
+
warn("Any data inside the SCE Agent app will be wiped.");
|
|
191
|
+
try {
|
|
192
|
+
adb(["-s", dev.serial, "uninstall", PACKAGE]);
|
|
193
|
+
}
|
|
194
|
+
catch { }
|
|
195
|
+
installResult = installApk(dev.serial, apkPath);
|
|
196
|
+
}
|
|
197
|
+
if (!installResult.ok) {
|
|
198
|
+
fail(`Install failed: ${installResult.error?.slice(0, 300)}`);
|
|
199
|
+
process.exit(1);
|
|
200
|
+
}
|
|
201
|
+
ok("APK installed.");
|
|
202
|
+
step(5, 6, "Enable accessibility, IME, permissions");
|
|
203
|
+
configureServices(dev.serial);
|
|
204
|
+
forceRestartApk(dev.serial);
|
|
205
|
+
ok("Services configured. APK restarted.");
|
|
206
|
+
step(6, 6, "Verify WS connection to relay");
|
|
207
|
+
info(`Polling ${cfg.baseUrl}/v1/devices for an online device matching '${dInfo.model}'...`);
|
|
208
|
+
const agent = new Auten(cfg);
|
|
209
|
+
const deadline = Date.now() + 60_000;
|
|
210
|
+
let online = null;
|
|
211
|
+
while (Date.now() < deadline) {
|
|
212
|
+
try {
|
|
213
|
+
const list = await agent.devices.list();
|
|
214
|
+
const candidate = list.find(d => d.online && d.model === dInfo.model);
|
|
215
|
+
if (candidate) {
|
|
216
|
+
online = { serial: candidate.serial };
|
|
217
|
+
break;
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
catch (err) {
|
|
221
|
+
info(`Relay query failed: ${err.message} — retrying...`);
|
|
222
|
+
}
|
|
223
|
+
await sleep(2000);
|
|
224
|
+
}
|
|
225
|
+
if (!online) {
|
|
226
|
+
fail("Phone did not appear online via WS within 60s.");
|
|
227
|
+
info("On phone: Settings → Accessibility → Auten Agent must be enabled.");
|
|
228
|
+
info("If accessibility is on but no WS: rebuild APK with the current relay URL via `auten build-apk`.");
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
ok(`Phone online: ${online.serial}`);
|
|
232
|
+
info("Round-tripping /look to confirm end-to-end flow...");
|
|
233
|
+
try {
|
|
234
|
+
const phone = agent.phone(online.serial);
|
|
235
|
+
const look = await phone.look();
|
|
236
|
+
ok(`/look returned ${look.elements.length} elements, ~${Math.round(look.annotated.length * 0.75 / 1024)} KB JPEG. End-to-end working.`);
|
|
237
|
+
}
|
|
238
|
+
catch (err) {
|
|
239
|
+
warn(`/look round-trip failed: ${err.message}`);
|
|
240
|
+
warn("WS connection is up but the phone could not return a screenshot. Investigate manually.");
|
|
241
|
+
}
|
|
242
|
+
console.log("");
|
|
243
|
+
banner("═════════════════════════════════════");
|
|
244
|
+
banner(" ✓ Phone ready — disconnect USB now");
|
|
245
|
+
banner("═════════════════════════════════════");
|
|
246
|
+
console.log("");
|
|
247
|
+
console.log(` Device serial: ${C.bold}${online.serial}${C.reset}`);
|
|
248
|
+
console.log(` Model: ${dInfo.model}`);
|
|
249
|
+
console.log(` Relay: ${cfg.baseUrl}`);
|
|
250
|
+
console.log("");
|
|
251
|
+
console.log(` ${C.dim}The phone keeps its WS connection over WiFi as long as the SCE Agent app is alive.${C.reset}`);
|
|
252
|
+
console.log("");
|
|
253
|
+
}
|
|
254
|
+
//# sourceMappingURL=add-phone.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"add-phone.js","sourceRoot":"","sources":["../../cli/add-phone.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface Suggestion {
|
|
2
|
+
name: string;
|
|
3
|
+
desc: string;
|
|
4
|
+
}
|
|
5
|
+
interface ReadOptions {
|
|
6
|
+
prompt: string;
|
|
7
|
+
/**
|
|
8
|
+
* Computes the suggestions to show beneath the prompt for the current input.
|
|
9
|
+
* Returning [] means no dropdown is visible.
|
|
10
|
+
*/
|
|
11
|
+
suggest: (line: string) => Suggestion[];
|
|
12
|
+
/** Older-first list of past entries. Up/Down recall them when no dropdown is visible. */
|
|
13
|
+
history?: string[];
|
|
14
|
+
maxVisible?: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function readLineWithSuggestions(opts: ReadOptions): Promise<string | null>;
|
|
17
|
+
/**
|
|
18
|
+
* Render a list and let the user navigate it with arrow keys; Enter returns
|
|
19
|
+
* the selected index, ESC/Ctrl+C returns null. The list stays on screen after
|
|
20
|
+
* selection so the user can see what they picked.
|
|
21
|
+
*/
|
|
22
|
+
export interface ListPickerOpts<T> {
|
|
23
|
+
items: T[];
|
|
24
|
+
render: (item: T, isSelected: boolean) => string;
|
|
25
|
+
header?: string;
|
|
26
|
+
footer?: string;
|
|
27
|
+
initialIndex?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare function selectFromList<T>(opts: ListPickerOpts<T>): Promise<number | null>;
|
|
30
|
+
export {};
|
|
31
|
+
//# sourceMappingURL=autocomplete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"autocomplete.d.ts","sourceRoot":"","sources":["../../cli/autocomplete.ts"],"names":[],"mappings":"AAcA,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,EAAE,CAAC;IACxC,yFAAyF;IACzF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAID,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAiQvF;AAkED;;;;GAIG;AACH,MAAM,WAAW,cAAc,CAAC,CAAC;IAC/B,KAAK,EAAE,CAAC,EAAE,CAAC;IACX,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,UAAU,EAAE,OAAO,KAAK,MAAM,CAAC;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,cAAc,CAAC,CAAC,EAAE,IAAI,EAAE,cAAc,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAoEvF"}
|