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 }); + }); +});