@computesdk/platform 0.0.0-stage → 0.2.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 computesdk
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,154 @@
1
- # Temporary Holding Version
1
+ # @computesdk/platform
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ ComputeSDK provider for [ComputeSDK Platform](https://platform.computesdk.com) hosted sandboxes — the same `compute` / `sandbox` interface as every other provider, backed by the platform's own sandbox API. Market placement, provider fallback, the secrets vault, warm pools and cost tracking all live server-side; your code gets one sandbox ID space and one API.
4
+
5
+ ```bash
6
+ npm install computesdk @computesdk/platform
7
+ ```
8
+
9
+ ```typescript
10
+ import { compute } from 'computesdk';
11
+ import { platform } from '@computesdk/platform';
12
+
13
+ const sdk = compute({
14
+ provider: platform({ apiKey: process.env.COMPUTE_API_KEY }),
15
+ });
16
+
17
+ const sandbox = await sdk.sandbox.create({ size: 'small' });
18
+ const result = await sandbox.runCommand('echo hello');
19
+ console.log(result.stdout);
20
+ await sandbox.destroy();
21
+ ```
22
+
23
+ ## Authentication
24
+
25
+ Credentials resolve once per provider instance, with the same precedence as the `compute` CLI:
26
+
27
+ 1. `apiKey` in config
28
+ 2. `COMPUTE_API_KEY` env var
29
+ 3. `BENCHMARKS_PLATFORM_API_KEY` env var (legacy alias)
30
+ 4. A `compute login` session (requires `@benchsdk/cli` installed — it's an optional peer dependency; the session store is read and refreshed but a login is never started)
31
+
32
+ Base URL resolves similarly: `baseUrl` in config, then `COMPUTE_PLATFORM_URL`, then `BENCHMARKS_PLATFORM_URL`, then `https://platform.computesdk.com`.
33
+
34
+ Credentials are only sent to `computesdk.com`, its subdomains, or loopback — pass `allowUntrustedHost: true` to send them elsewhere (HTTPS still required off-loopback). With no key configured you get a `no_credentials` error telling you to set `COMPUTE_API_KEY`, pass `apiKey`, or run `compute login`.
35
+
36
+ `org` in config (or `COMPUTE_ORG`) sends `X-Org-Slug` on every request, for API keys that span orgs. A stored login's saved org is never sent — the platform already knows the active org.
37
+
38
+ ## Sizes and pricing
39
+
40
+ Creates accept either a platform `size` or raw resources — never both:
41
+
42
+ ```typescript
43
+ // Sizes: 'small' | 'medium' | 'large' | 'xlarge'
44
+ await sdk.sandbox.create({ size: 'medium' });
45
+
46
+ // Or raw resources (aliases: cpus|vcpus, memoryMb|memoryMiB|memMiB|memory, diskMb|diskMiB)
47
+ await sdk.sandbox.create({ cpus: 4, memoryMb: 8192, diskMb: 20000 });
48
+ ```
49
+
50
+ Market pricing options — `maxPrice: { usd, per: 'hour' }` and `orderType: 'market' | 'limit'` — can be passed per call or set once as `defaults` on the provider. `providerOrder` ranks where the platform tries to place the sandbox: your own provider keys by name, or `'market'` for the compute market.
51
+
52
+ ```typescript
53
+ const provider = platform({
54
+ apiKey: process.env.COMPUTE_API_KEY,
55
+ defaults: {
56
+ size: 'small',
57
+ maxPrice: { usd: 0.5, per: 'hour' },
58
+ providerOrder: ['e2b', 'market'], // own E2B key first, market on failure
59
+ },
60
+ });
61
+ ```
62
+
63
+ ## Own-keys (no market)
64
+
65
+ A `providerOrder` with no `'market'` entry never touches the market — no buyer-lane approval, no credits, no cap; `maxPrice` and `orderType` are ignored (an own-key placement has no order semantics) and your provider bills you directly. The keys live in the org's vault, not in your code.
66
+
67
+ ```typescript
68
+ const provider = platform({
69
+ apiKey: process.env.COMPUTE_API_KEY,
70
+ defaults: { providerOrder: ['e2b'] }, // own-keys only
71
+ });
72
+ ```
73
+
74
+ Provider order resolution: the call's `providerOrder`, then `defaults.providerOrder`, then the org's sandbox provider order (dashboard), then its Actions provider order. An org with none of these defaults to `['market']` — so own-keys users must set a provider order somewhere.
75
+
76
+ ## Errors
77
+
78
+ API failures throw `PlatformApiError` with three derived fields:
79
+
80
+ - `code` — the body's `details.code`, then top-level `code`, then a code derived from the HTTP status (`bad_request`, `unauthenticated`, `forbidden`, `not_found`, `conflict`, `payload_too_large`, `rate_limited`, `server_error`, `http_error`)
81
+ - `details` — the body's `details` object (e.g. `details.attempts` on a placement failure)
82
+ - `retryable` — true for 429/502/503/504, except market codes, which don't change on retry
83
+
84
+ The market codes: `market_cap_required`, `market_access_required`, `limit_not_met`, `above_protection_limit`, `insufficient_credits`, `no_market_capacity`, `no_provider_configured`, `market_lane_not_approved`. Plus `sandbox_booting`, `idempotency_key_reused`, and the client's own `PlatformClientError` codes (`no_credentials`, `untrusted_host`, `untrusted_host_stored_auth`, `insecure_transport`, `invalid_argument`, `stream_ended`, `create_outcome_unknown`). Both code unions are exported and intentionally open.
85
+
86
+ ```typescript
87
+ try {
88
+ await sdk.sandbox.create();
89
+ } catch (err) {
90
+ if (err instanceof Error && 'code' in err) {
91
+ switch ((err as { code: string }).code) {
92
+ case 'insufficient_credits': /* top up */ break;
93
+ case 'no_market_capacity': /* retry later */ break;
94
+ }
95
+ }
96
+ }
97
+ ```
98
+
99
+ In multi-provider mode, `switch (err.code)` only sees the final error — the originals are on `err.errors`:
100
+
101
+ ```typescript
102
+ import { e2b } from '@computesdk/e2b';
103
+
104
+ const sdk = compute({ providers: [platform({ apiKey: k }), e2b({ apiKey: ek })] });
105
+ try {
106
+ await sdk.sandbox.create();
107
+ } catch (err) {
108
+ const codes = ((err as { errors?: { code?: string }[] }).errors ?? []).map((e) => e.code);
109
+ // e.g. ['no_market_capacity', 'unauthenticated']
110
+ }
111
+ ```
112
+
113
+ One exception: an error marked `fallback: false` (only `create_outcome_unknown` today) rethrows immediately — a box may exist and be billing, so trying another provider could boot a second one.
114
+
115
+ Retries the SDK runs itself (the CLI does none of these): `sandbox_booting` exponential backoff up to ~60s (matched on the code — `no_market_capacity` is also a 503 and is never retried), `429` honoring `Retry-After`, and network errors on GET/DELETE only. No other POST is retried.
116
+
117
+ ## Limits
118
+
119
+ - **Files**: ~4 MB per `readFile`/`writeFile` (UTF-8 bytes). The platform sits behind a 4.5 MB body cap; larger files need the upload/download URL route (not yet implemented).
120
+ - **Commands**: `timeout` caps at 290s — the platform clamps it silently, so the SDK rejects higher values with `invalid_argument`. Longer work goes to `runCommand(cmd, { background: true })` (the processes route).
121
+ - **Command length**: 64 KB.
122
+ - **Secrets**: up to 100 vault secret names per sandbox.
123
+
124
+ ## Idempotent create
125
+
126
+ Every `create` mints an `sdk-create:<uuid>` idempotency key, so a network blip or the 310s request timeout replays the same request instead of placing a second sandbox. Pass your own `idempotencyKey` to make the create safe across process restarts:
127
+
128
+ ```typescript
129
+ await sdk.sandbox.create({ size: 'small', idempotencyKey: 'deploy-2026-10-27-a' } as any);
130
+ ```
131
+
132
+ Same key + same request → the existing sandbox back, whatever its status. Same key + different request → `idempotency_key_reused` (409). A failed placement frees the key.
133
+
134
+ If the outcome can't be determined within ~6 minutes, create throws `create_outcome_unknown` — check the org dashboard before retrying; the sandbox may still be creating.
135
+
136
+ ## Other create options
137
+
138
+ `label` (≤200 chars, falls back to `name`), `secrets` (org vault names), `disk` (`{ diskId: '<orgSlug>/<diskId>', path, readonly?, branch? }`), `snapshotId`, `image`/`templateId`, `timeout` (→ `timeoutMs`), `envs` (merged under every command's `env`, request env wins).
139
+
140
+ ## What maps where
141
+
142
+ | SDK call | Platform route |
143
+ |---|---|
144
+ | `sandbox.create` | `POST /api/v1/sandboxes` |
145
+ | `sandbox.getById` | `GET /api/v1/sandboxes/:id` (404 → `null`) |
146
+ | `sandbox.list` | `GET /api/v1/sandboxes?status=running` (follows `nextCursor`) |
147
+ | `sandbox.destroy` | `DELETE /api/v1/sandboxes/:id` (404 = gone) |
148
+ | `runCommand` | `POST /api/v1/sandboxes/:id/commands` (`cwd`, `env`, `timeoutMs`) |
149
+ | `runCommand` + callbacks | same, `Accept: text/event-stream` (`stdout`/`stderr`/`exit`/`error`) |
150
+ | `runCommand` + `background` | `POST /api/v1/sandboxes/:id/processes` |
151
+ | `getUrl` | `GET /api/v1/sandboxes/:id/urls?port=&protocol=` |
152
+ | `filesystem.*` | `GET/POST/DELETE /api/v1/sandboxes/:id/files` |
153
+
154
+ Templates are not supported by this provider.
@@ -0,0 +1,334 @@
1
+ import * as _computesdk_provider from '@computesdk/provider';
2
+ import { CreateInstanceOptions } from '@computesdk/provider';
3
+
4
+ /**
5
+ * Thin client for the hosted ComputeSDK platform API.
6
+ *
7
+ * This is the single platform transport: `@computesdk/platform` (the SDK
8
+ * provider) and `@computesdk/cli` both use it. Wire types for Actions and
9
+ * sandboxes live in `types.ts` (sandboxes) and in the CLI (Actions); the API
10
+ * is the contract.
11
+ */
12
+ declare const DEFAULT_BASE_URL = "https://platform.computesdk.com";
13
+ /**
14
+ * Market order codes the platform returns. Retrying never changes the
15
+ * outcome, so errors carrying them are `retryable: false`.
16
+ */
17
+ declare const MARKET_CODES: ReadonlySet<string>;
18
+ /**
19
+ * Codes a `PlatformApiError` can carry — the market order codes, the sandbox
20
+ * lifecycle codes, and `codeForStatus`'s status-table codes. Kept open for
21
+ * codes added later; callers can `switch (err.code)`.
22
+ */
23
+ type PlatformApiErrorCode = 'market_cap_required' | 'market_access_required' | 'limit_not_met' | 'above_protection_limit' | 'insufficient_credits' | 'no_market_capacity' | 'no_provider_configured' | 'market_lane_not_approved' | 'sandbox_booting' | 'idempotency_key_reused' | 'bad_request' | 'unauthenticated' | 'forbidden' | 'not_found' | 'conflict' | 'payload_too_large' | 'rate_limited' | 'server_error' | 'http_error' | (string & {});
24
+ interface PlatformAuth {
25
+ apiKey: string;
26
+ baseUrl: string;
27
+ /** Sent as `X-Org-Slug` when set (--org / COMPUTE_ORG / stored login org). */
28
+ orgSlug?: string;
29
+ }
30
+ declare class PlatformApiError extends Error {
31
+ status: number;
32
+ body?: unknown | undefined;
33
+ /** details.code ?? body.code ?? codeForStatus(status) */
34
+ readonly code: PlatformApiErrorCode;
35
+ /** The body's `details` object, when the error response carried one. */
36
+ readonly details?: Record<string, unknown>;
37
+ /** 429/502/503/504 — except market codes, which don't change on retry. */
38
+ readonly retryable: boolean;
39
+ /** Parsed `Retry-After` in ms, when the response carried the header. */
40
+ retryAfterMs?: number;
41
+ constructor(status: number, message: string, body?: unknown | undefined);
42
+ }
43
+ /** Stable machine-readable codes for errors raised by the client itself. */
44
+ type PlatformClientErrorCode = 'no_credentials' | 'untrusted_host' | 'untrusted_host_stored_auth' | 'insecure_transport' | 'invalid_argument' | 'stream_ended' | 'create_outcome_unknown' | 'workflow_not_found' | (string & {});
45
+ /** An error the client raised before or instead of an API call. */
46
+ declare class PlatformClientError extends Error {
47
+ code: PlatformClientErrorCode;
48
+ /**
49
+ * `false` means falling back to another provider is unsafe — e.g.
50
+ * create_outcome_unknown, where a box may exist and be billing.
51
+ */
52
+ fallback?: boolean;
53
+ constructor(code: PlatformClientErrorCode, message: string);
54
+ }
55
+ /** The `--json` error envelope; `code` is stable, `message` is for humans. */
56
+ interface PlatformErrorEnvelope {
57
+ ok: false;
58
+ error: {
59
+ code: string;
60
+ message: string;
61
+ /** Present when the platform answered; absent for local/transport failures. */
62
+ httpStatus?: number;
63
+ retryable: boolean;
64
+ /** The platform's `details` object, when its error response carried one. */
65
+ details?: Record<string, unknown>;
66
+ };
67
+ }
68
+ declare function codeForStatus(status: number): string;
69
+ declare function errorDetails(body: unknown): Record<string, unknown> | undefined;
70
+ /**
71
+ * Classify any error thrown by an Actions command. API errors carry the HTTP
72
+ * status; CLI errors carry their own code; a fetch rejection (DNS, refused
73
+ * connection, TLS) is `network`; anything else is `unknown`.
74
+ */
75
+ declare function toErrorEnvelope(error: unknown): PlatformErrorEnvelope;
76
+ declare class PlatformClient {
77
+ private readonly auth;
78
+ private readonly fetchImpl;
79
+ constructor(auth: PlatformAuth, fetchImpl?: typeof fetch);
80
+ get baseUrl(): string;
81
+ get<T>(path: string, params?: Record<string, string | string[] | undefined>, opts?: RequestOpts): Promise<T>;
82
+ post<T>(path: string, body?: Record<string, unknown>, opts?: RequestOpts): Promise<T>;
83
+ /**
84
+ * POST JSON and return the raw response body for SSE reading
85
+ * (Accept: text/event-stream). Callers feed it to `readSseNamedEvents`.
86
+ */
87
+ postStream(path: string, body?: Record<string, unknown>, opts?: RequestOpts): Promise<ReadableStream<Uint8Array>>;
88
+ /** POST a raw text body (e.g. a unified diff to `/api/v1/actions/patches`). */
89
+ postText<T>(path: string, body: string, contentType: string, opts?: RequestOpts): Promise<T>;
90
+ put<T>(path: string, body?: Record<string, unknown>, opts?: RequestOpts): Promise<T>;
91
+ patch<T>(path: string, body?: Record<string, unknown>, opts?: RequestOpts): Promise<T>;
92
+ del<T>(path: string, opts?: RequestOpts): Promise<T>;
93
+ /**
94
+ * One `data:` JSON payload per SSE event. `next()` resolves to the payload,
95
+ * or null when the stream ends. Call `close()` to abort.
96
+ */
97
+ sse(path: string, params?: Record<string, string | string[] | undefined>, opts?: RequestOpts): AsyncGenerator<unknown>;
98
+ /**
99
+ * `sse()` with the frame's `event:` name preserved — for streams whose
100
+ * events are distinguished by name rather than payload shape (process
101
+ * follow: stdout/stderr share a `{chunk}` payload).
102
+ */
103
+ sseNamed(path: string, params?: Record<string, string | string[] | undefined>, opts?: RequestOpts): AsyncGenerator<{
104
+ event: string;
105
+ data: unknown;
106
+ }>;
107
+ /** Download bytes following redirects (artifact URLs 302 to storage). */
108
+ download(path: string, opts?: RequestOpts): Promise<Uint8Array>;
109
+ private headers;
110
+ private parse;
111
+ }
112
+ interface RequestOpts {
113
+ signal?: AbortSignal;
114
+ }
115
+ /** Minimal SSE reader: yields the JSON payload of each `data:` event. */
116
+ declare function readSseEvents(body: ReadableStream<Uint8Array>): AsyncGenerator<unknown>;
117
+ /** `readSseEvents` with the `event:` name preserved alongside the JSON payload. */
118
+ declare function readSseNamedEvents(body: ReadableStream<Uint8Array>): AsyncGenerator<{
119
+ event: string;
120
+ data: unknown;
121
+ }>;
122
+ /** The subset of `@benchsdk/cli`'s `resolveAuth` result Actions needs. */
123
+ type StoredPlatformAuth = {
124
+ apiKey?: string;
125
+ token?: string;
126
+ orgSlug?: string;
127
+ orgId?: string;
128
+ };
129
+ type StoredPlatformAuthResolver = (opts: {
130
+ baseUrl: string;
131
+ }) => Promise<StoredPlatformAuth>;
132
+ /**
133
+ * Precedence: `--api-key` > `COMPUTE_API_KEY` > `BENCHMARKS_PLATFORM_API_KEY`
134
+ * (legacy) > platform OAuth credentials stored by `compute login`
135
+ * (`~/.benchsdk/credentials.json`, via `@benchsdk/cli`'s `resolveAuth`, which
136
+ * refreshes an expired access token but never opens a browser). `compute
137
+ * login` writes the same store, so a platform login covers these commands.
138
+ */
139
+ declare function resolvePlatformAuth(opts: {
140
+ apiKey?: string;
141
+ baseUrl?: string;
142
+ allowUntrustedHost?: boolean;
143
+ /** One-off org override: sent as X-Org-Slug (also settable via COMPUTE_ORG). */
144
+ org?: string;
145
+ }, resolveStored?: StoredPlatformAuthResolver,
146
+ /** Overrides the no-credentials message's credential hint (the CLI passes `--api-key`). */
147
+ credentialsHint?: string): Promise<PlatformAuth>;
148
+ /** https://, or http:// to a loopback host only. */
149
+ declare function isSecurePlatformTransport(baseUrl: string): boolean;
150
+ /** computesdk.com (and subdomains) or localhost — safe to receive the API key. */
151
+ declare function isTrustedPlatformHost(baseUrl: string): boolean;
152
+
153
+ /**
154
+ * Sandbox wire types — mirror the response shapes of
155
+ * benchmarks-platform `lib/sandboxes` (the `/api/v1/sandboxes` routes).
156
+ * The API is the contract; keep in sync by hand.
157
+ */
158
+ interface SandboxCost {
159
+ rate: {
160
+ usd: number;
161
+ unit: string;
162
+ } | null;
163
+ runtimeSeconds: number;
164
+ costUsd: number | null;
165
+ settled: boolean;
166
+ }
167
+ /** `toSummary` — one row of GET /api/v1/sandboxes. */
168
+ interface SandboxSummary {
169
+ id: string;
170
+ label: string | null;
171
+ provider: string | null;
172
+ providerSandboxId: string | null;
173
+ status: 'creating' | 'running' | 'destroyed' | string;
174
+ placementAttempts: unknown[];
175
+ commandCount: number;
176
+ secrets: string[];
177
+ /** The `boot.image` asked for, and what the provider actually booted. */
178
+ requestedImage: string | null;
179
+ image: string | null;
180
+ createdAt: string;
181
+ lastCommandAt: string | null;
182
+ destroyedAt: string | null;
183
+ destroyError: string | null;
184
+ /** The sandbox's configured timeout, when one was set at create. */
185
+ timeoutMs: number | null;
186
+ /** How the sandbox was placed — source, order type, rate, max price, the
187
+ * requested platform `size` and the seller's `box` on a market fill. */
188
+ placement: {
189
+ source: 'market' | 'own-key';
190
+ size?: string | null;
191
+ box?: {
192
+ provider: string;
193
+ sizeName: string | null;
194
+ resources?: {
195
+ cpus: number | null;
196
+ memoryMb: number | null;
197
+ ephemeralDiskMb: number | null;
198
+ };
199
+ };
200
+ orderType?: 'market' | 'limit';
201
+ rate: {
202
+ usd: number;
203
+ per: string;
204
+ };
205
+ maxPrice?: {
206
+ usd: number;
207
+ per: string;
208
+ };
209
+ } | null;
210
+ cost: SandboxCost;
211
+ }
212
+ /** `toDetail` — POST /sandboxes and GET /sandboxes/{id}. */
213
+ interface SandboxDetail extends SandboxSummary {
214
+ /** BYOK direct-attach descriptor — null on market fills and ambient providers. */
215
+ attach: {
216
+ provider: string;
217
+ providerSandboxId: string;
218
+ region: string | null;
219
+ } | null;
220
+ }
221
+ interface SandboxProcess {
222
+ id: string;
223
+ jobId: string;
224
+ pid: number | null;
225
+ command: string;
226
+ cwd: string | null;
227
+ envNames: string[];
228
+ /** Whether the job's stdin pipe is open (spawn `--stdin`). */
229
+ stdin: boolean;
230
+ status: string;
231
+ exitCode: number | null;
232
+ signal: string | null;
233
+ startedAt: string;
234
+ exitedAt: string | null;
235
+ }
236
+ interface SandboxProcessStatus extends SandboxProcess {
237
+ stdout: string;
238
+ stderr: string;
239
+ }
240
+ /** The commands route's JSON (non-SSE) result. */
241
+ interface CommandResult {
242
+ commandId: string;
243
+ exitCode: number;
244
+ durationMs: number;
245
+ stdout: string;
246
+ stderr: string;
247
+ }
248
+ interface FileEntry {
249
+ name: string;
250
+ type: 'file' | 'directory';
251
+ size?: number;
252
+ modified?: string;
253
+ }
254
+ type PathView = {
255
+ path: string;
256
+ type: 'file';
257
+ content: string;
258
+ } | {
259
+ path: string;
260
+ type: 'directory';
261
+ entries: FileEntry[];
262
+ };
263
+ /** `snapshotView` — one row of GET /sandboxes/{id}/snapshots. */
264
+ interface SandboxSnapshot {
265
+ id: string;
266
+ sandboxId: string;
267
+ provider: string;
268
+ region: string | null;
269
+ providerSnapshotId: string;
270
+ label: string | null;
271
+ expiresAt: string | null;
272
+ createdAt: string;
273
+ deletedAt: string | null;
274
+ }
275
+
276
+ type PlatformSize = 'small' | 'medium' | 'large' | 'xlarge';
277
+ interface PlatformConfig {
278
+ /** An org API key or an OAuth access token; both are sent as Bearer. */
279
+ apiKey?: string;
280
+ /** baseUrl > COMPUTE_PLATFORM_URL > BENCHMARKS_PLATFORM_URL > the default host. */
281
+ baseUrl?: string;
282
+ /** Org slug, sent as X-Org-Slug (also COMPUTE_ORG); ignored for org API keys. */
283
+ org?: string;
284
+ /** Send credentials to a host outside computesdk.com/loopback. */
285
+ allowUntrustedHost?: boolean;
286
+ /** Applied to every create unless the call overrides it. */
287
+ defaults?: {
288
+ size?: PlatformSize;
289
+ maxPrice?: {
290
+ usd: number;
291
+ per: 'second' | 'minute' | 'hour';
292
+ };
293
+ orderType?: 'market' | 'limit';
294
+ providerOrder?: string[];
295
+ };
296
+ /** fetch override, for tests and proxies. */
297
+ fetch?: typeof fetch;
298
+ }
299
+ /** Platform-specific create options, alongside the universal ones. */
300
+ interface PlatformCreateOptions extends CreateInstanceOptions {
301
+ size?: PlatformSize;
302
+ maxPrice?: {
303
+ usd: number;
304
+ per: 'second' | 'minute' | 'hour';
305
+ };
306
+ orderType?: 'market' | 'limit';
307
+ providerOrder?: string[];
308
+ /** Org vault secret names to inject, up to 100. */
309
+ secrets?: string[];
310
+ /** Disk v1: `{ diskId, path, readonly?, branch? }`; diskId must be under `<orgSlug>/`. */
311
+ disk?: {
312
+ diskId: string;
313
+ path: string;
314
+ readonly?: boolean;
315
+ branch?: string;
316
+ };
317
+ /** Sandbox label (falls back to universal `name`); max 200 characters. */
318
+ label?: string;
319
+ /** Makes the create safe to replay across process restarts. */
320
+ idempotencyKey?: string;
321
+ }
322
+ /** What the SDK's instance handle carries through to every method call. */
323
+ interface PlatformInstance {
324
+ id: string;
325
+ detail: SandboxDetail;
326
+ client: PlatformClient;
327
+ /** envs passed at create — merged under each command's env. */
328
+ envs: Record<string, string>;
329
+ /** The create's `timeout` — getInfo fallback when `summary.timeoutMs` is null. */
330
+ createTimeout?: number;
331
+ }
332
+ declare const platform: (config: PlatformConfig) => _computesdk_provider.Provider<PlatformInstance, any, any, _computesdk_provider.Volume>;
333
+
334
+ export { type CommandResult, DEFAULT_BASE_URL, type FileEntry, MARKET_CODES, type PathView, PlatformApiError, type PlatformApiErrorCode, type PlatformAuth, PlatformClient, PlatformClientError, type PlatformClientErrorCode, type PlatformConfig, type PlatformCreateOptions, type PlatformErrorEnvelope, type PlatformSize, type RequestOpts, type SandboxCost, type SandboxDetail, type SandboxProcess, type SandboxProcessStatus, type SandboxSnapshot, type SandboxSummary, type StoredPlatformAuth, type StoredPlatformAuthResolver, codeForStatus, errorDetails, isSecurePlatformTransport, isTrustedPlatformHost, platform, readSseEvents, readSseNamedEvents, resolvePlatformAuth, toErrorEnvelope };