maka-agent 0.2.0-dev.16.20260903 → 0.2.0-dev.18.20260904
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/RUNTIME_HOST_PEER_THIRD_PARTY_NOTICES.txt +1 -1
- package/dist/cli-core.js +7 -3
- package/dist/mcp-capability-provider.js +3 -10
- package/dist/runtime-host-cli.js +28 -6
- package/dist/runtime-host-lifecycle-transaction.js +12 -10
- package/dist/runtime-host-managed-deployment.js +112 -51
- package/dist/runtime-host-managed-lifecycle-manager.js +2 -5
- package/dist/runtime-host-package-deployment.js +35 -2
- package/dist/runtime-host-peer-artifact.js +3 -3
- package/dist/runtime-host-peer-management-command.js +4 -4
- package/dist/runtime-host-peer-mesh-management-command.js +1 -1
- package/dist/runtime-host-profile-command.js +1 -1
- package/dist/runtime-host-service-management-command.js +24 -3
- package/dist/runtime-host-setup-command.js +13 -16
- package/dist/runtime-host-update-command.js +10 -9
- package/dist/runtime-host-update-reconciliation.js +7 -7
- package/dist/runtime-host-windows-service.js +132 -0
- package/dist/runtime-host-windows-task-runner.js +90 -0
- package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
- package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
- package/node_modules/@maka/runtime/dist/mcp-tools.js +83 -72
- package/node_modules/@maka/runtime-host/dist/client/host-profile.js +77 -29
- package/node_modules/@maka/runtime-host/dist/client/index.js +3 -3
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +2 -9
- package/node_modules/@maka/runtime-host/dist/client/ssh-operator-activation.js +48 -11
- package/node_modules/@maka/runtime-host/dist/client/wsl-control.js +0 -8
- package/node_modules/@maka/runtime-host/dist/client/wsl-environment.js +12 -8
- package/node_modules/@maka/runtime-host/dist/operator/index.js +1 -0
- package/node_modules/@maka/runtime-host/dist/operator/managed-deployment.js +14 -5
- package/node_modules/@maka/runtime-host/dist/operator/operator-command.js +110 -0
- package/node_modules/@maka/runtime-host/dist/operator/service-management-frame.js +3 -6
- package/node_modules/@maka/runtime-host/dist/operator/setup-frame.js +17 -1
- package/node_modules/@maka/runtime-host/dist/peer-reachability/owner.js +1 -2
- package/node_modules/@maka/runtime-host/dist/peer-reachability/publisher.js +4 -4
- package/node_modules/@maka/runtime-host/dist/protocol/client-capability.js +25 -7
- package/node_modules/@maka/runtime-host/dist/server/client-capability-coordinator.js +42 -24
- package/package.json +1 -1
|
@@ -5,7 +5,7 @@ Generated by scripts/generate-runtime-host-peer-notices.mjs from the exact
|
|
|
5
5
|
four-target production dependency inventory. Do not edit this file by hand.
|
|
6
6
|
|
|
7
7
|
Manifest: native/runtime-host-peer/Cargo.toml
|
|
8
|
-
Cargo.lock SHA-256:
|
|
8
|
+
Cargo.lock SHA-256: b1a7cdd67fee2bbde5bd8d91c6773f97e809515898604bde7ee0dbf4e04cbbd8
|
|
9
9
|
Inventory SHA-256: c28a17749fa5f9af237a49dd2b4ad9149b6c4224d383c4a5050eeac3be14073c
|
|
10
10
|
|
|
11
11
|
Packages
|
package/dist/cli-core.js
CHANGED
|
@@ -20,7 +20,7 @@ import { readFile } from 'node:fs/promises';
|
|
|
20
20
|
import { join } from 'node:path';
|
|
21
21
|
import { fileURLToPath } from 'node:url';
|
|
22
22
|
import { deriveMakaDataRoots, resolveMakaDataRoots } from './workspace-root.js';
|
|
23
|
-
import { configureRuntimeHostPeerClient,
|
|
23
|
+
import { configureRuntimeHostPeerClient, resolveRuntimeHostNativePath, } from './runtime-host-peer-artifact.js';
|
|
24
24
|
import { parseRuntimeHostCommand, parseRuntimeHostInstalledUpdateCommand, } from './runtime-host-cli.js';
|
|
25
25
|
import { resolveCliUiLocale } from './cli-ui-locale.js';
|
|
26
26
|
export const RELEASE_MAKA_CLI_LAUNCH_OPTIONS = {
|
|
@@ -264,6 +264,10 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
264
264
|
const { config } = await resolveRuntimeHostManagedDeployment(command.managedDeployment.rootId);
|
|
265
265
|
const peer = config.listeners.directPeer?.enabled ? config.listeners.directPeer : undefined;
|
|
266
266
|
const packageLayout = resolveRuntimeHostNpmDeploymentLayout(config.deploymentRoot, config.launch.package.integrity);
|
|
267
|
+
if (process.platform === 'win32') {
|
|
268
|
+
const { ownWindowsRuntimeHostProcessTree } = await import('./runtime-host-windows-service.js');
|
|
269
|
+
await ownWindowsRuntimeHostProcessTree(packageLayout.cliPath);
|
|
270
|
+
}
|
|
267
271
|
return runRuntimeHostServiceCli({
|
|
268
272
|
rootPath: config.root.path,
|
|
269
273
|
json: command.json,
|
|
@@ -276,7 +280,7 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
276
280
|
...(peer
|
|
277
281
|
? {
|
|
278
282
|
peer: {
|
|
279
|
-
nativePath: await
|
|
283
|
+
nativePath: await resolveRuntimeHostNativePath(packageLayout.cliPath),
|
|
280
284
|
keyPath: peer.keyPath,
|
|
281
285
|
expectedPeerId: peer.peerId,
|
|
282
286
|
listenAddresses: peer.listenAddresses,
|
|
@@ -681,7 +685,7 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
681
685
|
id: command.id,
|
|
682
686
|
name: command.name,
|
|
683
687
|
distribution: command.distribution,
|
|
684
|
-
|
|
688
|
+
operator: command.operator,
|
|
685
689
|
expectedRootId: command.expectedRootId,
|
|
686
690
|
}, {}, profileOptions);
|
|
687
691
|
}
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { createHash } from 'node:crypto';
|
|
20
|
-
import { CLIENT_CAPABILITY_MAX_TOOLS, CLIENT_CAPABILITY_MAX_TOOLS_PER_OFFER, decodeClientCapabilityReplaceInput, } from '@maka/runtime-host/protocol';
|
|
20
|
+
import { CLIENT_CAPABILITY_MAX_TOOLS, CLIENT_CAPABILITY_MAX_TOOLS_PER_OFFER, clientCapabilityEntityId, decodeClientCapabilityReplaceInput, } from '@maka/runtime-host/protocol';
|
|
21
21
|
const CAPABILITY_VERSION = '0';
|
|
22
22
|
export function createMcpCapabilityProvider(manager) {
|
|
23
23
|
const toolSnapshot = manager.toolSnapshot();
|
|
@@ -32,7 +32,7 @@ export function createMcpCapabilityProvider(manager) {
|
|
|
32
32
|
const projectedIdentities = new Set();
|
|
33
33
|
const projected = [];
|
|
34
34
|
for (const source of tools) {
|
|
35
|
-
const descriptor = projectMcpTool(source.descriptor,
|
|
35
|
+
const descriptor = projectMcpTool(source.descriptor, clientCapabilityEntityId(source.descriptor.serverId));
|
|
36
36
|
const identity = `${descriptor.serverId}\0${descriptor.name}`;
|
|
37
37
|
if (projectedIdentities.has(identity)) {
|
|
38
38
|
throw new Error('MCP tools collide after Client Capability identity normalization');
|
|
@@ -79,19 +79,12 @@ export function createMcpCapabilityProvider(manager) {
|
|
|
79
79
|
function projectMcpTool(tool, wireServerId) {
|
|
80
80
|
return {
|
|
81
81
|
serverId: wireServerId,
|
|
82
|
-
name:
|
|
82
|
+
name: clientCapabilityEntityId(tool.name),
|
|
83
83
|
...(tool.description ? { description: tool.description } : {}),
|
|
84
84
|
inputSchema: structuredClone(tool.inputSchema),
|
|
85
85
|
...(tool.annotations ? { annotations: { ...tool.annotations } } : {}),
|
|
86
86
|
};
|
|
87
87
|
}
|
|
88
|
-
function capabilityEntityId(value) {
|
|
89
|
-
if (/^[A-Za-z0-9_-]{1,128}$/u.test(value))
|
|
90
|
-
return value;
|
|
91
|
-
const label = value.replace(/[^A-Za-z0-9_-]+/gu, '_').slice(0, 103) || 'mcp';
|
|
92
|
-
const digest = createHash('sha256').update(value).digest('hex').slice(0, 24);
|
|
93
|
-
return `${label}_${digest}`;
|
|
94
|
-
}
|
|
95
88
|
function projectMcpResult(result) {
|
|
96
89
|
return {
|
|
97
90
|
content: result.content.map((block) => structuredClone(block)),
|
package/dist/runtime-host-cli.js
CHANGED
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { isAbsolute } from 'node:path';
|
|
20
20
|
import { isProductReleaseVersion, isSha512PackageIntegrity, } from '@maka/runtime-host/operator/update-package-evidence';
|
|
21
|
-
import { decodeRuntimeHostWebRtcStunPolicy, } from '@maka/runtime-host/operator';
|
|
21
|
+
import { createRuntimeHostLegacyPosixOperatorCommand, decodeRuntimeHostPosixOperatorCommand, decodeRuntimeHostWebRtcStunPolicy, } from '@maka/runtime-host/operator';
|
|
22
22
|
import { canonicalProjectDirectoryRootSpec, isCanonicalRuntimeHostWebSocketPath, PROJECT_DIRECTORY_MAX_ROOTS, projectDirectoryPosixRootSpecValid, projectDirectoryRootSpecValid, } from '@maka/runtime-host/protocol';
|
|
23
23
|
import { hasEphemeralRuntimeHostPeerPort } from './runtime-host-peer-artifact.js';
|
|
24
24
|
export function parseRuntimeHostCommand(argv) {
|
|
@@ -1348,6 +1348,7 @@ function parseProfileCommand(argv) {
|
|
|
1348
1348
|
let sshWebSocketPath = '/runtime-host';
|
|
1349
1349
|
let sshWebSocketPathConfigured = false;
|
|
1350
1350
|
let wslDistribution;
|
|
1351
|
+
let operator;
|
|
1351
1352
|
let operatorPath;
|
|
1352
1353
|
let expectedRootId;
|
|
1353
1354
|
let credentialEnv;
|
|
@@ -1362,6 +1363,7 @@ function parseProfileCommand(argv) {
|
|
|
1362
1363
|
argument !== '--ssh-remote-port' &&
|
|
1363
1364
|
argument !== '--ssh-websocket-path' &&
|
|
1364
1365
|
argument !== '--wsl-distribution' &&
|
|
1366
|
+
argument !== '--operator-command' &&
|
|
1365
1367
|
argument !== '--operator-path' &&
|
|
1366
1368
|
argument !== '--expected-root' &&
|
|
1367
1369
|
argument !== '--credential-env' &&
|
|
@@ -1395,6 +1397,14 @@ function parseProfileCommand(argv) {
|
|
|
1395
1397
|
}
|
|
1396
1398
|
if (argument === '--wsl-distribution')
|
|
1397
1399
|
wslDistribution = parsed;
|
|
1400
|
+
if (argument === '--operator-command') {
|
|
1401
|
+
try {
|
|
1402
|
+
operator = decodeRuntimeHostPosixOperatorCommand(JSON.parse(parsed));
|
|
1403
|
+
}
|
|
1404
|
+
catch {
|
|
1405
|
+
return error('--operator-command must be a valid Runtime Host operator command JSON value');
|
|
1406
|
+
}
|
|
1407
|
+
}
|
|
1398
1408
|
if (argument === '--operator-path')
|
|
1399
1409
|
operatorPath = parsed;
|
|
1400
1410
|
if (argument === '--expected-root')
|
|
@@ -1407,6 +1417,17 @@ function parseProfileCommand(argv) {
|
|
|
1407
1417
|
return error('--id is required');
|
|
1408
1418
|
if (!name)
|
|
1409
1419
|
return error('--name is required');
|
|
1420
|
+
if (operator && operatorPath) {
|
|
1421
|
+
return error('--operator-command and --operator-path cannot be combined');
|
|
1422
|
+
}
|
|
1423
|
+
if (operatorPath) {
|
|
1424
|
+
try {
|
|
1425
|
+
operator = createRuntimeHostLegacyPosixOperatorCommand(operatorPath);
|
|
1426
|
+
}
|
|
1427
|
+
catch {
|
|
1428
|
+
return error('--operator-path must be an absolute POSIX path');
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1410
1431
|
if ((tlsUrl ? 1 : 0) +
|
|
1411
1432
|
(plaintextUrl ? 1 : 0) +
|
|
1412
1433
|
(sshDestination ? 1 : 0) +
|
|
@@ -1414,12 +1435,13 @@ function parseProfileCommand(argv) {
|
|
|
1414
1435
|
1) {
|
|
1415
1436
|
return error('exactly one of --tls-url, --plaintext-url, --ssh-destination, or --wsl-distribution is required');
|
|
1416
1437
|
}
|
|
1417
|
-
if (wslDistribution && !
|
|
1418
|
-
return error('--wsl-distribution requires --operator-path');
|
|
1438
|
+
if (wslDistribution && !operator) {
|
|
1439
|
+
return error('--wsl-distribution requires --operator-command or --operator-path');
|
|
1419
1440
|
}
|
|
1420
|
-
if (!wslDistribution && operatorPath)
|
|
1441
|
+
if (!wslDistribution && operatorPath)
|
|
1421
1442
|
return error('--operator-path requires --wsl-distribution');
|
|
1422
|
-
|
|
1443
|
+
if (!wslDistribution && operator)
|
|
1444
|
+
return error('--operator-command requires --wsl-distribution');
|
|
1423
1445
|
if (wslDistribution && credentialEnv) {
|
|
1424
1446
|
return error('WSL environment profiles do not accept --credential-env');
|
|
1425
1447
|
}
|
|
@@ -1451,7 +1473,7 @@ function parseProfileCommand(argv) {
|
|
|
1451
1473
|
id,
|
|
1452
1474
|
name,
|
|
1453
1475
|
distribution: wslDistribution,
|
|
1454
|
-
|
|
1476
|
+
operator: operator,
|
|
1455
1477
|
expectedRootId,
|
|
1456
1478
|
};
|
|
1457
1479
|
}
|
|
@@ -17,12 +17,11 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
|
-
import { join } from 'node:path';
|
|
21
20
|
import { isDeepStrictEqual } from 'node:util';
|
|
22
21
|
import { resolveExistingStorageRoot, tryAcquireStateRootOwner, } from '@maka/storage/root-authority';
|
|
23
22
|
import { connectExistingRuntimeHost, prepareConnectedRuntimeHostRetirement, RuntimeHostOperationError, RuntimeHostRequestInterruptedError, waitForRuntimeHostReady, } from '@maka/runtime-host/client';
|
|
24
23
|
import { RUNTIME_HOST_PROTOCOL_VERSION } from '@maka/runtime-host/protocol';
|
|
25
|
-
import { beginRuntimeHostManagedDeploymentTransition, blockRuntimeHostManagedDeploymentTransition, commitRuntimeHostManagedDeploymentTransition, decodeRuntimeHostManagedDeploymentConfig, readRuntimeHostManagedDeploymentAuthorityRecord, resolveRuntimeHostManagedDeploymentAuthority, resolveRuntimeHostNpmDeploymentLayout, rollbackRuntimeHostManagedDeploymentTransition, RuntimeHostManagedDeploymentError, } from '@maka/runtime-host/operator';
|
|
24
|
+
import { beginRuntimeHostManagedDeploymentTransition, blockRuntimeHostManagedDeploymentTransition, commitRuntimeHostManagedDeploymentTransition, decodeRuntimeHostManagedDeploymentConfig, readRuntimeHostManagedDeploymentAuthorityRecord, resolveRuntimeHostManagedDeploymentAuthority, resolveRuntimeHostNpmDeploymentLayout, runtimeHostManagedOperatorModulePath, rollbackRuntimeHostManagedDeploymentTransition, RuntimeHostManagedDeploymentError, } from '@maka/runtime-host/operator';
|
|
26
25
|
/** The budget a managed Runtime Host has to become reachable after its lifecycle is activated. */
|
|
27
26
|
export const RUNTIME_HOST_READY_TIMEOUT_MS = 45_000;
|
|
28
27
|
export class RuntimeHostLifecycleTransactionError extends Error {
|
|
@@ -304,7 +303,7 @@ export async function replaceRuntimeHostLifecycle(input) {
|
|
|
304
303
|
const desired = decodeRuntimeHostManagedDeploymentConfig(input.desired);
|
|
305
304
|
const currentProvider = supervisedProvider(current ?? null, input.deps);
|
|
306
305
|
if (desired.lifecycle.mode === 'supervised') {
|
|
307
|
-
await input.deps.resolveProvider(desired
|
|
306
|
+
await input.deps.resolveProvider(desired).supervisor.preflight();
|
|
308
307
|
}
|
|
309
308
|
const retirement = await retireRuntimeHostLifecycleOwner({
|
|
310
309
|
rootPath: desired.root.path,
|
|
@@ -459,7 +458,7 @@ export async function activateRuntimeHostLifecycle(config, deps) {
|
|
|
459
458
|
const canonical = decodeRuntimeHostManagedDeploymentConfig(config);
|
|
460
459
|
if (canonical.lifecycle.mode !== 'supervised')
|
|
461
460
|
return;
|
|
462
|
-
const provider = deps.resolveProvider(canonical
|
|
461
|
+
const provider = deps.resolveProvider(canonical);
|
|
463
462
|
await provider.supervisor.activate();
|
|
464
463
|
if (canonical.reconciliation.trigger === 'scheduled') {
|
|
465
464
|
await provider.reconciliationTrigger.activate();
|
|
@@ -470,7 +469,7 @@ export async function verifyRuntimeHostLifecycleReady(config, deps, timeoutMs =
|
|
|
470
469
|
await verifyRuntimeHostLifecycleProjection(canonical, deps);
|
|
471
470
|
if (canonical.lifecycle.mode !== 'supervised')
|
|
472
471
|
return;
|
|
473
|
-
const provider = deps.resolveProvider(canonical
|
|
472
|
+
const provider = deps.resolveProvider(canonical);
|
|
474
473
|
const deadline = Date.now() + timeoutMs;
|
|
475
474
|
let lastFailure = new Error('Runtime Host is not ready');
|
|
476
475
|
while (Date.now() < deadline) {
|
|
@@ -519,7 +518,7 @@ export async function verifyRuntimeHostLifecycleProjection(config, deps) {
|
|
|
519
518
|
await deps.verifyOperator(canonical);
|
|
520
519
|
if (canonical.lifecycle.mode !== 'supervised')
|
|
521
520
|
return;
|
|
522
|
-
const provider = deps.resolveProvider(canonical
|
|
521
|
+
const provider = deps.resolveProvider(canonical);
|
|
523
522
|
await provider.supervisor.verify(runtimeHostSupervisorDefinition(canonical));
|
|
524
523
|
if (canonical.reconciliation.trigger !== 'scheduled')
|
|
525
524
|
return;
|
|
@@ -550,7 +549,12 @@ export function runtimeHostSupervisorDefinition(config) {
|
|
|
550
549
|
export function runtimeHostReconciliationTriggerDefinition(config) {
|
|
551
550
|
const canonical = decodeRuntimeHostManagedDeploymentConfig(config);
|
|
552
551
|
return {
|
|
553
|
-
command: [
|
|
552
|
+
command: [
|
|
553
|
+
canonical.launch.nodePath,
|
|
554
|
+
runtimeHostManagedOperatorModulePath(canonical.deploymentRoot, process.platform === 'win32' ? 'win32' : 'posix'),
|
|
555
|
+
'reconcile-update',
|
|
556
|
+
'--framed',
|
|
557
|
+
],
|
|
554
558
|
};
|
|
555
559
|
}
|
|
556
560
|
async function convergeLifecycleArtifacts(from, to, deps) {
|
|
@@ -600,7 +604,5 @@ async function restoreTransition(record, deps) {
|
|
|
600
604
|
await convergeTransitionOwnership(record.to, record.from, record, deps);
|
|
601
605
|
}
|
|
602
606
|
function supervisedProvider(config, deps) {
|
|
603
|
-
return config?.lifecycle.mode === 'supervised'
|
|
604
|
-
? deps.resolveProvider(config.lifecycle.provider)
|
|
605
|
-
: undefined;
|
|
607
|
+
return config?.lifecycle.mode === 'supervised' ? deps.resolveProvider(config) : undefined;
|
|
606
608
|
}
|
|
@@ -21,10 +21,10 @@ import { constants } from 'node:fs';
|
|
|
21
21
|
import { access, lstat, mkdir, open, readdir, realpath, rename, rm } from 'node:fs/promises';
|
|
22
22
|
import { homedir } from 'node:os';
|
|
23
23
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from 'node:path';
|
|
24
|
-
import { openRuntimeHostPackageDeployment, prepareRuntimeHostPackageDeployment, pruneRuntimeHostPackageDeployments, resolveRuntimeHostPackageCliPath, RuntimeHostPackageDeploymentError as RuntimeHostManagedDeploymentError, } from './runtime-host-package-deployment.js';
|
|
24
|
+
import { openRuntimeHostPackageDeployment, prepareRuntimeHostPackageDeployment, pruneRuntimeHostPackageDeployments, removeDeploymentDirectory, resolveRuntimeHostPackageCliPath, RuntimeHostPackageDeploymentError as RuntimeHostManagedDeploymentError, } from './runtime-host-package-deployment.js';
|
|
25
25
|
import { readStableBoundedFile, syncDirectory } from '@maka/storage/stable-storage';
|
|
26
26
|
import { resolveExistingStorageRoot, tryAcquireStateRootOwner } from '@maka/storage/root-authority';
|
|
27
|
-
import { resolveRuntimeHostManagedDeploymentAuthorityRoot, resolveRuntimeHostManagedDeploymentAuthority, resolveRuntimeHostNpmDeploymentLayout, } from '@maka/runtime-host/operator';
|
|
27
|
+
import { resolveRuntimeHostManagedDeploymentAuthorityRoot, resolveRuntimeHostManagedDeploymentAuthority, resolveRuntimeHostNpmDeploymentLayout, runtimeHostManagedOperatorModulePath, } from '@maka/runtime-host/operator';
|
|
28
28
|
export { RuntimeHostPackageDeploymentError as RuntimeHostManagedDeploymentError } from './runtime-host-package-deployment.js';
|
|
29
29
|
const CLEANUP_RECEIPT_FILE = 'cleanup-approved.json';
|
|
30
30
|
export function resolveRuntimeHostManagedPackageCliPath(deploymentRoot, version, packageIntegrity) {
|
|
@@ -277,11 +277,16 @@ export function resolveRuntimeHostManagedDeploymentRoot(serviceId, options = {})
|
|
|
277
277
|
function resolveRuntimeHostManagedDataHome(options = {}) {
|
|
278
278
|
const env = options.env ?? process.env;
|
|
279
279
|
const homeDir = options.homeDir ?? homedir();
|
|
280
|
-
|
|
280
|
+
const platform = options.platform ?? process.platform;
|
|
281
|
+
return platform === 'darwin'
|
|
281
282
|
? join(homeDir, 'Library', 'Application Support')
|
|
282
|
-
:
|
|
283
|
-
? env.
|
|
284
|
-
|
|
283
|
+
: platform === 'win32'
|
|
284
|
+
? env.LOCALAPPDATA && isAbsolute(env.LOCALAPPDATA)
|
|
285
|
+
? env.LOCALAPPDATA
|
|
286
|
+
: join(homeDir, 'AppData', 'Local')
|
|
287
|
+
: env.XDG_DATA_HOME && isAbsolute(env.XDG_DATA_HOME)
|
|
288
|
+
? env.XDG_DATA_HOME
|
|
289
|
+
: join(homeDir, '.local', 'share');
|
|
285
290
|
}
|
|
286
291
|
export function resolveRuntimeHostManagedControlRoot(serviceId) {
|
|
287
292
|
return join(resolveRuntimeHostManagedDeploymentAuthorityRoot(), serviceId, 'control');
|
|
@@ -372,24 +377,29 @@ export async function removeRuntimeHostManagedDeployment(root, serviceId) {
|
|
|
372
377
|
// recognized as already complete and reclaimed by the next deployment.
|
|
373
378
|
await syncDirectory(parent);
|
|
374
379
|
}
|
|
375
|
-
await
|
|
380
|
+
await removeDeploymentDirectory(retiredRoot);
|
|
376
381
|
await syncDirectory(parent);
|
|
377
382
|
}
|
|
378
383
|
function managedDeployment(staged, clientDataRoot, managedRootId) {
|
|
379
|
-
const
|
|
384
|
+
const modulePath = runtimeHostManagedOperatorModulePath(staged.root, process.platform === 'win32' ? 'win32' : 'posix');
|
|
380
385
|
return {
|
|
381
386
|
version: staged.version,
|
|
382
387
|
root: staged.root,
|
|
383
388
|
cliPath: staged.cliPath,
|
|
384
|
-
|
|
385
|
-
|
|
389
|
+
activate: async () => {
|
|
390
|
+
await writeOperatorLauncher(modulePath, process.execPath, staged.cliPath, clientDataRoot, managedRootId);
|
|
391
|
+
await forwardLegacyOperatorIfPresent(staged.root, process.execPath, modulePath);
|
|
392
|
+
},
|
|
386
393
|
cleanup: staged.cleanup,
|
|
387
394
|
rollback: staged.rollback,
|
|
388
395
|
};
|
|
389
396
|
}
|
|
390
397
|
async function writeOperatorLauncher(path, nodePath, cliPath, clientDataRoot, managedRootId, deploymentId) {
|
|
391
|
-
const temporaryPath = `${path}.${randomUUID()}.tmp`;
|
|
392
398
|
const contents = operatorLauncherContents(nodePath, cliPath, clientDataRoot, managedRootId, deploymentId);
|
|
399
|
+
await writeStableOperator(path, contents);
|
|
400
|
+
}
|
|
401
|
+
async function writeStableOperator(path, contents) {
|
|
402
|
+
const temporaryPath = `${path}.${randomUUID()}.tmp`;
|
|
393
403
|
try {
|
|
394
404
|
const file = await open(temporaryPath, 'wx', 0o700);
|
|
395
405
|
try {
|
|
@@ -400,44 +410,53 @@ async function writeOperatorLauncher(path, nodePath, cliPath, clientDataRoot, ma
|
|
|
400
410
|
await file.close();
|
|
401
411
|
}
|
|
402
412
|
await rename(temporaryPath, path);
|
|
403
|
-
|
|
404
|
-
try {
|
|
405
|
-
await parent.sync();
|
|
406
|
-
}
|
|
407
|
-
finally {
|
|
408
|
-
await parent.close();
|
|
409
|
-
}
|
|
413
|
+
await syncDirectory(dirname(path));
|
|
410
414
|
}
|
|
411
415
|
finally {
|
|
412
416
|
await rm(temporaryPath, { force: true });
|
|
413
417
|
}
|
|
414
418
|
}
|
|
415
419
|
function operatorLauncherContents(nodePath, cliPath, clientDataRoot, managedRootId, deploymentId) {
|
|
416
|
-
|
|
417
|
-
'
|
|
418
|
-
|
|
419
|
-
'
|
|
420
|
-
|
|
421
|
-
'
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
420
|
+
const fixedServiceArguments = [
|
|
421
|
+
'--client-data-root',
|
|
422
|
+
clientDataRoot,
|
|
423
|
+
'--managed-root-id',
|
|
424
|
+
managedRootId,
|
|
425
|
+
...(deploymentId ? ['--operator-deployment-id', deploymentId] : []),
|
|
426
|
+
];
|
|
427
|
+
return `import { spawn } from 'node:child_process';
|
|
428
|
+
|
|
429
|
+
const [action, ...args] = process.argv.slice(2);
|
|
430
|
+
const direct = new Set(['access', 'activate', 'connect', 'serve']);
|
|
431
|
+
const cliArgs = action === '__cleanup-managed-deployment'
|
|
432
|
+
? ['runtime-host', 'service', 'cleanup-deployment', ...args, ...${JSON.stringify(fixedServiceArguments)}]
|
|
433
|
+
: direct.has(action)
|
|
434
|
+
? ['runtime-host', action, ...args]
|
|
435
|
+
: ['runtime-host', 'service', ...(action === undefined ? [] : [action]), ...args, ...${JSON.stringify(fixedServiceArguments)}];
|
|
436
|
+
const child = spawn(${JSON.stringify(nodePath)}, [${JSON.stringify(cliPath)}, ...cliArgs], {
|
|
437
|
+
stdio: 'inherit',
|
|
438
|
+
windowsHide: true,
|
|
439
|
+
});
|
|
440
|
+
const signalForwarders = new Map();
|
|
441
|
+
for (const signal of ['SIGINT', 'SIGTERM']) {
|
|
442
|
+
const forward = () => child.kill(signal);
|
|
443
|
+
signalForwarders.set(signal, forward);
|
|
444
|
+
process.on(signal, forward);
|
|
445
|
+
}
|
|
446
|
+
const stopForwardingSignals = () => {
|
|
447
|
+
for (const [signal, forward] of signalForwarders) process.off(signal, forward);
|
|
448
|
+
};
|
|
449
|
+
child.once('error', (error) => {
|
|
450
|
+
stopForwardingSignals();
|
|
451
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
452
|
+
process.exitCode = 1;
|
|
453
|
+
});
|
|
454
|
+
child.once('exit', (code, signal) => {
|
|
455
|
+
stopForwardingSignals();
|
|
456
|
+
if (signal) process.kill(process.pid, signal);
|
|
457
|
+
else process.exitCode = code ?? 1;
|
|
458
|
+
});
|
|
459
|
+
`;
|
|
441
460
|
}
|
|
442
461
|
export async function convergeRuntimeHostManagedOperator(current, desired) {
|
|
443
462
|
const deployment = desired ?? current;
|
|
@@ -447,35 +466,77 @@ export async function convergeRuntimeHostManagedOperator(current, desired) {
|
|
|
447
466
|
// is removed. Package cleanup removes it with the deployment root.
|
|
448
467
|
if (!desired)
|
|
449
468
|
return;
|
|
450
|
-
const operatorPath =
|
|
469
|
+
const operatorPath = runtimeHostManagedOperatorModulePath(deployment.deploymentRoot, process.platform === 'win32' ? 'win32' : 'posix');
|
|
451
470
|
const layout = resolveRuntimeHostNpmDeploymentLayout(desired.deploymentRoot, desired.launch.package.integrity);
|
|
452
471
|
await writeOperatorLauncher(operatorPath, desired.launch.nodePath, layout.cliPath, resolveRuntimeHostManagedControlRoot(desired.root.id), desired.root.id, desired.deploymentId);
|
|
472
|
+
await forwardLegacyOperatorIfPresent(deployment.deploymentRoot, desired.launch.nodePath, operatorPath);
|
|
473
|
+
}
|
|
474
|
+
function legacyOperatorLauncherContents(nodePath, modulePath) {
|
|
475
|
+
return `#!/bin/sh\nexec ${quotePosix(nodePath)} ${quotePosix(modulePath)} "$@"\n`;
|
|
476
|
+
}
|
|
477
|
+
async function forwardLegacyOperatorIfPresent(deploymentRoot, nodePath, modulePath) {
|
|
478
|
+
if (process.platform === 'win32')
|
|
479
|
+
return;
|
|
480
|
+
const path = join(deploymentRoot, 'operator');
|
|
481
|
+
const exists = await access(path, constants.F_OK).then(() => true, (error) => {
|
|
482
|
+
if (isNodeError(error, 'ENOENT'))
|
|
483
|
+
return false;
|
|
484
|
+
throw error;
|
|
485
|
+
});
|
|
486
|
+
if (exists) {
|
|
487
|
+
await writeStableOperator(path, legacyOperatorLauncherContents(nodePath, modulePath));
|
|
488
|
+
}
|
|
453
489
|
}
|
|
454
490
|
export async function restoreRuntimeHostLegacyManagedOperator(input) {
|
|
455
|
-
await writeOperatorLauncher(
|
|
491
|
+
await writeOperatorLauncher(runtimeHostManagedOperatorModulePath(input.deploymentRoot, 'posix'), input.nodePath, input.cliPath, input.clientDataRoot, input.serviceId);
|
|
456
492
|
}
|
|
457
493
|
export async function verifyRuntimeHostManagedOperator(config) {
|
|
458
494
|
const layout = resolveRuntimeHostNpmDeploymentLayout(config.deploymentRoot, config.launch.package.integrity);
|
|
459
495
|
const expected = operatorLauncherContents(config.launch.nodePath, layout.cliPath, resolveRuntimeHostManagedControlRoot(config.root.id), config.root.id, config.deploymentId);
|
|
496
|
+
const operatorPath = runtimeHostManagedOperatorModulePath(config.deploymentRoot, process.platform === 'win32' ? 'win32' : 'posix');
|
|
460
497
|
const observed = await readStableBoundedFile({
|
|
461
|
-
path:
|
|
498
|
+
path: operatorPath,
|
|
462
499
|
maxBytes: Buffer.byteLength(expected),
|
|
463
500
|
invalidFile: () => new Error('The managed Runtime Host operator is not a stable regular file'),
|
|
464
501
|
}).then((contents) => new TextDecoder('utf-8', { fatal: true }).decode(contents));
|
|
465
502
|
if (observed !== expected)
|
|
466
503
|
throw new Error('The managed Runtime Host operator does not match its deployment');
|
|
467
|
-
await access(
|
|
468
|
-
throw new Error('The managed Runtime Host operator is not
|
|
504
|
+
await access(operatorPath, constants.R_OK).catch((error) => {
|
|
505
|
+
throw new Error('The managed Runtime Host operator is not readable', {
|
|
469
506
|
cause: error,
|
|
470
507
|
});
|
|
471
508
|
});
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
509
|
+
const legacyOperatorPath = join(config.deploymentRoot, 'operator');
|
|
510
|
+
const legacyExpected = legacyOperatorLauncherContents(config.launch.nodePath, operatorPath);
|
|
511
|
+
const legacyExists = await access(legacyOperatorPath, constants.F_OK).then(() => true, (error) => {
|
|
512
|
+
if (isNodeError(error, 'ENOENT'))
|
|
513
|
+
return false;
|
|
514
|
+
throw error;
|
|
515
|
+
});
|
|
516
|
+
const legacyObserved = legacyExists
|
|
517
|
+
? await readStableBoundedFile({
|
|
518
|
+
path: legacyOperatorPath,
|
|
519
|
+
maxBytes: Buffer.byteLength(legacyExpected),
|
|
520
|
+
invalidFile: () => new Error('The legacy managed Runtime Host operator is invalid'),
|
|
521
|
+
}).then((contents) => new TextDecoder('utf-8', { fatal: true }).decode(contents))
|
|
522
|
+
: null;
|
|
523
|
+
if (legacyObserved !== null && legacyObserved !== legacyExpected) {
|
|
524
|
+
throw new Error('The legacy managed Runtime Host operator does not match its deployment');
|
|
525
|
+
}
|
|
526
|
+
if (legacyObserved !== null) {
|
|
527
|
+
await access(legacyOperatorPath, constants.X_OK).catch((error) => {
|
|
528
|
+
throw new Error('The legacy managed Runtime Host operator is not executable', {
|
|
529
|
+
cause: error,
|
|
530
|
+
});
|
|
531
|
+
});
|
|
532
|
+
}
|
|
475
533
|
}
|
|
476
534
|
function isRecord(value) {
|
|
477
535
|
return value !== null && typeof value === 'object' && !Array.isArray(value);
|
|
478
536
|
}
|
|
537
|
+
function quotePosix(value) {
|
|
538
|
+
return `'${value.replaceAll("'", `'"'"'`)}'`;
|
|
539
|
+
}
|
|
479
540
|
function isNodeError(error, code) {
|
|
480
541
|
return error instanceof Error && 'code' in error && error.code === code;
|
|
481
542
|
}
|
|
@@ -26,7 +26,7 @@ export async function manageRuntimeHostManagedLifecycle(rootId, input, dependenc
|
|
|
26
26
|
const lifecycleDeps = {
|
|
27
27
|
convergeOperator: (currentConfig, desiredConfig) => convergeRuntimeHostManagedOperator(currentConfig, desiredConfig),
|
|
28
28
|
verifyOperator: verifyRuntimeHostManagedOperator,
|
|
29
|
-
resolveProvider:
|
|
29
|
+
resolveProvider: dependencies.resolveProvider,
|
|
30
30
|
};
|
|
31
31
|
const resolved = await resolveRecoverableRuntimeHostManagedDeployment(rootId, lifecycleDeps, {
|
|
32
32
|
...(input.expectedTarget ? { expectedTarget: input.expectedTarget } : {}),
|
|
@@ -45,10 +45,7 @@ export async function manageRuntimeHostManagedLifecycle(rootId, input, dependenc
|
|
|
45
45
|
if (dependencies.operatorClaim) {
|
|
46
46
|
assertRuntimeHostManagedOperatorConfig(config, dependencies.operatorClaim.deploymentId, dependencies.operatorClaim.cliPath);
|
|
47
47
|
}
|
|
48
|
-
const
|
|
49
|
-
const provider = supervisedLifecycle
|
|
50
|
-
? dependencies.resolveProvider(rootId, supervisedLifecycle.provider)
|
|
51
|
-
: undefined;
|
|
48
|
+
const provider = config.lifecycle.mode === 'supervised' ? dependencies.resolveProvider(config) : undefined;
|
|
52
49
|
if (input.action === 'install') {
|
|
53
50
|
throw new RuntimeHostServiceManagerError('target_mismatch', 'Managed Runtime Host installation must use runtime-host setup');
|
|
54
51
|
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
* under the License.
|
|
18
18
|
*/
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
|
+
import { spawn } from 'node:child_process';
|
|
20
21
|
import { cp, lstat, mkdir, readFile, readdir, realpath, rename, rm, stat } from 'node:fs/promises';
|
|
21
22
|
import { basename, dirname, isAbsolute, join, parse, relative, resolve, sep } from 'node:path';
|
|
22
23
|
import { resolveRuntimeHostNpmDeploymentLayout } from '@maka/runtime-host/operator';
|
|
@@ -223,12 +224,12 @@ async function removePackageAtomically(versionsRoot, packageName) {
|
|
|
223
224
|
const packageRoot = join(versionsRoot, packageName);
|
|
224
225
|
try {
|
|
225
226
|
if (packageName.startsWith('.') && packageName.endsWith('.deleted')) {
|
|
226
|
-
await
|
|
227
|
+
await removeDeploymentDirectory(packageRoot);
|
|
227
228
|
return;
|
|
228
229
|
}
|
|
229
230
|
const tombstone = join(versionsRoot, `.${packageName}.${randomUUID()}.deleted`);
|
|
230
231
|
await rename(packageRoot, tombstone);
|
|
231
|
-
await
|
|
232
|
+
await removeDeploymentDirectory(tombstone);
|
|
232
233
|
}
|
|
233
234
|
catch (error) {
|
|
234
235
|
if (isNodeError(error, 'ENOENT'))
|
|
@@ -236,6 +237,38 @@ async function removePackageAtomically(versionsRoot, packageName) {
|
|
|
236
237
|
throw new RuntimeHostPackageDeploymentError('deployment_failed', 'Unable to remove an inactive Runtime Host package', { cause: error });
|
|
237
238
|
}
|
|
238
239
|
}
|
|
240
|
+
export async function removeDeploymentDirectory(path) {
|
|
241
|
+
try {
|
|
242
|
+
await rm(path, { recursive: true, force: true });
|
|
243
|
+
}
|
|
244
|
+
catch (error) {
|
|
245
|
+
if (process.platform !== 'win32')
|
|
246
|
+
throw error;
|
|
247
|
+
deferWindowsDirectoryRemovalUntilExit(path);
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function deferWindowsDirectoryRemovalUntilExit(path) {
|
|
251
|
+
// Loaded native addons remain locked until this operator exits. The caller
|
|
252
|
+
// has already renamed the directory out of authority before reaching here.
|
|
253
|
+
const script = `const { rm } = require('node:fs/promises');
|
|
254
|
+
const path = process.argv[1];
|
|
255
|
+
const parent = Number(process.argv[2]);
|
|
256
|
+
const wait = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
257
|
+
(async () => {
|
|
258
|
+
for (let attempt = 0; attempt < 3000; attempt += 1) {
|
|
259
|
+
try { process.kill(parent, 0); } catch { break; }
|
|
260
|
+
await wait(100);
|
|
261
|
+
}
|
|
262
|
+
await rm(path, { recursive: true, force: true, maxRetries: 100, retryDelay: 100 });
|
|
263
|
+
})().catch(() => { process.exitCode = 1; });`;
|
|
264
|
+
const cleanup = spawn(process.execPath, ['-e', script, path, String(process.pid)], {
|
|
265
|
+
detached: true,
|
|
266
|
+
stdio: 'ignore',
|
|
267
|
+
windowsHide: true,
|
|
268
|
+
});
|
|
269
|
+
cleanup.on('error', () => undefined);
|
|
270
|
+
cleanup.unref();
|
|
271
|
+
}
|
|
239
272
|
function registryPackageLayout(deploymentRoot, integrity) {
|
|
240
273
|
try {
|
|
241
274
|
return resolveRuntimeHostNpmDeploymentLayout(deploymentRoot, integrity);
|
|
@@ -20,7 +20,7 @@ import { access, realpath } from 'node:fs/promises';
|
|
|
20
20
|
import { basename, dirname, join } from 'node:path';
|
|
21
21
|
const PEER_NATIVE_FILE = 'maka_runtime_host_peer.node';
|
|
22
22
|
const SUPPORTED_TARGETS = new Set(['darwin-arm64', 'linux-arm64', 'linux-x64', 'win32-x64']);
|
|
23
|
-
export async function
|
|
23
|
+
export async function resolveRuntimeHostNativePath(cliPath) {
|
|
24
24
|
const packageRoot = dirname(dirname(await realpath(cliPath)));
|
|
25
25
|
const target = runtimeHostPeerTarget();
|
|
26
26
|
const packaged = join(packageRoot, 'native', 'runtime-host-peer', 'prebuilds', target, PEER_NATIVE_FILE);
|
|
@@ -31,7 +31,7 @@ export async function resolveRuntimeHostPeerNativePath(cliPath) {
|
|
|
31
31
|
if (await isReadable(development))
|
|
32
32
|
return realpath(development);
|
|
33
33
|
}
|
|
34
|
-
throw new Error(`Maka does not include a
|
|
34
|
+
throw new Error(`Maka does not include a Runtime Host native artifact for ${target}`);
|
|
35
35
|
}
|
|
36
36
|
export function runtimeHostPeerTarget(platform = process.platform, arch = process.arch) {
|
|
37
37
|
const target = `${platform}-${arch}`;
|
|
@@ -56,7 +56,7 @@ export async function configureRuntimeHostPeerClient(input) {
|
|
|
56
56
|
if (explicitNativePath || explicitKeyPath)
|
|
57
57
|
return Boolean(explicitNativePath && explicitKeyPath);
|
|
58
58
|
try {
|
|
59
|
-
environment.MAKA_RUNTIME_HOST_PEER_NATIVE_PATH = await
|
|
59
|
+
environment.MAKA_RUNTIME_HOST_PEER_NATIVE_PATH = await resolveRuntimeHostNativePath(input.cliPath);
|
|
60
60
|
environment.MAKA_RUNTIME_HOST_PEER_KEY_PATH = resolveRuntimeHostClientPeerKeyPath(input.clientDataRoot);
|
|
61
61
|
return true;
|
|
62
62
|
}
|
|
@@ -28,7 +28,7 @@ import { allocateRuntimeHostPeerPort, RuntimeHostServiceManagerError, withRuntim
|
|
|
28
28
|
import { resolveRuntimeHostLifecycleProvider } from './runtime-host-service-management-command.js';
|
|
29
29
|
import { canDiscardRuntimeHostLifecycleDesiredArtifacts, replaceRuntimeHostLifecycle, resolveRecoverableRuntimeHostManagedDeployment, activateRuntimeHostLifecycle, verifyRuntimeHostLifecycleReady, } from './runtime-host-lifecycle-transaction.js';
|
|
30
30
|
import { manageRuntimeHostManagedLifecycle } from './runtime-host-managed-lifecycle-manager.js';
|
|
31
|
-
import { resolveRuntimeHostManagedPeerKeyPath,
|
|
31
|
+
import { resolveRuntimeHostManagedPeerKeyPath, resolveRuntimeHostNativePath, } from './runtime-host-peer-artifact.js';
|
|
32
32
|
import { assertRuntimeHostManagedOperatorConfig, assertRuntimeHostManagedOperatorDeployment, convergeRuntimeHostManagedOperator, pruneRuntimeHostManagedPeerKeys, resolveRuntimeHostManagedControlRoot, verifyRuntimeHostManagedOperator, } from './runtime-host-managed-deployment.js';
|
|
33
33
|
export async function runRuntimeHostPeerManagementCli(options, overrides = {}) {
|
|
34
34
|
const deps = {
|
|
@@ -50,7 +50,7 @@ async function runCanonicalRuntimeHostPeerManagementLocked(options, deps) {
|
|
|
50
50
|
const lifecycleDeps = {
|
|
51
51
|
convergeOperator: (currentConfig, desiredConfig) => convergeRuntimeHostManagedOperator(currentConfig, desiredConfig),
|
|
52
52
|
verifyOperator: verifyRuntimeHostManagedOperator,
|
|
53
|
-
resolveProvider:
|
|
53
|
+
resolveProvider: resolveRuntimeHostLifecycleProvider,
|
|
54
54
|
};
|
|
55
55
|
const resolved = await resolveRecoverableRuntimeHostManagedDeployment(rootId, lifecycleDeps, {
|
|
56
56
|
...(options.expectedTarget ? { expectedTarget: options.expectedTarget } : {}),
|
|
@@ -105,7 +105,7 @@ async function runCanonicalRuntimeHostPeerManagementLocked(options, deps) {
|
|
|
105
105
|
stagedKeyPath = join(dirname(current.keyPath), `runtime-host-peer.${randomUUID()}.key`);
|
|
106
106
|
const layout = resolveRuntimeHostNpmDeploymentLayout(config.deploymentRoot, config.launch.package.integrity);
|
|
107
107
|
const peerId = await ensureRuntimeHostPeerIdentity({
|
|
108
|
-
nativePath: await
|
|
108
|
+
nativePath: await resolveRuntimeHostNativePath(layout.cliPath),
|
|
109
109
|
keyPath: stagedKeyPath,
|
|
110
110
|
});
|
|
111
111
|
desired = {
|
|
@@ -198,7 +198,7 @@ async function prepareCanonicalPeer(options, config, current) {
|
|
|
198
198
|
const layout = resolveRuntimeHostNpmDeploymentLayout(config.deploymentRoot, config.launch.package.integrity);
|
|
199
199
|
const keyPath = current?.keyPath ?? resolveRuntimeHostManagedPeerKeyPath(config.deploymentRoot);
|
|
200
200
|
const peerId = await ensureRuntimeHostPeerIdentity({
|
|
201
|
-
nativePath: await
|
|
201
|
+
nativePath: await resolveRuntimeHostNativePath(layout.cliPath),
|
|
202
202
|
keyPath,
|
|
203
203
|
});
|
|
204
204
|
if (current && current.peerId !== peerId) {
|
|
@@ -46,7 +46,7 @@ export async function runRuntimeHostPeerMeshManagementCli(options, overrides = {
|
|
|
46
46
|
const resolved = await resolveRecoverableRuntimeHostManagedDeployment(options.managedRootId, {
|
|
47
47
|
convergeOperator: convergeRuntimeHostManagedOperator,
|
|
48
48
|
verifyOperator: verifyRuntimeHostManagedOperator,
|
|
49
|
-
resolveProvider:
|
|
49
|
+
resolveProvider: resolveRuntimeHostLifecycleProvider,
|
|
50
50
|
}, { expectedTarget: options.expectedTarget });
|
|
51
51
|
if (resolved.kind === 'absent') {
|
|
52
52
|
throw new RuntimeHostServiceManagerError('not_installed', 'The managed Runtime Host deployment is not installed');
|