@touchtechclub/simbox 0.3.0 → 0.4.1
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/dist/cli.js +61 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -438,7 +438,57 @@ class Spinner {
|
|
|
438
438
|
|
|
439
439
|
// src/remote.ts
|
|
440
440
|
import { spawn } from "node:child_process";
|
|
441
|
+
import { join as join3 } from "node:path";
|
|
442
|
+
|
|
443
|
+
// src/device-registration.ts
|
|
444
|
+
import { randomUUID } from "node:crypto";
|
|
445
|
+
import { existsSync, mkdirSync as mkdirSync2, readdirSync, statSync, unlinkSync, writeFileSync as writeFileSync2 } from "node:fs";
|
|
446
|
+
import { homedir as homedir2 } from "node:os";
|
|
441
447
|
import { join as join2 } from "node:path";
|
|
448
|
+
var MAX_AGE_MS = 5 * 60000;
|
|
449
|
+
function registerDevice(info, options = {}) {
|
|
450
|
+
if (!process.env.T3CODE_HOME && !process.env.SIMBOX_DEVICE_REGISTRATION_DIR && ![".s5code", ".t3"].some((home) => existsSync(join2(homedir2(), home, "userdata", "server-runtime.json"))))
|
|
451
|
+
return;
|
|
452
|
+
try {
|
|
453
|
+
const directory = process.env.SIMBOX_DEVICE_REGISTRATION_DIR ?? join2(configDir(), "device-registrations");
|
|
454
|
+
mkdirSync2(directory, { recursive: true, mode: 448 });
|
|
455
|
+
for (const file of readdirSync(directory)) {
|
|
456
|
+
if (!/^[a-f0-9-]{36}\.json$/.test(file))
|
|
457
|
+
continue;
|
|
458
|
+
const path = join2(directory, file);
|
|
459
|
+
if (Date.now() - statSync(path).mtimeMs > MAX_AGE_MS)
|
|
460
|
+
unlinkSync(path);
|
|
461
|
+
}
|
|
462
|
+
const args = options.args ?? [];
|
|
463
|
+
const flag = (name) => {
|
|
464
|
+
const end = args.indexOf("--");
|
|
465
|
+
const flags = end < 0 ? args : args.slice(0, end);
|
|
466
|
+
const index = flags.indexOf(name);
|
|
467
|
+
return index >= 0 ? flags[index + 1] : flags.find((arg) => arg.startsWith(`${name}=`))?.slice(name.length + 1);
|
|
468
|
+
};
|
|
469
|
+
const id = randomUUID();
|
|
470
|
+
writeFileSync2(join2(directory, `${id}.json`), JSON.stringify({
|
|
471
|
+
version: 1,
|
|
472
|
+
createdAt: Date.now(),
|
|
473
|
+
...info,
|
|
474
|
+
platform: flag("--platform") ?? options.platform,
|
|
475
|
+
deviceId: flag("--udid") ?? flag("--serial"),
|
|
476
|
+
deviceName: flag("--device"),
|
|
477
|
+
agentSession: flag("--session"),
|
|
478
|
+
stop: options.stop === true,
|
|
479
|
+
autoBoot: !options.args,
|
|
480
|
+
apiUrl: apiBaseUrl(),
|
|
481
|
+
userToken: loadToken()
|
|
482
|
+
}), { mode: 384, flag: "wx" });
|
|
483
|
+
process.stderr.write(`[simbox-device:${id}]
|
|
484
|
+
`);
|
|
485
|
+
} catch {
|
|
486
|
+
process.stderr.write(`Could not notify S5 Code about this device; Simbox remains connected.
|
|
487
|
+
`);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
// src/remote.ts
|
|
442
492
|
var STARTUP_TIMEOUT_MS = 300000;
|
|
443
493
|
async function waitForAndroid(runId, options = {}) {
|
|
444
494
|
const deadline = Date.now() + (options.timeoutMs ?? 12 * 60000);
|
|
@@ -546,13 +596,15 @@ async function cmdExec(args) {
|
|
|
546
596
|
delete env.AGENT_DEVICE_REMOTE_CONFIG;
|
|
547
597
|
delete env.AGENT_DEVICE_DAEMON_BASE_URL;
|
|
548
598
|
const code = await new Promise((resolve, reject) => {
|
|
549
|
-
const child = spawn(bin, remoteArgs(args, info,
|
|
599
|
+
const child = spawn(bin, remoteArgs(args, info, join3(configDir(), "agent-device")), {
|
|
550
600
|
stdio: "inherit",
|
|
551
601
|
env
|
|
552
602
|
});
|
|
553
603
|
child.on("error", reject);
|
|
554
604
|
child.on("exit", (status) => resolve(status ?? 1));
|
|
555
605
|
});
|
|
606
|
+
if (code === 0 && !args.some((arg) => ["help", "--help", "-h", "--version", "version"].includes(arg)))
|
|
607
|
+
registerDevice(info, { args });
|
|
556
608
|
if (code !== 0) {
|
|
557
609
|
process.stderr.write("Simbox did not retry the device command (it may already have executed). Use `simbox exec session list` to inspect it; the next command refreshes the tunnel automatically.\n");
|
|
558
610
|
}
|
|
@@ -699,6 +751,7 @@ async function cmdSim(opts) {
|
|
|
699
751
|
info = await waitForRemote(info);
|
|
700
752
|
if (opts.platform === "android")
|
|
701
753
|
await waitForAndroid(info.runId);
|
|
754
|
+
registerDevice(info, { platform: opts.platform });
|
|
702
755
|
if (json) {
|
|
703
756
|
const payload = {
|
|
704
757
|
tunnel_url: info.tunnelUrl,
|
|
@@ -740,6 +793,13 @@ async function cmdStop() {
|
|
|
740
793
|
return;
|
|
741
794
|
}
|
|
742
795
|
await stopRun(run.id);
|
|
796
|
+
if (run.tunnelUrl && run.daemonToken)
|
|
797
|
+
registerDevice({
|
|
798
|
+
runId: run.id,
|
|
799
|
+
tunnelUrl: run.tunnelUrl,
|
|
800
|
+
daemonToken: run.daemonToken,
|
|
801
|
+
expiresAt: run.expiresAt
|
|
802
|
+
}, { stop: true });
|
|
743
803
|
console.log(`${pc3.green("✔")} Stop requested for run ${pc3.bold(run.id)}.`);
|
|
744
804
|
}
|
|
745
805
|
async function cmdRepair() {
|