@promigence/sdk 0.1.0-beta.7 → 0.1.0-beta.8

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/README.md CHANGED
@@ -13,8 +13,9 @@ npm i @promigence/sdk
13
13
  ```
14
14
 
15
15
  You need a Promigence account (private beta, by invite). The quickest way to create one is the CLI:
16
- `npm i -g promigence`, then `promigence signup`. The SDK reads the key from `PROMIGENCE_API_KEY` or
17
- from where the CLI stored it: the system keychain, or `~/.config/promigence/credentials`.
16
+ `npm i -g promigence`, then `promigence signup`. The SDK uses the key you pass (`apiKey`) or
17
+ `PROMIGENCE_API_KEY`; with neither, the key the CLI stored: the system keychain, or
18
+ `~/.config/promigence/credentials`. A key you pass or set is used as is; the stored one is not read.
18
19
 
19
20
  ## Use it
20
21
 
@@ -748,6 +748,8 @@ export interface CreditOffer {
748
748
  state: string;
749
749
  credit_usd: number;
750
750
  card_bonus_usd: number;
751
+ /** USD charged to confirm Apple Pay, Google Pay or Amazon Pay when one is added (added to the credit). */
752
+ method_check_usd?: number;
751
753
  expires_at?: string | null;
752
754
  campaign?: string | null;
753
755
  message: string;
@@ -906,6 +908,16 @@ export interface BillingUsage {
906
908
  brand?: string;
907
909
  last4?: string;
908
910
  } | null;
911
+ /** Set when the card on file does not unlock paid limits for this organization (it already pays for another one,
912
+ * it is being confirmed with a $1 charge, or that charge did not go through). */
913
+ card_note?: string | null;
914
+ /** The $1 that confirms Apple Pay, Google Pay or Amazon Pay on file: `confirming`, `paid` or `failed`. */
915
+ method_check?: {
916
+ method: string;
917
+ status: string;
918
+ amount_usd: number;
919
+ bonus_usd?: number | null;
920
+ } | null;
909
921
  suspended?: boolean;
910
922
  suspend_reason?: string | null;
911
923
  period?: {
@@ -929,6 +941,10 @@ export interface BillingUsage {
929
941
  upcoming_invoice_error?: string | null;
930
942
  [extra: string]: unknown;
931
943
  }
944
+ /** One row of `GET /billing/history`: a credit the organization received, or a payment. */
945
+ export type BillingHistoryEntry = M.BillingHistoryEntry;
946
+ /** What `billing.historyPage()` lists: everything, only credits, or only payments. */
947
+ export type BillingHistoryKind = "all" | "credits" | "payments";
932
948
  /** One metered row of `GET /me/ledger`. */
933
949
  export interface LedgerEntry {
934
950
  entry_id: string;
@@ -2033,6 +2049,16 @@ export declare class PromigenceClient {
2033
2049
  limit?: number;
2034
2050
  cursor?: string;
2035
2051
  }) => Promise<Page<LedgerEntry>>;
2052
+ /**
2053
+ * `GET /billing/history` — the credits the organization received and its payments, newest
2054
+ * first (one page). `kind` narrows it to `credits` or `payments`; feed `nextCursor` back as
2055
+ * `cursor` until it is `null`. An owner's key.
2056
+ */
2057
+ historyPage: (opts?: {
2058
+ kind?: BillingHistoryKind;
2059
+ limit?: number;
2060
+ cursor?: string;
2061
+ }) => Promise<Page<BillingHistoryEntry>>;
2036
2062
  /** `POST /billing/checkout` — the hosted page that puts a card on file. */
2037
2063
  checkout: () => Promise<{
2038
2064
  url: string;
@@ -2433,6 +2459,18 @@ export declare class PromigenceClient {
2433
2459
  onData?: (data: Uint8Array) => void;
2434
2460
  onExit?: (exit: PtyExit) => void;
2435
2461
  timeoutMs?: number;
2462
+ /** Pick the same terminal up again when its connection drops or the service is updated;
2463
+ * see `PtyConnectOpts.resume`. Default: on. */
2464
+ resume?: boolean;
2465
+ /** Reconnect in a new shell when the service is updated (a WebSocket `Close` 1012) and the
2466
+ * terminal cannot be picked up again; see `PtyConnectOpts.reconnect`. Default: on without
2467
+ * `cmd`, off with one. */
2468
+ reconnect?: boolean;
2469
+ /** Called after each reconnect: `resumed` says whether it is the same terminal or a new
2470
+ * shell. */
2471
+ onReconnected?: (how: {
2472
+ resumed: boolean;
2473
+ }) => void;
2436
2474
  }) => Promise<PtySession>;
2437
2475
  /** `GET /sandboxes/:id`. */
2438
2476
  get: (sandboxId: string) => Promise<SandboxRecord>;
@@ -168,7 +168,7 @@ function decodeCredentials(buf) {
168
168
  return buf.subarray(3).toString("utf8");
169
169
  return buf.toString("utf8");
170
170
  }
171
- function storedCredentials(env = process.env) {
171
+ function storedCredentials(env = process.env, platform = process.platform) {
172
172
  const path = credentialsPath(env);
173
173
  let present = true;
174
174
  try {
@@ -178,7 +178,7 @@ function storedCredentials(env = process.env) {
178
178
  present = e.code !== "ENOENT";
179
179
  }
180
180
  if (!present) {
181
- const store = (0, credstore_js_1.keychainStore)(env);
181
+ const store = (0, credstore_js_1.keychainStore)(env, platform);
182
182
  if (store === undefined)
183
183
  return undefined;
184
184
  const r = (0, credstore_js_1.keychainReadCached)(store, path, env);
@@ -292,8 +292,6 @@ function keyOrigin(env = process.env) {
292
292
  const stored = readCredentialsWithStore(env);
293
293
  if (stored.creds.api_key)
294
294
  return stored.store === "macos-keychain" ? "macOS Keychain" : stored.store === "secret-service" ? "Secret Service keyring" : "credentials file";
295
- if (compatApiKey(env["E2B_API_KEY"]))
296
- return "E2B_API_KEY (compat)";
297
295
  return undefined;
298
296
  }
299
297
  function resolveCredentials(opts, env = process.env) {
@@ -302,17 +300,19 @@ function resolveCredentials(opts, env = process.env) {
302
300
  const t = u.replace(/\/+$/, "");
303
301
  return /^https?:\/\/[^/?#]+$/i.test(t) ? `${t}/v1` : t;
304
302
  };
305
- const { creds, store } = readCredentialsWithStore(env);
306
303
  const envKey = set(env["PROMIGENCE_API_KEY"]?.trim());
307
304
  const envUrl = set(env["PROMIGENCE_API_URL"]);
308
305
  const optKey = opts.apiKey?.trim();
306
+ const given = optKey !== undefined || envKey !== undefined;
307
+ const { creds, store } = given
308
+ ? { creds: {}, store: undefined }
309
+ : readCredentialsWithStore(env);
309
310
  const source = optKey !== undefined ? "opts" : envKey !== undefined ? "env" : creds.api_key !== undefined ? "file" : undefined;
310
311
  const ours = optKey ?? envKey ?? creds.api_key;
311
- const compat = ours === undefined ? compatApiKey(env["E2B_API_KEY"]) : undefined;
312
- const compatUrl = compat === undefined
313
- ? undefined
314
- : apiUrlFromCompatUrl(env["E2B_API_URL"]) ?? apiUrlFromCompatDomain(env["E2B_DOMAIN"]);
315
- const fromFile = trim(creds.api_url ?? compatUrl ?? core_js_1.DEFAULT_API_URL);
312
+ const fallback = ours === undefined ? opts.fallbackKey : undefined;
313
+ const fallbackKey = set(fallback?.apiKey.trim());
314
+ const fallbackUrl = fallbackKey === undefined ? undefined : set(fallback?.apiUrl);
315
+ const fromFile = trim(creds.api_url ?? fallbackUrl ?? core_js_1.DEFAULT_API_URL);
316
316
  const fromEnv = envUrl !== undefined ? trim(envUrl) : fromFile;
317
317
  const apiUrl = opts.apiUrl !== undefined ? trim(opts.apiUrl) : fromEnv;
318
318
  const paired = source === "file" ? fromFile : source === "env" ? fromEnv : apiUrl;
@@ -324,10 +324,10 @@ function resolveCredentials(opts, env = process.env) {
324
324
  : "Pass apiKey together with apiUrl, or set PROMIGENCE_API_URL to that URL instead of passing apiUrl.");
325
325
  return { apiKey: undefined, apiUrl, refusal };
326
326
  }
327
- const key = ours ?? compat;
327
+ const key = ours ?? fallbackKey;
328
328
  if (key) {
329
329
  const from = source === "opts" ? "the apiKey option" : source === "env" ? "PROMIGENCE_API_KEY"
330
- : source === "file" ? storedName(store, env) : "E2B_API_KEY";
330
+ : source === "file" ? storedName(store, env) : fallback.from;
331
331
  const refusal = keyRefusal(key, from);
332
332
  if (refusal)
333
333
  return { apiKey: undefined, apiUrl, refusal };
@@ -685,6 +685,7 @@ function errorFor(code, message, fix, extra = {}) {
685
685
  case "invalid_argument":
686
686
  return attach(new core_js_1.InvalidArgumentError(message, extra.cli ? fix : withoutCliHelp(fix), code));
687
687
  case "not_released": return attach(new core_js_1.NotReleasedError(message));
688
+ case "service_restart": return attach(new core_js_1.ServiceRestartError(message, fix));
688
689
  default:
689
690
  if (ENV_CODES.has(code) || extra.category === "env")
690
691
  return attach(new core_js_1.EnvFailedError(code, message, fix));
@@ -1291,6 +1292,14 @@ class PromigenceClient {
1291
1292
  const r = await this.request({ method: "GET", path: `/me/ledger?${pageQuery(limit, 1000, opts.cursor)}` });
1292
1293
  return pageOf(r, "entries", limit);
1293
1294
  },
1295
+ historyPage: async (opts = {}) => {
1296
+ const limit = opts.limit ?? 50;
1297
+ const q = new URLSearchParams(pageQuery(limit, 100, opts.cursor));
1298
+ if (opts.kind !== undefined && opts.kind !== "all")
1299
+ q.set("kind", opts.kind);
1300
+ const r = await this.request({ method: "GET", path: `/billing/history?${q.toString()}` });
1301
+ return pageOf(r, "entries", limit);
1302
+ },
1294
1303
  checkout: () => this.request({ method: "POST", path: "/billing/checkout", body: {} }),
1295
1304
  portal: () => this.request({ method: "POST", path: "/billing/portal", body: {} }),
1296
1305
  referrals: () => this.request({ method: "GET", path: "/referrals" }),
@@ -1785,6 +1794,10 @@ class PromigenceClient {
1785
1794
  on.heartbeat?.();
1786
1795
  continue;
1787
1796
  }
1797
+ if (event === "reconnect") {
1798
+ reader.cancel().catch(() => { });
1799
+ throw new core_js_1.ServiceRestartError(`a service restart stopped the command on sandbox ${sandboxId} while its output was streaming`, "Not billed: the time the command ran is credited back. The sandbox kept running; the command may have done part of its work before it stopped: run it again if that is safe.");
1800
+ }
1788
1801
  let parsed = {};
1789
1802
  try {
1790
1803
  parsed = JSON.parse(data);
@@ -2020,6 +2033,9 @@ class PromigenceClient {
2020
2033
  ...(opts.onData ? { onData: opts.onData } : {}),
2021
2034
  ...(opts.onExit ? { onExit: opts.onExit } : {}),
2022
2035
  ...(opts.timeoutMs === undefined ? {} : { timeoutMs: opts.timeoutMs }),
2036
+ ...(opts.resume === undefined ? {} : { resume: opts.resume }),
2037
+ ...(opts.reconnect === undefined ? {} : { reconnect: opts.reconnect }),
2038
+ ...(opts.onReconnected ? { onReconnected: opts.onReconnected } : {}),
2023
2039
  refuse: (status, text, retryAfter) => {
2024
2040
  let payload = {};
2025
2041
  try {
@@ -1,5 +1,5 @@
1
1
  /** Promigence SDK — constants, error hierarchy and shared types. */
2
- export declare const VERSION = "0.1.0-beta.7";
2
+ export declare const VERSION = "0.1.0-beta.8";
3
3
  export declare const DOCS_URL = "https://promigence.ai";
4
4
  /** The error reference; each code is an anchor on it (the API's `docs` link has the same form). */
5
5
  export declare const ERRORS_DOCS_URL = "https://www.promigence.ai/docs/errors";
@@ -190,6 +190,15 @@ export declare class TimeoutError extends PromigenceError {
190
190
  runId?: string;
191
191
  });
192
192
  }
193
+ /**
194
+ * A service update may stop a command that was running while its output was streaming to you
195
+ * (`execStream`, `commands.run` with output callbacks); the time it ran is credited back, and the
196
+ * sandbox keeps running. `retryable` is `false`: the command may have done part of its work before
197
+ * it stopped, so run it again only if that is safe. exit 3
198
+ */
199
+ export declare class ServiceRestartError extends PromigenceError {
200
+ constructor(message: string, fix: string);
201
+ }
193
202
  /** An API error with no more specific class (5xx, unknown code). exit from the table. */
194
203
  export declare class ApiError extends PromigenceError {
195
204
  }
package/dist/cjs/core.js CHANGED
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.EXIT_BY_CODE = exports.NotReleasedError = exports.ApiError = exports.TimeoutError = exports.RateLimitError = exports.UnreachableError = exports.NotFoundError = exports.AuthError = exports.NotVerifiedError = exports.SpendCapError = exports.CommandExitError = exports.EnvFailedError = exports.PreviewsUnavailableError = exports.UnsupportedError = exports.InvalidArgumentError = exports.PromigenceError = exports.PREVIEWS_UNAVAILABLE = exports.FILE_PUT_CHUNK_BYTES = exports.MAX_OUTPUT_BYTES_DEFAULT = exports.IMAGE_BUILD_LIST_PRICE = exports.IMAGE_BUILD_TIMEOUT_MS = exports.WAIT_TIMEOUT_MS = exports.KEY_CONTACT = exports.DEFAULT_API_URL = exports.ERRORS_DOCS_URL = exports.DOCS_URL = exports.VERSION = void 0;
3
+ exports.EXIT_BY_CODE = exports.NotReleasedError = exports.ApiError = exports.ServiceRestartError = exports.TimeoutError = exports.RateLimitError = exports.UnreachableError = exports.NotFoundError = exports.AuthError = exports.NotVerifiedError = exports.SpendCapError = exports.CommandExitError = exports.EnvFailedError = exports.PreviewsUnavailableError = exports.UnsupportedError = exports.InvalidArgumentError = exports.PromigenceError = exports.PREVIEWS_UNAVAILABLE = exports.FILE_PUT_CHUNK_BYTES = exports.MAX_OUTPUT_BYTES_DEFAULT = exports.IMAGE_BUILD_LIST_PRICE = exports.IMAGE_BUILD_TIMEOUT_MS = exports.WAIT_TIMEOUT_MS = exports.KEY_CONTACT = exports.DEFAULT_API_URL = exports.ERRORS_DOCS_URL = exports.DOCS_URL = exports.VERSION = void 0;
4
4
  exports.previewsFix = previewsFix;
5
5
  exports.withPreviewsFix = withPreviewsFix;
6
6
  exports.fixBeyondMessage = fixBeyondMessage;
7
7
  exports.previewsOff = previewsOff;
8
8
  exports.exitForCode = exitForCode;
9
9
  const hint_js_1 = require("./hint.js");
10
- exports.VERSION = "0.1.0-beta.7";
10
+ exports.VERSION = "0.1.0-beta.8";
11
11
  exports.DOCS_URL = "https://promigence.ai";
12
12
  exports.ERRORS_DOCS_URL = "https://www.promigence.ai/docs/errors";
13
13
  exports.DEFAULT_API_URL = "https://api.promigence.ai/v1";
@@ -215,6 +215,12 @@ class TimeoutError extends PromigenceError {
215
215
  }
216
216
  }
217
217
  exports.TimeoutError = TimeoutError;
218
+ class ServiceRestartError extends PromigenceError {
219
+ constructor(message, fix) {
220
+ super({ code: "service_restart", message, fix, exitCode: 3, category: "env", retryable: false });
221
+ }
222
+ }
223
+ exports.ServiceRestartError = ServiceRestartError;
218
224
  class ApiError extends PromigenceError {
219
225
  }
220
226
  exports.ApiError = ApiError;
@@ -233,6 +239,7 @@ exports.EXIT_BY_CODE = {
233
239
  invalid_argument: 2, unsupported: 2, not_released: 1, task_failed: 4,
234
240
  env_failed: 3, snapshot_rejected: 6, build_failed: 3, snapshot_failed: 4,
235
241
  not_connected: 7,
242
+ service_restart: 3,
236
243
  fork_failed: 3, start_timeout: 3, readiness_failed: 3, verify_too_slow: 3,
237
244
  verify_each_failed: 3, toolchain_mismatch: 3, sandbox_unresponsive: 3, oom_within_tier: 3,
238
245
  disk_full_within_tier: 3, sandbox_interrupted: 3, integrity_mismatch: 3, egress_unavailable: 3,
@@ -259,10 +266,11 @@ exports.EXIT_BY_CODE = {
259
266
  build_timeout: 4,
260
267
  image_unresolvable: 2,
261
268
  registry_unavailable: 3,
262
- trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached: 10,
269
+ trial_credits_exhausted: 5, card_required: 5, credit_unclaimed: 5, concurrency_limit: 5, egress_cap_reached: 5,
263
270
  billing_unavailable: 5,
264
271
  project_cap_reached: 5,
265
272
  spend_limit_reached: 5,
273
+ billing_hold: 5,
266
274
  tier_over_plan: 2,
267
275
  network_host_refused: 9, network_policy_unsupported: 3,
268
276
  secrets_in_snapshot: 2, secrets_unavailable: 3,
@@ -3,7 +3,8 @@
3
3
  * the credentials file (`~/.config/promigence/credentials`, 0600). The CLI writes it
4
4
  * (`promigence login`, `promigence auth login`, `promigence logout`); the CLI and both SDKs read it.
5
5
  *
6
- * macOS the login Keychain, through `security` (when HOME holds one)
6
+ * macOS the login Keychain, through `security` (when the user's home holds one: HOME,
7
+ * or the account's own home when the environment has no HOME)
7
8
  * Linux and BSD the Secret Service (GNOME Keyring, KWallet), through `secret-tool`, when a
8
9
  * desktop session bus is there (a CI job or an SSH shell has none: the file)
9
10
  * Windows the file: no tool that ships with Windows can read a stored secret back
@@ -34,7 +35,7 @@ export declare function storeLabel(store: CredentialStore, path?: string): strin
34
35
  * The keychain this process stores a sign-in in, or undefined for the file. `auto` is decided by
35
36
  * the platform and by whether its tool (and, for the Secret Service, a session bus) is there.
36
37
  */
37
- export declare function keychainStore(env?: NodeJS.ProcessEnv, platform?: string): KeychainStore | undefined;
38
+ export declare function keychainStore(env?: NodeJS.ProcessEnv, platform?: string, home?: () => string): KeychainStore | undefined;
38
39
  /**
39
40
  * The keychains a sign-out (or a sign-in that lands in the file) must clear for this path: the one
40
41
  * in use, and the platform's own even when `PROMIGENCE_CREDENTIAL_STORE=file` (an item a previous
@@ -13,6 +13,7 @@ exports.keychainCacheSet = keychainCacheSet;
13
13
  exports.forgetKeychainReads = forgetKeychainReads;
14
14
  const node_child_process_1 = require("node:child_process");
15
15
  const node_fs_1 = require("node:fs");
16
+ const node_os_1 = require("node:os");
16
17
  const node_path_1 = require("node:path");
17
18
  exports.KEYCHAIN_SERVICE = "promigence-cli";
18
19
  const KEYCHAIN_LABEL = "Promigence CLI credentials";
@@ -43,8 +44,19 @@ function sessionBus(env) {
43
44
  const run = env["XDG_RUNTIME_DIR"];
44
45
  return Boolean(run) && (0, node_fs_1.existsSync)((0, node_path_1.join)(run, "bus"));
45
46
  }
47
+ function userHome(env, home = node_os_1.homedir) {
48
+ const h = env["HOME"];
49
+ if (h)
50
+ return h;
51
+ try {
52
+ return home() || undefined;
53
+ }
54
+ catch {
55
+ return undefined;
56
+ }
57
+ }
46
58
  const warnedSetting = new Set();
47
- function keychainStore(env = process.env, platform = process.platform) {
59
+ function keychainStore(env = process.env, platform = process.platform, home = node_os_1.homedir) {
48
60
  const raw = (env["PROMIGENCE_CREDENTIAL_STORE"] ?? "").trim().toLowerCase();
49
61
  switch (raw) {
50
62
  case "file": return undefined;
@@ -59,8 +71,8 @@ function keychainStore(env = process.env, platform = process.platform) {
59
71
  }
60
72
  }
61
73
  if (platform === "darwin") {
62
- const home = env["HOME"];
63
- return home && (0, node_fs_1.existsSync)((0, node_path_1.join)(home, "Library", "Keychains")) && onPath("security", env) ? "macos-keychain" : undefined;
74
+ const h = userHome(env, home);
75
+ return h && (0, node_fs_1.existsSync)((0, node_path_1.join)(h, "Library", "Keychains")) && onPath("security", env) ? "macos-keychain" : undefined;
64
76
  }
65
77
  if (platform === "win32")
66
78
  return undefined;
@@ -107,8 +119,9 @@ function runTool(store, args, env, input, timeout) {
107
119
  const bin = onPath(toolName(store), env);
108
120
  if (bin === undefined)
109
121
  throw Object.assign(new Error(`${toolName(store)} not found`), { code: "ENOENT" });
122
+ const h = store === "macos-keychain" && !env["HOME"] ? userHome(env) : undefined;
110
123
  return (0, node_child_process_1.execFileSync)(bin, args, {
111
- encoding: "utf8", timeout, env,
124
+ encoding: "utf8", timeout, env: h ? { ...env, HOME: h } : env,
112
125
  ...(input === undefined ? { stdio: ["ignore", "pipe", "pipe"] } : { input, stdio: ["pipe", "pipe", "pipe"] }),
113
126
  });
114
127
  }
@@ -243,6 +243,36 @@ export interface BackgroundExecList {
243
243
  execs: Array<BackgroundExec>;
244
244
  sandbox_id: string;
245
245
  }
246
+ /**
247
+ * `GET /v1/billing/history` — your billing history, newest first: every credit you received and
248
+ * every payment, one page at a time.
249
+ */
250
+ export interface BillingHistory {
251
+ entries: Array<BillingHistoryEntry>;
252
+ /**
253
+ * Pass as `cursor` for the next, older page; `null` on the last page.
254
+ */
255
+ next_cursor?: string | null;
256
+ }
257
+ /**
258
+ * One entry of your billing history: a credit you received or a payment. Exactly one of
259
+ * `credit` and `payment` is set.
260
+ */
261
+ export interface BillingHistoryEntry {
262
+ /**
263
+ * When it happened, RFC 3339: when a credit was added, when a payment was made, failed or
264
+ * was refunded.
265
+ */
266
+ at: string;
267
+ /**
268
+ * A credit you received; `null` for a payment.
269
+ */
270
+ credit?: CreditGrant | null;
271
+ /**
272
+ * A payment; `null` for a credit.
273
+ */
274
+ payment?: Payment | null;
275
+ }
246
276
  /**
247
277
  * The billing period `usage` covers.
248
278
  */
@@ -261,9 +291,9 @@ export interface BillingPeriod {
261
291
  start: string;
262
292
  }
263
293
  /**
264
- * `GET /v1/billing` — plan, card on file, this month's usage, and the upcoming invoice
265
- * preview. Never fails because the payment provider is slow: the estimate is the only part
266
- * that asks it, and its failure is a field, not a status.
294
+ * `GET /v1/billing` — plan, card on file, this month's usage, and the upcoming invoice preview.
295
+ * Never fails because the payment provider is slow: the estimate is the only part that asks it,
296
+ * and its failure is a field, not a status.
267
297
  */
268
298
  export interface BillingStatus {
269
299
  /**
@@ -274,11 +304,22 @@ export interface BillingStatus {
274
304
  * `null` while no card is on file.
275
305
  */
276
306
  card?: CardOnFile | null;
307
+ /**
308
+ * A sentence to show beside the card when it does not unlock paid limits for this
309
+ * organization (it already pays for another one, or it is being confirmed with a $1 charge, or
310
+ * that charge did not go through); `null` otherwise.
311
+ */
312
+ card_note?: string | null;
277
313
  card_on_file: boolean;
278
314
  /**
279
315
  * True once a billing customer exists for the organisation.
280
316
  */
281
317
  customer: boolean;
318
+ /**
319
+ * The $1 that confirms the payment method on file when it has no stable payer (Apple Pay,
320
+ * Google Pay, Amazon Pay); `null` when it needed none.
321
+ */
322
+ method_check?: MethodCheckView | null;
282
323
  notice?: TrialNotice | null;
283
324
  org_id: string;
284
325
  period: BillingPeriod;
@@ -830,7 +871,7 @@ export interface CliTokenCreate {
830
871
  /**
831
872
  * Every error and failure code the API returns.
832
873
  */
833
- 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" | "stopped_by_support" | "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" | "account_blocked" | "setup_required";
874
+ 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" | "stopped_by_support" | "forbidden" | "snapshot_incompatible" | "storage_limit_reached" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "credit_unclaimed" | "billing_unavailable" | "project_cap_reached" | "spend_limit_reached" | "billing_hold" | "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" | "account_blocked" | "setup_required";
834
875
  export interface Concurrency {
835
876
  }
836
877
  /**
@@ -916,6 +957,41 @@ export interface CreditClaim {
916
957
  terms_version?: string | null;
917
958
  token?: string | null;
918
959
  }
960
+ /**
961
+ * A credit your organization received, and what is left of it.
962
+ */
963
+ export interface CreditGrant {
964
+ /**
965
+ * When it expires, RFC 3339; `null` when it never expires.
966
+ */
967
+ expires_at?: string | null;
968
+ /**
969
+ * When it was added, RFC 3339.
970
+ */
971
+ granted_at: string;
972
+ /**
973
+ * USD.
974
+ */
975
+ granted_usd: number;
976
+ /**
977
+ * What it is: `free_credit` (the free credit), `card_bonus` (credit for adding a card),
978
+ * `referral` (a referral reward), `plan` (usage included with a paid plan),
979
+ * `from_promigence` (credit Promigence added to your account), `service_restart` (credit
980
+ * for a command a service restart stopped), `confirmation_credit` (a $1 charge that
981
+ * confirmed a payment method, added back as credit), or `other`.
982
+ */
983
+ kind: string;
984
+ /**
985
+ * What is left of it, USD: 0 once it is used, expired or taken back. Credit that expires
986
+ * soonest is used first, and credit that never expires last.
987
+ */
988
+ remaining_usd: number;
989
+ /**
990
+ * `active` (some of it is left), `used` (all of it was used), `expired` (it expired before
991
+ * all of it was used), or `taken_back`.
992
+ */
993
+ status: string;
994
+ }
919
995
  /**
920
996
  * The account's free credit (`GET /v1/credits/offer`, and the answer to a claim). The credit is
921
997
  * claimed in the browser, where the terms are accepted: `POST /v1/credits/claim-link` makes the
@@ -942,6 +1018,11 @@ export interface CreditOffer {
942
1018
  * One sentence for a person.
943
1019
  */
944
1020
  message: string;
1021
+ /**
1022
+ * USD charged to confirm a payment method with no stable payer when it is added (Apple Pay,
1023
+ * Google Pay, Amazon Pay): it is added to your credit, and the card bonus comes with it.
1024
+ */
1025
+ method_check_usd?: number;
945
1026
  /**
946
1027
  * `claimable`, `claimed`, `pending_review`, `needs_card`, `not_eligible`, `offer_ended`,
947
1028
  * `denied` or `none`.
@@ -1075,7 +1156,7 @@ export interface ErrorBody {
1075
1156
  /**
1076
1157
  * Every error code the API returns. `category` decides whether the failure is billed: `env` is ours (not billed before hand-over; after it, the time since the sandbox's last snapshot is credited back, up to 24 hours, when our side shows the cause), `task` is your command and is billed. The full table is `x-promigence-error-codes` at the document root.
1077
1158
  */
1078
- export type ErrorCode = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "toolchain_mismatch" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "preempted" | "verify_did_not_cover" | "grader_failed" | "nonzero_exit" | "grade_not_passed" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "shutdown_by_task" | "modified_by_task" | "cap_killed" | "cap_exceeded" | "cap_paused" | "credits_paused" | "aborted_by_client" | "stopped_by_support" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "forbidden" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "snapshot_incompatible" | "storage_limit_reached" | "resume_unavailable" | "sandbox_unreachable" | "capacity_busy" | "region_at_capacity" | "builder_unavailable" | "builder_busy" | "overloaded" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "enoent" | "trial_credits_exhausted" | "credit_unclaimed" | "setup_required" | "card_required" | "billing_unavailable" | "concurrency_limit" | "egress_cap_reached" | "project_cap_reached" | "spend_limit_reached" | "tier_over_plan" | "network_host_refused" | "network_policy_unsupported" | "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" | "account_blocked";
1159
+ export type ErrorCode = "fork_failed" | "start_timeout" | "readiness_failed" | "verify_too_slow" | "verify_each_failed" | "toolchain_mismatch" | "sandbox_unresponsive" | "oom_within_tier" | "disk_full_within_tier" | "sandbox_interrupted" | "integrity_mismatch" | "egress_unavailable" | "service_timeout" | "preempted" | "verify_did_not_cover" | "grader_failed" | "nonzero_exit" | "grade_not_passed" | "task_timeout" | "oom_over_tier" | "disk_over_tier" | "shutdown_by_task" | "modified_by_task" | "cap_killed" | "cap_exceeded" | "cap_paused" | "credits_paused" | "aborted_by_client" | "stopped_by_support" | "expired" | "not_started" | "superseded" | "usage" | "internal" | "auth" | "forbidden" | "not_found" | "unreachable" | "rate_limited" | "timeout" | "not_verified" | "snapshot_incompatible" | "storage_limit_reached" | "resume_unavailable" | "sandbox_unreachable" | "capacity_busy" | "region_at_capacity" | "builder_unavailable" | "builder_busy" | "overloaded" | "tier_unavailable" | "snapshot_unavailable" | "capacity_limit" | "build_timeout" | "dockerfile_build_failed" | "image_unresolvable" | "registry_unavailable" | "enoent" | "trial_credits_exhausted" | "credit_unclaimed" | "setup_required" | "card_required" | "billing_unavailable" | "concurrency_limit" | "egress_cap_reached" | "project_cap_reached" | "spend_limit_reached" | "billing_hold" | "tier_over_plan" | "network_host_refused" | "network_policy_unsupported" | "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" | "account_blocked";
1079
1160
  /**
1080
1161
  * `POST /v1/sandboxes/{id}/execs`, and the `exec` of `POST /v1/runs`: one command. `argv` (a
1081
1162
  * non-empty list) or `sh` (a shell line) is required.
@@ -2547,6 +2628,29 @@ export interface MemberView {
2547
2628
  */
2548
2629
  you: boolean;
2549
2630
  }
2631
+ /**
2632
+ * The $1 charged to confirm a payment method with no stable payer (`GET /v1/billing`
2633
+ * `method_check`).
2634
+ */
2635
+ export interface MethodCheckView {
2636
+ /**
2637
+ * USD charged; added to your credit once paid.
2638
+ */
2639
+ amount_usd: number;
2640
+ /**
2641
+ * USD of credit that came with it (the card bonus), once paid; `null` otherwise.
2642
+ */
2643
+ bonus_usd?: number | null;
2644
+ /**
2645
+ * The method as a person reads it: `Apple Pay`, `Google Pay`, `Amazon Pay`, ...
2646
+ */
2647
+ method: string;
2648
+ /**
2649
+ * `confirming` (charged, its answer not in yet), `paid` (it counts as your payment method) or
2650
+ * `failed` (declined, or it needed you there to approve it: it does not count; add a card).
2651
+ */
2652
+ status: string;
2653
+ }
2550
2654
  /**
2551
2655
  * `POST /v1/orgs` and `POST /v1/orgs/{org}/projects`.
2552
2656
  */
@@ -2814,6 +2918,44 @@ export interface ParkedBytes {
2814
2918
  */
2815
2919
  allocated: number;
2816
2920
  }
2921
+ /**
2922
+ * A payment: an invoice paid, a payment that failed, a refund, or the charge that confirmed a
2923
+ * payment method.
2924
+ */
2925
+ export interface Payment {
2926
+ /**
2927
+ * USD: what was paid, what was due, what was refunded, or what confirmed the method.
2928
+ */
2929
+ amount_usd: number;
2930
+ /**
2931
+ * The invoice's number, as the invoice shows it; `null` when not known.
2932
+ */
2933
+ invoice_number?: string | null;
2934
+ /**
2935
+ * The invoice's page: its receipt once it is paid, where to pay it while a payment has
2936
+ * failed; `null` when not known.
2937
+ */
2938
+ invoice_url?: string | null;
2939
+ /**
2940
+ * `invoice_paid`, `payment_failed`, `refund`, or `method_check` (a charge, usually $1, that
2941
+ * confirmed a payment method; it comes back as credit).
2942
+ */
2943
+ kind: string;
2944
+ /**
2945
+ * `method_check`: the payment method it confirmed, by name (`Apple Pay`); `null` otherwise.
2946
+ */
2947
+ method?: string | null;
2948
+ /**
2949
+ * The plan whose fee the invoice billed; `null` when it billed usage alone.
2950
+ */
2951
+ plan?: string | null;
2952
+ /**
2953
+ * `paid` (for a payment that failed: paid since), `retrying` (it failed and will be tried
2954
+ * again), `failed` (it failed and will not be tried again; for `method_check`, the method
2955
+ * was not confirmed), `refunded`, or `confirmed` (`method_check`: the method is confirmed).
2956
+ */
2957
+ status: string;
2958
+ }
2817
2959
  export interface Percentiles {
2818
2960
  p50: number;
2819
2961
  p95: number;
@@ -4502,7 +4644,7 @@ export interface SandboxView {
4502
4644
  */
4503
4645
  outcome?: string | null;
4504
4646
  /**
4505
- * While it is paused: when it will be deleted, with its memory and files, unless it is
4647
+ * While it is paused: when it will be deleted, with its files and state, unless it is
4506
4648
  * resumed before then (RFC 3339). A paused sandbox is kept for 30 days, and resuming it
4507
4649
  * starts the 30 days again. Absent while it is not paused, and for a paused sandbox that is
4508
4650
  * not due to be deleted.
package/dist/cjs/proxy.js CHANGED
@@ -205,8 +205,9 @@ function requestVia(url, options, env = process.env) {
205
205
  connect.end();
206
206
  return undefined;
207
207
  };
208
+ const { agent: _agent, ...direct } = options;
208
209
  return (0, node_https_1.request)(url, {
209
- ...options,
210
+ ...direct,
210
211
  createConnection: createConnection,
211
212
  });
212
213
  }