@promigence/sdk 0.1.0-beta.4 → 0.1.0-beta.6

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.
@@ -359,7 +359,10 @@ export interface BuildJoined {
359
359
  */
360
360
  source: unknown;
361
361
  /**
362
- * `queued` | `running` | `verified` | `rejected` | `failed`.
362
+ * `queued` | `running` | `verified` | `built` | `rejected` | `failed`. `built` is a
363
+ * finished build that stored its snapshot with no verification command to run (an image
364
+ * built without `verify`): done and ready to start, like `verified`, but nothing was
365
+ * verified.
363
366
  */
364
367
  state: string;
365
368
  tier: string;
@@ -371,8 +374,8 @@ export interface BuildJoined {
371
374
  /**
372
375
  * True when the build finished `verified` and its verification command passed. False while
373
376
  * it is queued or running, when it failed or was rejected, and for an image built without
374
- * `verify` (stored, but nothing was verified). Nothing is stored and nothing is charged if
375
- * the command exits non-zero.
377
+ * `verify` (state `built`: stored, but nothing was verified). Nothing is stored and nothing
378
+ * is charged if the command exits non-zero.
376
379
  */
377
380
  verified: boolean;
378
381
  /**
@@ -402,7 +405,8 @@ export interface BuildLogView {
402
405
  */
403
406
  log: Array<string>;
404
407
  /**
405
- * `queued` | `running` | `verified` | `rejected` | `failed`.
408
+ * `queued` | `running` | `verified` | `built` | `rejected` | `failed` (`built`: stored with
409
+ * no verification command to run).
406
410
  */
407
411
  state: string;
408
412
  }
@@ -506,7 +510,10 @@ export interface BuildView {
506
510
  */
507
511
  source: unknown;
508
512
  /**
509
- * `queued` | `running` | `verified` | `rejected` | `failed`.
513
+ * `queued` | `running` | `verified` | `built` | `rejected` | `failed`. `built` is a
514
+ * finished build that stored its snapshot with no verification command to run (an image
515
+ * built without `verify`): done and ready to start, like `verified`, but nothing was
516
+ * verified.
510
517
  */
511
518
  state: string;
512
519
  tier: string;
@@ -518,8 +525,8 @@ export interface BuildView {
518
525
  /**
519
526
  * True when the build finished `verified` and its verification command passed. False while
520
527
  * it is queued or running, when it failed or was rejected, and for an image built without
521
- * `verify` (stored, but nothing was verified). Nothing is stored and nothing is charged if
522
- * the command exits non-zero.
528
+ * `verify` (state `built`: stored, but nothing was verified). Nothing is stored and nothing
529
+ * is charged if the command exits non-zero.
523
530
  */
524
531
  verified: boolean;
525
532
  /**
@@ -821,6 +828,68 @@ export interface CliTokenCreate {
821
828
  export type Code = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "capacity_busy" | "verify_did_not_cover" | "nonzero_exit" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "cap_killed" | "cap_exceeded" | "aborted_by_client" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "enoent" | "trial_credits_exhausted" | "card_required" | "concurrency_limit" | "egress_cap_reached" | "network_policy_unsupported" | "network_host_refused" | "toolchain_mismatch" | "resume_unavailable" | "sandbox_unreachable" | "region_at_capacity" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "builder_unavailable" | "builder_busy" | "overloaded" | "preempted" | "grader_failed" | "grade_not_passed" | "shutdown_by_task" | "modified_by_task" | "cap_paused" | "credits_paused" | "forbidden" | "snapshot_incompatible" | "storage_limit_reached" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "credit_unclaimed" | "billing_unavailable" | "project_cap_reached" | "spend_limit_reached" | "tier_over_plan" | "secrets_in_snapshot" | "secrets_unavailable" | "secret_binding_unsupported" | "idempotency_key_reused" | "idempotency_key_in_use" | "repo_credentials_not_supported" | "account_exists" | "invite_invalid" | "invite_required" | "key_expired";
822
829
  export interface Concurrency {
823
830
  }
831
+ /**
832
+ * One request to connect a code host (`github` or `gitlab`) to the organization, started by the
833
+ * person whose key or console session asked for it, and how it ended.
834
+ */
835
+ export interface ConnectRequest {
836
+ /**
837
+ * The account on the code host, once it is known.
838
+ */
839
+ account?: string | null;
840
+ /**
841
+ * RFC 3339.
842
+ */
843
+ created_at: string;
844
+ /**
845
+ * RFC 3339: when it ended; absent while it is pending.
846
+ */
847
+ finished_at?: string | null;
848
+ /**
849
+ * One or two sentences for a person: what happened, then what to do next.
850
+ */
851
+ message: string;
852
+ /**
853
+ * `github` or `gitlab`.
854
+ */
855
+ provider: string;
856
+ /**
857
+ * `icr_` and 32 hex digits.
858
+ */
859
+ request_id: string;
860
+ /**
861
+ * `pending` while it is not finished; then how it ended: `connected`, `updated` (already
862
+ * connected to this organization; its repository access changed), `already_connected`,
863
+ * `pending_provider_approval` (an owner of the account must approve it on the code host
864
+ * first), `declined`, `other_org` (connected to another organization), `needs_admin`,
865
+ * `not_installer`, `wrong_user` (the connection page was opened signed in to another
866
+ * account), `expired` or `failed`.
867
+ */
868
+ state: string;
869
+ }
870
+ /**
871
+ * `POST /v1/integrations/{github,gitlab}/requests`: a connection started for you in the console.
872
+ * Open `connect_url` in a browser signed in to the console as you, then read
873
+ * `GET /v1/integrations/{github,gitlab}/requests/{request_id}` for how it ends.
874
+ */
875
+ export interface ConnectTicket {
876
+ /**
877
+ * The console page that starts the connection: it carries the ticket and nothing else.
878
+ */
879
+ connect_url: string;
880
+ /**
881
+ * When the ticket stops working (RFC 3339): 5 minutes.
882
+ */
883
+ expires_at: string;
884
+ /**
885
+ * The connection request it starts (`icr_` and 32 hex digits).
886
+ */
887
+ request_id: string;
888
+ /**
889
+ * `ict_` and 32 hex digits: used once, by you only, within 5 minutes.
890
+ */
891
+ ticket_id: string;
892
+ }
824
893
  export interface Cost {
825
894
  /**
826
895
  * Σ `billable_seconds` over the run's sandboxes.
@@ -1436,7 +1505,8 @@ export interface FileWritten {
1436
1505
  */
1437
1506
  chunks: number;
1438
1507
  /**
1439
- * The file's permission bits, octal (`644`).
1508
+ * The file's permission bits after the write, octal (`644`). Without `?mode=` a file that
1509
+ * already existed keeps its own, and a new file is `644`.
1440
1510
  */
1441
1511
  mode: string;
1442
1512
  /**
@@ -2105,7 +2175,9 @@ export interface InviteView {
2105
2175
  */
2106
2176
  export interface KeyCreate {
2107
2177
  /**
2108
- * `full` (the default) | `run` (use sandboxes, nothing else) | `read` (lists and reports).
2178
+ * `full` (the default) | `run` (sandboxes, runs and builds, whose runs can use the project's
2179
+ * stored secrets; no changes to secrets, keys or billing) | `read` (reads everything in the
2180
+ * project, file contents and command output included; changes nothing).
2109
2181
  */
2110
2182
  access?: string | null;
2111
2183
  /**
@@ -2166,7 +2238,9 @@ export interface KeyRef {
2166
2238
  */
2167
2239
  export interface KeyView {
2168
2240
  /**
2169
- * What the key may do: `full`, `run` (use sandboxes) or `read` (lists and reports).
2241
+ * What the key may do: `full`, `run` (sandboxes, runs and builds, whose runs can use the
2242
+ * project's stored secrets; no changes to secrets, keys or billing) or `read` (reads
2243
+ * everything in the project, file contents and command output included; changes nothing).
2170
2244
  */
2171
2245
  access?: string;
2172
2246
  /**
@@ -2354,8 +2428,8 @@ export interface Me {
2354
2428
  */
2355
2429
  location?: string | null;
2356
2430
  /**
2357
- * The same place as a short code for an icon: `us-east`, `us-west`, `us-midwest`, `eu-west` or
2358
- * `india`. Only beside `location`; a code you do not know is fine to ignore.
2431
+ * The same place as a short code, for example `us-east`. Only beside `location`; new codes may
2432
+ * appear, and a code you do not know is fine to ignore.
2359
2433
  */
2360
2434
  location_code?: string | null;
2361
2435
  /**
@@ -2540,7 +2614,9 @@ export interface OrgDeleted {
2540
2614
  */
2541
2615
  export interface OrgKeyCreate {
2542
2616
  /**
2543
- * `full` (the default) | `run` (use sandboxes, nothing else) | `read` (lists and reports).
2617
+ * `full` (the default) | `run` (sandboxes, runs and builds, whose runs can use the project's
2618
+ * stored secrets; no changes to secrets, keys or billing) | `read` (reads everything in the
2619
+ * project, file contents and command output included; changes nothing).
2544
2620
  */
2545
2621
  access?: string | null;
2546
2622
  /**
@@ -2577,7 +2653,9 @@ export interface OrgKeyCreate {
2577
2653
  */
2578
2654
  export interface OrgKeyView {
2579
2655
  /**
2580
- * What the key may do: `full`, `run` (use sandboxes) or `read` (lists and reports).
2656
+ * What the key may do: `full`, `run` (sandboxes, runs and builds, whose runs can use the
2657
+ * project's stored secrets; no changes to secrets, keys or billing) or `read` (reads
2658
+ * everything in the project, file contents and command output included; changes nothing).
2581
2659
  */
2582
2660
  access?: string;
2583
2661
  /**
@@ -3423,7 +3501,7 @@ export interface Run {
3423
3501
  */
3424
3502
  export interface RunCanceled {
3425
3503
  /**
3426
- * How many queued sandboxes were dropped. They were never started and are never billed.
3504
+ * How many queued sandboxes were dropped. They were never started, so they are not billed.
3427
3505
  */
3428
3506
  canceled: number;
3429
3507
  ok: boolean;
@@ -4642,13 +4720,13 @@ export interface SecretStored {
4642
4720
  */
4643
4721
  next: Array<string>;
4644
4722
  /**
4645
- * What a sandbox that names this secret is given in its place: it works in requests to the
4646
- * bound hosts and nowhere else. Present when `hosts` is.
4723
+ * What the variable holds, in place of the value, in a sandbox that names this secret.
4724
+ * Present when `hosts` is.
4647
4725
  */
4648
4726
  placeholder?: string | null;
4649
4727
  /**
4650
- * `refused` when the value itself can never be given to a sandbox, `allowed` otherwise.
4651
- * Present when `hosts` is.
4728
+ * `refused` when the value itself can never be given to a sandbox, `allowed` (the default)
4729
+ * otherwise. Present when `hosts` is.
4652
4730
  */
4653
4731
  raw?: string | null;
4654
4732
  /**
@@ -4656,11 +4734,10 @@ export interface SecretStored {
4656
4734
  */
4657
4735
  updated_at: string;
4658
4736
  /**
4659
- * For each of `hosts`, in the same order, the address a sandbox sends its requests to,
4660
- * with the request's path added after it. Requests sent there are authenticated with the
4661
- * secret; a request made straight to the host (`https://<host>/…`)
4662
- * carries the placeholder, and the host refuses it. For a `*.` host, put the name
4663
- * in place of the `*`. Present when `hosts` is.
4737
+ * For each of `hosts`, in the same order, the address a sandbox sends that host's requests
4738
+ * to, with the request's path added after it. Requests sent there are authenticated with the
4739
+ * secret; a request sent straight to the host is not. For a `*.` host, put the name in place
4740
+ * of the `*`. Present when `hosts` is.
4664
4741
  */
4665
4742
  urls?: Array<string>;
4666
4743
  }
@@ -4687,14 +4764,15 @@ export interface SecretSummary {
4687
4764
  headers?: Array<string>;
4688
4765
  /**
4689
4766
  * The hosts the secret is bound to. Absent when it is not bound: a sandbox that names it is
4690
- * then given the value itself. When present, a sandbox is given a placeholder instead,
4691
- * which works in requests to these hosts and nowhere else.
4767
+ * then given the value itself. When present, requests to these hosts sent through `urls`
4768
+ * are authenticated with it, and the value stays out of the sandbox unless a run asks for
4769
+ * it and `raw` allows it.
4692
4770
  */
4693
4771
  hosts?: Array<string>;
4694
4772
  name: string;
4695
4773
  /**
4696
- * `refused` when the value itself can never be given to a sandbox, `allowed` otherwise.
4697
- * Present when `hosts` is.
4774
+ * `refused` when the value itself can never be given to a sandbox, `allowed` (the default)
4775
+ * otherwise. Present when `hosts` is.
4698
4776
  */
4699
4777
  raw?: string | null;
4700
4778
  /**
@@ -4726,8 +4804,9 @@ export interface SecretUseBound {
4726
4804
  */
4727
4805
  as?: string | null;
4728
4806
  /**
4729
- * `raw` delivers the value itself to a secret bound to hosts; omitted, such a secret is
4730
- * delivered as a placeholder that only works toward its hosts.
4807
+ * `raw` gives the command the value itself of a secret bound to hosts (refused when the
4808
+ * secret's `raw` is `refused`); omitted, the value stays out of the sandbox and requests to
4809
+ * its hosts sent through its `urls` are authenticated with it.
4731
4810
  */
4732
4811
  mode?: SecretUseMode | null;
4733
4812
  /**
@@ -4867,6 +4946,14 @@ export interface SnapshotCreate {
4867
4946
  * Build from a Dockerfile.
4868
4947
  */
4869
4948
  dockerfile?: DockerfileSource | null;
4949
+ /**
4950
+ * Image and Dockerfile forms: environment variables for every command, terminal and SSH
4951
+ * session in sandboxes from this snapshot (and for its own `setup`, `verify` and `start`),
4952
+ * set over the image's own `ENV` as `docker run -e` sets them. A value may build on a
4953
+ * variable the image sets with `${containerEnv:NAME}`, or `${containerEnv:NAME:default}`
4954
+ * when the image may not set it: `"PATH": "${containerEnv:PATH}:/opt/tools/bin"`.
4955
+ */
4956
+ env?: Record<string, string>;
4870
4957
  /**
4871
4958
  * `github:` repositories: the snapshot the build starts from, by id or alias. Default
4872
4959
  * `promigence/base`.
@@ -4998,7 +5085,7 @@ export interface SnapshotDeduped {
4998
5085
  */
4999
5086
  source: unknown;
5000
5087
  /**
5001
- * `verified`.
5088
+ * `verified`, or `built` when the snapshot was stored with no verification command to run.
5002
5089
  */
5003
5090
  state: string;
5004
5091
  /**
package/dist/proxy.d.ts CHANGED
@@ -1,3 +1,16 @@
1
+ /**
2
+ * `HTTPS_PROXY` / `HTTP_PROXY` / `ALL_PROXY` / `NO_PROXY` for the SDK and the CLI.
3
+ *
4
+ * Node's built-in `fetch` ignores the proxy variables (Node 22 has no `NODE_USE_ENV_PROXY`), so
5
+ * behind a corporate proxy the CLI could not reach the API while the Python SDK, which honours
6
+ * them, could. This is a small `fetch` over `node:http`/`node:https` that goes through the proxy
7
+ * the environment names: an `http://` URL is sent to the proxy in absolute form, an `https://` URL
8
+ * through a `CONNECT` tunnel with TLS to the API inside it (the proxy never sees the key). It is
9
+ * used only when a proxy variable applies to the API's host; otherwise nothing changes.
10
+ *
11
+ * No dependency: the proxy agents live in the `undici` package, which this SDK does not ship.
12
+ */
13
+ import { type ClientRequest, type RequestOptions } from "node:http";
1
14
  type FetchLike = typeof globalThis.fetch;
2
15
  /** Does `NO_PROXY` exempt `host` (`*`, an exact name, a `.suffix` or `suffix`, with an optional port)? */
3
16
  export declare function noProxy(host: string, port: string, env?: NodeJS.ProcessEnv): boolean;
@@ -8,4 +21,11 @@ export declare function proxyFor(url: string, env?: NodeJS.ProcessEnv): URL | un
8
21
  * sends JSON and file chunks of at most 16 MiB); response bodies stream.
9
22
  */
10
23
  export declare function proxyFetch(proxy: URL): FetchLike;
24
+ /**
25
+ * `node:http(s).request(url, options)`, through the proxy the environment names for `url` when one
26
+ * applies ([`proxyFor`]): an https URL over a `CONNECT` tunnel with TLS to the server inside it
27
+ * (the proxy never sees what is sent), an http URL in absolute form. For what `fetch` cannot
28
+ * carry: the terminal's and the SSH tunnel's WebSocket upgrades. With no proxy, the plain request.
29
+ */
30
+ export declare function requestVia(url: URL, options: RequestOptions, env?: NodeJS.ProcessEnv): ClientRequest;
11
31
  export {};
package/dist/proxy.js CHANGED
@@ -169,3 +169,38 @@ export function proxyFetch(proxy) {
169
169
  };
170
170
  return fetchViaProxy;
171
171
  }
172
+ export function requestVia(url, options, env = process.env) {
173
+ const proxy = proxyFor(url.href, env);
174
+ if (!proxy)
175
+ return (url.protocol === "https:" ? httpsRequest : httpRequest)(url, options);
176
+ const proxyRequest = proxy.protocol === "https:" ? httpsRequest : httpRequest;
177
+ const proxyPort = Number(proxy.port || (proxy.protocol === "https:" ? 443 : 80));
178
+ if (url.protocol === "http:") {
179
+ return proxyRequest({
180
+ ...options, host: proxy.hostname, port: proxyPort, path: url.href,
181
+ headers: { ...options.headers, host: url.host, ...proxyAuth(proxy) },
182
+ });
183
+ }
184
+ const port = Number(url.port || 443);
185
+ const createConnection = (_opts, done) => {
186
+ const connect = proxyRequest({
187
+ host: proxy.hostname, port: proxyPort, method: "CONNECT", path: `${url.hostname}:${port}`,
188
+ headers: { host: `${url.hostname}:${port}`, ...proxyAuth(proxy) },
189
+ });
190
+ connect.on("error", (e) => done(e));
191
+ connect.on("connect", (res, socket) => {
192
+ if (res.statusCode !== 200) {
193
+ socket.destroy();
194
+ done(new Error(`the proxy ${proxy.host} refused CONNECT ${url.host} (HTTP ${res.statusCode})`));
195
+ return;
196
+ }
197
+ done(null, tlsConnect({ socket, servername: url.hostname, ALPNProtocols: ["http/1.1"] }));
198
+ });
199
+ connect.end();
200
+ return undefined;
201
+ };
202
+ return httpsRequest(url, {
203
+ ...options,
204
+ createConnection: createConnection,
205
+ });
206
+ }
package/dist/pty.js CHANGED
@@ -1,7 +1,6 @@
1
1
  import { createHash, randomBytes } from "node:crypto";
2
- import { request as httpRequest } from "node:http";
3
- import { request as httpsRequest } from "node:https";
4
2
  import { CALLER_HEADER } from "./caller.js";
3
+ import { requestVia } from "./proxy.js";
5
4
  export const PTY_INPUT_CHUNK = 64 * 1024;
6
5
  const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
7
6
  export const PTY_COMMAND_HEADER = "promigence-pty-command";
@@ -143,7 +142,7 @@ export class PtySession {
143
142
  export function connectPty(opts) {
144
143
  const url = new URL(opts.url);
145
144
  const key = randomBytes(16).toString("base64");
146
- const req = (url.protocol === "https:" ? httpsRequest : httpRequest)(url, {
145
+ const req = requestVia(url, {
147
146
  method: "GET",
148
147
  headers: {
149
148
  connection: "Upgrade",
package/dist/sandbox.d.ts CHANGED
@@ -224,9 +224,10 @@ interface SandboxInit {
224
224
  timeoutMs?: number;
225
225
  }
226
226
  /**
227
- * The snapshot `Sandbox.create()` forks when it is given none: Debian 12 + Python 3.12, node/npm,
228
- * git, curl, jq, gcc/make, `small` tier (built in, not verified). It is always ready to start. The template
229
- * name `'base'` means the same thing.
227
+ * The snapshot `Sandbox.create()` forks when it is given none: Debian 12 + Python 3.12 (pip, venv, uv),
228
+ * Node 24 (npm), Bun, Go 1.27, Docker, git, Git LFS, the GitHub CLI, curl, jq, ripgrep, rsync, gcc/make,
229
+ * and the Claude Code, Codex, Gemini CLI and OpenCode agents, `small` tier (built in, not verified). It
230
+ * is always ready to start. The template name `'base'` means the same thing.
230
231
  */
231
232
  export declare const DEFAULT_SNAPSHOT = "promigence/base";
232
233
  /**
@@ -297,8 +298,14 @@ export declare class Sandbox {
297
298
  read(path: string, opts: {
298
299
  format: "bytes";
299
300
  }): Promise<Uint8Array>;
300
- /** Text is written as UTF-8; bytes as they are (a typed array, an `ArrayBuffer` or a `Blob`). */
301
- write(path: string, data: string | Uint8Array | ArrayBuffer | ArrayBufferView | Blob): Promise<void>;
301
+ /**
302
+ * Text is written as UTF-8; bytes as they are (a typed array, an `ArrayBuffer` or a `Blob`).
303
+ * A file that already exists keeps its mode, as a shell `>` or an editor's save does; a new
304
+ * one is `0o644`. `{ mode: 0o755 }` sets the mode either way.
305
+ */
306
+ write(path: string, data: string | Uint8Array | ArrayBuffer | ArrayBufferView | Blob, opts?: {
307
+ mode?: number;
308
+ }): Promise<void>;
302
309
  remove(path: string, opts?: {
303
310
  recursive?: boolean;
304
311
  }): Promise<void>;
package/dist/sandbox.js CHANGED
@@ -59,7 +59,7 @@ export function toEntryInfoFromPath(f) {
59
59
  return toEntryInfo({ ...f, name: at < 0 ? f.path : f.path.slice(at + 1) });
60
60
  }
61
61
  function buildIsFree(b) {
62
- return b.deduped === true || b.joined === true || b.idempotent_replay === true || b.state === "verified";
62
+ return b.deduped === true || b.joined === true || b.idempotent_replay === true || b.state === "verified" || b.state === "built";
63
63
  }
64
64
  function buildNotice(image) {
65
65
  return (b) => {
@@ -350,7 +350,7 @@ export class Sandbox {
350
350
  const bytes = await this.#client.sandboxes.files.get(this.sandboxId, path);
351
351
  return format === "bytes" ? bytes : new TextDecoder().decode(bytes);
352
352
  }),
353
- write: async (path, data) => {
353
+ write: async (path, data, opts = {}) => {
354
354
  let body;
355
355
  if (typeof data === "string" || data instanceof Uint8Array)
356
356
  body = data;
@@ -364,7 +364,7 @@ export class Sandbox {
364
364
  throw new InvalidArgumentError(`files.write data must be a string, a typed array, an ArrayBuffer or a Blob, got ${data === null ? "null" : typeof data}`, "Pass text, or the bytes as a Uint8Array.");
365
365
  }
366
366
  this.dirty = true;
367
- await this.#client.sandboxes.files.put(this.sandboxId, path, body, {});
367
+ await this.#client.sandboxes.files.put(this.sandboxId, path, body, opts.mode === undefined ? {} : { mode: opts.mode });
368
368
  },
369
369
  remove: async (path, opts = {}) => {
370
370
  this.dirty = true;
package/dist/ssh.js CHANGED
@@ -1,12 +1,11 @@
1
- import { request as httpRequest } from "node:http";
2
- import { request as httpsRequest } from "node:https";
3
1
  import { randomBytes } from "node:crypto";
4
2
  import { CALLER_HEADER } from "./caller.js";
3
+ import { requestVia } from "./proxy.js";
5
4
  import { FrameReader, encodeFrame, wsAccept } from "./pty.js";
6
5
  export function connectSshTunnel(opts) {
7
6
  const url = new URL(opts.url);
8
7
  const key = randomBytes(16).toString("base64");
9
- const req = (url.protocol === "https:" ? httpsRequest : httpRequest)(url, {
8
+ const req = requestVia(url, {
10
9
  method: "GET",
11
10
  headers: {
12
11
  connection: "Upgrade",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@promigence/sdk",
3
- "version": "0.1.0-beta.4",
3
+ "version": "0.1.0-beta.6",
4
4
  "description": "The fastest sandboxes for AI agents and code. The Promigence TypeScript SDK: snapshot an environment once, fork it as often as you need, run commands in every copy. A simple Sandbox class and the full PromigenceClient, with zero runtime dependencies.",
5
5
  "license": "Apache-2.0",
6
6
  "homepage": "https://www.promigence.ai",