@nomac/cli 0.13.0 → 0.13.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nomac/cli",
3
- "version": "0.13.0",
3
+ "version": "0.13.1",
4
4
  "description": "Cloud Mac sessions over SSH and HTTPS, plus iOS builds and publishing — built for agents.",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",
@@ -28,19 +28,26 @@ export function transportOptions(options = {}) {
28
28
  return { url, token, agent: proxy ? new HttpsProxyAgent(proxy) : undefined, ca: options.ca };
29
29
  }
30
30
 
31
- /** How long a busy guest is retried before guest_busy reaches the caller. */
32
- export const GUEST_BUSY_RETRY = { budgetMs: 75_000, pauseMs: 3_000 };
31
+ /** How long a busy or briefly unreachable Mac is retried before the error reaches the caller. */
32
+ export const GUEST_BUSY_RETRY = { budgetMs: 120_000, pauseMs: 3_000 };
33
+ /**
34
+ * Passing failures: a saturated guest (a first Simulator boot answers slowly for a minute or
35
+ * two), a Mac whose network dropped for a moment (most nights at its provider, October 2026),
36
+ * an answer lost on the way, or the same request still starting (copies of it that waited out
37
+ * an outage reach the Mac together).
38
+ */
39
+ const PASSING = new Set(["guest_busy", "host_unavailable", "outcome_unknown", "operation_pending"]);
33
40
 
34
41
  /**
35
- * A saturated guest (e.g. a first Simulator boot) answers slowly for a minute or
36
- * two. Guest operations are idempotent by job ID, request key and blob offset, so
37
- * only guest_busy is retried; every other failure is returned for reconciliation.
42
+ * Guest operations are idempotent by job ID, request key and blob offset (a job start always
43
+ * carries its request key), so passing failures are retried with the same request; every other
44
+ * failure is returned for reconciliation.
38
45
  */
39
46
  export function macRequest(method, path, options = {}) {
40
47
  const started = Date.now();
41
48
  // The first attempt runs synchronously, so invalid input still throws immediately.
42
49
  const attempt = () => macRequestOnce(method, path, options).catch(async error => {
43
- if (error?.code !== "guest_busy" || Date.now() - started + GUEST_BUSY_RETRY.pauseMs + 15_000 > GUEST_BUSY_RETRY.budgetMs) throw error;
50
+ if (!PASSING.has(error?.code) || Date.now() - started + GUEST_BUSY_RETRY.pauseMs + 15_000 > GUEST_BUSY_RETRY.budgetMs) throw error;
44
51
  await new Promise(resolve => setTimeout(resolve, GUEST_BUSY_RETRY.pauseMs));
45
52
  return attempt();
46
53
  });
@@ -53,7 +53,8 @@ export function sshArgs(session, { batch = true } = {}) {
53
53
  ...(session.mode === "hosted" ? ["-F", "/dev/null", "-o", `UserKnownHostsFile=${session.knownHosts}`, "-o", "GlobalKnownHostsFile=/dev/null",
54
54
  "-o", `HostKeyAlias=nomac-${session.id}`, "-o", `ProxyCommand=${[process.execPath, cliEntry(), "tunnel", session.id].map(shellQuote).join(" ")}`] : []),
55
55
  "-o", "StrictHostKeyChecking=yes", "-o", "ForwardAgent=no",
56
- "-o", "ConnectTimeout=15", "-o", "ServerAliveInterval=15", "-o", "ServerAliveCountMax=3",
56
+ // Two minutes of silence: a network drop at the Macs' provider pauses the stream until it resumes.
57
+ "-o", "ConnectTimeout=15", "-o", "ServerAliveInterval=15", "-o", "ServerAliveCountMax=8",
57
58
  ...multiplexArgs(session),
58
59
  ...(batch ? ["-o", "BatchMode=yes", "-o", "ClearAllForwardings=yes"] : []),
59
60
  ...(session.port ? ["-p", String(session.port)] : []),
@@ -52,7 +52,7 @@ export function sshConfigBlock(local, alias, project, { platform = process.platf
52
52
  ` ProxyCommand ${quoted(node)} ${quoted(bin)} tunnel ${local.id}`,
53
53
  " ForwardAgent no",
54
54
  " ServerAliveInterval 15",
55
- " ServerAliveCountMax 3",
55
+ " ServerAliveCountMax 8",
56
56
  `${END} ${alias}`,
57
57
  ].join("\n");
58
58
  }