@opentrust/cli 7.0.0 → 7.1.0

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.
package/README.md CHANGED
@@ -14,48 +14,68 @@ Or run directly with `npx`:
14
14
  npx @opentrust/cli <command>
15
15
  ```
16
16
 
17
- ## Prerequisites
17
+ ## Quick Start
18
18
 
19
- - **Node.js** >= 18
20
- - **pnpm** >= 9 (Dashboard uses pnpm monorepo)
21
- - Clone the [opentrust](https://github.com/opentrust-dev/opentrust) repo first
19
+ ```bash
20
+ # 1. Initialize project (clone repo into current directory)
21
+ mkdir my-project && cd my-project
22
+ opentrust init
22
23
 
23
- ## Usage
24
+ # 2a. Local mode — install dependencies and start
25
+ opentrust setup
26
+ opentrust start
24
27
 
25
- Navigate to your opentrust project directory, then:
28
+ # 2b. Docker mode build and start via Docker Compose
29
+ opentrust start --docker
30
+ ```
26
31
 
27
- ```bash
28
- # Install all dependencies, build, and initialize databases
29
- opentrust setup
32
+ ## Commands
30
33
 
31
- # Start all services (core + dashboard + gateway)
32
- opentrust start
34
+ | Command | Description |
35
+ |---------|-------------|
36
+ | `opentrust init` | Clone OpenTrust repository into current directory |
37
+ | `opentrust setup` | Install dependencies, build, and initialize databases |
38
+ | `opentrust start [service]` | Start services (core, dashboard, gateway, or all) |
39
+ | `opentrust stop [service]` | Stop services |
40
+ | `opentrust status` | Show status of all services |
41
+ | `opentrust logs <service>` | Tail logs for a service |
33
42
 
34
- # Start a single service
35
- opentrust start core
43
+ ### Docker Mode
36
44
 
37
- # Check status of all services
38
- opentrust status
45
+ All service commands support `--docker` (`-d`) flag to use Docker Compose:
39
46
 
40
- # Stop all services
41
- opentrust stop
47
+ ```bash
48
+ opentrust start --docker # docker compose up -d --build
49
+ opentrust stop --docker # docker compose down
50
+ opentrust status --docker # docker compose ps + health checks
51
+ opentrust logs --docker core # docker compose logs core
52
+ opentrust setup --docker # docker compose build
53
+ ```
42
54
 
43
- # Stop a single service
44
- opentrust stop gateway
55
+ ### Init Options
45
56
 
46
- # View logs
47
- opentrust logs core
48
- opentrust logs dashboard -f # follow mode
49
- opentrust logs gateway -n 100 # last 100 lines
57
+ ```bash
58
+ opentrust init --repo <url> # Custom git repository URL
59
+ opentrust init --branch <name> # Specific branch (default: main)
50
60
  ```
51
61
 
52
62
  ## Services
53
63
 
54
64
  | Service | Port | Description |
55
65
  |---------|------|-------------|
56
- | **Core** | 53666 | Security engine — content detection (S01-S10), behavior assessment, Agent registry |
57
- | **Dashboard** | 53667/53668 | Management panel — Agent assets, risk graph, policy management, detection logs |
58
- | **Gateway** | 8900 | AI security gateway — LLM API proxy with automatic PII/credential sanitization |
66
+ | **Core** | 53666 | Security engine — content detection (S01-S10), behavior assessment |
67
+ | **Dashboard** | 53667/53668 | Management panel — Agent assets, risk graph, policies, logs |
68
+ | **Gateway** | 8900 | AI security gateway — LLM API proxy with PII/credential sanitization |
69
+
70
+ ## Prerequisites
71
+
72
+ **Docker mode (recommended):**
73
+ - Docker >= 20.10
74
+ - Docker Compose >= 2.0
75
+
76
+ **Local mode:**
77
+ - Node.js >= 18 (Gateway requires >= 22)
78
+ - pnpm >= 9 (Dashboard uses pnpm monorepo)
59
79
 
60
80
  ## Environment Variables
61
81
 
@@ -0,0 +1,2 @@
1
+ import { Command } from "commander";
2
+ export declare function registerInitCommand(program: Command): void;
@@ -0,0 +1,75 @@
1
+ import { execSync } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ const DEFAULT_REPO = "https://github.com/anthropics/opentrust.git";
5
+ export function registerInitCommand(program) {
6
+ program
7
+ .command("init")
8
+ .description("Initialize OpenTrust project (clone repository into current directory)")
9
+ .option("--repo <url>", "Git repository URL", DEFAULT_REPO)
10
+ .option("--branch <name>", "Git branch to clone", "main")
11
+ .action(async (options) => {
12
+ const cwd = process.cwd();
13
+ const pkgPath = path.join(cwd, "package.json");
14
+ if (fs.existsSync(pkgPath)) {
15
+ try {
16
+ const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
17
+ if (pkg.name === "opentrust") {
18
+ console.log("OpenTrust project already exists in current directory.");
19
+ console.log("Run 'opentrust setup' to install dependencies.");
20
+ return;
21
+ }
22
+ }
23
+ catch { }
24
+ }
25
+ try {
26
+ execSync("git --version", { stdio: "ignore" });
27
+ }
28
+ catch {
29
+ console.error("Error: git is not installed. Please install git first.");
30
+ process.exit(1);
31
+ }
32
+ const isEmpty = fs.readdirSync(cwd).filter(f => !f.startsWith(".")).length === 0;
33
+ const targetDir = isEmpty ? cwd : path.join(cwd, "opentrust");
34
+ if (!isEmpty && fs.existsSync(targetDir)) {
35
+ console.error(`Directory already exists: ${targetDir}`);
36
+ console.error("Remove it or choose a different location.");
37
+ process.exit(1);
38
+ }
39
+ console.log("Initializing OpenTrust project...\n");
40
+ console.log(` Repository: ${options.repo}`);
41
+ console.log(` Branch: ${options.branch}`);
42
+ console.log(` Target: ${targetDir}\n`);
43
+ try {
44
+ if (isEmpty) {
45
+ execSync(`git clone --depth 1 --branch ${options.branch} ${options.repo} .`, { cwd, stdio: "inherit" });
46
+ }
47
+ else {
48
+ execSync(`git clone --depth 1 --branch ${options.branch} ${options.repo} opentrust`, { cwd, stdio: "inherit" });
49
+ }
50
+ }
51
+ catch {
52
+ console.error("\nFailed to clone repository.");
53
+ process.exit(1);
54
+ }
55
+ console.log("\n-------------------------------------------");
56
+ console.log("OpenTrust project initialized!");
57
+ console.log("-------------------------------------------\n");
58
+ if (isEmpty) {
59
+ console.log("Next steps:");
60
+ console.log(" opentrust setup # Install dependencies (local mode)");
61
+ console.log(" opentrust start # Start all services\n");
62
+ console.log("Or use Docker:");
63
+ console.log(" opentrust start --docker # Start via Docker Compose");
64
+ }
65
+ else {
66
+ console.log("Next steps:");
67
+ console.log(" cd opentrust");
68
+ console.log(" opentrust setup # Install dependencies (local mode)");
69
+ console.log(" opentrust start # Start all services\n");
70
+ console.log("Or use Docker:");
71
+ console.log(" cd opentrust");
72
+ console.log(" opentrust start --docker # Start via Docker Compose");
73
+ }
74
+ });
75
+ }
@@ -1,13 +1,27 @@
1
1
  import { spawn } from "node:child_process";
2
2
  import fs from "node:fs";
3
3
  import { SERVICES, getAllServiceKeys } from "../lib/process-manager.js";
4
+ import { requireProject } from "../lib/paths.js";
5
+ import { dockerLogs, getAllDockerServiceKeys } from "../lib/docker-manager.js";
4
6
  export function registerLogsCommand(program) {
5
7
  program
6
8
  .command("logs <service>")
7
9
  .description("Tail logs for a service (core, dashboard, gateway)")
8
10
  .option("-n, --lines <n>", "Number of lines to show", "50")
9
11
  .option("-f, --follow", "Follow log output", false)
12
+ .option("-d, --docker", "Use Docker Compose logs")
10
13
  .action(async (service, options) => {
14
+ if (options.docker) {
15
+ requireProject();
16
+ if (!getAllDockerServiceKeys().includes(service)) {
17
+ console.error(`Unknown service: ${service}`);
18
+ console.error(`Available: ${getAllDockerServiceKeys().join(", ")}`);
19
+ process.exit(1);
20
+ }
21
+ dockerLogs(service, options);
22
+ return;
23
+ }
24
+ requireProject();
11
25
  const svc = SERVICES[service];
12
26
  if (!svc) {
13
27
  console.error(`Unknown service: ${service}`);
@@ -1,11 +1,19 @@
1
1
  import { execSync } from "node:child_process";
2
2
  import fs from "node:fs";
3
- import { paths } from "../lib/paths.js";
3
+ import { paths, requireProject } from "../lib/paths.js";
4
+ import { dockerSetup } from "../lib/docker-manager.js";
4
5
  export function registerSetupCommand(program) {
5
6
  program
6
7
  .command("setup")
7
8
  .description("Install dependencies, build, and initialize databases")
8
- .action(async () => {
9
+ .option("-d, --docker", "Build Docker images instead of local setup")
10
+ .action(async (options) => {
11
+ if (options.docker) {
12
+ requireProject();
13
+ dockerSetup();
14
+ return;
15
+ }
16
+ requireProject();
9
17
  console.log("OpenTrust Setup\n");
10
18
  const steps = [
11
19
  {
@@ -1,9 +1,23 @@
1
1
  import { startService, getAllServiceKeys, SERVICES } from "../lib/process-manager.js";
2
+ import { requireProject } from "../lib/paths.js";
3
+ import { dockerStart, getAllDockerServiceKeys } from "../lib/docker-manager.js";
2
4
  export function registerStartCommand(program) {
3
5
  program
4
6
  .command("start [service]")
5
7
  .description("Start services (core, dashboard, gateway, or all)")
6
- .action(async (service) => {
8
+ .option("-d, --docker", "Use Docker Compose to start services")
9
+ .action(async (service, options) => {
10
+ if (options.docker) {
11
+ requireProject();
12
+ if (service && !getAllDockerServiceKeys().includes(service)) {
13
+ console.error(`Unknown service: ${service}`);
14
+ console.error(`Available: ${getAllDockerServiceKeys().join(", ")}`);
15
+ process.exit(1);
16
+ }
17
+ dockerStart(service);
18
+ return;
19
+ }
20
+ requireProject();
7
21
  const keys = service ? [service] : getAllServiceKeys();
8
22
  for (const key of keys) {
9
23
  if (!SERVICES[key]) {
@@ -1,9 +1,18 @@
1
1
  import { getStatus, checkHealth, getAllServiceKeys, SERVICES } from "../lib/process-manager.js";
2
+ import { requireProject } from "../lib/paths.js";
3
+ import { dockerStatus } from "../lib/docker-manager.js";
2
4
  export function registerStatusCommand(program) {
3
5
  program
4
6
  .command("status")
5
7
  .description("Show status of all OpenTrust services")
6
- .action(async () => {
8
+ .option("-d, --docker", "Show Docker Compose service status")
9
+ .action(async (options) => {
10
+ if (options.docker) {
11
+ requireProject();
12
+ await dockerStatus();
13
+ return;
14
+ }
15
+ requireProject();
7
16
  console.log("OpenTrust Service Status\n");
8
17
  const keys = getAllServiceKeys();
9
18
  for (const key of keys) {
@@ -1,9 +1,23 @@
1
1
  import { stopService, getAllServiceKeys, SERVICES } from "../lib/process-manager.js";
2
+ import { requireProject } from "../lib/paths.js";
3
+ import { dockerStop, getAllDockerServiceKeys } from "../lib/docker-manager.js";
2
4
  export function registerStopCommand(program) {
3
5
  program
4
6
  .command("stop [service]")
5
7
  .description("Stop services (core, dashboard, gateway, or all)")
6
- .action(async (service) => {
8
+ .option("-d, --docker", "Use Docker Compose to stop services")
9
+ .action(async (service, options) => {
10
+ if (options.docker) {
11
+ requireProject();
12
+ if (service && !getAllDockerServiceKeys().includes(service)) {
13
+ console.error(`Unknown service: ${service}`);
14
+ console.error(`Available: ${getAllDockerServiceKeys().join(", ")}`);
15
+ process.exit(1);
16
+ }
17
+ dockerStop(service);
18
+ return;
19
+ }
20
+ requireProject();
7
21
  const keys = service ? [service] : getAllServiceKeys();
8
22
  for (const key of keys) {
9
23
  if (!SERVICES[key]) {
package/dist/index.js CHANGED
@@ -3,6 +3,7 @@ import { Command } from "commander";
3
3
  import { readFileSync } from "node:fs";
4
4
  import { fileURLToPath } from "node:url";
5
5
  import { dirname, join } from "node:path";
6
+ import { registerInitCommand } from "./commands/init.js";
6
7
  import { registerStartCommand } from "./commands/start.js";
7
8
  import { registerStopCommand } from "./commands/stop.js";
8
9
  import { registerStatusCommand } from "./commands/status.js";
@@ -13,11 +14,12 @@ const pkg = JSON.parse(readFileSync(join(__dirname, "../package.json"), "utf-8")
13
14
  const program = new Command();
14
15
  program
15
16
  .name("opentrust")
16
- .description("OpenTrust — manage local AI security services")
17
+ .description("OpenTrust — AI Agent Runtime Security Platform")
17
18
  .version(pkg.version);
19
+ registerInitCommand(program);
20
+ registerSetupCommand(program);
18
21
  registerStartCommand(program);
19
22
  registerStopCommand(program);
20
23
  registerStatusCommand(program);
21
- registerSetupCommand(program);
22
24
  registerLogsCommand(program);
23
25
  program.parse();
@@ -0,0 +1,9 @@
1
+ export declare function dockerStart(service?: string): void;
2
+ export declare function dockerStop(service?: string): void;
3
+ export declare function dockerStatus(): Promise<void>;
4
+ export declare function dockerLogs(service: string, options: {
5
+ lines: string;
6
+ follow: boolean;
7
+ }): void;
8
+ export declare function dockerSetup(): void;
9
+ export declare function getAllDockerServiceKeys(): string[];
@@ -0,0 +1,175 @@
1
+ import { execSync, spawn } from "node:child_process";
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { paths } from "./paths.js";
5
+ const DOCKER_SERVICES = ["core", "dashboard", "gateway"];
6
+ const SERVICE_PORTS = {
7
+ core: 53666,
8
+ dashboard: 53667,
9
+ gateway: 8900,
10
+ };
11
+ const HEALTH_URLS = {
12
+ core: "http://localhost:53666/health",
13
+ dashboard: "http://localhost:53667/health",
14
+ gateway: "http://localhost:8900/health",
15
+ };
16
+ function getComposeCwd() {
17
+ return paths.projectRoot;
18
+ }
19
+ function ensureDockerCompose() {
20
+ const composePath = path.join(getComposeCwd(), "docker-compose.yml");
21
+ if (!fs.existsSync(composePath)) {
22
+ console.error("docker-compose.yml not found in project root.");
23
+ console.error("Run 'opentrust init' first to initialize the project.");
24
+ process.exit(1);
25
+ }
26
+ }
27
+ function getComposeCommand() {
28
+ try {
29
+ execSync("docker compose version", { stdio: "ignore" });
30
+ return "docker compose";
31
+ }
32
+ catch {
33
+ try {
34
+ execSync("docker-compose --version", { stdio: "ignore" });
35
+ return "docker-compose";
36
+ }
37
+ catch {
38
+ console.error("Error: Docker Compose not found.");
39
+ console.error("Install Docker Desktop or Docker Compose: https://docs.docker.com/compose/install/");
40
+ process.exit(1);
41
+ }
42
+ }
43
+ }
44
+ export function dockerStart(service) {
45
+ ensureDockerCompose();
46
+ const compose = getComposeCommand();
47
+ const cwd = getComposeCwd();
48
+ const services = service ? service : "";
49
+ console.log(service
50
+ ? `Starting ${service} via Docker Compose...`
51
+ : "Starting all services via Docker Compose...");
52
+ try {
53
+ execSync(`${compose} up -d --build ${services}`, { cwd, stdio: "inherit" });
54
+ }
55
+ catch {
56
+ console.error("\nDocker Compose failed. Check the output above for details.");
57
+ process.exit(1);
58
+ }
59
+ console.log("\nUse 'opentrust status --docker' to check health.");
60
+ console.log("Use 'opentrust logs --docker <service>' to view output.");
61
+ }
62
+ export function dockerStop(service) {
63
+ ensureDockerCompose();
64
+ const compose = getComposeCommand();
65
+ const cwd = getComposeCwd();
66
+ if (service) {
67
+ console.log(`Stopping ${service} via Docker Compose...`);
68
+ try {
69
+ execSync(`${compose} stop ${service}`, { cwd, stdio: "inherit" });
70
+ }
71
+ catch {
72
+ console.error(`Failed to stop ${service}.`);
73
+ }
74
+ }
75
+ else {
76
+ console.log("Stopping all services via Docker Compose...");
77
+ try {
78
+ execSync(`${compose} down`, { cwd, stdio: "inherit" });
79
+ }
80
+ catch {
81
+ console.error("Failed to stop services.");
82
+ }
83
+ }
84
+ }
85
+ export async function dockerStatus() {
86
+ ensureDockerCompose();
87
+ const compose = getComposeCommand();
88
+ const cwd = getComposeCwd();
89
+ console.log("OpenTrust Service Status (Docker)\n");
90
+ let psOutput = "";
91
+ try {
92
+ psOutput = execSync(`${compose} ps --format json`, { cwd, encoding: "utf-8" });
93
+ }
94
+ catch {
95
+ // fallback to non-json
96
+ try {
97
+ execSync(`${compose} ps`, { cwd, stdio: "inherit" });
98
+ }
99
+ catch { }
100
+ return;
101
+ }
102
+ const containers = psOutput.trim()
103
+ ? psOutput.trim().split("\n").map(line => {
104
+ try {
105
+ return JSON.parse(line);
106
+ }
107
+ catch {
108
+ return null;
109
+ }
110
+ }).filter(Boolean)
111
+ : [];
112
+ for (const svcKey of DOCKER_SERVICES) {
113
+ const port = SERVICE_PORTS[svcKey];
114
+ const container = containers.find((c) => c.Service === svcKey || c.Name?.includes(`opentrust-${svcKey}`));
115
+ let running = false;
116
+ let healthy = false;
117
+ let statusText = "not created";
118
+ if (container) {
119
+ const state = (container.State || "").toLowerCase();
120
+ const health = (container.Health || "").toLowerCase();
121
+ running = state === "running";
122
+ healthy = health === "healthy";
123
+ statusText = running
124
+ ? healthy ? "running (healthy)" : "running (starting...)"
125
+ : state || "stopped";
126
+ }
127
+ const icon = running
128
+ ? healthy ? "\x1b[32m●\x1b[0m" : "\x1b[33m●\x1b[0m"
129
+ : "\x1b[31m●\x1b[0m";
130
+ const name = svcKey.charAt(0).toUpperCase() + svcKey.slice(1);
131
+ console.log(` ${icon} ${name.padEnd(12)} ${statusText.padEnd(35)} port ${port}`);
132
+ }
133
+ console.log("");
134
+ }
135
+ export function dockerLogs(service, options) {
136
+ ensureDockerCompose();
137
+ const compose = getComposeCommand();
138
+ const cwd = getComposeCwd();
139
+ const args = [`--tail=${options.lines}`];
140
+ if (options.follow)
141
+ args.push("-f");
142
+ args.push(service);
143
+ const child = spawn(compose.split(" ")[0], [...compose.split(" ").slice(1), "logs", ...args], {
144
+ cwd,
145
+ stdio: "inherit",
146
+ });
147
+ child.on("error", (err) => {
148
+ console.error(`Failed to get logs: ${err.message}`);
149
+ });
150
+ process.on("SIGINT", () => {
151
+ child.kill();
152
+ process.exit(0);
153
+ });
154
+ }
155
+ export function dockerSetup() {
156
+ ensureDockerCompose();
157
+ const compose = getComposeCommand();
158
+ const cwd = getComposeCwd();
159
+ console.log("OpenTrust Setup (Docker)\n");
160
+ console.log("Building Docker images...\n");
161
+ try {
162
+ execSync(`${compose} build`, { cwd, stdio: "inherit" });
163
+ }
164
+ catch {
165
+ console.error("\nDocker build failed. Check the output above for details.");
166
+ process.exit(1);
167
+ }
168
+ console.log("\n-------------------------------------------");
169
+ console.log("Setup complete!");
170
+ console.log("-------------------------------------------");
171
+ console.log("\nRun 'opentrust start --docker' to launch all services.");
172
+ }
173
+ export function getAllDockerServiceKeys() {
174
+ return [...DOCKER_SERVICES];
175
+ }
@@ -1,3 +1,6 @@
1
+ export declare function isProjectAvailable(): boolean;
2
+ export declare function requireProject(): void;
3
+ export declare function hasDockerCompose(): boolean;
1
4
  export declare const paths: {
2
5
  projectRoot: string;
3
6
  runtime: string;
package/dist/lib/paths.js CHANGED
@@ -44,6 +44,24 @@ function isOpenTrustRoot(dir) {
44
44
  }
45
45
  }
46
46
  const projectRoot = findProjectRoot();
47
+ export function isProjectAvailable() {
48
+ return isOpenTrustRoot(projectRoot);
49
+ }
50
+ export function requireProject() {
51
+ if (!isProjectAvailable()) {
52
+ console.error("OpenTrust project not found in current directory.");
53
+ console.error("");
54
+ console.error("To initialize a new project:");
55
+ console.error(" opentrust init");
56
+ console.error("");
57
+ console.error("Or set OPENTRUST_HOME to point to your project:");
58
+ console.error(" export OPENTRUST_HOME=/path/to/opentrust");
59
+ process.exit(1);
60
+ }
61
+ }
62
+ export function hasDockerCompose() {
63
+ return fs.existsSync(path.join(projectRoot, "docker-compose.yml"));
64
+ }
47
65
  /** ~/.opentrust/ — runtime data (pid files, logs) */
48
66
  const runtimeDir = path.join(os.homedir(), ".opentrust");
49
67
  export const paths = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opentrust/cli",
3
- "version": "7.0.0",
3
+ "version": "7.1.0",
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": {