@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.
@@ -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 };