Skip to content
Talk to our solutions team

Execution

Running commands and containers from a script. Each function lists its parameters, defaults and return value.

Local shell execution functions.

Scope: System

FunctionDescription
shell.execute()Execute a shell script
shell.open()Open a persistent shell session
shell.run()Run a command in a persistent shell
shell.close()Close a persistent shell session

Execute a shell script. Accepts either a string (simple command) or a map with options.

ParameterTypeDefaultDescription
scriptstringShell script to execute
shellstring"bash"Shell to use (bash, sh, zsh)
workingDirstring"./"Working directory
userstringUser to run as
envmapEnvironment variables
inheritenvbooltrueInherit parent environment
interactiveboolfalseRun in interactive mode
historyboolfalseEnable shell history
forkboolfalseRun in separate process group
templateVarsmapLiquid template variables
streambooltrueStream output to stdout/stderr
captureboolfalseCapture output and return it
FieldTypeDescription
successboolWhether execution succeeded
errorstringError message if failed
outputstringCaptured output (when capture: true)
// Simple command (string form)
shell.execute("echo hello")
// With options (map form)
shell.execute({
script: `
npm ci
npm run build
`,
env: {
NODE_ENV: "production",
CI: "true"
}
})
// Isolated environment
shell.execute({
script: "env | wc -l",
env: { BUILD_MODE: "isolated" },
inheritenv: false
})
// Capture output
let result = shell.execute({
script: "hostname",
capture: true
})
log(result.output)
// Background process
shell.execute({
script: "nohup ./daemon.sh &",
fork: true
})
// Custom working directory
shell.execute({
script: "ls -la",
workingDir: "/app/frontend"
})

Open a persistent shell session that can be reused across multiple shell.run() calls. Returns a shell handle.

ParameterTypeDefaultDescription
shellstring"bash"Shell to use
workingDirstring"./"Working directory
userstringUser to run as
envmapEnvironment variables
inheritenvbooltrueInherit parent environment
forkboolfalseRun in separate process group
FieldTypeDescription
successboolWhether the shell was opened
shellIdstringShell handle for use with shell.run() and shell.close()
// Open a persistent shell
let sh = shell.open({ shell: "bash", workingDir: "/app" })
log("Shell opened: " + sh.shellId)

Execute a command in a persistent shell opened with shell.open().

ParameterTypeDefaultDescription
shellIdstringShell handle from shell.open() (required)
scriptstringShell script to execute (required)
streambooltrueStream output to stdout
captureboolfalseCapture output and return it
templateVarsmapLiquid template variables
FieldTypeDescription
successboolWhether execution succeeded
errorstringError message if failed
outputstringCaptured output (when capture: true)
// Run commands in a persistent shell
let sh = shell.open({ workingDir: "/app" })
shell.run({ shellId: sh.shellId, script: "npm ci" })
shell.run({ shellId: sh.shellId, script: "npm run build" })
// Capture output from persistent shell
let result = shell.run({
shellId: sh.shellId,
script: "node --version",
capture: true
})
log("Node version: " + result.output)
shell.close({ shellId: sh.shellId })

Close a persistent shell session.

ParameterTypeDefaultDescription
shellIdstringShell handle from shell.open() (required)
FieldTypeDescription
successboolWhether the shell was closed
// Full persistent shell lifecycle
let sh = shell.open({ shell: "bash" })
shell.run({ shellId: sh.shellId, script: "cd /app && npm ci" })
shell.run({ shellId: sh.shellId, script: "npm test" })
shell.run({ shellId: sh.shellId, script: "npm run build" })
shell.close({ shellId: sh.shellId })

Interactive shell session functions with conditional commands, output extraction, and check expressions.

Scope: System

FunctionDescription
supershell.execute()Execute an interactive shell session with conditional commands

Execute multiple commands in a single shell session with support for conditions (test/check), output extraction, and error handling.

ParameterTypeDefaultDescription
commandsarrayList of commands (string or command object)
shellstring"bash"Shell to use
workingDirstring"./"Working directory
userstringUser to run as
sudoboolfalseRun with sudo
onErrorstring"terminate"Error handling: "terminate" or "continue"
historyboolfalseEnable shell history
envmapEnvironment variables
inheritenvbooltrueInherit parent environment
forkboolfalseRun in separate process group
templateVarsmapLiquid template variables
PropertyTypeDescription
commandstringShell command to execute
teststringShell test condition ([ ]) — run only if test succeeds
testNegatedboolNegate the test condition
checkstringJavaScript expression — run only if true
checkNegatedboolNegate the check expression
extractstring/mapExtract output to variable(s). String: full output. Map: regex patterns
FieldTypeDescription
successboolWhether all commands succeeded
errorstringError message if failed
extractedVarsmapVariables extracted from command output
commandResultsarrayPer-command results with command, output, skipped, skipReason, error
// Simple commands (string array)
supershell.execute({
commands: [
"echo 'Starting'",
"npm install",
"npm run build"
]
})
// With conditions and extraction
supershell.execute({
commands: [
{ command: "git pull", test: "-d .git" },
{ command: "npm install", test: "-f package.json" },
{ command: "hostname", extract: "server_name" }
]
})
// Extract with regex patterns
supershell.execute({
commands: [
{
command: "cat /etc/os-release | grep VERSION_ID",
extract: {
os_version: 'VERSION_ID="(.+)"'
}
},
{
command: "free -m | grep Mem",
extract: {
total_memory: 'Mem:\\s+(\\d+)',
used_memory: 'Mem:\\s+\\d+\\s+(\\d+)'
}
}
]
})
// With environment variables
supershell.execute({
commands: [
"echo NODE_ENV=$NODE_ENV",
"npm run build"
],
env: {
NODE_ENV: "production",
CI: "true"
}
})
// Isolated environment
supershell.execute({
commands: ["env | wc -l"],
env: { BUILD_MODE: "isolated" },
inheritenv: false
})
// Continue on error
supershell.execute({
commands: [
"rm -f /tmp/cache/*",
"rm -f /tmp/old-logs/*"
],
onError: "continue"
})
// Result handling
let result = supershell.execute({
commands: [
{ command: "hostname", extract: "host" },
{ command: "date", extract: "timestamp" }
]
})
log(result.extractedVars.host)
log(result.extractedVars.timestamp)

SSH remote execution functions.

Scope: Network

FunctionDescription
ssh.connect()Establish an SSH connection; returns a clientId handle
ssh.execute()Execute commands over SSH
ssh.upload()Upload a file or directory via SCP
ssh.download()Download a file or directory via SCP
ssh.close()Close an SSH connection

ssh.connect() returns a clientId handle that ssh.execute() and ssh.close() can reuse across calls. ssh.upload() and ssh.download() always open and close their own connection — pass the connection parameters directly. ssh.execute() can do either: pass clientId from a previous ssh.connect(), or pass connection parameters for a one-off connection.

The following parameters describe how to reach the SSH server. Which ones are honoured depends on which function you call.

ParameterTypeDefaultDescription
hoststringSSH host (host or host:port)
userstringSSH username
passwordstringSSH password
keyPathstringPath to private key file
keyPassphrasestringPassphrase for an encrypted private key
authMethodstringinferred"key", "password", or "agent"
timeoutintConnection timeout in seconds
strictHostKeyCheckingboolfalseVerify host keys against known_hosts
knownHostsPathstringPath to a known_hosts file
agentForwardingboolfalseEnable SSH agent forwarding

Which connection parameters each function reads:

FunctionHonours
ssh.connect()All of the above
ssh.execute() (one-off, no clientId)host, user, password, keyPath
ssh.upload()host, user, password, keyPath
ssh.download()host, user, password, keyPath

For richer authentication (passphrases, agent, strict host key checking), call ssh.connect() first and pass clientId to ssh.execute(). To do the same on file transfers, use the scp namespace, which supports the full parameter set directly.

Establish a persistent SSH connection that can be reused across multiple operations.

FieldTypeDescription
successboolWhether the connection succeeded
clientIdstringHandle for subsequent ssh.execute() / ssh.close() calls
errorstringError message when success is false
// Connect with key-based auth
let conn = ssh.connect({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa"
})
log("Connected: " + conn.clientId)
// Connect with password and a short timeout
let conn = ssh.connect({
host: "10.0.0.1:22",
user: "admin",
password: "secret",
timeout: 10
})
// Verified host key, agent auth
let conn = ssh.connect({
host: "prod.example.com",
user: "deploy",
authMethod: "agent",
strictHostKeyChecking: true,
knownHostsPath: "~/.ssh/known_hosts"
})

Execute commands on a remote server via SSH. Use an existing connection (clientId) or supply basic connection parameters for a one-off call.

In addition to the connection parameters above:

ParameterTypeDefaultDescription
clientIdstringHandle from ssh.connect() (alternative to connection params)
commandsstringShell commands to execute (required)
envmapEnvironment variables
requestPTYboolfalseRequest a pseudo-terminal
ptyTerminalstringTerminal type for PTY (e.g. "xterm")
ptyWidthintPTY width in columns
ptyHeightintPTY height in rows
FieldTypeDescription
successboolWhether execution succeeded
outputstringCommand stdout
errorOutputstringCommand stderr
exitCodeintProcess exit code
errorstringError message when success is false
// Execute on an existing connection
let conn = ssh.connect({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa"
})
let result = ssh.execute({
clientId: conn.clientId,
commands: "uptime && df -h"
})
log("Output: " + result.output)
// One-off execution (no persistent connection)
let result = ssh.execute({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa",
commands: "hostname"
})
log("Server: " + result.output)
// With PTY for sudo / interactive commands
ssh.execute({
clientId: conn.clientId,
commands: "sudo systemctl restart nginx",
requestPTY: true,
ptyTerminal: "xterm"
})
ssh.close({ clientId: conn.clientId })

Upload a file or directory to a remote server via SCP. Always opens its own connection.

In addition to the connection parameters above:

ParameterTypeDefaultDescription
localPathstringLocal file or directory (required)
remotePathstringRemote destination path (required)
recursiveboolfalseUpload directories recursively
preserveModeboolfalsePreserve file permissions
FieldTypeDescription
successboolWhether the upload succeeded
bytesTransferredintNumber of bytes transferred
errorstringError message when success is false
// Upload a file
let result = ssh.upload({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa",
localPath: "./dist/app.tar.gz",
remotePath: "/tmp/app.tar.gz"
})
log("Uploaded " + result.bytesTransferred + " bytes")
// Upload a directory recursively, preserving permissions
ssh.upload({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa",
localPath: "./config/",
remotePath: "/etc/myapp/",
recursive: true,
preserveMode: true
})

Download a file or directory from a remote server via SCP. Always opens its own connection.

In addition to the connection parameters above:

ParameterTypeDefaultDescription
localPathstringLocal destination path (required)
remotePathstringRemote file or directory (required)
recursiveboolfalseDownload directories recursively
preserveModeboolfalsePreserve file permissions
FieldTypeDescription
successboolWhether the download succeeded
bytesTransferredintNumber of bytes transferred
errorstringError message when success is false
// Download a file
let result = ssh.download({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa",
remotePath: "/var/log/app.log",
localPath: "./logs/app.log"
})
log("Downloaded " + result.bytesTransferred + " bytes")
// Download a directory recursively
ssh.download({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa",
remotePath: "/etc/myapp/",
localPath: "./backup/config/",
recursive: true
})

Close a persistent SSH connection.

ParameterTypeDefaultDescription
clientIdstringHandle from ssh.connect() (required)
FieldTypeDescription
successboolWhether the connection was closed
errorstringError message when success is false
// Full lifecycle
let conn = ssh.connect({
host: "server.example.com",
user: "deploy",
keyPath: "~/.ssh/id_rsa"
})
ssh.execute({
clientId: conn.clientId,
commands: "cd /app && git pull && npm install"
})
ssh.execute({
clientId: conn.clientId,
commands: "systemctl restart myapp"
})
ssh.close({ clientId: conn.clientId })

Container operations. Shells out to podman by default; the binary path is configurable per call. The same eight functions are registered under two names — see Podman alias below.

The argument shapes work unchanged against the docker CLI — set binary: "docker" on the call if you need it.

Scope: System

The podman namespace points at the same eight functions as docker. Workflows that prefer the literal binary name can call podman.build(...) — it’s the same function. There is no behaviour difference between the two namespaces.

FunctionDescription
docker.build()Build a container image (also accepts --push to build-and-push in one step)
docker.push()Push an image to a registry
docker.pull()Pull an image from a registry
docker.run()Run a container (detached or foreground)
docker.login()Authenticate to a registry; password is sent on stdin
docker.tag()Add a new tag to an existing image
docker.inspect()Inspect an image / container / network
docker.rm()Remove one or more containers

Every function accepts these in addition to its own surface:

ParameterTypeDefaultDescription
binarystring"podman"Container CLI path
envmapProcess environment for the CLI process
timeoutint or stringWall-clock timeout

Every function returns at least these fields:

FieldTypeDescription
successboolWhether the command exited 0
exitCodeintProcess exit code
outputstringCaptured stdout
stderrstringCaptured stderr
errorstringFailure message
ParameterTypeDefaultDescription
contextstring"."Build context path
dockerfilestringContainerfile/Dockerfile path (-f)
tags[]stringImage tags (-t)
buildArgsmap--build-arg KEY=VALUE
platforms[]string--platform for multi-arch builds
targetstring--target build stage
noCacheboolfalse--no-cache
pullboolfalse--pull base images on build
pushboolfalse--push (build and push in one step)
labelsmap--label KEY=VALUE
secretsmap--secret id=<key>,src=<value>

Extra return: imageId (parsed from output when recognizable).

let r = docker.build({
context: "./services/api",
dockerfile: "build/Dockerfile",
tags: ["ghcr.io/example/api:" + sha, "ghcr.io/example/api:latest"],
buildArgs: { VERSION: version },
platforms: ["linux/amd64", "linux/arm64"],
push: true
})
if (!r.success) {
throw "build failed: " + r.stderr
}
log("built " + r.imageId)
ParameterTypeDescription
imagestringImage:tag (required)
docker.push({ image: "ghcr.io/example/api:v1.2.3" })
ParameterTypeDescription
imagestringImage:tag (required)
platformstring--platform
docker.pull({ image: "alpine:3", platform: "linux/arm64" })
ParameterTypeDefaultDescription
imagestringImage to run (required)
namestring--name
commandstringFirst positional after the image
args[]stringTrailing args
envmap--env KEY=VALUE (container env)
mounts[]map--mount entries; each: {source, target, readonly, type}
ports[]string--publish ("8080:80")
networkstring--network
workdirstring--workdir
userstring--user
entrypointstring--entrypoint
labelsmap--label
detachboolfalse-d
rmboolfalse--rm
interactiveboolfalse-i
ttyboolfalse-t
hostEnvmapEnv for the podman process itself (rare)

Mount entries:

FieldTypeDescription
sourcestringHost path or volume name
targetstringPath inside the container
readonlyboolro=true
typestringbind (default), volume, or tmpfs
// One-off migration container
docker.run({
image: "ghcr.io/example/api:" + sha,
rm: true,
env: { DATABASE_URL: dbUrl },
command: "./bin/migrate",
args: ["--apply"]
})
// Long-running detached container
let r = docker.run({
image: "registry.example.com/worker:latest",
name: "worker-1",
detach: true,
network: "app-net",
ports: ["9090:9090"],
mounts: [{ source: "/var/log/worker", target: "/var/log/worker" }],
env: { WORKER_ID: "1" }
})
ParameterTypeDescription
registrystringHostname (required)
usernamestringRequired
passwordstringRequired — sent on stdin (--password-stdin), never on the command line
docker.login({
registry: "ghcr.io",
username: vaultGet("ci/ghcr/user"),
password: vaultGet("ci/ghcr/token")
})
ParameterTypeDescription
sourcestringExisting image (required)
targetstringNew tag (required)
docker.tag({
source: "ghcr.io/example/api:dev",
target: "ghcr.io/example/api:v1.2.3"
})
ParameterTypeDescription
targetstringImage / container / network (required)
typestring--type filter
formatstring--format template

Without format, the raw JSON output is parsed and the first object is returned under data. With a format, output carries the raw text.

let info = docker.inspect({ target: "worker-1", type: "container" })
log("running: " + info.data.State.Running)
// Format-style
let status = docker.inspect({
target: "worker-1",
type: "container",
format: "{{.State.Status}}"
})
log(status.output.trim()) // "running" / "exited" / ...
ParameterTypeDescription
targets[]stringContainer names or IDs (required)
forcebool--force
volumesbool--volumes (remove anonymous volumes)

Extra return: removed ([]string of container IDs that were dropped).

docker.rm({ targets: ["worker-1", "worker-2"], force: true, volumes: true })

Alias for the docker namespace. Same eight functions, same parameters, same return shapes. The underlying binary that gets shelled out to is podman by default — set binary: "docker" on any call if you prefer.

There is no behaviour difference between calling podman.build(...) and docker.build(...). Pick whichever name reads better in your script.

FunctionDescription
podman.build()Build a container image
podman.push()Push an image to a registry
podman.pull()Pull an image from a registry
podman.run()Run a container
podman.login()Authenticate to a registry (password via stdin)
podman.tag()Add a new tag to an image
podman.inspect()Inspect an image / container / network
podman.rm()Remove one or more containers

See docker.md for the full per-function reference. Every example there works verbatim if you replace docker. with podman..

podman.login({
registry: "ghcr.io",
username: vaultGet("ci/ghcr/user"),
password: vaultGet("ci/ghcr/token")
})
let build = podman.build({
context: "./api",
tags: ["ghcr.io/example/api:" + sha],
push: true
})
log("built " + build.imageId)

Kubernetes operations via kubectl. The same seven functions are registered under two names: k8s (short) and kubectl (matches the binary). Use whichever reads better — they’re the same functions.

Scope: Network

FunctionDescription
k8s.apply()Apply a manifest (inline / file / kustomize)
k8s.delete()Delete resources by ref / selector / file
k8s.get()Read resources (auto-parses JSON into data)
k8s.exec()Run a command inside a pod
k8s.rolloutStatus()Block until a rollout completes
k8s.logs()Fetch container logs
k8s.scale()Scale a deployment / statefulset / replicaset

Every function accepts:

ParameterTypeDefaultDescription
binarystring"kubectl"kubectl binary path
kubeconfigstring--kubeconfig
contextstring--context
namespacestring--namespace
envmapProcess env for kubectl
timeoutint or stringWall-clock timeout (also --timeout for rolloutStatus)

Every function returns:

FieldTypeDescription
successboolWhether kubectl exited 0
exitCodeintExit code
outputstringCaptured stdout
stderrstringCaptured stderr
errorstringFailure reason
ParameterTypeDescription
manifeststringInline YAML/JSON — piped via stdin
filestringPath on disk (-f)
kustomizestringPath to a kustomize dir (-k)
serverSidebool--server-side
forcebool--force
validatebool--validate=... (unset → kubectl default)
dryRunstring"client" / "server" / "none"
fieldManagerstring--field-manager=<name>

Extra return: applied ([]string of refs).

k8s.apply({
namespace: "app",
file: "deploy/app.yaml",
serverSide: true
})
// Inline manifest, piped to stdin
k8s.apply({
namespace: "default",
manifest: `
apiVersion: v1
kind: ConfigMap
metadata: { name: feature-flags }
data: { enable_new_dashboard: "true" }
`
})

Provide at least one of: (kind + name), selector, file, or manifest.

ParameterTypeDescription
kind, namestring, stringSingle resource ref
selectorstring-l <label-selector>
filestring-f <path>
manifeststringInline YAML/JSON
forcebool--force
waitbool--wait=... (unset → kubectl default)
gracePeriodint--grace-period=<seconds>
ignoreNotFoundbool--ignore-not-found=true

Extra return: deleted ([]string of refs).

k8s.delete({
namespace: "tests",
kind: "pod",
selector: "owner=integration-tests",
ignoreNotFound: true
})
ParameterTypeDescription
kindstringRequired
namestringOptional — empty means “list”
selectorstring-l
allNamespacesbool-A
formatstring-o (when empty defaults to json and data is parsed)
showLabelsbool--show-labels

Extra return: data — parsed JSON object (single resource) or array (list). Set only when format is empty.

// Single resource
let pod = k8s.get({ namespace: "app", kind: "pod", name: "api-0" })
log("phase: " + pod.data.status.phase)
// List with selector
let pods = k8s.get({ namespace: "app", kind: "pod", selector: "app=api" })
log("api pods: " + pods.data.items.length)
// Custom format — raw text in `output`, no `data`
let names = k8s.get({ namespace: "app", kind: "pod", format: "name" })
log(names.output)
ParameterTypeDescription
podstringRequired
containerstring-c <container>
commandstringFirst positional after --
args[]stringTrailing positionals
stdinbool-i
ttybool-t
let r = k8s.exec({
namespace: "app",
pod: "api-7f9b8c4-xyz",
container: "api",
command: "./bin/migrate",
args: ["--apply"]
})
if (!r.success) {
throw "migrate failed: " + r.stderr
}
ParameterTypeDescription
kindstringdeployment (default) / statefulset / daemonset
namestringRequired
watchbool-w=... (unset → kubectl default)

The common timeout also becomes --timeout= for kubectl. Recommended to always set a timeout when calling this function.

k8s.rolloutStatus({
namespace: "app",
name: "api",
timeout: "5m"
})
ParameterTypeDescription
podstringRequired
containerstring-c
sincestring--since= (e.g. "5m", "1h")
sinceTimestring--since-time= (RFC3339)
tailint--tail (lines)
followbool-f — ⚠ blocks until the pod exits
previousbool-p
timestampsbool--timestamps
allContainersbool--all-containers
let logs = k8s.logs({
namespace: "app",
pod: "api-0",
container: "api",
since: "5m",
tail: 200
})
log(logs.output)
ParameterTypeDescription
kindstringRequired
namestringRequired
replicasintTarget count
currentintOptional precondition: --current-replicas=<n>
k8s.scale({
namespace: "app",
kind: "deployment",
name: "api",
replicas: 5,
current: 3 // optional precondition
})

Alias for the k8s namespace. Same seven functions, same parameters, same return shapes. Use whichever name reads better.

There is no behaviour difference between calling kubectl.apply(...) and k8s.apply(...).

FunctionDescription
kubectl.apply()Apply a manifest
kubectl.delete()Delete resources
kubectl.get()Read resources
kubectl.exec()Run a command inside a pod
kubectl.rolloutStatus()Block until a rollout completes
kubectl.logs()Fetch container logs
kubectl.scale()Scale a deployment / statefulset / replicaset

See k8s.md for the full per-function reference. Every example there works verbatim with kubectl. in place of k8s..

kubectl.apply({
namespace: "app",
file: "deploy/app.yaml",
serverSide: true
})
kubectl.rolloutStatus({
namespace: "app",
name: "api",
timeout: "5m"
})