Shell
Execute shell commands and manage their full lifecycle on the machine where the Tensorify CLI runner is running — run synchronously, start background processes, poll status, read output, wait for completion, and terminate processes.
Runs on the CLI runner only — requires tensorify runner start on your machine. Commands execute in the runner's shell environment with the permissions of the runner process. No authentication is required.
Each node run executes a single operation. Background process state is tracked in memory for the lifetime of the runner process.
Run a command synchronously and wait for it to finish. Returns stdout, stderr, exit code, and execution duration.
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | exec |
| command | string | Yes | Shell command to execute. Supports {{ }} bindings. |
| working_directory | string | No | Working directory for the command. |
| timeout | number | No | Timeout in seconds (default 30). Set to 0 for no limit. |
Output:
{
"stdout": "Hello, world\n",
"stderr": "",
"exit_code": 0,
"pid": 12345,
"status": "completed",
"duration_ms": 142,
"output_tail": "Hello, world\n",
"success": true
}
If the command exceeds the timeout, the process is killed and the node returns an error with status: "timeout".
Start a command in the background without blocking. Output is written to temporary files. Returns the process ID immediately.
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | start |
| command | string | Yes | Shell command to run in the background. |
| working_directory | string | No | Working directory for the command. |
| max_concurrent_processes | number | No | Maximum background processes allowed at once (default 5). Not exposed to AI agent tools. |
Output:
{
"stdout": "",
"stderr": "",
"exit_code": null,
"pid": 12346,
"status": "running",
"duration_ms": 0,
"output_tail": "",
"success": true
}
Use the returned pid with status, output, wait, or kill operations.
Check whether a background process is still running and get a tail of its combined stdout/stderr output (last 4 KB).
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | status |
| pid | number | Yes | Process ID from a start operation. Supports bindings. |
Output:
{
"stdout": "",
"stderr": "",
"exit_code": null,
"pid": 12346,
"status": "running",
"duration_ms": 5200,
"output_tail": "Processing batch 3...\n",
"success": true
}
When the process has finished, status is "completed" and exit_code is set.
Read the full stdout and stderr captured from a background process so far.
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | output |
| pid | number | Yes | Process ID from a start operation. Supports bindings. |
Output:
{
"stdout": "line 1\nline 2\n",
"stderr": "warning: deprecated flag\n",
"exit_code": null,
"pid": 12346,
"status": "running",
"duration_ms": 8100,
"output_tail": "line 2\n",
"success": true
}
Block until a background process completes. Returns full stdout, stderr, and exit code.
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | wait |
| pid | number | Yes | Process ID from a start operation. Supports bindings. |
| timeout | number | No | Maximum wait time in seconds (default 30). Set to 0 for no limit. |
Output:
{
"stdout": "done\n",
"stderr": "",
"exit_code": 0,
"pid": 12346,
"status": "completed",
"duration_ms": 15300,
"output_tail": "done\n",
"success": true
}
If the wait exceeds the timeout, the process continues running and the node returns an error with status: "running".
Send SIGTERM to a background process. If the process does not exit within 5 seconds, it is force-killed.
Config:
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| operation | enum | Yes | kill |
| pid | number | Yes | Process ID from a start operation. Supports bindings. |
Output:
{
"stdout": "",
"stderr": "",
"exit_code": -15,
"pid": 12346,
"status": "completed",
"duration_ms": 16200,
"output_tail": "",
"success": true,
"signal": "SIGTERM"
}
All operations emit a result object on the result handle, accessible downstream as {{ shell.* }}:
| Field | Type | Description |
|-------|------|-------------|
| stdout | string | Standard output |
| stderr | string | Standard error |
| exit_code | number | null | Process exit code (null while running) |
| pid | number | null | Process ID |
| status | string | "running", "completed", or "timeout" |
| duration_ms | number | Elapsed time in milliseconds |
| output_tail | string | Last 4 KB of stdout (or combined tail for status) |
| success | boolean | true for exit code 0 on exec/wait; true for successful lifecycle ops |
| signal | string | Signal sent (kill only), e.g. "SIGTERM" |
- Exec: If the command exceeds
timeout, the process is killed immediately. Partial stdout/stderr is returned withstatus: "timeout". - Wait: If the process has not finished within
timeout, the node errors but the background process keeps running. Usekillto terminate it manually. - Set
timeoutto0to disable the limit for exec or wait.
Background processes and their output files are tracked in the runner's in-memory registry. They persist for the lifetime of the tensorify runner start process. Restarting the runner clears all tracked background processes.
The max_concurrent_processes setting (default 5) prevents runaway background task creation. Starting a new process when the limit is reached returns an error.
Connect a Shell node to an AI Agent Tools handle to let the agent run commands on the runner machine.
Use Allowed Operations (Agent) to restrict which lifecycle operations the agent can use — for example, allow only exec for one-shot commands without background process management. Operations not in the allowed list are rejected at runtime. This setting is excluded from the tool schema.
When used as a tool, the agent supplies operation, command or pid, and optional working_directory and timeout as tool arguments.
Run a database backup script synchronously and branch on the exit code:
- Add a Shell node.
- Set Operation to
exec. - Set Command to
pg_dump mydb > /backups/mydb-$(date +%Y%m%d).sql. - Set Timeout to
300(5 minutes). - Connect the On Error branch to handle non-zero exit codes or timeouts.
Access results in downstream nodes:
{{ shell.stdout }}
{{ shell.exit_code }}
{{ shell.success }}
For long-running tasks, chain start → status (poll) → wait → output using the pid from the start step.
