@zixt/host 0.0.64 → 0.0.66

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 (2) hide show
  1. package/dist/index.js +102 -13
  2. 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.64",
34
+ version: "0.0.66",
35
35
  type: "module",
36
36
  exports: {
37
37
  ".": "./src/client.ts",
@@ -16331,13 +16331,18 @@ var TaskTimingBreakdown = external_exports.object({
16331
16331
  runs: external_exports.array(TaskTimingRun).max(TASK_TIMING_MAX_RUNS)
16332
16332
  }).strict();
16333
16333
  var TaskProgressStepState = external_exports.enum([
16334
- /** Reached, and the Task has since moved past it. */
16334
+ /** Reached and finished: the Task demonstrably passed through it. */
16335
16335
  "done",
16336
16336
  /** The furthest step the Task has reached. */
16337
16337
  "active",
16338
16338
  /** Not reached yet. */
16339
16339
  "pending",
16340
- /** The Task moved past this step without spending measurable time in it. */
16340
+ /**
16341
+ * The Task went past this step with nothing to show for it: no recorded
16342
+ * activity of that kind and no measurable time. Reserved for the steps
16343
+ * attributed from the activity record — a dispatched Task queued and started
16344
+ * up whatever the clock says, so those two are never reported as skipped.
16345
+ */
16341
16346
  "skipped"
16342
16347
  ]);
16343
16348
  var TaskProgressStep = external_exports.object({
@@ -16401,8 +16406,8 @@ var TaskProgressEstimate = external_exports.object({
16401
16406
  elapsedMs: external_exports.number().int().min(0),
16402
16407
  /** Of that, time a Machine was actually working. */
16403
16408
  activeMs: external_exports.number().int().min(0),
16404
- /** Working time still expected, as a range; null when unknowable. */
16405
- remaining: external_exports.object({ lowMs: external_exports.number().int().min(0), highMs: external_exports.number().int().min(0) }).strict().nullable(),
16409
+ /** Working time still expected, as one estimate; null when unknowable. */
16410
+ remainingMs: external_exports.number().int().min(0).nullable(),
16406
16411
  sample: TaskProgressSample.nullable(),
16407
16412
  /** Every TS-20 step, in lifecycle order. */
16408
16413
  steps: external_exports.array(TaskProgressStep),
@@ -27237,6 +27242,36 @@ import { lstat as lstat11, mkdir as mkdir10, realpath as realpath8 } from "node:
27237
27242
  import { homedir as homedir4 } from "node:os";
27238
27243
  import { dirname as dirname7, isAbsolute as isAbsolute14, join as join14, resolve as resolve9 } from "node:path";
27239
27244
 
27245
+ // src/tool-packs/browser/authentication-wall.ts
27246
+ var AUTH_PATH_SEGMENT = /(?:^|\/)(?:log[-_]?in|sign[-_]?in|sso|saml|auth|authorize|authenticate|oauth2?|session\/new|checkpoint)(?:\/|$)/i;
27247
+ var AUTH_HOST = /(?:^|\.)(?:auth0\.com|okta\.com|oktapreview\.com|onelogin\.com|pingidentity\.com|duosecurity\.com)$|^(?:accounts|login|signin|auth|id|idp|sso)\./i;
27248
+ var AUTH_QUERY = /[?&](?:redirect_uri|returnto|return_to|returnurl|samlrequest)=/i;
27249
+ var AUTH_TITLE = /\b(?:sign[- ]?in|log[- ]?in|login|authenticate|authentication required|unauthorized|access denied|session expired)\b/i;
27250
+ var PASSWORD_PROMPT = /\b(?:textbox|input|field)\b[^\n]{0,80}\bpass(?:word|phrase)\b/i;
27251
+ 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;
27252
+ function authenticationWallGuidance(origin) {
27253
+ return [
27254
+ `This page is asking someone to sign in to ${origin}.`,
27255
+ "You cannot type a password: if a saved website-login Credential covers this site, call browser_login with its name.",
27256
+ "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.",
27257
+ "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.",
27258
+ "Never ask for, accept, or type a password, token, or one-time code in chat.",
27259
+ "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."
27260
+ ].join(" ");
27261
+ }
27262
+ function detectAuthenticationWall(page2) {
27263
+ let url3;
27264
+ try {
27265
+ url3 = new URL(page2.url);
27266
+ } catch {
27267
+ return null;
27268
+ }
27269
+ if (url3.protocol !== "https:" && url3.protocol !== "http:") return null;
27270
+ 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));
27271
+ if (!walled) return null;
27272
+ return { origin: url3.origin, guidance: authenticationWallGuidance(url3.origin) };
27273
+ }
27274
+
27240
27275
  // src/tool-packs/browser/tool-definitions.ts
27241
27276
  function definition(name, description, properties, required2 = []) {
27242
27277
  return {
@@ -27327,13 +27362,15 @@ var BROWSER_TOOL_DEFINITIONS = [
27327
27362
  ];
27328
27363
 
27329
27364
  // src/tool-packs/browser/index.ts
27330
- function externalPage(url3, data, truncated = false) {
27365
+ function externalPage(page2, data, truncated = false) {
27366
+ const wall = detectAuthenticationWall(page2);
27331
27367
  return {
27332
27368
  ok: true,
27333
27369
  result: {
27334
- source: { provider: "browser", trust: "external_untrusted", url: url3 },
27370
+ source: { provider: "browser", trust: "external_untrusted", url: page2.url },
27335
27371
  data,
27336
- truncated
27372
+ truncated,
27373
+ ...wall ? { authenticationWall: wall } : {}
27337
27374
  }
27338
27375
  };
27339
27376
  }
@@ -27363,12 +27400,12 @@ function createBrowserToolPack(deps) {
27363
27400
  });
27364
27401
  await tool.navigate(url3);
27365
27402
  const state = tool.state();
27366
- return externalPage(state.url, { url: state.url, title: state.title });
27403
+ return externalPage(state, { url: state.url, title: state.title });
27367
27404
  }
27368
27405
  case "browser_read": {
27369
27406
  const page2 = await tool.read();
27370
27407
  return externalPage(
27371
- page2.url,
27408
+ page2,
27372
27409
  { url: page2.url, title: page2.title, text: page2.text },
27373
27410
  page2.truncated
27374
27411
  );
@@ -27404,7 +27441,7 @@ function createBrowserToolPack(deps) {
27404
27441
  ...y !== void 0 ? { y } : {}
27405
27442
  });
27406
27443
  const state = tool.state();
27407
- return externalPage(state.url, { url: state.url, title: state.title });
27444
+ return externalPage(state, { url: state.url, title: state.title });
27408
27445
  }
27409
27446
  case "browser_type": {
27410
27447
  const text = asString(args["text"]);
@@ -27421,14 +27458,14 @@ function createBrowserToolPack(deps) {
27421
27458
  ...args["submit"] === true ? { submit: true } : {}
27422
27459
  });
27423
27460
  const state = tool.state();
27424
- return externalPage(state.url, { url: state.url, title: state.title });
27461
+ return externalPage(state, { url: state.url, title: state.title });
27425
27462
  }
27426
27463
  case "browser_press": {
27427
27464
  const key = asString(args["key"]);
27428
27465
  if (!key) return { ok: false, error: "key is required" };
27429
27466
  await tool.press(key);
27430
27467
  const state = tool.state();
27431
- return externalPage(state.url, { url: state.url, title: state.title });
27468
+ return externalPage(state, { url: state.url, title: state.title });
27432
27469
  }
27433
27470
  case "browser_scroll": {
27434
27471
  const deltaY = asNumber(args["delta_y"]);
@@ -32912,6 +32949,53 @@ function renderAttachmentSection(files) {
32912
32949
 
32913
32950
  // src/runners/ask-user-server.ts
32914
32951
  import { createServer as createServer2 } from "node:http";
32952
+
32953
+ // src/runners/ask-user-secrets.ts
32954
+ 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?)";
32955
+ var SECRET_NOUN = new RegExp(String.raw`\b${SECRET_NOUN_SOURCE}\b`, "i");
32956
+ var SECRET_ENV_NAME = /\b[A-Z][A-Z0-9]*(?:_[A-Z0-9]+)*_(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD|PAT)\b/;
32957
+ function namesSecret(sentence) {
32958
+ return SECRET_NOUN.test(sentence) || SECRET_ENV_NAME.test(sentence);
32959
+ }
32960
+ var TRANSFER = "(?:paste|send|share|provide|supply|give|reply|respond|forward|drop|tell)";
32961
+ var REQUEST_PATTERNS = [
32962
+ new RegExp(String.raw`^\s*(?:please\s+)?${TRANSFER}\b`, "i"),
32963
+ new RegExp(String.raw`\b(?:can|could|would|will)\s+you\s+(?:please\s+)?${TRANSFER}\b`, "i"),
32964
+ new RegExp(
32965
+ String.raw`\b${TRANSFER}\b[^.?!]{0,40}\b(?:me|here|in chat|in the chat|in your (?:reply|answer|message)|below)\b`,
32966
+ "i"
32967
+ ),
32968
+ new RegExp(String.raw`\b${TRANSFER}\b[^.?!]{0,20}\byour\b`, "i"),
32969
+ new RegExp(
32970
+ String.raw`\bwhat(?:'s| is|s|\s+are)\s+(?:the|your)\s+(?:[\w-]+\s+){0,2}${SECRET_NOUN_SOURCE}\b`,
32971
+ "i"
32972
+ )
32973
+ ];
32974
+ var NEGATION = /\b(?:do not|don'?t|never|no need|without|rather than|instead of|avoid)\b/i;
32975
+ function namesSafeDestination(sentence) {
32976
+ 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(
32977
+ sentence
32978
+ );
32979
+ }
32980
+ var SECRET_IN_CHAT_REFUSAL = [
32981
+ "Not delivered: Zixt never carries a password, token, or one-time code through chat (W5).",
32982
+ "Ask for the capability instead of the value.",
32983
+ "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.",
32984
+ "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.",
32985
+ "Then ask again without requesting the value."
32986
+ ].join(" ");
32987
+ function secretSolicitationRefusal(question, context) {
32988
+ const sentences = `${question}
32989
+ ${context}`.split(/(?<=[.!?\n])\s+/).map((sentence) => sentence.trim()).filter((sentence) => sentence.length > 0);
32990
+ for (const sentence of sentences) {
32991
+ if (!namesSecret(sentence)) continue;
32992
+ if (NEGATION.test(sentence) || namesSafeDestination(sentence)) continue;
32993
+ if (REQUEST_PATTERNS.some((pattern) => pattern.test(sentence))) return SECRET_IN_CHAT_REFUSAL;
32994
+ }
32995
+ return null;
32996
+ }
32997
+
32998
+ // src/runners/ask-user-server.ts
32915
32999
  var CADENCE_PROPS = {
32916
33000
  cadence_kind: {
32917
33001
  type: "string",
@@ -33629,6 +33713,11 @@ function createAskUserServer() {
33629
33713
  }
33630
33714
  try {
33631
33715
  const context = typeof args["context"] === "string" ? args["context"] : "";
33716
+ const refusal = secretSolicitationRefusal(question, context);
33717
+ if (refusal) {
33718
+ toolText(refusal, true);
33719
+ return;
33720
+ }
33632
33721
  const rawChoices = args["choices"];
33633
33722
  const parsedChoices = rawChoices === void 0 ? void 0 : QuestionChoices.safeParse(rawChoices);
33634
33723
  if (parsedChoices && !parsedChoices.success) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zixt/host",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  ".": "./src/client.ts",