miravo 0.5.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.
- package/README.md +1 -1
- package/console-dist/assets/activity-DsWeRq4h.js +1 -0
- package/console-dist/assets/api-4AqKvsm9.js +1 -0
- package/console-dist/assets/arrow-right-Ea_UhTNi.js +1 -0
- package/console-dist/assets/arrow-up-down-DFSjzzl2.js +1 -0
- package/console-dist/assets/blueprint-card-classes-DBFCDy0M.js +1 -0
- package/console-dist/assets/box-C1WaoOMF.js +1 -0
- package/console-dist/assets/card-BjeP32PN.js +1 -0
- package/console-dist/assets/catalog-BJzyzbLR.js +1 -0
- package/console-dist/assets/catalog-DKjEm-c4.js +1 -0
- package/console-dist/assets/catalog-template-icons-BrUeHaCY.js +1 -0
- package/console-dist/assets/checkbox-DZlJXTE4.js +1 -0
- package/console-dist/assets/chunk-OE4NN4TA-CEjpfhS6.js +3 -0
- package/console-dist/assets/combobox-BGnuCYxO.js +1 -0
- package/console-dist/assets/control-CPhvwx9o.js +1 -0
- package/console-dist/assets/control-Cg2up9NA.js +1 -0
- package/console-dist/assets/copy-button-WkbNkMcd.js +1 -0
- package/console-dist/assets/createLucideIcon-Bwxw859K.js +1 -0
- package/console-dist/assets/deploy-tab-JeWDwPoZ.js +1 -0
- package/console-dist/assets/dist-BhbDML0a.js +1 -0
- package/console-dist/assets/dist-Cy8XTNFT.js +2 -0
- package/console-dist/assets/download-DQ6NH16U.js +1 -0
- package/console-dist/assets/engine-store-CrLnz692.js +1 -0
- package/console-dist/assets/events-CXm29Ok4.js +1 -0
- package/console-dist/assets/events-D01IxhnP.js +1 -0
- package/console-dist/assets/fleet-CfxbKXt9.js +1 -0
- package/console-dist/assets/fleet-lotMGVqe.js +1 -0
- package/console-dist/assets/format-kXTonpDJ.js +1 -0
- package/console-dist/assets/gauge-Ci8zNZlk.js +1 -0
- package/console-dist/assets/get-error-message-3Q5Q-2G5.js +1 -0
- package/console-dist/assets/index-CVPKSDvJ.js +12 -0
- package/console-dist/assets/index-DJkgDeun.css +2 -0
- package/console-dist/assets/input-BWEQFptx.js +1 -0
- package/console-dist/assets/instance-detail-C5IVwuh3.js +1 -0
- package/console-dist/assets/label-uephX5ZG.js +1 -0
- package/console-dist/assets/layers-CUsLQ1fq.js +1 -0
- package/console-dist/assets/login-C3RJli0m.js +126 -0
- package/console-dist/assets/models-B_UioWQ5.js +1 -0
- package/console-dist/assets/models-_IPlPiZ7.js +1 -0
- package/console-dist/assets/not-found-B8gAm08S.js +1 -0
- package/console-dist/assets/platform-targets-R3T-4eJ7.js +1 -0
- package/console-dist/assets/platforms-BWh0BQ3Y.js +1 -0
- package/console-dist/assets/platforms-DStNbtVc.js +1 -0
- package/console-dist/assets/proxy-CsnYqnPp.js +9 -0
- package/console-dist/assets/query-keys-BvtE7BMs.js +1 -0
- package/console-dist/assets/radio-CoHegOv5.js +1 -0
- package/console-dist/assets/rolldown-runtime-COnpUsM8.js +1 -0
- package/console-dist/assets/select-CeO4vP0G.js +1 -0
- package/console-dist/assets/select-display-items-CIzY8953.js +1 -0
- package/console-dist/assets/server-D9Kfn8fQ.js +1 -0
- package/console-dist/assets/shallow-6lGjQhtJ.js +1 -0
- package/console-dist/assets/tags-CiXOIHtY.js +4 -0
- package/console-dist/assets/tags-FQCXIxrP.js +1 -0
- package/console-dist/assets/tooltip-HGLF366Q.js +1 -0
- package/console-dist/assets/transition-nav-link-Df4Rk6vV.js +1 -0
- package/console-dist/assets/transition-types-CPlGtM8w.js +1 -0
- package/console-dist/assets/triangle-alert-adNk_sea.js +1 -0
- package/console-dist/assets/use-platform-stream-DGbK1k2L.js +2 -0
- package/console-dist/assets/use-transition-navigate-CCpcWXB0.js +2 -0
- package/console-dist/assets/validation-Blvud9_O.js +1 -0
- package/console-dist/assets/vendor-charts-CAZdaPlq.js +60 -0
- package/console-dist/assets/vendor-table-wd8JuMmT.js +4 -0
- package/console-dist/assets/vendor-ui-ByahnaY0.js +1 -0
- package/console-dist/index.html +70 -2
- package/package.json +9 -9
- package/src/__tests__/integration/executable-methods-runner.ts +7 -6
- package/src/__tests__/integration/executable-methods.integration.ts +214 -122
- package/src/__tests__/integration/opcua-concurrent-clients.integration.ts +314 -0
- package/src/commands/adapter.ts +180 -7
- package/src/commands/apply.test.ts +62 -0
- package/src/commands/apply.ts +216 -0
- package/src/commands/cleanup.test.ts +34 -0
- package/src/commands/cleanup.ts +201 -0
- package/src/commands/export.test.ts +51 -0
- package/src/commands/export.ts +404 -0
- package/src/commands/fork.ts +2 -2
- package/src/commands/inject.ts +2 -2
- package/src/commands/load.ts +1 -1
- package/src/commands/logs.ts +13 -15
- package/src/commands/models.test.ts +1 -1
- package/src/commands/models.ts +1 -1
- package/src/commands/pause.ts +3 -3
- package/src/commands/platforms.test.ts +186 -0
- package/src/commands/platforms.ts +371 -0
- package/src/commands/remove.ts +1 -1
- package/src/commands/reset.ts +2 -2
- package/src/commands/spawn.ts +2 -2
- package/src/commands/speed.ts +2 -2
- package/src/commands/start/adapter-config.ts +157 -0
- package/src/commands/start/catalog-le-dt.test.ts +50 -0
- package/src/commands/start/catalog-le-dt.ts +187 -0
- package/src/commands/start/catalog-model-schema.ts +89 -0
- package/src/commands/start/catalog-template-detail.ts +54 -0
- package/src/commands/start/daemon.ts +255 -0
- package/src/commands/start/display.ts +150 -0
- package/src/commands/start/engine-setup.ts +247 -0
- package/src/commands/start/events.ts +126 -0
- package/src/commands/start/index.ts +897 -0
- package/src/commands/start/protocol-plans.ts +239 -0
- package/src/commands/start/template-loader.ts +197 -0
- package/src/commands/start/template-resolver.ts +185 -0
- package/src/commands/start/types.ts +73 -0
- package/src/commands/start.test.ts +20 -21
- package/src/commands/status.ts +1 -1
- package/src/commands/stop.ts +19 -8
- package/src/commands/templates.test.ts +1 -1
- package/src/commands/templates.ts +1 -3
- package/src/index.ts +11 -3
- package/src/lib/admin-auth.ts +157 -0
- package/src/lib/admin-client.test.ts +31 -15
- package/src/lib/admin-client.ts +106 -6
- package/src/lib/admin-platform-routes.ts +1017 -0
- package/src/lib/admin-platform-stream.test.ts +434 -0
- package/src/lib/admin-platform-stream.ts +788 -0
- package/src/lib/admin-responses.ts +211 -0
- package/src/lib/admin-server.test.ts +274 -55
- package/src/lib/admin-server.ts +387 -248
- package/src/lib/auth-store.ts +87 -0
- package/src/lib/daemon-registry.ts +12 -14
- package/src/lib/le/le-apply.test.ts +591 -0
- package/src/lib/le/le-apply.ts +832 -0
- package/src/lib/le/le-auth.ts +89 -0
- package/src/lib/le/le-cleanup.test.ts +168 -0
- package/src/lib/le/le-cleanup.ts +399 -0
- package/src/lib/le/le-cli-helpers.ts +77 -0
- package/src/lib/le/le-client.ts +184 -0
- package/src/lib/le/le-concurrency.test.ts +157 -0
- package/src/lib/le/le-concurrency.ts +78 -0
- package/src/lib/le/le-connection-test.ts +42 -0
- package/src/lib/le/le-devicehub-properties.test.ts +53 -0
- package/src/lib/le/le-devicehub-properties.ts +33 -0
- package/src/lib/le/le-devicehub.ts +213 -0
- package/src/lib/le/le-digital-twins.ts +285 -0
- package/src/lib/le/le-drivers.ts +23 -0
- package/src/lib/le/le-endpoint.ts +40 -0
- package/src/lib/le/le-environments.test.ts +73 -0
- package/src/lib/le/le-environments.ts +156 -0
- package/src/lib/le/le-markers.ts +87 -0
- package/src/lib/le/le-plan.test.ts +26 -0
- package/src/lib/le/le-plan.ts +109 -0
- package/src/lib/le/le-platform-operations.test.ts +198 -0
- package/src/lib/le/le-platform-operations.ts +340 -0
- package/src/lib/le/le-static-model-schema.ts +78 -0
- package/src/lib/le/le-static-planner.test.ts +255 -0
- package/src/lib/le/le-static-planner.ts +442 -0
- package/src/lib/le/le-template-exporter.test.ts +527 -0
- package/src/lib/le/le-template-exporter.ts +459 -0
- package/src/lib/le/le-value-types.ts +23 -0
- package/src/lib/mqtt-client.ts +1 -2
- package/src/lib/resolve-simulation.ts +1 -6
- package/src/lib/session-store.ts +110 -0
- package/src/lib/shutdown.test.ts +184 -2
- package/src/lib/shutdown.ts +96 -36
- package/src/lib/template-category.ts +3 -3
- package/src/lib/template-locator.ts +8 -2
- package/src/lib/ws-hub.ts +72 -46
- package/src/logger.ts +18 -10
- package/src/output.ts +3 -0
- package/console-dist/assets/index-C1oOHU1J.js +0 -119
- package/console-dist/assets/index-C3XMYq26.css +0 -2
- package/src/commands/start.ts +0 -2253
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Credential storage — persists admin password at ~/.miravo/auth.json.
|
|
3
|
+
*
|
|
4
|
+
* Password priority: MIRAVO_ADMIN_PASSWORD env > ~/.miravo/auth.json > default "admin".
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { mkdir } from "node:fs/promises";
|
|
8
|
+
import { resolveMiravoHome } from "@miravo/core";
|
|
9
|
+
import type { PersistedCredential } from "@miravo/shared";
|
|
10
|
+
import { PersistedCredentialSchema } from "@miravo/shared";
|
|
11
|
+
|
|
12
|
+
// ---------------------------------------------------------------------------
|
|
13
|
+
// Paths
|
|
14
|
+
// ---------------------------------------------------------------------------
|
|
15
|
+
|
|
16
|
+
function authFilePath(): string {
|
|
17
|
+
return `${resolveMiravoHome()}/auth.json`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
// Read / Write
|
|
22
|
+
// ---------------------------------------------------------------------------
|
|
23
|
+
|
|
24
|
+
/** Load persisted credential from ~/.miravo/auth.json. Returns null if missing or invalid. */
|
|
25
|
+
export async function loadCredential(): Promise<PersistedCredential | null> {
|
|
26
|
+
const file = Bun.file(authFilePath());
|
|
27
|
+
if (!(await file.exists())) return null;
|
|
28
|
+
try {
|
|
29
|
+
const raw: unknown = await file.json();
|
|
30
|
+
const result = PersistedCredentialSchema.safeParse(raw);
|
|
31
|
+
return result.success ? result.data : null;
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Persist credential to ~/.miravo/auth.json with restricted permissions. */
|
|
38
|
+
export async function saveCredential(username: string, passwordHash: string): Promise<void> {
|
|
39
|
+
const filePath = authFilePath();
|
|
40
|
+
const dir = resolveMiravoHome();
|
|
41
|
+
await mkdir(dir, { recursive: true });
|
|
42
|
+
const data: PersistedCredential = { username, passwordHash };
|
|
43
|
+
await Bun.write(filePath, JSON.stringify(data, null, 2), { mode: 0o600 });
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
// Password resolution
|
|
48
|
+
// ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
interface ResolvedPassword {
|
|
51
|
+
/** Argon2id hash of the effective admin password. */
|
|
52
|
+
readonly passwordHash: string;
|
|
53
|
+
/** True when the effective password is the literal default "admin". */
|
|
54
|
+
readonly isDefault: boolean;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Resolve the admin password with priority:
|
|
59
|
+
* 1. MIRAVO_ADMIN_PASSWORD env var (plaintext → hashed)
|
|
60
|
+
* 2. ~/.miravo/auth.json (already hashed)
|
|
61
|
+
* 3. Default "admin" (plaintext → hashed)
|
|
62
|
+
*/
|
|
63
|
+
export async function resolveAdminPassword(): Promise<ResolvedPassword> {
|
|
64
|
+
// 1. Environment override
|
|
65
|
+
const envPassword = Bun.env["MIRAVO_ADMIN_PASSWORD"];
|
|
66
|
+
if (envPassword && envPassword.trim().length > 0) {
|
|
67
|
+
return {
|
|
68
|
+
passwordHash: await Bun.password.hash(envPassword),
|
|
69
|
+
isDefault: envPassword === "admin",
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// 2. Persisted credential file
|
|
74
|
+
const credential = await loadCredential();
|
|
75
|
+
if (credential) {
|
|
76
|
+
return {
|
|
77
|
+
passwordHash: credential.passwordHash,
|
|
78
|
+
isDefault: false, // File exists → user changed password at some point
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// 3. Default
|
|
83
|
+
return {
|
|
84
|
+
passwordHash: await Bun.password.hash("admin"),
|
|
85
|
+
isDefault: true,
|
|
86
|
+
};
|
|
87
|
+
}
|
|
@@ -32,10 +32,10 @@ const DaemonRegistryEntrySchema = z.object({
|
|
|
32
32
|
runId: z.string().min(1),
|
|
33
33
|
});
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
type DaemonAdapterEntry = z.infer<typeof DaemonAdapterEntrySchema>;
|
|
36
36
|
export type DaemonRegistryEntry = z.infer<typeof DaemonRegistryEntrySchema>;
|
|
37
37
|
|
|
38
|
-
|
|
38
|
+
interface EntryIdentityResult {
|
|
39
39
|
readonly status: "dead" | "verified" | "mismatch" | "unreachable";
|
|
40
40
|
readonly ready: boolean;
|
|
41
41
|
}
|
|
@@ -45,7 +45,7 @@ export interface EntryIdentityResult {
|
|
|
45
45
|
// ---------------------------------------------------------------------------
|
|
46
46
|
|
|
47
47
|
/** Returns the path to the daemon registry directory (`~/.miravo/daemon/`). */
|
|
48
|
-
|
|
48
|
+
function daemonDir(): string {
|
|
49
49
|
return `${resolveMiravoHome()}/daemon`;
|
|
50
50
|
}
|
|
51
51
|
|
|
@@ -193,7 +193,15 @@ export function isPidAlive(pid: number): boolean {
|
|
|
193
193
|
try {
|
|
194
194
|
process.kill(pid, 0);
|
|
195
195
|
return true;
|
|
196
|
-
} catch {
|
|
196
|
+
} catch (err) {
|
|
197
|
+
if (
|
|
198
|
+
err &&
|
|
199
|
+
typeof err === "object" &&
|
|
200
|
+
"code" in err &&
|
|
201
|
+
(err.code === "EPERM" || err.code === "EACCES")
|
|
202
|
+
) {
|
|
203
|
+
return true; // process exists but we can't signal it
|
|
204
|
+
}
|
|
197
205
|
return false;
|
|
198
206
|
}
|
|
199
207
|
}
|
|
@@ -239,16 +247,6 @@ export async function probeEntryIdentity(entry: DaemonRegistryEntry): Promise<En
|
|
|
239
247
|
}
|
|
240
248
|
}
|
|
241
249
|
|
|
242
|
-
export async function isEntryAlive(entry: DaemonRegistryEntry): Promise<boolean> {
|
|
243
|
-
const identity = await probeEntryIdentity(entry);
|
|
244
|
-
return identity.status === "verified" || identity.status === "unreachable";
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
export async function canSafelySignalEntry(entry: DaemonRegistryEntry): Promise<boolean> {
|
|
248
|
-
const identity = await probeEntryIdentity(entry);
|
|
249
|
-
return identity.status === "verified";
|
|
250
|
-
}
|
|
251
|
-
|
|
252
250
|
/**
|
|
253
251
|
* Remove all registry entries whose processes are no longer alive.
|
|
254
252
|
* Uses full identity verification (PID + runId) to handle PID reuse.
|