maka-agent 0.2.0-dev.8.20260830 → 0.2.0-dev.9.20260831
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/dist/cli-core.js +11 -0
- package/dist/runtime-host-cli.js +44 -0
- package/dist/runtime-host-installed-update-activator.js +70 -33
- package/dist/runtime-host-installed-update-coordinator.js +11 -96
- package/dist/runtime-host-lifecycle-transaction.js +2 -0
- package/dist/runtime-host-local-handoff.js +169 -38
- package/dist/runtime-host-local-source-retirement.js +103 -0
- package/dist/runtime-host-local-target-activation.js +141 -0
- package/dist/runtime-host-peer-management-command.js +10 -4
- 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/core/dist/artifacts.js +23 -15
- package/node_modules/@maka/core/dist/durable-tool-result-projection.js +124 -0
- package/node_modules/@maka/core/dist/llm-connections.js +20 -0
- package/node_modules/@maka/core/dist/runtime-event.js +28 -3
- package/node_modules/@maka/core/dist/session-name.js +0 -1
- package/node_modules/@maka/core/package.json +1 -0
- package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +95 -19
- package/node_modules/@maka/runtime/dist/conversation-copy.js +67 -0
- package/node_modules/@maka/runtime/dist/durable-tool-result-projection.js +390 -0
- package/node_modules/@maka/runtime/dist/model-history.js +12 -39
- package/node_modules/@maka/runtime/dist/recovery-resolver.js +18 -14
- package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +20 -11
- package/node_modules/@maka/runtime/dist/session-manager.js +0 -170
- package/node_modules/@maka/runtime/dist/tool-runtime.js +118 -71
- package/node_modules/@maka/runtime/package.json +1 -0
- package/node_modules/@maka/runtime-host/dist/candidate-entry.js +6 -1
- package/node_modules/@maka/runtime-host/dist/candidate-launch-owner-guard.js +13 -0
- package/node_modules/@maka/runtime-host/dist/client/connect-or-spawn.js +4 -1
- package/node_modules/@maka/runtime-host/dist/client/host-profile.js +27 -1
- package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/client/launcher.js +8 -2
- package/node_modules/@maka/runtime-host/dist/client/peer-client.js +11 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/index.js +1 -1
- package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +394 -113
- package/node_modules/@maka/runtime-host/dist/peer-mesh/store.js +90 -21
- package/node_modules/@maka/runtime-host/dist/protocol/index.js +8 -1
- package/node_modules/@maka/runtime-host/dist/protocol/oauth.js +60 -7
- package/node_modules/@maka/runtime-host/dist/protocol/usage-pricing.js +4 -0
- package/node_modules/@maka/runtime-host/dist/server/artifact-coordinator.js +2 -4
- package/node_modules/@maka/runtime-host/dist/server/candidate.js +3 -0
- package/node_modules/@maka/runtime-host/dist/server/client-capability-recovery.js +10 -7
- package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +5 -1
- package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +9 -1
- package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +10 -0
- package/node_modules/@maka/runtime-host/dist/server/oauth-coordinator.js +91 -42
- package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +10 -1
- package/node_modules/@maka/runtime-host/dist/server/usage-pricing-coordinator.js +45 -5
- package/node_modules/@maka/storage/dist/artifact-attachments.js +62 -11
- package/node_modules/@maka/storage/dist/artifact-store.js +11 -0
- package/node_modules/@maka/storage/dist/artifact-stores.js +4 -1
- package/node_modules/@maka/storage/dist/quiescent-session-snapshot.js +1154 -0
- package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +36 -0
- package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +213 -46
- package/node_modules/@maka/storage/dist/runtime-policy/document-io.js +1 -1
- package/node_modules/@maka/storage/dist/runtime-policy/oauth-login-receipt-document.js +186 -0
- package/node_modules/@maka/storage/dist/runtime-policy/onboarding-transaction.js +120 -1
- package/node_modules/@maka/storage/dist/runtime-policy-stores.js +2 -1
- package/node_modules/@maka/storage/dist/session-bundle-ustar.js +12 -0
- package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +5 -0
- package/package.json +1 -1
package/dist/cli-core.js
CHANGED
|
@@ -340,6 +340,17 @@ export async function runMakaCli(argv = process.argv.slice(2), options = RELEASE
|
|
|
340
340
|
...(command.awaitCoordinatorCommit ? { inheritableAuthorityLeaseFd: 4 } : {}),
|
|
341
341
|
});
|
|
342
342
|
}
|
|
343
|
+
case 'runtime-host-local-source-retire': {
|
|
344
|
+
const { runRuntimeHostLocalSourceRetirement } = await import('./runtime-host-local-source-retirement.js');
|
|
345
|
+
return runRuntimeHostLocalSourceRetirement({
|
|
346
|
+
rootPath: command.rootPath,
|
|
347
|
+
expectedRootId: command.expectedRootId,
|
|
348
|
+
expectedHostEpoch: command.expectedHostEpoch,
|
|
349
|
+
activeWorkPolicy: command.allowInterruptActiveTasks
|
|
350
|
+
? 'interrupt_active_work'
|
|
351
|
+
: 'refuse_active_work',
|
|
352
|
+
});
|
|
353
|
+
}
|
|
343
354
|
case 'runtime-host-setup': {
|
|
344
355
|
const { runRuntimeHostSetupCli } = await import('./runtime-host-setup-command.js');
|
|
345
356
|
const { RUNTIME_HOST_SETUP_SOURCE_PACKAGE_INTEGRITY_ENV } = await import('@maka/runtime-host/operator');
|
package/dist/runtime-host-cli.js
CHANGED
|
@@ -28,6 +28,8 @@ export function parseRuntimeHostCommand(argv) {
|
|
|
28
28
|
return parseLocalUpdateApply(argv.slice(1));
|
|
29
29
|
if (argv[0] === 'local-update-activate')
|
|
30
30
|
return parseLocalUpdateActivate(argv.slice(1));
|
|
31
|
+
if (argv[0] === 'local-source-retire')
|
|
32
|
+
return parseLocalSourceRetire(argv.slice(1));
|
|
31
33
|
if (argv[0] === 'serve')
|
|
32
34
|
return parseServeCommand(argv.slice(1));
|
|
33
35
|
if (argv[0] === 'setup')
|
|
@@ -277,6 +279,48 @@ function parseLocalUpdateActivate(argv) {
|
|
|
277
279
|
...(targetIntegrity ? { targetIntegrity } : {}),
|
|
278
280
|
};
|
|
279
281
|
}
|
|
282
|
+
function parseLocalSourceRetire(argv) {
|
|
283
|
+
const values = new Map();
|
|
284
|
+
let allowInterruptActiveTasks = false;
|
|
285
|
+
const options = new Set(['--root', '--expected-root-id', '--expected-host-epoch']);
|
|
286
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
287
|
+
const argument = argv[index];
|
|
288
|
+
if (argument === '--allow-interrupt-active-tasks') {
|
|
289
|
+
if (allowInterruptActiveTasks)
|
|
290
|
+
return error(`Duplicate ${argument}`);
|
|
291
|
+
allowInterruptActiveTasks = true;
|
|
292
|
+
continue;
|
|
293
|
+
}
|
|
294
|
+
if (!argument || !options.has(argument))
|
|
295
|
+
return error(`Unexpected argument: ${argument ?? ''}`);
|
|
296
|
+
if (values.has(argument))
|
|
297
|
+
return error(`Duplicate ${argument}`);
|
|
298
|
+
const parsed = optionValue(argv, index, argument);
|
|
299
|
+
if (typeof parsed !== 'string')
|
|
300
|
+
return parsed;
|
|
301
|
+
values.set(argument, parsed);
|
|
302
|
+
index += 1;
|
|
303
|
+
}
|
|
304
|
+
const rootPath = values.get('--root');
|
|
305
|
+
const expectedRootId = values.get('--expected-root-id');
|
|
306
|
+
const expectedHostEpoch = values.get('--expected-host-epoch');
|
|
307
|
+
if (!rootPath || !expectedRootId || !expectedHostEpoch) {
|
|
308
|
+
return error('runtime-host local-source-retire requires its exact source Host identity');
|
|
309
|
+
}
|
|
310
|
+
if (!isSafeAbsolutePath(rootPath)) {
|
|
311
|
+
return error('runtime-host local-source-retire root path must be absolute');
|
|
312
|
+
}
|
|
313
|
+
if (!/^[a-f0-9]{64}$/u.test(expectedRootId) || !isSafeIdentity(expectedHostEpoch)) {
|
|
314
|
+
return error('runtime-host local-source-retire Host identity is invalid');
|
|
315
|
+
}
|
|
316
|
+
return {
|
|
317
|
+
kind: 'runtime-host-local-source-retire',
|
|
318
|
+
rootPath,
|
|
319
|
+
expectedRootId,
|
|
320
|
+
expectedHostEpoch,
|
|
321
|
+
allowInterruptActiveTasks,
|
|
322
|
+
};
|
|
323
|
+
}
|
|
280
324
|
function isSafeIdentity(value) {
|
|
281
325
|
return value.length <= 512 && !/[\u0000-\u001f\u007f]/u.test(value);
|
|
282
326
|
}
|
|
@@ -18,8 +18,18 @@
|
|
|
18
18
|
*/
|
|
19
19
|
import { randomUUID } from 'node:crypto';
|
|
20
20
|
import { createRuntimeHostCandidateLaunchBarrier, prepareConnectedRuntimeHostRetirement, runtimeHostStartupError, } from '@maka/runtime-host/client';
|
|
21
|
-
import { readLocalHostDeploymentRecord } from '@maka/runtime-host/operator';
|
|
21
|
+
import { LocalHostDeploymentAuthorityError, readLocalHostDeploymentRecord, } from '@maka/runtime-host/operator';
|
|
22
22
|
import { INTERACTIVE_RUNTIME_HOST_COMPOSITION_ID, RUNTIME_HOST_PROTOCOL_VERSION, } from '@maka/runtime-host/protocol';
|
|
23
|
+
const DURABLE_SETTLEMENT_RETRY_MS = 100;
|
|
24
|
+
const DURABLE_SETTLEMENT_TIMEOUT_MS = 10_000;
|
|
25
|
+
export class RuntimeHostDurableSettlementError extends Error {
|
|
26
|
+
code;
|
|
27
|
+
constructor(code, message, options) {
|
|
28
|
+
super(message, options);
|
|
29
|
+
this.code = code;
|
|
30
|
+
this.name = 'RuntimeHostDurableSettlementError';
|
|
31
|
+
}
|
|
32
|
+
}
|
|
23
33
|
export async function runRuntimeHostInstalledUpdateActivator(input, overrides = {}) {
|
|
24
34
|
const launchBarrier = (overrides.createLaunchBarrier ?? createRuntimeHostCandidateLaunchBarrier)();
|
|
25
35
|
const result = await (overrides.connectOrSpawn ?? ((request) => launchBarrier.connect(request)))({
|
|
@@ -36,7 +46,7 @@ export async function runRuntimeHostInstalledUpdateActivator(input, overrides =
|
|
|
36
46
|
});
|
|
37
47
|
if (result.kind === 'connected') {
|
|
38
48
|
let exactTarget = false;
|
|
39
|
-
let
|
|
49
|
+
let durableSettlementOwnsRetirement = false;
|
|
40
50
|
try {
|
|
41
51
|
if (result.registration.rootId !== input.expectedRootId ||
|
|
42
52
|
result.registration.generation !== input.generation ||
|
|
@@ -49,9 +59,8 @@ export async function runRuntimeHostInstalledUpdateActivator(input, overrides =
|
|
|
49
59
|
if (!input.expectedOwnerInstallationId || !input.targetVersion || !input.targetIntegrity) {
|
|
50
60
|
throw new Error('The activator is missing its exact durable commit expectation');
|
|
51
61
|
}
|
|
52
|
-
|
|
62
|
+
durableSettlementOwnsRetirement = true;
|
|
53
63
|
await (overrides.awaitCoordinatorCommit ?? awaitCoordinatorCommit)({
|
|
54
|
-
registration: result.registration,
|
|
55
64
|
connection: result.connection,
|
|
56
65
|
expectedRootId: input.expectedRootId,
|
|
57
66
|
ownerInstallationId: input.expectedOwnerInstallationId,
|
|
@@ -69,7 +78,7 @@ export async function runRuntimeHostInstalledUpdateActivator(input, overrides =
|
|
|
69
78
|
return 0;
|
|
70
79
|
}
|
|
71
80
|
catch (error) {
|
|
72
|
-
if (exactTarget && !
|
|
81
|
+
if (exactTarget && !durableSettlementOwnsRetirement) {
|
|
73
82
|
await retireUncommittedTarget({
|
|
74
83
|
connection: result.connection,
|
|
75
84
|
ownsCandidate: result.spawnedProcess !== undefined,
|
|
@@ -100,8 +109,11 @@ export async function runRuntimeHostInstalledUpdateActivator(input, overrides =
|
|
|
100
109
|
*/
|
|
101
110
|
async function awaitCoordinatorCommit(input) {
|
|
102
111
|
if (typeof process.send !== 'function' || !process.connected) {
|
|
103
|
-
await
|
|
104
|
-
|
|
112
|
+
const settlement = await settleTargetFromDurableAuthority(input);
|
|
113
|
+
if (settlement === 'retired') {
|
|
114
|
+
throw new Error('The installed update activator lost its coordinator before ownership committed');
|
|
115
|
+
}
|
|
116
|
+
return;
|
|
105
117
|
}
|
|
106
118
|
await new Promise((resolve, reject) => {
|
|
107
119
|
let settled = false;
|
|
@@ -119,28 +131,19 @@ async function awaitCoordinatorCommit(input) {
|
|
|
119
131
|
const onMessage = (message) => {
|
|
120
132
|
if (!isCoordinatorMessage(message))
|
|
121
133
|
return;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
input.launchBarrier.release();
|
|
129
|
-
});
|
|
130
|
-
}
|
|
131
|
-
if (message.kind === 'abort') {
|
|
132
|
-
settle(async () => {
|
|
133
|
-
await retireUncommittedTarget(input);
|
|
134
|
-
throw new Error('The installed update coordinator aborted before durable ownership committed');
|
|
135
|
-
});
|
|
136
|
-
}
|
|
134
|
+
settle(async () => {
|
|
135
|
+
const settlement = await settleTargetFromDurableAuthority(input);
|
|
136
|
+
if (settlement === 'retired') {
|
|
137
|
+
throw new Error('The installed update coordinator settled without durable ownership');
|
|
138
|
+
}
|
|
139
|
+
});
|
|
137
140
|
};
|
|
138
141
|
const onDisconnect = () => {
|
|
139
142
|
settle(async () => {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
143
|
+
const settlement = await settleTargetFromDurableAuthority(input);
|
|
144
|
+
if (settlement === 'retired') {
|
|
145
|
+
throw new Error('The installed update coordinator exited before ownership committed');
|
|
146
|
+
}
|
|
144
147
|
});
|
|
145
148
|
};
|
|
146
149
|
process.on('message', onMessage);
|
|
@@ -149,14 +152,48 @@ async function awaitCoordinatorCommit(input) {
|
|
|
149
152
|
});
|
|
150
153
|
}
|
|
151
154
|
function isCoordinatorMessage(value) {
|
|
152
|
-
return (typeof value === 'object' &&
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
155
|
+
return (typeof value === 'object' && value !== null && value.kind === 'settle');
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Makes the activator the only authority for target release versus retirement.
|
|
159
|
+
* Read failures are ambiguous, so retain the launch barrier and inherited lease
|
|
160
|
+
* while retrying transient uncertainty. Permanent corruption and a bounded
|
|
161
|
+
* transient-read timeout fail closed: the activator exits without releasing the
|
|
162
|
+
* barrier, and the launch-owner guard retires the inaccessible candidate.
|
|
163
|
+
*/
|
|
164
|
+
export async function settleTargetFromDurableAuthority(input, options = {}) {
|
|
165
|
+
const now = options.now ?? (() => performance.now());
|
|
166
|
+
const retryRead = options.retryRead ??
|
|
167
|
+
((delayMs) => new Promise((resolve) => setTimeout(resolve, delayMs)));
|
|
168
|
+
const deadline = now() + (options.timeoutMs ?? DURABLE_SETTLEMENT_TIMEOUT_MS);
|
|
169
|
+
let record;
|
|
170
|
+
for (;;) {
|
|
171
|
+
try {
|
|
172
|
+
record = await input.readRecord(input.expectedRootId);
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
catch (error) {
|
|
176
|
+
if (error instanceof LocalHostDeploymentAuthorityError &&
|
|
177
|
+
error.code !== 'authority_io_failed') {
|
|
178
|
+
throw new RuntimeHostDurableSettlementError(error.code === 'invalid_record' ? 'invalid_record' : 'authority_unavailable', error.code === 'invalid_record'
|
|
179
|
+
? 'The local Runtime Host update requires recovery because its durable owner record is invalid'
|
|
180
|
+
: 'The local Runtime Host update requires recovery because its durable owner record cannot be read safely', { cause: error });
|
|
181
|
+
}
|
|
182
|
+
const remainingMs = deadline - now();
|
|
183
|
+
if (remainingMs <= 0) {
|
|
184
|
+
throw new RuntimeHostDurableSettlementError('authority_unavailable', 'The local Runtime Host update requires recovery because its durable owner record remained unavailable', { cause: error });
|
|
185
|
+
}
|
|
186
|
+
await retryRead(Math.min(DURABLE_SETTLEMENT_RETRY_MS, remainingMs));
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
if (isCommittedTarget(record, input)) {
|
|
190
|
+
input.launchBarrier.release();
|
|
191
|
+
return 'committed';
|
|
192
|
+
}
|
|
193
|
+
await retireUncommittedTarget(input);
|
|
194
|
+
return 'retired';
|
|
157
195
|
}
|
|
158
|
-
|
|
159
|
-
const record = await input.readRecord(input.expectedRootId);
|
|
196
|
+
function isCommittedTarget(record, input) {
|
|
160
197
|
return (record?.state.kind === 'owned' &&
|
|
161
198
|
record.state.owner.kind === 'cli' &&
|
|
162
199
|
record.state.owner.installationId === input.ownerInstallationId &&
|
|
@@ -27,6 +27,7 @@ import { resolveStorageRoot } from '@maka/storage/root-authority';
|
|
|
27
27
|
import { prepareRuntimeHostNpmGlobalStagedDeployment, reconcilePreparedRuntimeHostNpmGlobalDeployment, } from './runtime-host-local-handoff.js';
|
|
28
28
|
import { resolveRuntimeHostNpmGlobalInstallation, } from './runtime-host-cli-installation.js';
|
|
29
29
|
import { assertRuntimeHostArchiveExpansionBudget, withVerifiedRuntimeHostUpdateArchive, } from './runtime-host-update-package.js';
|
|
30
|
+
import { launchRuntimeHostTargetActivator, } from './runtime-host-local-target-activation.js';
|
|
30
31
|
const NPM_TIMEOUT_MS = 5 * 60_000;
|
|
31
32
|
const NPM_OUTPUT_MAX_BYTES = 64 * 1024;
|
|
32
33
|
const OFFLINE_REGISTRY = 'http://127.0.0.1:9/';
|
|
@@ -40,7 +41,7 @@ export async function runRuntimeHostInstalledUpdateCoordinator(input, authorityO
|
|
|
40
41
|
withArchive: withVerifiedRuntimeHostUpdateArchive,
|
|
41
42
|
prepareStaged: prepareRuntimeHostNpmGlobalStagedDeployment,
|
|
42
43
|
reconcile: reconcilePreparedRuntimeHostNpmGlobalDeployment,
|
|
43
|
-
activateTarget:
|
|
44
|
+
activateTarget: launchRuntimeHostTargetActivator,
|
|
44
45
|
installArchive: installRuntimeHostNpmGlobalArchive,
|
|
45
46
|
...overrides,
|
|
46
47
|
};
|
|
@@ -161,15 +162,18 @@ export async function runRuntimeHostInstalledUpdateCoordinator(input, authorityO
|
|
|
161
162
|
await finalizeInstalledPackage(input, installation, archivePath, installationOptions, deps, inheritableAuthorityLeaseFd);
|
|
162
163
|
},
|
|
163
164
|
}, authorityOptions);
|
|
164
|
-
if (result.kind === 'completed' && targetActivator) {
|
|
165
|
-
await targetActivator.settle('committed');
|
|
166
|
-
targetActivator = undefined;
|
|
167
|
-
}
|
|
168
165
|
}
|
|
169
166
|
finally {
|
|
170
|
-
if (targetActivator)
|
|
171
|
-
|
|
167
|
+
if (targetActivator) {
|
|
168
|
+
const settlement = targetActivator.settle();
|
|
169
|
+
if (result?.kind === 'completed')
|
|
170
|
+
await settlement;
|
|
171
|
+
else
|
|
172
|
+
await settlement.catch(() => undefined);
|
|
173
|
+
}
|
|
172
174
|
}
|
|
175
|
+
if (!result)
|
|
176
|
+
throw new Error('The installed update transaction produced no result');
|
|
173
177
|
if (result.kind === 'completed') {
|
|
174
178
|
process.stdout.write(`Updated Maka to ${input.target.version}.\n`);
|
|
175
179
|
return 0;
|
|
@@ -258,95 +262,6 @@ export async function installRuntimeHostNpmGlobalArchive(archivePath, inheritabl
|
|
|
258
262
|
});
|
|
259
263
|
});
|
|
260
264
|
}
|
|
261
|
-
function launchTargetActivator(input) {
|
|
262
|
-
const args = [
|
|
263
|
-
input.staged.cliPath,
|
|
264
|
-
'runtime-host',
|
|
265
|
-
'local-update-activate',
|
|
266
|
-
'--root',
|
|
267
|
-
input.rootPath,
|
|
268
|
-
'--expected-root-id',
|
|
269
|
-
input.rootId,
|
|
270
|
-
'--generation',
|
|
271
|
-
input.staged.launchGeneration,
|
|
272
|
-
'--candidate-entrypoint',
|
|
273
|
-
input.staged.candidateEntrypoint,
|
|
274
|
-
'--await-coordinator-commit',
|
|
275
|
-
'true',
|
|
276
|
-
'--expected-owner-installation-id',
|
|
277
|
-
input.ownerInstallationId,
|
|
278
|
-
'--target-version',
|
|
279
|
-
input.target.version,
|
|
280
|
-
'--target-integrity',
|
|
281
|
-
input.target.integrity,
|
|
282
|
-
...(input.takeoverHostEpoch ? ['--takeover-host-epoch', input.takeoverHostEpoch] : []),
|
|
283
|
-
];
|
|
284
|
-
return new Promise((resolve, reject) => {
|
|
285
|
-
const child = spawn(process.execPath, args, {
|
|
286
|
-
// fd 3 is the coordinator channel; fd 4 is the inherited authority
|
|
287
|
-
// lease. The activator, not the long-lived target, owns that lease.
|
|
288
|
-
stdio: ['inherit', 'inherit', 'inherit', 'ipc', input.inheritableAuthorityLeaseFd],
|
|
289
|
-
windowsHide: false,
|
|
290
|
-
});
|
|
291
|
-
let ready = false;
|
|
292
|
-
let settled = false;
|
|
293
|
-
const closed = new Promise((resolveClosed) => {
|
|
294
|
-
child.once('close', (code, signal) => resolveClosed({ code, signal }));
|
|
295
|
-
});
|
|
296
|
-
const closeError = async () => {
|
|
297
|
-
const { code, signal } = await closed;
|
|
298
|
-
if (signal)
|
|
299
|
-
throw new Error(`Maka target activator exited on ${signal}`);
|
|
300
|
-
if (code === 3)
|
|
301
|
-
throw new Error('The activated Runtime Host still owns active work');
|
|
302
|
-
if (code === 4)
|
|
303
|
-
throw new Error('The observed Runtime Host requires its operator');
|
|
304
|
-
throw new Error('The exact Maka target could not be activated');
|
|
305
|
-
};
|
|
306
|
-
const settle = async (outcome) => {
|
|
307
|
-
if (settled)
|
|
308
|
-
return;
|
|
309
|
-
settled = true;
|
|
310
|
-
if (child.connected) {
|
|
311
|
-
await new Promise((resolveSent, rejectSent) => {
|
|
312
|
-
child.send({ kind: outcome }, (error) => (error ? rejectSent(error) : resolveSent()));
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
|
-
const exited = await closed;
|
|
316
|
-
if (outcome === 'committed' && (exited.signal || exited.code !== 0)) {
|
|
317
|
-
if (exited.signal)
|
|
318
|
-
throw new Error(`Maka target activator exited on ${exited.signal}`);
|
|
319
|
-
throw new Error('The exact Maka target activator did not confirm durable ownership');
|
|
320
|
-
}
|
|
321
|
-
};
|
|
322
|
-
child.once('error', reject);
|
|
323
|
-
child.on('message', (message) => {
|
|
324
|
-
if (ready || !isTargetActivatorReadyMessage(message))
|
|
325
|
-
return;
|
|
326
|
-
ready = true;
|
|
327
|
-
resolve({ kind: 'ready', settle });
|
|
328
|
-
});
|
|
329
|
-
void closed.then(({ code, signal }) => {
|
|
330
|
-
if (ready)
|
|
331
|
-
return;
|
|
332
|
-
if (signal) {
|
|
333
|
-
reject(new Error(`Maka target activator exited on ${signal}`));
|
|
334
|
-
}
|
|
335
|
-
else if (code === 3) {
|
|
336
|
-
resolve({ kind: 'active_work', settle: async () => undefined });
|
|
337
|
-
}
|
|
338
|
-
else if (code === 4) {
|
|
339
|
-
resolve({ kind: 'operator_required', settle: async () => undefined });
|
|
340
|
-
}
|
|
341
|
-
else {
|
|
342
|
-
void closeError().catch(reject);
|
|
343
|
-
}
|
|
344
|
-
});
|
|
345
|
-
});
|
|
346
|
-
}
|
|
347
|
-
function isTargetActivatorReadyMessage(value) {
|
|
348
|
-
return (typeof value === 'object' && value !== null && value.kind === 'ready');
|
|
349
|
-
}
|
|
350
265
|
function updateTransactionId(rootId, installation, target) {
|
|
351
266
|
return `npm-global-update:${createHash('sha256')
|
|
352
267
|
.update(rootId)
|
|
@@ -52,6 +52,7 @@ export async function applyRetiredRuntimeHostLifecycleTransition(input) {
|
|
|
52
52
|
let transitionError;
|
|
53
53
|
let previousAuthorityRestored = false;
|
|
54
54
|
try {
|
|
55
|
+
await input.validateRetiredState?.();
|
|
55
56
|
result = await applyRuntimeHostLifecycleTransition(input.owner, {
|
|
56
57
|
operation: input.operation,
|
|
57
58
|
...(current ? { current } : {}),
|
|
@@ -304,6 +305,7 @@ export async function replaceRuntimeHostLifecycle(input) {
|
|
|
304
305
|
desired,
|
|
305
306
|
deps: input.deps,
|
|
306
307
|
...(input.activatePrevious ? { activatePrevious: input.activatePrevious } : {}),
|
|
308
|
+
...(input.validateRetiredState ? { validateRetiredState: input.validateRetiredState } : {}),
|
|
307
309
|
});
|
|
308
310
|
try {
|
|
309
311
|
if (input.activateDesired) {
|