@nekzus/liop-studio 1.0.0-alpha.5 → 1.0.0-alpha.7
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/dist/cli/index.js +95 -16
- package/dist/cli/index.js.map +1 -1
- package/dist/{index-DLA-Sm4s.d.ts → index-Cl7IupN0.d.ts} +2 -0
- package/dist/index.d.ts +9 -3
- package/dist/index.js +74 -13
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +64 -13
- package/dist/server/index.js.map +1 -1
- package/package.json +2 -2
- package/ui/README.md +45 -59
- package/ui/dist/assets/index-BjiNGEL8.js +306 -0
- package/ui/dist/assets/index-Cr1w0czW.css +1 -0
- package/ui/dist/index.html +2 -2
- package/ui/dist/assets/index-BMzlkxln.css +0 -1
- package/ui/dist/assets/index-DQC14us6.js +0 -275
package/dist/cli/index.js
CHANGED
|
@@ -5,9 +5,9 @@ import { Command } from "commander";
|
|
|
5
5
|
import pc2 from "picocolors";
|
|
6
6
|
|
|
7
7
|
// src/server/index.ts
|
|
8
|
-
import
|
|
8
|
+
import path2 from "path";
|
|
9
9
|
import process3 from "process";
|
|
10
|
-
import { fileURLToPath } from "url";
|
|
10
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
11
11
|
import { serve } from "@hono/node-server";
|
|
12
12
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
13
13
|
import { TokenTelemetryEngine as TokenTelemetryEngine5 } from "@nekzus/liop";
|
|
@@ -63,10 +63,29 @@ function validateHttpTarget(targetUrl) {
|
|
|
63
63
|
}
|
|
64
64
|
return parsed;
|
|
65
65
|
}
|
|
66
|
-
function validateHostHeader(host, allowedHosts = [
|
|
66
|
+
function validateHostHeader(host, allowedHosts = [
|
|
67
|
+
"localhost",
|
|
68
|
+
"127.0.0.1",
|
|
69
|
+
"0.0.0.0",
|
|
70
|
+
"::1",
|
|
71
|
+
"[::1]"
|
|
72
|
+
]) {
|
|
67
73
|
if (!host) return false;
|
|
68
|
-
const
|
|
69
|
-
|
|
74
|
+
const trimmed = host.trim();
|
|
75
|
+
let hostname;
|
|
76
|
+
if (trimmed.startsWith("[")) {
|
|
77
|
+
const closingIndex = trimmed.indexOf("]");
|
|
78
|
+
hostname = closingIndex !== -1 ? trimmed.slice(0, closingIndex + 1) : trimmed;
|
|
79
|
+
} else if (trimmed.includes(":") && trimmed.indexOf(":") !== trimmed.lastIndexOf(":")) {
|
|
80
|
+
hostname = trimmed;
|
|
81
|
+
} else {
|
|
82
|
+
hostname = trimmed.split(":")[0];
|
|
83
|
+
}
|
|
84
|
+
hostname = hostname.toLowerCase();
|
|
85
|
+
return allowedHosts.some((allowed) => {
|
|
86
|
+
const normAllowed = allowed.toLowerCase();
|
|
87
|
+
return normAllowed === hostname || hostname === "[::1]" && normAllowed === "::1" || hostname === "::1" && normAllowed === "[::1]";
|
|
88
|
+
});
|
|
70
89
|
}
|
|
71
90
|
|
|
72
91
|
// src/transports/grpc.transport.ts
|
|
@@ -467,16 +486,22 @@ var GrpcTransport = class {
|
|
|
467
486
|
connected = false;
|
|
468
487
|
target;
|
|
469
488
|
token;
|
|
489
|
+
tlsConfig;
|
|
470
490
|
constructor(options) {
|
|
471
491
|
this.target = options.target.replace(/^grpc:\/\//, "");
|
|
472
492
|
this.token = options.token;
|
|
493
|
+
this.tlsConfig = options.tls;
|
|
473
494
|
}
|
|
474
495
|
isConnected() {
|
|
475
496
|
return this.connected && this.client !== null;
|
|
476
497
|
}
|
|
477
498
|
async connect() {
|
|
478
499
|
const tokenProvider = this.token || createStudioTokenProvider();
|
|
479
|
-
|
|
500
|
+
const tls = this.tlsConfig || {
|
|
501
|
+
insecure: true,
|
|
502
|
+
suppressWarning: true
|
|
503
|
+
};
|
|
504
|
+
this.client = new LiopRpcClient(this.target, tls, tokenProvider);
|
|
480
505
|
this.connected = true;
|
|
481
506
|
}
|
|
482
507
|
async disconnect() {
|
|
@@ -1191,9 +1216,7 @@ var MeshTransport = class {
|
|
|
1191
1216
|
if (!this.isConnected()) {
|
|
1192
1217
|
await this.connect();
|
|
1193
1218
|
}
|
|
1194
|
-
const
|
|
1195
|
-
const peerId = clientAny.meshNode?.getPeerId?.()?.toString() || "UnknownPeer";
|
|
1196
|
-
const _connections = clientAny.meshNode?.node?.getConnections?.() || [];
|
|
1219
|
+
const peerId = this.client.peerId ?? "UnknownPeer";
|
|
1197
1220
|
const latencyMs = Math.max(1, Math.round(performance.now() - tStart));
|
|
1198
1221
|
const discovery = NetworkDiscoveryEngine.getInstance();
|
|
1199
1222
|
const meshDiscovered = await discovery.scanNetwork("127.0.0.1").catch(() => []);
|
|
@@ -1878,12 +1901,40 @@ function createTransport(config) {
|
|
|
1878
1901
|
}
|
|
1879
1902
|
}
|
|
1880
1903
|
|
|
1881
|
-
// src/
|
|
1904
|
+
// src/version.ts
|
|
1905
|
+
import fs from "fs";
|
|
1906
|
+
import path from "path";
|
|
1907
|
+
import { fileURLToPath } from "url";
|
|
1882
1908
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
1909
|
+
function getPackageVersion() {
|
|
1910
|
+
try {
|
|
1911
|
+
let currentDir = __dirname;
|
|
1912
|
+
for (let i = 0; i < 4; i++) {
|
|
1913
|
+
const candidate = path.join(currentDir, "package.json");
|
|
1914
|
+
if (fs.existsSync(candidate)) {
|
|
1915
|
+
const raw = fs.readFileSync(candidate, "utf-8");
|
|
1916
|
+
const parsed = JSON.parse(raw);
|
|
1917
|
+
if (parsed.name === "@nekzus/liop-studio" && typeof parsed.version === "string") {
|
|
1918
|
+
return parsed.version;
|
|
1919
|
+
}
|
|
1920
|
+
}
|
|
1921
|
+
currentDir = path.dirname(currentDir);
|
|
1922
|
+
}
|
|
1923
|
+
} catch {
|
|
1924
|
+
}
|
|
1925
|
+
return "1.0.0-alpha.5";
|
|
1926
|
+
}
|
|
1927
|
+
var STUDIO_VERSION = getPackageVersion();
|
|
1928
|
+
|
|
1929
|
+
// src/server/index.ts
|
|
1930
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
1883
1931
|
function createStudioServer(options = {}) {
|
|
1932
|
+
if (!process3.env.LIOP_SUPPRESS_TLS_WARNING) {
|
|
1933
|
+
process3.env.LIOP_SUPPRESS_TLS_WARNING = "true";
|
|
1934
|
+
}
|
|
1884
1935
|
const app = new Hono();
|
|
1885
1936
|
const port = options.port || 16e3;
|
|
1886
|
-
const distPath = options.distPath ||
|
|
1937
|
+
const distPath = options.distPath || path2.resolve(__dirname2, "../../ui/dist");
|
|
1887
1938
|
let activeConfig = options.initialTarget || {
|
|
1888
1939
|
type: "http",
|
|
1889
1940
|
http: { url: process3.env.LIOP_MCP_URL || "http://127.0.0.1:15000/mcp" }
|
|
@@ -1916,7 +1967,7 @@ function createStudioServer(options = {}) {
|
|
|
1916
1967
|
const isConnected = activeTransport.isConnected() && lastReport?.status === "online";
|
|
1917
1968
|
return c.json({
|
|
1918
1969
|
status: isConnected ? "healthy" : "offline",
|
|
1919
|
-
version:
|
|
1970
|
+
version: STUDIO_VERSION,
|
|
1920
1971
|
targetType: activeConfig.type,
|
|
1921
1972
|
connected: isConnected
|
|
1922
1973
|
});
|
|
@@ -1932,7 +1983,7 @@ function createStudioServer(options = {}) {
|
|
|
1932
1983
|
connected: isConnected,
|
|
1933
1984
|
toolsCount: isConnected ? lastReport?.totalTools || 0 : 0,
|
|
1934
1985
|
latencyMs: isConnected ? lastReport?.latencyMs || 0 : 0,
|
|
1935
|
-
version:
|
|
1986
|
+
version: STUDIO_VERSION,
|
|
1936
1987
|
serverInfo: lastReport?.serverInfo
|
|
1937
1988
|
});
|
|
1938
1989
|
});
|
|
@@ -2197,7 +2248,11 @@ function resolveTargetConfig(target, options = {}) {
|
|
|
2197
2248
|
if (isGrpcExplicit || /^([a-zA-Z0-9.-]+):(\d+)$/.test(trimmed) || trimmed.startsWith("grpc://")) {
|
|
2198
2249
|
return {
|
|
2199
2250
|
type: "grpc",
|
|
2200
|
-
grpc: {
|
|
2251
|
+
grpc: {
|
|
2252
|
+
target: trimmed,
|
|
2253
|
+
token,
|
|
2254
|
+
tls: { insecure: true, suppressWarning: true }
|
|
2255
|
+
}
|
|
2201
2256
|
};
|
|
2202
2257
|
}
|
|
2203
2258
|
const parts = trimmed.split(/\s+/);
|
|
@@ -2210,6 +2265,9 @@ function resolveTargetConfig(target, options = {}) {
|
|
|
2210
2265
|
};
|
|
2211
2266
|
}
|
|
2212
2267
|
async function runScan(targetStr, options) {
|
|
2268
|
+
if (!process4.env.LIOP_SUPPRESS_TLS_WARNING) {
|
|
2269
|
+
process4.env.LIOP_SUPPRESS_TLS_WARNING = "true";
|
|
2270
|
+
}
|
|
2213
2271
|
const config = resolveTargetConfig(targetStr, options.token);
|
|
2214
2272
|
const transport = createTransport(config);
|
|
2215
2273
|
try {
|
|
@@ -2237,14 +2295,24 @@ async function main() {
|
|
|
2237
2295
|
const program = new Command();
|
|
2238
2296
|
program.name("liop-studio").description(
|
|
2239
2297
|
"LIOP Sovereign Studio & Mesh Scanner (Universal MCP / LIOP Inspector)"
|
|
2240
|
-
).version(
|
|
2298
|
+
).version(STUDIO_VERSION).option("-p, --port <port>", "Port to bind local Studio server", "16000").option("--no-open", "Do not automatically open browser on launch").option(
|
|
2241
2299
|
"--stdio <command>",
|
|
2242
2300
|
"Initial target: Stdio command (e.g. 'node server.js')"
|
|
2243
2301
|
).option("--http <url>", "Initial target: HTTP / SSE MCP URL").option("--grpc <target>", "Initial target: Native LIOP gRPC endpoint").option("--mesh <multiaddr>", "Initial target: Libp2p P2P bootstrap node").option(
|
|
2244
2302
|
"--token <token>",
|
|
2245
2303
|
"Bearer or access token for target authentication"
|
|
2304
|
+
).option("--tls-ca <path>", "Path to root CA certificate for gRPC target").option(
|
|
2305
|
+
"--tls-cert <path>",
|
|
2306
|
+
"Path to client certificate chain for gRPC target"
|
|
2307
|
+
).option("--tls-key <path>", "Path to client private key for gRPC target").option(
|
|
2308
|
+
"--insecure",
|
|
2309
|
+
"Explicitly permit unencrypted gRPC credentials",
|
|
2310
|
+
true
|
|
2246
2311
|
).action(async (options) => {
|
|
2247
2312
|
const port = Number.parseInt(options.port, 10) || 16e3;
|
|
2313
|
+
if (!options.tlsCa && !options.tlsCert && !options.tlsKey) {
|
|
2314
|
+
process5.env.LIOP_SUPPRESS_TLS_WARNING = "true";
|
|
2315
|
+
}
|
|
2248
2316
|
let initialTarget;
|
|
2249
2317
|
if (options.stdio) {
|
|
2250
2318
|
const parts = options.stdio.trim().split(/\s+/);
|
|
@@ -2260,7 +2328,18 @@ async function main() {
|
|
|
2260
2328
|
} else if (options.grpc) {
|
|
2261
2329
|
initialTarget = {
|
|
2262
2330
|
type: "grpc",
|
|
2263
|
-
grpc: {
|
|
2331
|
+
grpc: {
|
|
2332
|
+
target: options.grpc,
|
|
2333
|
+
token: options.token,
|
|
2334
|
+
tls: options.tlsCa ? {
|
|
2335
|
+
rootCert: options.tlsCa,
|
|
2336
|
+
certChain: options.tlsCert,
|
|
2337
|
+
privateKey: options.tlsKey
|
|
2338
|
+
} : {
|
|
2339
|
+
insecure: true,
|
|
2340
|
+
suppressWarning: true
|
|
2341
|
+
}
|
|
2342
|
+
}
|
|
2264
2343
|
};
|
|
2265
2344
|
} else if (options.mesh) {
|
|
2266
2345
|
initialTarget = {
|