@zixt/host 0.0.65 → 0.0.67
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 +98 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -31,7 +31,7 @@ import { homedir } 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.67",
|
|
35
35
|
type: "module",
|
|
36
36
|
exports: {
|
|
37
37
|
".": "./src/client.ts",
|
|
@@ -19840,7 +19840,11 @@ var HttpOrigin2 = external_exports.url().max(2e3).refine((value) => {
|
|
|
19840
19840
|
const parsed = new URL(value);
|
|
19841
19841
|
return (parsed.protocol === "https:" || parsed.protocol === "http:" && (parsed.hostname === "localhost" || parsed.hostname === "127.0.0.1")) && parsed.origin === value && parsed.username === "" && parsed.password === "";
|
|
19842
19842
|
}, "must be an exact credential-free HTTPS origin or local loopback HTTP origin");
|
|
19843
|
-
var
|
|
19843
|
+
var GithubOrganizationLogin = external_exports.string().trim().min(1).max(39).regex(/^[A-Za-z0-9](?:-?[A-Za-z0-9])*$/);
|
|
19844
|
+
var StartGithubConnectionRequest = external_exports.object({
|
|
19845
|
+
organizationLogin: GithubOrganizationLogin,
|
|
19846
|
+
returnPath: SafeReturnPath2.optional()
|
|
19847
|
+
}).strict();
|
|
19844
19848
|
var StartGithubTeammateOAuthRequest = external_exports.object({
|
|
19845
19849
|
expectedRevision: external_exports.number().int().min(1),
|
|
19846
19850
|
returnPath: SafeReturnPath2.optional()
|
|
@@ -27242,6 +27246,36 @@ import { lstat as lstat11, mkdir as mkdir10, realpath as realpath8 } from "node:
|
|
|
27242
27246
|
import { homedir as homedir4 } from "node:os";
|
|
27243
27247
|
import { dirname as dirname7, isAbsolute as isAbsolute14, join as join14, resolve as resolve9 } from "node:path";
|
|
27244
27248
|
|
|
27249
|
+
// src/tool-packs/browser/authentication-wall.ts
|
|
27250
|
+
var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
|
|
27251
|
+
var AUTH_HOST = /(?:^|\.)(?:auth0\.com|okta\.com|oktapreview\.com|onelogin\.com|pingidentity\.com|duosecurity\.com)$|^(?:accounts|login|signin|auth|id|idp|sso)\./i;
|
|
27252
|
+
var AUTH_QUERY = /[?&](?:redirect_uri|returnto|return_to|returnurl|samlrequest)=/i;
|
|
27253
|
+
var AUTH_TITLE = /\b(?:sign[- ]?in|log[- ]?in|login|authenticate|authentication required|unauthorized|access denied|session expired)\b/i;
|
|
27254
|
+
var PASSWORD_PROMPT = /\b(?:textbox|input|field)\b[^\n]{0,80}\bpass(?:word|phrase)\b/i;
|
|
27255
|
+
var BLOCKED_STATEMENT = /\b(?:you (?:must|need to) (?:be )?(?:sign|log)(?:ged)? ?in|please (?:sign|log) ?in|(?:sign|log) ?in to continue|your session (?:has )?expired|session expired|401 unauthorized|403 forbidden|access denied|not authorized)\b/i;
|
|
27256
|
+
function authenticationWallGuidance(origin) {
|
|
27257
|
+
return [
|
|
27258
|
+
`This page is asking someone to sign in to ${origin}.`,
|
|
27259
|
+
"You cannot type a password: if a saved website-login Credential covers this site, call browser_login with its name.",
|
|
27260
|
+
"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.",
|
|
27261
|
+
"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.",
|
|
27262
|
+
"Never ask for, accept, or type a password, token, or one-time code in chat.",
|
|
27263
|
+
"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."
|
|
27264
|
+
].join(" ");
|
|
27265
|
+
}
|
|
27266
|
+
function detectAuthenticationWall(page2) {
|
|
27267
|
+
let url3;
|
|
27268
|
+
try {
|
|
27269
|
+
url3 = new URL(page2.url);
|
|
27270
|
+
} catch {
|
|
27271
|
+
return null;
|
|
27272
|
+
}
|
|
27273
|
+
if (url3.protocol !== "https:" && url3.protocol !== "http:") return null;
|
|
27274
|
+
const walled = AUTH_PATH_SEGMENT.test(url3.pathname) || AUTH_HOST.test(url3.hostname) || AUTH_QUERY.test(url3.search) || AUTH_TITLE.test(page2.title) || page2.text !== void 0 && (PASSWORD_PROMPT.test(page2.text) || BLOCKED_STATEMENT.test(page2.text));
|
|
27275
|
+
if (!walled) return null;
|
|
27276
|
+
return { origin: url3.origin, guidance: authenticationWallGuidance(url3.origin) };
|
|
27277
|
+
}
|
|
27278
|
+
|
|
27245
27279
|
// src/tool-packs/browser/tool-definitions.ts
|
|
27246
27280
|
function definition(name, description, properties, required2 = []) {
|
|
27247
27281
|
return {
|
|
@@ -27332,13 +27366,15 @@ var BROWSER_TOOL_DEFINITIONS = [
|
|
|
27332
27366
|
];
|
|
27333
27367
|
|
|
27334
27368
|
// src/tool-packs/browser/index.ts
|
|
27335
|
-
function externalPage(
|
|
27369
|
+
function externalPage(page2, data, truncated = false) {
|
|
27370
|
+
const wall = detectAuthenticationWall(page2);
|
|
27336
27371
|
return {
|
|
27337
27372
|
ok: true,
|
|
27338
27373
|
result: {
|
|
27339
|
-
source: { provider: "browser", trust: "external_untrusted", url:
|
|
27374
|
+
source: { provider: "browser", trust: "external_untrusted", url: page2.url },
|
|
27340
27375
|
data,
|
|
27341
|
-
truncated
|
|
27376
|
+
truncated,
|
|
27377
|
+
...wall ? { authenticationWall: wall } : {}
|
|
27342
27378
|
}
|
|
27343
27379
|
};
|
|
27344
27380
|
}
|
|
@@ -27368,12 +27404,12 @@ function createBrowserToolPack(deps) {
|
|
|
27368
27404
|
});
|
|
27369
27405
|
await tool.navigate(url3);
|
|
27370
27406
|
const state = tool.state();
|
|
27371
|
-
return externalPage(state
|
|
27407
|
+
return externalPage(state, { url: state.url, title: state.title });
|
|
27372
27408
|
}
|
|
27373
27409
|
case "browser_read": {
|
|
27374
27410
|
const page2 = await tool.read();
|
|
27375
27411
|
return externalPage(
|
|
27376
|
-
page2
|
|
27412
|
+
page2,
|
|
27377
27413
|
{ url: page2.url, title: page2.title, text: page2.text },
|
|
27378
27414
|
page2.truncated
|
|
27379
27415
|
);
|
|
@@ -27409,7 +27445,7 @@ function createBrowserToolPack(deps) {
|
|
|
27409
27445
|
...y !== void 0 ? { y } : {}
|
|
27410
27446
|
});
|
|
27411
27447
|
const state = tool.state();
|
|
27412
|
-
return externalPage(state
|
|
27448
|
+
return externalPage(state, { url: state.url, title: state.title });
|
|
27413
27449
|
}
|
|
27414
27450
|
case "browser_type": {
|
|
27415
27451
|
const text = asString(args["text"]);
|
|
@@ -27426,14 +27462,14 @@ function createBrowserToolPack(deps) {
|
|
|
27426
27462
|
...args["submit"] === true ? { submit: true } : {}
|
|
27427
27463
|
});
|
|
27428
27464
|
const state = tool.state();
|
|
27429
|
-
return externalPage(state
|
|
27465
|
+
return externalPage(state, { url: state.url, title: state.title });
|
|
27430
27466
|
}
|
|
27431
27467
|
case "browser_press": {
|
|
27432
27468
|
const key = asString(args["key"]);
|
|
27433
27469
|
if (!key) return { ok: false, error: "key is required" };
|
|
27434
27470
|
await tool.press(key);
|
|
27435
27471
|
const state = tool.state();
|
|
27436
|
-
return externalPage(state
|
|
27472
|
+
return externalPage(state, { url: state.url, title: state.title });
|
|
27437
27473
|
}
|
|
27438
27474
|
case "browser_scroll": {
|
|
27439
27475
|
const deltaY = asNumber(args["delta_y"]);
|
|
@@ -32917,6 +32953,53 @@ function renderAttachmentSection(files) {
|
|
|
32917
32953
|
|
|
32918
32954
|
// src/runners/ask-user-server.ts
|
|
32919
32955
|
import { createServer as createServer2 } from "node:http";
|
|
32956
|
+
|
|
32957
|
+
// src/runners/ask-user-secrets.ts
|
|
32958
|
+
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?)";
|
|
32959
|
+
var SECRET_NOUN = new RegExp(String.raw`\b${SECRET_NOUN_SOURCE}\b`, "i");
|
|
32960
|
+
var SECRET_ENV_NAME = /\b[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PAT)\b/;
|
|
32961
|
+
function namesSecret(sentence) {
|
|
32962
|
+
return SECRET_NOUN.test(sentence) || SECRET_ENV_NAME.test(sentence);
|
|
32963
|
+
}
|
|
32964
|
+
var TRANSFER = "(?:paste|send|share|provide|supply|give|reply|respond|forward|drop|tell)";
|
|
32965
|
+
var REQUEST_PATTERNS = [
|
|
32966
|
+
new RegExp(String.raw`^\s*(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
32967
|
+
new RegExp(String.raw`\b(?:can|could|would|will)\s+you\s+(?:please\s+)?${TRANSFER}\b`, "i"),
|
|
32968
|
+
new RegExp(
|
|
32969
|
+
String.raw`\b${TRANSFER}\b[^.?!]{0,40}\b(?:me|here|in chat|in the chat|in your (?:reply|answer|message)|below)\b`,
|
|
32970
|
+
"i"
|
|
32971
|
+
),
|
|
32972
|
+
new RegExp(String.raw`\b${TRANSFER}\b[^.?!]{0,20}\byour\b`, "i"),
|
|
32973
|
+
new RegExp(
|
|
32974
|
+
String.raw`\bwhat(?:'s| is|s|\s+are)\s+(?:the|your)\s+(?:[\w-]+\s+){0,2}${SECRET_NOUN_SOURCE}\b`,
|
|
32975
|
+
"i"
|
|
32976
|
+
)
|
|
32977
|
+
];
|
|
32978
|
+
var NEGATION = /\b(?:do not|don'?t|never|no need|without|rather than|instead of|avoid)\b/i;
|
|
32979
|
+
function namesSafeDestination(sentence) {
|
|
32980
|
+
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(
|
|
32981
|
+
sentence
|
|
32982
|
+
);
|
|
32983
|
+
}
|
|
32984
|
+
var SECRET_IN_CHAT_REFUSAL = [
|
|
32985
|
+
"Not delivered: Zixt never carries a password, token, or one-time code through chat (W5).",
|
|
32986
|
+
"Ask for the capability instead of the value.",
|
|
32987
|
+
"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.",
|
|
32988
|
+
"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.",
|
|
32989
|
+
"Then ask again without requesting the value."
|
|
32990
|
+
].join(" ");
|
|
32991
|
+
function secretSolicitationRefusal(question, context) {
|
|
32992
|
+
const sentences = `${question}
|
|
32993
|
+
${context}`.split(/(?<=[.!?\n])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
|
|
32994
|
+
for (const sentence of sentences) {
|
|
32995
|
+
if (!namesSecret(sentence)) continue;
|
|
32996
|
+
if (NEGATION.test(sentence) || namesSafeDestination(sentence)) continue;
|
|
32997
|
+
if (REQUEST_PATTERNS.some((pattern) => pattern.test(sentence))) return SECRET_IN_CHAT_REFUSAL;
|
|
32998
|
+
}
|
|
32999
|
+
return null;
|
|
33000
|
+
}
|
|
33001
|
+
|
|
33002
|
+
// src/runners/ask-user-server.ts
|
|
32920
33003
|
var CADENCE_PROPS = {
|
|
32921
33004
|
cadence_kind: {
|
|
32922
33005
|
type: "string",
|
|
@@ -33634,6 +33717,11 @@ function createAskUserServer() {
|
|
|
33634
33717
|
}
|
|
33635
33718
|
try {
|
|
33636
33719
|
const context = typeof args["context"] === "string" ? args["context"] : "";
|
|
33720
|
+
const refusal = secretSolicitationRefusal(question, context);
|
|
33721
|
+
if (refusal) {
|
|
33722
|
+
toolText(refusal, true);
|
|
33723
|
+
return;
|
|
33724
|
+
}
|
|
33637
33725
|
const rawChoices = args["choices"];
|
|
33638
33726
|
const parsedChoices = rawChoices === void 0 ? void 0 : QuestionChoices.safeParse(rawChoices);
|
|
33639
33727
|
if (parsedChoices && !parsedChoices.success) {
|