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

Field Type Description
timestamp int Unix timestamp
total_count int Total number of unique process names
processes array Array of process info objects

Process Info

Field Type Description
name string Process name (aggregated)
count int Number of instances running
memory int Total memory usage in bytes
memory_mb float Total memory usage in MB
cpu_time float CPU 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

Field Type Description
success bool Whether the command succeeded
action string "kill" or "launch"
message string Error message if failed
pid int PID of the affected process (if applicable)
name string Name 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,
      }),
    );
  }
};