Skip to content

Machine Output

ferman supports two machine-readable output modes:

  • --json for standard automation, scripts, and CI
  • --toon for compact, LLM-oriented structured output

Use these modes when you need predictable parsing instead of human-readable terminal text.

JSON Mode

JSON mode is the default structured output format for integrations.

bash
ferman 3000 --json

Example success result:

json
{
  "ok": true,
  "code": "PORT_INSPECTED",
  "port": 3000,
  "busy": true,
  "processes": [
    {
      "pid": 1234,
      "name": "node"
    }
  ],
  "action": "inspected",
  "message": "Dry mode active. No processes were terminated."
}

Example error result:

json
{
  "ok": false,
  "code": "INVALID_PORT",
  "message": "Port must be a whole number."
}

TOON Mode

TOON mode is useful when the output is consumed by LLM-oriented workflows and token efficiency matters more than ecosystem ubiquity.

bash
ferman 3000 --toon

Example success result:

toon
ok: true
code: PORT_INSPECTED
port: 3000
busy: true
processes[1]{pid,name}:
  1234,node
action: inspected
message: Dry mode active. No processes were terminated.

Example error result:

toon
ok: false
code: INVALID_PORT
message: Port must be a whole number.

Batch Output

Multi-port mode returns a batch result with a summary:

bash
ferman 3000 5173 5432 --json

Example batch result:

json
{
  "ok": true,
  "code": "BATCH_COMPLETED",
  "ports": [],
  "summary": {
    "total": 3,
    "busy": 0,
    "free": 3,
    "released": 0,
    "inspected": 0
  }
}

Port List Output

Use --list to inventory active listening ports across the system:

bash
ferman --list --json

Example result:

json
{
  "ok": true,
  "code": "PORTS_LISTED",
  "ports": [
    {
      "port": 3000,
      "processes": [
        {
          "pid": 1234,
          "name": "node"
        }
      ]
    }
  ],
  "count": 1,
  "message": "Listed active listening ports."
}

Node Process Output

Use --node to list active Node.js processes:

bash
ferman --node --json

Use --filter when you only want matching Node.js processes or node-port entries:

bash
ferman --node --filter mcp --json
ferman --node-ports --filter vite --json

Use --self when you explicitly want the current ferman invocation and its wrapper processes to remain visible:

bash
ferman --node --self --json

Use --node-ports to list active Node.js processes that currently expose listening ports:

bash
ferman --node-ports --json

Example --node-ports result:

json
{
  "ok": true,
  "code": "NODE_PORTS_LISTED",
  "processes": [
    {
      "pid": 1234,
      "name": "node",
      "command": "node server.js",
      "ports": [
        3000,
        9229
      ]
    }
  ],
  "count": 1,
  "message": "Listed active Node.js processes with listening ports."
}

Process Kill Output

Use --kill-all --name to terminate every process whose name or command matches a pattern:

bash
ferman --kill-all --name vite --json

Use --signal on Unix-like systems when you need explicit signal control:

bash
ferman --kill-all --name vite --signal SIGKILL --json

Example no-match result:

json
{
  "ok": true,
  "code": "NO_MATCHING_PROCESSES",
  "processes": [],
  "count": 0,
  "message": "No matching processes were found for pattern \"vite\"."
}

Plan Mode

Plan mode adds a recommendation without terminating anything:

bash
ferman 3000 --plan --json

Example recommendation:

json
{
  "recommendation": {
    "action": "terminate",
    "reason": "A single app-style development process is holding the port, so a targeted stop is a reasonable next step.",
    "risk": "low"
  }
}

Doctor Mode

Doctor mode uses the common-port scan and adds a diagnosis layer:

bash
ferman --doctor --json

Example diagnosis:

json
{
  "diagnosis": {
    "status": "attention",
    "message": "Some checked ports are busy across app and service workflows: 3000, 5432.",
    "recommendations": [
      "Run `ferman --plan --json` on a specific busy port for a safer next-step recommendation.",
      "Use `ferman <port> --dry` to inspect a busy port without terminating anything.",
      "Busy app-style ports (3000) look like a leftover local dev loop. Check watcher or restart scripts before forcing a kill.",
      "Service-style ports (5432) are busy. Confirm whether a local database, cache, or forwarded container port is expected before terminating it."
    ]
  }
}

JSON Schema

Print the current JSON Schema for machine-readable output:

bash
ferman --json-schema

This is useful for wrappers, validators, MCP tools, and agent integrations that want an explicit schema contract.

Watch Mode

Watch mode emits structured snapshots repeatedly without terminating anything:

bash
ferman 3000 --watch --json

Example watch event:

json
{
  "event": "snapshot",
  "iteration": 1,
  "timestamp": "2026-03-24T16:27:59.455Z",
  "hint": "Ports 3000 became busy again. A watcher, restart script, or container entrypoint may have recreated the listener.",
  "result": {
    "ok": true,
    "code": "PORT_INSPECTED",
    "port": 3000,
    "busy": true,
    "processes": [
      {
        "pid": 1234,
        "name": "node"
      }
    ],
    "action": "inspected",
    "message": "Dry mode active. No processes were terminated."
  }
}

Use --changed-only with watch mode when you want quieter output and only care about state transitions:

bash
ferman 3000 --watch --changed-only --json

In human-readable mode, watch now prints a short startup banner so it is clear whether it is waiting for changes or emitting regular snapshots. When ferman detects a useful transition, watch events also include a short hint about likely watcher, restart-loop, or container-driven reappearance.

Selection Rules

  • use --json when the consumer expects standard structured data
  • use --toon when the consumer is an LLM-oriented pipeline and compactness matters
  • do not combine --json and --toon in the same command
  • use --json-schema when an integration needs a formal contract
  • use --watch when a consumer needs repeated snapshots over time
  • use --changed-only with --watch when a consumer only needs changes, not every polling cycle

Exit Codes

Structured output does not change exit-code behavior:

  • 0: success
  • 1: runtime error
  • 2: invalid input

The hands of AI.