agent-host-protocol-ui 0.1.0 → 0.1.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.
- package/README.md +11 -3
- package/bin/cli.js +94 -18
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -90,14 +90,22 @@ Launch the UI directly in your browser without cloning or installing:
|
|
|
90
90
|
npx agent-host-protocol-ui
|
|
91
91
|
```
|
|
92
92
|
|
|
93
|
-
|
|
93
|
+
#### CLI Options & External Network Access
|
|
94
94
|
|
|
95
95
|
```sh
|
|
96
|
-
#
|
|
97
|
-
npx agent-host-protocol-ui --host
|
|
96
|
+
# Serve on all network interfaces (0.0.0.0) so it is accessible externally
|
|
97
|
+
npx agent-host-protocol-ui --host 0.0.0.0
|
|
98
|
+
# or:
|
|
99
|
+
npx agent-host-protocol-ui --bind 0.0.0.0
|
|
100
|
+
|
|
101
|
+
# Pre-configure your local or remote agent host connection
|
|
102
|
+
npx agent-host-protocol-ui --agent-host "ws://127.0.0.1:63877?tkn=your-token"
|
|
98
103
|
|
|
99
104
|
# Specify a custom port
|
|
100
105
|
npx agent-host-protocol-ui --port 3000
|
|
106
|
+
|
|
107
|
+
# Run headless without opening local browser (e.g. in remote VM or container)
|
|
108
|
+
npx agent-host-protocol-ui --bind 0.0.0.0 --port 8080 --no-open
|
|
101
109
|
```
|
|
102
110
|
|
|
103
111
|
---
|
package/bin/cli.js
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { exec } from "node:child_process";
|
|
4
4
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
5
5
|
import http from "node:http";
|
|
6
|
+
import os from "node:os";
|
|
6
7
|
import path from "node:path";
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
8
9
|
|
|
@@ -24,20 +25,70 @@ const MIME_TYPES = {
|
|
|
24
25
|
".woff2": "font/woff2",
|
|
25
26
|
};
|
|
26
27
|
|
|
28
|
+
function getNetworkIps() {
|
|
29
|
+
const ips = [];
|
|
30
|
+
try {
|
|
31
|
+
const interfaces = os.networkInterfaces();
|
|
32
|
+
for (const name of Object.keys(interfaces)) {
|
|
33
|
+
const netInterface = interfaces[name];
|
|
34
|
+
if (!netInterface) continue;
|
|
35
|
+
for (const iface of netInterface) {
|
|
36
|
+
if (iface.family === "IPv4" && !iface.internal) {
|
|
37
|
+
ips.push(iface.address);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
} catch {
|
|
42
|
+
// ignore network interface errors
|
|
43
|
+
}
|
|
44
|
+
return ips;
|
|
45
|
+
}
|
|
46
|
+
|
|
27
47
|
// Parse command line arguments
|
|
28
48
|
const args = process.argv.slice(2);
|
|
29
|
-
let port = 5173;
|
|
49
|
+
let port = Number.parseInt(process.env.PORT || "", 10) || 5173;
|
|
50
|
+
let listenHost = process.env.HOST || "localhost";
|
|
30
51
|
let autoOpen = true;
|
|
31
|
-
let
|
|
52
|
+
let agentHostParam = process.env.AGENT_HOST || "";
|
|
32
53
|
|
|
33
54
|
for (let i = 0; i < args.length; i++) {
|
|
34
|
-
|
|
55
|
+
let arg = args[i];
|
|
56
|
+
let value;
|
|
57
|
+
if (arg.includes("=")) {
|
|
58
|
+
const eqIdx = arg.indexOf("=");
|
|
59
|
+
value = arg.slice(eqIdx + 1);
|
|
60
|
+
arg = arg.slice(0, eqIdx);
|
|
61
|
+
}
|
|
62
|
+
|
|
35
63
|
if (arg === "--port" || arg === "-p") {
|
|
36
|
-
port = Number.parseInt(args[++i], 10) || 5173;
|
|
64
|
+
port = Number.parseInt(value ?? args[++i], 10) || 5173;
|
|
37
65
|
} else if (arg === "--no-open") {
|
|
38
66
|
autoOpen = false;
|
|
67
|
+
} else if (arg === "--bind" || arg === "-b" || arg === "--hostname" || arg === "--listen") {
|
|
68
|
+
listenHost = value ?? args[++i] ?? "0.0.0.0";
|
|
39
69
|
} else if (arg === "--host" || arg === "-h") {
|
|
40
|
-
|
|
70
|
+
if (value !== undefined) {
|
|
71
|
+
if (value.startsWith("ws://") || value.startsWith("wss://")) {
|
|
72
|
+
agentHostParam = value;
|
|
73
|
+
} else {
|
|
74
|
+
listenHost = value;
|
|
75
|
+
}
|
|
76
|
+
} else {
|
|
77
|
+
const next = args[i + 1];
|
|
78
|
+
if (!next || next.startsWith("-")) {
|
|
79
|
+
// Flag present without value: bind to 0.0.0.0 (like Vite --host)
|
|
80
|
+
listenHost = "0.0.0.0";
|
|
81
|
+
} else {
|
|
82
|
+
i++;
|
|
83
|
+
if (next.startsWith("ws://") || next.startsWith("wss://")) {
|
|
84
|
+
agentHostParam = next;
|
|
85
|
+
} else {
|
|
86
|
+
listenHost = next;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
} else if (arg === "--agent-host" || arg === "--ws" || arg === "-a") {
|
|
91
|
+
agentHostParam = value ?? args[++i] ?? "";
|
|
41
92
|
} else if (arg === "--help") {
|
|
42
93
|
console.log(`
|
|
43
94
|
agent-host-protocol-ui - Client-side UI for Agent Host Protocol
|
|
@@ -46,10 +97,17 @@ Usage:
|
|
|
46
97
|
npx agent-host-protocol-ui [options]
|
|
47
98
|
|
|
48
99
|
Options:
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
--
|
|
100
|
+
-b, --bind <address> Hostname/IP to listen on (e.g. 0.0.0.0 or localhost, default: localhost)
|
|
101
|
+
--host [address] Bind to address (default: 0.0.0.0 if flag present without value)
|
|
102
|
+
-p, --port <number> Port to listen on (default: 5173 or process.env.PORT)
|
|
103
|
+
-a, --agent-host <ws-url> Pre-configure agent host WebSocket URL
|
|
104
|
+
--no-open Do not automatically open the browser
|
|
105
|
+
--help Show help
|
|
106
|
+
|
|
107
|
+
Environment variables:
|
|
108
|
+
HOST=<address> Default hostname/IP to listen on (e.g. 0.0.0.0)
|
|
109
|
+
PORT=<number> Default port to listen on
|
|
110
|
+
AGENT_HOST=<ws-url> Default agent host WebSocket URL
|
|
53
111
|
`);
|
|
54
112
|
process.exit(0);
|
|
55
113
|
}
|
|
@@ -107,29 +165,47 @@ server.on("error", (err) => {
|
|
|
107
165
|
if (err && typeof err === "object" && "code" in err && err.code === "EADDRINUSE") {
|
|
108
166
|
console.log(`Port ${port} in use, trying ${port + 1}...`);
|
|
109
167
|
port++;
|
|
110
|
-
server.listen(port);
|
|
168
|
+
server.listen(port, listenHost);
|
|
111
169
|
} else {
|
|
112
170
|
console.error("Server error:", err);
|
|
113
171
|
process.exit(1);
|
|
114
172
|
}
|
|
115
173
|
});
|
|
116
174
|
|
|
117
|
-
server.listen(port, () => {
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
175
|
+
server.listen(port, listenHost, () => {
|
|
176
|
+
const isWildcard = listenHost === "0.0.0.0" || listenHost === "::";
|
|
177
|
+
const isLocal = listenHost === "localhost" || listenHost === "127.0.0.1" || listenHost === "::1";
|
|
178
|
+
const querySuffix = agentHostParam ? `?host=${encodeURIComponent(agentHostParam)}` : "";
|
|
179
|
+
|
|
180
|
+
const displayLocalUrl = `http://localhost:${port}${querySuffix}`;
|
|
181
|
+
const openUrl = isLocal || isWildcard ? displayLocalUrl : `http://${listenHost}:${port}${querySuffix}`;
|
|
182
|
+
const networkIps = isWildcard ? getNetworkIps() : [];
|
|
183
|
+
|
|
122
184
|
console.log(`
|
|
123
185
|
┌────────────────────────────────────────────────────────┐
|
|
124
186
|
│ │
|
|
125
187
|
│ Agent Host Protocol UI │
|
|
126
|
-
│
|
|
127
|
-
|
|
188
|
+
│ │`);
|
|
189
|
+
|
|
190
|
+
if (isWildcard) {
|
|
191
|
+
console.log(`│ > Local: ${displayLocalUrl.padEnd(42)}│`);
|
|
192
|
+
for (const ip of networkIps) {
|
|
193
|
+
const netUrl = `http://${ip}:${port}${querySuffix}`;
|
|
194
|
+
console.log(`│ > Network: ${netUrl.padEnd(42)}│`);
|
|
195
|
+
}
|
|
196
|
+
} else if (isLocal) {
|
|
197
|
+
console.log(`│ > Local: ${displayLocalUrl.padEnd(42)}│`);
|
|
198
|
+
} else {
|
|
199
|
+
const customUrl = `http://${listenHost}:${port}${querySuffix}`;
|
|
200
|
+
console.log(`│ > Host: ${customUrl.padEnd(42)}│`);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.log(`│ │
|
|
128
204
|
│ Press Ctrl+C to stop │
|
|
129
205
|
└────────────────────────────────────────────────────────┘
|
|
130
206
|
`);
|
|
131
207
|
if (autoOpen) {
|
|
132
|
-
openBrowser(
|
|
208
|
+
openBrowser(openUrl);
|
|
133
209
|
}
|
|
134
210
|
});
|
|
135
211
|
|
package/package.json
CHANGED