md4ai 0.7.7 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1232,7 +1232,7 @@ var CURRENT_VERSION;
1232
1232
  var init_check_update = __esm({
1233
1233
  "dist/check-update.js"() {
1234
1234
  "use strict";
1235
- CURRENT_VERSION = true ? "0.7.7" : "0.0.0-dev";
1235
+ CURRENT_VERSION = true ? "0.7.9" : "0.0.0-dev";
1236
1236
  }
1237
1237
  });
1238
1238
 
@@ -1591,7 +1591,15 @@ function findProcessesForConfig(config, processes) {
1591
1591
  });
1592
1592
  }
1593
1593
  }
1594
- return matches;
1594
+ const byTty = /* @__PURE__ */ new Map();
1595
+ for (const m of matches) {
1596
+ const key = m.tty || `pid-${m.pid}`;
1597
+ const existing = byTty.get(key);
1598
+ if (!existing || m.memoryMb > existing.memoryMb) {
1599
+ byTty.set(key, m);
1600
+ }
1601
+ }
1602
+ return Array.from(byTty.values());
1595
1603
  }
1596
1604
  function getProcessTable() {
1597
1605
  try {
@@ -1747,11 +1755,12 @@ function printTable(rows, deviceName) {
1747
1755
  MCP Monitor \u2014 ${deviceName}`));
1748
1756
  console.log(chalk18.dim(` ${(/* @__PURE__ */ new Date()).toLocaleTimeString()} \xB7 refreshes every 30s \xB7 Ctrl+C to stop
1749
1757
  `));
1750
- const running = rows.filter((r) => r.status === "running");
1758
+ const runningLocal = rows.filter((r) => r.status === "running" && r.server_type !== "http");
1759
+ const runningHttp = rows.filter((r) => r.status === "running" && r.server_type === "http");
1751
1760
  const stopped = rows.filter((r) => r.status === "stopped");
1752
1761
  const errored = rows.filter((r) => r.status === "error");
1753
1762
  const byTty = /* @__PURE__ */ new Map();
1754
- for (const r of running) {
1763
+ for (const r of runningLocal) {
1755
1764
  const key = r.session_tty ?? "unknown";
1756
1765
  const list = byTty.get(key) ?? [];
1757
1766
  list.push(r);
@@ -1768,6 +1777,13 @@ function printTable(rows, deviceName) {
1768
1777
  console.log("");
1769
1778
  }
1770
1779
  }
1780
+ if (runningHttp.length > 0) {
1781
+ console.log(chalk18.blue(` Remote Services (${runningHttp.length})`) + chalk18.dim(" \u2014 HTTP endpoints reachable"));
1782
+ for (const s of runningHttp) {
1783
+ console.log(` ${chalk18.blue("\u25CF")} ${s.server_name.padEnd(20)} ${chalk18.dim((s.http_url ?? "").padEnd(30))}`);
1784
+ }
1785
+ console.log("");
1786
+ }
1771
1787
  if (stopped.length > 0 || errored.length > 0) {
1772
1788
  const notRunning = [...stopped, ...errored];
1773
1789
  console.log(chalk18.yellow(` Not Running (${notRunning.length})`));
@@ -1782,6 +1798,8 @@ function printTable(rows, deviceName) {
1782
1798
  console.log(chalk18.yellow(" No MCP servers configured."));
1783
1799
  console.log(chalk18.dim(" Configure servers in ~/.claude/mcp.json or .mcp.json\n"));
1784
1800
  }
1801
+ console.log(chalk18.bgYellow.black.bold(" \u26A0 DO NOT CLOSE THIS WINDOW \u2014 it feeds live data to the dashboard \u26A0 "));
1802
+ console.log("");
1785
1803
  }
1786
1804
  function formatUptime(seconds) {
1787
1805
  if (seconds < 60)
@@ -1798,6 +1816,22 @@ async function mcpWatchCommand() {
1798
1816
  const deviceName = detectDeviceName();
1799
1817
  const myPid = process.pid;
1800
1818
  const myTty = detectTty();
1819
+ const staleThreshold = new Date(Date.now() - 12e4).toISOString();
1820
+ await supabase.from("mcp_watchers").delete().eq("device_id", deviceId).lt("last_heartbeat", staleThreshold);
1821
+ const { data: existingWatchers } = await supabase.from("mcp_watchers").select("pid, tty, cli_version, started_at").eq("device_id", deviceId);
1822
+ if (existingWatchers && existingWatchers.length > 0) {
1823
+ console.log("");
1824
+ console.log(chalk18.yellow(` Replacing ${existingWatchers.length} existing watcher${existingWatchers.length !== 1 ? "s" : ""} on this device...`));
1825
+ for (const w of existingWatchers) {
1826
+ try {
1827
+ process.kill(w.pid, "SIGTERM");
1828
+ } catch {
1829
+ }
1830
+ }
1831
+ await supabase.from("mcp_watchers").delete().eq("device_id", deviceId);
1832
+ await new Promise((r) => setTimeout(r, 1e3));
1833
+ console.log(chalk18.dim(" Previous watcher stopped.\n"));
1834
+ }
1801
1835
  process.stdout.write(`\x1B]0;${deviceName} MCP Monitor\x07`);
1802
1836
  console.log(chalk18.blue(`Starting MCP monitor for ${deviceName}...`));
1803
1837
  console.log("");
@@ -1814,8 +1848,6 @@ async function mcpWatchCommand() {
1814
1848
  started_at: (/* @__PURE__ */ new Date()).toISOString(),
1815
1849
  last_heartbeat: (/* @__PURE__ */ new Date()).toISOString()
1816
1850
  }, { onConflict: "device_id,pid" });
1817
- const staleThreshold = new Date(Date.now() - 12e4).toISOString();
1818
- await supabase.from("mcp_watchers").delete().eq("device_id", deviceId).lt("last_heartbeat", staleThreshold);
1819
1851
  async function cycle() {
1820
1852
  const configs = await readAllMcpConfigs();
1821
1853
  const httpConfigs = configs.filter((c) => c.type === "http" && c.url);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md4ai",
3
- "version": "0.7.7",
3
+ "version": "0.7.9",
4
4
  "description": "CLI for MD4AI — scan Claude projects and sync to your dashboard",
5
5
  "type": "module",
6
6
  "bin": {