@opentrust/cli 7.3.23 → 7.3.26

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.
@@ -13,9 +13,9 @@ const SCAFFOLD_PKG = {
13
13
  status: "opentrust status",
14
14
  },
15
15
  dependencies: {
16
- "@opentrust/core": "^7.3.23",
17
- "@opentrust/gateway": "^7.3.23",
18
- "@opentrust/dashboard": "^7.3.23",
16
+ "@opentrust/core": "^7.3.26",
17
+ "@opentrust/gateway": "^7.3.26",
18
+ "@opentrust/dashboard": "^7.3.26",
19
19
  },
20
20
  };
21
21
  const ENV_TEMPLATE = `# OpenTrust Configuration
@@ -1,6 +1,41 @@
1
1
  import { getStatus, checkHealth, getAllServiceKeys, SERVICES } from "../lib/process-manager.js";
2
2
  import { requireProject } from "../lib/paths.js";
3
3
  import { dockerStatus } from "../lib/docker-manager.js";
4
+ import { loadConfig } from "../lib/dashboard-client.js";
5
+ import fs from "node:fs";
6
+ import path from "node:path";
7
+ import os from "node:os";
8
+ const GREEN = "\x1b[32m●\x1b[0m";
9
+ const YELLOW = "\x1b[33m●\x1b[0m";
10
+ const RED = "\x1b[31m●\x1b[0m";
11
+ const PID_FILE = path.join(os.homedir(), ".opentrust", "connect.pid");
12
+ function getConnectDaemonStatus() {
13
+ if (!fs.existsSync(PID_FILE))
14
+ return { running: false, pid: null };
15
+ const pid = parseInt(fs.readFileSync(PID_FILE, "utf-8").trim(), 10);
16
+ if (isNaN(pid))
17
+ return { running: false, pid: null };
18
+ try {
19
+ process.kill(pid, 0);
20
+ return { running: true, pid };
21
+ }
22
+ catch {
23
+ return { running: false, pid: null };
24
+ }
25
+ }
26
+ async function checkDashboardReachable(url) {
27
+ try {
28
+ const controller = new AbortController();
29
+ const timer = setTimeout(() => controller.abort(), 5000);
30
+ const res = await fetch(`${url}/health`, { signal: controller.signal });
31
+ clearTimeout(timer);
32
+ const data = (await res.json());
33
+ return data.status === "ok";
34
+ }
35
+ catch {
36
+ return false;
37
+ }
38
+ }
4
39
  export function registerStatusCommand(program) {
5
40
  program
6
41
  .command("status")
@@ -14,12 +49,13 @@ export function registerStatusCommand(program) {
14
49
  }
15
50
  requireProject();
16
51
  console.log("OpenTrust Service Status\n");
52
+ // Services
17
53
  const keys = getAllServiceKeys();
18
54
  for (const key of keys) {
19
55
  const svc = SERVICES[key];
20
56
  const { running, pid } = getStatus(key);
21
57
  const healthy = running ? await checkHealth(key) : false;
22
- const statusIcon = running ? (healthy ? "\x1b[32m●\x1b[0m" : "\x1b[33m●\x1b[0m") : "\x1b[31m●\x1b[0m";
58
+ const statusIcon = running ? (healthy ? GREEN : YELLOW) : RED;
23
59
  const statusText = running
24
60
  ? healthy
25
61
  ? `running (PID ${pid})`
@@ -27,6 +63,35 @@ export function registerStatusCommand(program) {
27
63
  : "stopped";
28
64
  console.log(` ${statusIcon} ${svc.name.padEnd(12)} ${statusText.padEnd(35)} port ${svc.port}`);
29
65
  }
66
+ // Connect daemon
67
+ console.log("");
68
+ const daemon = getConnectDaemonStatus();
69
+ const config = loadConfig();
70
+ if (daemon.running) {
71
+ const reachable = config?.dashboardUrl
72
+ ? await checkDashboardReachable(config.dashboardUrl)
73
+ : false;
74
+ const connIcon = reachable ? GREEN : YELLOW;
75
+ const connText = reachable
76
+ ? `connected (PID ${daemon.pid})`
77
+ : `running but dashboard unreachable (PID ${daemon.pid})`;
78
+ console.log(` ${connIcon} ${"CLI Client".padEnd(12)} ${connText}`);
79
+ if (config?.dashboardUrl) {
80
+ console.log(` ${"".padEnd(15)} → ${config.dashboardUrl}`);
81
+ }
82
+ if (config?.hostId) {
83
+ console.log(` ${"".padEnd(15)} Host ID: ${config.hostId}`);
84
+ }
85
+ }
86
+ else if (config?.dashboardUrl) {
87
+ console.log(` ${RED} ${"CLI Client".padEnd(12)} not running (configured but daemon stopped)`);
88
+ console.log(` ${"".padEnd(15)} → ${config.dashboardUrl}`);
89
+ console.log(` ${"".padEnd(15)} Run: opentrust connect --daemon`);
90
+ }
91
+ else {
92
+ console.log(` ${RED} ${"CLI Client".padEnd(12)} not configured`);
93
+ console.log(` ${"".padEnd(15)} Run: opentrust connect --dashboard-url <url> --api-key <key> --daemon`);
94
+ }
30
95
  console.log("");
31
96
  });
32
97
  }
@@ -42,6 +42,10 @@ export function executeHostCommand(cmd) {
42
42
  return handleUninstallPlugin(payload);
43
43
  case "update_config":
44
44
  return handleUpdateConfig(payload);
45
+ case "install_guards":
46
+ return handleInstallGuards(payload);
47
+ case "upgrade_guards":
48
+ return handleUpgradeGuards(payload);
45
49
  default:
46
50
  return { success: false, error: `Unknown command type: ${cmd.type}` };
47
51
  }
@@ -251,3 +255,27 @@ function handleUpdateConfig(payload) {
251
255
  return { success: false, error: (err.message || String(err)).slice(0, 500) };
252
256
  }
253
257
  }
258
+ // ── Guards install / upgrade ─────────────────────────
259
+ function handleInstallGuards(payload) {
260
+ const version = payload.version || "latest";
261
+ const spec = version === "latest" ? "@opentrust/guards" : `@opentrust/guards@${version}`;
262
+ try {
263
+ const output = execSync(`openclaw plugins install ${spec}`, clawExecOpts(180_000));
264
+ return { success: true, output: output.trim().slice(-1000) };
265
+ }
266
+ catch (err) {
267
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 1000) };
268
+ }
269
+ }
270
+ function handleUpgradeGuards(payload) {
271
+ const version = payload.version || "latest";
272
+ const spec = version === "latest" ? "@opentrust/guards" : `@opentrust/guards@${version}`;
273
+ try {
274
+ const uninstallOut = execSync("openclaw plugins uninstall @opentrust/guards --force", clawExecOpts(60_000));
275
+ const installOut = execSync(`openclaw plugins install ${spec}`, clawExecOpts(180_000));
276
+ return { success: true, output: `Uninstall: ${uninstallOut.trim()}\nInstall: ${installOut.trim()}`.slice(-1000) };
277
+ }
278
+ catch (err) {
279
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 1000) };
280
+ }
281
+ }
@@ -46,6 +46,30 @@ export async function getServicesSnapshot() {
46
46
  }
47
47
  return result;
48
48
  }
49
+ function detectGuards() {
50
+ const openclawHome = process.env.OPENCLAW_HOME || path.join(os.homedir(), ".openclaw");
51
+ try {
52
+ const configPath = path.join(openclawHome, "openclaw.json");
53
+ if (!fs.existsSync(configPath))
54
+ return { installed: false };
55
+ const json = JSON.parse(fs.readFileSync(configPath, "utf-8"));
56
+ const entry = json?.plugins?.entries?.["opentrust-guard"];
57
+ if (!entry)
58
+ return { installed: false };
59
+ let version;
60
+ const pkgPath = path.join(entry.directory || "", "package.json");
61
+ if (fs.existsSync(pkgPath)) {
62
+ try {
63
+ version = JSON.parse(fs.readFileSync(pkgPath, "utf-8")).version;
64
+ }
65
+ catch { }
66
+ }
67
+ return { installed: true, version };
68
+ }
69
+ catch {
70
+ return { installed: false };
71
+ }
72
+ }
49
73
  export function getSystemMetadata() {
50
74
  const cpus = os.cpus();
51
75
  return {
@@ -55,5 +79,6 @@ export function getSystemMetadata() {
55
79
  freeMemMB: Math.round(os.freemem() / 1048576),
56
80
  uptime: os.uptime(),
57
81
  nodeVersion: process.version,
82
+ guards: detectGuards(),
58
83
  };
59
84
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentrust/cli",
3
- "version": "7.3.23",
3
+ "version": "7.3.26",
4
4
  "description": "CLI tool to manage OpenTrust AI Agent Runtime Security Platform — setup, start, stop, status, logs",
5
5
  "type": "module",
6
6
  "bin": {