Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .release-please-manifest.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
".": "0.14.2"
".": "0.15.0"
}
8 changes: 4 additions & 4 deletions .stats.yml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
configured_endpoints: 57
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel%2Fkernel-6c765f1c4ce1c4dd4ceb371f56bf047aa79af36031ba43cbd68fa16a5fdb9bb3.yml
openapi_spec_hash: e9086f69281360f4e0895c9274a59531
config_hash: deadfc4d2b0a947673bcf559b5db6e1b
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
9 changes: 9 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# Changelog

## 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)

### Features

* click mouse, move mouse, screenshot ([68e527c](https://github.com/onkernel/kernel-node-sdk/commit/68e527cefd5659f579119a39ecd4c170193bbed5))
* Phani/deploy with GitHub url ([1e97151](https://github.com/onkernel/kernel-node-sdk/commit/1e971513c25cdfe84624c033ad89c5bfdc7fef20))

## 0.14.2 (2025-10-16)

Full Changelog: [v0.14.1...v0.14.2](https://github.com/onkernel/kernel-node-sdk/compare/v0.14.1...v0.14.2)
Expand Down
22 changes: 5 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,29 +67,17 @@ import Kernel, { toFile } from '@onkernel/sdk';
const client = new Kernel();

// If you have access to Node `fs` we recommend using `fs.createReadStream()`:
await client.deployments.create({
entrypoint_rel_path: 'src/app.py',
file: fs.createReadStream('/path/to/file'),
});
await client.deployments.create({ file: fs.createReadStream('/path/to/file') });

// Or if you have the web `File` API you can pass a `File` instance:
await client.deployments.create({ entrypoint_rel_path: 'src/app.py', file: new File(['my bytes'], 'file') });
await client.deployments.create({ file: new File(['my bytes'], 'file') });

// You can also pass a `fetch` `Response`:
await client.deployments.create({
entrypoint_rel_path: 'src/app.py',
file: await fetch('https://somesite/file'),
});
await client.deployments.create({ file: await fetch('https://somesite/file') });

// Finally, if none of the above are convenient, you can use our `toFile` helper:
await client.deployments.create({
entrypoint_rel_path: 'src/app.py',
file: await toFile(Buffer.from('my bytes'), 'file'),
});
await client.deployments.create({
entrypoint_rel_path: 'src/app.py',
file: await toFile(new Uint8Array([0, 1, 2]), 'file'),
});
await client.deployments.create({ file: await toFile(Buffer.from('my bytes'), 'file') });
await client.deployments.create({ file: await toFile(new Uint8Array([0, 1, 2]), 'file') });
```

## Handling errors
Expand Down
12 changes: 12 additions & 0 deletions api.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,18 @@ Methods:

- <code title="get /browsers/{id}/logs/stream">client.browsers.logs.<a href="./src/resources/browsers/logs.ts">stream</a>(id, { ...params }) -> LogEvent</code>

## Computer

Methods:

- <code title="post /browsers/{id}/computer/screenshot">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">captureScreenshot</a>(id, { ...params }) -> Response</code>
- <code title="post /browsers/{id}/computer/click_mouse">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">clickMouse</a>(id, { ...params }) -> void</code>
- <code title="post /browsers/{id}/computer/drag_mouse">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">dragMouse</a>(id, { ...params }) -> void</code>
- <code title="post /browsers/{id}/computer/move_mouse">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">moveMouse</a>(id, { ...params }) -> void</code>
- <code title="post /browsers/{id}/computer/press_key">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">pressKey</a>(id, { ...params }) -> void</code>
- <code title="post /browsers/{id}/computer/scroll">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">scroll</a>(id, { ...params }) -> void</code>
- <code title="post /browsers/{id}/computer/type">client.browsers.computer.<a href="./src/resources/browsers/computer.ts">typeText</a>(id, { ...params }) -> void</code>

# Profiles

Types:
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@onkernel/sdk",
"version": "0.14.2",
"version": "0.15.0",
"description": "The official TypeScript library for the Kernel API",
"author": "Kernel <>",
"types": "dist/index.d.ts",
Expand Down
24 changes: 21 additions & 3 deletions src/internal/uploads.ts
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,27 @@ const addFormValue = async (form: FormData, key: string, value: unknown): Promis
} else if (Array.isArray(value)) {
await Promise.all(value.map((entry) => addFormValue(form, key + '[]', entry)));
} else if (typeof value === 'object') {
await Promise.all(
Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)),
);
// Special case: env_vars should always be flattened for backward compatibility
// with APIs that expect env_vars[KEY] format
const shouldAlwaysFlatten = key === 'env_vars';
// If the object doesn't contain any uploadable values,
// serialize it as JSON instead of flattening it into bracketed keys.
// This handles fields with contentType: application/json in the OpenAPI spec.
if (!shouldAlwaysFlatten && !hasUploadableValue(value)) {
// Filter out undefined values to check if object has any actual content
const entries = Object.entries(value).filter(([_, v]) => v !== undefined);
if (entries.length > 0) {
form.append(key, JSON.stringify(value));
}
// If all properties are undefined, don't add anything to the form
} else {
// Flatten objects that:
// - Contain uploadable values (files/blobs), or
// - Are explicitly marked to always flatten (like env_vars)
await Promise.all(
Object.entries(value).map(([name, prop]) => addFormValue(form, `${key}[${name}]`, prop)),
);
}
} else {
throw new TypeError(
`Invalid value given to form, expected a string, number, boolean, object, Array, File or Blob but got ${value} instead`,
Expand Down
24 changes: 24 additions & 0 deletions src/resources/browsers/browsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,17 @@

import { APIResource } from '../../core/resource';
import * as BrowsersAPI from './browsers';
import * as ComputerAPI from './computer';
import {
Computer,
ComputerCaptureScreenshotParams,
ComputerClickMouseParams,
ComputerDragMouseParams,
ComputerMoveMouseParams,
ComputerPressKeyParams,
ComputerScrollParams,
ComputerTypeTextParams,
} from './computer';
import * as LogsAPI from './logs';
import { LogStreamParams, Logs } from './logs';
import * as ProcessAPI from './process';
Expand Down Expand Up @@ -59,6 +70,7 @@ export class Browsers extends APIResource {
fs: FsAPI.Fs = new FsAPI.Fs(this._client);
process: ProcessAPI.Process = new ProcessAPI.Process(this._client);
logs: LogsAPI.Logs = new LogsAPI.Logs(this._client);
computer: ComputerAPI.Computer = new ComputerAPI.Computer(this._client);

/**
* Create a new browser session from within an action.
Expand Down Expand Up @@ -682,6 +694,7 @@ Browsers.Replays = Replays;
Browsers.Fs = Fs;
Browsers.Process = Process;
Browsers.Logs = Logs;
Browsers.Computer = Computer;

export declare namespace Browsers {
export {
Expand Down Expand Up @@ -739,4 +752,15 @@ export declare namespace Browsers {
};

export { Logs as Logs, type LogStreamParams as LogStreamParams };

export {
Computer as Computer,
type ComputerCaptureScreenshotParams as ComputerCaptureScreenshotParams,
type ComputerClickMouseParams as ComputerClickMouseParams,
type ComputerDragMouseParams as ComputerDragMouseParams,
type ComputerMoveMouseParams as ComputerMoveMouseParams,
type ComputerPressKeyParams as ComputerPressKeyParams,
type ComputerScrollParams as ComputerScrollParams,
type ComputerTypeTextParams as ComputerTypeTextParams,
};
}
Loading