@zixt/host 0.0.82 → 0.0.84
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 +96 -22
- 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.84",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -16805,6 +16805,7 @@ var ListTasksResponse = external_exports.object({
|
|
|
16805
16805
|
// ../../packages/contracts/src/protocol.ts
|
|
16806
16806
|
var PROTOCOL_VERSION = 8;
|
|
16807
16807
|
var BROWSER_PROFILE_INVENTORY_PAGE_SIZE = 200;
|
|
16808
|
+
var HELLO_UNWOUND_ASSIGNMENT_LIMIT = 1e3;
|
|
16808
16809
|
var TASK_CANCEL_ACK_EVENT = "zixt.task.cancel.acknowledged";
|
|
16809
16810
|
var TASK_CREDENTIAL_ROLLOVER_ACK_EVENT = "zixt.task.credential_rollover.acknowledged";
|
|
16810
16811
|
var UnwoundAssignmentRef = external_exports.object({
|
|
@@ -18051,7 +18052,7 @@ var HelloFrame = external_exports.object({
|
|
|
18051
18052
|
* prior socket died. Optional for rolling v5 hosts; repeated references are
|
|
18052
18053
|
* idempotent and remain presence/host/org/epoch fenced by the cloud.
|
|
18053
18054
|
*/
|
|
18054
|
-
unwoundAssignments: external_exports.array(UnwoundAssignmentRef).max(
|
|
18055
|
+
unwoundAssignments: external_exports.array(UnwoundAssignmentRef).max(HELLO_UNWOUND_ASSIGNMENT_LIMIT).optional()
|
|
18055
18056
|
});
|
|
18056
18057
|
var BrowserProfileInventoryFrame = external_exports.object({
|
|
18057
18058
|
type: external_exports.literal("browser.profile.inventory"),
|
|
@@ -18176,6 +18177,8 @@ var CLOSE_CODES = {
|
|
|
18176
18177
|
replacedByNewerConnection: 4003,
|
|
18177
18178
|
revoked: 4004
|
|
18178
18179
|
};
|
|
18180
|
+
var UNSUPPORTED_PROTOCOL_CLOSE_REASON = "unsupported protocol version";
|
|
18181
|
+
var CLOSE_REASON_MAX_BYTES = 123;
|
|
18179
18182
|
|
|
18180
18183
|
// ../../packages/contracts/src/manager.ts
|
|
18181
18184
|
var MANAGER_DEFAULT_MODEL = "gpt-5.6-luna";
|
|
@@ -21315,6 +21318,17 @@ function operationGrantRetryCause(code) {
|
|
|
21315
21318
|
}
|
|
21316
21319
|
return "GitHub is temporarily unavailable for credential issuance";
|
|
21317
21320
|
}
|
|
21321
|
+
function closeDetail(reason) {
|
|
21322
|
+
if (reason === void 0) return void 0;
|
|
21323
|
+
const raw = typeof reason === "string" ? reason : reason.toString("utf8");
|
|
21324
|
+
let printable = "";
|
|
21325
|
+
for (const character of raw) {
|
|
21326
|
+
const code = character.codePointAt(0) ?? 0;
|
|
21327
|
+
printable += code < 32 || code === 127 ? " " : character;
|
|
21328
|
+
}
|
|
21329
|
+
const text = printable.trim().slice(0, CLOSE_REASON_MAX_BYTES);
|
|
21330
|
+
return text.length > 0 ? text : void 0;
|
|
21331
|
+
}
|
|
21318
21332
|
var HostClient = class _HostClient {
|
|
21319
21333
|
constructor(opts) {
|
|
21320
21334
|
this.opts = opts;
|
|
@@ -21687,9 +21701,13 @@ var HostClient = class _HostClient {
|
|
|
21687
21701
|
const inventoryConfigured = Boolean(
|
|
21688
21702
|
this.opts.browser?.profileInventoryPages || this.opts.browser?.profileInventory
|
|
21689
21703
|
);
|
|
21690
|
-
const
|
|
21704
|
+
const disclaimable = [...this.pendingUnwoundAssignments.values()].sort(
|
|
21691
21705
|
(left, right) => left.taskId === right.taskId ? left.epoch - right.epoch : left.taskId.localeCompare(right.taskId)
|
|
21692
21706
|
);
|
|
21707
|
+
const unwoundAssignments = disclaimable.slice(0, HELLO_UNWOUND_ASSIGNMENT_LIMIT);
|
|
21708
|
+
if (disclaimable.length > unwoundAssignments.length) {
|
|
21709
|
+
this.opts.onDisclaimerBacklog?.(disclaimable.length, unwoundAssignments.length);
|
|
21710
|
+
}
|
|
21693
21711
|
this.send(
|
|
21694
21712
|
{
|
|
21695
21713
|
type: "hello",
|
|
@@ -21721,14 +21739,14 @@ var HostClient = class _HostClient {
|
|
|
21721
21739
|
if (this.ws === ws) ws.terminate();
|
|
21722
21740
|
});
|
|
21723
21741
|
});
|
|
21724
|
-
ws.on("close", (code) => {
|
|
21742
|
+
ws.on("close", (code, reason) => {
|
|
21725
21743
|
if (inventoryRetryTimer) clearTimeout(inventoryRetryTimer);
|
|
21726
|
-
void this.handleClose(ws, code, closeReason, frameTail);
|
|
21744
|
+
void this.handleClose(ws, code, closeReason, frameTail, closeDetail(reason));
|
|
21727
21745
|
});
|
|
21728
21746
|
ws.on("error", () => {
|
|
21729
21747
|
});
|
|
21730
21748
|
}
|
|
21731
|
-
async handleClose(ws, code, closeReason, frameTail = Promise.resolve()) {
|
|
21749
|
+
async handleClose(ws, code, closeReason, frameTail = Promise.resolve(), detail) {
|
|
21732
21750
|
if (this.ws !== ws) return;
|
|
21733
21751
|
this.ws = void 0;
|
|
21734
21752
|
this.protocolReady = false;
|
|
@@ -21767,13 +21785,18 @@ var HostClient = class _HostClient {
|
|
|
21767
21785
|
await this.unwindAllRuns("host connection was replaced by a newer client", "client_shutdown");
|
|
21768
21786
|
return;
|
|
21769
21787
|
}
|
|
21770
|
-
|
|
21771
|
-
|
|
21788
|
+
const versionMismatch = code === CLOSE_CODES.protocolError && detail === UNSUPPORTED_PROTOCOL_CLOSE_REASON;
|
|
21789
|
+
if (versionMismatch) {
|
|
21790
|
+
this.opts.onStatus?.("incompatible", detail);
|
|
21772
21791
|
this.stopped = true;
|
|
21773
21792
|
await this.unwindAllRuns("host protocol is incompatible", "client_shutdown");
|
|
21774
21793
|
return;
|
|
21775
21794
|
}
|
|
21776
|
-
|
|
21795
|
+
if (code === CLOSE_CODES.protocolError) {
|
|
21796
|
+
this.opts.onStatus?.("rejected", detail);
|
|
21797
|
+
} else {
|
|
21798
|
+
this.opts.onStatus?.(closeReason === "heartbeat_timeout" ? "unresponsive" : "disconnected");
|
|
21799
|
+
}
|
|
21777
21800
|
if (this.stopped) return;
|
|
21778
21801
|
await this.unwindAllRuns(
|
|
21779
21802
|
closeReason === "heartbeat_timeout" ? "Zixt Cloud stopped answering heartbeat probes" : "host connection was lost",
|
|
@@ -25446,6 +25469,9 @@ var DO_NOT_RESTART_EXIT_CODE = 64;
|
|
|
25446
25469
|
var RESTART_BACKOFF_MS = 2e3;
|
|
25447
25470
|
var MAX_RESTART_BACKOFF_MS = 6e4;
|
|
25448
25471
|
var CRASH_STREAK_RESET_MS = 6e4;
|
|
25472
|
+
function streakBackoffMs(streak) {
|
|
25473
|
+
return Math.min(MAX_RESTART_BACKOFF_MS, RESTART_BACKOFF_MS * 2 ** Math.min(streak - 1, 10));
|
|
25474
|
+
}
|
|
25449
25475
|
var RELEASE_PROBATION_MS = 5 * 6e4;
|
|
25450
25476
|
var FAST_UPDATE_EXIT_MS = 1e4;
|
|
25451
25477
|
var STOP_GRACE_MS = 3e4;
|
|
@@ -25496,6 +25522,23 @@ function versionsRoot() {
|
|
|
25496
25522
|
function npmCommand(platform = process.platform) {
|
|
25497
25523
|
return platform === "win32" ? "npm.cmd" : "npm";
|
|
25498
25524
|
}
|
|
25525
|
+
async function resolveInstallerCommand(options = {}) {
|
|
25526
|
+
const platform = options.platform ?? process.platform;
|
|
25527
|
+
const command = npmCommand(platform);
|
|
25528
|
+
if (platform !== "win32") return command;
|
|
25529
|
+
const execPath = options.execPath ?? process.execPath;
|
|
25530
|
+
const resolution = {
|
|
25531
|
+
platform,
|
|
25532
|
+
...options.searchPath !== void 0 ? { searchPath: options.searchPath } : {}
|
|
25533
|
+
};
|
|
25534
|
+
return (
|
|
25535
|
+
// npm ships beside the `node` running this process, and that copy is the
|
|
25536
|
+
// one matching it. A per-user Scheduled Task may carry no npm on PATH.
|
|
25537
|
+
await resolveTrustedCliCommand(join8(dirname4(execPath), command), resolution) ?? await resolveTrustedCliCommand(command, resolution) ?? // Nothing resolved: keep the previous behaviour, so a Machine without npm
|
|
25538
|
+
// fails one install rather than changing how failure is handled.
|
|
25539
|
+
command
|
|
25540
|
+
);
|
|
25541
|
+
}
|
|
25499
25542
|
function windowsInstallerCommandLine(command, args) {
|
|
25500
25543
|
return [command, ...args].map(quoteForCmd).join(" ");
|
|
25501
25544
|
}
|
|
@@ -25788,12 +25831,12 @@ var InstallerContainmentError = class extends Error {
|
|
|
25788
25831
|
async function installRelease(version2, options = {}) {
|
|
25789
25832
|
if (!VERSION_DIR.test(version2)) return null;
|
|
25790
25833
|
const platform = options.platform ?? process.platform;
|
|
25791
|
-
const installerCommand = options.installerCommand ?? npmCommand(platform);
|
|
25792
25834
|
const root = options.root ?? versionsRoot();
|
|
25793
25835
|
const prefix = join8(root, version2);
|
|
25794
25836
|
const entry = installedReleaseEntry(version2, root);
|
|
25795
25837
|
if (await validReleaseAtPrefix(prefix, version2)) return entry;
|
|
25796
25838
|
if (options.signal?.aborted) return null;
|
|
25839
|
+
const installerCommand = options.installerCommand ?? await resolveInstallerCommand({ platform });
|
|
25797
25840
|
await mkdir5(root, { recursive: true, mode: 448 });
|
|
25798
25841
|
const staging = join8(root, `.install-${version2}-${process.pid}-${crypto.randomUUID()}`);
|
|
25799
25842
|
const quarantine = join8(root, `.invalid-${version2}-${process.pid}-${crypto.randomUUID()}`);
|
|
@@ -26602,6 +26645,7 @@ async function superviseHost(options = {}) {
|
|
|
26602
26645
|
announceShutdown = resolve18;
|
|
26603
26646
|
});
|
|
26604
26647
|
const attempted = /* @__PURE__ */ new Set();
|
|
26648
|
+
let unsatisfiableUpdates = 0;
|
|
26605
26649
|
const waitOrShutdown = async (ms) => {
|
|
26606
26650
|
if (shuttingDown2) return false;
|
|
26607
26651
|
if (!customDelay) {
|
|
@@ -26622,11 +26666,7 @@ async function superviseHost(options = {}) {
|
|
|
26622
26666
|
const waitAfterCrash = async (runtimeMs) => {
|
|
26623
26667
|
if (runtimeMs >= CRASH_STREAK_RESET_MS) consecutiveCrashes = 0;
|
|
26624
26668
|
consecutiveCrashes++;
|
|
26625
|
-
|
|
26626
|
-
MAX_RESTART_BACKOFF_MS,
|
|
26627
|
-
RESTART_BACKOFF_MS * 2 ** Math.min(consecutiveCrashes - 1, 10)
|
|
26628
|
-
);
|
|
26629
|
-
return waitOrShutdown(backoff);
|
|
26669
|
+
return waitOrShutdown(streakBackoffMs(consecutiveCrashes));
|
|
26630
26670
|
};
|
|
26631
26671
|
const cleanupExitedWorker = async (exitedChild, childExited, workerBoundary, containment) => {
|
|
26632
26672
|
for (let attempt = 1; attempt <= CLEANUP_ATTEMPTS2; attempt++) {
|
|
@@ -26989,10 +27029,15 @@ async function superviseHost(options = {}) {
|
|
|
26989
27029
|
consecutiveCrashes = 0;
|
|
26990
27030
|
if (orderlyValidatedBoundary) rollbackCandidate = null;
|
|
26991
27031
|
const target = await published();
|
|
27032
|
+
let updateLanded = false;
|
|
26992
27033
|
if (target === null) {
|
|
26993
27034
|
log2(
|
|
26994
27035
|
"Zixt Host: a newer release was reported but the registry is unreachable; staying on the current version"
|
|
26995
27036
|
);
|
|
27037
|
+
} else if (target === command.version) {
|
|
27038
|
+
log2(
|
|
27039
|
+
`Zixt Host: this Machine already runs the newest published release (${target}), so an update cannot satisfy the cloud; waiting for a newer one`
|
|
27040
|
+
);
|
|
26996
27041
|
} else if (attempted.has(target)) {
|
|
26997
27042
|
log2(`Zixt Host: already running ${target}; ignoring a repeated update request`);
|
|
26998
27043
|
} else {
|
|
@@ -27066,6 +27111,7 @@ async function superviseHost(options = {}) {
|
|
|
27066
27111
|
}
|
|
27067
27112
|
rollbackCandidate = { failedVersion: target, command: fallback };
|
|
27068
27113
|
command = { entry, version: target };
|
|
27114
|
+
updateLanded = true;
|
|
27069
27115
|
if (reloadAfterActivation) return SUPERVISOR_RELOAD_EXIT_CODE;
|
|
27070
27116
|
if (releaseStore) {
|
|
27071
27117
|
const probation = durableState("probation", target, fallback.version);
|
|
@@ -27093,7 +27139,10 @@ async function superviseHost(options = {}) {
|
|
|
27093
27139
|
log2(`Zixt Host: could not install ${target}; staying on the current version`);
|
|
27094
27140
|
}
|
|
27095
27141
|
}
|
|
27096
|
-
|
|
27142
|
+
unsatisfiableUpdates = updateLanded ? 0 : unsatisfiableUpdates + 1;
|
|
27143
|
+
if (unsatisfiableUpdates > 0) {
|
|
27144
|
+
if (!await waitOrShutdown(streakBackoffMs(unsatisfiableUpdates))) return 0;
|
|
27145
|
+
} else if (now() - startedAt < FAST_UPDATE_EXIT_MS && !await waitOrShutdown(RESTART_BACKOFF_MS)) {
|
|
27097
27146
|
return 0;
|
|
27098
27147
|
}
|
|
27099
27148
|
if (shuttingDown2) return 0;
|
|
@@ -40385,16 +40434,26 @@ var colorOverride = forcedColor(cliOptions.color) ?? (process.env[HOST_CONSOLE_C
|
|
|
40385
40434
|
var hostConsoleTail = [];
|
|
40386
40435
|
var hostConsoleSequence = 0;
|
|
40387
40436
|
var clientForConsole = {};
|
|
40437
|
+
function recordConsoleLine(line) {
|
|
40438
|
+
const entry = { sequence: ++hostConsoleSequence, line };
|
|
40439
|
+
hostConsoleTail.push(entry);
|
|
40440
|
+
if (hostConsoleTail.length > 200) hostConsoleTail.shift();
|
|
40441
|
+
clientForConsole.current?.hostConsoleLine(entry);
|
|
40442
|
+
}
|
|
40388
40443
|
var log = createHostLogger({
|
|
40389
40444
|
...colorOverride === void 0 ? {} : { color: colorOverride },
|
|
40390
40445
|
write: (line) => {
|
|
40391
40446
|
console.error(line);
|
|
40392
|
-
|
|
40393
|
-
hostConsoleTail.push(entry);
|
|
40394
|
-
if (hostConsoleTail.length > 200) hostConsoleTail.shift();
|
|
40395
|
-
clientForConsole.current?.hostConsoleLine(entry);
|
|
40447
|
+
recordConsoleLine(line);
|
|
40396
40448
|
}
|
|
40397
40449
|
});
|
|
40450
|
+
function replayConsoleLine(level, message, context) {
|
|
40451
|
+
recordConsoleLine(
|
|
40452
|
+
formatHostLogLine(level, message, context, {
|
|
40453
|
+
...colorOverride === void 0 ? {} : { color: colorOverride }
|
|
40454
|
+
})
|
|
40455
|
+
);
|
|
40456
|
+
}
|
|
40398
40457
|
if (cliOptions.help) {
|
|
40399
40458
|
process.stdout.write(`${hostHelpText()}
|
|
40400
40459
|
`);
|
|
@@ -40779,6 +40838,14 @@ var client = new HostClient({
|
|
|
40779
40838
|
forgetAcknowledgedAcceptedAssignments(assignments, acceptedAssignmentRoot)
|
|
40780
40839
|
]);
|
|
40781
40840
|
},
|
|
40841
|
+
onDisclaimerBacklog: (pending, reported) => {
|
|
40842
|
+
log.warn("More unfinished Task claims than one connection can report", {
|
|
40843
|
+
machine,
|
|
40844
|
+
pending,
|
|
40845
|
+
reported,
|
|
40846
|
+
next: "The rest are reported as this Machine reconnects; report this if it does not clear"
|
|
40847
|
+
});
|
|
40848
|
+
},
|
|
40782
40849
|
persistAcceptedAssignment: (assignment) => recordAcceptedAssignment(assignment, acceptedAssignmentRoot).then(() => void 0),
|
|
40783
40850
|
forgetAcceptedAssignment: (assignment) => forgetAcceptedAssignment(assignment, acceptedAssignmentRoot),
|
|
40784
40851
|
persistTerminalOutcome: (hostId, outcome) => recordTerminalOutcome(hostId, outcome, terminalOutcomeRoot),
|
|
@@ -40810,7 +40877,7 @@ var client = new HostClient({
|
|
|
40810
40877
|
onUsableTelemetryReport: () => {
|
|
40811
40878
|
reportWorkerReadiness();
|
|
40812
40879
|
},
|
|
40813
|
-
onStatus: (status) => {
|
|
40880
|
+
onStatus: (status, detail) => {
|
|
40814
40881
|
if (status === lastReportedStatus) return;
|
|
40815
40882
|
lastReportedStatus = status;
|
|
40816
40883
|
switch (status) {
|
|
@@ -40850,6 +40917,13 @@ var client = new HostClient({
|
|
|
40850
40917
|
});
|
|
40851
40918
|
queueMicrotask(() => shutdown(packagedBuild ? UPDATE_EXIT_CODE : DO_NOT_RESTART_EXIT_CODE));
|
|
40852
40919
|
break;
|
|
40920
|
+
case "rejected":
|
|
40921
|
+
log.error("Zixt Cloud refused this Machine", {
|
|
40922
|
+
...connectionContext,
|
|
40923
|
+
reason: detail ?? "the cloud gave no reason",
|
|
40924
|
+
next: "Zixt keeps retrying; report this reason if the Machine stays offline, because no update changes it"
|
|
40925
|
+
});
|
|
40926
|
+
break;
|
|
40853
40927
|
}
|
|
40854
40928
|
},
|
|
40855
40929
|
executor,
|
|
@@ -40867,7 +40941,7 @@ for (const { record: record2 } of reportedWorkerExits) {
|
|
|
40867
40941
|
...context,
|
|
40868
40942
|
next: "This Machine restarted itself; report it if the same exit repeats"
|
|
40869
40943
|
});
|
|
40870
|
-
for (const line of record2.stderr)
|
|
40944
|
+
for (const line of record2.stderr) replayConsoleLine("error", "Previous worker output", { line });
|
|
40871
40945
|
}
|
|
40872
40946
|
log.info("Starting Zixt Host", connectionContext);
|
|
40873
40947
|
client.start();
|