diff --git a/.release-please-manifest.json b/.release-please-manifest.json
index f87262a..bc7e4aa 100644
--- a/.release-please-manifest.json
+++ b/.release-please-manifest.json
@@ -1,3 +1,3 @@
{
- ".": "0.15.0"
+ ".": "0.16.0"
}
diff --git a/.stats.yml b/.stats.yml
index b4dc606..8cd6a7c 100644
--- a/.stats.yml
+++ b/.stats.yml
@@ -1,4 +1,4 @@
-configured_endpoints: 64
-openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-e21f0324774a1762bc2bba0da3a8a6b0d0e74720d7a1c83dec813f9e027fcf58.yml
-openapi_spec_hash: f1b636abfd6cb8e7c2ba7ffb8e53b9ba
-config_hash: 09a2df23048cb16689c9a390d9e5bc47
+configured_endpoints: 65
+openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-ecf484375ede1edd7754779ad8beeebd4ba9118152fe6cd65772dc7245a19dee.yml
+openapi_spec_hash: b1f3f05005f75cbf5b82299459e2aa9b
+config_hash: 3ded7a0ed77b1bfd68eabc6763521fe8
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0725a2f..0422864 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,18 @@
# Changelog
+## 0.16.0 (2025-10-27)
+
+Full Changelog: [v0.15.0...v0.16.0](https://github.com/onkernel/kernel-node-sdk/compare/v0.15.0...v0.16.0)
+
+### Features
+
+* ad hoc playwright code exec AP| ([1112215](https://github.com/onkernel/kernel-node-sdk/commit/11122155f3745843cb56d19261e97d1df4eaadea))
+
+
+### Bug Fixes
+
+* **client:** incorrect offset pagination check ([63aee26](https://github.com/onkernel/kernel-node-sdk/commit/63aee268f4954577bfdf284f2e6af8adc466712d))
+
## 0.15.0 (2025-10-17)
Full Changelog: [v0.14.2...v0.15.0](https://github.com/onkernel/kernel-node-sdk/compare/v0.14.2...v0.15.0)
diff --git a/api.md b/api.md
index cd45552..3899a03 100644
--- a/api.md
+++ b/api.md
@@ -162,6 +162,16 @@ Methods:
- client.browsers.computer.scroll(id, { ...params }) -> void
- client.browsers.computer.typeText(id, { ...params }) -> void
+## Playwright
+
+Types:
+
+- PlaywrightExecuteResponse
+
+Methods:
+
+- client.browsers.playwright.execute(id, { ...params }) -> PlaywrightExecuteResponse
+
# Profiles
Types:
diff --git a/package.json b/package.json
index dfa3c73..386fb01 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@onkernel/sdk",
- "version": "0.15.0",
+ "version": "0.16.0",
"description": "The official TypeScript library for the Kernel API",
"author": "Kernel <>",
"types": "dist/index.d.ts",
diff --git a/src/core/pagination.ts b/src/core/pagination.ts
index c3266cd..9a507f0 100644
--- a/src/core/pagination.ts
+++ b/src/core/pagination.ts
@@ -148,11 +148,7 @@ export class OffsetPagination- extends AbstractPage
- {
}
nextPageRequestOptions(): PageRequestOptions | null {
- const offset = this.next_offset;
- if (!offset) {
- return null;
- }
-
+ const offset = this.next_offset ?? 0;
const length = this.getPaginatedItems().length;
const currentCount = offset + length;
diff --git a/src/resources/browsers/browsers.ts b/src/resources/browsers/browsers.ts
index df843b1..874e73a 100644
--- a/src/resources/browsers/browsers.ts
+++ b/src/resources/browsers/browsers.ts
@@ -15,6 +15,8 @@ import {
} from './computer';
import * as LogsAPI from './logs';
import { LogStreamParams, Logs } from './logs';
+import * as PlaywrightAPI from './playwright';
+import { Playwright, PlaywrightExecuteParams, PlaywrightExecuteResponse } from './playwright';
import * as ProcessAPI from './process';
import {
Process,
@@ -71,6 +73,7 @@ export class Browsers extends APIResource {
process: ProcessAPI.Process = new ProcessAPI.Process(this._client);
logs: LogsAPI.Logs = new LogsAPI.Logs(this._client);
computer: ComputerAPI.Computer = new ComputerAPI.Computer(this._client);
+ playwright: PlaywrightAPI.Playwright = new PlaywrightAPI.Playwright(this._client);
/**
* Create a new browser session from within an action.
@@ -695,6 +698,7 @@ Browsers.Fs = Fs;
Browsers.Process = Process;
Browsers.Logs = Logs;
Browsers.Computer = Computer;
+Browsers.Playwright = Playwright;
export declare namespace Browsers {
export {
@@ -763,4 +767,10 @@ export declare namespace Browsers {
type ComputerScrollParams as ComputerScrollParams,
type ComputerTypeTextParams as ComputerTypeTextParams,
};
+
+ export {
+ Playwright as Playwright,
+ type PlaywrightExecuteResponse as PlaywrightExecuteResponse,
+ type PlaywrightExecuteParams as PlaywrightExecuteParams,
+ };
}
diff --git a/src/resources/browsers/index.ts b/src/resources/browsers/index.ts
index 243f485..4bba398 100644
--- a/src/resources/browsers/index.ts
+++ b/src/resources/browsers/index.ts
@@ -39,6 +39,7 @@ export {
type FWriteFileParams,
} from './fs/index';
export { Logs, type LogStreamParams } from './logs';
+export { Playwright, type PlaywrightExecuteResponse, type PlaywrightExecuteParams } from './playwright';
export {
Process,
type ProcessExecResponse,
diff --git a/src/resources/browsers/playwright.ts b/src/resources/browsers/playwright.ts
new file mode 100644
index 0000000..bd99c52
--- /dev/null
+++ b/src/resources/browsers/playwright.ts
@@ -0,0 +1,83 @@
+// 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';
+import { path } from '../../internal/utils/path';
+
+export class Playwright extends APIResource {
+ /**
+ * Execute arbitrary Playwright code in a fresh execution context against the
+ * browser. The code runs in the same VM as the browser, minimizing latency and
+ * maximizing throughput. It has access to 'page', 'context', and 'browser'
+ * variables. It can `return` a value, and this value is returned in the response.
+ *
+ * @example
+ * ```ts
+ * const response = await client.browsers.playwright.execute(
+ * 'id',
+ * { code: 'code' },
+ * );
+ * ```
+ */
+ execute(
+ id: string,
+ body: PlaywrightExecuteParams,
+ options?: RequestOptions,
+ ): APIPromise {
+ return this._client.post(path`/browsers/${id}/playwright/execute`, { body, ...options });
+ }
+}
+
+/**
+ * Result of Playwright code execution
+ */
+export interface PlaywrightExecuteResponse {
+ /**
+ * Whether the code executed successfully
+ */
+ success: boolean;
+
+ /**
+ * Error message if execution failed
+ */
+ error?: string;
+
+ /**
+ * The value returned by the code (if any)
+ */
+ result?: unknown;
+
+ /**
+ * Standard error from the execution
+ */
+ stderr?: string;
+
+ /**
+ * Standard output from the execution
+ */
+ stdout?: string;
+}
+
+export interface PlaywrightExecuteParams {
+ /**
+ * TypeScript/JavaScript code to execute. The code has access to 'page', 'context',
+ * and 'browser' variables. It runs within a function, so you can use a return
+ * statement at the end to return a value. This value is returned as the `result`
+ * property in the response. Example: "await page.goto('https://example.com');
+ * return await page.title();"
+ */
+ code: string;
+
+ /**
+ * Maximum execution time in seconds. Default is 60.
+ */
+ timeout_sec?: number;
+}
+
+export declare namespace Playwright {
+ export {
+ type PlaywrightExecuteResponse as PlaywrightExecuteResponse,
+ type PlaywrightExecuteParams as PlaywrightExecuteParams,
+ };
+}
diff --git a/src/version.ts b/src/version.ts
index b67001e..be03af2 100644
--- a/src/version.ts
+++ b/src/version.ts
@@ -1 +1 @@
-export const VERSION = '0.15.0'; // x-release-please-version
+export const VERSION = '0.16.0'; // x-release-please-version
diff --git a/tests/api-resources/browsers/playwright.test.ts b/tests/api-resources/browsers/playwright.test.ts
new file mode 100644
index 0000000..5c45947
--- /dev/null
+++ b/tests/api-resources/browsers/playwright.test.ts
@@ -0,0 +1,27 @@
+// File generated from our OpenAPI spec by Stainless. See CONTRIBUTING.md for details.
+
+import Kernel from '@onkernel/sdk';
+
+const client = new Kernel({
+ apiKey: 'My API Key',
+ baseURL: process.env['TEST_API_BASE_URL'] ?? 'http://127.0.0.1:4010',
+});
+
+describe('resource playwright', () => {
+ // Prism tests are disabled
+ test.skip('execute: only required params', async () => {
+ const responsePromise = client.browsers.playwright.execute('id', { code: 'code' });
+ 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);
+ });
+
+ // Prism tests are disabled
+ test.skip('execute: required and optional params', async () => {
+ const response = await client.browsers.playwright.execute('id', { code: 'code', timeout_sec: 1 });
+ });
+});