Alpha
WebSocket

Processes Topic

Real-time process list and process management via WebSocket

The processes topic provides a real-time list of running processes and allows you to manage them (kill, launch) directly through WebSocket commands.

Subscribe

{ "op": "subscribe", "data": { "topics": ["processes"] } }

Event: process_list

Broadcasts immediately on subscribe, then at the configured interval (default: 3000ms).

{
  "type": "process_list",
  "data": {
    "timestamp": 1706140800,
    "total_count": 142,
    "processes": [
      {
        "name": "chrome",
        "count": 12,
        "memory": 2147483648,
        "memory_mb": 2048.0,
        "cpu_time": 156.7
      },
      {
        "name": "code",
        "count": 8,
        "memory": 1073741824,
        "memory_mb": 1024.0,
        "cpu_time": 89.3
      }
    ]
  }
}

Field Reference

Process List

FieldTypeDescription
timestampintUnix timestamp
total_countintTotal number of unique process names
processesarrayArray of process info objects

Process Info

FieldTypeDescription
namestringProcess name (aggregated)
countintNumber of instances running
memoryintTotal memory usage in bytes
memory_mbfloatTotal memory usage in MB
cpu_timefloatCPU time consumed

Aggregated Processes

Processes are grouped by name. For example, 12 Chrome helper processes appear as one entry with count: 12.

Sending Commands

Kill Process

Kill by PID:

{
  "op": "process_kill",
  "data": {
    "pid": 1234
  }
}

Kill by name (first match):

{
  "op": "process_kill",
  "data": {
    "name": "notepad.exe"
  }
}

Launch Process

{
  "op": "process_launch",
  "data": {
    "path": "notepad.exe",
    "args": ["file.txt"]
  }
}

Event: process_feedback

After sending a process command, you'll receive feedback:

{
  "type": "process_feedback",
  "data": {
    "success": true,
    "action": "kill",
    "message": null,
    "pid": 1234,
    "name": "notepad.exe"
  }
}

Feedback Fields

FieldTypeDescription
successboolWhether the command succeeded
actionstring"kill" or "launch"
messagestringError message if failed
pidintPID of the affected process (if applicable)
namestringName of the affected process

Kill Feedback Examples

Success:

{
  "type": "process_feedback",
  "data": {
    "success": true,
    "action": "kill",
    "message": null,
    "pid": 1234,
    "name": "notepad.exe"
  }
}

Failure (process not found):

{
  "type": "process_feedback",
  "data": {
    "success": false,
    "action": "kill",
    "message": "Process not found or could not be killed",
    "pid": 99999,
    "name": null
  }
}

Launch Feedback Examples

Success:

{
  "type": "process_feedback",
  "data": {
    "success": true,
    "action": "launch",
    "message": null,
    "pid": null,
    "name": "notepad.exe"
  }
}

Failure:

{
  "type": "process_feedback",
  "data": {
    "success": false,
    "action": "launch",
    "message": "The system cannot find the file specified.",
    "pid": null,
    "name": "nonexistent.exe"
  }
}

Configuration

In config.json:

{
  "websocket": {
    "processes": {
      "enabled": true,
      "interval_ms": 3000
    }
  }
}

Performance Note

Process enumeration can be resource-intensive. The default 3-second interval balances freshness with performance. Avoid setting this too low.

Example Use Cases

1. Task Manager Widget

Display top processes by memory usage:

const ws = new WebSocket("ws://localhost:9990/api/ws");

ws.onopen = () => {
  ws.send(
    JSON.stringify({
      op: "subscribe",
      data: { topics: ["processes"] },
    }),
  );
};

ws.onmessage = (event) => {
  const { type, data } = JSON.parse(event.data);

  if (type === "process_list") {
    // Already sorted by memory (highest first)
    const top5 = data.processes.slice(0, 5);
    renderProcessList(top5);
  }
};

function renderProcessList(processes) {
  const container = document.getElementById("processes");
  container.innerHTML = processes
    .map(
      (p) => `
    <div class="process-row">
      <span class="name">${p.name}</span>
      <span class="count">${p.count} instance${p.count > 1 ? "s" : ""}</span>
      <span class="memory">${p.memory_mb.toFixed(0)} MB</span>
      <button onclick="killProcess('${p.name}')">Kill</button>
    </div>
  `,
    )
    .join("");
}

2. Memory Hog Detector

Alert when a process uses too much memory:

const MEMORY_THRESHOLD_MB = 4096; // 4 GB

ws.onmessage = (event) => {
  const { type, data } = JSON.parse(event.data);

  if (type === "process_list") {
    for (const process of data.processes) {
      if (process.memory_mb > MEMORY_THRESHOLD_MB) {
        showAlert(`${process.name} is using ${process.memory_mb.toFixed(0)} MB!`);
      }
    }
  }
};

3. Quick Launch Buttons

Launch common applications:

const quickLaunch = {
  notepad: "notepad.exe",
  calculator: "calc.exe",
  explorer: "explorer.exe",
  terminal: "wt.exe",
};

function launchApp(appKey) {
  ws.send(
    JSON.stringify({
      op: "process_launch",
      data: { path: quickLaunch[appKey] },
    }),
  );
}

// Listen for feedback
ws.onmessage = (event) => {
  const { type, data } = JSON.parse(event.data);

  if (type === "process_feedback" && data.action === "launch") {
    if (data.success) {
      showToast(`Launched ${data.name}`);
    } else {
      showError(`Failed to launch: ${data.message}`);
    }
  }
};

4. Auto-Kill Memory Hogs

Automatically kill processes that exceed a threshold:

const AUTO_KILL_THRESHOLD_MB = 8192; // 8 GB
const PROTECTED = ["explorer", "code", "chrome"]; // Don't kill these

ws.onmessage = (event) => {
  const { type, data } = JSON.parse(event.data);

  if (type === "process_list") {
    for (const process of data.processes) {
      if (process.memory_mb > AUTO_KILL_THRESHOLD_MB) {
        if (!PROTECTED.includes(process.name.toLowerCase())) {
          console.log(`Auto-killing ${process.name} (${process.memory_mb} MB)`);
          ws.send(
            JSON.stringify({
              op: "process_kill",
              data: { name: process.name },
            }),
          );
        }
      }
    }
  }
};

5. Process Monitor with Kill Confirmation

Full process manager with feedback handling:

let processes = [];

ws.onmessage = (event) => {
  const { type, data } = JSON.parse(event.data);

  switch (type) {
    case "process_list":
      processes = data.processes;
      renderProcessTable(processes);
      break;

    case "process_feedback":
      if (data.action === "kill") {
        if (data.success) {
          showToast(`Killed ${data.name} (PID: ${data.pid})`);
        } else {
          showError(data.message);
        }
      }
      break;
  }
};

function killByName(name) {
  if (confirm(`Kill all instances of ${name}?`)) {
    ws.send(
      JSON.stringify({
        op: "process_kill",
        data: { name },
      }),
    );
  }
}

6. Startup Script

Launch multiple apps on connection:

const startupApps = [
  { path: "spotify.exe" },
  { path: "discord.exe" },
  { path: "code.exe", args: ["C:\\Projects\\myapp"] },
];

ws.onopen = () => {
  for (const app of startupApps) {
    ws.send(
      JSON.stringify({
        op: "process_launch",
        data: app,
      }),
    );
  }
};

On this page