From 8ea7bba5cd9cd9d047091386025965edeb316ab4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 00:59:13 +0000
Subject: [PATCH 01/18] chore: hide build context APIs
---
.stats.yml | 6 +-
api.md | 4 -
src/index.ts | 2 -
src/resources/blueprints.ts | 111 ------------------
src/resources/devboxes/devboxes.ts | 18 ---
src/resources/index.ts | 1 -
tests/api-resources/blueprints.test.ts | 4 -
tests/api-resources/devboxes/devboxes.test.ts | 54 ---------
8 files changed, 3 insertions(+), 197 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index bc705b998..1235f571e 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-0dd27c6877ed117c50fe0af95cee4d54c646d2484368e131b8e3315eba3fffcc.yml
-openapi_spec_hash: 68f663172747aef8e66f2b23289efc7b
+configured_endpoints: 94
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-907baea7d51fd2660895c74603cf1ff765eb9f62eb10ce6e0c1d17ac1c16abf2.yml
+openapi_spec_hash: f1280edb22cdd91238efc2b18e3d324c
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/api.md b/api.md
index 54c2fa2f5..9b205061c 100644
--- a/api.md
+++ b/api.md
@@ -97,7 +97,6 @@ Types:
- DevboxView
- DevboxCreateSSHKeyResponse
- DevboxDeleteDiskSnapshotResponse
-- DevboxKeepAliveResponse
- DevboxReadFileContentsResponse
- DevboxRemoveTunnelResponse
- DevboxUploadFileResponse
@@ -115,15 +114,12 @@ Methods:
- client.devboxes.execute(id, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.executeAsync(id, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.executeSync(id, { ...params }) -> DevboxExecutionDetailView
-- client.devboxes.keepAlive(id) -> unknown
- client.devboxes.listDiskSnapshots({ ...params }) -> DevboxSnapshotViewsDiskSnapshotsCursorIDPage
- client.devboxes.readFileContents(id, { ...params }) -> string
- client.devboxes.removeTunnel(id, { ...params }) -> unknown
-- client.devboxes.resume(id) -> DevboxView
- client.devboxes.shutdown(id) -> DevboxView
- client.devboxes.snapshotDisk(id, { ...params }) -> DevboxSnapshotView
- client.devboxes.snapshotDiskAsync(id, { ...params }) -> DevboxSnapshotView
-- client.devboxes.suspend(id) -> DevboxView
- client.devboxes.uploadFile(id, { ...params }) -> unknown
- client.devboxes.waitForCommand(devboxId, executionId, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.writeFileContents(id, { ...params }) -> DevboxExecutionDetailView
diff --git a/src/index.ts b/src/index.ts
index 59536fcb2..1b2f733c7 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -125,7 +125,6 @@ import {
DevboxExecuteParams,
DevboxExecuteSyncParams,
DevboxExecutionDetailView,
- DevboxKeepAliveResponse,
DevboxKillExecutionRequest,
DevboxListDiskSnapshotsParams,
DevboxListParams,
@@ -497,7 +496,6 @@ export declare namespace Runloop {
type DevboxView as DevboxView,
type DevboxCreateSSHKeyResponse as DevboxCreateSSHKeyResponse,
type DevboxDeleteDiskSnapshotResponse as DevboxDeleteDiskSnapshotResponse,
- type DevboxKeepAliveResponse as DevboxKeepAliveResponse,
type DevboxReadFileContentsResponse as DevboxReadFileContentsResponse,
type DevboxRemoveTunnelResponse as DevboxRemoveTunnelResponse,
type DevboxUploadFileResponse as DevboxUploadFileResponse,
diff --git a/src/resources/blueprints.ts b/src/resources/blueprints.ts
index 993c3f0d0..d6418ea46 100644
--- a/src/resources/blueprints.ts
+++ b/src/resources/blueprints.ts
@@ -318,11 +318,6 @@ export interface BlueprintBuildParameters {
*/
build_args?: { [key: string]: string } | null;
- /**
- * A build context backed by an Object.
- */
- build_context?: BlueprintBuildParameters.BuildContext | null;
-
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -348,14 +343,6 @@ export interface BlueprintBuildParameters {
*/
metadata?: { [key: string]: string } | null;
- /**
- * (Optional) Map of named build contexts to attach to the Blueprint build, where
- * the keys are the name used when referencing the contexts in a Dockerfile. See
- * Docker buildx additional contexts for details:
- * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
- */
- named_build_contexts?: { [key: string]: BlueprintBuildParameters.NamedBuildContexts } | null;
-
/**
* (Optional) Map of mount IDs/environment variable names to secret names. Secrets
* will be available to commands during the build. Secrets are NOT stored in the
@@ -378,30 +365,6 @@ export interface BlueprintBuildParameters {
}
export namespace BlueprintBuildParameters {
- /**
- * A build context backed by an Object.
- */
- export interface BuildContext {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
- /**
- * A build context backed by an Object.
- */
- export interface NamedBuildContexts {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
export interface Service {
/**
* The image of the container service.
@@ -640,11 +603,6 @@ export interface BlueprintCreateParams {
*/
build_args?: { [key: string]: string } | null;
- /**
- * A build context backed by an Object.
- */
- build_context?: BlueprintCreateParams.BuildContext | null;
-
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -670,14 +628,6 @@ export interface BlueprintCreateParams {
*/
metadata?: { [key: string]: string } | null;
- /**
- * (Optional) Map of named build contexts to attach to the Blueprint build, where
- * the keys are the name used when referencing the contexts in a Dockerfile. See
- * Docker buildx additional contexts for details:
- * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
- */
- named_build_contexts?: { [key: string]: BlueprintCreateParams.NamedBuildContexts } | null;
-
/**
* (Optional) Map of mount IDs/environment variable names to secret names. Secrets
* will be available to commands during the build. Secrets are NOT stored in the
@@ -700,30 +650,6 @@ export interface BlueprintCreateParams {
}
export namespace BlueprintCreateParams {
- /**
- * A build context backed by an Object.
- */
- export interface BuildContext {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
- /**
- * A build context backed by an Object.
- */
- export interface NamedBuildContexts {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
export interface Service {
/**
* The image of the container service.
@@ -855,11 +781,6 @@ export interface BlueprintPreviewParams {
*/
build_args?: { [key: string]: string } | null;
- /**
- * A build context backed by an Object.
- */
- build_context?: BlueprintPreviewParams.BuildContext | null;
-
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -885,14 +806,6 @@ export interface BlueprintPreviewParams {
*/
metadata?: { [key: string]: string } | null;
- /**
- * (Optional) Map of named build contexts to attach to the Blueprint build, where
- * the keys are the name used when referencing the contexts in a Dockerfile. See
- * Docker buildx additional contexts for details:
- * https://docs.docker.com/reference/cli/docker/buildx/build/#build-context
- */
- named_build_contexts?: { [key: string]: BlueprintPreviewParams.NamedBuildContexts } | null;
-
/**
* (Optional) Map of mount IDs/environment variable names to secret names. Secrets
* will be available to commands during the build. Secrets are NOT stored in the
@@ -915,30 +828,6 @@ export interface BlueprintPreviewParams {
}
export namespace BlueprintPreviewParams {
- /**
- * A build context backed by an Object.
- */
- export interface BuildContext {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
- /**
- * A build context backed by an Object.
- */
- export interface NamedBuildContexts {
- /**
- * The ID of an object, whose contents are to be used as a build context.
- */
- object_id: string;
-
- type: 'object';
- }
-
export interface Service {
/**
* The image of the container service.
diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts
index eb486e086..1fbc01ec8 100644
--- a/src/resources/devboxes/devboxes.ts
+++ b/src/resources/devboxes/devboxes.ts
@@ -395,15 +395,6 @@ export class Devboxes extends APIResource {
return this._client.post(`/v1/devboxes/${id}/remove_tunnel`, { body, ...options });
}
- /**
- * Resume a suspended Devbox with the disk state captured as suspend time. Note
- * that any previously running processes or daemons will need to be restarted using
- * the Devbox shell tools.
- */
- resume(id: string, options?: Core.RequestOptions): Core.APIPromise {
- return this._client.post(`/v1/devboxes/${id}/resume`, options);
- }
-
/**
* Shutdown a running Devbox. This will permanently stop the Devbox. If you want to
* save the state of the Devbox, you should take a snapshot before shutting down or
@@ -460,15 +451,6 @@ export class Devboxes extends APIResource {
return this._client.post(`/v1/devboxes/${id}/snapshot_disk_async`, { body, ...options });
}
- /**
- * Suspend a running Devbox and create a disk snapshot to enable resuming the
- * Devbox later with the same disk. Note this will not snapshot memory state such
- * as running processes.
- */
- suspend(id: string, options?: Core.RequestOptions): Core.APIPromise {
- return this._client.post(`/v1/devboxes/${id}/suspend`, options);
- }
-
/**
* Upload file contents of any type (binary, text, etc) to a Devbox. Note this API
* is suitable for large files (larger than 100MB) and efficiently uploads files
diff --git a/src/resources/index.ts b/src/resources/index.ts
index b07a85e3e..456395ee1 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -61,7 +61,6 @@ export {
type DevboxView,
type DevboxCreateSSHKeyResponse,
type DevboxDeleteDiskSnapshotResponse,
- type DevboxKeepAliveResponse,
type DevboxReadFileContentsResponse,
type DevboxRemoveTunnelResponse,
type DevboxUploadFileResponse,
diff --git a/tests/api-resources/blueprints.test.ts b/tests/api-resources/blueprints.test.ts
index 5f8049667..53fa329d4 100644
--- a/tests/api-resources/blueprints.test.ts
+++ b/tests/api-resources/blueprints.test.ts
@@ -26,7 +26,6 @@ describe('resource blueprints', () => {
base_blueprint_id: 'base_blueprint_id',
base_blueprint_name: 'base_blueprint_name',
build_args: { foo: 'string' },
- build_context: { object_id: 'object_id', type: 'object' },
code_mounts: [
{
repo_name: 'repo_name',
@@ -52,7 +51,6 @@ describe('resource blueprints', () => {
user_parameters: { uid: 0, username: 'username' },
},
metadata: { foo: 'string' },
- named_build_contexts: { foo: { object_id: 'object_id', type: 'object' } },
secrets: { foo: 'string' },
services: [
{
@@ -257,7 +255,6 @@ describe('resource blueprints', () => {
name: 'name',
base_blueprint_name: 'base_blueprint_name',
build_args: { foo: 'string' },
- build_context: { object_id: 'object_id', type: 'object' },
code_mounts: [
{
repo_name: 'repo_name',
@@ -283,7 +280,6 @@ describe('resource blueprints', () => {
user_parameters: { uid: 0, username: 'username' },
},
metadata: { foo: 'string' },
- named_build_contexts: { foo: { object_id: 'object_id', type: 'object' } },
secrets: { foo: 'string' },
services: [
{
diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts
index cba3193d9..6fa6e4243 100644
--- a/tests/api-resources/devboxes/devboxes.test.ts
+++ b/tests/api-resources/devboxes/devboxes.test.ts
@@ -262,24 +262,6 @@ describe('resource devboxes', () => {
});
});
- test('keepAlive', async () => {
- const responsePromise = client.devboxes.keepAlive('id');
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- test('keepAlive: request options instead of params are passed correctly', async () => {
- // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
- await expect(client.devboxes.keepAlive('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
- Runloop.NotFoundError,
- );
- });
-
test('listDiskSnapshots', async () => {
const responsePromise = client.devboxes.listDiskSnapshots();
const rawResponse = await responsePromise.asResponse();
@@ -345,24 +327,6 @@ describe('resource devboxes', () => {
const response = await client.devboxes.removeTunnel('id', { port: 0 });
});
- test('resume', async () => {
- const responsePromise = client.devboxes.resume('id');
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- test('resume: request options instead of params are passed correctly', async () => {
- // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
- await expect(client.devboxes.resume('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
- Runloop.NotFoundError,
- );
- });
-
test('shutdown', async () => {
const responsePromise = client.devboxes.shutdown('id');
const rawResponse = await responsePromise.asResponse();
@@ -439,24 +403,6 @@ describe('resource devboxes', () => {
).rejects.toThrow(Runloop.NotFoundError);
});
- test('suspend', async () => {
- const responsePromise = client.devboxes.suspend('id');
- const rawResponse = await responsePromise.asResponse();
- expect(rawResponse).toBeInstanceOf(Response);
- const response = await responsePromise;
- expect(response).not.toBeInstanceOf(Response);
- const dataAndResponse = await responsePromise.withResponse();
- expect(dataAndResponse.data).toBe(response);
- expect(dataAndResponse.response).toBe(rawResponse);
- });
-
- test('suspend: request options instead of params are passed correctly', async () => {
- // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
- await expect(client.devboxes.suspend('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
- Runloop.NotFoundError,
- );
- });
-
test('uploadFile: only required params', async () => {
const responsePromise = client.devboxes.uploadFile('id', { path: 'path' });
const rawResponse = await responsePromise.asResponse();
From 2ef3ede2bbc71b79f111ab9c0326573f44dfab4c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 24 Nov 2025 23:40:48 +0000
Subject: [PATCH 02/18] fix(devbox): launch parameter typo
---
.stats.yml | 4 ++--
src/resources/shared.ts | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 1235f571e..d57d5f1ec 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 94
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-907baea7d51fd2660895c74603cf1ff765eb9f62eb10ce6e0c1d17ac1c16abf2.yml
-openapi_spec_hash: f1280edb22cdd91238efc2b18e3d324c
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-ae41f8669a7ba1eec677634573b55bace4dedcf7027e0c1fee503d7c44472e3e.yml
+openapi_spec_hash: 9a3c12559ec74a00adffe7b254757903
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 3eee1e4a8..f352fa329 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -265,7 +265,7 @@ export namespace LaunchParameters {
*/
export interface UserParameters {
/**
- * User ID (UID) for the Linux user. Must be a positive integer.
+ * User ID (UID) for the Linux user. Must be a non-negative integer.
*/
uid: number;
From e810958cdab4b067d91f7a2e3cec481b44a5a7d9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 25 Nov 2025 02:37:39 +0000
Subject: [PATCH 03/18] fix(scorer): fixed RL_TEST_CONTEXT to RL_SCORER_CONTEXT
---
.stats.yml | 4 ++--
src/resources/scenarios/scorers.ts | 8 ++++----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index d57d5f1ec..f02816b21 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 94
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-ae41f8669a7ba1eec677634573b55bace4dedcf7027e0c1fee503d7c44472e3e.yml
-openapi_spec_hash: 9a3c12559ec74a00adffe7b254757903
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-c15740e10009ccfaf6cb6ae4463496618c05d033bdd779bf501f5afb0c05ffc9.yml
+openapi_spec_hash: a08d1a45d83ed2956ab643d1c6c07a40
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/scenarios/scorers.ts b/src/resources/scenarios/scorers.ts
index 7bfe05b32..5e5d0f892 100644
--- a/src/resources/scenarios/scorers.ts
+++ b/src/resources/scenarios/scorers.ts
@@ -79,7 +79,7 @@ export interface ScorerCreateResponse {
id: string;
/**
- * Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.
+ * Bash script that takes in $RL_SCORER_CONTEXT as env variable and runs scoring.
*/
bash_script: string;
@@ -99,7 +99,7 @@ export interface ScorerRetrieveResponse {
id: string;
/**
- * Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.
+ * Bash script that takes in $RL_SCORER_CONTEXT as env variable and runs scoring.
*/
bash_script: string;
@@ -119,7 +119,7 @@ export interface ScorerUpdateResponse {
id: string;
/**
- * Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.
+ * Bash script that takes in $RL_SCORER_CONTEXT as env variable and runs scoring.
*/
bash_script: string;
@@ -139,7 +139,7 @@ export interface ScorerListResponse {
id: string;
/**
- * Bash script that takes in $RL_TEST_CONTEXT as env variable and runs scoring.
+ * Bash script that takes in $RL_SCORER_CONTEXT as env variable and runs scoring.
*/
bash_script: string;
From a5143eff331d3404e1649ec57f01e67ea18b6613 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 2 Dec 2025 01:13:48 +0000
Subject: [PATCH 04/18] fix(api): don't ignore devbox keep_alive, suspend and
resume in api
---
.stats.yml | 6 +--
api.md | 4 ++
src/index.ts | 2 +
src/resources/devboxes/devboxes.ts | 18 +++++++
src/resources/index.ts | 1 +
tests/api-resources/devboxes/devboxes.test.ts | 54 +++++++++++++++++++
6 files changed, 82 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index f02816b21..21ba6b325 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 94
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-c15740e10009ccfaf6cb6ae4463496618c05d033bdd779bf501f5afb0c05ffc9.yml
-openapi_spec_hash: a08d1a45d83ed2956ab643d1c6c07a40
+configured_endpoints: 97
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-d2463b4c27719ea7275c8f587fa2c90e333471fdede11e5f944faa92dfb417d1.yml
+openapi_spec_hash: 132c1d9f04583e997df5d7698e155fff
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/api.md b/api.md
index 9b205061c..54c2fa2f5 100644
--- a/api.md
+++ b/api.md
@@ -97,6 +97,7 @@ Types:
- DevboxView
- DevboxCreateSSHKeyResponse
- DevboxDeleteDiskSnapshotResponse
+- DevboxKeepAliveResponse
- DevboxReadFileContentsResponse
- DevboxRemoveTunnelResponse
- DevboxUploadFileResponse
@@ -114,12 +115,15 @@ Methods:
- client.devboxes.execute(id, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.executeAsync(id, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.executeSync(id, { ...params }) -> DevboxExecutionDetailView
+- client.devboxes.keepAlive(id) -> unknown
- client.devboxes.listDiskSnapshots({ ...params }) -> DevboxSnapshotViewsDiskSnapshotsCursorIDPage
- client.devboxes.readFileContents(id, { ...params }) -> string
- client.devboxes.removeTunnel(id, { ...params }) -> unknown
+- client.devboxes.resume(id) -> DevboxView
- client.devboxes.shutdown(id) -> DevboxView
- client.devboxes.snapshotDisk(id, { ...params }) -> DevboxSnapshotView
- client.devboxes.snapshotDiskAsync(id, { ...params }) -> DevboxSnapshotView
+- client.devboxes.suspend(id) -> DevboxView
- client.devboxes.uploadFile(id, { ...params }) -> unknown
- client.devboxes.waitForCommand(devboxId, executionId, { ...params }) -> DevboxAsyncExecutionDetailView
- client.devboxes.writeFileContents(id, { ...params }) -> DevboxExecutionDetailView
diff --git a/src/index.ts b/src/index.ts
index 1b2f733c7..59536fcb2 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -125,6 +125,7 @@ import {
DevboxExecuteParams,
DevboxExecuteSyncParams,
DevboxExecutionDetailView,
+ DevboxKeepAliveResponse,
DevboxKillExecutionRequest,
DevboxListDiskSnapshotsParams,
DevboxListParams,
@@ -496,6 +497,7 @@ export declare namespace Runloop {
type DevboxView as DevboxView,
type DevboxCreateSSHKeyResponse as DevboxCreateSSHKeyResponse,
type DevboxDeleteDiskSnapshotResponse as DevboxDeleteDiskSnapshotResponse,
+ type DevboxKeepAliveResponse as DevboxKeepAliveResponse,
type DevboxReadFileContentsResponse as DevboxReadFileContentsResponse,
type DevboxRemoveTunnelResponse as DevboxRemoveTunnelResponse,
type DevboxUploadFileResponse as DevboxUploadFileResponse,
diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts
index 1fbc01ec8..eb486e086 100644
--- a/src/resources/devboxes/devboxes.ts
+++ b/src/resources/devboxes/devboxes.ts
@@ -395,6 +395,15 @@ export class Devboxes extends APIResource {
return this._client.post(`/v1/devboxes/${id}/remove_tunnel`, { body, ...options });
}
+ /**
+ * Resume a suspended Devbox with the disk state captured as suspend time. Note
+ * that any previously running processes or daemons will need to be restarted using
+ * the Devbox shell tools.
+ */
+ resume(id: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post(`/v1/devboxes/${id}/resume`, options);
+ }
+
/**
* Shutdown a running Devbox. This will permanently stop the Devbox. If you want to
* save the state of the Devbox, you should take a snapshot before shutting down or
@@ -451,6 +460,15 @@ export class Devboxes extends APIResource {
return this._client.post(`/v1/devboxes/${id}/snapshot_disk_async`, { body, ...options });
}
+ /**
+ * Suspend a running Devbox and create a disk snapshot to enable resuming the
+ * Devbox later with the same disk. Note this will not snapshot memory state such
+ * as running processes.
+ */
+ suspend(id: string, options?: Core.RequestOptions): Core.APIPromise {
+ return this._client.post(`/v1/devboxes/${id}/suspend`, options);
+ }
+
/**
* Upload file contents of any type (binary, text, etc) to a Devbox. Note this API
* is suitable for large files (larger than 100MB) and efficiently uploads files
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 456395ee1..b07a85e3e 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -61,6 +61,7 @@ export {
type DevboxView,
type DevboxCreateSSHKeyResponse,
type DevboxDeleteDiskSnapshotResponse,
+ type DevboxKeepAliveResponse,
type DevboxReadFileContentsResponse,
type DevboxRemoveTunnelResponse,
type DevboxUploadFileResponse,
diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts
index 6fa6e4243..cba3193d9 100644
--- a/tests/api-resources/devboxes/devboxes.test.ts
+++ b/tests/api-resources/devboxes/devboxes.test.ts
@@ -262,6 +262,24 @@ describe('resource devboxes', () => {
});
});
+ test('keepAlive', async () => {
+ const responsePromise = client.devboxes.keepAlive('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('keepAlive: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.devboxes.keepAlive('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
test('listDiskSnapshots', async () => {
const responsePromise = client.devboxes.listDiskSnapshots();
const rawResponse = await responsePromise.asResponse();
@@ -327,6 +345,24 @@ describe('resource devboxes', () => {
const response = await client.devboxes.removeTunnel('id', { port: 0 });
});
+ test('resume', async () => {
+ const responsePromise = client.devboxes.resume('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('resume: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.devboxes.resume('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
test('shutdown', async () => {
const responsePromise = client.devboxes.shutdown('id');
const rawResponse = await responsePromise.asResponse();
@@ -403,6 +439,24 @@ describe('resource devboxes', () => {
).rejects.toThrow(Runloop.NotFoundError);
});
+ test('suspend', async () => {
+ const responsePromise = client.devboxes.suspend('id');
+ const rawResponse = await responsePromise.asResponse();
+ expect(rawResponse).toBeInstanceOf(Response);
+ const response = await responsePromise;
+ expect(response).not.toBeInstanceOf(Response);
+ const dataAndResponse = await responsePromise.withResponse();
+ expect(dataAndResponse.data).toBe(response);
+ expect(dataAndResponse.response).toBe(rawResponse);
+ });
+
+ test('suspend: request options instead of params are passed correctly', async () => {
+ // ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
+ await expect(client.devboxes.suspend('id', { path: '/_stainless_unknown_path' })).rejects.toThrow(
+ Runloop.NotFoundError,
+ );
+ });
+
test('uploadFile: only required params', async () => {
const responsePromise = client.devboxes.uploadFile('id', { path: 'path' });
const rawResponse = await responsePromise.asResponse();
From e295c861c54be8320cf3a049023722159e1566d9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 25 Nov 2025 22:36:20 +0000
Subject: [PATCH 05/18] feat(blueprints): Add build context to the OpenAPI spec
(#6494)
---
.stats.yml | 4 +-
src/resources/blueprints.ts | 51 +++++++++++++++++++
src/resources/shared.ts | 15 ++++--
.../benchmarks/benchmarks.test.ts | 1 +
tests/api-resources/blueprints.test.ts | 2 +
.../api-resources/scenarios/scenarios.test.ts | 1 +
6 files changed, 69 insertions(+), 5 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 21ba6b325..a7dd140f8 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-d2463b4c27719ea7275c8f587fa2c90e333471fdede11e5f944faa92dfb417d1.yml
-openapi_spec_hash: 132c1d9f04583e997df5d7698e155fff
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b1e4697ee11a301905abe34736d6a2e74a2200c2f9bade48b6f50ee2d65a814f.yml
+openapi_spec_hash: 3ebe459b324ae2757ba3bee9d1484e90
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/blueprints.ts b/src/resources/blueprints.ts
index d6418ea46..8d501c22c 100644
--- a/src/resources/blueprints.ts
+++ b/src/resources/blueprints.ts
@@ -318,6 +318,11 @@ export interface BlueprintBuildParameters {
*/
build_args?: { [key: string]: string } | null;
+ /**
+ * A build context backed by an Object.
+ */
+ build_context?: BlueprintBuildParameters.BuildContext | null;
+
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -365,6 +370,18 @@ export interface BlueprintBuildParameters {
}
export namespace BlueprintBuildParameters {
+ /**
+ * A build context backed by an Object.
+ */
+ export interface BuildContext {
+ /**
+ * The ID of an object, whose contents are to be used as a build context.
+ */
+ object_id: string;
+
+ type: 'object';
+ }
+
export interface Service {
/**
* The image of the container service.
@@ -603,6 +620,11 @@ export interface BlueprintCreateParams {
*/
build_args?: { [key: string]: string } | null;
+ /**
+ * A build context backed by an Object.
+ */
+ build_context?: BlueprintCreateParams.BuildContext | null;
+
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -650,6 +672,18 @@ export interface BlueprintCreateParams {
}
export namespace BlueprintCreateParams {
+ /**
+ * A build context backed by an Object.
+ */
+ export interface BuildContext {
+ /**
+ * The ID of an object, whose contents are to be used as a build context.
+ */
+ object_id: string;
+
+ type: 'object';
+ }
+
export interface Service {
/**
* The image of the container service.
@@ -781,6 +815,11 @@ export interface BlueprintPreviewParams {
*/
build_args?: { [key: string]: string } | null;
+ /**
+ * A build context backed by an Object.
+ */
+ build_context?: BlueprintPreviewParams.BuildContext | null;
+
/**
* A list of code mounts to be included in the Blueprint.
*/
@@ -828,6 +867,18 @@ export interface BlueprintPreviewParams {
}
export namespace BlueprintPreviewParams {
+ /**
+ * A build context backed by an Object.
+ */
+ export interface BuildContext {
+ /**
+ * The ID of an object, whose contents are to be used as a build context.
+ */
+ object_id: string;
+
+ type: 'object';
+ }
+
export interface Service {
/**
* The image of the container service.
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index f352fa329..8b95be6e5 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -285,10 +285,14 @@ export type Mount =
export namespace Mount {
export interface FileMountParameters {
/**
- * Map of file paths to file contents to be written before setup. Keys are absolute
- * paths where files should be created, values are the file contents.
+ * Content of the file to mount.
*/
- files: { [key: string]: string };
+ content: string;
+
+ /**
+ * Target path where the file should be mounted.
+ */
+ target: string;
type: 'file_mount';
}
@@ -322,6 +326,11 @@ export interface RunProfile {
*/
launchParameters?: LaunchParameters | null;
+ /**
+ * A list of mounts to be included in the scenario run.
+ */
+ mounts?: Array | null;
+
/**
* Purpose of the run.
*/
diff --git a/tests/api-resources/benchmarks/benchmarks.test.ts b/tests/api-resources/benchmarks/benchmarks.test.ts
index ad125a1a0..d1850e6ba 100644
--- a/tests/api-resources/benchmarks/benchmarks.test.ts
+++ b/tests/api-resources/benchmarks/benchmarks.test.ts
@@ -189,6 +189,7 @@ describe('resource benchmarks', () => {
resource_size_request: 'X_SMALL',
user_parameters: { uid: 0, username: 'username' },
},
+ mounts: [{ object_id: 'object_id', object_path: 'object_path', type: 'object_mount' }],
purpose: 'purpose',
secrets: { foo: 'string' },
},
diff --git a/tests/api-resources/blueprints.test.ts b/tests/api-resources/blueprints.test.ts
index 53fa329d4..f781eb437 100644
--- a/tests/api-resources/blueprints.test.ts
+++ b/tests/api-resources/blueprints.test.ts
@@ -26,6 +26,7 @@ describe('resource blueprints', () => {
base_blueprint_id: 'base_blueprint_id',
base_blueprint_name: 'base_blueprint_name',
build_args: { foo: 'string' },
+ build_context: { object_id: 'object_id', type: 'object' },
code_mounts: [
{
repo_name: 'repo_name',
@@ -255,6 +256,7 @@ describe('resource blueprints', () => {
name: 'name',
base_blueprint_name: 'base_blueprint_name',
build_args: { foo: 'string' },
+ build_context: { object_id: 'object_id', type: 'object' },
code_mounts: [
{
repo_name: 'repo_name',
diff --git a/tests/api-resources/scenarios/scenarios.test.ts b/tests/api-resources/scenarios/scenarios.test.ts
index b1dc55f80..d3f185a50 100644
--- a/tests/api-resources/scenarios/scenarios.test.ts
+++ b/tests/api-resources/scenarios/scenarios.test.ts
@@ -251,6 +251,7 @@ describe('resource scenarios', () => {
resource_size_request: 'X_SMALL',
user_parameters: { uid: 0, username: 'username' },
},
+ mounts: [{ object_id: 'object_id', object_path: 'object_path', type: 'object_mount' }],
purpose: 'purpose',
secrets: { foo: 'string' },
},
From 1e6814677b20e12513da0faaa3cd4414a4d3df6e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 25 Nov 2025 23:45:27 +0000
Subject: [PATCH 06/18] chore(mounts): Update documentation for deprecated
fields to direct the user to the replacement API
---
.stats.yml | 4 ++--
src/resources/devboxes/devboxes.ts | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index a7dd140f8..0ab1f506b 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b1e4697ee11a301905abe34736d6a2e74a2200c2f9bade48b6f50ee2d65a814f.yml
-openapi_spec_hash: 3ebe459b324ae2757ba3bee9d1484e90
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-cb2d725f71e87810cd872eacd70e867ca10f94980fdf9c78bb2844c02ee47bf3.yml
+openapi_spec_hash: 16ce3e9184fc2afdee66db18a83a96e8
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts
index eb486e086..028d9a168 100644
--- a/src/resources/devboxes/devboxes.ts
+++ b/src/resources/devboxes/devboxes.ts
@@ -897,7 +897,7 @@ export interface DevboxCreateParams {
blueprint_name?: string | null;
/**
- * A list of code mounts to be included in the Devbox.
+ * A list of code mounts to be included in the Devbox. Use mounts instead.
*/
code_mounts?: Array | null;
@@ -914,7 +914,7 @@ export interface DevboxCreateParams {
environment_variables?: { [key: string]: string } | null;
/**
- * (Optional) Map of paths and file contents to write before setup..
+ * Map of paths and file contents to write before setup. Use mounts instead.
*/
file_mounts?: { [key: string]: string } | null;
From 4ebe08c525a71cecb26e78a3a52602efb40fb968 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 03:37:12 +0000
Subject: [PATCH 07/18] fix(mcp): return correct lines on typescript errors
---
.devcontainer/Dockerfile | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 .devcontainer/Dockerfile
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000..8ea34be96
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,23 @@
+# syntax=docker/dockerfile:1
+FROM debian:bookworm-slim AS stainless
+
+RUN apt-get update && apt-get install -y \
+ nodejs \
+ npm \
+ yarnpkg \
+ && apt-get clean autoclean
+
+# Ensure UTF-8 encoding
+ENV LANG=C.UTF-8
+ENV LC_ALL=C.UTF-8
+
+# Yarn
+RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn
+
+WORKDIR /workspace
+
+COPY package.json yarn.lock /workspace/
+
+RUN yarn install
+
+COPY . /workspace
From 83d2d6cb029c72383fdece53d3850af5416447a1 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 03:37:50 +0000
Subject: [PATCH 08/18] chore(internal): codegen related update
---
.devcontainer/Dockerfile | 23 -----------------------
1 file changed, 23 deletions(-)
delete mode 100644 .devcontainer/Dockerfile
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 8ea34be96..000000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-# syntax=docker/dockerfile:1
-FROM debian:bookworm-slim AS stainless
-
-RUN apt-get update && apt-get install -y \
- nodejs \
- npm \
- yarnpkg \
- && apt-get clean autoclean
-
-# Ensure UTF-8 encoding
-ENV LANG=C.UTF-8
-ENV LC_ALL=C.UTF-8
-
-# Yarn
-RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn
-
-WORKDIR /workspace
-
-COPY package.json yarn.lock /workspace/
-
-RUN yarn install
-
-COPY . /workspace
From 8932b2d7b4bc2a5c50487db572286448d388e6ea Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 03:38:32 +0000
Subject: [PATCH 09/18] fix(mcp): correct code tool API endpoint
---
.devcontainer/Dockerfile | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
create mode 100644 .devcontainer/Dockerfile
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000..8ea34be96
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,23 @@
+# syntax=docker/dockerfile:1
+FROM debian:bookworm-slim AS stainless
+
+RUN apt-get update && apt-get install -y \
+ nodejs \
+ npm \
+ yarnpkg \
+ && apt-get clean autoclean
+
+# Ensure UTF-8 encoding
+ENV LANG=C.UTF-8
+ENV LC_ALL=C.UTF-8
+
+# Yarn
+RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn
+
+WORKDIR /workspace
+
+COPY package.json yarn.lock /workspace/
+
+RUN yarn install
+
+COPY . /workspace
From 09eb01ddeb7496eb3badd068dba2fb9c1198fddf Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 6 Dec 2025 03:39:05 +0000
Subject: [PATCH 10/18] chore(internal): codegen related update
---
.devcontainer/Dockerfile | 23 -----------------------
1 file changed, 23 deletions(-)
delete mode 100644 .devcontainer/Dockerfile
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
deleted file mode 100644
index 8ea34be96..000000000
--- a/.devcontainer/Dockerfile
+++ /dev/null
@@ -1,23 +0,0 @@
-# syntax=docker/dockerfile:1
-FROM debian:bookworm-slim AS stainless
-
-RUN apt-get update && apt-get install -y \
- nodejs \
- npm \
- yarnpkg \
- && apt-get clean autoclean
-
-# Ensure UTF-8 encoding
-ENV LANG=C.UTF-8
-ENV LC_ALL=C.UTF-8
-
-# Yarn
-RUN ln -sf /usr/bin/yarnpkg /usr/bin/yarn
-
-WORKDIR /workspace
-
-COPY package.json yarn.lock /workspace/
-
-RUN yarn install
-
-COPY . /workspace
From 3e8406bb8b29a4e2cf87e89c22be7a8e5ecebf39 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 19:06:07 +0000
Subject: [PATCH 11/18] feat(devbox): return user for createSshKey
---
.stats.yml | 4 +-
api.md | 2 -
src/index.ts | 2 -
src/resources/devboxes/devboxes.ts | 5 +
src/resources/shared.ts | 117 ++++++++++--------
tests/api-resources/blueprints.test.ts | 2 -
tests/api-resources/devboxes/devboxes.test.ts | 1 -
7 files changed, 75 insertions(+), 58 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0ab1f506b..0cb6f9948 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-cb2d725f71e87810cd872eacd70e867ca10f94980fdf9c78bb2844c02ee47bf3.yml
-openapi_spec_hash: 16ce3e9184fc2afdee66db18a83a96e8
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b92a4ee1d2c5382b0d77ec6a16e2e03b79bfd0a08cd75e28ee219350d5b6c5c6.yml
+openapi_spec_hash: 20d89d072b105d18e5bb8f73adb75063
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/api.md b/api.md
index 54c2fa2f5..847aff9e1 100644
--- a/api.md
+++ b/api.md
@@ -3,12 +3,10 @@
Types:
- AfterIdle
-- AgentMountParameters
- AgentSource
- CodeMountParameters
- LaunchParameters
- Mount
-- ObjectMountParameters
- RunProfile
# Benchmarks
diff --git a/src/index.ts b/src/index.ts
index 59536fcb2..d38768874 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -590,12 +590,10 @@ export declare namespace Runloop {
};
export type AfterIdle = API.AfterIdle;
- export type AgentMountParameters = API.AgentMountParameters;
export type AgentSource = API.AgentSource;
export type CodeMountParameters = API.CodeMountParameters;
export type LaunchParameters = API.LaunchParameters;
export type Mount = API.Mount;
- export type ObjectMountParameters = API.ObjectMountParameters;
export type RunProfile = API.RunProfile;
}
diff --git a/src/resources/devboxes/devboxes.ts b/src/resources/devboxes/devboxes.ts
index 028d9a168..a7b2baf41 100644
--- a/src/resources/devboxes/devboxes.ts
+++ b/src/resources/devboxes/devboxes.ts
@@ -865,6 +865,11 @@ export interface DevboxCreateSSHKeyResponse {
*/
ssh_private_key: string;
+ /**
+ * The Linux user to use for SSH connections to this Devbox.
+ */
+ ssh_user: string;
+
/**
* The host url of the Devbox that can be used for SSH.
*/
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 8b95be6e5..98752f3e9 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -12,32 +12,6 @@ export interface AfterIdle {
on_idle: 'shutdown' | 'suspend';
}
-export interface AgentMountParameters {
- /**
- * The ID of the agent to mount. Either agent_id or name must be set.
- */
- agent_id: string | null;
-
- /**
- * The name of the agent to mount. Returns the most recent agent with a matching
- * name if no agent id string provided. Either agent id or name must be set
- */
- agent_name: string | null;
-
- type: 'agent_mount';
-
- /**
- * Path to mount the agent on the Devbox. Required for git and object agents. Use
- * absolute path (e.g., /home/user/agent)
- */
- agent_path?: string | null;
-
- /**
- * Optional auth token for private repositories. Only used for git agents.
- */
- auth_token?: string | null;
-}
-
/**
* Agent source configuration.
*/
@@ -167,8 +141,6 @@ export interface CodeMountParameters {
*/
repo_owner: string;
- type: 'code_mount';
-
/**
* The authentication token necessary to pull repo.
*/
@@ -276,14 +248,76 @@ export namespace LaunchParameters {
}
}
-export type Mount =
- | ObjectMountParameters
- | AgentMountParameters
- | CodeMountParameters
- | Mount.FileMountParameters;
+export type Mount = Mount.ObjectMount | Mount.AgentMount | Mount.CodeMount | Mount.FileMount;
export namespace Mount {
- export interface FileMountParameters {
+ export interface ObjectMount {
+ /**
+ * The ID of the object to write.
+ */
+ object_id: string;
+
+ /**
+ * The path to write the object on the Devbox. Use absolute path of object (ie
+ * /home/user/object.txt, or directory if archive /home/user/archive_dir)
+ */
+ object_path: string;
+
+ type: 'object_mount';
+ }
+
+ export interface AgentMount {
+ /**
+ * The ID of the agent to mount. Either agent_id or name must be set.
+ */
+ agent_id: string | null;
+
+ /**
+ * The name of the agent to mount. Returns the most recent agent with a matching
+ * name if no agent id string provided. Either agent id or name must be set
+ */
+ agent_name: string | null;
+
+ type: 'agent_mount';
+
+ /**
+ * Path to mount the agent on the Devbox. Required for git and object agents. Use
+ * absolute path (e.g., /home/user/agent)
+ */
+ agent_path?: string | null;
+
+ /**
+ * Optional auth token for private repositories. Only used for git agents.
+ */
+ auth_token?: string | null;
+ }
+
+ export interface CodeMount {
+ /**
+ * The name of the repo to mount. By default, code will be mounted at
+ * /home/user/{repo_name}s.
+ */
+ repo_name: string;
+
+ /**
+ * The owner of the repo.
+ */
+ repo_owner: string;
+
+ type: 'code_mount';
+
+ /**
+ * The authentication token necessary to pull repo.
+ */
+ token?: string | null;
+
+ /**
+ * Installation command to install and setup repository.
+ */
+ install_command?: string | null;
+ }
+
+ export interface FileMount {
/**
* Content of the file to mount.
*/
@@ -298,21 +332,6 @@ export namespace Mount {
}
}
-export interface ObjectMountParameters {
- /**
- * The ID of the object to write.
- */
- object_id: string;
-
- /**
- * The path to write the object on the Devbox. Use absolute path of object (ie
- * /home/user/object.txt, or directory if archive /home/user/archive_dir)
- */
- object_path: string;
-
- type: 'object_mount';
-}
-
export interface RunProfile {
/**
* Mapping of Environment Variable to Value. May be shown in devbox logging.
diff --git a/tests/api-resources/blueprints.test.ts b/tests/api-resources/blueprints.test.ts
index f781eb437..ad2bd35d0 100644
--- a/tests/api-resources/blueprints.test.ts
+++ b/tests/api-resources/blueprints.test.ts
@@ -31,7 +31,6 @@ describe('resource blueprints', () => {
{
repo_name: 'repo_name',
repo_owner: 'repo_owner',
- type: 'code_mount',
token: 'token',
install_command: 'install_command',
},
@@ -261,7 +260,6 @@ describe('resource blueprints', () => {
{
repo_name: 'repo_name',
repo_owner: 'repo_owner',
- type: 'code_mount',
token: 'token',
install_command: 'install_command',
},
diff --git a/tests/api-resources/devboxes/devboxes.test.ts b/tests/api-resources/devboxes/devboxes.test.ts
index cba3193d9..30eb681b6 100644
--- a/tests/api-resources/devboxes/devboxes.test.ts
+++ b/tests/api-resources/devboxes/devboxes.test.ts
@@ -39,7 +39,6 @@ describe('resource devboxes', () => {
{
repo_name: 'repo_name',
repo_owner: 'repo_owner',
- type: 'code_mount',
token: 'token',
install_command: 'install_command',
},
From e040bc2bd4411dd566fbe6e339055403eb52bfca Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Mon, 8 Dec 2025 20:23:37 +0000
Subject: [PATCH 12/18] feat(devbox): default to x86 arch
---
.stats.yml | 4 ++--
src/resources/shared.ts | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index 0cb6f9948..ca5e82df9 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-b92a4ee1d2c5382b0d77ec6a16e2e03b79bfd0a08cd75e28ee219350d5b6c5c6.yml
-openapi_spec_hash: 20d89d072b105d18e5bb8f73adb75063
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-f2df3524e4b99c38b634c334d098aa2c7d543d5ea0f49c4dd8f4d92723b81b94.yml
+openapi_spec_hash: c377abec5716d1d6c5b01a527a5bfdfb
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index 98752f3e9..b66aeb78b 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -165,7 +165,7 @@ export interface LaunchParameters {
after_idle?: AfterIdle | null;
/**
- * The target architecture for the Devbox. If unset, defaults to arm64.
+ * The target architecture for the Devbox. If unset, defaults to x86_64.
*/
architecture?: 'x86_64' | 'arm64' | null;
From 2610c5d9207fab989f335633e9b8034d6905afd0 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 13 Dec 2025 00:58:04 +0000
Subject: [PATCH 13/18] feat(devbox): added stdin streaming endpoint
---
.stats.yml | 4 +--
src/resources/agents.ts | 20 ++++++++++++++
src/resources/benchmarks/benchmarks.ts | 9 +++++--
src/resources/benchmarks/runs.ts | 5 ++++
src/resources/blueprints.ts | 10 +++++++
src/resources/scenarios/runs.ts | 15 +++++++++++
src/resources/scenarios/scenarios.ts | 5 ++++
src/resources/secrets.ts | 2 +-
src/resources/shared.ts | 10 -------
tests/api-resources/agents.test.ts | 26 +++++++++----------
.../benchmarks/benchmarks.test.ts | 2 +-
tests/api-resources/benchmarks/runs.test.ts | 2 +-
tests/api-resources/blueprints.test.ts | 4 +--
tests/api-resources/scenarios/runs.test.ts | 9 ++++++-
.../api-resources/scenarios/scenarios.test.ts | 8 +++++-
15 files changed, 96 insertions(+), 35 deletions(-)
diff --git a/.stats.yml b/.stats.yml
index ca5e82df9..4cce660dc 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
configured_endpoints: 97
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-f2df3524e4b99c38b634c334d098aa2c7d543d5ea0f49c4dd8f4d92723b81b94.yml
-openapi_spec_hash: c377abec5716d1d6c5b01a527a5bfdfb
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/runloop-ai%2Frunloop-370a5d676ff0ef41f3ca6ed669d29b6e3e6b7f0a914ac3dbed6bd45e75533c74.yml
+openapi_spec_hash: 7bb5ea1117d754b7985aff0da5bca3a7
config_hash: 2363f563f42501d2b1587a4f64bdccaf
diff --git a/src/resources/agents.ts b/src/resources/agents.ts
index 4c090332b..c895ff513 100644
--- a/src/resources/agents.ts
+++ b/src/resources/agents.ts
@@ -52,6 +52,11 @@ export interface AgentCreateParameters {
*/
name: string;
+ /**
+ * The version of the Agent. Must be a semver string (e.g., '2.0.65') or a SHA.
+ */
+ version: string;
+
/**
* The source configuration for the Agent.
*/
@@ -107,6 +112,11 @@ export interface AgentView {
*/
name: string;
+ /**
+ * The version of the Agent. A semver string (e.g., '2.0.65') or a SHA.
+ */
+ version: string;
+
/**
* The source configuration for the Agent.
*/
@@ -119,6 +129,11 @@ export interface AgentCreateParams {
*/
name: string;
+ /**
+ * The version of the Agent. Must be a semver string (e.g., '2.0.65') or a SHA.
+ */
+ version: string;
+
/**
* The source configuration for the Agent.
*/
@@ -140,6 +155,11 @@ export interface AgentListParams extends AgentsCursorIDPageParams {
* Search by agent ID or name.
*/
search?: string;
+
+ /**
+ * Filter by version. Use 'latest' to get the most recently created agent.
+ */
+ version?: string;
}
Agents.AgentViewsAgentsCursorIDPage = AgentViewsAgentsCursorIDPage;
diff --git a/src/resources/benchmarks/benchmarks.ts b/src/resources/benchmarks/benchmarks.ts
index 266e538ad..e00c617e7 100644
--- a/src/resources/benchmarks/benchmarks.ts
+++ b/src/resources/benchmarks/benchmarks.ts
@@ -405,11 +405,16 @@ export interface BenchmarkUpdateParams {
scenario_ids?: Array | null;
}
-export interface BenchmarkListParams extends BenchmarksCursorIDPageParams {}
+export interface BenchmarkListParams extends BenchmarksCursorIDPageParams {
+ /**
+ * Filter by name
+ */
+ name?: string;
+}
export interface BenchmarkDefinitionsParams {
/**
- * The limit of items to return. Default is 20.
+ * The limit of items to return. Default is 20. Max is 5000.
*/
limit?: number;
diff --git a/src/resources/benchmarks/runs.ts b/src/resources/benchmarks/runs.ts
index f732a09a3..18ce250d0 100644
--- a/src/resources/benchmarks/runs.ts
+++ b/src/resources/benchmarks/runs.ts
@@ -87,6 +87,11 @@ export interface RunListParams extends BenchmarkRunsCursorIDPageParams {
* The Benchmark ID to filter by.
*/
benchmark_id?: string;
+
+ /**
+ * Filter by name
+ */
+ name?: string;
}
export interface RunListScenarioRunsParams extends BenchmarkRunsCursorIDPageParams {
diff --git a/src/resources/blueprints.ts b/src/resources/blueprints.ts
index 8d501c22c..7d46dd8fa 100644
--- a/src/resources/blueprints.ts
+++ b/src/resources/blueprints.ts
@@ -740,6 +740,11 @@ export interface BlueprintListParams extends BlueprintsCursorIDPageParams {
* Filter by name
*/
name?: string;
+
+ /**
+ * Filter by build status (queued, provisioning, building, failed, build_complete)
+ */
+ status?: string;
}
export interface BlueprintCreateFromInspectionParams {
@@ -788,6 +793,11 @@ export interface BlueprintListPublicParams extends BlueprintsCursorIDPageParams
* Filter by name
*/
name?: string;
+
+ /**
+ * Filter by build status (queued, provisioning, building, failed, build_complete)
+ */
+ status?: string;
}
export interface BlueprintPreviewParams {
diff --git a/src/resources/scenarios/runs.ts b/src/resources/scenarios/runs.ts
index 0146e3781..61ac0e939 100644
--- a/src/resources/scenarios/runs.ts
+++ b/src/resources/scenarios/runs.ts
@@ -131,10 +131,25 @@ export class Runs extends APIResource {
}
export interface RunListParams extends BenchmarkRunsCursorIDPageParams {
+ /**
+ * Filter by benchmark run ID
+ */
+ benchmark_run_id?: string;
+
+ /**
+ * Filter by name
+ */
+ name?: string;
+
/**
* Filter runs associated to Scenario given ID
*/
scenario_id?: string;
+
+ /**
+ * Filter by state
+ */
+ state?: string;
}
export declare namespace Runs {
diff --git a/src/resources/scenarios/scenarios.ts b/src/resources/scenarios/scenarios.ts
index 8407de1c2..740066699 100644
--- a/src/resources/scenarios/scenarios.ts
+++ b/src/resources/scenarios/scenarios.ts
@@ -799,6 +799,11 @@ export interface ScenarioListParams extends ScenariosCursorIDPageParams {
* Query for Scenarios with a given name.
*/
name?: string;
+
+ /**
+ * Filter by validation type
+ */
+ validation_type?: string;
}
export interface ScenarioListPublicParams extends ScenariosCursorIDPageParams {
diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts
index 86f78f59e..305b61dd3 100644
--- a/src/resources/secrets.ts
+++ b/src/resources/secrets.ts
@@ -154,7 +154,7 @@ export interface SecretUpdateParams {
export interface SecretListParams {
/**
- * The limit of items to return. Default is 20.
+ * The limit of items to return. Default is 20. Max is 5000.
*/
limit?: number;
}
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index b66aeb78b..cfb476bc1 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -77,11 +77,6 @@ export namespace AgentSource {
*/
agent_setup?: Array | null;
- /**
- * NPM version constraint
- */
- npm_version?: string | null;
-
/**
* NPM registry URL
*/
@@ -117,11 +112,6 @@ export namespace AgentSource {
*/
agent_setup?: Array | null;
- /**
- * Pip version constraint
- */
- pip_version?: string | null;
-
/**
* Pip registry URL
*/
diff --git a/tests/api-resources/agents.test.ts b/tests/api-resources/agents.test.ts
index 6513f221d..3922a1ef6 100644
--- a/tests/api-resources/agents.test.ts
+++ b/tests/api-resources/agents.test.ts
@@ -10,7 +10,7 @@ const client = new Runloop({
describe('resource agents', () => {
test('create: only required params', async () => {
- const responsePromise = client.agents.create({ name: 'name' });
+ const responsePromise = client.agents.create({ name: 'name', version: 'version' });
const rawResponse = await responsePromise.asResponse();
expect(rawResponse).toBeInstanceOf(Response);
const response = await responsePromise;
@@ -23,22 +23,13 @@ describe('resource agents', () => {
test('create: required and optional params', async () => {
const response = await client.agents.create({
name: 'name',
+ version: 'version',
source: {
type: 'type',
git: { repository: 'repository', agent_setup: ['string'], ref: 'ref' },
- npm: {
- package_name: 'package_name',
- agent_setup: ['string'],
- npm_version: 'npm_version',
- registry_url: 'registry_url',
- },
+ npm: { package_name: 'package_name', agent_setup: ['string'], registry_url: 'registry_url' },
object: { object_id: 'object_id', agent_setup: ['string'] },
- pip: {
- package_name: 'package_name',
- agent_setup: ['string'],
- pip_version: 'pip_version',
- registry_url: 'registry_url',
- },
+ pip: { package_name: 'package_name', agent_setup: ['string'], registry_url: 'registry_url' },
},
});
});
@@ -83,7 +74,14 @@ describe('resource agents', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.agents.list(
- { is_public: true, limit: 0, name: 'name', search: 'search', starting_after: 'starting_after' },
+ {
+ is_public: true,
+ limit: 0,
+ name: 'name',
+ search: 'search',
+ starting_after: 'starting_after',
+ version: 'version',
+ },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
diff --git a/tests/api-resources/benchmarks/benchmarks.test.ts b/tests/api-resources/benchmarks/benchmarks.test.ts
index d1850e6ba..6e9c1a4ee 100644
--- a/tests/api-resources/benchmarks/benchmarks.test.ts
+++ b/tests/api-resources/benchmarks/benchmarks.test.ts
@@ -95,7 +95,7 @@ describe('resource benchmarks', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.benchmarks.list(
- { limit: 0, starting_after: 'starting_after' },
+ { limit: 0, name: 'name', starting_after: 'starting_after' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
diff --git a/tests/api-resources/benchmarks/runs.test.ts b/tests/api-resources/benchmarks/runs.test.ts
index 1afd23582..b4dae3887 100644
--- a/tests/api-resources/benchmarks/runs.test.ts
+++ b/tests/api-resources/benchmarks/runs.test.ts
@@ -49,7 +49,7 @@ describe('resource runs', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.benchmarks.runs.list(
- { benchmark_id: 'benchmark_id', limit: 0, starting_after: 'starting_after' },
+ { benchmark_id: 'benchmark_id', limit: 0, name: 'name', starting_after: 'starting_after' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
diff --git a/tests/api-resources/blueprints.test.ts b/tests/api-resources/blueprints.test.ts
index ad2bd35d0..2aad9a94e 100644
--- a/tests/api-resources/blueprints.test.ts
+++ b/tests/api-resources/blueprints.test.ts
@@ -131,7 +131,7 @@ describe('resource blueprints', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.blueprints.list(
- { limit: 0, name: 'name', starting_after: 'starting_after' },
+ { limit: 0, name: 'name', starting_after: 'starting_after', status: 'status' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
@@ -215,7 +215,7 @@ describe('resource blueprints', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.blueprints.listPublic(
- { limit: 0, name: 'name', starting_after: 'starting_after' },
+ { limit: 0, name: 'name', starting_after: 'starting_after', status: 'status' },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
diff --git a/tests/api-resources/scenarios/runs.test.ts b/tests/api-resources/scenarios/runs.test.ts
index e18aac9bc..0997ff36f 100644
--- a/tests/api-resources/scenarios/runs.test.ts
+++ b/tests/api-resources/scenarios/runs.test.ts
@@ -49,7 +49,14 @@ describe('resource runs', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.scenarios.runs.list(
- { limit: 0, scenario_id: 'scenario_id', starting_after: 'starting_after' },
+ {
+ benchmark_run_id: 'benchmark_run_id',
+ limit: 0,
+ name: 'name',
+ scenario_id: 'scenario_id',
+ starting_after: 'starting_after',
+ state: 'state',
+ },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
diff --git a/tests/api-resources/scenarios/scenarios.test.ts b/tests/api-resources/scenarios/scenarios.test.ts
index d3f185a50..72930d937 100644
--- a/tests/api-resources/scenarios/scenarios.test.ts
+++ b/tests/api-resources/scenarios/scenarios.test.ts
@@ -185,7 +185,13 @@ describe('resource scenarios', () => {
// ensure the request options are being passed correctly by passing an invalid HTTP method in order to cause an error
await expect(
client.scenarios.list(
- { benchmark_id: 'benchmark_id', limit: 0, name: 'name', starting_after: 'starting_after' },
+ {
+ benchmark_id: 'benchmark_id',
+ limit: 0,
+ name: 'name',
+ starting_after: 'starting_after',
+ validation_type: 'validation_type',
+ },
{ path: '/_stainless_unknown_path' },
),
).rejects.toThrow(Runloop.NotFoundError);
From 18414051998e62ae9a15f5bf10a90a53e9d46ec3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
<142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 13 Dec 2025 00:58:25 +0000
Subject: [PATCH 14/18] release: 1.1.0
---
.release-please-manifest.json | 2 +-
CHANGELOG.md | 30 ++++++++++++++++++++++++++++++
package-lock.json | 4 ++--
package.json | 2 +-
src/version.ts | 2 +-
5 files changed, 35 insertions(+), 5 deletions(-)
diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index 37fcefaab..5fdd88304 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "1.0.0"
+ ".": "1.1.0"
}
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 92b7eb321..78925691b 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,35 @@
# Changelog
+## 1.1.0 (2025-12-13)
+
+Full Changelog: [v1.0.0...v1.1.0](https://github.com/runloopai/api-client-ts/compare/v1.0.0...v1.1.0)
+
+### Features
+
+* **blueprints:** Add build context to the OpenAPI spec ([#6494](https://github.com/runloopai/api-client-ts/issues/6494)) ([e295c86](https://github.com/runloopai/api-client-ts/commit/e295c861c54be8320cf3a049023722159e1566d9))
+* **devbox:** added stdin streaming endpoint ([2610c5d](https://github.com/runloopai/api-client-ts/commit/2610c5d9207fab989f335633e9b8034d6905afd0))
+* **devbox:** added suspend async and promoted suspend to automatically await the devbox running ([#670](https://github.com/runloopai/api-client-ts/issues/670)) ([e814e00](https://github.com/runloopai/api-client-ts/commit/e814e000496e923023e525b038efcb39e34b4cdd))
+* **devbox:** default to x86 arch ([e040bc2](https://github.com/runloopai/api-client-ts/commit/e040bc2bd4411dd566fbe6e339055403eb52bfca))
+* **devbox:** return user for createSshKey ([3e8406b](https://github.com/runloopai/api-client-ts/commit/3e8406bb8b29a4e2cf87e89c22be7a8e5ecebf39))
+* **ignore matcher:** support for .dockerignore for build context ([#673](https://github.com/runloopai/api-client-ts/issues/673)) ([a843d54](https://github.com/runloopai/api-client-ts/commit/a843d54b93a69ea4cf8bf22475fd0cf6b04ba98b))
+
+
+### Bug Fixes
+
+* **api:** don't ignore devbox keep_alive, suspend and resume in api ([a5143ef](https://github.com/runloopai/api-client-ts/commit/a5143eff331d3404e1649ec57f01e67ea18b6613))
+* **devbox:** launch parameter typo ([2ef3ede](https://github.com/runloopai/api-client-ts/commit/2ef3ede2bbc71b79f111ab9c0326573f44dfab4c))
+* **mcp:** correct code tool API endpoint ([8932b2d](https://github.com/runloopai/api-client-ts/commit/8932b2d7b4bc2a5c50487db572286448d388e6ea))
+* **mcp:** return correct lines on typescript errors ([4ebe08c](https://github.com/runloopai/api-client-ts/commit/4ebe08c525a71cecb26e78a3a52602efb40fb968))
+* **scorer:** fixed RL_TEST_CONTEXT to RL_SCORER_CONTEXT ([e810958](https://github.com/runloopai/api-client-ts/commit/e810958cdab4b067d91f7a2e3cec481b44a5a7d9))
+
+
+### Chores
+
+* hide build context APIs ([8ea7bba](https://github.com/runloopai/api-client-ts/commit/8ea7bba5cd9cd9d047091386025965edeb316ab4))
+* **internal:** codegen related update ([09eb01d](https://github.com/runloopai/api-client-ts/commit/09eb01ddeb7496eb3badd068dba2fb9c1198fddf))
+* **internal:** codegen related update ([83d2d6c](https://github.com/runloopai/api-client-ts/commit/83d2d6cb029c72383fdece53d3850af5416447a1))
+* **mounts:** Update documentation for deprecated fields to direct the user to the replacement API ([1e68146](https://github.com/runloopai/api-client-ts/commit/1e6814677b20e12513da0faaa3cd4414a4d3df6e))
+
## 1.0.0 (2025-12-01)
Full Changelog: [v0.69.0...v1.0.0](https://github.com/runloopai/api-client-ts/compare/v0.69.0...v1.0.0)
diff --git a/package-lock.json b/package-lock.json
index 3afd4f0c5..4243f4ed0 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "@runloop/api-client",
- "version": "1.0.0",
+ "version": "1.1.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "@runloop/api-client",
- "version": "1.0.0",
+ "version": "1.1.0",
"license": "MIT",
"dependencies": {
"@types/node": "^18.11.18",
diff --git a/package.json b/package.json
index 2be2d1c00..8e1a406ee 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@runloop/api-client",
- "version": "1.0.0",
+ "version": "1.1.0",
"description": "The official TypeScript library for the Runloop API",
"author": "Runloop ",
"types": "dist/sdk.d.ts",
diff --git a/src/version.ts b/src/version.ts
index bea2896f0..c80f9757e 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '1.0.0'; // x-release-please-version
+export const VERSION = '1.1.0'; // x-release-please-version
From d09e73f69b635177ca0e2afb8162a0ae12169bea Mon Sep 17 00:00:00 2001
From: Albert Li
Date: Fri, 12 Dec 2025 17:13:46 -0800
Subject: [PATCH 15/18] Fix types
---
tests/objects/agent.test.ts | 20 +++++++++++++++----
tests/sdk/agent-ops.test.ts | 17 ++++++++++++++++
.../smoketests/object-oriented/agent.test.ts | 16 ++++++++++++---
3 files changed, 46 insertions(+), 7 deletions(-)
diff --git a/tests/objects/agent.test.ts b/tests/objects/agent.test.ts
index a8600c82b..fa8af04f3 100644
--- a/tests/objects/agent.test.ts
+++ b/tests/objects/agent.test.ts
@@ -23,6 +23,7 @@ describe('Agent (SDK)', () => {
id: 'agent-123',
create_time_ms: Date.now(),
name: 'test-agent',
+ version: '1.0.0',
is_public: false,
source: {
type: 'npm',
@@ -39,6 +40,7 @@ describe('Agent (SDK)', () => {
const agent = await Agent.create(mockClient, {
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -50,6 +52,7 @@ describe('Agent (SDK)', () => {
expect(mockClient.agents.create).toHaveBeenCalledWith(
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -78,6 +81,7 @@ describe('Agent (SDK)', () => {
const agent = await Agent.create(mockClient, {
name: 'git-agent',
+ version: '1.0.0',
source: {
type: 'git',
git: {
@@ -90,6 +94,7 @@ describe('Agent (SDK)', () => {
expect(mockClient.agents.create).toHaveBeenCalledWith(
{
name: 'git-agent',
+ version: '1.0.0',
source: {
type: 'git',
git: {
@@ -117,6 +122,7 @@ describe('Agent (SDK)', () => {
await Agent.create(mockClient, {
name: 'pip-agent',
+ version: '1.0.0',
source: {
type: 'pip',
pip: {
@@ -128,6 +134,7 @@ describe('Agent (SDK)', () => {
expect(mockClient.agents.create).toHaveBeenCalledWith(
{
name: 'pip-agent',
+ version: '1.0.0',
source: {
type: 'pip',
pip: {
@@ -152,9 +159,9 @@ describe('Agent (SDK)', () => {
describe('list', () => {
it('should list agents and return Agent instances', async () => {
const mockAgents = [
- { id: 'agent-001', name: 'first-agent', create_time_ms: Date.now(), is_public: false },
- { id: 'agent-002', name: 'second-agent', create_time_ms: Date.now(), is_public: true },
- { id: 'agent-003', name: 'third-agent', create_time_ms: Date.now(), is_public: false },
+ { id: 'agent-001', name: 'first-agent', version: '1.0.0', create_time_ms: Date.now(), is_public: false },
+ { id: 'agent-002', name: 'second-agent', version: '1.0.0', create_time_ms: Date.now(), is_public: true },
+ { id: 'agent-003', name: 'third-agent', version: '1.0.0', create_time_ms: Date.now(), is_public: false },
];
// Mock async iterator
@@ -181,7 +188,7 @@ describe('Agent (SDK)', () => {
it('should pass filter parameters to list', async () => {
const asyncIterator = {
async *[Symbol.asyncIterator]() {
- yield { id: 'agent-001', name: 'filtered-agent', create_time_ms: Date.now(), is_public: false };
+ yield { id: 'agent-001', name: 'filtered-agent', version: '1.0.0', create_time_ms: Date.now(), is_public: false };
},
};
@@ -214,6 +221,7 @@ describe('Agent (SDK)', () => {
mockClient.agents.create.mockResolvedValue(mockAgentData);
agent = await Agent.create(mockClient, {
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -259,6 +267,7 @@ describe('Agent (SDK)', () => {
await expect(
Agent.create(mockClient, {
name: 'failing-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -293,12 +302,14 @@ describe('Agent (SDK)', () => {
id: 'agent-minimal',
create_time_ms: Date.now(),
name: 'minimal',
+ version: '1.0.0',
is_public: false,
};
mockClient.agents.create.mockResolvedValue(minimalData);
const agent = await Agent.create(mockClient, {
name: 'minimal',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -325,6 +336,7 @@ describe('Agent (SDK)', () => {
const agent = await Agent.create(mockClient, {
name: 'object-agent',
+ version: '1.0.0',
source: {
type: 'object',
object: {
diff --git a/tests/sdk/agent-ops.test.ts b/tests/sdk/agent-ops.test.ts
index c8bbc1653..d082158b7 100644
--- a/tests/sdk/agent-ops.test.ts
+++ b/tests/sdk/agent-ops.test.ts
@@ -28,6 +28,7 @@ describe('AgentOps', () => {
id: 'agent-123',
create_time_ms: Date.now(),
name: 'test-agent',
+ version: '1.0.0',
is_public: false,
source: {
type: 'npm',
@@ -46,6 +47,7 @@ describe('AgentOps', () => {
it('should create an agent from npm package', async () => {
await agentOps.createFromNpm({
name: 'test-agent',
+ version: '1.0.0',
package_name: '@runloop/example-agent',
});
@@ -53,6 +55,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -67,6 +70,7 @@ describe('AgentOps', () => {
it('should create an agent with all npm options', async () => {
await agentOps.createFromNpm({
name: 'test-agent',
+ version: '1.0.0',
package_name: '@runloop/example-agent',
npm_version: '1.2.3',
registry_url: 'https://registry.example.com',
@@ -77,6 +81,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -96,6 +101,7 @@ describe('AgentOps', () => {
it('should create an agent from pip package', async () => {
await agentOps.createFromPip({
name: 'test-agent',
+ version: '1.0.0',
package_name: 'runloop-example-agent',
});
@@ -103,6 +109,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'pip',
pip: {
@@ -117,6 +124,7 @@ describe('AgentOps', () => {
it('should create an agent with all pip options', async () => {
await agentOps.createFromPip({
name: 'test-agent',
+ version: '1.0.0',
package_name: 'runloop-example-agent',
pip_version: '1.2.3',
registry_url: 'https://pypi.example.com',
@@ -127,6 +135,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'pip',
pip: {
@@ -146,6 +155,7 @@ describe('AgentOps', () => {
it('should create an agent from git repository', async () => {
await agentOps.createFromGit({
name: 'test-agent',
+ version: '1.0.0',
repository: 'https://github.com/example/agent-repo',
});
@@ -153,6 +163,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'git',
git: {
@@ -167,6 +178,7 @@ describe('AgentOps', () => {
it('should create an agent with all git options', async () => {
await agentOps.createFromGit({
name: 'test-agent',
+ version: '1.0.0',
repository: 'https://github.com/example/agent-repo',
ref: 'develop',
agent_setup: ['npm install', 'npm run build'],
@@ -176,6 +188,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'git',
git: {
@@ -194,6 +207,7 @@ describe('AgentOps', () => {
it('should create an agent from object', async () => {
await agentOps.createFromObject({
name: 'test-agent',
+ version: '1.0.0',
object_id: 'obj_123',
});
@@ -201,6 +215,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'object',
object: {
@@ -215,6 +230,7 @@ describe('AgentOps', () => {
it('should create an agent with agent_setup', async () => {
await agentOps.createFromObject({
name: 'test-agent',
+ version: '1.0.0',
object_id: 'obj_123',
agent_setup: ['chmod +x setup.sh', './setup.sh'],
});
@@ -223,6 +239,7 @@ describe('AgentOps', () => {
mockClient,
{
name: 'test-agent',
+ version: '1.0.0',
source: {
type: 'object',
object: {
diff --git a/tests/smoketests/object-oriented/agent.test.ts b/tests/smoketests/object-oriented/agent.test.ts
index 6ff8bd107..ed880a828 100644
--- a/tests/smoketests/object-oriented/agent.test.ts
+++ b/tests/smoketests/object-oriented/agent.test.ts
@@ -11,6 +11,7 @@ describe('smoketest: object-oriented agent', () => {
const name = uniqueName('sdk-agent-test-basic');
const agent = await runloop.agent.create({
name: name,
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -42,6 +43,7 @@ describe('smoketest: object-oriented agent', () => {
const name = uniqueName('sdk-agent-test-info');
const agent = await runloop.agent.create({
name: name,
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -84,6 +86,7 @@ describe('smoketest: object-oriented agent', () => {
// Create an agent
const created = await runloop.agent.create({
name: uniqueName('sdk-agent-test-retrieve'),
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -118,9 +121,9 @@ describe('smoketest: object-oriented agent', () => {
};
// Create multiple agents
- const agent1 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-1'), source: sourceConfig });
- const agent2 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-2'), source: sourceConfig });
- const agent3 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-3'), source: sourceConfig });
+ const agent1 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-1'), version: '1.0.0', source: sourceConfig });
+ const agent2 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-2'), version: '1.0.0', source: sourceConfig });
+ const agent3 = await runloop.agent.create({ name: uniqueName('sdk-agent-test-list-3'), version: '1.0.0', source: sourceConfig });
try {
// List agents
@@ -151,6 +154,7 @@ describe('smoketest: object-oriented agent', () => {
const agent = await runloop.agent.create({
name: name,
+ version: '1.0.0',
source: {
type: 'npm',
npm: {
@@ -179,6 +183,7 @@ describe('smoketest: object-oriented agent', () => {
const agent = await runloop.agent.create({
name: name,
+ version: '1.0.0',
source: {
type: 'git',
git: {
@@ -209,6 +214,7 @@ describe('smoketest: object-oriented agent', () => {
const name = uniqueName('sdk-agent-from-npm');
const agent = await runloop.agent.createFromNpm({
name: name,
+ version: '1.0.0',
package_name: '@runloop/hello-world-agent',
});
@@ -231,6 +237,7 @@ describe('smoketest: object-oriented agent', () => {
const name = uniqueName('sdk-agent-from-pip');
const agent = await runloop.agent.createFromPip({
name: name,
+ version: '1.0.0',
package_name: 'runloop-example-agent',
});
@@ -253,6 +260,7 @@ describe('smoketest: object-oriented agent', () => {
const name = uniqueName('sdk-agent-from-git');
const agent = await runloop.agent.createFromGit({
name: name,
+ version: '1.0.0',
repository: 'https://github.com/runloop/example-agent',
ref: 'main',
});
@@ -291,6 +299,7 @@ describe('smoketest: object-oriented agent', () => {
const agentName = uniqueName('sdk-agent-from-object');
agent = await runloop.agent.createFromObject({
name: agentName,
+ version: '1.0.0',
object_id: storageObject.id,
});
@@ -332,6 +341,7 @@ describe('smoketest: object-oriented agent', () => {
// Create agent from storage object
agent = await runloop.agent.createFromObject({
name: uniqueName('sdk-agent-for-mount'),
+ version: '1.0.0',
object_id: storageObject.id,
});
From 22a66677d722ea8ee9591c3b750451c00c2075f7 Mon Sep 17 00:00:00 2001
From: Albert Li
Date: Fri, 12 Dec 2025 17:24:21 -0800
Subject: [PATCH 16/18] Fix smoke tests
---
src/sdk/storage-object.ts | 11 +--
yarn.lock | 198 ++++++++++++++++++++------------------
2 files changed, 106 insertions(+), 103 deletions(-)
diff --git a/src/sdk/storage-object.ts b/src/sdk/storage-object.ts
index c8ab0181d..bf0d6281c 100644
--- a/src/sdk/storage-object.ts
+++ b/src/sdk/storage-object.ts
@@ -6,6 +6,7 @@ import type {
ObjectDownloadURLView,
ObjectListParams,
} from '../resources/objects';
+import { fetch } from '../_shims/index';
import * as fs from 'node:fs/promises';
import * as fsSync from 'node:fs';
import * as os from 'node:os';
@@ -509,17 +510,13 @@ export class StorageObject {
throw new Error('No upload URL available. Object may already be completed or deleted.');
}
- // Upload the file from disk
+ // Upload the file from disk (read into buffer like uploadFromFile does)
try {
- const fileStream = fsSync.createReadStream(tmpFilePath);
- const stats = await fs.stat(tmpFilePath);
+ const fileBuffer = await fs.readFile(tmpFilePath);
const response = await fetch(uploadUrl, {
method: 'PUT',
- body: fileStream as any,
- headers: {
- 'Content-Length': stats.size.toString(),
- },
+ body: fileBuffer,
});
if (!response.ok) {
diff --git a/yarn.lock b/yarn.lock
index 8cbe1beba..b7d81ffc8 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -16,7 +16,7 @@
resolved "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.5.tgz"
integrity sha512-6uFXyCayocRbqhZOB+6XcuZbkMNimwfVGFji8CTZnCzOHVGvDqzvitu1re2AU5LROliz7eQPhB8CpAMvnx9EjA==
-"@babel/core@^7.0.0", "@babel/core@^7.0.0 || ^8.0.0-0", "@babel/core@^7.0.0-0", "@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9", "@babel/core@^7.8.0", "@babel/core@>=7.0.0-beta.0 <8":
+"@babel/core@^7.11.6", "@babel/core@^7.12.3", "@babel/core@^7.23.9":
version "7.28.5"
resolved "https://registry.npmjs.org/@babel/core/-/core-7.28.5.tgz"
integrity sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==
@@ -500,13 +500,6 @@
strip-ansi "^6.0.0"
v8-to-istanbul "^9.0.1"
-"@jest/schemas@^29.6.3":
- version "29.6.3"
- resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz"
- integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==
- dependencies:
- "@sinclair/typebox" "^0.27.8"
-
"@jest/schemas@30.0.5":
version "30.0.5"
resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-30.0.5.tgz"
@@ -514,6 +507,13 @@
dependencies:
"@sinclair/typebox" "^0.34.0"
+"@jest/schemas@^29.6.3":
+ version "29.6.3"
+ resolved "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz"
+ integrity sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==
+ dependencies:
+ "@sinclair/typebox" "^0.27.8"
+
"@jest/source-map@^29.6.3":
version "29.6.3"
resolved "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz"
@@ -543,7 +543,7 @@
jest-haste-map "^29.7.0"
slash "^3.0.0"
-"@jest/transform@^29.0.0 || ^30.0.0", "@jest/transform@^29.7.0":
+"@jest/transform@^29.7.0":
version "29.7.0"
resolved "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz"
integrity sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==
@@ -564,7 +564,7 @@
slash "^3.0.0"
write-file-atomic "^4.0.2"
-"@jest/types@^29.0.0 || ^30.0.0", "@jest/types@30.2.0":
+"@jest/types@30.2.0":
version "30.2.0"
resolved "https://registry.npmjs.org/@jest/types/-/types-30.2.0.tgz"
integrity sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==
@@ -615,14 +615,6 @@
resolved "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz"
integrity sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==
-"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
- version "0.3.31"
- resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz"
- integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
- dependencies:
- "@jridgewell/resolve-uri" "^3.1.0"
- "@jridgewell/sourcemap-codec" "^1.4.14"
-
"@jridgewell/trace-mapping@0.3.9":
version "0.3.9"
resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz"
@@ -631,6 +623,14 @@
"@jridgewell/resolve-uri" "^3.0.3"
"@jridgewell/sourcemap-codec" "^1.4.10"
+"@jridgewell/trace-mapping@^0.3.12", "@jridgewell/trace-mapping@^0.3.18", "@jridgewell/trace-mapping@^0.3.24", "@jridgewell/trace-mapping@^0.3.28":
+ version "0.3.31"
+ resolved "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz"
+ integrity sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==
+ dependencies:
+ "@jridgewell/resolve-uri" "^3.1.0"
+ "@jridgewell/sourcemap-codec" "^1.4.14"
+
"@material/material-color-utilities@^0.3.0":
version "0.3.0"
resolved "https://registry.npmjs.org/@material/material-color-utilities/-/material-color-utilities-0.3.0.tgz"
@@ -644,7 +644,7 @@
"@nodelib/fs.stat" "2.0.5"
run-parallel "^1.1.9"
-"@nodelib/fs.stat@^2.0.2", "@nodelib/fs.stat@2.0.5":
+"@nodelib/fs.stat@2.0.5", "@nodelib/fs.stat@^2.0.2":
version "2.0.5"
resolved "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz"
integrity sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==
@@ -684,7 +684,7 @@
dependencies:
"@shikijs/types" "3.15.0"
-"@shikijs/types@^3.15.0", "@shikijs/types@3.15.0":
+"@shikijs/types@3.15.0", "@shikijs/types@^3.15.0":
version "3.15.0"
resolved "https://registry.npmjs.org/@shikijs/types/-/types-3.15.0.tgz"
integrity sha512-BnP+y/EQnhihgHy4oIAN+6FFtmfTekwOLsQbRw9hOKwqgNy8Bdsjq8B05oAt/ZgvIWWFrshV71ytOrlPfYjIJw==
@@ -734,7 +734,52 @@
resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.15.2.tgz"
integrity sha512-Ghyz4RJv4zyXzrUC1B2MLQBbppIB5c4jMZJybX2ebdEQAvryEKp3gq1kBksCNsatKGmEgXul88SETU19sMWcrw==
-"@swc/core@*", "@swc/core@^1.3.102", "@swc/core@>=1.2.50":
+"@swc/core-darwin-x64@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-darwin-x64/-/core-darwin-x64-1.15.2.tgz#f0c229fd21b0ef658cf50adb8b9a5f8c1919d2ec"
+ integrity sha512-7n/PGJOcL2QoptzL42L5xFFfXY5rFxLHnuz1foU+4ruUTG8x2IebGhtwVTpaDN8ShEv2UZObBlT1rrXTba15Zw==
+
+"@swc/core-linux-arm-gnueabihf@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.15.2.tgz#ab6d8535ab0294fb743044665c1c17330ccc2181"
+ integrity sha512-ZUQVCfRJ9wimuxkStRSlLwqX4TEDmv6/J+E6FicGkQ6ssLMWoKDy0cAo93HiWt/TWEee5vFhFaSQYzCuBEGO6A==
+
+"@swc/core-linux-arm64-gnu@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.15.2.tgz#c5db7bbba6af3bd93fd79b74850cf2fe04f1c074"
+ integrity sha512-GZh3pYBmfnpQ+JIg+TqLuz+pM+Mjsk5VOzi8nwKn/m+GvQBsxD5ectRtxuWUxMGNG8h0lMy4SnHRqdK3/iJl7A==
+
+"@swc/core-linux-arm64-musl@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.15.2.tgz#31cd61e6c83595248fda70a70e596f0a7f6cdf97"
+ integrity sha512-5av6VYZZeneiYIodwzGMlnyVakpuYZryGzFIbgu1XP8wVylZxduEzup4eP8atiMDFmIm+s4wn8GySJmYqeJC0A==
+
+"@swc/core-linux-x64-gnu@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.15.2.tgz#c857e95635fa2beaf6d3ecb9b1bd97ade5cda43a"
+ integrity sha512-1nO/UfdCLuT/uE/7oB3EZgTeZDCIa6nL72cFEpdegnqpJVNDI6Qb8U4g/4lfVPkmHq2lvxQ0L+n+JdgaZLhrRA==
+
+"@swc/core-linux-x64-musl@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.15.2.tgz#afa817865271f24502a0805cfab70ba553ade146"
+ integrity sha512-Ksfrb0Tx310kr+TLiUOvB/I80lyZ3lSOp6cM18zmNRT/92NB4mW8oX2Jo7K4eVEI2JWyaQUAFubDSha2Q+439A==
+
+"@swc/core-win32-arm64-msvc@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.15.2.tgz#5696added38837b6b3f442d63989ef4fcaa2d3de"
+ integrity sha512-IzUb5RlMUY0r1A9IuJrQ7Tbts1wWb73/zXVXT8VhewbHGoNlBKE0qUhKMED6Tv4wDF+pmbtUJmKXDthytAvLmg==
+
+"@swc/core-win32-ia32-msvc@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.15.2.tgz#3e42427998d49b54c55d49752b410309c7d02357"
+ integrity sha512-kCATEzuY2LP9AlbU2uScjcVhgnCAkRdu62vbce17Ro5kxEHxYWcugkveyBRS3AqZGtwAKYbMAuNloer9LS/hpw==
+
+"@swc/core-win32-x64-msvc@1.15.2":
+ version "1.15.2"
+ resolved "https://registry.yarnpkg.com/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.15.2.tgz#fa6505e20a3753b6884b35353d1614a03c54df7f"
+ integrity sha512-iJaHeYCF4jTn7OEKSa3KRiuVFIVYts8jYjNmCdyz1u5g8HRyTDISD76r8+ljEOgm36oviRQvcXaw6LFp1m0yyA==
+
+"@swc/core@^1.3.102":
version "1.15.2"
resolved "https://registry.npmjs.org/@swc/core/-/core-1.15.2.tgz"
integrity sha512-OQm+yJdXxvSjqGeaWhP6Ia264ogifwAO7Q12uTDVYj/Ks4jBTI4JknlcjDRAXtRhqbWsfbZyK/5RtuIPyptk3w==
@@ -900,7 +945,7 @@
"@types/tar@^6.1.13":
version "6.1.13"
- resolved "https://registry.npmjs.org/@types/tar/-/tar-6.1.13.tgz"
+ resolved "https://registry.yarnpkg.com/@types/tar/-/tar-6.1.13.tgz#9b5801c02175344101b4b91086ab2bbc8e93a9b6"
integrity sha512-IznnlmU5f4WcGTh2ltRu/Ijpmk8wiWXfF0VA4s+HPjHZgvFggk1YaIkbo5krX/zUCzWF8N/l4+W/LNxnvAJ8nw==
dependencies:
"@types/node" "*"
@@ -923,7 +968,7 @@
dependencies:
"@types/yargs-parser" "*"
-"@typescript-eslint/eslint-plugin@^6.7.0", "@typescript-eslint/eslint-plugin@6 - 7":
+"@typescript-eslint/eslint-plugin@^6.7.0":
version "6.21.0"
resolved "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.21.0.tgz"
integrity sha512-oy9+hTPCUFpngkEZUSzbf9MxI65wbKFoQYsgPdILTfbUldp5ovUuphZVe4i30emU9M/kP+T64Di0mxl7dSw3MA==
@@ -940,7 +985,7 @@
semver "^7.5.4"
ts-api-utils "^1.0.1"
-"@typescript-eslint/parser@^6.0.0 || ^6.0.0-alpha", "@typescript-eslint/parser@^6.7.0":
+"@typescript-eslint/parser@^6.7.0":
version "6.21.0"
resolved "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.21.0.tgz"
integrity sha512-tbsV1jPne5CkFQCgPBcDOt30ItF7aJoZL997JSF7MhGQqOeT3svWRYxiqlfA5RUdlHN6Fi+EI9bxqbdyAUZjYQ==
@@ -1033,7 +1078,7 @@ acorn-walk@^8.1.1:
dependencies:
acorn "^8.11.0"
-"acorn@^6.0.0 || ^7.0.0 || ^8.0.0", acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0:
+acorn@^8.11.0, acorn@^8.4.1, acorn@^8.9.0:
version "8.15.0"
resolved "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz"
integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==
@@ -1127,7 +1172,7 @@ asynckit@^0.4.0:
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz"
integrity sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==
-"babel-jest@^29.0.0 || ^30.0.0", babel-jest@^29.7.0:
+babel-jest@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz"
integrity sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==
@@ -1222,7 +1267,7 @@ braces@^3.0.3:
dependencies:
fill-range "^7.1.1"
-browserslist@^4.24.0, "browserslist@>= 4.21.0":
+browserslist@^4.24.0:
version "4.28.0"
resolved "https://registry.npmjs.org/browserslist/-/browserslist-4.28.0.tgz"
integrity sha512-tbydkR/CxfMwelN0vwdP/pLkDwyAASZ+VfWm4EOwlB6SWhx1sYnWLqo8N5j0rAzPfzfRaxt0mM/4wPU/Su84RQ==
@@ -1580,7 +1625,7 @@ eslint-visitor-keys@^3.4.1, eslint-visitor-keys@^3.4.3:
resolved "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz"
integrity sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==
-"eslint@^6.0.0 || ^7.0.0 || >=8.0.0", "eslint@^7.0.0 || ^8.0.0", eslint@^8.49.0, eslint@>=8.0.0, eslint@8:
+eslint@^8.49.0:
version "8.57.1"
resolved "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz"
integrity sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==
@@ -1719,7 +1764,7 @@ fast-glob@^3.2.12, fast-glob@^3.2.9:
merge2 "^1.3.0"
micromatch "^4.0.8"
-fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0, fast-json-stable-stringify@2.x:
+fast-json-stable-stringify@2.x, fast-json-stable-stringify@^2.0.0, fast-json-stable-stringify@^2.1.0:
version "2.1.0"
resolved "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz"
integrity sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==
@@ -1780,15 +1825,7 @@ find-cache-dir@^3.3.1:
make-dir "^3.0.2"
pkg-dir "^4.1.0"
-find-up@^4.0.0:
- version "4.1.0"
- resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
- integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
- dependencies:
- locate-path "^5.0.0"
- path-exists "^4.0.0"
-
-find-up@^4.1.0:
+find-up@^4.0.0, find-up@^4.1.0:
version "4.1.0"
resolved "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz"
integrity sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==
@@ -2087,7 +2124,7 @@ inflight@^1.0.4:
once "^1.3.0"
wrappy "1"
-inherits@^2.0.3, inherits@2:
+inherits@2, inherits@^2.0.3:
version "2.0.4"
resolved "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz"
integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
@@ -2390,16 +2427,16 @@ jest-pnp-resolver@^1.2.2:
resolved "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz"
integrity sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==
-jest-regex-util@^29.6.3:
- version "29.6.3"
- resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz"
- integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==
-
jest-regex-util@30.0.1:
version "30.0.1"
resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-30.0.1.tgz"
integrity sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==
+jest-regex-util@^29.6.3:
+ version "29.6.3"
+ resolved "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz"
+ integrity sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==
+
jest-resolve-dependencies@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz"
@@ -2408,7 +2445,7 @@ jest-resolve-dependencies@^29.7.0:
jest-regex-util "^29.6.3"
jest-snapshot "^29.7.0"
-jest-resolve@*, jest-resolve@^29.7.0:
+jest-resolve@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz"
integrity sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==
@@ -2504,7 +2541,7 @@ jest-snapshot@^29.7.0:
pretty-format "^29.7.0"
semver "^7.5.3"
-"jest-util@^29.0.0 || ^30.0.0", jest-util@^29.7.0:
+jest-util@^29.7.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz"
integrity sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==
@@ -2552,7 +2589,7 @@ jest-worker@^29.7.0:
merge-stream "^2.0.0"
supports-color "^8.0.0"
-"jest@^29.0.0 || ^30.0.0", jest@^29.4.0:
+jest@^29.4.0:
version "29.7.0"
resolved "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz"
integrity sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==
@@ -2782,28 +2819,14 @@ mimic-fn@^2.1.0:
resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz"
integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==
-minimatch@^3.0.4:
- version "3.1.2"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
- integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimatch@^3.0.5:
- version "3.1.2"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
- integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
- dependencies:
- brace-expansion "^1.1.7"
-
-minimatch@^3.1.1:
- version "3.1.2"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
- integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
+minimatch@9.0.3:
+ version "9.0.3"
+ resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz"
+ integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
dependencies:
- brace-expansion "^1.1.7"
+ brace-expansion "^2.0.1"
-minimatch@^3.1.2:
+minimatch@^3.0.4, minimatch@^3.0.5, minimatch@^3.1.1, minimatch@^3.1.2:
version "3.1.2"
resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz"
integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==
@@ -2817,13 +2840,6 @@ minimatch@^9.0.5:
dependencies:
brace-expansion "^2.0.1"
-minimatch@9.0.3:
- version "9.0.3"
- resolved "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz"
- integrity sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==
- dependencies:
- brace-expansion "^2.0.1"
-
minimist@^1.2.5, minimist@^1.2.6:
version "1.2.8"
resolved "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz"
@@ -3044,7 +3060,7 @@ prettier-linter-helpers@^1.0.0:
dependencies:
fast-diff "^1.1.2"
-prettier@^3.0.0, prettier@>=3.0.0:
+prettier@^3.0.0:
version "3.6.2"
resolved "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz"
integrity sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==
@@ -3165,17 +3181,7 @@ safe-buffer@~5.2.0:
resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz"
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
-semver@^6.0.0:
- version "6.3.1"
- resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
- integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-
-semver@^6.3.0:
- version "6.3.1"
- resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
- integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
-
-semver@^6.3.1:
+semver@^6.0.0, semver@^6.3.0, semver@^6.3.1:
version "6.3.1"
resolved "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz"
integrity sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==
@@ -3237,13 +3243,6 @@ stack-utils@^2.0.3:
dependencies:
escape-string-regexp "^2.0.0"
-string_decoder@^1.1.1:
- version "1.3.0"
- resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
- integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
- dependencies:
- safe-buffer "~5.2.0"
-
string-length@^4.0.1:
version "4.0.2"
resolved "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz"
@@ -3268,6 +3267,13 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
+string_decoder@^1.1.1:
+ version "1.3.0"
+ resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz"
+ integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
+ dependencies:
+ safe-buffer "~5.2.0"
+
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
version "6.0.1"
resolved "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz"
@@ -3402,7 +3408,7 @@ ts-jest@^29.1.0:
type-fest "^4.41.0"
yargs-parser "^21.1.1"
-ts-node@^10.5.0, ts-node@>=9.0.0:
+ts-node@^10.5.0:
version "10.9.2"
resolved "https://registry.npmjs.org/ts-node/-/ts-node-10.9.2.tgz"
integrity sha512-f0FFpIdcHgn8zcPSbf1dRevwt047YMnaiJM3u2w2RewrB+fob/zePZcrOyQoLMMO7aBIddLcQIEK5dYjkLnGrQ==
@@ -3527,7 +3533,7 @@ typedoc-plugin-pages@^1.1.0:
compare-versions "^3.6.0"
typedoc-default-themes "^0.10.1"
-"typedoc@^0.25.13 || ^0.26.x || ^0.27.x || ^0.28.x", typedoc@^0.28.14, typedoc@^0.28.9, "typedoc@>=0.26.0 <0.29.0", typedoc@~0.28.0, "typedoc@0.26.x || 0.27.x || 0.28.x", typedoc@0.28.x:
+typedoc@^0.28.14:
version "0.28.14"
resolved "https://registry.npmjs.org/typedoc/-/typedoc-0.28.14.tgz"
integrity sha512-ftJYPvpVfQvFzpkoSfHLkJybdA/geDJ8BGQt/ZnkkhnBYoYW6lBgPQXu6vqLxO4X75dA55hX8Af847H5KXlEFA==
@@ -3538,7 +3544,7 @@ typedoc-plugin-pages@^1.1.0:
minimatch "^9.0.5"
yaml "^2.8.1"
-typescript@^5.9.0, typescript@>=2.7, typescript@>=4.2.0, "typescript@>=4.3 <6", typescript@>=4.3.0, "typescript@5.0.x || 5.1.x || 5.2.x || 5.3.x || 5.4.x || 5.5.x || 5.6.x || 5.7.x || 5.8.x || 5.9.x":
+typescript@^5.9.0:
version "5.9.3"
resolved "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz"
integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
From 7870b6a4d133833fbb331df4bfba568ed29cb1c3 Mon Sep 17 00:00:00 2001
From: Albert Li
Date: Fri, 12 Dec 2025 17:28:20 -0800
Subject: [PATCH 17/18] Fix types
---
src/sdk/storage-object.ts | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/sdk/storage-object.ts b/src/sdk/storage-object.ts
index bf0d6281c..8809af4c3 100644
--- a/src/sdk/storage-object.ts
+++ b/src/sdk/storage-object.ts
@@ -321,7 +321,7 @@ export class StorageObject {
try {
const response = await fetch(uploadUrl, {
method: 'PUT',
- body: new Blob([text]),
+ body: Buffer.from(text, 'utf-8'),
});
if (!response.ok) {
@@ -396,7 +396,7 @@ export class StorageObject {
try {
const response = await fetch(uploadUrl, {
method: 'PUT',
- body: new Blob([buffer]),
+ body: buffer,
});
if (!response.ok) {
From 82f7a45392580aef1fb1f9f37f8b1cefe6153368 Mon Sep 17 00:00:00 2001
From: Albert Li
Date: Fri, 12 Dec 2025 17:32:21 -0800
Subject: [PATCH 18/18] Fix tests
---
tests/objects/storage-object.test.ts | 121 ++++++++++++++-------------
1 file changed, 63 insertions(+), 58 deletions(-)
diff --git a/tests/objects/storage-object.test.ts b/tests/objects/storage-object.test.ts
index 092bffc65..e3735a37d 100644
--- a/tests/objects/storage-object.test.ts
+++ b/tests/objects/storage-object.test.ts
@@ -4,8 +4,14 @@ import type { ObjectView, ObjectDownloadURLView } from '../../src/resources/obje
// Mock the Runloop client
jest.mock('../../src/index');
-// Mock fetch globally
-(global as any).fetch = jest.fn();
+// Mock the shims module to use our mock fetch
+jest.mock('../../src/_shims/index', () => ({
+ fetch: jest.fn(),
+}));
+
+// Get reference to the mocked fetch from shims
+import { fetch as shimsFetch } from '../../src/_shims/index';
+const mockedShimsFetch = shimsFetch as unknown as jest.Mock;
// Mock fs and path modules
jest.mock('node:fs/promises', () => ({
@@ -110,7 +116,7 @@ describe('StorageObject (New API)', () => {
};
// Reset fetch mock
- ((global as any).fetch as jest.Mock).mockReset();
+ mockedShimsFetch.mockReset();
});
describe('create', () => {
@@ -245,17 +251,17 @@ describe('StorageObject (New API)', () => {
// Mock getInfo to return object data with upload_url
mockClient.objects.retrieve.mockResolvedValue(mockObjectData);
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: true,
status: 200,
statusText: 'OK',
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
await storageObject.uploadContent('Hello, World!');
- expect((global as any).fetch).toHaveBeenCalledWith(mockObjectData.upload_url, {
+ expect(mockedShimsFetch).toHaveBeenCalledWith(mockObjectData.upload_url, {
method: 'PUT',
body: Buffer.from('Hello, World!', 'utf-8'),
});
@@ -265,18 +271,18 @@ describe('StorageObject (New API)', () => {
// Mock getInfo to return object data with upload_url
mockClient.objects.retrieve.mockResolvedValue(mockObjectData);
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: true,
status: 200,
statusText: 'OK',
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
const buffer = Buffer.from([0x89, 0x50, 0x4e, 0x47]);
await storageObject.uploadContent(buffer);
- expect((global as any).fetch).toHaveBeenCalledWith(mockObjectData.upload_url, {
+ expect(mockedShimsFetch).toHaveBeenCalledWith(mockObjectData.upload_url, {
method: 'PUT',
body: buffer,
});
@@ -294,14 +300,14 @@ describe('StorageObject (New API)', () => {
// Mock getInfo to return object data with upload_url
mockClient.objects.retrieve.mockResolvedValue(mockObjectData);
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: false,
status: 403,
statusText: 'Forbidden',
text: jest.fn().mockResolvedValue('Forbidden'),
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
await expect(storageObject.uploadContent('test')).rejects.toThrow('Upload failed: 403');
});
@@ -367,16 +373,16 @@ describe('StorageObject (New API)', () => {
mockClient.objects.download.mockResolvedValue(mockDownloadUrl);
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: true,
text: jest.fn().mockResolvedValue('File contents'),
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
const content = await storageObject.downloadAsText();
- expect((global as any).fetch).toHaveBeenCalledWith(mockDownloadUrl.download_url);
+ expect(mockedShimsFetch).toHaveBeenCalledWith(mockDownloadUrl.download_url);
expect(content).toBe('File contents');
});
@@ -387,13 +393,13 @@ describe('StorageObject (New API)', () => {
mockClient.objects.download.mockResolvedValue(mockDownloadUrl);
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: false,
status: 404,
statusText: 'Not Found',
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
await expect(storageObject.downloadAsText()).rejects.toThrow('Download failed: 404 Not Found');
});
@@ -408,16 +414,16 @@ describe('StorageObject (New API)', () => {
mockClient.objects.download.mockResolvedValue(mockDownloadUrl);
const mockArrayBuffer = new Uint8Array([0x89, 0x50, 0x4e, 0x47]).buffer;
- const mockFetchResponse = {
+ const mockedShimsFetchResponse = {
ok: true,
arrayBuffer: jest.fn().mockResolvedValue(mockArrayBuffer),
};
- ((global as any).fetch as jest.Mock).mockResolvedValue(mockFetchResponse);
+ mockedShimsFetch.mockResolvedValue(mockedShimsFetchResponse);
const buffer = await storageObject.downloadAsBuffer();
- expect((global as any).fetch).toHaveBeenCalledWith(mockDownloadUrl.download_url);
+ expect(mockedShimsFetch).toHaveBeenCalledWith(mockDownloadUrl.download_url);
expect(Buffer.isBuffer(buffer)).toBe(true);
expect(buffer.length).toBe(4);
});
@@ -452,7 +458,7 @@ describe('StorageObject (New API)', () => {
// Upload - mock getInfo for uploadContent
mockClient.objects.retrieve.mockResolvedValue(mockObjectData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({ ok: true });
+ mockedShimsFetch.mockResolvedValue({ ok: true });
await obj.uploadContent('Test content');
// Complete
@@ -465,7 +471,7 @@ describe('StorageObject (New API)', () => {
download_url: 'https://s3.example.com/download/workflow-test.txt',
};
mockClient.objects.download.mockResolvedValue(mockDownloadUrl);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
text: jest.fn().mockResolvedValue('Test content'),
});
@@ -480,7 +486,7 @@ describe('StorageObject (New API)', () => {
// Clear all mocks
jest.clearAllMocks();
// Reset global fetch mock
- ((global as any).fetch as jest.Mock).mockClear();
+ mockedShimsFetch.mockClear();
});
it('should upload a text file with auto-detected content-type', async () => {
@@ -496,7 +502,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -526,7 +532,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -576,7 +582,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.create.mockResolvedValue(mockObjectData);
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: false,
status: 500,
statusText: 'Internal Server Error',
@@ -600,7 +606,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -627,7 +633,7 @@ describe('StorageObject (New API)', () => {
// Clear all mocks
jest.clearAllMocks();
// Reset global fetch mock
- ((global as any).fetch as jest.Mock).mockClear();
+ mockedShimsFetch.mockClear();
});
it('should upload text content with text content-type', async () => {
@@ -640,7 +646,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -652,11 +658,11 @@ describe('StorageObject (New API)', () => {
{ name: 'hello.txt', content_type: 'text', metadata: null },
undefined,
);
- // uploadFromText uses Blob for fetch body
- const fetchCalls = ((global as any).fetch as jest.Mock).mock.calls;
+ // uploadFromText uses Buffer for fetch body
+ const fetchCalls = mockedShimsFetch.mock.calls;
expect(fetchCalls[0][0]).toBe('https://upload.example.com/text');
expect(fetchCalls[0][1].method).toBe('PUT');
- expect(fetchCalls[0][1].body).toBeInstanceOf(Blob);
+ expect(Buffer.isBuffer(fetchCalls[0][1].body)).toBe(true);
expect(result).toBeInstanceOf(StorageObject);
expect(result.id).toBe('text-123');
});
@@ -671,7 +677,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -696,7 +702,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.create.mockResolvedValue(mockObjectData);
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: false,
status: 403,
statusText: 'Forbidden',
@@ -717,7 +723,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -727,7 +733,7 @@ describe('StorageObject (New API)', () => {
// Verify all three steps were called
expect(mockClient.objects.create).toHaveBeenCalledTimes(1);
- expect((global as any).fetch).toHaveBeenCalledTimes(1);
+ expect(mockedShimsFetch).toHaveBeenCalledTimes(1);
expect(mockClient.objects.complete).toHaveBeenCalledTimes(1);
expect(result).toBeInstanceOf(StorageObject);
});
@@ -738,7 +744,7 @@ describe('StorageObject (New API)', () => {
// Clear all mocks
jest.clearAllMocks();
// Reset global fetch mock
- ((global as any).fetch as jest.Mock).mockClear();
+ mockedShimsFetch.mockClear();
});
it('should upload buffer with specified content-type and name', async () => {
@@ -751,7 +757,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -765,11 +771,11 @@ describe('StorageObject (New API)', () => {
{ name: 'buffer.txt', content_type: 'text', metadata: { source: 'buffer' } },
{ metadata: { source: 'buffer' } },
);
- // uploadFromBuffer uses Blob for fetch body
- const fetchCalls = ((global as any).fetch as jest.Mock).mock.calls;
+ // uploadFromBuffer uses Buffer for fetch body
+ const fetchCalls = mockedShimsFetch.mock.calls;
expect(fetchCalls[0][0]).toBe('https://upload.example.com/buffer');
expect(fetchCalls[0][1].method).toBe('PUT');
- expect(fetchCalls[0][1].body).toBeInstanceOf(Blob);
+ expect(Buffer.isBuffer(fetchCalls[0][1].body)).toBe(true);
expect(result).toBeInstanceOf(StorageObject);
expect(result.id).toBe('buffer-123');
});
@@ -796,7 +802,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.create.mockResolvedValue(mockObjectData);
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: false,
status: 403,
statusText: 'Forbidden',
@@ -817,7 +823,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -827,7 +833,7 @@ describe('StorageObject (New API)', () => {
// Verify all three steps were called
expect(mockClient.objects.create).toHaveBeenCalledTimes(1);
- expect((global as any).fetch).toHaveBeenCalledTimes(1);
+ expect(mockedShimsFetch).toHaveBeenCalledTimes(1);
expect(mockClient.objects.complete).toHaveBeenCalledTimes(1);
expect(result).toBeInstanceOf(StorageObject);
});
@@ -840,7 +846,7 @@ describe('StorageObject (New API)', () => {
// Clear all mocks
jest.clearAllMocks();
// Reset global fetch mock
- ((global as any).fetch as jest.Mock).mockClear();
+ mockedShimsFetch.mockClear();
// Get tar mock
mockTar = require('tar');
// Reset ignore matcher mock
@@ -852,6 +858,8 @@ describe('StorageObject (New API)', () => {
// Mock directory exists
mockFs.stat.mockResolvedValue({ isDirectory: () => true, size: 100 });
mockFs.mkdtemp.mockResolvedValue('/tmp/runloop-upload-123');
+ // Mock reading the tarball file
+ mockFs.readFile.mockResolvedValue(Buffer.from('mock tarball content'));
// Mock write stream
const mockWriteStream = {
@@ -859,12 +867,6 @@ describe('StorageObject (New API)', () => {
};
mockFsSync.createWriteStream.mockReturnValue(mockWriteStream);
- // Mock read stream
- const mockReadStream = {
- pipe: jest.fn(),
- };
- mockFsSync.createReadStream.mockReturnValue(mockReadStream);
-
// Mock tar stream
const mockTarStream = {
pipe: jest.fn((dest) => {
@@ -885,7 +887,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.retrieve.mockResolvedValue(mockObjectInfo);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -902,7 +904,7 @@ describe('StorageObject (New API)', () => {
expect(mockTar.create).toHaveBeenCalled();
expect(mockFs.mkdtemp).toHaveBeenCalled();
expect(mockFsSync.createWriteStream).toHaveBeenCalled();
- expect(mockFsSync.createReadStream).toHaveBeenCalled();
+ expect(mockFs.readFile).toHaveBeenCalled();
expect(mockFs.rm).toHaveBeenCalledWith('/tmp/runloop-upload-123', { recursive: true, force: true });
expect(result).toBeInstanceOf(StorageObject);
expect(result.id).toBe('dir-123');
@@ -912,13 +914,14 @@ describe('StorageObject (New API)', () => {
// Mock directory exists
mockFs.stat.mockResolvedValue({ isDirectory: () => true, size: 100 });
mockFs.mkdtemp.mockResolvedValue('/tmp/runloop-upload-123');
+ // Mock reading the tarball file
+ mockFs.readFile.mockResolvedValue(Buffer.from('mock tarball content'));
// Mocks for streams
const mockWriteStream = {
on: jest.fn().mockReturnThis(),
};
mockFsSync.createWriteStream.mockReturnValue(mockWriteStream);
- mockFsSync.createReadStream.mockReturnValue({});
// Provide a fake matcher
const matcher = { matches: jest.fn() };
@@ -939,7 +942,7 @@ describe('StorageObject (New API)', () => {
const mockObjectData = { id: 'dir-ignore', upload_url: 'https://upload.example.com/dir' };
mockClient.objects.create.mockResolvedValue(mockObjectData);
mockClient.objects.complete.mockResolvedValue({ ...mockObjectData, state: 'READ_ONLY' });
- ((global as any).fetch as jest.Mock).mockResolvedValue({ ok: true });
+ mockedShimsFetch.mockResolvedValue({ ok: true });
await StorageObject.uploadFromDir(mockClient, './my-project', {
name: 'project.tar.gz',
@@ -966,13 +969,14 @@ describe('StorageObject (New API)', () => {
// Mock directory exists
mockFs.stat.mockResolvedValue({ isDirectory: () => true, size: 100 });
mockFs.mkdtemp.mockResolvedValue('/tmp/runloop-upload-123');
+ // Mock reading the tarball file
+ mockFs.readFile.mockResolvedValue(Buffer.from('mock tarball content'));
// Mocks for streams
const mockWriteStream = {
on: jest.fn().mockReturnThis(),
};
mockFsSync.createWriteStream.mockReturnValue(mockWriteStream);
- mockFsSync.createReadStream.mockReturnValue({});
// Mock tar stream
const mockTarStream = {
@@ -991,7 +995,7 @@ describe('StorageObject (New API)', () => {
mockClient.objects.create.mockResolvedValue(mockObjectData);
mockClient.objects.complete.mockResolvedValue(mockCompletedData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: true,
status: 200,
statusText: 'OK',
@@ -1040,12 +1044,13 @@ describe('StorageObject (New API)', () => {
it('should handle upload failures gracefully', async () => {
mockFs.stat.mockResolvedValue({ isDirectory: () => true, size: 100 });
mockFs.mkdtemp.mockResolvedValue('/tmp/runloop-upload-123');
+ // Mock reading the tarball file
+ mockFs.readFile.mockResolvedValue(Buffer.from('mock tarball content'));
const mockWriteStream = {
on: jest.fn().mockReturnThis(),
};
mockFsSync.createWriteStream.mockReturnValue(mockWriteStream);
- mockFsSync.createReadStream.mockReturnValue({});
const mockTarStream = {
pipe: jest.fn((dest) => {
@@ -1060,7 +1065,7 @@ describe('StorageObject (New API)', () => {
const mockObjectData = { id: 'dir-999', upload_url: 'https://upload.example.com/dir' };
mockClient.objects.create.mockResolvedValue(mockObjectData);
- ((global as any).fetch as jest.Mock).mockResolvedValue({
+ mockedShimsFetch.mockResolvedValue({
ok: false,
status: 500,
statusText: 'Internal Server Error',