@blaxel/core 0.3.18 → 0.3.20-preview.286

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.
@@ -24,8 +24,8 @@ function missingCredentialsMessage() {
24
24
  return "No Blaxel credentials found. Set the BL_API_KEY and BL_WORKSPACE environment variables, or run `bl login`.";
25
25
  }
26
26
  // Build info - these placeholders are replaced at build time by build:replace-imports
27
- const BUILD_VERSION = "0.3.18";
28
- const BUILD_COMMIT = "57fc469276ceec702626782b675333c68e6bce4d";
27
+ const BUILD_VERSION = "0.3.20-preview.286";
28
+ const BUILD_COMMIT = "6ebbd206e01759209b37771835096c6500d9fbb9";
29
29
  const BUILD_SENTRY_DSN = "https://fd5e60e1c9820e1eef5ccebb84a07127@o4508714045276160.ingest.us.sentry.io/4510465864564736";
30
30
  const BLAXEL_API_VERSION = "2026-04-28";
31
31
  // Bun < 1.3.11 never sends connection-level WINDOW_UPDATE: the pooled h2
@@ -1,6 +1,61 @@
1
1
  // This file is auto-generated by @hey-api/openapi-ts
2
2
  import { formDataBodySerializer } from '@hey-api/client-fetch';
3
3
  import { client as _heyApiClient } from "./client.gen.js";
4
+ /**
5
+ * Export the filesystem changes to a presigned URL
6
+ * Archives everything the sandbox changed on top of its base image and streams it, uncompressed, to a presigned S3 PUT URL. The memory of the sandbox is not archived.
7
+ * The sandbox is quiesced first: the process list is saved (unless saveProcesses is false), every process is stopped, and the API then refuses the calls that would write to the filesystem. The freeze is not lifted afterwards, since an exported sandbox is meant to be restored elsewhere; call POST /archive/resume to lift it.
8
+ * Use dryRun to get the archive's content and exact size without stopping anything and without uploading.
9
+ * Set async to start the export and answer immediately, which is what archiving a large filesystem needs: the export then reports itself through GET /archive/status.
10
+ */
11
+ export const postArchiveExport = (options) => {
12
+ return (options.client ?? _heyApiClient).post({
13
+ security: [
14
+ {
15
+ scheme: 'bearer',
16
+ type: 'http'
17
+ }
18
+ ],
19
+ url: '/archive/export',
20
+ ...options,
21
+ headers: {
22
+ 'Content-Type': 'application/json',
23
+ ...options?.headers
24
+ }
25
+ });
26
+ };
27
+ /**
28
+ * Lift the archive freeze
29
+ * Makes the API serve every route again after an export. The processes stopped for the export are not relaunched: this exists so a failed or aborted export does not leave the sandbox unusable.
30
+ */
31
+ export const postArchiveResume = (options) => {
32
+ return (options?.client ?? _heyApiClient).post({
33
+ security: [
34
+ {
35
+ scheme: 'bearer',
36
+ type: 'http'
37
+ }
38
+ ],
39
+ url: '/archive/resume',
40
+ ...options
41
+ });
42
+ };
43
+ /**
44
+ * Get the archive status
45
+ * Reports whether the sandbox is frozen for an archive export, and which processes were stopped for it.
46
+ */
47
+ export const getArchiveStatus = (options) => {
48
+ return (options?.client ?? _heyApiClient).get({
49
+ security: [
50
+ {
51
+ scheme: 'bearer',
52
+ type: 'http'
53
+ }
54
+ ],
55
+ url: '/archive/status',
56
+ ...options
57
+ });
58
+ };
4
59
  /**
5
60
  * Apply code edit
6
61
  * Uses the configured LLM provider (Relace or Morph) to apply a code edit to the original content.
@@ -120,6 +175,22 @@ export const deleteDrivesMountByMountPath = (options) => {
120
175
  ...options
121
176
  });
122
177
  };
178
+ /**
179
+ * Reload environment from guest metadata
180
+ * Re-reads /bl/metadata and applies its environment to the sandbox-api process, so this process and every process started afterwards see the current values. Called by the guest init after an environment update; safe to call manually.
181
+ */
182
+ export const postEnvironmentReload = (options) => {
183
+ return (options?.client ?? _heyApiClient).post({
184
+ security: [
185
+ {
186
+ scheme: 'bearer',
187
+ type: 'http'
188
+ }
189
+ ],
190
+ url: '/environment/reload',
191
+ ...options
192
+ });
193
+ };
123
194
  /**
124
195
  * Search for text content in files
125
196
  * Searches for text content inside files using ripgrep. Returns matching lines with context.
@@ -602,6 +673,42 @@ export const getProcessByIdentifierLogsStream = (options) => {
602
673
  ...options
603
674
  });
604
675
  };
676
+ /**
677
+ * Close a process's stdin
678
+ * Send EOF to the process by closing its stdin pipe. Idempotent. For stdio protocols such as MCP this is the clean shutdown path.
679
+ */
680
+ export const deleteProcessByIdentifierStdin = (options) => {
681
+ return (options.client ?? _heyApiClient).delete({
682
+ security: [
683
+ {
684
+ scheme: 'bearer',
685
+ type: 'http'
686
+ }
687
+ ],
688
+ url: '/process/{identifier}/stdin',
689
+ ...options
690
+ });
691
+ };
692
+ /**
693
+ * Write to a process's stdin
694
+ * Write the raw request body to the stdin of a process started with "stdin": true. Bytes are forwarded verbatim, so include the trailing newline your protocol expects. Sequential requests keep their order; each body is written atomically with respect to other writers. The pipe does not survive a sandbox-api restart: once it is gone this returns 409 and the process must be restarted.
695
+ */
696
+ export const postProcessByIdentifierStdin = (options) => {
697
+ return (options.client ?? _heyApiClient).post({
698
+ security: [
699
+ {
700
+ scheme: 'bearer',
701
+ type: 'http'
702
+ }
703
+ ],
704
+ url: '/process/{identifier}/stdin',
705
+ ...options,
706
+ headers: {
707
+ 'Content-Type': 'application/octet-stream',
708
+ ...options?.headers
709
+ }
710
+ });
711
+ };
605
712
  /**
606
713
  * Upgrade the sandbox-api
607
714
  * Triggers an upgrade of the sandbox-api process. Returns 200 immediately before upgrading.
@@ -1,7 +1,7 @@
1
1
  import { settings } from "../../common/settings.js";
2
2
  import { SandboxAction } from "../action.js";
3
3
  import { retryOnTransientReset } from "../../common/transient-retry.js";
4
- import { deleteProcessByIdentifier, deleteProcessByIdentifierKill, getProcess, getProcessByIdentifier, getProcessByIdentifierLogs, postProcess } from "../client/index.js";
4
+ import { deleteProcessByIdentifier, deleteProcessByIdentifierKill, deleteProcessByIdentifierStdin, getProcess, getProcessByIdentifier, getProcessByIdentifierLogs, postProcess, postProcessByIdentifierStdin } from "../client/index.js";
5
5
  export class SandboxProcess extends SandboxAction {
6
6
  constructor(sandbox) {
7
7
  super(sandbox);
@@ -338,6 +338,33 @@ export class SandboxProcess extends SandboxAction {
338
338
  this.handleResponseError(response, data, error);
339
339
  return data;
340
340
  }
341
+ /**
342
+ * Write raw bytes to the stdin of a process started with `stdin: true`.
343
+ * Bytes go through verbatim, so include the trailing newline your protocol
344
+ * expects (one JSON-RPC message per call for an MCP stdio server). Not
345
+ * retried: a duplicate write would corrupt the stream.
346
+ */
347
+ async writeStdin(identifier, data) {
348
+ const { response, data: result, error } = await postProcessByIdentifierStdin(this.withClient({
349
+ path: { identifier },
350
+ baseUrl: this.url,
351
+ body: data,
352
+ // The generated client JSON-encodes bodies by default; stdin is raw.
353
+ bodySerializer: null,
354
+ }));
355
+ this.handleResponseError(response, result, error);
356
+ }
357
+ /**
358
+ * Close the process's stdin (EOF). Idempotent. For stdio protocols such as
359
+ * MCP this is the clean shutdown path.
360
+ */
361
+ async closeStdin(identifier) {
362
+ const { response, data, error } = await deleteProcessByIdentifierStdin(this.withClient({
363
+ path: { identifier },
364
+ baseUrl: this.url,
365
+ }));
366
+ this.handleResponseError(response, data, error);
367
+ }
341
368
  async logs(identifier, type = "all") {
342
369
  // Idempotent GET: self-heal a transient connection reset.
343
370
  const data = await retryOnTransientReset(async () => {