@shardflux/sdk 0.12.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.
@@ -2,12 +2,12 @@
2
2
  * A workspace handle: the latest view from the application API plus managed
3
3
  * tool tokens and cell clients (one per agent label / tool set).
4
4
  */
5
- import type { ClientContext, IdlePolicy, DiskLayout, ForkTarget, Operation, SuspendRequest, SuspendWhenIdleOptions, SuspendWhenIdleResult, WaitOptions, WorkspaceLifetime, WorkspaceOrigin, WorkspacePurpose, WorkspaceView } from './client.js';
5
+ import type { AllocationMode, ClientContext, IdlePolicy, DiskLayout, ForkTarget, Operation, SuspendRequest, SuspendWhenIdleOptions, SuspendWhenIdleResult, WaitOptions, WorkspaceLifetime, WorkspaceMemory, WorkspaceOrigin, WorkspacePurpose, WorkspaceView } from './client.js';
6
6
  import { CAPTURE_BARRIER, CellClient } from './cell.js';
7
7
  import { ToolCallCapture } from './capture.js';
8
8
  import type { ToolCallCaptureOptions } from './capture.js';
9
9
  import type { WorkspaceMode } from './errors.js';
10
- import type { FinishedOperation, LifecycleOptions, ResumeOptions, SuspendOptions, WaitedLifecycleOptions, WaitedResumeOptions, WaitedSuspendOptions } from './lifecycle.js';
10
+ import type { FinishedOperation, ForkOptions, LifecycleOptions, ResumeOptions, SuspendOptions, WaitedForkOptions, WaitedLifecycleOptions, WaitedResumeOptions, WaitedSuspendOptions } from './lifecycle.js';
11
11
  import { Trace } from './progress.js';
12
12
  import type { LifecycleTiming, ProgressListener } from './progress.js';
13
13
  import { WorkspaceSecrets } from './secrets.js';
@@ -67,7 +67,9 @@ export declare class Workspace {
67
67
  * woke the workspace), or a lifecycle call with `wait`. Null for handles from get()/list() until such a call.
68
68
  * `formatTiming(workspace.lastTiming)` prints it. After a resume or wake, `server.memoryRestored === false` (0.11.0+)
69
69
  * means the workspace booted from its saved disk instead of restoring its memory (`server.resumePath` `cold_boot`,
70
- * reason in `server.coldBootReason`): files are as of the suspend, running processes were restarted.
70
+ * reason in `server.coldBootReason`): files are as of the suspend, running processes were restarted. Reason
71
+ * `host_lost` (0.13.1+): the machine the workspace ran on failed and it booted from its disk, files kept;
72
+ * `server.hostLost` says what the resume restored (`hostLostOf(op)` on the operation).
71
73
  */
72
74
  get lastTiming(): LifecycleTiming | null;
73
75
  get id(): string;
@@ -82,6 +84,13 @@ export declare class Workspace {
82
84
  get grants(): WorkspaceView['grants'];
83
85
  get ceilings(): WorkspaceView['ceilings'];
84
86
  get template(): WorkspaceView['template'];
87
+ /**
88
+ * The template version whose immutable paths the workspace has mounted (0.13.0; `template.immutable_version`): the
89
+ * template's newest published version as of the workspace's last cold boot or resume, which can be newer than
90
+ * `template.version`. Null when the workspace mounts none (its version declares no immutable paths, it has not started
91
+ * since, or an older API).
92
+ */
93
+ get immutableVersion(): number | null;
85
94
  get pendingReason(): string | null;
86
95
  get activeOperation(): WorkspaceView['active_operation'];
87
96
  /** persistent or session; immutable. A view without the field (older API) is persistent. */
@@ -108,6 +117,14 @@ export declare class Workspace {
108
117
  * a resume after the request cancelled it. `refresh()` reads it again.
109
118
  */
110
119
  get suspendRequest(): SuspendRequest | null;
120
+ /**
121
+ * Memory of the workspace as of the last view (0.13.0): `{allocation_mode, promised_mib, held_mib,
122
+ * plugged_mib}`. An elastic workspace holds `held_mib` while idle and is grown towards `promised_mib` when a command
123
+ * needs it; `plugged_mib` is what is plugged above the floor now (null without a live allocation). Null on an older API.
124
+ */
125
+ get memory(): WorkspaceMemory | null;
126
+ /** `fixed` or `elastic` (0.13.0): the running VM's layout, else the next start's. Fixed on an older API. */
127
+ get allocationMode(): AllocationMode;
111
128
  /** The raw view (GET /v1/workspaces/{id}). */
112
129
  get data(): WorkspaceView;
113
130
  /**
@@ -159,6 +176,8 @@ export declare class Workspace {
159
176
  * resolve once it has FINISHED, with `workspace.state` then `suspended`. That is as soon as the workspace is sealed on
160
177
  * its host, typically in a few hundred ms. `result.durable` (also `lastTiming.server.durable`, 0.12.0+) turns true
161
178
  * when the copy lands in durable storage, typically within a second; `{ durable: true }` resolves only then.
179
+ * A suspend that finds the machine the workspace ran on failed succeeds at once (0.13.1+): `result.durable` is true
180
+ * and `result.host_lost` (`hostLostOf(op)`) has `detectedAt`; the next resume restores the workspace.
162
181
  *
163
182
  * await workspace.suspend({ wait: true });
164
183
  * await workspace.suspend({ durable: true }); // 0.12.0+: also wait for the durable copy
@@ -190,11 +209,16 @@ export declare class Workspace {
190
209
  * (also `lastTiming.server.memoryRestored`, 0.11.0+) is false when the resume booted the saved disk instead
191
210
  * (`resume_path` `cold_boot`): files kept, processes restarted. `result.lost_suspend` (also
192
211
  * `lastTiming.server.lostSuspend`, `lostSuspendOf(op)`, 0.12.0+) names a suspend this resume could not restore and the
193
- * checkpoint it restored instead (see the lifecycle reference).
212
+ * checkpoint it restored instead (see the lifecycle reference). `result.host_lost` (also `lastTiming.server.hostLost`,
213
+ * `hostLostOf(op)`, 0.13.1+): the machine the workspace ran on failed and this resume restored it, from its disk
214
+ * (`cold_boot_reason` `host_lost`) or from its newest checkpoint (`state_as_of`).
194
215
  */
195
216
  resume(opts: WaitedResumeOptions): Promise<FinishedOperation>;
196
217
  resume(opts?: ResumeOptions): Promise<Operation>;
197
- /** Takes a snapshot. Resolves when it is REQUESTED; with `{ wait: true }`, once it is taken. */
218
+ /**
219
+ * Takes a snapshot. Resolves when it is REQUESTED; with `{ wait: true }`, once it is taken. After the machine the
220
+ * workspace ran on failed, resume it first: until then the snapshot fails `resume_required` (0.13.1+).
221
+ */
198
222
  snapshot(opts: WaitedLifecycleOptions & {
199
223
  label?: string;
200
224
  }): Promise<FinishedOperation>;
@@ -203,13 +227,14 @@ export declare class Workspace {
203
227
  }): Promise<Operation>;
204
228
  /**
205
229
  * Forks into a new key. Resolves when the fork is REQUESTED (the copy's handle is returned at once); with
206
- * `{ wait: true }`, once the copy exists, with its handle refreshed.
230
+ * `{ wait: true }`, once the copy exists, with its handle refreshed. After the machine the workspace ran on failed,
231
+ * resume it first: until then the fork fails `resume_required` (0.13.1+).
207
232
  */
208
- fork(target: ForkTarget, opts: WaitedLifecycleOptions): Promise<{
233
+ fork(target: ForkTarget, opts: WaitedForkOptions): Promise<{
209
234
  operation: FinishedOperation;
210
235
  workspace: Workspace;
211
236
  }>;
212
- fork(target: ForkTarget, opts?: LifecycleOptions): Promise<{
237
+ fork(target: ForkTarget, opts?: ForkOptions): Promise<{
213
238
  operation: Operation;
214
239
  workspace: Workspace;
215
240
  }>;
@@ -286,8 +311,9 @@ export declare class Workspace {
286
311
  * that does not hold the request answers at once; the wake then waits for the operation and reads the view.
287
312
  *
288
313
  * A wake whose resume could not restore the workspace's memory (0.11.0+; the platform's VM runtime changed after the
289
- * suspend) still resolves `true`: the workspace runs from its saved disk, with every process restarted. `lastTiming`
290
- * and the `done` progress event say so (`server.memoryRestored === false`, `server.resumePath` `cold_boot`).
314
+ * suspend, or, 0.13.1+, the machine the workspace ran on failed) still resolves `true`: the workspace runs from its
315
+ * saved disk, with every process restarted. `lastTiming` and the `done` progress event say so
316
+ * (`server.memoryRestored === false`, `server.resumePath` `cold_boot`, `server.coldBootReason`).
291
317
  */
292
318
  wake(opts?: WakeOptions): Promise<boolean>;
293
319
  /**
package/dist/workspace.js CHANGED
@@ -44,7 +44,9 @@ export class Workspace {
44
44
  * woke the workspace), or a lifecycle call with `wait`. Null for handles from get()/list() until such a call.
45
45
  * `formatTiming(workspace.lastTiming)` prints it. After a resume or wake, `server.memoryRestored === false` (0.11.0+)
46
46
  * means the workspace booted from its saved disk instead of restoring its memory (`server.resumePath` `cold_boot`,
47
- * reason in `server.coldBootReason`): files are as of the suspend, running processes were restarted.
47
+ * reason in `server.coldBootReason`): files are as of the suspend, running processes were restarted. Reason
48
+ * `host_lost` (0.13.1+): the machine the workspace ran on failed and it booted from its disk, files kept;
49
+ * `server.hostLost` says what the resume restored (`hostLostOf(op)` on the operation).
48
50
  */
49
51
  get lastTiming() {
50
52
  return this.#lastTiming ?? this.#openTrace?.finished ?? null;
@@ -96,6 +98,15 @@ export class Workspace {
96
98
  get template() {
97
99
  return this.#view.template;
98
100
  }
101
+ /**
102
+ * The template version whose immutable paths the workspace has mounted (0.13.0; `template.immutable_version`): the
103
+ * template's newest published version as of the workspace's last cold boot or resume, which can be newer than
104
+ * `template.version`. Null when the workspace mounts none (its version declares no immutable paths, it has not started
105
+ * since, or an older API).
106
+ */
107
+ get immutableVersion() {
108
+ return this.#view.template.immutable_version ?? null;
109
+ }
99
110
  get pendingReason() {
100
111
  return this.#view.pending_reason;
101
112
  }
@@ -142,6 +153,18 @@ export class Workspace {
142
153
  get suspendRequest() {
143
154
  return this.#view.idle?.suspend_request ?? null;
144
155
  }
156
+ /**
157
+ * Memory of the workspace as of the last view (0.13.0): `{allocation_mode, promised_mib, held_mib,
158
+ * plugged_mib}`. An elastic workspace holds `held_mib` while idle and is grown towards `promised_mib` when a command
159
+ * needs it; `plugged_mib` is what is plugged above the floor now (null without a live allocation). Null on an older API.
160
+ */
161
+ get memory() {
162
+ return this.#view.memory ?? null;
163
+ }
164
+ /** `fixed` or `elastic` (0.13.0): the running VM's layout, else the next start's. Fixed on an older API. */
165
+ get allocationMode() {
166
+ return this.#view.memory?.allocation_mode ?? this.#view.caps?.allocation_mode ?? 'fixed';
167
+ }
145
168
  /** The raw view (GET /v1/workspaces/{id}). */
146
169
  get data() {
147
170
  return this.#view;
@@ -417,8 +440,9 @@ export class Workspace {
417
440
  * that does not hold the request answers at once; the wake then waits for the operation and reads the view.
418
441
  *
419
442
  * A wake whose resume could not restore the workspace's memory (0.11.0+; the platform's VM runtime changed after the
420
- * suspend) still resolves `true`: the workspace runs from its saved disk, with every process restarted. `lastTiming`
421
- * and the `done` progress event say so (`server.memoryRestored === false`, `server.resumePath` `cold_boot`).
443
+ * suspend, or, 0.13.1+, the machine the workspace ran on failed) still resolves `true`: the workspace runs from its
444
+ * saved disk, with every process restarted. `lastTiming` and the `done` progress event say so
445
+ * (`server.memoryRestored === false`, `server.resumePath` `cold_boot`, `server.coldBootReason`).
422
446
  */
423
447
  async wake(opts = {}) {
424
448
  // A file-first workspace runs from creation and is never suspended: nothing to wake.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@shardflux/sdk",
3
- "version": "0.12.0",
3
+ "version": "0.13.1",
4
4
  "type": "module",
5
5
  "description": "Shardflux TypeScript SDK: open persistent agent workspaces by key and give your agent workspace tools (exec, files, processes, PTY, git, browser).",
6
6
  "license": "Apache-2.0",