@zixt/host 0.0.84 → 0.0.86
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/index.js +118 -72
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { homedir as homedir3 } from "node:os";
|
|
|
31
31
|
// package.json
|
|
32
32
|
var package_default = {
|
|
33
33
|
name: "@zixt/host",
|
|
34
|
-
version: "0.0.
|
|
34
|
+
version: "0.0.86",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -25828,14 +25828,26 @@ setTimeout(() => { if (!launched) fail(); }, 130000).unref();
|
|
|
25828
25828
|
var InstallerContainmentError = class extends Error {
|
|
25829
25829
|
name = "InstallerContainmentError";
|
|
25830
25830
|
};
|
|
25831
|
+
function describeInstallerExit(code, signal) {
|
|
25832
|
+
if (signal !== null) return `was killed by ${signal}`;
|
|
25833
|
+
if (code === null) return "ended without reporting an exit code";
|
|
25834
|
+
return `exited with code ${code}`;
|
|
25835
|
+
}
|
|
25831
25836
|
async function installRelease(version2, options = {}) {
|
|
25832
|
-
|
|
25837
|
+
const fail = (reason, detail) => {
|
|
25838
|
+
options.onFailure?.({ version: version2, reason, detail });
|
|
25839
|
+
return null;
|
|
25840
|
+
};
|
|
25841
|
+
if (!VERSION_DIR.test(version2)) {
|
|
25842
|
+
return fail("unsupported_version", "that is not a release name this Host can install");
|
|
25843
|
+
}
|
|
25833
25844
|
const platform = options.platform ?? process.platform;
|
|
25834
25845
|
const root = options.root ?? versionsRoot();
|
|
25835
25846
|
const prefix = join8(root, version2);
|
|
25836
25847
|
const entry = installedReleaseEntry(version2, root);
|
|
25837
25848
|
if (await validReleaseAtPrefix(prefix, version2)) return entry;
|
|
25838
|
-
if (options.signal?.aborted)
|
|
25849
|
+
if (options.signal?.aborted)
|
|
25850
|
+
return fail("cancelled", "this Host was stopping before npm started");
|
|
25839
25851
|
const installerCommand = options.installerCommand ?? await resolveInstallerCommand({ platform });
|
|
25840
25852
|
await mkdir5(root, { recursive: true, mode: 448 });
|
|
25841
25853
|
const staging = join8(root, `.install-${version2}-${process.pid}-${crypto.randomUUID()}`);
|
|
@@ -25870,9 +25882,12 @@ async function installRelease(version2, options = {}) {
|
|
|
25870
25882
|
let child;
|
|
25871
25883
|
try {
|
|
25872
25884
|
child = spawnInstaller(staging, version2);
|
|
25873
|
-
} catch {
|
|
25885
|
+
} catch (error52) {
|
|
25874
25886
|
await rm5(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
25875
|
-
return
|
|
25887
|
+
return fail(
|
|
25888
|
+
"installer_unavailable",
|
|
25889
|
+
`${installerCommand} could not be started (${error52 instanceof Error ? error52.message : "unknown error"})`
|
|
25890
|
+
);
|
|
25876
25891
|
}
|
|
25877
25892
|
let resolveChildExited;
|
|
25878
25893
|
const childExited = new Promise((resolveExit) => {
|
|
@@ -25894,6 +25909,8 @@ async function installRelease(version2, options = {}) {
|
|
|
25894
25909
|
installerContainmentSetupError = error52;
|
|
25895
25910
|
return null;
|
|
25896
25911
|
}) : Promise.resolve(null);
|
|
25912
|
+
const timeoutMs = options.timeoutMs ?? INSTALL_TIMEOUT_MS;
|
|
25913
|
+
const outcome = { code: null, signal: null, timedOut: false, spawnError: null };
|
|
25897
25914
|
const installed = await new Promise((resolve18, reject3) => {
|
|
25898
25915
|
let finished = false;
|
|
25899
25916
|
let cleanupStarted = false;
|
|
@@ -25948,13 +25965,21 @@ async function installRelease(version2, options = {}) {
|
|
|
25948
25965
|
}
|
|
25949
25966
|
})();
|
|
25950
25967
|
};
|
|
25951
|
-
const timer = setTimeout(
|
|
25968
|
+
const timer = setTimeout(() => {
|
|
25969
|
+
outcome.timedOut = true;
|
|
25970
|
+
requestCleanup();
|
|
25971
|
+
}, timeoutMs);
|
|
25952
25972
|
timer.unref?.();
|
|
25953
|
-
child.once("error", () => {
|
|
25973
|
+
child.once("error", (error52) => {
|
|
25974
|
+
outcome.spawnError = error52.message;
|
|
25954
25975
|
observeExit();
|
|
25955
25976
|
requestCleanup();
|
|
25956
25977
|
});
|
|
25957
|
-
child.once("exit", (code) => {
|
|
25978
|
+
child.once("exit", (code, signal) => {
|
|
25979
|
+
if (!usesWindowsInstallerGuardian) {
|
|
25980
|
+
outcome.code = code;
|
|
25981
|
+
outcome.signal = signal;
|
|
25982
|
+
}
|
|
25958
25983
|
observeExit();
|
|
25959
25984
|
if (usesWindowsInstallerGuardian) {
|
|
25960
25985
|
requestCleanup();
|
|
@@ -25974,6 +25999,9 @@ async function installRelease(version2, options = {}) {
|
|
|
25974
25999
|
}
|
|
25975
26000
|
const code = message.code;
|
|
25976
26001
|
if (code !== null && (typeof code !== "number" || !Number.isInteger(code))) return;
|
|
26002
|
+
outcome.code = code;
|
|
26003
|
+
const signal = message.signal;
|
|
26004
|
+
outcome.signal = typeof signal === "string" ? signal : null;
|
|
25977
26005
|
successfulCleanupResult = code === 0;
|
|
25978
26006
|
requestCleanup();
|
|
25979
26007
|
});
|
|
@@ -26004,8 +26032,32 @@ async function installRelease(version2, options = {}) {
|
|
|
26004
26032
|
if (options.signal?.aborted) requestCleanup();
|
|
26005
26033
|
});
|
|
26006
26034
|
try {
|
|
26007
|
-
if (options.signal?.aborted
|
|
26008
|
-
return
|
|
26035
|
+
if (options.signal?.aborted) {
|
|
26036
|
+
return fail("cancelled", "this Host was stopping before the install finished");
|
|
26037
|
+
}
|
|
26038
|
+
if (!installed) {
|
|
26039
|
+
if (outcome.timedOut) {
|
|
26040
|
+
return fail(
|
|
26041
|
+
"installer_timed_out",
|
|
26042
|
+
`${installerCommand} was still running after ${Math.round(timeoutMs / 1e3)}s and was stopped`
|
|
26043
|
+
);
|
|
26044
|
+
}
|
|
26045
|
+
if (outcome.spawnError !== null) {
|
|
26046
|
+
return fail(
|
|
26047
|
+
"installer_unavailable",
|
|
26048
|
+
`${installerCommand} failed to run (${outcome.spawnError})`
|
|
26049
|
+
);
|
|
26050
|
+
}
|
|
26051
|
+
return fail(
|
|
26052
|
+
"installer_failed",
|
|
26053
|
+
`${installerCommand} install ${PACKAGE_NAME}@${version2} ${describeInstallerExit(outcome.code, outcome.signal)}`
|
|
26054
|
+
);
|
|
26055
|
+
}
|
|
26056
|
+
if (!await validReleaseAtPrefix(staging, version2)) {
|
|
26057
|
+
return fail(
|
|
26058
|
+
"incomplete_release",
|
|
26059
|
+
`${installerCommand} reported success but left no runnable ${PACKAGE_NAME}@${version2} in ${staging}`
|
|
26060
|
+
);
|
|
26009
26061
|
}
|
|
26010
26062
|
if (await validReleaseAtPrefix(prefix, version2)) return entry;
|
|
26011
26063
|
const existing = await lstat5(prefix).catch((error52) => {
|
|
@@ -26015,11 +26067,18 @@ async function installRelease(version2, options = {}) {
|
|
|
26015
26067
|
if (existing) await rename3(prefix, quarantine);
|
|
26016
26068
|
try {
|
|
26017
26069
|
await rename3(staging, prefix);
|
|
26018
|
-
} catch {
|
|
26019
|
-
|
|
26070
|
+
} catch (error52) {
|
|
26071
|
+
if (await validReleaseAtPrefix(prefix, version2)) return entry;
|
|
26072
|
+
return fail(
|
|
26073
|
+
"commit_failed",
|
|
26074
|
+
`the validated tree could not be moved into ${prefix} (${error52 instanceof Error ? error52.message : "unknown error"})`
|
|
26075
|
+
);
|
|
26020
26076
|
}
|
|
26021
26077
|
await syncDirectory3(root);
|
|
26022
|
-
return await validReleaseAtPrefix(prefix, version2) ? entry :
|
|
26078
|
+
return await validReleaseAtPrefix(prefix, version2) ? entry : fail(
|
|
26079
|
+
"commit_failed",
|
|
26080
|
+
`${prefix} is not a runnable ${PACKAGE_NAME}@${version2} after installing`
|
|
26081
|
+
);
|
|
26023
26082
|
} finally {
|
|
26024
26083
|
await rm5(staging, { recursive: true, force: true }).catch(() => void 0);
|
|
26025
26084
|
await rm5(quarantine, { recursive: true, force: true }).catch(() => void 0);
|
|
@@ -26601,7 +26660,10 @@ async function superviseHost(options = {}) {
|
|
|
26601
26660
|
platform,
|
|
26602
26661
|
workerDiagnosticsRoot
|
|
26603
26662
|
));
|
|
26604
|
-
const install = options.installVersion ?? ((version2, signal) => installRelease(version2,
|
|
26663
|
+
const install = options.installVersion ?? ((version2, signal, onFailure) => installRelease(version2, {
|
|
26664
|
+
...signal ? { signal } : {},
|
|
26665
|
+
...onFailure ? { onFailure } : {}
|
|
26666
|
+
}));
|
|
26605
26667
|
const cleanupWorker = options.cleanupWorker ?? (options.spawnWorker ? async () => {
|
|
26606
26668
|
} : null);
|
|
26607
26669
|
const createWorkerContainment = options.createWorkerContainment ?? (platform === "win32" && !options.spawnWorker ? async (target, identityNonce, signal) => {
|
|
@@ -27023,6 +27085,9 @@ async function superviseHost(options = {}) {
|
|
|
27023
27085
|
if (!await waitAfterCrash(runtimeMs)) return 0;
|
|
27024
27086
|
continue;
|
|
27025
27087
|
}
|
|
27088
|
+
log2(
|
|
27089
|
+
`Zixt Host: worker on ${command.version ?? "the launched copy"} asked to update (exit ${effectiveCode}${watchdogTriggered ? `, announced ${announcedExitCode} before its teardown was contained` : ""}); checking the published release`
|
|
27090
|
+
);
|
|
27026
27091
|
if (watchdogTriggered) {
|
|
27027
27092
|
await reportWorkerExit(workerExit, "installing the update it asked for anyway");
|
|
27028
27093
|
}
|
|
@@ -27030,6 +27095,7 @@ async function superviseHost(options = {}) {
|
|
|
27030
27095
|
if (orderlyValidatedBoundary) rollbackCandidate = null;
|
|
27031
27096
|
const target = await published();
|
|
27032
27097
|
let updateLanded = false;
|
|
27098
|
+
let rejectedUpdate = null;
|
|
27033
27099
|
if (target === null) {
|
|
27034
27100
|
log2(
|
|
27035
27101
|
"Zixt Host: a newer release was reported but the registry is unreachable; staying on the current version"
|
|
@@ -27042,13 +27108,22 @@ async function superviseHost(options = {}) {
|
|
|
27042
27108
|
log2(`Zixt Host: already running ${target}; ignoring a repeated update request`);
|
|
27043
27109
|
} else {
|
|
27044
27110
|
let entry;
|
|
27111
|
+
const attempt = { failure: null };
|
|
27112
|
+
log2(`Zixt Host: installing ${target} over ${command.version ?? "the launched copy"}`);
|
|
27045
27113
|
try {
|
|
27046
|
-
entry = await install(target, shutdownController.signal)
|
|
27114
|
+
entry = await install(target, shutdownController.signal, (failure2) => {
|
|
27115
|
+
attempt.failure = failure2;
|
|
27116
|
+
});
|
|
27047
27117
|
} catch (error52) {
|
|
27048
27118
|
if (error52 instanceof InstallerContainmentError) {
|
|
27049
27119
|
log2(`Zixt Host: ${error52.message}; handing recovery to the stable launcher`);
|
|
27050
27120
|
return 1;
|
|
27051
27121
|
}
|
|
27122
|
+
attempt.failure = {
|
|
27123
|
+
version: target,
|
|
27124
|
+
reason: "commit_failed",
|
|
27125
|
+
detail: error52 instanceof Error ? error52.message : "unknown error"
|
|
27126
|
+
};
|
|
27052
27127
|
entry = null;
|
|
27053
27128
|
}
|
|
27054
27129
|
if (shuttingDown2) return 0;
|
|
@@ -27136,9 +27211,14 @@ async function superviseHost(options = {}) {
|
|
|
27136
27211
|
}
|
|
27137
27212
|
}
|
|
27138
27213
|
} else {
|
|
27139
|
-
|
|
27214
|
+
const failure2 = attempt.failure;
|
|
27215
|
+
log2(
|
|
27216
|
+
`Zixt Host: could not install ${target} (${failure2 ? `${failure2.reason}: ${failure2.detail}` : "no reason reported"}); staying on ${command.version ?? "the launched copy"}`
|
|
27217
|
+
);
|
|
27218
|
+
if (failure2?.reason !== "cancelled") rejectedUpdate = target;
|
|
27140
27219
|
}
|
|
27141
27220
|
}
|
|
27221
|
+
if (rejectedUpdate) command = { ...command, rejectedVersion: rejectedUpdate };
|
|
27142
27222
|
unsatisfiableUpdates = updateLanded ? 0 : unsatisfiableUpdates + 1;
|
|
27143
27223
|
if (unsatisfiableUpdates > 0) {
|
|
27144
27224
|
if (!await waitOrShutdown(streakBackoffMs(unsatisfiableUpdates))) return 0;
|
|
@@ -28465,10 +28545,11 @@ var BLOCKED_STATEMENT = /\b(?:you (?:must|need to) (?:be )?(?:sign|log)(?:ged)?
|
|
|
28465
28545
|
function authenticationWallGuidance(origin) {
|
|
28466
28546
|
return [
|
|
28467
28547
|
`This page is asking someone to sign in to ${origin}.`,
|
|
28468
|
-
"
|
|
28548
|
+
"If a saved website-login Credential covers this site, call browser_login with its name.",
|
|
28469
28549
|
"Otherwise stop here and use ask_user to ask the person to sign in at the Browser panel, naming the Browser in the question so their panel opens.",
|
|
28550
|
+
"That is the route to ask for, because a saved login is filled by Host code, is never shown to you, and is scrubbed from anything you write.",
|
|
28470
28551
|
"This browser and its profile outlive the run, so a person can sign in after your session checkpoints and you continue on the authenticated page.",
|
|
28471
|
-
"
|
|
28552
|
+
"A one-time code expires and a person is faster at their own password prompt, so do not ask for either instead of the handoff; if they choose to send you a credential anyway, use it without repeating it.",
|
|
28472
28553
|
"If this Task cannot be verified without being signed in, ask now rather than reporting that limitation once you have already declared the work verified."
|
|
28473
28554
|
].join(" ");
|
|
28474
28555
|
}
|
|
@@ -34256,53 +34337,6 @@ function renderAttachmentSection(files) {
|
|
|
34256
34337
|
|
|
34257
34338
|
// src/runners/ask-user-server.ts
|
|
34258
34339
|
import { createServer as createServer2 } from "node:http";
|
|
34259
|
-
|
|
34260
|
-
// src/runners/ask-user-secrets.ts
|
|
34261
|
-
var SECRET_NOUN_SOURCE = "(?:passwords?|passphrases?|api[ -]?keys?|access tokens?|auth tokens?|api tokens?|bearer tokens?|refresh tokens?|tokens?|secret keys?|client secrets?|private keys?|one[- ]time (?:code|password)s?|otps?|2fa codes?|mfa codes?|verification codes?|security codes?|session cookies?)";
|
|
34262
|
-
var SECRET_NOUN = new RegExp(String.raw`\b${SECRET_NOUN_SOURCE}\b`, "i");
|
|
34263
|
-
var SECRET_ENV_NAME = /\b[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PAT)\b/;
|
|
34264
|
-
function namesSecret(sentence) {
|
|
34265
|
-
return SECRET_NOUN.test(sentence) || SECRET_ENV_NAME.test(sentence);
|
|
34266
|
-
}
|
|
34267
|
-
var TRANSFER = "(?:paste|send|share|provide|supply|give|reply|respond|forward|drop|tell)";
|
|
34268
|
-
var REQUEST_PATTERNS = [
|
|
34269
|
-
new RegExp(String.raw`^\s*(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
34270
|
-
new RegExp(String.raw`\b(?:can|could|would|will)\s+you\s+(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
34271
|
-
new RegExp(
|
|
34272
|
-
String.raw`\b${TRANSFER}\b[^.?!]{0,40}\b(?:me|here|in chat|in the chat|in your (?:reply|answer|message)|below)\b`,
|
|
34273
|
-
"i"
|
|
34274
|
-
),
|
|
34275
|
-
new RegExp(String.raw`\b${TRANSFER}\b[^.?!]{0,20}\byour\b`, "i"),
|
|
34276
|
-
new RegExp(
|
|
34277
|
-
String.raw`\bwhat(?:'s| is|s|\s+are)\s+(?:the|your)\s+(?:[\w-]+\s+){0,2}${SECRET_NOUN_SOURCE}\b`,
|
|
34278
|
-
"i"
|
|
34279
|
-
)
|
|
34280
|
-
];
|
|
34281
|
-
var NEGATION = /\b(?:do not|don'?t|never|no need|without|rather than|instead of|avoid)\b/i;
|
|
34282
|
-
function namesSafeDestination(sentence) {
|
|
34283
|
-
return /\bbrowser\b/i.test(sentence) || /\bcredentials?\s+(?:page|screen|tab|section|store|settings|panel|vault)\b/i.test(sentence) || /\b(?:add|adds|added|adding|store|stored|save|saved|create|created|put)\b[^.?!]{0,60}\bcredential/i.test(
|
|
34284
|
-
sentence
|
|
34285
|
-
);
|
|
34286
|
-
}
|
|
34287
|
-
var SECRET_IN_CHAT_REFUSAL = [
|
|
34288
|
-
"Not delivered: Zixt never carries a password, token, or one-time code through chat (W5).",
|
|
34289
|
-
"Ask for the capability instead of the value.",
|
|
34290
|
-
"For a website, ask the person to sign in themselves at the Browser panel, or to add a website-login Credential whose name you can pass to browser_login.",
|
|
34291
|
-
"For anything else, ask them to add it under Resources \u2192 Credentials as an UPPER_SNAKE_CASE name, which reaches your next run as an environment variable.",
|
|
34292
|
-
"Then ask again without requesting the value."
|
|
34293
|
-
].join(" ");
|
|
34294
|
-
function secretSolicitationRefusal(question, context) {
|
|
34295
|
-
const sentences = `${question}
|
|
34296
|
-
${context}`.split(/(?<=[.!?\n])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
|
|
34297
|
-
for (const sentence of sentences) {
|
|
34298
|
-
if (!namesSecret(sentence)) continue;
|
|
34299
|
-
if (NEGATION.test(sentence) || namesSafeDestination(sentence)) continue;
|
|
34300
|
-
if (REQUEST_PATTERNS.some((pattern) => pattern.test(sentence))) return SECRET_IN_CHAT_REFUSAL;
|
|
34301
|
-
}
|
|
34302
|
-
return null;
|
|
34303
|
-
}
|
|
34304
|
-
|
|
34305
|
-
// src/runners/ask-user-server.ts
|
|
34306
34340
|
var CADENCE_PROPS = {
|
|
34307
34341
|
cadence_kind: {
|
|
34308
34342
|
type: "string",
|
|
@@ -34322,7 +34356,7 @@ var CADENCE_PROPS = {
|
|
|
34322
34356
|
var TOOLS = [
|
|
34323
34357
|
{
|
|
34324
34358
|
name: "ask_user",
|
|
34325
|
-
description: "Ask the human supervising this task a question and wait for their answer. Use it whenever you need a decision, missing context, or plan approval before proceeding. When there are 2-5 concrete alternatives, provide them as choices; the person can still enter another answer. The answer arrives as text.",
|
|
34359
|
+
description: "Ask the human supervising this task a question and wait for their answer. Use it whenever you need a decision, missing context, or plan approval before proceeding. When there are 2-5 concrete alternatives, provide them as choices; the person can still enter another answer. The answer arrives as text. For a credential, ask for the capability rather than the value: a Credential added under Resources reaches your next run as an environment variable and is scrubbed from everything you write, and a website sign-in belongs at the Browser panel. If the person chooses to send you a value here anyway, use it for this task and store it with set_secret if it should persist, but never print it, write it into a file you commit, or repeat it in your report.",
|
|
34326
34360
|
inputSchema: {
|
|
34327
34361
|
type: "object",
|
|
34328
34362
|
properties: {
|
|
@@ -35020,11 +35054,6 @@ function createAskUserServer() {
|
|
|
35020
35054
|
}
|
|
35021
35055
|
try {
|
|
35022
35056
|
const context = typeof args["context"] === "string" ? args["context"] : "";
|
|
35023
|
-
const refusal = secretSolicitationRefusal(question, context);
|
|
35024
|
-
if (refusal) {
|
|
35025
|
-
toolText(refusal, true);
|
|
35026
|
-
return;
|
|
35027
|
-
}
|
|
35028
35057
|
const rawChoices = args["choices"];
|
|
35029
35058
|
const parsedChoices = rawChoices === void 0 ? void 0 : QuestionChoices.safeParse(rawChoices);
|
|
35030
35059
|
if (parsedChoices && !parsedChoices.success) {
|
|
@@ -40950,7 +40979,12 @@ function shutdown(exitCode = 0) {
|
|
|
40950
40979
|
if (shuttingDown) process.exit(exitCode);
|
|
40951
40980
|
shuttingDown = true;
|
|
40952
40981
|
retainRunAssignments();
|
|
40953
|
-
log.info("Stopping Zixt Host", {
|
|
40982
|
+
log.info("Stopping Zixt Host", {
|
|
40983
|
+
machine,
|
|
40984
|
+
activeTasks: activeSessions,
|
|
40985
|
+
exit: exitCode,
|
|
40986
|
+
reason: exitCode === UPDATE_EXIT_CODE ? "installing a Zixt Host update" : exitCode === DO_NOT_RESTART_EXIT_CODE ? "this Machine needs attention before it restarts" : "stop requested"
|
|
40987
|
+
});
|
|
40954
40988
|
beginWorkerShutdown({
|
|
40955
40989
|
activeTasks: activeSessions,
|
|
40956
40990
|
exitCode,
|
|
@@ -40963,6 +40997,9 @@ function shutdown(exitCode = 0) {
|
|
|
40963
40997
|
machine,
|
|
40964
40998
|
deadline: formatDuration(deadlineMs),
|
|
40965
40999
|
exit: code,
|
|
41000
|
+
// A stop that had to unwind live runs exits as a crash instead, so
|
|
41001
|
+
// the honoured code can differ from the verdict this stop was for.
|
|
41002
|
+
...code === exitCode ? {} : { requested: exitCode },
|
|
40966
41003
|
activeTasks: activeSessions,
|
|
40967
41004
|
next: "The Host restarts automatically; report this if it repeats"
|
|
40968
41005
|
}
|
|
@@ -40970,6 +41007,15 @@ function shutdown(exitCode = 0) {
|
|
|
40970
41007
|
}
|
|
40971
41008
|
});
|
|
40972
41009
|
}
|
|
41010
|
+
var skippedRelease = process.env.ZIXT_HOST_REJECT_VERSION;
|
|
41011
|
+
if (packagedBuild && skippedRelease) {
|
|
41012
|
+
log.warn("Skipping a Zixt Host release this Machine could not install", {
|
|
41013
|
+
machine,
|
|
41014
|
+
version: skippedRelease,
|
|
41015
|
+
running: HOST_VERSION,
|
|
41016
|
+
next: "This Machine keeps working and takes the next release; report it if it stays behind"
|
|
41017
|
+
});
|
|
41018
|
+
}
|
|
40973
41019
|
stopUpdateWatch = !packagedBuild ? () => {
|
|
40974
41020
|
} : watchForUpdates({
|
|
40975
41021
|
onUpdateAvailable: (version2) => {
|