miravo 0.4.0 → 0.6.0

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.
Files changed (161) hide show
  1. package/README.md +1 -1
  2. package/console-dist/assets/activity-DsWeRq4h.js +1 -0
  3. package/console-dist/assets/api-4AqKvsm9.js +1 -0
  4. package/console-dist/assets/arrow-right-Ea_UhTNi.js +1 -0
  5. package/console-dist/assets/arrow-up-down-DFSjzzl2.js +1 -0
  6. package/console-dist/assets/blueprint-card-classes-DBFCDy0M.js +1 -0
  7. package/console-dist/assets/box-C1WaoOMF.js +1 -0
  8. package/console-dist/assets/card-BjeP32PN.js +1 -0
  9. package/console-dist/assets/catalog-BJzyzbLR.js +1 -0
  10. package/console-dist/assets/catalog-DKjEm-c4.js +1 -0
  11. package/console-dist/assets/catalog-template-icons-BrUeHaCY.js +1 -0
  12. package/console-dist/assets/checkbox-DZlJXTE4.js +1 -0
  13. package/console-dist/assets/chunk-OE4NN4TA-CEjpfhS6.js +3 -0
  14. package/console-dist/assets/combobox-BGnuCYxO.js +1 -0
  15. package/console-dist/assets/control-CPhvwx9o.js +1 -0
  16. package/console-dist/assets/control-Cg2up9NA.js +1 -0
  17. package/console-dist/assets/copy-button-WkbNkMcd.js +1 -0
  18. package/console-dist/assets/createLucideIcon-Bwxw859K.js +1 -0
  19. package/console-dist/assets/deploy-tab-JeWDwPoZ.js +1 -0
  20. package/console-dist/assets/dist-BhbDML0a.js +1 -0
  21. package/console-dist/assets/dist-Cy8XTNFT.js +2 -0
  22. package/console-dist/assets/download-DQ6NH16U.js +1 -0
  23. package/console-dist/assets/engine-store-CrLnz692.js +1 -0
  24. package/console-dist/assets/events-CXm29Ok4.js +1 -0
  25. package/console-dist/assets/events-D01IxhnP.js +1 -0
  26. package/console-dist/assets/fleet-CfxbKXt9.js +1 -0
  27. package/console-dist/assets/fleet-lotMGVqe.js +1 -0
  28. package/console-dist/assets/format-kXTonpDJ.js +1 -0
  29. package/console-dist/assets/gauge-Ci8zNZlk.js +1 -0
  30. package/console-dist/assets/get-error-message-3Q5Q-2G5.js +1 -0
  31. package/console-dist/assets/index-CVPKSDvJ.js +12 -0
  32. package/console-dist/assets/index-DJkgDeun.css +2 -0
  33. package/console-dist/assets/input-BWEQFptx.js +1 -0
  34. package/console-dist/assets/instance-detail-C5IVwuh3.js +1 -0
  35. package/console-dist/assets/label-uephX5ZG.js +1 -0
  36. package/console-dist/assets/layers-CUsLQ1fq.js +1 -0
  37. package/console-dist/assets/login-C3RJli0m.js +126 -0
  38. package/console-dist/assets/models-B_UioWQ5.js +1 -0
  39. package/console-dist/assets/models-_IPlPiZ7.js +1 -0
  40. package/console-dist/assets/not-found-B8gAm08S.js +1 -0
  41. package/console-dist/assets/platform-targets-R3T-4eJ7.js +1 -0
  42. package/console-dist/assets/platforms-BWh0BQ3Y.js +1 -0
  43. package/console-dist/assets/platforms-DStNbtVc.js +1 -0
  44. package/console-dist/assets/proxy-CsnYqnPp.js +9 -0
  45. package/console-dist/assets/query-keys-BvtE7BMs.js +1 -0
  46. package/console-dist/assets/radio-CoHegOv5.js +1 -0
  47. package/console-dist/assets/rolldown-runtime-COnpUsM8.js +1 -0
  48. package/console-dist/assets/select-CeO4vP0G.js +1 -0
  49. package/console-dist/assets/select-display-items-CIzY8953.js +1 -0
  50. package/console-dist/assets/server-D9Kfn8fQ.js +1 -0
  51. package/console-dist/assets/shallow-6lGjQhtJ.js +1 -0
  52. package/console-dist/assets/tags-CiXOIHtY.js +4 -0
  53. package/console-dist/assets/tags-FQCXIxrP.js +1 -0
  54. package/console-dist/assets/tooltip-HGLF366Q.js +1 -0
  55. package/console-dist/assets/transition-nav-link-Df4Rk6vV.js +1 -0
  56. package/console-dist/assets/transition-types-CPlGtM8w.js +1 -0
  57. package/console-dist/assets/triangle-alert-adNk_sea.js +1 -0
  58. package/console-dist/assets/use-platform-stream-DGbK1k2L.js +2 -0
  59. package/console-dist/assets/use-transition-navigate-CCpcWXB0.js +2 -0
  60. package/console-dist/assets/validation-Blvud9_O.js +1 -0
  61. package/console-dist/assets/vendor-charts-CAZdaPlq.js +60 -0
  62. package/console-dist/assets/vendor-table-wd8JuMmT.js +4 -0
  63. package/console-dist/assets/vendor-ui-ByahnaY0.js +1 -0
  64. package/console-dist/index.html +70 -2
  65. package/package.json +9 -8
  66. package/src/__tests__/integration/executable-methods-runner.ts +7 -6
  67. package/src/__tests__/integration/executable-methods.integration.ts +214 -122
  68. package/src/__tests__/integration/opcua-concurrent-clients.integration.ts +314 -0
  69. package/src/commands/adapter.ts +180 -7
  70. package/src/commands/apply.test.ts +62 -0
  71. package/src/commands/apply.ts +216 -0
  72. package/src/commands/cleanup.test.ts +34 -0
  73. package/src/commands/cleanup.ts +201 -0
  74. package/src/commands/export.test.ts +51 -0
  75. package/src/commands/export.ts +404 -0
  76. package/src/commands/fork.ts +2 -2
  77. package/src/commands/inject.ts +2 -2
  78. package/src/commands/load.ts +1 -1
  79. package/src/commands/logs.ts +13 -15
  80. package/src/commands/models.test.ts +1 -1
  81. package/src/commands/models.ts +1 -1
  82. package/src/commands/pause.ts +3 -3
  83. package/src/commands/platforms.test.ts +186 -0
  84. package/src/commands/platforms.ts +371 -0
  85. package/src/commands/remove.ts +1 -1
  86. package/src/commands/reset.ts +2 -2
  87. package/src/commands/spawn.ts +2 -2
  88. package/src/commands/speed.ts +2 -2
  89. package/src/commands/start/adapter-config.ts +157 -0
  90. package/src/commands/start/catalog-le-dt.test.ts +50 -0
  91. package/src/commands/start/catalog-le-dt.ts +187 -0
  92. package/src/commands/start/catalog-model-schema.ts +89 -0
  93. package/src/commands/start/catalog-template-detail.ts +54 -0
  94. package/src/commands/start/daemon.ts +255 -0
  95. package/src/commands/start/display.ts +150 -0
  96. package/src/commands/start/engine-setup.ts +247 -0
  97. package/src/commands/start/events.ts +126 -0
  98. package/src/commands/start/index.ts +897 -0
  99. package/src/commands/start/protocol-plans.ts +239 -0
  100. package/src/commands/start/template-loader.ts +197 -0
  101. package/src/commands/start/template-resolver.ts +185 -0
  102. package/src/commands/start/types.ts +73 -0
  103. package/src/commands/start.test.ts +137 -16
  104. package/src/commands/status.ts +1 -1
  105. package/src/commands/stop.ts +19 -8
  106. package/src/commands/templates.test.ts +1 -1
  107. package/src/commands/templates.ts +1 -3
  108. package/src/index.ts +11 -3
  109. package/src/lib/admin-auth.ts +157 -0
  110. package/src/lib/admin-client.test.ts +31 -15
  111. package/src/lib/admin-client.ts +106 -6
  112. package/src/lib/admin-platform-routes.ts +1017 -0
  113. package/src/lib/admin-platform-stream.test.ts +434 -0
  114. package/src/lib/admin-platform-stream.ts +788 -0
  115. package/src/lib/admin-responses.ts +211 -0
  116. package/src/lib/admin-server.test.ts +274 -55
  117. package/src/lib/admin-server.ts +387 -248
  118. package/src/lib/auth-store.ts +87 -0
  119. package/src/lib/daemon-registry.ts +12 -14
  120. package/src/lib/le/le-apply.test.ts +591 -0
  121. package/src/lib/le/le-apply.ts +832 -0
  122. package/src/lib/le/le-auth.ts +89 -0
  123. package/src/lib/le/le-cleanup.test.ts +168 -0
  124. package/src/lib/le/le-cleanup.ts +399 -0
  125. package/src/lib/le/le-cli-helpers.ts +77 -0
  126. package/src/lib/le/le-client.ts +184 -0
  127. package/src/lib/le/le-concurrency.test.ts +157 -0
  128. package/src/lib/le/le-concurrency.ts +78 -0
  129. package/src/lib/le/le-connection-test.ts +42 -0
  130. package/src/lib/le/le-devicehub-properties.test.ts +53 -0
  131. package/src/lib/le/le-devicehub-properties.ts +33 -0
  132. package/src/lib/le/le-devicehub.ts +213 -0
  133. package/src/lib/le/le-digital-twins.ts +285 -0
  134. package/src/lib/le/le-drivers.ts +23 -0
  135. package/src/lib/le/le-endpoint.ts +40 -0
  136. package/src/lib/le/le-environments.test.ts +73 -0
  137. package/src/lib/le/le-environments.ts +156 -0
  138. package/src/lib/le/le-markers.ts +87 -0
  139. package/src/lib/le/le-plan.test.ts +26 -0
  140. package/src/lib/le/le-plan.ts +109 -0
  141. package/src/lib/le/le-platform-operations.test.ts +198 -0
  142. package/src/lib/le/le-platform-operations.ts +340 -0
  143. package/src/lib/le/le-static-model-schema.ts +78 -0
  144. package/src/lib/le/le-static-planner.test.ts +255 -0
  145. package/src/lib/le/le-static-planner.ts +442 -0
  146. package/src/lib/le/le-template-exporter.test.ts +527 -0
  147. package/src/lib/le/le-template-exporter.ts +459 -0
  148. package/src/lib/le/le-value-types.ts +23 -0
  149. package/src/lib/mqtt-client.ts +1 -2
  150. package/src/lib/resolve-simulation.ts +1 -6
  151. package/src/lib/session-store.ts +110 -0
  152. package/src/lib/shutdown.test.ts +184 -2
  153. package/src/lib/shutdown.ts +104 -34
  154. package/src/lib/template-category.ts +3 -3
  155. package/src/lib/template-locator.ts +8 -2
  156. package/src/lib/ws-hub.ts +72 -46
  157. package/src/logger.ts +39 -14
  158. package/src/output.ts +3 -0
  159. package/console-dist/assets/index-C3XMYq26.css +0 -2
  160. package/console-dist/assets/index-hUJSpKtB.js +0 -119
  161. package/src/commands/start.ts +0 -2023
@@ -10,6 +10,7 @@ import {
10
10
  EngineStateSnapshotSchema,
11
11
  MiravoError,
12
12
  } from "@miravo/shared";
13
+ import { loadCredential } from "./auth-store.ts";
13
14
 
14
15
  const DEFAULT_ADMIN_HOST = "127.0.0.1";
15
16
  const DEFAULT_ADMIN_PORT = 8080;
@@ -87,19 +88,67 @@ function parseAdminUrl(input: string): string {
87
88
  return url.toString().replace(/\/$/, "");
88
89
  }
89
90
 
90
- function buildRequestHeaders(body?: string): Record<string, string> | undefined {
91
+ // ---------------------------------------------------------------------------
92
+ // Session-based auth for CLI client
93
+ // ---------------------------------------------------------------------------
94
+
95
+ let sessionCookie: string | null = null;
96
+
97
+ async function loginToAdmin(adminUrl: string): Promise<void> {
98
+ // Resolve password: env > file > default
99
+ const envPassword = Bun.env["MIRAVO_ADMIN_PASSWORD"];
100
+ let password = "admin";
101
+ if (envPassword && envPassword.trim().length > 0) {
102
+ password = envPassword;
103
+ } else {
104
+ const credential = await loadCredential();
105
+ // If credential file exists, we can't reverse the hash — use "admin" as default.
106
+ // The server will verify against the stored hash. If the user changed their password,
107
+ // they need to set MIRAVO_ADMIN_PASSWORD env var for CLI access.
108
+ if (!credential) {
109
+ password = "admin";
110
+ }
111
+ }
112
+
113
+ const response = await fetch(`${adminUrl}/auth/login`, {
114
+ method: "POST",
115
+ headers: { "content-type": "application/json" },
116
+ body: JSON.stringify({ username: "admin", password }),
117
+ signal: AbortSignal.timeout(10_000),
118
+ });
119
+
120
+ if (!response.ok) {
121
+ throw new MiravoError(
122
+ "CLI authentication failed.",
123
+ "Set MIRAVO_ADMIN_PASSWORD or log in with default credentials (admin/admin).",
124
+ );
125
+ }
126
+
127
+ const setCookie = response.headers.get("set-cookie");
128
+ if (setCookie) {
129
+ // Extract just the cookie value (before first ;)
130
+ sessionCookie = setCookie.split(";")[0] ?? null;
131
+ }
132
+ }
133
+
134
+ async function ensureAuthenticated(adminUrl: string): Promise<void> {
135
+ if (sessionCookie) return;
136
+ await loginToAdmin(adminUrl);
137
+ }
138
+
139
+ function buildRequestHeaders(body?: string): Record<string, string> {
91
140
  const headers: Record<string, string> = {};
92
141
  if (body) {
93
142
  headers["content-type"] = "application/json";
94
143
  }
95
- const adminToken = Bun.env["MIRAVO_ADMIN_TOKEN"];
96
- if (adminToken && adminToken.trim().length > 0) {
97
- headers["authorization"] = `Bearer ${adminToken}`;
144
+ if (sessionCookie) {
145
+ headers["cookie"] = sessionCookie;
98
146
  }
99
- return Object.keys(headers).length > 0 ? headers : undefined;
147
+ return headers;
100
148
  }
101
149
 
102
150
  async function requestJson<T>(options: RequestJsonOptions<T>): Promise<T> {
151
+ await ensureAuthenticated(options.baseUrl);
103
152
  const requestUrl = new URL(options.path, `${options.baseUrl}/`).toString();
104
153
  const controller = new AbortController();
105
154
  const timer = setTimeout(() => controller.abort(), options.timeoutMs);
@@ -128,6 +177,18 @@ async function requestJson<T>(options: RequestJsonOptions<T>): Promise<T> {
128
177
  );
129
178
  }
130
179
 
180
+ // Re-authenticate on session expiry and retry once
181
+ if (response.status === 401) {
182
+ sessionCookie = null;
183
+ await loginToAdmin(options.baseUrl);
184
+ response = await fetch(requestUrl, {
185
+ method: options.method ?? "GET",
186
+ headers: buildRequestHeaders(options.body),
187
+ body: options.body,
188
+ signal: controller.signal,
189
+ });
190
+ }
191
+
131
192
  const text = await response.text();
132
193
  let parsedJson: unknown;
133
194
  if (text.length > 0) {
@@ -223,4 +284,43 @@ async function executeAdminCommand(
223
284
  });
224
285
  }
225
286
 
226
- export { executeAdminCommand, getAdminMetrics, getAdminSnapshot, getAdminState, resolveAdminUrl };
287
+ /** Schema that accepts any JSON object — used for adapter introspection (protocol-specific shape). */
288
+ const AnyObjectSchema = {
289
+ safeParse(value: unknown): SafeParseResult<Record<string, unknown>> {
290
+ if (typeof value === "object" && value !== null && !Array.isArray(value)) {
291
+ return { success: true, data: value as Record<string, unknown> };
292
+ }
293
+ return { success: false };
294
+ },
295
+ };
296
+
297
+ async function getManifest(adminUrl: string, timeoutMs: number): Promise<Record<string, unknown>> {
298
+ return requestJson({
299
+ baseUrl: adminUrl,
300
+ path: "/manifest",
301
+ timeoutMs,
302
+ schema: AnyObjectSchema,
303
+ });
304
+ }
305
+
306
+ async function getLeDtJson(
307
+ adminUrl: string,
308
+ modelName: string,
309
+ timeoutMs: number,
310
+ ): Promise<Record<string, unknown>> {
311
+ return requestJson({
312
+ baseUrl: adminUrl,
313
+ path: `/catalog/models/${encodeURIComponent(modelName)}/le-dt.json`,
314
+ timeoutMs,
315
+ schema: AnyObjectSchema,
316
+ });
317
+ }
318
+
319
+ export {
320
+ executeAdminCommand,
321
+ getAdminSnapshot,
322
+ getAdminState,
323
+ getLeDtJson,
324
+ getManifest,
325
+ resolveAdminUrl,
326
+ };