@shardflux/sdk 0.10.2 → 0.11.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/CHANGELOG.md +58 -26
- package/README.md +73 -51
- package/dist/account.d.ts +2 -2
- package/dist/account.js +1 -1
- package/dist/cell.d.ts +21 -21
- package/dist/cell.js +12 -12
- package/dist/client.d.ts +31 -31
- package/dist/client.js +17 -17
- package/dist/egress.d.ts +3 -3
- package/dist/errors.d.ts +18 -18
- package/dist/errors.js +11 -11
- package/dist/executions.d.ts +2 -2
- package/dist/feedback.d.ts +3 -3
- package/dist/generated/app-api.d.ts +1352 -21
- package/dist/http.d.ts +7 -11
- package/dist/http.js +8 -11
- package/dist/index.d.ts +1 -1
- package/dist/lifecycle.d.ts +2 -2
- package/dist/lifecycle.js +1 -1
- package/dist/progress.d.ts +38 -18
- package/dist/progress.js +17 -11
- package/dist/tar.d.ts +1 -1
- package/dist/tar.js +1 -1
- package/dist/template-file.d.ts +1 -1
- package/dist/template-file.js +1 -1
- package/dist/templates.d.ts +21 -21
- package/dist/templates.js +8 -8
- package/dist/tools.d.ts +3 -3
- package/dist/tools.js +4 -4
- package/dist/version-check.d.ts +1 -1
- package/dist/volumes.d.ts +1 -1
- package/dist/workspace.d.ts +30 -21
- package/dist/workspace.js +27 -20
- package/package.json +1 -1
package/dist/cell.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* (token expired or revoked early) invalidates the token and retries once with
|
|
8
8
|
* a fresh one; the retried request is safe because the gateway rejected the
|
|
9
9
|
* first before any effect (and exec/PTY starts are idempotent by session_id).
|
|
10
|
-
* The same holds for lifecycle refusals
|
|
10
|
+
* The same holds for lifecycle refusals: `workspace_busy` is
|
|
11
11
|
* waited out and `workspace_not_running` wakes the workspace, then the call is
|
|
12
12
|
* retried, all within one bounded transition budget per call.
|
|
13
13
|
*
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* `exec.run()` survives gateway restarts/disconnects by reconnecting with the
|
|
16
16
|
* offsets it already processed; it never starts the command a second time.
|
|
17
17
|
*
|
|
18
|
-
* File-first workspaces
|
|
18
|
+
* File-first workspaces serve the files routes from a
|
|
19
19
|
* versioned tree and run commands as executions (`executions.run()`); the
|
|
20
20
|
* client tracks the tree revision every response reports (`X-Tree-Revision`)
|
|
21
21
|
* and, when it knows the workspace's mode, refuses calls the mode does not
|
|
@@ -39,20 +39,20 @@ export type ProcessList = S['ProcessList'];
|
|
|
39
39
|
export type FileInfo = S['FileInfo'];
|
|
40
40
|
export type FileList = S['FileList'];
|
|
41
41
|
export type FileWriteResult = S['FileWriteResult'];
|
|
42
|
-
/** Search request/result of `POST /files/search
|
|
42
|
+
/** Search request/result of `POST /files/search`. */
|
|
43
43
|
export type FileSearchRequest = S['FileSearchRequest'];
|
|
44
44
|
export type FileSearchMatch = S['FileSearchMatch'];
|
|
45
45
|
export type FileSearchResult = S['FileSearchResult'];
|
|
46
|
-
/** One text edit of `POST /files/patch
|
|
46
|
+
/** One text edit of `POST /files/patch`, as sent on the wire. */
|
|
47
47
|
export type FileEdit = S['FileEdit'];
|
|
48
48
|
export type FilePatchRequest = S['FilePatchRequest'];
|
|
49
49
|
export type FilePatchResult = S['FilePatchResult'];
|
|
50
50
|
/** A content SHA-256 (lowercase hex), or `absent` for a path that must not exist. */
|
|
51
51
|
export type FileRevision = S['FileRevision'];
|
|
52
52
|
export type WakeHintResult = S['WakeHintResult'];
|
|
53
|
-
/** Where a running workspace's VM is
|
|
53
|
+
/** Where a running workspace's VM is: resident, frozen, hibernated or restoring. */
|
|
54
54
|
export type Residency = WakeHintResult['residency'];
|
|
55
|
-
/** `X-Served-From`: `disk` when a read was served from a suspended or hibernated workspace's disk
|
|
55
|
+
/** `X-Served-From`: `disk` when a read was served from a suspended or hibernated workspace's disk. */
|
|
56
56
|
export type ServedFrom = 'guest' | 'disk';
|
|
57
57
|
/** `files.readWithInfo()`: the bytes plus what the gateway reported about the file. */
|
|
58
58
|
export interface FileReadResult {
|
|
@@ -122,7 +122,7 @@ export type BrowserScreenshotRequest = S['BrowserScreenshotRequest'];
|
|
|
122
122
|
export type BrowserContentRequest = S['BrowserContentRequest'];
|
|
123
123
|
export type BrowserContent = S['BrowserContent'];
|
|
124
124
|
export type Signal = S['SignalValue'];
|
|
125
|
-
/** One entry of a workspace's changes against its template
|
|
125
|
+
/** One entry of a workspace's changes against its template. */
|
|
126
126
|
export type WorkspaceChange = S['WorkspaceChange'];
|
|
127
127
|
export type WorkspaceChangeKind = WorkspaceChange['change'];
|
|
128
128
|
export type WorkspaceChangesSummary = S['WorkspaceChangesSummary'];
|
|
@@ -155,8 +155,8 @@ export interface CellClientOptions {
|
|
|
155
155
|
* resolves `false` when there was nothing to wake (the API already reports it running), and the refusal then
|
|
156
156
|
* surfaces. It throws when the wake fails (OperationFailedError) or outlasts `timeoutMs` (OperationTimeoutError).
|
|
157
157
|
* Workspace.cell() supplies `workspace.wake()`. A call refused with `workspace_not_running` wakes the workspace and is
|
|
158
|
-
* retried; a refused call was never executed
|
|
159
|
-
* the refusal instead. A wake that put a new token into this client's manager (the held resume
|
|
158
|
+
* retried; a refused call was never executed, so the retry cannot duplicate it. `null` surfaces
|
|
159
|
+
* the refusal instead. A wake that put a new token into this client's manager (the held resume;
|
|
160
160
|
* `workspace.wake({ agentLabel, tools })`) is retried with it; otherwise the token is replaced before the retry.
|
|
161
161
|
*/
|
|
162
162
|
wake?: ((timeoutMs: number, signal?: AbortSignal) => Promise<boolean | void>) | null;
|
|
@@ -174,7 +174,7 @@ export interface CellClientOptions {
|
|
|
174
174
|
/** Internal: see CAPTURE_BARRIER. */
|
|
175
175
|
[CAPTURE_BARRIER]?: (() => Promise<unknown> | undefined) | undefined;
|
|
176
176
|
/**
|
|
177
|
-
* The workspace's mode
|
|
177
|
+
* The workspace's mode, or a function returning it (undefined: unknown). When known, calls the mode
|
|
178
178
|
* does not have fail at once with NotSupportedForModeError (`local` true) instead of a request: exec sessions, PTY,
|
|
179
179
|
* processes, version control, browser and changes on a file-first workspace; executions and `ifTreeRevision` on a
|
|
180
180
|
* processful one. Workspace.cell() supplies the workspace's.
|
|
@@ -183,7 +183,7 @@ export interface CellClientOptions {
|
|
|
183
183
|
/** Called with every tree revision a response reports (`X-Tree-Revision`, execution results, mismatch refusals). */
|
|
184
184
|
onTreeRevision?: (revision: number) => void;
|
|
185
185
|
}
|
|
186
|
-
/** `ifTreeRevision` (file-first workspaces
|
|
186
|
+
/** `ifTreeRevision` (file-first workspaces): the tree revision a mutating files call applies to. */
|
|
187
187
|
export interface TreeRevisionOptions {
|
|
188
188
|
/**
|
|
189
189
|
* Sent as `If-Match`: the call applies only while the tree is at this revision (`workspace.treeRevision`, or a
|
|
@@ -197,7 +197,7 @@ export interface TreeRevisionOptions {
|
|
|
197
197
|
interface TransitionOptions {
|
|
198
198
|
/** Wake a suspended workspace for this call (default true; exec output follow reconnects pass false). */
|
|
199
199
|
wake?: boolean;
|
|
200
|
-
/** Wait out `workspace_busy` (default true; the wake hint passes false: it
|
|
200
|
+
/** Wait out `workspace_busy` (default true; the wake hint passes false: it never waits). */
|
|
201
201
|
busy?: boolean;
|
|
202
202
|
}
|
|
203
203
|
export declare const DEFAULT_TRANSITION_TIMEOUT_MS = 120000;
|
|
@@ -245,7 +245,7 @@ export interface RunOptions {
|
|
|
245
245
|
/** Output reconnect attempts after a dropped stream (default 10). */
|
|
246
246
|
maxReconnects?: number;
|
|
247
247
|
/**
|
|
248
|
-
* Names of customer secrets
|
|
248
|
+
* Names of customer secrets the cell injects as environment variables `NAME=value` of this
|
|
249
249
|
* process only (sent as `secret_refs`). Values are resolved at session start with this workspace's tool token and
|
|
250
250
|
* never returned. A name the caller may not use refuses the whole start with 403 `forbidden`
|
|
251
251
|
* (details.reason `secret_not_available`, details.names) and nothing runs; a name also present in `env` is 422.
|
|
@@ -274,7 +274,7 @@ export declare class CellClient {
|
|
|
274
274
|
*/
|
|
275
275
|
close(): void;
|
|
276
276
|
/**
|
|
277
|
-
* One authorized request. Refreshes the token once on stale_epoch / 401. Lifecycle transitions
|
|
277
|
+
* One authorized request. Refreshes the token once on stale_epoch / 401. Lifecycle transitions,
|
|
278
278
|
* bounded in total by `transitionTimeoutMs`: a call refused with `workspace_busy` is retried after `Retry-After`; one
|
|
279
279
|
* refused with `workspace_not_running` (or whose token cannot be minted because the workspace is not running) wakes
|
|
280
280
|
* the workspace through `wake`, given the time left, and is retried with a fresh token, at most 3 wakes per call.
|
|
@@ -314,9 +314,9 @@ export declare class CellClient {
|
|
|
314
314
|
* the next revision (`treeRevision`, `changed`); processes, memory and files elsewhere do not survive it.
|
|
315
315
|
*
|
|
316
316
|
* The execution id (`executionId`, default a fresh `ex-<uuid>`) is the idempotency key: network failures and
|
|
317
|
-
* retryable 429/5xx answers (503 `no_execution_host`:
|
|
318
|
-
* id and request, at most `maxRetries` times, and an attempt that waits longer than
|
|
319
|
-
* with the same id. The cell answers 201 for the call that ran the command and 200 (`replayed`) with the recorded
|
|
317
|
+
* retryable 429/5xx answers (503 `no_execution_host`: the execution cannot be placed right now, with Retry-After) are
|
|
318
|
+
* retried with the same id and request, at most `maxRetries` times, and an attempt that waits longer than
|
|
319
|
+
* `attemptTimeoutMs` re-attaches with the same id. The cell answers 201 for the call that ran the command and 200 (`replayed`) with the recorded
|
|
320
320
|
* result otherwise, so the command runs at most once. `workspace_busy` (`execution_in_progress`: another execution
|
|
321
321
|
* holds the workspace) is waited out within `transitionTimeoutMs`; `execution_id_reused` (the id with another
|
|
322
322
|
* request) and validation errors are thrown at once. The SDK never retries with a new id: a result whose `state` is
|
|
@@ -376,7 +376,7 @@ export declare class CellClient {
|
|
|
376
376
|
/**
|
|
377
377
|
* Like `read()`, plus the file's size, `revision` (SHA-256 of the whole file, `X-File-Revision`, for regular files of
|
|
378
378
|
* 16 MiB or less; pass it as `expectedRevision` to `patch()`) and `servedFrom` (`disk` when a sleeping workspace was
|
|
379
|
-
* read from its disk without waking it
|
|
379
|
+
* read from its disk without waking it). 0.9.0+.
|
|
380
380
|
*/
|
|
381
381
|
readWithInfo: (path: string, opts?: {
|
|
382
382
|
offset?: number;
|
|
@@ -414,7 +414,7 @@ export declare class CellClient {
|
|
|
414
414
|
overwrite?: boolean;
|
|
415
415
|
} & TreeRevisionOptions) => Promise<FileInfo>;
|
|
416
416
|
/**
|
|
417
|
-
* Searches file contents under `path`, a directory or one file (
|
|
417
|
+
* Searches file contents under `path`, a directory or one file (0.9.0+): matching lines in path
|
|
418
418
|
* order, bounded by `maxMatches`, a 10 s budget and 4 MiB of results (`truncated`, `stop_reason` `max_matches`,
|
|
419
419
|
* `budget` or `max_bytes`). Binary files, symbolic links, special files and files above `maxFileBytes` are
|
|
420
420
|
* skipped. Read-only, so transient failures (e.g. 503 `host_capacity`) are retried; a suspended workspace whose
|
|
@@ -423,7 +423,7 @@ export declare class CellClient {
|
|
|
423
423
|
search: (path: string, pattern: string, opts?: FileSearchOptions) => Promise<FileSearchResponse>;
|
|
424
424
|
/**
|
|
425
425
|
* Applies text `edits` (each `oldText` must occur exactly once unless `replaceAll`; in order) or replaces the whole
|
|
426
|
-
* file with `content`, atomically and durably (
|
|
426
|
+
* file with `content`, atomically and durably (0.9.0+). With `expectedRevision` the file must
|
|
427
427
|
* still have that revision (`absent`: must not exist), else 409 `conflict` `revision_mismatch` with
|
|
428
428
|
* `details.current_revision`. Edits that do not apply: 422 `validation_failed` `edit_not_found` / `edit_ambiguous`
|
|
429
429
|
* (`details.index`), `edit_not_text`. Limits: a request of up to 7 MiB (else 413 `payload_too_large`; larger
|
|
@@ -437,7 +437,7 @@ export declare class CellClient {
|
|
|
437
437
|
} & TreeRevisionOptions) => Promise<FilePatchResult>;
|
|
438
438
|
};
|
|
439
439
|
/**
|
|
440
|
-
* `POST /wake-hint` (
|
|
440
|
+
* `POST /wake-hint` (0.9.0+): announces an imminent tool call so a hibernated workspace is restored
|
|
441
441
|
* ahead of it. It never wakes a suspended workspace, never waits out `workspace_busy` and is not retried: a suspended
|
|
442
442
|
* workspace answers 409 `workspace_not_running` (`Workspace.hint()` then wakes it in the background).
|
|
443
443
|
*/
|
package/dist/cell.js
CHANGED
|
@@ -200,7 +200,7 @@ export class CellClient {
|
|
|
200
200
|
this.#closer.abort(new DOMException('The workspace handle was closed.', 'AbortError'));
|
|
201
201
|
}
|
|
202
202
|
/**
|
|
203
|
-
* One authorized request. Refreshes the token once on stale_epoch / 401. Lifecycle transitions
|
|
203
|
+
* One authorized request. Refreshes the token once on stale_epoch / 401. Lifecycle transitions,
|
|
204
204
|
* bounded in total by `transitionTimeoutMs`: a call refused with `workspace_busy` is retried after `Retry-After`; one
|
|
205
205
|
* refused with `workspace_not_running` (or whose token cannot be minted because the workspace is not running) wakes
|
|
206
206
|
* the workspace through `wake`, given the time left, and is retried with a fresh token, at most 3 wakes per call.
|
|
@@ -262,7 +262,7 @@ export class CellClient {
|
|
|
262
262
|
const before = this.tokens.current;
|
|
263
263
|
if ((await this.#wake(left, signal)) === false)
|
|
264
264
|
throw err; // running per the API: nothing to wait for
|
|
265
|
-
// A held resume
|
|
265
|
+
// A held resume handed this client a token of the woken workspace: use it. Otherwise the
|
|
266
266
|
// old token is of the previous epoch: fetch a new one.
|
|
267
267
|
if (this.tokens.current === before)
|
|
268
268
|
this.tokens.invalidate();
|
|
@@ -475,7 +475,7 @@ export class CellClient {
|
|
|
475
475
|
reconnects,
|
|
476
476
|
};
|
|
477
477
|
}
|
|
478
|
-
// ---- executions (file-first workspaces
|
|
478
|
+
// ---- executions (file-first workspaces) -----------------------------
|
|
479
479
|
executions = {
|
|
480
480
|
/**
|
|
481
481
|
* Runs argv (no shell; `['bash', '-lc', line]` for shell syntax) as an execution of this file-first workspace: a
|
|
@@ -483,9 +483,9 @@ export class CellClient {
|
|
|
483
483
|
* the next revision (`treeRevision`, `changed`); processes, memory and files elsewhere do not survive it.
|
|
484
484
|
*
|
|
485
485
|
* The execution id (`executionId`, default a fresh `ex-<uuid>`) is the idempotency key: network failures and
|
|
486
|
-
* retryable 429/5xx answers (503 `no_execution_host`:
|
|
487
|
-
* id and request, at most `maxRetries` times, and an attempt that waits longer than
|
|
488
|
-
* with the same id. The cell answers 201 for the call that ran the command and 200 (`replayed`) with the recorded
|
|
486
|
+
* retryable 429/5xx answers (503 `no_execution_host`: the execution cannot be placed right now, with Retry-After) are
|
|
487
|
+
* retried with the same id and request, at most `maxRetries` times, and an attempt that waits longer than
|
|
488
|
+
* `attemptTimeoutMs` re-attaches with the same id. The cell answers 201 for the call that ran the command and 200 (`replayed`) with the recorded
|
|
489
489
|
* result otherwise, so the command runs at most once. `workspace_busy` (`execution_in_progress`: another execution
|
|
490
490
|
* holds the workspace) is waited out within `transitionTimeoutMs`; `execution_id_reused` (the id with another
|
|
491
491
|
* request) and validation errors are thrown at once. The SDK never retries with a new id: a result whose `state` is
|
|
@@ -744,7 +744,7 @@ export class CellClient {
|
|
|
744
744
|
/**
|
|
745
745
|
* Like `read()`, plus the file's size, `revision` (SHA-256 of the whole file, `X-File-Revision`, for regular files of
|
|
746
746
|
* 16 MiB or less; pass it as `expectedRevision` to `patch()`) and `servedFrom` (`disk` when a sleeping workspace was
|
|
747
|
-
* read from its disk without waking it
|
|
747
|
+
* read from its disk without waking it). 0.9.0+.
|
|
748
748
|
*/
|
|
749
749
|
readWithInfo: async (path, opts = {}) => {
|
|
750
750
|
const url = this.#p('/v1/workspaces/{workspace_id}/files');
|
|
@@ -805,7 +805,7 @@ export class CellClient {
|
|
|
805
805
|
headers: this.#ifMatch('files.move', opts),
|
|
806
806
|
}),
|
|
807
807
|
/**
|
|
808
|
-
* Searches file contents under `path`, a directory or one file (
|
|
808
|
+
* Searches file contents under `path`, a directory or one file (0.9.0+): matching lines in path
|
|
809
809
|
* order, bounded by `maxMatches`, a 10 s budget and 4 MiB of results (`truncated`, `stop_reason` `max_matches`,
|
|
810
810
|
* `budget` or `max_bytes`). Binary files, symbolic links, special files and files above `maxFileBytes` are
|
|
811
811
|
* skipped. Read-only, so transient failures (e.g. 503 `host_capacity`) are retried; a suspended workspace whose
|
|
@@ -833,7 +833,7 @@ export class CellClient {
|
|
|
833
833
|
},
|
|
834
834
|
/**
|
|
835
835
|
* Applies text `edits` (each `oldText` must occur exactly once unless `replaceAll`; in order) or replaces the whole
|
|
836
|
-
* file with `content`, atomically and durably (
|
|
836
|
+
* file with `content`, atomically and durably (0.9.0+). With `expectedRevision` the file must
|
|
837
837
|
* still have that revision (`absent`: must not exist), else 409 `conflict` `revision_mismatch` with
|
|
838
838
|
* `details.current_revision`. Edits that do not apply: 422 `validation_failed` `edit_not_found` / `edit_ambiguous`
|
|
839
839
|
* (`details.index`), `edit_not_text`. Limits: a request of up to 7 MiB (else 413 `payload_too_large`; larger
|
|
@@ -865,17 +865,17 @@ export class CellClient {
|
|
|
865
865
|
},
|
|
866
866
|
};
|
|
867
867
|
/**
|
|
868
|
-
* `POST /wake-hint` (
|
|
868
|
+
* `POST /wake-hint` (0.9.0+): announces an imminent tool call so a hibernated workspace is restored
|
|
869
869
|
* ahead of it. It never wakes a suspended workspace, never waits out `workspace_busy` and is not retried: a suspended
|
|
870
870
|
* workspace answers 409 `workspace_not_running` (`Workspace.hint()` then wakes it in the background).
|
|
871
871
|
*/
|
|
872
872
|
wakeHint(signal) {
|
|
873
|
-
// Nothing of a file-first workspace sleeps: the cell would answer `resident
|
|
873
|
+
// Nothing of a file-first workspace sleeps: the cell would answer `resident`.
|
|
874
874
|
if (this.mode === 'file_first')
|
|
875
875
|
return Promise.resolve({ residency: 'resident' });
|
|
876
876
|
return this.#json('POST', this.#p('/v1/workspaces/{workspace_id}/wake-hint'), { wake: false, busy: false, timeoutMs: 10_000, ...(signal ? { signal } : {}) });
|
|
877
877
|
}
|
|
878
|
-
// ---- changes against the template (layered workspaces
|
|
878
|
+
// ---- changes against the template (layered workspaces) ------------------
|
|
879
879
|
/**
|
|
880
880
|
* One page of the workspace's changes against its template (needs the `files` tool). File-first workspaces: each
|
|
881
881
|
* execution's result lists what it changed (`changed`); this route is refused (NotSupportedForModeError).
|
package/dist/client.d.ts
CHANGED
|
@@ -28,9 +28,9 @@ import { CaptureRegistry } from './capture.js';
|
|
|
28
28
|
import type { FeedbackReceipt, SendFeedbackParams } from './feedback.js';
|
|
29
29
|
export type WorkspaceView = components['schemas']['Workspace'];
|
|
30
30
|
export type Operation = components['schemas']['Operation'];
|
|
31
|
-
/** persistent (kept until deleted) or session (discarded when the session ends: close(), idle timeout
|
|
31
|
+
/** persistent (kept until deleted) or session (discarded when the session ends: close(), idle timeout). */
|
|
32
32
|
export type WorkspaceLifetime = components['schemas']['WorkspaceLifetime'];
|
|
33
|
-
/** legacy (one disk) or layered (the template chain read-only plus a workspace layer
|
|
33
|
+
/** legacy (one disk) or layered (the template chain read-only plus a workspace layer). */
|
|
34
34
|
export type DiskLayout = components['schemas']['DiskLayout'];
|
|
35
35
|
/** standard, template_draft (a template's dev-mode draft) or template_test (a test instance of a draft state). */
|
|
36
36
|
export type WorkspacePurpose = components['schemas']['WorkspacePurpose'];
|
|
@@ -56,7 +56,7 @@ type Ok<Op> = Op extends {
|
|
|
56
56
|
[K in keyof R]: K extends 200 | 201 | 202 ? JsonOf<R[K]> : never;
|
|
57
57
|
}[keyof R] : never;
|
|
58
58
|
export type OpenResponse = Ok<operations['postV1WorkspacesOpen']>;
|
|
59
|
-
/** POST /v1/workspaces/{id}/resume: the held 200
|
|
59
|
+
/** POST /v1/workspaces/{id}/resume: the held 200 or the lifecycle 202. */
|
|
60
60
|
export type ResumeResponse = Ok<operations['postV1WorkspacesWorkspaceIdResume']>;
|
|
61
61
|
/** What a resume request answered (0.9.0; `WorkspacesApi.requestResume`). */
|
|
62
62
|
export interface ResumeAnswer {
|
|
@@ -95,7 +95,7 @@ export type PortalSession = Ok<operations['postApiV1OrganizationsOrganizationIdB
|
|
|
95
95
|
export type InvoicePage = Ok<operations['getApiV1OrganizationsOrganizationIdBillingInvoices']>;
|
|
96
96
|
export type Invoice = InvoicePage['data'][number];
|
|
97
97
|
/**
|
|
98
|
-
* A pending suspend-when-idle request (0.10.0
|
|
98
|
+
* A pending suspend-when-idle request (0.10.0): once the workspace has been idle for `after_seconds`
|
|
99
99
|
* (counted from the later of its last work and `requested_at`), it is suspended; `not_before` = requested_at +
|
|
100
100
|
* after_seconds is the earliest.
|
|
101
101
|
*/
|
|
@@ -103,7 +103,7 @@ export type SuspendRequest = components['schemas']['SuspendRequest'];
|
|
|
103
103
|
/** POST /v1/workspaces/{id}/suspend-when-idle (202). */
|
|
104
104
|
export type SuspendWhenIdleResponse = Ok<operations['postV1WorkspacesWorkspaceIdSuspendWhenIdle']>;
|
|
105
105
|
export interface SuspendWhenIdleOptions {
|
|
106
|
-
/** Seconds the workspace must stay idle before it is suspended: an integer from
|
|
106
|
+
/** Seconds the workspace must stay idle before it is suspended: an integer from 0 (as soon as it is idle) to 3600 (the API refuses others with 422 validation_failed). */
|
|
107
107
|
afterSeconds: number;
|
|
108
108
|
/** Replays the stored response for a repeated request (default: a fresh key per call, so transport retries replay). */
|
|
109
109
|
idempotencyKey?: string;
|
|
@@ -121,7 +121,7 @@ export interface ShardfluxOptions {
|
|
|
121
121
|
apiKey: string;
|
|
122
122
|
/** Default https://api.shardflux.dev (override with `baseUrl`). */
|
|
123
123
|
baseUrl?: string;
|
|
124
|
-
/** Default: the runtime's fetch
|
|
124
|
+
/** Default: the runtime's fetch; on Node 26 every request uses a fresh connection (`Connection: close`) unless SHARDFLUX_HTTP_KEEPALIVE=1. */
|
|
125
125
|
fetch?: typeof fetch;
|
|
126
126
|
userAgent?: string;
|
|
127
127
|
/** Per-request timeout (ms), default 30 s. */
|
|
@@ -136,7 +136,7 @@ export interface ShardfluxOptions {
|
|
|
136
136
|
*/
|
|
137
137
|
onProgress?: ProgressListener;
|
|
138
138
|
/**
|
|
139
|
-
* The automatic version check (0.9.0
|
|
139
|
+
* The automatic version check (0.9.0): after the first successful API response of the process, a
|
|
140
140
|
* background GET /v1/client-versions (3 s timeout, errors swallowed) emits a `ShardfluxUpdateWarning` when this
|
|
141
141
|
* package is outdated or unsupported. Default true (`@shardflux/sdk` at SDK_VERSION); tools built on the SDK pass
|
|
142
142
|
* their own `{ package, version }` or `false`. `SHARDFLUX_NO_UPDATE_CHECK=1` or `NO_UPDATE_NOTIFIER=1` turn it off.
|
|
@@ -155,16 +155,16 @@ export interface ForkTarget {
|
|
|
155
155
|
}
|
|
156
156
|
export interface WaitOptions {
|
|
157
157
|
/**
|
|
158
|
-
* Give up waiting after this long (default 300 000 ms); the operation continues server side. A start
|
|
159
|
-
*
|
|
160
|
-
*
|
|
158
|
+
* Give up waiting after this long (default 300 000 ms); the operation continues server side. A queued start
|
|
159
|
+
* (`capacity_pending`) has a deadline (`error.details.deadline_at`, 15 minutes after it was created); past it, it
|
|
160
|
+
* fails with `capacity_unavailable` (retryable; nothing was started).
|
|
161
161
|
*/
|
|
162
162
|
timeoutMs?: number;
|
|
163
163
|
/** First poll delay (default 250 ms); doubles up to `maxPollIntervalMs` with jitter. Used when the server does not wait. */
|
|
164
164
|
pollIntervalMs?: number;
|
|
165
165
|
maxPollIntervalMs?: number;
|
|
166
166
|
/**
|
|
167
|
-
* Ask the server to hold each poll until the state changes (`Prefer: wait
|
|
167
|
+
* Ask the server to hold each poll until the state changes (`Prefer: wait`; default true). A server
|
|
168
168
|
* that does not wait answers at once and the SDK falls back to the backoff above.
|
|
169
169
|
*/
|
|
170
170
|
serverWait?: boolean;
|
|
@@ -189,7 +189,7 @@ export interface OpenParams {
|
|
|
189
189
|
*/
|
|
190
190
|
secrets?: string[];
|
|
191
191
|
/**
|
|
192
|
-
* The template version's text inputs `{NAME: value}` (0.7.0
|
|
192
|
+
* The template version's text inputs `{NAME: value}` (0.7.0), put into the environment of every
|
|
193
193
|
* exec, terminal, start command and service. A new key stores each given value, else the declared default; an
|
|
194
194
|
* existing key replaces them all (omitted leaves them unchanged). Secret inputs are not passed here: they bind the
|
|
195
195
|
* stored secret of the same name. ShardfluxApiError 422 with details.reason `input_unknown` (an undeclared name),
|
|
@@ -204,7 +204,7 @@ export interface OpenParams {
|
|
|
204
204
|
*/
|
|
205
205
|
lifetime?: WorkspaceLifetime;
|
|
206
206
|
/**
|
|
207
|
-
* `file_first` (0.9.0
|
|
207
|
+
* `file_first` (0.9.0): the workspace is a versioned file tree with no VM between executions. It is
|
|
208
208
|
* ready at once (no operation: the open answers with a tool token), never suspended, and runs commands as executions
|
|
209
209
|
* (`workspace.executions.run()`): a fresh VM on the latest tree whose changed files become the next tree revision;
|
|
210
210
|
* nothing else survives an execution. Needs a layered template version (409 `layout_unsupported` otherwise) and is
|
|
@@ -248,7 +248,7 @@ export interface FindByKeyOptions {
|
|
|
248
248
|
signal?: AbortSignal;
|
|
249
249
|
}
|
|
250
250
|
/**
|
|
251
|
-
* The workspace a key names
|
|
251
|
+
* The workspace a key names: the live row (deleted_at null) when there is one, since at most one live
|
|
252
252
|
* workspace holds a key; otherwise the newest tombstone (ended sessions leave tombstones with the same key, and a
|
|
253
253
|
* deleted persistent key keeps its tombstone). Null when no row has exactly this key. Rows need not be sorted.
|
|
254
254
|
*/
|
|
@@ -283,13 +283,13 @@ export declare class WorkspacesApi {
|
|
|
283
283
|
open(params: OpenParams): Promise<Workspace>;
|
|
284
284
|
/**
|
|
285
285
|
* Waits for an operation: each GET /v1/operations/{id} asks the server to hold the response until the state changes
|
|
286
|
-
* (`Prefer: wait`, at most 20 s
|
|
286
|
+
* (`Prefer: wait`, at most 20 s), so completion is seen within one notification of the commit. A server
|
|
287
287
|
* that does not wait is polled with bounded exponential backoff (+-20 % jitter). Resolves when the operation
|
|
288
288
|
* succeeds; throws OperationFailedError when it fails or is canceled, OperationTimeoutError after `timeoutMs` (the
|
|
289
289
|
* operation keeps running and can be awaited again). Both errors carry the wait's `timing`; `onProgress` sees each
|
|
290
|
-
* state change (queued, capacity_pending, running, with the server's reason) as it is observed. A start
|
|
291
|
-
* capacity_pending
|
|
292
|
-
* (`err.retryable` true: nothing was started
|
|
290
|
+
* state change (queued, capacity_pending, running, with the server's reason) as it is observed. A start in
|
|
291
|
+
* capacity_pending that passes its deadline (`deadlineAt` on the phase event) fails with `capacity_unavailable`
|
|
292
|
+
* (`err.retryable` true: nothing was started; send it again); the SDK does not retry it.
|
|
293
293
|
*/
|
|
294
294
|
waitForOperation(operationId: string, opts?: WaitOptions): Promise<Operation>;
|
|
295
295
|
/** One operation (GET /v1/operations/{id}); lifecycle operations stay pollable after a workspace is deleted. */
|
|
@@ -323,7 +323,7 @@ export declare class WorkspacesApi {
|
|
|
323
323
|
suspend(workspaceId: string, opts?: LifecycleOptions): Promise<Operation>;
|
|
324
324
|
/**
|
|
325
325
|
* Resumes a suspended workspace. Resolves when the resume is requested; with `wait`, once the workspace runs. With
|
|
326
|
-
* `wait` (0.9.0) the request is held by the server until the workspace runs (
|
|
326
|
+
* `wait` (0.9.0) the request is held by the server until the workspace runs (one request, timing phase
|
|
327
327
|
* `request` with reason `held`); a server that does not hold it answers at once and the operation is polled.
|
|
328
328
|
* `serverWait: false` polls only. `agentLabel`/`tools` choose the tool token the held answer carries (attribution
|
|
329
329
|
* only here; `workspace.resume()` keeps it). A workspace that is already running is ShardfluxApiError 409 `conflict`
|
|
@@ -333,7 +333,7 @@ export declare class WorkspacesApi {
|
|
|
333
333
|
resume(workspaceId: string, opts?: ResumeOptions): Promise<Operation>;
|
|
334
334
|
/**
|
|
335
335
|
* One `POST /v1/workspaces/{id}/resume` (0.9.0), held for up to `waitS` seconds when that is at least 1 (`Prefer:
|
|
336
|
-
* wait
|
|
336
|
+
* wait`), asking for the tool token of `agentLabel`/`tools`. `ready` only for a 200 the server says it
|
|
337
337
|
* held (`Preference-Applied`); every other answer is the operation to wait for, so a server without the held resume
|
|
338
338
|
* works unchanged. Refusals (409 operation_in_progress, already_running without the hold, ...) throw as usual.
|
|
339
339
|
* `Workspace.wake()` and `resume({ wait })` use it; most callers want those.
|
|
@@ -347,7 +347,7 @@ export declare class WorkspacesApi {
|
|
|
347
347
|
label?: string;
|
|
348
348
|
}): Promise<Operation>;
|
|
349
349
|
/**
|
|
350
|
-
* Suspends the workspace once it has been idle for `afterSeconds` (0.9.0
|
|
350
|
+
* Suspends the workspace once it has been idle for `afterSeconds` (0.9.0): meant for the end of an
|
|
351
351
|
* agent turn, so the workspace stops using RAM soon after instead of waiting out its idle policy. The idle time
|
|
352
352
|
* counts from the later of the workspace's last work and this request. A command still running, an attached exec or
|
|
353
353
|
* terminal stream, or a keepalive postpones the suspend until `afterSeconds` after it ends; a tool call after the
|
|
@@ -357,7 +357,7 @@ export declare class WorkspacesApi {
|
|
|
357
357
|
* Resolves with the recorded `suspendRequest`, or, when a suspend is already in progress, with that `operation` and
|
|
358
358
|
* nothing recorded. Tool-call capture writes recorded before the call land first (a later write would count as the
|
|
359
359
|
* next turn). Errors: ShardfluxApiError 409 with reason `not_running`, `operation_in_progress`, `session_lifetime` or
|
|
360
|
-
* `workspace_deleted`; 422 `validation_failed` for `afterSeconds` outside
|
|
360
|
+
* `workspace_deleted`; 422 `validation_failed` for `afterSeconds` outside 0..3600.
|
|
361
361
|
*
|
|
362
362
|
* await cloud.workspaces.suspendWhenIdle(workspace.id, { afterSeconds: 60 });
|
|
363
363
|
*/
|
|
@@ -369,7 +369,7 @@ export declare class WorkspacesApi {
|
|
|
369
369
|
*/
|
|
370
370
|
cancelSuspendWhenIdle(workspaceId: string): Promise<Workspace>;
|
|
371
371
|
/**
|
|
372
|
-
* Ends a session workspace now
|
|
372
|
+
* Ends a session workspace now: the workspace is deleted exactly like delete() (ended_reason
|
|
373
373
|
* closed) and returns the `delete` operation (input.reason session_closed); the key then opens a NEW workspace.
|
|
374
374
|
* Idempotent. A persistent workspace is ShardfluxApiError 409 (details.reason `not_session`): use
|
|
375
375
|
* `workspace.close()`, which calls this only for sessions. With `wait`, resolves once the delete has finished.
|
|
@@ -382,7 +382,7 @@ export declare class WorkspacesApi {
|
|
|
382
382
|
workspace: WorkspaceView;
|
|
383
383
|
}>;
|
|
384
384
|
/**
|
|
385
|
-
* Resets a layered workspace to its template
|
|
385
|
+
* Resets a layered workspace to its template: every change in the workspace layer is wiped; key,
|
|
386
386
|
* id, template version, caps, secret bindings and volume attachments stay. Running: restarted on a blank layer
|
|
387
387
|
* (processes are gone; old tool tokens get 409 stale_epoch and the SDK refreshes them). Suspended: stays suspended and
|
|
388
388
|
* boots blank on the next resume. Returns the `reset` operation; its result names the recovery checkpoint (restorable
|
|
@@ -391,7 +391,7 @@ export declare class WorkspacesApi {
|
|
|
391
391
|
reset(workspaceId: string, opts: WaitedLifecycleOptions): Promise<FinishedOperation>;
|
|
392
392
|
reset(workspaceId: string, opts?: LifecycleOptions): Promise<Operation>;
|
|
393
393
|
/**
|
|
394
|
-
* Saves a layered workspace as the next version of an organization template
|
|
394
|
+
* Saves a layered workspace as the next version of an organization template. A running workspace is
|
|
395
395
|
* captured briefly (`operation`, layer_snapshot); poll `build` with templates.builds.waitForBuild. Owners/admins and
|
|
396
396
|
* API keys with a tool permission only.
|
|
397
397
|
*/
|
|
@@ -409,7 +409,7 @@ export declare class WorkspacesApi {
|
|
|
409
409
|
operation: Operation;
|
|
410
410
|
workspace: Workspace;
|
|
411
411
|
}>;
|
|
412
|
-
/** The workspace's text inputs `{NAME: value}` (0.7.0
|
|
412
|
+
/** The workspace's text inputs `{NAME: value}` (0.7.0). Secret inputs are bound secrets, never listed. */
|
|
413
413
|
inputs(workspaceId: string): Promise<Record<string, string>>;
|
|
414
414
|
operations(workspaceId: string, params?: {
|
|
415
415
|
limit?: number;
|
|
@@ -454,17 +454,17 @@ export declare class Shardflux {
|
|
|
454
454
|
readonly egress: EgressPolicyApi;
|
|
455
455
|
/** Organization audit trail (owner/admin; API keys are refused with 403). */
|
|
456
456
|
readonly audit: AuditApi;
|
|
457
|
-
/** Shared volumes: persistent storage attached to workspaces at a mount path
|
|
457
|
+
/** Shared volumes: persistent storage attached to workspaces at a mount path. */
|
|
458
458
|
readonly volumes: VolumesApi;
|
|
459
459
|
constructor(opts: ShardfluxOptions);
|
|
460
460
|
/** The authenticated principal (the API key, its organization and project). */
|
|
461
461
|
me(): Promise<Me>;
|
|
462
462
|
entitlements(organizationId: string): Promise<Entitlements>;
|
|
463
463
|
/**
|
|
464
|
-
* Send feedback straight to the Shardflux
|
|
465
|
-
*
|
|
466
|
-
*
|
|
467
|
-
* the logs. `context.client` defaults to `shardflux-sdk-ts/<SDK_VERSION>`. Returns `{ id, receivedAt, duplicate }`
|
|
464
|
+
* Send feedback straight to the Shardflux team (0.9.0+; POST /v1/feedback), who read every message. Use it while you
|
|
465
|
+
* work, the moment something fails unexpectedly, an error or doc is unclear, an option is missing, or a workaround was
|
|
466
|
+
* needed, and when your user asks for a capability, an option or a smoother workflow; short and specific beats
|
|
467
|
+
* polished, and `context.requestId` / `errorCode` let the team find the logs. `context.client` defaults to `shardflux-sdk-ts/<SDK_VERSION>`. Returns `{ id, receivedAt, duplicate }`
|
|
468
468
|
* (`duplicate`: the same message from this key within 24 hours; no second email). 429 `rate_limited` (with
|
|
469
469
|
* `retryAfterSeconds`) and 422 `validation_failed` are ShardfluxApiErrors; the call is never retried.
|
|
470
470
|
*/
|
package/dist/client.js
CHANGED
|
@@ -13,7 +13,7 @@ import { Trace, combineListeners, traced } from "./progress.js";
|
|
|
13
13
|
import { CaptureRegistry } from "./capture.js";
|
|
14
14
|
import { sendFeedback } from "./feedback.js";
|
|
15
15
|
/**
|
|
16
|
-
* The workspace a key names
|
|
16
|
+
* The workspace a key names: the live row (deleted_at null) when there is one, since at most one live
|
|
17
17
|
* workspace holds a key; otherwise the newest tombstone (ended sessions leave tombstones with the same key, and a
|
|
18
18
|
* deleted persistent key keeps its tombstone). Null when no row has exactly this key. Rows need not be sorted.
|
|
19
19
|
*/
|
|
@@ -61,7 +61,7 @@ function abortableSleep(sleep, ms, signal) {
|
|
|
61
61
|
}
|
|
62
62
|
export class WorkspacesApi {
|
|
63
63
|
#ctx;
|
|
64
|
-
/** The cell endpoint of the last tool token seen: an open pre-connects to it while the server works
|
|
64
|
+
/** The cell endpoint of the last tool token seen: an open pre-connects to it while the server works. */
|
|
65
65
|
#cellHint = null;
|
|
66
66
|
constructor(ctx) {
|
|
67
67
|
this.#ctx = ctx;
|
|
@@ -108,7 +108,7 @@ export class WorkspacesApi {
|
|
|
108
108
|
const started = Date.now();
|
|
109
109
|
const timeoutMs = waitOpts?.timeoutMs ?? 300_000;
|
|
110
110
|
if (waitOpts && waitOpts.serverWait !== false) {
|
|
111
|
-
// Held open
|
|
111
|
+
// Held open: the server answers once the operation is terminal (200 with the running workspace
|
|
112
112
|
// and a tool token) or the wait elapsed (202); a server without it answers 202 at once and the poll below runs.
|
|
113
113
|
const s = Math.min(SERVER_WAIT_MAX_S, Math.floor(timeoutMs / 1000));
|
|
114
114
|
if (s >= 1) {
|
|
@@ -188,13 +188,13 @@ export class WorkspacesApi {
|
|
|
188
188
|
}
|
|
189
189
|
/**
|
|
190
190
|
* Waits for an operation: each GET /v1/operations/{id} asks the server to hold the response until the state changes
|
|
191
|
-
* (`Prefer: wait`, at most 20 s
|
|
191
|
+
* (`Prefer: wait`, at most 20 s), so completion is seen within one notification of the commit. A server
|
|
192
192
|
* that does not wait is polled with bounded exponential backoff (+-20 % jitter). Resolves when the operation
|
|
193
193
|
* succeeds; throws OperationFailedError when it fails or is canceled, OperationTimeoutError after `timeoutMs` (the
|
|
194
194
|
* operation keeps running and can be awaited again). Both errors carry the wait's `timing`; `onProgress` sees each
|
|
195
|
-
* state change (queued, capacity_pending, running, with the server's reason) as it is observed. A start
|
|
196
|
-
* capacity_pending
|
|
197
|
-
* (`err.retryable` true: nothing was started
|
|
195
|
+
* state change (queued, capacity_pending, running, with the server's reason) as it is observed. A start in
|
|
196
|
+
* capacity_pending that passes its deadline (`deadlineAt` on the phase event) fails with `capacity_unavailable`
|
|
197
|
+
* (`err.retryable` true: nothing was started; send it again); the SDK does not retry it.
|
|
198
198
|
*/
|
|
199
199
|
async waitForOperation(operationId, opts = {}) {
|
|
200
200
|
const inherited = opts[TRACE];
|
|
@@ -379,7 +379,7 @@ export class WorkspacesApi {
|
|
|
379
379
|
}
|
|
380
380
|
/**
|
|
381
381
|
* One `POST /v1/workspaces/{id}/resume` (0.9.0), held for up to `waitS` seconds when that is at least 1 (`Prefer:
|
|
382
|
-
* wait
|
|
382
|
+
* wait`), asking for the tool token of `agentLabel`/`tools`. `ready` only for a 200 the server says it
|
|
383
383
|
* held (`Preference-Applied`); every other answer is the operation to wait for, so a server without the held resume
|
|
384
384
|
* works unchanged. Refusals (409 operation_in_progress, already_running without the hold, ...) throw as usual.
|
|
385
385
|
* `Workspace.wake()` and `resume({ wait })` use it; most callers want those.
|
|
@@ -419,7 +419,7 @@ export class WorkspacesApi {
|
|
|
419
419
|
return this.#op('snapshot', workspaceId, opts.label === undefined ? {} : { label: opts.label }, opts);
|
|
420
420
|
}
|
|
421
421
|
/**
|
|
422
|
-
* Suspends the workspace once it has been idle for `afterSeconds` (0.9.0
|
|
422
|
+
* Suspends the workspace once it has been idle for `afterSeconds` (0.9.0): meant for the end of an
|
|
423
423
|
* agent turn, so the workspace stops using RAM soon after instead of waiting out its idle policy. The idle time
|
|
424
424
|
* counts from the later of the workspace's last work and this request. A command still running, an attached exec or
|
|
425
425
|
* terminal stream, or a keepalive postpones the suspend until `afterSeconds` after it ends; a tool call after the
|
|
@@ -429,7 +429,7 @@ export class WorkspacesApi {
|
|
|
429
429
|
* Resolves with the recorded `suspendRequest`, or, when a suspend is already in progress, with that `operation` and
|
|
430
430
|
* nothing recorded. Tool-call capture writes recorded before the call land first (a later write would count as the
|
|
431
431
|
* next turn). Errors: ShardfluxApiError 409 with reason `not_running`, `operation_in_progress`, `session_lifetime` or
|
|
432
|
-
* `workspace_deleted`; 422 `validation_failed` for `afterSeconds` outside
|
|
432
|
+
* `workspace_deleted`; 422 `validation_failed` for `afterSeconds` outside 0..3600.
|
|
433
433
|
*
|
|
434
434
|
* await cloud.workspaces.suspendWhenIdle(workspace.id, { afterSeconds: 60 });
|
|
435
435
|
*/
|
|
@@ -465,7 +465,7 @@ export class WorkspacesApi {
|
|
|
465
465
|
return this.#op('reset', workspaceId, body, opts);
|
|
466
466
|
}
|
|
467
467
|
/**
|
|
468
|
-
* Saves a layered workspace as the next version of an organization template
|
|
468
|
+
* Saves a layered workspace as the next version of an organization template. A running workspace is
|
|
469
469
|
* captured briefly (`operation`, layer_snapshot); poll `build` with templates.builds.waitForBuild. Owners/admins and
|
|
470
470
|
* API keys with a tool permission only.
|
|
471
471
|
*/
|
|
@@ -488,7 +488,7 @@ export class WorkspacesApi {
|
|
|
488
488
|
}, { settle: true });
|
|
489
489
|
return { operation, workspace: copy };
|
|
490
490
|
}
|
|
491
|
-
/** The workspace's text inputs `{NAME: value}` (0.7.0
|
|
491
|
+
/** The workspace's text inputs `{NAME: value}` (0.7.0). Secret inputs are bound secrets, never listed. */
|
|
492
492
|
async inputs(workspaceId) {
|
|
493
493
|
const body = await this.#http.json('GET', `/v1/workspaces/${encodeURIComponent(workspaceId)}/inputs`, {}, this.#auth);
|
|
494
494
|
return body.inputs;
|
|
@@ -546,7 +546,7 @@ export class Shardflux {
|
|
|
546
546
|
egress;
|
|
547
547
|
/** Organization audit trail (owner/admin; API keys are refused with 403). */
|
|
548
548
|
audit;
|
|
549
|
-
/** Shared volumes: persistent storage attached to workspaces at a mount path
|
|
549
|
+
/** Shared volumes: persistent storage attached to workspaces at a mount path. */
|
|
550
550
|
volumes;
|
|
551
551
|
#ctx;
|
|
552
552
|
constructor(opts) {
|
|
@@ -583,10 +583,10 @@ export class Shardflux {
|
|
|
583
583
|
return this.#ctx.http.json('GET', `/v1/organizations/${encodeURIComponent(organizationId)}/entitlements`, {}, this.#ctx.authorization);
|
|
584
584
|
}
|
|
585
585
|
/**
|
|
586
|
-
* Send feedback straight to the Shardflux
|
|
587
|
-
*
|
|
588
|
-
*
|
|
589
|
-
* the logs. `context.client` defaults to `shardflux-sdk-ts/<SDK_VERSION>`. Returns `{ id, receivedAt, duplicate }`
|
|
586
|
+
* Send feedback straight to the Shardflux team (0.9.0+; POST /v1/feedback), who read every message. Use it while you
|
|
587
|
+
* work, the moment something fails unexpectedly, an error or doc is unclear, an option is missing, or a workaround was
|
|
588
|
+
* needed, and when your user asks for a capability, an option or a smoother workflow; short and specific beats
|
|
589
|
+
* polished, and `context.requestId` / `errorCode` let the team find the logs. `context.client` defaults to `shardflux-sdk-ts/<SDK_VERSION>`. Returns `{ id, receivedAt, duplicate }`
|
|
590
590
|
* (`duplicate`: the same message from this key within 24 hours; no second email). 429 `rate_limited` (with
|
|
591
591
|
* `retryAfterSeconds`) and 422 `validation_failed` are ShardfluxApiErrors; the call is never retried.
|
|
592
592
|
*/
|
package/dist/egress.d.ts
CHANGED
|
@@ -50,7 +50,7 @@ export interface EgressPolicyVersion {
|
|
|
50
50
|
created_at: string;
|
|
51
51
|
}
|
|
52
52
|
export interface EffectiveEgressPolicy {
|
|
53
|
-
/** organization: an organization egress override
|
|
53
|
+
/** organization: an organization egress override wins over every policy (mode deny_all, no version). */
|
|
54
54
|
source: 'organization' | 'workspace' | 'project' | 'platform_default';
|
|
55
55
|
policy_version_id: string | null;
|
|
56
56
|
policy_version: number | null;
|
|
@@ -60,7 +60,7 @@ export interface EffectiveEgressPolicy {
|
|
|
60
60
|
policy_sha256: string;
|
|
61
61
|
}
|
|
62
62
|
/**
|
|
63
|
-
* Active organization egress override
|
|
63
|
+
* Active organization egress override: the organization used its whole outbound transfer allowance,
|
|
64
64
|
* so outbound internet traffic of every workspace is blocked until `lifts_at` (period end) or an upgrade/purchase.
|
|
65
65
|
* Stored policies are kept and apply again when it lifts.
|
|
66
66
|
*/
|
|
@@ -123,7 +123,7 @@ export interface WorkspaceEgressPolicy {
|
|
|
123
123
|
organization_override: OrganizationEgressOverride | null;
|
|
124
124
|
enforcement: EgressEnforcement;
|
|
125
125
|
/**
|
|
126
|
-
* The template version's network ceiling (0.7.0
|
|
126
|
+
* The template version's network ceiling (0.7.0 `defaults.egress`), or null. The host enforces
|
|
127
127
|
* `effective` intersected with it; a workspace policy it would narrow is refused with 422 egress_widening.
|
|
128
128
|
*/
|
|
129
129
|
template_egress: {
|