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.
Files changed (63) hide show
  1. package/dist/cli-core.js +11 -0
  2. package/dist/runtime-host-cli.js +44 -0
  3. package/dist/runtime-host-installed-update-activator.js +70 -33
  4. package/dist/runtime-host-installed-update-coordinator.js +11 -96
  5. package/dist/runtime-host-lifecycle-transaction.js +2 -0
  6. package/dist/runtime-host-local-handoff.js +169 -38
  7. package/dist/runtime-host-local-source-retirement.js +103 -0
  8. package/dist/runtime-host-local-target-activation.js +141 -0
  9. package/dist/runtime-host-peer-management-command.js +10 -4
  10. package/native/runtime-host-peer/prebuilds/darwin-arm64/maka_runtime_host_peer.node +0 -0
  11. package/native/runtime-host-peer/prebuilds/linux-arm64/maka_runtime_host_peer.node +0 -0
  12. package/native/runtime-host-peer/prebuilds/linux-x64/maka_runtime_host_peer.node +0 -0
  13. package/native/runtime-host-peer/prebuilds/win32-x64/maka_runtime_host_peer.node +0 -0
  14. package/node_modules/@maka/core/dist/artifacts.js +23 -15
  15. package/node_modules/@maka/core/dist/durable-tool-result-projection.js +124 -0
  16. package/node_modules/@maka/core/dist/llm-connections.js +20 -0
  17. package/node_modules/@maka/core/dist/runtime-event.js +28 -3
  18. package/node_modules/@maka/core/dist/session-name.js +0 -1
  19. package/node_modules/@maka/core/package.json +1 -0
  20. package/node_modules/@maka/runtime/dist/ai-sdk-backend.js +95 -19
  21. package/node_modules/@maka/runtime/dist/conversation-copy.js +67 -0
  22. package/node_modules/@maka/runtime/dist/durable-tool-result-projection.js +390 -0
  23. package/node_modules/@maka/runtime/dist/model-history.js +12 -39
  24. package/node_modules/@maka/runtime/dist/recovery-resolver.js +18 -14
  25. package/node_modules/@maka/runtime/dist/session-event-runtime-mapper.js +20 -11
  26. package/node_modules/@maka/runtime/dist/session-manager.js +0 -170
  27. package/node_modules/@maka/runtime/dist/tool-runtime.js +118 -71
  28. package/node_modules/@maka/runtime/package.json +1 -0
  29. package/node_modules/@maka/runtime-host/dist/candidate-entry.js +6 -1
  30. package/node_modules/@maka/runtime-host/dist/candidate-launch-owner-guard.js +13 -0
  31. package/node_modules/@maka/runtime-host/dist/client/connect-or-spawn.js +4 -1
  32. package/node_modules/@maka/runtime-host/dist/client/host-profile.js +27 -1
  33. package/node_modules/@maka/runtime-host/dist/client/index.js +1 -1
  34. package/node_modules/@maka/runtime-host/dist/client/launcher.js +8 -2
  35. package/node_modules/@maka/runtime-host/dist/client/peer-client.js +11 -1
  36. package/node_modules/@maka/runtime-host/dist/peer-mesh/index.js +1 -1
  37. package/node_modules/@maka/runtime-host/dist/peer-mesh/node.js +394 -113
  38. package/node_modules/@maka/runtime-host/dist/peer-mesh/store.js +90 -21
  39. package/node_modules/@maka/runtime-host/dist/protocol/index.js +8 -1
  40. package/node_modules/@maka/runtime-host/dist/protocol/oauth.js +60 -7
  41. package/node_modules/@maka/runtime-host/dist/protocol/usage-pricing.js +4 -0
  42. package/node_modules/@maka/runtime-host/dist/server/artifact-coordinator.js +2 -4
  43. package/node_modules/@maka/runtime-host/dist/server/candidate.js +3 -0
  44. package/node_modules/@maka/runtime-host/dist/server/client-capability-recovery.js +10 -7
  45. package/node_modules/@maka/runtime-host/dist/server/execution-composition.js +5 -1
  46. package/node_modules/@maka/runtime-host/dist/server/execution-model-composition.js +9 -1
  47. package/node_modules/@maka/runtime-host/dist/server/host-kernel.js +10 -0
  48. package/node_modules/@maka/runtime-host/dist/server/oauth-coordinator.js +91 -42
  49. package/node_modules/@maka/runtime-host/dist/server/session-revision-coordinator.js +10 -1
  50. package/node_modules/@maka/runtime-host/dist/server/usage-pricing-coordinator.js +45 -5
  51. package/node_modules/@maka/storage/dist/artifact-attachments.js +62 -11
  52. package/node_modules/@maka/storage/dist/artifact-store.js +11 -0
  53. package/node_modules/@maka/storage/dist/artifact-stores.js +4 -1
  54. package/node_modules/@maka/storage/dist/quiescent-session-snapshot.js +1154 -0
  55. package/node_modules/@maka/storage/dist/runtime-policy/connection-catalog-document.js +36 -0
  56. package/node_modules/@maka/storage/dist/runtime-policy/coordinator.js +213 -46
  57. package/node_modules/@maka/storage/dist/runtime-policy/document-io.js +1 -1
  58. package/node_modules/@maka/storage/dist/runtime-policy/oauth-login-receipt-document.js +186 -0
  59. package/node_modules/@maka/storage/dist/runtime-policy/onboarding-transaction.js +120 -1
  60. package/node_modules/@maka/storage/dist/runtime-policy-stores.js +2 -1
  61. package/node_modules/@maka/storage/dist/session-bundle-ustar.js +12 -0
  62. package/node_modules/@maka/storage/dist/sqlite-runtime-store.js +5 -0
  63. 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');
@@ -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 commitWaitOwnsAbort = false;
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
- commitWaitOwnsAbort = true;
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 && !commitWaitOwnsAbort) {
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 retireUncommittedTarget(input);
104
- throw new Error('The installed update activator lost its coordinator channel');
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
- if (message.kind === 'committed') {
123
- settle(async () => {
124
- if (!(await isCommittedTarget(input))) {
125
- await retireUncommittedTarget(input);
126
- throw new Error('The target activation was acknowledged before durable ownership committed');
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
- if (await isCommittedTarget(input))
141
- return;
142
- await retireUncommittedTarget(input);
143
- throw new Error('The installed update coordinator exited before durable ownership committed');
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
- value !== null &&
154
- value.kind !== undefined &&
155
- (value.kind === 'committed' ||
156
- value.kind === 'abort'));
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
- async function isCommittedTarget(input) {
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: launchTargetActivator,
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
- await targetActivator.settle('abort').catch(() => undefined);
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) {