@opentrust/cli 7.0.0 → 7.1.1
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 +47 -27
- package/dist/commands/init.d.ts +2 -0
- package/dist/commands/init.js +94 -0
- package/dist/commands/logs.js +14 -0
- package/dist/commands/setup.js +127 -47
- package/dist/commands/start.js +15 -1
- package/dist/commands/status.js +10 -1
- package/dist/commands/stop.js +15 -1
- package/dist/index.js +4 -2
- package/dist/lib/docker-manager.d.ts +9 -0
- package/dist/lib/docker-manager.js +175 -0
- package/dist/lib/paths.d.ts +10 -0
- package/dist/lib/paths.js +73 -17
- package/dist/lib/process-manager.d.ts +1 -0
- package/dist/lib/process-manager.js +88 -36
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @opentrust/cli
|
|
2
2
|
|
|
3
|
-
CLI tool to manage [OpenTrust](https://github.com/opentrust
|
|
3
|
+
CLI tool to manage [OpenTrust](https://github.com/opentrust/opentrust) — an open-source AI Agent Runtime Security Platform.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -14,48 +14,68 @@ Or run directly with `npx`:
|
|
|
14
14
|
npx @opentrust/cli <command>
|
|
15
15
|
```
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## Quick Start
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
-
|
|
19
|
+
```bash
|
|
20
|
+
# 1. Initialize project (clone repo into current directory)
|
|
21
|
+
mkdir my-project && cd my-project
|
|
22
|
+
opentrust init
|
|
22
23
|
|
|
23
|
-
|
|
24
|
+
# 2a. Local mode — install dependencies and start
|
|
25
|
+
opentrust setup
|
|
26
|
+
opentrust start
|
|
24
27
|
|
|
25
|
-
|
|
28
|
+
# 2b. Docker mode — build and start via Docker Compose
|
|
29
|
+
opentrust start --docker
|
|
30
|
+
```
|
|
26
31
|
|
|
27
|
-
|
|
28
|
-
# Install all dependencies, build, and initialize databases
|
|
29
|
-
opentrust setup
|
|
32
|
+
## Commands
|
|
30
33
|
|
|
31
|
-
|
|
32
|
-
|
|
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
|
-
|
|
35
|
-
opentrust start core
|
|
43
|
+
### Docker Mode
|
|
36
44
|
|
|
37
|
-
|
|
38
|
-
opentrust status
|
|
45
|
+
All service commands support `--docker` (`-d`) flag to use Docker Compose:
|
|
39
46
|
|
|
40
|
-
|
|
41
|
-
opentrust
|
|
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
|
-
|
|
44
|
-
opentrust stop gateway
|
|
55
|
+
### Init Options
|
|
45
56
|
|
|
46
|
-
|
|
47
|
-
opentrust
|
|
48
|
-
opentrust
|
|
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
|
|
57
|
-
| **Dashboard** | 53667/53668 | Management panel — Agent assets, risk graph,
|
|
58
|
-
| **Gateway** | 8900 | AI security gateway — LLM API proxy with
|
|
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,94 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import fs from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
const SCAFFOLD_PKG = {
|
|
5
|
+
name: "opentrust-project",
|
|
6
|
+
version: "1.0.0",
|
|
7
|
+
private: true,
|
|
8
|
+
description: "OpenTrust local deployment",
|
|
9
|
+
scripts: {
|
|
10
|
+
setup: "opentrust setup",
|
|
11
|
+
start: "opentrust start",
|
|
12
|
+
stop: "opentrust stop",
|
|
13
|
+
status: "opentrust status",
|
|
14
|
+
},
|
|
15
|
+
dependencies: {
|
|
16
|
+
"@opentrust/core": "^7.1.0",
|
|
17
|
+
"@opentrust/gateway": "^7.1.0",
|
|
18
|
+
"@opentrust/dashboard": "^7.1.0",
|
|
19
|
+
},
|
|
20
|
+
};
|
|
21
|
+
const ENV_TEMPLATE = `# OpenTrust Configuration
|
|
22
|
+
|
|
23
|
+
# Dashboard
|
|
24
|
+
DEV_MODE=true
|
|
25
|
+
DASHBOARD_MODE=embedded
|
|
26
|
+
DASHBOARD_DATA_DIR=./data
|
|
27
|
+
|
|
28
|
+
# Core
|
|
29
|
+
CORE_PORT=53666
|
|
30
|
+
|
|
31
|
+
# Gateway
|
|
32
|
+
GATEWAY_PORT=8900
|
|
33
|
+
# ANTHROPIC_API_KEY=sk-ant-xxx
|
|
34
|
+
# OPENAI_API_KEY=sk-xxx
|
|
35
|
+
# GEMINI_API_KEY=xxx
|
|
36
|
+
`;
|
|
37
|
+
export function registerInitCommand(program) {
|
|
38
|
+
program
|
|
39
|
+
.command("init")
|
|
40
|
+
.description("Initialize an OpenTrust project (install packages via npm)")
|
|
41
|
+
.option("--registry <url>", "npm registry URL")
|
|
42
|
+
.action(async (options) => {
|
|
43
|
+
const cwd = process.cwd();
|
|
44
|
+
const pkgPath = path.join(cwd, "package.json");
|
|
45
|
+
if (fs.existsSync(pkgPath)) {
|
|
46
|
+
try {
|
|
47
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
48
|
+
if (pkg.name === "opentrust" || pkg.name === "opentrust-project") {
|
|
49
|
+
console.log("OpenTrust project already exists in current directory.");
|
|
50
|
+
console.log("Run 'opentrust setup' to install dependencies.");
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
catch { }
|
|
55
|
+
}
|
|
56
|
+
console.log("Initializing OpenTrust project...\n");
|
|
57
|
+
// Write package.json
|
|
58
|
+
fs.writeFileSync(pkgPath, JSON.stringify(SCAFFOLD_PKG, null, 2) + "\n", "utf-8");
|
|
59
|
+
console.log(" Created package.json");
|
|
60
|
+
// Write .env
|
|
61
|
+
const envPath = path.join(cwd, ".env");
|
|
62
|
+
if (!fs.existsSync(envPath)) {
|
|
63
|
+
fs.writeFileSync(envPath, ENV_TEMPLATE, "utf-8");
|
|
64
|
+
console.log(" Created .env");
|
|
65
|
+
}
|
|
66
|
+
// Create data directory
|
|
67
|
+
const dataDir = path.join(cwd, "data");
|
|
68
|
+
if (!fs.existsSync(dataDir)) {
|
|
69
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
70
|
+
console.log(" Created data/");
|
|
71
|
+
}
|
|
72
|
+
// Install dependencies
|
|
73
|
+
console.log("\nInstalling packages...\n");
|
|
74
|
+
const registryArg = options.registry ? ` --registry ${options.registry}` : "";
|
|
75
|
+
try {
|
|
76
|
+
execSync(`npm install${registryArg}`, { cwd, stdio: "inherit" });
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
console.error("\nnpm install failed. Check the output above for details.");
|
|
80
|
+
process.exit(1);
|
|
81
|
+
}
|
|
82
|
+
console.log("\n-------------------------------------------");
|
|
83
|
+
console.log("OpenTrust project initialized!");
|
|
84
|
+
console.log("-------------------------------------------\n");
|
|
85
|
+
console.log("Next steps:");
|
|
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");
|
|
93
|
+
});
|
|
94
|
+
}
|
package/dist/commands/logs.js
CHANGED
|
@@ -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}`);
|
package/dist/commands/setup.js
CHANGED
|
@@ -1,57 +1,137 @@
|
|
|
1
1
|
import { execSync } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { paths, requireProject, projectMode, projectRoot } from "../lib/paths.js";
|
|
5
|
+
import { dockerSetup } from "../lib/docker-manager.js";
|
|
4
6
|
export function registerSetupCommand(program) {
|
|
5
7
|
program
|
|
6
8
|
.command("setup")
|
|
7
9
|
.description("Install dependencies, build, and initialize databases")
|
|
8
|
-
.
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
10
|
+
.option("-d, --docker", "Build Docker images instead of local setup")
|
|
11
|
+
.action(async (options) => {
|
|
12
|
+
if (options.docker) {
|
|
13
|
+
requireProject();
|
|
14
|
+
dockerSetup();
|
|
15
|
+
return;
|
|
16
|
+
}
|
|
17
|
+
requireProject();
|
|
18
|
+
if (projectMode === "npm") {
|
|
19
|
+
runNpmSetup();
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
runMonorepoSetup();
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function runMonorepoSetup() {
|
|
27
|
+
console.log("OpenTrust Setup (monorepo)\n");
|
|
28
|
+
const steps = [
|
|
29
|
+
{
|
|
30
|
+
label: "Core",
|
|
31
|
+
cwd: paths.core,
|
|
32
|
+
commands: ["npm install"],
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
label: "Dashboard",
|
|
36
|
+
cwd: paths.dashboard,
|
|
37
|
+
commands: [
|
|
38
|
+
"pnpm install",
|
|
39
|
+
"pnpm build",
|
|
40
|
+
"pnpm db:generate",
|
|
41
|
+
"pnpm db:migrate",
|
|
42
|
+
"pnpm db:seed",
|
|
43
|
+
],
|
|
44
|
+
},
|
|
45
|
+
{
|
|
46
|
+
label: "Gateway",
|
|
47
|
+
cwd: paths.gateway,
|
|
48
|
+
commands: ["npm install"],
|
|
49
|
+
},
|
|
50
|
+
];
|
|
51
|
+
for (const step of steps) {
|
|
52
|
+
if (!fs.existsSync(step.cwd)) {
|
|
53
|
+
console.log(` ⚠ ${step.label}: directory not found, skipping`);
|
|
54
|
+
continue;
|
|
55
|
+
}
|
|
56
|
+
console.log(`Setting up ${step.label}...`);
|
|
57
|
+
for (const cmd of step.commands) {
|
|
58
|
+
try {
|
|
59
|
+
console.log(` $ ${cmd}`);
|
|
60
|
+
execSync(cmd, { cwd: step.cwd, stdio: "inherit" });
|
|
37
61
|
}
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
console.log(` $ ${cmd}`);
|
|
42
|
-
execSync(cmd, { cwd: step.cwd, stdio: "inherit" });
|
|
43
|
-
}
|
|
44
|
-
catch (err) {
|
|
45
|
-
console.error(` Failed: ${cmd}`);
|
|
46
|
-
process.exit(1);
|
|
47
|
-
}
|
|
62
|
+
catch (err) {
|
|
63
|
+
console.error(` Failed: ${cmd}`);
|
|
64
|
+
process.exit(1);
|
|
48
65
|
}
|
|
49
|
-
console.log(` ${step.label} ready.\n`);
|
|
50
66
|
}
|
|
51
|
-
console.log(
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
67
|
+
console.log(` ${step.label} ready.\n`);
|
|
68
|
+
}
|
|
69
|
+
printSetupDone();
|
|
70
|
+
}
|
|
71
|
+
function runNpmSetup() {
|
|
72
|
+
console.log("OpenTrust Setup (npm packages)\n");
|
|
73
|
+
const dataDir = path.join(projectRoot, "data");
|
|
74
|
+
if (!fs.existsSync(dataDir)) {
|
|
75
|
+
fs.mkdirSync(dataDir, { recursive: true });
|
|
76
|
+
}
|
|
77
|
+
const env = {
|
|
78
|
+
...process.env,
|
|
79
|
+
DASHBOARD_DATA_DIR: dataDir,
|
|
80
|
+
DEV_MODE: "true",
|
|
81
|
+
};
|
|
82
|
+
// Load .env from project root if exists
|
|
83
|
+
const envFile = path.join(projectRoot, ".env");
|
|
84
|
+
if (fs.existsSync(envFile)) {
|
|
85
|
+
const content = fs.readFileSync(envFile, "utf-8");
|
|
86
|
+
for (const line of content.split("\n")) {
|
|
87
|
+
const trimmed = line.trim();
|
|
88
|
+
if (!trimmed || trimmed.startsWith("#"))
|
|
89
|
+
continue;
|
|
90
|
+
const eqIdx = trimmed.indexOf("=");
|
|
91
|
+
if (eqIdx > 0) {
|
|
92
|
+
const key = trimmed.slice(0, eqIdx).trim();
|
|
93
|
+
const val = trimmed.slice(eqIdx + 1).trim();
|
|
94
|
+
if (!env[key])
|
|
95
|
+
env[key] = val;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
// Run db:migrate
|
|
100
|
+
const migrateScript = path.join(projectRoot, "node_modules", "@opentrust", "db", "dist", "migrate.js");
|
|
101
|
+
if (fs.existsSync(migrateScript)) {
|
|
102
|
+
console.log("Running database migrations...");
|
|
103
|
+
try {
|
|
104
|
+
execSync(`node ${migrateScript}`, { cwd: projectRoot, stdio: "inherit", env });
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
console.error(" Migration failed.");
|
|
108
|
+
process.exit(1);
|
|
109
|
+
}
|
|
110
|
+
console.log(" Migrations complete.\n");
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
console.log(" ⚠ @opentrust/db not found, skipping migrations.");
|
|
114
|
+
console.log(" Run 'npm install' first.\n");
|
|
115
|
+
}
|
|
116
|
+
// Run db:seed
|
|
117
|
+
const seedScript = path.join(projectRoot, "node_modules", "@opentrust", "db", "dist", "seed.js");
|
|
118
|
+
if (fs.existsSync(seedScript)) {
|
|
119
|
+
console.log("Seeding database...");
|
|
120
|
+
try {
|
|
121
|
+
execSync(`node ${seedScript}`, { cwd: projectRoot, stdio: "inherit", env });
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
console.error(" Seed failed.");
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
console.log(" Seed complete.\n");
|
|
128
|
+
}
|
|
129
|
+
printSetupDone();
|
|
130
|
+
}
|
|
131
|
+
function printSetupDone() {
|
|
132
|
+
console.log("-------------------------------------------");
|
|
133
|
+
console.log("Setup complete!");
|
|
134
|
+
console.log("-------------------------------------------");
|
|
135
|
+
console.log("\nRun 'opentrust start' to launch all services.");
|
|
136
|
+
console.log("Or start individually: 'opentrust start core'");
|
|
57
137
|
}
|
package/dist/commands/start.js
CHANGED
|
@@ -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
|
-
.
|
|
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]) {
|
package/dist/commands/status.js
CHANGED
|
@@ -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
|
-
.
|
|
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) {
|
package/dist/commands/stop.js
CHANGED
|
@@ -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
|
-
.
|
|
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 —
|
|
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
|
+
}
|
package/dist/lib/paths.d.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
export type ProjectMode = "monorepo" | "npm" | "none";
|
|
2
|
+
export declare const projectMode: ProjectMode;
|
|
3
|
+
export declare const projectRoot: string;
|
|
4
|
+
export declare function isProjectAvailable(): boolean;
|
|
5
|
+
export declare function requireProject(): void;
|
|
6
|
+
export declare function hasDockerCompose(): boolean;
|
|
7
|
+
/** Resolve a node_modules package entry point */
|
|
8
|
+
export declare function resolveNpmPackage(packageName: string): string | null;
|
|
9
|
+
/** Resolve a bin script from a node_modules package */
|
|
10
|
+
export declare function resolveNpmBin(packageName: string, binName: string): string | null;
|
|
1
11
|
export declare const paths: {
|
|
2
12
|
projectRoot: string;
|
|
3
13
|
runtime: string;
|
package/dist/lib/paths.js
CHANGED
|
@@ -3,35 +3,41 @@ import os from "node:os";
|
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { fileURLToPath } from "node:url";
|
|
5
5
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
-
function
|
|
6
|
+
function detectProjectMode() {
|
|
7
7
|
// 1. OPENTRUST_HOME env var takes priority
|
|
8
8
|
if (process.env.OPENTRUST_HOME) {
|
|
9
|
-
|
|
9
|
+
const dir = path.resolve(process.env.OPENTRUST_HOME);
|
|
10
|
+
if (isMonorepoRoot(dir))
|
|
11
|
+
return { mode: "monorepo", root: dir };
|
|
12
|
+
if (isNpmProject(dir))
|
|
13
|
+
return { mode: "npm", root: dir };
|
|
14
|
+
return { mode: "none", root: dir };
|
|
10
15
|
}
|
|
11
|
-
// 2. Check if cwd looks like the opentrust project root
|
|
12
16
|
const cwd = process.cwd();
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
+
// 2. Check cwd
|
|
18
|
+
if (isMonorepoRoot(cwd))
|
|
19
|
+
return { mode: "monorepo", root: cwd };
|
|
20
|
+
if (isNpmProject(cwd))
|
|
21
|
+
return { mode: "npm", root: cwd };
|
|
22
|
+
// 3. Walk up from cwd
|
|
17
23
|
let dir = cwd;
|
|
18
24
|
while (true) {
|
|
19
25
|
const parent = path.dirname(dir);
|
|
20
26
|
if (parent === dir)
|
|
21
27
|
break;
|
|
22
28
|
dir = parent;
|
|
23
|
-
if (
|
|
24
|
-
return dir;
|
|
29
|
+
if (isMonorepoRoot(dir))
|
|
30
|
+
return { mode: "monorepo", root: dir };
|
|
31
|
+
if (isNpmProject(dir))
|
|
32
|
+
return { mode: "npm", root: dir };
|
|
25
33
|
}
|
|
26
|
-
// 4. Fallback: resolve relative to __dirname (
|
|
34
|
+
// 4. Fallback: resolve relative to __dirname (within monorepo)
|
|
27
35
|
const fallback = path.resolve(__dirname, "../../..");
|
|
28
|
-
if (
|
|
29
|
-
return fallback;
|
|
30
|
-
}
|
|
31
|
-
// 5. Last resort: use cwd and let commands fail with meaningful errors
|
|
32
|
-
return cwd;
|
|
36
|
+
if (isMonorepoRoot(fallback))
|
|
37
|
+
return { mode: "monorepo", root: fallback };
|
|
38
|
+
return { mode: "none", root: cwd };
|
|
33
39
|
}
|
|
34
|
-
function
|
|
40
|
+
function isMonorepoRoot(dir) {
|
|
35
41
|
try {
|
|
36
42
|
const pkgPath = path.join(dir, "package.json");
|
|
37
43
|
if (!fs.existsSync(pkgPath))
|
|
@@ -43,7 +49,57 @@ function isOpenTrustRoot(dir) {
|
|
|
43
49
|
return false;
|
|
44
50
|
}
|
|
45
51
|
}
|
|
46
|
-
|
|
52
|
+
function isNpmProject(dir) {
|
|
53
|
+
try {
|
|
54
|
+
const pkgPath = path.join(dir, "package.json");
|
|
55
|
+
if (!fs.existsSync(pkgPath))
|
|
56
|
+
return false;
|
|
57
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
58
|
+
if (pkg.name === "opentrust-project")
|
|
59
|
+
return true;
|
|
60
|
+
const deps = { ...pkg.dependencies, ...pkg.devDependencies };
|
|
61
|
+
return !!deps["@opentrust/core"] || !!deps["@opentrust/dashboard"];
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
return false;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
const detected = detectProjectMode();
|
|
68
|
+
export const projectMode = detected.mode;
|
|
69
|
+
export const projectRoot = detected.root;
|
|
70
|
+
export function isProjectAvailable() {
|
|
71
|
+
return detected.mode !== "none";
|
|
72
|
+
}
|
|
73
|
+
export function requireProject() {
|
|
74
|
+
if (!isProjectAvailable()) {
|
|
75
|
+
console.error("OpenTrust project not found in current directory.");
|
|
76
|
+
console.error("");
|
|
77
|
+
console.error("To initialize a new project:");
|
|
78
|
+
console.error(" opentrust init");
|
|
79
|
+
console.error("");
|
|
80
|
+
console.error("Or set OPENTRUST_HOME to point to your project:");
|
|
81
|
+
console.error(" export OPENTRUST_HOME=/path/to/opentrust");
|
|
82
|
+
process.exit(1);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
export function hasDockerCompose() {
|
|
86
|
+
return fs.existsSync(path.join(projectRoot, "docker-compose.yml"));
|
|
87
|
+
}
|
|
88
|
+
/** Resolve a node_modules package entry point */
|
|
89
|
+
export function resolveNpmPackage(packageName) {
|
|
90
|
+
const entryPoints = [
|
|
91
|
+
path.join(projectRoot, "node_modules", packageName, "dist", "index.js"),
|
|
92
|
+
path.join(projectRoot, "node_modules", packageName, "index.js"),
|
|
93
|
+
];
|
|
94
|
+
return entryPoints.find(p => fs.existsSync(p)) ?? null;
|
|
95
|
+
}
|
|
96
|
+
/** Resolve a bin script from a node_modules package */
|
|
97
|
+
export function resolveNpmBin(packageName, binName) {
|
|
98
|
+
const binPath = path.join(projectRoot, "node_modules", ".bin", binName);
|
|
99
|
+
if (fs.existsSync(binPath))
|
|
100
|
+
return binPath;
|
|
101
|
+
return null;
|
|
102
|
+
}
|
|
47
103
|
/** ~/.opentrust/ — runtime data (pid files, logs) */
|
|
48
104
|
const runtimeDir = path.join(os.homedir(), ".opentrust");
|
|
49
105
|
export const paths = {
|
|
@@ -1,38 +1,91 @@
|
|
|
1
1
|
import { spawn } from "node:child_process";
|
|
2
2
|
import fs from "node:fs";
|
|
3
|
-
import
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { paths, projectMode, projectRoot, resolveNpmPackage } from "./paths.js";
|
|
5
|
+
function buildServices() {
|
|
6
|
+
if (projectMode === "npm") {
|
|
7
|
+
return buildNpmServices();
|
|
8
|
+
}
|
|
9
|
+
return buildMonorepoServices();
|
|
10
|
+
}
|
|
11
|
+
function buildMonorepoServices() {
|
|
12
|
+
return {
|
|
13
|
+
core: {
|
|
14
|
+
name: "Core",
|
|
15
|
+
cwd: paths.core,
|
|
16
|
+
command: "npx",
|
|
17
|
+
args: ["tsx", "src/index.ts"],
|
|
18
|
+
pidFile: paths.corePid,
|
|
19
|
+
logFile: paths.coreLog,
|
|
20
|
+
port: 53666,
|
|
21
|
+
healthUrl: "http://localhost:53666/health",
|
|
22
|
+
},
|
|
23
|
+
dashboard: {
|
|
24
|
+
name: "Dashboard",
|
|
25
|
+
cwd: paths.dashboard,
|
|
26
|
+
command: "npx",
|
|
27
|
+
args: ["turbo", "dev"],
|
|
28
|
+
pidFile: paths.dashboardPid,
|
|
29
|
+
logFile: paths.dashboardLog,
|
|
30
|
+
port: 53667,
|
|
31
|
+
healthUrl: "http://localhost:53667/health",
|
|
32
|
+
},
|
|
33
|
+
gateway: {
|
|
34
|
+
name: "Gateway",
|
|
35
|
+
cwd: paths.gateway,
|
|
36
|
+
command: "npx",
|
|
37
|
+
args: ["tsx", "src/index.ts"],
|
|
38
|
+
pidFile: paths.gatewayPid,
|
|
39
|
+
logFile: paths.gatewayLog,
|
|
40
|
+
port: 8900,
|
|
41
|
+
healthUrl: "http://localhost:8900/health",
|
|
42
|
+
},
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function buildNpmServices() {
|
|
46
|
+
const coreEntry = resolveNpmPackage("@opentrust/core");
|
|
47
|
+
const dashboardEntry = resolveNpmPackage("@opentrust/dashboard");
|
|
48
|
+
const gatewayEntry = resolveNpmPackage("@opentrust/gateway");
|
|
49
|
+
const dataDir = path.join(projectRoot, "data");
|
|
50
|
+
return {
|
|
51
|
+
core: {
|
|
52
|
+
name: "Core",
|
|
53
|
+
cwd: projectRoot,
|
|
54
|
+
command: "node",
|
|
55
|
+
args: [coreEntry || "node_modules/@opentrust/core/dist/index.js"],
|
|
56
|
+
pidFile: paths.corePid,
|
|
57
|
+
logFile: paths.coreLog,
|
|
58
|
+
port: 53666,
|
|
59
|
+
healthUrl: "http://localhost:53666/health",
|
|
60
|
+
},
|
|
61
|
+
dashboard: {
|
|
62
|
+
name: "Dashboard",
|
|
63
|
+
cwd: projectRoot,
|
|
64
|
+
command: "node",
|
|
65
|
+
args: [dashboardEntry || "node_modules/@opentrust/dashboard/dist/index.js"],
|
|
66
|
+
pidFile: paths.dashboardPid,
|
|
67
|
+
logFile: paths.dashboardLog,
|
|
68
|
+
port: 53667,
|
|
69
|
+
healthUrl: "http://localhost:53667/health",
|
|
70
|
+
env: {
|
|
71
|
+
DASHBOARD_MODE: "embedded",
|
|
72
|
+
DEV_MODE: "true",
|
|
73
|
+
DASHBOARD_DATA_DIR: dataDir,
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
gateway: {
|
|
77
|
+
name: "Gateway",
|
|
78
|
+
cwd: projectRoot,
|
|
79
|
+
command: "node",
|
|
80
|
+
args: [gatewayEntry || "node_modules/@opentrust/gateway/dist/index.js"],
|
|
81
|
+
pidFile: paths.gatewayPid,
|
|
82
|
+
logFile: paths.gatewayLog,
|
|
83
|
+
port: 8900,
|
|
84
|
+
healthUrl: "http://localhost:8900/health",
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
export const SERVICES = buildServices();
|
|
36
89
|
function ensureDirs() {
|
|
37
90
|
for (const dir of [paths.runtime, paths.logs]) {
|
|
38
91
|
if (!fs.existsSync(dir))
|
|
@@ -45,7 +98,7 @@ export function startService(key) {
|
|
|
45
98
|
console.error(`Unknown service: ${key}`);
|
|
46
99
|
return false;
|
|
47
100
|
}
|
|
48
|
-
if (!fs.existsSync(svc.cwd)) {
|
|
101
|
+
if (projectMode === "monorepo" && !fs.existsSync(svc.cwd)) {
|
|
49
102
|
console.error(` ${svc.name}: directory not found at ${svc.cwd}`);
|
|
50
103
|
return false;
|
|
51
104
|
}
|
|
@@ -58,7 +111,7 @@ export function startService(key) {
|
|
|
58
111
|
const logFd = fs.openSync(svc.logFile, "a");
|
|
59
112
|
const child = spawn(svc.command, svc.args, {
|
|
60
113
|
cwd: svc.cwd,
|
|
61
|
-
env: { ...process.env, FORCE_COLOR: "0" },
|
|
114
|
+
env: { ...process.env, FORCE_COLOR: "0", ...svc.env },
|
|
62
115
|
stdio: ["ignore", logFd, logFd],
|
|
63
116
|
detached: true,
|
|
64
117
|
});
|
|
@@ -85,7 +138,6 @@ export function stopService(key) {
|
|
|
85
138
|
return false;
|
|
86
139
|
}
|
|
87
140
|
try {
|
|
88
|
-
// Kill the process group (negative PID) to stop all children
|
|
89
141
|
process.kill(-status.pid, "SIGTERM");
|
|
90
142
|
}
|
|
91
143
|
catch (err) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentrust/cli",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.1.1",
|
|
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": {
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
"llm-security",
|
|
34
34
|
"ai-agent"
|
|
35
35
|
],
|
|
36
|
-
"homepage": "https://github.com/opentrust
|
|
36
|
+
"homepage": "https://github.com/opentrust/opentrust#readme",
|
|
37
37
|
"repository": {
|
|
38
38
|
"type": "git",
|
|
39
|
-
"url": "git+https://github.com/opentrust
|
|
39
|
+
"url": "git+https://github.com/opentrust/opentrust.git",
|
|
40
40
|
"directory": "cli"
|
|
41
41
|
},
|
|
42
42
|
"bugs": {
|
|
43
|
-
"url": "https://github.com/opentrust
|
|
43
|
+
"url": "https://github.com/opentrust/opentrust/issues"
|
|
44
44
|
},
|
|
45
45
|
"author": "OpenTrust",
|
|
46
46
|
"license": "Apache-2.0",
|