@molecule/api-code-sandbox-flyio 1.2.9 → 1.3.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 CHANGED
@@ -3,15 +3,11 @@ AUTO-GENERATED — DO NOT EDIT THIS FILE.
3
3
  Generated by `mlcl sync-docs` from the package's src/index.ts JSDoc + mlcl/registry.json.
4
4
  Edits here are overwritten on the next commit (molecule's pre-commit hook regenerates).
5
5
  To change this document, edit the module-level JSDoc in src/index.ts.
6
- Generated: 2026-10-16T16:08:45.819Z
6
+ Generated: 2026-10-17T03:41:21.100Z
7
7
  -->
8
8
 
9
9
  # @molecule/api-code-sandbox-flyio
10
10
 
11
- > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
12
- > It is written to be read by coding agents as much as by people, and is generated from this
13
- > package's source — edit `src/index.ts` JSDoc, not this file.
14
-
15
11
  Fly.io Machines code-sandbox provider for molecule.dev.
16
12
 
17
13
  Runs each sandbox as a Fly Machine — a Firecracker microVM — managed over the
@@ -20,6 +16,10 @@ SCALE-TO-ZERO: `sleep()` maps to Fly's `suspend`, which snapshots the microVM's
20
16
  memory to disk, and a suspended Machine bills for storage only. Waking is a
21
17
  resume from that snapshot rather than a cold boot.
22
18
 
19
+ > **Auto-generated, AI-first package reference** for the [molecule.dev](https://molecule.dev) ecosystem.
20
+ > It is written to be read by coding agents as much as by people, and is generated from this
21
+ > package's source — edit `src/index.ts` JSDoc, not this file.
22
+
23
23
  ## Quick Start
24
24
 
25
25
  ```typescript
@@ -384,6 +384,12 @@ interface FlyioConfig {
384
384
  * `suspend` is the scale-to-zero mapping (resume from a memory snapshot on the
385
385
  * next request) and `stop` is a full stop with a cold boot on wake; opt into
386
386
  * either deliberately.
387
+ *
388
+ * This is the provider's STEADY-STATE policy, reported as
389
+ * `SandboxProvider.defaultIdleAction`. A caller can override it for one sandbox
390
+ * with `SandboxConfig.idleAction` and restore this value afterwards with
391
+ * `Sandbox.setIdleAction` — which is what a production deploy does so its
392
+ * destination cannot suspend mid-copy (m103, 2026-10-17).
387
393
  */
388
394
  autostop?: 'off' | 'stop' | 'suspend'
389
395
  /**
@@ -440,12 +446,6 @@ interface FlyioConfig {
440
446
  * Falls back to `FLY_SANDBOX_PRIVATE_SERVICES` (`<app>:<port>` pairs).
441
447
  *
442
448
  * Without this, a project with a database DOES NOT WORK on Fly: per-project
443
- * 6PNs are what stop tenants reaching each other, and the same isolation stops
444
- * a sandbox reaching the database it is supposed to use. Flycast is the only
445
- * mechanism Fly documents that grants ONE directed edge without exposing
446
- * anything publicly — see the `flycast.ts` module description.
447
- *
448
- * The declared PORT is load-bearing twice: it is unioned into
449
449
  // … truncated — the full declaration is in node_modules/@molecule/api-code-sandbox-flyio/dist/types.d.ts
450
450
  ```
451
451
 
@@ -1527,28 +1527,58 @@ function isFailedState(state: FlyMachineState): boolean
1527
1527
 
1528
1528
  **Returns:** `true` for `failed` and `launch_failed`.
1529
1529
 
1530
- #### `isTransientExecPrecondition(error)`
1530
+ #### `isTransientExecPrecondition(error, machineState)`
1531
1531
 
1532
- Whether a failed exec is Fly's TRANSIENT precondition — the request reached
1533
- the Machine's exec agent and the connection was dropped before the command
1534
- ran (`412 failed_precondition: exec request failed: EOF`) — rather than the
1535
- Machine being in a state an exec cannot run in.
1532
+ Whether a failed exec is Fly's TRANSIENT precondition — one a repeat (after a
1533
+ short wait) can clear, rather than a Machine state the exec has to wait out.
1536
1534
 
1537
- The distinction decides what retrying can achieve. A dropped connection is
1538
- worth repeating: the Machine is `started` and its agent recovers in seconds.
1539
- `failed_precondition: machine not running` is NOT — the Machine really is not
1540
- running, and that is what {@link FlyioSandboxProvider.startMachine} waits out
1541
- before the first exec. Repeating the exec there would only burn the caller's
1542
- budget against a condition the wait endpoint already answers.
1535
+ Fly answers the exec endpoint with 412 in two different situations, and only
1536
+ the BODY and the Machine's own reported state separate them:
1537
+
1538
+ 1. `failed_precondition: exec request failed: EOF` — the request reached the
1539
+ Machine's exec agent and the connection dropped before the command ran.
1540
+ Always transient: the Machine is `started` and its agent recovers in
1541
+ seconds.
1542
+ 2. `failed_precondition: machine not running` — transient ONLY while Fly's
1543
+ own Machines API reports the Machine `started`, `starting` or `replacing`
1544
+ (`machineState`). The exec endpoint lags the state Fly reports: a Machine
1545
+ whose config or image was just updated, or that is seconds past boot,
1546
+ reads `started` in `GET /machines/{id}` while its exec endpoint still
1547
+ refuses requests. Against a Machine Fly reports `stopped`/`suspended`/
1548
+ `destroyed` the same body is the REAL precondition — the Machine is not
1549
+ running, and {@link FlyioSandboxProvider.startMachine} is what answers it;
1550
+ repeating the exec would only burn the caller's budget.
1543
1551
 
1544
1552
  ```typescript
1545
- function isTransientExecPrecondition(error: unknown): boolean
1553
+ function isTransientExecPrecondition(error: unknown, machineState?: string | null): boolean
1546
1554
  ```
1547
1555
 
1548
1556
  - `error` — The failure an exec attempt raised.
1557
+ - `machineState` — The state `GET /machines/{id}` reports for the Machine, or `null`/`undefined` when it could not be read (which classifies case 2 as NOT transient — an unknown state is never assumed recoverable).
1549
1558
 
1550
1559
  **Returns:** `true` when repeating the exec is the right recovery.
1551
1560
 
1561
+ #### `isMachineWarmingUp(state)`
1562
+
1563
+ Whether a state Fly reports for a Machine means the Machine is up, or on its
1564
+ way up — the states in which an exec that was refused for `machine not
1565
+ running` is the exec endpoint lagging the state, not the truth.
1566
+
1567
+ A deliberate allow-list rather than "anything but stopped/suspended": the
1568
+ three states here are the ones a refused exec was observed to recover from,
1569
+ and every other state — `stopped`, `suspended`, `destroyed`, `failed`,
1570
+ `created`, unreadable — keeps today's immediate throw. Widening it without
1571
+ that evidence would turn a real precondition into a retry budget spent
1572
+ against a Machine that is not coming up.
1573
+
1574
+ ```typescript
1575
+ function isMachineWarmingUp(state: string | null | undefined): boolean
1576
+ ```
1577
+
1578
+ - `state` — The Machine state from `GET /machines/{id}`, if readable.
1579
+
1580
+ **Returns:** `true` when waiting and repeating the exec can clear the refusal.
1581
+
1552
1582
  #### `createProvider(config, client, store)`
1553
1583
 
1554
1584
  Creates a Fly.io Machines sandbox provider.
@@ -11,22 +11,49 @@ import { FlyApiClient } from './api.js';
11
11
  import { type ObjectStore } from './storage.js';
12
12
  import type { FlyioConfig } from './types.js';
13
13
  /**
14
- * Whether a failed exec is Fly's TRANSIENT precondition — the request reached
15
- * the Machine's exec agent and the connection was dropped before the command
16
- * ran (`412 failed_precondition: exec request failed: EOF`) — rather than the
17
- * Machine being in a state an exec cannot run in.
14
+ * Whether a failed exec is Fly's TRANSIENT precondition — one a repeat (after a
15
+ * short wait) can clear, rather than a Machine state the exec has to wait out.
18
16
  *
19
- * The distinction decides what retrying can achieve. A dropped connection is
20
- * worth repeating: the Machine is `started` and its agent recovers in seconds.
21
- * `failed_precondition: machine not running` is NOT — the Machine really is not
22
- * running, and that is what {@link FlyioSandboxProvider.startMachine} waits out
23
- * before the first exec. Repeating the exec there would only burn the caller's
24
- * budget against a condition the wait endpoint already answers.
17
+ * Fly answers the exec endpoint with 412 in two different situations, and only
18
+ * the BODY and the Machine's own reported state separate them:
19
+ *
20
+ * 1. `failed_precondition: exec request failed: EOF` — the request reached the
21
+ * Machine's exec agent and the connection dropped before the command ran.
22
+ * Always transient: the Machine is `started` and its agent recovers in
23
+ * seconds.
24
+ * 2. `failed_precondition: machine not running` — transient ONLY while Fly's
25
+ * own Machines API reports the Machine `started`, `starting` or `replacing`
26
+ * (`machineState`). The exec endpoint lags the state Fly reports: a Machine
27
+ * whose config or image was just updated, or that is seconds past boot,
28
+ * reads `started` in `GET /machines/{id}` while its exec endpoint still
29
+ * refuses requests. Against a Machine Fly reports `stopped`/`suspended`/
30
+ * `destroyed` the same body is the REAL precondition — the Machine is not
31
+ * running, and {@link FlyioSandboxProvider.startMachine} is what answers it;
32
+ * repeating the exec would only burn the caller's budget.
25
33
  *
26
34
  * @param error - The failure an exec attempt raised.
35
+ * @param machineState - The state `GET /machines/{id}` reports for the Machine,
36
+ * or `null`/`undefined` when it could not be read (which classifies case 2 as
37
+ * NOT transient — an unknown state is never assumed recoverable).
27
38
  * @returns `true` when repeating the exec is the right recovery.
28
39
  */
29
- export declare function isTransientExecPrecondition(error: unknown): boolean;
40
+ export declare function isTransientExecPrecondition(error: unknown, machineState?: string | null): boolean;
41
+ /**
42
+ * Whether a state Fly reports for a Machine means the Machine is up, or on its
43
+ * way up — the states in which an exec that was refused for `machine not
44
+ * running` is the exec endpoint lagging the state, not the truth.
45
+ *
46
+ * A deliberate allow-list rather than "anything but stopped/suspended": the
47
+ * three states here are the ones a refused exec was observed to recover from,
48
+ * and every other state — `stopped`, `suspended`, `destroyed`, `failed`,
49
+ * `created`, unreadable — keeps today's immediate throw. Widening it without
50
+ * that evidence would turn a real precondition into a retry budget spent
51
+ * against a Machine that is not coming up.
52
+ *
53
+ * @param state - The Machine state from `GET /machines/{id}`, if readable.
54
+ * @returns `true` when waiting and repeating the exec can clear the refusal.
55
+ */
56
+ export declare function isMachineWarmingUp(state: string | null | undefined): boolean;
30
57
  /**
31
58
  * Creates a Fly.io Machines sandbox provider.
32
59
  * @param config - Optional Fly configuration: API token/URL, org slug, app
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAWV,eAAe,EAGhB,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EAAE,YAAY,EAAgC,MAAM,UAAU,CAAA;AAwBrE,OAAO,EAAmD,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAEhG,OAAO,KAAK,EAIV,WAAW,EAUZ,MAAM,YAAY,CAAA;AAkBnB;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAGnE;AA8oFD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE,YAAY,EACrB,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,GACzB,eAAe,CAEjB"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAMH,OAAO,KAAK,EAYV,eAAe,EAGhB,MAAM,4BAA4B,CAAA;AAGnC,OAAO,EAAE,YAAY,EAAgC,MAAM,UAAU,CAAA;AAwBrE,OAAO,EAAmD,KAAK,WAAW,EAAE,MAAM,cAAc,CAAA;AAEhG,OAAO,KAAK,EAIV,WAAW,EAUZ,MAAM,YAAY,CAAA;AAkBnB;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAIjG;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE5E;AAkyFD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAC5B,MAAM,CAAC,EAAE,WAAW,EACpB,MAAM,CAAC,EAAE,YAAY,EACrB,KAAK,CAAC,EAAE,WAAW,GAAG,IAAI,GACzB,eAAe,CAEjB"}
package/dist/provider.js CHANGED
@@ -32,25 +32,56 @@ function describeDestroyFailure(step, id, error) {
32
32
  return `Fly sandbox destroy failed at the ${step} for ${id} (${status}): ${reason}`;
33
33
  }
34
34
  /**
35
- * Whether a failed exec is Fly's TRANSIENT precondition — the request reached
36
- * the Machine's exec agent and the connection was dropped before the command
37
- * ran (`412 failed_precondition: exec request failed: EOF`) — rather than the
38
- * Machine being in a state an exec cannot run in.
35
+ * Whether a failed exec is Fly's TRANSIENT precondition — one a repeat (after a
36
+ * short wait) can clear, rather than a Machine state the exec has to wait out.
39
37
  *
40
- * The distinction decides what retrying can achieve. A dropped connection is
41
- * worth repeating: the Machine is `started` and its agent recovers in seconds.
42
- * `failed_precondition: machine not running` is NOT — the Machine really is not
43
- * running, and that is what {@link FlyioSandboxProvider.startMachine} waits out
44
- * before the first exec. Repeating the exec there would only burn the caller's
45
- * budget against a condition the wait endpoint already answers.
38
+ * Fly answers the exec endpoint with 412 in two different situations, and only
39
+ * the BODY and the Machine's own reported state separate them:
40
+ *
41
+ * 1. `failed_precondition: exec request failed: EOF` — the request reached the
42
+ * Machine's exec agent and the connection dropped before the command ran.
43
+ * Always transient: the Machine is `started` and its agent recovers in
44
+ * seconds.
45
+ * 2. `failed_precondition: machine not running` — transient ONLY while Fly's
46
+ * own Machines API reports the Machine `started`, `starting` or `replacing`
47
+ * (`machineState`). The exec endpoint lags the state Fly reports: a Machine
48
+ * whose config or image was just updated, or that is seconds past boot,
49
+ * reads `started` in `GET /machines/{id}` while its exec endpoint still
50
+ * refuses requests. Against a Machine Fly reports `stopped`/`suspended`/
51
+ * `destroyed` the same body is the REAL precondition — the Machine is not
52
+ * running, and {@link FlyioSandboxProvider.startMachine} is what answers it;
53
+ * repeating the exec would only burn the caller's budget.
46
54
  *
47
55
  * @param error - The failure an exec attempt raised.
56
+ * @param machineState - The state `GET /machines/{id}` reports for the Machine,
57
+ * or `null`/`undefined` when it could not be read (which classifies case 2 as
58
+ * NOT transient — an unknown state is never assumed recoverable).
48
59
  * @returns `true` when repeating the exec is the right recovery.
49
60
  */
50
- export function isTransientExecPrecondition(error) {
61
+ export function isTransientExecPrecondition(error, machineState) {
51
62
  if (!(error instanceof FlyApiError) || error.status !== 412)
52
63
  return false;
53
- return EXEC_BODY_TRANSIENT.test(error.body) && !EXEC_BODY_MACHINE_NOT_RUNNING.test(error.body);
64
+ if (EXEC_BODY_DROPPED_CONNECTION.test(error.body))
65
+ return true;
66
+ return EXEC_BODY_MACHINE_NOT_RUNNING.test(error.body) && isMachineWarmingUp(machineState);
67
+ }
68
+ /**
69
+ * Whether a state Fly reports for a Machine means the Machine is up, or on its
70
+ * way up — the states in which an exec that was refused for `machine not
71
+ * running` is the exec endpoint lagging the state, not the truth.
72
+ *
73
+ * A deliberate allow-list rather than "anything but stopped/suspended": the
74
+ * three states here are the ones a refused exec was observed to recover from,
75
+ * and every other state — `stopped`, `suspended`, `destroyed`, `failed`,
76
+ * `created`, unreadable — keeps today's immediate throw. Widening it without
77
+ * that evidence would turn a real precondition into a retry budget spent
78
+ * against a Machine that is not coming up.
79
+ *
80
+ * @param state - The Machine state from `GET /machines/{id}`, if readable.
81
+ * @returns `true` when waiting and repeating the exec can clear the refusal.
82
+ */
83
+ export function isMachineWarmingUp(state) {
84
+ return state === 'started' || state === 'starting' || state === 'replacing';
54
85
  }
55
86
  /**
56
87
  * Default sandbox image. Fly pulls images itself, so this MUST be a reference
@@ -184,21 +215,25 @@ const MACHINE_CREATE_RETRY_STATUSES = [404, 412];
184
215
  * Machine's exec agent died before the command ran: `412 {"error":
185
216
  * "failed_precondition: exec request failed: EOF"}`. The Machine is `started`;
186
217
  * the agent inside it dropped the request (a Machine seconds past boot, or
187
- * Fly's own exec burst). The SAME status carries the precondition this provider
188
- * already handles — `failed_precondition: machine not running` — which is a
189
- * real state, not a dropped connection, and is reconciled by `startMachine`
190
- * BEFORE the first exec instead of by repeating it (see {@link
191
- * isTransientExecPrecondition}).
218
+ * Fly's own exec burst).
219
+ */
220
+ const EXEC_BODY_DROPPED_CONNECTION = /exec request failed/i;
221
+ /**
222
+ * The OTHER 412 the exec endpoint answers — `{"error":"failed_precondition:
223
+ * machine not running"}`. Whether that is the real precondition or the exec
224
+ * endpoint lagging a Machine that is up cannot be read off the body, so it is
225
+ * settled by the state Fly reports for the Machine at that moment
226
+ * ({@link isMachineWarmingUp}).
192
227
  */
193
- const EXEC_BODY_TRANSIENT = /exec request failed/i;
194
- /** The real-precondition 412, which retrying an exec cannot fix. */
195
228
  const EXEC_BODY_MACHINE_NOT_RUNNING = /machine not running/i;
196
229
  /**
197
- * Attempts for one exec when Fly answers the transient 412 of
198
- * {@link EXEC_BODY_TRANSIENT}. Four attempts over the three backoffs below is
199
- * under 12 s of waiting, against the ~75 s each fresh production deploy costs
200
- * when this is left to a caller: X1 run flash-m85 (2026-10-16) lost three
201
- * consecutive deploys, and the run, to this one condition.
230
+ * Attempts for one exec when Fly answers a transient 412 — either body of
231
+ * {@link isTransientExecPrecondition}. Four attempts over the three backoffs
232
+ * below is under 12 s of waiting, against the ~75 s each fresh production
233
+ * deploy costs when this is left to a caller: X1 run flash-m85 (2026-10-16)
234
+ * lost three consecutive deploys, and the run, to the dropped connection;
235
+ * flash-m94 (2026-10-16) lost 65 s and a whole redeploy to the same budget not
236
+ * covering `machine not running` on a Machine Fly reported `started`.
202
237
  */
203
238
  const EXEC_PRECONDITION_ATTEMPTS = 4;
204
239
  /**
@@ -258,6 +293,15 @@ const PROBE_EXEC_HEADROOM_SECONDS = 10;
258
293
  */
259
294
  class FlyioSandboxProvider {
260
295
  name = 'flyio';
296
+ /**
297
+ * The idle policy a sandbox gets when its own create does not name one — this
298
+ * provider's configured `autostop` (`FLY_PRODUCTION_AUTOSTOP` for production
299
+ * hosting). {@link SandboxConfig.idleAction} overrides it per Machine, and
300
+ * {@link Sandbox.setIdleAction} puts it back, which is how a deploy keeps its
301
+ * destination awake through a multi-minute copy and then returns the Machine
302
+ * to the app's real cost policy.
303
+ */
304
+ defaultIdleAction;
261
305
  config;
262
306
  client;
263
307
  metadataPrefix;
@@ -280,6 +324,7 @@ class FlyioSandboxProvider {
280
324
  */
281
325
  constructor(config = {}, client, store) {
282
326
  this.config = config;
327
+ this.defaultIdleAction = config.autostop ?? 'off';
283
328
  this.metadataPrefix = config.metadataPrefix ?? DEFAULT_METADATA_PREFIX;
284
329
  if (store !== undefined)
285
330
  this.templateStoreCache = store;
@@ -375,10 +420,14 @@ class FlyioSandboxProvider {
375
420
  * instead driven by the consumer's own per-tier hibernation loop, which calls
376
421
  * `sleep()`/`hibernate()` — the same provider-agnostic mechanism the Docker
377
422
  * bond relies on. An operator who wants Fly-native scale-to-zero can still opt
378
- * in with `config.autostop: 'suspend'`.
423
+ * in with `config.autostop: 'suspend'`, and a caller can override it for ONE
424
+ * Machine with {@link SandboxConfig.idleAction} (a production deploy keeps its
425
+ * destination `'off'` until the artifact has landed and the app is healthy).
426
+ * @param action - The idle action for this Machine's service; defaults to the
427
+ * provider's configured policy.
379
428
  * @returns The service definition, or `undefined`.
380
429
  */
381
- previewService() {
430
+ previewService(action = this.defaultIdleAction) {
382
431
  if (this.config.publicService === false)
383
432
  return undefined;
384
433
  return {
@@ -389,7 +438,7 @@ class FlyioSandboxProvider {
389
438
  { port: 443, handlers: ['tls', 'http'] },
390
439
  ],
391
440
  autostart: true,
392
- autostop: this.config.autostop ?? 'off',
441
+ autostop: action,
393
442
  min_machines_running: 0,
394
443
  };
395
444
  }
@@ -1126,7 +1175,7 @@ class FlyioSandboxProvider {
1126
1175
  // rootfs and only durable state pays the volume's small-file IO cost.
1127
1176
  machineConfig.mounts = [{ volume: volumeId, path: config.volumeMountPath ?? WORKSPACE_PATH }];
1128
1177
  }
1129
- const service = this.previewService();
1178
+ const service = this.previewService(config.idleAction);
1130
1179
  if (service)
1131
1180
  machineConfig.services = [service];
1132
1181
  const machine = await this.client.request(`/apps/${app}/machines`, {
@@ -1837,6 +1886,34 @@ class FlyioSandboxProvider {
1837
1886
  // ---------------------------------------------------------------------------
1838
1887
  // Sandbox
1839
1888
  // ---------------------------------------------------------------------------
1889
+ /**
1890
+ * Reads the state Fly reports for a Machine, or `null` when it cannot be read.
1891
+ *
1892
+ * Best-effort on purpose: this runs both on the failure path and just before a
1893
+ * retry, and a failed diagnostic read must not replace the failure it is
1894
+ * describing. `null` is meaningful — it never classifies a refusal as
1895
+ * recoverable (see {@link isTransientExecPrecondition}).
1896
+ *
1897
+ * @param app - The Fly app name.
1898
+ * @param machineId - The Fly Machine id.
1899
+ * @returns The Machine's state, or `null` when the read failed or 404'd.
1900
+ */
1901
+ async readMachineState(app, machineId) {
1902
+ try {
1903
+ const machine = await this.client.request(`/apps/${app}/machines/${machineId}`, {
1904
+ nullOn: [404],
1905
+ });
1906
+ return machine?.state ?? null;
1907
+ }
1908
+ catch (error) {
1909
+ logger.debug('Could not read the Machine state while an exec was refused', {
1910
+ app,
1911
+ machineId,
1912
+ error,
1913
+ });
1914
+ return null;
1915
+ }
1916
+ }
1840
1917
  /**
1841
1918
  * Issues one Fly exec call against a Machine.
1842
1919
  *
@@ -1875,28 +1952,38 @@ class FlyioSandboxProvider {
1875
1952
  return response ?? {};
1876
1953
  }
1877
1954
  catch (error) {
1878
- if (!isTransientExecPrecondition(error)) {
1879
- throw await this.withMachineState(error, app, machineId);
1955
+ // Which 412 this is cannot be read off the body alone: `machine not
1956
+ // running` is transient against a Machine Fly reports `started` and the
1957
+ // real precondition against one it reports `stopped`. So the state is
1958
+ // read here, once, and the same read decides the classification, the
1959
+ // wait below, and the state the error finally names.
1960
+ const state = error instanceof FlyApiError && error.status === 412
1961
+ ? await this.readMachineState(app, machineId)
1962
+ : null;
1963
+ if (!isTransientExecPrecondition(error, state)) {
1964
+ throw await this.withMachineState(error, app, machineId, state);
1880
1965
  }
1881
1966
  if (attempt >= EXEC_PRECONDITION_ATTEMPTS || Date.now() >= deadline) {
1882
- logger.warn('Fly kept dropping the exec connection; giving up on this exec', {
1967
+ logger.warn('Fly kept refusing the exec with a transient precondition', {
1883
1968
  app,
1884
1969
  machineId,
1885
1970
  attempt,
1971
+ state: state ?? 'unreadable',
1886
1972
  });
1887
- throw await this.withMachineState(error, app, machineId);
1973
+ throw await this.withMachineState(error, app, machineId, state);
1888
1974
  }
1889
- logger.warn('Fly dropped the exec connection (412 exec request failed); retrying', {
1975
+ logger.warn('Fly refused the exec with a transient precondition; retrying', {
1890
1976
  app,
1891
1977
  machineId,
1892
1978
  attempt,
1893
1979
  attempts: EXEC_PRECONDITION_ATTEMPTS,
1980
+ state: state ?? 'unreadable',
1894
1981
  });
1895
1982
  // The Machine is up (that is what makes this 412 the transient one), but
1896
1983
  // re-read it anyway: `stop`/`suspend` can land between attempts, and
1897
1984
  // retrying an exec against a Machine that is not running would repeat a
1898
1985
  // 412 that waiting — not repeating — is what answers.
1899
- await this.waitForExecReady(app, machineId);
1986
+ await this.waitForExecReady(app, machineId, state);
1900
1987
  await this.client.sleep(execPreconditionBackoffMs(attempt));
1901
1988
  }
1902
1989
  }
@@ -1908,17 +1995,17 @@ class FlyioSandboxProvider {
1908
1995
  *
1909
1996
  * A wait that does not reach `started` is logged and the exec is retried
1910
1997
  * anyway: the retry is the recovery this path exists for, and turning a
1911
- * recoverable dropped connection into a start-timeout error would hide the
1912
- * condition the caller's error message is supposed to name.
1998
+ * recoverable refusal into a start-timeout error would hide the condition the
1999
+ * caller's error message is supposed to name.
1913
2000
  *
1914
2001
  * @param app - The Fly app name.
1915
2002
  * @param machineId - The Fly Machine id.
2003
+ * @param state - The state already read for this Machine, when the caller read
2004
+ * one (the exec retry does); read again when omitted.
1916
2005
  */
1917
- async waitForExecReady(app, machineId) {
1918
- const machine = await this.client
1919
- .request(`/apps/${app}/machines/${machineId}`, { nullOn: [404] })
1920
- .catch(() => null);
1921
- if (machine?.state === 'started')
2006
+ async waitForExecReady(app, machineId, state) {
2007
+ const machineState = state === undefined ? await this.readMachineState(app, machineId) : state;
2008
+ if (machineState === 'started')
1922
2009
  return;
1923
2010
  try {
1924
2011
  await this.waitForStarted(app, machineId);
@@ -1927,7 +2014,7 @@ class FlyioSandboxProvider {
1927
2014
  logger.warn('The Machine did not report started after a refused exec; retrying the exec', {
1928
2015
  app,
1929
2016
  machineId,
1930
- state: machine?.state ?? 'unknown',
2017
+ state: machineState ?? 'unknown',
1931
2018
  error,
1932
2019
  });
1933
2020
  }
@@ -1944,19 +2031,19 @@ class FlyioSandboxProvider {
1944
2031
  * @param error - The failure to annotate.
1945
2032
  * @param app - The Fly app name.
1946
2033
  * @param machineId - The Fly Machine id.
2034
+ * @param knownState - The state already read for this Machine, when the caller
2035
+ * read one (the exec retry does); read again when omitted.
1947
2036
  * @returns The original error, or a 412 carrying the Machine's state.
1948
2037
  */
1949
- async withMachineState(error, app, machineId) {
2038
+ async withMachineState(error, app, machineId, knownState) {
1950
2039
  if (!(error instanceof Error))
1951
2040
  return new Error(String(error));
1952
2041
  if (!(error instanceof FlyApiError) || error.status !== 412)
1953
2042
  return error;
1954
2043
  if (/machine state:/i.test(error.message))
1955
2044
  return error;
1956
- const machine = await this.client
1957
- .request(`/apps/${app}/machines/${machineId}`, { nullOn: [404] })
1958
- .catch(() => null);
1959
- const state = machine?.state ?? 'unreadable';
2045
+ const read = knownState === undefined ? await this.readMachineState(app, machineId) : knownState;
2046
+ const state = read ?? 'unreadable';
1960
2047
  return new FlyApiError(error.method, error.path, error.status, `${error.body} (machine ${machineId} state: ${state})`, { cause: error });
1961
2048
  }
1962
2049
  /**
@@ -2054,6 +2141,65 @@ class FlyioSandboxProvider {
2054
2141
  `${totalSeconds}s (last observed state: ${lastState ?? 'unknown'}).`,
2055
2142
  }), { cause: lastError });
2056
2143
  }
2144
+ /**
2145
+ * Applies an idle policy to a running Machine's public service, in place.
2146
+ *
2147
+ * Fly's update endpoint takes the ENTIRE Machine config — "we don't support
2148
+ * partial updates" — and "If the Machine is running and the request is
2149
+ * successful, it will reboot" (verified against
2150
+ * https://docs.fly.io/machines/api/machines-resource, 2026-10-17). So this
2151
+ * re-reads the Machine, changes only each service's `autostop`, and waits for
2152
+ * the Machine to reach `started` again before resolving: the caller's next act
2153
+ * is to run commands in it. A Machine that ALREADY has the policy is left
2154
+ * alone — the reboot is a real cost, not a formality — and one that is not
2155
+ * running is updated with `skip_launch` so changing a parked Machine's policy
2156
+ * does not wake it.
2157
+ *
2158
+ * A Machine with no services has no proxy in front of it and therefore no
2159
+ * idle policy; that is a supported shape (a private sandbox), not an error.
2160
+ *
2161
+ * @param app - The Fly app name.
2162
+ * @param machineId - The Fly Machine id.
2163
+ * @param action - The idle action to apply to every service.
2164
+ * @throws {Error} When the Machine or its config cannot be read, the update is
2165
+ * rejected, or a rebooted Machine does not come back to `started`.
2166
+ */
2167
+ async applyIdleAction(app, machineId, action) {
2168
+ const machine = await this.client.request(`/apps/${app}/machines/${machineId}`, {
2169
+ nullOn: [404],
2170
+ });
2171
+ if (!machine?.config) {
2172
+ throw new Error(t('codeSandbox.flyio.error.idlePolicyUnreadable', { machineId }, {
2173
+ defaultValue: `Cannot change the idle policy of Fly Machine ${machineId}: its config could not be ` +
2174
+ 'read, so the Machine is left exactly as it is.',
2175
+ }));
2176
+ }
2177
+ const services = machine.config.services;
2178
+ if (!services?.length)
2179
+ return;
2180
+ if (services.every((service) => (service.autostop ?? 'off') === action))
2181
+ return;
2182
+ const config = {
2183
+ ...machine.config,
2184
+ services: services.map((service) => ({ ...service, autostop: action })),
2185
+ };
2186
+ // A running Machine reboots to apply the config, so wait for it; a parked
2187
+ // one is updated without being started (there is nothing to wait for).
2188
+ const wasRunning = machine.state === 'started' || machine.state === 'starting';
2189
+ await this.client.request(`/apps/${app}/machines/${machineId}`, {
2190
+ method: 'POST',
2191
+ body: {
2192
+ config,
2193
+ // Immutable, but the update body is a whole Machine description; send
2194
+ // back what was read rather than letting Fly infer them.
2195
+ ...(machine.name ? { name: machine.name } : {}),
2196
+ ...(machine.region ? { region: machine.region } : {}),
2197
+ ...(wasRunning ? {} : { skip_launch: true }),
2198
+ },
2199
+ });
2200
+ if (wasRunning)
2201
+ await this.waitForStarted(app, machineId);
2202
+ }
2057
2203
  /**
2058
2204
  * Builds the `Sandbox` facade for one Machine.
2059
2205
  * @param app - The Fly app name.
@@ -2098,6 +2244,15 @@ class FlyioSandboxProvider {
2098
2244
  await provider.startMachine(app, machineId);
2099
2245
  this.status = 'running';
2100
2246
  },
2247
+ /**
2248
+ * Applies an idle policy to this Machine's public service (see
2249
+ * {@link FlyioSandboxProvider.applyIdleAction} for the endpoint and the
2250
+ * reboot it costs). Resolves with the Machine running again.
2251
+ */
2252
+ async setIdleAction(action) {
2253
+ await provider.applyIdleAction(app, machineId, action);
2254
+ this.status = 'running';
2255
+ },
2101
2256
  async exec(command, opts) {
2102
2257
  return await execCommand(exec, command, opts, WORKSPACE_PATH);
2103
2258
  },
package/dist/types.d.ts CHANGED
@@ -111,6 +111,12 @@ export interface FlyioConfig {
111
111
  * `suspend` is the scale-to-zero mapping (resume from a memory snapshot on the
112
112
  * next request) and `stop` is a full stop with a cold boot on wake; opt into
113
113
  * either deliberately.
114
+ *
115
+ * This is the provider's STEADY-STATE policy, reported as
116
+ * `SandboxProvider.defaultIdleAction`. A caller can override it for one sandbox
117
+ * with `SandboxConfig.idleAction` and restore this value afterwards with
118
+ * `Sandbox.setIdleAction` — which is what a production deploy does so its
119
+ * destination cannot suspend mid-copy (m103, 2026-10-17).
114
120
  */
115
121
  autostop?: 'off' | 'stop' | 'suspend';
116
122
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@molecule/api-code-sandbox-flyio",
3
- "version": "1.2.9",
3
+ "version": "1.3.0",
4
4
  "description": "Fly.io Machines (Firecracker microVM) code sandbox provider",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -31,7 +31,7 @@
31
31
  "license": "Apache-2.0",
32
32
  "devDependencies": {
33
33
  "@molecule/api-bond": "1.0.2",
34
- "@molecule/api-code-sandbox": "1.3.0",
34
+ "@molecule/api-code-sandbox": "1.4.0",
35
35
  "@types/node": "26.1.2",
36
36
  "typescript": "6.0.3",
37
37
  "vitest": "4.1.11"