@opentrust/cli 7.3.21 → 7.3.23

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.
@@ -14,11 +14,18 @@ export function registerConnectCommand(program) {
14
14
  .command("connect")
15
15
  .description("Connect this host to an OpenTrust Dashboard for remote management")
16
16
  .option("--dashboard-url <url>", "Dashboard URL (e.g. http://host:53667)")
17
- .option("--api-key <key>", "Core API key (sk-og-...)")
17
+ .option("--api-key <key>", "System API key (sk-ot-...)")
18
18
  .option("--daemon", "Run in background as a daemon process")
19
19
  .action(async (opts) => {
20
20
  let config = loadConfig();
21
- if (opts.dashboardUrl && opts.apiKey) {
21
+ if (opts.dashboardUrl) {
22
+ if (!opts.apiKey) {
23
+ console.error("--api-key is required.");
24
+ console.error("");
25
+ console.error("Get your System API Key from Dashboard → Settings → System API Key,");
26
+ console.error("then run: opentrust connect --dashboard-url <url> --api-key sk-ot-xxx");
27
+ process.exit(1);
28
+ }
22
29
  config = {
23
30
  dashboardUrl: opts.dashboardUrl,
24
31
  apiKey: opts.apiKey,
@@ -31,7 +38,9 @@ export function registerConnectCommand(program) {
31
38
  console.error("No connection configured.");
32
39
  console.error("");
33
40
  console.error("Usage:");
34
- console.error(" opentrust connect --dashboard-url http://host:53667 --api-key sk-og-xxx");
41
+ console.error(" opentrust connect --dashboard-url http://host:53667 --api-key sk-ot-xxx");
42
+ console.error("");
43
+ console.error("Get the System API Key from Dashboard → Settings.");
35
44
  process.exit(1);
36
45
  }
37
46
  if (opts.daemon) {
@@ -13,15 +13,14 @@ const SCAFFOLD_PKG = {
13
13
  status: "opentrust status",
14
14
  },
15
15
  dependencies: {
16
- "@opentrust/core": "^7.3.21",
17
- "@opentrust/gateway": "^7.3.21",
18
- "@opentrust/dashboard": "^7.3.21",
16
+ "@opentrust/core": "^7.3.23",
17
+ "@opentrust/gateway": "^7.3.23",
18
+ "@opentrust/dashboard": "^7.3.23",
19
19
  },
20
20
  };
21
21
  const ENV_TEMPLATE = `# OpenTrust Configuration
22
22
 
23
23
  # Dashboard
24
- DEV_MODE=true
25
24
  DASHBOARD_MODE=embedded
26
25
  DASHBOARD_DATA_DIR=./data
27
26
 
@@ -30,6 +29,7 @@ CORE_PORT=53666
30
29
 
31
30
  # Gateway
32
31
  GATEWAY_PORT=8900
32
+ # OT_API_KEY= # System API Key for Gateway auth (from Dashboard Settings)
33
33
  # ANTHROPIC_API_KEY=sk-ant-xxx
34
34
  # OPENAI_API_KEY=sk-xxx
35
35
  # GEMINI_API_KEY=xxx
@@ -82,13 +82,13 @@ export function registerInitCommand(program) {
82
82
  console.log("\n-------------------------------------------");
83
83
  console.log("OpenTrust project initialized!");
84
84
  console.log("-------------------------------------------\n");
85
- console.log("Next steps:");
85
+ console.log("Quick start:");
86
86
  console.log(" opentrust setup # Run database migrations");
87
- console.log(" opentrust start # Start all services");
88
- console.log(" opentrust status # Check service health\n");
89
- console.log("Services:");
90
- console.log(" Core http://localhost:53666");
91
- console.log(" Dashboard http://localhost:53667/dashboard/");
92
- console.log(" Gateway http://localhost:8900");
87
+ console.log(" opentrust start # Start all services\n");
88
+ console.log("After starting, open the Dashboard:");
89
+ console.log(" http://localhost:53667/dashboard/\n");
90
+ console.log("Default login:");
91
+ console.log(" Username: admin");
92
+ console.log(" Password: admin");
93
93
  });
94
94
  }
@@ -77,7 +77,6 @@ function runNpmSetup() {
77
77
  const env = {
78
78
  ...process.env,
79
79
  DASHBOARD_DATA_DIR: dataDir,
80
- DEV_MODE: "true",
81
80
  };
82
81
  // Load .env from project root if exists
83
82
  const envFile = path.join(projectRoot, ".env");
@@ -132,6 +131,17 @@ function printSetupDone() {
132
131
  console.log("-------------------------------------------");
133
132
  console.log("Setup complete!");
134
133
  console.log("-------------------------------------------");
135
- console.log("\nRun 'opentrust start' to launch all services.");
136
- console.log("Or start individually: 'opentrust start core'");
134
+ console.log("");
135
+ console.log("Next step:");
136
+ console.log(" opentrust start");
137
+ console.log("");
138
+ console.log("After starting, open the Dashboard:");
139
+ console.log(" http://localhost:53667/dashboard/");
140
+ console.log("");
141
+ console.log("Default login:");
142
+ console.log(" Username: admin");
143
+ console.log(" Password: admin");
144
+ console.log("");
145
+ console.log("Please change the password after first login");
146
+ console.log("at Dashboard → Settings → Change Password.");
137
147
  }
@@ -32,7 +32,13 @@ export function registerStartCommand(program) {
32
32
  for (const key of keys) {
33
33
  startService(key);
34
34
  }
35
- console.log("\nUse 'opentrust status' to check health.");
35
+ console.log("");
36
+ console.log("-------------------------------------------");
37
+ console.log(" Dashboard http://localhost:53667/dashboard/");
38
+ console.log(" Login admin / admin");
39
+ console.log("-------------------------------------------");
40
+ console.log("");
41
+ console.log("Use 'opentrust status' to check health.");
36
42
  console.log("Use 'opentrust logs <service>' to view output.");
37
43
  });
38
44
  }
@@ -1,9 +1,20 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import os from "node:os";
4
5
  import { startService, stopService, getStatus, SERVICES } from "./process-manager.js";
5
6
  import { paths, projectRoot, projectMode } from "./paths.js";
6
7
  const SERVICE_KEYS = Object.keys(SERVICES);
8
+ const OPENCLAW_HOME = process.env.OPENCLAW_HOME || path.join(os.homedir(), ".openclaw");
9
+ function clawExecOpts(timeoutMs = 120_000) {
10
+ return {
11
+ encoding: "utf-8",
12
+ timeout: timeoutMs,
13
+ stdio: ["pipe", "pipe", "pipe"],
14
+ cwd: os.homedir(),
15
+ env: { ...process.env, HOME: os.homedir(), OPENCLAW_HOME },
16
+ };
17
+ }
7
18
  export function executeHostCommand(cmd) {
8
19
  const payload = cmd.payload ?? {};
9
20
  switch (cmd.type) {
@@ -19,6 +30,18 @@ export function executeHostCommand(cmd) {
19
30
  return handleFetchLogs(payload);
20
31
  case "update_env":
21
32
  return handleUpdateEnv(payload);
33
+ case "install_skill":
34
+ return handleInstallSkill(payload);
35
+ case "install_custom_skill":
36
+ return handleInstallCustomSkill(payload);
37
+ case "uninstall_skill":
38
+ return handleUninstallSkill(payload);
39
+ case "install_plugin":
40
+ return handleInstallPlugin(payload);
41
+ case "uninstall_plugin":
42
+ return handleUninstallPlugin(payload);
43
+ case "update_config":
44
+ return handleUpdateConfig(payload);
22
45
  default:
23
46
  return { success: false, error: `Unknown command type: ${cmd.type}` };
24
47
  }
@@ -139,3 +162,92 @@ function handleUpdateEnv(payload) {
139
162
  fs.writeFileSync(envFile, lines.join("\n"), "utf-8");
140
163
  return { success: true, output: `${key}=${value}` };
141
164
  }
165
+ // ── Skill / Plugin commands ──────────────────────────
166
+ function handleInstallSkill(payload) {
167
+ const skillName = payload.skillName;
168
+ if (!skillName)
169
+ return { success: false, error: "Missing skillName in payload" };
170
+ try {
171
+ const output = execSync(`clawhub install ${skillName} --force`, clawExecOpts());
172
+ return { success: true, output: output.trim() };
173
+ }
174
+ catch (err) {
175
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 500) };
176
+ }
177
+ }
178
+ function handleInstallCustomSkill(payload) {
179
+ const skillName = payload.skillName;
180
+ const content = payload.content;
181
+ if (!skillName || !content)
182
+ return { success: false, error: "Missing skillName or content" };
183
+ try {
184
+ const skillDir = path.join(OPENCLAW_HOME, "workspace", "skills", skillName);
185
+ fs.mkdirSync(skillDir, { recursive: true });
186
+ fs.writeFileSync(path.join(skillDir, "SKILL.md"), content, "utf-8");
187
+ try {
188
+ const output = execSync(`clawhub install ${skillDir} --force`, clawExecOpts());
189
+ return { success: true, output: output.trim() };
190
+ }
191
+ catch {
192
+ return { success: true, output: `Custom skill "${skillName}" saved to ${skillDir}/SKILL.md` };
193
+ }
194
+ }
195
+ catch (err) {
196
+ return { success: false, error: (err.message || String(err)).slice(0, 500) };
197
+ }
198
+ }
199
+ function handleUninstallSkill(payload) {
200
+ const skillName = payload.skillName;
201
+ if (!skillName)
202
+ return { success: false, error: "Missing skillName in payload" };
203
+ try {
204
+ const output = execSync(`clawhub uninstall ${skillName} --yes`, clawExecOpts(60_000));
205
+ return { success: true, output: output.trim() };
206
+ }
207
+ catch (err) {
208
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 500) };
209
+ }
210
+ }
211
+ function handleInstallPlugin(payload) {
212
+ const spec = payload.spec;
213
+ if (!spec)
214
+ return { success: false, error: "Missing spec in payload" };
215
+ try {
216
+ const output = execSync(`openclaw plugins install ${spec}`, clawExecOpts(180_000));
217
+ return { success: true, output: output.trim().slice(-500) };
218
+ }
219
+ catch (err) {
220
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 500) };
221
+ }
222
+ }
223
+ function handleUninstallPlugin(payload) {
224
+ const pluginId = payload.pluginId;
225
+ if (!pluginId)
226
+ return { success: false, error: "Missing pluginId in payload" };
227
+ try {
228
+ const output = execSync(`openclaw plugins uninstall ${pluginId} --force`, clawExecOpts(60_000));
229
+ return { success: true, output: output.trim().slice(-500) };
230
+ }
231
+ catch (err) {
232
+ return { success: false, error: (err.stderr?.toString() || err.message || String(err)).slice(0, 500) };
233
+ }
234
+ }
235
+ function handleUpdateConfig(payload) {
236
+ if (Object.keys(payload).length === 0)
237
+ return { success: false, error: "Empty config payload" };
238
+ try {
239
+ const configFile = path.join(OPENCLAW_HOME, "openclaw.json");
240
+ if (!fs.existsSync(configFile))
241
+ return { success: false, error: `Config not found: ${configFile}` };
242
+ const json = JSON.parse(fs.readFileSync(configFile, "utf-8"));
243
+ const entry = json?.plugins?.entries?.["opentrust-guard"];
244
+ if (!entry)
245
+ return { success: false, error: "opentrust-guard entry not found in openclaw.json" };
246
+ entry.config = { ...entry.config, ...payload };
247
+ fs.writeFileSync(configFile, JSON.stringify(json, null, 2) + "\n", "utf-8");
248
+ return { success: true, output: `Config updated: ${Object.keys(payload).join(", ")}` };
249
+ }
250
+ catch (err) {
251
+ return { success: false, error: (err.message || String(err)).slice(0, 500) };
252
+ }
253
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentrust/cli",
3
- "version": "7.3.21",
3
+ "version": "7.3.23",
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": {