@zixt/host 0.0.83 → 0.0.85
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 +67 -70
- 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.85",
|
|
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",
|
|
@@ -28442,10 +28465,11 @@ var BLOCKED_STATEMENT = /\b(?:you (?:must|need to) (?:be )?(?:sign|log)(?:ged)?
|
|
|
28442
28465
|
function authenticationWallGuidance(origin) {
|
|
28443
28466
|
return [
|
|
28444
28467
|
`This page is asking someone to sign in to ${origin}.`,
|
|
28445
|
-
"
|
|
28468
|
+
"If a saved website-login Credential covers this site, call browser_login with its name.",
|
|
28446
28469
|
"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.",
|
|
28470
|
+
"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.",
|
|
28447
28471
|
"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.",
|
|
28448
|
-
"
|
|
28472
|
+
"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.",
|
|
28449
28473
|
"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."
|
|
28450
28474
|
].join(" ");
|
|
28451
28475
|
}
|
|
@@ -34233,53 +34257,6 @@ function renderAttachmentSection(files) {
|
|
|
34233
34257
|
|
|
34234
34258
|
// src/runners/ask-user-server.ts
|
|
34235
34259
|
import { createServer as createServer2 } from "node:http";
|
|
34236
|
-
|
|
34237
|
-
// src/runners/ask-user-secrets.ts
|
|
34238
|
-
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?)";
|
|
34239
|
-
var SECRET_NOUN = new RegExp(String.raw`\b${SECRET_NOUN_SOURCE}\b`, "i");
|
|
34240
|
-
var SECRET_ENV_NAME = /\b[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PAT)\b/;
|
|
34241
|
-
function namesSecret(sentence) {
|
|
34242
|
-
return SECRET_NOUN.test(sentence) || SECRET_ENV_NAME.test(sentence);
|
|
34243
|
-
}
|
|
34244
|
-
var TRANSFER = "(?:paste|send|share|provide|supply|give|reply|respond|forward|drop|tell)";
|
|
34245
|
-
var REQUEST_PATTERNS = [
|
|
34246
|
-
new RegExp(String.raw`^\s*(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
34247
|
-
new RegExp(String.raw`\b(?:can|could|would|will)\s+you\s+(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
34248
|
-
new RegExp(
|
|
34249
|
-
String.raw`\b${TRANSFER}\b[^.?!]{0,40}\b(?:me|here|in chat|in the chat|in your (?:reply|answer|message)|below)\b`,
|
|
34250
|
-
"i"
|
|
34251
|
-
),
|
|
34252
|
-
new RegExp(String.raw`\b${TRANSFER}\b[^.?!]{0,20}\byour\b`, "i"),
|
|
34253
|
-
new RegExp(
|
|
34254
|
-
String.raw`\bwhat(?:'s| is|s|\s+are)\s+(?:the|your)\s+(?:[\w-]+\s+){0,2}${SECRET_NOUN_SOURCE}\b`,
|
|
34255
|
-
"i"
|
|
34256
|
-
)
|
|
34257
|
-
];
|
|
34258
|
-
var NEGATION = /\b(?:do not|don'?t|never|no need|without|rather than|instead of|avoid)\b/i;
|
|
34259
|
-
function namesSafeDestination(sentence) {
|
|
34260
|
-
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(
|
|
34261
|
-
sentence
|
|
34262
|
-
);
|
|
34263
|
-
}
|
|
34264
|
-
var SECRET_IN_CHAT_REFUSAL = [
|
|
34265
|
-
"Not delivered: Zixt never carries a password, token, or one-time code through chat (W5).",
|
|
34266
|
-
"Ask for the capability instead of the value.",
|
|
34267
|
-
"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.",
|
|
34268
|
-
"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.",
|
|
34269
|
-
"Then ask again without requesting the value."
|
|
34270
|
-
].join(" ");
|
|
34271
|
-
function secretSolicitationRefusal(question, context) {
|
|
34272
|
-
const sentences = `${question}
|
|
34273
|
-
${context}`.split(/(?<=[.!?\n])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
|
|
34274
|
-
for (const sentence of sentences) {
|
|
34275
|
-
if (!namesSecret(sentence)) continue;
|
|
34276
|
-
if (NEGATION.test(sentence) || namesSafeDestination(sentence)) continue;
|
|
34277
|
-
if (REQUEST_PATTERNS.some((pattern) => pattern.test(sentence))) return SECRET_IN_CHAT_REFUSAL;
|
|
34278
|
-
}
|
|
34279
|
-
return null;
|
|
34280
|
-
}
|
|
34281
|
-
|
|
34282
|
-
// src/runners/ask-user-server.ts
|
|
34283
34260
|
var CADENCE_PROPS = {
|
|
34284
34261
|
cadence_kind: {
|
|
34285
34262
|
type: "string",
|
|
@@ -34299,7 +34276,7 @@ var CADENCE_PROPS = {
|
|
|
34299
34276
|
var TOOLS = [
|
|
34300
34277
|
{
|
|
34301
34278
|
name: "ask_user",
|
|
34302
|
-
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.",
|
|
34279
|
+
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.",
|
|
34303
34280
|
inputSchema: {
|
|
34304
34281
|
type: "object",
|
|
34305
34282
|
properties: {
|
|
@@ -34997,11 +34974,6 @@ function createAskUserServer() {
|
|
|
34997
34974
|
}
|
|
34998
34975
|
try {
|
|
34999
34976
|
const context = typeof args["context"] === "string" ? args["context"] : "";
|
|
35000
|
-
const refusal = secretSolicitationRefusal(question, context);
|
|
35001
|
-
if (refusal) {
|
|
35002
|
-
toolText(refusal, true);
|
|
35003
|
-
return;
|
|
35004
|
-
}
|
|
35005
34977
|
const rawChoices = args["choices"];
|
|
35006
34978
|
const parsedChoices = rawChoices === void 0 ? void 0 : QuestionChoices.safeParse(rawChoices);
|
|
35007
34979
|
if (parsedChoices && !parsedChoices.success) {
|
|
@@ -40411,16 +40383,26 @@ var colorOverride = forcedColor(cliOptions.color) ?? (process.env[HOST_CONSOLE_C
|
|
|
40411
40383
|
var hostConsoleTail = [];
|
|
40412
40384
|
var hostConsoleSequence = 0;
|
|
40413
40385
|
var clientForConsole = {};
|
|
40386
|
+
function recordConsoleLine(line) {
|
|
40387
|
+
const entry = { sequence: ++hostConsoleSequence, line };
|
|
40388
|
+
hostConsoleTail.push(entry);
|
|
40389
|
+
if (hostConsoleTail.length > 200) hostConsoleTail.shift();
|
|
40390
|
+
clientForConsole.current?.hostConsoleLine(entry);
|
|
40391
|
+
}
|
|
40414
40392
|
var log = createHostLogger({
|
|
40415
40393
|
...colorOverride === void 0 ? {} : { color: colorOverride },
|
|
40416
40394
|
write: (line) => {
|
|
40417
40395
|
console.error(line);
|
|
40418
|
-
|
|
40419
|
-
hostConsoleTail.push(entry);
|
|
40420
|
-
if (hostConsoleTail.length > 200) hostConsoleTail.shift();
|
|
40421
|
-
clientForConsole.current?.hostConsoleLine(entry);
|
|
40396
|
+
recordConsoleLine(line);
|
|
40422
40397
|
}
|
|
40423
40398
|
});
|
|
40399
|
+
function replayConsoleLine(level, message, context) {
|
|
40400
|
+
recordConsoleLine(
|
|
40401
|
+
formatHostLogLine(level, message, context, {
|
|
40402
|
+
...colorOverride === void 0 ? {} : { color: colorOverride }
|
|
40403
|
+
})
|
|
40404
|
+
);
|
|
40405
|
+
}
|
|
40424
40406
|
if (cliOptions.help) {
|
|
40425
40407
|
process.stdout.write(`${hostHelpText()}
|
|
40426
40408
|
`);
|
|
@@ -40805,6 +40787,14 @@ var client = new HostClient({
|
|
|
40805
40787
|
forgetAcknowledgedAcceptedAssignments(assignments, acceptedAssignmentRoot)
|
|
40806
40788
|
]);
|
|
40807
40789
|
},
|
|
40790
|
+
onDisclaimerBacklog: (pending, reported) => {
|
|
40791
|
+
log.warn("More unfinished Task claims than one connection can report", {
|
|
40792
|
+
machine,
|
|
40793
|
+
pending,
|
|
40794
|
+
reported,
|
|
40795
|
+
next: "The rest are reported as this Machine reconnects; report this if it does not clear"
|
|
40796
|
+
});
|
|
40797
|
+
},
|
|
40808
40798
|
persistAcceptedAssignment: (assignment) => recordAcceptedAssignment(assignment, acceptedAssignmentRoot).then(() => void 0),
|
|
40809
40799
|
forgetAcceptedAssignment: (assignment) => forgetAcceptedAssignment(assignment, acceptedAssignmentRoot),
|
|
40810
40800
|
persistTerminalOutcome: (hostId, outcome) => recordTerminalOutcome(hostId, outcome, terminalOutcomeRoot),
|
|
@@ -40836,7 +40826,7 @@ var client = new HostClient({
|
|
|
40836
40826
|
onUsableTelemetryReport: () => {
|
|
40837
40827
|
reportWorkerReadiness();
|
|
40838
40828
|
},
|
|
40839
|
-
onStatus: (status) => {
|
|
40829
|
+
onStatus: (status, detail) => {
|
|
40840
40830
|
if (status === lastReportedStatus) return;
|
|
40841
40831
|
lastReportedStatus = status;
|
|
40842
40832
|
switch (status) {
|
|
@@ -40876,6 +40866,13 @@ var client = new HostClient({
|
|
|
40876
40866
|
});
|
|
40877
40867
|
queueMicrotask(() => shutdown(packagedBuild ? UPDATE_EXIT_CODE : DO_NOT_RESTART_EXIT_CODE));
|
|
40878
40868
|
break;
|
|
40869
|
+
case "rejected":
|
|
40870
|
+
log.error("Zixt Cloud refused this Machine", {
|
|
40871
|
+
...connectionContext,
|
|
40872
|
+
reason: detail ?? "the cloud gave no reason",
|
|
40873
|
+
next: "Zixt keeps retrying; report this reason if the Machine stays offline, because no update changes it"
|
|
40874
|
+
});
|
|
40875
|
+
break;
|
|
40879
40876
|
}
|
|
40880
40877
|
},
|
|
40881
40878
|
executor,
|
|
@@ -40893,7 +40890,7 @@ for (const { record: record2 } of reportedWorkerExits) {
|
|
|
40893
40890
|
...context,
|
|
40894
40891
|
next: "This Machine restarted itself; report it if the same exit repeats"
|
|
40895
40892
|
});
|
|
40896
|
-
for (const line of record2.stderr)
|
|
40893
|
+
for (const line of record2.stderr) replayConsoleLine("error", "Previous worker output", { line });
|
|
40897
40894
|
}
|
|
40898
40895
|
log.info("Starting Zixt Host", connectionContext);
|
|
40899
40896
|
client.start();
|