md4ai 0.6.0 → 0.6.2

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.
@@ -1161,7 +1161,7 @@ function escapeHtml(text) {
1161
1161
 
1162
1162
  // dist/check-update.js
1163
1163
  import chalk8 from "chalk";
1164
- var CURRENT_VERSION = "0.6.0";
1164
+ var CURRENT_VERSION = "0.6.2";
1165
1165
  async function checkForUpdate() {
1166
1166
  try {
1167
1167
  const controller = new AbortController();
@@ -2002,6 +2002,7 @@ async function fetchGitHubVersions(repo, signal) {
2002
2002
 
2003
2003
  // dist/commands/mcp-watch.js
2004
2004
  import chalk18 from "chalk";
2005
+ import { execFileSync as execFileSync5 } from "node:child_process";
2005
2006
 
2006
2007
  // dist/mcp/read-configs.js
2007
2008
  import { readFile as readFile7 } from "node:fs/promises";
@@ -2050,9 +2051,33 @@ function parseServers(data, source) {
2050
2051
  }
2051
2052
  return entries;
2052
2053
  }
2054
+ function parseFlatConfig(data, source) {
2055
+ if (!data)
2056
+ return [];
2057
+ const entries = [];
2058
+ for (const [name, server] of Object.entries(data)) {
2059
+ if (typeof server !== "object" || server === null)
2060
+ continue;
2061
+ if (!server.command && !server.url)
2062
+ continue;
2063
+ const serverType = server.type === "http" ? "http" : "stdio";
2064
+ entries.push({
2065
+ name,
2066
+ source,
2067
+ type: serverType,
2068
+ command: server.command,
2069
+ args: server.args,
2070
+ env: server.env,
2071
+ url: server.url
2072
+ });
2073
+ }
2074
+ return entries;
2075
+ }
2053
2076
  async function readAllMcpConfigs() {
2054
2077
  const home = homedir7();
2055
2078
  const entries = [];
2079
+ const userConfig = await readJsonSafe(join11(home, ".claude.json"));
2080
+ entries.push(...parseServers(userConfig, "global"));
2056
2081
  const globalMcp = await readJsonSafe(join11(home, ".claude", "mcp.json"));
2057
2082
  entries.push(...parseServers(globalMcp, "global"));
2058
2083
  const cwdMcp = await readJsonSafe(join11(process.cwd(), ".mcp.json"));
@@ -2078,6 +2103,34 @@ async function readAllMcpConfigs() {
2078
2103
  } catch {
2079
2104
  }
2080
2105
  }
2106
+ const cacheBase = join11(home, ".claude", "plugins", "cache");
2107
+ if (existsSync10(cacheBase)) {
2108
+ try {
2109
+ const registries = await readdir3(cacheBase, { withFileTypes: true });
2110
+ for (const reg of registries) {
2111
+ if (!reg.isDirectory())
2112
+ continue;
2113
+ const regDir = join11(cacheBase, reg.name);
2114
+ const plugins = await readdir3(regDir, { withFileTypes: true });
2115
+ for (const plugin of plugins) {
2116
+ if (!plugin.isDirectory())
2117
+ continue;
2118
+ const versionDirs = await readdir3(join11(regDir, plugin.name), { withFileTypes: true });
2119
+ for (const ver of versionDirs) {
2120
+ if (!ver.isDirectory())
2121
+ continue;
2122
+ const mcpPath = join11(regDir, plugin.name, ver.name, ".mcp.json");
2123
+ const flatData = await readJsonSafe(mcpPath);
2124
+ if (flatData) {
2125
+ entries.push(...parseFlatConfig(flatData, "plugin"));
2126
+ break;
2127
+ }
2128
+ }
2129
+ }
2130
+ }
2131
+ } catch {
2132
+ }
2133
+ }
2081
2134
  const seen = /* @__PURE__ */ new Set();
2082
2135
  const deduped = [];
2083
2136
  for (const entry of entries) {
@@ -2165,6 +2218,17 @@ function getProcessTable() {
2165
2218
 
2166
2219
  // dist/commands/mcp-watch.js
2167
2220
  var POLL_INTERVAL_MS = 3e4;
2221
+ function detectTty() {
2222
+ try {
2223
+ const result = execFileSync5("ps", ["-o", "tty=", "-p", String(process.pid)], {
2224
+ encoding: "utf-8",
2225
+ timeout: 3e3
2226
+ }).trim();
2227
+ return result && result !== "?" ? result : null;
2228
+ } catch {
2229
+ return null;
2230
+ }
2231
+ }
2168
2232
  function checkEnvVars(config) {
2169
2233
  const required = config.env ? Object.keys(config.env) : [];
2170
2234
  const missing = required.filter((key) => !process.env[key]);
@@ -2310,7 +2374,19 @@ async function mcpWatchCommand() {
2310
2374
  const { supabase, userId } = await getAuthenticatedClient();
2311
2375
  const deviceId = await resolveDeviceId(supabase, userId);
2312
2376
  const deviceName = detectDeviceName();
2377
+ const myPid = process.pid;
2378
+ const myTty = detectTty();
2313
2379
  console.log(chalk18.blue(`Starting MCP monitor for ${deviceName}...`));
2380
+ await supabase.from("mcp_watchers").upsert({
2381
+ device_id: deviceId,
2382
+ pid: myPid,
2383
+ tty: myTty,
2384
+ cli_version: CURRENT_VERSION,
2385
+ started_at: (/* @__PURE__ */ new Date()).toISOString(),
2386
+ last_heartbeat: (/* @__PURE__ */ new Date()).toISOString()
2387
+ }, { onConflict: "device_id,pid" });
2388
+ const staleThreshold = new Date(Date.now() - 12e4).toISOString();
2389
+ await supabase.from("mcp_watchers").delete().eq("device_id", deviceId).lt("last_heartbeat", staleThreshold);
2314
2390
  async function cycle() {
2315
2391
  const configs = await readAllMcpConfigs();
2316
2392
  const rows = buildRows(configs);
@@ -2323,17 +2399,23 @@ async function mcpWatchCommand() {
2323
2399
  checked_at: now
2324
2400
  })));
2325
2401
  }
2402
+ await supabase.from("mcp_watchers").update({ last_heartbeat: now }).eq("device_id", deviceId).eq("pid", myPid);
2326
2403
  printTable(rows, deviceName);
2327
2404
  }
2328
2405
  await cycle();
2329
2406
  const interval = setInterval(cycle, POLL_INTERVAL_MS);
2330
- const shutdown = () => {
2407
+ const shutdown = async () => {
2331
2408
  clearInterval(interval);
2409
+ await supabase.from("mcp_watchers").delete().eq("device_id", deviceId).eq("pid", myPid);
2332
2410
  console.log(chalk18.dim("\nMCP monitor stopped."));
2333
2411
  process.exit(0);
2334
2412
  };
2335
- process.on("SIGINT", shutdown);
2336
- process.on("SIGTERM", shutdown);
2413
+ process.on("SIGINT", () => {
2414
+ void shutdown();
2415
+ });
2416
+ process.on("SIGTERM", () => {
2417
+ void shutdown();
2418
+ });
2337
2419
  }
2338
2420
 
2339
2421
  // dist/index.js
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "md4ai",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "CLI for MD4AI — scan Claude projects and sync to your dashboard",
5
5
  "type": "module",
6
6
  "bin": {