@agent-compose/sdk 0.5.0 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1599,13 +1599,14 @@ function makeVercelSandboxProvider(sb, globalEnvs) {
1599
1599
  sandboxId: sb.sandboxId,
1600
1600
  commands: {
1601
1601
  async run(cmd, opts) {
1602
+ const sudo = opts?.sudo === true;
1602
1603
  if (opts?.background) {
1603
- sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
1604
+ sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...sudo ? { sudo: true } : {} }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
1604
1605
  return { exitCode: 0, stdout: "" };
1605
1606
  }
1606
1607
  const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
1607
1608
  let stdout = "";
1608
- const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
1609
+ const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...sudo ? { sudo: true } : {} });
1609
1610
  await pRetry(async (attempt) => {
1610
1611
  const h = attempt === 1 ? handle : await sb.getCommand(handle.cmdId);
1611
1612
  for await (const log of h.logs()) {
@@ -1644,8 +1645,9 @@ function makeLocalSandboxProvider() {
1644
1645
  sandboxId: "local",
1645
1646
  commands: {
1646
1647
  run(cmd, opts) {
1648
+ const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
1647
1649
  return new Promise((resolve, reject) => {
1648
- const proc = spawn("sh", ["-c", cmd], {
1650
+ const proc = spawn("sh", ["-c", finalCmd], {
1649
1651
  ...opts?.cwd ? { cwd: opts.cwd } : {},
1650
1652
  env: { ...process.env, ...opts?.envs ?? {} },
1651
1653
  stdio: ["ignore", "pipe", "pipe"]
@@ -1599,13 +1599,14 @@ function makeVercelSandboxProvider(sb, globalEnvs) {
1599
1599
  sandboxId: sb.sandboxId,
1600
1600
  commands: {
1601
1601
  async run(cmd, opts) {
1602
+ const sudo = opts?.sudo === true;
1602
1603
  if (opts?.background) {
1603
- sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
1604
+ sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...sudo ? { sudo: true } : {} }).catch((err) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
1604
1605
  return { exitCode: 0, stdout: "" };
1605
1606
  }
1606
1607
  const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
1607
1608
  let stdout = "";
1608
- const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
1609
+ const handle = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...sudo ? { sudo: true } : {} });
1609
1610
  await pRetry(async (attempt) => {
1610
1611
  const h = attempt === 1 ? handle : await sb.getCommand(handle.cmdId);
1611
1612
  for await (const log of h.logs()) {
@@ -1644,8 +1645,9 @@ function makeLocalSandboxProvider() {
1644
1645
  sandboxId: "local",
1645
1646
  commands: {
1646
1647
  run(cmd, opts) {
1648
+ const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
1647
1649
  return new Promise((resolve, reject) => {
1648
- const proc = spawn("sh", ["-c", cmd], {
1650
+ const proc = spawn("sh", ["-c", finalCmd], {
1649
1651
  ...opts?.cwd ? { cwd: opts.cwd } : {},
1650
1652
  env: { ...process.env, ...opts?.envs ?? {} },
1651
1653
  stdio: ["ignore", "pipe", "pipe"]
@@ -10,6 +10,11 @@ export interface SandboxCommandRunOptions {
10
10
  onStdout?: (data: string) => void;
11
11
  onStderr?: (data: string) => void;
12
12
  background?: boolean;
13
+ /** Run the command with root privileges. Vercel maps this to its native
14
+ * `sudo` flag; E2B runs the command as `user: "root"`; the local provider
15
+ * prepends `sudo`. Defaults to false. Requires the sandbox image to grant
16
+ * the command root (Vercel's runtimes do — passwordless). */
17
+ sudo?: boolean;
13
18
  }
14
19
  export interface SandboxCommandResult {
15
20
  exitCode: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-compose/sdk",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "Client library for agent-compose — define agents, runtimes, and workflows, and invoke them against an agent-compose server.",
5
5
  "license": "MIT",
6
6
  "repository": {
package/src/sandbox.ts CHANGED
@@ -200,16 +200,20 @@ function makeVercelSandboxProvider(sb: any, globalEnvs?: Record<string, string>)
200
200
  sandboxId: sb.sandboxId,
201
201
  commands: {
202
202
  async run(cmd, opts) {
203
+ // Vercel's runCommand takes a native `sudo` flag — pass it on the `sh`
204
+ // invocation so the whole shell (and every command it spawns) runs as
205
+ // root, matching `sb.runCommand({ cmd, args, sudo: true })` semantics.
206
+ const sudo = opts?.sudo === true;
203
207
  if (opts?.background) {
204
208
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
205
- void (sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true }) as Promise<any>)
209
+ void (sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts.cwd, env: mergeEnvs(opts.envs), detached: true, ...(sudo ? { sudo: true } : {}) }) as Promise<any>)
206
210
  .catch((err: unknown) => console.error(`[sandbox] background command failed: ${err instanceof Error ? err.message : String(err)}`));
207
211
  return { exitCode: 0, stdout: "" };
208
212
  }
209
213
  const signal = opts?.timeoutMs ? AbortSignal.timeout(opts.timeoutMs) : undefined;
210
214
  let stdout = "";
211
215
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
212
- const handle: any = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal });
216
+ const handle: any = await sb.runCommand({ cmd: "sh", args: ["-c", cmd], cwd: opts?.cwd, env: mergeEnvs(opts?.envs), detached: true, signal, ...(sudo ? { sudo: true } : {}) });
213
217
  // Reconnect to the already-running command on transient stream failures (e.g. BrotliDecompressionError).
214
218
  await pRetry(async (attempt) => {
215
219
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -261,8 +265,13 @@ export function makeLocalSandboxProvider(): SandboxProvider {
261
265
  sandboxId: "local",
262
266
  commands: {
263
267
  run(cmd, opts) {
268
+ // Prepend `sudo` so the command runs as root. The local provider
269
+ // targets the runner's own host VM (used by defineSandboxEnvironment
270
+ // recipes); harmless when the host is already root or has passwordless
271
+ // sudo, which is the only context it runs in.
272
+ const finalCmd = opts?.sudo ? `sudo ${cmd}` : cmd;
264
273
  return new Promise((resolve, reject) => {
265
- const proc = spawn("sh", ["-c", cmd], {
274
+ const proc = spawn("sh", ["-c", finalCmd], {
266
275
  ...(opts?.cwd ? { cwd: opts.cwd } : {}),
267
276
  env: { ...process.env, ...(opts?.envs ?? {}) },
268
277
  stdio: ["ignore", "pipe", "pipe"],
@@ -11,6 +11,11 @@ export interface SandboxCommandRunOptions {
11
11
  onStdout?: (data: string) => void;
12
12
  onStderr?: (data: string) => void;
13
13
  background?: boolean;
14
+ /** Run the command with root privileges. Vercel maps this to its native
15
+ * `sudo` flag; E2B runs the command as `user: "root"`; the local provider
16
+ * prepends `sudo`. Defaults to false. Requires the sandbox image to grant
17
+ * the command root (Vercel's runtimes do — passwordless). */
18
+ sudo?: boolean;
14
19
  }
15
20
 
16
21
  export interface SandboxCommandResult {