← Public packages
@cameronpak/box
Full Box Public API v1 client: lifecycle, prompts, files, commands, snapshots, environments, webhooks, desktop, hosting, and account.
src/run-command.ts
51 lines · 1.6 KB · TypeScriptimport { assertBoxId, boxRequest, failure, type Result } from './client.ts'
import type { CommandResult, CommandStarted } from './types.ts'
export type RunCommandInput = {
boxId: string
/** Shell command to run inside the box. */
command: string
/** Working directory relative to the box work directory. */
cwd?: string
/** 1 to 600 seconds. Defaults to 30. */
timeoutSeconds?: number
/**
* Start in the background and return a process id immediately.
* Poll getCommandStatus with that process id.
*/
detached?: boolean
}
export type RunCommandOutput = CommandResult | CommandStarted
/**
* Run one shell command in a box and return its exit code, stdout, and stderr.
* This is the main surface for building and testing code.
* With detached: true the command starts in the background and a process id
* is returned immediately; poll getCommandStatus for status and logs.
*/
export default async function runCommand(
input: RunCommandInput,
): Promise<Result<RunCommandOutput>> {
const invalid = assertBoxId(input?.boxId)
if (invalid) return failure<RunCommandOutput>(invalid)
if (!input?.command) {
return failure<RunCommandOutput>({
code: 'command_required',
message: 'command is required.',
status: 400,
})
}
const body: Record<string, unknown> = { command: input.command }
if (input.cwd !== undefined) body.cwd = input.cwd
if (input.timeoutSeconds !== undefined) body.timeoutSeconds = input.timeoutSeconds
if (input.detached !== undefined) body.detached = input.detached
return boxRequest<RunCommandOutput>({
path: '/boxes/' + input.boxId + '/commands',
method: 'POST',
body,
})
}