Command Transitions – The Complete Guide to Shell Execution in Agentic Nets
The Command transition enables Petri nets to execute shell commands, scripts, and file system operations through the agentic-net-executor service. While LLM transitions process AI prompts and Agent transitions enable autonomous reasoning, Command transitions provide direct system execution – running bash commands, scripts, and file operations with full result capture.
In this comprehensive guide, we’ll explore every capability of Command transitions:
- Bash execution – single commands, multi-line scripts, environment variables
- File system operations – readFile, writeFile, listDir, exists, mkdir, delete, stat
- Batch processing – multiple commands executed together with aggregated results
- Result capture – stdout, stderr, exit codes, execution duration
- Timeout handling – configurable per-command timeouts with graceful termination
- Error routing – conditional emit based on success/failure status
- Security controls – command blacklisting for dangerous operations
What Makes Command Transitions Different?
Unlike LLM/Agent transitions that process natural language, Command transitions execute concrete system operations. They:
- Execute directly – run bash commands or file operations via ProcessBuilder
- Capture full output – stdout, stderr, exit code, and execution timing
- Support multiple executors – bash for shell commands, fs for file operations
- Batch operations – group multiple commands by executor for efficient execution
- Return structured results – standardized CommandResult format with metadata
This makes Command transitions ideal for automation tasks, CI/CD pipelines, system administration, and external tool integration.
Architecture Overview
Command transitions run on the agentic-net-executor service (port 8084), separate from agentic-net-master:
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ agentic-net-node │ │ agentic-net-executor│ │ System Shell │
│ (port 8080) │───▶│ (port 8084) │───▶│ bash / fs │
│ Token Store │ │ Command Handler │ │ Operations │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│ │
│ ▼
│ ┌──────────────────┐
└──────────────│ Result Tokens │
└──────────────────┘
Command Token Schema
Every Command token follows this standardized schema:
{
"kind": "command", // Always "command" for command tokens
"id": "unique-cmd-id", // Unique command identifier (required)
"executor": "bash", // Target executor: "bash" or "fs"
"command": "exec", // Command type: "exec", "script", "readFile", etc.
"args": { // Command-specific arguments
"command": "echo Hello", // For bash: the actual shell command
"workingDir": "/path/to/dir",
"timeoutMs": 60000, // Default 60s, max 600000 (10 min)
"captureStderr": true, // Merge stderr into stdout (default true)
"env": {"KEY": "value"} // Optional environment variables
},
"expect": "text", // Expected return format: "json", "text", "binary"
"meta": { // Optional metadata for correlation
"correlationId": "req-001"
}
}
Required Fields
| Field | Type | Description |
|---|---|---|
kind |
string | Must be "command" |
id |
string | Unique identifier for this command |
executor |
string | Executor type: "bash" or "fs" |
command |
string | Operation type (executor-specific) |
args |
object | Command arguments |
Supported Executors
Bash Executor
The bash executor runs shell commands via ProcessBuilder("bash", "-c", command):
Command Types
exec– Execute a single shell commandscript– Execute a multi-line shell script
Bash Args Structure
{
"command": "ls -la /tmp", // The shell command to execute
"workingDir": "/home/user", // Working directory (optional)
"timeoutMs": 30000, // Timeout in milliseconds
"captureStderr": true, // Merge stderr into stdout
"env": { // Additional environment variables
"MY_VAR": "value",
"PATH": "/custom/bin:$PATH"
}
}
Example: Simple Echo Command
{
"kind": "command",
"id": "echo-001",
"executor": "bash",
"command": "exec",
"args": {
"command": "echo 'Hello from AgenticOS!'",
"timeoutMs": 10000
},
"expect": "text"
}
Example: Script with Multiple Lines
{
"kind": "command",
"id": "script-001",
"executor": "bash",
"command": "script",
"args": {
"command": "#!/bin/bash\nfor i in 1 2 3; do\n echo \"Iteration $i\"\ndone",
"timeoutMs": 30000
},
"expect": "text"
}
Example: Environment Variables
{
"kind": "command",
"id": "env-001",
"executor": "bash",
"command": "exec",
"args": {
"command": "echo \"User: $MY_USER, App: $MY_APP\"",
"env": {
"MY_USER": "alice",
"MY_APP": "agenticos"
},
"timeoutMs": 10000
},
"expect": "text"
}
File System Executor
The fs executor provides file system operations without shell command parsing:
Command Types
| Command | Description | Args |
|---|---|---|
readFile |
Read file contents | path, encoding |
writeFile |
Write file contents | path, content, encoding |
listDir |
List directory contents | path, recursive |
exists |
Check if path exists | path |
mkdir |
Create directory | path, recursive |
delete |
Delete file/directory | path, recursive |
stat |
Get file/directory stats | path |
Example: Read File
{
"kind": "command",
"id": "read-001",
"executor": "fs",
"command": "readFile",
"args": {
"path": "/etc/hosts",
"encoding": "utf-8"
},
"expect": "text"
}
Example: List Directory
{
"kind": "command",
"id": "list-001",
"executor": "fs",
"command": "listDir",
"args": {
"path": "/tmp",
"recursive": false
},
"expect": "json"
}
Example: Check File Exists
{
"kind": "command",
"id": "exists-001",
"executor": "fs",
"command": "exists",
"args": {
"path": "/var/log/syslog"
},
"expect": "json"
}
Command Result Schema
Every command execution returns a structured CommandResult:
{
"id": "echo-001", // Matches input command ID
"status": "SUCCESS", // SUCCESS, FAILED, TIMEOUT, SKIPPED
"output": {
"exitCode": 0, // Process exit code (bash only)
"stdout": "Hello from AgenticOS!",
"stderr": "",
"success": true,
"command": "echo 'Hello from AgenticOS!'"
},
"error": null, // Error message if failed
"durationMs": 15, // Execution time in milliseconds
"completedAt": "2026-01-06T10:00:00Z",
"meta": { // Echoed from input
"correlationId": "req-001"
}
}
Status Values
| Status | Description |
|---|---|
SUCCESS |
Command completed successfully (exit code 0) |
FAILED |
Command failed (non-zero exit code or error) |
TIMEOUT |
Command exceeded configured timeout |
SKIPPED |
Command was skipped (validation failure) |
Anatomy of a Command Transition Inscription
Every Command transition inscription follows this structure:
{
"id": "t-execute-commands",
"kind": "command",
"mode": "SINGLE",
"presets": {
"commands": {
"placeId": "command-queue",
"host": "myModel@localhost:8080",
"arcql": "FROM $ WHERE $.kind==\"command\"",
"take": "ALL",
"consume": true
}
},
"postsets": {
"results": {
"placeId": "results-queue",
"host": "myModel@localhost:8080"
}
},
"action": {
"type": "command",
"inputPlace": "commands",
"groupBy": "executor",
"dispatch": [
{ "executor": "bash", "channel": "default" },
{ "executor": "fs", "channel": "default" }
],
"await": "ALL",
"timeoutMs": 300000
},
"emit": [
{ "to": "results", "from": "@response", "when": "success" }
]
}
Key Inscription Fields
| Field | Description |
|---|---|
kind: "command" |
Identifies this as a Command transition |
action.type: "command" |
Specifies the Command action handler |
action.inputPlace |
Name of preset containing command tokens |
action.groupBy |
Group commands by executor type |
action.dispatch |
Routing rules for each executor |
action.await |
"ALL" to wait for all commands |
action.timeoutMs |
Overall transition timeout |
Batch Result Structure
When multiple commands are executed, results are aggregated into a BatchResult:
{
"batchPrefix": "t-execute-commands-1704542400000",
"batchResults": [
{
"executor": "bash",
"results": [
{ "id": "cmd-1", "status": "SUCCESS", "output": {...}, "durationMs": 15 },
{ "id": "cmd-2", "status": "SUCCESS", "output": {...}, "durationMs": 23 }
],
"totalCount": 2,
"successCount": 2,
"failedCount": 0
},
{
"executor": "fs",
"results": [
{ "id": "cmd-3", "status": "SUCCESS", "output": {...}, "durationMs": 5 }
],
"totalCount": 1,
"successCount": 1,
"failedCount": 0
}
],
"success": true
}
Real-World Use Cases
1. CI/CD Pipeline Automation
Execute build, test, and deployment commands as agentic process steps:
// Build step command token
{
"kind": "command",
"id": "build-step",
"executor": "bash",
"command": "exec",
"args": {
"command": "npm run build",
"workingDir": "/app/project",
"timeoutMs": 300000,
"env": { "NODE_ENV": "production" }
},
"expect": "text",
"meta": { "pipeline": "release-v2.1", "step": "build" }
}
2. Log File Analysis
Read and analyze log files for error patterns:
{
"kind": "command",
"id": "analyze-logs",
"executor": "bash",
"command": "exec",
"args": {
"command": "grep -c 'ERROR' /var/log/app.log",
"timeoutMs": 30000
},
"expect": "text"
}
3. System Health Checks
Monitor disk space, memory, and process status:
{
"kind": "command",
"id": "health-check",
"executor": "bash",
"command": "exec",
"args": {
"command": "df -h / | tail -1 | awk '{print $5}'",
"timeoutMs": 10000
},
"expect": "text",
"meta": { "check": "disk-usage" }
}
4. Database Backup
Execute database dump operations with proper credentials:
{
"kind": "command",
"id": "db-backup",
"executor": "bash",
"command": "exec",
"args": {
"command": "pg_dump $DB_NAME | gzip > /backups/db-$(date +%Y%m%d).sql.gz",
"env": {
"DB_NAME": "production",
"PGPASSWORD": "${secrets.db_password}"
},
"timeoutMs": 600000
},
"expect": "text"
}
5. AI CLI Tool Integration
Invoke Claude Code or other AI CLIs from agentic processes:
{
"kind": "command",
"id": "claude-analysis",
"executor": "bash",
"command": "exec",
"args": {
"command": "export PATH=$HOME/.local/bin:$PATH && claude -p 'Analyze this file for security issues' --no-session-persistence < /dev/null",
"workingDir": "/project",
"timeoutMs": 180000,
"env": { "HOME": "/Users/developer" }
},
"expect": "text"
}
Important: Always redirect stdin with < /dev/null when running interactive CLIs to prevent blocking.
Security Considerations
The BashCommandHandler includes a security blacklist to prevent dangerous operations:
Blacklisted Commands
rm -rf /– Recursive deletion of rootsudo– Privilege escalationmkfs– Filesystem formattingdd if=/dev/zero– Disk overwriting:(){ :|:& };:– Fork bomb
Commands matching blacklist patterns are rejected with SKIPPED status.
Best Practices
- Use absolute paths – Avoid path traversal vulnerabilities
- Validate inputs – Sanitize any user-provided data in commands
- Set timeouts – Always configure appropriate timeouts
- Limit permissions – Run executor service with minimal privileges
- Audit logging – Enable logging for command execution audit trail
API Reference
Register Transition
POST http://localhost:8084/api/pnml/transitions
Content-Type: application/json
{
"transitionId": "my-command-transition",
"inscription": { ... },
"autoStart": true,
"tags": { "type": "command" }
}
Fire Transition Manually
POST http://localhost:8084/api/pnml/transitions/{transitionId}/fireOnce
Content-Type: application/json
{
"modelId": "my-model",
"boundTokens": {
"commands": [
{
"kind": "command",
"id": "test-001",
"executor": "bash",
"command": "exec",
"args": { "command": "echo Hello", "timeoutMs": 30000 },
"expect": "text"
}
]
}
}
Delete Transition
DELETE http://localhost:8084/api/pnml/transitions/{transitionId}
Error Handling Patterns
Conditional Emit Based on Status
{
"emit": [
{ "to": "success-queue", "from": "@response", "when": "success" },
{ "to": "error-queue", "from": "@response", "when": "error" }
]
}
Handling Timeouts
Commands that exceed their timeoutMs are terminated and return:
{
"id": "slow-cmd",
"status": "TIMEOUT",
"output": null,
"error": "Command timed out after 10000ms",
"durationMs": 10000
}
Handling Non-Zero Exit Codes
Failed commands return with FAILED status:
{
"id": "failing-cmd",
"status": "FAILED",
"output": {
"exitCode": 1,
"stdout": "",
"stderr": "Error: File not found",
"success": false
},
"error": null,
"durationMs": 15
}
Integration with Other Transitions
Command transitions work seamlessly with other transition types:
- Agent → Command: Agent creates command tokens, Command executes them
- Command → LLM: Command output analyzed by LLM for insights
- MAP → Command: Transform data into command tokens
- Command → HTTP: Command results sent to external webhooks
Summary
Command transitions provide direct system execution within Agentic Nets. Key capabilities:
- Shell execution via bash executor with full environment control
- File operations via fs executor without shell parsing
- Batch processing with grouped results by executor
- Complete output capture including stdout, stderr, exit codes
- Timeout handling with configurable per-command limits
- Security controls via command blacklisting
- Integration patterns with other transition types
For automation, CI/CD, system administration, and external tool integration, Command transitions are the essential building block in your Agentic Agentic nets.