<!--
hoody-terminal Subskill (sdk)
Auto-generated by Hoody Skills Generator
Generated: 2026-05-06T20:08:51.581Z
Model: mimo-v2.5-pro + fixer:mimo-v2.5-pro
Mode: sdk


Tokens: 9820

DO NOT EDIT MANUALLY - Changes will be overwritten on next generation
-->

# hoody-terminal Subskill

## Overview

**hoody-terminal** provides HTTP-accessible terminal sessions that are multiplayer by default. Every terminal session is a REST endpoint—create, execute, interact, and monitor terminals programmatically without persistent connections.

### When to Use

- **Command execution**: Run shell commands synchronously or asynchronously in container environments
- **Terminal automation**: Script interactive CLI applications using snapshot/find/wait/press primitives
- **System monitoring**: Query processes, ports, resources, and daemon configurations
- **Multiplayer sessions**: Share terminal sessions across multiple clients simultaneously
- **Remote access**: Connect to SSH sessions through the terminal proxy with SOCKS5 support

### Service Philosophy

Terminal sessions are first-class HTTP resources. Each session has a unique `terminal_id` and supports concurrent access. Commands execute asynchronously by default—submit via `execute`, poll via `result`. The service wraps libvterm for accurate terminal emulation, enabling screen-aware automation through snapshots and pattern matching.

### Authentication

All endpoints except `/api/v1/terminal/health` require authentication via the SDK. The health endpoint is unauthenticated and always returns HTTP 200.

### Base URL

```
https://{projectId}-{containerId}-terminal-{serviceId}.{node}.containers.hoody.icu
```

Use the SDK client which handles URL construction automatically.

---

## Common Workflows

### 1. Health Check

Verify the terminal service is running:

```
const health = await client.terminal.health.check();
```

Response:

```
{
  "status": "healthy",
  "service": "hoody-terminal",
  "version": "1.0.0",
  "uptime": 3600,
  "timestamp": "2025-01-15T10:30:00Z",
  "checks": {
    "database": "ok",
    "memory": "ok"
  }
}
```

### 2. Create Session and Execute Command

The standard pattern for running commands:

```
// Create or reuse a terminal session
const session = await client.terminal.sessions.create({
  terminal_id: "my-session"
});

// Execute a command
const execution = await client.terminal.execution.execute({
  command: "ls -la /tmp",
  terminal_id: "my-session"
});

// Poll for results
const result = await client.terminal.execution.getResult(execution.command_id);
```

Execute response:

```
{
  "command_id": "cmd-abc123",
  "terminal_id": "my-session",
  "status": "running",
  "pid": 12345
}
```

Result response:

```
{
  "command_id": "cmd-abc123",
  "status": "completed",
  "exit_code": 0,
  "stdout": "total 8\ndrwxrwxrwt 2 root root 4096 Jan 15 10:30 .\n",
  "stderr": "",
  "duration_ms": 45
}
```

### 3. Ephemeral Command Execution

Execute a command without managing session lifecycle:

```
const execution = await client.terminal.execution.execute({
  command: "echo 'Hello World'",
  ephemeral: true
});

const result = await client.terminal.execution.getResult(execution.command_id);
```

### 4. Write Input to Terminal

Send keyboard input directly to a session's PTY (`write` is a direct method on `client.terminal`, not a nested sub-resource):

```
await client.terminal.write("my-session", {
  data: "y\n"
});
```

### 5. List Active Sessions

```
const sessions = await client.terminal.sessions.list();
```

Response:

```
[
  {
    "terminal_id": "my-session",
    "created_at": "2025-01-15T10:00:00Z",
    "pid": 12340,
    "shell": "/bin/bash",
    "recent_commands": [
      {
        "command_id": "cmd-abc123",
        "command": "ls -la /tmp",
        "status": "completed"
      }
    ]
  }
]
```

### 6. Get Command History

```
const history = await client.terminal.sessions.listHistory({ terminal_id: "my-session" });
```

### 7. Capture Terminal Screenshot

Convert terminal output to an image:

```
const screenshot = await client.terminal.sessions.captureScreenshot("my-session", {
  format: "png",
  foreground: "#ffffff",
  background: "#1e1e1e",
  fontsize: 14,
  save: true // stores to persistent storage; URL returned in response
});
```

### 8. Get Raw Terminal Output

Retrieve the terminal buffer in various formats:

```
const raw = await client.terminal.sessions.getRawOutput({
  terminal_id: "my-session",
  format: "text",
  tail: 100
});
```

### 9. Abort Running Command

Cancel a command with graceful (SIGINT) or force (SIGKILL) mode:

```
// Graceful abort (Ctrl+C equivalent)
await client.terminal.abort({ command_id: "cmd-abc123" });

// Force abort
await client.terminal.abort("cmd-abc123", { force: true });
```

### 10. Destroy Session

Clean up when done:

```
await client.terminal.sessions.delete({ terminal_id: "my-session" });
```

---

## Advanced Operations

### Terminal Automation Pipeline

Build robust automation using the snapshot/find/wait/press primitives:

```
// 1. Get current screen state
const snapshot = await client.terminal.terminalAutomation.getTerminalSnapshot("my-session", {
  include_colors: false,
  include_highlights: false
});

// 2. Search for a pattern
const matches = await client.terminal.terminalAutomation.findInTerminal(
  "my-session",
  "Password:",
  {
    scope: "screen",
    limit: 1,
    case_insensitive: false
  }
);

// 3. Wait for a condition before proceeding
const waitResult = await client.terminal.terminalAutomation.waitForTerminal("my-session", {
  mode: "regex",
  pattern: "\\$\\s*$",
  timeout_ms: 10000,
  debounce_ms: 500
});

// 4. Send key presses
await client.terminal.terminalAutomation.pressTerminalKeys("my-session", {
  keys: ["Enter"]
});

// 5. Paste text with bracketed mode
await client.terminal.terminalAutomation.pasteTerminalText("my-session", {
  text: "my-secret-password",
  bracketed: true
});
```

Snapshot response:

```
{
  "lines": ["$ ls -la", "total 8", "drwxr-xr-x 3 user user 4096 Jan 15 10:30 ."],
  "cursor": { "row": 3, "col": 0 },
  "title": "user@container:~",
  "alt_screen": false,
  "dimensions": { "rows": 24, "cols": 80 }
}
```

Find response:

```
{
  "hits": [
    {
      "row": 0,
      "col": 2,
      "text": "Password:",
      "match": "Password:"
    }
  ],
  "total": 1
}
```

### SSH Session with SOCKS5 Proxy

Connect to remote hosts through a SOCKS5 proxy:

```
const session = await client.terminal.sessions.create({
  terminal_id: "remote-ssh",
  ssh_host: "192.168.1.100",
  ssh_user: "admin",
  ssh_port: 22,
  ssh_key: "/hoody/storage/keys/id_rsa",
  socks5_host: "proxy.example.com",
  socks5_port: "1080"
});

const execution = await client.terminal.execution.execute({
  command: "uname -a",
  terminal_id: "remote-ssh"
});
```

### System Monitoring

Query system state through dedicated endpoints:

```
// List all processes with filtering
const processes = await client.terminal.system.listProcesses({
  sort: "cpu",
  limit: 10,
  filter: "node"
});

// Get specific process details
const process = await client.terminal.system.getProcess(1234);

// List listening ports
const ports = await client.terminal.system.listPorts({
  protocol: "tcp",
  hoody_only: true
});

// Get system resources
const resources = await client.terminal.system.getResources();

// Get display information
const displays = await client.terminal.system.getDisplayInfo();

// Get daemon configuration
const daemons = await client.terminal.system.getDaemonConfig();
```

Resources response:

```
{
  "cpu": { "usage_percent": 23.5, "cores": 4 },
  "memory": { "total_mb": 8192, "used_mb": 4096, "usage_percent": 50.0 },
  "disk": { "total_gb": 100, "used_gb": 45, "usage_percent": 45.0 },
  "network": { "interfaces": ["eth0", "lo"] },
  "uptime_seconds": 86400
}
```

### Process Signal Management

Send Unix signals to processes:

```
// Send SIGTERM by PID
await client.terminal.system.sendSignal({
  pid: 1234,
  signal: "SIGTERM"
});

// Send SIGKILL by process name (matches multiple)
await client.terminal.system.sendSignal({
  name: "node",
  signal: "SIGKILL"
});
```

### System Shutdown/Reboot

```
// Shutdown with 60 second delay
await client.terminal.system.shutdown({ delay: 60 });

// Immediate reboot
await client.terminal.system.reboot();
```

### WebSocket Real-Time Connection

For interactive terminal sessions with real-time I/O:

```
client.terminal.sessions.connectWebSocket({
  terminal_id: "interactive-session",
  readonly: false
});
```

### Automation Metrics and State

Monitor automation resource usage:

```
// Global automation metrics
const metrics = await client.terminal.terminalAutomation.getAutomationMetrics();

// Per-session automation state
const state = await client.terminal.terminalAutomation.getSessionAutomationState({ terminal_id: "my-session" });

// List supported key names
const keys = await client.terminal.terminalAutomation.listSupportedKeys();
```

Metrics response:

```
{
  "active_vterm_sessions": 5,
  "memory_used_mb": 12.5,
  "memory_cap_mb": 512,
  "active_waiters": 2,
  "max_sessions": 100
}
```

### Error Recovery Pattern

Handle command failures gracefully:

```
async function executeWithRetry(
  command: string,
  terminalId: string,
  maxRetries: number = 3
): Promise<any> {
  for (let attempt = 1; attempt <= maxRetries; attempt++) {
    const execution = await client.terminal.execution.execute({
      command,
      terminal_id: terminalId
    });

    // Wait for completion
    const result = await client.terminal.terminalAutomation.waitForTerminal(terminalId, {
      mode: "stable", // waits until terminal output is unchanged for debounce_ms
      debounce_ms: 1000,
      timeout_ms: 30000
    });

    const cmdResult = await client.terminal.execution.getResult(execution.command_id);

    if (cmdResult.exit_code === 0) {
      return cmdResult;
    }

    if (attempt < maxRetries) {
      console.log(`Attempt ${attempt} failed, retrying...`);
      await new Promise(r => setTimeout(r, 1000 * attempt));
    }
  }

  throw new Error(`Command failed after ${maxRetries} attempts`);
}
```

### Performance Considerations

- **Session reuse**: Create sessions once and reuse for multiple commands to avoid startup overhead
- **Ephemeral sessions**: Use `ephemeral: true` for one-off commands to auto-cleanup
- **Polling intervals**: For long-running commands, implement exponential backoff when polling results
- **Buffer management**: Use `tail` parameter on raw output to limit response size
- **Automation limits**: Monitor `getAutomationMetrics()` to avoid exceeding session caps

---

## Quick Reference

### Essential Endpoints

| Operation | SDK Method | HTTP |
|-----------|-----------|------|
| Health check | `client.terminal.health.check()` | GET `/api/v1/terminal/health` |
| Create session | `client.terminal.sessions.create(data)` | POST `/api/v1/terminal/create` |
| Execute command | `client.terminal.execution.execute(data)` | POST `/api/v1/terminal/execute` |
| Get result | `client.terminal.execution.getResult(command_id)` | GET `/api/v1/terminal/result/{command_id}` |
| Write input | `client.terminal.write(terminal_id, data)` | POST `/api/v1/terminal/write` |
| List sessions | `client.terminal.sessions.list()` | GET `/api/v1/terminal/sessions` |
| Delete session | `client.terminal.sessions.delete(terminal_id)` | DELETE `/api/v1/terminal/{terminal_id}` |
| Screenshot | `client.terminal.sessions.captureScreenshot(terminal_id)` | GET `/api/v1/terminal/screenshot` |
| Snapshot | `client.terminal.terminalAutomation.getTerminalSnapshot(terminal_id)` | GET `/api/v1/terminal/snapshot` |
| Find pattern | `client.terminal.terminalAutomation.findInTerminal(terminal_id, pattern)` | GET `/api/v1/terminal/find` |
| Wait condition | `client.terminal.terminalAutomation.waitForTerminal(terminal_id, data)` | POST `/api/v1/terminal/wait` |
| System resources | `client.terminal.system.getResources()` | GET `/api/v1/system/resources` |
| List processes | `client.terminal.system.listProcesses()` | GET `/api/v1/system/processes` |

### Common Parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `terminal_id` | string | Session identifier (created or reused) |
| `command` | string | Shell command to execute |
| `ephemeral` | boolean | Auto-destroy session after command |
| `command_id` | string | Unique execution identifier |
| `pattern` | string | PCRE2 regex for terminal search |
| `timeout_ms` | integer | Maximum wait duration |
| `debounce_ms` | integer | Stability detection window |

### Response Patterns

**Command execution**: Returns `command_id` immediately, poll `getResult` for output
**Session operations**: Return session metadata with `terminal_id`
**System queries**: Return JSON arrays or objects with requested data
**Automation**: Return screen state, matches, or wait results