From 2f70ad9e95854605f9f38c401d49f8422d62af75 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 22 Feb 2025 08:52:42 +0000
Subject: [PATCH 01/44] fix(internal): return in castToError instead of
 throwing (#43)

---
 src/internal/errors.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/internal/errors.ts b/src/internal/errors.ts
index 653a6ec..82c7b14 100644
--- a/src/internal/errors.ts
+++ b/src/internal/errors.ts
@@ -22,7 +22,7 @@ export const castToError = (err: any): Error => {
         // @ts-ignore - not all envs have native support for cause yet
         if (err.cause && !error.cause) error.cause = err.cause;
         if (err.name) error.name = err.name;
-        throw error;
+        return error;
       }
     } catch {}
     try {

From bd9e5361115c7f9adc8c8d9798f38a04b55ab03c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 22 Feb 2025 09:11:16 +0000
Subject: [PATCH 02/44] chore(internal): remove unnecessary todo (#45)

---
 src/internal/parse.ts | 2 --
 1 file changed, 2 deletions(-)

diff --git a/src/internal/parse.ts b/src/internal/parse.ts
index 799b71c..2085087 100644
--- a/src/internal/parse.ts
+++ b/src/internal/parse.ts
@@ -34,8 +34,6 @@ export async function defaultParseResponse<T>(client: Gitpod, props: APIResponse
     }
 
     const text = await response.text();
-
-    // TODO handle blob, arraybuffer, other content types, etc.
     return text as unknown as T;
   })();
   loggerFor(client).debug(

From 6450e47a5f12103274528a67028b91a01b9c55b8 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 28 Feb 2025 04:06:07 +0000
Subject: [PATCH 03/44] docs: update URLs from stainlessapi.com to
 stainless.com (#46)

More details at https://www.stainless.com/changelog/stainless-com
---
 README.md   | 2 +-
 SECURITY.md | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/README.md b/README.md
index e071c46..ae0223a 100644
--- a/README.md
+++ b/README.md
@@ -6,7 +6,7 @@ This library provides convenient access to the Gitpod REST API from server-side
 
 The REST API documentation can be found on [docs.gitpod.io](https://docs.gitpod.io). The full API of this library can be found in [api.md](api.md).
 
-It is generated with [Stainless](https://www.stainlessapi.com/).
+It is generated with [Stainless](https://www.stainless.com/).
 
 ## Installation
 
diff --git a/SECURITY.md b/SECURITY.md
index 0985c82..2b0ed90 100644
--- a/SECURITY.md
+++ b/SECURITY.md
@@ -2,9 +2,9 @@
 
 ## Reporting Security Issues
 
-This SDK is generated by [Stainless Software Inc](http://stainlessapi.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
+This SDK is generated by [Stainless Software Inc](http://stainless.com). Stainless takes security seriously, and encourages you to report any security vulnerability promptly so that appropriate action can be taken.
 
-To report a security issue, please contact the Stainless team at security@stainlessapi.com.
+To report a security issue, please contact the Stainless team at security@stainless.com.
 
 ## Responsible Disclosure
 

From cd888bc3c16d0d2cbf3b3c96ab23dc7d46360598 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:33:40 +0000
Subject: [PATCH 04/44] chore(client): only accept standard types for file
 uploads (#47)

---
 scripts/build                                 |   4 +-
 src/client.ts                                 |   4 +-
 src/internal/polyfill/file.node.d.ts          |   9 -
 src/internal/polyfill/file.node.js            |  17 --
 src/internal/polyfill/file.node.mjs           |   9 -
 src/internal/shims.ts                         |  56 -----
 .../{polyfill => shims}/crypto.node.d.ts      |   0
 .../{polyfill => shims}/crypto.node.js        |   0
 .../{polyfill => shims}/crypto.node.mjs       |   0
 src/internal/shims/file.node.d.ts             |  20 ++
 src/internal/shims/file.node.js               |  11 +
 src/internal/shims/file.node.mjs              |   2 +
 src/internal/to-file.ts                       | 152 ++++++++++++
 src/internal/uploads.ts                       | 220 ++++--------------
 src/internal/utils/uuid.ts                    |   2 +-
 src/uploads.ts                                |   3 +-
 tests/uploads.test.ts                         |  38 ++-
 17 files changed, 267 insertions(+), 280 deletions(-)
 delete mode 100644 src/internal/polyfill/file.node.d.ts
 delete mode 100644 src/internal/polyfill/file.node.js
 delete mode 100644 src/internal/polyfill/file.node.mjs
 rename src/internal/{polyfill => shims}/crypto.node.d.ts (100%)
 rename src/internal/{polyfill => shims}/crypto.node.js (100%)
 rename src/internal/{polyfill => shims}/crypto.node.mjs (100%)
 create mode 100644 src/internal/shims/file.node.d.ts
 create mode 100644 src/internal/shims/file.node.js
 create mode 100644 src/internal/shims/file.node.mjs
 create mode 100644 src/internal/to-file.ts

diff --git a/scripts/build b/scripts/build
index 08bfe2e..7b100ad 100755
--- a/scripts/build
+++ b/scripts/build
@@ -40,8 +40,8 @@ cp dist/index.d.ts dist/index.d.mts
 cp tsconfig.dist-src.json dist/src/tsconfig.json
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts
-mkdir -p dist/internal/polyfill
-cp src/internal/polyfill/*.{mjs,js,d.ts} dist/internal/polyfill
+mkdir -p dist/internal/shims
+cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims
 
 node scripts/utils/postprocess-files.cjs
 
diff --git a/src/client.ts b/src/client.ts
index 9836801..8c0af2b 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -726,7 +726,9 @@ export class Gitpod {
 
     const timeout = setTimeout(() => controller.abort(), ms);
 
-    const isReadableBody = Shims.isReadableLike(options.body);
+    const isReadableBody =
+      ((globalThis as any).ReadableStream && options.body instanceof (globalThis as any).ReadableStream) ||
+      (typeof options.body === 'object' && options.body !== null && Symbol.asyncIterator in options.body);
 
     const fetchOptions: RequestInit = {
       signal: controller.signal as any,
diff --git a/src/internal/polyfill/file.node.d.ts b/src/internal/polyfill/file.node.d.ts
deleted file mode 100644
index b2a59bf..0000000
--- a/src/internal/polyfill/file.node.d.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * This file polyfills the global `File` object for you if it's not already defined
- * when running on Node.js
- *
- * This is only needed on Node.js v18 & v19. Newer versions already define `File`
- * as a global.
- */
-
-export {};
diff --git a/src/internal/polyfill/file.node.js b/src/internal/polyfill/file.node.js
deleted file mode 100644
index eba997e..0000000
--- a/src/internal/polyfill/file.node.js
+++ /dev/null
@@ -1,17 +0,0 @@
-/**
- * This file polyfills the global `File` object for you if it's not already defined
- * when running on Node.js
- *
- * This is only needed on Node.js v18 & v19. Newer versions already define `File`
- * as a global.
- */
-
-if (typeof require !== 'undefined') {
-  if (!globalThis.File) {
-    try {
-      // Use [require][0](...) and not require(...) so bundlers don't try to bundle the
-      // buffer module.
-      globalThis.File = [require][0]('node:buffer').File;
-    } catch (e) {}
-  }
-}
diff --git a/src/internal/polyfill/file.node.mjs b/src/internal/polyfill/file.node.mjs
deleted file mode 100644
index 520dcb8..0000000
--- a/src/internal/polyfill/file.node.mjs
+++ /dev/null
@@ -1,9 +0,0 @@
-/**
- * This file polyfills the global `File` object for you if it's not already defined
- * when running on Node.js
- *
- * This is only needed on Node.js v18 & v19. Newer versions already define `File`
- * as a global.
- */
-
-import './file.node.js';
diff --git a/src/internal/shims.ts b/src/internal/shims.ts
index cb91e94..95b03fb 100644
--- a/src/internal/shims.ts
+++ b/src/internal/shims.ts
@@ -20,62 +20,6 @@ export function getDefaultFetch(): Fetch {
   );
 }
 
-/**
- * A minimal copy of the NodeJS `stream.Readable` class so that we can
- * accept the NodeJS types in certain places, e.g. file uploads
- *
- * https://nodejs.org/api/stream.html#class-streamreadable
- */
-export interface ReadableLike {
-  readable: boolean;
-  readonly readableEnded: boolean;
-  readonly readableFlowing: boolean | null;
-  readonly readableHighWaterMark: number;
-  readonly readableLength: number;
-  readonly readableObjectMode: boolean;
-  destroyed: boolean;
-  read(size?: number): any;
-  pause(): this;
-  resume(): this;
-  isPaused(): boolean;
-  destroy(error?: Error): this;
-  [Symbol.asyncIterator](): AsyncIterableIterator<any>;
-}
-
-/**
- * Determines if the given value looks like a NodeJS `stream.Readable`
- * object and that it is readable, i.e. has not been consumed.
- *
- * https://nodejs.org/api/stream.html#class-streamreadable
- */
-export function isReadableLike(value: any) {
-  // We declare our own class of Readable here, so it's not feasible to
-  // do an 'instanceof' check. Instead, check for Readable-like properties.
-  return !!value && value.readable === true && typeof value.read === 'function';
-}
-
-/**
- * A minimal copy of the NodeJS `fs.ReadStream` class for usage within file uploads.
- *
- * https://nodejs.org/api/fs.html#class-fsreadstream
- */
-export interface FsReadStreamLike extends ReadableLike {
-  path: {}; // real type is string | Buffer but we can't reference `Buffer` here
-}
-
-/**
- * Determines if the given value looks like a NodeJS `fs.ReadStream`
- * object.
- *
- * This just checks if the object matches our `Readable` interface
- * and defines a `path` property, there may be false positives.
- *
- * https://nodejs.org/api/fs.html#class-fsreadstream
- */
-export function isFsReadStreamLike(value: any): value is FsReadStreamLike {
-  return isReadableLike(value) && 'path' in value;
-}
-
 type ReadableStreamArgs = ConstructorParameters<typeof ReadableStream>;
 
 export function makeReadableStream(...args: ReadableStreamArgs): ReadableStream {
diff --git a/src/internal/polyfill/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts
similarity index 100%
rename from src/internal/polyfill/crypto.node.d.ts
rename to src/internal/shims/crypto.node.d.ts
diff --git a/src/internal/polyfill/crypto.node.js b/src/internal/shims/crypto.node.js
similarity index 100%
rename from src/internal/polyfill/crypto.node.js
rename to src/internal/shims/crypto.node.js
diff --git a/src/internal/polyfill/crypto.node.mjs b/src/internal/shims/crypto.node.mjs
similarity index 100%
rename from src/internal/polyfill/crypto.node.mjs
rename to src/internal/shims/crypto.node.mjs
diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts
new file mode 100644
index 0000000..9dc6b2f
--- /dev/null
+++ b/src/internal/shims/file.node.d.ts
@@ -0,0 +1,20 @@
+// The infer is to make TS show it as a nice union type,
+// instead of literally `ConstructorParameters<typeof Blob>[0]`
+type FallbackBlobSource = ConstructorParameters<typeof Blob>[0] extends infer T ? T : never;
+/**
+ * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files.
+ */
+declare class FallbackFile extends Blob {
+  constructor(sources: FallbackBlobSource, fileName: string, options?: any);
+  /**
+   * The name of the `File`.
+   */
+  readonly name: string;
+  /**
+   * The last modified date of the `File`.
+   */
+  readonly lastModified: number;
+}
+export type File = InstanceType<typeof File>;
+export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor
+: typeof FallbackFile;
diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js
new file mode 100644
index 0000000..3f8c2ed
--- /dev/null
+++ b/src/internal/shims/file.node.js
@@ -0,0 +1,11 @@
+if (typeof require !== 'undefined') {
+  if (globalThis.File) {
+    exports.File = globalThis.File;
+  } else {
+    try {
+      // Use [require][0](...) and not require(...) so bundlers don't try to bundle the
+      // buffer module.
+      exports.File = [require][0]('node:buffer').File;
+    } catch (e) {}
+  }
+}
diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs
new file mode 100644
index 0000000..1f103f5
--- /dev/null
+++ b/src/internal/shims/file.node.mjs
@@ -0,0 +1,2 @@
+import * as mod from './file.node.js';
+export const File = globalThis.File || mod.File;
diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts
new file mode 100644
index 0000000..69b76d3
--- /dev/null
+++ b/src/internal/to-file.ts
@@ -0,0 +1,152 @@
+import { File } from './shims/file.node.js';
+import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads';
+import type { FilePropertyBag } from './builtin-types';
+
+type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView;
+
+/**
+ * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc.
+ * Don't add arrayBuffer here, node-fetch doesn't have it
+ */
+interface BlobLike {
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */
+  readonly size: number;
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */
+  readonly type: string;
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */
+  text(): Promise<string>;
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
+  slice(start?: number, end?: number): BlobLike;
+}
+
+/**
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
+ */
+const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
+  value != null &&
+  typeof value === 'object' &&
+  typeof value.size === 'number' &&
+  typeof value.type === 'string' &&
+  typeof value.text === 'function' &&
+  typeof value.slice === 'function' &&
+  typeof value.arrayBuffer === 'function';
+
+/**
+ * Intended to match DOM File, node:buffer File, undici File, etc.
+ */
+interface FileLike extends BlobLike {
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */
+  readonly lastModified: number;
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */
+  readonly name?: string | undefined;
+}
+
+/**
+ * This check adds the arrayBuffer() method type because it is available and used at runtime
+ */
+const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
+  value != null &&
+  typeof value === 'object' &&
+  typeof value.name === 'string' &&
+  typeof value.lastModified === 'number' &&
+  isBlobLike(value);
+
+/**
+ * Intended to match DOM Response, node-fetch Response, undici Response, etc.
+ */
+export interface ResponseLike {
+  url: string;
+  blob(): Promise<BlobLike>;
+}
+
+const isResponseLike = (value: any): value is ResponseLike =>
+  value != null &&
+  typeof value === 'object' &&
+  typeof value.url === 'string' &&
+  typeof value.blob === 'function';
+
+export type ToFileInput =
+  | FileLike
+  | ResponseLike
+  | Exclude<BlobLikePart, string>
+  | AsyncIterable<BlobLikePart>;
+
+/**
+ * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
+ * @param value the raw content of the file.  Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
+ * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
+ * @param {Object=} options additional properties
+ * @param {string=} options.type the MIME type of the content
+ * @param {number=} options.lastModified the last modified timestamp
+ * @returns a {@link File} with the given properties
+ */
+export async function toFile(
+  value: ToFileInput | PromiseLike<ToFileInput>,
+  name?: string | null | undefined,
+  options?: FilePropertyBag | undefined,
+): Promise<File> {
+  // If it's a promise, resolve it.
+  value = await value;
+
+  // If we've been given a `File` we don't need to do anything
+  if (isFileLike(value)) {
+    if (File && value instanceof File) {
+      return value;
+    }
+    return makeFile([await value.arrayBuffer()], value.name);
+  }
+
+  if (isResponseLike(value)) {
+    const blob = await value.blob();
+    name ||= new URL(value.url).pathname.split(/[\\/]/).pop();
+
+    return makeFile(await getBytes(blob), name, options);
+  }
+
+  const parts = await getBytes(value);
+
+  name ||= getName(value);
+
+  if (!options?.type) {
+    const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type);
+    if (typeof type === 'string') {
+      options = { ...options, type };
+    }
+  }
+
+  return makeFile(parts, name, options);
+}
+
+async function getBytes(value: BlobLikePart | AsyncIterable<BlobLikePart>): Promise<Array<BlobPart>> {
+  let parts: Array<BlobPart> = [];
+  if (
+    typeof value === 'string' ||
+    ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
+    value instanceof ArrayBuffer
+  ) {
+    parts.push(value);
+  } else if (isBlobLike(value)) {
+    parts.push(value instanceof Blob ? value : await value.arrayBuffer());
+  } else if (
+    isAsyncIterable(value) // includes Readable, ReadableStream, etc.
+  ) {
+    for await (const chunk of value) {
+      parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating?
+    }
+  } else {
+    const constructor = value?.constructor?.name;
+    throw new Error(
+      `Unexpected data type: ${typeof value}${
+        constructor ? `; constructor: ${constructor}` : ''
+      }${propsForError(value)}`,
+    );
+  }
+
+  return parts;
+}
+
+function propsForError(value: unknown): string {
+  if (typeof value !== 'object' || value === null) return '';
+  const props = Object.getOwnPropertyNames(value);
+  return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`;
+}
diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts
index ee2029c..54431c1 100644
--- a/src/internal/uploads.ts
+++ b/src/internal/uploads.ts
@@ -1,11 +1,16 @@
 import { type RequestOptions } from './request-options';
 import type { FilePropertyBag, Fetch } from './builtin-types';
-import { isFsReadStreamLike, type FsReadStreamLike } from './shims';
 import type { Gitpod } from '../client';
-import './polyfill/file.node.js';
+import { File } from './shims/file.node.js';
+import { ReadableStreamFrom } from './shims';
 
-type BlobLikePart = string | ArrayBuffer | ArrayBufferView | BlobLike | DataView;
-type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView;
+export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView;
+type FsReadStream = AsyncIterable<Uint8Array> & { path: string | { toString(): string } };
+
+// https://github.com/oven-sh/bun/issues/5980
+interface BunFile extends Blob {
+  readonly name?: string | undefined;
+}
 
 /**
  * Typically, this is a native "File" class.
@@ -16,188 +21,41 @@ type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView;
  * For convenience, you can also pass a fetch Response, or in Node,
  * the result of fs.createReadStream().
  */
-export type Uploadable = FileLike | ResponseLike | FsReadStreamLike;
-
-/**
- * Intended to match DOM Blob, node-fetch Blob, node:buffer Blob, etc.
- * Don't add arrayBuffer here, node-fetch doesn't have it
- */
-interface BlobLike {
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/size) */
-  readonly size: number;
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/type) */
-  readonly type: string;
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/text) */
-  text(): Promise<string>;
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Blob/slice) */
-  slice(start?: number, end?: number): BlobLike;
-}
-
-/**
- * This check adds the arrayBuffer() method type because it is available and used at runtime
- */
-const isBlobLike = (value: any): value is BlobLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
-  value != null &&
-  typeof value === 'object' &&
-  typeof value.size === 'number' &&
-  typeof value.type === 'string' &&
-  typeof value.text === 'function' &&
-  typeof value.slice === 'function' &&
-  typeof value.arrayBuffer === 'function';
-
-/**
- * Intended to match DOM File, node:buffer File, undici File, etc.
- */
-interface FileLike extends BlobLike {
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/lastModified) */
-  readonly lastModified: number;
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/File/name) */
-  readonly name?: string | undefined;
-}
-declare var FileClass: {
-  prototype: FileLike;
-  new (fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike;
-};
-
-/**
- * This check adds the arrayBuffer() method type because it is available and used at runtime
- */
-const isFileLike = (value: any): value is FileLike & { arrayBuffer(): Promise<ArrayBuffer> } =>
-  value != null &&
-  typeof value === 'object' &&
-  typeof value.name === 'string' &&
-  typeof value.lastModified === 'number' &&
-  isBlobLike(value);
-
-/**
- * Intended to match DOM Response, node-fetch Response, undici Response, etc.
- */
-export interface ResponseLike {
-  url: string;
-  blob(): Promise<BlobLike>;
-}
-
-const isResponseLike = (value: any): value is ResponseLike =>
-  value != null &&
-  typeof value === 'object' &&
-  typeof value.url === 'string' &&
-  typeof value.blob === 'function';
-
-const isUploadable = (value: any): value is Uploadable => {
-  return isFileLike(value) || isResponseLike(value) || isFsReadStreamLike(value);
-};
-
-type ToFileInput = Uploadable | Exclude<BlobLikePart, string> | AsyncIterable<BlobLikePart>;
+export type Uploadable = File | Response | FsReadStream | BunFile;
 
 /**
  * Construct a `File` instance. This is used to ensure a helpful error is thrown
- * for environments that don't define a global `File` yet and so that we don't
- * accidentally rely on a global `File` type in our annotations.
+ * for environments that don't define a global `File` yet.
  */
-function makeFile(fileBits: BlobPart[], fileName: string, options?: FilePropertyBag): FileLike {
-  const File = (globalThis as any).File as typeof FileClass | undefined;
+export function makeFile(
+  fileBits: BlobPart[],
+  fileName: string | undefined,
+  options?: FilePropertyBag,
+): File {
   if (typeof File === 'undefined') {
     throw new Error('`File` is not defined as a global which is required for file uploads');
   }
 
-  return new File(fileBits, fileName, options);
+  return new File(fileBits as any, fileName ?? 'unknown_file', options);
 }
 
-/**
- * Helper for creating a {@link File} to pass to an SDK upload method from a variety of different data formats
- * @param value the raw content of the file.  Can be an {@link Uploadable}, {@link BlobLikePart}, or {@link AsyncIterable} of {@link BlobLikePart}s
- * @param {string=} name the name of the file. If omitted, toFile will try to determine a file name from bits if possible
- * @param {Object=} options additional properties
- * @param {string=} options.type the MIME type of the content
- * @param {number=} options.lastModified the last modified timestamp
- * @returns a {@link File} with the given properties
- */
-export async function toFile(
-  value: ToFileInput | PromiseLike<ToFileInput>,
-  name?: string | null | undefined,
-  options?: FilePropertyBag | undefined,
-): Promise<FileLike> {
-  // If it's a promise, resolve it.
-  value = await value;
-
-  // If we've been given a `File` we don't need to do anything
-  if (isFileLike(value)) {
-    const File = (globalThis as any).File as typeof FileClass | undefined;
-    if (File && value instanceof File) {
-      return value;
-    }
-    return makeFile([await value.arrayBuffer()], value.name ?? 'unknown_file');
-  }
-
-  if (isResponseLike(value)) {
-    const blob = await value.blob();
-    name ||= new URL(value.url).pathname.split(/[\\/]/).pop() ?? 'unknown_file';
-
-    return makeFile(await getBytes(blob), name, options);
-  }
-
-  const parts = await getBytes(value);
-
-  name ||= getName(value) ?? 'unknown_file';
-
-  if (!options?.type) {
-    const type = parts.find((part) => typeof part === 'object' && 'type' in part && part.type);
-    if (typeof type === 'string') {
-      options = { ...options, type };
-    }
-  }
-
-  return makeFile(parts, name, options);
-}
-
-export async function getBytes(
-  value: Uploadable | BlobLikePart | AsyncIterable<BlobLikePart>,
-): Promise<Array<BlobPart>> {
-  let parts: Array<BlobPart> = [];
-  if (
-    typeof value === 'string' ||
-    ArrayBuffer.isView(value) || // includes Uint8Array, Buffer, etc.
-    value instanceof ArrayBuffer
-  ) {
-    parts.push(value);
-  } else if (isBlobLike(value)) {
-    parts.push(value instanceof Blob ? value : await value.arrayBuffer());
-  } else if (
-    isAsyncIterableIterator(value) // includes Readable, ReadableStream, etc.
-  ) {
-    for await (const chunk of value) {
-      parts.push(...(await getBytes(chunk as BlobLikePart))); // TODO, consider validating?
-    }
-  } else {
-    const constructor = value?.constructor?.name;
-    throw new Error(
-      `Unexpected data type: ${typeof value}${
-        constructor ? `; constructor: ${constructor}` : ''
-      }${propsForError(value)}`,
-    );
-  }
-
-  return parts;
-}
-
-function propsForError(value: unknown): string {
-  if (typeof value !== 'object' || value === null) return '';
-  const props = Object.getOwnPropertyNames(value);
-  return `; props: [${props.map((p) => `"${p}"`).join(', ')}]`;
-}
-
-function getName(value: unknown): string | undefined {
+export function getName(value: any): string | undefined {
   return (
-    (typeof value === 'object' &&
-      value !== null &&
-      (('name' in value && String(value.name)) ||
-        ('filename' in value && String(value.filename)) ||
-        ('path' in value && String(value.path).split(/[\\/]/).pop()))) ||
-    undefined
+    (
+      (typeof value === 'object' &&
+        value !== null &&
+        (('name' in value && value.name && String(value.name)) ||
+          ('url' in value && value.url && String(value.url)) ||
+          ('filename' in value && value.filename && String(value.filename)) ||
+          ('path' in value && value.path && String(value.path)))) ||
+      ''
+    )
+      .split(/[\\/]/)
+      .pop() || undefined
   );
 }
 
-const isAsyncIterableIterator = (value: any): value is AsyncIterableIterator<unknown> =>
+export const isAsyncIterable = (value: any): value is AsyncIterable<any> =>
   value != null && typeof value === 'object' && typeof value[Symbol.asyncIterator] === 'function';
 
 /**
@@ -268,6 +126,15 @@ export const createForm = async <T = Record<string, unknown>>(
   return form;
 };
 
+// We check for Blob not File because Bun.File doesn't inherit from File,
+// but they both inherit from Blob and have a `name` property at runtime.
+const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value);
+
+const isUploadable = (value: unknown) =>
+  typeof value === 'object' &&
+  value !== null &&
+  (value instanceof Response || isAsyncIterable(value) || isNamedBlob(value));
+
 const hasUploadableValue = (value: unknown): boolean => {
   if (isUploadable(value)) return true;
   if (Array.isArray(value)) return value.some(hasUploadableValue);
@@ -290,9 +157,12 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis
   // TODO: make nested formats configurable
   if (typeof value === 'string' || typeof value === 'number' || typeof value === 'boolean') {
     form.append(key, String(value));
-  } else if (isUploadable(value)) {
-    const file = await toFile(value);
-    form.append(key, file as any);
+  } else if (value instanceof Response) {
+    form.append(key, makeFile([await value.blob()], getName(value)));
+  } else if (isAsyncIterable(value)) {
+    form.append(key, makeFile([await new Response(ReadableStreamFrom(value)).blob()], getName(value)));
+  } else if (isNamedBlob(value)) {
+    form.append(key, value, getName(value));
   } else if (Array.isArray(value)) {
     await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry)));
   } else if (typeof value === 'object') {
diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts
index 6c43f81..1349c42 100644
--- a/src/internal/utils/uuid.ts
+++ b/src/internal/utils/uuid.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { crypto } from '../polyfill/crypto.node';
+import { crypto } from '../shims/crypto.node.js';
 
 /**
  * https://stackoverflow.com/a/2117523
diff --git a/src/uploads.ts b/src/uploads.ts
index 77b6576..79d3073 100644
--- a/src/uploads.ts
+++ b/src/uploads.ts
@@ -1 +1,2 @@
-export { type Uploadable, toFile } from './internal/uploads';
+export { type Uploadable } from './internal/uploads';
+export { toFile, type ToFileInput } from './internal/to-file';
diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index 5758464..0fc3454 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -1,5 +1,5 @@
 import fs from 'fs';
-import type { ResponseLike } from '@gitpod/sdk/internal/uploads';
+import type { ResponseLike } from '@gitpod/sdk/internal/to-file';
 import { toFile } from '@gitpod/sdk/uploads';
 
 class MyClass {
@@ -13,6 +13,12 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon
   };
 }
 
+beforeEach(() => {
+  // The file shim captures the global File object when it's first imported.
+  // Reset modules before each test so we can test the error thrown when it's undefined.
+  jest.resetModules();
+});
+
 describe('toFile', () => {
   it('throws a helpful error for mismatched types', async () => {
     await expect(
@@ -62,15 +68,29 @@ describe('toFile', () => {
     expect(file.name).toEqual('input.jsonl');
     expect(file.type).toBe('jsonl');
   });
+
+  it('is assignable to File and Blob', async () => {
+    const input = new File(['foo'], 'input.jsonl', { type: 'jsonl' });
+    const result = await toFile(input);
+    const file: File = result;
+    const blob: Blob = result;
+    void file, blob;
+  });
 });
 
-test('missing File error message', async () => {
-  // @ts-ignore
-  globalThis.File = undefined;
+describe('missing File error message', () => {
+  beforeEach(() => {
+    // @ts-ignore
+    globalThis.File = undefined;
+    require('node:buffer').File = undefined;
+  });
 
-  await expect(
-    toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })),
-  ).rejects.toMatchInlineSnapshot(
-    `[Error: \`File\` is not defined as a global which is required for file uploads]`,
-  );
+  test('is thrown', async () => {
+    const uploads = await import('@gitpod/sdk/uploads');
+    await expect(
+      uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })),
+    ).rejects.toMatchInlineSnapshot(
+      `[Error: \`File\` is not defined as a global which is required for file uploads]`,
+    );
+  });
 });

From c1031bd67090cc27d55472a5a32ee70df9ee781e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:40:09 +0000
Subject: [PATCH 05/44] chore(internal): fix tests failing on node v18 (#48)

---
 tests/uploads.test.ts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index 0fc3454..a118892 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -1,6 +1,7 @@
 import fs from 'fs';
 import type { ResponseLike } from '@gitpod/sdk/internal/to-file';
 import { toFile } from '@gitpod/sdk/uploads';
+import { File } from 'node:buffer';
 
 class MyClass {
   name: string = 'foo';

From 41da630123709c225f8c173bbd2aace382d0e865 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:41:57 +0000
Subject: [PATCH 06/44] chore(internal): constrain synckit dev dependency (#49)

---
 package.json | 3 +++
 yarn.lock    | 8 ++++----
 2 files changed, 7 insertions(+), 4 deletions(-)

diff --git a/package.json b/package.json
index d59480b..dae603a 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,9 @@
     "typescript": "^4.8.2",
     "typescript-eslint": "^8.24.0"
   },
+  "resolutions": {
+    "synckit": "0.8.8"
+  },
   "imports": {
     "@gitpod/sdk": ".",
     "@gitpod/sdk/*": "./src/*"
diff --git a/yarn.lock b/yarn.lock
index 6bd4ab2..6c01b49 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -3317,10 +3317,10 @@ supports-preserve-symlinks-flag@^1.0.0:
   resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
   integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
 
-synckit@^0.9.1:
-  version "0.9.2"
-  resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.9.2.tgz#a3a935eca7922d48b9e7d6c61822ee6c3ae4ec62"
-  integrity sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==
+synckit@0.8.8, synckit@^0.9.1:
+  version "0.8.8"
+  resolved "https://registry.yarnpkg.com/synckit/-/synckit-0.8.8.tgz#fe7fe446518e3d3d49f5e429f443cf08b6edfcd7"
+  integrity sha512-HwOKAP7Wc5aRGYdKH+dw0PRRpbO841v2DENBtjnR5HFWoiNByAl7vrx3p0G/rCyYXQsrxqtX48TImFtPcIHSpQ==
   dependencies:
     "@pkgr/core" "^0.1.0"
     tslib "^2.6.2"

From 1262a7bcd5e0619e1eaef399ee967b629c79ce09 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:44:15 +0000
Subject: [PATCH 07/44] fix(client): fix TypeError with undefined File (#50)

---
 src/internal/uploads.ts | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts
index 54431c1..e09bcbb 100644
--- a/src/internal/uploads.ts
+++ b/src/internal/uploads.ts
@@ -128,7 +128,8 @@ export const createForm = async <T = Record<string, unknown>>(
 
 // We check for Blob not File because Bun.File doesn't inherit from File,
 // but they both inherit from Blob and have a `name` property at runtime.
-const isNamedBlob = (value: object) => value instanceof File || (value instanceof Blob && 'name' in value);
+const isNamedBlob = (value: object) =>
+  (File && value instanceof File) || (value instanceof Blob && 'name' in value);
 
 const isUploadable = (value: unknown) =>
   typeof value === 'object' &&

From e1e0fb509bfd526c9a8183480ad88330f0c7b240 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:46:13 +0000
Subject: [PATCH 08/44] fix(internal): clean up undefined File test (#51)

---
 tests/uploads.test.ts | 18 ++++++++++++------
 1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index a118892..f320eea 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -14,12 +14,6 @@ function mockResponse({ url, content }: { url: string; content?: Blob }): Respon
   };
 }
 
-beforeEach(() => {
-  // The file shim captures the global File object when it's first imported.
-  // Reset modules before each test so we can test the error thrown when it's undefined.
-  jest.resetModules();
-});
-
 describe('toFile', () => {
   it('throws a helpful error for mismatched types', async () => {
     await expect(
@@ -80,11 +74,23 @@ describe('toFile', () => {
 });
 
 describe('missing File error message', () => {
+  let prevFile: unknown;
   beforeEach(() => {
+    // The file shim captures the global File object when it's first imported.
+    // Reset modules before each test so we can test the error thrown when it's undefined.
+    jest.resetModules();
+    // @ts-ignore
+    prevFile = globalThis.File;
     // @ts-ignore
     globalThis.File = undefined;
     require('node:buffer').File = undefined;
   });
+  afterEach(() => {
+    // Clean up
+    // @ts-ignore
+    globalThis.File = prevFile;
+    jest.resetModules();
+  });
 
   test('is thrown', async () => {
     const uploads = await import('@gitpod/sdk/uploads');

From 2eded46344af89fbaef371ab685056b8952aa946 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 4 Mar 2025 10:47:26 +0000
Subject: [PATCH 09/44] fix(tests): manually reset node:buffer File (#52)

---
 tests/uploads.test.ts | 12 ++++++++----
 1 file changed, 8 insertions(+), 4 deletions(-)

diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index f320eea..7b28bb5 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -74,21 +74,25 @@ describe('toFile', () => {
 });
 
 describe('missing File error message', () => {
-  let prevFile: unknown;
+  let prevGlobalFile: unknown;
+  let prevNodeFile: unknown;
   beforeEach(() => {
     // The file shim captures the global File object when it's first imported.
     // Reset modules before each test so we can test the error thrown when it's undefined.
     jest.resetModules();
+    const buffer = require('node:buffer');
     // @ts-ignore
-    prevFile = globalThis.File;
+    prevGlobalFile = globalThis.File;
+    prevNodeFile = buffer.File;
     // @ts-ignore
     globalThis.File = undefined;
-    require('node:buffer').File = undefined;
+    buffer.File = undefined;
   });
   afterEach(() => {
     // Clean up
     // @ts-ignore
-    globalThis.File = prevFile;
+    globalThis.File = prevGlobalFile;
+    require('node:buffer').File = prevNodeFile;
     jest.resetModules();
   });
 

From 54a7db864f182bd872aeceae04747930a3e419a7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 5 Mar 2025 10:43:21 +0000
Subject: [PATCH 10/44] chore(types): improved go to definition on fetchOptions
 (#53)

---
 src/internal/types.ts | 14 +++-----------
 1 file changed, 3 insertions(+), 11 deletions(-)

diff --git a/src/internal/types.ts b/src/internal/types.ts
index 50c16e9..c3bce5a 100644
--- a/src/internal/types.ts
+++ b/src/internal/types.ts
@@ -6,14 +6,6 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
 export type KeysEnum<T> = { [P in keyof Required<T>]: true };
 
 type NotAny<T> = [unknown] extends [T] ? never : T;
-type Literal<T> = PropertyKey extends T ? never : T;
-type MappedLiteralKeys<T> = T extends any ? Literal<keyof T> : never;
-type MappedIndex<T, K> =
-  T extends any ?
-    K extends keyof T ?
-      T[K]
-    : never
-  : never;
 
 /**
  * Some environments overload the global fetch function, and Parameters<T> only gets the last signature.
@@ -93,6 +85,6 @@ type RequestInits =
  * This type contains `RequestInit` options that may be available on the current runtime,
  * including per-platform extensions like `dispatcher`, `agent`, `client`, etc.
  */
-export type MergedRequestInit = {
-  [K in MappedLiteralKeys<RequestInits>]?: MappedIndex<RequestInits, K> | undefined;
-};
+export type MergedRequestInit = RequestInits &
+  /** We don't include these in the types as they'll be overridden for every request. */
+  Partial<Record<'body' | 'headers' | 'method' | 'signal', never>>;

From 25092c5070acc3602094bf34f304105cb7bd7157 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 5 Mar 2025 11:28:04 +0000
Subject: [PATCH 11/44] chore(docs): improve docs for withResponse/asResponse
 (#54)

---
 README.md | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/README.md b/README.md
index ae0223a..0cbfd5f 100644
--- a/README.md
+++ b/README.md
@@ -171,8 +171,10 @@ while (page.hasNextPage()) {
 ### Accessing raw Response data (e.g., headers)
 
 The "raw" `Response` returned by `fetch()` can be accessed through the `.asResponse()` method on the `APIPromise` type that all methods return.
+This method returns as soon as the headers for a successful response are received and does not consume the response body, so you are free to write custom parsing or streaming logic.
 
 You can also use the `.withResponse()` method to get the raw `Response` along with the parsed data.
+Unlike `.asResponse()` this method consumes the body, returning once it is parsed.
 
 <!-- prettier-ignore -->
 ```ts

From 71a1bef58884eb34434a3e590cf0942c8166d33b Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 11 Mar 2025 06:44:38 +0000
Subject: [PATCH 12/44] chore(internal): codegen related update (#55)

---
 scripts/bootstrap     | 2 +-
 src/internal/parse.ts | 4 ++--
 2 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/scripts/bootstrap b/scripts/bootstrap
index 05dd47a..0af58e2 100755
--- a/scripts/bootstrap
+++ b/scripts/bootstrap
@@ -4,7 +4,7 @@ set -e
 
 cd "$(dirname "$0")/.."
 
-if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ]; then
+if [ -f "Brewfile" ] && [ "$(uname -s)" = "Darwin" ] && [ "$SKIP_BREW" != "1" ]; then
   brew bundle check >/dev/null 2>&1 || {
     echo "==> Installing Homebrew dependencies…"
     brew bundle
diff --git a/src/internal/parse.ts b/src/internal/parse.ts
index 2085087..a12647d 100644
--- a/src/internal/parse.ts
+++ b/src/internal/parse.ts
@@ -26,8 +26,8 @@ export async function defaultParseResponse<T>(client: Gitpod, props: APIResponse
     }
 
     const contentType = response.headers.get('content-type');
-    const isJSON =
-      contentType?.includes('application/json') || contentType?.includes('application/vnd.api+json');
+    const mediaType = contentType?.split(';')[0]?.trim();
+    const isJSON = mediaType?.includes('application/json') || mediaType?.endsWith('+json');
     if (isJSON) {
       const json = await response.json();
       return json as T;

From 6431dc9927a315b9faf1e906c95930bcec65f3d5 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 14 Mar 2025 04:40:14 +0000
Subject: [PATCH 13/44] chore(internal): remove extra empty newlines (#56)

---
 .github/workflows/ci.yml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index e3530dc..0312165 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -63,4 +63,3 @@ jobs:
 
       - name: Run tests
         run: ./scripts/test
-

From 23166e607ec2b8915a97e974e09cdc0abdbc6c23 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 14 Mar 2025 04:50:04 +0000
Subject: [PATCH 14/44] fix(exports): ensure resource imports don't require
 /index (#57)

---
 src/resources/environments.ts                   | 3 +++
 src/resources/environments/automations.ts       | 3 +++
 src/resources/environments/automations/tasks.ts | 3 +++
 src/resources/organizations.ts                  | 3 +++
 src/resources/projects.ts                       | 3 +++
 src/resources/runners.ts                        | 3 +++
 src/resources/runners/configurations.ts         | 3 +++
 src/resources/users.ts                          | 3 +++
 8 files changed, 24 insertions(+)
 create mode 100644 src/resources/environments.ts
 create mode 100644 src/resources/environments/automations.ts
 create mode 100644 src/resources/environments/automations/tasks.ts
 create mode 100644 src/resources/organizations.ts
 create mode 100644 src/resources/projects.ts
 create mode 100644 src/resources/runners.ts
 create mode 100644 src/resources/runners/configurations.ts
 create mode 100644 src/resources/users.ts

diff --git a/src/resources/environments.ts b/src/resources/environments.ts
new file mode 100644
index 0000000..85fdba4
--- /dev/null
+++ b/src/resources/environments.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './environments/index';
diff --git a/src/resources/environments/automations.ts b/src/resources/environments/automations.ts
new file mode 100644
index 0000000..e13af42
--- /dev/null
+++ b/src/resources/environments/automations.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './automations/index';
diff --git a/src/resources/environments/automations/tasks.ts b/src/resources/environments/automations/tasks.ts
new file mode 100644
index 0000000..a93e814
--- /dev/null
+++ b/src/resources/environments/automations/tasks.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './tasks/index';
diff --git a/src/resources/organizations.ts b/src/resources/organizations.ts
new file mode 100644
index 0000000..61ddaf1
--- /dev/null
+++ b/src/resources/organizations.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './organizations/index';
diff --git a/src/resources/projects.ts b/src/resources/projects.ts
new file mode 100644
index 0000000..f9985fc
--- /dev/null
+++ b/src/resources/projects.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './projects/index';
diff --git a/src/resources/runners.ts b/src/resources/runners.ts
new file mode 100644
index 0000000..003f18c
--- /dev/null
+++ b/src/resources/runners.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './runners/index';
diff --git a/src/resources/runners/configurations.ts b/src/resources/runners/configurations.ts
new file mode 100644
index 0000000..451b34e
--- /dev/null
+++ b/src/resources/runners/configurations.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './configurations/index';
diff --git a/src/resources/users.ts b/src/resources/users.ts
new file mode 100644
index 0000000..db908c7
--- /dev/null
+++ b/src/resources/users.ts
@@ -0,0 +1,3 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+export * from './users/index';

From 716b94c4be5a42cfaf9f59fcdb9332b912113869 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 15 Mar 2025 04:08:41 +0000
Subject: [PATCH 15/44] fix(internal): add mts file + crypto shim types (#58)

---
 scripts/build                        | 11 +++--------
 src/internal/shims/crypto.node.d.mts |  1 +
 src/internal/shims/file.node.d.mts   |  1 +
 3 files changed, 5 insertions(+), 8 deletions(-)
 create mode 100644 src/internal/shims/crypto.node.d.mts
 create mode 100644 src/internal/shims/file.node.d.mts

diff --git a/scripts/build b/scripts/build
index 7b100ad..047fe3d 100755
--- a/scripts/build
+++ b/scripts/build
@@ -28,20 +28,15 @@ node scripts/utils/make-dist-package-json.cjs > dist/package.json
 
 # build to .js/.mjs/.d.ts files
 npm exec tsc-multi
-# we need to add exports = module.exports = Gitpod to index.js;
-# No way to get that from index.ts because it would cause compile errors
+# we need to patch index.js so that `new module.exports()` works for cjs backwards
+# compat. No way to get that from index.ts because it would cause compile errors
 # when building .mjs
 node scripts/utils/fix-index-exports.cjs
-# with "moduleResolution": "nodenext", if ESM resolves to index.d.ts,
-# it'll have TS errors on the default import.  But if it resolves to
-# index.d.mts the default import will work (even though both files have
-# the same export default statement)
-cp dist/index.d.ts dist/index.d.mts
 cp tsconfig.dist-src.json dist/src/tsconfig.json
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts
 mkdir -p dist/internal/shims
-cp src/internal/shims/*.{mjs,js,d.ts} dist/internal/shims
+cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims
 
 node scripts/utils/postprocess-files.cjs
 
diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts
new file mode 100644
index 0000000..5cc1963
--- /dev/null
+++ b/src/internal/shims/crypto.node.d.mts
@@ -0,0 +1 @@
+export { crypto } from './crypto.node.js';
diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts
new file mode 100644
index 0000000..38cc9ff
--- /dev/null
+++ b/src/internal/shims/file.node.d.mts
@@ -0,0 +1 @@
+export { File } from './file.node.js';

From 51d47fd93e6be04336019ec05c60841a5d25195c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 19 Mar 2025 08:04:20 +0000
Subject: [PATCH 16/44] chore(internal): minor client file refactoring (#59)

---
 src/client.ts                | 50 +++---------------------------------
 src/internal/types.ts        |  2 ++
 src/internal/utils/log.ts    | 30 +++++++++++++++++++++-
 src/internal/utils/values.ts |  8 ++++++
 4 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/src/client.ts b/src/client.ts
index 8c0af2b..4371dfa 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -1,10 +1,12 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
 import type { RequestInit, RequestInfo, BodyInit } from './internal/builtin-types';
-import type { HTTPMethod, PromiseOrValue, MergedRequestInit } from './internal/types';
+import type { HTTPMethod, PromiseOrValue, MergedRequestInit, FinalizedRequestInit } from './internal/types';
 import { uuid4 } from './internal/utils/uuid';
-import { validatePositiveInteger, isAbsoluteURL, hasOwn } from './internal/utils/values';
+import { validatePositiveInteger, isAbsoluteURL, safeJSON } from './internal/utils/values';
 import { sleep } from './internal/utils/sleep';
+import { type Logger, type LogLevel, parseLogLevel } from './internal/utils/log';
+export type { Logger, LogLevel } from './internal/utils/log';
 import { castToError, isAbortError } from './internal/errors';
 import type { APIResponseProps } from './internal/parse';
 import { getPlatformHeaders } from './internal/detect-platform';
@@ -235,48 +237,6 @@ import {
   Users,
 } from './resources/users/users';
 
-const safeJSON = (text: string) => {
-  try {
-    return JSON.parse(text);
-  } catch (err) {
-    return undefined;
-  }
-};
-
-type LogFn = (message: string, ...rest: unknown[]) => void;
-export type Logger = {
-  error: LogFn;
-  warn: LogFn;
-  info: LogFn;
-  debug: LogFn;
-};
-export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug';
-const parseLogLevel = (
-  maybeLevel: string | undefined,
-  sourceName: string,
-  client: Gitpod,
-): LogLevel | undefined => {
-  if (!maybeLevel) {
-    return undefined;
-  }
-  const levels: Record<LogLevel, true> = {
-    off: true,
-    error: true,
-    warn: true,
-    info: true,
-    debug: true,
-  };
-  if (hasOwn(levels, maybeLevel)) {
-    return maybeLevel;
-  }
-  loggerFor(client).warn(
-    `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(
-      Object.keys(levels),
-    )}`,
-  );
-  return undefined;
-};
-
 export interface ClientOptions {
   /**
    * Defaults to process.env['GITPOD_API_KEY'].
@@ -350,8 +310,6 @@ export interface ClientOptions {
   logger?: Logger | undefined;
 }
 
-type FinalizedRequestInit = RequestInit & { headers: Headers };
-
 /**
  * API Client for interfacing with the Gitpod API.
  */
diff --git a/src/internal/types.ts b/src/internal/types.ts
index c3bce5a..d7928cd 100644
--- a/src/internal/types.ts
+++ b/src/internal/types.ts
@@ -5,6 +5,8 @@ export type HTTPMethod = 'get' | 'post' | 'put' | 'patch' | 'delete';
 
 export type KeysEnum<T> = { [P in keyof Required<T>]: true };
 
+export type FinalizedRequestInit = RequestInit & { headers: Headers };
+
 type NotAny<T> = [unknown] extends [T] ? never : T;
 
 /**
diff --git a/src/internal/utils/log.ts b/src/internal/utils/log.ts
index e446d4c..8fdf60d 100644
--- a/src/internal/utils/log.ts
+++ b/src/internal/utils/log.ts
@@ -1,9 +1,18 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import type { LogLevel, Logger } from '../../client';
+import { hasOwn } from './values';
 import { type Gitpod } from '../../client';
 import { RequestOptions } from '../request-options';
 
+type LogFn = (message: string, ...rest: unknown[]) => void;
+export type Logger = {
+  error: LogFn;
+  warn: LogFn;
+  info: LogFn;
+  debug: LogFn;
+};
+export type LogLevel = 'off' | 'error' | 'warn' | 'info' | 'debug';
+
 const levelNumbers = {
   off: 0,
   error: 200,
@@ -12,6 +21,25 @@ const levelNumbers = {
   debug: 500,
 };
 
+export const parseLogLevel = (
+  maybeLevel: string | undefined,
+  sourceName: string,
+  client: Gitpod,
+): LogLevel | undefined => {
+  if (!maybeLevel) {
+    return undefined;
+  }
+  if (hasOwn(levelNumbers, maybeLevel)) {
+    return maybeLevel;
+  }
+  loggerFor(client).warn(
+    `${sourceName} was set to ${JSON.stringify(maybeLevel)}, expected one of ${JSON.stringify(
+      Object.keys(levelNumbers),
+    )}`,
+  );
+  return undefined;
+};
+
 function noop() {}
 
 function makeLogFn(fnLevel: keyof Logger, logger: Logger | undefined, logLevel: LogLevel) {
diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts
index 86e3eda..43b0e39 100644
--- a/src/internal/utils/values.ts
+++ b/src/internal/utils/values.ts
@@ -92,3 +92,11 @@ export const maybeCoerceBoolean = (value: unknown): boolean | undefined => {
   }
   return coerceBoolean(value);
 };
+
+export const safeJSON = (text: string) => {
+  try {
+    return JSON.parse(text);
+  } catch (err) {
+    return undefined;
+  }
+};

From 0049aac07585fb4a1536ef6ff191b4ba5d5b9720 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Mar 2025 04:51:04 +0000
Subject: [PATCH 17/44] chore(exports): cleaner resource index imports (#60)

---
 src/resources.ts | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 src/resources.ts

diff --git a/src/resources.ts b/src/resources.ts
new file mode 100644
index 0000000..b283d57
--- /dev/null
+++ b/src/resources.ts
@@ -0,0 +1 @@
+export * from './resources/index';

From a9df2c166e44d19ff8b374e5225d29971c72bb3e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 20 Mar 2025 04:52:28 +0000
Subject: [PATCH 18/44] chore(exports): stop using path fallbacks (#61)

---
 scripts/utils/postprocess-files.cjs | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/scripts/utils/postprocess-files.cjs b/scripts/utils/postprocess-files.cjs
index d16c864..deae575 100644
--- a/scripts/utils/postprocess-files.cjs
+++ b/scripts/utils/postprocess-files.cjs
@@ -50,14 +50,14 @@ async function postprocess() {
     if (entry.isDirectory() && entry.name !== 'src' && entry.name !== 'internal' && entry.name !== 'bin') {
       const subpath = './' + entry.name;
       newExports[subpath + '/*.mjs'] = {
-        default: [subpath + '/*.mjs', subpath + '/*/index.mjs'],
+        default: subpath + '/*.mjs',
       };
       newExports[subpath + '/*.js'] = {
-        default: [subpath + '/*.js', subpath + '/*/index.js'],
+        default: subpath + '/*.js',
       };
       newExports[subpath + '/*'] = {
-        import: [subpath + '/*.mjs', subpath + '/*/index.mjs'],
-        require: [subpath + '/*.js', subpath + '/*/index.js'],
+        import: subpath + '/*.mjs',
+        require: subpath + '/*.js',
       };
     } else if (entry.isFile() && /\.[cm]?js$/.test(entry.name)) {
       const { name, ext } = path.parse(entry.name);

From b79e1f2dd9348ab00466e4477af0fe08670354e4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 27 Mar 2025 03:35:22 +0000
Subject: [PATCH 19/44] codegen metadata

---
 .stats.yml | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/.stats.yml b/.stats.yml
index 2c4d8ac..e8f1d28 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,2 +1,4 @@
 configured_endpoints: 111
 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3655d5ad0ac3e228c1519af70dbf3d0bfa3c47a2d06d4cac92a650da051b49a6.yml
+openapi_spec_hash: 5dbb5577e6a7cae7db615b1b06c9d23e
+config_hash: 719ad411c0ec7402a7a4c1f95515280c

From e4008c3ab36557410e2124287eb9ab861e5d81d2 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 27 Mar 2025 03:42:03 +0000
Subject: [PATCH 20/44] chore(client): move misc public files to new `core/`
 directory, deprecate old paths (#62)

---
 src/api-promise.ts                            |   94 +-
 src/client.ts                                 |   10 +-
 src/core/README.md                            |    3 +
 src/core/api-promise.ts                       |   92 ++
 src/core/error.ts                             |  140 ++
 src/core/pagination.ts                        | 1220 ++++++++++++++++
 src/core/resource.ts                          |   11 +
 src/core/uploads.ts                           |    2 +
 src/error.ts                                  |  142 +-
 src/index.ts                                  |    8 +-
 src/internal/README.md                        |    3 +
 src/internal/decoders/jsonl.ts                |    2 +-
 src/internal/decoders/line.ts                 |    2 +-
 src/internal/utils/base64.ts                  |    2 +-
 src/internal/utils/path.ts                    |    2 +-
 src/internal/utils/values.ts                  |    2 +-
 src/pagination.ts                             | 1222 +----------------
 src/resource.ts                               |   13 +-
 src/resources/accounts.ts                     |    6 +-
 src/resources/editors.ts                      |    6 +-
 .../environments/automations/automations.ts   |    4 +-
 .../environments/automations/services.ts      |    6 +-
 .../automations/tasks/executions.ts           |    6 +-
 .../environments/automations/tasks/tasks.ts   |    6 +-
 src/resources/environments/classes.ts         |    8 +-
 src/resources/environments/environments.ts    |    6 +-
 src/resources/events.ts                       |    6 +-
 src/resources/groups.ts                       |    4 +-
 src/resources/identity.ts                     |    4 +-
 .../organizations/domain-verifications.ts     |   10 +-
 src/resources/organizations/invites.ts        |    4 +-
 src/resources/organizations/organizations.ts  |    6 +-
 .../organizations/sso-configurations.ts       |    6 +-
 src/resources/projects/policies.ts            |    6 +-
 src/resources/projects/projects.ts            |    6 +-
 .../runners/configurations/configurations.ts  |    4 +-
 .../configurations/environment-classes.ts     |   10 +-
 .../host-authentication-tokens.ts             |    6 +-
 .../runners/configurations/schema.ts          |    4 +-
 .../configurations/scm-integrations.ts        |    6 +-
 src/resources/runners/policies.ts             |    6 +-
 src/resources/runners/runners.ts              |    6 +-
 src/resources/secrets.ts                      |    6 +-
 src/resources/shared.ts                       |    2 +-
 src/resources/users/pats.ts                   |   10 +-
 src/resources/users/users.ts                  |    4 +-
 src/uploads.ts                                |    4 +-
 tests/form.test.ts                            |    2 +-
 tests/index.test.ts                           |    2 +-
 tests/uploads.test.ts                         |    4 +-
 50 files changed, 1589 insertions(+), 1557 deletions(-)
 create mode 100644 src/core/README.md
 create mode 100644 src/core/api-promise.ts
 create mode 100644 src/core/error.ts
 create mode 100644 src/core/pagination.ts
 create mode 100644 src/core/resource.ts
 create mode 100644 src/core/uploads.ts
 create mode 100644 src/internal/README.md

diff --git a/src/api-promise.ts b/src/api-promise.ts
index a7416b0..8c775ee 100644
--- a/src/api-promise.ts
+++ b/src/api-promise.ts
@@ -1,92 +1,2 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { type Gitpod } from './client';
-
-import { type PromiseOrValue } from './internal/types';
-import { APIResponseProps, defaultParseResponse } from './internal/parse';
-
-/**
- * A subclass of `Promise` providing additional helper methods
- * for interacting with the SDK.
- */
-export class APIPromise<T> extends Promise<T> {
-  private parsedPromise: Promise<T> | undefined;
-  #client: Gitpod;
-
-  constructor(
-    client: Gitpod,
-    private responsePromise: Promise<APIResponseProps>,
-    private parseResponse: (
-      client: Gitpod,
-      props: APIResponseProps,
-    ) => PromiseOrValue<T> = defaultParseResponse,
-  ) {
-    super((resolve) => {
-      // this is maybe a bit weird but this has to be a no-op to not implicitly
-      // parse the response body; instead .then, .catch, .finally are overridden
-      // to parse the response
-      resolve(null as any);
-    });
-    this.#client = client;
-  }
-
-  _thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
-    return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
-      transform(await this.parseResponse(client, props), props),
-    );
-  }
-
-  /**
-   * Gets the raw `Response` instance instead of parsing the response
-   * data.
-   *
-   * If you want to parse the response body but still get the `Response`
-   * instance, you can use {@link withResponse()}.
-   *
-   * 👋 Getting the wrong TypeScript type for `Response`?
-   * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
-   * to your `tsconfig.json`.
-   */
-  asResponse(): Promise<Response> {
-    return this.responsePromise.then((p) => p.response);
-  }
-
-  /**
-   * Gets the parsed response data and the raw `Response` instance.
-   *
-   * If you just want to get the raw `Response` instance without parsing it,
-   * you can use {@link asResponse()}.
-   *
-   * 👋 Getting the wrong TypeScript type for `Response`?
-   * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
-   * to your `tsconfig.json`.
-   */
-  async withResponse(): Promise<{ data: T; response: Response }> {
-    const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
-    return { data, response };
-  }
-
-  private parse(): Promise<T> {
-    if (!this.parsedPromise) {
-      this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
-    }
-    return this.parsedPromise;
-  }
-
-  override then<TResult1 = T, TResult2 = never>(
-    onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
-    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
-  ): Promise<TResult1 | TResult2> {
-    return this.parse().then(onfulfilled, onrejected);
-  }
-
-  override catch<TResult = never>(
-    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
-  ): Promise<T | TResult> {
-    return this.parse().catch(onrejected);
-  }
-
-  override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
-    return this.parse().finally(onfinally);
-  }
-}
+/** @deprecated Import from ./core/api-promise instead */
+export * from './core/api-promise';
diff --git a/src/client.ts b/src/client.ts
index 4371dfa..ef0b007 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -13,8 +13,8 @@ import { getPlatformHeaders } from './internal/detect-platform';
 import * as Shims from './internal/shims';
 import * as Opts from './internal/request-options';
 import { VERSION } from './version';
-import * as Errors from './error';
-import * as Pagination from './pagination';
+import * as Errors from './core/error';
+import * as Pagination from './core/pagination';
 import {
   AbstractPage,
   type DomainVerificationsPageParams,
@@ -57,10 +57,10 @@ import {
   TasksPageResponse,
   type TokensPageParams,
   TokensPageResponse,
-} from './pagination';
-import * as Uploads from './uploads';
+} from './core/pagination';
+import * as Uploads from './core/uploads';
 import * as API from './resources/index';
-import { APIPromise } from './api-promise';
+import { APIPromise } from './core/api-promise';
 import { type Fetch } from './internal/builtin-types';
 import { HeadersLike, NullableHeaders, buildHeaders } from './internal/headers';
 import { FinalRequestOptions, RequestOptions } from './internal/request-options';
diff --git a/src/core/README.md b/src/core/README.md
new file mode 100644
index 0000000..485fce8
--- /dev/null
+++ b/src/core/README.md
@@ -0,0 +1,3 @@
+# `core`
+
+This directory holds public modules implementing non-resource-specific SDK functionality.
diff --git a/src/core/api-promise.ts b/src/core/api-promise.ts
new file mode 100644
index 0000000..639a545
--- /dev/null
+++ b/src/core/api-promise.ts
@@ -0,0 +1,92 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { type Gitpod } from '../client';
+
+import { type PromiseOrValue } from '../internal/types';
+import { APIResponseProps, defaultParseResponse } from '../internal/parse';
+
+/**
+ * A subclass of `Promise` providing additional helper methods
+ * for interacting with the SDK.
+ */
+export class APIPromise<T> extends Promise<T> {
+  private parsedPromise: Promise<T> | undefined;
+  #client: Gitpod;
+
+  constructor(
+    client: Gitpod,
+    private responsePromise: Promise<APIResponseProps>,
+    private parseResponse: (
+      client: Gitpod,
+      props: APIResponseProps,
+    ) => PromiseOrValue<T> = defaultParseResponse,
+  ) {
+    super((resolve) => {
+      // this is maybe a bit weird but this has to be a no-op to not implicitly
+      // parse the response body; instead .then, .catch, .finally are overridden
+      // to parse the response
+      resolve(null as any);
+    });
+    this.#client = client;
+  }
+
+  _thenUnwrap<U>(transform: (data: T, props: APIResponseProps) => U): APIPromise<U> {
+    return new APIPromise(this.#client, this.responsePromise, async (client, props) =>
+      transform(await this.parseResponse(client, props), props),
+    );
+  }
+
+  /**
+   * Gets the raw `Response` instance instead of parsing the response
+   * data.
+   *
+   * If you want to parse the response body but still get the `Response`
+   * instance, you can use {@link withResponse()}.
+   *
+   * 👋 Getting the wrong TypeScript type for `Response`?
+   * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
+   * to your `tsconfig.json`.
+   */
+  asResponse(): Promise<Response> {
+    return this.responsePromise.then((p) => p.response);
+  }
+
+  /**
+   * Gets the parsed response data and the raw `Response` instance.
+   *
+   * If you just want to get the raw `Response` instance without parsing it,
+   * you can use {@link asResponse()}.
+   *
+   * 👋 Getting the wrong TypeScript type for `Response`?
+   * Try setting `"moduleResolution": "NodeNext"` or add `"lib": ["DOM"]`
+   * to your `tsconfig.json`.
+   */
+  async withResponse(): Promise<{ data: T; response: Response }> {
+    const [data, response] = await Promise.all([this.parse(), this.asResponse()]);
+    return { data, response };
+  }
+
+  private parse(): Promise<T> {
+    if (!this.parsedPromise) {
+      this.parsedPromise = this.responsePromise.then((data) => this.parseResponse(this.#client, data));
+    }
+    return this.parsedPromise;
+  }
+
+  override then<TResult1 = T, TResult2 = never>(
+    onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | undefined | null,
+    onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | undefined | null,
+  ): Promise<TResult1 | TResult2> {
+    return this.parse().then(onfulfilled, onrejected);
+  }
+
+  override catch<TResult = never>(
+    onrejected?: ((reason: any) => TResult | PromiseLike<TResult>) | undefined | null,
+  ): Promise<T | TResult> {
+    return this.parse().catch(onrejected);
+  }
+
+  override finally(onfinally?: (() => void) | undefined | null): Promise<T> {
+    return this.parse().finally(onfinally);
+  }
+}
diff --git a/src/core/error.ts b/src/core/error.ts
new file mode 100644
index 0000000..1b22334
--- /dev/null
+++ b/src/core/error.ts
@@ -0,0 +1,140 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { castToError } from '../internal/errors';
+import * as Shared from '../resources/shared';
+
+export class GitpodError extends Error {}
+
+export class APIError<
+  TStatus extends number | undefined = number | undefined,
+  THeaders extends Headers | undefined = Headers | undefined,
+  TError extends Object | undefined = Object | undefined,
+> extends GitpodError {
+  /** HTTP status for the response that caused the error */
+  readonly status: TStatus;
+  /** HTTP headers for the response that caused the error */
+  readonly headers: THeaders;
+  /** JSON body of the response that caused the error */
+  readonly error: TError;
+
+  /**
+   * The status code, which should be an enum value of
+   * [google.rpc.Code][google.rpc.Code].
+   */
+  readonly code?: Shared.ErrorCode | undefined;
+
+  constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) {
+    super(`${APIError.makeMessage(status, error, message)}`);
+    this.status = status;
+    this.headers = headers;
+    this.error = error;
+
+    const data = error as Record<string, any>;
+    this.code = data?.['code'];
+  }
+
+  private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
+    const msg =
+      error?.message ?
+        typeof error.message === 'string' ?
+          error.message
+        : JSON.stringify(error.message)
+      : error ? JSON.stringify(error)
+      : message;
+
+    if (status && msg) {
+      return `${status} ${msg}`;
+    }
+    if (status) {
+      return `${status} status code (no body)`;
+    }
+    if (msg) {
+      return msg;
+    }
+    return '(no status code or body)';
+  }
+
+  static generate(
+    status: number | undefined,
+    errorResponse: Object | undefined,
+    message: string | undefined,
+    headers: Headers | undefined,
+  ): APIError {
+    if (!status || !headers) {
+      return new APIConnectionError({ message, cause: castToError(errorResponse) });
+    }
+
+    const error = errorResponse as Record<string, any>;
+
+    if (status === 400) {
+      return new BadRequestError(status, error, message, headers);
+    }
+
+    if (status === 401) {
+      return new AuthenticationError(status, error, message, headers);
+    }
+
+    if (status === 403) {
+      return new PermissionDeniedError(status, error, message, headers);
+    }
+
+    if (status === 404) {
+      return new NotFoundError(status, error, message, headers);
+    }
+
+    if (status === 409) {
+      return new ConflictError(status, error, message, headers);
+    }
+
+    if (status === 422) {
+      return new UnprocessableEntityError(status, error, message, headers);
+    }
+
+    if (status === 429) {
+      return new RateLimitError(status, error, message, headers);
+    }
+
+    if (status >= 500) {
+      return new InternalServerError(status, error, message, headers);
+    }
+
+    return new APIError(status, error, message, headers);
+  }
+}
+
+export class APIUserAbortError extends APIError<undefined, undefined, undefined> {
+  constructor({ message }: { message?: string } = {}) {
+    super(undefined, undefined, message || 'Request was aborted.', undefined);
+  }
+}
+
+export class APIConnectionError extends APIError<undefined, undefined, undefined> {
+  constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) {
+    super(undefined, undefined, message || 'Connection error.', undefined);
+    // in some environments the 'cause' property is already declared
+    // @ts-ignore
+    if (cause) this.cause = cause;
+  }
+}
+
+export class APIConnectionTimeoutError extends APIConnectionError {
+  constructor({ message }: { message?: string } = {}) {
+    super({ message: message ?? 'Request timed out.' });
+  }
+}
+
+export class BadRequestError extends APIError<400, Headers> {}
+
+export class AuthenticationError extends APIError<401, Headers> {}
+
+export class PermissionDeniedError extends APIError<403, Headers> {}
+
+export class NotFoundError extends APIError<404, Headers> {}
+
+export class ConflictError extends APIError<409, Headers> {}
+
+export class UnprocessableEntityError extends APIError<422, Headers> {}
+
+export class RateLimitError extends APIError<429, Headers> {}
+
+export class InternalServerError extends APIError<number, Headers> {}
diff --git a/src/core/pagination.ts b/src/core/pagination.ts
new file mode 100644
index 0000000..5ae7b97
--- /dev/null
+++ b/src/core/pagination.ts
@@ -0,0 +1,1220 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { GitpodError } from './error';
+import { FinalRequestOptions } from '../internal/request-options';
+import { defaultParseResponse } from '../internal/parse';
+import { type Gitpod } from '../client';
+import { APIPromise } from './api-promise';
+import { type APIResponseProps } from '../internal/parse';
+import { maybeObj } from '../internal/utils/values';
+
+export type PageRequestOptions = Pick<FinalRequestOptions, 'query' | 'headers' | 'body' | 'path' | 'method'>;
+
+export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
+  #client: Gitpod;
+  protected options: FinalRequestOptions;
+
+  protected response: Response;
+  protected body: unknown;
+
+  constructor(client: Gitpod, response: Response, body: unknown, options: FinalRequestOptions) {
+    this.#client = client;
+    this.options = options;
+    this.response = response;
+    this.body = body;
+  }
+
+  abstract nextPageRequestOptions(): PageRequestOptions | null;
+
+  abstract getPaginatedItems(): Item[];
+
+  hasNextPage(): boolean {
+    const items = this.getPaginatedItems();
+    if (!items.length) return false;
+    return this.nextPageRequestOptions() != null;
+  }
+
+  async getNextPage(): Promise<this> {
+    const nextOptions = this.nextPageRequestOptions();
+    if (!nextOptions) {
+      throw new GitpodError(
+        'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.',
+      );
+    }
+
+    return await this.#client.requestAPIList(this.constructor as any, nextOptions);
+  }
+
+  async *iterPages(): AsyncGenerator<this> {
+    let page: this = this;
+    yield page;
+    while (page.hasNextPage()) {
+      page = await page.getNextPage();
+      yield page;
+    }
+  }
+
+  async *[Symbol.asyncIterator](): AsyncGenerator<Item> {
+    for await (const page of this.iterPages()) {
+      for (const item of page.getPaginatedItems()) {
+        yield item;
+      }
+    }
+  }
+}
+
+/**
+ * This subclass of Promise will resolve to an instantiated Page once the request completes.
+ *
+ * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg:
+ *
+ *    for await (const item of client.items.list()) {
+ *      console.log(item)
+ *    }
+ */
+export class PagePromise<
+    PageClass extends AbstractPage<Item>,
+    Item = ReturnType<PageClass['getPaginatedItems']>[number],
+  >
+  extends APIPromise<PageClass>
+  implements AsyncIterable<Item>
+{
+  constructor(
+    client: Gitpod,
+    request: Promise<APIResponseProps>,
+    Page: new (...args: ConstructorParameters<typeof AbstractPage>) => PageClass,
+  ) {
+    super(
+      client,
+      request,
+      async (client, props) =>
+        new Page(client, props.response, await defaultParseResponse(client, props), props.options),
+    );
+  }
+
+  /**
+   * Allow auto-paginating iteration on an unawaited list call, eg:
+   *
+   *    for await (const item of client.items.list()) {
+   *      console.log(item)
+   *    }
+   */
+  async *[Symbol.asyncIterator]() {
+    const page = await this;
+    for await (const item of page) {
+      yield item;
+    }
+  }
+}
+
+export interface DomainVerificationsPageResponse<Item> {
+  domainVerifications: Array<Item>;
+
+  pagination: DomainVerificationsPageResponse.Pagination;
+}
+
+export namespace DomainVerificationsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface DomainVerificationsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class DomainVerificationsPage<Item>
+  extends AbstractPage<Item>
+  implements DomainVerificationsPageResponse<Item>
+{
+  domainVerifications: Array<Item>;
+
+  pagination: DomainVerificationsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: DomainVerificationsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.domainVerifications = body.domainVerifications || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.domainVerifications ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface EditorsPageResponse<Item> {
+  editors: Array<Item>;
+
+  pagination: EditorsPageResponse.Pagination;
+}
+
+export namespace EditorsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface EditorsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class EditorsPage<Item> extends AbstractPage<Item> implements EditorsPageResponse<Item> {
+  editors: Array<Item>;
+
+  pagination: EditorsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: EditorsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.editors = body.editors || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.editors ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface EntriesPageResponse<Item> {
+  entries: Array<Item>;
+
+  pagination: EntriesPageResponse.Pagination;
+}
+
+export namespace EntriesPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface EntriesPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class EntriesPage<Item> extends AbstractPage<Item> implements EntriesPageResponse<Item> {
+  entries: Array<Item>;
+
+  pagination: EntriesPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: EntriesPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.entries = body.entries || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.entries ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface EnvironmentClassesPageResponse<Item> {
+  environmentClasses: Array<Item>;
+
+  pagination: EnvironmentClassesPageResponse.Pagination;
+}
+
+export namespace EnvironmentClassesPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface EnvironmentClassesPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class EnvironmentClassesPage<Item>
+  extends AbstractPage<Item>
+  implements EnvironmentClassesPageResponse<Item>
+{
+  environmentClasses: Array<Item>;
+
+  pagination: EnvironmentClassesPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: EnvironmentClassesPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.environmentClasses = body.environmentClasses || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.environmentClasses ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface EnvironmentsPageResponse<Item> {
+  environments: Array<Item>;
+
+  pagination: EnvironmentsPageResponse.Pagination;
+}
+
+export namespace EnvironmentsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface EnvironmentsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class EnvironmentsPage<Item> extends AbstractPage<Item> implements EnvironmentsPageResponse<Item> {
+  environments: Array<Item>;
+
+  pagination: EnvironmentsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: EnvironmentsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.environments = body.environments || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.environments ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface GroupsPageResponse<Item> {
+  groups: Array<Item>;
+
+  pagination: GroupsPageResponse.Pagination;
+}
+
+export namespace GroupsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface GroupsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class GroupsPage<Item> extends AbstractPage<Item> implements GroupsPageResponse<Item> {
+  groups: Array<Item>;
+
+  pagination: GroupsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: GroupsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.groups = body.groups || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.groups ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface IntegrationsPageResponse<Item> {
+  integrations: Array<Item>;
+
+  pagination: IntegrationsPageResponse.Pagination;
+}
+
+export namespace IntegrationsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface IntegrationsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class IntegrationsPage<Item> extends AbstractPage<Item> implements IntegrationsPageResponse<Item> {
+  integrations: Array<Item>;
+
+  pagination: IntegrationsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: IntegrationsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.integrations = body.integrations || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.integrations ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface LoginProvidersPageResponse<Item> {
+  loginProviders: Array<Item>;
+
+  pagination: LoginProvidersPageResponse.Pagination;
+}
+
+export namespace LoginProvidersPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface LoginProvidersPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class LoginProvidersPage<Item> extends AbstractPage<Item> implements LoginProvidersPageResponse<Item> {
+  loginProviders: Array<Item>;
+
+  pagination: LoginProvidersPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: LoginProvidersPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.loginProviders = body.loginProviders || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.loginProviders ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface MembersPageResponse<Item> {
+  members: Array<Item>;
+
+  pagination: MembersPageResponse.Pagination;
+}
+
+export namespace MembersPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface MembersPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class MembersPage<Item> extends AbstractPage<Item> implements MembersPageResponse<Item> {
+  members: Array<Item>;
+
+  pagination: MembersPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: MembersPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.members = body.members || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.members ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface OrganizationsPageResponse<Item> {
+  organizations: Array<Item>;
+
+  pagination: OrganizationsPageResponse.Pagination;
+}
+
+export namespace OrganizationsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface OrganizationsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class OrganizationsPage<Item> extends AbstractPage<Item> implements OrganizationsPageResponse<Item> {
+  organizations: Array<Item>;
+
+  pagination: OrganizationsPageResponse.Pagination;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: OrganizationsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.organizations = body.organizations || [];
+    this.pagination = body.pagination || {};
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.organizations ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface PersonalAccessTokensPageResponse<Item> {
+  pagination: PersonalAccessTokensPageResponse.Pagination;
+
+  personalAccessTokens: Array<Item>;
+}
+
+export namespace PersonalAccessTokensPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface PersonalAccessTokensPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class PersonalAccessTokensPage<Item>
+  extends AbstractPage<Item>
+  implements PersonalAccessTokensPageResponse<Item>
+{
+  pagination: PersonalAccessTokensPageResponse.Pagination;
+
+  personalAccessTokens: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: PersonalAccessTokensPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.personalAccessTokens = body.personalAccessTokens || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.personalAccessTokens ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface PoliciesPageResponse<Item> {
+  pagination: PoliciesPageResponse.Pagination;
+
+  policies: Array<Item>;
+}
+
+export namespace PoliciesPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface PoliciesPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class PoliciesPage<Item> extends AbstractPage<Item> implements PoliciesPageResponse<Item> {
+  pagination: PoliciesPageResponse.Pagination;
+
+  policies: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: PoliciesPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.policies = body.policies || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.policies ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface ProjectsPageResponse<Item> {
+  pagination: ProjectsPageResponse.Pagination;
+
+  projects: Array<Item>;
+}
+
+export namespace ProjectsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface ProjectsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class ProjectsPage<Item> extends AbstractPage<Item> implements ProjectsPageResponse<Item> {
+  pagination: ProjectsPageResponse.Pagination;
+
+  projects: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: ProjectsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.projects = body.projects || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.projects ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface RunnersPageResponse<Item> {
+  pagination: RunnersPageResponse.Pagination;
+
+  runners: Array<Item>;
+}
+
+export namespace RunnersPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface RunnersPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class RunnersPage<Item> extends AbstractPage<Item> implements RunnersPageResponse<Item> {
+  pagination: RunnersPageResponse.Pagination;
+
+  runners: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: RunnersPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.runners = body.runners || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.runners ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface SecretsPageResponse<Item> {
+  pagination: SecretsPageResponse.Pagination;
+
+  secrets: Array<Item>;
+}
+
+export namespace SecretsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface SecretsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class SecretsPage<Item> extends AbstractPage<Item> implements SecretsPageResponse<Item> {
+  pagination: SecretsPageResponse.Pagination;
+
+  secrets: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: SecretsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.secrets = body.secrets || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.secrets ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface ServicesPageResponse<Item> {
+  pagination: ServicesPageResponse.Pagination;
+
+  services: Array<Item>;
+}
+
+export namespace ServicesPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface ServicesPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class ServicesPage<Item> extends AbstractPage<Item> implements ServicesPageResponse<Item> {
+  pagination: ServicesPageResponse.Pagination;
+
+  services: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: ServicesPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.services = body.services || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.services ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface SSOConfigurationsPageResponse<Item> {
+  pagination: SSOConfigurationsPageResponse.Pagination;
+
+  ssoConfigurations: Array<Item>;
+}
+
+export namespace SSOConfigurationsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface SSOConfigurationsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class SSOConfigurationsPage<Item>
+  extends AbstractPage<Item>
+  implements SSOConfigurationsPageResponse<Item>
+{
+  pagination: SSOConfigurationsPageResponse.Pagination;
+
+  ssoConfigurations: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: SSOConfigurationsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.ssoConfigurations = body.ssoConfigurations || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.ssoConfigurations ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface TaskExecutionsPageResponse<Item> {
+  pagination: TaskExecutionsPageResponse.Pagination;
+
+  taskExecutions: Array<Item>;
+}
+
+export namespace TaskExecutionsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface TaskExecutionsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class TaskExecutionsPage<Item> extends AbstractPage<Item> implements TaskExecutionsPageResponse<Item> {
+  pagination: TaskExecutionsPageResponse.Pagination;
+
+  taskExecutions: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: TaskExecutionsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.taskExecutions = body.taskExecutions || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.taskExecutions ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface TasksPageResponse<Item> {
+  pagination: TasksPageResponse.Pagination;
+
+  tasks: Array<Item>;
+}
+
+export namespace TasksPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface TasksPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class TasksPage<Item> extends AbstractPage<Item> implements TasksPageResponse<Item> {
+  pagination: TasksPageResponse.Pagination;
+
+  tasks: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: TasksPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.tasks = body.tasks || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.tasks ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
+export interface TokensPageResponse<Item> {
+  pagination: TokensPageResponse.Pagination;
+
+  tokens: Array<Item>;
+}
+
+export namespace TokensPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface TokensPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class TokensPage<Item> extends AbstractPage<Item> implements TokensPageResponse<Item> {
+  pagination: TokensPageResponse.Pagination;
+
+  tokens: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: TokensPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.tokens = body.tokens || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.tokens ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
diff --git a/src/core/resource.ts b/src/core/resource.ts
new file mode 100644
index 0000000..c73b82d
--- /dev/null
+++ b/src/core/resource.ts
@@ -0,0 +1,11 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import type { Gitpod } from '../client';
+
+export class APIResource {
+  protected _client: Gitpod;
+
+  constructor(client: Gitpod) {
+    this._client = client;
+  }
+}
diff --git a/src/core/uploads.ts b/src/core/uploads.ts
new file mode 100644
index 0000000..2882ca6
--- /dev/null
+++ b/src/core/uploads.ts
@@ -0,0 +1,2 @@
+export { type Uploadable } from '../internal/uploads';
+export { toFile, type ToFileInput } from '../internal/to-file';
diff --git a/src/error.ts b/src/error.ts
index 67145c6..fc55f46 100644
--- a/src/error.ts
+++ b/src/error.ts
@@ -1,140 +1,2 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { castToError } from './internal/errors';
-import * as Shared from './resources/shared';
-
-export class GitpodError extends Error {}
-
-export class APIError<
-  TStatus extends number | undefined = number | undefined,
-  THeaders extends Headers | undefined = Headers | undefined,
-  TError extends Object | undefined = Object | undefined,
-> extends GitpodError {
-  /** HTTP status for the response that caused the error */
-  readonly status: TStatus;
-  /** HTTP headers for the response that caused the error */
-  readonly headers: THeaders;
-  /** JSON body of the response that caused the error */
-  readonly error: TError;
-
-  /**
-   * The status code, which should be an enum value of
-   * [google.rpc.Code][google.rpc.Code].
-   */
-  readonly code?: Shared.ErrorCode | undefined;
-
-  constructor(status: TStatus, error: TError, message: string | undefined, headers: THeaders) {
-    super(`${APIError.makeMessage(status, error, message)}`);
-    this.status = status;
-    this.headers = headers;
-    this.error = error;
-
-    const data = error as Record<string, any>;
-    this.code = data?.['code'];
-  }
-
-  private static makeMessage(status: number | undefined, error: any, message: string | undefined) {
-    const msg =
-      error?.message ?
-        typeof error.message === 'string' ?
-          error.message
-        : JSON.stringify(error.message)
-      : error ? JSON.stringify(error)
-      : message;
-
-    if (status && msg) {
-      return `${status} ${msg}`;
-    }
-    if (status) {
-      return `${status} status code (no body)`;
-    }
-    if (msg) {
-      return msg;
-    }
-    return '(no status code or body)';
-  }
-
-  static generate(
-    status: number | undefined,
-    errorResponse: Object | undefined,
-    message: string | undefined,
-    headers: Headers | undefined,
-  ): APIError {
-    if (!status || !headers) {
-      return new APIConnectionError({ message, cause: castToError(errorResponse) });
-    }
-
-    const error = errorResponse as Record<string, any>;
-
-    if (status === 400) {
-      return new BadRequestError(status, error, message, headers);
-    }
-
-    if (status === 401) {
-      return new AuthenticationError(status, error, message, headers);
-    }
-
-    if (status === 403) {
-      return new PermissionDeniedError(status, error, message, headers);
-    }
-
-    if (status === 404) {
-      return new NotFoundError(status, error, message, headers);
-    }
-
-    if (status === 409) {
-      return new ConflictError(status, error, message, headers);
-    }
-
-    if (status === 422) {
-      return new UnprocessableEntityError(status, error, message, headers);
-    }
-
-    if (status === 429) {
-      return new RateLimitError(status, error, message, headers);
-    }
-
-    if (status >= 500) {
-      return new InternalServerError(status, error, message, headers);
-    }
-
-    return new APIError(status, error, message, headers);
-  }
-}
-
-export class APIUserAbortError extends APIError<undefined, undefined, undefined> {
-  constructor({ message }: { message?: string } = {}) {
-    super(undefined, undefined, message || 'Request was aborted.', undefined);
-  }
-}
-
-export class APIConnectionError extends APIError<undefined, undefined, undefined> {
-  constructor({ message, cause }: { message?: string | undefined; cause?: Error | undefined }) {
-    super(undefined, undefined, message || 'Connection error.', undefined);
-    // in some environments the 'cause' property is already declared
-    // @ts-ignore
-    if (cause) this.cause = cause;
-  }
-}
-
-export class APIConnectionTimeoutError extends APIConnectionError {
-  constructor({ message }: { message?: string } = {}) {
-    super({ message: message ?? 'Request timed out.' });
-  }
-}
-
-export class BadRequestError extends APIError<400, Headers> {}
-
-export class AuthenticationError extends APIError<401, Headers> {}
-
-export class PermissionDeniedError extends APIError<403, Headers> {}
-
-export class NotFoundError extends APIError<404, Headers> {}
-
-export class ConflictError extends APIError<409, Headers> {}
-
-export class UnprocessableEntityError extends APIError<422, Headers> {}
-
-export class RateLimitError extends APIError<429, Headers> {}
-
-export class InternalServerError extends APIError<number, Headers> {}
+/** @deprecated Import from ./core/error instead */
+export * from './core/error';
diff --git a/src/index.ts b/src/index.ts
index 2b3917a..0eaf4c8 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,10 +2,10 @@
 
 export { Gitpod as default } from './client';
 
-export { type Uploadable, toFile } from './uploads';
-export { APIPromise } from './api-promise';
+export { type Uploadable, toFile } from './core/uploads';
+export { APIPromise } from './core/api-promise';
 export { Gitpod, type ClientOptions } from './client';
-export { PagePromise } from './pagination';
+export { PagePromise } from './core/pagination';
 export {
   GitpodError,
   APIError,
@@ -20,4 +20,4 @@ export {
   InternalServerError,
   PermissionDeniedError,
   UnprocessableEntityError,
-} from './error';
+} from './core/error';
diff --git a/src/internal/README.md b/src/internal/README.md
new file mode 100644
index 0000000..3ef5a25
--- /dev/null
+++ b/src/internal/README.md
@@ -0,0 +1,3 @@
+# `internal`
+
+The modules in this directory are not importable outside this package and will change between releases.
diff --git a/src/internal/decoders/jsonl.ts b/src/internal/decoders/jsonl.ts
index cb40d92..79ec5f8 100644
--- a/src/internal/decoders/jsonl.ts
+++ b/src/internal/decoders/jsonl.ts
@@ -1,4 +1,4 @@
-import { GitpodError } from '../../error';
+import { GitpodError } from '../../core/error';
 import { ReadableStreamToAsyncIterable } from '../shims';
 import { LineDecoder, type Bytes } from './line';
 
diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts
index 0295286..a4c237f 100644
--- a/src/internal/decoders/line.ts
+++ b/src/internal/decoders/line.ts
@@ -1,4 +1,4 @@
-import { GitpodError } from '../../error';
+import { GitpodError } from '../../core/error';
 
 export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
 
diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts
index 3b077b3..50d616c 100644
--- a/src/internal/utils/base64.ts
+++ b/src/internal/utils/base64.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { GitpodError } from '../../error';
+import { GitpodError } from '../../core/error';
 
 export const toBase64 = (data: string | Uint8Array | null | undefined): string => {
   if (!data) return '';
diff --git a/src/internal/utils/path.ts b/src/internal/utils/path.ts
index 0115b07..56154a2 100644
--- a/src/internal/utils/path.ts
+++ b/src/internal/utils/path.ts
@@ -1,4 +1,4 @@
-import { GitpodError } from '../../error';
+import { GitpodError } from '../../core/error';
 
 /**
  * Percent-encode everything that isn't safe to have in a path without encoding safe chars.
diff --git a/src/internal/utils/values.ts b/src/internal/utils/values.ts
index 43b0e39..d0e9c61 100644
--- a/src/internal/utils/values.ts
+++ b/src/internal/utils/values.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { GitpodError } from '../../error';
+import { GitpodError } from '../../core/error';
 
 // https://url.spec.whatwg.org/#url-scheme-string
 const startsWithSchemeRegexp = /^[a-z][a-z0-9+.-]*:/i;
diff --git a/src/pagination.ts b/src/pagination.ts
index 7bacc0a..90bf015 100644
--- a/src/pagination.ts
+++ b/src/pagination.ts
@@ -1,1220 +1,2 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import { GitpodError } from './error';
-import { FinalRequestOptions } from './internal/request-options';
-import { defaultParseResponse } from './internal/parse';
-import { APIPromise } from './api-promise';
-import { type Gitpod } from './client';
-import { type APIResponseProps } from './internal/parse';
-import { maybeObj } from './internal/utils/values';
-
-export type PageRequestOptions = Pick<FinalRequestOptions, 'query' | 'headers' | 'body' | 'path' | 'method'>;
-
-export abstract class AbstractPage<Item> implements AsyncIterable<Item> {
-  #client: Gitpod;
-  protected options: FinalRequestOptions;
-
-  protected response: Response;
-  protected body: unknown;
-
-  constructor(client: Gitpod, response: Response, body: unknown, options: FinalRequestOptions) {
-    this.#client = client;
-    this.options = options;
-    this.response = response;
-    this.body = body;
-  }
-
-  abstract nextPageRequestOptions(): PageRequestOptions | null;
-
-  abstract getPaginatedItems(): Item[];
-
-  hasNextPage(): boolean {
-    const items = this.getPaginatedItems();
-    if (!items.length) return false;
-    return this.nextPageRequestOptions() != null;
-  }
-
-  async getNextPage(): Promise<this> {
-    const nextOptions = this.nextPageRequestOptions();
-    if (!nextOptions) {
-      throw new GitpodError(
-        'No next page expected; please check `.hasNextPage()` before calling `.getNextPage()`.',
-      );
-    }
-
-    return await this.#client.requestAPIList(this.constructor as any, nextOptions);
-  }
-
-  async *iterPages(): AsyncGenerator<this> {
-    let page: this = this;
-    yield page;
-    while (page.hasNextPage()) {
-      page = await page.getNextPage();
-      yield page;
-    }
-  }
-
-  async *[Symbol.asyncIterator](): AsyncGenerator<Item> {
-    for await (const page of this.iterPages()) {
-      for (const item of page.getPaginatedItems()) {
-        yield item;
-      }
-    }
-  }
-}
-
-/**
- * This subclass of Promise will resolve to an instantiated Page once the request completes.
- *
- * It also implements AsyncIterable to allow auto-paginating iteration on an unawaited list call, eg:
- *
- *    for await (const item of client.items.list()) {
- *      console.log(item)
- *    }
- */
-export class PagePromise<
-    PageClass extends AbstractPage<Item>,
-    Item = ReturnType<PageClass['getPaginatedItems']>[number],
-  >
-  extends APIPromise<PageClass>
-  implements AsyncIterable<Item>
-{
-  constructor(
-    client: Gitpod,
-    request: Promise<APIResponseProps>,
-    Page: new (...args: ConstructorParameters<typeof AbstractPage>) => PageClass,
-  ) {
-    super(
-      client,
-      request,
-      async (client, props) =>
-        new Page(client, props.response, await defaultParseResponse(client, props), props.options),
-    );
-  }
-
-  /**
-   * Allow auto-paginating iteration on an unawaited list call, eg:
-   *
-   *    for await (const item of client.items.list()) {
-   *      console.log(item)
-   *    }
-   */
-  async *[Symbol.asyncIterator]() {
-    const page = await this;
-    for await (const item of page) {
-      yield item;
-    }
-  }
-}
-
-export interface DomainVerificationsPageResponse<Item> {
-  domainVerifications: Array<Item>;
-
-  pagination: DomainVerificationsPageResponse.Pagination;
-}
-
-export namespace DomainVerificationsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface DomainVerificationsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class DomainVerificationsPage<Item>
-  extends AbstractPage<Item>
-  implements DomainVerificationsPageResponse<Item>
-{
-  domainVerifications: Array<Item>;
-
-  pagination: DomainVerificationsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: DomainVerificationsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.domainVerifications = body.domainVerifications || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.domainVerifications ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface EditorsPageResponse<Item> {
-  editors: Array<Item>;
-
-  pagination: EditorsPageResponse.Pagination;
-}
-
-export namespace EditorsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface EditorsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class EditorsPage<Item> extends AbstractPage<Item> implements EditorsPageResponse<Item> {
-  editors: Array<Item>;
-
-  pagination: EditorsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: EditorsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.editors = body.editors || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.editors ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface EntriesPageResponse<Item> {
-  entries: Array<Item>;
-
-  pagination: EntriesPageResponse.Pagination;
-}
-
-export namespace EntriesPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface EntriesPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class EntriesPage<Item> extends AbstractPage<Item> implements EntriesPageResponse<Item> {
-  entries: Array<Item>;
-
-  pagination: EntriesPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: EntriesPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.entries = body.entries || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.entries ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface EnvironmentClassesPageResponse<Item> {
-  environmentClasses: Array<Item>;
-
-  pagination: EnvironmentClassesPageResponse.Pagination;
-}
-
-export namespace EnvironmentClassesPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface EnvironmentClassesPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class EnvironmentClassesPage<Item>
-  extends AbstractPage<Item>
-  implements EnvironmentClassesPageResponse<Item>
-{
-  environmentClasses: Array<Item>;
-
-  pagination: EnvironmentClassesPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: EnvironmentClassesPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.environmentClasses = body.environmentClasses || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.environmentClasses ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface EnvironmentsPageResponse<Item> {
-  environments: Array<Item>;
-
-  pagination: EnvironmentsPageResponse.Pagination;
-}
-
-export namespace EnvironmentsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface EnvironmentsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class EnvironmentsPage<Item> extends AbstractPage<Item> implements EnvironmentsPageResponse<Item> {
-  environments: Array<Item>;
-
-  pagination: EnvironmentsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: EnvironmentsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.environments = body.environments || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.environments ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface GroupsPageResponse<Item> {
-  groups: Array<Item>;
-
-  pagination: GroupsPageResponse.Pagination;
-}
-
-export namespace GroupsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface GroupsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class GroupsPage<Item> extends AbstractPage<Item> implements GroupsPageResponse<Item> {
-  groups: Array<Item>;
-
-  pagination: GroupsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: GroupsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.groups = body.groups || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.groups ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface IntegrationsPageResponse<Item> {
-  integrations: Array<Item>;
-
-  pagination: IntegrationsPageResponse.Pagination;
-}
-
-export namespace IntegrationsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface IntegrationsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class IntegrationsPage<Item> extends AbstractPage<Item> implements IntegrationsPageResponse<Item> {
-  integrations: Array<Item>;
-
-  pagination: IntegrationsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: IntegrationsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.integrations = body.integrations || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.integrations ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface LoginProvidersPageResponse<Item> {
-  loginProviders: Array<Item>;
-
-  pagination: LoginProvidersPageResponse.Pagination;
-}
-
-export namespace LoginProvidersPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface LoginProvidersPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class LoginProvidersPage<Item> extends AbstractPage<Item> implements LoginProvidersPageResponse<Item> {
-  loginProviders: Array<Item>;
-
-  pagination: LoginProvidersPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: LoginProvidersPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.loginProviders = body.loginProviders || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.loginProviders ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface MembersPageResponse<Item> {
-  members: Array<Item>;
-
-  pagination: MembersPageResponse.Pagination;
-}
-
-export namespace MembersPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface MembersPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class MembersPage<Item> extends AbstractPage<Item> implements MembersPageResponse<Item> {
-  members: Array<Item>;
-
-  pagination: MembersPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: MembersPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.members = body.members || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.members ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface OrganizationsPageResponse<Item> {
-  organizations: Array<Item>;
-
-  pagination: OrganizationsPageResponse.Pagination;
-}
-
-export namespace OrganizationsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface OrganizationsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class OrganizationsPage<Item> extends AbstractPage<Item> implements OrganizationsPageResponse<Item> {
-  organizations: Array<Item>;
-
-  pagination: OrganizationsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: OrganizationsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.organizations = body.organizations || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.organizations ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface PersonalAccessTokensPageResponse<Item> {
-  pagination: PersonalAccessTokensPageResponse.Pagination;
-
-  personalAccessTokens: Array<Item>;
-}
-
-export namespace PersonalAccessTokensPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface PersonalAccessTokensPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class PersonalAccessTokensPage<Item>
-  extends AbstractPage<Item>
-  implements PersonalAccessTokensPageResponse<Item>
-{
-  pagination: PersonalAccessTokensPageResponse.Pagination;
-
-  personalAccessTokens: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: PersonalAccessTokensPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.personalAccessTokens = body.personalAccessTokens || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.personalAccessTokens ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface PoliciesPageResponse<Item> {
-  pagination: PoliciesPageResponse.Pagination;
-
-  policies: Array<Item>;
-}
-
-export namespace PoliciesPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface PoliciesPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class PoliciesPage<Item> extends AbstractPage<Item> implements PoliciesPageResponse<Item> {
-  pagination: PoliciesPageResponse.Pagination;
-
-  policies: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: PoliciesPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.policies = body.policies || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.policies ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface ProjectsPageResponse<Item> {
-  pagination: ProjectsPageResponse.Pagination;
-
-  projects: Array<Item>;
-}
-
-export namespace ProjectsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface ProjectsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class ProjectsPage<Item> extends AbstractPage<Item> implements ProjectsPageResponse<Item> {
-  pagination: ProjectsPageResponse.Pagination;
-
-  projects: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: ProjectsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.projects = body.projects || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.projects ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface RunnersPageResponse<Item> {
-  pagination: RunnersPageResponse.Pagination;
-
-  runners: Array<Item>;
-}
-
-export namespace RunnersPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface RunnersPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class RunnersPage<Item> extends AbstractPage<Item> implements RunnersPageResponse<Item> {
-  pagination: RunnersPageResponse.Pagination;
-
-  runners: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: RunnersPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.runners = body.runners || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.runners ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface SecretsPageResponse<Item> {
-  pagination: SecretsPageResponse.Pagination;
-
-  secrets: Array<Item>;
-}
-
-export namespace SecretsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface SecretsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class SecretsPage<Item> extends AbstractPage<Item> implements SecretsPageResponse<Item> {
-  pagination: SecretsPageResponse.Pagination;
-
-  secrets: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: SecretsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.secrets = body.secrets || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.secrets ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface ServicesPageResponse<Item> {
-  pagination: ServicesPageResponse.Pagination;
-
-  services: Array<Item>;
-}
-
-export namespace ServicesPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface ServicesPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class ServicesPage<Item> extends AbstractPage<Item> implements ServicesPageResponse<Item> {
-  pagination: ServicesPageResponse.Pagination;
-
-  services: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: ServicesPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.services = body.services || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.services ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface SSOConfigurationsPageResponse<Item> {
-  pagination: SSOConfigurationsPageResponse.Pagination;
-
-  ssoConfigurations: Array<Item>;
-}
-
-export namespace SSOConfigurationsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface SSOConfigurationsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class SSOConfigurationsPage<Item>
-  extends AbstractPage<Item>
-  implements SSOConfigurationsPageResponse<Item>
-{
-  pagination: SSOConfigurationsPageResponse.Pagination;
-
-  ssoConfigurations: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: SSOConfigurationsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.ssoConfigurations = body.ssoConfigurations || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.ssoConfigurations ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface TaskExecutionsPageResponse<Item> {
-  pagination: TaskExecutionsPageResponse.Pagination;
-
-  taskExecutions: Array<Item>;
-}
-
-export namespace TaskExecutionsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface TaskExecutionsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class TaskExecutionsPage<Item> extends AbstractPage<Item> implements TaskExecutionsPageResponse<Item> {
-  pagination: TaskExecutionsPageResponse.Pagination;
-
-  taskExecutions: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: TaskExecutionsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.taskExecutions = body.taskExecutions || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.taskExecutions ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface TasksPageResponse<Item> {
-  pagination: TasksPageResponse.Pagination;
-
-  tasks: Array<Item>;
-}
-
-export namespace TasksPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface TasksPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class TasksPage<Item> extends AbstractPage<Item> implements TasksPageResponse<Item> {
-  pagination: TasksPageResponse.Pagination;
-
-  tasks: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: TasksPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.tasks = body.tasks || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.tasks ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
-export interface TokensPageResponse<Item> {
-  pagination: TokensPageResponse.Pagination;
-
-  tokens: Array<Item>;
-}
-
-export namespace TokensPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface TokensPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class TokensPage<Item> extends AbstractPage<Item> implements TokensPageResponse<Item> {
-  pagination: TokensPageResponse.Pagination;
-
-  tokens: Array<Item>;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: TokensPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.pagination = body.pagination || {};
-    this.tokens = body.tokens || [];
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.tokens ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
+/** @deprecated Import from ./core/pagination instead */
+export * from './core/pagination';
diff --git a/src/resource.ts b/src/resource.ts
index ce38897..363e351 100644
--- a/src/resource.ts
+++ b/src/resource.ts
@@ -1,11 +1,2 @@
-// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
-
-import type { Gitpod } from './client';
-
-export class APIResource {
-  protected _client: Gitpod;
-
-  constructor(client: Gitpod) {
-    this._client = client;
-  }
-}
+/** @deprecated Import from ./core/resource instead */
+export * from './core/resource';
diff --git a/src/resources/accounts.ts b/src/resources/accounts.ts
index 6704ddc..b341c47 100644
--- a/src/resources/accounts.ts
+++ b/src/resources/accounts.ts
@@ -1,9 +1,9 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
+import { APIResource } from '../core/resource';
 import * as Shared from './shared';
-import { APIPromise } from '../api-promise';
-import { LoginProvidersPage, type LoginProvidersPageParams, PagePromise } from '../pagination';
+import { APIPromise } from '../core/api-promise';
+import { LoginProvidersPage, type LoginProvidersPageParams, PagePromise } from '../core/pagination';
 import { RequestOptions } from '../internal/request-options';
 
 export class Accounts extends APIResource {
diff --git a/src/resources/editors.ts b/src/resources/editors.ts
index 11232fc..28832f9 100644
--- a/src/resources/editors.ts
+++ b/src/resources/editors.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
-import { APIPromise } from '../api-promise';
-import { EditorsPage, type EditorsPageParams, PagePromise } from '../pagination';
+import { APIResource } from '../core/resource';
+import { APIPromise } from '../core/api-promise';
+import { EditorsPage, type EditorsPageParams, PagePromise } from '../core/pagination';
 import { RequestOptions } from '../internal/request-options';
 
 export class Editors extends APIResource {
diff --git a/src/resources/environments/automations/automations.ts b/src/resources/environments/automations/automations.ts
index 9659f33..a369c3c 100644
--- a/src/resources/environments/automations/automations.ts
+++ b/src/resources/environments/automations/automations.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
+import { APIResource } from '../../../core/resource';
 import * as Shared from '../../shared';
 import * as ServicesAPI from './services';
 import {
@@ -40,7 +40,7 @@ import {
   TaskUpdateResponse,
   Tasks as TasksAPITasks,
 } from './tasks/tasks';
-import { APIPromise } from '../../../api-promise';
+import { APIPromise } from '../../../core/api-promise';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class Automations extends APIResource {
diff --git a/src/resources/environments/automations/services.ts b/src/resources/environments/automations/services.ts
index 4089844..6941f18 100644
--- a/src/resources/environments/automations/services.ts
+++ b/src/resources/environments/automations/services.ts
@@ -1,10 +1,10 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
+import { APIResource } from '../../../core/resource';
 import * as ServicesAPI from './services';
 import * as Shared from '../../shared';
-import { APIPromise } from '../../../api-promise';
-import { PagePromise, ServicesPage, type ServicesPageParams } from '../../../pagination';
+import { APIPromise } from '../../../core/api-promise';
+import { PagePromise, ServicesPage, type ServicesPageParams } from '../../../core/pagination';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class Services extends APIResource {
diff --git a/src/resources/environments/automations/tasks/executions.ts b/src/resources/environments/automations/tasks/executions.ts
index d8bc0cf..47410d8 100644
--- a/src/resources/environments/automations/tasks/executions.ts
+++ b/src/resources/environments/automations/tasks/executions.ts
@@ -1,10 +1,10 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../../resource';
+import { APIResource } from '../../../../core/resource';
 import * as Shared from '../../../shared';
 import { TaskExecutionsTaskExecutionsPage } from '../../../shared';
-import { APIPromise } from '../../../../api-promise';
-import { PagePromise, TaskExecutionsPage, type TaskExecutionsPageParams } from '../../../../pagination';
+import { APIPromise } from '../../../../core/api-promise';
+import { PagePromise, TaskExecutionsPage, type TaskExecutionsPageParams } from '../../../../core/pagination';
 import { RequestOptions } from '../../../../internal/request-options';
 
 export class Executions extends APIResource {
diff --git a/src/resources/environments/automations/tasks/tasks.ts b/src/resources/environments/automations/tasks/tasks.ts
index a1e1b97..6a85c1f 100644
--- a/src/resources/environments/automations/tasks/tasks.ts
+++ b/src/resources/environments/automations/tasks/tasks.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../../resource';
+import { APIResource } from '../../../../core/resource';
 import * as Shared from '../../../shared';
 import { TasksTasksPage } from '../../../shared';
 import * as ExecutionsAPI from './executions';
@@ -12,8 +12,8 @@ import {
   ExecutionStopResponse,
   Executions,
 } from './executions';
-import { APIPromise } from '../../../../api-promise';
-import { PagePromise, TasksPage, type TasksPageParams } from '../../../../pagination';
+import { APIPromise } from '../../../../core/api-promise';
+import { PagePromise, TasksPage, type TasksPageParams } from '../../../../core/pagination';
 import { RequestOptions } from '../../../../internal/request-options';
 
 export class Tasks extends APIResource {
diff --git a/src/resources/environments/classes.ts b/src/resources/environments/classes.ts
index d1a03ee..709e8bc 100644
--- a/src/resources/environments/classes.ts
+++ b/src/resources/environments/classes.ts
@@ -1,10 +1,14 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
 import { EnvironmentClassesEnvironmentClassesPage } from '../shared';
 import * as RunnersAPI from '../runners/runners';
-import { EnvironmentClassesPage, type EnvironmentClassesPageParams, PagePromise } from '../../pagination';
+import {
+  EnvironmentClassesPage,
+  type EnvironmentClassesPageParams,
+  PagePromise,
+} from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Classes extends APIResource {
diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts
index ee1390b..2534b7f 100644
--- a/src/resources/environments/environments.ts
+++ b/src/resources/environments/environments.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as EnvironmentsAPI from './environments';
 import * as Shared from '../shared';
 import * as ClassesAPI from './classes';
@@ -14,8 +14,8 @@ import {
   Automations,
   AutomationsFile as AutomationsAPIAutomationsFile,
 } from './automations/automations';
-import { APIPromise } from '../../api-promise';
-import { EnvironmentsPage, type EnvironmentsPageParams, PagePromise } from '../../pagination';
+import { APIPromise } from '../../core/api-promise';
+import { EnvironmentsPage, type EnvironmentsPageParams, PagePromise } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Environments extends APIResource {
diff --git a/src/resources/events.ts b/src/resources/events.ts
index 927e568..68a011a 100644
--- a/src/resources/events.ts
+++ b/src/resources/events.ts
@@ -1,10 +1,10 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
+import { APIResource } from '../core/resource';
 import * as EventsAPI from './events';
 import * as Shared from './shared';
-import { APIPromise } from '../api-promise';
-import { EntriesPage, type EntriesPageParams, PagePromise } from '../pagination';
+import { APIPromise } from '../core/api-promise';
+import { EntriesPage, type EntriesPageParams, PagePromise } from '../core/pagination';
 import { buildHeaders } from '../internal/headers';
 import { RequestOptions } from '../internal/request-options';
 import { JSONLDecoder } from '../internal/decoders/jsonl';
diff --git a/src/resources/groups.ts b/src/resources/groups.ts
index b67b15c..56384a4 100644
--- a/src/resources/groups.ts
+++ b/src/resources/groups.ts
@@ -1,7 +1,7 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
-import { GroupsPage, type GroupsPageParams, PagePromise } from '../pagination';
+import { APIResource } from '../core/resource';
+import { GroupsPage, type GroupsPageParams, PagePromise } from '../core/pagination';
 import { RequestOptions } from '../internal/request-options';
 
 export class Groups extends APIResource {
diff --git a/src/resources/identity.ts b/src/resources/identity.ts
index 9bfb3fd..e351965 100644
--- a/src/resources/identity.ts
+++ b/src/resources/identity.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
+import { APIResource } from '../core/resource';
 import * as Shared from './shared';
-import { APIPromise } from '../api-promise';
+import { APIPromise } from '../core/api-promise';
 import { RequestOptions } from '../internal/request-options';
 
 export class Identity extends APIResource {
diff --git a/src/resources/organizations/domain-verifications.ts b/src/resources/organizations/domain-verifications.ts
index 8fcb6a9..51e3a9e 100644
--- a/src/resources/organizations/domain-verifications.ts
+++ b/src/resources/organizations/domain-verifications.ts
@@ -1,8 +1,12 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
-import { APIPromise } from '../../api-promise';
-import { DomainVerificationsPage, type DomainVerificationsPageParams, PagePromise } from '../../pagination';
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import {
+  DomainVerificationsPage,
+  type DomainVerificationsPageParams,
+  PagePromise,
+} from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class DomainVerifications extends APIResource {
diff --git a/src/resources/organizations/invites.ts b/src/resources/organizations/invites.ts
index b8f3540..5dded81 100644
--- a/src/resources/organizations/invites.ts
+++ b/src/resources/organizations/invites.ts
@@ -1,7 +1,7 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
-import { APIPromise } from '../../api-promise';
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Invites extends APIResource {
diff --git a/src/resources/organizations/organizations.ts b/src/resources/organizations/organizations.ts
index bdba148..b0b452d 100644
--- a/src/resources/organizations/organizations.ts
+++ b/src/resources/organizations/organizations.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
 import * as DomainVerificationsAPI from './domain-verifications';
 import {
@@ -46,14 +46,14 @@ import {
   SSOConfigurations,
   SSOConfigurationsSSOConfigurationsPage,
 } from './sso-configurations';
-import { APIPromise } from '../../api-promise';
+import { APIPromise } from '../../core/api-promise';
 import {
   MembersPage,
   type MembersPageParams,
   OrganizationsPage,
   type OrganizationsPageParams,
   PagePromise,
-} from '../../pagination';
+} from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Organizations extends APIResource {
diff --git a/src/resources/organizations/sso-configurations.ts b/src/resources/organizations/sso-configurations.ts
index 83e5205..a447375 100644
--- a/src/resources/organizations/sso-configurations.ts
+++ b/src/resources/organizations/sso-configurations.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, SSOConfigurationsPage, type SSOConfigurationsPageParams } from '../../pagination';
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import { PagePromise, SSOConfigurationsPage, type SSOConfigurationsPageParams } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class SSOConfigurations extends APIResource {
diff --git a/src/resources/projects/policies.ts b/src/resources/projects/policies.ts
index 07d3d09..ea39ec5 100644
--- a/src/resources/projects/policies.ts
+++ b/src/resources/projects/policies.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../pagination';
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Policies extends APIResource {
diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts
index 7ca91c8..3f3967a 100644
--- a/src/resources/projects/projects.ts
+++ b/src/resources/projects/projects.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
 import * as PoliciesAPI from './policies';
 import {
@@ -16,8 +16,8 @@ import {
   ProjectPolicy,
   ProjectRole,
 } from './policies';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, ProjectsPage, type ProjectsPageParams } from '../../pagination';
+import { APIPromise } from '../../core/api-promise';
+import { PagePromise, ProjectsPage, type ProjectsPageParams } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Projects extends APIResource {
diff --git a/src/resources/runners/configurations/configurations.ts b/src/resources/runners/configurations/configurations.ts
index 0213678..db30ece 100644
--- a/src/resources/runners/configurations/configurations.ts
+++ b/src/resources/runners/configurations/configurations.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
+import { APIResource } from '../../../core/resource';
 import * as Shared from '../../shared';
 import * as EnvironmentClassesAPI from './environment-classes';
 import {
@@ -47,7 +47,7 @@ import {
   ScmIntegrations,
   ScmIntegrationsIntegrationsPage,
 } from './scm-integrations';
-import { APIPromise } from '../../../api-promise';
+import { APIPromise } from '../../../core/api-promise';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class Configurations extends APIResource {
diff --git a/src/resources/runners/configurations/environment-classes.ts b/src/resources/runners/configurations/environment-classes.ts
index 9e70d73..1db7137 100644
--- a/src/resources/runners/configurations/environment-classes.ts
+++ b/src/resources/runners/configurations/environment-classes.ts
@@ -1,11 +1,15 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
+import { APIResource } from '../../../core/resource';
 import * as Shared from '../../shared';
 import { EnvironmentClassesEnvironmentClassesPage } from '../../shared';
 import * as RunnersAPI from '../runners';
-import { APIPromise } from '../../../api-promise';
-import { EnvironmentClassesPage, type EnvironmentClassesPageParams, PagePromise } from '../../../pagination';
+import { APIPromise } from '../../../core/api-promise';
+import {
+  EnvironmentClassesPage,
+  type EnvironmentClassesPageParams,
+  PagePromise,
+} from '../../../core/pagination';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class EnvironmentClasses extends APIResource {
diff --git a/src/resources/runners/configurations/host-authentication-tokens.ts b/src/resources/runners/configurations/host-authentication-tokens.ts
index 0b7240e..8196628 100644
--- a/src/resources/runners/configurations/host-authentication-tokens.ts
+++ b/src/resources/runners/configurations/host-authentication-tokens.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
-import { APIPromise } from '../../../api-promise';
-import { PagePromise, TokensPage, type TokensPageParams } from '../../../pagination';
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
+import { PagePromise, TokensPage, type TokensPageParams } from '../../../core/pagination';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class HostAuthenticationTokens extends APIResource {
diff --git a/src/resources/runners/configurations/schema.ts b/src/resources/runners/configurations/schema.ts
index 137908c..a7885dd 100644
--- a/src/resources/runners/configurations/schema.ts
+++ b/src/resources/runners/configurations/schema.ts
@@ -1,7 +1,7 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
-import { APIPromise } from '../../../api-promise';
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class Schema extends APIResource {
diff --git a/src/resources/runners/configurations/scm-integrations.ts b/src/resources/runners/configurations/scm-integrations.ts
index d6dcc3f..ebdc52b 100644
--- a/src/resources/runners/configurations/scm-integrations.ts
+++ b/src/resources/runners/configurations/scm-integrations.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../../resource';
-import { APIPromise } from '../../../api-promise';
-import { IntegrationsPage, type IntegrationsPageParams, PagePromise } from '../../../pagination';
+import { APIResource } from '../../../core/resource';
+import { APIPromise } from '../../../core/api-promise';
+import { IntegrationsPage, type IntegrationsPageParams, PagePromise } from '../../../core/pagination';
 import { RequestOptions } from '../../../internal/request-options';
 
 export class ScmIntegrations extends APIResource {
diff --git a/src/resources/runners/policies.ts b/src/resources/runners/policies.ts
index 4b71a77..0cdd4c1 100644
--- a/src/resources/runners/policies.ts
+++ b/src/resources/runners/policies.ts
@@ -1,8 +1,8 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../pagination';
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import { PagePromise, PoliciesPage, type PoliciesPageParams } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Policies extends APIResource {
diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts
index 4efa8a4..0925d50 100644
--- a/src/resources/runners/runners.ts
+++ b/src/resources/runners/runners.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as RunnersAPI from './runners';
 import * as Shared from '../shared';
 import * as PoliciesAPI from './policies';
@@ -26,8 +26,8 @@ import {
   FieldValidationError,
   ScmIntegrationValidationResult,
 } from './configurations/configurations';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, RunnersPage, type RunnersPageParams } from '../../pagination';
+import { APIPromise } from '../../core/api-promise';
+import { PagePromise, RunnersPage, type RunnersPageParams } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Runners extends APIResource {
diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts
index 845d02e..62ceb78 100644
--- a/src/resources/secrets.ts
+++ b/src/resources/secrets.ts
@@ -1,9 +1,9 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../resource';
+import { APIResource } from '../core/resource';
 import * as Shared from './shared';
-import { APIPromise } from '../api-promise';
-import { PagePromise, SecretsPage, type SecretsPageParams } from '../pagination';
+import { APIPromise } from '../core/api-promise';
+import { PagePromise, SecretsPage, type SecretsPageParams } from '../core/pagination';
 import { RequestOptions } from '../internal/request-options';
 
 export class Secrets extends APIResource {
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index e6c63f1..b771f1d 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -1,7 +1,7 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
 import * as Shared from './shared';
-import { EnvironmentClassesPage, TaskExecutionsPage, TasksPage } from '../pagination';
+import { EnvironmentClassesPage, TaskExecutionsPage, TasksPage } from '../core/pagination';
 
 /**
  * An AutomationTrigger represents a trigger for an automation action. The
diff --git a/src/resources/users/pats.ts b/src/resources/users/pats.ts
index d8037ac..6827d68 100644
--- a/src/resources/users/pats.ts
+++ b/src/resources/users/pats.ts
@@ -1,9 +1,13 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
-import { APIPromise } from '../../api-promise';
-import { PagePromise, PersonalAccessTokensPage, type PersonalAccessTokensPageParams } from '../../pagination';
+import { APIPromise } from '../../core/api-promise';
+import {
+  PagePromise,
+  PersonalAccessTokensPage,
+  type PersonalAccessTokensPageParams,
+} from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Pats extends APIResource {
diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts
index 63c3f75..4fb4bad 100644
--- a/src/resources/users/users.ts
+++ b/src/resources/users/users.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIResource } from '../../resource';
+import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
 import * as PatsAPI from './pats';
 import {
@@ -13,7 +13,7 @@ import {
   PersonalAccessToken,
   PersonalAccessTokensPersonalAccessTokensPage,
 } from './pats';
-import { APIPromise } from '../../api-promise';
+import { APIPromise } from '../../core/api-promise';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Users extends APIResource {
diff --git a/src/uploads.ts b/src/uploads.ts
index 79d3073..b2ef647 100644
--- a/src/uploads.ts
+++ b/src/uploads.ts
@@ -1,2 +1,2 @@
-export { type Uploadable } from './internal/uploads';
-export { toFile, type ToFileInput } from './internal/to-file';
+/** @deprecated Import from ./core/uploads instead */
+export * from './core/uploads';
diff --git a/tests/form.test.ts b/tests/form.test.ts
index 1dd9656..cb575ba 100644
--- a/tests/form.test.ts
+++ b/tests/form.test.ts
@@ -1,5 +1,5 @@
 import { multipartFormRequestOptions, createForm } from '@gitpod/sdk/internal/uploads';
-import { toFile } from '@gitpod/sdk/uploads';
+import { toFile } from '@gitpod/sdk/core/uploads';
 
 describe('form data validation', () => {
   test('valid values do not error', async () => {
diff --git a/tests/index.test.ts b/tests/index.test.ts
index 24fd099..afe3fed 100644
--- a/tests/index.test.ts
+++ b/tests/index.test.ts
@@ -1,6 +1,6 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { APIPromise } from '@gitpod/sdk/api-promise';
+import { APIPromise } from '@gitpod/sdk/core/api-promise';
 
 import util from 'node:util';
 import Gitpod from '@gitpod/sdk';
diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index 7b28bb5..d18eb6c 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -1,6 +1,6 @@
 import fs from 'fs';
 import type { ResponseLike } from '@gitpod/sdk/internal/to-file';
-import { toFile } from '@gitpod/sdk/uploads';
+import { toFile } from '@gitpod/sdk/core/uploads';
 import { File } from 'node:buffer';
 
 class MyClass {
@@ -97,7 +97,7 @@ describe('missing File error message', () => {
   });
 
   test('is thrown', async () => {
-    const uploads = await import('@gitpod/sdk/uploads');
+    const uploads = await import('@gitpod/sdk/core/uploads');
     await expect(
       uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })),
     ).rejects.toMatchInlineSnapshot(

From dab243394f6b0f60cedc65f3eabcf1bfe64ed640 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 3 Apr 2025 06:54:56 +0000
Subject: [PATCH 21/44] fix(client): send `X-Stainless-Timeout` in seconds
 (#63)

---
 src/client.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/client.ts b/src/client.ts
index ef0b007..8f973c0 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -835,7 +835,7 @@ export class Gitpod {
         Accept: 'application/json',
         'User-Agent': this.getUserAgent(),
         'X-Stainless-Retry-Count': String(retryCount),
-        ...(options.timeout ? { 'X-Stainless-Timeout': String(options.timeout) } : {}),
+        ...(options.timeout ? { 'X-Stainless-Timeout': String(Math.trunc(options.timeout / 1000)) } : {}),
         ...getPlatformHeaders(),
       },
       this.authHeaders(options),

From 38e00c9995d8528c361bf709d3951a0f00238ada Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 3 Apr 2025 07:20:40 +0000
Subject: [PATCH 22/44] chore(internal): add aliases for Record and Array (#64)

---
 src/internal/builtin-types.ts | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/src/internal/builtin-types.ts b/src/internal/builtin-types.ts
index b2e598a..c23d3bd 100644
--- a/src/internal/builtin-types.ts
+++ b/src/internal/builtin-types.ts
@@ -39,9 +39,23 @@ type _HeadersInit = RequestInit['headers'];
  */
 type _BodyInit = RequestInit['body'];
 
+/**
+ * An alias to the builtin `Array<T>` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Array<T> = Array<T>;
+
+/**
+ * An alias to the builtin `Record<K, T>` type so we can
+ * easily alias it in import statements if there are name clashes.
+ */
+type _Record<K extends keyof any, T> = Record<K, T>;
+
 export type {
+  _Array as Array,
   _BodyInit as BodyInit,
   _HeadersInit as HeadersInit,
+  _Record as Record,
   _RequestInfo as RequestInfo,
   _RequestInit as RequestInit,
   _Response as Response,

From 62c4790ed0515d7644fca6075b5d9304bd4b1642 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 4 Apr 2025 08:18:11 +0000
Subject: [PATCH 23/44] chore(client): make jsonl methods consistent with other
 streaming methods (#65)

---
 api.md                               |   2 +-
 src/resources/events.ts              |   5 +-
 tests/internal/decoders/line.test.ts | 128 +++++++++++++++++++++++++++
 3 files changed, 133 insertions(+), 2 deletions(-)
 create mode 100644 tests/internal/decoders/line.test.ts

diff --git a/api.md b/api.md
index 8e80f38..4a2d257 100644
--- a/api.md
+++ b/api.md
@@ -174,7 +174,7 @@ Types:
 Methods:
 
 - <code title="post /gitpod.v1.EventService/ListAuditLogs">client.events.<a href="./src/resources/events.ts">list</a>({ ...params }) -> EventListResponsesEntriesPage</code>
-- <code title="post /gitpod.v1.EventService/WatchEvents">client.events.<a href="./src/resources/events.ts">watch</a>({ ...params }) -> JSONLDecoder&lt;EventWatchResponse&gt;</code>
+- <code title="post /gitpod.v1.EventService/WatchEvents">client.events.<a href="./src/resources/events.ts">watch</a>({ ...params }) -> EventWatchResponse</code>
 
 # Groups
 
diff --git a/src/resources/events.ts b/src/resources/events.ts
index 68a011a..bc5d412 100644
--- a/src/resources/events.ts
+++ b/src/resources/events.ts
@@ -79,9 +79,12 @@ export class Events extends APIResource {
           { 'Content-Type': 'application/jsonl', Accept: 'application/jsonl' },
           options?.headers,
         ]),
+        stream: true,
         __binaryResponse: true,
       })
-      ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller));
+      ._thenUnwrap((_, props) => JSONLDecoder.fromResponse(props.response, props.controller)) as APIPromise<
+      JSONLDecoder<EventWatchResponse>
+    >;
   }
 }
 
diff --git a/tests/internal/decoders/line.test.ts b/tests/internal/decoders/line.test.ts
new file mode 100644
index 0000000..9f45693
--- /dev/null
+++ b/tests/internal/decoders/line.test.ts
@@ -0,0 +1,128 @@
+import { findDoubleNewlineIndex, LineDecoder } from '@gitpod/sdk/internal/decoders/line';
+
+function decodeChunks(chunks: string[], { flush }: { flush: boolean } = { flush: false }): string[] {
+  const decoder = new LineDecoder();
+  const lines: string[] = [];
+  for (const chunk of chunks) {
+    lines.push(...decoder.decode(chunk));
+  }
+
+  if (flush) {
+    lines.push(...decoder.flush());
+  }
+
+  return lines;
+}
+
+describe('line decoder', () => {
+  test('basic', () => {
+    // baz is not included because the line hasn't ended yet
+    expect(decodeChunks(['foo', ' bar\nbaz'])).toEqual(['foo bar']);
+  });
+
+  test('basic with \\r', () => {
+    expect(decodeChunks(['foo', ' bar\r\nbaz'])).toEqual(['foo bar']);
+    expect(decodeChunks(['foo', ' bar\r\nbaz'], { flush: true })).toEqual(['foo bar', 'baz']);
+  });
+
+  test('trailing new lines', () => {
+    expect(decodeChunks(['foo', ' bar', 'baz\n', 'thing\n'])).toEqual(['foo barbaz', 'thing']);
+  });
+
+  test('trailing new lines with \\r', () => {
+    expect(decodeChunks(['foo', ' bar', 'baz\r\n', 'thing\r\n'])).toEqual(['foo barbaz', 'thing']);
+  });
+
+  test('escaped new lines', () => {
+    expect(decodeChunks(['foo', ' bar\\nbaz\n'])).toEqual(['foo bar\\nbaz']);
+  });
+
+  test('escaped new lines with \\r', () => {
+    expect(decodeChunks(['foo', ' bar\\r\\nbaz\n'])).toEqual(['foo bar\\r\\nbaz']);
+  });
+
+  test('\\r & \\n split across multiple chunks', () => {
+    expect(decodeChunks(['foo\r', '\n', 'bar'], { flush: true })).toEqual(['foo', 'bar']);
+  });
+
+  test('single \\r', () => {
+    expect(decodeChunks(['foo\r', 'bar'], { flush: true })).toEqual(['foo', 'bar']);
+  });
+
+  test('double \\r', () => {
+    expect(decodeChunks(['foo\r', 'bar\r'], { flush: true })).toEqual(['foo', 'bar']);
+    expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']);
+    // implementation detail that we don't yield the single \r line until a new \r or \n is encountered
+    expect(decodeChunks(['foo\r', '\r', 'bar'], { flush: false })).toEqual(['foo']);
+  });
+
+  test('double \\r then \\r\\n', () => {
+    expect(decodeChunks(['foo\r', '\r', '\r', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']);
+    expect(decodeChunks(['foo\n', '\n', '\n', 'bar', '\n'])).toEqual(['foo', '', '', 'bar']);
+  });
+
+  test('double newline', () => {
+    expect(decodeChunks(['foo\n\nbar'], { flush: true })).toEqual(['foo', '', 'bar']);
+    expect(decodeChunks(['foo', '\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']);
+    expect(decodeChunks(['foo\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']);
+    expect(decodeChunks(['foo', '\n', '\n', 'bar'], { flush: true })).toEqual(['foo', '', 'bar']);
+  });
+
+  test('multi-byte characters across chunks', () => {
+    const decoder = new LineDecoder();
+
+    // bytes taken from the string 'известни' and arbitrarily split
+    // so that some multi-byte characters span multiple chunks
+    expect(decoder.decode(new Uint8Array([0xd0]))).toHaveLength(0);
+    expect(decoder.decode(new Uint8Array([0xb8, 0xd0, 0xb7, 0xd0]))).toHaveLength(0);
+    expect(
+      decoder.decode(new Uint8Array([0xb2, 0xd0, 0xb5, 0xd1, 0x81, 0xd1, 0x82, 0xd0, 0xbd, 0xd0, 0xb8])),
+    ).toHaveLength(0);
+
+    const decoded = decoder.decode(new Uint8Array([0xa]));
+    expect(decoded).toEqual(['известни']);
+  });
+
+  test('flushing trailing newlines', () => {
+    expect(decodeChunks(['foo\n', '\nbar'], { flush: true })).toEqual(['foo', '', 'bar']);
+  });
+
+  test('flushing empty buffer', () => {
+    expect(decodeChunks([], { flush: true })).toEqual([]);
+  });
+});
+
+describe('findDoubleNewlineIndex', () => {
+  test('finds \\n\\n', () => {
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\nbar'))).toBe(5);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\nbar'))).toBe(2);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\n\n'))).toBe(5);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\n\n'))).toBe(2);
+  });
+
+  test('finds \\r\\r', () => {
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\rbar'))).toBe(5);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\rbar'))).toBe(2);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\r'))).toBe(5);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\r'))).toBe(2);
+  });
+
+  test('finds \\r\\n\\r\\n', () => {
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\nbar'))).toBe(7);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\nbar'))).toBe(4);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r\n'))).toBe(7);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('\r\n\r\n'))).toBe(4);
+  });
+
+  test('returns -1 when no double newline found', () => {
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\nbar'))).toBe(-1);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\rbar'))).toBe(-1);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\nbar'))).toBe(-1);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode(''))).toBe(-1);
+  });
+
+  test('handles incomplete patterns', () => {
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n\r'))).toBe(-1);
+    expect(findDoubleNewlineIndex(new TextEncoder().encode('foo\r\n'))).toBe(-1);
+  });
+});

From 8aa007bc39d87e8b96861748a23d4faa5d084c8a Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 4 Apr 2025 08:28:47 +0000
Subject: [PATCH 24/44] fix(api): improve type resolution when importing as a
 package (#66)

---
 packages/mcp-server/src/tools.ts | 1 +
 1 file changed, 1 insertion(+)
 create mode 100644 packages/mcp-server/src/tools.ts

diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts
new file mode 100644
index 0000000..7e516de
--- /dev/null
+++ b/packages/mcp-server/src/tools.ts
@@ -0,0 +1 @@
+export * from './tools/index';

From 65686bf96f2a2147c620810605bc66876ec0c13e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 5 Apr 2025 02:20:11 +0000
Subject: [PATCH 25/44] fix(mcp): remove unused tools.ts (#67)

---
 packages/mcp-server/src/tools.ts | 1 -
 1 file changed, 1 deletion(-)
 delete mode 100644 packages/mcp-server/src/tools.ts

diff --git a/packages/mcp-server/src/tools.ts b/packages/mcp-server/src/tools.ts
deleted file mode 100644
index 7e516de..0000000
--- a/packages/mcp-server/src/tools.ts
+++ /dev/null
@@ -1 +0,0 @@
-export * from './tools/index';

From 3ced7939c98da7bc8c42a457da3aee4510a778a7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 8 Apr 2025 02:49:49 +0000
Subject: [PATCH 26/44] fix(client): send all configured auth headers (#68)

---
 src/client.ts | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/src/client.ts b/src/client.ts
index 8f973c0..08e24e7 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -385,8 +385,8 @@ export class Gitpod {
     return;
   }
 
-  protected authHeaders(opts: FinalRequestOptions): Headers | undefined {
-    return new Headers({ Authorization: `Bearer ${this.bearerToken}` });
+  protected authHeaders(opts: FinalRequestOptions): NullableHeaders | undefined {
+    return buildHeaders([{ Authorization: `Bearer ${this.bearerToken}` }]);
   }
 
   /**

From af4a60aa5f1bc957cdb96b0996f4ee02c0d7d469 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 9 Apr 2025 02:30:31 +0000
Subject: [PATCH 27/44] chore(tests): improve enum examples (#69)

---
 tests/api-resources/organizations/organizations.test.ts | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tests/api-resources/organizations/organizations.test.ts b/tests/api-resources/organizations/organizations.test.ts
index f88e6bd..16be6a5 100644
--- a/tests/api-resources/organizations/organizations.test.ts
+++ b/tests/api-resources/organizations/organizations.test.ts
@@ -179,7 +179,7 @@ describe('resource organizations', () => {
     const response = await client.organizations.setRole({
       organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
       userId: 'f53d2330-3795-4c5d-a1f3-453121af9c60',
-      role: 'ORGANIZATION_ROLE_UNSPECIFIED',
+      role: 'ORGANIZATION_ROLE_MEMBER',
     });
   });
 });

From dbd4446148041e01ec058c0a19568a17ad7384f7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 10 Apr 2025 02:36:11 +0000
Subject: [PATCH 28/44] chore(internal): upload builds and expand CI branch
 coverage

---
 .github/workflows/ci.yml         | 36 ++++++++++++++++++++++----------
 scripts/utils/upload-artifact.sh | 25 ++++++++++++++++++++++
 2 files changed, 50 insertions(+), 11 deletions(-)
 create mode 100755 scripts/utils/upload-artifact.sh

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 0312165..5e6495e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,19 +1,18 @@
 name: CI
 on:
   push:
-    branches:
-      - main
-  pull_request:
-    branches:
-      - main
-      - next
+    branches-ignore:
+      - 'generated'
+      - 'codegen/**'
+      - 'integrated/**'
+      - 'preview-head/**'
+      - 'preview-base/**'
+      - 'preview/**'
 
 jobs:
   lint:
     name: lint
     runs-on: ubuntu-latest
-    
-
     steps:
       - uses: actions/checkout@v4
 
@@ -31,8 +30,9 @@ jobs:
   build:
     name: build
     runs-on: ubuntu-latest
-    
-
+    permissions:
+      contents: read
+      id-token: write
     steps:
       - uses: actions/checkout@v4
 
@@ -46,10 +46,24 @@ jobs:
 
       - name: Check build
         run: ./scripts/build
+
+      - name: Get GitHub OIDC Token
+        if: github.repository == 'stainless-sdks/gitpod-typescript'
+        id: github-oidc
+        uses: actions/github-script@v6
+        with:
+          script: core.setOutput('github_token', await core.getIDToken());
+
+      - name: Upload tarball
+        if: github.repository == 'stainless-sdks/gitpod-typescript'
+        env:
+          URL: https://pkg.stainless.com/s
+          AUTH: ${{ steps.github-oidc.outputs.github_token }}
+          SHA: ${{ github.sha }}
+        run: ./scripts/utils/upload-artifact.sh
   test:
     name: test
     runs-on: ubuntu-latest
-
     steps:
       - uses: actions/checkout@v4
 
diff --git a/scripts/utils/upload-artifact.sh b/scripts/utils/upload-artifact.sh
new file mode 100755
index 0000000..864a4c8
--- /dev/null
+++ b/scripts/utils/upload-artifact.sh
@@ -0,0 +1,25 @@
+#!/usr/bin/env bash
+set -exuo pipefail
+
+RESPONSE=$(curl -X POST "$URL" \
+  -H "Authorization: Bearer $AUTH" \
+  -H "Content-Type: application/json")
+
+SIGNED_URL=$(echo "$RESPONSE" | jq -r '.url')
+
+if [[ "$SIGNED_URL" == "null" ]]; then
+  echo -e "\033[31mFailed to get signed URL.\033[0m"
+  exit 1
+fi
+
+UPLOAD_RESPONSE=$(tar -cz dist | curl -v -X PUT \
+  -H "Content-Type: application/gzip" \
+  --data-binary @- "$SIGNED_URL" 2>&1)
+
+if echo "$UPLOAD_RESPONSE" | grep -q "HTTP/[0-9.]* 200"; then
+  echo -e "\033[32mUploaded build to Stainless storage.\033[0m"
+  echo -e "\033[32mInstallation: npm install 'https://pkg.stainless.com/s/gitpod-typescript/$SHA'\033[0m"
+else
+  echo -e "\033[31mFailed to upload artifact.\033[0m"
+  exit 1
+fi

From 726127ae7ad639fc5587724e20559893ea3c67eb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 10 Apr 2025 02:38:28 +0000
Subject: [PATCH 29/44] chore(internal): improve node 18 shims

---
 package.json                               |  4 ++
 scripts/build                              |  2 -
 src/internal/shims/crypto.node.d.mts       |  1 -
 src/internal/shims/crypto.node.d.ts        | 10 ----
 src/internal/shims/crypto.node.js          | 11 ----
 src/internal/shims/crypto.node.mjs         |  2 -
 src/internal/shims/crypto.ts               | 18 ++++++
 src/internal/shims/file.node.d.mts         |  1 -
 src/internal/shims/file.node.d.ts          | 20 -------
 src/internal/shims/file.node.js            | 11 ----
 src/internal/shims/file.node.mjs           |  2 -
 src/internal/shims/file.ts                 | 32 +++++++++++
 src/internal/shims/getBuiltinModule.ts     | 64 ++++++++++++++++++++++
 src/internal/shims/nullGetBuiltinModule.ts |  1 +
 src/internal/to-file.ts                    |  4 +-
 src/internal/uploads.ts                    |  9 +--
 src/internal/utils/uuid.ts                 | 16 ++++--
 tests/uploads.test.ts                      |  2 +-
 18 files changed, 136 insertions(+), 74 deletions(-)
 delete mode 100644 src/internal/shims/crypto.node.d.mts
 delete mode 100644 src/internal/shims/crypto.node.d.ts
 delete mode 100644 src/internal/shims/crypto.node.js
 delete mode 100644 src/internal/shims/crypto.node.mjs
 create mode 100644 src/internal/shims/crypto.ts
 delete mode 100644 src/internal/shims/file.node.d.mts
 delete mode 100644 src/internal/shims/file.node.d.ts
 delete mode 100644 src/internal/shims/file.node.js
 delete mode 100644 src/internal/shims/file.node.mjs
 create mode 100644 src/internal/shims/file.ts
 create mode 100644 src/internal/shims/getBuiltinModule.ts
 create mode 100644 src/internal/shims/nullGetBuiltinModule.ts

diff --git a/package.json b/package.json
index dae603a..e99d450 100644
--- a/package.json
+++ b/package.json
@@ -53,6 +53,10 @@
   "resolutions": {
     "synckit": "0.8.8"
   },
+  "browser": {
+    "./internal/shims/getBuiltinModule.mjs": "./internal/shims/nullGetBuiltinModule.mjs",
+    "./internal/shims/getBuiltinModule.js": "./internal/shims/nullGetBuiltinModule.js"
+  },
   "imports": {
     "@gitpod/sdk": ".",
     "@gitpod/sdk/*": "./src/*"
diff --git a/scripts/build b/scripts/build
index 047fe3d..afc1898 100755
--- a/scripts/build
+++ b/scripts/build
@@ -35,8 +35,6 @@ node scripts/utils/fix-index-exports.cjs
 cp tsconfig.dist-src.json dist/src/tsconfig.json
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.ts
 cp src/internal/shim-types.d.ts dist/internal/shim-types.d.mts
-mkdir -p dist/internal/shims
-cp src/internal/shims/*.{mjs,js,d.ts,d.mts} dist/internal/shims
 
 node scripts/utils/postprocess-files.cjs
 
diff --git a/src/internal/shims/crypto.node.d.mts b/src/internal/shims/crypto.node.d.mts
deleted file mode 100644
index 5cc1963..0000000
--- a/src/internal/shims/crypto.node.d.mts
+++ /dev/null
@@ -1 +0,0 @@
-export { crypto } from './crypto.node.js';
diff --git a/src/internal/shims/crypto.node.d.ts b/src/internal/shims/crypto.node.d.ts
deleted file mode 100644
index dc7caac..0000000
--- a/src/internal/shims/crypto.node.d.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export declare const crypto: {
-  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */
-  getRandomValues<T extends ArrayBufferView | null>(array: T): T;
-  /**
-   * Available only in secure contexts.
-   *
-   * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
-   */
-  randomUUID?: () => string;
-};
diff --git a/src/internal/shims/crypto.node.js b/src/internal/shims/crypto.node.js
deleted file mode 100644
index 83062a3..0000000
--- a/src/internal/shims/crypto.node.js
+++ /dev/null
@@ -1,11 +0,0 @@
-if (typeof require !== 'undefined') {
-  if (globalThis.crypto) {
-    exports.crypto = globalThis.crypto;
-  } else {
-    try {
-      // Use [require][0](...) and not require(...) so bundlers don't try to bundle the
-      // crypto module.
-      exports.crypto = [require][0]('node:crypto').webcrypto;
-    } catch (e) {}
-  }
-}
diff --git a/src/internal/shims/crypto.node.mjs b/src/internal/shims/crypto.node.mjs
deleted file mode 100644
index 24c6f3b..0000000
--- a/src/internal/shims/crypto.node.mjs
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as mod from './crypto.node.js';
-export const crypto = globalThis.crypto || mod.crypto;
diff --git a/src/internal/shims/crypto.ts b/src/internal/shims/crypto.ts
new file mode 100644
index 0000000..905f81c
--- /dev/null
+++ b/src/internal/shims/crypto.ts
@@ -0,0 +1,18 @@
+import { getBuiltinModule } from './getBuiltinModule';
+
+type Crypto = {
+  /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/getRandomValues) */
+  getRandomValues<T extends ArrayBufferView | null>(array: T): T;
+  /**
+   * Available only in secure contexts.
+   *
+   * [MDN Reference](https://developer.mozilla.org/docs/Web/API/Crypto/randomUUID)
+   */
+  randomUUID?: () => string;
+};
+export let getCrypto: () => Crypto | undefined = function lazyGetCrypto() {
+  if (getCrypto !== lazyGetCrypto) return getCrypto();
+  const crypto: Crypto = (globalThis as any).crypto || (getBuiltinModule?.('node:crypto') as any)?.webcrypto;
+  getCrypto = () => crypto;
+  return crypto;
+};
diff --git a/src/internal/shims/file.node.d.mts b/src/internal/shims/file.node.d.mts
deleted file mode 100644
index 38cc9ff..0000000
--- a/src/internal/shims/file.node.d.mts
+++ /dev/null
@@ -1 +0,0 @@
-export { File } from './file.node.js';
diff --git a/src/internal/shims/file.node.d.ts b/src/internal/shims/file.node.d.ts
deleted file mode 100644
index 9dc6b2f..0000000
--- a/src/internal/shims/file.node.d.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// The infer is to make TS show it as a nice union type,
-// instead of literally `ConstructorParameters<typeof Blob>[0]`
-type FallbackBlobSource = ConstructorParameters<typeof Blob>[0] extends infer T ? T : never;
-/**
- * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files.
- */
-declare class FallbackFile extends Blob {
-  constructor(sources: FallbackBlobSource, fileName: string, options?: any);
-  /**
-   * The name of the `File`.
-   */
-  readonly name: string;
-  /**
-   * The last modified date of the `File`.
-   */
-  readonly lastModified: number;
-}
-export type File = InstanceType<typeof File>;
-export const File: typeof globalThis extends { File: infer fileConstructor } ? fileConstructor
-: typeof FallbackFile;
diff --git a/src/internal/shims/file.node.js b/src/internal/shims/file.node.js
deleted file mode 100644
index 3f8c2ed..0000000
--- a/src/internal/shims/file.node.js
+++ /dev/null
@@ -1,11 +0,0 @@
-if (typeof require !== 'undefined') {
-  if (globalThis.File) {
-    exports.File = globalThis.File;
-  } else {
-    try {
-      // Use [require][0](...) and not require(...) so bundlers don't try to bundle the
-      // buffer module.
-      exports.File = [require][0]('node:buffer').File;
-    } catch (e) {}
-  }
-}
diff --git a/src/internal/shims/file.node.mjs b/src/internal/shims/file.node.mjs
deleted file mode 100644
index 1f103f5..0000000
--- a/src/internal/shims/file.node.mjs
+++ /dev/null
@@ -1,2 +0,0 @@
-import * as mod from './file.node.js';
-export const File = globalThis.File || mod.File;
diff --git a/src/internal/shims/file.ts b/src/internal/shims/file.ts
new file mode 100644
index 0000000..d5dc820
--- /dev/null
+++ b/src/internal/shims/file.ts
@@ -0,0 +1,32 @@
+import { getBuiltinModule } from './getBuiltinModule';
+
+export let getFile = function lazyGetFile(): FileConstructor {
+  if (getFile !== lazyGetFile) return getFile();
+  // We can drop getBuiltinModule once we no longer support Node < 20.0.0
+  const File = (globalThis as any).File ?? (getBuiltinModule?.('node:buffer') as any)?.File;
+  if (!File) throw new Error('`File` is not defined as a global, which is required for file uploads.');
+  getFile = () => File;
+  return File;
+};
+
+type FileConstructor =
+  typeof globalThis extends { File: infer fileConstructor } ? fileConstructor : typeof FallbackFile;
+export type File = InstanceType<FileConstructor>;
+
+// The infer is to make TS show it as a nice union type,
+// instead of literally `ConstructorParameters<typeof Blob>[0]`
+type FallbackBlobSource = ConstructorParameters<typeof Blob>[0] extends infer T ? T : never;
+/**
+ * A [`File`](https://developer.mozilla.org/en-US/docs/Web/API/File) provides information about files.
+ */
+declare class FallbackFile extends Blob {
+  constructor(sources: FallbackBlobSource, fileName: string, options?: any);
+  /**
+   * The name of the `File`.
+   */
+  readonly name: string;
+  /**
+   * The last modified date of the `File`.
+   */
+  readonly lastModified: number;
+}
diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts
new file mode 100644
index 0000000..a202f20
--- /dev/null
+++ b/src/internal/shims/getBuiltinModule.ts
@@ -0,0 +1,64 @@
+/**
+ * Load a Node built-in module. ID may or may not be prefixed by `node:` and
+ * will be normalized. If we used static imports then our bundle size would be bloated by
+ * injected polyfills, and if we used dynamic require then in addition to bundlers logging warnings,
+ * our code would not work when bundled to ESM and run in Node 18.
+ * @param {string} id ID of the built-in to be loaded.
+ * @returns {object|undefined} exports of the built-in. Undefined if the built-in
+ * does not exist.
+ */
+export let getBuiltinModule: null | ((id: string) => object | undefined) = function getBuiltinModuleLazy(
+  id: string,
+): object | undefined {
+  try {
+    if (getBuiltinModule !== getBuiltinModuleLazy) return getBuiltinModule!(id);
+    if ((process as any).getBuiltinModule) {
+      getBuiltinModule = (process as any).getBuiltinModule;
+    } else {
+      /* Fallback implementation for Node 18 */
+      function createFallbackGetBuiltinModule(BuiltinModule: any) {
+        return function getBuiltinModule(id: string): object | undefined {
+          id = BuiltinModule.normalizeRequirableId(String(id));
+          if (!BuiltinModule.canBeRequiredByUsers(id)) {
+            return;
+          }
+          const mod = BuiltinModule.map.get(id);
+          mod.compileForPublicLoader();
+          return mod.exports;
+        };
+      }
+      const magicKey = Math.random() + '';
+      let module: { BuiltinModule: any } | undefined;
+      try {
+        const kClone = Object.getOwnPropertySymbols(Blob.prototype).find(
+          (e) => e.description?.includes('clone'),
+        )!;
+        Object.defineProperty(Object.prototype, magicKey, {
+          get() {
+            module = this;
+            throw null;
+          },
+          configurable: true,
+        });
+        structuredClone(
+          new (class extends Blob {
+            [kClone]() {
+              return {
+                deserializeInfo: 'internal/bootstrap/realm:' + magicKey,
+              };
+            }
+          })([]),
+        );
+      } catch {}
+      delete (Object.prototype as any)[magicKey];
+      if (module) {
+        getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule);
+      } else {
+        getBuiltinModule = () => undefined;
+      }
+    }
+    return getBuiltinModule!(id);
+  } catch {
+    return undefined;
+  }
+};
diff --git a/src/internal/shims/nullGetBuiltinModule.ts b/src/internal/shims/nullGetBuiltinModule.ts
new file mode 100644
index 0000000..8bd2280
--- /dev/null
+++ b/src/internal/shims/nullGetBuiltinModule.ts
@@ -0,0 +1 @@
+export const getBuiltinModule = null;
diff --git a/src/internal/to-file.ts b/src/internal/to-file.ts
index 69b76d3..e92ac69 100644
--- a/src/internal/to-file.ts
+++ b/src/internal/to-file.ts
@@ -1,4 +1,4 @@
-import { File } from './shims/file.node.js';
+import { type File, getFile } from './shims/file';
 import { BlobPart, getName, makeFile, isAsyncIterable } from './uploads';
 import type { FilePropertyBag } from './builtin-types';
 
@@ -90,7 +90,7 @@ export async function toFile(
 
   // If we've been given a `File` we don't need to do anything
   if (isFileLike(value)) {
-    if (File && value instanceof File) {
+    if (value instanceof getFile()) {
       return value;
     }
     return makeFile([await value.arrayBuffer()], value.name);
diff --git a/src/internal/uploads.ts b/src/internal/uploads.ts
index e09bcbb..fa0627a 100644
--- a/src/internal/uploads.ts
+++ b/src/internal/uploads.ts
@@ -1,7 +1,7 @@
 import { type RequestOptions } from './request-options';
 import type { FilePropertyBag, Fetch } from './builtin-types';
 import type { Gitpod } from '../client';
-import { File } from './shims/file.node.js';
+import { type File, getFile } from './shims/file';
 import { ReadableStreamFrom } from './shims';
 
 export type BlobPart = string | ArrayBuffer | ArrayBufferView | Blob | DataView;
@@ -32,10 +32,7 @@ export function makeFile(
   fileName: string | undefined,
   options?: FilePropertyBag,
 ): File {
-  if (typeof File === 'undefined') {
-    throw new Error('`File` is not defined as a global which is required for file uploads');
-  }
-
+  const File = getFile();
   return new File(fileBits as any, fileName ?? 'unknown_file', options);
 }
 
@@ -129,7 +126,7 @@ export const createForm = async <T = Record<string, unknown>>(
 // We check for Blob not File because Bun.File doesn't inherit from File,
 // but they both inherit from Blob and have a `name` property at runtime.
 const isNamedBlob = (value: object) =>
-  (File && value instanceof File) || (value instanceof Blob && 'name' in value);
+  value instanceof getFile() || (value instanceof Blob && 'name' in value);
 
 const isUploadable = (value: unknown) =>
   typeof value === 'object' &&
diff --git a/src/internal/utils/uuid.ts b/src/internal/utils/uuid.ts
index 1349c42..5a262c6 100644
--- a/src/internal/utils/uuid.ts
+++ b/src/internal/utils/uuid.ts
@@ -1,13 +1,19 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
-import { crypto } from '../shims/crypto.node.js';
+import { getCrypto } from '../shims/crypto';
 
 /**
  * https://stackoverflow.com/a/2117523
  */
-export function uuid4() {
-  if (crypto.randomUUID) return crypto.randomUUID();
+export let uuid4 = function () {
+  const crypto = getCrypto();
+  if (crypto?.randomUUID) {
+    uuid4 = crypto.randomUUID.bind(crypto);
+    return crypto.randomUUID();
+  }
+  const u8 = new Uint8Array(1);
+  const randomByte = crypto ? () => crypto.getRandomValues(u8)[0]! : () => (Math.random() * 0xff) & 0xff;
   return '10000000-1000-4000-8000-100000000000'.replace(/[018]/g, (c) =>
-    (+c ^ (crypto.getRandomValues(new Uint8Array(1))[0]! & (15 >> (+c / 4)))).toString(16),
+    (+c ^ (randomByte() & (15 >> (+c / 4)))).toString(16),
   );
-}
+};
diff --git a/tests/uploads.test.ts b/tests/uploads.test.ts
index d18eb6c..27bf8b3 100644
--- a/tests/uploads.test.ts
+++ b/tests/uploads.test.ts
@@ -101,7 +101,7 @@ describe('missing File error message', () => {
     await expect(
       uploads.toFile(mockResponse({ url: 'https://example.com/my/audio.mp3' })),
     ).rejects.toMatchInlineSnapshot(
-      `[Error: \`File\` is not defined as a global which is required for file uploads]`,
+      `[Error: \`File\` is not defined as a global, which is required for file uploads.]`,
     );
   });
 });

From e8cd029655896872fa1ccd8b71807f8c0ac565c9 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 10 Apr 2025 02:40:38 +0000
Subject: [PATCH 30/44] chore(internal): reduce CI branch coverage

---
 .github/workflows/ci.yml | 13 ++++++-------
 1 file changed, 6 insertions(+), 7 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 5e6495e..4864646 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,13 +1,12 @@
 name: CI
 on:
   push:
-    branches-ignore:
-      - 'generated'
-      - 'codegen/**'
-      - 'integrated/**'
-      - 'preview-head/**'
-      - 'preview-base/**'
-      - 'preview/**'
+    branches:
+      - main
+  pull_request:
+    branches:
+      - main
+      - next
 
 jobs:
   lint:

From 702757cc250c54fa31731233f3b88841b42baa32 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 11 Apr 2025 02:18:00 +0000
Subject: [PATCH 31/44] fix(internal): fix file uploads in node 18 jest

---
 src/internal/shims/getBuiltinModule.ts | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/internal/shims/getBuiltinModule.ts b/src/internal/shims/getBuiltinModule.ts
index a202f20..64daa2c 100644
--- a/src/internal/shims/getBuiltinModule.ts
+++ b/src/internal/shims/getBuiltinModule.ts
@@ -29,11 +29,13 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct
       }
       const magicKey = Math.random() + '';
       let module: { BuiltinModule: any } | undefined;
+      let ObjectPrototype: {} = Blob;
+      for (let next; (next = Reflect.getPrototypeOf(ObjectPrototype)); ObjectPrototype = next);
       try {
         const kClone = Object.getOwnPropertySymbols(Blob.prototype).find(
           (e) => e.description?.includes('clone'),
         )!;
-        Object.defineProperty(Object.prototype, magicKey, {
+        Object.defineProperty(ObjectPrototype, magicKey, {
           get() {
             module = this;
             throw null;
@@ -50,7 +52,7 @@ export let getBuiltinModule: null | ((id: string) => object | undefined) = funct
           })([]),
         );
       } catch {}
-      delete (Object.prototype as any)[magicKey];
+      delete (ObjectPrototype as any)[magicKey];
       if (module) {
         getBuiltinModule = createFallbackGetBuiltinModule(module.BuiltinModule);
       } else {

From e3c6fb879bc94b55e66f65a5238102ba390387a8 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 15 Apr 2025 02:50:59 +0000
Subject: [PATCH 32/44] chore(client): minor internal fixes

---
 src/client.ts | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/src/client.ts b/src/client.ts
index 08e24e7..8db32fe 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -786,17 +786,17 @@ export class Gitpod {
   }
 
   buildRequest(
-    options: FinalRequestOptions,
+    inputOptions: FinalRequestOptions,
     { retryCount = 0 }: { retryCount?: number } = {},
   ): { req: FinalizedRequestInit; url: string; timeout: number } {
-    options = { ...options };
+    const options = { ...inputOptions };
     const { method, path, query } = options;
 
     const url = this.buildURL(path!, query as Record<string, unknown>);
     if ('timeout' in options) validatePositiveInteger('timeout', options.timeout);
     options.timeout = options.timeout ?? this.timeout;
     const { bodyHeaders, body } = this.buildBody({ options });
-    const reqHeaders = this.buildHeaders({ options, method, bodyHeaders, retryCount });
+    const reqHeaders = this.buildHeaders({ options: inputOptions, method, bodyHeaders, retryCount });
 
     const req: FinalizedRequestInit = {
       method,

From b3a1e96efe94fd726a49c050eb1a6e0069171983 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 23 Apr 2025 03:13:35 +0000
Subject: [PATCH 33/44] chore(perf): faster base64 decoding

---
 src/internal/utils/base64.ts | 14 ++++++++------
 1 file changed, 8 insertions(+), 6 deletions(-)

diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts
index 50d616c..725fbda 100644
--- a/src/internal/utils/base64.ts
+++ b/src/internal/utils/base64.ts
@@ -22,15 +22,17 @@ export const toBase64 = (data: string | Uint8Array | null | undefined): string =
 
 export const fromBase64 = (str: string): Uint8Array => {
   if (typeof (globalThis as any).Buffer !== 'undefined') {
-    return new Uint8Array((globalThis as any).Buffer.from(str, 'base64'));
+    const buf = (globalThis as any).Buffer.from(str, 'base64');
+    return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
   }
 
   if (typeof atob !== 'undefined') {
-    return new Uint8Array(
-      atob(str)
-        .split('')
-        .map((c) => c.charCodeAt(0)),
-    );
+    const bstr = atob(str);
+    const buf = new Uint8Array(bstr.length);
+    for (let i = 0; i < bstr.length; i++) {
+      buf[i] = bstr.charCodeAt(i);
+    }
+    return buf;
   }
 
   throw new GitpodError('Cannot decode base64 string; Expected `Buffer` or `atob` to be defined');

From d78258ce7b00f01f7714c59bda0d12d3f70b7ec3 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 23 Apr 2025 03:18:10 +0000
Subject: [PATCH 34/44] chore(ci): add timeout thresholds for CI jobs

---
 .github/workflows/ci.yml | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 4864646..43d363e 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -10,6 +10,7 @@ on:
 
 jobs:
   lint:
+    timeout-minutes: 10
     name: lint
     runs-on: ubuntu-latest
     steps:
@@ -27,6 +28,7 @@ jobs:
         run: ./scripts/lint
 
   build:
+    timeout-minutes: 5
     name: build
     runs-on: ubuntu-latest
     permissions:
@@ -61,6 +63,7 @@ jobs:
           SHA: ${{ github.sha }}
         run: ./scripts/utils/upload-artifact.sh
   test:
+    timeout-minutes: 10
     name: test
     runs-on: ubuntu-latest
     steps:

From c60c38f7f805d86e56d6a2f96c742b1549d62e5c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 24 Apr 2025 02:31:00 +0000
Subject: [PATCH 35/44] chore(internal): codegen related update

---
 .github/workflows/ci.yml             | 18 +++++++++---------
 .github/workflows/publish-npm.yml    |  2 +-
 .github/workflows/release-doctor.yml |  2 +-
 3 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 43d363e..221b21a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -1,18 +1,18 @@
 name: CI
 on:
   push:
-    branches:
-      - main
-  pull_request:
-    branches:
-      - main
-      - next
+    branches-ignore:
+      - 'generated'
+      - 'codegen/**'
+      - 'integrated/**'
+      - 'stl-preview-head/**'
+      - 'stl-preview-base/**'
 
 jobs:
   lint:
     timeout-minutes: 10
     name: lint
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04
     steps:
       - uses: actions/checkout@v4
 
@@ -30,7 +30,7 @@ jobs:
   build:
     timeout-minutes: 5
     name: build
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04
     permissions:
       contents: read
       id-token: write
@@ -65,7 +65,7 @@ jobs:
   test:
     timeout-minutes: 10
     name: test
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04
     steps:
       - uses: actions/checkout@v4
 
diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index d11b246..224f0d7 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -11,7 +11,7 @@ on:
 jobs:
   publish:
     name: publish
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04
 
     steps:
       - uses: actions/checkout@v4
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 742b303..07e7079 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -8,7 +8,7 @@ on:
 jobs:
   release_doctor:
     name: release doctor
-    runs-on: ubuntu-latest
+    runs-on: depot-ubuntu-24.04
     if: github.repository == 'gitpod-io/gitpod-sdk-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
 
     steps:

From 678516c59e2a0a39caa817aa847f9a3f197172b7 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 24 Apr 2025 02:31:37 +0000
Subject: [PATCH 36/44] chore(ci): only use depot for staging repos

---
 .github/workflows/ci.yml             | 6 +++---
 .github/workflows/publish-npm.yml    | 2 +-
 .github/workflows/release-doctor.yml | 2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 221b21a..8c21a27 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -12,7 +12,7 @@ jobs:
   lint:
     timeout-minutes: 10
     name: lint
-    runs-on: depot-ubuntu-24.04
+    runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
     steps:
       - uses: actions/checkout@v4
 
@@ -30,7 +30,7 @@ jobs:
   build:
     timeout-minutes: 5
     name: build
-    runs-on: depot-ubuntu-24.04
+    runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
     permissions:
       contents: read
       id-token: write
@@ -65,7 +65,7 @@ jobs:
   test:
     timeout-minutes: 10
     name: test
-    runs-on: depot-ubuntu-24.04
+    runs-on: ${{ github.repository == 'stainless-sdks/gitpod-typescript' && 'depot-ubuntu-24.04' || 'ubuntu-latest' }}
     steps:
       - uses: actions/checkout@v4
 
diff --git a/.github/workflows/publish-npm.yml b/.github/workflows/publish-npm.yml
index 224f0d7..d11b246 100644
--- a/.github/workflows/publish-npm.yml
+++ b/.github/workflows/publish-npm.yml
@@ -11,7 +11,7 @@ on:
 jobs:
   publish:
     name: publish
-    runs-on: depot-ubuntu-24.04
+    runs-on: ubuntu-latest
 
     steps:
       - uses: actions/checkout@v4
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 07e7079..742b303 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -8,7 +8,7 @@ on:
 jobs:
   release_doctor:
     name: release doctor
-    runs-on: depot-ubuntu-24.04
+    runs-on: ubuntu-latest
     if: github.repository == 'gitpod-io/gitpod-sdk-typescript' && (github.event_name == 'push' || github.event_name == 'workflow_dispatch' || startsWith(github.head_ref, 'release-please') || github.head_ref == 'next')
 
     steps:

From eafa310bb3964addb8bbbf8c8811564f6985068e Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Tue, 29 Apr 2025 02:56:55 +0000
Subject: [PATCH 37/44] chore(internal): refactor utils

---
 src/client.ts                 | 10 +++---
 src/internal/decoders/line.ts | 67 ++++++-----------------------------
 src/internal/headers.ts       |  5 +--
 src/internal/utils/base64.ts  |  9 ++---
 src/internal/utils/bytes.ts   | 32 +++++++++++++++++
 5 files changed, 56 insertions(+), 67 deletions(-)
 create mode 100644 src/internal/utils/bytes.ts

diff --git a/src/client.ts b/src/client.ts
index 8db32fe..3aadcfe 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -700,12 +700,12 @@ export class Gitpod {
       fetchOptions.method = method.toUpperCase();
     }
 
-    return (
+    try {
       // use undefined this binding; fetch errors if bound to something else in browser/cloudflare
-      this.fetch.call(undefined, url, fetchOptions).finally(() => {
-        clearTimeout(timeout);
-      })
-    );
+      return await this.fetch.call(undefined, url, fetchOptions);
+    } finally {
+      clearTimeout(timeout);
+    }
   }
 
   private shouldRetry(response: Response): boolean {
diff --git a/src/internal/decoders/line.ts b/src/internal/decoders/line.ts
index a4c237f..b3bfa97 100644
--- a/src/internal/decoders/line.ts
+++ b/src/internal/decoders/line.ts
@@ -1,4 +1,4 @@
-import { GitpodError } from '../../core/error';
+import { concatBytes, decodeUTF8, encodeUTF8 } from '../utils/bytes';
 
 export type Bytes = string | ArrayBuffer | Uint8Array | null | undefined;
 
@@ -13,16 +13,11 @@ export class LineDecoder {
   static NEWLINE_CHARS = new Set(['\n', '\r']);
   static NEWLINE_REGEXP = /\r\n|[\n\r]/g;
 
-  buffer: Uint8Array;
+  #buffer: Uint8Array;
   #carriageReturnIndex: number | null;
-  textDecoder:
-    | undefined
-    | {
-        decode(buffer: Uint8Array | ArrayBuffer): string;
-      };
 
   constructor() {
-    this.buffer = new Uint8Array();
+    this.#buffer = new Uint8Array();
     this.#carriageReturnIndex = null;
   }
 
@@ -33,17 +28,14 @@ export class LineDecoder {
 
     const binaryChunk =
       chunk instanceof ArrayBuffer ? new Uint8Array(chunk)
-      : typeof chunk === 'string' ? new TextEncoder().encode(chunk)
+      : typeof chunk === 'string' ? encodeUTF8(chunk)
       : chunk;
 
-    let newData = new Uint8Array(this.buffer.length + binaryChunk.length);
-    newData.set(this.buffer);
-    newData.set(binaryChunk, this.buffer.length);
-    this.buffer = newData;
+    this.#buffer = concatBytes([this.#buffer, binaryChunk]);
 
     const lines: string[] = [];
     let patternIndex;
-    while ((patternIndex = findNewlineIndex(this.buffer, this.#carriageReturnIndex)) != null) {
+    while ((patternIndex = findNewlineIndex(this.#buffer, this.#carriageReturnIndex)) != null) {
       if (patternIndex.carriage && this.#carriageReturnIndex == null) {
         // skip until we either get a corresponding `\n`, a new `\r` or nothing
         this.#carriageReturnIndex = patternIndex.index;
@@ -55,8 +47,8 @@ export class LineDecoder {
         this.#carriageReturnIndex != null &&
         (patternIndex.index !== this.#carriageReturnIndex + 1 || patternIndex.carriage)
       ) {
-        lines.push(this.decodeText(this.buffer.slice(0, this.#carriageReturnIndex - 1)));
-        this.buffer = this.buffer.slice(this.#carriageReturnIndex);
+        lines.push(decodeUTF8(this.#buffer.subarray(0, this.#carriageReturnIndex - 1)));
+        this.#buffer = this.#buffer.subarray(this.#carriageReturnIndex);
         this.#carriageReturnIndex = null;
         continue;
       }
@@ -64,55 +56,18 @@ export class LineDecoder {
       const endIndex =
         this.#carriageReturnIndex !== null ? patternIndex.preceding - 1 : patternIndex.preceding;
 
-      const line = this.decodeText(this.buffer.slice(0, endIndex));
+      const line = decodeUTF8(this.#buffer.subarray(0, endIndex));
       lines.push(line);
 
-      this.buffer = this.buffer.slice(patternIndex.index);
+      this.#buffer = this.#buffer.subarray(patternIndex.index);
       this.#carriageReturnIndex = null;
     }
 
     return lines;
   }
 
-  decodeText(bytes: Bytes): string {
-    if (bytes == null) return '';
-    if (typeof bytes === 'string') return bytes;
-
-    // Node:
-    if (typeof (globalThis as any).Buffer !== 'undefined') {
-      if (bytes instanceof (globalThis as any).Buffer) {
-        return bytes.toString();
-      }
-      if (bytes instanceof Uint8Array) {
-        return (globalThis as any).Buffer.from(bytes).toString();
-      }
-
-      throw new GitpodError(
-        `Unexpected: received non-Uint8Array (${bytes.constructor.name}) stream chunk in an environment with a global "Buffer" defined, which this library assumes to be Node. Please report this error.`,
-      );
-    }
-
-    // Browser
-    if (typeof (globalThis as any).TextDecoder !== 'undefined') {
-      if (bytes instanceof Uint8Array || bytes instanceof ArrayBuffer) {
-        this.textDecoder ??= new (globalThis as any).TextDecoder('utf8');
-        return this.textDecoder!.decode(bytes);
-      }
-
-      throw new GitpodError(
-        `Unexpected: received non-Uint8Array/ArrayBuffer (${
-          (bytes as any).constructor.name
-        }) in a web platform. Please report this error.`,
-      );
-    }
-
-    throw new GitpodError(
-      `Unexpected: neither Buffer nor TextDecoder are available as globals. Please report this error.`,
-    );
-  }
-
   flush(): string[] {
-    if (!this.buffer.length) {
+    if (!this.#buffer.length) {
       return [];
     }
     return this.decode('\n');
diff --git a/src/internal/headers.ts b/src/internal/headers.ts
index a110a12..8659dde 100644
--- a/src/internal/headers.ts
+++ b/src/internal/headers.ts
@@ -3,7 +3,7 @@
 type HeaderValue = string | undefined | null;
 export type HeadersLike =
   | Headers
-  | readonly [string, HeaderValue][]
+  | readonly HeaderValue[][]
   | Record<string, HeaderValue | readonly HeaderValue[]>
   | undefined
   | null
@@ -40,7 +40,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [strin
   }
 
   let shouldClear = false;
-  let iter: Iterable<readonly [string, HeaderValue | readonly HeaderValue[]]>;
+  let iter: Iterable<readonly (HeaderValue | readonly HeaderValue[])[]>;
   if (headers instanceof Headers) {
     iter = headers.entries();
   } else if (isArray(headers)) {
@@ -51,6 +51,7 @@ function* iterateHeaders(headers: HeadersLike): IterableIterator<readonly [strin
   }
   for (let row of iter) {
     const name = row[0];
+    if (typeof name !== 'string') throw new TypeError('expected header name to be a string');
     const values = isArray(row[1]) ? row[1] : [row[1]];
     let didClear = false;
     for (const value of values) {
diff --git a/src/internal/utils/base64.ts b/src/internal/utils/base64.ts
index 725fbda..04d8296 100644
--- a/src/internal/utils/base64.ts
+++ b/src/internal/utils/base64.ts
@@ -1,18 +1,19 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
 import { GitpodError } from '../../core/error';
+import { encodeUTF8 } from './bytes';
 
 export const toBase64 = (data: string | Uint8Array | null | undefined): string => {
   if (!data) return '';
 
-  if (typeof data === 'string') {
-    data = new (globalThis as any).TextEncoder().encode(data);
-  }
-
   if (typeof (globalThis as any).Buffer !== 'undefined') {
     return (globalThis as any).Buffer.from(data).toString('base64');
   }
 
+  if (typeof data === 'string') {
+    data = encodeUTF8(data);
+  }
+
   if (typeof btoa !== 'undefined') {
     return btoa(String.fromCharCode.apply(null, data as any));
   }
diff --git a/src/internal/utils/bytes.ts b/src/internal/utils/bytes.ts
new file mode 100644
index 0000000..8da627a
--- /dev/null
+++ b/src/internal/utils/bytes.ts
@@ -0,0 +1,32 @@
+export function concatBytes(buffers: Uint8Array[]): Uint8Array {
+  let length = 0;
+  for (const buffer of buffers) {
+    length += buffer.length;
+  }
+  const output = new Uint8Array(length);
+  let index = 0;
+  for (const buffer of buffers) {
+    output.set(buffer, index);
+    index += buffer.length;
+  }
+
+  return output;
+}
+
+let encodeUTF8_: (str: string) => Uint8Array;
+export function encodeUTF8(str: string) {
+  let encoder;
+  return (
+    encodeUTF8_ ??
+    ((encoder = new (globalThis as any).TextEncoder()), (encodeUTF8_ = encoder.encode.bind(encoder)))
+  )(str);
+}
+
+let decodeUTF8_: (bytes: Uint8Array) => string;
+export function decodeUTF8(bytes: Uint8Array) {
+  let decoder;
+  return (
+    decodeUTF8_ ??
+    ((decoder = new (globalThis as any).TextDecoder()), (decodeUTF8_ = decoder.decode.bind(decoder)))
+  )(bytes);
+}

From fea4ecb31efa7b73aec94c3aed1f574b80611110 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Thu, 1 May 2025 03:36:12 +0000
Subject: [PATCH 38/44] docs(readme): fix typo

---
 README.md | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/README.md b/README.md
index 0cbfd5f..a2f50c6 100644
--- a/README.md
+++ b/README.md
@@ -80,7 +80,7 @@ async function main() {
 main();
 ```
 
-Error codes are as followed:
+Error codes are as follows:
 
 | Status Code | Error Type                 |
 | ----------- | -------------------------- |

From e94c55895af8caf60720420c33c1e22c6e2d5bd4 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 3 May 2025 02:38:17 +0000
Subject: [PATCH 39/44] chore(internal): codegen related update

---
 .devcontainer/devcontainer.json      | 4 +---
 .github/workflows/release-doctor.yml | 1 -
 package.json                         | 2 +-
 release-please-config.json           | 5 +----
 scripts/build                        | 6 +++++-
 scripts/format                       | 4 ++++
 tsconfig.build.json                  | 2 +-
 tsconfig.json                        | 2 +-
 8 files changed, 14 insertions(+), 12 deletions(-)

diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
index 763462f..43fd5a7 100644
--- a/.devcontainer/devcontainer.json
+++ b/.devcontainer/devcontainer.json
@@ -9,9 +9,7 @@
   "postCreateCommand": "yarn install",
   "customizations": {
     "vscode": {
-      "extensions": [
-        "esbenp.prettier-vscode"
-      ]
+      "extensions": ["esbenp.prettier-vscode"]
     }
   }
 }
diff --git a/.github/workflows/release-doctor.yml b/.github/workflows/release-doctor.yml
index 742b303..f875bac 100644
--- a/.github/workflows/release-doctor.yml
+++ b/.github/workflows/release-doctor.yml
@@ -19,4 +19,3 @@ jobs:
           bash ./bin/check-release-environment
         env:
           NPM_TOKEN: ${{ secrets.GITPOD_NPM_TOKEN || secrets.NPM_TOKEN }}
-
diff --git a/package.json b/package.json
index e99d450..46025d4 100644
--- a/package.json
+++ b/package.json
@@ -17,7 +17,7 @@
     "test": "./scripts/test",
     "build": "./scripts/build",
     "prepublishOnly": "echo 'to publish, run yarn build && (cd dist; yarn publish)' && exit 1",
-    "format": "prettier --write --cache --cache-strategy metadata . !dist",
+    "format": "./scripts/format",
     "prepare": "if ./scripts/utils/check-is-in-git-install.sh; then ./scripts/build && ./scripts/utils/git-swap.sh; fi",
     "tsn": "ts-node -r tsconfig-paths/register",
     "lint": "./scripts/lint",
diff --git a/release-please-config.json b/release-please-config.json
index 624ed99..1ebd0bd 100644
--- a/release-please-config.json
+++ b/release-please-config.json
@@ -60,8 +60,5 @@
     }
   ],
   "release-type": "node",
-  "extra-files": [
-    "src/version.ts",
-    "README.md"
-  ]
+  "extra-files": ["src/version.ts", "README.md"]
 }
diff --git a/scripts/build b/scripts/build
index afc1898..3323742 100755
--- a/scripts/build
+++ b/scripts/build
@@ -19,9 +19,13 @@ for file in LICENSE CHANGELOG.md; do
   if [ -e "${file}" ]; then cp "${file}" dist; fi
 done
 if [ -e "bin/cli" ]; then
-  mkdir dist/bin
+  mkdir -p dist/bin
   cp -p "bin/cli" dist/bin/;
 fi
+if [ -e "bin/migration-config.json" ]; then
+  mkdir -p dist/bin
+  cp -p "bin/migration-config.json" dist/bin/;
+fi
 # this converts the export map paths for the dist directory
 # and does a few other minor things
 node scripts/utils/make-dist-package-json.cjs > dist/package.json
diff --git a/scripts/format b/scripts/format
index 903b1ef..7a75640 100755
--- a/scripts/format
+++ b/scripts/format
@@ -6,3 +6,7 @@ cd "$(dirname "$0")/.."
 
 echo "==> Running eslint --fix"
 ./node_modules/.bin/eslint --fix .
+
+echo "==> Running prettier --write"
+# format things eslint didn't
+./node_modules/.bin/prettier --write --cache --cache-strategy metadata . '!**/dist' '!**/*.ts' '!**/*.mts' '!**/*.cts' '!**/*.js' '!**/*.mjs' '!**/*.cjs'
diff --git a/tsconfig.build.json b/tsconfig.build.json
index 269698c..0460cd2 100644
--- a/tsconfig.build.json
+++ b/tsconfig.build.json
@@ -6,7 +6,7 @@
     "rootDir": "./dist/src",
     "paths": {
       "@gitpod/sdk/*": ["dist/src/*"],
-      "@gitpod/sdk": ["dist/src/index.ts"],
+      "@gitpod/sdk": ["dist/src/index.ts"]
     },
     "noEmit": false,
     "declaration": true,
diff --git a/tsconfig.json b/tsconfig.json
index 4ae7ffe..db8ba0b 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -31,7 +31,7 @@
     "noUncheckedIndexedAccess": true,
     "noImplicitOverride": true,
     "noPropertyAccessFromIndexSignature": true,
-		"isolatedModules": false,
+    "isolatedModules": false,
 
     "skipLibCheck": true
   }

From b52aa0747ab51dbdf0eeb63e3fce2c255f47a06c Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Sat, 3 May 2025 02:39:00 +0000
Subject: [PATCH 40/44] chore(internal): share typescript helpers

---
 package.json   |  10 ++--
 tsc-multi.json |   4 +-
 yarn.lock      | 128 ++++++++++++++++++++++++-------------------------
 3 files changed, 71 insertions(+), 71 deletions(-)

diff --git a/package.json b/package.json
index 46025d4..615f6e6 100644
--- a/package.json
+++ b/package.json
@@ -32,8 +32,8 @@
     "@types/node": "^20.17.6",
     "@types/ssh2": "^1.15.4",
     "@types/sshpk": "^1.17.4",
-    "@typescript-eslint/eslint-plugin": "^8.24.0",
-    "@typescript-eslint/parser": "^8.24.0",
+    "@typescript-eslint/eslint-plugin": "8.31.1",
+    "@typescript-eslint/parser": "8.31.1",
     "eslint": "^9.20.1",
     "eslint-plugin-prettier": "^5.2.3",
     "eslint-plugin-unused-imports": "^4.1.4",
@@ -45,10 +45,10 @@
     "sshpk": "^1.18.0",
     "ts-jest": "^29.1.0",
     "ts-node": "^10.5.0",
-    "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz",
+    "tsc-multi": "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz",
     "tsconfig-paths": "^4.0.0",
-    "typescript": "^4.8.2",
-    "typescript-eslint": "^8.24.0"
+    "typescript": "5.8.3",
+    "typescript-eslint": "8.31.1"
   },
   "resolutions": {
     "synckit": "0.8.8"
diff --git a/tsc-multi.json b/tsc-multi.json
index 4facad5..170bac7 100644
--- a/tsc-multi.json
+++ b/tsc-multi.json
@@ -1,7 +1,7 @@
 {
   "targets": [
-    { "extname": ".js", "module": "commonjs" },
-    { "extname": ".mjs", "module": "esnext" }
+    { "extname": ".js", "module": "commonjs", "shareHelpers": "internal/tslib.js" },
+    { "extname": ".mjs", "module": "esnext", "shareHelpers": "internal/tslib.mjs" }
   ],
   "projects": ["tsconfig.build.json"]
 }
diff --git a/yarn.lock b/yarn.lock
index 6c01b49..414e05d 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -990,62 +990,62 @@
   dependencies:
     "@types/yargs-parser" "*"
 
-"@typescript-eslint/eslint-plugin@8.24.0", "@typescript-eslint/eslint-plugin@^8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.24.0.tgz#574a95d67660a1e4544ae131d672867a5b40abb3"
-  integrity sha512-aFcXEJJCI4gUdXgoo/j9udUYIHgF23MFkg09LFz2dzEmU0+1Plk4rQWv/IYKvPHAtlkkGoB3m5e6oUp+JPsNaQ==
+"@typescript-eslint/eslint-plugin@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.31.1.tgz#62f1befe59647524994e89de4516d8dcba7a850a"
+  integrity sha512-oUlH4h1ABavI4F0Xnl8/fOtML/eu8nI2A1nYd+f+55XI0BLu+RIqKoCiZKNo6DtqZBEQm5aNKA20G3Z5w3R6GQ==
   dependencies:
     "@eslint-community/regexpp" "^4.10.0"
-    "@typescript-eslint/scope-manager" "8.24.0"
-    "@typescript-eslint/type-utils" "8.24.0"
-    "@typescript-eslint/utils" "8.24.0"
-    "@typescript-eslint/visitor-keys" "8.24.0"
+    "@typescript-eslint/scope-manager" "8.31.1"
+    "@typescript-eslint/type-utils" "8.31.1"
+    "@typescript-eslint/utils" "8.31.1"
+    "@typescript-eslint/visitor-keys" "8.31.1"
     graphemer "^1.4.0"
     ignore "^5.3.1"
     natural-compare "^1.4.0"
     ts-api-utils "^2.0.1"
 
-"@typescript-eslint/parser@8.24.0", "@typescript-eslint/parser@^8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.24.0.tgz#bba837f9ee125b78f459ad947ff9b61be8139085"
-  integrity sha512-MFDaO9CYiard9j9VepMNa9MTcqVvSny2N4hkY6roquzj8pdCBRENhErrteaQuu7Yjn1ppk0v1/ZF9CG3KIlrTA==
+"@typescript-eslint/parser@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-8.31.1.tgz#e9b0ccf30d37dde724ee4d15f4dbc195995cce1b"
+  integrity sha512-oU/OtYVydhXnumd0BobL9rkJg7wFJ9bFFPmSmB/bf/XWN85hlViji59ko6bSKBXyseT9V8l+CN1nwmlbiN0G7Q==
   dependencies:
-    "@typescript-eslint/scope-manager" "8.24.0"
-    "@typescript-eslint/types" "8.24.0"
-    "@typescript-eslint/typescript-estree" "8.24.0"
-    "@typescript-eslint/visitor-keys" "8.24.0"
+    "@typescript-eslint/scope-manager" "8.31.1"
+    "@typescript-eslint/types" "8.31.1"
+    "@typescript-eslint/typescript-estree" "8.31.1"
+    "@typescript-eslint/visitor-keys" "8.31.1"
     debug "^4.3.4"
 
-"@typescript-eslint/scope-manager@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.24.0.tgz#2e34b3eb2ce768f2ffb109474174ced5417002b1"
-  integrity sha512-HZIX0UByphEtdVBKaQBgTDdn9z16l4aTUz8e8zPQnyxwHBtf5vtl1L+OhH+m1FGV9DrRmoDuYKqzVrvWDcDozw==
+"@typescript-eslint/scope-manager@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-8.31.1.tgz#1eb52e76878f545e4add142e0d8e3e97e7aa443b"
+  integrity sha512-BMNLOElPxrtNQMIsFHE+3P0Yf1z0dJqV9zLdDxN/xLlWMlXK/ApEsVEKzpizg9oal8bAT5Sc7+ocal7AC1HCVw==
   dependencies:
-    "@typescript-eslint/types" "8.24.0"
-    "@typescript-eslint/visitor-keys" "8.24.0"
+    "@typescript-eslint/types" "8.31.1"
+    "@typescript-eslint/visitor-keys" "8.31.1"
 
-"@typescript-eslint/type-utils@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.24.0.tgz#6ee3ec4db06f9e5e7b01ca6c2b5dd5843a9fd1e8"
-  integrity sha512-8fitJudrnY8aq0F1wMiPM1UUgiXQRJ5i8tFjq9kGfRajU+dbPyOuHbl0qRopLEidy0MwqgTHDt6CnSeXanNIwA==
+"@typescript-eslint/type-utils@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/type-utils/-/type-utils-8.31.1.tgz#be0f438fb24b03568e282a0aed85f776409f970c"
+  integrity sha512-fNaT/m9n0+dpSp8G/iOQ05GoHYXbxw81x+yvr7TArTuZuCA6VVKbqWYVZrV5dVagpDTtj/O8k5HBEE/p/HM5LA==
   dependencies:
-    "@typescript-eslint/typescript-estree" "8.24.0"
-    "@typescript-eslint/utils" "8.24.0"
+    "@typescript-eslint/typescript-estree" "8.31.1"
+    "@typescript-eslint/utils" "8.31.1"
     debug "^4.3.4"
     ts-api-utils "^2.0.1"
 
-"@typescript-eslint/types@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.24.0.tgz#694e7fb18d70506c317b816de9521300b0f72c8e"
-  integrity sha512-VacJCBTyje7HGAw7xp11q439A+zeGG0p0/p2zsZwpnMzjPB5WteaWqt4g2iysgGFafrqvyLWqq6ZPZAOCoefCw==
+"@typescript-eslint/types@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-8.31.1.tgz#478ed6f7e8aee1be7b63a60212b6bffe1423b5d4"
+  integrity sha512-SfepaEFUDQYRoA70DD9GtytljBePSj17qPxFHA/h3eg6lPTqGJ5mWOtbXCk1YrVU1cTJRd14nhaXWFu0l2troQ==
 
-"@typescript-eslint/typescript-estree@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.24.0.tgz#0487349be174097bb329a58273100a9629e03c6c"
-  integrity sha512-ITjYcP0+8kbsvT9bysygfIfb+hBj6koDsu37JZG7xrCiy3fPJyNmfVtaGsgTUSEuTzcvME5YI5uyL5LD1EV5ZQ==
+"@typescript-eslint/typescript-estree@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-8.31.1.tgz#37792fe7ef4d3021c7580067c8f1ae66daabacdf"
+  integrity sha512-kaA0ueLe2v7KunYOyWYtlf/QhhZb7+qh4Yw6Ni5kgukMIG+iP773tjgBiLWIXYumWCwEq3nLW+TUywEp8uEeag==
   dependencies:
-    "@typescript-eslint/types" "8.24.0"
-    "@typescript-eslint/visitor-keys" "8.24.0"
+    "@typescript-eslint/types" "8.31.1"
+    "@typescript-eslint/visitor-keys" "8.31.1"
     debug "^4.3.4"
     fast-glob "^3.3.2"
     is-glob "^4.0.3"
@@ -1053,22 +1053,22 @@
     semver "^7.6.0"
     ts-api-utils "^2.0.1"
 
-"@typescript-eslint/utils@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.24.0.tgz#21cb1195ae79230af825bfeed59574f5cb70a749"
-  integrity sha512-07rLuUBElvvEb1ICnafYWr4hk8/U7X9RDCOqd9JcAMtjh/9oRmcfN4yGzbPVirgMR0+HLVHehmu19CWeh7fsmQ==
+"@typescript-eslint/utils@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/utils/-/utils-8.31.1.tgz#5628ea0393598a0b2f143d0fc6d019f0dee9dd14"
+  integrity sha512-2DSI4SNfF5T4oRveQ4nUrSjUqjMND0nLq9rEkz0gfGr3tg0S5KB6DhwR+WZPCjzkZl3cH+4x2ce3EsL50FubjQ==
   dependencies:
     "@eslint-community/eslint-utils" "^4.4.0"
-    "@typescript-eslint/scope-manager" "8.24.0"
-    "@typescript-eslint/types" "8.24.0"
-    "@typescript-eslint/typescript-estree" "8.24.0"
+    "@typescript-eslint/scope-manager" "8.31.1"
+    "@typescript-eslint/types" "8.31.1"
+    "@typescript-eslint/typescript-estree" "8.31.1"
 
-"@typescript-eslint/visitor-keys@8.24.0":
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.24.0.tgz#36ecf0b9b1d819ad88a3bd4157ab7d594cb797c9"
-  integrity sha512-kArLq83QxGLbuHrTMoOEWO+l2MwsNS2TGISEdx8xgqpkbytB07XmlQyQdNDrCc1ecSqx0cnmhGvpX+VBwqqSkg==
+"@typescript-eslint/visitor-keys@8.31.1":
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-8.31.1.tgz#6742b0e3ba1e0c1e35bdaf78c03e759eb8dd8e75"
+  integrity sha512-I+/rgqOVBn6f0o7NDTmAPWWC6NuqhV174lfYvAm9fUaWeiefLdux9/YI3/nLugEn9L8fcSi0XmpKi/r5u0nmpw==
   dependencies:
-    "@typescript-eslint/types" "8.24.0"
+    "@typescript-eslint/types" "8.31.1"
     eslint-visitor-keys "^4.2.0"
 
 acorn-jsx@^5.3.2:
@@ -3403,9 +3403,9 @@ ts-node@^10.5.0:
     v8-compile-cache-lib "^3.0.0"
     yn "3.1.1"
 
-"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz":
-  version "1.1.3"
-  resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.3/tsc-multi.tgz#8fc21fc95b247b86721b95fabfb10c6a436134c3"
+"tsc-multi@https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz":
+  version "1.1.4"
+  resolved "https://github.com/stainless-api/tsc-multi/releases/download/v1.1.4/tsc-multi-1.1.4.tgz#cbed459a9e902f5295ec3daaf1c7aa3b10427e55"
   dependencies:
     debug "^4.3.7"
     fast-glob "^3.3.2"
@@ -3459,24 +3459,24 @@ type-fest@^0.21.3:
   resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.21.3.tgz#d260a24b0198436e133fa26a524a6d65fa3b2e37"
   integrity sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==
 
-typescript-eslint@^8.24.0:
-  version "8.24.0"
-  resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.24.0.tgz#cc655e71885ecb8280342b422ad839a2e2e46a96"
-  integrity sha512-/lmv4366en/qbB32Vz5+kCNZEMf6xYHwh1z48suBwZvAtnXKbP+YhGe8OLE2BqC67LMqKkCNLtjejdwsdW6uOQ==
+typescript-eslint@8.31.1:
+  version "8.31.1"
+  resolved "https://registry.yarnpkg.com/typescript-eslint/-/typescript-eslint-8.31.1.tgz#b77ab1e48ced2daab9225ff94bab54391a4af69b"
+  integrity sha512-j6DsEotD/fH39qKzXTQRwYYWlt7D+0HmfpOK+DVhwJOFLcdmn92hq3mBb7HlKJHbjjI/gTOqEcc9d6JfpFf/VA==
   dependencies:
-    "@typescript-eslint/eslint-plugin" "8.24.0"
-    "@typescript-eslint/parser" "8.24.0"
-    "@typescript-eslint/utils" "8.24.0"
+    "@typescript-eslint/eslint-plugin" "8.31.1"
+    "@typescript-eslint/parser" "8.31.1"
+    "@typescript-eslint/utils" "8.31.1"
 
 typescript@5.6.1-rc:
   version "5.6.1-rc"
   resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.6.1-rc.tgz#d5e4d7d8170174fed607b74cc32aba3d77018e02"
   integrity sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==
 
-typescript@^4.8.2:
-  version "4.9.5"
-  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
-  integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
+typescript@5.8.3:
+  version "5.8.3"
+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.8.3.tgz#92f8a3e5e3cf497356f4178c34cd65a7f5e8440e"
+  integrity sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==
 
 undici-types@~5.26.4:
   version "5.26.5"

From f50f5adf1ea13bb39845ff8644e2f670bc01856d Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Wed, 7 May 2025 09:04:45 +0000
Subject: [PATCH 41/44] feat(api): manual updates

---
 .stats.yml                                    |   8 +-
 api.md                                        |  35 ++-
 src/client.ts                                 |  28 +--
 src/core/pagination.ts                        |  55 -----
 src/resources/editors.ts                      |  31 ++-
 .../environments/automations/services.ts      |  11 +
 src/resources/environments/environments.ts    |  65 ++++++
 src/resources/environments/index.ts           |   2 +
 src/resources/events.ts                       |   8 +-
 src/resources/identity.ts                     |   8 +
 src/resources/index.ts                        |  10 +-
 src/resources/organizations/index.ts          |  12 +-
 src/resources/organizations/organizations.ts  | 118 +++-------
 src/resources/organizations/policies.ts       | 217 ++++++++++++++++++
 src/resources/projects/projects.ts            |  30 +++
 .../runners/configurations/schema.ts          |  56 +++++
 src/resources/runners/index.ts                |   2 +
 src/resources/runners/runners.ts              |  88 ++++++-
 src/resources/secrets.ts                      |  62 ++---
 src/resources/shared.ts                       |   6 +
 src/resources/users/dotfiles.ts               |  89 +++++++
 src/resources/users/index.ts                  |   8 +
 src/resources/users/users.ts                  |  20 ++
 .../environments/environments.test.ts         |  21 ++
 .../organizations/organizations.test.ts       |  12 -
 .../organizations/policies.test.ts            |  61 +++++
 tests/api-resources/projects/projects.test.ts |   1 +
 tests/api-resources/users/dotfiles.test.ts    |  34 +++
 28 files changed, 887 insertions(+), 211 deletions(-)
 create mode 100644 src/resources/organizations/policies.ts
 create mode 100644 src/resources/users/dotfiles.ts
 create mode 100644 tests/api-resources/organizations/policies.test.ts
 create mode 100644 tests/api-resources/users/dotfiles.test.ts

diff --git a/.stats.yml b/.stats.yml
index e8f1d28..ef4c630 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 111
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-3655d5ad0ac3e228c1519af70dbf3d0bfa3c47a2d06d4cac92a650da051b49a6.yml
-openapi_spec_hash: 5dbb5577e6a7cae7db615b1b06c9d23e
-config_hash: 719ad411c0ec7402a7a4c1f95515280c
+configured_endpoints: 115
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml
+openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d
+config_hash: 981e43e8b1e3ddabd435d350aeeed417
diff --git a/api.md b/api.md
index 4a2d257..82689ae 100644
--- a/api.md
+++ b/api.md
@@ -68,6 +68,7 @@ Types:
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentRetrieveResponse</a></code>
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentUpdateResponse</a></code>
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentDeleteResponse</a></code>
+- <code><a href="./src/resources/environments/environments.ts">EnvironmentCreateEnvironmentTokenResponse</a></code>
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentCreateFromProjectResponse</a></code>
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentCreateLogsTokenResponse</a></code>
 - <code><a href="./src/resources/environments/environments.ts">EnvironmentMarkActiveResponse</a></code>
@@ -81,6 +82,7 @@ Methods:
 - <code title="post /gitpod.v1.EnvironmentService/UpdateEnvironment">client.environments.<a href="./src/resources/environments/environments.ts">update</a>({ ...params }) -> unknown</code>
 - <code title="post /gitpod.v1.EnvironmentService/ListEnvironments">client.environments.<a href="./src/resources/environments/environments.ts">list</a>({ ...params }) -> EnvironmentsEnvironmentsPage</code>
 - <code title="post /gitpod.v1.EnvironmentService/DeleteEnvironment">client.environments.<a href="./src/resources/environments/environments.ts">delete</a>({ ...params }) -> unknown</code>
+- <code title="post /gitpod.v1.EnvironmentService/CreateEnvironmentAccessToken">client.environments.<a href="./src/resources/environments/environments.ts">createEnvironmentToken</a>({ ...params }) -> EnvironmentCreateEnvironmentTokenResponse</code>
 - <code title="post /gitpod.v1.EnvironmentService/CreateEnvironmentFromProject">client.environments.<a href="./src/resources/environments/environments.ts">createFromProject</a>({ ...params }) -> EnvironmentCreateFromProjectResponse</code>
 - <code title="post /gitpod.v1.EnvironmentService/CreateEnvironmentLogsToken">client.environments.<a href="./src/resources/environments/environments.ts">createLogsToken</a>({ ...params }) -> EnvironmentCreateLogsTokenResponse</code>
 - <code title="post /gitpod.v1.EnvironmentService/MarkEnvironmentActive">client.environments.<a href="./src/resources/environments/environments.ts">markActive</a>({ ...params }) -> unknown</code>
@@ -190,6 +192,7 @@ Methods:
 
 Types:
 
+- <code><a href="./src/resources/identity.ts">IDTokenVersion</a></code>
 - <code><a href="./src/resources/identity.ts">IdentityExchangeTokenResponse</a></code>
 - <code><a href="./src/resources/identity.ts">IdentityGetAuthenticatedIdentityResponse</a></code>
 - <code><a href="./src/resources/identity.ts">IdentityGetIDTokenResponse</a></code>
@@ -207,7 +210,7 @@ Types:
 - <code><a href="./src/resources/organizations/organizations.ts">InviteDomains</a></code>
 - <code><a href="./src/resources/organizations/organizations.ts">Organization</a></code>
 - <code><a href="./src/resources/organizations/organizations.ts">OrganizationMember</a></code>
-- <code><a href="./src/resources/organizations/organizations.ts">Scope</a></code>
+- <code><a href="./src/resources/organizations/organizations.ts">OrganizationTier</a></code>
 - <code><a href="./src/resources/organizations/organizations.ts">OrganizationCreateResponse</a></code>
 - <code><a href="./src/resources/organizations/organizations.ts">OrganizationRetrieveResponse</a></code>
 - <code><a href="./src/resources/organizations/organizations.ts">OrganizationUpdateResponse</a></code>
@@ -221,7 +224,6 @@ Methods:
 - <code title="post /gitpod.v1.OrganizationService/CreateOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">create</a>({ ...params }) -> OrganizationCreateResponse</code>
 - <code title="post /gitpod.v1.OrganizationService/GetOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">retrieve</a>({ ...params }) -> OrganizationRetrieveResponse</code>
 - <code title="post /gitpod.v1.OrganizationService/UpdateOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">update</a>({ ...params }) -> OrganizationUpdateResponse</code>
-- <code title="post /gitpod.v1.OrganizationService/ListOrganizations">client.organizations.<a href="./src/resources/organizations/organizations.ts">list</a>({ ...params }) -> OrganizationsOrganizationsPage</code>
 - <code title="post /gitpod.v1.OrganizationService/DeleteOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">delete</a>({ ...params }) -> unknown</code>
 - <code title="post /gitpod.v1.OrganizationService/JoinOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">join</a>({ ...params }) -> OrganizationJoinResponse</code>
 - <code title="post /gitpod.v1.OrganizationService/LeaveOrganization">client.organizations.<a href="./src/resources/organizations/organizations.ts">leave</a>({ ...params }) -> unknown</code>
@@ -262,6 +264,19 @@ Methods:
 - <code title="post /gitpod.v1.OrganizationService/GetOrganizationInvite">client.organizations.invites.<a href="./src/resources/organizations/invites.ts">retrieve</a>({ ...params }) -> InviteRetrieveResponse</code>
 - <code title="post /gitpod.v1.OrganizationService/GetOrganizationInviteSummary">client.organizations.invites.<a href="./src/resources/organizations/invites.ts">getSummary</a>({ ...params }) -> InviteGetSummaryResponse</code>
 
+## Policies
+
+Types:
+
+- <code><a href="./src/resources/organizations/policies.ts">OrganizationPolicies</a></code>
+- <code><a href="./src/resources/organizations/policies.ts">PolicyRetrieveResponse</a></code>
+- <code><a href="./src/resources/organizations/policies.ts">PolicyUpdateResponse</a></code>
+
+Methods:
+
+- <code title="post /gitpod.v1.OrganizationService/GetOrganizationPolicies">client.organizations.policies.<a href="./src/resources/organizations/policies.ts">retrieve</a>({ ...params }) -> PolicyRetrieveResponse</code>
+- <code title="post /gitpod.v1.OrganizationService/UpdateOrganizationPolicies">client.organizations.policies.<a href="./src/resources/organizations/policies.ts">update</a>({ ...params }) -> unknown</code>
+
 ## SSOConfigurations
 
 Types:
@@ -326,6 +341,8 @@ Methods:
 
 Types:
 
+- <code><a href="./src/resources/runners/runners.ts">LogLevel</a></code>
+- <code><a href="./src/resources/runners/runners.ts">MetricsConfiguration</a></code>
 - <code><a href="./src/resources/runners/runners.ts">Runner</a></code>
 - <code><a href="./src/resources/runners/runners.ts">RunnerCapability</a></code>
 - <code><a href="./src/resources/runners/runners.ts">RunnerConfiguration</a></code>
@@ -453,6 +470,7 @@ Methods:
 Types:
 
 - <code><a href="./src/resources/secrets.ts">Secret</a></code>
+- <code><a href="./src/resources/secrets.ts">SecretScope</a></code>
 - <code><a href="./src/resources/secrets.ts">SecretCreateResponse</a></code>
 - <code><a href="./src/resources/secrets.ts">SecretDeleteResponse</a></code>
 - <code><a href="./src/resources/secrets.ts">SecretGetValueResponse</a></code>
@@ -479,6 +497,19 @@ Methods:
 - <code title="post /gitpod.v1.UserService/GetAuthenticatedUser">client.users.<a href="./src/resources/users/users.ts">getAuthenticatedUser</a>({ ...params }) -> UserGetAuthenticatedUserResponse</code>
 - <code title="post /gitpod.v1.UserService/SetSuspended">client.users.<a href="./src/resources/users/users.ts">setSuspended</a>({ ...params }) -> unknown</code>
 
+## Dotfiles
+
+Types:
+
+- <code><a href="./src/resources/users/dotfiles.ts">DotfilesConfiguration</a></code>
+- <code><a href="./src/resources/users/dotfiles.ts">DotfileGetResponse</a></code>
+- <code><a href="./src/resources/users/dotfiles.ts">DotfileSetResponse</a></code>
+
+Methods:
+
+- <code title="post /gitpod.v1.UserService/GetDotfilesConfiguration">client.users.dotfiles.<a href="./src/resources/users/dotfiles.ts">get</a>({ ...params }) -> DotfileGetResponse</code>
+- <code title="post /gitpod.v1.UserService/SetDotfilesConfiguration">client.users.dotfiles.<a href="./src/resources/users/dotfiles.ts">set</a>({ ...params }) -> unknown</code>
+
 ## Pats
 
 Types:
diff --git a/src/client.ts b/src/client.ts
index 3aadcfe..e9880cc 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -35,8 +35,6 @@ import {
   LoginProvidersPageResponse,
   type MembersPageParams,
   MembersPageResponse,
-  type OrganizationsPageParams,
-  OrganizationsPageResponse,
   type PersonalAccessTokensPageParams,
   PersonalAccessTokensPageResponse,
   type PoliciesPageParams,
@@ -101,6 +99,7 @@ import {
 } from './resources/events';
 import { Group, GroupListParams, Groups, GroupsGroupsPage } from './resources/groups';
 import {
+  IDTokenVersion,
   Identity,
   IdentityExchangeTokenParams,
   IdentityExchangeTokenResponse,
@@ -118,6 +117,7 @@ import {
   SecretGetValueParams,
   SecretGetValueResponse,
   SecretListParams,
+  SecretScope,
   SecretUpdateValueParams,
   SecretUpdateValueResponse,
   Secrets,
@@ -130,6 +130,8 @@ import {
   AdmissionLevel,
   Environment,
   EnvironmentActivitySignal,
+  EnvironmentCreateEnvironmentTokenParams,
+  EnvironmentCreateEnvironmentTokenResponse,
   EnvironmentCreateFromProjectParams,
   EnvironmentCreateFromProjectResponse,
   EnvironmentCreateLogsTokenParams,
@@ -168,18 +170,16 @@ import {
   OrganizationLeaveParams,
   OrganizationLeaveResponse,
   OrganizationListMembersParams,
-  OrganizationListParams,
   OrganizationMember,
   OrganizationMembersMembersPage,
   OrganizationRetrieveParams,
   OrganizationRetrieveResponse,
   OrganizationSetRoleParams,
   OrganizationSetRoleResponse,
+  OrganizationTier,
   OrganizationUpdateParams,
   OrganizationUpdateResponse,
   Organizations,
-  OrganizationsOrganizationsPage,
-  Scope,
 } from './resources/organizations/organizations';
 import {
   EnvironmentInitializer,
@@ -201,6 +201,8 @@ import {
   ProjectsProjectsPage,
 } from './resources/projects/projects';
 import {
+  LogLevel,
+  MetricsConfiguration,
   Runner,
   RunnerCapability,
   RunnerCheckAuthenticationForHostParams,
@@ -973,12 +975,6 @@ export declare namespace Gitpod {
   export import MembersPage = Pagination.MembersPage;
   export { type MembersPageParams as MembersPageParams, type MembersPageResponse as MembersPageResponse };
 
-  export import OrganizationsPage = Pagination.OrganizationsPage;
-  export {
-    type OrganizationsPageParams as OrganizationsPageParams,
-    type OrganizationsPageResponse as OrganizationsPageResponse,
-  };
-
   export import PersonalAccessTokensPage = Pagination.PersonalAccessTokensPage;
   export {
     type PersonalAccessTokensPageParams as PersonalAccessTokensPageParams,
@@ -1058,6 +1054,7 @@ export declare namespace Gitpod {
     type EnvironmentRetrieveResponse as EnvironmentRetrieveResponse,
     type EnvironmentUpdateResponse as EnvironmentUpdateResponse,
     type EnvironmentDeleteResponse as EnvironmentDeleteResponse,
+    type EnvironmentCreateEnvironmentTokenResponse as EnvironmentCreateEnvironmentTokenResponse,
     type EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse,
     type EnvironmentCreateLogsTokenResponse as EnvironmentCreateLogsTokenResponse,
     type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse,
@@ -1069,6 +1066,7 @@ export declare namespace Gitpod {
     type EnvironmentUpdateParams as EnvironmentUpdateParams,
     type EnvironmentListParams as EnvironmentListParams,
     type EnvironmentDeleteParams as EnvironmentDeleteParams,
+    type EnvironmentCreateEnvironmentTokenParams as EnvironmentCreateEnvironmentTokenParams,
     type EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams,
     type EnvironmentCreateLogsTokenParams as EnvironmentCreateLogsTokenParams,
     type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams,
@@ -1096,6 +1094,7 @@ export declare namespace Gitpod {
 
   export {
     Identity as Identity,
+    type IDTokenVersion as IDTokenVersion,
     type IdentityExchangeTokenResponse as IdentityExchangeTokenResponse,
     type IdentityGetAuthenticatedIdentityResponse as IdentityGetAuthenticatedIdentityResponse,
     type IdentityGetIDTokenResponse as IdentityGetIDTokenResponse,
@@ -1109,7 +1108,7 @@ export declare namespace Gitpod {
     type InviteDomains as InviteDomains,
     type Organization as Organization,
     type OrganizationMember as OrganizationMember,
-    type Scope as Scope,
+    type OrganizationTier as OrganizationTier,
     type OrganizationCreateResponse as OrganizationCreateResponse,
     type OrganizationRetrieveResponse as OrganizationRetrieveResponse,
     type OrganizationUpdateResponse as OrganizationUpdateResponse,
@@ -1117,12 +1116,10 @@ export declare namespace Gitpod {
     type OrganizationJoinResponse as OrganizationJoinResponse,
     type OrganizationLeaveResponse as OrganizationLeaveResponse,
     type OrganizationSetRoleResponse as OrganizationSetRoleResponse,
-    type OrganizationsOrganizationsPage as OrganizationsOrganizationsPage,
     type OrganizationMembersMembersPage as OrganizationMembersMembersPage,
     type OrganizationCreateParams as OrganizationCreateParams,
     type OrganizationRetrieveParams as OrganizationRetrieveParams,
     type OrganizationUpdateParams as OrganizationUpdateParams,
-    type OrganizationListParams as OrganizationListParams,
     type OrganizationDeleteParams as OrganizationDeleteParams,
     type OrganizationJoinParams as OrganizationJoinParams,
     type OrganizationLeaveParams as OrganizationLeaveParams,
@@ -1152,6 +1149,8 @@ export declare namespace Gitpod {
 
   export {
     Runners as Runners,
+    type LogLevel as LogLevel,
+    type MetricsConfiguration as MetricsConfiguration,
     type Runner as Runner,
     type RunnerCapability as RunnerCapability,
     type RunnerConfiguration as RunnerConfiguration,
@@ -1182,6 +1181,7 @@ export declare namespace Gitpod {
   export {
     Secrets as Secrets,
     type Secret as Secret,
+    type SecretScope as SecretScope,
     type SecretCreateResponse as SecretCreateResponse,
     type SecretDeleteResponse as SecretDeleteResponse,
     type SecretGetValueResponse as SecretGetValueResponse,
diff --git a/src/core/pagination.ts b/src/core/pagination.ts
index 5ae7b97..250b4fc 100644
--- a/src/core/pagination.ts
+++ b/src/core/pagination.ts
@@ -608,61 +608,6 @@ export class MembersPage<Item> extends AbstractPage<Item> implements MembersPage
   }
 }
 
-export interface OrganizationsPageResponse<Item> {
-  organizations: Array<Item>;
-
-  pagination: OrganizationsPageResponse.Pagination;
-}
-
-export namespace OrganizationsPageResponse {
-  export interface Pagination {
-    nextToken?: string;
-  }
-}
-
-export interface OrganizationsPageParams {
-  pageSize?: number;
-
-  token?: string;
-}
-
-export class OrganizationsPage<Item> extends AbstractPage<Item> implements OrganizationsPageResponse<Item> {
-  organizations: Array<Item>;
-
-  pagination: OrganizationsPageResponse.Pagination;
-
-  constructor(
-    client: Gitpod,
-    response: Response,
-    body: OrganizationsPageResponse<Item>,
-    options: FinalRequestOptions,
-  ) {
-    super(client, response, body, options);
-
-    this.organizations = body.organizations || [];
-    this.pagination = body.pagination || {};
-  }
-
-  getPaginatedItems(): Item[] {
-    return this.organizations ?? [];
-  }
-
-  nextPageRequestOptions(): PageRequestOptions | null {
-    const cursor = this.pagination?.nextToken;
-    if (!cursor) {
-      return null;
-    }
-
-    return {
-      ...this.options,
-      query: {
-        ...maybeObj(this.options.query),
-        token: cursor,
-      },
-    };
-  }
-}
-
 export interface PersonalAccessTokensPageResponse<Item> {
   pagination: PersonalAccessTokensPageResponse.Pagination;
 
diff --git a/src/resources/editors.ts b/src/resources/editors.ts
index 28832f9..84853ac 100644
--- a/src/resources/editors.ts
+++ b/src/resources/editors.ts
@@ -29,7 +29,8 @@ export class Editors extends APIResource {
   }
 
   /**
-   * Lists all available code editors.
+   * Lists all available code editors, optionally filtered to those allowed in an
+   * organization.
    *
    * Use this method to:
    *
@@ -48,6 +49,18 @@ export class Editors extends APIResource {
    *   pagination:
    *     pageSize: 20
    *   ```
+   *
+   * - List editors available to the organization:
+   *
+   *   Shows all available editors that are allowed by the policies enforced in the
+   *   organization with pagination.
+   *
+   *   ```yaml
+   *   pagination:
+   *     pageSize: 20
+   *   filter:
+   *     allowedByPolicy: true
+   *   ```
    */
   list(params: EditorListParams, options?: RequestOptions): PagePromise<EditorsEditorsPage, Editor> {
     const { token, pageSize, ...body } = params;
@@ -126,6 +139,11 @@ export interface EditorRetrieveParams {
 }
 
 export interface EditorListParams extends EditorsPageParams {
+  /**
+   * Body param: filter contains the filter options for listing editors
+   */
+  filter?: EditorListParams.Filter;
+
   /**
    * Body param: pagination contains the pagination options for listing environments
    */
@@ -133,6 +151,17 @@ export interface EditorListParams extends EditorsPageParams {
 }
 
 export namespace EditorListParams {
+  /**
+   * filter contains the filter options for listing editors
+   */
+  export interface Filter {
+    /**
+     * allowed_by_policy filters the response to only editors that are allowed by the
+     * policies enforced in the organization
+     */
+    allowedByPolicy?: boolean;
+  }
+
   /**
    * pagination contains the pagination options for listing environments
    */
diff --git a/src/resources/environments/automations/services.ts b/src/resources/environments/automations/services.ts
index 6941f18..efd2c80 100644
--- a/src/resources/environments/automations/services.ts
+++ b/src/resources/environments/automations/services.ts
@@ -393,6 +393,12 @@ export interface ServiceStatus {
    */
   logUrl?: string;
 
+  /**
+   * output contains the output of the service. setting an output field to empty
+   * string will unset it.
+   */
+  output?: Record<string, string>;
+
   /**
    * phase is the current phase of the service.
    */
@@ -507,6 +513,11 @@ export namespace ServiceUpdateParams {
 
     logUrl?: string | null;
 
+    /**
+     * setting an output field to empty string will unset it.
+     */
+    output?: Record<string, string>;
+
     phase?: ServicesAPI.ServicePhase | null;
 
     session?: string | null;
diff --git a/src/resources/environments/environments.ts b/src/resources/environments/environments.ts
index 2534b7f..695ee9e 100644
--- a/src/resources/environments/environments.ts
+++ b/src/resources/environments/environments.ts
@@ -255,6 +255,32 @@ export class Environments extends APIResource {
     return this._client.post('/gitpod.v1.EnvironmentService/DeleteEnvironment', { body, ...options });
   }
 
+  /**
+   * Creates an access token for the environment.
+   *
+   * Generated tokens are valid for one hour and provide environment-specific access
+   * permissions. The token is scoped to a specific environment.
+   *
+   * ### Examples
+   *
+   * - Generate environment token:
+   *
+   *   Creates a temporary access token for accessing an environment.
+   *
+   *   ```yaml
+   *   environmentId: "07e03a28-65a5-4d98-b532-8ea67b188048"
+   *   ```
+   */
+  createEnvironmentToken(
+    body: EnvironmentCreateEnvironmentTokenParams,
+    options?: RequestOptions,
+  ): APIPromise<EnvironmentCreateEnvironmentTokenResponse> {
+    return this._client.post('/gitpod.v1.EnvironmentService/CreateEnvironmentAccessToken', {
+      body,
+      ...options,
+    });
+  }
+
   /**
    * Creates an environment from an existing project configuration and starts it.
    *
@@ -618,6 +644,12 @@ export namespace EnvironmentSpec {
    * devcontainer is the devcontainer spec of the environment
    */
   export interface Devcontainer {
+    /**
+     * default_devcontainer_image is the default image that is used to start the
+     * devcontainer if no devcontainer config file is found
+     */
+    defaultDevcontainerImage?: string;
+
     /**
      * devcontainer_file_path is the path to the devcontainer file relative to the repo
      * root path must not be absolute (start with a /):
@@ -678,6 +710,11 @@ export namespace EnvironmentSpec {
   }
 
   export interface Secret {
+    /**
+     * id is the unique identifier of the secret.
+     */
+    id?: string;
+
     /**
      * container_registry_basic_auth_host is the hostname of the container registry
      * that supports basic auth
@@ -862,6 +899,12 @@ export namespace EnvironmentStatus {
      * environment.
      */
     session?: string;
+
+    /**
+     * warning_message contains warnings, e.g. when no triggers are defined in the
+     * automations file.
+     */
+    warningMessage?: string;
   }
 
   /**
@@ -1162,6 +1205,11 @@ export namespace EnvironmentStatus {
   }
 
   export interface Secret {
+    /**
+     * id is the unique identifier of the secret.
+     */
+    id?: string;
+
     /**
      * failure_message contains the reason the secret failed to be materialize.
      */
@@ -1226,6 +1274,13 @@ export type EnvironmentUpdateResponse = unknown;
 
 export type EnvironmentDeleteResponse = unknown;
 
+export interface EnvironmentCreateEnvironmentTokenResponse {
+  /**
+   * access_token is the token that can be used for environment authentication
+   */
+  accessToken: string;
+}
+
 export interface EnvironmentCreateFromProjectResponse {
   /**
    * +resource get environment
@@ -1482,6 +1537,14 @@ export interface EnvironmentDeleteParams {
   force?: boolean;
 }
 
+export interface EnvironmentCreateEnvironmentTokenParams {
+  /**
+   * environment_id specifies the environment for which the access token should be
+   * created.
+   */
+  environmentId: string;
+}
+
 export interface EnvironmentCreateFromProjectParams {
   projectId?: string;
 
@@ -1547,6 +1610,7 @@ export declare namespace Environments {
     type EnvironmentRetrieveResponse as EnvironmentRetrieveResponse,
     type EnvironmentUpdateResponse as EnvironmentUpdateResponse,
     type EnvironmentDeleteResponse as EnvironmentDeleteResponse,
+    type EnvironmentCreateEnvironmentTokenResponse as EnvironmentCreateEnvironmentTokenResponse,
     type EnvironmentCreateFromProjectResponse as EnvironmentCreateFromProjectResponse,
     type EnvironmentCreateLogsTokenResponse as EnvironmentCreateLogsTokenResponse,
     type EnvironmentMarkActiveResponse as EnvironmentMarkActiveResponse,
@@ -1558,6 +1622,7 @@ export declare namespace Environments {
     type EnvironmentUpdateParams as EnvironmentUpdateParams,
     type EnvironmentListParams as EnvironmentListParams,
     type EnvironmentDeleteParams as EnvironmentDeleteParams,
+    type EnvironmentCreateEnvironmentTokenParams as EnvironmentCreateEnvironmentTokenParams,
     type EnvironmentCreateFromProjectParams as EnvironmentCreateFromProjectParams,
     type EnvironmentCreateLogsTokenParams as EnvironmentCreateLogsTokenParams,
     type EnvironmentMarkActiveParams as EnvironmentMarkActiveParams,
diff --git a/src/resources/environments/index.ts b/src/resources/environments/index.ts
index f72333e..4378540 100644
--- a/src/resources/environments/index.ts
+++ b/src/resources/environments/index.ts
@@ -20,6 +20,7 @@ export {
   type EnvironmentRetrieveResponse,
   type EnvironmentUpdateResponse,
   type EnvironmentDeleteResponse,
+  type EnvironmentCreateEnvironmentTokenResponse,
   type EnvironmentCreateFromProjectResponse,
   type EnvironmentCreateLogsTokenResponse,
   type EnvironmentMarkActiveResponse,
@@ -30,6 +31,7 @@ export {
   type EnvironmentUpdateParams,
   type EnvironmentListParams,
   type EnvironmentDeleteParams,
+  type EnvironmentCreateEnvironmentTokenParams,
   type EnvironmentCreateFromProjectParams,
   type EnvironmentCreateLogsTokenParams,
   type EnvironmentMarkActiveParams,
diff --git a/src/resources/events.ts b/src/resources/events.ts
index bc5d412..109d1aa 100644
--- a/src/resources/events.ts
+++ b/src/resources/events.ts
@@ -116,7 +116,13 @@ export type ResourceType =
   | 'RESOURCE_TYPE_SERVICE_ACCOUNT'
   | 'RESOURCE_TYPE_SECRET'
   | 'RESOURCE_TYPE_SSO_CONFIG'
-  | 'RESOURCE_TYPE_DOMAIN_VERIFICATION';
+  | 'RESOURCE_TYPE_DOMAIN_VERIFICATION'
+  | 'RESOURCE_TYPE_AGENT_EXECUTION'
+  | 'RESOURCE_TYPE_RUNNER_LLM_INTEGRATION'
+  | 'RESOURCE_TYPE_AGENT'
+  | 'RESOURCE_TYPE_ENVIRONMENT_SESSION'
+  | 'RESOURCE_TYPE_USER_SECRET'
+  | 'RESOURCE_TYPE_ORGANIZATION_POLICY';
 
 export interface EventListResponse {
   id?: string;
diff --git a/src/resources/identity.ts b/src/resources/identity.ts
index e351965..d1fa01f 100644
--- a/src/resources/identity.ts
+++ b/src/resources/identity.ts
@@ -97,6 +97,8 @@ export class Identity extends APIResource {
   }
 }
 
+export type IDTokenVersion = 'ID_TOKEN_VERSION_UNSPECIFIED' | 'ID_TOKEN_VERSION_V1' | 'ID_TOKEN_VERSION_V2';
+
 export interface IdentityExchangeTokenResponse {
   /**
    * access_token is the new access token
@@ -130,10 +132,16 @@ export interface IdentityGetAuthenticatedIdentityParams {
 
 export interface IdentityGetIDTokenParams {
   audience?: Array<string>;
+
+  /**
+   * version is the version of the ID token.
+   */
+  version?: IDTokenVersion;
 }
 
 export declare namespace Identity {
   export {
+    type IDTokenVersion as IDTokenVersion,
     type IdentityExchangeTokenResponse as IdentityExchangeTokenResponse,
     type IdentityGetAuthenticatedIdentityResponse as IdentityGetAuthenticatedIdentityResponse,
     type IdentityGetIDTokenResponse as IdentityGetIDTokenResponse,
diff --git a/src/resources/index.ts b/src/resources/index.ts
index 5a58cc0..be1edca 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -39,6 +39,7 @@ export {
   type EnvironmentRetrieveResponse,
   type EnvironmentUpdateResponse,
   type EnvironmentDeleteResponse,
+  type EnvironmentCreateEnvironmentTokenResponse,
   type EnvironmentCreateFromProjectResponse,
   type EnvironmentCreateLogsTokenResponse,
   type EnvironmentMarkActiveResponse,
@@ -49,6 +50,7 @@ export {
   type EnvironmentUpdateParams,
   type EnvironmentListParams,
   type EnvironmentDeleteParams,
+  type EnvironmentCreateEnvironmentTokenParams,
   type EnvironmentCreateFromProjectParams,
   type EnvironmentCreateLogsTokenParams,
   type EnvironmentMarkActiveParams,
@@ -69,6 +71,7 @@ export {
 export { Groups, type Group, type GroupListParams, type GroupsGroupsPage } from './groups';
 export {
   Identity,
+  type IDTokenVersion,
   type IdentityExchangeTokenResponse,
   type IdentityGetAuthenticatedIdentityResponse,
   type IdentityGetIDTokenResponse,
@@ -81,7 +84,7 @@ export {
   type InviteDomains,
   type Organization,
   type OrganizationMember,
-  type Scope,
+  type OrganizationTier,
   type OrganizationCreateResponse,
   type OrganizationRetrieveResponse,
   type OrganizationUpdateResponse,
@@ -92,13 +95,11 @@ export {
   type OrganizationCreateParams,
   type OrganizationRetrieveParams,
   type OrganizationUpdateParams,
-  type OrganizationListParams,
   type OrganizationDeleteParams,
   type OrganizationJoinParams,
   type OrganizationLeaveParams,
   type OrganizationListMembersParams,
   type OrganizationSetRoleParams,
-  type OrganizationsOrganizationsPage,
   type OrganizationMembersMembersPage,
 } from './organizations/organizations';
 export {
@@ -122,6 +123,8 @@ export {
 } from './projects/projects';
 export {
   Runners,
+  type LogLevel,
+  type MetricsConfiguration,
   type Runner,
   type RunnerCapability,
   type RunnerConfiguration,
@@ -151,6 +154,7 @@ export {
 export {
   Secrets,
   type Secret,
+  type SecretScope,
   type SecretCreateResponse,
   type SecretDeleteResponse,
   type SecretGetValueResponse,
diff --git a/src/resources/organizations/index.ts b/src/resources/organizations/index.ts
index f9b1e8f..a023d54 100644
--- a/src/resources/organizations/index.ts
+++ b/src/resources/organizations/index.ts
@@ -30,7 +30,7 @@ export {
   type InviteDomains,
   type Organization,
   type OrganizationMember,
-  type Scope,
+  type OrganizationTier,
   type OrganizationCreateResponse,
   type OrganizationRetrieveResponse,
   type OrganizationUpdateResponse,
@@ -41,15 +41,21 @@ export {
   type OrganizationCreateParams,
   type OrganizationRetrieveParams,
   type OrganizationUpdateParams,
-  type OrganizationListParams,
   type OrganizationDeleteParams,
   type OrganizationJoinParams,
   type OrganizationLeaveParams,
   type OrganizationListMembersParams,
   type OrganizationSetRoleParams,
-  type OrganizationsOrganizationsPage,
   type OrganizationMembersMembersPage,
 } from './organizations';
+export {
+  Policies,
+  type OrganizationPolicies,
+  type PolicyRetrieveResponse,
+  type PolicyUpdateResponse,
+  type PolicyRetrieveParams,
+  type PolicyUpdateParams,
+} from './policies';
 export {
   SSOConfigurations,
   type ProviderType,
diff --git a/src/resources/organizations/organizations.ts b/src/resources/organizations/organizations.ts
index b0b452d..2393f17 100644
--- a/src/resources/organizations/organizations.ts
+++ b/src/resources/organizations/organizations.ts
@@ -29,6 +29,15 @@ import {
   Invites,
   OrganizationInvite,
 } from './invites';
+import * as PoliciesAPI from './policies';
+import {
+  OrganizationPolicies,
+  Policies,
+  PolicyRetrieveParams,
+  PolicyRetrieveResponse,
+  PolicyUpdateParams,
+  PolicyUpdateResponse,
+} from './policies';
 import * as SSOConfigurationsAPI from './sso-configurations';
 import {
   ProviderType,
@@ -47,19 +56,14 @@ import {
   SSOConfigurationsSSOConfigurationsPage,
 } from './sso-configurations';
 import { APIPromise } from '../../core/api-promise';
-import {
-  MembersPage,
-  type MembersPageParams,
-  OrganizationsPage,
-  type OrganizationsPageParams,
-  PagePromise,
-} from '../../core/pagination';
+import { MembersPage, type MembersPageParams, PagePromise } from '../../core/pagination';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Organizations extends APIResource {
   domainVerifications: DomainVerificationsAPI.DomainVerifications =
     new DomainVerificationsAPI.DomainVerifications(this._client);
   invites: InvitesAPI.Invites = new InvitesAPI.Invites(this._client);
+  policies: PoliciesAPI.Policies = new PoliciesAPI.Policies(this._client);
   ssoConfigurations: SSOConfigurationsAPI.SSOConfigurations = new SSOConfigurationsAPI.SSOConfigurations(
     this._client,
   );
@@ -165,49 +169,6 @@ export class Organizations extends APIResource {
     return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganization', { body, ...options });
   }
 
-  /**
-   * Lists all organizations the caller has access to with optional filtering.
-   *
-   * Use this method to:
-   *
-   * - View organizations you're a member of
-   * - Browse all available organizations
-   * - Paginate through organization results
-   *
-   * ### Examples
-   *
-   * - List member organizations:
-   *
-   *   Shows organizations where the caller is a member.
-   *
-   *   ```yaml
-   *   pagination:
-   *     pageSize: 20
-   *   scope: SCOPE_MEMBER
-   *   ```
-   *
-   * - List all organizations:
-   *
-   *   Shows all organizations visible to the caller.
-   *
-   *   ```yaml
-   *   pagination:
-   *     pageSize: 50
-   *   scope: SCOPE_ALL
-   *   ```
-   */
-  list(
-    params: OrganizationListParams,
-    options?: RequestOptions,
-  ): PagePromise<OrganizationsOrganizationsPage, Organization> {
-    const { token, pageSize, ...body } = params;
-    return this._client.getAPIList(
-      '/gitpod.v1.OrganizationService/ListOrganizations',
-      OrganizationsPage<Organization>,
-      { query: { token, pageSize }, body, method: 'post', ...options },
-    );
-  }
-
   /**
    * Permanently deletes an organization.
    *
@@ -370,8 +331,6 @@ export class Organizations extends APIResource {
   }
 }
 
-export type OrganizationsOrganizationsPage = OrganizationsPage<Organization>;
-
 export type OrganizationMembersMembersPage = MembersPage<OrganizationMember>;
 
 export interface InviteDomains {
@@ -478,6 +437,11 @@ export interface Organization {
 
   name: string;
 
+  /**
+   * The tier of the organization - free or enterprise
+   */
+  tier: OrganizationTier;
+
   /**
    * A Timestamp represents a point in time independent of any time zone or local
    * calendar, encoded as a count of seconds and fractions of seconds at nanosecond
@@ -684,7 +648,10 @@ export interface OrganizationMember {
   avatarUrl?: string;
 }
 
-export type Scope = 'SCOPE_UNSPECIFIED' | 'SCOPE_MEMBER' | 'SCOPE_ALL';
+export type OrganizationTier =
+  | 'ORGANIZATION_TIER_UNSPECIFIED'
+  | 'ORGANIZATION_TIER_FREE'
+  | 'ORGANIZATION_TIER_ENTERPRISE';
 
 export interface OrganizationCreateResponse {
   /**
@@ -769,37 +736,6 @@ export interface OrganizationUpdateParams {
   name?: string | null;
 }
 
-export interface OrganizationListParams extends OrganizationsPageParams {
-  /**
-   * Body param: pagination contains the pagination options for listing organizations
-   */
-  pagination?: OrganizationListParams.Pagination;
-
-  /**
-   * Body param: scope is the scope of the organizations to list
-   */
-  scope?: Scope;
-}
-
-export namespace OrganizationListParams {
-  /**
-   * pagination contains the pagination options for listing organizations
-   */
-  export interface Pagination {
-    /**
-     * Token for the next set of results that was returned as next_token of a
-     * PaginationResponse
-     */
-    token?: string;
-
-    /**
-     * Page size is the maximum number of results to retrieve per page. Defaults to 25.
-     * Maximum 100.
-     */
-    pageSize?: number;
-  }
-}
-
 export interface OrganizationDeleteParams {
   /**
    * organization_id is the ID of the organization to delete
@@ -864,6 +800,7 @@ export interface OrganizationSetRoleParams {
 
 Organizations.DomainVerifications = DomainVerifications;
 Organizations.Invites = Invites;
+Organizations.Policies = Policies;
 Organizations.SSOConfigurations = SSOConfigurations;
 
 export declare namespace Organizations {
@@ -871,7 +808,7 @@ export declare namespace Organizations {
     type InviteDomains as InviteDomains,
     type Organization as Organization,
     type OrganizationMember as OrganizationMember,
-    type Scope as Scope,
+    type OrganizationTier as OrganizationTier,
     type OrganizationCreateResponse as OrganizationCreateResponse,
     type OrganizationRetrieveResponse as OrganizationRetrieveResponse,
     type OrganizationUpdateResponse as OrganizationUpdateResponse,
@@ -879,12 +816,10 @@ export declare namespace Organizations {
     type OrganizationJoinResponse as OrganizationJoinResponse,
     type OrganizationLeaveResponse as OrganizationLeaveResponse,
     type OrganizationSetRoleResponse as OrganizationSetRoleResponse,
-    type OrganizationsOrganizationsPage as OrganizationsOrganizationsPage,
     type OrganizationMembersMembersPage as OrganizationMembersMembersPage,
     type OrganizationCreateParams as OrganizationCreateParams,
     type OrganizationRetrieveParams as OrganizationRetrieveParams,
     type OrganizationUpdateParams as OrganizationUpdateParams,
-    type OrganizationListParams as OrganizationListParams,
     type OrganizationDeleteParams as OrganizationDeleteParams,
     type OrganizationJoinParams as OrganizationJoinParams,
     type OrganizationLeaveParams as OrganizationLeaveParams,
@@ -919,6 +854,15 @@ export declare namespace Organizations {
     type InviteGetSummaryParams as InviteGetSummaryParams,
   };
 
+  export {
+    Policies as Policies,
+    type OrganizationPolicies as OrganizationPolicies,
+    type PolicyRetrieveResponse as PolicyRetrieveResponse,
+    type PolicyUpdateResponse as PolicyUpdateResponse,
+    type PolicyRetrieveParams as PolicyRetrieveParams,
+    type PolicyUpdateParams as PolicyUpdateParams,
+  };
+
   export {
     SSOConfigurations as SSOConfigurations,
     type ProviderType as ProviderType,
diff --git a/src/resources/organizations/policies.ts b/src/resources/organizations/policies.ts
new file mode 100644
index 0000000..468ef07
--- /dev/null
+++ b/src/resources/organizations/policies.ts
@@ -0,0 +1,217 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+
+export class Policies extends APIResource {
+  /**
+   * Gets organization policy settings by organization ID.
+   *
+   * Use this method to:
+   *
+   * - Retrieve current policy settings for an organization
+   * - View resource limits and restrictions
+   * - Check allowed editors and other configurations
+   *
+   * ### Examples
+   *
+   * - Get organization policies:
+   *
+   *   Retrieves policy settings for a specific organization.
+   *
+   *   ```yaml
+   *   organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047"
+   *   ```
+   */
+  retrieve(body: PolicyRetrieveParams, options?: RequestOptions): APIPromise<PolicyRetrieveResponse> {
+    return this._client.post('/gitpod.v1.OrganizationService/GetOrganizationPolicies', { body, ...options });
+  }
+
+  /**
+   * Updates organization policy settings.
+   *
+   * Use this method to:
+   *
+   * - Configure editor restrictions
+   * - Set environment resource limits
+   * - Define project creation permissions
+   * - Customize default configurations
+   *
+   * ### Examples
+   *
+   * - Update editor policies:
+   *
+   *   Restricts available editors and sets a default.
+   *
+   *   ```yaml
+   *   organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047"
+   *   allowedEditorIds:
+   *     - "vscode"
+   *     - "jetbrains"
+   *   defaultEditorId: "vscode"
+   *   ```
+   *
+   * - Set environment limits:
+   *
+   *   Configures limits for environment usage.
+   *
+   *   ```yaml
+   *   organizationId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047"
+   *   maximumEnvironmentTimeout: "3600s"
+   *   maximumRunningEnvironmentsPerUser: "5"
+   *   maximumEnvironmentsPerUser: "20"
+   *   ```
+   */
+  update(body: PolicyUpdateParams, options?: RequestOptions): APIPromise<unknown> {
+    return this._client.post('/gitpod.v1.OrganizationService/UpdateOrganizationPolicies', {
+      body,
+      ...options,
+    });
+  }
+}
+
+export interface OrganizationPolicies {
+  /**
+   * allowed_editor_ids is the list of editor IDs that are allowed to be used in the
+   * organization
+   */
+  allowedEditorIds: Array<string>;
+
+  /**
+   * allow_local_runners controls whether local runners are allowed to be used in the
+   * organization
+   */
+  allowLocalRunners: boolean;
+
+  /**
+   * default_editor_id is the default editor ID to be used when a user doesn't
+   * specify one
+   */
+  defaultEditorId: string;
+
+  /**
+   * default_environment_image is the default container image when none is defined in
+   * repo
+   */
+  defaultEnvironmentImage: string;
+
+  /**
+   * maximum_environments_per_user limits total environments (running or stopped) per
+   * user
+   */
+  maximumEnvironmentsPerUser: string;
+
+  /**
+   * maximum_running_environments_per_user limits simultaneously running environments
+   * per user
+   */
+  maximumRunningEnvironmentsPerUser: string;
+
+  /**
+   * members_create_projects controls whether members can create projects
+   */
+  membersCreateProjects: boolean;
+
+  /**
+   * members_require_projects controls whether environments can only be created from
+   * projects by non-admin users
+   */
+  membersRequireProjects: boolean;
+
+  /**
+   * organization_id is the ID of the organization
+   */
+  organizationId: string;
+
+  /**
+   * maximum_environment_timeout controls the maximum timeout allowed for
+   * environments in seconds. 0 means no limit (never). Minimum duration is 30
+   * minutes.
+   */
+  maximumEnvironmentTimeout?: string;
+}
+
+export interface PolicyRetrieveResponse {
+  policies: OrganizationPolicies;
+}
+
+export type PolicyUpdateResponse = unknown;
+
+export interface PolicyRetrieveParams {
+  /**
+   * organization_id is the ID of the organization to retrieve policies for
+   */
+  organizationId: string;
+}
+
+export interface PolicyUpdateParams {
+  /**
+   * organization_id is the ID of the organization to update policies for
+   */
+  organizationId: string;
+
+  /**
+   * allowed_editor_ids is the list of editor IDs that are allowed to be used in the
+   * organization
+   */
+  allowedEditorIds?: Array<string>;
+
+  /**
+   * allow_local_runners controls whether local runners are allowed to be used in the
+   * organization
+   */
+  allowLocalRunners?: boolean | null;
+
+  /**
+   * default_editor_id is the default editor ID to be used when a user doesn't
+   * specify one
+   */
+  defaultEditorId?: string | null;
+
+  /**
+   * default_environment_image is the default container image when none is defined in
+   * repo
+   */
+  defaultEnvironmentImage?: string | null;
+
+  /**
+   * maximum_environments_per_user limits total environments (running or stopped) per
+   * user
+   */
+  maximumEnvironmentsPerUser?: string | null;
+
+  /**
+   * maximum_environment_timeout controls the maximum timeout allowed for
+   * environments in seconds. 0 means no limit (never). Minimum duration is 30
+   * minutes.
+   */
+  maximumEnvironmentTimeout?: string | null;
+
+  /**
+   * maximum_running_environments_per_user limits simultaneously running environments
+   * per user
+   */
+  maximumRunningEnvironmentsPerUser?: string | null;
+
+  /**
+   * members_create_projects controls whether members can create projects
+   */
+  membersCreateProjects?: boolean | null;
+
+  /**
+   * members_require_projects controls whether environments can only be created from
+   * projects by non-admin users
+   */
+  membersRequireProjects?: boolean | null;
+}
+
+export declare namespace Policies {
+  export {
+    type OrganizationPolicies as OrganizationPolicies,
+    type PolicyRetrieveResponse as PolicyRetrieveResponse,
+    type PolicyUpdateResponse as PolicyUpdateResponse,
+    type PolicyRetrieveParams as PolicyRetrieveParams,
+    type PolicyUpdateParams as PolicyUpdateParams,
+  };
+}
diff --git a/src/resources/projects/projects.ts b/src/resources/projects/projects.ts
index 3f3967a..27f10b3 100644
--- a/src/resources/projects/projects.ts
+++ b/src/resources/projects/projects.ts
@@ -293,6 +293,12 @@ export interface Project {
 
   metadata?: ProjectMetadata;
 
+  /**
+   * technical_description is a detailed technical description of the project This
+   * field is not returned by default in GetProject or ListProjects responses
+   */
+  technicalDescription?: string;
+
   usedBy?: Project.UsedBy;
 }
 
@@ -572,6 +578,12 @@ export interface ProjectCreateParams {
   devcontainerFilePath?: string;
 
   name?: string;
+
+  /**
+   * technical_description is a detailed technical description of the project This
+   * field is not returned by default in GetProject or ListProjects responses 8KB max
+   */
+  technicalDescription?: string;
 }
 
 export interface ProjectRetrieveParams {
@@ -615,9 +627,20 @@ export interface ProjectUpdateParams {
    * project_id specifies the project identifier
    */
   projectId?: string;
+
+  /**
+   * technical_description is a detailed technical description of the project This
+   * field is not returned by default in GetProject or ListProjects responses 8KB max
+   */
+  technicalDescription?: string | null;
 }
 
 export interface ProjectListParams extends ProjectsPageParams {
+  /**
+   * Body param:
+   */
+  filter?: ProjectListParams.Filter;
+
   /**
    * Body param: pagination contains the pagination options for listing organizations
    */
@@ -625,6 +648,13 @@ export interface ProjectListParams extends ProjectsPageParams {
 }
 
 export namespace ProjectListParams {
+  export interface Filter {
+    /**
+     * project_ids filters the response to only projects with these IDs
+     */
+    projectIds?: Array<string>;
+  }
+
   /**
    * pagination contains the pagination options for listing organizations
    */
diff --git a/src/resources/runners/configurations/schema.ts b/src/resources/runners/configurations/schema.ts
index a7885dd..cd1222c 100644
--- a/src/resources/runners/configurations/schema.ts
+++ b/src/resources/runners/configurations/schema.ts
@@ -78,11 +78,39 @@ export namespace RunnerConfigurationSchema {
     }
 
     export interface Enum {
+      /**
+       * @deprecated deprecated, will be removed, use default_value instead
+       */
       default?: string;
 
+      defaultValue?: Enum.DefaultValue;
+
+      possibleValues?: Array<Enum.PossibleValue>;
+
+      /**
+       * @deprecated deprecated, will be removed, use possible_values instead
+       */
       values?: Array<string>;
     }
 
+    export namespace Enum {
+      export interface DefaultValue {
+        detail?: string;
+
+        subtitle?: string;
+
+        title?: string;
+      }
+
+      export interface PossibleValue {
+        detail?: string;
+
+        subtitle?: string;
+
+        title?: string;
+      }
+    }
+
     export interface Int {
       default?: number;
 
@@ -130,11 +158,39 @@ export namespace RunnerConfigurationSchema {
     }
 
     export interface Enum {
+      /**
+       * @deprecated deprecated, will be removed, use default_value instead
+       */
       default?: string;
 
+      defaultValue?: Enum.DefaultValue;
+
+      possibleValues?: Array<Enum.PossibleValue>;
+
+      /**
+       * @deprecated deprecated, will be removed, use possible_values instead
+       */
       values?: Array<string>;
     }
 
+    export namespace Enum {
+      export interface DefaultValue {
+        detail?: string;
+
+        subtitle?: string;
+
+        title?: string;
+      }
+
+      export interface PossibleValue {
+        detail?: string;
+
+        subtitle?: string;
+
+        title?: string;
+      }
+    }
+
     export interface Int {
       default?: number;
 
diff --git a/src/resources/runners/index.ts b/src/resources/runners/index.ts
index 4534266..0f5a99a 100644
--- a/src/resources/runners/index.ts
+++ b/src/resources/runners/index.ts
@@ -23,6 +23,8 @@ export {
 } from './policies';
 export {
   Runners,
+  type LogLevel,
+  type MetricsConfiguration,
   type Runner,
   type RunnerCapability,
   type RunnerConfiguration,
diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts
index 0925d50..223f884 100644
--- a/src/resources/runners/runners.ts
+++ b/src/resources/runners/runners.ts
@@ -288,6 +288,35 @@ export class Runners extends APIResource {
 
 export type RunnersRunnersPage = RunnersPage<Runner>;
 
+export type LogLevel =
+  | 'LOG_LEVEL_UNSPECIFIED'
+  | 'LOG_LEVEL_DEBUG'
+  | 'LOG_LEVEL_INFO'
+  | 'LOG_LEVEL_WARN'
+  | 'LOG_LEVEL_ERROR';
+
+export interface MetricsConfiguration {
+  /**
+   * enabled indicates whether the runner should collect metrics
+   */
+  enabled?: boolean;
+
+  /**
+   * password is the password to use for the metrics collector
+   */
+  password?: string;
+
+  /**
+   * url is the URL of the metrics collector
+   */
+  url?: string;
+
+  /**
+   * username is the username to use for the metrics collector
+   */
+  username?: string;
+}
+
 export interface Runner {
   /**
    * Time when the Runner was created.
@@ -335,7 +364,10 @@ export interface Runner {
 export type RunnerCapability =
   | 'RUNNER_CAPABILITY_UNSPECIFIED'
   | 'RUNNER_CAPABILITY_FETCH_LOCAL_SCM_INTEGRATIONS'
-  | 'RUNNER_CAPABILITY_SECRET_CONTAINER_REGISTRY';
+  | 'RUNNER_CAPABILITY_SECRET_CONTAINER_REGISTRY'
+  | 'RUNNER_CAPABILITY_AGENT_EXECUTION'
+  | 'RUNNER_CAPABILITY_ALLOW_ENV_TOKEN_POPULATION'
+  | 'RUNNER_CAPABILITY_DEFAULT_DEV_CONTAINER_IMAGE';
 
 export interface RunnerConfiguration {
   /**
@@ -343,6 +375,16 @@ export interface RunnerConfiguration {
    */
   autoUpdate?: boolean;
 
+  /**
+   * log_level is the log level for the runner
+   */
+  logLevel?: LogLevel;
+
+  /**
+   * metrics contains configuration for the runner's metrics collection
+   */
+  metrics?: MetricsConfiguration;
+
   /**
    * Region to deploy the runner in, if applicable. This is mainly used for remote
    * runners, and is only a hint. The runner may be deployed in a different region.
@@ -570,6 +612,11 @@ export interface RunnerParseContextURLResponse {
   git?: RunnerParseContextURLResponse.Git;
 
   originalContextUrl?: string;
+
+  /**
+   * project_ids is a list of projects to which the context URL belongs to.
+   */
+  projectIds?: Array<string>;
 }
 
 export namespace RunnerParseContextURLResponse {
@@ -658,11 +705,48 @@ export namespace RunnerUpdateParams {
        */
       autoUpdate?: boolean | null;
 
+      /**
+       * log_level is the log level for the runner
+       */
+      logLevel?: RunnersAPI.LogLevel | null;
+
+      /**
+       * metrics contains configuration for the runner's metrics collection
+       */
+      metrics?: Configuration.Metrics | null;
+
       /**
        * The release channel the runner is on
        */
       releaseChannel?: RunnersAPI.RunnerReleaseChannel | null;
     }
+
+    export namespace Configuration {
+      /**
+       * metrics contains configuration for the runner's metrics collection
+       */
+      export interface Metrics {
+        /**
+         * enabled indicates whether the runner should collect metrics
+         */
+        enabled?: boolean | null;
+
+        /**
+         * password is the password to use for the metrics collector
+         */
+        password?: string | null;
+
+        /**
+         * url is the URL of the metrics collector
+         */
+        url?: string | null;
+
+        /**
+         * username is the username to use for the metrics collector
+         */
+        username?: string | null;
+      }
+    }
   }
 }
 
@@ -747,6 +831,8 @@ Runners.Policies = Policies;
 
 export declare namespace Runners {
   export {
+    type LogLevel as LogLevel,
+    type MetricsConfiguration as MetricsConfiguration,
     type Runner as Runner,
     type RunnerCapability as RunnerCapability,
     type RunnerConfiguration as RunnerConfiguration,
diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts
index 62ceb78..f6a9e38 100644
--- a/src/resources/secrets.ts
+++ b/src/resources/secrets.ts
@@ -1,6 +1,7 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
 import { APIResource } from '../core/resource';
+import * as SecretsAPI from './secrets';
 import * as Shared from './shared';
 import { APIPromise } from '../core/api-promise';
 import { PagePromise, SecretsPage, type SecretsPageParams } from '../core/pagination';
@@ -57,25 +58,7 @@ export class Secrets extends APIResource {
   }
 
   /**
-   * Lists secrets with optional filtering.
-   *
-   * Use this method to:
-   *
-   * - View all project secrets
-   * - Filter secrets by project
-   *
-   * ### Examples
-   *
-   * - List project secrets:
-   *
-   *   Shows all secrets for a project.
-   *
-   *   ```yaml
-   *   filter:
-   *     projectIds: ["b0e12f6c-4c67-429d-a4a6-d9838b5da047"]
-   *   pagination:
-   *     pageSize: 20
-   *   ```
+   * ListSecrets
    */
   list(params: SecretListParams, options?: RequestOptions): PagePromise<SecretsSecretsPage, Secret> {
     const { token, pageSize, ...body } = params;
@@ -280,10 +263,12 @@ export interface Secret {
   name?: string;
 
   /**
-   * The Project ID this Secret belongs to
+   * @deprecated The Project ID this Secret belongs to Deprecated: use scope instead
    */
   projectId?: string;
 
+  scope?: SecretScope;
+
   /**
    * A Timestamp represents a point in time independent of any time zone or local
    * calendar, encoded as a count of seconds and fractions of seconds at nanosecond
@@ -377,6 +362,18 @@ export interface Secret {
   updatedAt?: string;
 }
 
+export interface SecretScope {
+  /**
+   * project_id is the Project ID this Secret belongs to
+   */
+  projectId?: string;
+
+  /**
+   * user_id is the User ID this Secret belongs to
+   */
+  userId?: string;
+}
+
 export interface SecretCreateResponse {
   secret?: Secret;
 }
@@ -392,12 +389,7 @@ export type SecretUpdateValueResponse = unknown;
 export interface SecretCreateParams {
   /**
    * secret will be mounted as a docker config in the environment VM, mount will have
-   * the docker registry host value must be a valid registry host (e.g.
-   * registry.docker.com, https://registry.docker.com, ghcr.io:5050):
-   *
-   * ```
-   * this.matches('^[a-zA-Z0-9.-/:]+(:[0-9]+)?$')
-   * ```
+   * the docker registry host
    */
   containerRegistryBasicAuthHost?: string;
 
@@ -420,10 +412,16 @@ export interface SecretCreateParams {
   name?: string;
 
   /**
-   * project_id is the ProjectID this Secret belongs to
+   * @deprecated project_id is the ProjectID this Secret belongs to Deprecated: use
+   * scope instead
    */
   projectId?: string;
 
+  /**
+   * scope is the scope of the secret
+   */
+  scope?: SecretScope;
+
   /**
    * value is the plaintext value of the secret
    */
@@ -445,9 +443,16 @@ export interface SecretListParams extends SecretsPageParams {
 export namespace SecretListParams {
   export interface Filter {
     /**
-     * project_ids filters the response to only Secrets used by these Project IDs
+     * @deprecated project_ids filters the response to only Secrets used by these
+     * Project IDs Deprecated: use scope instead. Values in project_ids will be
+     * ignored.
      */
     projectIds?: Array<string>;
+
+    /**
+     * scope is the scope of the secrets to list
+     */
+    scope?: SecretsAPI.SecretScope;
   }
 
   /**
@@ -488,6 +493,7 @@ export interface SecretUpdateValueParams {
 export declare namespace Secrets {
   export {
     type Secret as Secret,
+    type SecretScope as SecretScope,
     type SecretCreateResponse as SecretCreateResponse,
     type SecretDeleteResponse as SecretDeleteResponse,
     type SecretGetValueResponse as SecretGetValueResponse,
diff --git a/src/resources/shared.ts b/src/resources/shared.ts
index b771f1d..d2f7c17 100644
--- a/src/resources/shared.ts
+++ b/src/resources/shared.ts
@@ -280,6 +280,12 @@ export namespace TaskExecutionStatus {
      */
     failureMessage?: string;
 
+    /**
+     * output contains the output of the task execution. setting an output field to
+     * empty string will unset it.
+     */
+    output?: Record<string, string>;
+
     /**
      * phase is the current phase of the execution step
      */
diff --git a/src/resources/users/dotfiles.ts b/src/resources/users/dotfiles.ts
new file mode 100644
index 0000000..7a69609
--- /dev/null
+++ b/src/resources/users/dotfiles.ts
@@ -0,0 +1,89 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../../core/resource';
+import { APIPromise } from '../../core/api-promise';
+import { RequestOptions } from '../../internal/request-options';
+
+export class Dotfiles extends APIResource {
+  /**
+   * Gets the dotfiles for a user.
+   *
+   * Use this method to:
+   *
+   * - Retrieve user dotfiles
+   *
+   * ### Examples
+   *
+   * - Get dotfiles:
+   *
+   *   Retrieves the dotfiles for the current user.
+   *
+   *   ```yaml
+   *   {}
+   *   ```
+   */
+  get(body: DotfileGetParams, options?: RequestOptions): APIPromise<DotfileGetResponse> {
+    return this._client.post('/gitpod.v1.UserService/GetDotfilesConfiguration', { body, ...options });
+  }
+
+  /**
+   * Sets the dotfiles configuration for a user.
+   *
+   * Use this method to:
+   *
+   * - Configure user dotfiles
+   * - Update dotfiles settings
+   *
+   * ### Examples
+   *
+   * - Set dotfiles configuration:
+   *
+   *   Sets the dotfiles configuration for the current user.
+   *
+   *   ```yaml
+   *   { "repository": "https://github.com/gitpod-io/dotfiles" }
+   *   ```
+   *
+   * - Remove dotfiles:
+   *
+   *   Removes the dotfiles for the current user.
+   *
+   *   ```yaml
+   *   {}
+   *   ```
+   */
+  set(body: DotfileSetParams, options?: RequestOptions): APIPromise<unknown> {
+    return this._client.post('/gitpod.v1.UserService/SetDotfilesConfiguration', { body, ...options });
+  }
+}
+
+export interface DotfilesConfiguration {
+  /**
+   * The URL of a dotfiles repository.
+   */
+  repository?: string;
+}
+
+export interface DotfileGetResponse {
+  dotfilesConfiguration: DotfilesConfiguration;
+}
+
+export type DotfileSetResponse = unknown;
+
+export interface DotfileGetParams {
+  empty?: boolean;
+}
+
+export interface DotfileSetParams {
+  repository?: string;
+}
+
+export declare namespace Dotfiles {
+  export {
+    type DotfilesConfiguration as DotfilesConfiguration,
+    type DotfileGetResponse as DotfileGetResponse,
+    type DotfileSetResponse as DotfileSetResponse,
+    type DotfileGetParams as DotfileGetParams,
+    type DotfileSetParams as DotfileSetParams,
+  };
+}
diff --git a/src/resources/users/index.ts b/src/resources/users/index.ts
index 159e1d4..c91cbf0 100644
--- a/src/resources/users/index.ts
+++ b/src/resources/users/index.ts
@@ -1,5 +1,13 @@
 // File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
 
+export {
+  Dotfiles,
+  type DotfilesConfiguration,
+  type DotfileGetResponse,
+  type DotfileSetResponse,
+  type DotfileGetParams,
+  type DotfileSetParams,
+} from './dotfiles';
 export {
   Pats,
   type PersonalAccessToken,
diff --git a/src/resources/users/users.ts b/src/resources/users/users.ts
index 4fb4bad..07f8eca 100644
--- a/src/resources/users/users.ts
+++ b/src/resources/users/users.ts
@@ -2,6 +2,15 @@
 
 import { APIResource } from '../../core/resource';
 import * as Shared from '../shared';
+import * as DotfilesAPI from './dotfiles';
+import {
+  DotfileGetParams,
+  DotfileGetResponse,
+  DotfileSetParams,
+  DotfileSetResponse,
+  Dotfiles,
+  DotfilesConfiguration,
+} from './dotfiles';
 import * as PatsAPI from './pats';
 import {
   PatDeleteParams,
@@ -17,6 +26,7 @@ import { APIPromise } from '../../core/api-promise';
 import { RequestOptions } from '../../internal/request-options';
 
 export class Users extends APIResource {
+  dotfiles: DotfilesAPI.Dotfiles = new DotfilesAPI.Dotfiles(this._client);
   pats: PatsAPI.Pats = new PatsAPI.Pats(this._client);
 
   /**
@@ -130,6 +140,7 @@ export interface UserSetSuspendedParams {
   userId?: string;
 }
 
+Users.Dotfiles = Dotfiles;
 Users.Pats = Pats;
 
 export declare namespace Users {
@@ -141,6 +152,15 @@ export declare namespace Users {
     type UserSetSuspendedParams as UserSetSuspendedParams,
   };
 
+  export {
+    Dotfiles as Dotfiles,
+    type DotfilesConfiguration as DotfilesConfiguration,
+    type DotfileGetResponse as DotfileGetResponse,
+    type DotfileSetResponse as DotfileSetResponse,
+    type DotfileGetParams as DotfileGetParams,
+    type DotfileSetParams as DotfileSetParams,
+  };
+
   export {
     Pats as Pats,
     type PersonalAccessToken as PersonalAccessToken,
diff --git a/tests/api-resources/environments/environments.test.ts b/tests/api-resources/environments/environments.test.ts
index 22b33f8..aaf1efc 100644
--- a/tests/api-resources/environments/environments.test.ts
+++ b/tests/api-resources/environments/environments.test.ts
@@ -77,6 +77,27 @@ describe('resource environments', () => {
     expect(dataAndResponse.response).toBe(rawResponse);
   });
 
+  // skipped: tests are disabled for the time being
+  test.skip('createEnvironmentToken: only required params', async () => {
+    const responsePromise = client.environments.createEnvironmentToken({
+      environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048',
+    });
+    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);
+  });
+
+  // skipped: tests are disabled for the time being
+  test.skip('createEnvironmentToken: required and optional params', async () => {
+    const response = await client.environments.createEnvironmentToken({
+      environmentId: '07e03a28-65a5-4d98-b532-8ea67b188048',
+    });
+  });
+
   // skipped: tests are disabled for the time being
   test.skip('createFromProject', async () => {
     const responsePromise = client.environments.createFromProject({});
diff --git a/tests/api-resources/organizations/organizations.test.ts b/tests/api-resources/organizations/organizations.test.ts
index 16be6a5..09fc8b7 100644
--- a/tests/api-resources/organizations/organizations.test.ts
+++ b/tests/api-resources/organizations/organizations.test.ts
@@ -73,18 +73,6 @@ describe('resource organizations', () => {
     });
   });
 
-  // skipped: tests are disabled for the time being
-  test.skip('list', async () => {
-    const responsePromise = client.organizations.list({});
-    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);
-  });
-
   // skipped: tests are disabled for the time being
   test.skip('delete: only required params', async () => {
     const responsePromise = client.organizations.delete({
diff --git a/tests/api-resources/organizations/policies.test.ts b/tests/api-resources/organizations/policies.test.ts
new file mode 100644
index 0000000..a0aba22
--- /dev/null
+++ b/tests/api-resources/organizations/policies.test.ts
@@ -0,0 +1,61 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Gitpod from '@gitpod/sdk';
+
+const client = new Gitpod({
+  bearerToken: 'My Bearer Token',
+  baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource policies', () => {
+  // skipped: tests are disabled for the time being
+  test.skip('retrieve: only required params', async () => {
+    const responsePromise = client.organizations.policies.retrieve({
+      organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
+    });
+    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);
+  });
+
+  // skipped: tests are disabled for the time being
+  test.skip('retrieve: required and optional params', async () => {
+    const response = await client.organizations.policies.retrieve({
+      organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
+    });
+  });
+
+  // skipped: tests are disabled for the time being
+  test.skip('update: only required params', async () => {
+    const responsePromise = client.organizations.policies.update({
+      organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
+    });
+    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);
+  });
+
+  // skipped: tests are disabled for the time being
+  test.skip('update: required and optional params', async () => {
+    const response = await client.organizations.policies.update({
+      organizationId: 'b0e12f6c-4c67-429d-a4a6-d9838b5da047',
+      allowedEditorIds: ['string'],
+      allowLocalRunners: true,
+      defaultEditorId: 'defaultEditorId',
+      defaultEnvironmentImage: 'defaultEnvironmentImage',
+      maximumEnvironmentsPerUser: '20',
+      maximumEnvironmentTimeout: '3600s',
+      maximumRunningEnvironmentsPerUser: '5',
+      membersCreateProjects: true,
+      membersRequireProjects: true,
+    });
+  });
+});
diff --git a/tests/api-resources/projects/projects.test.ts b/tests/api-resources/projects/projects.test.ts
index 1ad8e40..b30ee89 100644
--- a/tests/api-resources/projects/projects.test.ts
+++ b/tests/api-resources/projects/projects.test.ts
@@ -41,6 +41,7 @@ describe('resource projects', () => {
       automationsFilePath: 'automationsFilePath',
       devcontainerFilePath: 'devcontainerFilePath',
       name: 'Web Application',
+      technicalDescription: 'technicalDescription',
     });
   });
 
diff --git a/tests/api-resources/users/dotfiles.test.ts b/tests/api-resources/users/dotfiles.test.ts
new file mode 100644
index 0000000..5694cb1
--- /dev/null
+++ b/tests/api-resources/users/dotfiles.test.ts
@@ -0,0 +1,34 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Gitpod from '@gitpod/sdk';
+
+const client = new Gitpod({
+  bearerToken: 'My Bearer Token',
+  baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource dotfiles', () => {
+  // skipped: tests are disabled for the time being
+  test.skip('get', async () => {
+    const responsePromise = client.users.dotfiles.get({});
+    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);
+  });
+
+  // skipped: tests are disabled for the time being
+  test.skip('set', async () => {
+    const responsePromise = client.users.dotfiles.set({});
+    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);
+  });
+});

From f0edc9696d24e0a4e4ed648b585883616cde251f Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 09:52:40 +0000
Subject: [PATCH 42/44] feat(api): manual updates

---
 .stats.yml                        |   4 +-
 api.md                            |  10 +++
 src/client.ts                     |  20 +++++
 src/core/pagination.ts            |  55 ++++++++++++
 src/resources/index.ts            |   6 ++
 src/resources/usage.ts            | 140 ++++++++++++++++++++++++++++++
 tests/api-resources/usage.test.ts |  22 +++++
 7 files changed, 255 insertions(+), 2 deletions(-)
 create mode 100644 src/resources/usage.ts
 create mode 100644 tests/api-resources/usage.test.ts

diff --git a/.stats.yml b/.stats.yml
index ef4c630..5233e38 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 115
+configured_endpoints: 116
 openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml
 openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d
-config_hash: 981e43e8b1e3ddabd435d350aeeed417
+config_hash: 60929489bdc1eaf979e7ef74fdd17b94
diff --git a/api.md b/api.md
index 82689ae..516cda9 100644
--- a/api.md
+++ b/api.md
@@ -484,6 +484,16 @@ Methods:
 - <code title="post /gitpod.v1.SecretService/GetSecretValue">client.secrets.<a href="./src/resources/secrets.ts">getValue</a>({ ...params }) -> SecretGetValueResponse</code>
 - <code title="post /gitpod.v1.SecretService/UpdateSecretValue">client.secrets.<a href="./src/resources/secrets.ts">updateValue</a>({ ...params }) -> unknown</code>
 
+# Usage
+
+Types:
+
+- <code><a href="./src/resources/usage.ts">EnvironmentSession</a></code>
+
+Methods:
+
+- <code title="post /gitpod.v1.UsageService/ListEnvironmentSessions">client.usage.<a href="./src/resources/usage.ts">listEnvironmentSessions</a>({ ...params }) -> EnvironmentSessionsSessionsPage</code>
+
 # Users
 
 Types:
diff --git a/src/client.ts b/src/client.ts
index e9880cc..d7e3523 100644
--- a/src/client.ts
+++ b/src/client.ts
@@ -49,6 +49,8 @@ import {
   SecretsPageResponse,
   type ServicesPageParams,
   ServicesPageResponse,
+  type SessionsPageParams,
+  SessionsPageResponse,
   type TaskExecutionsPageParams,
   TaskExecutionsPageResponse,
   type TasksPageParams,
@@ -123,6 +125,12 @@ import {
   Secrets,
   SecretsSecretsPage,
 } from './resources/secrets';
+import {
+  EnvironmentSession,
+  EnvironmentSessionsSessionsPage,
+  Usage,
+  UsageListEnvironmentSessionsParams,
+} from './resources/usage';
 import { readEnv } from './internal/utils/env';
 import { formatRequestDetails, loggerFor } from './internal/utils/log';
 import { isEmptyObj } from './internal/utils/values';
@@ -917,6 +925,7 @@ export class Gitpod {
   projects: API.Projects = new API.Projects(this);
   runners: API.Runners = new API.Runners(this);
   secrets: API.Secrets = new API.Secrets(this);
+  usage: API.Usage = new API.Usage(this);
   users: API.Users = new API.Users(this);
 }
 Gitpod.Accounts = Accounts;
@@ -929,6 +938,7 @@ Gitpod.Organizations = Organizations;
 Gitpod.Projects = Projects;
 Gitpod.Runners = Runners;
 Gitpod.Secrets = Secrets;
+Gitpod.Usage = Usage;
 Gitpod.Users = Users;
 export declare namespace Gitpod {
   export type RequestOptions = Opts.RequestOptions;
@@ -996,6 +1006,9 @@ export declare namespace Gitpod {
   export import ServicesPage = Pagination.ServicesPage;
   export { type ServicesPageParams as ServicesPageParams, type ServicesPageResponse as ServicesPageResponse };
 
+  export import SessionsPage = Pagination.SessionsPage;
+  export { type SessionsPageParams as SessionsPageParams, type SessionsPageResponse as SessionsPageResponse };
+
   export import SSOConfigurationsPage = Pagination.SSOConfigurationsPage;
   export {
     type SSOConfigurationsPageParams as SSOConfigurationsPageParams,
@@ -1194,6 +1207,13 @@ export declare namespace Gitpod {
     type SecretUpdateValueParams as SecretUpdateValueParams,
   };
 
+  export {
+    Usage as Usage,
+    type EnvironmentSession as EnvironmentSession,
+    type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage,
+    type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams,
+  };
+
   export {
     Users as Users,
     type User as User,
diff --git a/src/core/pagination.ts b/src/core/pagination.ts
index 250b4fc..f72f6ff 100644
--- a/src/core/pagination.ts
+++ b/src/core/pagination.ts
@@ -941,6 +941,61 @@ export class ServicesPage<Item> extends AbstractPage<Item> implements ServicesPa
   }
 }
 
+export interface SessionsPageResponse<Item> {
+  pagination: SessionsPageResponse.Pagination;
+
+  sessions: Array<Item>;
+}
+
+export namespace SessionsPageResponse {
+  export interface Pagination {
+    nextToken?: string;
+  }
+}
+
+export interface SessionsPageParams {
+  pageSize?: number;
+
+  token?: string;
+}
+
+export class SessionsPage<Item> extends AbstractPage<Item> implements SessionsPageResponse<Item> {
+  pagination: SessionsPageResponse.Pagination;
+
+  sessions: Array<Item>;
+
+  constructor(
+    client: Gitpod,
+    response: Response,
+    body: SessionsPageResponse<Item>,
+    options: FinalRequestOptions,
+  ) {
+    super(client, response, body, options);
+
+    this.pagination = body.pagination || {};
+    this.sessions = body.sessions || [];
+  }
+
+  getPaginatedItems(): Item[] {
+    return this.sessions ?? [];
+  }
+
+  nextPageRequestOptions(): PageRequestOptions | null {
+    const cursor = this.pagination?.nextToken;
+    if (!cursor) {
+      return null;
+    }
+
+    return {
+      ...this.options,
+      query: {
+        ...maybeObj(this.options.query),
+        token: cursor,
+      },
+    };
+  }
+}
+
 export interface SSOConfigurationsPageResponse<Item> {
   pagination: SSOConfigurationsPageResponse.Pagination;
 
diff --git a/src/resources/index.ts b/src/resources/index.ts
index be1edca..664e230 100644
--- a/src/resources/index.ts
+++ b/src/resources/index.ts
@@ -166,6 +166,12 @@ export {
   type SecretUpdateValueParams,
   type SecretsSecretsPage,
 } from './secrets';
+export {
+  Usage,
+  type EnvironmentSession,
+  type UsageListEnvironmentSessionsParams,
+  type EnvironmentSessionsSessionsPage,
+} from './usage';
 export {
   Users,
   type User,
diff --git a/src/resources/usage.ts b/src/resources/usage.ts
new file mode 100644
index 0000000..c648e2c
--- /dev/null
+++ b/src/resources/usage.ts
@@ -0,0 +1,140 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import { APIResource } from '../core/resource';
+import { PagePromise, SessionsPage, type SessionsPageParams } from '../core/pagination';
+import { RequestOptions } from '../internal/request-options';
+
+export class Usage extends APIResource {
+  /**
+   * Lists environment sessions within a specified date range.
+   *
+   * Returns a list of environment sessions that were active within the specified
+   * date range.
+   */
+  listEnvironmentSessions(
+    params: UsageListEnvironmentSessionsParams,
+    options?: RequestOptions,
+  ): PagePromise<EnvironmentSessionsSessionsPage, EnvironmentSession> {
+    const { token, pageSize, ...body } = params;
+    return this._client.getAPIList(
+      '/gitpod.v1.UsageService/ListEnvironmentSessions',
+      SessionsPage<EnvironmentSession>,
+      { query: { token, pageSize }, body, method: 'post', ...options },
+    );
+  }
+}
+
+export type EnvironmentSessionsSessionsPage = SessionsPage<EnvironmentSession>;
+
+export interface EnvironmentSession {
+  /**
+   * Environment session ID.
+   */
+  id?: string;
+
+  /**
+   * Time when the session was created.
+   */
+  createdAt?: string;
+
+  /**
+   * Environment class ID associated with the session.
+   */
+  environmentClassId?: string;
+
+  /**
+   * Environment ID associated with the session.
+   */
+  environmentId?: string;
+
+  /**
+   * Project ID associated with the session.
+   */
+  projectId?: string;
+
+  /**
+   * Runner ID associated with the session.
+   */
+  runnerId?: string;
+
+  /**
+   * Time when the session was stopped.
+   */
+  stoppedAt?: string;
+
+  /**
+   * User ID who created the session.
+   */
+  userId?: string;
+}
+
+export interface UsageListEnvironmentSessionsParams extends SessionsPageParams {
+  /**
+   * Body param: Filter options.
+   */
+  filter?: UsageListEnvironmentSessionsParams.Filter;
+
+  /**
+   * Body param: Pagination options.
+   */
+  pagination?: UsageListEnvironmentSessionsParams.Pagination;
+}
+
+export namespace UsageListEnvironmentSessionsParams {
+  /**
+   * Filter options.
+   */
+  export interface Filter {
+    /**
+     * Date range to query sessions within.
+     */
+    dateRange: Filter.DateRange;
+
+    /**
+     * Optional project ID to filter sessions by.
+     */
+    projectId?: string;
+  }
+
+  export namespace Filter {
+    /**
+     * Date range to query sessions within.
+     */
+    export interface DateRange {
+      /**
+       * End time of the date range (exclusive).
+       */
+      endTime: string;
+
+      /**
+       * Start time of the date range (inclusive).
+       */
+      startTime: string;
+    }
+  }
+
+  /**
+   * Pagination options.
+   */
+  export interface Pagination {
+    /**
+     * Token for the next set of results that was returned as next_token of a
+     * PaginationResponse
+     */
+    token?: string;
+
+    /**
+     * Page size is the maximum number of results to retrieve per page. Defaults to 25.
+     * Maximum 100.
+     */
+    pageSize?: number;
+  }
+}
+
+export declare namespace Usage {
+  export {
+    type EnvironmentSession as EnvironmentSession,
+    type EnvironmentSessionsSessionsPage as EnvironmentSessionsSessionsPage,
+    type UsageListEnvironmentSessionsParams as UsageListEnvironmentSessionsParams,
+  };
+}
diff --git a/tests/api-resources/usage.test.ts b/tests/api-resources/usage.test.ts
new file mode 100644
index 0000000..1d2b3dc
--- /dev/null
+++ b/tests/api-resources/usage.test.ts
@@ -0,0 +1,22 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Gitpod from '@gitpod/sdk';
+
+const client = new Gitpod({
+  bearerToken: 'My Bearer Token',
+  baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource usage', () => {
+  // skipped: tests are disabled for the time being
+  test.skip('listEnvironmentSessions', async () => {
+    const responsePromise = client.usage.listEnvironmentSessions({});
+    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);
+  });
+});

From 77b6f44b695808f66ce955683f86965c3b8605fb Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 10:19:57 +0000
Subject: [PATCH 43/44] feat(api): manual updates

---
 .stats.yml                       |  4 ++--
 src/resources/runners/runners.ts | 13 +++++++++++++
 src/resources/secrets.ts         | 33 +++++++++++++++++++++++++++++++-
 src/resources/usage.ts           | 29 +++++++++++++++++++++++-----
 4 files changed, 71 insertions(+), 8 deletions(-)

diff --git a/.stats.yml b/.stats.yml
index 5233e38..9cdc117 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
 configured_endpoints: 116
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-d854bc81e0a99171716893e6790a87ba350bb6fc778f8e3244abdd47d5c252c3.yml
-openapi_spec_hash: 5189220e4712a7b0cdd35beba2ebb47d
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/gitpod%2Fgitpod-2e6ddfc9da00e33fcf13baf0b67012b97f051fa986658ff114fde989e56caa94.yml
+openapi_spec_hash: 5af02ea2008312d609394e548756e761
 config_hash: 60929489bdc1eaf979e7ef74fdd17b94
diff --git a/src/resources/runners/runners.ts b/src/resources/runners/runners.ts
index 223f884..5abb6dd 100644
--- a/src/resources/runners/runners.ts
+++ b/src/resources/runners/runners.ts
@@ -375,6 +375,13 @@ export interface RunnerConfiguration {
    */
   autoUpdate?: boolean;
 
+  /**
+   * devcontainer_image_cache_enabled controls whether the devcontainer build cache
+   * is enabled for this runner. Only takes effect on supported runners, currently
+   * only AWS EC2 runners.
+   */
+  devcontainerImageCacheEnabled?: boolean;
+
   /**
    * log_level is the log level for the runner
    */
@@ -705,6 +712,12 @@ export namespace RunnerUpdateParams {
        */
       autoUpdate?: boolean | null;
 
+      /**
+       * devcontainer_image_cache_enabled controls whether the shared devcontainer build
+       * cache is enabled for this runner.
+       */
+      devcontainerImageCacheEnabled?: boolean | null;
+
       /**
        * log_level is the log level for the runner
        */
diff --git a/src/resources/secrets.ts b/src/resources/secrets.ts
index f6a9e38..68c387d 100644
--- a/src/resources/secrets.ts
+++ b/src/resources/secrets.ts
@@ -58,7 +58,38 @@ export class Secrets extends APIResource {
   }
 
   /**
-   * ListSecrets
+   * Lists secrets
+   *
+   * Use this method to:
+   *
+   * - View all project secrets
+   * - View all user secrets
+   *
+   * ### Examples
+   *
+   * - List project secrets:
+   *
+   *   Shows all secrets for a project.
+   *
+   *   ```yaml
+   *   filter:
+   *     scope:
+   *       projectId: "b0e12f6c-4c67-429d-a4a6-d9838b5da047"
+   *   pagination:
+   *     pageSize: 20
+   *   ```
+   *
+   * - List user secrets:
+   *
+   *   Shows all secrets for a user.
+   *
+   *   ```yaml
+   *   filter:
+   *     scope:
+   *       userId: "123e4567-e89b-12d3-a456-426614174000"
+   *   pagination:
+   *     pageSize: 20
+   *   ```
    */
   list(params: SecretListParams, options?: RequestOptions): PagePromise<SecretsSecretsPage, Secret> {
     const { token, pageSize, ...body } = params;
diff --git a/src/resources/usage.ts b/src/resources/usage.ts
index c648e2c..9417a8f 100644
--- a/src/resources/usage.ts
+++ b/src/resources/usage.ts
@@ -6,10 +6,29 @@ import { RequestOptions } from '../internal/request-options';
 
 export class Usage extends APIResource {
   /**
-   * Lists environment sessions within a specified date range.
+   * Lists completed environment sessions within a specified date range.
    *
-   * Returns a list of environment sessions that were active within the specified
-   * date range.
+   * Returns a list of environment sessions that were completed within the specified
+   * date range. Currently running sessions are not included.
+   *
+   * Use this method to:
+   *
+   * - View environment sessions
+   * - Filter by project
+   * - Monitor session activity
+   * - Create custom usage reports
+   *
+   * ### Example
+   *
+   * ```yaml
+   * filter:
+   *   projectId: "d2c94c27-3b76-4a42-b88c-95a85e392c68"
+   *   dateRange:
+   *     startTime: "2024-01-01T00:00:00Z"
+   *     endTime: "2024-01-02T00:00:00Z"
+   * pagination:
+   *   pageSize: 100
+   * ```
    */
   listEnvironmentSessions(
     params: UsageListEnvironmentSessionsParams,
@@ -48,7 +67,7 @@ export interface EnvironmentSession {
   environmentId?: string;
 
   /**
-   * Project ID associated with the session.
+   * Project ID associated with the session (if available).
    */
   projectId?: string;
 
@@ -63,7 +82,7 @@ export interface EnvironmentSession {
   stoppedAt?: string;
 
   /**
-   * User ID who created the session.
+   * User ID that created the session.
    */
   userId?: string;
 }

From d3b5e40b63271ba856520577aa8aaa5df64b3a38 Mon Sep 17 00:00:00 2001
From: "stainless-app[bot]"
 <142633134+stainless-app[bot]@users.noreply.github.com>
Date: Fri, 9 May 2025 10:20:20 +0000
Subject: [PATCH 44/44] release: 0.6.0

---
 .release-please-manifest.json |  2 +-
 CHANGELOG.md                  | 61 +++++++++++++++++++++++++++++++++++
 package.json                  |  2 +-
 src/version.ts                |  2 +-
 4 files changed, 64 insertions(+), 3 deletions(-)

diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f1c1e58..bcd0522 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
 {
-  ".": "0.5.0"
+  ".": "0.6.0"
 }
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b82eb11..b76115e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,66 @@
 # Changelog
 
+## 0.6.0 (2025-05-09)
+
+Full Changelog: [v0.5.0...v0.6.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.5.0...v0.6.0)
+
+### Features
+
+* **api:** manual updates ([77b6f44](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/77b6f44b695808f66ce955683f86965c3b8605fb))
+* **api:** manual updates ([f0edc96](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/f0edc9696d24e0a4e4ed648b585883616cde251f))
+* **api:** manual updates ([f50f5ad](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/f50f5adf1ea13bb39845ff8644e2f670bc01856d))
+
+
+### Bug Fixes
+
+* **api:** improve type resolution when importing as a package ([#66](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/66)) ([8aa007b](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/8aa007bc39d87e8b96861748a23d4faa5d084c8a))
+* **client:** fix TypeError with undefined File ([#50](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/50)) ([1262a7b](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/1262a7bcd5e0619e1eaef399ee967b629c79ce09))
+* **client:** send `X-Stainless-Timeout` in seconds ([#63](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/63)) ([dab2433](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/dab243394f6b0f60cedc65f3eabcf1bfe64ed640))
+* **client:** send all configured auth headers ([#68](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/68)) ([3ced793](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/3ced7939c98da7bc8c42a457da3aee4510a778a7))
+* **exports:** ensure resource imports don't require /index ([#57](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/57)) ([23166e6](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/23166e607ec2b8915a97e974e09cdc0abdbc6c23))
+* **internal:** add mts file + crypto shim types ([#58](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/58)) ([716b94c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/716b94c4be5a42cfaf9f59fcdb9332b912113869))
+* **internal:** clean up undefined File test ([#51](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/51)) ([e1e0fb5](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e1e0fb509bfd526c9a8183480ad88330f0c7b240))
+* **internal:** fix file uploads in node 18 jest ([702757c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/702757cc250c54fa31731233f3b88841b42baa32))
+* **internal:** return in castToError instead of throwing ([#43](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/43)) ([2f70ad9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/2f70ad9e95854605f9f38c401d49f8422d62af75))
+* **mcp:** remove unused tools.ts ([#67](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/67)) ([65686bf](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/65686bf96f2a2147c620810605bc66876ec0c13e))
+* **tests:** manually reset node:buffer File ([#52](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/52)) ([2eded46](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/2eded46344af89fbaef371ab685056b8952aa946))
+
+
+### Chores
+
+* **ci:** add timeout thresholds for CI jobs ([d78258c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/d78258ce7b00f01f7714c59bda0d12d3f70b7ec3))
+* **ci:** only use depot for staging repos ([678516c](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/678516c59e2a0a39caa817aa847f9a3f197172b7))
+* **client:** make jsonl methods consistent with other streaming methods ([#65](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/65)) ([62c4790](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/62c4790ed0515d7644fca6075b5d9304bd4b1642))
+* **client:** minor internal fixes ([e3c6fb8](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e3c6fb879bc94b55e66f65a5238102ba390387a8))
+* **client:** move misc public files to new `core/` directory, deprecate old paths ([#62](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/62)) ([e4008c3](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e4008c3ab36557410e2124287eb9ab861e5d81d2))
+* **client:** only accept standard types for file uploads ([#47](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/47)) ([cd888bc](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/cd888bc3c16d0d2cbf3b3c96ab23dc7d46360598))
+* **docs:** improve docs for withResponse/asResponse ([#54](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/54)) ([25092c5](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/25092c5070acc3602094bf34f304105cb7bd7157))
+* **exports:** cleaner resource index imports ([#60](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/60)) ([0049aac](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/0049aac07585fb4a1536ef6ff191b4ba5d5b9720))
+* **exports:** stop using path fallbacks ([#61](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/61)) ([a9df2c1](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/a9df2c166e44d19ff8b374e5225d29971c72bb3e))
+* **internal:** add aliases for Record and Array ([#64](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/64)) ([38e00c9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/38e00c9995d8528c361bf709d3951a0f00238ada))
+* **internal:** codegen related update ([e94c558](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e94c55895af8caf60720420c33c1e22c6e2d5bd4))
+* **internal:** codegen related update ([c60c38f](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/c60c38f7f805d86e56d6a2f96c742b1549d62e5c))
+* **internal:** codegen related update ([#55](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/55)) ([71a1bef](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/71a1bef58884eb34434a3e590cf0942c8166d33b))
+* **internal:** constrain synckit dev dependency ([#49](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/49)) ([41da630](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/41da630123709c225f8c173bbd2aace382d0e865))
+* **internal:** fix tests failing on node v18 ([#48](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/48)) ([c1031bd](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/c1031bd67090cc27d55472a5a32ee70df9ee781e))
+* **internal:** improve node 18 shims ([726127a](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/726127ae7ad639fc5587724e20559893ea3c67eb))
+* **internal:** minor client file refactoring ([#59](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/59)) ([51d47fd](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/51d47fd93e6be04336019ec05c60841a5d25195c))
+* **internal:** reduce CI branch coverage ([e8cd029](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/e8cd029655896872fa1ccd8b71807f8c0ac565c9))
+* **internal:** refactor utils ([eafa310](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/eafa310bb3964addb8bbbf8c8811564f6985068e))
+* **internal:** remove extra empty newlines ([#56](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/56)) ([6431dc9](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/6431dc9927a315b9faf1e906c95930bcec65f3d5))
+* **internal:** remove unnecessary todo ([#45](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/45)) ([bd9e536](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/bd9e5361115c7f9adc8c8d9798f38a04b55ab03c))
+* **internal:** share typescript helpers ([b52aa07](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/b52aa0747ab51dbdf0eeb63e3fce2c255f47a06c))
+* **internal:** upload builds and expand CI branch coverage ([dbd4446](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/dbd4446148041e01ec058c0a19568a17ad7384f7))
+* **perf:** faster base64 decoding ([b3a1e96](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/b3a1e96efe94fd726a49c050eb1a6e0069171983))
+* **tests:** improve enum examples ([#69](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/69)) ([af4a60a](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/af4a60aa5f1bc957cdb96b0996f4ee02c0d7d469))
+* **types:** improved go to definition on fetchOptions ([#53](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/53)) ([54a7db8](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/54a7db864f182bd872aeceae04747930a3e419a7))
+
+
+### Documentation
+
+* **readme:** fix typo ([fea4ecb](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/fea4ecb31efa7b73aec94c3aed1f574b80611110))
+* update URLs from stainlessapi.com to stainless.com ([#46](https://github.com/gitpod-io/gitpod-sdk-typescript/issues/46)) ([6450e47](https://github.com/gitpod-io/gitpod-sdk-typescript/commit/6450e47a5f12103274528a67028b91a01b9c55b8))
+
 ## 0.5.0 (2025-02-21)
 
 Full Changelog: [v0.4.0...v0.5.0](https://github.com/gitpod-io/gitpod-sdk-typescript/compare/v0.4.0...v0.5.0)
diff --git a/package.json b/package.json
index 615f6e6..00c10f8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@gitpod/sdk",
-  "version": "0.5.0",
+  "version": "0.6.0",
   "description": "The official TypeScript library for the Gitpod API",
   "author": "Gitpod <dev-feedback@gitpod.com>",
   "types": "dist/index.d.ts",
diff --git a/src/version.ts b/src/version.ts
index 1f5d158..30c2817 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.5.0'; // x-release-please-version
+export const VERSION = '0.6.0'; // x-release-please-version