@computesdk/buddy

中文文档
1.0.22发布于 2026/11/07MITTypeScriptESM + CJS近 30 天下载 8767

Buddy provider for ComputeSDK - Persistent Ubuntu sandboxes for agents, booting in milliseconds, with preview URLs and snapshots

原始使用文档
文档目录13 节
  1. Installation
  2. Setup
  3. Quick Start
  4. Configuration
  5. Choosing an installation
  6. Create options
  7. Exposing ports
  8. Filesystem
  9. Snapshots
  10. Dropping down to the Buddy SDK
  11. Supported Operations
  12. Notes
  13. License

@computesdk/buddy

Buddy provider for ComputeSDK.

Each sandbox is a Buddy sandbox — an Ubuntu microVM in your Buddy project, served from a pre-warmed pool. Commands stream their output as they run, ports are published through Buddy tunnels, and snapshots double as reusable base images.

Built on @buddy-works/sandbox-sdk, Buddy's official TypeScript SDK.

Installation

npm install @computesdk/buddy

Node 20.19 or 22.12 and newer is required, matching the Buddy SDK (ESM and CommonJS builds are both shipped).

Setup

  1. Create an API token in Buddy → My ID → Access tokens with the SANDBOX_MANAGE scope
  2. Create (or pick) a Buddy project for your sandboxes
  3. Set environment variables:
export BUDDY_TOKEN=your_api_token_here
export BUDDY_WORKSPACE=your_workspace_domain
export BUDDY_PROJECT=your_project_name

Quick Start

import { buddy } from '@computesdk/buddy';

const compute = buddy();

const sandbox = await compute.instances.create();

const result = await sandbox.runCommand('echo "hello from buddy"');
console.log(result.stdout);

await sandbox.destroy();

Credentials are read from the environment, so buddy() needs no arguments. Pass them explicitly to override:

const compute = buddy({
  token: process.env.BUDDY_TOKEN!,
  workspace: 'acme',
  project: 'sandboxes',
});

Configuration

interface BuddyConfig {
  /** API token with the `SANDBOX_MANAGE` scope. Falls back to `BUDDY_TOKEN`. */
  token?: string;
  /** Workspace domain. Falls back to `BUDDY_WORKSPACE`. */
  workspace?: string;
  /** Project the sandboxes belong to. Falls back to `BUDDY_PROJECT`. */
  project?: string;
  /** Base OS image — `'ubuntu:24.04'` (default) or `'ubuntu:22.04'`. */
  os?: string;
  /** Resource preset, `"{vCPU}x{RAM GB}"` from `1x2` to `12x24`. Buddy's own default applies when omitted. */
  resources?: BuddyResources;
  /** Buddy installation — `'US'` (default) or `'EU'`. */
  region?: BuddyRegion;
  /** Sandbox lifetime in milliseconds, after which Buddy stops it. Defaults to 1 hour. */
  timeout?: number;
  /** Ports to expose on every sandbox this provider creates. */
  ports?: BuddyPortInput[];
  /** API base URL. Overrides `region`, for on-premise installations. */
  apiUrl?: string;
}

Choosing an installation

Buddy runs independent installations rather than regions within one API, each with its own host, accounts and tokens. region selects both the API host and where tunnels terminate:

const compute = buddy({ region: 'EU' });
regionAPI host
US (default)https://api.buddy.works
EUhttps://api.eu.buddy.works

A token issued by one installation is not valid on the others. For an on-premise installation, set apiUrl instead.

Create options

Beyond the cross-provider options, create accepts:

await compute.instances.create({
  // Expose ports up front, so getUrl needs no extra round trip
  ports: [3000, { port: 443, type: 'TLS', region: 'EU' }],
  // Resources — either a preset, or cpu/memory that map onto one
  resources: '4x8',
  // Commands run once when the sandbox first boots
  firstBootCommands: 'npm ci',
  // Working directory for the sandbox's apps
  appDir: '/buddy/app',
  tags: ['ci'],
});

snapshotId (or templateId) starts the sandbox from a snapshot instead of a base image.

Exposing ports

const sandbox = await compute.instances.create({ ports: [3000] });
await sandbox.runCommand('npx serve -l 3000', { background: true });

const url = await sandbox.getUrl({ port: 3000 });

getUrl opens a tunnel on demand if the port was not declared at create time, keeping any tunnels already open. Only HTTP and TLS tunnels get a public URL; TCP and SSH tunnels are reached by host and port, reported in getInfo.

Filesystem

await sandbox.filesystem.mkdir('/buddy/app');
await sandbox.filesystem.writeFile('/buddy/app/index.js', 'console.log(1)');
await sandbox.filesystem.readFile('/buddy/app/index.js');
await sandbox.filesystem.readdir('/buddy/app');
await sandbox.filesystem.exists('/buddy/app/index.js');
await sandbox.filesystem.remove('/buddy/app');

Relative paths resolve against /buddy, the home directory of the default buddy user.

The first filesystem call on a sandbox waits for its first-boot setup to finish. Buddy queues commands against a starting sandbox, but the content endpoints do not: during setup they either refuse the request or accept a write and discard it once setup completes. The wait costs a few hundred milliseconds on a freshly created sandbox and nothing afterwards.

Snapshots

A snapshot is a disk image taken from a live sandbox, and doubles as the reusable base image other providers call a template.

const snapshot = await compute.snapshot.create(sandbox.instanceId, { name: 'with-deps' });

await compute.snapshot.list();                                 // the whole project
await compute.snapshot.list({ instanceId: sandbox.instanceId });  // one sandbox
await compute.snapshot.delete(snapshot.id);

// Booting from it is a normal create
const prepared = await compute.instances.create({ snapshotId: snapshot.id });

Buddy creates snapshots asynchronously and they cannot be restored until they turn CREATED, so create waits for that before returning. metadata is accepted for cross-provider compatibility but not stored: Buddy keeps only a name.

Buddy has no separate template entity, so template.list and template.delete alias the snapshot methods and template.create throws, pointing at snapshot.create.

Dropping down to the Buddy SDK

getInstance() returns the handle the provider works with, including the live SDK client and filesystem, so Buddy features outside the ComputeSDK surface stay reachable without building a second client:

const { client, fs, sandboxId } = sandbox.getInstance();
await client.getSandboxAppLogs({ path: { sandbox_id: sandboxId, app_id: 'web' } });

The handle's fs and client call the API directly, without the provider's first-boot wait: on a sandbox that has just been created, make one sandbox.filesystem call (even exists) before uploading through them.

Supported Operations

MethodSupportedNotes
create✅One request; returns while the sandbox is still starting, since commands queue against it.
getById✅Returns null when the sandbox no longer exists.
list✅Lists the sandboxes in the configured project.
destroy✅Retries on server errors; a no-op if the sandbox is already gone.
runCommand✅One round trip via exec for plain calls; streams output as it arrives when callbacks are passed. Real exit codes either way.
getInfo✅Reports Buddy's own status and setup status, plus every tunnel, in metadata.
getUrl✅Opens a tunnel if the port has none yet, keeping the existing ones.
filesystem✅Transfers file contents through Buddy's native endpoints, without command-line content limits. Reads first resolve symlinks with a native command; existing directories are accepted only after verifying their type.
snapshot✅create / list / delete; create waits until the snapshot is restorable.
template⚠️No template entity in Buddy — list/delete alias snapshots, create throws with a hint.

Notes

  • create does not wait for the sandbox to reach RUNNING. Buddy queues commands submitted against a starting sandbox, so waiting would only add latency to the first command. For the same reason the provider calls the SDK's BuddyApiClient directly instead of Sandbox.create(), which polls for readiness once a second.
  • runCommand(cmd) without streaming callbacks or a timeout runs through Buddy's synchronous exec endpoint: one request that returns stdout, stderr and the exit code together. Such a command leaves no entry in the sandbox's command history. The server waits at most 60 s for it; past that the call returns exit code 124 with the server's message in stderr, and the process keeps running in the sandbox. Pass a timeout for commands that may run longer or must be stopped.
  • runCommand(cmd, { onStdout, onStderr }), streamCommand, background: true and any timeout use the asynchronous execs resource instead, so output arrives as it is produced, the command shows up in the history, and a timeout kills it. Its log does not tell stdout from stderr, so all output goes to stdout and onStdout; onStderr is not called. Buddy runs at most 3 such commands at once per member in one sandbox and 10 per workspace — over that, runCommand throws — and stops each one after 90 minutes, including background ones.
  • runCommand(cmd, { background: true }) returns as soon as Buddy has queued the command, without reading its output.
  • runCommand(cmd, { timeout }) returns the timeout result when the timeout passes and terminates the command.
  • Sandbox placement inside an installation is not selectable; region picks the installation and the tunnel location.

License

MIT

版本与发布记录

@computesdk/buddy 共发布 22 个版本,首次发布于 2026/09/10;过去 12 个月发布了 22 个版本。

版本发布日期距今
1.0.22latest2026/11/073 天前
1.0.212026/11/064 天前
1.0.202026/11/046 天前
1.0.192026/10/2812 天前
1.0.182026/10/2714 天前
1.0.172026/10/2317 天前

关于 @computesdk/buddy 的常见问题

@computesdk/buddy 是什么?

Buddy provider for ComputeSDK - Persistent Ubuntu sandboxes for agents, booting in milliseconds, with preview URLs and snapshots

如何安装 @computesdk/buddy?

在项目目录运行 npm install @computesdk/buddy,或使用 pnpm add / yarn add / bun add。

@computesdk/buddy 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@computesdk/buddy 支持 ESM 还是 CommonJS?

同时提供 ES Module 与 CommonJS 入口,import 和 require() 都可以使用,打包工具会自动选择合适的版本。

@computesdk/buddy 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js ^20.19.0 || >=22.12.0。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@computesdk/buddy 可以商用吗?

@computesdk/buddy 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@computesdk/buddy 的下载量有多少?

根据 npm 官方下载统计,@computesdk/buddy 在 2026/10/11 – 2026/11/09 这 30 天内被下载 8,767 次,日均约 292 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@computesdk/buddy 还在维护吗?

最新版本 1.0.22 发布于 2026/11/07(3 天前);至今共发布 22 个版本,其中过去 12 个月发布了 22 个;首次发布于 2026/09/10。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。