@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.
Files changed (2) hide show
  1. package/dist/cli.js +61 -1
  2. 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, join2(configDir(), "agent-device")), {
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() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@touchtechclub/simbox",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "On-demand iOS simulators & Android emulators on your own GitHub Actions minutes.",
5
5
  "repository": {
6
6
  "type": "git",