@nekzus/liop-studio 1.0.0-alpha.2 → 1.0.0-alpha.21
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 +71 -28
- package/dist/cli/index.js +118 -28
- 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 +97 -25
- package/dist/index.js.map +1 -1
- package/dist/server/index.d.ts +2 -1
- package/dist/server/index.js +87 -25
- package/dist/server/index.js.map +1 -1
- package/package.json +6 -6
- 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/favicon.svg +14 -0
- package/ui/dist/icons.svg +24 -0
- package/ui/dist/index.html +14 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as _hono_node_server from '@hono/node-server';
|
|
2
2
|
import * as hono_types from 'hono/types';
|
|
3
3
|
import { Hono } from 'hono';
|
|
4
|
+
import { LiopTlsOptions } from '@nekzus/liop';
|
|
4
5
|
|
|
5
6
|
type TargetTransportType = "stdio" | "http" | "grpc" | "mesh";
|
|
6
7
|
interface TargetConnectionConfig {
|
|
@@ -19,6 +20,7 @@ interface TargetConnectionConfig {
|
|
|
19
20
|
target: string;
|
|
20
21
|
useTls?: boolean;
|
|
21
22
|
token?: string;
|
|
23
|
+
tls?: LiopTlsOptions;
|
|
22
24
|
};
|
|
23
25
|
mesh?: {
|
|
24
26
|
bootstrapNodes?: string[];
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { T as TargetConnectionConfig, S as ScanReport, a as ScannedTargetNode, E as EnrichedTool, b as StudioTransport, c as TargetTransportType, d as ExecutionResult } from './index-
|
|
2
|
-
export { e as ExecutionTelemetry, f as ServerOptions, g as createStudioServer } from './index-
|
|
1
|
+
import { T as TargetConnectionConfig, S as ScanReport, a as ScannedTargetNode, E as EnrichedTool, b as StudioTransport, c as TargetTransportType, d as ExecutionResult } from './index-Cl7IupN0.js';
|
|
2
|
+
export { e as ExecutionTelemetry, f as ServerOptions, g as createStudioServer } from './index-Cl7IupN0.js';
|
|
3
|
+
import { LiopTlsOptions } from '@nekzus/liop';
|
|
3
4
|
import '@hono/node-server';
|
|
4
5
|
import 'hono/types';
|
|
5
6
|
import 'hono';
|
|
@@ -73,6 +74,7 @@ declare function validateHttpTarget(targetUrl: string): URL;
|
|
|
73
74
|
declare const sanitizeUrl: typeof validateHttpTarget;
|
|
74
75
|
/**
|
|
75
76
|
* Validates Host headers to prevent DNS Rebinding attacks on local ports.
|
|
77
|
+
* Supports IPv4, localhost and IPv6 loopback ([::1] / ::1).
|
|
76
78
|
*/
|
|
77
79
|
declare function validateHostHeader(host: string | undefined, allowedHosts?: string[]): boolean;
|
|
78
80
|
|
|
@@ -80,6 +82,7 @@ interface GrpcTransportOptions {
|
|
|
80
82
|
target: string;
|
|
81
83
|
useTls?: boolean;
|
|
82
84
|
token?: string;
|
|
85
|
+
tls?: LiopTlsOptions;
|
|
83
86
|
}
|
|
84
87
|
declare class GrpcTransport implements StudioTransport {
|
|
85
88
|
readonly type: TargetTransportType;
|
|
@@ -87,6 +90,7 @@ declare class GrpcTransport implements StudioTransport {
|
|
|
87
90
|
private connected;
|
|
88
91
|
private target;
|
|
89
92
|
private token?;
|
|
93
|
+
private tlsConfig?;
|
|
90
94
|
constructor(options: GrpcTransportOptions);
|
|
91
95
|
isConnected(): boolean;
|
|
92
96
|
connect(): Promise<void>;
|
|
@@ -170,4 +174,6 @@ declare class StdioTransport implements StudioTransport {
|
|
|
170
174
|
|
|
171
175
|
declare function createTransport(config: TargetConnectionConfig): StudioTransport;
|
|
172
176
|
|
|
173
|
-
|
|
177
|
+
declare const STUDIO_VERSION: string;
|
|
178
|
+
|
|
179
|
+
export { EnrichedTool, ExecutionResult, GrpcTransport, type GrpcTransportOptions, HttpTransport, type HttpTransportOptions, MeshTransport, type MeshTransportOptions, NetworkDiscoveryEngine, STUDIO_VERSION, ScanReport, ScannedTargetNode, StdioTransport, type StdioTransportOptions, StudioTransport, TargetConnectionConfig, TargetTransportType, createTransport, formatScanTable, resolveTargetConfig, runScan, sanitizeCommand, sanitizeUrl, validateHostHeader, validateHttpTarget };
|
package/dist/index.js
CHANGED
|
@@ -23,7 +23,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
23
23
|
role: "Clinical Healthcare & EHR Patient Records",
|
|
24
24
|
isolation: "pnet Swarm Key (PSK) + HIPAA Strict Mode",
|
|
25
25
|
dataset: "2,500 clinical EHR patient records",
|
|
26
|
-
defaultTool: "Analyze_Synthetic_Medical_Records"
|
|
26
|
+
defaultTool: "Analyze_Synthetic_Medical_Records",
|
|
27
|
+
defaultTools: ["Analyze_Synthetic_Medical_Records"]
|
|
27
28
|
},
|
|
28
29
|
{
|
|
29
30
|
id: "bank",
|
|
@@ -35,7 +36,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
35
36
|
role: "Core Banking & Financial Settlement",
|
|
36
37
|
isolation: "pnet Swarm Key (PSK) + Differential Privacy",
|
|
37
38
|
dataset: "1,500 synthetic accounts ($148M balance)",
|
|
38
|
-
defaultTool: "Analyze_Synthetic_Bank_Transactions"
|
|
39
|
+
defaultTool: "Analyze_Synthetic_Bank_Transactions",
|
|
40
|
+
defaultTools: ["Analyze_Synthetic_Bank_Transactions"]
|
|
39
41
|
},
|
|
40
42
|
{
|
|
41
43
|
id: "blg",
|
|
@@ -46,7 +48,12 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
46
48
|
tierLabel: "Tier 1: Sovereign Enclaves (In-Situ Origin)",
|
|
47
49
|
role: "Dual-NIC Perimeter Security Bridge (Tier 1 <-> Tier 2)",
|
|
48
50
|
isolation: "6-Layer Zero-Trust + AST Guardian + Egress Shield",
|
|
49
|
-
defaultTool: "BLG_Inspect_Enclave_Perimeter"
|
|
51
|
+
defaultTool: "BLG_Inspect_Enclave_Perimeter",
|
|
52
|
+
defaultTools: [
|
|
53
|
+
"BLG_Inspect_Enclave_Perimeter",
|
|
54
|
+
"BLG_Execute_Healthcare_Analytics",
|
|
55
|
+
"BLG_Execute_Banking_Analytics"
|
|
56
|
+
]
|
|
50
57
|
},
|
|
51
58
|
{
|
|
52
59
|
id: "oracle",
|
|
@@ -58,7 +65,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
58
65
|
role: "Real-time High Frequency Trading Market Simulator",
|
|
59
66
|
isolation: "Consortium Node + 50ms Tick Streaming Buffer",
|
|
60
67
|
dataset: "8 Instruments + L2 Orderbook",
|
|
61
|
-
defaultTool: "Analyze_HFT_Market_Data"
|
|
68
|
+
defaultTool: "Analyze_HFT_Market_Data",
|
|
69
|
+
defaultTools: ["Analyze_HFT_Market_Data", "LiopMeshStatus"]
|
|
62
70
|
},
|
|
63
71
|
{
|
|
64
72
|
id: "relay",
|
|
@@ -68,7 +76,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
68
76
|
tierLabel: "Tier 2: Consortium Routing & Gateways",
|
|
69
77
|
role: "Kademlia DHT & libp2p Circuit Relay v2 Node",
|
|
70
78
|
isolation: "Public Swarm Mesh Relay",
|
|
71
|
-
defaultTool: "LiopMeshStatus"
|
|
79
|
+
defaultTool: "LiopMeshStatus",
|
|
80
|
+
defaultTools: ["LiopMeshStatus"]
|
|
72
81
|
},
|
|
73
82
|
{
|
|
74
83
|
id: "nexus",
|
|
@@ -78,7 +87,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
78
87
|
tierLabel: "Tier 2: Consortium Routing & Gateways",
|
|
79
88
|
role: "OAuth 2.1 RFC 8707 Auth Server & Mesh Authority",
|
|
80
89
|
isolation: "Zero-Trust Identity Provider",
|
|
81
|
-
defaultTool: "Authenticate_Client"
|
|
90
|
+
defaultTool: "Authenticate_Client",
|
|
91
|
+
defaultTools: ["Authenticate_Client"]
|
|
82
92
|
},
|
|
83
93
|
{
|
|
84
94
|
id: "edge",
|
|
@@ -90,7 +100,8 @@ var DEFAULT_PRESET_PROFILES = [
|
|
|
90
100
|
role: "Edge Telemetry & Hostile 3G WAN Industrial Node",
|
|
91
101
|
isolation: "WAN Jitter/Loss Resistant Client",
|
|
92
102
|
dataset: "Edge Telemetry Sensors (Pressure, RPM, Temp)",
|
|
93
|
-
defaultTool: "Analyze_IoT_Sensor_Data"
|
|
103
|
+
defaultTool: "Analyze_IoT_Sensor_Data",
|
|
104
|
+
defaultTools: ["Analyze_IoT_Sensor_Data"]
|
|
94
105
|
}
|
|
95
106
|
];
|
|
96
107
|
var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
|
|
@@ -123,7 +134,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
|
|
|
123
134
|
/**
|
|
124
135
|
* Probe a specific HTTP/Health endpoint dynamically.
|
|
125
136
|
*/
|
|
126
|
-
async probeHttpNode(host, port, timeoutMs =
|
|
137
|
+
async probeHttpNode(host, port, timeoutMs = 3500) {
|
|
127
138
|
const url = `http://${host}:${port}`;
|
|
128
139
|
const t0 = performance.now();
|
|
129
140
|
const controller = new AbortController();
|
|
@@ -210,7 +221,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
|
|
|
210
221
|
peerId: probe.peerId || `peer-${profile.id}`,
|
|
211
222
|
multiaddrs: probe.multiaddrs || [],
|
|
212
223
|
version: probe.version || "2.5.0",
|
|
213
|
-
tools: probe.tools && probe.tools.length > 0 ? probe.tools : [],
|
|
224
|
+
tools: probe.tools && probe.tools.length > 0 ? probe.tools : profile.defaultTools || (profile.defaultTool ? [profile.defaultTool] : []),
|
|
214
225
|
role: profile.role,
|
|
215
226
|
isolation: profile.isolation,
|
|
216
227
|
dataset: profile.dataset,
|
|
@@ -232,7 +243,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
|
|
|
232
243
|
peerId: `peer-${profile.id}`,
|
|
233
244
|
multiaddrs: [],
|
|
234
245
|
version: "2.5.0",
|
|
235
|
-
tools: [],
|
|
246
|
+
tools: profile.defaultTools || (profile.defaultTool ? [profile.defaultTool] : []),
|
|
236
247
|
role: profile.role,
|
|
237
248
|
isolation: profile.isolation,
|
|
238
249
|
dataset: profile.dataset,
|
|
@@ -270,7 +281,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
|
|
|
270
281
|
const probe = await this.probeHttpNode(host, matchedProfile.httpPort);
|
|
271
282
|
const isOnline = status === "online" || Boolean(probe?.tools) && (probe?.tools?.length ?? 0) > 0;
|
|
272
283
|
const nodeName = probe?.name?.replace("PRODUCTION-", "").replace(/-/g, " ") || matchedProfile.defaultName;
|
|
273
|
-
const defaultTools = matchedProfile.defaultTool ? [matchedProfile.defaultTool] : ["Execute_WASI_Logic"];
|
|
284
|
+
const defaultTools = matchedProfile.defaultTools || (matchedProfile.defaultTool ? [matchedProfile.defaultTool] : ["Execute_WASI_Logic"]);
|
|
274
285
|
const tools = isOnline ? probe?.tools && probe.tools.length > 0 ? probe.tools : defaultTools : [];
|
|
275
286
|
const enriched = isOnline && probe?.enrichedTools && probe.enrichedTools.length > 0 ? probe.enrichedTools : tools.map((t) => ({
|
|
276
287
|
name: t,
|
|
@@ -388,16 +399,22 @@ var GrpcTransport = class {
|
|
|
388
399
|
connected = false;
|
|
389
400
|
target;
|
|
390
401
|
token;
|
|
402
|
+
tlsConfig;
|
|
391
403
|
constructor(options) {
|
|
392
404
|
this.target = options.target.replace(/^grpc:\/\//, "");
|
|
393
405
|
this.token = options.token;
|
|
406
|
+
this.tlsConfig = options.tls;
|
|
394
407
|
}
|
|
395
408
|
isConnected() {
|
|
396
409
|
return this.connected && this.client !== null;
|
|
397
410
|
}
|
|
398
411
|
async connect() {
|
|
399
412
|
const tokenProvider = this.token || createStudioTokenProvider();
|
|
400
|
-
|
|
413
|
+
const tls = this.tlsConfig || {
|
|
414
|
+
insecure: true,
|
|
415
|
+
suppressWarning: true
|
|
416
|
+
};
|
|
417
|
+
this.client = new LiopRpcClient(this.target, tls, tokenProvider);
|
|
401
418
|
this.connected = true;
|
|
402
419
|
}
|
|
403
420
|
async disconnect() {
|
|
@@ -800,10 +817,29 @@ function validateHttpTarget(targetUrl) {
|
|
|
800
817
|
return parsed;
|
|
801
818
|
}
|
|
802
819
|
var sanitizeUrl = validateHttpTarget;
|
|
803
|
-
function validateHostHeader(host, allowedHosts = [
|
|
820
|
+
function validateHostHeader(host, allowedHosts = [
|
|
821
|
+
"localhost",
|
|
822
|
+
"127.0.0.1",
|
|
823
|
+
"0.0.0.0",
|
|
824
|
+
"::1",
|
|
825
|
+
"[::1]"
|
|
826
|
+
]) {
|
|
804
827
|
if (!host) return false;
|
|
805
|
-
const
|
|
806
|
-
|
|
828
|
+
const trimmed = host.trim();
|
|
829
|
+
let hostname;
|
|
830
|
+
if (trimmed.startsWith("[")) {
|
|
831
|
+
const closingIndex = trimmed.indexOf("]");
|
|
832
|
+
hostname = closingIndex !== -1 ? trimmed.slice(0, closingIndex + 1) : trimmed;
|
|
833
|
+
} else if (trimmed.includes(":") && trimmed.indexOf(":") !== trimmed.lastIndexOf(":")) {
|
|
834
|
+
hostname = trimmed;
|
|
835
|
+
} else {
|
|
836
|
+
hostname = trimmed.split(":")[0];
|
|
837
|
+
}
|
|
838
|
+
hostname = hostname.toLowerCase();
|
|
839
|
+
return allowedHosts.some((allowed) => {
|
|
840
|
+
const normAllowed = allowed.toLowerCase();
|
|
841
|
+
return normAllowed === hostname || hostname === "[::1]" && normAllowed === "::1" || hostname === "::1" && normAllowed === "[::1]";
|
|
842
|
+
});
|
|
807
843
|
}
|
|
808
844
|
|
|
809
845
|
// src/transports/http.transport.ts
|
|
@@ -1170,9 +1206,7 @@ var MeshTransport = class {
|
|
|
1170
1206
|
if (!this.isConnected()) {
|
|
1171
1207
|
await this.connect();
|
|
1172
1208
|
}
|
|
1173
|
-
const
|
|
1174
|
-
const peerId = clientAny.meshNode?.getPeerId?.()?.toString() || "UnknownPeer";
|
|
1175
|
-
const _connections = clientAny.meshNode?.node?.getConnections?.() || [];
|
|
1209
|
+
const peerId = this.client.peerId ?? "UnknownPeer";
|
|
1176
1210
|
const latencyMs = Math.max(1, Math.round(performance.now() - tStart));
|
|
1177
1211
|
const discovery = NetworkDiscoveryEngine.getInstance();
|
|
1178
1212
|
const meshDiscovered = await discovery.scanNetwork("127.0.0.1").catch(() => []);
|
|
@@ -1945,7 +1979,11 @@ function resolveTargetConfig(target, options = {}) {
|
|
|
1945
1979
|
if (isGrpcExplicit || /^([a-zA-Z0-9.-]+):(\d+)$/.test(trimmed) || trimmed.startsWith("grpc://")) {
|
|
1946
1980
|
return {
|
|
1947
1981
|
type: "grpc",
|
|
1948
|
-
grpc: {
|
|
1982
|
+
grpc: {
|
|
1983
|
+
target: trimmed,
|
|
1984
|
+
token,
|
|
1985
|
+
tls: { insecure: true, suppressWarning: true }
|
|
1986
|
+
}
|
|
1949
1987
|
};
|
|
1950
1988
|
}
|
|
1951
1989
|
const parts = trimmed.split(/\s+/);
|
|
@@ -1958,6 +1996,9 @@ function resolveTargetConfig(target, options = {}) {
|
|
|
1958
1996
|
};
|
|
1959
1997
|
}
|
|
1960
1998
|
async function runScan(targetStr, options) {
|
|
1999
|
+
if (!process3.env.LIOP_SUPPRESS_TLS_WARNING) {
|
|
2000
|
+
process3.env.LIOP_SUPPRESS_TLS_WARNING = "true";
|
|
2001
|
+
}
|
|
1961
2002
|
const config = resolveTargetConfig(targetStr, options.token);
|
|
1962
2003
|
const transport = createTransport(config);
|
|
1963
2004
|
try {
|
|
@@ -1981,19 +2022,49 @@ async function runScan(targetStr, options) {
|
|
|
1981
2022
|
}
|
|
1982
2023
|
|
|
1983
2024
|
// src/server/index.ts
|
|
1984
|
-
import
|
|
2025
|
+
import path2 from "path";
|
|
1985
2026
|
import process4 from "process";
|
|
1986
|
-
import { fileURLToPath } from "url";
|
|
2027
|
+
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
1987
2028
|
import { serve } from "@hono/node-server";
|
|
1988
2029
|
import { serveStatic } from "@hono/node-server/serve-static";
|
|
1989
2030
|
import { TokenTelemetryEngine as TokenTelemetryEngine5 } from "@nekzus/liop";
|
|
1990
2031
|
import { Hono } from "hono";
|
|
1991
2032
|
import { streamSSE } from "hono/streaming";
|
|
2033
|
+
|
|
2034
|
+
// src/version.ts
|
|
2035
|
+
import fs from "fs";
|
|
2036
|
+
import path from "path";
|
|
2037
|
+
import { fileURLToPath } from "url";
|
|
1992
2038
|
var __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
2039
|
+
function getPackageVersion() {
|
|
2040
|
+
try {
|
|
2041
|
+
let currentDir = __dirname;
|
|
2042
|
+
for (let i = 0; i < 4; i++) {
|
|
2043
|
+
const candidate = path.join(currentDir, "package.json");
|
|
2044
|
+
if (fs.existsSync(candidate)) {
|
|
2045
|
+
const raw = fs.readFileSync(candidate, "utf-8");
|
|
2046
|
+
const parsed = JSON.parse(raw);
|
|
2047
|
+
if (parsed.name === "@nekzus/liop-studio" && typeof parsed.version === "string") {
|
|
2048
|
+
return parsed.version;
|
|
2049
|
+
}
|
|
2050
|
+
}
|
|
2051
|
+
currentDir = path.dirname(currentDir);
|
|
2052
|
+
}
|
|
2053
|
+
} catch {
|
|
2054
|
+
}
|
|
2055
|
+
return "1.0.0-alpha.5";
|
|
2056
|
+
}
|
|
2057
|
+
var STUDIO_VERSION = getPackageVersion();
|
|
2058
|
+
|
|
2059
|
+
// src/server/index.ts
|
|
2060
|
+
var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
|
|
1993
2061
|
function createStudioServer(options = {}) {
|
|
2062
|
+
if (!process4.env.LIOP_SUPPRESS_TLS_WARNING) {
|
|
2063
|
+
process4.env.LIOP_SUPPRESS_TLS_WARNING = "true";
|
|
2064
|
+
}
|
|
1994
2065
|
const app = new Hono();
|
|
1995
2066
|
const port = options.port || 16e3;
|
|
1996
|
-
const distPath = options.distPath ||
|
|
2067
|
+
const distPath = options.distPath || path2.resolve(__dirname2, "../../ui/dist");
|
|
1997
2068
|
let activeConfig = options.initialTarget || {
|
|
1998
2069
|
type: "http",
|
|
1999
2070
|
http: { url: process4.env.LIOP_MCP_URL || "http://127.0.0.1:15000/mcp" }
|
|
@@ -2013,7 +2084,7 @@ function createStudioServer(options = {}) {
|
|
|
2013
2084
|
app.use(
|
|
2014
2085
|
"/*",
|
|
2015
2086
|
serveStatic({
|
|
2016
|
-
root:
|
|
2087
|
+
root: distPath,
|
|
2017
2088
|
rewriteRequestPath: (pathStr) => {
|
|
2018
2089
|
if (!pathStr.includes(".") && !pathStr.startsWith("/api") && pathStr !== "/health") {
|
|
2019
2090
|
return "/index.html";
|
|
@@ -2026,7 +2097,7 @@ function createStudioServer(options = {}) {
|
|
|
2026
2097
|
const isConnected = activeTransport.isConnected() && lastReport?.status === "online";
|
|
2027
2098
|
return c.json({
|
|
2028
2099
|
status: isConnected ? "healthy" : "offline",
|
|
2029
|
-
version:
|
|
2100
|
+
version: STUDIO_VERSION,
|
|
2030
2101
|
targetType: activeConfig.type,
|
|
2031
2102
|
connected: isConnected
|
|
2032
2103
|
});
|
|
@@ -2042,7 +2113,7 @@ function createStudioServer(options = {}) {
|
|
|
2042
2113
|
connected: isConnected,
|
|
2043
2114
|
toolsCount: isConnected ? lastReport?.totalTools || 0 : 0,
|
|
2044
2115
|
latencyMs: isConnected ? lastReport?.latencyMs || 0 : 0,
|
|
2045
|
-
version:
|
|
2116
|
+
version: STUDIO_VERSION,
|
|
2046
2117
|
serverInfo: lastReport?.serverInfo
|
|
2047
2118
|
});
|
|
2048
2119
|
});
|
|
@@ -2220,6 +2291,7 @@ export {
|
|
|
2220
2291
|
HttpTransport,
|
|
2221
2292
|
MeshTransport,
|
|
2222
2293
|
NetworkDiscoveryEngine,
|
|
2294
|
+
STUDIO_VERSION,
|
|
2223
2295
|
StdioTransport,
|
|
2224
2296
|
createStudioServer,
|
|
2225
2297
|
createTransport,
|