@promigence/sdk 0.1.0-beta.4 → 0.1.0-beta.5
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/dist/cjs/client.d.ts +40 -47
- package/dist/cjs/client.js +19 -187
- package/dist/cjs/context.d.ts +119 -0
- package/dist/cjs/context.js +598 -0
- package/dist/cjs/core.d.ts +1 -1
- package/dist/cjs/core.js +2 -1
- package/dist/cjs/github.d.ts +27 -0
- package/dist/cjs/index.d.ts +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/models.gen.d.ts +118 -31
- package/dist/cjs/proxy.d.ts +20 -0
- package/dist/cjs/proxy.js +36 -0
- package/dist/cjs/pty.js +2 -3
- package/dist/cjs/sandbox.d.ts +8 -2
- package/dist/cjs/sandbox.js +3 -3
- package/dist/cjs/ssh.js +2 -3
- package/dist/client.d.ts +40 -47
- package/dist/client.js +18 -183
- package/dist/context.d.ts +119 -0
- package/dist/context.js +588 -0
- package/dist/core.d.ts +1 -1
- package/dist/core.js +2 -1
- package/dist/github.d.ts +27 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/models.gen.d.ts +118 -31
- package/dist/proxy.d.ts +20 -0
- package/dist/proxy.js +35 -0
- package/dist/pty.js +2 -3
- package/dist/sandbox.d.ts +8 -2
- package/dist/sandbox.js +3 -3
- package/dist/ssh.js +2 -3
- package/package.json +1 -1
package/dist/cjs/models.gen.d.ts
CHANGED
|
@@ -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
|
|
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
|
|
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` (
|
|
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` (
|
|
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
|
|
2358
|
-
*
|
|
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` (
|
|
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` (
|
|
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
|
|
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
|
|
4646
|
-
*
|
|
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`
|
|
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
|
|
4660
|
-
* with the request's path added after it. Requests sent there are authenticated with the
|
|
4661
|
-
* secret; a request
|
|
4662
|
-
*
|
|
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,
|
|
4691
|
-
*
|
|
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`
|
|
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`
|
|
4730
|
-
*
|
|
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/cjs/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/cjs/proxy.js
CHANGED
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.noProxy = noProxy;
|
|
4
4
|
exports.proxyFor = proxyFor;
|
|
5
5
|
exports.proxyFetch = proxyFetch;
|
|
6
|
+
exports.requestVia = requestVia;
|
|
6
7
|
const node_http_1 = require("node:http");
|
|
7
8
|
const node_https_1 = require("node:https");
|
|
8
9
|
const node_tls_1 = require("node:tls");
|
|
@@ -174,3 +175,38 @@ function proxyFetch(proxy) {
|
|
|
174
175
|
};
|
|
175
176
|
return fetchViaProxy;
|
|
176
177
|
}
|
|
178
|
+
function requestVia(url, options, env = process.env) {
|
|
179
|
+
const proxy = proxyFor(url.href, env);
|
|
180
|
+
if (!proxy)
|
|
181
|
+
return (url.protocol === "https:" ? node_https_1.request : node_http_1.request)(url, options);
|
|
182
|
+
const proxyRequest = proxy.protocol === "https:" ? node_https_1.request : node_http_1.request;
|
|
183
|
+
const proxyPort = Number(proxy.port || (proxy.protocol === "https:" ? 443 : 80));
|
|
184
|
+
if (url.protocol === "http:") {
|
|
185
|
+
return proxyRequest({
|
|
186
|
+
...options, host: proxy.hostname, port: proxyPort, path: url.href,
|
|
187
|
+
headers: { ...options.headers, host: url.host, ...proxyAuth(proxy) },
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
const port = Number(url.port || 443);
|
|
191
|
+
const createConnection = (_opts, done) => {
|
|
192
|
+
const connect = proxyRequest({
|
|
193
|
+
host: proxy.hostname, port: proxyPort, method: "CONNECT", path: `${url.hostname}:${port}`,
|
|
194
|
+
headers: { host: `${url.hostname}:${port}`, ...proxyAuth(proxy) },
|
|
195
|
+
});
|
|
196
|
+
connect.on("error", (e) => done(e));
|
|
197
|
+
connect.on("connect", (res, socket) => {
|
|
198
|
+
if (res.statusCode !== 200) {
|
|
199
|
+
socket.destroy();
|
|
200
|
+
done(new Error(`the proxy ${proxy.host} refused CONNECT ${url.host} (HTTP ${res.statusCode})`));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
done(null, (0, node_tls_1.connect)({ socket, servername: url.hostname, ALPNProtocols: ["http/1.1"] }));
|
|
204
|
+
});
|
|
205
|
+
connect.end();
|
|
206
|
+
return undefined;
|
|
207
|
+
};
|
|
208
|
+
return (0, node_https_1.request)(url, {
|
|
209
|
+
...options,
|
|
210
|
+
createConnection: createConnection,
|
|
211
|
+
});
|
|
212
|
+
}
|
package/dist/cjs/pty.js
CHANGED
|
@@ -5,9 +5,8 @@ exports.wsAccept = wsAccept;
|
|
|
5
5
|
exports.encodeFrame = encodeFrame;
|
|
6
6
|
exports.connectPty = connectPty;
|
|
7
7
|
const node_crypto_1 = require("node:crypto");
|
|
8
|
-
const node_http_1 = require("node:http");
|
|
9
|
-
const node_https_1 = require("node:https");
|
|
10
8
|
const caller_js_1 = require("./caller.js");
|
|
9
|
+
const proxy_js_1 = require("./proxy.js");
|
|
11
10
|
exports.PTY_INPUT_CHUNK = 64 * 1024;
|
|
12
11
|
const WS_GUID = "258EAFA5-E914-47DA-95CA-C5AB0DC85B11";
|
|
13
12
|
exports.PTY_COMMAND_HEADER = "promigence-pty-command";
|
|
@@ -151,7 +150,7 @@ exports.PtySession = PtySession;
|
|
|
151
150
|
function connectPty(opts) {
|
|
152
151
|
const url = new URL(opts.url);
|
|
153
152
|
const key = (0, node_crypto_1.randomBytes)(16).toString("base64");
|
|
154
|
-
const req = (
|
|
153
|
+
const req = (0, proxy_js_1.requestVia)(url, {
|
|
155
154
|
method: "GET",
|
|
156
155
|
headers: {
|
|
157
156
|
connection: "Upgrade",
|
package/dist/cjs/sandbox.d.ts
CHANGED
|
@@ -297,8 +297,14 @@ export declare class Sandbox {
|
|
|
297
297
|
read(path: string, opts: {
|
|
298
298
|
format: "bytes";
|
|
299
299
|
}): Promise<Uint8Array>;
|
|
300
|
-
/**
|
|
301
|
-
|
|
300
|
+
/**
|
|
301
|
+
* Text is written as UTF-8; bytes as they are (a typed array, an `ArrayBuffer` or a `Blob`).
|
|
302
|
+
* A file that already exists keeps its mode, as a shell `>` or an editor's save does; a new
|
|
303
|
+
* one is `0o644`. `{ mode: 0o755 }` sets the mode either way.
|
|
304
|
+
*/
|
|
305
|
+
write(path: string, data: string | Uint8Array | ArrayBuffer | ArrayBufferView | Blob, opts?: {
|
|
306
|
+
mode?: number;
|
|
307
|
+
}): Promise<void>;
|
|
302
308
|
remove(path: string, opts?: {
|
|
303
309
|
recursive?: boolean;
|
|
304
310
|
}): Promise<void>;
|
package/dist/cjs/sandbox.js
CHANGED
|
@@ -69,7 +69,7 @@ function toEntryInfoFromPath(f) {
|
|
|
69
69
|
return toEntryInfo({ ...f, name: at < 0 ? f.path : f.path.slice(at + 1) });
|
|
70
70
|
}
|
|
71
71
|
function buildIsFree(b) {
|
|
72
|
-
return b.deduped === true || b.joined === true || b.idempotent_replay === true || b.state === "verified";
|
|
72
|
+
return b.deduped === true || b.joined === true || b.idempotent_replay === true || b.state === "verified" || b.state === "built";
|
|
73
73
|
}
|
|
74
74
|
function buildNotice(image) {
|
|
75
75
|
return (b) => {
|
|
@@ -360,7 +360,7 @@ class Sandbox {
|
|
|
360
360
|
const bytes = await this.#client.sandboxes.files.get(this.sandboxId, path);
|
|
361
361
|
return format === "bytes" ? bytes : new TextDecoder().decode(bytes);
|
|
362
362
|
}),
|
|
363
|
-
write: async (path, data) => {
|
|
363
|
+
write: async (path, data, opts = {}) => {
|
|
364
364
|
let body;
|
|
365
365
|
if (typeof data === "string" || data instanceof Uint8Array)
|
|
366
366
|
body = data;
|
|
@@ -374,7 +374,7 @@ class Sandbox {
|
|
|
374
374
|
throw new core_js_1.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.");
|
|
375
375
|
}
|
|
376
376
|
this.dirty = true;
|
|
377
|
-
await this.#client.sandboxes.files.put(this.sandboxId, path, body, {});
|
|
377
|
+
await this.#client.sandboxes.files.put(this.sandboxId, path, body, opts.mode === undefined ? {} : { mode: opts.mode });
|
|
378
378
|
},
|
|
379
379
|
remove: async (path, opts = {}) => {
|
|
380
380
|
this.dirty = true;
|
package/dist/cjs/ssh.js
CHANGED
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.connectSshTunnel = connectSshTunnel;
|
|
4
|
-
const node_http_1 = require("node:http");
|
|
5
|
-
const node_https_1 = require("node:https");
|
|
6
4
|
const node_crypto_1 = require("node:crypto");
|
|
7
5
|
const caller_js_1 = require("./caller.js");
|
|
6
|
+
const proxy_js_1 = require("./proxy.js");
|
|
8
7
|
const pty_js_1 = require("./pty.js");
|
|
9
8
|
function connectSshTunnel(opts) {
|
|
10
9
|
const url = new URL(opts.url);
|
|
11
10
|
const key = (0, node_crypto_1.randomBytes)(16).toString("base64");
|
|
12
|
-
const req = (
|
|
11
|
+
const req = (0, proxy_js_1.requestVia)(url, {
|
|
13
12
|
method: "GET",
|
|
14
13
|
headers: {
|
|
15
14
|
connection: "Upgrade",
|
package/dist/client.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { type Bundle } from "./bundle.js";
|
|
|
5
5
|
import { type PtyExit, type PtySession } from "./pty.js";
|
|
6
6
|
import { type SshTunnel } from "./ssh.js";
|
|
7
7
|
import type * as M from "./models.gen.js";
|
|
8
|
-
import { type GithubConnect, type GithubDisconnected, type GithubRepos, type GithubStatus, type GithubUntracked } from "./github.js";
|
|
8
|
+
import { type ConnectRequest, type ConnectTicket, type GithubConnect, type GithubDisconnected, type GithubRepos, type GithubStatus, type GithubUntracked } from "./github.js";
|
|
9
9
|
import { type GitlabConnect, type GitlabDisconnected, type GitlabRepos, type GitlabStatus, type GitlabUntracked } from "./gitlab.js";
|
|
10
10
|
export type FetchLike = typeof globalThis.fetch;
|
|
11
11
|
/**
|
|
@@ -343,7 +343,8 @@ export interface RunReport {
|
|
|
343
343
|
[extra: string]: unknown;
|
|
344
344
|
}
|
|
345
345
|
/** A build of a snapshot (`POST /snapshots`, `GET /snapshots/builds/:id`). */
|
|
346
|
-
|
|
346
|
+
/** `built`: finished and stored with no verification command to run; done, like `verified`. */
|
|
347
|
+
export type BuildState = "queued" | "running" | "verified" | "built" | "rejected" | "failed";
|
|
347
348
|
export interface SecretRecord {
|
|
348
349
|
name: string;
|
|
349
350
|
/** Length of the stored value, so a caller can sanity-check without reading it. */
|
|
@@ -353,9 +354,9 @@ export interface SecretRecord {
|
|
|
353
354
|
updated_at?: string;
|
|
354
355
|
/**
|
|
355
356
|
* The hosts the secret is bound to. Absent when it is not bound: a sandbox that names it is
|
|
356
|
-
* then given the value. When present, the sandbox
|
|
357
|
-
*
|
|
358
|
-
*
|
|
357
|
+
* then given the value. When present, requests the sandbox sends to the host's address in
|
|
358
|
+
* `urls` are authenticated with the secret, a request made straight to `https://<host>/` is not,
|
|
359
|
+
* and the value stays out of the sandbox unless a run asks for it (`raw`).
|
|
359
360
|
*/
|
|
360
361
|
hosts?: string[];
|
|
361
362
|
/**
|
|
@@ -364,7 +365,7 @@ export interface SecretRecord {
|
|
|
364
365
|
*/
|
|
365
366
|
urls?: string[];
|
|
366
367
|
/**
|
|
367
|
-
* The variables a sandbox that names this secret is also given, each
|
|
368
|
+
* The variables a sandbox that names this secret is also given, each set to its host's
|
|
368
369
|
* address in `urls`: `OPENAI_BASE_URL` for `api.openai.com`, `ANTHROPIC_BASE_URL` for
|
|
369
370
|
* `api.anthropic.com`. Absent when there is none. A variable the caller sets itself wins.
|
|
370
371
|
*/
|
|
@@ -379,10 +380,10 @@ export interface SecretRecord {
|
|
|
379
380
|
scan_responses?: boolean;
|
|
380
381
|
}
|
|
381
382
|
/**
|
|
382
|
-
* `secrets.set` options: bind the secret to hosts.
|
|
383
|
-
*
|
|
384
|
-
*
|
|
385
|
-
*
|
|
383
|
+
* `secrets.set` options: bind the secret to hosts. Requests a sandbox sends to the host's address
|
|
384
|
+
* the answer gives in `urls` (and to `$OPENAI_BASE_URL` / `$ANTHROPIC_BASE_URL` for those
|
|
385
|
+
* providers) are authenticated with it, one sent straight to the host is not, and the value stays
|
|
386
|
+
* out of the sandbox unless a run asks for it (`raw: "refused"` forbids that; the default allows it).
|
|
386
387
|
*
|
|
387
388
|
* Every option left out keeps what the secret already has, so setting a bound secret again with
|
|
388
389
|
* a new value (a rotation) keeps its binding. `hosts: []` removes it.
|
|
@@ -1478,8 +1479,8 @@ export interface SandboxNetworkCut {
|
|
|
1478
1479
|
* secrets: ["OPENAI_API_KEY", { name: "work_secret_7", as: "ANTHROPIC_WORK_SECRET" }]
|
|
1479
1480
|
* ```
|
|
1480
1481
|
*
|
|
1481
|
-
* A secret bound to hosts (`secrets.set(name, value, { hosts })`)
|
|
1482
|
-
* `mode: "raw"` asks for the value itself, and is refused for one stored with `raw: "refused"`.
|
|
1482
|
+
* A secret bound to hosts (`secrets.set(name, value, { hosts })`) does not put its value in the
|
|
1483
|
+
* sandbox; `mode: "raw"` asks for the value itself, and is refused for one stored with `raw: "refused"`.
|
|
1483
1484
|
*/
|
|
1484
1485
|
export type SecretBinding = string | {
|
|
1485
1486
|
name: string;
|
|
@@ -1649,6 +1650,14 @@ export interface SnapshotCreateOpts {
|
|
|
1649
1650
|
verify?: VerifySpec;
|
|
1650
1651
|
/** Image forms: a background process started before the snapshot, so forks inherit it running. */
|
|
1651
1652
|
start?: string | string[];
|
|
1653
|
+
/**
|
|
1654
|
+
* Image and Dockerfile forms: environment variables for every command, terminal and SSH
|
|
1655
|
+
* session in this snapshot's sandboxes (and its own setup, verify and start), set over the
|
|
1656
|
+
* image's `ENV` as `docker run -e` sets them. A value may build on what the image sets with
|
|
1657
|
+
* `${containerEnv:NAME}` (or `${containerEnv:NAME:default}`):
|
|
1658
|
+
* `{ PATH: "${containerEnv:PATH}:/opt/tools/bin" }`.
|
|
1659
|
+
*/
|
|
1660
|
+
env?: Record<string, string>;
|
|
1652
1661
|
tier?: Tier;
|
|
1653
1662
|
/** Image forms: the name of a stored secret holding the registry credentials. */
|
|
1654
1663
|
registrySecret?: string;
|
|
@@ -1772,28 +1781,6 @@ export declare function imageRefNamesVersion(image: string): boolean;
|
|
|
1772
1781
|
export declare function checkImageVersioned(image: string): void;
|
|
1773
1782
|
/** A git context, pinned: `https://github.com/org/app@<40 hex>`. A branch is not a pin. */
|
|
1774
1783
|
export declare const CONTEXT_GIT_RE: RegExp;
|
|
1775
|
-
/** The prefix a packed directory travels under. */
|
|
1776
|
-
export declare const CONTEXT_TAR_PREFIX = "tar;base64,";
|
|
1777
|
-
/**
|
|
1778
|
-
* Directories never worth sending. `.dockerignore` is **not** applied to a context that fits: it
|
|
1779
|
-
* is sent with the context and the build applies it, so honouring it twice could only disagree
|
|
1780
|
-
* with the build. The cost is that editing an ignored file still changes the snapshot's
|
|
1781
|
-
* identity, which is the safe direction to be wrong in. Only a context over the limit — one that
|
|
1782
|
-
* would be refused anyway — is packed again without what its `.dockerignore` excludes.
|
|
1783
|
-
*/
|
|
1784
|
-
export declare const CONTEXT_SKIP: Set<string>;
|
|
1785
|
-
/**
|
|
1786
|
-
* A `.dockerignore`, as the build reads it: one pattern a line, `#` comments, `!` re-includes,
|
|
1787
|
-
* Go `filepath.Match` syntax plus `**`, anchored at the context root, and a pattern that matches a
|
|
1788
|
-
* directory matches everything under it. The last pattern that matches a path decides. Returns
|
|
1789
|
-
* `undefined` for a file with no patterns.
|
|
1790
|
-
*/
|
|
1791
|
-
export declare function dockerignoreMatcher(text: string): {
|
|
1792
|
-
ignored: (rel: string) => boolean;
|
|
1793
|
-
exceptions: boolean;
|
|
1794
|
-
} | undefined;
|
|
1795
|
-
/** The server's limit, refused here so a 9 MB context does not cross the wire to be told no. */
|
|
1796
|
-
export declare const CONTEXT_MAX_BYTES: number;
|
|
1797
1784
|
/**
|
|
1798
1785
|
* What in a repository URL can carry a credential: a user name, password or token (`https://TOKEN@…`,
|
|
1799
1786
|
* `https://user:pass@…`, `:token@`, a percent-encoded `@`, any `@` in a scheme URL, the scp form's
|
|
@@ -1813,19 +1800,6 @@ export declare const REPO_CREDENTIALS_FIX: string;
|
|
|
1813
1800
|
export declare function checkRepoUrl(url: unknown, field: string): void;
|
|
1814
1801
|
/** Refuse a context that is neither a pinned git URL nor a packed directory. */
|
|
1815
1802
|
export declare function checkDockerfileContext(context: unknown): asserts context is string;
|
|
1816
|
-
/**
|
|
1817
|
-
* Pack a directory into the string `dockerfile.context` takes.
|
|
1818
|
-
*
|
|
1819
|
-
* The archive is only transport: the snapshot's identity is computed from the *entries* server
|
|
1820
|
-
* side, so this does not have to agree byte-for-byte with `sdk-py`'s packer — and two calls on
|
|
1821
|
-
* an unchanged directory give the same snapshot either way.
|
|
1822
|
-
*/
|
|
1823
|
-
export declare function packContext(dir: string, opts?: {
|
|
1824
|
-
maxBytes?: number;
|
|
1825
|
-
keep?: readonly string[];
|
|
1826
|
-
}): string;
|
|
1827
|
-
/** The Dockerfile's path as the context sees it, for `dockerfile.path`. */
|
|
1828
|
-
export declare function contextRelative(contextDir: string, dockerfilePath: string): string;
|
|
1829
1803
|
/**
|
|
1830
1804
|
* The `POST /snapshots` body for one of its three forms; throws `InvalidArgumentError` before
|
|
1831
1805
|
* anything is sent. Kept field-for-field with `sdk-py` (`_ops.snapshot_create_body`) so the two
|
|
@@ -2115,6 +2089,14 @@ export declare class PromigenceClient {
|
|
|
2115
2089
|
status: () => Promise<GithubStatus>;
|
|
2116
2090
|
/** `POST /integrations/github/connect` — the install link (15 minutes); open it in a browser. */
|
|
2117
2091
|
connect: () => Promise<GithubConnect>;
|
|
2092
|
+
/**
|
|
2093
|
+
* `POST /integrations/github/requests` — a connection started for you in the console: open
|
|
2094
|
+
* `connect_url` in a browser signed in to the console as you (a 404 means the console cannot start
|
|
2095
|
+
* it here: use `connect()`).
|
|
2096
|
+
*/
|
|
2097
|
+
ticket: () => Promise<ConnectTicket>;
|
|
2098
|
+
/** `GET /integrations/github/requests/:id` — one of your connection requests: `pending`, or how it ended. */
|
|
2099
|
+
request: (requestId: string) => Promise<ConnectRequest>;
|
|
2118
2100
|
/** `DELETE /integrations/github/installations/:id` — nothing is built from that account any more. */
|
|
2119
2101
|
disconnect: (installationId: number | string) => Promise<GithubDisconnected>;
|
|
2120
2102
|
/** `GET /integrations/github/repos` — one page (at most 100) across every connection. */
|
|
@@ -2135,6 +2117,14 @@ export declare class PromigenceClient {
|
|
|
2135
2117
|
status: () => Promise<GitlabStatus>;
|
|
2136
2118
|
/** `POST /integrations/gitlab/connect` — the authorize link (15 minutes); open it in a browser. */
|
|
2137
2119
|
connect: () => Promise<GitlabConnect>;
|
|
2120
|
+
/**
|
|
2121
|
+
* `POST /integrations/gitlab/requests` — a connection started for you in the console: open
|
|
2122
|
+
* `connect_url` in a browser signed in to the console as you (a 404 means the console cannot start
|
|
2123
|
+
* it here: use `connect()`).
|
|
2124
|
+
*/
|
|
2125
|
+
ticket: () => Promise<ConnectTicket>;
|
|
2126
|
+
/** `GET /integrations/gitlab/requests/:id` — one of your connection requests: `pending`, or how it ended. */
|
|
2127
|
+
request: (requestId: string) => Promise<ConnectRequest>;
|
|
2138
2128
|
/** `DELETE /integrations/gitlab/connections/:id` — revoked on GitLab; nothing is built through it any more. */
|
|
2139
2129
|
disconnect: (connectionId: string) => Promise<GitlabDisconnected>;
|
|
2140
2130
|
/** `GET /integrations/gitlab/repos` — one page (at most 100) of one connection's projects. */
|
|
@@ -2636,6 +2626,9 @@ export declare class PromigenceClient {
|
|
|
2636
2626
|
* A failure mid-loop leaves a **prefix** in the sandbox, not a corrupt file, and the
|
|
2637
2627
|
* thrown error carries how far it got (`written` in the error's evidence).
|
|
2638
2628
|
* Re-running the same `put` is safe: chunk 0 truncates.
|
|
2629
|
+
*
|
|
2630
|
+
* `mode` (`0o755`) sets the file's permission bits. Without it a file that already exists
|
|
2631
|
+
* keeps its mode, as a shell `>` does, and a new one is `0o644`.
|
|
2639
2632
|
*/
|
|
2640
2633
|
put: (sandboxId: string, path: string, data: string | Uint8Array, opts?: {
|
|
2641
2634
|
mode?: number;
|