@nekzus/liop-studio 1.0.0-alpha.2 → 1.0.0-alpha.20

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.
@@ -1,4 +1,5 @@
1
1
  import '@hono/node-server';
2
2
  import 'hono/types';
3
3
  import 'hono';
4
- export { f as ServerOptions, g as createStudioServer } from '../index-DLA-Sm4s.js';
4
+ export { f as ServerOptions, g as createStudioServer } from '../index-Cl7IupN0.js';
5
+ import '@nekzus/liop';
@@ -1,7 +1,7 @@
1
1
  // src/server/index.ts
2
- import path from "path";
2
+ import path2 from "path";
3
3
  import process3 from "process";
4
- import { fileURLToPath } from "url";
4
+ import { fileURLToPath as fileURLToPath2 } from "url";
5
5
  import { serve } from "@hono/node-server";
6
6
  import { serveStatic } from "@hono/node-server/serve-static";
7
7
  import { TokenTelemetryEngine as TokenTelemetryEngine5 } from "@nekzus/liop";
@@ -57,10 +57,29 @@ function validateHttpTarget(targetUrl) {
57
57
  }
58
58
  return parsed;
59
59
  }
60
- function validateHostHeader(host, allowedHosts = ["localhost", "127.0.0.1", "0.0.0.0"]) {
60
+ function validateHostHeader(host, allowedHosts = [
61
+ "localhost",
62
+ "127.0.0.1",
63
+ "0.0.0.0",
64
+ "::1",
65
+ "[::1]"
66
+ ]) {
61
67
  if (!host) return false;
62
- const hostname = host.split(":")[0].toLowerCase();
63
- return allowedHosts.includes(hostname);
68
+ const trimmed = host.trim();
69
+ let hostname;
70
+ if (trimmed.startsWith("[")) {
71
+ const closingIndex = trimmed.indexOf("]");
72
+ hostname = closingIndex !== -1 ? trimmed.slice(0, closingIndex + 1) : trimmed;
73
+ } else if (trimmed.includes(":") && trimmed.indexOf(":") !== trimmed.lastIndexOf(":")) {
74
+ hostname = trimmed;
75
+ } else {
76
+ hostname = trimmed.split(":")[0];
77
+ }
78
+ hostname = hostname.toLowerCase();
79
+ return allowedHosts.some((allowed) => {
80
+ const normAllowed = allowed.toLowerCase();
81
+ return normAllowed === hostname || hostname === "[::1]" && normAllowed === "::1" || hostname === "::1" && normAllowed === "[::1]";
82
+ });
64
83
  }
65
84
 
66
85
  // src/transports/grpc.transport.ts
@@ -85,7 +104,8 @@ var DEFAULT_PRESET_PROFILES = [
85
104
  role: "Clinical Healthcare & EHR Patient Records",
86
105
  isolation: "pnet Swarm Key (PSK) + HIPAA Strict Mode",
87
106
  dataset: "2,500 clinical EHR patient records",
88
- defaultTool: "Analyze_Synthetic_Medical_Records"
107
+ defaultTool: "Analyze_Synthetic_Medical_Records",
108
+ defaultTools: ["Analyze_Synthetic_Medical_Records"]
89
109
  },
90
110
  {
91
111
  id: "bank",
@@ -97,7 +117,8 @@ var DEFAULT_PRESET_PROFILES = [
97
117
  role: "Core Banking & Financial Settlement",
98
118
  isolation: "pnet Swarm Key (PSK) + Differential Privacy",
99
119
  dataset: "1,500 synthetic accounts ($148M balance)",
100
- defaultTool: "Analyze_Synthetic_Bank_Transactions"
120
+ defaultTool: "Analyze_Synthetic_Bank_Transactions",
121
+ defaultTools: ["Analyze_Synthetic_Bank_Transactions"]
101
122
  },
102
123
  {
103
124
  id: "blg",
@@ -108,7 +129,12 @@ var DEFAULT_PRESET_PROFILES = [
108
129
  tierLabel: "Tier 1: Sovereign Enclaves (In-Situ Origin)",
109
130
  role: "Dual-NIC Perimeter Security Bridge (Tier 1 <-> Tier 2)",
110
131
  isolation: "6-Layer Zero-Trust + AST Guardian + Egress Shield",
111
- defaultTool: "BLG_Inspect_Enclave_Perimeter"
132
+ defaultTool: "BLG_Inspect_Enclave_Perimeter",
133
+ defaultTools: [
134
+ "BLG_Inspect_Enclave_Perimeter",
135
+ "BLG_Execute_Healthcare_Analytics",
136
+ "BLG_Execute_Banking_Analytics"
137
+ ]
112
138
  },
113
139
  {
114
140
  id: "oracle",
@@ -120,7 +146,8 @@ var DEFAULT_PRESET_PROFILES = [
120
146
  role: "Real-time High Frequency Trading Market Simulator",
121
147
  isolation: "Consortium Node + 50ms Tick Streaming Buffer",
122
148
  dataset: "8 Instruments + L2 Orderbook",
123
- defaultTool: "Analyze_HFT_Market_Data"
149
+ defaultTool: "Analyze_HFT_Market_Data",
150
+ defaultTools: ["Analyze_HFT_Market_Data", "LiopMeshStatus"]
124
151
  },
125
152
  {
126
153
  id: "relay",
@@ -130,7 +157,8 @@ var DEFAULT_PRESET_PROFILES = [
130
157
  tierLabel: "Tier 2: Consortium Routing & Gateways",
131
158
  role: "Kademlia DHT & libp2p Circuit Relay v2 Node",
132
159
  isolation: "Public Swarm Mesh Relay",
133
- defaultTool: "LiopMeshStatus"
160
+ defaultTool: "LiopMeshStatus",
161
+ defaultTools: ["LiopMeshStatus"]
134
162
  },
135
163
  {
136
164
  id: "nexus",
@@ -140,7 +168,8 @@ var DEFAULT_PRESET_PROFILES = [
140
168
  tierLabel: "Tier 2: Consortium Routing & Gateways",
141
169
  role: "OAuth 2.1 RFC 8707 Auth Server & Mesh Authority",
142
170
  isolation: "Zero-Trust Identity Provider",
143
- defaultTool: "Authenticate_Client"
171
+ defaultTool: "Authenticate_Client",
172
+ defaultTools: ["Authenticate_Client"]
144
173
  },
145
174
  {
146
175
  id: "edge",
@@ -152,7 +181,8 @@ var DEFAULT_PRESET_PROFILES = [
152
181
  role: "Edge Telemetry & Hostile 3G WAN Industrial Node",
153
182
  isolation: "WAN Jitter/Loss Resistant Client",
154
183
  dataset: "Edge Telemetry Sensors (Pressure, RPM, Temp)",
155
- defaultTool: "Analyze_IoT_Sensor_Data"
184
+ defaultTool: "Analyze_IoT_Sensor_Data",
185
+ defaultTools: ["Analyze_IoT_Sensor_Data"]
156
186
  }
157
187
  ];
158
188
  var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
@@ -185,7 +215,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
185
215
  /**
186
216
  * Probe a specific HTTP/Health endpoint dynamically.
187
217
  */
188
- async probeHttpNode(host, port, timeoutMs = 1200) {
218
+ async probeHttpNode(host, port, timeoutMs = 3500) {
189
219
  const url = `http://${host}:${port}`;
190
220
  const t0 = performance.now();
191
221
  const controller = new AbortController();
@@ -272,7 +302,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
272
302
  peerId: probe.peerId || `peer-${profile.id}`,
273
303
  multiaddrs: probe.multiaddrs || [],
274
304
  version: probe.version || "2.5.0",
275
- tools: probe.tools && probe.tools.length > 0 ? probe.tools : [],
305
+ tools: probe.tools && probe.tools.length > 0 ? probe.tools : profile.defaultTools || (profile.defaultTool ? [profile.defaultTool] : []),
276
306
  role: profile.role,
277
307
  isolation: profile.isolation,
278
308
  dataset: profile.dataset,
@@ -294,7 +324,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
294
324
  peerId: `peer-${profile.id}`,
295
325
  multiaddrs: [],
296
326
  version: "2.5.0",
297
- tools: [],
327
+ tools: profile.defaultTools || (profile.defaultTool ? [profile.defaultTool] : []),
298
328
  role: profile.role,
299
329
  isolation: profile.isolation,
300
330
  dataset: profile.dataset,
@@ -332,7 +362,7 @@ var NetworkDiscoveryEngine = class _NetworkDiscoveryEngine {
332
362
  const probe = await this.probeHttpNode(host, matchedProfile.httpPort);
333
363
  const isOnline = status === "online" || Boolean(probe?.tools) && (probe?.tools?.length ?? 0) > 0;
334
364
  const nodeName = probe?.name?.replace("PRODUCTION-", "").replace(/-/g, " ") || matchedProfile.defaultName;
335
- const defaultTools = matchedProfile.defaultTool ? [matchedProfile.defaultTool] : ["Execute_WASI_Logic"];
365
+ const defaultTools = matchedProfile.defaultTools || (matchedProfile.defaultTool ? [matchedProfile.defaultTool] : ["Execute_WASI_Logic"]);
336
366
  const tools = isOnline ? probe?.tools && probe.tools.length > 0 ? probe.tools : defaultTools : [];
337
367
  const enriched = isOnline && probe?.enrichedTools && probe.enrichedTools.length > 0 ? probe.enrichedTools : tools.map((t) => ({
338
368
  name: t,
@@ -450,16 +480,22 @@ var GrpcTransport = class {
450
480
  connected = false;
451
481
  target;
452
482
  token;
483
+ tlsConfig;
453
484
  constructor(options) {
454
485
  this.target = options.target.replace(/^grpc:\/\//, "");
455
486
  this.token = options.token;
487
+ this.tlsConfig = options.tls;
456
488
  }
457
489
  isConnected() {
458
490
  return this.connected && this.client !== null;
459
491
  }
460
492
  async connect() {
461
493
  const tokenProvider = this.token || createStudioTokenProvider();
462
- this.client = new LiopRpcClient(this.target, void 0, tokenProvider);
494
+ const tls = this.tlsConfig || {
495
+ insecure: true,
496
+ suppressWarning: true
497
+ };
498
+ this.client = new LiopRpcClient(this.target, tls, tokenProvider);
463
499
  this.connected = true;
464
500
  }
465
501
  async disconnect() {
@@ -1174,9 +1210,7 @@ var MeshTransport = class {
1174
1210
  if (!this.isConnected()) {
1175
1211
  await this.connect();
1176
1212
  }
1177
- const clientAny = this.client;
1178
- const peerId = clientAny.meshNode?.getPeerId?.()?.toString() || "UnknownPeer";
1179
- const _connections = clientAny.meshNode?.node?.getConnections?.() || [];
1213
+ const peerId = this.client.peerId ?? "UnknownPeer";
1180
1214
  const latencyMs = Math.max(1, Math.round(performance.now() - tStart));
1181
1215
  const discovery = NetworkDiscoveryEngine.getInstance();
1182
1216
  const meshDiscovered = await discovery.scanNetwork("127.0.0.1").catch(() => []);
@@ -1861,12 +1895,40 @@ function createTransport(config) {
1861
1895
  }
1862
1896
  }
1863
1897
 
1864
- // src/server/index.ts
1898
+ // src/version.ts
1899
+ import fs from "fs";
1900
+ import path from "path";
1901
+ import { fileURLToPath } from "url";
1865
1902
  var __dirname = path.dirname(fileURLToPath(import.meta.url));
1903
+ function getPackageVersion() {
1904
+ try {
1905
+ let currentDir = __dirname;
1906
+ for (let i = 0; i < 4; i++) {
1907
+ const candidate = path.join(currentDir, "package.json");
1908
+ if (fs.existsSync(candidate)) {
1909
+ const raw = fs.readFileSync(candidate, "utf-8");
1910
+ const parsed = JSON.parse(raw);
1911
+ if (parsed.name === "@nekzus/liop-studio" && typeof parsed.version === "string") {
1912
+ return parsed.version;
1913
+ }
1914
+ }
1915
+ currentDir = path.dirname(currentDir);
1916
+ }
1917
+ } catch {
1918
+ }
1919
+ return "1.0.0-alpha.5";
1920
+ }
1921
+ var STUDIO_VERSION = getPackageVersion();
1922
+
1923
+ // src/server/index.ts
1924
+ var __dirname2 = path2.dirname(fileURLToPath2(import.meta.url));
1866
1925
  function createStudioServer(options = {}) {
1926
+ if (!process3.env.LIOP_SUPPRESS_TLS_WARNING) {
1927
+ process3.env.LIOP_SUPPRESS_TLS_WARNING = "true";
1928
+ }
1867
1929
  const app = new Hono();
1868
1930
  const port = options.port || 16e3;
1869
- const distPath = options.distPath || path.resolve(__dirname, "../../ui/dist");
1931
+ const distPath = options.distPath || path2.resolve(__dirname2, "../../ui/dist");
1870
1932
  let activeConfig = options.initialTarget || {
1871
1933
  type: "http",
1872
1934
  http: { url: process3.env.LIOP_MCP_URL || "http://127.0.0.1:15000/mcp" }
@@ -1886,7 +1948,7 @@ function createStudioServer(options = {}) {
1886
1948
  app.use(
1887
1949
  "/*",
1888
1950
  serveStatic({
1889
- root: path.relative(process3.cwd(), distPath).replace(/\\/g, "/"),
1951
+ root: distPath,
1890
1952
  rewriteRequestPath: (pathStr) => {
1891
1953
  if (!pathStr.includes(".") && !pathStr.startsWith("/api") && pathStr !== "/health") {
1892
1954
  return "/index.html";
@@ -1899,7 +1961,7 @@ function createStudioServer(options = {}) {
1899
1961
  const isConnected = activeTransport.isConnected() && lastReport?.status === "online";
1900
1962
  return c.json({
1901
1963
  status: isConnected ? "healthy" : "offline",
1902
- version: "1.0.0",
1964
+ version: STUDIO_VERSION,
1903
1965
  targetType: activeConfig.type,
1904
1966
  connected: isConnected
1905
1967
  });
@@ -1915,7 +1977,7 @@ function createStudioServer(options = {}) {
1915
1977
  connected: isConnected,
1916
1978
  toolsCount: isConnected ? lastReport?.totalTools || 0 : 0,
1917
1979
  latencyMs: isConnected ? lastReport?.latencyMs || 0 : 0,
1918
- version: "1.0.0",
1980
+ version: STUDIO_VERSION,
1919
1981
  serverInfo: lastReport?.serverInfo
1920
1982
  });
1921
1983
  });